Qt: Add work in progress interface
|
@ -0,0 +1,3 @@
|
|||
/*
|
||||
!.gitignore
|
||||
!README.md
|
|
@ -0,0 +1,11 @@
|
|||
# PCSX2 Qt Binaries
|
||||
|
||||
## Windows
|
||||
|
||||
You can download the binaries from https://github.com/PCSX2/pcsx2-windows-dependencies
|
||||
|
||||
Grab the latest release without symbols (or, if you want to debug Qt, with symbols), and extract it to this directory.
|
||||
|
||||
## Linux
|
||||
|
||||
TODO
|
|
@ -0,0 +1,656 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31606.5
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3rdparty", "3rdparty", "{78EBE642-7A4D-4EA7-86BE-5639C6646C38}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
3rdparty\svn_readme.txt = 3rdparty\svn_readme.txt
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{2D6F0A62-A247-4CCF-947F-FCD54BE16103}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SoundTouch", "3rdparty\soundtouch\SoundTouch.vcxproj", "{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "3rdparty\zlib\zlib.vcxproj", "{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bin2cpp", "tools\bin2cpp\bin2c.vcxproj", "{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libjpeg", "3rdparty\libjpeg\libjpeg.vcxproj", "{BC236261-77E8-4567-8D09-45CD02965EB6}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wx30_config", "3rdparty\wxwidgets3.0\build\msw\wx30_config.vcxproj", "{01F4CE10-2CFB-41A8-B41F-E54337868A1D}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wx30_base", "3rdparty\wxwidgets3.0\build\msw\wx30_base.vcxproj", "{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpng", "3rdparty\libpng\projects\vstudio\libpng\libpng.vcxproj", "{D6973076-9317-4EF2-A0B8-B7A18AC0713E}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pthreads4w", "3rdparty\pthreads4w\build\pthreads4w.vcxproj", "{0FAE817D-9A32-4830-857E-81DA57246E16}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "baseclasses", "3rdparty\baseclasses\baseclasses.vcxproj", "{27F17499-A372-4408-8AFA-4F9F4584FBD3}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblzma", "3rdparty\xz\liblzma.vcxproj", "{12728250-16EC-4DC6-94D7-E21DD88947F8}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fmt", "3rdparty\fmt\fmt.vcxproj", "{449AD25E-424A-4714-BABC-68706CDCC33B}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libsamplerate", "3rdparty\libsamplerate\libsamplerate.vcxproj", "{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libchdr", "3rdparty\libchdr\libchdr.vcxproj", "{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jpgd", "3rdparty\jpgd\jpgd.vcxproj", "{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "common\common.vcxproj", "{4639972E-424E-4E13-8B07-CA403C481346}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pcsx2core", "pcsx2\pcsx2core.vcxproj", "{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glad", "3rdparty\glad\glad.vcxproj", "{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "imgui", "3rdparty\imgui\imgui.vcxproj", "{88FB34EC-845E-4F21-A552-F1573B9ED167}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pcsx2-qt", "pcsx2-qt\pcsx2-qt.vcxproj", "{2A016F21-87AE-4154-8271-1F57E91408E9}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simpleini", "3rdparty\simpleini\simpleini.vcxproj", "{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cubeb", "3rdparty\cubeb\cubeb.vcxproj", "{BF74C473-DC04-44B3-92E8-4145F4E77342}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ryml", "3rdparty\rapidyaml\ryml.vcxproj", "{DE9653B6-17DD-356A-9EE0-28A731772587}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glslang", "3rdparty\glslang\glslang.vcxproj", "{EF6834A9-11F3-4331-BC34-21B325ABB180}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug AVX2|Win32 = Debug AVX2|Win32
|
||||
Debug AVX2|x64 = Debug AVX2|x64
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Devel AVX2|Win32 = Devel AVX2|Win32
|
||||
Devel AVX2|x64 = Devel AVX2|x64
|
||||
Devel|Win32 = Devel|Win32
|
||||
Devel|x64 = Devel|x64
|
||||
Release AVX2|Win32 = Release AVX2|Win32
|
||||
Release AVX2|x64 = Release AVX2|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Debug|x64.Build.0 = Debug|x64
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Devel|x64.Build.0 = Devel|x64
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Release|Win32.Build.0 = Release|Win32
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Release|x64.ActiveCfg = Release|x64
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D}.Release|x64.Build.0 = Release|x64
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Debug|x64.Build.0 = Debug|x64
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Devel|x64.Build.0 = Devel|x64
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release|Win32.Build.0 = Release|Win32
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release|x64.ActiveCfg = Release|x64
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47}.Release|x64.Build.0 = Release|x64
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Debug|x64.Build.0 = Debug|x64
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Devel|x64.Build.0 = Devel|x64
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Release|Win32.Build.0 = Release|Win32
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Release|x64.ActiveCfg = Release|x64
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}.Release|x64.Build.0 = Release|x64
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Debug|x64.Build.0 = Debug|x64
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Devel|x64.Build.0 = Devel|x64
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release|Win32.Build.0 = Release|Win32
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release|x64.ActiveCfg = Release|x64
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6}.Release|x64.Build.0 = Release|x64
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{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}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Devel|x64.Build.0 = Devel|x64
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release|Win32.Build.0 = Release|Win32
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release|x64.ActiveCfg = Release|x64
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D}.Release|x64.Build.0 = Release|x64
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{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}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Devel|x64.Build.0 = Devel|x64
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release|Win32.Build.0 = Release|Win32
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release|x64.ActiveCfg = Release|x64
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release|x64.Build.0 = Release|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Debug|x64.Build.0 = Debug|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Devel|x64.Build.0 = Devel|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release|Win32.Build.0 = Release|Win32
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release|x64.ActiveCfg = Release|x64
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E}.Release|x64.Build.0 = Release|x64
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Debug|x64.Build.0 = Debug|x64
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Devel|x64.Build.0 = Devel|x64
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Release|Win32.Build.0 = Release|Win32
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Release|x64.ActiveCfg = Release|x64
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16}.Release|x64.Build.0 = Release|x64
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Debug|x64.Build.0 = Debug|x64
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Devel|x64.Build.0 = Devel|x64
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Release|Win32.Build.0 = Release|Win32
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Release|x64.ActiveCfg = Release|x64
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3}.Release|x64.Build.0 = Release|x64
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|x64.Build.0 = Debug|x64
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Devel|x64.Build.0 = Devel|x64
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|Win32.Build.0 = Release|Win32
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|x64.ActiveCfg = Release|x64
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|x64.Build.0 = Release|x64
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Debug|x64.Build.0 = Debug|x64
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Devel|x64.Build.0 = Devel|x64
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Release|Win32.Build.0 = Release|Win32
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Release|x64.ActiveCfg = Release|x64
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B}.Release|x64.Build.0 = Release|x64
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Debug|x64.Build.0 = Debug|x64
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Devel|x64.Build.0 = Devel|x64
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Release|Win32.Build.0 = Release|Win32
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Release|x64.ActiveCfg = Release|x64
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F}.Release|x64.Build.0 = Release|x64
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Debug|x64.Build.0 = Debug|x64
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Devel|x64.Build.0 = Devel|x64
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Release|Win32.Build.0 = Release|Win32
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Release|x64.ActiveCfg = Release|x64
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0}.Release|x64.Build.0 = Release|x64
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Debug|x64.Build.0 = Debug|x64
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Devel|x64.Build.0 = Devel|x64
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Release|Win32.Build.0 = Release|Win32
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Release|x64.ActiveCfg = Release|x64
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63}.Release|x64.Build.0 = Release|x64
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Debug|x64.Build.0 = Debug|x64
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Devel|x64.Build.0 = Devel|x64
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Release|Win32.Build.0 = Release|Win32
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Release|x64.ActiveCfg = Release|x64
|
||||
{4639972E-424E-4E13-8B07-CA403C481346}.Release|x64.Build.0 = Release|x64
|
||||
{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}.Debug AVX2|Win32.ActiveCfg = Debug AVX2|Win32
|
||||
{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}.Debug AVX2|Win32.Build.0 = Debug AVX2|Win32
|
||||
{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}.Debug AVX2|x64.ActiveCfg = Debug AVX2|x64
|
||||
{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}.Debug AVX2|x64.Build.0 = Debug AVX2|x64
|
||||
{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}.Debug|x64.Build.0 = Debug|x64
|
||||
{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}.Devel AVX2|Win32.ActiveCfg = Devel AVX2|Win32
|
||||
{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}.Devel AVX2|Win32.Build.0 = Devel AVX2|Win32
|
||||
{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}.Devel AVX2|x64.ActiveCfg = Devel AVX2|x64
|
||||
{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}.Devel AVX2|x64.Build.0 = Devel AVX2|x64
|
||||
{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}.Devel|x64.Build.0 = Devel|x64
|
||||
{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}.Release AVX2|Win32.ActiveCfg = Release AVX2|Win32
|
||||
{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}.Release AVX2|Win32.Build.0 = Release AVX2|Win32
|
||||
{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}.Release AVX2|x64.ActiveCfg = Release AVX2|x64
|
||||
{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}.Release AVX2|x64.Build.0 = Release AVX2|x64
|
||||
{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}.Release|Win32.Build.0 = Release|Win32
|
||||
{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}.Release|x64.ActiveCfg = Release|x64
|
||||
{6C7986C4-3E4D-4DCC-B3C6-6BB12B238995}.Release|x64.Build.0 = Release|x64
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Debug|x64.Build.0 = Debug|x64
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Devel|x64.Build.0 = Devel|x64
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Release|Win32.Build.0 = Release|Win32
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Release|x64.ActiveCfg = Release|x64
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A}.Release|x64.Build.0 = Release|x64
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Debug|x64.Build.0 = Debug|x64
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Devel|x64.Build.0 = Devel|x64
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Release|Win32.Build.0 = Release|Win32
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Release|x64.ActiveCfg = Release|x64
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167}.Release|x64.Build.0 = Release|x64
|
||||
{2A016F21-87AE-4154-8271-1F57E91408E9}.Debug AVX2|Win32.ActiveCfg = Debug AVX2|Win32
|
||||
{2A016F21-87AE-4154-8271-1F57E91408E9}.Debug AVX2|Win32.Build.0 = Debug AVX2|Win32
|
||||
{2A016F21-87AE-4154-8271-1F57E91408E9}.Debug AVX2|x64.ActiveCfg = Debug AVX2|x64
|
||||
{2A016F21-87AE-4154-8271-1F57E91408E9}.Debug AVX2|x64.Build.0 = Debug AVX2|x64
|
||||
{2A016F21-87AE-4154-8271-1F57E91408E9}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{2A016F21-87AE-4154-8271-1F57E91408E9}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{2A016F21-87AE-4154-8271-1F57E91408E9}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{2A016F21-87AE-4154-8271-1F57E91408E9}.Debug|x64.Build.0 = Debug|x64
|
||||
{2A016F21-87AE-4154-8271-1F57E91408E9}.Devel AVX2|Win32.ActiveCfg = Devel AVX2|Win32
|
||||
{2A016F21-87AE-4154-8271-1F57E91408E9}.Devel AVX2|Win32.Build.0 = Devel AVX2|Win32
|
||||
{2A016F21-87AE-4154-8271-1F57E91408E9}.Devel AVX2|x64.ActiveCfg = Devel AVX2|x64
|
||||
{2A016F21-87AE-4154-8271-1F57E91408E9}.Devel AVX2|x64.Build.0 = Devel AVX2|x64
|
||||
{2A016F21-87AE-4154-8271-1F57E91408E9}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{2A016F21-87AE-4154-8271-1F57E91408E9}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{2A016F21-87AE-4154-8271-1F57E91408E9}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{2A016F21-87AE-4154-8271-1F57E91408E9}.Devel|x64.Build.0 = Devel|x64
|
||||
{2A016F21-87AE-4154-8271-1F57E91408E9}.Release AVX2|Win32.ActiveCfg = Release AVX2|Win32
|
||||
{2A016F21-87AE-4154-8271-1F57E91408E9}.Release AVX2|Win32.Build.0 = Release AVX2|Win32
|
||||
{2A016F21-87AE-4154-8271-1F57E91408E9}.Release AVX2|x64.ActiveCfg = Release AVX2|x64
|
||||
{2A016F21-87AE-4154-8271-1F57E91408E9}.Release AVX2|x64.Build.0 = Release AVX2|x64
|
||||
{2A016F21-87AE-4154-8271-1F57E91408E9}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{2A016F21-87AE-4154-8271-1F57E91408E9}.Release|Win32.Build.0 = Release|Win32
|
||||
{2A016F21-87AE-4154-8271-1F57E91408E9}.Release|x64.ActiveCfg = Release|x64
|
||||
{2A016F21-87AE-4154-8271-1F57E91408E9}.Release|x64.Build.0 = Release|x64
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Debug|x64.Build.0 = Debug|x64
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Devel|x64.Build.0 = Devel|x64
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Release|Win32.Build.0 = Release|Win32
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Release|x64.ActiveCfg = Release|x64
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266}.Release|x64.Build.0 = Release|x64
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Debug|x64.Build.0 = Debug|x64
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Devel|x64.Build.0 = Devel|x64
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Release|Win32.Build.0 = Release|Win32
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Release|x64.ActiveCfg = Release|x64
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342}.Release|x64.Build.0 = Release|x64
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Debug|x64.Build.0 = Debug|x64
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Devel|x64.Build.0 = Devel|x64
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Release|Win32.Build.0 = Release|Win32
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Release|x64.ActiveCfg = Release|x64
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587}.Release|x64.Build.0 = Release|x64
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug AVX2|Win32.ActiveCfg = Debug|Win32
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug AVX2|Win32.Build.0 = Debug|Win32
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug AVX2|x64.ActiveCfg = Debug|x64
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug AVX2|x64.Build.0 = Debug|x64
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Debug|x64.Build.0 = Debug|x64
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel AVX2|Win32.ActiveCfg = Devel|Win32
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel AVX2|Win32.Build.0 = Devel|Win32
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel AVX2|x64.ActiveCfg = Devel|x64
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel AVX2|x64.Build.0 = Devel|x64
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel|Win32.ActiveCfg = Devel|Win32
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel|Win32.Build.0 = Devel|Win32
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel|x64.ActiveCfg = Devel|x64
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Devel|x64.Build.0 = Devel|x64
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Release AVX2|Win32.ActiveCfg = Release|Win32
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Release AVX2|Win32.Build.0 = Release|Win32
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Release AVX2|x64.ActiveCfg = Release|x64
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Release AVX2|x64.Build.0 = Release|x64
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Release|Win32.Build.0 = Release|Win32
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Release|x64.ActiveCfg = Release|x64
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{E9B51944-7E6D-4BCD-83F2-7BBD5A46182D} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
|
||||
{2F6C0388-20CB-4242-9F6C-A6EBB6A83F47} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
|
||||
{677B7D11-D5E1-40B3-88B1-9A4DF83D2213} = {2D6F0A62-A247-4CCF-947F-FCD54BE16103}
|
||||
{BC236261-77E8-4567-8D09-45CD02965EB6} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
|
||||
{01F4CE10-2CFB-41A8-B41F-E54337868A1D} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
|
||||
{3FCC50C2-81E9-5DB2-B8D8-2129427568B1} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
|
||||
{D6973076-9317-4EF2-A0B8-B7A18AC0713E} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
|
||||
{0FAE817D-9A32-4830-857E-81DA57246E16} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
|
||||
{27F17499-A372-4408-8AFA-4F9F4584FBD3} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
|
||||
{12728250-16EC-4DC6-94D7-E21DD88947F8} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
|
||||
{449AD25E-424A-4714-BABC-68706CDCC33B} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
|
||||
{47AFDBEF-F15F-4BC0-B436-5BE443C3F80F} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
|
||||
{A0D2B3AD-1F72-4EE3-8B5C-F2C358DA35F0} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
|
||||
{ED2F21FD-0A36-4A8F-9B90-E7D92A2ACB63} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
|
||||
{C0293B32-5ACF-40F0-AA6C-E6DA6F3BF33A} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
|
||||
{88FB34EC-845E-4F21-A552-F1573B9ED167} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
|
||||
{1EC8B3C0-8FB3-46DE-A2E0-A9121203F266} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
|
||||
{BF74C473-DC04-44B3-92E8-4145F4E77342} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
|
||||
{DE9653B6-17DD-356A-9EE0-28A731772587} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
|
||||
{EF6834A9-11F3-4331-BC34-21B325ABB180} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {0BC474EA-3628-45D3-9DBC-E22D0B7E0F77}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
After Width: | Height: | Size: 81 KiB |
|
@ -232,6 +232,10 @@ if(NOT USE_SYSTEM_YAML)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
if(QT_BUILD)
|
||||
find_package(Qt6 COMPONENTS Core Gui Widgets Network LinguistTools REQUIRED)
|
||||
endif()
|
||||
|
||||
add_subdirectory(3rdparty/libchdr/libchdr EXCLUDE_FROM_ALL)
|
||||
|
||||
if(USE_NATIVE_TOOLS)
|
||||
|
|
|
@ -0,0 +1,197 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="UserMacros">
|
||||
<BinaryOutputDir>$(SolutionDir)bin\</BinaryOutputDir>
|
||||
<QTDIRDefault Condition="'$(Platform)'=='x64'">$(SolutionDir)3rdparty\qt\6.2.2\msvc2019_64\</QTDIRDefault>
|
||||
<QTDIRDefault Condition="'$(Platform)'=='ARM64'">$(SolutionDir)3rdparty\qt\6.2.2\msvc2019_arm64\</QTDIRDefault>
|
||||
<QTDIR Condition="Exists('$(QTDIRDefault)') And ('$(QTDIR)'=='' Or !Exists('$(QTDIR)'))">$(QTDIRDefault)</QTDIR>
|
||||
<QTDIR Condition="Exists('$(QTDIR)') And !HasTrailingSlash('$(QTDIR)')">$(QTDIR)\</QTDIR>
|
||||
<QTDIRHost>$(SolutionDir)3rdparty\qt\6.2.2\msvc2019_64\</QTDIRHost>
|
||||
<QtDirValid>false</QtDirValid>
|
||||
<QtDirValid Condition="Exists('$(QTDIR)')">true</QtDirValid>
|
||||
<QtIncludeDir>$(QTDIR)include\</QtIncludeDir>
|
||||
<QtLibDir>$(QTDIR)lib\</QtLibDir>
|
||||
<QtBinDir>$(QTDIR)bin\</QtBinDir>
|
||||
<QtHostBinDir>$(QTDIRHost)bin\</QtHostBinDir>
|
||||
<QtPluginsDir>$(QTDIR)plugins\</QtPluginsDir>
|
||||
<QtTranslationsDir>$(QTDIR)translations\</QtTranslationsDir>
|
||||
<QtToolOutDir>$(IntDir)</QtToolOutDir>
|
||||
<QtMocOutPrefix>$(QtToolOutDir)moc_</QtMocOutPrefix>
|
||||
<QtTsOutDir>$(BinaryOutputDir)translations\</QtTsOutDir>
|
||||
<QtDebugSuffix>d</QtDebugSuffix>
|
||||
<QtLibSuffix Condition="$(Configuration.Contains(Debug))">$(QtDebugSuffix)</QtLibSuffix>
|
||||
<QtPluginFolder>QtPlugins</QtPluginFolder>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions Condition="!$(Configuration.Contains(Debug))">QT_NO_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(QtToolOutDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(QtIncludeDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(QtLibDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>Qt6Core$(QtLibSuffix).lib;Qt6Gui$(QtLibSuffix).lib;Qt6Widgets$(QtLibSuffix).lib;Qt6Network$(QtLibSuffix).lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
<!--Passes all .qrc files to rcc and puts output in the build directory-->
|
||||
<ItemGroup>
|
||||
<ResFiles Include="$(MSBuildProjectDirectory)\**\*.qrc" />
|
||||
</ItemGroup>
|
||||
<Target Name="QtResource"
|
||||
BeforeTargets="ClCompile"
|
||||
Inputs="@(ResFiles)"
|
||||
Condition="'@(QtResource)'!=''"
|
||||
Outputs="@(ResFiles->'$(QtToolOutDir)qrc_%(Filename).cpp')">
|
||||
<Message Text="rcc %(ResFiles.Filename)" Importance="High" />
|
||||
<Error Condition="!$(QtDirValid)" Text="QTDIR not valid (download/extract the zip)" />
|
||||
<MakeDir Directories="$(QtToolOutDir)" />
|
||||
<Exec Command=""$(QtHostBinDir)rcc.exe" "%(ResFiles.FullPath)" -o "$(QtToolOutDir)qrc_%(ResFiles.Filename).cpp"" />
|
||||
</Target>
|
||||
|
||||
<Target Name="QtResourceClean">
|
||||
<Delete Files="@(ResFiles->'$(QtToolOutDir)qrc_%(Filename).cpp')" />
|
||||
</Target>
|
||||
|
||||
<!--Passes all .ui files to uic and puts output in the build directory-->
|
||||
<ItemGroup>
|
||||
<UiFiles Include="$(MSBuildProjectDirectory)\**\*.ui" />
|
||||
</ItemGroup>
|
||||
<Target Name="QtUi"
|
||||
BeforeTargets="ClCompile"
|
||||
Inputs="@(UiFiles)"
|
||||
Condition="'@(QtUi)'!=''"
|
||||
Outputs="@(UiFiles->'$(QtToolOutDir)ui_%(Filename).h')">
|
||||
<Message Text="uic %(UiFiles.Filename)" Importance="High" />
|
||||
<Error Condition="!$(QtDirValid)" Text="QTDIR not valid (download/extract the zip)" />
|
||||
<MakeDir Directories="$(QtToolOutDir)" />
|
||||
<Exec Command=""$(QtHostBinDir)uic.exe" "%(UiFiles.FullPath)" -o "$(QtToolOutDir)ui_%(UiFiles.Filename).h"" />
|
||||
</Target>
|
||||
|
||||
<Target Name="QtUiClean">
|
||||
<Delete Files="@(UiFiles->'$(QtToolOutDir)ui_%(Filename).h')" />
|
||||
</Target>
|
||||
|
||||
<!--Compile files needed to MOC and output in the build directory-->
|
||||
<!--TODO find a way to autocreate from ClCompile settings-->
|
||||
<PropertyGroup>
|
||||
<MocDefines></MocDefines>
|
||||
<MocDefines Condition="!$(Configuration.Contains(Debug))">-DQT_NO_DEBUG -DNDEBUG $(MocDefines)</MocDefines>
|
||||
<MocIncludes>"-I$(QtIncludeDir)" "-I$(SolutionDir)pcsx2" "-I$(SolutionDir)" -I.</MocIncludes>
|
||||
</PropertyGroup>
|
||||
<Target Name="QtMoc"
|
||||
BeforeTargets="ClCompile"
|
||||
Condition="'@(QtMoc)'!=''"
|
||||
Inputs="%(QtMoc.Identity);%(QtMoc.AdditionalDependencies);$(MSBuildProjectFile)"
|
||||
Outputs="$(QtToolOutDir)%(QtMoc.RelativeDir)moc_%(QtMoc.Filename).cpp">
|
||||
<Message Text="moc %(QtMoc.Filename) $(QtToolOutDir)%(QtMoc.RelativeDir)moc_%(QtMoc.Filename).cpp" Importance="High" />
|
||||
<Error Condition="!$(QtDirValid)" Text="QTDIR not set or non-existent (pull the submodule?)" />
|
||||
<MakeDir Directories="$(QtToolOutDir)" />
|
||||
<Exec Command=""$(QtHostBinDir)moc.exe" "%(QtMoc.FullPath)" -b "PrecompiledHeader.h" -o "$(QtToolOutDir)%(QtMoc.RelativeDir)moc_%(QtMoc.Filename).cpp" -f%(QtMoc.Filename)%(QtMoc.Extension) $(MocDefines) $(MocIncludes)" />
|
||||
</Target>
|
||||
|
||||
<ItemGroup>
|
||||
<MocOutputs Include="$(QtToolOutDir)moc_*.cpp" />
|
||||
</ItemGroup>
|
||||
<Target Name="QtMocClean">
|
||||
<Delete Files="@(MocOutputs)" />
|
||||
</Target>
|
||||
|
||||
<!--Expose the new targets to VS-->
|
||||
<ItemGroup>
|
||||
<PropertyPageSchema Include="$(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml" />
|
||||
<AvailableItemName Include="QtResource">
|
||||
<Targets>QtResource</Targets>
|
||||
</AvailableItemName>
|
||||
<AvailableItemName Include="QtUi">
|
||||
<Targets>QtUi</Targets>
|
||||
</AvailableItemName>
|
||||
<AvailableItemName Include="QtMoc">
|
||||
<Targets>QtMoc</Targets>
|
||||
</AvailableItemName>
|
||||
<AvailableItemName Include="QtTs">
|
||||
<Targets>QtTs</Targets>
|
||||
</AvailableItemName>
|
||||
</ItemGroup>
|
||||
|
||||
<!--Copy the needed dlls-->
|
||||
<ItemGroup>
|
||||
<QtLibNames Include="Qt6Core$(QtLibSuffix);Qt6Gui$(QtLibSuffix);Qt6Widgets$(QtLibSuffix);Qt6Network$(QtLibSuffix);Qt6Svg$(QtLibSuffix)" />
|
||||
<QtDlls Include="@(QtLibNames -> '$(QtBinDir)%(Identity).dll')" />
|
||||
<!--Filter plugins to copy based on the observation that all debug versions end in "d"-->
|
||||
<QtAllPlugins Include="$(QtPluginsDir)**\*$(QtLibSuffix).dll" />
|
||||
<QtPlugins Condition="$(Configuration.Contains(Debug))" Include="@(QtAllPlugins)" />
|
||||
<QtPlugins Condition="!$(Configuration.Contains(Debug))" Exclude="$(QtPluginsDir)**\*$(QtDebugSuffix).dll" Include="@(QtAllPlugins)" />
|
||||
<QtPluginsDest Include="@(QtPlugins -> '$(BinaryOutputDir)$(QtPluginFolder)\%(RecursiveDir)%(Filename)%(Extension)')" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<QtConfFile>$(BinaryOutputDir)qt.conf</QtConfFile>
|
||||
</PropertyGroup>
|
||||
<Target Name="QtCopyBinaries"
|
||||
AfterTargets="Build"
|
||||
Inputs="@(QtDlls);@(QtPlugins)"
|
||||
Outputs="@(QtDlls -> '$(BinaryOutputDir)%(RecursiveDir)%(Filename)%(Extension)');@(QtPlugins -> '$(BinaryOutputDir)$(QtPluginFolder)\%(RecursiveDir)%(Filename)%(Extension)')">
|
||||
<Message Text="Copying Qt .dlls" Importance="High" />
|
||||
<Copy
|
||||
SourceFiles="@(QtDlls)"
|
||||
DestinationFolder="$(BinaryOutputDir)"
|
||||
SkipUnchangedFiles="true"
|
||||
/>
|
||||
<Copy
|
||||
SourceFiles="@(QtPlugins)"
|
||||
DestinationFiles="@(QtPluginsDest)"
|
||||
SkipUnchangedFiles="true"
|
||||
/>
|
||||
</Target>
|
||||
<Target Name="QtCreateConf"
|
||||
BeforeTargets="QtCopyBinaries"
|
||||
Condition="!Exists('$(QtConfFile)')">
|
||||
<!--
|
||||
Create a file which tells Qt where to look for "plugins".
|
||||
Otherwise Qt only looks in ./<subtype>/type.dll instead of ./$(QtPluginFolder)/<subtype>/type.dll, which is messy
|
||||
-->
|
||||
<WriteLinesToFile
|
||||
File="$(QtConfFile)"
|
||||
Lines="[Paths];Plugins = ./$(QtPluginFolder)"
|
||||
Overwrite="true"
|
||||
/>
|
||||
</Target>
|
||||
|
||||
<!--Copies base translation files-->
|
||||
<ItemGroup>
|
||||
<BaseTsFiles Include="$(QtTranslationsDir)\*.qm" />
|
||||
</ItemGroup>
|
||||
<Target Name="QtCopyBaseTranslations"
|
||||
AfterTargets="Build"
|
||||
Inputs="@(BaseTsFiles)"
|
||||
Outputs="@(BaseTsFiles -> '$(QtTsOutDir)%(RecursiveDir)%(Filename)%(Extension)')">
|
||||
<Message Text="Copying base translation files" Importance="High" />
|
||||
<Copy
|
||||
SourceFiles="@(BaseTsFiles)"
|
||||
DestinationFolder="$(QtTsOutDir)"
|
||||
SkipUnchangedFiles="true"
|
||||
/>
|
||||
</Target>
|
||||
|
||||
<!--Compiles all translation files-->
|
||||
<ItemGroup>
|
||||
<TsFiles Include="$(MSBuildProjectDirectory)\**\*.ts" />
|
||||
</ItemGroup>
|
||||
<Target Name="QtTs"
|
||||
BeforeTargets="ClCompile"
|
||||
Inputs="@(TsFiles)"
|
||||
Condition="'@(QtTs)'!=''"
|
||||
Outputs="@(TsFiles->'$(QtTsOutDir)%(Filename).qm')">
|
||||
<Message Text="lrelease %(TsFiles.Filename)" Importance="High" />
|
||||
<Error Condition="!$(QtDirValid)" Text="QTDIR not valid (download/extract the zip)" />
|
||||
<MakeDir Directories="$(QtTsOutDir)" />
|
||||
<Exec Command=""$(QtHostBinDir)lrelease.exe" "%(TsFiles.FullPath)" -qm "$(QtTsOutDir)%(TsFiles.Filename).qm"" />
|
||||
</Target>
|
||||
<ItemGroup>
|
||||
<TsOutputs Include="$(QtTsOutDir)*.qm" />
|
||||
</ItemGroup>
|
||||
<Target Name="QtTsClean">
|
||||
<Delete Files="@(TsOutputs)" />
|
||||
</Target>
|
||||
</Project>
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<CleanDependsOn>QtResourceClean;QtUiClean;QtMocClean;QtTsClean;$(CleanDependsOn)</CleanDependsOn>
|
||||
<!--
|
||||
<ComputeLinkInputsTargets>$(ComputeLinkInputsTargets);QtComputeMocOutput;</ComputeLinkInputsTargets>
|
||||
<ComputeLibInputsTargets>$(ComputeLibInputsTargets);QtComputeMocOutput;</ComputeLibInputsTargets>
|
||||
-->
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ProjectSchemaDefinitions xmlns="http://schemas.microsoft.com/build/2009/properties">
|
||||
<ItemType Name="QtResource" DisplayName="Qt Resource File" />
|
||||
<ItemType Name="QtUi" DisplayName="Qt User Interface File" />
|
||||
<ItemType Name="QtMoc" DisplayName="Qt Meta Object File" />
|
||||
<ItemType Name="QtTs" DisplayName="Qt Translation File" />
|
||||
<ContentType Name="QtUi" DisplayName="Qt User Interface Compiler" />
|
||||
<ContentType Name="QtResource" DisplayName="Qt Resource Compiler" />
|
||||
<ContentType Name="QtMoc" DisplayName="Qt Meta Object Compiler" />
|
||||
<ContentType Name="QtTs" DisplayName="Qt Translation Compiler" />
|
||||
<FileExtension Name="*.qrc" ContentType="QtResource" />
|
||||
<FileExtension Name="*.ui" ContentType="QtUi" />
|
||||
<FileExtension Name="*.ts" ContentType="QtTs" />
|
||||
</ProjectSchemaDefinitions>
|
|
@ -0,0 +1,76 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "AboutDialog.h"
|
||||
#include "QtUtils.h"
|
||||
#include "svnrev.h"
|
||||
#include <QtCore/QString>
|
||||
#include <QtWidgets/QDialog>
|
||||
|
||||
AboutDialog::AboutDialog(QWidget* parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
setFixedSize(geometry().width(), geometry().height());
|
||||
|
||||
m_ui.scmversion->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
m_ui.scmversion->setText(GIT_REV);
|
||||
|
||||
m_ui.links->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
m_ui.links->setOpenExternalLinks(true);
|
||||
m_ui.links->setText(QStringLiteral(
|
||||
R"(<a href="%1">%2</a> | <a href="%3">%4</a> | <a href="%5">%6</a> | <a href="%7">%8</a>)")
|
||||
.arg(getWebsiteUrl())
|
||||
.arg(tr("Website"))
|
||||
.arg(getSupportForumsUrl())
|
||||
.arg(tr("Support Forums"))
|
||||
.arg(getGitHubRepositoryUrl())
|
||||
.arg(tr("GitHub Repository"))
|
||||
.arg(getLicenseUrl())
|
||||
.arg(tr("License")));
|
||||
|
||||
connect(m_ui.buttonBox, &QDialogButtonBox::rejected, this, &QDialog::close);
|
||||
}
|
||||
|
||||
AboutDialog::~AboutDialog() = default;
|
||||
|
||||
QString AboutDialog::getWebsiteUrl()
|
||||
{
|
||||
return QStringLiteral("https://pcsx2.net/");
|
||||
}
|
||||
|
||||
QString AboutDialog::getSupportForumsUrl()
|
||||
{
|
||||
return QStringLiteral("https://forums.pcsx2.net/");
|
||||
}
|
||||
|
||||
QString AboutDialog::getGitHubRepositoryUrl()
|
||||
{
|
||||
return QStringLiteral("https://github.com/PCSX2/pcsx2");
|
||||
}
|
||||
|
||||
QString AboutDialog::getLicenseUrl()
|
||||
{
|
||||
return QStringLiteral("https://github.com/PCSX2/pcsx2/blob/master/pcsx2/Docs/License.txt");
|
||||
}
|
||||
|
||||
QString AboutDialog::getDiscordServerUrl()
|
||||
{
|
||||
return QStringLiteral("https://discord.com/invite/TCz3t9k");
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ui_AboutDialog.h"
|
||||
#include <QtWidgets/QDialog>
|
||||
|
||||
class AboutDialog final : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AboutDialog(QWidget* parent = nullptr);
|
||||
~AboutDialog();
|
||||
|
||||
static QString getWebsiteUrl();
|
||||
static QString getSupportForumsUrl();
|
||||
static QString getGitHubRepositoryUrl();
|
||||
static QString getLicenseUrl();
|
||||
static QString getDiscordServerUrl();
|
||||
|
||||
private:
|
||||
Ui::AboutDialog m_ui;
|
||||
};
|
|
@ -0,0 +1,168 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AboutDialog</class>
|
||||
<widget class="QDialog" name="AboutDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>576</width>
|
||||
<height>294</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>About PCSX2</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="icon">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>260</width>
|
||||
<height>260</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="resources/resources.qrc">:/icons/logo.png</pixmap>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="scmversion">
|
||||
<property name="text">
|
||||
<string>SCM Version</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="description">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>PCSX2 is a free and open-source PlayStation 2 (PS2) emulator. Its purpose is to emulate the PS2's hardware, using a combination of MIPS CPU Interpreters, Recompilers and a Virtual Machine which manages hardware states and PS2 system memory. This allows you to play PS2 games on your PC, with many additional features and benefits.</p></body></html></string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignJustify|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="disclaimer">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>PlayStation 2 and PS2 are registered trademarks of Sony Interactive Entertainment. This application is not affiliated in any way with Sony Interactive Entertainment.</p></body></html></string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignJustify|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="links">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close</set>
|
||||
</property>
|
||||
<property name="centerButtons">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="resources/resources.qrc"/>
|
||||
<include location="resources/icons.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,102 @@
|
|||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
|
||||
add_executable(pcsx2-qt)
|
||||
|
||||
if (PACKAGE_MODE)
|
||||
install(TARGETS pcsx2-qt DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
else()
|
||||
install(TARGETS pcsx2-qt DESTINATION ${CMAKE_SOURCE_DIR}/bin)
|
||||
endif()
|
||||
|
||||
target_sources(pcsx2-qt PRIVATE
|
||||
AboutDialog.cpp
|
||||
AboutDialog.h
|
||||
AboutDialog.ui
|
||||
DisplayWidget.cpp
|
||||
DisplayWidget.h
|
||||
EmuThread.cpp
|
||||
EmuThread.h
|
||||
Main.cpp
|
||||
MainWindow.cpp
|
||||
MainWindow.h
|
||||
MainWindow.ui
|
||||
PrecompiledHeader.cpp
|
||||
PrecompiledHeader.h
|
||||
QtHost.cpp
|
||||
QtHost.h
|
||||
QtKeyCodes.cpp
|
||||
QtUtils.cpp
|
||||
QtUtils.h
|
||||
SettingWidgetBinder.h
|
||||
GameList/GameListModel.cpp
|
||||
GameList/GameListModel.h
|
||||
GameList/GameListRefreshThread.cpp
|
||||
GameList/GameListRefreshThread.h
|
||||
GameList/GameListWidget.cpp
|
||||
GameList/GameListWidget.h
|
||||
Settings/AdvancedSystemSettingsWidget.cpp
|
||||
Settings/AdvancedSystemSettingsWidget.h
|
||||
Settings/AdvancedSystemSettingsWidget.ui
|
||||
Settings/BIOSSettingsWidget.cpp
|
||||
Settings/BIOSSettingsWidget.h
|
||||
Settings/BIOSSettingsWidget.ui
|
||||
Settings/ControllerBindingWidget.ui
|
||||
Settings/ControllerBindingWidget_DualShock2.ui
|
||||
Settings/ControllerBindingWidgets.cpp
|
||||
Settings/ControllerBindingWidgets.h
|
||||
Settings/ControllerGlobalSettingsWidget.cpp
|
||||
Settings/ControllerGlobalSettingsWidget.h
|
||||
Settings/ControllerGlobalSettingsWidget.ui
|
||||
Settings/ControllerSettingsDialog.cpp
|
||||
Settings/ControllerSettingsDialog.h
|
||||
Settings/ControllerSettingsDialog.ui
|
||||
Settings/EmulationSettingsWidget.cpp
|
||||
Settings/EmulationSettingsWidget.h
|
||||
Settings/EmulationSettingsWidget.ui
|
||||
Settings/GameFixSettingsWidget.cpp
|
||||
Settings/GameFixSettingsWidget.h
|
||||
Settings/GameFixSettingsWidget.ui
|
||||
Settings/GameListSettingsWidget.cpp
|
||||
Settings/GameListSettingsWidget.h
|
||||
Settings/GameListSettingsWidget.ui
|
||||
Settings/GraphicsSettingsWidget.cpp
|
||||
Settings/GraphicsSettingsWidget.h
|
||||
Settings/GraphicsSettingsWidget.ui
|
||||
Settings/HotkeySettingsWidget.cpp
|
||||
Settings/HotkeySettingsWidget.h
|
||||
Settings/InputBindingDialog.cpp
|
||||
Settings/InputBindingDialog.h
|
||||
Settings/InputBindingDialog.ui
|
||||
Settings/InputBindingWidget.cpp
|
||||
Settings/InputBindingWidget.h
|
||||
Settings/InterfaceSettingsWidget.cpp
|
||||
Settings/InterfaceSettingsWidget.h
|
||||
Settings/InterfaceSettingsWidget.ui
|
||||
Settings/SettingsDialog.cpp
|
||||
Settings/SettingsDialog.h
|
||||
Settings/SettingsDialog.ui
|
||||
Settings/SystemSettingsWidget.cpp
|
||||
Settings/SystemSettingsWidget.h
|
||||
Settings/SystemSettingsWidget.ui
|
||||
resources/resources.qrc
|
||||
)
|
||||
|
||||
target_precompile_headers(pcsx2-qt PRIVATE PrecompiledHeader.h)
|
||||
|
||||
target_include_directories(pcsx2-qt PRIVATE
|
||||
${Qt6Gui_PRIVATE_INCLUDE_DIRS}
|
||||
"${CMAKE_BINARY_DIR}/common/include"
|
||||
"${CMAKE_SOURCE_DIR}/pcsx2"
|
||||
"${CMAKE_SOURCE_DIR}/pcsx2-qt"
|
||||
)
|
||||
|
||||
target_link_libraries(pcsx2-qt PRIVATE
|
||||
PCSX2_FLAGS
|
||||
PCSX2
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
Qt6::Network
|
||||
)
|
|
@ -0,0 +1,334 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "DisplayWidget.h"
|
||||
#include "EmuThread.h"
|
||||
#include "QtHost.h"
|
||||
|
||||
#include "pcsx2/GS/GSIntrin.h" // _BitScanForward
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtGui/QKeyEvent>
|
||||
#include <QtGui/QScreen>
|
||||
#include <QtGui/QWindow>
|
||||
#include <QtGui/QWindowStateChangeEvent>
|
||||
#include <cmath>
|
||||
|
||||
#if !defined(_WIN32) && !defined(APPLE)
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
#endif
|
||||
|
||||
DisplayWidget::DisplayWidget(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
// We want a native window for both D3D and OpenGL.
|
||||
setAutoFillBackground(false);
|
||||
setAttribute(Qt::WA_NativeWindow, true);
|
||||
setAttribute(Qt::WA_NoSystemBackground, true);
|
||||
setAttribute(Qt::WA_PaintOnScreen, true);
|
||||
setFocusPolicy(Qt::StrongFocus);
|
||||
setMouseTracking(true);
|
||||
}
|
||||
|
||||
DisplayWidget::~DisplayWidget() = default;
|
||||
|
||||
qreal DisplayWidget::devicePixelRatioFromScreen() const
|
||||
{
|
||||
QScreen* screen_for_ratio;
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||
screen_for_ratio = windowHandle()->screen();
|
||||
#else
|
||||
screen_for_ratio = screen();
|
||||
#endif
|
||||
if (!screen_for_ratio)
|
||||
screen_for_ratio = QGuiApplication::primaryScreen();
|
||||
|
||||
return screen_for_ratio ? screen_for_ratio->devicePixelRatio() : static_cast<qreal>(1);
|
||||
}
|
||||
|
||||
int DisplayWidget::scaledWindowWidth() const
|
||||
{
|
||||
return static_cast<int>(std::ceil(static_cast<qreal>(width()) * devicePixelRatioFromScreen()));
|
||||
}
|
||||
|
||||
int DisplayWidget::scaledWindowHeight() const
|
||||
{
|
||||
return static_cast<int>(std::ceil(static_cast<qreal>(height()) * devicePixelRatioFromScreen()));
|
||||
}
|
||||
|
||||
std::optional<WindowInfo> DisplayWidget::getWindowInfo() const
|
||||
{
|
||||
WindowInfo wi;
|
||||
|
||||
// Windows and Apple are easy here since there's no display connection.
|
||||
#if defined(_WIN32)
|
||||
wi.type = WindowInfo::Type::Win32;
|
||||
wi.window_handle = reinterpret_cast<void*>(winId());
|
||||
#elif defined(__APPLE__)
|
||||
wi.type = WindowInfo::Type::MacOS;
|
||||
wi.window_handle = reinterpret_cast<void*>(winId());
|
||||
#else
|
||||
QPlatformNativeInterface* pni = QGuiApplication::platformNativeInterface();
|
||||
const QString platform_name = QGuiApplication::platformName();
|
||||
if (platform_name == QStringLiteral("xcb"))
|
||||
{
|
||||
wi.type = WindowInfo::Type::X11;
|
||||
wi.display_connection = pni->nativeResourceForWindow("display", windowHandle());
|
||||
wi.window_handle = reinterpret_cast<void*>(winId());
|
||||
}
|
||||
else if (platform_name == QStringLiteral("wayland"))
|
||||
{
|
||||
wi.type = WindowInfo::Type::Wayland;
|
||||
wi.display_connection = pni->nativeResourceForWindow("display", windowHandle());
|
||||
wi.window_handle = pni->nativeResourceForWindow("surface", windowHandle());
|
||||
}
|
||||
else
|
||||
{
|
||||
qCritical() << "Unknown PNI platform " << platform_name;
|
||||
return std::nullopt;
|
||||
}
|
||||
#endif
|
||||
|
||||
wi.surface_width = scaledWindowWidth();
|
||||
wi.surface_height = scaledWindowHeight();
|
||||
wi.surface_scale = devicePixelRatioFromScreen();
|
||||
return wi;
|
||||
}
|
||||
|
||||
void DisplayWidget::setRelativeMode(bool enabled)
|
||||
{
|
||||
if (m_relative_mouse_enabled == enabled)
|
||||
return;
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
m_relative_mouse_start_position = QCursor::pos();
|
||||
|
||||
const QPoint center_pos = mapToGlobal(QPoint(width() / 2, height() / 2));
|
||||
QCursor::setPos(center_pos);
|
||||
m_relative_mouse_last_position = center_pos;
|
||||
grabMouse();
|
||||
}
|
||||
else
|
||||
{
|
||||
QCursor::setPos(m_relative_mouse_start_position);
|
||||
releaseMouse();
|
||||
}
|
||||
|
||||
m_relative_mouse_enabled = enabled;
|
||||
}
|
||||
|
||||
QPaintEngine* DisplayWidget::paintEngine() const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool DisplayWidget::event(QEvent* event)
|
||||
{
|
||||
switch (event->type())
|
||||
{
|
||||
case QEvent::KeyPress:
|
||||
case QEvent::KeyRelease:
|
||||
{
|
||||
const QKeyEvent* key_event = static_cast<QKeyEvent*>(event);
|
||||
if (!key_event->isAutoRepeat())
|
||||
{
|
||||
emit windowKeyEvent(key_event->key(), static_cast<int>(key_event->modifiers()),
|
||||
event->type() == QEvent::KeyPress);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
case QEvent::MouseMove:
|
||||
{
|
||||
const QMouseEvent* mouse_event = static_cast<QMouseEvent*>(event);
|
||||
|
||||
if (!m_relative_mouse_enabled)
|
||||
{
|
||||
const qreal dpr = devicePixelRatioFromScreen();
|
||||
const QPoint mouse_pos = mouse_event->pos();
|
||||
const int scaled_x = static_cast<int>(static_cast<qreal>(mouse_pos.x()) * dpr);
|
||||
const int scaled_y = static_cast<int>(static_cast<qreal>(mouse_pos.y()) * dpr);
|
||||
|
||||
windowMouseMoveEvent(scaled_x, scaled_y);
|
||||
}
|
||||
else
|
||||
{
|
||||
const QPoint center_pos = mapToGlobal(QPoint((width() + 1) / 2, (height() + 1) / 2));
|
||||
const QPoint mouse_pos = mapToGlobal(mouse_event->pos());
|
||||
|
||||
const int dx = mouse_pos.x() - center_pos.x();
|
||||
const int dy = mouse_pos.y() - center_pos.y();
|
||||
m_relative_mouse_last_position.setX(m_relative_mouse_last_position.x() + dx);
|
||||
m_relative_mouse_last_position.setY(m_relative_mouse_last_position.y() + dy);
|
||||
windowMouseMoveEvent(m_relative_mouse_last_position.x(), m_relative_mouse_last_position.y());
|
||||
QCursor::setPos(center_pos);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
case QEvent::MouseButtonPress:
|
||||
case QEvent::MouseButtonDblClick:
|
||||
case QEvent::MouseButtonRelease:
|
||||
{
|
||||
unsigned long button_index;
|
||||
if (_BitScanForward(&button_index, static_cast<u32>(static_cast<const QMouseEvent*>(event)->button())))
|
||||
emit windowMouseButtonEvent(static_cast<int>(button_index + 1u), event->type() != QEvent::MouseButtonRelease);
|
||||
|
||||
if (event->type() == QEvent::MouseButtonDblClick &&
|
||||
static_cast<const QMouseEvent*>(event)->button() == Qt::LeftButton &&
|
||||
Host::GetBoolSettingValue("UI", "DoubleClickTogglesFullscreen", true))
|
||||
{
|
||||
g_emu_thread->toggleFullscreen();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
case QEvent::Wheel:
|
||||
{
|
||||
const QWheelEvent* wheel_event = static_cast<QWheelEvent*>(event);
|
||||
emit windowMouseWheelEvent(wheel_event->angleDelta());
|
||||
return true;
|
||||
}
|
||||
|
||||
case QEvent::Resize:
|
||||
{
|
||||
QWidget::event(event);
|
||||
|
||||
emit windowResizedEvent(scaledWindowWidth(), scaledWindowHeight(), devicePixelRatioFromScreen());
|
||||
return true;
|
||||
}
|
||||
|
||||
case QEvent::Close:
|
||||
{
|
||||
emit windowClosedEvent();
|
||||
QWidget::event(event);
|
||||
return true;
|
||||
}
|
||||
|
||||
case QEvent::WindowStateChange:
|
||||
{
|
||||
QWidget::event(event);
|
||||
|
||||
if (static_cast<QWindowStateChangeEvent*>(event)->oldState() & Qt::WindowMinimized)
|
||||
emit windowRestoredEvent();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
case QEvent::FocusIn:
|
||||
{
|
||||
QWidget::event(event);
|
||||
emit windowFocusEvent();
|
||||
return true;
|
||||
}
|
||||
|
||||
case QEvent::ActivationChange:
|
||||
{
|
||||
QWidget::event(event);
|
||||
if (isActiveWindow())
|
||||
emit windowFocusEvent();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
default:
|
||||
return QWidget::event(event);
|
||||
}
|
||||
}
|
||||
|
||||
DisplayContainer::DisplayContainer()
|
||||
: QStackedWidget(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
DisplayContainer::~DisplayContainer() = default;
|
||||
|
||||
bool DisplayContainer::IsNeeded(bool fullscreen, bool render_to_main)
|
||||
{
|
||||
#if defined(_WIN32) || defined(__APPLE__)
|
||||
return false;
|
||||
#else
|
||||
if (fullscreen || render_to_main)
|
||||
return false;
|
||||
|
||||
// We only need this on Wayland because of client-side decorations...
|
||||
const QString platform_name = QGuiApplication::platformName();
|
||||
return (platform_name == QStringLiteral("wayland"));
|
||||
#endif
|
||||
}
|
||||
|
||||
void DisplayContainer::setDisplayWidget(DisplayWidget* widget)
|
||||
{
|
||||
pxAssert(!m_display_widget);
|
||||
m_display_widget = widget;
|
||||
addWidget(widget);
|
||||
}
|
||||
|
||||
DisplayWidget* DisplayContainer::removeDisplayWidget()
|
||||
{
|
||||
DisplayWidget* widget = m_display_widget;
|
||||
pxAssert(widget);
|
||||
m_display_widget = nullptr;
|
||||
removeWidget(widget);
|
||||
return widget;
|
||||
}
|
||||
|
||||
bool DisplayContainer::event(QEvent* event)
|
||||
{
|
||||
const bool res = QStackedWidget::event(event);
|
||||
if (!m_display_widget)
|
||||
return res;
|
||||
|
||||
switch (event->type())
|
||||
{
|
||||
case QEvent::Close:
|
||||
{
|
||||
emit m_display_widget->windowClosedEvent();
|
||||
}
|
||||
break;
|
||||
|
||||
case QEvent::WindowStateChange:
|
||||
{
|
||||
if (static_cast<QWindowStateChangeEvent*>(event)->oldState() & Qt::WindowMinimized)
|
||||
emit m_display_widget->windowRestoredEvent();
|
||||
}
|
||||
break;
|
||||
|
||||
case QEvent::FocusIn:
|
||||
{
|
||||
emit m_display_widget->windowFocusEvent();
|
||||
}
|
||||
break;
|
||||
|
||||
case QEvent::ActivationChange:
|
||||
{
|
||||
if (isActiveWindow())
|
||||
emit m_display_widget->windowFocusEvent();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "common/WindowInfo.h"
|
||||
#include <QtWidgets/QStackedWidget>
|
||||
#include <QtWidgets/QWidget>
|
||||
#include <optional>
|
||||
|
||||
class DisplayWidget final : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DisplayWidget(QWidget* parent);
|
||||
~DisplayWidget();
|
||||
|
||||
QPaintEngine* paintEngine() const override;
|
||||
|
||||
int scaledWindowWidth() const;
|
||||
int scaledWindowHeight() const;
|
||||
qreal devicePixelRatioFromScreen() const;
|
||||
|
||||
std::optional<WindowInfo> getWindowInfo() const;
|
||||
|
||||
void setRelativeMode(bool enabled);
|
||||
|
||||
Q_SIGNALS:
|
||||
void windowFocusEvent();
|
||||
void windowResizedEvent(int width, int height, float scale);
|
||||
void windowRestoredEvent();
|
||||
void windowClosedEvent();
|
||||
void windowKeyEvent(int key_code, int mods, bool pressed);
|
||||
void windowMouseMoveEvent(int x, int y);
|
||||
void windowMouseButtonEvent(int button, bool pressed);
|
||||
void windowMouseWheelEvent(const QPoint& angle_delta);
|
||||
|
||||
protected:
|
||||
bool event(QEvent* event) override;
|
||||
|
||||
private:
|
||||
QPoint m_relative_mouse_start_position{};
|
||||
QPoint m_relative_mouse_last_position{};
|
||||
bool m_relative_mouse_enabled = false;
|
||||
};
|
||||
|
||||
class DisplayContainer final : public QStackedWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DisplayContainer();
|
||||
~DisplayContainer();
|
||||
|
||||
static bool IsNeeded(bool fullscreen, bool render_to_main);
|
||||
|
||||
void setDisplayWidget(DisplayWidget* widget);
|
||||
DisplayWidget* removeDisplayWidget();
|
||||
|
||||
protected:
|
||||
bool event(QEvent* event) override;
|
||||
|
||||
private:
|
||||
DisplayWidget* m_display_widget = nullptr;
|
||||
};
|
|
@ -0,0 +1,755 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include <QtWidgets/QApplication>
|
||||
|
||||
#include "common/Assertions.h"
|
||||
#include "common/Console.h"
|
||||
#include "common/Exceptions.h"
|
||||
#include "common/SettingsWrapper.h"
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
#include "pcsx2/CDVD/CDVD.h"
|
||||
#include "pcsx2/Frontend/InputManager.h"
|
||||
#include "pcsx2/Frontend/ImGuiManager.h"
|
||||
#include "pcsx2/GS.h"
|
||||
#include "pcsx2/HostDisplay.h"
|
||||
#include "pcsx2/PAD/Host/PAD.h"
|
||||
#include "pcsx2/PerformanceMetrics.h"
|
||||
#include "pcsx2/VMManager.h"
|
||||
|
||||
#include "pcsx2/Frontend/OpenGLHostDisplay.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "pcsx2/Frontend/D3D11HostDisplay.h"
|
||||
#endif
|
||||
|
||||
#include "DisplayWidget.h"
|
||||
#include "EmuThread.h"
|
||||
#include "MainWindow.h"
|
||||
#include "QtHost.h"
|
||||
|
||||
EmuThread* g_emu_thread = nullptr;
|
||||
WindowInfo g_gs_window_info;
|
||||
|
||||
static std::unique_ptr<HostDisplay> s_host_display;
|
||||
|
||||
EmuThread::EmuThread(QThread* ui_thread)
|
||||
: QThread()
|
||||
, m_ui_thread(ui_thread)
|
||||
{
|
||||
}
|
||||
|
||||
EmuThread::~EmuThread() = default;
|
||||
|
||||
bool EmuThread::isOnEmuThread() const
|
||||
{
|
||||
return QThread::currentThread() == this;
|
||||
}
|
||||
|
||||
void EmuThread::start()
|
||||
{
|
||||
pxAssertRel(!g_emu_thread, "Emu thread does not exist");
|
||||
|
||||
g_emu_thread = new EmuThread(QThread::currentThread());
|
||||
g_emu_thread->QThread::start();
|
||||
g_emu_thread->m_started_semaphore.acquire();
|
||||
g_emu_thread->moveToThread(g_emu_thread);
|
||||
g_main_window->connectVMThreadSignals(g_emu_thread);
|
||||
}
|
||||
|
||||
void EmuThread::stop()
|
||||
{
|
||||
pxAssertRel(g_emu_thread, "Emu thread exists");
|
||||
pxAssertRel(!g_emu_thread->isOnEmuThread(), "Not called on the emu thread");
|
||||
|
||||
QMetaObject::invokeMethod(g_emu_thread, &EmuThread::stopInThread, Qt::QueuedConnection);
|
||||
while (g_emu_thread->isRunning())
|
||||
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 1);
|
||||
}
|
||||
|
||||
void EmuThread::stopInThread()
|
||||
{
|
||||
if (VMManager::HasValidVM())
|
||||
destroyVM();
|
||||
|
||||
m_event_loop->quit();
|
||||
m_shutdown_flag.store(true);
|
||||
}
|
||||
|
||||
void EmuThread::startVM(std::shared_ptr<VMBootParameters> boot_params)
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "startVM", Qt::QueuedConnection,
|
||||
Q_ARG(std::shared_ptr<VMBootParameters>, boot_params));
|
||||
return;
|
||||
}
|
||||
|
||||
pxAssertRel(!VMManager::HasValidVM(), "VM is shut down");
|
||||
|
||||
emit onVMStarting();
|
||||
|
||||
// create the display, this may take a while...
|
||||
m_is_fullscreen = boot_params->fullscreen.value_or(QtHost::GetBaseBoolSettingValue("UI", "StartFullscreen", false));
|
||||
m_is_rendering_to_main = !m_is_fullscreen && QtHost::GetBaseBoolSettingValue("UI", "RenderToMainWindow", true);
|
||||
if (!VMManager::Initialize(*boot_params))
|
||||
return;
|
||||
|
||||
VMManager::SetState(VMState::Running);
|
||||
m_event_loop->quit();
|
||||
}
|
||||
|
||||
void EmuThread::resetVM()
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, &EmuThread::resetVM, Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
|
||||
VMManager::Reset();
|
||||
}
|
||||
|
||||
void EmuThread::setVMPaused(bool paused)
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "setVMPaused", Qt::QueuedConnection, Q_ARG(bool, paused));
|
||||
return;
|
||||
}
|
||||
|
||||
VMManager::SetPaused(paused);
|
||||
}
|
||||
|
||||
void EmuThread::shutdownVM(bool allow_save_to_state /* = true */, bool blocking /* = false */)
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "shutdownVM", Qt::QueuedConnection, Q_ARG(bool, allow_save_to_state),
|
||||
Q_ARG(bool, blocking));
|
||||
|
||||
if (blocking)
|
||||
{
|
||||
// we need to yield here, since the display gets destroyed
|
||||
while (VMManager::HasValidVM())
|
||||
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 1);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const VMState state = VMManager::GetState();
|
||||
if (state == VMState::Paused)
|
||||
m_event_loop->quit();
|
||||
else if (state != VMState::Running)
|
||||
return;
|
||||
|
||||
VMManager::SetState(VMState::Stopping);
|
||||
}
|
||||
|
||||
void EmuThread::loadState(const QString& filename)
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "loadState", Qt::QueuedConnection, Q_ARG(const QString&, filename));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!VMManager::HasValidVM())
|
||||
return;
|
||||
|
||||
VMManager::LoadState(filename.toUtf8().constData());
|
||||
}
|
||||
|
||||
void EmuThread::loadStateFromSlot(qint32 slot)
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "loadStateFromSlot", Qt::QueuedConnection, Q_ARG(qint32, slot));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!VMManager::HasValidVM())
|
||||
return;
|
||||
|
||||
VMManager::LoadStateFromSlot(slot);
|
||||
}
|
||||
|
||||
void EmuThread::saveState(const QString& filename)
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "saveState", Qt::QueuedConnection, Q_ARG(const QString&, filename));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!VMManager::HasValidVM())
|
||||
return;
|
||||
|
||||
if (!VMManager::SaveState(filename.toUtf8().constData()))
|
||||
{
|
||||
// this one is usually the result of a user-chosen path, so we can display a message box safely here
|
||||
Console.Error("Failed to save state");
|
||||
}
|
||||
}
|
||||
|
||||
void EmuThread::saveStateToSlot(qint32 slot)
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "saveStateToSlot", Qt::QueuedConnection, Q_ARG(qint32, slot));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!VMManager::HasValidVM())
|
||||
return;
|
||||
|
||||
VMManager::SaveStateToSlot(slot);
|
||||
}
|
||||
|
||||
void EmuThread::run()
|
||||
{
|
||||
PerformanceMetrics::SetCPUThreadTimer(Common::ThreadCPUTimer::GetForCallingThread());
|
||||
m_event_loop = new QEventLoop();
|
||||
m_started_semaphore.release();
|
||||
|
||||
if (!VMManager::InitializeMemory())
|
||||
pxFailRel("Failed to allocate memory map");
|
||||
|
||||
// we need input sources ready for binding
|
||||
reloadInputSources();
|
||||
createBackgroundControllerPollTimer();
|
||||
startBackgroundControllerPollTimer();
|
||||
|
||||
while (!m_shutdown_flag.load())
|
||||
{
|
||||
if (!VMManager::HasValidVM())
|
||||
{
|
||||
m_event_loop->exec();
|
||||
continue;
|
||||
}
|
||||
|
||||
executeVM();
|
||||
}
|
||||
|
||||
stopBackgroundControllerPollTimer();
|
||||
destroyBackgroundControllerPollTimer();
|
||||
InputManager::CloseSources();
|
||||
VMManager::ReleaseMemory();
|
||||
PerformanceMetrics::SetCPUThreadTimer(Common::ThreadCPUTimer());
|
||||
moveToThread(m_ui_thread);
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
void EmuThread::destroyVM()
|
||||
{
|
||||
VMManager::Shutdown();
|
||||
}
|
||||
|
||||
void EmuThread::executeVM()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
switch (VMManager::GetState())
|
||||
{
|
||||
case VMState::Initializing:
|
||||
pxFailRel("Shouldn't be in the starting state state");
|
||||
continue;
|
||||
|
||||
case VMState::Paused:
|
||||
m_event_loop->exec();
|
||||
continue;
|
||||
|
||||
case VMState::Running:
|
||||
m_event_loop->processEvents(QEventLoop::AllEvents);
|
||||
VMManager::Execute();
|
||||
continue;
|
||||
|
||||
case VMState::Stopping:
|
||||
destroyVM();
|
||||
m_event_loop->processEvents(QEventLoop::AllEvents);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EmuThread::createBackgroundControllerPollTimer()
|
||||
{
|
||||
pxAssert(!m_background_controller_polling_timer);
|
||||
m_background_controller_polling_timer = new QTimer(this);
|
||||
m_background_controller_polling_timer->setSingleShot(false);
|
||||
m_background_controller_polling_timer->setTimerType(Qt::CoarseTimer);
|
||||
connect(m_background_controller_polling_timer, &QTimer::timeout, this, &EmuThread::doBackgroundControllerPoll);
|
||||
}
|
||||
|
||||
void EmuThread::destroyBackgroundControllerPollTimer()
|
||||
{
|
||||
delete m_background_controller_polling_timer;
|
||||
m_background_controller_polling_timer = nullptr;
|
||||
}
|
||||
|
||||
void EmuThread::startBackgroundControllerPollTimer()
|
||||
{
|
||||
if (m_background_controller_polling_timer->isActive())
|
||||
return;
|
||||
|
||||
m_background_controller_polling_timer->start(BACKGROUND_CONTROLLER_POLLING_INTERVAL);
|
||||
}
|
||||
|
||||
void EmuThread::stopBackgroundControllerPollTimer()
|
||||
{
|
||||
if (!m_background_controller_polling_timer->isActive())
|
||||
return;
|
||||
|
||||
m_background_controller_polling_timer->stop();
|
||||
}
|
||||
|
||||
void EmuThread::doBackgroundControllerPoll()
|
||||
{
|
||||
InputManager::PollSources();
|
||||
}
|
||||
|
||||
void EmuThread::toggleFullscreen()
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, &EmuThread::toggleFullscreen, Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
|
||||
setFullscreen(!m_is_fullscreen);
|
||||
}
|
||||
|
||||
void EmuThread::setFullscreen(bool fullscreen)
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "setFullscreen", Qt::QueuedConnection, Q_ARG(bool, fullscreen));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!VMManager::HasValidVM() || m_is_fullscreen == fullscreen)
|
||||
return;
|
||||
|
||||
// This will call back to us on the MTGS thread.
|
||||
m_is_fullscreen = fullscreen;
|
||||
GetMTGS().UpdateDisplayWindow();
|
||||
GetMTGS().WaitGS();
|
||||
}
|
||||
|
||||
void EmuThread::applySettings()
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, &EmuThread::applySettings, Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
|
||||
checkForSettingChanges();
|
||||
VMManager::ApplySettings();
|
||||
}
|
||||
|
||||
void EmuThread::checkForSettingChanges()
|
||||
{
|
||||
if (VMManager::HasValidVM())
|
||||
{
|
||||
const bool render_to_main = QtHost::GetBaseBoolSettingValue("UI", "RenderToMainWindow", true);
|
||||
if (!m_is_fullscreen && m_is_rendering_to_main != render_to_main)
|
||||
{
|
||||
m_is_rendering_to_main = render_to_main;
|
||||
GetMTGS().UpdateDisplayWindow();
|
||||
GetMTGS().WaitGS();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EmuThread::toggleSoftwareRendering()
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, &EmuThread::toggleSoftwareRendering, Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!VMManager::HasValidVM())
|
||||
return;
|
||||
|
||||
GetMTGS().ToggleSoftwareRendering();
|
||||
}
|
||||
|
||||
void EmuThread::switchRenderer(GSRendererType renderer)
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "switchRenderer", Qt::QueuedConnection, Q_ARG(GSRendererType, renderer));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!VMManager::HasValidVM())
|
||||
return;
|
||||
|
||||
GetMTGS().SwitchRenderer(renderer);
|
||||
}
|
||||
|
||||
void EmuThread::changeDisc(const QString& path)
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "changeDisc", Qt::QueuedConnection, Q_ARG(const QString&, path));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!VMManager::HasValidVM())
|
||||
return;
|
||||
|
||||
VMManager::ChangeDisc(path.toStdString());
|
||||
}
|
||||
|
||||
void EmuThread::reloadPatches()
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, &EmuThread::reloadPatches, Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!VMManager::HasValidVM())
|
||||
return;
|
||||
|
||||
VMManager::ReloadPatches(true);
|
||||
}
|
||||
|
||||
void EmuThread::reloadInputSources()
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, &EmuThread::reloadInputSources, Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = Host::GetSettingsLock();
|
||||
SettingsInterface* si = Host::GetSettingsInterface();
|
||||
InputManager::ReloadSources(*si);
|
||||
|
||||
// skip loading bindings if we're not running, since it'll get done on startup anyway
|
||||
if (VMManager::HasValidVM())
|
||||
InputManager::ReloadBindings(*si);
|
||||
}
|
||||
|
||||
void EmuThread::reloadInputBindings()
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, &EmuThread::reloadInputBindings, Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
|
||||
// skip loading bindings if we're not running, since it'll get done on startup anyway
|
||||
if (!VMManager::HasValidVM())
|
||||
return;
|
||||
|
||||
auto lock = Host::GetSettingsLock();
|
||||
SettingsInterface* si = Host::GetSettingsInterface();
|
||||
InputManager::ReloadBindings(*si);
|
||||
}
|
||||
|
||||
void EmuThread::requestDisplaySize(float scale)
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "requestDisplaySize", Qt::QueuedConnection, Q_ARG(float, scale));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!VMManager::HasValidVM())
|
||||
return;
|
||||
|
||||
VMManager::RequestDisplaySize(scale);
|
||||
}
|
||||
|
||||
void EmuThread::enumerateInputDevices()
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, &EmuThread::enumerateInputDevices, Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
|
||||
const std::vector<std::pair<std::string, std::string>> devs(InputManager::EnumerateDevices());
|
||||
QList<QPair<QString, QString>> qdevs;
|
||||
qdevs.reserve(devs.size());
|
||||
for (const std::pair<std::string, std::string>& dev : devs)
|
||||
qdevs.emplace_back(QString::fromStdString(dev.first), QString::fromStdString(dev.second));
|
||||
|
||||
onInputDevicesEnumerated(qdevs);
|
||||
}
|
||||
|
||||
void EmuThread::enumerateVibrationMotors()
|
||||
{
|
||||
if (!isOnEmuThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, &EmuThread::enumerateVibrationMotors, Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
|
||||
const std::vector<InputBindingKey> motors(InputManager::EnumerateMotors());
|
||||
QList<InputBindingKey> qmotors;
|
||||
qmotors.reserve(motors.size());
|
||||
for (InputBindingKey key : motors)
|
||||
qmotors.push_back(key);
|
||||
|
||||
onVibrationMotorsEnumerated(qmotors);
|
||||
}
|
||||
|
||||
void EmuThread::connectDisplaySignals(DisplayWidget* widget)
|
||||
{
|
||||
widget->disconnect(this);
|
||||
|
||||
connect(widget, &DisplayWidget::windowFocusEvent, this, &EmuThread::onDisplayWindowFocused);
|
||||
connect(widget, &DisplayWidget::windowResizedEvent, this, &EmuThread::onDisplayWindowResized);
|
||||
// connect(widget, &DisplayWidget::windowRestoredEvent, this, &EmuThread::redrawDisplayWindow);
|
||||
connect(widget, &DisplayWidget::windowClosedEvent, []() { g_emu_thread->shutdownVM(true, true); });
|
||||
connect(widget, &DisplayWidget::windowKeyEvent, this, &EmuThread::onDisplayWindowKeyEvent);
|
||||
connect(widget, &DisplayWidget::windowMouseMoveEvent, this, &EmuThread::onDisplayWindowMouseMoveEvent);
|
||||
connect(widget, &DisplayWidget::windowMouseButtonEvent, this, &EmuThread::onDisplayWindowMouseButtonEvent);
|
||||
connect(widget, &DisplayWidget::windowMouseWheelEvent, this, &EmuThread::onDisplayWindowMouseWheelEvent);
|
||||
}
|
||||
|
||||
void EmuThread::onDisplayWindowMouseMoveEvent(int x, int y) {}
|
||||
|
||||
void EmuThread::onDisplayWindowMouseButtonEvent(int button, bool pressed)
|
||||
{
|
||||
InputManager::InvokeEvents(InputManager::MakeHostMouseButtonKey(button), pressed ? 1.0f : 0.0f);
|
||||
}
|
||||
|
||||
void EmuThread::onDisplayWindowMouseWheelEvent(const QPoint& delta_angle) {}
|
||||
|
||||
void EmuThread::onDisplayWindowKeyEvent(int key, int mods, bool pressed)
|
||||
{
|
||||
InputManager::InvokeEvents(InputManager::MakeHostKeyboardKey(key), pressed ? 1.0f : 0.0f);
|
||||
}
|
||||
|
||||
void EmuThread::onDisplayWindowResized(int width, int height, float scale)
|
||||
{
|
||||
if (!VMManager::HasValidVM())
|
||||
return;
|
||||
|
||||
GetMTGS().ResizeDisplayWindow(width, height, scale);
|
||||
}
|
||||
|
||||
void EmuThread::onDisplayWindowFocused() {}
|
||||
|
||||
void EmuThread::updateDisplay()
|
||||
{
|
||||
pxAssertRel(!isOnEmuThread(), "Not on emu thread");
|
||||
|
||||
// finished with the display for now
|
||||
HostDisplay* display = Host::GetHostDisplay();
|
||||
display->DoneRenderContextCurrent();
|
||||
|
||||
// but we should get it back after this call
|
||||
DisplayWidget* widget = onUpdateDisplayRequested(m_is_fullscreen, !m_is_fullscreen && m_is_rendering_to_main);
|
||||
if (!widget || !display->MakeRenderContextCurrent())
|
||||
{
|
||||
pxFailRel("Failed to recreate context after updating");
|
||||
return;
|
||||
}
|
||||
|
||||
// this is always a new widget, so reconnect it
|
||||
connectDisplaySignals(widget);
|
||||
}
|
||||
|
||||
HostDisplay* EmuThread::acquireHostDisplay(HostDisplay::RenderAPI api)
|
||||
{
|
||||
s_host_display = HostDisplay::CreateDisplayForAPI(api);
|
||||
if (!s_host_display)
|
||||
return nullptr;
|
||||
|
||||
DisplayWidget* widget = emit onCreateDisplayRequested(m_is_fullscreen, m_is_rendering_to_main);
|
||||
if (!widget)
|
||||
{
|
||||
s_host_display.reset();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
connectDisplaySignals(widget);
|
||||
|
||||
if (!s_host_display->MakeRenderContextCurrent())
|
||||
{
|
||||
Console.Error("Failed to make render context current");
|
||||
releaseHostDisplay();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!s_host_display->InitializeRenderDevice(StringUtil::wxStringToUTF8String(EmuFolders::Cache.ToString()), false) ||
|
||||
!ImGuiManager::Initialize())
|
||||
{
|
||||
Console.Error("Failed to initialize device/imgui");
|
||||
releaseHostDisplay();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
g_gs_window_info = s_host_display->GetWindowInfo();
|
||||
|
||||
return s_host_display.get();
|
||||
}
|
||||
|
||||
void EmuThread::releaseHostDisplay()
|
||||
{
|
||||
ImGuiManager::Shutdown();
|
||||
|
||||
if (s_host_display)
|
||||
{
|
||||
s_host_display->DestroyRenderSurface();
|
||||
s_host_display->DestroyRenderDevice();
|
||||
}
|
||||
|
||||
g_gs_window_info = WindowInfo();
|
||||
|
||||
emit onDestroyDisplayRequested();
|
||||
|
||||
s_host_display.reset();
|
||||
}
|
||||
|
||||
HostDisplay* Host::GetHostDisplay()
|
||||
{
|
||||
return s_host_display.get();
|
||||
}
|
||||
|
||||
HostDisplay* Host::AcquireHostDisplay(HostDisplay::RenderAPI api)
|
||||
{
|
||||
return g_emu_thread->acquireHostDisplay(api);
|
||||
}
|
||||
|
||||
void Host::ReleaseHostDisplay()
|
||||
{
|
||||
g_emu_thread->releaseHostDisplay();
|
||||
}
|
||||
|
||||
bool Host::BeginPresentFrame(bool frame_skip)
|
||||
{
|
||||
return s_host_display->BeginPresent(frame_skip);
|
||||
}
|
||||
|
||||
void Host::EndPresentFrame()
|
||||
{
|
||||
ImGuiManager::RenderOSD();
|
||||
s_host_display->EndPresent();
|
||||
ImGuiManager::NewFrame();
|
||||
}
|
||||
|
||||
void Host::ResizeHostDisplay(u32 new_window_width, u32 new_window_height, float new_window_scale)
|
||||
{
|
||||
s_host_display->ResizeRenderWindow(new_window_width, new_window_height, new_window_scale);
|
||||
ImGuiManager::WindowResized();
|
||||
}
|
||||
|
||||
void Host::RequestResizeHostDisplay(s32 width, s32 height)
|
||||
{
|
||||
g_emu_thread->onResizeDisplayRequested(width, height);
|
||||
}
|
||||
|
||||
void Host::UpdateHostDisplay()
|
||||
{
|
||||
g_emu_thread->updateDisplay();
|
||||
ImGuiManager::WindowResized();
|
||||
}
|
||||
|
||||
void Host::OnVMStarting()
|
||||
{
|
||||
g_emu_thread->stopBackgroundControllerPollTimer();
|
||||
emit g_emu_thread->onVMStarting();
|
||||
}
|
||||
|
||||
void Host::OnVMStarted()
|
||||
{
|
||||
emit g_emu_thread->onVMStarted();
|
||||
}
|
||||
|
||||
void Host::OnVMDestroyed()
|
||||
{
|
||||
emit g_emu_thread->onVMStopped();
|
||||
g_emu_thread->startBackgroundControllerPollTimer();
|
||||
}
|
||||
|
||||
void Host::OnVMPaused()
|
||||
{
|
||||
g_emu_thread->startBackgroundControllerPollTimer();
|
||||
emit g_emu_thread->onVMPaused();
|
||||
}
|
||||
|
||||
void Host::OnVMResumed()
|
||||
{
|
||||
// exit the event loop when we eventually return
|
||||
g_emu_thread->getEventLoop()->quit();
|
||||
g_emu_thread->stopBackgroundControllerPollTimer();
|
||||
emit g_emu_thread->onVMResumed();
|
||||
}
|
||||
|
||||
void Host::OnGameChanged(const std::string& disc_path, const std::string& game_serial, const std::string& game_name,
|
||||
u32 game_crc)
|
||||
{
|
||||
emit g_emu_thread->onGameChanged(QString::fromStdString(disc_path), QString::fromStdString(game_serial),
|
||||
QString::fromStdString(game_name), game_crc);
|
||||
}
|
||||
|
||||
void Host::PumpMessagesOnCPUThread()
|
||||
{
|
||||
g_emu_thread->getEventLoop()->processEvents(QEventLoop::AllEvents);
|
||||
}
|
||||
|
||||
ScopedVMPause::ScopedVMPause(bool was_paused)
|
||||
: m_was_paused(was_paused)
|
||||
{
|
||||
if (!m_was_paused)
|
||||
g_emu_thread->setVMPaused(true);
|
||||
}
|
||||
|
||||
ScopedVMPause::~ScopedVMPause()
|
||||
{
|
||||
if (m_was_paused)
|
||||
g_emu_thread->setVMPaused(false);
|
||||
}
|
||||
|
||||
alignas(16) static SysMtgsThread s_mtgs_thread;
|
||||
|
||||
SysMtgsThread& GetMTGS()
|
||||
{
|
||||
return s_mtgs_thread;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Hotkeys
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
BEGIN_HOTKEY_LIST(g_host_hotkeys)
|
||||
DEFINE_HOTKEY("Screenshot", "General", "Save Screenshot", [](bool pressed) {
|
||||
if (!pressed)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
})
|
||||
DEFINE_HOTKEY("TogglePause", "System", "Toggle Pause", [](bool pressed) {
|
||||
if (!pressed)
|
||||
g_emu_thread->setVMPaused(VMManager::GetState() != VMState::Paused);
|
||||
})
|
||||
DEFINE_HOTKEY("ToggleFullscreen", "General", "Toggle Fullscreen", [](bool pressed) {
|
||||
if (!pressed)
|
||||
g_emu_thread->toggleFullscreen();
|
||||
})
|
||||
END_HOTKEY_LIST()
|
|
@ -0,0 +1,144 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "pcsx2/Host.h"
|
||||
#include "pcsx2/HostDisplay.h"
|
||||
#include "pcsx2/Frontend/InputManager.h"
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QEventLoop>
|
||||
#include <QtCore/QPair>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QSemaphore>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QThread>
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
|
||||
class DisplayWidget;
|
||||
struct VMBootParameters;
|
||||
|
||||
class EmuThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit EmuThread(QThread* ui_thread);
|
||||
~EmuThread();
|
||||
|
||||
static void start();
|
||||
static void stop();
|
||||
|
||||
__fi QEventLoop* getEventLoop() const { return m_event_loop; }
|
||||
|
||||
bool isOnEmuThread() const;
|
||||
|
||||
/// Called back from the GS thread when the display state changes (e.g. fullscreen, render to main).
|
||||
HostDisplay* acquireHostDisplay(HostDisplay::RenderAPI api);
|
||||
void releaseHostDisplay();
|
||||
void updateDisplay();
|
||||
|
||||
void startBackgroundControllerPollTimer();
|
||||
void stopBackgroundControllerPollTimer();
|
||||
|
||||
public Q_SLOTS:
|
||||
void startVM(std::shared_ptr<VMBootParameters> boot_params);
|
||||
void resetVM();
|
||||
void setVMPaused(bool paused);
|
||||
void shutdownVM(bool allow_save_to_state = true, bool blocking = false);
|
||||
void loadState(const QString& filename);
|
||||
void loadStateFromSlot(qint32 slot);
|
||||
void saveState(const QString& filename);
|
||||
void saveStateToSlot(qint32 slot);
|
||||
void toggleFullscreen();
|
||||
void setFullscreen(bool fullscreen);
|
||||
void applySettings();
|
||||
void toggleSoftwareRendering();
|
||||
void switchRenderer(GSRendererType renderer);
|
||||
void changeDisc(const QString& path);
|
||||
void reloadPatches();
|
||||
void reloadInputSources();
|
||||
void reloadInputBindings();
|
||||
void requestDisplaySize(float scale);
|
||||
void enumerateInputDevices();
|
||||
void enumerateVibrationMotors();
|
||||
|
||||
Q_SIGNALS:
|
||||
DisplayWidget* onCreateDisplayRequested(bool fullscreen, bool render_to_main);
|
||||
DisplayWidget* onUpdateDisplayRequested(bool fullscreen, bool render_to_main);
|
||||
void onResizeDisplayRequested(qint32 width, qint32 height);
|
||||
void onDestroyDisplayRequested();
|
||||
void onVMStarting();
|
||||
void onVMStarted();
|
||||
void onVMPaused();
|
||||
void onVMResumed();
|
||||
void onVMStopped();
|
||||
void onGameChanged(const QString& path, const QString& serial, const QString& name, quint32 crc);
|
||||
void onInputDevicesEnumerated(const QList<QPair<QString, QString>>& devices);
|
||||
void onInputDeviceConnected(const QString& identifier, const QString& device_name);
|
||||
void onInputDeviceDisconnected(const QString& identifier);
|
||||
void onVibrationMotorsEnumerated(const QList<InputBindingKey>& motors);
|
||||
|
||||
protected:
|
||||
void run();
|
||||
|
||||
private:
|
||||
static constexpr u32 BACKGROUND_CONTROLLER_POLLING_INTERVAL =
|
||||
100; /// Interval at which the controllers are polled when the system is not active.
|
||||
|
||||
void connectDisplaySignals(DisplayWidget* widget);
|
||||
void destroyVM();
|
||||
void executeVM();
|
||||
void checkForSettingChanges();
|
||||
|
||||
void createBackgroundControllerPollTimer();
|
||||
void destroyBackgroundControllerPollTimer();
|
||||
|
||||
private Q_SLOTS:
|
||||
void stopInThread();
|
||||
void doBackgroundControllerPoll();
|
||||
void onDisplayWindowMouseMoveEvent(int x, int y);
|
||||
void onDisplayWindowMouseButtonEvent(int button, bool pressed);
|
||||
void onDisplayWindowMouseWheelEvent(const QPoint& delta_angle);
|
||||
void onDisplayWindowResized(int width, int height, float scale);
|
||||
void onDisplayWindowFocused();
|
||||
void onDisplayWindowKeyEvent(int key, int mods, bool pressed);
|
||||
|
||||
private:
|
||||
QThread* m_ui_thread;
|
||||
QSemaphore m_started_semaphore;
|
||||
QEventLoop* m_event_loop = nullptr;
|
||||
QTimer* m_background_controller_polling_timer = nullptr;
|
||||
|
||||
std::atomic_bool m_shutdown_flag{false};
|
||||
|
||||
bool m_is_rendering_to_main = false;
|
||||
bool m_is_fullscreen = false;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Helper class to pause/unpause the emulation thread.
|
||||
/// </summary>
|
||||
class ScopedVMPause
|
||||
{
|
||||
public:
|
||||
ScopedVMPause(bool was_paused);
|
||||
~ScopedVMPause();
|
||||
|
||||
private:
|
||||
bool m_was_paused;
|
||||
};
|
||||
|
||||
extern EmuThread* g_emu_thread;
|
|
@ -0,0 +1,490 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "GameListModel.h"
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/StringUtil.h"
|
||||
#include <QtCore/QDate>
|
||||
#include <QtCore/QDateTime>
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtGui/QIcon>
|
||||
#include <QtGui/QPainter>
|
||||
|
||||
static constexpr std::array<const char*, GameListModel::Column_Count> s_column_names = {
|
||||
{"Type", "Code", "Title", "File Title", "CRC", "Size", "Region", "Compatibility", "Cover"}};
|
||||
|
||||
static constexpr int COVER_ART_WIDTH = 350;
|
||||
static constexpr int COVER_ART_HEIGHT = 512;
|
||||
static constexpr int COVER_ART_SPACING = 32;
|
||||
|
||||
static int DPRScale(int size, float dpr)
|
||||
{
|
||||
return static_cast<int>(static_cast<float>(size) * dpr);
|
||||
}
|
||||
|
||||
static int DPRUnscale(int size, float dpr)
|
||||
{
|
||||
return static_cast<int>(static_cast<float>(size) / dpr);
|
||||
}
|
||||
|
||||
static void resizeAndPadPixmap(QPixmap* pm, int expected_width, int expected_height, float dpr)
|
||||
{
|
||||
const int dpr_expected_width = DPRScale(expected_width, dpr);
|
||||
const int dpr_expected_height = DPRScale(expected_height, dpr);
|
||||
if (pm->width() == dpr_expected_width && pm->height() == dpr_expected_height)
|
||||
return;
|
||||
|
||||
*pm = pm->scaled(dpr_expected_width, dpr_expected_height, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
if (pm->width() == dpr_expected_width && pm->height() == dpr_expected_height)
|
||||
return;
|
||||
|
||||
// QPainter works in unscaled coordinates.
|
||||
int xoffs = 0;
|
||||
int yoffs = 0;
|
||||
if (pm->width() < dpr_expected_width)
|
||||
xoffs = DPRUnscale((dpr_expected_width - pm->width()) / 2, dpr);
|
||||
if (pm->height() < dpr_expected_height)
|
||||
yoffs = DPRUnscale((dpr_expected_height - pm->height()) / 2, dpr);
|
||||
|
||||
QPixmap padded_image(dpr_expected_width, dpr_expected_height);
|
||||
padded_image.setDevicePixelRatio(dpr);
|
||||
padded_image.fill(Qt::transparent);
|
||||
QPainter painter;
|
||||
if (painter.begin(&padded_image))
|
||||
{
|
||||
painter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
painter.drawPixmap(xoffs, yoffs, *pm);
|
||||
painter.setCompositionMode(QPainter::CompositionMode_Destination);
|
||||
painter.fillRect(padded_image.rect(), QColor(0, 0, 0, 0));
|
||||
painter.end();
|
||||
}
|
||||
|
||||
*pm = padded_image;
|
||||
}
|
||||
|
||||
static QPixmap createPlaceholderImage(const QPixmap& placeholder_pixmap, int width, int height, float scale,
|
||||
const std::string& title)
|
||||
{
|
||||
const float dpr = qApp->devicePixelRatio();
|
||||
QPixmap pm(placeholder_pixmap.copy());
|
||||
pm.setDevicePixelRatio(dpr);
|
||||
if (pm.isNull())
|
||||
return QPixmap();
|
||||
|
||||
resizeAndPadPixmap(&pm, width, height, dpr);
|
||||
QPainter painter;
|
||||
if (painter.begin(&pm))
|
||||
{
|
||||
QFont font;
|
||||
font.setPointSize(std::max(static_cast<int>(32.0f * scale), 1));
|
||||
painter.setFont(font);
|
||||
painter.setPen(Qt::white);
|
||||
|
||||
const QRect text_rc(0, 0, static_cast<int>(static_cast<float>(width)),
|
||||
static_cast<int>(static_cast<float>(height)));
|
||||
painter.drawText(text_rc, Qt::AlignCenter | Qt::TextWordWrap, QString::fromStdString(title));
|
||||
painter.end();
|
||||
}
|
||||
|
||||
return pm;
|
||||
}
|
||||
|
||||
std::optional<GameListModel::Column> GameListModel::getColumnIdForName(std::string_view name)
|
||||
{
|
||||
for (int column = 0; column < Column_Count; column++)
|
||||
{
|
||||
if (name == s_column_names[column])
|
||||
return static_cast<Column>(column);
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const char* GameListModel::getColumnName(Column col)
|
||||
{
|
||||
return s_column_names[static_cast<int>(col)];
|
||||
}
|
||||
|
||||
GameListModel::GameListModel(QObject* parent /* = nullptr */)
|
||||
: QAbstractTableModel(parent)
|
||||
{
|
||||
loadCommonImages();
|
||||
setColumnDisplayNames();
|
||||
}
|
||||
GameListModel::~GameListModel() = default;
|
||||
|
||||
void GameListModel::setCoverScale(float scale)
|
||||
{
|
||||
if (m_cover_scale == scale)
|
||||
return;
|
||||
|
||||
m_cover_pixmap_cache.clear();
|
||||
m_cover_scale = scale;
|
||||
}
|
||||
|
||||
void GameListModel::refreshCovers()
|
||||
{
|
||||
m_cover_pixmap_cache.clear();
|
||||
refresh();
|
||||
}
|
||||
|
||||
int GameListModel::getCoverArtWidth() const
|
||||
{
|
||||
return std::max(static_cast<int>(static_cast<float>(COVER_ART_WIDTH) * m_cover_scale), 1);
|
||||
}
|
||||
|
||||
int GameListModel::getCoverArtHeight() const
|
||||
{
|
||||
return std::max(static_cast<int>(static_cast<float>(COVER_ART_HEIGHT) * m_cover_scale), 1);
|
||||
}
|
||||
|
||||
int GameListModel::getCoverArtSpacing() const
|
||||
{
|
||||
return std::max(static_cast<int>(static_cast<float>(COVER_ART_SPACING) * m_cover_scale), 1);
|
||||
}
|
||||
|
||||
int GameListModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
if (parent.isValid())
|
||||
return 0;
|
||||
|
||||
return static_cast<int>(GameList::GetEntryCount());
|
||||
}
|
||||
|
||||
int GameListModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
if (parent.isValid())
|
||||
return 0;
|
||||
|
||||
return Column_Count;
|
||||
}
|
||||
|
||||
QVariant GameListModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return {};
|
||||
|
||||
const int row = index.row();
|
||||
if (row < 0 || row >= static_cast<int>(GameList::GetEntryCount()))
|
||||
return {};
|
||||
|
||||
const auto lock = GameList::GetLock();
|
||||
const GameList::Entry* ge = GameList::GetEntryByIndex(row);
|
||||
if (!ge)
|
||||
return {};
|
||||
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
{
|
||||
switch (index.column())
|
||||
{
|
||||
case Column_Serial:
|
||||
return QString::fromStdString(ge->serial);
|
||||
|
||||
case Column_Title:
|
||||
return QString::fromStdString(ge->title);
|
||||
|
||||
case Column_FileTitle:
|
||||
{
|
||||
const std::string_view file_title(FileSystem::GetFileTitleFromPath(ge->path));
|
||||
return QString::fromUtf8(file_title.data(), static_cast<int>(file_title.length()));
|
||||
}
|
||||
|
||||
case Column_CRC:
|
||||
return QStringLiteral("%1").arg(ge->crc, 8, 16, QChar('0'));
|
||||
|
||||
case Column_Size:
|
||||
return QString("%1 MB").arg(static_cast<double>(ge->total_size) / 1048576.0, 0, 'f', 2);
|
||||
|
||||
case Column_Cover:
|
||||
{
|
||||
if (m_show_titles_for_covers)
|
||||
return QString::fromStdString(ge->title);
|
||||
else
|
||||
return {};
|
||||
}
|
||||
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
case Qt::InitialSortOrderRole:
|
||||
{
|
||||
switch (index.column())
|
||||
{
|
||||
case Column_Type:
|
||||
return static_cast<int>(ge->type);
|
||||
|
||||
case Column_Serial:
|
||||
return QString::fromStdString(ge->serial);
|
||||
|
||||
case Column_Title:
|
||||
case Column_Cover:
|
||||
return QString::fromStdString(ge->title);
|
||||
|
||||
case Column_FileTitle:
|
||||
{
|
||||
const std::string_view file_title(FileSystem::GetFileTitleFromPath(ge->path));
|
||||
return QString::fromUtf8(file_title.data(), static_cast<int>(file_title.length()));
|
||||
}
|
||||
|
||||
case Column_CRC:
|
||||
return static_cast<int>(ge->crc);
|
||||
|
||||
case Column_Region:
|
||||
return static_cast<int>(ge->region);
|
||||
|
||||
case Column_Compatibility:
|
||||
return static_cast<int>(ge->compatibility_rating);
|
||||
|
||||
case Column_Size:
|
||||
return static_cast<qulonglong>(ge->total_size);
|
||||
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
case Qt::DecorationRole:
|
||||
{
|
||||
switch (index.column())
|
||||
{
|
||||
case Column_Type:
|
||||
{
|
||||
switch (ge->type)
|
||||
{
|
||||
case GameList::EntryType::PS1Disc:
|
||||
case GameList::EntryType::PS2Disc:
|
||||
// return ((ge->settings.GetUserSettingsCount() > 0) ? m_type_disc_with_settings_pixmap : // m_type_disc_pixmap);
|
||||
return m_type_disc_pixmap;
|
||||
case GameList::EntryType::Playlist:
|
||||
return m_type_playlist_pixmap;
|
||||
case GameList::EntryType::ELF:
|
||||
default:
|
||||
return m_type_exe_pixmap;
|
||||
}
|
||||
}
|
||||
|
||||
case Column_Region:
|
||||
{
|
||||
switch (ge->region)
|
||||
{
|
||||
case GameList::Region::NTSC_J:
|
||||
return m_region_jp_pixmap;
|
||||
case GameList::Region::NTSC_UC:
|
||||
return m_region_us_pixmap;
|
||||
case GameList::Region::PAL:
|
||||
return m_region_eu_pixmap;
|
||||
case GameList::Region::Other:
|
||||
default:
|
||||
return m_region_other_pixmap;
|
||||
}
|
||||
}
|
||||
|
||||
case Column_Compatibility:
|
||||
{
|
||||
return m_compatibiliy_pixmaps[static_cast<int>(
|
||||
(static_cast<u32>(ge->compatibility_rating) >= GameList::CompatibilityRatingCount) ?
|
||||
GameList::CompatibilityRating::Unknown :
|
||||
ge->compatibility_rating)];
|
||||
}
|
||||
|
||||
case Column_Cover:
|
||||
{
|
||||
auto it = m_cover_pixmap_cache.find(ge->path);
|
||||
if (it != m_cover_pixmap_cache.end())
|
||||
return it->second;
|
||||
|
||||
QPixmap image;
|
||||
std::string path = GameList::GetCoverImagePathForEntry(ge);
|
||||
if (!path.empty())
|
||||
{
|
||||
const float dpr = qApp->devicePixelRatio();
|
||||
image = QPixmap(QString::fromStdString(path));
|
||||
if (!image.isNull())
|
||||
{
|
||||
image.setDevicePixelRatio(dpr);
|
||||
resizeAndPadPixmap(&image, getCoverArtWidth(), getCoverArtHeight(), dpr);
|
||||
}
|
||||
}
|
||||
|
||||
if (image.isNull())
|
||||
{
|
||||
image = createPlaceholderImage(m_placeholder_pixmap, getCoverArtWidth(), getCoverArtHeight(), m_cover_scale,
|
||||
ge->title);
|
||||
}
|
||||
|
||||
m_cover_pixmap_cache.emplace(ge->path, image);
|
||||
return image;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QVariant GameListModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (orientation != Qt::Horizontal || role != Qt::DisplayRole || section < 0 || section >= Column_Count)
|
||||
return {};
|
||||
|
||||
return m_column_display_names[section];
|
||||
}
|
||||
|
||||
void GameListModel::refresh()
|
||||
{
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
bool GameListModel::titlesLessThan(int left_row, int right_row) const
|
||||
{
|
||||
if (left_row < 0 || left_row >= static_cast<int>(GameList::GetEntryCount()) || right_row < 0 ||
|
||||
right_row >= static_cast<int>(GameList::GetEntryCount()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const GameList::Entry* left = GameList::GetEntryByIndex(left_row);
|
||||
const GameList::Entry* right = GameList::GetEntryByIndex(right_row);
|
||||
return (StringUtil::Strcasecmp(left->title.c_str(), right->title.c_str()) < 0);
|
||||
}
|
||||
|
||||
bool GameListModel::lessThan(const QModelIndex& left_index, const QModelIndex& right_index, int column) const
|
||||
{
|
||||
if (!left_index.isValid() || !right_index.isValid())
|
||||
return false;
|
||||
|
||||
const int left_row = left_index.row();
|
||||
const int right_row = right_index.row();
|
||||
if (left_row < 0 || left_row >= static_cast<int>(GameList::GetEntryCount()) || right_row < 0 ||
|
||||
right_row >= static_cast<int>(GameList::GetEntryCount()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto lock = GameList::GetLock();
|
||||
const GameList::Entry* left = GameList::GetEntryByIndex(left_row);
|
||||
const GameList::Entry* right = GameList::GetEntryByIndex(right_row);
|
||||
if (!left || !right)
|
||||
return false;
|
||||
|
||||
switch (column)
|
||||
{
|
||||
case Column_Type:
|
||||
{
|
||||
if (left->type == right->type)
|
||||
return titlesLessThan(left_row, right_row);
|
||||
|
||||
return static_cast<int>(left->type) < static_cast<int>(right->type);
|
||||
}
|
||||
|
||||
case Column_Serial:
|
||||
{
|
||||
if (left->serial == right->serial)
|
||||
return titlesLessThan(left_row, right_row);
|
||||
return (StringUtil::Strcasecmp(left->serial.c_str(), right->serial.c_str()) < 0);
|
||||
}
|
||||
|
||||
case Column_Title:
|
||||
{
|
||||
return titlesLessThan(left_row, right_row);
|
||||
}
|
||||
|
||||
case Column_FileTitle:
|
||||
{
|
||||
const std::string_view file_title_left(FileSystem::GetFileTitleFromPath(left->path));
|
||||
const std::string_view file_title_right(FileSystem::GetFileTitleFromPath(right->path));
|
||||
if (file_title_left == file_title_right)
|
||||
return titlesLessThan(left_row, right_row);
|
||||
|
||||
const std::size_t smallest = std::min(file_title_left.size(), file_title_right.size());
|
||||
return (StringUtil::Strncasecmp(file_title_left.data(), file_title_right.data(), smallest) < 0);
|
||||
}
|
||||
|
||||
case Column_Region:
|
||||
{
|
||||
if (left->region == right->region)
|
||||
return titlesLessThan(left_row, right_row);
|
||||
return (static_cast<int>(left->region) < static_cast<int>(right->region));
|
||||
}
|
||||
|
||||
case Column_Compatibility:
|
||||
{
|
||||
if (left->compatibility_rating == right->compatibility_rating)
|
||||
return titlesLessThan(left_row, right_row);
|
||||
|
||||
return (static_cast<int>(left->compatibility_rating) < static_cast<int>(right->compatibility_rating));
|
||||
}
|
||||
|
||||
case Column_Size:
|
||||
{
|
||||
if (left->total_size == right->total_size)
|
||||
return titlesLessThan(left_row, right_row);
|
||||
|
||||
return (left->total_size < right->total_size);
|
||||
}
|
||||
|
||||
case Column_CRC:
|
||||
{
|
||||
if (left->crc == right->crc)
|
||||
return titlesLessThan(left_row, right_row);
|
||||
|
||||
return (left->crc < right->crc);
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void GameListModel::loadCommonImages()
|
||||
{
|
||||
m_type_disc_pixmap = QIcon(QStringLiteral(":/icons/media-optical-24.png")).pixmap(QSize(24, 24));
|
||||
m_type_disc_with_settings_pixmap = QIcon(QStringLiteral(":/icons/media-optical-gear-24.png")).pixmap(QSize(24, 24));
|
||||
m_type_exe_pixmap = QIcon(QStringLiteral(":/icons/applications-system-24.png")).pixmap(QSize(24, 24));
|
||||
m_type_playlist_pixmap = QIcon(QStringLiteral(":/icons/address-book-new-22.png")).pixmap(QSize(22, 22));
|
||||
m_region_eu_pixmap = QIcon(QStringLiteral(":/icons/flag-eu.png")).pixmap(QSize(42, 30));
|
||||
m_region_jp_pixmap = QIcon(QStringLiteral(":/icons/flag-jp.png")).pixmap(QSize(42, 30));
|
||||
m_region_us_pixmap = QIcon(QStringLiteral(":/icons/flag-us.png")).pixmap(QSize(42, 30));
|
||||
m_region_other_pixmap = QIcon(QStringLiteral(":/icons/flag-other.png")).pixmap(QSize(42, 30));
|
||||
|
||||
for (u32 i = 1; i < GameList::CompatibilityRatingCount; i++)
|
||||
m_compatibiliy_pixmaps[i].load(QStringLiteral(":/icons/star-%1.png").arg(i - 1));
|
||||
|
||||
m_placeholder_pixmap.load(QString::fromStdString(Path::CombineStdString(EmuFolders::Resources, "cover-placeholder.png")));
|
||||
}
|
||||
|
||||
void GameListModel::setColumnDisplayNames()
|
||||
{
|
||||
m_column_display_names[Column_Type] = tr("Type");
|
||||
m_column_display_names[Column_Serial] = tr("Code");
|
||||
m_column_display_names[Column_Title] = tr("Title");
|
||||
m_column_display_names[Column_FileTitle] = tr("File Title");
|
||||
m_column_display_names[Column_CRC] = tr("CRC");
|
||||
m_column_display_names[Column_Size] = tr("Size");
|
||||
m_column_display_names[Column_Region] = tr("Region");
|
||||
m_column_display_names[Column_Compatibility] = tr("Compatibility");
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "pcsx2/Frontend/GameList.h"
|
||||
#include <QtCore/QAbstractTableModel>
|
||||
#include <QtGui/QPixmap>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <optional>
|
||||
#include <unordered_map>
|
||||
|
||||
class GameListModel final : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Column : int
|
||||
{
|
||||
Column_Type,
|
||||
Column_Serial,
|
||||
Column_Title,
|
||||
Column_FileTitle,
|
||||
Column_CRC,
|
||||
Column_Size,
|
||||
Column_Region,
|
||||
Column_Compatibility,
|
||||
Column_Cover,
|
||||
|
||||
Column_Count
|
||||
};
|
||||
|
||||
static std::optional<Column> getColumnIdForName(std::string_view name);
|
||||
static const char* getColumnName(Column col);
|
||||
|
||||
GameListModel(QObject* parent = nullptr);
|
||||
~GameListModel();
|
||||
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
|
||||
__fi const QString& getColumnDisplayName(int column) { return m_column_display_names[column]; }
|
||||
|
||||
void refresh();
|
||||
|
||||
bool titlesLessThan(int left_row, int right_row) const;
|
||||
|
||||
bool lessThan(const QModelIndex& left_index, const QModelIndex& right_index, int column) const;
|
||||
|
||||
bool getShowCoverTitles() const { return m_show_titles_for_covers; }
|
||||
void setShowCoverTitles(bool enabled) { m_show_titles_for_covers = enabled; }
|
||||
|
||||
float getCoverScale() const { return m_cover_scale; }
|
||||
void setCoverScale(float scale);
|
||||
int getCoverArtWidth() const;
|
||||
int getCoverArtHeight() const;
|
||||
int getCoverArtSpacing() const;
|
||||
void refreshCovers();
|
||||
|
||||
private:
|
||||
void loadCommonImages();
|
||||
void setColumnDisplayNames();
|
||||
|
||||
float m_cover_scale = 1.0f;
|
||||
bool m_show_titles_for_covers = false;
|
||||
|
||||
std::array<QString, Column_Count> m_column_display_names;
|
||||
|
||||
QPixmap m_type_disc_pixmap;
|
||||
QPixmap m_type_disc_with_settings_pixmap;
|
||||
QPixmap m_type_exe_pixmap;
|
||||
QPixmap m_type_playlist_pixmap;
|
||||
|
||||
QPixmap m_region_jp_pixmap;
|
||||
QPixmap m_region_eu_pixmap;
|
||||
QPixmap m_region_us_pixmap;
|
||||
QPixmap m_region_other_pixmap;
|
||||
|
||||
QPixmap m_placeholder_pixmap;
|
||||
|
||||
std::array<QPixmap, static_cast<int>(GameList::CompatibilityRatingCount)> m_compatibiliy_pixmaps;
|
||||
mutable std::unordered_map<std::string, QPixmap> m_cover_pixmap_cache;
|
||||
};
|
|
@ -0,0 +1,130 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "common/ProgressCallback.h"
|
||||
#include "common/Timer.h"
|
||||
#include "pcsx2/Frontend/GameList.h"
|
||||
|
||||
#include "GameListRefreshThread.h"
|
||||
|
||||
#include <QtWidgets/QMessageBox>
|
||||
|
||||
// Limit UI update times to 4 per second, so we don't spend longer redrawing the UI than scanning
|
||||
static constexpr float UI_UPDATE_INTERVAL = 0.25f;
|
||||
|
||||
AsyncRefreshProgressCallback::AsyncRefreshProgressCallback(GameListRefreshThread* parent)
|
||||
: m_parent(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void AsyncRefreshProgressCallback::Cancel()
|
||||
{
|
||||
// Not atomic, but we don't need to cancel immediately.
|
||||
m_cancelled = true;
|
||||
}
|
||||
|
||||
void AsyncRefreshProgressCallback::SetStatusText(const char* text)
|
||||
{
|
||||
QString new_text(QString::fromUtf8(text));
|
||||
if (new_text == m_status_text)
|
||||
return;
|
||||
|
||||
m_status_text = new_text;
|
||||
fireUpdate();
|
||||
}
|
||||
|
||||
void AsyncRefreshProgressCallback::SetProgressRange(u32 range)
|
||||
{
|
||||
BaseProgressCallback::SetProgressRange(range);
|
||||
if (static_cast<int>(m_progress_range) == m_last_range)
|
||||
return;
|
||||
|
||||
m_last_range = static_cast<int>(m_progress_range);
|
||||
fireUpdate();
|
||||
}
|
||||
|
||||
void AsyncRefreshProgressCallback::SetProgressValue(u32 value)
|
||||
{
|
||||
BaseProgressCallback::SetProgressValue(value);
|
||||
if (static_cast<int>(m_progress_value) == m_last_value)
|
||||
return;
|
||||
|
||||
m_last_value = static_cast<int>(m_progress_value);
|
||||
fireUpdate();
|
||||
}
|
||||
|
||||
void AsyncRefreshProgressCallback::SetTitle(const char* title) {}
|
||||
|
||||
void AsyncRefreshProgressCallback::DisplayError(const char* message)
|
||||
{
|
||||
QMessageBox::critical(nullptr, QStringLiteral("Error"), QString::fromUtf8(message));
|
||||
}
|
||||
|
||||
void AsyncRefreshProgressCallback::DisplayWarning(const char* message)
|
||||
{
|
||||
QMessageBox::warning(nullptr, QStringLiteral("Warning"), QString::fromUtf8(message));
|
||||
}
|
||||
|
||||
void AsyncRefreshProgressCallback::DisplayInformation(const char* message)
|
||||
{
|
||||
QMessageBox::information(nullptr, QStringLiteral("Information"), QString::fromUtf8(message));
|
||||
}
|
||||
|
||||
void AsyncRefreshProgressCallback::DisplayDebugMessage(const char* message)
|
||||
{
|
||||
qDebug() << message;
|
||||
}
|
||||
|
||||
void AsyncRefreshProgressCallback::ModalError(const char* message)
|
||||
{
|
||||
QMessageBox::critical(nullptr, QStringLiteral("Error"), QString::fromUtf8(message));
|
||||
}
|
||||
|
||||
bool AsyncRefreshProgressCallback::ModalConfirmation(const char* message)
|
||||
{
|
||||
return QMessageBox::question(nullptr, QStringLiteral("Question"), QString::fromUtf8(message)) == QMessageBox::Yes;
|
||||
}
|
||||
|
||||
void AsyncRefreshProgressCallback::ModalInformation(const char* message)
|
||||
{
|
||||
QMessageBox::information(nullptr, QStringLiteral("Information"), QString::fromUtf8(message));
|
||||
}
|
||||
|
||||
void AsyncRefreshProgressCallback::fireUpdate()
|
||||
{
|
||||
m_parent->refreshProgress(m_status_text, m_last_value, m_last_range);
|
||||
}
|
||||
|
||||
GameListRefreshThread::GameListRefreshThread(bool invalidate_cache)
|
||||
: QThread()
|
||||
, m_progress(this)
|
||||
, m_invalidate_cache(invalidate_cache)
|
||||
{
|
||||
}
|
||||
|
||||
GameListRefreshThread::~GameListRefreshThread() = default;
|
||||
|
||||
void GameListRefreshThread::cancel()
|
||||
{
|
||||
m_progress.Cancel();
|
||||
}
|
||||
|
||||
void GameListRefreshThread::run()
|
||||
{
|
||||
GameList::Refresh(m_invalidate_cache, &m_progress);
|
||||
emit refreshComplete();
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QThread>
|
||||
#include <QtCore/QSemaphore>
|
||||
|
||||
#include "common/ProgressCallback.h"
|
||||
#include "common/Timer.h"
|
||||
|
||||
class GameListRefreshThread;
|
||||
|
||||
class AsyncRefreshProgressCallback : public BaseProgressCallback
|
||||
{
|
||||
public:
|
||||
AsyncRefreshProgressCallback(GameListRefreshThread* parent);
|
||||
|
||||
void Cancel();
|
||||
|
||||
void SetStatusText(const char* text) override;
|
||||
void SetProgressRange(u32 range) override;
|
||||
void SetProgressValue(u32 value) override;
|
||||
void SetTitle(const char* title) override;
|
||||
void DisplayError(const char* message) override;
|
||||
void DisplayWarning(const char* message) override;
|
||||
void DisplayInformation(const char* message) override;
|
||||
void DisplayDebugMessage(const char* message) override;
|
||||
void ModalError(const char* message) override;
|
||||
bool ModalConfirmation(const char* message) override;
|
||||
void ModalInformation(const char* message) override;
|
||||
|
||||
private:
|
||||
void fireUpdate();
|
||||
|
||||
GameListRefreshThread* m_parent;
|
||||
Common::Timer m_last_update_time;
|
||||
QString m_status_text;
|
||||
int m_last_range = 1;
|
||||
int m_last_value = 0;
|
||||
};
|
||||
|
||||
class GameListRefreshThread final : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GameListRefreshThread(bool invalidate_cache);
|
||||
~GameListRefreshThread();
|
||||
|
||||
void cancel();
|
||||
|
||||
Q_SIGNALS:
|
||||
void refreshProgress(const QString& status, int current, int total);
|
||||
void refreshComplete();
|
||||
|
||||
protected:
|
||||
void run();
|
||||
|
||||
private:
|
||||
AsyncRefreshProgressCallback m_progress;
|
||||
bool m_invalidate_cache;
|
||||
};
|
|
@ -0,0 +1,457 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
#include "pcsx2/Frontend/GameList.h"
|
||||
|
||||
#include <QtCore/QSortFilterProxyModel>
|
||||
#include <QtGui/QPixmap>
|
||||
#include <QtGui/QWheelEvent>
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <QtWidgets/QHeaderView>
|
||||
#include <QtWidgets/QMenu>
|
||||
|
||||
#include "GameListModel.h"
|
||||
#include "GameListRefreshThread.h"
|
||||
#include "GameListWidget.h"
|
||||
#include "QtHost.h"
|
||||
#include "QtUtils.h"
|
||||
|
||||
class GameListSortModel final : public QSortFilterProxyModel
|
||||
{
|
||||
public:
|
||||
explicit GameListSortModel(GameListModel* parent)
|
||||
: QSortFilterProxyModel(parent)
|
||||
, m_model(parent)
|
||||
{
|
||||
}
|
||||
|
||||
bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override
|
||||
{
|
||||
// TODO: Search
|
||||
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
|
||||
}
|
||||
|
||||
bool lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const override
|
||||
{
|
||||
return m_model->lessThan(source_left, source_right, source_left.column());
|
||||
}
|
||||
|
||||
private:
|
||||
GameListModel* m_model;
|
||||
};
|
||||
|
||||
GameListWidget::GameListWidget(QWidget* parent /* = nullptr */)
|
||||
: QStackedWidget(parent)
|
||||
{
|
||||
}
|
||||
|
||||
GameListWidget::~GameListWidget() = default;
|
||||
|
||||
void GameListWidget::initialize()
|
||||
{
|
||||
m_model = new GameListModel(this);
|
||||
m_model->setCoverScale(QtHost::GetBaseFloatSettingValue("UI", "GameListCoverArtScale", 0.45f));
|
||||
m_model->setShowCoverTitles(QtHost::GetBaseBoolSettingValue("UI", "GameListShowCoverTitles", true));
|
||||
m_model->setCoverScale(0.45f);
|
||||
m_model->setShowCoverTitles(true);
|
||||
|
||||
m_sort_model = new GameListSortModel(m_model);
|
||||
m_sort_model->setSourceModel(m_model);
|
||||
m_table_view = new QTableView(this);
|
||||
m_table_view->setModel(m_sort_model);
|
||||
m_table_view->setSortingEnabled(true);
|
||||
m_table_view->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
m_table_view->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
m_table_view->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
m_table_view->setAlternatingRowColors(true);
|
||||
m_table_view->setShowGrid(false);
|
||||
m_table_view->setCurrentIndex({});
|
||||
m_table_view->horizontalHeader()->setHighlightSections(false);
|
||||
m_table_view->horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
m_table_view->verticalHeader()->hide();
|
||||
m_table_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||
|
||||
loadTableViewColumnVisibilitySettings();
|
||||
loadTableViewColumnSortSettings();
|
||||
|
||||
connect(m_table_view->selectionModel(), &QItemSelectionModel::currentChanged, this,
|
||||
&GameListWidget::onSelectionModelCurrentChanged);
|
||||
connect(m_table_view, &QTableView::activated, this, &GameListWidget::onTableViewItemActivated);
|
||||
connect(m_table_view, &QTableView::customContextMenuRequested, this,
|
||||
&GameListWidget::onTableViewContextMenuRequested);
|
||||
connect(m_table_view->horizontalHeader(), &QHeaderView::customContextMenuRequested, this,
|
||||
&GameListWidget::onTableViewHeaderContextMenuRequested);
|
||||
connect(m_table_view->horizontalHeader(), &QHeaderView::sortIndicatorChanged, this,
|
||||
&GameListWidget::onTableViewHeaderSortIndicatorChanged);
|
||||
|
||||
insertWidget(0, m_table_view);
|
||||
|
||||
m_list_view = new GameListGridListView(this);
|
||||
m_list_view->setModel(m_sort_model);
|
||||
m_list_view->setModelColumn(GameListModel::Column_Cover);
|
||||
m_list_view->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
m_list_view->setViewMode(QListView::IconMode);
|
||||
m_list_view->setResizeMode(QListView::Adjust);
|
||||
m_list_view->setUniformItemSizes(true);
|
||||
m_list_view->setItemAlignment(Qt::AlignHCenter);
|
||||
m_list_view->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
m_list_view->setFrameStyle(QFrame::NoFrame);
|
||||
m_list_view->setSpacing(m_model->getCoverArtSpacing());
|
||||
updateListFont();
|
||||
|
||||
connect(m_list_view->selectionModel(), &QItemSelectionModel::currentChanged, this,
|
||||
&GameListWidget::onSelectionModelCurrentChanged);
|
||||
connect(m_list_view, &GameListGridListView::zoomIn, this, &GameListWidget::gridZoomIn);
|
||||
connect(m_list_view, &GameListGridListView::zoomOut, this, &GameListWidget::gridZoomOut);
|
||||
connect(m_list_view, &QListView::activated, this, &GameListWidget::onListViewItemActivated);
|
||||
connect(m_list_view, &QListView::customContextMenuRequested, this, &GameListWidget::onListViewContextMenuRequested);
|
||||
|
||||
insertWidget(1, m_list_view);
|
||||
|
||||
if (QtHost::GetBaseBoolSettingValue("UI", "GameListGridView", false))
|
||||
setCurrentIndex(1);
|
||||
else
|
||||
setCurrentIndex(0);
|
||||
|
||||
resizeTableViewColumnsToFit();
|
||||
}
|
||||
|
||||
bool GameListWidget::isShowingGameList() const
|
||||
{
|
||||
return currentIndex() == 0;
|
||||
}
|
||||
|
||||
bool GameListWidget::isShowingGameGrid() const
|
||||
{
|
||||
return currentIndex() == 1;
|
||||
}
|
||||
|
||||
bool GameListWidget::getShowGridCoverTitles() const
|
||||
{
|
||||
return m_model->getShowCoverTitles();
|
||||
}
|
||||
|
||||
void GameListWidget::refresh(bool invalidate_cache)
|
||||
{
|
||||
if (m_refresh_thread)
|
||||
{
|
||||
m_refresh_thread->cancel();
|
||||
m_refresh_thread->wait();
|
||||
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||
pxAssertRel(!m_refresh_thread, "Game list thread should be unreferenced by now");
|
||||
}
|
||||
|
||||
m_refresh_thread = new GameListRefreshThread(invalidate_cache);
|
||||
connect(m_refresh_thread, &GameListRefreshThread::refreshProgress, this, &GameListWidget::onRefreshProgress,
|
||||
Qt::QueuedConnection);
|
||||
connect(m_refresh_thread, &GameListRefreshThread::refreshComplete, this, &GameListWidget::onRefreshComplete,
|
||||
Qt::QueuedConnection);
|
||||
m_refresh_thread->start();
|
||||
}
|
||||
|
||||
void GameListWidget::onRefreshProgress(const QString& status, int current, int total)
|
||||
{
|
||||
m_model->refresh();
|
||||
emit refreshProgress(status, current, total);
|
||||
}
|
||||
|
||||
void GameListWidget::onRefreshComplete()
|
||||
{
|
||||
m_model->refresh();
|
||||
emit refreshComplete();
|
||||
|
||||
pxAssertRel(m_refresh_thread, "Has a refresh thread");
|
||||
m_refresh_thread->wait();
|
||||
delete m_refresh_thread;
|
||||
m_refresh_thread = nullptr;
|
||||
}
|
||||
|
||||
void GameListWidget::onSelectionModelCurrentChanged(const QModelIndex& current, const QModelIndex& previous)
|
||||
{
|
||||
const QModelIndex source_index = m_sort_model->mapToSource(current);
|
||||
if (!source_index.isValid() || source_index.row() >= static_cast<int>(GameList::GetEntryCount()))
|
||||
return;
|
||||
|
||||
emit selectionChanged();
|
||||
}
|
||||
|
||||
void GameListWidget::onTableViewItemActivated(const QModelIndex& index)
|
||||
{
|
||||
const QModelIndex source_index = m_sort_model->mapToSource(index);
|
||||
if (!source_index.isValid() || source_index.row() >= static_cast<int>(GameList::GetEntryCount()))
|
||||
return;
|
||||
|
||||
emit entryActivated();
|
||||
}
|
||||
|
||||
void GameListWidget::onTableViewContextMenuRequested(const QPoint& point)
|
||||
{
|
||||
emit entryContextMenuRequested(m_table_view->mapToGlobal(point));
|
||||
}
|
||||
|
||||
void GameListWidget::onListViewItemActivated(const QModelIndex& index)
|
||||
{
|
||||
const QModelIndex source_index = m_sort_model->mapToSource(index);
|
||||
if (!source_index.isValid() || source_index.row() >= static_cast<int>(GameList::GetEntryCount()))
|
||||
return;
|
||||
|
||||
emit entryActivated();
|
||||
}
|
||||
|
||||
void GameListWidget::onListViewContextMenuRequested(const QPoint& point)
|
||||
{
|
||||
emit entryContextMenuRequested(m_list_view->mapToGlobal(point));
|
||||
}
|
||||
|
||||
void GameListWidget::onTableViewHeaderContextMenuRequested(const QPoint& point)
|
||||
{
|
||||
QMenu menu;
|
||||
|
||||
for (int column = 0; column < GameListModel::Column_Count; column++)
|
||||
{
|
||||
if (column == GameListModel::Column_Cover)
|
||||
continue;
|
||||
|
||||
QAction* action = menu.addAction(m_model->getColumnDisplayName(column));
|
||||
action->setCheckable(true);
|
||||
action->setChecked(!m_table_view->isColumnHidden(column));
|
||||
connect(action, &QAction::toggled, [this, column](bool enabled) {
|
||||
m_table_view->setColumnHidden(column, !enabled);
|
||||
saveTableViewColumnVisibilitySettings(column);
|
||||
resizeTableViewColumnsToFit();
|
||||
});
|
||||
}
|
||||
|
||||
menu.exec(m_table_view->mapToGlobal(point));
|
||||
}
|
||||
|
||||
void GameListWidget::onTableViewHeaderSortIndicatorChanged(int, Qt::SortOrder)
|
||||
{
|
||||
saveTableViewColumnSortSettings();
|
||||
}
|
||||
|
||||
void GameListWidget::listZoom(float delta)
|
||||
{
|
||||
static constexpr float MIN_SCALE = 0.1f;
|
||||
static constexpr float MAX_SCALE = 2.0f;
|
||||
|
||||
const float new_scale = std::clamp(m_model->getCoverScale() + delta, MIN_SCALE, MAX_SCALE);
|
||||
QtHost::SetBaseFloatSettingValue("UI", "GameListCoverArtScale", new_scale);
|
||||
m_model->setCoverScale(new_scale);
|
||||
updateListFont();
|
||||
|
||||
m_model->refresh();
|
||||
}
|
||||
|
||||
void GameListWidget::gridZoomIn()
|
||||
{
|
||||
listZoom(0.05f);
|
||||
}
|
||||
|
||||
void GameListWidget::gridZoomOut()
|
||||
{
|
||||
listZoom(-0.05f);
|
||||
}
|
||||
|
||||
void GameListWidget::refreshGridCovers()
|
||||
{
|
||||
m_model->refreshCovers();
|
||||
}
|
||||
|
||||
void GameListWidget::showGameList()
|
||||
{
|
||||
if (currentIndex() == 0)
|
||||
return;
|
||||
|
||||
QtHost::SetBaseBoolSettingValue("UI", "GameListGridView", false);
|
||||
setCurrentIndex(0);
|
||||
resizeTableViewColumnsToFit();
|
||||
}
|
||||
|
||||
void GameListWidget::showGameGrid()
|
||||
{
|
||||
if (currentIndex() == 1)
|
||||
return;
|
||||
|
||||
QtHost::SetBaseBoolSettingValue("UI", "GameListGridView", true);
|
||||
setCurrentIndex(1);
|
||||
}
|
||||
|
||||
void GameListWidget::setShowCoverTitles(bool enabled)
|
||||
{
|
||||
if (m_model->getShowCoverTitles() == enabled)
|
||||
return;
|
||||
|
||||
QtHost::SetBaseBoolSettingValue("UI", "GameListShowCoverTitles", enabled);
|
||||
m_model->setShowCoverTitles(enabled);
|
||||
if (isShowingGameGrid())
|
||||
m_model->refresh();
|
||||
}
|
||||
|
||||
void GameListWidget::updateListFont()
|
||||
{
|
||||
QFont font;
|
||||
font.setPointSizeF(16.0f * m_model->getCoverScale());
|
||||
m_list_view->setFont(font);
|
||||
}
|
||||
|
||||
void GameListWidget::resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
QStackedWidget::resizeEvent(event);
|
||||
resizeTableViewColumnsToFit();
|
||||
}
|
||||
|
||||
void GameListWidget::resizeTableViewColumnsToFit()
|
||||
{
|
||||
QtUtils::ResizeColumnsForTableView(m_table_view, {
|
||||
32, // type
|
||||
80, // code
|
||||
-1, // title
|
||||
-1, // file title
|
||||
50, // crc
|
||||
80, // size
|
||||
50, // region
|
||||
100 // compatibility
|
||||
});
|
||||
}
|
||||
|
||||
static std::string getColumnVisibilitySettingsKeyName(int column)
|
||||
{
|
||||
return StringUtil::StdStringFromFormat("Show%s",
|
||||
GameListModel::getColumnName(static_cast<GameListModel::Column>(column)));
|
||||
}
|
||||
|
||||
void GameListWidget::loadTableViewColumnVisibilitySettings()
|
||||
{
|
||||
static constexpr std::array<bool, GameListModel::Column_Count> DEFAULT_VISIBILITY = {{
|
||||
true, // type
|
||||
true, // code
|
||||
true, // title
|
||||
false, // file title
|
||||
false, // crc
|
||||
true, // size
|
||||
true, // region
|
||||
true // compatibility
|
||||
}};
|
||||
|
||||
for (int column = 0; column < GameListModel::Column_Count; column++)
|
||||
{
|
||||
const bool visible = QtHost::GetBaseBoolSettingValue(
|
||||
"GameListTableView", getColumnVisibilitySettingsKeyName(column).c_str(), DEFAULT_VISIBILITY[column]);
|
||||
m_table_view->setColumnHidden(column, !visible);
|
||||
}
|
||||
}
|
||||
|
||||
void GameListWidget::saveTableViewColumnVisibilitySettings()
|
||||
{
|
||||
for (int column = 0; column < GameListModel::Column_Count; column++)
|
||||
{
|
||||
const bool visible = !m_table_view->isColumnHidden(column);
|
||||
QtHost::SetBaseBoolSettingValue("GameListTableView", getColumnVisibilitySettingsKeyName(column).c_str(), visible);
|
||||
}
|
||||
}
|
||||
|
||||
void GameListWidget::saveTableViewColumnVisibilitySettings(int column)
|
||||
{
|
||||
const bool visible = !m_table_view->isColumnHidden(column);
|
||||
QtHost::SetBaseBoolSettingValue("GameListTableView", getColumnVisibilitySettingsKeyName(column).c_str(), visible);
|
||||
}
|
||||
|
||||
void GameListWidget::loadTableViewColumnSortSettings()
|
||||
{
|
||||
const GameListModel::Column DEFAULT_SORT_COLUMN = GameListModel::Column_Type;
|
||||
const bool DEFAULT_SORT_DESCENDING = false;
|
||||
|
||||
const GameListModel::Column sort_column =
|
||||
GameListModel::getColumnIdForName(QtHost::GetBaseStringSettingValue("GameListTableView", "SortColumn"))
|
||||
.value_or(DEFAULT_SORT_COLUMN);
|
||||
const bool sort_descending =
|
||||
QtHost::GetBaseBoolSettingValue("GameListTableView", "SortDescending", DEFAULT_SORT_DESCENDING);
|
||||
m_table_view->sortByColumn(sort_column, sort_descending ? Qt::DescendingOrder : Qt::AscendingOrder);
|
||||
}
|
||||
|
||||
void GameListWidget::saveTableViewColumnSortSettings()
|
||||
{
|
||||
const int sort_column = m_table_view->horizontalHeader()->sortIndicatorSection();
|
||||
const bool sort_descending = (m_table_view->horizontalHeader()->sortIndicatorOrder() == Qt::DescendingOrder);
|
||||
|
||||
if (sort_column >= 0 && sort_column < GameListModel::Column_Count)
|
||||
{
|
||||
QtHost::SetBaseStringSettingValue(
|
||||
"GameListTableView", "SortColumn", GameListModel::getColumnName(static_cast<GameListModel::Column>(sort_column)));
|
||||
}
|
||||
|
||||
QtHost::SetBaseBoolSettingValue("GameListTableView", "SortDescending", sort_descending);
|
||||
}
|
||||
|
||||
const GameList::Entry* GameListWidget::getSelectedEntry() const
|
||||
{
|
||||
if (currentIndex() == 0)
|
||||
{
|
||||
const QItemSelectionModel* selection_model = m_table_view->selectionModel();
|
||||
if (!selection_model->hasSelection())
|
||||
return nullptr;
|
||||
|
||||
const QModelIndexList selected_rows = selection_model->selectedRows();
|
||||
if (selected_rows.empty())
|
||||
return nullptr;
|
||||
|
||||
const QModelIndex source_index = m_sort_model->mapToSource(selected_rows[0]);
|
||||
if (!source_index.isValid())
|
||||
return nullptr;
|
||||
|
||||
return GameList::GetEntryByIndex(source_index.row());
|
||||
}
|
||||
else
|
||||
{
|
||||
const QItemSelectionModel* selection_model = m_list_view->selectionModel();
|
||||
if (!selection_model->hasSelection())
|
||||
return nullptr;
|
||||
|
||||
const QModelIndex source_index = m_sort_model->mapToSource(selection_model->currentIndex());
|
||||
if (!source_index.isValid())
|
||||
return nullptr;
|
||||
|
||||
return GameList::GetEntryByIndex(source_index.row());
|
||||
}
|
||||
}
|
||||
|
||||
GameListGridListView::GameListGridListView(QWidget* parent /*= nullptr*/)
|
||||
: QListView(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void GameListGridListView::wheelEvent(QWheelEvent* e)
|
||||
{
|
||||
if (e->modifiers() & Qt::ControlModifier)
|
||||
{
|
||||
int dy = e->angleDelta().y();
|
||||
if (dy != 0)
|
||||
{
|
||||
if (dy < 0)
|
||||
zoomOut();
|
||||
else
|
||||
zoomIn();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QListView::wheelEvent(e);
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "pcsx2/Frontend/GameList.h"
|
||||
#include <QtWidgets/QListView>
|
||||
#include <QtWidgets/QStackedWidget>
|
||||
#include <QtWidgets/QTableView>
|
||||
|
||||
Q_DECLARE_METATYPE(const GameList::Entry*);
|
||||
|
||||
class GameListModel;
|
||||
class GameListSortModel;
|
||||
class GameListRefreshThread;
|
||||
|
||||
class GameListGridListView : public QListView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GameListGridListView(QWidget* parent = nullptr);
|
||||
|
||||
Q_SIGNALS:
|
||||
void zoomOut();
|
||||
void zoomIn();
|
||||
|
||||
protected:
|
||||
void wheelEvent(QWheelEvent* e);
|
||||
};
|
||||
|
||||
class GameListWidget : public QStackedWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GameListWidget(QWidget* parent = nullptr);
|
||||
~GameListWidget();
|
||||
|
||||
__fi GameListModel* getModel() const { return m_model; }
|
||||
|
||||
void initialize();
|
||||
|
||||
void refresh(bool invalidate_cache);
|
||||
|
||||
bool isShowingGameList() const;
|
||||
bool isShowingGameGrid() const;
|
||||
|
||||
bool getShowGridCoverTitles() const;
|
||||
|
||||
const GameList::Entry* getSelectedEntry() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void refreshProgress(const QString& status, int current, int total);
|
||||
void refreshComplete();
|
||||
|
||||
void selectionChanged();
|
||||
void entryActivated();
|
||||
void entryContextMenuRequested(const QPoint& point);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onRefreshProgress(const QString& status, int current, int total);
|
||||
void onRefreshComplete();
|
||||
|
||||
void onSelectionModelCurrentChanged(const QModelIndex& current, const QModelIndex& previous);
|
||||
void onTableViewItemActivated(const QModelIndex& index);
|
||||
void onTableViewContextMenuRequested(const QPoint& point);
|
||||
void onTableViewHeaderContextMenuRequested(const QPoint& point);
|
||||
void onTableViewHeaderSortIndicatorChanged(int, Qt::SortOrder);
|
||||
void onListViewItemActivated(const QModelIndex& index);
|
||||
void onListViewContextMenuRequested(const QPoint& point);
|
||||
|
||||
public Q_SLOTS:
|
||||
void showGameList();
|
||||
void showGameGrid();
|
||||
void setShowCoverTitles(bool enabled);
|
||||
void gridZoomIn();
|
||||
void gridZoomOut();
|
||||
void refreshGridCovers();
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent* event);
|
||||
|
||||
private:
|
||||
void resizeTableViewColumnsToFit();
|
||||
void loadTableViewColumnVisibilitySettings();
|
||||
void saveTableViewColumnVisibilitySettings();
|
||||
void saveTableViewColumnVisibilitySettings(int column);
|
||||
void loadTableViewColumnSortSettings();
|
||||
void saveTableViewColumnSortSettings();
|
||||
void listZoom(float delta);
|
||||
void updateListFont();
|
||||
|
||||
GameListModel* m_model = nullptr;
|
||||
GameListSortModel* m_sort_model = nullptr;
|
||||
QTableView* m_table_view = nullptr;
|
||||
GameListGridListView* m_list_view = nullptr;
|
||||
|
||||
GameListRefreshThread* m_refresh_thread = nullptr;
|
||||
};
|
|
@ -0,0 +1,264 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include <QtWidgets/QApplication>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "MainWindow.h"
|
||||
#include "EmuThread.h"
|
||||
#include "QtHost.h"
|
||||
|
||||
#include "CDVD/CDVD.h"
|
||||
#include "Frontend/GameList.h"
|
||||
#include "svnrev.h"
|
||||
|
||||
static void PrintCommandLineVersion()
|
||||
{
|
||||
std::fprintf(stderr, "PCSX2 Version %s\n", GIT_REV);
|
||||
std::fprintf(stderr, "https://pcsx2.net/\n");
|
||||
std::fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
static void PrintCommandLineHelp(const char* progname)
|
||||
{
|
||||
PrintCommandLineVersion();
|
||||
std::fprintf(stderr, "Usage: %s [parameters] [--] [boot filename]\n", progname);
|
||||
std::fprintf(stderr, "\n");
|
||||
std::fprintf(stderr, " -help: Displays this information and exits.\n");
|
||||
std::fprintf(stderr, " -version: Displays version information and exits.\n");
|
||||
std::fprintf(stderr, " -batch: Enables batch mode (exits after powering off).\n");
|
||||
std::fprintf(stderr, " -fastboot: Force fast boot for provided filename.\n");
|
||||
std::fprintf(stderr, " -slowboot: Force slow boot for provided filename.\n");
|
||||
std::fprintf(stderr, " -resume: Load resume save state. If a boot filename is provided,\n"
|
||||
" that game's resume state will be loaded, otherwise the most\n"
|
||||
" recent resume save state will be loaded.\n");
|
||||
std::fprintf(stderr, " -state <index>: Loads specified save state by index.\n");
|
||||
std::fprintf(stderr, " -statefile <filename>: Loads state from the specified filename.\n"
|
||||
" No boot filename is required with this option.\n");
|
||||
std::fprintf(stderr, " -fullscreen: Enters fullscreen mode immediately after starting.\n");
|
||||
std::fprintf(stderr, " -nofullscreen: Prevents fullscreen mode from triggering if enabled.\n");
|
||||
std::fprintf(stderr, " -portable: Forces \"portable mode\", data in same directory.\n");
|
||||
std::fprintf(stderr, " -settings <filename>: Loads a custom settings configuration from the\n"
|
||||
" specified filename. Default settings applied if file not found.\n");
|
||||
std::fprintf(stderr, " --: Signals that no more arguments will follow and the remaining\n"
|
||||
" parameters make up the filename. Use when the filename contains\n"
|
||||
" spaces or starts with a dash.\n");
|
||||
std::fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
static std::shared_ptr<VMBootParameters>& AutoBoot(std::shared_ptr<VMBootParameters>& autoboot)
|
||||
{
|
||||
if (!autoboot)
|
||||
{
|
||||
autoboot = std::make_shared<VMBootParameters>();
|
||||
autoboot->source_type = CDVD_SourceType::NoDisc;
|
||||
}
|
||||
return autoboot;
|
||||
}
|
||||
|
||||
static bool ParseCommandLineOptions(int argc, char* argv[], std::shared_ptr<VMBootParameters>& autoboot)
|
||||
{
|
||||
std::optional<bool> fast_boot;
|
||||
std::optional<bool> start_fullscreen;
|
||||
std::optional<s32> state_index;
|
||||
std::string state_filename;
|
||||
bool no_more_args = false;
|
||||
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
if (!no_more_args)
|
||||
{
|
||||
#define CHECK_ARG(str) !std::strcmp(argv[i], str)
|
||||
#define CHECK_ARG_PARAM(str) (!std::strcmp(argv[i], str) && ((i + 1) < argc))
|
||||
|
||||
if (CHECK_ARG("-help"))
|
||||
{
|
||||
PrintCommandLineHelp(argv[0]);
|
||||
return false;
|
||||
}
|
||||
else if (CHECK_ARG("-version"))
|
||||
{
|
||||
PrintCommandLineVersion();
|
||||
return false;
|
||||
}
|
||||
else if (CHECK_ARG("-batch"))
|
||||
{
|
||||
Console.WriteLn("Enabling batch mode.");
|
||||
AutoBoot(autoboot)->batch_mode = true;
|
||||
continue;
|
||||
}
|
||||
else if (CHECK_ARG("-fastboot"))
|
||||
{
|
||||
Console.WriteLn("Forcing fast boot.");
|
||||
fast_boot = true;
|
||||
continue;
|
||||
}
|
||||
else if (CHECK_ARG("-slowboot"))
|
||||
{
|
||||
Console.WriteLn("Forcing slow boot.");
|
||||
fast_boot = false;
|
||||
continue;
|
||||
}
|
||||
else if (CHECK_ARG("-resume"))
|
||||
{
|
||||
state_index = -1;
|
||||
continue;
|
||||
}
|
||||
else if (CHECK_ARG_PARAM("-state"))
|
||||
{
|
||||
state_index = std::atoi(argv[++i]);
|
||||
continue;
|
||||
}
|
||||
else if (CHECK_ARG_PARAM("-statefile"))
|
||||
{
|
||||
AutoBoot(autoboot)->save_state = argv[++i];
|
||||
continue;
|
||||
}
|
||||
else if (CHECK_ARG_PARAM("-elf"))
|
||||
{
|
||||
AutoBoot(autoboot)->elf_override = argv[++i];
|
||||
continue;
|
||||
}
|
||||
else if (CHECK_ARG("-fullscreen"))
|
||||
{
|
||||
Console.WriteLn("Going fullscreen after booting.");
|
||||
start_fullscreen = true;
|
||||
continue;
|
||||
}
|
||||
else if (CHECK_ARG("-nofullscreen"))
|
||||
{
|
||||
Console.WriteLn("Preventing fullscreen after booting.");
|
||||
start_fullscreen = false;
|
||||
continue;
|
||||
}
|
||||
else if (CHECK_ARG("-portable"))
|
||||
{
|
||||
Console.WriteLn("Using portable mode.");
|
||||
// SetUserDirectoryToProgramDirectory();
|
||||
continue;
|
||||
}
|
||||
else if (CHECK_ARG("-resume"))
|
||||
{
|
||||
state_index = -1;
|
||||
continue;
|
||||
}
|
||||
else if (CHECK_ARG("--"))
|
||||
{
|
||||
no_more_args = true;
|
||||
continue;
|
||||
}
|
||||
else if (argv[i][0] == '-')
|
||||
{
|
||||
Console.Error("Unknown parameter: '%s'", argv[i]);
|
||||
return false;
|
||||
}
|
||||
|
||||
#undef CHECK_ARG
|
||||
#undef CHECK_ARG_PARAM
|
||||
}
|
||||
|
||||
if (!AutoBoot(autoboot)->source.empty())
|
||||
AutoBoot(autoboot)->source += ' ';
|
||||
else
|
||||
AutoBoot(autoboot)->source_type = CDVD_SourceType::Iso;
|
||||
|
||||
AutoBoot(autoboot)->source += argv[i];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
QApplication app(argc, argv);
|
||||
std::shared_ptr<VMBootParameters> autoboot;
|
||||
if (!ParseCommandLineOptions(argc, argv, autoboot))
|
||||
return EXIT_FAILURE;
|
||||
|
||||
MainWindow* main_window = new MainWindow(QApplication::style()->objectName());
|
||||
|
||||
if (!QtHost::Initialize())
|
||||
{
|
||||
delete main_window;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
main_window->initialize();
|
||||
EmuThread::start();
|
||||
|
||||
main_window->refreshGameList(false);
|
||||
main_window->show();
|
||||
|
||||
if (autoboot)
|
||||
g_emu_thread->startVM(std::move(autoboot));
|
||||
|
||||
const int result = app.exec();
|
||||
|
||||
EmuThread::stop();
|
||||
QtHost::Shutdown();
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
// Apparently Qt6 got rid of this?
|
||||
#include "common/RedtapeWindows.h"
|
||||
#include <shellapi.h>
|
||||
|
||||
/*
|
||||
WinMain() - Initializes Windows and calls user's startup function main().
|
||||
NOTE: WinMain() won't be called if the application was linked as a "console"
|
||||
application.
|
||||
*/
|
||||
|
||||
// Convert a wchar_t to char string, equivalent to QString::toLocal8Bit()
|
||||
// when passed CP_ACP.
|
||||
static inline char* wideToMulti(unsigned int codePage, const wchar_t* aw)
|
||||
{
|
||||
const int required = WideCharToMultiByte(codePage, 0, aw, -1, nullptr, 0, nullptr, nullptr);
|
||||
char* result = new char[required];
|
||||
WideCharToMultiByte(codePage, 0, aw, -1, result, required, nullptr, nullptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
extern "C" int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR /*cmdParamarg*/, int /* cmdShow */)
|
||||
{
|
||||
int argc = 0;
|
||||
wchar_t** argvW = CommandLineToArgvW(GetCommandLineW(), &argc);
|
||||
if (argvW == nullptr)
|
||||
return -1;
|
||||
char** argv = new char*[argc + 1];
|
||||
for (int i = 0; i != argc; ++i)
|
||||
argv[i] = wideToMulti(CP_ACP, argvW[i]);
|
||||
argv[argc] = nullptr;
|
||||
LocalFree(argvW);
|
||||
const int exitCode = main(argc, argv);
|
||||
for (int i = 0; (i != argc) && (argv[i] != nullptr); ++i)
|
||||
delete[] argv[i];
|
||||
delete[] argv;
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,177 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtWidgets/QMainWindow>
|
||||
#include <optional>
|
||||
|
||||
#include "Settings/ControllerSettingsDialog.h"
|
||||
#include "Settings/SettingsDialog.h"
|
||||
#include "ui_MainWindow.h"
|
||||
|
||||
class QProgressBar;
|
||||
|
||||
class DisplayWidget;
|
||||
class DisplayContainer;
|
||||
class GameListWidget;
|
||||
class ControllerSettingsDialog;
|
||||
|
||||
class EmuThread;
|
||||
|
||||
namespace GameList
|
||||
{
|
||||
struct Entry;
|
||||
}
|
||||
|
||||
class MainWindow final : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static const char* DEFAULT_THEME_NAME;
|
||||
|
||||
public:
|
||||
explicit MainWindow(const QString& unthemed_style_name);
|
||||
~MainWindow();
|
||||
|
||||
void initialize();
|
||||
void connectVMThreadSignals(EmuThread* thread);
|
||||
|
||||
public Q_SLOTS:
|
||||
void refreshGameList(bool invalidate_cache);
|
||||
void invalidateSaveStateCache();
|
||||
void reportError(const QString& title, const QString& message);
|
||||
|
||||
private Q_SLOTS:
|
||||
DisplayWidget* createDisplay(bool fullscreen, bool render_to_main);
|
||||
DisplayWidget* updateDisplay(bool fullscreen, bool render_to_main);
|
||||
void displayResizeRequested(qint32 width, qint32 height);
|
||||
void destroyDisplay();
|
||||
void focusDisplayWidget();
|
||||
|
||||
void onGameListRefreshComplete();
|
||||
void onGameListRefreshProgress(const QString& status, int current, int total);
|
||||
void onGameListSelectionChanged();
|
||||
void onGameListEntryActivated();
|
||||
void onGameListEntryContextMenuRequested(const QPoint& point);
|
||||
|
||||
void onStartFileActionTriggered();
|
||||
void onStartBIOSActionTriggered();
|
||||
void onChangeDiscFromFileActionTriggered();
|
||||
void onChangeDiscFromGameListActionTriggered();
|
||||
void onChangeDiscFromDeviceActionTriggered();
|
||||
void onChangeDiscMenuAboutToShow();
|
||||
void onChangeDiscMenuAboutToHide();
|
||||
void onLoadStateMenuAboutToShow();
|
||||
void onSaveStateMenuAboutToShow();
|
||||
void onViewToolbarActionToggled(bool checked);
|
||||
void onViewLockToolbarActionToggled(bool checked);
|
||||
void onViewStatusBarActionToggled(bool checked);
|
||||
void onViewGameListActionTriggered();
|
||||
void onViewGameGridActionTriggered();
|
||||
void onViewSystemDisplayTriggered();
|
||||
void onViewGamePropertiesActionTriggered();
|
||||
void onGitHubRepositoryActionTriggered();
|
||||
void onSupportForumsActionTriggered();
|
||||
void onDiscordServerActionTriggered();
|
||||
void onAboutActionTriggered();
|
||||
void onCheckForUpdatesActionTriggered();
|
||||
void onToolsOpenDataDirectoryTriggered();
|
||||
void onThemeChanged();
|
||||
void onThemeChangedFromSettings();
|
||||
|
||||
void onVMStarting();
|
||||
void onVMStarted();
|
||||
void onVMPaused();
|
||||
void onVMResumed();
|
||||
void onVMStopped();
|
||||
|
||||
void onGameChanged(const QString& path, const QString& serial, const QString& name, quint32 crc);
|
||||
|
||||
void recreate();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent* event);
|
||||
|
||||
private:
|
||||
enum : s32
|
||||
{
|
||||
NUM_SAVE_STATE_SLOTS = 10,
|
||||
};
|
||||
|
||||
void setupAdditionalUi();
|
||||
void connectSignals();
|
||||
void setStyleFromSettings();
|
||||
void setIconThemeFromSettings();
|
||||
|
||||
void saveStateToConfig();
|
||||
void restoreStateFromConfig();
|
||||
|
||||
void updateEmulationActions(bool starting, bool running);
|
||||
void updateWindowTitle();
|
||||
void setProgressBar(int current, int total);
|
||||
void clearProgressBar();
|
||||
|
||||
bool isShowingGameList() const;
|
||||
void switchToGameListView();
|
||||
void switchToEmulationView();
|
||||
|
||||
QWidget* getDisplayContainer() const;
|
||||
void saveDisplayWindowGeometryToConfig();
|
||||
void restoreDisplayWindowGeometryFromConfig();
|
||||
void destroyDisplayWidget();
|
||||
void setDisplayFullscreen(const std::string& fullscreen_mode);
|
||||
|
||||
SettingsDialog* getSettingsDialog();
|
||||
void doSettings(SettingsDialog::Category category = SettingsDialog::Category::Count);
|
||||
|
||||
ControllerSettingsDialog* getControllerSettingsDialog();
|
||||
void doControllerSettings(ControllerSettingsDialog::Category category = ControllerSettingsDialog::Category::Count);
|
||||
|
||||
void startGameListEntry(const GameList::Entry* entry, std::optional<s32> save_slot = std::nullopt,
|
||||
std::optional<bool> fast_boot = std::nullopt);
|
||||
void setGameListEntryCoverImage(const GameList::Entry* entry);
|
||||
|
||||
void loadSaveStateSlot(s32 slot);
|
||||
void loadSaveStateFile(const QString& filename, const QString& state_filename);
|
||||
void populateLoadStateMenu(QMenu* menu, const QString& filename, const QString& serial, quint32 crc);
|
||||
void populateSaveStateMenu(QMenu* menu, const QString& serial, quint32 crc);
|
||||
void updateSaveStateMenus(const QString& filename, const QString& serial, quint32 crc);
|
||||
|
||||
Ui::MainWindow m_ui;
|
||||
|
||||
QString m_unthemed_style_name;
|
||||
|
||||
GameListWidget* m_game_list_widget = nullptr;
|
||||
DisplayWidget* m_display_widget = nullptr;
|
||||
DisplayContainer* m_display_container = nullptr;
|
||||
|
||||
SettingsDialog* m_settings_dialog = nullptr;
|
||||
ControllerSettingsDialog* m_controller_settings_dialog = nullptr;
|
||||
|
||||
QProgressBar* m_status_progress_widget = nullptr;
|
||||
|
||||
QString m_current_disc_path;
|
||||
QString m_current_game_serial;
|
||||
QString m_current_game_name;
|
||||
quint32 m_current_game_crc;
|
||||
bool m_vm_valid = false;
|
||||
bool m_vm_paused = false;
|
||||
bool m_save_states_invalidated = false;
|
||||
bool m_was_focused_on_container_switch = false;
|
||||
};
|
||||
|
||||
extern MainWindow* g_main_window;
|
|
@ -0,0 +1,648 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>700</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="acceptDrops">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>PCSX2</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="resources/resources.qrc">
|
||||
<normaloff>:/icons/AppIcon.png</normaloff>:/icons/AppIcon.png</iconset>
|
||||
</property>
|
||||
<widget class="QStackedWidget" name="mainContainer">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page"/>
|
||||
<widget class="QWidget" name="page_2"/>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menuBar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuSystem">
|
||||
<property name="title">
|
||||
<string>&System</string>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuChangeDisc">
|
||||
<property name="title">
|
||||
<string>Change Disc</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="dvd-line"/>
|
||||
</property>
|
||||
<actiongroup name="actionGroupChangeDiscSubImages"/>
|
||||
<addaction name="actionChangeDiscFromFile"/>
|
||||
<addaction name="actionChangeDiscFromDevice"/>
|
||||
<addaction name="actionChangeDiscFromGameList"/>
|
||||
<addaction name="actionRemoveDisc"/>
|
||||
<addaction name="separator"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuCheats">
|
||||
<property name="title">
|
||||
<string>Cheats</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="flask-line"/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuLoadState">
|
||||
<property name="title">
|
||||
<string>Load State</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="folder-open-line"/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuSaveState">
|
||||
<property name="title">
|
||||
<string>Save State</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="save-3-line"/>
|
||||
</property>
|
||||
</widget>
|
||||
<addaction name="actionStartFile"/>
|
||||
<addaction name="actionStartDisc"/>
|
||||
<addaction name="actionStartBios"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionPowerOff"/>
|
||||
<addaction name="actionReset"/>
|
||||
<addaction name="actionPause"/>
|
||||
<addaction name="menuChangeDisc"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="menuCheats"/>
|
||||
<addaction name="actionScreenshot"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="menuLoadState"/>
|
||||
<addaction name="menuSaveState"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionExit"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuSettings">
|
||||
<property name="title">
|
||||
<string>S&ettings</string>
|
||||
</property>
|
||||
<addaction name="actionInterfaceSettings"/>
|
||||
<addaction name="actionGameListSettings"/>
|
||||
<addaction name="actionBIOSSettings"/>
|
||||
<addaction name="actionEmulationSettings"/>
|
||||
<addaction name="actionSystemSettings"/>
|
||||
<addaction name="actionGraphicsSettings"/>
|
||||
<addaction name="actionAudioSettings"/>
|
||||
<addaction name="actionMemoryCardSettings"/>
|
||||
<addaction name="actionControllerSettings"/>
|
||||
<addaction name="actionHotkeySettings"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionAddGameDirectory"/>
|
||||
<addaction name="actionScanForNewGames"/>
|
||||
<addaction name="actionRescanAllGames"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuHelp">
|
||||
<property name="title">
|
||||
<string>&Help</string>
|
||||
</property>
|
||||
<addaction name="actionGitHubRepository"/>
|
||||
<addaction name="actionSupportForums"/>
|
||||
<addaction name="actionDiscordServer"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionCheckForUpdates"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionAboutQt"/>
|
||||
<addaction name="actionAbout"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuDebug">
|
||||
<property name="title">
|
||||
<string>&Debug</string>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuDebugSwitchRenderer">
|
||||
<property name="title">
|
||||
<string>Switch Renderer</string>
|
||||
</property>
|
||||
</widget>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionToggleSoftwareRendering"/>
|
||||
<addaction name="menuDebugSwitchRenderer"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionReloadPatches"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menu_View">
|
||||
<property name="title">
|
||||
<string>&View</string>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuWindowSize">
|
||||
<property name="title">
|
||||
<string>&Window Size</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="window-2-line"/>
|
||||
</property>
|
||||
</widget>
|
||||
<addaction name="actionViewToolbar"/>
|
||||
<addaction name="actionViewLockToolbar"/>
|
||||
<addaction name="actionViewStatusBar"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionViewGameList"/>
|
||||
<addaction name="actionViewGameGrid"/>
|
||||
<addaction name="actionViewSystemDisplay"/>
|
||||
<addaction name="actionViewGameProperties"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionFullscreen"/>
|
||||
<addaction name="menuWindowSize"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionGridViewShowTitles"/>
|
||||
<addaction name="actionGridViewZoomIn"/>
|
||||
<addaction name="actionGridViewZoomOut"/>
|
||||
<addaction name="actionGridViewRefreshCovers"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menu_Tools">
|
||||
<property name="title">
|
||||
<string>&Tools</string>
|
||||
</property>
|
||||
<addaction name="actionOpenDataDirectory"/>
|
||||
</widget>
|
||||
<addaction name="menuSystem"/>
|
||||
<addaction name="menuSettings"/>
|
||||
<addaction name="menu_View"/>
|
||||
<addaction name="menu_Tools"/>
|
||||
<addaction name="menuDebug"/>
|
||||
<addaction name="menuHelp"/>
|
||||
</widget>
|
||||
<widget class="QToolBar" name="toolBar">
|
||||
<property name="windowTitle">
|
||||
<string>toolBar</string>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonTextUnderIcon</enum>
|
||||
</property>
|
||||
<attribute name="toolBarArea">
|
||||
<enum>TopToolBarArea</enum>
|
||||
</attribute>
|
||||
<attribute name="toolBarBreak">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<addaction name="actionStartFile"/>
|
||||
<addaction name="actionStartDisc"/>
|
||||
<addaction name="actionStartBios"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionPowerOff"/>
|
||||
<addaction name="actionReset"/>
|
||||
<addaction name="actionPause"/>
|
||||
<addaction name="actionChangeDisc"/>
|
||||
<addaction name="actionCheats"/>
|
||||
<addaction name="actionScreenshot"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionLoadState"/>
|
||||
<addaction name="actionSaveState"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionFullscreen"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionSettings"/>
|
||||
<addaction name="actionControllerSettings"/>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusBar"/>
|
||||
<action name="actionStartFile">
|
||||
<property name="text">
|
||||
<string>Start &File...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="file-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionStartDisc">
|
||||
<property name="text">
|
||||
<string>Start &Disc...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="disc-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionStartBios">
|
||||
<property name="text">
|
||||
<string>Start &BIOS</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="hard-drive-2-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionScanForNewGames">
|
||||
<property name="text">
|
||||
<string>&Scan For New Games</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="file-search-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRescanAllGames">
|
||||
<property name="text">
|
||||
<string>&Rescan All Games</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="refresh-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPowerOff">
|
||||
<property name="text">
|
||||
<string>Shut &Down</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="shut-down-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionReset">
|
||||
<property name="text">
|
||||
<string>&Reset</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="restart-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPause">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Pause</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="pause-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionLoadState">
|
||||
<property name="text">
|
||||
<string>&Load State</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="folder-open-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSaveState">
|
||||
<property name="text">
|
||||
<string>&Save State</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="save-3-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionExit">
|
||||
<property name="text">
|
||||
<string>E&xit</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="door-open-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionBIOSSettings">
|
||||
<property name="text">
|
||||
<string>&BIOS</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="hard-drive-2-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSystemSettings">
|
||||
<property name="text">
|
||||
<string>System</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="artboard-2-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEmulationSettings">
|
||||
<property name="text">
|
||||
<string>Emulation</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="dashboard-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionControllerSettings">
|
||||
<property name="text">
|
||||
<string>&Controllers</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="gamepad-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionHotkeySettings">
|
||||
<property name="text">
|
||||
<string>&Hotkeys</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="keyboard-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionGraphicsSettings">
|
||||
<property name="text">
|
||||
<string>&Graphics</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="brush-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPostProcessingSettings">
|
||||
<property name="text">
|
||||
<string>&Post-Processing Settings...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionFullscreen">
|
||||
<property name="text">
|
||||
<string>Fullscreen</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="fullscreen-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionResolution_Scale">
|
||||
<property name="text">
|
||||
<string>Resolution Scale</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionGitHubRepository">
|
||||
<property name="text">
|
||||
<string>&GitHub Repository...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSupportForums">
|
||||
<property name="text">
|
||||
<string>Support &Forums...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionDiscordServer">
|
||||
<property name="text">
|
||||
<string>&Discord Server...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCheckForUpdates">
|
||||
<property name="icon">
|
||||
<iconset theme="download-2-line"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Check for &Updates...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAboutQt">
|
||||
<property name="icon">
|
||||
<iconset resource="resources/resources.qrc">
|
||||
<normaloff>:/icons/QT.png</normaloff>:/icons/QT.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>About &Qt...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAbout">
|
||||
<property name="text">
|
||||
<string>&About PCSX2...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionChangeDisc">
|
||||
<property name="text">
|
||||
<string>Change Disc...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="dvd-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCheats">
|
||||
<property name="text">
|
||||
<string>Cheats...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="flask-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAudioSettings">
|
||||
<property name="text">
|
||||
<string>&Audio</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="volume-up-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionGameListSettings">
|
||||
<property name="text">
|
||||
<string>Game List</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="folder-settings-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionInterfaceSettings">
|
||||
<property name="text">
|
||||
<string>Interface</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="settings-3-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAddGameDirectory">
|
||||
<property name="text">
|
||||
<string>Add Game Directory...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="folder-add-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSettings">
|
||||
<property name="text">
|
||||
<string>&Settings...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="settings-3-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionChangeDiscFromFile">
|
||||
<property name="text">
|
||||
<string>From File...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionChangeDiscFromDevice">
|
||||
<property name="text">
|
||||
<string>From Device...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionChangeDiscFromGameList">
|
||||
<property name="text">
|
||||
<string>From Game List...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRemoveDisc">
|
||||
<property name="text">
|
||||
<string>Remove Disc</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionGlobal_State">
|
||||
<property name="text">
|
||||
<string>Global State</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionScreenshot">
|
||||
<property name="text">
|
||||
<string>&Screenshot</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="screenshot-2-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionMemoryCardSettings">
|
||||
<property name="text">
|
||||
<string>&Memory Cards</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="sd-card-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionViewToolbar">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Toolbar</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionViewLockToolbar">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Lock Toolbar</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionViewStatusBar">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Status Bar</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionViewGameList">
|
||||
<property name="text">
|
||||
<string>Game &List</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="list-check"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionViewSystemDisplay">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>System &Display</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="tv-2-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionViewGameProperties">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Game &Properties</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="file-settings-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionViewGameGrid">
|
||||
<property name="text">
|
||||
<string>Game &Grid</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="function-line"/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionGridViewShowTitles">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show Titles (Grid View)</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionGridViewZoomIn">
|
||||
<property name="text">
|
||||
<string>Zoom &In (Grid View)</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl++</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionGridViewZoomOut">
|
||||
<property name="text">
|
||||
<string>Zoom &Out (Grid View)</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+-</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionGridViewRefreshCovers">
|
||||
<property name="text">
|
||||
<string>Refresh &Covers (Grid View)</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionOpen_Memory_Card_Directory">
|
||||
<property name="text">
|
||||
<string>Open Memory Card Directory...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionOpenDataDirectory">
|
||||
<property name="text">
|
||||
<string>Open Data Directory...</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionToggleSoftwareRendering">
|
||||
<property name="text">
|
||||
<string>Toggle Software Rendering</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionReloadPatches">
|
||||
<property name="text">
|
||||
<string>Reload Cheats/Patches</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="resources/resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,16 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
|
@ -0,0 +1,21 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pcsx2/PrecompiledHeader.h"
|
||||
|
||||
// Needed because of moc shenanigans with pch.
|
||||
#include <memory>
|
||||
|
||||
#include <QtCore/QtCore>
|
|
@ -0,0 +1,506 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "common/Assertions.h"
|
||||
#include "common/Console.h"
|
||||
#include "common/FileSystem.h"
|
||||
#include "common/SettingsWrapper.h"
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
#include "pcsx2/Frontend/GameList.h"
|
||||
#include "pcsx2/Frontend/INISettingsInterface.h"
|
||||
#include "pcsx2/HostSettings.h"
|
||||
#include "pcsx2/PAD/Host/PAD.h"
|
||||
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
|
||||
#include "EmuThread.h"
|
||||
#include "GameList/GameListWidget.h"
|
||||
#include "MainWindow.h"
|
||||
#include "QtHost.h"
|
||||
|
||||
#include "pcsx2/DebugTools/Debug.h"
|
||||
|
||||
static constexpr u32 SETTINGS_VERSION = 1;
|
||||
static constexpr u32 SETTINGS_SAVE_DELAY = 1000;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Local function declarations
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
static void InitializeWxRubbish();
|
||||
static bool InitializeConfig();
|
||||
static void SetDefaultConfig();
|
||||
static void QueueSettingsSave();
|
||||
static void SaveSettings();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Local variable declarations
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
static std::unique_ptr<QTimer> s_settings_save_timer;
|
||||
static std::unique_ptr<INISettingsInterface> s_base_settings_interface;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Initialization/Shutdown
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool QtHost::Initialize()
|
||||
{
|
||||
qRegisterMetaType<std::shared_ptr<VMBootParameters>>();
|
||||
qRegisterMetaType<GSRendererType>();
|
||||
qRegisterMetaType<const GameList::Entry*>();
|
||||
qRegisterMetaType<InputBindingKey>();
|
||||
|
||||
InitializeWxRubbish();
|
||||
if (!InitializeConfig())
|
||||
{
|
||||
Console.WriteLn("Failed to initialize config.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void QtHost::Shutdown() {}
|
||||
|
||||
static bool SetCriticalFolders()
|
||||
{
|
||||
std::string program_path(FileSystem::GetProgramPath());
|
||||
EmuFolders::AppRoot = wxDirName(wxFileName(StringUtil::UTF8StringToWxString(program_path)));
|
||||
EmuFolders::DataRoot = EmuFolders::AppRoot;
|
||||
#ifndef _WIN32
|
||||
const char* homedir = getenv("HOME");
|
||||
if (homedir)
|
||||
EmuFolders::DataRoot = Path::Combine(wxString::FromUTF8(homedir), wxString(L"PCSX2"));
|
||||
#endif
|
||||
|
||||
EmuFolders::Settings = EmuFolders::DataRoot.Combine(wxDirName(L"inis"));
|
||||
EmuFolders::Resources = EmuFolders::AppRoot.Combine(wxDirName(L"resources"));
|
||||
|
||||
// the resources directory should exist, bail out if not
|
||||
if (!EmuFolders::Resources.Exists())
|
||||
{
|
||||
QMessageBox::critical(nullptr, QStringLiteral("Error"),
|
||||
QStringLiteral("Resources directory is missing, your installation is incomplete."));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void QtHost::UpdateFolders()
|
||||
{
|
||||
// TODO: This should happen with the VM thread paused.
|
||||
auto lock = Host::GetSettingsLock();
|
||||
EmuFolders::LoadConfig(*s_base_settings_interface.get());
|
||||
EmuFolders::EnsureFoldersExist();
|
||||
}
|
||||
|
||||
bool InitializeConfig()
|
||||
{
|
||||
if (!SetCriticalFolders())
|
||||
return false;
|
||||
|
||||
const std::string path(Path::CombineStdString(EmuFolders::Settings, "PCSX2.ini"));
|
||||
s_base_settings_interface = std::make_unique<INISettingsInterface>(std::move(path));
|
||||
Host::Internal::SetBaseSettingsLayer(s_base_settings_interface.get());
|
||||
|
||||
uint settings_version;
|
||||
if (!s_base_settings_interface->Load() ||
|
||||
!s_base_settings_interface->GetUIntValue("UI", "SettingsVersion", &settings_version) ||
|
||||
settings_version != SETTINGS_VERSION)
|
||||
{
|
||||
QMessageBox::critical(
|
||||
g_main_window, qApp->translate("QtHost", "Settings Reset"),
|
||||
qApp->translate("QtHost", "Settings do not exist or are the incorrect version, resetting to defaults."));
|
||||
SetDefaultConfig();
|
||||
s_base_settings_interface->Save();
|
||||
}
|
||||
|
||||
// TODO: Handle reset to defaults if load fails.
|
||||
EmuFolders::LoadConfig(*s_base_settings_interface.get());
|
||||
EmuFolders::EnsureFoldersExist();
|
||||
QtHost::UpdateLogging();
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetDefaultConfig()
|
||||
{
|
||||
EmuConfig = Pcsx2Config();
|
||||
EmuFolders::SetDefaults();
|
||||
|
||||
SettingsInterface& si = *s_base_settings_interface.get();
|
||||
si.SetUIntValue("UI", "SettingsVersion", SETTINGS_VERSION);
|
||||
|
||||
{
|
||||
SettingsSaveWrapper wrapper(si);
|
||||
EmuConfig.LoadSave(wrapper);
|
||||
}
|
||||
|
||||
EmuFolders::Save(si);
|
||||
PAD::SetDefaultConfig(si);
|
||||
}
|
||||
|
||||
std::string QtHost::GetBaseStringSettingValue(const char* section, const char* key, const char* default_value /*= ""*/)
|
||||
{
|
||||
auto lock = Host::GetSettingsLock();
|
||||
return s_base_settings_interface->GetStringValue(section, key, default_value);
|
||||
}
|
||||
|
||||
bool QtHost::GetBaseBoolSettingValue(const char* section, const char* key, bool default_value /*= false*/)
|
||||
{
|
||||
auto lock = Host::GetSettingsLock();
|
||||
return s_base_settings_interface->GetBoolValue(section, key, default_value);
|
||||
}
|
||||
|
||||
int QtHost::GetBaseIntSettingValue(const char* section, const char* key, int default_value /*= 0*/)
|
||||
{
|
||||
auto lock = Host::GetSettingsLock();
|
||||
return s_base_settings_interface->GetIntValue(section, key, default_value);
|
||||
}
|
||||
|
||||
float QtHost::GetBaseFloatSettingValue(const char* section, const char* key, float default_value /*= 0.0f*/)
|
||||
{
|
||||
auto lock = Host::GetSettingsLock();
|
||||
return s_base_settings_interface->GetFloatValue(section, key, default_value);
|
||||
}
|
||||
|
||||
std::vector<std::string> QtHost::GetBaseStringListSetting(const char* section, const char* key)
|
||||
{
|
||||
auto lock = Host::GetSettingsLock();
|
||||
return s_base_settings_interface->GetStringList(section, key);
|
||||
}
|
||||
|
||||
void QtHost::SetBaseBoolSettingValue(const char* section, const char* key, bool value)
|
||||
{
|
||||
auto lock = Host::GetSettingsLock();
|
||||
s_base_settings_interface->SetBoolValue(section, key, value);
|
||||
QueueSettingsSave();
|
||||
}
|
||||
|
||||
void QtHost::SetBaseIntSettingValue(const char* section, const char* key, int value)
|
||||
{
|
||||
auto lock = Host::GetSettingsLock();
|
||||
s_base_settings_interface->SetIntValue(section, key, value);
|
||||
QueueSettingsSave();
|
||||
}
|
||||
|
||||
void QtHost::SetBaseFloatSettingValue(const char* section, const char* key, float value)
|
||||
{
|
||||
auto lock = Host::GetSettingsLock();
|
||||
s_base_settings_interface->SetFloatValue(section, key, value);
|
||||
QueueSettingsSave();
|
||||
}
|
||||
|
||||
void QtHost::SetBaseStringSettingValue(const char* section, const char* key, const char* value)
|
||||
{
|
||||
auto lock = Host::GetSettingsLock();
|
||||
s_base_settings_interface->SetStringValue(section, key, value);
|
||||
QueueSettingsSave();
|
||||
}
|
||||
|
||||
void QtHost::SetBaseStringListSettingValue(const char* section, const char* key, const std::vector<std::string>& values)
|
||||
{
|
||||
auto lock = Host::GetSettingsLock();
|
||||
s_base_settings_interface->SetStringList(section, key, values);
|
||||
QueueSettingsSave();
|
||||
}
|
||||
|
||||
bool QtHost::AddBaseValueToStringList(const char* section, const char* key, const char* value)
|
||||
{
|
||||
auto lock = Host::GetSettingsLock();
|
||||
if (!s_base_settings_interface->AddToStringList(section, key, value))
|
||||
return false;
|
||||
|
||||
QueueSettingsSave();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QtHost::RemoveBaseValueFromStringList(const char* section, const char* key, const char* value)
|
||||
{
|
||||
auto lock = Host::GetSettingsLock();
|
||||
if (!s_base_settings_interface->RemoveFromStringList(section, key, value))
|
||||
return false;
|
||||
|
||||
QueueSettingsSave();
|
||||
return true;
|
||||
}
|
||||
|
||||
void QtHost::RemoveBaseSettingValue(const char* section, const char* key)
|
||||
{
|
||||
auto lock = Host::GetSettingsLock();
|
||||
s_base_settings_interface->DeleteValue(section, key);
|
||||
QueueSettingsSave();
|
||||
}
|
||||
|
||||
void SaveSettings()
|
||||
{
|
||||
pxAssertRel(!g_emu_thread->isOnEmuThread(), "Saving should happen on the UI thread.");
|
||||
|
||||
{
|
||||
auto lock = Host::GetSettingsLock();
|
||||
if (!s_base_settings_interface->Save())
|
||||
Console.Error("Failed to save settings.");
|
||||
}
|
||||
|
||||
s_settings_save_timer->deleteLater();
|
||||
s_settings_save_timer.release();
|
||||
}
|
||||
|
||||
void QueueSettingsSave()
|
||||
{
|
||||
if (s_settings_save_timer)
|
||||
return;
|
||||
|
||||
s_settings_save_timer = std::make_unique<QTimer>();
|
||||
s_settings_save_timer->connect(s_settings_save_timer.get(), &QTimer::timeout, SaveSettings);
|
||||
s_settings_save_timer->setSingleShot(true);
|
||||
s_settings_save_timer->start(SETTINGS_SAVE_DELAY);
|
||||
}
|
||||
|
||||
std::optional<std::vector<u8>> Host::ReadResourceFile(const char* filename)
|
||||
{
|
||||
const std::string path(Path::CombineStdString(EmuFolders::Resources, filename));
|
||||
std::optional<std::vector<u8>> ret(FileSystem::ReadBinaryFile(path.c_str()));
|
||||
if (!ret.has_value())
|
||||
Console.Error("Failed to read resource file '%s'", filename);
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::optional<std::string> Host::ReadResourceFileToString(const char* filename)
|
||||
{
|
||||
const std::string path(Path::CombineStdString(EmuFolders::Resources, filename));
|
||||
std::optional<std::string> ret(FileSystem::ReadFileToString(path.c_str()));
|
||||
if (!ret.has_value())
|
||||
Console.Error("Failed to read resource file to string '%s'", filename);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Host::ReportErrorAsync(const std::string_view& title, const std::string_view& message)
|
||||
{
|
||||
if (!title.empty() && !message.empty())
|
||||
{
|
||||
Console.Error("ReportErrorAsync: %*s: %*s",
|
||||
static_cast<int>(title.size()), title.data(),
|
||||
static_cast<int>(message.size()), message.data());
|
||||
}
|
||||
else if (!message.empty())
|
||||
{
|
||||
Console.Error("ReportErrorAsync: %*s",
|
||||
static_cast<int>(message.size()), message.data());
|
||||
}
|
||||
|
||||
QMetaObject::invokeMethod(g_main_window, "reportError", Qt::QueuedConnection,
|
||||
Q_ARG(const QString&, title.empty() ? QString() : QString::fromUtf8(title.data(), title.size())),
|
||||
Q_ARG(const QString&, message.empty() ? QString() : QString::fromUtf8(message.data(), message.size())));
|
||||
}
|
||||
|
||||
void Host::OnInputDeviceConnected(const std::string_view& identifier, const std::string_view& device_name)
|
||||
{
|
||||
emit g_emu_thread->onInputDeviceConnected(
|
||||
identifier.empty() ? QString() : QString::fromUtf8(identifier.data(), identifier.size()),
|
||||
device_name.empty() ? QString() : QString::fromUtf8(device_name.data(), device_name.size()));
|
||||
}
|
||||
|
||||
void Host::OnInputDeviceDisconnected(const std::string_view& identifier)
|
||||
{
|
||||
emit g_emu_thread->onInputDeviceDisconnected(
|
||||
identifier.empty() ? QString() : QString::fromUtf8(identifier.data(), identifier.size()));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Interface Stuff
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const IConsoleWriter* PatchesCon = &Console;
|
||||
|
||||
void LoadAllPatchesAndStuff(const Pcsx2Config& cfg)
|
||||
{
|
||||
// FIXME
|
||||
}
|
||||
|
||||
void PatchesVerboseReset()
|
||||
{
|
||||
// FIXME
|
||||
}
|
||||
|
||||
// Replacement for Console so we actually get output to our console window on Windows.
|
||||
#ifdef _WIN32
|
||||
#include "common/RedtapeWindows.h"
|
||||
|
||||
static bool s_debugger_attached = false;
|
||||
static bool s_console_handle_set = false;
|
||||
static HANDLE s_console_handle = nullptr;
|
||||
|
||||
static void __concall ConsoleWinQt_SetTitle(const wxString& title)
|
||||
{
|
||||
SetConsoleTitleW(title.wc_str());
|
||||
}
|
||||
|
||||
static void __concall ConsoleWinQt_DoSetColor(ConsoleColors color)
|
||||
{
|
||||
if (!s_console_handle)
|
||||
return;
|
||||
|
||||
static constexpr WORD colors[ConsoleColors_Count] = {
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE, // default
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE, // black
|
||||
FOREGROUND_GREEN, // green
|
||||
FOREGROUND_RED, // red
|
||||
FOREGROUND_BLUE, // blue
|
||||
FOREGROUND_RED | FOREGROUND_BLUE, // magenta
|
||||
FOREGROUND_RED | FOREGROUND_GREEN, // orange
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE, // gray
|
||||
FOREGROUND_BLUE | FOREGROUND_INTENSITY, // cyan
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY, // yellow
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY, // white
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE, // strong black
|
||||
FOREGROUND_RED | FOREGROUND_INTENSITY, // strong red
|
||||
FOREGROUND_GREEN | FOREGROUND_INTENSITY, // strong green
|
||||
FOREGROUND_BLUE | FOREGROUND_INTENSITY, // strong blue
|
||||
FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY, // strong magenta
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY, // strong orange
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE, // strong gray
|
||||
FOREGROUND_BLUE | FOREGROUND_INTENSITY, // strong cyan
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY, // strong yellow
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY, // strong white
|
||||
};
|
||||
|
||||
SetConsoleTextAttribute(s_console_handle, colors[static_cast<u32>(color)]);
|
||||
}
|
||||
|
||||
static void __concall ConsoleWinQt_Newline()
|
||||
{
|
||||
if (!s_console_handle)
|
||||
return;
|
||||
|
||||
if (s_debugger_attached)
|
||||
OutputDebugStringW(L"\n");
|
||||
|
||||
DWORD written;
|
||||
WriteConsoleW(s_console_handle, L"\n", 1, &written, nullptr);
|
||||
}
|
||||
|
||||
static void __concall ConsoleWinQt_DoWrite(const wxString& fmt)
|
||||
{
|
||||
if (!s_console_handle)
|
||||
return;
|
||||
|
||||
if (s_debugger_attached)
|
||||
OutputDebugStringW(fmt.wc_str());
|
||||
|
||||
DWORD written;
|
||||
WriteConsoleW(s_console_handle, fmt.wc_str(), static_cast<DWORD>(fmt.size()), &written, nullptr);
|
||||
}
|
||||
|
||||
static void __concall ConsoleWinQt_DoWriteLn(const wxString& fmt)
|
||||
{
|
||||
if (!s_console_handle)
|
||||
return;
|
||||
|
||||
if (s_debugger_attached)
|
||||
{
|
||||
OutputDebugStringW(fmt.wc_str());
|
||||
OutputDebugStringW(L"\n");
|
||||
}
|
||||
|
||||
DWORD written;
|
||||
WriteConsoleW(s_console_handle, fmt.wc_str(), static_cast<DWORD>(fmt.size()), &written, nullptr);
|
||||
WriteConsoleW(s_console_handle, L"\n", 1, &written, nullptr);
|
||||
}
|
||||
|
||||
static const IConsoleWriter ConsoleWriter_WinQt =
|
||||
{
|
||||
ConsoleWinQt_DoWrite,
|
||||
ConsoleWinQt_DoWriteLn,
|
||||
ConsoleWinQt_DoSetColor,
|
||||
|
||||
ConsoleWinQt_DoWrite,
|
||||
ConsoleWinQt_Newline,
|
||||
ConsoleWinQt_SetTitle,
|
||||
};
|
||||
#endif
|
||||
|
||||
void QtHost::UpdateLogging()
|
||||
{
|
||||
// TODO: Make this an actual option.
|
||||
bool console_logging_enabled = false;
|
||||
|
||||
#if defined(_DEBUG) || defined(PCSX2_DEVBUILD)
|
||||
console_logging_enabled = true;
|
||||
#endif
|
||||
|
||||
DevConWriterEnabled = console_logging_enabled;
|
||||
SysConsole.eeConsole.Enabled = console_logging_enabled;
|
||||
SysConsole.iopConsole.Enabled = console_logging_enabled;
|
||||
|
||||
if (console_logging_enabled)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
s_debugger_attached = IsDebuggerPresent();
|
||||
if (!s_console_handle_set)
|
||||
{
|
||||
bool handle_valid = (GetConsoleWindow() != NULL);
|
||||
if (!handle_valid)
|
||||
{
|
||||
AllocConsole();
|
||||
handle_valid = (freopen("CONIN$", "r", stdin) != nullptr);
|
||||
handle_valid = (freopen("CONOUT$", "w", stdout) != nullptr);
|
||||
handle_valid = (freopen("CONOUT$", "w", stderr) != nullptr);
|
||||
}
|
||||
|
||||
if (handle_valid)
|
||||
{
|
||||
s_console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
s_console_handle_set = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!s_console_handle && !s_debugger_attached)
|
||||
Console_SetActiveHandler(ConsoleWriter_Null);
|
||||
else
|
||||
Console_SetActiveHandler(ConsoleWriter_WinQt);
|
||||
#else
|
||||
Console_SetActiveHandler(ConsoleWriter_Stdout);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
Console_SetActiveHandler(ConsoleWriter_Null);
|
||||
}
|
||||
}
|
||||
|
||||
#include <wx/module.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
extern "C" HINSTANCE wxGetInstance();
|
||||
extern void wxSetInstance(HINSTANCE hInst);
|
||||
#endif
|
||||
|
||||
void InitializeWxRubbish()
|
||||
{
|
||||
wxLog::DoCreateOnDemand();
|
||||
wxLog::GetActiveTarget();
|
||||
|
||||
#ifdef _WIN32
|
||||
if (!wxGetInstance())
|
||||
wxSetInstance(::GetModuleHandle(NULL));
|
||||
#endif // _WIN32
|
||||
|
||||
wxModule::RegisterModules();
|
||||
wxModule::InitializeModules();
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "pcsx2/Host.h"
|
||||
#include "pcsx2/HostDisplay.h"
|
||||
#include "pcsx2/HostSettings.h"
|
||||
#include "pcsx2/Frontend/InputManager.h"
|
||||
#include "pcsx2/VMManager.h"
|
||||
#include <QtCore/QMetaType>
|
||||
|
||||
class SettingsInterface;
|
||||
|
||||
class EmuThread;
|
||||
|
||||
Q_DECLARE_METATYPE(GSRendererType);
|
||||
Q_DECLARE_METATYPE(std::shared_ptr<VMBootParameters>);
|
||||
Q_DECLARE_METATYPE(InputBindingKey);
|
||||
|
||||
namespace QtHost
|
||||
{
|
||||
bool Initialize();
|
||||
void Shutdown();
|
||||
|
||||
void UpdateFolders();
|
||||
void UpdateLogging();
|
||||
|
||||
/// Thread-safe settings access.
|
||||
std::string GetBaseStringSettingValue(const char* section, const char* key, const char* default_value = "");
|
||||
bool GetBaseBoolSettingValue(const char* section, const char* key, bool default_value = false);
|
||||
int GetBaseIntSettingValue(const char* section, const char* key, int default_value = 0);
|
||||
float GetBaseFloatSettingValue(const char* section, const char* key, float default_value = 0.0f);
|
||||
std::vector<std::string> GetBaseStringListSetting(const char* section, const char* key);
|
||||
void SetBaseBoolSettingValue(const char* section, const char* key, bool value);
|
||||
void SetBaseIntSettingValue(const char* section, const char* key, int value);
|
||||
void SetBaseFloatSettingValue(const char* section, const char* key, float value);
|
||||
void SetBaseStringSettingValue(const char* section, const char* key, const char* value);
|
||||
void SetBaseStringListSettingValue(const char* section, const char* key, const std::vector<std::string>& values);
|
||||
bool AddBaseValueToStringList(const char* section, const char* key, const char* value);
|
||||
bool RemoveBaseValueFromStringList(const char* section, const char* key, const char* value);
|
||||
void RemoveBaseSettingValue(const char* section, const char* key);
|
||||
} // namespace QtHost
|
|
@ -0,0 +1,486 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "pcsx2/Frontend/InputManager.h"
|
||||
|
||||
struct KeyCodeName
|
||||
{
|
||||
int code;
|
||||
const char* name;
|
||||
};
|
||||
|
||||
static constexpr KeyCodeName s_qt_key_names[] = {
|
||||
{Qt::Key_Escape, "Escape"},
|
||||
{Qt::Key_Tab, "Tab"},
|
||||
{Qt::Key_Backtab, "Backtab"},
|
||||
{Qt::Key_Backspace, "Backspace"},
|
||||
{Qt::Key_Return, "Return"},
|
||||
{Qt::Key_Enter, "Enter"},
|
||||
{Qt::Key_Insert, "Insert"},
|
||||
{Qt::Key_Delete, "Delete"},
|
||||
{Qt::Key_Pause, "Pause"},
|
||||
{Qt::Key_Print, "Print"},
|
||||
{Qt::Key_SysReq, "SysReq"},
|
||||
{Qt::Key_Clear, "Clear"},
|
||||
{Qt::Key_Home, "Home"},
|
||||
{Qt::Key_End, "End"},
|
||||
{Qt::Key_Left, "Left"},
|
||||
{Qt::Key_Up, "Up"},
|
||||
{Qt::Key_Right, "Right"},
|
||||
{Qt::Key_Down, "Down"},
|
||||
{Qt::Key_PageUp, "PageUp"},
|
||||
{Qt::Key_PageDown, "PageDown"},
|
||||
{Qt::Key_Shift, "Shift"},
|
||||
{Qt::Key_Control, "Control"},
|
||||
{Qt::Key_Meta, "Meta"},
|
||||
{Qt::Key_Alt, "Alt"},
|
||||
{Qt::Key_CapsLock, "CapsLock"},
|
||||
{Qt::Key_NumLock, "NumLock"},
|
||||
{Qt::Key_ScrollLock, "ScrollLock"},
|
||||
{Qt::Key_F1, "F1"},
|
||||
{Qt::Key_F2, "F2"},
|
||||
{Qt::Key_F3, "F3"},
|
||||
{Qt::Key_F4, "F4"},
|
||||
{Qt::Key_F5, "F5"},
|
||||
{Qt::Key_F6, "F6"},
|
||||
{Qt::Key_F7, "F7"},
|
||||
{Qt::Key_F8, "F8"},
|
||||
{Qt::Key_F9, "F9"},
|
||||
{Qt::Key_F10, "F10"},
|
||||
{Qt::Key_F11, "F11"},
|
||||
{Qt::Key_F12, "F12"},
|
||||
{Qt::Key_F13, "F13"},
|
||||
{Qt::Key_F14, "F14"},
|
||||
{Qt::Key_F15, "F15"},
|
||||
{Qt::Key_F16, "F16"},
|
||||
{Qt::Key_F17, "F17"},
|
||||
{Qt::Key_F18, "F18"},
|
||||
{Qt::Key_F19, "F19"},
|
||||
{Qt::Key_F20, "F20"},
|
||||
{Qt::Key_F21, "F21"},
|
||||
{Qt::Key_F22, "F22"},
|
||||
{Qt::Key_F23, "F23"},
|
||||
{Qt::Key_F24, "F24"},
|
||||
{Qt::Key_F25, "F25"},
|
||||
{Qt::Key_F26, "F26"},
|
||||
{Qt::Key_F27, "F27"},
|
||||
{Qt::Key_F28, "F28"},
|
||||
{Qt::Key_F29, "F29"},
|
||||
{Qt::Key_F30, "F30"},
|
||||
{Qt::Key_F31, "F31"},
|
||||
{Qt::Key_F32, "F32"},
|
||||
{Qt::Key_F33, "F33"},
|
||||
{Qt::Key_F34, "F34"},
|
||||
{Qt::Key_F35, "F35"},
|
||||
{Qt::Key_Super_L, "Super_L"},
|
||||
{Qt::Key_Super_R, "Super_R"},
|
||||
{Qt::Key_Menu, "Menu"},
|
||||
{Qt::Key_Hyper_L, "Hyper_L"},
|
||||
{Qt::Key_Hyper_R, "Hyper_R"},
|
||||
{Qt::Key_Help, "Help"},
|
||||
{Qt::Key_Direction_L, "Direction_L"},
|
||||
{Qt::Key_Direction_R, "Direction_R"},
|
||||
{Qt::Key_Space, "Space"},
|
||||
{Qt::Key_Any, "Any"},
|
||||
{Qt::Key_Exclam, "Exclam"},
|
||||
{Qt::Key_QuoteDbl, "QuoteDbl"},
|
||||
{Qt::Key_NumberSign, "NumberSign"},
|
||||
{Qt::Key_Dollar, "Dollar"},
|
||||
{Qt::Key_Percent, "Percent"},
|
||||
{Qt::Key_Ampersand, "Ampersand"},
|
||||
{Qt::Key_Apostrophe, "Apostrophe"},
|
||||
{Qt::Key_ParenLeft, "ParenLeft"},
|
||||
{Qt::Key_ParenRight, "ParenRight"},
|
||||
{Qt::Key_Asterisk, "Asterisk"},
|
||||
{Qt::Key_Plus, "Plus"},
|
||||
{Qt::Key_Comma, "Comma"},
|
||||
{Qt::Key_Minus, "Minus"},
|
||||
{Qt::Key_Period, "Period"},
|
||||
{Qt::Key_Slash, "Slash"},
|
||||
{Qt::Key_0, "0"},
|
||||
{Qt::Key_1, "1"},
|
||||
{Qt::Key_2, "2"},
|
||||
{Qt::Key_3, "3"},
|
||||
{Qt::Key_4, "4"},
|
||||
{Qt::Key_5, "5"},
|
||||
{Qt::Key_6, "6"},
|
||||
{Qt::Key_7, "7"},
|
||||
{Qt::Key_8, "8"},
|
||||
{Qt::Key_9, "9"},
|
||||
{Qt::Key_Colon, "Colon"},
|
||||
{Qt::Key_Semicolon, "Semicolon"},
|
||||
{Qt::Key_Less, "Less"},
|
||||
{Qt::Key_Equal, "Equal"},
|
||||
{Qt::Key_Greater, "Greater"},
|
||||
{Qt::Key_Question, "Question"},
|
||||
{Qt::Key_At, "At"},
|
||||
{Qt::Key_A, "A"},
|
||||
{Qt::Key_B, "B"},
|
||||
{Qt::Key_C, "C"},
|
||||
{Qt::Key_D, "D"},
|
||||
{Qt::Key_E, "E"},
|
||||
{Qt::Key_F, "F"},
|
||||
{Qt::Key_G, "G"},
|
||||
{Qt::Key_H, "H"},
|
||||
{Qt::Key_I, "I"},
|
||||
{Qt::Key_J, "J"},
|
||||
{Qt::Key_K, "K"},
|
||||
{Qt::Key_L, "L"},
|
||||
{Qt::Key_M, "M"},
|
||||
{Qt::Key_N, "N"},
|
||||
{Qt::Key_O, "O"},
|
||||
{Qt::Key_P, "P"},
|
||||
{Qt::Key_Q, "Q"},
|
||||
{Qt::Key_R, "R"},
|
||||
{Qt::Key_S, "S"},
|
||||
{Qt::Key_T, "T"},
|
||||
{Qt::Key_U, "U"},
|
||||
{Qt::Key_V, "V"},
|
||||
{Qt::Key_W, "W"},
|
||||
{Qt::Key_X, "X"},
|
||||
{Qt::Key_Y, "Y"},
|
||||
{Qt::Key_Z, "Z"},
|
||||
{Qt::Key_BracketLeft, "BracketLeft"},
|
||||
{Qt::Key_Backslash, "Backslash"},
|
||||
{Qt::Key_BracketRight, "BracketRight"},
|
||||
{Qt::Key_AsciiCircum, "AsciiCircum"},
|
||||
{Qt::Key_Underscore, "Underscore"},
|
||||
{Qt::Key_QuoteLeft, "QuoteLeft"},
|
||||
{Qt::Key_BraceLeft, "BraceLeft"},
|
||||
{Qt::Key_Bar, "Bar"},
|
||||
{Qt::Key_BraceRight, "BraceRight"},
|
||||
{Qt::Key_AsciiTilde, "AsciiTilde"},
|
||||
{Qt::Key_nobreakspace, "nobreakspace"},
|
||||
{Qt::Key_exclamdown, "exclamdown"},
|
||||
{Qt::Key_cent, "cent"},
|
||||
{Qt::Key_sterling, "sterling"},
|
||||
{Qt::Key_currency, "currency"},
|
||||
{Qt::Key_yen, "yen"},
|
||||
{Qt::Key_brokenbar, "brokenbar"},
|
||||
{Qt::Key_section, "section"},
|
||||
{Qt::Key_diaeresis, "diaeresis"},
|
||||
{Qt::Key_copyright, "copyright"},
|
||||
{Qt::Key_ordfeminine, "ordfeminine"},
|
||||
{Qt::Key_guillemotleft, "guillemotleft"},
|
||||
{Qt::Key_notsign, "notsign"},
|
||||
{Qt::Key_hyphen, "hyphen"},
|
||||
{Qt::Key_registered, "registered"},
|
||||
{Qt::Key_macron, "macron"},
|
||||
{Qt::Key_degree, "degree"},
|
||||
{Qt::Key_plusminus, "plusminus"},
|
||||
{Qt::Key_twosuperior, "twosuperior"},
|
||||
{Qt::Key_threesuperior, "threesuperior"},
|
||||
{Qt::Key_acute, "acute"},
|
||||
{Qt::Key_mu, "mu"},
|
||||
{Qt::Key_paragraph, "paragraph"},
|
||||
{Qt::Key_periodcentered, "periodcentered"},
|
||||
{Qt::Key_cedilla, "cedilla"},
|
||||
{Qt::Key_onesuperior, "onesuperior"},
|
||||
{Qt::Key_masculine, "masculine"},
|
||||
{Qt::Key_guillemotright, "guillemotright"},
|
||||
{Qt::Key_onequarter, "onequarter"},
|
||||
{Qt::Key_onehalf, "onehalf"},
|
||||
{Qt::Key_threequarters, "threequarters"},
|
||||
{Qt::Key_questiondown, "questiondown"},
|
||||
{Qt::Key_Agrave, "Agrave"},
|
||||
{Qt::Key_Aacute, "Aacute"},
|
||||
{Qt::Key_Acircumflex, "Acircumflex"},
|
||||
{Qt::Key_Atilde, "Atilde"},
|
||||
{Qt::Key_Adiaeresis, "Adiaeresis"},
|
||||
{Qt::Key_Aring, "Aring"},
|
||||
{Qt::Key_AE, "AE"},
|
||||
{Qt::Key_Ccedilla, "Ccedilla"},
|
||||
{Qt::Key_Egrave, "Egrave"},
|
||||
{Qt::Key_Eacute, "Eacute"},
|
||||
{Qt::Key_Ecircumflex, "Ecircumflex"},
|
||||
{Qt::Key_Ediaeresis, "Ediaeresis"},
|
||||
{Qt::Key_Igrave, "Igrave"},
|
||||
{Qt::Key_Iacute, "Iacute"},
|
||||
{Qt::Key_Icircumflex, "Icircumflex"},
|
||||
{Qt::Key_Idiaeresis, "Idiaeresis"},
|
||||
{Qt::Key_ETH, "ETH"},
|
||||
{Qt::Key_Ntilde, "Ntilde"},
|
||||
{Qt::Key_Ograve, "Ograve"},
|
||||
{Qt::Key_Oacute, "Oacute"},
|
||||
{Qt::Key_Ocircumflex, "Ocircumflex"},
|
||||
{Qt::Key_Otilde, "Otilde"},
|
||||
{Qt::Key_Odiaeresis, "Odiaeresis"},
|
||||
{Qt::Key_multiply, "multiply"},
|
||||
{Qt::Key_Ooblique, "Ooblique"},
|
||||
{Qt::Key_Ugrave, "Ugrave"},
|
||||
{Qt::Key_Uacute, "Uacute"},
|
||||
{Qt::Key_Ucircumflex, "Ucircumflex"},
|
||||
{Qt::Key_Udiaeresis, "Udiaeresis"},
|
||||
{Qt::Key_Yacute, "Yacute"},
|
||||
{Qt::Key_THORN, "THORN"},
|
||||
{Qt::Key_ssharp, "ssharp"},
|
||||
{Qt::Key_division, "division"},
|
||||
{Qt::Key_ydiaeresis, "ydiaeresis"},
|
||||
{Qt::Key_AltGr, "AltGr"},
|
||||
{Qt::Key_Multi_key, "Multi_key"},
|
||||
{Qt::Key_Codeinput, "Codeinput"},
|
||||
{Qt::Key_SingleCandidate, "SingleCandidate"},
|
||||
{Qt::Key_MultipleCandidate, "MultipleCandidate"},
|
||||
{Qt::Key_PreviousCandidate, "PreviousCandidate"},
|
||||
{Qt::Key_Mode_switch, "Mode_switch"},
|
||||
{Qt::Key_Kanji, "Kanji"},
|
||||
{Qt::Key_Muhenkan, "Muhenkan"},
|
||||
{Qt::Key_Henkan, "Henkan"},
|
||||
{Qt::Key_Romaji, "Romaji"},
|
||||
{Qt::Key_Hiragana, "Hiragana"},
|
||||
{Qt::Key_Katakana, "Katakana"},
|
||||
{Qt::Key_Hiragana_Katakana, "Hiragana_Katakana"},
|
||||
{Qt::Key_Zenkaku, "Zenkaku"},
|
||||
{Qt::Key_Hankaku, "Hankaku"},
|
||||
{Qt::Key_Zenkaku_Hankaku, "Zenkaku_Hankaku"},
|
||||
{Qt::Key_Touroku, "Touroku"},
|
||||
{Qt::Key_Massyo, "Massyo"},
|
||||
{Qt::Key_Kana_Lock, "Kana_Lock"},
|
||||
{Qt::Key_Kana_Shift, "Kana_Shift"},
|
||||
{Qt::Key_Eisu_Shift, "Eisu_Shift"},
|
||||
{Qt::Key_Eisu_toggle, "Eisu_toggle"},
|
||||
{Qt::Key_Hangul, "Hangul"},
|
||||
{Qt::Key_Hangul_Start, "Hangul_Start"},
|
||||
{Qt::Key_Hangul_End, "Hangul_End"},
|
||||
{Qt::Key_Hangul_Hanja, "Hangul_Hanja"},
|
||||
{Qt::Key_Hangul_Jamo, "Hangul_Jamo"},
|
||||
{Qt::Key_Hangul_Romaja, "Hangul_Romaja"},
|
||||
{Qt::Key_Hangul_Jeonja, "Hangul_Jeonja"},
|
||||
{Qt::Key_Hangul_Banja, "Hangul_Banja"},
|
||||
{Qt::Key_Hangul_PreHanja, "Hangul_PreHanja"},
|
||||
{Qt::Key_Hangul_PostHanja, "Hangul_PostHanja"},
|
||||
{Qt::Key_Hangul_Special, "Hangul_Special"},
|
||||
{Qt::Key_Dead_Grave, "Dead_Grave"},
|
||||
{Qt::Key_Dead_Acute, "Dead_Acute"},
|
||||
{Qt::Key_Dead_Circumflex, "Dead_Circumflex"},
|
||||
{Qt::Key_Dead_Tilde, "Dead_Tilde"},
|
||||
{Qt::Key_Dead_Macron, "Dead_Macron"},
|
||||
{Qt::Key_Dead_Breve, "Dead_Breve"},
|
||||
{Qt::Key_Dead_Abovedot, "Dead_Abovedot"},
|
||||
{Qt::Key_Dead_Diaeresis, "Dead_Diaeresis"},
|
||||
{Qt::Key_Dead_Abovering, "Dead_Abovering"},
|
||||
{Qt::Key_Dead_Doubleacute, "Dead_Doubleacute"},
|
||||
{Qt::Key_Dead_Caron, "Dead_Caron"},
|
||||
{Qt::Key_Dead_Cedilla, "Dead_Cedilla"},
|
||||
{Qt::Key_Dead_Ogonek, "Dead_Ogonek"},
|
||||
{Qt::Key_Dead_Iota, "Dead_Iota"},
|
||||
{Qt::Key_Dead_Voiced_Sound, "Dead_Voiced_Sound"},
|
||||
{Qt::Key_Dead_Semivoiced_Sound, "Dead_Semivoiced_Sound"},
|
||||
{Qt::Key_Dead_Belowdot, "Dead_Belowdot"},
|
||||
{Qt::Key_Dead_Hook, "Dead_Hook"},
|
||||
{Qt::Key_Dead_Horn, "Dead_Horn"},
|
||||
{Qt::Key_Back, "Back"},
|
||||
{Qt::Key_Forward, "Forward"},
|
||||
{Qt::Key_Stop, "Stop"},
|
||||
{Qt::Key_Refresh, "Refresh"},
|
||||
{Qt::Key_VolumeDown, "VolumeDown"},
|
||||
{Qt::Key_VolumeMute, "VolumeMute"},
|
||||
{Qt::Key_VolumeUp, "VolumeUp"},
|
||||
{Qt::Key_BassBoost, "BassBoost"},
|
||||
{Qt::Key_BassUp, "BassUp"},
|
||||
{Qt::Key_BassDown, "BassDown"},
|
||||
{Qt::Key_TrebleUp, "TrebleUp"},
|
||||
{Qt::Key_TrebleDown, "TrebleDown"},
|
||||
{Qt::Key_MediaPlay, "MediaPlay"},
|
||||
{Qt::Key_MediaStop, "MediaStop"},
|
||||
{Qt::Key_MediaPrevious, "MediaPrevious"},
|
||||
{Qt::Key_MediaNext, "MediaNext"},
|
||||
{Qt::Key_MediaRecord, "MediaRecord"},
|
||||
{Qt::Key_MediaPause, "MediaPause"},
|
||||
{Qt::Key_MediaTogglePlayPause, "MediaTogglePlayPause"},
|
||||
{Qt::Key_HomePage, "HomePage"},
|
||||
{Qt::Key_Favorites, "Favorites"},
|
||||
{Qt::Key_Search, "Search"},
|
||||
{Qt::Key_Standby, "Standby"},
|
||||
{Qt::Key_OpenUrl, "OpenUrl"},
|
||||
{Qt::Key_LaunchMail, "LaunchMail"},
|
||||
{Qt::Key_LaunchMedia, "LaunchMedia"},
|
||||
{Qt::Key_Launch0, "Launch0"},
|
||||
{Qt::Key_Launch1, "Launch1"},
|
||||
{Qt::Key_Launch2, "Launch2"},
|
||||
{Qt::Key_Launch3, "Launch3"},
|
||||
{Qt::Key_Launch4, "Launch4"},
|
||||
{Qt::Key_Launch5, "Launch5"},
|
||||
{Qt::Key_Launch6, "Launch6"},
|
||||
{Qt::Key_Launch7, "Launch7"},
|
||||
{Qt::Key_Launch8, "Launch8"},
|
||||
{Qt::Key_Launch9, "Launch9"},
|
||||
{Qt::Key_LaunchA, "LaunchA"},
|
||||
{Qt::Key_LaunchB, "LaunchB"},
|
||||
{Qt::Key_LaunchC, "LaunchC"},
|
||||
{Qt::Key_LaunchD, "LaunchD"},
|
||||
{Qt::Key_LaunchE, "LaunchE"},
|
||||
{Qt::Key_LaunchF, "LaunchF"},
|
||||
{Qt::Key_MonBrightnessUp, "MonBrightnessUp"},
|
||||
{Qt::Key_MonBrightnessDown, "MonBrightnessDown"},
|
||||
{Qt::Key_KeyboardLightOnOff, "KeyboardLightOnOff"},
|
||||
{Qt::Key_KeyboardBrightnessUp, "KeyboardBrightnessUp"},
|
||||
{Qt::Key_KeyboardBrightnessDown, "KeyboardBrightnessDown"},
|
||||
{Qt::Key_PowerOff, "PowerOff"},
|
||||
{Qt::Key_WakeUp, "WakeUp"},
|
||||
{Qt::Key_Eject, "Eject"},
|
||||
{Qt::Key_ScreenSaver, "ScreenSaver"},
|
||||
{Qt::Key_WWW, "WWW"},
|
||||
{Qt::Key_Memo, "Memo"},
|
||||
{Qt::Key_LightBulb, "LightBulb"},
|
||||
{Qt::Key_Shop, "Shop"},
|
||||
{Qt::Key_History, "History"},
|
||||
{Qt::Key_AddFavorite, "AddFavorite"},
|
||||
{Qt::Key_HotLinks, "HotLinks"},
|
||||
{Qt::Key_BrightnessAdjust, "BrightnessAdjust"},
|
||||
{Qt::Key_Finance, "Finance"},
|
||||
{Qt::Key_Community, "Community"},
|
||||
{Qt::Key_AudioRewind, "AudioRewind"},
|
||||
{Qt::Key_BackForward, "BackForward"},
|
||||
{Qt::Key_ApplicationLeft, "ApplicationLeft"},
|
||||
{Qt::Key_ApplicationRight, "ApplicationRight"},
|
||||
{Qt::Key_Book, "Book"},
|
||||
{Qt::Key_CD, "CD"},
|
||||
{Qt::Key_Calculator, "Calculator"},
|
||||
{Qt::Key_ToDoList, "ToDoList"},
|
||||
{Qt::Key_ClearGrab, "ClearGrab"},
|
||||
{Qt::Key_Close, "Close"},
|
||||
{Qt::Key_Copy, "Copy"},
|
||||
{Qt::Key_Cut, "Cut"},
|
||||
{Qt::Key_Display, "Display"},
|
||||
{Qt::Key_DOS, "DOS"},
|
||||
{Qt::Key_Documents, "Documents"},
|
||||
{Qt::Key_Excel, "Excel"},
|
||||
{Qt::Key_Explorer, "Explorer"},
|
||||
{Qt::Key_Game, "Game"},
|
||||
{Qt::Key_Go, "Go"},
|
||||
{Qt::Key_iTouch, "iTouch"},
|
||||
{Qt::Key_LogOff, "LogOff"},
|
||||
{Qt::Key_Market, "Market"},
|
||||
{Qt::Key_Meeting, "Meeting"},
|
||||
{Qt::Key_MenuKB, "MenuKB"},
|
||||
{Qt::Key_MenuPB, "MenuPB"},
|
||||
{Qt::Key_MySites, "MySites"},
|
||||
{Qt::Key_News, "News"},
|
||||
{Qt::Key_OfficeHome, "OfficeHome"},
|
||||
{Qt::Key_Option, "Option"},
|
||||
{Qt::Key_Paste, "Paste"},
|
||||
{Qt::Key_Phone, "Phone"},
|
||||
{Qt::Key_Calendar, "Calendar"},
|
||||
{Qt::Key_Reply, "Reply"},
|
||||
{Qt::Key_Reload, "Reload"},
|
||||
{Qt::Key_RotateWindows, "RotateWindows"},
|
||||
{Qt::Key_RotationPB, "RotationPB"},
|
||||
{Qt::Key_RotationKB, "RotationKB"},
|
||||
{Qt::Key_Save, "Save"},
|
||||
{Qt::Key_Send, "Send"},
|
||||
{Qt::Key_Spell, "Spell"},
|
||||
{Qt::Key_SplitScreen, "SplitScreen"},
|
||||
{Qt::Key_Support, "Support"},
|
||||
{Qt::Key_TaskPane, "TaskPane"},
|
||||
{Qt::Key_Terminal, "Terminal"},
|
||||
{Qt::Key_Tools, "Tools"},
|
||||
{Qt::Key_Travel, "Travel"},
|
||||
{Qt::Key_Video, "Video"},
|
||||
{Qt::Key_Word, "Word"},
|
||||
{Qt::Key_Xfer, "Xfer"},
|
||||
{Qt::Key_ZoomIn, "ZoomIn"},
|
||||
{Qt::Key_ZoomOut, "ZoomOut"},
|
||||
{Qt::Key_Away, "Away"},
|
||||
{Qt::Key_Messenger, "Messenger"},
|
||||
{Qt::Key_WebCam, "WebCam"},
|
||||
{Qt::Key_MailForward, "MailForward"},
|
||||
{Qt::Key_Pictures, "Pictures"},
|
||||
{Qt::Key_Music, "Music"},
|
||||
{Qt::Key_Battery, "Battery"},
|
||||
{Qt::Key_Bluetooth, "Bluetooth"},
|
||||
{Qt::Key_WLAN, "WLAN"},
|
||||
{Qt::Key_UWB, "UWB"},
|
||||
{Qt::Key_AudioForward, "AudioForward"},
|
||||
{Qt::Key_AudioRepeat, "AudioRepeat"},
|
||||
{Qt::Key_AudioRandomPlay, "AudioRandomPlay"},
|
||||
{Qt::Key_Subtitle, "Subtitle"},
|
||||
{Qt::Key_AudioCycleTrack, "AudioCycleTrack"},
|
||||
{Qt::Key_Time, "Time"},
|
||||
{Qt::Key_Hibernate, "Hibernate"},
|
||||
{Qt::Key_View, "View"},
|
||||
{Qt::Key_TopMenu, "TopMenu"},
|
||||
{Qt::Key_PowerDown, "PowerDown"},
|
||||
{Qt::Key_Suspend, "Suspend"},
|
||||
{Qt::Key_ContrastAdjust, "ContrastAdjust"},
|
||||
{Qt::Key_LaunchG, "LaunchG"},
|
||||
{Qt::Key_LaunchH, "LaunchH"},
|
||||
{Qt::Key_TouchpadToggle, "TouchpadToggle"},
|
||||
{Qt::Key_TouchpadOn, "TouchpadOn"},
|
||||
{Qt::Key_TouchpadOff, "TouchpadOff"},
|
||||
{Qt::Key_MicMute, "MicMute"},
|
||||
{Qt::Key_Red, "Red"},
|
||||
{Qt::Key_Green, "Green"},
|
||||
{Qt::Key_Yellow, "Yellow"},
|
||||
{Qt::Key_Blue, "Blue"},
|
||||
{Qt::Key_ChannelUp, "ChannelUp"},
|
||||
{Qt::Key_ChannelDown, "ChannelDown"},
|
||||
{Qt::Key_Guide, "Guide"},
|
||||
{Qt::Key_Info, "Info"},
|
||||
{Qt::Key_Settings, "Settings"},
|
||||
{Qt::Key_MicVolumeUp, "MicVolumeUp"},
|
||||
{Qt::Key_MicVolumeDown, "MicVolumeDown"},
|
||||
{Qt::Key_New, "New"},
|
||||
{Qt::Key_Open, "Open"},
|
||||
{Qt::Key_Find, "Find"},
|
||||
{Qt::Key_Undo, "Undo"},
|
||||
{Qt::Key_Redo, "Redo"},
|
||||
{Qt::Key_MediaLast, "MediaLast"},
|
||||
{Qt::Key_Select, "Select"},
|
||||
{Qt::Key_Yes, "Yes"},
|
||||
{Qt::Key_No, "No"},
|
||||
{Qt::Key_Cancel, "Cancel"},
|
||||
{Qt::Key_Printer, "Printer"},
|
||||
{Qt::Key_Execute, "Execute"},
|
||||
{Qt::Key_Sleep, "Sleep"},
|
||||
{Qt::Key_Play, "Play"},
|
||||
{Qt::Key_Zoom, "Zoom"},
|
||||
{Qt::Key_Exit, "Exit"},
|
||||
{Qt::Key_Context1, "Context1"},
|
||||
{Qt::Key_Context2, "Context2"},
|
||||
{Qt::Key_Context3, "Context3"},
|
||||
{Qt::Key_Context4, "Context4"},
|
||||
{Qt::Key_Call, "Call"},
|
||||
{Qt::Key_Hangup, "Hangup"},
|
||||
{Qt::Key_Flip, "Flip"},
|
||||
{Qt::Key_ToggleCallHangup, "ToggleCallHangup"},
|
||||
{Qt::Key_VoiceDial, "VoiceDial"},
|
||||
{Qt::Key_LastNumberRedial, "LastNumberRedial"},
|
||||
{Qt::Key_Camera, "Camera"},
|
||||
{Qt::Key_CameraFocus, "CameraFocus"}};
|
||||
|
||||
std::optional<u32> InputManager::ConvertHostKeyboardStringToCode(const std::string_view& str)
|
||||
{
|
||||
for (const KeyCodeName& name : s_qt_key_names)
|
||||
{
|
||||
if (str == name.name)
|
||||
return static_cast<u32>(name.code);
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> InputManager::ConvertHostKeyboardCodeToString(u32 code)
|
||||
{
|
||||
for (const KeyCodeName& name : s_qt_key_names)
|
||||
{
|
||||
if (static_cast<int>(code) == name.code)
|
||||
return std::string(name.name);
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
|
@ -0,0 +1,703 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QMetaObject>
|
||||
#include <QtGui/QDesktopServices>
|
||||
#include <QtGui/QKeyEvent>
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
#include <QtGui/QAction>
|
||||
#else
|
||||
#include <QtWidgets/QAction>
|
||||
#endif
|
||||
|
||||
#include <QtWidgets/QComboBox>
|
||||
#include <QtWidgets/QDialog>
|
||||
#include <QtWidgets/QHeaderView>
|
||||
#include <QtWidgets/QInputDialog>
|
||||
#include <QtWidgets/QMainWindow>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <QtWidgets/QScrollBar>
|
||||
#include <QtWidgets/QStyle>
|
||||
#include <QtWidgets/QTableView>
|
||||
#include <QtWidgets/QTreeView>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <map>
|
||||
|
||||
#include "QtUtils.h"
|
||||
|
||||
namespace QtUtils
|
||||
{
|
||||
void MarkActionAsDefault(QAction* action)
|
||||
{
|
||||
QFont new_font(action->font());
|
||||
new_font.setBold(true);
|
||||
action->setFont(new_font);
|
||||
}
|
||||
|
||||
QFrame* CreateHorizontalLine(QWidget* parent)
|
||||
{
|
||||
QFrame* line = new QFrame(parent);
|
||||
line->setFrameShape(QFrame::HLine);
|
||||
line->setFrameShadow(QFrame::Sunken);
|
||||
return line;
|
||||
}
|
||||
|
||||
QWidget* GetRootWidget(QWidget* widget, bool stop_at_window_or_dialog)
|
||||
{
|
||||
QWidget* next_parent = widget->parentWidget();
|
||||
while (next_parent)
|
||||
{
|
||||
if (stop_at_window_or_dialog && (widget->metaObject()->inherits(&QMainWindow::staticMetaObject) ||
|
||||
widget->metaObject()->inherits(&QDialog::staticMetaObject)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
widget = next_parent;
|
||||
next_parent = widget->parentWidget();
|
||||
}
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void ResizeColumnsForView(T* view, const std::initializer_list<int>& widths)
|
||||
{
|
||||
QHeaderView* header;
|
||||
if constexpr (std::is_same_v<T, QTableView>)
|
||||
header = view->horizontalHeader();
|
||||
else
|
||||
header = view->header();
|
||||
|
||||
const int min_column_width = header->minimumSectionSize();
|
||||
const int scrollbar_width = ((view->verticalScrollBar() && view->verticalScrollBar()->isVisible()) ||
|
||||
view->verticalScrollBarPolicy() == Qt::ScrollBarAlwaysOn) ?
|
||||
view->verticalScrollBar()->width() :
|
||||
0;
|
||||
int num_flex_items = 0;
|
||||
int total_width = 0;
|
||||
int column_index = 0;
|
||||
for (const int spec_width : widths)
|
||||
{
|
||||
if (!view->isColumnHidden(column_index))
|
||||
{
|
||||
if (spec_width < 0)
|
||||
num_flex_items++;
|
||||
else
|
||||
total_width += std::max(spec_width, min_column_width);
|
||||
}
|
||||
|
||||
column_index++;
|
||||
}
|
||||
|
||||
const int flex_width =
|
||||
(num_flex_items > 0) ?
|
||||
std::max((view->contentsRect().width() - total_width - scrollbar_width) / num_flex_items, 1) :
|
||||
0;
|
||||
|
||||
column_index = 0;
|
||||
for (const int spec_width : widths)
|
||||
{
|
||||
if (view->isColumnHidden(column_index))
|
||||
{
|
||||
column_index++;
|
||||
continue;
|
||||
}
|
||||
|
||||
const int width = spec_width < 0 ? flex_width : (std::max(spec_width, min_column_width));
|
||||
view->setColumnWidth(column_index, width);
|
||||
column_index++;
|
||||
}
|
||||
}
|
||||
|
||||
void ResizeColumnsForTableView(QTableView* view, const std::initializer_list<int>& widths)
|
||||
{
|
||||
ResizeColumnsForView(view, widths);
|
||||
}
|
||||
|
||||
void ResizeColumnsForTreeView(QTreeView* view, const std::initializer_list<int>& widths)
|
||||
{
|
||||
ResizeColumnsForView(view, widths);
|
||||
}
|
||||
|
||||
static const std::map<int, QString> s_qt_key_names = {
|
||||
{Qt::Key_Escape, QStringLiteral("Escape")},
|
||||
{Qt::Key_Tab, QStringLiteral("Tab")},
|
||||
{Qt::Key_Backtab, QStringLiteral("Backtab")},
|
||||
{Qt::Key_Backspace, QStringLiteral("Backspace")},
|
||||
{Qt::Key_Return, QStringLiteral("Return")},
|
||||
{Qt::Key_Enter, QStringLiteral("Enter")},
|
||||
{Qt::Key_Insert, QStringLiteral("Insert")},
|
||||
{Qt::Key_Delete, QStringLiteral("Delete")},
|
||||
{Qt::Key_Pause, QStringLiteral("Pause")},
|
||||
{Qt::Key_Print, QStringLiteral("Print")},
|
||||
{Qt::Key_SysReq, QStringLiteral("SysReq")},
|
||||
{Qt::Key_Clear, QStringLiteral("Clear")},
|
||||
{Qt::Key_Home, QStringLiteral("Home")},
|
||||
{Qt::Key_End, QStringLiteral("End")},
|
||||
{Qt::Key_Left, QStringLiteral("Left")},
|
||||
{Qt::Key_Up, QStringLiteral("Up")},
|
||||
{Qt::Key_Right, QStringLiteral("Right")},
|
||||
{Qt::Key_Down, QStringLiteral("Down")},
|
||||
{Qt::Key_PageUp, QStringLiteral("PageUp")},
|
||||
{Qt::Key_PageDown, QStringLiteral("PageDown")},
|
||||
{Qt::Key_Shift, QStringLiteral("Shift")},
|
||||
{Qt::Key_Control, QStringLiteral("Control")},
|
||||
{Qt::Key_Meta, QStringLiteral("Meta")},
|
||||
{Qt::Key_Alt, QStringLiteral("Alt")},
|
||||
{Qt::Key_CapsLock, QStringLiteral("CapsLock")},
|
||||
{Qt::Key_NumLock, QStringLiteral("NumLock")},
|
||||
{Qt::Key_ScrollLock, QStringLiteral("ScrollLock")},
|
||||
{Qt::Key_F1, QStringLiteral("F1")},
|
||||
{Qt::Key_F2, QStringLiteral("F2")},
|
||||
{Qt::Key_F3, QStringLiteral("F3")},
|
||||
{Qt::Key_F4, QStringLiteral("F4")},
|
||||
{Qt::Key_F5, QStringLiteral("F5")},
|
||||
{Qt::Key_F6, QStringLiteral("F6")},
|
||||
{Qt::Key_F7, QStringLiteral("F7")},
|
||||
{Qt::Key_F8, QStringLiteral("F8")},
|
||||
{Qt::Key_F9, QStringLiteral("F9")},
|
||||
{Qt::Key_F10, QStringLiteral("F10")},
|
||||
{Qt::Key_F11, QStringLiteral("F11")},
|
||||
{Qt::Key_F12, QStringLiteral("F12")},
|
||||
{Qt::Key_F13, QStringLiteral("F13")},
|
||||
{Qt::Key_F14, QStringLiteral("F14")},
|
||||
{Qt::Key_F15, QStringLiteral("F15")},
|
||||
{Qt::Key_F16, QStringLiteral("F16")},
|
||||
{Qt::Key_F17, QStringLiteral("F17")},
|
||||
{Qt::Key_F18, QStringLiteral("F18")},
|
||||
{Qt::Key_F19, QStringLiteral("F19")},
|
||||
{Qt::Key_F20, QStringLiteral("F20")},
|
||||
{Qt::Key_F21, QStringLiteral("F21")},
|
||||
{Qt::Key_F22, QStringLiteral("F22")},
|
||||
{Qt::Key_F23, QStringLiteral("F23")},
|
||||
{Qt::Key_F24, QStringLiteral("F24")},
|
||||
{Qt::Key_F25, QStringLiteral("F25")},
|
||||
{Qt::Key_F26, QStringLiteral("F26")},
|
||||
{Qt::Key_F27, QStringLiteral("F27")},
|
||||
{Qt::Key_F28, QStringLiteral("F28")},
|
||||
{Qt::Key_F29, QStringLiteral("F29")},
|
||||
{Qt::Key_F30, QStringLiteral("F30")},
|
||||
{Qt::Key_F31, QStringLiteral("F31")},
|
||||
{Qt::Key_F32, QStringLiteral("F32")},
|
||||
{Qt::Key_F33, QStringLiteral("F33")},
|
||||
{Qt::Key_F34, QStringLiteral("F34")},
|
||||
{Qt::Key_F35, QStringLiteral("F35")},
|
||||
{Qt::Key_Super_L, QStringLiteral("Super_L")},
|
||||
{Qt::Key_Super_R, QStringLiteral("Super_R")},
|
||||
{Qt::Key_Menu, QStringLiteral("Menu")},
|
||||
{Qt::Key_Hyper_L, QStringLiteral("Hyper_L")},
|
||||
{Qt::Key_Hyper_R, QStringLiteral("Hyper_R")},
|
||||
{Qt::Key_Help, QStringLiteral("Help")},
|
||||
{Qt::Key_Direction_L, QStringLiteral("Direction_L")},
|
||||
{Qt::Key_Direction_R, QStringLiteral("Direction_R")},
|
||||
{Qt::Key_Space, QStringLiteral("Space")},
|
||||
{Qt::Key_Any, QStringLiteral("Any")},
|
||||
{Qt::Key_Exclam, QStringLiteral("Exclam")},
|
||||
{Qt::Key_QuoteDbl, QStringLiteral("QuoteDbl")},
|
||||
{Qt::Key_NumberSign, QStringLiteral("NumberSign")},
|
||||
{Qt::Key_Dollar, QStringLiteral("Dollar")},
|
||||
{Qt::Key_Percent, QStringLiteral("Percent")},
|
||||
{Qt::Key_Ampersand, QStringLiteral("Ampersand")},
|
||||
{Qt::Key_Apostrophe, QStringLiteral("Apostrophe")},
|
||||
{Qt::Key_ParenLeft, QStringLiteral("ParenLeft")},
|
||||
{Qt::Key_ParenRight, QStringLiteral("ParenRight")},
|
||||
{Qt::Key_Asterisk, QStringLiteral("Asterisk")},
|
||||
{Qt::Key_Plus, QStringLiteral("Plus")},
|
||||
{Qt::Key_Comma, QStringLiteral("Comma")},
|
||||
{Qt::Key_Minus, QStringLiteral("Minus")},
|
||||
{Qt::Key_Period, QStringLiteral("Period")},
|
||||
{Qt::Key_Slash, QStringLiteral("Slash")},
|
||||
{Qt::Key_0, QStringLiteral("0")},
|
||||
{Qt::Key_1, QStringLiteral("1")},
|
||||
{Qt::Key_2, QStringLiteral("2")},
|
||||
{Qt::Key_3, QStringLiteral("3")},
|
||||
{Qt::Key_4, QStringLiteral("4")},
|
||||
{Qt::Key_5, QStringLiteral("5")},
|
||||
{Qt::Key_6, QStringLiteral("6")},
|
||||
{Qt::Key_7, QStringLiteral("7")},
|
||||
{Qt::Key_8, QStringLiteral("8")},
|
||||
{Qt::Key_9, QStringLiteral("9")},
|
||||
{Qt::Key_Colon, QStringLiteral("Colon")},
|
||||
{Qt::Key_Semicolon, QStringLiteral("Semicolon")},
|
||||
{Qt::Key_Less, QStringLiteral("Less")},
|
||||
{Qt::Key_Equal, QStringLiteral("Equal")},
|
||||
{Qt::Key_Greater, QStringLiteral("Greater")},
|
||||
{Qt::Key_Question, QStringLiteral("Question")},
|
||||
{Qt::Key_At, QStringLiteral("At")},
|
||||
{Qt::Key_A, QStringLiteral("A")},
|
||||
{Qt::Key_B, QStringLiteral("B")},
|
||||
{Qt::Key_C, QStringLiteral("C")},
|
||||
{Qt::Key_D, QStringLiteral("D")},
|
||||
{Qt::Key_E, QStringLiteral("E")},
|
||||
{Qt::Key_F, QStringLiteral("F")},
|
||||
{Qt::Key_G, QStringLiteral("G")},
|
||||
{Qt::Key_H, QStringLiteral("H")},
|
||||
{Qt::Key_I, QStringLiteral("I")},
|
||||
{Qt::Key_J, QStringLiteral("J")},
|
||||
{Qt::Key_K, QStringLiteral("K")},
|
||||
{Qt::Key_L, QStringLiteral("L")},
|
||||
{Qt::Key_M, QStringLiteral("M")},
|
||||
{Qt::Key_N, QStringLiteral("N")},
|
||||
{Qt::Key_O, QStringLiteral("O")},
|
||||
{Qt::Key_P, QStringLiteral("P")},
|
||||
{Qt::Key_Q, QStringLiteral("Q")},
|
||||
{Qt::Key_R, QStringLiteral("R")},
|
||||
{Qt::Key_S, QStringLiteral("S")},
|
||||
{Qt::Key_T, QStringLiteral("T")},
|
||||
{Qt::Key_U, QStringLiteral("U")},
|
||||
{Qt::Key_V, QStringLiteral("V")},
|
||||
{Qt::Key_W, QStringLiteral("W")},
|
||||
{Qt::Key_X, QStringLiteral("X")},
|
||||
{Qt::Key_Y, QStringLiteral("Y")},
|
||||
{Qt::Key_Z, QStringLiteral("Z")},
|
||||
{Qt::Key_BracketLeft, QStringLiteral("BracketLeft")},
|
||||
{Qt::Key_Backslash, QStringLiteral("Backslash")},
|
||||
{Qt::Key_BracketRight, QStringLiteral("BracketRight")},
|
||||
{Qt::Key_AsciiCircum, QStringLiteral("AsciiCircum")},
|
||||
{Qt::Key_Underscore, QStringLiteral("Underscore")},
|
||||
{Qt::Key_QuoteLeft, QStringLiteral("QuoteLeft")},
|
||||
{Qt::Key_BraceLeft, QStringLiteral("BraceLeft")},
|
||||
{Qt::Key_Bar, QStringLiteral("Bar")},
|
||||
{Qt::Key_BraceRight, QStringLiteral("BraceRight")},
|
||||
{Qt::Key_AsciiTilde, QStringLiteral("AsciiTilde")},
|
||||
{Qt::Key_nobreakspace, QStringLiteral("nobreakspace")},
|
||||
{Qt::Key_exclamdown, QStringLiteral("exclamdown")},
|
||||
{Qt::Key_cent, QStringLiteral("cent")},
|
||||
{Qt::Key_sterling, QStringLiteral("sterling")},
|
||||
{Qt::Key_currency, QStringLiteral("currency")},
|
||||
{Qt::Key_yen, QStringLiteral("yen")},
|
||||
{Qt::Key_brokenbar, QStringLiteral("brokenbar")},
|
||||
{Qt::Key_section, QStringLiteral("section")},
|
||||
{Qt::Key_diaeresis, QStringLiteral("diaeresis")},
|
||||
{Qt::Key_copyright, QStringLiteral("copyright")},
|
||||
{Qt::Key_ordfeminine, QStringLiteral("ordfeminine")},
|
||||
{Qt::Key_guillemotleft, QStringLiteral("guillemotleft")},
|
||||
{Qt::Key_notsign, QStringLiteral("notsign")},
|
||||
{Qt::Key_hyphen, QStringLiteral("hyphen")},
|
||||
{Qt::Key_registered, QStringLiteral("registered")},
|
||||
{Qt::Key_macron, QStringLiteral("macron")},
|
||||
{Qt::Key_degree, QStringLiteral("degree")},
|
||||
{Qt::Key_plusminus, QStringLiteral("plusminus")},
|
||||
{Qt::Key_twosuperior, QStringLiteral("twosuperior")},
|
||||
{Qt::Key_threesuperior, QStringLiteral("threesuperior")},
|
||||
{Qt::Key_acute, QStringLiteral("acute")},
|
||||
{Qt::Key_mu, QStringLiteral("mu")},
|
||||
{Qt::Key_paragraph, QStringLiteral("paragraph")},
|
||||
{Qt::Key_periodcentered, QStringLiteral("periodcentered")},
|
||||
{Qt::Key_cedilla, QStringLiteral("cedilla")},
|
||||
{Qt::Key_onesuperior, QStringLiteral("onesuperior")},
|
||||
{Qt::Key_masculine, QStringLiteral("masculine")},
|
||||
{Qt::Key_guillemotright, QStringLiteral("guillemotright")},
|
||||
{Qt::Key_onequarter, QStringLiteral("onequarter")},
|
||||
{Qt::Key_onehalf, QStringLiteral("onehalf")},
|
||||
{Qt::Key_threequarters, QStringLiteral("threequarters")},
|
||||
{Qt::Key_questiondown, QStringLiteral("questiondown")},
|
||||
{Qt::Key_Agrave, QStringLiteral("Agrave")},
|
||||
{Qt::Key_Aacute, QStringLiteral("Aacute")},
|
||||
{Qt::Key_Acircumflex, QStringLiteral("Acircumflex")},
|
||||
{Qt::Key_Atilde, QStringLiteral("Atilde")},
|
||||
{Qt::Key_Adiaeresis, QStringLiteral("Adiaeresis")},
|
||||
{Qt::Key_Aring, QStringLiteral("Aring")},
|
||||
{Qt::Key_AE, QStringLiteral("AE")},
|
||||
{Qt::Key_Ccedilla, QStringLiteral("Ccedilla")},
|
||||
{Qt::Key_Egrave, QStringLiteral("Egrave")},
|
||||
{Qt::Key_Eacute, QStringLiteral("Eacute")},
|
||||
{Qt::Key_Ecircumflex, QStringLiteral("Ecircumflex")},
|
||||
{Qt::Key_Ediaeresis, QStringLiteral("Ediaeresis")},
|
||||
{Qt::Key_Igrave, QStringLiteral("Igrave")},
|
||||
{Qt::Key_Iacute, QStringLiteral("Iacute")},
|
||||
{Qt::Key_Icircumflex, QStringLiteral("Icircumflex")},
|
||||
{Qt::Key_Idiaeresis, QStringLiteral("Idiaeresis")},
|
||||
{Qt::Key_ETH, QStringLiteral("ETH")},
|
||||
{Qt::Key_Ntilde, QStringLiteral("Ntilde")},
|
||||
{Qt::Key_Ograve, QStringLiteral("Ograve")},
|
||||
{Qt::Key_Oacute, QStringLiteral("Oacute")},
|
||||
{Qt::Key_Ocircumflex, QStringLiteral("Ocircumflex")},
|
||||
{Qt::Key_Otilde, QStringLiteral("Otilde")},
|
||||
{Qt::Key_Odiaeresis, QStringLiteral("Odiaeresis")},
|
||||
{Qt::Key_multiply, QStringLiteral("multiply")},
|
||||
{Qt::Key_Ooblique, QStringLiteral("Ooblique")},
|
||||
{Qt::Key_Ugrave, QStringLiteral("Ugrave")},
|
||||
{Qt::Key_Uacute, QStringLiteral("Uacute")},
|
||||
{Qt::Key_Ucircumflex, QStringLiteral("Ucircumflex")},
|
||||
{Qt::Key_Udiaeresis, QStringLiteral("Udiaeresis")},
|
||||
{Qt::Key_Yacute, QStringLiteral("Yacute")},
|
||||
{Qt::Key_THORN, QStringLiteral("THORN")},
|
||||
{Qt::Key_ssharp, QStringLiteral("ssharp")},
|
||||
{Qt::Key_division, QStringLiteral("division")},
|
||||
{Qt::Key_ydiaeresis, QStringLiteral("ydiaeresis")},
|
||||
{Qt::Key_AltGr, QStringLiteral("AltGr")},
|
||||
{Qt::Key_Multi_key, QStringLiteral("Multi_key")},
|
||||
{Qt::Key_Codeinput, QStringLiteral("Codeinput")},
|
||||
{Qt::Key_SingleCandidate, QStringLiteral("SingleCandidate")},
|
||||
{Qt::Key_MultipleCandidate, QStringLiteral("MultipleCandidate")},
|
||||
{Qt::Key_PreviousCandidate, QStringLiteral("PreviousCandidate")},
|
||||
{Qt::Key_Mode_switch, QStringLiteral("Mode_switch")},
|
||||
{Qt::Key_Kanji, QStringLiteral("Kanji")},
|
||||
{Qt::Key_Muhenkan, QStringLiteral("Muhenkan")},
|
||||
{Qt::Key_Henkan, QStringLiteral("Henkan")},
|
||||
{Qt::Key_Romaji, QStringLiteral("Romaji")},
|
||||
{Qt::Key_Hiragana, QStringLiteral("Hiragana")},
|
||||
{Qt::Key_Katakana, QStringLiteral("Katakana")},
|
||||
{Qt::Key_Hiragana_Katakana, QStringLiteral("Hiragana_Katakana")},
|
||||
{Qt::Key_Zenkaku, QStringLiteral("Zenkaku")},
|
||||
{Qt::Key_Hankaku, QStringLiteral("Hankaku")},
|
||||
{Qt::Key_Zenkaku_Hankaku, QStringLiteral("Zenkaku_Hankaku")},
|
||||
{Qt::Key_Touroku, QStringLiteral("Touroku")},
|
||||
{Qt::Key_Massyo, QStringLiteral("Massyo")},
|
||||
{Qt::Key_Kana_Lock, QStringLiteral("Kana_Lock")},
|
||||
{Qt::Key_Kana_Shift, QStringLiteral("Kana_Shift")},
|
||||
{Qt::Key_Eisu_Shift, QStringLiteral("Eisu_Shift")},
|
||||
{Qt::Key_Eisu_toggle, QStringLiteral("Eisu_toggle")},
|
||||
{Qt::Key_Hangul, QStringLiteral("Hangul")},
|
||||
{Qt::Key_Hangul_Start, QStringLiteral("Hangul_Start")},
|
||||
{Qt::Key_Hangul_End, QStringLiteral("Hangul_End")},
|
||||
{Qt::Key_Hangul_Hanja, QStringLiteral("Hangul_Hanja")},
|
||||
{Qt::Key_Hangul_Jamo, QStringLiteral("Hangul_Jamo")},
|
||||
{Qt::Key_Hangul_Romaja, QStringLiteral("Hangul_Romaja")},
|
||||
{Qt::Key_Hangul_Jeonja, QStringLiteral("Hangul_Jeonja")},
|
||||
{Qt::Key_Hangul_Banja, QStringLiteral("Hangul_Banja")},
|
||||
{Qt::Key_Hangul_PreHanja, QStringLiteral("Hangul_PreHanja")},
|
||||
{Qt::Key_Hangul_PostHanja, QStringLiteral("Hangul_PostHanja")},
|
||||
{Qt::Key_Hangul_Special, QStringLiteral("Hangul_Special")},
|
||||
{Qt::Key_Dead_Grave, QStringLiteral("Dead_Grave")},
|
||||
{Qt::Key_Dead_Acute, QStringLiteral("Dead_Acute")},
|
||||
{Qt::Key_Dead_Circumflex, QStringLiteral("Dead_Circumflex")},
|
||||
{Qt::Key_Dead_Tilde, QStringLiteral("Dead_Tilde")},
|
||||
{Qt::Key_Dead_Macron, QStringLiteral("Dead_Macron")},
|
||||
{Qt::Key_Dead_Breve, QStringLiteral("Dead_Breve")},
|
||||
{Qt::Key_Dead_Abovedot, QStringLiteral("Dead_Abovedot")},
|
||||
{Qt::Key_Dead_Diaeresis, QStringLiteral("Dead_Diaeresis")},
|
||||
{Qt::Key_Dead_Abovering, QStringLiteral("Dead_Abovering")},
|
||||
{Qt::Key_Dead_Doubleacute, QStringLiteral("Dead_Doubleacute")},
|
||||
{Qt::Key_Dead_Caron, QStringLiteral("Dead_Caron")},
|
||||
{Qt::Key_Dead_Cedilla, QStringLiteral("Dead_Cedilla")},
|
||||
{Qt::Key_Dead_Ogonek, QStringLiteral("Dead_Ogonek")},
|
||||
{Qt::Key_Dead_Iota, QStringLiteral("Dead_Iota")},
|
||||
{Qt::Key_Dead_Voiced_Sound, QStringLiteral("Dead_Voiced_Sound")},
|
||||
{Qt::Key_Dead_Semivoiced_Sound, QStringLiteral("Dead_Semivoiced_Sound")},
|
||||
{Qt::Key_Dead_Belowdot, QStringLiteral("Dead_Belowdot")},
|
||||
{Qt::Key_Dead_Hook, QStringLiteral("Dead_Hook")},
|
||||
{Qt::Key_Dead_Horn, QStringLiteral("Dead_Horn")},
|
||||
{Qt::Key_Back, QStringLiteral("Back")},
|
||||
{Qt::Key_Forward, QStringLiteral("Forward")},
|
||||
{Qt::Key_Stop, QStringLiteral("Stop")},
|
||||
{Qt::Key_Refresh, QStringLiteral("Refresh")},
|
||||
{Qt::Key_VolumeDown, QStringLiteral("VolumeDown")},
|
||||
{Qt::Key_VolumeMute, QStringLiteral("VolumeMute")},
|
||||
{Qt::Key_VolumeUp, QStringLiteral("VolumeUp")},
|
||||
{Qt::Key_BassBoost, QStringLiteral("BassBoost")},
|
||||
{Qt::Key_BassUp, QStringLiteral("BassUp")},
|
||||
{Qt::Key_BassDown, QStringLiteral("BassDown")},
|
||||
{Qt::Key_TrebleUp, QStringLiteral("TrebleUp")},
|
||||
{Qt::Key_TrebleDown, QStringLiteral("TrebleDown")},
|
||||
{Qt::Key_MediaPlay, QStringLiteral("MediaPlay")},
|
||||
{Qt::Key_MediaStop, QStringLiteral("MediaStop")},
|
||||
{Qt::Key_MediaPrevious, QStringLiteral("MediaPrevious")},
|
||||
{Qt::Key_MediaNext, QStringLiteral("MediaNext")},
|
||||
{Qt::Key_MediaRecord, QStringLiteral("MediaRecord")},
|
||||
{Qt::Key_MediaPause, QStringLiteral("MediaPause")},
|
||||
{Qt::Key_MediaTogglePlayPause, QStringLiteral("MediaTogglePlayPause")},
|
||||
{Qt::Key_HomePage, QStringLiteral("HomePage")},
|
||||
{Qt::Key_Favorites, QStringLiteral("Favorites")},
|
||||
{Qt::Key_Search, QStringLiteral("Search")},
|
||||
{Qt::Key_Standby, QStringLiteral("Standby")},
|
||||
{Qt::Key_OpenUrl, QStringLiteral("OpenUrl")},
|
||||
{Qt::Key_LaunchMail, QStringLiteral("LaunchMail")},
|
||||
{Qt::Key_LaunchMedia, QStringLiteral("LaunchMedia")},
|
||||
{Qt::Key_Launch0, QStringLiteral("Launch0")},
|
||||
{Qt::Key_Launch1, QStringLiteral("Launch1")},
|
||||
{Qt::Key_Launch2, QStringLiteral("Launch2")},
|
||||
{Qt::Key_Launch3, QStringLiteral("Launch3")},
|
||||
{Qt::Key_Launch4, QStringLiteral("Launch4")},
|
||||
{Qt::Key_Launch5, QStringLiteral("Launch5")},
|
||||
{Qt::Key_Launch6, QStringLiteral("Launch6")},
|
||||
{Qt::Key_Launch7, QStringLiteral("Launch7")},
|
||||
{Qt::Key_Launch8, QStringLiteral("Launch8")},
|
||||
{Qt::Key_Launch9, QStringLiteral("Launch9")},
|
||||
{Qt::Key_LaunchA, QStringLiteral("LaunchA")},
|
||||
{Qt::Key_LaunchB, QStringLiteral("LaunchB")},
|
||||
{Qt::Key_LaunchC, QStringLiteral("LaunchC")},
|
||||
{Qt::Key_LaunchD, QStringLiteral("LaunchD")},
|
||||
{Qt::Key_LaunchE, QStringLiteral("LaunchE")},
|
||||
{Qt::Key_LaunchF, QStringLiteral("LaunchF")},
|
||||
{Qt::Key_MonBrightnessUp, QStringLiteral("MonBrightnessUp")},
|
||||
{Qt::Key_MonBrightnessDown, QStringLiteral("MonBrightnessDown")},
|
||||
{Qt::Key_KeyboardLightOnOff, QStringLiteral("KeyboardLightOnOff")},
|
||||
{Qt::Key_KeyboardBrightnessUp, QStringLiteral("KeyboardBrightnessUp")},
|
||||
{Qt::Key_KeyboardBrightnessDown, QStringLiteral("KeyboardBrightnessDown")},
|
||||
{Qt::Key_PowerOff, QStringLiteral("PowerOff")},
|
||||
{Qt::Key_WakeUp, QStringLiteral("WakeUp")},
|
||||
{Qt::Key_Eject, QStringLiteral("Eject")},
|
||||
{Qt::Key_ScreenSaver, QStringLiteral("ScreenSaver")},
|
||||
{Qt::Key_WWW, QStringLiteral("WWW")},
|
||||
{Qt::Key_Memo, QStringLiteral("Memo")},
|
||||
{Qt::Key_LightBulb, QStringLiteral("LightBulb")},
|
||||
{Qt::Key_Shop, QStringLiteral("Shop")},
|
||||
{Qt::Key_History, QStringLiteral("History")},
|
||||
{Qt::Key_AddFavorite, QStringLiteral("AddFavorite")},
|
||||
{Qt::Key_HotLinks, QStringLiteral("HotLinks")},
|
||||
{Qt::Key_BrightnessAdjust, QStringLiteral("BrightnessAdjust")},
|
||||
{Qt::Key_Finance, QStringLiteral("Finance")},
|
||||
{Qt::Key_Community, QStringLiteral("Community")},
|
||||
{Qt::Key_AudioRewind, QStringLiteral("AudioRewind")},
|
||||
{Qt::Key_BackForward, QStringLiteral("BackForward")},
|
||||
{Qt::Key_ApplicationLeft, QStringLiteral("ApplicationLeft")},
|
||||
{Qt::Key_ApplicationRight, QStringLiteral("ApplicationRight")},
|
||||
{Qt::Key_Book, QStringLiteral("Book")},
|
||||
{Qt::Key_CD, QStringLiteral("CD")},
|
||||
{Qt::Key_Calculator, QStringLiteral("Calculator")},
|
||||
{Qt::Key_ToDoList, QStringLiteral("ToDoList")},
|
||||
{Qt::Key_ClearGrab, QStringLiteral("ClearGrab")},
|
||||
{Qt::Key_Close, QStringLiteral("Close")},
|
||||
{Qt::Key_Copy, QStringLiteral("Copy")},
|
||||
{Qt::Key_Cut, QStringLiteral("Cut")},
|
||||
{Qt::Key_Display, QStringLiteral("Display")},
|
||||
{Qt::Key_DOS, QStringLiteral("DOS")},
|
||||
{Qt::Key_Documents, QStringLiteral("Documents")},
|
||||
{Qt::Key_Excel, QStringLiteral("Excel")},
|
||||
{Qt::Key_Explorer, QStringLiteral("Explorer")},
|
||||
{Qt::Key_Game, QStringLiteral("Game")},
|
||||
{Qt::Key_Go, QStringLiteral("Go")},
|
||||
{Qt::Key_iTouch, QStringLiteral("iTouch")},
|
||||
{Qt::Key_LogOff, QStringLiteral("LogOff")},
|
||||
{Qt::Key_Market, QStringLiteral("Market")},
|
||||
{Qt::Key_Meeting, QStringLiteral("Meeting")},
|
||||
{Qt::Key_MenuKB, QStringLiteral("MenuKB")},
|
||||
{Qt::Key_MenuPB, QStringLiteral("MenuPB")},
|
||||
{Qt::Key_MySites, QStringLiteral("MySites")},
|
||||
{Qt::Key_News, QStringLiteral("News")},
|
||||
{Qt::Key_OfficeHome, QStringLiteral("OfficeHome")},
|
||||
{Qt::Key_Option, QStringLiteral("Option")},
|
||||
{Qt::Key_Paste, QStringLiteral("Paste")},
|
||||
{Qt::Key_Phone, QStringLiteral("Phone")},
|
||||
{Qt::Key_Calendar, QStringLiteral("Calendar")},
|
||||
{Qt::Key_Reply, QStringLiteral("Reply")},
|
||||
{Qt::Key_Reload, QStringLiteral("Reload")},
|
||||
{Qt::Key_RotateWindows, QStringLiteral("RotateWindows")},
|
||||
{Qt::Key_RotationPB, QStringLiteral("RotationPB")},
|
||||
{Qt::Key_RotationKB, QStringLiteral("RotationKB")},
|
||||
{Qt::Key_Save, QStringLiteral("Save")},
|
||||
{Qt::Key_Send, QStringLiteral("Send")},
|
||||
{Qt::Key_Spell, QStringLiteral("Spell")},
|
||||
{Qt::Key_SplitScreen, QStringLiteral("SplitScreen")},
|
||||
{Qt::Key_Support, QStringLiteral("Support")},
|
||||
{Qt::Key_TaskPane, QStringLiteral("TaskPane")},
|
||||
{Qt::Key_Terminal, QStringLiteral("Terminal")},
|
||||
{Qt::Key_Tools, QStringLiteral("Tools")},
|
||||
{Qt::Key_Travel, QStringLiteral("Travel")},
|
||||
{Qt::Key_Video, QStringLiteral("Video")},
|
||||
{Qt::Key_Word, QStringLiteral("Word")},
|
||||
{Qt::Key_Xfer, QStringLiteral("Xfer")},
|
||||
{Qt::Key_ZoomIn, QStringLiteral("ZoomIn")},
|
||||
{Qt::Key_ZoomOut, QStringLiteral("ZoomOut")},
|
||||
{Qt::Key_Away, QStringLiteral("Away")},
|
||||
{Qt::Key_Messenger, QStringLiteral("Messenger")},
|
||||
{Qt::Key_WebCam, QStringLiteral("WebCam")},
|
||||
{Qt::Key_MailForward, QStringLiteral("MailForward")},
|
||||
{Qt::Key_Pictures, QStringLiteral("Pictures")},
|
||||
{Qt::Key_Music, QStringLiteral("Music")},
|
||||
{Qt::Key_Battery, QStringLiteral("Battery")},
|
||||
{Qt::Key_Bluetooth, QStringLiteral("Bluetooth")},
|
||||
{Qt::Key_WLAN, QStringLiteral("WLAN")},
|
||||
{Qt::Key_UWB, QStringLiteral("UWB")},
|
||||
{Qt::Key_AudioForward, QStringLiteral("AudioForward")},
|
||||
{Qt::Key_AudioRepeat, QStringLiteral("AudioRepeat")},
|
||||
{Qt::Key_AudioRandomPlay, QStringLiteral("AudioRandomPlay")},
|
||||
{Qt::Key_Subtitle, QStringLiteral("Subtitle")},
|
||||
{Qt::Key_AudioCycleTrack, QStringLiteral("AudioCycleTrack")},
|
||||
{Qt::Key_Time, QStringLiteral("Time")},
|
||||
{Qt::Key_Hibernate, QStringLiteral("Hibernate")},
|
||||
{Qt::Key_View, QStringLiteral("View")},
|
||||
{Qt::Key_TopMenu, QStringLiteral("TopMenu")},
|
||||
{Qt::Key_PowerDown, QStringLiteral("PowerDown")},
|
||||
{Qt::Key_Suspend, QStringLiteral("Suspend")},
|
||||
{Qt::Key_ContrastAdjust, QStringLiteral("ContrastAdjust")},
|
||||
{Qt::Key_LaunchG, QStringLiteral("LaunchG")},
|
||||
{Qt::Key_LaunchH, QStringLiteral("LaunchH")},
|
||||
{Qt::Key_TouchpadToggle, QStringLiteral("TouchpadToggle")},
|
||||
{Qt::Key_TouchpadOn, QStringLiteral("TouchpadOn")},
|
||||
{Qt::Key_TouchpadOff, QStringLiteral("TouchpadOff")},
|
||||
{Qt::Key_MicMute, QStringLiteral("MicMute")},
|
||||
{Qt::Key_Red, QStringLiteral("Red")},
|
||||
{Qt::Key_Green, QStringLiteral("Green")},
|
||||
{Qt::Key_Yellow, QStringLiteral("Yellow")},
|
||||
{Qt::Key_Blue, QStringLiteral("Blue")},
|
||||
{Qt::Key_ChannelUp, QStringLiteral("ChannelUp")},
|
||||
{Qt::Key_ChannelDown, QStringLiteral("ChannelDown")},
|
||||
{Qt::Key_Guide, QStringLiteral("Guide")},
|
||||
{Qt::Key_Info, QStringLiteral("Info")},
|
||||
{Qt::Key_Settings, QStringLiteral("Settings")},
|
||||
{Qt::Key_MicVolumeUp, QStringLiteral("MicVolumeUp")},
|
||||
{Qt::Key_MicVolumeDown, QStringLiteral("MicVolumeDown")},
|
||||
{Qt::Key_New, QStringLiteral("New")},
|
||||
{Qt::Key_Open, QStringLiteral("Open")},
|
||||
{Qt::Key_Find, QStringLiteral("Find")},
|
||||
{Qt::Key_Undo, QStringLiteral("Undo")},
|
||||
{Qt::Key_Redo, QStringLiteral("Redo")},
|
||||
{Qt::Key_MediaLast, QStringLiteral("MediaLast")},
|
||||
{Qt::Key_Select, QStringLiteral("Select")},
|
||||
{Qt::Key_Yes, QStringLiteral("Yes")},
|
||||
{Qt::Key_No, QStringLiteral("No")},
|
||||
{Qt::Key_Cancel, QStringLiteral("Cancel")},
|
||||
{Qt::Key_Printer, QStringLiteral("Printer")},
|
||||
{Qt::Key_Execute, QStringLiteral("Execute")},
|
||||
{Qt::Key_Sleep, QStringLiteral("Sleep")},
|
||||
{Qt::Key_Play, QStringLiteral("Play")},
|
||||
{Qt::Key_Zoom, QStringLiteral("Zoom")},
|
||||
{Qt::Key_Exit, QStringLiteral("Exit")},
|
||||
{Qt::Key_Context1, QStringLiteral("Context1")},
|
||||
{Qt::Key_Context2, QStringLiteral("Context2")},
|
||||
{Qt::Key_Context3, QStringLiteral("Context3")},
|
||||
{Qt::Key_Context4, QStringLiteral("Context4")},
|
||||
{Qt::Key_Call, QStringLiteral("Call")},
|
||||
{Qt::Key_Hangup, QStringLiteral("Hangup")},
|
||||
{Qt::Key_Flip, QStringLiteral("Flip")},
|
||||
{Qt::Key_ToggleCallHangup, QStringLiteral("ToggleCallHangup")},
|
||||
{Qt::Key_VoiceDial, QStringLiteral("VoiceDial")},
|
||||
{Qt::Key_LastNumberRedial, QStringLiteral("LastNumberRedial")},
|
||||
{Qt::Key_Camera, QStringLiteral("Camera")},
|
||||
{Qt::Key_CameraFocus, QStringLiteral("CameraFocus")}};
|
||||
|
||||
struct QtKeyModifierEntry
|
||||
{
|
||||
Qt::KeyboardModifier mod;
|
||||
Qt::Key key;
|
||||
QString name;
|
||||
};
|
||||
|
||||
static const std::array<QtKeyModifierEntry, 5> s_qt_key_modifiers = {
|
||||
{{Qt::ShiftModifier, Qt::Key_Shift, QStringLiteral("Shift")},
|
||||
{Qt::ControlModifier, Qt::Key_Control, QStringLiteral("Control")},
|
||||
{Qt::AltModifier, Qt::Key_Alt, QStringLiteral("Alt")},
|
||||
{Qt::MetaModifier, Qt::Key_Meta, QStringLiteral("Meta")},
|
||||
{Qt::KeypadModifier, static_cast<Qt::Key>(0), QStringLiteral("Keypad")}}};
|
||||
|
||||
QString GetKeyIdentifier(int key)
|
||||
{
|
||||
const auto it = s_qt_key_names.find(key);
|
||||
return it == s_qt_key_names.end() ? QString() : it->second;
|
||||
}
|
||||
|
||||
std::optional<int> GetKeyIdForIdentifier(const QString& key_identifier)
|
||||
{
|
||||
for (const auto& it : s_qt_key_names)
|
||||
{
|
||||
if (it.second == key_identifier)
|
||||
return it.first;
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
QString KeyEventToString(int key, Qt::KeyboardModifiers mods)
|
||||
{
|
||||
QString key_name = GetKeyIdentifier(key);
|
||||
if (key_name.isEmpty())
|
||||
return {};
|
||||
|
||||
QString ret;
|
||||
for (const QtKeyModifierEntry& mod : s_qt_key_modifiers)
|
||||
{
|
||||
if (mods & mod.mod && key != mod.key)
|
||||
{
|
||||
ret.append(mod.name);
|
||||
ret.append('+');
|
||||
}
|
||||
}
|
||||
|
||||
ret.append(key_name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::optional<int> ParseKeyString(const QString& key_str)
|
||||
{
|
||||
const QStringList sections = key_str.split('+');
|
||||
std::optional<int> key_id = GetKeyIdForIdentifier(sections.last());
|
||||
if (!key_id)
|
||||
return std::nullopt;
|
||||
|
||||
int ret = key_id.value();
|
||||
|
||||
if (sections.size() > 1)
|
||||
{
|
||||
const int num_modifiers = sections.size() - 1;
|
||||
for (int i = 0; i < num_modifiers; i++)
|
||||
{
|
||||
for (const QtKeyModifierEntry& mod : s_qt_key_modifiers)
|
||||
{
|
||||
if (sections[i] == mod.name)
|
||||
{
|
||||
ret |= static_cast<int>(mod.mod);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int KeyEventToInt(int key, Qt::KeyboardModifiers mods)
|
||||
{
|
||||
int val = key;
|
||||
if (mods != 0)
|
||||
{
|
||||
for (const QtKeyModifierEntry& mod : s_qt_key_modifiers)
|
||||
{
|
||||
if (mods & mod.mod && key != mod.key)
|
||||
val |= static_cast<int>(mod.mod);
|
||||
}
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void OpenURL(QWidget* parent, const QUrl& qurl)
|
||||
{
|
||||
if (!QDesktopServices::openUrl(qurl))
|
||||
{
|
||||
QMessageBox::critical(parent, QObject::tr("Failed to open URL"),
|
||||
QObject::tr("Failed to open URL.\n\nThe URL was: %1").arg(qurl.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
void OpenURL(QWidget* parent, const char* url)
|
||||
{
|
||||
return OpenURL(parent, QUrl::fromEncoded(QByteArray(url, static_cast<int>(std::strlen(url)))));
|
||||
}
|
||||
|
||||
void OpenURL(QWidget* parent, const QString& url)
|
||||
{
|
||||
return OpenURL(parent, QUrl(url));
|
||||
}
|
||||
|
||||
wxString QStringToWxString(const QString& str)
|
||||
{
|
||||
return wxString(str.toStdWString());
|
||||
}
|
||||
|
||||
QString WxStringToQString(const wxString& str)
|
||||
{
|
||||
return QString::fromStdWString(str.ToStdWstring());
|
||||
}
|
||||
|
||||
} // namespace QtUtils
|
|
@ -0,0 +1,85 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QMetaType>
|
||||
#include <QtCore/QString>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <optional>
|
||||
|
||||
Q_DECLARE_METATYPE(std::optional<bool>);
|
||||
Q_DECLARE_METATYPE(std::function<void()>);
|
||||
|
||||
class ByteStream;
|
||||
|
||||
class QAction;
|
||||
class QComboBox;
|
||||
class QFrame;
|
||||
class QKeyEvent;
|
||||
class QTableView;
|
||||
class QTreeView;
|
||||
class QVariant;
|
||||
class QWidget;
|
||||
class QUrl;
|
||||
|
||||
// TODO: Get rid of wx interoperability later on.
|
||||
#include <wx/string.h>
|
||||
|
||||
namespace QtUtils
|
||||
{
|
||||
/// Marks an action as the "default" - i.e. makes the text bold.
|
||||
void MarkActionAsDefault(QAction* action);
|
||||
|
||||
/// Creates a horizontal line widget.
|
||||
QFrame* CreateHorizontalLine(QWidget* parent);
|
||||
|
||||
/// Returns the greatest parent of a widget, i.e. its dialog/window.
|
||||
QWidget* GetRootWidget(QWidget* widget, bool stop_at_window_or_dialog = true);
|
||||
|
||||
/// Resizes columns of the table view to at the specified widths. A negative width will stretch the column to use the
|
||||
/// remaining space.
|
||||
void ResizeColumnsForTableView(QTableView* view, const std::initializer_list<int>& widths);
|
||||
void ResizeColumnsForTreeView(QTreeView* view, const std::initializer_list<int>& widths);
|
||||
|
||||
/// Returns a string identifier for a Qt key ID.
|
||||
QString GetKeyIdentifier(int key);
|
||||
|
||||
/// Returns the integer Qt key ID for an identifier.
|
||||
std::optional<int> GetKeyIdForIdentifier(const QString& key_identifier);
|
||||
|
||||
/// Stringizes a key event.
|
||||
QString KeyEventToString(int key, Qt::KeyboardModifiers mods);
|
||||
|
||||
/// Returns an integer id for a stringized key event. Modifiers are in the upper bits.
|
||||
std::optional<int> ParseKeyString(const QString& key_str);
|
||||
|
||||
/// Returns a key id for a key event, including any modifiers.
|
||||
int KeyEventToInt(int key, Qt::KeyboardModifiers mods);
|
||||
|
||||
/// Opens a URL with the default handler.
|
||||
void OpenURL(QWidget* parent, const QUrl& qurl);
|
||||
|
||||
/// Opens a URL string with the default handler.
|
||||
void OpenURL(QWidget* parent, const char* url);
|
||||
|
||||
/// Opens a URL string with the default handler.
|
||||
void OpenURL(QWidget* parent, const QString& url);
|
||||
|
||||
// TODO: Get rid of wx interoperability later on.
|
||||
wxString QStringToWxString(const QString& str);
|
||||
QString WxStringToQString(const wxString& str);
|
||||
} // namespace QtUtils
|
|
@ -0,0 +1,417 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <QtCore/QtCore>
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
#include <QtGui/QAction>
|
||||
#else
|
||||
#include <QtWidgets/QAction>
|
||||
#endif
|
||||
|
||||
#include <QtWidgets/QCheckBox>
|
||||
#include <QtWidgets/QComboBox>
|
||||
#include <QtWidgets/QDoubleSpinBox>
|
||||
#include <QtWidgets/QLineEdit>
|
||||
#include <QtWidgets/QSlider>
|
||||
#include <QtWidgets/QSpinBox>
|
||||
|
||||
#include "EmuThread.h"
|
||||
#include "QtHost.h"
|
||||
|
||||
namespace SettingWidgetBinder
|
||||
{
|
||||
template <typename T>
|
||||
struct SettingAccessor
|
||||
{
|
||||
static bool getBoolValue(const T* widget);
|
||||
static void setBoolValue(T* widget, bool value);
|
||||
|
||||
static int getIntValue(const T* widget);
|
||||
static void setIntValue(T* widget, int value);
|
||||
|
||||
static int getFloatValue(const T* widget);
|
||||
static void setFloatValue(T* widget, int value);
|
||||
|
||||
static QString getStringValue(const T* widget);
|
||||
static void setStringValue(T* widget, const QString& value);
|
||||
|
||||
template <typename F>
|
||||
static void connectValueChanged(T* widget, F func);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct SettingAccessor<QLineEdit>
|
||||
{
|
||||
static bool getBoolValue(const QLineEdit* widget) { return widget->text().toInt() != 0; }
|
||||
static void setBoolValue(QLineEdit* widget, bool value)
|
||||
{
|
||||
widget->setText(value ? QStringLiteral("1") : QStringLiteral("0"));
|
||||
}
|
||||
|
||||
static int getIntValue(const QLineEdit* widget) { return widget->text().toInt(); }
|
||||
static void setIntValue(QLineEdit* widget, int value) { widget->setText(QString::number(value)); }
|
||||
|
||||
static float getFloatValue(const QLineEdit* widget) { return widget->text().toFloat(); }
|
||||
static void setFloatValue(QLineEdit* widget, float value) { widget->setText(QString::number(value)); }
|
||||
|
||||
static QString getStringValue(const QLineEdit* widget) { return widget->text(); }
|
||||
static void setStringValue(QLineEdit* widget, const QString& value) { widget->setText(value); }
|
||||
|
||||
template <typename F>
|
||||
static void connectValueChanged(QLineEdit* widget, F func)
|
||||
{
|
||||
widget->connect(widget, &QLineEdit::textChanged, func);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct SettingAccessor<QComboBox>
|
||||
{
|
||||
static bool getBoolValue(const QComboBox* widget) { return widget->currentIndex() > 0; }
|
||||
static void setBoolValue(QComboBox* widget, bool value) { widget->setCurrentIndex(value ? 1 : 0); }
|
||||
|
||||
static int getIntValue(const QComboBox* widget) { return widget->currentIndex(); }
|
||||
static void setIntValue(QComboBox* widget, int value) { widget->setCurrentIndex(value); }
|
||||
|
||||
static float getFloatValue(const QComboBox* widget) { return static_cast<float>(widget->currentIndex()); }
|
||||
static void setFloatValue(QComboBox* widget, float value) { widget->setCurrentIndex(static_cast<int>(value)); }
|
||||
|
||||
static QString getStringValue(const QComboBox* widget)
|
||||
{
|
||||
const QVariant currentData(widget->currentData());
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
if (currentData.type() == QVariant::String)
|
||||
return currentData.toString();
|
||||
#else
|
||||
if (currentData.metaType().id() == QMetaType::QString)
|
||||
return currentData.toString();
|
||||
#endif
|
||||
|
||||
return widget->currentText();
|
||||
}
|
||||
|
||||
static void setStringValue(QComboBox* widget, const QString& value)
|
||||
{
|
||||
const int index = widget->findData(value);
|
||||
if (index >= 0)
|
||||
{
|
||||
widget->setCurrentIndex(index);
|
||||
return;
|
||||
}
|
||||
|
||||
widget->setCurrentText(value);
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
static void connectValueChanged(QComboBox* widget, F func)
|
||||
{
|
||||
widget->connect(widget, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), func);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct SettingAccessor<QCheckBox>
|
||||
{
|
||||
static bool getBoolValue(const QCheckBox* widget) { return widget->isChecked(); }
|
||||
static void setBoolValue(QCheckBox* widget, bool value) { widget->setChecked(value); }
|
||||
|
||||
static int getIntValue(const QCheckBox* widget) { return widget->isChecked() ? 1 : 0; }
|
||||
static void setIntValue(QCheckBox* widget, int value) { widget->setChecked(value != 0); }
|
||||
|
||||
static float getFloatValue(const QCheckBox* widget) { return widget->isChecked() ? 1.0f : 0.0f; }
|
||||
static void setFloatValue(QCheckBox* widget, float value) { widget->setChecked(value != 0.0f); }
|
||||
|
||||
static QString getStringValue(const QCheckBox* widget)
|
||||
{
|
||||
return widget->isChecked() ? QStringLiteral("1") : QStringLiteral("0");
|
||||
}
|
||||
static void setStringValue(QCheckBox* widget, const QString& value) { widget->setChecked(value.toInt() != 0); }
|
||||
|
||||
template <typename F>
|
||||
static void connectValueChanged(QCheckBox* widget, F func)
|
||||
{
|
||||
widget->connect(widget, &QCheckBox::stateChanged, func);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct SettingAccessor<QSlider>
|
||||
{
|
||||
static bool getBoolValue(const QSlider* widget) { return widget->value() > 0; }
|
||||
static void setBoolValue(QSlider* widget, bool value) { widget->setValue(value ? 1 : 0); }
|
||||
|
||||
static int getIntValue(const QSlider* widget) { return widget->value(); }
|
||||
static void setIntValue(QSlider* widget, int value) { widget->setValue(value); }
|
||||
|
||||
static float getFloatValue(const QSlider* widget) { return static_cast<float>(widget->value()); }
|
||||
static void setFloatValue(QSlider* widget, float value) { widget->setValue(static_cast<int>(value)); }
|
||||
|
||||
static QString getStringValue(const QSlider* widget) { return QString::number(widget->value()); }
|
||||
static void setStringValue(QSlider* widget, const QString& value) { widget->setValue(value.toInt()); }
|
||||
|
||||
template <typename F>
|
||||
static void connectValueChanged(QSlider* widget, F func)
|
||||
{
|
||||
widget->connect(widget, &QSlider::valueChanged, func);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct SettingAccessor<QSpinBox>
|
||||
{
|
||||
static bool getBoolValue(const QSpinBox* widget) { return widget->value() > 0; }
|
||||
static void setBoolValue(QSpinBox* widget, bool value) { widget->setValue(value ? 1 : 0); }
|
||||
|
||||
static int getIntValue(const QSpinBox* widget) { return widget->value(); }
|
||||
static void setIntValue(QSpinBox* widget, int value) { widget->setValue(value); }
|
||||
|
||||
static float getFloatValue(const QSpinBox* widget) { return static_cast<float>(widget->value()); }
|
||||
static void setFloatValue(QSpinBox* widget, float value) { widget->setValue(static_cast<int>(value)); }
|
||||
|
||||
static QString getStringValue(const QSpinBox* widget) { return QString::number(widget->value()); }
|
||||
static void setStringValue(QSpinBox* widget, const QString& value) { widget->setValue(value.toInt()); }
|
||||
|
||||
template <typename F>
|
||||
static void connectValueChanged(QSpinBox* widget, F func)
|
||||
{
|
||||
widget->connect(widget, QOverload<int>::of(&QSpinBox::valueChanged), func);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct SettingAccessor<QDoubleSpinBox>
|
||||
{
|
||||
static bool getBoolValue(const QDoubleSpinBox* widget) { return widget->value() > 0.0; }
|
||||
static void setBoolValue(QDoubleSpinBox* widget, bool value) { widget->setValue(value ? 1.0 : 0.0); }
|
||||
|
||||
static int getIntValue(const QDoubleSpinBox* widget) { return static_cast<int>(widget->value()); }
|
||||
static void setIntValue(QDoubleSpinBox* widget, int value) { widget->setValue(static_cast<double>(value)); }
|
||||
|
||||
static float getFloatValue(const QDoubleSpinBox* widget) { return static_cast<float>(widget->value()); }
|
||||
static void setFloatValue(QDoubleSpinBox* widget, float value) { widget->setValue(static_cast<double>(value)); }
|
||||
|
||||
static QString getStringValue(const QDoubleSpinBox* widget) { return QString::number(widget->value()); }
|
||||
static void setStringValue(QDoubleSpinBox* widget, const QString& value) { widget->setValue(value.toDouble()); }
|
||||
|
||||
template <typename F>
|
||||
static void connectValueChanged(QDoubleSpinBox* widget, F func)
|
||||
{
|
||||
widget->connect(widget, QOverload<double>::of(&QDoubleSpinBox::valueChanged), func);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct SettingAccessor<QAction>
|
||||
{
|
||||
static bool getBoolValue(const QAction* widget) { return widget->isChecked(); }
|
||||
static void setBoolValue(QAction* widget, bool value) { widget->setChecked(value); }
|
||||
|
||||
static int getIntValue(const QAction* widget) { return widget->isChecked() ? 1 : 0; }
|
||||
static void setIntValue(QAction* widget, int value) { widget->setChecked(value != 0); }
|
||||
|
||||
static float getFloatValue(const QAction* widget) { return widget->isChecked() ? 1.0f : 0.0f; }
|
||||
static void setFloatValue(QAction* widget, float value) { widget->setChecked(value != 0.0f); }
|
||||
|
||||
static QString getStringValue(const QAction* widget)
|
||||
{
|
||||
return widget->isChecked() ? QStringLiteral("1") : QStringLiteral("0");
|
||||
}
|
||||
static void setStringValue(QAction* widget, const QString& value) { widget->setChecked(value.toInt() != 0); }
|
||||
|
||||
template <typename F>
|
||||
static void connectValueChanged(QAction* widget, F func)
|
||||
{
|
||||
widget->connect(widget, &QAction::toggled, func);
|
||||
}
|
||||
};
|
||||
|
||||
/// Binds a widget's value to a setting, updating it when the value changes.
|
||||
|
||||
template <typename WidgetType>
|
||||
static void BindWidgetToBoolSetting(WidgetType* widget, std::string section, std::string key, bool default_value)
|
||||
{
|
||||
using Accessor = SettingAccessor<WidgetType>;
|
||||
|
||||
bool value = QtHost::GetBaseBoolSettingValue(section.c_str(), key.c_str(), default_value);
|
||||
|
||||
Accessor::setBoolValue(widget, value);
|
||||
|
||||
Accessor::connectValueChanged(widget, [widget, section, key]() {
|
||||
const bool new_value = Accessor::getBoolValue(widget);
|
||||
QtHost::SetBaseBoolSettingValue(section.c_str(), key.c_str(), new_value);
|
||||
g_emu_thread->applySettings();
|
||||
});
|
||||
}
|
||||
|
||||
template <typename WidgetType>
|
||||
static void BindWidgetToIntSetting(WidgetType* widget, std::string section, std::string key, int default_value, int option_offset = 0)
|
||||
{
|
||||
using Accessor = SettingAccessor<WidgetType>;
|
||||
|
||||
s32 value = QtHost::GetBaseIntSettingValue(section.c_str(), key.c_str(), static_cast<s32>(default_value)) - option_offset;
|
||||
|
||||
Accessor::setIntValue(widget, static_cast<int>(value));
|
||||
|
||||
Accessor::connectValueChanged(widget, [widget, section, key, option_offset]() {
|
||||
const int new_value = Accessor::getIntValue(widget);
|
||||
QtHost::SetBaseIntSettingValue(section.c_str(), key.c_str(), new_value + option_offset);
|
||||
g_emu_thread->applySettings();
|
||||
});
|
||||
}
|
||||
|
||||
template <typename WidgetType>
|
||||
static void BindWidgetToFloatSetting(WidgetType* widget, std::string section, std::string key, float default_value)
|
||||
{
|
||||
using Accessor = SettingAccessor<WidgetType>;
|
||||
|
||||
float value = QtHost::GetBaseFloatSettingValue(section.c_str(), key.c_str(), default_value);
|
||||
|
||||
Accessor::setFloatValue(widget, value);
|
||||
|
||||
Accessor::connectValueChanged(widget, [widget, section, key]() {
|
||||
const float new_value = Accessor::getFloatValue(widget);
|
||||
QtHost::SetBaseFloatSettingValue(section.c_str(), key.c_str(), new_value);
|
||||
g_emu_thread->applySettings();
|
||||
});
|
||||
}
|
||||
|
||||
template <typename WidgetType>
|
||||
static void BindWidgetToNormalizedSetting(WidgetType* widget, std::string section, std::string key, float range,
|
||||
float default_value)
|
||||
{
|
||||
using Accessor = SettingAccessor<WidgetType>;
|
||||
|
||||
float value = QtHost::GetBaseFloatSettingValue(section.c_str(), key.c_str(), default_value);
|
||||
|
||||
Accessor::setIntValue(widget, static_cast<int>(value * range));
|
||||
|
||||
Accessor::connectValueChanged(widget, [widget, section, key, range]() {
|
||||
const float new_value = (static_cast<float>(Accessor::getIntValue(widget)) / range);
|
||||
QtHost::SetBaseFloatSettingValue(section.c_str(), key.c_str(), new_value);
|
||||
g_emu_thread->applySettings();
|
||||
});
|
||||
}
|
||||
|
||||
template <typename WidgetType>
|
||||
static void BindWidgetToStringSetting(WidgetType* widget, std::string section, std::string key,
|
||||
std::string default_value = std::string())
|
||||
{
|
||||
using Accessor = SettingAccessor<WidgetType>;
|
||||
|
||||
std::string value = QtHost::GetBaseStringSettingValue(section.c_str(), key.c_str(), default_value.c_str());
|
||||
|
||||
Accessor::setStringValue(widget, QString::fromStdString(value));
|
||||
|
||||
Accessor::connectValueChanged(widget, [widget, section, key]() {
|
||||
const QString new_value = Accessor::getStringValue(widget);
|
||||
if (!new_value.isEmpty())
|
||||
QtHost::SetBaseStringSettingValue(section.c_str(), key.c_str(), new_value.toUtf8().constData());
|
||||
else
|
||||
QtHost::RemoveBaseSettingValue(section.c_str(), key.c_str());
|
||||
|
||||
g_emu_thread->applySettings();
|
||||
});
|
||||
}
|
||||
|
||||
template <typename WidgetType, typename DataType>
|
||||
static void BindWidgetToEnumSetting(WidgetType* widget, std::string section, std::string key,
|
||||
std::optional<DataType> (*from_string_function)(const char* str),
|
||||
const char* (*to_string_function)(DataType value), DataType default_value)
|
||||
{
|
||||
using Accessor = SettingAccessor<WidgetType>;
|
||||
using UnderlyingType = std::underlying_type_t<DataType>;
|
||||
|
||||
// TODO: Clean this up?
|
||||
const std::string old_setting_string_value =
|
||||
QtHost::GetBaseStringSettingValue(section.c_str(), key.c_str(), to_string_function(default_value));
|
||||
const std::optional<DataType> old_setting_value = from_string_function(old_setting_string_value.c_str());
|
||||
if (old_setting_value.has_value())
|
||||
Accessor::setIntValue(widget, static_cast<int>(static_cast<UnderlyingType>(old_setting_value.value())));
|
||||
else
|
||||
Accessor::setIntValue(widget, static_cast<int>(static_cast<UnderlyingType>(default_value)));
|
||||
|
||||
Accessor::connectValueChanged(widget, [widget, section, key, to_string_function]() {
|
||||
const DataType value = static_cast<DataType>(static_cast<UnderlyingType>(Accessor::getIntValue(widget)));
|
||||
const char* string_value = to_string_function(value);
|
||||
QtHost::SetBaseStringSettingValue(section.c_str(), key.c_str(), string_value);
|
||||
g_emu_thread->applySettings();
|
||||
});
|
||||
}
|
||||
|
||||
template <typename WidgetType, typename DataType>
|
||||
static void BindWidgetToEnumSetting(WidgetType* widget, std::string section, std::string key, const char** enum_names,
|
||||
DataType default_value)
|
||||
{
|
||||
using Accessor = SettingAccessor<WidgetType>;
|
||||
using UnderlyingType = std::underlying_type_t<DataType>;
|
||||
|
||||
const std::string old_setting_string_value = QtHost::GetBaseStringSettingValue(
|
||||
section.c_str(), key.c_str(), enum_names[static_cast<UnderlyingType>(default_value)]);
|
||||
|
||||
UnderlyingType enum_index = static_cast<UnderlyingType>(default_value);
|
||||
for (UnderlyingType i = 0; enum_names[i] != nullptr; i++)
|
||||
{
|
||||
if (old_setting_string_value == enum_names[i])
|
||||
{
|
||||
enum_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Accessor::setIntValue(widget, static_cast<int>(enum_index));
|
||||
|
||||
Accessor::connectValueChanged(widget, [widget, section, key, enum_names]() {
|
||||
const UnderlyingType value = static_cast<UnderlyingType>(Accessor::getIntValue(widget));
|
||||
const char* string_value = enum_names[value];
|
||||
QtHost::SetBaseStringSettingValue(section.c_str(), key.c_str(), string_value);
|
||||
g_emu_thread->applySettings();
|
||||
});
|
||||
}
|
||||
|
||||
template <typename WidgetType>
|
||||
static void BindWidgetToEnumSetting(WidgetType* widget, std::string section, std::string key, const char** enum_names,
|
||||
const char** enum_values, const char* default_value)
|
||||
{
|
||||
using Accessor = SettingAccessor<WidgetType>;
|
||||
|
||||
const std::string old_setting_string_value =
|
||||
QtHost::GetBaseStringSettingValue(section.c_str(), key.c_str(), default_value);
|
||||
|
||||
for (int i = 0; enum_names[i] != nullptr; i++)
|
||||
widget->addItem(QString::fromUtf8(enum_names[i]));
|
||||
|
||||
int enum_index = -1;
|
||||
for (int i = 0; enum_values[i] != nullptr; i++)
|
||||
{
|
||||
if (old_setting_string_value == enum_values[i])
|
||||
{
|
||||
enum_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (enum_index >= 0)
|
||||
Accessor::setIntValue(widget, enum_index);
|
||||
|
||||
Accessor::connectValueChanged(widget, [widget, section, key, enum_values]() {
|
||||
const int value = Accessor::getIntValue(widget);
|
||||
QtHost::SetBaseStringSettingValue(section.c_str(), key.c_str(), enum_values[value]);
|
||||
g_emu_thread->applySettings();
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace SettingWidgetBinder
|
|
@ -0,0 +1,50 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <algorithm>
|
||||
|
||||
#include "AdvancedSystemSettingsWidget.h"
|
||||
#include "EmuThread.h"
|
||||
#include "QtUtils.h"
|
||||
#include "SettingWidgetBinder.h"
|
||||
#include "SettingsDialog.h"
|
||||
|
||||
AdvancedSystemSettingsWidget::AdvancedSystemSettingsWidget(QWidget* parent, SettingsDialog* dialog)
|
||||
: QWidget(parent)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.eeRecompiler, "EmuCore/CPU/Recompiler", "EnableEE", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.eeCache, "EmuCore/CPU/Recompiler", "EnableEECache", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.eeINTCSpinDetection, "EmuCore/Speedhacks", "IntcStat", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.eeWaitLoopDetection, "EmuCore/Speedhacks", "WaitLoop", true);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.vu0Recompiler, "EmuCore/CPU/Recompiler", "EnableVU0", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.vu1Recompiler, "EmuCore/CPU/Recompiler", "EnableVU1", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.vuFlagHack, "EmuCore/Speedhacks", "vuFlagHack", true);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.iopRecompiler, "EmuCore/CPU/Recompiler", "EnableIOP", true);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.gameFixes, "", "EnableGameFixes", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.patches, "EmuCore", "EnablePatches", true);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToFloatSetting(m_ui.ntscFrameRate, "EmuCore/GS", "FramerateNTSC", 59.94f);
|
||||
SettingWidgetBinder::BindWidgetToFloatSetting(m_ui.palFrameRate, "EmuCore/GS", "FrameratePAL", 50.00f);
|
||||
}
|
||||
|
||||
AdvancedSystemSettingsWidget::~AdvancedSystemSettingsWidget() = default;
|
|
@ -0,0 +1,34 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtWidgets/QWidget>
|
||||
|
||||
#include "ui_AdvancedSystemSettingsWidget.h"
|
||||
|
||||
class SettingsDialog;
|
||||
|
||||
class AdvancedSystemSettingsWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AdvancedSystemSettingsWidget(QWidget* parent, SettingsDialog* dialog);
|
||||
~AdvancedSystemSettingsWidget();
|
||||
|
||||
private:
|
||||
Ui::AdvancedSystemSettingsWidget m_ui;
|
||||
};
|
|
@ -0,0 +1,197 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AdvancedSystemSettingsWidget</class>
|
||||
<widget class="QWidget" name="AdvancedSystemSettingsWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>648</width>
|
||||
<height>481</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>EmotionEngine (MIPS-IV)</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="eeRecompiler">
|
||||
<property name="text">
|
||||
<string>Enable Recompiler</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="eeWaitLoopDetection">
|
||||
<property name="text">
|
||||
<string>Wait Loop Detection</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="eeCache">
|
||||
<property name="text">
|
||||
<string>Enable Cache (Slow)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="eeINTCSpinDetection">
|
||||
<property name="text">
|
||||
<string>INTC Spin Detection</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Vector Units (VU)</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="vuFlagHack">
|
||||
<property name="text">
|
||||
<string>mVU Flag Hack</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="vu0Recompiler">
|
||||
<property name="text">
|
||||
<string>Enable VU0 Recompiler (Micro Mode)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="vu1Recompiler">
|
||||
<property name="text">
|
||||
<string>Enable VU1 Recompiler</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>I/O Processor (IOP, MIPS-I)</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="iopRecompiler">
|
||||
<property name="text">
|
||||
<string>Enable Recompiler</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_4">
|
||||
<property name="title">
|
||||
<string>Game Settings</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="gameFixes">
|
||||
<property name="text">
|
||||
<string>Enable Game Fixes</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="patches">
|
||||
<property name="text">
|
||||
<string>Enable Compatibility Patches</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="basicGroupBox">
|
||||
<property name="title">
|
||||
<string>Frame Rate Control</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="1" column="1">
|
||||
<widget class="QDoubleSpinBox" name="palFrameRate">
|
||||
<property name="suffix">
|
||||
<string> hz</string>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QDoubleSpinBox" name="ntscFrameRate">
|
||||
<property name="suffix">
|
||||
<string> hz</string>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>PAL Frame Rate:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>NTSC Frame Rate:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>3</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../resources/resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,179 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include <QtGui/QIcon>
|
||||
#include <QtWidgets/QFileDialog>
|
||||
#include <algorithm>
|
||||
|
||||
#include "pcsx2/ps2/BiosTools.h"
|
||||
|
||||
#include "BIOSSettingsWidget.h"
|
||||
#include "QtUtils.h"
|
||||
#include "SettingWidgetBinder.h"
|
||||
#include "SettingsDialog.h"
|
||||
|
||||
BIOSSettingsWidget::BIOSSettingsWidget(QWidget* parent, SettingsDialog* dialog)
|
||||
: QWidget(parent)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.fastBoot, "EmuCore", "EnableFastBoot", true);
|
||||
|
||||
dialog->registerWidgetHelp(m_ui.fastBoot, tr("Fast Boot"), tr("Unchecked"),
|
||||
tr("Patches the BIOS to skip the console's boot animation."));
|
||||
|
||||
updateSearchDirectory();
|
||||
refreshList();
|
||||
|
||||
connect(m_ui.searchDirectory, &QLineEdit::textChanged, [this](const QString& text) {
|
||||
QtHost::SetBaseStringSettingValue("Folders", "Bios", text.toUtf8().constData());
|
||||
QtHost::UpdateFolders();
|
||||
refreshList();
|
||||
});
|
||||
connect(m_ui.resetSearchDirectory, &QPushButton::clicked, [this]() {
|
||||
QtHost::RemoveBaseSettingValue("Folders", "Bios");
|
||||
QtHost::UpdateFolders();
|
||||
updateSearchDirectory();
|
||||
refreshList();
|
||||
});
|
||||
connect(m_ui.browseSearchDirectory, &QPushButton::clicked, this, &BIOSSettingsWidget::browseSearchDirectory);
|
||||
connect(m_ui.openSearchDirectory, &QPushButton::clicked, this, &BIOSSettingsWidget::openSearchDirectory);
|
||||
connect(m_ui.refresh, &QPushButton::clicked, this, &BIOSSettingsWidget::refreshList);
|
||||
connect(m_ui.fileList, &QTreeWidget::currentItemChanged, this, &BIOSSettingsWidget::listItemChanged);
|
||||
}
|
||||
|
||||
BIOSSettingsWidget::~BIOSSettingsWidget()
|
||||
{
|
||||
if (m_refresh_thread)
|
||||
m_refresh_thread->wait();
|
||||
}
|
||||
|
||||
void BIOSSettingsWidget::refreshList()
|
||||
{
|
||||
if (m_refresh_thread)
|
||||
{
|
||||
m_refresh_thread->wait();
|
||||
delete m_refresh_thread;
|
||||
}
|
||||
|
||||
QSignalBlocker blocker(m_ui.fileList);
|
||||
m_ui.fileList->clear();
|
||||
m_ui.fileList->setEnabled(false);
|
||||
|
||||
m_refresh_thread = new RefreshThread(this, m_ui.searchDirectory->text());
|
||||
m_refresh_thread->start();
|
||||
}
|
||||
|
||||
void BIOSSettingsWidget::browseSearchDirectory()
|
||||
{
|
||||
QString directory = QDir::toNativeSeparators(QFileDialog::getExistingDirectory(
|
||||
QtUtils::GetRootWidget(this), tr("Select Directory"), m_ui.searchDirectory->text()));
|
||||
if (directory.isEmpty())
|
||||
return;
|
||||
|
||||
m_ui.searchDirectory->setText(directory);
|
||||
}
|
||||
|
||||
void BIOSSettingsWidget::openSearchDirectory()
|
||||
{
|
||||
QtUtils::OpenURL(this, QUrl::fromLocalFile(m_ui.searchDirectory->text()));
|
||||
}
|
||||
|
||||
void BIOSSettingsWidget::updateSearchDirectory()
|
||||
{
|
||||
// this will generate a full path
|
||||
m_ui.searchDirectory->setText(QtUtils::WxStringToQString(EmuFolders::Bios.ToString()));
|
||||
}
|
||||
|
||||
void BIOSSettingsWidget::listRefreshed(const QVector<BIOSInfo>& items)
|
||||
{
|
||||
const std::string selected_bios(QtHost::GetBaseStringSettingValue("Filenames", "BIOS"));
|
||||
|
||||
QSignalBlocker sb(m_ui.fileList);
|
||||
for (const BIOSInfo& bi : items)
|
||||
{
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem();
|
||||
item->setText(0, QString::fromStdString(bi.filename));
|
||||
item->setText(1, QString::fromStdString(bi.description));
|
||||
|
||||
switch (bi.region)
|
||||
{
|
||||
case 2: // Japan
|
||||
item->setIcon(0, QIcon(QStringLiteral(":/icons/flag-jp.png")));
|
||||
break;
|
||||
|
||||
case 3: // USA
|
||||
item->setIcon(0, QIcon(QStringLiteral(":/icons/flag-us.png")));
|
||||
break;
|
||||
|
||||
case 4: // Europe
|
||||
item->setIcon(0, QIcon(QStringLiteral(":/icons/flag-eu.png")));
|
||||
break;
|
||||
|
||||
case 5: // HK
|
||||
case 6: // Free
|
||||
case 7: // China
|
||||
case 0: // T10K
|
||||
case 1: // Test
|
||||
default:
|
||||
item->setIcon(0, QIcon(QStringLiteral(":/icons/flag-jp.png")));
|
||||
break;
|
||||
}
|
||||
|
||||
m_ui.fileList->addTopLevelItem(item);
|
||||
|
||||
if (bi.filename == selected_bios)
|
||||
item->setSelected(true);
|
||||
}
|
||||
m_ui.fileList->setEnabled(true);
|
||||
}
|
||||
|
||||
void BIOSSettingsWidget::listItemChanged(const QTreeWidgetItem* current, const QTreeWidgetItem* previous)
|
||||
{
|
||||
QtHost::SetBaseStringSettingValue("Filenames", "BIOS", current->text(0).toUtf8().constData());
|
||||
}
|
||||
|
||||
BIOSSettingsWidget::RefreshThread::RefreshThread(BIOSSettingsWidget* parent, const QString& directory)
|
||||
: QThread(parent)
|
||||
, m_parent(parent)
|
||||
, m_directory(directory)
|
||||
{
|
||||
}
|
||||
|
||||
BIOSSettingsWidget::RefreshThread::~RefreshThread() = default;
|
||||
|
||||
void BIOSSettingsWidget::RefreshThread::run()
|
||||
{
|
||||
QVector<BIOSInfo> items;
|
||||
|
||||
QDir dir(m_directory);
|
||||
if (dir.exists())
|
||||
{
|
||||
for (const QFileInfo& info : dir.entryInfoList(QDir::Files))
|
||||
{
|
||||
BIOSInfo bi;
|
||||
QString full_path(info.absoluteFilePath());
|
||||
if (!IsBIOS(full_path.toUtf8().constData(), bi.version, bi.description, bi.region, bi.zone))
|
||||
continue;
|
||||
|
||||
bi.filename = info.fileName().toStdString();
|
||||
items.push_back(std::move(bi));
|
||||
}
|
||||
}
|
||||
|
||||
QMetaObject::invokeMethod(m_parent, "listRefreshed", Qt::QueuedConnection, Q_ARG(const QVector<BIOSInfo>&, items));
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QPair>
|
||||
#include <QtCore/QVector>
|
||||
#include <QtWidgets/QWidget>
|
||||
#include <string>
|
||||
|
||||
#include "ui_BIOSSettingsWidget.h"
|
||||
|
||||
class SettingsDialog;
|
||||
class QThread;
|
||||
|
||||
// TODO: Move to core.
|
||||
struct BIOSInfo
|
||||
{
|
||||
std::string filename;
|
||||
std::string description;
|
||||
std::string zone;
|
||||
u32 version;
|
||||
u32 region;
|
||||
};
|
||||
Q_DECLARE_METATYPE(BIOSInfo);
|
||||
|
||||
class BIOSSettingsWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BIOSSettingsWidget(QWidget* parent, SettingsDialog* dialog);
|
||||
~BIOSSettingsWidget();
|
||||
|
||||
private Q_SLOTS:
|
||||
void refreshList();
|
||||
void browseSearchDirectory();
|
||||
void openSearchDirectory();
|
||||
void updateSearchDirectory();
|
||||
|
||||
void listItemChanged(const QTreeWidgetItem* current, const QTreeWidgetItem* previous);
|
||||
void listRefreshed(const QVector<BIOSInfo>& items);
|
||||
|
||||
private:
|
||||
Ui::BIOSSettingsWidget m_ui;
|
||||
|
||||
class RefreshThread final : public QThread
|
||||
{
|
||||
public:
|
||||
RefreshThread(BIOSSettingsWidget* parent, const QString& directory);
|
||||
~RefreshThread();
|
||||
|
||||
protected:
|
||||
void run() override;
|
||||
|
||||
private:
|
||||
BIOSSettingsWidget* m_parent;
|
||||
QString m_directory;
|
||||
};
|
||||
|
||||
RefreshThread* m_refresh_thread = nullptr;
|
||||
};
|
|
@ -0,0 +1,161 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>BIOSSettingsWidget</class>
|
||||
<widget class="QWidget" name="BIOSSettingsWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>618</width>
|
||||
<height>408</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>BIOS Directory</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>PCSX2 will search for BIOS images in this directory.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="searchDirectory"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="browseSearchDirectory">
|
||||
<property name="text">
|
||||
<string>Browse...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="resetSearchDirectory">
|
||||
<property name="text">
|
||||
<string>Reset</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>BIOS Selection</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="openSearchDirectory">
|
||||
<property name="text">
|
||||
<string>Open in Explorer...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="refresh">
|
||||
<property name="text">
|
||||
<string>Refresh List</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QTreeWidget" name="fileList">
|
||||
<property name="rootIsDecorated">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Filename</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Version</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Options and Patches</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="fastBoot">
|
||||
<property name="text">
|
||||
<string>Fast Boot</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="resources/resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,97 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ControllerBindingWidget</class>
|
||||
<widget class="QWidget" name="ControllerBindingWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>834</width>
|
||||
<height>560</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="0">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Controller Type</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QComboBox" name="controllerType"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>460</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="automaticBinding">
|
||||
<property name="text">
|
||||
<string>Automatic binding</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="gamepad-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="loadProfile">
|
||||
<property name="text">
|
||||
<string>Load Profile</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="folder-open-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="saveProfile">
|
||||
<property name="text">
|
||||
<string>Save Profile</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="save-3-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../resources/resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,158 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <algorithm>
|
||||
|
||||
#include "ControllerBindingWidgets.h"
|
||||
#include "ControllerSettingsDialog.h"
|
||||
#include "EmuThread.h"
|
||||
#include "QtUtils.h"
|
||||
#include "SettingWidgetBinder.h"
|
||||
#include "SettingsDialog.h"
|
||||
|
||||
#include "common/StringUtil.h"
|
||||
#include "pcsx2/PAD/Host/PAD.h"
|
||||
|
||||
ControllerBindingWidget::ControllerBindingWidget(QWidget* parent, ControllerSettingsDialog* dialog, u32 port)
|
||||
: QWidget(parent)
|
||||
, m_dialog(dialog)
|
||||
, m_config_section(StringUtil::StdStringFromFormat("Pad%u", port + 1u))
|
||||
, m_port_number(port)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
populateControllerTypes();
|
||||
onTypeChanged();
|
||||
|
||||
SettingWidgetBinder::BindWidgetToStringSetting(m_ui.controllerType, m_config_section, "Type", "None");
|
||||
connect(m_ui.controllerType, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&ControllerBindingWidget::onTypeChanged);
|
||||
}
|
||||
|
||||
ControllerBindingWidget::~ControllerBindingWidget()
|
||||
{
|
||||
}
|
||||
|
||||
void ControllerBindingWidget::populateControllerTypes()
|
||||
{
|
||||
m_ui.controllerType->addItem(tr("None (Not Connected)"), QStringLiteral("None"));
|
||||
for (const std::string& type : PAD::GetControllerTypeNames())
|
||||
m_ui.controllerType->addItem(QString::fromStdString(type), QString::fromStdString(type));
|
||||
}
|
||||
|
||||
void ControllerBindingWidget::onTypeChanged()
|
||||
{
|
||||
if (m_current_widget)
|
||||
{
|
||||
m_ui.verticalLayout->removeWidget(m_current_widget);
|
||||
delete m_current_widget;
|
||||
m_current_widget = nullptr;
|
||||
}
|
||||
|
||||
m_controller_type = QtHost::GetBaseStringSettingValue(m_config_section.c_str(), "Type");
|
||||
|
||||
const int index = m_ui.controllerType->findData(QString::fromStdString(m_controller_type));
|
||||
if (index >= 0 && index != m_ui.controllerType->currentIndex())
|
||||
{
|
||||
QSignalBlocker sb(m_ui.controllerType);
|
||||
m_ui.controllerType->setCurrentIndex(index);
|
||||
}
|
||||
|
||||
if (m_controller_type == "DualShock2")
|
||||
m_current_widget = ControllerBindingWidget_DualShock2::createInstance(this);
|
||||
else
|
||||
m_current_widget = new ControllerBindingWidget_Base(this);
|
||||
|
||||
m_ui.verticalLayout->addWidget(m_current_widget, 1);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ControllerBindingWidget_Base::ControllerBindingWidget_Base(ControllerBindingWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
}
|
||||
|
||||
ControllerBindingWidget_Base::~ControllerBindingWidget_Base()
|
||||
{
|
||||
}
|
||||
|
||||
void ControllerBindingWidget_Base::initBindingWidgets()
|
||||
{
|
||||
const std::string& type = getControllerType();
|
||||
const std::string& config_section = getConfigSection();
|
||||
std::vector<std::string> bindings(PAD::GetControllerBinds(type));
|
||||
|
||||
for (std::string& binding : bindings)
|
||||
{
|
||||
InputBindingWidget* widget = findChild<InputBindingWidget*>(QString::fromStdString(binding));
|
||||
if (!widget)
|
||||
{
|
||||
Console.Error("(ControllerBindingWidget_Base) No widget found for '%s' (%*s)",
|
||||
binding.c_str(), static_cast<int>(type.size()), type.data());
|
||||
continue;
|
||||
}
|
||||
|
||||
widget->setKey(config_section, std::move(binding));
|
||||
}
|
||||
|
||||
const PAD::VibrationCapabilities vibe_caps = PAD::GetControllerVibrationCapabilities(type);
|
||||
switch (vibe_caps)
|
||||
{
|
||||
case PAD::VibrationCapabilities::LargeSmallMotors:
|
||||
{
|
||||
InputVibrationBindingWidget* widget = findChild<InputVibrationBindingWidget*>(QStringLiteral("LargeMotor"));
|
||||
if (widget)
|
||||
widget->setKey(getDialog(), config_section, "LargeMotor");
|
||||
|
||||
widget = findChild<InputVibrationBindingWidget*>(QStringLiteral("SmallMotor"));
|
||||
if (widget)
|
||||
widget->setKey(getDialog(), config_section, "SmallMotor");
|
||||
}
|
||||
break;
|
||||
|
||||
case PAD::VibrationCapabilities::SingleMotor:
|
||||
{
|
||||
InputVibrationBindingWidget* widget = findChild<InputVibrationBindingWidget*>(QStringLiteral("Motor"));
|
||||
if (widget)
|
||||
widget->setKey(getDialog(), config_section, "Motor");
|
||||
}
|
||||
break;
|
||||
|
||||
case PAD::VibrationCapabilities::NoVibration:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ControllerBindingWidget_DualShock2::ControllerBindingWidget_DualShock2(ControllerBindingWidget* parent)
|
||||
: ControllerBindingWidget_Base(parent)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
initBindingWidgets();
|
||||
}
|
||||
|
||||
ControllerBindingWidget_DualShock2::~ControllerBindingWidget_DualShock2()
|
||||
{
|
||||
}
|
||||
|
||||
ControllerBindingWidget_Base* ControllerBindingWidget_DualShock2::createInstance(ControllerBindingWidget* parent)
|
||||
{
|
||||
return new ControllerBindingWidget_DualShock2(parent);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
|
@ -0,0 +1,86 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtWidgets/QWidget>
|
||||
|
||||
#include "ui_ControllerBindingWidget.h"
|
||||
#include "ui_ControllerBindingWidget_DualShock2.h"
|
||||
|
||||
class InputBindingWidget;
|
||||
class ControllerSettingsDialog;
|
||||
class ControllerBindingWidget_Base;
|
||||
|
||||
class ControllerBindingWidget final : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ControllerBindingWidget(QWidget* parent, ControllerSettingsDialog* dialog, u32 port);
|
||||
~ControllerBindingWidget();
|
||||
|
||||
__fi ControllerSettingsDialog* getDialog() const { return m_dialog; }
|
||||
__fi const std::string& getConfigSection() const { return m_config_section; }
|
||||
__fi const std::string& getControllerType() const { return m_controller_type; }
|
||||
__fi u32 getPortNumber() const { return m_port_number; }
|
||||
|
||||
private Q_SLOTS:
|
||||
void onTypeChanged();
|
||||
|
||||
private:
|
||||
void populateControllerTypes();
|
||||
|
||||
Ui::ControllerBindingWidget m_ui;
|
||||
|
||||
ControllerSettingsDialog* m_dialog;
|
||||
|
||||
std::string m_config_section;
|
||||
std::string m_controller_type;
|
||||
u32 m_port_number;
|
||||
|
||||
ControllerBindingWidget_Base* m_current_widget = nullptr;
|
||||
};
|
||||
|
||||
class ControllerBindingWidget_Base : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ControllerBindingWidget_Base(ControllerBindingWidget* parent);
|
||||
virtual ~ControllerBindingWidget_Base();
|
||||
|
||||
__fi ControllerSettingsDialog* getDialog() const { return static_cast<ControllerBindingWidget*>(parent())->getDialog(); }
|
||||
__fi const std::string& getConfigSection() const { return static_cast<ControllerBindingWidget*>(parent())->getConfigSection(); }
|
||||
__fi const std::string& getControllerType() const { return static_cast<ControllerBindingWidget*>(parent())->getControllerType(); }
|
||||
__fi u32 getPortNumber() const { return static_cast<ControllerBindingWidget*>(parent())->getPortNumber(); }
|
||||
|
||||
protected:
|
||||
void initBindingWidgets();
|
||||
};
|
||||
|
||||
class ControllerBindingWidget_DualShock2 final : public ControllerBindingWidget_Base
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ControllerBindingWidget_DualShock2(ControllerBindingWidget* parent);
|
||||
~ControllerBindingWidget_DualShock2();
|
||||
|
||||
static ControllerBindingWidget_Base* createInstance(ControllerBindingWidget* parent);
|
||||
|
||||
private:
|
||||
Ui::ControllerBindingWidget_DualShock2 m_ui;
|
||||
};
|
|
@ -0,0 +1,64 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "Frontend/InputManager.h"
|
||||
#include "Settings/ControllerGlobalSettingsWidget.h"
|
||||
#include "Settings/ControllerSettingsDialog.h"
|
||||
#include "QtUtils.h"
|
||||
#include "SettingWidgetBinder.h"
|
||||
|
||||
ControllerGlobalSettingsWidget::ControllerGlobalSettingsWidget(QWidget* parent, ControllerSettingsDialog* dialog)
|
||||
: QWidget(parent)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.enableSDLSource, "InputSources", "SDL", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.enableSDLEnhancedMode, "InputSources", "SDLControllerEnhancedMode", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.enableXInputSource, "InputSources", "XInput", false);
|
||||
|
||||
connect(m_ui.enableSDLSource, &QCheckBox::stateChanged, this, &ControllerGlobalSettingsWidget::updateSDLOptionsEnabled);
|
||||
updateSDLOptionsEnabled();
|
||||
}
|
||||
|
||||
ControllerGlobalSettingsWidget::~ControllerGlobalSettingsWidget() = default;
|
||||
|
||||
void ControllerGlobalSettingsWidget::addDeviceToList(const QString& identifier, const QString& name)
|
||||
{
|
||||
QListWidgetItem* item = new QListWidgetItem();
|
||||
item->setText(QStringLiteral("%1: %2").arg(identifier).arg(name));
|
||||
item->setData(Qt::UserRole, identifier);
|
||||
m_ui.deviceList->addItem(item);
|
||||
}
|
||||
|
||||
void ControllerGlobalSettingsWidget::removeDeviceFromList(const QString& identifier)
|
||||
{
|
||||
const int count = m_ui.deviceList->count();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
QListWidgetItem* item = m_ui.deviceList->item(i);
|
||||
if (item->data(Qt::UserRole) != identifier)
|
||||
continue;
|
||||
|
||||
delete m_ui.deviceList->takeItem(i);
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerGlobalSettingsWidget::updateSDLOptionsEnabled()
|
||||
{
|
||||
const bool enabled = m_ui.enableSDLSource->isChecked();
|
||||
m_ui.enableSDLEnhancedMode->setEnabled(enabled);
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtWidgets/QWidget>
|
||||
#include <QtCore/QMap>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
#include "ui_ControllerGlobalSettingsWidget.h"
|
||||
|
||||
class ControllerSettingsDialog;
|
||||
|
||||
class ControllerGlobalSettingsWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ControllerGlobalSettingsWidget(QWidget* parent, ControllerSettingsDialog* dialog);
|
||||
~ControllerGlobalSettingsWidget();
|
||||
|
||||
void addDeviceToList(const QString& identifier, const QString& name);
|
||||
void removeDeviceFromList(const QString& identifier);
|
||||
|
||||
private:
|
||||
void updateSDLOptionsEnabled();
|
||||
|
||||
Ui::ControllerGlobalSettingsWidget m_ui;
|
||||
};
|
|
@ -0,0 +1,173 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ControllerGlobalSettingsWidget</class>
|
||||
<widget class="QWidget" name="ControllerGlobalSettingsWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>880</width>
|
||||
<height>712</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>SDL Input Source</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>The SDL input source supports most controllers, and provides advanced functionality for Dualshock 4/Dualsense pads in Bluetooth mode (Vibration/LED Control).</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="enableSDLSource">
|
||||
<property name="text">
|
||||
<string>Enable SDL Input Source</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="enableSDLEnhancedMode">
|
||||
<property name="text">
|
||||
<string>Dualshock 4/Dualsense Enhanced Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>XInput Source</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>The XInput source provides support for XBox 360/XBox One/XBox Series controllers, and third party controllers which implement the XInput protocol.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="enableXInputSource">
|
||||
<property name="text">
|
||||
<string>Enable XInput Input Source</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_4">
|
||||
<property name="title">
|
||||
<string>Controller Multitap</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>The multitap enables up to 8 controllers to be connected to the console. Each multitap provides 4 ports. Multitap is not supported by all games. (NOT YET IMPLEMENTED)</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="multitapPort1">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Multitap on Console Port 1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="multitapPort2">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Multitap on Console Port 2</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>Detected Devices</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QListWidget" name="deviceList">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,119 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "EmuThread.h"
|
||||
#include "QtHost.h"
|
||||
#include "Settings/ControllerSettingsDialog.h"
|
||||
#include "Settings/ControllerGlobalSettingsWidget.h"
|
||||
#include "Settings/ControllerBindingWidgets.h"
|
||||
#include "Settings/HotkeySettingsWidget.h"
|
||||
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <QtWidgets/QTextEdit>
|
||||
|
||||
ControllerSettingsDialog::ControllerSettingsDialog(QWidget* parent /* = nullptr */)
|
||||
: QDialog(parent)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
|
||||
m_global_settings = new ControllerGlobalSettingsWidget(m_ui.settingsContainer, this);
|
||||
m_ui.settingsContainer->insertWidget(0, m_global_settings);
|
||||
|
||||
for (u32 i = 0; i < MAX_PORTS; i++)
|
||||
{
|
||||
m_port_bindings[i] = new ControllerBindingWidget(m_ui.settingsContainer, this, i);
|
||||
m_ui.settingsContainer->insertWidget(i + 1, m_port_bindings[i]);
|
||||
}
|
||||
|
||||
m_hotkey_settings = new HotkeySettingsWidget(m_ui.settingsContainer, this);
|
||||
m_ui.settingsContainer->insertWidget(3, m_hotkey_settings);
|
||||
|
||||
m_ui.settingsCategory->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
connect(m_ui.settingsCategory, &QListWidget::currentRowChanged, this, &ControllerSettingsDialog::onCategoryCurrentRowChanged);
|
||||
connect(m_ui.buttonBox, &QDialogButtonBox::rejected, this, &ControllerSettingsDialog::close);
|
||||
|
||||
connect(g_emu_thread, &EmuThread::onInputDevicesEnumerated, this, &ControllerSettingsDialog::onInputDevicesEnumerated);
|
||||
connect(g_emu_thread, &EmuThread::onInputDeviceConnected, this, &ControllerSettingsDialog::onInputDeviceConnected);
|
||||
connect(g_emu_thread, &EmuThread::onInputDeviceDisconnected, this, &ControllerSettingsDialog::onInputDeviceDisconnected);
|
||||
connect(g_emu_thread, &EmuThread::onVibrationMotorsEnumerated, this, &ControllerSettingsDialog::onVibrationMotorsEnumerated);
|
||||
|
||||
// trigger a device enumeration to populate the device list
|
||||
g_emu_thread->enumerateInputDevices();
|
||||
g_emu_thread->enumerateVibrationMotors();
|
||||
}
|
||||
|
||||
ControllerSettingsDialog::~ControllerSettingsDialog() = default;
|
||||
|
||||
void ControllerSettingsDialog::setCategory(Category category)
|
||||
{
|
||||
switch (category)
|
||||
{
|
||||
case Category::GlobalSettings:
|
||||
m_ui.settingsCategory->setCurrentRow(0);
|
||||
break;
|
||||
|
||||
// TODO: These will need to take multitap into consideration in the future.
|
||||
case Category::FirstControllerSettings:
|
||||
m_ui.settingsCategory->setCurrentRow(1);
|
||||
break;
|
||||
|
||||
case Category::HotkeySettings:
|
||||
m_ui.settingsCategory->setCurrentRow(3);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerSettingsDialog::onCategoryCurrentRowChanged(int row)
|
||||
{
|
||||
m_ui.settingsContainer->setCurrentIndex(row);
|
||||
}
|
||||
|
||||
void ControllerSettingsDialog::onInputDevicesEnumerated(const QList<QPair<QString, QString>>& devices)
|
||||
{
|
||||
for (const QPair<QString, QString>& device : devices)
|
||||
m_global_settings->addDeviceToList(device.first, device.second);
|
||||
}
|
||||
|
||||
void ControllerSettingsDialog::onInputDeviceConnected(const QString& identifier, const QString& device_name)
|
||||
{
|
||||
m_global_settings->addDeviceToList(identifier, device_name);
|
||||
g_emu_thread->enumerateVibrationMotors();
|
||||
}
|
||||
|
||||
void ControllerSettingsDialog::onInputDeviceDisconnected(const QString& identifier)
|
||||
{
|
||||
m_global_settings->removeDeviceFromList(identifier);
|
||||
g_emu_thread->enumerateVibrationMotors();
|
||||
}
|
||||
|
||||
void ControllerSettingsDialog::onVibrationMotorsEnumerated(const QList<InputBindingKey>& motors)
|
||||
{
|
||||
m_vibration_motors.clear();
|
||||
m_vibration_motors.reserve(motors.size());
|
||||
|
||||
for (const InputBindingKey key : motors)
|
||||
{
|
||||
const std::string key_str(InputManager::ConvertInputBindingKeyToString(key));
|
||||
if (!key_str.empty())
|
||||
m_vibration_motors.push_back(QString::fromStdString(key_str));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "ui_ControllerSettingsDialog.h"
|
||||
#include "Frontend/InputManager.h"
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QPair>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtWidgets/QDialog>
|
||||
#include <array>
|
||||
|
||||
class ControllerGlobalSettingsWidget;
|
||||
class ControllerBindingWidget;
|
||||
class HotkeySettingsWidget;
|
||||
|
||||
class ControllerSettingsDialog final : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum class Category
|
||||
{
|
||||
GlobalSettings,
|
||||
FirstControllerSettings,
|
||||
HotkeySettings,
|
||||
Count
|
||||
};
|
||||
|
||||
enum : u32
|
||||
{
|
||||
MAX_PORTS = 2
|
||||
};
|
||||
|
||||
ControllerSettingsDialog(QWidget* parent = nullptr);
|
||||
~ControllerSettingsDialog();
|
||||
|
||||
HotkeySettingsWidget* getHotkeySettingsWidget() const { return m_hotkey_settings; }
|
||||
|
||||
__fi const QStringList& getVibrationMotors() const { return m_vibration_motors; }
|
||||
|
||||
public Q_SLOTS:
|
||||
void setCategory(Category category);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onCategoryCurrentRowChanged(int row);
|
||||
|
||||
void onInputDevicesEnumerated(const QList<QPair<QString, QString>>& devices);
|
||||
void onInputDeviceConnected(const QString& identifier, const QString& device_name);
|
||||
void onInputDeviceDisconnected(const QString& identifier);
|
||||
void onVibrationMotorsEnumerated(const QList<InputBindingKey>& motors);
|
||||
|
||||
private:
|
||||
Ui::ControllerSettingsDialog m_ui;
|
||||
|
||||
ControllerGlobalSettingsWidget* m_global_settings = nullptr;
|
||||
std::array<ControllerBindingWidget*, MAX_PORTS> m_port_bindings{};
|
||||
HotkeySettingsWidget* m_hotkey_settings = nullptr;
|
||||
|
||||
QStringList m_vibration_motors;
|
||||
};
|
|
@ -0,0 +1,122 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ControllerSettingsDialog</class>
|
||||
<widget class="QDialog" name="ControllerSettingsDialog">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::WindowModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1274</width>
|
||||
<height>668</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>PCSX2 Controller Settings</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout" columnstretch="0,0">
|
||||
<item row="0" column="0">
|
||||
<widget class="QListWidget" name="settingsCategory">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>150</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>150</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Global Settings</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="settings-3-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Controller 1</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="gamepad-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Controller 2</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="gamepad-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Hotkeys</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="keyboard-line">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QStackedWidget" name="settingsContainer">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>1100</width>
|
||||
<height>620</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page"/>
|
||||
<widget class="QWidget" name="page_3"/>
|
||||
<widget class="QWidget" name="page_4"/>
|
||||
<widget class="QWidget" name="page_5"/>
|
||||
<widget class="QWidget" name="page_6"/>
|
||||
<widget class="QWidget" name="page_2"/>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../resources/resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,165 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <limits>
|
||||
|
||||
#include "EmulationSettingsWidget.h"
|
||||
#include "QtUtils.h"
|
||||
#include "SettingWidgetBinder.h"
|
||||
#include "SettingsDialog.h"
|
||||
|
||||
static constexpr u32 DEFAULT_FRAME_LATENCY = 2;
|
||||
|
||||
static void FillComboBoxWithEmulationSpeeds(QComboBox* cb)
|
||||
{
|
||||
cb->addItem(qApp->translate("GeneralSettingsWidget", "Unlimited"), QVariant(0.0f));
|
||||
|
||||
static const int speeds[] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 125, 150, 175,
|
||||
200, 250, 300, 350, 400, 450, 500, 600, 700, 800, 900, 1000};
|
||||
for (const int speed : speeds)
|
||||
{
|
||||
cb->addItem(qApp->translate("EmulationSettingsWidget", "%1% [%2 FPS (NTSC) / %3 FPS (PAL)]")
|
||||
.arg(speed)
|
||||
.arg((60 * speed) / 100)
|
||||
.arg((50 * speed) / 100),
|
||||
QVariant(static_cast<float>(speed) / 100.0f));
|
||||
}
|
||||
}
|
||||
|
||||
EmulationSettingsWidget::EmulationSettingsWidget(QWidget* parent, SettingsDialog* dialog)
|
||||
: QWidget(parent)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
|
||||
FillComboBoxWithEmulationSpeeds(m_ui.normalSpeed);
|
||||
if (const int index =
|
||||
m_ui.normalSpeed->findData(QVariant(QtHost::GetBaseFloatSettingValue("Framerate", "NominalScalar", 1.0f)));
|
||||
index >= 0)
|
||||
{
|
||||
m_ui.normalSpeed->setCurrentIndex(index);
|
||||
}
|
||||
connect(m_ui.normalSpeed, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&EmulationSettingsWidget::onNormalSpeedIndexChanged);
|
||||
FillComboBoxWithEmulationSpeeds(m_ui.fastForwardSpeed);
|
||||
|
||||
if (const int index =
|
||||
m_ui.fastForwardSpeed->findData(QVariant(QtHost::GetBaseFloatSettingValue("Framerate", "TurboScalar", 2.0f)));
|
||||
index >= 0)
|
||||
{
|
||||
m_ui.fastForwardSpeed->setCurrentIndex(index);
|
||||
}
|
||||
connect(m_ui.fastForwardSpeed, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&EmulationSettingsWidget::onFastForwardSpeedIndexChanged);
|
||||
|
||||
FillComboBoxWithEmulationSpeeds(m_ui.slowMotionSpeed);
|
||||
if (const int index =
|
||||
m_ui.slowMotionSpeed->findData(QVariant(QtHost::GetBaseFloatSettingValue("Framerate", "SlomoScalar", 0.5f)));
|
||||
index >= 0)
|
||||
{
|
||||
m_ui.slowMotionSpeed->setCurrentIndex(index);
|
||||
}
|
||||
connect(m_ui.slowMotionSpeed, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&EmulationSettingsWidget::onSlowMotionSpeedIndexChanged);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.speedLimiter, "EmuCore/GS", "FrameLimitEnable", true);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(m_ui.maxFrameLatency, "EmuCore/GS", "VsyncQueueSize", DEFAULT_FRAME_LATENCY);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.syncToHostRefreshRate, "EmuCore/GS", "SyncToHostRefreshRate",
|
||||
false);
|
||||
connect(m_ui.optimalFramePacing, &QCheckBox::toggled, this, &EmulationSettingsWidget::onOptimalFramePacingChanged);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.cheats, "EmuCore", "EnableCheats", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.widescreenPatches, "EmuCore", "EnableWideScreenPatches", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.perGameSettings, "EmuCore", "EnablePerGameSettings", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.hostFilesystem, "EmuCore", "HostFs", false);
|
||||
|
||||
dialog->registerWidgetHelp(
|
||||
m_ui.normalSpeed, tr("Normal Speed"), "100%",
|
||||
tr("Sets the target emulation speed. It is not guaranteed that this speed will be reached, "
|
||||
"and if not, the emulator will run as fast as it can manage."));
|
||||
dialog->registerWidgetHelp(
|
||||
m_ui.fastForwardSpeed, tr("Fast Forward Speed"), tr("User Preference"),
|
||||
tr("Sets the fast forward speed. This speed will be used when the fast forward hotkey is pressed/toggled."));
|
||||
dialog->registerWidgetHelp(
|
||||
m_ui.slowMotionSpeed, tr("Slow Motion Speed"), tr("User Preference"),
|
||||
tr("Sets the slow motion speed. This speed will be used when the slow motion hotkey is pressed/toggled."));
|
||||
|
||||
dialog->registerWidgetHelp(
|
||||
m_ui.syncToHostRefreshRate, tr("Sync To Host Refresh Rate"), tr("Unchecked"),
|
||||
tr("Adjusts the emulation speed so the console's refresh rate matches the host's refresh rate when both VSync and "
|
||||
"Audio Resampling settings are enabled. This results in the smoothest animations possible, at the cost of "
|
||||
"potentially increasing the emulation speed by less than 1%. Sync To Host Refresh Rate will not take effect if "
|
||||
"the console's refresh rate is too far from the host's refresh rate. Users with variable refresh rate displays "
|
||||
"should disable this option."));
|
||||
dialog->registerWidgetHelp(m_ui.cheats, tr("Enable Cheats"), tr("Unchecked"),
|
||||
tr("Automatically loads and applies cheats on game start."));
|
||||
dialog->registerWidgetHelp(
|
||||
m_ui.perGameSettings, tr("Enable Per-Game Settings"), tr("Checked"),
|
||||
tr("When enabled, per-game settings will be applied, and incompatible enhancements will be disabled. You should "
|
||||
"leave this option enabled except when testing enhancements with incompatible games."));
|
||||
|
||||
updateOptimalFramePacing();
|
||||
}
|
||||
|
||||
EmulationSettingsWidget::~EmulationSettingsWidget() = default;
|
||||
|
||||
void EmulationSettingsWidget::onNormalSpeedIndexChanged(int index)
|
||||
{
|
||||
bool okay;
|
||||
const float value = m_ui.normalSpeed->currentData().toFloat(&okay);
|
||||
QtHost::SetBaseFloatSettingValue("Framerate", "NominalScalar", okay ? value : 1.0f);
|
||||
g_emu_thread->applySettings();
|
||||
}
|
||||
|
||||
void EmulationSettingsWidget::onFastForwardSpeedIndexChanged(int index)
|
||||
{
|
||||
bool okay;
|
||||
const float value = m_ui.fastForwardSpeed->currentData().toFloat(&okay);
|
||||
QtHost::SetBaseFloatSettingValue("Framerate", "TurboScalar", okay ? value : 1.0f);
|
||||
g_emu_thread->applySettings();
|
||||
}
|
||||
|
||||
void EmulationSettingsWidget::onSlowMotionSpeedIndexChanged(int index)
|
||||
{
|
||||
bool okay;
|
||||
const float value = m_ui.slowMotionSpeed->currentData().toFloat(&okay);
|
||||
QtHost::SetBaseFloatSettingValue("Framerate", "SlomoScalar", okay ? value : 1.0f);
|
||||
g_emu_thread->applySettings();
|
||||
}
|
||||
|
||||
void EmulationSettingsWidget::onOptimalFramePacingChanged(bool checked)
|
||||
{
|
||||
const QSignalBlocker sb(m_ui.maxFrameLatency);
|
||||
m_ui.maxFrameLatency->setValue(DEFAULT_FRAME_LATENCY);
|
||||
m_ui.maxFrameLatency->setEnabled(!checked);
|
||||
|
||||
QtHost::SetBaseIntSettingValue("EmuCore/GS", "VsyncQueueSize", checked ? 0 : DEFAULT_FRAME_LATENCY);
|
||||
g_emu_thread->applySettings();
|
||||
}
|
||||
|
||||
void EmulationSettingsWidget::updateOptimalFramePacing()
|
||||
{
|
||||
const int value = QtHost::GetBaseIntSettingValue("EmuCore/GS", "VsyncQueueSize", DEFAULT_FRAME_LATENCY);
|
||||
const bool optimal = (value == 0);
|
||||
|
||||
const QSignalBlocker sb(m_ui.optimalFramePacing);
|
||||
m_ui.optimalFramePacing->setChecked(optimal);
|
||||
|
||||
const QSignalBlocker sb2(m_ui.maxFrameLatency);
|
||||
m_ui.maxFrameLatency->setEnabled(!optimal);
|
||||
m_ui.maxFrameLatency->setValue(optimal ? DEFAULT_FRAME_LATENCY : value);
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtWidgets/QWidget>
|
||||
|
||||
#include "ui_EmulationSettingsWidget.h"
|
||||
|
||||
class SettingsDialog;
|
||||
|
||||
class EmulationSettingsWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
EmulationSettingsWidget(QWidget* parent, SettingsDialog* dialog);
|
||||
~EmulationSettingsWidget();
|
||||
|
||||
private Q_SLOTS:
|
||||
void onNormalSpeedIndexChanged(int index);
|
||||
void onFastForwardSpeedIndexChanged(int index);
|
||||
void onSlowMotionSpeedIndexChanged(int index);
|
||||
void onOptimalFramePacingChanged(bool checked);
|
||||
|
||||
private:
|
||||
void updateOptimalFramePacing();
|
||||
|
||||
Ui::EmulationSettingsWidget m_ui;
|
||||
};
|
|
@ -0,0 +1,178 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>EmulationSettingsWidget</class>
|
||||
<widget class="QWidget" name="EmulationSettingsWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>672</width>
|
||||
<height>518</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_5">
|
||||
<property name="title">
|
||||
<string>Speed Control</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="fastForwardSpeed"/>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="slowMotionSpeed"/>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="normalSpeed"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Normal Speed:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Slow Motion Speed:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Fast Forward Speed:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="speedLimiter">
|
||||
<property name="text">
|
||||
<string>Enable Speed Limiter</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="basicGroupBox">
|
||||
<property name="title">
|
||||
<string>Frame Pacing/Latency Control</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="maxFrameLatency">
|
||||
<property name="suffix">
|
||||
<string> frames</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>5</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Maximum Frame Latency:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="basicCheckboxGridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="optimalFramePacing">
|
||||
<property name="text">
|
||||
<string>Optimal Frame Pacing</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="syncToHostRefreshRate">
|
||||
<property name="text">
|
||||
<string>Adjust To Host Refresh Rate</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Game Settings</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="perGameSettings">
|
||||
<property name="text">
|
||||
<string>Enable Per-Game Settings</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="cheats">
|
||||
<property name="text">
|
||||
<string>Enable Cheats</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="widescreenPatches">
|
||||
<property name="text">
|
||||
<string>Enable Widescreen Patches</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="hostFilesystem">
|
||||
<property name="text">
|
||||
<string>Enable Host Filesystem</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../resources/resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,50 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <algorithm>
|
||||
|
||||
#include "GameFixSettingsWidget.h"
|
||||
#include "EmuThread.h"
|
||||
#include "QtUtils.h"
|
||||
#include "SettingWidgetBinder.h"
|
||||
#include "SettingsDialog.h"
|
||||
|
||||
GameFixSettingsWidget::GameFixSettingsWidget(QWidget* parent, SettingsDialog* dialog)
|
||||
: QWidget(parent)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.FpuMulHack, "EmuCore/Gamefixes", "FpuMulHack", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.FpuNegDivHack, "EmuCore/Gamefixes", "FpuNegDivHack", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.GoemonTlbHack, "EmuCore/Gamefixes", "GoemonTlbHack", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.SoftwareRendererFMVHack, "EmuCore/Gamefixes", "SoftwareRendererFMVHack", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.SkipMPEGHack, "EmuCore/Gamefixes", "SkipMPEGHack", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.OPHFlagHack, "EmuCore/Gamefixes", "OPHFlagHack", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.EETimingHack, "EmuCore/Gamefixes", "EETimingHack", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.DMABusyHack, "EmuCore/Gamefixes", "DMABusyHack", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.GIFFIFOHack, "EmuCore/Gamefixes", "GIFFIFOHack", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.VIFFIFOHack, "EmuCore/Gamefixes", "VIFFIFOHack", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.VIF1StallHack, "EmuCore/Gamefixes", "VIF1StallHack", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.VuAddSubHack, "EmuCore/Gamefixes", "VuAddSubHack", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.IbitHack, "EmuCore/Gamefixes", "IbitHack", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.VUKickstartHack, "EmuCore/Gamefixes", "VUKickstartHack", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.VUOverflowHack, "EmuCore/Gamefixes", "VUOverflowHack", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.XgKickHack, "EmuCore/Gamefixes", "XgKickHack", false);
|
||||
}
|
||||
|
||||
GameFixSettingsWidget::~GameFixSettingsWidget() = default;
|
|
@ -0,0 +1,34 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtWidgets/QWidget>
|
||||
|
||||
#include "ui_GameFixSettingsWidget.h"
|
||||
|
||||
class SettingsDialog;
|
||||
|
||||
class GameFixSettingsWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GameFixSettingsWidget(QWidget* parent, SettingsDialog* dialog);
|
||||
~GameFixSettingsWidget();
|
||||
|
||||
private:
|
||||
Ui::GameFixSettingsWidget m_ui;
|
||||
};
|
|
@ -0,0 +1,166 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>GameFixSettingsWidget</class>
|
||||
<widget class="QWidget" name="GameFixSettingsWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>648</width>
|
||||
<height>481</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Game Fixes (NOT recommended to change globally)</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="FpuNegDivHack">
|
||||
<property name="text">
|
||||
<string>FPU Negative Divide Hack (For Gundam Games)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="FpuMulHack">
|
||||
<property name="text">
|
||||
<string>FPU Multiply Hack (For Tales of Destiny)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="SoftwareRendererFMVHack">
|
||||
<property name="text">
|
||||
<string>Use Software Renderer For FMVs</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="SkipMPEGHack">
|
||||
<property name="text">
|
||||
<string>Skip MPEG Hack (Skips Videos/FMVs)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="GoemonTlbHack">
|
||||
<property name="text">
|
||||
<string>Preload TLB Hack (For Goemon)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="EETimingHack">
|
||||
<property name="text">
|
||||
<string>EE Timing Hack (General Purpose Timing Hack)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="OPHFlagHack">
|
||||
<property name="text">
|
||||
<string>OPH Flag Hack (For Bleach Blade Battlers)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="GIFFIFOHack">
|
||||
<property name="text">
|
||||
<string>Emulate GIF FIFO (Correct But Slower)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="DMABusyHack">
|
||||
<property name="text">
|
||||
<string>DMA Busy Hack (Deny Writes When Busy)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="VIF1StallHack">
|
||||
<property name="text">
|
||||
<string>Delay VIF1 Stalls (For SOCOM 2 HUD/Spy Hunter)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="VIFFIFOHack">
|
||||
<property name="text">
|
||||
<string>Emulate VIF FIFO (Correct But Slower)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="IbitHack">
|
||||
<property name="text">
|
||||
<string>VU I Bit Hack (For Scarface The World is Yours/Crash Tag Team Racing)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="VuAddSubHack">
|
||||
<property name="text">
|
||||
<string>VU Add Hack (For Tri-Ace Games)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="VUOverflowHack">
|
||||
<property name="text">
|
||||
<string>VU Overflow Hack (Superman Returns)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="VUKickstartHack">
|
||||
<property name="text">
|
||||
<string>VU Kickstart Hack (Run Ahead)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="XgKickHack">
|
||||
<property name="text">
|
||||
<string>VU XGKick Sync (Correct But Slower)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../resources/resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,244 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include <QtCore/QAbstractTableModel>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QSettings>
|
||||
#include <QtCore/QUrl>
|
||||
#include <QtWidgets/QCheckBox>
|
||||
#include <QtWidgets/QFileDialog>
|
||||
#include <QtWidgets/QHeaderView>
|
||||
#include <QtWidgets/QMenu>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <algorithm>
|
||||
|
||||
#include "GameListSettingsWidget.h"
|
||||
#include "MainWindow.h"
|
||||
#include "QtHost.h"
|
||||
#include "QtUtils.h"
|
||||
|
||||
GameListSettingsWidget::GameListSettingsWidget(QWidget* parent, SettingsDialog* dialog)
|
||||
: QWidget(parent)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
|
||||
m_ui.searchDirectoryList->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
m_ui.searchDirectoryList->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
m_ui.searchDirectoryList->setAlternatingRowColors(true);
|
||||
m_ui.searchDirectoryList->setShowGrid(false);
|
||||
m_ui.searchDirectoryList->horizontalHeader()->setHighlightSections(false);
|
||||
m_ui.searchDirectoryList->verticalHeader()->hide();
|
||||
m_ui.searchDirectoryList->setCurrentIndex({});
|
||||
m_ui.searchDirectoryList->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
|
||||
|
||||
connect(m_ui.searchDirectoryList, &QTableWidget::customContextMenuRequested, this,
|
||||
&GameListSettingsWidget::onDirectoryListContextMenuRequested);
|
||||
connect(m_ui.addSearchDirectoryButton, &QPushButton::clicked, this,
|
||||
&GameListSettingsWidget::onAddSearchDirectoryButtonClicked);
|
||||
connect(m_ui.removeSearchDirectoryButton, &QPushButton::clicked, this,
|
||||
&GameListSettingsWidget::onRemoveSearchDirectoryButtonClicked);
|
||||
connect(m_ui.addExcludedPath, &QPushButton::clicked, this, &GameListSettingsWidget::onAddExcludedPathButtonClicked);
|
||||
connect(m_ui.removeExcludedPath, &QPushButton::clicked, this,
|
||||
&GameListSettingsWidget::onRemoveExcludedPathButtonClicked);
|
||||
connect(m_ui.rescanAllGames, &QPushButton::clicked, this, &GameListSettingsWidget::onRescanAllGamesClicked);
|
||||
connect(m_ui.scanForNewGames, &QPushButton::clicked, this, &GameListSettingsWidget::onScanForNewGamesClicked);
|
||||
|
||||
refreshDirectoryList();
|
||||
refreshExclusionList();
|
||||
}
|
||||
|
||||
GameListSettingsWidget::~GameListSettingsWidget() = default;
|
||||
|
||||
bool GameListSettingsWidget::addExcludedPath(const std::string& path)
|
||||
{
|
||||
if (!QtHost::AddBaseValueToStringList("GameList", "ExcludedPaths", path.c_str()))
|
||||
return false;
|
||||
|
||||
m_ui.excludedPaths->addItem(QString::fromStdString(path));
|
||||
g_main_window->refreshGameList(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
void GameListSettingsWidget::refreshExclusionList()
|
||||
{
|
||||
m_ui.excludedPaths->clear();
|
||||
|
||||
const std::vector<std::string> paths(QtHost::GetBaseStringListSetting("GameList", "ExcludedPaths"));
|
||||
for (const std::string& path : paths)
|
||||
m_ui.excludedPaths->addItem(QString::fromStdString(path));
|
||||
}
|
||||
|
||||
void GameListSettingsWidget::resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
QWidget::resizeEvent(event);
|
||||
|
||||
QtUtils::ResizeColumnsForTableView(m_ui.searchDirectoryList, {-1, 100});
|
||||
}
|
||||
|
||||
void GameListSettingsWidget::addPathToTable(const std::string& path, bool recursive)
|
||||
{
|
||||
const int row = m_ui.searchDirectoryList->rowCount();
|
||||
m_ui.searchDirectoryList->insertRow(row);
|
||||
|
||||
QTableWidgetItem* item = new QTableWidgetItem();
|
||||
item->setText(QString::fromStdString(path));
|
||||
m_ui.searchDirectoryList->setItem(row, 0, item);
|
||||
|
||||
QCheckBox* cb = new QCheckBox(m_ui.searchDirectoryList);
|
||||
m_ui.searchDirectoryList->setCellWidget(row, 1, cb);
|
||||
cb->setChecked(recursive);
|
||||
|
||||
connect(cb, &QCheckBox::stateChanged, [this, item](int state) {
|
||||
const std::string path(item->text().toStdString());
|
||||
if (state == Qt::Checked)
|
||||
{
|
||||
QtHost::RemoveBaseValueFromStringList("GameList", "Paths", path.c_str());
|
||||
QtHost::AddBaseValueToStringList("GameList", "RecursivePaths", path.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
QtHost::RemoveBaseValueFromStringList("GameList", "RecursivePaths", path.c_str());
|
||||
QtHost::AddBaseValueToStringList("GameList", "Paths", path.c_str());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void GameListSettingsWidget::refreshDirectoryList()
|
||||
{
|
||||
QSignalBlocker sb(m_ui.searchDirectoryList);
|
||||
while (m_ui.searchDirectoryList->rowCount() > 0)
|
||||
m_ui.searchDirectoryList->removeRow(0);
|
||||
|
||||
std::vector<std::string> path_list = QtHost::GetBaseStringListSetting("GameList", "Paths");
|
||||
for (const std::string& entry : path_list)
|
||||
addPathToTable(entry, false);
|
||||
|
||||
path_list = QtHost::GetBaseStringListSetting("GameList", "RecursivePaths");
|
||||
for (const std::string& entry : path_list)
|
||||
addPathToTable(entry, true);
|
||||
|
||||
m_ui.searchDirectoryList->sortByColumn(0, Qt::AscendingOrder);
|
||||
}
|
||||
|
||||
void GameListSettingsWidget::addSearchDirectory(const QString& path, bool recursive)
|
||||
{
|
||||
const std::string spath(path.toStdString());
|
||||
QtHost::RemoveBaseValueFromStringList("GameList", recursive ? "Paths" : "RecursivePaths", spath.c_str());
|
||||
QtHost::AddBaseValueToStringList("GameList", recursive ? "RecursivePaths" : "Paths", spath.c_str());
|
||||
refreshDirectoryList();
|
||||
g_main_window->refreshGameList(false);
|
||||
}
|
||||
|
||||
void GameListSettingsWidget::removeSearchDirectory(const QString& path)
|
||||
{
|
||||
const std::string spath(path.toStdString());
|
||||
if (!QtHost::RemoveBaseValueFromStringList("GameList", "Paths", spath.c_str()) &&
|
||||
!QtHost::RemoveBaseValueFromStringList("GameList", "RecursivePaths", spath.c_str()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
refreshDirectoryList();
|
||||
g_main_window->refreshGameList(false);
|
||||
}
|
||||
|
||||
void GameListSettingsWidget::onDirectoryListContextMenuRequested(const QPoint& point)
|
||||
{
|
||||
QModelIndexList selection = m_ui.searchDirectoryList->selectionModel()->selectedIndexes();
|
||||
if (selection.size() < 1)
|
||||
return;
|
||||
|
||||
const int row = selection[0].row();
|
||||
|
||||
QMenu menu;
|
||||
menu.addAction(tr("Remove"), [this]() { onRemoveSearchDirectoryButtonClicked(); });
|
||||
menu.addSeparator();
|
||||
menu.addAction(tr("Open Directory..."), [this, row]() {
|
||||
QtUtils::OpenURL(this, QUrl::fromLocalFile(m_ui.searchDirectoryList->item(row, 0)->text()));
|
||||
});
|
||||
menu.exec(m_ui.searchDirectoryList->mapToGlobal(point));
|
||||
}
|
||||
|
||||
void GameListSettingsWidget::addSearchDirectory(QWidget* parent_widget)
|
||||
{
|
||||
QString dir =
|
||||
QDir::toNativeSeparators(QFileDialog::getExistingDirectory(parent_widget, tr("Select Search Directory")));
|
||||
|
||||
if (dir.isEmpty())
|
||||
return;
|
||||
|
||||
QMessageBox::StandardButton selection =
|
||||
QMessageBox::question(this, tr("Scan Recursively?"),
|
||||
tr("Would you like to scan the directory \"%1\" recursively?\n\nScanning recursively takes "
|
||||
"more time, but will identify files in subdirectories.")
|
||||
.arg(dir),
|
||||
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
|
||||
if (selection == QMessageBox::Cancel)
|
||||
return;
|
||||
|
||||
const bool recursive = (selection == QMessageBox::Yes);
|
||||
addSearchDirectory(dir, recursive);
|
||||
}
|
||||
|
||||
void GameListSettingsWidget::onAddSearchDirectoryButtonClicked()
|
||||
{
|
||||
addSearchDirectory(this);
|
||||
}
|
||||
|
||||
void GameListSettingsWidget::onRemoveSearchDirectoryButtonClicked()
|
||||
{
|
||||
const int row = m_ui.searchDirectoryList->currentRow();
|
||||
QTableWidgetItem* item = (row >= 0) ? m_ui.searchDirectoryList->takeItem(row, 0) : nullptr;
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
removeSearchDirectory(item->text());
|
||||
delete item;
|
||||
}
|
||||
|
||||
void GameListSettingsWidget::onAddExcludedPathButtonClicked()
|
||||
{
|
||||
QString path =
|
||||
QDir::toNativeSeparators(QFileDialog::getOpenFileName(QtUtils::GetRootWidget(this), tr("Select Path")));
|
||||
if (path.isEmpty())
|
||||
return;
|
||||
|
||||
addExcludedPath(path.toStdString());
|
||||
}
|
||||
|
||||
void GameListSettingsWidget::onRemoveExcludedPathButtonClicked()
|
||||
{
|
||||
const int row = m_ui.excludedPaths->currentRow();
|
||||
QListWidgetItem* item = (row >= 0) ? m_ui.excludedPaths->takeItem(row) : 0;
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
QtHost::RemoveBaseValueFromStringList("GameList", "ExcludedPaths", item->text().toUtf8().constData());
|
||||
delete item;
|
||||
|
||||
g_main_window->refreshGameList(false);
|
||||
}
|
||||
|
||||
void GameListSettingsWidget::onRescanAllGamesClicked()
|
||||
{
|
||||
g_main_window->refreshGameList(true);
|
||||
}
|
||||
|
||||
void GameListSettingsWidget::onScanForNewGamesClicked()
|
||||
{
|
||||
g_main_window->refreshGameList(false);
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <QtWidgets/QWidget>
|
||||
|
||||
#include "ui_GameListSettingsWidget.h"
|
||||
|
||||
class SettingsDialog;
|
||||
|
||||
class GameListSearchDirectoriesModel;
|
||||
|
||||
class GameListSettingsWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GameListSettingsWidget(QWidget* parent, SettingsDialog* dialog);
|
||||
~GameListSettingsWidget();
|
||||
|
||||
bool addExcludedPath(const std::string& path);
|
||||
void refreshExclusionList();
|
||||
|
||||
public Q_SLOTS:
|
||||
void addSearchDirectory(QWidget* parent_widget);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onDirectoryListContextMenuRequested(const QPoint& point);
|
||||
void onAddSearchDirectoryButtonClicked();
|
||||
void onRemoveSearchDirectoryButtonClicked();
|
||||
void onAddExcludedPathButtonClicked();
|
||||
void onRemoveExcludedPathButtonClicked();
|
||||
void onScanForNewGamesClicked();
|
||||
void onRescanAllGamesClicked();
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent* event);
|
||||
|
||||
private:
|
||||
void addPathToTable(const std::string& path, bool recursive);
|
||||
void refreshDirectoryList();
|
||||
void addSearchDirectory(const QString& path, bool recursive);
|
||||
void removeSearchDirectory(const QString& path);
|
||||
|
||||
Ui::GameListSettingsWidget m_ui;
|
||||
};
|
|
@ -0,0 +1,213 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>GameListSettingsWidget</class>
|
||||
<widget class="QWidget" name="GameListSettingsWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>532</width>
|
||||
<height>376</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,2,0,1,0">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Search Directories (will be scanned for games)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="addSearchDirectoryButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="folder-add-line" />
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="removeSearchDirectoryButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Remove</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="folder-reduce-line" />
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTableWidget" name="searchDirectoryList">
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Search Directory</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Scan Recursively</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Excluded Paths (will not be scanned)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="addExcludedPath">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="file-add-line" />
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="removeExcludedPath">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Remove</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="file-reduce-line" />
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="excludedPaths"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="scanForNewGames">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Scan For New Games</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="file-search-line" />
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="rescanAllGames">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Rescan All Games</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="refresh-line" />
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="resources/resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,381 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "GraphicsSettingsWidget.h"
|
||||
#include "QtUtils.h"
|
||||
#include "SettingWidgetBinder.h"
|
||||
#include "SettingsDialog.h"
|
||||
#include <QtWidgets/QMessageBox>
|
||||
|
||||
#include "pcsx2/GS/GS.h"
|
||||
#include "pcsx2/GS/GSUtil.h"
|
||||
|
||||
#include "Frontend/VulkanHostDisplay.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "Frontend/D3D11HostDisplay.h"
|
||||
#endif
|
||||
|
||||
struct RendererInfo
|
||||
{
|
||||
const char* name;
|
||||
GSRendererType type;
|
||||
};
|
||||
|
||||
static constexpr RendererInfo s_renderer_info[] = {
|
||||
QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "Automatic"),
|
||||
GSRendererType::Auto,
|
||||
#ifdef _WIN32
|
||||
QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "Direct3D 11"),
|
||||
GSRendererType::DX11,
|
||||
#endif
|
||||
QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "OpenGL"),
|
||||
GSRendererType::OGL,
|
||||
QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "Vulkan"),
|
||||
GSRendererType::VK,
|
||||
QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "Software"),
|
||||
GSRendererType::SW,
|
||||
QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "Null"),
|
||||
GSRendererType::Null,
|
||||
};
|
||||
|
||||
static const char* s_anisotropic_filtering_entries[] = {QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "Off (Default)"),
|
||||
QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "2x"),
|
||||
QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "4x"),
|
||||
QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "8x"),
|
||||
QT_TRANSLATE_NOOP("GraphicsSettingsWidget", "16x"),
|
||||
nullptr};
|
||||
static const char* s_anisotropic_filtering_values[] = {"1", "2", "4", "8", "16", nullptr};
|
||||
|
||||
static constexpr int DEFAULT_INTERLACE_MODE = 7;
|
||||
|
||||
GraphicsSettingsWidget::GraphicsSettingsWidget(QWidget* parent, SettingsDialog* dialog)
|
||||
: QWidget(parent)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Global Settings
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SettingWidgetBinder::BindWidgetToStringSetting(m_ui.adapter, "EmuCore/GS", "Adapter");
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(m_ui.vsync, "EmuCore/GS", "VsyncEnable", 0);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.enableHWFixes, "EmuCore/GS", "UserHacks", false);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Game Display Settings
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SettingWidgetBinder::BindWidgetToEnumSetting(m_ui.aspectRatio, "EmuCore/GS", "AspectRatio",
|
||||
Pcsx2Config::GSOptions::AspectRatioNames, AspectRatioType::R4_3);
|
||||
SettingWidgetBinder::BindWidgetToEnumSetting(m_ui.fmvAspectRatio, "EmuCore/GS", "FMVAspectRatioSwitch",
|
||||
Pcsx2Config::GSOptions::FMVAspectRatioSwitchNames,
|
||||
FMVAspectRatioSwitchType::Off);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(m_ui.interlacing, "EmuCore/GS", "interlace", DEFAULT_INTERLACE_MODE);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.bilinearFiltering, "EmuCore/GS", "LinearPresent", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.integerScaling, "EmuCore/GS", "IntegerScaling", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.internalResolutionScreenshots, "EmuCore/GS",
|
||||
"InternalResolutionScreenshots", false);
|
||||
SettingWidgetBinder::BindWidgetToFloatSetting(m_ui.zoom, "EmuCore/GS", "Zoom", 100.0f);
|
||||
SettingWidgetBinder::BindWidgetToFloatSetting(m_ui.stretchY, "EmuCore/GS", "StretchY", 100.0f);
|
||||
SettingWidgetBinder::BindWidgetToFloatSetting(m_ui.offsetX, "EmuCore/GS", "OffsetX", 0.0f);
|
||||
SettingWidgetBinder::BindWidgetToFloatSetting(m_ui.offsetY, "EmuCore/GS", "OffsetY", 0.0f);
|
||||
|
||||
connect(m_ui.integerScaling, &QCheckBox::stateChanged, this, &GraphicsSettingsWidget::onIntegerScalingChanged);
|
||||
onIntegerScalingChanged();
|
||||
|
||||
connect(m_ui.fullscreenModes, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&GraphicsSettingsWidget::onFullscreenModeChanged);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// OSD Settings
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SettingWidgetBinder::BindWidgetToFloatSetting(m_ui.osdScale, "EmuCore/GS", "OsdScale", 100.0f);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.osdShowMessages, "EmuCore/GS", "OsdShowMessages", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.osdShowSpeed, "EmuCore/GS", "OsdShowSpeed", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.osdShowFPS, "EmuCore/GS", "OsdShowFPS", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.osdShowCPU, "EmuCore/GS", "OsdShowCPU", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.osdShowResolution, "EmuCore/GS", "OsdShowResolution", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.osdShowGSStats, "EmuCore/GS", "OsdShowGSStats", false);
|
||||
|
||||
dialog->registerWidgetHelp(m_ui.osdShowMessages, tr("Show OSD Messages"), tr("Checked"),
|
||||
tr("Shows on-screen-display messages when events occur such as save states being "
|
||||
"created/loaded, screenshots being taken, etc."));
|
||||
dialog->registerWidgetHelp(m_ui.osdShowFPS, tr("Show Game Frame Rate"), tr("Unchecked"),
|
||||
tr("Shows the internal frame rate of the game in the top-right corner of the display."));
|
||||
dialog->registerWidgetHelp(
|
||||
m_ui.osdShowSpeed, tr("Show Emulation Speed"), tr("Unchecked"),
|
||||
tr("Shows the current emulation speed of the system in the top-right corner of the display as a percentage."));
|
||||
dialog->registerWidgetHelp(m_ui.osdShowResolution, tr("Show Resolution"), tr("Unchecked"),
|
||||
tr("Shows the resolution of the game in the top-right corner of the display."));
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// HW Settings
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(m_ui.upscaleMultiplier, "EmuCore/GS", "upscale_multiplier", 1);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(m_ui.textureFiltering, "EmuCore/GS", "filter",
|
||||
static_cast<int>(BiFiltering::PS2));
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(m_ui.trilinearFiltering, "EmuCore/GS", "UserHacks_TriFilter",
|
||||
static_cast<int>(TriFiltering::Off));
|
||||
SettingWidgetBinder::BindWidgetToEnumSetting(m_ui.anisotropicFiltering, "EmuCore/GS", "MaxAnisotropy",
|
||||
s_anisotropic_filtering_entries, s_anisotropic_filtering_values, "1");
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(m_ui.dithering, "EmuCore/GS", "dithering_ps2", 2);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(m_ui.mipmapping, "EmuCore/GS", "mipmap_hw",
|
||||
static_cast<int>(HWMipmapLevel::Automatic), -1);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(m_ui.crcFixLevel, "EmuCore/GS", "crc_hack_level",
|
||||
static_cast<int>(CRCHackLevel::Automatic), -1);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(m_ui.blending, "EmuCore/GS", "accurate_blending_unit",
|
||||
static_cast<int>(AccBlendLevel::Basic));
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.accurateDATE, "EmuCore/GS", "accurate_date", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.conservativeBufferAllocation, "EmuCore/GS",
|
||||
"conservative_framebuffer", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.gpuPaletteConversion, "EmuCore/GS", "paltex", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.preloadTexture, "EmuCore/GS", "preload_texture", false);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// HW Renderer Fixes
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(m_ui.halfScreenFix, "EmuCore/GS", "UserHacks_Half_Bottom_Override", -1,
|
||||
-1);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(m_ui.skipDrawRangeStart, "EmuCore/GS", "UserHacks_SkipDraw", 0);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(m_ui.skipDrawRangeCount, "EmuCore/GS", "UserHacks_SkipDraw_Offset", 0);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.hwAutoFlush, "EmuCore/GS", "UserHacks_AutoFlush", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.frameBufferConversion, "EmuCore/GS", "UserHacks_CPU_FB_Conversion",
|
||||
false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.disableDepthEmulation, "EmuCore/GS",
|
||||
"UserHacks_DisableDepthSupport", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.memoryWrapping, "EmuCore/GS", "wrap_gs_mem", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.disableSafeFeatures, "EmuCore/GS",
|
||||
"UserHacks_Disable_Safe_Features", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.preloadFrameData, "EmuCore/GS", "preload_frame_with_gs_data",
|
||||
false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.fastTextureInvalidation, "EmuCore/GS",
|
||||
"UserHacks_DisablePartialInvalidation", false);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// HW Upscaling Fixes
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(m_ui.halfPixelOffset, "EmuCore/GS", "UserHacks_HalfPixelOffset", 0);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(m_ui.roundSprite, "EmuCore/GS", "UserHacks_RoundSprite", 0);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(m_ui.textureOffsetX, "EmuCore/GS", "UserHacks_TCOffsetX", 0);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(m_ui.textureOffsetY, "EmuCore/GS", "UserHacks_TCOffsetY", 0);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.alignSprite, "EmuCore/GS", "UserHacks_align_sprite_X", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.mergeSprite, "EmuCore/GS", "UserHacks_merge_pp_sprite", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.wildHack, "EmuCore/GS", "UserHacks_WildHack", false);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Advanced Settings
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.useBlitSwapChain, "EmuCore/GS", "UseBlitSwapChain", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.useDebugDevice, "EmuCore/GS", "UseDebugDevice", false);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// SW Settings
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(m_ui.extraSWThreads, "EmuCore/GS", "extrathreads", 2);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.swAutoFlush, "EmuCore/GS", "autoflush_sw", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.swAA1, "EmuCore/GS", "aa1", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.swMipmap, "EmuCore/GS", "mipmap", true);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Non-trivial settings
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
const GSRendererType current_renderer = static_cast<GSRendererType>(
|
||||
QtHost::GetBaseIntSettingValue("EmuCore/GS", "Renderer", static_cast<int>(GSRendererType::Auto)));
|
||||
for (const RendererInfo& ri : s_renderer_info)
|
||||
{
|
||||
m_ui.renderer->addItem(qApp->translate("GraphicsSettingsWidget", ri.name));
|
||||
if (ri.type == current_renderer)
|
||||
m_ui.renderer->setCurrentIndex(m_ui.renderer->count() - 1);
|
||||
}
|
||||
connect(m_ui.renderer, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&GraphicsSettingsWidget::onRendererChanged);
|
||||
connect(m_ui.enableHWFixes, &QCheckBox::stateChanged, this, &GraphicsSettingsWidget::onEnableHardwareFixesChanged);
|
||||
updateRendererDependentOptions();
|
||||
|
||||
dialog->registerWidgetHelp(m_ui.useBlitSwapChain, tr("Use Blit Swap Chain"), tr("Unchecked"),
|
||||
tr("Uses a blit presentation model instead of flipping when using the Direct3D 11 "
|
||||
"renderer. This usually results in slower performance, but may be required for some "
|
||||
"streaming applications, or to uncap framerates on some systems."));
|
||||
}
|
||||
|
||||
GraphicsSettingsWidget::~GraphicsSettingsWidget() = default;
|
||||
|
||||
void GraphicsSettingsWidget::onRendererChanged(int index)
|
||||
{
|
||||
QtHost::SetBaseIntSettingValue("EmuCore/GS", "Renderer", static_cast<int>(s_renderer_info[index].type));
|
||||
g_emu_thread->applySettings();
|
||||
updateRendererDependentOptions();
|
||||
}
|
||||
|
||||
void GraphicsSettingsWidget::onAdapterChanged(int index)
|
||||
{
|
||||
if (index == 0)
|
||||
QtHost::RemoveBaseSettingValue("EmuCore/GS", "Adapter");
|
||||
else
|
||||
QtHost::SetBaseStringSettingValue("EmuCore/GS", "Adapter", m_ui.adapter->currentText().toUtf8().constData());
|
||||
g_emu_thread->applySettings();
|
||||
}
|
||||
|
||||
void GraphicsSettingsWidget::onEnableHardwareFixesChanged()
|
||||
{
|
||||
const bool enabled = m_ui.enableHWFixes->isChecked();
|
||||
m_ui.hardwareRendererGroup->setTabEnabled(2, enabled);
|
||||
m_ui.hardwareRendererGroup->setTabEnabled(3, enabled);
|
||||
}
|
||||
|
||||
void GraphicsSettingsWidget::updateRendererDependentOptions()
|
||||
{
|
||||
const int index = m_ui.renderer->currentIndex();
|
||||
GSRendererType type = s_renderer_info[index].type;
|
||||
if (type == GSRendererType::Auto)
|
||||
type = GSUtil::GetPreferredRenderer();
|
||||
|
||||
#ifdef _WIN32
|
||||
const bool is_dx11 = (type == GSRendererType::DX11 || type == GSRendererType::SW);
|
||||
#else
|
||||
const bool is_dx11 = false;
|
||||
#endif
|
||||
|
||||
const bool is_hardware = (type == GSRendererType::DX11 || type == GSRendererType::OGL || type == GSRendererType::VK);
|
||||
const bool is_software = (type == GSRendererType::SW);
|
||||
|
||||
// move advanced tab to the correct parent
|
||||
static constexpr std::array<const char*, 3> move_tab_names = {{"Display", "On-Screen Display", "Advanced"}};
|
||||
const std::array<QWidget*, 3> move_tab_pointers = {{m_ui.gameDisplayTab, m_ui.osdTab, m_ui.advancedTab}};
|
||||
for (size_t i = 0; i < move_tab_pointers.size(); i++)
|
||||
{
|
||||
QWidget* tab = move_tab_pointers[i];
|
||||
const QString tab_label(tr(move_tab_names[i]));
|
||||
if (const int index = m_ui.softwareRendererGroup->indexOf(tab); index >= 0 && is_hardware)
|
||||
m_ui.softwareRendererGroup->removeTab(index);
|
||||
if (const int index = m_ui.hardwareRendererGroup->indexOf(tab); index >= 0 && is_software)
|
||||
m_ui.hardwareRendererGroup->removeTab(index);
|
||||
if (const int index = m_ui.hardwareRendererGroup->indexOf(tab); index < 0 && is_hardware)
|
||||
m_ui.hardwareRendererGroup->insertTab((i == 0) ? 0 : m_ui.hardwareRendererGroup->count(), tab, tab_label);
|
||||
if (const int index = m_ui.softwareRendererGroup->indexOf(tab); index < 0 && is_software)
|
||||
m_ui.softwareRendererGroup->insertTab((i == 0) ? 0 : m_ui.softwareRendererGroup->count(), tab, tab_label);
|
||||
}
|
||||
|
||||
if (is_hardware != is_software)
|
||||
{
|
||||
if (is_hardware)
|
||||
m_ui.hardwareRendererGroup->setCurrentIndex(0);
|
||||
else
|
||||
m_ui.softwareRendererGroup->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
if (m_hardware_renderer_visible != is_hardware)
|
||||
{
|
||||
m_ui.hardwareRendererGroup->setVisible(is_hardware);
|
||||
if (!is_hardware)
|
||||
m_ui.verticalLayout->removeWidget(m_ui.hardwareRendererGroup);
|
||||
else
|
||||
m_ui.verticalLayout->insertWidget(1, m_ui.hardwareRendererGroup);
|
||||
|
||||
m_hardware_renderer_visible = is_hardware;
|
||||
}
|
||||
|
||||
if (m_software_renderer_visible != is_software)
|
||||
{
|
||||
m_ui.softwareRendererGroup->setVisible(is_software);
|
||||
if (!is_hardware)
|
||||
m_ui.verticalLayout->removeWidget(m_ui.softwareRendererGroup);
|
||||
else
|
||||
m_ui.verticalLayout->insertWidget(1, m_ui.softwareRendererGroup);
|
||||
|
||||
m_software_renderer_visible = is_software;
|
||||
}
|
||||
|
||||
m_ui.useBlitSwapChain->setEnabled(is_dx11);
|
||||
|
||||
// populate adapters
|
||||
HostDisplay::AdapterAndModeList modes;
|
||||
switch (type)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
case GSRendererType::DX11:
|
||||
modes = D3D11HostDisplay::StaticGetAdapterAndModeList();
|
||||
break;
|
||||
#endif
|
||||
|
||||
case GSRendererType::VK:
|
||||
modes = VulkanHostDisplay::StaticGetAdapterAndModeList(nullptr);
|
||||
break;
|
||||
|
||||
case GSRendererType::OGL:
|
||||
case GSRendererType::SW:
|
||||
case GSRendererType::Null:
|
||||
case GSRendererType::Auto:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// fill+select adapters
|
||||
{
|
||||
const std::string current_adapter = QtHost::GetBaseStringSettingValue("EmuCore/GS", "Adapter", "");
|
||||
QSignalBlocker sb(m_ui.adapter);
|
||||
m_ui.adapter->clear();
|
||||
m_ui.adapter->setEnabled(!modes.adapter_names.empty());
|
||||
m_ui.adapter->addItem(tr("(Default)"));
|
||||
for (const std::string& adapter : modes.adapter_names)
|
||||
{
|
||||
m_ui.adapter->addItem(QString::fromStdString(adapter));
|
||||
if (current_adapter == adapter)
|
||||
m_ui.adapter->setCurrentIndex(m_ui.adapter->count() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
// fill+select fullscreen modes
|
||||
{
|
||||
QSignalBlocker sb(m_ui.fullscreenModes);
|
||||
|
||||
const std::string current_mode(QtHost::GetBaseStringSettingValue("EmuCore/GS", "FullscreenMode", ""));
|
||||
m_ui.fullscreenModes->clear();
|
||||
m_ui.fullscreenModes->addItem(tr("Borderless Fullscreen"));
|
||||
if (current_mode.empty())
|
||||
m_ui.fullscreenModes->setCurrentIndex(0);
|
||||
|
||||
for (const std::string& fs_mode : modes.fullscreen_modes)
|
||||
{
|
||||
m_ui.fullscreenModes->addItem(QString::fromStdString(fs_mode));
|
||||
if (current_mode == fs_mode)
|
||||
m_ui.fullscreenModes->setCurrentIndex(m_ui.fullscreenModes->count() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
m_ui.enableHWFixes->setEnabled(is_hardware);
|
||||
onEnableHardwareFixesChanged();
|
||||
}
|
||||
|
||||
void GraphicsSettingsWidget::onIntegerScalingChanged()
|
||||
{
|
||||
m_ui.bilinearFiltering->setEnabled(!m_ui.integerScaling->isChecked());
|
||||
}
|
||||
|
||||
void GraphicsSettingsWidget::onFullscreenModeChanged(int index)
|
||||
{
|
||||
if (index == 0)
|
||||
{
|
||||
QtHost::RemoveBaseSettingValue("EmuCore/GS", "FullscreenMode");
|
||||
}
|
||||
else
|
||||
{
|
||||
QtHost::SetBaseStringSettingValue("EmuCore/GS", "FullscreenMode",
|
||||
m_ui.fullscreenModes->currentText().toUtf8().constData());
|
||||
}
|
||||
|
||||
g_emu_thread->applySettings();
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtWidgets/QWidget>
|
||||
|
||||
#include "ui_GraphicsSettingsWidget.h"
|
||||
|
||||
class SettingsDialog;
|
||||
|
||||
class GraphicsSettingsWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GraphicsSettingsWidget(QWidget* parent, SettingsDialog* dialog);
|
||||
~GraphicsSettingsWidget();
|
||||
|
||||
void updateRendererDependentOptions();
|
||||
|
||||
Q_SIGNALS:
|
||||
void fullscreenModesChanged(const QStringList& modes);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onRendererChanged(int index);
|
||||
void onAdapterChanged(int index);
|
||||
void onEnableHardwareFixesChanged();
|
||||
void onIntegerScalingChanged();
|
||||
void onFullscreenModeChanged(int index);
|
||||
|
||||
private:
|
||||
Ui::GraphicsSettingsWidget m_ui;
|
||||
|
||||
bool m_hardware_renderer_visible = true;
|
||||
bool m_software_renderer_visible = true;
|
||||
};
|
|
@ -0,0 +1,997 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>GraphicsSettingsWidget</class>
|
||||
<widget class="QWidget" name="GraphicsSettingsWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>747</width>
|
||||
<height>890</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>Renderer</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Renderer:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="renderer"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Adapter:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="adapter"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="hardwareRendererGroup">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="documentMode">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QGroupBox" name="gameDisplayTab">
|
||||
<attribute name="title">
|
||||
<string>Display</string>
|
||||
</attribute>
|
||||
<layout class="QFormLayout" name="formLayout_7">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_28">
|
||||
<property name="text">
|
||||
<string>Fullscreen Mode:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="fullscreenModes"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_27">
|
||||
<property name="text">
|
||||
<string>Aspect Ratio:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="aspectRatio">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Fit to Window/Screen</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Standard (4:3)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Widescreen (16:9)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_22">
|
||||
<property name="text">
|
||||
<string>FMV Aspect Ratio:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="fmvAspectRatio">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Off (Default)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Standard (4:3)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Widescreen (16:9)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_23">
|
||||
<property name="text">
|
||||
<string>Interlacing:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="interlacing">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Weave (Top Field First, Sawtooth)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Weave (Bottom Field First, Sawtooth)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Bob (Top Field First)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Bob (Bottom Field First)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Blend (Top Field First, Half FPS)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Blend (Bottom Field First, Half FPS)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Automatic (Default)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_21">
|
||||
<property name="text">
|
||||
<string>Zoom:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QSpinBox" name="zoom">
|
||||
<property name="suffix">
|
||||
<string>%</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>300</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_24">
|
||||
<property name="text">
|
||||
<string>Stretch Height:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QSpinBox" name="stretchY">
|
||||
<property name="suffix">
|
||||
<string>%</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>300</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_26">
|
||||
<property name="text">
|
||||
<string>Offset:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3" stretch="1,0,1">
|
||||
<item>
|
||||
<widget class="QSpinBox" name="offsetX">
|
||||
<property name="suffix">
|
||||
<string>px</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_25">
|
||||
<property name="text">
|
||||
<string>x</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="offsetY">
|
||||
<property name="suffix">
|
||||
<string>px</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="7" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="0" column="2">
|
||||
<widget class="QCheckBox" name="integerScaling">
|
||||
<property name="text">
|
||||
<string>Integer Upscaling</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="bilinearFiltering">
|
||||
<property name="text">
|
||||
<string>Bilinear Filtering</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="vsync">
|
||||
<property name="text">
|
||||
<string>Sync To Host Refresh (VSync)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QCheckBox" name="internalResolutionScreenshots">
|
||||
<property name="text">
|
||||
<string>Internal Resolution Screenshots</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="hardwareRenderingTab">
|
||||
<attribute name="title">
|
||||
<string>Rendering</string>
|
||||
</attribute>
|
||||
<layout class="QFormLayout" name="formLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Internal Resolution:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="upscaleMultiplier">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Custom</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Native (PS2)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>2x Native (~720p)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>3x Native (~1080p)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>4x Native (~1440p/2K)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>5x Native (~1620p)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>6x Native (~2160p/4K)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>7x Native (~2520p)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>8x Native (~2280p)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Mipmapping:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="mipmapping">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Automatic (Default)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Off</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Basic (Generated Mipmaps)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Full (PS2 Mipmaps)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="text">
|
||||
<string>Texture Filtering:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="textureFiltering">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Nearest</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Bilinear (Forced)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Bilinear (PS2)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Bilinear (Forced excluding sprite)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>Trilinear Filtering:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="trilinearFiltering">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None (Default)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Trilinear (PS2)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Trilinear (Forced)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Anisotropic Filtering:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="anisotropicFiltering"/>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Dithering:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QComboBox" name="dithering">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Off</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Scaled</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Unscaled (Default)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>CRC Fix Level:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QComboBox" name="crcFixLevel">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Automatic (Default)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None (Debug)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Minimum (Debug)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Partial (OpenGL)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Full (Direct3D)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Aggressive</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Blending Accuracy:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QComboBox" name="blending">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Minimum (Fastest)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Basic (Recommended)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Medium</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>High</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Full (Very Slow)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Ultra (Ultra Slow)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="basicCheckboxGridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="accurateDATE">
|
||||
<property name="text">
|
||||
<string>Accurate Destination Alpha Test</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="conservativeBufferAllocation">
|
||||
<property name="text">
|
||||
<string>Conservative Buffer Allocation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="gpuPaletteConversion">
|
||||
<property name="text">
|
||||
<string>GPU Palette Conversion</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="preloadTexture">
|
||||
<property name="text">
|
||||
<string>Preload Textures</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="enableHWFixes">
|
||||
<property name="text">
|
||||
<string>Enable Hardware Renderer Fixes</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="hardwareFixesTab">
|
||||
<attribute name="title">
|
||||
<string>Hardware Fixes</string>
|
||||
</attribute>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Half Screen Fix:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="halfScreenFix">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Automatic (Default)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Force Disabled</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Force Enabled</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="text">
|
||||
<string>Skipdraw Range:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QSpinBox" name="skipDrawRangeStart"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="skipDrawRangeCount"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="hwAutoFlush">
|
||||
<property name="text">
|
||||
<string>Auto Flush</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="frameBufferConversion">
|
||||
<property name="text">
|
||||
<string>Frame Buffer Conversion</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="disableDepthEmulation">
|
||||
<property name="text">
|
||||
<string>Disable Depth Emulation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="memoryWrapping">
|
||||
<property name="text">
|
||||
<string>Memory Wrapping</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="disableSafeFeatures">
|
||||
<property name="text">
|
||||
<string>Disable Safe Features</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="preloadFrameData">
|
||||
<property name="text">
|
||||
<string>Preload Frame Data</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="fastTextureInvalidation">
|
||||
<property name="text">
|
||||
<string>Fast Texture Invalidation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="upscalingFixesTab">
|
||||
<attribute name="title">
|
||||
<string>Upscaling Fixes</string>
|
||||
</attribute>
|
||||
<layout class="QFormLayout" name="formLayout_5">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="text">
|
||||
<string>Half Pixel Offset:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="halfPixelOffset">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Off (Default)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Normal (Vertex)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Special (Texture)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Special (Texture - Aggressive)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="text">
|
||||
<string>Round Sprite:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="roundSprite">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Off (Default</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Half</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Full</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="text">
|
||||
<string>Texture Offsets:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,1,0,1">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_17">
|
||||
<property name="text">
|
||||
<string>X:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="textureOffsetX"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_18">
|
||||
<property name="text">
|
||||
<string>Y:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="textureOffsetY"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="mergeSprite">
|
||||
<property name="text">
|
||||
<string>Merge Sprite</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="alignSprite">
|
||||
<property name="text">
|
||||
<string>Align Sprite</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="wildHack">
|
||||
<property name="text">
|
||||
<string>Wild Arms Hack</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="osdTab">
|
||||
<attribute name="title">
|
||||
<string>On-Screen Display</string>
|
||||
</attribute>
|
||||
<layout class="QFormLayout" name="formLayout_8">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_29">
|
||||
<property name="text">
|
||||
<string>OSD Scale:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="osdScale">
|
||||
<property name="suffix">
|
||||
<string>%</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>500</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout_6">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="osdShowMessages">
|
||||
<property name="text">
|
||||
<string>Show Notifications</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="osdShowSpeed">
|
||||
<property name="text">
|
||||
<string>Show Speed</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="osdShowFPS">
|
||||
<property name="text">
|
||||
<string>Show FPS</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="osdShowResolution">
|
||||
<property name="text">
|
||||
<string>Show Resolution</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="osdShowCPU">
|
||||
<property name="text">
|
||||
<string>Show CPU Usage</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="osdShowGSStats">
|
||||
<property name="text">
|
||||
<string>Show Statistics</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="advancedTab">
|
||||
<attribute name="title">
|
||||
<string>Advanced</string>
|
||||
</attribute>
|
||||
<layout class="QFormLayout" name="formLayout_6">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="useBlitSwapChain">
|
||||
<property name="text">
|
||||
<string>Use Blit Swap Chain</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="useDebugDevice">
|
||||
<property name="text">
|
||||
<string>Use Debug Device</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="softwareRendererGroup">
|
||||
<property name="documentMode">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QGroupBox" name="softwareRendererSettings">
|
||||
<attribute name="title">
|
||||
<string>Rendering</string>
|
||||
</attribute>
|
||||
<layout class="QFormLayout" name="formLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Extra Rendering Threads:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="extraSWThreads">
|
||||
<property name="suffix">
|
||||
<string> threads</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="swAutoFlush">
|
||||
<property name="text">
|
||||
<string>Auto Flush</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="swMipmap">
|
||||
<property name="text">
|
||||
<string>Mipmapping</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="swAA1">
|
||||
<property name="text">
|
||||
<string>Edge Anti-Aliasing</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,84 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "Frontend/InputManager.h"
|
||||
#include "Settings/HotkeySettingsWidget.h"
|
||||
#include "Settings/ControllerSettingsDialog.h"
|
||||
#include "InputBindingWidget.h"
|
||||
#include "QtUtils.h"
|
||||
#include "SettingWidgetBinder.h"
|
||||
#include <QtWidgets/QGridLayout>
|
||||
#include <QtWidgets/QLabel>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <QtWidgets/QScrollArea>
|
||||
#include <QtWidgets/QTabWidget>
|
||||
|
||||
HotkeySettingsWidget::HotkeySettingsWidget(QWidget* parent, ControllerSettingsDialog* dialog)
|
||||
: QWidget(parent)
|
||||
{
|
||||
createUi();
|
||||
}
|
||||
|
||||
HotkeySettingsWidget::~HotkeySettingsWidget() = default;
|
||||
|
||||
void HotkeySettingsWidget::createUi()
|
||||
{
|
||||
QGridLayout* layout = new QGridLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
m_tab_widget = new QTabWidget(this);
|
||||
|
||||
createButtons();
|
||||
|
||||
layout->addWidget(m_tab_widget, 0, 0, 1, 1);
|
||||
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
void HotkeySettingsWidget::createButtons()
|
||||
{
|
||||
const std::vector<const HotkeyInfo*> hotkeys(InputManager::GetHotkeyList());
|
||||
for (const HotkeyInfo* hotkey : hotkeys)
|
||||
{
|
||||
const auto category = qApp->translate("Hotkeys", hotkey->category);
|
||||
|
||||
auto iter = m_categories.find(category);
|
||||
if (iter == m_categories.end())
|
||||
{
|
||||
QScrollArea* scroll = new QScrollArea(m_tab_widget);
|
||||
QWidget* container = new QWidget(scroll);
|
||||
QVBoxLayout* vlayout = new QVBoxLayout(container);
|
||||
QGridLayout* layout = new QGridLayout();
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
vlayout->addLayout(layout);
|
||||
vlayout->addStretch(1);
|
||||
iter = m_categories.insert(category, Category{container, layout});
|
||||
scroll->setWidget(container);
|
||||
scroll->setWidgetResizable(true);
|
||||
scroll->setBackgroundRole(QPalette::Base);
|
||||
scroll->setFrameShape(QFrame::NoFrame);
|
||||
m_tab_widget->addTab(scroll, category);
|
||||
}
|
||||
|
||||
QWidget* container = iter->container;
|
||||
QGridLayout* layout = iter->layout;
|
||||
const int target_row = layout->count() / 2;
|
||||
|
||||
layout->addWidget(new QLabel(qApp->translate("Hotkeys", hotkey->display_name), container), target_row, 0);
|
||||
layout->addWidget(new InputBindingWidget(container, "Hotkeys", hotkey->name), target_row, 1);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtWidgets/QWidget>
|
||||
#include <QtCore/QMap>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
class QTabWidget;
|
||||
class QGridLayout;
|
||||
|
||||
class ControllerSettingsDialog;
|
||||
|
||||
class HotkeySettingsWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
HotkeySettingsWidget(QWidget* parent, ControllerSettingsDialog* dialog);
|
||||
~HotkeySettingsWidget();
|
||||
|
||||
private:
|
||||
void createUi();
|
||||
void createButtons();
|
||||
|
||||
QTabWidget* m_tab_widget;
|
||||
|
||||
struct Category
|
||||
{
|
||||
QWidget* container;
|
||||
QGridLayout* layout;
|
||||
};
|
||||
QMap<QString, Category> m_categories;
|
||||
};
|
|
@ -0,0 +1,230 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "EmuThread.h"
|
||||
#include "QtHost.h"
|
||||
#include "Settings/InputBindingDialog.h"
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtGui/QKeyEvent>
|
||||
#include <QtGui/QMouseEvent>
|
||||
|
||||
// _BitScanForward()
|
||||
#include "pcsx2/GS/GSIntrin.h"
|
||||
|
||||
InputBindingDialog::InputBindingDialog(std::string section_name, std::string key_name,
|
||||
std::vector<std::string> bindings, QWidget* parent)
|
||||
: QDialog(parent)
|
||||
, m_section_name(std::move(section_name))
|
||||
, m_key_name(std::move(key_name))
|
||||
, m_bindings(std::move(bindings))
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
m_ui.title->setText(
|
||||
tr("Bindings for %1 %2").arg(QString::fromStdString(m_section_name)).arg(QString::fromStdString(m_key_name)));
|
||||
m_ui.buttonBox->button(QDialogButtonBox::Close)->setText(tr("Close"));
|
||||
|
||||
connect(m_ui.addBinding, &QPushButton::clicked, this, &InputBindingDialog::onAddBindingButtonClicked);
|
||||
connect(m_ui.removeBinding, &QPushButton::clicked, this, &InputBindingDialog::onRemoveBindingButtonClicked);
|
||||
connect(m_ui.clearBindings, &QPushButton::clicked, this, &InputBindingDialog::onClearBindingsButtonClicked);
|
||||
connect(m_ui.buttonBox, &QDialogButtonBox::rejected, [this]() { done(0); });
|
||||
updateList();
|
||||
}
|
||||
|
||||
InputBindingDialog::~InputBindingDialog()
|
||||
{
|
||||
Q_ASSERT(!isListeningForInput());
|
||||
}
|
||||
|
||||
bool InputBindingDialog::eventFilter(QObject* watched, QEvent* event)
|
||||
{
|
||||
const QEvent::Type event_type = event->type();
|
||||
|
||||
// if the key is being released, set the input
|
||||
if (event_type == QEvent::KeyRelease || event_type == QEvent::MouseButtonPress)
|
||||
{
|
||||
addNewBinding();
|
||||
stopListeningForInput();
|
||||
return true;
|
||||
}
|
||||
else if (event_type == QEvent::KeyPress)
|
||||
{
|
||||
const QKeyEvent* key_event = static_cast<const QKeyEvent*>(event);
|
||||
m_new_bindings.push_back(InputManager::MakeHostKeyboardKey(key_event->key()));
|
||||
return true;
|
||||
}
|
||||
else if (event_type == QEvent::MouseButtonPress)
|
||||
{
|
||||
unsigned long button_index;
|
||||
if (_BitScanForward(&button_index, static_cast<u32>(static_cast<const QMouseEvent*>(event)->button())))
|
||||
m_new_bindings.push_back(InputManager::MakeHostMouseButtonKey(button_index));
|
||||
return true;
|
||||
}
|
||||
else if (event_type == QEvent::MouseButtonDblClick)
|
||||
{
|
||||
// just eat double clicks
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void InputBindingDialog::onInputListenTimerTimeout()
|
||||
{
|
||||
m_input_listen_remaining_seconds--;
|
||||
if (m_input_listen_remaining_seconds == 0)
|
||||
{
|
||||
stopListeningForInput();
|
||||
return;
|
||||
}
|
||||
|
||||
m_ui.status->setText(tr("Push Button/Axis... [%1]").arg(m_input_listen_remaining_seconds));
|
||||
}
|
||||
|
||||
void InputBindingDialog::startListeningForInput(u32 timeout_in_seconds)
|
||||
{
|
||||
m_input_listen_timer = new QTimer(this);
|
||||
m_input_listen_timer->setSingleShot(false);
|
||||
m_input_listen_timer->start(1000);
|
||||
|
||||
m_input_listen_timer->connect(m_input_listen_timer, &QTimer::timeout, this,
|
||||
&InputBindingDialog::onInputListenTimerTimeout);
|
||||
m_input_listen_remaining_seconds = timeout_in_seconds;
|
||||
m_ui.status->setText(tr("Push Button/Axis... [%1]").arg(m_input_listen_remaining_seconds));
|
||||
m_ui.addBinding->setEnabled(false);
|
||||
m_ui.removeBinding->setEnabled(false);
|
||||
m_ui.clearBindings->setEnabled(false);
|
||||
m_ui.buttonBox->setEnabled(false);
|
||||
|
||||
installEventFilter(this);
|
||||
grabKeyboard();
|
||||
grabMouse();
|
||||
}
|
||||
|
||||
void InputBindingDialog::stopListeningForInput()
|
||||
{
|
||||
m_ui.status->clear();
|
||||
m_ui.addBinding->setEnabled(true);
|
||||
m_ui.removeBinding->setEnabled(true);
|
||||
m_ui.clearBindings->setEnabled(true);
|
||||
m_ui.buttonBox->setEnabled(true);
|
||||
|
||||
delete m_input_listen_timer;
|
||||
m_input_listen_timer = nullptr;
|
||||
|
||||
releaseMouse();
|
||||
releaseKeyboard();
|
||||
removeEventFilter(this);
|
||||
}
|
||||
|
||||
void InputBindingDialog::addNewBinding()
|
||||
{
|
||||
if (m_new_bindings.empty())
|
||||
return;
|
||||
|
||||
const std::string new_binding(
|
||||
InputManager::ConvertInputBindingKeysToString(m_new_bindings.data(), m_new_bindings.size()));
|
||||
if (!new_binding.empty())
|
||||
{
|
||||
if (std::find(m_bindings.begin(), m_bindings.end(), new_binding) != m_bindings.end())
|
||||
return;
|
||||
|
||||
m_ui.bindingList->addItem(QString::fromStdString(new_binding));
|
||||
m_bindings.push_back(std::move(new_binding));
|
||||
saveListToSettings();
|
||||
}
|
||||
}
|
||||
|
||||
void InputBindingDialog::onAddBindingButtonClicked()
|
||||
{
|
||||
if (isListeningForInput())
|
||||
stopListeningForInput();
|
||||
|
||||
startListeningForInput(TIMEOUT_FOR_BINDING);
|
||||
}
|
||||
|
||||
void InputBindingDialog::onRemoveBindingButtonClicked()
|
||||
{
|
||||
const int row = m_ui.bindingList->currentRow();
|
||||
if (row < 0 || static_cast<size_t>(row) >= m_bindings.size())
|
||||
return;
|
||||
|
||||
m_bindings.erase(m_bindings.begin() + row);
|
||||
delete m_ui.bindingList->takeItem(row);
|
||||
saveListToSettings();
|
||||
}
|
||||
|
||||
void InputBindingDialog::onClearBindingsButtonClicked()
|
||||
{
|
||||
m_bindings.clear();
|
||||
m_ui.bindingList->clear();
|
||||
saveListToSettings();
|
||||
}
|
||||
|
||||
void InputBindingDialog::updateList()
|
||||
{
|
||||
m_ui.bindingList->clear();
|
||||
for (const std::string& binding : m_bindings)
|
||||
m_ui.bindingList->addItem(QString::fromStdString(binding));
|
||||
}
|
||||
|
||||
void InputBindingDialog::saveListToSettings()
|
||||
{
|
||||
if (!m_bindings.empty())
|
||||
QtHost::SetBaseStringListSettingValue(m_section_name.c_str(), m_key_name.c_str(), m_bindings);
|
||||
else
|
||||
QtHost::RemoveBaseSettingValue(m_section_name.c_str(), m_key_name.c_str());
|
||||
|
||||
g_emu_thread->reloadInputBindings();
|
||||
}
|
||||
|
||||
void InputBindingDialog::inputManagerHookCallback(InputBindingKey key, float value)
|
||||
{
|
||||
for (InputBindingKey other_key : m_new_bindings)
|
||||
{
|
||||
if (other_key.MaskDirection() == key.MaskDirection())
|
||||
{
|
||||
if (value < 0.25f)
|
||||
{
|
||||
// if this key is in our new binding list, it's a "release", and we're done
|
||||
addNewBinding();
|
||||
stopListeningForInput();
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise, keep waiting
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// new binding, add it to the list, but wait for a decent distance first, and then wait for release
|
||||
if (value >= 0.25f)
|
||||
m_new_bindings.push_back(key);
|
||||
}
|
||||
|
||||
void InputBindingDialog::hookInputManager()
|
||||
{
|
||||
InputManager::SetHook([this](InputBindingKey key, float value) {
|
||||
QMetaObject::invokeMethod(this, "inputManagerHookCallback", Qt::QueuedConnection, Q_ARG(InputBindingKey, key),
|
||||
Q_ARG(float, value));
|
||||
return InputInterceptHook::CallbackResult::StopProcessingEvent;
|
||||
});
|
||||
}
|
||||
|
||||
void InputBindingDialog::unhookInputManager()
|
||||
{
|
||||
InputManager::RemoveHook();
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "ui_InputBindingDialog.h"
|
||||
#include "Frontend/InputManager.h"
|
||||
#include <QtWidgets/QDialog>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class InputBindingDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
InputBindingDialog(std::string section_name, std::string key_name, std::vector<std::string> bindings, QWidget* parent);
|
||||
~InputBindingDialog();
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onAddBindingButtonClicked();
|
||||
void onRemoveBindingButtonClicked();
|
||||
void onClearBindingsButtonClicked();
|
||||
void onInputListenTimerTimeout();
|
||||
void inputManagerHookCallback(InputBindingKey key, float value);
|
||||
|
||||
protected:
|
||||
enum : u32
|
||||
{
|
||||
TIMEOUT_FOR_BINDING = 5
|
||||
};
|
||||
|
||||
virtual bool eventFilter(QObject* watched, QEvent* event) override;
|
||||
|
||||
virtual void startListeningForInput(u32 timeout_in_seconds);
|
||||
virtual void stopListeningForInput();
|
||||
|
||||
bool isListeningForInput() const { return m_input_listen_timer != nullptr; }
|
||||
void addNewBinding();
|
||||
|
||||
void updateList();
|
||||
void saveListToSettings();
|
||||
|
||||
void hookInputManager();
|
||||
void unhookInputManager();
|
||||
|
||||
Ui::InputBindingDialog m_ui;
|
||||
|
||||
std::string m_section_name;
|
||||
std::string m_key_name;
|
||||
std::vector<std::string> m_bindings;
|
||||
std::vector<InputBindingKey> m_new_bindings;
|
||||
|
||||
QTimer* m_input_listen_timer = nullptr;
|
||||
u32 m_input_listen_remaining_seconds = 0;
|
||||
};
|
|
@ -0,0 +1,76 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>InputBindingDialog</class>
|
||||
<widget class="QDialog" name="InputBindingDialog">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::WindowModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>533</width>
|
||||
<height>283</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Edit Bindings</string>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="title">
|
||||
<property name="text">
|
||||
<string>Bindings for Controller0/ButtonCircle</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="bindingList"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="status">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="addBinding">
|
||||
<property name="text">
|
||||
<string>Add Binding</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="removeBinding">
|
||||
<property name="text">
|
||||
<string>Remove Binding</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="clearBindings">
|
||||
<property name="text">
|
||||
<string>Clear Bindings</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,371 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "EmuThread.h"
|
||||
#include "QtHost.h"
|
||||
#include "QtUtils.h"
|
||||
#include "Settings/ControllerSettingsDialog.h"
|
||||
#include "Settings/InputBindingDialog.h"
|
||||
#include "Settings/InputBindingWidget.h"
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtGui/QKeyEvent>
|
||||
#include <QtGui/QMouseEvent>
|
||||
#include <QtWidgets/QInputDialog>
|
||||
#include <cmath>
|
||||
#include <sstream>
|
||||
|
||||
#include "pcsx2/GS/GSIntrin.h" // _BitScanForward
|
||||
|
||||
InputBindingWidget::InputBindingWidget(QWidget* parent)
|
||||
: QPushButton(parent)
|
||||
{
|
||||
connect(this, &QPushButton::clicked, this, &InputBindingWidget::onClicked);
|
||||
}
|
||||
|
||||
InputBindingWidget::InputBindingWidget(QWidget* parent, std::string section_name, std::string key_name)
|
||||
: QPushButton(parent)
|
||||
{
|
||||
setMinimumWidth(225);
|
||||
setMaximumWidth(225);
|
||||
|
||||
connect(this, &QPushButton::clicked, this, &InputBindingWidget::onClicked);
|
||||
|
||||
setKey(std::move(section_name), std::move(key_name));
|
||||
}
|
||||
|
||||
InputBindingWidget::~InputBindingWidget()
|
||||
{
|
||||
Q_ASSERT(!isListeningForInput());
|
||||
}
|
||||
|
||||
void InputBindingWidget::setKey(std::string section_name, std::string key_name)
|
||||
{
|
||||
m_section_name = std::move(section_name);
|
||||
m_key_name = std::move(key_name);
|
||||
m_bindings = QtHost::GetBaseStringListSetting(m_section_name.c_str(), m_key_name.c_str());
|
||||
updateText();
|
||||
}
|
||||
|
||||
void InputBindingWidget::updateText()
|
||||
{
|
||||
if (m_bindings.empty())
|
||||
{
|
||||
setText(QString());
|
||||
}
|
||||
else if (m_bindings.size() > 1)
|
||||
{
|
||||
setText(tr("%n bindings", "", static_cast<int>(m_bindings.size())));
|
||||
|
||||
// keep the full thing for the tooltip
|
||||
std::stringstream ss;
|
||||
bool first = true;
|
||||
for (const std::string& binding : m_bindings)
|
||||
{
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
ss << "\n";
|
||||
ss << binding;
|
||||
}
|
||||
setToolTip(QString::fromStdString(ss.str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
QString binding_text(QString::fromStdString(m_bindings[0]));
|
||||
setToolTip(binding_text);
|
||||
|
||||
// fix up accelerators, and if it's too long, ellipsise it
|
||||
if (binding_text.contains('&'))
|
||||
binding_text = binding_text.replace(QStringLiteral("&"), QStringLiteral("&&"));
|
||||
if (binding_text.length() > 35)
|
||||
binding_text = binding_text.left(35).append(QStringLiteral("..."));
|
||||
setText(binding_text);
|
||||
}
|
||||
}
|
||||
|
||||
bool InputBindingWidget::eventFilter(QObject* watched, QEvent* event)
|
||||
{
|
||||
const QEvent::Type event_type = event->type();
|
||||
|
||||
// if the key is being released, set the input
|
||||
if (event_type == QEvent::KeyRelease || event_type == QEvent::MouseButtonPress)
|
||||
{
|
||||
setNewBinding();
|
||||
stopListeningForInput();
|
||||
return true;
|
||||
}
|
||||
else if (event_type == QEvent::KeyPress)
|
||||
{
|
||||
const QKeyEvent* key_event = static_cast<const QKeyEvent*>(event);
|
||||
m_new_bindings.push_back(InputManager::MakeHostKeyboardKey(key_event->key()));
|
||||
return true;
|
||||
}
|
||||
else if (event_type == QEvent::MouseButtonPress)
|
||||
{
|
||||
unsigned long button_index;
|
||||
if (_BitScanForward(&button_index, static_cast<u32>(static_cast<const QMouseEvent*>(event)->button())))
|
||||
m_new_bindings.push_back(InputManager::MakeHostMouseButtonKey(button_index));
|
||||
return true;
|
||||
}
|
||||
else if (event_type == QEvent::MouseButtonDblClick)
|
||||
{
|
||||
// just eat double clicks
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InputBindingWidget::event(QEvent* event)
|
||||
{
|
||||
if (event->type() == QEvent::MouseButtonRelease)
|
||||
{
|
||||
QMouseEvent* mev = static_cast<QMouseEvent*>(event);
|
||||
if (mev->button() == Qt::LeftButton && mev->modifiers() & Qt::ShiftModifier)
|
||||
{
|
||||
openDialog();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return QPushButton::event(event);
|
||||
}
|
||||
|
||||
void InputBindingWidget::mouseReleaseEvent(QMouseEvent* e)
|
||||
{
|
||||
if (e->button() == Qt::RightButton)
|
||||
{
|
||||
clearBinding();
|
||||
return;
|
||||
}
|
||||
|
||||
QPushButton::mouseReleaseEvent(e);
|
||||
}
|
||||
|
||||
void InputBindingWidget::setNewBinding()
|
||||
{
|
||||
if (m_new_bindings.empty())
|
||||
return;
|
||||
|
||||
const std::string new_binding(
|
||||
InputManager::ConvertInputBindingKeysToString(m_new_bindings.data(), m_new_bindings.size()));
|
||||
if (!new_binding.empty())
|
||||
{
|
||||
QtHost::SetBaseStringSettingValue(m_section_name.c_str(), m_key_name.c_str(), new_binding.c_str());
|
||||
g_emu_thread->reloadInputBindings();
|
||||
}
|
||||
|
||||
m_bindings.clear();
|
||||
m_bindings.push_back(std::move(new_binding));
|
||||
}
|
||||
|
||||
void InputBindingWidget::clearBinding()
|
||||
{
|
||||
m_bindings.clear();
|
||||
QtHost::RemoveBaseSettingValue(m_section_name.c_str(), m_key_name.c_str());
|
||||
g_emu_thread->reloadInputBindings();
|
||||
updateText();
|
||||
}
|
||||
|
||||
void InputBindingWidget::reloadBinding()
|
||||
{
|
||||
m_bindings = QtHost::GetBaseStringListSetting(m_section_name.c_str(), m_key_name.c_str());
|
||||
updateText();
|
||||
}
|
||||
|
||||
void InputBindingWidget::onClicked()
|
||||
{
|
||||
if (m_bindings.size() > 1)
|
||||
{
|
||||
openDialog();
|
||||
return;
|
||||
}
|
||||
|
||||
if (isListeningForInput())
|
||||
stopListeningForInput();
|
||||
|
||||
startListeningForInput(TIMEOUT_FOR_SINGLE_BINDING);
|
||||
}
|
||||
|
||||
void InputBindingWidget::onInputListenTimerTimeout()
|
||||
{
|
||||
m_input_listen_remaining_seconds--;
|
||||
if (m_input_listen_remaining_seconds == 0)
|
||||
{
|
||||
stopListeningForInput();
|
||||
return;
|
||||
}
|
||||
|
||||
setText(tr("Push Button/Axis... [%1]").arg(m_input_listen_remaining_seconds));
|
||||
}
|
||||
|
||||
void InputBindingWidget::startListeningForInput(u32 timeout_in_seconds)
|
||||
{
|
||||
m_new_bindings.clear();
|
||||
m_input_listen_timer = new QTimer(this);
|
||||
m_input_listen_timer->setSingleShot(false);
|
||||
m_input_listen_timer->start(1000);
|
||||
|
||||
m_input_listen_timer->connect(m_input_listen_timer, &QTimer::timeout, this,
|
||||
&InputBindingWidget::onInputListenTimerTimeout);
|
||||
m_input_listen_remaining_seconds = timeout_in_seconds;
|
||||
setText(tr("Push Button/Axis... [%1]").arg(m_input_listen_remaining_seconds));
|
||||
|
||||
installEventFilter(this);
|
||||
grabKeyboard();
|
||||
grabMouse();
|
||||
hookInputManager();
|
||||
}
|
||||
|
||||
void InputBindingWidget::stopListeningForInput()
|
||||
{
|
||||
updateText();
|
||||
delete m_input_listen_timer;
|
||||
m_input_listen_timer = nullptr;
|
||||
std::vector<InputBindingKey>().swap(m_new_bindings);
|
||||
|
||||
unhookInputManager();
|
||||
releaseMouse();
|
||||
releaseKeyboard();
|
||||
removeEventFilter(this);
|
||||
}
|
||||
|
||||
void InputBindingWidget::inputManagerHookCallback(InputBindingKey key, float value)
|
||||
{
|
||||
const float abs_value = std::abs(value);
|
||||
|
||||
for (InputBindingKey other_key : m_new_bindings)
|
||||
{
|
||||
if (other_key.MaskDirection() == key.MaskDirection())
|
||||
{
|
||||
if (abs_value < 0.5f)
|
||||
{
|
||||
// if this key is in our new binding list, it's a "release", and we're done
|
||||
setNewBinding();
|
||||
stopListeningForInput();
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise, keep waiting
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// new binding, add it to the list, but wait for a decent distance first, and then wait for release
|
||||
if (abs_value >= 0.5f)
|
||||
{
|
||||
InputBindingKey key_to_add = key;
|
||||
key_to_add.negative = (value < 0.0f);
|
||||
m_new_bindings.push_back(key_to_add);
|
||||
}
|
||||
}
|
||||
|
||||
void InputBindingWidget::hookInputManager()
|
||||
{
|
||||
InputManager::SetHook([this](InputBindingKey key, float value) {
|
||||
QMetaObject::invokeMethod(this, "inputManagerHookCallback", Qt::QueuedConnection, Q_ARG(InputBindingKey, key),
|
||||
Q_ARG(float, value));
|
||||
return InputInterceptHook::CallbackResult::StopProcessingEvent;
|
||||
});
|
||||
}
|
||||
|
||||
void InputBindingWidget::unhookInputManager()
|
||||
{
|
||||
InputManager::RemoveHook();
|
||||
}
|
||||
|
||||
void InputBindingWidget::openDialog()
|
||||
{
|
||||
InputBindingDialog binding_dialog(m_section_name, m_key_name, m_bindings, QtUtils::GetRootWidget(this));
|
||||
binding_dialog.exec();
|
||||
reloadBinding();
|
||||
}
|
||||
|
||||
InputVibrationBindingWidget::InputVibrationBindingWidget(QWidget* parent)
|
||||
{
|
||||
connect(this, &QPushButton::clicked, this, &InputVibrationBindingWidget::onClicked);
|
||||
}
|
||||
|
||||
InputVibrationBindingWidget::InputVibrationBindingWidget(QWidget* parent, ControllerSettingsDialog* dialog, std::string section_name, std::string key_name)
|
||||
{
|
||||
setMinimumWidth(225);
|
||||
setMaximumWidth(225);
|
||||
|
||||
connect(this, &QPushButton::clicked, this, &InputVibrationBindingWidget::onClicked);
|
||||
|
||||
setKey(dialog, std::move(section_name), std::move(key_name));
|
||||
}
|
||||
|
||||
InputVibrationBindingWidget::~InputVibrationBindingWidget()
|
||||
{
|
||||
}
|
||||
|
||||
void InputVibrationBindingWidget::setKey(ControllerSettingsDialog* dialog, std::string section_name, std::string key_name)
|
||||
{
|
||||
m_dialog = dialog;
|
||||
m_section_name = std::move(section_name);
|
||||
m_key_name = std::move(key_name);
|
||||
m_binding = QtHost::GetBaseStringSettingValue(m_section_name.c_str(), m_key_name.c_str());
|
||||
setText(QString::fromStdString(m_binding));
|
||||
}
|
||||
|
||||
void InputVibrationBindingWidget::clearBinding()
|
||||
{
|
||||
m_binding = {};
|
||||
QtHost::RemoveBaseSettingValue(m_section_name.c_str(), m_key_name.c_str());
|
||||
g_emu_thread->reloadInputBindings();
|
||||
setText(QString());
|
||||
}
|
||||
|
||||
void InputVibrationBindingWidget::onClicked()
|
||||
{
|
||||
QInputDialog dialog(QtUtils::GetRootWidget(this));
|
||||
|
||||
const QString full_key(QStringLiteral("%1/%2").arg(QString::fromStdString(m_section_name)).arg(QString::fromStdString(m_key_name)));
|
||||
const QString current(QString::fromStdString(m_binding));
|
||||
QStringList input_options(m_dialog->getVibrationMotors());
|
||||
if (!current.isEmpty() && input_options.indexOf(current) < 0)
|
||||
input_options.append(current);
|
||||
|
||||
QInputDialog input_dialog(this);
|
||||
input_dialog.setWindowTitle(full_key);
|
||||
input_dialog.setLabelText(tr("Select vibration motor for %1.").arg(full_key));
|
||||
input_dialog.setInputMode(QInputDialog::TextInput);
|
||||
input_dialog.setOptions(QInputDialog::UseListViewForComboBoxItems);
|
||||
input_dialog.setComboBoxEditable(false);
|
||||
input_dialog.setComboBoxItems(std::move(input_options));
|
||||
input_dialog.setTextValue(current);
|
||||
if (input_dialog.exec() == 0)
|
||||
return;
|
||||
|
||||
const QString new_value(input_dialog.textValue());
|
||||
m_binding = new_value.toStdString();
|
||||
QtHost::SetBaseStringSettingValue(m_section_name.c_str(), m_key_name.c_str(), m_binding.c_str());
|
||||
setText(new_value);
|
||||
}
|
||||
|
||||
void InputVibrationBindingWidget::mouseReleaseEvent(QMouseEvent* e)
|
||||
{
|
||||
if (e->button() == Qt::RightButton)
|
||||
{
|
||||
clearBinding();
|
||||
return;
|
||||
}
|
||||
|
||||
QPushButton::mouseReleaseEvent(e);
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "common/Pcsx2Defs.h"
|
||||
#include "pcsx2/Frontend/InputManager.h"
|
||||
#include <QtWidgets/QPushButton>
|
||||
#include <optional>
|
||||
|
||||
class QTimer;
|
||||
|
||||
class ControllerSettingsDialog;
|
||||
|
||||
class InputBindingWidget : public QPushButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
InputBindingWidget(QWidget* parent);
|
||||
InputBindingWidget(QWidget* parent, std::string section_name, std::string key_name);
|
||||
~InputBindingWidget();
|
||||
|
||||
void setKey(std::string section_name, std::string key_name);
|
||||
|
||||
public Q_SLOTS:
|
||||
void clearBinding();
|
||||
void reloadBinding();
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onClicked();
|
||||
void onInputListenTimerTimeout();
|
||||
void inputManagerHookCallback(InputBindingKey key, float value);
|
||||
|
||||
protected:
|
||||
enum : u32
|
||||
{
|
||||
TIMEOUT_FOR_SINGLE_BINDING = 5,
|
||||
TIMEOUT_FOR_ALL_BINDING = 10
|
||||
};
|
||||
|
||||
virtual bool eventFilter(QObject* watched, QEvent* event) override;
|
||||
virtual bool event(QEvent* event) override;
|
||||
virtual void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
virtual void startListeningForInput(u32 timeout_in_seconds);
|
||||
virtual void stopListeningForInput();
|
||||
virtual void openDialog();
|
||||
|
||||
bool isListeningForInput() const { return m_input_listen_timer != nullptr; }
|
||||
void setNewBinding();
|
||||
void updateText();
|
||||
|
||||
void hookInputManager();
|
||||
void unhookInputManager();
|
||||
|
||||
std::string m_section_name;
|
||||
std::string m_key_name;
|
||||
std::vector<std::string> m_bindings;
|
||||
std::vector<InputBindingKey> m_new_bindings;
|
||||
QTimer* m_input_listen_timer = nullptr;
|
||||
u32 m_input_listen_remaining_seconds = 0;
|
||||
};
|
||||
|
||||
class InputVibrationBindingWidget : public QPushButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
InputVibrationBindingWidget(QWidget* parent);
|
||||
InputVibrationBindingWidget(QWidget* parent, ControllerSettingsDialog* dialog, std::string section_name, std::string key_name);
|
||||
~InputVibrationBindingWidget();
|
||||
|
||||
void setKey(ControllerSettingsDialog* dialog, std::string section_name, std::string key_name);
|
||||
|
||||
public Q_SLOTS:
|
||||
void clearBinding();
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onClicked();
|
||||
|
||||
protected:
|
||||
virtual void mouseReleaseEvent(QMouseEvent* e) override;
|
||||
|
||||
private:
|
||||
std::string m_section_name;
|
||||
std::string m_key_name;
|
||||
std::string m_binding;
|
||||
|
||||
ControllerSettingsDialog* m_dialog;
|
||||
};
|
|
@ -0,0 +1,101 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "InterfaceSettingsWidget.h"
|
||||
#include "MainWindow.h"
|
||||
#include "SettingWidgetBinder.h"
|
||||
#include "SettingsDialog.h"
|
||||
|
||||
static const char* THEME_NAMES[] = {QT_TRANSLATE_NOOP("InterfaceSettingsWidget", "Native"),
|
||||
QT_TRANSLATE_NOOP("InterfaceSettingsWidget", "Fusion"),
|
||||
QT_TRANSLATE_NOOP("InterfaceSettingsWidget", "Dark Fusion (Gray)"),
|
||||
QT_TRANSLATE_NOOP("InterfaceSettingsWidget", "Dark Fusion (Blue)"), nullptr};
|
||||
|
||||
static const char* THEME_VALUES[] = {"", "fusion", "darkfusion", "darkfusionblue", nullptr};
|
||||
|
||||
InterfaceSettingsWidget::InterfaceSettingsWidget(QWidget* parent, SettingsDialog* dialog)
|
||||
: QWidget(parent)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.inhibitScreensaver, "UI", "InhibitScreensaver", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.discordPresence, "UI", "DiscordPresence", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.confirmPowerOff, "UI", "ConfirmPowerOff", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.saveStateOnExit, "EmuCore", "AutoStateLoadSave", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.pauseOnStart, "UI", "StartPaused", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.pauseOnFocusLoss, "UI", "PauseOnFocusLoss", false);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.startFullscreen, "UI", "StartFullscreen", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.doubleClickTogglesFullscreen, "UI", "DoubleClickTogglesFullscreen",
|
||||
true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.hideMouseCursor, "UI", "HideMouseCursor", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.renderToMainWindow, "UI", "RenderToMainWindow", true);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToEnumSetting(m_ui.theme, "UI", "Theme", THEME_NAMES, THEME_VALUES,
|
||||
MainWindow::DEFAULT_THEME_NAME);
|
||||
connect(m_ui.theme, QOverload<int>::of(&QComboBox::currentIndexChanged), [this]() { emit themeChanged(); });
|
||||
|
||||
dialog->registerWidgetHelp(
|
||||
m_ui.inhibitScreensaver, tr("Inhibit Screensaver"), tr("Checked"),
|
||||
tr("Prevents the screen saver from activating and the host from sleeping while emulation is running."));
|
||||
|
||||
dialog->registerWidgetHelp(m_ui.discordPresence, tr("Enable Discord Presence"), tr("Unchecked"),
|
||||
tr("Shows the game you are currently playing as part of your profile in Discord."));
|
||||
if (true)
|
||||
{
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.autoUpdateEnabled, "AutoUpdater", "CheckAtStartup", true);
|
||||
dialog->registerWidgetHelp(m_ui.autoUpdateEnabled, tr("Enable Automatic Update Check"), tr("Checked"),
|
||||
tr("Automatically checks for updates to the program on startup. Updates can be deferred "
|
||||
"until later or skipped entirely."));
|
||||
|
||||
// m_ui.autoUpdateTag->addItems(AutoUpdaterDialog::getTagList());
|
||||
// SettingWidgetBinder::BindWidgetToStringSetting(m_ui.autoUpdateTag, "AutoUpdater", "UpdateTag",
|
||||
// AutoUpdaterDialog::getDefaultTag());
|
||||
|
||||
// m_ui.autoUpdateCurrentVersion->setText(tr("%1 (%2)").arg(g_scm_tag_str).arg(g_scm_date_str));
|
||||
// connect(m_ui.checkForUpdates, &QPushButton::clicked, [this]() {
|
||||
// m_host_interface->getMainWindow()->checkForUpdates(true); });
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui.verticalLayout->removeWidget(m_ui.automaticUpdaterGroup);
|
||||
m_ui.automaticUpdaterGroup->hide();
|
||||
}
|
||||
|
||||
dialog->registerWidgetHelp(
|
||||
m_ui.confirmPowerOff, tr("Confirm Power Off"), tr("Checked"),
|
||||
tr("Determines whether a prompt will be displayed to confirm shutting down the emulator/game "
|
||||
"when the hotkey is pressed."));
|
||||
dialog->registerWidgetHelp(m_ui.saveStateOnExit, tr("Save State On Exit"), tr("Checked"),
|
||||
tr("Automatically saves the emulator state when powering down or exiting. You can then "
|
||||
"resume directly from where you left off next time."));
|
||||
dialog->registerWidgetHelp(m_ui.pauseOnStart, tr("Pause On Start"), tr("Unchecked"),
|
||||
tr("Pauses the emulator when a game is started."));
|
||||
dialog->registerWidgetHelp(m_ui.pauseOnFocusLoss, tr("Pause On Focus Loss"), tr("Unchecked"),
|
||||
tr("Pauses the emulator when you minimize the window or switch to another application, "
|
||||
"and unpauses when you switch back."));
|
||||
dialog->registerWidgetHelp(m_ui.startFullscreen, tr("Start Fullscreen"), tr("Unchecked"),
|
||||
tr("Automatically switches to fullscreen mode when a game is started."));
|
||||
dialog->registerWidgetHelp(m_ui.hideMouseCursor, tr("Hide Cursor In Fullscreen"), tr("Checked"),
|
||||
tr("Hides the mouse pointer/cursor when the emulator is in fullscreen mode."));
|
||||
dialog->registerWidgetHelp(
|
||||
m_ui.renderToMainWindow, tr("Render To Main Window"), tr("Checked"),
|
||||
tr("Renders the display of the simulated console to the main window of the application, over "
|
||||
"the game list. If unchecked, the display will render in a separate window."));
|
||||
}
|
||||
|
||||
InterfaceSettingsWidget::~InterfaceSettingsWidget() = default;
|
|
@ -0,0 +1,37 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtWidgets/QWidget>
|
||||
|
||||
#include "ui_InterfaceSettingsWidget.h"
|
||||
|
||||
class SettingsDialog;
|
||||
|
||||
class InterfaceSettingsWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
InterfaceSettingsWidget(QWidget* parent, SettingsDialog* dialog);
|
||||
~InterfaceSettingsWidget();
|
||||
|
||||
Q_SIGNALS:
|
||||
void themeChanged();
|
||||
|
||||
private:
|
||||
Ui::InterfaceSettingsWidget m_ui;
|
||||
};
|
|
@ -0,0 +1,240 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>InterfaceSettingsWidget</class>
|
||||
<widget class="QWidget" name="InterfaceSettingsWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>698</width>
|
||||
<height>740</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_4">
|
||||
<property name="title">
|
||||
<string>Behaviour</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="formLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="inhibitScreensaver">
|
||||
<property name="text">
|
||||
<string>Inhibit Screensaver</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="discordPresence">
|
||||
<property name="text">
|
||||
<string>Enable Discord Presence</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="pauseOnStart">
|
||||
<property name="text">
|
||||
<string>Pause On Start</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="pauseOnFocusLoss">
|
||||
<property name="text">
|
||||
<string>Pause On Focus Loss</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="confirmPowerOff">
|
||||
<property name="text">
|
||||
<string>Confirm Power Off</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QCheckBox" name="saveStateOnExit">
|
||||
<property name="text">
|
||||
<string>Save/Load State On Exit/Resume</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Game Display</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_3">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="startFullscreen">
|
||||
<property name="text">
|
||||
<string>Start Fullscreen</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="hideMouseCursor">
|
||||
<property name="text">
|
||||
<string>Hide Mouse Cursor</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="renderToMainWindow">
|
||||
<property name="text">
|
||||
<string>Render To Main Window</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="doubleClickTogglesFullscreen">
|
||||
<property name="text">
|
||||
<string>Double-Click Toggles Fullscreen</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="disableWindowResizing">
|
||||
<property name="text">
|
||||
<string>Disable Window Resizing</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Preferences</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Language:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="language"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Theme:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="theme"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="automaticUpdaterGroup">
|
||||
<property name="title">
|
||||
<string>Automatic Updater</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Update Channel:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="autoUpdateTag"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Current Version:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="autoUpdateCurrentVersion">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="autoUpdateEnabled">
|
||||
<property name="text">
|
||||
<string>Enable Automatic Update Check</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="checkForUpdates">
|
||||
<property name="text">
|
||||
<string>Check for Updates...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../resources/resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>OSDSettingsWidget</class>
|
||||
<widget class="QWidget" name="OSDSettingsWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>604</width>
|
||||
<height>469</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,1">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_5">
|
||||
<property name="title">
|
||||
<string>On-Screen Display</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>OSD Scale:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="osdScale">
|
||||
<property name="suffix">
|
||||
<string>%</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>500</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="osdShowMessages">
|
||||
<property name="text">
|
||||
<string>Show Notifications</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="osdShowSpeed">
|
||||
<property name="text">
|
||||
<string>Show Speed</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="osdShowFPS">
|
||||
<property name="text">
|
||||
<string>Show FPS</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="osdShowResolution">
|
||||
<property name="text">
|
||||
<string>Show Resolution</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="osdShowCPU">
|
||||
<property name="text">
|
||||
<string>Show CPU Usage</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="osdShowGSStats">
|
||||
<property name="text">
|
||||
<string>Show Statistics</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,156 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "QtHost.h"
|
||||
#include "SettingsDialog.h"
|
||||
|
||||
#include "AdvancedSystemSettingsWidget.h"
|
||||
#include "BIOSSettingsWidget.h"
|
||||
#include "EmulationSettingsWidget.h"
|
||||
#include "GameFixSettingsWidget.h"
|
||||
#include "GameListSettingsWidget.h"
|
||||
#include "GraphicsSettingsWidget.h"
|
||||
#include "HotkeySettingsWidget.h"
|
||||
#include "InterfaceSettingsWidget.h"
|
||||
#include "SystemSettingsWidget.h"
|
||||
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <QtWidgets/QTextEdit>
|
||||
|
||||
static constexpr char DEFAULT_SETTING_HELP_TEXT[] = "";
|
||||
|
||||
SettingsDialog::SettingsDialog(QWidget* parent /* = nullptr */)
|
||||
: QDialog(parent)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
setCategoryHelpTexts();
|
||||
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
|
||||
m_interface_settings = new InterfaceSettingsWidget(m_ui.settingsContainer, this);
|
||||
m_game_list_settings = new GameListSettingsWidget(m_ui.settingsContainer, this);
|
||||
m_bios_settings = new BIOSSettingsWidget(m_ui.settingsContainer, this);
|
||||
m_emulation_settings = new EmulationSettingsWidget(m_ui.settingsContainer, this);
|
||||
m_system_settings = new SystemSettingsWidget(m_ui.settingsContainer, this);
|
||||
m_advanced_system_settings = new AdvancedSystemSettingsWidget(m_ui.settingsContainer, this);
|
||||
m_game_fix_settings_widget = new GameFixSettingsWidget(m_ui.settingsContainer, this);
|
||||
m_graphics_settings = new GraphicsSettingsWidget(m_ui.settingsContainer, this);
|
||||
|
||||
m_ui.settingsContainer->insertWidget(static_cast<int>(Category::InterfaceSettings), m_interface_settings);
|
||||
m_ui.settingsContainer->insertWidget(static_cast<int>(Category::GameListSettings), m_game_list_settings);
|
||||
m_ui.settingsContainer->insertWidget(static_cast<int>(Category::BIOSSettings), m_bios_settings);
|
||||
m_ui.settingsContainer->insertWidget(static_cast<int>(Category::EmulationSettings), m_emulation_settings);
|
||||
m_ui.settingsContainer->insertWidget(static_cast<int>(Category::SystemSettings), m_system_settings);
|
||||
m_ui.settingsContainer->insertWidget(static_cast<int>(Category::AdvancedSystemSettings), m_advanced_system_settings);
|
||||
m_ui.settingsContainer->insertWidget(static_cast<int>(Category::GameFixSettings), m_game_fix_settings_widget);
|
||||
m_ui.settingsContainer->insertWidget(static_cast<int>(Category::GraphicsSettings), m_graphics_settings);
|
||||
|
||||
m_ui.settingsCategory->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
m_ui.settingsCategory->setCurrentRow(0);
|
||||
m_ui.settingsContainer->setCurrentIndex(0);
|
||||
m_ui.helpText->setText(m_category_help_text[0]);
|
||||
connect(m_ui.settingsCategory, &QListWidget::currentRowChanged, this, &SettingsDialog::onCategoryCurrentRowChanged);
|
||||
connect(m_ui.closeButton, &QPushButton::clicked, this, &SettingsDialog::accept);
|
||||
connect(m_ui.restoreDefaultsButton, &QPushButton::clicked, this, &SettingsDialog::onRestoreDefaultsClicked);
|
||||
}
|
||||
|
||||
SettingsDialog::~SettingsDialog() = default;
|
||||
|
||||
void SettingsDialog::setCategoryHelpTexts()
|
||||
{
|
||||
m_category_help_text[static_cast<int>(Category::InterfaceSettings)] =
|
||||
tr("<strong>Interface Settings</strong><hr>These options control how the software looks and behaves.<br><br>Mouse "
|
||||
"over "
|
||||
"an option for additional information.");
|
||||
m_category_help_text[static_cast<int>(Category::SystemSettings)] =
|
||||
tr("<strong>System Settings</strong><hr>These options determine the configuration of the simulated "
|
||||
"console.<br><br>Mouse over an option for additional information.");
|
||||
m_category_help_text[static_cast<int>(Category::GameListSettings)] =
|
||||
tr("<strong>Game List Settings</strong><hr>The list above shows the directories which will be searched by "
|
||||
"PCSX2 to populate the game list. Search directories can be added, removed, and switched to "
|
||||
"recursive/non-recursive.");
|
||||
m_category_help_text[static_cast<int>(Category::AudioSettings)] =
|
||||
tr("<strong>Audio Settings</strong><hr>These options control the audio output of the console. Mouse over an option "
|
||||
"for additional information.");
|
||||
}
|
||||
|
||||
void SettingsDialog::setCategory(Category category)
|
||||
{
|
||||
if (category >= Category::Count)
|
||||
return;
|
||||
|
||||
m_ui.settingsCategory->setCurrentRow(static_cast<int>(category));
|
||||
}
|
||||
|
||||
void SettingsDialog::onCategoryCurrentRowChanged(int row)
|
||||
{
|
||||
Q_ASSERT(row < static_cast<int>(Category::Count));
|
||||
m_ui.settingsContainer->setCurrentIndex(row);
|
||||
m_ui.helpText->setText(m_category_help_text[row]);
|
||||
}
|
||||
|
||||
void SettingsDialog::onRestoreDefaultsClicked()
|
||||
{
|
||||
if (QMessageBox::question(this, tr("Confirm Restore Defaults"),
|
||||
tr("Are you sure you want to restore the default settings? Any preferences will be lost."),
|
||||
QMessageBox::Yes, QMessageBox::No) != QMessageBox::Yes)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
void SettingsDialog::registerWidgetHelp(QObject* object, QString title, QString recommended_value, QString text)
|
||||
{
|
||||
// construct rich text with formatted description
|
||||
QString full_text;
|
||||
full_text += "<table width='100%' cellpadding='0' cellspacing='0'><tr><td><strong>";
|
||||
full_text += title;
|
||||
full_text += "</strong></td><td align='right'><strong>";
|
||||
full_text += tr("Recommended Value");
|
||||
full_text += ": </strong>";
|
||||
full_text += recommended_value;
|
||||
full_text += "</td></table><hr>";
|
||||
full_text += text;
|
||||
|
||||
m_widget_help_text_map[object] = std::move(full_text);
|
||||
object->installEventFilter(this);
|
||||
}
|
||||
|
||||
bool SettingsDialog::eventFilter(QObject* object, QEvent* event)
|
||||
{
|
||||
if (event->type() == QEvent::Enter)
|
||||
{
|
||||
auto iter = m_widget_help_text_map.constFind(object);
|
||||
if (iter != m_widget_help_text_map.end())
|
||||
{
|
||||
m_current_help_widget = object;
|
||||
m_ui.helpText->setText(iter.value());
|
||||
}
|
||||
}
|
||||
else if (event->type() == QEvent::Leave)
|
||||
{
|
||||
if (m_current_help_widget)
|
||||
{
|
||||
m_current_help_widget = nullptr;
|
||||
m_ui.helpText->setText(m_category_help_text[m_ui.settingsCategory->currentRow()]);
|
||||
}
|
||||
}
|
||||
|
||||
return QDialog::eventFilter(object, event);
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "ui_SettingsDialog.h"
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QString>
|
||||
#include <QtWidgets/QDialog>
|
||||
#include <array>
|
||||
|
||||
class InterfaceSettingsWidget;
|
||||
class GameListSettingsWidget;
|
||||
class EmulationSettingsWidget;
|
||||
class BIOSSettingsWidget;
|
||||
class SystemSettingsWidget;
|
||||
class AdvancedSystemSettingsWidget;
|
||||
class GameFixSettingsWidget;
|
||||
class GraphicsSettingsWidget;
|
||||
class AudioSettingsWidget;
|
||||
class MemoryCardSettingsWidget;
|
||||
|
||||
class SettingsDialog final : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum class Category
|
||||
{
|
||||
InterfaceSettings,
|
||||
GameListSettings,
|
||||
BIOSSettings,
|
||||
EmulationSettings,
|
||||
SystemSettings,
|
||||
AdvancedSystemSettings,
|
||||
GameFixSettings,
|
||||
GraphicsSettings,
|
||||
AudioSettings,
|
||||
MemoryCardSettings,
|
||||
Count
|
||||
};
|
||||
|
||||
explicit SettingsDialog(QWidget* parent = nullptr);
|
||||
~SettingsDialog();
|
||||
|
||||
InterfaceSettingsWidget* getInterfaceSettingsWidget() const { return m_interface_settings; }
|
||||
GameListSettingsWidget* getGameListSettingsWidget() const { return m_game_list_settings; }
|
||||
BIOSSettingsWidget* getBIOSSettingsWidget() const { return m_bios_settings; }
|
||||
EmulationSettingsWidget* getEmulationSettingsWidget() const { return m_emulation_settings; }
|
||||
SystemSettingsWidget* getSystemSettingsWidget() const { return m_system_settings; }
|
||||
AdvancedSystemSettingsWidget* getAdvancedSystemSettingsWidget() const { return m_advanced_system_settings; }
|
||||
GameFixSettingsWidget* getGameFixSettingsWidget() const { return m_game_fix_settings_widget; }
|
||||
GraphicsSettingsWidget* getGraphicsSettingsWidget() const { return m_graphics_settings; }
|
||||
AudioSettingsWidget* getAudioSettingsWidget() const { return m_audio_settings; }
|
||||
MemoryCardSettingsWidget* getMemoryCardSettingsWidget() const { return m_memory_card_settings; }
|
||||
|
||||
void registerWidgetHelp(QObject* object, QString title, QString recommended_value, QString text);
|
||||
bool eventFilter(QObject* object, QEvent* event) override;
|
||||
|
||||
Q_SIGNALS:
|
||||
void settingsResetToDefaults();
|
||||
|
||||
public Q_SLOTS:
|
||||
void setCategory(Category category);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onCategoryCurrentRowChanged(int row);
|
||||
void onRestoreDefaultsClicked();
|
||||
|
||||
private:
|
||||
void setCategoryHelpTexts();
|
||||
|
||||
Ui::SettingsDialog m_ui;
|
||||
|
||||
InterfaceSettingsWidget* m_interface_settings = nullptr;
|
||||
GameListSettingsWidget* m_game_list_settings = nullptr;
|
||||
BIOSSettingsWidget* m_bios_settings = nullptr;
|
||||
EmulationSettingsWidget* m_emulation_settings = nullptr;
|
||||
SystemSettingsWidget* m_system_settings = nullptr;
|
||||
AdvancedSystemSettingsWidget* m_advanced_system_settings = nullptr;
|
||||
GameFixSettingsWidget* m_game_fix_settings_widget = nullptr;
|
||||
GraphicsSettingsWidget* m_graphics_settings = nullptr;
|
||||
AudioSettingsWidget* m_audio_settings = nullptr;
|
||||
MemoryCardSettingsWidget* m_memory_card_settings = nullptr;
|
||||
|
||||
std::array<QString, static_cast<int>(Category::Count)> m_category_help_text;
|
||||
|
||||
QObject* m_current_help_widget = nullptr;
|
||||
QMap<QObject*, QString> m_widget_help_text_map;
|
||||
};
|
|
@ -0,0 +1,227 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SettingsDialog</class>
|
||||
<widget class="QDialog" name="SettingsDialog">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::WindowModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>780</width>
|
||||
<height>650</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>PCSX2 Settings</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1">
|
||||
<item row="0" column="0">
|
||||
<widget class="QListWidget" name="settingsCategory">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>150</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>150</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Interface</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="settings-3-line"/>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Game List</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="folder-settings-line"/>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>BIOS</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="hard-drive-2-line"/>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Emulation</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="dashboard-line"/>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>System</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="artboard-2-line"/>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Advanced System</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="artboard-2-line"/>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Game Fixes</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="close-line"/>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Graphics</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="brush-line"/>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Audio</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="volume-up-line"/>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Memory Cards</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="sd-card-line"/>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QStackedWidget" name="settingsContainer">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>500</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page"/>
|
||||
<widget class="QWidget" name="page_2"/>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QTextEdit" name="helpText">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>120</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QComboBox" name="settingsPreset">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Preset: Custom</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Preset: Safe (Default)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Preset: Fast</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="restoreDefaultsButton">
|
||||
<property name="text">
|
||||
<string>Restore Defaults</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="closeButton">
|
||||
<property name="text">
|
||||
<string>Close</string>
|
||||
</property>
|
||||
<property name="default">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../resources/resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,88 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <algorithm>
|
||||
|
||||
#include "EmuThread.h"
|
||||
#include "QtUtils.h"
|
||||
#include "SettingWidgetBinder.h"
|
||||
#include "SettingsDialog.h"
|
||||
#include "SystemSettingsWidget.h"
|
||||
|
||||
static constexpr int MINIMUM_EE_CYCLE_RATE = -3;
|
||||
static constexpr int MAXIMUM_EE_CYCLE_RATE = 3;
|
||||
static constexpr int DEFAULT_EE_CYCLE_RATE = 0;
|
||||
static constexpr int DEFAULT_EE_CYCLE_SKIP = 0;
|
||||
|
||||
SystemSettingsWidget::SystemSettingsWidget(QWidget* parent, SettingsDialog* dialog)
|
||||
: QWidget(parent)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(m_ui.eeRoundingMode, "EmuCore/CPU", "FPU.Roundmode", 3);
|
||||
m_ui.eeClampMode->setCurrentIndex(getClampingModeIndex(false));
|
||||
connect(m_ui.eeClampMode, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
[this](int index) { setClampingMode(false, index); });
|
||||
m_ui.eeCycleRate->setCurrentIndex(
|
||||
std::clamp(QtHost::GetBaseIntSettingValue("EmuCore/Speedhacks", "EECycleRate", DEFAULT_EE_CYCLE_RATE),
|
||||
MINIMUM_EE_CYCLE_RATE, MAXIMUM_EE_CYCLE_RATE) +
|
||||
(0 - MINIMUM_EE_CYCLE_RATE));
|
||||
connect(m_ui.eeCycleRate, QOverload<int>::of(&QComboBox::currentIndexChanged), [](int index) {
|
||||
QtHost::SetBaseIntSettingValue("EmuCore/Speedhacks", "EECycleRate", MINIMUM_EE_CYCLE_RATE + index);
|
||||
g_emu_thread->applySettings();
|
||||
});
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(m_ui.eeCycleSkipping, "EmuCore/Speedhacks", "EECycleSkip", 0);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.MTVU, "EmuCore/Speedhacks", "vuThread", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.instantVU1, "EmuCore/Speedhacks", "vu1Instant", true);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(m_ui.vuRoundingMode, "EmuCore/CPU", "VU.Roundmode", 3);
|
||||
m_ui.vuClampMode->setCurrentIndex(getClampingModeIndex(true));
|
||||
connect(m_ui.vuClampMode, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
[this](int index) { setClampingMode(true, index); });
|
||||
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_ui.fastCDVD, "EmuCore/Speedhacks", "fastCDVD", false);
|
||||
|
||||
updateVU1InstantState();
|
||||
connect(m_ui.MTVU, &QCheckBox::stateChanged, this, &SystemSettingsWidget::updateVU1InstantState);
|
||||
}
|
||||
|
||||
SystemSettingsWidget::~SystemSettingsWidget() = default;
|
||||
|
||||
void SystemSettingsWidget::updateVU1InstantState()
|
||||
{
|
||||
m_ui.instantVU1->setEnabled(!m_ui.MTVU->isChecked());
|
||||
}
|
||||
|
||||
int SystemSettingsWidget::getClampingModeIndex(bool vu)
|
||||
{
|
||||
if (QtHost::GetBaseBoolSettingValue("EmuCore/CPU/Recompiler", vu ? "vuSignOverflow" : "fpuFullMode", false))
|
||||
return 3;
|
||||
if (QtHost::GetBaseBoolSettingValue("EmuCore/CPU/Recompiler", vu ? "vuExtraOverflow" : "fpuExtraOverflow", false))
|
||||
return 2;
|
||||
if (QtHost::GetBaseBoolSettingValue("EmuCore/CPU/Recompiler", vu ? "vuOverflow" : "fpuOverflow", true))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SystemSettingsWidget::setClampingMode(bool vu, int index)
|
||||
{
|
||||
QtHost::SetBaseBoolSettingValue("EmuCore/CPU/Recompiler", vu ? "vuSignOverflow" : "fpuFullMode", (index >= 3));
|
||||
QtHost::SetBaseBoolSettingValue("EmuCore/CPU/Recompiler", vu ? "vuExtraOverflow" : "fpuExtraOverflow", (index >= 2));
|
||||
QtHost::SetBaseBoolSettingValue("EmuCore/CPU/Recompiler", vu ? "vuOverflow" : "fpuOverflow", (index >= 1));
|
||||
g_emu_thread->applySettings();
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtWidgets/QWidget>
|
||||
|
||||
#include "ui_SystemSettingsWidget.h"
|
||||
|
||||
class SettingsDialog;
|
||||
|
||||
class SystemSettingsWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SystemSettingsWidget(QWidget* parent, SettingsDialog* dialog);
|
||||
~SystemSettingsWidget();
|
||||
|
||||
private Q_SLOTS:
|
||||
void updateVU1InstantState();
|
||||
|
||||
private:
|
||||
static int getClampingModeIndex(bool vu);
|
||||
static void setClampingMode(bool vu, int index);
|
||||
|
||||
Ui::SystemSettingsWidget m_ui;
|
||||
};
|
|
@ -0,0 +1,301 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SystemSettingsWidget</class>
|
||||
<widget class="QWidget" name="SystemSettingsWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>648</width>
|
||||
<height>454</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,0,1">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>EmotionEngine (EE, MIPS-IV)</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Cycle Rate:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="eeCycleRate">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>50% Speed</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>60% Speed</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>75% Speed</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>100% (Normal Speed)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>130% Speed</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>180% Speed</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>300% Speed</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Cycle Skip:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="eeCycleSkipping">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Normal</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Mild Underclock</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Moderate Underclock</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Maximum Underclock</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>Rounding Mode:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="eeRoundingMode">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Nearest</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Negative</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Positive</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Chop/Zero (Default)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="text">
|
||||
<string>Clamping Mode:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="eeClampMode">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Normal (Default)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Extra + Preserve Sign</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Full</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Vector Units (VU)</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Rounding Mode:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="vuRoundingMode">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Nearest</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Negative</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Positive</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Chop/Zero (Default)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Clamping Mode:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="vuClampMode">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Normal (Default)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Extra + Preserve Sign</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Full</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="MTVU">
|
||||
<property name="text">
|
||||
<string>MTVU (Multi-Threaded VU1)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="instantVU1">
|
||||
<property name="text">
|
||||
<string>Instant VU1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>I/O Processor (IOP, MIPS-I)</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="fastCDVD">
|
||||
<property name="text">
|
||||
<string>Enable Fast CDVD</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>3</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../resources/resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,292 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(SolutionDir)common\vsprops\BaseProjectConfig.props" />
|
||||
<Import Project="$(SolutionDir)common\vsprops\ProjectConfigAVX2.props" />
|
||||
<Import Project="$(SolutionDir)common\vsprops\WinSDK.props" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{2A016F21-87AE-4154-8271-1F57E91408E9}</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<WholeProgramOptimization Condition="$(Configuration.Contains(Release))">true</WholeProgramOptimization>
|
||||
<UseDebugLibraries Condition="$(Configuration.Contains(Debug))">true</UseDebugLibraries>
|
||||
<UseDebugLibraries Condition="!$(Configuration.Contains(Debug))">false</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings" />
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(SolutionDir)common\vsprops\common.props" />
|
||||
<Import Project="$(SolutionDir)common\vsprops\BaseProperties.props" />
|
||||
<Import Project="$(SolutionDir)common\vsprops\3rdpartyDeps.props" />
|
||||
<Import Project="$(SolutionDir)common\vsprops\pthreads.props" />
|
||||
<Import Project="$(SolutionDir)common\vsprops\QtCompile.props" />
|
||||
<Import Condition="$(Configuration.Contains(Debug))" Project="$(SolutionDir)common\vsprops\CodeGen_Debug.props" />
|
||||
<Import Condition="$(Configuration.Contains(Devel))" Project="$(SolutionDir)common\vsprops\CodeGen_Devel.props" />
|
||||
<Import Condition="$(Configuration.Contains(Release))" Project="$(SolutionDir)common\vsprops\CodeGen_Release.props" />
|
||||
<Import Condition="!$(Configuration.Contains(Release))" Project="$(SolutionDir)common\vsprops\IncrementalLinking.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<TargetName>$(EXEString)</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\xbyak;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\freetype\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\xz\xz\src\liblzma\api;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\baseclasses;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\libpng;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\glad\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\simpleini\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir);$(SolutionDir)pcsx2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<!-- Needed for moc pch -->
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(ProjectDir)\Settings;$(ProjectDir)\GameList</AdditionalIncludeDirectories>
|
||||
<ExceptionHandling>Async</ExceptionHandling>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>PrecompiledHeader.h</PrecompiledHeaderFile>
|
||||
<EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
|
||||
<PreprocessorDefinitions>WIN32_LEAN_AND_MEAN;LZMA_API_STATIC;BUILD_DX=1;SPU2X_PORTAUDIO;DIRECTINPUT_VERSION=0x0800;PCSX2_CORE;DISABLE_RECORDING;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="$(Configuration.Contains(Debug))">PCSX2_DEBUG;PCSX2_DEVBUILD;_SECURE_SCL_=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="$(Configuration.Contains(Devel))">PCSX2_DEVEL;PCSX2_DEVBUILD;NDEBUG;_SECURE_SCL_=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="$(Configuration.Contains(Release))">NDEBUG;_SECURE_SCL_=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(CI)'=='true'">PCSX2_CI;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="!$(Configuration.Contains(AVX2))">_M_SSE=0x401;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="$(Configuration.Contains(AVX2))">_M_SSE=0x501;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<!-- This flag will throw a warning on x64 as SSE2 is implied-->
|
||||
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
|
||||
<EnableEnhancedInstructionSet Condition="'$(Platform)'!='x64'">StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
|
||||
<EnableEnhancedInstructionSet Condition="$(Configuration.Contains(AVX2))">AdvancedVectorExtensions2</EnableEnhancedInstructionSet>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<ObjectFileName>$(IntDir)%(RelativeDir)</ObjectFileName>
|
||||
<!-- SH 2/3 flashlight, explicitly set here don't change -->
|
||||
<!-- https://github.com/PCSX2/pcsx2/commit/16431653e4d92fda4069031897e24fbe4688d36a -->
|
||||
<FloatingPointModel>Precise</FloatingPointModel>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalOptions>/Zc:__cplusplus /Zo /utf-8%(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<LargeAddressAware>Yes</LargeAddressAware>
|
||||
<AdditionalDependencies>comctl32.lib;ws2_32.lib;shlwapi.lib;winmm.lib;rpcrt4.lib;iphlpapi.lib;dsound.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>dxguid.lib;dinput8.lib;hid.lib;PowrProf.lib;d3dcompiler.lib;d3d11.lib;dxgi.lib;strmiids.lib;opengl32.lib;comsuppw.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="$(SolutionDir)3rdparty\wxwidgets3.0\include\wx\msw\wx.rc">
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\wxwidgets3.0\$(PlatformName);$(SolutionDir)3rdparty\wxwidgets3.0\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
<ResourceCompile Include="..\pcsx2\PCSX2.rc" />
|
||||
<ResourceCompile Include="..\pcsx2\GS\GS.rc" />
|
||||
<ResourceCompile Include="..\pcsx2\PAD\Windows\PAD.rc" />
|
||||
<ResourceCompile Include="..\pcsx2\SPU2\Windows\SPU2.rc" />
|
||||
<ResourceCompile Include="..\pcsx2\USB\usb-pad\dx\versionproxy.rc" />
|
||||
<ResourceCompile Include="..\pcsx2\USB\usb-pad\raw\raw-config.rc" />
|
||||
<ResourceCompile Include="..\pcsx2\USB\Win32\USBDialog.rc" />
|
||||
<ResourceCompile Include="..\pcsx2\windows\wxResources.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\baseclasses\baseclasses.vcxproj">
|
||||
<Project>{27f17499-a372-4408-8afa-4f9f4584fbd3}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\fmt\fmt.vcxproj">
|
||||
<Project>{449ad25e-424a-4714-babc-68706cdcc33b}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\libjpeg\libjpeg.vcxproj">
|
||||
<Project>{bc236261-77e8-4567-8d09-45cd02965eb6}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\libpng\projects\vstudio\libpng\libpng.vcxproj">
|
||||
<Project>{d6973076-9317-4ef2-a0b8-b7a18ac0713e}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\libsamplerate\libsamplerate.vcxproj">
|
||||
<Project>{47afdbef-f15f-4bc0-b436-5be443c3f80f}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\pthreads4w\build\pthreads4w.vcxproj">
|
||||
<Project>{0fae817d-9a32-4830-857e-81da57246e16}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\soundtouch\SoundTouch.vcxproj">
|
||||
<Project>{e9b51944-7e6d-4bcd-83f2-7bbd5a46182d}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\wxwidgets3.0\build\msw\wx30_base.vcxproj">
|
||||
<Project>{3fcc50c2-81e9-5db2-b8d8-2129427568b1}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\xz\liblzma.vcxproj">
|
||||
<Project>{12728250-16ec-4dc6-94d7-e21dd88947f8}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\libchdr\libchdr.vcxproj">
|
||||
<Project>{a0d2b3ad-1f72-4ee3-8b5c-f2c358da35f0}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\zlib\zlib.vcxproj">
|
||||
<Project>{2f6c0388-20cb-4242-9f6c-a6ebb6a83f47}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)tools\bin2cpp\bin2c.vcxproj">
|
||||
<Project>{677b7d11-d5e1-40b3-88b1-9a4df83d2213}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\jpgd\jpgd.vcxproj">
|
||||
<Project>{ed2f21fd-0a36-4a8f-9b90-e7d92a2acb63}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\imgui\imgui.vcxproj">
|
||||
<Project>{88fb34ec-845e-4f21-a552-f1573b9ed167}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)common\common.vcxproj">
|
||||
<Project>{4639972e-424e-4e13-8b07-ca403c481346}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)pcsx2\pcsx2core.vcxproj">
|
||||
<Project>{6c7986c4-3e4d-4dcc-b3c6-6bb12b238995}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(SolutionDir)3rdparty\glad\glad.vcxproj">
|
||||
<Project>{c0293b32-5acf-40f0-aa6c-e6da6f3bf33a}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Manifest Include="..\pcsx2\windows\PCSX2.manifest" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Settings\BIOSSettingsWidget.cpp" />
|
||||
<ClCompile Include="Settings\ControllerBindingWidgets.cpp" />
|
||||
<ClCompile Include="Settings\ControllerGlobalSettingsWidget.cpp" />
|
||||
<ClCompile Include="Settings\EmulationSettingsWidget.cpp" />
|
||||
<ClCompile Include="Settings\GameListSettingsWidget.cpp" />
|
||||
<ClCompile Include="Settings\GraphicsSettingsWidget.cpp" />
|
||||
<ClCompile Include="Settings\InterfaceSettingsWidget.cpp" />
|
||||
<ClCompile Include="Settings\SystemSettingsWidget.cpp" />
|
||||
<ClCompile Include="Settings\SettingsDialog.cpp" />
|
||||
<ClCompile Include="Settings\AdvancedSystemSettingsWidget.cpp" />
|
||||
<ClCompile Include="Settings\GameFixSettingsWidget.cpp" />
|
||||
<ClCompile Include="Settings\HotkeySettingsWidget.cpp" />
|
||||
<ClCompile Include="Settings\InputBindingDialog.cpp" />
|
||||
<ClCompile Include="Settings\InputBindingWidget.cpp" />
|
||||
<ClCompile Include="Settings\ControllerSettingsDialog.cpp" />
|
||||
<ClCompile Include="GameList\GameListModel.cpp" />
|
||||
<ClCompile Include="GameList\GameListRefreshThread.cpp" />
|
||||
<ClCompile Include="GameList\GameListWidget.cpp" />
|
||||
<ClCompile Include="AboutDialog.cpp" />
|
||||
<ClCompile Include="DisplayWidget.cpp" />
|
||||
<ClCompile Include="QtHost.cpp" />
|
||||
<ClCompile Include="Main.cpp" />
|
||||
<ClCompile Include="MainWindow.cpp" />
|
||||
<ClCompile Include="PrecompiledHeader.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="EmuThread.cpp" />
|
||||
<ClCompile Include="QtKeyCodes.cpp" />
|
||||
<ClCompile Include="QtUtils.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtMoc Include="Settings\SystemSettingsWidget.h" />
|
||||
<QtMoc Include="Settings\InterfaceSettingsWidget.h" />
|
||||
<QtMoc Include="Settings\GameListSettingsWidget.h" />
|
||||
<QtMoc Include="Settings\BIOSSettingsWidget.h" />
|
||||
<QtMoc Include="Settings\EmulationSettingsWidget.h" />
|
||||
<QtMoc Include="Settings\GraphicsSettingsWidget.h" />
|
||||
<QtMoc Include="Settings\SettingsDialog.h" />
|
||||
<QtMoc Include="Settings\AdvancedSystemSettingsWidget.h" />
|
||||
<QtMoc Include="Settings\GameFixSettingsWidget.h" />
|
||||
<QtMoc Include="Settings\HotkeySettingsWidget.h" />
|
||||
<QtMoc Include="Settings\InputBindingDialog.h" />
|
||||
<QtMoc Include="Settings\InputBindingWidget.h" />
|
||||
<QtMoc Include="Settings\ControllerSettingsDialog.h" />
|
||||
<QtMoc Include="GameList\GameListModel.h" />
|
||||
<QtMoc Include="GameList\GameListWidget.h" />
|
||||
<QtMoc Include="GameList\GameListRefreshThread.h" />
|
||||
<ClInclude Include="QtUtils.h" />
|
||||
<QtMoc Include="Settings\ControllerBindingWidgets.h" />
|
||||
<QtMoc Include="Settings\ControllerGlobalSettingsWidget.h" />
|
||||
<ClInclude Include="SettingWidgetBinder.h" />
|
||||
<ClInclude Include="QtHost.h" />
|
||||
<ClInclude Include="PrecompiledHeader.h" />
|
||||
<QtMoc Include="AboutDialog.h" />
|
||||
<QtMoc Include="EmuThread.h" />
|
||||
<QtMoc Include="MainWindow.h" />
|
||||
<QtMoc Include="DisplayWidget.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtResource Include="resources\resources.qrc">
|
||||
<FileType>Document</FileType>
|
||||
</QtResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="$(IntDir)Settings\moc_BIOSSettingsWidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)Settings\moc_ControllerBindingWidgets.cpp" />
|
||||
<ClCompile Include="x64\Devel\Settings\moc_ControllerGlobalSettingsWidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)Settings\moc_ControllerSettingsDialog.cpp" />
|
||||
<ClCompile Include="$(IntDir)Settings\moc_EmulationSettingsWidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)Settings\moc_GameListSettingsWidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)Settings\moc_GraphicsSettingsWidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)Settings\moc_InterfaceSettingsWidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)Settings\moc_SystemSettingsWidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)Settings\moc_SettingsDialog.cpp" />
|
||||
<ClCompile Include="$(IntDir)Settings\moc_AdvancedSystemSettingsWidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)Settings\moc_GameFixSettingsWidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)Settings\moc_HotkeySettingsWidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)Settings\moc_InputBindingDialog.cpp" />
|
||||
<ClCompile Include="$(IntDir)Settings\moc_InputBindingWidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)GameList\moc_GameListModel.cpp" />
|
||||
<ClCompile Include="$(IntDir)GameList\moc_GameListRefreshThread.cpp" />
|
||||
<ClCompile Include="$(IntDir)GameList\moc_GameListWidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_AboutDialog.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_DisplayWidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_EmuThread.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_MainWindow.cpp" />
|
||||
<ClCompile Include="$(IntDir)qrc_resources.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtUi Include="MainWindow.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\SettingsDialog.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\SystemSettingsWidget.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\GameListSettingsWidget.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\BIOSSettingsWidget.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\EmulationSettingsWidget.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\GraphicsSettingsWidget.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\InterfaceSettingsWidget.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\AdvancedSystemSettingsWidget.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\GameFixSettingsWidget.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\InputBindingDialog.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\ControllerSettingsDialog.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\ControllerBindingWidget_DualShock2.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\ControllerBindingWidget.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\ControllerGlobalSettingsWidget.ui">
|
||||
<FileType>Document</FileType>
|
||||
</QtUi>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<Import Project="$(SolutionDir)common\vsprops\QtCompile.targets" />
|
||||
<ImportGroup Label="ExtensionTargets" />
|
||||
</Project>
|
|
@ -0,0 +1,301 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Resources">
|
||||
<UniqueIdentifier>{1f18feb4-85f0-455d-927a-d4d6b226d8a5}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="moc">
|
||||
<UniqueIdentifier>{1ab68559-2163-40b5-818b-d2a7ff210c12}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Settings">
|
||||
<UniqueIdentifier>{11eec1ee-70c1-42ad-8cd1-e7f72f4c8673}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="GameList">
|
||||
<UniqueIdentifier>{aff229ec-39ea-40d4-b1c9-b5c4a932a2e0}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="$(SolutionDir)3rdparty\wxwidgets3.0\include\wx\msw\wx.rc">
|
||||
<Filter>Resources</Filter>
|
||||
</ResourceCompile>
|
||||
<ResourceCompile Include="..\pcsx2\GS\GS.rc">
|
||||
<Filter>Resources</Filter>
|
||||
</ResourceCompile>
|
||||
<ResourceCompile Include="..\pcsx2\PAD\Windows\PAD.rc">
|
||||
<Filter>Resources</Filter>
|
||||
</ResourceCompile>
|
||||
<ResourceCompile Include="..\pcsx2\PCSX2.rc">
|
||||
<Filter>Resources</Filter>
|
||||
</ResourceCompile>
|
||||
<ResourceCompile Include="..\pcsx2\USB\usb-pad\raw\raw-config.rc">
|
||||
<Filter>Resources</Filter>
|
||||
</ResourceCompile>
|
||||
<ResourceCompile Include="..\pcsx2\SPU2\Windows\SPU2.rc">
|
||||
<Filter>Resources</Filter>
|
||||
</ResourceCompile>
|
||||
<ResourceCompile Include="..\pcsx2\USB\Win32\USBDialog.rc">
|
||||
<Filter>Resources</Filter>
|
||||
</ResourceCompile>
|
||||
<ResourceCompile Include="..\pcsx2\USB\usb-pad\dx\versionproxy.rc">
|
||||
<Filter>Resources</Filter>
|
||||
</ResourceCompile>
|
||||
<ResourceCompile Include="..\pcsx2\windows\wxResources.rc">
|
||||
<Filter>Resources</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="PrecompiledHeader.cpp" />
|
||||
<ClCompile Include="Main.cpp" />
|
||||
<ClCompile Include="QtHost.cpp" />
|
||||
<ClCompile Include="MainWindow.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_MainWindow.cpp">
|
||||
<Filter>moc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(IntDir)qrc_resources.cpp">
|
||||
<Filter>Resources</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DisplayWidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_DisplayWidget.cpp">
|
||||
<Filter>moc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="EmuThread.cpp" />
|
||||
<ClCompile Include="QtUtils.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_EmuThread.cpp">
|
||||
<Filter>moc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="QtKeyCodes.cpp" />
|
||||
<ClCompile Include="Settings\BIOSSettingsWidget.cpp">
|
||||
<Filter>Settings</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Settings\EmulationSettingsWidget.cpp">
|
||||
<Filter>Settings</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Settings\GameListSettingsWidget.cpp">
|
||||
<Filter>Settings</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Settings\GraphicsSettingsWidget.cpp">
|
||||
<Filter>Settings</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Settings\InterfaceSettingsWidget.cpp">
|
||||
<Filter>Settings</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Settings\SettingsDialog.cpp">
|
||||
<Filter>Settings</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Settings\SystemSettingsWidget.cpp">
|
||||
<Filter>Settings</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(IntDir)Settings\moc_BIOSSettingsWidget.cpp">
|
||||
<Filter>moc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(IntDir)Settings\moc_EmulationSettingsWidget.cpp">
|
||||
<Filter>moc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(IntDir)Settings\moc_GameListSettingsWidget.cpp">
|
||||
<Filter>moc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(IntDir)Settings\moc_GraphicsSettingsWidget.cpp">
|
||||
<Filter>moc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(IntDir)Settings\moc_InterfaceSettingsWidget.cpp">
|
||||
<Filter>moc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(IntDir)Settings\moc_SettingsDialog.cpp">
|
||||
<Filter>moc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(IntDir)Settings\moc_SystemSettingsWidget.cpp">
|
||||
<Filter>moc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(IntDir)Settings\moc_AdvancedSystemSettingsWidget.cpp">
|
||||
<Filter>moc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Settings\AdvancedSystemSettingsWidget.cpp">
|
||||
<Filter>Settings</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(IntDir)Settings\moc_GameFixSettingsWidget.cpp">
|
||||
<Filter>moc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Settings\GameFixSettingsWidget.cpp">
|
||||
<Filter>Settings</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(IntDir)Settings\moc_HotkeySettingsWidget.cpp">
|
||||
<Filter>moc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(IntDir)Settings\moc_InputBindingDialog.cpp">
|
||||
<Filter>moc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(IntDir)Settings\moc_InputBindingWidget.cpp">
|
||||
<Filter>moc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Settings\InputBindingWidget.cpp">
|
||||
<Filter>Settings</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Settings\HotkeySettingsWidget.cpp">
|
||||
<Filter>Settings</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Settings\InputBindingDialog.cpp">
|
||||
<Filter>Settings</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="AboutDialog.cpp" />
|
||||
<ClCompile Include="GameList\GameListRefreshThread.cpp">
|
||||
<Filter>GameList</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GameList\GameListWidget.cpp">
|
||||
<Filter>GameList</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GameList\GameListModel.cpp">
|
||||
<Filter>GameList</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(IntDir)moc_AboutDialog.cpp">
|
||||
<Filter>moc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(IntDir)Settings\moc_ControllerSettingsDialog.cpp">
|
||||
<Filter>moc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(IntDir)GameList\moc_GameListModel.cpp">
|
||||
<Filter>moc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(IntDir)GameList\moc_GameListRefreshThread.cpp">
|
||||
<Filter>moc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(IntDir)GameList\moc_GameListWidget.cpp">
|
||||
<Filter>moc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Settings\ControllerSettingsDialog.cpp">
|
||||
<Filter>Settings</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Settings\ControllerBindingWidgets.cpp">
|
||||
<Filter>Settings</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(IntDir)Settings\moc_ControllerBindingWidgets.cpp">
|
||||
<Filter>moc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Settings\ControllerGlobalSettingsWidget.cpp">
|
||||
<Filter>Settings</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="x64\Devel\Settings\moc_ControllerGlobalSettingsWidget.cpp">
|
||||
<Filter>moc</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Manifest Include="..\pcsx2\windows\PCSX2.manifest">
|
||||
<Filter>Resources</Filter>
|
||||
</Manifest>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="PrecompiledHeader.h" />
|
||||
<ClInclude Include="QtHost.h" />
|
||||
<ClInclude Include="QtUtils.h" />
|
||||
<ClInclude Include="SettingWidgetBinder.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtMoc Include="MainWindow.h" />
|
||||
<QtMoc Include="DisplayWidget.h" />
|
||||
<QtMoc Include="EmuThread.h" />
|
||||
<QtMoc Include="Settings\BIOSSettingsWidget.h">
|
||||
<Filter>Settings</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Settings\EmulationSettingsWidget.h">
|
||||
<Filter>Settings</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Settings\GameListSettingsWidget.h">
|
||||
<Filter>Settings</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Settings\GraphicsSettingsWidget.h">
|
||||
<Filter>Settings</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Settings\InterfaceSettingsWidget.h">
|
||||
<Filter>Settings</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Settings\SettingsDialog.h">
|
||||
<Filter>Settings</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Settings\SystemSettingsWidget.h">
|
||||
<Filter>Settings</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Settings\AdvancedSystemSettingsWidget.h">
|
||||
<Filter>Settings</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Settings\GameFixSettingsWidget.h">
|
||||
<Filter>Settings</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Settings\HotkeySettingsWidget.h">
|
||||
<Filter>Settings</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Settings\InputBindingDialog.h">
|
||||
<Filter>Settings</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Settings\InputBindingWidget.h">
|
||||
<Filter>Settings</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="AboutDialog.h" />
|
||||
<QtMoc Include="GameList\GameListWidget.h">
|
||||
<Filter>GameList</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="GameList\GameListModel.h">
|
||||
<Filter>GameList</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="GameList\GameListRefreshThread.h">
|
||||
<Filter>GameList</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Settings\ControllerSettingsDialog.h">
|
||||
<Filter>Settings</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Settings\ControllerBindingWidgets.h">
|
||||
<Filter>Settings</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="Settings\ControllerGlobalSettingsWidget.h">
|
||||
<Filter>Settings</Filter>
|
||||
</QtMoc>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtResource Include="resources\resources.qrc">
|
||||
<Filter>Resources</Filter>
|
||||
</QtResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtUi Include="mainwindow.ui" />
|
||||
<QtUi Include="Settings\BIOSSettingsWidget.ui">
|
||||
<Filter>Settings</Filter>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\EmulationSettingsWidget.ui">
|
||||
<Filter>Settings</Filter>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\GameListSettingsWidget.ui">
|
||||
<Filter>Settings</Filter>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\GraphicsSettingsWidget.ui">
|
||||
<Filter>Settings</Filter>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\InterfaceSettingsWidget.ui">
|
||||
<Filter>Settings</Filter>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\SystemSettingsWidget.ui">
|
||||
<Filter>Settings</Filter>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\SettingsDialog.ui">
|
||||
<Filter>Settings</Filter>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\AdvancedSystemSettingsWidget.ui">
|
||||
<Filter>Settings</Filter>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\GameFixSettingsWidget.ui">
|
||||
<Filter>Settings</Filter>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\InputBindingDialog.ui">
|
||||
<Filter>Settings</Filter>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\ControllerSettingsDialog.ui">
|
||||
<Filter>Settings</Filter>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\ControllerBindingWidget_DualShock2.ui">
|
||||
<Filter>Settings</Filter>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\ControllerBindingWidget.ui">
|
||||
<Filter>Settings</Filter>
|
||||
</QtUi>
|
||||
<QtUi Include="Settings\ControllerGlobalSettingsWidget.ui">
|
||||
<Filter>Settings</Filter>
|
||||
</QtUi>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,13 @@
|
|||
#!/bin/sh
|
||||
|
||||
IFS="
|
||||
"
|
||||
|
||||
printf "<RCC>\n"
|
||||
printf "\t<qresource>\n"
|
||||
for i in $(find . -not -iname '*.sh' -not -iname '*.qrc' -type f | cut -d'/' -f2-99); do
|
||||
printf "\t\t<file>%s</file>\n" "$i"
|
||||
done
|
||||
printf "\t</qresource>\n"
|
||||
printf "</RCC>\n"
|
||||
|
After Width: | Height: | Size: 675 B |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 681 B |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 165 B |
After Width: | Height: | Size: 147 B |
After Width: | Height: | Size: 210 B |
After Width: | Height: | Size: 127 B |
After Width: | Height: | Size: 162 B |
After Width: | Height: | Size: 230 B |
After Width: | Height: | Size: 159 B |
After Width: | Height: | Size: 146 B |
After Width: | Height: | Size: 222 B |