diff --git a/CMakeLists.txt b/CMakeLists.txt index a02270e70..964495d6f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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() diff --git a/data/database/chtdb.txt b/data/resources/chtdb.txt similarity index 100% rename from data/database/chtdb.txt rename to data/resources/chtdb.txt diff --git a/data/database/compatibility.xml b/data/resources/database/compatibility.xml similarity index 100% rename from data/database/compatibility.xml rename to data/resources/database/compatibility.xml diff --git a/data/database/gamedb.json b/data/resources/database/gamedb.json similarity index 99% rename from data/database/gamedb.json rename to data/resources/database/gamedb.json index 8a832339c..97cded1bf 100644 --- a/data/database/gamedb.json +++ b/data/resources/database/gamedb.json @@ -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" ] }, diff --git a/data/database/gamesettings.ini b/data/resources/database/gamesettings.ini similarity index 100% rename from data/database/gamesettings.ini rename to data/resources/database/gamesettings.ini diff --git a/data/resources/fonts/LICENSE.txt b/data/resources/fonts/LICENSE.txt new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/data/resources/fonts/LICENSE.txt @@ -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. diff --git a/data/resources/roboto-regular.ttf b/data/resources/fonts/Roboto-Regular.ttf similarity index 100% rename from data/resources/roboto-regular.ttf rename to data/resources/fonts/Roboto-Regular.ttf diff --git a/data/resources/fonts/RobotoMono-Medium.ttf b/data/resources/fonts/RobotoMono-Medium.ttf new file mode 100644 index 000000000..8461be77a Binary files /dev/null and b/data/resources/fonts/RobotoMono-Medium.ttf differ diff --git a/data/resources/fa-solid-900.ttf b/data/resources/fonts/fa-solid-900.ttf similarity index 100% rename from data/resources/fa-solid-900.ttf rename to data/resources/fonts/fa-solid-900.ttf diff --git a/data/resources/flag-jp.png b/data/resources/fullscreenui/NTSC-J.png similarity index 100% rename from data/resources/flag-jp.png rename to data/resources/fullscreenui/NTSC-J.png diff --git a/data/resources/flag-uc.png b/data/resources/fullscreenui/NTSC-U.png similarity index 100% rename from data/resources/flag-uc.png rename to data/resources/fullscreenui/NTSC-U.png diff --git a/data/resources/flag-eu.png b/data/resources/fullscreenui/PAL.png similarity index 100% rename from data/resources/flag-eu.png rename to data/resources/fullscreenui/PAL.png diff --git a/data/resources/address-book-new.png b/data/resources/fullscreenui/address-book-new.png similarity index 100% rename from data/resources/address-book-new.png rename to data/resources/fullscreenui/address-book-new.png diff --git a/data/resources/applications-system.png b/data/resources/fullscreenui/applications-system.png similarity index 100% rename from data/resources/applications-system.png rename to data/resources/fullscreenui/applications-system.png diff --git a/data/resources/duck.png b/data/resources/fullscreenui/duck.png similarity index 100% rename from data/resources/duck.png rename to data/resources/fullscreenui/duck.png diff --git a/data/resources/media-cdrom.png b/data/resources/fullscreenui/media-cdrom.png similarity index 100% rename from data/resources/media-cdrom.png rename to data/resources/fullscreenui/media-cdrom.png diff --git a/data/resources/multimedia-player.png b/data/resources/fullscreenui/multimedia-player.png similarity index 100% rename from data/resources/multimedia-player.png rename to data/resources/fullscreenui/multimedia-player.png diff --git a/data/resources/fullscreenui/placeholder.png b/data/resources/fullscreenui/placeholder.png new file mode 100644 index 000000000..064082d2c Binary files /dev/null and b/data/resources/fullscreenui/placeholder.png differ diff --git a/data/resources/star-0.png b/data/resources/fullscreenui/star-0.png similarity index 100% rename from data/resources/star-0.png rename to data/resources/fullscreenui/star-0.png diff --git a/data/resources/star-1.png b/data/resources/fullscreenui/star-1.png similarity index 100% rename from data/resources/star-1.png rename to data/resources/fullscreenui/star-1.png diff --git a/data/resources/star-2.png b/data/resources/fullscreenui/star-2.png similarity index 100% rename from data/resources/star-2.png rename to data/resources/fullscreenui/star-2.png diff --git a/data/resources/star-3.png b/data/resources/fullscreenui/star-3.png similarity index 100% rename from data/resources/star-3.png rename to data/resources/fullscreenui/star-3.png diff --git a/data/resources/star-4.png b/data/resources/fullscreenui/star-4.png similarity index 100% rename from data/resources/star-4.png rename to data/resources/fullscreenui/star-4.png diff --git a/data/resources/star-5.png b/data/resources/fullscreenui/star-5.png similarity index 100% rename from data/resources/star-5.png rename to data/resources/fullscreenui/star-5.png diff --git a/data/database/gamecontrollerdb.txt b/data/resources/gamecontrollerdb.txt similarity index 100% rename from data/database/gamecontrollerdb.txt rename to data/resources/gamecontrollerdb.txt diff --git a/data/resources/images/cover-placeholder.png b/data/resources/images/cover-placeholder.png new file mode 100644 index 000000000..18dc446fe Binary files /dev/null and b/data/resources/images/cover-placeholder.png differ diff --git a/dep/msvc/qt b/dep/msvc/qt index fb9018121..f44f99baa 160000 --- a/dep/msvc/qt +++ b/dep/msvc/qt @@ -1 +1 @@ -Subproject commit fb9018121818293b72e9f5064b2cb202e713c501 +Subproject commit f44f99baad9c52e6e98831f95dde283b3c3d7993 diff --git a/dep/msvc/vsprops/QtCompile.props b/dep/msvc/vsprops/QtCompile.props index c01b9bbfb..ceeff3114 100644 --- a/dep/msvc/vsprops/QtCompile.props +++ b/dep/msvc/vsprops/QtCompile.props @@ -2,36 +2,38 @@ $(SolutionDir)bin\$(Platform)\ - $(SolutionDir)dep\msvc\qt\6.1.0\msvc2019_64\ - $(SolutionDir)dep\msvc\qt\6.1.0\msvc2019_arm64\ - $(QTDIRDefault) - $(QTDIR)\ - $(SolutionDir)dep\msvc\qt\6.1.0\msvc2019_64\ - false - true - $(QTDIR)include\ - $(QTDIR)lib\ - $(QTDIR)bin\ - $(QTDIRHost)bin\ - $(QTDIR)plugins\ - $(QTDIR)translations\ - $(SolutionDir)build\$(ProjectName)-$(Platform)-$(Configuration)\ + $(SolutionDir)dep\msvc\qt\6.1.0\msvc2019_64\ + $(SolutionDir)dep\msvc\qt\6.3.1\msvc2022_arm64\ + $(DSQTDIRDefault) + $(DSQTDIR)\ + $(SolutionDir)dep\msvc\qt\6.1.0\msvc2019_64\ + $(SolutionDir)dep\msvc\qt\6.3.1\msvc2022_64\ + false + true + $(DSQTDIR)include\ + $(DSQTDIR)lib\ + $(DSQTDIR)bin\ + $(DSQTDIRHost)bin\ + $(DSQTDIR)plugins\ + $(DSQTDIR)translations\ + $(IntDir) $(QtToolOutDir)moc_ $(BinaryOutputDir)translations\ d - $(QtDebugSuffix) + $(QtDebugSuffix) QtPlugins + $(QtLibDir)Qt6EntryPoint$(QtLibSuffix).lib - QT_NO_DEBUG;%(PreprocessorDefinitions) + QT_NO_DEBUG;%(PreprocessorDefinitions) $(ProjectDir);%(AdditionalIncludeDirectories) $(QtToolOutDir);%(AdditionalIncludeDirectories) $(QtIncludeDir);%(AdditionalIncludeDirectories) $(QtLibDir);%(AdditionalLibraryDirectories) - Qt6Core$(QtLibSuffix).lib;Qt6Gui$(QtLibSuffix).lib;Qt6Widgets$(QtLibSuffix).lib;Qt6Network$(QtLibSuffix).lib;%(AdditionalDependencies) + Qt6Core$(QtLibSuffix).lib;Qt6Gui$(QtLibSuffix).lib;Qt6Widgets$(QtLibSuffix).lib;Qt6Network$(QtLibSuffix).lib;Qt6Concurrent$(QtLibSuffix).lib;%(AdditionalDependencies) @@ -45,7 +47,7 @@ Condition="'@(QtResource)'!=''" Outputs="@(ResFiles->'$(QtToolOutDir)qrc_%(Filename).cpp')"> - + @@ -64,7 +66,7 @@ Condition="'@(QtUi)'!=''" Outputs="@(UiFiles->'$(QtToolOutDir)ui_%(Filename).h')"> - + @@ -77,26 +79,18 @@ - -DQT_NO_DEBUG -DNDEBUG $(MocDefines) - - "-I$(QtIncludeDir)" "-I$(SolutionDir)src" -I. + -DQT_NO_DEBUG -DNDEBUG $(MocDefines) + -I"$(QtIncludeDir)." -I"$(SolutionDir)pcsx2" "-I$(SolutionDir)." -I. - - + Outputs="$(QtToolOutDir)%(QtMoc.RelativeDir)moc_%(QtMoc.Filename).cpp"> + + - + @@ -125,21 +119,24 @@ - + - - + + + + + $(BinaryOutputDir)qt.conf + Inputs="@(QtDlls);@(QtPlugins);@(QtTLSDlls)" + Outputs="@(QtDlls -> '$(BinaryOutputDir)%(RecursiveDir)%(Filename)%(Extension)');@(QtPluginsDest);@(QtTLSDllsDest)"> + - + diff --git a/duckstation.sln b/duckstation.sln index 85630632f..bae76438e 100644 --- a/duckstation.sln +++ b/duckstation.sln @@ -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 diff --git a/src/common/byte_stream.cpp b/src/common/byte_stream.cpp index 5a2639399..53ba7791b 100644 --- a/src/common/byte_stream.cpp +++ b/src/common/byte_stream.cpp @@ -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(str.size()); + return (Write2(&size, sizeof(size)) && (size == 0 || Write2(str.data(), size))); +} + std::unique_ptr ByteStream::OpenFile(const char* fileName, u32 openMode) { if ((openMode & (BYTESTREAM_OPEN_CREATE | BYTESTREAM_OPEN_WRITE)) == BYTESTREAM_OPEN_WRITE) diff --git a/src/common/byte_stream.h b/src/common/byte_stream.h index cc4506cf0..b4f163101 100644 --- a/src/common/byte_stream.h +++ b/src/common/byte_stream.h @@ -2,6 +2,7 @@ #include "types.h" #include #include +#include #include // 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 OpenFile(const char* FileName, u32 OpenMode); diff --git a/src/common/d3d11/shader_cache.cpp b/src/common/d3d11/shader_cache.cpp index 7ed06c32c..1b77c8a62 100644 --- a/src/common/d3d11/shader_cache.cpp +++ b/src/common/d3d11/shader_cache.cpp @@ -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) { diff --git a/src/common/d3d12/shader_cache.cpp b/src/common/d3d12/shader_cache.cpp index 4baa09266..4ef40a3e5 100644 --- a/src/common/d3d12/shader_cache.cpp +++ b/src/common/d3d12/shader_cache.cpp @@ -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 += "_"; diff --git a/src/common/gl/shader_cache.cpp b/src/common/gl/shader_cache.cpp index 3306c4b79..f64055204 100644 --- a/src/common/gl/shader_cache.cpp +++ b/src/common/gl/shader_cache.cpp @@ -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 ShaderCache::GetProgram(const std::string_view vertex_shader, diff --git a/src/common/http_downloader.cpp b/src/common/http_downloader.cpp index b44dd5db2..ec558595c 100644 --- a/src/common/http_downloader.cpp +++ b/src/common/http_downloader.cpp @@ -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"; diff --git a/src/common/http_downloader.h b/src/common/http_downloader.h index 2b9e8f82c..5a83aafc7 100644 --- a/src/common/http_downloader.h +++ b/src/common/http_downloader.h @@ -7,7 +7,7 @@ #include #include -namespace FrontendCommon { +namespace Common { class HTTPDownloader { diff --git a/src/common/http_downloader_curl.cpp b/src/common/http_downloader_curl.cpp index 3809a4750..6513817d3 100644 --- a/src/common/http_downloader_curl.cpp +++ b/src/common/http_downloader_curl.cpp @@ -9,7 +9,7 @@ #include Log_SetChannel(HTTPDownloaderCurl); -namespace FrontendCommon { +namespace Common { HTTPDownloaderCurl::HTTPDownloaderCurl() : HTTPDownloader() {} diff --git a/src/common/http_downloader_curl.h b/src/common/http_downloader_curl.h index 3f18ec30b..9fbcf6a57 100644 --- a/src/common/http_downloader_curl.h +++ b/src/common/http_downloader_curl.h @@ -6,7 +6,7 @@ #include #include -namespace FrontendCommon { +namespace Common { class HTTPDownloaderCurl final : public HTTPDownloader { diff --git a/src/common/http_downloader_uwp.cpp b/src/common/http_downloader_uwp.cpp index 3a3573008..e3159923a 100644 --- a/src/common/http_downloader_uwp.cpp +++ b/src/common/http_downloader_uwp.cpp @@ -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)) {} diff --git a/src/common/http_downloader_uwp.h b/src/common/http_downloader_uwp.h index f476f5205..3a0be4299 100644 --- a/src/common/http_downloader_uwp.h +++ b/src/common/http_downloader_uwp.h @@ -6,7 +6,7 @@ #include -namespace FrontendCommon { +namespace Common { class HTTPDownloaderUWP final : public HTTPDownloader { diff --git a/src/common/http_downloader_winhttp.cpp b/src/common/http_downloader_winhttp.cpp index 1aa95fb15..cfbc6d7be 100644 --- a/src/common/http_downloader_winhttp.cpp +++ b/src/common/http_downloader_winhttp.cpp @@ -9,7 +9,7 @@ Log_SetChannel(HTTPDownloaderWinHttp); #pragma comment(lib, "winhttp.lib") -namespace FrontendCommon { +namespace Common { HTTPDownloaderWinHttp::HTTPDownloaderWinHttp() : HTTPDownloader() {} diff --git a/src/common/http_downloader_winhttp.h b/src/common/http_downloader_winhttp.h index 5168fbfb0..8fda82232 100644 --- a/src/common/http_downloader_winhttp.h +++ b/src/common/http_downloader_winhttp.h @@ -5,7 +5,7 @@ #include -namespace FrontendCommon { +namespace Common { class HTTPDownloaderWinHttp final : public HTTPDownloader { diff --git a/src/common/lru_cache.h b/src/common/lru_cache.h index 6c76e66cb..aafae1837 100644 --- a/src/common/lru_cache.h +++ b/src/common/lru_cache.h @@ -1,4 +1,5 @@ #pragma once +#include "heterogeneous_containers.h" #include #include @@ -13,7 +14,7 @@ class LRUCache CounterType last_access; }; - using MapType = std::map; + using MapType = std::conditional_t, StringMap, std::map>; public: LRUCache(std::size_t max_capacity = 16, bool manual_evict = false) diff --git a/src/common/threading.cpp b/src/common/threading.cpp index 07428fffc..b814727d9 100644 --- a/src/common/threading.cpp +++ b/src/common/threading.cpp @@ -24,15 +24,18 @@ #include #define gettid() syscall(SYS_gettid) #endif -#else +#elif defined(__APPLE__) +#include +#include +#include +#include +#include #include #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(&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 +} diff --git a/src/common/types.h b/src/common/types.h index 9a7645c93..c7fbc52e5 100644 --- a/src/common/types.h +++ b/src/common/types.h @@ -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 diff --git a/src/common/vulkan/shader_cache.cpp b/src/common/vulkan/shader_cache.cpp index e7f1a8c1b..786f03000 100644 --- a/src/common/vulkan/shader_cache.cpp +++ b/src/common/vulkan/shader_cache.cpp @@ -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"; diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 85804eef5..f6239e687 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -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() diff --git a/src/core/achievements.h b/src/core/achievements.h new file mode 100644 index 000000000..51d575019 --- /dev/null +++ b/src/core/achievements.h @@ -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 diff --git a/src/core/analog_controller.cpp b/src/core/analog_controller.cpp index ab5455c4a..b2b213290 100644 --- a/src/core/analog_controller.cpp +++ b/src/core/analog_controller.cpp @@ -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 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 AnalogController::GetAxisCodeByName(std::string_view axis_name) const +float AnalogController::GetBindState(u32 index) const { - return StaticGetAxisCodeByName(axis_name); -} + if (index >= static_cast(Button::Count)) + { + const u32 sub_index = index - static_cast(Button::Count); + if (sub_index >= static_cast(m_half_axis_state.size())) + return 0.0f; -std::optional 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(Axis::Count)) + return static_cast(m_half_axis_state[sub_index]) * (1.0f / 255.0f); + } + else if (index < static_cast(Button::Analog)) + { + return static_cast(((m_button_state >> index) & 1u) ^ 1u); + } + else + { return 0.0f; - - // 0..255 -> -1..1 - const float value = (((static_cast(m_axis_state[static_cast(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(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(std::clamp(std::round(((scaled_value + 1.0f) / 2.0f) * 255.0f), 0.0f, 255.0f)); - - SetAxisState(static_cast(axis_code), u8_value); -} - -void AnalogController::SetAxisState(Axis axis, u8 value) -{ - if (value != m_axis_state[static_cast(axis)]) - System::SetRunaheadReplayFlag(); - - m_axis_state[static_cast(axis)] = value; -} - -bool AnalogController::GetButtonState(s32 button_code) const -{ - if (button_code < 0 || button_code >= static_cast(Button::Analog)) - return false; - - const u16 bit = u16(1) << static_cast(button_code); - return ((m_button_state & bit) == 0); -} - -void AnalogController::SetButtonState(Button button, bool pressed) -{ - if (button == Button::Analog) + if (index == static_cast(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(Button::Count)) + { + const u32 sub_index = index - static_cast(Button::Count); + if (sub_index >= static_cast(m_half_axis_state.size())) + return; - const u16 bit = u16(1) << static_cast(button); + value = ApplyAnalogDeadzoneSensitivity(m_analog_deadzone, m_analog_sensitivity, value); + const u8 u8_value = static_cast(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(pos)] != 0) ? (127u + ((m_half_axis_state[static_cast(pos)] + 1u) / 2u)) : \ + (127u - (m_half_axis_state[static_cast(neg)] / 2u))) + + switch (static_cast(sub_index)) + { + case HalfAxis::LLeft: + case HalfAxis::LRight: + m_axis_state[static_cast(Axis::LeftX)] = MERGE(HalfAxis::LRight, HalfAxis::LLeft); + break; + + case HalfAxis::LDown: + case HalfAxis::LUp: + m_axis_state[static_cast(Axis::LeftY)] = MERGE(HalfAxis::LDown, HalfAxis::LUp); + break; + + case HalfAxis::RLeft: + case HalfAxis::RRight: + m_axis_state[static_cast(Axis::RightX)] = MERGE(HalfAxis::RRight, HalfAxis::RLeft); + break; + + case HalfAxis::RDown: + case HalfAxis::RUp: + m_axis_state[static_cast(Axis::RightY)] = MERGE(HalfAxis::RDown, HalfAxis::RUp); + break; + + default: + break; + } + +#undef MERGE + + return; + } + + const u16 bit = u16(1) << static_cast(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(Button::Count)) - return; - - SetButtonState(static_cast