UI: Massive revamp, new features and improvements
|
@ -89,12 +89,12 @@ if(WIN32 AND USE_SDL2)
|
|||
set(SDL2_LIBRARIES "${CMAKE_CURRENT_SOURCE_DIR}/dep/msvc/sdl2/lib64/SDL2.lib")
|
||||
set(SDL2MAIN_LIBRARIES "${CMAKE_CURRENT_SOURCE_DIR}/dep/msvc/sdl2/lib64/SDL2main.lib")
|
||||
set(SDL2_DLL_PATH "${CMAKE_CURRENT_SOURCE_DIR}/dep/msvc/sdl2/bin64/SDL2.dll")
|
||||
set(Qt5_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dep/msvc/qt/5.15.0/msvc2017_64/lib/cmake/Qt5")
|
||||
set(Qt6_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dep/msvc/qt/6.1.0/msvc2019_64/lib/cmake/Qt6")
|
||||
else()
|
||||
set(SDL2_LIBRARIES "${CMAKE_CURRENT_SOURCE_DIR}/dep/msvc/sdl2/lib32/SDL2.lib")
|
||||
set(SDL2MAIN_LIBRARIES "${CMAKE_CURRENT_SOURCE_DIR}/dep/msvc/sdl2/lib32/SDL2main.lib")
|
||||
set(SDL2_DLL_PATH "${CMAKE_CURRENT_SOURCE_DIR}/dep/msvc/sdl2/bin32/SDL2.dll")
|
||||
set(Qt5_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dep/msvc/qt/5.15.0/msvc2017_32/lib/cmake/Qt5")
|
||||
set(Qt6_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dep/msvc/qt/6.1.0/msvc2019_32/lib/cmake/Qt6")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
@ -105,7 +105,7 @@ if(NOT ANDROID)
|
|||
find_package(SDL2 REQUIRED)
|
||||
endif()
|
||||
if(BUILD_QT_FRONTEND)
|
||||
find_package(Qt5 COMPONENTS Core Gui Widgets Network LinguistTools REQUIRED)
|
||||
find_package(Qt6 COMPONENTS Core Gui Widgets Network LinguistTools REQUIRED)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
|
|
@ -36683,7 +36683,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -94490,7 +94490,7 @@
|
|||
"AnalogController",
|
||||
"DigitalController",
|
||||
"PlayStationMouse",
|
||||
"NamcoGuncon",
|
||||
"GunCon",
|
||||
"KonamiJustifier"
|
||||
],
|
||||
"track_data": [
|
||||
|
@ -94528,7 +94528,7 @@
|
|||
"AnalogController",
|
||||
"DigitalController",
|
||||
"PlayStationMouse",
|
||||
"NamcoGuncon",
|
||||
"GunCon",
|
||||
"KonamiJustifier"
|
||||
],
|
||||
"track_data": [
|
||||
|
@ -94566,7 +94566,7 @@
|
|||
"AnalogController",
|
||||
"DigitalController",
|
||||
"PlayStationMouse",
|
||||
"NamcoGuncon",
|
||||
"GunCon",
|
||||
"KonamiJustifier"
|
||||
],
|
||||
"track_data": [
|
||||
|
@ -94604,7 +94604,7 @@
|
|||
"AnalogController",
|
||||
"DigitalController",
|
||||
"PlayStationMouse",
|
||||
"NamcoGuncon",
|
||||
"GunCon",
|
||||
"KonamiJustifier"
|
||||
],
|
||||
"track_data": [
|
||||
|
@ -94642,7 +94642,7 @@
|
|||
"AnalogController",
|
||||
"DigitalController",
|
||||
"PlayStationMouse",
|
||||
"NamcoGuncon",
|
||||
"GunCon",
|
||||
"KonamiJustifier"
|
||||
],
|
||||
"track_data": [
|
||||
|
@ -118156,7 +118156,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon",
|
||||
"GunCon",
|
||||
"KonamiJustifier",
|
||||
"PlayStationMouse"
|
||||
],
|
||||
|
@ -131024,7 +131024,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -159741,7 +159741,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon",
|
||||
"GunCon",
|
||||
"KonamiJustifier",
|
||||
"PlayStationMouse"
|
||||
],
|
||||
|
@ -161094,7 +161094,7 @@
|
|||
"AnalogController",
|
||||
"DigitalController",
|
||||
"PlayStationMouse",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -168086,7 +168086,7 @@
|
|||
"linkCable": false,
|
||||
"controllers": [
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -168130,7 +168130,7 @@
|
|||
"linkCable": false,
|
||||
"controllers": [
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -168166,7 +168166,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -168202,7 +168202,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -168264,7 +168264,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -168300,7 +168300,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -169280,7 +169280,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -169316,7 +169316,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -169792,7 +169792,7 @@
|
|||
"linkCable": false,
|
||||
"controllers": [
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -200165,7 +200165,7 @@
|
|||
"linkCable": false,
|
||||
"controllers": [
|
||||
"DigitalController",
|
||||
"NamcoGuncon",
|
||||
"GunCon",
|
||||
"KonamiJustifier"
|
||||
],
|
||||
"track_data": [
|
||||
|
@ -200201,7 +200201,7 @@
|
|||
"linkCable": false,
|
||||
"controllers": [
|
||||
"DigitalController",
|
||||
"NamcoGuncon",
|
||||
"GunCon",
|
||||
"KonamiJustifier"
|
||||
],
|
||||
"track_data": [
|
||||
|
@ -201057,7 +201057,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -243440,7 +243440,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon",
|
||||
"GunCon",
|
||||
"KonamiJustifier"
|
||||
],
|
||||
"track_data": [
|
||||
|
@ -243477,7 +243477,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon",
|
||||
"GunCon",
|
||||
"KonamiJustifier"
|
||||
],
|
||||
"track_data": [
|
||||
|
@ -250279,7 +250279,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon",
|
||||
"GunCon",
|
||||
"KonamiJustifier"
|
||||
],
|
||||
"track_data": [
|
||||
|
@ -250316,7 +250316,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon",
|
||||
"GunCon",
|
||||
"KonamiJustifier"
|
||||
],
|
||||
"track_data": [
|
||||
|
@ -257141,7 +257141,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -257262,7 +257262,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -290498,7 +290498,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -313576,7 +313576,7 @@
|
|||
"linkCable": false,
|
||||
"controllers": [
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -313620,7 +313620,7 @@
|
|||
"linkCable": false,
|
||||
"controllers": [
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -313660,7 +313660,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -313696,7 +313696,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -313736,7 +313736,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -313772,7 +313772,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -313808,7 +313808,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -323119,7 +323119,7 @@
|
|||
"linkCable": false,
|
||||
"controllers": [
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -336352,7 +336352,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon",
|
||||
"GunCon",
|
||||
"PlayStationMouse"
|
||||
],
|
||||
"track_data": [
|
||||
|
@ -336389,7 +336389,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon",
|
||||
"GunCon",
|
||||
"PlayStationMouse"
|
||||
]
|
||||
},
|
||||
|
@ -336437,7 +336437,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon",
|
||||
"GunCon",
|
||||
"PlayStationMouse"
|
||||
],
|
||||
"track_data": [
|
||||
|
@ -336837,7 +336837,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -336874,7 +336874,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -336910,7 +336910,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -338230,7 +338230,7 @@
|
|||
"linkCable": false,
|
||||
"controllers": [
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -338333,7 +338333,7 @@
|
|||
"linkCable": false,
|
||||
"controllers": [
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -338436,7 +338436,7 @@
|
|||
"linkCable": false,
|
||||
"controllers": [
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -338539,7 +338539,7 @@
|
|||
"linkCable": false,
|
||||
"controllers": [
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -370386,7 +370386,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -372433,7 +372433,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -430122,7 +430122,7 @@
|
|||
"linkCable": false,
|
||||
"controllers": [
|
||||
"DigitalController",
|
||||
"NamcoGuncon",
|
||||
"GunCon",
|
||||
"PlayStationMouse"
|
||||
],
|
||||
"track_data": [
|
||||
|
@ -430287,7 +430287,7 @@
|
|||
"linkCable": false,
|
||||
"controllers": [
|
||||
"DigitalController",
|
||||
"NamcoGuncon",
|
||||
"GunCon",
|
||||
"PlayStationMouse"
|
||||
],
|
||||
"track_data": [
|
||||
|
@ -430451,7 +430451,7 @@
|
|||
"linkCable": false,
|
||||
"controllers": [
|
||||
"DigitalController",
|
||||
"NamcoGuncon",
|
||||
"GunCon",
|
||||
"PlayStationMouse"
|
||||
],
|
||||
"track_data": [
|
||||
|
@ -430615,7 +430615,7 @@
|
|||
"linkCable": false,
|
||||
"controllers": [
|
||||
"DigitalController",
|
||||
"NamcoGuncon",
|
||||
"GunCon",
|
||||
"PlayStationMouse"
|
||||
],
|
||||
"track_data": [
|
||||
|
@ -430780,7 +430780,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -430810,7 +430810,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -431114,7 +431114,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -431234,7 +431234,7 @@
|
|||
"controllers": [
|
||||
"AnalogController",
|
||||
"DigitalController",
|
||||
"NamcoGuncon"
|
||||
"GunCon"
|
||||
],
|
||||
"track_data": [
|
||||
{
|
||||
|
@ -431353,7 +431353,7 @@
|
|||
"linkCable": false,
|
||||
"controllers": [
|
||||
"DigitalController",
|
||||
"NamcoGuncon",
|
||||
"GunCon",
|
||||
"PlayStationMouse"
|
||||
]
|
||||
},
|
|
@ -0,0 +1,202 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 120 KiB |
Before Width: | Height: | Size: 117 KiB After Width: | Height: | Size: 117 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 202 KiB After Width: | Height: | Size: 202 KiB |
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 6.0 KiB |
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 209 KiB |
|
@ -1 +1 @@
|
|||
Subproject commit fb9018121818293b72e9f5064b2cb202e713c501
|
||||
Subproject commit f44f99baad9c52e6e98831f95dde283b3c3d7993
|
|
@ -2,36 +2,38 @@
|
|||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="UserMacros">
|
||||
<BinaryOutputDir>$(SolutionDir)bin\$(Platform)\</BinaryOutputDir>
|
||||
<QTDIRDefault Condition="'$(Platform)'=='x64'">$(SolutionDir)dep\msvc\qt\6.1.0\msvc2019_64\</QTDIRDefault>
|
||||
<QTDIRDefault Condition="'$(Platform)'=='ARM64'">$(SolutionDir)dep\msvc\qt\6.1.0\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)dep\msvc\qt\6.1.0\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>$(SolutionDir)build\$(ProjectName)-$(Platform)-$(Configuration)\</QtToolOutDir>
|
||||
<DSQTDIRDefault Condition="'$(Platform)'=='x64'">$(SolutionDir)dep\msvc\qt\6.1.0\msvc2019_64\</DSQTDIRDefault>
|
||||
<DSQTDIRDefault Condition="'$(Platform)'=='ARM64'">$(SolutionDir)dep\msvc\qt\6.3.1\msvc2022_arm64\</DSQTDIRDefault>
|
||||
<DSQTDIR Condition="Exists('$(DSQTDIRDefault)') And ('$(DSQTDIR)'=='' Or !Exists('$(DSQTDIR)'))">$(DSQTDIRDefault)</DSQTDIR>
|
||||
<DSQTDIR Condition="Exists('$(DSQTDIR)') And !HasTrailingSlash('$(DSQTDIR)')">$(DSQTDIR)\</DSQTDIR>
|
||||
<DSQTDIRHost Condition="'$(Platform)'!='ARM64'">$(SolutionDir)dep\msvc\qt\6.1.0\msvc2019_64\</DSQTDIRHost>
|
||||
<DSQTDIRHost Condition="'$(Platform)'=='ARM64'">$(SolutionDir)dep\msvc\qt\6.3.1\msvc2022_64\</DSQTDIRHost>
|
||||
<DSQTDIRValid>false</DSQTDIRValid>
|
||||
<DSQTDIRValid Condition="Exists('$(DSQTDIR)')">true</DSQTDIRValid>
|
||||
<QtIncludeDir>$(DSQTDIR)include\</QtIncludeDir>
|
||||
<QtLibDir>$(DSQTDIR)lib\</QtLibDir>
|
||||
<QtBinDir>$(DSQTDIR)bin\</QtBinDir>
|
||||
<QtHostBinDir>$(DSQTDIRHost)bin\</QtHostBinDir>
|
||||
<QtPluginsDir>$(DSQTDIR)plugins\</QtPluginsDir>
|
||||
<QtTranslationsDir>$(DSQTDIR)translations\</QtTranslationsDir>
|
||||
<QtToolOutDir>$(IntDir)</QtToolOutDir>
|
||||
<QtMocOutPrefix>$(QtToolOutDir)moc_</QtMocOutPrefix>
|
||||
<QtTsOutDir>$(BinaryOutputDir)translations\</QtTsOutDir>
|
||||
<QtDebugSuffix>d</QtDebugSuffix>
|
||||
<QtLibSuffix Condition="'$(Configuration)'=='Debug' Or '$(Configuration)'=='DebugFast'">$(QtDebugSuffix)</QtLibSuffix>
|
||||
<QtLibSuffix Condition="$(Configuration.Contains(Debug))">$(QtDebugSuffix)</QtLibSuffix>
|
||||
<QtPluginFolder>QtPlugins</QtPluginFolder>
|
||||
<QtEntryPointLib>$(QtLibDir)Qt6EntryPoint$(QtLibSuffix).lib</QtEntryPointLib>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)'=='Release' Or '$(Configuration)'=='ReleaseLTCG'">QT_NO_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<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>
|
||||
<AdditionalDependencies>Qt6Core$(QtLibSuffix).lib;Qt6Gui$(QtLibSuffix).lib;Qt6Widgets$(QtLibSuffix).lib;Qt6Network$(QtLibSuffix).lib;Qt6Concurrent$(QtLibSuffix).lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
|
@ -45,7 +47,7 @@
|
|||
Condition="'@(QtResource)'!=''"
|
||||
Outputs="@(ResFiles->'$(QtToolOutDir)qrc_%(Filename).cpp')">
|
||||
<Message Text="rcc %(ResFiles.Filename)" Importance="High" />
|
||||
<Error Condition="!$(QtDirValid)" Text="QTDIR not set or non-existent (pull the submodule?)" />
|
||||
<Error Condition="!$(DSQTDIRValid)" Text="Qt directory non-existent (pull the submodule?)" />
|
||||
<MakeDir Directories="$(QtToolOutDir)" />
|
||||
<Exec Command=""$(QtHostBinDir)rcc.exe" "%(ResFiles.FullPath)" -o "$(QtToolOutDir)qrc_%(ResFiles.Filename).cpp"" />
|
||||
</Target>
|
||||
|
@ -64,7 +66,7 @@
|
|||
Condition="'@(QtUi)'!=''"
|
||||
Outputs="@(UiFiles->'$(QtToolOutDir)ui_%(Filename).h')">
|
||||
<Message Text="uic %(UiFiles.Filename)" Importance="High" />
|
||||
<Error Condition="!$(QtDirValid)" Text="QTDIR not set or non-existent (pull the submodule?)" />
|
||||
<Error Condition="!$(DSQTDIRValid)" Text="Qt directory non-existent (pull the submodule?)" />
|
||||
<MakeDir Directories="$(QtToolOutDir)" />
|
||||
<Exec Command=""$(QtHostBinDir)uic.exe" "%(UiFiles.FullPath)" -o "$(QtToolOutDir)ui_%(UiFiles.Filename).h"" />
|
||||
</Target>
|
||||
|
@ -77,26 +79,18 @@
|
|||
<!--TODO find a way to autocreate from ClCompile settings-->
|
||||
<PropertyGroup>
|
||||
<MocDefines></MocDefines>
|
||||
<MocDefines Condition="'$(Configuration)'=='Release' Or '$(Configuration)'=='ReleaseLTCG'">-DQT_NO_DEBUG -DNDEBUG $(MocDefines)</MocDefines>
|
||||
<!-- !!!HOLY UGLY BATMAN!!!
|
||||
Be very careful here when adding include directories. Each path must have the whole arg surrounded by doublequotes - HOWEVER,
|
||||
the ending doublequote cannot be directly preceeded by a directory seperator. In other words, you must use:
|
||||
"-I$(SomeDir) "
|
||||
instead of
|
||||
"-I$(SomeDir)"
|
||||
in order to prevent the trailing slash from escaping the doublequote after value replacement.
|
||||
-->
|
||||
<MocIncludes>"-I$(QtIncludeDir)" "-I$(SolutionDir)src" -I.</MocIncludes>
|
||||
<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)moc_%(QtMoc.Filename).cpp">
|
||||
<Message Text="moc %(QtMoc.Filename) $(QtToolOutDir)moc_%(QtMoc.Filename).cpp" Importance="High" />
|
||||
<Error Condition="!$(QtDirValid)" Text="QTDIR not set or non-existent (pull the submodule?)" />
|
||||
Outputs="$(QtToolOutDir)%(QtMoc.RelativeDir)moc_%(QtMoc.Filename).cpp">
|
||||
<Message Text="moc %(QtMoc.Filename) $(QtToolOutDir)%(QtMoc.RelativeDir)moc_%(QtMoc.Filename).cpp" Importance="High" />
|
||||
<Error Condition="!$(DSQTDIRValid)" Text="Qt directory non-existent (pull the submodule?)" />
|
||||
<MakeDir Directories="$(QtToolOutDir)" />
|
||||
<Exec Command=""$(QtHostBinDir)moc.exe" "%(QtMoc.FullPath)" -o "$(QtToolOutDir)moc_%(QtMoc.Filename).cpp" -f%(QtMoc.Filename)%(QtMoc.Extension) $(MocDefines) $(MocIncludes)" />
|
||||
<Exec Command=""$(QtHostBinDir)moc.exe" "%(QtMoc.FullPath)" -o "$(QtToolOutDir)%(QtMoc.RelativeDir)moc_%(QtMoc.Filename).cpp" -f%(QtMoc.Filename)%(QtMoc.Extension) $(MocDefines) $(MocIncludes)" />
|
||||
</Target>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -125,21 +119,24 @@
|
|||
|
||||
<!--Copy the needed dlls-->
|
||||
<ItemGroup>
|
||||
<QtLibNames Include="Qt6Core$(QtLibSuffix);Qt6Gui$(QtLibSuffix);Qt6Widgets$(QtLibSuffix);Qt6Network$(QtLibSuffix);Qt6Svg$(QtLibSuffix)" />
|
||||
<QtLibNames Include="Qt6Core$(QtLibSuffix);Qt6Gui$(QtLibSuffix);Qt6Widgets$(QtLibSuffix);Qt6Network$(QtLibSuffix);Qt6Svg$(QtLibSuffix);Qt6Concurrent$(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)'=='Debug' Or '$(Configuration)'=='DebugFast'" Include="@(QtAllPlugins)" />
|
||||
<QtPlugins Condition="'$(Configuration)'=='Release' Or '$(Configuration)'=='ReleaseLTCG'" Exclude="$(QtPluginsDir)**\*$(QtDebugSuffix).dll" Include="@(QtAllPlugins)" />
|
||||
<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)')" />
|
||||
<!--Our normal *d filter fails for the TLS DLLs, because backend ends in d. -->
|
||||
<!--<QtTLSDlls Include="$(QtPluginsDir)tls\qcertonlybackend$(QtLibSuffix).dll;$(QtPluginsDir)tls\qschannelbackend$(QtLibSuffix).dll" />-->
|
||||
<QtTLSDllsDest Include="@(QtTLSDlls -> '$(BinaryOutputDir)$(QtPluginFolder)\tls\%(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)')">
|
||||
Inputs="@(QtDlls);@(QtPlugins);@(QtTLSDlls)"
|
||||
Outputs="@(QtDlls -> '$(BinaryOutputDir)%(RecursiveDir)%(Filename)%(Extension)');@(QtPluginsDest);@(QtTLSDllsDest)">
|
||||
<Message Text="Copying Qt .dlls" Importance="High" />
|
||||
<Copy
|
||||
SourceFiles="@(QtDlls)"
|
||||
|
@ -151,6 +148,11 @@
|
|||
DestinationFiles="@(QtPluginsDest)"
|
||||
SkipUnchangedFiles="true"
|
||||
/>
|
||||
<Copy
|
||||
SourceFiles="@(QtTLSDlls)"
|
||||
DestinationFiles="@(QtTLSDllsDest)"
|
||||
SkipUnchangedFiles="true"
|
||||
/>
|
||||
</Target>
|
||||
<Target Name="QtCreateConf"
|
||||
BeforeTargets="QtCopyBinaries"
|
||||
|
@ -192,7 +194,7 @@
|
|||
Condition="'@(QtTs)'!=''"
|
||||
Outputs="@(TsFiles->'$(QtTsOutDir)%(Filename).qm')">
|
||||
<Message Text="lrelease %(TsFiles.Filename)" Importance="High" />
|
||||
<Error Condition="!$(QtDirValid)" Text="QTDIR not set or non-existent (pull the submodule?)" />
|
||||
<Error Condition="!$(DSQTDIRValid)" Text="Qt directory non-existent (pull the submodule?)" />
|
||||
<MakeDir Directories="$(QtTsOutDir)" />
|
||||
<Exec Command=""$(QtHostBinDir)lrelease.exe" "%(TsFiles.FullPath)" -qm "$(QtTsOutDir)%(TsFiles.Filename).qm"" />
|
||||
</Target>
|
||||
|
|
|
@ -16,6 +16,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "src\common\common
|
|||
{ED601289-AC1A-46B8-A8ED-17DB9EB73423} = {ED601289-AC1A-46B8-A8ED-17DB9EB73423}
|
||||
{8BDA439C-6358-45FB-9994-2FF083BABE06} = {8BDA439C-6358-45FB-9994-2FF083BABE06}
|
||||
{7FF9FDB9-D504-47DB-A16A-B08071999620} = {7FF9FDB9-D504-47DB-A16A-B08071999620}
|
||||
{8BE398E6-B882-4248-9065-FECC8728E038} = {8BE398E6-B882-4248-9065-FECC8728E038}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core", "src\core\core.vcxproj", "{868B98C8-65A1-494B-8346-250A73A48C0A}"
|
||||
|
@ -811,30 +812,22 @@ Global
|
|||
{39F0ADFF-3A84-470D-9CF0-CA49E164F2F3}.ReleaseUWP|x64.ActiveCfg = ReleaseUWP|x64
|
||||
{39F0ADFF-3A84-470D-9CF0-CA49E164F2F3}.ReleaseUWP|x86.ActiveCfg = ReleaseUWP|Win32
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.Debug|x64.Build.0 = Debug|x64
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.Debug|x86.Build.0 = Debug|Win32
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.DebugFast|ARM64.ActiveCfg = DebugFast|ARM64
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.DebugFast|ARM64.Build.0 = DebugFast|ARM64
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.DebugFast|x64.ActiveCfg = DebugFast|x64
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.DebugFast|x64.Build.0 = DebugFast|x64
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.DebugFast|x86.ActiveCfg = DebugFast|Win32
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.DebugFast|x86.Build.0 = DebugFast|Win32
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.DebugUWP|ARM64.ActiveCfg = DebugUWP|ARM64
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.DebugUWP|x64.ActiveCfg = DebugUWP|x64
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.Release|x64.ActiveCfg = Release|x64
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.Release|x64.Build.0 = Release|x64
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.Release|x86.ActiveCfg = Release|Win32
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.Release|x86.Build.0 = Release|Win32
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.ReleaseLTCG|ARM64.ActiveCfg = ReleaseLTCG|ARM64
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.ReleaseLTCG|ARM64.Build.0 = ReleaseLTCG|ARM64
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.ReleaseLTCG|x64.ActiveCfg = ReleaseLTCG|x64
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.ReleaseLTCG|x64.Build.0 = ReleaseLTCG|x64
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.ReleaseLTCG|x86.ActiveCfg = ReleaseLTCG|Win32
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.ReleaseLTCG|x86.Build.0 = ReleaseLTCG|Win32
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.ReleaseUWP|ARM64.ActiveCfg = ReleaseUWP|ARM64
|
||||
|
|
|
@ -896,6 +896,105 @@ void GrowableMemoryByteStream::Grow(u32 MinimumGrowth)
|
|||
ResizeMemory(NewSize);
|
||||
}
|
||||
|
||||
bool ByteStream::ReadU8(u8* dest)
|
||||
{
|
||||
return Read2(dest, sizeof(u8));
|
||||
}
|
||||
|
||||
bool ByteStream::ReadU16(u16* dest)
|
||||
{
|
||||
return Read2(dest, sizeof(u16));
|
||||
}
|
||||
|
||||
bool ByteStream::ReadU32(u32* dest)
|
||||
{
|
||||
return Read2(dest, sizeof(u32));
|
||||
}
|
||||
|
||||
bool ByteStream::ReadU64(u64* dest)
|
||||
{
|
||||
return Read2(dest, sizeof(u64));
|
||||
}
|
||||
|
||||
bool ByteStream::ReadS8(s8* dest)
|
||||
{
|
||||
return Read2(dest, sizeof(s8));
|
||||
}
|
||||
|
||||
bool ByteStream::ReadS16(s16* dest)
|
||||
{
|
||||
return Read2(dest, sizeof(s16));
|
||||
}
|
||||
|
||||
bool ByteStream::ReadS32(s32* dest)
|
||||
{
|
||||
return Read2(dest, sizeof(s32));
|
||||
}
|
||||
|
||||
bool ByteStream::ReadS64(s64* dest)
|
||||
{
|
||||
return Read2(dest, sizeof(s64));
|
||||
}
|
||||
|
||||
bool ByteStream::ReadSizePrefixedString(std::string* dest)
|
||||
{
|
||||
u32 size;
|
||||
if (!Read2(&size, sizeof(size)))
|
||||
return false;
|
||||
|
||||
dest->resize(size);
|
||||
if (!Read2(dest->data(), size))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ByteStream::WriteU8(u8 dest)
|
||||
{
|
||||
return Write2(&dest, sizeof(u8));
|
||||
}
|
||||
|
||||
bool ByteStream::WriteU16(u16 dest)
|
||||
{
|
||||
return Write2(&dest, sizeof(u16));
|
||||
}
|
||||
|
||||
bool ByteStream::WriteU32(u32 dest)
|
||||
{
|
||||
return Write2(&dest, sizeof(u32));
|
||||
}
|
||||
|
||||
bool ByteStream::WriteU64(u64 dest)
|
||||
{
|
||||
return Write2(&dest, sizeof(u64));
|
||||
}
|
||||
|
||||
bool ByteStream::WriteS8(s8 dest)
|
||||
{
|
||||
return Write2(&dest, sizeof(s8));
|
||||
}
|
||||
|
||||
bool ByteStream::WriteS16(s16 dest)
|
||||
{
|
||||
return Write2(&dest, sizeof(s16));
|
||||
}
|
||||
|
||||
bool ByteStream::WriteS32(s32 dest)
|
||||
{
|
||||
return Write2(&dest, sizeof(s32));
|
||||
}
|
||||
|
||||
bool ByteStream::WriteS64(s64 dest)
|
||||
{
|
||||
return Write2(&dest, sizeof(s64));
|
||||
}
|
||||
|
||||
bool ByteStream::WriteSizePrefixedString(const std::string_view& str)
|
||||
{
|
||||
const u32 size = static_cast<u32>(str.size());
|
||||
return (Write2(&size, sizeof(size)) && (size == 0 || Write2(str.data(), size)));
|
||||
}
|
||||
|
||||
std::unique_ptr<ByteStream> ByteStream::OpenFile(const char* fileName, u32 openMode)
|
||||
{
|
||||
if ((openMode & (BYTESTREAM_OPEN_CREATE | BYTESTREAM_OPEN_WRITE)) == BYTESTREAM_OPEN_WRITE)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "types.h"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
// base byte stream creation functions
|
||||
|
@ -76,6 +77,26 @@ public:
|
|||
inline void SetErrorState() { m_errorState = true; }
|
||||
inline void ClearErrorState() { m_errorState = false; }
|
||||
|
||||
bool ReadU8(u8* dest);
|
||||
bool ReadU16(u16* dest);
|
||||
bool ReadU32(u32* dest);
|
||||
bool ReadU64(u64* dest);
|
||||
bool ReadS8(s8* dest);
|
||||
bool ReadS16(s16* dest);
|
||||
bool ReadS32(s32* dest);
|
||||
bool ReadS64(s64* dest);
|
||||
bool ReadSizePrefixedString(std::string* dest);
|
||||
|
||||
bool WriteU8(u8 dest);
|
||||
bool WriteU16(u16 dest);
|
||||
bool WriteU32(u32 dest);
|
||||
bool WriteU64(u64 dest);
|
||||
bool WriteS8(s8 dest);
|
||||
bool WriteS16(s16 dest);
|
||||
bool WriteS32(s32 dest);
|
||||
bool WriteS64(s64 dest);
|
||||
bool WriteSizePrefixedString(const std::string_view& str);
|
||||
|
||||
// base byte stream creation functions
|
||||
// opens a local file-based stream. fills in error if passed, and returns false if the file cannot be opened.
|
||||
static std::unique_ptr<ByteStream> OpenFile(const char* FileName, u32 OpenMode);
|
||||
|
|
|
@ -167,7 +167,7 @@ std::string ShaderCache::GetCacheBaseFileName(const std::string_view& base_path,
|
|||
bool debug)
|
||||
{
|
||||
std::string base_filename(base_path);
|
||||
base_filename += "d3d_shaders_";
|
||||
base_filename += FS_OSPATH_SEPARATOR_STR "d3d_shaders_";
|
||||
|
||||
switch (feature_level)
|
||||
{
|
||||
|
|
|
@ -226,7 +226,7 @@ std::string ShaderCache::GetCacheBaseFileName(const std::string_view& base_path,
|
|||
D3D_FEATURE_LEVEL feature_level, bool debug)
|
||||
{
|
||||
std::string base_filename(base_path);
|
||||
base_filename += "d3d12_";
|
||||
base_filename += FS_OSPATH_SEPARATOR_STR "d3d12_";
|
||||
base_filename += type;
|
||||
base_filename += "_";
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "../file_system.h"
|
||||
#include "../log.h"
|
||||
#include "../md5_digest.h"
|
||||
#include "../path.h"
|
||||
#include "../string_util.h"
|
||||
Log_SetChannel(GL::ShaderCache);
|
||||
|
||||
|
@ -251,12 +252,12 @@ ShaderCache::CacheIndexKey ShaderCache::GetCacheKey(const std::string_view& vert
|
|||
|
||||
std::string ShaderCache::GetIndexFileName() const
|
||||
{
|
||||
return StringUtil::StdStringFromFormat("%sgl_programs.idx", m_base_path.c_str());
|
||||
return Path::Combine(m_base_path, "gl_programs.idx");
|
||||
}
|
||||
|
||||
std::string ShaderCache::GetBlobFileName() const
|
||||
{
|
||||
return StringUtil::StdStringFromFormat("%sgl_programs.bin", m_base_path.c_str());
|
||||
return Path::Combine(m_base_path, "gl_programs.bin");
|
||||
}
|
||||
|
||||
std::optional<Program> ShaderCache::GetProgram(const std::string_view vertex_shader,
|
||||
|
|
|
@ -7,7 +7,7 @@ Log_SetChannel(HTTPDownloader);
|
|||
static constexpr float DEFAULT_TIMEOUT_IN_SECONDS = 30;
|
||||
static constexpr u32 DEFAULT_MAX_ACTIVE_REQUESTS = 4;
|
||||
|
||||
namespace FrontendCommon {
|
||||
namespace Common {
|
||||
|
||||
const char HTTPDownloader::DEFAULT_USER_AGENT[] =
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0";
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace FrontendCommon {
|
||||
namespace Common {
|
||||
|
||||
class HTTPDownloader
|
||||
{
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include <signal.h>
|
||||
Log_SetChannel(HTTPDownloaderCurl);
|
||||
|
||||
namespace FrontendCommon {
|
||||
namespace Common {
|
||||
|
||||
HTTPDownloaderCurl::HTTPDownloaderCurl() : HTTPDownloader() {}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include <mutex>
|
||||
#include <curl/curl.h>
|
||||
|
||||
namespace FrontendCommon {
|
||||
namespace Common {
|
||||
|
||||
class HTTPDownloaderCurl final : public HTTPDownloader
|
||||
{
|
||||
|
|
|
@ -13,7 +13,7 @@ Log_SetChannel(HTTPDownloaderWinHttp);
|
|||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::Web::Http;
|
||||
|
||||
namespace FrontendCommon {
|
||||
namespace Common {
|
||||
|
||||
HTTPDownloaderUWP::HTTPDownloaderUWP(std::string user_agent) : HTTPDownloader(), m_user_agent(std::move(user_agent)) {}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include <winrt/windows.Web.Http.h>
|
||||
|
||||
namespace FrontendCommon {
|
||||
namespace Common {
|
||||
|
||||
class HTTPDownloaderUWP final : public HTTPDownloader
|
||||
{
|
||||
|
|
|
@ -9,7 +9,7 @@ Log_SetChannel(HTTPDownloaderWinHttp);
|
|||
|
||||
#pragma comment(lib, "winhttp.lib")
|
||||
|
||||
namespace FrontendCommon {
|
||||
namespace Common {
|
||||
|
||||
HTTPDownloaderWinHttp::HTTPDownloaderWinHttp() : HTTPDownloader() {}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include <winhttp.h>
|
||||
|
||||
namespace FrontendCommon {
|
||||
namespace Common {
|
||||
|
||||
class HTTPDownloaderWinHttp final : public HTTPDownloader
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#include "heterogeneous_containers.h"
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
|
||||
|
@ -13,7 +14,7 @@ class LRUCache
|
|||
CounterType last_access;
|
||||
};
|
||||
|
||||
using MapType = std::map<K, Item>;
|
||||
using MapType = std::conditional_t<std::is_same_v<K, std::string>, StringMap<Item>, std::map<K, Item>>;
|
||||
|
||||
public:
|
||||
LRUCache(std::size_t max_capacity = 16, bool manual_evict = false)
|
||||
|
|
|
@ -24,15 +24,18 @@
|
|||
#include <sys/syscall.h>
|
||||
#define gettid() syscall(SYS_gettid)
|
||||
#endif
|
||||
#else
|
||||
#elif defined(__APPLE__)
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_error.h>
|
||||
#include <mach/mach_time.h>
|
||||
#include <mach/semaphore.h>
|
||||
#include <mach/task.h>
|
||||
#include <pthread_np.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
// This hacky union would probably fail on some cpu platforms if the contents of FILETIME aren't
|
||||
// packed (but for any x86 CPU and microsoft compiler, they will be).
|
||||
union FileTimeSucks
|
||||
union FileTimeU64Union
|
||||
{
|
||||
FILETIME filetime;
|
||||
u64 u64time;
|
||||
|
@ -208,18 +211,16 @@ Threading::ThreadHandle& Threading::ThreadHandle::operator=(const ThreadHandle&
|
|||
|
||||
u64 Threading::ThreadHandle::GetCPUTime() const
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
#if 0
|
||||
#if defined(_WIN32) && !defined(_UWP) && !defined(_M_ARM64)
|
||||
u64 ret = 0;
|
||||
if (m_native_handle)
|
||||
QueryThreadCycleTime((HANDLE)m_native_handle, &ret);
|
||||
return ret;
|
||||
#else
|
||||
FileTimeSucks user = {}, kernel = {};
|
||||
#elif defined(_WIN32)
|
||||
FileTimeU64Union user = {}, kernel = {};
|
||||
FILETIME dummy;
|
||||
GetThreadTimes((HANDLE)m_native_handle, &dummy, &dummy, &kernel.filetime, &user.filetime);
|
||||
return user.u64time + kernel.u64time;
|
||||
#endif
|
||||
#elif defined(__APPLE__)
|
||||
return getthreadtime(pthread_mach_thread_np((pthread_t)m_native_handle));
|
||||
#elif defined(__linux__)
|
||||
|
@ -457,17 +458,15 @@ Threading::ThreadHandle& Threading::Thread::operator=(Thread&& thread)
|
|||
|
||||
u64 Threading::GetThreadCpuTime()
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
#if 0
|
||||
#if defined(_WIN32) && !defined(_UWP) && !defined(_M_ARM64)
|
||||
u64 ret = 0;
|
||||
QueryThreadCycleTime(GetCurrentThread(), &ret);
|
||||
return ret;
|
||||
#else
|
||||
FileTimeSucks user = {}, kernel = {};
|
||||
#elif defined(_WIN32)
|
||||
FileTimeU64Union user = {}, kernel = {};
|
||||
FILETIME dummy;
|
||||
GetThreadTimes(GetCurrentThread(), &dummy, &dummy, &kernel.filetime, &user.filetime);
|
||||
return user.u64time + kernel.u64time;
|
||||
#endif
|
||||
#elif defined(__APPLE__)
|
||||
return getthreadtime(pthread_mach_thread_np(pthread_self()));
|
||||
#else
|
||||
|
@ -477,17 +476,33 @@ u64 Threading::GetThreadCpuTime()
|
|||
|
||||
u64 Threading::GetThreadTicksPerSecond()
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
#if 0
|
||||
#if defined(_WIN32) && !defined(_UWP) && !defined(_M_ARM64)
|
||||
// On x86, despite what the MS documentation says, this basically appears to be rdtsc.
|
||||
// So, the frequency is our base clock speed (and stable regardless of power management).
|
||||
static u64 frequency = 0;
|
||||
if (unlikely(frequency == 0))
|
||||
frequency = x86caps.CachedMHz() * u64(1000000);
|
||||
if (UNLIKELY(frequency == 0))
|
||||
{
|
||||
frequency = 1000000;
|
||||
|
||||
HKEY hKey;
|
||||
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0, KEY_READ, &hKey) ==
|
||||
ERROR_SUCCESS)
|
||||
{
|
||||
DWORD value;
|
||||
DWORD value_size = sizeof(value);
|
||||
if (RegQueryValueExW(hKey, L"~MHz", 0, nullptr, reinterpret_cast<LPBYTE>(&value), &value_size) == ERROR_SUCCESS)
|
||||
{
|
||||
// value is in mhz, convert to hz
|
||||
frequency *= value;
|
||||
}
|
||||
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
}
|
||||
|
||||
return frequency;
|
||||
#else
|
||||
#elif defined(_WIN32)
|
||||
return 10000000;
|
||||
#endif
|
||||
#elif defined(__APPLE__)
|
||||
return 1000000;
|
||||
|
||||
|
@ -539,3 +554,60 @@ void Threading::SetNameOfCurrentThread(const char* name)
|
|||
pthread_set_name_np(pthread_self(), name);
|
||||
#endif
|
||||
}
|
||||
|
||||
Threading::KernelSemaphore::KernelSemaphore()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
m_sema = CreateSemaphore(nullptr, 0, LONG_MAX, nullptr);
|
||||
#elif defined(__APPLE__)
|
||||
semaphore_create(mach_task_self(), &m_sema, SYNC_POLICY_FIFO, 0);
|
||||
#else
|
||||
sem_init(&m_sema, false, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
Threading::KernelSemaphore::~KernelSemaphore()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
CloseHandle(m_sema);
|
||||
#elif defined(__APPLE__)
|
||||
semaphore_destroy(mach_task_self(), m_sema);
|
||||
#else
|
||||
sem_destroy(&m_sema);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Threading::KernelSemaphore::Post()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
ReleaseSemaphore(m_sema, 1, nullptr);
|
||||
#elif defined(__APPLE__)
|
||||
semaphore_signal(m_sema);
|
||||
#else
|
||||
sem_post(&m_sema);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Threading::KernelSemaphore::Wait()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
WaitForSingleObject(m_sema, INFINITE);
|
||||
#elif defined(__APPLE__)
|
||||
semaphore_wait(m_sema);
|
||||
#else
|
||||
sem_wait(&m_sema);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Threading::KernelSemaphore::TryWait()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return WaitForSingleObject(m_sema, 0) == WAIT_OBJECT_0;
|
||||
#elif defined(__APPLE__)
|
||||
mach_timespec_t time = {};
|
||||
kern_return_t res = semaphore_timedwait(m_sema, time);
|
||||
return (res != KERN_OPERATION_TIMED_OUT);
|
||||
#else
|
||||
return sem_trywait(&m_sema) == 0;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -55,6 +55,16 @@ char (&__countof_ArraySizeHelper(T (&array)[N]))[N];
|
|||
#define printflike(n,m)
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// TODO: Use C++20 [[likely]] when available.
|
||||
#define LIKELY(x) (!!(x))
|
||||
#define UNLIKELY(x) (!!(x))
|
||||
#else
|
||||
#define LIKELY(x) __builtin_expect(!!(x), 1)
|
||||
#define UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||
#endif
|
||||
|
||||
|
||||
// disable warnings that show up at warning level 4
|
||||
// TODO: Move to build system instead
|
||||
#ifdef _MSC_VER
|
||||
|
|
|
@ -386,7 +386,7 @@ void ShaderCache::ClosePipelineCache()
|
|||
std::string ShaderCache::GetShaderCacheBaseFileName(const std::string_view& base_path, bool debug)
|
||||
{
|
||||
std::string base_filename(base_path);
|
||||
base_filename += "vulkan_shaders";
|
||||
base_filename += FS_OSPATH_SEPARATOR_STR "vulkan_shaders";
|
||||
|
||||
if (debug)
|
||||
base_filename += "_debug";
|
||||
|
@ -397,7 +397,7 @@ std::string ShaderCache::GetShaderCacheBaseFileName(const std::string_view& base
|
|||
std::string ShaderCache::GetPipelineCacheBaseFileName(const std::string_view& base_path, bool debug)
|
||||
{
|
||||
std::string base_filename(base_path);
|
||||
base_filename += "vulkan_pipelines";
|
||||
base_filename += FS_OSPATH_SEPARATOR_STR "vulkan_pipelines";
|
||||
|
||||
if (debug)
|
||||
base_filename += "_debug";
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
add_library(core
|
||||
achievements.h
|
||||
analog_controller.cpp
|
||||
analog_controller.h
|
||||
analog_joystick.cpp
|
||||
|
@ -28,6 +29,8 @@ add_library(core
|
|||
digital_controller.h
|
||||
dma.cpp
|
||||
dma.h
|
||||
game_database.cpp
|
||||
game_database.h
|
||||
gdb_protocol.cpp
|
||||
gdb_protocol.h
|
||||
gpu.cpp
|
||||
|
@ -48,21 +51,18 @@ add_library(core
|
|||
gpu_sw_backend.cpp
|
||||
gpu_sw_backend.h
|
||||
gpu_types.h
|
||||
guncon.cpp
|
||||
guncon.h
|
||||
gte.cpp
|
||||
gte.h
|
||||
gte_types.h
|
||||
host.cpp
|
||||
host.h
|
||||
host_display.cpp
|
||||
host_display.h
|
||||
host_interface.cpp
|
||||
host_interface.h
|
||||
host_interface_progress_callback.cpp
|
||||
host_interface_progress_callback.h
|
||||
host_settings.h
|
||||
imgui_styles.cpp
|
||||
imgui_styles.h
|
||||
imgui_fullscreen.cpp
|
||||
imgui_fullscreen.h
|
||||
interrupt_controller.cpp
|
||||
interrupt_controller.h
|
||||
libcrypt_game_codes.cpp
|
||||
|
@ -75,8 +75,6 @@ add_library(core
|
|||
memory_card_image.h
|
||||
multitap.cpp
|
||||
multitap.h
|
||||
namco_guncon.cpp
|
||||
namco_guncon.h
|
||||
negcon.cpp
|
||||
negcon.h
|
||||
pad.cpp
|
||||
|
@ -123,7 +121,7 @@ set(RECOMPILER_SRCS
|
|||
target_include_directories(core PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/..")
|
||||
target_include_directories(core PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/..")
|
||||
target_link_libraries(core PUBLIC Threads::Threads common util zlib)
|
||||
target_link_libraries(core PRIVATE glad stb xxhash imgui)
|
||||
target_link_libraries(core PRIVATE glad stb xxhash imgui rapidjson tinyxml2)
|
||||
|
||||
if(WIN32)
|
||||
target_sources(core PRIVATE
|
||||
|
@ -161,10 +159,5 @@ else()
|
|||
endif()
|
||||
|
||||
if(ENABLE_CHEEVOS)
|
||||
target_sources(core PRIVATE
|
||||
cheevos.cpp
|
||||
cheevos.h
|
||||
)
|
||||
target_compile_definitions(core PUBLIC -DWITH_CHEEVOS=1)
|
||||
target_link_libraries(core PRIVATE rcheevos rapidjson)
|
||||
target_compile_definitions(core PRIVATE -DWITH_CHEEVOS=1)
|
||||
endif()
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
#pragma once
|
||||
#include "common/types.h"
|
||||
|
||||
class StateWrapper;
|
||||
class CDImage;
|
||||
|
||||
namespace Achievements {
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
|
||||
// Implemented in Host.
|
||||
extern bool Reset();
|
||||
extern bool DoState(StateWrapper& sw);
|
||||
extern void GameChanged(const std::string& path, CDImage* image);
|
||||
|
||||
/// Re-enables hardcode mode if it is enabled in the settings.
|
||||
extern void ResetChallengeMode();
|
||||
|
||||
/// Forces hardcore mode off until next reset.
|
||||
extern void DisableChallengeMode();
|
||||
|
||||
/// Prompts the user to disable hardcore mode, if they agree, returns true.
|
||||
extern bool ConfirmChallengeModeDisable(const char* trigger);
|
||||
|
||||
/// Returns true if features such as save states should be disabled.
|
||||
extern bool ChallengeModeActive();
|
||||
|
||||
#else
|
||||
|
||||
// Make noops when compiling without cheevos.
|
||||
static inline bool Reset()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
static inline bool DoState(StateWrapper& sw)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
static constexpr inline bool ChallengeModeActive()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void ResetChallengeMode() {}
|
||||
|
||||
static inline void DisableChallengeMode() {}
|
||||
|
||||
static inline bool ConfirmChallengeModeDisable(const char* trigger)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace Achievements
|
|
@ -1,14 +1,14 @@
|
|||
#include "analog_controller.h"
|
||||
#include "common/log.h"
|
||||
#include "common/string_util.h"
|
||||
#include "host_interface.h"
|
||||
#include "host.h"
|
||||
#include "settings.h"
|
||||
#include "system.h"
|
||||
#include "util/state_wrapper.h"
|
||||
#include <cmath>
|
||||
Log_SetChannel(AnalogController);
|
||||
|
||||
AnalogController::AnalogController(u32 index) : m_index(index)
|
||||
AnalogController::AnalogController(u32 index) : Controller(index)
|
||||
{
|
||||
m_axis_state.fill(0x80);
|
||||
Reset();
|
||||
|
@ -29,7 +29,12 @@ void AnalogController::Reset()
|
|||
m_tx_buffer.fill(0x00);
|
||||
m_analog_mode = false;
|
||||
m_configuration_mode = false;
|
||||
m_motor_state.fill(0);
|
||||
|
||||
for (u32 i = 0; i < NUM_MOTORS; i++)
|
||||
{
|
||||
if (m_motor_state[i] != 0)
|
||||
SetMotorState(i, 0);
|
||||
}
|
||||
|
||||
m_dualshock_enabled = false;
|
||||
ResetRumbleConfig();
|
||||
|
@ -40,8 +45,8 @@ void AnalogController::Reset()
|
|||
{
|
||||
if (g_settings.controller_disable_analog_mode_forcing)
|
||||
{
|
||||
g_host_interface->AddOSDMessage(
|
||||
g_host_interface->TranslateStdString(
|
||||
Host::AddOSDMessage(
|
||||
Host::TranslateStdString(
|
||||
"OSDMessage", "Analog mode forcing is disabled by game settings. Controller will start in digital mode."),
|
||||
10.0f);
|
||||
}
|
||||
|
@ -88,72 +93,42 @@ bool AnalogController::DoState(StateWrapper& sw, bool apply_input_state)
|
|||
|
||||
if (old_analog_mode != m_analog_mode)
|
||||
{
|
||||
g_host_interface->AddFormattedOSDMessage(
|
||||
Host::AddFormattedOSDMessage(
|
||||
5.0f,
|
||||
m_analog_mode ?
|
||||
g_host_interface->TranslateString("AnalogController", "Controller %u switched to analog mode.") :
|
||||
g_host_interface->TranslateString("AnalogController", "Controller %u switched to digital mode."),
|
||||
m_analog_mode ? Host::TranslateString("AnalogController", "Controller %u switched to analog mode.") :
|
||||
Host::TranslateString("AnalogController", "Controller %u switched to digital mode."),
|
||||
m_index + 1u);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<s32> AnalogController::GetAxisCodeByName(std::string_view axis_name) const
|
||||
float AnalogController::GetBindState(u32 index) const
|
||||
{
|
||||
return StaticGetAxisCodeByName(axis_name);
|
||||
}
|
||||
if (index >= static_cast<u32>(Button::Count))
|
||||
{
|
||||
const u32 sub_index = index - static_cast<u32>(Button::Count);
|
||||
if (sub_index >= static_cast<u32>(m_half_axis_state.size()))
|
||||
return 0.0f;
|
||||
|
||||
std::optional<s32> AnalogController::GetButtonCodeByName(std::string_view button_name) const
|
||||
{
|
||||
return StaticGetButtonCodeByName(button_name);
|
||||
}
|
||||
|
||||
float AnalogController::GetAxisState(s32 axis_code) const
|
||||
{
|
||||
if (axis_code < 0 || axis_code >= static_cast<s32>(Axis::Count))
|
||||
return static_cast<float>(m_half_axis_state[sub_index]) * (1.0f / 255.0f);
|
||||
}
|
||||
else if (index < static_cast<u32>(Button::Analog))
|
||||
{
|
||||
return static_cast<float>(((m_button_state >> index) & 1u) ^ 1u);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0.0f;
|
||||
|
||||
// 0..255 -> -1..1
|
||||
const float value = (((static_cast<float>(m_axis_state[static_cast<s32>(axis_code)]) / 255.0f) * 2.0f) - 1.0f);
|
||||
return std::clamp(value / m_axis_scale, -1.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void AnalogController::SetAxisState(s32 axis_code, float value)
|
||||
void AnalogController::SetBindState(u32 index, float value)
|
||||
{
|
||||
if (axis_code < 0 || axis_code >= static_cast<s32>(Axis::Count))
|
||||
return;
|
||||
|
||||
// -1..1 -> 0..255
|
||||
const float scaled_value = std::clamp(value * m_axis_scale, -1.0f, 1.0f);
|
||||
const u8 u8_value = static_cast<u8>(std::clamp(std::round(((scaled_value + 1.0f) / 2.0f) * 255.0f), 0.0f, 255.0f));
|
||||
|
||||
SetAxisState(static_cast<Axis>(axis_code), u8_value);
|
||||
}
|
||||
|
||||
void AnalogController::SetAxisState(Axis axis, u8 value)
|
||||
{
|
||||
if (value != m_axis_state[static_cast<u8>(axis)])
|
||||
System::SetRunaheadReplayFlag();
|
||||
|
||||
m_axis_state[static_cast<u8>(axis)] = value;
|
||||
}
|
||||
|
||||
bool AnalogController::GetButtonState(s32 button_code) const
|
||||
{
|
||||
if (button_code < 0 || button_code >= static_cast<s32>(Button::Analog))
|
||||
return false;
|
||||
|
||||
const u16 bit = u16(1) << static_cast<u8>(button_code);
|
||||
return ((m_button_state & bit) == 0);
|
||||
}
|
||||
|
||||
void AnalogController::SetButtonState(Button button, bool pressed)
|
||||
{
|
||||
if (button == Button::Analog)
|
||||
if (index == static_cast<s32>(Button::Analog))
|
||||
{
|
||||
// analog toggle
|
||||
if (pressed)
|
||||
if (value >= 0.5f)
|
||||
{
|
||||
if (m_command == Command::Idle)
|
||||
ProcessAnalogModeToggle();
|
||||
|
@ -163,10 +138,58 @@ void AnalogController::SetButtonState(Button button, bool pressed)
|
|||
|
||||
return;
|
||||
}
|
||||
else if (index >= static_cast<u32>(Button::Count))
|
||||
{
|
||||
const u32 sub_index = index - static_cast<u32>(Button::Count);
|
||||
if (sub_index >= static_cast<u32>(m_half_axis_state.size()))
|
||||
return;
|
||||
|
||||
const u16 bit = u16(1) << static_cast<u8>(button);
|
||||
value = ApplyAnalogDeadzoneSensitivity(m_analog_deadzone, m_analog_sensitivity, value);
|
||||
const u8 u8_value = static_cast<u8>(std::clamp(value * 255.0f, 0.0f, 255.0f));
|
||||
if (u8_value == m_half_axis_state[sub_index])
|
||||
return;
|
||||
|
||||
if (pressed)
|
||||
m_half_axis_state[sub_index] = u8_value;
|
||||
System::SetRunaheadReplayFlag();
|
||||
|
||||
#define MERGE(pos, neg) \
|
||||
((m_half_axis_state[static_cast<u32>(pos)] != 0) ? (127u + ((m_half_axis_state[static_cast<u32>(pos)] + 1u) / 2u)) : \
|
||||
(127u - (m_half_axis_state[static_cast<u32>(neg)] / 2u)))
|
||||
|
||||
switch (static_cast<HalfAxis>(sub_index))
|
||||
{
|
||||
case HalfAxis::LLeft:
|
||||
case HalfAxis::LRight:
|
||||
m_axis_state[static_cast<u8>(Axis::LeftX)] = MERGE(HalfAxis::LRight, HalfAxis::LLeft);
|
||||
break;
|
||||
|
||||
case HalfAxis::LDown:
|
||||
case HalfAxis::LUp:
|
||||
m_axis_state[static_cast<u8>(Axis::LeftY)] = MERGE(HalfAxis::LDown, HalfAxis::LUp);
|
||||
break;
|
||||
|
||||
case HalfAxis::RLeft:
|
||||
case HalfAxis::RRight:
|
||||
m_axis_state[static_cast<u8>(Axis::RightX)] = MERGE(HalfAxis::RRight, HalfAxis::RLeft);
|
||||
break;
|
||||
|
||||
case HalfAxis::RDown:
|
||||
case HalfAxis::RUp:
|
||||
m_axis_state[static_cast<u8>(Axis::RightY)] = MERGE(HalfAxis::RDown, HalfAxis::RUp);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#undef MERGE
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const u16 bit = u16(1) << static_cast<u8>(index);
|
||||
|
||||
if (value >= 0.5f)
|
||||
{
|
||||
if (m_button_state & bit)
|
||||
System::SetRunaheadReplayFlag();
|
||||
|
@ -182,14 +205,6 @@ void AnalogController::SetButtonState(Button button, bool pressed)
|
|||
}
|
||||
}
|
||||
|
||||
void AnalogController::SetButtonState(s32 button_code, bool pressed)
|
||||
{
|
||||
if (button_code < 0 || button_code >= static_cast<s32>(Button::Count))
|
||||
return;
|
||||
|
||||
SetButtonState(static_cast<Button>(button_code), pressed);
|
||||
}
|
||||
|
||||
u32 AnalogController::GetButtonStateBits() const
|
||||
{
|
||||
// flip bits, native data is active low
|
||||
|
@ -202,26 +217,6 @@ std::optional<u32> AnalogController::GetAnalogInputBytes() const
|
|||
m_axis_state[static_cast<size_t>(Axis::RightY)] << 8 | m_axis_state[static_cast<size_t>(Axis::RightX)];
|
||||
}
|
||||
|
||||
u32 AnalogController::GetVibrationMotorCount() const
|
||||
{
|
||||
return NUM_MOTORS;
|
||||
}
|
||||
|
||||
float AnalogController::GetVibrationMotorStrength(u32 motor)
|
||||
{
|
||||
DebugAssert(motor < NUM_MOTORS);
|
||||
if (m_motor_state[motor] == 0)
|
||||
return 0.0f;
|
||||
|
||||
// Curve from https://github.com/KrossX/Pokopom/blob/master/Pokopom/Input_XInput.cpp#L210
|
||||
const double x =
|
||||
static_cast<double>(std::min<u32>(static_cast<u32>(m_motor_state[motor]) + static_cast<u32>(m_rumble_bias), 255));
|
||||
const double strength = 0.006474549734772402 * std::pow(x, 3.0) - 1.258165252213538 * std::pow(x, 2.0) +
|
||||
156.82454281087692 * x + 3.637978807091713e-11;
|
||||
|
||||
return static_cast<float>(strength / 65535.0);
|
||||
}
|
||||
|
||||
void AnalogController::ResetTransferState()
|
||||
{
|
||||
if (m_analog_toggle_queued)
|
||||
|
@ -240,11 +235,11 @@ void AnalogController::SetAnalogMode(bool enabled)
|
|||
return;
|
||||
|
||||
Log_InfoPrintf("Controller %u switched to %s mode.", m_index + 1u, enabled ? "analog" : "digital");
|
||||
g_host_interface->AddFormattedOSDMessage(
|
||||
5.0f,
|
||||
enabled ? g_host_interface->TranslateString("AnalogController", "Controller %u switched to analog mode.") :
|
||||
g_host_interface->TranslateString("AnalogController", "Controller %u switched to digital mode."),
|
||||
m_index + 1u);
|
||||
Host::AddFormattedOSDMessage(5.0f,
|
||||
enabled ?
|
||||
Host::TranslateString("AnalogController", "Controller %u switched to analog mode.") :
|
||||
Host::TranslateString("AnalogController", "Controller %u switched to digital mode."),
|
||||
m_index + 1u);
|
||||
m_analog_mode = enabled;
|
||||
}
|
||||
|
||||
|
@ -252,11 +247,10 @@ void AnalogController::ProcessAnalogModeToggle()
|
|||
{
|
||||
if (m_analog_locked)
|
||||
{
|
||||
g_host_interface->AddFormattedOSDMessage(
|
||||
Host::AddFormattedOSDMessage(
|
||||
5.0f,
|
||||
m_analog_mode ?
|
||||
g_host_interface->TranslateString("AnalogController", "Controller %u is locked to analog mode by the game.") :
|
||||
g_host_interface->TranslateString("AnalogController", "Controller %u is locked to digital mode by the game."),
|
||||
m_analog_mode ? Host::TranslateString("AnalogController", "Controller %u is locked to analog mode by the game.") :
|
||||
Host::TranslateString("AnalogController", "Controller %u is locked to digital mode by the game."),
|
||||
m_index + 1u);
|
||||
}
|
||||
else
|
||||
|
@ -269,10 +263,32 @@ void AnalogController::ProcessAnalogModeToggle()
|
|||
}
|
||||
}
|
||||
|
||||
void AnalogController::SetMotorState(u8 motor, u8 value)
|
||||
void AnalogController::SetMotorState(u32 motor, u8 value)
|
||||
{
|
||||
DebugAssert(motor < NUM_MOTORS);
|
||||
m_motor_state[motor] = value;
|
||||
if (m_motor_state[motor] != value)
|
||||
{
|
||||
m_motor_state[motor] = value;
|
||||
UpdateHostVibration();
|
||||
}
|
||||
}
|
||||
|
||||
void AnalogController::UpdateHostVibration()
|
||||
{
|
||||
std::array<float, NUM_MOTORS> hvalues;
|
||||
for (u32 motor = 0; motor < NUM_MOTORS; motor++)
|
||||
{
|
||||
// Curve from https://github.com/KrossX/Pokopom/blob/master/Pokopom/Input_XInput.cpp#L210
|
||||
const u8 state = m_motor_state[motor];
|
||||
const double x =
|
||||
static_cast<double>(std::min<u32>(state + static_cast<u32>(m_rumble_bias), 255));
|
||||
const double strength = 0.006474549734772402 * std::pow(x, 3.0) - 1.258165252213538 * std::pow(x, 2.0) +
|
||||
156.82454281087692 * x + 3.637978807091713e-11;
|
||||
|
||||
hvalues[motor] = (state != 0) ? static_cast<float>(strength / 65535.0) : 0.0f;
|
||||
}
|
||||
|
||||
Host::SetPadVibrationIntensity(m_index, hvalues[0], hvalues[1]);
|
||||
}
|
||||
|
||||
u8 AnalogController::GetExtraButtonMaskLSB() const
|
||||
|
@ -350,7 +366,7 @@ bool AnalogController::Transfer(const u8 data_in, u8* data_out)
|
|||
|
||||
if (data_in == 0x01)
|
||||
{
|
||||
Log_DevPrintf("ACK controller access");
|
||||
Log_DebugPrintf("ACK controller access");
|
||||
m_command = Command::Ready;
|
||||
return true;
|
||||
}
|
||||
|
@ -689,10 +705,10 @@ bool AnalogController::Transfer(const u8 data_in, u8* data_out)
|
|||
{
|
||||
m_command = Command::Idle;
|
||||
|
||||
Log_DevPrintf("Rx: %02x %02x %02x %02x %02x %02x %02x %02x", m_rx_buffer[0], m_rx_buffer[1], m_rx_buffer[2],
|
||||
m_rx_buffer[3], m_rx_buffer[4], m_rx_buffer[5], m_rx_buffer[6], m_rx_buffer[7]);
|
||||
Log_DevPrintf("Tx: %02x %02x %02x %02x %02x %02x %02x %02x", m_tx_buffer[0], m_tx_buffer[1], m_tx_buffer[2],
|
||||
m_tx_buffer[3], m_tx_buffer[4], m_tx_buffer[5], m_tx_buffer[6], m_tx_buffer[7]);
|
||||
Log_DebugPrintf("Rx: %02x %02x %02x %02x %02x %02x %02x %02x", m_rx_buffer[0], m_rx_buffer[1], m_rx_buffer[2],
|
||||
m_rx_buffer[3], m_rx_buffer[4], m_rx_buffer[5], m_rx_buffer[6], m_rx_buffer[7]);
|
||||
Log_DebugPrintf("Tx: %02x %02x %02x %02x %02x %02x %02x %02x", m_tx_buffer[0], m_tx_buffer[1], m_tx_buffer[2],
|
||||
m_tx_buffer[3], m_tx_buffer[4], m_tx_buffer[5], m_tx_buffer[6], m_tx_buffer[7]);
|
||||
|
||||
m_rx_buffer.fill(0x00);
|
||||
m_tx_buffer.fill(0x00);
|
||||
|
@ -706,122 +722,89 @@ std::unique_ptr<AnalogController> AnalogController::Create(u32 index)
|
|||
return std::make_unique<AnalogController>(index);
|
||||
}
|
||||
|
||||
std::optional<s32> AnalogController::StaticGetAxisCodeByName(std::string_view axis_name)
|
||||
{
|
||||
#define AXIS(name) \
|
||||
if (axis_name == #name) \
|
||||
static const Controller::ControllerBindingInfo s_binding_info[] = {
|
||||
#define BUTTON(name, display_name, button, genb) \
|
||||
{ \
|
||||
return static_cast<s32>(ZeroExtend32(static_cast<u8>(Axis::name))); \
|
||||
name, display_name, static_cast<u32>(button), Controller::ControllerBindingType::Button, genb \
|
||||
}
|
||||
#define AXIS(name, display_name, halfaxis, genb) \
|
||||
{ \
|
||||
name, display_name, static_cast<u32>(AnalogController::Button::Count) + static_cast<u32>(halfaxis), \
|
||||
Controller::ControllerBindingType::HalfAxis, genb \
|
||||
}
|
||||
|
||||
AXIS(LeftX);
|
||||
AXIS(LeftY);
|
||||
AXIS(RightX);
|
||||
AXIS(RightY);
|
||||
BUTTON("Up", "D-Pad Up", AnalogController::Button::Up, GenericInputBinding::DPadUp),
|
||||
BUTTON("Right", "D-Pad Right", AnalogController::Button::Right, GenericInputBinding::DPadRight),
|
||||
BUTTON("Down", "D-Pad Down", AnalogController::Button::Down, GenericInputBinding::DPadDown),
|
||||
BUTTON("Left", "D-Pad Left", AnalogController::Button::Left, GenericInputBinding::DPadLeft),
|
||||
BUTTON("Triangle", "Triangle", AnalogController::Button::Triangle, GenericInputBinding::Triangle),
|
||||
BUTTON("Circle", "Circle", AnalogController::Button::Circle, GenericInputBinding::Circle),
|
||||
BUTTON("Cross", "Cross", AnalogController::Button::Cross, GenericInputBinding::Cross),
|
||||
BUTTON("Square", "Square", AnalogController::Button::Square, GenericInputBinding::Square),
|
||||
BUTTON("Select", "Select", AnalogController::Button::Select, GenericInputBinding::Select),
|
||||
BUTTON("Start", "Start", AnalogController::Button::Start, GenericInputBinding::Start),
|
||||
BUTTON("Analog", "Analog Toggle", AnalogController::Button::Analog, GenericInputBinding::System),
|
||||
BUTTON("L1", "L1", AnalogController::Button::L1, GenericInputBinding::L1),
|
||||
BUTTON("R1", "R1", AnalogController::Button::R1, GenericInputBinding::R1),
|
||||
BUTTON("L2", "L2", AnalogController::Button::L2, GenericInputBinding::L2),
|
||||
BUTTON("R2", "R2", AnalogController::Button::R2, GenericInputBinding::R2),
|
||||
BUTTON("L3", "L3", AnalogController::Button::L3, GenericInputBinding::L3),
|
||||
BUTTON("R3", "R3", AnalogController::Button::R3, GenericInputBinding::R3),
|
||||
|
||||
return std::nullopt;
|
||||
AXIS("LLeft", "Left Stick Left", AnalogController::HalfAxis::LLeft, GenericInputBinding::LeftStickLeft),
|
||||
AXIS("LRight", "Left Stick Right", AnalogController::HalfAxis::LRight, GenericInputBinding::LeftStickRight),
|
||||
AXIS("LDown", "Left Stick Down", AnalogController::HalfAxis::LDown, GenericInputBinding::LeftStickDown),
|
||||
AXIS("LUp", "Left Stick Up", AnalogController::HalfAxis::LUp, GenericInputBinding::LeftStickUp),
|
||||
AXIS("RLeft", "Right Stick Left", AnalogController::HalfAxis::RLeft, GenericInputBinding::RightStickLeft),
|
||||
AXIS("RRight", "Right Stick Right", AnalogController::HalfAxis::RRight, GenericInputBinding::RightStickRight),
|
||||
AXIS("RDown", "Right Stick Down", AnalogController::HalfAxis::RDown, GenericInputBinding::RightStickDown),
|
||||
AXIS("RUp", "Right Stick Up", AnalogController::HalfAxis::RUp, GenericInputBinding::RightStickUp),
|
||||
|
||||
#undef AXIS
|
||||
}
|
||||
|
||||
std::optional<s32> AnalogController::StaticGetButtonCodeByName(std::string_view button_name)
|
||||
{
|
||||
#define BUTTON(name) \
|
||||
if (button_name == #name) \
|
||||
{ \
|
||||
return static_cast<s32>(ZeroExtend32(static_cast<u8>(Button::name))); \
|
||||
}
|
||||
|
||||
BUTTON(Select);
|
||||
BUTTON(L3);
|
||||
BUTTON(R3);
|
||||
BUTTON(Start);
|
||||
BUTTON(Up);
|
||||
BUTTON(Right);
|
||||
BUTTON(Down);
|
||||
BUTTON(Left);
|
||||
BUTTON(L2);
|
||||
BUTTON(R2);
|
||||
BUTTON(L1);
|
||||
BUTTON(R1);
|
||||
BUTTON(Triangle);
|
||||
BUTTON(Circle);
|
||||
BUTTON(Cross);
|
||||
BUTTON(Square);
|
||||
BUTTON(Analog);
|
||||
|
||||
return std::nullopt;
|
||||
|
||||
#undef BUTTON
|
||||
}
|
||||
};
|
||||
|
||||
Controller::AxisList AnalogController::StaticGetAxisNames()
|
||||
static const SettingInfo s_settings[] = {
|
||||
{SettingInfo::Type::Boolean, "ForceAnalogOnReset", TRANSLATABLE("AnalogController", "Force Analog Mode on Reset"),
|
||||
TRANSLATABLE("AnalogController", "Forces the controller to analog mode when the console is reset/powered on. May "
|
||||
"cause issues with games, so it is recommended to leave this option off."),
|
||||
"true"},
|
||||
{SettingInfo::Type::Boolean, "AnalogDPadInDigitalMode",
|
||||
TRANSLATABLE("AnalogController", "Use Analog Sticks for D-Pad in Digital Mode"),
|
||||
TRANSLATABLE("AnalogController",
|
||||
"Allows you to use the analog sticks to control the d-pad in digital mode, as well as the buttons."),
|
||||
"true"},
|
||||
{SettingInfo::Type::Float, "AnalogDeadzone", TRANSLATABLE("AnalogController", "Analog Deadzone"),
|
||||
TRANSLATABLE("AnalogController",
|
||||
"Sets the analog stick deadzone, i.e. the fraction of the stick movement which will be ignored."),
|
||||
"0.00f", "0.00f", "1.00f", "0.01f"},
|
||||
{SettingInfo::Type::Float, "AnalogSensitivity", TRANSLATABLE("AnalogController", "Analog Sensitivity"),
|
||||
TRANSLATABLE(
|
||||
"AnalogController",
|
||||
"Sets the analog stick axis scaling factor. A value between 1.30 and 1.40 is recommended when using recent "
|
||||
"controllers, e.g. DualShock 4, Xbox One Controller."),
|
||||
"1.33f", "0.01f", "2.00f", "0.01f"},
|
||||
{SettingInfo::Type::Integer, "VibrationBias", TRANSLATABLE("AnalogController", "Vibration Bias"),
|
||||
TRANSLATABLE("AnalogController", "Sets the rumble bias value. If rumble in some games is too weak or not "
|
||||
"functioning, try increasing this value."),
|
||||
"8", "0", "255", "1"}};
|
||||
|
||||
const Controller::ControllerInfo AnalogController::INFO = {ControllerType::AnalogController,
|
||||
"AnalogController",
|
||||
TRANSLATABLE("ControllerType", "Analog Controller"),
|
||||
s_binding_info,
|
||||
countof(s_binding_info),
|
||||
s_settings,
|
||||
countof(s_settings),
|
||||
Controller::VibrationCapabilities::LargeSmallMotors};
|
||||
|
||||
void AnalogController::LoadSettings(SettingsInterface& si, const char* section)
|
||||
{
|
||||
return {{TRANSLATABLE("AnalogController", "LeftX"), static_cast<s32>(Axis::LeftX), AxisType::Full},
|
||||
{TRANSLATABLE("AnalogController", "LeftY"), static_cast<s32>(Axis::LeftY), AxisType::Full},
|
||||
{TRANSLATABLE("AnalogController", "RightX"), static_cast<s32>(Axis::RightX), AxisType::Full},
|
||||
{TRANSLATABLE("AnalogController", "RightY"), static_cast<s32>(Axis::RightY), AxisType::Full}};
|
||||
}
|
||||
|
||||
Controller::ButtonList AnalogController::StaticGetButtonNames()
|
||||
{
|
||||
return {{TRANSLATABLE("AnalogController", "Up"), static_cast<s32>(Button::Up)},
|
||||
{TRANSLATABLE("AnalogController", "Down"), static_cast<s32>(Button::Down)},
|
||||
{TRANSLATABLE("AnalogController", "Left"), static_cast<s32>(Button::Left)},
|
||||
{TRANSLATABLE("AnalogController", "Right"), static_cast<s32>(Button::Right)},
|
||||
{TRANSLATABLE("AnalogController", "Select"), static_cast<s32>(Button::Select)},
|
||||
{TRANSLATABLE("AnalogController", "Start"), static_cast<s32>(Button::Start)},
|
||||
{TRANSLATABLE("AnalogController", "Triangle"), static_cast<s32>(Button::Triangle)},
|
||||
{TRANSLATABLE("AnalogController", "Cross"), static_cast<s32>(Button::Cross)},
|
||||
{TRANSLATABLE("AnalogController", "Circle"), static_cast<s32>(Button::Circle)},
|
||||
{TRANSLATABLE("AnalogController", "Square"), static_cast<s32>(Button::Square)},
|
||||
{TRANSLATABLE("AnalogController", "L1"), static_cast<s32>(Button::L1)},
|
||||
{TRANSLATABLE("AnalogController", "L2"), static_cast<s32>(Button::L2)},
|
||||
{TRANSLATABLE("AnalogController", "R1"), static_cast<s32>(Button::R1)},
|
||||
{TRANSLATABLE("AnalogController", "R2"), static_cast<s32>(Button::R2)},
|
||||
{TRANSLATABLE("AnalogController", "L3"), static_cast<s32>(Button::L3)},
|
||||
{TRANSLATABLE("AnalogController", "R3"), static_cast<s32>(Button::R3)},
|
||||
{TRANSLATABLE("AnalogController", "Analog"), static_cast<s32>(Button::Analog)}};
|
||||
}
|
||||
|
||||
u32 AnalogController::StaticGetVibrationMotorCount()
|
||||
{
|
||||
return NUM_MOTORS;
|
||||
}
|
||||
|
||||
Controller::SettingList AnalogController::StaticGetSettings()
|
||||
{
|
||||
static constexpr std::array<SettingInfo, 4> settings = {
|
||||
{{SettingInfo::Type::Boolean, "ForceAnalogOnReset", TRANSLATABLE("AnalogController", "Force Analog Mode on Reset"),
|
||||
TRANSLATABLE("AnalogController", "Forces the controller to analog mode when the console is reset/powered on. May "
|
||||
"cause issues with games, so it is recommended to leave this option off."),
|
||||
"false"},
|
||||
{SettingInfo::Type::Boolean, "AnalogDPadInDigitalMode",
|
||||
TRANSLATABLE("AnalogController", "Use Analog Sticks for D-Pad in Digital Mode"),
|
||||
TRANSLATABLE("AnalogController",
|
||||
"Allows you to use the analog sticks to control the d-pad in digital mode, as well as the buttons."),
|
||||
"false"},
|
||||
{SettingInfo::Type::Float, "AxisScale", TRANSLATABLE("AnalogController", "Analog Axis Scale"),
|
||||
TRANSLATABLE(
|
||||
"AnalogController",
|
||||
"Sets the analog stick axis scaling factor. A value between 1.30 and 1.40 is recommended when using recent "
|
||||
"controllers, e.g. DualShock 4, Xbox One Controller."),
|
||||
"1.00f", "0.01f", "1.50f", "0.01f"},
|
||||
{SettingInfo::Type::Integer, "VibrationBias", TRANSLATABLE("AnalogController", "Vibration Bias"),
|
||||
TRANSLATABLE("AnalogController", "Sets the rumble bias value. If rumble in some games is too weak or not "
|
||||
"functioning, try increasing this value."),
|
||||
"8", "0", "255", "1"}}};
|
||||
|
||||
return SettingList(settings.begin(), settings.end());
|
||||
}
|
||||
|
||||
void AnalogController::LoadSettings(const char* section)
|
||||
{
|
||||
Controller::LoadSettings(section);
|
||||
m_force_analog_on_reset = g_host_interface->GetBoolSettingValue(section, "ForceAnalogOnReset", false);
|
||||
m_analog_dpad_in_digital_mode = g_host_interface->GetBoolSettingValue(section, "AnalogDPadInDigitalMode", false);
|
||||
m_axis_scale =
|
||||
std::clamp(std::abs(g_host_interface->GetFloatSettingValue(section, "AxisScale", 1.00f)), 0.01f, 1.50f);
|
||||
m_rumble_bias =
|
||||
static_cast<u8>(std::min<u32>(g_host_interface->GetIntSettingValue(section, "VibrationBias", 8), 255));
|
||||
Controller::LoadSettings(si, section);
|
||||
m_force_analog_on_reset = si.GetBoolValue(section, "ForceAnalogOnReset", true);
|
||||
m_analog_dpad_in_digital_mode = si.GetBoolValue(section, "AnalogDPadInDigitalMode", true);
|
||||
m_analog_deadzone = std::clamp(si.GetFloatValue(section, "AnalogDeadzone", DEFAULT_STICK_DEADZONE), 0.0f, 1.0f);
|
||||
m_analog_sensitivity =
|
||||
std::clamp(si.GetFloatValue(section, "AnalogSensitivity", DEFAULT_STICK_SENSITIVITY), 0.01f, 3.0f);
|
||||
m_rumble_bias = static_cast<u8>(std::min<u32>(si.GetIntValue(section, "VibrationBias", 8), 255));
|
||||
}
|
||||
|
|
|
@ -39,43 +39,42 @@ public:
|
|||
Count
|
||||
};
|
||||
|
||||
enum class HalfAxis : u8
|
||||
{
|
||||
LLeft,
|
||||
LRight,
|
||||
LDown,
|
||||
LUp,
|
||||
RLeft,
|
||||
RRight,
|
||||
RDown,
|
||||
RUp,
|
||||
Count
|
||||
};
|
||||
|
||||
static constexpr u8 NUM_MOTORS = 2;
|
||||
|
||||
static const Controller::ControllerInfo INFO;
|
||||
|
||||
AnalogController(u32 index);
|
||||
~AnalogController() override;
|
||||
|
||||
static std::unique_ptr<AnalogController> Create(u32 index);
|
||||
static std::optional<s32> StaticGetAxisCodeByName(std::string_view axis_name);
|
||||
static std::optional<s32> StaticGetButtonCodeByName(std::string_view button_name);
|
||||
static AxisList StaticGetAxisNames();
|
||||
static ButtonList StaticGetButtonNames();
|
||||
static u32 StaticGetVibrationMotorCount();
|
||||
static SettingList StaticGetSettings();
|
||||
|
||||
ControllerType GetType() const override;
|
||||
std::optional<s32> GetAxisCodeByName(std::string_view axis_name) const override;
|
||||
std::optional<s32> GetButtonCodeByName(std::string_view button_name) const override;
|
||||
|
||||
void Reset() override;
|
||||
bool DoState(StateWrapper& sw, bool ignore_input_state) override;
|
||||
|
||||
float GetAxisState(s32 axis_code) const override;
|
||||
void SetAxisState(s32 axis_code, float value) override;
|
||||
bool GetButtonState(s32 button_code) const override;
|
||||
void SetButtonState(s32 button_code, bool pressed) override;
|
||||
float GetBindState(u32 index) const override;
|
||||
void SetBindState(u32 index, float value) override;
|
||||
u32 GetButtonStateBits() const override;
|
||||
std::optional<u32> GetAnalogInputBytes() const override;
|
||||
|
||||
void ResetTransferState() override;
|
||||
bool Transfer(const u8 data_in, u8* data_out) override;
|
||||
|
||||
void SetAxisState(Axis axis, u8 value);
|
||||
void SetButtonState(Button button, bool pressed);
|
||||
|
||||
u32 GetVibrationMotorCount() const override;
|
||||
float GetVibrationMotorStrength(u32 motor) override;
|
||||
|
||||
void LoadSettings(const char* section) override;
|
||||
void LoadSettings(SettingsInterface& si, const char* section) override;
|
||||
|
||||
private:
|
||||
using MotorState = std::array<u8, NUM_MOTORS>;
|
||||
|
@ -111,16 +110,16 @@ private:
|
|||
|
||||
void SetAnalogMode(bool enabled);
|
||||
void ProcessAnalogModeToggle();
|
||||
void SetMotorState(u8 motor, u8 value);
|
||||
void SetMotorState(u32 motor, u8 value);
|
||||
void UpdateHostVibration();
|
||||
u8 GetExtraButtonMaskLSB() const;
|
||||
void ResetRumbleConfig();
|
||||
void SetMotorStateForConfigIndex(int index, u8 value);
|
||||
|
||||
u32 m_index;
|
||||
|
||||
bool m_force_analog_on_reset = false;
|
||||
bool m_analog_dpad_in_digital_mode = false;
|
||||
float m_axis_scale = 1.00f;
|
||||
float m_analog_deadzone = 0.0f;
|
||||
float m_analog_sensitivity = 1.33f;
|
||||
u8 m_rumble_bias = 8;
|
||||
|
||||
bool m_analog_mode = false;
|
||||
|
@ -151,6 +150,9 @@ private:
|
|||
|
||||
MotorState m_motor_state{};
|
||||
|
||||
// both directions of axis state, merged to m_axis_state
|
||||
std::array<u8, static_cast<u32>(HalfAxis::Count)> m_half_axis_state{};
|
||||
|
||||
// Member variables that are no longer used, but kept and serialized for compatibility with older save states
|
||||
u8 m_command_param = 0;
|
||||
bool m_legacy_rumble_unlocked = false;
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
#include "analog_joystick.h"
|
||||
#include "common/log.h"
|
||||
#include "common/string_util.h"
|
||||
#include "host_interface.h"
|
||||
#include "host.h"
|
||||
#include "system.h"
|
||||
#include "util/state_wrapper.h"
|
||||
#include <cmath>
|
||||
Log_SetChannel(AnalogJoystick);
|
||||
|
||||
AnalogJoystick::AnalogJoystick(u32 index)
|
||||
AnalogJoystick::AnalogJoystick(u32 index) : Controller(index)
|
||||
{
|
||||
m_index = index;
|
||||
m_axis_state.fill(0x80);
|
||||
Reset();
|
||||
}
|
||||
|
@ -50,82 +49,101 @@ bool AnalogJoystick::DoState(StateWrapper& sw, bool apply_input_state)
|
|||
|
||||
if (sw.IsReading() && (old_analog_mode != m_analog_mode))
|
||||
{
|
||||
g_host_interface->AddFormattedOSDMessage(
|
||||
5.0f,
|
||||
m_analog_mode ? g_host_interface->TranslateString("AnalogJoystick", "Controller %u switched to analog mode.") :
|
||||
g_host_interface->TranslateString("AnalogJoystick", "Controller %u switched to digital mode."),
|
||||
m_index + 1u);
|
||||
Host::AddFormattedOSDMessage(5.0f,
|
||||
m_analog_mode ?
|
||||
Host::TranslateString("AnalogJoystick", "Controller %u switched to analog mode.") :
|
||||
Host::TranslateString("AnalogJoystick", "Controller %u switched to digital mode."),
|
||||
m_index + 1u);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<s32> AnalogJoystick::GetAxisCodeByName(std::string_view axis_name) const
|
||||
float AnalogJoystick::GetBindState(u32 index) const
|
||||
{
|
||||
return StaticGetAxisCodeByName(axis_name);
|
||||
}
|
||||
|
||||
std::optional<s32> AnalogJoystick::GetButtonCodeByName(std::string_view button_name) const
|
||||
{
|
||||
return StaticGetButtonCodeByName(button_name);
|
||||
}
|
||||
|
||||
float AnalogJoystick::GetAxisState(s32 axis_code) const
|
||||
{
|
||||
if (axis_code < 0 || axis_code >= static_cast<s32>(Axis::Count))
|
||||
return 0.0f;
|
||||
|
||||
// 0..255 -> -1..1
|
||||
const float value = (((static_cast<float>(m_axis_state[static_cast<s32>(axis_code)]) / 255.0f) * 2.0f) - 1.0f);
|
||||
return std::clamp(value / m_axis_scale, -1.0f, 1.0f);
|
||||
}
|
||||
|
||||
void AnalogJoystick::SetAxisState(s32 axis_code, float value)
|
||||
{
|
||||
if (axis_code < 0 || axis_code >= static_cast<s32>(Axis::Count))
|
||||
return;
|
||||
|
||||
// -1..1 -> 0..255
|
||||
const float scaled_value = std::clamp(value * m_axis_scale, -1.0f, 1.0f);
|
||||
const u8 u8_value = static_cast<u8>(std::clamp(std::round(((scaled_value + 1.0f) / 2.0f) * 255.0f), 0.0f, 255.0f));
|
||||
|
||||
SetAxisState(static_cast<Axis>(axis_code), u8_value);
|
||||
}
|
||||
|
||||
void AnalogJoystick::SetAxisState(Axis axis, u8 value)
|
||||
{
|
||||
if (m_axis_state[static_cast<u8>(axis)] != value)
|
||||
System::SetRunaheadReplayFlag();
|
||||
|
||||
m_axis_state[static_cast<u8>(axis)] = value;
|
||||
}
|
||||
|
||||
bool AnalogJoystick::GetButtonState(s32 button_code) const
|
||||
{
|
||||
if (button_code < 0 || button_code >= static_cast<s32>(Button::Count))
|
||||
return false;
|
||||
|
||||
const u16 bit = u16(1) << static_cast<u8>(button_code);
|
||||
return ((m_button_state & bit) == 0);
|
||||
}
|
||||
|
||||
void AnalogJoystick::SetButtonState(Button button, bool pressed)
|
||||
{
|
||||
if (button == Button::Mode)
|
||||
if (index >= static_cast<u32>(Button::Count))
|
||||
{
|
||||
if (pressed)
|
||||
const u32 sub_index = index - static_cast<u32>(Button::Count);
|
||||
if (sub_index >= static_cast<u32>(m_half_axis_state.size()))
|
||||
return 0.0f;
|
||||
|
||||
return static_cast<float>(m_half_axis_state[sub_index]) * (1.0f / 255.0f);
|
||||
}
|
||||
else if (index < static_cast<u32>(Button::Mode))
|
||||
{
|
||||
return static_cast<float>(((m_button_state >> index) & 1u) ^ 1u);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void AnalogJoystick::SetBindState(u32 index, float value)
|
||||
{
|
||||
if (index == static_cast<s32>(Button::Mode))
|
||||
{
|
||||
// analog toggle
|
||||
if (value >= 0.5f)
|
||||
ToggleAnalogMode();
|
||||
|
||||
return;
|
||||
}
|
||||
else if (index >= static_cast<u32>(Button::Count))
|
||||
{
|
||||
const u32 sub_index = index - static_cast<u32>(Button::Count);
|
||||
if (sub_index >= static_cast<u32>(m_half_axis_state.size()))
|
||||
return;
|
||||
|
||||
const u16 bit = u16(1) << static_cast<u8>(button);
|
||||
value = ApplyAnalogDeadzoneSensitivity(m_analog_deadzone, m_analog_sensitivity, value);
|
||||
const u8 u8_value = static_cast<u8>(std::clamp(value * 255.0f, 0.0f, 255.0f));
|
||||
if (u8_value != m_half_axis_state[sub_index])
|
||||
System::SetRunaheadReplayFlag();
|
||||
|
||||
if (pressed)
|
||||
m_half_axis_state[sub_index] = u8_value;
|
||||
|
||||
#define MERGE(pos, neg) \
|
||||
((m_half_axis_state[static_cast<u32>(pos)] != 0) ? (127u + ((m_half_axis_state[static_cast<u32>(pos)] + 1u) / 2u)) : \
|
||||
(127u - (m_half_axis_state[static_cast<u32>(neg)] / 2u)))
|
||||
|
||||
switch (static_cast<HalfAxis>(sub_index))
|
||||
{
|
||||
case HalfAxis::LLeft:
|
||||
case HalfAxis::LRight:
|
||||
m_axis_state[static_cast<u8>(Axis::LeftX)] = MERGE(HalfAxis::LRight, HalfAxis::LLeft);
|
||||
break;
|
||||
|
||||
case HalfAxis::LDown:
|
||||
case HalfAxis::LUp:
|
||||
m_axis_state[static_cast<u8>(Axis::LeftY)] = MERGE(HalfAxis::LDown, HalfAxis::LUp);
|
||||
break;
|
||||
|
||||
case HalfAxis::RLeft:
|
||||
case HalfAxis::RRight:
|
||||
m_axis_state[static_cast<u8>(Axis::RightX)] = MERGE(HalfAxis::RRight, HalfAxis::RLeft);
|
||||
break;
|
||||
|
||||
case HalfAxis::RDown:
|
||||
case HalfAxis::RUp:
|
||||
m_axis_state[static_cast<u8>(Axis::RightY)] = MERGE(HalfAxis::RDown, HalfAxis::RUp);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#undef MERGE
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const u16 bit = u16(1) << static_cast<u8>(index);
|
||||
|
||||
if (value >= 0.5f)
|
||||
{
|
||||
if (m_button_state & bit)
|
||||
System::SetRunaheadReplayFlag();
|
||||
|
||||
m_button_state &= ~bit;
|
||||
m_button_state &= ~(bit);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -136,14 +154,6 @@ void AnalogJoystick::SetButtonState(Button button, bool pressed)
|
|||
}
|
||||
}
|
||||
|
||||
void AnalogJoystick::SetButtonState(s32 button_code, bool pressed)
|
||||
{
|
||||
if (button_code < 0 || button_code >= static_cast<s32>(Button::Count))
|
||||
return;
|
||||
|
||||
SetButtonState(static_cast<Button>(button_code), pressed);
|
||||
}
|
||||
|
||||
u32 AnalogJoystick::GetButtonStateBits() const
|
||||
{
|
||||
return m_button_state ^ 0xFFFF;
|
||||
|
@ -173,11 +183,11 @@ void AnalogJoystick::ToggleAnalogMode()
|
|||
m_analog_mode = !m_analog_mode;
|
||||
|
||||
Log_InfoPrintf("Joystick %u switched to %s mode.", m_index + 1u, m_analog_mode ? "analog" : "digital");
|
||||
g_host_interface->AddFormattedOSDMessage(
|
||||
5.0f,
|
||||
m_analog_mode ? g_host_interface->TranslateString("AnalogJoystick", "Controller %u switched to analog mode.") :
|
||||
g_host_interface->TranslateString("AnalogJoystick", "Controller %u switched to digital mode."),
|
||||
m_index + 1u);
|
||||
Host::AddFormattedOSDMessage(5.0f,
|
||||
m_analog_mode ?
|
||||
Host::TranslateString("AnalogJoystick", "Controller %u switched to analog mode.") :
|
||||
Host::TranslateString("AnalogJoystick", "Controller %u switched to digital mode."),
|
||||
m_index + 1u);
|
||||
}
|
||||
|
||||
bool AnalogJoystick::Transfer(const u8 data_in, u8* data_out)
|
||||
|
@ -272,104 +282,73 @@ std::unique_ptr<AnalogJoystick> AnalogJoystick::Create(u32 index)
|
|||
return std::make_unique<AnalogJoystick>(index);
|
||||
}
|
||||
|
||||
std::optional<s32> AnalogJoystick::StaticGetAxisCodeByName(std::string_view axis_name)
|
||||
{
|
||||
#define AXIS(name) \
|
||||
if (axis_name == #name) \
|
||||
static const Controller::ControllerBindingInfo s_binding_info[] = {
|
||||
#define BUTTON(name, display_name, button, genb) \
|
||||
{ \
|
||||
return static_cast<s32>(ZeroExtend32(static_cast<u8>(Axis::name))); \
|
||||
name, display_name, static_cast<u32>(button), Controller::ControllerBindingType::Button, genb \
|
||||
}
|
||||
#define AXIS(name, display_name, halfaxis, genb) \
|
||||
{ \
|
||||
name, display_name, static_cast<u32>(AnalogJoystick::Button::Count) + static_cast<u32>(halfaxis), \
|
||||
Controller::ControllerBindingType::HalfAxis, genb \
|
||||
}
|
||||
|
||||
AXIS(LeftX);
|
||||
AXIS(LeftY);
|
||||
AXIS(RightX);
|
||||
AXIS(RightY);
|
||||
BUTTON("Up", "D-Pad Up", AnalogJoystick::Button::Up, GenericInputBinding::DPadUp),
|
||||
BUTTON("Right", "D-Pad Right", AnalogJoystick::Button::Right, GenericInputBinding::DPadRight),
|
||||
BUTTON("Down", "D-Pad Down", AnalogJoystick::Button::Down, GenericInputBinding::DPadDown),
|
||||
BUTTON("Left", "D-Pad Left", AnalogJoystick::Button::Left, GenericInputBinding::DPadLeft),
|
||||
BUTTON("Triangle", "Triangle", AnalogJoystick::Button::Triangle, GenericInputBinding::Triangle),
|
||||
BUTTON("Circle", "Circle", AnalogJoystick::Button::Circle, GenericInputBinding::Circle),
|
||||
BUTTON("Cross", "Cross", AnalogJoystick::Button::Cross, GenericInputBinding::Cross),
|
||||
BUTTON("Square", "Square", AnalogJoystick::Button::Square, GenericInputBinding::Square),
|
||||
BUTTON("Select", "Select", AnalogJoystick::Button::Select, GenericInputBinding::Select),
|
||||
BUTTON("Start", "Start", AnalogJoystick::Button::Start, GenericInputBinding::Start),
|
||||
BUTTON("Mode", "Mode Toggle", AnalogJoystick::Button::Mode, GenericInputBinding::System),
|
||||
BUTTON("L1", "L1", AnalogJoystick::Button::L1, GenericInputBinding::L1),
|
||||
BUTTON("R1", "R1", AnalogJoystick::Button::R1, GenericInputBinding::R1),
|
||||
BUTTON("L2", "L2", AnalogJoystick::Button::L2, GenericInputBinding::L2),
|
||||
BUTTON("R2", "R2", AnalogJoystick::Button::R2, GenericInputBinding::R2),
|
||||
BUTTON("L3", "L3", AnalogJoystick::Button::L3, GenericInputBinding::L3),
|
||||
BUTTON("R3", "R3", AnalogJoystick::Button::R3, GenericInputBinding::R3),
|
||||
|
||||
return std::nullopt;
|
||||
AXIS("LLeft", "Left Stick Left", AnalogJoystick::HalfAxis::LLeft, GenericInputBinding::LeftStickLeft),
|
||||
AXIS("LRight", "Left Stick Right", AnalogJoystick::HalfAxis::LRight, GenericInputBinding::LeftStickRight),
|
||||
AXIS("LDown", "Left Stick Down", AnalogJoystick::HalfAxis::LDown, GenericInputBinding::LeftStickDown),
|
||||
AXIS("LUp", "Left Stick Up", AnalogJoystick::HalfAxis::LUp, GenericInputBinding::LeftStickUp),
|
||||
AXIS("RLeft", "Right Stick Left", AnalogJoystick::HalfAxis::RLeft, GenericInputBinding::RightStickLeft),
|
||||
AXIS("RRight", "Right Stick Right", AnalogJoystick::HalfAxis::RRight, GenericInputBinding::RightStickRight),
|
||||
AXIS("RDown", "Right Stick Down", AnalogJoystick::HalfAxis::RDown, GenericInputBinding::RightStickDown),
|
||||
AXIS("RUp", "Right Stick Up", AnalogJoystick::HalfAxis::RUp, GenericInputBinding::RightStickUp),
|
||||
|
||||
#undef AXIS
|
||||
}
|
||||
|
||||
std::optional<s32> AnalogJoystick::StaticGetButtonCodeByName(std::string_view button_name)
|
||||
{
|
||||
#define BUTTON(name) \
|
||||
if (button_name == #name) \
|
||||
{ \
|
||||
return static_cast<s32>(ZeroExtend32(static_cast<u8>(Button::name))); \
|
||||
}
|
||||
|
||||
BUTTON(Select);
|
||||
BUTTON(L3);
|
||||
BUTTON(R3);
|
||||
BUTTON(Start);
|
||||
BUTTON(Up);
|
||||
BUTTON(Right);
|
||||
BUTTON(Down);
|
||||
BUTTON(Left);
|
||||
BUTTON(L2);
|
||||
BUTTON(R2);
|
||||
BUTTON(L1);
|
||||
BUTTON(R1);
|
||||
BUTTON(Triangle);
|
||||
BUTTON(Circle);
|
||||
BUTTON(Cross);
|
||||
BUTTON(Square);
|
||||
BUTTON(Mode);
|
||||
|
||||
return std::nullopt;
|
||||
|
||||
#undef BUTTON
|
||||
}
|
||||
};
|
||||
|
||||
Controller::AxisList AnalogJoystick::StaticGetAxisNames()
|
||||
static const SettingInfo s_settings[] = {
|
||||
{SettingInfo::Type::Float, "AnalogDeadzone", TRANSLATABLE("AnalogController", "Analog Deadzone"),
|
||||
TRANSLATABLE("AnalogController",
|
||||
"Sets the analog stick deadzone, i.e. the fraction of the stick movement which will be ignored.s"),
|
||||
"1.00f", "0.00f", "1.00f", "0.01f"},
|
||||
{SettingInfo::Type::Float, "AnalogSensitivity", TRANSLATABLE("AnalogController", "Analog Sensitivity"),
|
||||
TRANSLATABLE(
|
||||
"AnalogController",
|
||||
"Sets the analog stick axis scaling factor. A value between 1.30 and 1.40 is recommended when using recent "
|
||||
"controllers, e.g. DualShock 4, Xbox One Controller."),
|
||||
"1.33f", "0.01f", "2.00f", "0.01f"}};
|
||||
|
||||
const Controller::ControllerInfo AnalogJoystick::INFO = {ControllerType::AnalogJoystick,
|
||||
"AnalogJoystick",
|
||||
TRANSLATABLE("ControllerType", "Analog Joystick"),
|
||||
s_binding_info,
|
||||
countof(s_binding_info),
|
||||
s_settings,
|
||||
countof(s_settings),
|
||||
Controller::VibrationCapabilities::NoVibration};
|
||||
|
||||
void AnalogJoystick::LoadSettings(SettingsInterface& si, const char* section)
|
||||
{
|
||||
return {{TRANSLATABLE("AnalogJoystick", "LeftX"), static_cast<s32>(Axis::LeftX), AxisType::Full},
|
||||
{TRANSLATABLE("AnalogJoystick", "LeftY"), static_cast<s32>(Axis::LeftY), AxisType::Full},
|
||||
{TRANSLATABLE("AnalogJoystick", "RightX"), static_cast<s32>(Axis::RightX), AxisType::Full},
|
||||
{TRANSLATABLE("AnalogJoystick", "RightY"), static_cast<s32>(Axis::RightY), AxisType::Full}};
|
||||
}
|
||||
|
||||
Controller::ButtonList AnalogJoystick::StaticGetButtonNames()
|
||||
{
|
||||
return {{TRANSLATABLE("AnalogJoystick", "Up"), static_cast<s32>(Button::Up)},
|
||||
{TRANSLATABLE("AnalogJoystick", "Down"), static_cast<s32>(Button::Down)},
|
||||
{TRANSLATABLE("AnalogJoystick", "Left"), static_cast<s32>(Button::Left)},
|
||||
{TRANSLATABLE("AnalogJoystick", "Right"), static_cast<s32>(Button::Right)},
|
||||
{TRANSLATABLE("AnalogJoystick", "Select"), static_cast<s32>(Button::Select)},
|
||||
{TRANSLATABLE("AnalogJoystick", "Start"), static_cast<s32>(Button::Start)},
|
||||
{TRANSLATABLE("AnalogJoystick", "Triangle"), static_cast<s32>(Button::Triangle)},
|
||||
{TRANSLATABLE("AnalogJoystick", "Cross"), static_cast<s32>(Button::Cross)},
|
||||
{TRANSLATABLE("AnalogJoystick", "Circle"), static_cast<s32>(Button::Circle)},
|
||||
{TRANSLATABLE("AnalogJoystick", "Square"), static_cast<s32>(Button::Square)},
|
||||
{TRANSLATABLE("AnalogJoystick", "L1"), static_cast<s32>(Button::L1)},
|
||||
{TRANSLATABLE("AnalogJoystick", "L2"), static_cast<s32>(Button::L2)},
|
||||
{TRANSLATABLE("AnalogJoystick", "R1"), static_cast<s32>(Button::R1)},
|
||||
{TRANSLATABLE("AnalogJoystick", "R2"), static_cast<s32>(Button::R2)},
|
||||
{TRANSLATABLE("AnalogJoystick", "L3"), static_cast<s32>(Button::L3)},
|
||||
{TRANSLATABLE("AnalogJoystick", "R3"), static_cast<s32>(Button::R3)},
|
||||
{TRANSLATABLE("AnalogJoystick", "Analog"), static_cast<s32>(Button::Mode)}};
|
||||
}
|
||||
|
||||
u32 AnalogJoystick::StaticGetVibrationMotorCount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Controller::SettingList AnalogJoystick::StaticGetSettings()
|
||||
{
|
||||
static constexpr std::array<SettingInfo, 1> settings = {
|
||||
{{SettingInfo::Type::Float, "AxisScale", TRANSLATABLE("AnalogJoystick", "Analog Axis Scale"),
|
||||
TRANSLATABLE(
|
||||
"AnalogJoystick",
|
||||
"Sets the analog stick axis scaling factor. A value between 1.30 and 1.40 is recommended when using recent "
|
||||
"controllers, e.g. DualShock 4, Xbox One Controller."),
|
||||
"1.00f", "0.01f", "1.50f", "0.01f"}}};
|
||||
|
||||
return SettingList(settings.begin(), settings.end());
|
||||
}
|
||||
|
||||
void AnalogJoystick::LoadSettings(const char* section)
|
||||
{
|
||||
Controller::LoadSettings(section);
|
||||
m_axis_scale = std::clamp(g_host_interface->GetFloatSettingValue(section, "AxisScale", 1.00f), 0.01f, 1.50f);
|
||||
Controller::LoadSettings(si, section);
|
||||
m_analog_deadzone = std::clamp(si.GetFloatValue(section, "AnalogDeadzone", DEFAULT_STICK_DEADZONE), 0.0f, 1.0f);
|
||||
m_analog_sensitivity =
|
||||
std::clamp(si.GetFloatValue(section, "AnalogSensitivity", DEFAULT_STICK_SENSITIVITY), 0.01f, 3.0f);
|
||||
}
|
||||
|
|
|
@ -39,38 +39,40 @@ public:
|
|||
Count
|
||||
};
|
||||
|
||||
enum class HalfAxis : u8
|
||||
{
|
||||
LLeft,
|
||||
LRight,
|
||||
LDown,
|
||||
LUp,
|
||||
RLeft,
|
||||
RRight,
|
||||
RDown,
|
||||
RUp,
|
||||
Count
|
||||
};
|
||||
|
||||
static const Controller::ControllerInfo INFO;
|
||||
|
||||
AnalogJoystick(u32 index);
|
||||
~AnalogJoystick() override;
|
||||
|
||||
static std::unique_ptr<AnalogJoystick> Create(u32 index);
|
||||
static std::optional<s32> StaticGetAxisCodeByName(std::string_view axis_name);
|
||||
static std::optional<s32> StaticGetButtonCodeByName(std::string_view button_name);
|
||||
static AxisList StaticGetAxisNames();
|
||||
static ButtonList StaticGetButtonNames();
|
||||
static u32 StaticGetVibrationMotorCount();
|
||||
static SettingList StaticGetSettings();
|
||||
|
||||
ControllerType GetType() const override;
|
||||
std::optional<s32> GetAxisCodeByName(std::string_view axis_name) const override;
|
||||
std::optional<s32> GetButtonCodeByName(std::string_view button_name) const override;
|
||||
|
||||
void Reset() override;
|
||||
bool DoState(StateWrapper& sw, bool apply_input_state) override;
|
||||
|
||||
float GetAxisState(s32 axis_code) const override;
|
||||
void SetAxisState(s32 axis_code, float value) override;
|
||||
bool GetButtonState(s32 button_code) const override;
|
||||
void SetButtonState(s32 button_code, bool pressed) override;
|
||||
float GetBindState(u32 index) const override;
|
||||
void SetBindState(u32 index, float value) override;
|
||||
u32 GetButtonStateBits() const override;
|
||||
std::optional<u32> GetAnalogInputBytes() const override;
|
||||
|
||||
void ResetTransferState() override;
|
||||
bool Transfer(const u8 data_in, u8* data_out) override;
|
||||
|
||||
void LoadSettings(const char* section) override;
|
||||
|
||||
void SetAxisState(Axis axis, u8 value);
|
||||
void SetButtonState(Button button, bool pressed);
|
||||
void LoadSettings(SettingsInterface& si, const char* section) override;
|
||||
|
||||
private:
|
||||
enum class TransferState : u8
|
||||
|
@ -89,9 +91,8 @@ private:
|
|||
u16 GetID() const;
|
||||
void ToggleAnalogMode();
|
||||
|
||||
u32 m_index;
|
||||
|
||||
float m_axis_scale = 1.00f;
|
||||
float m_analog_deadzone = 0.0f;
|
||||
float m_analog_sensitivity = 1.33f;
|
||||
|
||||
// On original hardware, the mode toggle is a switch rather than a button, so we'll enable Analog Mode by default
|
||||
bool m_analog_mode = true;
|
||||
|
@ -101,5 +102,8 @@ private:
|
|||
|
||||
std::array<u8, static_cast<u8>(Axis::Count)> m_axis_state{};
|
||||
|
||||
// both directions of axis state, merged to m_axis_state
|
||||
std::array<u8, static_cast<u32>(HalfAxis::Count)> m_half_axis_state{};
|
||||
|
||||
TransferState m_transfer_state = TransferState::Idle;
|
||||
};
|
||||
|
|
|
@ -3,7 +3,11 @@
|
|||
#include "common/file_system.h"
|
||||
#include "common/log.h"
|
||||
#include "common/md5_digest.h"
|
||||
#include "common/path.h"
|
||||
#include "cpu_disasm.h"
|
||||
#include "host.h"
|
||||
#include "host_settings.h"
|
||||
#include "settings.h"
|
||||
#include <array>
|
||||
#include <cerrno>
|
||||
Log_SetChannel(BIOS);
|
||||
|
@ -272,3 +276,143 @@ DiscRegion GetPSExeDiscRegion(const PSEXEHeader& header)
|
|||
}
|
||||
|
||||
} // namespace BIOS
|
||||
|
||||
std::optional<std::vector<u8>> BIOS::GetBIOSImage(ConsoleRegion region)
|
||||
{
|
||||
std::string bios_name;
|
||||
switch (region)
|
||||
{
|
||||
case ConsoleRegion::NTSC_J:
|
||||
bios_name = Host::GetStringSettingValue("BIOS", "PathNTSCJ", "");
|
||||
break;
|
||||
|
||||
case ConsoleRegion::PAL:
|
||||
bios_name = Host::GetStringSettingValue("BIOS", "PathPAL", "");
|
||||
break;
|
||||
|
||||
case ConsoleRegion::NTSC_U:
|
||||
default:
|
||||
bios_name = Host::GetStringSettingValue("BIOS", "PathNTSCU", "");
|
||||
break;
|
||||
}
|
||||
|
||||
if (bios_name.empty())
|
||||
{
|
||||
// auto-detect
|
||||
return FindBIOSImageInDirectory(region, EmuFolders::Bios.c_str());
|
||||
}
|
||||
|
||||
// try the configured path
|
||||
std::optional<Image> image = LoadImageFromFile(Path::Combine(EmuFolders::Bios, bios_name).c_str());
|
||||
if (!image.has_value())
|
||||
{
|
||||
Host::ReportFormattedErrorAsync(
|
||||
"Error", Host::TranslateString("HostInterface", "Failed to load configured BIOS file '%s'"), bios_name.c_str());
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
Hash found_hash = GetHash(*image);
|
||||
Log_DevPrintf("Hash for BIOS '%s': %s", bios_name.c_str(), found_hash.ToString().c_str());
|
||||
|
||||
if (!IsValidHashForRegion(region, found_hash))
|
||||
Log_WarningPrintf("Hash for BIOS '%s' does not match region. This may cause issues.", bios_name.c_str());
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
std::optional<std::vector<u8>> BIOS::FindBIOSImageInDirectory(ConsoleRegion region, const char* directory)
|
||||
{
|
||||
Log_InfoPrintf("Searching for a %s BIOS in '%s'...", Settings::GetConsoleRegionDisplayName(region), directory);
|
||||
|
||||
FileSystem::FindResultsArray results;
|
||||
FileSystem::FindFiles(
|
||||
directory, "*", FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES | FILESYSTEM_FIND_RELATIVE_PATHS, &results);
|
||||
|
||||
std::string fallback_path;
|
||||
std::optional<Image> fallback_image;
|
||||
const ImageInfo* fallback_info = nullptr;
|
||||
|
||||
for (const FILESYSTEM_FIND_DATA& fd : results)
|
||||
{
|
||||
if (fd.Size != BIOS_SIZE && fd.Size != BIOS_SIZE_PS2 && fd.Size != BIOS_SIZE_PS3)
|
||||
{
|
||||
Log_WarningPrintf("Skipping '%s': incorrect size", fd.FileName.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string full_path(Path::Combine(directory, fd.FileName));
|
||||
std::optional<Image> found_image = LoadImageFromFile(full_path.c_str());
|
||||
if (!found_image)
|
||||
continue;
|
||||
|
||||
Hash found_hash = GetHash(*found_image);
|
||||
Log_DevPrintf("Hash for BIOS '%s': %s", fd.FileName.c_str(), found_hash.ToString().c_str());
|
||||
|
||||
const ImageInfo* ii = GetImageInfoForHash(found_hash);
|
||||
|
||||
if (IsValidHashForRegion(region, found_hash))
|
||||
{
|
||||
Log_InfoPrintf("Using BIOS '%s': %s", fd.FileName.c_str(), ii ? ii->description : "");
|
||||
return found_image;
|
||||
}
|
||||
|
||||
// don't let an unknown bios take precedence over a known one
|
||||
if (!fallback_path.empty() && (fallback_info || !ii))
|
||||
continue;
|
||||
|
||||
fallback_path = std::move(full_path);
|
||||
fallback_image = std::move(found_image);
|
||||
fallback_info = ii;
|
||||
}
|
||||
|
||||
if (!fallback_image.has_value())
|
||||
{
|
||||
Host::ReportFormattedErrorAsync("Error",
|
||||
Host::TranslateString("HostInterface", "No BIOS image found for %s region"),
|
||||
Settings::GetConsoleRegionDisplayName(region));
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if (!fallback_info)
|
||||
{
|
||||
Log_WarningPrintf("Using unknown BIOS '%s'. This may crash.", fallback_path.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
Log_WarningPrintf("Falling back to possibly-incompatible image '%s': %s", fallback_path.c_str(),
|
||||
fallback_info->description);
|
||||
}
|
||||
|
||||
return fallback_image;
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string, const BIOS::ImageInfo*>> BIOS::FindBIOSImagesInDirectory(const char* directory)
|
||||
{
|
||||
std::vector<std::pair<std::string, const ImageInfo*>> results;
|
||||
|
||||
FileSystem::FindResultsArray files;
|
||||
FileSystem::FindFiles(directory, "*",
|
||||
FILESYSTEM_FIND_FILES | FILESYSTEM_FIND_HIDDEN_FILES | FILESYSTEM_FIND_RELATIVE_PATHS, &files);
|
||||
|
||||
for (FILESYSTEM_FIND_DATA& fd : files)
|
||||
{
|
||||
if (fd.Size != BIOS_SIZE && fd.Size != BIOS_SIZE_PS2 && fd.Size != BIOS_SIZE_PS3)
|
||||
continue;
|
||||
|
||||
std::string full_path(Path::Combine(directory, fd.FileName));
|
||||
std::optional<Image> found_image = LoadImageFromFile(full_path.c_str());
|
||||
if (!found_image)
|
||||
continue;
|
||||
|
||||
Hash found_hash = GetHash(*found_image);
|
||||
const ImageInfo* ii = GetImageInfoForHash(found_hash);
|
||||
results.emplace_back(std::move(fd.FileName), ii);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
bool BIOS::HasAnyBIOSImages()
|
||||
{
|
||||
return FindBIOSImageInDirectory(ConsoleRegion::Auto, EmuFolders::Bios.c_str()).has_value();
|
||||
}
|
||||
|
|
|
@ -70,4 +70,17 @@ bool PatchBIOSForEXE(u8* image, u32 image_size, u32 r_pc, u32 r_gp, u32 r_sp, u3
|
|||
|
||||
bool IsValidPSExeHeader(const PSEXEHeader& header, u32 file_size);
|
||||
DiscRegion GetPSExeDiscRegion(const PSEXEHeader& header);
|
||||
|
||||
/// Loads the BIOS image for the specified region.
|
||||
std::optional<std::vector<u8>> GetBIOSImage(ConsoleRegion region);
|
||||
|
||||
/// Searches for a BIOS image for the specified region in the specified directory. If no match is found, the first
|
||||
/// BIOS image within 512KB and 4MB will be used.
|
||||
std::optional<std::vector<u8>> FindBIOSImageInDirectory(ConsoleRegion region, const char* directory);
|
||||
|
||||
/// Returns a list of filenames and descriptions for BIOS images in a directory.
|
||||
std::vector<std::pair<std::string, const BIOS::ImageInfo*>> FindBIOSImagesInDirectory(const char* directory);
|
||||
|
||||
/// Returns true if any BIOS images are found in the configured BIOS directory.
|
||||
bool HasAnyBIOSImages();
|
||||
} // namespace BIOS
|
|
@ -10,7 +10,7 @@
|
|||
#include "cpu_disasm.h"
|
||||
#include "dma.h"
|
||||
#include "gpu.h"
|
||||
#include "host_interface.h"
|
||||
#include "host.h"
|
||||
#include "interrupt_controller.h"
|
||||
#include "mdec.h"
|
||||
#include "pad.h"
|
||||
|
@ -130,7 +130,7 @@ bool Initialize()
|
|||
{
|
||||
if (!AllocateMemory(g_settings.enable_8mb_ram))
|
||||
{
|
||||
g_host_interface->ReportError("Failed to allocate memory");
|
||||
Host::ReportErrorAsync("Error", "Failed to allocate memory");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "common/log.h"
|
||||
#include "common/platform.h"
|
||||
#include "dma.h"
|
||||
#include "host.h"
|
||||
#include "imgui.h"
|
||||
#include "interrupt_controller.h"
|
||||
#include "settings.h"
|
||||
|
@ -2722,7 +2723,7 @@ void CDROM::DrawDebugWindow()
|
|||
{
|
||||
static const ImVec4 active_color{1.0f, 1.0f, 1.0f, 1.0f};
|
||||
static const ImVec4 inactive_color{0.4f, 0.4f, 0.4f, 1.0f};
|
||||
const float framebuffer_scale = ImGui::GetIO().DisplayFramebufferScale.x;
|
||||
const float framebuffer_scale = Host::GetOSDScale();
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(800.0f * framebuffer_scale, 550.0f * framebuffer_scale), ImGuiCond_FirstUseEver);
|
||||
if (!ImGui::Begin("CDROM State", nullptr))
|
||||
|
|
|
@ -29,6 +29,7 @@ public:
|
|||
bool HasMedia() const { return m_reader.HasMedia(); }
|
||||
const std::string& GetMediaFileName() const { return m_reader.GetMediaFileName(); }
|
||||
const CDImage* GetMedia() const { return m_reader.GetMedia(); }
|
||||
DiscRegion GetDiscRegion() const { return m_disc_region; }
|
||||
bool IsMediaPS1Disc() const;
|
||||
bool DoesMediaRegionMatchConsole() const;
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "controller.h"
|
||||
#include "cpu_code_cache.h"
|
||||
#include "cpu_core.h"
|
||||
#include "host_interface.h"
|
||||
#include "host.h"
|
||||
#include "system.h"
|
||||
#include <cctype>
|
||||
#include <iomanip>
|
||||
|
@ -686,17 +686,11 @@ bool CheatList::SaveToPCSXRFile(const char* filename)
|
|||
|
||||
bool CheatList::LoadFromPackage(const std::string& game_code)
|
||||
{
|
||||
std::unique_ptr<ByteStream> stream =
|
||||
g_host_interface->OpenPackageFile("database/chtdb.txt", BYTESTREAM_OPEN_READ | BYTESTREAM_OPEN_STREAMED);
|
||||
if (!stream)
|
||||
const std::optional<std::string> db_string(Host::ReadResourceFileToString("chtdb.txt"));
|
||||
if (!db_string.has_value())
|
||||
return false;
|
||||
|
||||
std::string db_string = ByteStream::ReadStreamToString(stream.get());
|
||||
stream.reset();
|
||||
if (db_string.empty())
|
||||
return false;
|
||||
|
||||
std::istringstream iss(db_string);
|
||||
std::istringstream iss(db_string.value());
|
||||
std::string line;
|
||||
while (std::getline(iss, line))
|
||||
{
|
||||
|
|
1802
src/core/cheevos.cpp
|
@ -2,12 +2,27 @@
|
|||
#include "analog_controller.h"
|
||||
#include "analog_joystick.h"
|
||||
#include "digital_controller.h"
|
||||
#include "namco_guncon.h"
|
||||
#include "fmt/format.h"
|
||||
#include "guncon.h"
|
||||
#include "negcon.h"
|
||||
#include "playstation_mouse.h"
|
||||
#include "util/state_wrapper.h"
|
||||
|
||||
Controller::Controller() = default;
|
||||
static const Controller::ControllerInfo s_none_info = {ControllerType::None,
|
||||
"None",
|
||||
"Not Connected",
|
||||
nullptr,
|
||||
0,
|
||||
nullptr,
|
||||
0,
|
||||
Controller::VibrationCapabilities::NoVibration};
|
||||
|
||||
static const Controller::ControllerInfo* s_controller_info[] = {
|
||||
&s_none_info, &DigitalController::INFO, &AnalogController::INFO, &AnalogJoystick::INFO, &NeGcon::INFO,
|
||||
&GunCon::INFO, &PlayStationMouse::INFO,
|
||||
};
|
||||
|
||||
Controller::Controller(u32 index) : m_index(index) {}
|
||||
|
||||
Controller::~Controller() = default;
|
||||
|
||||
|
@ -26,19 +41,12 @@ bool Controller::Transfer(const u8 data_in, u8* data_out)
|
|||
return false;
|
||||
}
|
||||
|
||||
float Controller::GetAxisState(s32 axis_code) const
|
||||
float Controller::GetBindState(u32 index) const
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
void Controller::SetAxisState(s32 axis_code, float value) {}
|
||||
|
||||
bool Controller::GetButtonState(s32 button_code) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void Controller::SetButtonState(s32 button_code, bool pressed) {}
|
||||
void Controller::SetBindState(u32 index, float value) {}
|
||||
|
||||
u32 Controller::GetButtonStateBits() const
|
||||
{
|
||||
|
@ -50,17 +58,7 @@ std::optional<u32> Controller::GetAnalogInputBytes() const
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
u32 Controller::GetVibrationMotorCount() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
float Controller::GetVibrationMotorStrength(u32 motor)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
void Controller::LoadSettings(const char* section) {}
|
||||
void Controller::LoadSettings(SettingsInterface& si, const char* section) {}
|
||||
|
||||
bool Controller::GetSoftwareCursor(const Common::RGBA8Image** image, float* image_scale, bool* relative_mode)
|
||||
{
|
||||
|
@ -72,7 +70,7 @@ std::unique_ptr<Controller> Controller::Create(ControllerType type, u32 index)
|
|||
switch (type)
|
||||
{
|
||||
case ControllerType::DigitalController:
|
||||
return DigitalController::Create();
|
||||
return DigitalController::Create(index);
|
||||
|
||||
case ControllerType::AnalogController:
|
||||
return AnalogController::Create(index);
|
||||
|
@ -80,14 +78,14 @@ std::unique_ptr<Controller> Controller::Create(ControllerType type, u32 index)
|
|||
case ControllerType::AnalogJoystick:
|
||||
return AnalogJoystick::Create(index);
|
||||
|
||||
case ControllerType::NamcoGunCon:
|
||||
return NamcoGunCon::Create();
|
||||
case ControllerType::GunCon:
|
||||
return GunCon::Create(index);
|
||||
|
||||
case ControllerType::PlayStationMouse:
|
||||
return PlayStationMouse::Create();
|
||||
return PlayStationMouse::Create(index);
|
||||
|
||||
case ControllerType::NeGcon:
|
||||
return NeGcon::Create();
|
||||
return NeGcon::Create(index);
|
||||
|
||||
case ControllerType::None:
|
||||
default:
|
||||
|
@ -95,179 +93,134 @@ std::unique_ptr<Controller> Controller::Create(ControllerType type, u32 index)
|
|||
}
|
||||
}
|
||||
|
||||
std::optional<s32> Controller::GetAxisCodeByName(std::string_view button_name) const
|
||||
const char* Controller::GetDefaultPadType(u32 pad)
|
||||
{
|
||||
return (pad == 0) ? "DigitalController" : "None";
|
||||
}
|
||||
|
||||
const Controller::ControllerInfo* Controller::GetControllerInfo(ControllerType type)
|
||||
{
|
||||
for (const ControllerInfo* info : s_controller_info)
|
||||
{
|
||||
if (type == info->type)
|
||||
return info;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const Controller::ControllerInfo* Controller::GetControllerInfo(const std::string_view& name)
|
||||
{
|
||||
for (const ControllerInfo* info : s_controller_info)
|
||||
{
|
||||
if (name == info->name)
|
||||
return info;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string, std::string>> Controller::GetControllerTypeNames()
|
||||
{
|
||||
std::vector<std::pair<std::string, std::string>> ret;
|
||||
for (const ControllerInfo* info : s_controller_info)
|
||||
ret.emplace_back(info->name, info->display_name);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<std::string> Controller::GetControllerBinds(const std::string_view& type)
|
||||
{
|
||||
std::vector<std::string> ret;
|
||||
|
||||
const ControllerInfo* info = GetControllerInfo(type);
|
||||
if (info)
|
||||
{
|
||||
for (u32 i = 0; i < info->num_bindings; i++)
|
||||
{
|
||||
const ControllerBindingInfo& bi = info->bindings[i];
|
||||
if (bi.type == ControllerBindingType::Unknown || bi.type == ControllerBindingType::Motor)
|
||||
continue;
|
||||
|
||||
ret.emplace_back(info->bindings[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<std::string> Controller::GetControllerBinds(ControllerType type)
|
||||
{
|
||||
std::vector<std::string> ret;
|
||||
|
||||
const ControllerInfo* info = GetControllerInfo(type);
|
||||
if (info)
|
||||
{
|
||||
for (u32 i = 0; i < info->num_bindings; i++)
|
||||
{
|
||||
const ControllerBindingInfo& bi = info->bindings[i];
|
||||
if (bi.type == ControllerBindingType::Unknown || bi.type == ControllerBindingType::Motor)
|
||||
continue;
|
||||
|
||||
ret.emplace_back(info->bindings[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::optional<u32> Controller::GetBindIndex(ControllerType type, const std::string_view& bind_name)
|
||||
{
|
||||
const ControllerInfo* info = GetControllerInfo(type);
|
||||
if (!info)
|
||||
return std::nullopt;
|
||||
|
||||
for (u32 i = 0; i < info->num_bindings; i++)
|
||||
{
|
||||
if (bind_name == info->bindings[i].name)
|
||||
return i;
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<s32> Controller::GetButtonCodeByName(std::string_view button_name) const
|
||||
Controller::VibrationCapabilities Controller::GetControllerVibrationCapabilities(const std::string_view& type)
|
||||
{
|
||||
return std::nullopt;
|
||||
const ControllerInfo* info = GetControllerInfo(type);
|
||||
return info ? info->vibration_caps : VibrationCapabilities::NoVibration;
|
||||
}
|
||||
|
||||
Controller::AxisList Controller::GetAxisNames(ControllerType type)
|
||||
std::tuple<u32, u32> Controller::ConvertPadToPortAndSlot(u32 index)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ControllerType::DigitalController:
|
||||
return DigitalController::StaticGetAxisNames();
|
||||
|
||||
case ControllerType::AnalogController:
|
||||
return AnalogController::StaticGetAxisNames();
|
||||
|
||||
case ControllerType::AnalogJoystick:
|
||||
return AnalogJoystick::StaticGetAxisNames();
|
||||
|
||||
case ControllerType::NamcoGunCon:
|
||||
return NamcoGunCon::StaticGetAxisNames();
|
||||
|
||||
case ControllerType::PlayStationMouse:
|
||||
return PlayStationMouse::StaticGetAxisNames();
|
||||
|
||||
case ControllerType::NeGcon:
|
||||
return NeGcon::StaticGetAxisNames();
|
||||
|
||||
case ControllerType::None:
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
if (index > 4) // [5,6,7]
|
||||
return std::make_tuple(1, index - 4); // 2B,2C,2D
|
||||
else if (index > 1) // [2,3,4]
|
||||
return std::make_tuple(0, index - 1); // 1B,1C,1D
|
||||
else // [0,1]
|
||||
return std::make_tuple(index, 0); // 1A,2A
|
||||
}
|
||||
|
||||
Controller::ButtonList Controller::GetButtonNames(ControllerType type)
|
||||
u32 Controller::ConvertPortAndSlotToPad(u32 port, u32 slot)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ControllerType::DigitalController:
|
||||
return DigitalController::StaticGetButtonNames();
|
||||
|
||||
case ControllerType::AnalogController:
|
||||
return AnalogController::StaticGetButtonNames();
|
||||
|
||||
case ControllerType::AnalogJoystick:
|
||||
return AnalogJoystick::StaticGetButtonNames();
|
||||
|
||||
case ControllerType::NamcoGunCon:
|
||||
return NamcoGunCon::StaticGetButtonNames();
|
||||
|
||||
case ControllerType::PlayStationMouse:
|
||||
return PlayStationMouse::StaticGetButtonNames();
|
||||
|
||||
case ControllerType::NeGcon:
|
||||
return NeGcon::StaticGetButtonNames();
|
||||
|
||||
case ControllerType::None:
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
if (slot == 0)
|
||||
return port;
|
||||
else if (port == 0) // slot=[0,1]
|
||||
return slot + 1; // 2,3,4
|
||||
else
|
||||
return slot + 4; // 5,6,7
|
||||
}
|
||||
|
||||
u32 Controller::GetVibrationMotorCount(ControllerType type)
|
||||
bool Controller::PadIsMultitapSlot(u32 index)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ControllerType::DigitalController:
|
||||
return DigitalController::StaticGetVibrationMotorCount();
|
||||
|
||||
case ControllerType::AnalogController:
|
||||
return AnalogController::StaticGetVibrationMotorCount();
|
||||
|
||||
case ControllerType::AnalogJoystick:
|
||||
return AnalogJoystick::StaticGetVibrationMotorCount();
|
||||
|
||||
case ControllerType::NamcoGunCon:
|
||||
return NamcoGunCon::StaticGetVibrationMotorCount();
|
||||
|
||||
case ControllerType::PlayStationMouse:
|
||||
return PlayStationMouse::StaticGetVibrationMotorCount();
|
||||
|
||||
case ControllerType::NeGcon:
|
||||
return NeGcon::StaticGetVibrationMotorCount();
|
||||
|
||||
case ControllerType::None:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return (index >= 2);
|
||||
}
|
||||
|
||||
std::optional<s32> Controller::GetAxisCodeByName(ControllerType type, std::string_view axis_name)
|
||||
bool Controller::PortAndSlotIsMultitap(u32 port, u32 slot)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ControllerType::DigitalController:
|
||||
return DigitalController::StaticGetAxisCodeByName(axis_name);
|
||||
|
||||
case ControllerType::AnalogController:
|
||||
return AnalogController::StaticGetAxisCodeByName(axis_name);
|
||||
|
||||
case ControllerType::AnalogJoystick:
|
||||
return AnalogJoystick::StaticGetAxisCodeByName(axis_name);
|
||||
|
||||
case ControllerType::NamcoGunCon:
|
||||
return NamcoGunCon::StaticGetAxisCodeByName(axis_name);
|
||||
|
||||
case ControllerType::PlayStationMouse:
|
||||
return PlayStationMouse::StaticGetAxisCodeByName(axis_name);
|
||||
|
||||
case ControllerType::NeGcon:
|
||||
return NeGcon::StaticGetAxisCodeByName(axis_name);
|
||||
|
||||
case ControllerType::None:
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
return (slot != 0);
|
||||
}
|
||||
|
||||
std::optional<s32> Controller::GetButtonCodeByName(ControllerType type, std::string_view button_name)
|
||||
std::string Controller::GetSettingsSection(u32 pad)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ControllerType::DigitalController:
|
||||
return DigitalController::StaticGetButtonCodeByName(button_name);
|
||||
|
||||
case ControllerType::AnalogController:
|
||||
return AnalogController::StaticGetButtonCodeByName(button_name);
|
||||
|
||||
case ControllerType::AnalogJoystick:
|
||||
return AnalogJoystick::StaticGetButtonCodeByName(button_name);
|
||||
|
||||
case ControllerType::NamcoGunCon:
|
||||
return NamcoGunCon::StaticGetButtonCodeByName(button_name);
|
||||
|
||||
case ControllerType::PlayStationMouse:
|
||||
return PlayStationMouse::StaticGetButtonCodeByName(button_name);
|
||||
|
||||
case ControllerType::NeGcon:
|
||||
return NeGcon::StaticGetButtonCodeByName(button_name);
|
||||
|
||||
case ControllerType::None:
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
Controller::SettingList Controller::GetSettings(ControllerType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ControllerType::DigitalController:
|
||||
return DigitalController::StaticGetSettings();
|
||||
|
||||
case ControllerType::AnalogController:
|
||||
return AnalogController::StaticGetSettings();
|
||||
|
||||
case ControllerType::AnalogJoystick:
|
||||
return AnalogJoystick::StaticGetSettings();
|
||||
|
||||
case ControllerType::NamcoGunCon:
|
||||
return NamcoGunCon::StaticGetSettings();
|
||||
|
||||
case ControllerType::NeGcon:
|
||||
return NeGcon::StaticGetSettings();
|
||||
|
||||
case ControllerType::PlayStationMouse:
|
||||
return PlayStationMouse::StaticGetSettings();
|
||||
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
return fmt::format("Pad{}", pad + 1u);
|
||||
}
|
||||
|
|
|
@ -6,36 +6,67 @@
|
|||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
class SettingsInterface;
|
||||
class StateWrapper;
|
||||
class HostInterface;
|
||||
|
||||
enum class GenericInputBinding : u8;
|
||||
|
||||
class Controller
|
||||
{
|
||||
public:
|
||||
enum class AxisType : u8
|
||||
enum class ControllerBindingType : u8
|
||||
{
|
||||
Full,
|
||||
Half
|
||||
Unknown,
|
||||
Button,
|
||||
Axis,
|
||||
HalfAxis,
|
||||
Motor,
|
||||
Macro
|
||||
};
|
||||
|
||||
using ButtonList = std::vector<std::pair<std::string, s32>>;
|
||||
using AxisList = std::vector<std::tuple<std::string, s32, AxisType>>;
|
||||
using SettingList = std::vector<SettingInfo>;
|
||||
enum class VibrationCapabilities : u8
|
||||
{
|
||||
NoVibration,
|
||||
LargeSmallMotors,
|
||||
SingleMotor,
|
||||
Count
|
||||
};
|
||||
|
||||
Controller();
|
||||
struct ControllerBindingInfo
|
||||
{
|
||||
const char* name;
|
||||
const char* display_name;
|
||||
u32 bind_index;
|
||||
ControllerBindingType type;
|
||||
GenericInputBinding generic_mapping;
|
||||
};
|
||||
|
||||
struct ControllerInfo
|
||||
{
|
||||
ControllerType type;
|
||||
const char* name;
|
||||
const char* display_name;
|
||||
const ControllerBindingInfo* bindings;
|
||||
u32 num_bindings;
|
||||
const SettingInfo* settings;
|
||||
u32 num_settings;
|
||||
VibrationCapabilities vibration_caps;
|
||||
};
|
||||
|
||||
/// Default stick deadzone/sensitivity.
|
||||
static constexpr float DEFAULT_STICK_DEADZONE = 0.0f;
|
||||
static constexpr float DEFAULT_STICK_SENSITIVITY = 1.33f;
|
||||
|
||||
Controller(u32 index);
|
||||
virtual ~Controller();
|
||||
|
||||
/// Returns the type of controller.
|
||||
virtual ControllerType GetType() const = 0;
|
||||
|
||||
/// Gets the integer code for an axis in the specified controller type.
|
||||
virtual std::optional<s32> GetAxisCodeByName(std::string_view axis_name) const;
|
||||
|
||||
/// Gets the integer code for a button in the specified controller type.
|
||||
virtual std::optional<s32> GetButtonCodeByName(std::string_view button_name) const;
|
||||
|
||||
virtual void Reset();
|
||||
virtual bool DoState(StateWrapper& sw, bool apply_input_state);
|
||||
|
||||
|
@ -46,16 +77,10 @@ public:
|
|||
virtual bool Transfer(const u8 data_in, u8* data_out);
|
||||
|
||||
/// Changes the specified axis state. Values are normalized from -1..1.
|
||||
virtual float GetAxisState(s32 axis_code) const;
|
||||
virtual float GetBindState(u32 index) const;
|
||||
|
||||
/// Changes the specified axis state. Values are normalized from -1..1.
|
||||
virtual void SetAxisState(s32 axis_code, float value);
|
||||
|
||||
/// Returns the specified button state.
|
||||
virtual bool GetButtonState(s32 button_code) const;
|
||||
|
||||
/// Changes the specified button state.
|
||||
virtual void SetButtonState(s32 button_code, bool pressed);
|
||||
/// Changes the specified bind state. Values are normalized from -1..1.
|
||||
virtual void SetBindState(u32 index, float value);
|
||||
|
||||
/// Returns a bitmask of the current button states, 1 = on.
|
||||
virtual u32 GetButtonStateBits() const;
|
||||
|
@ -63,14 +88,8 @@ public:
|
|||
/// Returns analog input bytes packed as a u32. Values are specific to controller type.
|
||||
virtual std::optional<u32> GetAnalogInputBytes() const;
|
||||
|
||||
/// Returns the number of vibration motors.
|
||||
virtual u32 GetVibrationMotorCount() const;
|
||||
|
||||
/// Queries the state of the specified vibration motor. Values are normalized from 0..1.
|
||||
virtual float GetVibrationMotorStrength(u32 motor);
|
||||
|
||||
/// Loads/refreshes any per-controller settings.
|
||||
virtual void LoadSettings(const char* section);
|
||||
virtual void LoadSettings(SettingsInterface& si, const char* section);
|
||||
|
||||
/// Returns the software cursor to use for this controller, if any.
|
||||
virtual bool GetSoftwareCursor(const Common::RGBA8Image** image, float* image_scale, bool* relative_mode);
|
||||
|
@ -78,21 +97,45 @@ public:
|
|||
/// Creates a new controller of the specified type.
|
||||
static std::unique_ptr<Controller> Create(ControllerType type, u32 index);
|
||||
|
||||
/// Returns the default type for the specified port.
|
||||
static const char* GetDefaultPadType(u32 pad);
|
||||
|
||||
/// Returns a list of controller type names. Pair of [name, display name].
|
||||
static std::vector<std::pair<std::string, std::string>> GetControllerTypeNames();
|
||||
|
||||
/// Returns the list of binds for the specified controller type.
|
||||
static std::vector<std::string> GetControllerBinds(const std::string_view& type);
|
||||
static std::vector<std::string> GetControllerBinds(ControllerType type);
|
||||
|
||||
/// Gets the integer code for an axis in the specified controller type.
|
||||
static std::optional<s32> GetAxisCodeByName(ControllerType type, std::string_view axis_name);
|
||||
static std::optional<u32> GetBindIndex(ControllerType type, const std::string_view& bind_name);
|
||||
|
||||
/// Gets the integer code for a button in the specified controller type.
|
||||
static std::optional<s32> GetButtonCodeByName(ControllerType type, std::string_view button_name);
|
||||
/// Returns the vibration configuration for the specified controller type.
|
||||
static VibrationCapabilities GetControllerVibrationCapabilities(const std::string_view& type);
|
||||
|
||||
/// Returns a list of axises for the specified controller type.
|
||||
static AxisList GetAxisNames(ControllerType type);
|
||||
/// Returns general information for the specified controller type.
|
||||
static const ControllerInfo* GetControllerInfo(ControllerType type);
|
||||
static const ControllerInfo* GetControllerInfo(const std::string_view& name);
|
||||
|
||||
/// Returns a list of buttons for the specified controller type.
|
||||
static ButtonList GetButtonNames(ControllerType type);
|
||||
/// Converts a global pad index to a multitap port and slot.
|
||||
static std::tuple<u32, u32> ConvertPadToPortAndSlot(u32 index);
|
||||
|
||||
/// Returns the number of vibration motors.
|
||||
static u32 GetVibrationMotorCount(ControllerType type);
|
||||
/// Converts a multitap port and slot to a global pad index.
|
||||
static u32 ConvertPortAndSlotToPad(u32 port, u32 slot);
|
||||
|
||||
/// Returns settings for the controller.
|
||||
static SettingList GetSettings(ControllerType type);
|
||||
/// Returns true if the given pad index is a multitap slot.
|
||||
static bool PadIsMultitapSlot(u32 index);
|
||||
static bool PortAndSlotIsMultitap(u32 port, u32 slot);
|
||||
|
||||
/// Returns the configuration section for the specified gamepad.
|
||||
static std::string GetSettingsSection(u32 pad);
|
||||
|
||||
/// Applies an analog deadzone/sensitivity.
|
||||
static float ApplyAnalogDeadzoneSensitivity(float deadzone, float sensitivity, float value)
|
||||
{
|
||||
return (value < deadzone) ? 0.0f : ((value - deadzone) / (1.0f - deadzone) * sensitivity);
|
||||
}
|
||||
|
||||
protected:
|
||||
u32 m_index;
|
||||
};
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<PreprocessorDefinitions Condition="('$(Platform)'=='x64' Or '$(Platform)'=='ARM' Or '$(Platform)'=='ARM64')">WITH_RECOMPILER=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="('$(Platform)'=='x64' Or '$(Platform)'=='ARM64') And ('$(BuildingForUWP)'!='true')">WITH_MMAP_FASTMEM=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xxhash\include;$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\rcheevos\include;$(SolutionDir)dep\rapidjson\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)dep\tinyxml2\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xxhash\include;$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\rcheevos\include;$(SolutionDir)dep\rapidjson\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories Condition="('$(BuildingForUWP)'!='true' And '$(Platform)'!='ARM64')">$(SolutionDir)dep\rainterface;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
|
||||
<AdditionalIncludeDirectories Condition="'$(Platform)'=='x64'">$(SolutionDir)dep\xbyak\xbyak;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
|
@ -19,7 +19,7 @@
|
|||
|
||||
<ItemDefinitionGroup>
|
||||
<Lib>
|
||||
<AdditionalDependencies>$(RootBuildDir)rcheevos\rcheevos.lib;$(RootBuildDir)imgui\imgui.lib;$(RootBuildDir)stb\stb.lib;$(RootBuildDir)xxhash\xxhash.lib;$(RootBuildDir)zlib\zlib.lib;$(RootBuildDir)util\util.lib;$(RootBuildDir)common\common.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>$(RootBuildDir)tinyxml2\tinyxml2.lib;$(RootBuildDir)rcheevos\rcheevos.lib;$(RootBuildDir)imgui\imgui.lib;$(RootBuildDir)stb\stb.lib;$(RootBuildDir)xxhash\xxhash.lib;$(RootBuildDir)zlib\zlib.lib;$(RootBuildDir)util\util.lib;$(RootBuildDir)common\common.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies Condition="('$(BuildingForUWP)'!='true' And '$(Platform)'!='ARM64')">$(RootBuildDir)rainterface\rainterface.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies Condition="'$(Platform)'=='ARM64'">$(RootBuildDir)vixl\vixl.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Lib>
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
<ClCompile Include="cdrom.cpp" />
|
||||
<ClCompile Include="cdrom_async_reader.cpp" />
|
||||
<ClCompile Include="cheats.cpp" />
|
||||
<ClCompile Include="cheevos.cpp" />
|
||||
<ClCompile Include="cpu_core.cpp" />
|
||||
<ClCompile Include="cpu_disasm.cpp" />
|
||||
<ClCompile Include="cpu_code_cache.cpp" />
|
||||
|
@ -33,6 +32,7 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="cpu_types.cpp" />
|
||||
<ClCompile Include="digital_controller.cpp" />
|
||||
<ClCompile Include="game_database.cpp" />
|
||||
<ClCompile Include="gpu_backend.cpp" />
|
||||
<ClCompile Include="gpu_commands.cpp" />
|
||||
<ClCompile Include="gpu_hw_d3d11.cpp" />
|
||||
|
@ -47,18 +47,16 @@
|
|||
<ClCompile Include="gpu.cpp" />
|
||||
<ClCompile Include="gpu_hw.cpp" />
|
||||
<ClCompile Include="gpu_hw_opengl.cpp" />
|
||||
<ClCompile Include="host.cpp" />
|
||||
<ClCompile Include="host_display.cpp" />
|
||||
<ClCompile Include="host_interface.cpp" />
|
||||
<ClCompile Include="host_interface_progress_callback.cpp" />
|
||||
<ClCompile Include="imgui_fullscreen.cpp" />
|
||||
<ClCompile Include="imgui_styles.cpp" />
|
||||
<ClCompile Include="interrupt_controller.cpp" />
|
||||
<ClCompile Include="libcrypt_game_codes.cpp" />
|
||||
<ClCompile Include="mdec.cpp" />
|
||||
<ClCompile Include="memory_card.cpp" />
|
||||
<ClCompile Include="memory_card_image.cpp" />
|
||||
<ClCompile Include="multitap.cpp" />
|
||||
<ClCompile Include="namco_guncon.cpp" />
|
||||
<ClCompile Include="guncon.cpp" />
|
||||
<ClCompile Include="negcon.cpp" />
|
||||
<ClCompile Include="pad.cpp" />
|
||||
<ClCompile Include="controller.cpp" />
|
||||
|
@ -83,7 +81,7 @@
|
|||
<ClInclude Include="cdrom.h" />
|
||||
<ClInclude Include="cdrom_async_reader.h" />
|
||||
<ClInclude Include="cheats.h" />
|
||||
<ClInclude Include="cheevos.h" />
|
||||
<ClInclude Include="achievements.h" />
|
||||
<ClInclude Include="cpu_core.h" />
|
||||
<ClInclude Include="cpu_core_private.h" />
|
||||
<ClInclude Include="cpu_disasm.h" />
|
||||
|
@ -101,6 +99,7 @@
|
|||
<ExcludedFromBuild Condition="'$(Platform)'=='Win32'">true</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="digital_controller.h" />
|
||||
<ClInclude Include="game_database.h" />
|
||||
<ClInclude Include="gpu_backend.h" />
|
||||
<ClInclude Include="gpu_hw_d3d11.h" />
|
||||
<ClInclude Include="gpu_hw_d3d12.h" />
|
||||
|
@ -119,18 +118,15 @@
|
|||
<ClInclude Include="gte_types.h" />
|
||||
<ClInclude Include="host.h" />
|
||||
<ClInclude Include="host_display.h" />
|
||||
<ClInclude Include="host_interface.h" />
|
||||
<ClInclude Include="host_interface_progress_callback.h" />
|
||||
<ClInclude Include="host_settings.h" />
|
||||
<ClInclude Include="imgui_fullscreen.h" />
|
||||
<ClInclude Include="imgui_styles.h" />
|
||||
<ClInclude Include="interrupt_controller.h" />
|
||||
<ClInclude Include="libcrypt_game_codes.h" />
|
||||
<ClInclude Include="mdec.h" />
|
||||
<ClInclude Include="memory_card.h" />
|
||||
<ClInclude Include="memory_card_image.h" />
|
||||
<ClInclude Include="multitap.h" />
|
||||
<ClInclude Include="namco_guncon.h" />
|
||||
<ClInclude Include="guncon.h" />
|
||||
<ClInclude Include="negcon.h" />
|
||||
<ClInclude Include="pad.h" />
|
||||
<ClInclude Include="controller.h" />
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
<ClCompile Include="gpu.cpp" />
|
||||
<ClCompile Include="gpu_hw_opengl.cpp" />
|
||||
<ClCompile Include="gpu_hw.cpp" />
|
||||
<ClCompile Include="host_interface.cpp" />
|
||||
<ClCompile Include="interrupt_controller.cpp" />
|
||||
<ClCompile Include="cdrom.cpp" />
|
||||
<ClCompile Include="gte.cpp" />
|
||||
|
@ -40,7 +39,7 @@
|
|||
<ClCompile Include="timing_event.cpp" />
|
||||
<ClCompile Include="cdrom_async_reader.cpp" />
|
||||
<ClCompile Include="psf_loader.cpp" />
|
||||
<ClCompile Include="namco_guncon.cpp" />
|
||||
<ClCompile Include="guncon.cpp" />
|
||||
<ClCompile Include="playstation_mouse.cpp" />
|
||||
<ClCompile Include="negcon.cpp" />
|
||||
<ClCompile Include="gpu_hw_vulkan.cpp" />
|
||||
|
@ -58,9 +57,8 @@
|
|||
<ClCompile Include="texture_replacements.cpp" />
|
||||
<ClCompile Include="multitap.cpp" />
|
||||
<ClCompile Include="gpu_hw_d3d12.cpp" />
|
||||
<ClCompile Include="imgui_fullscreen.cpp" />
|
||||
<ClCompile Include="imgui_styles.cpp" />
|
||||
<ClCompile Include="cheevos.cpp" />
|
||||
<ClCompile Include="host.cpp" />
|
||||
<ClCompile Include="game_database.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="types.h" />
|
||||
|
@ -74,7 +72,6 @@
|
|||
<ClInclude Include="gpu.h" />
|
||||
<ClInclude Include="gpu_hw_opengl.h" />
|
||||
<ClInclude Include="gpu_hw.h" />
|
||||
<ClInclude Include="host_interface.h" />
|
||||
<ClInclude Include="interrupt_controller.h" />
|
||||
<ClInclude Include="cdrom.h" />
|
||||
<ClInclude Include="gte.h" />
|
||||
|
@ -101,7 +98,7 @@
|
|||
<ClInclude Include="timing_event.h" />
|
||||
<ClInclude Include="cdrom_async_reader.h" />
|
||||
<ClInclude Include="psf_loader.h" />
|
||||
<ClInclude Include="namco_guncon.h" />
|
||||
<ClInclude Include="guncon.h" />
|
||||
<ClInclude Include="playstation_mouse.h" />
|
||||
<ClInclude Include="negcon.h" />
|
||||
<ClInclude Include="gpu_hw_vulkan.h" />
|
||||
|
@ -123,10 +120,9 @@
|
|||
<ClInclude Include="multitap.h" />
|
||||
<ClInclude Include="gpu_hw_d3d12.h" />
|
||||
<ClInclude Include="gdb_protocol.h" />
|
||||
<ClInclude Include="imgui_fullscreen.h" />
|
||||
<ClInclude Include="imgui_styles.h" />
|
||||
<ClInclude Include="cheevos.h" />
|
||||
<ClInclude Include="host.h" />
|
||||
<ClInclude Include="host_settings.h" />
|
||||
<ClInclude Include="achievements.h" />
|
||||
<ClInclude Include="game_database.h" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -7,7 +7,7 @@
|
|||
#include "cpu_disasm.h"
|
||||
#include "cpu_recompiler_thunks.h"
|
||||
#include "gte.h"
|
||||
#include "host_interface.h"
|
||||
#include "host.h"
|
||||
#include "pgxp.h"
|
||||
#include "settings.h"
|
||||
#include "system.h"
|
||||
|
@ -1691,8 +1691,8 @@ bool AddBreakpoint(VirtualMemoryAddress address, bool auto_clear, bool enabled)
|
|||
|
||||
if (!auto_clear)
|
||||
{
|
||||
g_host_interface->ReportFormattedDebuggerMessage(
|
||||
g_host_interface->TranslateString("DebuggerMessage", "Added breakpoint at 0x%08X."), address);
|
||||
Host::ReportFormattedDebuggerMessage(Host::TranslateString("DebuggerMessage", "Added breakpoint at 0x%08X."),
|
||||
address);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1718,8 +1718,8 @@ bool RemoveBreakpoint(VirtualMemoryAddress address)
|
|||
if (it == s_breakpoints.end())
|
||||
return false;
|
||||
|
||||
g_host_interface->ReportFormattedDebuggerMessage(
|
||||
g_host_interface->TranslateString("DebuggerMessage", "Removed breakpoint at 0x%08X."), address);
|
||||
Host::ReportFormattedDebuggerMessage(Host::TranslateString("DebuggerMessage", "Removed breakpoint at 0x%08X."),
|
||||
address);
|
||||
|
||||
s_breakpoints.erase(it);
|
||||
UpdateDebugDispatcherFlag();
|
||||
|
@ -1750,8 +1750,8 @@ bool AddStepOverBreakpoint()
|
|||
|
||||
if (!IsCallInstruction(inst))
|
||||
{
|
||||
g_host_interface->ReportFormattedDebuggerMessage(
|
||||
g_host_interface->TranslateString("DebuggerMessage", "0x%08X is not a call instruction."), g_state.regs.pc);
|
||||
Host::ReportFormattedDebuggerMessage(Host::TranslateString("DebuggerMessage", "0x%08X is not a call instruction."),
|
||||
g_state.regs.pc);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1760,16 +1760,15 @@ bool AddStepOverBreakpoint()
|
|||
|
||||
if (IsBranchInstruction(inst))
|
||||
{
|
||||
g_host_interface->ReportFormattedDebuggerMessage(
|
||||
g_host_interface->TranslateString("DebuggerMessage", "Can't step over double branch at 0x%08X"), g_state.regs.pc);
|
||||
Host::ReportFormattedDebuggerMessage(
|
||||
Host::TranslateString("DebuggerMessage", "Can't step over double branch at 0x%08X"), g_state.regs.pc);
|
||||
return false;
|
||||
}
|
||||
|
||||
// skip the delay slot
|
||||
bp_pc += sizeof(Instruction);
|
||||
|
||||
g_host_interface->ReportFormattedDebuggerMessage(
|
||||
g_host_interface->TranslateString("DebuggerMessage", "Stepping over to 0x%08X."), bp_pc);
|
||||
Host::ReportFormattedDebuggerMessage(Host::TranslateString("DebuggerMessage", "Stepping over to 0x%08X."), bp_pc);
|
||||
|
||||
return AddBreakpoint(bp_pc, true);
|
||||
}
|
||||
|
@ -1785,25 +1784,22 @@ bool AddStepOutBreakpoint(u32 max_instructions_to_search)
|
|||
Instruction inst;
|
||||
if (!SafeReadInstruction(ret_pc, &inst.bits))
|
||||
{
|
||||
g_host_interface->ReportFormattedDebuggerMessage(
|
||||
g_host_interface->TranslateString("DebuggerMessage",
|
||||
"Instruction read failed at %08X while searching for function end."),
|
||||
Host::ReportFormattedDebuggerMessage(
|
||||
Host::TranslateString("DebuggerMessage", "Instruction read failed at %08X while searching for function end."),
|
||||
ret_pc);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsReturnInstruction(inst))
|
||||
{
|
||||
g_host_interface->ReportFormattedDebuggerMessage(
|
||||
g_host_interface->TranslateString("DebuggerMessage", "Stepping out to 0x%08X."), ret_pc);
|
||||
Host::ReportFormattedDebuggerMessage(Host::TranslateString("DebuggerMessage", "Stepping out to 0x%08X."), ret_pc);
|
||||
|
||||
return AddBreakpoint(ret_pc, true);
|
||||
}
|
||||
}
|
||||
|
||||
g_host_interface->ReportFormattedDebuggerMessage(
|
||||
g_host_interface->TranslateString("DebuggerMessage",
|
||||
"No return instruction found after %u instructions for step-out at %08X."),
|
||||
Host::ReportFormattedDebuggerMessage(
|
||||
Host::TranslateString("DebuggerMessage", "No return instruction found after %u instructions for step-out at %08X."),
|
||||
max_instructions_to_search, g_state.regs.pc);
|
||||
|
||||
return false;
|
||||
|
@ -1857,18 +1853,18 @@ ALWAYS_INLINE_RELEASE static bool BreakpointCheck()
|
|||
}
|
||||
else
|
||||
{
|
||||
g_host_interface->PauseSystem(true);
|
||||
System::PauseSystem(true);
|
||||
|
||||
if (bp.auto_clear)
|
||||
{
|
||||
g_host_interface->ReportFormattedDebuggerMessage("Stopped execution at 0x%08X.", pc);
|
||||
Host::ReportFormattedDebuggerMessage("Stopped execution at 0x%08X.", pc);
|
||||
s_breakpoints.erase(s_breakpoints.begin() + i);
|
||||
count--;
|
||||
UpdateDebugDispatcherFlag();
|
||||
}
|
||||
else
|
||||
{
|
||||
g_host_interface->ReportFormattedDebuggerMessage("Hit breakpoint %u at 0x%08X.", bp.number, pc);
|
||||
Host::ReportFormattedDebuggerMessage("Hit breakpoint %u at 0x%08X.", bp.number, pc);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
@ -1979,7 +1975,7 @@ void SingleStep()
|
|||
{
|
||||
s_single_step = true;
|
||||
ExecuteDebug();
|
||||
g_host_interface->ReportFormattedDebuggerMessage("Stepped to 0x%08X.", g_state.regs.pc);
|
||||
Host::ReportFormattedDebuggerMessage("Stepped to 0x%08X.", g_state.regs.pc);
|
||||
}
|
||||
|
||||
namespace CodeCache {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#include "digital_controller.h"
|
||||
#include "common/assert.h"
|
||||
#include "host_interface.h"
|
||||
#include "host.h"
|
||||
#include "system.h"
|
||||
#include "util/state_wrapper.h"
|
||||
|
||||
DigitalController::DigitalController() = default;
|
||||
DigitalController::DigitalController(u32 index) : Controller(index) {}
|
||||
|
||||
DigitalController::~DigitalController() = default;
|
||||
|
||||
|
@ -13,16 +13,6 @@ ControllerType DigitalController::GetType() const
|
|||
return ControllerType::DigitalController;
|
||||
}
|
||||
|
||||
std::optional<s32> DigitalController::GetAxisCodeByName(std::string_view axis_name) const
|
||||
{
|
||||
return StaticGetAxisCodeByName(axis_name);
|
||||
}
|
||||
|
||||
std::optional<s32> DigitalController::GetButtonCodeByName(std::string_view button_name) const
|
||||
{
|
||||
return StaticGetButtonCodeByName(button_name);
|
||||
}
|
||||
|
||||
void DigitalController::Reset()
|
||||
{
|
||||
m_transfer_state = TransferState::Idle;
|
||||
|
@ -42,18 +32,25 @@ bool DigitalController::DoState(StateWrapper& sw, bool apply_input_state)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool DigitalController::GetButtonState(s32 button_code) const
|
||||
float DigitalController::GetBindState(u32 index) const
|
||||
{
|
||||
if (button_code < 0 || button_code >= static_cast<s32>(Button::Count))
|
||||
return false;
|
||||
|
||||
const u16 bit = u16(1) << static_cast<u8>(button_code);
|
||||
return ((m_button_state & bit) == 0);
|
||||
if (index < static_cast<u32>(Button::Count))
|
||||
{
|
||||
return static_cast<float>(((m_button_state >> index) & 1u) ^ 1u);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void DigitalController::SetButtonState(Button button, bool pressed)
|
||||
void DigitalController::SetBindState(u32 index, float value)
|
||||
{
|
||||
const u16 bit = u16(1) << static_cast<u8>(button);
|
||||
if (index >= static_cast<u32>(Button::Count))
|
||||
return;
|
||||
|
||||
const bool pressed = (value >= 0.5f);
|
||||
const u16 bit = u16(1) << static_cast<u8>(index);
|
||||
if (pressed)
|
||||
{
|
||||
if (m_button_state & bit)
|
||||
|
@ -70,14 +67,6 @@ void DigitalController::SetButtonState(Button button, bool pressed)
|
|||
}
|
||||
}
|
||||
|
||||
void DigitalController::SetButtonState(s32 button_code, bool pressed)
|
||||
{
|
||||
if (button_code < 0 || button_code >= static_cast<s32>(Button::Count))
|
||||
return;
|
||||
|
||||
SetButtonState(static_cast<Button>(button_code), pressed);
|
||||
}
|
||||
|
||||
u32 DigitalController::GetButtonStateBits() const
|
||||
{
|
||||
return m_button_state ^ 0xFFFF;
|
||||
|
@ -146,87 +135,53 @@ bool DigitalController::Transfer(const u8 data_in, u8* data_out)
|
|||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<DigitalController> DigitalController::Create()
|
||||
std::unique_ptr<DigitalController> DigitalController::Create(u32 index)
|
||||
{
|
||||
return std::make_unique<DigitalController>();
|
||||
return std::make_unique<DigitalController>(index);
|
||||
}
|
||||
|
||||
std::optional<s32> DigitalController::StaticGetAxisCodeByName(std::string_view button_name)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<s32> DigitalController::StaticGetButtonCodeByName(std::string_view button_name)
|
||||
{
|
||||
#define BUTTON(name) \
|
||||
if (button_name == #name) \
|
||||
static const Controller::ControllerBindingInfo s_binding_info[] = {
|
||||
#define BUTTON(name, display_name, button, genb) \
|
||||
{ \
|
||||
return static_cast<s32>(ZeroExtend32(static_cast<u8>(Button::name))); \
|
||||
name, display_name, static_cast<u32>(button), Controller::ControllerBindingType::Button, genb \
|
||||
}
|
||||
|
||||
BUTTON(Select);
|
||||
BUTTON(L3);
|
||||
BUTTON(R3);
|
||||
BUTTON(Start);
|
||||
BUTTON(Up);
|
||||
BUTTON(Right);
|
||||
BUTTON(Down);
|
||||
BUTTON(Left);
|
||||
BUTTON(L2);
|
||||
BUTTON(R2);
|
||||
BUTTON(L1);
|
||||
BUTTON(R1);
|
||||
BUTTON(Triangle);
|
||||
BUTTON(Circle);
|
||||
BUTTON(Cross);
|
||||
BUTTON(Square);
|
||||
|
||||
return std::nullopt;
|
||||
BUTTON("Up", "D-Pad Up", DigitalController::Button::Up, GenericInputBinding::DPadUp),
|
||||
BUTTON("Right", "D-Pad Right", DigitalController::Button::Right, GenericInputBinding::DPadRight),
|
||||
BUTTON("Down", "D-Pad Down", DigitalController::Button::Down, GenericInputBinding::DPadDown),
|
||||
BUTTON("Left", "D-Pad Left", DigitalController::Button::Left, GenericInputBinding::DPadLeft),
|
||||
BUTTON("Triangle", "Triangle", DigitalController::Button::Triangle, GenericInputBinding::Triangle),
|
||||
BUTTON("Circle", "Circle", DigitalController::Button::Circle, GenericInputBinding::Circle),
|
||||
BUTTON("Cross", "Cross", DigitalController::Button::Cross, GenericInputBinding::Cross),
|
||||
BUTTON("Square", "Square", DigitalController::Button::Square, GenericInputBinding::Square),
|
||||
BUTTON("Select", "Select", DigitalController::Button::Select, GenericInputBinding::Select),
|
||||
BUTTON("Start", "Start", DigitalController::Button::Start, GenericInputBinding::Start),
|
||||
BUTTON("L1", "L1", DigitalController::Button::L1, GenericInputBinding::L1),
|
||||
BUTTON("R1", "R1", DigitalController::Button::R1, GenericInputBinding::R1),
|
||||
BUTTON("L2", "L2", DigitalController::Button::L2, GenericInputBinding::L2),
|
||||
BUTTON("R2", "R2", DigitalController::Button::R2, GenericInputBinding::R2),
|
||||
|
||||
#undef BUTTON
|
||||
}
|
||||
};
|
||||
|
||||
Controller::AxisList DigitalController::StaticGetAxisNames()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
static const SettingInfo s_settings[] = {
|
||||
{SettingInfo::Type::Boolean, "ForcePopnControllerMode",
|
||||
TRANSLATABLE("DigitalController", "Force Pop'n Controller Mode"),
|
||||
TRANSLATABLE("DigitalController", "Forces the Digital Controller to act as a Pop'n Controller."), "false"}};
|
||||
|
||||
Controller::ButtonList DigitalController::StaticGetButtonNames()
|
||||
{
|
||||
return {{TRANSLATABLE("DigitalController", "Up"), static_cast<s32>(Button::Up)},
|
||||
{TRANSLATABLE("DigitalController", "Down"), static_cast<s32>(Button::Down)},
|
||||
{TRANSLATABLE("DigitalController", "Left"), static_cast<s32>(Button::Left)},
|
||||
{TRANSLATABLE("DigitalController", "Right"), static_cast<s32>(Button::Right)},
|
||||
{TRANSLATABLE("DigitalController", "Select"), static_cast<s32>(Button::Select)},
|
||||
{TRANSLATABLE("DigitalController", "Start"), static_cast<s32>(Button::Start)},
|
||||
{TRANSLATABLE("DigitalController", "Triangle"), static_cast<s32>(Button::Triangle)},
|
||||
{TRANSLATABLE("DigitalController", "Cross"), static_cast<s32>(Button::Cross)},
|
||||
{TRANSLATABLE("DigitalController", "Circle"), static_cast<s32>(Button::Circle)},
|
||||
{TRANSLATABLE("DigitalController", "Square"), static_cast<s32>(Button::Square)},
|
||||
{TRANSLATABLE("DigitalController", "L1"), static_cast<s32>(Button::L1)},
|
||||
{TRANSLATABLE("DigitalController", "L2"), static_cast<s32>(Button::L2)},
|
||||
{TRANSLATABLE("DigitalController", "R1"), static_cast<s32>(Button::R1)},
|
||||
{TRANSLATABLE("DigitalController", "R2"), static_cast<s32>(Button::R2)}};
|
||||
}
|
||||
const Controller::ControllerInfo DigitalController::INFO = {ControllerType::DigitalController,
|
||||
"DigitalController",
|
||||
TRANSLATABLE("ControllerType", "Digital Controller"),
|
||||
s_binding_info,
|
||||
countof(s_binding_info),
|
||||
s_settings,
|
||||
countof(s_settings),
|
||||
Controller::VibrationCapabilities::NoVibration};
|
||||
|
||||
u32 DigitalController::StaticGetVibrationMotorCount()
|
||||
void DigitalController::LoadSettings(SettingsInterface& si, const char* section)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Controller::SettingList DigitalController::StaticGetSettings()
|
||||
{
|
||||
static constexpr std::array<SettingInfo, 1> settings = {
|
||||
{{SettingInfo::Type::Boolean, "ForcePopnControllerMode",
|
||||
TRANSLATABLE("DigitalController", "Force Pop'n Controller Mode"),
|
||||
TRANSLATABLE("DigitalController", "Forces the Digital Controller to act as a Pop'n Controller."), "false"}}};
|
||||
return SettingList(settings.begin(), settings.end());
|
||||
}
|
||||
|
||||
void DigitalController::LoadSettings(const char* section)
|
||||
{
|
||||
Controller::LoadSettings(section);
|
||||
m_popn_controller_mode = g_host_interface->GetBoolSettingValue(section, "ForcePopnControllerMode", false);
|
||||
Controller::LoadSettings(si, section);
|
||||
m_popn_controller_mode = si.GetBoolValue(section, "ForcePopnControllerMode", false);
|
||||
}
|
||||
|
||||
u8 DigitalController::GetButtonsLSBMask() const
|
||||
|
|
|
@ -28,34 +28,26 @@ public:
|
|||
Count
|
||||
};
|
||||
|
||||
DigitalController();
|
||||
static const Controller::ControllerInfo INFO;
|
||||
|
||||
DigitalController(u32 index);
|
||||
~DigitalController() override;
|
||||
|
||||
static std::unique_ptr<DigitalController> Create();
|
||||
static std::optional<s32> StaticGetAxisCodeByName(std::string_view button_name);
|
||||
static std::optional<s32> StaticGetButtonCodeByName(std::string_view button_name);
|
||||
static AxisList StaticGetAxisNames();
|
||||
static ButtonList StaticGetButtonNames();
|
||||
static u32 StaticGetVibrationMotorCount();
|
||||
static SettingList StaticGetSettings();
|
||||
static std::unique_ptr<DigitalController> Create(u32 index);
|
||||
|
||||
ControllerType GetType() const override;
|
||||
std::optional<s32> GetAxisCodeByName(std::string_view axis_name) const override;
|
||||
std::optional<s32> GetButtonCodeByName(std::string_view button_name) const override;
|
||||
|
||||
void Reset() override;
|
||||
bool DoState(StateWrapper& sw, bool apply_input_state) override;
|
||||
|
||||
bool GetButtonState(s32 button_code) const override;
|
||||
void SetButtonState(s32 button_code, bool pressed) override;
|
||||
float GetBindState(u32 index) const override;
|
||||
void SetBindState(u32 index, float value) override;
|
||||
u32 GetButtonStateBits() const override;
|
||||
|
||||
void ResetTransferState() override;
|
||||
bool Transfer(const u8 data_in, u8* data_out) override;
|
||||
|
||||
void SetButtonState(Button button, bool pressed);
|
||||
|
||||
void LoadSettings(const char* section) override;
|
||||
void LoadSettings(SettingsInterface& si, const char* section) override;
|
||||
|
||||
private:
|
||||
enum class TransferState : u8
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "cpu_code_cache.h"
|
||||
#include "cpu_core.h"
|
||||
#include "gpu.h"
|
||||
#include "host.h"
|
||||
#include "imgui.h"
|
||||
#include "interrupt_controller.h"
|
||||
#include "mdec.h"
|
||||
|
@ -626,7 +627,7 @@ void DMA::DrawDebugStateWindow()
|
|||
{"MDECin", "MDECout", "GPU", "CDROM", "SPU", "PIO", "OTC"}};
|
||||
static constexpr std::array<const char*, 4> sync_mode_names = {{"Manual", "Request", "LinkedList", "Reserved"}};
|
||||
|
||||
const float framebuffer_scale = ImGui::GetIO().DisplayFramebufferScale.x;
|
||||
const float framebuffer_scale = Host::GetOSDScale();
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(850.0f * framebuffer_scale, 250.0f * framebuffer_scale), ImGuiCond_FirstUseEver);
|
||||
if (!ImGui::Begin("DMA State", nullptr))
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
#pragma once
|
||||
#include "core/types.h"
|
||||
#include "util/cd_image_hasher.h"
|
||||
#include <bitset>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
class CDImage;
|
||||
|
||||
struct Settings;
|
||||
|
||||
namespace GameDatabase {
|
||||
enum class CompatibilityRating : u32
|
||||
{
|
||||
Unknown = 0,
|
||||
DoesntBoot = 1,
|
||||
CrashesInIntro = 2,
|
||||
CrashesInGame = 3,
|
||||
GraphicalAudioIssues = 4,
|
||||
NoIssues = 5,
|
||||
Count,
|
||||
};
|
||||
|
||||
enum class Trait : u32
|
||||
{
|
||||
ForceInterpreter,
|
||||
ForceSoftwareRenderer,
|
||||
ForceSoftwareRendererForReadbacks,
|
||||
ForceInterlacing,
|
||||
DisableTrueColor,
|
||||
DisableUpscaling,
|
||||
DisableScaledDithering,
|
||||
DisableForceNTSCTimings,
|
||||
DisableWidescreen,
|
||||
DisablePGXP,
|
||||
DisablePGXPCulling,
|
||||
DisablePGXPTextureCorrection,
|
||||
DisablePGXPDepthBuffer,
|
||||
ForcePGXPVertexCache,
|
||||
ForcePGXPCPUMode,
|
||||
ForceRecompilerMemoryExceptions,
|
||||
ForceRecompilerICache,
|
||||
ForceRecompilerLUTFastmem,
|
||||
|
||||
Count
|
||||
};
|
||||
|
||||
struct Entry
|
||||
{
|
||||
// TODO: Make string_view.
|
||||
std::string serial;
|
||||
std::string title;
|
||||
std::string genre;
|
||||
std::string developer;
|
||||
std::string publisher;
|
||||
u64 release_date;
|
||||
u8 min_players;
|
||||
u8 max_players;
|
||||
u8 min_blocks;
|
||||
u8 max_blocks;
|
||||
u32 supported_controllers;
|
||||
CompatibilityRating compatibility;
|
||||
|
||||
std::bitset<static_cast<int>(Trait::Count)> traits{};
|
||||
std::optional<s16> display_active_start_offset;
|
||||
std::optional<s16> display_active_end_offset;
|
||||
std::optional<s8> display_line_start_offset;
|
||||
std::optional<s8> display_line_end_offset;
|
||||
std::optional<u32> dma_max_slice_ticks;
|
||||
std::optional<u32> dma_halt_ticks;
|
||||
std::optional<u32> gpu_fifo_size;
|
||||
std::optional<u32> gpu_max_run_ahead;
|
||||
std::optional<float> gpu_pgxp_tolerance;
|
||||
std::optional<float> gpu_pgxp_depth_threshold;
|
||||
|
||||
ALWAYS_INLINE bool HasTrait(Trait trait) const { return traits[static_cast<int>(trait)]; }
|
||||
|
||||
void ApplySettings(Settings& settings, bool display_osd_messages) const;
|
||||
};
|
||||
|
||||
void EnsureLoaded();
|
||||
void Unload();
|
||||
|
||||
const Entry* GetEntryForDisc(CDImage* image);
|
||||
const Entry* GetEntryForSerial(const std::string_view& serial);
|
||||
const Entry* GetEntryForCode(const std::string_view& code);
|
||||
std::string GetSerialForDisc(CDImage* image);
|
||||
std::string GetSerialForPath(const char* path);
|
||||
|
||||
const char* GetTraitName(Trait trait);
|
||||
const char* GetTraitDisplayName(Trait trait);
|
||||
|
||||
const char* GetCompatibilityRatingName(CompatibilityRating rating);
|
||||
const char* GetCompatibilityRatingDisplayName(CompatibilityRating rating);
|
||||
|
||||
/// Map of track hashes for image verification
|
||||
struct TrackData
|
||||
{
|
||||
TrackData(std::vector<std::string> codes, std::string revisionString, uint32_t revision)
|
||||
: codes(std::move(codes)), revisionString(revisionString), revision(revision)
|
||||
{
|
||||
}
|
||||
|
||||
friend bool operator==(const TrackData& left, const TrackData& right)
|
||||
{
|
||||
// 'revisionString' is deliberately ignored in comparisons as it's redundant with comparing 'revision'! Do not
|
||||
// change!
|
||||
return left.codes == right.codes && left.revision == right.revision;
|
||||
}
|
||||
|
||||
std::vector<std::string> codes;
|
||||
std::string revisionString;
|
||||
uint32_t revision;
|
||||
};
|
||||
|
||||
using TrackHashesMap = std::multimap<CDImageHasher::Hash, TrackData>;
|
||||
const TrackHashesMap& GetTrackHashesMap();
|
||||
void EnsureTrackHashesMapLoaded();
|
||||
|
||||
} // namespace GameDatabase
|
|
@ -4,7 +4,7 @@
|
|||
#include "common/log.h"
|
||||
#include "common/string_util.h"
|
||||
#include "cpu_core.h"
|
||||
#include "frontend-common/common_host_interface.h"
|
||||
#include "frontend-common/common_host.h"
|
||||
#include "system.h"
|
||||
#include <functional>
|
||||
#include <iomanip>
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
#include "common/log.h"
|
||||
#include "common/string_util.h"
|
||||
#include "dma.h"
|
||||
#include "host.h"
|
||||
#include "host_display.h"
|
||||
#include "host_interface.h"
|
||||
#include "imgui.h"
|
||||
#include "interrupt_controller.h"
|
||||
#include "settings.h"
|
||||
|
@ -24,9 +24,8 @@ GPU::GPU() = default;
|
|||
|
||||
GPU::~GPU() = default;
|
||||
|
||||
bool GPU::Initialize(HostDisplay* host_display)
|
||||
bool GPU::Initialize()
|
||||
{
|
||||
m_host_display = host_display;
|
||||
m_force_progressive_scan = g_settings.gpu_disable_interlacing;
|
||||
m_force_ntsc_timings = g_settings.gpu_force_ntsc_timings;
|
||||
m_crtc_tick_event = TimingEvents::CreateTimingEvent(
|
||||
|
@ -41,6 +40,16 @@ bool GPU::Initialize(HostDisplay* host_display)
|
|||
m_max_run_ahead = g_settings.gpu_max_run_ahead;
|
||||
m_console_is_pal = System::IsPALRegion();
|
||||
UpdateCRTCConfig();
|
||||
|
||||
g_host_display->SetDisplayLinearFiltering(g_settings.display_linear_filtering);
|
||||
g_host_display->SetDisplayIntegerScaling(g_settings.display_integer_scaling);
|
||||
g_host_display->SetDisplayStretch(g_settings.display_stretch);
|
||||
if (g_settings.display_post_processing &&
|
||||
!g_host_display->SetPostProcessingChain(g_settings.display_post_process_chain))
|
||||
{
|
||||
Host::AddOSDMessage(Host::TranslateStdString("OSDMessage", "Failed to load post processing shader chain."), 20.0f);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -59,6 +68,10 @@ void GPU::UpdateSettings()
|
|||
|
||||
// Crop mode calls this, so recalculate the display area
|
||||
UpdateCRTCDisplayParameters();
|
||||
|
||||
g_host_display->SetDisplayLinearFiltering(g_settings.display_linear_filtering);
|
||||
g_host_display->SetDisplayIntegerScaling(g_settings.display_integer_scaling);
|
||||
g_host_display->SetDisplayStretch(g_settings.display_stretch);
|
||||
}
|
||||
|
||||
bool GPU::IsHardwareRenderer()
|
||||
|
@ -962,9 +975,9 @@ void GPU::UpdateCommandTickEvent()
|
|||
bool GPU::ConvertScreenCoordinatesToBeamTicksAndLines(s32 window_x, s32 window_y, float x_scale, u32* out_tick,
|
||||
u32* out_line) const
|
||||
{
|
||||
auto [display_x, display_y] = m_host_display->ConvertWindowCoordinatesToDisplayCoordinates(
|
||||
window_x, window_y, m_host_display->GetWindowWidth(), m_host_display->GetWindowHeight(),
|
||||
m_host_display->GetDisplayTopMargin());
|
||||
auto [display_x, display_y] = g_host_display->ConvertWindowCoordinatesToDisplayCoordinates(
|
||||
window_x, window_y, g_host_display->GetWindowWidth(), g_host_display->GetWindowHeight(),
|
||||
g_host_display->GetDisplayTopMargin());
|
||||
|
||||
if (x_scale != 1.0f)
|
||||
{
|
||||
|
@ -1551,7 +1564,7 @@ bool GPU::DumpVRAMToFile(const char* filename, u32 width, u32 height, u32 stride
|
|||
|
||||
void GPU::DrawDebugStateWindow()
|
||||
{
|
||||
const float framebuffer_scale = ImGui::GetIO().DisplayFramebufferScale.x;
|
||||
const float framebuffer_scale = Host::GetOSDScale();
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(450.0f * framebuffer_scale, 550.0f * framebuffer_scale), ImGuiCond_FirstUseEver);
|
||||
if (!ImGui::Begin("GPU", nullptr))
|
||||
|
|
|
@ -75,7 +75,7 @@ public:
|
|||
|
||||
virtual GPURenderer GetRendererType() const = 0;
|
||||
|
||||
virtual bool Initialize(HostDisplay* host_display);
|
||||
virtual bool Initialize();
|
||||
virtual void Reset(bool clear_vram);
|
||||
virtual bool DoState(StateWrapper& sw, HostDisplayTexture** save_to_texture, bool update_display);
|
||||
|
||||
|
@ -319,8 +319,6 @@ protected:
|
|||
AddCommandTicks(std::max(width, height));
|
||||
}
|
||||
|
||||
HostDisplay* m_host_display = nullptr;
|
||||
|
||||
std::unique_ptr<TimingEvent> m_crtc_tick_event;
|
||||
std::unique_ptr<TimingEvent> m_command_tick_event;
|
||||
|
||||
|
|
|
@ -173,7 +173,7 @@ void GPUBackend::StartGPUThread()
|
|||
{
|
||||
m_gpu_loop_done.store(false);
|
||||
m_use_gpu_thread = true;
|
||||
m_gpu_thread = std::thread(&GPUBackend::RunGPULoop, this);
|
||||
m_gpu_thread.Start([this]() { RunGPULoop(); });
|
||||
Log_InfoPrint("GPU thread started.");
|
||||
}
|
||||
|
||||
|
@ -184,7 +184,7 @@ void GPUBackend::StopGPUThread()
|
|||
|
||||
m_gpu_loop_done.store(true);
|
||||
WakeGPUThread();
|
||||
m_gpu_thread.join();
|
||||
m_gpu_thread.Join();
|
||||
m_use_gpu_thread = false;
|
||||
Log_InfoPrint("GPU thread stopped.");
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
#include "common/event.h"
|
||||
#include "common/heap_array.h"
|
||||
#include "common/threading.h"
|
||||
#include "gpu_types.h"
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
|
@ -20,6 +21,7 @@ public:
|
|||
virtual ~GPUBackend();
|
||||
|
||||
ALWAYS_INLINE u16* GetVRAM() const { return m_vram_ptr; }
|
||||
ALWAYS_INLINE const Threading::Thread* GetThread() const { return m_use_gpu_thread ? &m_gpu_thread : nullptr; }
|
||||
|
||||
virtual bool Initialize(bool force_thread);
|
||||
virtual void UpdateSettings();
|
||||
|
@ -67,7 +69,7 @@ protected:
|
|||
Common::Event m_sync_event;
|
||||
std::atomic_bool m_gpu_thread_sleeping{false};
|
||||
std::atomic_bool m_gpu_loop_done{false};
|
||||
std::thread m_gpu_thread;
|
||||
Threading::Thread m_gpu_thread;
|
||||
bool m_use_gpu_thread = false;
|
||||
|
||||
std::mutex m_sync_mutex;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "common/log.h"
|
||||
#include "cpu_core.h"
|
||||
#include "gpu_sw_backend.h"
|
||||
#include "host.h"
|
||||
#include "imgui.h"
|
||||
#include "pgxp.h"
|
||||
#include "settings.h"
|
||||
|
@ -43,14 +44,14 @@ GPU_HW::~GPU_HW()
|
|||
}
|
||||
}
|
||||
|
||||
bool GPU_HW::Initialize(HostDisplay* host_display)
|
||||
bool GPU_HW::Initialize()
|
||||
{
|
||||
if (!GPU::Initialize(host_display))
|
||||
if (!GPU::Initialize())
|
||||
return false;
|
||||
|
||||
m_resolution_scale = CalculateResolutionScale();
|
||||
m_multisamples = std::min(g_settings.gpu_multisamples, m_max_multisamples);
|
||||
m_render_api = host_display->GetRenderAPI();
|
||||
m_render_api = g_host_display->GetRenderAPI();
|
||||
m_per_sample_shading = g_settings.gpu_per_sample_shading && m_supports_per_sample_shading;
|
||||
m_true_color = g_settings.gpu_true_color;
|
||||
m_scaled_dithering = g_settings.gpu_scaled_dithering;
|
||||
|
@ -61,29 +62,26 @@ bool GPU_HW::Initialize(HostDisplay* host_display)
|
|||
|
||||
if (m_multisamples != g_settings.gpu_multisamples)
|
||||
{
|
||||
g_host_interface->AddFormattedOSDMessage(
|
||||
20.0f, g_host_interface->TranslateString("OSDMessage", "%ux MSAA is not supported, using %ux instead."),
|
||||
g_settings.gpu_multisamples, m_multisamples);
|
||||
Host::AddFormattedOSDMessage(20.0f,
|
||||
Host::TranslateString("OSDMessage", "%ux MSAA is not supported, using %ux instead."),
|
||||
g_settings.gpu_multisamples, m_multisamples);
|
||||
}
|
||||
if (!m_per_sample_shading && g_settings.gpu_per_sample_shading)
|
||||
{
|
||||
g_host_interface->AddOSDMessage(
|
||||
g_host_interface->TranslateStdString("OSDMessage", "SSAA is not supported, using MSAA instead."), 20.0f);
|
||||
Host::AddOSDMessage(Host::TranslateStdString("OSDMessage", "SSAA is not supported, using MSAA instead."), 20.0f);
|
||||
}
|
||||
if (!m_supports_dual_source_blend && TextureFilterRequiresDualSourceBlend(m_texture_filtering))
|
||||
{
|
||||
g_host_interface->AddFormattedOSDMessage(
|
||||
20.0f,
|
||||
g_host_interface->TranslateString("OSDMessage",
|
||||
"Texture filter '%s' is not supported with the current renderer."),
|
||||
Host::AddFormattedOSDMessage(
|
||||
20.0f, Host::TranslateString("OSDMessage", "Texture filter '%s' is not supported with the current renderer."),
|
||||
Settings::GetTextureFilterDisplayName(m_texture_filtering));
|
||||
m_texture_filtering = GPUTextureFilter::Nearest;
|
||||
}
|
||||
if (!m_supports_adaptive_downsampling && g_settings.gpu_resolution_scale > 1 &&
|
||||
g_settings.gpu_downsample_mode == GPUDownsampleMode::Adaptive)
|
||||
{
|
||||
g_host_interface->AddOSDMessage(
|
||||
g_host_interface->TranslateStdString(
|
||||
Host::AddOSDMessage(
|
||||
Host::TranslateStdString(
|
||||
"OSDMessage", "Adaptive downsampling is not supported with the current renderer, using box filter instead."),
|
||||
20.0f);
|
||||
}
|
||||
|
@ -149,27 +147,26 @@ void GPU_HW::UpdateHWSettings(bool* framebuffer_changed, bool* shaders_changed)
|
|||
|
||||
if (m_resolution_scale != resolution_scale)
|
||||
{
|
||||
g_host_interface->AddKeyedFormattedOSDMessage(
|
||||
Host::AddKeyedFormattedOSDMessage(
|
||||
"ResolutionScale", 10.0f,
|
||||
g_host_interface->TranslateString("OSDMessage", "Resolution scale set to %ux (display %ux%u, VRAM %ux%u)"),
|
||||
resolution_scale, m_crtc_state.display_vram_width * resolution_scale,
|
||||
resolution_scale * m_crtc_state.display_vram_height, VRAM_WIDTH * resolution_scale,
|
||||
VRAM_HEIGHT * resolution_scale);
|
||||
Host::TranslateString("OSDMessage", "Resolution scale set to %ux (display %ux%u, VRAM %ux%u)"), resolution_scale,
|
||||
m_crtc_state.display_vram_width * resolution_scale, resolution_scale * m_crtc_state.display_vram_height,
|
||||
VRAM_WIDTH * resolution_scale, VRAM_HEIGHT * resolution_scale);
|
||||
}
|
||||
|
||||
if (m_multisamples != multisamples || m_per_sample_shading != per_sample_shading)
|
||||
{
|
||||
if (per_sample_shading)
|
||||
{
|
||||
g_host_interface->AddKeyedFormattedOSDMessage(
|
||||
"Multisampling", 10.0f,
|
||||
g_host_interface->TranslateString("OSDMessage", "Multisample anti-aliasing set to %ux (SSAA)."), multisamples);
|
||||
Host::AddKeyedFormattedOSDMessage(
|
||||
"Multisampling", 10.0f, Host::TranslateString("OSDMessage", "Multisample anti-aliasing set to %ux (SSAA)."),
|
||||
multisamples);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_host_interface->AddKeyedFormattedOSDMessage(
|
||||
"Multisampling", 10.0f,
|
||||
g_host_interface->TranslateString("OSDMessage", "Multisample anti-aliasing set to %ux."), multisamples);
|
||||
Host::AddKeyedFormattedOSDMessage("Multisampling", 10.0f,
|
||||
Host::TranslateString("OSDMessage", "Multisample anti-aliasing set to %ux."),
|
||||
multisamples);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,7 +212,7 @@ u32 GPU_HW::CalculateResolutionScale() const
|
|||
(m_console_is_pal ? (PAL_VERTICAL_ACTIVE_END - PAL_VERTICAL_ACTIVE_START) :
|
||||
(NTSC_VERTICAL_ACTIVE_END - NTSC_VERTICAL_ACTIVE_START));
|
||||
const s32 preferred_scale =
|
||||
static_cast<s32>(std::ceil(static_cast<float>(m_host_display->GetWindowHeight()) / height));
|
||||
static_cast<s32>(std::ceil(static_cast<float>(g_host_display->GetWindowHeight()) / height));
|
||||
Log_InfoPrintf("Height = %d, preferred scale = %d", height, preferred_scale);
|
||||
|
||||
scale = static_cast<u32>(std::clamp<s32>(preferred_scale, 1, m_max_resolution_scale));
|
||||
|
@ -229,10 +226,9 @@ u32 GPU_HW::CalculateResolutionScale() const
|
|||
|
||||
if (g_settings.gpu_resolution_scale != 0)
|
||||
{
|
||||
g_host_interface->AddFormattedOSDMessage(
|
||||
Host::AddFormattedOSDMessage(
|
||||
10.0f,
|
||||
g_host_interface->TranslateString("OSDMessage",
|
||||
"Resolution scale %ux not supported for adaptive smoothing, using %ux."),
|
||||
Host::TranslateString("OSDMessage", "Resolution scale %ux not supported for adaptive smoothing, using %ux."),
|
||||
scale, new_scale);
|
||||
}
|
||||
|
||||
|
@ -1410,7 +1406,7 @@ void GPU_HW::DrawRendererStats(bool is_idle_frame)
|
|||
const auto& stats = m_last_renderer_stats;
|
||||
|
||||
ImGui::Columns(2);
|
||||
ImGui::SetColumnWidth(0, 200.0f * ImGui::GetIO().DisplayFramebufferScale.x);
|
||||
ImGui::SetColumnWidth(0, 200.0f * Host::GetOSDScale());
|
||||
|
||||
ImGui::TextUnformatted("Resolution Scale:");
|
||||
ImGui::NextColumn();
|
||||
|
@ -1487,7 +1483,7 @@ void GPU_HW::ShaderCompileProgressTracker::Increment()
|
|||
const u64 tv = Common::Timer::GetCurrentValue();
|
||||
if ((tv - m_start_time) >= m_min_time && (tv - m_last_update_time) >= m_update_interval)
|
||||
{
|
||||
g_host_interface->DisplayLoadingScreen(m_title.c_str(), 0, static_cast<int>(m_total), static_cast<int>(m_progress));
|
||||
Host::DisplayLoadingScreen(m_title.c_str(), 0, static_cast<int>(m_total), static_cast<int>(m_progress));
|
||||
m_last_update_time = tv;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ public:
|
|||
GPU_HW();
|
||||
virtual ~GPU_HW();
|
||||
|
||||
virtual bool Initialize(HostDisplay* host_display) override;
|
||||
virtual bool Initialize() override;
|
||||
virtual void Reset(bool clear_vram) override;
|
||||
virtual bool DoState(StateWrapper& sw, HostDisplayTexture** host_texture, bool update_display) override;
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include "gpu_hw_shadergen.h"
|
||||
#include "gpu_sw_backend.h"
|
||||
#include "host_display.h"
|
||||
#include "host_interface.h"
|
||||
#include "shader_cache_version.h"
|
||||
#include "system.h"
|
||||
#include "util/state_wrapper.h"
|
||||
|
@ -16,8 +15,11 @@ GPU_HW_D3D11::GPU_HW_D3D11() = default;
|
|||
|
||||
GPU_HW_D3D11::~GPU_HW_D3D11()
|
||||
{
|
||||
if (m_host_display)
|
||||
m_host_display->ClearDisplayTexture();
|
||||
if (g_host_display)
|
||||
{
|
||||
g_host_display->ClearDisplayTexture();
|
||||
ResetGraphicsAPIState();
|
||||
}
|
||||
|
||||
if (m_context)
|
||||
m_context->ClearState();
|
||||
|
@ -31,22 +33,22 @@ GPURenderer GPU_HW_D3D11::GetRendererType() const
|
|||
return GPURenderer::HardwareD3D11;
|
||||
}
|
||||
|
||||
bool GPU_HW_D3D11::Initialize(HostDisplay* host_display)
|
||||
bool GPU_HW_D3D11::Initialize()
|
||||
{
|
||||
if (host_display->GetRenderAPI() != HostDisplay::RenderAPI::D3D11)
|
||||
if (!Host::AcquireHostDisplay(HostDisplay::RenderAPI::D3D11))
|
||||
{
|
||||
Log_ErrorPrintf("Host render API is incompatible");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_device = static_cast<ID3D11Device*>(host_display->GetRenderDevice());
|
||||
m_context = static_cast<ID3D11DeviceContext*>(host_display->GetRenderContext());
|
||||
m_device = static_cast<ID3D11Device*>(g_host_display->GetRenderDevice());
|
||||
m_context = static_cast<ID3D11DeviceContext*>(g_host_display->GetRenderContext());
|
||||
if (!m_device || !m_context)
|
||||
return false;
|
||||
|
||||
SetCapabilities();
|
||||
|
||||
if (!GPU_HW::Initialize(host_display))
|
||||
if (!GPU_HW::Initialize())
|
||||
return false;
|
||||
|
||||
if (!CreateFramebuffer())
|
||||
|
@ -122,7 +124,7 @@ bool GPU_HW_D3D11::DoState(StateWrapper& sw, HostDisplayTexture** host_texture,
|
|||
{
|
||||
delete tex;
|
||||
|
||||
tex = m_host_display
|
||||
tex = g_host_display
|
||||
->CreateTexture(m_vram_texture.GetWidth(), m_vram_texture.GetHeight(), 1, 1,
|
||||
m_vram_texture.GetSamples(), HostDisplayPixelFormat::RGBA8, nullptr, 0, false)
|
||||
.release();
|
||||
|
@ -178,7 +180,7 @@ void GPU_HW_D3D11::UpdateSettings()
|
|||
RestoreGraphicsAPIState();
|
||||
ReadVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT);
|
||||
ResetGraphicsAPIState();
|
||||
m_host_display->ClearDisplayTexture();
|
||||
g_host_display->ClearDisplayTexture();
|
||||
CreateFramebuffer();
|
||||
}
|
||||
|
||||
|
@ -501,10 +503,10 @@ void GPU_HW_D3D11::DestroyStateObjects()
|
|||
bool GPU_HW_D3D11::CompileShaders()
|
||||
{
|
||||
D3D11::ShaderCache shader_cache;
|
||||
shader_cache.Open(g_host_interface->GetShaderCacheBasePath(), m_device->GetFeatureLevel(), SHADER_CACHE_VERSION,
|
||||
shader_cache.Open(EmuFolders::Cache, m_device->GetFeatureLevel(), SHADER_CACHE_VERSION,
|
||||
g_settings.gpu_use_debug_device);
|
||||
|
||||
GPU_HW_ShaderGen shadergen(m_host_display->GetRenderAPI(), m_resolution_scale, m_multisamples, m_per_sample_shading,
|
||||
GPU_HW_ShaderGen shadergen(g_host_display->GetRenderAPI(), m_resolution_scale, m_multisamples, m_per_sample_shading,
|
||||
m_true_color, m_scaled_dithering, m_texture_filtering, m_using_uv_limits,
|
||||
m_pgxp_depth_buffer, m_supports_dual_source_blend);
|
||||
|
||||
|
@ -826,7 +828,7 @@ void GPU_HW_D3D11::ClearDisplay()
|
|||
{
|
||||
GPU_HW::ClearDisplay();
|
||||
|
||||
m_host_display->ClearDisplayTexture();
|
||||
g_host_display->ClearDisplayTexture();
|
||||
|
||||
static constexpr std::array<float, 4> clear_color = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
m_context->ClearRenderTargetView(m_display_texture.GetD3DRTV(), clear_color.data());
|
||||
|
@ -841,23 +843,23 @@ void GPU_HW_D3D11::UpdateDisplay()
|
|||
if (IsUsingMultisampling())
|
||||
{
|
||||
UpdateVRAMReadTexture();
|
||||
m_host_display->SetDisplayTexture(m_vram_read_texture.GetD3DSRV(), HostDisplayPixelFormat::RGBA8,
|
||||
g_host_display->SetDisplayTexture(m_vram_read_texture.GetD3DSRV(), HostDisplayPixelFormat::RGBA8,
|
||||
m_vram_read_texture.GetWidth(), m_vram_read_texture.GetHeight(), 0, 0,
|
||||
m_vram_read_texture.GetWidth(), m_vram_read_texture.GetHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_host_display->SetDisplayTexture(m_vram_texture.GetD3DSRV(), HostDisplayPixelFormat::RGBA8,
|
||||
g_host_display->SetDisplayTexture(m_vram_texture.GetD3DSRV(), HostDisplayPixelFormat::RGBA8,
|
||||
m_vram_texture.GetWidth(), m_vram_texture.GetHeight(), 0, 0,
|
||||
m_vram_texture.GetWidth(), m_vram_texture.GetHeight());
|
||||
}
|
||||
|
||||
m_host_display->SetDisplayParameters(VRAM_WIDTH, VRAM_HEIGHT, 0, 0, VRAM_WIDTH, VRAM_HEIGHT,
|
||||
g_host_display->SetDisplayParameters(VRAM_WIDTH, VRAM_HEIGHT, 0, 0, VRAM_WIDTH, VRAM_HEIGHT,
|
||||
static_cast<float>(VRAM_WIDTH) / static_cast<float>(VRAM_HEIGHT));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_host_display->SetDisplayParameters(m_crtc_state.display_width, m_crtc_state.display_height,
|
||||
g_host_display->SetDisplayParameters(m_crtc_state.display_width, m_crtc_state.display_height,
|
||||
m_crtc_state.display_origin_left, m_crtc_state.display_origin_top,
|
||||
m_crtc_state.display_vram_width, m_crtc_state.display_vram_height,
|
||||
GetDisplayAspectRatio());
|
||||
|
@ -875,7 +877,7 @@ void GPU_HW_D3D11::UpdateDisplay()
|
|||
|
||||
if (IsDisplayDisabled())
|
||||
{
|
||||
m_host_display->ClearDisplayTexture();
|
||||
g_host_display->ClearDisplayTexture();
|
||||
}
|
||||
else if (!m_GPUSTAT.display_area_color_depth_24 && interlaced == InterlacedRenderMode::None &&
|
||||
!IsUsingMultisampling() && (scaled_vram_offset_x + scaled_display_width) <= m_vram_texture.GetWidth() &&
|
||||
|
@ -889,7 +891,7 @@ void GPU_HW_D3D11::UpdateDisplay()
|
|||
}
|
||||
else
|
||||
{
|
||||
m_host_display->SetDisplayTexture(m_vram_texture.GetD3DSRV(), HostDisplayPixelFormat::RGBA8,
|
||||
g_host_display->SetDisplayTexture(m_vram_texture.GetD3DSRV(), HostDisplayPixelFormat::RGBA8,
|
||||
m_vram_texture.GetWidth(), m_vram_texture.GetHeight(), scaled_vram_offset_x,
|
||||
scaled_vram_offset_y, scaled_display_width, scaled_display_height);
|
||||
}
|
||||
|
@ -921,7 +923,7 @@ void GPU_HW_D3D11::UpdateDisplay()
|
|||
}
|
||||
else
|
||||
{
|
||||
m_host_display->SetDisplayTexture(m_display_texture.GetD3DSRV(), HostDisplayPixelFormat::RGBA8,
|
||||
g_host_display->SetDisplayTexture(m_display_texture.GetD3DSRV(), HostDisplayPixelFormat::RGBA8,
|
||||
m_display_texture.GetWidth(), m_display_texture.GetHeight(), 0, 0,
|
||||
scaled_display_width, scaled_display_height);
|
||||
}
|
||||
|
@ -1202,7 +1204,7 @@ void GPU_HW_D3D11::DownsampleFramebufferAdaptive(D3D11::Texture& source, u32 lef
|
|||
|
||||
RestoreGraphicsAPIState();
|
||||
|
||||
m_host_display->SetDisplayTexture(m_display_texture.GetD3DSRV(), HostDisplayPixelFormat::RGBA8,
|
||||
g_host_display->SetDisplayTexture(m_display_texture.GetD3DSRV(), HostDisplayPixelFormat::RGBA8,
|
||||
m_display_texture.GetWidth(), m_display_texture.GetHeight(), left, top, width,
|
||||
height);
|
||||
}
|
||||
|
@ -1227,7 +1229,7 @@ void GPU_HW_D3D11::DownsampleFramebufferBoxFilter(D3D11::Texture& source, u32 le
|
|||
|
||||
RestoreGraphicsAPIState();
|
||||
|
||||
m_host_display->SetDisplayTexture(m_downsample_texture.GetD3DSRV(), HostDisplayPixelFormat::RGBA8,
|
||||
g_host_display->SetDisplayTexture(m_downsample_texture.GetD3DSRV(), HostDisplayPixelFormat::RGBA8,
|
||||
m_downsample_texture.GetWidth(), m_downsample_texture.GetHeight(), ds_left, ds_top,
|
||||
ds_width, ds_height);
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ public:
|
|||
|
||||
GPURenderer GetRendererType() const override;
|
||||
|
||||
bool Initialize(HostDisplay* host_display) override;
|
||||
bool Initialize() override;
|
||||
void Reset(bool clear_vram) override;
|
||||
bool DoState(StateWrapper& sw, HostDisplayTexture** host_texture, bool update_display) override;
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include "common/timer.h"
|
||||
#include "gpu_hw_shadergen.h"
|
||||
#include "host_display.h"
|
||||
#include "host_interface.h"
|
||||
#include "system.h"
|
||||
Log_SetChannel(GPU_HW_D3D12);
|
||||
|
||||
|
@ -19,9 +18,9 @@ GPU_HW_D3D12::GPU_HW_D3D12() = default;
|
|||
|
||||
GPU_HW_D3D12::~GPU_HW_D3D12()
|
||||
{
|
||||
if (m_host_display)
|
||||
if (g_host_display)
|
||||
{
|
||||
m_host_display->ClearDisplayTexture();
|
||||
g_host_display->ClearDisplayTexture();
|
||||
ResetGraphicsAPIState();
|
||||
}
|
||||
|
||||
|
@ -33,9 +32,9 @@ GPURenderer GPU_HW_D3D12::GetRendererType() const
|
|||
return GPURenderer::HardwareD3D12;
|
||||
}
|
||||
|
||||
bool GPU_HW_D3D12::Initialize(HostDisplay* host_display)
|
||||
bool GPU_HW_D3D12::Initialize()
|
||||
{
|
||||
if (host_display->GetRenderAPI() != HostDisplay::RenderAPI::D3D12)
|
||||
if (!Host::AcquireHostDisplay(HostDisplay::RenderAPI::D3D12))
|
||||
{
|
||||
Log_ErrorPrintf("Host render API is incompatible");
|
||||
return false;
|
||||
|
@ -43,7 +42,7 @@ bool GPU_HW_D3D12::Initialize(HostDisplay* host_display)
|
|||
|
||||
SetCapabilities();
|
||||
|
||||
if (!GPU_HW::Initialize(host_display))
|
||||
if (!GPU_HW::Initialize())
|
||||
return false;
|
||||
|
||||
if (!CreateRootSignatures())
|
||||
|
@ -144,7 +143,7 @@ void GPU_HW_D3D12::UpdateSettings()
|
|||
}
|
||||
|
||||
// Everything should be finished executing before recreating resources.
|
||||
m_host_display->ClearDisplayTexture();
|
||||
g_host_display->ClearDisplayTexture();
|
||||
g_d3d12_context->ExecuteCommandList(true);
|
||||
|
||||
if (framebuffer_changed)
|
||||
|
@ -413,10 +412,9 @@ bool GPU_HW_D3D12::CreateTextureBuffer()
|
|||
bool GPU_HW_D3D12::CompilePipelines()
|
||||
{
|
||||
D3D12::ShaderCache shader_cache;
|
||||
shader_cache.Open(g_host_interface->GetShaderCacheBasePath(), g_d3d12_context->GetFeatureLevel(),
|
||||
g_settings.gpu_use_debug_device);
|
||||
shader_cache.Open(EmuFolders::Cache, g_d3d12_context->GetFeatureLevel(), g_settings.gpu_use_debug_device);
|
||||
|
||||
GPU_HW_ShaderGen shadergen(m_host_display->GetRenderAPI(), m_resolution_scale, m_multisamples, m_per_sample_shading,
|
||||
GPU_HW_ShaderGen shadergen(g_host_display->GetRenderAPI(), m_resolution_scale, m_multisamples, m_per_sample_shading,
|
||||
m_true_color, m_scaled_dithering, m_texture_filtering, m_using_uv_limits,
|
||||
m_pgxp_depth_buffer, m_supports_dual_source_blend);
|
||||
|
||||
|
@ -852,7 +850,7 @@ void GPU_HW_D3D12::ClearDisplay()
|
|||
{
|
||||
GPU_HW::ClearDisplay();
|
||||
|
||||
m_host_display->ClearDisplayTexture();
|
||||
g_host_display->ClearDisplayTexture();
|
||||
|
||||
static constexpr float clear_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
m_display_texture.TransitionToState(D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
|
@ -869,23 +867,23 @@ void GPU_HW_D3D12::UpdateDisplay()
|
|||
if (IsUsingMultisampling())
|
||||
{
|
||||
UpdateVRAMReadTexture();
|
||||
m_host_display->SetDisplayTexture(&m_vram_read_texture, HostDisplayPixelFormat::RGBA8,
|
||||
g_host_display->SetDisplayTexture(&m_vram_read_texture, HostDisplayPixelFormat::RGBA8,
|
||||
m_vram_read_texture.GetWidth(), m_vram_read_texture.GetHeight(), 0, 0,
|
||||
m_vram_read_texture.GetWidth(), m_vram_read_texture.GetHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_vram_texture.TransitionToState(D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
||||
m_host_display->SetDisplayTexture(&m_vram_texture, HostDisplayPixelFormat::RGBA8, m_vram_texture.GetWidth(),
|
||||
g_host_display->SetDisplayTexture(&m_vram_texture, HostDisplayPixelFormat::RGBA8, m_vram_texture.GetWidth(),
|
||||
m_vram_texture.GetHeight(), 0, 0, m_vram_texture.GetWidth(),
|
||||
m_vram_texture.GetHeight());
|
||||
}
|
||||
m_host_display->SetDisplayParameters(VRAM_WIDTH, VRAM_HEIGHT, 0, 0, VRAM_WIDTH, VRAM_HEIGHT,
|
||||
g_host_display->SetDisplayParameters(VRAM_WIDTH, VRAM_HEIGHT, 0, 0, VRAM_WIDTH, VRAM_HEIGHT,
|
||||
static_cast<float>(VRAM_WIDTH) / static_cast<float>(VRAM_HEIGHT));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_host_display->SetDisplayParameters(m_crtc_state.display_width, m_crtc_state.display_height,
|
||||
g_host_display->SetDisplayParameters(m_crtc_state.display_width, m_crtc_state.display_height,
|
||||
m_crtc_state.display_origin_left, m_crtc_state.display_origin_top,
|
||||
m_crtc_state.display_vram_width, m_crtc_state.display_vram_height,
|
||||
GetDisplayAspectRatio());
|
||||
|
@ -903,14 +901,14 @@ void GPU_HW_D3D12::UpdateDisplay()
|
|||
|
||||
if (IsDisplayDisabled())
|
||||
{
|
||||
m_host_display->ClearDisplayTexture();
|
||||
g_host_display->ClearDisplayTexture();
|
||||
}
|
||||
else if (!m_GPUSTAT.display_area_color_depth_24 && interlaced == InterlacedRenderMode::None &&
|
||||
!IsUsingMultisampling() && (scaled_vram_offset_x + scaled_display_width) <= m_vram_texture.GetWidth() &&
|
||||
(scaled_vram_offset_y + scaled_display_height) <= m_vram_texture.GetHeight())
|
||||
{
|
||||
m_vram_texture.TransitionToState(D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
||||
m_host_display->SetDisplayTexture(&m_vram_texture, HostDisplayPixelFormat::RGBA8, m_vram_texture.GetWidth(),
|
||||
g_host_display->SetDisplayTexture(&m_vram_texture, HostDisplayPixelFormat::RGBA8, m_vram_texture.GetWidth(),
|
||||
m_vram_texture.GetHeight(), scaled_vram_offset_x, scaled_vram_offset_y,
|
||||
scaled_display_width, scaled_display_height);
|
||||
}
|
||||
|
@ -938,7 +936,7 @@ void GPU_HW_D3D12::UpdateDisplay()
|
|||
m_display_texture.TransitionToState(D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
||||
m_vram_texture.TransitionToState(D3D12_RESOURCE_STATE_RENDER_TARGET);
|
||||
|
||||
m_host_display->SetDisplayTexture(&m_display_texture, HostDisplayPixelFormat::RGBA8, m_display_texture.GetWidth(),
|
||||
g_host_display->SetDisplayTexture(&m_display_texture, HostDisplayPixelFormat::RGBA8, m_display_texture.GetWidth(),
|
||||
m_display_texture.GetHeight(), 0, 0, scaled_display_width,
|
||||
scaled_display_height);
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ public:
|
|||
|
||||
GPURenderer GetRendererType() const override;
|
||||
|
||||
bool Initialize(HostDisplay* host_display) override;
|
||||
bool Initialize() override;
|
||||
void Reset(bool clear_vram) override;
|
||||
|
||||
void ResetGraphicsAPIState() override;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "common/log.h"
|
||||
#include "common/timer.h"
|
||||
#include "gpu_hw_shadergen.h"
|
||||
#include "host.h"
|
||||
#include "host_display.h"
|
||||
#include "shader_cache_version.h"
|
||||
#include "system.h"
|
||||
|
@ -24,9 +25,9 @@ GPU_HW_OpenGL::~GPU_HW_OpenGL()
|
|||
if (m_texture_buffer_r16ui_texture != 0)
|
||||
glDeleteTextures(1, &m_texture_buffer_r16ui_texture);
|
||||
|
||||
if (m_host_display)
|
||||
if (g_host_display)
|
||||
{
|
||||
m_host_display->ClearDisplayTexture();
|
||||
g_host_display->ClearDisplayTexture();
|
||||
ResetGraphicsAPIState();
|
||||
}
|
||||
|
||||
|
@ -40,31 +41,30 @@ GPURenderer GPU_HW_OpenGL::GetRendererType() const
|
|||
return GPURenderer::HardwareOpenGL;
|
||||
}
|
||||
|
||||
bool GPU_HW_OpenGL::Initialize(HostDisplay* host_display)
|
||||
bool GPU_HW_OpenGL::Initialize()
|
||||
{
|
||||
if (host_display->GetRenderAPI() != HostDisplay::RenderAPI::OpenGL &&
|
||||
host_display->GetRenderAPI() != HostDisplay::RenderAPI::OpenGLES)
|
||||
if (!Host::AcquireHostDisplay(HostDisplay::RenderAPI::OpenGL))
|
||||
{
|
||||
Log_ErrorPrintf("Host render API type is incompatible");
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool opengl_is_available =
|
||||
((host_display->GetRenderAPI() == HostDisplay::RenderAPI::OpenGL &&
|
||||
((g_host_display->GetRenderAPI() == HostDisplay::RenderAPI::OpenGL &&
|
||||
(GLAD_GL_VERSION_3_0 || GLAD_GL_ARB_uniform_buffer_object)) ||
|
||||
(host_display->GetRenderAPI() == HostDisplay::RenderAPI::OpenGLES && GLAD_GL_ES_VERSION_3_0));
|
||||
(g_host_display->GetRenderAPI() == HostDisplay::RenderAPI::OpenGLES && GLAD_GL_ES_VERSION_3_0));
|
||||
if (!opengl_is_available)
|
||||
{
|
||||
g_host_interface->AddOSDMessage(
|
||||
g_host_interface->TranslateStdString("OSDMessage", "OpenGL renderer unavailable, your driver or hardware is not "
|
||||
"recent enough. OpenGL 3.1 or OpenGL ES 3.0 is required."),
|
||||
20.0f);
|
||||
Host::AddOSDMessage(Host::TranslateStdString("OSDMessage",
|
||||
"OpenGL renderer unavailable, your driver or hardware is not "
|
||||
"recent enough. OpenGL 3.1 or OpenGL ES 3.0 is required."),
|
||||
20.0f);
|
||||
return false;
|
||||
}
|
||||
|
||||
SetCapabilities(host_display);
|
||||
SetCapabilities();
|
||||
|
||||
if (!GPU_HW::Initialize(host_display))
|
||||
if (!GPU_HW::Initialize())
|
||||
return false;
|
||||
|
||||
if (!CreateFramebuffer())
|
||||
|
@ -133,7 +133,7 @@ bool GPU_HW_OpenGL::DoState(StateWrapper& sw, HostDisplayTexture** host_texture,
|
|||
{
|
||||
delete tex;
|
||||
|
||||
tex = m_host_display
|
||||
tex = g_host_display
|
||||
->CreateTexture(m_vram_texture.GetWidth(), m_vram_texture.GetHeight(), 1, 1,
|
||||
m_vram_texture.GetSamples(), HostDisplayPixelFormat::RGBA8, nullptr, 0, false)
|
||||
.release();
|
||||
|
@ -252,7 +252,7 @@ void GPU_HW_OpenGL::UpdateSettings()
|
|||
RestoreGraphicsAPIState();
|
||||
ReadVRAM(0, 0, VRAM_WIDTH, VRAM_HEIGHT);
|
||||
ResetGraphicsAPIState();
|
||||
m_host_display->ClearDisplayTexture();
|
||||
g_host_display->ClearDisplayTexture();
|
||||
CreateFramebuffer();
|
||||
}
|
||||
if (shaders_changed)
|
||||
|
@ -297,7 +297,7 @@ std::tuple<s32, s32> GPU_HW_OpenGL::ConvertToFramebufferCoordinates(s32 x, s32 y
|
|||
return std::make_tuple(x, static_cast<s32>(static_cast<s32>(VRAM_HEIGHT) - y));
|
||||
}
|
||||
|
||||
void GPU_HW_OpenGL::SetCapabilities(HostDisplay* host_display)
|
||||
void GPU_HW_OpenGL::SetCapabilities()
|
||||
{
|
||||
GLint max_texture_size = VRAM_WIDTH;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
|
||||
|
@ -510,10 +510,10 @@ bool GPU_HW_OpenGL::CreateTextureBuffer()
|
|||
bool GPU_HW_OpenGL::CompilePrograms()
|
||||
{
|
||||
GL::ShaderCache shader_cache;
|
||||
shader_cache.Open(IsGLES(), g_host_interface->GetShaderCacheBasePath(), SHADER_CACHE_VERSION);
|
||||
shader_cache.Open(IsGLES(), EmuFolders::Cache, SHADER_CACHE_VERSION);
|
||||
|
||||
const bool use_binding_layout = GPU_HW_ShaderGen::UseGLSLBindingLayout();
|
||||
GPU_HW_ShaderGen shadergen(m_host_display->GetRenderAPI(), m_resolution_scale, m_multisamples, m_per_sample_shading,
|
||||
GPU_HW_ShaderGen shadergen(g_host_display->GetRenderAPI(), m_resolution_scale, m_multisamples, m_per_sample_shading,
|
||||
m_true_color, m_scaled_dithering, m_texture_filtering, m_using_uv_limits,
|
||||
m_pgxp_depth_buffer, m_supports_dual_source_blend);
|
||||
|
||||
|
@ -844,7 +844,7 @@ void GPU_HW_OpenGL::ClearDisplay()
|
|||
{
|
||||
GPU_HW::ClearDisplay();
|
||||
|
||||
m_host_display->ClearDisplayTexture();
|
||||
g_host_display->ClearDisplayTexture();
|
||||
|
||||
m_display_texture.BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
@ -864,7 +864,7 @@ void GPU_HW_OpenGL::UpdateDisplay()
|
|||
{
|
||||
UpdateVRAMReadTexture();
|
||||
|
||||
m_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_vram_read_texture.GetGLId())),
|
||||
g_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_vram_read_texture.GetGLId())),
|
||||
HostDisplayPixelFormat::RGBA8, m_vram_read_texture.GetWidth(),
|
||||
static_cast<s32>(m_vram_read_texture.GetHeight()), 0,
|
||||
m_vram_read_texture.GetHeight(), m_vram_read_texture.GetWidth(),
|
||||
|
@ -872,17 +872,17 @@ void GPU_HW_OpenGL::UpdateDisplay()
|
|||
}
|
||||
else
|
||||
{
|
||||
m_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_vram_texture.GetGLId())),
|
||||
g_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_vram_texture.GetGLId())),
|
||||
HostDisplayPixelFormat::RGBA8, m_vram_texture.GetWidth(),
|
||||
static_cast<s32>(m_vram_texture.GetHeight()), 0, m_vram_texture.GetHeight(),
|
||||
m_vram_texture.GetWidth(), -static_cast<s32>(m_vram_texture.GetHeight()));
|
||||
}
|
||||
m_host_display->SetDisplayParameters(VRAM_WIDTH, VRAM_HEIGHT, 0, 0, VRAM_WIDTH, VRAM_HEIGHT,
|
||||
g_host_display->SetDisplayParameters(VRAM_WIDTH, VRAM_HEIGHT, 0, 0, VRAM_WIDTH, VRAM_HEIGHT,
|
||||
static_cast<float>(VRAM_WIDTH) / static_cast<float>(VRAM_HEIGHT));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_host_display->SetDisplayParameters(m_crtc_state.display_width, m_crtc_state.display_height,
|
||||
g_host_display->SetDisplayParameters(m_crtc_state.display_width, m_crtc_state.display_height,
|
||||
m_crtc_state.display_origin_left, m_crtc_state.display_origin_top,
|
||||
m_crtc_state.display_vram_width, m_crtc_state.display_vram_height,
|
||||
GetDisplayAspectRatio());
|
||||
|
@ -900,7 +900,7 @@ void GPU_HW_OpenGL::UpdateDisplay()
|
|||
|
||||
if (IsDisplayDisabled())
|
||||
{
|
||||
m_host_display->ClearDisplayTexture();
|
||||
g_host_display->ClearDisplayTexture();
|
||||
}
|
||||
else if (!m_GPUSTAT.display_area_color_depth_24 && interlaced == GPU_HW::InterlacedRenderMode::None &&
|
||||
!IsUsingMultisampling() && (scaled_vram_offset_x + scaled_display_width) <= m_vram_texture.GetWidth() &&
|
||||
|
@ -913,7 +913,7 @@ void GPU_HW_OpenGL::UpdateDisplay()
|
|||
}
|
||||
else
|
||||
{
|
||||
m_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_vram_texture.GetGLId())),
|
||||
g_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_vram_texture.GetGLId())),
|
||||
HostDisplayPixelFormat::RGBA8, m_vram_texture.GetWidth(),
|
||||
m_vram_texture.GetHeight(), scaled_vram_offset_x,
|
||||
m_vram_texture.GetHeight() - scaled_vram_offset_y, scaled_display_width,
|
||||
|
@ -960,7 +960,7 @@ void GPU_HW_OpenGL::UpdateDisplay()
|
|||
}
|
||||
else
|
||||
{
|
||||
m_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_display_texture.GetGLId())),
|
||||
g_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_display_texture.GetGLId())),
|
||||
HostDisplayPixelFormat::RGBA8, m_display_texture.GetWidth(),
|
||||
m_display_texture.GetHeight(), 0, scaled_display_height, scaled_display_width,
|
||||
-static_cast<s32>(scaled_display_height));
|
||||
|
@ -1353,7 +1353,7 @@ void GPU_HW_OpenGL::DownsampleFramebufferBoxFilter(GL::Texture& source, u32 left
|
|||
|
||||
RestoreGraphicsAPIState();
|
||||
|
||||
m_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_downsample_texture.GetGLId())),
|
||||
g_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_downsample_texture.GetGLId())),
|
||||
HostDisplayPixelFormat::RGBA8, m_downsample_texture.GetWidth(),
|
||||
m_downsample_texture.GetHeight(), ds_left,
|
||||
m_downsample_texture.GetHeight() - ds_top, ds_width, -static_cast<s32>(ds_height));
|
||||
|
|
|
@ -18,7 +18,7 @@ public:
|
|||
|
||||
GPURenderer GetRendererType() const override;
|
||||
|
||||
bool Initialize(HostDisplay* host_display) override;
|
||||
bool Initialize() override;
|
||||
void Reset(bool clear_vram) override;
|
||||
bool DoState(StateWrapper& sw, HostDisplayTexture** host_texture, bool update_display) override;
|
||||
|
||||
|
@ -57,7 +57,7 @@ private:
|
|||
|
||||
std::tuple<s32, s32> ConvertToFramebufferCoordinates(s32 x, s32 y);
|
||||
|
||||
void SetCapabilities(HostDisplay* host_display);
|
||||
void SetCapabilities();
|
||||
bool CreateFramebuffer();
|
||||
void ClearFramebuffer();
|
||||
void CopyFramebufferForState(GLenum target, GLuint src_texture, u32 src_fbo, u32 src_x, u32 src_y, GLuint dst_texture,
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "common/vulkan/util.h"
|
||||
#include "gpu_hw_shadergen.h"
|
||||
#include "host_display.h"
|
||||
#include "host_interface.h"
|
||||
#include "system.h"
|
||||
#include "util/state_wrapper.h"
|
||||
Log_SetChannel(GPU_HW_Vulkan);
|
||||
|
@ -18,9 +17,9 @@ GPU_HW_Vulkan::GPU_HW_Vulkan() = default;
|
|||
|
||||
GPU_HW_Vulkan::~GPU_HW_Vulkan()
|
||||
{
|
||||
if (m_host_display)
|
||||
if (g_host_display)
|
||||
{
|
||||
m_host_display->ClearDisplayTexture();
|
||||
g_host_display->ClearDisplayTexture();
|
||||
ResetGraphicsAPIState();
|
||||
}
|
||||
|
||||
|
@ -32,9 +31,9 @@ GPURenderer GPU_HW_Vulkan::GetRendererType() const
|
|||
return GPURenderer::HardwareVulkan;
|
||||
}
|
||||
|
||||
bool GPU_HW_Vulkan::Initialize(HostDisplay* host_display)
|
||||
bool GPU_HW_Vulkan::Initialize()
|
||||
{
|
||||
if (host_display->GetRenderAPI() != HostDisplay::RenderAPI::Vulkan)
|
||||
if (!Host::AcquireHostDisplay(HostDisplay::RenderAPI::Vulkan))
|
||||
{
|
||||
Log_ErrorPrintf("Host render API is incompatible");
|
||||
return false;
|
||||
|
@ -43,7 +42,7 @@ bool GPU_HW_Vulkan::Initialize(HostDisplay* host_display)
|
|||
Assert(g_vulkan_shader_cache);
|
||||
SetCapabilities();
|
||||
|
||||
if (!GPU_HW::Initialize(host_display))
|
||||
if (!GPU_HW::Initialize())
|
||||
return false;
|
||||
|
||||
if (!CreatePipelineLayouts())
|
||||
|
@ -144,7 +143,7 @@ bool GPU_HW_Vulkan::DoState(StateWrapper& sw, HostDisplayTexture** host_texture,
|
|||
{
|
||||
delete htex;
|
||||
|
||||
htex = m_host_display
|
||||
htex = g_host_display
|
||||
->CreateTexture(m_vram_texture.GetWidth(), m_vram_texture.GetHeight(), 1, 1,
|
||||
m_vram_texture.GetSamples(), HostDisplayPixelFormat::RGBA8, nullptr, 0, false)
|
||||
.release();
|
||||
|
@ -179,7 +178,7 @@ void GPU_HW_Vulkan::ResetGraphicsAPIState()
|
|||
|
||||
EndRenderPass();
|
||||
|
||||
if (m_host_display->GetDisplayTextureHandle() == &m_vram_texture)
|
||||
if (g_host_display->GetDisplayTextureHandle() == &m_vram_texture)
|
||||
{
|
||||
m_vram_texture.TransitionToLayout(g_vulkan_context->GetCurrentCommandBuffer(),
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
|
@ -218,7 +217,7 @@ void GPU_HW_Vulkan::UpdateSettings()
|
|||
}
|
||||
|
||||
// Everything should be finished executing before recreating resources.
|
||||
m_host_display->ClearDisplayTexture();
|
||||
g_host_display->ClearDisplayTexture();
|
||||
g_vulkan_context->ExecuteCommandBuffer(true);
|
||||
|
||||
if (framebuffer_changed)
|
||||
|
@ -923,7 +922,7 @@ bool GPU_HW_Vulkan::CompilePipelines()
|
|||
VkDevice device = g_vulkan_context->GetDevice();
|
||||
VkPipelineCache pipeline_cache = g_vulkan_shader_cache->GetPipelineCache();
|
||||
|
||||
GPU_HW_ShaderGen shadergen(m_host_display->GetRenderAPI(), m_resolution_scale, m_multisamples, m_per_sample_shading,
|
||||
GPU_HW_ShaderGen shadergen(g_host_display->GetRenderAPI(), m_resolution_scale, m_multisamples, m_per_sample_shading,
|
||||
m_true_color, m_scaled_dithering, m_texture_filtering, m_using_uv_limits,
|
||||
m_pgxp_depth_buffer, m_supports_dual_source_blend);
|
||||
|
||||
|
@ -1405,7 +1404,7 @@ void GPU_HW_Vulkan::ClearDisplay()
|
|||
GPU_HW::ClearDisplay();
|
||||
EndRenderPass();
|
||||
|
||||
m_host_display->ClearDisplayTexture();
|
||||
g_host_display->ClearDisplayTexture();
|
||||
|
||||
VkCommandBuffer cmdbuf = g_vulkan_context->GetCurrentCommandBuffer();
|
||||
const Vulkan::Util::DebugScope debugScope(cmdbuf, "GPU_HW_Vulkan::ClearDisplay");
|
||||
|
@ -1435,22 +1434,22 @@ void GPU_HW_Vulkan::UpdateDisplay()
|
|||
UpdateVRAMReadTexture();
|
||||
}
|
||||
|
||||
m_host_display->SetDisplayTexture(&m_vram_read_texture, HostDisplayPixelFormat::RGBA8,
|
||||
g_host_display->SetDisplayTexture(&m_vram_read_texture, HostDisplayPixelFormat::RGBA8,
|
||||
m_vram_read_texture.GetWidth(), m_vram_read_texture.GetHeight(), 0, 0,
|
||||
m_vram_read_texture.GetWidth(), m_vram_read_texture.GetHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_host_display->SetDisplayTexture(&m_vram_texture, HostDisplayPixelFormat::RGBA8, m_vram_texture.GetWidth(),
|
||||
g_host_display->SetDisplayTexture(&m_vram_texture, HostDisplayPixelFormat::RGBA8, m_vram_texture.GetWidth(),
|
||||
m_vram_texture.GetHeight(), 0, 0, m_vram_texture.GetWidth(),
|
||||
m_vram_texture.GetHeight());
|
||||
}
|
||||
m_host_display->SetDisplayParameters(VRAM_WIDTH, VRAM_HEIGHT, 0, 0, VRAM_WIDTH, VRAM_HEIGHT,
|
||||
g_host_display->SetDisplayParameters(VRAM_WIDTH, VRAM_HEIGHT, 0, 0, VRAM_WIDTH, VRAM_HEIGHT,
|
||||
static_cast<float>(VRAM_WIDTH) / static_cast<float>(VRAM_HEIGHT));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_host_display->SetDisplayParameters(m_crtc_state.display_width, m_crtc_state.display_height,
|
||||
g_host_display->SetDisplayParameters(m_crtc_state.display_width, m_crtc_state.display_height,
|
||||
m_crtc_state.display_origin_left, m_crtc_state.display_origin_top,
|
||||
m_crtc_state.display_vram_width, m_crtc_state.display_vram_height,
|
||||
GetDisplayAspectRatio());
|
||||
|
@ -1468,7 +1467,7 @@ void GPU_HW_Vulkan::UpdateDisplay()
|
|||
|
||||
if (IsDisplayDisabled())
|
||||
{
|
||||
m_host_display->ClearDisplayTexture();
|
||||
g_host_display->ClearDisplayTexture();
|
||||
}
|
||||
else if (!m_GPUSTAT.display_area_color_depth_24 && interlaced == InterlacedRenderMode::None &&
|
||||
!IsUsingMultisampling() && (scaled_vram_offset_x + scaled_display_width) <= m_vram_texture.GetWidth() &&
|
||||
|
@ -1481,7 +1480,7 @@ void GPU_HW_Vulkan::UpdateDisplay()
|
|||
}
|
||||
else
|
||||
{
|
||||
m_host_display->SetDisplayTexture(&m_vram_texture, HostDisplayPixelFormat::RGBA8, m_vram_texture.GetWidth(),
|
||||
g_host_display->SetDisplayTexture(&m_vram_texture, HostDisplayPixelFormat::RGBA8, m_vram_texture.GetWidth(),
|
||||
m_vram_texture.GetHeight(), scaled_vram_offset_x, scaled_vram_offset_y,
|
||||
scaled_display_width, scaled_display_height);
|
||||
}
|
||||
|
@ -1528,7 +1527,7 @@ void GPU_HW_Vulkan::UpdateDisplay()
|
|||
}
|
||||
else
|
||||
{
|
||||
m_host_display->SetDisplayTexture(&m_display_texture, HostDisplayPixelFormat::RGBA8,
|
||||
g_host_display->SetDisplayTexture(&m_display_texture, HostDisplayPixelFormat::RGBA8,
|
||||
m_display_texture.GetWidth(), m_display_texture.GetHeight(), 0, 0,
|
||||
scaled_display_width, scaled_display_height);
|
||||
RestoreGraphicsAPIState();
|
||||
|
@ -1938,7 +1937,7 @@ void GPU_HW_Vulkan::DownsampleFramebufferBoxFilter(Vulkan::Texture& source, u32
|
|||
|
||||
RestoreGraphicsAPIState();
|
||||
|
||||
m_host_display->SetDisplayTexture(&m_downsample_texture, HostDisplayPixelFormat::RGBA8,
|
||||
g_host_display->SetDisplayTexture(&m_downsample_texture, HostDisplayPixelFormat::RGBA8,
|
||||
m_downsample_texture.GetWidth(), m_downsample_texture.GetHeight(), ds_left, ds_top,
|
||||
ds_width, ds_height);
|
||||
}
|
||||
|
@ -2037,7 +2036,7 @@ void GPU_HW_Vulkan::DownsampleFramebufferAdaptive(Vulkan::Texture& source, u32 l
|
|||
}
|
||||
RestoreGraphicsAPIState();
|
||||
|
||||
m_host_display->SetDisplayTexture(&m_display_texture, HostDisplayPixelFormat::RGBA8, m_display_texture.GetWidth(),
|
||||
g_host_display->SetDisplayTexture(&m_display_texture, HostDisplayPixelFormat::RGBA8, m_display_texture.GetWidth(),
|
||||
m_display_texture.GetHeight(), left, top, width, height);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ public:
|
|||
|
||||
GPURenderer GetRendererType() const override;
|
||||
|
||||
bool Initialize(HostDisplay* host_display) override;
|
||||
bool Initialize() override;
|
||||
void Reset(bool clear_vram) override;
|
||||
bool DoState(StateWrapper& sw, HostDisplayTexture** host_texture, bool update_display) override;
|
||||
|
||||
|
|
|
@ -36,8 +36,8 @@ GPU_SW::GPU_SW()
|
|||
GPU_SW::~GPU_SW()
|
||||
{
|
||||
m_backend.Shutdown();
|
||||
if (m_host_display)
|
||||
m_host_display->ClearDisplayTexture();
|
||||
if (g_host_display)
|
||||
g_host_display->ClearDisplayTexture();
|
||||
}
|
||||
|
||||
GPURenderer GPU_SW::GetRendererType() const
|
||||
|
@ -45,9 +45,13 @@ GPURenderer GPU_SW::GetRendererType() const
|
|||
return GPURenderer::Software;
|
||||
}
|
||||
|
||||
bool GPU_SW::Initialize(HostDisplay* host_display)
|
||||
bool GPU_SW::Initialize()
|
||||
{
|
||||
if (!GPU::Initialize(host_display) || !m_backend.Initialize(false))
|
||||
// we need something to draw in.. but keep the current api if we have one
|
||||
if (!g_host_display && !Host::AcquireHostDisplay(HostDisplay::GetPreferredAPI()))
|
||||
return false;
|
||||
|
||||
if (!GPU::Initialize() || !m_backend.Initialize(false))
|
||||
return false;
|
||||
|
||||
static constexpr auto formats_for_16bit = make_array(HostDisplayPixelFormat::RGB565, HostDisplayPixelFormat::RGBA5551,
|
||||
|
@ -57,7 +61,7 @@ bool GPU_SW::Initialize(HostDisplay* host_display)
|
|||
HostDisplayPixelFormat::RGBA5551);
|
||||
for (const HostDisplayPixelFormat format : formats_for_16bit)
|
||||
{
|
||||
if (m_host_display->SupportsDisplayPixelFormat(format))
|
||||
if (g_host_display->SupportsDisplayPixelFormat(format))
|
||||
{
|
||||
m_16bit_display_format = format;
|
||||
break;
|
||||
|
@ -65,7 +69,7 @@ bool GPU_SW::Initialize(HostDisplay* host_display)
|
|||
}
|
||||
for (const HostDisplayPixelFormat format : formats_for_24bit)
|
||||
{
|
||||
if (m_host_display->SupportsDisplayPixelFormat(format))
|
||||
if (g_host_display->SupportsDisplayPixelFormat(format))
|
||||
{
|
||||
m_24bit_display_format = format;
|
||||
break;
|
||||
|
@ -233,7 +237,7 @@ void GPU_SW::CopyOut15Bit(u32 src_x, u32 src_y, u32 width, u32 height, u32 field
|
|||
|
||||
if (!interlaced)
|
||||
{
|
||||
if (!m_host_display->BeginSetDisplayPixels(display_format, width, height, reinterpret_cast<void**>(&dst_ptr),
|
||||
if (!g_host_display->BeginSetDisplayPixels(display_format, width, height, reinterpret_cast<void**>(&dst_ptr),
|
||||
&dst_stride))
|
||||
{
|
||||
return;
|
||||
|
@ -285,11 +289,11 @@ void GPU_SW::CopyOut15Bit(u32 src_x, u32 src_y, u32 width, u32 height, u32 field
|
|||
|
||||
if (!interlaced)
|
||||
{
|
||||
m_host_display->EndSetDisplayPixels();
|
||||
g_host_display->EndSetDisplayPixels();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_host_display->SetDisplayPixels(display_format, width, height, m_display_texture_buffer.data(), output_stride);
|
||||
g_host_display->SetDisplayPixels(display_format, width, height, m_display_texture_buffer.data(), output_stride);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -327,7 +331,7 @@ void GPU_SW::CopyOut24Bit(u32 src_x, u32 src_y, u32 skip_x, u32 width, u32 heigh
|
|||
|
||||
if (!interlaced)
|
||||
{
|
||||
if (!m_host_display->BeginSetDisplayPixels(display_format, width, height, reinterpret_cast<void**>(&dst_ptr),
|
||||
if (!g_host_display->BeginSetDisplayPixels(display_format, width, height, reinterpret_cast<void**>(&dst_ptr),
|
||||
&dst_stride))
|
||||
{
|
||||
return;
|
||||
|
@ -443,11 +447,11 @@ void GPU_SW::CopyOut24Bit(u32 src_x, u32 src_y, u32 skip_x, u32 width, u32 heigh
|
|||
|
||||
if (!interlaced)
|
||||
{
|
||||
m_host_display->EndSetDisplayPixels();
|
||||
g_host_display->EndSetDisplayPixels();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_host_display->SetDisplayPixels(display_format, width, height, m_display_texture_buffer.data(), output_stride);
|
||||
g_host_display->SetDisplayPixels(display_format, width, height, m_display_texture_buffer.data(), output_stride);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -486,14 +490,14 @@ void GPU_SW::UpdateDisplay()
|
|||
|
||||
if (!g_settings.debugging.show_vram)
|
||||
{
|
||||
m_host_display->SetDisplayParameters(m_crtc_state.display_width, m_crtc_state.display_height,
|
||||
g_host_display->SetDisplayParameters(m_crtc_state.display_width, m_crtc_state.display_height,
|
||||
m_crtc_state.display_origin_left, m_crtc_state.display_origin_top,
|
||||
m_crtc_state.display_vram_width, m_crtc_state.display_vram_height,
|
||||
GetDisplayAspectRatio());
|
||||
|
||||
if (IsDisplayDisabled())
|
||||
{
|
||||
m_host_display->ClearDisplayTexture();
|
||||
g_host_display->ClearDisplayTexture();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -534,7 +538,7 @@ void GPU_SW::UpdateDisplay()
|
|||
else
|
||||
{
|
||||
CopyOut15Bit(m_16bit_display_format, 0, 0, VRAM_WIDTH, VRAM_HEIGHT, 0, false, false);
|
||||
m_host_display->SetDisplayParameters(VRAM_WIDTH, VRAM_HEIGHT, 0, 0, VRAM_WIDTH, VRAM_HEIGHT,
|
||||
g_host_display->SetDisplayParameters(VRAM_WIDTH, VRAM_HEIGHT, 0, 0, VRAM_WIDTH, VRAM_HEIGHT,
|
||||
static_cast<float>(VRAM_WIDTH) / static_cast<float>(VRAM_HEIGHT));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,11 @@
|
|||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace Threading
|
||||
{
|
||||
class Thread;
|
||||
}
|
||||
|
||||
class HostDisplayTexture;
|
||||
|
||||
class GPU_SW final : public GPU
|
||||
|
@ -15,9 +20,11 @@ public:
|
|||
GPU_SW();
|
||||
~GPU_SW() override;
|
||||
|
||||
ALWAYS_INLINE const GPU_SW_Backend& GetBackend() const { return m_backend; }
|
||||
|
||||
GPURenderer GetRendererType() const override;
|
||||
|
||||
bool Initialize(HostDisplay* host_display) override;
|
||||
bool Initialize() override;
|
||||
bool DoState(StateWrapper& sw, HostDisplayTexture** host_texture, bool update_display) override;
|
||||
void Reset(bool clear_vram) override;
|
||||
void UpdateSettings() override;
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include "cpu_core.h"
|
||||
#include "cpu_core_private.h"
|
||||
#include "host_display.h"
|
||||
#include "host_interface.h"
|
||||
#include "pgxp.h"
|
||||
#include "settings.h"
|
||||
#include "timing_event.h"
|
||||
|
@ -188,15 +187,14 @@ void UpdateAspectRatio()
|
|||
{
|
||||
case DisplayAspectRatio::MatchWindow:
|
||||
{
|
||||
const HostDisplay* display = g_host_interface->GetDisplay();
|
||||
if (!display)
|
||||
if (!g_host_display)
|
||||
{
|
||||
s_aspect_ratio = DisplayAspectRatio::R4_3;
|
||||
return;
|
||||
}
|
||||
|
||||
num = display->GetWindowWidth();
|
||||
denom = display->GetWindowHeight();
|
||||
num = g_host_display->GetWindowWidth();
|
||||
denom = g_host_display->GetWindowHeight();
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -0,0 +1,273 @@
|
|||
#include "guncon.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/log.h"
|
||||
#include "gpu.h"
|
||||
#include "host.h"
|
||||
#include "host_display.h"
|
||||
#include "resources.h"
|
||||
#include "system.h"
|
||||
#include "util/state_wrapper.h"
|
||||
#include <array>
|
||||
Log_SetChannel(GunCon);
|
||||
|
||||
static constexpr std::array<u8, static_cast<size_t>(GunCon::Button::Count)> s_button_indices = {{13, 3, 14}};
|
||||
|
||||
GunCon::GunCon(u32 index) : Controller(index) {}
|
||||
|
||||
GunCon::~GunCon() = default;
|
||||
|
||||
ControllerType GunCon::GetType() const
|
||||
{
|
||||
return ControllerType::GunCon;
|
||||
}
|
||||
|
||||
void GunCon::Reset()
|
||||
{
|
||||
m_transfer_state = TransferState::Idle;
|
||||
}
|
||||
|
||||
bool GunCon::DoState(StateWrapper& sw, bool apply_input_state)
|
||||
{
|
||||
if (!Controller::DoState(sw, apply_input_state))
|
||||
return false;
|
||||
|
||||
u16 button_state = m_button_state;
|
||||
u16 position_x = m_position_x;
|
||||
u16 position_y = m_position_y;
|
||||
sw.Do(&button_state);
|
||||
sw.Do(&position_x);
|
||||
sw.Do(&position_y);
|
||||
if (apply_input_state)
|
||||
{
|
||||
m_button_state = button_state;
|
||||
m_position_x = position_x;
|
||||
m_position_y = position_y;
|
||||
}
|
||||
|
||||
sw.Do(&m_transfer_state);
|
||||
return true;
|
||||
}
|
||||
|
||||
float GunCon::GetBindState(u32 index) const
|
||||
{
|
||||
if (index >= s_button_indices.size())
|
||||
return 0.0f;
|
||||
|
||||
const u32 bit = s_button_indices[index];
|
||||
return static_cast<float>(((m_button_state >> bit) & 1u) ^ 1u);
|
||||
}
|
||||
|
||||
void GunCon::SetBindState(u32 index, float value)
|
||||
{
|
||||
const bool pressed = (value >= 0.5f);
|
||||
if (index == static_cast<u32>(Button::ShootOffscreen))
|
||||
{
|
||||
if (m_shoot_offscreen != pressed)
|
||||
{
|
||||
m_shoot_offscreen = pressed;
|
||||
SetBindState(static_cast<u32>(Button::Trigger), pressed);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (pressed)
|
||||
m_button_state &= ~(u16(1) << s_button_indices[static_cast<u8>(index)]);
|
||||
else
|
||||
m_button_state |= u16(1) << s_button_indices[static_cast<u8>(index)];
|
||||
}
|
||||
|
||||
void GunCon::ResetTransferState()
|
||||
{
|
||||
m_transfer_state = TransferState::Idle;
|
||||
}
|
||||
|
||||
bool GunCon::Transfer(const u8 data_in, u8* data_out)
|
||||
{
|
||||
static constexpr u16 ID = 0x5A63;
|
||||
|
||||
switch (m_transfer_state)
|
||||
{
|
||||
case TransferState::Idle:
|
||||
{
|
||||
*data_out = 0xFF;
|
||||
|
||||
if (data_in == 0x01)
|
||||
{
|
||||
m_transfer_state = TransferState::Ready;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
case TransferState::Ready:
|
||||
{
|
||||
if (data_in == 0x42)
|
||||
{
|
||||
*data_out = Truncate8(ID);
|
||||
m_transfer_state = TransferState::IDMSB;
|
||||
return true;
|
||||
}
|
||||
|
||||
*data_out = 0xFF;
|
||||
return false;
|
||||
}
|
||||
|
||||
case TransferState::IDMSB:
|
||||
{
|
||||
*data_out = Truncate8(ID >> 8);
|
||||
m_transfer_state = TransferState::ButtonsLSB;
|
||||
return true;
|
||||
}
|
||||
|
||||
case TransferState::ButtonsLSB:
|
||||
{
|
||||
*data_out = Truncate8(m_button_state);
|
||||
m_transfer_state = TransferState::ButtonsMSB;
|
||||
return true;
|
||||
}
|
||||
|
||||
case TransferState::ButtonsMSB:
|
||||
{
|
||||
*data_out = Truncate8(m_button_state >> 8);
|
||||
m_transfer_state = TransferState::XLSB;
|
||||
return true;
|
||||
}
|
||||
|
||||
case TransferState::XLSB:
|
||||
{
|
||||
UpdatePosition();
|
||||
*data_out = Truncate8(m_position_x);
|
||||
m_transfer_state = TransferState::XMSB;
|
||||
return true;
|
||||
}
|
||||
|
||||
case TransferState::XMSB:
|
||||
{
|
||||
*data_out = Truncate8(m_position_x >> 8);
|
||||
m_transfer_state = TransferState::YLSB;
|
||||
return true;
|
||||
}
|
||||
|
||||
case TransferState::YLSB:
|
||||
{
|
||||
*data_out = Truncate8(m_position_y);
|
||||
m_transfer_state = TransferState::YMSB;
|
||||
return true;
|
||||
}
|
||||
|
||||
case TransferState::YMSB:
|
||||
{
|
||||
*data_out = Truncate8(m_position_y >> 8);
|
||||
m_transfer_state = TransferState::Idle;
|
||||
return false;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
UnreachableCode();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GunCon::UpdatePosition()
|
||||
{
|
||||
// get screen coordinates
|
||||
const s32 mouse_x = g_host_display->GetMousePositionX();
|
||||
const s32 mouse_y = g_host_display->GetMousePositionY();
|
||||
|
||||
// are we within the active display area?
|
||||
u32 tick, line;
|
||||
if (mouse_x < 0 || mouse_y < 0 ||
|
||||
!g_gpu->ConvertScreenCoordinatesToBeamTicksAndLines(mouse_x, mouse_y, m_x_scale, &tick, &line) ||
|
||||
m_shoot_offscreen)
|
||||
{
|
||||
Log_DebugPrintf("Lightgun out of range for window coordinates %d,%d", mouse_x, mouse_y);
|
||||
m_position_x = 0x01;
|
||||
m_position_y = 0x0A;
|
||||
return;
|
||||
}
|
||||
|
||||
// 8MHz units for X = 44100*768*11/7 = 53222400 / 8000000 = 6.6528
|
||||
const double divider = static_cast<double>(g_gpu->GetCRTCFrequency()) / 8000000.0;
|
||||
m_position_x = static_cast<u16>(static_cast<float>(tick) / static_cast<float>(divider));
|
||||
m_position_y = static_cast<u16>(line);
|
||||
Log_DebugPrintf("Lightgun window coordinates %d,%d -> tick %u line %u 8mhz ticks %u", mouse_x, mouse_y, tick, line,
|
||||
m_position_x);
|
||||
}
|
||||
|
||||
std::unique_ptr<GunCon> GunCon::Create(u32 index)
|
||||
{
|
||||
return std::make_unique<GunCon>(index);
|
||||
}
|
||||
|
||||
static const Controller::ControllerBindingInfo s_binding_info[] = {
|
||||
#define BUTTON(name, display_name, button, genb) \
|
||||
{ \
|
||||
name, display_name, static_cast<u32>(button), Controller::ControllerBindingType::Button, genb \
|
||||
}
|
||||
|
||||
BUTTON("Trigger", "Trigger", GunCon::Button::Trigger, GenericInputBinding::R2),
|
||||
BUTTON("ShootOffscreen", "ShootOffscreen", GunCon::Button::ShootOffscreen, GenericInputBinding::L2),
|
||||
BUTTON("A", "A", GunCon::Button::A, GenericInputBinding::Cross),
|
||||
BUTTON("B", "B", GunCon::Button::B, GenericInputBinding::Circle),
|
||||
|
||||
#undef BUTTON
|
||||
};
|
||||
|
||||
static const SettingInfo s_settings[] = {
|
||||
{SettingInfo::Type::Path, "CrosshairImagePath", TRANSLATABLE("NamcoGunCon", "Crosshair Image Path"),
|
||||
TRANSLATABLE("NamcoGunCon", "Path to an image to use as a crosshair/cursor.")},
|
||||
{SettingInfo::Type::Float, "CrosshairScale", TRANSLATABLE("NamcoGunCon", "Crosshair Image Scale"),
|
||||
TRANSLATABLE("NamcoGunCon", "Scale of crosshair image on screen."), "1.0", "0.0001", "100.0", "0.10"},
|
||||
{SettingInfo::Type::Float, "XScale", TRANSLATABLE("NamcoGunCon", "X Scale"),
|
||||
TRANSLATABLE("NamcoGunCon", "Scales X coordinates relative to the center of the screen."), "1.0", "0.01", "2.0",
|
||||
"0.01"}};
|
||||
|
||||
const Controller::ControllerInfo GunCon::INFO = {ControllerType::GunCon,
|
||||
"GunCon",
|
||||
TRANSLATABLE("ControllerType", "GunCon"),
|
||||
s_binding_info,
|
||||
countof(s_binding_info),
|
||||
s_settings,
|
||||
countof(s_settings),
|
||||
Controller::VibrationCapabilities::NoVibration};
|
||||
|
||||
void GunCon::LoadSettings(SettingsInterface& si, const char* section)
|
||||
{
|
||||
Controller::LoadSettings(si, section);
|
||||
|
||||
std::string path = si.GetStringValue(section, "CrosshairImagePath");
|
||||
if (path != m_crosshair_image_path)
|
||||
{
|
||||
m_crosshair_image_path = std::move(path);
|
||||
if (m_crosshair_image_path.empty() || !m_crosshair_image.LoadFromFile(m_crosshair_image_path.c_str()))
|
||||
{
|
||||
m_crosshair_image.Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef __ANDROID__
|
||||
if (!m_crosshair_image.IsValid())
|
||||
{
|
||||
m_crosshair_image.SetPixels(Resources::CROSSHAIR_IMAGE_WIDTH, Resources::CROSSHAIR_IMAGE_HEIGHT,
|
||||
Resources::CROSSHAIR_IMAGE_DATA.data());
|
||||
}
|
||||
#endif
|
||||
|
||||
m_crosshair_image_scale = si.GetFloatValue(section, "CrosshairScale", 1.0f);
|
||||
|
||||
m_x_scale = si.GetFloatValue(section, "XScale", 1.0f);
|
||||
}
|
||||
|
||||
bool GunCon::GetSoftwareCursor(const Common::RGBA8Image** image, float* image_scale, bool* relative_mode)
|
||||
{
|
||||
if (!m_crosshair_image.IsValid())
|
||||
return false;
|
||||
|
||||
*image = &m_crosshair_image;
|
||||
*image_scale = m_crosshair_image_scale;
|
||||
*relative_mode = false;
|
||||
return true;
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
#include <optional>
|
||||
#include <string_view>
|
||||
|
||||
class NamcoGunCon final : public Controller
|
||||
class GunCon final : public Controller
|
||||
{
|
||||
public:
|
||||
enum class Button : u8
|
||||
|
@ -16,34 +16,27 @@ public:
|
|||
Count
|
||||
};
|
||||
|
||||
NamcoGunCon();
|
||||
~NamcoGunCon() override;
|
||||
static const Controller::ControllerInfo INFO;
|
||||
|
||||
static std::unique_ptr<NamcoGunCon> Create();
|
||||
static std::optional<s32> StaticGetAxisCodeByName(std::string_view button_name);
|
||||
static std::optional<s32> StaticGetButtonCodeByName(std::string_view button_name);
|
||||
static AxisList StaticGetAxisNames();
|
||||
static ButtonList StaticGetButtonNames();
|
||||
static u32 StaticGetVibrationMotorCount();
|
||||
static SettingList StaticGetSettings();
|
||||
GunCon(u32 index);
|
||||
~GunCon() override;
|
||||
|
||||
static std::unique_ptr<GunCon> Create(u32 index);
|
||||
|
||||
ControllerType GetType() const override;
|
||||
std::optional<s32> GetAxisCodeByName(std::string_view axis_name) const override;
|
||||
std::optional<s32> GetButtonCodeByName(std::string_view button_name) const override;
|
||||
|
||||
void Reset() override;
|
||||
bool DoState(StateWrapper& sw, bool apply_input_state) override;
|
||||
void LoadSettings(const char* section) override;
|
||||
|
||||
void LoadSettings(SettingsInterface& si, const char* section) override;
|
||||
bool GetSoftwareCursor(const Common::RGBA8Image** image, float* image_scale, bool* relative_mode) override;
|
||||
|
||||
bool GetButtonState(s32 button_code) const override;
|
||||
void SetButtonState(s32 button_code, bool pressed) override;
|
||||
float GetBindState(u32 index) const override;
|
||||
void SetBindState(u32 index, float value) override;
|
||||
|
||||
void ResetTransferState() override;
|
||||
bool Transfer(const u8 data_in, u8* data_out) override;
|
||||
|
||||
void SetButtonState(Button button, bool pressed);
|
||||
|
||||
private:
|
||||
void UpdatePosition();
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
#include "host.h"
|
||||
#include "common/string_util.h"
|
||||
#include <cstdarg>
|
||||
|
||||
void Host::ReportFormattedErrorAsync(const std::string_view& title, const char* format, ...)
|
||||
{
|
||||
std::va_list ap;
|
||||
va_start(ap, format);
|
||||
std::string message(StringUtil::StdStringFromFormatV(format, ap));
|
||||
va_end(ap);
|
||||
ReportErrorAsync(title, message);
|
||||
}
|
||||
|
||||
bool Host::ConfirmFormattedMessage(const std::string_view& title, const char* format, ...)
|
||||
{
|
||||
std::va_list ap;
|
||||
va_start(ap, format);
|
||||
std::string message = StringUtil::StdStringFromFormatV(format, ap);
|
||||
va_end(ap);
|
||||
|
||||
return ConfirmMessage(title, message);
|
||||
}
|
||||
|
||||
void Host::ReportFormattedDebuggerMessage(const char* format, ...)
|
||||
{
|
||||
std::va_list ap;
|
||||
va_start(ap, format);
|
||||
std::string message = StringUtil::StdStringFromFormatV(format, ap);
|
||||
va_end(ap);
|
||||
|
||||
ReportDebuggerMessage(message);
|
||||
}
|
|
@ -1,12 +1,67 @@
|
|||
#pragma once
|
||||
|
||||
#include "common/string.h"
|
||||
#include "common/types.h"
|
||||
|
||||
#include <ctime>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
struct WindowInfo;
|
||||
enum class AudioBackend : u8;
|
||||
class AudioStream;
|
||||
class CDImage;
|
||||
|
||||
/// Marks a core string as being translatable.
|
||||
#define TRANSLATABLE(context, str) str
|
||||
|
||||
/// Generic input bindings. These roughly match a DualShock 4 or XBox One controller.
|
||||
/// They are used for automatic binding to PS2 controller types, and for big picture mode navigation.
|
||||
enum class GenericInputBinding : u8
|
||||
{
|
||||
Unknown,
|
||||
|
||||
DPadUp,
|
||||
DPadRight,
|
||||
DPadLeft,
|
||||
DPadDown,
|
||||
|
||||
LeftStickUp,
|
||||
LeftStickRight,
|
||||
LeftStickDown,
|
||||
LeftStickLeft,
|
||||
L3,
|
||||
|
||||
RightStickUp,
|
||||
RightStickRight,
|
||||
RightStickDown,
|
||||
RightStickLeft,
|
||||
R3,
|
||||
|
||||
Triangle, // Y on XBox pads.
|
||||
Circle, // B on XBox pads.
|
||||
Cross, // A on XBox pads.
|
||||
Square, // X on XBox pads.
|
||||
|
||||
Select, // Share on DS4, View on XBox pads.
|
||||
Start, // Options on DS4, Menu on XBox pads.
|
||||
System, // PS button on DS4, Guide button on XBox pads.
|
||||
|
||||
L1, // LB on Xbox pads.
|
||||
L2, // Left trigger on XBox pads.
|
||||
R1, // RB on XBox pads.
|
||||
R2, // Right trigger on Xbox pads.
|
||||
|
||||
SmallMotor, // High frequency vibration.
|
||||
LargeMotor, // Low frequency vibration.
|
||||
|
||||
Count,
|
||||
};
|
||||
|
||||
namespace Host {
|
||||
/// Reads a file from the resources directory of the application.
|
||||
/// This may be outside of the "normal" filesystem on platforms such as Mac.
|
||||
|
@ -15,6 +70,18 @@ std::optional<std::vector<u8>> ReadResourceFile(const char* filename);
|
|||
/// Reads a resource file file from the resources directory as a string.
|
||||
std::optional<std::string> ReadResourceFileToString(const char* filename);
|
||||
|
||||
/// Returns the modified time of a resource.
|
||||
std::optional<std::time_t> GetResourceFileTimestamp(const char* filename);
|
||||
|
||||
/// Translates a string to the current language.
|
||||
TinyString TranslateString(const char* context, const char* str, const char* disambiguation = nullptr, int n = -1);
|
||||
std::string TranslateStdString(const char* context, const char* str, const char* disambiguation = nullptr, int n = -1);
|
||||
|
||||
std::unique_ptr<AudioStream> CreateAudioStream(AudioBackend backend);
|
||||
|
||||
/// Returns the scale of OSD elements.
|
||||
float GetOSDScale();
|
||||
|
||||
/// Adds OSD messages, duration is in seconds.
|
||||
void AddOSDMessage(std::string message, float duration = 2.0f);
|
||||
void AddKeyedOSDMessage(std::string key, std::string message, float duration = 2.0f);
|
||||
|
@ -26,4 +93,26 @@ void ClearOSDMessages();
|
|||
/// Displays an asynchronous error on the UI thread, i.e. doesn't block the caller.
|
||||
void ReportErrorAsync(const std::string_view& title, const std::string_view& message);
|
||||
void ReportFormattedErrorAsync(const std::string_view& title, const char* format, ...);
|
||||
|
||||
/// Displays a synchronous confirmation on the UI thread, i.e. blocks the caller.
|
||||
bool ConfirmMessage(const std::string_view& title, const std::string_view& message);
|
||||
bool ConfirmFormattedMessage(const std::string_view& title, const char* format, ...);
|
||||
|
||||
/// Debugger feedback.
|
||||
void ReportDebuggerMessage(const std::string_view& message);
|
||||
void ReportFormattedDebuggerMessage(const char* format, ...);
|
||||
|
||||
/// Displays a loading screen with the logo, rendered with ImGui. Use when executing possibly-time-consuming tasks
|
||||
/// such as compiling shaders when starting up.
|
||||
void DisplayLoadingScreen(const char* message, int progress_min = -1, int progress_max = -1, int progress_value = -1);
|
||||
|
||||
/// Internal method used by pads to dispatch vibration updates to input sources.
|
||||
/// Intensity is normalized from 0 to 1.
|
||||
void SetPadVibrationIntensity(u32 pad_index, float large_or_single_motor_intensity, float small_motor_intensity);
|
||||
|
||||
/// Enables "relative" mouse mode, locking the cursor position and returning relative coordinates.
|
||||
void SetMouseMode(bool relative, bool hide_cursor);
|
||||
|
||||
/// Safely executes a function on the VM thread.
|
||||
void RunOnCPUThread(std::function<void()> function, bool block = false);
|
||||
} // namespace Host
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include "common/log.h"
|
||||
#include "common/string_util.h"
|
||||
#include "common/timer.h"
|
||||
#include "host_interface.h"
|
||||
#include "stb_image.h"
|
||||
#include "stb_image_resize.h"
|
||||
#include "stb_image_write.h"
|
||||
|
@ -16,10 +15,72 @@
|
|||
#include <vector>
|
||||
Log_SetChannel(HostDisplay);
|
||||
|
||||
std::unique_ptr<HostDisplay> g_host_display;
|
||||
|
||||
HostDisplayTexture::~HostDisplayTexture() = default;
|
||||
|
||||
HostDisplay::~HostDisplay() = default;
|
||||
|
||||
HostDisplay::RenderAPI HostDisplay::GetPreferredAPI()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return RenderAPI::D3D11;
|
||||
#else
|
||||
return RenderAPI::OpenGL;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool HostDisplay::ParseFullscreenMode(const std::string_view& mode, u32* width, u32* height, float* refresh_rate)
|
||||
{
|
||||
if (!mode.empty())
|
||||
{
|
||||
std::string_view::size_type sep1 = mode.find('x');
|
||||
if (sep1 != std::string_view::npos)
|
||||
{
|
||||
std::optional<u32> owidth = StringUtil::FromChars<u32>(mode.substr(0, sep1));
|
||||
sep1++;
|
||||
|
||||
while (sep1 < mode.length() && std::isspace(mode[sep1]))
|
||||
sep1++;
|
||||
|
||||
if (owidth.has_value() && sep1 < mode.length())
|
||||
{
|
||||
std::string_view::size_type sep2 = mode.find('@', sep1);
|
||||
if (sep2 != std::string_view::npos)
|
||||
{
|
||||
std::optional<u32> oheight = StringUtil::FromChars<u32>(mode.substr(sep1, sep2 - sep1));
|
||||
sep2++;
|
||||
|
||||
while (sep2 < mode.length() && std::isspace(mode[sep2]))
|
||||
sep2++;
|
||||
|
||||
if (oheight.has_value() && sep2 < mode.length())
|
||||
{
|
||||
std::optional<float> orefresh_rate = StringUtil::FromChars<float>(mode.substr(sep2));
|
||||
if (orefresh_rate.has_value())
|
||||
{
|
||||
*width = owidth.value();
|
||||
*height = oheight.value();
|
||||
*refresh_rate = orefresh_rate.value();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*width = 0;
|
||||
*height = 0;
|
||||
*refresh_rate = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string HostDisplay::GetFullscreenModeString(u32 width, u32 height, float refresh_rate)
|
||||
{
|
||||
return StringUtil::StdStringFromFormat("%u x %u @ %f hz", width, height, refresh_rate);
|
||||
}
|
||||
|
||||
bool HostDisplay::UsesLowerLeftOrigin() const
|
||||
{
|
||||
const RenderAPI api = GetRenderAPI();
|
||||
|
|
|
@ -62,6 +62,15 @@ public:
|
|||
|
||||
virtual ~HostDisplay();
|
||||
|
||||
/// Returns the default/preferred API for the system.
|
||||
static RenderAPI GetPreferredAPI();
|
||||
|
||||
/// Parses a fullscreen mode into its components (width * height @ refresh hz)
|
||||
static bool ParseFullscreenMode(const std::string_view& mode, u32* width, u32* height, float* refresh_rate);
|
||||
|
||||
/// Converts a fullscreen mode to a string.
|
||||
static std::string GetFullscreenModeString(u32 width, u32 height, float refresh_rate);
|
||||
|
||||
ALWAYS_INLINE const WindowInfo& GetWindowInfo() const { return m_window_info; }
|
||||
ALWAYS_INLINE s32 GetWindowWidth() const { return static_cast<s32>(m_window_info.surface_width); }
|
||||
ALWAYS_INLINE s32 GetWindowHeight() const { return static_cast<s32>(m_window_info.surface_height); }
|
||||
|
@ -290,3 +299,25 @@ protected:
|
|||
bool m_display_integer_scaling = false;
|
||||
bool m_display_stretch = false;
|
||||
};
|
||||
|
||||
/// Returns a pointer to the current host display abstraction. Assumes AcquireHostDisplay() has been caled.
|
||||
extern std::unique_ptr<HostDisplay> g_host_display;
|
||||
|
||||
namespace Host {
|
||||
/// Creates the host display. This may create a new window. The API used depends on the current configuration.
|
||||
bool AcquireHostDisplay(HostDisplay::RenderAPI api);
|
||||
|
||||
/// Destroys the host display. This may close the display window.
|
||||
void ReleaseHostDisplay();
|
||||
|
||||
/// Returns false if the window was completely occluded. If frame_skip is set, the frame won't be
|
||||
/// displayed, but the GPU command queue will still be flushed.
|
||||
//bool BeginPresentFrame(bool frame_skip);
|
||||
|
||||
/// Presents the frame to the display, and renders OSD elements.
|
||||
//void EndPresentFrame();
|
||||
|
||||
/// Provided by the host; renders the display.
|
||||
void RenderDisplay();
|
||||
void InvalidateDisplay();
|
||||
} // namespace Host
|
||||
|
|
|
@ -1,225 +0,0 @@
|
|||
#pragma once
|
||||
#include "common/string.h"
|
||||
#include "common/timer.h"
|
||||
#include "settings.h"
|
||||
#include "types.h"
|
||||
#include <chrono>
|
||||
#include <deque>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
enum LOGLEVEL;
|
||||
|
||||
class AudioStream;
|
||||
class ByteStream;
|
||||
class CDImage;
|
||||
class HostDisplay;
|
||||
class GameList;
|
||||
|
||||
struct SystemBootParameters;
|
||||
|
||||
namespace BIOS {
|
||||
struct ImageInfo;
|
||||
}
|
||||
|
||||
class HostInterface
|
||||
{
|
||||
public:
|
||||
enum : u32
|
||||
{
|
||||
AUDIO_SAMPLE_RATE = 44100,
|
||||
AUDIO_CHANNELS = 2,
|
||||
DEFAULT_AUDIO_BUFFER_SIZE = 2048
|
||||
};
|
||||
|
||||
HostInterface();
|
||||
virtual ~HostInterface();
|
||||
|
||||
/// Access to host display.
|
||||
ALWAYS_INLINE HostDisplay* GetDisplay() const { return m_display.get(); }
|
||||
ALWAYS_INLINE bool HasDisplay() const { return static_cast<bool>(m_display.get()); }
|
||||
|
||||
/// Access to host audio stream.
|
||||
ALWAYS_INLINE AudioStream* GetAudioStream() const { return m_audio_stream.get(); }
|
||||
|
||||
/// Initializes the emulator frontend.
|
||||
virtual bool Initialize();
|
||||
|
||||
/// Shuts down the emulator frontend.
|
||||
virtual void Shutdown();
|
||||
|
||||
virtual bool BootSystem(std::shared_ptr<SystemBootParameters> parameters);
|
||||
virtual void PauseSystem(bool paused);
|
||||
virtual void ResetSystem();
|
||||
virtual void DestroySystem();
|
||||
|
||||
/// Loads state from the specified filename.
|
||||
bool LoadState(const char* filename);
|
||||
|
||||
virtual void ReportError(const char* message);
|
||||
virtual void ReportMessage(const char* message);
|
||||
virtual void ReportDebuggerMessage(const char* message);
|
||||
virtual bool ConfirmMessage(const char* message);
|
||||
|
||||
void ReportFormattedError(const char* format, ...) printflike(2, 3);
|
||||
void ReportFormattedMessage(const char* format, ...) printflike(2, 3);
|
||||
void ReportFormattedDebuggerMessage(const char* format, ...) printflike(2, 3);
|
||||
bool ConfirmFormattedMessage(const char* format, ...) printflike(2, 3);
|
||||
|
||||
/// Adds OSD messages, duration is in seconds.
|
||||
virtual void AddOSDMessage(std::string message, float duration = 2.0f) = 0;
|
||||
virtual void AddKeyedOSDMessage(std::string key, std::string message, float duration = 2.0f) = 0;
|
||||
virtual void RemoveKeyedOSDMessage(std::string key) = 0;
|
||||
void AddFormattedOSDMessage(float duration, const char* format, ...) printflike(3, 4);
|
||||
void AddKeyedFormattedOSDMessage(std::string key, float duration, const char* format, ...) printflike(4, 5);
|
||||
|
||||
/// Returns the base user directory path.
|
||||
ALWAYS_INLINE const std::string& GetUserDirectory() const { return m_user_directory; }
|
||||
|
||||
/// Returns a path relative to the user directory.
|
||||
std::string GetUserDirectoryRelativePath(const char* format, ...) const printflike(2, 3);
|
||||
|
||||
/// Returns a path relative to the application directory (for system files).
|
||||
std::string GetProgramDirectoryRelativePath(const char* format, ...) const printflike(2, 3);
|
||||
|
||||
/// Returns a string which can be used as part of a filename, based on the current date/time.
|
||||
static TinyString GetTimestampStringForFileName();
|
||||
|
||||
/// Displays a loading screen with the logo, rendered with ImGui. Use when executing possibly-time-consuming tasks
|
||||
/// such as compiling shaders when starting up.
|
||||
virtual void DisplayLoadingScreen(const char* message, int progress_min = -1, int progress_max = -1,
|
||||
int progress_value = -1) = 0;
|
||||
|
||||
/// Retrieves information about specified game from game list.
|
||||
virtual void GetGameInfo(const char* path, CDImage* image, std::string* code, std::string* title) = 0;
|
||||
|
||||
/// Returns the directory where per-game memory cards will be saved.
|
||||
virtual std::string GetMemoryCardDirectory() const;
|
||||
|
||||
/// Returns the default path to a memory card.
|
||||
virtual std::string GetSharedMemoryCardPath(u32 slot) const;
|
||||
|
||||
/// Returns the default path to a memory card for a specific game.
|
||||
virtual std::string GetGameMemoryCardPath(const char* game_code, u32 slot) const;
|
||||
|
||||
/// Returns the path to the shader cache directory.
|
||||
virtual std::string GetShaderCacheBasePath() const;
|
||||
|
||||
/// Returns a setting value from the configuration.
|
||||
virtual std::string GetStringSettingValue(const char* section, const char* key, const char* default_value = "") = 0;
|
||||
|
||||
/// Returns a boolean setting from the configuration.
|
||||
virtual bool GetBoolSettingValue(const char* section, const char* key, bool default_value = false);
|
||||
|
||||
/// Returns an integer setting from the configuration.
|
||||
virtual int GetIntSettingValue(const char* section, const char* key, int default_value = 0);
|
||||
|
||||
/// Returns a float setting from the configuration.
|
||||
virtual float GetFloatSettingValue(const char* section, const char* key, float default_value = 0.0f);
|
||||
|
||||
/// Returns a string list from the configuration.
|
||||
virtual std::vector<std::string> GetSettingStringList(const char* section, const char* key) = 0;
|
||||
|
||||
/// Returns the settings interface.
|
||||
virtual SettingsInterface* GetSettingsInterface() = 0;
|
||||
virtual std::lock_guard<std::recursive_mutex> GetSettingsLock() = 0;
|
||||
|
||||
/// Translates a string to the current language.
|
||||
virtual TinyString TranslateString(const char* context, const char* str, const char* disambiguation = nullptr,
|
||||
int n = -1) const;
|
||||
virtual std::string TranslateStdString(const char* context, const char* str, const char* disambiguation = nullptr,
|
||||
int n = -1) const;
|
||||
|
||||
/// Returns the path to the directory to search for BIOS images.
|
||||
virtual std::string GetBIOSDirectory();
|
||||
|
||||
/// Loads the BIOS image for the specified region.
|
||||
std::optional<std::vector<u8>> GetBIOSImage(ConsoleRegion region);
|
||||
|
||||
/// Searches for a BIOS image for the specified region in the specified directory. If no match is found, the first
|
||||
/// BIOS image within 512KB and 4MB will be used.
|
||||
std::optional<std::vector<u8>> FindBIOSImageInDirectory(ConsoleRegion region, const char* directory);
|
||||
|
||||
/// Returns a list of filenames and descriptions for BIOS images in a directory.
|
||||
std::vector<std::pair<std::string, const BIOS::ImageInfo*>> FindBIOSImagesInDirectory(const char* directory);
|
||||
|
||||
/// Returns true if any BIOS images are found in the configured BIOS directory.
|
||||
bool HasAnyBIOSImages();
|
||||
|
||||
/// Opens a file in the DuckStation "package".
|
||||
/// This is the APK for Android builds, or the program directory for standalone builds.
|
||||
virtual std::unique_ptr<ByteStream> OpenPackageFile(const char* path, u32 flags) = 0;
|
||||
|
||||
virtual void OnRunningGameChanged(const std::string& path, CDImage* image, const std::string& game_code,
|
||||
const std::string& game_title) = 0;
|
||||
virtual void OnSystemPerformanceCountersUpdated() = 0;
|
||||
|
||||
/// Called when the display is invalidated (e.g. a state is loaded).
|
||||
virtual void OnDisplayInvalidated() = 0;
|
||||
|
||||
/// Called when achievements data is loaded.
|
||||
virtual void OnAchievementsRefreshed() = 0;
|
||||
|
||||
protected:
|
||||
virtual bool AcquireHostDisplay() = 0;
|
||||
virtual void ReleaseHostDisplay() = 0;
|
||||
virtual std::unique_ptr<AudioStream> CreateAudioStream(AudioBackend backend) = 0;
|
||||
virtual s32 GetAudioOutputVolume() const;
|
||||
|
||||
virtual void OnSystemCreated() = 0;
|
||||
virtual void OnSystemPaused(bool paused) = 0;
|
||||
virtual void OnSystemDestroyed() = 0;
|
||||
virtual void OnControllerTypeChanged(u32 slot) = 0;
|
||||
|
||||
/// Restores all settings to defaults.
|
||||
virtual void SetDefaultSettings(SettingsInterface& si);
|
||||
|
||||
/// Loads settings to m_settings and any frontend-specific parameters.
|
||||
virtual void LoadSettings(SettingsInterface& si);
|
||||
|
||||
/// Saves current settings variables to ini.
|
||||
virtual void SaveSettings(SettingsInterface& si);
|
||||
|
||||
/// Checks and fixes up any incompatible settings.
|
||||
virtual void FixIncompatibleSettings(bool display_osd_messages);
|
||||
|
||||
/// Checks for settings changes, std::move() the old settings away for comparing beforehand.
|
||||
virtual void CheckForSettingsChanges(const Settings& old_settings);
|
||||
|
||||
/// Switches the GPU renderer by saving state, recreating the display window, and restoring state (if needed).
|
||||
virtual void RecreateSystem();
|
||||
|
||||
/// Enables "relative" mouse mode, locking the cursor position and returning relative coordinates.
|
||||
virtual void SetMouseMode(bool relative, bool hide_cursor) = 0;
|
||||
|
||||
/// Call when host display size changes, use with "match display" aspect ratio setting.
|
||||
virtual void OnHostDisplayResized();
|
||||
|
||||
/// Sets the user directory to the program directory, i.e. "portable mode".
|
||||
void SetUserDirectoryToProgramDirectory();
|
||||
|
||||
/// Quick switch between software and hardware rendering.
|
||||
void ToggleSoftwareRendering();
|
||||
|
||||
/// Adjusts the internal (render) resolution of the hardware backends.
|
||||
void ModifyResolutionScale(s32 increment);
|
||||
|
||||
/// Updates software cursor state, based on controllers.
|
||||
void UpdateSoftwareCursor();
|
||||
|
||||
bool SaveState(const char* filename);
|
||||
void CreateAudioStream();
|
||||
|
||||
std::unique_ptr<HostDisplay> m_display;
|
||||
std::unique_ptr<AudioStream> m_audio_stream;
|
||||
std::string m_program_directory;
|
||||
std::string m_user_directory;
|
||||
};
|
||||
|
||||
#define TRANSLATABLE(context, str) str
|
||||
|
||||
extern HostInterface* g_host_interface;
|
|
@ -1,10 +1,14 @@
|
|||
#include "host_interface_progress_callback.h"
|
||||
#include "common/log.h"
|
||||
#include "host.h"
|
||||
Log_SetChannel(HostInterfaceProgressCallback);
|
||||
|
||||
HostInterfaceProgressCallback::HostInterfaceProgressCallback() : BaseProgressCallback() {}
|
||||
|
||||
void HostInterfaceProgressCallback::PushState() { BaseProgressCallback::PushState(); }
|
||||
void HostInterfaceProgressCallback::PushState()
|
||||
{
|
||||
BaseProgressCallback::PushState();
|
||||
}
|
||||
|
||||
void HostInterfaceProgressCallback::PopState()
|
||||
{
|
||||
|
@ -57,32 +61,42 @@ void HostInterfaceProgressCallback::Redraw(bool force)
|
|||
return;
|
||||
|
||||
m_last_progress_percent = percent;
|
||||
g_host_interface->DisplayLoadingScreen(m_status_text, 0, static_cast<int>(m_progress_range),
|
||||
static_cast<int>(m_progress_value));
|
||||
Host::DisplayLoadingScreen(m_status_text, 0, static_cast<int>(m_progress_range), static_cast<int>(m_progress_value));
|
||||
}
|
||||
|
||||
void HostInterfaceProgressCallback::DisplayError(const char* message) { Log_ErrorPrint(message); }
|
||||
void HostInterfaceProgressCallback::DisplayError(const char* message)
|
||||
{
|
||||
Log_ErrorPrint(message);
|
||||
}
|
||||
|
||||
void HostInterfaceProgressCallback::DisplayWarning(const char* message) { Log_WarningPrint(message); }
|
||||
void HostInterfaceProgressCallback::DisplayWarning(const char* message)
|
||||
{
|
||||
Log_WarningPrint(message);
|
||||
}
|
||||
|
||||
void HostInterfaceProgressCallback::DisplayInformation(const char* message) { Log_InfoPrint(message); }
|
||||
void HostInterfaceProgressCallback::DisplayInformation(const char* message)
|
||||
{
|
||||
Log_InfoPrint(message);
|
||||
}
|
||||
|
||||
void HostInterfaceProgressCallback::DisplayDebugMessage(const char* message) { Log_DevPrint(message); }
|
||||
void HostInterfaceProgressCallback::DisplayDebugMessage(const char* message)
|
||||
{
|
||||
Log_DevPrint(message);
|
||||
}
|
||||
|
||||
void HostInterfaceProgressCallback::ModalError(const char* message)
|
||||
{
|
||||
Log_ErrorPrint(message);
|
||||
g_host_interface->ReportError(message);
|
||||
Host::ReportErrorAsync("Error", message);
|
||||
}
|
||||
|
||||
bool HostInterfaceProgressCallback::ModalConfirmation(const char* message)
|
||||
{
|
||||
Log_InfoPrint(message);
|
||||
return g_host_interface->ConfirmMessage(message);
|
||||
return Host::ConfirmMessage("Confirm", message);
|
||||
}
|
||||
|
||||
void HostInterfaceProgressCallback::ModalInformation(const char* message)
|
||||
{
|
||||
Log_InfoPrint(message);
|
||||
g_host_interface->ReportMessage(message);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#pragma once
|
||||
#include "common/progress_callback.h"
|
||||
#include "host_interface.h"
|
||||
|
||||
class HostInterfaceProgressCallback final : public BaseProgressCallback
|
||||
{
|
||||
|
|
|
@ -18,13 +18,16 @@ double GetBaseDoubleSettingValue(const char* section, const char* key, double de
|
|||
std::vector<std::string> GetBaseStringListSetting(const char* section, const char* key);
|
||||
|
||||
// Allows the emucore to write settings back to the frontend. Use with care.
|
||||
// You should call CommitBaseSettingChanges() after finishing writing, or it may not be written to disk.
|
||||
// You should call CommitBaseSettingChanges() if you directly write to the layer (i.e. not these functions), or it may
|
||||
// not be written to disk.
|
||||
void SetBaseBoolSettingValue(const char* section, const char* key, bool value);
|
||||
void SetBaseIntSettingValue(const char* section, const char* key, s32 value);
|
||||
void SetBaseUIntSettingValue(const char* section, const char* key, u32 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 AddValueToBaseStringListSetting(const char* section, const char* key, const char* value);
|
||||
bool RemoveValueFromBaseStringListSetting(const char* section, const char* key, const char* value);
|
||||
void DeleteBaseSettingValue(const char* section, const char* key);
|
||||
void CommitBaseSettingChanges();
|
||||
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
#include "imgui_styles.h"
|
||||
|
||||
void ImGui::StyleColorsDarker(ImGuiStyle* dst)
|
||||
{
|
||||
ImGuiStyle* style = dst ? dst : &ImGui::GetStyle();
|
||||
ImVec4* colors = style->Colors;
|
||||
|
||||
colors[ImGuiCol_Text] = ImVec4(0.95f, 0.96f, 0.98f, 1.00f);
|
||||
colors[ImGuiCol_TextDisabled] = ImVec4(0.36f, 0.42f, 0.47f, 1.00f);
|
||||
colors[ImGuiCol_WindowBg] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
|
||||
colors[ImGuiCol_ChildBg] = ImVec4(0.15f, 0.18f, 0.22f, 1.00f);
|
||||
colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.08f, 0.08f, 0.94f);
|
||||
colors[ImGuiCol_Border] = ImVec4(0.08f, 0.10f, 0.12f, 1.00f);
|
||||
colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
|
||||
colors[ImGuiCol_FrameBg] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
|
||||
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.12f, 0.20f, 0.28f, 1.00f);
|
||||
colors[ImGuiCol_FrameBgActive] = ImVec4(0.09f, 0.12f, 0.14f, 1.00f);
|
||||
colors[ImGuiCol_TitleBg] = ImVec4(0.09f, 0.12f, 0.14f, 0.65f);
|
||||
colors[ImGuiCol_TitleBgActive] = ImVec4(0.08f, 0.10f, 0.12f, 1.00f);
|
||||
colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 0.51f);
|
||||
colors[ImGuiCol_MenuBarBg] = ImVec4(0.15f, 0.18f, 0.22f, 1.00f);
|
||||
colors[ImGuiCol_ScrollbarBg] = ImVec4(0.02f, 0.02f, 0.02f, 0.39f);
|
||||
colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
|
||||
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.18f, 0.22f, 0.25f, 1.00f);
|
||||
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.09f, 0.21f, 0.31f, 1.00f);
|
||||
colors[ImGuiCol_CheckMark] = ImVec4(0.28f, 0.56f, 1.00f, 1.00f);
|
||||
colors[ImGuiCol_SliderGrab] = ImVec4(0.28f, 0.56f, 1.00f, 1.00f);
|
||||
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.37f, 0.61f, 1.00f, 1.00f);
|
||||
colors[ImGuiCol_Button] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
|
||||
colors[ImGuiCol_ButtonHovered] = ImVec4(0.33f, 0.38f, 0.46f, 1.00f);
|
||||
colors[ImGuiCol_ButtonActive] = ImVec4(0.27f, 0.32f, 0.38f, 1.00f);
|
||||
colors[ImGuiCol_Header] = ImVec4(0.20f, 0.25f, 0.29f, 0.55f);
|
||||
colors[ImGuiCol_HeaderHovered] = ImVec4(0.33f, 0.38f, 0.46f, 1.00f);
|
||||
colors[ImGuiCol_HeaderActive] = ImVec4(0.27f, 0.32f, 0.38f, 1.00f);
|
||||
colors[ImGuiCol_Separator] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
|
||||
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.33f, 0.38f, 0.46f, 1.00f);
|
||||
colors[ImGuiCol_SeparatorActive] = ImVec4(0.27f, 0.32f, 0.38f, 1.00f);
|
||||
colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.59f, 0.98f, 0.25f);
|
||||
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.33f, 0.38f, 0.46f, 1.00f);
|
||||
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.27f, 0.32f, 0.38f, 1.00f);
|
||||
colors[ImGuiCol_Tab] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
|
||||
colors[ImGuiCol_TabHovered] = ImVec4(0.33f, 0.38f, 0.46f, 1.00f);
|
||||
colors[ImGuiCol_TabActive] = ImVec4(0.27f, 0.32f, 0.38f, 1.00f);
|
||||
colors[ImGuiCol_TabUnfocused] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
|
||||
colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
|
||||
colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f);
|
||||
colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f);
|
||||
colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
|
||||
colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f);
|
||||
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f);
|
||||
colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f);
|
||||
colors[ImGuiCol_NavHighlight] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
|
||||
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f);
|
||||
colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f);
|
||||
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f);
|
||||
}
|