diff options
301 files changed, 11786 insertions, 5934 deletions
diff --git a/.gitmodules b/.gitmodules index a08850c1a..4f4e8690b 100644 --- a/.gitmodules +++ b/.gitmodules | |||
| @@ -7,6 +7,9 @@ | |||
| 7 | [submodule "catch"] | 7 | [submodule "catch"] |
| 8 | path = externals/catch | 8 | path = externals/catch |
| 9 | url = https://github.com/philsquared/Catch.git | 9 | url = https://github.com/philsquared/Catch.git |
| 10 | [submodule "cubeb"] | ||
| 11 | path = externals/cubeb | ||
| 12 | url = https://github.com/kinetiknz/cubeb.git | ||
| 10 | [submodule "dynarmic"] | 13 | [submodule "dynarmic"] |
| 11 | path = externals/dynarmic | 14 | path = externals/dynarmic |
| 12 | url = https://github.com/MerryMage/dynarmic.git | 15 | url = https://github.com/MerryMage/dynarmic.git |
| @@ -22,3 +25,9 @@ | |||
| 22 | [submodule "unicorn"] | 25 | [submodule "unicorn"] |
| 23 | path = externals/unicorn | 26 | path = externals/unicorn |
| 24 | url = https://github.com/yuzu-emu/unicorn | 27 | url = https://github.com/yuzu-emu/unicorn |
| 28 | [submodule "mbedtls"] | ||
| 29 | path = externals/mbedtls | ||
| 30 | url = https://github.com/DarkLordZach/mbedtls | ||
| 31 | [submodule "opus"] | ||
| 32 | path = externals/opus | ||
| 33 | url = https://github.com/ogniK5377/opus.git | ||
diff --git a/CMakeLists.txt b/CMakeLists.txt index 86d2423ed..3639b623c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt | |||
| @@ -17,6 +17,8 @@ CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" ON "EN | |||
| 17 | 17 | ||
| 18 | option(YUZU_USE_BUNDLED_UNICORN "Build/Download bundled Unicorn" ON) | 18 | option(YUZU_USE_BUNDLED_UNICORN "Build/Download bundled Unicorn" ON) |
| 19 | 19 | ||
| 20 | option(ENABLE_CUBEB "Enables the cubeb audio backend" ON) | ||
| 21 | |||
| 20 | if(NOT EXISTS ${CMAKE_SOURCE_DIR}/.git/hooks/pre-commit) | 22 | if(NOT EXISTS ${CMAKE_SOURCE_DIR}/.git/hooks/pre-commit) |
| 21 | message(STATUS "Copying pre-commit hook") | 23 | message(STATUS "Copying pre-commit hook") |
| 22 | file(COPY hooks/pre-commit | 24 | file(COPY hooks/pre-commit |
diff --git a/dist/qt_themes/qdarkstyle/LICENSE.md b/dist/qt_themes/qdarkstyle/LICENSE.md new file mode 100644 index 000000000..d8910aea5 --- /dev/null +++ b/dist/qt_themes/qdarkstyle/LICENSE.md | |||
| @@ -0,0 +1,183 @@ | |||
| 1 | # License | ||
| 2 | |||
| 3 | ## The MIT License (MIT) - Code | ||
| 4 | |||
| 5 | Copyright (c) 2013-2018 Colin Duquesnoy | ||
| 6 | |||
| 7 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| 8 | of this software and associated documentation files (the "Software"), to deal | ||
| 9 | in the Software without restriction, including without limitation the rights | ||
| 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| 11 | copies of the Software, and to permit persons to whom the Software is | ||
| 12 | furnished to do so, subject to the following conditions: | ||
| 13 | |||
| 14 | The above copyright notice and this permission notice shall be included in | ||
| 15 | all copies or substantial portions of the Software. | ||
| 16 | |||
| 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| 23 | THE SOFTWARE. | ||
| 24 | |||
| 25 | ## Creative Commons Attribution International 4.0 - Images | ||
| 26 | |||
| 27 | QDarkStyle (c) 2013-2018 Colin Duquesnoy | ||
| 28 | |||
| 29 | Creative Commons Corporation (“Creative Commons”) is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an “as-is” basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible. | ||
| 30 | |||
| 31 | ### Using Creative Commons Public Licenses | ||
| 32 | |||
| 33 | Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses. | ||
| 34 | |||
| 35 | * __Considerations for licensors:__ Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. [More considerations for licensors](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensors). | ||
| 36 | |||
| 37 | * __Considerations for the public:__ By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor’s permission is not necessary for any reason–for example, because of any applicable exception or limitation to copyright–then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. [More considerations for the public](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensees). | ||
| 38 | |||
| 39 | ## Creative Commons Attribution 4.0 International Public License | ||
| 40 | |||
| 41 | By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions. | ||
| 42 | |||
| 43 | ### Section 1 – Definitions | ||
| 44 | |||
| 45 | a. __Adapted Material__ means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image. | ||
| 46 | |||
| 47 | b. __Adapter's License__ means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License. | ||
| 48 | |||
| 49 | c. __Copyright and Similar Rights__ means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights. | ||
| 50 | |||
| 51 | d. __Effective Technological Measures__ means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements. | ||
| 52 | |||
| 53 | e. __Exceptions and Limitations__ means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material. | ||
| 54 | |||
| 55 | f. __Licensed Material__ means the artistic or literary work, database, or other material to which the Licensor applied this Public License. | ||
| 56 | |||
| 57 | g. __Licensed Rights__ means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license. | ||
| 58 | |||
| 59 | h. __Licensor__ means the individual(s) or entity(ies) granting rights under this Public License. | ||
| 60 | |||
| 61 | i. __Share__ means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them. | ||
| 62 | |||
| 63 | j. __Sui Generis Database Rights__ means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world. | ||
| 64 | |||
| 65 | k. __You__ means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning. | ||
| 66 | |||
| 67 | ### Section 2 – Scope | ||
| 68 | |||
| 69 | a. ___License grant.___ | ||
| 70 | |||
| 71 | 1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to: | ||
| 72 | |||
| 73 | A. reproduce and Share the Licensed Material, in whole or in part; and | ||
| 74 | |||
| 75 | B. produce, reproduce, and Share Adapted Material. | ||
| 76 | |||
| 77 | 2. __Exceptions and Limitations.__ For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions. | ||
| 78 | |||
| 79 | 3. __Term.__ The term of this Public License is specified in Section 6(a). | ||
| 80 | |||
| 81 | 4. __Media and formats; technical modifications allowed.__ The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material. | ||
| 82 | |||
| 83 | 5. __Downstream recipients.__ | ||
| 84 | |||
| 85 | A. __Offer from the Licensor – Licensed Material.__ Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License. | ||
| 86 | |||
| 87 | B. __No downstream restrictions.__ You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material. | ||
| 88 | |||
| 89 | 6. __No endorsement.__ Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i). | ||
| 90 | |||
| 91 | b. ___Other rights.___ | ||
| 92 | |||
| 93 | 1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise. | ||
| 94 | |||
| 95 | 2. Patent and trademark rights are not licensed under this Public License. | ||
| 96 | |||
| 97 | 3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties. | ||
| 98 | |||
| 99 | ### Section 3 – License Conditions | ||
| 100 | |||
| 101 | Your exercise of the Licensed Rights is expressly made subject to the following conditions. | ||
| 102 | |||
| 103 | a. ___Attribution.___ | ||
| 104 | |||
| 105 | 1. If You Share the Licensed Material (including in modified form), You must: | ||
| 106 | |||
| 107 | A. retain the following if it is supplied by the Licensor with the Licensed Material: | ||
| 108 | |||
| 109 | i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated); | ||
| 110 | |||
| 111 | ii. a copyright notice; | ||
| 112 | |||
| 113 | iii. a notice that refers to this Public License; | ||
| 114 | |||
| 115 | iv. a notice that refers to the disclaimer of warranties; | ||
| 116 | |||
| 117 | v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable; | ||
| 118 | |||
| 119 | B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and | ||
| 120 | |||
| 121 | C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License. | ||
| 122 | |||
| 123 | 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information. | ||
| 124 | |||
| 125 | 3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable. | ||
| 126 | |||
| 127 | 4. If You Share Adapted Material You produce, the Adapter's License You apply must not prevent recipients of the Adapted Material from complying with this Public License. | ||
| 128 | |||
| 129 | ### Section 4 – Sui Generis Database Rights | ||
| 130 | |||
| 131 | Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material: | ||
| 132 | |||
| 133 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database; | ||
| 134 | |||
| 135 | b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material; and | ||
| 136 | |||
| 137 | c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database. | ||
| 138 | |||
| 139 | For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights. | ||
| 140 | |||
| 141 | ### Section 5 – Disclaimer of Warranties and Limitation of Liability | ||
| 142 | |||
| 143 | a. __Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.__ | ||
| 144 | |||
| 145 | b. __To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.__ | ||
| 146 | |||
| 147 | c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability. | ||
| 148 | |||
| 149 | ### Section 6 – Term and Termination | ||
| 150 | |||
| 151 | a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically. | ||
| 152 | |||
| 153 | b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates: | ||
| 154 | |||
| 155 | 1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or | ||
| 156 | |||
| 157 | 2. upon express reinstatement by the Licensor. | ||
| 158 | |||
| 159 | For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License. | ||
| 160 | |||
| 161 | c. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License. | ||
| 162 | |||
| 163 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License. | ||
| 164 | |||
| 165 | ### Section 7 – Other Terms and Conditions | ||
| 166 | |||
| 167 | a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed. | ||
| 168 | |||
| 169 | b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License. | ||
| 170 | |||
| 171 | ### Section 8 – Interpretation | ||
| 172 | |||
| 173 | a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License. | ||
| 174 | |||
| 175 | b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions. | ||
| 176 | |||
| 177 | c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor. | ||
| 178 | |||
| 179 | d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority. | ||
| 180 | |||
| 181 | > Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at [creativecommons.org/policies](http://creativecommons.org/policies), Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses. | ||
| 182 | > | ||
| 183 | > Creative Commons may be contacted at creativecommons.org \ No newline at end of file | ||
diff --git a/dist/qt_themes/qdarkstyle/style.qss b/dist/qt_themes/qdarkstyle/style.qss index c8e50312a..399c38dce 100644 --- a/dist/qt_themes/qdarkstyle/style.qss +++ b/dist/qt_themes/qdarkstyle/style.qss | |||
| @@ -1,40 +1,15 @@ | |||
| 1 | /* | 1 | QToolTip { |
| 2 | * The MIT License (MIT) | ||
| 3 | * | ||
| 4 | * Copyright (c) <2013-2014> <Colin Duquesnoy> | ||
| 5 | * | ||
| 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| 7 | * of this software and associated documentation files (the "Software"), to deal | ||
| 8 | * in the Software without restriction, including without limitation the rights | ||
| 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| 10 | * copies of the Software, and to permit persons to whom the Software is | ||
| 11 | * furnished to do so, subject to the following conditions: | ||
| 12 | |||
| 13 | * The above copyright notice and this permission notice shall be included in | ||
| 14 | * all copies or substantial portions of the Software. | ||
| 15 | |||
| 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| 22 | * THE SOFTWARE. | ||
| 23 | */ | ||
| 24 | QToolTip | ||
| 25 | { | ||
| 26 | border: 1px solid #76797C; | 2 | border: 1px solid #76797C; |
| 27 | background-color: rgb(90, 102, 117);; | 3 | background-color: #5A7566; |
| 28 | color: white; | 4 | color: white; |
| 29 | padding: 5px; | 5 | padding: 0px; /*remove padding, for fix combobox tooltip.*/ |
| 30 | opacity: 200; | 6 | opacity: 200; |
| 31 | } | 7 | } |
| 32 | 8 | ||
| 33 | QWidget | 9 | QWidget { |
| 34 | { | ||
| 35 | color: #eff0f1; | 10 | color: #eff0f1; |
| 36 | background-color: #31363b; | 11 | background-color: #31363b; |
| 37 | selection-background-color:#3daee9; | 12 | selection-background-color: #3daee9; |
| 38 | selection-color: #eff0f1; | 13 | selection-color: #eff0f1; |
| 39 | background-clip: border; | 14 | background-clip: border; |
| 40 | border-image: none; | 15 | border-image: none; |
| @@ -42,43 +17,38 @@ QWidget | |||
| 42 | outline: 0; | 17 | outline: 0; |
| 43 | } | 18 | } |
| 44 | 19 | ||
| 45 | QWidget:item:hover | 20 | QWidget:item:hover { |
| 46 | { | ||
| 47 | background-color: #18465d; | 21 | background-color: #18465d; |
| 48 | color: #eff0f1; | 22 | color: #eff0f1; |
| 49 | } | 23 | } |
| 50 | 24 | ||
| 51 | QWidget:item:selected | 25 | QWidget:item:selected { |
| 52 | { | ||
| 53 | background-color: #18465d; | 26 | background-color: #18465d; |
| 54 | } | 27 | } |
| 55 | 28 | ||
| 56 | QCheckBox | 29 | QCheckBox { |
| 57 | { | ||
| 58 | spacing: 5px; | 30 | spacing: 5px; |
| 59 | outline: none; | 31 | outline: none; |
| 60 | color: #eff0f1; | 32 | color: #eff0f1; |
| 61 | margin-bottom: 2px; | 33 | margin-bottom: 2px; |
| 62 | } | 34 | } |
| 63 | 35 | ||
| 64 | QCheckBox:disabled | 36 | QCheckBox:disabled { |
| 65 | { | ||
| 66 | color: #76797C; | 37 | color: #76797C; |
| 67 | } | 38 | } |
| 68 | 39 | ||
| 69 | QCheckBox::indicator, | 40 | QCheckBox::indicator, |
| 70 | QGroupBox::indicator | 41 | QGroupBox::indicator { |
| 71 | { | ||
| 72 | width: 18px; | 42 | width: 18px; |
| 73 | height: 18px; | 43 | height: 18px; |
| 74 | } | 44 | } |
| 75 | QGroupBox::indicator | 45 | |
| 76 | { | 46 | QGroupBox::indicator { |
| 77 | margin-left: 2px; | 47 | margin-left: 2px; |
| 78 | } | 48 | } |
| 79 | 49 | ||
| 80 | QCheckBox::indicator:unchecked | 50 | QCheckBox::indicator:unchecked, |
| 81 | { | 51 | QGroupBox::indicator:unchecked { |
| 82 | image: url(:/qss_icons/rc/checkbox_unchecked.png); | 52 | image: url(:/qss_icons/rc/checkbox_unchecked.png); |
| 83 | } | 53 | } |
| 84 | 54 | ||
| @@ -87,14 +57,13 @@ QCheckBox::indicator:unchecked:focus, | |||
| 87 | QCheckBox::indicator:unchecked:pressed, | 57 | QCheckBox::indicator:unchecked:pressed, |
| 88 | QGroupBox::indicator:unchecked:hover, | 58 | QGroupBox::indicator:unchecked:hover, |
| 89 | QGroupBox::indicator:unchecked:focus, | 59 | QGroupBox::indicator:unchecked:focus, |
| 90 | QGroupBox::indicator:unchecked:pressed | 60 | QGroupBox::indicator:unchecked:pressed { |
| 91 | { | 61 | border: none; |
| 92 | border: none; | ||
| 93 | image: url(:/qss_icons/rc/checkbox_unchecked_focus.png); | 62 | image: url(:/qss_icons/rc/checkbox_unchecked_focus.png); |
| 94 | } | 63 | } |
| 95 | 64 | ||
| 96 | QCheckBox::indicator:checked | 65 | QCheckBox::indicator:checked, |
| 97 | { | 66 | QGroupBox::indicator:checked { |
| 98 | image: url(:/qss_icons/rc/checkbox_checked.png); | 67 | image: url(:/qss_icons/rc/checkbox_checked.png); |
| 99 | } | 68 | } |
| 100 | 69 | ||
| @@ -103,72 +72,60 @@ QCheckBox::indicator:checked:focus, | |||
| 103 | QCheckBox::indicator:checked:pressed, | 72 | QCheckBox::indicator:checked:pressed, |
| 104 | QGroupBox::indicator:checked:hover, | 73 | QGroupBox::indicator:checked:hover, |
| 105 | QGroupBox::indicator:checked:focus, | 74 | QGroupBox::indicator:checked:focus, |
| 106 | QGroupBox::indicator:checked:pressed | 75 | QGroupBox::indicator:checked:pressed { |
| 107 | { | 76 | border: none; |
| 108 | border: none; | ||
| 109 | image: url(:/qss_icons/rc/checkbox_checked_focus.png); | 77 | image: url(:/qss_icons/rc/checkbox_checked_focus.png); |
| 110 | } | 78 | } |
| 111 | 79 | ||
| 112 | 80 | QCheckBox::indicator:indeterminate { | |
| 113 | QCheckBox::indicator:indeterminate | ||
| 114 | { | ||
| 115 | image: url(:/qss_icons/rc/checkbox_indeterminate.png); | 81 | image: url(:/qss_icons/rc/checkbox_indeterminate.png); |
| 116 | } | 82 | } |
| 117 | 83 | ||
| 118 | QCheckBox::indicator:indeterminate:focus, | 84 | QCheckBox::indicator:indeterminate:focus, |
| 119 | QCheckBox::indicator:indeterminate:hover, | 85 | QCheckBox::indicator:indeterminate:hover, |
| 120 | QCheckBox::indicator:indeterminate:pressed | 86 | QCheckBox::indicator:indeterminate:pressed { |
| 121 | { | ||
| 122 | image: url(:/qss_icons/rc/checkbox_indeterminate_focus.png); | 87 | image: url(:/qss_icons/rc/checkbox_indeterminate_focus.png); |
| 123 | } | 88 | } |
| 124 | 89 | ||
| 125 | QCheckBox::indicator:checked:disabled, | 90 | QCheckBox::indicator:checked:disabled, |
| 126 | QGroupBox::indicator:checked:disabled | 91 | QGroupBox::indicator:checked:disabled { |
| 127 | { | ||
| 128 | image: url(:/qss_icons/rc/checkbox_checked_disabled.png); | 92 | image: url(:/qss_icons/rc/checkbox_checked_disabled.png); |
| 129 | } | 93 | } |
| 130 | 94 | ||
| 131 | QCheckBox::indicator:unchecked:disabled, | 95 | QCheckBox::indicator:unchecked:disabled, |
| 132 | QGroupBox::indicator:unchecked:disabled | 96 | QGroupBox::indicator:unchecked:disabled { |
| 133 | { | ||
| 134 | image: url(:/qss_icons/rc/checkbox_unchecked_disabled.png); | 97 | image: url(:/qss_icons/rc/checkbox_unchecked_disabled.png); |
| 135 | } | 98 | } |
| 136 | 99 | ||
| 137 | QRadioButton | 100 | QRadioButton { |
| 138 | { | ||
| 139 | spacing: 5px; | 101 | spacing: 5px; |
| 140 | outline: none; | 102 | outline: none; |
| 141 | color: #eff0f1; | 103 | color: #eff0f1; |
| 142 | margin-bottom: 2px; | 104 | margin-bottom: 2px; |
| 143 | } | 105 | } |
| 144 | 106 | ||
| 145 | QRadioButton:disabled | 107 | QRadioButton:disabled { |
| 146 | { | ||
| 147 | color: #76797C; | 108 | color: #76797C; |
| 148 | } | 109 | } |
| 149 | QRadioButton::indicator | 110 | |
| 150 | { | 111 | QRadioButton::indicator { |
| 151 | width: 21px; | 112 | width: 21px; |
| 152 | height: 21px; | 113 | height: 21px; |
| 153 | } | 114 | } |
| 154 | 115 | ||
| 155 | QRadioButton::indicator:unchecked | 116 | QRadioButton::indicator:unchecked { |
| 156 | { | ||
| 157 | image: url(:/qss_icons/rc/radio_unchecked.png); | 117 | image: url(:/qss_icons/rc/radio_unchecked.png); |
| 158 | } | 118 | } |
| 159 | 119 | ||
| 160 | |||
| 161 | QRadioButton::indicator:unchecked:hover, | 120 | QRadioButton::indicator:unchecked:hover, |
| 162 | QRadioButton::indicator:unchecked:focus, | 121 | QRadioButton::indicator:unchecked:focus, |
| 163 | QRadioButton::indicator:unchecked:pressed | 122 | QRadioButton::indicator:unchecked:pressed { |
| 164 | { | ||
| 165 | border: none; | 123 | border: none; |
| 166 | outline: none; | 124 | outline: none; |
| 167 | image: url(:/qss_icons/rc/radio_unchecked_focus.png); | 125 | image: url(:/qss_icons/rc/radio_unchecked_focus.png); |
| 168 | } | 126 | } |
| 169 | 127 | ||
| 170 | QRadioButton::indicator:checked | 128 | QRadioButton::indicator:checked { |
| 171 | { | ||
| 172 | border: none; | 129 | border: none; |
| 173 | outline: none; | 130 | outline: none; |
| 174 | image: url(:/qss_icons/rc/radio_checked.png); | 131 | image: url(:/qss_icons/rc/radio_checked.png); |
| @@ -176,72 +133,60 @@ QRadioButton::indicator:checked | |||
| 176 | 133 | ||
| 177 | QRadioButton::indicator:checked:hover, | 134 | QRadioButton::indicator:checked:hover, |
| 178 | QRadioButton::indicator:checked:focus, | 135 | QRadioButton::indicator:checked:focus, |
| 179 | QRadioButton::indicator:checked:pressed | 136 | QRadioButton::indicator:checked:pressed { |
| 180 | { | ||
| 181 | border: none; | 137 | border: none; |
| 182 | outline: none; | 138 | outline: none; |
| 183 | image: url(:/qss_icons/rc/radio_checked_focus.png); | 139 | image: url(:/qss_icons/rc/radio_checked_focus.png); |
| 184 | } | 140 | } |
| 185 | 141 | ||
| 186 | QRadioButton::indicator:checked:disabled | 142 | QRadioButton::indicator:checked:disabled { |
| 187 | { | ||
| 188 | outline: none; | 143 | outline: none; |
| 189 | image: url(:/qss_icons/rc/radio_checked_disabled.png); | 144 | image: url(:/qss_icons/rc/radio_checked_disabled.png); |
| 190 | } | 145 | } |
| 191 | 146 | ||
| 192 | QRadioButton::indicator:unchecked:disabled | 147 | QRadioButton::indicator:unchecked:disabled { |
| 193 | { | ||
| 194 | image: url(:/qss_icons/rc/radio_unchecked_disabled.png); | 148 | image: url(:/qss_icons/rc/radio_unchecked_disabled.png); |
| 195 | } | 149 | } |
| 196 | 150 | ||
| 197 | 151 | QMenuBar { | |
| 198 | QMenuBar | ||
| 199 | { | ||
| 200 | background-color: #31363b; | 152 | background-color: #31363b; |
| 201 | color: #eff0f1; | 153 | color: #eff0f1; |
| 202 | } | 154 | } |
| 203 | 155 | ||
| 204 | QMenuBar::item | 156 | QMenuBar::item { |
| 205 | { | ||
| 206 | background: transparent; | 157 | background: transparent; |
| 207 | } | 158 | } |
| 208 | 159 | ||
| 209 | QMenuBar::item:selected | 160 | QMenuBar::item:selected { |
| 210 | { | ||
| 211 | background: transparent; | 161 | background: transparent; |
| 212 | border: 1px solid #76797C; | 162 | border: 1px solid #76797C; |
| 213 | } | 163 | } |
| 214 | 164 | ||
| 215 | QMenuBar::item:pressed | 165 | QMenuBar::item:pressed { |
| 216 | { | ||
| 217 | border: 1px solid #76797C; | 166 | border: 1px solid #76797C; |
| 218 | background-color: #3daee9; | 167 | background-color: #3daee9; |
| 219 | color: #eff0f1; | 168 | color: #eff0f1; |
| 220 | margin-bottom:-1px; | 169 | margin-bottom: -1px; |
| 221 | padding-bottom:1px; | 170 | padding-bottom: 1px; |
| 222 | } | 171 | } |
| 223 | 172 | ||
| 224 | QMenu | 173 | QMenu { |
| 225 | { | ||
| 226 | border: 1px solid #76797C; | 174 | border: 1px solid #76797C; |
| 227 | color: #eff0f1; | 175 | color: #eff0f1; |
| 228 | margin: 2px; | 176 | margin: 2px; |
| 229 | } | 177 | } |
| 230 | 178 | ||
| 231 | QMenu::icon | 179 | QMenu::icon { |
| 232 | { | ||
| 233 | margin: 5px; | 180 | margin: 5px; |
| 234 | } | 181 | } |
| 235 | 182 | ||
| 236 | QMenu::item | 183 | QMenu::item { |
| 237 | { | ||
| 238 | padding: 5px 30px 5px 30px; | 184 | padding: 5px 30px 5px 30px; |
| 239 | margin-left: 5px; | 185 | border: 1px solid transparent; |
| 240 | border: 1px solid transparent; /* reserve space for selection border */ | 186 | /* reserve space for selection border */ |
| 241 | } | 187 | } |
| 242 | 188 | ||
| 243 | QMenu::item:selected | 189 | QMenu::item:selected { |
| 244 | { | ||
| 245 | color: #eff0f1; | 190 | color: #eff0f1; |
| 246 | } | 191 | } |
| 247 | 192 | ||
| @@ -257,8 +202,10 @@ QMenu::indicator { | |||
| 257 | height: 18px; | 202 | height: 18px; |
| 258 | } | 203 | } |
| 259 | 204 | ||
| 205 | |||
| 260 | /* non-exclusive indicator = check box style indicator | 206 | /* non-exclusive indicator = check box style indicator |
| 261 | (see QActionGroup::setExclusive) */ | 207 | (see QActionGroup::setExclusive) */ |
| 208 | |||
| 262 | QMenu::indicator:non-exclusive:unchecked { | 209 | QMenu::indicator:non-exclusive:unchecked { |
| 263 | image: url(:/qss_icons/rc/checkbox_unchecked.png); | 210 | image: url(:/qss_icons/rc/checkbox_unchecked.png); |
| 264 | } | 211 | } |
| @@ -275,7 +222,9 @@ QMenu::indicator:non-exclusive:checked:selected { | |||
| 275 | image: url(:/qss_icons/rc/checkbox_checked_disabled.png); | 222 | image: url(:/qss_icons/rc/checkbox_checked_disabled.png); |
| 276 | } | 223 | } |
| 277 | 224 | ||
| 225 | |||
| 278 | /* exclusive indicator = radio button style indicator (see QActionGroup::setExclusive) */ | 226 | /* exclusive indicator = radio button style indicator (see QActionGroup::setExclusive) */ |
| 227 | |||
| 279 | QMenu::indicator:exclusive:unchecked { | 228 | QMenu::indicator:exclusive:unchecked { |
| 280 | image: url(:/qss_icons/rc/radio_unchecked.png); | 229 | image: url(:/qss_icons/rc/radio_unchecked.png); |
| 281 | } | 230 | } |
| @@ -297,33 +246,31 @@ QMenu::right-arrow { | |||
| 297 | image: url(:/qss_icons/rc/right_arrow.png) | 246 | image: url(:/qss_icons/rc/right_arrow.png) |
| 298 | } | 247 | } |
| 299 | 248 | ||
| 300 | 249 | QWidget:disabled { | |
| 301 | QWidget:disabled | ||
| 302 | { | ||
| 303 | color: #454545; | 250 | color: #454545; |
| 304 | background-color: #31363b; | 251 | background-color: #31363b; |
| 305 | } | 252 | } |
| 306 | 253 | ||
| 307 | QAbstractItemView | 254 | QAbstractItemView { |
| 308 | { | ||
| 309 | alternate-background-color: #31363b; | 255 | alternate-background-color: #31363b; |
| 310 | color: #eff0f1; | 256 | color: #eff0f1; |
| 311 | border: 1px solid 3A3939; | 257 | border: 1px solid #3A3939; |
| 312 | border-radius: 2px; | 258 | border-radius: 2px; |
| 313 | } | 259 | } |
| 314 | 260 | ||
| 315 | QWidget:focus, QMenuBar:focus | 261 | QWidget:focus, |
| 316 | { | 262 | QMenuBar:focus { |
| 317 | border: 1px solid #3daee9; | 263 | border: 1px solid #3daee9; |
| 318 | } | 264 | } |
| 319 | 265 | ||
| 320 | QTabWidget:focus, QCheckBox:focus, QRadioButton:focus, QSlider:focus | 266 | QTabWidget:focus, |
| 321 | { | 267 | QCheckBox:focus, |
| 268 | QRadioButton:focus, | ||
| 269 | QSlider:focus { | ||
| 322 | border: none; | 270 | border: none; |
| 323 | } | 271 | } |
| 324 | 272 | ||
| 325 | QLineEdit | 273 | QLineEdit { |
| 326 | { | ||
| 327 | background-color: #232629; | 274 | background-color: #232629; |
| 328 | padding: 5px; | 275 | padding: 5px; |
| 329 | border-style: solid; | 276 | border-style: solid; |
| @@ -332,13 +279,12 @@ QLineEdit | |||
| 332 | color: #eff0f1; | 279 | color: #eff0f1; |
| 333 | } | 280 | } |
| 334 | 281 | ||
| 335 | QAbstractItemView QLineEdit | 282 | QAbstractItemView QLineEdit { |
| 336 | { | ||
| 337 | padding: 0; | 283 | padding: 0; |
| 338 | } | 284 | } |
| 339 | 285 | ||
| 340 | QGroupBox { | 286 | QGroupBox { |
| 341 | border:1px solid #76797C; | 287 | border: 1px solid #76797C; |
| 342 | border-radius: 2px; | 288 | border-radius: 2px; |
| 343 | margin-top: 20px; | 289 | margin-top: 20px; |
| 344 | } | 290 | } |
| @@ -351,15 +297,13 @@ QGroupBox::title { | |||
| 351 | padding-top: 10px; | 297 | padding-top: 10px; |
| 352 | } | 298 | } |
| 353 | 299 | ||
| 354 | QAbstractScrollArea | 300 | QAbstractScrollArea { |
| 355 | { | ||
| 356 | border-radius: 2px; | 301 | border-radius: 2px; |
| 357 | border: 1px solid #76797C; | 302 | border: 1px solid #76797C; |
| 358 | background-color: transparent; | 303 | background-color: transparent; |
| 359 | } | 304 | } |
| 360 | 305 | ||
| 361 | QScrollBar:horizontal | 306 | QScrollBar:horizontal { |
| 362 | { | ||
| 363 | height: 15px; | 307 | height: 15px; |
| 364 | margin: 3px 15px 3px 15px; | 308 | margin: 3px 15px 3px 15px; |
| 365 | border: 1px transparent #2A2929; | 309 | border: 1px transparent #2A2929; |
| @@ -367,15 +311,13 @@ QScrollBar:horizontal | |||
| 367 | background-color: #2A2929; | 311 | background-color: #2A2929; |
| 368 | } | 312 | } |
| 369 | 313 | ||
| 370 | QScrollBar::handle:horizontal | 314 | QScrollBar::handle:horizontal { |
| 371 | { | ||
| 372 | background-color: #605F5F; | 315 | background-color: #605F5F; |
| 373 | min-width: 5px; | 316 | min-width: 5px; |
| 374 | border-radius: 4px; | 317 | border-radius: 4px; |
| 375 | } | 318 | } |
| 376 | 319 | ||
| 377 | QScrollBar::add-line:horizontal | 320 | QScrollBar::add-line:horizontal { |
| 378 | { | ||
| 379 | margin: 0px 3px 0px 3px; | 321 | margin: 0px 3px 0px 3px; |
| 380 | border-image: url(:/qss_icons/rc/right_arrow_disabled.png); | 322 | border-image: url(:/qss_icons/rc/right_arrow_disabled.png); |
| 381 | width: 10px; | 323 | width: 10px; |
| @@ -384,8 +326,7 @@ QScrollBar::add-line:horizontal | |||
| 384 | subcontrol-origin: margin; | 326 | subcontrol-origin: margin; |
| 385 | } | 327 | } |
| 386 | 328 | ||
| 387 | QScrollBar::sub-line:horizontal | 329 | QScrollBar::sub-line:horizontal { |
| 388 | { | ||
| 389 | margin: 0px 3px 0px 3px; | 330 | margin: 0px 3px 0px 3px; |
| 390 | border-image: url(:/qss_icons/rc/left_arrow_disabled.png); | 331 | border-image: url(:/qss_icons/rc/left_arrow_disabled.png); |
| 391 | height: 10px; | 332 | height: 10px; |
| @@ -394,8 +335,8 @@ QScrollBar::sub-line:horizontal | |||
| 394 | subcontrol-origin: margin; | 335 | subcontrol-origin: margin; |
| 395 | } | 336 | } |
| 396 | 337 | ||
| 397 | QScrollBar::add-line:horizontal:hover,QScrollBar::add-line:horizontal:on | 338 | QScrollBar::add-line:horizontal:hover, |
| 398 | { | 339 | QScrollBar::add-line:horizontal:on { |
| 399 | border-image: url(:/qss_icons/rc/right_arrow.png); | 340 | border-image: url(:/qss_icons/rc/right_arrow.png); |
| 400 | height: 10px; | 341 | height: 10px; |
| 401 | width: 10px; | 342 | width: 10px; |
| @@ -403,9 +344,8 @@ QScrollBar::add-line:horizontal:hover,QScrollBar::add-line:horizontal:on | |||
| 403 | subcontrol-origin: margin; | 344 | subcontrol-origin: margin; |
| 404 | } | 345 | } |
| 405 | 346 | ||
| 406 | 347 | QScrollBar::sub-line:horizontal:hover, | |
| 407 | QScrollBar::sub-line:horizontal:hover, QScrollBar::sub-line:horizontal:on | 348 | QScrollBar::sub-line:horizontal:on { |
| 408 | { | ||
| 409 | border-image: url(:/qss_icons/rc/left_arrow.png); | 349 | border-image: url(:/qss_icons/rc/left_arrow.png); |
| 410 | height: 10px; | 350 | height: 10px; |
| 411 | width: 10px; | 351 | width: 10px; |
| @@ -413,19 +353,17 @@ QScrollBar::sub-line:horizontal:hover, QScrollBar::sub-line:horizontal:on | |||
| 413 | subcontrol-origin: margin; | 353 | subcontrol-origin: margin; |
| 414 | } | 354 | } |
| 415 | 355 | ||
| 416 | QScrollBar::up-arrow:horizontal, QScrollBar::down-arrow:horizontal | 356 | QScrollBar::up-arrow:horizontal, |
| 417 | { | 357 | QScrollBar::down-arrow:horizontal { |
| 418 | background: none; | 358 | background: none; |
| 419 | } | 359 | } |
| 420 | 360 | ||
| 421 | 361 | QScrollBar::add-page:horizontal, | |
| 422 | QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal | 362 | QScrollBar::sub-page:horizontal { |
| 423 | { | ||
| 424 | background: none; | 363 | background: none; |
| 425 | } | 364 | } |
| 426 | 365 | ||
| 427 | QScrollBar:vertical | 366 | QScrollBar:vertical { |
| 428 | { | ||
| 429 | background-color: #2A2929; | 367 | background-color: #2A2929; |
| 430 | width: 15px; | 368 | width: 15px; |
| 431 | margin: 15px 3px 15px 3px; | 369 | margin: 15px 3px 15px 3px; |
| @@ -433,15 +371,13 @@ QScrollBar:vertical | |||
| 433 | border-radius: 4px; | 371 | border-radius: 4px; |
| 434 | } | 372 | } |
| 435 | 373 | ||
| 436 | QScrollBar::handle:vertical | 374 | QScrollBar::handle:vertical { |
| 437 | { | ||
| 438 | background-color: #605F5F; | 375 | background-color: #605F5F; |
| 439 | min-height: 5px; | 376 | min-height: 5px; |
| 440 | border-radius: 4px; | 377 | border-radius: 4px; |
| 441 | } | 378 | } |
| 442 | 379 | ||
| 443 | QScrollBar::sub-line:vertical | 380 | QScrollBar::sub-line:vertical { |
| 444 | { | ||
| 445 | margin: 3px 0px 3px 0px; | 381 | margin: 3px 0px 3px 0px; |
| 446 | border-image: url(:/qss_icons/rc/up_arrow_disabled.png); | 382 | border-image: url(:/qss_icons/rc/up_arrow_disabled.png); |
| 447 | height: 10px; | 383 | height: 10px; |
| @@ -450,8 +386,7 @@ QScrollBar::sub-line:vertical | |||
| 450 | subcontrol-origin: margin; | 386 | subcontrol-origin: margin; |
| 451 | } | 387 | } |
| 452 | 388 | ||
| 453 | QScrollBar::add-line:vertical | 389 | QScrollBar::add-line:vertical { |
| 454 | { | ||
| 455 | margin: 3px 0px 3px 0px; | 390 | margin: 3px 0px 3px 0px; |
| 456 | border-image: url(:/qss_icons/rc/down_arrow_disabled.png); | 391 | border-image: url(:/qss_icons/rc/down_arrow_disabled.png); |
| 457 | height: 10px; | 392 | height: 10px; |
| @@ -460,9 +395,8 @@ QScrollBar::add-line:vertical | |||
| 460 | subcontrol-origin: margin; | 395 | subcontrol-origin: margin; |
| 461 | } | 396 | } |
| 462 | 397 | ||
| 463 | QScrollBar::sub-line:vertical:hover,QScrollBar::sub-line:vertical:on | 398 | QScrollBar::sub-line:vertical:hover, |
| 464 | { | 399 | QScrollBar::sub-line:vertical:on { |
| 465 | |||
| 466 | border-image: url(:/qss_icons/rc/up_arrow.png); | 400 | border-image: url(:/qss_icons/rc/up_arrow.png); |
| 467 | height: 10px; | 401 | height: 10px; |
| 468 | width: 10px; | 402 | width: 10px; |
| @@ -470,9 +404,8 @@ QScrollBar::sub-line:vertical:hover,QScrollBar::sub-line:vertical:on | |||
| 470 | subcontrol-origin: margin; | 404 | subcontrol-origin: margin; |
| 471 | } | 405 | } |
| 472 | 406 | ||
| 473 | 407 | QScrollBar::add-line:vertical:hover, | |
| 474 | QScrollBar::add-line:vertical:hover, QScrollBar::add-line:vertical:on | 408 | QScrollBar::add-line:vertical:on { |
| 475 | { | ||
| 476 | border-image: url(:/qss_icons/rc/down_arrow.png); | 409 | border-image: url(:/qss_icons/rc/down_arrow.png); |
| 477 | height: 10px; | 410 | height: 10px; |
| 478 | width: 10px; | 411 | width: 10px; |
| @@ -480,34 +413,31 @@ QScrollBar::add-line:vertical:hover, QScrollBar::add-line:vertical:on | |||
| 480 | subcontrol-origin: margin; | 413 | subcontrol-origin: margin; |
| 481 | } | 414 | } |
| 482 | 415 | ||
| 483 | QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical | 416 | QScrollBar::up-arrow:vertical, |
| 484 | { | 417 | QScrollBar::down-arrow:vertical { |
| 485 | background: none; | 418 | background: none; |
| 486 | } | 419 | } |
| 487 | 420 | ||
| 488 | 421 | QScrollBar::add-page:vertical, | |
| 489 | QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical | 422 | QScrollBar::sub-page:vertical { |
| 490 | { | ||
| 491 | background: none; | 423 | background: none; |
| 492 | } | 424 | } |
| 493 | 425 | ||
| 494 | QTextEdit | 426 | QTextEdit { |
| 495 | { | ||
| 496 | background-color: #232629; | 427 | background-color: #232629; |
| 497 | color: #eff0f1; | 428 | color: #eff0f1; |
| 498 | border: 1px solid #76797C; | 429 | border: 1px solid #76797C; |
| 499 | } | 430 | } |
| 500 | 431 | ||
| 501 | QPlainTextEdit | 432 | QPlainTextEdit { |
| 502 | { | 433 | background-color: #232629; |
| 503 | background-color: #232629;; | 434 | ; |
| 504 | color: #eff0f1; | 435 | color: #eff0f1; |
| 505 | border-radius: 2px; | 436 | border-radius: 2px; |
| 506 | border: 1px solid #76797C; | 437 | border: 1px solid #76797C; |
| 507 | } | 438 | } |
| 508 | 439 | ||
| 509 | QHeaderView::section | 440 | QHeaderView::section { |
| 510 | { | ||
| 511 | background-color: #76797C; | 441 | background-color: #76797C; |
| 512 | color: #eff0f1; | 442 | color: #eff0f1; |
| 513 | padding: 5px; | 443 | padding: 5px; |
| @@ -520,9 +450,7 @@ QSizeGrip { | |||
| 520 | height: 12px; | 450 | height: 12px; |
| 521 | } | 451 | } |
| 522 | 452 | ||
| 523 | 453 | QMainWindow::separator { | |
| 524 | QMainWindow::separator | ||
| 525 | { | ||
| 526 | background-color: #31363b; | 454 | background-color: #31363b; |
| 527 | color: white; | 455 | color: white; |
| 528 | padding-left: 4px; | 456 | padding-left: 4px; |
| @@ -530,9 +458,7 @@ QMainWindow::separator | |||
| 530 | border: 1px dashed #76797C; | 458 | border: 1px dashed #76797C; |
| 531 | } | 459 | } |
| 532 | 460 | ||
| 533 | QMainWindow::separator:hover | 461 | QMainWindow::separator:hover { |
| 534 | { | ||
| 535 | |||
| 536 | background-color: #787876; | 462 | background-color: #787876; |
| 537 | color: white; | 463 | color: white; |
| 538 | padding-left: 4px; | 464 | padding-left: 4px; |
| @@ -540,9 +466,7 @@ QMainWindow::separator:hover | |||
| 540 | spacing: 2px; | 466 | spacing: 2px; |
| 541 | } | 467 | } |
| 542 | 468 | ||
| 543 | 469 | QMenu::separator { | |
| 544 | QMenu::separator | ||
| 545 | { | ||
| 546 | height: 1px; | 470 | height: 1px; |
| 547 | background-color: #76797C; | 471 | background-color: #76797C; |
| 548 | color: white; | 472 | color: white; |
| @@ -551,21 +475,17 @@ QMenu::separator | |||
| 551 | margin-right: 5px; | 475 | margin-right: 5px; |
| 552 | } | 476 | } |
| 553 | 477 | ||
| 554 | 478 | QFrame { | |
| 555 | QFrame | ||
| 556 | { | ||
| 557 | border-radius: 2px; | 479 | border-radius: 2px; |
| 558 | border: 1px solid #76797C; | 480 | border: 1px solid #76797C; |
| 559 | } | 481 | } |
| 560 | 482 | ||
| 561 | QFrame[frameShape="0"] | 483 | QFrame[frameShape="0"] { |
| 562 | { | ||
| 563 | border-radius: 2px; | 484 | border-radius: 2px; |
| 564 | border: 1px transparent #76797C; | 485 | border: 1px transparent #76797C; |
| 565 | } | 486 | } |
| 566 | 487 | ||
| 567 | QStackedWidget | 488 | QStackedWidget { |
| 568 | { | ||
| 569 | border: 1px transparent black; | 489 | border: 1px transparent black; |
| 570 | } | 490 | } |
| 571 | 491 | ||
| @@ -578,21 +498,24 @@ QToolBar { | |||
| 578 | QToolBar::handle:horizontal { | 498 | QToolBar::handle:horizontal { |
| 579 | image: url(:/qss_icons/rc/Hmovetoolbar.png); | 499 | image: url(:/qss_icons/rc/Hmovetoolbar.png); |
| 580 | } | 500 | } |
| 501 | |||
| 581 | QToolBar::handle:vertical { | 502 | QToolBar::handle:vertical { |
| 582 | image: url(:/qss_icons/rc/Vmovetoolbar.png); | 503 | image: url(:/qss_icons/rc/Vmovetoolbar.png); |
| 583 | } | 504 | } |
| 505 | |||
| 584 | QToolBar::separator:horizontal { | 506 | QToolBar::separator:horizontal { |
| 585 | image: url(:/qss_icons/rc/Hsepartoolbar.png); | 507 | image: url(:/qss_icons/rc/Hsepartoolbar.png); |
| 586 | } | 508 | } |
| 509 | |||
| 587 | QToolBar::separator:vertical { | 510 | QToolBar::separator:vertical { |
| 588 | image: url(:/qss_icons/rc/Vsepartoolbar.png); | 511 | image: url(:/qss_icons/rc/Vsepartoolbar.png); |
| 589 | } | 512 | } |
| 513 | |||
| 590 | QToolButton#qt_toolbar_ext_button { | 514 | QToolButton#qt_toolbar_ext_button { |
| 591 | background: #58595a | 515 | background: #58595a |
| 592 | } | 516 | } |
| 593 | 517 | ||
| 594 | QPushButton | 518 | QPushButton { |
| 595 | { | ||
| 596 | color: #eff0f1; | 519 | color: #eff0f1; |
| 597 | background-color: #31363b; | 520 | background-color: #31363b; |
| 598 | border-width: 1px; | 521 | border-width: 1px; |
| @@ -603,8 +526,7 @@ QPushButton | |||
| 603 | outline: none; | 526 | outline: none; |
| 604 | } | 527 | } |
| 605 | 528 | ||
| 606 | QPushButton:disabled | 529 | QPushButton:disabled { |
| 607 | { | ||
| 608 | background-color: #31363b; | 530 | background-color: #31363b; |
| 609 | border-width: 1px; | 531 | border-width: 1px; |
| 610 | border-color: #454545; | 532 | border-color: #454545; |
| @@ -622,15 +544,13 @@ QPushButton:focus { | |||
| 622 | color: white; | 544 | color: white; |
| 623 | } | 545 | } |
| 624 | 546 | ||
| 625 | QPushButton:pressed | 547 | QPushButton:pressed { |
| 626 | { | ||
| 627 | background-color: #3daee9; | 548 | background-color: #3daee9; |
| 628 | padding-top: -15px; | 549 | padding-top: -15px; |
| 629 | padding-bottom: -17px; | 550 | padding-bottom: -17px; |
| 630 | } | 551 | } |
| 631 | 552 | ||
| 632 | QComboBox | 553 | QComboBox { |
| 633 | { | ||
| 634 | selection-background-color: #3daee9; | 554 | selection-background-color: #3daee9; |
| 635 | border-style: solid; | 555 | border-style: solid; |
| 636 | border: 1px solid #76797C; | 556 | border: 1px solid #76797C; |
| @@ -639,38 +559,40 @@ QComboBox | |||
| 639 | min-width: 75px; | 559 | min-width: 75px; |
| 640 | } | 560 | } |
| 641 | 561 | ||
| 642 | QPushButton:checked{ | 562 | QPushButton:checked { |
| 643 | background-color: #76797C; | 563 | background-color: #76797C; |
| 644 | border-color: #6A6969; | 564 | border-color: #6A6969; |
| 645 | } | 565 | } |
| 646 | 566 | ||
| 647 | QComboBox:hover,QPushButton:hover,QAbstractSpinBox:hover,QLineEdit:hover,QTextEdit:hover,QPlainTextEdit:hover,QAbstractView:hover,QTreeView:hover | 567 | QComboBox:hover, |
| 648 | { | 568 | QPushButton:hover, |
| 569 | QAbstractSpinBox:hover, | ||
| 570 | QLineEdit:hover, | ||
| 571 | QTextEdit:hover, | ||
| 572 | QPlainTextEdit:hover, | ||
| 573 | QAbstractView:hover, | ||
| 574 | QTreeView:hover { | ||
| 649 | border: 1px solid #3daee9; | 575 | border: 1px solid #3daee9; |
| 650 | color: #eff0f1; | 576 | color: #eff0f1; |
| 651 | } | 577 | } |
| 652 | 578 | ||
| 653 | QComboBox:on | 579 | QComboBox:on { |
| 654 | { | ||
| 655 | padding-top: 3px; | 580 | padding-top: 3px; |
| 656 | padding-left: 4px; | 581 | padding-left: 4px; |
| 657 | selection-background-color: #4a4a4a; | 582 | selection-background-color: #4a4a4a; |
| 658 | } | 583 | } |
| 659 | 584 | ||
| 660 | QComboBox QAbstractItemView | 585 | QComboBox QAbstractItemView { |
| 661 | { | ||
| 662 | background-color: #232629; | 586 | background-color: #232629; |
| 663 | border-radius: 2px; | 587 | border-radius: 2px; |
| 664 | border: 1px solid #76797C; | 588 | border: 1px solid #76797C; |
| 665 | selection-background-color: #18465d; | 589 | selection-background-color: #18465d; |
| 666 | } | 590 | } |
| 667 | 591 | ||
| 668 | QComboBox::drop-down | 592 | QComboBox::drop-down { |
| 669 | { | ||
| 670 | subcontrol-origin: padding; | 593 | subcontrol-origin: padding; |
| 671 | subcontrol-position: top right; | 594 | subcontrol-position: top right; |
| 672 | width: 15px; | 595 | width: 15px; |
| 673 | |||
| 674 | border-left-width: 0px; | 596 | border-left-width: 0px; |
| 675 | border-left-color: darkgray; | 597 | border-left-color: darkgray; |
| 676 | border-left-style: solid; | 598 | border-left-style: solid; |
| @@ -678,14 +600,13 @@ QComboBox::drop-down | |||
| 678 | border-bottom-right-radius: 3px; | 600 | border-bottom-right-radius: 3px; |
| 679 | } | 601 | } |
| 680 | 602 | ||
| 681 | QComboBox::down-arrow | 603 | QComboBox::down-arrow { |
| 682 | { | ||
| 683 | image: url(:/qss_icons/rc/down_arrow_disabled.png); | 604 | image: url(:/qss_icons/rc/down_arrow_disabled.png); |
| 684 | } | 605 | } |
| 685 | 606 | ||
| 686 | QComboBox::down-arrow:on, QComboBox::down-arrow:hover, | 607 | QComboBox::down-arrow:on, |
| 687 | QComboBox::down-arrow:focus | 608 | QComboBox::down-arrow:hover, |
| 688 | { | 609 | QComboBox::down-arrow:focus { |
| 689 | image: url(:/qss_icons/rc/down_arrow.png); | 610 | image: url(:/qss_icons/rc/down_arrow.png); |
| 690 | } | 611 | } |
| 691 | 612 | ||
| @@ -698,49 +619,47 @@ QAbstractSpinBox { | |||
| 698 | min-width: 75px; | 619 | min-width: 75px; |
| 699 | } | 620 | } |
| 700 | 621 | ||
| 701 | QAbstractSpinBox:up-button | 622 | QAbstractSpinBox:up-button { |
| 702 | { | ||
| 703 | background-color: transparent; | 623 | background-color: transparent; |
| 704 | subcontrol-origin: border; | 624 | subcontrol-origin: border; |
| 705 | subcontrol-position: center right; | 625 | subcontrol-position: center right; |
| 706 | } | 626 | } |
| 707 | 627 | ||
| 708 | QAbstractSpinBox:down-button | 628 | QAbstractSpinBox:down-button { |
| 709 | { | ||
| 710 | background-color: transparent; | 629 | background-color: transparent; |
| 711 | subcontrol-origin: border; | 630 | subcontrol-origin: border; |
| 712 | subcontrol-position: center left; | 631 | subcontrol-position: center left; |
| 713 | } | 632 | } |
| 714 | 633 | ||
| 715 | QAbstractSpinBox::up-arrow,QAbstractSpinBox::up-arrow:disabled,QAbstractSpinBox::up-arrow:off { | 634 | QAbstractSpinBox::up-arrow, |
| 635 | QAbstractSpinBox::up-arrow:disabled, | ||
| 636 | QAbstractSpinBox::up-arrow:off { | ||
| 716 | image: url(:/qss_icons/rc/up_arrow_disabled.png); | 637 | image: url(:/qss_icons/rc/up_arrow_disabled.png); |
| 717 | width: 10px; | 638 | width: 10px; |
| 718 | height: 10px; | 639 | height: 10px; |
| 719 | } | 640 | } |
| 720 | QAbstractSpinBox::up-arrow:hover | 641 | |
| 721 | { | 642 | QAbstractSpinBox::up-arrow:hover { |
| 722 | image: url(:/qss_icons/rc/up_arrow.png); | 643 | image: url(:/qss_icons/rc/up_arrow.png); |
| 723 | } | 644 | } |
| 724 | 645 | ||
| 725 | 646 | QAbstractSpinBox::down-arrow, | |
| 726 | QAbstractSpinBox::down-arrow,QAbstractSpinBox::down-arrow:disabled,QAbstractSpinBox::down-arrow:off | 647 | QAbstractSpinBox::down-arrow:disabled, |
| 727 | { | 648 | QAbstractSpinBox::down-arrow:off { |
| 728 | image: url(:/qss_icons/rc/down_arrow_disabled.png); | 649 | image: url(:/qss_icons/rc/down_arrow_disabled.png); |
| 729 | width: 10px; | 650 | width: 10px; |
| 730 | height: 10px; | 651 | height: 10px; |
| 731 | } | 652 | } |
| 732 | QAbstractSpinBox::down-arrow:hover | 653 | |
| 733 | { | 654 | QAbstractSpinBox::down-arrow:hover { |
| 734 | image: url(:/qss_icons/rc/down_arrow.png); | 655 | image: url(:/qss_icons/rc/down_arrow.png); |
| 735 | } | 656 | } |
| 736 | 657 | ||
| 737 | 658 | QLabel { | |
| 738 | QLabel | ||
| 739 | { | ||
| 740 | border: 0px solid black; | 659 | border: 0px solid black; |
| 741 | } | 660 | } |
| 742 | 661 | ||
| 743 | QTabWidget{ | 662 | QTabWidget { |
| 744 | border: 0px transparent black; | 663 | border: 0px transparent black; |
| 745 | } | 664 | } |
| 746 | 665 | ||
| @@ -751,27 +670,24 @@ QTabWidget::pane { | |||
| 751 | } | 670 | } |
| 752 | 671 | ||
| 753 | QTabWidget::tab-bar { | 672 | QTabWidget::tab-bar { |
| 754 | left: 5px; /* move to the right by 5px */ | 673 | /* left: 5px; move to the right by 5px */ |
| 755 | } | 674 | } |
| 756 | 675 | ||
| 757 | QTabBar | 676 | QTabBar { |
| 758 | { | ||
| 759 | qproperty-drawBase: 0; | 677 | qproperty-drawBase: 0; |
| 760 | border-radius: 3px; | 678 | border-radius: 3px; |
| 761 | } | 679 | } |
| 762 | 680 | ||
| 763 | QTabBar:focus | 681 | QTabBar:focus { |
| 764 | { | ||
| 765 | border: 0px transparent black; | 682 | border: 0px transparent black; |
| 766 | } | 683 | } |
| 767 | 684 | ||
| 768 | QTabBar::close-button { | 685 | QTabBar::close-button { |
| 769 | image: url(:/qss_icons/rc/close.png); | 686 | image: url(:/qss_icons/rc/close.png); |
| 770 | background: transparent; | 687 | background: transparent; |
| 771 | } | 688 | } |
| 772 | 689 | ||
| 773 | QTabBar::close-button:hover | 690 | QTabBar::close-button:hover { |
| 774 | { | ||
| 775 | image: url(:/qss_icons/rc/close-hover.png); | 691 | image: url(:/qss_icons/rc/close-hover.png); |
| 776 | background: transparent; | 692 | background: transparent; |
| 777 | } | 693 | } |
| @@ -781,7 +697,9 @@ QTabBar::close-button:pressed { | |||
| 781 | background: transparent; | 697 | background: transparent; |
| 782 | } | 698 | } |
| 783 | 699 | ||
| 700 | |||
| 784 | /* TOP TABS */ | 701 | /* TOP TABS */ |
| 702 | |||
| 785 | QTabBar::tab:top { | 703 | QTabBar::tab:top { |
| 786 | color: #eff0f1; | 704 | color: #eff0f1; |
| 787 | border: 1px solid #76797C; | 705 | border: 1px solid #76797C; |
| @@ -793,12 +711,11 @@ QTabBar::tab:top { | |||
| 793 | border-top-right-radius: 2px; | 711 | border-top-right-radius: 2px; |
| 794 | } | 712 | } |
| 795 | 713 | ||
| 796 | QTabBar::tab:top:!selected | 714 | QTabBar::tab:top:selected { |
| 797 | { | ||
| 798 | color: #eff0f1; | 715 | color: #eff0f1; |
| 799 | background-color: #54575B; | 716 | background-color: #54575B; |
| 800 | border: 1px solid #76797C; | 717 | border: 1px solid #76797C; |
| 801 | border-bottom: 1px transparent black; | 718 | border-bottom: 2px solid #3daee9; |
| 802 | border-top-left-radius: 2px; | 719 | border-top-left-radius: 2px; |
| 803 | border-top-right-radius: 2px; | 720 | border-top-right-radius: 2px; |
| 804 | } | 721 | } |
| @@ -807,7 +724,9 @@ QTabBar::tab:top:!selected:hover { | |||
| 807 | background-color: #3daee9; | 724 | background-color: #3daee9; |
| 808 | } | 725 | } |
| 809 | 726 | ||
| 727 | |||
| 810 | /* BOTTOM TABS */ | 728 | /* BOTTOM TABS */ |
| 729 | |||
| 811 | QTabBar::tab:bottom { | 730 | QTabBar::tab:bottom { |
| 812 | color: #eff0f1; | 731 | color: #eff0f1; |
| 813 | border: 1px solid #76797C; | 732 | border: 1px solid #76797C; |
| @@ -819,12 +738,11 @@ QTabBar::tab:bottom { | |||
| 819 | min-width: 50px; | 738 | min-width: 50px; |
| 820 | } | 739 | } |
| 821 | 740 | ||
| 822 | QTabBar::tab:bottom:!selected | 741 | QTabBar::tab:bottom:selected { |
| 823 | { | ||
| 824 | color: #eff0f1; | 742 | color: #eff0f1; |
| 825 | background-color: #54575B; | 743 | background-color: #54575B; |
| 826 | border: 1px solid #76797C; | 744 | border: 1px solid #76797C; |
| 827 | border-top: 1px transparent black; | 745 | border-top: 2px solid #3daee9; |
| 828 | border-bottom-left-radius: 2px; | 746 | border-bottom-left-radius: 2px; |
| 829 | border-bottom-right-radius: 2px; | 747 | border-bottom-right-radius: 2px; |
| 830 | } | 748 | } |
| @@ -833,7 +751,9 @@ QTabBar::tab:bottom:!selected:hover { | |||
| 833 | background-color: #3daee9; | 751 | background-color: #3daee9; |
| 834 | } | 752 | } |
| 835 | 753 | ||
| 754 | |||
| 836 | /* LEFT TABS */ | 755 | /* LEFT TABS */ |
| 756 | |||
| 837 | QTabBar::tab:left { | 757 | QTabBar::tab:left { |
| 838 | color: #eff0f1; | 758 | color: #eff0f1; |
| 839 | border: 1px solid #76797C; | 759 | border: 1px solid #76797C; |
| @@ -845,12 +765,11 @@ QTabBar::tab:left { | |||
| 845 | min-height: 50px; | 765 | min-height: 50px; |
| 846 | } | 766 | } |
| 847 | 767 | ||
| 848 | QTabBar::tab:left:!selected | 768 | QTabBar::tab:left:selected { |
| 849 | { | ||
| 850 | color: #eff0f1; | 769 | color: #eff0f1; |
| 851 | background-color: #54575B; | 770 | background-color: #54575B; |
| 852 | border: 1px solid #76797C; | 771 | border: 1px solid #76797C; |
| 853 | border-left: 1px transparent black; | 772 | border-left: 2px solid #3daee9; |
| 854 | border-top-right-radius: 2px; | 773 | border-top-right-radius: 2px; |
| 855 | border-bottom-right-radius: 2px; | 774 | border-bottom-right-radius: 2px; |
| 856 | } | 775 | } |
| @@ -861,6 +780,7 @@ QTabBar::tab:left:!selected:hover { | |||
| 861 | 780 | ||
| 862 | 781 | ||
| 863 | /* RIGHT TABS */ | 782 | /* RIGHT TABS */ |
| 783 | |||
| 864 | QTabBar::tab:right { | 784 | QTabBar::tab:right { |
| 865 | color: #eff0f1; | 785 | color: #eff0f1; |
| 866 | border: 1px solid #76797C; | 786 | border: 1px solid #76797C; |
| @@ -872,12 +792,11 @@ QTabBar::tab:right { | |||
| 872 | min-height: 50px; | 792 | min-height: 50px; |
| 873 | } | 793 | } |
| 874 | 794 | ||
| 875 | QTabBar::tab:right:!selected | 795 | QTabBar::tab:right:selected { |
| 876 | { | ||
| 877 | color: #eff0f1; | 796 | color: #eff0f1; |
| 878 | background-color: #54575B; | 797 | background-color: #54575B; |
| 879 | border: 1px solid #76797C; | 798 | border: 1px solid #76797C; |
| 880 | border-right: 1px transparent black; | 799 | border-right: 2px solid #3daee9; |
| 881 | border-top-left-radius: 2px; | 800 | border-top-left-radius: 2px; |
| 882 | border-bottom-left-radius: 2px; | 801 | border-bottom-left-radius: 2px; |
| 883 | } | 802 | } |
| @@ -887,21 +806,20 @@ QTabBar::tab:right:!selected:hover { | |||
| 887 | } | 806 | } |
| 888 | 807 | ||
| 889 | QTabBar QToolButton::right-arrow:enabled { | 808 | QTabBar QToolButton::right-arrow:enabled { |
| 890 | image: url(:/qss_icons/rc/right_arrow.png); | 809 | image: url(:/qss_icons/rc/right_arrow.png); |
| 891 | } | 810 | } |
| 892 | 811 | ||
| 893 | QTabBar QToolButton::left-arrow:enabled { | 812 | QTabBar QToolButton::left-arrow:enabled { |
| 894 | image: url(:/qss_icons/rc/left_arrow.png); | 813 | image: url(:/qss_icons/rc/left_arrow.png); |
| 895 | } | 814 | } |
| 896 | 815 | ||
| 897 | QTabBar QToolButton::right-arrow:disabled { | 816 | QTabBar QToolButton::right-arrow:disabled { |
| 898 | image: url(:/qss_icons/rc/right_arrow_disabled.png); | 817 | image: url(:/qss_icons/rc/right_arrow_disabled.png); |
| 899 | } | 818 | } |
| 900 | |||
| 901 | QTabBar QToolButton::left-arrow:disabled { | ||
| 902 | image: url(:/qss_icons/rc/left_arrow_disabled.png); | ||
| 903 | } | ||
| 904 | 819 | ||
| 820 | QTabBar QToolButton::left-arrow:disabled { | ||
| 821 | image: url(:/qss_icons/rc/left_arrow_disabled.png); | ||
| 822 | } | ||
| 905 | 823 | ||
| 906 | QDockWidget { | 824 | QDockWidget { |
| 907 | background: #31363b; | 825 | background: #31363b; |
| @@ -910,29 +828,32 @@ QDockWidget { | |||
| 910 | titlebar-normal-icon: url(:/qss_icons/rc/undock.png); | 828 | titlebar-normal-icon: url(:/qss_icons/rc/undock.png); |
| 911 | } | 829 | } |
| 912 | 830 | ||
| 913 | QDockWidget::close-button, QDockWidget::float-button { | 831 | QDockWidget::close-button, |
| 832 | QDockWidget::float-button { | ||
| 914 | border: 1px solid transparent; | 833 | border: 1px solid transparent; |
| 915 | border-radius: 2px; | 834 | border-radius: 2px; |
| 916 | background: transparent; | 835 | background: transparent; |
| 917 | } | 836 | } |
| 918 | 837 | ||
| 919 | QDockWidget::close-button:hover, QDockWidget::float-button:hover { | 838 | QDockWidget::close-button:hover, |
| 839 | QDockWidget::float-button:hover { | ||
| 920 | background: rgba(255, 255, 255, 10); | 840 | background: rgba(255, 255, 255, 10); |
| 921 | } | 841 | } |
| 922 | 842 | ||
| 923 | QDockWidget::close-button:pressed, QDockWidget::float-button:pressed { | 843 | QDockWidget::close-button:pressed, |
| 844 | QDockWidget::float-button:pressed { | ||
| 924 | padding: 1px -1px -1px 1px; | 845 | padding: 1px -1px -1px 1px; |
| 925 | background: rgba(255, 255, 255, 10); | 846 | background: rgba(255, 255, 255, 10); |
| 926 | } | 847 | } |
| 927 | 848 | ||
| 928 | QTreeView, QListView | 849 | QTreeView, |
| 929 | { | 850 | QListView { |
| 930 | border: 1px solid #76797C; | 851 | border: 1px solid #76797C; |
| 931 | background-color: #232629; | 852 | background-color: #232629; |
| 932 | } | 853 | } |
| 933 | 854 | ||
| 934 | QTreeView:branch:selected, QTreeView:branch:hover | 855 | QTreeView:branch:selected, |
| 935 | { | 856 | QTreeView:branch:hover { |
| 936 | background: url(:/qss_icons/rc/transparent.png); | 857 | background: url(:/qss_icons/rc/transparent.png); |
| 937 | } | 858 | } |
| 938 | 859 | ||
| @@ -954,31 +875,75 @@ QTreeView::branch:closed:has-children:has-siblings { | |||
| 954 | } | 875 | } |
| 955 | 876 | ||
| 956 | QTreeView::branch:open:has-children:!has-siblings, | 877 | QTreeView::branch:open:has-children:!has-siblings, |
| 957 | QTreeView::branch:open:has-children:has-siblings { | 878 | QTreeView::branch:open:has-children:has-siblings { |
| 958 | image: url(:/qss_icons/rc/branch_open.png); | 879 | image: url(:/qss_icons/rc/branch_open.png); |
| 959 | } | 880 | } |
| 960 | 881 | ||
| 961 | QTreeView::branch:has-children:!has-siblings:closed:hover, | 882 | QTreeView::branch:has-children:!has-siblings:closed:hover, |
| 962 | QTreeView::branch:closed:has-children:has-siblings:hover { | 883 | QTreeView::branch:closed:has-children:has-siblings:hover { |
| 963 | image: url(:/qss_icons/rc/branch_closed-on.png); | 884 | image: url(:/qss_icons/rc/branch_closed-on.png); |
| 964 | } | 885 | } |
| 965 | 886 | ||
| 966 | QTreeView::branch:open:has-children:!has-siblings:hover, | 887 | QTreeView::branch:open:has-children:!has-siblings:hover, |
| 967 | QTreeView::branch:open:has-children:has-siblings:hover { | 888 | QTreeView::branch:open:has-children:has-siblings:hover { |
| 968 | image: url(:/qss_icons/rc/branch_open-on.png); | 889 | image: url(:/qss_icons/rc/branch_open-on.png); |
| 969 | } | 890 | } |
| 970 | 891 | ||
| 971 | QListView::item:!selected:hover, QTreeView::item:!selected:hover { | 892 | QListView::item:!selected:hover, |
| 893 | QTreeView::item:!selected:hover { | ||
| 972 | background: #18465d; | 894 | background: #18465d; |
| 973 | outline: 0; | 895 | outline: 0; |
| 974 | color: #eff0f1 | 896 | color: #eff0f1 |
| 975 | } | 897 | } |
| 976 | 898 | ||
| 977 | QListView::item:selected:hover, QTreeView::item:selected:hover { | 899 | QListView::item:selected:hover, |
| 900 | QTreeView::item:selected:hover { | ||
| 978 | background: #287399; | 901 | background: #287399; |
| 979 | color: #eff0f1; | 902 | color: #eff0f1; |
| 980 | } | 903 | } |
| 981 | 904 | ||
| 905 | QTreeView::indicator:checked, | ||
| 906 | QListView::indicator:checked { | ||
| 907 | image: url(:/qss_icons/rc/checkbox_checked.png); | ||
| 908 | } | ||
| 909 | |||
| 910 | QTreeView::indicator:unchecked, | ||
| 911 | QListView::indicator:unchecked { | ||
| 912 | image: url(:/qss_icons/rc/checkbox_unchecked.png); | ||
| 913 | } | ||
| 914 | |||
| 915 | QTreeView::indicator:indeterminate, | ||
| 916 | QListView::indicator:indeterminate { | ||
| 917 | image: url(:/qss_icons/rc/checkbox_indeterminate.png); | ||
| 918 | } | ||
| 919 | |||
| 920 | QTreeView::indicator:checked:hover, | ||
| 921 | QTreeView::indicator:checked:focus, | ||
| 922 | QTreeView::indicator:checked:pressed, | ||
| 923 | QListView::indicator:checked:hover, | ||
| 924 | QListView::indicator:checked:focus, | ||
| 925 | QListView::indicator:checked:pressed { | ||
| 926 | image: url(:/qss_icons/rc/checkbox_checked_focus.png); | ||
| 927 | } | ||
| 928 | |||
| 929 | QTreeView::indicator:unchecked:hover, | ||
| 930 | QTreeView::indicator:unchecked:focus, | ||
| 931 | QTreeView::indicator:unchecked:pressed, | ||
| 932 | QListView::indicator:unchecked:hover, | ||
| 933 | QListView::indicator:unchecked:focus, | ||
| 934 | QListView::indicator:unchecked:pressed { | ||
| 935 | image: url(:/qss_icons/rc/checkbox_unchecked_focus.png); | ||
| 936 | } | ||
| 937 | |||
| 938 | QTreeView::indicator:indeterminate:hover, | ||
| 939 | QTreeView::indicator:indeterminate:focus, | ||
| 940 | QTreeView::indicator:indeterminate:pressed, | ||
| 941 | QListView::indicator:indeterminate:hover, | ||
| 942 | QListView::indicator:indeterminate:focus, | ||
| 943 | QListView::indicator:indeterminate:pressed { | ||
| 944 | image: url(:/qss_icons/rc/checkbox_indeterminate_focus.png); | ||
| 945 | } | ||
| 946 | |||
| 982 | QSlider::groove:horizontal { | 947 | QSlider::groove:horizontal { |
| 983 | border: 1px solid #565a5e; | 948 | border: 1px solid #565a5e; |
| 984 | height: 4px; | 949 | height: 4px; |
| @@ -1021,38 +986,49 @@ QToolButton { | |||
| 1021 | padding: 5px; | 986 | padding: 5px; |
| 1022 | } | 987 | } |
| 1023 | 988 | ||
| 1024 | QToolButton[popupMode="1"] { /* only for MenuButtonPopup */ | 989 | QToolButton[popupMode="1"] { |
| 1025 | padding-right: 20px; /* make way for the popup button */ | 990 | /* only for MenuButtonPopup */ |
| 1026 | border: 1px #76797C; | 991 | padding-right: 20px; |
| 1027 | border-radius: 5px; | 992 | /* make way for the popup button */ |
| 993 | border: 1px #76797C; | ||
| 994 | border-radius: 5px; | ||
| 1028 | } | 995 | } |
| 1029 | 996 | ||
| 1030 | QToolButton[popupMode="2"] { /* only for InstantPopup */ | 997 | QToolButton[popupMode="2"] { |
| 1031 | padding-right: 10px; /* make way for the popup button */ | 998 | /* only for InstantPopup */ |
| 1032 | border: 1px #76797C; | 999 | padding-right: 10px; |
| 1000 | /* make way for the popup button */ | ||
| 1001 | border: 1px #76797C; | ||
| 1033 | } | 1002 | } |
| 1034 | 1003 | ||
| 1035 | 1004 | QToolButton:hover, | |
| 1036 | QToolButton:hover, QToolButton::menu-button:hover { | 1005 | QToolButton::menu-button:hover { |
| 1037 | background-color: transparent; | 1006 | background-color: transparent; |
| 1038 | border: 1px solid #3daee9; | 1007 | border: 1px solid #3daee9; |
| 1039 | padding: 5px; | 1008 | padding: 5px; |
| 1040 | } | 1009 | } |
| 1041 | 1010 | ||
| 1042 | QToolButton:checked, QToolButton:pressed, | 1011 | QToolButton:checked, |
| 1043 | QToolButton::menu-button:pressed { | 1012 | QToolButton:pressed, |
| 1013 | QToolButton::menu-button:pressed { | ||
| 1044 | background-color: #3daee9; | 1014 | background-color: #3daee9; |
| 1045 | border: 1px solid #3daee9; | 1015 | border: 1px solid #3daee9; |
| 1046 | padding: 5px; | 1016 | padding: 5px; |
| 1047 | } | 1017 | } |
| 1048 | 1018 | ||
| 1019 | |||
| 1049 | /* the subcontrol below is used only in the InstantPopup or DelayedPopup mode */ | 1020 | /* the subcontrol below is used only in the InstantPopup or DelayedPopup mode */ |
| 1021 | |||
| 1050 | QToolButton::menu-indicator { | 1022 | QToolButton::menu-indicator { |
| 1051 | image: url(:/qss_icons/rc/down_arrow.png); | 1023 | image: url(:/qss_icons/rc/down_arrow.png); |
| 1052 | top: -7px; left: -2px; /* shift it a bit */ | 1024 | top: -7px; |
| 1025 | left: -2px; | ||
| 1026 | /* shift it a bit */ | ||
| 1053 | } | 1027 | } |
| 1054 | 1028 | ||
| 1029 | |||
| 1055 | /* the subcontrols below are used only in the MenuButtonPopup mode */ | 1030 | /* the subcontrols below are used only in the MenuButtonPopup mode */ |
| 1031 | |||
| 1056 | QToolButton::menu-button { | 1032 | QToolButton::menu-button { |
| 1057 | border: 1px transparent #76797C; | 1033 | border: 1px transparent #76797C; |
| 1058 | border-top-right-radius: 6px; | 1034 | border-top-right-radius: 6px; |
| @@ -1070,47 +1046,46 @@ QToolButton::menu-arrow:open { | |||
| 1070 | border: 1px solid #76797C; | 1046 | border: 1px solid #76797C; |
| 1071 | } | 1047 | } |
| 1072 | 1048 | ||
| 1073 | QPushButton::menu-indicator { | 1049 | QPushButton::menu-indicator { |
| 1074 | subcontrol-origin: padding; | 1050 | subcontrol-origin: padding; |
| 1075 | subcontrol-position: bottom right; | 1051 | subcontrol-position: bottom right; |
| 1076 | left: 8px; | 1052 | left: 8px; |
| 1077 | } | 1053 | } |
| 1078 | 1054 | ||
| 1079 | QTableView | 1055 | QTableView { |
| 1080 | { | ||
| 1081 | border: 1px solid #76797C; | 1056 | border: 1px solid #76797C; |
| 1082 | gridline-color: #31363b; | 1057 | gridline-color: #31363b; |
| 1083 | background-color: #232629; | 1058 | background-color: #232629; |
| 1084 | } | 1059 | } |
| 1085 | 1060 | ||
| 1086 | 1061 | QTableView, | |
| 1087 | QTableView, QHeaderView | 1062 | QHeaderView { |
| 1088 | { | ||
| 1089 | border-radius: 0px; | 1063 | border-radius: 0px; |
| 1090 | } | 1064 | } |
| 1091 | 1065 | ||
| 1092 | QTableView::item:pressed, QListView::item:pressed, QTreeView::item:pressed { | 1066 | QTableView::item:pressed, |
| 1067 | QListView::item:pressed, | ||
| 1068 | QTreeView::item:pressed { | ||
| 1093 | background: #18465d; | 1069 | background: #18465d; |
| 1094 | color: #eff0f1; | 1070 | color: #eff0f1; |
| 1095 | } | 1071 | } |
| 1096 | 1072 | ||
| 1097 | QTableView::item:selected:active, QTreeView::item:selected:active, QListView::item:selected:active { | 1073 | QTableView::item:selected:active, |
| 1074 | QTreeView::item:selected:active, | ||
| 1075 | QListView::item:selected:active { | ||
| 1098 | background: #287399; | 1076 | background: #287399; |
| 1099 | color: #eff0f1; | 1077 | color: #eff0f1; |
| 1100 | } | 1078 | } |
| 1101 | 1079 | ||
| 1102 | 1080 | QHeaderView { | |
| 1103 | QHeaderView | ||
| 1104 | { | ||
| 1105 | background-color: #31363b; | 1081 | background-color: #31363b; |
| 1106 | border: 1px transparent; | 1082 | border: 1px transparent; |
| 1107 | border-radius: 0px; | 1083 | border-radius: 0px; |
| 1108 | margin: 0px; | 1084 | margin: 0px; |
| 1109 | padding: 0px; | 1085 | padding: 0px; |
| 1110 | |||
| 1111 | } | 1086 | } |
| 1112 | 1087 | ||
| 1113 | QHeaderView::section { | 1088 | QHeaderView::section { |
| 1114 | background-color: #31363b; | 1089 | background-color: #31363b; |
| 1115 | color: #eff0f1; | 1090 | color: #eff0f1; |
| 1116 | padding: 5px; | 1091 | padding: 5px; |
| @@ -1119,34 +1094,32 @@ QHeaderView::section { | |||
| 1119 | text-align: center; | 1094 | text-align: center; |
| 1120 | } | 1095 | } |
| 1121 | 1096 | ||
| 1122 | QHeaderView::section::vertical::first, QHeaderView::section::vertical::only-one | 1097 | QHeaderView::section::vertical::first, |
| 1123 | { | 1098 | QHeaderView::section::vertical::only-one { |
| 1124 | border-top: 1px solid #76797C; | 1099 | border-top: 1px solid #76797C; |
| 1125 | } | 1100 | } |
| 1126 | 1101 | ||
| 1127 | QHeaderView::section::vertical | 1102 | QHeaderView::section::vertical { |
| 1128 | { | ||
| 1129 | border-top: transparent; | 1103 | border-top: transparent; |
| 1130 | } | 1104 | } |
| 1131 | 1105 | ||
| 1132 | QHeaderView::section::horizontal::first, QHeaderView::section::horizontal::only-one | 1106 | QHeaderView::section::horizontal::first, |
| 1133 | { | 1107 | QHeaderView::section::horizontal::only-one { |
| 1134 | border-left: 1px solid #76797C; | 1108 | border-left: 1px solid #76797C; |
| 1135 | } | 1109 | } |
| 1136 | 1110 | ||
| 1137 | QHeaderView::section::horizontal | 1111 | QHeaderView::section::horizontal { |
| 1138 | { | ||
| 1139 | border-left: transparent; | 1112 | border-left: transparent; |
| 1140 | } | 1113 | } |
| 1141 | 1114 | ||
| 1142 | 1115 | QHeaderView::section:checked { | |
| 1143 | QHeaderView::section:checked | ||
| 1144 | { | ||
| 1145 | color: white; | 1116 | color: white; |
| 1146 | background-color: #334e5e; | 1117 | background-color: #334e5e; |
| 1147 | } | 1118 | } |
| 1119 | |||
| 1120 | |||
| 1121 | /* style the sort indicator */ | ||
| 1148 | 1122 | ||
| 1149 | /* style the sort indicator */ | ||
| 1150 | QHeaderView::down-arrow { | 1123 | QHeaderView::down-arrow { |
| 1151 | image: url(:/qss_icons/rc/down_arrow.png); | 1124 | image: url(:/qss_icons/rc/down_arrow.png); |
| 1152 | } | 1125 | } |
| @@ -1155,14 +1128,13 @@ QHeaderView::up-arrow { | |||
| 1155 | image: url(:/qss_icons/rc/up_arrow.png); | 1128 | image: url(:/qss_icons/rc/up_arrow.png); |
| 1156 | } | 1129 | } |
| 1157 | 1130 | ||
| 1158 | |||
| 1159 | QTableCornerButton::section { | 1131 | QTableCornerButton::section { |
| 1160 | background-color: #31363b; | 1132 | background-color: #31363b; |
| 1161 | border: 1px transparent #76797C; | 1133 | border: 1px transparent #76797C; |
| 1162 | border-radius: 0px; | 1134 | border-radius: 0px; |
| 1163 | } | 1135 | } |
| 1164 | 1136 | ||
| 1165 | QToolBox { | 1137 | QToolBox { |
| 1166 | padding: 5px; | 1138 | padding: 5px; |
| 1167 | border: 1px transparent black; | 1139 | border: 1px transparent black; |
| 1168 | } | 1140 | } |
| @@ -1176,22 +1148,22 @@ QToolBox::tab { | |||
| 1176 | border-top-right-radius: 5px; | 1148 | border-top-right-radius: 5px; |
| 1177 | } | 1149 | } |
| 1178 | 1150 | ||
| 1179 | QToolBox::tab:selected { /* italicize selected tabs */ | 1151 | QToolBox::tab:selected { |
| 1152 | /* italicize selected tabs */ | ||
| 1180 | font: italic; | 1153 | font: italic; |
| 1181 | background-color: #31363b; | 1154 | background-color: #31363b; |
| 1182 | border-color: #3daee9; | 1155 | border-color: #3daee9; |
| 1183 | } | 1156 | } |
| 1184 | 1157 | ||
| 1185 | QStatusBar::item { | 1158 | QStatusBar::item { |
| 1186 | border: 0px transparent dark; | 1159 | border: 0px transparent dark; |
| 1187 | } | 1160 | } |
| 1188 | |||
| 1189 | 1161 | ||
| 1190 | QFrame[height="3"], QFrame[width="3"] { | 1162 | QFrame[height="3"], |
| 1163 | QFrame[width="3"] { | ||
| 1191 | background-color: #76797C; | 1164 | background-color: #76797C; |
| 1192 | } | 1165 | } |
| 1193 | 1166 | ||
| 1194 | |||
| 1195 | QSplitter::handle { | 1167 | QSplitter::handle { |
| 1196 | border: 1px dashed #76797C; | 1168 | border: 1px dashed #76797C; |
| 1197 | } | 1169 | } |
| @@ -1219,8 +1191,7 @@ QProgressBar::chunk { | |||
| 1219 | background-color: #05B8CC; | 1191 | background-color: #05B8CC; |
| 1220 | } | 1192 | } |
| 1221 | 1193 | ||
| 1222 | QDateEdit | 1194 | QDateEdit { |
| 1223 | { | ||
| 1224 | selection-background-color: #3daee9; | 1195 | selection-background-color: #3daee9; |
| 1225 | border-style: solid; | 1196 | border-style: solid; |
| 1226 | border: 1px solid #3375A3; | 1197 | border: 1px solid #3375A3; |
| @@ -1229,23 +1200,20 @@ QDateEdit | |||
| 1229 | min-width: 75px; | 1200 | min-width: 75px; |
| 1230 | } | 1201 | } |
| 1231 | 1202 | ||
| 1232 | QDateEdit:on | 1203 | QDateEdit:on { |
| 1233 | { | ||
| 1234 | padding-top: 3px; | 1204 | padding-top: 3px; |
| 1235 | padding-left: 4px; | 1205 | padding-left: 4px; |
| 1236 | selection-background-color: #4a4a4a; | 1206 | selection-background-color: #4a4a4a; |
| 1237 | } | 1207 | } |
| 1238 | 1208 | ||
| 1239 | QDateEdit QAbstractItemView | 1209 | QDateEdit QAbstractItemView { |
| 1240 | { | ||
| 1241 | background-color: #232629; | 1210 | background-color: #232629; |
| 1242 | border-radius: 2px; | 1211 | border-radius: 2px; |
| 1243 | border: 1px solid #3375A3; | 1212 | border: 1px solid #3375A3; |
| 1244 | selection-background-color: #3daee9; | 1213 | selection-background-color: #3daee9; |
| 1245 | } | 1214 | } |
| 1246 | 1215 | ||
| 1247 | QDateEdit::drop-down | 1216 | QDateEdit::drop-down { |
| 1248 | { | ||
| 1249 | subcontrol-origin: padding; | 1217 | subcontrol-origin: padding; |
| 1250 | subcontrol-position: top right; | 1218 | subcontrol-position: top right; |
| 1251 | width: 15px; | 1219 | width: 15px; |
| @@ -1256,13 +1224,12 @@ QDateEdit::drop-down | |||
| 1256 | border-bottom-right-radius: 3px; | 1224 | border-bottom-right-radius: 3px; |
| 1257 | } | 1225 | } |
| 1258 | 1226 | ||
| 1259 | QDateEdit::down-arrow | 1227 | QDateEdit::down-arrow { |
| 1260 | { | ||
| 1261 | image: url(:/qss_icons/rc/down_arrow_disabled.png); | 1228 | image: url(:/qss_icons/rc/down_arrow_disabled.png); |
| 1262 | } | 1229 | } |
| 1263 | 1230 | ||
| 1264 | QDateEdit::down-arrow:on, QDateEdit::down-arrow:hover, | 1231 | QDateEdit::down-arrow:on, |
| 1265 | QDateEdit::down-arrow:focus | 1232 | QDateEdit::down-arrow:hover, |
| 1266 | { | 1233 | QDateEdit::down-arrow:focus { |
| 1267 | image: url(:/qss_icons/rc/down_arrow.png); | 1234 | image: url(:/qss_icons/rc/down_arrow.png); |
| 1268 | } | 1235 | } |
diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index d2b0652a5..db21f3d50 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt | |||
| @@ -35,6 +35,10 @@ set(LZ4_BUNDLED_MODE ON) | |||
| 35 | add_subdirectory(lz4/contrib/cmake_unofficial) | 35 | add_subdirectory(lz4/contrib/cmake_unofficial) |
| 36 | target_include_directories(lz4_static INTERFACE ./lz4/lib) | 36 | target_include_directories(lz4_static INTERFACE ./lz4/lib) |
| 37 | 37 | ||
| 38 | # mbedtls | ||
| 39 | add_subdirectory(mbedtls EXCLUDE_FROM_ALL) | ||
| 40 | target_include_directories(mbedtls PUBLIC ./mbedtls/include) | ||
| 41 | |||
| 38 | # MicroProfile | 42 | # MicroProfile |
| 39 | add_library(microprofile INTERFACE) | 43 | add_library(microprofile INTERFACE) |
| 40 | target_include_directories(microprofile INTERFACE ./microprofile) | 44 | target_include_directories(microprofile INTERFACE ./microprofile) |
| @@ -50,3 +54,13 @@ if (ARCHITECTURE_x86_64) | |||
| 50 | target_include_directories(xbyak INTERFACE ./xbyak/xbyak) | 54 | target_include_directories(xbyak INTERFACE ./xbyak/xbyak) |
| 51 | target_compile_definitions(xbyak INTERFACE XBYAK_NO_OP_NAMES) | 55 | target_compile_definitions(xbyak INTERFACE XBYAK_NO_OP_NAMES) |
| 52 | endif() | 56 | endif() |
| 57 | |||
| 58 | # Opus | ||
| 59 | add_subdirectory(opus) | ||
| 60 | target_include_directories(opus INTERFACE ./opus/include) | ||
| 61 | |||
| 62 | # Cubeb | ||
| 63 | if(ENABLE_CUBEB) | ||
| 64 | set(BUILD_TESTS OFF CACHE BOOL "") | ||
| 65 | add_subdirectory(cubeb EXCLUDE_FROM_ALL) | ||
| 66 | endif() | ||
diff --git a/externals/cubeb b/externals/cubeb new file mode 160000 | |||
| Subproject 12b78c0edfa40007e41dbdcd9dfe367fbb98d01 | |||
diff --git a/externals/dynarmic b/externals/dynarmic | |||
| Subproject 98e23801297167db1fd266696484a49096e734c | Subproject 4f96c63025af34c1490c59f6729497b9866ffa3 | ||
diff --git a/externals/glad/include/glad/glad.h b/externals/glad/include/glad/glad.h index 5f4b962d9..fd41dc702 100644 --- a/externals/glad/include/glad/glad.h +++ b/externals/glad/include/glad/glad.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | 2 | ||
| 3 | OpenGL loader generated by glad 0.1.25 on Fri Jul 20 07:59:28 2018. | 3 | OpenGL loader generated by glad 0.1.26 on Tue Aug 7 08:21:50 2018. |
| 4 | 4 | ||
| 5 | Language/Generator: C/C++ | 5 | Language/Generator: C/C++ |
| 6 | Specification: gl | 6 | Specification: gl |
| @@ -15,6 +15,7 @@ | |||
| 15 | GL_AMD_debug_output, | 15 | GL_AMD_debug_output, |
| 16 | GL_AMD_depth_clamp_separate, | 16 | GL_AMD_depth_clamp_separate, |
| 17 | GL_AMD_draw_buffers_blend, | 17 | GL_AMD_draw_buffers_blend, |
| 18 | GL_AMD_framebuffer_multisample_advanced, | ||
| 18 | GL_AMD_framebuffer_sample_positions, | 19 | GL_AMD_framebuffer_sample_positions, |
| 19 | GL_AMD_gcn_shader, | 20 | GL_AMD_gcn_shader, |
| 20 | GL_AMD_gpu_shader_half_float, | 21 | GL_AMD_gpu_shader_half_float, |
| @@ -600,7 +601,7 @@ | |||
| 600 | Omit khrplatform: False | 601 | Omit khrplatform: False |
| 601 | 602 | ||
| 602 | Commandline: | 603 | Commandline: |
| 603 | --profile="core" --api="gl=3.3" --generator="c" --spec="gl" --extensions="GL_3DFX_multisample,GL_3DFX_tbuffer,GL_3DFX_texture_compression_FXT1,GL_AMD_blend_minmax_factor,GL_AMD_conservative_depth,GL_AMD_debug_output,GL_AMD_depth_clamp_separate,GL_AMD_draw_buffers_blend,GL_AMD_framebuffer_sample_positions,GL_AMD_gcn_shader,GL_AMD_gpu_shader_half_float,GL_AMD_gpu_shader_int16,GL_AMD_gpu_shader_int64,GL_AMD_interleaved_elements,GL_AMD_multi_draw_indirect,GL_AMD_name_gen_delete,GL_AMD_occlusion_query_event,GL_AMD_performance_monitor,GL_AMD_pinned_memory,GL_AMD_query_buffer_object,GL_AMD_sample_positions,GL_AMD_seamless_cubemap_per_texture,GL_AMD_shader_atomic_counter_ops,GL_AMD_shader_ballot,GL_AMD_shader_explicit_vertex_parameter,GL_AMD_shader_gpu_shader_half_float_fetch,GL_AMD_shader_image_load_store_lod,GL_AMD_shader_stencil_export,GL_AMD_shader_trinary_minmax,GL_AMD_sparse_texture,GL_AMD_stencil_operation_extended,GL_AMD_texture_gather_bias_lod,GL_AMD_texture_texture4,GL_AMD_transform_feedback3_lines_triangles,GL_AMD_transform_feedback4,GL_AMD_vertex_shader_layer,GL_AMD_vertex_shader_tessellator,GL_AMD_vertex_shader_viewport_index,GL_APPLE_aux_depth_stencil,GL_APPLE_client_storage,GL_APPLE_element_array,GL_APPLE_fence,GL_APPLE_float_pixels,GL_APPLE_flush_buffer_range,GL_APPLE_object_purgeable,GL_APPLE_rgb_422,GL_APPLE_row_bytes,GL_APPLE_specular_vector,GL_APPLE_texture_range,GL_APPLE_transform_hint,GL_APPLE_vertex_array_object,GL_APPLE_vertex_array_range,GL_APPLE_vertex_program_evaluators,GL_APPLE_ycbcr_422,GL_ARB_ES2_compatibility,GL_ARB_ES3_1_compatibility,GL_ARB_ES3_2_compatibility,GL_ARB_ES3_compatibility,GL_ARB_arrays_of_arrays,GL_ARB_base_instance,GL_ARB_bindless_texture,GL_ARB_blend_func_extended,GL_ARB_buffer_storage,GL_ARB_cl_event,GL_ARB_clear_buffer_object,GL_ARB_clear_texture,GL_ARB_clip_control,GL_ARB_color_buffer_float,GL_ARB_compatibility,GL_ARB_compressed_texture_pixel_storage,GL_ARB_compute_shader,GL_ARB_compute_variable_group_size,GL_ARB_conditional_render_inverted,GL_ARB_conservative_depth,GL_ARB_copy_buffer,GL_ARB_copy_image,GL_ARB_cull_distance,GL_ARB_debug_output,GL_ARB_depth_buffer_float,GL_ARB_depth_clamp,GL_ARB_depth_texture,GL_ARB_derivative_control,GL_ARB_direct_state_access,GL_ARB_draw_buffers,GL_ARB_draw_buffers_blend,GL_ARB_draw_elements_base_vertex,GL_ARB_draw_indirect,GL_ARB_draw_instanced,GL_ARB_enhanced_layouts,GL_ARB_explicit_attrib_location,GL_ARB_explicit_uniform_location,GL_ARB_fragment_coord_conventions,GL_ARB_fragment_layer_viewport,GL_ARB_fragment_program,GL_ARB_fragment_program_shadow,GL_ARB_fragment_shader,GL_ARB_fragment_shader_interlock,GL_ARB_framebuffer_no_attachments,GL_ARB_framebuffer_object,GL_ARB_framebuffer_sRGB,GL_ARB_geometry_shader4,GL_ARB_get_program_binary,GL_ARB_get_texture_sub_image,GL_ARB_gl_spirv,GL_ARB_gpu_shader5,GL_ARB_gpu_shader_fp64,GL_ARB_gpu_shader_int64,GL_ARB_half_float_pixel,GL_ARB_half_float_vertex,GL_ARB_imaging,GL_ARB_indirect_parameters,GL_ARB_instanced_arrays,GL_ARB_internalformat_query,GL_ARB_internalformat_query2,GL_ARB_invalidate_subdata,GL_ARB_map_buffer_alignment,GL_ARB_map_buffer_range,GL_ARB_matrix_palette,GL_ARB_multi_bind,GL_ARB_multi_draw_indirect,GL_ARB_multisample,GL_ARB_multitexture,GL_ARB_occlusion_query,GL_ARB_occlusion_query2,GL_ARB_parallel_shader_compile,GL_ARB_pipeline_statistics_query,GL_ARB_pixel_buffer_object,GL_ARB_point_parameters,GL_ARB_point_sprite,GL_ARB_polygon_offset_clamp,GL_ARB_post_depth_coverage,GL_ARB_program_interface_query,GL_ARB_provoking_vertex,GL_ARB_query_buffer_object,GL_ARB_robust_buffer_access_behavior,GL_ARB_robustness,GL_ARB_robustness_isolation,GL_ARB_sample_locations,GL_ARB_sample_shading,GL_ARB_sampler_objects,GL_ARB_seamless_cube_map,GL_ARB_seamless_cubemap_per_texture,GL_ARB_separate_shader_objects,GL_ARB_shader_atomic_counter_ops,GL_ARB_shader_atomic_counters,GL_ARB_shader_ballot,GL_ARB_shader_bit_encoding,GL_ARB_shader_clock,GL_ARB_shader_draw_parameters,GL_ARB_shader_group_vote,GL_ARB_shader_image_load_store,GL_ARB_shader_image_size,GL_ARB_shader_objects,GL_ARB_shader_precision,GL_ARB_shader_stencil_export,GL_ARB_shader_storage_buffer_object,GL_ARB_shader_subroutine,GL_ARB_shader_texture_image_samples,GL_ARB_shader_texture_lod,GL_ARB_shader_viewport_layer_array,GL_ARB_shading_language_100,GL_ARB_shading_language_420pack,GL_ARB_shading_language_include,GL_ARB_shading_language_packing,GL_ARB_shadow,GL_ARB_shadow_ambient,GL_ARB_sparse_buffer,GL_ARB_sparse_texture,GL_ARB_sparse_texture2,GL_ARB_sparse_texture_clamp,GL_ARB_spirv_extensions,GL_ARB_stencil_texturing,GL_ARB_sync,GL_ARB_tessellation_shader,GL_ARB_texture_barrier,GL_ARB_texture_border_clamp,GL_ARB_texture_buffer_object,GL_ARB_texture_buffer_object_rgb32,GL_ARB_texture_buffer_range,GL_ARB_texture_compression,GL_ARB_texture_compression_bptc,GL_ARB_texture_compression_rgtc,GL_ARB_texture_cube_map,GL_ARB_texture_cube_map_array,GL_ARB_texture_env_add,GL_ARB_texture_env_combine,GL_ARB_texture_env_crossbar,GL_ARB_texture_env_dot3,GL_ARB_texture_filter_anisotropic,GL_ARB_texture_filter_minmax,GL_ARB_texture_float,GL_ARB_texture_gather,GL_ARB_texture_mirror_clamp_to_edge,GL_ARB_texture_mirrored_repeat,GL_ARB_texture_multisample,GL_ARB_texture_non_power_of_two,GL_ARB_texture_query_levels,GL_ARB_texture_query_lod,GL_ARB_texture_rectangle,GL_ARB_texture_rg,GL_ARB_texture_rgb10_a2ui,GL_ARB_texture_stencil8,GL_ARB_texture_storage,GL_ARB_texture_storage_multisample,GL_ARB_texture_swizzle,GL_ARB_texture_view,GL_ARB_timer_query,GL_ARB_transform_feedback2,GL_ARB_transform_feedback3,GL_ARB_transform_feedback_instanced,GL_ARB_transform_feedback_overflow_query,GL_ARB_transpose_matrix,GL_ARB_uniform_buffer_object,GL_ARB_vertex_array_bgra,GL_ARB_vertex_array_object,GL_ARB_vertex_attrib_64bit,GL_ARB_vertex_attrib_binding,GL_ARB_vertex_blend,GL_ARB_vertex_buffer_object,GL_ARB_vertex_program,GL_ARB_vertex_shader,GL_ARB_vertex_type_10f_11f_11f_rev,GL_ARB_vertex_type_2_10_10_10_rev,GL_ARB_viewport_array,GL_ARB_window_pos,GL_ATI_draw_buffers,GL_ATI_element_array,GL_ATI_envmap_bumpmap,GL_ATI_fragment_shader,GL_ATI_map_object_buffer,GL_ATI_meminfo,GL_ATI_pixel_format_float,GL_ATI_pn_triangles,GL_ATI_separate_stencil,GL_ATI_text_fragment_shader,GL_ATI_texture_env_combine3,GL_ATI_texture_float,GL_ATI_texture_mirror_once,GL_ATI_vertex_array_object,GL_ATI_vertex_attrib_array_object,GL_ATI_vertex_streams,GL_EXT_422_pixels,GL_EXT_EGL_image_storage,GL_EXT_abgr,GL_EXT_bgra,GL_EXT_bindable_uniform,GL_EXT_blend_color,GL_EXT_blend_equation_separate,GL_EXT_blend_func_separate,GL_EXT_blend_logic_op,GL_EXT_blend_minmax,GL_EXT_blend_subtract,GL_EXT_clip_volume_hint,GL_EXT_cmyka,GL_EXT_color_subtable,GL_EXT_compiled_vertex_array,GL_EXT_convolution,GL_EXT_coordinate_frame,GL_EXT_copy_texture,GL_EXT_cull_vertex,GL_EXT_debug_label,GL_EXT_debug_marker,GL_EXT_depth_bounds_test,GL_EXT_direct_state_access,GL_EXT_draw_buffers2,GL_EXT_draw_instanced,GL_EXT_draw_range_elements,GL_EXT_external_buffer,GL_EXT_fog_coord,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_multisample_blit_scaled,GL_EXT_framebuffer_object,GL_EXT_framebuffer_sRGB,GL_EXT_geometry_shader4,GL_EXT_gpu_program_parameters,GL_EXT_gpu_shader4,GL_EXT_histogram,GL_EXT_index_array_formats,GL_EXT_index_func,GL_EXT_index_material,GL_EXT_index_texture,GL_EXT_light_texture,GL_EXT_memory_object,GL_EXT_memory_object_fd,GL_EXT_memory_object_win32,GL_EXT_misc_attribute,GL_EXT_multi_draw_arrays,GL_EXT_multisample,GL_EXT_packed_depth_stencil,GL_EXT_packed_float,GL_EXT_packed_pixels,GL_EXT_paletted_texture,GL_EXT_pixel_buffer_object,GL_EXT_pixel_transform,GL_EXT_pixel_transform_color_table,GL_EXT_point_parameters,GL_EXT_polygon_offset,GL_EXT_polygon_offset_clamp,GL_EXT_post_depth_coverage,GL_EXT_provoking_vertex,GL_EXT_raster_multisample,GL_EXT_rescale_normal,GL_EXT_secondary_color,GL_EXT_semaphore,GL_EXT_semaphore_fd,GL_EXT_semaphore_win32,GL_EXT_separate_shader_objects,GL_EXT_separate_specular_color,GL_EXT_shader_framebuffer_fetch,GL_EXT_shader_framebuffer_fetch_non_coherent,GL_EXT_shader_image_load_formatted,GL_EXT_shader_image_load_store,GL_EXT_shader_integer_mix,GL_EXT_shadow_funcs,GL_EXT_shared_texture_palette,GL_EXT_sparse_texture2,GL_EXT_stencil_clear_tag,GL_EXT_stencil_two_side,GL_EXT_stencil_wrap,GL_EXT_subtexture,GL_EXT_texture,GL_EXT_texture3D,GL_EXT_texture_array,GL_EXT_texture_buffer_object,GL_EXT_texture_compression_latc,GL_EXT_texture_compression_rgtc,GL_EXT_texture_compression_s3tc,GL_EXT_texture_cube_map,GL_EXT_texture_env_add,GL_EXT_texture_env_combine,GL_EXT_texture_env_dot3,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_filter_minmax,GL_EXT_texture_integer,GL_EXT_texture_lod_bias,GL_EXT_texture_mirror_clamp,GL_EXT_texture_object,GL_EXT_texture_perturb_normal,GL_EXT_texture_sRGB,GL_EXT_texture_sRGB_decode,GL_EXT_texture_shared_exponent,GL_EXT_texture_snorm,GL_EXT_texture_swizzle,GL_EXT_timer_query,GL_EXT_transform_feedback,GL_EXT_vertex_array,GL_EXT_vertex_array_bgra,GL_EXT_vertex_attrib_64bit,GL_EXT_vertex_shader,GL_EXT_vertex_weighting,GL_EXT_win32_keyed_mutex,GL_EXT_window_rectangles,GL_EXT_x11_sync_object,GL_GREMEDY_frame_terminator,GL_GREMEDY_string_marker,GL_HP_convolution_border_modes,GL_HP_image_transform,GL_HP_occlusion_test,GL_HP_texture_lighting,GL_IBM_cull_vertex,GL_IBM_multimode_draw_arrays,GL_IBM_rasterpos_clip,GL_IBM_static_data,GL_IBM_texture_mirrored_repeat,GL_IBM_vertex_array_lists,GL_INGR_blend_func_separate,GL_INGR_color_clamp,GL_INGR_interlace_read,GL_INTEL_blackhole_render,GL_INTEL_conservative_rasterization,GL_INTEL_fragment_shader_ordering,GL_INTEL_framebuffer_CMAA,GL_INTEL_map_texture,GL_INTEL_parallel_arrays,GL_INTEL_performance_query,GL_KHR_blend_equation_advanced,GL_KHR_blend_equation_advanced_coherent,GL_KHR_context_flush_control,GL_KHR_debug,GL_KHR_no_error,GL_KHR_parallel_shader_compile,GL_KHR_robust_buffer_access_behavior,GL_KHR_robustness,GL_KHR_texture_compression_astc_hdr,GL_KHR_texture_compression_astc_ldr,GL_KHR_texture_compression_astc_sliced_3d,GL_MESAX_texture_stack,GL_MESA_pack_invert,GL_MESA_program_binary_formats,GL_MESA_resize_buffers,GL_MESA_shader_integer_functions,GL_MESA_tile_raster_order,GL_MESA_window_pos,GL_MESA_ycbcr_texture,GL_NVX_blend_equation_advanced_multi_draw_buffers,GL_NVX_conditional_render,GL_NVX_gpu_memory_info,GL_NVX_linked_gpu_multicast,GL_NV_alpha_to_coverage_dither_control,GL_NV_bindless_multi_draw_indirect,GL_NV_bindless_multi_draw_indirect_count,GL_NV_bindless_texture,GL_NV_blend_equation_advanced,GL_NV_blend_equation_advanced_coherent,GL_NV_blend_minmax_factor,GL_NV_blend_square,GL_NV_clip_space_w_scaling,GL_NV_command_list,GL_NV_compute_program5,GL_NV_conditional_render,GL_NV_conservative_raster,GL_NV_conservative_raster_dilate,GL_NV_conservative_raster_pre_snap,GL_NV_conservative_raster_pre_snap_triangles,GL_NV_conservative_raster_underestimation,GL_NV_copy_depth_to_color,GL_NV_copy_image,GL_NV_deep_texture3D,GL_NV_depth_buffer_float,GL_NV_depth_clamp,GL_NV_draw_texture,GL_NV_draw_vulkan_image,GL_NV_evaluators,GL_NV_explicit_multisample,GL_NV_fence,GL_NV_fill_rectangle,GL_NV_float_buffer,GL_NV_fog_distance,GL_NV_fragment_coverage_to_color,GL_NV_fragment_program,GL_NV_fragment_program2,GL_NV_fragment_program4,GL_NV_fragment_program_option,GL_NV_fragment_shader_interlock,GL_NV_framebuffer_mixed_samples,GL_NV_framebuffer_multisample_coverage,GL_NV_geometry_program4,GL_NV_geometry_shader4,GL_NV_geometry_shader_passthrough,GL_NV_gpu_multicast,GL_NV_gpu_program4,GL_NV_gpu_program5,GL_NV_gpu_program5_mem_extended,GL_NV_gpu_shader5,GL_NV_half_float,GL_NV_internalformat_sample_query,GL_NV_light_max_exponent,GL_NV_multisample_coverage,GL_NV_multisample_filter_hint,GL_NV_occlusion_query,GL_NV_packed_depth_stencil,GL_NV_parameter_buffer_object,GL_NV_parameter_buffer_object2,GL_NV_path_rendering,GL_NV_path_rendering_shared_edge,GL_NV_pixel_data_range,GL_NV_point_sprite,GL_NV_present_video,GL_NV_primitive_restart,GL_NV_query_resource,GL_NV_query_resource_tag,GL_NV_register_combiners,GL_NV_register_combiners2,GL_NV_robustness_video_memory_purge,GL_NV_sample_locations,GL_NV_sample_mask_override_coverage,GL_NV_shader_atomic_counters,GL_NV_shader_atomic_float,GL_NV_shader_atomic_float64,GL_NV_shader_atomic_fp16_vector,GL_NV_shader_atomic_int64,GL_NV_shader_buffer_load,GL_NV_shader_buffer_store,GL_NV_shader_storage_buffer_object,GL_NV_shader_thread_group,GL_NV_shader_thread_shuffle,GL_NV_stereo_view_rendering,GL_NV_tessellation_program5,GL_NV_texgen_emboss,GL_NV_texgen_reflection,GL_NV_texture_barrier,GL_NV_texture_compression_vtc,GL_NV_texture_env_combine4,GL_NV_texture_expand_normal,GL_NV_texture_multisample,GL_NV_texture_rectangle,GL_NV_texture_rectangle_compressed,GL_NV_texture_shader,GL_NV_texture_shader2,GL_NV_texture_shader3,GL_NV_transform_feedback,GL_NV_transform_feedback2,GL_NV_uniform_buffer_unified_memory,GL_NV_vdpau_interop,GL_NV_vertex_array_range,GL_NV_vertex_array_range2,GL_NV_vertex_attrib_integer_64bit,GL_NV_vertex_buffer_unified_memory,GL_NV_vertex_program,GL_NV_vertex_program1_1,GL_NV_vertex_program2,GL_NV_vertex_program2_option,GL_NV_vertex_program3,GL_NV_vertex_program4,GL_NV_video_capture,GL_NV_viewport_array2,GL_NV_viewport_swizzle,GL_OES_byte_coordinates,GL_OES_compressed_paletted_texture,GL_OES_fixed_point,GL_OES_query_matrix,GL_OES_read_format,GL_OES_single_precision,GL_OML_interlace,GL_OML_resample,GL_OML_subsample,GL_OVR_multiview,GL_OVR_multiview2,GL_PGI_misc_hints,GL_PGI_vertex_hints,GL_REND_screen_coordinates,GL_S3_s3tc,GL_SGIS_detail_texture,GL_SGIS_fog_function,GL_SGIS_generate_mipmap,GL_SGIS_multisample,GL_SGIS_pixel_texture,GL_SGIS_point_line_texgen,GL_SGIS_point_parameters,GL_SGIS_sharpen_texture,GL_SGIS_texture4D,GL_SGIS_texture_border_clamp,GL_SGIS_texture_color_mask,GL_SGIS_texture_edge_clamp,GL_SGIS_texture_filter4,GL_SGIS_texture_lod,GL_SGIS_texture_select,GL_SGIX_async,GL_SGIX_async_histogram,GL_SGIX_async_pixel,GL_SGIX_blend_alpha_minmax,GL_SGIX_calligraphic_fragment,GL_SGIX_clipmap,GL_SGIX_convolution_accuracy,GL_SGIX_depth_pass_instrument,GL_SGIX_depth_texture,GL_SGIX_flush_raster,GL_SGIX_fog_offset,GL_SGIX_fragment_lighting,GL_SGIX_framezoom,GL_SGIX_igloo_interface,GL_SGIX_instruments,GL_SGIX_interlace,GL_SGIX_ir_instrument1,GL_SGIX_list_priority,GL_SGIX_pixel_texture,GL_SGIX_pixel_tiles,GL_SGIX_polynomial_ffd,GL_SGIX_reference_plane,GL_SGIX_resample,GL_SGIX_scalebias_hint,GL_SGIX_shadow,GL_SGIX_shadow_ambient,GL_SGIX_sprite,GL_SGIX_subsample,GL_SGIX_tag_sample_buffer,GL_SGIX_texture_add_env,GL_SGIX_texture_coordinate_clamp,GL_SGIX_texture_lod_bias,GL_SGIX_texture_multi_buffer,GL_SGIX_texture_scale_bias,GL_SGIX_vertex_preclip,GL_SGIX_ycrcb,GL_SGIX_ycrcb_subsample,GL_SGIX_ycrcba,GL_SGI_color_matrix,GL_SGI_color_table,GL_SGI_texture_color_table,GL_SUNX_constant_data,GL_SUN_convolution_border_modes,GL_SUN_global_alpha,GL_SUN_mesh_array,GL_SUN_slice_accum,GL_SUN_triangle_list,GL_SUN_vertex,GL_WIN_phong_shading,GL_WIN_specular_fog" | 604 | --profile="core" --api="gl=3.3" --generator="c" --spec="gl" --extensions="GL_3DFX_multisample,GL_3DFX_tbuffer,GL_3DFX_texture_compression_FXT1,GL_AMD_blend_minmax_factor,GL_AMD_conservative_depth,GL_AMD_debug_output,GL_AMD_depth_clamp_separate,GL_AMD_draw_buffers_blend,GL_AMD_framebuffer_multisample_advanced,GL_AMD_framebuffer_sample_positions,GL_AMD_gcn_shader,GL_AMD_gpu_shader_half_float,GL_AMD_gpu_shader_int16,GL_AMD_gpu_shader_int64,GL_AMD_interleaved_elements,GL_AMD_multi_draw_indirect,GL_AMD_name_gen_delete,GL_AMD_occlusion_query_event,GL_AMD_performance_monitor,GL_AMD_pinned_memory,GL_AMD_query_buffer_object,GL_AMD_sample_positions,GL_AMD_seamless_cubemap_per_texture,GL_AMD_shader_atomic_counter_ops,GL_AMD_shader_ballot,GL_AMD_shader_explicit_vertex_parameter,GL_AMD_shader_gpu_shader_half_float_fetch,GL_AMD_shader_image_load_store_lod,GL_AMD_shader_stencil_export,GL_AMD_shader_trinary_minmax,GL_AMD_sparse_texture,GL_AMD_stencil_operation_extended,GL_AMD_texture_gather_bias_lod,GL_AMD_texture_texture4,GL_AMD_transform_feedback3_lines_triangles,GL_AMD_transform_feedback4,GL_AMD_vertex_shader_layer,GL_AMD_vertex_shader_tessellator,GL_AMD_vertex_shader_viewport_index,GL_APPLE_aux_depth_stencil,GL_APPLE_client_storage,GL_APPLE_element_array,GL_APPLE_fence,GL_APPLE_float_pixels,GL_APPLE_flush_buffer_range,GL_APPLE_object_purgeable,GL_APPLE_rgb_422,GL_APPLE_row_bytes,GL_APPLE_specular_vector,GL_APPLE_texture_range,GL_APPLE_transform_hint,GL_APPLE_vertex_array_object,GL_APPLE_vertex_array_range,GL_APPLE_vertex_program_evaluators,GL_APPLE_ycbcr_422,GL_ARB_ES2_compatibility,GL_ARB_ES3_1_compatibility,GL_ARB_ES3_2_compatibility,GL_ARB_ES3_compatibility,GL_ARB_arrays_of_arrays,GL_ARB_base_instance,GL_ARB_bindless_texture,GL_ARB_blend_func_extended,GL_ARB_buffer_storage,GL_ARB_cl_event,GL_ARB_clear_buffer_object,GL_ARB_clear_texture,GL_ARB_clip_control,GL_ARB_color_buffer_float,GL_ARB_compatibility,GL_ARB_compressed_texture_pixel_storage,GL_ARB_compute_shader,GL_ARB_compute_variable_group_size,GL_ARB_conditional_render_inverted,GL_ARB_conservative_depth,GL_ARB_copy_buffer,GL_ARB_copy_image,GL_ARB_cull_distance,GL_ARB_debug_output,GL_ARB_depth_buffer_float,GL_ARB_depth_clamp,GL_ARB_depth_texture,GL_ARB_derivative_control,GL_ARB_direct_state_access,GL_ARB_draw_buffers,GL_ARB_draw_buffers_blend,GL_ARB_draw_elements_base_vertex,GL_ARB_draw_indirect,GL_ARB_draw_instanced,GL_ARB_enhanced_layouts,GL_ARB_explicit_attrib_location,GL_ARB_explicit_uniform_location,GL_ARB_fragment_coord_conventions,GL_ARB_fragment_layer_viewport,GL_ARB_fragment_program,GL_ARB_fragment_program_shadow,GL_ARB_fragment_shader,GL_ARB_fragment_shader_interlock,GL_ARB_framebuffer_no_attachments,GL_ARB_framebuffer_object,GL_ARB_framebuffer_sRGB,GL_ARB_geometry_shader4,GL_ARB_get_program_binary,GL_ARB_get_texture_sub_image,GL_ARB_gl_spirv,GL_ARB_gpu_shader5,GL_ARB_gpu_shader_fp64,GL_ARB_gpu_shader_int64,GL_ARB_half_float_pixel,GL_ARB_half_float_vertex,GL_ARB_imaging,GL_ARB_indirect_parameters,GL_ARB_instanced_arrays,GL_ARB_internalformat_query,GL_ARB_internalformat_query2,GL_ARB_invalidate_subdata,GL_ARB_map_buffer_alignment,GL_ARB_map_buffer_range,GL_ARB_matrix_palette,GL_ARB_multi_bind,GL_ARB_multi_draw_indirect,GL_ARB_multisample,GL_ARB_multitexture,GL_ARB_occlusion_query,GL_ARB_occlusion_query2,GL_ARB_parallel_shader_compile,GL_ARB_pipeline_statistics_query,GL_ARB_pixel_buffer_object,GL_ARB_point_parameters,GL_ARB_point_sprite,GL_ARB_polygon_offset_clamp,GL_ARB_post_depth_coverage,GL_ARB_program_interface_query,GL_ARB_provoking_vertex,GL_ARB_query_buffer_object,GL_ARB_robust_buffer_access_behavior,GL_ARB_robustness,GL_ARB_robustness_isolation,GL_ARB_sample_locations,GL_ARB_sample_shading,GL_ARB_sampler_objects,GL_ARB_seamless_cube_map,GL_ARB_seamless_cubemap_per_texture,GL_ARB_separate_shader_objects,GL_ARB_shader_atomic_counter_ops,GL_ARB_shader_atomic_counters,GL_ARB_shader_ballot,GL_ARB_shader_bit_encoding,GL_ARB_shader_clock,GL_ARB_shader_draw_parameters,GL_ARB_shader_group_vote,GL_ARB_shader_image_load_store,GL_ARB_shader_image_size,GL_ARB_shader_objects,GL_ARB_shader_precision,GL_ARB_shader_stencil_export,GL_ARB_shader_storage_buffer_object,GL_ARB_shader_subroutine,GL_ARB_shader_texture_image_samples,GL_ARB_shader_texture_lod,GL_ARB_shader_viewport_layer_array,GL_ARB_shading_language_100,GL_ARB_shading_language_420pack,GL_ARB_shading_language_include,GL_ARB_shading_language_packing,GL_ARB_shadow,GL_ARB_shadow_ambient,GL_ARB_sparse_buffer,GL_ARB_sparse_texture,GL_ARB_sparse_texture2,GL_ARB_sparse_texture_clamp,GL_ARB_spirv_extensions,GL_ARB_stencil_texturing,GL_ARB_sync,GL_ARB_tessellation_shader,GL_ARB_texture_barrier,GL_ARB_texture_border_clamp,GL_ARB_texture_buffer_object,GL_ARB_texture_buffer_object_rgb32,GL_ARB_texture_buffer_range,GL_ARB_texture_compression,GL_ARB_texture_compression_bptc,GL_ARB_texture_compression_rgtc,GL_ARB_texture_cube_map,GL_ARB_texture_cube_map_array,GL_ARB_texture_env_add,GL_ARB_texture_env_combine,GL_ARB_texture_env_crossbar,GL_ARB_texture_env_dot3,GL_ARB_texture_filter_anisotropic,GL_ARB_texture_filter_minmax,GL_ARB_texture_float,GL_ARB_texture_gather,GL_ARB_texture_mirror_clamp_to_edge,GL_ARB_texture_mirrored_repeat,GL_ARB_texture_multisample,GL_ARB_texture_non_power_of_two,GL_ARB_texture_query_levels,GL_ARB_texture_query_lod,GL_ARB_texture_rectangle,GL_ARB_texture_rg,GL_ARB_texture_rgb10_a2ui,GL_ARB_texture_stencil8,GL_ARB_texture_storage,GL_ARB_texture_storage_multisample,GL_ARB_texture_swizzle,GL_ARB_texture_view,GL_ARB_timer_query,GL_ARB_transform_feedback2,GL_ARB_transform_feedback3,GL_ARB_transform_feedback_instanced,GL_ARB_transform_feedback_overflow_query,GL_ARB_transpose_matrix,GL_ARB_uniform_buffer_object,GL_ARB_vertex_array_bgra,GL_ARB_vertex_array_object,GL_ARB_vertex_attrib_64bit,GL_ARB_vertex_attrib_binding,GL_ARB_vertex_blend,GL_ARB_vertex_buffer_object,GL_ARB_vertex_program,GL_ARB_vertex_shader,GL_ARB_vertex_type_10f_11f_11f_rev,GL_ARB_vertex_type_2_10_10_10_rev,GL_ARB_viewport_array,GL_ARB_window_pos,GL_ATI_draw_buffers,GL_ATI_element_array,GL_ATI_envmap_bumpmap,GL_ATI_fragment_shader,GL_ATI_map_object_buffer,GL_ATI_meminfo,GL_ATI_pixel_format_float,GL_ATI_pn_triangles,GL_ATI_separate_stencil,GL_ATI_text_fragment_shader,GL_ATI_texture_env_combine3,GL_ATI_texture_float,GL_ATI_texture_mirror_once,GL_ATI_vertex_array_object,GL_ATI_vertex_attrib_array_object,GL_ATI_vertex_streams,GL_EXT_422_pixels,GL_EXT_EGL_image_storage,GL_EXT_abgr,GL_EXT_bgra,GL_EXT_bindable_uniform,GL_EXT_blend_color,GL_EXT_blend_equation_separate,GL_EXT_blend_func_separate,GL_EXT_blend_logic_op,GL_EXT_blend_minmax,GL_EXT_blend_subtract,GL_EXT_clip_volume_hint,GL_EXT_cmyka,GL_EXT_color_subtable,GL_EXT_compiled_vertex_array,GL_EXT_convolution,GL_EXT_coordinate_frame,GL_EXT_copy_texture,GL_EXT_cull_vertex,GL_EXT_debug_label,GL_EXT_debug_marker,GL_EXT_depth_bounds_test,GL_EXT_direct_state_access,GL_EXT_draw_buffers2,GL_EXT_draw_instanced,GL_EXT_draw_range_elements,GL_EXT_external_buffer,GL_EXT_fog_coord,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_multisample_blit_scaled,GL_EXT_framebuffer_object,GL_EXT_framebuffer_sRGB,GL_EXT_geometry_shader4,GL_EXT_gpu_program_parameters,GL_EXT_gpu_shader4,GL_EXT_histogram,GL_EXT_index_array_formats,GL_EXT_index_func,GL_EXT_index_material,GL_EXT_index_texture,GL_EXT_light_texture,GL_EXT_memory_object,GL_EXT_memory_object_fd,GL_EXT_memory_object_win32,GL_EXT_misc_attribute,GL_EXT_multi_draw_arrays,GL_EXT_multisample,GL_EXT_packed_depth_stencil,GL_EXT_packed_float,GL_EXT_packed_pixels,GL_EXT_paletted_texture,GL_EXT_pixel_buffer_object,GL_EXT_pixel_transform,GL_EXT_pixel_transform_color_table,GL_EXT_point_parameters,GL_EXT_polygon_offset,GL_EXT_polygon_offset_clamp,GL_EXT_post_depth_coverage,GL_EXT_provoking_vertex,GL_EXT_raster_multisample,GL_EXT_rescale_normal,GL_EXT_secondary_color,GL_EXT_semaphore,GL_EXT_semaphore_fd,GL_EXT_semaphore_win32,GL_EXT_separate_shader_objects,GL_EXT_separate_specular_color,GL_EXT_shader_framebuffer_fetch,GL_EXT_shader_framebuffer_fetch_non_coherent,GL_EXT_shader_image_load_formatted,GL_EXT_shader_image_load_store,GL_EXT_shader_integer_mix,GL_EXT_shadow_funcs,GL_EXT_shared_texture_palette,GL_EXT_sparse_texture2,GL_EXT_stencil_clear_tag,GL_EXT_stencil_two_side,GL_EXT_stencil_wrap,GL_EXT_subtexture,GL_EXT_texture,GL_EXT_texture3D,GL_EXT_texture_array,GL_EXT_texture_buffer_object,GL_EXT_texture_compression_latc,GL_EXT_texture_compression_rgtc,GL_EXT_texture_compression_s3tc,GL_EXT_texture_cube_map,GL_EXT_texture_env_add,GL_EXT_texture_env_combine,GL_EXT_texture_env_dot3,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_filter_minmax,GL_EXT_texture_integer,GL_EXT_texture_lod_bias,GL_EXT_texture_mirror_clamp,GL_EXT_texture_object,GL_EXT_texture_perturb_normal,GL_EXT_texture_sRGB,GL_EXT_texture_sRGB_decode,GL_EXT_texture_shared_exponent,GL_EXT_texture_snorm,GL_EXT_texture_swizzle,GL_EXT_timer_query,GL_EXT_transform_feedback,GL_EXT_vertex_array,GL_EXT_vertex_array_bgra,GL_EXT_vertex_attrib_64bit,GL_EXT_vertex_shader,GL_EXT_vertex_weighting,GL_EXT_win32_keyed_mutex,GL_EXT_window_rectangles,GL_EXT_x11_sync_object,GL_GREMEDY_frame_terminator,GL_GREMEDY_string_marker,GL_HP_convolution_border_modes,GL_HP_image_transform,GL_HP_occlusion_test,GL_HP_texture_lighting,GL_IBM_cull_vertex,GL_IBM_multimode_draw_arrays,GL_IBM_rasterpos_clip,GL_IBM_static_data,GL_IBM_texture_mirrored_repeat,GL_IBM_vertex_array_lists,GL_INGR_blend_func_separate,GL_INGR_color_clamp,GL_INGR_interlace_read,GL_INTEL_blackhole_render,GL_INTEL_conservative_rasterization,GL_INTEL_fragment_shader_ordering,GL_INTEL_framebuffer_CMAA,GL_INTEL_map_texture,GL_INTEL_parallel_arrays,GL_INTEL_performance_query,GL_KHR_blend_equation_advanced,GL_KHR_blend_equation_advanced_coherent,GL_KHR_context_flush_control,GL_KHR_debug,GL_KHR_no_error,GL_KHR_parallel_shader_compile,GL_KHR_robust_buffer_access_behavior,GL_KHR_robustness,GL_KHR_texture_compression_astc_hdr,GL_KHR_texture_compression_astc_ldr,GL_KHR_texture_compression_astc_sliced_3d,GL_MESAX_texture_stack,GL_MESA_pack_invert,GL_MESA_program_binary_formats,GL_MESA_resize_buffers,GL_MESA_shader_integer_functions,GL_MESA_tile_raster_order,GL_MESA_window_pos,GL_MESA_ycbcr_texture,GL_NVX_blend_equation_advanced_multi_draw_buffers,GL_NVX_conditional_render,GL_NVX_gpu_memory_info,GL_NVX_linked_gpu_multicast,GL_NV_alpha_to_coverage_dither_control,GL_NV_bindless_multi_draw_indirect,GL_NV_bindless_multi_draw_indirect_count,GL_NV_bindless_texture,GL_NV_blend_equation_advanced,GL_NV_blend_equation_advanced_coherent,GL_NV_blend_minmax_factor,GL_NV_blend_square,GL_NV_clip_space_w_scaling,GL_NV_command_list,GL_NV_compute_program5,GL_NV_conditional_render,GL_NV_conservative_raster,GL_NV_conservative_raster_dilate,GL_NV_conservative_raster_pre_snap,GL_NV_conservative_raster_pre_snap_triangles,GL_NV_conservative_raster_underestimation,GL_NV_copy_depth_to_color,GL_NV_copy_image,GL_NV_deep_texture3D,GL_NV_depth_buffer_float,GL_NV_depth_clamp,GL_NV_draw_texture,GL_NV_draw_vulkan_image,GL_NV_evaluators,GL_NV_explicit_multisample,GL_NV_fence,GL_NV_fill_rectangle,GL_NV_float_buffer,GL_NV_fog_distance,GL_NV_fragment_coverage_to_color,GL_NV_fragment_program,GL_NV_fragment_program2,GL_NV_fragment_program4,GL_NV_fragment_program_option,GL_NV_fragment_shader_interlock,GL_NV_framebuffer_mixed_samples,GL_NV_framebuffer_multisample_coverage,GL_NV_geometry_program4,GL_NV_geometry_shader4,GL_NV_geometry_shader_passthrough,GL_NV_gpu_multicast,GL_NV_gpu_program4,GL_NV_gpu_program5,GL_NV_gpu_program5_mem_extended,GL_NV_gpu_shader5,GL_NV_half_float,GL_NV_internalformat_sample_query,GL_NV_light_max_exponent,GL_NV_multisample_coverage,GL_NV_multisample_filter_hint,GL_NV_occlusion_query,GL_NV_packed_depth_stencil,GL_NV_parameter_buffer_object,GL_NV_parameter_buffer_object2,GL_NV_path_rendering,GL_NV_path_rendering_shared_edge,GL_NV_pixel_data_range,GL_NV_point_sprite,GL_NV_present_video,GL_NV_primitive_restart,GL_NV_query_resource,GL_NV_query_resource_tag,GL_NV_register_combiners,GL_NV_register_combiners2,GL_NV_robustness_video_memory_purge,GL_NV_sample_locations,GL_NV_sample_mask_override_coverage,GL_NV_shader_atomic_counters,GL_NV_shader_atomic_float,GL_NV_shader_atomic_float64,GL_NV_shader_atomic_fp16_vector,GL_NV_shader_atomic_int64,GL_NV_shader_buffer_load,GL_NV_shader_buffer_store,GL_NV_shader_storage_buffer_object,GL_NV_shader_thread_group,GL_NV_shader_thread_shuffle,GL_NV_stereo_view_rendering,GL_NV_tessellation_program5,GL_NV_texgen_emboss,GL_NV_texgen_reflection,GL_NV_texture_barrier,GL_NV_texture_compression_vtc,GL_NV_texture_env_combine4,GL_NV_texture_expand_normal,GL_NV_texture_multisample,GL_NV_texture_rectangle,GL_NV_texture_rectangle_compressed,GL_NV_texture_shader,GL_NV_texture_shader2,GL_NV_texture_shader3,GL_NV_transform_feedback,GL_NV_transform_feedback2,GL_NV_uniform_buffer_unified_memory,GL_NV_vdpau_interop,GL_NV_vertex_array_range,GL_NV_vertex_array_range2,GL_NV_vertex_attrib_integer_64bit,GL_NV_vertex_buffer_unified_memory,GL_NV_vertex_program,GL_NV_vertex_program1_1,GL_NV_vertex_program2,GL_NV_vertex_program2_option,GL_NV_vertex_program3,GL_NV_vertex_program4,GL_NV_video_capture,GL_NV_viewport_array2,GL_NV_viewport_swizzle,GL_OES_byte_coordinates,GL_OES_compressed_paletted_texture,GL_OES_fixed_point,GL_OES_query_matrix,GL_OES_read_format,GL_OES_single_precision,GL_OML_interlace,GL_OML_resample,GL_OML_subsample,GL_OVR_multiview,GL_OVR_multiview2,GL_PGI_misc_hints,GL_PGI_vertex_hints,GL_REND_screen_coordinates,GL_S3_s3tc,GL_SGIS_detail_texture,GL_SGIS_fog_function,GL_SGIS_generate_mipmap,GL_SGIS_multisample,GL_SGIS_pixel_texture,GL_SGIS_point_line_texgen,GL_SGIS_point_parameters,GL_SGIS_sharpen_texture,GL_SGIS_texture4D,GL_SGIS_texture_border_clamp,GL_SGIS_texture_color_mask,GL_SGIS_texture_edge_clamp,GL_SGIS_texture_filter4,GL_SGIS_texture_lod,GL_SGIS_texture_select,GL_SGIX_async,GL_SGIX_async_histogram,GL_SGIX_async_pixel,GL_SGIX_blend_alpha_minmax,GL_SGIX_calligraphic_fragment,GL_SGIX_clipmap,GL_SGIX_convolution_accuracy,GL_SGIX_depth_pass_instrument,GL_SGIX_depth_texture,GL_SGIX_flush_raster,GL_SGIX_fog_offset,GL_SGIX_fragment_lighting,GL_SGIX_framezoom,GL_SGIX_igloo_interface,GL_SGIX_instruments,GL_SGIX_interlace,GL_SGIX_ir_instrument1,GL_SGIX_list_priority,GL_SGIX_pixel_texture,GL_SGIX_pixel_tiles,GL_SGIX_polynomial_ffd,GL_SGIX_reference_plane,GL_SGIX_resample,GL_SGIX_scalebias_hint,GL_SGIX_shadow,GL_SGIX_shadow_ambient,GL_SGIX_sprite,GL_SGIX_subsample,GL_SGIX_tag_sample_buffer,GL_SGIX_texture_add_env,GL_SGIX_texture_coordinate_clamp,GL_SGIX_texture_lod_bias,GL_SGIX_texture_multi_buffer,GL_SGIX_texture_scale_bias,GL_SGIX_vertex_preclip,GL_SGIX_ycrcb,GL_SGIX_ycrcb_subsample,GL_SGIX_ycrcba,GL_SGI_color_matrix,GL_SGI_color_table,GL_SGI_texture_color_table,GL_SUNX_constant_data,GL_SUN_convolution_border_modes,GL_SUN_global_alpha,GL_SUN_mesh_array,GL_SUN_slice_accum,GL_SUN_triangle_list,GL_SUN_vertex,GL_WIN_phong_shading,GL_WIN_specular_fog" |
| 604 | Online: | 605 | Online: |
| 605 | Too many extensions | 606 | Too many extensions |
| 606 | */ | 607 | */ |
| @@ -1409,7 +1410,6 @@ typedef void (APIENTRY *GLVULKANPROCNV)(void); | |||
| 1409 | #define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 | 1410 | #define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 |
| 1410 | #define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 | 1411 | #define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 |
| 1411 | #define GL_MAX_SAMPLES 0x8D57 | 1412 | #define GL_MAX_SAMPLES 0x8D57 |
| 1412 | #define GL_INDEX 0x8222 | ||
| 1413 | #define GL_FRAMEBUFFER_SRGB 0x8DB9 | 1413 | #define GL_FRAMEBUFFER_SRGB 0x8DB9 |
| 1414 | #define GL_HALF_FLOAT 0x140B | 1414 | #define GL_HALF_FLOAT 0x140B |
| 1415 | #define GL_MAP_READ_BIT 0x0001 | 1415 | #define GL_MAP_READ_BIT 0x0001 |
| @@ -2780,6 +2780,12 @@ GLAPI PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv; | |||
| 2780 | #define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150 | 2780 | #define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150 |
| 2781 | #define GL_DEPTH_CLAMP_NEAR_AMD 0x901E | 2781 | #define GL_DEPTH_CLAMP_NEAR_AMD 0x901E |
| 2782 | #define GL_DEPTH_CLAMP_FAR_AMD 0x901F | 2782 | #define GL_DEPTH_CLAMP_FAR_AMD 0x901F |
| 2783 | #define GL_RENDERBUFFER_STORAGE_SAMPLES_AMD 0x91B2 | ||
| 2784 | #define GL_MAX_COLOR_FRAMEBUFFER_SAMPLES_AMD 0x91B3 | ||
| 2785 | #define GL_MAX_COLOR_FRAMEBUFFER_STORAGE_SAMPLES_AMD 0x91B4 | ||
| 2786 | #define GL_MAX_DEPTH_STENCIL_FRAMEBUFFER_SAMPLES_AMD 0x91B5 | ||
| 2787 | #define GL_NUM_SUPPORTED_MULTISAMPLE_MODES_AMD 0x91B6 | ||
| 2788 | #define GL_SUPPORTED_MULTISAMPLE_MODES_AMD 0x91B7 | ||
| 2783 | #define GL_SUBSAMPLE_DISTANCE_AMD 0x883F | 2789 | #define GL_SUBSAMPLE_DISTANCE_AMD 0x883F |
| 2784 | #define GL_PIXELS_PER_SAMPLE_PATTERN_X_AMD 0x91AE | 2790 | #define GL_PIXELS_PER_SAMPLE_PATTERN_X_AMD 0x91AE |
| 2785 | #define GL_PIXELS_PER_SAMPLE_PATTERN_Y_AMD 0x91AF | 2791 | #define GL_PIXELS_PER_SAMPLE_PATTERN_Y_AMD 0x91AF |
| @@ -3157,6 +3163,7 @@ GLAPI PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv; | |||
| 3157 | #define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316 | 3163 | #define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316 |
| 3158 | #define GL_MAX_FRAMEBUFFER_LAYERS 0x9317 | 3164 | #define GL_MAX_FRAMEBUFFER_LAYERS 0x9317 |
| 3159 | #define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318 | 3165 | #define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318 |
| 3166 | #define GL_INDEX 0x8222 | ||
| 3160 | #define GL_LINES_ADJACENCY_ARB 0x000A | 3167 | #define GL_LINES_ADJACENCY_ARB 0x000A |
| 3161 | #define GL_LINE_STRIP_ADJACENCY_ARB 0x000B | 3168 | #define GL_LINE_STRIP_ADJACENCY_ARB 0x000B |
| 3162 | #define GL_TRIANGLES_ADJACENCY_ARB 0x000C | 3169 | #define GL_TRIANGLES_ADJACENCY_ARB 0x000C |
| @@ -6433,6 +6440,16 @@ typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC)(GLuint buf, GL | |||
| 6433 | GLAPI PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC glad_glBlendEquationSeparateIndexedAMD; | 6440 | GLAPI PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC glad_glBlendEquationSeparateIndexedAMD; |
| 6434 | #define glBlendEquationSeparateIndexedAMD glad_glBlendEquationSeparateIndexedAMD | 6441 | #define glBlendEquationSeparateIndexedAMD glad_glBlendEquationSeparateIndexedAMD |
| 6435 | #endif | 6442 | #endif |
| 6443 | #ifndef GL_AMD_framebuffer_multisample_advanced | ||
| 6444 | #define GL_AMD_framebuffer_multisample_advanced 1 | ||
| 6445 | GLAPI int GLAD_GL_AMD_framebuffer_multisample_advanced; | ||
| 6446 | typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC)(GLenum target, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height); | ||
| 6447 | GLAPI PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC glad_glRenderbufferStorageMultisampleAdvancedAMD; | ||
| 6448 | #define glRenderbufferStorageMultisampleAdvancedAMD glad_glRenderbufferStorageMultisampleAdvancedAMD | ||
| 6449 | typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC)(GLuint renderbuffer, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height); | ||
| 6450 | GLAPI PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC glad_glNamedRenderbufferStorageMultisampleAdvancedAMD; | ||
| 6451 | #define glNamedRenderbufferStorageMultisampleAdvancedAMD glad_glNamedRenderbufferStorageMultisampleAdvancedAMD | ||
| 6452 | #endif | ||
| 6436 | #ifndef GL_AMD_framebuffer_sample_positions | 6453 | #ifndef GL_AMD_framebuffer_sample_positions |
| 6437 | #define GL_AMD_framebuffer_sample_positions 1 | 6454 | #define GL_AMD_framebuffer_sample_positions 1 |
| 6438 | GLAPI int GLAD_GL_AMD_framebuffer_sample_positions; | 6455 | GLAPI int GLAD_GL_AMD_framebuffer_sample_positions; |
diff --git a/externals/glad/src/glad.c b/externals/glad/src/glad.c index 13607e449..1cf0890b9 100644 --- a/externals/glad/src/glad.c +++ b/externals/glad/src/glad.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | 2 | ||
| 3 | OpenGL loader generated by glad 0.1.25 on Fri Jul 20 07:59:28 2018. | 3 | OpenGL loader generated by glad 0.1.26 on Tue Aug 7 08:21:50 2018. |
| 4 | 4 | ||
| 5 | Language/Generator: C/C++ | 5 | Language/Generator: C/C++ |
| 6 | Specification: gl | 6 | Specification: gl |
| @@ -15,6 +15,7 @@ | |||
| 15 | GL_AMD_debug_output, | 15 | GL_AMD_debug_output, |
| 16 | GL_AMD_depth_clamp_separate, | 16 | GL_AMD_depth_clamp_separate, |
| 17 | GL_AMD_draw_buffers_blend, | 17 | GL_AMD_draw_buffers_blend, |
| 18 | GL_AMD_framebuffer_multisample_advanced, | ||
| 18 | GL_AMD_framebuffer_sample_positions, | 19 | GL_AMD_framebuffer_sample_positions, |
| 19 | GL_AMD_gcn_shader, | 20 | GL_AMD_gcn_shader, |
| 20 | GL_AMD_gpu_shader_half_float, | 21 | GL_AMD_gpu_shader_half_float, |
| @@ -600,7 +601,7 @@ | |||
| 600 | Omit khrplatform: False | 601 | Omit khrplatform: False |
| 601 | 602 | ||
| 602 | Commandline: | 603 | Commandline: |
| 603 | --profile="core" --api="gl=3.3" --generator="c" --spec="gl" --extensions="GL_3DFX_multisample,GL_3DFX_tbuffer,GL_3DFX_texture_compression_FXT1,GL_AMD_blend_minmax_factor,GL_AMD_conservative_depth,GL_AMD_debug_output,GL_AMD_depth_clamp_separate,GL_AMD_draw_buffers_blend,GL_AMD_framebuffer_sample_positions,GL_AMD_gcn_shader,GL_AMD_gpu_shader_half_float,GL_AMD_gpu_shader_int16,GL_AMD_gpu_shader_int64,GL_AMD_interleaved_elements,GL_AMD_multi_draw_indirect,GL_AMD_name_gen_delete,GL_AMD_occlusion_query_event,GL_AMD_performance_monitor,GL_AMD_pinned_memory,GL_AMD_query_buffer_object,GL_AMD_sample_positions,GL_AMD_seamless_cubemap_per_texture,GL_AMD_shader_atomic_counter_ops,GL_AMD_shader_ballot,GL_AMD_shader_explicit_vertex_parameter,GL_AMD_shader_gpu_shader_half_float_fetch,GL_AMD_shader_image_load_store_lod,GL_AMD_shader_stencil_export,GL_AMD_shader_trinary_minmax,GL_AMD_sparse_texture,GL_AMD_stencil_operation_extended,GL_AMD_texture_gather_bias_lod,GL_AMD_texture_texture4,GL_AMD_transform_feedback3_lines_triangles,GL_AMD_transform_feedback4,GL_AMD_vertex_shader_layer,GL_AMD_vertex_shader_tessellator,GL_AMD_vertex_shader_viewport_index,GL_APPLE_aux_depth_stencil,GL_APPLE_client_storage,GL_APPLE_element_array,GL_APPLE_fence,GL_APPLE_float_pixels,GL_APPLE_flush_buffer_range,GL_APPLE_object_purgeable,GL_APPLE_rgb_422,GL_APPLE_row_bytes,GL_APPLE_specular_vector,GL_APPLE_texture_range,GL_APPLE_transform_hint,GL_APPLE_vertex_array_object,GL_APPLE_vertex_array_range,GL_APPLE_vertex_program_evaluators,GL_APPLE_ycbcr_422,GL_ARB_ES2_compatibility,GL_ARB_ES3_1_compatibility,GL_ARB_ES3_2_compatibility,GL_ARB_ES3_compatibility,GL_ARB_arrays_of_arrays,GL_ARB_base_instance,GL_ARB_bindless_texture,GL_ARB_blend_func_extended,GL_ARB_buffer_storage,GL_ARB_cl_event,GL_ARB_clear_buffer_object,GL_ARB_clear_texture,GL_ARB_clip_control,GL_ARB_color_buffer_float,GL_ARB_compatibility,GL_ARB_compressed_texture_pixel_storage,GL_ARB_compute_shader,GL_ARB_compute_variable_group_size,GL_ARB_conditional_render_inverted,GL_ARB_conservative_depth,GL_ARB_copy_buffer,GL_ARB_copy_image,GL_ARB_cull_distance,GL_ARB_debug_output,GL_ARB_depth_buffer_float,GL_ARB_depth_clamp,GL_ARB_depth_texture,GL_ARB_derivative_control,GL_ARB_direct_state_access,GL_ARB_draw_buffers,GL_ARB_draw_buffers_blend,GL_ARB_draw_elements_base_vertex,GL_ARB_draw_indirect,GL_ARB_draw_instanced,GL_ARB_enhanced_layouts,GL_ARB_explicit_attrib_location,GL_ARB_explicit_uniform_location,GL_ARB_fragment_coord_conventions,GL_ARB_fragment_layer_viewport,GL_ARB_fragment_program,GL_ARB_fragment_program_shadow,GL_ARB_fragment_shader,GL_ARB_fragment_shader_interlock,GL_ARB_framebuffer_no_attachments,GL_ARB_framebuffer_object,GL_ARB_framebuffer_sRGB,GL_ARB_geometry_shader4,GL_ARB_get_program_binary,GL_ARB_get_texture_sub_image,GL_ARB_gl_spirv,GL_ARB_gpu_shader5,GL_ARB_gpu_shader_fp64,GL_ARB_gpu_shader_int64,GL_ARB_half_float_pixel,GL_ARB_half_float_vertex,GL_ARB_imaging,GL_ARB_indirect_parameters,GL_ARB_instanced_arrays,GL_ARB_internalformat_query,GL_ARB_internalformat_query2,GL_ARB_invalidate_subdata,GL_ARB_map_buffer_alignment,GL_ARB_map_buffer_range,GL_ARB_matrix_palette,GL_ARB_multi_bind,GL_ARB_multi_draw_indirect,GL_ARB_multisample,GL_ARB_multitexture,GL_ARB_occlusion_query,GL_ARB_occlusion_query2,GL_ARB_parallel_shader_compile,GL_ARB_pipeline_statistics_query,GL_ARB_pixel_buffer_object,GL_ARB_point_parameters,GL_ARB_point_sprite,GL_ARB_polygon_offset_clamp,GL_ARB_post_depth_coverage,GL_ARB_program_interface_query,GL_ARB_provoking_vertex,GL_ARB_query_buffer_object,GL_ARB_robust_buffer_access_behavior,GL_ARB_robustness,GL_ARB_robustness_isolation,GL_ARB_sample_locations,GL_ARB_sample_shading,GL_ARB_sampler_objects,GL_ARB_seamless_cube_map,GL_ARB_seamless_cubemap_per_texture,GL_ARB_separate_shader_objects,GL_ARB_shader_atomic_counter_ops,GL_ARB_shader_atomic_counters,GL_ARB_shader_ballot,GL_ARB_shader_bit_encoding,GL_ARB_shader_clock,GL_ARB_shader_draw_parameters,GL_ARB_shader_group_vote,GL_ARB_shader_image_load_store,GL_ARB_shader_image_size,GL_ARB_shader_objects,GL_ARB_shader_precision,GL_ARB_shader_stencil_export,GL_ARB_shader_storage_buffer_object,GL_ARB_shader_subroutine,GL_ARB_shader_texture_image_samples,GL_ARB_shader_texture_lod,GL_ARB_shader_viewport_layer_array,GL_ARB_shading_language_100,GL_ARB_shading_language_420pack,GL_ARB_shading_language_include,GL_ARB_shading_language_packing,GL_ARB_shadow,GL_ARB_shadow_ambient,GL_ARB_sparse_buffer,GL_ARB_sparse_texture,GL_ARB_sparse_texture2,GL_ARB_sparse_texture_clamp,GL_ARB_spirv_extensions,GL_ARB_stencil_texturing,GL_ARB_sync,GL_ARB_tessellation_shader,GL_ARB_texture_barrier,GL_ARB_texture_border_clamp,GL_ARB_texture_buffer_object,GL_ARB_texture_buffer_object_rgb32,GL_ARB_texture_buffer_range,GL_ARB_texture_compression,GL_ARB_texture_compression_bptc,GL_ARB_texture_compression_rgtc,GL_ARB_texture_cube_map,GL_ARB_texture_cube_map_array,GL_ARB_texture_env_add,GL_ARB_texture_env_combine,GL_ARB_texture_env_crossbar,GL_ARB_texture_env_dot3,GL_ARB_texture_filter_anisotropic,GL_ARB_texture_filter_minmax,GL_ARB_texture_float,GL_ARB_texture_gather,GL_ARB_texture_mirror_clamp_to_edge,GL_ARB_texture_mirrored_repeat,GL_ARB_texture_multisample,GL_ARB_texture_non_power_of_two,GL_ARB_texture_query_levels,GL_ARB_texture_query_lod,GL_ARB_texture_rectangle,GL_ARB_texture_rg,GL_ARB_texture_rgb10_a2ui,GL_ARB_texture_stencil8,GL_ARB_texture_storage,GL_ARB_texture_storage_multisample,GL_ARB_texture_swizzle,GL_ARB_texture_view,GL_ARB_timer_query,GL_ARB_transform_feedback2,GL_ARB_transform_feedback3,GL_ARB_transform_feedback_instanced,GL_ARB_transform_feedback_overflow_query,GL_ARB_transpose_matrix,GL_ARB_uniform_buffer_object,GL_ARB_vertex_array_bgra,GL_ARB_vertex_array_object,GL_ARB_vertex_attrib_64bit,GL_ARB_vertex_attrib_binding,GL_ARB_vertex_blend,GL_ARB_vertex_buffer_object,GL_ARB_vertex_program,GL_ARB_vertex_shader,GL_ARB_vertex_type_10f_11f_11f_rev,GL_ARB_vertex_type_2_10_10_10_rev,GL_ARB_viewport_array,GL_ARB_window_pos,GL_ATI_draw_buffers,GL_ATI_element_array,GL_ATI_envmap_bumpmap,GL_ATI_fragment_shader,GL_ATI_map_object_buffer,GL_ATI_meminfo,GL_ATI_pixel_format_float,GL_ATI_pn_triangles,GL_ATI_separate_stencil,GL_ATI_text_fragment_shader,GL_ATI_texture_env_combine3,GL_ATI_texture_float,GL_ATI_texture_mirror_once,GL_ATI_vertex_array_object,GL_ATI_vertex_attrib_array_object,GL_ATI_vertex_streams,GL_EXT_422_pixels,GL_EXT_EGL_image_storage,GL_EXT_abgr,GL_EXT_bgra,GL_EXT_bindable_uniform,GL_EXT_blend_color,GL_EXT_blend_equation_separate,GL_EXT_blend_func_separate,GL_EXT_blend_logic_op,GL_EXT_blend_minmax,GL_EXT_blend_subtract,GL_EXT_clip_volume_hint,GL_EXT_cmyka,GL_EXT_color_subtable,GL_EXT_compiled_vertex_array,GL_EXT_convolution,GL_EXT_coordinate_frame,GL_EXT_copy_texture,GL_EXT_cull_vertex,GL_EXT_debug_label,GL_EXT_debug_marker,GL_EXT_depth_bounds_test,GL_EXT_direct_state_access,GL_EXT_draw_buffers2,GL_EXT_draw_instanced,GL_EXT_draw_range_elements,GL_EXT_external_buffer,GL_EXT_fog_coord,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_multisample_blit_scaled,GL_EXT_framebuffer_object,GL_EXT_framebuffer_sRGB,GL_EXT_geometry_shader4,GL_EXT_gpu_program_parameters,GL_EXT_gpu_shader4,GL_EXT_histogram,GL_EXT_index_array_formats,GL_EXT_index_func,GL_EXT_index_material,GL_EXT_index_texture,GL_EXT_light_texture,GL_EXT_memory_object,GL_EXT_memory_object_fd,GL_EXT_memory_object_win32,GL_EXT_misc_attribute,GL_EXT_multi_draw_arrays,GL_EXT_multisample,GL_EXT_packed_depth_stencil,GL_EXT_packed_float,GL_EXT_packed_pixels,GL_EXT_paletted_texture,GL_EXT_pixel_buffer_object,GL_EXT_pixel_transform,GL_EXT_pixel_transform_color_table,GL_EXT_point_parameters,GL_EXT_polygon_offset,GL_EXT_polygon_offset_clamp,GL_EXT_post_depth_coverage,GL_EXT_provoking_vertex,GL_EXT_raster_multisample,GL_EXT_rescale_normal,GL_EXT_secondary_color,GL_EXT_semaphore,GL_EXT_semaphore_fd,GL_EXT_semaphore_win32,GL_EXT_separate_shader_objects,GL_EXT_separate_specular_color,GL_EXT_shader_framebuffer_fetch,GL_EXT_shader_framebuffer_fetch_non_coherent,GL_EXT_shader_image_load_formatted,GL_EXT_shader_image_load_store,GL_EXT_shader_integer_mix,GL_EXT_shadow_funcs,GL_EXT_shared_texture_palette,GL_EXT_sparse_texture2,GL_EXT_stencil_clear_tag,GL_EXT_stencil_two_side,GL_EXT_stencil_wrap,GL_EXT_subtexture,GL_EXT_texture,GL_EXT_texture3D,GL_EXT_texture_array,GL_EXT_texture_buffer_object,GL_EXT_texture_compression_latc,GL_EXT_texture_compression_rgtc,GL_EXT_texture_compression_s3tc,GL_EXT_texture_cube_map,GL_EXT_texture_env_add,GL_EXT_texture_env_combine,GL_EXT_texture_env_dot3,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_filter_minmax,GL_EXT_texture_integer,GL_EXT_texture_lod_bias,GL_EXT_texture_mirror_clamp,GL_EXT_texture_object,GL_EXT_texture_perturb_normal,GL_EXT_texture_sRGB,GL_EXT_texture_sRGB_decode,GL_EXT_texture_shared_exponent,GL_EXT_texture_snorm,GL_EXT_texture_swizzle,GL_EXT_timer_query,GL_EXT_transform_feedback,GL_EXT_vertex_array,GL_EXT_vertex_array_bgra,GL_EXT_vertex_attrib_64bit,GL_EXT_vertex_shader,GL_EXT_vertex_weighting,GL_EXT_win32_keyed_mutex,GL_EXT_window_rectangles,GL_EXT_x11_sync_object,GL_GREMEDY_frame_terminator,GL_GREMEDY_string_marker,GL_HP_convolution_border_modes,GL_HP_image_transform,GL_HP_occlusion_test,GL_HP_texture_lighting,GL_IBM_cull_vertex,GL_IBM_multimode_draw_arrays,GL_IBM_rasterpos_clip,GL_IBM_static_data,GL_IBM_texture_mirrored_repeat,GL_IBM_vertex_array_lists,GL_INGR_blend_func_separate,GL_INGR_color_clamp,GL_INGR_interlace_read,GL_INTEL_blackhole_render,GL_INTEL_conservative_rasterization,GL_INTEL_fragment_shader_ordering,GL_INTEL_framebuffer_CMAA,GL_INTEL_map_texture,GL_INTEL_parallel_arrays,GL_INTEL_performance_query,GL_KHR_blend_equation_advanced,GL_KHR_blend_equation_advanced_coherent,GL_KHR_context_flush_control,GL_KHR_debug,GL_KHR_no_error,GL_KHR_parallel_shader_compile,GL_KHR_robust_buffer_access_behavior,GL_KHR_robustness,GL_KHR_texture_compression_astc_hdr,GL_KHR_texture_compression_astc_ldr,GL_KHR_texture_compression_astc_sliced_3d,GL_MESAX_texture_stack,GL_MESA_pack_invert,GL_MESA_program_binary_formats,GL_MESA_resize_buffers,GL_MESA_shader_integer_functions,GL_MESA_tile_raster_order,GL_MESA_window_pos,GL_MESA_ycbcr_texture,GL_NVX_blend_equation_advanced_multi_draw_buffers,GL_NVX_conditional_render,GL_NVX_gpu_memory_info,GL_NVX_linked_gpu_multicast,GL_NV_alpha_to_coverage_dither_control,GL_NV_bindless_multi_draw_indirect,GL_NV_bindless_multi_draw_indirect_count,GL_NV_bindless_texture,GL_NV_blend_equation_advanced,GL_NV_blend_equation_advanced_coherent,GL_NV_blend_minmax_factor,GL_NV_blend_square,GL_NV_clip_space_w_scaling,GL_NV_command_list,GL_NV_compute_program5,GL_NV_conditional_render,GL_NV_conservative_raster,GL_NV_conservative_raster_dilate,GL_NV_conservative_raster_pre_snap,GL_NV_conservative_raster_pre_snap_triangles,GL_NV_conservative_raster_underestimation,GL_NV_copy_depth_to_color,GL_NV_copy_image,GL_NV_deep_texture3D,GL_NV_depth_buffer_float,GL_NV_depth_clamp,GL_NV_draw_texture,GL_NV_draw_vulkan_image,GL_NV_evaluators,GL_NV_explicit_multisample,GL_NV_fence,GL_NV_fill_rectangle,GL_NV_float_buffer,GL_NV_fog_distance,GL_NV_fragment_coverage_to_color,GL_NV_fragment_program,GL_NV_fragment_program2,GL_NV_fragment_program4,GL_NV_fragment_program_option,GL_NV_fragment_shader_interlock,GL_NV_framebuffer_mixed_samples,GL_NV_framebuffer_multisample_coverage,GL_NV_geometry_program4,GL_NV_geometry_shader4,GL_NV_geometry_shader_passthrough,GL_NV_gpu_multicast,GL_NV_gpu_program4,GL_NV_gpu_program5,GL_NV_gpu_program5_mem_extended,GL_NV_gpu_shader5,GL_NV_half_float,GL_NV_internalformat_sample_query,GL_NV_light_max_exponent,GL_NV_multisample_coverage,GL_NV_multisample_filter_hint,GL_NV_occlusion_query,GL_NV_packed_depth_stencil,GL_NV_parameter_buffer_object,GL_NV_parameter_buffer_object2,GL_NV_path_rendering,GL_NV_path_rendering_shared_edge,GL_NV_pixel_data_range,GL_NV_point_sprite,GL_NV_present_video,GL_NV_primitive_restart,GL_NV_query_resource,GL_NV_query_resource_tag,GL_NV_register_combiners,GL_NV_register_combiners2,GL_NV_robustness_video_memory_purge,GL_NV_sample_locations,GL_NV_sample_mask_override_coverage,GL_NV_shader_atomic_counters,GL_NV_shader_atomic_float,GL_NV_shader_atomic_float64,GL_NV_shader_atomic_fp16_vector,GL_NV_shader_atomic_int64,GL_NV_shader_buffer_load,GL_NV_shader_buffer_store,GL_NV_shader_storage_buffer_object,GL_NV_shader_thread_group,GL_NV_shader_thread_shuffle,GL_NV_stereo_view_rendering,GL_NV_tessellation_program5,GL_NV_texgen_emboss,GL_NV_texgen_reflection,GL_NV_texture_barrier,GL_NV_texture_compression_vtc,GL_NV_texture_env_combine4,GL_NV_texture_expand_normal,GL_NV_texture_multisample,GL_NV_texture_rectangle,GL_NV_texture_rectangle_compressed,GL_NV_texture_shader,GL_NV_texture_shader2,GL_NV_texture_shader3,GL_NV_transform_feedback,GL_NV_transform_feedback2,GL_NV_uniform_buffer_unified_memory,GL_NV_vdpau_interop,GL_NV_vertex_array_range,GL_NV_vertex_array_range2,GL_NV_vertex_attrib_integer_64bit,GL_NV_vertex_buffer_unified_memory,GL_NV_vertex_program,GL_NV_vertex_program1_1,GL_NV_vertex_program2,GL_NV_vertex_program2_option,GL_NV_vertex_program3,GL_NV_vertex_program4,GL_NV_video_capture,GL_NV_viewport_array2,GL_NV_viewport_swizzle,GL_OES_byte_coordinates,GL_OES_compressed_paletted_texture,GL_OES_fixed_point,GL_OES_query_matrix,GL_OES_read_format,GL_OES_single_precision,GL_OML_interlace,GL_OML_resample,GL_OML_subsample,GL_OVR_multiview,GL_OVR_multiview2,GL_PGI_misc_hints,GL_PGI_vertex_hints,GL_REND_screen_coordinates,GL_S3_s3tc,GL_SGIS_detail_texture,GL_SGIS_fog_function,GL_SGIS_generate_mipmap,GL_SGIS_multisample,GL_SGIS_pixel_texture,GL_SGIS_point_line_texgen,GL_SGIS_point_parameters,GL_SGIS_sharpen_texture,GL_SGIS_texture4D,GL_SGIS_texture_border_clamp,GL_SGIS_texture_color_mask,GL_SGIS_texture_edge_clamp,GL_SGIS_texture_filter4,GL_SGIS_texture_lod,GL_SGIS_texture_select,GL_SGIX_async,GL_SGIX_async_histogram,GL_SGIX_async_pixel,GL_SGIX_blend_alpha_minmax,GL_SGIX_calligraphic_fragment,GL_SGIX_clipmap,GL_SGIX_convolution_accuracy,GL_SGIX_depth_pass_instrument,GL_SGIX_depth_texture,GL_SGIX_flush_raster,GL_SGIX_fog_offset,GL_SGIX_fragment_lighting,GL_SGIX_framezoom,GL_SGIX_igloo_interface,GL_SGIX_instruments,GL_SGIX_interlace,GL_SGIX_ir_instrument1,GL_SGIX_list_priority,GL_SGIX_pixel_texture,GL_SGIX_pixel_tiles,GL_SGIX_polynomial_ffd,GL_SGIX_reference_plane,GL_SGIX_resample,GL_SGIX_scalebias_hint,GL_SGIX_shadow,GL_SGIX_shadow_ambient,GL_SGIX_sprite,GL_SGIX_subsample,GL_SGIX_tag_sample_buffer,GL_SGIX_texture_add_env,GL_SGIX_texture_coordinate_clamp,GL_SGIX_texture_lod_bias,GL_SGIX_texture_multi_buffer,GL_SGIX_texture_scale_bias,GL_SGIX_vertex_preclip,GL_SGIX_ycrcb,GL_SGIX_ycrcb_subsample,GL_SGIX_ycrcba,GL_SGI_color_matrix,GL_SGI_color_table,GL_SGI_texture_color_table,GL_SUNX_constant_data,GL_SUN_convolution_border_modes,GL_SUN_global_alpha,GL_SUN_mesh_array,GL_SUN_slice_accum,GL_SUN_triangle_list,GL_SUN_vertex,GL_WIN_phong_shading,GL_WIN_specular_fog" | 604 | --profile="core" --api="gl=3.3" --generator="c" --spec="gl" --extensions="GL_3DFX_multisample,GL_3DFX_tbuffer,GL_3DFX_texture_compression_FXT1,GL_AMD_blend_minmax_factor,GL_AMD_conservative_depth,GL_AMD_debug_output,GL_AMD_depth_clamp_separate,GL_AMD_draw_buffers_blend,GL_AMD_framebuffer_multisample_advanced,GL_AMD_framebuffer_sample_positions,GL_AMD_gcn_shader,GL_AMD_gpu_shader_half_float,GL_AMD_gpu_shader_int16,GL_AMD_gpu_shader_int64,GL_AMD_interleaved_elements,GL_AMD_multi_draw_indirect,GL_AMD_name_gen_delete,GL_AMD_occlusion_query_event,GL_AMD_performance_monitor,GL_AMD_pinned_memory,GL_AMD_query_buffer_object,GL_AMD_sample_positions,GL_AMD_seamless_cubemap_per_texture,GL_AMD_shader_atomic_counter_ops,GL_AMD_shader_ballot,GL_AMD_shader_explicit_vertex_parameter,GL_AMD_shader_gpu_shader_half_float_fetch,GL_AMD_shader_image_load_store_lod,GL_AMD_shader_stencil_export,GL_AMD_shader_trinary_minmax,GL_AMD_sparse_texture,GL_AMD_stencil_operation_extended,GL_AMD_texture_gather_bias_lod,GL_AMD_texture_texture4,GL_AMD_transform_feedback3_lines_triangles,GL_AMD_transform_feedback4,GL_AMD_vertex_shader_layer,GL_AMD_vertex_shader_tessellator,GL_AMD_vertex_shader_viewport_index,GL_APPLE_aux_depth_stencil,GL_APPLE_client_storage,GL_APPLE_element_array,GL_APPLE_fence,GL_APPLE_float_pixels,GL_APPLE_flush_buffer_range,GL_APPLE_object_purgeable,GL_APPLE_rgb_422,GL_APPLE_row_bytes,GL_APPLE_specular_vector,GL_APPLE_texture_range,GL_APPLE_transform_hint,GL_APPLE_vertex_array_object,GL_APPLE_vertex_array_range,GL_APPLE_vertex_program_evaluators,GL_APPLE_ycbcr_422,GL_ARB_ES2_compatibility,GL_ARB_ES3_1_compatibility,GL_ARB_ES3_2_compatibility,GL_ARB_ES3_compatibility,GL_ARB_arrays_of_arrays,GL_ARB_base_instance,GL_ARB_bindless_texture,GL_ARB_blend_func_extended,GL_ARB_buffer_storage,GL_ARB_cl_event,GL_ARB_clear_buffer_object,GL_ARB_clear_texture,GL_ARB_clip_control,GL_ARB_color_buffer_float,GL_ARB_compatibility,GL_ARB_compressed_texture_pixel_storage,GL_ARB_compute_shader,GL_ARB_compute_variable_group_size,GL_ARB_conditional_render_inverted,GL_ARB_conservative_depth,GL_ARB_copy_buffer,GL_ARB_copy_image,GL_ARB_cull_distance,GL_ARB_debug_output,GL_ARB_depth_buffer_float,GL_ARB_depth_clamp,GL_ARB_depth_texture,GL_ARB_derivative_control,GL_ARB_direct_state_access,GL_ARB_draw_buffers,GL_ARB_draw_buffers_blend,GL_ARB_draw_elements_base_vertex,GL_ARB_draw_indirect,GL_ARB_draw_instanced,GL_ARB_enhanced_layouts,GL_ARB_explicit_attrib_location,GL_ARB_explicit_uniform_location,GL_ARB_fragment_coord_conventions,GL_ARB_fragment_layer_viewport,GL_ARB_fragment_program,GL_ARB_fragment_program_shadow,GL_ARB_fragment_shader,GL_ARB_fragment_shader_interlock,GL_ARB_framebuffer_no_attachments,GL_ARB_framebuffer_object,GL_ARB_framebuffer_sRGB,GL_ARB_geometry_shader4,GL_ARB_get_program_binary,GL_ARB_get_texture_sub_image,GL_ARB_gl_spirv,GL_ARB_gpu_shader5,GL_ARB_gpu_shader_fp64,GL_ARB_gpu_shader_int64,GL_ARB_half_float_pixel,GL_ARB_half_float_vertex,GL_ARB_imaging,GL_ARB_indirect_parameters,GL_ARB_instanced_arrays,GL_ARB_internalformat_query,GL_ARB_internalformat_query2,GL_ARB_invalidate_subdata,GL_ARB_map_buffer_alignment,GL_ARB_map_buffer_range,GL_ARB_matrix_palette,GL_ARB_multi_bind,GL_ARB_multi_draw_indirect,GL_ARB_multisample,GL_ARB_multitexture,GL_ARB_occlusion_query,GL_ARB_occlusion_query2,GL_ARB_parallel_shader_compile,GL_ARB_pipeline_statistics_query,GL_ARB_pixel_buffer_object,GL_ARB_point_parameters,GL_ARB_point_sprite,GL_ARB_polygon_offset_clamp,GL_ARB_post_depth_coverage,GL_ARB_program_interface_query,GL_ARB_provoking_vertex,GL_ARB_query_buffer_object,GL_ARB_robust_buffer_access_behavior,GL_ARB_robustness,GL_ARB_robustness_isolation,GL_ARB_sample_locations,GL_ARB_sample_shading,GL_ARB_sampler_objects,GL_ARB_seamless_cube_map,GL_ARB_seamless_cubemap_per_texture,GL_ARB_separate_shader_objects,GL_ARB_shader_atomic_counter_ops,GL_ARB_shader_atomic_counters,GL_ARB_shader_ballot,GL_ARB_shader_bit_encoding,GL_ARB_shader_clock,GL_ARB_shader_draw_parameters,GL_ARB_shader_group_vote,GL_ARB_shader_image_load_store,GL_ARB_shader_image_size,GL_ARB_shader_objects,GL_ARB_shader_precision,GL_ARB_shader_stencil_export,GL_ARB_shader_storage_buffer_object,GL_ARB_shader_subroutine,GL_ARB_shader_texture_image_samples,GL_ARB_shader_texture_lod,GL_ARB_shader_viewport_layer_array,GL_ARB_shading_language_100,GL_ARB_shading_language_420pack,GL_ARB_shading_language_include,GL_ARB_shading_language_packing,GL_ARB_shadow,GL_ARB_shadow_ambient,GL_ARB_sparse_buffer,GL_ARB_sparse_texture,GL_ARB_sparse_texture2,GL_ARB_sparse_texture_clamp,GL_ARB_spirv_extensions,GL_ARB_stencil_texturing,GL_ARB_sync,GL_ARB_tessellation_shader,GL_ARB_texture_barrier,GL_ARB_texture_border_clamp,GL_ARB_texture_buffer_object,GL_ARB_texture_buffer_object_rgb32,GL_ARB_texture_buffer_range,GL_ARB_texture_compression,GL_ARB_texture_compression_bptc,GL_ARB_texture_compression_rgtc,GL_ARB_texture_cube_map,GL_ARB_texture_cube_map_array,GL_ARB_texture_env_add,GL_ARB_texture_env_combine,GL_ARB_texture_env_crossbar,GL_ARB_texture_env_dot3,GL_ARB_texture_filter_anisotropic,GL_ARB_texture_filter_minmax,GL_ARB_texture_float,GL_ARB_texture_gather,GL_ARB_texture_mirror_clamp_to_edge,GL_ARB_texture_mirrored_repeat,GL_ARB_texture_multisample,GL_ARB_texture_non_power_of_two,GL_ARB_texture_query_levels,GL_ARB_texture_query_lod,GL_ARB_texture_rectangle,GL_ARB_texture_rg,GL_ARB_texture_rgb10_a2ui,GL_ARB_texture_stencil8,GL_ARB_texture_storage,GL_ARB_texture_storage_multisample,GL_ARB_texture_swizzle,GL_ARB_texture_view,GL_ARB_timer_query,GL_ARB_transform_feedback2,GL_ARB_transform_feedback3,GL_ARB_transform_feedback_instanced,GL_ARB_transform_feedback_overflow_query,GL_ARB_transpose_matrix,GL_ARB_uniform_buffer_object,GL_ARB_vertex_array_bgra,GL_ARB_vertex_array_object,GL_ARB_vertex_attrib_64bit,GL_ARB_vertex_attrib_binding,GL_ARB_vertex_blend,GL_ARB_vertex_buffer_object,GL_ARB_vertex_program,GL_ARB_vertex_shader,GL_ARB_vertex_type_10f_11f_11f_rev,GL_ARB_vertex_type_2_10_10_10_rev,GL_ARB_viewport_array,GL_ARB_window_pos,GL_ATI_draw_buffers,GL_ATI_element_array,GL_ATI_envmap_bumpmap,GL_ATI_fragment_shader,GL_ATI_map_object_buffer,GL_ATI_meminfo,GL_ATI_pixel_format_float,GL_ATI_pn_triangles,GL_ATI_separate_stencil,GL_ATI_text_fragment_shader,GL_ATI_texture_env_combine3,GL_ATI_texture_float,GL_ATI_texture_mirror_once,GL_ATI_vertex_array_object,GL_ATI_vertex_attrib_array_object,GL_ATI_vertex_streams,GL_EXT_422_pixels,GL_EXT_EGL_image_storage,GL_EXT_abgr,GL_EXT_bgra,GL_EXT_bindable_uniform,GL_EXT_blend_color,GL_EXT_blend_equation_separate,GL_EXT_blend_func_separate,GL_EXT_blend_logic_op,GL_EXT_blend_minmax,GL_EXT_blend_subtract,GL_EXT_clip_volume_hint,GL_EXT_cmyka,GL_EXT_color_subtable,GL_EXT_compiled_vertex_array,GL_EXT_convolution,GL_EXT_coordinate_frame,GL_EXT_copy_texture,GL_EXT_cull_vertex,GL_EXT_debug_label,GL_EXT_debug_marker,GL_EXT_depth_bounds_test,GL_EXT_direct_state_access,GL_EXT_draw_buffers2,GL_EXT_draw_instanced,GL_EXT_draw_range_elements,GL_EXT_external_buffer,GL_EXT_fog_coord,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_multisample_blit_scaled,GL_EXT_framebuffer_object,GL_EXT_framebuffer_sRGB,GL_EXT_geometry_shader4,GL_EXT_gpu_program_parameters,GL_EXT_gpu_shader4,GL_EXT_histogram,GL_EXT_index_array_formats,GL_EXT_index_func,GL_EXT_index_material,GL_EXT_index_texture,GL_EXT_light_texture,GL_EXT_memory_object,GL_EXT_memory_object_fd,GL_EXT_memory_object_win32,GL_EXT_misc_attribute,GL_EXT_multi_draw_arrays,GL_EXT_multisample,GL_EXT_packed_depth_stencil,GL_EXT_packed_float,GL_EXT_packed_pixels,GL_EXT_paletted_texture,GL_EXT_pixel_buffer_object,GL_EXT_pixel_transform,GL_EXT_pixel_transform_color_table,GL_EXT_point_parameters,GL_EXT_polygon_offset,GL_EXT_polygon_offset_clamp,GL_EXT_post_depth_coverage,GL_EXT_provoking_vertex,GL_EXT_raster_multisample,GL_EXT_rescale_normal,GL_EXT_secondary_color,GL_EXT_semaphore,GL_EXT_semaphore_fd,GL_EXT_semaphore_win32,GL_EXT_separate_shader_objects,GL_EXT_separate_specular_color,GL_EXT_shader_framebuffer_fetch,GL_EXT_shader_framebuffer_fetch_non_coherent,GL_EXT_shader_image_load_formatted,GL_EXT_shader_image_load_store,GL_EXT_shader_integer_mix,GL_EXT_shadow_funcs,GL_EXT_shared_texture_palette,GL_EXT_sparse_texture2,GL_EXT_stencil_clear_tag,GL_EXT_stencil_two_side,GL_EXT_stencil_wrap,GL_EXT_subtexture,GL_EXT_texture,GL_EXT_texture3D,GL_EXT_texture_array,GL_EXT_texture_buffer_object,GL_EXT_texture_compression_latc,GL_EXT_texture_compression_rgtc,GL_EXT_texture_compression_s3tc,GL_EXT_texture_cube_map,GL_EXT_texture_env_add,GL_EXT_texture_env_combine,GL_EXT_texture_env_dot3,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_filter_minmax,GL_EXT_texture_integer,GL_EXT_texture_lod_bias,GL_EXT_texture_mirror_clamp,GL_EXT_texture_object,GL_EXT_texture_perturb_normal,GL_EXT_texture_sRGB,GL_EXT_texture_sRGB_decode,GL_EXT_texture_shared_exponent,GL_EXT_texture_snorm,GL_EXT_texture_swizzle,GL_EXT_timer_query,GL_EXT_transform_feedback,GL_EXT_vertex_array,GL_EXT_vertex_array_bgra,GL_EXT_vertex_attrib_64bit,GL_EXT_vertex_shader,GL_EXT_vertex_weighting,GL_EXT_win32_keyed_mutex,GL_EXT_window_rectangles,GL_EXT_x11_sync_object,GL_GREMEDY_frame_terminator,GL_GREMEDY_string_marker,GL_HP_convolution_border_modes,GL_HP_image_transform,GL_HP_occlusion_test,GL_HP_texture_lighting,GL_IBM_cull_vertex,GL_IBM_multimode_draw_arrays,GL_IBM_rasterpos_clip,GL_IBM_static_data,GL_IBM_texture_mirrored_repeat,GL_IBM_vertex_array_lists,GL_INGR_blend_func_separate,GL_INGR_color_clamp,GL_INGR_interlace_read,GL_INTEL_blackhole_render,GL_INTEL_conservative_rasterization,GL_INTEL_fragment_shader_ordering,GL_INTEL_framebuffer_CMAA,GL_INTEL_map_texture,GL_INTEL_parallel_arrays,GL_INTEL_performance_query,GL_KHR_blend_equation_advanced,GL_KHR_blend_equation_advanced_coherent,GL_KHR_context_flush_control,GL_KHR_debug,GL_KHR_no_error,GL_KHR_parallel_shader_compile,GL_KHR_robust_buffer_access_behavior,GL_KHR_robustness,GL_KHR_texture_compression_astc_hdr,GL_KHR_texture_compression_astc_ldr,GL_KHR_texture_compression_astc_sliced_3d,GL_MESAX_texture_stack,GL_MESA_pack_invert,GL_MESA_program_binary_formats,GL_MESA_resize_buffers,GL_MESA_shader_integer_functions,GL_MESA_tile_raster_order,GL_MESA_window_pos,GL_MESA_ycbcr_texture,GL_NVX_blend_equation_advanced_multi_draw_buffers,GL_NVX_conditional_render,GL_NVX_gpu_memory_info,GL_NVX_linked_gpu_multicast,GL_NV_alpha_to_coverage_dither_control,GL_NV_bindless_multi_draw_indirect,GL_NV_bindless_multi_draw_indirect_count,GL_NV_bindless_texture,GL_NV_blend_equation_advanced,GL_NV_blend_equation_advanced_coherent,GL_NV_blend_minmax_factor,GL_NV_blend_square,GL_NV_clip_space_w_scaling,GL_NV_command_list,GL_NV_compute_program5,GL_NV_conditional_render,GL_NV_conservative_raster,GL_NV_conservative_raster_dilate,GL_NV_conservative_raster_pre_snap,GL_NV_conservative_raster_pre_snap_triangles,GL_NV_conservative_raster_underestimation,GL_NV_copy_depth_to_color,GL_NV_copy_image,GL_NV_deep_texture3D,GL_NV_depth_buffer_float,GL_NV_depth_clamp,GL_NV_draw_texture,GL_NV_draw_vulkan_image,GL_NV_evaluators,GL_NV_explicit_multisample,GL_NV_fence,GL_NV_fill_rectangle,GL_NV_float_buffer,GL_NV_fog_distance,GL_NV_fragment_coverage_to_color,GL_NV_fragment_program,GL_NV_fragment_program2,GL_NV_fragment_program4,GL_NV_fragment_program_option,GL_NV_fragment_shader_interlock,GL_NV_framebuffer_mixed_samples,GL_NV_framebuffer_multisample_coverage,GL_NV_geometry_program4,GL_NV_geometry_shader4,GL_NV_geometry_shader_passthrough,GL_NV_gpu_multicast,GL_NV_gpu_program4,GL_NV_gpu_program5,GL_NV_gpu_program5_mem_extended,GL_NV_gpu_shader5,GL_NV_half_float,GL_NV_internalformat_sample_query,GL_NV_light_max_exponent,GL_NV_multisample_coverage,GL_NV_multisample_filter_hint,GL_NV_occlusion_query,GL_NV_packed_depth_stencil,GL_NV_parameter_buffer_object,GL_NV_parameter_buffer_object2,GL_NV_path_rendering,GL_NV_path_rendering_shared_edge,GL_NV_pixel_data_range,GL_NV_point_sprite,GL_NV_present_video,GL_NV_primitive_restart,GL_NV_query_resource,GL_NV_query_resource_tag,GL_NV_register_combiners,GL_NV_register_combiners2,GL_NV_robustness_video_memory_purge,GL_NV_sample_locations,GL_NV_sample_mask_override_coverage,GL_NV_shader_atomic_counters,GL_NV_shader_atomic_float,GL_NV_shader_atomic_float64,GL_NV_shader_atomic_fp16_vector,GL_NV_shader_atomic_int64,GL_NV_shader_buffer_load,GL_NV_shader_buffer_store,GL_NV_shader_storage_buffer_object,GL_NV_shader_thread_group,GL_NV_shader_thread_shuffle,GL_NV_stereo_view_rendering,GL_NV_tessellation_program5,GL_NV_texgen_emboss,GL_NV_texgen_reflection,GL_NV_texture_barrier,GL_NV_texture_compression_vtc,GL_NV_texture_env_combine4,GL_NV_texture_expand_normal,GL_NV_texture_multisample,GL_NV_texture_rectangle,GL_NV_texture_rectangle_compressed,GL_NV_texture_shader,GL_NV_texture_shader2,GL_NV_texture_shader3,GL_NV_transform_feedback,GL_NV_transform_feedback2,GL_NV_uniform_buffer_unified_memory,GL_NV_vdpau_interop,GL_NV_vertex_array_range,GL_NV_vertex_array_range2,GL_NV_vertex_attrib_integer_64bit,GL_NV_vertex_buffer_unified_memory,GL_NV_vertex_program,GL_NV_vertex_program1_1,GL_NV_vertex_program2,GL_NV_vertex_program2_option,GL_NV_vertex_program3,GL_NV_vertex_program4,GL_NV_video_capture,GL_NV_viewport_array2,GL_NV_viewport_swizzle,GL_OES_byte_coordinates,GL_OES_compressed_paletted_texture,GL_OES_fixed_point,GL_OES_query_matrix,GL_OES_read_format,GL_OES_single_precision,GL_OML_interlace,GL_OML_resample,GL_OML_subsample,GL_OVR_multiview,GL_OVR_multiview2,GL_PGI_misc_hints,GL_PGI_vertex_hints,GL_REND_screen_coordinates,GL_S3_s3tc,GL_SGIS_detail_texture,GL_SGIS_fog_function,GL_SGIS_generate_mipmap,GL_SGIS_multisample,GL_SGIS_pixel_texture,GL_SGIS_point_line_texgen,GL_SGIS_point_parameters,GL_SGIS_sharpen_texture,GL_SGIS_texture4D,GL_SGIS_texture_border_clamp,GL_SGIS_texture_color_mask,GL_SGIS_texture_edge_clamp,GL_SGIS_texture_filter4,GL_SGIS_texture_lod,GL_SGIS_texture_select,GL_SGIX_async,GL_SGIX_async_histogram,GL_SGIX_async_pixel,GL_SGIX_blend_alpha_minmax,GL_SGIX_calligraphic_fragment,GL_SGIX_clipmap,GL_SGIX_convolution_accuracy,GL_SGIX_depth_pass_instrument,GL_SGIX_depth_texture,GL_SGIX_flush_raster,GL_SGIX_fog_offset,GL_SGIX_fragment_lighting,GL_SGIX_framezoom,GL_SGIX_igloo_interface,GL_SGIX_instruments,GL_SGIX_interlace,GL_SGIX_ir_instrument1,GL_SGIX_list_priority,GL_SGIX_pixel_texture,GL_SGIX_pixel_tiles,GL_SGIX_polynomial_ffd,GL_SGIX_reference_plane,GL_SGIX_resample,GL_SGIX_scalebias_hint,GL_SGIX_shadow,GL_SGIX_shadow_ambient,GL_SGIX_sprite,GL_SGIX_subsample,GL_SGIX_tag_sample_buffer,GL_SGIX_texture_add_env,GL_SGIX_texture_coordinate_clamp,GL_SGIX_texture_lod_bias,GL_SGIX_texture_multi_buffer,GL_SGIX_texture_scale_bias,GL_SGIX_vertex_preclip,GL_SGIX_ycrcb,GL_SGIX_ycrcb_subsample,GL_SGIX_ycrcba,GL_SGI_color_matrix,GL_SGI_color_table,GL_SGI_texture_color_table,GL_SUNX_constant_data,GL_SUN_convolution_border_modes,GL_SUN_global_alpha,GL_SUN_mesh_array,GL_SUN_slice_accum,GL_SUN_triangle_list,GL_SUN_vertex,GL_WIN_phong_shading,GL_WIN_specular_fog" |
| 604 | Online: | 605 | Online: |
| 605 | Too many extensions | 606 | Too many extensions |
| 606 | */ | 607 | */ |
| @@ -739,7 +740,7 @@ int gladLoadGL(void) { | |||
| 739 | return status; | 740 | return status; |
| 740 | } | 741 | } |
| 741 | 742 | ||
| 742 | struct gladGLversionStruct GLVersion; | 743 | struct gladGLversionStruct GLVersion = { 0, 0 }; |
| 743 | 744 | ||
| 744 | #if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0) | 745 | #if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0) |
| 745 | #define _GLAD_IS_SOME_NEW_VERSION 1 | 746 | #define _GLAD_IS_SOME_NEW_VERSION 1 |
| @@ -838,3190 +839,3193 @@ static int has_ext(const char *ext) { | |||
| 838 | 839 | ||
| 839 | return 0; | 840 | return 0; |
| 840 | } | 841 | } |
| 841 | int GLAD_GL_VERSION_1_0; | 842 | int GLAD_GL_VERSION_1_0 = 0; |
| 842 | int GLAD_GL_VERSION_1_1; | 843 | int GLAD_GL_VERSION_1_1 = 0; |
| 843 | int GLAD_GL_VERSION_1_2; | 844 | int GLAD_GL_VERSION_1_2 = 0; |
| 844 | int GLAD_GL_VERSION_1_3; | 845 | int GLAD_GL_VERSION_1_3 = 0; |
| 845 | int GLAD_GL_VERSION_1_4; | 846 | int GLAD_GL_VERSION_1_4 = 0; |
| 846 | int GLAD_GL_VERSION_1_5; | 847 | int GLAD_GL_VERSION_1_5 = 0; |
| 847 | int GLAD_GL_VERSION_2_0; | 848 | int GLAD_GL_VERSION_2_0 = 0; |
| 848 | int GLAD_GL_VERSION_2_1; | 849 | int GLAD_GL_VERSION_2_1 = 0; |
| 849 | int GLAD_GL_VERSION_3_0; | 850 | int GLAD_GL_VERSION_3_0 = 0; |
| 850 | int GLAD_GL_VERSION_3_1; | 851 | int GLAD_GL_VERSION_3_1 = 0; |
| 851 | int GLAD_GL_VERSION_3_2; | 852 | int GLAD_GL_VERSION_3_2 = 0; |
| 852 | int GLAD_GL_VERSION_3_3; | 853 | int GLAD_GL_VERSION_3_3 = 0; |
| 853 | PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D; | 854 | PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D = NULL; |
| 854 | PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui; | 855 | PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui = NULL; |
| 855 | PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate; | 856 | PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate = NULL; |
| 856 | PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer; | 857 | PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer = NULL; |
| 857 | PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D; | 858 | PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D = NULL; |
| 858 | PFNGLTEXCOORDP3UIVPROC glad_glTexCoordP3uiv; | 859 | PFNGLTEXCOORDP3UIVPROC glad_glTexCoordP3uiv = NULL; |
| 859 | PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv; | 860 | PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv = NULL; |
| 860 | PFNGLBINDSAMPLERPROC glad_glBindSampler; | 861 | PFNGLBINDSAMPLERPROC glad_glBindSampler = NULL; |
| 861 | PFNGLLINEWIDTHPROC glad_glLineWidth; | 862 | PFNGLLINEWIDTHPROC glad_glLineWidth = NULL; |
| 862 | PFNGLCOLORP3UIVPROC glad_glColorP3uiv; | 863 | PFNGLCOLORP3UIVPROC glad_glColorP3uiv = NULL; |
| 863 | PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v; | 864 | PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v = NULL; |
| 864 | PFNGLCOMPILESHADERPROC glad_glCompileShader; | 865 | PFNGLCOMPILESHADERPROC glad_glCompileShader = NULL; |
| 865 | PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying; | 866 | PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying = NULL; |
| 866 | PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer; | 867 | PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer = NULL; |
| 867 | PFNGLMULTITEXCOORDP3UIPROC glad_glMultiTexCoordP3ui; | 868 | PFNGLMULTITEXCOORDP3UIPROC glad_glMultiTexCoordP3ui = NULL; |
| 868 | PFNGLVERTEXP4UIPROC glad_glVertexP4ui; | 869 | PFNGLVERTEXP4UIPROC glad_glVertexP4ui = NULL; |
| 869 | PFNGLENABLEIPROC glad_glEnablei; | 870 | PFNGLENABLEIPROC glad_glEnablei = NULL; |
| 870 | PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui; | 871 | PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui = NULL; |
| 871 | PFNGLCREATESHADERPROC glad_glCreateShader; | 872 | PFNGLCREATESHADERPROC glad_glCreateShader = NULL; |
| 872 | PFNGLISBUFFERPROC glad_glIsBuffer; | 873 | PFNGLISBUFFERPROC glad_glIsBuffer = NULL; |
| 873 | PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv; | 874 | PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv = NULL; |
| 874 | PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers; | 875 | PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers = NULL; |
| 875 | PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D; | 876 | PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D = NULL; |
| 876 | PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D; | 877 | PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D = NULL; |
| 877 | PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f; | 878 | PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f = NULL; |
| 878 | PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate; | 879 | PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate = NULL; |
| 879 | PFNGLHINTPROC glad_glHint; | 880 | PFNGLHINTPROC glad_glHint = NULL; |
| 880 | PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s; | 881 | PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s = NULL; |
| 881 | PFNGLSAMPLEMASKIPROC glad_glSampleMaski; | 882 | PFNGLSAMPLEMASKIPROC glad_glSampleMaski = NULL; |
| 882 | PFNGLVERTEXP2UIPROC glad_glVertexP2ui; | 883 | PFNGLVERTEXP2UIPROC glad_glVertexP2ui = NULL; |
| 883 | PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv; | 884 | PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv = NULL; |
| 884 | PFNGLPOINTSIZEPROC glad_glPointSize; | 885 | PFNGLPOINTSIZEPROC glad_glPointSize = NULL; |
| 885 | PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv; | 886 | PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv = NULL; |
| 886 | PFNGLDELETEPROGRAMPROC glad_glDeleteProgram; | 887 | PFNGLDELETEPROGRAMPROC glad_glDeleteProgram = NULL; |
| 887 | PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv; | 888 | PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv = NULL; |
| 888 | PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage; | 889 | PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL; |
| 889 | PFNGLWAITSYNCPROC glad_glWaitSync; | 890 | PFNGLWAITSYNCPROC glad_glWaitSync = NULL; |
| 890 | PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv; | 891 | PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv = NULL; |
| 891 | PFNGLUNIFORM3IPROC glad_glUniform3i; | 892 | PFNGLUNIFORM3IPROC glad_glUniform3i = NULL; |
| 892 | PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv; | 893 | PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv = NULL; |
| 893 | PFNGLUNIFORM3FPROC glad_glUniform3f; | 894 | PFNGLUNIFORM3FPROC glad_glUniform3f = NULL; |
| 894 | PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv; | 895 | PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv = NULL; |
| 895 | PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv; | 896 | PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv = NULL; |
| 896 | PFNGLTEXCOORDP2UIPROC glad_glTexCoordP2ui; | 897 | PFNGLTEXCOORDP2UIPROC glad_glTexCoordP2ui = NULL; |
| 897 | PFNGLCOLORMASKIPROC glad_glColorMaski; | 898 | PFNGLCOLORMASKIPROC glad_glColorMaski = NULL; |
| 898 | PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi; | 899 | PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi = NULL; |
| 899 | PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays; | 900 | PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays = NULL; |
| 900 | PFNGLMULTITEXCOORDP2UIPROC glad_glMultiTexCoordP2ui; | 901 | PFNGLMULTITEXCOORDP2UIPROC glad_glMultiTexCoordP2ui = NULL; |
| 901 | PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv; | 902 | PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv = NULL; |
| 902 | PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex; | 903 | PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex = NULL; |
| 903 | PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv; | 904 | PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv = NULL; |
| 904 | PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv; | 905 | PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv = NULL; |
| 905 | PFNGLMULTITEXCOORDP4UIPROC glad_glMultiTexCoordP4ui; | 906 | PFNGLMULTITEXCOORDP4UIPROC glad_glMultiTexCoordP4ui = NULL; |
| 906 | PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers; | 907 | PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers = NULL; |
| 907 | PFNGLDRAWARRAYSPROC glad_glDrawArrays; | 908 | PFNGLDRAWARRAYSPROC glad_glDrawArrays = NULL; |
| 908 | PFNGLUNIFORM1UIPROC glad_glUniform1ui; | 909 | PFNGLUNIFORM1UIPROC glad_glUniform1ui = NULL; |
| 909 | PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i; | 910 | PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i = NULL; |
| 910 | PFNGLTEXCOORDP3UIPROC glad_glTexCoordP3ui; | 911 | PFNGLTEXCOORDP3UIPROC glad_glTexCoordP3ui = NULL; |
| 911 | PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d; | 912 | PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d = NULL; |
| 912 | PFNGLCLEARPROC glad_glClear; | 913 | PFNGLCLEARPROC glad_glClear = NULL; |
| 913 | PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName; | 914 | PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName = NULL; |
| 914 | PFNGLISENABLEDPROC glad_glIsEnabled; | 915 | PFNGLISENABLEDPROC glad_glIsEnabled = NULL; |
| 915 | PFNGLSTENCILOPPROC glad_glStencilOp; | 916 | PFNGLSTENCILOPPROC glad_glStencilOp = NULL; |
| 916 | PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D; | 917 | PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D = NULL; |
| 917 | PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv; | 918 | PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv = NULL; |
| 918 | PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub; | 919 | PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub = NULL; |
| 919 | PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation; | 920 | PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation = NULL; |
| 920 | PFNGLTEXIMAGE1DPROC glad_glTexImage1D; | 921 | PFNGLTEXIMAGE1DPROC glad_glTexImage1D = NULL; |
| 921 | PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv; | 922 | PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv = NULL; |
| 922 | PFNGLGETTEXIMAGEPROC glad_glGetTexImage; | 923 | PFNGLGETTEXIMAGEPROC glad_glGetTexImage = NULL; |
| 923 | PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v; | 924 | PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v = NULL; |
| 924 | PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers; | 925 | PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers = NULL; |
| 925 | PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders; | 926 | PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders = NULL; |
| 926 | PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer; | 927 | PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer = NULL; |
| 927 | PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays; | 928 | PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays = NULL; |
| 928 | PFNGLISVERTEXARRAYPROC glad_glIsVertexArray; | 929 | PFNGLISVERTEXARRAYPROC glad_glIsVertexArray = NULL; |
| 929 | PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray; | 930 | PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray = NULL; |
| 930 | PFNGLGETQUERYIVPROC glad_glGetQueryiv; | 931 | PFNGLGETQUERYIVPROC glad_glGetQueryiv = NULL; |
| 931 | PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv; | 932 | PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv = NULL; |
| 932 | PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices; | 933 | PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices = NULL; |
| 933 | PFNGLISSHADERPROC glad_glIsShader; | 934 | PFNGLISSHADERPROC glad_glIsShader = NULL; |
| 934 | PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv; | 935 | PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv = NULL; |
| 935 | PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv; | 936 | PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv = NULL; |
| 936 | PFNGLENABLEPROC glad_glEnable; | 937 | PFNGLENABLEPROC glad_glEnable = NULL; |
| 937 | PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv; | 938 | PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv = NULL; |
| 938 | PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation; | 939 | PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation = NULL; |
| 939 | PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv; | 940 | PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv = NULL; |
| 940 | PFNGLMULTITEXCOORDP3UIVPROC glad_glMultiTexCoordP3uiv; | 941 | PFNGLMULTITEXCOORDP3UIVPROC glad_glMultiTexCoordP3uiv = NULL; |
| 941 | PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui; | 942 | PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui = NULL; |
| 942 | PFNGLGETUNIFORMFVPROC glad_glGetUniformfv; | 943 | PFNGLGETUNIFORMFVPROC glad_glGetUniformfv = NULL; |
| 943 | PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv; | 944 | PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv = NULL; |
| 944 | PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv; | 945 | PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv = NULL; |
| 945 | PFNGLDRAWBUFFERPROC glad_glDrawBuffer; | 946 | PFNGLDRAWBUFFERPROC glad_glDrawBuffer = NULL; |
| 946 | PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv; | 947 | PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv = NULL; |
| 947 | PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced; | 948 | PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced = NULL; |
| 948 | PFNGLFLUSHPROC glad_glFlush; | 949 | PFNGLFLUSHPROC glad_glFlush = NULL; |
| 949 | PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv; | 950 | PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv = NULL; |
| 950 | PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv; | 951 | PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv = NULL; |
| 951 | PFNGLFENCESYNCPROC glad_glFenceSync; | 952 | PFNGLFENCESYNCPROC glad_glFenceSync = NULL; |
| 952 | PFNGLCOLORP3UIPROC glad_glColorP3ui; | 953 | PFNGLCOLORP3UIPROC glad_glColorP3ui = NULL; |
| 953 | PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv; | 954 | PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv = NULL; |
| 954 | PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender; | 955 | PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender = NULL; |
| 955 | PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv; | 956 | PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv = NULL; |
| 956 | PFNGLMULTITEXCOORDP4UIVPROC glad_glMultiTexCoordP4uiv; | 957 | PFNGLMULTITEXCOORDP4UIVPROC glad_glMultiTexCoordP4uiv = NULL; |
| 957 | PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate; | 958 | PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate = NULL; |
| 958 | PFNGLGENSAMPLERSPROC glad_glGenSamplers; | 959 | PFNGLGENSAMPLERSPROC glad_glGenSamplers = NULL; |
| 959 | PFNGLCLAMPCOLORPROC glad_glClampColor; | 960 | PFNGLCLAMPCOLORPROC glad_glClampColor = NULL; |
| 960 | PFNGLUNIFORM4IVPROC glad_glUniform4iv; | 961 | PFNGLUNIFORM4IVPROC glad_glUniform4iv = NULL; |
| 961 | PFNGLCLEARSTENCILPROC glad_glClearStencil; | 962 | PFNGLCLEARSTENCILPROC glad_glClearStencil = NULL; |
| 962 | PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv; | 963 | PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv = NULL; |
| 963 | PFNGLGENTEXTURESPROC glad_glGenTextures; | 964 | PFNGLGENTEXTURESPROC glad_glGenTextures = NULL; |
| 964 | PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv; | 965 | PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv = NULL; |
| 965 | PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv; | 966 | PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv = NULL; |
| 966 | PFNGLISSYNCPROC glad_glIsSync; | 967 | PFNGLISSYNCPROC glad_glIsSync = NULL; |
| 967 | PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName; | 968 | PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName = NULL; |
| 968 | PFNGLUNIFORM2IPROC glad_glUniform2i; | 969 | PFNGLUNIFORM2IPROC glad_glUniform2i = NULL; |
| 969 | PFNGLUNIFORM2FPROC glad_glUniform2f; | 970 | PFNGLUNIFORM2FPROC glad_glUniform2f = NULL; |
| 970 | PFNGLTEXCOORDP4UIPROC glad_glTexCoordP4ui; | 971 | PFNGLTEXCOORDP4UIPROC glad_glTexCoordP4ui = NULL; |
| 971 | PFNGLGETPROGRAMIVPROC glad_glGetProgramiv; | 972 | PFNGLGETPROGRAMIVPROC glad_glGetProgramiv = NULL; |
| 972 | PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer; | 973 | PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer = NULL; |
| 973 | PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer; | 974 | PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer = NULL; |
| 974 | PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange; | 975 | PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange = NULL; |
| 975 | PFNGLGENQUERIESPROC glad_glGenQueries; | 976 | PFNGLGENQUERIESPROC glad_glGenQueries = NULL; |
| 976 | PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui; | 977 | PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui = NULL; |
| 977 | PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D; | 978 | PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D = NULL; |
| 978 | PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v; | 979 | PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v = NULL; |
| 979 | PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers; | 980 | PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers = NULL; |
| 980 | PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D; | 981 | PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D = NULL; |
| 981 | PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer; | 982 | PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer = NULL; |
| 982 | PFNGLISENABLEDIPROC glad_glIsEnabledi; | 983 | PFNGLISENABLEDIPROC glad_glIsEnabledi = NULL; |
| 983 | PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui; | 984 | PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui = NULL; |
| 984 | PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed; | 985 | PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed = NULL; |
| 985 | PFNGLUNIFORM2IVPROC glad_glUniform2iv; | 986 | PFNGLUNIFORM2IVPROC glad_glUniform2iv = NULL; |
| 986 | PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv; | 987 | PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv = NULL; |
| 987 | PFNGLUNIFORM4UIVPROC glad_glUniform4uiv; | 988 | PFNGLUNIFORM4UIVPROC glad_glUniform4uiv = NULL; |
| 988 | PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D; | 989 | PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D = NULL; |
| 989 | PFNGLGETSHADERIVPROC glad_glGetShaderiv; | 990 | PFNGLGETSHADERIVPROC glad_glGetShaderiv = NULL; |
| 990 | PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation; | 991 | PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation = NULL; |
| 991 | PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset; | 992 | PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset = NULL; |
| 992 | PFNGLGETDOUBLEVPROC glad_glGetDoublev; | 993 | PFNGLGETDOUBLEVPROC glad_glGetDoublev = NULL; |
| 993 | PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d; | 994 | PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d = NULL; |
| 994 | PFNGLGETUNIFORMIVPROC glad_glGetUniformiv; | 995 | PFNGLGETUNIFORMIVPROC glad_glGetUniformiv = NULL; |
| 995 | PFNGLMULTITEXCOORDP1UIVPROC glad_glMultiTexCoordP1uiv; | 996 | PFNGLMULTITEXCOORDP1UIVPROC glad_glMultiTexCoordP1uiv = NULL; |
| 996 | PFNGLUNIFORM3FVPROC glad_glUniform3fv; | 997 | PFNGLUNIFORM3FVPROC glad_glUniform3fv = NULL; |
| 997 | PFNGLDEPTHRANGEPROC glad_glDepthRange; | 998 | PFNGLDEPTHRANGEPROC glad_glDepthRange = NULL; |
| 998 | PFNGLMAPBUFFERPROC glad_glMapBuffer; | 999 | PFNGLMAPBUFFERPROC glad_glMapBuffer = NULL; |
| 999 | PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D; | 1000 | PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D = NULL; |
| 1000 | PFNGLDELETESYNCPROC glad_glDeleteSync; | 1001 | PFNGLDELETESYNCPROC glad_glDeleteSync = NULL; |
| 1001 | PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D; | 1002 | PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D = NULL; |
| 1002 | PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv; | 1003 | PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv = NULL; |
| 1003 | PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements; | 1004 | PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements = NULL; |
| 1004 | PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv; | 1005 | PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv = NULL; |
| 1005 | PFNGLUNIFORM3IVPROC glad_glUniform3iv; | 1006 | PFNGLUNIFORM3IVPROC glad_glUniform3iv = NULL; |
| 1006 | PFNGLPOLYGONMODEPROC glad_glPolygonMode; | 1007 | PFNGLPOLYGONMODEPROC glad_glPolygonMode = NULL; |
| 1007 | PFNGLDRAWBUFFERSPROC glad_glDrawBuffers; | 1008 | PFNGLDRAWBUFFERSPROC glad_glDrawBuffers = NULL; |
| 1008 | PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv; | 1009 | PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv = NULL; |
| 1009 | PFNGLUSEPROGRAMPROC glad_glUseProgram; | 1010 | PFNGLUSEPROGRAMPROC glad_glUseProgram = NULL; |
| 1010 | PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog; | 1011 | PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog = NULL; |
| 1011 | PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray; | 1012 | PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray = NULL; |
| 1012 | PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers; | 1013 | PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers = NULL; |
| 1013 | PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv; | 1014 | PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv = NULL; |
| 1014 | PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex; | 1015 | PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex = NULL; |
| 1015 | PFNGLUNIFORM2UIVPROC glad_glUniform2uiv; | 1016 | PFNGLUNIFORM2UIVPROC glad_glUniform2uiv = NULL; |
| 1016 | PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D; | 1017 | PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D = NULL; |
| 1017 | PFNGLFINISHPROC glad_glFinish; | 1018 | PFNGLFINISHPROC glad_glFinish = NULL; |
| 1018 | PFNGLDELETESHADERPROC glad_glDeleteShader; | 1019 | PFNGLDELETESHADERPROC glad_glDeleteShader = NULL; |
| 1019 | PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv; | 1020 | PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv = NULL; |
| 1020 | PFNGLVIEWPORTPROC glad_glViewport; | 1021 | PFNGLVIEWPORTPROC glad_glViewport = NULL; |
| 1021 | PFNGLUNIFORM1UIVPROC glad_glUniform1uiv; | 1022 | PFNGLUNIFORM1UIVPROC glad_glUniform1uiv = NULL; |
| 1022 | PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings; | 1023 | PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings = NULL; |
| 1023 | PFNGLUNIFORM2UIPROC glad_glUniform2ui; | 1024 | PFNGLUNIFORM2UIPROC glad_glUniform2ui = NULL; |
| 1024 | PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i; | 1025 | PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i = NULL; |
| 1025 | PFNGLCLEARDEPTHPROC glad_glClearDepth; | 1026 | PFNGLCLEARDEPTHPROC glad_glClearDepth = NULL; |
| 1026 | PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv; | 1027 | PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv = NULL; |
| 1027 | PFNGLTEXPARAMETERFPROC glad_glTexParameterf; | 1028 | PFNGLTEXPARAMETERFPROC glad_glTexParameterf = NULL; |
| 1028 | PFNGLTEXPARAMETERIPROC glad_glTexParameteri; | 1029 | PFNGLTEXPARAMETERIPROC glad_glTexParameteri = NULL; |
| 1029 | PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource; | 1030 | PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource = NULL; |
| 1030 | PFNGLTEXBUFFERPROC glad_glTexBuffer; | 1031 | PFNGLTEXBUFFERPROC glad_glTexBuffer = NULL; |
| 1031 | PFNGLPIXELSTOREIPROC glad_glPixelStorei; | 1032 | PFNGLPIXELSTOREIPROC glad_glPixelStorei = NULL; |
| 1032 | PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram; | 1033 | PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram = NULL; |
| 1033 | PFNGLPIXELSTOREFPROC glad_glPixelStoref; | 1034 | PFNGLPIXELSTOREFPROC glad_glPixelStoref = NULL; |
| 1034 | PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v; | 1035 | PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v = NULL; |
| 1035 | PFNGLMULTITEXCOORDP2UIVPROC glad_glMultiTexCoordP2uiv; | 1036 | PFNGLMULTITEXCOORDP2UIVPROC glad_glMultiTexCoordP2uiv = NULL; |
| 1036 | PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv; | 1037 | PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv = NULL; |
| 1037 | PFNGLLINKPROGRAMPROC glad_glLinkProgram; | 1038 | PFNGLLINKPROGRAMPROC glad_glLinkProgram = NULL; |
| 1038 | PFNGLBINDTEXTUREPROC glad_glBindTexture; | 1039 | PFNGLBINDTEXTUREPROC glad_glBindTexture = NULL; |
| 1039 | PFNGLGETSTRINGPROC glad_glGetString; | 1040 | PFNGLGETSTRINGPROC glad_glGetString = NULL; |
| 1040 | PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv; | 1041 | PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv = NULL; |
| 1041 | PFNGLDETACHSHADERPROC glad_glDetachShader; | 1042 | PFNGLDETACHSHADERPROC glad_glDetachShader = NULL; |
| 1042 | PFNGLENDQUERYPROC glad_glEndQuery; | 1043 | PFNGLENDQUERYPROC glad_glEndQuery = NULL; |
| 1043 | PFNGLNORMALP3UIPROC glad_glNormalP3ui; | 1044 | PFNGLNORMALP3UIPROC glad_glNormalP3ui = NULL; |
| 1044 | PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui; | 1045 | PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui = NULL; |
| 1045 | PFNGLDELETETEXTURESPROC glad_glDeleteTextures; | 1046 | PFNGLDELETETEXTURESPROC glad_glDeleteTextures = NULL; |
| 1046 | PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate; | 1047 | PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate = NULL; |
| 1047 | PFNGLDELETEQUERIESPROC glad_glDeleteQueries; | 1048 | PFNGLDELETEQUERIESPROC glad_glDeleteQueries = NULL; |
| 1048 | PFNGLNORMALP3UIVPROC glad_glNormalP3uiv; | 1049 | PFNGLNORMALP3UIVPROC glad_glNormalP3uiv = NULL; |
| 1049 | PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f; | 1050 | PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f = NULL; |
| 1050 | PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d; | 1051 | PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d = NULL; |
| 1051 | PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv; | 1052 | PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv = NULL; |
| 1052 | PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s; | 1053 | PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s = NULL; |
| 1053 | PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex; | 1054 | PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex = NULL; |
| 1054 | PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage; | 1055 | PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage = NULL; |
| 1055 | PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri; | 1056 | PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri = NULL; |
| 1056 | PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf; | 1057 | PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf = NULL; |
| 1057 | PFNGLUNIFORM1FPROC glad_glUniform1f; | 1058 | PFNGLUNIFORM1FPROC glad_glUniform1f = NULL; |
| 1058 | PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv; | 1059 | PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv = NULL; |
| 1059 | PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage; | 1060 | PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage = NULL; |
| 1060 | PFNGLUNIFORM1IPROC glad_glUniform1i; | 1061 | PFNGLUNIFORM1IPROC glad_glUniform1i = NULL; |
| 1061 | PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib; | 1062 | PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib = NULL; |
| 1062 | PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D; | 1063 | PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D = NULL; |
| 1063 | PFNGLDISABLEPROC glad_glDisable; | 1064 | PFNGLDISABLEPROC glad_glDisable = NULL; |
| 1064 | PFNGLLOGICOPPROC glad_glLogicOp; | 1065 | PFNGLLOGICOPPROC glad_glLogicOp = NULL; |
| 1065 | PFNGLUNIFORM4UIPROC glad_glUniform4ui; | 1066 | PFNGLUNIFORM4UIPROC glad_glUniform4ui = NULL; |
| 1066 | PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer; | 1067 | PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer = NULL; |
| 1067 | PFNGLCULLFACEPROC glad_glCullFace; | 1068 | PFNGLCULLFACEPROC glad_glCullFace = NULL; |
| 1068 | PFNGLGETSTRINGIPROC glad_glGetStringi; | 1069 | PFNGLGETSTRINGIPROC glad_glGetStringi = NULL; |
| 1069 | PFNGLATTACHSHADERPROC glad_glAttachShader; | 1070 | PFNGLATTACHSHADERPROC glad_glAttachShader = NULL; |
| 1070 | PFNGLQUERYCOUNTERPROC glad_glQueryCounter; | 1071 | PFNGLQUERYCOUNTERPROC glad_glQueryCounter = NULL; |
| 1071 | PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex; | 1072 | PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex = NULL; |
| 1072 | PFNGLDRAWELEMENTSPROC glad_glDrawElements; | 1073 | PFNGLDRAWELEMENTSPROC glad_glDrawElements = NULL; |
| 1073 | PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv; | 1074 | PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv = NULL; |
| 1074 | PFNGLUNIFORM1IVPROC glad_glUniform1iv; | 1075 | PFNGLUNIFORM1IVPROC glad_glUniform1iv = NULL; |
| 1075 | PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv; | 1076 | PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv = NULL; |
| 1076 | PFNGLREADBUFFERPROC glad_glReadBuffer; | 1077 | PFNGLREADBUFFERPROC glad_glReadBuffer = NULL; |
| 1077 | PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv; | 1078 | PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv = NULL; |
| 1078 | PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced; | 1079 | PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced = NULL; |
| 1079 | PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap; | 1080 | PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap = NULL; |
| 1080 | PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv; | 1081 | PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv = NULL; |
| 1081 | PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f; | 1082 | PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f = NULL; |
| 1082 | PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv; | 1083 | PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv = NULL; |
| 1083 | PFNGLPOINTPARAMETERIPROC glad_glPointParameteri; | 1084 | PFNGLPOINTPARAMETERIPROC glad_glPointParameteri = NULL; |
| 1084 | PFNGLBLENDCOLORPROC glad_glBlendColor; | 1085 | PFNGLBLENDCOLORPROC glad_glBlendColor = NULL; |
| 1085 | PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv; | 1086 | PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv = NULL; |
| 1086 | PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer; | 1087 | PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer = NULL; |
| 1087 | PFNGLPOINTPARAMETERFPROC glad_glPointParameterf; | 1088 | PFNGLPOINTPARAMETERFPROC glad_glPointParameterf = NULL; |
| 1088 | PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s; | 1089 | PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s = NULL; |
| 1089 | PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer; | 1090 | PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer = NULL; |
| 1090 | PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv; | 1091 | PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv = NULL; |
| 1091 | PFNGLISPROGRAMPROC glad_glIsProgram; | 1092 | PFNGLISPROGRAMPROC glad_glIsProgram = NULL; |
| 1092 | PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv; | 1093 | PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv = NULL; |
| 1093 | PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv; | 1094 | PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv = NULL; |
| 1094 | PFNGLUNIFORM4IPROC glad_glUniform4i; | 1095 | PFNGLUNIFORM4IPROC glad_glUniform4i = NULL; |
| 1095 | PFNGLACTIVETEXTUREPROC glad_glActiveTexture; | 1096 | PFNGLACTIVETEXTUREPROC glad_glActiveTexture = NULL; |
| 1096 | PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray; | 1097 | PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray = NULL; |
| 1097 | PFNGLREADPIXELSPROC glad_glReadPixels; | 1098 | PFNGLREADPIXELSPROC glad_glReadPixels = NULL; |
| 1098 | PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv; | 1099 | PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv = NULL; |
| 1099 | PFNGLUNIFORM4FPROC glad_glUniform4f; | 1100 | PFNGLUNIFORM4FPROC glad_glUniform4f = NULL; |
| 1100 | PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample; | 1101 | PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample = NULL; |
| 1101 | PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv; | 1102 | PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv = NULL; |
| 1102 | PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex; | 1103 | PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex = NULL; |
| 1103 | PFNGLSTENCILFUNCPROC glad_glStencilFunc; | 1104 | PFNGLSTENCILFUNCPROC glad_glStencilFunc = NULL; |
| 1104 | PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding; | 1105 | PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding = NULL; |
| 1105 | PFNGLCOLORP4UIPROC glad_glColorP4ui; | 1106 | PFNGLCOLORP4UIPROC glad_glColorP4ui = NULL; |
| 1106 | PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv; | 1107 | PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv = NULL; |
| 1107 | PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog; | 1108 | PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog = NULL; |
| 1108 | PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i; | 1109 | PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i = NULL; |
| 1109 | PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData; | 1110 | PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData = NULL; |
| 1110 | PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate; | 1111 | PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate = NULL; |
| 1111 | PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui; | 1112 | PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui = NULL; |
| 1112 | PFNGLGENBUFFERSPROC glad_glGenBuffers; | 1113 | PFNGLGENBUFFERSPROC glad_glGenBuffers = NULL; |
| 1113 | PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv; | 1114 | PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv = NULL; |
| 1114 | PFNGLBLENDFUNCPROC glad_glBlendFunc; | 1115 | PFNGLBLENDFUNCPROC glad_glBlendFunc = NULL; |
| 1115 | PFNGLCREATEPROGRAMPROC glad_glCreateProgram; | 1116 | PFNGLCREATEPROGRAMPROC glad_glCreateProgram = NULL; |
| 1116 | PFNGLTEXIMAGE3DPROC glad_glTexImage3D; | 1117 | PFNGLTEXIMAGE3DPROC glad_glTexImage3D = NULL; |
| 1117 | PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer; | 1118 | PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer = NULL; |
| 1118 | PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex; | 1119 | PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex = NULL; |
| 1119 | PFNGLGETINTEGER64VPROC glad_glGetInteger64v; | 1120 | PFNGLGETINTEGER64VPROC glad_glGetInteger64v = NULL; |
| 1120 | PFNGLSCISSORPROC glad_glScissor; | 1121 | PFNGLSCISSORPROC glad_glScissor = NULL; |
| 1121 | PFNGLTEXCOORDP4UIVPROC glad_glTexCoordP4uiv; | 1122 | PFNGLTEXCOORDP4UIVPROC glad_glTexCoordP4uiv = NULL; |
| 1122 | PFNGLGETBOOLEANVPROC glad_glGetBooleanv; | 1123 | PFNGLGETBOOLEANVPROC glad_glGetBooleanv = NULL; |
| 1123 | PFNGLVERTEXP2UIVPROC glad_glVertexP2uiv; | 1124 | PFNGLVERTEXP2UIVPROC glad_glVertexP2uiv = NULL; |
| 1124 | PFNGLUNIFORM3UIVPROC glad_glUniform3uiv; | 1125 | PFNGLUNIFORM3UIVPROC glad_glUniform3uiv = NULL; |
| 1125 | PFNGLCLEARCOLORPROC glad_glClearColor; | 1126 | PFNGLCLEARCOLORPROC glad_glClearColor = NULL; |
| 1126 | PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv; | 1127 | PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv = NULL; |
| 1127 | PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv; | 1128 | PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv = NULL; |
| 1128 | PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v; | 1129 | PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v = NULL; |
| 1129 | PFNGLCOLORP4UIVPROC glad_glColorP4uiv; | 1130 | PFNGLCOLORP4UIVPROC glad_glColorP4uiv = NULL; |
| 1130 | PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv; | 1131 | PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv = NULL; |
| 1131 | PFNGLUNIFORM3UIPROC glad_glUniform3ui; | 1132 | PFNGLUNIFORM3UIPROC glad_glUniform3ui = NULL; |
| 1132 | PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv; | 1133 | PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv = NULL; |
| 1133 | PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv; | 1134 | PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv = NULL; |
| 1134 | PFNGLUNIFORM2FVPROC glad_glUniform2fv; | 1135 | PFNGLUNIFORM2FVPROC glad_glUniform2fv = NULL; |
| 1135 | PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv; | 1136 | PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv = NULL; |
| 1136 | PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange; | 1137 | PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange = NULL; |
| 1137 | PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv; | 1138 | PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv = NULL; |
| 1138 | PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv; | 1139 | PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv = NULL; |
| 1139 | PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv; | 1140 | PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv = NULL; |
| 1140 | PFNGLDEPTHFUNCPROC glad_glDepthFunc; | 1141 | PFNGLDEPTHFUNCPROC glad_glDepthFunc = NULL; |
| 1141 | PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D; | 1142 | PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D = NULL; |
| 1142 | PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv; | 1143 | PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv = NULL; |
| 1143 | PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv; | 1144 | PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv = NULL; |
| 1144 | PFNGLMULTITEXCOORDP1UIPROC glad_glMultiTexCoordP1ui; | 1145 | PFNGLMULTITEXCOORDP1UIPROC glad_glMultiTexCoordP1ui = NULL; |
| 1145 | PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync; | 1146 | PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync = NULL; |
| 1146 | PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui; | 1147 | PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui = NULL; |
| 1147 | PFNGLCOLORMASKPROC glad_glColorMask; | 1148 | PFNGLCOLORMASKPROC glad_glColorMask = NULL; |
| 1148 | PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv; | 1149 | PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv = NULL; |
| 1149 | PFNGLBLENDEQUATIONPROC glad_glBlendEquation; | 1150 | PFNGLBLENDEQUATIONPROC glad_glBlendEquation = NULL; |
| 1150 | PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation; | 1151 | PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation = NULL; |
| 1151 | PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback; | 1152 | PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback = NULL; |
| 1152 | PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv; | 1153 | PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv = NULL; |
| 1153 | PFNGLUNIFORM4FVPROC glad_glUniform4fv; | 1154 | PFNGLUNIFORM4FVPROC glad_glUniform4fv = NULL; |
| 1154 | PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback; | 1155 | PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback = NULL; |
| 1155 | PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv; | 1156 | PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv = NULL; |
| 1156 | PFNGLISSAMPLERPROC glad_glIsSampler; | 1157 | PFNGLISSAMPLERPROC glad_glIsSampler = NULL; |
| 1157 | PFNGLVERTEXP3UIPROC glad_glVertexP3ui; | 1158 | PFNGLVERTEXP3UIPROC glad_glVertexP3ui = NULL; |
| 1158 | PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor; | 1159 | PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor = NULL; |
| 1159 | PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D; | 1160 | PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D = NULL; |
| 1160 | PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D; | 1161 | PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D = NULL; |
| 1161 | PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex; | 1162 | PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex = NULL; |
| 1162 | PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus; | 1163 | PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus = NULL; |
| 1163 | PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender; | 1164 | PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender = NULL; |
| 1164 | PFNGLVERTEXP3UIVPROC glad_glVertexP3uiv; | 1165 | PFNGLVERTEXP3UIVPROC glad_glVertexP3uiv = NULL; |
| 1165 | PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation; | 1166 | PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation = NULL; |
| 1166 | PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv; | 1167 | PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv = NULL; |
| 1167 | PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv; | 1168 | PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv = NULL; |
| 1168 | PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements; | 1169 | PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements = NULL; |
| 1169 | PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv; | 1170 | PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv = NULL; |
| 1170 | PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase; | 1171 | PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase = NULL; |
| 1171 | PFNGLBUFFERSUBDATAPROC glad_glBufferSubData; | 1172 | PFNGLBUFFERSUBDATAPROC glad_glBufferSubData = NULL; |
| 1172 | PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv; | 1173 | PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv = NULL; |
| 1173 | PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange; | 1174 | PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange = NULL; |
| 1174 | PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture; | 1175 | PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture = NULL; |
| 1175 | PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays; | 1176 | PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays = NULL; |
| 1176 | PFNGLVERTEXP4UIVPROC glad_glVertexP4uiv; | 1177 | PFNGLVERTEXP4UIVPROC glad_glVertexP4uiv = NULL; |
| 1177 | PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv; | 1178 | PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv = NULL; |
| 1178 | PFNGLDISABLEIPROC glad_glDisablei; | 1179 | PFNGLDISABLEIPROC glad_glDisablei = NULL; |
| 1179 | PFNGLSHADERSOURCEPROC glad_glShaderSource; | 1180 | PFNGLSHADERSOURCEPROC glad_glShaderSource = NULL; |
| 1180 | PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers; | 1181 | PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers = NULL; |
| 1181 | PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv; | 1182 | PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv = NULL; |
| 1182 | PFNGLGETSYNCIVPROC glad_glGetSynciv; | 1183 | PFNGLGETSYNCIVPROC glad_glGetSynciv = NULL; |
| 1183 | PFNGLTEXCOORDP2UIVPROC glad_glTexCoordP2uiv; | 1184 | PFNGLTEXCOORDP2UIVPROC glad_glTexCoordP2uiv = NULL; |
| 1184 | PFNGLBEGINQUERYPROC glad_glBeginQuery; | 1185 | PFNGLBEGINQUERYPROC glad_glBeginQuery = NULL; |
| 1185 | PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv; | 1186 | PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv = NULL; |
| 1186 | PFNGLBINDBUFFERPROC glad_glBindBuffer; | 1187 | PFNGLBINDBUFFERPROC glad_glBindBuffer = NULL; |
| 1187 | PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv; | 1188 | PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv = NULL; |
| 1188 | PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv; | 1189 | PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv = NULL; |
| 1189 | PFNGLBUFFERDATAPROC glad_glBufferData; | 1190 | PFNGLBUFFERDATAPROC glad_glBufferData = NULL; |
| 1190 | PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv; | 1191 | PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv = NULL; |
| 1191 | PFNGLTEXCOORDP1UIPROC glad_glTexCoordP1ui; | 1192 | PFNGLTEXCOORDP1UIPROC glad_glTexCoordP1ui = NULL; |
| 1192 | PFNGLGETERRORPROC glad_glGetError; | 1193 | PFNGLGETERRORPROC glad_glGetError = NULL; |
| 1193 | PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui; | 1194 | PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui = NULL; |
| 1194 | PFNGLGETFLOATVPROC glad_glGetFloatv; | 1195 | PFNGLGETFLOATVPROC glad_glGetFloatv = NULL; |
| 1195 | PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D; | 1196 | PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D = NULL; |
| 1196 | PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv; | 1197 | PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv = NULL; |
| 1197 | PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv; | 1198 | PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv = NULL; |
| 1198 | PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i; | 1199 | PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i = NULL; |
| 1199 | PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv; | 1200 | PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv = NULL; |
| 1200 | PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv; | 1201 | PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv = NULL; |
| 1201 | PFNGLGETINTEGERVPROC glad_glGetIntegerv; | 1202 | PFNGLGETINTEGERVPROC glad_glGetIntegerv = NULL; |
| 1202 | PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv; | 1203 | PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv = NULL; |
| 1203 | PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D; | 1204 | PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D = NULL; |
| 1204 | PFNGLISQUERYPROC glad_glIsQuery; | 1205 | PFNGLISQUERYPROC glad_glIsQuery = NULL; |
| 1205 | PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv; | 1206 | PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv = NULL; |
| 1206 | PFNGLTEXIMAGE2DPROC glad_glTexImage2D; | 1207 | PFNGLTEXIMAGE2DPROC glad_glTexImage2D = NULL; |
| 1207 | PFNGLSTENCILMASKPROC glad_glStencilMask; | 1208 | PFNGLSTENCILMASKPROC glad_glStencilMask = NULL; |
| 1208 | PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv; | 1209 | PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv = NULL; |
| 1209 | PFNGLISTEXTUREPROC glad_glIsTexture; | 1210 | PFNGLISTEXTUREPROC glad_glIsTexture = NULL; |
| 1210 | PFNGLUNIFORM1FVPROC glad_glUniform1fv; | 1211 | PFNGLUNIFORM1FVPROC glad_glUniform1fv = NULL; |
| 1211 | PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv; | 1212 | PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv = NULL; |
| 1212 | PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv; | 1213 | PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv = NULL; |
| 1213 | PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv; | 1214 | PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv = NULL; |
| 1214 | PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData; | 1215 | PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData = NULL; |
| 1215 | PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv; | 1216 | PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv = NULL; |
| 1216 | PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d; | 1217 | PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d = NULL; |
| 1217 | PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f; | 1218 | PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f = NULL; |
| 1218 | PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv; | 1219 | PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv = NULL; |
| 1219 | PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v; | 1220 | PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v = NULL; |
| 1220 | PFNGLDEPTHMASKPROC glad_glDepthMask; | 1221 | PFNGLDEPTHMASKPROC glad_glDepthMask = NULL; |
| 1221 | PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s; | 1222 | PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s = NULL; |
| 1222 | PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample; | 1223 | PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample = NULL; |
| 1223 | PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex; | 1224 | PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex = NULL; |
| 1224 | PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample; | 1225 | PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample = NULL; |
| 1225 | PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform; | 1226 | PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform = NULL; |
| 1226 | PFNGLFRONTFACEPROC glad_glFrontFace; | 1227 | PFNGLFRONTFACEPROC glad_glFrontFace = NULL; |
| 1227 | int GLAD_GL_SGIX_pixel_tiles; | 1228 | int GLAD_GL_SGIX_pixel_tiles = 0; |
| 1228 | int GLAD_GL_EXT_post_depth_coverage; | 1229 | int GLAD_GL_EXT_post_depth_coverage = 0; |
| 1229 | int GLAD_GL_APPLE_element_array; | 1230 | int GLAD_GL_APPLE_element_array = 0; |
| 1230 | int GLAD_GL_AMD_multi_draw_indirect; | 1231 | int GLAD_GL_AMD_multi_draw_indirect = 0; |
| 1231 | int GLAD_GL_EXT_blend_subtract; | 1232 | int GLAD_GL_EXT_blend_subtract = 0; |
| 1232 | int GLAD_GL_SGIX_tag_sample_buffer; | 1233 | int GLAD_GL_SGIX_tag_sample_buffer = 0; |
| 1233 | int GLAD_GL_NV_point_sprite; | 1234 | int GLAD_GL_NV_point_sprite = 0; |
| 1234 | int GLAD_GL_IBM_texture_mirrored_repeat; | 1235 | int GLAD_GL_IBM_texture_mirrored_repeat = 0; |
| 1235 | int GLAD_GL_APPLE_transform_hint; | 1236 | int GLAD_GL_APPLE_transform_hint = 0; |
| 1236 | int GLAD_GL_ATI_separate_stencil; | 1237 | int GLAD_GL_ATI_separate_stencil = 0; |
| 1237 | int GLAD_GL_NV_shader_atomic_int64; | 1238 | int GLAD_GL_NV_shader_atomic_int64 = 0; |
| 1238 | int GLAD_GL_EXT_semaphore_win32; | 1239 | int GLAD_GL_EXT_semaphore_win32 = 0; |
| 1239 | int GLAD_GL_NV_vertex_program2_option; | 1240 | int GLAD_GL_NV_vertex_program2_option = 0; |
| 1240 | int GLAD_GL_EXT_texture_buffer_object; | 1241 | int GLAD_GL_EXT_texture_buffer_object = 0; |
| 1241 | int GLAD_GL_ARB_vertex_blend; | 1242 | int GLAD_GL_ARB_vertex_blend = 0; |
| 1242 | int GLAD_GL_OVR_multiview; | 1243 | int GLAD_GL_OVR_multiview = 0; |
| 1243 | int GLAD_GL_AMD_shader_gpu_shader_half_float_fetch; | 1244 | int GLAD_GL_AMD_shader_gpu_shader_half_float_fetch = 0; |
| 1244 | int GLAD_GL_NV_vertex_program2; | 1245 | int GLAD_GL_NV_vertex_program2 = 0; |
| 1245 | int GLAD_GL_ARB_program_interface_query; | 1246 | int GLAD_GL_ARB_program_interface_query = 0; |
| 1246 | int GLAD_GL_EXT_misc_attribute; | 1247 | int GLAD_GL_EXT_misc_attribute = 0; |
| 1247 | int GLAD_GL_NV_multisample_coverage; | 1248 | int GLAD_GL_NV_multisample_coverage = 0; |
| 1248 | int GLAD_GL_ARB_shading_language_packing; | 1249 | int GLAD_GL_ARB_shading_language_packing = 0; |
| 1249 | int GLAD_GL_EXT_texture_cube_map; | 1250 | int GLAD_GL_EXT_texture_cube_map = 0; |
| 1250 | int GLAD_GL_NV_viewport_array2; | 1251 | int GLAD_GL_NV_viewport_array2 = 0; |
| 1251 | int GLAD_GL_ARB_texture_stencil8; | 1252 | int GLAD_GL_ARB_texture_stencil8 = 0; |
| 1252 | int GLAD_GL_EXT_index_func; | 1253 | int GLAD_GL_EXT_index_func = 0; |
| 1253 | int GLAD_GL_EXT_memory_object_fd; | 1254 | int GLAD_GL_EXT_memory_object_fd = 0; |
| 1254 | int GLAD_GL_OES_compressed_paletted_texture; | 1255 | int GLAD_GL_OES_compressed_paletted_texture = 0; |
| 1255 | int GLAD_GL_MESA_shader_integer_functions; | 1256 | int GLAD_GL_MESA_shader_integer_functions = 0; |
| 1256 | int GLAD_GL_NV_shader_buffer_load; | 1257 | int GLAD_GL_NV_shader_buffer_load = 0; |
| 1257 | int GLAD_GL_EXT_color_subtable; | 1258 | int GLAD_GL_EXT_color_subtable = 0; |
| 1258 | int GLAD_GL_SUNX_constant_data; | 1259 | int GLAD_GL_SUNX_constant_data = 0; |
| 1259 | int GLAD_GL_EXT_texture_compression_s3tc; | 1260 | int GLAD_GL_EXT_texture_compression_s3tc = 0; |
| 1260 | int GLAD_GL_EXT_multi_draw_arrays; | 1261 | int GLAD_GL_EXT_multi_draw_arrays = 0; |
| 1261 | int GLAD_GL_ARB_shader_atomic_counters; | 1262 | int GLAD_GL_ARB_shader_atomic_counters = 0; |
| 1262 | int GLAD_GL_ARB_arrays_of_arrays; | 1263 | int GLAD_GL_ARB_arrays_of_arrays = 0; |
| 1263 | int GLAD_GL_NV_conditional_render; | 1264 | int GLAD_GL_NV_conditional_render = 0; |
| 1264 | int GLAD_GL_EXT_texture_env_combine; | 1265 | int GLAD_GL_EXT_texture_env_combine = 0; |
| 1265 | int GLAD_GL_NV_fog_distance; | 1266 | int GLAD_GL_NV_fog_distance = 0; |
| 1266 | int GLAD_GL_SGIX_async_histogram; | 1267 | int GLAD_GL_SGIX_async_histogram = 0; |
| 1267 | int GLAD_GL_MESA_resize_buffers; | 1268 | int GLAD_GL_MESA_resize_buffers = 0; |
| 1268 | int GLAD_GL_NV_light_max_exponent; | 1269 | int GLAD_GL_NV_light_max_exponent = 0; |
| 1269 | int GLAD_GL_NV_texture_env_combine4; | 1270 | int GLAD_GL_NV_texture_env_combine4 = 0; |
| 1270 | int GLAD_GL_ARB_spirv_extensions; | 1271 | int GLAD_GL_ARB_spirv_extensions = 0; |
| 1271 | int GLAD_GL_ARB_texture_view; | 1272 | int GLAD_GL_ARB_texture_view = 0; |
| 1272 | int GLAD_GL_ARB_texture_env_combine; | 1273 | int GLAD_GL_ARB_texture_env_combine = 0; |
| 1273 | int GLAD_GL_ARB_map_buffer_range; | 1274 | int GLAD_GL_ARB_map_buffer_range = 0; |
| 1274 | int GLAD_GL_EXT_convolution; | 1275 | int GLAD_GL_EXT_convolution = 0; |
| 1275 | int GLAD_GL_NV_compute_program5; | 1276 | int GLAD_GL_NV_compute_program5 = 0; |
| 1276 | int GLAD_GL_NV_vertex_attrib_integer_64bit; | 1277 | int GLAD_GL_NV_vertex_attrib_integer_64bit = 0; |
| 1277 | int GLAD_GL_EXT_paletted_texture; | 1278 | int GLAD_GL_EXT_paletted_texture = 0; |
| 1278 | int GLAD_GL_ARB_texture_buffer_object; | 1279 | int GLAD_GL_ARB_texture_buffer_object = 0; |
| 1279 | int GLAD_GL_ATI_pn_triangles; | 1280 | int GLAD_GL_ATI_pn_triangles = 0; |
| 1280 | int GLAD_GL_SGIX_resample; | 1281 | int GLAD_GL_SGIX_resample = 0; |
| 1281 | int GLAD_GL_SGIX_flush_raster; | 1282 | int GLAD_GL_SGIX_flush_raster = 0; |
| 1282 | int GLAD_GL_EXT_light_texture; | 1283 | int GLAD_GL_EXT_light_texture = 0; |
| 1283 | int GLAD_GL_ARB_point_sprite; | 1284 | int GLAD_GL_ARB_point_sprite = 0; |
| 1284 | int GLAD_GL_SUN_convolution_border_modes; | 1285 | int GLAD_GL_SUN_convolution_border_modes = 0; |
| 1285 | int GLAD_GL_EXT_semaphore_fd; | 1286 | int GLAD_GL_EXT_semaphore_fd = 0; |
| 1286 | int GLAD_GL_NV_parameter_buffer_object2; | 1287 | int GLAD_GL_NV_parameter_buffer_object2 = 0; |
| 1287 | int GLAD_GL_ARB_half_float_pixel; | 1288 | int GLAD_GL_ARB_half_float_pixel = 0; |
| 1288 | int GLAD_GL_NV_tessellation_program5; | 1289 | int GLAD_GL_NV_tessellation_program5 = 0; |
| 1289 | int GLAD_GL_REND_screen_coordinates; | 1290 | int GLAD_GL_REND_screen_coordinates = 0; |
| 1290 | int GLAD_GL_EXT_shared_texture_palette; | 1291 | int GLAD_GL_EXT_shared_texture_palette = 0; |
| 1291 | int GLAD_GL_EXT_packed_float; | 1292 | int GLAD_GL_EXT_packed_float = 0; |
| 1292 | int GLAD_GL_OML_subsample; | 1293 | int GLAD_GL_OML_subsample = 0; |
| 1293 | int GLAD_GL_SGIX_vertex_preclip; | 1294 | int GLAD_GL_SGIX_vertex_preclip = 0; |
| 1294 | int GLAD_GL_SGIX_texture_scale_bias; | 1295 | int GLAD_GL_SGIX_texture_scale_bias = 0; |
| 1295 | int GLAD_GL_AMD_draw_buffers_blend; | 1296 | int GLAD_GL_AMD_draw_buffers_blend = 0; |
| 1296 | int GLAD_GL_APPLE_texture_range; | 1297 | int GLAD_GL_APPLE_texture_range = 0; |
| 1297 | int GLAD_GL_EXT_texture_array; | 1298 | int GLAD_GL_EXT_texture_array = 0; |
| 1298 | int GLAD_GL_NV_texture_barrier; | 1299 | int GLAD_GL_NV_texture_barrier = 0; |
| 1299 | int GLAD_GL_ARB_texture_query_levels; | 1300 | int GLAD_GL_ARB_texture_query_levels = 0; |
| 1300 | int GLAD_GL_NV_texgen_emboss; | 1301 | int GLAD_GL_NV_texgen_emboss = 0; |
| 1301 | int GLAD_GL_EXT_texture_swizzle; | 1302 | int GLAD_GL_EXT_texture_swizzle = 0; |
| 1302 | int GLAD_GL_ARB_texture_rg; | 1303 | int GLAD_GL_ARB_texture_rg = 0; |
| 1303 | int GLAD_GL_ARB_vertex_type_2_10_10_10_rev; | 1304 | int GLAD_GL_ARB_vertex_type_2_10_10_10_rev = 0; |
| 1304 | int GLAD_GL_ARB_fragment_shader; | 1305 | int GLAD_GL_ARB_fragment_shader = 0; |
| 1305 | int GLAD_GL_3DFX_tbuffer; | 1306 | int GLAD_GL_3DFX_tbuffer = 0; |
| 1306 | int GLAD_GL_GREMEDY_frame_terminator; | 1307 | int GLAD_GL_GREMEDY_frame_terminator = 0; |
| 1307 | int GLAD_GL_IBM_cull_vertex; | 1308 | int GLAD_GL_IBM_cull_vertex = 0; |
| 1308 | int GLAD_GL_EXT_separate_shader_objects; | 1309 | int GLAD_GL_EXT_separate_shader_objects = 0; |
| 1309 | int GLAD_GL_NV_texture_multisample; | 1310 | int GLAD_GL_NV_texture_multisample = 0; |
| 1310 | int GLAD_GL_ARB_shader_objects; | 1311 | int GLAD_GL_ARB_shader_objects = 0; |
| 1311 | int GLAD_GL_ARB_framebuffer_object; | 1312 | int GLAD_GL_ARB_framebuffer_object = 0; |
| 1312 | int GLAD_GL_EXT_external_buffer; | 1313 | int GLAD_GL_EXT_external_buffer = 0; |
| 1313 | int GLAD_GL_ATI_envmap_bumpmap; | 1314 | int GLAD_GL_ATI_envmap_bumpmap = 0; |
| 1314 | int GLAD_GL_AMD_shader_explicit_vertex_parameter; | 1315 | int GLAD_GL_AMD_shader_explicit_vertex_parameter = 0; |
| 1315 | int GLAD_GL_ARB_robust_buffer_access_behavior; | 1316 | int GLAD_GL_ARB_robust_buffer_access_behavior = 0; |
| 1316 | int GLAD_GL_ARB_shader_stencil_export; | 1317 | int GLAD_GL_ARB_shader_stencil_export = 0; |
| 1317 | int GLAD_GL_NV_texture_rectangle; | 1318 | int GLAD_GL_NV_texture_rectangle = 0; |
| 1318 | int GLAD_GL_ARB_enhanced_layouts; | 1319 | int GLAD_GL_ARB_enhanced_layouts = 0; |
| 1319 | int GLAD_GL_ARB_texture_rectangle; | 1320 | int GLAD_GL_ARB_texture_rectangle = 0; |
| 1320 | int GLAD_GL_SGI_texture_color_table; | 1321 | int GLAD_GL_SGI_texture_color_table = 0; |
| 1321 | int GLAD_GL_NV_viewport_swizzle; | 1322 | int GLAD_GL_NV_viewport_swizzle = 0; |
| 1322 | int GLAD_GL_ATI_map_object_buffer; | 1323 | int GLAD_GL_ATI_map_object_buffer = 0; |
| 1323 | int GLAD_GL_ARB_robustness; | 1324 | int GLAD_GL_ARB_robustness = 0; |
| 1324 | int GLAD_GL_NV_pixel_data_range; | 1325 | int GLAD_GL_NV_pixel_data_range = 0; |
| 1325 | int GLAD_GL_EXT_framebuffer_blit; | 1326 | int GLAD_GL_EXT_framebuffer_blit = 0; |
| 1326 | int GLAD_GL_ARB_gpu_shader_fp64; | 1327 | int GLAD_GL_ARB_gpu_shader_fp64 = 0; |
| 1327 | int GLAD_GL_NV_command_list; | 1328 | int GLAD_GL_NV_command_list = 0; |
| 1328 | int GLAD_GL_SGIX_depth_texture; | 1329 | int GLAD_GL_SGIX_depth_texture = 0; |
| 1329 | int GLAD_GL_AMD_framebuffer_sample_positions; | 1330 | int GLAD_GL_AMD_framebuffer_sample_positions = 0; |
| 1330 | int GLAD_GL_GREMEDY_string_marker; | 1331 | int GLAD_GL_GREMEDY_string_marker = 0; |
| 1331 | int GLAD_GL_ARB_texture_compression_bptc; | 1332 | int GLAD_GL_ARB_texture_compression_bptc = 0; |
| 1332 | int GLAD_GL_EXT_subtexture; | 1333 | int GLAD_GL_EXT_subtexture = 0; |
| 1333 | int GLAD_GL_EXT_pixel_transform_color_table; | 1334 | int GLAD_GL_EXT_pixel_transform_color_table = 0; |
| 1334 | int GLAD_GL_EXT_texture_compression_rgtc; | 1335 | int GLAD_GL_EXT_texture_compression_rgtc = 0; |
| 1335 | int GLAD_GL_ARB_shader_atomic_counter_ops; | 1336 | int GLAD_GL_ARB_shader_atomic_counter_ops = 0; |
| 1336 | int GLAD_GL_SGIX_depth_pass_instrument; | 1337 | int GLAD_GL_SGIX_depth_pass_instrument = 0; |
| 1337 | int GLAD_GL_EXT_gpu_program_parameters; | 1338 | int GLAD_GL_EXT_gpu_program_parameters = 0; |
| 1338 | int GLAD_GL_NV_evaluators; | 1339 | int GLAD_GL_NV_evaluators = 0; |
| 1339 | int GLAD_GL_EXT_shader_framebuffer_fetch_non_coherent; | 1340 | int GLAD_GL_EXT_shader_framebuffer_fetch_non_coherent = 0; |
| 1340 | int GLAD_GL_SGIS_texture_filter4; | 1341 | int GLAD_GL_SGIS_texture_filter4 = 0; |
| 1341 | int GLAD_GL_AMD_performance_monitor; | 1342 | int GLAD_GL_AMD_performance_monitor = 0; |
| 1342 | int GLAD_GL_NV_geometry_shader4; | 1343 | int GLAD_GL_NV_geometry_shader4 = 0; |
| 1343 | int GLAD_GL_EXT_stencil_clear_tag; | 1344 | int GLAD_GL_EXT_stencil_clear_tag = 0; |
| 1344 | int GLAD_GL_NV_vertex_program1_1; | 1345 | int GLAD_GL_NV_vertex_program1_1 = 0; |
| 1345 | int GLAD_GL_NV_present_video; | 1346 | int GLAD_GL_NV_present_video = 0; |
| 1346 | int GLAD_GL_ARB_texture_compression_rgtc; | 1347 | int GLAD_GL_ARB_texture_compression_rgtc = 0; |
| 1347 | int GLAD_GL_HP_convolution_border_modes; | 1348 | int GLAD_GL_HP_convolution_border_modes = 0; |
| 1348 | int GLAD_GL_EXT_shader_integer_mix; | 1349 | int GLAD_GL_EXT_shader_integer_mix = 0; |
| 1349 | int GLAD_GL_SGIX_framezoom; | 1350 | int GLAD_GL_SGIX_framezoom = 0; |
| 1350 | int GLAD_GL_ARB_stencil_texturing; | 1351 | int GLAD_GL_ARB_stencil_texturing = 0; |
| 1351 | int GLAD_GL_ARB_shader_clock; | 1352 | int GLAD_GL_ARB_shader_clock = 0; |
| 1352 | int GLAD_GL_NV_shader_atomic_fp16_vector; | 1353 | int GLAD_GL_NV_shader_atomic_fp16_vector = 0; |
| 1353 | int GLAD_GL_SGIX_fog_offset; | 1354 | int GLAD_GL_SGIX_fog_offset = 0; |
| 1354 | int GLAD_GL_ARB_draw_elements_base_vertex; | 1355 | int GLAD_GL_ARB_draw_elements_base_vertex = 0; |
| 1355 | int GLAD_GL_INGR_interlace_read; | 1356 | int GLAD_GL_INGR_interlace_read = 0; |
| 1356 | int GLAD_GL_NV_transform_feedback; | 1357 | int GLAD_GL_NV_transform_feedback = 0; |
| 1357 | int GLAD_GL_NV_fragment_program; | 1358 | int GLAD_GL_NV_fragment_program = 0; |
| 1358 | int GLAD_GL_AMD_stencil_operation_extended; | 1359 | int GLAD_GL_AMD_stencil_operation_extended = 0; |
| 1359 | int GLAD_GL_ARB_seamless_cubemap_per_texture; | 1360 | int GLAD_GL_ARB_seamless_cubemap_per_texture = 0; |
| 1360 | int GLAD_GL_ARB_instanced_arrays; | 1361 | int GLAD_GL_ARB_instanced_arrays = 0; |
| 1361 | int GLAD_GL_ARB_get_texture_sub_image; | 1362 | int GLAD_GL_ARB_get_texture_sub_image = 0; |
| 1362 | int GLAD_GL_NV_vertex_array_range2; | 1363 | int GLAD_GL_NV_vertex_array_range2 = 0; |
| 1363 | int GLAD_GL_KHR_robustness; | 1364 | int GLAD_GL_KHR_robustness = 0; |
| 1364 | int GLAD_GL_AMD_sparse_texture; | 1365 | int GLAD_GL_AMD_sparse_texture = 0; |
| 1365 | int GLAD_GL_ARB_clip_control; | 1366 | int GLAD_GL_ARB_clip_control = 0; |
| 1366 | int GLAD_GL_NV_fragment_coverage_to_color; | 1367 | int GLAD_GL_NV_fragment_coverage_to_color = 0; |
| 1367 | int GLAD_GL_NV_fence; | 1368 | int GLAD_GL_NV_fence = 0; |
| 1368 | int GLAD_GL_ARB_texture_buffer_range; | 1369 | int GLAD_GL_ARB_texture_buffer_range = 0; |
| 1369 | int GLAD_GL_SUN_mesh_array; | 1370 | int GLAD_GL_SUN_mesh_array = 0; |
| 1370 | int GLAD_GL_ARB_vertex_attrib_binding; | 1371 | int GLAD_GL_ARB_vertex_attrib_binding = 0; |
| 1371 | int GLAD_GL_ARB_framebuffer_no_attachments; | 1372 | int GLAD_GL_ARB_framebuffer_no_attachments = 0; |
| 1372 | int GLAD_GL_ARB_cl_event; | 1373 | int GLAD_GL_ARB_cl_event = 0; |
| 1373 | int GLAD_GL_EXT_vertex_weighting; | 1374 | int GLAD_GL_EXT_vertex_weighting = 0; |
| 1374 | int GLAD_GL_ARB_derivative_control; | 1375 | int GLAD_GL_ARB_derivative_control = 0; |
| 1375 | int GLAD_GL_NV_packed_depth_stencil; | 1376 | int GLAD_GL_NV_packed_depth_stencil = 0; |
| 1376 | int GLAD_GL_OES_single_precision; | 1377 | int GLAD_GL_OES_single_precision = 0; |
| 1377 | int GLAD_GL_NV_primitive_restart; | 1378 | int GLAD_GL_NV_primitive_restart = 0; |
| 1378 | int GLAD_GL_SUN_global_alpha; | 1379 | int GLAD_GL_SUN_global_alpha = 0; |
| 1379 | int GLAD_GL_ARB_fragment_shader_interlock; | 1380 | int GLAD_GL_ARB_fragment_shader_interlock = 0; |
| 1380 | int GLAD_GL_EXT_texture_object; | 1381 | int GLAD_GL_EXT_texture_object = 0; |
| 1381 | int GLAD_GL_AMD_name_gen_delete; | 1382 | int GLAD_GL_AMD_name_gen_delete = 0; |
| 1382 | int GLAD_GL_NV_texture_compression_vtc; | 1383 | int GLAD_GL_NV_texture_compression_vtc = 0; |
| 1383 | int GLAD_GL_NV_sample_mask_override_coverage; | 1384 | int GLAD_GL_NV_sample_mask_override_coverage = 0; |
| 1384 | int GLAD_GL_NV_texture_shader3; | 1385 | int GLAD_GL_NV_texture_shader3 = 0; |
| 1385 | int GLAD_GL_MESA_tile_raster_order; | 1386 | int GLAD_GL_MESA_tile_raster_order = 0; |
| 1386 | int GLAD_GL_ARB_texture_filter_anisotropic; | 1387 | int GLAD_GL_ARB_texture_filter_anisotropic = 0; |
| 1387 | int GLAD_GL_EXT_texture; | 1388 | int GLAD_GL_EXT_texture = 0; |
| 1388 | int GLAD_GL_ARB_buffer_storage; | 1389 | int GLAD_GL_ARB_buffer_storage = 0; |
| 1389 | int GLAD_GL_AMD_shader_atomic_counter_ops; | 1390 | int GLAD_GL_AMD_shader_atomic_counter_ops = 0; |
| 1390 | int GLAD_GL_APPLE_vertex_program_evaluators; | 1391 | int GLAD_GL_APPLE_vertex_program_evaluators = 0; |
| 1391 | int GLAD_GL_AMD_texture_gather_bias_lod; | 1392 | int GLAD_GL_AMD_texture_gather_bias_lod = 0; |
| 1392 | int GLAD_GL_NV_texgen_reflection; | 1393 | int GLAD_GL_NV_texgen_reflection = 0; |
| 1393 | int GLAD_GL_ARB_explicit_uniform_location; | 1394 | int GLAD_GL_ARB_explicit_uniform_location = 0; |
| 1394 | int GLAD_GL_ARB_depth_buffer_float; | 1395 | int GLAD_GL_ARB_depth_buffer_float = 0; |
| 1395 | int GLAD_GL_NV_path_rendering_shared_edge; | 1396 | int GLAD_GL_NV_path_rendering_shared_edge = 0; |
| 1396 | int GLAD_GL_SGIX_shadow_ambient; | 1397 | int GLAD_GL_SGIX_shadow_ambient = 0; |
| 1397 | int GLAD_GL_ARB_texture_cube_map; | 1398 | int GLAD_GL_ARB_texture_cube_map = 0; |
| 1398 | int GLAD_GL_AMD_vertex_shader_viewport_index; | 1399 | int GLAD_GL_AMD_vertex_shader_viewport_index = 0; |
| 1399 | int GLAD_GL_SGIX_list_priority; | 1400 | int GLAD_GL_SGIX_list_priority = 0; |
| 1400 | int GLAD_GL_NV_vertex_buffer_unified_memory; | 1401 | int GLAD_GL_NV_vertex_buffer_unified_memory = 0; |
| 1401 | int GLAD_GL_NV_uniform_buffer_unified_memory; | 1402 | int GLAD_GL_NV_uniform_buffer_unified_memory = 0; |
| 1402 | int GLAD_GL_ARB_clear_texture; | 1403 | int GLAD_GL_ARB_clear_texture = 0; |
| 1403 | int GLAD_GL_ATI_texture_env_combine3; | 1404 | int GLAD_GL_ATI_texture_env_combine3 = 0; |
| 1404 | int GLAD_GL_NV_depth_clamp; | 1405 | int GLAD_GL_NV_depth_clamp = 0; |
| 1405 | int GLAD_GL_ARB_map_buffer_alignment; | 1406 | int GLAD_GL_ARB_map_buffer_alignment = 0; |
| 1406 | int GLAD_GL_EXT_memory_object; | 1407 | int GLAD_GL_EXT_memory_object = 0; |
| 1407 | int GLAD_GL_NV_blend_equation_advanced; | 1408 | int GLAD_GL_NV_blend_equation_advanced = 0; |
| 1408 | int GLAD_GL_SGIS_sharpen_texture; | 1409 | int GLAD_GL_SGIS_sharpen_texture = 0; |
| 1409 | int GLAD_GL_KHR_robust_buffer_access_behavior; | 1410 | int GLAD_GL_KHR_robust_buffer_access_behavior = 0; |
| 1410 | int GLAD_GL_ARB_pipeline_statistics_query; | 1411 | int GLAD_GL_ARB_pipeline_statistics_query = 0; |
| 1411 | int GLAD_GL_ARB_vertex_program; | 1412 | int GLAD_GL_ARB_vertex_program = 0; |
| 1412 | int GLAD_GL_ARB_texture_rgb10_a2ui; | 1413 | int GLAD_GL_ARB_texture_rgb10_a2ui = 0; |
| 1413 | int GLAD_GL_OML_interlace; | 1414 | int GLAD_GL_OML_interlace = 0; |
| 1414 | int GLAD_GL_ATI_pixel_format_float; | 1415 | int GLAD_GL_ATI_pixel_format_float = 0; |
| 1415 | int GLAD_GL_NV_clip_space_w_scaling; | 1416 | int GLAD_GL_NV_clip_space_w_scaling = 0; |
| 1416 | int GLAD_GL_ARB_vertex_buffer_object; | 1417 | int GLAD_GL_ARB_vertex_buffer_object = 0; |
| 1417 | int GLAD_GL_EXT_shadow_funcs; | 1418 | int GLAD_GL_EXT_shadow_funcs = 0; |
| 1418 | int GLAD_GL_ATI_text_fragment_shader; | 1419 | int GLAD_GL_ATI_text_fragment_shader = 0; |
| 1419 | int GLAD_GL_NV_vertex_array_range; | 1420 | int GLAD_GL_NV_vertex_array_range = 0; |
| 1420 | int GLAD_GL_SGIX_fragment_lighting; | 1421 | int GLAD_GL_SGIX_fragment_lighting = 0; |
| 1421 | int GLAD_GL_AMD_shader_ballot; | 1422 | int GLAD_GL_AMD_shader_ballot = 0; |
| 1422 | int GLAD_GL_NV_texture_expand_normal; | 1423 | int GLAD_GL_NV_texture_expand_normal = 0; |
| 1423 | int GLAD_GL_NV_framebuffer_multisample_coverage; | 1424 | int GLAD_GL_NV_framebuffer_multisample_coverage = 0; |
| 1424 | int GLAD_GL_EXT_timer_query; | 1425 | int GLAD_GL_EXT_timer_query = 0; |
| 1425 | int GLAD_GL_EXT_vertex_array_bgra; | 1426 | int GLAD_GL_EXT_vertex_array_bgra = 0; |
| 1426 | int GLAD_GL_NV_bindless_texture; | 1427 | int GLAD_GL_NV_bindless_texture = 0; |
| 1427 | int GLAD_GL_KHR_debug; | 1428 | int GLAD_GL_KHR_debug = 0; |
| 1428 | int GLAD_GL_SGIS_texture_border_clamp; | 1429 | int GLAD_GL_SGIS_texture_border_clamp = 0; |
| 1429 | int GLAD_GL_ATI_vertex_attrib_array_object; | 1430 | int GLAD_GL_ATI_vertex_attrib_array_object = 0; |
| 1430 | int GLAD_GL_SGIX_clipmap; | 1431 | int GLAD_GL_SGIX_clipmap = 0; |
| 1431 | int GLAD_GL_EXT_geometry_shader4; | 1432 | int GLAD_GL_EXT_geometry_shader4 = 0; |
| 1432 | int GLAD_GL_ARB_shader_texture_image_samples; | 1433 | int GLAD_GL_ARB_shader_texture_image_samples = 0; |
| 1433 | int GLAD_GL_MESA_ycbcr_texture; | 1434 | int GLAD_GL_MESA_ycbcr_texture = 0; |
| 1434 | int GLAD_GL_MESAX_texture_stack; | 1435 | int GLAD_GL_MESAX_texture_stack = 0; |
| 1435 | int GLAD_GL_AMD_seamless_cubemap_per_texture; | 1436 | int GLAD_GL_AMD_seamless_cubemap_per_texture = 0; |
| 1436 | int GLAD_GL_EXT_bindable_uniform; | 1437 | int GLAD_GL_EXT_bindable_uniform = 0; |
| 1437 | int GLAD_GL_KHR_texture_compression_astc_hdr; | 1438 | int GLAD_GL_KHR_texture_compression_astc_hdr = 0; |
| 1438 | int GLAD_GL_ARB_shader_ballot; | 1439 | int GLAD_GL_ARB_shader_ballot = 0; |
| 1439 | int GLAD_GL_KHR_blend_equation_advanced; | 1440 | int GLAD_GL_KHR_blend_equation_advanced = 0; |
| 1440 | int GLAD_GL_ARB_fragment_program_shadow; | 1441 | int GLAD_GL_ARB_fragment_program_shadow = 0; |
| 1441 | int GLAD_GL_ATI_element_array; | 1442 | int GLAD_GL_ATI_element_array = 0; |
| 1442 | int GLAD_GL_AMD_texture_texture4; | 1443 | int GLAD_GL_AMD_texture_texture4 = 0; |
| 1443 | int GLAD_GL_SGIX_reference_plane; | 1444 | int GLAD_GL_SGIX_reference_plane = 0; |
| 1444 | int GLAD_GL_EXT_stencil_two_side; | 1445 | int GLAD_GL_EXT_stencil_two_side = 0; |
| 1445 | int GLAD_GL_ARB_transform_feedback_overflow_query; | 1446 | int GLAD_GL_ARB_transform_feedback_overflow_query = 0; |
| 1446 | int GLAD_GL_SGIX_texture_lod_bias; | 1447 | int GLAD_GL_SGIX_texture_lod_bias = 0; |
| 1447 | int GLAD_GL_KHR_no_error; | 1448 | int GLAD_GL_KHR_no_error = 0; |
| 1448 | int GLAD_GL_NV_explicit_multisample; | 1449 | int GLAD_GL_NV_explicit_multisample = 0; |
| 1449 | int GLAD_GL_NV_stereo_view_rendering; | 1450 | int GLAD_GL_NV_stereo_view_rendering = 0; |
| 1450 | int GLAD_GL_IBM_static_data; | 1451 | int GLAD_GL_IBM_static_data = 0; |
| 1451 | int GLAD_GL_EXT_clip_volume_hint; | 1452 | int GLAD_GL_EXT_clip_volume_hint = 0; |
| 1452 | int GLAD_GL_EXT_texture_perturb_normal; | 1453 | int GLAD_GL_EXT_texture_perturb_normal = 0; |
| 1453 | int GLAD_GL_NV_fragment_program2; | 1454 | int GLAD_GL_NV_fragment_program2 = 0; |
| 1454 | int GLAD_GL_NV_fragment_program4; | 1455 | int GLAD_GL_NV_fragment_program4 = 0; |
| 1455 | int GLAD_GL_EXT_point_parameters; | 1456 | int GLAD_GL_EXT_point_parameters = 0; |
| 1456 | int GLAD_GL_PGI_misc_hints; | 1457 | int GLAD_GL_PGI_misc_hints = 0; |
| 1457 | int GLAD_GL_EXT_EGL_image_storage; | 1458 | int GLAD_GL_EXT_EGL_image_storage = 0; |
| 1458 | int GLAD_GL_SGIX_subsample; | 1459 | int GLAD_GL_SGIX_subsample = 0; |
| 1459 | int GLAD_GL_AMD_shader_stencil_export; | 1460 | int GLAD_GL_AMD_shader_stencil_export = 0; |
| 1460 | int GLAD_GL_ARB_shader_texture_lod; | 1461 | int GLAD_GL_ARB_shader_texture_lod = 0; |
| 1461 | int GLAD_GL_ARB_vertex_shader; | 1462 | int GLAD_GL_ARB_vertex_shader = 0; |
| 1462 | int GLAD_GL_ARB_depth_clamp; | 1463 | int GLAD_GL_ARB_depth_clamp = 0; |
| 1463 | int GLAD_GL_SGIS_texture_select; | 1464 | int GLAD_GL_SGIS_texture_select = 0; |
| 1464 | int GLAD_GL_NV_texture_shader; | 1465 | int GLAD_GL_NV_texture_shader = 0; |
| 1465 | int GLAD_GL_ARB_tessellation_shader; | 1466 | int GLAD_GL_ARB_tessellation_shader = 0; |
| 1466 | int GLAD_GL_EXT_draw_buffers2; | 1467 | int GLAD_GL_EXT_draw_buffers2 = 0; |
| 1467 | int GLAD_GL_ARB_vertex_attrib_64bit; | 1468 | int GLAD_GL_ARB_vertex_attrib_64bit = 0; |
| 1468 | int GLAD_GL_EXT_texture_filter_minmax; | 1469 | int GLAD_GL_EXT_texture_filter_minmax = 0; |
| 1469 | int GLAD_GL_NV_query_resource; | 1470 | int GLAD_GL_NV_query_resource = 0; |
| 1470 | int GLAD_GL_AMD_interleaved_elements; | 1471 | int GLAD_GL_AMD_interleaved_elements = 0; |
| 1471 | int GLAD_GL_ARB_fragment_program; | 1472 | int GLAD_GL_ARB_fragment_program = 0; |
| 1472 | int GLAD_GL_OML_resample; | 1473 | int GLAD_GL_OML_resample = 0; |
| 1473 | int GLAD_GL_APPLE_ycbcr_422; | 1474 | int GLAD_GL_APPLE_ycbcr_422 = 0; |
| 1474 | int GLAD_GL_SGIX_texture_add_env; | 1475 | int GLAD_GL_SGIX_texture_add_env = 0; |
| 1475 | int GLAD_GL_ARB_shadow_ambient; | 1476 | int GLAD_GL_ARB_shadow_ambient = 0; |
| 1476 | int GLAD_GL_ARB_texture_storage; | 1477 | int GLAD_GL_ARB_texture_storage = 0; |
| 1477 | int GLAD_GL_EXT_pixel_buffer_object; | 1478 | int GLAD_GL_EXT_pixel_buffer_object = 0; |
| 1478 | int GLAD_GL_ARB_copy_image; | 1479 | int GLAD_GL_ARB_copy_image = 0; |
| 1479 | int GLAD_GL_SGIS_pixel_texture; | 1480 | int GLAD_GL_SGIS_pixel_texture = 0; |
| 1480 | int GLAD_GL_SGIS_generate_mipmap; | 1481 | int GLAD_GL_SGIS_generate_mipmap = 0; |
| 1481 | int GLAD_GL_SGIX_instruments; | 1482 | int GLAD_GL_SGIX_instruments = 0; |
| 1482 | int GLAD_GL_ARB_fragment_layer_viewport; | 1483 | int GLAD_GL_ARB_fragment_layer_viewport = 0; |
| 1483 | int GLAD_GL_ARB_shader_storage_buffer_object; | 1484 | int GLAD_GL_ARB_shader_storage_buffer_object = 0; |
| 1484 | int GLAD_GL_EXT_sparse_texture2; | 1485 | int GLAD_GL_EXT_sparse_texture2 = 0; |
| 1485 | int GLAD_GL_EXT_blend_minmax; | 1486 | int GLAD_GL_EXT_blend_minmax = 0; |
| 1486 | int GLAD_GL_MESA_pack_invert; | 1487 | int GLAD_GL_MESA_pack_invert = 0; |
| 1487 | int GLAD_GL_ARB_base_instance; | 1488 | int GLAD_GL_ARB_base_instance = 0; |
| 1488 | int GLAD_GL_SGIX_convolution_accuracy; | 1489 | int GLAD_GL_SGIX_convolution_accuracy = 0; |
| 1489 | int GLAD_GL_PGI_vertex_hints; | 1490 | int GLAD_GL_PGI_vertex_hints = 0; |
| 1490 | int GLAD_GL_AMD_transform_feedback4; | 1491 | int GLAD_GL_AMD_transform_feedback4 = 0; |
| 1491 | int GLAD_GL_ARB_ES3_1_compatibility; | 1492 | int GLAD_GL_ARB_ES3_1_compatibility = 0; |
| 1492 | int GLAD_GL_EXT_memory_object_win32; | 1493 | int GLAD_GL_EXT_memory_object_win32 = 0; |
| 1493 | int GLAD_GL_EXT_texture_integer; | 1494 | int GLAD_GL_EXT_texture_integer = 0; |
| 1494 | int GLAD_GL_ARB_texture_multisample; | 1495 | int GLAD_GL_ARB_texture_multisample = 0; |
| 1495 | int GLAD_GL_ATI_vertex_streams; | 1496 | int GLAD_GL_ATI_vertex_streams = 0; |
| 1496 | int GLAD_GL_AMD_gpu_shader_int64; | 1497 | int GLAD_GL_AMD_gpu_shader_int64 = 0; |
| 1497 | int GLAD_GL_S3_s3tc; | 1498 | int GLAD_GL_S3_s3tc = 0; |
| 1498 | int GLAD_GL_ARB_query_buffer_object; | 1499 | int GLAD_GL_ARB_query_buffer_object = 0; |
| 1499 | int GLAD_GL_AMD_vertex_shader_tessellator; | 1500 | int GLAD_GL_AMD_vertex_shader_tessellator = 0; |
| 1500 | int GLAD_GL_ARB_invalidate_subdata; | 1501 | int GLAD_GL_ARB_invalidate_subdata = 0; |
| 1501 | int GLAD_GL_NV_draw_vulkan_image; | 1502 | int GLAD_GL_NV_draw_vulkan_image = 0; |
| 1502 | int GLAD_GL_EXT_index_material; | 1503 | int GLAD_GL_EXT_index_material = 0; |
| 1503 | int GLAD_GL_NVX_linked_gpu_multicast; | 1504 | int GLAD_GL_NVX_linked_gpu_multicast = 0; |
| 1504 | int GLAD_GL_NV_blend_equation_advanced_coherent; | 1505 | int GLAD_GL_NV_blend_equation_advanced_coherent = 0; |
| 1505 | int GLAD_GL_KHR_texture_compression_astc_sliced_3d; | 1506 | int GLAD_GL_KHR_texture_compression_astc_sliced_3d = 0; |
| 1506 | int GLAD_GL_INTEL_parallel_arrays; | 1507 | int GLAD_GL_INTEL_parallel_arrays = 0; |
| 1507 | int GLAD_GL_ATI_draw_buffers; | 1508 | int GLAD_GL_ATI_draw_buffers = 0; |
| 1508 | int GLAD_GL_WIN_specular_fog; | 1509 | int GLAD_GL_WIN_specular_fog = 0; |
| 1509 | int GLAD_GL_EXT_cmyka; | 1510 | int GLAD_GL_EXT_cmyka = 0; |
| 1510 | int GLAD_GL_SGIX_pixel_texture; | 1511 | int GLAD_GL_SGIX_pixel_texture = 0; |
| 1511 | int GLAD_GL_APPLE_specular_vector; | 1512 | int GLAD_GL_APPLE_specular_vector = 0; |
| 1512 | int GLAD_GL_ARB_compatibility; | 1513 | int GLAD_GL_ARB_compatibility = 0; |
| 1513 | int GLAD_GL_ARB_timer_query; | 1514 | int GLAD_GL_ARB_timer_query = 0; |
| 1514 | int GLAD_GL_SGIX_interlace; | 1515 | int GLAD_GL_SGIX_interlace = 0; |
| 1515 | int GLAD_GL_NV_parameter_buffer_object; | 1516 | int GLAD_GL_NV_parameter_buffer_object = 0; |
| 1516 | int GLAD_GL_AMD_shader_trinary_minmax; | 1517 | int GLAD_GL_AMD_shader_trinary_minmax = 0; |
| 1517 | int GLAD_GL_ARB_direct_state_access; | 1518 | int GLAD_GL_ARB_direct_state_access = 0; |
| 1518 | int GLAD_GL_EXT_rescale_normal; | 1519 | int GLAD_GL_EXT_rescale_normal = 0; |
| 1519 | int GLAD_GL_ARB_pixel_buffer_object; | 1520 | int GLAD_GL_ARB_pixel_buffer_object = 0; |
| 1520 | int GLAD_GL_ARB_uniform_buffer_object; | 1521 | int GLAD_GL_ARB_uniform_buffer_object = 0; |
| 1521 | int GLAD_GL_ARB_vertex_type_10f_11f_11f_rev; | 1522 | int GLAD_GL_ARB_vertex_type_10f_11f_11f_rev = 0; |
| 1522 | int GLAD_GL_ARB_texture_swizzle; | 1523 | int GLAD_GL_ARB_texture_swizzle = 0; |
| 1523 | int GLAD_GL_NV_transform_feedback2; | 1524 | int GLAD_GL_NV_transform_feedback2 = 0; |
| 1524 | int GLAD_GL_SGIX_async_pixel; | 1525 | int GLAD_GL_SGIX_async_pixel = 0; |
| 1525 | int GLAD_GL_NV_fragment_program_option; | 1526 | int GLAD_GL_NV_fragment_program_option = 0; |
| 1526 | int GLAD_GL_ARB_explicit_attrib_location; | 1527 | int GLAD_GL_ARB_explicit_attrib_location = 0; |
| 1527 | int GLAD_GL_EXT_blend_color; | 1528 | int GLAD_GL_EXT_blend_color = 0; |
| 1528 | int GLAD_GL_NV_shader_thread_group; | 1529 | int GLAD_GL_NV_shader_thread_group = 0; |
| 1529 | int GLAD_GL_EXT_stencil_wrap; | 1530 | int GLAD_GL_EXT_stencil_wrap = 0; |
| 1530 | int GLAD_GL_EXT_index_array_formats; | 1531 | int GLAD_GL_EXT_index_array_formats = 0; |
| 1531 | int GLAD_GL_OVR_multiview2; | 1532 | int GLAD_GL_OVR_multiview2 = 0; |
| 1532 | int GLAD_GL_EXT_histogram; | 1533 | int GLAD_GL_EXT_histogram = 0; |
| 1533 | int GLAD_GL_EXT_polygon_offset; | 1534 | int GLAD_GL_EXT_polygon_offset = 0; |
| 1534 | int GLAD_GL_SGIS_point_parameters; | 1535 | int GLAD_GL_SGIS_point_parameters = 0; |
| 1535 | int GLAD_GL_SGIX_ycrcb; | 1536 | int GLAD_GL_SGIX_ycrcb = 0; |
| 1536 | int GLAD_GL_EXT_direct_state_access; | 1537 | int GLAD_GL_EXT_direct_state_access = 0; |
| 1537 | int GLAD_GL_ARB_cull_distance; | 1538 | int GLAD_GL_ARB_cull_distance = 0; |
| 1538 | int GLAD_GL_AMD_sample_positions; | 1539 | int GLAD_GL_AMD_sample_positions = 0; |
| 1539 | int GLAD_GL_NV_vertex_program; | 1540 | int GLAD_GL_NV_vertex_program = 0; |
| 1540 | int GLAD_GL_NV_shader_thread_shuffle; | 1541 | int GLAD_GL_NV_shader_thread_shuffle = 0; |
| 1541 | int GLAD_GL_ARB_shader_precision; | 1542 | int GLAD_GL_ARB_shader_precision = 0; |
| 1542 | int GLAD_GL_EXT_vertex_shader; | 1543 | int GLAD_GL_EXT_vertex_shader = 0; |
| 1543 | int GLAD_GL_EXT_blend_func_separate; | 1544 | int GLAD_GL_EXT_blend_func_separate = 0; |
| 1544 | int GLAD_GL_APPLE_fence; | 1545 | int GLAD_GL_APPLE_fence = 0; |
| 1545 | int GLAD_GL_NV_query_resource_tag; | 1546 | int GLAD_GL_NV_query_resource_tag = 0; |
| 1546 | int GLAD_GL_OES_byte_coordinates; | 1547 | int GLAD_GL_OES_byte_coordinates = 0; |
| 1547 | int GLAD_GL_ARB_transpose_matrix; | 1548 | int GLAD_GL_ARB_transpose_matrix = 0; |
| 1548 | int GLAD_GL_ARB_provoking_vertex; | 1549 | int GLAD_GL_ARB_provoking_vertex = 0; |
| 1549 | int GLAD_GL_EXT_fog_coord; | 1550 | int GLAD_GL_EXT_fog_coord = 0; |
| 1550 | int GLAD_GL_EXT_vertex_array; | 1551 | int GLAD_GL_EXT_vertex_array = 0; |
| 1551 | int GLAD_GL_ARB_half_float_vertex; | 1552 | int GLAD_GL_ARB_half_float_vertex = 0; |
| 1552 | int GLAD_GL_EXT_blend_equation_separate; | 1553 | int GLAD_GL_EXT_blend_equation_separate = 0; |
| 1553 | int GLAD_GL_NV_framebuffer_mixed_samples; | 1554 | int GLAD_GL_NV_framebuffer_mixed_samples = 0; |
| 1554 | int GLAD_GL_NVX_conditional_render; | 1555 | int GLAD_GL_NVX_conditional_render = 0; |
| 1555 | int GLAD_GL_ARB_multi_draw_indirect; | 1556 | int GLAD_GL_ARB_multi_draw_indirect = 0; |
| 1556 | int GLAD_GL_EXT_raster_multisample; | 1557 | int GLAD_GL_EXT_raster_multisample = 0; |
| 1557 | int GLAD_GL_NV_copy_image; | 1558 | int GLAD_GL_NV_copy_image = 0; |
| 1558 | int GLAD_GL_HP_texture_lighting; | 1559 | int GLAD_GL_HP_texture_lighting = 0; |
| 1559 | int GLAD_GL_INTEL_framebuffer_CMAA; | 1560 | int GLAD_GL_INTEL_framebuffer_CMAA = 0; |
| 1560 | int GLAD_GL_ARB_transform_feedback2; | 1561 | int GLAD_GL_ARB_transform_feedback2 = 0; |
| 1561 | int GLAD_GL_ARB_transform_feedback3; | 1562 | int GLAD_GL_ARB_transform_feedback3 = 0; |
| 1562 | int GLAD_GL_SGIX_ycrcba; | 1563 | int GLAD_GL_SGIX_ycrcba = 0; |
| 1563 | int GLAD_GL_EXT_debug_marker; | 1564 | int GLAD_GL_EXT_debug_marker = 0; |
| 1564 | int GLAD_GL_EXT_bgra; | 1565 | int GLAD_GL_EXT_bgra = 0; |
| 1565 | int GLAD_GL_ARB_sparse_texture_clamp; | 1566 | int GLAD_GL_ARB_sparse_texture_clamp = 0; |
| 1566 | int GLAD_GL_EXT_pixel_transform; | 1567 | int GLAD_GL_EXT_pixel_transform = 0; |
| 1567 | int GLAD_GL_ARB_conservative_depth; | 1568 | int GLAD_GL_ARB_conservative_depth = 0; |
| 1568 | int GLAD_GL_ATI_fragment_shader; | 1569 | int GLAD_GL_ATI_fragment_shader = 0; |
| 1569 | int GLAD_GL_ARB_vertex_array_object; | 1570 | int GLAD_GL_ARB_vertex_array_object = 0; |
| 1570 | int GLAD_GL_SUN_triangle_list; | 1571 | int GLAD_GL_SUN_triangle_list = 0; |
| 1571 | int GLAD_GL_EXT_texture_env_add; | 1572 | int GLAD_GL_EXT_texture_env_add = 0; |
| 1572 | int GLAD_GL_EXT_packed_depth_stencil; | 1573 | int GLAD_GL_EXT_packed_depth_stencil = 0; |
| 1573 | int GLAD_GL_EXT_texture_mirror_clamp; | 1574 | int GLAD_GL_EXT_texture_mirror_clamp = 0; |
| 1574 | int GLAD_GL_NV_multisample_filter_hint; | 1575 | int GLAD_GL_NV_multisample_filter_hint = 0; |
| 1575 | int GLAD_GL_APPLE_float_pixels; | 1576 | int GLAD_GL_APPLE_float_pixels = 0; |
| 1576 | int GLAD_GL_ARB_transform_feedback_instanced; | 1577 | int GLAD_GL_ARB_transform_feedback_instanced = 0; |
| 1577 | int GLAD_GL_SGIX_async; | 1578 | int GLAD_GL_SGIX_async = 0; |
| 1578 | int GLAD_GL_EXT_texture_compression_latc; | 1579 | int GLAD_GL_EXT_texture_compression_latc = 0; |
| 1579 | int GLAD_GL_NV_robustness_video_memory_purge; | 1580 | int GLAD_GL_NV_robustness_video_memory_purge = 0; |
| 1580 | int GLAD_GL_ARB_shading_language_100; | 1581 | int GLAD_GL_ARB_shading_language_100 = 0; |
| 1581 | int GLAD_GL_INTEL_performance_query; | 1582 | int GLAD_GL_INTEL_performance_query = 0; |
| 1582 | int GLAD_GL_ARB_texture_mirror_clamp_to_edge; | 1583 | int GLAD_GL_ARB_texture_mirror_clamp_to_edge = 0; |
| 1583 | int GLAD_GL_NV_gpu_shader5; | 1584 | int GLAD_GL_NV_gpu_shader5 = 0; |
| 1584 | int GLAD_GL_NV_bindless_multi_draw_indirect_count; | 1585 | int GLAD_GL_NV_bindless_multi_draw_indirect_count = 0; |
| 1585 | int GLAD_GL_ARB_ES2_compatibility; | 1586 | int GLAD_GL_ARB_ES2_compatibility = 0; |
| 1586 | int GLAD_GL_ARB_indirect_parameters; | 1587 | int GLAD_GL_ARB_indirect_parameters = 0; |
| 1587 | int GLAD_GL_EXT_window_rectangles; | 1588 | int GLAD_GL_EXT_window_rectangles = 0; |
| 1588 | int GLAD_GL_NV_half_float; | 1589 | int GLAD_GL_NV_half_float = 0; |
| 1589 | int GLAD_GL_ARB_ES3_2_compatibility; | 1590 | int GLAD_GL_ARB_ES3_2_compatibility = 0; |
| 1590 | int GLAD_GL_ATI_texture_mirror_once; | 1591 | int GLAD_GL_ATI_texture_mirror_once = 0; |
| 1591 | int GLAD_GL_IBM_rasterpos_clip; | 1592 | int GLAD_GL_IBM_rasterpos_clip = 0; |
| 1592 | int GLAD_GL_EXT_semaphore; | 1593 | int GLAD_GL_EXT_semaphore = 0; |
| 1593 | int GLAD_GL_SGIX_shadow; | 1594 | int GLAD_GL_SGIX_shadow = 0; |
| 1594 | int GLAD_GL_EXT_polygon_offset_clamp; | 1595 | int GLAD_GL_EXT_polygon_offset_clamp = 0; |
| 1595 | int GLAD_GL_NV_deep_texture3D; | 1596 | int GLAD_GL_NV_deep_texture3D = 0; |
| 1596 | int GLAD_GL_ARB_shader_draw_parameters; | 1597 | int GLAD_GL_ARB_shader_draw_parameters = 0; |
| 1597 | int GLAD_GL_SGIX_calligraphic_fragment; | 1598 | int GLAD_GL_SGIX_calligraphic_fragment = 0; |
| 1598 | int GLAD_GL_ARB_shader_bit_encoding; | 1599 | int GLAD_GL_ARB_shader_bit_encoding = 0; |
| 1599 | int GLAD_GL_EXT_compiled_vertex_array; | 1600 | int GLAD_GL_EXT_compiled_vertex_array = 0; |
| 1600 | int GLAD_GL_NV_depth_buffer_float; | 1601 | int GLAD_GL_NV_depth_buffer_float = 0; |
| 1601 | int GLAD_GL_NV_occlusion_query; | 1602 | int GLAD_GL_NV_occlusion_query = 0; |
| 1602 | int GLAD_GL_APPLE_flush_buffer_range; | 1603 | int GLAD_GL_APPLE_flush_buffer_range = 0; |
| 1603 | int GLAD_GL_ARB_imaging; | 1604 | int GLAD_GL_ARB_imaging = 0; |
| 1604 | int GLAD_GL_NV_shader_atomic_float; | 1605 | int GLAD_GL_NV_shader_atomic_float = 0; |
| 1605 | int GLAD_GL_ARB_draw_buffers_blend; | 1606 | int GLAD_GL_ARB_draw_buffers_blend = 0; |
| 1606 | int GLAD_GL_AMD_gcn_shader; | 1607 | int GLAD_GL_AMD_gcn_shader = 0; |
| 1607 | int GLAD_GL_AMD_blend_minmax_factor; | 1608 | int GLAD_GL_AMD_blend_minmax_factor = 0; |
| 1608 | int GLAD_GL_EXT_texture_sRGB_decode; | 1609 | int GLAD_GL_EXT_texture_sRGB_decode = 0; |
| 1609 | int GLAD_GL_ARB_shading_language_420pack; | 1610 | int GLAD_GL_ARB_shading_language_420pack = 0; |
| 1610 | int GLAD_GL_ARB_shader_viewport_layer_array; | 1611 | int GLAD_GL_ARB_shader_viewport_layer_array = 0; |
| 1611 | int GLAD_GL_ATI_meminfo; | 1612 | int GLAD_GL_ATI_meminfo = 0; |
| 1612 | int GLAD_GL_EXT_abgr; | 1613 | int GLAD_GL_EXT_abgr = 0; |
| 1613 | int GLAD_GL_AMD_pinned_memory; | 1614 | int GLAD_GL_AMD_pinned_memory = 0; |
| 1614 | int GLAD_GL_EXT_texture_snorm; | 1615 | int GLAD_GL_EXT_texture_snorm = 0; |
| 1615 | int GLAD_GL_SGIX_texture_coordinate_clamp; | 1616 | int GLAD_GL_SGIX_texture_coordinate_clamp = 0; |
| 1616 | int GLAD_GL_ARB_clear_buffer_object; | 1617 | int GLAD_GL_ARB_clear_buffer_object = 0; |
| 1617 | int GLAD_GL_ARB_multisample; | 1618 | int GLAD_GL_ARB_multisample = 0; |
| 1618 | int GLAD_GL_EXT_debug_label; | 1619 | int GLAD_GL_EXT_debug_label = 0; |
| 1619 | int GLAD_GL_ARB_sample_shading; | 1620 | int GLAD_GL_ARB_sample_shading = 0; |
| 1620 | int GLAD_GL_NV_internalformat_sample_query; | 1621 | int GLAD_GL_NV_internalformat_sample_query = 0; |
| 1621 | int GLAD_GL_INTEL_map_texture; | 1622 | int GLAD_GL_INTEL_map_texture = 0; |
| 1622 | int GLAD_GL_ARB_texture_env_crossbar; | 1623 | int GLAD_GL_ARB_texture_env_crossbar = 0; |
| 1623 | int GLAD_GL_EXT_422_pixels; | 1624 | int GLAD_GL_EXT_422_pixels = 0; |
| 1624 | int GLAD_GL_NV_blend_minmax_factor; | 1625 | int GLAD_GL_NV_blend_minmax_factor = 0; |
| 1625 | int GLAD_GL_NV_conservative_raster_pre_snap_triangles; | 1626 | int GLAD_GL_NV_conservative_raster_pre_snap_triangles = 0; |
| 1626 | int GLAD_GL_ARB_compute_shader; | 1627 | int GLAD_GL_ARB_compute_shader = 0; |
| 1627 | int GLAD_GL_EXT_blend_logic_op; | 1628 | int GLAD_GL_EXT_blend_logic_op = 0; |
| 1628 | int GLAD_GL_ARB_blend_func_extended; | 1629 | int GLAD_GL_ARB_blend_func_extended = 0; |
| 1629 | int GLAD_GL_IBM_vertex_array_lists; | 1630 | int GLAD_GL_IBM_vertex_array_lists = 0; |
| 1630 | int GLAD_GL_ARB_color_buffer_float; | 1631 | int GLAD_GL_ARB_color_buffer_float = 0; |
| 1631 | int GLAD_GL_ARB_bindless_texture; | 1632 | int GLAD_GL_ARB_bindless_texture = 0; |
| 1632 | int GLAD_GL_ARB_window_pos; | 1633 | int GLAD_GL_ARB_window_pos = 0; |
| 1633 | int GLAD_GL_ARB_internalformat_query; | 1634 | int GLAD_GL_ARB_internalformat_query = 0; |
| 1634 | int GLAD_GL_ARB_shadow; | 1635 | int GLAD_GL_ARB_shadow = 0; |
| 1635 | int GLAD_GL_ARB_texture_mirrored_repeat; | 1636 | int GLAD_GL_ARB_texture_mirrored_repeat = 0; |
| 1636 | int GLAD_GL_EXT_shader_image_load_store; | 1637 | int GLAD_GL_EXT_shader_image_load_store = 0; |
| 1637 | int GLAD_GL_EXT_copy_texture; | 1638 | int GLAD_GL_EXT_copy_texture = 0; |
| 1638 | int GLAD_GL_NV_register_combiners2; | 1639 | int GLAD_GL_NV_register_combiners2 = 0; |
| 1639 | int GLAD_GL_SGIX_ycrcb_subsample; | 1640 | int GLAD_GL_SGIX_ycrcb_subsample = 0; |
| 1640 | int GLAD_GL_NV_alpha_to_coverage_dither_control; | 1641 | int GLAD_GL_NV_alpha_to_coverage_dither_control = 0; |
| 1641 | int GLAD_GL_SGIX_ir_instrument1; | 1642 | int GLAD_GL_SGIX_ir_instrument1 = 0; |
| 1642 | int GLAD_GL_NV_draw_texture; | 1643 | int GLAD_GL_NV_draw_texture = 0; |
| 1643 | int GLAD_GL_EXT_texture_shared_exponent; | 1644 | int GLAD_GL_EXT_texture_shared_exponent = 0; |
| 1644 | int GLAD_GL_NV_texture_shader2; | 1645 | int GLAD_GL_NV_texture_shader2 = 0; |
| 1645 | int GLAD_GL_EXT_draw_instanced; | 1646 | int GLAD_GL_EXT_draw_instanced = 0; |
| 1646 | int GLAD_GL_NV_copy_depth_to_color; | 1647 | int GLAD_GL_NV_copy_depth_to_color = 0; |
| 1647 | int GLAD_GL_ARB_viewport_array; | 1648 | int GLAD_GL_ARB_viewport_array = 0; |
| 1648 | int GLAD_GL_ARB_separate_shader_objects; | 1649 | int GLAD_GL_ARB_separate_shader_objects = 0; |
| 1649 | int GLAD_GL_NV_conservative_raster_pre_snap; | 1650 | int GLAD_GL_NV_conservative_raster_pre_snap = 0; |
| 1650 | int GLAD_GL_EXT_depth_bounds_test; | 1651 | int GLAD_GL_EXT_depth_bounds_test = 0; |
| 1651 | int GLAD_GL_HP_image_transform; | 1652 | int GLAD_GL_HP_image_transform = 0; |
| 1652 | int GLAD_GL_ARB_texture_env_add; | 1653 | int GLAD_GL_ARB_texture_env_add = 0; |
| 1653 | int GLAD_GL_NV_video_capture; | 1654 | int GLAD_GL_NV_video_capture = 0; |
| 1654 | int GLAD_GL_ARB_sampler_objects; | 1655 | int GLAD_GL_ARB_sampler_objects = 0; |
| 1655 | int GLAD_GL_ARB_matrix_palette; | 1656 | int GLAD_GL_ARB_matrix_palette = 0; |
| 1656 | int GLAD_GL_SGIS_texture_color_mask; | 1657 | int GLAD_GL_SGIS_texture_color_mask = 0; |
| 1657 | int GLAD_GL_EXT_packed_pixels; | 1658 | int GLAD_GL_EXT_packed_pixels = 0; |
| 1658 | int GLAD_GL_EXT_coordinate_frame; | 1659 | int GLAD_GL_EXT_coordinate_frame = 0; |
| 1659 | int GLAD_GL_ARB_texture_compression; | 1660 | int GLAD_GL_ARB_texture_compression = 0; |
| 1660 | int GLAD_GL_ARB_multi_bind; | 1661 | int GLAD_GL_ARB_multi_bind = 0; |
| 1661 | int GLAD_GL_APPLE_aux_depth_stencil; | 1662 | int GLAD_GL_APPLE_aux_depth_stencil = 0; |
| 1662 | int GLAD_GL_ARB_shader_subroutine; | 1663 | int GLAD_GL_ARB_shader_subroutine = 0; |
| 1663 | int GLAD_GL_EXT_framebuffer_sRGB; | 1664 | int GLAD_GL_EXT_framebuffer_sRGB = 0; |
| 1664 | int GLAD_GL_ARB_texture_storage_multisample; | 1665 | int GLAD_GL_ARB_texture_storage_multisample = 0; |
| 1665 | int GLAD_GL_KHR_blend_equation_advanced_coherent; | 1666 | int GLAD_GL_KHR_blend_equation_advanced_coherent = 0; |
| 1666 | int GLAD_GL_EXT_vertex_attrib_64bit; | 1667 | int GLAD_GL_EXT_vertex_attrib_64bit = 0; |
| 1667 | int GLAD_GL_NV_shader_atomic_float64; | 1668 | int GLAD_GL_NV_shader_atomic_float64 = 0; |
| 1668 | int GLAD_GL_ARB_depth_texture; | 1669 | int GLAD_GL_ARB_depth_texture = 0; |
| 1669 | int GLAD_GL_NV_shader_buffer_store; | 1670 | int GLAD_GL_NV_shader_buffer_store = 0; |
| 1670 | int GLAD_GL_OES_query_matrix; | 1671 | int GLAD_GL_OES_query_matrix = 0; |
| 1671 | int GLAD_GL_MESA_window_pos; | 1672 | int GLAD_GL_MESA_window_pos = 0; |
| 1672 | int GLAD_GL_NV_fill_rectangle; | 1673 | int GLAD_GL_NV_fill_rectangle = 0; |
| 1673 | int GLAD_GL_NV_shader_storage_buffer_object; | 1674 | int GLAD_GL_NV_shader_storage_buffer_object = 0; |
| 1674 | int GLAD_GL_ARB_texture_query_lod; | 1675 | int GLAD_GL_ARB_texture_query_lod = 0; |
| 1675 | int GLAD_GL_ARB_copy_buffer; | 1676 | int GLAD_GL_ARB_copy_buffer = 0; |
| 1676 | int GLAD_GL_ARB_shader_image_size; | 1677 | int GLAD_GL_ARB_shader_image_size = 0; |
| 1677 | int GLAD_GL_NV_shader_atomic_counters; | 1678 | int GLAD_GL_NV_shader_atomic_counters = 0; |
| 1678 | int GLAD_GL_APPLE_object_purgeable; | 1679 | int GLAD_GL_APPLE_object_purgeable = 0; |
| 1679 | int GLAD_GL_ARB_occlusion_query; | 1680 | int GLAD_GL_ARB_occlusion_query = 0; |
| 1680 | int GLAD_GL_INGR_color_clamp; | 1681 | int GLAD_GL_INGR_color_clamp = 0; |
| 1681 | int GLAD_GL_SGI_color_table; | 1682 | int GLAD_GL_SGI_color_table = 0; |
| 1682 | int GLAD_GL_NV_gpu_program5_mem_extended; | 1683 | int GLAD_GL_NV_gpu_program5_mem_extended = 0; |
| 1683 | int GLAD_GL_ARB_texture_cube_map_array; | 1684 | int GLAD_GL_ARB_texture_cube_map_array = 0; |
| 1684 | int GLAD_GL_SGIX_scalebias_hint; | 1685 | int GLAD_GL_SGIX_scalebias_hint = 0; |
| 1685 | int GLAD_GL_EXT_gpu_shader4; | 1686 | int GLAD_GL_EXT_gpu_shader4 = 0; |
| 1686 | int GLAD_GL_NV_geometry_program4; | 1687 | int GLAD_GL_NV_geometry_program4 = 0; |
| 1687 | int GLAD_GL_EXT_framebuffer_multisample_blit_scaled; | 1688 | int GLAD_GL_EXT_framebuffer_multisample_blit_scaled = 0; |
| 1688 | int GLAD_GL_AMD_debug_output; | 1689 | int GLAD_GL_AMD_debug_output = 0; |
| 1689 | int GLAD_GL_ARB_texture_border_clamp; | 1690 | int GLAD_GL_ARB_texture_border_clamp = 0; |
| 1690 | int GLAD_GL_EXT_win32_keyed_mutex; | 1691 | int GLAD_GL_EXT_win32_keyed_mutex = 0; |
| 1691 | int GLAD_GL_ARB_fragment_coord_conventions; | 1692 | int GLAD_GL_ARB_fragment_coord_conventions = 0; |
| 1692 | int GLAD_GL_ARB_multitexture; | 1693 | int GLAD_GL_ARB_multitexture = 0; |
| 1693 | int GLAD_GL_SGIX_polynomial_ffd; | 1694 | int GLAD_GL_SGIX_polynomial_ffd = 0; |
| 1694 | int GLAD_GL_EXT_texture_env_dot3; | 1695 | int GLAD_GL_EXT_texture_env_dot3 = 0; |
| 1695 | int GLAD_GL_EXT_provoking_vertex; | 1696 | int GLAD_GL_EXT_provoking_vertex = 0; |
| 1696 | int GLAD_GL_ARB_point_parameters; | 1697 | int GLAD_GL_ARB_point_parameters = 0; |
| 1697 | int GLAD_GL_ARB_shader_image_load_store; | 1698 | int GLAD_GL_ARB_shader_image_load_store = 0; |
| 1698 | int GLAD_GL_ARB_conditional_render_inverted; | 1699 | int GLAD_GL_ARB_conditional_render_inverted = 0; |
| 1699 | int GLAD_GL_HP_occlusion_test; | 1700 | int GLAD_GL_HP_occlusion_test = 0; |
| 1700 | int GLAD_GL_ARB_ES3_compatibility; | 1701 | int GLAD_GL_ARB_ES3_compatibility = 0; |
| 1701 | int GLAD_GL_ARB_texture_barrier; | 1702 | int GLAD_GL_ARB_texture_barrier = 0; |
| 1702 | int GLAD_GL_ARB_texture_buffer_object_rgb32; | 1703 | int GLAD_GL_ARB_texture_buffer_object_rgb32 = 0; |
| 1703 | int GLAD_GL_NV_bindless_multi_draw_indirect; | 1704 | int GLAD_GL_NV_bindless_multi_draw_indirect = 0; |
| 1704 | int GLAD_GL_SGIX_texture_multi_buffer; | 1705 | int GLAD_GL_SGIX_texture_multi_buffer = 0; |
| 1705 | int GLAD_GL_INTEL_blackhole_render; | 1706 | int GLAD_GL_INTEL_blackhole_render = 0; |
| 1706 | int GLAD_GL_AMD_shader_image_load_store_lod; | 1707 | int GLAD_GL_AMD_shader_image_load_store_lod = 0; |
| 1707 | int GLAD_GL_KHR_texture_compression_astc_ldr; | 1708 | int GLAD_GL_KHR_texture_compression_astc_ldr = 0; |
| 1708 | int GLAD_GL_3DFX_multisample; | 1709 | int GLAD_GL_3DFX_multisample = 0; |
| 1709 | int GLAD_GL_INTEL_fragment_shader_ordering; | 1710 | int GLAD_GL_INTEL_fragment_shader_ordering = 0; |
| 1710 | int GLAD_GL_ARB_texture_env_dot3; | 1711 | int GLAD_GL_ARB_texture_env_dot3 = 0; |
| 1711 | int GLAD_GL_NV_gpu_program4; | 1712 | int GLAD_GL_NV_gpu_program4 = 0; |
| 1712 | int GLAD_GL_NV_gpu_program5; | 1713 | int GLAD_GL_NV_gpu_program5 = 0; |
| 1713 | int GLAD_GL_NV_float_buffer; | 1714 | int GLAD_GL_NV_float_buffer = 0; |
| 1714 | int GLAD_GL_SGIS_texture_edge_clamp; | 1715 | int GLAD_GL_SGIS_texture_edge_clamp = 0; |
| 1715 | int GLAD_GL_ARB_framebuffer_sRGB; | 1716 | int GLAD_GL_ARB_framebuffer_sRGB = 0; |
| 1716 | int GLAD_GL_SUN_slice_accum; | 1717 | int GLAD_GL_SUN_slice_accum = 0; |
| 1717 | int GLAD_GL_EXT_index_texture; | 1718 | int GLAD_GL_EXT_index_texture = 0; |
| 1718 | int GLAD_GL_EXT_shader_image_load_formatted; | 1719 | int GLAD_GL_EXT_shader_image_load_formatted = 0; |
| 1719 | int GLAD_GL_ARB_geometry_shader4; | 1720 | int GLAD_GL_ARB_geometry_shader4 = 0; |
| 1720 | int GLAD_GL_EXT_separate_specular_color; | 1721 | int GLAD_GL_EXT_separate_specular_color = 0; |
| 1721 | int GLAD_GL_AMD_depth_clamp_separate; | 1722 | int GLAD_GL_AMD_depth_clamp_separate = 0; |
| 1722 | int GLAD_GL_NV_conservative_raster; | 1723 | int GLAD_GL_NV_conservative_raster = 0; |
| 1723 | int GLAD_GL_ARB_sparse_texture2; | 1724 | int GLAD_GL_ARB_sparse_texture2 = 0; |
| 1724 | int GLAD_GL_SGIX_sprite; | 1725 | int GLAD_GL_SGIX_sprite = 0; |
| 1725 | int GLAD_GL_ARB_get_program_binary; | 1726 | int GLAD_GL_ARB_get_program_binary = 0; |
| 1726 | int GLAD_GL_AMD_occlusion_query_event; | 1727 | int GLAD_GL_AMD_occlusion_query_event = 0; |
| 1727 | int GLAD_GL_SGIS_multisample; | 1728 | int GLAD_GL_SGIS_multisample = 0; |
| 1728 | int GLAD_GL_EXT_framebuffer_object; | 1729 | int GLAD_GL_EXT_framebuffer_object = 0; |
| 1729 | int GLAD_GL_ARB_robustness_isolation; | 1730 | int GLAD_GL_ARB_robustness_isolation = 0; |
| 1730 | int GLAD_GL_ARB_vertex_array_bgra; | 1731 | int GLAD_GL_ARB_vertex_array_bgra = 0; |
| 1731 | int GLAD_GL_APPLE_vertex_array_range; | 1732 | int GLAD_GL_APPLE_vertex_array_range = 0; |
| 1732 | int GLAD_GL_AMD_query_buffer_object; | 1733 | int GLAD_GL_AMD_query_buffer_object = 0; |
| 1733 | int GLAD_GL_NV_register_combiners; | 1734 | int GLAD_GL_NV_register_combiners = 0; |
| 1734 | int GLAD_GL_ARB_draw_buffers; | 1735 | int GLAD_GL_ARB_draw_buffers = 0; |
| 1735 | int GLAD_GL_NVX_blend_equation_advanced_multi_draw_buffers; | 1736 | int GLAD_GL_NVX_blend_equation_advanced_multi_draw_buffers = 0; |
| 1736 | int GLAD_GL_AMD_gpu_shader_int16; | 1737 | int GLAD_GL_AMD_gpu_shader_int16 = 0; |
| 1737 | int GLAD_GL_ARB_debug_output; | 1738 | int GLAD_GL_ARB_debug_output = 0; |
| 1738 | int GLAD_GL_EXT_shader_framebuffer_fetch; | 1739 | int GLAD_GL_EXT_shader_framebuffer_fetch = 0; |
| 1739 | int GLAD_GL_SGI_color_matrix; | 1740 | int GLAD_GL_SGI_color_matrix = 0; |
| 1740 | int GLAD_GL_EXT_cull_vertex; | 1741 | int GLAD_GL_EXT_cull_vertex = 0; |
| 1741 | int GLAD_GL_EXT_texture_sRGB; | 1742 | int GLAD_GL_AMD_framebuffer_multisample_advanced = 0; |
| 1742 | int GLAD_GL_APPLE_row_bytes; | 1743 | int GLAD_GL_EXT_texture_sRGB = 0; |
| 1743 | int GLAD_GL_NV_conservative_raster_underestimation; | 1744 | int GLAD_GL_APPLE_row_bytes = 0; |
| 1744 | int GLAD_GL_IBM_multimode_draw_arrays; | 1745 | int GLAD_GL_NV_conservative_raster_underestimation = 0; |
| 1745 | int GLAD_GL_KHR_parallel_shader_compile; | 1746 | int GLAD_GL_IBM_multimode_draw_arrays = 0; |
| 1746 | int GLAD_GL_APPLE_vertex_array_object; | 1747 | int GLAD_GL_KHR_parallel_shader_compile = 0; |
| 1747 | int GLAD_GL_3DFX_texture_compression_FXT1; | 1748 | int GLAD_GL_APPLE_vertex_array_object = 0; |
| 1748 | int GLAD_GL_NV_fragment_shader_interlock; | 1749 | int GLAD_GL_3DFX_texture_compression_FXT1 = 0; |
| 1749 | int GLAD_GL_AMD_conservative_depth; | 1750 | int GLAD_GL_NV_fragment_shader_interlock = 0; |
| 1750 | int GLAD_GL_ARB_texture_float; | 1751 | int GLAD_GL_AMD_conservative_depth = 0; |
| 1751 | int GLAD_GL_ARB_compressed_texture_pixel_storage; | 1752 | int GLAD_GL_ARB_texture_float = 0; |
| 1752 | int GLAD_GL_SGIS_detail_texture; | 1753 | int GLAD_GL_ARB_compressed_texture_pixel_storage = 0; |
| 1753 | int GLAD_GL_NV_geometry_shader_passthrough; | 1754 | int GLAD_GL_SGIS_detail_texture = 0; |
| 1754 | int GLAD_GL_ARB_draw_instanced; | 1755 | int GLAD_GL_NV_geometry_shader_passthrough = 0; |
| 1755 | int GLAD_GL_OES_read_format; | 1756 | int GLAD_GL_ARB_draw_instanced = 0; |
| 1756 | int GLAD_GL_ATI_texture_float; | 1757 | int GLAD_GL_OES_read_format = 0; |
| 1757 | int GLAD_GL_ARB_texture_gather; | 1758 | int GLAD_GL_ATI_texture_float = 0; |
| 1758 | int GLAD_GL_AMD_vertex_shader_layer; | 1759 | int GLAD_GL_ARB_texture_gather = 0; |
| 1759 | int GLAD_GL_ARB_shading_language_include; | 1760 | int GLAD_GL_AMD_vertex_shader_layer = 0; |
| 1760 | int GLAD_GL_APPLE_client_storage; | 1761 | int GLAD_GL_ARB_shading_language_include = 0; |
| 1761 | int GLAD_GL_WIN_phong_shading; | 1762 | int GLAD_GL_APPLE_client_storage = 0; |
| 1762 | int GLAD_GL_INGR_blend_func_separate; | 1763 | int GLAD_GL_WIN_phong_shading = 0; |
| 1763 | int GLAD_GL_NV_path_rendering; | 1764 | int GLAD_GL_INGR_blend_func_separate = 0; |
| 1764 | int GLAD_GL_NV_conservative_raster_dilate; | 1765 | int GLAD_GL_NV_path_rendering = 0; |
| 1765 | int GLAD_GL_AMD_gpu_shader_half_float; | 1766 | int GLAD_GL_NV_conservative_raster_dilate = 0; |
| 1766 | int GLAD_GL_ARB_post_depth_coverage; | 1767 | int GLAD_GL_AMD_gpu_shader_half_float = 0; |
| 1767 | int GLAD_GL_ARB_texture_non_power_of_two; | 1768 | int GLAD_GL_ARB_post_depth_coverage = 0; |
| 1768 | int GLAD_GL_APPLE_rgb_422; | 1769 | int GLAD_GL_ARB_texture_non_power_of_two = 0; |
| 1769 | int GLAD_GL_EXT_texture_lod_bias; | 1770 | int GLAD_GL_APPLE_rgb_422 = 0; |
| 1770 | int GLAD_GL_ARB_gpu_shader_int64; | 1771 | int GLAD_GL_EXT_texture_lod_bias = 0; |
| 1771 | int GLAD_GL_ARB_seamless_cube_map; | 1772 | int GLAD_GL_ARB_gpu_shader_int64 = 0; |
| 1772 | int GLAD_GL_ARB_shader_group_vote; | 1773 | int GLAD_GL_ARB_seamless_cube_map = 0; |
| 1773 | int GLAD_GL_NV_vdpau_interop; | 1774 | int GLAD_GL_ARB_shader_group_vote = 0; |
| 1774 | int GLAD_GL_ARB_occlusion_query2; | 1775 | int GLAD_GL_NV_vdpau_interop = 0; |
| 1775 | int GLAD_GL_ARB_internalformat_query2; | 1776 | int GLAD_GL_ARB_occlusion_query2 = 0; |
| 1776 | int GLAD_GL_EXT_texture_filter_anisotropic; | 1777 | int GLAD_GL_ARB_internalformat_query2 = 0; |
| 1777 | int GLAD_GL_SUN_vertex; | 1778 | int GLAD_GL_EXT_texture_filter_anisotropic = 0; |
| 1778 | int GLAD_GL_EXT_transform_feedback; | 1779 | int GLAD_GL_SUN_vertex = 0; |
| 1779 | int GLAD_GL_SGIX_igloo_interface; | 1780 | int GLAD_GL_EXT_transform_feedback = 0; |
| 1780 | int GLAD_GL_SGIS_texture_lod; | 1781 | int GLAD_GL_SGIX_igloo_interface = 0; |
| 1781 | int GLAD_GL_NV_vertex_program3; | 1782 | int GLAD_GL_SGIS_texture_lod = 0; |
| 1782 | int GLAD_GL_ARB_draw_indirect; | 1783 | int GLAD_GL_NV_vertex_program3 = 0; |
| 1783 | int GLAD_GL_NV_vertex_program4; | 1784 | int GLAD_GL_ARB_draw_indirect = 0; |
| 1784 | int GLAD_GL_AMD_transform_feedback3_lines_triangles; | 1785 | int GLAD_GL_NV_vertex_program4 = 0; |
| 1785 | int GLAD_GL_SGIS_fog_function; | 1786 | int GLAD_GL_AMD_transform_feedback3_lines_triangles = 0; |
| 1786 | int GLAD_GL_EXT_x11_sync_object; | 1787 | int GLAD_GL_SGIS_fog_function = 0; |
| 1787 | int GLAD_GL_ARB_sync; | 1788 | int GLAD_GL_EXT_x11_sync_object = 0; |
| 1788 | int GLAD_GL_NV_texture_rectangle_compressed; | 1789 | int GLAD_GL_ARB_sync = 0; |
| 1789 | int GLAD_GL_NV_sample_locations; | 1790 | int GLAD_GL_NV_texture_rectangle_compressed = 0; |
| 1790 | int GLAD_GL_NV_gpu_multicast; | 1791 | int GLAD_GL_NV_sample_locations = 0; |
| 1791 | int GLAD_GL_ARB_gl_spirv; | 1792 | int GLAD_GL_NV_gpu_multicast = 0; |
| 1792 | int GLAD_GL_ARB_compute_variable_group_size; | 1793 | int GLAD_GL_ARB_gl_spirv = 0; |
| 1793 | int GLAD_GL_OES_fixed_point; | 1794 | int GLAD_GL_ARB_compute_variable_group_size = 0; |
| 1794 | int GLAD_GL_MESA_program_binary_formats; | 1795 | int GLAD_GL_OES_fixed_point = 0; |
| 1795 | int GLAD_GL_NV_blend_square; | 1796 | int GLAD_GL_MESA_program_binary_formats = 0; |
| 1796 | int GLAD_GL_EXT_framebuffer_multisample; | 1797 | int GLAD_GL_NV_blend_square = 0; |
| 1797 | int GLAD_GL_ARB_gpu_shader5; | 1798 | int GLAD_GL_EXT_framebuffer_multisample = 0; |
| 1798 | int GLAD_GL_SGIS_texture4D; | 1799 | int GLAD_GL_ARB_gpu_shader5 = 0; |
| 1799 | int GLAD_GL_EXT_texture3D; | 1800 | int GLAD_GL_SGIS_texture4D = 0; |
| 1800 | int GLAD_GL_EXT_multisample; | 1801 | int GLAD_GL_EXT_texture3D = 0; |
| 1801 | int GLAD_GL_EXT_secondary_color; | 1802 | int GLAD_GL_EXT_multisample = 0; |
| 1802 | int GLAD_GL_INTEL_conservative_rasterization; | 1803 | int GLAD_GL_EXT_secondary_color = 0; |
| 1803 | int GLAD_GL_ARB_texture_filter_minmax; | 1804 | int GLAD_GL_INTEL_conservative_rasterization = 0; |
| 1804 | int GLAD_GL_ATI_vertex_array_object; | 1805 | int GLAD_GL_ARB_texture_filter_minmax = 0; |
| 1805 | int GLAD_GL_ARB_parallel_shader_compile; | 1806 | int GLAD_GL_ATI_vertex_array_object = 0; |
| 1806 | int GLAD_GL_NVX_gpu_memory_info; | 1807 | int GLAD_GL_ARB_parallel_shader_compile = 0; |
| 1807 | int GLAD_GL_ARB_sparse_texture; | 1808 | int GLAD_GL_NVX_gpu_memory_info = 0; |
| 1808 | int GLAD_GL_SGIS_point_line_texgen; | 1809 | int GLAD_GL_ARB_sparse_texture = 0; |
| 1809 | int GLAD_GL_ARB_sample_locations; | 1810 | int GLAD_GL_SGIS_point_line_texgen = 0; |
| 1810 | int GLAD_GL_ARB_sparse_buffer; | 1811 | int GLAD_GL_ARB_sample_locations = 0; |
| 1811 | int GLAD_GL_ARB_polygon_offset_clamp; | 1812 | int GLAD_GL_ARB_sparse_buffer = 0; |
| 1812 | int GLAD_GL_EXT_draw_range_elements; | 1813 | int GLAD_GL_ARB_polygon_offset_clamp = 0; |
| 1813 | int GLAD_GL_SGIX_blend_alpha_minmax; | 1814 | int GLAD_GL_EXT_draw_range_elements = 0; |
| 1814 | int GLAD_GL_KHR_context_flush_control; | 1815 | int GLAD_GL_SGIX_blend_alpha_minmax = 0; |
| 1815 | PFNGLTBUFFERMASK3DFXPROC glad_glTbufferMask3DFX; | 1816 | int GLAD_GL_KHR_context_flush_control = 0; |
| 1816 | PFNGLDEBUGMESSAGEENABLEAMDPROC glad_glDebugMessageEnableAMD; | 1817 | PFNGLTBUFFERMASK3DFXPROC glad_glTbufferMask3DFX = NULL; |
| 1817 | PFNGLDEBUGMESSAGEINSERTAMDPROC glad_glDebugMessageInsertAMD; | 1818 | PFNGLDEBUGMESSAGEENABLEAMDPROC glad_glDebugMessageEnableAMD = NULL; |
| 1818 | PFNGLDEBUGMESSAGECALLBACKAMDPROC glad_glDebugMessageCallbackAMD; | 1819 | PFNGLDEBUGMESSAGEINSERTAMDPROC glad_glDebugMessageInsertAMD = NULL; |
| 1819 | PFNGLGETDEBUGMESSAGELOGAMDPROC glad_glGetDebugMessageLogAMD; | 1820 | PFNGLDEBUGMESSAGECALLBACKAMDPROC glad_glDebugMessageCallbackAMD = NULL; |
| 1820 | PFNGLBLENDFUNCINDEXEDAMDPROC glad_glBlendFuncIndexedAMD; | 1821 | PFNGLGETDEBUGMESSAGELOGAMDPROC glad_glGetDebugMessageLogAMD = NULL; |
| 1821 | PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC glad_glBlendFuncSeparateIndexedAMD; | 1822 | PFNGLBLENDFUNCINDEXEDAMDPROC glad_glBlendFuncIndexedAMD = NULL; |
| 1822 | PFNGLBLENDEQUATIONINDEXEDAMDPROC glad_glBlendEquationIndexedAMD; | 1823 | PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC glad_glBlendFuncSeparateIndexedAMD = NULL; |
| 1823 | PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC glad_glBlendEquationSeparateIndexedAMD; | 1824 | PFNGLBLENDEQUATIONINDEXEDAMDPROC glad_glBlendEquationIndexedAMD = NULL; |
| 1824 | PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC glad_glFramebufferSamplePositionsfvAMD; | 1825 | PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC glad_glBlendEquationSeparateIndexedAMD = NULL; |
| 1825 | PFNGLNAMEDFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC glad_glNamedFramebufferSamplePositionsfvAMD; | 1826 | PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC glad_glRenderbufferStorageMultisampleAdvancedAMD = NULL; |
| 1826 | PFNGLGETFRAMEBUFFERPARAMETERFVAMDPROC glad_glGetFramebufferParameterfvAMD; | 1827 | PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC glad_glNamedRenderbufferStorageMultisampleAdvancedAMD = NULL; |
| 1827 | PFNGLGETNAMEDFRAMEBUFFERPARAMETERFVAMDPROC glad_glGetNamedFramebufferParameterfvAMD; | 1828 | PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC glad_glFramebufferSamplePositionsfvAMD = NULL; |
| 1828 | PFNGLUNIFORM1I64NVPROC glad_glUniform1i64NV; | 1829 | PFNGLNAMEDFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC glad_glNamedFramebufferSamplePositionsfvAMD = NULL; |
| 1829 | PFNGLUNIFORM2I64NVPROC glad_glUniform2i64NV; | 1830 | PFNGLGETFRAMEBUFFERPARAMETERFVAMDPROC glad_glGetFramebufferParameterfvAMD = NULL; |
| 1830 | PFNGLUNIFORM3I64NVPROC glad_glUniform3i64NV; | 1831 | PFNGLGETNAMEDFRAMEBUFFERPARAMETERFVAMDPROC glad_glGetNamedFramebufferParameterfvAMD = NULL; |
| 1831 | PFNGLUNIFORM4I64NVPROC glad_glUniform4i64NV; | 1832 | PFNGLUNIFORM1I64NVPROC glad_glUniform1i64NV = NULL; |
| 1832 | PFNGLUNIFORM1I64VNVPROC glad_glUniform1i64vNV; | 1833 | PFNGLUNIFORM2I64NVPROC glad_glUniform2i64NV = NULL; |
| 1833 | PFNGLUNIFORM2I64VNVPROC glad_glUniform2i64vNV; | 1834 | PFNGLUNIFORM3I64NVPROC glad_glUniform3i64NV = NULL; |
| 1834 | PFNGLUNIFORM3I64VNVPROC glad_glUniform3i64vNV; | 1835 | PFNGLUNIFORM4I64NVPROC glad_glUniform4i64NV = NULL; |
| 1835 | PFNGLUNIFORM4I64VNVPROC glad_glUniform4i64vNV; | 1836 | PFNGLUNIFORM1I64VNVPROC glad_glUniform1i64vNV = NULL; |
| 1836 | PFNGLUNIFORM1UI64NVPROC glad_glUniform1ui64NV; | 1837 | PFNGLUNIFORM2I64VNVPROC glad_glUniform2i64vNV = NULL; |
| 1837 | PFNGLUNIFORM2UI64NVPROC glad_glUniform2ui64NV; | 1838 | PFNGLUNIFORM3I64VNVPROC glad_glUniform3i64vNV = NULL; |
| 1838 | PFNGLUNIFORM3UI64NVPROC glad_glUniform3ui64NV; | 1839 | PFNGLUNIFORM4I64VNVPROC glad_glUniform4i64vNV = NULL; |
| 1839 | PFNGLUNIFORM4UI64NVPROC glad_glUniform4ui64NV; | 1840 | PFNGLUNIFORM1UI64NVPROC glad_glUniform1ui64NV = NULL; |
| 1840 | PFNGLUNIFORM1UI64VNVPROC glad_glUniform1ui64vNV; | 1841 | PFNGLUNIFORM2UI64NVPROC glad_glUniform2ui64NV = NULL; |
| 1841 | PFNGLUNIFORM2UI64VNVPROC glad_glUniform2ui64vNV; | 1842 | PFNGLUNIFORM3UI64NVPROC glad_glUniform3ui64NV = NULL; |
| 1842 | PFNGLUNIFORM3UI64VNVPROC glad_glUniform3ui64vNV; | 1843 | PFNGLUNIFORM4UI64NVPROC glad_glUniform4ui64NV = NULL; |
| 1843 | PFNGLUNIFORM4UI64VNVPROC glad_glUniform4ui64vNV; | 1844 | PFNGLUNIFORM1UI64VNVPROC glad_glUniform1ui64vNV = NULL; |
| 1844 | PFNGLGETUNIFORMI64VNVPROC glad_glGetUniformi64vNV; | 1845 | PFNGLUNIFORM2UI64VNVPROC glad_glUniform2ui64vNV = NULL; |
| 1845 | PFNGLGETUNIFORMUI64VNVPROC glad_glGetUniformui64vNV; | 1846 | PFNGLUNIFORM3UI64VNVPROC glad_glUniform3ui64vNV = NULL; |
| 1846 | PFNGLPROGRAMUNIFORM1I64NVPROC glad_glProgramUniform1i64NV; | 1847 | PFNGLUNIFORM4UI64VNVPROC glad_glUniform4ui64vNV = NULL; |
| 1847 | PFNGLPROGRAMUNIFORM2I64NVPROC glad_glProgramUniform2i64NV; | 1848 | PFNGLGETUNIFORMI64VNVPROC glad_glGetUniformi64vNV = NULL; |
| 1848 | PFNGLPROGRAMUNIFORM3I64NVPROC glad_glProgramUniform3i64NV; | 1849 | PFNGLGETUNIFORMUI64VNVPROC glad_glGetUniformui64vNV = NULL; |
| 1849 | PFNGLPROGRAMUNIFORM4I64NVPROC glad_glProgramUniform4i64NV; | 1850 | PFNGLPROGRAMUNIFORM1I64NVPROC glad_glProgramUniform1i64NV = NULL; |
| 1850 | PFNGLPROGRAMUNIFORM1I64VNVPROC glad_glProgramUniform1i64vNV; | 1851 | PFNGLPROGRAMUNIFORM2I64NVPROC glad_glProgramUniform2i64NV = NULL; |
| 1851 | PFNGLPROGRAMUNIFORM2I64VNVPROC glad_glProgramUniform2i64vNV; | 1852 | PFNGLPROGRAMUNIFORM3I64NVPROC glad_glProgramUniform3i64NV = NULL; |
| 1852 | PFNGLPROGRAMUNIFORM3I64VNVPROC glad_glProgramUniform3i64vNV; | 1853 | PFNGLPROGRAMUNIFORM4I64NVPROC glad_glProgramUniform4i64NV = NULL; |
| 1853 | PFNGLPROGRAMUNIFORM4I64VNVPROC glad_glProgramUniform4i64vNV; | 1854 | PFNGLPROGRAMUNIFORM1I64VNVPROC glad_glProgramUniform1i64vNV = NULL; |
| 1854 | PFNGLPROGRAMUNIFORM1UI64NVPROC glad_glProgramUniform1ui64NV; | 1855 | PFNGLPROGRAMUNIFORM2I64VNVPROC glad_glProgramUniform2i64vNV = NULL; |
| 1855 | PFNGLPROGRAMUNIFORM2UI64NVPROC glad_glProgramUniform2ui64NV; | 1856 | PFNGLPROGRAMUNIFORM3I64VNVPROC glad_glProgramUniform3i64vNV = NULL; |
| 1856 | PFNGLPROGRAMUNIFORM3UI64NVPROC glad_glProgramUniform3ui64NV; | 1857 | PFNGLPROGRAMUNIFORM4I64VNVPROC glad_glProgramUniform4i64vNV = NULL; |
| 1857 | PFNGLPROGRAMUNIFORM4UI64NVPROC glad_glProgramUniform4ui64NV; | 1858 | PFNGLPROGRAMUNIFORM1UI64NVPROC glad_glProgramUniform1ui64NV = NULL; |
| 1858 | PFNGLPROGRAMUNIFORM1UI64VNVPROC glad_glProgramUniform1ui64vNV; | 1859 | PFNGLPROGRAMUNIFORM2UI64NVPROC glad_glProgramUniform2ui64NV = NULL; |
| 1859 | PFNGLPROGRAMUNIFORM2UI64VNVPROC glad_glProgramUniform2ui64vNV; | 1860 | PFNGLPROGRAMUNIFORM3UI64NVPROC glad_glProgramUniform3ui64NV = NULL; |
| 1860 | PFNGLPROGRAMUNIFORM3UI64VNVPROC glad_glProgramUniform3ui64vNV; | 1861 | PFNGLPROGRAMUNIFORM4UI64NVPROC glad_glProgramUniform4ui64NV = NULL; |
| 1861 | PFNGLPROGRAMUNIFORM4UI64VNVPROC glad_glProgramUniform4ui64vNV; | 1862 | PFNGLPROGRAMUNIFORM1UI64VNVPROC glad_glProgramUniform1ui64vNV = NULL; |
| 1862 | PFNGLVERTEXATTRIBPARAMETERIAMDPROC glad_glVertexAttribParameteriAMD; | 1863 | PFNGLPROGRAMUNIFORM2UI64VNVPROC glad_glProgramUniform2ui64vNV = NULL; |
| 1863 | PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC glad_glMultiDrawArraysIndirectAMD; | 1864 | PFNGLPROGRAMUNIFORM3UI64VNVPROC glad_glProgramUniform3ui64vNV = NULL; |
| 1864 | PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC glad_glMultiDrawElementsIndirectAMD; | 1865 | PFNGLPROGRAMUNIFORM4UI64VNVPROC glad_glProgramUniform4ui64vNV = NULL; |
| 1865 | PFNGLGENNAMESAMDPROC glad_glGenNamesAMD; | 1866 | PFNGLVERTEXATTRIBPARAMETERIAMDPROC glad_glVertexAttribParameteriAMD = NULL; |
| 1866 | PFNGLDELETENAMESAMDPROC glad_glDeleteNamesAMD; | 1867 | PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC glad_glMultiDrawArraysIndirectAMD = NULL; |
| 1867 | PFNGLISNAMEAMDPROC glad_glIsNameAMD; | 1868 | PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC glad_glMultiDrawElementsIndirectAMD = NULL; |
| 1868 | PFNGLQUERYOBJECTPARAMETERUIAMDPROC glad_glQueryObjectParameteruiAMD; | 1869 | PFNGLGENNAMESAMDPROC glad_glGenNamesAMD = NULL; |
| 1869 | PFNGLGETPERFMONITORGROUPSAMDPROC glad_glGetPerfMonitorGroupsAMD; | 1870 | PFNGLDELETENAMESAMDPROC glad_glDeleteNamesAMD = NULL; |
| 1870 | PFNGLGETPERFMONITORCOUNTERSAMDPROC glad_glGetPerfMonitorCountersAMD; | 1871 | PFNGLISNAMEAMDPROC glad_glIsNameAMD = NULL; |
| 1871 | PFNGLGETPERFMONITORGROUPSTRINGAMDPROC glad_glGetPerfMonitorGroupStringAMD; | 1872 | PFNGLQUERYOBJECTPARAMETERUIAMDPROC glad_glQueryObjectParameteruiAMD = NULL; |
| 1872 | PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC glad_glGetPerfMonitorCounterStringAMD; | 1873 | PFNGLGETPERFMONITORGROUPSAMDPROC glad_glGetPerfMonitorGroupsAMD = NULL; |
| 1873 | PFNGLGETPERFMONITORCOUNTERINFOAMDPROC glad_glGetPerfMonitorCounterInfoAMD; | 1874 | PFNGLGETPERFMONITORCOUNTERSAMDPROC glad_glGetPerfMonitorCountersAMD = NULL; |
| 1874 | PFNGLGENPERFMONITORSAMDPROC glad_glGenPerfMonitorsAMD; | 1875 | PFNGLGETPERFMONITORGROUPSTRINGAMDPROC glad_glGetPerfMonitorGroupStringAMD = NULL; |
| 1875 | PFNGLDELETEPERFMONITORSAMDPROC glad_glDeletePerfMonitorsAMD; | 1876 | PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC glad_glGetPerfMonitorCounterStringAMD = NULL; |
| 1876 | PFNGLSELECTPERFMONITORCOUNTERSAMDPROC glad_glSelectPerfMonitorCountersAMD; | 1877 | PFNGLGETPERFMONITORCOUNTERINFOAMDPROC glad_glGetPerfMonitorCounterInfoAMD = NULL; |
| 1877 | PFNGLBEGINPERFMONITORAMDPROC glad_glBeginPerfMonitorAMD; | 1878 | PFNGLGENPERFMONITORSAMDPROC glad_glGenPerfMonitorsAMD = NULL; |
| 1878 | PFNGLENDPERFMONITORAMDPROC glad_glEndPerfMonitorAMD; | 1879 | PFNGLDELETEPERFMONITORSAMDPROC glad_glDeletePerfMonitorsAMD = NULL; |
| 1879 | PFNGLGETPERFMONITORCOUNTERDATAAMDPROC glad_glGetPerfMonitorCounterDataAMD; | 1880 | PFNGLSELECTPERFMONITORCOUNTERSAMDPROC glad_glSelectPerfMonitorCountersAMD = NULL; |
| 1880 | PFNGLSETMULTISAMPLEFVAMDPROC glad_glSetMultisamplefvAMD; | 1881 | PFNGLBEGINPERFMONITORAMDPROC glad_glBeginPerfMonitorAMD = NULL; |
| 1881 | PFNGLTEXSTORAGESPARSEAMDPROC glad_glTexStorageSparseAMD; | 1882 | PFNGLENDPERFMONITORAMDPROC glad_glEndPerfMonitorAMD = NULL; |
| 1882 | PFNGLTEXTURESTORAGESPARSEAMDPROC glad_glTextureStorageSparseAMD; | 1883 | PFNGLGETPERFMONITORCOUNTERDATAAMDPROC glad_glGetPerfMonitorCounterDataAMD = NULL; |
| 1883 | PFNGLSTENCILOPVALUEAMDPROC glad_glStencilOpValueAMD; | 1884 | PFNGLSETMULTISAMPLEFVAMDPROC glad_glSetMultisamplefvAMD = NULL; |
| 1884 | PFNGLTESSELLATIONFACTORAMDPROC glad_glTessellationFactorAMD; | 1885 | PFNGLTEXSTORAGESPARSEAMDPROC glad_glTexStorageSparseAMD = NULL; |
| 1885 | PFNGLTESSELLATIONMODEAMDPROC glad_glTessellationModeAMD; | 1886 | PFNGLTEXTURESTORAGESPARSEAMDPROC glad_glTextureStorageSparseAMD = NULL; |
| 1886 | PFNGLELEMENTPOINTERAPPLEPROC glad_glElementPointerAPPLE; | 1887 | PFNGLSTENCILOPVALUEAMDPROC glad_glStencilOpValueAMD = NULL; |
| 1887 | PFNGLDRAWELEMENTARRAYAPPLEPROC glad_glDrawElementArrayAPPLE; | 1888 | PFNGLTESSELLATIONFACTORAMDPROC glad_glTessellationFactorAMD = NULL; |
| 1888 | PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC glad_glDrawRangeElementArrayAPPLE; | 1889 | PFNGLTESSELLATIONMODEAMDPROC glad_glTessellationModeAMD = NULL; |
| 1889 | PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC glad_glMultiDrawElementArrayAPPLE; | 1890 | PFNGLELEMENTPOINTERAPPLEPROC glad_glElementPointerAPPLE = NULL; |
| 1890 | PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC glad_glMultiDrawRangeElementArrayAPPLE; | 1891 | PFNGLDRAWELEMENTARRAYAPPLEPROC glad_glDrawElementArrayAPPLE = NULL; |
| 1891 | PFNGLGENFENCESAPPLEPROC glad_glGenFencesAPPLE; | 1892 | PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC glad_glDrawRangeElementArrayAPPLE = NULL; |
| 1892 | PFNGLDELETEFENCESAPPLEPROC glad_glDeleteFencesAPPLE; | 1893 | PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC glad_glMultiDrawElementArrayAPPLE = NULL; |
| 1893 | PFNGLSETFENCEAPPLEPROC glad_glSetFenceAPPLE; | 1894 | PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC glad_glMultiDrawRangeElementArrayAPPLE = NULL; |
| 1894 | PFNGLISFENCEAPPLEPROC glad_glIsFenceAPPLE; | 1895 | PFNGLGENFENCESAPPLEPROC glad_glGenFencesAPPLE = NULL; |
| 1895 | PFNGLTESTFENCEAPPLEPROC glad_glTestFenceAPPLE; | 1896 | PFNGLDELETEFENCESAPPLEPROC glad_glDeleteFencesAPPLE = NULL; |
| 1896 | PFNGLFINISHFENCEAPPLEPROC glad_glFinishFenceAPPLE; | 1897 | PFNGLSETFENCEAPPLEPROC glad_glSetFenceAPPLE = NULL; |
| 1897 | PFNGLTESTOBJECTAPPLEPROC glad_glTestObjectAPPLE; | 1898 | PFNGLISFENCEAPPLEPROC glad_glIsFenceAPPLE = NULL; |
| 1898 | PFNGLFINISHOBJECTAPPLEPROC glad_glFinishObjectAPPLE; | 1899 | PFNGLTESTFENCEAPPLEPROC glad_glTestFenceAPPLE = NULL; |
| 1899 | PFNGLBUFFERPARAMETERIAPPLEPROC glad_glBufferParameteriAPPLE; | 1900 | PFNGLFINISHFENCEAPPLEPROC glad_glFinishFenceAPPLE = NULL; |
| 1900 | PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glad_glFlushMappedBufferRangeAPPLE; | 1901 | PFNGLTESTOBJECTAPPLEPROC glad_glTestObjectAPPLE = NULL; |
| 1901 | PFNGLOBJECTPURGEABLEAPPLEPROC glad_glObjectPurgeableAPPLE; | 1902 | PFNGLFINISHOBJECTAPPLEPROC glad_glFinishObjectAPPLE = NULL; |
| 1902 | PFNGLOBJECTUNPURGEABLEAPPLEPROC glad_glObjectUnpurgeableAPPLE; | 1903 | PFNGLBUFFERPARAMETERIAPPLEPROC glad_glBufferParameteriAPPLE = NULL; |
| 1903 | PFNGLGETOBJECTPARAMETERIVAPPLEPROC glad_glGetObjectParameterivAPPLE; | 1904 | PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glad_glFlushMappedBufferRangeAPPLE = NULL; |
| 1904 | PFNGLTEXTURERANGEAPPLEPROC glad_glTextureRangeAPPLE; | 1905 | PFNGLOBJECTPURGEABLEAPPLEPROC glad_glObjectPurgeableAPPLE = NULL; |
| 1905 | PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC glad_glGetTexParameterPointervAPPLE; | 1906 | PFNGLOBJECTUNPURGEABLEAPPLEPROC glad_glObjectUnpurgeableAPPLE = NULL; |
| 1906 | PFNGLBINDVERTEXARRAYAPPLEPROC glad_glBindVertexArrayAPPLE; | 1907 | PFNGLGETOBJECTPARAMETERIVAPPLEPROC glad_glGetObjectParameterivAPPLE = NULL; |
| 1907 | PFNGLDELETEVERTEXARRAYSAPPLEPROC glad_glDeleteVertexArraysAPPLE; | 1908 | PFNGLTEXTURERANGEAPPLEPROC glad_glTextureRangeAPPLE = NULL; |
| 1908 | PFNGLGENVERTEXARRAYSAPPLEPROC glad_glGenVertexArraysAPPLE; | 1909 | PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC glad_glGetTexParameterPointervAPPLE = NULL; |
| 1909 | PFNGLISVERTEXARRAYAPPLEPROC glad_glIsVertexArrayAPPLE; | 1910 | PFNGLBINDVERTEXARRAYAPPLEPROC glad_glBindVertexArrayAPPLE = NULL; |
| 1910 | PFNGLVERTEXARRAYRANGEAPPLEPROC glad_glVertexArrayRangeAPPLE; | 1911 | PFNGLDELETEVERTEXARRAYSAPPLEPROC glad_glDeleteVertexArraysAPPLE = NULL; |
| 1911 | PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC glad_glFlushVertexArrayRangeAPPLE; | 1912 | PFNGLGENVERTEXARRAYSAPPLEPROC glad_glGenVertexArraysAPPLE = NULL; |
| 1912 | PFNGLVERTEXARRAYPARAMETERIAPPLEPROC glad_glVertexArrayParameteriAPPLE; | 1913 | PFNGLISVERTEXARRAYAPPLEPROC glad_glIsVertexArrayAPPLE = NULL; |
| 1913 | PFNGLENABLEVERTEXATTRIBAPPLEPROC glad_glEnableVertexAttribAPPLE; | 1914 | PFNGLVERTEXARRAYRANGEAPPLEPROC glad_glVertexArrayRangeAPPLE = NULL; |
| 1914 | PFNGLDISABLEVERTEXATTRIBAPPLEPROC glad_glDisableVertexAttribAPPLE; | 1915 | PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC glad_glFlushVertexArrayRangeAPPLE = NULL; |
| 1915 | PFNGLISVERTEXATTRIBENABLEDAPPLEPROC glad_glIsVertexAttribEnabledAPPLE; | 1916 | PFNGLVERTEXARRAYPARAMETERIAPPLEPROC glad_glVertexArrayParameteriAPPLE = NULL; |
| 1916 | PFNGLMAPVERTEXATTRIB1DAPPLEPROC glad_glMapVertexAttrib1dAPPLE; | 1917 | PFNGLENABLEVERTEXATTRIBAPPLEPROC glad_glEnableVertexAttribAPPLE = NULL; |
| 1917 | PFNGLMAPVERTEXATTRIB1FAPPLEPROC glad_glMapVertexAttrib1fAPPLE; | 1918 | PFNGLDISABLEVERTEXATTRIBAPPLEPROC glad_glDisableVertexAttribAPPLE = NULL; |
| 1918 | PFNGLMAPVERTEXATTRIB2DAPPLEPROC glad_glMapVertexAttrib2dAPPLE; | 1919 | PFNGLISVERTEXATTRIBENABLEDAPPLEPROC glad_glIsVertexAttribEnabledAPPLE = NULL; |
| 1919 | PFNGLMAPVERTEXATTRIB2FAPPLEPROC glad_glMapVertexAttrib2fAPPLE; | 1920 | PFNGLMAPVERTEXATTRIB1DAPPLEPROC glad_glMapVertexAttrib1dAPPLE = NULL; |
| 1920 | PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler; | 1921 | PFNGLMAPVERTEXATTRIB1FAPPLEPROC glad_glMapVertexAttrib1fAPPLE = NULL; |
| 1921 | PFNGLSHADERBINARYPROC glad_glShaderBinary; | 1922 | PFNGLMAPVERTEXATTRIB2DAPPLEPROC glad_glMapVertexAttrib2dAPPLE = NULL; |
| 1922 | PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat; | 1923 | PFNGLMAPVERTEXATTRIB2FAPPLEPROC glad_glMapVertexAttrib2fAPPLE = NULL; |
| 1923 | PFNGLDEPTHRANGEFPROC glad_glDepthRangef; | 1924 | PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler = NULL; |
| 1924 | PFNGLCLEARDEPTHFPROC glad_glClearDepthf; | 1925 | PFNGLSHADERBINARYPROC glad_glShaderBinary = NULL; |
| 1925 | PFNGLMEMORYBARRIERBYREGIONPROC glad_glMemoryBarrierByRegion; | 1926 | PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat = NULL; |
| 1926 | PFNGLPRIMITIVEBOUNDINGBOXARBPROC glad_glPrimitiveBoundingBoxARB; | 1927 | PFNGLDEPTHRANGEFPROC glad_glDepthRangef = NULL; |
| 1927 | PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glad_glDrawArraysInstancedBaseInstance; | 1928 | PFNGLCLEARDEPTHFPROC glad_glClearDepthf = NULL; |
| 1928 | PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC glad_glDrawElementsInstancedBaseInstance; | 1929 | PFNGLMEMORYBARRIERBYREGIONPROC glad_glMemoryBarrierByRegion = NULL; |
| 1929 | PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glad_glDrawElementsInstancedBaseVertexBaseInstance; | 1930 | PFNGLPRIMITIVEBOUNDINGBOXARBPROC glad_glPrimitiveBoundingBoxARB = NULL; |
| 1930 | PFNGLGETTEXTUREHANDLEARBPROC glad_glGetTextureHandleARB; | 1931 | PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glad_glDrawArraysInstancedBaseInstance = NULL; |
| 1931 | PFNGLGETTEXTURESAMPLERHANDLEARBPROC glad_glGetTextureSamplerHandleARB; | 1932 | PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC glad_glDrawElementsInstancedBaseInstance = NULL; |
| 1932 | PFNGLMAKETEXTUREHANDLERESIDENTARBPROC glad_glMakeTextureHandleResidentARB; | 1933 | PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glad_glDrawElementsInstancedBaseVertexBaseInstance = NULL; |
| 1933 | PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC glad_glMakeTextureHandleNonResidentARB; | 1934 | PFNGLGETTEXTUREHANDLEARBPROC glad_glGetTextureHandleARB = NULL; |
| 1934 | PFNGLGETIMAGEHANDLEARBPROC glad_glGetImageHandleARB; | 1935 | PFNGLGETTEXTURESAMPLERHANDLEARBPROC glad_glGetTextureSamplerHandleARB = NULL; |
| 1935 | PFNGLMAKEIMAGEHANDLERESIDENTARBPROC glad_glMakeImageHandleResidentARB; | 1936 | PFNGLMAKETEXTUREHANDLERESIDENTARBPROC glad_glMakeTextureHandleResidentARB = NULL; |
| 1936 | PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC glad_glMakeImageHandleNonResidentARB; | 1937 | PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC glad_glMakeTextureHandleNonResidentARB = NULL; |
| 1937 | PFNGLUNIFORMHANDLEUI64ARBPROC glad_glUniformHandleui64ARB; | 1938 | PFNGLGETIMAGEHANDLEARBPROC glad_glGetImageHandleARB = NULL; |
| 1938 | PFNGLUNIFORMHANDLEUI64VARBPROC glad_glUniformHandleui64vARB; | 1939 | PFNGLMAKEIMAGEHANDLERESIDENTARBPROC glad_glMakeImageHandleResidentARB = NULL; |
| 1939 | PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC glad_glProgramUniformHandleui64ARB; | 1940 | PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC glad_glMakeImageHandleNonResidentARB = NULL; |
| 1940 | PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC glad_glProgramUniformHandleui64vARB; | 1941 | PFNGLUNIFORMHANDLEUI64ARBPROC glad_glUniformHandleui64ARB = NULL; |
| 1941 | PFNGLISTEXTUREHANDLERESIDENTARBPROC glad_glIsTextureHandleResidentARB; | 1942 | PFNGLUNIFORMHANDLEUI64VARBPROC glad_glUniformHandleui64vARB = NULL; |
| 1942 | PFNGLISIMAGEHANDLERESIDENTARBPROC glad_glIsImageHandleResidentARB; | 1943 | PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC glad_glProgramUniformHandleui64ARB = NULL; |
| 1943 | PFNGLVERTEXATTRIBL1UI64ARBPROC glad_glVertexAttribL1ui64ARB; | 1944 | PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC glad_glProgramUniformHandleui64vARB = NULL; |
| 1944 | PFNGLVERTEXATTRIBL1UI64VARBPROC glad_glVertexAttribL1ui64vARB; | 1945 | PFNGLISTEXTUREHANDLERESIDENTARBPROC glad_glIsTextureHandleResidentARB = NULL; |
| 1945 | PFNGLGETVERTEXATTRIBLUI64VARBPROC glad_glGetVertexAttribLui64vARB; | 1946 | PFNGLISIMAGEHANDLERESIDENTARBPROC glad_glIsImageHandleResidentARB = NULL; |
| 1946 | PFNGLBUFFERSTORAGEPROC glad_glBufferStorage; | 1947 | PFNGLVERTEXATTRIBL1UI64ARBPROC glad_glVertexAttribL1ui64ARB = NULL; |
| 1947 | PFNGLCREATESYNCFROMCLEVENTARBPROC glad_glCreateSyncFromCLeventARB; | 1948 | PFNGLVERTEXATTRIBL1UI64VARBPROC glad_glVertexAttribL1ui64vARB = NULL; |
| 1948 | PFNGLCLEARBUFFERDATAPROC glad_glClearBufferData; | 1949 | PFNGLGETVERTEXATTRIBLUI64VARBPROC glad_glGetVertexAttribLui64vARB = NULL; |
| 1949 | PFNGLCLEARBUFFERSUBDATAPROC glad_glClearBufferSubData; | 1950 | PFNGLBUFFERSTORAGEPROC glad_glBufferStorage = NULL; |
| 1950 | PFNGLCLEARTEXIMAGEPROC glad_glClearTexImage; | 1951 | PFNGLCREATESYNCFROMCLEVENTARBPROC glad_glCreateSyncFromCLeventARB = NULL; |
| 1951 | PFNGLCLEARTEXSUBIMAGEPROC glad_glClearTexSubImage; | 1952 | PFNGLCLEARBUFFERDATAPROC glad_glClearBufferData = NULL; |
| 1952 | PFNGLCLIPCONTROLPROC glad_glClipControl; | 1953 | PFNGLCLEARBUFFERSUBDATAPROC glad_glClearBufferSubData = NULL; |
| 1953 | PFNGLCLAMPCOLORARBPROC glad_glClampColorARB; | 1954 | PFNGLCLEARTEXIMAGEPROC glad_glClearTexImage = NULL; |
| 1954 | PFNGLDISPATCHCOMPUTEPROC glad_glDispatchCompute; | 1955 | PFNGLCLEARTEXSUBIMAGEPROC glad_glClearTexSubImage = NULL; |
| 1955 | PFNGLDISPATCHCOMPUTEINDIRECTPROC glad_glDispatchComputeIndirect; | 1956 | PFNGLCLIPCONTROLPROC glad_glClipControl = NULL; |
| 1956 | PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC glad_glDispatchComputeGroupSizeARB; | 1957 | PFNGLCLAMPCOLORARBPROC glad_glClampColorARB = NULL; |
| 1957 | PFNGLCOPYIMAGESUBDATAPROC glad_glCopyImageSubData; | 1958 | PFNGLDISPATCHCOMPUTEPROC glad_glDispatchCompute = NULL; |
| 1958 | PFNGLDEBUGMESSAGECONTROLARBPROC glad_glDebugMessageControlARB; | 1959 | PFNGLDISPATCHCOMPUTEINDIRECTPROC glad_glDispatchComputeIndirect = NULL; |
| 1959 | PFNGLDEBUGMESSAGEINSERTARBPROC glad_glDebugMessageInsertARB; | 1960 | PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC glad_glDispatchComputeGroupSizeARB = NULL; |
| 1960 | PFNGLDEBUGMESSAGECALLBACKARBPROC glad_glDebugMessageCallbackARB; | 1961 | PFNGLCOPYIMAGESUBDATAPROC glad_glCopyImageSubData = NULL; |
| 1961 | PFNGLGETDEBUGMESSAGELOGARBPROC glad_glGetDebugMessageLogARB; | 1962 | PFNGLDEBUGMESSAGECONTROLARBPROC glad_glDebugMessageControlARB = NULL; |
| 1962 | PFNGLCREATETRANSFORMFEEDBACKSPROC glad_glCreateTransformFeedbacks; | 1963 | PFNGLDEBUGMESSAGEINSERTARBPROC glad_glDebugMessageInsertARB = NULL; |
| 1963 | PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC glad_glTransformFeedbackBufferBase; | 1964 | PFNGLDEBUGMESSAGECALLBACKARBPROC glad_glDebugMessageCallbackARB = NULL; |
| 1964 | PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC glad_glTransformFeedbackBufferRange; | 1965 | PFNGLGETDEBUGMESSAGELOGARBPROC glad_glGetDebugMessageLogARB = NULL; |
| 1965 | PFNGLGETTRANSFORMFEEDBACKIVPROC glad_glGetTransformFeedbackiv; | 1966 | PFNGLCREATETRANSFORMFEEDBACKSPROC glad_glCreateTransformFeedbacks = NULL; |
| 1966 | PFNGLGETTRANSFORMFEEDBACKI_VPROC glad_glGetTransformFeedbacki_v; | 1967 | PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC glad_glTransformFeedbackBufferBase = NULL; |
| 1967 | PFNGLGETTRANSFORMFEEDBACKI64_VPROC glad_glGetTransformFeedbacki64_v; | 1968 | PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC glad_glTransformFeedbackBufferRange = NULL; |
| 1968 | PFNGLCREATEBUFFERSPROC glad_glCreateBuffers; | 1969 | PFNGLGETTRANSFORMFEEDBACKIVPROC glad_glGetTransformFeedbackiv = NULL; |
| 1969 | PFNGLNAMEDBUFFERSTORAGEPROC glad_glNamedBufferStorage; | 1970 | PFNGLGETTRANSFORMFEEDBACKI_VPROC glad_glGetTransformFeedbacki_v = NULL; |
| 1970 | PFNGLNAMEDBUFFERDATAPROC glad_glNamedBufferData; | 1971 | PFNGLGETTRANSFORMFEEDBACKI64_VPROC glad_glGetTransformFeedbacki64_v = NULL; |
| 1971 | PFNGLNAMEDBUFFERSUBDATAPROC glad_glNamedBufferSubData; | 1972 | PFNGLCREATEBUFFERSPROC glad_glCreateBuffers = NULL; |
| 1972 | PFNGLCOPYNAMEDBUFFERSUBDATAPROC glad_glCopyNamedBufferSubData; | 1973 | PFNGLNAMEDBUFFERSTORAGEPROC glad_glNamedBufferStorage = NULL; |
| 1973 | PFNGLCLEARNAMEDBUFFERDATAPROC glad_glClearNamedBufferData; | 1974 | PFNGLNAMEDBUFFERDATAPROC glad_glNamedBufferData = NULL; |
| 1974 | PFNGLCLEARNAMEDBUFFERSUBDATAPROC glad_glClearNamedBufferSubData; | 1975 | PFNGLNAMEDBUFFERSUBDATAPROC glad_glNamedBufferSubData = NULL; |
| 1975 | PFNGLMAPNAMEDBUFFERPROC glad_glMapNamedBuffer; | 1976 | PFNGLCOPYNAMEDBUFFERSUBDATAPROC glad_glCopyNamedBufferSubData = NULL; |
| 1976 | PFNGLMAPNAMEDBUFFERRANGEPROC glad_glMapNamedBufferRange; | 1977 | PFNGLCLEARNAMEDBUFFERDATAPROC glad_glClearNamedBufferData = NULL; |
| 1977 | PFNGLUNMAPNAMEDBUFFERPROC glad_glUnmapNamedBuffer; | 1978 | PFNGLCLEARNAMEDBUFFERSUBDATAPROC glad_glClearNamedBufferSubData = NULL; |
| 1978 | PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC glad_glFlushMappedNamedBufferRange; | 1979 | PFNGLMAPNAMEDBUFFERPROC glad_glMapNamedBuffer = NULL; |
| 1979 | PFNGLGETNAMEDBUFFERPARAMETERIVPROC glad_glGetNamedBufferParameteriv; | 1980 | PFNGLMAPNAMEDBUFFERRANGEPROC glad_glMapNamedBufferRange = NULL; |
| 1980 | PFNGLGETNAMEDBUFFERPARAMETERI64VPROC glad_glGetNamedBufferParameteri64v; | 1981 | PFNGLUNMAPNAMEDBUFFERPROC glad_glUnmapNamedBuffer = NULL; |
| 1981 | PFNGLGETNAMEDBUFFERPOINTERVPROC glad_glGetNamedBufferPointerv; | 1982 | PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC glad_glFlushMappedNamedBufferRange = NULL; |
| 1982 | PFNGLGETNAMEDBUFFERSUBDATAPROC glad_glGetNamedBufferSubData; | 1983 | PFNGLGETNAMEDBUFFERPARAMETERIVPROC glad_glGetNamedBufferParameteriv = NULL; |
| 1983 | PFNGLCREATEFRAMEBUFFERSPROC glad_glCreateFramebuffers; | 1984 | PFNGLGETNAMEDBUFFERPARAMETERI64VPROC glad_glGetNamedBufferParameteri64v = NULL; |
| 1984 | PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC glad_glNamedFramebufferRenderbuffer; | 1985 | PFNGLGETNAMEDBUFFERPOINTERVPROC glad_glGetNamedBufferPointerv = NULL; |
| 1985 | PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC glad_glNamedFramebufferParameteri; | 1986 | PFNGLGETNAMEDBUFFERSUBDATAPROC glad_glGetNamedBufferSubData = NULL; |
| 1986 | PFNGLNAMEDFRAMEBUFFERTEXTUREPROC glad_glNamedFramebufferTexture; | 1987 | PFNGLCREATEFRAMEBUFFERSPROC glad_glCreateFramebuffers = NULL; |
| 1987 | PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC glad_glNamedFramebufferTextureLayer; | 1988 | PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC glad_glNamedFramebufferRenderbuffer = NULL; |
| 1988 | PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC glad_glNamedFramebufferDrawBuffer; | 1989 | PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC glad_glNamedFramebufferParameteri = NULL; |
| 1989 | PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC glad_glNamedFramebufferDrawBuffers; | 1990 | PFNGLNAMEDFRAMEBUFFERTEXTUREPROC glad_glNamedFramebufferTexture = NULL; |
| 1990 | PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC glad_glNamedFramebufferReadBuffer; | 1991 | PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC glad_glNamedFramebufferTextureLayer = NULL; |
| 1991 | PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC glad_glInvalidateNamedFramebufferData; | 1992 | PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC glad_glNamedFramebufferDrawBuffer = NULL; |
| 1992 | PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC glad_glInvalidateNamedFramebufferSubData; | 1993 | PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC glad_glNamedFramebufferDrawBuffers = NULL; |
| 1993 | PFNGLCLEARNAMEDFRAMEBUFFERIVPROC glad_glClearNamedFramebufferiv; | 1994 | PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC glad_glNamedFramebufferReadBuffer = NULL; |
| 1994 | PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC glad_glClearNamedFramebufferuiv; | 1995 | PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC glad_glInvalidateNamedFramebufferData = NULL; |
| 1995 | PFNGLCLEARNAMEDFRAMEBUFFERFVPROC glad_glClearNamedFramebufferfv; | 1996 | PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC glad_glInvalidateNamedFramebufferSubData = NULL; |
| 1996 | PFNGLCLEARNAMEDFRAMEBUFFERFIPROC glad_glClearNamedFramebufferfi; | 1997 | PFNGLCLEARNAMEDFRAMEBUFFERIVPROC glad_glClearNamedFramebufferiv = NULL; |
| 1997 | PFNGLBLITNAMEDFRAMEBUFFERPROC glad_glBlitNamedFramebuffer; | 1998 | PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC glad_glClearNamedFramebufferuiv = NULL; |
| 1998 | PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC glad_glCheckNamedFramebufferStatus; | 1999 | PFNGLCLEARNAMEDFRAMEBUFFERFVPROC glad_glClearNamedFramebufferfv = NULL; |
| 1999 | PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC glad_glGetNamedFramebufferParameteriv; | 2000 | PFNGLCLEARNAMEDFRAMEBUFFERFIPROC glad_glClearNamedFramebufferfi = NULL; |
| 2000 | PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetNamedFramebufferAttachmentParameteriv; | 2001 | PFNGLBLITNAMEDFRAMEBUFFERPROC glad_glBlitNamedFramebuffer = NULL; |
| 2001 | PFNGLCREATERENDERBUFFERSPROC glad_glCreateRenderbuffers; | 2002 | PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC glad_glCheckNamedFramebufferStatus = NULL; |
| 2002 | PFNGLNAMEDRENDERBUFFERSTORAGEPROC glad_glNamedRenderbufferStorage; | 2003 | PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC glad_glGetNamedFramebufferParameteriv = NULL; |
| 2003 | PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glNamedRenderbufferStorageMultisample; | 2004 | PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetNamedFramebufferAttachmentParameteriv = NULL; |
| 2004 | PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC glad_glGetNamedRenderbufferParameteriv; | 2005 | PFNGLCREATERENDERBUFFERSPROC glad_glCreateRenderbuffers = NULL; |
| 2005 | PFNGLCREATETEXTURESPROC glad_glCreateTextures; | 2006 | PFNGLNAMEDRENDERBUFFERSTORAGEPROC glad_glNamedRenderbufferStorage = NULL; |
| 2006 | PFNGLTEXTUREBUFFERPROC glad_glTextureBuffer; | 2007 | PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glNamedRenderbufferStorageMultisample = NULL; |
| 2007 | PFNGLTEXTUREBUFFERRANGEPROC glad_glTextureBufferRange; | 2008 | PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC glad_glGetNamedRenderbufferParameteriv = NULL; |
| 2008 | PFNGLTEXTURESTORAGE1DPROC glad_glTextureStorage1D; | 2009 | PFNGLCREATETEXTURESPROC glad_glCreateTextures = NULL; |
| 2009 | PFNGLTEXTURESTORAGE2DPROC glad_glTextureStorage2D; | 2010 | PFNGLTEXTUREBUFFERPROC glad_glTextureBuffer = NULL; |
| 2010 | PFNGLTEXTURESTORAGE3DPROC glad_glTextureStorage3D; | 2011 | PFNGLTEXTUREBUFFERRANGEPROC glad_glTextureBufferRange = NULL; |
| 2011 | PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC glad_glTextureStorage2DMultisample; | 2012 | PFNGLTEXTURESTORAGE1DPROC glad_glTextureStorage1D = NULL; |
| 2012 | PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC glad_glTextureStorage3DMultisample; | 2013 | PFNGLTEXTURESTORAGE2DPROC glad_glTextureStorage2D = NULL; |
| 2013 | PFNGLTEXTURESUBIMAGE1DPROC glad_glTextureSubImage1D; | 2014 | PFNGLTEXTURESTORAGE3DPROC glad_glTextureStorage3D = NULL; |
| 2014 | PFNGLTEXTURESUBIMAGE2DPROC glad_glTextureSubImage2D; | 2015 | PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC glad_glTextureStorage2DMultisample = NULL; |
| 2015 | PFNGLTEXTURESUBIMAGE3DPROC glad_glTextureSubImage3D; | 2016 | PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC glad_glTextureStorage3DMultisample = NULL; |
| 2016 | PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC glad_glCompressedTextureSubImage1D; | 2017 | PFNGLTEXTURESUBIMAGE1DPROC glad_glTextureSubImage1D = NULL; |
| 2017 | PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC glad_glCompressedTextureSubImage2D; | 2018 | PFNGLTEXTURESUBIMAGE2DPROC glad_glTextureSubImage2D = NULL; |
| 2018 | PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC glad_glCompressedTextureSubImage3D; | 2019 | PFNGLTEXTURESUBIMAGE3DPROC glad_glTextureSubImage3D = NULL; |
| 2019 | PFNGLCOPYTEXTURESUBIMAGE1DPROC glad_glCopyTextureSubImage1D; | 2020 | PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC glad_glCompressedTextureSubImage1D = NULL; |
| 2020 | PFNGLCOPYTEXTURESUBIMAGE2DPROC glad_glCopyTextureSubImage2D; | 2021 | PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC glad_glCompressedTextureSubImage2D = NULL; |
| 2021 | PFNGLCOPYTEXTURESUBIMAGE3DPROC glad_glCopyTextureSubImage3D; | 2022 | PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC glad_glCompressedTextureSubImage3D = NULL; |
| 2022 | PFNGLTEXTUREPARAMETERFPROC glad_glTextureParameterf; | 2023 | PFNGLCOPYTEXTURESUBIMAGE1DPROC glad_glCopyTextureSubImage1D = NULL; |
| 2023 | PFNGLTEXTUREPARAMETERFVPROC glad_glTextureParameterfv; | 2024 | PFNGLCOPYTEXTURESUBIMAGE2DPROC glad_glCopyTextureSubImage2D = NULL; |
| 2024 | PFNGLTEXTUREPARAMETERIPROC glad_glTextureParameteri; | 2025 | PFNGLCOPYTEXTURESUBIMAGE3DPROC glad_glCopyTextureSubImage3D = NULL; |
| 2025 | PFNGLTEXTUREPARAMETERIIVPROC glad_glTextureParameterIiv; | 2026 | PFNGLTEXTUREPARAMETERFPROC glad_glTextureParameterf = NULL; |
| 2026 | PFNGLTEXTUREPARAMETERIUIVPROC glad_glTextureParameterIuiv; | 2027 | PFNGLTEXTUREPARAMETERFVPROC glad_glTextureParameterfv = NULL; |
| 2027 | PFNGLTEXTUREPARAMETERIVPROC glad_glTextureParameteriv; | 2028 | PFNGLTEXTUREPARAMETERIPROC glad_glTextureParameteri = NULL; |
| 2028 | PFNGLGENERATETEXTUREMIPMAPPROC glad_glGenerateTextureMipmap; | 2029 | PFNGLTEXTUREPARAMETERIIVPROC glad_glTextureParameterIiv = NULL; |
| 2029 | PFNGLBINDTEXTUREUNITPROC glad_glBindTextureUnit; | 2030 | PFNGLTEXTUREPARAMETERIUIVPROC glad_glTextureParameterIuiv = NULL; |
| 2030 | PFNGLGETTEXTUREIMAGEPROC glad_glGetTextureImage; | 2031 | PFNGLTEXTUREPARAMETERIVPROC glad_glTextureParameteriv = NULL; |
| 2031 | PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC glad_glGetCompressedTextureImage; | 2032 | PFNGLGENERATETEXTUREMIPMAPPROC glad_glGenerateTextureMipmap = NULL; |
| 2032 | PFNGLGETTEXTURELEVELPARAMETERFVPROC glad_glGetTextureLevelParameterfv; | 2033 | PFNGLBINDTEXTUREUNITPROC glad_glBindTextureUnit = NULL; |
| 2033 | PFNGLGETTEXTURELEVELPARAMETERIVPROC glad_glGetTextureLevelParameteriv; | 2034 | PFNGLGETTEXTUREIMAGEPROC glad_glGetTextureImage = NULL; |
| 2034 | PFNGLGETTEXTUREPARAMETERFVPROC glad_glGetTextureParameterfv; | 2035 | PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC glad_glGetCompressedTextureImage = NULL; |
| 2035 | PFNGLGETTEXTUREPARAMETERIIVPROC glad_glGetTextureParameterIiv; | 2036 | PFNGLGETTEXTURELEVELPARAMETERFVPROC glad_glGetTextureLevelParameterfv = NULL; |
| 2036 | PFNGLGETTEXTUREPARAMETERIUIVPROC glad_glGetTextureParameterIuiv; | 2037 | PFNGLGETTEXTURELEVELPARAMETERIVPROC glad_glGetTextureLevelParameteriv = NULL; |
| 2037 | PFNGLGETTEXTUREPARAMETERIVPROC glad_glGetTextureParameteriv; | 2038 | PFNGLGETTEXTUREPARAMETERFVPROC glad_glGetTextureParameterfv = NULL; |
| 2038 | PFNGLCREATEVERTEXARRAYSPROC glad_glCreateVertexArrays; | 2039 | PFNGLGETTEXTUREPARAMETERIIVPROC glad_glGetTextureParameterIiv = NULL; |
| 2039 | PFNGLDISABLEVERTEXARRAYATTRIBPROC glad_glDisableVertexArrayAttrib; | 2040 | PFNGLGETTEXTUREPARAMETERIUIVPROC glad_glGetTextureParameterIuiv = NULL; |
| 2040 | PFNGLENABLEVERTEXARRAYATTRIBPROC glad_glEnableVertexArrayAttrib; | 2041 | PFNGLGETTEXTUREPARAMETERIVPROC glad_glGetTextureParameteriv = NULL; |
| 2041 | PFNGLVERTEXARRAYELEMENTBUFFERPROC glad_glVertexArrayElementBuffer; | 2042 | PFNGLCREATEVERTEXARRAYSPROC glad_glCreateVertexArrays = NULL; |
| 2042 | PFNGLVERTEXARRAYVERTEXBUFFERPROC glad_glVertexArrayVertexBuffer; | 2043 | PFNGLDISABLEVERTEXARRAYATTRIBPROC glad_glDisableVertexArrayAttrib = NULL; |
| 2043 | PFNGLVERTEXARRAYVERTEXBUFFERSPROC glad_glVertexArrayVertexBuffers; | 2044 | PFNGLENABLEVERTEXARRAYATTRIBPROC glad_glEnableVertexArrayAttrib = NULL; |
| 2044 | PFNGLVERTEXARRAYATTRIBBINDINGPROC glad_glVertexArrayAttribBinding; | 2045 | PFNGLVERTEXARRAYELEMENTBUFFERPROC glad_glVertexArrayElementBuffer = NULL; |
| 2045 | PFNGLVERTEXARRAYATTRIBFORMATPROC glad_glVertexArrayAttribFormat; | 2046 | PFNGLVERTEXARRAYVERTEXBUFFERPROC glad_glVertexArrayVertexBuffer = NULL; |
| 2046 | PFNGLVERTEXARRAYATTRIBIFORMATPROC glad_glVertexArrayAttribIFormat; | 2047 | PFNGLVERTEXARRAYVERTEXBUFFERSPROC glad_glVertexArrayVertexBuffers = NULL; |
| 2047 | PFNGLVERTEXARRAYATTRIBLFORMATPROC glad_glVertexArrayAttribLFormat; | 2048 | PFNGLVERTEXARRAYATTRIBBINDINGPROC glad_glVertexArrayAttribBinding = NULL; |
| 2048 | PFNGLVERTEXARRAYBINDINGDIVISORPROC glad_glVertexArrayBindingDivisor; | 2049 | PFNGLVERTEXARRAYATTRIBFORMATPROC glad_glVertexArrayAttribFormat = NULL; |
| 2049 | PFNGLGETVERTEXARRAYIVPROC glad_glGetVertexArrayiv; | 2050 | PFNGLVERTEXARRAYATTRIBIFORMATPROC glad_glVertexArrayAttribIFormat = NULL; |
| 2050 | PFNGLGETVERTEXARRAYINDEXEDIVPROC glad_glGetVertexArrayIndexediv; | 2051 | PFNGLVERTEXARRAYATTRIBLFORMATPROC glad_glVertexArrayAttribLFormat = NULL; |
| 2051 | PFNGLGETVERTEXARRAYINDEXED64IVPROC glad_glGetVertexArrayIndexed64iv; | 2052 | PFNGLVERTEXARRAYBINDINGDIVISORPROC glad_glVertexArrayBindingDivisor = NULL; |
| 2052 | PFNGLCREATESAMPLERSPROC glad_glCreateSamplers; | 2053 | PFNGLGETVERTEXARRAYIVPROC glad_glGetVertexArrayiv = NULL; |
| 2053 | PFNGLCREATEPROGRAMPIPELINESPROC glad_glCreateProgramPipelines; | 2054 | PFNGLGETVERTEXARRAYINDEXEDIVPROC glad_glGetVertexArrayIndexediv = NULL; |
| 2054 | PFNGLCREATEQUERIESPROC glad_glCreateQueries; | 2055 | PFNGLGETVERTEXARRAYINDEXED64IVPROC glad_glGetVertexArrayIndexed64iv = NULL; |
| 2055 | PFNGLGETQUERYBUFFEROBJECTI64VPROC glad_glGetQueryBufferObjecti64v; | 2056 | PFNGLCREATESAMPLERSPROC glad_glCreateSamplers = NULL; |
| 2056 | PFNGLGETQUERYBUFFEROBJECTIVPROC glad_glGetQueryBufferObjectiv; | 2057 | PFNGLCREATEPROGRAMPIPELINESPROC glad_glCreateProgramPipelines = NULL; |
| 2057 | PFNGLGETQUERYBUFFEROBJECTUI64VPROC glad_glGetQueryBufferObjectui64v; | 2058 | PFNGLCREATEQUERIESPROC glad_glCreateQueries = NULL; |
| 2058 | PFNGLGETQUERYBUFFEROBJECTUIVPROC glad_glGetQueryBufferObjectuiv; | 2059 | PFNGLGETQUERYBUFFEROBJECTI64VPROC glad_glGetQueryBufferObjecti64v = NULL; |
| 2059 | PFNGLDRAWBUFFERSARBPROC glad_glDrawBuffersARB; | 2060 | PFNGLGETQUERYBUFFEROBJECTIVPROC glad_glGetQueryBufferObjectiv = NULL; |
| 2060 | PFNGLBLENDEQUATIONIARBPROC glad_glBlendEquationiARB; | 2061 | PFNGLGETQUERYBUFFEROBJECTUI64VPROC glad_glGetQueryBufferObjectui64v = NULL; |
| 2061 | PFNGLBLENDEQUATIONSEPARATEIARBPROC glad_glBlendEquationSeparateiARB; | 2062 | PFNGLGETQUERYBUFFEROBJECTUIVPROC glad_glGetQueryBufferObjectuiv = NULL; |
| 2062 | PFNGLBLENDFUNCIARBPROC glad_glBlendFunciARB; | 2063 | PFNGLDRAWBUFFERSARBPROC glad_glDrawBuffersARB = NULL; |
| 2063 | PFNGLBLENDFUNCSEPARATEIARBPROC glad_glBlendFuncSeparateiARB; | 2064 | PFNGLBLENDEQUATIONIARBPROC glad_glBlendEquationiARB = NULL; |
| 2064 | PFNGLDRAWARRAYSINDIRECTPROC glad_glDrawArraysIndirect; | 2065 | PFNGLBLENDEQUATIONSEPARATEIARBPROC glad_glBlendEquationSeparateiARB = NULL; |
| 2065 | PFNGLDRAWELEMENTSINDIRECTPROC glad_glDrawElementsIndirect; | 2066 | PFNGLBLENDFUNCIARBPROC glad_glBlendFunciARB = NULL; |
| 2066 | PFNGLDRAWARRAYSINSTANCEDARBPROC glad_glDrawArraysInstancedARB; | 2067 | PFNGLBLENDFUNCSEPARATEIARBPROC glad_glBlendFuncSeparateiARB = NULL; |
| 2067 | PFNGLDRAWELEMENTSINSTANCEDARBPROC glad_glDrawElementsInstancedARB; | 2068 | PFNGLDRAWARRAYSINDIRECTPROC glad_glDrawArraysIndirect = NULL; |
| 2068 | PFNGLPROGRAMSTRINGARBPROC glad_glProgramStringARB; | 2069 | PFNGLDRAWELEMENTSINDIRECTPROC glad_glDrawElementsIndirect = NULL; |
| 2069 | PFNGLBINDPROGRAMARBPROC glad_glBindProgramARB; | 2070 | PFNGLDRAWARRAYSINSTANCEDARBPROC glad_glDrawArraysInstancedARB = NULL; |
| 2070 | PFNGLDELETEPROGRAMSARBPROC glad_glDeleteProgramsARB; | 2071 | PFNGLDRAWELEMENTSINSTANCEDARBPROC glad_glDrawElementsInstancedARB = NULL; |
| 2071 | PFNGLGENPROGRAMSARBPROC glad_glGenProgramsARB; | 2072 | PFNGLPROGRAMSTRINGARBPROC glad_glProgramStringARB = NULL; |
| 2072 | PFNGLPROGRAMENVPARAMETER4DARBPROC glad_glProgramEnvParameter4dARB; | 2073 | PFNGLBINDPROGRAMARBPROC glad_glBindProgramARB = NULL; |
| 2073 | PFNGLPROGRAMENVPARAMETER4DVARBPROC glad_glProgramEnvParameter4dvARB; | 2074 | PFNGLDELETEPROGRAMSARBPROC glad_glDeleteProgramsARB = NULL; |
| 2074 | PFNGLPROGRAMENVPARAMETER4FARBPROC glad_glProgramEnvParameter4fARB; | 2075 | PFNGLGENPROGRAMSARBPROC glad_glGenProgramsARB = NULL; |
| 2075 | PFNGLPROGRAMENVPARAMETER4FVARBPROC glad_glProgramEnvParameter4fvARB; | 2076 | PFNGLPROGRAMENVPARAMETER4DARBPROC glad_glProgramEnvParameter4dARB = NULL; |
| 2076 | PFNGLPROGRAMLOCALPARAMETER4DARBPROC glad_glProgramLocalParameter4dARB; | 2077 | PFNGLPROGRAMENVPARAMETER4DVARBPROC glad_glProgramEnvParameter4dvARB = NULL; |
| 2077 | PFNGLPROGRAMLOCALPARAMETER4DVARBPROC glad_glProgramLocalParameter4dvARB; | 2078 | PFNGLPROGRAMENVPARAMETER4FARBPROC glad_glProgramEnvParameter4fARB = NULL; |
| 2078 | PFNGLPROGRAMLOCALPARAMETER4FARBPROC glad_glProgramLocalParameter4fARB; | 2079 | PFNGLPROGRAMENVPARAMETER4FVARBPROC glad_glProgramEnvParameter4fvARB = NULL; |
| 2079 | PFNGLPROGRAMLOCALPARAMETER4FVARBPROC glad_glProgramLocalParameter4fvARB; | 2080 | PFNGLPROGRAMLOCALPARAMETER4DARBPROC glad_glProgramLocalParameter4dARB = NULL; |
| 2080 | PFNGLGETPROGRAMENVPARAMETERDVARBPROC glad_glGetProgramEnvParameterdvARB; | 2081 | PFNGLPROGRAMLOCALPARAMETER4DVARBPROC glad_glProgramLocalParameter4dvARB = NULL; |
| 2081 | PFNGLGETPROGRAMENVPARAMETERFVARBPROC glad_glGetProgramEnvParameterfvARB; | 2082 | PFNGLPROGRAMLOCALPARAMETER4FARBPROC glad_glProgramLocalParameter4fARB = NULL; |
| 2082 | PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC glad_glGetProgramLocalParameterdvARB; | 2083 | PFNGLPROGRAMLOCALPARAMETER4FVARBPROC glad_glProgramLocalParameter4fvARB = NULL; |
| 2083 | PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC glad_glGetProgramLocalParameterfvARB; | 2084 | PFNGLGETPROGRAMENVPARAMETERDVARBPROC glad_glGetProgramEnvParameterdvARB = NULL; |
| 2084 | PFNGLGETPROGRAMIVARBPROC glad_glGetProgramivARB; | 2085 | PFNGLGETPROGRAMENVPARAMETERFVARBPROC glad_glGetProgramEnvParameterfvARB = NULL; |
| 2085 | PFNGLGETPROGRAMSTRINGARBPROC glad_glGetProgramStringARB; | 2086 | PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC glad_glGetProgramLocalParameterdvARB = NULL; |
| 2086 | PFNGLISPROGRAMARBPROC glad_glIsProgramARB; | 2087 | PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC glad_glGetProgramLocalParameterfvARB = NULL; |
| 2087 | PFNGLFRAMEBUFFERPARAMETERIPROC glad_glFramebufferParameteri; | 2088 | PFNGLGETPROGRAMIVARBPROC glad_glGetProgramivARB = NULL; |
| 2088 | PFNGLGETFRAMEBUFFERPARAMETERIVPROC glad_glGetFramebufferParameteriv; | 2089 | PFNGLGETPROGRAMSTRINGARBPROC glad_glGetProgramStringARB = NULL; |
| 2089 | PFNGLPROGRAMPARAMETERIARBPROC glad_glProgramParameteriARB; | 2090 | PFNGLISPROGRAMARBPROC glad_glIsProgramARB = NULL; |
| 2090 | PFNGLFRAMEBUFFERTEXTUREARBPROC glad_glFramebufferTextureARB; | 2091 | PFNGLFRAMEBUFFERPARAMETERIPROC glad_glFramebufferParameteri = NULL; |
| 2091 | PFNGLFRAMEBUFFERTEXTURELAYERARBPROC glad_glFramebufferTextureLayerARB; | 2092 | PFNGLGETFRAMEBUFFERPARAMETERIVPROC glad_glGetFramebufferParameteriv = NULL; |
| 2092 | PFNGLFRAMEBUFFERTEXTUREFACEARBPROC glad_glFramebufferTextureFaceARB; | 2093 | PFNGLPROGRAMPARAMETERIARBPROC glad_glProgramParameteriARB = NULL; |
| 2093 | PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary; | 2094 | PFNGLFRAMEBUFFERTEXTUREARBPROC glad_glFramebufferTextureARB = NULL; |
| 2094 | PFNGLPROGRAMBINARYPROC glad_glProgramBinary; | 2095 | PFNGLFRAMEBUFFERTEXTURELAYERARBPROC glad_glFramebufferTextureLayerARB = NULL; |
| 2095 | PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri; | 2096 | PFNGLFRAMEBUFFERTEXTUREFACEARBPROC glad_glFramebufferTextureFaceARB = NULL; |
| 2096 | PFNGLGETTEXTURESUBIMAGEPROC glad_glGetTextureSubImage; | 2097 | PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary = NULL; |
| 2097 | PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC glad_glGetCompressedTextureSubImage; | 2098 | PFNGLPROGRAMBINARYPROC glad_glProgramBinary = NULL; |
| 2098 | PFNGLSPECIALIZESHADERARBPROC glad_glSpecializeShaderARB; | 2099 | PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri = NULL; |
| 2099 | PFNGLUNIFORM1DPROC glad_glUniform1d; | 2100 | PFNGLGETTEXTURESUBIMAGEPROC glad_glGetTextureSubImage = NULL; |
| 2100 | PFNGLUNIFORM2DPROC glad_glUniform2d; | 2101 | PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC glad_glGetCompressedTextureSubImage = NULL; |
| 2101 | PFNGLUNIFORM3DPROC glad_glUniform3d; | 2102 | PFNGLSPECIALIZESHADERARBPROC glad_glSpecializeShaderARB = NULL; |
| 2102 | PFNGLUNIFORM4DPROC glad_glUniform4d; | 2103 | PFNGLUNIFORM1DPROC glad_glUniform1d = NULL; |
| 2103 | PFNGLUNIFORM1DVPROC glad_glUniform1dv; | 2104 | PFNGLUNIFORM2DPROC glad_glUniform2d = NULL; |
| 2104 | PFNGLUNIFORM2DVPROC glad_glUniform2dv; | 2105 | PFNGLUNIFORM3DPROC glad_glUniform3d = NULL; |
| 2105 | PFNGLUNIFORM3DVPROC glad_glUniform3dv; | 2106 | PFNGLUNIFORM4DPROC glad_glUniform4d = NULL; |
| 2106 | PFNGLUNIFORM4DVPROC glad_glUniform4dv; | 2107 | PFNGLUNIFORM1DVPROC glad_glUniform1dv = NULL; |
| 2107 | PFNGLUNIFORMMATRIX2DVPROC glad_glUniformMatrix2dv; | 2108 | PFNGLUNIFORM2DVPROC glad_glUniform2dv = NULL; |
| 2108 | PFNGLUNIFORMMATRIX3DVPROC glad_glUniformMatrix3dv; | 2109 | PFNGLUNIFORM3DVPROC glad_glUniform3dv = NULL; |
| 2109 | PFNGLUNIFORMMATRIX4DVPROC glad_glUniformMatrix4dv; | 2110 | PFNGLUNIFORM4DVPROC glad_glUniform4dv = NULL; |
| 2110 | PFNGLUNIFORMMATRIX2X3DVPROC glad_glUniformMatrix2x3dv; | 2111 | PFNGLUNIFORMMATRIX2DVPROC glad_glUniformMatrix2dv = NULL; |
| 2111 | PFNGLUNIFORMMATRIX2X4DVPROC glad_glUniformMatrix2x4dv; | 2112 | PFNGLUNIFORMMATRIX3DVPROC glad_glUniformMatrix3dv = NULL; |
| 2112 | PFNGLUNIFORMMATRIX3X2DVPROC glad_glUniformMatrix3x2dv; | 2113 | PFNGLUNIFORMMATRIX4DVPROC glad_glUniformMatrix4dv = NULL; |
| 2113 | PFNGLUNIFORMMATRIX3X4DVPROC glad_glUniformMatrix3x4dv; | 2114 | PFNGLUNIFORMMATRIX2X3DVPROC glad_glUniformMatrix2x3dv = NULL; |
| 2114 | PFNGLUNIFORMMATRIX4X2DVPROC glad_glUniformMatrix4x2dv; | 2115 | PFNGLUNIFORMMATRIX2X4DVPROC glad_glUniformMatrix2x4dv = NULL; |
| 2115 | PFNGLUNIFORMMATRIX4X3DVPROC glad_glUniformMatrix4x3dv; | 2116 | PFNGLUNIFORMMATRIX3X2DVPROC glad_glUniformMatrix3x2dv = NULL; |
| 2116 | PFNGLGETUNIFORMDVPROC glad_glGetUniformdv; | 2117 | PFNGLUNIFORMMATRIX3X4DVPROC glad_glUniformMatrix3x4dv = NULL; |
| 2117 | PFNGLUNIFORM1I64ARBPROC glad_glUniform1i64ARB; | 2118 | PFNGLUNIFORMMATRIX4X2DVPROC glad_glUniformMatrix4x2dv = NULL; |
| 2118 | PFNGLUNIFORM2I64ARBPROC glad_glUniform2i64ARB; | 2119 | PFNGLUNIFORMMATRIX4X3DVPROC glad_glUniformMatrix4x3dv = NULL; |
| 2119 | PFNGLUNIFORM3I64ARBPROC glad_glUniform3i64ARB; | 2120 | PFNGLGETUNIFORMDVPROC glad_glGetUniformdv = NULL; |
| 2120 | PFNGLUNIFORM4I64ARBPROC glad_glUniform4i64ARB; | 2121 | PFNGLUNIFORM1I64ARBPROC glad_glUniform1i64ARB = NULL; |
| 2121 | PFNGLUNIFORM1I64VARBPROC glad_glUniform1i64vARB; | 2122 | PFNGLUNIFORM2I64ARBPROC glad_glUniform2i64ARB = NULL; |
| 2122 | PFNGLUNIFORM2I64VARBPROC glad_glUniform2i64vARB; | 2123 | PFNGLUNIFORM3I64ARBPROC glad_glUniform3i64ARB = NULL; |
| 2123 | PFNGLUNIFORM3I64VARBPROC glad_glUniform3i64vARB; | 2124 | PFNGLUNIFORM4I64ARBPROC glad_glUniform4i64ARB = NULL; |
| 2124 | PFNGLUNIFORM4I64VARBPROC glad_glUniform4i64vARB; | 2125 | PFNGLUNIFORM1I64VARBPROC glad_glUniform1i64vARB = NULL; |
| 2125 | PFNGLUNIFORM1UI64ARBPROC glad_glUniform1ui64ARB; | 2126 | PFNGLUNIFORM2I64VARBPROC glad_glUniform2i64vARB = NULL; |
| 2126 | PFNGLUNIFORM2UI64ARBPROC glad_glUniform2ui64ARB; | 2127 | PFNGLUNIFORM3I64VARBPROC glad_glUniform3i64vARB = NULL; |
| 2127 | PFNGLUNIFORM3UI64ARBPROC glad_glUniform3ui64ARB; | 2128 | PFNGLUNIFORM4I64VARBPROC glad_glUniform4i64vARB = NULL; |
| 2128 | PFNGLUNIFORM4UI64ARBPROC glad_glUniform4ui64ARB; | 2129 | PFNGLUNIFORM1UI64ARBPROC glad_glUniform1ui64ARB = NULL; |
| 2129 | PFNGLUNIFORM1UI64VARBPROC glad_glUniform1ui64vARB; | 2130 | PFNGLUNIFORM2UI64ARBPROC glad_glUniform2ui64ARB = NULL; |
| 2130 | PFNGLUNIFORM2UI64VARBPROC glad_glUniform2ui64vARB; | 2131 | PFNGLUNIFORM3UI64ARBPROC glad_glUniform3ui64ARB = NULL; |
| 2131 | PFNGLUNIFORM3UI64VARBPROC glad_glUniform3ui64vARB; | 2132 | PFNGLUNIFORM4UI64ARBPROC glad_glUniform4ui64ARB = NULL; |
| 2132 | PFNGLUNIFORM4UI64VARBPROC glad_glUniform4ui64vARB; | 2133 | PFNGLUNIFORM1UI64VARBPROC glad_glUniform1ui64vARB = NULL; |
| 2133 | PFNGLGETUNIFORMI64VARBPROC glad_glGetUniformi64vARB; | 2134 | PFNGLUNIFORM2UI64VARBPROC glad_glUniform2ui64vARB = NULL; |
| 2134 | PFNGLGETUNIFORMUI64VARBPROC glad_glGetUniformui64vARB; | 2135 | PFNGLUNIFORM3UI64VARBPROC glad_glUniform3ui64vARB = NULL; |
| 2135 | PFNGLGETNUNIFORMI64VARBPROC glad_glGetnUniformi64vARB; | 2136 | PFNGLUNIFORM4UI64VARBPROC glad_glUniform4ui64vARB = NULL; |
| 2136 | PFNGLGETNUNIFORMUI64VARBPROC glad_glGetnUniformui64vARB; | 2137 | PFNGLGETUNIFORMI64VARBPROC glad_glGetUniformi64vARB = NULL; |
| 2137 | PFNGLPROGRAMUNIFORM1I64ARBPROC glad_glProgramUniform1i64ARB; | 2138 | PFNGLGETUNIFORMUI64VARBPROC glad_glGetUniformui64vARB = NULL; |
| 2138 | PFNGLPROGRAMUNIFORM2I64ARBPROC glad_glProgramUniform2i64ARB; | 2139 | PFNGLGETNUNIFORMI64VARBPROC glad_glGetnUniformi64vARB = NULL; |
| 2139 | PFNGLPROGRAMUNIFORM3I64ARBPROC glad_glProgramUniform3i64ARB; | 2140 | PFNGLGETNUNIFORMUI64VARBPROC glad_glGetnUniformui64vARB = NULL; |
| 2140 | PFNGLPROGRAMUNIFORM4I64ARBPROC glad_glProgramUniform4i64ARB; | 2141 | PFNGLPROGRAMUNIFORM1I64ARBPROC glad_glProgramUniform1i64ARB = NULL; |
| 2141 | PFNGLPROGRAMUNIFORM1I64VARBPROC glad_glProgramUniform1i64vARB; | 2142 | PFNGLPROGRAMUNIFORM2I64ARBPROC glad_glProgramUniform2i64ARB = NULL; |
| 2142 | PFNGLPROGRAMUNIFORM2I64VARBPROC glad_glProgramUniform2i64vARB; | 2143 | PFNGLPROGRAMUNIFORM3I64ARBPROC glad_glProgramUniform3i64ARB = NULL; |
| 2143 | PFNGLPROGRAMUNIFORM3I64VARBPROC glad_glProgramUniform3i64vARB; | 2144 | PFNGLPROGRAMUNIFORM4I64ARBPROC glad_glProgramUniform4i64ARB = NULL; |
| 2144 | PFNGLPROGRAMUNIFORM4I64VARBPROC glad_glProgramUniform4i64vARB; | 2145 | PFNGLPROGRAMUNIFORM1I64VARBPROC glad_glProgramUniform1i64vARB = NULL; |
| 2145 | PFNGLPROGRAMUNIFORM1UI64ARBPROC glad_glProgramUniform1ui64ARB; | 2146 | PFNGLPROGRAMUNIFORM2I64VARBPROC glad_glProgramUniform2i64vARB = NULL; |
| 2146 | PFNGLPROGRAMUNIFORM2UI64ARBPROC glad_glProgramUniform2ui64ARB; | 2147 | PFNGLPROGRAMUNIFORM3I64VARBPROC glad_glProgramUniform3i64vARB = NULL; |
| 2147 | PFNGLPROGRAMUNIFORM3UI64ARBPROC glad_glProgramUniform3ui64ARB; | 2148 | PFNGLPROGRAMUNIFORM4I64VARBPROC glad_glProgramUniform4i64vARB = NULL; |
| 2148 | PFNGLPROGRAMUNIFORM4UI64ARBPROC glad_glProgramUniform4ui64ARB; | 2149 | PFNGLPROGRAMUNIFORM1UI64ARBPROC glad_glProgramUniform1ui64ARB = NULL; |
| 2149 | PFNGLPROGRAMUNIFORM1UI64VARBPROC glad_glProgramUniform1ui64vARB; | 2150 | PFNGLPROGRAMUNIFORM2UI64ARBPROC glad_glProgramUniform2ui64ARB = NULL; |
| 2150 | PFNGLPROGRAMUNIFORM2UI64VARBPROC glad_glProgramUniform2ui64vARB; | 2151 | PFNGLPROGRAMUNIFORM3UI64ARBPROC glad_glProgramUniform3ui64ARB = NULL; |
| 2151 | PFNGLPROGRAMUNIFORM3UI64VARBPROC glad_glProgramUniform3ui64vARB; | 2152 | PFNGLPROGRAMUNIFORM4UI64ARBPROC glad_glProgramUniform4ui64ARB = NULL; |
| 2152 | PFNGLPROGRAMUNIFORM4UI64VARBPROC glad_glProgramUniform4ui64vARB; | 2153 | PFNGLPROGRAMUNIFORM1UI64VARBPROC glad_glProgramUniform1ui64vARB = NULL; |
| 2153 | PFNGLCOLORTABLEPROC glad_glColorTable; | 2154 | PFNGLPROGRAMUNIFORM2UI64VARBPROC glad_glProgramUniform2ui64vARB = NULL; |
| 2154 | PFNGLCOLORTABLEPARAMETERFVPROC glad_glColorTableParameterfv; | 2155 | PFNGLPROGRAMUNIFORM3UI64VARBPROC glad_glProgramUniform3ui64vARB = NULL; |
| 2155 | PFNGLCOLORTABLEPARAMETERIVPROC glad_glColorTableParameteriv; | 2156 | PFNGLPROGRAMUNIFORM4UI64VARBPROC glad_glProgramUniform4ui64vARB = NULL; |
| 2156 | PFNGLCOPYCOLORTABLEPROC glad_glCopyColorTable; | 2157 | PFNGLCOLORTABLEPROC glad_glColorTable = NULL; |
| 2157 | PFNGLGETCOLORTABLEPROC glad_glGetColorTable; | 2158 | PFNGLCOLORTABLEPARAMETERFVPROC glad_glColorTableParameterfv = NULL; |
| 2158 | PFNGLGETCOLORTABLEPARAMETERFVPROC glad_glGetColorTableParameterfv; | 2159 | PFNGLCOLORTABLEPARAMETERIVPROC glad_glColorTableParameteriv = NULL; |
| 2159 | PFNGLGETCOLORTABLEPARAMETERIVPROC glad_glGetColorTableParameteriv; | 2160 | PFNGLCOPYCOLORTABLEPROC glad_glCopyColorTable = NULL; |
| 2160 | PFNGLCOLORSUBTABLEPROC glad_glColorSubTable; | 2161 | PFNGLGETCOLORTABLEPROC glad_glGetColorTable = NULL; |
| 2161 | PFNGLCOPYCOLORSUBTABLEPROC glad_glCopyColorSubTable; | 2162 | PFNGLGETCOLORTABLEPARAMETERFVPROC glad_glGetColorTableParameterfv = NULL; |
| 2162 | PFNGLCONVOLUTIONFILTER1DPROC glad_glConvolutionFilter1D; | 2163 | PFNGLGETCOLORTABLEPARAMETERIVPROC glad_glGetColorTableParameteriv = NULL; |
| 2163 | PFNGLCONVOLUTIONFILTER2DPROC glad_glConvolutionFilter2D; | 2164 | PFNGLCOLORSUBTABLEPROC glad_glColorSubTable = NULL; |
| 2164 | PFNGLCONVOLUTIONPARAMETERFPROC glad_glConvolutionParameterf; | 2165 | PFNGLCOPYCOLORSUBTABLEPROC glad_glCopyColorSubTable = NULL; |
| 2165 | PFNGLCONVOLUTIONPARAMETERFVPROC glad_glConvolutionParameterfv; | 2166 | PFNGLCONVOLUTIONFILTER1DPROC glad_glConvolutionFilter1D = NULL; |
| 2166 | PFNGLCONVOLUTIONPARAMETERIPROC glad_glConvolutionParameteri; | 2167 | PFNGLCONVOLUTIONFILTER2DPROC glad_glConvolutionFilter2D = NULL; |
| 2167 | PFNGLCONVOLUTIONPARAMETERIVPROC glad_glConvolutionParameteriv; | 2168 | PFNGLCONVOLUTIONPARAMETERFPROC glad_glConvolutionParameterf = NULL; |
| 2168 | PFNGLCOPYCONVOLUTIONFILTER1DPROC glad_glCopyConvolutionFilter1D; | 2169 | PFNGLCONVOLUTIONPARAMETERFVPROC glad_glConvolutionParameterfv = NULL; |
| 2169 | PFNGLCOPYCONVOLUTIONFILTER2DPROC glad_glCopyConvolutionFilter2D; | 2170 | PFNGLCONVOLUTIONPARAMETERIPROC glad_glConvolutionParameteri = NULL; |
| 2170 | PFNGLGETCONVOLUTIONFILTERPROC glad_glGetConvolutionFilter; | 2171 | PFNGLCONVOLUTIONPARAMETERIVPROC glad_glConvolutionParameteriv = NULL; |
| 2171 | PFNGLGETCONVOLUTIONPARAMETERFVPROC glad_glGetConvolutionParameterfv; | 2172 | PFNGLCOPYCONVOLUTIONFILTER1DPROC glad_glCopyConvolutionFilter1D = NULL; |
| 2172 | PFNGLGETCONVOLUTIONPARAMETERIVPROC glad_glGetConvolutionParameteriv; | 2173 | PFNGLCOPYCONVOLUTIONFILTER2DPROC glad_glCopyConvolutionFilter2D = NULL; |
| 2173 | PFNGLGETSEPARABLEFILTERPROC glad_glGetSeparableFilter; | 2174 | PFNGLGETCONVOLUTIONFILTERPROC glad_glGetConvolutionFilter = NULL; |
| 2174 | PFNGLSEPARABLEFILTER2DPROC glad_glSeparableFilter2D; | 2175 | PFNGLGETCONVOLUTIONPARAMETERFVPROC glad_glGetConvolutionParameterfv = NULL; |
| 2175 | PFNGLGETHISTOGRAMPROC glad_glGetHistogram; | 2176 | PFNGLGETCONVOLUTIONPARAMETERIVPROC glad_glGetConvolutionParameteriv = NULL; |
| 2176 | PFNGLGETHISTOGRAMPARAMETERFVPROC glad_glGetHistogramParameterfv; | 2177 | PFNGLGETSEPARABLEFILTERPROC glad_glGetSeparableFilter = NULL; |
| 2177 | PFNGLGETHISTOGRAMPARAMETERIVPROC glad_glGetHistogramParameteriv; | 2178 | PFNGLSEPARABLEFILTER2DPROC glad_glSeparableFilter2D = NULL; |
| 2178 | PFNGLGETMINMAXPROC glad_glGetMinmax; | 2179 | PFNGLGETHISTOGRAMPROC glad_glGetHistogram = NULL; |
| 2179 | PFNGLGETMINMAXPARAMETERFVPROC glad_glGetMinmaxParameterfv; | 2180 | PFNGLGETHISTOGRAMPARAMETERFVPROC glad_glGetHistogramParameterfv = NULL; |
| 2180 | PFNGLGETMINMAXPARAMETERIVPROC glad_glGetMinmaxParameteriv; | 2181 | PFNGLGETHISTOGRAMPARAMETERIVPROC glad_glGetHistogramParameteriv = NULL; |
| 2181 | PFNGLHISTOGRAMPROC glad_glHistogram; | 2182 | PFNGLGETMINMAXPROC glad_glGetMinmax = NULL; |
| 2182 | PFNGLMINMAXPROC glad_glMinmax; | 2183 | PFNGLGETMINMAXPARAMETERFVPROC glad_glGetMinmaxParameterfv = NULL; |
| 2183 | PFNGLRESETHISTOGRAMPROC glad_glResetHistogram; | 2184 | PFNGLGETMINMAXPARAMETERIVPROC glad_glGetMinmaxParameteriv = NULL; |
| 2184 | PFNGLRESETMINMAXPROC glad_glResetMinmax; | 2185 | PFNGLHISTOGRAMPROC glad_glHistogram = NULL; |
| 2185 | PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC glad_glMultiDrawArraysIndirectCountARB; | 2186 | PFNGLMINMAXPROC glad_glMinmax = NULL; |
| 2186 | PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC glad_glMultiDrawElementsIndirectCountARB; | 2187 | PFNGLRESETHISTOGRAMPROC glad_glResetHistogram = NULL; |
| 2187 | PFNGLVERTEXATTRIBDIVISORARBPROC glad_glVertexAttribDivisorARB; | 2188 | PFNGLRESETMINMAXPROC glad_glResetMinmax = NULL; |
| 2188 | PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ; | 2189 | PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC glad_glMultiDrawArraysIndirectCountARB = NULL; |
| 2189 | PFNGLGETINTERNALFORMATI64VPROC glad_glGetInternalformati64v; | 2190 | PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC glad_glMultiDrawElementsIndirectCountARB = NULL; |
| 2190 | PFNGLINVALIDATETEXSUBIMAGEPROC glad_glInvalidateTexSubImage; | 2191 | PFNGLVERTEXATTRIBDIVISORARBPROC glad_glVertexAttribDivisorARB = NULL; |
| 2191 | PFNGLINVALIDATETEXIMAGEPROC glad_glInvalidateTexImage; | 2192 | PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ = NULL; |
| 2192 | PFNGLINVALIDATEBUFFERSUBDATAPROC glad_glInvalidateBufferSubData; | 2193 | PFNGLGETINTERNALFORMATI64VPROC glad_glGetInternalformati64v = NULL; |
| 2193 | PFNGLINVALIDATEBUFFERDATAPROC glad_glInvalidateBufferData; | 2194 | PFNGLINVALIDATETEXSUBIMAGEPROC glad_glInvalidateTexSubImage = NULL; |
| 2194 | PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer; | 2195 | PFNGLINVALIDATETEXIMAGEPROC glad_glInvalidateTexImage = NULL; |
| 2195 | PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer; | 2196 | PFNGLINVALIDATEBUFFERSUBDATAPROC glad_glInvalidateBufferSubData = NULL; |
| 2196 | PFNGLCURRENTPALETTEMATRIXARBPROC glad_glCurrentPaletteMatrixARB; | 2197 | PFNGLINVALIDATEBUFFERDATAPROC glad_glInvalidateBufferData = NULL; |
| 2197 | PFNGLMATRIXINDEXUBVARBPROC glad_glMatrixIndexubvARB; | 2198 | PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer = NULL; |
| 2198 | PFNGLMATRIXINDEXUSVARBPROC glad_glMatrixIndexusvARB; | 2199 | PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer = NULL; |
| 2199 | PFNGLMATRIXINDEXUIVARBPROC glad_glMatrixIndexuivARB; | 2200 | PFNGLCURRENTPALETTEMATRIXARBPROC glad_glCurrentPaletteMatrixARB = NULL; |
| 2200 | PFNGLMATRIXINDEXPOINTERARBPROC glad_glMatrixIndexPointerARB; | 2201 | PFNGLMATRIXINDEXUBVARBPROC glad_glMatrixIndexubvARB = NULL; |
| 2201 | PFNGLBINDBUFFERSBASEPROC glad_glBindBuffersBase; | 2202 | PFNGLMATRIXINDEXUSVARBPROC glad_glMatrixIndexusvARB = NULL; |
| 2202 | PFNGLBINDBUFFERSRANGEPROC glad_glBindBuffersRange; | 2203 | PFNGLMATRIXINDEXUIVARBPROC glad_glMatrixIndexuivARB = NULL; |
| 2203 | PFNGLBINDTEXTURESPROC glad_glBindTextures; | 2204 | PFNGLMATRIXINDEXPOINTERARBPROC glad_glMatrixIndexPointerARB = NULL; |
| 2204 | PFNGLBINDSAMPLERSPROC glad_glBindSamplers; | 2205 | PFNGLBINDBUFFERSBASEPROC glad_glBindBuffersBase = NULL; |
| 2205 | PFNGLBINDIMAGETEXTURESPROC glad_glBindImageTextures; | 2206 | PFNGLBINDBUFFERSRANGEPROC glad_glBindBuffersRange = NULL; |
| 2206 | PFNGLBINDVERTEXBUFFERSPROC glad_glBindVertexBuffers; | 2207 | PFNGLBINDTEXTURESPROC glad_glBindTextures = NULL; |
| 2207 | PFNGLMULTIDRAWARRAYSINDIRECTPROC glad_glMultiDrawArraysIndirect; | 2208 | PFNGLBINDSAMPLERSPROC glad_glBindSamplers = NULL; |
| 2208 | PFNGLMULTIDRAWELEMENTSINDIRECTPROC glad_glMultiDrawElementsIndirect; | 2209 | PFNGLBINDIMAGETEXTURESPROC glad_glBindImageTextures = NULL; |
| 2209 | PFNGLSAMPLECOVERAGEARBPROC glad_glSampleCoverageARB; | 2210 | PFNGLBINDVERTEXBUFFERSPROC glad_glBindVertexBuffers = NULL; |
| 2210 | PFNGLACTIVETEXTUREARBPROC glad_glActiveTextureARB; | 2211 | PFNGLMULTIDRAWARRAYSINDIRECTPROC glad_glMultiDrawArraysIndirect = NULL; |
| 2211 | PFNGLCLIENTACTIVETEXTUREARBPROC glad_glClientActiveTextureARB; | 2212 | PFNGLMULTIDRAWELEMENTSINDIRECTPROC glad_glMultiDrawElementsIndirect = NULL; |
| 2212 | PFNGLMULTITEXCOORD1DARBPROC glad_glMultiTexCoord1dARB; | 2213 | PFNGLSAMPLECOVERAGEARBPROC glad_glSampleCoverageARB = NULL; |
| 2213 | PFNGLMULTITEXCOORD1DVARBPROC glad_glMultiTexCoord1dvARB; | 2214 | PFNGLACTIVETEXTUREARBPROC glad_glActiveTextureARB = NULL; |
| 2214 | PFNGLMULTITEXCOORD1FARBPROC glad_glMultiTexCoord1fARB; | 2215 | PFNGLCLIENTACTIVETEXTUREARBPROC glad_glClientActiveTextureARB = NULL; |
| 2215 | PFNGLMULTITEXCOORD1FVARBPROC glad_glMultiTexCoord1fvARB; | 2216 | PFNGLMULTITEXCOORD1DARBPROC glad_glMultiTexCoord1dARB = NULL; |
| 2216 | PFNGLMULTITEXCOORD1IARBPROC glad_glMultiTexCoord1iARB; | 2217 | PFNGLMULTITEXCOORD1DVARBPROC glad_glMultiTexCoord1dvARB = NULL; |
| 2217 | PFNGLMULTITEXCOORD1IVARBPROC glad_glMultiTexCoord1ivARB; | 2218 | PFNGLMULTITEXCOORD1FARBPROC glad_glMultiTexCoord1fARB = NULL; |
| 2218 | PFNGLMULTITEXCOORD1SARBPROC glad_glMultiTexCoord1sARB; | 2219 | PFNGLMULTITEXCOORD1FVARBPROC glad_glMultiTexCoord1fvARB = NULL; |
| 2219 | PFNGLMULTITEXCOORD1SVARBPROC glad_glMultiTexCoord1svARB; | 2220 | PFNGLMULTITEXCOORD1IARBPROC glad_glMultiTexCoord1iARB = NULL; |
| 2220 | PFNGLMULTITEXCOORD2DARBPROC glad_glMultiTexCoord2dARB; | 2221 | PFNGLMULTITEXCOORD1IVARBPROC glad_glMultiTexCoord1ivARB = NULL; |
| 2221 | PFNGLMULTITEXCOORD2DVARBPROC glad_glMultiTexCoord2dvARB; | 2222 | PFNGLMULTITEXCOORD1SARBPROC glad_glMultiTexCoord1sARB = NULL; |
| 2222 | PFNGLMULTITEXCOORD2FARBPROC glad_glMultiTexCoord2fARB; | 2223 | PFNGLMULTITEXCOORD1SVARBPROC glad_glMultiTexCoord1svARB = NULL; |
| 2223 | PFNGLMULTITEXCOORD2FVARBPROC glad_glMultiTexCoord2fvARB; | 2224 | PFNGLMULTITEXCOORD2DARBPROC glad_glMultiTexCoord2dARB = NULL; |
| 2224 | PFNGLMULTITEXCOORD2IARBPROC glad_glMultiTexCoord2iARB; | 2225 | PFNGLMULTITEXCOORD2DVARBPROC glad_glMultiTexCoord2dvARB = NULL; |
| 2225 | PFNGLMULTITEXCOORD2IVARBPROC glad_glMultiTexCoord2ivARB; | 2226 | PFNGLMULTITEXCOORD2FARBPROC glad_glMultiTexCoord2fARB = NULL; |
| 2226 | PFNGLMULTITEXCOORD2SARBPROC glad_glMultiTexCoord2sARB; | 2227 | PFNGLMULTITEXCOORD2FVARBPROC glad_glMultiTexCoord2fvARB = NULL; |
| 2227 | PFNGLMULTITEXCOORD2SVARBPROC glad_glMultiTexCoord2svARB; | 2228 | PFNGLMULTITEXCOORD2IARBPROC glad_glMultiTexCoord2iARB = NULL; |
| 2228 | PFNGLMULTITEXCOORD3DARBPROC glad_glMultiTexCoord3dARB; | 2229 | PFNGLMULTITEXCOORD2IVARBPROC glad_glMultiTexCoord2ivARB = NULL; |
| 2229 | PFNGLMULTITEXCOORD3DVARBPROC glad_glMultiTexCoord3dvARB; | 2230 | PFNGLMULTITEXCOORD2SARBPROC glad_glMultiTexCoord2sARB = NULL; |
| 2230 | PFNGLMULTITEXCOORD3FARBPROC glad_glMultiTexCoord3fARB; | 2231 | PFNGLMULTITEXCOORD2SVARBPROC glad_glMultiTexCoord2svARB = NULL; |
| 2231 | PFNGLMULTITEXCOORD3FVARBPROC glad_glMultiTexCoord3fvARB; | 2232 | PFNGLMULTITEXCOORD3DARBPROC glad_glMultiTexCoord3dARB = NULL; |
| 2232 | PFNGLMULTITEXCOORD3IARBPROC glad_glMultiTexCoord3iARB; | 2233 | PFNGLMULTITEXCOORD3DVARBPROC glad_glMultiTexCoord3dvARB = NULL; |
| 2233 | PFNGLMULTITEXCOORD3IVARBPROC glad_glMultiTexCoord3ivARB; | 2234 | PFNGLMULTITEXCOORD3FARBPROC glad_glMultiTexCoord3fARB = NULL; |
| 2234 | PFNGLMULTITEXCOORD3SARBPROC glad_glMultiTexCoord3sARB; | 2235 | PFNGLMULTITEXCOORD3FVARBPROC glad_glMultiTexCoord3fvARB = NULL; |
| 2235 | PFNGLMULTITEXCOORD3SVARBPROC glad_glMultiTexCoord3svARB; | 2236 | PFNGLMULTITEXCOORD3IARBPROC glad_glMultiTexCoord3iARB = NULL; |
| 2236 | PFNGLMULTITEXCOORD4DARBPROC glad_glMultiTexCoord4dARB; | 2237 | PFNGLMULTITEXCOORD3IVARBPROC glad_glMultiTexCoord3ivARB = NULL; |
| 2237 | PFNGLMULTITEXCOORD4DVARBPROC glad_glMultiTexCoord4dvARB; | 2238 | PFNGLMULTITEXCOORD3SARBPROC glad_glMultiTexCoord3sARB = NULL; |
| 2238 | PFNGLMULTITEXCOORD4FARBPROC glad_glMultiTexCoord4fARB; | 2239 | PFNGLMULTITEXCOORD3SVARBPROC glad_glMultiTexCoord3svARB = NULL; |
| 2239 | PFNGLMULTITEXCOORD4FVARBPROC glad_glMultiTexCoord4fvARB; | 2240 | PFNGLMULTITEXCOORD4DARBPROC glad_glMultiTexCoord4dARB = NULL; |
| 2240 | PFNGLMULTITEXCOORD4IARBPROC glad_glMultiTexCoord4iARB; | 2241 | PFNGLMULTITEXCOORD4DVARBPROC glad_glMultiTexCoord4dvARB = NULL; |
| 2241 | PFNGLMULTITEXCOORD4IVARBPROC glad_glMultiTexCoord4ivARB; | 2242 | PFNGLMULTITEXCOORD4FARBPROC glad_glMultiTexCoord4fARB = NULL; |
| 2242 | PFNGLMULTITEXCOORD4SARBPROC glad_glMultiTexCoord4sARB; | 2243 | PFNGLMULTITEXCOORD4FVARBPROC glad_glMultiTexCoord4fvARB = NULL; |
| 2243 | PFNGLMULTITEXCOORD4SVARBPROC glad_glMultiTexCoord4svARB; | 2244 | PFNGLMULTITEXCOORD4IARBPROC glad_glMultiTexCoord4iARB = NULL; |
| 2244 | PFNGLGENQUERIESARBPROC glad_glGenQueriesARB; | 2245 | PFNGLMULTITEXCOORD4IVARBPROC glad_glMultiTexCoord4ivARB = NULL; |
| 2245 | PFNGLDELETEQUERIESARBPROC glad_glDeleteQueriesARB; | 2246 | PFNGLMULTITEXCOORD4SARBPROC glad_glMultiTexCoord4sARB = NULL; |
| 2246 | PFNGLISQUERYARBPROC glad_glIsQueryARB; | 2247 | PFNGLMULTITEXCOORD4SVARBPROC glad_glMultiTexCoord4svARB = NULL; |
| 2247 | PFNGLBEGINQUERYARBPROC glad_glBeginQueryARB; | 2248 | PFNGLGENQUERIESARBPROC glad_glGenQueriesARB = NULL; |
| 2248 | PFNGLENDQUERYARBPROC glad_glEndQueryARB; | 2249 | PFNGLDELETEQUERIESARBPROC glad_glDeleteQueriesARB = NULL; |
| 2249 | PFNGLGETQUERYIVARBPROC glad_glGetQueryivARB; | 2250 | PFNGLISQUERYARBPROC glad_glIsQueryARB = NULL; |
| 2250 | PFNGLGETQUERYOBJECTIVARBPROC glad_glGetQueryObjectivARB; | 2251 | PFNGLBEGINQUERYARBPROC glad_glBeginQueryARB = NULL; |
| 2251 | PFNGLGETQUERYOBJECTUIVARBPROC glad_glGetQueryObjectuivARB; | 2252 | PFNGLENDQUERYARBPROC glad_glEndQueryARB = NULL; |
| 2252 | PFNGLMAXSHADERCOMPILERTHREADSARBPROC glad_glMaxShaderCompilerThreadsARB; | 2253 | PFNGLGETQUERYIVARBPROC glad_glGetQueryivARB = NULL; |
| 2253 | PFNGLPOINTPARAMETERFARBPROC glad_glPointParameterfARB; | 2254 | PFNGLGETQUERYOBJECTIVARBPROC glad_glGetQueryObjectivARB = NULL; |
| 2254 | PFNGLPOINTPARAMETERFVARBPROC glad_glPointParameterfvARB; | 2255 | PFNGLGETQUERYOBJECTUIVARBPROC glad_glGetQueryObjectuivARB = NULL; |
| 2255 | PFNGLPOLYGONOFFSETCLAMPPROC glad_glPolygonOffsetClamp; | 2256 | PFNGLMAXSHADERCOMPILERTHREADSARBPROC glad_glMaxShaderCompilerThreadsARB = NULL; |
| 2256 | PFNGLGETPROGRAMINTERFACEIVPROC glad_glGetProgramInterfaceiv; | 2257 | PFNGLPOINTPARAMETERFARBPROC glad_glPointParameterfARB = NULL; |
| 2257 | PFNGLGETPROGRAMRESOURCEINDEXPROC glad_glGetProgramResourceIndex; | 2258 | PFNGLPOINTPARAMETERFVARBPROC glad_glPointParameterfvARB = NULL; |
| 2258 | PFNGLGETPROGRAMRESOURCENAMEPROC glad_glGetProgramResourceName; | 2259 | PFNGLPOLYGONOFFSETCLAMPPROC glad_glPolygonOffsetClamp = NULL; |
| 2259 | PFNGLGETPROGRAMRESOURCEIVPROC glad_glGetProgramResourceiv; | 2260 | PFNGLGETPROGRAMINTERFACEIVPROC glad_glGetProgramInterfaceiv = NULL; |
| 2260 | PFNGLGETPROGRAMRESOURCELOCATIONPROC glad_glGetProgramResourceLocation; | 2261 | PFNGLGETPROGRAMRESOURCEINDEXPROC glad_glGetProgramResourceIndex = NULL; |
| 2261 | PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC glad_glGetProgramResourceLocationIndex; | 2262 | PFNGLGETPROGRAMRESOURCENAMEPROC glad_glGetProgramResourceName = NULL; |
| 2262 | PFNGLGETGRAPHICSRESETSTATUSARBPROC glad_glGetGraphicsResetStatusARB; | 2263 | PFNGLGETPROGRAMRESOURCEIVPROC glad_glGetProgramResourceiv = NULL; |
| 2263 | PFNGLGETNTEXIMAGEARBPROC glad_glGetnTexImageARB; | 2264 | PFNGLGETPROGRAMRESOURCELOCATIONPROC glad_glGetProgramResourceLocation = NULL; |
| 2264 | PFNGLREADNPIXELSARBPROC glad_glReadnPixelsARB; | 2265 | PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC glad_glGetProgramResourceLocationIndex = NULL; |
| 2265 | PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC glad_glGetnCompressedTexImageARB; | 2266 | PFNGLGETGRAPHICSRESETSTATUSARBPROC glad_glGetGraphicsResetStatusARB = NULL; |
| 2266 | PFNGLGETNUNIFORMFVARBPROC glad_glGetnUniformfvARB; | 2267 | PFNGLGETNTEXIMAGEARBPROC glad_glGetnTexImageARB = NULL; |
| 2267 | PFNGLGETNUNIFORMIVARBPROC glad_glGetnUniformivARB; | 2268 | PFNGLREADNPIXELSARBPROC glad_glReadnPixelsARB = NULL; |
| 2268 | PFNGLGETNUNIFORMUIVARBPROC glad_glGetnUniformuivARB; | 2269 | PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC glad_glGetnCompressedTexImageARB = NULL; |
| 2269 | PFNGLGETNUNIFORMDVARBPROC glad_glGetnUniformdvARB; | 2270 | PFNGLGETNUNIFORMFVARBPROC glad_glGetnUniformfvARB = NULL; |
| 2270 | PFNGLGETNMAPDVARBPROC glad_glGetnMapdvARB; | 2271 | PFNGLGETNUNIFORMIVARBPROC glad_glGetnUniformivARB = NULL; |
| 2271 | PFNGLGETNMAPFVARBPROC glad_glGetnMapfvARB; | 2272 | PFNGLGETNUNIFORMUIVARBPROC glad_glGetnUniformuivARB = NULL; |
| 2272 | PFNGLGETNMAPIVARBPROC glad_glGetnMapivARB; | 2273 | PFNGLGETNUNIFORMDVARBPROC glad_glGetnUniformdvARB = NULL; |
| 2273 | PFNGLGETNPIXELMAPFVARBPROC glad_glGetnPixelMapfvARB; | 2274 | PFNGLGETNMAPDVARBPROC glad_glGetnMapdvARB = NULL; |
| 2274 | PFNGLGETNPIXELMAPUIVARBPROC glad_glGetnPixelMapuivARB; | 2275 | PFNGLGETNMAPFVARBPROC glad_glGetnMapfvARB = NULL; |
| 2275 | PFNGLGETNPIXELMAPUSVARBPROC glad_glGetnPixelMapusvARB; | 2276 | PFNGLGETNMAPIVARBPROC glad_glGetnMapivARB = NULL; |
| 2276 | PFNGLGETNPOLYGONSTIPPLEARBPROC glad_glGetnPolygonStippleARB; | 2277 | PFNGLGETNPIXELMAPFVARBPROC glad_glGetnPixelMapfvARB = NULL; |
| 2277 | PFNGLGETNCOLORTABLEARBPROC glad_glGetnColorTableARB; | 2278 | PFNGLGETNPIXELMAPUIVARBPROC glad_glGetnPixelMapuivARB = NULL; |
| 2278 | PFNGLGETNCONVOLUTIONFILTERARBPROC glad_glGetnConvolutionFilterARB; | 2279 | PFNGLGETNPIXELMAPUSVARBPROC glad_glGetnPixelMapusvARB = NULL; |
| 2279 | PFNGLGETNSEPARABLEFILTERARBPROC glad_glGetnSeparableFilterARB; | 2280 | PFNGLGETNPOLYGONSTIPPLEARBPROC glad_glGetnPolygonStippleARB = NULL; |
| 2280 | PFNGLGETNHISTOGRAMARBPROC glad_glGetnHistogramARB; | 2281 | PFNGLGETNCOLORTABLEARBPROC glad_glGetnColorTableARB = NULL; |
| 2281 | PFNGLGETNMINMAXARBPROC glad_glGetnMinmaxARB; | 2282 | PFNGLGETNCONVOLUTIONFILTERARBPROC glad_glGetnConvolutionFilterARB = NULL; |
| 2282 | PFNGLFRAMEBUFFERSAMPLELOCATIONSFVARBPROC glad_glFramebufferSampleLocationsfvARB; | 2283 | PFNGLGETNSEPARABLEFILTERARBPROC glad_glGetnSeparableFilterARB = NULL; |
| 2283 | PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVARBPROC glad_glNamedFramebufferSampleLocationsfvARB; | 2284 | PFNGLGETNHISTOGRAMARBPROC glad_glGetnHistogramARB = NULL; |
| 2284 | PFNGLEVALUATEDEPTHVALUESARBPROC glad_glEvaluateDepthValuesARB; | 2285 | PFNGLGETNMINMAXARBPROC glad_glGetnMinmaxARB = NULL; |
| 2285 | PFNGLMINSAMPLESHADINGARBPROC glad_glMinSampleShadingARB; | 2286 | PFNGLFRAMEBUFFERSAMPLELOCATIONSFVARBPROC glad_glFramebufferSampleLocationsfvARB = NULL; |
| 2286 | PFNGLUSEPROGRAMSTAGESPROC glad_glUseProgramStages; | 2287 | PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVARBPROC glad_glNamedFramebufferSampleLocationsfvARB = NULL; |
| 2287 | PFNGLACTIVESHADERPROGRAMPROC glad_glActiveShaderProgram; | 2288 | PFNGLEVALUATEDEPTHVALUESARBPROC glad_glEvaluateDepthValuesARB = NULL; |
| 2288 | PFNGLCREATESHADERPROGRAMVPROC glad_glCreateShaderProgramv; | 2289 | PFNGLMINSAMPLESHADINGARBPROC glad_glMinSampleShadingARB = NULL; |
| 2289 | PFNGLBINDPROGRAMPIPELINEPROC glad_glBindProgramPipeline; | 2290 | PFNGLUSEPROGRAMSTAGESPROC glad_glUseProgramStages = NULL; |
| 2290 | PFNGLDELETEPROGRAMPIPELINESPROC glad_glDeleteProgramPipelines; | 2291 | PFNGLACTIVESHADERPROGRAMPROC glad_glActiveShaderProgram = NULL; |
| 2291 | PFNGLGENPROGRAMPIPELINESPROC glad_glGenProgramPipelines; | 2292 | PFNGLCREATESHADERPROGRAMVPROC glad_glCreateShaderProgramv = NULL; |
| 2292 | PFNGLISPROGRAMPIPELINEPROC glad_glIsProgramPipeline; | 2293 | PFNGLBINDPROGRAMPIPELINEPROC glad_glBindProgramPipeline = NULL; |
| 2293 | PFNGLGETPROGRAMPIPELINEIVPROC glad_glGetProgramPipelineiv; | 2294 | PFNGLDELETEPROGRAMPIPELINESPROC glad_glDeleteProgramPipelines = NULL; |
| 2294 | PFNGLPROGRAMUNIFORM1IPROC glad_glProgramUniform1i; | 2295 | PFNGLGENPROGRAMPIPELINESPROC glad_glGenProgramPipelines = NULL; |
| 2295 | PFNGLPROGRAMUNIFORM1IVPROC glad_glProgramUniform1iv; | 2296 | PFNGLISPROGRAMPIPELINEPROC glad_glIsProgramPipeline = NULL; |
| 2296 | PFNGLPROGRAMUNIFORM1FPROC glad_glProgramUniform1f; | 2297 | PFNGLGETPROGRAMPIPELINEIVPROC glad_glGetProgramPipelineiv = NULL; |
| 2297 | PFNGLPROGRAMUNIFORM1FVPROC glad_glProgramUniform1fv; | 2298 | PFNGLPROGRAMUNIFORM1IPROC glad_glProgramUniform1i = NULL; |
| 2298 | PFNGLPROGRAMUNIFORM1DPROC glad_glProgramUniform1d; | 2299 | PFNGLPROGRAMUNIFORM1IVPROC glad_glProgramUniform1iv = NULL; |
| 2299 | PFNGLPROGRAMUNIFORM1DVPROC glad_glProgramUniform1dv; | 2300 | PFNGLPROGRAMUNIFORM1FPROC glad_glProgramUniform1f = NULL; |
| 2300 | PFNGLPROGRAMUNIFORM1UIPROC glad_glProgramUniform1ui; | 2301 | PFNGLPROGRAMUNIFORM1FVPROC glad_glProgramUniform1fv = NULL; |
| 2301 | PFNGLPROGRAMUNIFORM1UIVPROC glad_glProgramUniform1uiv; | 2302 | PFNGLPROGRAMUNIFORM1DPROC glad_glProgramUniform1d = NULL; |
| 2302 | PFNGLPROGRAMUNIFORM2IPROC glad_glProgramUniform2i; | 2303 | PFNGLPROGRAMUNIFORM1DVPROC glad_glProgramUniform1dv = NULL; |
| 2303 | PFNGLPROGRAMUNIFORM2IVPROC glad_glProgramUniform2iv; | 2304 | PFNGLPROGRAMUNIFORM1UIPROC glad_glProgramUniform1ui = NULL; |
| 2304 | PFNGLPROGRAMUNIFORM2FPROC glad_glProgramUniform2f; | 2305 | PFNGLPROGRAMUNIFORM1UIVPROC glad_glProgramUniform1uiv = NULL; |
| 2305 | PFNGLPROGRAMUNIFORM2FVPROC glad_glProgramUniform2fv; | 2306 | PFNGLPROGRAMUNIFORM2IPROC glad_glProgramUniform2i = NULL; |
| 2306 | PFNGLPROGRAMUNIFORM2DPROC glad_glProgramUniform2d; | 2307 | PFNGLPROGRAMUNIFORM2IVPROC glad_glProgramUniform2iv = NULL; |
| 2307 | PFNGLPROGRAMUNIFORM2DVPROC glad_glProgramUniform2dv; | 2308 | PFNGLPROGRAMUNIFORM2FPROC glad_glProgramUniform2f = NULL; |
| 2308 | PFNGLPROGRAMUNIFORM2UIPROC glad_glProgramUniform2ui; | 2309 | PFNGLPROGRAMUNIFORM2FVPROC glad_glProgramUniform2fv = NULL; |
| 2309 | PFNGLPROGRAMUNIFORM2UIVPROC glad_glProgramUniform2uiv; | 2310 | PFNGLPROGRAMUNIFORM2DPROC glad_glProgramUniform2d = NULL; |
| 2310 | PFNGLPROGRAMUNIFORM3IPROC glad_glProgramUniform3i; | 2311 | PFNGLPROGRAMUNIFORM2DVPROC glad_glProgramUniform2dv = NULL; |
| 2311 | PFNGLPROGRAMUNIFORM3IVPROC glad_glProgramUniform3iv; | 2312 | PFNGLPROGRAMUNIFORM2UIPROC glad_glProgramUniform2ui = NULL; |
| 2312 | PFNGLPROGRAMUNIFORM3FPROC glad_glProgramUniform3f; | 2313 | PFNGLPROGRAMUNIFORM2UIVPROC glad_glProgramUniform2uiv = NULL; |
| 2313 | PFNGLPROGRAMUNIFORM3FVPROC glad_glProgramUniform3fv; | 2314 | PFNGLPROGRAMUNIFORM3IPROC glad_glProgramUniform3i = NULL; |
| 2314 | PFNGLPROGRAMUNIFORM3DPROC glad_glProgramUniform3d; | 2315 | PFNGLPROGRAMUNIFORM3IVPROC glad_glProgramUniform3iv = NULL; |
| 2315 | PFNGLPROGRAMUNIFORM3DVPROC glad_glProgramUniform3dv; | 2316 | PFNGLPROGRAMUNIFORM3FPROC glad_glProgramUniform3f = NULL; |
| 2316 | PFNGLPROGRAMUNIFORM3UIPROC glad_glProgramUniform3ui; | 2317 | PFNGLPROGRAMUNIFORM3FVPROC glad_glProgramUniform3fv = NULL; |
| 2317 | PFNGLPROGRAMUNIFORM3UIVPROC glad_glProgramUniform3uiv; | 2318 | PFNGLPROGRAMUNIFORM3DPROC glad_glProgramUniform3d = NULL; |
| 2318 | PFNGLPROGRAMUNIFORM4IPROC glad_glProgramUniform4i; | 2319 | PFNGLPROGRAMUNIFORM3DVPROC glad_glProgramUniform3dv = NULL; |
| 2319 | PFNGLPROGRAMUNIFORM4IVPROC glad_glProgramUniform4iv; | 2320 | PFNGLPROGRAMUNIFORM3UIPROC glad_glProgramUniform3ui = NULL; |
| 2320 | PFNGLPROGRAMUNIFORM4FPROC glad_glProgramUniform4f; | 2321 | PFNGLPROGRAMUNIFORM3UIVPROC glad_glProgramUniform3uiv = NULL; |
| 2321 | PFNGLPROGRAMUNIFORM4FVPROC glad_glProgramUniform4fv; | 2322 | PFNGLPROGRAMUNIFORM4IPROC glad_glProgramUniform4i = NULL; |
| 2322 | PFNGLPROGRAMUNIFORM4DPROC glad_glProgramUniform4d; | 2323 | PFNGLPROGRAMUNIFORM4IVPROC glad_glProgramUniform4iv = NULL; |
| 2323 | PFNGLPROGRAMUNIFORM4DVPROC glad_glProgramUniform4dv; | 2324 | PFNGLPROGRAMUNIFORM4FPROC glad_glProgramUniform4f = NULL; |
| 2324 | PFNGLPROGRAMUNIFORM4UIPROC glad_glProgramUniform4ui; | 2325 | PFNGLPROGRAMUNIFORM4FVPROC glad_glProgramUniform4fv = NULL; |
| 2325 | PFNGLPROGRAMUNIFORM4UIVPROC glad_glProgramUniform4uiv; | 2326 | PFNGLPROGRAMUNIFORM4DPROC glad_glProgramUniform4d = NULL; |
| 2326 | PFNGLPROGRAMUNIFORMMATRIX2FVPROC glad_glProgramUniformMatrix2fv; | 2327 | PFNGLPROGRAMUNIFORM4DVPROC glad_glProgramUniform4dv = NULL; |
| 2327 | PFNGLPROGRAMUNIFORMMATRIX3FVPROC glad_glProgramUniformMatrix3fv; | 2328 | PFNGLPROGRAMUNIFORM4UIPROC glad_glProgramUniform4ui = NULL; |
| 2328 | PFNGLPROGRAMUNIFORMMATRIX4FVPROC glad_glProgramUniformMatrix4fv; | 2329 | PFNGLPROGRAMUNIFORM4UIVPROC glad_glProgramUniform4uiv = NULL; |
| 2329 | PFNGLPROGRAMUNIFORMMATRIX2DVPROC glad_glProgramUniformMatrix2dv; | 2330 | PFNGLPROGRAMUNIFORMMATRIX2FVPROC glad_glProgramUniformMatrix2fv = NULL; |
| 2330 | PFNGLPROGRAMUNIFORMMATRIX3DVPROC glad_glProgramUniformMatrix3dv; | 2331 | PFNGLPROGRAMUNIFORMMATRIX3FVPROC glad_glProgramUniformMatrix3fv = NULL; |
| 2331 | PFNGLPROGRAMUNIFORMMATRIX4DVPROC glad_glProgramUniformMatrix4dv; | 2332 | PFNGLPROGRAMUNIFORMMATRIX4FVPROC glad_glProgramUniformMatrix4fv = NULL; |
| 2332 | PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC glad_glProgramUniformMatrix2x3fv; | 2333 | PFNGLPROGRAMUNIFORMMATRIX2DVPROC glad_glProgramUniformMatrix2dv = NULL; |
| 2333 | PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC glad_glProgramUniformMatrix3x2fv; | 2334 | PFNGLPROGRAMUNIFORMMATRIX3DVPROC glad_glProgramUniformMatrix3dv = NULL; |
| 2334 | PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC glad_glProgramUniformMatrix2x4fv; | 2335 | PFNGLPROGRAMUNIFORMMATRIX4DVPROC glad_glProgramUniformMatrix4dv = NULL; |
| 2335 | PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC glad_glProgramUniformMatrix4x2fv; | 2336 | PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC glad_glProgramUniformMatrix2x3fv = NULL; |
| 2336 | PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC glad_glProgramUniformMatrix3x4fv; | 2337 | PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC glad_glProgramUniformMatrix3x2fv = NULL; |
| 2337 | PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glad_glProgramUniformMatrix4x3fv; | 2338 | PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC glad_glProgramUniformMatrix2x4fv = NULL; |
| 2338 | PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC glad_glProgramUniformMatrix2x3dv; | 2339 | PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC glad_glProgramUniformMatrix4x2fv = NULL; |
| 2339 | PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC glad_glProgramUniformMatrix3x2dv; | 2340 | PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC glad_glProgramUniformMatrix3x4fv = NULL; |
| 2340 | PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC glad_glProgramUniformMatrix2x4dv; | 2341 | PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glad_glProgramUniformMatrix4x3fv = NULL; |
| 2341 | PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC glad_glProgramUniformMatrix4x2dv; | 2342 | PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC glad_glProgramUniformMatrix2x3dv = NULL; |
| 2342 | PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC glad_glProgramUniformMatrix3x4dv; | 2343 | PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC glad_glProgramUniformMatrix3x2dv = NULL; |
| 2343 | PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC glad_glProgramUniformMatrix4x3dv; | 2344 | PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC glad_glProgramUniformMatrix2x4dv = NULL; |
| 2344 | PFNGLVALIDATEPROGRAMPIPELINEPROC glad_glValidateProgramPipeline; | 2345 | PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC glad_glProgramUniformMatrix4x2dv = NULL; |
| 2345 | PFNGLGETPROGRAMPIPELINEINFOLOGPROC glad_glGetProgramPipelineInfoLog; | 2346 | PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC glad_glProgramUniformMatrix3x4dv = NULL; |
| 2346 | PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC glad_glGetActiveAtomicCounterBufferiv; | 2347 | PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC glad_glProgramUniformMatrix4x3dv = NULL; |
| 2347 | PFNGLBINDIMAGETEXTUREPROC glad_glBindImageTexture; | 2348 | PFNGLVALIDATEPROGRAMPIPELINEPROC glad_glValidateProgramPipeline = NULL; |
| 2348 | PFNGLMEMORYBARRIERPROC glad_glMemoryBarrier; | 2349 | PFNGLGETPROGRAMPIPELINEINFOLOGPROC glad_glGetProgramPipelineInfoLog = NULL; |
| 2349 | PFNGLDELETEOBJECTARBPROC glad_glDeleteObjectARB; | 2350 | PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC glad_glGetActiveAtomicCounterBufferiv = NULL; |
| 2350 | PFNGLGETHANDLEARBPROC glad_glGetHandleARB; | 2351 | PFNGLBINDIMAGETEXTUREPROC glad_glBindImageTexture = NULL; |
| 2351 | PFNGLDETACHOBJECTARBPROC glad_glDetachObjectARB; | 2352 | PFNGLMEMORYBARRIERPROC glad_glMemoryBarrier = NULL; |
| 2352 | PFNGLCREATESHADEROBJECTARBPROC glad_glCreateShaderObjectARB; | 2353 | PFNGLDELETEOBJECTARBPROC glad_glDeleteObjectARB = NULL; |
| 2353 | PFNGLSHADERSOURCEARBPROC glad_glShaderSourceARB; | 2354 | PFNGLGETHANDLEARBPROC glad_glGetHandleARB = NULL; |
| 2354 | PFNGLCOMPILESHADERARBPROC glad_glCompileShaderARB; | 2355 | PFNGLDETACHOBJECTARBPROC glad_glDetachObjectARB = NULL; |
| 2355 | PFNGLCREATEPROGRAMOBJECTARBPROC glad_glCreateProgramObjectARB; | 2356 | PFNGLCREATESHADEROBJECTARBPROC glad_glCreateShaderObjectARB = NULL; |
| 2356 | PFNGLATTACHOBJECTARBPROC glad_glAttachObjectARB; | 2357 | PFNGLSHADERSOURCEARBPROC glad_glShaderSourceARB = NULL; |
| 2357 | PFNGLLINKPROGRAMARBPROC glad_glLinkProgramARB; | 2358 | PFNGLCOMPILESHADERARBPROC glad_glCompileShaderARB = NULL; |
| 2358 | PFNGLUSEPROGRAMOBJECTARBPROC glad_glUseProgramObjectARB; | 2359 | PFNGLCREATEPROGRAMOBJECTARBPROC glad_glCreateProgramObjectARB = NULL; |
| 2359 | PFNGLVALIDATEPROGRAMARBPROC glad_glValidateProgramARB; | 2360 | PFNGLATTACHOBJECTARBPROC glad_glAttachObjectARB = NULL; |
| 2360 | PFNGLUNIFORM1FARBPROC glad_glUniform1fARB; | 2361 | PFNGLLINKPROGRAMARBPROC glad_glLinkProgramARB = NULL; |
| 2361 | PFNGLUNIFORM2FARBPROC glad_glUniform2fARB; | 2362 | PFNGLUSEPROGRAMOBJECTARBPROC glad_glUseProgramObjectARB = NULL; |
| 2362 | PFNGLUNIFORM3FARBPROC glad_glUniform3fARB; | 2363 | PFNGLVALIDATEPROGRAMARBPROC glad_glValidateProgramARB = NULL; |
| 2363 | PFNGLUNIFORM4FARBPROC glad_glUniform4fARB; | 2364 | PFNGLUNIFORM1FARBPROC glad_glUniform1fARB = NULL; |
| 2364 | PFNGLUNIFORM1IARBPROC glad_glUniform1iARB; | 2365 | PFNGLUNIFORM2FARBPROC glad_glUniform2fARB = NULL; |
| 2365 | PFNGLUNIFORM2IARBPROC glad_glUniform2iARB; | 2366 | PFNGLUNIFORM3FARBPROC glad_glUniform3fARB = NULL; |
| 2366 | PFNGLUNIFORM3IARBPROC glad_glUniform3iARB; | 2367 | PFNGLUNIFORM4FARBPROC glad_glUniform4fARB = NULL; |
| 2367 | PFNGLUNIFORM4IARBPROC glad_glUniform4iARB; | 2368 | PFNGLUNIFORM1IARBPROC glad_glUniform1iARB = NULL; |
| 2368 | PFNGLUNIFORM1FVARBPROC glad_glUniform1fvARB; | 2369 | PFNGLUNIFORM2IARBPROC glad_glUniform2iARB = NULL; |
| 2369 | PFNGLUNIFORM2FVARBPROC glad_glUniform2fvARB; | 2370 | PFNGLUNIFORM3IARBPROC glad_glUniform3iARB = NULL; |
| 2370 | PFNGLUNIFORM3FVARBPROC glad_glUniform3fvARB; | 2371 | PFNGLUNIFORM4IARBPROC glad_glUniform4iARB = NULL; |
| 2371 | PFNGLUNIFORM4FVARBPROC glad_glUniform4fvARB; | 2372 | PFNGLUNIFORM1FVARBPROC glad_glUniform1fvARB = NULL; |
| 2372 | PFNGLUNIFORM1IVARBPROC glad_glUniform1ivARB; | 2373 | PFNGLUNIFORM2FVARBPROC glad_glUniform2fvARB = NULL; |
| 2373 | PFNGLUNIFORM2IVARBPROC glad_glUniform2ivARB; | 2374 | PFNGLUNIFORM3FVARBPROC glad_glUniform3fvARB = NULL; |
| 2374 | PFNGLUNIFORM3IVARBPROC glad_glUniform3ivARB; | 2375 | PFNGLUNIFORM4FVARBPROC glad_glUniform4fvARB = NULL; |
| 2375 | PFNGLUNIFORM4IVARBPROC glad_glUniform4ivARB; | 2376 | PFNGLUNIFORM1IVARBPROC glad_glUniform1ivARB = NULL; |
| 2376 | PFNGLUNIFORMMATRIX2FVARBPROC glad_glUniformMatrix2fvARB; | 2377 | PFNGLUNIFORM2IVARBPROC glad_glUniform2ivARB = NULL; |
| 2377 | PFNGLUNIFORMMATRIX3FVARBPROC glad_glUniformMatrix3fvARB; | 2378 | PFNGLUNIFORM3IVARBPROC glad_glUniform3ivARB = NULL; |
| 2378 | PFNGLUNIFORMMATRIX4FVARBPROC glad_glUniformMatrix4fvARB; | 2379 | PFNGLUNIFORM4IVARBPROC glad_glUniform4ivARB = NULL; |
| 2379 | PFNGLGETOBJECTPARAMETERFVARBPROC glad_glGetObjectParameterfvARB; | 2380 | PFNGLUNIFORMMATRIX2FVARBPROC glad_glUniformMatrix2fvARB = NULL; |
| 2380 | PFNGLGETOBJECTPARAMETERIVARBPROC glad_glGetObjectParameterivARB; | 2381 | PFNGLUNIFORMMATRIX3FVARBPROC glad_glUniformMatrix3fvARB = NULL; |
| 2381 | PFNGLGETINFOLOGARBPROC glad_glGetInfoLogARB; | 2382 | PFNGLUNIFORMMATRIX4FVARBPROC glad_glUniformMatrix4fvARB = NULL; |
| 2382 | PFNGLGETATTACHEDOBJECTSARBPROC glad_glGetAttachedObjectsARB; | 2383 | PFNGLGETOBJECTPARAMETERFVARBPROC glad_glGetObjectParameterfvARB = NULL; |
| 2383 | PFNGLGETUNIFORMLOCATIONARBPROC glad_glGetUniformLocationARB; | 2384 | PFNGLGETOBJECTPARAMETERIVARBPROC glad_glGetObjectParameterivARB = NULL; |
| 2384 | PFNGLGETACTIVEUNIFORMARBPROC glad_glGetActiveUniformARB; | 2385 | PFNGLGETINFOLOGARBPROC glad_glGetInfoLogARB = NULL; |
| 2385 | PFNGLGETUNIFORMFVARBPROC glad_glGetUniformfvARB; | 2386 | PFNGLGETATTACHEDOBJECTSARBPROC glad_glGetAttachedObjectsARB = NULL; |
| 2386 | PFNGLGETUNIFORMIVARBPROC glad_glGetUniformivARB; | 2387 | PFNGLGETUNIFORMLOCATIONARBPROC glad_glGetUniformLocationARB = NULL; |
| 2387 | PFNGLGETSHADERSOURCEARBPROC glad_glGetShaderSourceARB; | 2388 | PFNGLGETACTIVEUNIFORMARBPROC glad_glGetActiveUniformARB = NULL; |
| 2388 | PFNGLSHADERSTORAGEBLOCKBINDINGPROC glad_glShaderStorageBlockBinding; | 2389 | PFNGLGETUNIFORMFVARBPROC glad_glGetUniformfvARB = NULL; |
| 2389 | PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC glad_glGetSubroutineUniformLocation; | 2390 | PFNGLGETUNIFORMIVARBPROC glad_glGetUniformivARB = NULL; |
| 2390 | PFNGLGETSUBROUTINEINDEXPROC glad_glGetSubroutineIndex; | 2391 | PFNGLGETSHADERSOURCEARBPROC glad_glGetShaderSourceARB = NULL; |
| 2391 | PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC glad_glGetActiveSubroutineUniformiv; | 2392 | PFNGLSHADERSTORAGEBLOCKBINDINGPROC glad_glShaderStorageBlockBinding = NULL; |
| 2392 | PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC glad_glGetActiveSubroutineUniformName; | 2393 | PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC glad_glGetSubroutineUniformLocation = NULL; |
| 2393 | PFNGLGETACTIVESUBROUTINENAMEPROC glad_glGetActiveSubroutineName; | 2394 | PFNGLGETSUBROUTINEINDEXPROC glad_glGetSubroutineIndex = NULL; |
| 2394 | PFNGLUNIFORMSUBROUTINESUIVPROC glad_glUniformSubroutinesuiv; | 2395 | PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC glad_glGetActiveSubroutineUniformiv = NULL; |
| 2395 | PFNGLGETUNIFORMSUBROUTINEUIVPROC glad_glGetUniformSubroutineuiv; | 2396 | PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC glad_glGetActiveSubroutineUniformName = NULL; |
| 2396 | PFNGLGETPROGRAMSTAGEIVPROC glad_glGetProgramStageiv; | 2397 | PFNGLGETACTIVESUBROUTINENAMEPROC glad_glGetActiveSubroutineName = NULL; |
| 2397 | PFNGLNAMEDSTRINGARBPROC glad_glNamedStringARB; | 2398 | PFNGLUNIFORMSUBROUTINESUIVPROC glad_glUniformSubroutinesuiv = NULL; |
| 2398 | PFNGLDELETENAMEDSTRINGARBPROC glad_glDeleteNamedStringARB; | 2399 | PFNGLGETUNIFORMSUBROUTINEUIVPROC glad_glGetUniformSubroutineuiv = NULL; |
| 2399 | PFNGLCOMPILESHADERINCLUDEARBPROC glad_glCompileShaderIncludeARB; | 2400 | PFNGLGETPROGRAMSTAGEIVPROC glad_glGetProgramStageiv = NULL; |
| 2400 | PFNGLISNAMEDSTRINGARBPROC glad_glIsNamedStringARB; | 2401 | PFNGLNAMEDSTRINGARBPROC glad_glNamedStringARB = NULL; |
| 2401 | PFNGLGETNAMEDSTRINGARBPROC glad_glGetNamedStringARB; | 2402 | PFNGLDELETENAMEDSTRINGARBPROC glad_glDeleteNamedStringARB = NULL; |
| 2402 | PFNGLGETNAMEDSTRINGIVARBPROC glad_glGetNamedStringivARB; | 2403 | PFNGLCOMPILESHADERINCLUDEARBPROC glad_glCompileShaderIncludeARB = NULL; |
| 2403 | PFNGLBUFFERPAGECOMMITMENTARBPROC glad_glBufferPageCommitmentARB; | 2404 | PFNGLISNAMEDSTRINGARBPROC glad_glIsNamedStringARB = NULL; |
| 2404 | PFNGLNAMEDBUFFERPAGECOMMITMENTEXTPROC glad_glNamedBufferPageCommitmentEXT; | 2405 | PFNGLGETNAMEDSTRINGARBPROC glad_glGetNamedStringARB = NULL; |
| 2405 | PFNGLNAMEDBUFFERPAGECOMMITMENTARBPROC glad_glNamedBufferPageCommitmentARB; | 2406 | PFNGLGETNAMEDSTRINGIVARBPROC glad_glGetNamedStringivARB = NULL; |
| 2406 | PFNGLTEXPAGECOMMITMENTARBPROC glad_glTexPageCommitmentARB; | 2407 | PFNGLBUFFERPAGECOMMITMENTARBPROC glad_glBufferPageCommitmentARB = NULL; |
| 2407 | PFNGLPATCHPARAMETERIPROC glad_glPatchParameteri; | 2408 | PFNGLNAMEDBUFFERPAGECOMMITMENTEXTPROC glad_glNamedBufferPageCommitmentEXT = NULL; |
| 2408 | PFNGLPATCHPARAMETERFVPROC glad_glPatchParameterfv; | 2409 | PFNGLNAMEDBUFFERPAGECOMMITMENTARBPROC glad_glNamedBufferPageCommitmentARB = NULL; |
| 2409 | PFNGLTEXTUREBARRIERPROC glad_glTextureBarrier; | 2410 | PFNGLTEXPAGECOMMITMENTARBPROC glad_glTexPageCommitmentARB = NULL; |
| 2410 | PFNGLTEXBUFFERARBPROC glad_glTexBufferARB; | 2411 | PFNGLPATCHPARAMETERIPROC glad_glPatchParameteri = NULL; |
| 2411 | PFNGLTEXBUFFERRANGEPROC glad_glTexBufferRange; | 2412 | PFNGLPATCHPARAMETERFVPROC glad_glPatchParameterfv = NULL; |
| 2412 | PFNGLCOMPRESSEDTEXIMAGE3DARBPROC glad_glCompressedTexImage3DARB; | 2413 | PFNGLTEXTUREBARRIERPROC glad_glTextureBarrier = NULL; |
| 2413 | PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glad_glCompressedTexImage2DARB; | 2414 | PFNGLTEXBUFFERARBPROC glad_glTexBufferARB = NULL; |
| 2414 | PFNGLCOMPRESSEDTEXIMAGE1DARBPROC glad_glCompressedTexImage1DARB; | 2415 | PFNGLTEXBUFFERRANGEPROC glad_glTexBufferRange = NULL; |
| 2415 | PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC glad_glCompressedTexSubImage3DARB; | 2416 | PFNGLCOMPRESSEDTEXIMAGE3DARBPROC glad_glCompressedTexImage3DARB = NULL; |
| 2416 | PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC glad_glCompressedTexSubImage2DARB; | 2417 | PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glad_glCompressedTexImage2DARB = NULL; |
| 2417 | PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC glad_glCompressedTexSubImage1DARB; | 2418 | PFNGLCOMPRESSEDTEXIMAGE1DARBPROC glad_glCompressedTexImage1DARB = NULL; |
| 2418 | PFNGLGETCOMPRESSEDTEXIMAGEARBPROC glad_glGetCompressedTexImageARB; | 2419 | PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC glad_glCompressedTexSubImage3DARB = NULL; |
| 2419 | PFNGLTEXSTORAGE1DPROC glad_glTexStorage1D; | 2420 | PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC glad_glCompressedTexSubImage2DARB = NULL; |
| 2420 | PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D; | 2421 | PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC glad_glCompressedTexSubImage1DARB = NULL; |
| 2421 | PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D; | 2422 | PFNGLGETCOMPRESSEDTEXIMAGEARBPROC glad_glGetCompressedTexImageARB = NULL; |
| 2422 | PFNGLTEXSTORAGE2DMULTISAMPLEPROC glad_glTexStorage2DMultisample; | 2423 | PFNGLTEXSTORAGE1DPROC glad_glTexStorage1D = NULL; |
| 2423 | PFNGLTEXSTORAGE3DMULTISAMPLEPROC glad_glTexStorage3DMultisample; | 2424 | PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D = NULL; |
| 2424 | PFNGLTEXTUREVIEWPROC glad_glTextureView; | 2425 | PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D = NULL; |
| 2425 | PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback; | 2426 | PFNGLTEXSTORAGE2DMULTISAMPLEPROC glad_glTexStorage2DMultisample = NULL; |
| 2426 | PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks; | 2427 | PFNGLTEXSTORAGE3DMULTISAMPLEPROC glad_glTexStorage3DMultisample = NULL; |
| 2427 | PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks; | 2428 | PFNGLTEXTUREVIEWPROC glad_glTextureView = NULL; |
| 2428 | PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback; | 2429 | PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback = NULL; |
| 2429 | PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback; | 2430 | PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks = NULL; |
| 2430 | PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback; | 2431 | PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks = NULL; |
| 2431 | PFNGLDRAWTRANSFORMFEEDBACKPROC glad_glDrawTransformFeedback; | 2432 | PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback = NULL; |
| 2432 | PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC glad_glDrawTransformFeedbackStream; | 2433 | PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback = NULL; |
| 2433 | PFNGLBEGINQUERYINDEXEDPROC glad_glBeginQueryIndexed; | 2434 | PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback = NULL; |
| 2434 | PFNGLENDQUERYINDEXEDPROC glad_glEndQueryIndexed; | 2435 | PFNGLDRAWTRANSFORMFEEDBACKPROC glad_glDrawTransformFeedback = NULL; |
| 2435 | PFNGLGETQUERYINDEXEDIVPROC glad_glGetQueryIndexediv; | 2436 | PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC glad_glDrawTransformFeedbackStream = NULL; |
| 2436 | PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC glad_glDrawTransformFeedbackInstanced; | 2437 | PFNGLBEGINQUERYINDEXEDPROC glad_glBeginQueryIndexed = NULL; |
| 2437 | PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC glad_glDrawTransformFeedbackStreamInstanced; | 2438 | PFNGLENDQUERYINDEXEDPROC glad_glEndQueryIndexed = NULL; |
| 2438 | PFNGLLOADTRANSPOSEMATRIXFARBPROC glad_glLoadTransposeMatrixfARB; | 2439 | PFNGLGETQUERYINDEXEDIVPROC glad_glGetQueryIndexediv = NULL; |
| 2439 | PFNGLLOADTRANSPOSEMATRIXDARBPROC glad_glLoadTransposeMatrixdARB; | 2440 | PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC glad_glDrawTransformFeedbackInstanced = NULL; |
| 2440 | PFNGLMULTTRANSPOSEMATRIXFARBPROC glad_glMultTransposeMatrixfARB; | 2441 | PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC glad_glDrawTransformFeedbackStreamInstanced = NULL; |
| 2441 | PFNGLMULTTRANSPOSEMATRIXDARBPROC glad_glMultTransposeMatrixdARB; | 2442 | PFNGLLOADTRANSPOSEMATRIXFARBPROC glad_glLoadTransposeMatrixfARB = NULL; |
| 2442 | PFNGLVERTEXATTRIBL1DPROC glad_glVertexAttribL1d; | 2443 | PFNGLLOADTRANSPOSEMATRIXDARBPROC glad_glLoadTransposeMatrixdARB = NULL; |
| 2443 | PFNGLVERTEXATTRIBL2DPROC glad_glVertexAttribL2d; | 2444 | PFNGLMULTTRANSPOSEMATRIXFARBPROC glad_glMultTransposeMatrixfARB = NULL; |
| 2444 | PFNGLVERTEXATTRIBL3DPROC glad_glVertexAttribL3d; | 2445 | PFNGLMULTTRANSPOSEMATRIXDARBPROC glad_glMultTransposeMatrixdARB = NULL; |
| 2445 | PFNGLVERTEXATTRIBL4DPROC glad_glVertexAttribL4d; | 2446 | PFNGLVERTEXATTRIBL1DPROC glad_glVertexAttribL1d = NULL; |
| 2446 | PFNGLVERTEXATTRIBL1DVPROC glad_glVertexAttribL1dv; | 2447 | PFNGLVERTEXATTRIBL2DPROC glad_glVertexAttribL2d = NULL; |
| 2447 | PFNGLVERTEXATTRIBL2DVPROC glad_glVertexAttribL2dv; | 2448 | PFNGLVERTEXATTRIBL3DPROC glad_glVertexAttribL3d = NULL; |
| 2448 | PFNGLVERTEXATTRIBL3DVPROC glad_glVertexAttribL3dv; | 2449 | PFNGLVERTEXATTRIBL4DPROC glad_glVertexAttribL4d = NULL; |
| 2449 | PFNGLVERTEXATTRIBL4DVPROC glad_glVertexAttribL4dv; | 2450 | PFNGLVERTEXATTRIBL1DVPROC glad_glVertexAttribL1dv = NULL; |
| 2450 | PFNGLVERTEXATTRIBLPOINTERPROC glad_glVertexAttribLPointer; | 2451 | PFNGLVERTEXATTRIBL2DVPROC glad_glVertexAttribL2dv = NULL; |
| 2451 | PFNGLGETVERTEXATTRIBLDVPROC glad_glGetVertexAttribLdv; | 2452 | PFNGLVERTEXATTRIBL3DVPROC glad_glVertexAttribL3dv = NULL; |
| 2452 | PFNGLBINDVERTEXBUFFERPROC glad_glBindVertexBuffer; | 2453 | PFNGLVERTEXATTRIBL4DVPROC glad_glVertexAttribL4dv = NULL; |
| 2453 | PFNGLVERTEXATTRIBFORMATPROC glad_glVertexAttribFormat; | 2454 | PFNGLVERTEXATTRIBLPOINTERPROC glad_glVertexAttribLPointer = NULL; |
| 2454 | PFNGLVERTEXATTRIBIFORMATPROC glad_glVertexAttribIFormat; | 2455 | PFNGLGETVERTEXATTRIBLDVPROC glad_glGetVertexAttribLdv = NULL; |
| 2455 | PFNGLVERTEXATTRIBLFORMATPROC glad_glVertexAttribLFormat; | 2456 | PFNGLBINDVERTEXBUFFERPROC glad_glBindVertexBuffer = NULL; |
| 2456 | PFNGLVERTEXATTRIBBINDINGPROC glad_glVertexAttribBinding; | 2457 | PFNGLVERTEXATTRIBFORMATPROC glad_glVertexAttribFormat = NULL; |
| 2457 | PFNGLVERTEXBINDINGDIVISORPROC glad_glVertexBindingDivisor; | 2458 | PFNGLVERTEXATTRIBIFORMATPROC glad_glVertexAttribIFormat = NULL; |
| 2458 | PFNGLWEIGHTBVARBPROC glad_glWeightbvARB; | 2459 | PFNGLVERTEXATTRIBLFORMATPROC glad_glVertexAttribLFormat = NULL; |
| 2459 | PFNGLWEIGHTSVARBPROC glad_glWeightsvARB; | 2460 | PFNGLVERTEXATTRIBBINDINGPROC glad_glVertexAttribBinding = NULL; |
| 2460 | PFNGLWEIGHTIVARBPROC glad_glWeightivARB; | 2461 | PFNGLVERTEXBINDINGDIVISORPROC glad_glVertexBindingDivisor = NULL; |
| 2461 | PFNGLWEIGHTFVARBPROC glad_glWeightfvARB; | 2462 | PFNGLWEIGHTBVARBPROC glad_glWeightbvARB = NULL; |
| 2462 | PFNGLWEIGHTDVARBPROC glad_glWeightdvARB; | 2463 | PFNGLWEIGHTSVARBPROC glad_glWeightsvARB = NULL; |
| 2463 | PFNGLWEIGHTUBVARBPROC glad_glWeightubvARB; | 2464 | PFNGLWEIGHTIVARBPROC glad_glWeightivARB = NULL; |
| 2464 | PFNGLWEIGHTUSVARBPROC glad_glWeightusvARB; | 2465 | PFNGLWEIGHTFVARBPROC glad_glWeightfvARB = NULL; |
| 2465 | PFNGLWEIGHTUIVARBPROC glad_glWeightuivARB; | 2466 | PFNGLWEIGHTDVARBPROC glad_glWeightdvARB = NULL; |
| 2466 | PFNGLWEIGHTPOINTERARBPROC glad_glWeightPointerARB; | 2467 | PFNGLWEIGHTUBVARBPROC glad_glWeightubvARB = NULL; |
| 2467 | PFNGLVERTEXBLENDARBPROC glad_glVertexBlendARB; | 2468 | PFNGLWEIGHTUSVARBPROC glad_glWeightusvARB = NULL; |
| 2468 | PFNGLBINDBUFFERARBPROC glad_glBindBufferARB; | 2469 | PFNGLWEIGHTUIVARBPROC glad_glWeightuivARB = NULL; |
| 2469 | PFNGLDELETEBUFFERSARBPROC glad_glDeleteBuffersARB; | 2470 | PFNGLWEIGHTPOINTERARBPROC glad_glWeightPointerARB = NULL; |
| 2470 | PFNGLGENBUFFERSARBPROC glad_glGenBuffersARB; | 2471 | PFNGLVERTEXBLENDARBPROC glad_glVertexBlendARB = NULL; |
| 2471 | PFNGLISBUFFERARBPROC glad_glIsBufferARB; | 2472 | PFNGLBINDBUFFERARBPROC glad_glBindBufferARB = NULL; |
| 2472 | PFNGLBUFFERDATAARBPROC glad_glBufferDataARB; | 2473 | PFNGLDELETEBUFFERSARBPROC glad_glDeleteBuffersARB = NULL; |
| 2473 | PFNGLBUFFERSUBDATAARBPROC glad_glBufferSubDataARB; | 2474 | PFNGLGENBUFFERSARBPROC glad_glGenBuffersARB = NULL; |
| 2474 | PFNGLGETBUFFERSUBDATAARBPROC glad_glGetBufferSubDataARB; | 2475 | PFNGLISBUFFERARBPROC glad_glIsBufferARB = NULL; |
| 2475 | PFNGLMAPBUFFERARBPROC glad_glMapBufferARB; | 2476 | PFNGLBUFFERDATAARBPROC glad_glBufferDataARB = NULL; |
| 2476 | PFNGLUNMAPBUFFERARBPROC glad_glUnmapBufferARB; | 2477 | PFNGLBUFFERSUBDATAARBPROC glad_glBufferSubDataARB = NULL; |
| 2477 | PFNGLGETBUFFERPARAMETERIVARBPROC glad_glGetBufferParameterivARB; | 2478 | PFNGLGETBUFFERSUBDATAARBPROC glad_glGetBufferSubDataARB = NULL; |
| 2478 | PFNGLGETBUFFERPOINTERVARBPROC glad_glGetBufferPointervARB; | 2479 | PFNGLMAPBUFFERARBPROC glad_glMapBufferARB = NULL; |
| 2479 | PFNGLVERTEXATTRIB1DARBPROC glad_glVertexAttrib1dARB; | 2480 | PFNGLUNMAPBUFFERARBPROC glad_glUnmapBufferARB = NULL; |
| 2480 | PFNGLVERTEXATTRIB1DVARBPROC glad_glVertexAttrib1dvARB; | 2481 | PFNGLGETBUFFERPARAMETERIVARBPROC glad_glGetBufferParameterivARB = NULL; |
| 2481 | PFNGLVERTEXATTRIB1FARBPROC glad_glVertexAttrib1fARB; | 2482 | PFNGLGETBUFFERPOINTERVARBPROC glad_glGetBufferPointervARB = NULL; |
| 2482 | PFNGLVERTEXATTRIB1FVARBPROC glad_glVertexAttrib1fvARB; | 2483 | PFNGLVERTEXATTRIB1DARBPROC glad_glVertexAttrib1dARB = NULL; |
| 2483 | PFNGLVERTEXATTRIB1SARBPROC glad_glVertexAttrib1sARB; | 2484 | PFNGLVERTEXATTRIB1DVARBPROC glad_glVertexAttrib1dvARB = NULL; |
| 2484 | PFNGLVERTEXATTRIB1SVARBPROC glad_glVertexAttrib1svARB; | 2485 | PFNGLVERTEXATTRIB1FARBPROC glad_glVertexAttrib1fARB = NULL; |
| 2485 | PFNGLVERTEXATTRIB2DARBPROC glad_glVertexAttrib2dARB; | 2486 | PFNGLVERTEXATTRIB1FVARBPROC glad_glVertexAttrib1fvARB = NULL; |
| 2486 | PFNGLVERTEXATTRIB2DVARBPROC glad_glVertexAttrib2dvARB; | 2487 | PFNGLVERTEXATTRIB1SARBPROC glad_glVertexAttrib1sARB = NULL; |
| 2487 | PFNGLVERTEXATTRIB2FARBPROC glad_glVertexAttrib2fARB; | 2488 | PFNGLVERTEXATTRIB1SVARBPROC glad_glVertexAttrib1svARB = NULL; |
| 2488 | PFNGLVERTEXATTRIB2FVARBPROC glad_glVertexAttrib2fvARB; | 2489 | PFNGLVERTEXATTRIB2DARBPROC glad_glVertexAttrib2dARB = NULL; |
| 2489 | PFNGLVERTEXATTRIB2SARBPROC glad_glVertexAttrib2sARB; | 2490 | PFNGLVERTEXATTRIB2DVARBPROC glad_glVertexAttrib2dvARB = NULL; |
| 2490 | PFNGLVERTEXATTRIB2SVARBPROC glad_glVertexAttrib2svARB; | 2491 | PFNGLVERTEXATTRIB2FARBPROC glad_glVertexAttrib2fARB = NULL; |
| 2491 | PFNGLVERTEXATTRIB3DARBPROC glad_glVertexAttrib3dARB; | 2492 | PFNGLVERTEXATTRIB2FVARBPROC glad_glVertexAttrib2fvARB = NULL; |
| 2492 | PFNGLVERTEXATTRIB3DVARBPROC glad_glVertexAttrib3dvARB; | 2493 | PFNGLVERTEXATTRIB2SARBPROC glad_glVertexAttrib2sARB = NULL; |
| 2493 | PFNGLVERTEXATTRIB3FARBPROC glad_glVertexAttrib3fARB; | 2494 | PFNGLVERTEXATTRIB2SVARBPROC glad_glVertexAttrib2svARB = NULL; |
| 2494 | PFNGLVERTEXATTRIB3FVARBPROC glad_glVertexAttrib3fvARB; | 2495 | PFNGLVERTEXATTRIB3DARBPROC glad_glVertexAttrib3dARB = NULL; |
| 2495 | PFNGLVERTEXATTRIB3SARBPROC glad_glVertexAttrib3sARB; | 2496 | PFNGLVERTEXATTRIB3DVARBPROC glad_glVertexAttrib3dvARB = NULL; |
| 2496 | PFNGLVERTEXATTRIB3SVARBPROC glad_glVertexAttrib3svARB; | 2497 | PFNGLVERTEXATTRIB3FARBPROC glad_glVertexAttrib3fARB = NULL; |
| 2497 | PFNGLVERTEXATTRIB4NBVARBPROC glad_glVertexAttrib4NbvARB; | 2498 | PFNGLVERTEXATTRIB3FVARBPROC glad_glVertexAttrib3fvARB = NULL; |
| 2498 | PFNGLVERTEXATTRIB4NIVARBPROC glad_glVertexAttrib4NivARB; | 2499 | PFNGLVERTEXATTRIB3SARBPROC glad_glVertexAttrib3sARB = NULL; |
| 2499 | PFNGLVERTEXATTRIB4NSVARBPROC glad_glVertexAttrib4NsvARB; | 2500 | PFNGLVERTEXATTRIB3SVARBPROC glad_glVertexAttrib3svARB = NULL; |
| 2500 | PFNGLVERTEXATTRIB4NUBARBPROC glad_glVertexAttrib4NubARB; | 2501 | PFNGLVERTEXATTRIB4NBVARBPROC glad_glVertexAttrib4NbvARB = NULL; |
| 2501 | PFNGLVERTEXATTRIB4NUBVARBPROC glad_glVertexAttrib4NubvARB; | 2502 | PFNGLVERTEXATTRIB4NIVARBPROC glad_glVertexAttrib4NivARB = NULL; |
| 2502 | PFNGLVERTEXATTRIB4NUIVARBPROC glad_glVertexAttrib4NuivARB; | 2503 | PFNGLVERTEXATTRIB4NSVARBPROC glad_glVertexAttrib4NsvARB = NULL; |
| 2503 | PFNGLVERTEXATTRIB4NUSVARBPROC glad_glVertexAttrib4NusvARB; | 2504 | PFNGLVERTEXATTRIB4NUBARBPROC glad_glVertexAttrib4NubARB = NULL; |
| 2504 | PFNGLVERTEXATTRIB4BVARBPROC glad_glVertexAttrib4bvARB; | 2505 | PFNGLVERTEXATTRIB4NUBVARBPROC glad_glVertexAttrib4NubvARB = NULL; |
| 2505 | PFNGLVERTEXATTRIB4DARBPROC glad_glVertexAttrib4dARB; | 2506 | PFNGLVERTEXATTRIB4NUIVARBPROC glad_glVertexAttrib4NuivARB = NULL; |
| 2506 | PFNGLVERTEXATTRIB4DVARBPROC glad_glVertexAttrib4dvARB; | 2507 | PFNGLVERTEXATTRIB4NUSVARBPROC glad_glVertexAttrib4NusvARB = NULL; |
| 2507 | PFNGLVERTEXATTRIB4FARBPROC glad_glVertexAttrib4fARB; | 2508 | PFNGLVERTEXATTRIB4BVARBPROC glad_glVertexAttrib4bvARB = NULL; |
| 2508 | PFNGLVERTEXATTRIB4FVARBPROC glad_glVertexAttrib4fvARB; | 2509 | PFNGLVERTEXATTRIB4DARBPROC glad_glVertexAttrib4dARB = NULL; |
| 2509 | PFNGLVERTEXATTRIB4IVARBPROC glad_glVertexAttrib4ivARB; | 2510 | PFNGLVERTEXATTRIB4DVARBPROC glad_glVertexAttrib4dvARB = NULL; |
| 2510 | PFNGLVERTEXATTRIB4SARBPROC glad_glVertexAttrib4sARB; | 2511 | PFNGLVERTEXATTRIB4FARBPROC glad_glVertexAttrib4fARB = NULL; |
| 2511 | PFNGLVERTEXATTRIB4SVARBPROC glad_glVertexAttrib4svARB; | 2512 | PFNGLVERTEXATTRIB4FVARBPROC glad_glVertexAttrib4fvARB = NULL; |
| 2512 | PFNGLVERTEXATTRIB4UBVARBPROC glad_glVertexAttrib4ubvARB; | 2513 | PFNGLVERTEXATTRIB4IVARBPROC glad_glVertexAttrib4ivARB = NULL; |
| 2513 | PFNGLVERTEXATTRIB4UIVARBPROC glad_glVertexAttrib4uivARB; | 2514 | PFNGLVERTEXATTRIB4SARBPROC glad_glVertexAttrib4sARB = NULL; |
| 2514 | PFNGLVERTEXATTRIB4USVARBPROC glad_glVertexAttrib4usvARB; | 2515 | PFNGLVERTEXATTRIB4SVARBPROC glad_glVertexAttrib4svARB = NULL; |
| 2515 | PFNGLVERTEXATTRIBPOINTERARBPROC glad_glVertexAttribPointerARB; | 2516 | PFNGLVERTEXATTRIB4UBVARBPROC glad_glVertexAttrib4ubvARB = NULL; |
| 2516 | PFNGLENABLEVERTEXATTRIBARRAYARBPROC glad_glEnableVertexAttribArrayARB; | 2517 | PFNGLVERTEXATTRIB4UIVARBPROC glad_glVertexAttrib4uivARB = NULL; |
| 2517 | PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glad_glDisableVertexAttribArrayARB; | 2518 | PFNGLVERTEXATTRIB4USVARBPROC glad_glVertexAttrib4usvARB = NULL; |
| 2518 | PFNGLGETVERTEXATTRIBDVARBPROC glad_glGetVertexAttribdvARB; | 2519 | PFNGLVERTEXATTRIBPOINTERARBPROC glad_glVertexAttribPointerARB = NULL; |
| 2519 | PFNGLGETVERTEXATTRIBFVARBPROC glad_glGetVertexAttribfvARB; | 2520 | PFNGLENABLEVERTEXATTRIBARRAYARBPROC glad_glEnableVertexAttribArrayARB = NULL; |
| 2520 | PFNGLGETVERTEXATTRIBIVARBPROC glad_glGetVertexAttribivARB; | 2521 | PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glad_glDisableVertexAttribArrayARB = NULL; |
| 2521 | PFNGLGETVERTEXATTRIBPOINTERVARBPROC glad_glGetVertexAttribPointervARB; | 2522 | PFNGLGETVERTEXATTRIBDVARBPROC glad_glGetVertexAttribdvARB = NULL; |
| 2522 | PFNGLBINDATTRIBLOCATIONARBPROC glad_glBindAttribLocationARB; | 2523 | PFNGLGETVERTEXATTRIBFVARBPROC glad_glGetVertexAttribfvARB = NULL; |
| 2523 | PFNGLGETACTIVEATTRIBARBPROC glad_glGetActiveAttribARB; | 2524 | PFNGLGETVERTEXATTRIBIVARBPROC glad_glGetVertexAttribivARB = NULL; |
| 2524 | PFNGLGETATTRIBLOCATIONARBPROC glad_glGetAttribLocationARB; | 2525 | PFNGLGETVERTEXATTRIBPOINTERVARBPROC glad_glGetVertexAttribPointervARB = NULL; |
| 2525 | PFNGLVIEWPORTARRAYVPROC glad_glViewportArrayv; | 2526 | PFNGLBINDATTRIBLOCATIONARBPROC glad_glBindAttribLocationARB = NULL; |
| 2526 | PFNGLVIEWPORTINDEXEDFPROC glad_glViewportIndexedf; | 2527 | PFNGLGETACTIVEATTRIBARBPROC glad_glGetActiveAttribARB = NULL; |
| 2527 | PFNGLVIEWPORTINDEXEDFVPROC glad_glViewportIndexedfv; | 2528 | PFNGLGETATTRIBLOCATIONARBPROC glad_glGetAttribLocationARB = NULL; |
| 2528 | PFNGLSCISSORARRAYVPROC glad_glScissorArrayv; | 2529 | PFNGLVIEWPORTARRAYVPROC glad_glViewportArrayv = NULL; |
| 2529 | PFNGLSCISSORINDEXEDPROC glad_glScissorIndexed; | 2530 | PFNGLVIEWPORTINDEXEDFPROC glad_glViewportIndexedf = NULL; |
| 2530 | PFNGLSCISSORINDEXEDVPROC glad_glScissorIndexedv; | 2531 | PFNGLVIEWPORTINDEXEDFVPROC glad_glViewportIndexedfv = NULL; |
| 2531 | PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv; | 2532 | PFNGLSCISSORARRAYVPROC glad_glScissorArrayv = NULL; |
| 2532 | PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed; | 2533 | PFNGLSCISSORINDEXEDPROC glad_glScissorIndexed = NULL; |
| 2533 | PFNGLGETFLOATI_VPROC glad_glGetFloati_v; | 2534 | PFNGLSCISSORINDEXEDVPROC glad_glScissorIndexedv = NULL; |
| 2534 | PFNGLGETDOUBLEI_VPROC glad_glGetDoublei_v; | 2535 | PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv = NULL; |
| 2535 | PFNGLWINDOWPOS2DARBPROC glad_glWindowPos2dARB; | 2536 | PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed = NULL; |
| 2536 | PFNGLWINDOWPOS2DVARBPROC glad_glWindowPos2dvARB; | 2537 | PFNGLGETFLOATI_VPROC glad_glGetFloati_v = NULL; |
| 2537 | PFNGLWINDOWPOS2FARBPROC glad_glWindowPos2fARB; | 2538 | PFNGLGETDOUBLEI_VPROC glad_glGetDoublei_v = NULL; |
| 2538 | PFNGLWINDOWPOS2FVARBPROC glad_glWindowPos2fvARB; | 2539 | PFNGLWINDOWPOS2DARBPROC glad_glWindowPos2dARB = NULL; |
| 2539 | PFNGLWINDOWPOS2IARBPROC glad_glWindowPos2iARB; | 2540 | PFNGLWINDOWPOS2DVARBPROC glad_glWindowPos2dvARB = NULL; |
| 2540 | PFNGLWINDOWPOS2IVARBPROC glad_glWindowPos2ivARB; | 2541 | PFNGLWINDOWPOS2FARBPROC glad_glWindowPos2fARB = NULL; |
| 2541 | PFNGLWINDOWPOS2SARBPROC glad_glWindowPos2sARB; | 2542 | PFNGLWINDOWPOS2FVARBPROC glad_glWindowPos2fvARB = NULL; |
| 2542 | PFNGLWINDOWPOS2SVARBPROC glad_glWindowPos2svARB; | 2543 | PFNGLWINDOWPOS2IARBPROC glad_glWindowPos2iARB = NULL; |
| 2543 | PFNGLWINDOWPOS3DARBPROC glad_glWindowPos3dARB; | 2544 | PFNGLWINDOWPOS2IVARBPROC glad_glWindowPos2ivARB = NULL; |
| 2544 | PFNGLWINDOWPOS3DVARBPROC glad_glWindowPos3dvARB; | 2545 | PFNGLWINDOWPOS2SARBPROC glad_glWindowPos2sARB = NULL; |
| 2545 | PFNGLWINDOWPOS3FARBPROC glad_glWindowPos3fARB; | 2546 | PFNGLWINDOWPOS2SVARBPROC glad_glWindowPos2svARB = NULL; |
| 2546 | PFNGLWINDOWPOS3FVARBPROC glad_glWindowPos3fvARB; | 2547 | PFNGLWINDOWPOS3DARBPROC glad_glWindowPos3dARB = NULL; |
| 2547 | PFNGLWINDOWPOS3IARBPROC glad_glWindowPos3iARB; | 2548 | PFNGLWINDOWPOS3DVARBPROC glad_glWindowPos3dvARB = NULL; |
| 2548 | PFNGLWINDOWPOS3IVARBPROC glad_glWindowPos3ivARB; | 2549 | PFNGLWINDOWPOS3FARBPROC glad_glWindowPos3fARB = NULL; |
| 2549 | PFNGLWINDOWPOS3SARBPROC glad_glWindowPos3sARB; | 2550 | PFNGLWINDOWPOS3FVARBPROC glad_glWindowPos3fvARB = NULL; |
| 2550 | PFNGLWINDOWPOS3SVARBPROC glad_glWindowPos3svARB; | 2551 | PFNGLWINDOWPOS3IARBPROC glad_glWindowPos3iARB = NULL; |
| 2551 | PFNGLDRAWBUFFERSATIPROC glad_glDrawBuffersATI; | 2552 | PFNGLWINDOWPOS3IVARBPROC glad_glWindowPos3ivARB = NULL; |
| 2552 | PFNGLELEMENTPOINTERATIPROC glad_glElementPointerATI; | 2553 | PFNGLWINDOWPOS3SARBPROC glad_glWindowPos3sARB = NULL; |
| 2553 | PFNGLDRAWELEMENTARRAYATIPROC glad_glDrawElementArrayATI; | 2554 | PFNGLWINDOWPOS3SVARBPROC glad_glWindowPos3svARB = NULL; |
| 2554 | PFNGLDRAWRANGEELEMENTARRAYATIPROC glad_glDrawRangeElementArrayATI; | 2555 | PFNGLDRAWBUFFERSATIPROC glad_glDrawBuffersATI = NULL; |
| 2555 | PFNGLTEXBUMPPARAMETERIVATIPROC glad_glTexBumpParameterivATI; | 2556 | PFNGLELEMENTPOINTERATIPROC glad_glElementPointerATI = NULL; |
| 2556 | PFNGLTEXBUMPPARAMETERFVATIPROC glad_glTexBumpParameterfvATI; | 2557 | PFNGLDRAWELEMENTARRAYATIPROC glad_glDrawElementArrayATI = NULL; |
| 2557 | PFNGLGETTEXBUMPPARAMETERIVATIPROC glad_glGetTexBumpParameterivATI; | 2558 | PFNGLDRAWRANGEELEMENTARRAYATIPROC glad_glDrawRangeElementArrayATI = NULL; |
| 2558 | PFNGLGETTEXBUMPPARAMETERFVATIPROC glad_glGetTexBumpParameterfvATI; | 2559 | PFNGLTEXBUMPPARAMETERIVATIPROC glad_glTexBumpParameterivATI = NULL; |
| 2559 | PFNGLGENFRAGMENTSHADERSATIPROC glad_glGenFragmentShadersATI; | 2560 | PFNGLTEXBUMPPARAMETERFVATIPROC glad_glTexBumpParameterfvATI = NULL; |
| 2560 | PFNGLBINDFRAGMENTSHADERATIPROC glad_glBindFragmentShaderATI; | 2561 | PFNGLGETTEXBUMPPARAMETERIVATIPROC glad_glGetTexBumpParameterivATI = NULL; |
| 2561 | PFNGLDELETEFRAGMENTSHADERATIPROC glad_glDeleteFragmentShaderATI; | 2562 | PFNGLGETTEXBUMPPARAMETERFVATIPROC glad_glGetTexBumpParameterfvATI = NULL; |
| 2562 | PFNGLBEGINFRAGMENTSHADERATIPROC glad_glBeginFragmentShaderATI; | 2563 | PFNGLGENFRAGMENTSHADERSATIPROC glad_glGenFragmentShadersATI = NULL; |
| 2563 | PFNGLENDFRAGMENTSHADERATIPROC glad_glEndFragmentShaderATI; | 2564 | PFNGLBINDFRAGMENTSHADERATIPROC glad_glBindFragmentShaderATI = NULL; |
| 2564 | PFNGLPASSTEXCOORDATIPROC glad_glPassTexCoordATI; | 2565 | PFNGLDELETEFRAGMENTSHADERATIPROC glad_glDeleteFragmentShaderATI = NULL; |
| 2565 | PFNGLSAMPLEMAPATIPROC glad_glSampleMapATI; | 2566 | PFNGLBEGINFRAGMENTSHADERATIPROC glad_glBeginFragmentShaderATI = NULL; |
| 2566 | PFNGLCOLORFRAGMENTOP1ATIPROC glad_glColorFragmentOp1ATI; | 2567 | PFNGLENDFRAGMENTSHADERATIPROC glad_glEndFragmentShaderATI = NULL; |
| 2567 | PFNGLCOLORFRAGMENTOP2ATIPROC glad_glColorFragmentOp2ATI; | 2568 | PFNGLPASSTEXCOORDATIPROC glad_glPassTexCoordATI = NULL; |
| 2568 | PFNGLCOLORFRAGMENTOP3ATIPROC glad_glColorFragmentOp3ATI; | 2569 | PFNGLSAMPLEMAPATIPROC glad_glSampleMapATI = NULL; |
| 2569 | PFNGLALPHAFRAGMENTOP1ATIPROC glad_glAlphaFragmentOp1ATI; | 2570 | PFNGLCOLORFRAGMENTOP1ATIPROC glad_glColorFragmentOp1ATI = NULL; |
| 2570 | PFNGLALPHAFRAGMENTOP2ATIPROC glad_glAlphaFragmentOp2ATI; | 2571 | PFNGLCOLORFRAGMENTOP2ATIPROC glad_glColorFragmentOp2ATI = NULL; |
| 2571 | PFNGLALPHAFRAGMENTOP3ATIPROC glad_glAlphaFragmentOp3ATI; | 2572 | PFNGLCOLORFRAGMENTOP3ATIPROC glad_glColorFragmentOp3ATI = NULL; |
| 2572 | PFNGLSETFRAGMENTSHADERCONSTANTATIPROC glad_glSetFragmentShaderConstantATI; | 2573 | PFNGLALPHAFRAGMENTOP1ATIPROC glad_glAlphaFragmentOp1ATI = NULL; |
| 2573 | PFNGLMAPOBJECTBUFFERATIPROC glad_glMapObjectBufferATI; | 2574 | PFNGLALPHAFRAGMENTOP2ATIPROC glad_glAlphaFragmentOp2ATI = NULL; |
| 2574 | PFNGLUNMAPOBJECTBUFFERATIPROC glad_glUnmapObjectBufferATI; | 2575 | PFNGLALPHAFRAGMENTOP3ATIPROC glad_glAlphaFragmentOp3ATI = NULL; |
| 2575 | PFNGLPNTRIANGLESIATIPROC glad_glPNTrianglesiATI; | 2576 | PFNGLSETFRAGMENTSHADERCONSTANTATIPROC glad_glSetFragmentShaderConstantATI = NULL; |
| 2576 | PFNGLPNTRIANGLESFATIPROC glad_glPNTrianglesfATI; | 2577 | PFNGLMAPOBJECTBUFFERATIPROC glad_glMapObjectBufferATI = NULL; |
| 2577 | PFNGLSTENCILOPSEPARATEATIPROC glad_glStencilOpSeparateATI; | 2578 | PFNGLUNMAPOBJECTBUFFERATIPROC glad_glUnmapObjectBufferATI = NULL; |
| 2578 | PFNGLSTENCILFUNCSEPARATEATIPROC glad_glStencilFuncSeparateATI; | 2579 | PFNGLPNTRIANGLESIATIPROC glad_glPNTrianglesiATI = NULL; |
| 2579 | PFNGLNEWOBJECTBUFFERATIPROC glad_glNewObjectBufferATI; | 2580 | PFNGLPNTRIANGLESFATIPROC glad_glPNTrianglesfATI = NULL; |
| 2580 | PFNGLISOBJECTBUFFERATIPROC glad_glIsObjectBufferATI; | 2581 | PFNGLSTENCILOPSEPARATEATIPROC glad_glStencilOpSeparateATI = NULL; |
| 2581 | PFNGLUPDATEOBJECTBUFFERATIPROC glad_glUpdateObjectBufferATI; | 2582 | PFNGLSTENCILFUNCSEPARATEATIPROC glad_glStencilFuncSeparateATI = NULL; |
| 2582 | PFNGLGETOBJECTBUFFERFVATIPROC glad_glGetObjectBufferfvATI; | 2583 | PFNGLNEWOBJECTBUFFERATIPROC glad_glNewObjectBufferATI = NULL; |
| 2583 | PFNGLGETOBJECTBUFFERIVATIPROC glad_glGetObjectBufferivATI; | 2584 | PFNGLISOBJECTBUFFERATIPROC glad_glIsObjectBufferATI = NULL; |
| 2584 | PFNGLFREEOBJECTBUFFERATIPROC glad_glFreeObjectBufferATI; | 2585 | PFNGLUPDATEOBJECTBUFFERATIPROC glad_glUpdateObjectBufferATI = NULL; |
| 2585 | PFNGLARRAYOBJECTATIPROC glad_glArrayObjectATI; | 2586 | PFNGLGETOBJECTBUFFERFVATIPROC glad_glGetObjectBufferfvATI = NULL; |
| 2586 | PFNGLGETARRAYOBJECTFVATIPROC glad_glGetArrayObjectfvATI; | 2587 | PFNGLGETOBJECTBUFFERIVATIPROC glad_glGetObjectBufferivATI = NULL; |
| 2587 | PFNGLGETARRAYOBJECTIVATIPROC glad_glGetArrayObjectivATI; | 2588 | PFNGLFREEOBJECTBUFFERATIPROC glad_glFreeObjectBufferATI = NULL; |
| 2588 | PFNGLVARIANTARRAYOBJECTATIPROC glad_glVariantArrayObjectATI; | 2589 | PFNGLARRAYOBJECTATIPROC glad_glArrayObjectATI = NULL; |
| 2589 | PFNGLGETVARIANTARRAYOBJECTFVATIPROC glad_glGetVariantArrayObjectfvATI; | 2590 | PFNGLGETARRAYOBJECTFVATIPROC glad_glGetArrayObjectfvATI = NULL; |
| 2590 | PFNGLGETVARIANTARRAYOBJECTIVATIPROC glad_glGetVariantArrayObjectivATI; | 2591 | PFNGLGETARRAYOBJECTIVATIPROC glad_glGetArrayObjectivATI = NULL; |
| 2591 | PFNGLVERTEXATTRIBARRAYOBJECTATIPROC glad_glVertexAttribArrayObjectATI; | 2592 | PFNGLVARIANTARRAYOBJECTATIPROC glad_glVariantArrayObjectATI = NULL; |
| 2592 | PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC glad_glGetVertexAttribArrayObjectfvATI; | 2593 | PFNGLGETVARIANTARRAYOBJECTFVATIPROC glad_glGetVariantArrayObjectfvATI = NULL; |
| 2593 | PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC glad_glGetVertexAttribArrayObjectivATI; | 2594 | PFNGLGETVARIANTARRAYOBJECTIVATIPROC glad_glGetVariantArrayObjectivATI = NULL; |
| 2594 | PFNGLVERTEXSTREAM1SATIPROC glad_glVertexStream1sATI; | 2595 | PFNGLVERTEXATTRIBARRAYOBJECTATIPROC glad_glVertexAttribArrayObjectATI = NULL; |
| 2595 | PFNGLVERTEXSTREAM1SVATIPROC glad_glVertexStream1svATI; | 2596 | PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC glad_glGetVertexAttribArrayObjectfvATI = NULL; |
| 2596 | PFNGLVERTEXSTREAM1IATIPROC glad_glVertexStream1iATI; | 2597 | PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC glad_glGetVertexAttribArrayObjectivATI = NULL; |
| 2597 | PFNGLVERTEXSTREAM1IVATIPROC glad_glVertexStream1ivATI; | 2598 | PFNGLVERTEXSTREAM1SATIPROC glad_glVertexStream1sATI = NULL; |
| 2598 | PFNGLVERTEXSTREAM1FATIPROC glad_glVertexStream1fATI; | 2599 | PFNGLVERTEXSTREAM1SVATIPROC glad_glVertexStream1svATI = NULL; |
| 2599 | PFNGLVERTEXSTREAM1FVATIPROC glad_glVertexStream1fvATI; | 2600 | PFNGLVERTEXSTREAM1IATIPROC glad_glVertexStream1iATI = NULL; |
| 2600 | PFNGLVERTEXSTREAM1DATIPROC glad_glVertexStream1dATI; | 2601 | PFNGLVERTEXSTREAM1IVATIPROC glad_glVertexStream1ivATI = NULL; |
| 2601 | PFNGLVERTEXSTREAM1DVATIPROC glad_glVertexStream1dvATI; | 2602 | PFNGLVERTEXSTREAM1FATIPROC glad_glVertexStream1fATI = NULL; |
| 2602 | PFNGLVERTEXSTREAM2SATIPROC glad_glVertexStream2sATI; | 2603 | PFNGLVERTEXSTREAM1FVATIPROC glad_glVertexStream1fvATI = NULL; |
| 2603 | PFNGLVERTEXSTREAM2SVATIPROC glad_glVertexStream2svATI; | 2604 | PFNGLVERTEXSTREAM1DATIPROC glad_glVertexStream1dATI = NULL; |
| 2604 | PFNGLVERTEXSTREAM2IATIPROC glad_glVertexStream2iATI; | 2605 | PFNGLVERTEXSTREAM1DVATIPROC glad_glVertexStream1dvATI = NULL; |
| 2605 | PFNGLVERTEXSTREAM2IVATIPROC glad_glVertexStream2ivATI; | 2606 | PFNGLVERTEXSTREAM2SATIPROC glad_glVertexStream2sATI = NULL; |
| 2606 | PFNGLVERTEXSTREAM2FATIPROC glad_glVertexStream2fATI; | 2607 | PFNGLVERTEXSTREAM2SVATIPROC glad_glVertexStream2svATI = NULL; |
| 2607 | PFNGLVERTEXSTREAM2FVATIPROC glad_glVertexStream2fvATI; | 2608 | PFNGLVERTEXSTREAM2IATIPROC glad_glVertexStream2iATI = NULL; |
| 2608 | PFNGLVERTEXSTREAM2DATIPROC glad_glVertexStream2dATI; | 2609 | PFNGLVERTEXSTREAM2IVATIPROC glad_glVertexStream2ivATI = NULL; |
| 2609 | PFNGLVERTEXSTREAM2DVATIPROC glad_glVertexStream2dvATI; | 2610 | PFNGLVERTEXSTREAM2FATIPROC glad_glVertexStream2fATI = NULL; |
| 2610 | PFNGLVERTEXSTREAM3SATIPROC glad_glVertexStream3sATI; | 2611 | PFNGLVERTEXSTREAM2FVATIPROC glad_glVertexStream2fvATI = NULL; |
| 2611 | PFNGLVERTEXSTREAM3SVATIPROC glad_glVertexStream3svATI; | 2612 | PFNGLVERTEXSTREAM2DATIPROC glad_glVertexStream2dATI = NULL; |
| 2612 | PFNGLVERTEXSTREAM3IATIPROC glad_glVertexStream3iATI; | 2613 | PFNGLVERTEXSTREAM2DVATIPROC glad_glVertexStream2dvATI = NULL; |
| 2613 | PFNGLVERTEXSTREAM3IVATIPROC glad_glVertexStream3ivATI; | 2614 | PFNGLVERTEXSTREAM3SATIPROC glad_glVertexStream3sATI = NULL; |
| 2614 | PFNGLVERTEXSTREAM3FATIPROC glad_glVertexStream3fATI; | 2615 | PFNGLVERTEXSTREAM3SVATIPROC glad_glVertexStream3svATI = NULL; |
| 2615 | PFNGLVERTEXSTREAM3FVATIPROC glad_glVertexStream3fvATI; | 2616 | PFNGLVERTEXSTREAM3IATIPROC glad_glVertexStream3iATI = NULL; |
| 2616 | PFNGLVERTEXSTREAM3DATIPROC glad_glVertexStream3dATI; | 2617 | PFNGLVERTEXSTREAM3IVATIPROC glad_glVertexStream3ivATI = NULL; |
| 2617 | PFNGLVERTEXSTREAM3DVATIPROC glad_glVertexStream3dvATI; | 2618 | PFNGLVERTEXSTREAM3FATIPROC glad_glVertexStream3fATI = NULL; |
| 2618 | PFNGLVERTEXSTREAM4SATIPROC glad_glVertexStream4sATI; | 2619 | PFNGLVERTEXSTREAM3FVATIPROC glad_glVertexStream3fvATI = NULL; |
| 2619 | PFNGLVERTEXSTREAM4SVATIPROC glad_glVertexStream4svATI; | 2620 | PFNGLVERTEXSTREAM3DATIPROC glad_glVertexStream3dATI = NULL; |
| 2620 | PFNGLVERTEXSTREAM4IATIPROC glad_glVertexStream4iATI; | 2621 | PFNGLVERTEXSTREAM3DVATIPROC glad_glVertexStream3dvATI = NULL; |
| 2621 | PFNGLVERTEXSTREAM4IVATIPROC glad_glVertexStream4ivATI; | 2622 | PFNGLVERTEXSTREAM4SATIPROC glad_glVertexStream4sATI = NULL; |
| 2622 | PFNGLVERTEXSTREAM4FATIPROC glad_glVertexStream4fATI; | 2623 | PFNGLVERTEXSTREAM4SVATIPROC glad_glVertexStream4svATI = NULL; |
| 2623 | PFNGLVERTEXSTREAM4FVATIPROC glad_glVertexStream4fvATI; | 2624 | PFNGLVERTEXSTREAM4IATIPROC glad_glVertexStream4iATI = NULL; |
| 2624 | PFNGLVERTEXSTREAM4DATIPROC glad_glVertexStream4dATI; | 2625 | PFNGLVERTEXSTREAM4IVATIPROC glad_glVertexStream4ivATI = NULL; |
| 2625 | PFNGLVERTEXSTREAM4DVATIPROC glad_glVertexStream4dvATI; | 2626 | PFNGLVERTEXSTREAM4FATIPROC glad_glVertexStream4fATI = NULL; |
| 2626 | PFNGLNORMALSTREAM3BATIPROC glad_glNormalStream3bATI; | 2627 | PFNGLVERTEXSTREAM4FVATIPROC glad_glVertexStream4fvATI = NULL; |
| 2627 | PFNGLNORMALSTREAM3BVATIPROC glad_glNormalStream3bvATI; | 2628 | PFNGLVERTEXSTREAM4DATIPROC glad_glVertexStream4dATI = NULL; |
| 2628 | PFNGLNORMALSTREAM3SATIPROC glad_glNormalStream3sATI; | 2629 | PFNGLVERTEXSTREAM4DVATIPROC glad_glVertexStream4dvATI = NULL; |
| 2629 | PFNGLNORMALSTREAM3SVATIPROC glad_glNormalStream3svATI; | 2630 | PFNGLNORMALSTREAM3BATIPROC glad_glNormalStream3bATI = NULL; |
| 2630 | PFNGLNORMALSTREAM3IATIPROC glad_glNormalStream3iATI; | 2631 | PFNGLNORMALSTREAM3BVATIPROC glad_glNormalStream3bvATI = NULL; |
| 2631 | PFNGLNORMALSTREAM3IVATIPROC glad_glNormalStream3ivATI; | 2632 | PFNGLNORMALSTREAM3SATIPROC glad_glNormalStream3sATI = NULL; |
| 2632 | PFNGLNORMALSTREAM3FATIPROC glad_glNormalStream3fATI; | 2633 | PFNGLNORMALSTREAM3SVATIPROC glad_glNormalStream3svATI = NULL; |
| 2633 | PFNGLNORMALSTREAM3FVATIPROC glad_glNormalStream3fvATI; | 2634 | PFNGLNORMALSTREAM3IATIPROC glad_glNormalStream3iATI = NULL; |
| 2634 | PFNGLNORMALSTREAM3DATIPROC glad_glNormalStream3dATI; | 2635 | PFNGLNORMALSTREAM3IVATIPROC glad_glNormalStream3ivATI = NULL; |
| 2635 | PFNGLNORMALSTREAM3DVATIPROC glad_glNormalStream3dvATI; | 2636 | PFNGLNORMALSTREAM3FATIPROC glad_glNormalStream3fATI = NULL; |
| 2636 | PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC glad_glClientActiveVertexStreamATI; | 2637 | PFNGLNORMALSTREAM3FVATIPROC glad_glNormalStream3fvATI = NULL; |
| 2637 | PFNGLVERTEXBLENDENVIATIPROC glad_glVertexBlendEnviATI; | 2638 | PFNGLNORMALSTREAM3DATIPROC glad_glNormalStream3dATI = NULL; |
| 2638 | PFNGLVERTEXBLENDENVFATIPROC glad_glVertexBlendEnvfATI; | 2639 | PFNGLNORMALSTREAM3DVATIPROC glad_glNormalStream3dvATI = NULL; |
| 2639 | PFNGLEGLIMAGETARGETTEXSTORAGEEXTPROC glad_glEGLImageTargetTexStorageEXT; | 2640 | PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC glad_glClientActiveVertexStreamATI = NULL; |
| 2640 | PFNGLEGLIMAGETARGETTEXTURESTORAGEEXTPROC glad_glEGLImageTargetTextureStorageEXT; | 2641 | PFNGLVERTEXBLENDENVIATIPROC glad_glVertexBlendEnviATI = NULL; |
| 2641 | PFNGLUNIFORMBUFFEREXTPROC glad_glUniformBufferEXT; | 2642 | PFNGLVERTEXBLENDENVFATIPROC glad_glVertexBlendEnvfATI = NULL; |
| 2642 | PFNGLGETUNIFORMBUFFERSIZEEXTPROC glad_glGetUniformBufferSizeEXT; | 2643 | PFNGLEGLIMAGETARGETTEXSTORAGEEXTPROC glad_glEGLImageTargetTexStorageEXT = NULL; |
| 2643 | PFNGLGETUNIFORMOFFSETEXTPROC glad_glGetUniformOffsetEXT; | 2644 | PFNGLEGLIMAGETARGETTEXTURESTORAGEEXTPROC glad_glEGLImageTargetTextureStorageEXT = NULL; |
| 2644 | PFNGLBLENDCOLOREXTPROC glad_glBlendColorEXT; | 2645 | PFNGLUNIFORMBUFFEREXTPROC glad_glUniformBufferEXT = NULL; |
| 2645 | PFNGLBLENDEQUATIONSEPARATEEXTPROC glad_glBlendEquationSeparateEXT; | 2646 | PFNGLGETUNIFORMBUFFERSIZEEXTPROC glad_glGetUniformBufferSizeEXT = NULL; |
| 2646 | PFNGLBLENDFUNCSEPARATEEXTPROC glad_glBlendFuncSeparateEXT; | 2647 | PFNGLGETUNIFORMOFFSETEXTPROC glad_glGetUniformOffsetEXT = NULL; |
| 2647 | PFNGLBLENDEQUATIONEXTPROC glad_glBlendEquationEXT; | 2648 | PFNGLBLENDCOLOREXTPROC glad_glBlendColorEXT = NULL; |
| 2648 | PFNGLCOLORSUBTABLEEXTPROC glad_glColorSubTableEXT; | 2649 | PFNGLBLENDEQUATIONSEPARATEEXTPROC glad_glBlendEquationSeparateEXT = NULL; |
| 2649 | PFNGLCOPYCOLORSUBTABLEEXTPROC glad_glCopyColorSubTableEXT; | 2650 | PFNGLBLENDFUNCSEPARATEEXTPROC glad_glBlendFuncSeparateEXT = NULL; |
| 2650 | PFNGLLOCKARRAYSEXTPROC glad_glLockArraysEXT; | 2651 | PFNGLBLENDEQUATIONEXTPROC glad_glBlendEquationEXT = NULL; |
| 2651 | PFNGLUNLOCKARRAYSEXTPROC glad_glUnlockArraysEXT; | 2652 | PFNGLCOLORSUBTABLEEXTPROC glad_glColorSubTableEXT = NULL; |
| 2652 | PFNGLCONVOLUTIONFILTER1DEXTPROC glad_glConvolutionFilter1DEXT; | 2653 | PFNGLCOPYCOLORSUBTABLEEXTPROC glad_glCopyColorSubTableEXT = NULL; |
| 2653 | PFNGLCONVOLUTIONFILTER2DEXTPROC glad_glConvolutionFilter2DEXT; | 2654 | PFNGLLOCKARRAYSEXTPROC glad_glLockArraysEXT = NULL; |
| 2654 | PFNGLCONVOLUTIONPARAMETERFEXTPROC glad_glConvolutionParameterfEXT; | 2655 | PFNGLUNLOCKARRAYSEXTPROC glad_glUnlockArraysEXT = NULL; |
| 2655 | PFNGLCONVOLUTIONPARAMETERFVEXTPROC glad_glConvolutionParameterfvEXT; | 2656 | PFNGLCONVOLUTIONFILTER1DEXTPROC glad_glConvolutionFilter1DEXT = NULL; |
| 2656 | PFNGLCONVOLUTIONPARAMETERIEXTPROC glad_glConvolutionParameteriEXT; | 2657 | PFNGLCONVOLUTIONFILTER2DEXTPROC glad_glConvolutionFilter2DEXT = NULL; |
| 2657 | PFNGLCONVOLUTIONPARAMETERIVEXTPROC glad_glConvolutionParameterivEXT; | 2658 | PFNGLCONVOLUTIONPARAMETERFEXTPROC glad_glConvolutionParameterfEXT = NULL; |
| 2658 | PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC glad_glCopyConvolutionFilter1DEXT; | 2659 | PFNGLCONVOLUTIONPARAMETERFVEXTPROC glad_glConvolutionParameterfvEXT = NULL; |
| 2659 | PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC glad_glCopyConvolutionFilter2DEXT; | 2660 | PFNGLCONVOLUTIONPARAMETERIEXTPROC glad_glConvolutionParameteriEXT = NULL; |
| 2660 | PFNGLGETCONVOLUTIONFILTEREXTPROC glad_glGetConvolutionFilterEXT; | 2661 | PFNGLCONVOLUTIONPARAMETERIVEXTPROC glad_glConvolutionParameterivEXT = NULL; |
| 2661 | PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC glad_glGetConvolutionParameterfvEXT; | 2662 | PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC glad_glCopyConvolutionFilter1DEXT = NULL; |
| 2662 | PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC glad_glGetConvolutionParameterivEXT; | 2663 | PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC glad_glCopyConvolutionFilter2DEXT = NULL; |
| 2663 | PFNGLGETSEPARABLEFILTEREXTPROC glad_glGetSeparableFilterEXT; | 2664 | PFNGLGETCONVOLUTIONFILTEREXTPROC glad_glGetConvolutionFilterEXT = NULL; |
| 2664 | PFNGLSEPARABLEFILTER2DEXTPROC glad_glSeparableFilter2DEXT; | 2665 | PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC glad_glGetConvolutionParameterfvEXT = NULL; |
| 2665 | PFNGLTANGENT3BEXTPROC glad_glTangent3bEXT; | 2666 | PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC glad_glGetConvolutionParameterivEXT = NULL; |
| 2666 | PFNGLTANGENT3BVEXTPROC glad_glTangent3bvEXT; | 2667 | PFNGLGETSEPARABLEFILTEREXTPROC glad_glGetSeparableFilterEXT = NULL; |
| 2667 | PFNGLTANGENT3DEXTPROC glad_glTangent3dEXT; | 2668 | PFNGLSEPARABLEFILTER2DEXTPROC glad_glSeparableFilter2DEXT = NULL; |
| 2668 | PFNGLTANGENT3DVEXTPROC glad_glTangent3dvEXT; | 2669 | PFNGLTANGENT3BEXTPROC glad_glTangent3bEXT = NULL; |
| 2669 | PFNGLTANGENT3FEXTPROC glad_glTangent3fEXT; | 2670 | PFNGLTANGENT3BVEXTPROC glad_glTangent3bvEXT = NULL; |
| 2670 | PFNGLTANGENT3FVEXTPROC glad_glTangent3fvEXT; | 2671 | PFNGLTANGENT3DEXTPROC glad_glTangent3dEXT = NULL; |
| 2671 | PFNGLTANGENT3IEXTPROC glad_glTangent3iEXT; | 2672 | PFNGLTANGENT3DVEXTPROC glad_glTangent3dvEXT = NULL; |
| 2672 | PFNGLTANGENT3IVEXTPROC glad_glTangent3ivEXT; | 2673 | PFNGLTANGENT3FEXTPROC glad_glTangent3fEXT = NULL; |
| 2673 | PFNGLTANGENT3SEXTPROC glad_glTangent3sEXT; | 2674 | PFNGLTANGENT3FVEXTPROC glad_glTangent3fvEXT = NULL; |
| 2674 | PFNGLTANGENT3SVEXTPROC glad_glTangent3svEXT; | 2675 | PFNGLTANGENT3IEXTPROC glad_glTangent3iEXT = NULL; |
| 2675 | PFNGLBINORMAL3BEXTPROC glad_glBinormal3bEXT; | 2676 | PFNGLTANGENT3IVEXTPROC glad_glTangent3ivEXT = NULL; |
| 2676 | PFNGLBINORMAL3BVEXTPROC glad_glBinormal3bvEXT; | 2677 | PFNGLTANGENT3SEXTPROC glad_glTangent3sEXT = NULL; |
| 2677 | PFNGLBINORMAL3DEXTPROC glad_glBinormal3dEXT; | 2678 | PFNGLTANGENT3SVEXTPROC glad_glTangent3svEXT = NULL; |
| 2678 | PFNGLBINORMAL3DVEXTPROC glad_glBinormal3dvEXT; | 2679 | PFNGLBINORMAL3BEXTPROC glad_glBinormal3bEXT = NULL; |
| 2679 | PFNGLBINORMAL3FEXTPROC glad_glBinormal3fEXT; | 2680 | PFNGLBINORMAL3BVEXTPROC glad_glBinormal3bvEXT = NULL; |
| 2680 | PFNGLBINORMAL3FVEXTPROC glad_glBinormal3fvEXT; | 2681 | PFNGLBINORMAL3DEXTPROC glad_glBinormal3dEXT = NULL; |
| 2681 | PFNGLBINORMAL3IEXTPROC glad_glBinormal3iEXT; | 2682 | PFNGLBINORMAL3DVEXTPROC glad_glBinormal3dvEXT = NULL; |
| 2682 | PFNGLBINORMAL3IVEXTPROC glad_glBinormal3ivEXT; | 2683 | PFNGLBINORMAL3FEXTPROC glad_glBinormal3fEXT = NULL; |
| 2683 | PFNGLBINORMAL3SEXTPROC glad_glBinormal3sEXT; | 2684 | PFNGLBINORMAL3FVEXTPROC glad_glBinormal3fvEXT = NULL; |
| 2684 | PFNGLBINORMAL3SVEXTPROC glad_glBinormal3svEXT; | 2685 | PFNGLBINORMAL3IEXTPROC glad_glBinormal3iEXT = NULL; |
| 2685 | PFNGLTANGENTPOINTEREXTPROC glad_glTangentPointerEXT; | 2686 | PFNGLBINORMAL3IVEXTPROC glad_glBinormal3ivEXT = NULL; |
| 2686 | PFNGLBINORMALPOINTEREXTPROC glad_glBinormalPointerEXT; | 2687 | PFNGLBINORMAL3SEXTPROC glad_glBinormal3sEXT = NULL; |
| 2687 | PFNGLCOPYTEXIMAGE1DEXTPROC glad_glCopyTexImage1DEXT; | 2688 | PFNGLBINORMAL3SVEXTPROC glad_glBinormal3svEXT = NULL; |
| 2688 | PFNGLCOPYTEXIMAGE2DEXTPROC glad_glCopyTexImage2DEXT; | 2689 | PFNGLTANGENTPOINTEREXTPROC glad_glTangentPointerEXT = NULL; |
| 2689 | PFNGLCOPYTEXSUBIMAGE1DEXTPROC glad_glCopyTexSubImage1DEXT; | 2690 | PFNGLBINORMALPOINTEREXTPROC glad_glBinormalPointerEXT = NULL; |
| 2690 | PFNGLCOPYTEXSUBIMAGE2DEXTPROC glad_glCopyTexSubImage2DEXT; | 2691 | PFNGLCOPYTEXIMAGE1DEXTPROC glad_glCopyTexImage1DEXT = NULL; |
| 2691 | PFNGLCOPYTEXSUBIMAGE3DEXTPROC glad_glCopyTexSubImage3DEXT; | 2692 | PFNGLCOPYTEXIMAGE2DEXTPROC glad_glCopyTexImage2DEXT = NULL; |
| 2692 | PFNGLCULLPARAMETERDVEXTPROC glad_glCullParameterdvEXT; | 2693 | PFNGLCOPYTEXSUBIMAGE1DEXTPROC glad_glCopyTexSubImage1DEXT = NULL; |
| 2693 | PFNGLCULLPARAMETERFVEXTPROC glad_glCullParameterfvEXT; | 2694 | PFNGLCOPYTEXSUBIMAGE2DEXTPROC glad_glCopyTexSubImage2DEXT = NULL; |
| 2694 | PFNGLLABELOBJECTEXTPROC glad_glLabelObjectEXT; | 2695 | PFNGLCOPYTEXSUBIMAGE3DEXTPROC glad_glCopyTexSubImage3DEXT = NULL; |
| 2695 | PFNGLGETOBJECTLABELEXTPROC glad_glGetObjectLabelEXT; | 2696 | PFNGLCULLPARAMETERDVEXTPROC glad_glCullParameterdvEXT = NULL; |
| 2696 | PFNGLINSERTEVENTMARKEREXTPROC glad_glInsertEventMarkerEXT; | 2697 | PFNGLCULLPARAMETERFVEXTPROC glad_glCullParameterfvEXT = NULL; |
| 2697 | PFNGLPUSHGROUPMARKEREXTPROC glad_glPushGroupMarkerEXT; | 2698 | PFNGLLABELOBJECTEXTPROC glad_glLabelObjectEXT = NULL; |
| 2698 | PFNGLPOPGROUPMARKEREXTPROC glad_glPopGroupMarkerEXT; | 2699 | PFNGLGETOBJECTLABELEXTPROC glad_glGetObjectLabelEXT = NULL; |
| 2699 | PFNGLDEPTHBOUNDSEXTPROC glad_glDepthBoundsEXT; | 2700 | PFNGLINSERTEVENTMARKEREXTPROC glad_glInsertEventMarkerEXT = NULL; |
| 2700 | PFNGLMATRIXLOADFEXTPROC glad_glMatrixLoadfEXT; | 2701 | PFNGLPUSHGROUPMARKEREXTPROC glad_glPushGroupMarkerEXT = NULL; |
| 2701 | PFNGLMATRIXLOADDEXTPROC glad_glMatrixLoaddEXT; | 2702 | PFNGLPOPGROUPMARKEREXTPROC glad_glPopGroupMarkerEXT = NULL; |
| 2702 | PFNGLMATRIXMULTFEXTPROC glad_glMatrixMultfEXT; | 2703 | PFNGLDEPTHBOUNDSEXTPROC glad_glDepthBoundsEXT = NULL; |
| 2703 | PFNGLMATRIXMULTDEXTPROC glad_glMatrixMultdEXT; | 2704 | PFNGLMATRIXLOADFEXTPROC glad_glMatrixLoadfEXT = NULL; |
| 2704 | PFNGLMATRIXLOADIDENTITYEXTPROC glad_glMatrixLoadIdentityEXT; | 2705 | PFNGLMATRIXLOADDEXTPROC glad_glMatrixLoaddEXT = NULL; |
| 2705 | PFNGLMATRIXROTATEFEXTPROC glad_glMatrixRotatefEXT; | 2706 | PFNGLMATRIXMULTFEXTPROC glad_glMatrixMultfEXT = NULL; |
| 2706 | PFNGLMATRIXROTATEDEXTPROC glad_glMatrixRotatedEXT; | 2707 | PFNGLMATRIXMULTDEXTPROC glad_glMatrixMultdEXT = NULL; |
| 2707 | PFNGLMATRIXSCALEFEXTPROC glad_glMatrixScalefEXT; | 2708 | PFNGLMATRIXLOADIDENTITYEXTPROC glad_glMatrixLoadIdentityEXT = NULL; |
| 2708 | PFNGLMATRIXSCALEDEXTPROC glad_glMatrixScaledEXT; | 2709 | PFNGLMATRIXROTATEFEXTPROC glad_glMatrixRotatefEXT = NULL; |
| 2709 | PFNGLMATRIXTRANSLATEFEXTPROC glad_glMatrixTranslatefEXT; | 2710 | PFNGLMATRIXROTATEDEXTPROC glad_glMatrixRotatedEXT = NULL; |
| 2710 | PFNGLMATRIXTRANSLATEDEXTPROC glad_glMatrixTranslatedEXT; | 2711 | PFNGLMATRIXSCALEFEXTPROC glad_glMatrixScalefEXT = NULL; |
| 2711 | PFNGLMATRIXFRUSTUMEXTPROC glad_glMatrixFrustumEXT; | 2712 | PFNGLMATRIXSCALEDEXTPROC glad_glMatrixScaledEXT = NULL; |
| 2712 | PFNGLMATRIXORTHOEXTPROC glad_glMatrixOrthoEXT; | 2713 | PFNGLMATRIXTRANSLATEFEXTPROC glad_glMatrixTranslatefEXT = NULL; |
| 2713 | PFNGLMATRIXPOPEXTPROC glad_glMatrixPopEXT; | 2714 | PFNGLMATRIXTRANSLATEDEXTPROC glad_glMatrixTranslatedEXT = NULL; |
| 2714 | PFNGLMATRIXPUSHEXTPROC glad_glMatrixPushEXT; | 2715 | PFNGLMATRIXFRUSTUMEXTPROC glad_glMatrixFrustumEXT = NULL; |
| 2715 | PFNGLCLIENTATTRIBDEFAULTEXTPROC glad_glClientAttribDefaultEXT; | 2716 | PFNGLMATRIXORTHOEXTPROC glad_glMatrixOrthoEXT = NULL; |
| 2716 | PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC glad_glPushClientAttribDefaultEXT; | 2717 | PFNGLMATRIXPOPEXTPROC glad_glMatrixPopEXT = NULL; |
| 2717 | PFNGLTEXTUREPARAMETERFEXTPROC glad_glTextureParameterfEXT; | 2718 | PFNGLMATRIXPUSHEXTPROC glad_glMatrixPushEXT = NULL; |
| 2718 | PFNGLTEXTUREPARAMETERFVEXTPROC glad_glTextureParameterfvEXT; | 2719 | PFNGLCLIENTATTRIBDEFAULTEXTPROC glad_glClientAttribDefaultEXT = NULL; |
| 2719 | PFNGLTEXTUREPARAMETERIEXTPROC glad_glTextureParameteriEXT; | 2720 | PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC glad_glPushClientAttribDefaultEXT = NULL; |
| 2720 | PFNGLTEXTUREPARAMETERIVEXTPROC glad_glTextureParameterivEXT; | 2721 | PFNGLTEXTUREPARAMETERFEXTPROC glad_glTextureParameterfEXT = NULL; |
| 2721 | PFNGLTEXTUREIMAGE1DEXTPROC glad_glTextureImage1DEXT; | 2722 | PFNGLTEXTUREPARAMETERFVEXTPROC glad_glTextureParameterfvEXT = NULL; |
| 2722 | PFNGLTEXTUREIMAGE2DEXTPROC glad_glTextureImage2DEXT; | 2723 | PFNGLTEXTUREPARAMETERIEXTPROC glad_glTextureParameteriEXT = NULL; |
| 2723 | PFNGLTEXTURESUBIMAGE1DEXTPROC glad_glTextureSubImage1DEXT; | 2724 | PFNGLTEXTUREPARAMETERIVEXTPROC glad_glTextureParameterivEXT = NULL; |
| 2724 | PFNGLTEXTURESUBIMAGE2DEXTPROC glad_glTextureSubImage2DEXT; | 2725 | PFNGLTEXTUREIMAGE1DEXTPROC glad_glTextureImage1DEXT = NULL; |
| 2725 | PFNGLCOPYTEXTUREIMAGE1DEXTPROC glad_glCopyTextureImage1DEXT; | 2726 | PFNGLTEXTUREIMAGE2DEXTPROC glad_glTextureImage2DEXT = NULL; |
| 2726 | PFNGLCOPYTEXTUREIMAGE2DEXTPROC glad_glCopyTextureImage2DEXT; | 2727 | PFNGLTEXTURESUBIMAGE1DEXTPROC glad_glTextureSubImage1DEXT = NULL; |
| 2727 | PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC glad_glCopyTextureSubImage1DEXT; | 2728 | PFNGLTEXTURESUBIMAGE2DEXTPROC glad_glTextureSubImage2DEXT = NULL; |
| 2728 | PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC glad_glCopyTextureSubImage2DEXT; | 2729 | PFNGLCOPYTEXTUREIMAGE1DEXTPROC glad_glCopyTextureImage1DEXT = NULL; |
| 2729 | PFNGLGETTEXTUREIMAGEEXTPROC glad_glGetTextureImageEXT; | 2730 | PFNGLCOPYTEXTUREIMAGE2DEXTPROC glad_glCopyTextureImage2DEXT = NULL; |
| 2730 | PFNGLGETTEXTUREPARAMETERFVEXTPROC glad_glGetTextureParameterfvEXT; | 2731 | PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC glad_glCopyTextureSubImage1DEXT = NULL; |
| 2731 | PFNGLGETTEXTUREPARAMETERIVEXTPROC glad_glGetTextureParameterivEXT; | 2732 | PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC glad_glCopyTextureSubImage2DEXT = NULL; |
| 2732 | PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC glad_glGetTextureLevelParameterfvEXT; | 2733 | PFNGLGETTEXTUREIMAGEEXTPROC glad_glGetTextureImageEXT = NULL; |
| 2733 | PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC glad_glGetTextureLevelParameterivEXT; | 2734 | PFNGLGETTEXTUREPARAMETERFVEXTPROC glad_glGetTextureParameterfvEXT = NULL; |
| 2734 | PFNGLTEXTUREIMAGE3DEXTPROC glad_glTextureImage3DEXT; | 2735 | PFNGLGETTEXTUREPARAMETERIVEXTPROC glad_glGetTextureParameterivEXT = NULL; |
| 2735 | PFNGLTEXTURESUBIMAGE3DEXTPROC glad_glTextureSubImage3DEXT; | 2736 | PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC glad_glGetTextureLevelParameterfvEXT = NULL; |
| 2736 | PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC glad_glCopyTextureSubImage3DEXT; | 2737 | PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC glad_glGetTextureLevelParameterivEXT = NULL; |
| 2737 | PFNGLBINDMULTITEXTUREEXTPROC glad_glBindMultiTextureEXT; | 2738 | PFNGLTEXTUREIMAGE3DEXTPROC glad_glTextureImage3DEXT = NULL; |
| 2738 | PFNGLMULTITEXCOORDPOINTEREXTPROC glad_glMultiTexCoordPointerEXT; | 2739 | PFNGLTEXTURESUBIMAGE3DEXTPROC glad_glTextureSubImage3DEXT = NULL; |
| 2739 | PFNGLMULTITEXENVFEXTPROC glad_glMultiTexEnvfEXT; | 2740 | PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC glad_glCopyTextureSubImage3DEXT = NULL; |
| 2740 | PFNGLMULTITEXENVFVEXTPROC glad_glMultiTexEnvfvEXT; | 2741 | PFNGLBINDMULTITEXTUREEXTPROC glad_glBindMultiTextureEXT = NULL; |
| 2741 | PFNGLMULTITEXENVIEXTPROC glad_glMultiTexEnviEXT; | 2742 | PFNGLMULTITEXCOORDPOINTEREXTPROC glad_glMultiTexCoordPointerEXT = NULL; |
| 2742 | PFNGLMULTITEXENVIVEXTPROC glad_glMultiTexEnvivEXT; | 2743 | PFNGLMULTITEXENVFEXTPROC glad_glMultiTexEnvfEXT = NULL; |
| 2743 | PFNGLMULTITEXGENDEXTPROC glad_glMultiTexGendEXT; | 2744 | PFNGLMULTITEXENVFVEXTPROC glad_glMultiTexEnvfvEXT = NULL; |
| 2744 | PFNGLMULTITEXGENDVEXTPROC glad_glMultiTexGendvEXT; | 2745 | PFNGLMULTITEXENVIEXTPROC glad_glMultiTexEnviEXT = NULL; |
| 2745 | PFNGLMULTITEXGENFEXTPROC glad_glMultiTexGenfEXT; | 2746 | PFNGLMULTITEXENVIVEXTPROC glad_glMultiTexEnvivEXT = NULL; |
| 2746 | PFNGLMULTITEXGENFVEXTPROC glad_glMultiTexGenfvEXT; | 2747 | PFNGLMULTITEXGENDEXTPROC glad_glMultiTexGendEXT = NULL; |
| 2747 | PFNGLMULTITEXGENIEXTPROC glad_glMultiTexGeniEXT; | 2748 | PFNGLMULTITEXGENDVEXTPROC glad_glMultiTexGendvEXT = NULL; |
| 2748 | PFNGLMULTITEXGENIVEXTPROC glad_glMultiTexGenivEXT; | 2749 | PFNGLMULTITEXGENFEXTPROC glad_glMultiTexGenfEXT = NULL; |
| 2749 | PFNGLGETMULTITEXENVFVEXTPROC glad_glGetMultiTexEnvfvEXT; | 2750 | PFNGLMULTITEXGENFVEXTPROC glad_glMultiTexGenfvEXT = NULL; |
| 2750 | PFNGLGETMULTITEXENVIVEXTPROC glad_glGetMultiTexEnvivEXT; | 2751 | PFNGLMULTITEXGENIEXTPROC glad_glMultiTexGeniEXT = NULL; |
| 2751 | PFNGLGETMULTITEXGENDVEXTPROC glad_glGetMultiTexGendvEXT; | 2752 | PFNGLMULTITEXGENIVEXTPROC glad_glMultiTexGenivEXT = NULL; |
| 2752 | PFNGLGETMULTITEXGENFVEXTPROC glad_glGetMultiTexGenfvEXT; | 2753 | PFNGLGETMULTITEXENVFVEXTPROC glad_glGetMultiTexEnvfvEXT = NULL; |
| 2753 | PFNGLGETMULTITEXGENIVEXTPROC glad_glGetMultiTexGenivEXT; | 2754 | PFNGLGETMULTITEXENVIVEXTPROC glad_glGetMultiTexEnvivEXT = NULL; |
| 2754 | PFNGLMULTITEXPARAMETERIEXTPROC glad_glMultiTexParameteriEXT; | 2755 | PFNGLGETMULTITEXGENDVEXTPROC glad_glGetMultiTexGendvEXT = NULL; |
| 2755 | PFNGLMULTITEXPARAMETERIVEXTPROC glad_glMultiTexParameterivEXT; | 2756 | PFNGLGETMULTITEXGENFVEXTPROC glad_glGetMultiTexGenfvEXT = NULL; |
| 2756 | PFNGLMULTITEXPARAMETERFEXTPROC glad_glMultiTexParameterfEXT; | 2757 | PFNGLGETMULTITEXGENIVEXTPROC glad_glGetMultiTexGenivEXT = NULL; |
| 2757 | PFNGLMULTITEXPARAMETERFVEXTPROC glad_glMultiTexParameterfvEXT; | 2758 | PFNGLMULTITEXPARAMETERIEXTPROC glad_glMultiTexParameteriEXT = NULL; |
| 2758 | PFNGLMULTITEXIMAGE1DEXTPROC glad_glMultiTexImage1DEXT; | 2759 | PFNGLMULTITEXPARAMETERIVEXTPROC glad_glMultiTexParameterivEXT = NULL; |
| 2759 | PFNGLMULTITEXIMAGE2DEXTPROC glad_glMultiTexImage2DEXT; | 2760 | PFNGLMULTITEXPARAMETERFEXTPROC glad_glMultiTexParameterfEXT = NULL; |
| 2760 | PFNGLMULTITEXSUBIMAGE1DEXTPROC glad_glMultiTexSubImage1DEXT; | 2761 | PFNGLMULTITEXPARAMETERFVEXTPROC glad_glMultiTexParameterfvEXT = NULL; |
| 2761 | PFNGLMULTITEXSUBIMAGE2DEXTPROC glad_glMultiTexSubImage2DEXT; | 2762 | PFNGLMULTITEXIMAGE1DEXTPROC glad_glMultiTexImage1DEXT = NULL; |
| 2762 | PFNGLCOPYMULTITEXIMAGE1DEXTPROC glad_glCopyMultiTexImage1DEXT; | 2763 | PFNGLMULTITEXIMAGE2DEXTPROC glad_glMultiTexImage2DEXT = NULL; |
| 2763 | PFNGLCOPYMULTITEXIMAGE2DEXTPROC glad_glCopyMultiTexImage2DEXT; | 2764 | PFNGLMULTITEXSUBIMAGE1DEXTPROC glad_glMultiTexSubImage1DEXT = NULL; |
| 2764 | PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC glad_glCopyMultiTexSubImage1DEXT; | 2765 | PFNGLMULTITEXSUBIMAGE2DEXTPROC glad_glMultiTexSubImage2DEXT = NULL; |
| 2765 | PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC glad_glCopyMultiTexSubImage2DEXT; | 2766 | PFNGLCOPYMULTITEXIMAGE1DEXTPROC glad_glCopyMultiTexImage1DEXT = NULL; |
| 2766 | PFNGLGETMULTITEXIMAGEEXTPROC glad_glGetMultiTexImageEXT; | 2767 | PFNGLCOPYMULTITEXIMAGE2DEXTPROC glad_glCopyMultiTexImage2DEXT = NULL; |
| 2767 | PFNGLGETMULTITEXPARAMETERFVEXTPROC glad_glGetMultiTexParameterfvEXT; | 2768 | PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC glad_glCopyMultiTexSubImage1DEXT = NULL; |
| 2768 | PFNGLGETMULTITEXPARAMETERIVEXTPROC glad_glGetMultiTexParameterivEXT; | 2769 | PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC glad_glCopyMultiTexSubImage2DEXT = NULL; |
| 2769 | PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC glad_glGetMultiTexLevelParameterfvEXT; | 2770 | PFNGLGETMULTITEXIMAGEEXTPROC glad_glGetMultiTexImageEXT = NULL; |
| 2770 | PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC glad_glGetMultiTexLevelParameterivEXT; | 2771 | PFNGLGETMULTITEXPARAMETERFVEXTPROC glad_glGetMultiTexParameterfvEXT = NULL; |
| 2771 | PFNGLMULTITEXIMAGE3DEXTPROC glad_glMultiTexImage3DEXT; | 2772 | PFNGLGETMULTITEXPARAMETERIVEXTPROC glad_glGetMultiTexParameterivEXT = NULL; |
| 2772 | PFNGLMULTITEXSUBIMAGE3DEXTPROC glad_glMultiTexSubImage3DEXT; | 2773 | PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC glad_glGetMultiTexLevelParameterfvEXT = NULL; |
| 2773 | PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC glad_glCopyMultiTexSubImage3DEXT; | 2774 | PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC glad_glGetMultiTexLevelParameterivEXT = NULL; |
| 2774 | PFNGLENABLECLIENTSTATEINDEXEDEXTPROC glad_glEnableClientStateIndexedEXT; | 2775 | PFNGLMULTITEXIMAGE3DEXTPROC glad_glMultiTexImage3DEXT = NULL; |
| 2775 | PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC glad_glDisableClientStateIndexedEXT; | 2776 | PFNGLMULTITEXSUBIMAGE3DEXTPROC glad_glMultiTexSubImage3DEXT = NULL; |
| 2776 | PFNGLGETFLOATINDEXEDVEXTPROC glad_glGetFloatIndexedvEXT; | 2777 | PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC glad_glCopyMultiTexSubImage3DEXT = NULL; |
| 2777 | PFNGLGETDOUBLEINDEXEDVEXTPROC glad_glGetDoubleIndexedvEXT; | 2778 | PFNGLENABLECLIENTSTATEINDEXEDEXTPROC glad_glEnableClientStateIndexedEXT = NULL; |
| 2778 | PFNGLGETPOINTERINDEXEDVEXTPROC glad_glGetPointerIndexedvEXT; | 2779 | PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC glad_glDisableClientStateIndexedEXT = NULL; |
| 2779 | PFNGLENABLEINDEXEDEXTPROC glad_glEnableIndexedEXT; | 2780 | PFNGLGETFLOATINDEXEDVEXTPROC glad_glGetFloatIndexedvEXT = NULL; |
| 2780 | PFNGLDISABLEINDEXEDEXTPROC glad_glDisableIndexedEXT; | 2781 | PFNGLGETDOUBLEINDEXEDVEXTPROC glad_glGetDoubleIndexedvEXT = NULL; |
| 2781 | PFNGLISENABLEDINDEXEDEXTPROC glad_glIsEnabledIndexedEXT; | 2782 | PFNGLGETPOINTERINDEXEDVEXTPROC glad_glGetPointerIndexedvEXT = NULL; |
| 2782 | PFNGLGETINTEGERINDEXEDVEXTPROC glad_glGetIntegerIndexedvEXT; | 2783 | PFNGLENABLEINDEXEDEXTPROC glad_glEnableIndexedEXT = NULL; |
| 2783 | PFNGLGETBOOLEANINDEXEDVEXTPROC glad_glGetBooleanIndexedvEXT; | 2784 | PFNGLDISABLEINDEXEDEXTPROC glad_glDisableIndexedEXT = NULL; |
| 2784 | PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC glad_glCompressedTextureImage3DEXT; | 2785 | PFNGLISENABLEDINDEXEDEXTPROC glad_glIsEnabledIndexedEXT = NULL; |
| 2785 | PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC glad_glCompressedTextureImage2DEXT; | 2786 | PFNGLGETINTEGERINDEXEDVEXTPROC glad_glGetIntegerIndexedvEXT = NULL; |
| 2786 | PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC glad_glCompressedTextureImage1DEXT; | 2787 | PFNGLGETBOOLEANINDEXEDVEXTPROC glad_glGetBooleanIndexedvEXT = NULL; |
| 2787 | PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC glad_glCompressedTextureSubImage3DEXT; | 2788 | PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC glad_glCompressedTextureImage3DEXT = NULL; |
| 2788 | PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC glad_glCompressedTextureSubImage2DEXT; | 2789 | PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC glad_glCompressedTextureImage2DEXT = NULL; |
| 2789 | PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC glad_glCompressedTextureSubImage1DEXT; | 2790 | PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC glad_glCompressedTextureImage1DEXT = NULL; |
| 2790 | PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC glad_glGetCompressedTextureImageEXT; | 2791 | PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC glad_glCompressedTextureSubImage3DEXT = NULL; |
| 2791 | PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC glad_glCompressedMultiTexImage3DEXT; | 2792 | PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC glad_glCompressedTextureSubImage2DEXT = NULL; |
| 2792 | PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC glad_glCompressedMultiTexImage2DEXT; | 2793 | PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC glad_glCompressedTextureSubImage1DEXT = NULL; |
| 2793 | PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC glad_glCompressedMultiTexImage1DEXT; | 2794 | PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC glad_glGetCompressedTextureImageEXT = NULL; |
| 2794 | PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC glad_glCompressedMultiTexSubImage3DEXT; | 2795 | PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC glad_glCompressedMultiTexImage3DEXT = NULL; |
| 2795 | PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC glad_glCompressedMultiTexSubImage2DEXT; | 2796 | PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC glad_glCompressedMultiTexImage2DEXT = NULL; |
| 2796 | PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC glad_glCompressedMultiTexSubImage1DEXT; | 2797 | PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC glad_glCompressedMultiTexImage1DEXT = NULL; |
| 2797 | PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC glad_glGetCompressedMultiTexImageEXT; | 2798 | PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC glad_glCompressedMultiTexSubImage3DEXT = NULL; |
| 2798 | PFNGLMATRIXLOADTRANSPOSEFEXTPROC glad_glMatrixLoadTransposefEXT; | 2799 | PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC glad_glCompressedMultiTexSubImage2DEXT = NULL; |
| 2799 | PFNGLMATRIXLOADTRANSPOSEDEXTPROC glad_glMatrixLoadTransposedEXT; | 2800 | PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC glad_glCompressedMultiTexSubImage1DEXT = NULL; |
| 2800 | PFNGLMATRIXMULTTRANSPOSEFEXTPROC glad_glMatrixMultTransposefEXT; | 2801 | PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC glad_glGetCompressedMultiTexImageEXT = NULL; |
| 2801 | PFNGLMATRIXMULTTRANSPOSEDEXTPROC glad_glMatrixMultTransposedEXT; | 2802 | PFNGLMATRIXLOADTRANSPOSEFEXTPROC glad_glMatrixLoadTransposefEXT = NULL; |
| 2802 | PFNGLNAMEDBUFFERDATAEXTPROC glad_glNamedBufferDataEXT; | 2803 | PFNGLMATRIXLOADTRANSPOSEDEXTPROC glad_glMatrixLoadTransposedEXT = NULL; |
| 2803 | PFNGLNAMEDBUFFERSUBDATAEXTPROC glad_glNamedBufferSubDataEXT; | 2804 | PFNGLMATRIXMULTTRANSPOSEFEXTPROC glad_glMatrixMultTransposefEXT = NULL; |
| 2804 | PFNGLMAPNAMEDBUFFEREXTPROC glad_glMapNamedBufferEXT; | 2805 | PFNGLMATRIXMULTTRANSPOSEDEXTPROC glad_glMatrixMultTransposedEXT = NULL; |
| 2805 | PFNGLUNMAPNAMEDBUFFEREXTPROC glad_glUnmapNamedBufferEXT; | 2806 | PFNGLNAMEDBUFFERDATAEXTPROC glad_glNamedBufferDataEXT = NULL; |
| 2806 | PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC glad_glGetNamedBufferParameterivEXT; | 2807 | PFNGLNAMEDBUFFERSUBDATAEXTPROC glad_glNamedBufferSubDataEXT = NULL; |
| 2807 | PFNGLGETNAMEDBUFFERPOINTERVEXTPROC glad_glGetNamedBufferPointervEXT; | 2808 | PFNGLMAPNAMEDBUFFEREXTPROC glad_glMapNamedBufferEXT = NULL; |
| 2808 | PFNGLGETNAMEDBUFFERSUBDATAEXTPROC glad_glGetNamedBufferSubDataEXT; | 2809 | PFNGLUNMAPNAMEDBUFFEREXTPROC glad_glUnmapNamedBufferEXT = NULL; |
| 2809 | PFNGLPROGRAMUNIFORM1FEXTPROC glad_glProgramUniform1fEXT; | 2810 | PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC glad_glGetNamedBufferParameterivEXT = NULL; |
| 2810 | PFNGLPROGRAMUNIFORM2FEXTPROC glad_glProgramUniform2fEXT; | 2811 | PFNGLGETNAMEDBUFFERPOINTERVEXTPROC glad_glGetNamedBufferPointervEXT = NULL; |
| 2811 | PFNGLPROGRAMUNIFORM3FEXTPROC glad_glProgramUniform3fEXT; | 2812 | PFNGLGETNAMEDBUFFERSUBDATAEXTPROC glad_glGetNamedBufferSubDataEXT = NULL; |
| 2812 | PFNGLPROGRAMUNIFORM4FEXTPROC glad_glProgramUniform4fEXT; | 2813 | PFNGLPROGRAMUNIFORM1FEXTPROC glad_glProgramUniform1fEXT = NULL; |
| 2813 | PFNGLPROGRAMUNIFORM1IEXTPROC glad_glProgramUniform1iEXT; | 2814 | PFNGLPROGRAMUNIFORM2FEXTPROC glad_glProgramUniform2fEXT = NULL; |
| 2814 | PFNGLPROGRAMUNIFORM2IEXTPROC glad_glProgramUniform2iEXT; | 2815 | PFNGLPROGRAMUNIFORM3FEXTPROC glad_glProgramUniform3fEXT = NULL; |
| 2815 | PFNGLPROGRAMUNIFORM3IEXTPROC glad_glProgramUniform3iEXT; | 2816 | PFNGLPROGRAMUNIFORM4FEXTPROC glad_glProgramUniform4fEXT = NULL; |
| 2816 | PFNGLPROGRAMUNIFORM4IEXTPROC glad_glProgramUniform4iEXT; | 2817 | PFNGLPROGRAMUNIFORM1IEXTPROC glad_glProgramUniform1iEXT = NULL; |
| 2817 | PFNGLPROGRAMUNIFORM1FVEXTPROC glad_glProgramUniform1fvEXT; | 2818 | PFNGLPROGRAMUNIFORM2IEXTPROC glad_glProgramUniform2iEXT = NULL; |
| 2818 | PFNGLPROGRAMUNIFORM2FVEXTPROC glad_glProgramUniform2fvEXT; | 2819 | PFNGLPROGRAMUNIFORM3IEXTPROC glad_glProgramUniform3iEXT = NULL; |
| 2819 | PFNGLPROGRAMUNIFORM3FVEXTPROC glad_glProgramUniform3fvEXT; | 2820 | PFNGLPROGRAMUNIFORM4IEXTPROC glad_glProgramUniform4iEXT = NULL; |
| 2820 | PFNGLPROGRAMUNIFORM4FVEXTPROC glad_glProgramUniform4fvEXT; | 2821 | PFNGLPROGRAMUNIFORM1FVEXTPROC glad_glProgramUniform1fvEXT = NULL; |
| 2821 | PFNGLPROGRAMUNIFORM1IVEXTPROC glad_glProgramUniform1ivEXT; | 2822 | PFNGLPROGRAMUNIFORM2FVEXTPROC glad_glProgramUniform2fvEXT = NULL; |
| 2822 | PFNGLPROGRAMUNIFORM2IVEXTPROC glad_glProgramUniform2ivEXT; | 2823 | PFNGLPROGRAMUNIFORM3FVEXTPROC glad_glProgramUniform3fvEXT = NULL; |
| 2823 | PFNGLPROGRAMUNIFORM3IVEXTPROC glad_glProgramUniform3ivEXT; | 2824 | PFNGLPROGRAMUNIFORM4FVEXTPROC glad_glProgramUniform4fvEXT = NULL; |
| 2824 | PFNGLPROGRAMUNIFORM4IVEXTPROC glad_glProgramUniform4ivEXT; | 2825 | PFNGLPROGRAMUNIFORM1IVEXTPROC glad_glProgramUniform1ivEXT = NULL; |
| 2825 | PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC glad_glProgramUniformMatrix2fvEXT; | 2826 | PFNGLPROGRAMUNIFORM2IVEXTPROC glad_glProgramUniform2ivEXT = NULL; |
| 2826 | PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC glad_glProgramUniformMatrix3fvEXT; | 2827 | PFNGLPROGRAMUNIFORM3IVEXTPROC glad_glProgramUniform3ivEXT = NULL; |
| 2827 | PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC glad_glProgramUniformMatrix4fvEXT; | 2828 | PFNGLPROGRAMUNIFORM4IVEXTPROC glad_glProgramUniform4ivEXT = NULL; |
| 2828 | PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC glad_glProgramUniformMatrix2x3fvEXT; | 2829 | PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC glad_glProgramUniformMatrix2fvEXT = NULL; |
| 2829 | PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC glad_glProgramUniformMatrix3x2fvEXT; | 2830 | PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC glad_glProgramUniformMatrix3fvEXT = NULL; |
| 2830 | PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC glad_glProgramUniformMatrix2x4fvEXT; | 2831 | PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC glad_glProgramUniformMatrix4fvEXT = NULL; |
| 2831 | PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC glad_glProgramUniformMatrix4x2fvEXT; | 2832 | PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC glad_glProgramUniformMatrix2x3fvEXT = NULL; |
| 2832 | PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC glad_glProgramUniformMatrix3x4fvEXT; | 2833 | PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC glad_glProgramUniformMatrix3x2fvEXT = NULL; |
| 2833 | PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC glad_glProgramUniformMatrix4x3fvEXT; | 2834 | PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC glad_glProgramUniformMatrix2x4fvEXT = NULL; |
| 2834 | PFNGLTEXTUREBUFFEREXTPROC glad_glTextureBufferEXT; | 2835 | PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC glad_glProgramUniformMatrix4x2fvEXT = NULL; |
| 2835 | PFNGLMULTITEXBUFFEREXTPROC glad_glMultiTexBufferEXT; | 2836 | PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC glad_glProgramUniformMatrix3x4fvEXT = NULL; |
| 2836 | PFNGLTEXTUREPARAMETERIIVEXTPROC glad_glTextureParameterIivEXT; | 2837 | PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC glad_glProgramUniformMatrix4x3fvEXT = NULL; |
| 2837 | PFNGLTEXTUREPARAMETERIUIVEXTPROC glad_glTextureParameterIuivEXT; | 2838 | PFNGLTEXTUREBUFFEREXTPROC glad_glTextureBufferEXT = NULL; |
| 2838 | PFNGLGETTEXTUREPARAMETERIIVEXTPROC glad_glGetTextureParameterIivEXT; | 2839 | PFNGLMULTITEXBUFFEREXTPROC glad_glMultiTexBufferEXT = NULL; |
| 2839 | PFNGLGETTEXTUREPARAMETERIUIVEXTPROC glad_glGetTextureParameterIuivEXT; | 2840 | PFNGLTEXTUREPARAMETERIIVEXTPROC glad_glTextureParameterIivEXT = NULL; |
| 2840 | PFNGLMULTITEXPARAMETERIIVEXTPROC glad_glMultiTexParameterIivEXT; | 2841 | PFNGLTEXTUREPARAMETERIUIVEXTPROC glad_glTextureParameterIuivEXT = NULL; |
| 2841 | PFNGLMULTITEXPARAMETERIUIVEXTPROC glad_glMultiTexParameterIuivEXT; | 2842 | PFNGLGETTEXTUREPARAMETERIIVEXTPROC glad_glGetTextureParameterIivEXT = NULL; |
| 2842 | PFNGLGETMULTITEXPARAMETERIIVEXTPROC glad_glGetMultiTexParameterIivEXT; | 2843 | PFNGLGETTEXTUREPARAMETERIUIVEXTPROC glad_glGetTextureParameterIuivEXT = NULL; |
| 2843 | PFNGLGETMULTITEXPARAMETERIUIVEXTPROC glad_glGetMultiTexParameterIuivEXT; | 2844 | PFNGLMULTITEXPARAMETERIIVEXTPROC glad_glMultiTexParameterIivEXT = NULL; |
| 2844 | PFNGLPROGRAMUNIFORM1UIEXTPROC glad_glProgramUniform1uiEXT; | 2845 | PFNGLMULTITEXPARAMETERIUIVEXTPROC glad_glMultiTexParameterIuivEXT = NULL; |
| 2845 | PFNGLPROGRAMUNIFORM2UIEXTPROC glad_glProgramUniform2uiEXT; | 2846 | PFNGLGETMULTITEXPARAMETERIIVEXTPROC glad_glGetMultiTexParameterIivEXT = NULL; |
| 2846 | PFNGLPROGRAMUNIFORM3UIEXTPROC glad_glProgramUniform3uiEXT; | 2847 | PFNGLGETMULTITEXPARAMETERIUIVEXTPROC glad_glGetMultiTexParameterIuivEXT = NULL; |
| 2847 | PFNGLPROGRAMUNIFORM4UIEXTPROC glad_glProgramUniform4uiEXT; | 2848 | PFNGLPROGRAMUNIFORM1UIEXTPROC glad_glProgramUniform1uiEXT = NULL; |
| 2848 | PFNGLPROGRAMUNIFORM1UIVEXTPROC glad_glProgramUniform1uivEXT; | 2849 | PFNGLPROGRAMUNIFORM2UIEXTPROC glad_glProgramUniform2uiEXT = NULL; |
| 2849 | PFNGLPROGRAMUNIFORM2UIVEXTPROC glad_glProgramUniform2uivEXT; | 2850 | PFNGLPROGRAMUNIFORM3UIEXTPROC glad_glProgramUniform3uiEXT = NULL; |
| 2850 | PFNGLPROGRAMUNIFORM3UIVEXTPROC glad_glProgramUniform3uivEXT; | 2851 | PFNGLPROGRAMUNIFORM4UIEXTPROC glad_glProgramUniform4uiEXT = NULL; |
| 2851 | PFNGLPROGRAMUNIFORM4UIVEXTPROC glad_glProgramUniform4uivEXT; | 2852 | PFNGLPROGRAMUNIFORM1UIVEXTPROC glad_glProgramUniform1uivEXT = NULL; |
| 2852 | PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC glad_glNamedProgramLocalParameters4fvEXT; | 2853 | PFNGLPROGRAMUNIFORM2UIVEXTPROC glad_glProgramUniform2uivEXT = NULL; |
| 2853 | PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC glad_glNamedProgramLocalParameterI4iEXT; | 2854 | PFNGLPROGRAMUNIFORM3UIVEXTPROC glad_glProgramUniform3uivEXT = NULL; |
| 2854 | PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC glad_glNamedProgramLocalParameterI4ivEXT; | 2855 | PFNGLPROGRAMUNIFORM4UIVEXTPROC glad_glProgramUniform4uivEXT = NULL; |
| 2855 | PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC glad_glNamedProgramLocalParametersI4ivEXT; | 2856 | PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC glad_glNamedProgramLocalParameters4fvEXT = NULL; |
| 2856 | PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC glad_glNamedProgramLocalParameterI4uiEXT; | 2857 | PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC glad_glNamedProgramLocalParameterI4iEXT = NULL; |
| 2857 | PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC glad_glNamedProgramLocalParameterI4uivEXT; | 2858 | PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC glad_glNamedProgramLocalParameterI4ivEXT = NULL; |
| 2858 | PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC glad_glNamedProgramLocalParametersI4uivEXT; | 2859 | PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC glad_glNamedProgramLocalParametersI4ivEXT = NULL; |
| 2859 | PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC glad_glGetNamedProgramLocalParameterIivEXT; | 2860 | PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC glad_glNamedProgramLocalParameterI4uiEXT = NULL; |
| 2860 | PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC glad_glGetNamedProgramLocalParameterIuivEXT; | 2861 | PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC glad_glNamedProgramLocalParameterI4uivEXT = NULL; |
| 2861 | PFNGLENABLECLIENTSTATEIEXTPROC glad_glEnableClientStateiEXT; | 2862 | PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC glad_glNamedProgramLocalParametersI4uivEXT = NULL; |
| 2862 | PFNGLDISABLECLIENTSTATEIEXTPROC glad_glDisableClientStateiEXT; | 2863 | PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC glad_glGetNamedProgramLocalParameterIivEXT = NULL; |
| 2863 | PFNGLGETFLOATI_VEXTPROC glad_glGetFloati_vEXT; | 2864 | PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC glad_glGetNamedProgramLocalParameterIuivEXT = NULL; |
| 2864 | PFNGLGETDOUBLEI_VEXTPROC glad_glGetDoublei_vEXT; | 2865 | PFNGLENABLECLIENTSTATEIEXTPROC glad_glEnableClientStateiEXT = NULL; |
| 2865 | PFNGLGETPOINTERI_VEXTPROC glad_glGetPointeri_vEXT; | 2866 | PFNGLDISABLECLIENTSTATEIEXTPROC glad_glDisableClientStateiEXT = NULL; |
| 2866 | PFNGLNAMEDPROGRAMSTRINGEXTPROC glad_glNamedProgramStringEXT; | 2867 | PFNGLGETFLOATI_VEXTPROC glad_glGetFloati_vEXT = NULL; |
| 2867 | PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC glad_glNamedProgramLocalParameter4dEXT; | 2868 | PFNGLGETDOUBLEI_VEXTPROC glad_glGetDoublei_vEXT = NULL; |
| 2868 | PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC glad_glNamedProgramLocalParameter4dvEXT; | 2869 | PFNGLGETPOINTERI_VEXTPROC glad_glGetPointeri_vEXT = NULL; |
| 2869 | PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC glad_glNamedProgramLocalParameter4fEXT; | 2870 | PFNGLNAMEDPROGRAMSTRINGEXTPROC glad_glNamedProgramStringEXT = NULL; |
| 2870 | PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC glad_glNamedProgramLocalParameter4fvEXT; | 2871 | PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC glad_glNamedProgramLocalParameter4dEXT = NULL; |
| 2871 | PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC glad_glGetNamedProgramLocalParameterdvEXT; | 2872 | PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC glad_glNamedProgramLocalParameter4dvEXT = NULL; |
| 2872 | PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC glad_glGetNamedProgramLocalParameterfvEXT; | 2873 | PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC glad_glNamedProgramLocalParameter4fEXT = NULL; |
| 2873 | PFNGLGETNAMEDPROGRAMIVEXTPROC glad_glGetNamedProgramivEXT; | 2874 | PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC glad_glNamedProgramLocalParameter4fvEXT = NULL; |
| 2874 | PFNGLGETNAMEDPROGRAMSTRINGEXTPROC glad_glGetNamedProgramStringEXT; | 2875 | PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC glad_glGetNamedProgramLocalParameterdvEXT = NULL; |
| 2875 | PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC glad_glNamedRenderbufferStorageEXT; | 2876 | PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC glad_glGetNamedProgramLocalParameterfvEXT = NULL; |
| 2876 | PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC glad_glGetNamedRenderbufferParameterivEXT; | 2877 | PFNGLGETNAMEDPROGRAMIVEXTPROC glad_glGetNamedProgramivEXT = NULL; |
| 2877 | PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glNamedRenderbufferStorageMultisampleEXT; | 2878 | PFNGLGETNAMEDPROGRAMSTRINGEXTPROC glad_glGetNamedProgramStringEXT = NULL; |
| 2878 | PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC glad_glNamedRenderbufferStorageMultisampleCoverageEXT; | 2879 | PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC glad_glNamedRenderbufferStorageEXT = NULL; |
| 2879 | PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC glad_glCheckNamedFramebufferStatusEXT; | 2880 | PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC glad_glGetNamedRenderbufferParameterivEXT = NULL; |
| 2880 | PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC glad_glNamedFramebufferTexture1DEXT; | 2881 | PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glNamedRenderbufferStorageMultisampleEXT = NULL; |
| 2881 | PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC glad_glNamedFramebufferTexture2DEXT; | 2882 | PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC glad_glNamedRenderbufferStorageMultisampleCoverageEXT = NULL; |
| 2882 | PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC glad_glNamedFramebufferTexture3DEXT; | 2883 | PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC glad_glCheckNamedFramebufferStatusEXT = NULL; |
| 2883 | PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC glad_glNamedFramebufferRenderbufferEXT; | 2884 | PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC glad_glNamedFramebufferTexture1DEXT = NULL; |
| 2884 | PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glad_glGetNamedFramebufferAttachmentParameterivEXT; | 2885 | PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC glad_glNamedFramebufferTexture2DEXT = NULL; |
| 2885 | PFNGLGENERATETEXTUREMIPMAPEXTPROC glad_glGenerateTextureMipmapEXT; | 2886 | PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC glad_glNamedFramebufferTexture3DEXT = NULL; |
| 2886 | PFNGLGENERATEMULTITEXMIPMAPEXTPROC glad_glGenerateMultiTexMipmapEXT; | 2887 | PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC glad_glNamedFramebufferRenderbufferEXT = NULL; |
| 2887 | PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC glad_glFramebufferDrawBufferEXT; | 2888 | PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glad_glGetNamedFramebufferAttachmentParameterivEXT = NULL; |
| 2888 | PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC glad_glFramebufferDrawBuffersEXT; | 2889 | PFNGLGENERATETEXTUREMIPMAPEXTPROC glad_glGenerateTextureMipmapEXT = NULL; |
| 2889 | PFNGLFRAMEBUFFERREADBUFFEREXTPROC glad_glFramebufferReadBufferEXT; | 2890 | PFNGLGENERATEMULTITEXMIPMAPEXTPROC glad_glGenerateMultiTexMipmapEXT = NULL; |
| 2890 | PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC glad_glGetFramebufferParameterivEXT; | 2891 | PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC glad_glFramebufferDrawBufferEXT = NULL; |
| 2891 | PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC glad_glNamedCopyBufferSubDataEXT; | 2892 | PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC glad_glFramebufferDrawBuffersEXT = NULL; |
| 2892 | PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC glad_glNamedFramebufferTextureEXT; | 2893 | PFNGLFRAMEBUFFERREADBUFFEREXTPROC glad_glFramebufferReadBufferEXT = NULL; |
| 2893 | PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC glad_glNamedFramebufferTextureLayerEXT; | 2894 | PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC glad_glGetFramebufferParameterivEXT = NULL; |
| 2894 | PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC glad_glNamedFramebufferTextureFaceEXT; | 2895 | PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC glad_glNamedCopyBufferSubDataEXT = NULL; |
| 2895 | PFNGLTEXTURERENDERBUFFEREXTPROC glad_glTextureRenderbufferEXT; | 2896 | PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC glad_glNamedFramebufferTextureEXT = NULL; |
| 2896 | PFNGLMULTITEXRENDERBUFFEREXTPROC glad_glMultiTexRenderbufferEXT; | 2897 | PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC glad_glNamedFramebufferTextureLayerEXT = NULL; |
| 2897 | PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC glad_glVertexArrayVertexOffsetEXT; | 2898 | PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC glad_glNamedFramebufferTextureFaceEXT = NULL; |
| 2898 | PFNGLVERTEXARRAYCOLOROFFSETEXTPROC glad_glVertexArrayColorOffsetEXT; | 2899 | PFNGLTEXTURERENDERBUFFEREXTPROC glad_glTextureRenderbufferEXT = NULL; |
| 2899 | PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC glad_glVertexArrayEdgeFlagOffsetEXT; | 2900 | PFNGLMULTITEXRENDERBUFFEREXTPROC glad_glMultiTexRenderbufferEXT = NULL; |
| 2900 | PFNGLVERTEXARRAYINDEXOFFSETEXTPROC glad_glVertexArrayIndexOffsetEXT; | 2901 | PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC glad_glVertexArrayVertexOffsetEXT = NULL; |
| 2901 | PFNGLVERTEXARRAYNORMALOFFSETEXTPROC glad_glVertexArrayNormalOffsetEXT; | 2902 | PFNGLVERTEXARRAYCOLOROFFSETEXTPROC glad_glVertexArrayColorOffsetEXT = NULL; |
| 2902 | PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC glad_glVertexArrayTexCoordOffsetEXT; | 2903 | PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC glad_glVertexArrayEdgeFlagOffsetEXT = NULL; |
| 2903 | PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC glad_glVertexArrayMultiTexCoordOffsetEXT; | 2904 | PFNGLVERTEXARRAYINDEXOFFSETEXTPROC glad_glVertexArrayIndexOffsetEXT = NULL; |
| 2904 | PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC glad_glVertexArrayFogCoordOffsetEXT; | 2905 | PFNGLVERTEXARRAYNORMALOFFSETEXTPROC glad_glVertexArrayNormalOffsetEXT = NULL; |
| 2905 | PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC glad_glVertexArraySecondaryColorOffsetEXT; | 2906 | PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC glad_glVertexArrayTexCoordOffsetEXT = NULL; |
| 2906 | PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC glad_glVertexArrayVertexAttribOffsetEXT; | 2907 | PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC glad_glVertexArrayMultiTexCoordOffsetEXT = NULL; |
| 2907 | PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC glad_glVertexArrayVertexAttribIOffsetEXT; | 2908 | PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC glad_glVertexArrayFogCoordOffsetEXT = NULL; |
| 2908 | PFNGLENABLEVERTEXARRAYEXTPROC glad_glEnableVertexArrayEXT; | 2909 | PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC glad_glVertexArraySecondaryColorOffsetEXT = NULL; |
| 2909 | PFNGLDISABLEVERTEXARRAYEXTPROC glad_glDisableVertexArrayEXT; | 2910 | PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC glad_glVertexArrayVertexAttribOffsetEXT = NULL; |
| 2910 | PFNGLENABLEVERTEXARRAYATTRIBEXTPROC glad_glEnableVertexArrayAttribEXT; | 2911 | PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC glad_glVertexArrayVertexAttribIOffsetEXT = NULL; |
| 2911 | PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC glad_glDisableVertexArrayAttribEXT; | 2912 | PFNGLENABLEVERTEXARRAYEXTPROC glad_glEnableVertexArrayEXT = NULL; |
| 2912 | PFNGLGETVERTEXARRAYINTEGERVEXTPROC glad_glGetVertexArrayIntegervEXT; | 2913 | PFNGLDISABLEVERTEXARRAYEXTPROC glad_glDisableVertexArrayEXT = NULL; |
| 2913 | PFNGLGETVERTEXARRAYPOINTERVEXTPROC glad_glGetVertexArrayPointervEXT; | 2914 | PFNGLENABLEVERTEXARRAYATTRIBEXTPROC glad_glEnableVertexArrayAttribEXT = NULL; |
| 2914 | PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC glad_glGetVertexArrayIntegeri_vEXT; | 2915 | PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC glad_glDisableVertexArrayAttribEXT = NULL; |
| 2915 | PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC glad_glGetVertexArrayPointeri_vEXT; | 2916 | PFNGLGETVERTEXARRAYINTEGERVEXTPROC glad_glGetVertexArrayIntegervEXT = NULL; |
| 2916 | PFNGLMAPNAMEDBUFFERRANGEEXTPROC glad_glMapNamedBufferRangeEXT; | 2917 | PFNGLGETVERTEXARRAYPOINTERVEXTPROC glad_glGetVertexArrayPointervEXT = NULL; |
| 2917 | PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC glad_glFlushMappedNamedBufferRangeEXT; | 2918 | PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC glad_glGetVertexArrayIntegeri_vEXT = NULL; |
| 2918 | PFNGLNAMEDBUFFERSTORAGEEXTPROC glad_glNamedBufferStorageEXT; | 2919 | PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC glad_glGetVertexArrayPointeri_vEXT = NULL; |
| 2919 | PFNGLCLEARNAMEDBUFFERDATAEXTPROC glad_glClearNamedBufferDataEXT; | 2920 | PFNGLMAPNAMEDBUFFERRANGEEXTPROC glad_glMapNamedBufferRangeEXT = NULL; |
| 2920 | PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC glad_glClearNamedBufferSubDataEXT; | 2921 | PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC glad_glFlushMappedNamedBufferRangeEXT = NULL; |
| 2921 | PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC glad_glNamedFramebufferParameteriEXT; | 2922 | PFNGLNAMEDBUFFERSTORAGEEXTPROC glad_glNamedBufferStorageEXT = NULL; |
| 2922 | PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC glad_glGetNamedFramebufferParameterivEXT; | 2923 | PFNGLCLEARNAMEDBUFFERDATAEXTPROC glad_glClearNamedBufferDataEXT = NULL; |
| 2923 | PFNGLPROGRAMUNIFORM1DEXTPROC glad_glProgramUniform1dEXT; | 2924 | PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC glad_glClearNamedBufferSubDataEXT = NULL; |
| 2924 | PFNGLPROGRAMUNIFORM2DEXTPROC glad_glProgramUniform2dEXT; | 2925 | PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC glad_glNamedFramebufferParameteriEXT = NULL; |
| 2925 | PFNGLPROGRAMUNIFORM3DEXTPROC glad_glProgramUniform3dEXT; | 2926 | PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC glad_glGetNamedFramebufferParameterivEXT = NULL; |
| 2926 | PFNGLPROGRAMUNIFORM4DEXTPROC glad_glProgramUniform4dEXT; | 2927 | PFNGLPROGRAMUNIFORM1DEXTPROC glad_glProgramUniform1dEXT = NULL; |
| 2927 | PFNGLPROGRAMUNIFORM1DVEXTPROC glad_glProgramUniform1dvEXT; | 2928 | PFNGLPROGRAMUNIFORM2DEXTPROC glad_glProgramUniform2dEXT = NULL; |
| 2928 | PFNGLPROGRAMUNIFORM2DVEXTPROC glad_glProgramUniform2dvEXT; | 2929 | PFNGLPROGRAMUNIFORM3DEXTPROC glad_glProgramUniform3dEXT = NULL; |
| 2929 | PFNGLPROGRAMUNIFORM3DVEXTPROC glad_glProgramUniform3dvEXT; | 2930 | PFNGLPROGRAMUNIFORM4DEXTPROC glad_glProgramUniform4dEXT = NULL; |
| 2930 | PFNGLPROGRAMUNIFORM4DVEXTPROC glad_glProgramUniform4dvEXT; | 2931 | PFNGLPROGRAMUNIFORM1DVEXTPROC glad_glProgramUniform1dvEXT = NULL; |
| 2931 | PFNGLPROGRAMUNIFORMMATRIX2DVEXTPROC glad_glProgramUniformMatrix2dvEXT; | 2932 | PFNGLPROGRAMUNIFORM2DVEXTPROC glad_glProgramUniform2dvEXT = NULL; |
| 2932 | PFNGLPROGRAMUNIFORMMATRIX3DVEXTPROC glad_glProgramUniformMatrix3dvEXT; | 2933 | PFNGLPROGRAMUNIFORM3DVEXTPROC glad_glProgramUniform3dvEXT = NULL; |
| 2933 | PFNGLPROGRAMUNIFORMMATRIX4DVEXTPROC glad_glProgramUniformMatrix4dvEXT; | 2934 | PFNGLPROGRAMUNIFORM4DVEXTPROC glad_glProgramUniform4dvEXT = NULL; |
| 2934 | PFNGLPROGRAMUNIFORMMATRIX2X3DVEXTPROC glad_glProgramUniformMatrix2x3dvEXT; | 2935 | PFNGLPROGRAMUNIFORMMATRIX2DVEXTPROC glad_glProgramUniformMatrix2dvEXT = NULL; |
| 2935 | PFNGLPROGRAMUNIFORMMATRIX2X4DVEXTPROC glad_glProgramUniformMatrix2x4dvEXT; | 2936 | PFNGLPROGRAMUNIFORMMATRIX3DVEXTPROC glad_glProgramUniformMatrix3dvEXT = NULL; |
| 2936 | PFNGLPROGRAMUNIFORMMATRIX3X2DVEXTPROC glad_glProgramUniformMatrix3x2dvEXT; | 2937 | PFNGLPROGRAMUNIFORMMATRIX4DVEXTPROC glad_glProgramUniformMatrix4dvEXT = NULL; |
| 2937 | PFNGLPROGRAMUNIFORMMATRIX3X4DVEXTPROC glad_glProgramUniformMatrix3x4dvEXT; | 2938 | PFNGLPROGRAMUNIFORMMATRIX2X3DVEXTPROC glad_glProgramUniformMatrix2x3dvEXT = NULL; |
| 2938 | PFNGLPROGRAMUNIFORMMATRIX4X2DVEXTPROC glad_glProgramUniformMatrix4x2dvEXT; | 2939 | PFNGLPROGRAMUNIFORMMATRIX2X4DVEXTPROC glad_glProgramUniformMatrix2x4dvEXT = NULL; |
| 2939 | PFNGLPROGRAMUNIFORMMATRIX4X3DVEXTPROC glad_glProgramUniformMatrix4x3dvEXT; | 2940 | PFNGLPROGRAMUNIFORMMATRIX3X2DVEXTPROC glad_glProgramUniformMatrix3x2dvEXT = NULL; |
| 2940 | PFNGLTEXTUREBUFFERRANGEEXTPROC glad_glTextureBufferRangeEXT; | 2941 | PFNGLPROGRAMUNIFORMMATRIX3X4DVEXTPROC glad_glProgramUniformMatrix3x4dvEXT = NULL; |
| 2941 | PFNGLTEXTURESTORAGE1DEXTPROC glad_glTextureStorage1DEXT; | 2942 | PFNGLPROGRAMUNIFORMMATRIX4X2DVEXTPROC glad_glProgramUniformMatrix4x2dvEXT = NULL; |
| 2942 | PFNGLTEXTURESTORAGE2DEXTPROC glad_glTextureStorage2DEXT; | 2943 | PFNGLPROGRAMUNIFORMMATRIX4X3DVEXTPROC glad_glProgramUniformMatrix4x3dvEXT = NULL; |
| 2943 | PFNGLTEXTURESTORAGE3DEXTPROC glad_glTextureStorage3DEXT; | 2944 | PFNGLTEXTUREBUFFERRANGEEXTPROC glad_glTextureBufferRangeEXT = NULL; |
| 2944 | PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC glad_glTextureStorage2DMultisampleEXT; | 2945 | PFNGLTEXTURESTORAGE1DEXTPROC glad_glTextureStorage1DEXT = NULL; |
| 2945 | PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC glad_glTextureStorage3DMultisampleEXT; | 2946 | PFNGLTEXTURESTORAGE2DEXTPROC glad_glTextureStorage2DEXT = NULL; |
| 2946 | PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC glad_glVertexArrayBindVertexBufferEXT; | 2947 | PFNGLTEXTURESTORAGE3DEXTPROC glad_glTextureStorage3DEXT = NULL; |
| 2947 | PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC glad_glVertexArrayVertexAttribFormatEXT; | 2948 | PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC glad_glTextureStorage2DMultisampleEXT = NULL; |
| 2948 | PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC glad_glVertexArrayVertexAttribIFormatEXT; | 2949 | PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC glad_glTextureStorage3DMultisampleEXT = NULL; |
| 2949 | PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC glad_glVertexArrayVertexAttribLFormatEXT; | 2950 | PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC glad_glVertexArrayBindVertexBufferEXT = NULL; |
| 2950 | PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC glad_glVertexArrayVertexAttribBindingEXT; | 2951 | PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC glad_glVertexArrayVertexAttribFormatEXT = NULL; |
| 2951 | PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC glad_glVertexArrayVertexBindingDivisorEXT; | 2952 | PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC glad_glVertexArrayVertexAttribIFormatEXT = NULL; |
| 2952 | PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC glad_glVertexArrayVertexAttribLOffsetEXT; | 2953 | PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC glad_glVertexArrayVertexAttribLFormatEXT = NULL; |
| 2953 | PFNGLTEXTUREPAGECOMMITMENTEXTPROC glad_glTexturePageCommitmentEXT; | 2954 | PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC glad_glVertexArrayVertexAttribBindingEXT = NULL; |
| 2954 | PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC glad_glVertexArrayVertexAttribDivisorEXT; | 2955 | PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC glad_glVertexArrayVertexBindingDivisorEXT = NULL; |
| 2955 | PFNGLCOLORMASKINDEXEDEXTPROC glad_glColorMaskIndexedEXT; | 2956 | PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC glad_glVertexArrayVertexAttribLOffsetEXT = NULL; |
| 2956 | PFNGLDRAWARRAYSINSTANCEDEXTPROC glad_glDrawArraysInstancedEXT; | 2957 | PFNGLTEXTUREPAGECOMMITMENTEXTPROC glad_glTexturePageCommitmentEXT = NULL; |
| 2957 | PFNGLDRAWELEMENTSINSTANCEDEXTPROC glad_glDrawElementsInstancedEXT; | 2958 | PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC glad_glVertexArrayVertexAttribDivisorEXT = NULL; |
| 2958 | PFNGLDRAWRANGEELEMENTSEXTPROC glad_glDrawRangeElementsEXT; | 2959 | PFNGLCOLORMASKINDEXEDEXTPROC glad_glColorMaskIndexedEXT = NULL; |
| 2959 | PFNGLBUFFERSTORAGEEXTERNALEXTPROC glad_glBufferStorageExternalEXT; | 2960 | PFNGLDRAWARRAYSINSTANCEDEXTPROC glad_glDrawArraysInstancedEXT = NULL; |
| 2960 | PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC glad_glNamedBufferStorageExternalEXT; | 2961 | PFNGLDRAWELEMENTSINSTANCEDEXTPROC glad_glDrawElementsInstancedEXT = NULL; |
| 2961 | PFNGLFOGCOORDFEXTPROC glad_glFogCoordfEXT; | 2962 | PFNGLDRAWRANGEELEMENTSEXTPROC glad_glDrawRangeElementsEXT = NULL; |
| 2962 | PFNGLFOGCOORDFVEXTPROC glad_glFogCoordfvEXT; | 2963 | PFNGLBUFFERSTORAGEEXTERNALEXTPROC glad_glBufferStorageExternalEXT = NULL; |
| 2963 | PFNGLFOGCOORDDEXTPROC glad_glFogCoorddEXT; | 2964 | PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC glad_glNamedBufferStorageExternalEXT = NULL; |
| 2964 | PFNGLFOGCOORDDVEXTPROC glad_glFogCoorddvEXT; | 2965 | PFNGLFOGCOORDFEXTPROC glad_glFogCoordfEXT = NULL; |
| 2965 | PFNGLFOGCOORDPOINTEREXTPROC glad_glFogCoordPointerEXT; | 2966 | PFNGLFOGCOORDFVEXTPROC glad_glFogCoordfvEXT = NULL; |
| 2966 | PFNGLBLITFRAMEBUFFEREXTPROC glad_glBlitFramebufferEXT; | 2967 | PFNGLFOGCOORDDEXTPROC glad_glFogCoorddEXT = NULL; |
| 2967 | PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glRenderbufferStorageMultisampleEXT; | 2968 | PFNGLFOGCOORDDVEXTPROC glad_glFogCoorddvEXT = NULL; |
| 2968 | PFNGLISRENDERBUFFEREXTPROC glad_glIsRenderbufferEXT; | 2969 | PFNGLFOGCOORDPOINTEREXTPROC glad_glFogCoordPointerEXT = NULL; |
| 2969 | PFNGLBINDRENDERBUFFEREXTPROC glad_glBindRenderbufferEXT; | 2970 | PFNGLBLITFRAMEBUFFEREXTPROC glad_glBlitFramebufferEXT = NULL; |
| 2970 | PFNGLDELETERENDERBUFFERSEXTPROC glad_glDeleteRenderbuffersEXT; | 2971 | PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glRenderbufferStorageMultisampleEXT = NULL; |
| 2971 | PFNGLGENRENDERBUFFERSEXTPROC glad_glGenRenderbuffersEXT; | 2972 | PFNGLISRENDERBUFFEREXTPROC glad_glIsRenderbufferEXT = NULL; |
| 2972 | PFNGLRENDERBUFFERSTORAGEEXTPROC glad_glRenderbufferStorageEXT; | 2973 | PFNGLBINDRENDERBUFFEREXTPROC glad_glBindRenderbufferEXT = NULL; |
| 2973 | PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glad_glGetRenderbufferParameterivEXT; | 2974 | PFNGLDELETERENDERBUFFERSEXTPROC glad_glDeleteRenderbuffersEXT = NULL; |
| 2974 | PFNGLISFRAMEBUFFEREXTPROC glad_glIsFramebufferEXT; | 2975 | PFNGLGENRENDERBUFFERSEXTPROC glad_glGenRenderbuffersEXT = NULL; |
| 2975 | PFNGLBINDFRAMEBUFFEREXTPROC glad_glBindFramebufferEXT; | 2976 | PFNGLRENDERBUFFERSTORAGEEXTPROC glad_glRenderbufferStorageEXT = NULL; |
| 2976 | PFNGLDELETEFRAMEBUFFERSEXTPROC glad_glDeleteFramebuffersEXT; | 2977 | PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glad_glGetRenderbufferParameterivEXT = NULL; |
| 2977 | PFNGLGENFRAMEBUFFERSEXTPROC glad_glGenFramebuffersEXT; | 2978 | PFNGLISFRAMEBUFFEREXTPROC glad_glIsFramebufferEXT = NULL; |
| 2978 | PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glad_glCheckFramebufferStatusEXT; | 2979 | PFNGLBINDFRAMEBUFFEREXTPROC glad_glBindFramebufferEXT = NULL; |
| 2979 | PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glad_glFramebufferTexture1DEXT; | 2980 | PFNGLDELETEFRAMEBUFFERSEXTPROC glad_glDeleteFramebuffersEXT = NULL; |
| 2980 | PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glad_glFramebufferTexture2DEXT; | 2981 | PFNGLGENFRAMEBUFFERSEXTPROC glad_glGenFramebuffersEXT = NULL; |
| 2981 | PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glad_glFramebufferTexture3DEXT; | 2982 | PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glad_glCheckFramebufferStatusEXT = NULL; |
| 2982 | PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glad_glFramebufferRenderbufferEXT; | 2983 | PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glad_glFramebufferTexture1DEXT = NULL; |
| 2983 | PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glad_glGetFramebufferAttachmentParameterivEXT; | 2984 | PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glad_glFramebufferTexture2DEXT = NULL; |
| 2984 | PFNGLGENERATEMIPMAPEXTPROC glad_glGenerateMipmapEXT; | 2985 | PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glad_glFramebufferTexture3DEXT = NULL; |
| 2985 | PFNGLPROGRAMPARAMETERIEXTPROC glad_glProgramParameteriEXT; | 2986 | PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glad_glFramebufferRenderbufferEXT = NULL; |
| 2986 | PFNGLPROGRAMENVPARAMETERS4FVEXTPROC glad_glProgramEnvParameters4fvEXT; | 2987 | PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glad_glGetFramebufferAttachmentParameterivEXT = NULL; |
| 2987 | PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC glad_glProgramLocalParameters4fvEXT; | 2988 | PFNGLGENERATEMIPMAPEXTPROC glad_glGenerateMipmapEXT = NULL; |
| 2988 | PFNGLGETUNIFORMUIVEXTPROC glad_glGetUniformuivEXT; | 2989 | PFNGLPROGRAMPARAMETERIEXTPROC glad_glProgramParameteriEXT = NULL; |
| 2989 | PFNGLBINDFRAGDATALOCATIONEXTPROC glad_glBindFragDataLocationEXT; | 2990 | PFNGLPROGRAMENVPARAMETERS4FVEXTPROC glad_glProgramEnvParameters4fvEXT = NULL; |
| 2990 | PFNGLGETFRAGDATALOCATIONEXTPROC glad_glGetFragDataLocationEXT; | 2991 | PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC glad_glProgramLocalParameters4fvEXT = NULL; |
| 2991 | PFNGLUNIFORM1UIEXTPROC glad_glUniform1uiEXT; | 2992 | PFNGLGETUNIFORMUIVEXTPROC glad_glGetUniformuivEXT = NULL; |
| 2992 | PFNGLUNIFORM2UIEXTPROC glad_glUniform2uiEXT; | 2993 | PFNGLBINDFRAGDATALOCATIONEXTPROC glad_glBindFragDataLocationEXT = NULL; |
| 2993 | PFNGLUNIFORM3UIEXTPROC glad_glUniform3uiEXT; | 2994 | PFNGLGETFRAGDATALOCATIONEXTPROC glad_glGetFragDataLocationEXT = NULL; |
| 2994 | PFNGLUNIFORM4UIEXTPROC glad_glUniform4uiEXT; | 2995 | PFNGLUNIFORM1UIEXTPROC glad_glUniform1uiEXT = NULL; |
| 2995 | PFNGLUNIFORM1UIVEXTPROC glad_glUniform1uivEXT; | 2996 | PFNGLUNIFORM2UIEXTPROC glad_glUniform2uiEXT = NULL; |
| 2996 | PFNGLUNIFORM2UIVEXTPROC glad_glUniform2uivEXT; | 2997 | PFNGLUNIFORM3UIEXTPROC glad_glUniform3uiEXT = NULL; |
| 2997 | PFNGLUNIFORM3UIVEXTPROC glad_glUniform3uivEXT; | 2998 | PFNGLUNIFORM4UIEXTPROC glad_glUniform4uiEXT = NULL; |
| 2998 | PFNGLUNIFORM4UIVEXTPROC glad_glUniform4uivEXT; | 2999 | PFNGLUNIFORM1UIVEXTPROC glad_glUniform1uivEXT = NULL; |
| 2999 | PFNGLGETHISTOGRAMEXTPROC glad_glGetHistogramEXT; | 3000 | PFNGLUNIFORM2UIVEXTPROC glad_glUniform2uivEXT = NULL; |
| 3000 | PFNGLGETHISTOGRAMPARAMETERFVEXTPROC glad_glGetHistogramParameterfvEXT; | 3001 | PFNGLUNIFORM3UIVEXTPROC glad_glUniform3uivEXT = NULL; |
| 3001 | PFNGLGETHISTOGRAMPARAMETERIVEXTPROC glad_glGetHistogramParameterivEXT; | 3002 | PFNGLUNIFORM4UIVEXTPROC glad_glUniform4uivEXT = NULL; |
| 3002 | PFNGLGETMINMAXEXTPROC glad_glGetMinmaxEXT; | 3003 | PFNGLGETHISTOGRAMEXTPROC glad_glGetHistogramEXT = NULL; |
| 3003 | PFNGLGETMINMAXPARAMETERFVEXTPROC glad_glGetMinmaxParameterfvEXT; | 3004 | PFNGLGETHISTOGRAMPARAMETERFVEXTPROC glad_glGetHistogramParameterfvEXT = NULL; |
| 3004 | PFNGLGETMINMAXPARAMETERIVEXTPROC glad_glGetMinmaxParameterivEXT; | 3005 | PFNGLGETHISTOGRAMPARAMETERIVEXTPROC glad_glGetHistogramParameterivEXT = NULL; |
| 3005 | PFNGLHISTOGRAMEXTPROC glad_glHistogramEXT; | 3006 | PFNGLGETMINMAXEXTPROC glad_glGetMinmaxEXT = NULL; |
| 3006 | PFNGLMINMAXEXTPROC glad_glMinmaxEXT; | 3007 | PFNGLGETMINMAXPARAMETERFVEXTPROC glad_glGetMinmaxParameterfvEXT = NULL; |
| 3007 | PFNGLRESETHISTOGRAMEXTPROC glad_glResetHistogramEXT; | 3008 | PFNGLGETMINMAXPARAMETERIVEXTPROC glad_glGetMinmaxParameterivEXT = NULL; |
| 3008 | PFNGLRESETMINMAXEXTPROC glad_glResetMinmaxEXT; | 3009 | PFNGLHISTOGRAMEXTPROC glad_glHistogramEXT = NULL; |
| 3009 | PFNGLINDEXFUNCEXTPROC glad_glIndexFuncEXT; | 3010 | PFNGLMINMAXEXTPROC glad_glMinmaxEXT = NULL; |
| 3010 | PFNGLINDEXMATERIALEXTPROC glad_glIndexMaterialEXT; | 3011 | PFNGLRESETHISTOGRAMEXTPROC glad_glResetHistogramEXT = NULL; |
| 3011 | PFNGLAPPLYTEXTUREEXTPROC glad_glApplyTextureEXT; | 3012 | PFNGLRESETMINMAXEXTPROC glad_glResetMinmaxEXT = NULL; |
| 3012 | PFNGLTEXTURELIGHTEXTPROC glad_glTextureLightEXT; | 3013 | PFNGLINDEXFUNCEXTPROC glad_glIndexFuncEXT = NULL; |
| 3013 | PFNGLTEXTUREMATERIALEXTPROC glad_glTextureMaterialEXT; | 3014 | PFNGLINDEXMATERIALEXTPROC glad_glIndexMaterialEXT = NULL; |
| 3014 | PFNGLGETUNSIGNEDBYTEVEXTPROC glad_glGetUnsignedBytevEXT; | 3015 | PFNGLAPPLYTEXTUREEXTPROC glad_glApplyTextureEXT = NULL; |
| 3015 | PFNGLGETUNSIGNEDBYTEI_VEXTPROC glad_glGetUnsignedBytei_vEXT; | 3016 | PFNGLTEXTURELIGHTEXTPROC glad_glTextureLightEXT = NULL; |
| 3016 | PFNGLDELETEMEMORYOBJECTSEXTPROC glad_glDeleteMemoryObjectsEXT; | 3017 | PFNGLTEXTUREMATERIALEXTPROC glad_glTextureMaterialEXT = NULL; |
| 3017 | PFNGLISMEMORYOBJECTEXTPROC glad_glIsMemoryObjectEXT; | 3018 | PFNGLGETUNSIGNEDBYTEVEXTPROC glad_glGetUnsignedBytevEXT = NULL; |
| 3018 | PFNGLCREATEMEMORYOBJECTSEXTPROC glad_glCreateMemoryObjectsEXT; | 3019 | PFNGLGETUNSIGNEDBYTEI_VEXTPROC glad_glGetUnsignedBytei_vEXT = NULL; |
| 3019 | PFNGLMEMORYOBJECTPARAMETERIVEXTPROC glad_glMemoryObjectParameterivEXT; | 3020 | PFNGLDELETEMEMORYOBJECTSEXTPROC glad_glDeleteMemoryObjectsEXT = NULL; |
| 3020 | PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC glad_glGetMemoryObjectParameterivEXT; | 3021 | PFNGLISMEMORYOBJECTEXTPROC glad_glIsMemoryObjectEXT = NULL; |
| 3021 | PFNGLTEXSTORAGEMEM2DEXTPROC glad_glTexStorageMem2DEXT; | 3022 | PFNGLCREATEMEMORYOBJECTSEXTPROC glad_glCreateMemoryObjectsEXT = NULL; |
| 3022 | PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC glad_glTexStorageMem2DMultisampleEXT; | 3023 | PFNGLMEMORYOBJECTPARAMETERIVEXTPROC glad_glMemoryObjectParameterivEXT = NULL; |
| 3023 | PFNGLTEXSTORAGEMEM3DEXTPROC glad_glTexStorageMem3DEXT; | 3024 | PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC glad_glGetMemoryObjectParameterivEXT = NULL; |
| 3024 | PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC glad_glTexStorageMem3DMultisampleEXT; | 3025 | PFNGLTEXSTORAGEMEM2DEXTPROC glad_glTexStorageMem2DEXT = NULL; |
| 3025 | PFNGLBUFFERSTORAGEMEMEXTPROC glad_glBufferStorageMemEXT; | 3026 | PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC glad_glTexStorageMem2DMultisampleEXT = NULL; |
| 3026 | PFNGLTEXTURESTORAGEMEM2DEXTPROC glad_glTextureStorageMem2DEXT; | 3027 | PFNGLTEXSTORAGEMEM3DEXTPROC glad_glTexStorageMem3DEXT = NULL; |
| 3027 | PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC glad_glTextureStorageMem2DMultisampleEXT; | 3028 | PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC glad_glTexStorageMem3DMultisampleEXT = NULL; |
| 3028 | PFNGLTEXTURESTORAGEMEM3DEXTPROC glad_glTextureStorageMem3DEXT; | 3029 | PFNGLBUFFERSTORAGEMEMEXTPROC glad_glBufferStorageMemEXT = NULL; |
| 3029 | PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC glad_glTextureStorageMem3DMultisampleEXT; | 3030 | PFNGLTEXTURESTORAGEMEM2DEXTPROC glad_glTextureStorageMem2DEXT = NULL; |
| 3030 | PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC glad_glNamedBufferStorageMemEXT; | 3031 | PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC glad_glTextureStorageMem2DMultisampleEXT = NULL; |
| 3031 | PFNGLTEXSTORAGEMEM1DEXTPROC glad_glTexStorageMem1DEXT; | 3032 | PFNGLTEXTURESTORAGEMEM3DEXTPROC glad_glTextureStorageMem3DEXT = NULL; |
| 3032 | PFNGLTEXTURESTORAGEMEM1DEXTPROC glad_glTextureStorageMem1DEXT; | 3033 | PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC glad_glTextureStorageMem3DMultisampleEXT = NULL; |
| 3033 | PFNGLIMPORTMEMORYFDEXTPROC glad_glImportMemoryFdEXT; | 3034 | PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC glad_glNamedBufferStorageMemEXT = NULL; |
| 3034 | PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC glad_glImportMemoryWin32HandleEXT; | 3035 | PFNGLTEXSTORAGEMEM1DEXTPROC glad_glTexStorageMem1DEXT = NULL; |
| 3035 | PFNGLIMPORTMEMORYWIN32NAMEEXTPROC glad_glImportMemoryWin32NameEXT; | 3036 | PFNGLTEXTURESTORAGEMEM1DEXTPROC glad_glTextureStorageMem1DEXT = NULL; |
| 3036 | PFNGLMULTIDRAWARRAYSEXTPROC glad_glMultiDrawArraysEXT; | 3037 | PFNGLIMPORTMEMORYFDEXTPROC glad_glImportMemoryFdEXT = NULL; |
| 3037 | PFNGLMULTIDRAWELEMENTSEXTPROC glad_glMultiDrawElementsEXT; | 3038 | PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC glad_glImportMemoryWin32HandleEXT = NULL; |
| 3038 | PFNGLSAMPLEMASKEXTPROC glad_glSampleMaskEXT; | 3039 | PFNGLIMPORTMEMORYWIN32NAMEEXTPROC glad_glImportMemoryWin32NameEXT = NULL; |
| 3039 | PFNGLSAMPLEPATTERNEXTPROC glad_glSamplePatternEXT; | 3040 | PFNGLMULTIDRAWARRAYSEXTPROC glad_glMultiDrawArraysEXT = NULL; |
| 3040 | PFNGLCOLORTABLEEXTPROC glad_glColorTableEXT; | 3041 | PFNGLMULTIDRAWELEMENTSEXTPROC glad_glMultiDrawElementsEXT = NULL; |
| 3041 | PFNGLGETCOLORTABLEEXTPROC glad_glGetColorTableEXT; | 3042 | PFNGLSAMPLEMASKEXTPROC glad_glSampleMaskEXT = NULL; |
| 3042 | PFNGLGETCOLORTABLEPARAMETERIVEXTPROC glad_glGetColorTableParameterivEXT; | 3043 | PFNGLSAMPLEPATTERNEXTPROC glad_glSamplePatternEXT = NULL; |
| 3043 | PFNGLGETCOLORTABLEPARAMETERFVEXTPROC glad_glGetColorTableParameterfvEXT; | 3044 | PFNGLCOLORTABLEEXTPROC glad_glColorTableEXT = NULL; |
| 3044 | PFNGLPIXELTRANSFORMPARAMETERIEXTPROC glad_glPixelTransformParameteriEXT; | 3045 | PFNGLGETCOLORTABLEEXTPROC glad_glGetColorTableEXT = NULL; |
| 3045 | PFNGLPIXELTRANSFORMPARAMETERFEXTPROC glad_glPixelTransformParameterfEXT; | 3046 | PFNGLGETCOLORTABLEPARAMETERIVEXTPROC glad_glGetColorTableParameterivEXT = NULL; |
| 3046 | PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC glad_glPixelTransformParameterivEXT; | 3047 | PFNGLGETCOLORTABLEPARAMETERFVEXTPROC glad_glGetColorTableParameterfvEXT = NULL; |
| 3047 | PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC glad_glPixelTransformParameterfvEXT; | 3048 | PFNGLPIXELTRANSFORMPARAMETERIEXTPROC glad_glPixelTransformParameteriEXT = NULL; |
| 3048 | PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC glad_glGetPixelTransformParameterivEXT; | 3049 | PFNGLPIXELTRANSFORMPARAMETERFEXTPROC glad_glPixelTransformParameterfEXT = NULL; |
| 3049 | PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC glad_glGetPixelTransformParameterfvEXT; | 3050 | PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC glad_glPixelTransformParameterivEXT = NULL; |
| 3050 | PFNGLPOINTPARAMETERFEXTPROC glad_glPointParameterfEXT; | 3051 | PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC glad_glPixelTransformParameterfvEXT = NULL; |
| 3051 | PFNGLPOINTPARAMETERFVEXTPROC glad_glPointParameterfvEXT; | 3052 | PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC glad_glGetPixelTransformParameterivEXT = NULL; |
| 3052 | PFNGLPOLYGONOFFSETEXTPROC glad_glPolygonOffsetEXT; | 3053 | PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC glad_glGetPixelTransformParameterfvEXT = NULL; |
| 3053 | PFNGLPOLYGONOFFSETCLAMPEXTPROC glad_glPolygonOffsetClampEXT; | 3054 | PFNGLPOINTPARAMETERFEXTPROC glad_glPointParameterfEXT = NULL; |
| 3054 | PFNGLPROVOKINGVERTEXEXTPROC glad_glProvokingVertexEXT; | 3055 | PFNGLPOINTPARAMETERFVEXTPROC glad_glPointParameterfvEXT = NULL; |
| 3055 | PFNGLRASTERSAMPLESEXTPROC glad_glRasterSamplesEXT; | 3056 | PFNGLPOLYGONOFFSETEXTPROC glad_glPolygonOffsetEXT = NULL; |
| 3056 | PFNGLSECONDARYCOLOR3BEXTPROC glad_glSecondaryColor3bEXT; | 3057 | PFNGLPOLYGONOFFSETCLAMPEXTPROC glad_glPolygonOffsetClampEXT = NULL; |
| 3057 | PFNGLSECONDARYCOLOR3BVEXTPROC glad_glSecondaryColor3bvEXT; | 3058 | PFNGLPROVOKINGVERTEXEXTPROC glad_glProvokingVertexEXT = NULL; |
| 3058 | PFNGLSECONDARYCOLOR3DEXTPROC glad_glSecondaryColor3dEXT; | 3059 | PFNGLRASTERSAMPLESEXTPROC glad_glRasterSamplesEXT = NULL; |
| 3059 | PFNGLSECONDARYCOLOR3DVEXTPROC glad_glSecondaryColor3dvEXT; | 3060 | PFNGLSECONDARYCOLOR3BEXTPROC glad_glSecondaryColor3bEXT = NULL; |
| 3060 | PFNGLSECONDARYCOLOR3FEXTPROC glad_glSecondaryColor3fEXT; | 3061 | PFNGLSECONDARYCOLOR3BVEXTPROC glad_glSecondaryColor3bvEXT = NULL; |
| 3061 | PFNGLSECONDARYCOLOR3FVEXTPROC glad_glSecondaryColor3fvEXT; | 3062 | PFNGLSECONDARYCOLOR3DEXTPROC glad_glSecondaryColor3dEXT = NULL; |
| 3062 | PFNGLSECONDARYCOLOR3IEXTPROC glad_glSecondaryColor3iEXT; | 3063 | PFNGLSECONDARYCOLOR3DVEXTPROC glad_glSecondaryColor3dvEXT = NULL; |
| 3063 | PFNGLSECONDARYCOLOR3IVEXTPROC glad_glSecondaryColor3ivEXT; | 3064 | PFNGLSECONDARYCOLOR3FEXTPROC glad_glSecondaryColor3fEXT = NULL; |
| 3064 | PFNGLSECONDARYCOLOR3SEXTPROC glad_glSecondaryColor3sEXT; | 3065 | PFNGLSECONDARYCOLOR3FVEXTPROC glad_glSecondaryColor3fvEXT = NULL; |
| 3065 | PFNGLSECONDARYCOLOR3SVEXTPROC glad_glSecondaryColor3svEXT; | 3066 | PFNGLSECONDARYCOLOR3IEXTPROC glad_glSecondaryColor3iEXT = NULL; |
| 3066 | PFNGLSECONDARYCOLOR3UBEXTPROC glad_glSecondaryColor3ubEXT; | 3067 | PFNGLSECONDARYCOLOR3IVEXTPROC glad_glSecondaryColor3ivEXT = NULL; |
| 3067 | PFNGLSECONDARYCOLOR3UBVEXTPROC glad_glSecondaryColor3ubvEXT; | 3068 | PFNGLSECONDARYCOLOR3SEXTPROC glad_glSecondaryColor3sEXT = NULL; |
| 3068 | PFNGLSECONDARYCOLOR3UIEXTPROC glad_glSecondaryColor3uiEXT; | 3069 | PFNGLSECONDARYCOLOR3SVEXTPROC glad_glSecondaryColor3svEXT = NULL; |
| 3069 | PFNGLSECONDARYCOLOR3UIVEXTPROC glad_glSecondaryColor3uivEXT; | 3070 | PFNGLSECONDARYCOLOR3UBEXTPROC glad_glSecondaryColor3ubEXT = NULL; |
| 3070 | PFNGLSECONDARYCOLOR3USEXTPROC glad_glSecondaryColor3usEXT; | 3071 | PFNGLSECONDARYCOLOR3UBVEXTPROC glad_glSecondaryColor3ubvEXT = NULL; |
| 3071 | PFNGLSECONDARYCOLOR3USVEXTPROC glad_glSecondaryColor3usvEXT; | 3072 | PFNGLSECONDARYCOLOR3UIEXTPROC glad_glSecondaryColor3uiEXT = NULL; |
| 3072 | PFNGLSECONDARYCOLORPOINTEREXTPROC glad_glSecondaryColorPointerEXT; | 3073 | PFNGLSECONDARYCOLOR3UIVEXTPROC glad_glSecondaryColor3uivEXT = NULL; |
| 3073 | PFNGLGENSEMAPHORESEXTPROC glad_glGenSemaphoresEXT; | 3074 | PFNGLSECONDARYCOLOR3USEXTPROC glad_glSecondaryColor3usEXT = NULL; |
| 3074 | PFNGLDELETESEMAPHORESEXTPROC glad_glDeleteSemaphoresEXT; | 3075 | PFNGLSECONDARYCOLOR3USVEXTPROC glad_glSecondaryColor3usvEXT = NULL; |
| 3075 | PFNGLISSEMAPHOREEXTPROC glad_glIsSemaphoreEXT; | 3076 | PFNGLSECONDARYCOLORPOINTEREXTPROC glad_glSecondaryColorPointerEXT = NULL; |
| 3076 | PFNGLSEMAPHOREPARAMETERUI64VEXTPROC glad_glSemaphoreParameterui64vEXT; | 3077 | PFNGLGENSEMAPHORESEXTPROC glad_glGenSemaphoresEXT = NULL; |
| 3077 | PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC glad_glGetSemaphoreParameterui64vEXT; | 3078 | PFNGLDELETESEMAPHORESEXTPROC glad_glDeleteSemaphoresEXT = NULL; |
| 3078 | PFNGLWAITSEMAPHOREEXTPROC glad_glWaitSemaphoreEXT; | 3079 | PFNGLISSEMAPHOREEXTPROC glad_glIsSemaphoreEXT = NULL; |
| 3079 | PFNGLSIGNALSEMAPHOREEXTPROC glad_glSignalSemaphoreEXT; | 3080 | PFNGLSEMAPHOREPARAMETERUI64VEXTPROC glad_glSemaphoreParameterui64vEXT = NULL; |
| 3080 | PFNGLIMPORTSEMAPHOREFDEXTPROC glad_glImportSemaphoreFdEXT; | 3081 | PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC glad_glGetSemaphoreParameterui64vEXT = NULL; |
| 3081 | PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC glad_glImportSemaphoreWin32HandleEXT; | 3082 | PFNGLWAITSEMAPHOREEXTPROC glad_glWaitSemaphoreEXT = NULL; |
| 3082 | PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC glad_glImportSemaphoreWin32NameEXT; | 3083 | PFNGLSIGNALSEMAPHOREEXTPROC glad_glSignalSemaphoreEXT = NULL; |
| 3083 | PFNGLUSESHADERPROGRAMEXTPROC glad_glUseShaderProgramEXT; | 3084 | PFNGLIMPORTSEMAPHOREFDEXTPROC glad_glImportSemaphoreFdEXT = NULL; |
| 3084 | PFNGLACTIVEPROGRAMEXTPROC glad_glActiveProgramEXT; | 3085 | PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC glad_glImportSemaphoreWin32HandleEXT = NULL; |
| 3085 | PFNGLCREATESHADERPROGRAMEXTPROC glad_glCreateShaderProgramEXT; | 3086 | PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC glad_glImportSemaphoreWin32NameEXT = NULL; |
| 3086 | PFNGLACTIVESHADERPROGRAMEXTPROC glad_glActiveShaderProgramEXT; | 3087 | PFNGLUSESHADERPROGRAMEXTPROC glad_glUseShaderProgramEXT = NULL; |
| 3087 | PFNGLBINDPROGRAMPIPELINEEXTPROC glad_glBindProgramPipelineEXT; | 3088 | PFNGLACTIVEPROGRAMEXTPROC glad_glActiveProgramEXT = NULL; |
| 3088 | PFNGLCREATESHADERPROGRAMVEXTPROC glad_glCreateShaderProgramvEXT; | 3089 | PFNGLCREATESHADERPROGRAMEXTPROC glad_glCreateShaderProgramEXT = NULL; |
| 3089 | PFNGLDELETEPROGRAMPIPELINESEXTPROC glad_glDeleteProgramPipelinesEXT; | 3090 | PFNGLACTIVESHADERPROGRAMEXTPROC glad_glActiveShaderProgramEXT = NULL; |
| 3090 | PFNGLGENPROGRAMPIPELINESEXTPROC glad_glGenProgramPipelinesEXT; | 3091 | PFNGLBINDPROGRAMPIPELINEEXTPROC glad_glBindProgramPipelineEXT = NULL; |
| 3091 | PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC glad_glGetProgramPipelineInfoLogEXT; | 3092 | PFNGLCREATESHADERPROGRAMVEXTPROC glad_glCreateShaderProgramvEXT = NULL; |
| 3092 | PFNGLGETPROGRAMPIPELINEIVEXTPROC glad_glGetProgramPipelineivEXT; | 3093 | PFNGLDELETEPROGRAMPIPELINESEXTPROC glad_glDeleteProgramPipelinesEXT = NULL; |
| 3093 | PFNGLISPROGRAMPIPELINEEXTPROC glad_glIsProgramPipelineEXT; | 3094 | PFNGLGENPROGRAMPIPELINESEXTPROC glad_glGenProgramPipelinesEXT = NULL; |
| 3094 | PFNGLUSEPROGRAMSTAGESEXTPROC glad_glUseProgramStagesEXT; | 3095 | PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC glad_glGetProgramPipelineInfoLogEXT = NULL; |
| 3095 | PFNGLVALIDATEPROGRAMPIPELINEEXTPROC glad_glValidateProgramPipelineEXT; | 3096 | PFNGLGETPROGRAMPIPELINEIVEXTPROC glad_glGetProgramPipelineivEXT = NULL; |
| 3096 | PFNGLFRAMEBUFFERFETCHBARRIEREXTPROC glad_glFramebufferFetchBarrierEXT; | 3097 | PFNGLISPROGRAMPIPELINEEXTPROC glad_glIsProgramPipelineEXT = NULL; |
| 3097 | PFNGLBINDIMAGETEXTUREEXTPROC glad_glBindImageTextureEXT; | 3098 | PFNGLUSEPROGRAMSTAGESEXTPROC glad_glUseProgramStagesEXT = NULL; |
| 3098 | PFNGLMEMORYBARRIEREXTPROC glad_glMemoryBarrierEXT; | 3099 | PFNGLVALIDATEPROGRAMPIPELINEEXTPROC glad_glValidateProgramPipelineEXT = NULL; |
| 3099 | PFNGLSTENCILCLEARTAGEXTPROC glad_glStencilClearTagEXT; | 3100 | PFNGLFRAMEBUFFERFETCHBARRIEREXTPROC glad_glFramebufferFetchBarrierEXT = NULL; |
| 3100 | PFNGLACTIVESTENCILFACEEXTPROC glad_glActiveStencilFaceEXT; | 3101 | PFNGLBINDIMAGETEXTUREEXTPROC glad_glBindImageTextureEXT = NULL; |
| 3101 | PFNGLTEXSUBIMAGE1DEXTPROC glad_glTexSubImage1DEXT; | 3102 | PFNGLMEMORYBARRIEREXTPROC glad_glMemoryBarrierEXT = NULL; |
| 3102 | PFNGLTEXSUBIMAGE2DEXTPROC glad_glTexSubImage2DEXT; | 3103 | PFNGLSTENCILCLEARTAGEXTPROC glad_glStencilClearTagEXT = NULL; |
| 3103 | PFNGLTEXIMAGE3DEXTPROC glad_glTexImage3DEXT; | 3104 | PFNGLACTIVESTENCILFACEEXTPROC glad_glActiveStencilFaceEXT = NULL; |
| 3104 | PFNGLTEXSUBIMAGE3DEXTPROC glad_glTexSubImage3DEXT; | 3105 | PFNGLTEXSUBIMAGE1DEXTPROC glad_glTexSubImage1DEXT = NULL; |
| 3105 | PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC glad_glFramebufferTextureLayerEXT; | 3106 | PFNGLTEXSUBIMAGE2DEXTPROC glad_glTexSubImage2DEXT = NULL; |
| 3106 | PFNGLTEXBUFFEREXTPROC glad_glTexBufferEXT; | 3107 | PFNGLTEXIMAGE3DEXTPROC glad_glTexImage3DEXT = NULL; |
| 3107 | PFNGLTEXPARAMETERIIVEXTPROC glad_glTexParameterIivEXT; | 3108 | PFNGLTEXSUBIMAGE3DEXTPROC glad_glTexSubImage3DEXT = NULL; |
| 3108 | PFNGLTEXPARAMETERIUIVEXTPROC glad_glTexParameterIuivEXT; | 3109 | PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC glad_glFramebufferTextureLayerEXT = NULL; |
| 3109 | PFNGLGETTEXPARAMETERIIVEXTPROC glad_glGetTexParameterIivEXT; | 3110 | PFNGLTEXBUFFEREXTPROC glad_glTexBufferEXT = NULL; |
| 3110 | PFNGLGETTEXPARAMETERIUIVEXTPROC glad_glGetTexParameterIuivEXT; | 3111 | PFNGLTEXPARAMETERIIVEXTPROC glad_glTexParameterIivEXT = NULL; |
| 3111 | PFNGLCLEARCOLORIIEXTPROC glad_glClearColorIiEXT; | 3112 | PFNGLTEXPARAMETERIUIVEXTPROC glad_glTexParameterIuivEXT = NULL; |
| 3112 | PFNGLCLEARCOLORIUIEXTPROC glad_glClearColorIuiEXT; | 3113 | PFNGLGETTEXPARAMETERIIVEXTPROC glad_glGetTexParameterIivEXT = NULL; |
| 3113 | PFNGLARETEXTURESRESIDENTEXTPROC glad_glAreTexturesResidentEXT; | 3114 | PFNGLGETTEXPARAMETERIUIVEXTPROC glad_glGetTexParameterIuivEXT = NULL; |
| 3114 | PFNGLBINDTEXTUREEXTPROC glad_glBindTextureEXT; | 3115 | PFNGLCLEARCOLORIIEXTPROC glad_glClearColorIiEXT = NULL; |
| 3115 | PFNGLDELETETEXTURESEXTPROC glad_glDeleteTexturesEXT; | 3116 | PFNGLCLEARCOLORIUIEXTPROC glad_glClearColorIuiEXT = NULL; |
| 3116 | PFNGLGENTEXTURESEXTPROC glad_glGenTexturesEXT; | 3117 | PFNGLARETEXTURESRESIDENTEXTPROC glad_glAreTexturesResidentEXT = NULL; |
| 3117 | PFNGLISTEXTUREEXTPROC glad_glIsTextureEXT; | 3118 | PFNGLBINDTEXTUREEXTPROC glad_glBindTextureEXT = NULL; |
| 3118 | PFNGLPRIORITIZETEXTURESEXTPROC glad_glPrioritizeTexturesEXT; | 3119 | PFNGLDELETETEXTURESEXTPROC glad_glDeleteTexturesEXT = NULL; |
| 3119 | PFNGLTEXTURENORMALEXTPROC glad_glTextureNormalEXT; | 3120 | PFNGLGENTEXTURESEXTPROC glad_glGenTexturesEXT = NULL; |
| 3120 | PFNGLGETQUERYOBJECTI64VEXTPROC glad_glGetQueryObjecti64vEXT; | 3121 | PFNGLISTEXTUREEXTPROC glad_glIsTextureEXT = NULL; |
| 3121 | PFNGLGETQUERYOBJECTUI64VEXTPROC glad_glGetQueryObjectui64vEXT; | 3122 | PFNGLPRIORITIZETEXTURESEXTPROC glad_glPrioritizeTexturesEXT = NULL; |
| 3122 | PFNGLBEGINTRANSFORMFEEDBACKEXTPROC glad_glBeginTransformFeedbackEXT; | 3123 | PFNGLTEXTURENORMALEXTPROC glad_glTextureNormalEXT = NULL; |
| 3123 | PFNGLENDTRANSFORMFEEDBACKEXTPROC glad_glEndTransformFeedbackEXT; | 3124 | PFNGLGETQUERYOBJECTI64VEXTPROC glad_glGetQueryObjecti64vEXT = NULL; |
| 3124 | PFNGLBINDBUFFERRANGEEXTPROC glad_glBindBufferRangeEXT; | 3125 | PFNGLGETQUERYOBJECTUI64VEXTPROC glad_glGetQueryObjectui64vEXT = NULL; |
| 3125 | PFNGLBINDBUFFEROFFSETEXTPROC glad_glBindBufferOffsetEXT; | 3126 | PFNGLBEGINTRANSFORMFEEDBACKEXTPROC glad_glBeginTransformFeedbackEXT = NULL; |
| 3126 | PFNGLBINDBUFFERBASEEXTPROC glad_glBindBufferBaseEXT; | 3127 | PFNGLENDTRANSFORMFEEDBACKEXTPROC glad_glEndTransformFeedbackEXT = NULL; |
| 3127 | PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC glad_glTransformFeedbackVaryingsEXT; | 3128 | PFNGLBINDBUFFERRANGEEXTPROC glad_glBindBufferRangeEXT = NULL; |
| 3128 | PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC glad_glGetTransformFeedbackVaryingEXT; | 3129 | PFNGLBINDBUFFEROFFSETEXTPROC glad_glBindBufferOffsetEXT = NULL; |
| 3129 | PFNGLARRAYELEMENTEXTPROC glad_glArrayElementEXT; | 3130 | PFNGLBINDBUFFERBASEEXTPROC glad_glBindBufferBaseEXT = NULL; |
| 3130 | PFNGLCOLORPOINTEREXTPROC glad_glColorPointerEXT; | 3131 | PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC glad_glTransformFeedbackVaryingsEXT = NULL; |
| 3131 | PFNGLDRAWARRAYSEXTPROC glad_glDrawArraysEXT; | 3132 | PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC glad_glGetTransformFeedbackVaryingEXT = NULL; |
| 3132 | PFNGLEDGEFLAGPOINTEREXTPROC glad_glEdgeFlagPointerEXT; | 3133 | PFNGLARRAYELEMENTEXTPROC glad_glArrayElementEXT = NULL; |
| 3133 | PFNGLGETPOINTERVEXTPROC glad_glGetPointervEXT; | 3134 | PFNGLCOLORPOINTEREXTPROC glad_glColorPointerEXT = NULL; |
| 3134 | PFNGLINDEXPOINTEREXTPROC glad_glIndexPointerEXT; | 3135 | PFNGLDRAWARRAYSEXTPROC glad_glDrawArraysEXT = NULL; |
| 3135 | PFNGLNORMALPOINTEREXTPROC glad_glNormalPointerEXT; | 3136 | PFNGLEDGEFLAGPOINTEREXTPROC glad_glEdgeFlagPointerEXT = NULL; |
| 3136 | PFNGLTEXCOORDPOINTEREXTPROC glad_glTexCoordPointerEXT; | 3137 | PFNGLGETPOINTERVEXTPROC glad_glGetPointervEXT = NULL; |
| 3137 | PFNGLVERTEXPOINTEREXTPROC glad_glVertexPointerEXT; | 3138 | PFNGLINDEXPOINTEREXTPROC glad_glIndexPointerEXT = NULL; |
| 3138 | PFNGLVERTEXATTRIBL1DEXTPROC glad_glVertexAttribL1dEXT; | 3139 | PFNGLNORMALPOINTEREXTPROC glad_glNormalPointerEXT = NULL; |
| 3139 | PFNGLVERTEXATTRIBL2DEXTPROC glad_glVertexAttribL2dEXT; | 3140 | PFNGLTEXCOORDPOINTEREXTPROC glad_glTexCoordPointerEXT = NULL; |
| 3140 | PFNGLVERTEXATTRIBL3DEXTPROC glad_glVertexAttribL3dEXT; | 3141 | PFNGLVERTEXPOINTEREXTPROC glad_glVertexPointerEXT = NULL; |
| 3141 | PFNGLVERTEXATTRIBL4DEXTPROC glad_glVertexAttribL4dEXT; | 3142 | PFNGLVERTEXATTRIBL1DEXTPROC glad_glVertexAttribL1dEXT = NULL; |
| 3142 | PFNGLVERTEXATTRIBL1DVEXTPROC glad_glVertexAttribL1dvEXT; | 3143 | PFNGLVERTEXATTRIBL2DEXTPROC glad_glVertexAttribL2dEXT = NULL; |
| 3143 | PFNGLVERTEXATTRIBL2DVEXTPROC glad_glVertexAttribL2dvEXT; | 3144 | PFNGLVERTEXATTRIBL3DEXTPROC glad_glVertexAttribL3dEXT = NULL; |
| 3144 | PFNGLVERTEXATTRIBL3DVEXTPROC glad_glVertexAttribL3dvEXT; | 3145 | PFNGLVERTEXATTRIBL4DEXTPROC glad_glVertexAttribL4dEXT = NULL; |
| 3145 | PFNGLVERTEXATTRIBL4DVEXTPROC glad_glVertexAttribL4dvEXT; | 3146 | PFNGLVERTEXATTRIBL1DVEXTPROC glad_glVertexAttribL1dvEXT = NULL; |
| 3146 | PFNGLVERTEXATTRIBLPOINTEREXTPROC glad_glVertexAttribLPointerEXT; | 3147 | PFNGLVERTEXATTRIBL2DVEXTPROC glad_glVertexAttribL2dvEXT = NULL; |
| 3147 | PFNGLGETVERTEXATTRIBLDVEXTPROC glad_glGetVertexAttribLdvEXT; | 3148 | PFNGLVERTEXATTRIBL3DVEXTPROC glad_glVertexAttribL3dvEXT = NULL; |
| 3148 | PFNGLBEGINVERTEXSHADEREXTPROC glad_glBeginVertexShaderEXT; | 3149 | PFNGLVERTEXATTRIBL4DVEXTPROC glad_glVertexAttribL4dvEXT = NULL; |
| 3149 | PFNGLENDVERTEXSHADEREXTPROC glad_glEndVertexShaderEXT; | 3150 | PFNGLVERTEXATTRIBLPOINTEREXTPROC glad_glVertexAttribLPointerEXT = NULL; |
| 3150 | PFNGLBINDVERTEXSHADEREXTPROC glad_glBindVertexShaderEXT; | 3151 | PFNGLGETVERTEXATTRIBLDVEXTPROC glad_glGetVertexAttribLdvEXT = NULL; |
| 3151 | PFNGLGENVERTEXSHADERSEXTPROC glad_glGenVertexShadersEXT; | 3152 | PFNGLBEGINVERTEXSHADEREXTPROC glad_glBeginVertexShaderEXT = NULL; |
| 3152 | PFNGLDELETEVERTEXSHADEREXTPROC glad_glDeleteVertexShaderEXT; | 3153 | PFNGLENDVERTEXSHADEREXTPROC glad_glEndVertexShaderEXT = NULL; |
| 3153 | PFNGLSHADEROP1EXTPROC glad_glShaderOp1EXT; | 3154 | PFNGLBINDVERTEXSHADEREXTPROC glad_glBindVertexShaderEXT = NULL; |
| 3154 | PFNGLSHADEROP2EXTPROC glad_glShaderOp2EXT; | 3155 | PFNGLGENVERTEXSHADERSEXTPROC glad_glGenVertexShadersEXT = NULL; |
| 3155 | PFNGLSHADEROP3EXTPROC glad_glShaderOp3EXT; | 3156 | PFNGLDELETEVERTEXSHADEREXTPROC glad_glDeleteVertexShaderEXT = NULL; |
| 3156 | PFNGLSWIZZLEEXTPROC glad_glSwizzleEXT; | 3157 | PFNGLSHADEROP1EXTPROC glad_glShaderOp1EXT = NULL; |
| 3157 | PFNGLWRITEMASKEXTPROC glad_glWriteMaskEXT; | 3158 | PFNGLSHADEROP2EXTPROC glad_glShaderOp2EXT = NULL; |
| 3158 | PFNGLINSERTCOMPONENTEXTPROC glad_glInsertComponentEXT; | 3159 | PFNGLSHADEROP3EXTPROC glad_glShaderOp3EXT = NULL; |
| 3159 | PFNGLEXTRACTCOMPONENTEXTPROC glad_glExtractComponentEXT; | 3160 | PFNGLSWIZZLEEXTPROC glad_glSwizzleEXT = NULL; |
| 3160 | PFNGLGENSYMBOLSEXTPROC glad_glGenSymbolsEXT; | 3161 | PFNGLWRITEMASKEXTPROC glad_glWriteMaskEXT = NULL; |
| 3161 | PFNGLSETINVARIANTEXTPROC glad_glSetInvariantEXT; | 3162 | PFNGLINSERTCOMPONENTEXTPROC glad_glInsertComponentEXT = NULL; |
| 3162 | PFNGLSETLOCALCONSTANTEXTPROC glad_glSetLocalConstantEXT; | 3163 | PFNGLEXTRACTCOMPONENTEXTPROC glad_glExtractComponentEXT = NULL; |
| 3163 | PFNGLVARIANTBVEXTPROC glad_glVariantbvEXT; | 3164 | PFNGLGENSYMBOLSEXTPROC glad_glGenSymbolsEXT = NULL; |
| 3164 | PFNGLVARIANTSVEXTPROC glad_glVariantsvEXT; | 3165 | PFNGLSETINVARIANTEXTPROC glad_glSetInvariantEXT = NULL; |
| 3165 | PFNGLVARIANTIVEXTPROC glad_glVariantivEXT; | 3166 | PFNGLSETLOCALCONSTANTEXTPROC glad_glSetLocalConstantEXT = NULL; |
| 3166 | PFNGLVARIANTFVEXTPROC glad_glVariantfvEXT; | 3167 | PFNGLVARIANTBVEXTPROC glad_glVariantbvEXT = NULL; |
| 3167 | PFNGLVARIANTDVEXTPROC glad_glVariantdvEXT; | 3168 | PFNGLVARIANTSVEXTPROC glad_glVariantsvEXT = NULL; |
| 3168 | PFNGLVARIANTUBVEXTPROC glad_glVariantubvEXT; | 3169 | PFNGLVARIANTIVEXTPROC glad_glVariantivEXT = NULL; |
| 3169 | PFNGLVARIANTUSVEXTPROC glad_glVariantusvEXT; | 3170 | PFNGLVARIANTFVEXTPROC glad_glVariantfvEXT = NULL; |
| 3170 | PFNGLVARIANTUIVEXTPROC glad_glVariantuivEXT; | 3171 | PFNGLVARIANTDVEXTPROC glad_glVariantdvEXT = NULL; |
| 3171 | PFNGLVARIANTPOINTEREXTPROC glad_glVariantPointerEXT; | 3172 | PFNGLVARIANTUBVEXTPROC glad_glVariantubvEXT = NULL; |
| 3172 | PFNGLENABLEVARIANTCLIENTSTATEEXTPROC glad_glEnableVariantClientStateEXT; | 3173 | PFNGLVARIANTUSVEXTPROC glad_glVariantusvEXT = NULL; |
| 3173 | PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC glad_glDisableVariantClientStateEXT; | 3174 | PFNGLVARIANTUIVEXTPROC glad_glVariantuivEXT = NULL; |
| 3174 | PFNGLBINDLIGHTPARAMETEREXTPROC glad_glBindLightParameterEXT; | 3175 | PFNGLVARIANTPOINTEREXTPROC glad_glVariantPointerEXT = NULL; |
| 3175 | PFNGLBINDMATERIALPARAMETEREXTPROC glad_glBindMaterialParameterEXT; | 3176 | PFNGLENABLEVARIANTCLIENTSTATEEXTPROC glad_glEnableVariantClientStateEXT = NULL; |
| 3176 | PFNGLBINDTEXGENPARAMETEREXTPROC glad_glBindTexGenParameterEXT; | 3177 | PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC glad_glDisableVariantClientStateEXT = NULL; |
| 3177 | PFNGLBINDTEXTUREUNITPARAMETEREXTPROC glad_glBindTextureUnitParameterEXT; | 3178 | PFNGLBINDLIGHTPARAMETEREXTPROC glad_glBindLightParameterEXT = NULL; |
| 3178 | PFNGLBINDPARAMETEREXTPROC glad_glBindParameterEXT; | 3179 | PFNGLBINDMATERIALPARAMETEREXTPROC glad_glBindMaterialParameterEXT = NULL; |
| 3179 | PFNGLISVARIANTENABLEDEXTPROC glad_glIsVariantEnabledEXT; | 3180 | PFNGLBINDTEXGENPARAMETEREXTPROC glad_glBindTexGenParameterEXT = NULL; |
| 3180 | PFNGLGETVARIANTBOOLEANVEXTPROC glad_glGetVariantBooleanvEXT; | 3181 | PFNGLBINDTEXTUREUNITPARAMETEREXTPROC glad_glBindTextureUnitParameterEXT = NULL; |
| 3181 | PFNGLGETVARIANTINTEGERVEXTPROC glad_glGetVariantIntegervEXT; | 3182 | PFNGLBINDPARAMETEREXTPROC glad_glBindParameterEXT = NULL; |
| 3182 | PFNGLGETVARIANTFLOATVEXTPROC glad_glGetVariantFloatvEXT; | 3183 | PFNGLISVARIANTENABLEDEXTPROC glad_glIsVariantEnabledEXT = NULL; |
| 3183 | PFNGLGETVARIANTPOINTERVEXTPROC glad_glGetVariantPointervEXT; | 3184 | PFNGLGETVARIANTBOOLEANVEXTPROC glad_glGetVariantBooleanvEXT = NULL; |
| 3184 | PFNGLGETINVARIANTBOOLEANVEXTPROC glad_glGetInvariantBooleanvEXT; | 3185 | PFNGLGETVARIANTINTEGERVEXTPROC glad_glGetVariantIntegervEXT = NULL; |
| 3185 | PFNGLGETINVARIANTINTEGERVEXTPROC glad_glGetInvariantIntegervEXT; | 3186 | PFNGLGETVARIANTFLOATVEXTPROC glad_glGetVariantFloatvEXT = NULL; |
| 3186 | PFNGLGETINVARIANTFLOATVEXTPROC glad_glGetInvariantFloatvEXT; | 3187 | PFNGLGETVARIANTPOINTERVEXTPROC glad_glGetVariantPointervEXT = NULL; |
| 3187 | PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC glad_glGetLocalConstantBooleanvEXT; | 3188 | PFNGLGETINVARIANTBOOLEANVEXTPROC glad_glGetInvariantBooleanvEXT = NULL; |
| 3188 | PFNGLGETLOCALCONSTANTINTEGERVEXTPROC glad_glGetLocalConstantIntegervEXT; | 3189 | PFNGLGETINVARIANTINTEGERVEXTPROC glad_glGetInvariantIntegervEXT = NULL; |
| 3189 | PFNGLGETLOCALCONSTANTFLOATVEXTPROC glad_glGetLocalConstantFloatvEXT; | 3190 | PFNGLGETINVARIANTFLOATVEXTPROC glad_glGetInvariantFloatvEXT = NULL; |
| 3190 | PFNGLVERTEXWEIGHTFEXTPROC glad_glVertexWeightfEXT; | 3191 | PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC glad_glGetLocalConstantBooleanvEXT = NULL; |
| 3191 | PFNGLVERTEXWEIGHTFVEXTPROC glad_glVertexWeightfvEXT; | 3192 | PFNGLGETLOCALCONSTANTINTEGERVEXTPROC glad_glGetLocalConstantIntegervEXT = NULL; |
| 3192 | PFNGLVERTEXWEIGHTPOINTEREXTPROC glad_glVertexWeightPointerEXT; | 3193 | PFNGLGETLOCALCONSTANTFLOATVEXTPROC glad_glGetLocalConstantFloatvEXT = NULL; |
| 3193 | PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC glad_glAcquireKeyedMutexWin32EXT; | 3194 | PFNGLVERTEXWEIGHTFEXTPROC glad_glVertexWeightfEXT = NULL; |
| 3194 | PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC glad_glReleaseKeyedMutexWin32EXT; | 3195 | PFNGLVERTEXWEIGHTFVEXTPROC glad_glVertexWeightfvEXT = NULL; |
| 3195 | PFNGLWINDOWRECTANGLESEXTPROC glad_glWindowRectanglesEXT; | 3196 | PFNGLVERTEXWEIGHTPOINTEREXTPROC glad_glVertexWeightPointerEXT = NULL; |
| 3196 | PFNGLIMPORTSYNCEXTPROC glad_glImportSyncEXT; | 3197 | PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC glad_glAcquireKeyedMutexWin32EXT = NULL; |
| 3197 | PFNGLFRAMETERMINATORGREMEDYPROC glad_glFrameTerminatorGREMEDY; | 3198 | PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC glad_glReleaseKeyedMutexWin32EXT = NULL; |
| 3198 | PFNGLSTRINGMARKERGREMEDYPROC glad_glStringMarkerGREMEDY; | 3199 | PFNGLWINDOWRECTANGLESEXTPROC glad_glWindowRectanglesEXT = NULL; |
| 3199 | PFNGLIMAGETRANSFORMPARAMETERIHPPROC glad_glImageTransformParameteriHP; | 3200 | PFNGLIMPORTSYNCEXTPROC glad_glImportSyncEXT = NULL; |
| 3200 | PFNGLIMAGETRANSFORMPARAMETERFHPPROC glad_glImageTransformParameterfHP; | 3201 | PFNGLFRAMETERMINATORGREMEDYPROC glad_glFrameTerminatorGREMEDY = NULL; |
| 3201 | PFNGLIMAGETRANSFORMPARAMETERIVHPPROC glad_glImageTransformParameterivHP; | 3202 | PFNGLSTRINGMARKERGREMEDYPROC glad_glStringMarkerGREMEDY = NULL; |
| 3202 | PFNGLIMAGETRANSFORMPARAMETERFVHPPROC glad_glImageTransformParameterfvHP; | 3203 | PFNGLIMAGETRANSFORMPARAMETERIHPPROC glad_glImageTransformParameteriHP = NULL; |
| 3203 | PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC glad_glGetImageTransformParameterivHP; | 3204 | PFNGLIMAGETRANSFORMPARAMETERFHPPROC glad_glImageTransformParameterfHP = NULL; |
| 3204 | PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC glad_glGetImageTransformParameterfvHP; | 3205 | PFNGLIMAGETRANSFORMPARAMETERIVHPPROC glad_glImageTransformParameterivHP = NULL; |
| 3205 | PFNGLMULTIMODEDRAWARRAYSIBMPROC glad_glMultiModeDrawArraysIBM; | 3206 | PFNGLIMAGETRANSFORMPARAMETERFVHPPROC glad_glImageTransformParameterfvHP = NULL; |
| 3206 | PFNGLMULTIMODEDRAWELEMENTSIBMPROC glad_glMultiModeDrawElementsIBM; | 3207 | PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC glad_glGetImageTransformParameterivHP = NULL; |
| 3207 | PFNGLFLUSHSTATICDATAIBMPROC glad_glFlushStaticDataIBM; | 3208 | PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC glad_glGetImageTransformParameterfvHP = NULL; |
| 3208 | PFNGLCOLORPOINTERLISTIBMPROC glad_glColorPointerListIBM; | 3209 | PFNGLMULTIMODEDRAWARRAYSIBMPROC glad_glMultiModeDrawArraysIBM = NULL; |
| 3209 | PFNGLSECONDARYCOLORPOINTERLISTIBMPROC glad_glSecondaryColorPointerListIBM; | 3210 | PFNGLMULTIMODEDRAWELEMENTSIBMPROC glad_glMultiModeDrawElementsIBM = NULL; |
| 3210 | PFNGLEDGEFLAGPOINTERLISTIBMPROC glad_glEdgeFlagPointerListIBM; | 3211 | PFNGLFLUSHSTATICDATAIBMPROC glad_glFlushStaticDataIBM = NULL; |
| 3211 | PFNGLFOGCOORDPOINTERLISTIBMPROC glad_glFogCoordPointerListIBM; | 3212 | PFNGLCOLORPOINTERLISTIBMPROC glad_glColorPointerListIBM = NULL; |
| 3212 | PFNGLINDEXPOINTERLISTIBMPROC glad_glIndexPointerListIBM; | 3213 | PFNGLSECONDARYCOLORPOINTERLISTIBMPROC glad_glSecondaryColorPointerListIBM = NULL; |
| 3213 | PFNGLNORMALPOINTERLISTIBMPROC glad_glNormalPointerListIBM; | 3214 | PFNGLEDGEFLAGPOINTERLISTIBMPROC glad_glEdgeFlagPointerListIBM = NULL; |
| 3214 | PFNGLTEXCOORDPOINTERLISTIBMPROC glad_glTexCoordPointerListIBM; | 3215 | PFNGLFOGCOORDPOINTERLISTIBMPROC glad_glFogCoordPointerListIBM = NULL; |
| 3215 | PFNGLVERTEXPOINTERLISTIBMPROC glad_glVertexPointerListIBM; | 3216 | PFNGLINDEXPOINTERLISTIBMPROC glad_glIndexPointerListIBM = NULL; |
| 3216 | PFNGLBLENDFUNCSEPARATEINGRPROC glad_glBlendFuncSeparateINGR; | 3217 | PFNGLNORMALPOINTERLISTIBMPROC glad_glNormalPointerListIBM = NULL; |
| 3217 | PFNGLAPPLYFRAMEBUFFERATTACHMENTCMAAINTELPROC glad_glApplyFramebufferAttachmentCMAAINTEL; | 3218 | PFNGLTEXCOORDPOINTERLISTIBMPROC glad_glTexCoordPointerListIBM = NULL; |
| 3218 | PFNGLSYNCTEXTUREINTELPROC glad_glSyncTextureINTEL; | 3219 | PFNGLVERTEXPOINTERLISTIBMPROC glad_glVertexPointerListIBM = NULL; |
| 3219 | PFNGLUNMAPTEXTURE2DINTELPROC glad_glUnmapTexture2DINTEL; | 3220 | PFNGLBLENDFUNCSEPARATEINGRPROC glad_glBlendFuncSeparateINGR = NULL; |
| 3220 | PFNGLMAPTEXTURE2DINTELPROC glad_glMapTexture2DINTEL; | 3221 | PFNGLAPPLYFRAMEBUFFERATTACHMENTCMAAINTELPROC glad_glApplyFramebufferAttachmentCMAAINTEL = NULL; |
| 3221 | PFNGLVERTEXPOINTERVINTELPROC glad_glVertexPointervINTEL; | 3222 | PFNGLSYNCTEXTUREINTELPROC glad_glSyncTextureINTEL = NULL; |
| 3222 | PFNGLNORMALPOINTERVINTELPROC glad_glNormalPointervINTEL; | 3223 | PFNGLUNMAPTEXTURE2DINTELPROC glad_glUnmapTexture2DINTEL = NULL; |
| 3223 | PFNGLCOLORPOINTERVINTELPROC glad_glColorPointervINTEL; | 3224 | PFNGLMAPTEXTURE2DINTELPROC glad_glMapTexture2DINTEL = NULL; |
| 3224 | PFNGLTEXCOORDPOINTERVINTELPROC glad_glTexCoordPointervINTEL; | 3225 | PFNGLVERTEXPOINTERVINTELPROC glad_glVertexPointervINTEL = NULL; |
| 3225 | PFNGLBEGINPERFQUERYINTELPROC glad_glBeginPerfQueryINTEL; | 3226 | PFNGLNORMALPOINTERVINTELPROC glad_glNormalPointervINTEL = NULL; |
| 3226 | PFNGLCREATEPERFQUERYINTELPROC glad_glCreatePerfQueryINTEL; | 3227 | PFNGLCOLORPOINTERVINTELPROC glad_glColorPointervINTEL = NULL; |
| 3227 | PFNGLDELETEPERFQUERYINTELPROC glad_glDeletePerfQueryINTEL; | 3228 | PFNGLTEXCOORDPOINTERVINTELPROC glad_glTexCoordPointervINTEL = NULL; |
| 3228 | PFNGLENDPERFQUERYINTELPROC glad_glEndPerfQueryINTEL; | 3229 | PFNGLBEGINPERFQUERYINTELPROC glad_glBeginPerfQueryINTEL = NULL; |
| 3229 | PFNGLGETFIRSTPERFQUERYIDINTELPROC glad_glGetFirstPerfQueryIdINTEL; | 3230 | PFNGLCREATEPERFQUERYINTELPROC glad_glCreatePerfQueryINTEL = NULL; |
| 3230 | PFNGLGETNEXTPERFQUERYIDINTELPROC glad_glGetNextPerfQueryIdINTEL; | 3231 | PFNGLDELETEPERFQUERYINTELPROC glad_glDeletePerfQueryINTEL = NULL; |
| 3231 | PFNGLGETPERFCOUNTERINFOINTELPROC glad_glGetPerfCounterInfoINTEL; | 3232 | PFNGLENDPERFQUERYINTELPROC glad_glEndPerfQueryINTEL = NULL; |
| 3232 | PFNGLGETPERFQUERYDATAINTELPROC glad_glGetPerfQueryDataINTEL; | 3233 | PFNGLGETFIRSTPERFQUERYIDINTELPROC glad_glGetFirstPerfQueryIdINTEL = NULL; |
| 3233 | PFNGLGETPERFQUERYIDBYNAMEINTELPROC glad_glGetPerfQueryIdByNameINTEL; | 3234 | PFNGLGETNEXTPERFQUERYIDINTELPROC glad_glGetNextPerfQueryIdINTEL = NULL; |
| 3234 | PFNGLGETPERFQUERYINFOINTELPROC glad_glGetPerfQueryInfoINTEL; | 3235 | PFNGLGETPERFCOUNTERINFOINTELPROC glad_glGetPerfCounterInfoINTEL = NULL; |
| 3235 | PFNGLBLENDBARRIERKHRPROC glad_glBlendBarrierKHR; | 3236 | PFNGLGETPERFQUERYDATAINTELPROC glad_glGetPerfQueryDataINTEL = NULL; |
| 3236 | PFNGLDEBUGMESSAGECONTROLPROC glad_glDebugMessageControl; | 3237 | PFNGLGETPERFQUERYIDBYNAMEINTELPROC glad_glGetPerfQueryIdByNameINTEL = NULL; |
| 3237 | PFNGLDEBUGMESSAGEINSERTPROC glad_glDebugMessageInsert; | 3238 | PFNGLGETPERFQUERYINFOINTELPROC glad_glGetPerfQueryInfoINTEL = NULL; |
| 3238 | PFNGLDEBUGMESSAGECALLBACKPROC glad_glDebugMessageCallback; | 3239 | PFNGLBLENDBARRIERKHRPROC glad_glBlendBarrierKHR = NULL; |
| 3239 | PFNGLGETDEBUGMESSAGELOGPROC glad_glGetDebugMessageLog; | 3240 | PFNGLDEBUGMESSAGECONTROLPROC glad_glDebugMessageControl = NULL; |
| 3240 | PFNGLPUSHDEBUGGROUPPROC glad_glPushDebugGroup; | 3241 | PFNGLDEBUGMESSAGEINSERTPROC glad_glDebugMessageInsert = NULL; |
| 3241 | PFNGLPOPDEBUGGROUPPROC glad_glPopDebugGroup; | 3242 | PFNGLDEBUGMESSAGECALLBACKPROC glad_glDebugMessageCallback = NULL; |
| 3242 | PFNGLOBJECTLABELPROC glad_glObjectLabel; | 3243 | PFNGLGETDEBUGMESSAGELOGPROC glad_glGetDebugMessageLog = NULL; |
| 3243 | PFNGLGETOBJECTLABELPROC glad_glGetObjectLabel; | 3244 | PFNGLPUSHDEBUGGROUPPROC glad_glPushDebugGroup = NULL; |
| 3244 | PFNGLOBJECTPTRLABELPROC glad_glObjectPtrLabel; | 3245 | PFNGLPOPDEBUGGROUPPROC glad_glPopDebugGroup = NULL; |
| 3245 | PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel; | 3246 | PFNGLOBJECTLABELPROC glad_glObjectLabel = NULL; |
| 3246 | PFNGLGETPOINTERVPROC glad_glGetPointerv; | 3247 | PFNGLGETOBJECTLABELPROC glad_glGetObjectLabel = NULL; |
| 3247 | PFNGLDEBUGMESSAGECONTROLKHRPROC glad_glDebugMessageControlKHR; | 3248 | PFNGLOBJECTPTRLABELPROC glad_glObjectPtrLabel = NULL; |
| 3248 | PFNGLDEBUGMESSAGEINSERTKHRPROC glad_glDebugMessageInsertKHR; | 3249 | PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel = NULL; |
| 3249 | PFNGLDEBUGMESSAGECALLBACKKHRPROC glad_glDebugMessageCallbackKHR; | 3250 | PFNGLGETPOINTERVPROC glad_glGetPointerv = NULL; |
| 3250 | PFNGLGETDEBUGMESSAGELOGKHRPROC glad_glGetDebugMessageLogKHR; | 3251 | PFNGLDEBUGMESSAGECONTROLKHRPROC glad_glDebugMessageControlKHR = NULL; |
| 3251 | PFNGLPUSHDEBUGGROUPKHRPROC glad_glPushDebugGroupKHR; | 3252 | PFNGLDEBUGMESSAGEINSERTKHRPROC glad_glDebugMessageInsertKHR = NULL; |
| 3252 | PFNGLPOPDEBUGGROUPKHRPROC glad_glPopDebugGroupKHR; | 3253 | PFNGLDEBUGMESSAGECALLBACKKHRPROC glad_glDebugMessageCallbackKHR = NULL; |
| 3253 | PFNGLOBJECTLABELKHRPROC glad_glObjectLabelKHR; | 3254 | PFNGLGETDEBUGMESSAGELOGKHRPROC glad_glGetDebugMessageLogKHR = NULL; |
| 3254 | PFNGLGETOBJECTLABELKHRPROC glad_glGetObjectLabelKHR; | 3255 | PFNGLPUSHDEBUGGROUPKHRPROC glad_glPushDebugGroupKHR = NULL; |
| 3255 | PFNGLOBJECTPTRLABELKHRPROC glad_glObjectPtrLabelKHR; | 3256 | PFNGLPOPDEBUGGROUPKHRPROC glad_glPopDebugGroupKHR = NULL; |
| 3256 | PFNGLGETOBJECTPTRLABELKHRPROC glad_glGetObjectPtrLabelKHR; | 3257 | PFNGLOBJECTLABELKHRPROC glad_glObjectLabelKHR = NULL; |
| 3257 | PFNGLGETPOINTERVKHRPROC glad_glGetPointervKHR; | 3258 | PFNGLGETOBJECTLABELKHRPROC glad_glGetObjectLabelKHR = NULL; |
| 3258 | PFNGLMAXSHADERCOMPILERTHREADSKHRPROC glad_glMaxShaderCompilerThreadsKHR; | 3259 | PFNGLOBJECTPTRLABELKHRPROC glad_glObjectPtrLabelKHR = NULL; |
| 3259 | PFNGLGETGRAPHICSRESETSTATUSPROC glad_glGetGraphicsResetStatus; | 3260 | PFNGLGETOBJECTPTRLABELKHRPROC glad_glGetObjectPtrLabelKHR = NULL; |
| 3260 | PFNGLREADNPIXELSPROC glad_glReadnPixels; | 3261 | PFNGLGETPOINTERVKHRPROC glad_glGetPointervKHR = NULL; |
| 3261 | PFNGLGETNUNIFORMFVPROC glad_glGetnUniformfv; | 3262 | PFNGLMAXSHADERCOMPILERTHREADSKHRPROC glad_glMaxShaderCompilerThreadsKHR = NULL; |
| 3262 | PFNGLGETNUNIFORMIVPROC glad_glGetnUniformiv; | 3263 | PFNGLGETGRAPHICSRESETSTATUSPROC glad_glGetGraphicsResetStatus = NULL; |
| 3263 | PFNGLGETNUNIFORMUIVPROC glad_glGetnUniformuiv; | 3264 | PFNGLREADNPIXELSPROC glad_glReadnPixels = NULL; |
| 3264 | PFNGLGETGRAPHICSRESETSTATUSKHRPROC glad_glGetGraphicsResetStatusKHR; | 3265 | PFNGLGETNUNIFORMFVPROC glad_glGetnUniformfv = NULL; |
| 3265 | PFNGLREADNPIXELSKHRPROC glad_glReadnPixelsKHR; | 3266 | PFNGLGETNUNIFORMIVPROC glad_glGetnUniformiv = NULL; |
| 3266 | PFNGLGETNUNIFORMFVKHRPROC glad_glGetnUniformfvKHR; | 3267 | PFNGLGETNUNIFORMUIVPROC glad_glGetnUniformuiv = NULL; |
| 3267 | PFNGLGETNUNIFORMIVKHRPROC glad_glGetnUniformivKHR; | 3268 | PFNGLGETGRAPHICSRESETSTATUSKHRPROC glad_glGetGraphicsResetStatusKHR = NULL; |
| 3268 | PFNGLGETNUNIFORMUIVKHRPROC glad_glGetnUniformuivKHR; | 3269 | PFNGLREADNPIXELSKHRPROC glad_glReadnPixelsKHR = NULL; |
| 3269 | PFNGLRESIZEBUFFERSMESAPROC glad_glResizeBuffersMESA; | 3270 | PFNGLGETNUNIFORMFVKHRPROC glad_glGetnUniformfvKHR = NULL; |
| 3270 | PFNGLWINDOWPOS2DMESAPROC glad_glWindowPos2dMESA; | 3271 | PFNGLGETNUNIFORMIVKHRPROC glad_glGetnUniformivKHR = NULL; |
| 3271 | PFNGLWINDOWPOS2DVMESAPROC glad_glWindowPos2dvMESA; | 3272 | PFNGLGETNUNIFORMUIVKHRPROC glad_glGetnUniformuivKHR = NULL; |
| 3272 | PFNGLWINDOWPOS2FMESAPROC glad_glWindowPos2fMESA; | 3273 | PFNGLRESIZEBUFFERSMESAPROC glad_glResizeBuffersMESA = NULL; |
| 3273 | PFNGLWINDOWPOS2FVMESAPROC glad_glWindowPos2fvMESA; | 3274 | PFNGLWINDOWPOS2DMESAPROC glad_glWindowPos2dMESA = NULL; |
| 3274 | PFNGLWINDOWPOS2IMESAPROC glad_glWindowPos2iMESA; | 3275 | PFNGLWINDOWPOS2DVMESAPROC glad_glWindowPos2dvMESA = NULL; |
| 3275 | PFNGLWINDOWPOS2IVMESAPROC glad_glWindowPos2ivMESA; | 3276 | PFNGLWINDOWPOS2FMESAPROC glad_glWindowPos2fMESA = NULL; |
| 3276 | PFNGLWINDOWPOS2SMESAPROC glad_glWindowPos2sMESA; | 3277 | PFNGLWINDOWPOS2FVMESAPROC glad_glWindowPos2fvMESA = NULL; |
| 3277 | PFNGLWINDOWPOS2SVMESAPROC glad_glWindowPos2svMESA; | 3278 | PFNGLWINDOWPOS2IMESAPROC glad_glWindowPos2iMESA = NULL; |
| 3278 | PFNGLWINDOWPOS3DMESAPROC glad_glWindowPos3dMESA; | 3279 | PFNGLWINDOWPOS2IVMESAPROC glad_glWindowPos2ivMESA = NULL; |
| 3279 | PFNGLWINDOWPOS3DVMESAPROC glad_glWindowPos3dvMESA; | 3280 | PFNGLWINDOWPOS2SMESAPROC glad_glWindowPos2sMESA = NULL; |
| 3280 | PFNGLWINDOWPOS3FMESAPROC glad_glWindowPos3fMESA; | 3281 | PFNGLWINDOWPOS2SVMESAPROC glad_glWindowPos2svMESA = NULL; |
| 3281 | PFNGLWINDOWPOS3FVMESAPROC glad_glWindowPos3fvMESA; | 3282 | PFNGLWINDOWPOS3DMESAPROC glad_glWindowPos3dMESA = NULL; |
| 3282 | PFNGLWINDOWPOS3IMESAPROC glad_glWindowPos3iMESA; | 3283 | PFNGLWINDOWPOS3DVMESAPROC glad_glWindowPos3dvMESA = NULL; |
| 3283 | PFNGLWINDOWPOS3IVMESAPROC glad_glWindowPos3ivMESA; | 3284 | PFNGLWINDOWPOS3FMESAPROC glad_glWindowPos3fMESA = NULL; |
| 3284 | PFNGLWINDOWPOS3SMESAPROC glad_glWindowPos3sMESA; | 3285 | PFNGLWINDOWPOS3FVMESAPROC glad_glWindowPos3fvMESA = NULL; |
| 3285 | PFNGLWINDOWPOS3SVMESAPROC glad_glWindowPos3svMESA; | 3286 | PFNGLWINDOWPOS3IMESAPROC glad_glWindowPos3iMESA = NULL; |
| 3286 | PFNGLWINDOWPOS4DMESAPROC glad_glWindowPos4dMESA; | 3287 | PFNGLWINDOWPOS3IVMESAPROC glad_glWindowPos3ivMESA = NULL; |
| 3287 | PFNGLWINDOWPOS4DVMESAPROC glad_glWindowPos4dvMESA; | 3288 | PFNGLWINDOWPOS3SMESAPROC glad_glWindowPos3sMESA = NULL; |
| 3288 | PFNGLWINDOWPOS4FMESAPROC glad_glWindowPos4fMESA; | 3289 | PFNGLWINDOWPOS3SVMESAPROC glad_glWindowPos3svMESA = NULL; |
| 3289 | PFNGLWINDOWPOS4FVMESAPROC glad_glWindowPos4fvMESA; | 3290 | PFNGLWINDOWPOS4DMESAPROC glad_glWindowPos4dMESA = NULL; |
| 3290 | PFNGLWINDOWPOS4IMESAPROC glad_glWindowPos4iMESA; | 3291 | PFNGLWINDOWPOS4DVMESAPROC glad_glWindowPos4dvMESA = NULL; |
| 3291 | PFNGLWINDOWPOS4IVMESAPROC glad_glWindowPos4ivMESA; | 3292 | PFNGLWINDOWPOS4FMESAPROC glad_glWindowPos4fMESA = NULL; |
| 3292 | PFNGLWINDOWPOS4SMESAPROC glad_glWindowPos4sMESA; | 3293 | PFNGLWINDOWPOS4FVMESAPROC glad_glWindowPos4fvMESA = NULL; |
| 3293 | PFNGLWINDOWPOS4SVMESAPROC glad_glWindowPos4svMESA; | 3294 | PFNGLWINDOWPOS4IMESAPROC glad_glWindowPos4iMESA = NULL; |
| 3294 | PFNGLBEGINCONDITIONALRENDERNVXPROC glad_glBeginConditionalRenderNVX; | 3295 | PFNGLWINDOWPOS4IVMESAPROC glad_glWindowPos4ivMESA = NULL; |
| 3295 | PFNGLENDCONDITIONALRENDERNVXPROC glad_glEndConditionalRenderNVX; | 3296 | PFNGLWINDOWPOS4SMESAPROC glad_glWindowPos4sMESA = NULL; |
| 3296 | PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC glad_glLGPUNamedBufferSubDataNVX; | 3297 | PFNGLWINDOWPOS4SVMESAPROC glad_glWindowPos4svMESA = NULL; |
| 3297 | PFNGLLGPUCOPYIMAGESUBDATANVXPROC glad_glLGPUCopyImageSubDataNVX; | 3298 | PFNGLBEGINCONDITIONALRENDERNVXPROC glad_glBeginConditionalRenderNVX = NULL; |
| 3298 | PFNGLLGPUINTERLOCKNVXPROC glad_glLGPUInterlockNVX; | 3299 | PFNGLENDCONDITIONALRENDERNVXPROC glad_glEndConditionalRenderNVX = NULL; |
| 3299 | PFNGLALPHATOCOVERAGEDITHERCONTROLNVPROC glad_glAlphaToCoverageDitherControlNV; | 3300 | PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC glad_glLGPUNamedBufferSubDataNVX = NULL; |
| 3300 | PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC glad_glMultiDrawArraysIndirectBindlessNV; | 3301 | PFNGLLGPUCOPYIMAGESUBDATANVXPROC glad_glLGPUCopyImageSubDataNVX = NULL; |
| 3301 | PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC glad_glMultiDrawElementsIndirectBindlessNV; | 3302 | PFNGLLGPUINTERLOCKNVXPROC glad_glLGPUInterlockNVX = NULL; |
| 3302 | PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC glad_glMultiDrawArraysIndirectBindlessCountNV; | 3303 | PFNGLALPHATOCOVERAGEDITHERCONTROLNVPROC glad_glAlphaToCoverageDitherControlNV = NULL; |
| 3303 | PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC glad_glMultiDrawElementsIndirectBindlessCountNV; | 3304 | PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC glad_glMultiDrawArraysIndirectBindlessNV = NULL; |
| 3304 | PFNGLGETTEXTUREHANDLENVPROC glad_glGetTextureHandleNV; | 3305 | PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC glad_glMultiDrawElementsIndirectBindlessNV = NULL; |
| 3305 | PFNGLGETTEXTURESAMPLERHANDLENVPROC glad_glGetTextureSamplerHandleNV; | 3306 | PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC glad_glMultiDrawArraysIndirectBindlessCountNV = NULL; |
| 3306 | PFNGLMAKETEXTUREHANDLERESIDENTNVPROC glad_glMakeTextureHandleResidentNV; | 3307 | PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC glad_glMultiDrawElementsIndirectBindlessCountNV = NULL; |
| 3307 | PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC glad_glMakeTextureHandleNonResidentNV; | 3308 | PFNGLGETTEXTUREHANDLENVPROC glad_glGetTextureHandleNV = NULL; |
| 3308 | PFNGLGETIMAGEHANDLENVPROC glad_glGetImageHandleNV; | 3309 | PFNGLGETTEXTURESAMPLERHANDLENVPROC glad_glGetTextureSamplerHandleNV = NULL; |
| 3309 | PFNGLMAKEIMAGEHANDLERESIDENTNVPROC glad_glMakeImageHandleResidentNV; | 3310 | PFNGLMAKETEXTUREHANDLERESIDENTNVPROC glad_glMakeTextureHandleResidentNV = NULL; |
| 3310 | PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC glad_glMakeImageHandleNonResidentNV; | 3311 | PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC glad_glMakeTextureHandleNonResidentNV = NULL; |
| 3311 | PFNGLUNIFORMHANDLEUI64NVPROC glad_glUniformHandleui64NV; | 3312 | PFNGLGETIMAGEHANDLENVPROC glad_glGetImageHandleNV = NULL; |
| 3312 | PFNGLUNIFORMHANDLEUI64VNVPROC glad_glUniformHandleui64vNV; | 3313 | PFNGLMAKEIMAGEHANDLERESIDENTNVPROC glad_glMakeImageHandleResidentNV = NULL; |
| 3313 | PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC glad_glProgramUniformHandleui64NV; | 3314 | PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC glad_glMakeImageHandleNonResidentNV = NULL; |
| 3314 | PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC glad_glProgramUniformHandleui64vNV; | 3315 | PFNGLUNIFORMHANDLEUI64NVPROC glad_glUniformHandleui64NV = NULL; |
| 3315 | PFNGLISTEXTUREHANDLERESIDENTNVPROC glad_glIsTextureHandleResidentNV; | 3316 | PFNGLUNIFORMHANDLEUI64VNVPROC glad_glUniformHandleui64vNV = NULL; |
| 3316 | PFNGLISIMAGEHANDLERESIDENTNVPROC glad_glIsImageHandleResidentNV; | 3317 | PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC glad_glProgramUniformHandleui64NV = NULL; |
| 3317 | PFNGLBLENDPARAMETERINVPROC glad_glBlendParameteriNV; | 3318 | PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC glad_glProgramUniformHandleui64vNV = NULL; |
| 3318 | PFNGLBLENDBARRIERNVPROC glad_glBlendBarrierNV; | 3319 | PFNGLISTEXTUREHANDLERESIDENTNVPROC glad_glIsTextureHandleResidentNV = NULL; |
| 3319 | PFNGLVIEWPORTPOSITIONWSCALENVPROC glad_glViewportPositionWScaleNV; | 3320 | PFNGLISIMAGEHANDLERESIDENTNVPROC glad_glIsImageHandleResidentNV = NULL; |
| 3320 | PFNGLCREATESTATESNVPROC glad_glCreateStatesNV; | 3321 | PFNGLBLENDPARAMETERINVPROC glad_glBlendParameteriNV = NULL; |
| 3321 | PFNGLDELETESTATESNVPROC glad_glDeleteStatesNV; | 3322 | PFNGLBLENDBARRIERNVPROC glad_glBlendBarrierNV = NULL; |
| 3322 | PFNGLISSTATENVPROC glad_glIsStateNV; | 3323 | PFNGLVIEWPORTPOSITIONWSCALENVPROC glad_glViewportPositionWScaleNV = NULL; |
| 3323 | PFNGLSTATECAPTURENVPROC glad_glStateCaptureNV; | 3324 | PFNGLCREATESTATESNVPROC glad_glCreateStatesNV = NULL; |
| 3324 | PFNGLGETCOMMANDHEADERNVPROC glad_glGetCommandHeaderNV; | 3325 | PFNGLDELETESTATESNVPROC glad_glDeleteStatesNV = NULL; |
| 3325 | PFNGLGETSTAGEINDEXNVPROC glad_glGetStageIndexNV; | 3326 | PFNGLISSTATENVPROC glad_glIsStateNV = NULL; |
| 3326 | PFNGLDRAWCOMMANDSNVPROC glad_glDrawCommandsNV; | 3327 | PFNGLSTATECAPTURENVPROC glad_glStateCaptureNV = NULL; |
| 3327 | PFNGLDRAWCOMMANDSADDRESSNVPROC glad_glDrawCommandsAddressNV; | 3328 | PFNGLGETCOMMANDHEADERNVPROC glad_glGetCommandHeaderNV = NULL; |
| 3328 | PFNGLDRAWCOMMANDSSTATESNVPROC glad_glDrawCommandsStatesNV; | 3329 | PFNGLGETSTAGEINDEXNVPROC glad_glGetStageIndexNV = NULL; |
| 3329 | PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC glad_glDrawCommandsStatesAddressNV; | 3330 | PFNGLDRAWCOMMANDSNVPROC glad_glDrawCommandsNV = NULL; |
| 3330 | PFNGLCREATECOMMANDLISTSNVPROC glad_glCreateCommandListsNV; | 3331 | PFNGLDRAWCOMMANDSADDRESSNVPROC glad_glDrawCommandsAddressNV = NULL; |
| 3331 | PFNGLDELETECOMMANDLISTSNVPROC glad_glDeleteCommandListsNV; | 3332 | PFNGLDRAWCOMMANDSSTATESNVPROC glad_glDrawCommandsStatesNV = NULL; |
| 3332 | PFNGLISCOMMANDLISTNVPROC glad_glIsCommandListNV; | 3333 | PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC glad_glDrawCommandsStatesAddressNV = NULL; |
| 3333 | PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC glad_glListDrawCommandsStatesClientNV; | 3334 | PFNGLCREATECOMMANDLISTSNVPROC glad_glCreateCommandListsNV = NULL; |
| 3334 | PFNGLCOMMANDLISTSEGMENTSNVPROC glad_glCommandListSegmentsNV; | 3335 | PFNGLDELETECOMMANDLISTSNVPROC glad_glDeleteCommandListsNV = NULL; |
| 3335 | PFNGLCOMPILECOMMANDLISTNVPROC glad_glCompileCommandListNV; | 3336 | PFNGLISCOMMANDLISTNVPROC glad_glIsCommandListNV = NULL; |
| 3336 | PFNGLCALLCOMMANDLISTNVPROC glad_glCallCommandListNV; | 3337 | PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC glad_glListDrawCommandsStatesClientNV = NULL; |
| 3337 | PFNGLBEGINCONDITIONALRENDERNVPROC glad_glBeginConditionalRenderNV; | 3338 | PFNGLCOMMANDLISTSEGMENTSNVPROC glad_glCommandListSegmentsNV = NULL; |
| 3338 | PFNGLENDCONDITIONALRENDERNVPROC glad_glEndConditionalRenderNV; | 3339 | PFNGLCOMPILECOMMANDLISTNVPROC glad_glCompileCommandListNV = NULL; |
| 3339 | PFNGLSUBPIXELPRECISIONBIASNVPROC glad_glSubpixelPrecisionBiasNV; | 3340 | PFNGLCALLCOMMANDLISTNVPROC glad_glCallCommandListNV = NULL; |
| 3340 | PFNGLCONSERVATIVERASTERPARAMETERFNVPROC glad_glConservativeRasterParameterfNV; | 3341 | PFNGLBEGINCONDITIONALRENDERNVPROC glad_glBeginConditionalRenderNV = NULL; |
| 3341 | PFNGLCONSERVATIVERASTERPARAMETERINVPROC glad_glConservativeRasterParameteriNV; | 3342 | PFNGLENDCONDITIONALRENDERNVPROC glad_glEndConditionalRenderNV = NULL; |
| 3342 | PFNGLCOPYIMAGESUBDATANVPROC glad_glCopyImageSubDataNV; | 3343 | PFNGLSUBPIXELPRECISIONBIASNVPROC glad_glSubpixelPrecisionBiasNV = NULL; |
| 3343 | PFNGLDEPTHRANGEDNVPROC glad_glDepthRangedNV; | 3344 | PFNGLCONSERVATIVERASTERPARAMETERFNVPROC glad_glConservativeRasterParameterfNV = NULL; |
| 3344 | PFNGLCLEARDEPTHDNVPROC glad_glClearDepthdNV; | 3345 | PFNGLCONSERVATIVERASTERPARAMETERINVPROC glad_glConservativeRasterParameteriNV = NULL; |
| 3345 | PFNGLDEPTHBOUNDSDNVPROC glad_glDepthBoundsdNV; | 3346 | PFNGLCOPYIMAGESUBDATANVPROC glad_glCopyImageSubDataNV = NULL; |
| 3346 | PFNGLDRAWTEXTURENVPROC glad_glDrawTextureNV; | 3347 | PFNGLDEPTHRANGEDNVPROC glad_glDepthRangedNV = NULL; |
| 3347 | PFNGLDRAWVKIMAGENVPROC glad_glDrawVkImageNV; | 3348 | PFNGLCLEARDEPTHDNVPROC glad_glClearDepthdNV = NULL; |
| 3348 | PFNGLGETVKPROCADDRNVPROC glad_glGetVkProcAddrNV; | 3349 | PFNGLDEPTHBOUNDSDNVPROC glad_glDepthBoundsdNV = NULL; |
| 3349 | PFNGLWAITVKSEMAPHORENVPROC glad_glWaitVkSemaphoreNV; | 3350 | PFNGLDRAWTEXTURENVPROC glad_glDrawTextureNV = NULL; |
| 3350 | PFNGLSIGNALVKSEMAPHORENVPROC glad_glSignalVkSemaphoreNV; | 3351 | PFNGLDRAWVKIMAGENVPROC glad_glDrawVkImageNV = NULL; |
| 3351 | PFNGLSIGNALVKFENCENVPROC glad_glSignalVkFenceNV; | 3352 | PFNGLGETVKPROCADDRNVPROC glad_glGetVkProcAddrNV = NULL; |
| 3352 | PFNGLMAPCONTROLPOINTSNVPROC glad_glMapControlPointsNV; | 3353 | PFNGLWAITVKSEMAPHORENVPROC glad_glWaitVkSemaphoreNV = NULL; |
| 3353 | PFNGLMAPPARAMETERIVNVPROC glad_glMapParameterivNV; | 3354 | PFNGLSIGNALVKSEMAPHORENVPROC glad_glSignalVkSemaphoreNV = NULL; |
| 3354 | PFNGLMAPPARAMETERFVNVPROC glad_glMapParameterfvNV; | 3355 | PFNGLSIGNALVKFENCENVPROC glad_glSignalVkFenceNV = NULL; |
| 3355 | PFNGLGETMAPCONTROLPOINTSNVPROC glad_glGetMapControlPointsNV; | 3356 | PFNGLMAPCONTROLPOINTSNVPROC glad_glMapControlPointsNV = NULL; |
| 3356 | PFNGLGETMAPPARAMETERIVNVPROC glad_glGetMapParameterivNV; | 3357 | PFNGLMAPPARAMETERIVNVPROC glad_glMapParameterivNV = NULL; |
| 3357 | PFNGLGETMAPPARAMETERFVNVPROC glad_glGetMapParameterfvNV; | 3358 | PFNGLMAPPARAMETERFVNVPROC glad_glMapParameterfvNV = NULL; |
| 3358 | PFNGLGETMAPATTRIBPARAMETERIVNVPROC glad_glGetMapAttribParameterivNV; | 3359 | PFNGLGETMAPCONTROLPOINTSNVPROC glad_glGetMapControlPointsNV = NULL; |
| 3359 | PFNGLGETMAPATTRIBPARAMETERFVNVPROC glad_glGetMapAttribParameterfvNV; | 3360 | PFNGLGETMAPPARAMETERIVNVPROC glad_glGetMapParameterivNV = NULL; |
| 3360 | PFNGLEVALMAPSNVPROC glad_glEvalMapsNV; | 3361 | PFNGLGETMAPPARAMETERFVNVPROC glad_glGetMapParameterfvNV = NULL; |
| 3361 | PFNGLGETMULTISAMPLEFVNVPROC glad_glGetMultisamplefvNV; | 3362 | PFNGLGETMAPATTRIBPARAMETERIVNVPROC glad_glGetMapAttribParameterivNV = NULL; |
| 3362 | PFNGLSAMPLEMASKINDEXEDNVPROC glad_glSampleMaskIndexedNV; | 3363 | PFNGLGETMAPATTRIBPARAMETERFVNVPROC glad_glGetMapAttribParameterfvNV = NULL; |
| 3363 | PFNGLTEXRENDERBUFFERNVPROC glad_glTexRenderbufferNV; | 3364 | PFNGLEVALMAPSNVPROC glad_glEvalMapsNV = NULL; |
| 3364 | PFNGLDELETEFENCESNVPROC glad_glDeleteFencesNV; | 3365 | PFNGLGETMULTISAMPLEFVNVPROC glad_glGetMultisamplefvNV = NULL; |
| 3365 | PFNGLGENFENCESNVPROC glad_glGenFencesNV; | 3366 | PFNGLSAMPLEMASKINDEXEDNVPROC glad_glSampleMaskIndexedNV = NULL; |
| 3366 | PFNGLISFENCENVPROC glad_glIsFenceNV; | 3367 | PFNGLTEXRENDERBUFFERNVPROC glad_glTexRenderbufferNV = NULL; |
| 3367 | PFNGLTESTFENCENVPROC glad_glTestFenceNV; | 3368 | PFNGLDELETEFENCESNVPROC glad_glDeleteFencesNV = NULL; |
| 3368 | PFNGLGETFENCEIVNVPROC glad_glGetFenceivNV; | 3369 | PFNGLGENFENCESNVPROC glad_glGenFencesNV = NULL; |
| 3369 | PFNGLFINISHFENCENVPROC glad_glFinishFenceNV; | 3370 | PFNGLISFENCENVPROC glad_glIsFenceNV = NULL; |
| 3370 | PFNGLSETFENCENVPROC glad_glSetFenceNV; | 3371 | PFNGLTESTFENCENVPROC glad_glTestFenceNV = NULL; |
| 3371 | PFNGLFRAGMENTCOVERAGECOLORNVPROC glad_glFragmentCoverageColorNV; | 3372 | PFNGLGETFENCEIVNVPROC glad_glGetFenceivNV = NULL; |
| 3372 | PFNGLPROGRAMNAMEDPARAMETER4FNVPROC glad_glProgramNamedParameter4fNV; | 3373 | PFNGLFINISHFENCENVPROC glad_glFinishFenceNV = NULL; |
| 3373 | PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC glad_glProgramNamedParameter4fvNV; | 3374 | PFNGLSETFENCENVPROC glad_glSetFenceNV = NULL; |
| 3374 | PFNGLPROGRAMNAMEDPARAMETER4DNVPROC glad_glProgramNamedParameter4dNV; | 3375 | PFNGLFRAGMENTCOVERAGECOLORNVPROC glad_glFragmentCoverageColorNV = NULL; |
| 3375 | PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC glad_glProgramNamedParameter4dvNV; | 3376 | PFNGLPROGRAMNAMEDPARAMETER4FNVPROC glad_glProgramNamedParameter4fNV = NULL; |
| 3376 | PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC glad_glGetProgramNamedParameterfvNV; | 3377 | PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC glad_glProgramNamedParameter4fvNV = NULL; |
| 3377 | PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC glad_glGetProgramNamedParameterdvNV; | 3378 | PFNGLPROGRAMNAMEDPARAMETER4DNVPROC glad_glProgramNamedParameter4dNV = NULL; |
| 3378 | PFNGLCOVERAGEMODULATIONTABLENVPROC glad_glCoverageModulationTableNV; | 3379 | PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC glad_glProgramNamedParameter4dvNV = NULL; |
| 3379 | PFNGLGETCOVERAGEMODULATIONTABLENVPROC glad_glGetCoverageModulationTableNV; | 3380 | PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC glad_glGetProgramNamedParameterfvNV = NULL; |
| 3380 | PFNGLCOVERAGEMODULATIONNVPROC glad_glCoverageModulationNV; | 3381 | PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC glad_glGetProgramNamedParameterdvNV = NULL; |
| 3381 | PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC glad_glRenderbufferStorageMultisampleCoverageNV; | 3382 | PFNGLCOVERAGEMODULATIONTABLENVPROC glad_glCoverageModulationTableNV = NULL; |
| 3382 | PFNGLPROGRAMVERTEXLIMITNVPROC glad_glProgramVertexLimitNV; | 3383 | PFNGLGETCOVERAGEMODULATIONTABLENVPROC glad_glGetCoverageModulationTableNV = NULL; |
| 3383 | PFNGLFRAMEBUFFERTEXTUREEXTPROC glad_glFramebufferTextureEXT; | 3384 | PFNGLCOVERAGEMODULATIONNVPROC glad_glCoverageModulationNV = NULL; |
| 3384 | PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC glad_glFramebufferTextureFaceEXT; | 3385 | PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC glad_glRenderbufferStorageMultisampleCoverageNV = NULL; |
| 3385 | PFNGLRENDERGPUMASKNVPROC glad_glRenderGpuMaskNV; | 3386 | PFNGLPROGRAMVERTEXLIMITNVPROC glad_glProgramVertexLimitNV = NULL; |
| 3386 | PFNGLMULTICASTBUFFERSUBDATANVPROC glad_glMulticastBufferSubDataNV; | 3387 | PFNGLFRAMEBUFFERTEXTUREEXTPROC glad_glFramebufferTextureEXT = NULL; |
| 3387 | PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC glad_glMulticastCopyBufferSubDataNV; | 3388 | PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC glad_glFramebufferTextureFaceEXT = NULL; |
| 3388 | PFNGLMULTICASTCOPYIMAGESUBDATANVPROC glad_glMulticastCopyImageSubDataNV; | 3389 | PFNGLRENDERGPUMASKNVPROC glad_glRenderGpuMaskNV = NULL; |
| 3389 | PFNGLMULTICASTBLITFRAMEBUFFERNVPROC glad_glMulticastBlitFramebufferNV; | 3390 | PFNGLMULTICASTBUFFERSUBDATANVPROC glad_glMulticastBufferSubDataNV = NULL; |
| 3390 | PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glMulticastFramebufferSampleLocationsfvNV; | 3391 | PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC glad_glMulticastCopyBufferSubDataNV = NULL; |
| 3391 | PFNGLMULTICASTBARRIERNVPROC glad_glMulticastBarrierNV; | 3392 | PFNGLMULTICASTCOPYIMAGESUBDATANVPROC glad_glMulticastCopyImageSubDataNV = NULL; |
| 3392 | PFNGLMULTICASTWAITSYNCNVPROC glad_glMulticastWaitSyncNV; | 3393 | PFNGLMULTICASTBLITFRAMEBUFFERNVPROC glad_glMulticastBlitFramebufferNV = NULL; |
| 3393 | PFNGLMULTICASTGETQUERYOBJECTIVNVPROC glad_glMulticastGetQueryObjectivNV; | 3394 | PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glMulticastFramebufferSampleLocationsfvNV = NULL; |
| 3394 | PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC glad_glMulticastGetQueryObjectuivNV; | 3395 | PFNGLMULTICASTBARRIERNVPROC glad_glMulticastBarrierNV = NULL; |
| 3395 | PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC glad_glMulticastGetQueryObjecti64vNV; | 3396 | PFNGLMULTICASTWAITSYNCNVPROC glad_glMulticastWaitSyncNV = NULL; |
| 3396 | PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC glad_glMulticastGetQueryObjectui64vNV; | 3397 | PFNGLMULTICASTGETQUERYOBJECTIVNVPROC glad_glMulticastGetQueryObjectivNV = NULL; |
| 3397 | PFNGLPROGRAMLOCALPARAMETERI4INVPROC glad_glProgramLocalParameterI4iNV; | 3398 | PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC glad_glMulticastGetQueryObjectuivNV = NULL; |
| 3398 | PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC glad_glProgramLocalParameterI4ivNV; | 3399 | PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC glad_glMulticastGetQueryObjecti64vNV = NULL; |
| 3399 | PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC glad_glProgramLocalParametersI4ivNV; | 3400 | PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC glad_glMulticastGetQueryObjectui64vNV = NULL; |
| 3400 | PFNGLPROGRAMLOCALPARAMETERI4UINVPROC glad_glProgramLocalParameterI4uiNV; | 3401 | PFNGLPROGRAMLOCALPARAMETERI4INVPROC glad_glProgramLocalParameterI4iNV = NULL; |
| 3401 | PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC glad_glProgramLocalParameterI4uivNV; | 3402 | PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC glad_glProgramLocalParameterI4ivNV = NULL; |
| 3402 | PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC glad_glProgramLocalParametersI4uivNV; | 3403 | PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC glad_glProgramLocalParametersI4ivNV = NULL; |
| 3403 | PFNGLPROGRAMENVPARAMETERI4INVPROC glad_glProgramEnvParameterI4iNV; | 3404 | PFNGLPROGRAMLOCALPARAMETERI4UINVPROC glad_glProgramLocalParameterI4uiNV = NULL; |
| 3404 | PFNGLPROGRAMENVPARAMETERI4IVNVPROC glad_glProgramEnvParameterI4ivNV; | 3405 | PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC glad_glProgramLocalParameterI4uivNV = NULL; |
| 3405 | PFNGLPROGRAMENVPARAMETERSI4IVNVPROC glad_glProgramEnvParametersI4ivNV; | 3406 | PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC glad_glProgramLocalParametersI4uivNV = NULL; |
| 3406 | PFNGLPROGRAMENVPARAMETERI4UINVPROC glad_glProgramEnvParameterI4uiNV; | 3407 | PFNGLPROGRAMENVPARAMETERI4INVPROC glad_glProgramEnvParameterI4iNV = NULL; |
| 3407 | PFNGLPROGRAMENVPARAMETERI4UIVNVPROC glad_glProgramEnvParameterI4uivNV; | 3408 | PFNGLPROGRAMENVPARAMETERI4IVNVPROC glad_glProgramEnvParameterI4ivNV = NULL; |
| 3408 | PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC glad_glProgramEnvParametersI4uivNV; | 3409 | PFNGLPROGRAMENVPARAMETERSI4IVNVPROC glad_glProgramEnvParametersI4ivNV = NULL; |
| 3409 | PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC glad_glGetProgramLocalParameterIivNV; | 3410 | PFNGLPROGRAMENVPARAMETERI4UINVPROC glad_glProgramEnvParameterI4uiNV = NULL; |
| 3410 | PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC glad_glGetProgramLocalParameterIuivNV; | 3411 | PFNGLPROGRAMENVPARAMETERI4UIVNVPROC glad_glProgramEnvParameterI4uivNV = NULL; |
| 3411 | PFNGLGETPROGRAMENVPARAMETERIIVNVPROC glad_glGetProgramEnvParameterIivNV; | 3412 | PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC glad_glProgramEnvParametersI4uivNV = NULL; |
| 3412 | PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC glad_glGetProgramEnvParameterIuivNV; | 3413 | PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC glad_glGetProgramLocalParameterIivNV = NULL; |
| 3413 | PFNGLPROGRAMSUBROUTINEPARAMETERSUIVNVPROC glad_glProgramSubroutineParametersuivNV; | 3414 | PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC glad_glGetProgramLocalParameterIuivNV = NULL; |
| 3414 | PFNGLGETPROGRAMSUBROUTINEPARAMETERUIVNVPROC glad_glGetProgramSubroutineParameteruivNV; | 3415 | PFNGLGETPROGRAMENVPARAMETERIIVNVPROC glad_glGetProgramEnvParameterIivNV = NULL; |
| 3415 | PFNGLVERTEX2HNVPROC glad_glVertex2hNV; | 3416 | PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC glad_glGetProgramEnvParameterIuivNV = NULL; |
| 3416 | PFNGLVERTEX2HVNVPROC glad_glVertex2hvNV; | 3417 | PFNGLPROGRAMSUBROUTINEPARAMETERSUIVNVPROC glad_glProgramSubroutineParametersuivNV = NULL; |
| 3417 | PFNGLVERTEX3HNVPROC glad_glVertex3hNV; | 3418 | PFNGLGETPROGRAMSUBROUTINEPARAMETERUIVNVPROC glad_glGetProgramSubroutineParameteruivNV = NULL; |
| 3418 | PFNGLVERTEX3HVNVPROC glad_glVertex3hvNV; | 3419 | PFNGLVERTEX2HNVPROC glad_glVertex2hNV = NULL; |
| 3419 | PFNGLVERTEX4HNVPROC glad_glVertex4hNV; | 3420 | PFNGLVERTEX2HVNVPROC glad_glVertex2hvNV = NULL; |
| 3420 | PFNGLVERTEX4HVNVPROC glad_glVertex4hvNV; | 3421 | PFNGLVERTEX3HNVPROC glad_glVertex3hNV = NULL; |
| 3421 | PFNGLNORMAL3HNVPROC glad_glNormal3hNV; | 3422 | PFNGLVERTEX3HVNVPROC glad_glVertex3hvNV = NULL; |
| 3422 | PFNGLNORMAL3HVNVPROC glad_glNormal3hvNV; | 3423 | PFNGLVERTEX4HNVPROC glad_glVertex4hNV = NULL; |
| 3423 | PFNGLCOLOR3HNVPROC glad_glColor3hNV; | 3424 | PFNGLVERTEX4HVNVPROC glad_glVertex4hvNV = NULL; |
| 3424 | PFNGLCOLOR3HVNVPROC glad_glColor3hvNV; | 3425 | PFNGLNORMAL3HNVPROC glad_glNormal3hNV = NULL; |
| 3425 | PFNGLCOLOR4HNVPROC glad_glColor4hNV; | 3426 | PFNGLNORMAL3HVNVPROC glad_glNormal3hvNV = NULL; |
| 3426 | PFNGLCOLOR4HVNVPROC glad_glColor4hvNV; | 3427 | PFNGLCOLOR3HNVPROC glad_glColor3hNV = NULL; |
| 3427 | PFNGLTEXCOORD1HNVPROC glad_glTexCoord1hNV; | 3428 | PFNGLCOLOR3HVNVPROC glad_glColor3hvNV = NULL; |
| 3428 | PFNGLTEXCOORD1HVNVPROC glad_glTexCoord1hvNV; | 3429 | PFNGLCOLOR4HNVPROC glad_glColor4hNV = NULL; |
| 3429 | PFNGLTEXCOORD2HNVPROC glad_glTexCoord2hNV; | 3430 | PFNGLCOLOR4HVNVPROC glad_glColor4hvNV = NULL; |
| 3430 | PFNGLTEXCOORD2HVNVPROC glad_glTexCoord2hvNV; | 3431 | PFNGLTEXCOORD1HNVPROC glad_glTexCoord1hNV = NULL; |
| 3431 | PFNGLTEXCOORD3HNVPROC glad_glTexCoord3hNV; | 3432 | PFNGLTEXCOORD1HVNVPROC glad_glTexCoord1hvNV = NULL; |
| 3432 | PFNGLTEXCOORD3HVNVPROC glad_glTexCoord3hvNV; | 3433 | PFNGLTEXCOORD2HNVPROC glad_glTexCoord2hNV = NULL; |
| 3433 | PFNGLTEXCOORD4HNVPROC glad_glTexCoord4hNV; | 3434 | PFNGLTEXCOORD2HVNVPROC glad_glTexCoord2hvNV = NULL; |
| 3434 | PFNGLTEXCOORD4HVNVPROC glad_glTexCoord4hvNV; | 3435 | PFNGLTEXCOORD3HNVPROC glad_glTexCoord3hNV = NULL; |
| 3435 | PFNGLMULTITEXCOORD1HNVPROC glad_glMultiTexCoord1hNV; | 3436 | PFNGLTEXCOORD3HVNVPROC glad_glTexCoord3hvNV = NULL; |
| 3436 | PFNGLMULTITEXCOORD1HVNVPROC glad_glMultiTexCoord1hvNV; | 3437 | PFNGLTEXCOORD4HNVPROC glad_glTexCoord4hNV = NULL; |
| 3437 | PFNGLMULTITEXCOORD2HNVPROC glad_glMultiTexCoord2hNV; | 3438 | PFNGLTEXCOORD4HVNVPROC glad_glTexCoord4hvNV = NULL; |
| 3438 | PFNGLMULTITEXCOORD2HVNVPROC glad_glMultiTexCoord2hvNV; | 3439 | PFNGLMULTITEXCOORD1HNVPROC glad_glMultiTexCoord1hNV = NULL; |
| 3439 | PFNGLMULTITEXCOORD3HNVPROC glad_glMultiTexCoord3hNV; | 3440 | PFNGLMULTITEXCOORD1HVNVPROC glad_glMultiTexCoord1hvNV = NULL; |
| 3440 | PFNGLMULTITEXCOORD3HVNVPROC glad_glMultiTexCoord3hvNV; | 3441 | PFNGLMULTITEXCOORD2HNVPROC glad_glMultiTexCoord2hNV = NULL; |
| 3441 | PFNGLMULTITEXCOORD4HNVPROC glad_glMultiTexCoord4hNV; | 3442 | PFNGLMULTITEXCOORD2HVNVPROC glad_glMultiTexCoord2hvNV = NULL; |
| 3442 | PFNGLMULTITEXCOORD4HVNVPROC glad_glMultiTexCoord4hvNV; | 3443 | PFNGLMULTITEXCOORD3HNVPROC glad_glMultiTexCoord3hNV = NULL; |
| 3443 | PFNGLFOGCOORDHNVPROC glad_glFogCoordhNV; | 3444 | PFNGLMULTITEXCOORD3HVNVPROC glad_glMultiTexCoord3hvNV = NULL; |
| 3444 | PFNGLFOGCOORDHVNVPROC glad_glFogCoordhvNV; | 3445 | PFNGLMULTITEXCOORD4HNVPROC glad_glMultiTexCoord4hNV = NULL; |
| 3445 | PFNGLSECONDARYCOLOR3HNVPROC glad_glSecondaryColor3hNV; | 3446 | PFNGLMULTITEXCOORD4HVNVPROC glad_glMultiTexCoord4hvNV = NULL; |
| 3446 | PFNGLSECONDARYCOLOR3HVNVPROC glad_glSecondaryColor3hvNV; | 3447 | PFNGLFOGCOORDHNVPROC glad_glFogCoordhNV = NULL; |
| 3447 | PFNGLVERTEXWEIGHTHNVPROC glad_glVertexWeighthNV; | 3448 | PFNGLFOGCOORDHVNVPROC glad_glFogCoordhvNV = NULL; |
| 3448 | PFNGLVERTEXWEIGHTHVNVPROC glad_glVertexWeighthvNV; | 3449 | PFNGLSECONDARYCOLOR3HNVPROC glad_glSecondaryColor3hNV = NULL; |
| 3449 | PFNGLVERTEXATTRIB1HNVPROC glad_glVertexAttrib1hNV; | 3450 | PFNGLSECONDARYCOLOR3HVNVPROC glad_glSecondaryColor3hvNV = NULL; |
| 3450 | PFNGLVERTEXATTRIB1HVNVPROC glad_glVertexAttrib1hvNV; | 3451 | PFNGLVERTEXWEIGHTHNVPROC glad_glVertexWeighthNV = NULL; |
| 3451 | PFNGLVERTEXATTRIB2HNVPROC glad_glVertexAttrib2hNV; | 3452 | PFNGLVERTEXWEIGHTHVNVPROC glad_glVertexWeighthvNV = NULL; |
| 3452 | PFNGLVERTEXATTRIB2HVNVPROC glad_glVertexAttrib2hvNV; | 3453 | PFNGLVERTEXATTRIB1HNVPROC glad_glVertexAttrib1hNV = NULL; |
| 3453 | PFNGLVERTEXATTRIB3HNVPROC glad_glVertexAttrib3hNV; | 3454 | PFNGLVERTEXATTRIB1HVNVPROC glad_glVertexAttrib1hvNV = NULL; |
| 3454 | PFNGLVERTEXATTRIB3HVNVPROC glad_glVertexAttrib3hvNV; | 3455 | PFNGLVERTEXATTRIB2HNVPROC glad_glVertexAttrib2hNV = NULL; |
| 3455 | PFNGLVERTEXATTRIB4HNVPROC glad_glVertexAttrib4hNV; | 3456 | PFNGLVERTEXATTRIB2HVNVPROC glad_glVertexAttrib2hvNV = NULL; |
| 3456 | PFNGLVERTEXATTRIB4HVNVPROC glad_glVertexAttrib4hvNV; | 3457 | PFNGLVERTEXATTRIB3HNVPROC glad_glVertexAttrib3hNV = NULL; |
| 3457 | PFNGLVERTEXATTRIBS1HVNVPROC glad_glVertexAttribs1hvNV; | 3458 | PFNGLVERTEXATTRIB3HVNVPROC glad_glVertexAttrib3hvNV = NULL; |
| 3458 | PFNGLVERTEXATTRIBS2HVNVPROC glad_glVertexAttribs2hvNV; | 3459 | PFNGLVERTEXATTRIB4HNVPROC glad_glVertexAttrib4hNV = NULL; |
| 3459 | PFNGLVERTEXATTRIBS3HVNVPROC glad_glVertexAttribs3hvNV; | 3460 | PFNGLVERTEXATTRIB4HVNVPROC glad_glVertexAttrib4hvNV = NULL; |
| 3460 | PFNGLVERTEXATTRIBS4HVNVPROC glad_glVertexAttribs4hvNV; | 3461 | PFNGLVERTEXATTRIBS1HVNVPROC glad_glVertexAttribs1hvNV = NULL; |
| 3461 | PFNGLGETINTERNALFORMATSAMPLEIVNVPROC glad_glGetInternalformatSampleivNV; | 3462 | PFNGLVERTEXATTRIBS2HVNVPROC glad_glVertexAttribs2hvNV = NULL; |
| 3462 | PFNGLGENOCCLUSIONQUERIESNVPROC glad_glGenOcclusionQueriesNV; | 3463 | PFNGLVERTEXATTRIBS3HVNVPROC glad_glVertexAttribs3hvNV = NULL; |
| 3463 | PFNGLDELETEOCCLUSIONQUERIESNVPROC glad_glDeleteOcclusionQueriesNV; | 3464 | PFNGLVERTEXATTRIBS4HVNVPROC glad_glVertexAttribs4hvNV = NULL; |
| 3464 | PFNGLISOCCLUSIONQUERYNVPROC glad_glIsOcclusionQueryNV; | 3465 | PFNGLGETINTERNALFORMATSAMPLEIVNVPROC glad_glGetInternalformatSampleivNV = NULL; |
| 3465 | PFNGLBEGINOCCLUSIONQUERYNVPROC glad_glBeginOcclusionQueryNV; | 3466 | PFNGLGENOCCLUSIONQUERIESNVPROC glad_glGenOcclusionQueriesNV = NULL; |
| 3466 | PFNGLENDOCCLUSIONQUERYNVPROC glad_glEndOcclusionQueryNV; | 3467 | PFNGLDELETEOCCLUSIONQUERIESNVPROC glad_glDeleteOcclusionQueriesNV = NULL; |
| 3467 | PFNGLGETOCCLUSIONQUERYIVNVPROC glad_glGetOcclusionQueryivNV; | 3468 | PFNGLISOCCLUSIONQUERYNVPROC glad_glIsOcclusionQueryNV = NULL; |
| 3468 | PFNGLGETOCCLUSIONQUERYUIVNVPROC glad_glGetOcclusionQueryuivNV; | 3469 | PFNGLBEGINOCCLUSIONQUERYNVPROC glad_glBeginOcclusionQueryNV = NULL; |
| 3469 | PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC glad_glProgramBufferParametersfvNV; | 3470 | PFNGLENDOCCLUSIONQUERYNVPROC glad_glEndOcclusionQueryNV = NULL; |
| 3470 | PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC glad_glProgramBufferParametersIivNV; | 3471 | PFNGLGETOCCLUSIONQUERYIVNVPROC glad_glGetOcclusionQueryivNV = NULL; |
| 3471 | PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC glad_glProgramBufferParametersIuivNV; | 3472 | PFNGLGETOCCLUSIONQUERYUIVNVPROC glad_glGetOcclusionQueryuivNV = NULL; |
| 3472 | PFNGLGENPATHSNVPROC glad_glGenPathsNV; | 3473 | PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC glad_glProgramBufferParametersfvNV = NULL; |
| 3473 | PFNGLDELETEPATHSNVPROC glad_glDeletePathsNV; | 3474 | PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC glad_glProgramBufferParametersIivNV = NULL; |
| 3474 | PFNGLISPATHNVPROC glad_glIsPathNV; | 3475 | PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC glad_glProgramBufferParametersIuivNV = NULL; |
| 3475 | PFNGLPATHCOMMANDSNVPROC glad_glPathCommandsNV; | 3476 | PFNGLGENPATHSNVPROC glad_glGenPathsNV = NULL; |
| 3476 | PFNGLPATHCOORDSNVPROC glad_glPathCoordsNV; | 3477 | PFNGLDELETEPATHSNVPROC glad_glDeletePathsNV = NULL; |
| 3477 | PFNGLPATHSUBCOMMANDSNVPROC glad_glPathSubCommandsNV; | 3478 | PFNGLISPATHNVPROC glad_glIsPathNV = NULL; |
| 3478 | PFNGLPATHSUBCOORDSNVPROC glad_glPathSubCoordsNV; | 3479 | PFNGLPATHCOMMANDSNVPROC glad_glPathCommandsNV = NULL; |
| 3479 | PFNGLPATHSTRINGNVPROC glad_glPathStringNV; | 3480 | PFNGLPATHCOORDSNVPROC glad_glPathCoordsNV = NULL; |
| 3480 | PFNGLPATHGLYPHSNVPROC glad_glPathGlyphsNV; | 3481 | PFNGLPATHSUBCOMMANDSNVPROC glad_glPathSubCommandsNV = NULL; |
| 3481 | PFNGLPATHGLYPHRANGENVPROC glad_glPathGlyphRangeNV; | 3482 | PFNGLPATHSUBCOORDSNVPROC glad_glPathSubCoordsNV = NULL; |
| 3482 | PFNGLWEIGHTPATHSNVPROC glad_glWeightPathsNV; | 3483 | PFNGLPATHSTRINGNVPROC glad_glPathStringNV = NULL; |
| 3483 | PFNGLCOPYPATHNVPROC glad_glCopyPathNV; | 3484 | PFNGLPATHGLYPHSNVPROC glad_glPathGlyphsNV = NULL; |
| 3484 | PFNGLINTERPOLATEPATHSNVPROC glad_glInterpolatePathsNV; | 3485 | PFNGLPATHGLYPHRANGENVPROC glad_glPathGlyphRangeNV = NULL; |
| 3485 | PFNGLTRANSFORMPATHNVPROC glad_glTransformPathNV; | 3486 | PFNGLWEIGHTPATHSNVPROC glad_glWeightPathsNV = NULL; |
| 3486 | PFNGLPATHPARAMETERIVNVPROC glad_glPathParameterivNV; | 3487 | PFNGLCOPYPATHNVPROC glad_glCopyPathNV = NULL; |
| 3487 | PFNGLPATHPARAMETERINVPROC glad_glPathParameteriNV; | 3488 | PFNGLINTERPOLATEPATHSNVPROC glad_glInterpolatePathsNV = NULL; |
| 3488 | PFNGLPATHPARAMETERFVNVPROC glad_glPathParameterfvNV; | 3489 | PFNGLTRANSFORMPATHNVPROC glad_glTransformPathNV = NULL; |
| 3489 | PFNGLPATHPARAMETERFNVPROC glad_glPathParameterfNV; | 3490 | PFNGLPATHPARAMETERIVNVPROC glad_glPathParameterivNV = NULL; |
| 3490 | PFNGLPATHDASHARRAYNVPROC glad_glPathDashArrayNV; | 3491 | PFNGLPATHPARAMETERINVPROC glad_glPathParameteriNV = NULL; |
| 3491 | PFNGLPATHSTENCILFUNCNVPROC glad_glPathStencilFuncNV; | 3492 | PFNGLPATHPARAMETERFVNVPROC glad_glPathParameterfvNV = NULL; |
| 3492 | PFNGLPATHSTENCILDEPTHOFFSETNVPROC glad_glPathStencilDepthOffsetNV; | 3493 | PFNGLPATHPARAMETERFNVPROC glad_glPathParameterfNV = NULL; |
| 3493 | PFNGLSTENCILFILLPATHNVPROC glad_glStencilFillPathNV; | 3494 | PFNGLPATHDASHARRAYNVPROC glad_glPathDashArrayNV = NULL; |
| 3494 | PFNGLSTENCILSTROKEPATHNVPROC glad_glStencilStrokePathNV; | 3495 | PFNGLPATHSTENCILFUNCNVPROC glad_glPathStencilFuncNV = NULL; |
| 3495 | PFNGLSTENCILFILLPATHINSTANCEDNVPROC glad_glStencilFillPathInstancedNV; | 3496 | PFNGLPATHSTENCILDEPTHOFFSETNVPROC glad_glPathStencilDepthOffsetNV = NULL; |
| 3496 | PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC glad_glStencilStrokePathInstancedNV; | 3497 | PFNGLSTENCILFILLPATHNVPROC glad_glStencilFillPathNV = NULL; |
| 3497 | PFNGLPATHCOVERDEPTHFUNCNVPROC glad_glPathCoverDepthFuncNV; | 3498 | PFNGLSTENCILSTROKEPATHNVPROC glad_glStencilStrokePathNV = NULL; |
| 3498 | PFNGLCOVERFILLPATHNVPROC glad_glCoverFillPathNV; | 3499 | PFNGLSTENCILFILLPATHINSTANCEDNVPROC glad_glStencilFillPathInstancedNV = NULL; |
| 3499 | PFNGLCOVERSTROKEPATHNVPROC glad_glCoverStrokePathNV; | 3500 | PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC glad_glStencilStrokePathInstancedNV = NULL; |
| 3500 | PFNGLCOVERFILLPATHINSTANCEDNVPROC glad_glCoverFillPathInstancedNV; | 3501 | PFNGLPATHCOVERDEPTHFUNCNVPROC glad_glPathCoverDepthFuncNV = NULL; |
| 3501 | PFNGLCOVERSTROKEPATHINSTANCEDNVPROC glad_glCoverStrokePathInstancedNV; | 3502 | PFNGLCOVERFILLPATHNVPROC glad_glCoverFillPathNV = NULL; |
| 3502 | PFNGLGETPATHPARAMETERIVNVPROC glad_glGetPathParameterivNV; | 3503 | PFNGLCOVERSTROKEPATHNVPROC glad_glCoverStrokePathNV = NULL; |
| 3503 | PFNGLGETPATHPARAMETERFVNVPROC glad_glGetPathParameterfvNV; | 3504 | PFNGLCOVERFILLPATHINSTANCEDNVPROC glad_glCoverFillPathInstancedNV = NULL; |
| 3504 | PFNGLGETPATHCOMMANDSNVPROC glad_glGetPathCommandsNV; | 3505 | PFNGLCOVERSTROKEPATHINSTANCEDNVPROC glad_glCoverStrokePathInstancedNV = NULL; |
| 3505 | PFNGLGETPATHCOORDSNVPROC glad_glGetPathCoordsNV; | 3506 | PFNGLGETPATHPARAMETERIVNVPROC glad_glGetPathParameterivNV = NULL; |
| 3506 | PFNGLGETPATHDASHARRAYNVPROC glad_glGetPathDashArrayNV; | 3507 | PFNGLGETPATHPARAMETERFVNVPROC glad_glGetPathParameterfvNV = NULL; |
| 3507 | PFNGLGETPATHMETRICSNVPROC glad_glGetPathMetricsNV; | 3508 | PFNGLGETPATHCOMMANDSNVPROC glad_glGetPathCommandsNV = NULL; |
| 3508 | PFNGLGETPATHMETRICRANGENVPROC glad_glGetPathMetricRangeNV; | 3509 | PFNGLGETPATHCOORDSNVPROC glad_glGetPathCoordsNV = NULL; |
| 3509 | PFNGLGETPATHSPACINGNVPROC glad_glGetPathSpacingNV; | 3510 | PFNGLGETPATHDASHARRAYNVPROC glad_glGetPathDashArrayNV = NULL; |
| 3510 | PFNGLISPOINTINFILLPATHNVPROC glad_glIsPointInFillPathNV; | 3511 | PFNGLGETPATHMETRICSNVPROC glad_glGetPathMetricsNV = NULL; |
| 3511 | PFNGLISPOINTINSTROKEPATHNVPROC glad_glIsPointInStrokePathNV; | 3512 | PFNGLGETPATHMETRICRANGENVPROC glad_glGetPathMetricRangeNV = NULL; |
| 3512 | PFNGLGETPATHLENGTHNVPROC glad_glGetPathLengthNV; | 3513 | PFNGLGETPATHSPACINGNVPROC glad_glGetPathSpacingNV = NULL; |
| 3513 | PFNGLPOINTALONGPATHNVPROC glad_glPointAlongPathNV; | 3514 | PFNGLISPOINTINFILLPATHNVPROC glad_glIsPointInFillPathNV = NULL; |
| 3514 | PFNGLMATRIXLOAD3X2FNVPROC glad_glMatrixLoad3x2fNV; | 3515 | PFNGLISPOINTINSTROKEPATHNVPROC glad_glIsPointInStrokePathNV = NULL; |
| 3515 | PFNGLMATRIXLOAD3X3FNVPROC glad_glMatrixLoad3x3fNV; | 3516 | PFNGLGETPATHLENGTHNVPROC glad_glGetPathLengthNV = NULL; |
| 3516 | PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC glad_glMatrixLoadTranspose3x3fNV; | 3517 | PFNGLPOINTALONGPATHNVPROC glad_glPointAlongPathNV = NULL; |
| 3517 | PFNGLMATRIXMULT3X2FNVPROC glad_glMatrixMult3x2fNV; | 3518 | PFNGLMATRIXLOAD3X2FNVPROC glad_glMatrixLoad3x2fNV = NULL; |
| 3518 | PFNGLMATRIXMULT3X3FNVPROC glad_glMatrixMult3x3fNV; | 3519 | PFNGLMATRIXLOAD3X3FNVPROC glad_glMatrixLoad3x3fNV = NULL; |
| 3519 | PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC glad_glMatrixMultTranspose3x3fNV; | 3520 | PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC glad_glMatrixLoadTranspose3x3fNV = NULL; |
| 3520 | PFNGLSTENCILTHENCOVERFILLPATHNVPROC glad_glStencilThenCoverFillPathNV; | 3521 | PFNGLMATRIXMULT3X2FNVPROC glad_glMatrixMult3x2fNV = NULL; |
| 3521 | PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC glad_glStencilThenCoverStrokePathNV; | 3522 | PFNGLMATRIXMULT3X3FNVPROC glad_glMatrixMult3x3fNV = NULL; |
| 3522 | PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC glad_glStencilThenCoverFillPathInstancedNV; | 3523 | PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC glad_glMatrixMultTranspose3x3fNV = NULL; |
| 3523 | PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC glad_glStencilThenCoverStrokePathInstancedNV; | 3524 | PFNGLSTENCILTHENCOVERFILLPATHNVPROC glad_glStencilThenCoverFillPathNV = NULL; |
| 3524 | PFNGLPATHGLYPHINDEXRANGENVPROC glad_glPathGlyphIndexRangeNV; | 3525 | PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC glad_glStencilThenCoverStrokePathNV = NULL; |
| 3525 | PFNGLPATHGLYPHINDEXARRAYNVPROC glad_glPathGlyphIndexArrayNV; | 3526 | PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC glad_glStencilThenCoverFillPathInstancedNV = NULL; |
| 3526 | PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC glad_glPathMemoryGlyphIndexArrayNV; | 3527 | PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC glad_glStencilThenCoverStrokePathInstancedNV = NULL; |
| 3527 | PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC glad_glProgramPathFragmentInputGenNV; | 3528 | PFNGLPATHGLYPHINDEXRANGENVPROC glad_glPathGlyphIndexRangeNV = NULL; |
| 3528 | PFNGLGETPROGRAMRESOURCEFVNVPROC glad_glGetProgramResourcefvNV; | 3529 | PFNGLPATHGLYPHINDEXARRAYNVPROC glad_glPathGlyphIndexArrayNV = NULL; |
| 3529 | PFNGLPATHCOLORGENNVPROC glad_glPathColorGenNV; | 3530 | PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC glad_glPathMemoryGlyphIndexArrayNV = NULL; |
| 3530 | PFNGLPATHTEXGENNVPROC glad_glPathTexGenNV; | 3531 | PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC glad_glProgramPathFragmentInputGenNV = NULL; |
| 3531 | PFNGLPATHFOGGENNVPROC glad_glPathFogGenNV; | 3532 | PFNGLGETPROGRAMRESOURCEFVNVPROC glad_glGetProgramResourcefvNV = NULL; |
| 3532 | PFNGLGETPATHCOLORGENIVNVPROC glad_glGetPathColorGenivNV; | 3533 | PFNGLPATHCOLORGENNVPROC glad_glPathColorGenNV = NULL; |
| 3533 | PFNGLGETPATHCOLORGENFVNVPROC glad_glGetPathColorGenfvNV; | 3534 | PFNGLPATHTEXGENNVPROC glad_glPathTexGenNV = NULL; |
| 3534 | PFNGLGETPATHTEXGENIVNVPROC glad_glGetPathTexGenivNV; | 3535 | PFNGLPATHFOGGENNVPROC glad_glPathFogGenNV = NULL; |
| 3535 | PFNGLGETPATHTEXGENFVNVPROC glad_glGetPathTexGenfvNV; | 3536 | PFNGLGETPATHCOLORGENIVNVPROC glad_glGetPathColorGenivNV = NULL; |
| 3536 | PFNGLPIXELDATARANGENVPROC glad_glPixelDataRangeNV; | 3537 | PFNGLGETPATHCOLORGENFVNVPROC glad_glGetPathColorGenfvNV = NULL; |
| 3537 | PFNGLFLUSHPIXELDATARANGENVPROC glad_glFlushPixelDataRangeNV; | 3538 | PFNGLGETPATHTEXGENIVNVPROC glad_glGetPathTexGenivNV = NULL; |
| 3538 | PFNGLPOINTPARAMETERINVPROC glad_glPointParameteriNV; | 3539 | PFNGLGETPATHTEXGENFVNVPROC glad_glGetPathTexGenfvNV = NULL; |
| 3539 | PFNGLPOINTPARAMETERIVNVPROC glad_glPointParameterivNV; | 3540 | PFNGLPIXELDATARANGENVPROC glad_glPixelDataRangeNV = NULL; |
| 3540 | PFNGLPRESENTFRAMEKEYEDNVPROC glad_glPresentFrameKeyedNV; | 3541 | PFNGLFLUSHPIXELDATARANGENVPROC glad_glFlushPixelDataRangeNV = NULL; |
| 3541 | PFNGLPRESENTFRAMEDUALFILLNVPROC glad_glPresentFrameDualFillNV; | 3542 | PFNGLPOINTPARAMETERINVPROC glad_glPointParameteriNV = NULL; |
| 3542 | PFNGLGETVIDEOIVNVPROC glad_glGetVideoivNV; | 3543 | PFNGLPOINTPARAMETERIVNVPROC glad_glPointParameterivNV = NULL; |
| 3543 | PFNGLGETVIDEOUIVNVPROC glad_glGetVideouivNV; | 3544 | PFNGLPRESENTFRAMEKEYEDNVPROC glad_glPresentFrameKeyedNV = NULL; |
| 3544 | PFNGLGETVIDEOI64VNVPROC glad_glGetVideoi64vNV; | 3545 | PFNGLPRESENTFRAMEDUALFILLNVPROC glad_glPresentFrameDualFillNV = NULL; |
| 3545 | PFNGLGETVIDEOUI64VNVPROC glad_glGetVideoui64vNV; | 3546 | PFNGLGETVIDEOIVNVPROC glad_glGetVideoivNV = NULL; |
| 3546 | PFNGLPRIMITIVERESTARTNVPROC glad_glPrimitiveRestartNV; | 3547 | PFNGLGETVIDEOUIVNVPROC glad_glGetVideouivNV = NULL; |
| 3547 | PFNGLPRIMITIVERESTARTINDEXNVPROC glad_glPrimitiveRestartIndexNV; | 3548 | PFNGLGETVIDEOI64VNVPROC glad_glGetVideoi64vNV = NULL; |
| 3548 | PFNGLQUERYRESOURCENVPROC glad_glQueryResourceNV; | 3549 | PFNGLGETVIDEOUI64VNVPROC glad_glGetVideoui64vNV = NULL; |
| 3549 | PFNGLGENQUERYRESOURCETAGNVPROC glad_glGenQueryResourceTagNV; | 3550 | PFNGLPRIMITIVERESTARTNVPROC glad_glPrimitiveRestartNV = NULL; |
| 3550 | PFNGLDELETEQUERYRESOURCETAGNVPROC glad_glDeleteQueryResourceTagNV; | 3551 | PFNGLPRIMITIVERESTARTINDEXNVPROC glad_glPrimitiveRestartIndexNV = NULL; |
| 3551 | PFNGLQUERYRESOURCETAGNVPROC glad_glQueryResourceTagNV; | 3552 | PFNGLQUERYRESOURCENVPROC glad_glQueryResourceNV = NULL; |
| 3552 | PFNGLCOMBINERPARAMETERFVNVPROC glad_glCombinerParameterfvNV; | 3553 | PFNGLGENQUERYRESOURCETAGNVPROC glad_glGenQueryResourceTagNV = NULL; |
| 3553 | PFNGLCOMBINERPARAMETERFNVPROC glad_glCombinerParameterfNV; | 3554 | PFNGLDELETEQUERYRESOURCETAGNVPROC glad_glDeleteQueryResourceTagNV = NULL; |
| 3554 | PFNGLCOMBINERPARAMETERIVNVPROC glad_glCombinerParameterivNV; | 3555 | PFNGLQUERYRESOURCETAGNVPROC glad_glQueryResourceTagNV = NULL; |
| 3555 | PFNGLCOMBINERPARAMETERINVPROC glad_glCombinerParameteriNV; | 3556 | PFNGLCOMBINERPARAMETERFVNVPROC glad_glCombinerParameterfvNV = NULL; |
| 3556 | PFNGLCOMBINERINPUTNVPROC glad_glCombinerInputNV; | 3557 | PFNGLCOMBINERPARAMETERFNVPROC glad_glCombinerParameterfNV = NULL; |
| 3557 | PFNGLCOMBINEROUTPUTNVPROC glad_glCombinerOutputNV; | 3558 | PFNGLCOMBINERPARAMETERIVNVPROC glad_glCombinerParameterivNV = NULL; |
| 3558 | PFNGLFINALCOMBINERINPUTNVPROC glad_glFinalCombinerInputNV; | 3559 | PFNGLCOMBINERPARAMETERINVPROC glad_glCombinerParameteriNV = NULL; |
| 3559 | PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC glad_glGetCombinerInputParameterfvNV; | 3560 | PFNGLCOMBINERINPUTNVPROC glad_glCombinerInputNV = NULL; |
| 3560 | PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC glad_glGetCombinerInputParameterivNV; | 3561 | PFNGLCOMBINEROUTPUTNVPROC glad_glCombinerOutputNV = NULL; |
| 3561 | PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC glad_glGetCombinerOutputParameterfvNV; | 3562 | PFNGLFINALCOMBINERINPUTNVPROC glad_glFinalCombinerInputNV = NULL; |
| 3562 | PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC glad_glGetCombinerOutputParameterivNV; | 3563 | PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC glad_glGetCombinerInputParameterfvNV = NULL; |
| 3563 | PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC glad_glGetFinalCombinerInputParameterfvNV; | 3564 | PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC glad_glGetCombinerInputParameterivNV = NULL; |
| 3564 | PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC glad_glGetFinalCombinerInputParameterivNV; | 3565 | PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC glad_glGetCombinerOutputParameterfvNV = NULL; |
| 3565 | PFNGLCOMBINERSTAGEPARAMETERFVNVPROC glad_glCombinerStageParameterfvNV; | 3566 | PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC glad_glGetCombinerOutputParameterivNV = NULL; |
| 3566 | PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC glad_glGetCombinerStageParameterfvNV; | 3567 | PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC glad_glGetFinalCombinerInputParameterfvNV = NULL; |
| 3567 | PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glFramebufferSampleLocationsfvNV; | 3568 | PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC glad_glGetFinalCombinerInputParameterivNV = NULL; |
| 3568 | PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glNamedFramebufferSampleLocationsfvNV; | 3569 | PFNGLCOMBINERSTAGEPARAMETERFVNVPROC glad_glCombinerStageParameterfvNV = NULL; |
| 3569 | PFNGLRESOLVEDEPTHVALUESNVPROC glad_glResolveDepthValuesNV; | 3570 | PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC glad_glGetCombinerStageParameterfvNV = NULL; |
| 3570 | PFNGLMAKEBUFFERRESIDENTNVPROC glad_glMakeBufferResidentNV; | 3571 | PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glFramebufferSampleLocationsfvNV = NULL; |
| 3571 | PFNGLMAKEBUFFERNONRESIDENTNVPROC glad_glMakeBufferNonResidentNV; | 3572 | PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC glad_glNamedFramebufferSampleLocationsfvNV = NULL; |
| 3572 | PFNGLISBUFFERRESIDENTNVPROC glad_glIsBufferResidentNV; | 3573 | PFNGLRESOLVEDEPTHVALUESNVPROC glad_glResolveDepthValuesNV = NULL; |
| 3573 | PFNGLMAKENAMEDBUFFERRESIDENTNVPROC glad_glMakeNamedBufferResidentNV; | 3574 | PFNGLMAKEBUFFERRESIDENTNVPROC glad_glMakeBufferResidentNV = NULL; |
| 3574 | PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC glad_glMakeNamedBufferNonResidentNV; | 3575 | PFNGLMAKEBUFFERNONRESIDENTNVPROC glad_glMakeBufferNonResidentNV = NULL; |
| 3575 | PFNGLISNAMEDBUFFERRESIDENTNVPROC glad_glIsNamedBufferResidentNV; | 3576 | PFNGLISBUFFERRESIDENTNVPROC glad_glIsBufferResidentNV = NULL; |
| 3576 | PFNGLGETBUFFERPARAMETERUI64VNVPROC glad_glGetBufferParameterui64vNV; | 3577 | PFNGLMAKENAMEDBUFFERRESIDENTNVPROC glad_glMakeNamedBufferResidentNV = NULL; |
| 3577 | PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC glad_glGetNamedBufferParameterui64vNV; | 3578 | PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC glad_glMakeNamedBufferNonResidentNV = NULL; |
| 3578 | PFNGLGETINTEGERUI64VNVPROC glad_glGetIntegerui64vNV; | 3579 | PFNGLISNAMEDBUFFERRESIDENTNVPROC glad_glIsNamedBufferResidentNV = NULL; |
| 3579 | PFNGLUNIFORMUI64NVPROC glad_glUniformui64NV; | 3580 | PFNGLGETBUFFERPARAMETERUI64VNVPROC glad_glGetBufferParameterui64vNV = NULL; |
| 3580 | PFNGLUNIFORMUI64VNVPROC glad_glUniformui64vNV; | 3581 | PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC glad_glGetNamedBufferParameterui64vNV = NULL; |
| 3581 | PFNGLPROGRAMUNIFORMUI64NVPROC glad_glProgramUniformui64NV; | 3582 | PFNGLGETINTEGERUI64VNVPROC glad_glGetIntegerui64vNV = NULL; |
| 3582 | PFNGLPROGRAMUNIFORMUI64VNVPROC glad_glProgramUniformui64vNV; | 3583 | PFNGLUNIFORMUI64NVPROC glad_glUniformui64NV = NULL; |
| 3583 | PFNGLTEXTUREBARRIERNVPROC glad_glTextureBarrierNV; | 3584 | PFNGLUNIFORMUI64VNVPROC glad_glUniformui64vNV = NULL; |
| 3584 | PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC glad_glTexImage2DMultisampleCoverageNV; | 3585 | PFNGLPROGRAMUNIFORMUI64NVPROC glad_glProgramUniformui64NV = NULL; |
| 3585 | PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC glad_glTexImage3DMultisampleCoverageNV; | 3586 | PFNGLPROGRAMUNIFORMUI64VNVPROC glad_glProgramUniformui64vNV = NULL; |
| 3586 | PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC glad_glTextureImage2DMultisampleNV; | 3587 | PFNGLTEXTUREBARRIERNVPROC glad_glTextureBarrierNV = NULL; |
| 3587 | PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC glad_glTextureImage3DMultisampleNV; | 3588 | PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC glad_glTexImage2DMultisampleCoverageNV = NULL; |
| 3588 | PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC glad_glTextureImage2DMultisampleCoverageNV; | 3589 | PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC glad_glTexImage3DMultisampleCoverageNV = NULL; |
| 3589 | PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC glad_glTextureImage3DMultisampleCoverageNV; | 3590 | PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC glad_glTextureImage2DMultisampleNV = NULL; |
| 3590 | PFNGLBEGINTRANSFORMFEEDBACKNVPROC glad_glBeginTransformFeedbackNV; | 3591 | PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC glad_glTextureImage3DMultisampleNV = NULL; |
| 3591 | PFNGLENDTRANSFORMFEEDBACKNVPROC glad_glEndTransformFeedbackNV; | 3592 | PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC glad_glTextureImage2DMultisampleCoverageNV = NULL; |
| 3592 | PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC glad_glTransformFeedbackAttribsNV; | 3593 | PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC glad_glTextureImage3DMultisampleCoverageNV = NULL; |
| 3593 | PFNGLBINDBUFFERRANGENVPROC glad_glBindBufferRangeNV; | 3594 | PFNGLBEGINTRANSFORMFEEDBACKNVPROC glad_glBeginTransformFeedbackNV = NULL; |
| 3594 | PFNGLBINDBUFFEROFFSETNVPROC glad_glBindBufferOffsetNV; | 3595 | PFNGLENDTRANSFORMFEEDBACKNVPROC glad_glEndTransformFeedbackNV = NULL; |
| 3595 | PFNGLBINDBUFFERBASENVPROC glad_glBindBufferBaseNV; | 3596 | PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC glad_glTransformFeedbackAttribsNV = NULL; |
| 3596 | PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC glad_glTransformFeedbackVaryingsNV; | 3597 | PFNGLBINDBUFFERRANGENVPROC glad_glBindBufferRangeNV = NULL; |
| 3597 | PFNGLACTIVEVARYINGNVPROC glad_glActiveVaryingNV; | 3598 | PFNGLBINDBUFFEROFFSETNVPROC glad_glBindBufferOffsetNV = NULL; |
| 3598 | PFNGLGETVARYINGLOCATIONNVPROC glad_glGetVaryingLocationNV; | 3599 | PFNGLBINDBUFFERBASENVPROC glad_glBindBufferBaseNV = NULL; |
| 3599 | PFNGLGETACTIVEVARYINGNVPROC glad_glGetActiveVaryingNV; | 3600 | PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC glad_glTransformFeedbackVaryingsNV = NULL; |
| 3600 | PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC glad_glGetTransformFeedbackVaryingNV; | 3601 | PFNGLACTIVEVARYINGNVPROC glad_glActiveVaryingNV = NULL; |
| 3601 | PFNGLTRANSFORMFEEDBACKSTREAMATTRIBSNVPROC glad_glTransformFeedbackStreamAttribsNV; | 3602 | PFNGLGETVARYINGLOCATIONNVPROC glad_glGetVaryingLocationNV = NULL; |
| 3602 | PFNGLBINDTRANSFORMFEEDBACKNVPROC glad_glBindTransformFeedbackNV; | 3603 | PFNGLGETACTIVEVARYINGNVPROC glad_glGetActiveVaryingNV = NULL; |
| 3603 | PFNGLDELETETRANSFORMFEEDBACKSNVPROC glad_glDeleteTransformFeedbacksNV; | 3604 | PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC glad_glGetTransformFeedbackVaryingNV = NULL; |
| 3604 | PFNGLGENTRANSFORMFEEDBACKSNVPROC glad_glGenTransformFeedbacksNV; | 3605 | PFNGLTRANSFORMFEEDBACKSTREAMATTRIBSNVPROC glad_glTransformFeedbackStreamAttribsNV = NULL; |
| 3605 | PFNGLISTRANSFORMFEEDBACKNVPROC glad_glIsTransformFeedbackNV; | 3606 | PFNGLBINDTRANSFORMFEEDBACKNVPROC glad_glBindTransformFeedbackNV = NULL; |
| 3606 | PFNGLPAUSETRANSFORMFEEDBACKNVPROC glad_glPauseTransformFeedbackNV; | 3607 | PFNGLDELETETRANSFORMFEEDBACKSNVPROC glad_glDeleteTransformFeedbacksNV = NULL; |
| 3607 | PFNGLRESUMETRANSFORMFEEDBACKNVPROC glad_glResumeTransformFeedbackNV; | 3608 | PFNGLGENTRANSFORMFEEDBACKSNVPROC glad_glGenTransformFeedbacksNV = NULL; |
| 3608 | PFNGLDRAWTRANSFORMFEEDBACKNVPROC glad_glDrawTransformFeedbackNV; | 3609 | PFNGLISTRANSFORMFEEDBACKNVPROC glad_glIsTransformFeedbackNV = NULL; |
| 3609 | PFNGLVDPAUINITNVPROC glad_glVDPAUInitNV; | 3610 | PFNGLPAUSETRANSFORMFEEDBACKNVPROC glad_glPauseTransformFeedbackNV = NULL; |
| 3610 | PFNGLVDPAUFININVPROC glad_glVDPAUFiniNV; | 3611 | PFNGLRESUMETRANSFORMFEEDBACKNVPROC glad_glResumeTransformFeedbackNV = NULL; |
| 3611 | PFNGLVDPAUREGISTERVIDEOSURFACENVPROC glad_glVDPAURegisterVideoSurfaceNV; | 3612 | PFNGLDRAWTRANSFORMFEEDBACKNVPROC glad_glDrawTransformFeedbackNV = NULL; |
| 3612 | PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC glad_glVDPAURegisterOutputSurfaceNV; | 3613 | PFNGLVDPAUINITNVPROC glad_glVDPAUInitNV = NULL; |
| 3613 | PFNGLVDPAUISSURFACENVPROC glad_glVDPAUIsSurfaceNV; | 3614 | PFNGLVDPAUFININVPROC glad_glVDPAUFiniNV = NULL; |
| 3614 | PFNGLVDPAUUNREGISTERSURFACENVPROC glad_glVDPAUUnregisterSurfaceNV; | 3615 | PFNGLVDPAUREGISTERVIDEOSURFACENVPROC glad_glVDPAURegisterVideoSurfaceNV = NULL; |
| 3615 | PFNGLVDPAUGETSURFACEIVNVPROC glad_glVDPAUGetSurfaceivNV; | 3616 | PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC glad_glVDPAURegisterOutputSurfaceNV = NULL; |
| 3616 | PFNGLVDPAUSURFACEACCESSNVPROC glad_glVDPAUSurfaceAccessNV; | 3617 | PFNGLVDPAUISSURFACENVPROC glad_glVDPAUIsSurfaceNV = NULL; |
| 3617 | PFNGLVDPAUMAPSURFACESNVPROC glad_glVDPAUMapSurfacesNV; | 3618 | PFNGLVDPAUUNREGISTERSURFACENVPROC glad_glVDPAUUnregisterSurfaceNV = NULL; |
| 3618 | PFNGLVDPAUUNMAPSURFACESNVPROC glad_glVDPAUUnmapSurfacesNV; | 3619 | PFNGLVDPAUGETSURFACEIVNVPROC glad_glVDPAUGetSurfaceivNV = NULL; |
| 3619 | PFNGLFLUSHVERTEXARRAYRANGENVPROC glad_glFlushVertexArrayRangeNV; | 3620 | PFNGLVDPAUSURFACEACCESSNVPROC glad_glVDPAUSurfaceAccessNV = NULL; |
| 3620 | PFNGLVERTEXARRAYRANGENVPROC glad_glVertexArrayRangeNV; | 3621 | PFNGLVDPAUMAPSURFACESNVPROC glad_glVDPAUMapSurfacesNV = NULL; |
| 3621 | PFNGLVERTEXATTRIBL1I64NVPROC glad_glVertexAttribL1i64NV; | 3622 | PFNGLVDPAUUNMAPSURFACESNVPROC glad_glVDPAUUnmapSurfacesNV = NULL; |
| 3622 | PFNGLVERTEXATTRIBL2I64NVPROC glad_glVertexAttribL2i64NV; | 3623 | PFNGLFLUSHVERTEXARRAYRANGENVPROC glad_glFlushVertexArrayRangeNV = NULL; |
| 3623 | PFNGLVERTEXATTRIBL3I64NVPROC glad_glVertexAttribL3i64NV; | 3624 | PFNGLVERTEXARRAYRANGENVPROC glad_glVertexArrayRangeNV = NULL; |
| 3624 | PFNGLVERTEXATTRIBL4I64NVPROC glad_glVertexAttribL4i64NV; | 3625 | PFNGLVERTEXATTRIBL1I64NVPROC glad_glVertexAttribL1i64NV = NULL; |
| 3625 | PFNGLVERTEXATTRIBL1I64VNVPROC glad_glVertexAttribL1i64vNV; | 3626 | PFNGLVERTEXATTRIBL2I64NVPROC glad_glVertexAttribL2i64NV = NULL; |
| 3626 | PFNGLVERTEXATTRIBL2I64VNVPROC glad_glVertexAttribL2i64vNV; | 3627 | PFNGLVERTEXATTRIBL3I64NVPROC glad_glVertexAttribL3i64NV = NULL; |
| 3627 | PFNGLVERTEXATTRIBL3I64VNVPROC glad_glVertexAttribL3i64vNV; | 3628 | PFNGLVERTEXATTRIBL4I64NVPROC glad_glVertexAttribL4i64NV = NULL; |
| 3628 | PFNGLVERTEXATTRIBL4I64VNVPROC glad_glVertexAttribL4i64vNV; | 3629 | PFNGLVERTEXATTRIBL1I64VNVPROC glad_glVertexAttribL1i64vNV = NULL; |
| 3629 | PFNGLVERTEXATTRIBL1UI64NVPROC glad_glVertexAttribL1ui64NV; | 3630 | PFNGLVERTEXATTRIBL2I64VNVPROC glad_glVertexAttribL2i64vNV = NULL; |
| 3630 | PFNGLVERTEXATTRIBL2UI64NVPROC glad_glVertexAttribL2ui64NV; | 3631 | PFNGLVERTEXATTRIBL3I64VNVPROC glad_glVertexAttribL3i64vNV = NULL; |
| 3631 | PFNGLVERTEXATTRIBL3UI64NVPROC glad_glVertexAttribL3ui64NV; | 3632 | PFNGLVERTEXATTRIBL4I64VNVPROC glad_glVertexAttribL4i64vNV = NULL; |
| 3632 | PFNGLVERTEXATTRIBL4UI64NVPROC glad_glVertexAttribL4ui64NV; | 3633 | PFNGLVERTEXATTRIBL1UI64NVPROC glad_glVertexAttribL1ui64NV = NULL; |
| 3633 | PFNGLVERTEXATTRIBL1UI64VNVPROC glad_glVertexAttribL1ui64vNV; | 3634 | PFNGLVERTEXATTRIBL2UI64NVPROC glad_glVertexAttribL2ui64NV = NULL; |
| 3634 | PFNGLVERTEXATTRIBL2UI64VNVPROC glad_glVertexAttribL2ui64vNV; | 3635 | PFNGLVERTEXATTRIBL3UI64NVPROC glad_glVertexAttribL3ui64NV = NULL; |
| 3635 | PFNGLVERTEXATTRIBL3UI64VNVPROC glad_glVertexAttribL3ui64vNV; | 3636 | PFNGLVERTEXATTRIBL4UI64NVPROC glad_glVertexAttribL4ui64NV = NULL; |
| 3636 | PFNGLVERTEXATTRIBL4UI64VNVPROC glad_glVertexAttribL4ui64vNV; | 3637 | PFNGLVERTEXATTRIBL1UI64VNVPROC glad_glVertexAttribL1ui64vNV = NULL; |
| 3637 | PFNGLGETVERTEXATTRIBLI64VNVPROC glad_glGetVertexAttribLi64vNV; | 3638 | PFNGLVERTEXATTRIBL2UI64VNVPROC glad_glVertexAttribL2ui64vNV = NULL; |
| 3638 | PFNGLGETVERTEXATTRIBLUI64VNVPROC glad_glGetVertexAttribLui64vNV; | 3639 | PFNGLVERTEXATTRIBL3UI64VNVPROC glad_glVertexAttribL3ui64vNV = NULL; |
| 3639 | PFNGLVERTEXATTRIBLFORMATNVPROC glad_glVertexAttribLFormatNV; | 3640 | PFNGLVERTEXATTRIBL4UI64VNVPROC glad_glVertexAttribL4ui64vNV = NULL; |
| 3640 | PFNGLBUFFERADDRESSRANGENVPROC glad_glBufferAddressRangeNV; | 3641 | PFNGLGETVERTEXATTRIBLI64VNVPROC glad_glGetVertexAttribLi64vNV = NULL; |
| 3641 | PFNGLVERTEXFORMATNVPROC glad_glVertexFormatNV; | 3642 | PFNGLGETVERTEXATTRIBLUI64VNVPROC glad_glGetVertexAttribLui64vNV = NULL; |
| 3642 | PFNGLNORMALFORMATNVPROC glad_glNormalFormatNV; | 3643 | PFNGLVERTEXATTRIBLFORMATNVPROC glad_glVertexAttribLFormatNV = NULL; |
| 3643 | PFNGLCOLORFORMATNVPROC glad_glColorFormatNV; | 3644 | PFNGLBUFFERADDRESSRANGENVPROC glad_glBufferAddressRangeNV = NULL; |
| 3644 | PFNGLINDEXFORMATNVPROC glad_glIndexFormatNV; | 3645 | PFNGLVERTEXFORMATNVPROC glad_glVertexFormatNV = NULL; |
| 3645 | PFNGLTEXCOORDFORMATNVPROC glad_glTexCoordFormatNV; | 3646 | PFNGLNORMALFORMATNVPROC glad_glNormalFormatNV = NULL; |
| 3646 | PFNGLEDGEFLAGFORMATNVPROC glad_glEdgeFlagFormatNV; | 3647 | PFNGLCOLORFORMATNVPROC glad_glColorFormatNV = NULL; |
| 3647 | PFNGLSECONDARYCOLORFORMATNVPROC glad_glSecondaryColorFormatNV; | 3648 | PFNGLINDEXFORMATNVPROC glad_glIndexFormatNV = NULL; |
| 3648 | PFNGLFOGCOORDFORMATNVPROC glad_glFogCoordFormatNV; | 3649 | PFNGLTEXCOORDFORMATNVPROC glad_glTexCoordFormatNV = NULL; |
| 3649 | PFNGLVERTEXATTRIBFORMATNVPROC glad_glVertexAttribFormatNV; | 3650 | PFNGLEDGEFLAGFORMATNVPROC glad_glEdgeFlagFormatNV = NULL; |
| 3650 | PFNGLVERTEXATTRIBIFORMATNVPROC glad_glVertexAttribIFormatNV; | 3651 | PFNGLSECONDARYCOLORFORMATNVPROC glad_glSecondaryColorFormatNV = NULL; |
| 3651 | PFNGLGETINTEGERUI64I_VNVPROC glad_glGetIntegerui64i_vNV; | 3652 | PFNGLFOGCOORDFORMATNVPROC glad_glFogCoordFormatNV = NULL; |
| 3652 | PFNGLAREPROGRAMSRESIDENTNVPROC glad_glAreProgramsResidentNV; | 3653 | PFNGLVERTEXATTRIBFORMATNVPROC glad_glVertexAttribFormatNV = NULL; |
| 3653 | PFNGLBINDPROGRAMNVPROC glad_glBindProgramNV; | 3654 | PFNGLVERTEXATTRIBIFORMATNVPROC glad_glVertexAttribIFormatNV = NULL; |
| 3654 | PFNGLDELETEPROGRAMSNVPROC glad_glDeleteProgramsNV; | 3655 | PFNGLGETINTEGERUI64I_VNVPROC glad_glGetIntegerui64i_vNV = NULL; |
| 3655 | PFNGLEXECUTEPROGRAMNVPROC glad_glExecuteProgramNV; | 3656 | PFNGLAREPROGRAMSRESIDENTNVPROC glad_glAreProgramsResidentNV = NULL; |
| 3656 | PFNGLGENPROGRAMSNVPROC glad_glGenProgramsNV; | 3657 | PFNGLBINDPROGRAMNVPROC glad_glBindProgramNV = NULL; |
| 3657 | PFNGLGETPROGRAMPARAMETERDVNVPROC glad_glGetProgramParameterdvNV; | 3658 | PFNGLDELETEPROGRAMSNVPROC glad_glDeleteProgramsNV = NULL; |
| 3658 | PFNGLGETPROGRAMPARAMETERFVNVPROC glad_glGetProgramParameterfvNV; | 3659 | PFNGLEXECUTEPROGRAMNVPROC glad_glExecuteProgramNV = NULL; |
| 3659 | PFNGLGETPROGRAMIVNVPROC glad_glGetProgramivNV; | 3660 | PFNGLGENPROGRAMSNVPROC glad_glGenProgramsNV = NULL; |
| 3660 | PFNGLGETPROGRAMSTRINGNVPROC glad_glGetProgramStringNV; | 3661 | PFNGLGETPROGRAMPARAMETERDVNVPROC glad_glGetProgramParameterdvNV = NULL; |
| 3661 | PFNGLGETTRACKMATRIXIVNVPROC glad_glGetTrackMatrixivNV; | 3662 | PFNGLGETPROGRAMPARAMETERFVNVPROC glad_glGetProgramParameterfvNV = NULL; |
| 3662 | PFNGLGETVERTEXATTRIBDVNVPROC glad_glGetVertexAttribdvNV; | 3663 | PFNGLGETPROGRAMIVNVPROC glad_glGetProgramivNV = NULL; |
| 3663 | PFNGLGETVERTEXATTRIBFVNVPROC glad_glGetVertexAttribfvNV; | 3664 | PFNGLGETPROGRAMSTRINGNVPROC glad_glGetProgramStringNV = NULL; |
| 3664 | PFNGLGETVERTEXATTRIBIVNVPROC glad_glGetVertexAttribivNV; | 3665 | PFNGLGETTRACKMATRIXIVNVPROC glad_glGetTrackMatrixivNV = NULL; |
| 3665 | PFNGLGETVERTEXATTRIBPOINTERVNVPROC glad_glGetVertexAttribPointervNV; | 3666 | PFNGLGETVERTEXATTRIBDVNVPROC glad_glGetVertexAttribdvNV = NULL; |
| 3666 | PFNGLISPROGRAMNVPROC glad_glIsProgramNV; | 3667 | PFNGLGETVERTEXATTRIBFVNVPROC glad_glGetVertexAttribfvNV = NULL; |
| 3667 | PFNGLLOADPROGRAMNVPROC glad_glLoadProgramNV; | 3668 | PFNGLGETVERTEXATTRIBIVNVPROC glad_glGetVertexAttribivNV = NULL; |
| 3668 | PFNGLPROGRAMPARAMETER4DNVPROC glad_glProgramParameter4dNV; | 3669 | PFNGLGETVERTEXATTRIBPOINTERVNVPROC glad_glGetVertexAttribPointervNV = NULL; |
| 3669 | PFNGLPROGRAMPARAMETER4DVNVPROC glad_glProgramParameter4dvNV; | 3670 | PFNGLISPROGRAMNVPROC glad_glIsProgramNV = NULL; |
| 3670 | PFNGLPROGRAMPARAMETER4FNVPROC glad_glProgramParameter4fNV; | 3671 | PFNGLLOADPROGRAMNVPROC glad_glLoadProgramNV = NULL; |
| 3671 | PFNGLPROGRAMPARAMETER4FVNVPROC glad_glProgramParameter4fvNV; | 3672 | PFNGLPROGRAMPARAMETER4DNVPROC glad_glProgramParameter4dNV = NULL; |
| 3672 | PFNGLPROGRAMPARAMETERS4DVNVPROC glad_glProgramParameters4dvNV; | 3673 | PFNGLPROGRAMPARAMETER4DVNVPROC glad_glProgramParameter4dvNV = NULL; |
| 3673 | PFNGLPROGRAMPARAMETERS4FVNVPROC glad_glProgramParameters4fvNV; | 3674 | PFNGLPROGRAMPARAMETER4FNVPROC glad_glProgramParameter4fNV = NULL; |
| 3674 | PFNGLREQUESTRESIDENTPROGRAMSNVPROC glad_glRequestResidentProgramsNV; | 3675 | PFNGLPROGRAMPARAMETER4FVNVPROC glad_glProgramParameter4fvNV = NULL; |
| 3675 | PFNGLTRACKMATRIXNVPROC glad_glTrackMatrixNV; | 3676 | PFNGLPROGRAMPARAMETERS4DVNVPROC glad_glProgramParameters4dvNV = NULL; |
| 3676 | PFNGLVERTEXATTRIBPOINTERNVPROC glad_glVertexAttribPointerNV; | 3677 | PFNGLPROGRAMPARAMETERS4FVNVPROC glad_glProgramParameters4fvNV = NULL; |
| 3677 | PFNGLVERTEXATTRIB1DNVPROC glad_glVertexAttrib1dNV; | 3678 | PFNGLREQUESTRESIDENTPROGRAMSNVPROC glad_glRequestResidentProgramsNV = NULL; |
| 3678 | PFNGLVERTEXATTRIB1DVNVPROC glad_glVertexAttrib1dvNV; | 3679 | PFNGLTRACKMATRIXNVPROC glad_glTrackMatrixNV = NULL; |
| 3679 | PFNGLVERTEXATTRIB1FNVPROC glad_glVertexAttrib1fNV; | 3680 | PFNGLVERTEXATTRIBPOINTERNVPROC glad_glVertexAttribPointerNV = NULL; |
| 3680 | PFNGLVERTEXATTRIB1FVNVPROC glad_glVertexAttrib1fvNV; | 3681 | PFNGLVERTEXATTRIB1DNVPROC glad_glVertexAttrib1dNV = NULL; |
| 3681 | PFNGLVERTEXATTRIB1SNVPROC glad_glVertexAttrib1sNV; | 3682 | PFNGLVERTEXATTRIB1DVNVPROC glad_glVertexAttrib1dvNV = NULL; |
| 3682 | PFNGLVERTEXATTRIB1SVNVPROC glad_glVertexAttrib1svNV; | 3683 | PFNGLVERTEXATTRIB1FNVPROC glad_glVertexAttrib1fNV = NULL; |
| 3683 | PFNGLVERTEXATTRIB2DNVPROC glad_glVertexAttrib2dNV; | 3684 | PFNGLVERTEXATTRIB1FVNVPROC glad_glVertexAttrib1fvNV = NULL; |
| 3684 | PFNGLVERTEXATTRIB2DVNVPROC glad_glVertexAttrib2dvNV; | 3685 | PFNGLVERTEXATTRIB1SNVPROC glad_glVertexAttrib1sNV = NULL; |
| 3685 | PFNGLVERTEXATTRIB2FNVPROC glad_glVertexAttrib2fNV; | 3686 | PFNGLVERTEXATTRIB1SVNVPROC glad_glVertexAttrib1svNV = NULL; |
| 3686 | PFNGLVERTEXATTRIB2FVNVPROC glad_glVertexAttrib2fvNV; | 3687 | PFNGLVERTEXATTRIB2DNVPROC glad_glVertexAttrib2dNV = NULL; |
| 3687 | PFNGLVERTEXATTRIB2SNVPROC glad_glVertexAttrib2sNV; | 3688 | PFNGLVERTEXATTRIB2DVNVPROC glad_glVertexAttrib2dvNV = NULL; |
| 3688 | PFNGLVERTEXATTRIB2SVNVPROC glad_glVertexAttrib2svNV; | 3689 | PFNGLVERTEXATTRIB2FNVPROC glad_glVertexAttrib2fNV = NULL; |
| 3689 | PFNGLVERTEXATTRIB3DNVPROC glad_glVertexAttrib3dNV; | 3690 | PFNGLVERTEXATTRIB2FVNVPROC glad_glVertexAttrib2fvNV = NULL; |
| 3690 | PFNGLVERTEXATTRIB3DVNVPROC glad_glVertexAttrib3dvNV; | 3691 | PFNGLVERTEXATTRIB2SNVPROC glad_glVertexAttrib2sNV = NULL; |
| 3691 | PFNGLVERTEXATTRIB3FNVPROC glad_glVertexAttrib3fNV; | 3692 | PFNGLVERTEXATTRIB2SVNVPROC glad_glVertexAttrib2svNV = NULL; |
| 3692 | PFNGLVERTEXATTRIB3FVNVPROC glad_glVertexAttrib3fvNV; | 3693 | PFNGLVERTEXATTRIB3DNVPROC glad_glVertexAttrib3dNV = NULL; |
| 3693 | PFNGLVERTEXATTRIB3SNVPROC glad_glVertexAttrib3sNV; | 3694 | PFNGLVERTEXATTRIB3DVNVPROC glad_glVertexAttrib3dvNV = NULL; |
| 3694 | PFNGLVERTEXATTRIB3SVNVPROC glad_glVertexAttrib3svNV; | 3695 | PFNGLVERTEXATTRIB3FNVPROC glad_glVertexAttrib3fNV = NULL; |
| 3695 | PFNGLVERTEXATTRIB4DNVPROC glad_glVertexAttrib4dNV; | 3696 | PFNGLVERTEXATTRIB3FVNVPROC glad_glVertexAttrib3fvNV = NULL; |
| 3696 | PFNGLVERTEXATTRIB4DVNVPROC glad_glVertexAttrib4dvNV; | 3697 | PFNGLVERTEXATTRIB3SNVPROC glad_glVertexAttrib3sNV = NULL; |
| 3697 | PFNGLVERTEXATTRIB4FNVPROC glad_glVertexAttrib4fNV; | 3698 | PFNGLVERTEXATTRIB3SVNVPROC glad_glVertexAttrib3svNV = NULL; |
| 3698 | PFNGLVERTEXATTRIB4FVNVPROC glad_glVertexAttrib4fvNV; | 3699 | PFNGLVERTEXATTRIB4DNVPROC glad_glVertexAttrib4dNV = NULL; |
| 3699 | PFNGLVERTEXATTRIB4SNVPROC glad_glVertexAttrib4sNV; | 3700 | PFNGLVERTEXATTRIB4DVNVPROC glad_glVertexAttrib4dvNV = NULL; |
| 3700 | PFNGLVERTEXATTRIB4SVNVPROC glad_glVertexAttrib4svNV; | 3701 | PFNGLVERTEXATTRIB4FNVPROC glad_glVertexAttrib4fNV = NULL; |
| 3701 | PFNGLVERTEXATTRIB4UBNVPROC glad_glVertexAttrib4ubNV; | 3702 | PFNGLVERTEXATTRIB4FVNVPROC glad_glVertexAttrib4fvNV = NULL; |
| 3702 | PFNGLVERTEXATTRIB4UBVNVPROC glad_glVertexAttrib4ubvNV; | 3703 | PFNGLVERTEXATTRIB4SNVPROC glad_glVertexAttrib4sNV = NULL; |
| 3703 | PFNGLVERTEXATTRIBS1DVNVPROC glad_glVertexAttribs1dvNV; | 3704 | PFNGLVERTEXATTRIB4SVNVPROC glad_glVertexAttrib4svNV = NULL; |
| 3704 | PFNGLVERTEXATTRIBS1FVNVPROC glad_glVertexAttribs1fvNV; | 3705 | PFNGLVERTEXATTRIB4UBNVPROC glad_glVertexAttrib4ubNV = NULL; |
| 3705 | PFNGLVERTEXATTRIBS1SVNVPROC glad_glVertexAttribs1svNV; | 3706 | PFNGLVERTEXATTRIB4UBVNVPROC glad_glVertexAttrib4ubvNV = NULL; |
| 3706 | PFNGLVERTEXATTRIBS2DVNVPROC glad_glVertexAttribs2dvNV; | 3707 | PFNGLVERTEXATTRIBS1DVNVPROC glad_glVertexAttribs1dvNV = NULL; |
| 3707 | PFNGLVERTEXATTRIBS2FVNVPROC glad_glVertexAttribs2fvNV; | 3708 | PFNGLVERTEXATTRIBS1FVNVPROC glad_glVertexAttribs1fvNV = NULL; |
| 3708 | PFNGLVERTEXATTRIBS2SVNVPROC glad_glVertexAttribs2svNV; | 3709 | PFNGLVERTEXATTRIBS1SVNVPROC glad_glVertexAttribs1svNV = NULL; |
| 3709 | PFNGLVERTEXATTRIBS3DVNVPROC glad_glVertexAttribs3dvNV; | 3710 | PFNGLVERTEXATTRIBS2DVNVPROC glad_glVertexAttribs2dvNV = NULL; |
| 3710 | PFNGLVERTEXATTRIBS3FVNVPROC glad_glVertexAttribs3fvNV; | 3711 | PFNGLVERTEXATTRIBS2FVNVPROC glad_glVertexAttribs2fvNV = NULL; |
| 3711 | PFNGLVERTEXATTRIBS3SVNVPROC glad_glVertexAttribs3svNV; | 3712 | PFNGLVERTEXATTRIBS2SVNVPROC glad_glVertexAttribs2svNV = NULL; |
| 3712 | PFNGLVERTEXATTRIBS4DVNVPROC glad_glVertexAttribs4dvNV; | 3713 | PFNGLVERTEXATTRIBS3DVNVPROC glad_glVertexAttribs3dvNV = NULL; |
| 3713 | PFNGLVERTEXATTRIBS4FVNVPROC glad_glVertexAttribs4fvNV; | 3714 | PFNGLVERTEXATTRIBS3FVNVPROC glad_glVertexAttribs3fvNV = NULL; |
| 3714 | PFNGLVERTEXATTRIBS4SVNVPROC glad_glVertexAttribs4svNV; | 3715 | PFNGLVERTEXATTRIBS3SVNVPROC glad_glVertexAttribs3svNV = NULL; |
| 3715 | PFNGLVERTEXATTRIBS4UBVNVPROC glad_glVertexAttribs4ubvNV; | 3716 | PFNGLVERTEXATTRIBS4DVNVPROC glad_glVertexAttribs4dvNV = NULL; |
| 3716 | PFNGLVERTEXATTRIBI1IEXTPROC glad_glVertexAttribI1iEXT; | 3717 | PFNGLVERTEXATTRIBS4FVNVPROC glad_glVertexAttribs4fvNV = NULL; |
| 3717 | PFNGLVERTEXATTRIBI2IEXTPROC glad_glVertexAttribI2iEXT; | 3718 | PFNGLVERTEXATTRIBS4SVNVPROC glad_glVertexAttribs4svNV = NULL; |
| 3718 | PFNGLVERTEXATTRIBI3IEXTPROC glad_glVertexAttribI3iEXT; | 3719 | PFNGLVERTEXATTRIBS4UBVNVPROC glad_glVertexAttribs4ubvNV = NULL; |
| 3719 | PFNGLVERTEXATTRIBI4IEXTPROC glad_glVertexAttribI4iEXT; | 3720 | PFNGLVERTEXATTRIBI1IEXTPROC glad_glVertexAttribI1iEXT = NULL; |
| 3720 | PFNGLVERTEXATTRIBI1UIEXTPROC glad_glVertexAttribI1uiEXT; | 3721 | PFNGLVERTEXATTRIBI2IEXTPROC glad_glVertexAttribI2iEXT = NULL; |
| 3721 | PFNGLVERTEXATTRIBI2UIEXTPROC glad_glVertexAttribI2uiEXT; | 3722 | PFNGLVERTEXATTRIBI3IEXTPROC glad_glVertexAttribI3iEXT = NULL; |
| 3722 | PFNGLVERTEXATTRIBI3UIEXTPROC glad_glVertexAttribI3uiEXT; | 3723 | PFNGLVERTEXATTRIBI4IEXTPROC glad_glVertexAttribI4iEXT = NULL; |
| 3723 | PFNGLVERTEXATTRIBI4UIEXTPROC glad_glVertexAttribI4uiEXT; | 3724 | PFNGLVERTEXATTRIBI1UIEXTPROC glad_glVertexAttribI1uiEXT = NULL; |
| 3724 | PFNGLVERTEXATTRIBI1IVEXTPROC glad_glVertexAttribI1ivEXT; | 3725 | PFNGLVERTEXATTRIBI2UIEXTPROC glad_glVertexAttribI2uiEXT = NULL; |
| 3725 | PFNGLVERTEXATTRIBI2IVEXTPROC glad_glVertexAttribI2ivEXT; | 3726 | PFNGLVERTEXATTRIBI3UIEXTPROC glad_glVertexAttribI3uiEXT = NULL; |
| 3726 | PFNGLVERTEXATTRIBI3IVEXTPROC glad_glVertexAttribI3ivEXT; | 3727 | PFNGLVERTEXATTRIBI4UIEXTPROC glad_glVertexAttribI4uiEXT = NULL; |
| 3727 | PFNGLVERTEXATTRIBI4IVEXTPROC glad_glVertexAttribI4ivEXT; | 3728 | PFNGLVERTEXATTRIBI1IVEXTPROC glad_glVertexAttribI1ivEXT = NULL; |
| 3728 | PFNGLVERTEXATTRIBI1UIVEXTPROC glad_glVertexAttribI1uivEXT; | 3729 | PFNGLVERTEXATTRIBI2IVEXTPROC glad_glVertexAttribI2ivEXT = NULL; |
| 3729 | PFNGLVERTEXATTRIBI2UIVEXTPROC glad_glVertexAttribI2uivEXT; | 3730 | PFNGLVERTEXATTRIBI3IVEXTPROC glad_glVertexAttribI3ivEXT = NULL; |
| 3730 | PFNGLVERTEXATTRIBI3UIVEXTPROC glad_glVertexAttribI3uivEXT; | 3731 | PFNGLVERTEXATTRIBI4IVEXTPROC glad_glVertexAttribI4ivEXT = NULL; |
| 3731 | PFNGLVERTEXATTRIBI4UIVEXTPROC glad_glVertexAttribI4uivEXT; | 3732 | PFNGLVERTEXATTRIBI1UIVEXTPROC glad_glVertexAttribI1uivEXT = NULL; |
| 3732 | PFNGLVERTEXATTRIBI4BVEXTPROC glad_glVertexAttribI4bvEXT; | 3733 | PFNGLVERTEXATTRIBI2UIVEXTPROC glad_glVertexAttribI2uivEXT = NULL; |
| 3733 | PFNGLVERTEXATTRIBI4SVEXTPROC glad_glVertexAttribI4svEXT; | 3734 | PFNGLVERTEXATTRIBI3UIVEXTPROC glad_glVertexAttribI3uivEXT = NULL; |
| 3734 | PFNGLVERTEXATTRIBI4UBVEXTPROC glad_glVertexAttribI4ubvEXT; | 3735 | PFNGLVERTEXATTRIBI4UIVEXTPROC glad_glVertexAttribI4uivEXT = NULL; |
| 3735 | PFNGLVERTEXATTRIBI4USVEXTPROC glad_glVertexAttribI4usvEXT; | 3736 | PFNGLVERTEXATTRIBI4BVEXTPROC glad_glVertexAttribI4bvEXT = NULL; |
| 3736 | PFNGLVERTEXATTRIBIPOINTEREXTPROC glad_glVertexAttribIPointerEXT; | 3737 | PFNGLVERTEXATTRIBI4SVEXTPROC glad_glVertexAttribI4svEXT = NULL; |
| 3737 | PFNGLGETVERTEXATTRIBIIVEXTPROC glad_glGetVertexAttribIivEXT; | 3738 | PFNGLVERTEXATTRIBI4UBVEXTPROC glad_glVertexAttribI4ubvEXT = NULL; |
| 3738 | PFNGLGETVERTEXATTRIBIUIVEXTPROC glad_glGetVertexAttribIuivEXT; | 3739 | PFNGLVERTEXATTRIBI4USVEXTPROC glad_glVertexAttribI4usvEXT = NULL; |
| 3739 | PFNGLBEGINVIDEOCAPTURENVPROC glad_glBeginVideoCaptureNV; | 3740 | PFNGLVERTEXATTRIBIPOINTEREXTPROC glad_glVertexAttribIPointerEXT = NULL; |
| 3740 | PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC glad_glBindVideoCaptureStreamBufferNV; | 3741 | PFNGLGETVERTEXATTRIBIIVEXTPROC glad_glGetVertexAttribIivEXT = NULL; |
| 3741 | PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC glad_glBindVideoCaptureStreamTextureNV; | 3742 | PFNGLGETVERTEXATTRIBIUIVEXTPROC glad_glGetVertexAttribIuivEXT = NULL; |
| 3742 | PFNGLENDVIDEOCAPTURENVPROC glad_glEndVideoCaptureNV; | 3743 | PFNGLBEGINVIDEOCAPTURENVPROC glad_glBeginVideoCaptureNV = NULL; |
| 3743 | PFNGLGETVIDEOCAPTUREIVNVPROC glad_glGetVideoCaptureivNV; | 3744 | PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC glad_glBindVideoCaptureStreamBufferNV = NULL; |
| 3744 | PFNGLGETVIDEOCAPTURESTREAMIVNVPROC glad_glGetVideoCaptureStreamivNV; | 3745 | PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC glad_glBindVideoCaptureStreamTextureNV = NULL; |
| 3745 | PFNGLGETVIDEOCAPTURESTREAMFVNVPROC glad_glGetVideoCaptureStreamfvNV; | 3746 | PFNGLENDVIDEOCAPTURENVPROC glad_glEndVideoCaptureNV = NULL; |
| 3746 | PFNGLGETVIDEOCAPTURESTREAMDVNVPROC glad_glGetVideoCaptureStreamdvNV; | 3747 | PFNGLGETVIDEOCAPTUREIVNVPROC glad_glGetVideoCaptureivNV = NULL; |
| 3747 | PFNGLVIDEOCAPTURENVPROC glad_glVideoCaptureNV; | 3748 | PFNGLGETVIDEOCAPTURESTREAMIVNVPROC glad_glGetVideoCaptureStreamivNV = NULL; |
| 3748 | PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC glad_glVideoCaptureStreamParameterivNV; | 3749 | PFNGLGETVIDEOCAPTURESTREAMFVNVPROC glad_glGetVideoCaptureStreamfvNV = NULL; |
| 3749 | PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC glad_glVideoCaptureStreamParameterfvNV; | 3750 | PFNGLGETVIDEOCAPTURESTREAMDVNVPROC glad_glGetVideoCaptureStreamdvNV = NULL; |
| 3750 | PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC glad_glVideoCaptureStreamParameterdvNV; | 3751 | PFNGLVIDEOCAPTURENVPROC glad_glVideoCaptureNV = NULL; |
| 3751 | PFNGLVIEWPORTSWIZZLENVPROC glad_glViewportSwizzleNV; | 3752 | PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC glad_glVideoCaptureStreamParameterivNV = NULL; |
| 3752 | PFNGLMULTITEXCOORD1BOESPROC glad_glMultiTexCoord1bOES; | 3753 | PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC glad_glVideoCaptureStreamParameterfvNV = NULL; |
| 3753 | PFNGLMULTITEXCOORD1BVOESPROC glad_glMultiTexCoord1bvOES; | 3754 | PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC glad_glVideoCaptureStreamParameterdvNV = NULL; |
| 3754 | PFNGLMULTITEXCOORD2BOESPROC glad_glMultiTexCoord2bOES; | 3755 | PFNGLVIEWPORTSWIZZLENVPROC glad_glViewportSwizzleNV = NULL; |
| 3755 | PFNGLMULTITEXCOORD2BVOESPROC glad_glMultiTexCoord2bvOES; | 3756 | PFNGLMULTITEXCOORD1BOESPROC glad_glMultiTexCoord1bOES = NULL; |
| 3756 | PFNGLMULTITEXCOORD3BOESPROC glad_glMultiTexCoord3bOES; | 3757 | PFNGLMULTITEXCOORD1BVOESPROC glad_glMultiTexCoord1bvOES = NULL; |
| 3757 | PFNGLMULTITEXCOORD3BVOESPROC glad_glMultiTexCoord3bvOES; | 3758 | PFNGLMULTITEXCOORD2BOESPROC glad_glMultiTexCoord2bOES = NULL; |
| 3758 | PFNGLMULTITEXCOORD4BOESPROC glad_glMultiTexCoord4bOES; | 3759 | PFNGLMULTITEXCOORD2BVOESPROC glad_glMultiTexCoord2bvOES = NULL; |
| 3759 | PFNGLMULTITEXCOORD4BVOESPROC glad_glMultiTexCoord4bvOES; | 3760 | PFNGLMULTITEXCOORD3BOESPROC glad_glMultiTexCoord3bOES = NULL; |
| 3760 | PFNGLTEXCOORD1BOESPROC glad_glTexCoord1bOES; | 3761 | PFNGLMULTITEXCOORD3BVOESPROC glad_glMultiTexCoord3bvOES = NULL; |
| 3761 | PFNGLTEXCOORD1BVOESPROC glad_glTexCoord1bvOES; | 3762 | PFNGLMULTITEXCOORD4BOESPROC glad_glMultiTexCoord4bOES = NULL; |
| 3762 | PFNGLTEXCOORD2BOESPROC glad_glTexCoord2bOES; | 3763 | PFNGLMULTITEXCOORD4BVOESPROC glad_glMultiTexCoord4bvOES = NULL; |
| 3763 | PFNGLTEXCOORD2BVOESPROC glad_glTexCoord2bvOES; | 3764 | PFNGLTEXCOORD1BOESPROC glad_glTexCoord1bOES = NULL; |
| 3764 | PFNGLTEXCOORD3BOESPROC glad_glTexCoord3bOES; | 3765 | PFNGLTEXCOORD1BVOESPROC glad_glTexCoord1bvOES = NULL; |
| 3765 | PFNGLTEXCOORD3BVOESPROC glad_glTexCoord3bvOES; | 3766 | PFNGLTEXCOORD2BOESPROC glad_glTexCoord2bOES = NULL; |
| 3766 | PFNGLTEXCOORD4BOESPROC glad_glTexCoord4bOES; | 3767 | PFNGLTEXCOORD2BVOESPROC glad_glTexCoord2bvOES = NULL; |
| 3767 | PFNGLTEXCOORD4BVOESPROC glad_glTexCoord4bvOES; | 3768 | PFNGLTEXCOORD3BOESPROC glad_glTexCoord3bOES = NULL; |
| 3768 | PFNGLVERTEX2BOESPROC glad_glVertex2bOES; | 3769 | PFNGLTEXCOORD3BVOESPROC glad_glTexCoord3bvOES = NULL; |
| 3769 | PFNGLVERTEX2BVOESPROC glad_glVertex2bvOES; | 3770 | PFNGLTEXCOORD4BOESPROC glad_glTexCoord4bOES = NULL; |
| 3770 | PFNGLVERTEX3BOESPROC glad_glVertex3bOES; | 3771 | PFNGLTEXCOORD4BVOESPROC glad_glTexCoord4bvOES = NULL; |
| 3771 | PFNGLVERTEX3BVOESPROC glad_glVertex3bvOES; | 3772 | PFNGLVERTEX2BOESPROC glad_glVertex2bOES = NULL; |
| 3772 | PFNGLVERTEX4BOESPROC glad_glVertex4bOES; | 3773 | PFNGLVERTEX2BVOESPROC glad_glVertex2bvOES = NULL; |
| 3773 | PFNGLVERTEX4BVOESPROC glad_glVertex4bvOES; | 3774 | PFNGLVERTEX3BOESPROC glad_glVertex3bOES = NULL; |
| 3774 | PFNGLALPHAFUNCXOESPROC glad_glAlphaFuncxOES; | 3775 | PFNGLVERTEX3BVOESPROC glad_glVertex3bvOES = NULL; |
| 3775 | PFNGLCLEARCOLORXOESPROC glad_glClearColorxOES; | 3776 | PFNGLVERTEX4BOESPROC glad_glVertex4bOES = NULL; |
| 3776 | PFNGLCLEARDEPTHXOESPROC glad_glClearDepthxOES; | 3777 | PFNGLVERTEX4BVOESPROC glad_glVertex4bvOES = NULL; |
| 3777 | PFNGLCLIPPLANEXOESPROC glad_glClipPlanexOES; | 3778 | PFNGLALPHAFUNCXOESPROC glad_glAlphaFuncxOES = NULL; |
| 3778 | PFNGLCOLOR4XOESPROC glad_glColor4xOES; | 3779 | PFNGLCLEARCOLORXOESPROC glad_glClearColorxOES = NULL; |
| 3779 | PFNGLDEPTHRANGEXOESPROC glad_glDepthRangexOES; | 3780 | PFNGLCLEARDEPTHXOESPROC glad_glClearDepthxOES = NULL; |
| 3780 | PFNGLFOGXOESPROC glad_glFogxOES; | 3781 | PFNGLCLIPPLANEXOESPROC glad_glClipPlanexOES = NULL; |
| 3781 | PFNGLFOGXVOESPROC glad_glFogxvOES; | 3782 | PFNGLCOLOR4XOESPROC glad_glColor4xOES = NULL; |
| 3782 | PFNGLFRUSTUMXOESPROC glad_glFrustumxOES; | 3783 | PFNGLDEPTHRANGEXOESPROC glad_glDepthRangexOES = NULL; |
| 3783 | PFNGLGETCLIPPLANEXOESPROC glad_glGetClipPlanexOES; | 3784 | PFNGLFOGXOESPROC glad_glFogxOES = NULL; |
| 3784 | PFNGLGETFIXEDVOESPROC glad_glGetFixedvOES; | 3785 | PFNGLFOGXVOESPROC glad_glFogxvOES = NULL; |
| 3785 | PFNGLGETTEXENVXVOESPROC glad_glGetTexEnvxvOES; | 3786 | PFNGLFRUSTUMXOESPROC glad_glFrustumxOES = NULL; |
| 3786 | PFNGLGETTEXPARAMETERXVOESPROC glad_glGetTexParameterxvOES; | 3787 | PFNGLGETCLIPPLANEXOESPROC glad_glGetClipPlanexOES = NULL; |
| 3787 | PFNGLLIGHTMODELXOESPROC glad_glLightModelxOES; | 3788 | PFNGLGETFIXEDVOESPROC glad_glGetFixedvOES = NULL; |
| 3788 | PFNGLLIGHTMODELXVOESPROC glad_glLightModelxvOES; | 3789 | PFNGLGETTEXENVXVOESPROC glad_glGetTexEnvxvOES = NULL; |
| 3789 | PFNGLLIGHTXOESPROC glad_glLightxOES; | 3790 | PFNGLGETTEXPARAMETERXVOESPROC glad_glGetTexParameterxvOES = NULL; |
| 3790 | PFNGLLIGHTXVOESPROC glad_glLightxvOES; | 3791 | PFNGLLIGHTMODELXOESPROC glad_glLightModelxOES = NULL; |
| 3791 | PFNGLLINEWIDTHXOESPROC glad_glLineWidthxOES; | 3792 | PFNGLLIGHTMODELXVOESPROC glad_glLightModelxvOES = NULL; |
| 3792 | PFNGLLOADMATRIXXOESPROC glad_glLoadMatrixxOES; | 3793 | PFNGLLIGHTXOESPROC glad_glLightxOES = NULL; |
| 3793 | PFNGLMATERIALXOESPROC glad_glMaterialxOES; | 3794 | PFNGLLIGHTXVOESPROC glad_glLightxvOES = NULL; |
| 3794 | PFNGLMATERIALXVOESPROC glad_glMaterialxvOES; | 3795 | PFNGLLINEWIDTHXOESPROC glad_glLineWidthxOES = NULL; |
| 3795 | PFNGLMULTMATRIXXOESPROC glad_glMultMatrixxOES; | 3796 | PFNGLLOADMATRIXXOESPROC glad_glLoadMatrixxOES = NULL; |
| 3796 | PFNGLMULTITEXCOORD4XOESPROC glad_glMultiTexCoord4xOES; | 3797 | PFNGLMATERIALXOESPROC glad_glMaterialxOES = NULL; |
| 3797 | PFNGLNORMAL3XOESPROC glad_glNormal3xOES; | 3798 | PFNGLMATERIALXVOESPROC glad_glMaterialxvOES = NULL; |
| 3798 | PFNGLORTHOXOESPROC glad_glOrthoxOES; | 3799 | PFNGLMULTMATRIXXOESPROC glad_glMultMatrixxOES = NULL; |
| 3799 | PFNGLPOINTPARAMETERXVOESPROC glad_glPointParameterxvOES; | 3800 | PFNGLMULTITEXCOORD4XOESPROC glad_glMultiTexCoord4xOES = NULL; |
| 3800 | PFNGLPOINTSIZEXOESPROC glad_glPointSizexOES; | 3801 | PFNGLNORMAL3XOESPROC glad_glNormal3xOES = NULL; |
| 3801 | PFNGLPOLYGONOFFSETXOESPROC glad_glPolygonOffsetxOES; | 3802 | PFNGLORTHOXOESPROC glad_glOrthoxOES = NULL; |
| 3802 | PFNGLROTATEXOESPROC glad_glRotatexOES; | 3803 | PFNGLPOINTPARAMETERXVOESPROC glad_glPointParameterxvOES = NULL; |
| 3803 | PFNGLSCALEXOESPROC glad_glScalexOES; | 3804 | PFNGLPOINTSIZEXOESPROC glad_glPointSizexOES = NULL; |
| 3804 | PFNGLTEXENVXOESPROC glad_glTexEnvxOES; | 3805 | PFNGLPOLYGONOFFSETXOESPROC glad_glPolygonOffsetxOES = NULL; |
| 3805 | PFNGLTEXENVXVOESPROC glad_glTexEnvxvOES; | 3806 | PFNGLROTATEXOESPROC glad_glRotatexOES = NULL; |
| 3806 | PFNGLTEXPARAMETERXOESPROC glad_glTexParameterxOES; | 3807 | PFNGLSCALEXOESPROC glad_glScalexOES = NULL; |
| 3807 | PFNGLTEXPARAMETERXVOESPROC glad_glTexParameterxvOES; | 3808 | PFNGLTEXENVXOESPROC glad_glTexEnvxOES = NULL; |
| 3808 | PFNGLTRANSLATEXOESPROC glad_glTranslatexOES; | 3809 | PFNGLTEXENVXVOESPROC glad_glTexEnvxvOES = NULL; |
| 3809 | PFNGLGETLIGHTXVOESPROC glad_glGetLightxvOES; | 3810 | PFNGLTEXPARAMETERXOESPROC glad_glTexParameterxOES = NULL; |
| 3810 | PFNGLGETMATERIALXVOESPROC glad_glGetMaterialxvOES; | 3811 | PFNGLTEXPARAMETERXVOESPROC glad_glTexParameterxvOES = NULL; |
| 3811 | PFNGLPOINTPARAMETERXOESPROC glad_glPointParameterxOES; | 3812 | PFNGLTRANSLATEXOESPROC glad_glTranslatexOES = NULL; |
| 3812 | PFNGLSAMPLECOVERAGEXOESPROC glad_glSampleCoveragexOES; | 3813 | PFNGLGETLIGHTXVOESPROC glad_glGetLightxvOES = NULL; |
| 3813 | PFNGLACCUMXOESPROC glad_glAccumxOES; | 3814 | PFNGLGETMATERIALXVOESPROC glad_glGetMaterialxvOES = NULL; |
| 3814 | PFNGLBITMAPXOESPROC glad_glBitmapxOES; | 3815 | PFNGLPOINTPARAMETERXOESPROC glad_glPointParameterxOES = NULL; |
| 3815 | PFNGLBLENDCOLORXOESPROC glad_glBlendColorxOES; | 3816 | PFNGLSAMPLECOVERAGEXOESPROC glad_glSampleCoveragexOES = NULL; |
| 3816 | PFNGLCLEARACCUMXOESPROC glad_glClearAccumxOES; | 3817 | PFNGLACCUMXOESPROC glad_glAccumxOES = NULL; |
| 3817 | PFNGLCOLOR3XOESPROC glad_glColor3xOES; | 3818 | PFNGLBITMAPXOESPROC glad_glBitmapxOES = NULL; |
| 3818 | PFNGLCOLOR3XVOESPROC glad_glColor3xvOES; | 3819 | PFNGLBLENDCOLORXOESPROC glad_glBlendColorxOES = NULL; |
| 3819 | PFNGLCOLOR4XVOESPROC glad_glColor4xvOES; | 3820 | PFNGLCLEARACCUMXOESPROC glad_glClearAccumxOES = NULL; |
| 3820 | PFNGLCONVOLUTIONPARAMETERXOESPROC glad_glConvolutionParameterxOES; | 3821 | PFNGLCOLOR3XOESPROC glad_glColor3xOES = NULL; |
| 3821 | PFNGLCONVOLUTIONPARAMETERXVOESPROC glad_glConvolutionParameterxvOES; | 3822 | PFNGLCOLOR3XVOESPROC glad_glColor3xvOES = NULL; |
| 3822 | PFNGLEVALCOORD1XOESPROC glad_glEvalCoord1xOES; | 3823 | PFNGLCOLOR4XVOESPROC glad_glColor4xvOES = NULL; |
| 3823 | PFNGLEVALCOORD1XVOESPROC glad_glEvalCoord1xvOES; | 3824 | PFNGLCONVOLUTIONPARAMETERXOESPROC glad_glConvolutionParameterxOES = NULL; |
| 3824 | PFNGLEVALCOORD2XOESPROC glad_glEvalCoord2xOES; | 3825 | PFNGLCONVOLUTIONPARAMETERXVOESPROC glad_glConvolutionParameterxvOES = NULL; |
| 3825 | PFNGLEVALCOORD2XVOESPROC glad_glEvalCoord2xvOES; | 3826 | PFNGLEVALCOORD1XOESPROC glad_glEvalCoord1xOES = NULL; |
| 3826 | PFNGLFEEDBACKBUFFERXOESPROC glad_glFeedbackBufferxOES; | 3827 | PFNGLEVALCOORD1XVOESPROC glad_glEvalCoord1xvOES = NULL; |
| 3827 | PFNGLGETCONVOLUTIONPARAMETERXVOESPROC glad_glGetConvolutionParameterxvOES; | 3828 | PFNGLEVALCOORD2XOESPROC glad_glEvalCoord2xOES = NULL; |
| 3828 | PFNGLGETHISTOGRAMPARAMETERXVOESPROC glad_glGetHistogramParameterxvOES; | 3829 | PFNGLEVALCOORD2XVOESPROC glad_glEvalCoord2xvOES = NULL; |
| 3829 | PFNGLGETLIGHTXOESPROC glad_glGetLightxOES; | 3830 | PFNGLFEEDBACKBUFFERXOESPROC glad_glFeedbackBufferxOES = NULL; |
| 3830 | PFNGLGETMAPXVOESPROC glad_glGetMapxvOES; | 3831 | PFNGLGETCONVOLUTIONPARAMETERXVOESPROC glad_glGetConvolutionParameterxvOES = NULL; |
| 3831 | PFNGLGETMATERIALXOESPROC glad_glGetMaterialxOES; | 3832 | PFNGLGETHISTOGRAMPARAMETERXVOESPROC glad_glGetHistogramParameterxvOES = NULL; |
| 3832 | PFNGLGETPIXELMAPXVPROC glad_glGetPixelMapxv; | 3833 | PFNGLGETLIGHTXOESPROC glad_glGetLightxOES = NULL; |
| 3833 | PFNGLGETTEXGENXVOESPROC glad_glGetTexGenxvOES; | 3834 | PFNGLGETMAPXVOESPROC glad_glGetMapxvOES = NULL; |
| 3834 | PFNGLGETTEXLEVELPARAMETERXVOESPROC glad_glGetTexLevelParameterxvOES; | 3835 | PFNGLGETMATERIALXOESPROC glad_glGetMaterialxOES = NULL; |
| 3835 | PFNGLINDEXXOESPROC glad_glIndexxOES; | 3836 | PFNGLGETPIXELMAPXVPROC glad_glGetPixelMapxv = NULL; |
| 3836 | PFNGLINDEXXVOESPROC glad_glIndexxvOES; | 3837 | PFNGLGETTEXGENXVOESPROC glad_glGetTexGenxvOES = NULL; |
| 3837 | PFNGLLOADTRANSPOSEMATRIXXOESPROC glad_glLoadTransposeMatrixxOES; | 3838 | PFNGLGETTEXLEVELPARAMETERXVOESPROC glad_glGetTexLevelParameterxvOES = NULL; |
| 3838 | PFNGLMAP1XOESPROC glad_glMap1xOES; | 3839 | PFNGLINDEXXOESPROC glad_glIndexxOES = NULL; |
| 3839 | PFNGLMAP2XOESPROC glad_glMap2xOES; | 3840 | PFNGLINDEXXVOESPROC glad_glIndexxvOES = NULL; |
| 3840 | PFNGLMAPGRID1XOESPROC glad_glMapGrid1xOES; | 3841 | PFNGLLOADTRANSPOSEMATRIXXOESPROC glad_glLoadTransposeMatrixxOES = NULL; |
| 3841 | PFNGLMAPGRID2XOESPROC glad_glMapGrid2xOES; | 3842 | PFNGLMAP1XOESPROC glad_glMap1xOES = NULL; |
| 3842 | PFNGLMULTTRANSPOSEMATRIXXOESPROC glad_glMultTransposeMatrixxOES; | 3843 | PFNGLMAP2XOESPROC glad_glMap2xOES = NULL; |
| 3843 | PFNGLMULTITEXCOORD1XOESPROC glad_glMultiTexCoord1xOES; | 3844 | PFNGLMAPGRID1XOESPROC glad_glMapGrid1xOES = NULL; |
| 3844 | PFNGLMULTITEXCOORD1XVOESPROC glad_glMultiTexCoord1xvOES; | 3845 | PFNGLMAPGRID2XOESPROC glad_glMapGrid2xOES = NULL; |
| 3845 | PFNGLMULTITEXCOORD2XOESPROC glad_glMultiTexCoord2xOES; | 3846 | PFNGLMULTTRANSPOSEMATRIXXOESPROC glad_glMultTransposeMatrixxOES = NULL; |
| 3846 | PFNGLMULTITEXCOORD2XVOESPROC glad_glMultiTexCoord2xvOES; | 3847 | PFNGLMULTITEXCOORD1XOESPROC glad_glMultiTexCoord1xOES = NULL; |
| 3847 | PFNGLMULTITEXCOORD3XOESPROC glad_glMultiTexCoord3xOES; | 3848 | PFNGLMULTITEXCOORD1XVOESPROC glad_glMultiTexCoord1xvOES = NULL; |
| 3848 | PFNGLMULTITEXCOORD3XVOESPROC glad_glMultiTexCoord3xvOES; | 3849 | PFNGLMULTITEXCOORD2XOESPROC glad_glMultiTexCoord2xOES = NULL; |
| 3849 | PFNGLMULTITEXCOORD4XVOESPROC glad_glMultiTexCoord4xvOES; | 3850 | PFNGLMULTITEXCOORD2XVOESPROC glad_glMultiTexCoord2xvOES = NULL; |
| 3850 | PFNGLNORMAL3XVOESPROC glad_glNormal3xvOES; | 3851 | PFNGLMULTITEXCOORD3XOESPROC glad_glMultiTexCoord3xOES = NULL; |
| 3851 | PFNGLPASSTHROUGHXOESPROC glad_glPassThroughxOES; | 3852 | PFNGLMULTITEXCOORD3XVOESPROC glad_glMultiTexCoord3xvOES = NULL; |
| 3852 | PFNGLPIXELMAPXPROC glad_glPixelMapx; | 3853 | PFNGLMULTITEXCOORD4XVOESPROC glad_glMultiTexCoord4xvOES = NULL; |
| 3853 | PFNGLPIXELSTOREXPROC glad_glPixelStorex; | 3854 | PFNGLNORMAL3XVOESPROC glad_glNormal3xvOES = NULL; |
| 3854 | PFNGLPIXELTRANSFERXOESPROC glad_glPixelTransferxOES; | 3855 | PFNGLPASSTHROUGHXOESPROC glad_glPassThroughxOES = NULL; |
| 3855 | PFNGLPIXELZOOMXOESPROC glad_glPixelZoomxOES; | 3856 | PFNGLPIXELMAPXPROC glad_glPixelMapx = NULL; |
| 3856 | PFNGLPRIORITIZETEXTURESXOESPROC glad_glPrioritizeTexturesxOES; | 3857 | PFNGLPIXELSTOREXPROC glad_glPixelStorex = NULL; |
| 3857 | PFNGLRASTERPOS2XOESPROC glad_glRasterPos2xOES; | 3858 | PFNGLPIXELTRANSFERXOESPROC glad_glPixelTransferxOES = NULL; |
| 3858 | PFNGLRASTERPOS2XVOESPROC glad_glRasterPos2xvOES; | 3859 | PFNGLPIXELZOOMXOESPROC glad_glPixelZoomxOES = NULL; |
| 3859 | PFNGLRASTERPOS3XOESPROC glad_glRasterPos3xOES; | 3860 | PFNGLPRIORITIZETEXTURESXOESPROC glad_glPrioritizeTexturesxOES = NULL; |
| 3860 | PFNGLRASTERPOS3XVOESPROC glad_glRasterPos3xvOES; | 3861 | PFNGLRASTERPOS2XOESPROC glad_glRasterPos2xOES = NULL; |
| 3861 | PFNGLRASTERPOS4XOESPROC glad_glRasterPos4xOES; | 3862 | PFNGLRASTERPOS2XVOESPROC glad_glRasterPos2xvOES = NULL; |
| 3862 | PFNGLRASTERPOS4XVOESPROC glad_glRasterPos4xvOES; | 3863 | PFNGLRASTERPOS3XOESPROC glad_glRasterPos3xOES = NULL; |
| 3863 | PFNGLRECTXOESPROC glad_glRectxOES; | 3864 | PFNGLRASTERPOS3XVOESPROC glad_glRasterPos3xvOES = NULL; |
| 3864 | PFNGLRECTXVOESPROC glad_glRectxvOES; | 3865 | PFNGLRASTERPOS4XOESPROC glad_glRasterPos4xOES = NULL; |
| 3865 | PFNGLTEXCOORD1XOESPROC glad_glTexCoord1xOES; | 3866 | PFNGLRASTERPOS4XVOESPROC glad_glRasterPos4xvOES = NULL; |
| 3866 | PFNGLTEXCOORD1XVOESPROC glad_glTexCoord1xvOES; | 3867 | PFNGLRECTXOESPROC glad_glRectxOES = NULL; |
| 3867 | PFNGLTEXCOORD2XOESPROC glad_glTexCoord2xOES; | 3868 | PFNGLRECTXVOESPROC glad_glRectxvOES = NULL; |
| 3868 | PFNGLTEXCOORD2XVOESPROC glad_glTexCoord2xvOES; | 3869 | PFNGLTEXCOORD1XOESPROC glad_glTexCoord1xOES = NULL; |
| 3869 | PFNGLTEXCOORD3XOESPROC glad_glTexCoord3xOES; | 3870 | PFNGLTEXCOORD1XVOESPROC glad_glTexCoord1xvOES = NULL; |
| 3870 | PFNGLTEXCOORD3XVOESPROC glad_glTexCoord3xvOES; | 3871 | PFNGLTEXCOORD2XOESPROC glad_glTexCoord2xOES = NULL; |
| 3871 | PFNGLTEXCOORD4XOESPROC glad_glTexCoord4xOES; | 3872 | PFNGLTEXCOORD2XVOESPROC glad_glTexCoord2xvOES = NULL; |
| 3872 | PFNGLTEXCOORD4XVOESPROC glad_glTexCoord4xvOES; | 3873 | PFNGLTEXCOORD3XOESPROC glad_glTexCoord3xOES = NULL; |
| 3873 | PFNGLTEXGENXOESPROC glad_glTexGenxOES; | 3874 | PFNGLTEXCOORD3XVOESPROC glad_glTexCoord3xvOES = NULL; |
| 3874 | PFNGLTEXGENXVOESPROC glad_glTexGenxvOES; | 3875 | PFNGLTEXCOORD4XOESPROC glad_glTexCoord4xOES = NULL; |
| 3875 | PFNGLVERTEX2XOESPROC glad_glVertex2xOES; | 3876 | PFNGLTEXCOORD4XVOESPROC glad_glTexCoord4xvOES = NULL; |
| 3876 | PFNGLVERTEX2XVOESPROC glad_glVertex2xvOES; | 3877 | PFNGLTEXGENXOESPROC glad_glTexGenxOES = NULL; |
| 3877 | PFNGLVERTEX3XOESPROC glad_glVertex3xOES; | 3878 | PFNGLTEXGENXVOESPROC glad_glTexGenxvOES = NULL; |
| 3878 | PFNGLVERTEX3XVOESPROC glad_glVertex3xvOES; | 3879 | PFNGLVERTEX2XOESPROC glad_glVertex2xOES = NULL; |
| 3879 | PFNGLVERTEX4XOESPROC glad_glVertex4xOES; | 3880 | PFNGLVERTEX2XVOESPROC glad_glVertex2xvOES = NULL; |
| 3880 | PFNGLVERTEX4XVOESPROC glad_glVertex4xvOES; | 3881 | PFNGLVERTEX3XOESPROC glad_glVertex3xOES = NULL; |
| 3881 | PFNGLQUERYMATRIXXOESPROC glad_glQueryMatrixxOES; | 3882 | PFNGLVERTEX3XVOESPROC glad_glVertex3xvOES = NULL; |
| 3882 | PFNGLCLEARDEPTHFOESPROC glad_glClearDepthfOES; | 3883 | PFNGLVERTEX4XOESPROC glad_glVertex4xOES = NULL; |
| 3883 | PFNGLCLIPPLANEFOESPROC glad_glClipPlanefOES; | 3884 | PFNGLVERTEX4XVOESPROC glad_glVertex4xvOES = NULL; |
| 3884 | PFNGLDEPTHRANGEFOESPROC glad_glDepthRangefOES; | 3885 | PFNGLQUERYMATRIXXOESPROC glad_glQueryMatrixxOES = NULL; |
| 3885 | PFNGLFRUSTUMFOESPROC glad_glFrustumfOES; | 3886 | PFNGLCLEARDEPTHFOESPROC glad_glClearDepthfOES = NULL; |
| 3886 | PFNGLGETCLIPPLANEFOESPROC glad_glGetClipPlanefOES; | 3887 | PFNGLCLIPPLANEFOESPROC glad_glClipPlanefOES = NULL; |
| 3887 | PFNGLORTHOFOESPROC glad_glOrthofOES; | 3888 | PFNGLDEPTHRANGEFOESPROC glad_glDepthRangefOES = NULL; |
| 3888 | PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC glad_glFramebufferTextureMultiviewOVR; | 3889 | PFNGLFRUSTUMFOESPROC glad_glFrustumfOES = NULL; |
| 3889 | PFNGLHINTPGIPROC glad_glHintPGI; | 3890 | PFNGLGETCLIPPLANEFOESPROC glad_glGetClipPlanefOES = NULL; |
| 3890 | PFNGLDETAILTEXFUNCSGISPROC glad_glDetailTexFuncSGIS; | 3891 | PFNGLORTHOFOESPROC glad_glOrthofOES = NULL; |
| 3891 | PFNGLGETDETAILTEXFUNCSGISPROC glad_glGetDetailTexFuncSGIS; | 3892 | PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC glad_glFramebufferTextureMultiviewOVR = NULL; |
| 3892 | PFNGLFOGFUNCSGISPROC glad_glFogFuncSGIS; | 3893 | PFNGLHINTPGIPROC glad_glHintPGI = NULL; |
| 3893 | PFNGLGETFOGFUNCSGISPROC glad_glGetFogFuncSGIS; | 3894 | PFNGLDETAILTEXFUNCSGISPROC glad_glDetailTexFuncSGIS = NULL; |
| 3894 | PFNGLSAMPLEMASKSGISPROC glad_glSampleMaskSGIS; | 3895 | PFNGLGETDETAILTEXFUNCSGISPROC glad_glGetDetailTexFuncSGIS = NULL; |
| 3895 | PFNGLSAMPLEPATTERNSGISPROC glad_glSamplePatternSGIS; | 3896 | PFNGLFOGFUNCSGISPROC glad_glFogFuncSGIS = NULL; |
| 3896 | PFNGLPIXELTEXGENPARAMETERISGISPROC glad_glPixelTexGenParameteriSGIS; | 3897 | PFNGLGETFOGFUNCSGISPROC glad_glGetFogFuncSGIS = NULL; |
| 3897 | PFNGLPIXELTEXGENPARAMETERIVSGISPROC glad_glPixelTexGenParameterivSGIS; | 3898 | PFNGLSAMPLEMASKSGISPROC glad_glSampleMaskSGIS = NULL; |
| 3898 | PFNGLPIXELTEXGENPARAMETERFSGISPROC glad_glPixelTexGenParameterfSGIS; | 3899 | PFNGLSAMPLEPATTERNSGISPROC glad_glSamplePatternSGIS = NULL; |
| 3899 | PFNGLPIXELTEXGENPARAMETERFVSGISPROC glad_glPixelTexGenParameterfvSGIS; | 3900 | PFNGLPIXELTEXGENPARAMETERISGISPROC glad_glPixelTexGenParameteriSGIS = NULL; |
| 3900 | PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC glad_glGetPixelTexGenParameterivSGIS; | 3901 | PFNGLPIXELTEXGENPARAMETERIVSGISPROC glad_glPixelTexGenParameterivSGIS = NULL; |
| 3901 | PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC glad_glGetPixelTexGenParameterfvSGIS; | 3902 | PFNGLPIXELTEXGENPARAMETERFSGISPROC glad_glPixelTexGenParameterfSGIS = NULL; |
| 3902 | PFNGLPOINTPARAMETERFSGISPROC glad_glPointParameterfSGIS; | 3903 | PFNGLPIXELTEXGENPARAMETERFVSGISPROC glad_glPixelTexGenParameterfvSGIS = NULL; |
| 3903 | PFNGLPOINTPARAMETERFVSGISPROC glad_glPointParameterfvSGIS; | 3904 | PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC glad_glGetPixelTexGenParameterivSGIS = NULL; |
| 3904 | PFNGLSHARPENTEXFUNCSGISPROC glad_glSharpenTexFuncSGIS; | 3905 | PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC glad_glGetPixelTexGenParameterfvSGIS = NULL; |
| 3905 | PFNGLGETSHARPENTEXFUNCSGISPROC glad_glGetSharpenTexFuncSGIS; | 3906 | PFNGLPOINTPARAMETERFSGISPROC glad_glPointParameterfSGIS = NULL; |
| 3906 | PFNGLTEXIMAGE4DSGISPROC glad_glTexImage4DSGIS; | 3907 | PFNGLPOINTPARAMETERFVSGISPROC glad_glPointParameterfvSGIS = NULL; |
| 3907 | PFNGLTEXSUBIMAGE4DSGISPROC glad_glTexSubImage4DSGIS; | 3908 | PFNGLSHARPENTEXFUNCSGISPROC glad_glSharpenTexFuncSGIS = NULL; |
| 3908 | PFNGLTEXTURECOLORMASKSGISPROC glad_glTextureColorMaskSGIS; | 3909 | PFNGLGETSHARPENTEXFUNCSGISPROC glad_glGetSharpenTexFuncSGIS = NULL; |
| 3909 | PFNGLGETTEXFILTERFUNCSGISPROC glad_glGetTexFilterFuncSGIS; | 3910 | PFNGLTEXIMAGE4DSGISPROC glad_glTexImage4DSGIS = NULL; |
| 3910 | PFNGLTEXFILTERFUNCSGISPROC glad_glTexFilterFuncSGIS; | 3911 | PFNGLTEXSUBIMAGE4DSGISPROC glad_glTexSubImage4DSGIS = NULL; |
| 3911 | PFNGLASYNCMARKERSGIXPROC glad_glAsyncMarkerSGIX; | 3912 | PFNGLTEXTURECOLORMASKSGISPROC glad_glTextureColorMaskSGIS = NULL; |
| 3912 | PFNGLFINISHASYNCSGIXPROC glad_glFinishAsyncSGIX; | 3913 | PFNGLGETTEXFILTERFUNCSGISPROC glad_glGetTexFilterFuncSGIS = NULL; |
| 3913 | PFNGLPOLLASYNCSGIXPROC glad_glPollAsyncSGIX; | 3914 | PFNGLTEXFILTERFUNCSGISPROC glad_glTexFilterFuncSGIS = NULL; |
| 3914 | PFNGLGENASYNCMARKERSSGIXPROC glad_glGenAsyncMarkersSGIX; | 3915 | PFNGLASYNCMARKERSGIXPROC glad_glAsyncMarkerSGIX = NULL; |
| 3915 | PFNGLDELETEASYNCMARKERSSGIXPROC glad_glDeleteAsyncMarkersSGIX; | 3916 | PFNGLFINISHASYNCSGIXPROC glad_glFinishAsyncSGIX = NULL; |
| 3916 | PFNGLISASYNCMARKERSGIXPROC glad_glIsAsyncMarkerSGIX; | 3917 | PFNGLPOLLASYNCSGIXPROC glad_glPollAsyncSGIX = NULL; |
| 3917 | PFNGLFLUSHRASTERSGIXPROC glad_glFlushRasterSGIX; | 3918 | PFNGLGENASYNCMARKERSSGIXPROC glad_glGenAsyncMarkersSGIX = NULL; |
| 3918 | PFNGLFRAGMENTCOLORMATERIALSGIXPROC glad_glFragmentColorMaterialSGIX; | 3919 | PFNGLDELETEASYNCMARKERSSGIXPROC glad_glDeleteAsyncMarkersSGIX = NULL; |
| 3919 | PFNGLFRAGMENTLIGHTFSGIXPROC glad_glFragmentLightfSGIX; | 3920 | PFNGLISASYNCMARKERSGIXPROC glad_glIsAsyncMarkerSGIX = NULL; |
| 3920 | PFNGLFRAGMENTLIGHTFVSGIXPROC glad_glFragmentLightfvSGIX; | 3921 | PFNGLFLUSHRASTERSGIXPROC glad_glFlushRasterSGIX = NULL; |
| 3921 | PFNGLFRAGMENTLIGHTISGIXPROC glad_glFragmentLightiSGIX; | 3922 | PFNGLFRAGMENTCOLORMATERIALSGIXPROC glad_glFragmentColorMaterialSGIX = NULL; |
| 3922 | PFNGLFRAGMENTLIGHTIVSGIXPROC glad_glFragmentLightivSGIX; | 3923 | PFNGLFRAGMENTLIGHTFSGIXPROC glad_glFragmentLightfSGIX = NULL; |
| 3923 | PFNGLFRAGMENTLIGHTMODELFSGIXPROC glad_glFragmentLightModelfSGIX; | 3924 | PFNGLFRAGMENTLIGHTFVSGIXPROC glad_glFragmentLightfvSGIX = NULL; |
| 3924 | PFNGLFRAGMENTLIGHTMODELFVSGIXPROC glad_glFragmentLightModelfvSGIX; | 3925 | PFNGLFRAGMENTLIGHTISGIXPROC glad_glFragmentLightiSGIX = NULL; |
| 3925 | PFNGLFRAGMENTLIGHTMODELISGIXPROC glad_glFragmentLightModeliSGIX; | 3926 | PFNGLFRAGMENTLIGHTIVSGIXPROC glad_glFragmentLightivSGIX = NULL; |
| 3926 | PFNGLFRAGMENTLIGHTMODELIVSGIXPROC glad_glFragmentLightModelivSGIX; | 3927 | PFNGLFRAGMENTLIGHTMODELFSGIXPROC glad_glFragmentLightModelfSGIX = NULL; |
| 3927 | PFNGLFRAGMENTMATERIALFSGIXPROC glad_glFragmentMaterialfSGIX; | 3928 | PFNGLFRAGMENTLIGHTMODELFVSGIXPROC glad_glFragmentLightModelfvSGIX = NULL; |
| 3928 | PFNGLFRAGMENTMATERIALFVSGIXPROC glad_glFragmentMaterialfvSGIX; | 3929 | PFNGLFRAGMENTLIGHTMODELISGIXPROC glad_glFragmentLightModeliSGIX = NULL; |
| 3929 | PFNGLFRAGMENTMATERIALISGIXPROC glad_glFragmentMaterialiSGIX; | 3930 | PFNGLFRAGMENTLIGHTMODELIVSGIXPROC glad_glFragmentLightModelivSGIX = NULL; |
| 3930 | PFNGLFRAGMENTMATERIALIVSGIXPROC glad_glFragmentMaterialivSGIX; | 3931 | PFNGLFRAGMENTMATERIALFSGIXPROC glad_glFragmentMaterialfSGIX = NULL; |
| 3931 | PFNGLGETFRAGMENTLIGHTFVSGIXPROC glad_glGetFragmentLightfvSGIX; | 3932 | PFNGLFRAGMENTMATERIALFVSGIXPROC glad_glFragmentMaterialfvSGIX = NULL; |
| 3932 | PFNGLGETFRAGMENTLIGHTIVSGIXPROC glad_glGetFragmentLightivSGIX; | 3933 | PFNGLFRAGMENTMATERIALISGIXPROC glad_glFragmentMaterialiSGIX = NULL; |
| 3933 | PFNGLGETFRAGMENTMATERIALFVSGIXPROC glad_glGetFragmentMaterialfvSGIX; | 3934 | PFNGLFRAGMENTMATERIALIVSGIXPROC glad_glFragmentMaterialivSGIX = NULL; |
| 3934 | PFNGLGETFRAGMENTMATERIALIVSGIXPROC glad_glGetFragmentMaterialivSGIX; | 3935 | PFNGLGETFRAGMENTLIGHTFVSGIXPROC glad_glGetFragmentLightfvSGIX = NULL; |
| 3935 | PFNGLLIGHTENVISGIXPROC glad_glLightEnviSGIX; | 3936 | PFNGLGETFRAGMENTLIGHTIVSGIXPROC glad_glGetFragmentLightivSGIX = NULL; |
| 3936 | PFNGLFRAMEZOOMSGIXPROC glad_glFrameZoomSGIX; | 3937 | PFNGLGETFRAGMENTMATERIALFVSGIXPROC glad_glGetFragmentMaterialfvSGIX = NULL; |
| 3937 | PFNGLIGLOOINTERFACESGIXPROC glad_glIglooInterfaceSGIX; | 3938 | PFNGLGETFRAGMENTMATERIALIVSGIXPROC glad_glGetFragmentMaterialivSGIX = NULL; |
| 3938 | PFNGLGETINSTRUMENTSSGIXPROC glad_glGetInstrumentsSGIX; | 3939 | PFNGLLIGHTENVISGIXPROC glad_glLightEnviSGIX = NULL; |
| 3939 | PFNGLINSTRUMENTSBUFFERSGIXPROC glad_glInstrumentsBufferSGIX; | 3940 | PFNGLFRAMEZOOMSGIXPROC glad_glFrameZoomSGIX = NULL; |
| 3940 | PFNGLPOLLINSTRUMENTSSGIXPROC glad_glPollInstrumentsSGIX; | 3941 | PFNGLIGLOOINTERFACESGIXPROC glad_glIglooInterfaceSGIX = NULL; |
| 3941 | PFNGLREADINSTRUMENTSSGIXPROC glad_glReadInstrumentsSGIX; | 3942 | PFNGLGETINSTRUMENTSSGIXPROC glad_glGetInstrumentsSGIX = NULL; |
| 3942 | PFNGLSTARTINSTRUMENTSSGIXPROC glad_glStartInstrumentsSGIX; | 3943 | PFNGLINSTRUMENTSBUFFERSGIXPROC glad_glInstrumentsBufferSGIX = NULL; |
| 3943 | PFNGLSTOPINSTRUMENTSSGIXPROC glad_glStopInstrumentsSGIX; | 3944 | PFNGLPOLLINSTRUMENTSSGIXPROC glad_glPollInstrumentsSGIX = NULL; |
| 3944 | PFNGLGETLISTPARAMETERFVSGIXPROC glad_glGetListParameterfvSGIX; | 3945 | PFNGLREADINSTRUMENTSSGIXPROC glad_glReadInstrumentsSGIX = NULL; |
| 3945 | PFNGLGETLISTPARAMETERIVSGIXPROC glad_glGetListParameterivSGIX; | 3946 | PFNGLSTARTINSTRUMENTSSGIXPROC glad_glStartInstrumentsSGIX = NULL; |
| 3946 | PFNGLLISTPARAMETERFSGIXPROC glad_glListParameterfSGIX; | 3947 | PFNGLSTOPINSTRUMENTSSGIXPROC glad_glStopInstrumentsSGIX = NULL; |
| 3947 | PFNGLLISTPARAMETERFVSGIXPROC glad_glListParameterfvSGIX; | 3948 | PFNGLGETLISTPARAMETERFVSGIXPROC glad_glGetListParameterfvSGIX = NULL; |
| 3948 | PFNGLLISTPARAMETERISGIXPROC glad_glListParameteriSGIX; | 3949 | PFNGLGETLISTPARAMETERIVSGIXPROC glad_glGetListParameterivSGIX = NULL; |
| 3949 | PFNGLLISTPARAMETERIVSGIXPROC glad_glListParameterivSGIX; | 3950 | PFNGLLISTPARAMETERFSGIXPROC glad_glListParameterfSGIX = NULL; |
| 3950 | PFNGLPIXELTEXGENSGIXPROC glad_glPixelTexGenSGIX; | 3951 | PFNGLLISTPARAMETERFVSGIXPROC glad_glListParameterfvSGIX = NULL; |
| 3951 | PFNGLDEFORMATIONMAP3DSGIXPROC glad_glDeformationMap3dSGIX; | 3952 | PFNGLLISTPARAMETERISGIXPROC glad_glListParameteriSGIX = NULL; |
| 3952 | PFNGLDEFORMATIONMAP3FSGIXPROC glad_glDeformationMap3fSGIX; | 3953 | PFNGLLISTPARAMETERIVSGIXPROC glad_glListParameterivSGIX = NULL; |
| 3953 | PFNGLDEFORMSGIXPROC glad_glDeformSGIX; | 3954 | PFNGLPIXELTEXGENSGIXPROC glad_glPixelTexGenSGIX = NULL; |
| 3954 | PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC glad_glLoadIdentityDeformationMapSGIX; | 3955 | PFNGLDEFORMATIONMAP3DSGIXPROC glad_glDeformationMap3dSGIX = NULL; |
| 3955 | PFNGLREFERENCEPLANESGIXPROC glad_glReferencePlaneSGIX; | 3956 | PFNGLDEFORMATIONMAP3FSGIXPROC glad_glDeformationMap3fSGIX = NULL; |
| 3956 | PFNGLSPRITEPARAMETERFSGIXPROC glad_glSpriteParameterfSGIX; | 3957 | PFNGLDEFORMSGIXPROC glad_glDeformSGIX = NULL; |
| 3957 | PFNGLSPRITEPARAMETERFVSGIXPROC glad_glSpriteParameterfvSGIX; | 3958 | PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC glad_glLoadIdentityDeformationMapSGIX = NULL; |
| 3958 | PFNGLSPRITEPARAMETERISGIXPROC glad_glSpriteParameteriSGIX; | 3959 | PFNGLREFERENCEPLANESGIXPROC glad_glReferencePlaneSGIX = NULL; |
| 3959 | PFNGLSPRITEPARAMETERIVSGIXPROC glad_glSpriteParameterivSGIX; | 3960 | PFNGLSPRITEPARAMETERFSGIXPROC glad_glSpriteParameterfSGIX = NULL; |
| 3960 | PFNGLTAGSAMPLEBUFFERSGIXPROC glad_glTagSampleBufferSGIX; | 3961 | PFNGLSPRITEPARAMETERFVSGIXPROC glad_glSpriteParameterfvSGIX = NULL; |
| 3961 | PFNGLCOLORTABLESGIPROC glad_glColorTableSGI; | 3962 | PFNGLSPRITEPARAMETERISGIXPROC glad_glSpriteParameteriSGIX = NULL; |
| 3962 | PFNGLCOLORTABLEPARAMETERFVSGIPROC glad_glColorTableParameterfvSGI; | 3963 | PFNGLSPRITEPARAMETERIVSGIXPROC glad_glSpriteParameterivSGIX = NULL; |
| 3963 | PFNGLCOLORTABLEPARAMETERIVSGIPROC glad_glColorTableParameterivSGI; | 3964 | PFNGLTAGSAMPLEBUFFERSGIXPROC glad_glTagSampleBufferSGIX = NULL; |
| 3964 | PFNGLCOPYCOLORTABLESGIPROC glad_glCopyColorTableSGI; | 3965 | PFNGLCOLORTABLESGIPROC glad_glColorTableSGI = NULL; |
| 3965 | PFNGLGETCOLORTABLESGIPROC glad_glGetColorTableSGI; | 3966 | PFNGLCOLORTABLEPARAMETERFVSGIPROC glad_glColorTableParameterfvSGI = NULL; |
| 3966 | PFNGLGETCOLORTABLEPARAMETERFVSGIPROC glad_glGetColorTableParameterfvSGI; | 3967 | PFNGLCOLORTABLEPARAMETERIVSGIPROC glad_glColorTableParameterivSGI = NULL; |
| 3967 | PFNGLGETCOLORTABLEPARAMETERIVSGIPROC glad_glGetColorTableParameterivSGI; | 3968 | PFNGLCOPYCOLORTABLESGIPROC glad_glCopyColorTableSGI = NULL; |
| 3968 | PFNGLFINISHTEXTURESUNXPROC glad_glFinishTextureSUNX; | 3969 | PFNGLGETCOLORTABLESGIPROC glad_glGetColorTableSGI = NULL; |
| 3969 | PFNGLGLOBALALPHAFACTORBSUNPROC glad_glGlobalAlphaFactorbSUN; | 3970 | PFNGLGETCOLORTABLEPARAMETERFVSGIPROC glad_glGetColorTableParameterfvSGI = NULL; |
| 3970 | PFNGLGLOBALALPHAFACTORSSUNPROC glad_glGlobalAlphaFactorsSUN; | 3971 | PFNGLGETCOLORTABLEPARAMETERIVSGIPROC glad_glGetColorTableParameterivSGI = NULL; |
| 3971 | PFNGLGLOBALALPHAFACTORISUNPROC glad_glGlobalAlphaFactoriSUN; | 3972 | PFNGLFINISHTEXTURESUNXPROC glad_glFinishTextureSUNX = NULL; |
| 3972 | PFNGLGLOBALALPHAFACTORFSUNPROC glad_glGlobalAlphaFactorfSUN; | 3973 | PFNGLGLOBALALPHAFACTORBSUNPROC glad_glGlobalAlphaFactorbSUN = NULL; |
| 3973 | PFNGLGLOBALALPHAFACTORDSUNPROC glad_glGlobalAlphaFactordSUN; | 3974 | PFNGLGLOBALALPHAFACTORSSUNPROC glad_glGlobalAlphaFactorsSUN = NULL; |
| 3974 | PFNGLGLOBALALPHAFACTORUBSUNPROC glad_glGlobalAlphaFactorubSUN; | 3975 | PFNGLGLOBALALPHAFACTORISUNPROC glad_glGlobalAlphaFactoriSUN = NULL; |
| 3975 | PFNGLGLOBALALPHAFACTORUSSUNPROC glad_glGlobalAlphaFactorusSUN; | 3976 | PFNGLGLOBALALPHAFACTORFSUNPROC glad_glGlobalAlphaFactorfSUN = NULL; |
| 3976 | PFNGLGLOBALALPHAFACTORUISUNPROC glad_glGlobalAlphaFactoruiSUN; | 3977 | PFNGLGLOBALALPHAFACTORDSUNPROC glad_glGlobalAlphaFactordSUN = NULL; |
| 3977 | PFNGLDRAWMESHARRAYSSUNPROC glad_glDrawMeshArraysSUN; | 3978 | PFNGLGLOBALALPHAFACTORUBSUNPROC glad_glGlobalAlphaFactorubSUN = NULL; |
| 3978 | PFNGLREPLACEMENTCODEUISUNPROC glad_glReplacementCodeuiSUN; | 3979 | PFNGLGLOBALALPHAFACTORUSSUNPROC glad_glGlobalAlphaFactorusSUN = NULL; |
| 3979 | PFNGLREPLACEMENTCODEUSSUNPROC glad_glReplacementCodeusSUN; | 3980 | PFNGLGLOBALALPHAFACTORUISUNPROC glad_glGlobalAlphaFactoruiSUN = NULL; |
| 3980 | PFNGLREPLACEMENTCODEUBSUNPROC glad_glReplacementCodeubSUN; | 3981 | PFNGLDRAWMESHARRAYSSUNPROC glad_glDrawMeshArraysSUN = NULL; |
| 3981 | PFNGLREPLACEMENTCODEUIVSUNPROC glad_glReplacementCodeuivSUN; | 3982 | PFNGLREPLACEMENTCODEUISUNPROC glad_glReplacementCodeuiSUN = NULL; |
| 3982 | PFNGLREPLACEMENTCODEUSVSUNPROC glad_glReplacementCodeusvSUN; | 3983 | PFNGLREPLACEMENTCODEUSSUNPROC glad_glReplacementCodeusSUN = NULL; |
| 3983 | PFNGLREPLACEMENTCODEUBVSUNPROC glad_glReplacementCodeubvSUN; | 3984 | PFNGLREPLACEMENTCODEUBSUNPROC glad_glReplacementCodeubSUN = NULL; |
| 3984 | PFNGLREPLACEMENTCODEPOINTERSUNPROC glad_glReplacementCodePointerSUN; | 3985 | PFNGLREPLACEMENTCODEUIVSUNPROC glad_glReplacementCodeuivSUN = NULL; |
| 3985 | PFNGLCOLOR4UBVERTEX2FSUNPROC glad_glColor4ubVertex2fSUN; | 3986 | PFNGLREPLACEMENTCODEUSVSUNPROC glad_glReplacementCodeusvSUN = NULL; |
| 3986 | PFNGLCOLOR4UBVERTEX2FVSUNPROC glad_glColor4ubVertex2fvSUN; | 3987 | PFNGLREPLACEMENTCODEUBVSUNPROC glad_glReplacementCodeubvSUN = NULL; |
| 3987 | PFNGLCOLOR4UBVERTEX3FSUNPROC glad_glColor4ubVertex3fSUN; | 3988 | PFNGLREPLACEMENTCODEPOINTERSUNPROC glad_glReplacementCodePointerSUN = NULL; |
| 3988 | PFNGLCOLOR4UBVERTEX3FVSUNPROC glad_glColor4ubVertex3fvSUN; | 3989 | PFNGLCOLOR4UBVERTEX2FSUNPROC glad_glColor4ubVertex2fSUN = NULL; |
| 3989 | PFNGLCOLOR3FVERTEX3FSUNPROC glad_glColor3fVertex3fSUN; | 3990 | PFNGLCOLOR4UBVERTEX2FVSUNPROC glad_glColor4ubVertex2fvSUN = NULL; |
| 3990 | PFNGLCOLOR3FVERTEX3FVSUNPROC glad_glColor3fVertex3fvSUN; | 3991 | PFNGLCOLOR4UBVERTEX3FSUNPROC glad_glColor4ubVertex3fSUN = NULL; |
| 3991 | PFNGLNORMAL3FVERTEX3FSUNPROC glad_glNormal3fVertex3fSUN; | 3992 | PFNGLCOLOR4UBVERTEX3FVSUNPROC glad_glColor4ubVertex3fvSUN = NULL; |
| 3992 | PFNGLNORMAL3FVERTEX3FVSUNPROC glad_glNormal3fVertex3fvSUN; | 3993 | PFNGLCOLOR3FVERTEX3FSUNPROC glad_glColor3fVertex3fSUN = NULL; |
| 3993 | PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glColor4fNormal3fVertex3fSUN; | 3994 | PFNGLCOLOR3FVERTEX3FVSUNPROC glad_glColor3fVertex3fvSUN = NULL; |
| 3994 | PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glColor4fNormal3fVertex3fvSUN; | 3995 | PFNGLNORMAL3FVERTEX3FSUNPROC glad_glNormal3fVertex3fSUN = NULL; |
| 3995 | PFNGLTEXCOORD2FVERTEX3FSUNPROC glad_glTexCoord2fVertex3fSUN; | 3996 | PFNGLNORMAL3FVERTEX3FVSUNPROC glad_glNormal3fVertex3fvSUN = NULL; |
| 3996 | PFNGLTEXCOORD2FVERTEX3FVSUNPROC glad_glTexCoord2fVertex3fvSUN; | 3997 | PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glColor4fNormal3fVertex3fSUN = NULL; |
| 3997 | PFNGLTEXCOORD4FVERTEX4FSUNPROC glad_glTexCoord4fVertex4fSUN; | 3998 | PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glColor4fNormal3fVertex3fvSUN = NULL; |
| 3998 | PFNGLTEXCOORD4FVERTEX4FVSUNPROC glad_glTexCoord4fVertex4fvSUN; | 3999 | PFNGLTEXCOORD2FVERTEX3FSUNPROC glad_glTexCoord2fVertex3fSUN = NULL; |
| 3999 | PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC glad_glTexCoord2fColor4ubVertex3fSUN; | 4000 | PFNGLTEXCOORD2FVERTEX3FVSUNPROC glad_glTexCoord2fVertex3fvSUN = NULL; |
| 4000 | PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC glad_glTexCoord2fColor4ubVertex3fvSUN; | 4001 | PFNGLTEXCOORD4FVERTEX4FSUNPROC glad_glTexCoord4fVertex4fSUN = NULL; |
| 4001 | PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC glad_glTexCoord2fColor3fVertex3fSUN; | 4002 | PFNGLTEXCOORD4FVERTEX4FVSUNPROC glad_glTexCoord4fVertex4fvSUN = NULL; |
| 4002 | PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC glad_glTexCoord2fColor3fVertex3fvSUN; | 4003 | PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC glad_glTexCoord2fColor4ubVertex3fSUN = NULL; |
| 4003 | PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC glad_glTexCoord2fNormal3fVertex3fSUN; | 4004 | PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC glad_glTexCoord2fColor4ubVertex3fvSUN = NULL; |
| 4004 | PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC glad_glTexCoord2fNormal3fVertex3fvSUN; | 4005 | PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC glad_glTexCoord2fColor3fVertex3fSUN = NULL; |
| 4005 | PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glTexCoord2fColor4fNormal3fVertex3fSUN; | 4006 | PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC glad_glTexCoord2fColor3fVertex3fvSUN = NULL; |
| 4006 | PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glTexCoord2fColor4fNormal3fVertex3fvSUN; | 4007 | PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC glad_glTexCoord2fNormal3fVertex3fSUN = NULL; |
| 4007 | PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC glad_glTexCoord4fColor4fNormal3fVertex4fSUN; | 4008 | PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC glad_glTexCoord2fNormal3fVertex3fvSUN = NULL; |
| 4008 | PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC glad_glTexCoord4fColor4fNormal3fVertex4fvSUN; | 4009 | PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glTexCoord2fColor4fNormal3fVertex3fSUN = NULL; |
| 4009 | PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC glad_glReplacementCodeuiVertex3fSUN; | 4010 | PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glTexCoord2fColor4fNormal3fVertex3fvSUN = NULL; |
| 4010 | PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC glad_glReplacementCodeuiVertex3fvSUN; | 4011 | PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC glad_glTexCoord4fColor4fNormal3fVertex4fSUN = NULL; |
| 4011 | PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC glad_glReplacementCodeuiColor4ubVertex3fSUN; | 4012 | PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC glad_glTexCoord4fColor4fNormal3fVertex4fvSUN = NULL; |
| 4012 | PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC glad_glReplacementCodeuiColor4ubVertex3fvSUN; | 4013 | PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC glad_glReplacementCodeuiVertex3fSUN = NULL; |
| 4013 | PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC glad_glReplacementCodeuiColor3fVertex3fSUN; | 4014 | PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC glad_glReplacementCodeuiVertex3fvSUN = NULL; |
| 4014 | PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC glad_glReplacementCodeuiColor3fVertex3fvSUN; | 4015 | PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC glad_glReplacementCodeuiColor4ubVertex3fSUN = NULL; |
| 4015 | PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiNormal3fVertex3fSUN; | 4016 | PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC glad_glReplacementCodeuiColor4ubVertex3fvSUN = NULL; |
| 4016 | PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiNormal3fVertex3fvSUN; | 4017 | PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC glad_glReplacementCodeuiColor3fVertex3fSUN = NULL; |
| 4017 | PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiColor4fNormal3fVertex3fSUN; | 4018 | PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC glad_glReplacementCodeuiColor3fVertex3fvSUN = NULL; |
| 4018 | PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiColor4fNormal3fVertex3fvSUN; | 4019 | PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiNormal3fVertex3fSUN = NULL; |
| 4019 | PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fVertex3fSUN; | 4020 | PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiNormal3fVertex3fvSUN = NULL; |
| 4020 | PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fVertex3fvSUN; | 4021 | PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiColor4fNormal3fVertex3fSUN = NULL; |
| 4021 | PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN; | 4022 | PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiColor4fNormal3fVertex3fvSUN = NULL; |
| 4022 | PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN; | 4023 | PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fVertex3fSUN = NULL; |
| 4023 | PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN; | 4024 | PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fVertex3fvSUN = NULL; |
| 4024 | PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN; | 4025 | PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN = NULL; |
| 4026 | PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN = NULL; | ||
| 4027 | PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC glad_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN = NULL; | ||
| 4028 | PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC glad_glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN = NULL; | ||
| 4025 | static void load_GL_VERSION_1_0(GLADloadproc load) { | 4029 | static void load_GL_VERSION_1_0(GLADloadproc load) { |
| 4026 | if(!GLAD_GL_VERSION_1_0) return; | 4030 | if(!GLAD_GL_VERSION_1_0) return; |
| 4027 | glad_glCullFace = (PFNGLCULLFACEPROC)load("glCullFace"); | 4031 | glad_glCullFace = (PFNGLCULLFACEPROC)load("glCullFace"); |
| @@ -4453,6 +4457,11 @@ static void load_GL_AMD_draw_buffers_blend(GLADloadproc load) { | |||
| 4453 | glad_glBlendEquationIndexedAMD = (PFNGLBLENDEQUATIONINDEXEDAMDPROC)load("glBlendEquationIndexedAMD"); | 4457 | glad_glBlendEquationIndexedAMD = (PFNGLBLENDEQUATIONINDEXEDAMDPROC)load("glBlendEquationIndexedAMD"); |
| 4454 | glad_glBlendEquationSeparateIndexedAMD = (PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC)load("glBlendEquationSeparateIndexedAMD"); | 4458 | glad_glBlendEquationSeparateIndexedAMD = (PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC)load("glBlendEquationSeparateIndexedAMD"); |
| 4455 | } | 4459 | } |
| 4460 | static void load_GL_AMD_framebuffer_multisample_advanced(GLADloadproc load) { | ||
| 4461 | if(!GLAD_GL_AMD_framebuffer_multisample_advanced) return; | ||
| 4462 | glad_glRenderbufferStorageMultisampleAdvancedAMD = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC)load("glRenderbufferStorageMultisampleAdvancedAMD"); | ||
| 4463 | glad_glNamedRenderbufferStorageMultisampleAdvancedAMD = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC)load("glNamedRenderbufferStorageMultisampleAdvancedAMD"); | ||
| 4464 | } | ||
| 4456 | static void load_GL_AMD_framebuffer_sample_positions(GLADloadproc load) { | 4465 | static void load_GL_AMD_framebuffer_sample_positions(GLADloadproc load) { |
| 4457 | if(!GLAD_GL_AMD_framebuffer_sample_positions) return; | 4466 | if(!GLAD_GL_AMD_framebuffer_sample_positions) return; |
| 4458 | glad_glFramebufferSamplePositionsfvAMD = (PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC)load("glFramebufferSamplePositionsfvAMD"); | 4467 | glad_glFramebufferSamplePositionsfvAMD = (PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC)load("glFramebufferSamplePositionsfvAMD"); |
| @@ -7812,6 +7821,7 @@ static int find_extensionsGL(void) { | |||
| 7812 | GLAD_GL_AMD_debug_output = has_ext("GL_AMD_debug_output"); | 7821 | GLAD_GL_AMD_debug_output = has_ext("GL_AMD_debug_output"); |
| 7813 | GLAD_GL_AMD_depth_clamp_separate = has_ext("GL_AMD_depth_clamp_separate"); | 7822 | GLAD_GL_AMD_depth_clamp_separate = has_ext("GL_AMD_depth_clamp_separate"); |
| 7814 | GLAD_GL_AMD_draw_buffers_blend = has_ext("GL_AMD_draw_buffers_blend"); | 7823 | GLAD_GL_AMD_draw_buffers_blend = has_ext("GL_AMD_draw_buffers_blend"); |
| 7824 | GLAD_GL_AMD_framebuffer_multisample_advanced = has_ext("GL_AMD_framebuffer_multisample_advanced"); | ||
| 7815 | GLAD_GL_AMD_framebuffer_sample_positions = has_ext("GL_AMD_framebuffer_sample_positions"); | 7825 | GLAD_GL_AMD_framebuffer_sample_positions = has_ext("GL_AMD_framebuffer_sample_positions"); |
| 7816 | GLAD_GL_AMD_gcn_shader = has_ext("GL_AMD_gcn_shader"); | 7826 | GLAD_GL_AMD_gcn_shader = has_ext("GL_AMD_gcn_shader"); |
| 7817 | GLAD_GL_AMD_gpu_shader_half_float = has_ext("GL_AMD_gpu_shader_half_float"); | 7827 | GLAD_GL_AMD_gpu_shader_half_float = has_ext("GL_AMD_gpu_shader_half_float"); |
| @@ -8473,6 +8483,7 @@ int gladLoadGLLoader(GLADloadproc load) { | |||
| 8473 | load_GL_3DFX_tbuffer(load); | 8483 | load_GL_3DFX_tbuffer(load); |
| 8474 | load_GL_AMD_debug_output(load); | 8484 | load_GL_AMD_debug_output(load); |
| 8475 | load_GL_AMD_draw_buffers_blend(load); | 8485 | load_GL_AMD_draw_buffers_blend(load); |
| 8486 | load_GL_AMD_framebuffer_multisample_advanced(load); | ||
| 8476 | load_GL_AMD_framebuffer_sample_positions(load); | 8487 | load_GL_AMD_framebuffer_sample_positions(load); |
| 8477 | load_GL_AMD_gpu_shader_int64(load); | 8488 | load_GL_AMD_gpu_shader_int64(load); |
| 8478 | load_GL_AMD_interleaved_elements(load); | 8489 | load_GL_AMD_interleaved_elements(load); |
diff --git a/externals/mbedtls b/externals/mbedtls new file mode 160000 | |||
| Subproject 06b1b55434dd5d821e911583d629cff39a04b38 | |||
diff --git a/externals/opus b/externals/opus new file mode 160000 | |||
| Subproject b2871922a12abb49579512d604cabc471a59ad9 | |||
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 85354f43e..a88551fbc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt | |||
| @@ -3,6 +3,7 @@ include_directories(.) | |||
| 3 | 3 | ||
| 4 | add_subdirectory(common) | 4 | add_subdirectory(common) |
| 5 | add_subdirectory(core) | 5 | add_subdirectory(core) |
| 6 | add_subdirectory(audio_core) | ||
| 6 | add_subdirectory(video_core) | 7 | add_subdirectory(video_core) |
| 7 | add_subdirectory(input_common) | 8 | add_subdirectory(input_common) |
| 8 | add_subdirectory(tests) | 9 | add_subdirectory(tests) |
diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt new file mode 100644 index 000000000..ec71524a3 --- /dev/null +++ b/src/audio_core/CMakeLists.txt | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | add_library(audio_core STATIC | ||
| 2 | audio_out.cpp | ||
| 3 | audio_out.h | ||
| 4 | audio_renderer.cpp | ||
| 5 | audio_renderer.h | ||
| 6 | buffer.h | ||
| 7 | codec.cpp | ||
| 8 | codec.h | ||
| 9 | null_sink.h | ||
| 10 | stream.cpp | ||
| 11 | stream.h | ||
| 12 | sink.h | ||
| 13 | sink_details.cpp | ||
| 14 | sink_details.h | ||
| 15 | sink_stream.h | ||
| 16 | |||
| 17 | $<$<BOOL:${ENABLE_CUBEB}>:cubeb_sink.cpp cubeb_sink.h> | ||
| 18 | ) | ||
| 19 | |||
| 20 | create_target_directory_groups(audio_core) | ||
| 21 | |||
| 22 | target_link_libraries(audio_core PUBLIC common core) | ||
| 23 | |||
| 24 | if(ENABLE_CUBEB) | ||
| 25 | target_link_libraries(audio_core PRIVATE cubeb) | ||
| 26 | target_compile_definitions(audio_core PRIVATE -DHAVE_CUBEB=1) | ||
| 27 | endif() | ||
diff --git a/src/audio_core/audio_out.cpp b/src/audio_core/audio_out.cpp new file mode 100644 index 000000000..12632a95c --- /dev/null +++ b/src/audio_core/audio_out.cpp | |||
| @@ -0,0 +1,58 @@ | |||
| 1 | // Copyright 2018 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "audio_core/audio_out.h" | ||
| 6 | #include "audio_core/sink.h" | ||
| 7 | #include "audio_core/sink_details.h" | ||
| 8 | #include "common/assert.h" | ||
| 9 | #include "common/logging/log.h" | ||
| 10 | #include "core/settings.h" | ||
| 11 | |||
| 12 | namespace AudioCore { | ||
| 13 | |||
| 14 | /// Returns the stream format from the specified number of channels | ||
| 15 | static Stream::Format ChannelsToStreamFormat(u32 num_channels) { | ||
| 16 | switch (num_channels) { | ||
| 17 | case 1: | ||
| 18 | return Stream::Format::Mono16; | ||
| 19 | case 2: | ||
| 20 | return Stream::Format::Stereo16; | ||
| 21 | case 6: | ||
| 22 | return Stream::Format::Multi51Channel16; | ||
| 23 | } | ||
| 24 | |||
| 25 | LOG_CRITICAL(Audio, "Unimplemented num_channels={}", num_channels); | ||
| 26 | UNREACHABLE(); | ||
| 27 | return {}; | ||
| 28 | } | ||
| 29 | |||
| 30 | StreamPtr AudioOut::OpenStream(u32 sample_rate, u32 num_channels, std::string&& name, | ||
| 31 | Stream::ReleaseCallback&& release_callback) { | ||
| 32 | if (!sink) { | ||
| 33 | const SinkDetails& sink_details = GetSinkDetails(Settings::values.sink_id); | ||
| 34 | sink = sink_details.factory(Settings::values.audio_device_id); | ||
| 35 | } | ||
| 36 | |||
| 37 | return std::make_shared<Stream>( | ||
| 38 | sample_rate, ChannelsToStreamFormat(num_channels), std::move(release_callback), | ||
| 39 | sink->AcquireSinkStream(sample_rate, num_channels, name), std::move(name)); | ||
| 40 | } | ||
| 41 | |||
| 42 | std::vector<Buffer::Tag> AudioOut::GetTagsAndReleaseBuffers(StreamPtr stream, size_t max_count) { | ||
| 43 | return stream->GetTagsAndReleaseBuffers(max_count); | ||
| 44 | } | ||
| 45 | |||
| 46 | void AudioOut::StartStream(StreamPtr stream) { | ||
| 47 | stream->Play(); | ||
| 48 | } | ||
| 49 | |||
| 50 | void AudioOut::StopStream(StreamPtr stream) { | ||
| 51 | stream->Stop(); | ||
| 52 | } | ||
| 53 | |||
| 54 | bool AudioOut::QueueBuffer(StreamPtr stream, Buffer::Tag tag, std::vector<s16>&& data) { | ||
| 55 | return stream->QueueBuffer(std::make_shared<Buffer>(tag, std::move(data))); | ||
| 56 | } | ||
| 57 | |||
| 58 | } // namespace AudioCore | ||
diff --git a/src/audio_core/audio_out.h b/src/audio_core/audio_out.h new file mode 100644 index 000000000..39b7e656b --- /dev/null +++ b/src/audio_core/audio_out.h | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | // Copyright 2018 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | #include <string> | ||
| 9 | #include <vector> | ||
| 10 | |||
| 11 | #include "audio_core/buffer.h" | ||
| 12 | #include "audio_core/sink.h" | ||
| 13 | #include "audio_core/stream.h" | ||
| 14 | #include "common/common_types.h" | ||
| 15 | |||
| 16 | namespace AudioCore { | ||
| 17 | |||
| 18 | /** | ||
| 19 | * Represents an audio playback interface, used to open and play audio streams | ||
| 20 | */ | ||
| 21 | class AudioOut { | ||
| 22 | public: | ||
| 23 | /// Opens a new audio stream | ||
| 24 | StreamPtr OpenStream(u32 sample_rate, u32 num_channels, std::string&& name, | ||
| 25 | Stream::ReleaseCallback&& release_callback); | ||
| 26 | |||
| 27 | /// Returns a vector of recently released buffers specified by tag for the specified stream | ||
| 28 | std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(StreamPtr stream, size_t max_count); | ||
| 29 | |||
| 30 | /// Starts an audio stream for playback | ||
| 31 | void StartStream(StreamPtr stream); | ||
| 32 | |||
| 33 | /// Stops an audio stream that is currently playing | ||
| 34 | void StopStream(StreamPtr stream); | ||
| 35 | |||
| 36 | /// Queues a buffer into the specified audio stream, returns true on success | ||
| 37 | bool QueueBuffer(StreamPtr stream, Buffer::Tag tag, std::vector<s16>&& data); | ||
| 38 | |||
| 39 | private: | ||
| 40 | SinkPtr sink; | ||
| 41 | }; | ||
| 42 | |||
| 43 | } // namespace AudioCore | ||
diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp new file mode 100644 index 000000000..282f345c5 --- /dev/null +++ b/src/audio_core/audio_renderer.cpp | |||
| @@ -0,0 +1,234 @@ | |||
| 1 | // Copyright 2018 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "audio_core/audio_renderer.h" | ||
| 6 | #include "common/assert.h" | ||
| 7 | #include "common/logging/log.h" | ||
| 8 | #include "core/memory.h" | ||
| 9 | |||
| 10 | namespace AudioCore { | ||
| 11 | |||
| 12 | constexpr u32 STREAM_SAMPLE_RATE{48000}; | ||
| 13 | constexpr u32 STREAM_NUM_CHANNELS{2}; | ||
| 14 | |||
| 15 | AudioRenderer::AudioRenderer(AudioRendererParameter params, | ||
| 16 | Kernel::SharedPtr<Kernel::Event> buffer_event) | ||
| 17 | : worker_params{params}, buffer_event{buffer_event}, voices(params.voice_count) { | ||
| 18 | |||
| 19 | audio_core = std::make_unique<AudioCore::AudioOut>(); | ||
| 20 | stream = audio_core->OpenStream(STREAM_SAMPLE_RATE, STREAM_NUM_CHANNELS, "AudioRenderer", | ||
| 21 | [=]() { buffer_event->Signal(); }); | ||
| 22 | audio_core->StartStream(stream); | ||
| 23 | |||
| 24 | QueueMixedBuffer(0); | ||
| 25 | QueueMixedBuffer(1); | ||
| 26 | QueueMixedBuffer(2); | ||
| 27 | } | ||
| 28 | |||
| 29 | std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_params) { | ||
| 30 | // Copy UpdateDataHeader struct | ||
| 31 | UpdateDataHeader config{}; | ||
| 32 | std::memcpy(&config, input_params.data(), sizeof(UpdateDataHeader)); | ||
| 33 | u32 memory_pool_count = worker_params.effect_count + (worker_params.voice_count * 4); | ||
| 34 | |||
| 35 | // Copy MemoryPoolInfo structs | ||
| 36 | std::vector<MemoryPoolInfo> mem_pool_info(memory_pool_count); | ||
| 37 | std::memcpy(mem_pool_info.data(), | ||
| 38 | input_params.data() + sizeof(UpdateDataHeader) + config.behavior_size, | ||
| 39 | memory_pool_count * sizeof(MemoryPoolInfo)); | ||
| 40 | |||
| 41 | // Copy VoiceInfo structs | ||
| 42 | size_t offset{sizeof(UpdateDataHeader) + config.behavior_size + config.memory_pools_size + | ||
| 43 | config.voice_resource_size}; | ||
| 44 | for (auto& voice : voices) { | ||
| 45 | std::memcpy(&voice.Info(), input_params.data() + offset, sizeof(VoiceInfo)); | ||
| 46 | offset += sizeof(VoiceInfo); | ||
| 47 | } | ||
| 48 | |||
| 49 | // Update voices | ||
| 50 | for (auto& voice : voices) { | ||
| 51 | voice.UpdateState(); | ||
| 52 | if (!voice.GetInfo().is_in_use) { | ||
| 53 | continue; | ||
| 54 | } | ||
| 55 | if (voice.GetInfo().is_new) { | ||
| 56 | voice.SetWaveIndex(voice.GetInfo().wave_buffer_head); | ||
| 57 | } | ||
| 58 | } | ||
| 59 | |||
| 60 | // Update memory pool state | ||
| 61 | std::vector<MemoryPoolEntry> memory_pool(memory_pool_count); | ||
| 62 | for (size_t index = 0; index < memory_pool.size(); ++index) { | ||
| 63 | if (mem_pool_info[index].pool_state == MemoryPoolStates::RequestAttach) { | ||
| 64 | memory_pool[index].state = MemoryPoolStates::Attached; | ||
| 65 | } else if (mem_pool_info[index].pool_state == MemoryPoolStates::RequestDetach) { | ||
| 66 | memory_pool[index].state = MemoryPoolStates::Detached; | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | // Release previous buffers and queue next ones for playback | ||
| 71 | ReleaseAndQueueBuffers(); | ||
| 72 | |||
| 73 | // Copy output header | ||
| 74 | UpdateDataHeader response_data{worker_params}; | ||
| 75 | std::vector<u8> output_params(response_data.total_size); | ||
| 76 | std::memcpy(output_params.data(), &response_data, sizeof(UpdateDataHeader)); | ||
| 77 | |||
| 78 | // Copy output memory pool entries | ||
| 79 | std::memcpy(output_params.data() + sizeof(UpdateDataHeader), memory_pool.data(), | ||
| 80 | response_data.memory_pools_size); | ||
| 81 | |||
| 82 | // Copy output voice status | ||
| 83 | size_t voice_out_status_offset{sizeof(UpdateDataHeader) + response_data.memory_pools_size}; | ||
| 84 | for (const auto& voice : voices) { | ||
| 85 | std::memcpy(output_params.data() + voice_out_status_offset, &voice.GetOutStatus(), | ||
| 86 | sizeof(VoiceOutStatus)); | ||
| 87 | voice_out_status_offset += sizeof(VoiceOutStatus); | ||
| 88 | } | ||
| 89 | |||
| 90 | return output_params; | ||
| 91 | } | ||
| 92 | |||
| 93 | void AudioRenderer::VoiceState::SetWaveIndex(size_t index) { | ||
| 94 | wave_index = index & 3; | ||
| 95 | is_refresh_pending = true; | ||
| 96 | } | ||
| 97 | |||
| 98 | std::vector<s16> AudioRenderer::VoiceState::DequeueSamples(size_t sample_count) { | ||
| 99 | if (!IsPlaying()) { | ||
| 100 | return {}; | ||
| 101 | } | ||
| 102 | |||
| 103 | if (is_refresh_pending) { | ||
| 104 | RefreshBuffer(); | ||
| 105 | } | ||
| 106 | |||
| 107 | const size_t max_size{samples.size() - offset}; | ||
| 108 | const size_t dequeue_offset{offset}; | ||
| 109 | size_t size{sample_count * STREAM_NUM_CHANNELS}; | ||
| 110 | if (size > max_size) { | ||
| 111 | size = max_size; | ||
| 112 | } | ||
| 113 | |||
| 114 | out_status.played_sample_count += size / STREAM_NUM_CHANNELS; | ||
| 115 | offset += size; | ||
| 116 | |||
| 117 | const auto& wave_buffer{info.wave_buffer[wave_index]}; | ||
| 118 | if (offset == samples.size()) { | ||
| 119 | offset = 0; | ||
| 120 | |||
| 121 | if (!wave_buffer.is_looping) { | ||
| 122 | SetWaveIndex(wave_index + 1); | ||
| 123 | } | ||
| 124 | |||
| 125 | out_status.wave_buffer_consumed++; | ||
| 126 | |||
| 127 | if (wave_buffer.end_of_stream) { | ||
| 128 | info.play_state = PlayState::Paused; | ||
| 129 | } | ||
| 130 | } | ||
| 131 | |||
| 132 | return {samples.begin() + dequeue_offset, samples.begin() + dequeue_offset + size}; | ||
| 133 | } | ||
| 134 | |||
| 135 | void AudioRenderer::VoiceState::UpdateState() { | ||
| 136 | if (is_in_use && !info.is_in_use) { | ||
| 137 | // No longer in use, reset state | ||
| 138 | is_refresh_pending = true; | ||
| 139 | wave_index = 0; | ||
| 140 | offset = 0; | ||
| 141 | out_status = {}; | ||
| 142 | } | ||
| 143 | is_in_use = info.is_in_use; | ||
| 144 | } | ||
| 145 | |||
| 146 | void AudioRenderer::VoiceState::RefreshBuffer() { | ||
| 147 | std::vector<s16> new_samples(info.wave_buffer[wave_index].buffer_sz / sizeof(s16)); | ||
| 148 | Memory::ReadBlock(info.wave_buffer[wave_index].buffer_addr, new_samples.data(), | ||
| 149 | info.wave_buffer[wave_index].buffer_sz); | ||
| 150 | |||
| 151 | switch (static_cast<Codec::PcmFormat>(info.sample_format)) { | ||
| 152 | case Codec::PcmFormat::Int16: { | ||
| 153 | // PCM16 is played as-is | ||
| 154 | break; | ||
| 155 | } | ||
| 156 | case Codec::PcmFormat::Adpcm: { | ||
| 157 | // Decode ADPCM to PCM16 | ||
| 158 | Codec::ADPCM_Coeff coeffs; | ||
| 159 | Memory::ReadBlock(info.additional_params_addr, coeffs.data(), sizeof(Codec::ADPCM_Coeff)); | ||
| 160 | new_samples = Codec::DecodeADPCM(reinterpret_cast<u8*>(new_samples.data()), | ||
| 161 | new_samples.size() * sizeof(s16), coeffs, adpcm_state); | ||
| 162 | break; | ||
| 163 | } | ||
| 164 | default: | ||
| 165 | LOG_CRITICAL(Audio, "Unimplemented sample_format={}", info.sample_format); | ||
| 166 | UNREACHABLE(); | ||
| 167 | break; | ||
| 168 | } | ||
| 169 | |||
| 170 | switch (info.channel_count) { | ||
| 171 | case 1: | ||
| 172 | // 1 channel is upsampled to 2 channel | ||
| 173 | samples.resize(new_samples.size() * 2); | ||
| 174 | for (size_t index = 0; index < new_samples.size(); ++index) { | ||
| 175 | samples[index * 2] = new_samples[index]; | ||
| 176 | samples[index * 2 + 1] = new_samples[index]; | ||
| 177 | } | ||
| 178 | break; | ||
| 179 | case 2: { | ||
| 180 | // 2 channel is played as is | ||
| 181 | samples = std::move(new_samples); | ||
| 182 | break; | ||
| 183 | } | ||
| 184 | default: | ||
| 185 | LOG_CRITICAL(Audio, "Unimplemented channel_count={}", info.channel_count); | ||
| 186 | UNREACHABLE(); | ||
| 187 | break; | ||
| 188 | } | ||
| 189 | |||
| 190 | is_refresh_pending = false; | ||
| 191 | } | ||
| 192 | |||
| 193 | static constexpr s16 ClampToS16(s32 value) { | ||
| 194 | return static_cast<s16>(std::clamp(value, -32768, 32767)); | ||
| 195 | } | ||
| 196 | |||
| 197 | void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) { | ||
| 198 | constexpr size_t BUFFER_SIZE{512}; | ||
| 199 | std::vector<s16> buffer(BUFFER_SIZE * stream->GetNumChannels()); | ||
| 200 | |||
| 201 | for (auto& voice : voices) { | ||
| 202 | if (!voice.IsPlaying()) { | ||
| 203 | continue; | ||
| 204 | } | ||
| 205 | |||
| 206 | size_t offset{}; | ||
| 207 | s64 samples_remaining{BUFFER_SIZE}; | ||
| 208 | while (samples_remaining > 0) { | ||
| 209 | const std::vector<s16> samples{voice.DequeueSamples(samples_remaining)}; | ||
| 210 | |||
| 211 | if (samples.empty()) { | ||
| 212 | break; | ||
| 213 | } | ||
| 214 | |||
| 215 | samples_remaining -= samples.size(); | ||
| 216 | |||
| 217 | for (const auto& sample : samples) { | ||
| 218 | const s32 buffer_sample{buffer[offset]}; | ||
| 219 | buffer[offset++] = | ||
| 220 | ClampToS16(buffer_sample + static_cast<s32>(sample * voice.GetInfo().volume)); | ||
| 221 | } | ||
| 222 | } | ||
| 223 | } | ||
| 224 | audio_core->QueueBuffer(stream, tag, std::move(buffer)); | ||
| 225 | } | ||
| 226 | |||
| 227 | void AudioRenderer::ReleaseAndQueueBuffers() { | ||
| 228 | const auto released_buffers{audio_core->GetTagsAndReleaseBuffers(stream, 2)}; | ||
| 229 | for (const auto& tag : released_buffers) { | ||
| 230 | QueueMixedBuffer(tag); | ||
| 231 | } | ||
| 232 | } | ||
| 233 | |||
| 234 | } // namespace AudioCore | ||
diff --git a/src/audio_core/audio_renderer.h b/src/audio_core/audio_renderer.h new file mode 100644 index 000000000..6950a4681 --- /dev/null +++ b/src/audio_core/audio_renderer.h | |||
| @@ -0,0 +1,206 @@ | |||
| 1 | // Copyright 2018 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <array> | ||
| 8 | #include <memory> | ||
| 9 | #include <vector> | ||
| 10 | |||
| 11 | #include "audio_core/audio_out.h" | ||
| 12 | #include "audio_core/codec.h" | ||
| 13 | #include "audio_core/stream.h" | ||
| 14 | #include "common/common_types.h" | ||
| 15 | #include "common/swap.h" | ||
| 16 | #include "core/hle/kernel/event.h" | ||
| 17 | |||
| 18 | namespace AudioCore { | ||
| 19 | |||
| 20 | enum class PlayState : u8 { | ||
| 21 | Started = 0, | ||
| 22 | Stopped = 1, | ||
| 23 | Paused = 2, | ||
| 24 | }; | ||
| 25 | |||
| 26 | struct AudioRendererParameter { | ||
| 27 | u32_le sample_rate; | ||
| 28 | u32_le sample_count; | ||
| 29 | u32_le unknown_8; | ||
| 30 | u32_le unknown_c; | ||
| 31 | u32_le voice_count; | ||
| 32 | u32_le sink_count; | ||
| 33 | u32_le effect_count; | ||
| 34 | u32_le unknown_1c; | ||
| 35 | u8 unknown_20; | ||
| 36 | INSERT_PADDING_BYTES(3); | ||
| 37 | u32_le splitter_count; | ||
| 38 | u32_le unknown_2c; | ||
| 39 | INSERT_PADDING_WORDS(1); | ||
| 40 | u32_le revision; | ||
| 41 | }; | ||
| 42 | static_assert(sizeof(AudioRendererParameter) == 52, "AudioRendererParameter is an invalid size"); | ||
| 43 | |||
| 44 | enum class MemoryPoolStates : u32 { // Should be LE | ||
| 45 | Invalid = 0x0, | ||
| 46 | Unknown = 0x1, | ||
| 47 | RequestDetach = 0x2, | ||
| 48 | Detached = 0x3, | ||
| 49 | RequestAttach = 0x4, | ||
| 50 | Attached = 0x5, | ||
| 51 | Released = 0x6, | ||
| 52 | }; | ||
| 53 | |||
| 54 | struct MemoryPoolEntry { | ||
| 55 | MemoryPoolStates state; | ||
| 56 | u32_le unknown_4; | ||
| 57 | u32_le unknown_8; | ||
| 58 | u32_le unknown_c; | ||
| 59 | }; | ||
| 60 | static_assert(sizeof(MemoryPoolEntry) == 0x10, "MemoryPoolEntry has wrong size"); | ||
| 61 | |||
| 62 | struct MemoryPoolInfo { | ||
| 63 | u64_le pool_address; | ||
| 64 | u64_le pool_size; | ||
| 65 | MemoryPoolStates pool_state; | ||
| 66 | INSERT_PADDING_WORDS(3); // Unknown | ||
| 67 | }; | ||
| 68 | static_assert(sizeof(MemoryPoolInfo) == 0x20, "MemoryPoolInfo has wrong size"); | ||
| 69 | struct BiquadFilter { | ||
| 70 | u8 enable; | ||
| 71 | INSERT_PADDING_BYTES(1); | ||
| 72 | std::array<s16_le, 3> numerator; | ||
| 73 | std::array<s16_le, 2> denominator; | ||
| 74 | }; | ||
| 75 | static_assert(sizeof(BiquadFilter) == 0xc, "BiquadFilter has wrong size"); | ||
| 76 | |||
| 77 | struct WaveBuffer { | ||
| 78 | u64_le buffer_addr; | ||
| 79 | u64_le buffer_sz; | ||
| 80 | s32_le start_sample_offset; | ||
| 81 | s32_le end_sample_offset; | ||
| 82 | u8 is_looping; | ||
| 83 | u8 end_of_stream; | ||
| 84 | u8 sent_to_server; | ||
| 85 | INSERT_PADDING_BYTES(5); | ||
| 86 | u64 context_addr; | ||
| 87 | u64 context_sz; | ||
| 88 | INSERT_PADDING_BYTES(8); | ||
| 89 | }; | ||
| 90 | static_assert(sizeof(WaveBuffer) == 0x38, "WaveBuffer has wrong size"); | ||
| 91 | |||
| 92 | struct VoiceInfo { | ||
| 93 | u32_le id; | ||
| 94 | u32_le node_id; | ||
| 95 | u8 is_new; | ||
| 96 | u8 is_in_use; | ||
| 97 | PlayState play_state; | ||
| 98 | u8 sample_format; | ||
| 99 | u32_le sample_rate; | ||
| 100 | u32_le priority; | ||
| 101 | u32_le sorting_order; | ||
| 102 | u32_le channel_count; | ||
| 103 | float_le pitch; | ||
| 104 | float_le volume; | ||
| 105 | std::array<BiquadFilter, 2> biquad_filter; | ||
| 106 | u32_le wave_buffer_count; | ||
| 107 | u32_le wave_buffer_head; | ||
| 108 | INSERT_PADDING_WORDS(1); | ||
| 109 | u64_le additional_params_addr; | ||
| 110 | u64_le additional_params_sz; | ||
| 111 | u32_le mix_id; | ||
| 112 | u32_le splitter_info_id; | ||
| 113 | std::array<WaveBuffer, 4> wave_buffer; | ||
| 114 | std::array<u32_le, 6> voice_channel_resource_ids; | ||
| 115 | INSERT_PADDING_BYTES(24); | ||
| 116 | }; | ||
| 117 | static_assert(sizeof(VoiceInfo) == 0x170, "VoiceInfo is wrong size"); | ||
| 118 | |||
| 119 | struct VoiceOutStatus { | ||
| 120 | u64_le played_sample_count; | ||
| 121 | u32_le wave_buffer_consumed; | ||
| 122 | u32_le voice_drops_count; | ||
| 123 | }; | ||
| 124 | static_assert(sizeof(VoiceOutStatus) == 0x10, "VoiceOutStatus has wrong size"); | ||
| 125 | |||
| 126 | struct UpdateDataHeader { | ||
| 127 | UpdateDataHeader() {} | ||
| 128 | |||
| 129 | explicit UpdateDataHeader(const AudioRendererParameter& config) { | ||
| 130 | revision = Common::MakeMagic('R', 'E', 'V', '4'); // 5.1.0 Revision | ||
| 131 | behavior_size = 0xb0; | ||
| 132 | memory_pools_size = (config.effect_count + (config.voice_count * 4)) * 0x10; | ||
| 133 | voices_size = config.voice_count * 0x10; | ||
| 134 | voice_resource_size = 0x0; | ||
| 135 | effects_size = config.effect_count * 0x10; | ||
| 136 | mixes_size = 0x0; | ||
| 137 | sinks_size = config.sink_count * 0x20; | ||
| 138 | performance_manager_size = 0x10; | ||
| 139 | total_size = sizeof(UpdateDataHeader) + behavior_size + memory_pools_size + voices_size + | ||
| 140 | effects_size + sinks_size + performance_manager_size; | ||
| 141 | } | ||
| 142 | |||
| 143 | u32_le revision; | ||
| 144 | u32_le behavior_size; | ||
| 145 | u32_le memory_pools_size; | ||
| 146 | u32_le voices_size; | ||
| 147 | u32_le voice_resource_size; | ||
| 148 | u32_le effects_size; | ||
| 149 | u32_le mixes_size; | ||
| 150 | u32_le sinks_size; | ||
| 151 | u32_le performance_manager_size; | ||
| 152 | INSERT_PADDING_WORDS(6); | ||
| 153 | u32_le total_size; | ||
| 154 | }; | ||
| 155 | static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size"); | ||
| 156 | |||
| 157 | class AudioRenderer { | ||
| 158 | public: | ||
| 159 | AudioRenderer(AudioRendererParameter params, Kernel::SharedPtr<Kernel::Event> buffer_event); | ||
| 160 | std::vector<u8> UpdateAudioRenderer(const std::vector<u8>& input_params); | ||
| 161 | void QueueMixedBuffer(Buffer::Tag tag); | ||
| 162 | void ReleaseAndQueueBuffers(); | ||
| 163 | |||
| 164 | private: | ||
| 165 | class VoiceState { | ||
| 166 | public: | ||
| 167 | bool IsPlaying() const { | ||
| 168 | return is_in_use && info.play_state == PlayState::Started; | ||
| 169 | } | ||
| 170 | |||
| 171 | const VoiceOutStatus& GetOutStatus() const { | ||
| 172 | return out_status; | ||
| 173 | } | ||
| 174 | |||
| 175 | const VoiceInfo& GetInfo() const { | ||
| 176 | return info; | ||
| 177 | } | ||
| 178 | |||
| 179 | VoiceInfo& Info() { | ||
| 180 | return info; | ||
| 181 | } | ||
| 182 | |||
| 183 | void SetWaveIndex(size_t index); | ||
| 184 | std::vector<s16> DequeueSamples(size_t sample_count); | ||
| 185 | void UpdateState(); | ||
| 186 | void RefreshBuffer(); | ||
| 187 | |||
| 188 | private: | ||
| 189 | bool is_in_use{}; | ||
| 190 | bool is_refresh_pending{}; | ||
| 191 | size_t wave_index{}; | ||
| 192 | size_t offset{}; | ||
| 193 | Codec::ADPCMState adpcm_state{}; | ||
| 194 | std::vector<s16> samples; | ||
| 195 | VoiceOutStatus out_status{}; | ||
| 196 | VoiceInfo info{}; | ||
| 197 | }; | ||
| 198 | |||
| 199 | AudioRendererParameter worker_params; | ||
| 200 | Kernel::SharedPtr<Kernel::Event> buffer_event; | ||
| 201 | std::vector<VoiceState> voices; | ||
| 202 | std::unique_ptr<AudioCore::AudioOut> audio_core; | ||
| 203 | AudioCore::StreamPtr stream; | ||
| 204 | }; | ||
| 205 | |||
| 206 | } // namespace AudioCore | ||
diff --git a/src/audio_core/buffer.h b/src/audio_core/buffer.h new file mode 100644 index 000000000..a323b23ec --- /dev/null +++ b/src/audio_core/buffer.h | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | // Copyright 2018 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | #include <vector> | ||
| 9 | |||
| 10 | #include "common/common_types.h" | ||
| 11 | |||
| 12 | namespace AudioCore { | ||
| 13 | |||
| 14 | /** | ||
| 15 | * Represents a buffer of audio samples to be played in an audio stream | ||
| 16 | */ | ||
| 17 | class Buffer { | ||
| 18 | public: | ||
| 19 | using Tag = u64; | ||
| 20 | |||
| 21 | Buffer(Tag tag, std::vector<s16>&& samples) : tag{tag}, samples{std::move(samples)} {} | ||
| 22 | |||
| 23 | /// Returns the raw audio data for the buffer | ||
| 24 | std::vector<s16>& Samples() { | ||
| 25 | return samples; | ||
| 26 | } | ||
| 27 | |||
| 28 | /// Returns the raw audio data for the buffer | ||
| 29 | const std::vector<s16>& GetSamples() const { | ||
| 30 | return samples; | ||
| 31 | } | ||
| 32 | |||
| 33 | /// Returns the buffer tag, this is provided by the game to the audout service | ||
| 34 | Tag GetTag() const { | ||
| 35 | return tag; | ||
| 36 | } | ||
| 37 | |||
| 38 | private: | ||
| 39 | Tag tag; | ||
| 40 | std::vector<s16> samples; | ||
| 41 | }; | ||
| 42 | |||
| 43 | using BufferPtr = std::shared_ptr<Buffer>; | ||
| 44 | |||
| 45 | } // namespace AudioCore | ||
diff --git a/src/audio_core/codec.cpp b/src/audio_core/codec.cpp new file mode 100644 index 000000000..c3021403f --- /dev/null +++ b/src/audio_core/codec.cpp | |||
| @@ -0,0 +1,77 @@ | |||
| 1 | // Copyright 2018 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | |||
| 7 | #include "audio_core/codec.h" | ||
| 8 | |||
| 9 | namespace AudioCore::Codec { | ||
| 10 | |||
| 11 | std::vector<s16> DecodeADPCM(const u8* const data, size_t size, const ADPCM_Coeff& coeff, | ||
| 12 | ADPCMState& state) { | ||
| 13 | // GC-ADPCM with scale factor and variable coefficients. | ||
| 14 | // Frames are 8 bytes long containing 14 samples each. | ||
| 15 | // Samples are 4 bits (one nibble) long. | ||
| 16 | |||
| 17 | constexpr size_t FRAME_LEN = 8; | ||
| 18 | constexpr size_t SAMPLES_PER_FRAME = 14; | ||
| 19 | constexpr std::array<int, 16> SIGNED_NIBBLES = { | ||
| 20 | {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}}; | ||
| 21 | |||
| 22 | const size_t sample_count = (size / FRAME_LEN) * SAMPLES_PER_FRAME; | ||
| 23 | const size_t ret_size = | ||
| 24 | sample_count % 2 == 0 ? sample_count : sample_count + 1; // Ensure multiple of two. | ||
| 25 | std::vector<s16> ret(ret_size); | ||
| 26 | |||
| 27 | int yn1 = state.yn1, yn2 = state.yn2; | ||
| 28 | |||
| 29 | const size_t NUM_FRAMES = | ||
| 30 | (sample_count + (SAMPLES_PER_FRAME - 1)) / SAMPLES_PER_FRAME; // Round up. | ||
| 31 | for (size_t framei = 0; framei < NUM_FRAMES; framei++) { | ||
| 32 | const int frame_header = data[framei * FRAME_LEN]; | ||
| 33 | const int scale = 1 << (frame_header & 0xF); | ||
| 34 | const int idx = (frame_header >> 4) & 0x7; | ||
| 35 | |||
| 36 | // Coefficients are fixed point with 11 bits fractional part. | ||
| 37 | const int coef1 = coeff[idx * 2 + 0]; | ||
| 38 | const int coef2 = coeff[idx * 2 + 1]; | ||
| 39 | |||
| 40 | // Decodes an audio sample. One nibble produces one sample. | ||
| 41 | const auto decode_sample = [&](const int nibble) -> s16 { | ||
| 42 | const int xn = nibble * scale; | ||
| 43 | // We first transform everything into 11 bit fixed point, perform the second order | ||
| 44 | // digital filter, then transform back. | ||
| 45 | // 0x400 == 0.5 in 11 bit fixed point. | ||
| 46 | // Filter: y[n] = x[n] + 0.5 + c1 * y[n-1] + c2 * y[n-2] | ||
| 47 | int val = ((xn << 11) + 0x400 + coef1 * yn1 + coef2 * yn2) >> 11; | ||
| 48 | // Clamp to output range. | ||
| 49 | val = std::clamp<s32>(val, -32768, 32767); | ||
| 50 | // Advance output feedback. | ||
| 51 | yn2 = yn1; | ||
| 52 | yn1 = val; | ||
| 53 | return static_cast<s16>(val); | ||
| 54 | }; | ||
| 55 | |||
| 56 | size_t outputi = framei * SAMPLES_PER_FRAME; | ||
| 57 | size_t datai = framei * FRAME_LEN + 1; | ||
| 58 | for (size_t i = 0; i < SAMPLES_PER_FRAME && outputi < sample_count; i += 2) { | ||
| 59 | const s16 sample1 = decode_sample(SIGNED_NIBBLES[data[datai] >> 4]); | ||
| 60 | ret[outputi] = sample1; | ||
| 61 | outputi++; | ||
| 62 | |||
| 63 | const s16 sample2 = decode_sample(SIGNED_NIBBLES[data[datai] & 0xF]); | ||
| 64 | ret[outputi] = sample2; | ||
| 65 | outputi++; | ||
| 66 | |||
| 67 | datai++; | ||
| 68 | } | ||
| 69 | } | ||
| 70 | |||
| 71 | state.yn1 = yn1; | ||
| 72 | state.yn2 = yn2; | ||
| 73 | |||
| 74 | return ret; | ||
| 75 | } | ||
| 76 | |||
| 77 | } // namespace AudioCore::Codec | ||
diff --git a/src/audio_core/codec.h b/src/audio_core/codec.h new file mode 100644 index 000000000..3f845c42c --- /dev/null +++ b/src/audio_core/codec.h | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | // Copyright 2018 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <array> | ||
| 8 | #include <vector> | ||
| 9 | |||
| 10 | #include "common/common_types.h" | ||
| 11 | |||
| 12 | namespace AudioCore::Codec { | ||
| 13 | |||
| 14 | enum class PcmFormat : u32 { | ||
| 15 | Invalid = 0, | ||
| 16 | Int8 = 1, | ||
| 17 | Int16 = 2, | ||
| 18 | Int24 = 3, | ||
| 19 | Int32 = 4, | ||
| 20 | PcmFloat = 5, | ||
| 21 | Adpcm = 6, | ||
| 22 | }; | ||
| 23 | |||
| 24 | /// See: Codec::DecodeADPCM | ||
| 25 | struct ADPCMState { | ||
| 26 | // Two historical samples from previous processed buffer, | ||
| 27 | // required for ADPCM decoding | ||
| 28 | s16 yn1; ///< y[n-1] | ||
| 29 | s16 yn2; ///< y[n-2] | ||
| 30 | }; | ||
| 31 | |||
| 32 | using ADPCM_Coeff = std::array<s16, 16>; | ||
| 33 | |||
| 34 | /** | ||
| 35 | * @param data Pointer to buffer that contains ADPCM data to decode | ||
| 36 | * @param size Size of buffer in bytes | ||
| 37 | * @param coeff ADPCM coefficients | ||
| 38 | * @param state ADPCM state, this is updated with new state | ||
| 39 | * @return Decoded stereo signed PCM16 data, sample_count in length | ||
| 40 | */ | ||
| 41 | std::vector<s16> DecodeADPCM(const u8* const data, size_t size, const ADPCM_Coeff& coeff, | ||
| 42 | ADPCMState& state); | ||
| 43 | |||
| 44 | }; // namespace AudioCore::Codec | ||
diff --git a/src/audio_core/cubeb_sink.cpp b/src/audio_core/cubeb_sink.cpp new file mode 100644 index 000000000..1501ef1f4 --- /dev/null +++ b/src/audio_core/cubeb_sink.cpp | |||
| @@ -0,0 +1,200 @@ | |||
| 1 | // Copyright 2018 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | #include <cstring> | ||
| 7 | |||
| 8 | #include "audio_core/cubeb_sink.h" | ||
| 9 | #include "audio_core/stream.h" | ||
| 10 | #include "common/logging/log.h" | ||
| 11 | |||
| 12 | namespace AudioCore { | ||
| 13 | |||
| 14 | class SinkStreamImpl final : public SinkStream { | ||
| 15 | public: | ||
| 16 | SinkStreamImpl(cubeb* ctx, u32 sample_rate, u32 num_channels_, cubeb_devid output_device, | ||
| 17 | const std::string& name) | ||
| 18 | : ctx{ctx}, num_channels{num_channels_} { | ||
| 19 | |||
| 20 | if (num_channels == 6) { | ||
| 21 | // 6-channel audio does not seem to work with cubeb + SDL, so we downsample this to 2 | ||
| 22 | // channel for now | ||
| 23 | is_6_channel = true; | ||
| 24 | num_channels = 2; | ||
| 25 | } | ||
| 26 | |||
| 27 | cubeb_stream_params params{}; | ||
| 28 | params.rate = sample_rate; | ||
| 29 | params.channels = num_channels; | ||
| 30 | params.format = CUBEB_SAMPLE_S16NE; | ||
| 31 | params.layout = num_channels == 1 ? CUBEB_LAYOUT_MONO : CUBEB_LAYOUT_STEREO; | ||
| 32 | |||
| 33 | u32 minimum_latency{}; | ||
| 34 | if (cubeb_get_min_latency(ctx, ¶ms, &minimum_latency) != CUBEB_OK) { | ||
| 35 | LOG_CRITICAL(Audio_Sink, "Error getting minimum latency"); | ||
| 36 | } | ||
| 37 | |||
| 38 | if (cubeb_stream_init(ctx, &stream_backend, name.c_str(), nullptr, nullptr, output_device, | ||
| 39 | ¶ms, std::max(512u, minimum_latency), | ||
| 40 | &SinkStreamImpl::DataCallback, &SinkStreamImpl::StateCallback, | ||
| 41 | this) != CUBEB_OK) { | ||
| 42 | LOG_CRITICAL(Audio_Sink, "Error initializing cubeb stream"); | ||
| 43 | return; | ||
| 44 | } | ||
| 45 | |||
| 46 | if (cubeb_stream_start(stream_backend) != CUBEB_OK) { | ||
| 47 | LOG_CRITICAL(Audio_Sink, "Error starting cubeb stream"); | ||
| 48 | return; | ||
| 49 | } | ||
| 50 | } | ||
| 51 | |||
| 52 | ~SinkStreamImpl() { | ||
| 53 | if (!ctx) { | ||
| 54 | return; | ||
| 55 | } | ||
| 56 | |||
| 57 | if (cubeb_stream_stop(stream_backend) != CUBEB_OK) { | ||
| 58 | LOG_CRITICAL(Audio_Sink, "Error stopping cubeb stream"); | ||
| 59 | } | ||
| 60 | |||
| 61 | cubeb_stream_destroy(stream_backend); | ||
| 62 | } | ||
| 63 | |||
| 64 | void EnqueueSamples(u32 num_channels, const std::vector<s16>& samples) override { | ||
| 65 | if (!ctx) { | ||
| 66 | return; | ||
| 67 | } | ||
| 68 | |||
| 69 | queue.reserve(queue.size() + samples.size() * GetNumChannels()); | ||
| 70 | |||
| 71 | if (is_6_channel) { | ||
| 72 | // Downsample 6 channels to 2 | ||
| 73 | const size_t sample_count_copy_size = samples.size() * 2; | ||
| 74 | queue.reserve(sample_count_copy_size); | ||
| 75 | for (size_t i = 0; i < samples.size(); i += num_channels) { | ||
| 76 | queue.push_back(samples[i]); | ||
| 77 | queue.push_back(samples[i + 1]); | ||
| 78 | } | ||
| 79 | } else { | ||
| 80 | // Copy as-is | ||
| 81 | std::copy(samples.begin(), samples.end(), std::back_inserter(queue)); | ||
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 85 | u32 GetNumChannels() const { | ||
| 86 | return num_channels; | ||
| 87 | } | ||
| 88 | |||
| 89 | private: | ||
| 90 | std::vector<std::string> device_list; | ||
| 91 | |||
| 92 | cubeb* ctx{}; | ||
| 93 | cubeb_stream* stream_backend{}; | ||
| 94 | u32 num_channels{}; | ||
| 95 | bool is_6_channel{}; | ||
| 96 | |||
| 97 | std::vector<s16> queue; | ||
| 98 | |||
| 99 | static long DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer, | ||
| 100 | void* output_buffer, long num_frames); | ||
| 101 | static void StateCallback(cubeb_stream* stream, void* user_data, cubeb_state state); | ||
| 102 | }; | ||
| 103 | |||
| 104 | CubebSink::CubebSink(std::string target_device_name) { | ||
| 105 | if (cubeb_init(&ctx, "yuzu", nullptr) != CUBEB_OK) { | ||
| 106 | LOG_CRITICAL(Audio_Sink, "cubeb_init failed"); | ||
| 107 | return; | ||
| 108 | } | ||
| 109 | |||
| 110 | if (target_device_name != auto_device_name && !target_device_name.empty()) { | ||
| 111 | cubeb_device_collection collection; | ||
| 112 | if (cubeb_enumerate_devices(ctx, CUBEB_DEVICE_TYPE_OUTPUT, &collection) != CUBEB_OK) { | ||
| 113 | LOG_WARNING(Audio_Sink, "Audio output device enumeration not supported"); | ||
| 114 | } else { | ||
| 115 | const auto collection_end{collection.device + collection.count}; | ||
| 116 | const auto device{std::find_if(collection.device, collection_end, | ||
| 117 | [&](const cubeb_device_info& device) { | ||
| 118 | return target_device_name == device.friendly_name; | ||
| 119 | })}; | ||
| 120 | if (device != collection_end) { | ||
| 121 | output_device = device->devid; | ||
| 122 | } | ||
| 123 | cubeb_device_collection_destroy(ctx, &collection); | ||
| 124 | } | ||
| 125 | } | ||
| 126 | } | ||
| 127 | |||
| 128 | CubebSink::~CubebSink() { | ||
| 129 | if (!ctx) { | ||
| 130 | return; | ||
| 131 | } | ||
| 132 | |||
| 133 | for (auto& sink_stream : sink_streams) { | ||
| 134 | sink_stream.reset(); | ||
| 135 | } | ||
| 136 | |||
| 137 | cubeb_destroy(ctx); | ||
| 138 | } | ||
| 139 | |||
| 140 | SinkStream& CubebSink::AcquireSinkStream(u32 sample_rate, u32 num_channels, | ||
| 141 | const std::string& name) { | ||
| 142 | sink_streams.push_back( | ||
| 143 | std::make_unique<SinkStreamImpl>(ctx, sample_rate, num_channels, output_device, name)); | ||
| 144 | return *sink_streams.back(); | ||
| 145 | } | ||
| 146 | |||
| 147 | long SinkStreamImpl::DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer, | ||
| 148 | void* output_buffer, long num_frames) { | ||
| 149 | SinkStreamImpl* impl = static_cast<SinkStreamImpl*>(user_data); | ||
| 150 | u8* buffer = reinterpret_cast<u8*>(output_buffer); | ||
| 151 | |||
| 152 | if (!impl) { | ||
| 153 | return {}; | ||
| 154 | } | ||
| 155 | |||
| 156 | const size_t frames_to_write{ | ||
| 157 | std::min(impl->queue.size() / impl->GetNumChannels(), static_cast<size_t>(num_frames))}; | ||
| 158 | |||
| 159 | memcpy(buffer, impl->queue.data(), frames_to_write * sizeof(s16) * impl->GetNumChannels()); | ||
| 160 | impl->queue.erase(impl->queue.begin(), | ||
| 161 | impl->queue.begin() + frames_to_write * impl->GetNumChannels()); | ||
| 162 | |||
| 163 | if (frames_to_write < num_frames) { | ||
| 164 | // Fill the rest of the frames with silence | ||
| 165 | memset(buffer + frames_to_write * sizeof(s16) * impl->GetNumChannels(), 0, | ||
| 166 | (num_frames - frames_to_write) * sizeof(s16) * impl->GetNumChannels()); | ||
| 167 | } | ||
| 168 | |||
| 169 | return num_frames; | ||
| 170 | } | ||
| 171 | |||
| 172 | void SinkStreamImpl::StateCallback(cubeb_stream* stream, void* user_data, cubeb_state state) {} | ||
| 173 | |||
| 174 | std::vector<std::string> ListCubebSinkDevices() { | ||
| 175 | std::vector<std::string> device_list; | ||
| 176 | cubeb* ctx; | ||
| 177 | |||
| 178 | if (cubeb_init(&ctx, "Citra Device Enumerator", nullptr) != CUBEB_OK) { | ||
| 179 | LOG_CRITICAL(Audio_Sink, "cubeb_init failed"); | ||
| 180 | return {}; | ||
| 181 | } | ||
| 182 | |||
| 183 | cubeb_device_collection collection; | ||
| 184 | if (cubeb_enumerate_devices(ctx, CUBEB_DEVICE_TYPE_OUTPUT, &collection) != CUBEB_OK) { | ||
| 185 | LOG_WARNING(Audio_Sink, "Audio output device enumeration not supported"); | ||
| 186 | } else { | ||
| 187 | for (size_t i = 0; i < collection.count; i++) { | ||
| 188 | const cubeb_device_info& device = collection.device[i]; | ||
| 189 | if (device.friendly_name) { | ||
| 190 | device_list.emplace_back(device.friendly_name); | ||
| 191 | } | ||
| 192 | } | ||
| 193 | cubeb_device_collection_destroy(ctx, &collection); | ||
| 194 | } | ||
| 195 | |||
| 196 | cubeb_destroy(ctx); | ||
| 197 | return device_list; | ||
| 198 | } | ||
| 199 | |||
| 200 | } // namespace AudioCore | ||
diff --git a/src/audio_core/cubeb_sink.h b/src/audio_core/cubeb_sink.h new file mode 100644 index 000000000..59cbf05e9 --- /dev/null +++ b/src/audio_core/cubeb_sink.h | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | // Copyright 2018 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <string> | ||
| 8 | #include <vector> | ||
| 9 | |||
| 10 | #include <cubeb/cubeb.h> | ||
| 11 | |||
| 12 | #include "audio_core/sink.h" | ||
| 13 | |||
| 14 | namespace AudioCore { | ||
| 15 | |||
| 16 | class CubebSink final : public Sink { | ||
| 17 | public: | ||
| 18 | explicit CubebSink(std::string device_id); | ||
| 19 | ~CubebSink() override; | ||
| 20 | |||
| 21 | SinkStream& AcquireSinkStream(u32 sample_rate, u32 num_channels, | ||
| 22 | const std::string& name) override; | ||
| 23 | |||
| 24 | private: | ||
| 25 | cubeb* ctx{}; | ||
| 26 | cubeb_devid output_device{}; | ||
| 27 | std::vector<SinkStreamPtr> sink_streams; | ||
| 28 | }; | ||
| 29 | |||
| 30 | std::vector<std::string> ListCubebSinkDevices(); | ||
| 31 | |||
| 32 | } // namespace AudioCore | ||
diff --git a/src/audio_core/null_sink.h b/src/audio_core/null_sink.h new file mode 100644 index 000000000..f235d93e5 --- /dev/null +++ b/src/audio_core/null_sink.h | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | // Copyright 2018 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "audio_core/sink.h" | ||
| 8 | |||
| 9 | namespace AudioCore { | ||
| 10 | |||
| 11 | class NullSink final : public Sink { | ||
| 12 | public: | ||
| 13 | explicit NullSink(std::string){}; | ||
| 14 | ~NullSink() override = default; | ||
| 15 | |||
| 16 | SinkStream& AcquireSinkStream(u32 /*sample_rate*/, u32 /*num_channels*/, | ||
| 17 | const std::string& /*name*/) override { | ||
| 18 | return null_sink_stream; | ||
| 19 | } | ||
| 20 | |||
| 21 | private: | ||
| 22 | struct NullSinkStreamImpl final : SinkStream { | ||
| 23 | void EnqueueSamples(u32 /*num_channels*/, const std::vector<s16>& /*samples*/) override {} | ||
| 24 | } null_sink_stream; | ||
| 25 | }; | ||
| 26 | |||
| 27 | } // namespace AudioCore | ||
diff --git a/src/audio_core/sink.h b/src/audio_core/sink.h new file mode 100644 index 000000000..95c7b2b6e --- /dev/null +++ b/src/audio_core/sink.h | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | // Copyright 2018 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | #include <string> | ||
| 9 | |||
| 10 | #include "audio_core/sink_stream.h" | ||
| 11 | #include "common/common_types.h" | ||
| 12 | |||
| 13 | namespace AudioCore { | ||
| 14 | |||
| 15 | constexpr char auto_device_name[] = "auto"; | ||
| 16 | |||
| 17 | /** | ||
| 18 | * This class is an interface for an audio sink. An audio sink accepts samples in stereo signed | ||
| 19 | * PCM16 format to be output. Sinks *do not* handle resampling and expect the correct sample rate. | ||
| 20 | * They are dumb outputs. | ||
| 21 | */ | ||
| 22 | class Sink { | ||
| 23 | public: | ||
| 24 | virtual ~Sink() = default; | ||
| 25 | virtual SinkStream& AcquireSinkStream(u32 sample_rate, u32 num_channels, | ||
| 26 | const std::string& name) = 0; | ||
| 27 | }; | ||
| 28 | |||
| 29 | using SinkPtr = std::unique_ptr<Sink>; | ||
| 30 | |||
| 31 | } // namespace AudioCore | ||
diff --git a/src/audio_core/sink_details.cpp b/src/audio_core/sink_details.cpp new file mode 100644 index 000000000..955ba20fb --- /dev/null +++ b/src/audio_core/sink_details.cpp | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | // Copyright 2018 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | #include <memory> | ||
| 7 | #include <string> | ||
| 8 | #include <vector> | ||
| 9 | #include "audio_core/null_sink.h" | ||
| 10 | #include "audio_core/sink_details.h" | ||
| 11 | #ifdef HAVE_CUBEB | ||
| 12 | #include "audio_core/cubeb_sink.h" | ||
| 13 | #endif | ||
| 14 | #include "common/logging/log.h" | ||
| 15 | |||
| 16 | namespace AudioCore { | ||
| 17 | |||
| 18 | // g_sink_details is ordered in terms of desirability, with the best choice at the top. | ||
| 19 | const std::vector<SinkDetails> g_sink_details = { | ||
| 20 | #ifdef HAVE_CUBEB | ||
| 21 | SinkDetails{"cubeb", &std::make_unique<CubebSink, std::string>, &ListCubebSinkDevices}, | ||
| 22 | #endif | ||
| 23 | SinkDetails{"null", &std::make_unique<NullSink, std::string>, | ||
| 24 | [] { return std::vector<std::string>{"null"}; }}, | ||
| 25 | }; | ||
| 26 | |||
| 27 | const SinkDetails& GetSinkDetails(std::string sink_id) { | ||
| 28 | auto iter = | ||
| 29 | std::find_if(g_sink_details.begin(), g_sink_details.end(), | ||
| 30 | [sink_id](const auto& sink_detail) { return sink_detail.id == sink_id; }); | ||
| 31 | |||
| 32 | if (sink_id == "auto" || iter == g_sink_details.end()) { | ||
| 33 | if (sink_id != "auto") { | ||
| 34 | LOG_ERROR(Audio, "AudioCore::SelectSink given invalid sink_id {}", sink_id); | ||
| 35 | } | ||
| 36 | // Auto-select. | ||
| 37 | // g_sink_details is ordered in terms of desirability, with the best choice at the front. | ||
| 38 | iter = g_sink_details.begin(); | ||
| 39 | } | ||
| 40 | |||
| 41 | return *iter; | ||
| 42 | } | ||
| 43 | |||
| 44 | } // namespace AudioCore | ||
diff --git a/src/audio_core/sink_details.h b/src/audio_core/sink_details.h new file mode 100644 index 000000000..ea666c554 --- /dev/null +++ b/src/audio_core/sink_details.h | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | // Copyright 2018 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <functional> | ||
| 8 | #include <memory> | ||
| 9 | #include <utility> | ||
| 10 | #include <vector> | ||
| 11 | |||
| 12 | namespace AudioCore { | ||
| 13 | |||
| 14 | class Sink; | ||
| 15 | |||
| 16 | struct SinkDetails { | ||
| 17 | using FactoryFn = std::function<std::unique_ptr<Sink>(std::string)>; | ||
| 18 | using ListDevicesFn = std::function<std::vector<std::string>()>; | ||
| 19 | |||
| 20 | SinkDetails(const char* id_, FactoryFn factory_, ListDevicesFn list_devices_) | ||
| 21 | : id(id_), factory(std::move(factory_)), list_devices(std::move(list_devices_)) {} | ||
| 22 | |||
| 23 | /// Name for this sink. | ||
| 24 | const char* id; | ||
| 25 | /// A method to call to construct an instance of this type of sink. | ||
| 26 | FactoryFn factory; | ||
| 27 | /// A method to call to list available devices. | ||
| 28 | ListDevicesFn list_devices; | ||
| 29 | }; | ||
| 30 | |||
| 31 | extern const std::vector<SinkDetails> g_sink_details; | ||
| 32 | |||
| 33 | const SinkDetails& GetSinkDetails(std::string sink_id); | ||
| 34 | |||
| 35 | } // namespace AudioCore | ||
diff --git a/src/audio_core/sink_stream.h b/src/audio_core/sink_stream.h new file mode 100644 index 000000000..41b6736d8 --- /dev/null +++ b/src/audio_core/sink_stream.h | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | // Copyright 2018 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | #include <vector> | ||
| 9 | |||
| 10 | #include "common/common_types.h" | ||
| 11 | |||
| 12 | namespace AudioCore { | ||
| 13 | |||
| 14 | /** | ||
| 15 | * Accepts samples in stereo signed PCM16 format to be output. Sinks *do not* handle resampling and | ||
| 16 | * expect the correct sample rate. They are dumb outputs. | ||
| 17 | */ | ||
| 18 | class SinkStream { | ||
| 19 | public: | ||
| 20 | virtual ~SinkStream() = default; | ||
| 21 | |||
| 22 | /** | ||
| 23 | * Feed stereo samples to sink. | ||
| 24 | * @param num_channels Number of channels used. | ||
| 25 | * @param samples Samples in interleaved stereo PCM16 format. | ||
| 26 | */ | ||
| 27 | virtual void EnqueueSamples(u32 num_channels, const std::vector<s16>& samples) = 0; | ||
| 28 | }; | ||
| 29 | |||
| 30 | using SinkStreamPtr = std::unique_ptr<SinkStream>; | ||
| 31 | |||
| 32 | } // namespace AudioCore | ||
diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp new file mode 100644 index 000000000..ad9e2915c --- /dev/null +++ b/src/audio_core/stream.cpp | |||
| @@ -0,0 +1,127 @@ | |||
| 1 | // Copyright 2018 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | #include <cmath> | ||
| 7 | |||
| 8 | #include "audio_core/sink.h" | ||
| 9 | #include "audio_core/sink_details.h" | ||
| 10 | #include "audio_core/stream.h" | ||
| 11 | #include "common/assert.h" | ||
| 12 | #include "common/logging/log.h" | ||
| 13 | #include "core/core_timing.h" | ||
| 14 | #include "core/core_timing_util.h" | ||
| 15 | #include "core/settings.h" | ||
| 16 | |||
| 17 | namespace AudioCore { | ||
| 18 | |||
| 19 | constexpr size_t MaxAudioBufferCount{32}; | ||
| 20 | |||
| 21 | u32 Stream::GetNumChannels() const { | ||
| 22 | switch (format) { | ||
| 23 | case Format::Mono16: | ||
| 24 | return 1; | ||
| 25 | case Format::Stereo16: | ||
| 26 | return 2; | ||
| 27 | case Format::Multi51Channel16: | ||
| 28 | return 6; | ||
| 29 | } | ||
| 30 | LOG_CRITICAL(Audio, "Unimplemented format={}", static_cast<u32>(format)); | ||
| 31 | UNREACHABLE(); | ||
| 32 | return {}; | ||
| 33 | } | ||
| 34 | |||
| 35 | Stream::Stream(u32 sample_rate, Format format, ReleaseCallback&& release_callback, | ||
| 36 | SinkStream& sink_stream, std::string&& name_) | ||
| 37 | : sample_rate{sample_rate}, format{format}, release_callback{std::move(release_callback)}, | ||
| 38 | sink_stream{sink_stream}, name{std::move(name_)} { | ||
| 39 | |||
| 40 | release_event = CoreTiming::RegisterEvent( | ||
| 41 | name, [this](u64 userdata, int cycles_late) { ReleaseActiveBuffer(); }); | ||
| 42 | } | ||
| 43 | |||
| 44 | void Stream::Play() { | ||
| 45 | state = State::Playing; | ||
| 46 | PlayNextBuffer(); | ||
| 47 | } | ||
| 48 | |||
| 49 | void Stream::Stop() { | ||
| 50 | ASSERT_MSG(false, "Unimplemented"); | ||
| 51 | } | ||
| 52 | |||
| 53 | s64 Stream::GetBufferReleaseCycles(const Buffer& buffer) const { | ||
| 54 | const size_t num_samples{buffer.GetSamples().size() / GetNumChannels()}; | ||
| 55 | return CoreTiming::usToCycles((static_cast<u64>(num_samples) * 1000000) / sample_rate); | ||
| 56 | } | ||
| 57 | |||
| 58 | static void VolumeAdjustSamples(std::vector<s16>& samples) { | ||
| 59 | const float volume{std::clamp(Settings::values.volume, 0.0f, 1.0f)}; | ||
| 60 | |||
| 61 | if (volume == 1.0f) { | ||
| 62 | return; | ||
| 63 | } | ||
| 64 | |||
| 65 | // Implementation of a volume slider with a dynamic range of 60 dB | ||
| 66 | const float volume_scale_factor{std::exp(6.90775f * volume) * 0.001f}; | ||
| 67 | for (auto& sample : samples) { | ||
| 68 | sample = static_cast<s16>(sample * volume_scale_factor); | ||
| 69 | } | ||
| 70 | } | ||
| 71 | |||
| 72 | void Stream::PlayNextBuffer() { | ||
| 73 | if (!IsPlaying()) { | ||
| 74 | // Ensure we are in playing state before playing the next buffer | ||
| 75 | return; | ||
| 76 | } | ||
| 77 | |||
| 78 | if (active_buffer) { | ||
| 79 | // Do not queue a new buffer if we are already playing a buffer | ||
| 80 | return; | ||
| 81 | } | ||
| 82 | |||
| 83 | if (queued_buffers.empty()) { | ||
| 84 | // No queued buffers - we are effectively paused | ||
| 85 | return; | ||
| 86 | } | ||
| 87 | |||
| 88 | active_buffer = queued_buffers.front(); | ||
| 89 | queued_buffers.pop(); | ||
| 90 | |||
| 91 | VolumeAdjustSamples(active_buffer->Samples()); | ||
| 92 | sink_stream.EnqueueSamples(GetNumChannels(), active_buffer->GetSamples()); | ||
| 93 | |||
| 94 | CoreTiming::ScheduleEventThreadsafe(GetBufferReleaseCycles(*active_buffer), release_event, {}); | ||
| 95 | } | ||
| 96 | |||
| 97 | void Stream::ReleaseActiveBuffer() { | ||
| 98 | ASSERT(active_buffer); | ||
| 99 | released_buffers.push(std::move(active_buffer)); | ||
| 100 | release_callback(); | ||
| 101 | PlayNextBuffer(); | ||
| 102 | } | ||
| 103 | |||
| 104 | bool Stream::QueueBuffer(BufferPtr&& buffer) { | ||
| 105 | if (queued_buffers.size() < MaxAudioBufferCount) { | ||
| 106 | queued_buffers.push(std::move(buffer)); | ||
| 107 | PlayNextBuffer(); | ||
| 108 | return true; | ||
| 109 | } | ||
| 110 | return false; | ||
| 111 | } | ||
| 112 | |||
| 113 | bool Stream::ContainsBuffer(Buffer::Tag tag) const { | ||
| 114 | ASSERT_MSG(false, "Unimplemented"); | ||
| 115 | return {}; | ||
| 116 | } | ||
| 117 | |||
| 118 | std::vector<Buffer::Tag> Stream::GetTagsAndReleaseBuffers(size_t max_count) { | ||
| 119 | std::vector<Buffer::Tag> tags; | ||
| 120 | for (size_t count = 0; count < max_count && !released_buffers.empty(); ++count) { | ||
| 121 | tags.push_back(released_buffers.front()->GetTag()); | ||
| 122 | released_buffers.pop(); | ||
| 123 | } | ||
| 124 | return tags; | ||
| 125 | } | ||
| 126 | |||
| 127 | } // namespace AudioCore | ||
diff --git a/src/audio_core/stream.h b/src/audio_core/stream.h new file mode 100644 index 000000000..049b92ca9 --- /dev/null +++ b/src/audio_core/stream.h | |||
| @@ -0,0 +1,102 @@ | |||
| 1 | // Copyright 2018 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <functional> | ||
| 8 | #include <memory> | ||
| 9 | #include <string> | ||
| 10 | #include <vector> | ||
| 11 | #include <queue> | ||
| 12 | |||
| 13 | #include "audio_core/buffer.h" | ||
| 14 | #include "audio_core/sink_stream.h" | ||
| 15 | #include "common/assert.h" | ||
| 16 | #include "common/common_types.h" | ||
| 17 | #include "core/core_timing.h" | ||
| 18 | |||
| 19 | namespace AudioCore { | ||
| 20 | |||
| 21 | /** | ||
| 22 | * Represents an audio stream, which is a sequence of queued buffers, to be outputed by AudioOut | ||
| 23 | */ | ||
| 24 | class Stream { | ||
| 25 | public: | ||
| 26 | /// Audio format of the stream | ||
| 27 | enum class Format { | ||
| 28 | Mono16, | ||
| 29 | Stereo16, | ||
| 30 | Multi51Channel16, | ||
| 31 | }; | ||
| 32 | |||
| 33 | /// Callback function type, used to change guest state on a buffer being released | ||
| 34 | using ReleaseCallback = std::function<void()>; | ||
| 35 | |||
| 36 | Stream(u32 sample_rate, Format format, ReleaseCallback&& release_callback, | ||
| 37 | SinkStream& sink_stream, std::string&& name_); | ||
| 38 | |||
| 39 | /// Plays the audio stream | ||
| 40 | void Play(); | ||
| 41 | |||
| 42 | /// Stops the audio stream | ||
| 43 | void Stop(); | ||
| 44 | |||
| 45 | /// Queues a buffer into the audio stream, returns true on success | ||
| 46 | bool QueueBuffer(BufferPtr&& buffer); | ||
| 47 | |||
| 48 | /// Returns true if the audio stream contains a buffer with the specified tag | ||
| 49 | bool ContainsBuffer(Buffer::Tag tag) const; | ||
| 50 | |||
| 51 | /// Returns a vector of recently released buffers specified by tag | ||
| 52 | std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(size_t max_count); | ||
| 53 | |||
| 54 | /// Returns true if the stream is currently playing | ||
| 55 | bool IsPlaying() const { | ||
| 56 | return state == State::Playing; | ||
| 57 | } | ||
| 58 | |||
| 59 | /// Returns the number of queued buffers | ||
| 60 | size_t GetQueueSize() const { | ||
| 61 | return queued_buffers.size(); | ||
| 62 | } | ||
| 63 | |||
| 64 | /// Gets the sample rate | ||
| 65 | u32 GetSampleRate() const { | ||
| 66 | return sample_rate; | ||
| 67 | } | ||
| 68 | |||
| 69 | /// Gets the number of channels | ||
| 70 | u32 GetNumChannels() const; | ||
| 71 | |||
| 72 | private: | ||
| 73 | /// Current state of the stream | ||
| 74 | enum class State { | ||
| 75 | Stopped, | ||
| 76 | Playing, | ||
| 77 | }; | ||
| 78 | |||
| 79 | /// Plays the next queued buffer in the audio stream, starting playback if necessary | ||
| 80 | void PlayNextBuffer(); | ||
| 81 | |||
| 82 | /// Releases the actively playing buffer, signalling that it has been completed | ||
| 83 | void ReleaseActiveBuffer(); | ||
| 84 | |||
| 85 | /// Gets the number of core cycles when the specified buffer will be released | ||
| 86 | s64 GetBufferReleaseCycles(const Buffer& buffer) const; | ||
| 87 | |||
| 88 | u32 sample_rate; ///< Sample rate of the stream | ||
| 89 | Format format; ///< Format of the stream | ||
| 90 | ReleaseCallback release_callback; ///< Buffer release callback for the stream | ||
| 91 | State state{State::Stopped}; ///< Playback state of the stream | ||
| 92 | CoreTiming::EventType* release_event{}; ///< Core timing release event for the stream | ||
| 93 | BufferPtr active_buffer; ///< Actively playing buffer in the stream | ||
| 94 | std::queue<BufferPtr> queued_buffers; ///< Buffers queued to be played in the stream | ||
| 95 | std::queue<BufferPtr> released_buffers; ///< Buffers recently released from the stream | ||
| 96 | SinkStream& sink_stream; ///< Output sink for the stream | ||
| 97 | std::string name; ///< Name of the stream, must be unique | ||
| 98 | }; | ||
| 99 | |||
| 100 | using StreamPtr = std::shared_ptr<Stream>; | ||
| 101 | |||
| 102 | } // namespace AudioCore | ||
diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h index 93f1c0044..8b0d34da6 100644 --- a/src/common/common_funcs.h +++ b/src/common/common_funcs.h | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include <string> | 7 | #include <string> |
| 8 | 8 | ||
| 9 | #if !defined(ARCHITECTURE_x86_64) && !defined(ARCHITECTURE_ARM) | 9 | #if !defined(ARCHITECTURE_x86_64) |
| 10 | #include <cstdlib> // for exit | 10 | #include <cstdlib> // for exit |
| 11 | #endif | 11 | #endif |
| 12 | #include "common/common_types.h" | 12 | #include "common/common_types.h" |
| @@ -32,8 +32,6 @@ | |||
| 32 | 32 | ||
| 33 | #ifdef ARCHITECTURE_x86_64 | 33 | #ifdef ARCHITECTURE_x86_64 |
| 34 | #define Crash() __asm__ __volatile__("int $3") | 34 | #define Crash() __asm__ __volatile__("int $3") |
| 35 | #elif defined(ARCHITECTURE_ARM) | ||
| 36 | #define Crash() __asm__ __volatile__("trap") | ||
| 37 | #else | 35 | #else |
| 38 | #define Crash() exit(1) | 36 | #define Crash() exit(1) |
| 39 | #endif | 37 | #endif |
diff --git a/src/common/common_paths.h b/src/common/common_paths.h index 6799a357a..df2ce80b1 100644 --- a/src/common/common_paths.h +++ b/src/common/common_paths.h | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #define SDMC_DIR "sdmc" | 32 | #define SDMC_DIR "sdmc" |
| 33 | #define NAND_DIR "nand" | 33 | #define NAND_DIR "nand" |
| 34 | #define SYSDATA_DIR "sysdata" | 34 | #define SYSDATA_DIR "sysdata" |
| 35 | #define KEYS_DIR "keys" | ||
| 35 | #define LOG_DIR "log" | 36 | #define LOG_DIR "log" |
| 36 | 37 | ||
| 37 | // Filenames | 38 | // Filenames |
diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index b8dd92b65..7aeda737f 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp | |||
| @@ -706,6 +706,7 @@ const std::string& GetUserPath(UserPath path, const std::string& new_path) { | |||
| 706 | paths.emplace(UserPath::SDMCDir, user_path + SDMC_DIR DIR_SEP); | 706 | paths.emplace(UserPath::SDMCDir, user_path + SDMC_DIR DIR_SEP); |
| 707 | paths.emplace(UserPath::NANDDir, user_path + NAND_DIR DIR_SEP); | 707 | paths.emplace(UserPath::NANDDir, user_path + NAND_DIR DIR_SEP); |
| 708 | paths.emplace(UserPath::SysDataDir, user_path + SYSDATA_DIR DIR_SEP); | 708 | paths.emplace(UserPath::SysDataDir, user_path + SYSDATA_DIR DIR_SEP); |
| 709 | paths.emplace(UserPath::KeysDir, user_path + KEYS_DIR DIR_SEP); | ||
| 709 | // TODO: Put the logs in a better location for each OS | 710 | // TODO: Put the logs in a better location for each OS |
| 710 | paths.emplace(UserPath::LogDir, user_path + LOG_DIR DIR_SEP); | 711 | paths.emplace(UserPath::LogDir, user_path + LOG_DIR DIR_SEP); |
| 711 | } | 712 | } |
| @@ -736,6 +737,19 @@ const std::string& GetUserPath(UserPath path, const std::string& new_path) { | |||
| 736 | return paths[path]; | 737 | return paths[path]; |
| 737 | } | 738 | } |
| 738 | 739 | ||
| 740 | std::string GetHactoolConfigurationPath() { | ||
| 741 | #ifdef _WIN32 | ||
| 742 | PWSTR pw_local_path = nullptr; | ||
| 743 | if (SHGetKnownFolderPath(FOLDERID_Profile, 0, nullptr, &pw_local_path) != S_OK) | ||
| 744 | return ""; | ||
| 745 | std::string local_path = Common::UTF16ToUTF8(pw_local_path); | ||
| 746 | CoTaskMemFree(pw_local_path); | ||
| 747 | return local_path + "\\.switch"; | ||
| 748 | #else | ||
| 749 | return GetHomeDirectory() + "/.switch"; | ||
| 750 | #endif | ||
| 751 | } | ||
| 752 | |||
| 739 | size_t WriteStringToFile(bool text_file, const std::string& str, const char* filename) { | 753 | size_t WriteStringToFile(bool text_file, const std::string& str, const char* filename) { |
| 740 | return FileUtil::IOFile(filename, text_file ? "w" : "wb").WriteBytes(str.data(), str.size()); | 754 | return FileUtil::IOFile(filename, text_file ? "w" : "wb").WriteBytes(str.data(), str.size()); |
| 741 | } | 755 | } |
diff --git a/src/common/file_util.h b/src/common/file_util.h index bc9272d89..28697d527 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h | |||
| @@ -23,6 +23,7 @@ namespace FileUtil { | |||
| 23 | enum class UserPath { | 23 | enum class UserPath { |
| 24 | CacheDir, | 24 | CacheDir, |
| 25 | ConfigDir, | 25 | ConfigDir, |
| 26 | KeysDir, | ||
| 26 | LogDir, | 27 | LogDir, |
| 27 | NANDDir, | 28 | NANDDir, |
| 28 | RootDir, | 29 | RootDir, |
| @@ -125,6 +126,8 @@ bool SetCurrentDir(const std::string& directory); | |||
| 125 | // directory. To be used in "multi-user" mode (that is, installed). | 126 | // directory. To be used in "multi-user" mode (that is, installed). |
| 126 | const std::string& GetUserPath(UserPath path, const std::string& new_path = ""); | 127 | const std::string& GetUserPath(UserPath path, const std::string& new_path = ""); |
| 127 | 128 | ||
| 129 | std::string GetHactoolConfigurationPath(); | ||
| 130 | |||
| 128 | // Returns the path to where the sys file are | 131 | // Returns the path to where the sys file are |
| 129 | std::string GetSysDirectory(); | 132 | std::string GetSysDirectory(); |
| 130 | 133 | ||
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index ad9edbcdf..355abd682 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp | |||
| @@ -168,26 +168,41 @@ void FileBackend::Write(const Entry& entry) { | |||
| 168 | SUB(Service, AM) \ | 168 | SUB(Service, AM) \ |
| 169 | SUB(Service, AOC) \ | 169 | SUB(Service, AOC) \ |
| 170 | SUB(Service, APM) \ | 170 | SUB(Service, APM) \ |
| 171 | SUB(Service, ARP) \ | ||
| 171 | SUB(Service, BCAT) \ | 172 | SUB(Service, BCAT) \ |
| 173 | SUB(Service, BPC) \ | ||
| 174 | SUB(Service, BTM) \ | ||
| 175 | SUB(Service, Capture) \ | ||
| 172 | SUB(Service, Fatal) \ | 176 | SUB(Service, Fatal) \ |
| 177 | SUB(Service, FGM) \ | ||
| 173 | SUB(Service, Friend) \ | 178 | SUB(Service, Friend) \ |
| 174 | SUB(Service, FS) \ | 179 | SUB(Service, FS) \ |
| 175 | SUB(Service, HID) \ | 180 | SUB(Service, HID) \ |
| 181 | SUB(Service, LBL) \ | ||
| 176 | SUB(Service, LDN) \ | 182 | SUB(Service, LDN) \ |
| 177 | SUB(Service, LM) \ | 183 | SUB(Service, LM) \ |
| 184 | SUB(Service, Migration) \ | ||
| 185 | SUB(Service, Mii) \ | ||
| 178 | SUB(Service, MM) \ | 186 | SUB(Service, MM) \ |
| 187 | SUB(Service, NCM) \ | ||
| 188 | SUB(Service, NFC) \ | ||
| 179 | SUB(Service, NFP) \ | 189 | SUB(Service, NFP) \ |
| 180 | SUB(Service, NIFM) \ | 190 | SUB(Service, NIFM) \ |
| 181 | SUB(Service, NS) \ | 191 | SUB(Service, NS) \ |
| 182 | SUB(Service, NVDRV) \ | 192 | SUB(Service, NVDRV) \ |
| 193 | SUB(Service, PCIE) \ | ||
| 183 | SUB(Service, PCTL) \ | 194 | SUB(Service, PCTL) \ |
| 195 | SUB(Service, PCV) \ | ||
| 184 | SUB(Service, PREPO) \ | 196 | SUB(Service, PREPO) \ |
| 197 | SUB(Service, PSC) \ | ||
| 185 | SUB(Service, SET) \ | 198 | SUB(Service, SET) \ |
| 186 | SUB(Service, SM) \ | 199 | SUB(Service, SM) \ |
| 187 | SUB(Service, SPL) \ | 200 | SUB(Service, SPL) \ |
| 188 | SUB(Service, SSL) \ | 201 | SUB(Service, SSL) \ |
| 189 | SUB(Service, Time) \ | 202 | SUB(Service, Time) \ |
| 203 | SUB(Service, USB) \ | ||
| 190 | SUB(Service, VI) \ | 204 | SUB(Service, VI) \ |
| 205 | SUB(Service, WLAN) \ | ||
| 191 | CLS(HW) \ | 206 | CLS(HW) \ |
| 192 | SUB(HW, Memory) \ | 207 | SUB(HW, Memory) \ |
| 193 | SUB(HW, LCD) \ | 208 | SUB(HW, LCD) \ |
| @@ -204,6 +219,7 @@ void FileBackend::Write(const Entry& entry) { | |||
| 204 | CLS(Input) \ | 219 | CLS(Input) \ |
| 205 | CLS(Network) \ | 220 | CLS(Network) \ |
| 206 | CLS(Loader) \ | 221 | CLS(Loader) \ |
| 222 | CLS(Crypto) \ | ||
| 207 | CLS(WebService) | 223 | CLS(WebService) |
| 208 | 224 | ||
| 209 | // GetClassName is a macro defined by Windows.h, grrr... | 225 | // GetClassName is a macro defined by Windows.h, grrr... |
diff --git a/src/common/logging/log.h b/src/common/logging/log.h index ad3cbf5d1..a889ebefa 100644 --- a/src/common/logging/log.h +++ b/src/common/logging/log.h | |||
| @@ -54,27 +54,42 @@ enum class Class : ClassType { | |||
| 54 | Service_AM, ///< The AM (Applet manager) service | 54 | Service_AM, ///< The AM (Applet manager) service |
| 55 | Service_AOC, ///< The AOC (AddOn Content) service | 55 | Service_AOC, ///< The AOC (AddOn Content) service |
| 56 | Service_APM, ///< The APM (Performance) service | 56 | Service_APM, ///< The APM (Performance) service |
| 57 | Service_ARP, ///< The ARP service | ||
| 57 | Service_Audio, ///< The Audio (Audio control) service | 58 | Service_Audio, ///< The Audio (Audio control) service |
| 58 | Service_BCAT, ///< The BCAT service | 59 | Service_BCAT, ///< The BCAT service |
| 60 | Service_BPC, ///< The BPC service | ||
| 61 | Service_BTM, ///< The BTM service | ||
| 62 | Service_Capture, ///< The capture service | ||
| 59 | Service_Fatal, ///< The Fatal service | 63 | Service_Fatal, ///< The Fatal service |
| 64 | Service_FGM, ///< The FGM service | ||
| 60 | Service_Friend, ///< The friend service | 65 | Service_Friend, ///< The friend service |
| 61 | Service_FS, ///< The FS (Filesystem) service | 66 | Service_FS, ///< The FS (Filesystem) service |
| 62 | Service_HID, ///< The HID (Human interface device) service | 67 | Service_HID, ///< The HID (Human interface device) service |
| 68 | Service_LBL, ///< The LBL (LCD backlight) service | ||
| 63 | Service_LDN, ///< The LDN (Local domain network) service | 69 | Service_LDN, ///< The LDN (Local domain network) service |
| 64 | Service_LM, ///< The LM (Logger) service | 70 | Service_LM, ///< The LM (Logger) service |
| 71 | Service_Migration, ///< The migration service | ||
| 72 | Service_Mii, ///< The Mii service | ||
| 65 | Service_MM, ///< The MM (Multimedia) service | 73 | Service_MM, ///< The MM (Multimedia) service |
| 74 | Service_NCM, ///< The NCM service | ||
| 75 | Service_NFC, ///< The NFC (Near-field communication) service | ||
| 66 | Service_NFP, ///< The NFP service | 76 | Service_NFP, ///< The NFP service |
| 67 | Service_NIFM, ///< The NIFM (Network interface) service | 77 | Service_NIFM, ///< The NIFM (Network interface) service |
| 68 | Service_NS, ///< The NS services | 78 | Service_NS, ///< The NS services |
| 69 | Service_NVDRV, ///< The NVDRV (Nvidia driver) service | 79 | Service_NVDRV, ///< The NVDRV (Nvidia driver) service |
| 80 | Service_PCIE, ///< The PCIe service | ||
| 70 | Service_PCTL, ///< The PCTL (Parental control) service | 81 | Service_PCTL, ///< The PCTL (Parental control) service |
| 82 | Service_PCV, ///< The PCV service | ||
| 71 | Service_PREPO, ///< The PREPO (Play report) service | 83 | Service_PREPO, ///< The PREPO (Play report) service |
| 84 | Service_PSC, ///< The PSC service | ||
| 72 | Service_SET, ///< The SET (Settings) service | 85 | Service_SET, ///< The SET (Settings) service |
| 73 | Service_SM, ///< The SM (Service manager) service | 86 | Service_SM, ///< The SM (Service manager) service |
| 74 | Service_SPL, ///< The SPL service | 87 | Service_SPL, ///< The SPL service |
| 75 | Service_SSL, ///< The SSL service | 88 | Service_SSL, ///< The SSL service |
| 76 | Service_Time, ///< The time service | 89 | Service_Time, ///< The time service |
| 90 | Service_USB, ///< The USB (Universal Serial Bus) service | ||
| 77 | Service_VI, ///< The VI (Video interface) service | 91 | Service_VI, ///< The VI (Video interface) service |
| 92 | Service_WLAN, ///< The WLAN (Wireless local area network) service | ||
| 78 | HW, ///< Low-level hardware emulation | 93 | HW, ///< Low-level hardware emulation |
| 79 | HW_Memory, ///< Memory-map and address translation | 94 | HW_Memory, ///< Memory-map and address translation |
| 80 | HW_LCD, ///< LCD register emulation | 95 | HW_LCD, ///< LCD register emulation |
| @@ -89,6 +104,7 @@ enum class Class : ClassType { | |||
| 89 | Audio_DSP, ///< The HLE implementation of the DSP | 104 | Audio_DSP, ///< The HLE implementation of the DSP |
| 90 | Audio_Sink, ///< Emulator audio output backend | 105 | Audio_Sink, ///< Emulator audio output backend |
| 91 | Loader, ///< ROM loader | 106 | Loader, ///< ROM loader |
| 107 | Crypto, ///< Cryptographic engine/functions | ||
| 92 | Input, ///< Input emulation | 108 | Input, ///< Input emulation |
| 93 | Network, ///< Network emulation | 109 | Network, ///< Network emulation |
| 94 | WebService, ///< Interface to yuzu Web Services | 110 | WebService, ///< Interface to yuzu Web Services |
diff --git a/src/common/logging/text_formatter.h b/src/common/logging/text_formatter.h index c587faefb..9609cec7c 100644 --- a/src/common/logging/text_formatter.h +++ b/src/common/logging/text_formatter.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <cstddef> | 7 | #include <cstddef> |
| 8 | #include <string> | ||
| 8 | 9 | ||
| 9 | namespace Log { | 10 | namespace Log { |
| 10 | 11 | ||
diff --git a/src/common/math_util.h b/src/common/math_util.h index c6a83c953..343cdd902 100644 --- a/src/common/math_util.h +++ b/src/common/math_util.h | |||
| @@ -19,12 +19,12 @@ inline bool IntervalsIntersect(unsigned start0, unsigned length0, unsigned start | |||
| 19 | 19 | ||
| 20 | template <class T> | 20 | template <class T> |
| 21 | struct Rectangle { | 21 | struct Rectangle { |
| 22 | T left; | 22 | T left{}; |
| 23 | T top; | 23 | T top{}; |
| 24 | T right; | 24 | T right{}; |
| 25 | T bottom; | 25 | T bottom{}; |
| 26 | 26 | ||
| 27 | Rectangle() {} | 27 | Rectangle() = default; |
| 28 | 28 | ||
| 29 | Rectangle(T left, T top, T right, T bottom) | 29 | Rectangle(T left, T top, T right, T bottom) |
| 30 | : left(left), top(top), right(right), bottom(bottom) {} | 30 | : left(left), top(top), right(right), bottom(bottom) {} |
diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp index 1f0456aee..0ca663032 100644 --- a/src/common/string_util.cpp +++ b/src/common/string_util.cpp | |||
| @@ -2,12 +2,12 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <algorithm> | ||
| 5 | #include <cctype> | 6 | #include <cctype> |
| 6 | #include <cerrno> | 7 | #include <cerrno> |
| 7 | #include <cstdio> | 8 | #include <cstdio> |
| 8 | #include <cstdlib> | 9 | #include <cstdlib> |
| 9 | #include <cstring> | 10 | #include <cstring> |
| 10 | #include <boost/range/algorithm/transform.hpp> | ||
| 11 | #include "common/common_paths.h" | 11 | #include "common/common_paths.h" |
| 12 | #include "common/logging/log.h" | 12 | #include "common/logging/log.h" |
| 13 | #include "common/string_util.h" | 13 | #include "common/string_util.h" |
| @@ -24,13 +24,15 @@ namespace Common { | |||
| 24 | 24 | ||
| 25 | /// Make a string lowercase | 25 | /// Make a string lowercase |
| 26 | std::string ToLower(std::string str) { | 26 | std::string ToLower(std::string str) { |
| 27 | boost::transform(str, str.begin(), ::tolower); | 27 | std::transform(str.begin(), str.end(), str.begin(), |
| 28 | [](unsigned char c) { return std::tolower(c); }); | ||
| 28 | return str; | 29 | return str; |
| 29 | } | 30 | } |
| 30 | 31 | ||
| 31 | /// Make a string uppercase | 32 | /// Make a string uppercase |
| 32 | std::string ToUpper(std::string str) { | 33 | std::string ToUpper(std::string str) { |
| 33 | boost::transform(str, str.begin(), ::toupper); | 34 | std::transform(str.begin(), str.end(), str.begin(), |
| 35 | [](unsigned char c) { return std::toupper(c); }); | ||
| 34 | return str; | 36 | return str; |
| 35 | } | 37 | } |
| 36 | 38 | ||
diff --git a/src/common/swap.h b/src/common/swap.h index fc7af4280..32af0b6ac 100644 --- a/src/common/swap.h +++ b/src/common/swap.h | |||
| @@ -69,7 +69,7 @@ inline u32 swap32(u32 _data) { | |||
| 69 | inline u64 swap64(u64 _data) { | 69 | inline u64 swap64(u64 _data) { |
| 70 | return _byteswap_uint64(_data); | 70 | return _byteswap_uint64(_data); |
| 71 | } | 71 | } |
| 72 | #elif ARCHITECTURE_ARM | 72 | #elif defined(ARCHITECTURE_ARM) && (__ARM_ARCH >= 6) |
| 73 | inline u16 swap16(u16 _data) { | 73 | inline u16 swap16(u16 _data) { |
| 74 | u32 data = _data; | 74 | u32 data = _data; |
| 75 | __asm__("rev16 %0, %1\n" : "=l"(data) : "l"(data)); | 75 | __asm__("rev16 %0, %1\n" : "=l"(data) : "l"(data)); |
diff --git a/src/common/threadsafe_queue.h b/src/common/threadsafe_queue.h index a0c731e8c..edf13bc49 100644 --- a/src/common/threadsafe_queue.h +++ b/src/common/threadsafe_queue.h | |||
| @@ -33,9 +33,11 @@ public: | |||
| 33 | bool Empty() const { | 33 | bool Empty() const { |
| 34 | return !read_ptr->next.load(); | 34 | return !read_ptr->next.load(); |
| 35 | } | 35 | } |
| 36 | |||
| 36 | T& Front() const { | 37 | T& Front() const { |
| 37 | return read_ptr->current; | 38 | return read_ptr->current; |
| 38 | } | 39 | } |
| 40 | |||
| 39 | template <typename Arg> | 41 | template <typename Arg> |
| 40 | void Push(Arg&& t) { | 42 | void Push(Arg&& t) { |
| 41 | // create the element, add it to the queue | 43 | // create the element, add it to the queue |
| @@ -108,15 +110,41 @@ private: | |||
| 108 | // single reader, multiple writer queue | 110 | // single reader, multiple writer queue |
| 109 | 111 | ||
| 110 | template <typename T, bool NeedSize = true> | 112 | template <typename T, bool NeedSize = true> |
| 111 | class MPSCQueue : public SPSCQueue<T, NeedSize> { | 113 | class MPSCQueue { |
| 112 | public: | 114 | public: |
| 115 | u32 Size() const { | ||
| 116 | return spsc_queue.Size(); | ||
| 117 | } | ||
| 118 | |||
| 119 | bool Empty() const { | ||
| 120 | return spsc_queue.Empty(); | ||
| 121 | } | ||
| 122 | |||
| 123 | T& Front() const { | ||
| 124 | return spsc_queue.Front(); | ||
| 125 | } | ||
| 126 | |||
| 113 | template <typename Arg> | 127 | template <typename Arg> |
| 114 | void Push(Arg&& t) { | 128 | void Push(Arg&& t) { |
| 115 | std::lock_guard<std::mutex> lock(write_lock); | 129 | std::lock_guard<std::mutex> lock(write_lock); |
| 116 | SPSCQueue<T, NeedSize>::Push(t); | 130 | spsc_queue.Push(t); |
| 131 | } | ||
| 132 | |||
| 133 | void Pop() { | ||
| 134 | return spsc_queue.Pop(); | ||
| 135 | } | ||
| 136 | |||
| 137 | bool Pop(T& t) { | ||
| 138 | return spsc_queue.Pop(t); | ||
| 139 | } | ||
| 140 | |||
| 141 | // not thread-safe | ||
| 142 | void Clear() { | ||
| 143 | spsc_queue.Clear(); | ||
| 117 | } | 144 | } |
| 118 | 145 | ||
| 119 | private: | 146 | private: |
| 147 | SPSCQueue<T, NeedSize> spsc_queue; | ||
| 120 | std::mutex write_lock; | 148 | std::mutex write_lock; |
| 121 | }; | 149 | }; |
| 122 | } // namespace Common | 150 | } // namespace Common |
diff --git a/src/common/timer.cpp b/src/common/timer.cpp index f0c5b1a43..2dc15e434 100644 --- a/src/common/timer.cpp +++ b/src/common/timer.cpp | |||
| @@ -3,31 +3,16 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <ctime> | 5 | #include <ctime> |
| 6 | |||
| 7 | #include <fmt/format.h> | 6 | #include <fmt/format.h> |
| 8 | |||
| 9 | #ifdef _WIN32 | ||
| 10 | #include <windows.h> | ||
| 11 | // windows.h needs to be included before other windows headers | ||
| 12 | #include <mmsystem.h> | ||
| 13 | #include <sys/timeb.h> | ||
| 14 | #else | ||
| 15 | #include <sys/time.h> | ||
| 16 | #endif | ||
| 17 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 18 | #include "common/string_util.h" | 8 | #include "common/string_util.h" |
| 19 | #include "common/timer.h" | 9 | #include "common/timer.h" |
| 20 | 10 | ||
| 21 | namespace Common { | 11 | namespace Common { |
| 22 | 12 | ||
| 23 | u32 Timer::GetTimeMs() { | 13 | std::chrono::milliseconds Timer::GetTimeMs() { |
| 24 | #ifdef _WIN32 | 14 | return std::chrono::duration_cast<std::chrono::milliseconds>( |
| 25 | return timeGetTime(); | 15 | std::chrono::system_clock::now().time_since_epoch()); |
| 26 | #else | ||
| 27 | struct timeval t; | ||
| 28 | (void)gettimeofday(&t, nullptr); | ||
| 29 | return ((u32)(t.tv_sec * 1000 + t.tv_usec / 1000)); | ||
| 30 | #endif | ||
| 31 | } | 16 | } |
| 32 | 17 | ||
| 33 | // -------------------------------------------- | 18 | // -------------------------------------------- |
| @@ -63,7 +48,7 @@ void Timer::Update() { | |||
| 63 | // ------------------------------------- | 48 | // ------------------------------------- |
| 64 | 49 | ||
| 65 | // Get the number of milliseconds since the last Update() | 50 | // Get the number of milliseconds since the last Update() |
| 66 | u64 Timer::GetTimeDifference() { | 51 | std::chrono::milliseconds Timer::GetTimeDifference() { |
| 67 | return GetTimeMs() - m_LastTime; | 52 | return GetTimeMs() - m_LastTime; |
| 68 | } | 53 | } |
| 69 | 54 | ||
| @@ -74,11 +59,11 @@ void Timer::AddTimeDifference() { | |||
| 74 | } | 59 | } |
| 75 | 60 | ||
| 76 | // Get the time elapsed since the Start() | 61 | // Get the time elapsed since the Start() |
| 77 | u64 Timer::GetTimeElapsed() { | 62 | std::chrono::milliseconds Timer::GetTimeElapsed() { |
| 78 | // If we have not started yet, return 1 (because then I don't | 63 | // If we have not started yet, return 1 (because then I don't |
| 79 | // have to change the FPS calculation in CoreRerecording.cpp . | 64 | // have to change the FPS calculation in CoreRerecording.cpp . |
| 80 | if (m_StartTime == 0) | 65 | if (m_StartTime.count() == 0) |
| 81 | return 1; | 66 | return std::chrono::milliseconds(1); |
| 82 | 67 | ||
| 83 | // Return the final timer time if the timer is stopped | 68 | // Return the final timer time if the timer is stopped |
| 84 | if (!m_Running) | 69 | if (!m_Running) |
| @@ -90,49 +75,34 @@ u64 Timer::GetTimeElapsed() { | |||
| 90 | // Get the formatted time elapsed since the Start() | 75 | // Get the formatted time elapsed since the Start() |
| 91 | std::string Timer::GetTimeElapsedFormatted() const { | 76 | std::string Timer::GetTimeElapsedFormatted() const { |
| 92 | // If we have not started yet, return zero | 77 | // If we have not started yet, return zero |
| 93 | if (m_StartTime == 0) | 78 | if (m_StartTime.count() == 0) |
| 94 | return "00:00:00:000"; | 79 | return "00:00:00:000"; |
| 95 | 80 | ||
| 96 | // The number of milliseconds since the start. | 81 | // The number of milliseconds since the start. |
| 97 | // Use a different value if the timer is stopped. | 82 | // Use a different value if the timer is stopped. |
| 98 | u64 Milliseconds; | 83 | std::chrono::milliseconds Milliseconds; |
| 99 | if (m_Running) | 84 | if (m_Running) |
| 100 | Milliseconds = GetTimeMs() - m_StartTime; | 85 | Milliseconds = GetTimeMs() - m_StartTime; |
| 101 | else | 86 | else |
| 102 | Milliseconds = m_LastTime - m_StartTime; | 87 | Milliseconds = m_LastTime - m_StartTime; |
| 103 | // Seconds | 88 | // Seconds |
| 104 | u32 Seconds = (u32)(Milliseconds / 1000); | 89 | std::chrono::seconds Seconds = std::chrono::duration_cast<std::chrono::seconds>(Milliseconds); |
| 105 | // Minutes | 90 | // Minutes |
| 106 | u32 Minutes = Seconds / 60; | 91 | std::chrono::minutes Minutes = std::chrono::duration_cast<std::chrono::minutes>(Milliseconds); |
| 107 | // Hours | 92 | // Hours |
| 108 | u32 Hours = Minutes / 60; | 93 | std::chrono::hours Hours = std::chrono::duration_cast<std::chrono::hours>(Milliseconds); |
| 109 | 94 | ||
| 110 | std::string TmpStr = fmt::format("{:02}:{:02}:{:02}:{:03}", Hours, Minutes % 60, Seconds % 60, | 95 | std::string TmpStr = fmt::format("{:02}:{:02}:{:02}:{:03}", Hours.count(), Minutes.count() % 60, |
| 111 | Milliseconds % 1000); | 96 | Seconds.count() % 60, Milliseconds.count() % 1000); |
| 112 | return TmpStr; | 97 | return TmpStr; |
| 113 | } | 98 | } |
| 114 | 99 | ||
| 115 | // Get current time | ||
| 116 | void Timer::IncreaseResolution() { | ||
| 117 | #ifdef _WIN32 | ||
| 118 | timeBeginPeriod(1); | ||
| 119 | #endif | ||
| 120 | } | ||
| 121 | |||
| 122 | void Timer::RestoreResolution() { | ||
| 123 | #ifdef _WIN32 | ||
| 124 | timeEndPeriod(1); | ||
| 125 | #endif | ||
| 126 | } | ||
| 127 | |||
| 128 | // Get the number of seconds since January 1 1970 | 100 | // Get the number of seconds since January 1 1970 |
| 129 | u64 Timer::GetTimeSinceJan1970() { | 101 | std::chrono::seconds Timer::GetTimeSinceJan1970() { |
| 130 | time_t ltime; | 102 | return std::chrono::duration_cast<std::chrono::seconds>(GetTimeMs()); |
| 131 | time(<ime); | ||
| 132 | return ((u64)ltime); | ||
| 133 | } | 103 | } |
| 134 | 104 | ||
| 135 | u64 Timer::GetLocalTimeSinceJan1970() { | 105 | std::chrono::seconds Timer::GetLocalTimeSinceJan1970() { |
| 136 | time_t sysTime, tzDiff, tzDST; | 106 | time_t sysTime, tzDiff, tzDST; |
| 137 | struct tm* gmTime; | 107 | struct tm* gmTime; |
| 138 | 108 | ||
| @@ -149,7 +119,7 @@ u64 Timer::GetLocalTimeSinceJan1970() { | |||
| 149 | gmTime = gmtime(&sysTime); | 119 | gmTime = gmtime(&sysTime); |
| 150 | tzDiff = sysTime - mktime(gmTime); | 120 | tzDiff = sysTime - mktime(gmTime); |
| 151 | 121 | ||
| 152 | return (u64)(sysTime + tzDiff + tzDST); | 122 | return std::chrono::seconds(sysTime + tzDiff + tzDST); |
| 153 | } | 123 | } |
| 154 | 124 | ||
| 155 | // Return the current time formatted as Minutes:Seconds:Milliseconds | 125 | // Return the current time formatted as Minutes:Seconds:Milliseconds |
| @@ -164,30 +134,16 @@ std::string Timer::GetTimeFormatted() { | |||
| 164 | 134 | ||
| 165 | strftime(tmp, 6, "%M:%S", gmTime); | 135 | strftime(tmp, 6, "%M:%S", gmTime); |
| 166 | 136 | ||
| 167 | // Now tack on the milliseconds | 137 | u64 milliseconds = static_cast<u64>(GetTimeMs().count()) % 1000; |
| 168 | #ifdef _WIN32 | 138 | return fmt::format("{}:{:03}", tmp, milliseconds); |
| 169 | struct timeb tp; | ||
| 170 | (void)::ftime(&tp); | ||
| 171 | return fmt::format("{}:{:03}", tmp, tp.millitm); | ||
| 172 | #else | ||
| 173 | struct timeval t; | ||
| 174 | (void)gettimeofday(&t, nullptr); | ||
| 175 | return fmt::format("{}:{:03}", tmp, static_cast<int>(t.tv_usec / 1000)); | ||
| 176 | #endif | ||
| 177 | } | 139 | } |
| 178 | 140 | ||
| 179 | // Returns a timestamp with decimals for precise time comparisons | 141 | // Returns a timestamp with decimals for precise time comparisons |
| 180 | // ---------------- | 142 | // ---------------- |
| 181 | double Timer::GetDoubleTime() { | 143 | double Timer::GetDoubleTime() { |
| 182 | #ifdef _WIN32 | ||
| 183 | struct timeb tp; | ||
| 184 | (void)::ftime(&tp); | ||
| 185 | #else | ||
| 186 | struct timeval t; | ||
| 187 | (void)gettimeofday(&t, nullptr); | ||
| 188 | #endif | ||
| 189 | // Get continuous timestamp | 144 | // Get continuous timestamp |
| 190 | u64 TmpSeconds = Common::Timer::GetTimeSinceJan1970(); | 145 | u64 TmpSeconds = static_cast<u64>(Common::Timer::GetTimeSinceJan1970().count()); |
| 146 | double ms = static_cast<u64>(GetTimeMs().count()) % 1000; | ||
| 191 | 147 | ||
| 192 | // Remove a few years. We only really want enough seconds to make | 148 | // Remove a few years. We only really want enough seconds to make |
| 193 | // sure that we are detecting actual actions, perhaps 60 seconds is | 149 | // sure that we are detecting actual actions, perhaps 60 seconds is |
| @@ -196,12 +152,7 @@ double Timer::GetDoubleTime() { | |||
| 196 | TmpSeconds = TmpSeconds - (38 * 365 * 24 * 60 * 60); | 152 | TmpSeconds = TmpSeconds - (38 * 365 * 24 * 60 * 60); |
| 197 | 153 | ||
| 198 | // Make a smaller integer that fits in the double | 154 | // Make a smaller integer that fits in the double |
| 199 | u32 Seconds = (u32)TmpSeconds; | 155 | u32 Seconds = static_cast<u32>(TmpSeconds); |
| 200 | #ifdef _WIN32 | ||
| 201 | double ms = tp.millitm / 1000.0 / 1000.0; | ||
| 202 | #else | ||
| 203 | double ms = t.tv_usec / 1000000.0; | ||
| 204 | #endif | ||
| 205 | double TmpTime = Seconds + ms; | 156 | double TmpTime = Seconds + ms; |
| 206 | 157 | ||
| 207 | return TmpTime; | 158 | return TmpTime; |
diff --git a/src/common/timer.h b/src/common/timer.h index 78d37426b..27b521baa 100644 --- a/src/common/timer.h +++ b/src/common/timer.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <chrono> | ||
| 7 | #include <string> | 8 | #include <string> |
| 8 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 9 | 10 | ||
| @@ -18,24 +19,22 @@ public: | |||
| 18 | 19 | ||
| 19 | // The time difference is always returned in milliseconds, regardless of alternative internal | 20 | // The time difference is always returned in milliseconds, regardless of alternative internal |
| 20 | // representation | 21 | // representation |
| 21 | u64 GetTimeDifference(); | 22 | std::chrono::milliseconds GetTimeDifference(); |
| 22 | void AddTimeDifference(); | 23 | void AddTimeDifference(); |
| 23 | 24 | ||
| 24 | static void IncreaseResolution(); | 25 | static std::chrono::seconds GetTimeSinceJan1970(); |
| 25 | static void RestoreResolution(); | 26 | static std::chrono::seconds GetLocalTimeSinceJan1970(); |
| 26 | static u64 GetTimeSinceJan1970(); | ||
| 27 | static u64 GetLocalTimeSinceJan1970(); | ||
| 28 | static double GetDoubleTime(); | 27 | static double GetDoubleTime(); |
| 29 | 28 | ||
| 30 | static std::string GetTimeFormatted(); | 29 | static std::string GetTimeFormatted(); |
| 31 | std::string GetTimeElapsedFormatted() const; | 30 | std::string GetTimeElapsedFormatted() const; |
| 32 | u64 GetTimeElapsed(); | 31 | std::chrono::milliseconds GetTimeElapsed(); |
| 33 | 32 | ||
| 34 | static u32 GetTimeMs(); | 33 | static std::chrono::milliseconds GetTimeMs(); |
| 35 | 34 | ||
| 36 | private: | 35 | private: |
| 37 | u64 m_LastTime; | 36 | std::chrono::milliseconds m_LastTime; |
| 38 | u64 m_StartTime; | 37 | std::chrono::milliseconds m_StartTime; |
| 39 | bool m_Running; | 38 | bool m_Running; |
| 40 | }; | 39 | }; |
| 41 | 40 | ||
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index b74e495ef..0abf7edc1 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -12,6 +12,16 @@ add_library(core STATIC | |||
| 12 | core_timing.h | 12 | core_timing.h |
| 13 | core_timing_util.cpp | 13 | core_timing_util.cpp |
| 14 | core_timing_util.h | 14 | core_timing_util.h |
| 15 | crypto/aes_util.cpp | ||
| 16 | crypto/aes_util.h | ||
| 17 | crypto/encryption_layer.cpp | ||
| 18 | crypto/encryption_layer.h | ||
| 19 | crypto/key_manager.cpp | ||
| 20 | crypto/key_manager.h | ||
| 21 | crypto/ctr_encryption_layer.cpp | ||
| 22 | crypto/ctr_encryption_layer.h | ||
| 23 | file_sys/card_image.cpp | ||
| 24 | file_sys/card_image.h | ||
| 15 | file_sys/content_archive.cpp | 25 | file_sys/content_archive.cpp |
| 16 | file_sys/content_archive.h | 26 | file_sys/content_archive.h |
| 17 | file_sys/control_metadata.cpp | 27 | file_sys/control_metadata.cpp |
| @@ -23,6 +33,8 @@ add_library(core STATIC | |||
| 23 | file_sys/partition_filesystem.h | 33 | file_sys/partition_filesystem.h |
| 24 | file_sys/program_metadata.cpp | 34 | file_sys/program_metadata.cpp |
| 25 | file_sys/program_metadata.h | 35 | file_sys/program_metadata.h |
| 36 | file_sys/romfs.cpp | ||
| 37 | file_sys/romfs.h | ||
| 26 | file_sys/romfs_factory.cpp | 38 | file_sys/romfs_factory.cpp |
| 27 | file_sys/romfs_factory.h | 39 | file_sys/romfs_factory.h |
| 28 | file_sys/savedata_factory.cpp | 40 | file_sys/savedata_factory.cpp |
| @@ -35,6 +47,8 @@ add_library(core STATIC | |||
| 35 | file_sys/vfs_offset.h | 47 | file_sys/vfs_offset.h |
| 36 | file_sys/vfs_real.cpp | 48 | file_sys/vfs_real.cpp |
| 37 | file_sys/vfs_real.h | 49 | file_sys/vfs_real.h |
| 50 | file_sys/vfs_vector.cpp | ||
| 51 | file_sys/vfs_vector.h | ||
| 38 | frontend/emu_window.cpp | 52 | frontend/emu_window.cpp |
| 39 | frontend/emu_window.h | 53 | frontend/emu_window.h |
| 40 | frontend/framebuffer_layout.cpp | 54 | frontend/framebuffer_layout.cpp |
| @@ -59,12 +73,10 @@ add_library(core STATIC | |||
| 59 | hle/kernel/hle_ipc.h | 73 | hle/kernel/hle_ipc.h |
| 60 | hle/kernel/kernel.cpp | 74 | hle/kernel/kernel.cpp |
| 61 | hle/kernel/kernel.h | 75 | hle/kernel/kernel.h |
| 62 | hle/kernel/memory.cpp | ||
| 63 | hle/kernel/memory.h | ||
| 64 | hle/kernel/mutex.cpp | 76 | hle/kernel/mutex.cpp |
| 65 | hle/kernel/mutex.h | 77 | hle/kernel/mutex.h |
| 66 | hle/kernel/object_address_table.cpp | 78 | hle/kernel/object.cpp |
| 67 | hle/kernel/object_address_table.h | 79 | hle/kernel/object.h |
| 68 | hle/kernel/process.cpp | 80 | hle/kernel/process.cpp |
| 69 | hle/kernel/process.h | 81 | hle/kernel/process.h |
| 70 | hle/kernel/resource_limit.cpp | 82 | hle/kernel/resource_limit.cpp |
| @@ -110,23 +122,41 @@ add_library(core STATIC | |||
| 110 | hle/service/am/applet_ae.h | 122 | hle/service/am/applet_ae.h |
| 111 | hle/service/am/applet_oe.cpp | 123 | hle/service/am/applet_oe.cpp |
| 112 | hle/service/am/applet_oe.h | 124 | hle/service/am/applet_oe.h |
| 125 | hle/service/am/idle.cpp | ||
| 126 | hle/service/am/idle.h | ||
| 127 | hle/service/am/omm.cpp | ||
| 128 | hle/service/am/omm.h | ||
| 129 | hle/service/am/spsm.cpp | ||
| 130 | hle/service/am/spsm.h | ||
| 113 | hle/service/aoc/aoc_u.cpp | 131 | hle/service/aoc/aoc_u.cpp |
| 114 | hle/service/aoc/aoc_u.h | 132 | hle/service/aoc/aoc_u.h |
| 115 | hle/service/apm/apm.cpp | 133 | hle/service/apm/apm.cpp |
| 116 | hle/service/apm/apm.h | 134 | hle/service/apm/apm.h |
| 117 | hle/service/apm/interface.cpp | 135 | hle/service/apm/interface.cpp |
| 118 | hle/service/apm/interface.h | 136 | hle/service/apm/interface.h |
| 137 | hle/service/arp/arp.cpp | ||
| 138 | hle/service/arp/arp.h | ||
| 139 | hle/service/audio/audctl.cpp | ||
| 140 | hle/service/audio/audctl.h | ||
| 141 | hle/service/audio/auddbg.cpp | ||
| 142 | hle/service/audio/auddbg.h | ||
| 143 | hle/service/audio/audin_a.cpp | ||
| 144 | hle/service/audio/audin_a.h | ||
| 119 | hle/service/audio/audin_u.cpp | 145 | hle/service/audio/audin_u.cpp |
| 120 | hle/service/audio/audin_u.h | 146 | hle/service/audio/audin_u.h |
| 121 | hle/service/audio/audio.cpp | 147 | hle/service/audio/audio.cpp |
| 122 | hle/service/audio/audio.h | 148 | hle/service/audio/audio.h |
| 149 | hle/service/audio/audout_a.cpp | ||
| 150 | hle/service/audio/audout_a.h | ||
| 123 | hle/service/audio/audout_u.cpp | 151 | hle/service/audio/audout_u.cpp |
| 124 | hle/service/audio/audout_u.h | 152 | hle/service/audio/audout_u.h |
| 153 | hle/service/audio/audrec_a.cpp | ||
| 154 | hle/service/audio/audrec_a.h | ||
| 125 | hle/service/audio/audrec_u.cpp | 155 | hle/service/audio/audrec_u.cpp |
| 126 | hle/service/audio/audrec_u.h | 156 | hle/service/audio/audrec_u.h |
| 157 | hle/service/audio/audren_a.cpp | ||
| 158 | hle/service/audio/audren_a.h | ||
| 127 | hle/service/audio/audren_u.cpp | 159 | hle/service/audio/audren_u.cpp |
| 128 | hle/service/audio/audren_u.cpp | ||
| 129 | hle/service/audio/audren_u.h | ||
| 130 | hle/service/audio/audren_u.h | 160 | hle/service/audio/audren_u.h |
| 131 | hle/service/audio/codecctl.cpp | 161 | hle/service/audio/codecctl.cpp |
| 132 | hle/service/audio/codecctl.h | 162 | hle/service/audio/codecctl.h |
| @@ -136,6 +166,14 @@ add_library(core STATIC | |||
| 136 | hle/service/bcat/bcat.h | 166 | hle/service/bcat/bcat.h |
| 137 | hle/service/bcat/module.cpp | 167 | hle/service/bcat/module.cpp |
| 138 | hle/service/bcat/module.h | 168 | hle/service/bcat/module.h |
| 169 | hle/service/bpc/bpc.cpp | ||
| 170 | hle/service/bpc/bpc.h | ||
| 171 | hle/service/btdrv/btdrv.cpp | ||
| 172 | hle/service/btdrv/btdrv.h | ||
| 173 | hle/service/btm/btm.cpp | ||
| 174 | hle/service/btm/btm.h | ||
| 175 | hle/service/caps/caps.cpp | ||
| 176 | hle/service/caps/caps.h | ||
| 139 | hle/service/erpt/erpt.cpp | 177 | hle/service/erpt/erpt.cpp |
| 140 | hle/service/erpt/erpt.h | 178 | hle/service/erpt/erpt.h |
| 141 | hle/service/es/es.cpp | 179 | hle/service/es/es.cpp |
| @@ -150,8 +188,14 @@ add_library(core STATIC | |||
| 150 | hle/service/fatal/fatal_u.h | 188 | hle/service/fatal/fatal_u.h |
| 151 | hle/service/filesystem/filesystem.cpp | 189 | hle/service/filesystem/filesystem.cpp |
| 152 | hle/service/filesystem/filesystem.h | 190 | hle/service/filesystem/filesystem.h |
| 191 | hle/service/filesystem/fsp_ldr.cpp | ||
| 192 | hle/service/filesystem/fsp_ldr.h | ||
| 193 | hle/service/filesystem/fsp_pr.cpp | ||
| 194 | hle/service/filesystem/fsp_pr.h | ||
| 153 | hle/service/filesystem/fsp_srv.cpp | 195 | hle/service/filesystem/fsp_srv.cpp |
| 154 | hle/service/filesystem/fsp_srv.h | 196 | hle/service/filesystem/fsp_srv.h |
| 197 | hle/service/fgm/fgm.cpp | ||
| 198 | hle/service/fgm/fgm.h | ||
| 155 | hle/service/friend/friend.cpp | 199 | hle/service/friend/friend.cpp |
| 156 | hle/service/friend/friend.h | 200 | hle/service/friend/friend.h |
| 157 | hle/service/friend/interface.cpp | 201 | hle/service/friend/interface.cpp |
| @@ -164,14 +208,24 @@ add_library(core STATIC | |||
| 164 | hle/service/hid/irs.h | 208 | hle/service/hid/irs.h |
| 165 | hle/service/hid/xcd.cpp | 209 | hle/service/hid/xcd.cpp |
| 166 | hle/service/hid/xcd.h | 210 | hle/service/hid/xcd.h |
| 211 | hle/service/lbl/lbl.cpp | ||
| 212 | hle/service/lbl/lbl.h | ||
| 167 | hle/service/ldn/ldn.cpp | 213 | hle/service/ldn/ldn.cpp |
| 168 | hle/service/ldn/ldn.h | 214 | hle/service/ldn/ldn.h |
| 169 | hle/service/ldr/ldr.cpp | 215 | hle/service/ldr/ldr.cpp |
| 170 | hle/service/ldr/ldr.h | 216 | hle/service/ldr/ldr.h |
| 171 | hle/service/lm/lm.cpp | 217 | hle/service/lm/lm.cpp |
| 172 | hle/service/lm/lm.h | 218 | hle/service/lm/lm.h |
| 219 | hle/service/mig/mig.cpp | ||
| 220 | hle/service/mig/mig.h | ||
| 221 | hle/service/mii/mii.cpp | ||
| 222 | hle/service/mii/mii.h | ||
| 173 | hle/service/mm/mm_u.cpp | 223 | hle/service/mm/mm_u.cpp |
| 174 | hle/service/mm/mm_u.h | 224 | hle/service/mm/mm_u.h |
| 225 | hle/service/ncm/ncm.cpp | ||
| 226 | hle/service/ncm/ncm.h | ||
| 227 | hle/service/nfc/nfc.cpp | ||
| 228 | hle/service/nfc/nfc.h | ||
| 175 | hle/service/nfp/nfp.cpp | 229 | hle/service/nfp/nfp.cpp |
| 176 | hle/service/nfp/nfp.h | 230 | hle/service/nfp/nfp.h |
| 177 | hle/service/nfp/nfp_user.cpp | 231 | hle/service/nfp/nfp_user.cpp |
| @@ -209,14 +263,20 @@ add_library(core STATIC | |||
| 209 | hle/service/nvflinger/buffer_queue.h | 263 | hle/service/nvflinger/buffer_queue.h |
| 210 | hle/service/nvflinger/nvflinger.cpp | 264 | hle/service/nvflinger/nvflinger.cpp |
| 211 | hle/service/nvflinger/nvflinger.h | 265 | hle/service/nvflinger/nvflinger.h |
| 266 | hle/service/pcie/pcie.cpp | ||
| 267 | hle/service/pcie/pcie.h | ||
| 212 | hle/service/pctl/module.cpp | 268 | hle/service/pctl/module.cpp |
| 213 | hle/service/pctl/module.h | 269 | hle/service/pctl/module.h |
| 214 | hle/service/pctl/pctl.cpp | 270 | hle/service/pctl/pctl.cpp |
| 215 | hle/service/pctl/pctl.h | 271 | hle/service/pctl/pctl.h |
| 272 | hle/service/pcv/pcv.cpp | ||
| 273 | hle/service/pcv/pcv.h | ||
| 216 | hle/service/pm/pm.cpp | 274 | hle/service/pm/pm.cpp |
| 217 | hle/service/pm/pm.h | 275 | hle/service/pm/pm.h |
| 218 | hle/service/prepo/prepo.cpp | 276 | hle/service/prepo/prepo.cpp |
| 219 | hle/service/prepo/prepo.h | 277 | hle/service/prepo/prepo.h |
| 278 | hle/service/psc/psc.cpp | ||
| 279 | hle/service/psc/psc.h | ||
| 220 | hle/service/service.cpp | 280 | hle/service/service.cpp |
| 221 | hle/service/service.h | 281 | hle/service/service.h |
| 222 | hle/service/set/set.cpp | 282 | hle/service/set/set.cpp |
| @@ -255,6 +315,8 @@ add_library(core STATIC | |||
| 255 | hle/service/time/interface.h | 315 | hle/service/time/interface.h |
| 256 | hle/service/time/time.cpp | 316 | hle/service/time/time.cpp |
| 257 | hle/service/time/time.h | 317 | hle/service/time/time.h |
| 318 | hle/service/usb/usb.cpp | ||
| 319 | hle/service/usb/usb.h | ||
| 258 | hle/service/vi/vi.cpp | 320 | hle/service/vi/vi.cpp |
| 259 | hle/service/vi/vi.h | 321 | hle/service/vi/vi.h |
| 260 | hle/service/vi/vi_m.cpp | 322 | hle/service/vi/vi_m.cpp |
| @@ -263,10 +325,8 @@ add_library(core STATIC | |||
| 263 | hle/service/vi/vi_s.h | 325 | hle/service/vi/vi_s.h |
| 264 | hle/service/vi/vi_u.cpp | 326 | hle/service/vi/vi_u.cpp |
| 265 | hle/service/vi/vi_u.h | 327 | hle/service/vi/vi_u.h |
| 266 | hw/hw.cpp | 328 | hle/service/wlan/wlan.cpp |
| 267 | hw/hw.h | 329 | hle/service/wlan/wlan.h |
| 268 | hw/lcd.cpp | ||
| 269 | hw/lcd.h | ||
| 270 | loader/deconstructed_rom_directory.cpp | 330 | loader/deconstructed_rom_directory.cpp |
| 271 | loader/deconstructed_rom_directory.h | 331 | loader/deconstructed_rom_directory.h |
| 272 | loader/elf.cpp | 332 | loader/elf.cpp |
| @@ -281,6 +341,8 @@ add_library(core STATIC | |||
| 281 | loader/nro.h | 341 | loader/nro.h |
| 282 | loader/nso.cpp | 342 | loader/nso.cpp |
| 283 | loader/nso.h | 343 | loader/nso.h |
| 344 | loader/xci.cpp | ||
| 345 | loader/xci.h | ||
| 284 | memory.cpp | 346 | memory.cpp |
| 285 | memory.h | 347 | memory.h |
| 286 | memory_hook.cpp | 348 | memory_hook.cpp |
| @@ -299,8 +361,8 @@ add_library(core STATIC | |||
| 299 | 361 | ||
| 300 | create_target_directory_groups(core) | 362 | create_target_directory_groups(core) |
| 301 | 363 | ||
| 302 | target_link_libraries(core PUBLIC common PRIVATE video_core) | 364 | target_link_libraries(core PUBLIC common PRIVATE audio_core video_core) |
| 303 | target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt lz4_static unicorn) | 365 | target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt lz4_static mbedtls opus unicorn) |
| 304 | 366 | ||
| 305 | if (ARCHITECTURE_x86_64) | 367 | if (ARCHITECTURE_x86_64) |
| 306 | target_sources(core PRIVATE | 368 | target_sources(core PRIVATE |
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index 57b8634b9..ceb3f7683 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | #include "core/arm/dynarmic/arm_dynarmic.h" | 10 | #include "core/arm/dynarmic/arm_dynarmic.h" |
| 11 | #include "core/core.h" | 11 | #include "core/core.h" |
| 12 | #include "core/core_timing.h" | 12 | #include "core/core_timing.h" |
| 13 | #include "core/hle/kernel/memory.h" | 13 | #include "core/hle/kernel/process.h" |
| 14 | #include "core/hle/kernel/svc.h" | 14 | #include "core/hle/kernel/svc.h" |
| 15 | #include "core/memory.h" | 15 | #include "core/memory.h" |
| 16 | 16 | ||
| @@ -139,14 +139,12 @@ void ARM_Dynarmic::Step() { | |||
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | ARM_Dynarmic::ARM_Dynarmic(std::shared_ptr<ExclusiveMonitor> exclusive_monitor, size_t core_index) | 141 | ARM_Dynarmic::ARM_Dynarmic(std::shared_ptr<ExclusiveMonitor> exclusive_monitor, size_t core_index) |
| 142 | : cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), | 142 | : cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), core_index{core_index}, |
| 143 | jit(MakeJit()), exclusive_monitor{std::dynamic_pointer_cast<DynarmicExclusiveMonitor>( | 143 | exclusive_monitor{std::dynamic_pointer_cast<DynarmicExclusiveMonitor>(exclusive_monitor)} { |
| 144 | exclusive_monitor)}, | 144 | ThreadContext ctx; |
| 145 | core_index{core_index} { | ||
| 146 | ARM_Interface::ThreadContext ctx; | ||
| 147 | inner_unicorn.SaveContext(ctx); | 145 | inner_unicorn.SaveContext(ctx); |
| 148 | LoadContext(ctx); | ||
| 149 | PageTableChanged(); | 146 | PageTableChanged(); |
| 147 | LoadContext(ctx); | ||
| 150 | } | 148 | } |
| 151 | 149 | ||
| 152 | ARM_Dynarmic::~ARM_Dynarmic() = default; | 150 | ARM_Dynarmic::~ARM_Dynarmic() = default; |
| @@ -205,7 +203,7 @@ u64 ARM_Dynarmic::GetTlsAddress() const { | |||
| 205 | return cb->tpidrro_el0; | 203 | return cb->tpidrro_el0; |
| 206 | } | 204 | } |
| 207 | 205 | ||
| 208 | void ARM_Dynarmic::SetTlsAddress(u64 address) { | 206 | void ARM_Dynarmic::SetTlsAddress(VAddr address) { |
| 209 | cb->tpidrro_el0 = address; | 207 | cb->tpidrro_el0 = address; |
| 210 | } | 208 | } |
| 211 | 209 | ||
| @@ -217,7 +215,7 @@ void ARM_Dynarmic::SetTPIDR_EL0(u64 value) { | |||
| 217 | cb->tpidr_el0 = value; | 215 | cb->tpidr_el0 = value; |
| 218 | } | 216 | } |
| 219 | 217 | ||
| 220 | void ARM_Dynarmic::SaveContext(ARM_Interface::ThreadContext& ctx) { | 218 | void ARM_Dynarmic::SaveContext(ThreadContext& ctx) { |
| 221 | ctx.cpu_registers = jit->GetRegisters(); | 219 | ctx.cpu_registers = jit->GetRegisters(); |
| 222 | ctx.sp = jit->GetSP(); | 220 | ctx.sp = jit->GetSP(); |
| 223 | ctx.pc = jit->GetPC(); | 221 | ctx.pc = jit->GetPC(); |
| @@ -226,7 +224,7 @@ void ARM_Dynarmic::SaveContext(ARM_Interface::ThreadContext& ctx) { | |||
| 226 | ctx.fpscr = jit->GetFpcr(); | 224 | ctx.fpscr = jit->GetFpcr(); |
| 227 | } | 225 | } |
| 228 | 226 | ||
| 229 | void ARM_Dynarmic::LoadContext(const ARM_Interface::ThreadContext& ctx) { | 227 | void ARM_Dynarmic::LoadContext(const ThreadContext& ctx) { |
| 230 | jit->SetRegisters(ctx.cpu_registers); | 228 | jit->SetRegisters(ctx.cpu_registers); |
| 231 | jit->SetSP(ctx.sp); | 229 | jit->SetSP(ctx.sp); |
| 232 | jit->SetPC(ctx.pc); | 230 | jit->SetPC(ctx.pc); |
diff --git a/src/core/arm/unicorn/arm_unicorn.cpp b/src/core/arm/unicorn/arm_unicorn.cpp index 4c11f35a4..6bc349460 100644 --- a/src/core/arm/unicorn/arm_unicorn.cpp +++ b/src/core/arm/unicorn/arm_unicorn.cpp | |||
| @@ -203,7 +203,7 @@ void ARM_Unicorn::ExecuteInstructions(int num_instructions) { | |||
| 203 | } | 203 | } |
| 204 | Kernel::Thread* thread = Kernel::GetCurrentThread(); | 204 | Kernel::Thread* thread = Kernel::GetCurrentThread(); |
| 205 | SaveContext(thread->context); | 205 | SaveContext(thread->context); |
| 206 | if (last_bkpt_hit || (num_instructions == 1)) { | 206 | if (last_bkpt_hit || GDBStub::GetCpuStepFlag()) { |
| 207 | last_bkpt_hit = false; | 207 | last_bkpt_hit = false; |
| 208 | GDBStub::Break(); | 208 | GDBStub::Break(); |
| 209 | GDBStub::SendTrap(thread, 5); | 209 | GDBStub::SendTrap(thread, 5); |
diff --git a/src/core/core.cpp b/src/core/core.cpp index b7f4b4532..085ba68d0 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -15,11 +15,10 @@ | |||
| 15 | #include "core/hle/service/service.h" | 15 | #include "core/hle/service/service.h" |
| 16 | #include "core/hle/service/sm/controller.h" | 16 | #include "core/hle/service/sm/controller.h" |
| 17 | #include "core/hle/service/sm/sm.h" | 17 | #include "core/hle/service/sm/sm.h" |
| 18 | #include "core/hw/hw.h" | ||
| 19 | #include "core/loader/loader.h" | 18 | #include "core/loader/loader.h" |
| 20 | #include "core/memory_setup.h" | ||
| 21 | #include "core/settings.h" | 19 | #include "core/settings.h" |
| 22 | #include "file_sys/vfs_real.h" | 20 | #include "file_sys/vfs_real.h" |
| 21 | #include "video_core/renderer_base.h" | ||
| 23 | #include "video_core/video_core.h" | 22 | #include "video_core/video_core.h" |
| 24 | 23 | ||
| 25 | namespace Core { | 24 | namespace Core { |
| @@ -63,7 +62,6 @@ System::ResultStatus System::RunLoop(bool tight_loop) { | |||
| 63 | // execute. Otherwise, get out of the loop function. | 62 | // execute. Otherwise, get out of the loop function. |
| 64 | if (GDBStub::GetCpuHaltFlag()) { | 63 | if (GDBStub::GetCpuHaltFlag()) { |
| 65 | if (GDBStub::GetCpuStepFlag()) { | 64 | if (GDBStub::GetCpuStepFlag()) { |
| 66 | GDBStub::SetCpuStepFlag(false); | ||
| 67 | tight_loop = false; | 65 | tight_loop = false; |
| 68 | } else { | 66 | } else { |
| 69 | return ResultStatus::Success; | 67 | return ResultStatus::Success; |
| @@ -79,6 +77,10 @@ System::ResultStatus System::RunLoop(bool tight_loop) { | |||
| 79 | } | 77 | } |
| 80 | } | 78 | } |
| 81 | 79 | ||
| 80 | if (GDBStub::IsServerEnabled()) { | ||
| 81 | GDBStub::SetCpuStepFlag(false); | ||
| 82 | } | ||
| 83 | |||
| 82 | return status; | 84 | return status; |
| 83 | } | 85 | } |
| 84 | 86 | ||
| @@ -86,7 +88,7 @@ System::ResultStatus System::SingleStep() { | |||
| 86 | return RunLoop(false); | 88 | return RunLoop(false); |
| 87 | } | 89 | } |
| 88 | 90 | ||
| 89 | System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& filepath) { | 91 | System::ResultStatus System::Load(EmuWindow& emu_window, const std::string& filepath) { |
| 90 | app_loader = Loader::GetLoader(std::make_shared<FileSys::RealVfsFile>(filepath)); | 92 | app_loader = Loader::GetLoader(std::make_shared<FileSys::RealVfsFile>(filepath)); |
| 91 | 93 | ||
| 92 | if (!app_loader) { | 94 | if (!app_loader) { |
| @@ -101,8 +103,10 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file | |||
| 101 | static_cast<int>(system_mode.second)); | 103 | static_cast<int>(system_mode.second)); |
| 102 | 104 | ||
| 103 | switch (system_mode.second) { | 105 | switch (system_mode.second) { |
| 104 | case Loader::ResultStatus::ErrorEncrypted: | 106 | case Loader::ResultStatus::ErrorMissingKeys: |
| 105 | return ResultStatus::ErrorLoader_ErrorEncrypted; | 107 | return ResultStatus::ErrorLoader_ErrorMissingKeys; |
| 108 | case Loader::ResultStatus::ErrorDecrypting: | ||
| 109 | return ResultStatus::ErrorLoader_ErrorDecrypting; | ||
| 106 | case Loader::ResultStatus::ErrorInvalidFormat: | 110 | case Loader::ResultStatus::ErrorInvalidFormat: |
| 107 | return ResultStatus::ErrorLoader_ErrorInvalidFormat; | 111 | return ResultStatus::ErrorLoader_ErrorInvalidFormat; |
| 108 | case Loader::ResultStatus::ErrorUnsupportedArch: | 112 | case Loader::ResultStatus::ErrorUnsupportedArch: |
| @@ -112,7 +116,7 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file | |||
| 112 | } | 116 | } |
| 113 | } | 117 | } |
| 114 | 118 | ||
| 115 | ResultStatus init_result{Init(emu_window, system_mode.first.get())}; | 119 | ResultStatus init_result{Init(emu_window)}; |
| 116 | if (init_result != ResultStatus::Success) { | 120 | if (init_result != ResultStatus::Success) { |
| 117 | LOG_CRITICAL(Core, "Failed to initialize system (Error {})!", | 121 | LOG_CRITICAL(Core, "Failed to initialize system (Error {})!", |
| 118 | static_cast<int>(init_result)); | 122 | static_cast<int>(init_result)); |
| @@ -126,8 +130,10 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file | |||
| 126 | System::Shutdown(); | 130 | System::Shutdown(); |
| 127 | 131 | ||
| 128 | switch (load_result) { | 132 | switch (load_result) { |
| 129 | case Loader::ResultStatus::ErrorEncrypted: | 133 | case Loader::ResultStatus::ErrorMissingKeys: |
| 130 | return ResultStatus::ErrorLoader_ErrorEncrypted; | 134 | return ResultStatus::ErrorLoader_ErrorMissingKeys; |
| 135 | case Loader::ResultStatus::ErrorDecrypting: | ||
| 136 | return ResultStatus::ErrorLoader_ErrorDecrypting; | ||
| 131 | case Loader::ResultStatus::ErrorInvalidFormat: | 137 | case Loader::ResultStatus::ErrorInvalidFormat: |
| 132 | return ResultStatus::ErrorLoader_ErrorInvalidFormat; | 138 | return ResultStatus::ErrorLoader_ErrorInvalidFormat; |
| 133 | case Loader::ResultStatus::ErrorUnsupportedArch: | 139 | case Loader::ResultStatus::ErrorUnsupportedArch: |
| @@ -163,7 +169,7 @@ Cpu& System::CpuCore(size_t core_index) { | |||
| 163 | return *cpu_cores[core_index]; | 169 | return *cpu_cores[core_index]; |
| 164 | } | 170 | } |
| 165 | 171 | ||
| 166 | System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) { | 172 | System::ResultStatus System::Init(EmuWindow& emu_window) { |
| 167 | LOG_DEBUG(HW_Memory, "initialized OK"); | 173 | LOG_DEBUG(HW_Memory, "initialized OK"); |
| 168 | 174 | ||
| 169 | CoreTiming::Init(); | 175 | CoreTiming::Init(); |
| @@ -176,19 +182,20 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) { | |||
| 176 | cpu_cores[index] = std::make_shared<Cpu>(cpu_exclusive_monitor, cpu_barrier, index); | 182 | cpu_cores[index] = std::make_shared<Cpu>(cpu_exclusive_monitor, cpu_barrier, index); |
| 177 | } | 183 | } |
| 178 | 184 | ||
| 179 | gpu_core = std::make_unique<Tegra::GPU>(); | ||
| 180 | telemetry_session = std::make_unique<Core::TelemetrySession>(); | 185 | telemetry_session = std::make_unique<Core::TelemetrySession>(); |
| 181 | service_manager = std::make_shared<Service::SM::ServiceManager>(); | 186 | service_manager = std::make_shared<Service::SM::ServiceManager>(); |
| 182 | 187 | ||
| 183 | HW::Init(); | 188 | Kernel::Init(); |
| 184 | Kernel::Init(system_mode); | ||
| 185 | Service::Init(service_manager); | 189 | Service::Init(service_manager); |
| 186 | GDBStub::Init(); | 190 | GDBStub::Init(); |
| 187 | 191 | ||
| 188 | if (!VideoCore::Init(emu_window)) { | 192 | renderer = VideoCore::CreateRenderer(emu_window); |
| 193 | if (!renderer->Init()) { | ||
| 189 | return ResultStatus::ErrorVideoCore; | 194 | return ResultStatus::ErrorVideoCore; |
| 190 | } | 195 | } |
| 191 | 196 | ||
| 197 | gpu_core = std::make_unique<Tegra::GPU>(renderer->Rasterizer()); | ||
| 198 | |||
| 192 | // Create threads for CPU cores 1-3, and build thread_to_cpu map | 199 | // Create threads for CPU cores 1-3, and build thread_to_cpu map |
| 193 | // CPU core 0 is run on the main thread | 200 | // CPU core 0 is run on the main thread |
| 194 | thread_to_cpu[std::this_thread::get_id()] = cpu_cores[0]; | 201 | thread_to_cpu[std::this_thread::get_id()] = cpu_cores[0]; |
| @@ -220,11 +227,10 @@ void System::Shutdown() { | |||
| 220 | perf_results.frametime * 1000.0); | 227 | perf_results.frametime * 1000.0); |
| 221 | 228 | ||
| 222 | // Shutdown emulation session | 229 | // Shutdown emulation session |
| 223 | VideoCore::Shutdown(); | 230 | renderer.reset(); |
| 224 | GDBStub::Shutdown(); | 231 | GDBStub::Shutdown(); |
| 225 | Service::Shutdown(); | 232 | Service::Shutdown(); |
| 226 | Kernel::Shutdown(); | 233 | Kernel::Shutdown(); |
| 227 | HW::Shutdown(); | ||
| 228 | service_manager.reset(); | 234 | service_manager.reset(); |
| 229 | telemetry_session.reset(); | 235 | telemetry_session.reset(); |
| 230 | gpu_core.reset(); | 236 | gpu_core.reset(); |
diff --git a/src/core/core.h b/src/core/core.h index c123fe401..c8ca4b247 100644 --- a/src/core/core.h +++ b/src/core/core.h | |||
| @@ -11,7 +11,7 @@ | |||
| 11 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| 12 | #include "core/arm/exclusive_monitor.h" | 12 | #include "core/arm/exclusive_monitor.h" |
| 13 | #include "core/core_cpu.h" | 13 | #include "core/core_cpu.h" |
| 14 | #include "core/hle/kernel/kernel.h" | 14 | #include "core/hle/kernel/object.h" |
| 15 | #include "core/hle/kernel/scheduler.h" | 15 | #include "core/hle/kernel/scheduler.h" |
| 16 | #include "core/loader/loader.h" | 16 | #include "core/loader/loader.h" |
| 17 | #include "core/memory.h" | 17 | #include "core/memory.h" |
| @@ -27,6 +27,10 @@ namespace Service::SM { | |||
| 27 | class ServiceManager; | 27 | class ServiceManager; |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | namespace VideoCore { | ||
| 31 | class RendererBase; | ||
| 32 | } | ||
| 33 | |||
| 30 | namespace Core { | 34 | namespace Core { |
| 31 | 35 | ||
| 32 | class System { | 36 | class System { |
| @@ -43,12 +47,14 @@ public: | |||
| 43 | 47 | ||
| 44 | /// Enumeration representing the return values of the System Initialize and Load process. | 48 | /// Enumeration representing the return values of the System Initialize and Load process. |
| 45 | enum class ResultStatus : u32 { | 49 | enum class ResultStatus : u32 { |
| 46 | Success, ///< Succeeded | 50 | Success, ///< Succeeded |
| 47 | ErrorNotInitialized, ///< Error trying to use core prior to initialization | 51 | ErrorNotInitialized, ///< Error trying to use core prior to initialization |
| 48 | ErrorGetLoader, ///< Error finding the correct application loader | 52 | ErrorGetLoader, ///< Error finding the correct application loader |
| 49 | ErrorSystemMode, ///< Error determining the system mode | 53 | ErrorSystemMode, ///< Error determining the system mode |
| 50 | ErrorLoader, ///< Error loading the specified application | 54 | ErrorLoader, ///< Error loading the specified application |
| 51 | ErrorLoader_ErrorEncrypted, ///< Error loading the specified application due to encryption | 55 | ErrorLoader_ErrorMissingKeys, ///< Error because the key/keys needed to run could not be |
| 56 | ///< found. | ||
| 57 | ErrorLoader_ErrorDecrypting, ///< Error loading the specified application due to encryption | ||
| 52 | ErrorLoader_ErrorInvalidFormat, ///< Error loading the specified application due to an | 58 | ErrorLoader_ErrorInvalidFormat, ///< Error loading the specified application due to an |
| 53 | /// invalid format | 59 | /// invalid format |
| 54 | ErrorSystemFiles, ///< Error in finding system files | 60 | ErrorSystemFiles, ///< Error in finding system files |
| @@ -76,16 +82,28 @@ public: | |||
| 76 | */ | 82 | */ |
| 77 | ResultStatus SingleStep(); | 83 | ResultStatus SingleStep(); |
| 78 | 84 | ||
| 85 | /** | ||
| 86 | * Invalidate the CPU instruction caches | ||
| 87 | * This function should only be used by GDB Stub to support breakpoints, memory updates and | ||
| 88 | * step/continue commands. | ||
| 89 | */ | ||
| 90 | void InvalidateCpuInstructionCaches() { | ||
| 91 | for (auto& cpu : cpu_cores) { | ||
| 92 | cpu->ArmInterface().ClearInstructionCache(); | ||
| 93 | } | ||
| 94 | } | ||
| 95 | |||
| 79 | /// Shutdown the emulated system. | 96 | /// Shutdown the emulated system. |
| 80 | void Shutdown(); | 97 | void Shutdown(); |
| 81 | 98 | ||
| 82 | /** | 99 | /** |
| 83 | * Load an executable application. | 100 | * Load an executable application. |
| 84 | * @param emu_window Pointer to the host-system window used for video output and keyboard input. | 101 | * @param emu_window Reference to the host-system window used for video output and keyboard |
| 102 | * input. | ||
| 85 | * @param filepath String path to the executable application to load on the host file system. | 103 | * @param filepath String path to the executable application to load on the host file system. |
| 86 | * @returns ResultStatus code, indicating if the operation succeeded. | 104 | * @returns ResultStatus code, indicating if the operation succeeded. |
| 87 | */ | 105 | */ |
| 88 | ResultStatus Load(EmuWindow* emu_window, const std::string& filepath); | 106 | ResultStatus Load(EmuWindow& emu_window, const std::string& filepath); |
| 89 | 107 | ||
| 90 | /** | 108 | /** |
| 91 | * Indicates if the emulated system is powered on (all subsystems initialized and able to run an | 109 | * Indicates if the emulated system is powered on (all subsystems initialized and able to run an |
| @@ -126,11 +144,26 @@ public: | |||
| 126 | /// Gets a CPU interface to the CPU core with the specified index | 144 | /// Gets a CPU interface to the CPU core with the specified index |
| 127 | Cpu& CpuCore(size_t core_index); | 145 | Cpu& CpuCore(size_t core_index); |
| 128 | 146 | ||
| 129 | /// Gets the GPU interface | 147 | /// Gets a mutable reference to the GPU interface |
| 130 | Tegra::GPU& GPU() { | 148 | Tegra::GPU& GPU() { |
| 131 | return *gpu_core; | 149 | return *gpu_core; |
| 132 | } | 150 | } |
| 133 | 151 | ||
| 152 | /// Gets an immutable reference to the GPU interface. | ||
| 153 | const Tegra::GPU& GPU() const { | ||
| 154 | return *gpu_core; | ||
| 155 | } | ||
| 156 | |||
| 157 | /// Gets a mutable reference to the renderer. | ||
| 158 | VideoCore::RendererBase& Renderer() { | ||
| 159 | return *renderer; | ||
| 160 | } | ||
| 161 | |||
| 162 | /// Gets an immutable reference to the renderer. | ||
| 163 | const VideoCore::RendererBase& Renderer() const { | ||
| 164 | return *renderer; | ||
| 165 | } | ||
| 166 | |||
| 134 | /// Gets the scheduler for the CPU core that is currently running | 167 | /// Gets the scheduler for the CPU core that is currently running |
| 135 | Kernel::Scheduler& CurrentScheduler() { | 168 | Kernel::Scheduler& CurrentScheduler() { |
| 136 | return *CurrentCpuCore().Scheduler(); | 169 | return *CurrentCpuCore().Scheduler(); |
| @@ -186,14 +219,15 @@ private: | |||
| 186 | 219 | ||
| 187 | /** | 220 | /** |
| 188 | * Initialize the emulated system. | 221 | * Initialize the emulated system. |
| 189 | * @param emu_window Pointer to the host-system window used for video output and keyboard input. | 222 | * @param emu_window Reference to the host-system window used for video output and keyboard |
| 190 | * @param system_mode The system mode. | 223 | * input. |
| 191 | * @return ResultStatus code, indicating if the operation succeeded. | 224 | * @return ResultStatus code, indicating if the operation succeeded. |
| 192 | */ | 225 | */ |
| 193 | ResultStatus Init(EmuWindow* emu_window, u32 system_mode); | 226 | ResultStatus Init(EmuWindow& emu_window); |
| 194 | 227 | ||
| 195 | /// AppLoader used to load the current executing application | 228 | /// AppLoader used to load the current executing application |
| 196 | std::unique_ptr<Loader::AppLoader> app_loader; | 229 | std::unique_ptr<Loader::AppLoader> app_loader; |
| 230 | std::unique_ptr<VideoCore::RendererBase> renderer; | ||
| 197 | std::unique_ptr<Tegra::GPU> gpu_core; | 231 | std::unique_ptr<Tegra::GPU> gpu_core; |
| 198 | std::shared_ptr<Tegra::DebugContext> debug_context; | 232 | std::shared_ptr<Tegra::DebugContext> debug_context; |
| 199 | Kernel::SharedPtr<Kernel::Process> current_process; | 233 | Kernel::SharedPtr<Kernel::Process> current_process; |
diff --git a/src/core/core_cpu.cpp b/src/core/core_cpu.cpp index 54e15a701..46a522fcd 100644 --- a/src/core/core_cpu.cpp +++ b/src/core/core_cpu.cpp | |||
| @@ -12,7 +12,6 @@ | |||
| 12 | #include "core/arm/unicorn/arm_unicorn.h" | 12 | #include "core/arm/unicorn/arm_unicorn.h" |
| 13 | #include "core/core_cpu.h" | 13 | #include "core/core_cpu.h" |
| 14 | #include "core/core_timing.h" | 14 | #include "core/core_timing.h" |
| 15 | #include "core/hle/kernel/kernel.h" | ||
| 16 | #include "core/hle/kernel/scheduler.h" | 15 | #include "core/hle/kernel/scheduler.h" |
| 17 | #include "core/hle/kernel/thread.h" | 16 | #include "core/hle/kernel/thread.h" |
| 18 | #include "core/settings.h" | 17 | #include "core/settings.h" |
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index a1b6f96f1..d3bb6f818 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp | |||
| @@ -141,7 +141,7 @@ void ScheduleEvent(s64 cycles_into_future, const EventType* event_type, u64 user | |||
| 141 | ForceExceptionCheck(cycles_into_future); | 141 | ForceExceptionCheck(cycles_into_future); |
| 142 | 142 | ||
| 143 | event_queue.emplace_back(Event{timeout, event_fifo_id++, userdata, event_type}); | 143 | event_queue.emplace_back(Event{timeout, event_fifo_id++, userdata, event_type}); |
| 144 | std::push_heap(event_queue.begin(), event_queue.end(), std::greater<Event>()); | 144 | std::push_heap(event_queue.begin(), event_queue.end(), std::greater<>()); |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | void ScheduleEventThreadsafe(s64 cycles_into_future, const EventType* event_type, u64 userdata) { | 147 | void ScheduleEventThreadsafe(s64 cycles_into_future, const EventType* event_type, u64 userdata) { |
| @@ -156,7 +156,7 @@ void UnscheduleEvent(const EventType* event_type, u64 userdata) { | |||
| 156 | // Removing random items breaks the invariant so we have to re-establish it. | 156 | // Removing random items breaks the invariant so we have to re-establish it. |
| 157 | if (itr != event_queue.end()) { | 157 | if (itr != event_queue.end()) { |
| 158 | event_queue.erase(itr, event_queue.end()); | 158 | event_queue.erase(itr, event_queue.end()); |
| 159 | std::make_heap(event_queue.begin(), event_queue.end(), std::greater<Event>()); | 159 | std::make_heap(event_queue.begin(), event_queue.end(), std::greater<>()); |
| 160 | } | 160 | } |
| 161 | } | 161 | } |
| 162 | 162 | ||
| @@ -167,7 +167,7 @@ void RemoveEvent(const EventType* event_type) { | |||
| 167 | // Removing random items breaks the invariant so we have to re-establish it. | 167 | // Removing random items breaks the invariant so we have to re-establish it. |
| 168 | if (itr != event_queue.end()) { | 168 | if (itr != event_queue.end()) { |
| 169 | event_queue.erase(itr, event_queue.end()); | 169 | event_queue.erase(itr, event_queue.end()); |
| 170 | std::make_heap(event_queue.begin(), event_queue.end(), std::greater<Event>()); | 170 | std::make_heap(event_queue.begin(), event_queue.end(), std::greater<>()); |
| 171 | } | 171 | } |
| 172 | } | 172 | } |
| 173 | 173 | ||
| @@ -190,7 +190,7 @@ void MoveEvents() { | |||
| 190 | for (Event ev; ts_queue.Pop(ev);) { | 190 | for (Event ev; ts_queue.Pop(ev);) { |
| 191 | ev.fifo_order = event_fifo_id++; | 191 | ev.fifo_order = event_fifo_id++; |
| 192 | event_queue.emplace_back(std::move(ev)); | 192 | event_queue.emplace_back(std::move(ev)); |
| 193 | std::push_heap(event_queue.begin(), event_queue.end(), std::greater<Event>()); | 193 | std::push_heap(event_queue.begin(), event_queue.end(), std::greater<>()); |
| 194 | } | 194 | } |
| 195 | } | 195 | } |
| 196 | 196 | ||
| @@ -205,7 +205,7 @@ void Advance() { | |||
| 205 | 205 | ||
| 206 | while (!event_queue.empty() && event_queue.front().time <= global_timer) { | 206 | while (!event_queue.empty() && event_queue.front().time <= global_timer) { |
| 207 | Event evt = std::move(event_queue.front()); | 207 | Event evt = std::move(event_queue.front()); |
| 208 | std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<Event>()); | 208 | std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<>()); |
| 209 | event_queue.pop_back(); | 209 | event_queue.pop_back(); |
| 210 | evt.type->callback(evt.userdata, static_cast<int>(global_timer - evt.time)); | 210 | evt.type->callback(evt.userdata, static_cast<int>(global_timer - evt.time)); |
| 211 | } | 211 | } |
| @@ -226,8 +226,8 @@ void Idle() { | |||
| 226 | downcount = 0; | 226 | downcount = 0; |
| 227 | } | 227 | } |
| 228 | 228 | ||
| 229 | u64 GetGlobalTimeUs() { | 229 | std::chrono::microseconds GetGlobalTimeUs() { |
| 230 | return GetTicks() * 1000000 / BASE_CLOCK_RATE; | 230 | return std::chrono::microseconds{GetTicks() * 1000000 / BASE_CLOCK_RATE}; |
| 231 | } | 231 | } |
| 232 | 232 | ||
| 233 | int GetDowncount() { | 233 | int GetDowncount() { |
diff --git a/src/core/core_timing.h b/src/core/core_timing.h index 7fe6380ad..dfa161c0d 100644 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h | |||
| @@ -17,12 +17,17 @@ | |||
| 17 | * ScheduleEvent(periodInCycles - cyclesLate, callback, "whatever") | 17 | * ScheduleEvent(periodInCycles - cyclesLate, callback, "whatever") |
| 18 | */ | 18 | */ |
| 19 | 19 | ||
| 20 | #include <chrono> | ||
| 20 | #include <functional> | 21 | #include <functional> |
| 21 | #include <string> | 22 | #include <string> |
| 22 | #include "common/common_types.h" | 23 | #include "common/common_types.h" |
| 23 | 24 | ||
| 24 | namespace CoreTiming { | 25 | namespace CoreTiming { |
| 25 | 26 | ||
| 27 | struct EventType; | ||
| 28 | |||
| 29 | using TimedCallback = std::function<void(u64 userdata, int cycles_late)>; | ||
| 30 | |||
| 26 | /** | 31 | /** |
| 27 | * CoreTiming begins at the boundary of timing slice -1. An initial call to Advance() is | 32 | * CoreTiming begins at the boundary of timing slice -1. An initial call to Advance() is |
| 28 | * required to end slice -1 and start slice 0 before the first cycle of code is executed. | 33 | * required to end slice -1 and start slice 0 before the first cycle of code is executed. |
| @@ -30,8 +35,6 @@ namespace CoreTiming { | |||
| 30 | void Init(); | 35 | void Init(); |
| 31 | void Shutdown(); | 36 | void Shutdown(); |
| 32 | 37 | ||
| 33 | typedef std::function<void(u64 userdata, int cycles_late)> TimedCallback; | ||
| 34 | |||
| 35 | /** | 38 | /** |
| 36 | * This should only be called from the emu thread, if you are calling it any other thread, you are | 39 | * This should only be called from the emu thread, if you are calling it any other thread, you are |
| 37 | * doing something evil | 40 | * doing something evil |
| @@ -40,8 +43,6 @@ u64 GetTicks(); | |||
| 40 | u64 GetIdleTicks(); | 43 | u64 GetIdleTicks(); |
| 41 | void AddTicks(u64 ticks); | 44 | void AddTicks(u64 ticks); |
| 42 | 45 | ||
| 43 | struct EventType; | ||
| 44 | |||
| 45 | /** | 46 | /** |
| 46 | * Returns the event_type identifier. if name is not unique, it will assert. | 47 | * Returns the event_type identifier. if name is not unique, it will assert. |
| 47 | */ | 48 | */ |
| @@ -86,7 +87,7 @@ void ClearPendingEvents(); | |||
| 86 | 87 | ||
| 87 | void ForceExceptionCheck(s64 cycles); | 88 | void ForceExceptionCheck(s64 cycles); |
| 88 | 89 | ||
| 89 | u64 GetGlobalTimeUs(); | 90 | std::chrono::microseconds GetGlobalTimeUs(); |
| 90 | 91 | ||
| 91 | int GetDowncount(); | 92 | int GetDowncount(); |
| 92 | 93 | ||
diff --git a/src/core/crypto/aes_util.cpp b/src/core/crypto/aes_util.cpp new file mode 100644 index 000000000..a9876c83e --- /dev/null +++ b/src/core/crypto/aes_util.cpp | |||
| @@ -0,0 +1,115 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <mbedtls/cipher.h> | ||
| 6 | #include "common/assert.h" | ||
| 7 | #include "common/logging/log.h" | ||
| 8 | #include "core/crypto/aes_util.h" | ||
| 9 | #include "core/crypto/key_manager.h" | ||
| 10 | |||
| 11 | namespace Core::Crypto { | ||
| 12 | namespace { | ||
| 13 | std::vector<u8> CalculateNintendoTweak(size_t sector_id) { | ||
| 14 | std::vector<u8> out(0x10); | ||
| 15 | for (size_t i = 0xF; i <= 0xF; --i) { | ||
| 16 | out[i] = sector_id & 0xFF; | ||
| 17 | sector_id >>= 8; | ||
| 18 | } | ||
| 19 | return out; | ||
| 20 | } | ||
| 21 | } // Anonymous namespace | ||
| 22 | |||
| 23 | static_assert(static_cast<size_t>(Mode::CTR) == static_cast<size_t>(MBEDTLS_CIPHER_AES_128_CTR), | ||
| 24 | "CTR has incorrect value."); | ||
| 25 | static_assert(static_cast<size_t>(Mode::ECB) == static_cast<size_t>(MBEDTLS_CIPHER_AES_128_ECB), | ||
| 26 | "ECB has incorrect value."); | ||
| 27 | static_assert(static_cast<size_t>(Mode::XTS) == static_cast<size_t>(MBEDTLS_CIPHER_AES_128_XTS), | ||
| 28 | "XTS has incorrect value."); | ||
| 29 | |||
| 30 | // Structure to hide mbedtls types from header file | ||
| 31 | struct CipherContext { | ||
| 32 | mbedtls_cipher_context_t encryption_context; | ||
| 33 | mbedtls_cipher_context_t decryption_context; | ||
| 34 | }; | ||
| 35 | |||
| 36 | template <typename Key, size_t KeySize> | ||
| 37 | Crypto::AESCipher<Key, KeySize>::AESCipher(Key key, Mode mode) | ||
| 38 | : ctx(std::make_unique<CipherContext>()) { | ||
| 39 | mbedtls_cipher_init(&ctx->encryption_context); | ||
| 40 | mbedtls_cipher_init(&ctx->decryption_context); | ||
| 41 | |||
| 42 | ASSERT_MSG((mbedtls_cipher_setup( | ||
| 43 | &ctx->encryption_context, | ||
| 44 | mbedtls_cipher_info_from_type(static_cast<mbedtls_cipher_type_t>(mode))) || | ||
| 45 | mbedtls_cipher_setup( | ||
| 46 | &ctx->decryption_context, | ||
| 47 | mbedtls_cipher_info_from_type(static_cast<mbedtls_cipher_type_t>(mode)))) == 0, | ||
| 48 | "Failed to initialize mbedtls ciphers."); | ||
| 49 | |||
| 50 | ASSERT( | ||
| 51 | !mbedtls_cipher_setkey(&ctx->encryption_context, key.data(), KeySize * 8, MBEDTLS_ENCRYPT)); | ||
| 52 | ASSERT( | ||
| 53 | !mbedtls_cipher_setkey(&ctx->decryption_context, key.data(), KeySize * 8, MBEDTLS_DECRYPT)); | ||
| 54 | //"Failed to set key on mbedtls ciphers."); | ||
| 55 | } | ||
| 56 | |||
| 57 | template <typename Key, size_t KeySize> | ||
| 58 | AESCipher<Key, KeySize>::~AESCipher() { | ||
| 59 | mbedtls_cipher_free(&ctx->encryption_context); | ||
| 60 | mbedtls_cipher_free(&ctx->decryption_context); | ||
| 61 | } | ||
| 62 | |||
| 63 | template <typename Key, size_t KeySize> | ||
| 64 | void AESCipher<Key, KeySize>::SetIV(std::vector<u8> iv) { | ||
| 65 | ASSERT_MSG((mbedtls_cipher_set_iv(&ctx->encryption_context, iv.data(), iv.size()) || | ||
| 66 | mbedtls_cipher_set_iv(&ctx->decryption_context, iv.data(), iv.size())) == 0, | ||
| 67 | "Failed to set IV on mbedtls ciphers."); | ||
| 68 | } | ||
| 69 | |||
| 70 | template <typename Key, size_t KeySize> | ||
| 71 | void AESCipher<Key, KeySize>::Transcode(const u8* src, size_t size, u8* dest, Op op) const { | ||
| 72 | auto* const context = op == Op::Encrypt ? &ctx->encryption_context : &ctx->decryption_context; | ||
| 73 | |||
| 74 | mbedtls_cipher_reset(context); | ||
| 75 | |||
| 76 | size_t written = 0; | ||
| 77 | if (mbedtls_cipher_get_cipher_mode(context) == MBEDTLS_MODE_XTS) { | ||
| 78 | mbedtls_cipher_update(context, src, size, dest, &written); | ||
| 79 | if (written != size) { | ||
| 80 | LOG_WARNING(Crypto, "Not all data was decrypted requested={:016X}, actual={:016X}.", | ||
| 81 | size, written); | ||
| 82 | } | ||
| 83 | } else { | ||
| 84 | const auto block_size = mbedtls_cipher_get_block_size(context); | ||
| 85 | |||
| 86 | for (size_t offset = 0; offset < size; offset += block_size) { | ||
| 87 | auto length = std::min<size_t>(block_size, size - offset); | ||
| 88 | mbedtls_cipher_update(context, src + offset, length, dest + offset, &written); | ||
| 89 | if (written != length) { | ||
| 90 | LOG_WARNING(Crypto, "Not all data was decrypted requested={:016X}, actual={:016X}.", | ||
| 91 | length, written); | ||
| 92 | } | ||
| 93 | } | ||
| 94 | } | ||
| 95 | |||
| 96 | mbedtls_cipher_finish(context, nullptr, nullptr); | ||
| 97 | } | ||
| 98 | |||
| 99 | template <typename Key, size_t KeySize> | ||
| 100 | void AESCipher<Key, KeySize>::XTSTranscode(const u8* src, size_t size, u8* dest, size_t sector_id, | ||
| 101 | size_t sector_size, Op op) { | ||
| 102 | if (size % sector_size > 0) { | ||
| 103 | LOG_CRITICAL(Crypto, "Data size must be a multiple of sector size."); | ||
| 104 | return; | ||
| 105 | } | ||
| 106 | |||
| 107 | for (size_t i = 0; i < size; i += sector_size) { | ||
| 108 | SetIV(CalculateNintendoTweak(sector_id++)); | ||
| 109 | Transcode<u8, u8>(src + i, sector_size, dest + i, op); | ||
| 110 | } | ||
| 111 | } | ||
| 112 | |||
| 113 | template class AESCipher<Key128>; | ||
| 114 | template class AESCipher<Key256>; | ||
| 115 | } // namespace Core::Crypto \ No newline at end of file | ||
diff --git a/src/core/crypto/aes_util.h b/src/core/crypto/aes_util.h new file mode 100644 index 000000000..8ce9d6612 --- /dev/null +++ b/src/core/crypto/aes_util.h | |||
| @@ -0,0 +1,64 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | #include <type_traits> | ||
| 9 | #include <vector> | ||
| 10 | #include "common/common_types.h" | ||
| 11 | #include "core/file_sys/vfs.h" | ||
| 12 | |||
| 13 | namespace Core::Crypto { | ||
| 14 | |||
| 15 | struct CipherContext; | ||
| 16 | |||
| 17 | enum class Mode { | ||
| 18 | CTR = 11, | ||
| 19 | ECB = 2, | ||
| 20 | XTS = 70, | ||
| 21 | }; | ||
| 22 | |||
| 23 | enum class Op { | ||
| 24 | Encrypt, | ||
| 25 | Decrypt, | ||
| 26 | }; | ||
| 27 | |||
| 28 | template <typename Key, size_t KeySize = sizeof(Key)> | ||
| 29 | class AESCipher { | ||
| 30 | static_assert(std::is_same_v<Key, std::array<u8, KeySize>>, "Key must be std::array of u8."); | ||
| 31 | static_assert(KeySize == 0x10 || KeySize == 0x20, "KeySize must be 128 or 256."); | ||
| 32 | |||
| 33 | public: | ||
| 34 | AESCipher(Key key, Mode mode); | ||
| 35 | |||
| 36 | ~AESCipher(); | ||
| 37 | |||
| 38 | void SetIV(std::vector<u8> iv); | ||
| 39 | |||
| 40 | template <typename Source, typename Dest> | ||
| 41 | void Transcode(const Source* src, size_t size, Dest* dest, Op op) const { | ||
| 42 | static_assert(std::is_trivially_copyable_v<Source> && std::is_trivially_copyable_v<Dest>, | ||
| 43 | "Transcode source and destination types must be trivially copyable."); | ||
| 44 | Transcode(reinterpret_cast<const u8*>(src), size, reinterpret_cast<u8*>(dest), op); | ||
| 45 | } | ||
| 46 | |||
| 47 | void Transcode(const u8* src, size_t size, u8* dest, Op op) const; | ||
| 48 | |||
| 49 | template <typename Source, typename Dest> | ||
| 50 | void XTSTranscode(const Source* src, size_t size, Dest* dest, size_t sector_id, | ||
| 51 | size_t sector_size, Op op) { | ||
| 52 | static_assert(std::is_trivially_copyable_v<Source> && std::is_trivially_copyable_v<Dest>, | ||
| 53 | "XTSTranscode source and destination types must be trivially copyable."); | ||
| 54 | XTSTranscode(reinterpret_cast<const u8*>(src), size, reinterpret_cast<u8*>(dest), sector_id, | ||
| 55 | sector_size, op); | ||
| 56 | } | ||
| 57 | |||
| 58 | void XTSTranscode(const u8* src, size_t size, u8* dest, size_t sector_id, size_t sector_size, | ||
| 59 | Op op); | ||
| 60 | |||
| 61 | private: | ||
| 62 | std::unique_ptr<CipherContext> ctx; | ||
| 63 | }; | ||
| 64 | } // namespace Core::Crypto | ||
diff --git a/src/core/crypto/ctr_encryption_layer.cpp b/src/core/crypto/ctr_encryption_layer.cpp new file mode 100644 index 000000000..106db02b3 --- /dev/null +++ b/src/core/crypto/ctr_encryption_layer.cpp | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <cstring> | ||
| 6 | #include "common/assert.h" | ||
| 7 | #include "core/crypto/ctr_encryption_layer.h" | ||
| 8 | |||
| 9 | namespace Core::Crypto { | ||
| 10 | |||
| 11 | CTREncryptionLayer::CTREncryptionLayer(FileSys::VirtualFile base_, Key128 key_, size_t base_offset) | ||
| 12 | : EncryptionLayer(std::move(base_)), base_offset(base_offset), cipher(key_, Mode::CTR), | ||
| 13 | iv(16, 0) {} | ||
| 14 | |||
| 15 | size_t CTREncryptionLayer::Read(u8* data, size_t length, size_t offset) const { | ||
| 16 | if (length == 0) | ||
| 17 | return 0; | ||
| 18 | |||
| 19 | const auto sector_offset = offset & 0xF; | ||
| 20 | if (sector_offset == 0) { | ||
| 21 | UpdateIV(base_offset + offset); | ||
| 22 | std::vector<u8> raw = base->ReadBytes(length, offset); | ||
| 23 | if (raw.size() != length) | ||
| 24 | return Read(data, raw.size(), offset); | ||
| 25 | cipher.Transcode(raw.data(), length, data, Op::Decrypt); | ||
| 26 | return length; | ||
| 27 | } | ||
| 28 | |||
| 29 | // offset does not fall on block boundary (0x10) | ||
| 30 | std::vector<u8> block = base->ReadBytes(0x10, offset - sector_offset); | ||
| 31 | UpdateIV(base_offset + offset - sector_offset); | ||
| 32 | cipher.Transcode(block.data(), block.size(), block.data(), Op::Decrypt); | ||
| 33 | size_t read = 0x10 - sector_offset; | ||
| 34 | |||
| 35 | if (length + sector_offset < 0x10) { | ||
| 36 | std::memcpy(data, block.data() + sector_offset, std::min<u64>(length, read)); | ||
| 37 | return read; | ||
| 38 | } | ||
| 39 | std::memcpy(data, block.data() + sector_offset, read); | ||
| 40 | return read + Read(data + read, length - read, offset + read); | ||
| 41 | } | ||
| 42 | |||
| 43 | void CTREncryptionLayer::SetIV(const std::vector<u8>& iv_) { | ||
| 44 | const auto length = std::min(iv_.size(), iv.size()); | ||
| 45 | iv.assign(iv_.cbegin(), iv_.cbegin() + length); | ||
| 46 | } | ||
| 47 | |||
| 48 | void CTREncryptionLayer::UpdateIV(size_t offset) const { | ||
| 49 | offset >>= 4; | ||
| 50 | for (size_t i = 0; i < 8; ++i) { | ||
| 51 | iv[16 - i - 1] = offset & 0xFF; | ||
| 52 | offset >>= 8; | ||
| 53 | } | ||
| 54 | cipher.SetIV(iv); | ||
| 55 | } | ||
| 56 | } // namespace Core::Crypto | ||
diff --git a/src/core/crypto/ctr_encryption_layer.h b/src/core/crypto/ctr_encryption_layer.h new file mode 100644 index 000000000..11b8683c7 --- /dev/null +++ b/src/core/crypto/ctr_encryption_layer.h | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <vector> | ||
| 8 | #include "core/crypto/aes_util.h" | ||
| 9 | #include "core/crypto/encryption_layer.h" | ||
| 10 | #include "core/crypto/key_manager.h" | ||
| 11 | |||
| 12 | namespace Core::Crypto { | ||
| 13 | |||
| 14 | // Sits on top of a VirtualFile and provides CTR-mode AES decription. | ||
| 15 | class CTREncryptionLayer : public EncryptionLayer { | ||
| 16 | public: | ||
| 17 | CTREncryptionLayer(FileSys::VirtualFile base, Key128 key, size_t base_offset); | ||
| 18 | |||
| 19 | size_t Read(u8* data, size_t length, size_t offset) const override; | ||
| 20 | |||
| 21 | void SetIV(const std::vector<u8>& iv); | ||
| 22 | |||
| 23 | private: | ||
| 24 | size_t base_offset; | ||
| 25 | |||
| 26 | // Must be mutable as operations modify cipher contexts. | ||
| 27 | mutable AESCipher<Key128> cipher; | ||
| 28 | mutable std::vector<u8> iv; | ||
| 29 | |||
| 30 | void UpdateIV(size_t offset) const; | ||
| 31 | }; | ||
| 32 | |||
| 33 | } // namespace Core::Crypto | ||
diff --git a/src/core/crypto/encryption_layer.cpp b/src/core/crypto/encryption_layer.cpp new file mode 100644 index 000000000..4204527e3 --- /dev/null +++ b/src/core/crypto/encryption_layer.cpp | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/crypto/encryption_layer.h" | ||
| 6 | |||
| 7 | namespace Core::Crypto { | ||
| 8 | |||
| 9 | EncryptionLayer::EncryptionLayer(FileSys::VirtualFile base_) : base(std::move(base_)) {} | ||
| 10 | |||
| 11 | std::string EncryptionLayer::GetName() const { | ||
| 12 | return base->GetName(); | ||
| 13 | } | ||
| 14 | |||
| 15 | size_t EncryptionLayer::GetSize() const { | ||
| 16 | return base->GetSize(); | ||
| 17 | } | ||
| 18 | |||
| 19 | bool EncryptionLayer::Resize(size_t new_size) { | ||
| 20 | return false; | ||
| 21 | } | ||
| 22 | |||
| 23 | std::shared_ptr<FileSys::VfsDirectory> EncryptionLayer::GetContainingDirectory() const { | ||
| 24 | return base->GetContainingDirectory(); | ||
| 25 | } | ||
| 26 | |||
| 27 | bool EncryptionLayer::IsWritable() const { | ||
| 28 | return false; | ||
| 29 | } | ||
| 30 | |||
| 31 | bool EncryptionLayer::IsReadable() const { | ||
| 32 | return true; | ||
| 33 | } | ||
| 34 | |||
| 35 | size_t EncryptionLayer::Write(const u8* data, size_t length, size_t offset) { | ||
| 36 | return 0; | ||
| 37 | } | ||
| 38 | |||
| 39 | bool EncryptionLayer::Rename(std::string_view name) { | ||
| 40 | return base->Rename(name); | ||
| 41 | } | ||
| 42 | } // namespace Core::Crypto | ||
diff --git a/src/core/crypto/encryption_layer.h b/src/core/crypto/encryption_layer.h new file mode 100644 index 000000000..7f05af9b4 --- /dev/null +++ b/src/core/crypto/encryption_layer.h | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "common/common_types.h" | ||
| 8 | #include "core/file_sys/vfs.h" | ||
| 9 | |||
| 10 | namespace Core::Crypto { | ||
| 11 | |||
| 12 | // Basically non-functional class that implements all of the methods that are irrelevant to an | ||
| 13 | // EncryptionLayer. Reduces duplicate code. | ||
| 14 | class EncryptionLayer : public FileSys::VfsFile { | ||
| 15 | public: | ||
| 16 | explicit EncryptionLayer(FileSys::VirtualFile base); | ||
| 17 | |||
| 18 | size_t Read(u8* data, size_t length, size_t offset) const override = 0; | ||
| 19 | |||
| 20 | std::string GetName() const override; | ||
| 21 | size_t GetSize() const override; | ||
| 22 | bool Resize(size_t new_size) override; | ||
| 23 | std::shared_ptr<FileSys::VfsDirectory> GetContainingDirectory() const override; | ||
| 24 | bool IsWritable() const override; | ||
| 25 | bool IsReadable() const override; | ||
| 26 | size_t Write(const u8* data, size_t length, size_t offset) override; | ||
| 27 | bool Rename(std::string_view name) override; | ||
| 28 | |||
| 29 | protected: | ||
| 30 | FileSys::VirtualFile base; | ||
| 31 | }; | ||
| 32 | |||
| 33 | } // namespace Core::Crypto | ||
diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp new file mode 100644 index 000000000..fc45e7ab5 --- /dev/null +++ b/src/core/crypto/key_manager.cpp | |||
| @@ -0,0 +1,208 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | #include <array> | ||
| 7 | #include <fstream> | ||
| 8 | #include <locale> | ||
| 9 | #include <sstream> | ||
| 10 | #include <string_view> | ||
| 11 | #include "common/common_paths.h" | ||
| 12 | #include "common/file_util.h" | ||
| 13 | #include "core/crypto/key_manager.h" | ||
| 14 | #include "core/settings.h" | ||
| 15 | |||
| 16 | namespace Core::Crypto { | ||
| 17 | |||
| 18 | static u8 ToHexNibble(char c1) { | ||
| 19 | if (c1 >= 65 && c1 <= 70) | ||
| 20 | return c1 - 55; | ||
| 21 | if (c1 >= 97 && c1 <= 102) | ||
| 22 | return c1 - 87; | ||
| 23 | if (c1 >= 48 && c1 <= 57) | ||
| 24 | return c1 - 48; | ||
| 25 | throw std::logic_error("Invalid hex digit"); | ||
| 26 | } | ||
| 27 | |||
| 28 | template <size_t Size> | ||
| 29 | static std::array<u8, Size> HexStringToArray(std::string_view str) { | ||
| 30 | std::array<u8, Size> out{}; | ||
| 31 | for (size_t i = 0; i < 2 * Size; i += 2) { | ||
| 32 | auto d1 = str[i]; | ||
| 33 | auto d2 = str[i + 1]; | ||
| 34 | out[i / 2] = (ToHexNibble(d1) << 4) | ToHexNibble(d2); | ||
| 35 | } | ||
| 36 | return out; | ||
| 37 | } | ||
| 38 | |||
| 39 | std::array<u8, 16> operator""_array16(const char* str, size_t len) { | ||
| 40 | if (len != 32) | ||
| 41 | throw std::logic_error("Not of correct size."); | ||
| 42 | return HexStringToArray<16>(str); | ||
| 43 | } | ||
| 44 | |||
| 45 | std::array<u8, 32> operator""_array32(const char* str, size_t len) { | ||
| 46 | if (len != 64) | ||
| 47 | throw std::logic_error("Not of correct size."); | ||
| 48 | return HexStringToArray<32>(str); | ||
| 49 | } | ||
| 50 | |||
| 51 | KeyManager::KeyManager() { | ||
| 52 | // Initialize keys | ||
| 53 | const std::string hactool_keys_dir = FileUtil::GetHactoolConfigurationPath(); | ||
| 54 | const std::string yuzu_keys_dir = FileUtil::GetUserPath(FileUtil::UserPath::KeysDir); | ||
| 55 | if (Settings::values.use_dev_keys) { | ||
| 56 | dev_mode = true; | ||
| 57 | AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "dev.keys", false); | ||
| 58 | } else { | ||
| 59 | dev_mode = false; | ||
| 60 | AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "prod.keys", false); | ||
| 61 | } | ||
| 62 | |||
| 63 | AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "title.keys", true); | ||
| 64 | } | ||
| 65 | |||
| 66 | void KeyManager::LoadFromFile(const std::string& filename, bool is_title_keys) { | ||
| 67 | std::ifstream file(filename); | ||
| 68 | if (!file.is_open()) | ||
| 69 | return; | ||
| 70 | |||
| 71 | std::string line; | ||
| 72 | while (std::getline(file, line)) { | ||
| 73 | std::vector<std::string> out; | ||
| 74 | std::stringstream stream(line); | ||
| 75 | std::string item; | ||
| 76 | while (std::getline(stream, item, '=')) | ||
| 77 | out.push_back(std::move(item)); | ||
| 78 | |||
| 79 | if (out.size() != 2) | ||
| 80 | continue; | ||
| 81 | |||
| 82 | out[0].erase(std::remove(out[0].begin(), out[0].end(), ' '), out[0].end()); | ||
| 83 | out[1].erase(std::remove(out[1].begin(), out[1].end(), ' '), out[1].end()); | ||
| 84 | |||
| 85 | if (is_title_keys) { | ||
| 86 | auto rights_id_raw = HexStringToArray<16>(out[0]); | ||
| 87 | u128 rights_id{}; | ||
| 88 | std::memcpy(rights_id.data(), rights_id_raw.data(), rights_id_raw.size()); | ||
| 89 | Key128 key = HexStringToArray<16>(out[1]); | ||
| 90 | SetKey(S128KeyType::Titlekey, key, rights_id[1], rights_id[0]); | ||
| 91 | } else { | ||
| 92 | std::transform(out[0].begin(), out[0].end(), out[0].begin(), ::tolower); | ||
| 93 | if (s128_file_id.find(out[0]) != s128_file_id.end()) { | ||
| 94 | const auto index = s128_file_id.at(out[0]); | ||
| 95 | Key128 key = HexStringToArray<16>(out[1]); | ||
| 96 | SetKey(index.type, key, index.field1, index.field2); | ||
| 97 | } else if (s256_file_id.find(out[0]) != s256_file_id.end()) { | ||
| 98 | const auto index = s256_file_id.at(out[0]); | ||
| 99 | Key256 key = HexStringToArray<32>(out[1]); | ||
| 100 | SetKey(index.type, key, index.field1, index.field2); | ||
| 101 | } | ||
| 102 | } | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | void KeyManager::AttemptLoadKeyFile(const std::string& dir1, const std::string& dir2, | ||
| 107 | const std::string& filename, bool title) { | ||
| 108 | if (FileUtil::Exists(dir1 + DIR_SEP + filename)) | ||
| 109 | LoadFromFile(dir1 + DIR_SEP + filename, title); | ||
| 110 | else if (FileUtil::Exists(dir2 + DIR_SEP + filename)) | ||
| 111 | LoadFromFile(dir2 + DIR_SEP + filename, title); | ||
| 112 | } | ||
| 113 | |||
| 114 | bool KeyManager::HasKey(S128KeyType id, u64 field1, u64 field2) const { | ||
| 115 | return s128_keys.find({id, field1, field2}) != s128_keys.end(); | ||
| 116 | } | ||
| 117 | |||
| 118 | bool KeyManager::HasKey(S256KeyType id, u64 field1, u64 field2) const { | ||
| 119 | return s256_keys.find({id, field1, field2}) != s256_keys.end(); | ||
| 120 | } | ||
| 121 | |||
| 122 | Key128 KeyManager::GetKey(S128KeyType id, u64 field1, u64 field2) const { | ||
| 123 | if (!HasKey(id, field1, field2)) | ||
| 124 | return {}; | ||
| 125 | return s128_keys.at({id, field1, field2}); | ||
| 126 | } | ||
| 127 | |||
| 128 | Key256 KeyManager::GetKey(S256KeyType id, u64 field1, u64 field2) const { | ||
| 129 | if (!HasKey(id, field1, field2)) | ||
| 130 | return {}; | ||
| 131 | return s256_keys.at({id, field1, field2}); | ||
| 132 | } | ||
| 133 | |||
| 134 | void KeyManager::SetKey(S128KeyType id, Key128 key, u64 field1, u64 field2) { | ||
| 135 | s128_keys[{id, field1, field2}] = key; | ||
| 136 | } | ||
| 137 | |||
| 138 | void KeyManager::SetKey(S256KeyType id, Key256 key, u64 field1, u64 field2) { | ||
| 139 | s256_keys[{id, field1, field2}] = key; | ||
| 140 | } | ||
| 141 | |||
| 142 | bool KeyManager::KeyFileExists(bool title) { | ||
| 143 | const std::string hactool_keys_dir = FileUtil::GetHactoolConfigurationPath(); | ||
| 144 | const std::string yuzu_keys_dir = FileUtil::GetUserPath(FileUtil::UserPath::KeysDir); | ||
| 145 | if (title) { | ||
| 146 | return FileUtil::Exists(hactool_keys_dir + DIR_SEP + "title.keys") || | ||
| 147 | FileUtil::Exists(yuzu_keys_dir + DIR_SEP + "title.keys"); | ||
| 148 | } | ||
| 149 | |||
| 150 | if (Settings::values.use_dev_keys) { | ||
| 151 | return FileUtil::Exists(hactool_keys_dir + DIR_SEP + "dev.keys") || | ||
| 152 | FileUtil::Exists(yuzu_keys_dir + DIR_SEP + "dev.keys"); | ||
| 153 | } | ||
| 154 | |||
| 155 | return FileUtil::Exists(hactool_keys_dir + DIR_SEP + "prod.keys") || | ||
| 156 | FileUtil::Exists(yuzu_keys_dir + DIR_SEP + "prod.keys"); | ||
| 157 | } | ||
| 158 | |||
| 159 | const std::unordered_map<std::string, KeyIndex<S128KeyType>> KeyManager::s128_file_id = { | ||
| 160 | {"master_key_00", {S128KeyType::Master, 0, 0}}, | ||
| 161 | {"master_key_01", {S128KeyType::Master, 1, 0}}, | ||
| 162 | {"master_key_02", {S128KeyType::Master, 2, 0}}, | ||
| 163 | {"master_key_03", {S128KeyType::Master, 3, 0}}, | ||
| 164 | {"master_key_04", {S128KeyType::Master, 4, 0}}, | ||
| 165 | {"package1_key_00", {S128KeyType::Package1, 0, 0}}, | ||
| 166 | {"package1_key_01", {S128KeyType::Package1, 1, 0}}, | ||
| 167 | {"package1_key_02", {S128KeyType::Package1, 2, 0}}, | ||
| 168 | {"package1_key_03", {S128KeyType::Package1, 3, 0}}, | ||
| 169 | {"package1_key_04", {S128KeyType::Package1, 4, 0}}, | ||
| 170 | {"package2_key_00", {S128KeyType::Package2, 0, 0}}, | ||
| 171 | {"package2_key_01", {S128KeyType::Package2, 1, 0}}, | ||
| 172 | {"package2_key_02", {S128KeyType::Package2, 2, 0}}, | ||
| 173 | {"package2_key_03", {S128KeyType::Package2, 3, 0}}, | ||
| 174 | {"package2_key_04", {S128KeyType::Package2, 4, 0}}, | ||
| 175 | {"titlekek_00", {S128KeyType::Titlekek, 0, 0}}, | ||
| 176 | {"titlekek_01", {S128KeyType::Titlekek, 1, 0}}, | ||
| 177 | {"titlekek_02", {S128KeyType::Titlekek, 2, 0}}, | ||
| 178 | {"titlekek_03", {S128KeyType::Titlekek, 3, 0}}, | ||
| 179 | {"titlekek_04", {S128KeyType::Titlekek, 4, 0}}, | ||
| 180 | {"eticket_rsa_kek", {S128KeyType::ETicketRSAKek, 0, 0}}, | ||
| 181 | {"key_area_key_application_00", | ||
| 182 | {S128KeyType::KeyArea, 0, static_cast<u64>(KeyAreaKeyType::Application)}}, | ||
| 183 | {"key_area_key_application_01", | ||
| 184 | {S128KeyType::KeyArea, 1, static_cast<u64>(KeyAreaKeyType::Application)}}, | ||
| 185 | {"key_area_key_application_02", | ||
| 186 | {S128KeyType::KeyArea, 2, static_cast<u64>(KeyAreaKeyType::Application)}}, | ||
| 187 | {"key_area_key_application_03", | ||
| 188 | {S128KeyType::KeyArea, 3, static_cast<u64>(KeyAreaKeyType::Application)}}, | ||
| 189 | {"key_area_key_application_04", | ||
| 190 | {S128KeyType::KeyArea, 4, static_cast<u64>(KeyAreaKeyType::Application)}}, | ||
| 191 | {"key_area_key_ocean_00", {S128KeyType::KeyArea, 0, static_cast<u64>(KeyAreaKeyType::Ocean)}}, | ||
| 192 | {"key_area_key_ocean_01", {S128KeyType::KeyArea, 1, static_cast<u64>(KeyAreaKeyType::Ocean)}}, | ||
| 193 | {"key_area_key_ocean_02", {S128KeyType::KeyArea, 2, static_cast<u64>(KeyAreaKeyType::Ocean)}}, | ||
| 194 | {"key_area_key_ocean_03", {S128KeyType::KeyArea, 3, static_cast<u64>(KeyAreaKeyType::Ocean)}}, | ||
| 195 | {"key_area_key_ocean_04", {S128KeyType::KeyArea, 4, static_cast<u64>(KeyAreaKeyType::Ocean)}}, | ||
| 196 | {"key_area_key_system_00", {S128KeyType::KeyArea, 0, static_cast<u64>(KeyAreaKeyType::System)}}, | ||
| 197 | {"key_area_key_system_01", {S128KeyType::KeyArea, 1, static_cast<u64>(KeyAreaKeyType::System)}}, | ||
| 198 | {"key_area_key_system_02", {S128KeyType::KeyArea, 2, static_cast<u64>(KeyAreaKeyType::System)}}, | ||
| 199 | {"key_area_key_system_03", {S128KeyType::KeyArea, 3, static_cast<u64>(KeyAreaKeyType::System)}}, | ||
| 200 | {"key_area_key_system_04", {S128KeyType::KeyArea, 4, static_cast<u64>(KeyAreaKeyType::System)}}, | ||
| 201 | }; | ||
| 202 | |||
| 203 | const std::unordered_map<std::string, KeyIndex<S256KeyType>> KeyManager::s256_file_id = { | ||
| 204 | {"header_key", {S256KeyType::Header, 0, 0}}, | ||
| 205 | {"sd_card_save_key", {S256KeyType::SDSave, 0, 0}}, | ||
| 206 | {"sd_card_nca_key", {S256KeyType::SDNCA, 0, 0}}, | ||
| 207 | }; | ||
| 208 | } // namespace Core::Crypto | ||
diff --git a/src/core/crypto/key_manager.h b/src/core/crypto/key_manager.h new file mode 100644 index 000000000..c4c53cefc --- /dev/null +++ b/src/core/crypto/key_manager.h | |||
| @@ -0,0 +1,120 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <array> | ||
| 8 | #include <string> | ||
| 9 | #include <type_traits> | ||
| 10 | #include <unordered_map> | ||
| 11 | #include <vector> | ||
| 12 | #include <fmt/format.h> | ||
| 13 | #include "common/common_types.h" | ||
| 14 | |||
| 15 | namespace Core::Crypto { | ||
| 16 | |||
| 17 | using Key128 = std::array<u8, 0x10>; | ||
| 18 | using Key256 = std::array<u8, 0x20>; | ||
| 19 | using SHA256Hash = std::array<u8, 0x20>; | ||
| 20 | |||
| 21 | static_assert(sizeof(Key128) == 16, "Key128 must be 128 bytes big."); | ||
| 22 | static_assert(sizeof(Key256) == 32, "Key128 must be 128 bytes big."); | ||
| 23 | |||
| 24 | enum class S256KeyType : u64 { | ||
| 25 | Header, // | ||
| 26 | SDSave, // | ||
| 27 | SDNCA, // | ||
| 28 | }; | ||
| 29 | |||
| 30 | enum class S128KeyType : u64 { | ||
| 31 | Master, // f1=crypto revision | ||
| 32 | Package1, // f1=crypto revision | ||
| 33 | Package2, // f1=crypto revision | ||
| 34 | Titlekek, // f1=crypto revision | ||
| 35 | ETicketRSAKek, // | ||
| 36 | KeyArea, // f1=crypto revision f2=type {app, ocean, system} | ||
| 37 | SDSeed, // | ||
| 38 | Titlekey, // f1=rights id LSB f2=rights id MSB | ||
| 39 | }; | ||
| 40 | |||
| 41 | enum class KeyAreaKeyType : u8 { | ||
| 42 | Application, | ||
| 43 | Ocean, | ||
| 44 | System, | ||
| 45 | }; | ||
| 46 | |||
| 47 | template <typename KeyType> | ||
| 48 | struct KeyIndex { | ||
| 49 | KeyType type; | ||
| 50 | u64 field1; | ||
| 51 | u64 field2; | ||
| 52 | |||
| 53 | std::string DebugInfo() const { | ||
| 54 | u8 key_size = 16; | ||
| 55 | if constexpr (std::is_same_v<KeyType, S256KeyType>) | ||
| 56 | key_size = 32; | ||
| 57 | return fmt::format("key_size={:02X}, key={:02X}, field1={:016X}, field2={:016X}", key_size, | ||
| 58 | static_cast<u8>(type), field1, field2); | ||
| 59 | } | ||
| 60 | }; | ||
| 61 | |||
| 62 | // The following two (== and hash) are so KeyIndex can be a key in unordered_map | ||
| 63 | |||
| 64 | template <typename KeyType> | ||
| 65 | bool operator==(const KeyIndex<KeyType>& lhs, const KeyIndex<KeyType>& rhs) { | ||
| 66 | return std::tie(lhs.type, lhs.field1, lhs.field2) == std::tie(rhs.type, rhs.field1, rhs.field2); | ||
| 67 | } | ||
| 68 | |||
| 69 | template <typename KeyType> | ||
| 70 | bool operator!=(const KeyIndex<KeyType>& lhs, const KeyIndex<KeyType>& rhs) { | ||
| 71 | return !operator==(lhs, rhs); | ||
| 72 | } | ||
| 73 | |||
| 74 | } // namespace Core::Crypto | ||
| 75 | |||
| 76 | namespace std { | ||
| 77 | template <typename KeyType> | ||
| 78 | struct hash<Core::Crypto::KeyIndex<KeyType>> { | ||
| 79 | size_t operator()(const Core::Crypto::KeyIndex<KeyType>& k) const { | ||
| 80 | using std::hash; | ||
| 81 | |||
| 82 | return ((hash<u64>()(static_cast<u64>(k.type)) ^ (hash<u64>()(k.field1) << 1)) >> 1) ^ | ||
| 83 | (hash<u64>()(k.field2) << 1); | ||
| 84 | } | ||
| 85 | }; | ||
| 86 | } // namespace std | ||
| 87 | |||
| 88 | namespace Core::Crypto { | ||
| 89 | |||
| 90 | std::array<u8, 0x10> operator"" _array16(const char* str, size_t len); | ||
| 91 | std::array<u8, 0x20> operator"" _array32(const char* str, size_t len); | ||
| 92 | |||
| 93 | class KeyManager { | ||
| 94 | public: | ||
| 95 | KeyManager(); | ||
| 96 | |||
| 97 | bool HasKey(S128KeyType id, u64 field1 = 0, u64 field2 = 0) const; | ||
| 98 | bool HasKey(S256KeyType id, u64 field1 = 0, u64 field2 = 0) const; | ||
| 99 | |||
| 100 | Key128 GetKey(S128KeyType id, u64 field1 = 0, u64 field2 = 0) const; | ||
| 101 | Key256 GetKey(S256KeyType id, u64 field1 = 0, u64 field2 = 0) const; | ||
| 102 | |||
| 103 | void SetKey(S128KeyType id, Key128 key, u64 field1 = 0, u64 field2 = 0); | ||
| 104 | void SetKey(S256KeyType id, Key256 key, u64 field1 = 0, u64 field2 = 0); | ||
| 105 | |||
| 106 | static bool KeyFileExists(bool title); | ||
| 107 | |||
| 108 | private: | ||
| 109 | std::unordered_map<KeyIndex<S128KeyType>, Key128> s128_keys; | ||
| 110 | std::unordered_map<KeyIndex<S256KeyType>, Key256> s256_keys; | ||
| 111 | |||
| 112 | bool dev_mode; | ||
| 113 | void LoadFromFile(const std::string& filename, bool is_title_keys); | ||
| 114 | void AttemptLoadKeyFile(const std::string& dir1, const std::string& dir2, | ||
| 115 | const std::string& filename, bool title); | ||
| 116 | |||
| 117 | static const std::unordered_map<std::string, KeyIndex<S128KeyType>> s128_file_id; | ||
| 118 | static const std::unordered_map<std::string, KeyIndex<S256KeyType>> s256_file_id; | ||
| 119 | }; | ||
| 120 | } // namespace Core::Crypto | ||
diff --git a/src/core/crypto/sha_util.cpp b/src/core/crypto/sha_util.cpp new file mode 100644 index 000000000..180008a85 --- /dev/null +++ b/src/core/crypto/sha_util.cpp | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | namespace Crypto {} // namespace Crypto | ||
diff --git a/src/core/crypto/sha_util.h b/src/core/crypto/sha_util.h new file mode 100644 index 000000000..fa3fa9d33 --- /dev/null +++ b/src/core/crypto/sha_util.h | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "common/assert.h" | ||
| 8 | #include "core/file_sys/vfs.h" | ||
| 9 | #include "key_manager.h" | ||
| 10 | #include "mbedtls/cipher.h" | ||
| 11 | |||
| 12 | namespace Crypto { | ||
| 13 | typedef std::array<u8, 0x20> SHA256Hash; | ||
| 14 | |||
| 15 | inline SHA256Hash operator"" _HASH(const char* data, size_t len) { | ||
| 16 | if (len != 0x40) | ||
| 17 | return {}; | ||
| 18 | } | ||
| 19 | |||
| 20 | } // namespace Crypto | ||
diff --git a/src/core/file_sys/card_image.cpp b/src/core/file_sys/card_image.cpp new file mode 100644 index 000000000..395eea8ae --- /dev/null +++ b/src/core/file_sys/card_image.cpp | |||
| @@ -0,0 +1,149 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <array> | ||
| 6 | #include <string> | ||
| 7 | #include <core/loader/loader.h> | ||
| 8 | #include "core/file_sys/card_image.h" | ||
| 9 | #include "core/file_sys/partition_filesystem.h" | ||
| 10 | #include "core/file_sys/vfs_offset.h" | ||
| 11 | |||
| 12 | namespace FileSys { | ||
| 13 | |||
| 14 | XCI::XCI(VirtualFile file_) : file(std::move(file_)), partitions(0x4) { | ||
| 15 | if (file->ReadObject(&header) != sizeof(GamecardHeader)) { | ||
| 16 | status = Loader::ResultStatus::ErrorInvalidFormat; | ||
| 17 | return; | ||
| 18 | } | ||
| 19 | |||
| 20 | if (header.magic != Common::MakeMagic('H', 'E', 'A', 'D')) { | ||
| 21 | status = Loader::ResultStatus::ErrorInvalidFormat; | ||
| 22 | return; | ||
| 23 | } | ||
| 24 | |||
| 25 | PartitionFilesystem main_hfs( | ||
| 26 | std::make_shared<OffsetVfsFile>(file, header.hfs_size, header.hfs_offset)); | ||
| 27 | |||
| 28 | if (main_hfs.GetStatus() != Loader::ResultStatus::Success) { | ||
| 29 | status = main_hfs.GetStatus(); | ||
| 30 | return; | ||
| 31 | } | ||
| 32 | |||
| 33 | static constexpr std::array<const char*, 0x4> partition_names = {"update", "normal", "secure", | ||
| 34 | "logo"}; | ||
| 35 | |||
| 36 | for (XCIPartition partition : | ||
| 37 | {XCIPartition::Update, XCIPartition::Normal, XCIPartition::Secure, XCIPartition::Logo}) { | ||
| 38 | auto raw = main_hfs.GetFile(partition_names[static_cast<size_t>(partition)]); | ||
| 39 | if (raw != nullptr) | ||
| 40 | partitions[static_cast<size_t>(partition)] = std::make_shared<PartitionFilesystem>(raw); | ||
| 41 | } | ||
| 42 | |||
| 43 | auto result = AddNCAFromPartition(XCIPartition::Secure); | ||
| 44 | if (result != Loader::ResultStatus::Success) { | ||
| 45 | status = result; | ||
| 46 | return; | ||
| 47 | } | ||
| 48 | |||
| 49 | result = AddNCAFromPartition(XCIPartition::Update); | ||
| 50 | if (result != Loader::ResultStatus::Success) { | ||
| 51 | status = result; | ||
| 52 | return; | ||
| 53 | } | ||
| 54 | |||
| 55 | result = AddNCAFromPartition(XCIPartition::Normal); | ||
| 56 | if (result != Loader::ResultStatus::Success) { | ||
| 57 | status = result; | ||
| 58 | return; | ||
| 59 | } | ||
| 60 | |||
| 61 | if (GetFormatVersion() >= 0x2) { | ||
| 62 | result = AddNCAFromPartition(XCIPartition::Logo); | ||
| 63 | if (result != Loader::ResultStatus::Success) { | ||
| 64 | status = result; | ||
| 65 | return; | ||
| 66 | } | ||
| 67 | } | ||
| 68 | |||
| 69 | status = Loader::ResultStatus::Success; | ||
| 70 | } | ||
| 71 | |||
| 72 | Loader::ResultStatus XCI::GetStatus() const { | ||
| 73 | return status; | ||
| 74 | } | ||
| 75 | |||
| 76 | VirtualDir XCI::GetPartition(XCIPartition partition) const { | ||
| 77 | return partitions[static_cast<size_t>(partition)]; | ||
| 78 | } | ||
| 79 | |||
| 80 | VirtualDir XCI::GetSecurePartition() const { | ||
| 81 | return GetPartition(XCIPartition::Secure); | ||
| 82 | } | ||
| 83 | |||
| 84 | VirtualDir XCI::GetNormalPartition() const { | ||
| 85 | return GetPartition(XCIPartition::Normal); | ||
| 86 | } | ||
| 87 | |||
| 88 | VirtualDir XCI::GetUpdatePartition() const { | ||
| 89 | return GetPartition(XCIPartition::Update); | ||
| 90 | } | ||
| 91 | |||
| 92 | VirtualDir XCI::GetLogoPartition() const { | ||
| 93 | return GetPartition(XCIPartition::Logo); | ||
| 94 | } | ||
| 95 | |||
| 96 | std::shared_ptr<NCA> XCI::GetNCAByType(NCAContentType type) const { | ||
| 97 | const auto iter = | ||
| 98 | std::find_if(ncas.begin(), ncas.end(), | ||
| 99 | [type](const std::shared_ptr<NCA>& nca) { return nca->GetType() == type; }); | ||
| 100 | return iter == ncas.end() ? nullptr : *iter; | ||
| 101 | } | ||
| 102 | |||
| 103 | VirtualFile XCI::GetNCAFileByType(NCAContentType type) const { | ||
| 104 | auto nca = GetNCAByType(type); | ||
| 105 | if (nca != nullptr) | ||
| 106 | return nca->GetBaseFile(); | ||
| 107 | return nullptr; | ||
| 108 | } | ||
| 109 | |||
| 110 | std::vector<std::shared_ptr<VfsFile>> XCI::GetFiles() const { | ||
| 111 | return {}; | ||
| 112 | } | ||
| 113 | |||
| 114 | std::vector<std::shared_ptr<VfsDirectory>> XCI::GetSubdirectories() const { | ||
| 115 | return std::vector<std::shared_ptr<VfsDirectory>>(); | ||
| 116 | } | ||
| 117 | |||
| 118 | std::string XCI::GetName() const { | ||
| 119 | return file->GetName(); | ||
| 120 | } | ||
| 121 | |||
| 122 | std::shared_ptr<VfsDirectory> XCI::GetParentDirectory() const { | ||
| 123 | return file->GetContainingDirectory(); | ||
| 124 | } | ||
| 125 | |||
| 126 | bool XCI::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) { | ||
| 127 | return false; | ||
| 128 | } | ||
| 129 | |||
| 130 | Loader::ResultStatus XCI::AddNCAFromPartition(XCIPartition part) { | ||
| 131 | if (partitions[static_cast<size_t>(part)] == nullptr) { | ||
| 132 | return Loader::ResultStatus::ErrorInvalidFormat; | ||
| 133 | } | ||
| 134 | |||
| 135 | for (const VirtualFile& file : partitions[static_cast<size_t>(part)]->GetFiles()) { | ||
| 136 | if (file->GetExtension() != "nca") | ||
| 137 | continue; | ||
| 138 | auto nca = std::make_shared<NCA>(file); | ||
| 139 | if (nca->GetStatus() == Loader::ResultStatus::Success) | ||
| 140 | ncas.push_back(std::move(nca)); | ||
| 141 | } | ||
| 142 | |||
| 143 | return Loader::ResultStatus::Success; | ||
| 144 | } | ||
| 145 | |||
| 146 | u8 XCI::GetFormatVersion() const { | ||
| 147 | return GetLogoPartition() == nullptr ? 0x1 : 0x2; | ||
| 148 | } | ||
| 149 | } // namespace FileSys | ||
diff --git a/src/core/file_sys/card_image.h b/src/core/file_sys/card_image.h new file mode 100644 index 000000000..e089d737c --- /dev/null +++ b/src/core/file_sys/card_image.h | |||
| @@ -0,0 +1,96 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <array> | ||
| 8 | #include <vector> | ||
| 9 | #include "common/common_types.h" | ||
| 10 | #include "common/swap.h" | ||
| 11 | #include "core/file_sys/content_archive.h" | ||
| 12 | #include "core/file_sys/vfs.h" | ||
| 13 | #include "core/loader/loader.h" | ||
| 14 | |||
| 15 | namespace FileSys { | ||
| 16 | |||
| 17 | enum class GamecardSize : u8 { | ||
| 18 | S_1GB = 0xFA, | ||
| 19 | S_2GB = 0xF8, | ||
| 20 | S_4GB = 0xF0, | ||
| 21 | S_8GB = 0xE0, | ||
| 22 | S_16GB = 0xE1, | ||
| 23 | S_32GB = 0xE2, | ||
| 24 | }; | ||
| 25 | |||
| 26 | struct GamecardInfo { | ||
| 27 | std::array<u8, 0x70> data; | ||
| 28 | }; | ||
| 29 | static_assert(sizeof(GamecardInfo) == 0x70, "GamecardInfo has incorrect size."); | ||
| 30 | |||
| 31 | struct GamecardHeader { | ||
| 32 | std::array<u8, 0x100> signature; | ||
| 33 | u32_le magic; | ||
| 34 | u32_le secure_area_start; | ||
| 35 | u32_le backup_area_start; | ||
| 36 | u8 kek_index; | ||
| 37 | GamecardSize size; | ||
| 38 | u8 header_version; | ||
| 39 | u8 flags; | ||
| 40 | u64_le package_id; | ||
| 41 | u64_le valid_data_end; | ||
| 42 | u128 info_iv; | ||
| 43 | u64_le hfs_offset; | ||
| 44 | u64_le hfs_size; | ||
| 45 | std::array<u8, 0x20> hfs_header_hash; | ||
| 46 | std::array<u8, 0x20> initial_data_hash; | ||
| 47 | u32_le secure_mode_flag; | ||
| 48 | u32_le title_key_flag; | ||
| 49 | u32_le key_flag; | ||
| 50 | u32_le normal_area_end; | ||
| 51 | GamecardInfo info; | ||
| 52 | }; | ||
| 53 | static_assert(sizeof(GamecardHeader) == 0x200, "GamecardHeader has incorrect size."); | ||
| 54 | |||
| 55 | enum class XCIPartition : u8 { Update, Normal, Secure, Logo }; | ||
| 56 | |||
| 57 | class XCI : public ReadOnlyVfsDirectory { | ||
| 58 | public: | ||
| 59 | explicit XCI(VirtualFile file); | ||
| 60 | |||
| 61 | Loader::ResultStatus GetStatus() const; | ||
| 62 | |||
| 63 | u8 GetFormatVersion() const; | ||
| 64 | |||
| 65 | VirtualDir GetPartition(XCIPartition partition) const; | ||
| 66 | VirtualDir GetSecurePartition() const; | ||
| 67 | VirtualDir GetNormalPartition() const; | ||
| 68 | VirtualDir GetUpdatePartition() const; | ||
| 69 | VirtualDir GetLogoPartition() const; | ||
| 70 | |||
| 71 | std::shared_ptr<NCA> GetNCAByType(NCAContentType type) const; | ||
| 72 | VirtualFile GetNCAFileByType(NCAContentType type) const; | ||
| 73 | |||
| 74 | std::vector<std::shared_ptr<VfsFile>> GetFiles() const override; | ||
| 75 | |||
| 76 | std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override; | ||
| 77 | |||
| 78 | std::string GetName() const override; | ||
| 79 | |||
| 80 | std::shared_ptr<VfsDirectory> GetParentDirectory() const override; | ||
| 81 | |||
| 82 | protected: | ||
| 83 | bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override; | ||
| 84 | |||
| 85 | private: | ||
| 86 | Loader::ResultStatus AddNCAFromPartition(XCIPartition part); | ||
| 87 | |||
| 88 | VirtualFile file; | ||
| 89 | GamecardHeader header{}; | ||
| 90 | |||
| 91 | Loader::ResultStatus status; | ||
| 92 | |||
| 93 | std::vector<VirtualDir> partitions; | ||
| 94 | std::vector<std::shared_ptr<NCA>> ncas; | ||
| 95 | }; | ||
| 96 | } // namespace FileSys | ||
diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp index d6b20c047..3529166ac 100644 --- a/src/core/file_sys/content_archive.cpp +++ b/src/core/file_sys/content_archive.cpp | |||
| @@ -4,9 +4,12 @@ | |||
| 4 | 4 | ||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | #include <utility> | 6 | #include <utility> |
| 7 | 7 | #include <boost/optional.hpp> | |
| 8 | #include "common/logging/log.h" | 8 | #include "common/logging/log.h" |
| 9 | #include "core/crypto/aes_util.h" | ||
| 10 | #include "core/crypto/ctr_encryption_layer.h" | ||
| 9 | #include "core/file_sys/content_archive.h" | 11 | #include "core/file_sys/content_archive.h" |
| 12 | #include "core/file_sys/romfs.h" | ||
| 10 | #include "core/file_sys/vfs_offset.h" | 13 | #include "core/file_sys/vfs_offset.h" |
| 11 | #include "core/loader/loader.h" | 14 | #include "core/loader/loader.h" |
| 12 | 15 | ||
| @@ -28,11 +31,19 @@ enum class NCASectionFilesystemType : u8 { | |||
| 28 | struct NCASectionHeaderBlock { | 31 | struct NCASectionHeaderBlock { |
| 29 | INSERT_PADDING_BYTES(3); | 32 | INSERT_PADDING_BYTES(3); |
| 30 | NCASectionFilesystemType filesystem_type; | 33 | NCASectionFilesystemType filesystem_type; |
| 31 | u8 crypto_type; | 34 | NCASectionCryptoType crypto_type; |
| 32 | INSERT_PADDING_BYTES(3); | 35 | INSERT_PADDING_BYTES(3); |
| 33 | }; | 36 | }; |
| 34 | static_assert(sizeof(NCASectionHeaderBlock) == 0x8, "NCASectionHeaderBlock has incorrect size."); | 37 | static_assert(sizeof(NCASectionHeaderBlock) == 0x8, "NCASectionHeaderBlock has incorrect size."); |
| 35 | 38 | ||
| 39 | struct NCASectionRaw { | ||
| 40 | NCASectionHeaderBlock header; | ||
| 41 | std::array<u8, 0x138> block_data; | ||
| 42 | std::array<u8, 0x8> section_ctr; | ||
| 43 | INSERT_PADDING_BYTES(0xB8); | ||
| 44 | }; | ||
| 45 | static_assert(sizeof(NCASectionRaw) == 0x200, "NCASectionRaw has incorrect size."); | ||
| 46 | |||
| 36 | struct PFS0Superblock { | 47 | struct PFS0Superblock { |
| 37 | NCASectionHeaderBlock header_block; | 48 | NCASectionHeaderBlock header_block; |
| 38 | std::array<u8, 0x20> hash; | 49 | std::array<u8, 0x20> hash; |
| @@ -42,79 +53,200 @@ struct PFS0Superblock { | |||
| 42 | u64_le hash_table_size; | 53 | u64_le hash_table_size; |
| 43 | u64_le pfs0_header_offset; | 54 | u64_le pfs0_header_offset; |
| 44 | u64_le pfs0_size; | 55 | u64_le pfs0_size; |
| 45 | INSERT_PADDING_BYTES(432); | 56 | INSERT_PADDING_BYTES(0x1B0); |
| 46 | }; | 57 | }; |
| 47 | static_assert(sizeof(PFS0Superblock) == 0x200, "PFS0Superblock has incorrect size."); | 58 | static_assert(sizeof(PFS0Superblock) == 0x200, "PFS0Superblock has incorrect size."); |
| 48 | 59 | ||
| 49 | struct IVFCLevel { | ||
| 50 | u64_le offset; | ||
| 51 | u64_le size; | ||
| 52 | u32_le block_size; | ||
| 53 | u32_le reserved; | ||
| 54 | }; | ||
| 55 | static_assert(sizeof(IVFCLevel) == 0x18, "IVFCLevel has incorrect size."); | ||
| 56 | |||
| 57 | struct RomFSSuperblock { | 60 | struct RomFSSuperblock { |
| 58 | NCASectionHeaderBlock header_block; | 61 | NCASectionHeaderBlock header_block; |
| 59 | u32_le magic; | 62 | IVFCHeader ivfc; |
| 60 | u32_le magic_number; | 63 | INSERT_PADDING_BYTES(0x118); |
| 61 | INSERT_PADDING_BYTES(8); | ||
| 62 | std::array<IVFCLevel, 6> levels; | ||
| 63 | INSERT_PADDING_BYTES(64); | ||
| 64 | }; | 64 | }; |
| 65 | static_assert(sizeof(RomFSSuperblock) == 0xE8, "RomFSSuperblock has incorrect size."); | 65 | static_assert(sizeof(RomFSSuperblock) == 0x200, "RomFSSuperblock has incorrect size."); |
| 66 | |||
| 67 | union NCASectionHeader { | ||
| 68 | NCASectionRaw raw; | ||
| 69 | PFS0Superblock pfs0; | ||
| 70 | RomFSSuperblock romfs; | ||
| 71 | }; | ||
| 72 | static_assert(sizeof(NCASectionHeader) == 0x200, "NCASectionHeader has incorrect size."); | ||
| 73 | |||
| 74 | bool IsValidNCA(const NCAHeader& header) { | ||
| 75 | // TODO(DarkLordZach): Add NCA2/NCA0 support. | ||
| 76 | return header.magic == Common::MakeMagic('N', 'C', 'A', '3'); | ||
| 77 | } | ||
| 78 | |||
| 79 | u8 NCA::GetCryptoRevision() const { | ||
| 80 | u8 master_key_id = header.crypto_type; | ||
| 81 | if (header.crypto_type_2 > master_key_id) | ||
| 82 | master_key_id = header.crypto_type_2; | ||
| 83 | if (master_key_id > 0) | ||
| 84 | --master_key_id; | ||
| 85 | return master_key_id; | ||
| 86 | } | ||
| 87 | |||
| 88 | boost::optional<Core::Crypto::Key128> NCA::GetKeyAreaKey(NCASectionCryptoType type) const { | ||
| 89 | const auto master_key_id = GetCryptoRevision(); | ||
| 90 | |||
| 91 | if (!keys.HasKey(Core::Crypto::S128KeyType::KeyArea, master_key_id, header.key_index)) | ||
| 92 | return boost::none; | ||
| 93 | |||
| 94 | std::vector<u8> key_area(header.key_area.begin(), header.key_area.end()); | ||
| 95 | Core::Crypto::AESCipher<Core::Crypto::Key128> cipher( | ||
| 96 | keys.GetKey(Core::Crypto::S128KeyType::KeyArea, master_key_id, header.key_index), | ||
| 97 | Core::Crypto::Mode::ECB); | ||
| 98 | cipher.Transcode(key_area.data(), key_area.size(), key_area.data(), Core::Crypto::Op::Decrypt); | ||
| 99 | |||
| 100 | Core::Crypto::Key128 out; | ||
| 101 | if (type == NCASectionCryptoType::XTS) | ||
| 102 | std::copy(key_area.begin(), key_area.begin() + 0x10, out.begin()); | ||
| 103 | else if (type == NCASectionCryptoType::CTR) | ||
| 104 | std::copy(key_area.begin() + 0x20, key_area.begin() + 0x30, out.begin()); | ||
| 105 | else | ||
| 106 | LOG_CRITICAL(Crypto, "Called GetKeyAreaKey on invalid NCASectionCryptoType type={:02X}", | ||
| 107 | static_cast<u8>(type)); | ||
| 108 | u128 out_128{}; | ||
| 109 | memcpy(out_128.data(), out.data(), 16); | ||
| 110 | LOG_DEBUG(Crypto, "called with crypto_rev={:02X}, kak_index={:02X}, key={:016X}{:016X}", | ||
| 111 | master_key_id, header.key_index, out_128[1], out_128[0]); | ||
| 112 | |||
| 113 | return out; | ||
| 114 | } | ||
| 115 | |||
| 116 | boost::optional<Core::Crypto::Key128> NCA::GetTitlekey() const { | ||
| 117 | const auto master_key_id = GetCryptoRevision(); | ||
| 118 | |||
| 119 | u128 rights_id{}; | ||
| 120 | memcpy(rights_id.data(), header.rights_id.data(), 16); | ||
| 121 | if (rights_id == u128{}) | ||
| 122 | return boost::none; | ||
| 123 | |||
| 124 | auto titlekey = keys.GetKey(Core::Crypto::S128KeyType::Titlekey, rights_id[1], rights_id[0]); | ||
| 125 | if (titlekey == Core::Crypto::Key128{}) | ||
| 126 | return boost::none; | ||
| 127 | Core::Crypto::AESCipher<Core::Crypto::Key128> cipher( | ||
| 128 | keys.GetKey(Core::Crypto::S128KeyType::Titlekek, master_key_id), Core::Crypto::Mode::ECB); | ||
| 129 | cipher.Transcode(titlekey.data(), titlekey.size(), titlekey.data(), Core::Crypto::Op::Decrypt); | ||
| 130 | |||
| 131 | return titlekey; | ||
| 132 | } | ||
| 133 | |||
| 134 | VirtualFile NCA::Decrypt(NCASectionHeader s_header, VirtualFile in, u64 starting_offset) const { | ||
| 135 | if (!encrypted) | ||
| 136 | return in; | ||
| 137 | |||
| 138 | switch (s_header.raw.header.crypto_type) { | ||
| 139 | case NCASectionCryptoType::NONE: | ||
| 140 | LOG_DEBUG(Crypto, "called with mode=NONE"); | ||
| 141 | return in; | ||
| 142 | case NCASectionCryptoType::CTR: | ||
| 143 | LOG_DEBUG(Crypto, "called with mode=CTR, starting_offset={:016X}", starting_offset); | ||
| 144 | { | ||
| 145 | boost::optional<Core::Crypto::Key128> key = boost::none; | ||
| 146 | if (std::find_if_not(header.rights_id.begin(), header.rights_id.end(), | ||
| 147 | [](char c) { return c == 0; }) == header.rights_id.end()) { | ||
| 148 | key = GetKeyAreaKey(NCASectionCryptoType::CTR); | ||
| 149 | } else { | ||
| 150 | key = GetTitlekey(); | ||
| 151 | } | ||
| 152 | |||
| 153 | if (key == boost::none) | ||
| 154 | return nullptr; | ||
| 155 | auto out = std::make_shared<Core::Crypto::CTREncryptionLayer>( | ||
| 156 | std::move(in), key.value(), starting_offset); | ||
| 157 | std::vector<u8> iv(16); | ||
| 158 | for (u8 i = 0; i < 8; ++i) | ||
| 159 | iv[i] = s_header.raw.section_ctr[0x8 - i - 1]; | ||
| 160 | out->SetIV(iv); | ||
| 161 | return std::static_pointer_cast<VfsFile>(out); | ||
| 162 | } | ||
| 163 | case NCASectionCryptoType::XTS: | ||
| 164 | // TODO(DarkLordZach): Implement XTSEncryptionLayer. | ||
| 165 | default: | ||
| 166 | LOG_ERROR(Crypto, "called with unhandled crypto type={:02X}", | ||
| 167 | static_cast<u8>(s_header.raw.header.crypto_type)); | ||
| 168 | return nullptr; | ||
| 169 | } | ||
| 170 | } | ||
| 66 | 171 | ||
| 67 | NCA::NCA(VirtualFile file_) : file(std::move(file_)) { | 172 | NCA::NCA(VirtualFile file_) : file(std::move(file_)) { |
| 68 | if (sizeof(NCAHeader) != file->ReadObject(&header)) | 173 | if (sizeof(NCAHeader) != file->ReadObject(&header)) |
| 69 | LOG_CRITICAL(Loader, "File reader errored out during header read."); | 174 | LOG_ERROR(Loader, "File reader errored out during header read."); |
| 175 | |||
| 176 | encrypted = false; | ||
| 70 | 177 | ||
| 71 | if (!IsValidNCA(header)) { | 178 | if (!IsValidNCA(header)) { |
| 72 | status = Loader::ResultStatus::ErrorInvalidFormat; | 179 | NCAHeader dec_header{}; |
| 73 | return; | 180 | Core::Crypto::AESCipher<Core::Crypto::Key256> cipher( |
| 181 | keys.GetKey(Core::Crypto::S256KeyType::Header), Core::Crypto::Mode::XTS); | ||
| 182 | cipher.XTSTranscode(&header, sizeof(NCAHeader), &dec_header, 0, 0x200, | ||
| 183 | Core::Crypto::Op::Decrypt); | ||
| 184 | if (IsValidNCA(dec_header)) { | ||
| 185 | header = dec_header; | ||
| 186 | encrypted = true; | ||
| 187 | } else { | ||
| 188 | if (!keys.HasKey(Core::Crypto::S256KeyType::Header)) | ||
| 189 | status = Loader::ResultStatus::ErrorMissingKeys; | ||
| 190 | else | ||
| 191 | status = Loader::ResultStatus::ErrorDecrypting; | ||
| 192 | return; | ||
| 193 | } | ||
| 74 | } | 194 | } |
| 75 | 195 | ||
| 76 | std::ptrdiff_t number_sections = | 196 | const std::ptrdiff_t number_sections = |
| 77 | std::count_if(std::begin(header.section_tables), std::end(header.section_tables), | 197 | std::count_if(std::begin(header.section_tables), std::end(header.section_tables), |
| 78 | [](NCASectionTableEntry entry) { return entry.media_offset > 0; }); | 198 | [](NCASectionTableEntry entry) { return entry.media_offset > 0; }); |
| 79 | 199 | ||
| 200 | std::vector<NCASectionHeader> sections(number_sections); | ||
| 201 | const auto length_sections = SECTION_HEADER_SIZE * number_sections; | ||
| 202 | |||
| 203 | if (encrypted) { | ||
| 204 | auto raw = file->ReadBytes(length_sections, SECTION_HEADER_OFFSET); | ||
| 205 | Core::Crypto::AESCipher<Core::Crypto::Key256> cipher( | ||
| 206 | keys.GetKey(Core::Crypto::S256KeyType::Header), Core::Crypto::Mode::XTS); | ||
| 207 | cipher.XTSTranscode(raw.data(), length_sections, sections.data(), 2, SECTION_HEADER_SIZE, | ||
| 208 | Core::Crypto::Op::Decrypt); | ||
| 209 | } else { | ||
| 210 | file->ReadBytes(sections.data(), length_sections, SECTION_HEADER_OFFSET); | ||
| 211 | } | ||
| 212 | |||
| 80 | for (std::ptrdiff_t i = 0; i < number_sections; ++i) { | 213 | for (std::ptrdiff_t i = 0; i < number_sections; ++i) { |
| 81 | // Seek to beginning of this section. | 214 | auto section = sections[i]; |
| 82 | NCASectionHeaderBlock block{}; | ||
| 83 | if (sizeof(NCASectionHeaderBlock) != | ||
| 84 | file->ReadObject(&block, SECTION_HEADER_OFFSET + i * SECTION_HEADER_SIZE)) | ||
| 85 | LOG_CRITICAL(Loader, "File reader errored out during header read."); | ||
| 86 | |||
| 87 | if (block.filesystem_type == NCASectionFilesystemType::ROMFS) { | ||
| 88 | RomFSSuperblock sb{}; | ||
| 89 | if (sizeof(RomFSSuperblock) != | ||
| 90 | file->ReadObject(&sb, SECTION_HEADER_OFFSET + i * SECTION_HEADER_SIZE)) | ||
| 91 | LOG_CRITICAL(Loader, "File reader errored out during header read."); | ||
| 92 | 215 | ||
| 216 | if (section.raw.header.filesystem_type == NCASectionFilesystemType::ROMFS) { | ||
| 93 | const size_t romfs_offset = | 217 | const size_t romfs_offset = |
| 94 | header.section_tables[i].media_offset * MEDIA_OFFSET_MULTIPLIER + | 218 | header.section_tables[i].media_offset * MEDIA_OFFSET_MULTIPLIER + |
| 95 | sb.levels[IVFC_MAX_LEVEL - 1].offset; | 219 | section.romfs.ivfc.levels[IVFC_MAX_LEVEL - 1].offset; |
| 96 | const size_t romfs_size = sb.levels[IVFC_MAX_LEVEL - 1].size; | 220 | const size_t romfs_size = section.romfs.ivfc.levels[IVFC_MAX_LEVEL - 1].size; |
| 97 | files.emplace_back(std::make_shared<OffsetVfsFile>(file, romfs_size, romfs_offset)); | 221 | auto dec = |
| 98 | romfs = files.back(); | 222 | Decrypt(section, std::make_shared<OffsetVfsFile>(file, romfs_size, romfs_offset), |
| 99 | } else if (block.filesystem_type == NCASectionFilesystemType::PFS0) { | 223 | romfs_offset); |
| 100 | PFS0Superblock sb{}; | 224 | if (dec != nullptr) { |
| 101 | // Seek back to beginning of this section. | 225 | files.push_back(std::move(dec)); |
| 102 | if (sizeof(PFS0Superblock) != | 226 | romfs = files.back(); |
| 103 | file->ReadObject(&sb, SECTION_HEADER_OFFSET + i * SECTION_HEADER_SIZE)) | 227 | } else { |
| 104 | LOG_CRITICAL(Loader, "File reader errored out during header read."); | 228 | status = Loader::ResultStatus::ErrorMissingKeys; |
| 105 | 229 | return; | |
| 230 | } | ||
| 231 | } else if (section.raw.header.filesystem_type == NCASectionFilesystemType::PFS0) { | ||
| 106 | u64 offset = (static_cast<u64>(header.section_tables[i].media_offset) * | 232 | u64 offset = (static_cast<u64>(header.section_tables[i].media_offset) * |
| 107 | MEDIA_OFFSET_MULTIPLIER) + | 233 | MEDIA_OFFSET_MULTIPLIER) + |
| 108 | sb.pfs0_header_offset; | 234 | section.pfs0.pfs0_header_offset; |
| 109 | u64 size = MEDIA_OFFSET_MULTIPLIER * (header.section_tables[i].media_end_offset - | 235 | u64 size = MEDIA_OFFSET_MULTIPLIER * (header.section_tables[i].media_end_offset - |
| 110 | header.section_tables[i].media_offset); | 236 | header.section_tables[i].media_offset); |
| 111 | auto npfs = std::make_shared<PartitionFilesystem>( | 237 | auto dec = |
| 112 | std::make_shared<OffsetVfsFile>(file, size, offset)); | 238 | Decrypt(section, std::make_shared<OffsetVfsFile>(file, size, offset), offset); |
| 239 | if (dec != nullptr) { | ||
| 240 | auto npfs = std::make_shared<PartitionFilesystem>(std::move(dec)); | ||
| 113 | 241 | ||
| 114 | if (npfs->GetStatus() == Loader::ResultStatus::Success) { | 242 | if (npfs->GetStatus() == Loader::ResultStatus::Success) { |
| 115 | dirs.emplace_back(npfs); | 243 | dirs.push_back(std::move(npfs)); |
| 116 | if (IsDirectoryExeFS(dirs.back())) | 244 | if (IsDirectoryExeFS(dirs.back())) |
| 117 | exefs = dirs.back(); | 245 | exefs = dirs.back(); |
| 246 | } | ||
| 247 | } else { | ||
| 248 | status = Loader::ResultStatus::ErrorMissingKeys; | ||
| 249 | return; | ||
| 118 | } | 250 | } |
| 119 | } | 251 | } |
| 120 | } | 252 | } |
| @@ -164,6 +296,10 @@ VirtualDir NCA::GetExeFS() const { | |||
| 164 | return exefs; | 296 | return exefs; |
| 165 | } | 297 | } |
| 166 | 298 | ||
| 299 | VirtualFile NCA::GetBaseFile() const { | ||
| 300 | return file; | ||
| 301 | } | ||
| 302 | |||
| 167 | bool NCA::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) { | 303 | bool NCA::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) { |
| 168 | return false; | 304 | return false; |
| 169 | } | 305 | } |
diff --git a/src/core/file_sys/content_archive.h b/src/core/file_sys/content_archive.h index 0b8b9db61..a8879d9a8 100644 --- a/src/core/file_sys/content_archive.h +++ b/src/core/file_sys/content_archive.h | |||
| @@ -8,14 +8,18 @@ | |||
| 8 | #include <memory> | 8 | #include <memory> |
| 9 | #include <string> | 9 | #include <string> |
| 10 | #include <vector> | 10 | #include <vector> |
| 11 | 11 | #include <boost/optional.hpp> | |
| 12 | #include "common/common_funcs.h" | 12 | #include "common/common_funcs.h" |
| 13 | #include "common/common_types.h" | 13 | #include "common/common_types.h" |
| 14 | #include "common/swap.h" | 14 | #include "common/swap.h" |
| 15 | #include "core/crypto/key_manager.h" | ||
| 15 | #include "core/file_sys/partition_filesystem.h" | 16 | #include "core/file_sys/partition_filesystem.h" |
| 17 | #include "core/loader/loader.h" | ||
| 16 | 18 | ||
| 17 | namespace FileSys { | 19 | namespace FileSys { |
| 18 | 20 | ||
| 21 | union NCASectionHeader; | ||
| 22 | |||
| 19 | enum class NCAContentType : u8 { | 23 | enum class NCAContentType : u8 { |
| 20 | Program = 0, | 24 | Program = 0, |
| 21 | Meta = 1, | 25 | Meta = 1, |
| @@ -24,6 +28,13 @@ enum class NCAContentType : u8 { | |||
| 24 | Data = 4, | 28 | Data = 4, |
| 25 | }; | 29 | }; |
| 26 | 30 | ||
| 31 | enum class NCASectionCryptoType : u8 { | ||
| 32 | NONE = 1, | ||
| 33 | XTS = 2, | ||
| 34 | CTR = 3, | ||
| 35 | BKTR = 4, | ||
| 36 | }; | ||
| 37 | |||
| 27 | struct NCASectionTableEntry { | 38 | struct NCASectionTableEntry { |
| 28 | u32_le media_offset; | 39 | u32_le media_offset; |
| 29 | u32_le media_end_offset; | 40 | u32_le media_end_offset; |
| @@ -48,7 +59,7 @@ struct NCAHeader { | |||
| 48 | std::array<u8, 0x10> rights_id; | 59 | std::array<u8, 0x10> rights_id; |
| 49 | std::array<NCASectionTableEntry, 0x4> section_tables; | 60 | std::array<NCASectionTableEntry, 0x4> section_tables; |
| 50 | std::array<std::array<u8, 0x20>, 0x4> hash_tables; | 61 | std::array<std::array<u8, 0x20>, 0x4> hash_tables; |
| 51 | std::array<std::array<u8, 0x10>, 0x4> key_area; | 62 | std::array<u8, 0x40> key_area; |
| 52 | INSERT_PADDING_BYTES(0xC0); | 63 | INSERT_PADDING_BYTES(0xC0); |
| 53 | }; | 64 | }; |
| 54 | static_assert(sizeof(NCAHeader) == 0x400, "NCAHeader has incorrect size."); | 65 | static_assert(sizeof(NCAHeader) == 0x400, "NCAHeader has incorrect size."); |
| @@ -58,10 +69,7 @@ inline bool IsDirectoryExeFS(const std::shared_ptr<VfsDirectory>& pfs) { | |||
| 58 | return pfs->GetFile("main") != nullptr && pfs->GetFile("main.npdm") != nullptr; | 69 | return pfs->GetFile("main") != nullptr && pfs->GetFile("main.npdm") != nullptr; |
| 59 | } | 70 | } |
| 60 | 71 | ||
| 61 | inline bool IsValidNCA(const NCAHeader& header) { | 72 | bool IsValidNCA(const NCAHeader& header); |
| 62 | return header.magic == Common::MakeMagic('N', 'C', 'A', '2') || | ||
| 63 | header.magic == Common::MakeMagic('N', 'C', 'A', '3'); | ||
| 64 | } | ||
| 65 | 73 | ||
| 66 | // An implementation of VfsDirectory that represents a Nintendo Content Archive (NCA) conatiner. | 74 | // An implementation of VfsDirectory that represents a Nintendo Content Archive (NCA) conatiner. |
| 67 | // After construction, use GetStatus to determine if the file is valid and ready to be used. | 75 | // After construction, use GetStatus to determine if the file is valid and ready to be used. |
| @@ -81,10 +89,17 @@ public: | |||
| 81 | VirtualFile GetRomFS() const; | 89 | VirtualFile GetRomFS() const; |
| 82 | VirtualDir GetExeFS() const; | 90 | VirtualDir GetExeFS() const; |
| 83 | 91 | ||
| 92 | VirtualFile GetBaseFile() const; | ||
| 93 | |||
| 84 | protected: | 94 | protected: |
| 85 | bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override; | 95 | bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override; |
| 86 | 96 | ||
| 87 | private: | 97 | private: |
| 98 | u8 GetCryptoRevision() const; | ||
| 99 | boost::optional<Core::Crypto::Key128> GetKeyAreaKey(NCASectionCryptoType type) const; | ||
| 100 | boost::optional<Core::Crypto::Key128> GetTitlekey() const; | ||
| 101 | VirtualFile Decrypt(NCASectionHeader header, VirtualFile in, u64 starting_offset) const; | ||
| 102 | |||
| 88 | std::vector<VirtualDir> dirs; | 103 | std::vector<VirtualDir> dirs; |
| 89 | std::vector<VirtualFile> files; | 104 | std::vector<VirtualFile> files; |
| 90 | 105 | ||
| @@ -95,6 +110,10 @@ private: | |||
| 95 | NCAHeader header{}; | 110 | NCAHeader header{}; |
| 96 | 111 | ||
| 97 | Loader::ResultStatus status{}; | 112 | Loader::ResultStatus status{}; |
| 113 | |||
| 114 | bool encrypted; | ||
| 115 | |||
| 116 | Core::Crypto::KeyManager keys; | ||
| 98 | }; | 117 | }; |
| 99 | 118 | ||
| 100 | } // namespace FileSys | 119 | } // namespace FileSys |
diff --git a/src/core/file_sys/partition_filesystem.cpp b/src/core/file_sys/partition_filesystem.cpp index 521e21078..47e032b19 100644 --- a/src/core/file_sys/partition_filesystem.cpp +++ b/src/core/file_sys/partition_filesystem.cpp | |||
| @@ -97,9 +97,8 @@ void PartitionFilesystem::PrintDebugInfo() const { | |||
| 97 | LOG_DEBUG(Service_FS, "Magic: {:.4}", pfs_header.magic); | 97 | LOG_DEBUG(Service_FS, "Magic: {:.4}", pfs_header.magic); |
| 98 | LOG_DEBUG(Service_FS, "Files: {}", pfs_header.num_entries); | 98 | LOG_DEBUG(Service_FS, "Files: {}", pfs_header.num_entries); |
| 99 | for (u32 i = 0; i < pfs_header.num_entries; i++) { | 99 | for (u32 i = 0; i < pfs_header.num_entries; i++) { |
| 100 | LOG_DEBUG(Service_FS, " > File {}: {} (0x{:X} bytes, at 0x{:X})", i, | 100 | LOG_DEBUG(Service_FS, " > File {}: {} (0x{:X} bytes)", i, |
| 101 | pfs_files[i]->GetName(), pfs_files[i]->GetSize(), | 101 | pfs_files[i]->GetName(), pfs_files[i]->GetSize()); |
| 102 | dynamic_cast<OffsetVfsFile*>(pfs_files[i].get())->GetOffset()); | ||
| 103 | } | 102 | } |
| 104 | } | 103 | } |
| 105 | 104 | ||
diff --git a/src/core/file_sys/romfs.cpp b/src/core/file_sys/romfs.cpp new file mode 100644 index 000000000..ff3ddb29c --- /dev/null +++ b/src/core/file_sys/romfs.cpp | |||
| @@ -0,0 +1,124 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/common_types.h" | ||
| 6 | #include "common/swap.h" | ||
| 7 | #include "core/file_sys/romfs.h" | ||
| 8 | #include "core/file_sys/vfs.h" | ||
| 9 | #include "core/file_sys/vfs_offset.h" | ||
| 10 | #include "core/file_sys/vfs_vector.h" | ||
| 11 | |||
| 12 | namespace FileSys { | ||
| 13 | |||
| 14 | constexpr u32 ROMFS_ENTRY_EMPTY = 0xFFFFFFFF; | ||
| 15 | |||
| 16 | struct TableLocation { | ||
| 17 | u64_le offset; | ||
| 18 | u64_le size; | ||
| 19 | }; | ||
| 20 | static_assert(sizeof(TableLocation) == 0x10, "TableLocation has incorrect size."); | ||
| 21 | |||
| 22 | struct RomFSHeader { | ||
| 23 | u64_le header_size; | ||
| 24 | TableLocation directory_hash; | ||
| 25 | TableLocation directory_meta; | ||
| 26 | TableLocation file_hash; | ||
| 27 | TableLocation file_meta; | ||
| 28 | u64_le data_offset; | ||
| 29 | }; | ||
| 30 | static_assert(sizeof(RomFSHeader) == 0x50, "RomFSHeader has incorrect size."); | ||
| 31 | |||
| 32 | struct DirectoryEntry { | ||
| 33 | u32_le sibling; | ||
| 34 | u32_le child_dir; | ||
| 35 | u32_le child_file; | ||
| 36 | u32_le hash; | ||
| 37 | u32_le name_length; | ||
| 38 | }; | ||
| 39 | static_assert(sizeof(DirectoryEntry) == 0x14, "DirectoryEntry has incorrect size."); | ||
| 40 | |||
| 41 | struct FileEntry { | ||
| 42 | u32_le parent; | ||
| 43 | u32_le sibling; | ||
| 44 | u64_le offset; | ||
| 45 | u64_le size; | ||
| 46 | u32_le hash; | ||
| 47 | u32_le name_length; | ||
| 48 | }; | ||
| 49 | static_assert(sizeof(FileEntry) == 0x20, "FileEntry has incorrect size."); | ||
| 50 | |||
| 51 | template <typename Entry> | ||
| 52 | static std::pair<Entry, std::string> GetEntry(const VirtualFile& file, size_t offset) { | ||
| 53 | Entry entry{}; | ||
| 54 | if (file->ReadObject(&entry, offset) != sizeof(Entry)) | ||
| 55 | return {}; | ||
| 56 | std::string string(entry.name_length, '\0'); | ||
| 57 | if (file->ReadArray(&string[0], string.size(), offset + sizeof(Entry)) != string.size()) | ||
| 58 | return {}; | ||
| 59 | return {entry, string}; | ||
| 60 | } | ||
| 61 | |||
| 62 | void ProcessFile(VirtualFile file, size_t file_offset, size_t data_offset, u32 this_file_offset, | ||
| 63 | std::shared_ptr<VectorVfsDirectory> parent) { | ||
| 64 | while (true) { | ||
| 65 | auto entry = GetEntry<FileEntry>(file, file_offset + this_file_offset); | ||
| 66 | |||
| 67 | parent->AddFile(std::make_shared<OffsetVfsFile>( | ||
| 68 | file, entry.first.size, entry.first.offset + data_offset, entry.second, parent)); | ||
| 69 | |||
| 70 | if (entry.first.sibling == ROMFS_ENTRY_EMPTY) | ||
| 71 | break; | ||
| 72 | |||
| 73 | this_file_offset = entry.first.sibling; | ||
| 74 | } | ||
| 75 | } | ||
| 76 | |||
| 77 | void ProcessDirectory(VirtualFile file, size_t dir_offset, size_t file_offset, size_t data_offset, | ||
| 78 | u32 this_dir_offset, std::shared_ptr<VectorVfsDirectory> parent) { | ||
| 79 | while (true) { | ||
| 80 | auto entry = GetEntry<DirectoryEntry>(file, dir_offset + this_dir_offset); | ||
| 81 | auto current = std::make_shared<VectorVfsDirectory>( | ||
| 82 | std::vector<VirtualFile>{}, std::vector<VirtualDir>{}, parent, entry.second); | ||
| 83 | |||
| 84 | if (entry.first.child_file != ROMFS_ENTRY_EMPTY) { | ||
| 85 | ProcessFile(file, file_offset, data_offset, entry.first.child_file, current); | ||
| 86 | } | ||
| 87 | |||
| 88 | if (entry.first.child_dir != ROMFS_ENTRY_EMPTY) { | ||
| 89 | ProcessDirectory(file, dir_offset, file_offset, data_offset, entry.first.child_dir, | ||
| 90 | current); | ||
| 91 | } | ||
| 92 | |||
| 93 | parent->AddDirectory(current); | ||
| 94 | if (entry.first.sibling == ROMFS_ENTRY_EMPTY) | ||
| 95 | break; | ||
| 96 | this_dir_offset = entry.first.sibling; | ||
| 97 | } | ||
| 98 | } | ||
| 99 | |||
| 100 | VirtualDir ExtractRomFS(VirtualFile file) { | ||
| 101 | RomFSHeader header{}; | ||
| 102 | if (file->ReadObject(&header) != sizeof(RomFSHeader)) | ||
| 103 | return nullptr; | ||
| 104 | |||
| 105 | if (header.header_size != sizeof(RomFSHeader)) | ||
| 106 | return nullptr; | ||
| 107 | |||
| 108 | const u64 file_offset = header.file_meta.offset; | ||
| 109 | const u64 dir_offset = header.directory_meta.offset + 4; | ||
| 110 | |||
| 111 | const auto root = | ||
| 112 | std::make_shared<VectorVfsDirectory>(std::vector<VirtualFile>{}, std::vector<VirtualDir>{}, | ||
| 113 | file->GetContainingDirectory(), file->GetName()); | ||
| 114 | |||
| 115 | ProcessDirectory(file, dir_offset, file_offset, header.data_offset, 0, root); | ||
| 116 | |||
| 117 | VirtualDir out = std::move(root); | ||
| 118 | |||
| 119 | while (out->GetSubdirectory("") != nullptr) | ||
| 120 | out = out->GetSubdirectory(""); | ||
| 121 | |||
| 122 | return out; | ||
| 123 | } | ||
| 124 | } // namespace FileSys | ||
diff --git a/src/core/file_sys/romfs.h b/src/core/file_sys/romfs.h new file mode 100644 index 000000000..03a876d22 --- /dev/null +++ b/src/core/file_sys/romfs.h | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <array> | ||
| 8 | #include "common/common_funcs.h" | ||
| 9 | #include "common/swap.h" | ||
| 10 | #include "core/file_sys/vfs.h" | ||
| 11 | |||
| 12 | namespace FileSys { | ||
| 13 | |||
| 14 | struct IVFCLevel { | ||
| 15 | u64_le offset; | ||
| 16 | u64_le size; | ||
| 17 | u32_le block_size; | ||
| 18 | u32_le reserved; | ||
| 19 | }; | ||
| 20 | static_assert(sizeof(IVFCLevel) == 0x18, "IVFCLevel has incorrect size."); | ||
| 21 | |||
| 22 | struct IVFCHeader { | ||
| 23 | u32_le magic; | ||
| 24 | u32_le magic_number; | ||
| 25 | INSERT_PADDING_BYTES(8); | ||
| 26 | std::array<IVFCLevel, 6> levels; | ||
| 27 | INSERT_PADDING_BYTES(64); | ||
| 28 | }; | ||
| 29 | static_assert(sizeof(IVFCHeader) == 0xE0, "IVFCHeader has incorrect size."); | ||
| 30 | |||
| 31 | // Converts a RomFS binary blob to VFS Filesystem | ||
| 32 | // Returns nullptr on failure | ||
| 33 | VirtualDir ExtractRomFS(VirtualFile file); | ||
| 34 | |||
| 35 | } // namespace FileSys | ||
diff --git a/src/core/file_sys/vfs.cpp b/src/core/file_sys/vfs.cpp index b99a4fd5b..dae1c16ef 100644 --- a/src/core/file_sys/vfs.cpp +++ b/src/core/file_sys/vfs.cpp | |||
| @@ -46,6 +46,13 @@ size_t VfsFile::WriteBytes(const std::vector<u8>& data, size_t offset) { | |||
| 46 | return Write(data.data(), data.size(), offset); | 46 | return Write(data.data(), data.size(), offset); |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | std::string VfsFile::GetFullPath() const { | ||
| 50 | if (GetContainingDirectory() == nullptr) | ||
| 51 | return "/" + GetName(); | ||
| 52 | |||
| 53 | return GetContainingDirectory()->GetFullPath() + "/" + GetName(); | ||
| 54 | } | ||
| 55 | |||
| 49 | std::shared_ptr<VfsFile> VfsDirectory::GetFileRelative(std::string_view path) const { | 56 | std::shared_ptr<VfsFile> VfsDirectory::GetFileRelative(std::string_view path) const { |
| 50 | auto vec = FileUtil::SplitPathComponents(path); | 57 | auto vec = FileUtil::SplitPathComponents(path); |
| 51 | vec.erase(std::remove_if(vec.begin(), vec.end(), [](const auto& str) { return str.empty(); }), | 58 | vec.erase(std::remove_if(vec.begin(), vec.end(), [](const auto& str) { return str.empty(); }), |
| @@ -243,6 +250,13 @@ bool VfsDirectory::Copy(std::string_view src, std::string_view dest) { | |||
| 243 | return f2->WriteBytes(f1->ReadAllBytes()) == f1->GetSize(); | 250 | return f2->WriteBytes(f1->ReadAllBytes()) == f1->GetSize(); |
| 244 | } | 251 | } |
| 245 | 252 | ||
| 253 | std::string VfsDirectory::GetFullPath() const { | ||
| 254 | if (IsRoot()) | ||
| 255 | return GetName(); | ||
| 256 | |||
| 257 | return GetParentDirectory()->GetFullPath() + "/" + GetName(); | ||
| 258 | } | ||
| 259 | |||
| 246 | bool ReadOnlyVfsDirectory::IsWritable() const { | 260 | bool ReadOnlyVfsDirectory::IsWritable() const { |
| 247 | return false; | 261 | return false; |
| 248 | } | 262 | } |
| @@ -270,4 +284,33 @@ bool ReadOnlyVfsDirectory::DeleteFile(std::string_view name) { | |||
| 270 | bool ReadOnlyVfsDirectory::Rename(std::string_view name) { | 284 | bool ReadOnlyVfsDirectory::Rename(std::string_view name) { |
| 271 | return false; | 285 | return false; |
| 272 | } | 286 | } |
| 287 | |||
| 288 | bool DeepEquals(const VirtualFile& file1, const VirtualFile& file2, size_t block_size) { | ||
| 289 | if (file1->GetSize() != file2->GetSize()) | ||
| 290 | return false; | ||
| 291 | |||
| 292 | std::vector<u8> f1_v(block_size); | ||
| 293 | std::vector<u8> f2_v(block_size); | ||
| 294 | for (size_t i = 0; i < file1->GetSize(); i += block_size) { | ||
| 295 | auto f1_vs = file1->Read(f1_v.data(), block_size, i); | ||
| 296 | auto f2_vs = file2->Read(f2_v.data(), block_size, i); | ||
| 297 | |||
| 298 | if (f1_vs != f2_vs) | ||
| 299 | return false; | ||
| 300 | auto iters = std::mismatch(f1_v.begin(), f1_v.end(), f2_v.begin(), f2_v.end()); | ||
| 301 | if (iters.first != f1_v.end() && iters.second != f2_v.end()) | ||
| 302 | return false; | ||
| 303 | } | ||
| 304 | |||
| 305 | return true; | ||
| 306 | } | ||
| 307 | |||
| 308 | bool VfsRawCopy(VirtualFile src, VirtualFile dest) { | ||
| 309 | if (src == nullptr || dest == nullptr) | ||
| 310 | return false; | ||
| 311 | if (!dest->Resize(src->GetSize())) | ||
| 312 | return false; | ||
| 313 | std::vector<u8> data = src->ReadAllBytes(); | ||
| 314 | return dest->WriteBytes(data, 0) == data.size(); | ||
| 315 | } | ||
| 273 | } // namespace FileSys | 316 | } // namespace FileSys |
diff --git a/src/core/file_sys/vfs.h b/src/core/file_sys/vfs.h index 4a13b8378..fab9e2b45 100644 --- a/src/core/file_sys/vfs.h +++ b/src/core/file_sys/vfs.h | |||
| @@ -113,6 +113,9 @@ struct VfsFile : NonCopyable { | |||
| 113 | 113 | ||
| 114 | // Renames the file to name. Returns whether or not the operation was successsful. | 114 | // Renames the file to name. Returns whether or not the operation was successsful. |
| 115 | virtual bool Rename(std::string_view name) = 0; | 115 | virtual bool Rename(std::string_view name) = 0; |
| 116 | |||
| 117 | // Returns the full path of this file as a string, recursively | ||
| 118 | virtual std::string GetFullPath() const; | ||
| 116 | }; | 119 | }; |
| 117 | 120 | ||
| 118 | // A class representing a directory in an abstract filesystem. | 121 | // A class representing a directory in an abstract filesystem. |
| @@ -213,6 +216,17 @@ struct VfsDirectory : NonCopyable { | |||
| 213 | return ReplaceFileWithSubdirectory(file_p, std::make_shared<Directory>(file_p)); | 216 | return ReplaceFileWithSubdirectory(file_p, std::make_shared<Directory>(file_p)); |
| 214 | } | 217 | } |
| 215 | 218 | ||
| 219 | bool InterpretAsDirectory(const std::function<VirtualDir(VirtualFile)>& function, | ||
| 220 | const std::string& file) { | ||
| 221 | auto file_p = GetFile(file); | ||
| 222 | if (file_p == nullptr) | ||
| 223 | return false; | ||
| 224 | return ReplaceFileWithSubdirectory(file_p, function(file_p)); | ||
| 225 | } | ||
| 226 | |||
| 227 | // Returns the full path of this directory as a string, recursively | ||
| 228 | virtual std::string GetFullPath() const; | ||
| 229 | |||
| 216 | protected: | 230 | protected: |
| 217 | // Backend for InterpretAsDirectory. | 231 | // Backend for InterpretAsDirectory. |
| 218 | // Removes all references to file and adds a reference to dir in the directory's implementation. | 232 | // Removes all references to file and adds a reference to dir in the directory's implementation. |
| @@ -230,4 +244,13 @@ struct ReadOnlyVfsDirectory : public VfsDirectory { | |||
| 230 | bool DeleteFile(std::string_view name) override; | 244 | bool DeleteFile(std::string_view name) override; |
| 231 | bool Rename(std::string_view name) override; | 245 | bool Rename(std::string_view name) override; |
| 232 | }; | 246 | }; |
| 247 | |||
| 248 | // Compare the two files, byte-for-byte, in increments specificed by block_size | ||
| 249 | bool DeepEquals(const VirtualFile& file1, const VirtualFile& file2, size_t block_size = 0x200); | ||
| 250 | |||
| 251 | // A method that copies the raw data between two different implementations of VirtualFile. If you | ||
| 252 | // are using the same implementation, it is probably better to use the Copy method in the parent | ||
| 253 | // directory of src/dest. | ||
| 254 | bool VfsRawCopy(VirtualFile src, VirtualFile dest); | ||
| 255 | |||
| 233 | } // namespace FileSys | 256 | } // namespace FileSys |
diff --git a/src/core/file_sys/vfs_offset.cpp b/src/core/file_sys/vfs_offset.cpp index a40331cef..847cde2f5 100644 --- a/src/core/file_sys/vfs_offset.cpp +++ b/src/core/file_sys/vfs_offset.cpp | |||
| @@ -10,8 +10,9 @@ | |||
| 10 | namespace FileSys { | 10 | namespace FileSys { |
| 11 | 11 | ||
| 12 | OffsetVfsFile::OffsetVfsFile(std::shared_ptr<VfsFile> file_, size_t size_, size_t offset_, | 12 | OffsetVfsFile::OffsetVfsFile(std::shared_ptr<VfsFile> file_, size_t size_, size_t offset_, |
| 13 | std::string name_) | 13 | std::string name_, VirtualDir parent_) |
| 14 | : file(std::move(file_)), offset(offset_), size(size_), name(std::move(name_)) {} | 14 | : file(file_), offset(offset_), size(size_), name(std::move(name_)), |
| 15 | parent(parent_ == nullptr ? file->GetContainingDirectory() : std::move(parent_)) {} | ||
| 15 | 16 | ||
| 16 | std::string OffsetVfsFile::GetName() const { | 17 | std::string OffsetVfsFile::GetName() const { |
| 17 | return name.empty() ? file->GetName() : name; | 18 | return name.empty() ? file->GetName() : name; |
| @@ -35,7 +36,7 @@ bool OffsetVfsFile::Resize(size_t new_size) { | |||
| 35 | } | 36 | } |
| 36 | 37 | ||
| 37 | std::shared_ptr<VfsDirectory> OffsetVfsFile::GetContainingDirectory() const { | 38 | std::shared_ptr<VfsDirectory> OffsetVfsFile::GetContainingDirectory() const { |
| 38 | return file->GetContainingDirectory(); | 39 | return parent; |
| 39 | } | 40 | } |
| 40 | 41 | ||
| 41 | bool OffsetVfsFile::IsWritable() const { | 42 | bool OffsetVfsFile::IsWritable() const { |
diff --git a/src/core/file_sys/vfs_offset.h b/src/core/file_sys/vfs_offset.h index 4f471e3ba..235970dc5 100644 --- a/src/core/file_sys/vfs_offset.h +++ b/src/core/file_sys/vfs_offset.h | |||
| @@ -17,7 +17,7 @@ namespace FileSys { | |||
| 17 | // the size of this wrapper. | 17 | // the size of this wrapper. |
| 18 | struct OffsetVfsFile : public VfsFile { | 18 | struct OffsetVfsFile : public VfsFile { |
| 19 | OffsetVfsFile(std::shared_ptr<VfsFile> file, size_t size, size_t offset = 0, | 19 | OffsetVfsFile(std::shared_ptr<VfsFile> file, size_t size, size_t offset = 0, |
| 20 | std::string new_name = ""); | 20 | std::string new_name = "", VirtualDir new_parent = nullptr); |
| 21 | 21 | ||
| 22 | std::string GetName() const override; | 22 | std::string GetName() const override; |
| 23 | size_t GetSize() const override; | 23 | size_t GetSize() const override; |
| @@ -44,6 +44,7 @@ private: | |||
| 44 | size_t offset; | 44 | size_t offset; |
| 45 | size_t size; | 45 | size_t size; |
| 46 | std::string name; | 46 | std::string name; |
| 47 | VirtualDir parent; | ||
| 47 | }; | 48 | }; |
| 48 | 49 | ||
| 49 | } // namespace FileSys | 50 | } // namespace FileSys |
diff --git a/src/core/file_sys/vfs_real.cpp b/src/core/file_sys/vfs_real.cpp index 9ce2e1efa..82d54da4a 100644 --- a/src/core/file_sys/vfs_real.cpp +++ b/src/core/file_sys/vfs_real.cpp | |||
| @@ -195,6 +195,12 @@ bool RealVfsDirectory::Rename(std::string_view name) { | |||
| 195 | return FileUtil::Rename(path, new_name); | 195 | return FileUtil::Rename(path, new_name); |
| 196 | } | 196 | } |
| 197 | 197 | ||
| 198 | std::string RealVfsDirectory::GetFullPath() const { | ||
| 199 | auto out = path; | ||
| 200 | std::replace(out.begin(), out.end(), '\\', '/'); | ||
| 201 | return out; | ||
| 202 | } | ||
| 203 | |||
| 198 | bool RealVfsDirectory::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) { | 204 | bool RealVfsDirectory::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) { |
| 199 | const auto iter = std::find(files.begin(), files.end(), file); | 205 | const auto iter = std::find(files.begin(), files.end(), file); |
| 200 | if (iter == files.end()) | 206 | if (iter == files.end()) |
diff --git a/src/core/file_sys/vfs_real.h b/src/core/file_sys/vfs_real.h index 2151211c9..243d58576 100644 --- a/src/core/file_sys/vfs_real.h +++ b/src/core/file_sys/vfs_real.h | |||
| @@ -41,7 +41,7 @@ private: | |||
| 41 | 41 | ||
| 42 | // An implementation of VfsDirectory that represents a directory on the user's computer. | 42 | // An implementation of VfsDirectory that represents a directory on the user's computer. |
| 43 | struct RealVfsDirectory : public VfsDirectory { | 43 | struct RealVfsDirectory : public VfsDirectory { |
| 44 | RealVfsDirectory(const std::string& path, Mode perms); | 44 | RealVfsDirectory(const std::string& path, Mode perms = Mode::Read); |
| 45 | 45 | ||
| 46 | std::vector<std::shared_ptr<VfsFile>> GetFiles() const override; | 46 | std::vector<std::shared_ptr<VfsFile>> GetFiles() const override; |
| 47 | std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override; | 47 | std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override; |
| @@ -54,6 +54,7 @@ struct RealVfsDirectory : public VfsDirectory { | |||
| 54 | bool DeleteSubdirectory(std::string_view name) override; | 54 | bool DeleteSubdirectory(std::string_view name) override; |
| 55 | bool DeleteFile(std::string_view name) override; | 55 | bool DeleteFile(std::string_view name) override; |
| 56 | bool Rename(std::string_view name) override; | 56 | bool Rename(std::string_view name) override; |
| 57 | std::string GetFullPath() const override; | ||
| 57 | 58 | ||
| 58 | protected: | 59 | protected: |
| 59 | bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override; | 60 | bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override; |
diff --git a/src/core/file_sys/vfs_vector.cpp b/src/core/file_sys/vfs_vector.cpp new file mode 100644 index 000000000..fda603960 --- /dev/null +++ b/src/core/file_sys/vfs_vector.cpp | |||
| @@ -0,0 +1,86 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | #include <utility> | ||
| 7 | #include "core/file_sys/vfs_vector.h" | ||
| 8 | |||
| 9 | namespace FileSys { | ||
| 10 | VectorVfsDirectory::VectorVfsDirectory(std::vector<VirtualFile> files_, | ||
| 11 | std::vector<VirtualDir> dirs_, VirtualDir parent_, | ||
| 12 | std::string name_) | ||
| 13 | : files(std::move(files_)), dirs(std::move(dirs_)), parent(std::move(parent_)), | ||
| 14 | name(std::move(name_)) {} | ||
| 15 | |||
| 16 | std::vector<std::shared_ptr<VfsFile>> VectorVfsDirectory::GetFiles() const { | ||
| 17 | return files; | ||
| 18 | } | ||
| 19 | |||
| 20 | std::vector<std::shared_ptr<VfsDirectory>> VectorVfsDirectory::GetSubdirectories() const { | ||
| 21 | return dirs; | ||
| 22 | } | ||
| 23 | |||
| 24 | bool VectorVfsDirectory::IsWritable() const { | ||
| 25 | return false; | ||
| 26 | } | ||
| 27 | |||
| 28 | bool VectorVfsDirectory::IsReadable() const { | ||
| 29 | return true; | ||
| 30 | } | ||
| 31 | |||
| 32 | std::string VectorVfsDirectory::GetName() const { | ||
| 33 | return name; | ||
| 34 | } | ||
| 35 | |||
| 36 | std::shared_ptr<VfsDirectory> VectorVfsDirectory::GetParentDirectory() const { | ||
| 37 | return parent; | ||
| 38 | } | ||
| 39 | |||
| 40 | template <typename T> | ||
| 41 | static bool FindAndRemoveVectorElement(std::vector<T>& vec, std::string_view name) { | ||
| 42 | const auto iter = | ||
| 43 | std::find_if(vec.begin(), vec.end(), [name](const T& e) { return e->GetName() == name; }); | ||
| 44 | if (iter == vec.end()) | ||
| 45 | return false; | ||
| 46 | |||
| 47 | vec.erase(iter); | ||
| 48 | return true; | ||
| 49 | } | ||
| 50 | |||
| 51 | bool VectorVfsDirectory::DeleteSubdirectory(std::string_view name) { | ||
| 52 | return FindAndRemoveVectorElement(dirs, name); | ||
| 53 | } | ||
| 54 | |||
| 55 | bool VectorVfsDirectory::DeleteFile(std::string_view name) { | ||
| 56 | return FindAndRemoveVectorElement(files, name); | ||
| 57 | } | ||
| 58 | |||
| 59 | bool VectorVfsDirectory::Rename(std::string_view name_) { | ||
| 60 | name = name_; | ||
| 61 | return true; | ||
| 62 | } | ||
| 63 | |||
| 64 | std::shared_ptr<VfsDirectory> VectorVfsDirectory::CreateSubdirectory(std::string_view name) { | ||
| 65 | return nullptr; | ||
| 66 | } | ||
| 67 | |||
| 68 | std::shared_ptr<VfsFile> VectorVfsDirectory::CreateFile(std::string_view name) { | ||
| 69 | return nullptr; | ||
| 70 | } | ||
| 71 | |||
| 72 | void VectorVfsDirectory::AddFile(VirtualFile file) { | ||
| 73 | files.push_back(std::move(file)); | ||
| 74 | } | ||
| 75 | |||
| 76 | void VectorVfsDirectory::AddDirectory(VirtualDir dir) { | ||
| 77 | dirs.push_back(std::move(dir)); | ||
| 78 | } | ||
| 79 | |||
| 80 | bool VectorVfsDirectory::ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) { | ||
| 81 | if (!DeleteFile(file->GetName())) | ||
| 82 | return false; | ||
| 83 | dirs.emplace_back(std::move(dir)); | ||
| 84 | return true; | ||
| 85 | } | ||
| 86 | } // namespace FileSys | ||
diff --git a/src/core/file_sys/vfs_vector.h b/src/core/file_sys/vfs_vector.h new file mode 100644 index 000000000..ba469647b --- /dev/null +++ b/src/core/file_sys/vfs_vector.h | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "core/file_sys/vfs.h" | ||
| 8 | |||
| 9 | namespace FileSys { | ||
| 10 | |||
| 11 | // An implementation of VfsDirectory that maintains two vectors for subdirectories and files. | ||
| 12 | // Vector data is supplied upon construction. | ||
| 13 | struct VectorVfsDirectory : public VfsDirectory { | ||
| 14 | explicit VectorVfsDirectory(std::vector<VirtualFile> files = {}, | ||
| 15 | std::vector<VirtualDir> dirs = {}, VirtualDir parent = nullptr, | ||
| 16 | std::string name = ""); | ||
| 17 | |||
| 18 | std::vector<std::shared_ptr<VfsFile>> GetFiles() const override; | ||
| 19 | std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override; | ||
| 20 | bool IsWritable() const override; | ||
| 21 | bool IsReadable() const override; | ||
| 22 | std::string GetName() const override; | ||
| 23 | std::shared_ptr<VfsDirectory> GetParentDirectory() const override; | ||
| 24 | bool DeleteSubdirectory(std::string_view name) override; | ||
| 25 | bool DeleteFile(std::string_view name) override; | ||
| 26 | bool Rename(std::string_view name) override; | ||
| 27 | std::shared_ptr<VfsDirectory> CreateSubdirectory(std::string_view name) override; | ||
| 28 | std::shared_ptr<VfsFile> CreateFile(std::string_view name) override; | ||
| 29 | |||
| 30 | virtual void AddFile(VirtualFile file); | ||
| 31 | virtual void AddDirectory(VirtualDir dir); | ||
| 32 | |||
| 33 | protected: | ||
| 34 | bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override; | ||
| 35 | |||
| 36 | private: | ||
| 37 | std::vector<VirtualFile> files; | ||
| 38 | std::vector<VirtualDir> dirs; | ||
| 39 | |||
| 40 | VirtualDir parent; | ||
| 41 | std::string name; | ||
| 42 | }; | ||
| 43 | |||
| 44 | } // namespace FileSys | ||
diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp index 5ca573652..332e5c3d0 100644 --- a/src/core/gdbstub/gdbstub.cpp +++ b/src/core/gdbstub/gdbstub.cpp | |||
| @@ -37,45 +37,46 @@ | |||
| 37 | #include "core/core.h" | 37 | #include "core/core.h" |
| 38 | #include "core/core_cpu.h" | 38 | #include "core/core_cpu.h" |
| 39 | #include "core/gdbstub/gdbstub.h" | 39 | #include "core/gdbstub/gdbstub.h" |
| 40 | #include "core/hle/kernel/kernel.h" | ||
| 41 | #include "core/hle/kernel/scheduler.h" | 40 | #include "core/hle/kernel/scheduler.h" |
| 42 | #include "core/loader/loader.h" | 41 | #include "core/loader/loader.h" |
| 43 | #include "core/memory.h" | 42 | #include "core/memory.h" |
| 44 | 43 | ||
| 45 | const int GDB_BUFFER_SIZE = 10000; | 44 | namespace GDBStub { |
| 45 | namespace { | ||
| 46 | constexpr int GDB_BUFFER_SIZE = 10000; | ||
| 46 | 47 | ||
| 47 | const char GDB_STUB_START = '$'; | 48 | constexpr char GDB_STUB_START = '$'; |
| 48 | const char GDB_STUB_END = '#'; | 49 | constexpr char GDB_STUB_END = '#'; |
| 49 | const char GDB_STUB_ACK = '+'; | 50 | constexpr char GDB_STUB_ACK = '+'; |
| 50 | const char GDB_STUB_NACK = '-'; | 51 | constexpr char GDB_STUB_NACK = '-'; |
| 51 | 52 | ||
| 52 | #ifndef SIGTRAP | 53 | #ifndef SIGTRAP |
| 53 | const u32 SIGTRAP = 5; | 54 | constexpr u32 SIGTRAP = 5; |
| 54 | #endif | 55 | #endif |
| 55 | 56 | ||
| 56 | #ifndef SIGTERM | 57 | #ifndef SIGTERM |
| 57 | const u32 SIGTERM = 15; | 58 | constexpr u32 SIGTERM = 15; |
| 58 | #endif | 59 | #endif |
| 59 | 60 | ||
| 60 | #ifndef MSG_WAITALL | 61 | #ifndef MSG_WAITALL |
| 61 | const u32 MSG_WAITALL = 8; | 62 | constexpr u32 MSG_WAITALL = 8; |
| 62 | #endif | 63 | #endif |
| 63 | 64 | ||
| 64 | const u32 LR_REGISTER = 30; | 65 | constexpr u32 LR_REGISTER = 30; |
| 65 | const u32 SP_REGISTER = 31; | 66 | constexpr u32 SP_REGISTER = 31; |
| 66 | const u32 PC_REGISTER = 32; | 67 | constexpr u32 PC_REGISTER = 32; |
| 67 | const u32 CPSR_REGISTER = 33; | 68 | constexpr u32 CPSR_REGISTER = 33; |
| 68 | const u32 UC_ARM64_REG_Q0 = 34; | 69 | constexpr u32 UC_ARM64_REG_Q0 = 34; |
| 69 | const u32 FPSCR_REGISTER = 66; | 70 | constexpr u32 FPSCR_REGISTER = 66; |
| 70 | 71 | ||
| 71 | // TODO/WiP - Used while working on support for FPU | 72 | // TODO/WiP - Used while working on support for FPU |
| 72 | const u32 TODO_DUMMY_REG_997 = 997; | 73 | constexpr u32 TODO_DUMMY_REG_997 = 997; |
| 73 | const u32 TODO_DUMMY_REG_998 = 998; | 74 | constexpr u32 TODO_DUMMY_REG_998 = 998; |
| 74 | 75 | ||
| 75 | // For sample XML files see the GDB source /gdb/features | 76 | // For sample XML files see the GDB source /gdb/features |
| 76 | // GDB also wants the l character at the start | 77 | // GDB also wants the l character at the start |
| 77 | // This XML defines what the registers are for this specific ARM device | 78 | // This XML defines what the registers are for this specific ARM device |
| 78 | static const char* target_xml = | 79 | constexpr char target_xml[] = |
| 79 | R"(l<?xml version="1.0"?> | 80 | R"(l<?xml version="1.0"?> |
| 80 | <!DOCTYPE target SYSTEM "gdb-target.dtd"> | 81 | <!DOCTYPE target SYSTEM "gdb-target.dtd"> |
| 81 | <target version="1.0"> | 82 | <target version="1.0"> |
| @@ -141,30 +142,28 @@ static const char* target_xml = | |||
| 141 | </target> | 142 | </target> |
| 142 | )"; | 143 | )"; |
| 143 | 144 | ||
| 144 | namespace GDBStub { | 145 | int gdbserver_socket = -1; |
| 145 | |||
| 146 | static int gdbserver_socket = -1; | ||
| 147 | 146 | ||
| 148 | static u8 command_buffer[GDB_BUFFER_SIZE]; | 147 | u8 command_buffer[GDB_BUFFER_SIZE]; |
| 149 | static u32 command_length; | 148 | u32 command_length; |
| 150 | 149 | ||
| 151 | static u32 latest_signal = 0; | 150 | u32 latest_signal = 0; |
| 152 | static bool memory_break = false; | 151 | bool memory_break = false; |
| 153 | 152 | ||
| 154 | static Kernel::Thread* current_thread = nullptr; | 153 | Kernel::Thread* current_thread = nullptr; |
| 155 | static u32 current_core = 0; | 154 | u32 current_core = 0; |
| 156 | 155 | ||
| 157 | // Binding to a port within the reserved ports range (0-1023) requires root permissions, | 156 | // Binding to a port within the reserved ports range (0-1023) requires root permissions, |
| 158 | // so default to a port outside of that range. | 157 | // so default to a port outside of that range. |
| 159 | static u16 gdbstub_port = 24689; | 158 | u16 gdbstub_port = 24689; |
| 160 | 159 | ||
| 161 | static bool halt_loop = true; | 160 | bool halt_loop = true; |
| 162 | static bool step_loop = false; | 161 | bool step_loop = false; |
| 163 | static bool send_trap = false; | 162 | bool send_trap = false; |
| 164 | 163 | ||
| 165 | // If set to false, the server will never be started and no | 164 | // If set to false, the server will never be started and no |
| 166 | // gdbstub-related functions will be executed. | 165 | // gdbstub-related functions will be executed. |
| 167 | static std::atomic<bool> server_enabled(false); | 166 | std::atomic<bool> server_enabled(false); |
| 168 | 167 | ||
| 169 | #ifdef _WIN32 | 168 | #ifdef _WIN32 |
| 170 | WSADATA InitData; | 169 | WSADATA InitData; |
| @@ -172,23 +171,26 @@ WSADATA InitData; | |||
| 172 | 171 | ||
| 173 | struct Breakpoint { | 172 | struct Breakpoint { |
| 174 | bool active; | 173 | bool active; |
| 175 | PAddr addr; | 174 | VAddr addr; |
| 176 | u64 len; | 175 | u64 len; |
| 176 | std::array<u8, 4> inst; | ||
| 177 | }; | 177 | }; |
| 178 | 178 | ||
| 179 | static std::map<u64, Breakpoint> breakpoints_execute; | 179 | using BreakpointMap = std::map<VAddr, Breakpoint>; |
| 180 | static std::map<u64, Breakpoint> breakpoints_read; | 180 | BreakpointMap breakpoints_execute; |
| 181 | static std::map<u64, Breakpoint> breakpoints_write; | 181 | BreakpointMap breakpoints_read; |
| 182 | BreakpointMap breakpoints_write; | ||
| 182 | 183 | ||
| 183 | struct Module { | 184 | struct Module { |
| 184 | std::string name; | 185 | std::string name; |
| 185 | PAddr beg; | 186 | VAddr beg; |
| 186 | PAddr end; | 187 | VAddr end; |
| 187 | }; | 188 | }; |
| 188 | 189 | ||
| 189 | static std::vector<Module> modules; | 190 | std::vector<Module> modules; |
| 191 | } // Anonymous namespace | ||
| 190 | 192 | ||
| 191 | void RegisterModule(std::string name, PAddr beg, PAddr end, bool add_elf_ext) { | 193 | void RegisterModule(std::string name, VAddr beg, VAddr end, bool add_elf_ext) { |
| 192 | Module module; | 194 | Module module; |
| 193 | if (add_elf_ext) { | 195 | if (add_elf_ext) { |
| 194 | Common::SplitPath(name, nullptr, &module.name, nullptr); | 196 | Common::SplitPath(name, nullptr, &module.name, nullptr); |
| @@ -419,11 +421,11 @@ static u8 CalculateChecksum(const u8* buffer, size_t length) { | |||
| 419 | } | 421 | } |
| 420 | 422 | ||
| 421 | /** | 423 | /** |
| 422 | * Get the list of breakpoints for a given breakpoint type. | 424 | * Get the map of breakpoints for a given breakpoint type. |
| 423 | * | 425 | * |
| 424 | * @param type Type of breakpoint list. | 426 | * @param type Type of breakpoint map. |
| 425 | */ | 427 | */ |
| 426 | static std::map<u64, Breakpoint>& GetBreakpointList(BreakpointType type) { | 428 | static BreakpointMap& GetBreakpointMap(BreakpointType type) { |
| 427 | switch (type) { | 429 | switch (type) { |
| 428 | case BreakpointType::Execute: | 430 | case BreakpointType::Execute: |
| 429 | return breakpoints_execute; | 431 | return breakpoints_execute; |
| @@ -442,20 +444,24 @@ static std::map<u64, Breakpoint>& GetBreakpointList(BreakpointType type) { | |||
| 442 | * @param type Type of breakpoint. | 444 | * @param type Type of breakpoint. |
| 443 | * @param addr Address of breakpoint. | 445 | * @param addr Address of breakpoint. |
| 444 | */ | 446 | */ |
| 445 | static void RemoveBreakpoint(BreakpointType type, PAddr addr) { | 447 | static void RemoveBreakpoint(BreakpointType type, VAddr addr) { |
| 446 | std::map<u64, Breakpoint>& p = GetBreakpointList(type); | 448 | BreakpointMap& p = GetBreakpointMap(type); |
| 447 | 449 | ||
| 448 | auto bp = p.find(static_cast<u64>(addr)); | 450 | const auto bp = p.find(addr); |
| 449 | if (bp != p.end()) { | 451 | if (bp == p.end()) { |
| 450 | LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: {:016X} bytes at {:016X} of type {}", | 452 | return; |
| 451 | bp->second.len, bp->second.addr, static_cast<int>(type)); | ||
| 452 | p.erase(static_cast<u64>(addr)); | ||
| 453 | } | 453 | } |
| 454 | |||
| 455 | LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: {:016X} bytes at {:016X} of type {}", | ||
| 456 | bp->second.len, bp->second.addr, static_cast<int>(type)); | ||
| 457 | Memory::WriteBlock(bp->second.addr, bp->second.inst.data(), bp->second.inst.size()); | ||
| 458 | Core::System::GetInstance().InvalidateCpuInstructionCaches(); | ||
| 459 | p.erase(addr); | ||
| 454 | } | 460 | } |
| 455 | 461 | ||
| 456 | BreakpointAddress GetNextBreakpointFromAddress(PAddr addr, BreakpointType type) { | 462 | BreakpointAddress GetNextBreakpointFromAddress(VAddr addr, BreakpointType type) { |
| 457 | std::map<u64, Breakpoint>& p = GetBreakpointList(type); | 463 | const BreakpointMap& p = GetBreakpointMap(type); |
| 458 | auto next_breakpoint = p.lower_bound(static_cast<u64>(addr)); | 464 | const auto next_breakpoint = p.lower_bound(addr); |
| 459 | BreakpointAddress breakpoint; | 465 | BreakpointAddress breakpoint; |
| 460 | 466 | ||
| 461 | if (next_breakpoint != p.end()) { | 467 | if (next_breakpoint != p.end()) { |
| @@ -469,36 +475,38 @@ BreakpointAddress GetNextBreakpointFromAddress(PAddr addr, BreakpointType type) | |||
| 469 | return breakpoint; | 475 | return breakpoint; |
| 470 | } | 476 | } |
| 471 | 477 | ||
| 472 | bool CheckBreakpoint(PAddr addr, BreakpointType type) { | 478 | bool CheckBreakpoint(VAddr addr, BreakpointType type) { |
| 473 | if (!IsConnected()) { | 479 | if (!IsConnected()) { |
| 474 | return false; | 480 | return false; |
| 475 | } | 481 | } |
| 476 | 482 | ||
| 477 | std::map<u64, Breakpoint>& p = GetBreakpointList(type); | 483 | const BreakpointMap& p = GetBreakpointMap(type); |
| 484 | const auto bp = p.find(addr); | ||
| 478 | 485 | ||
| 479 | auto bp = p.find(static_cast<u64>(addr)); | 486 | if (bp == p.end()) { |
| 480 | if (bp != p.end()) { | 487 | return false; |
| 481 | u64 len = bp->second.len; | 488 | } |
| 482 | 489 | ||
| 483 | // IDA Pro defaults to 4-byte breakpoints for all non-hardware breakpoints | 490 | u64 len = bp->second.len; |
| 484 | // no matter if it's a 4-byte or 2-byte instruction. When you execute a | ||
| 485 | // Thumb instruction with a 4-byte breakpoint set, it will set a breakpoint on | ||
| 486 | // two instructions instead of the single instruction you placed the breakpoint | ||
| 487 | // on. So, as a way to make sure that execution breakpoints are only breaking | ||
| 488 | // on the instruction that was specified, set the length of an execution | ||
| 489 | // breakpoint to 1. This should be fine since the CPU should never begin executing | ||
| 490 | // an instruction anywhere except the beginning of the instruction. | ||
| 491 | if (type == BreakpointType::Execute) { | ||
| 492 | len = 1; | ||
| 493 | } | ||
| 494 | 491 | ||
| 495 | if (bp->second.active && (addr >= bp->second.addr && addr < bp->second.addr + len)) { | 492 | // IDA Pro defaults to 4-byte breakpoints for all non-hardware breakpoints |
| 496 | LOG_DEBUG(Debug_GDBStub, | 493 | // no matter if it's a 4-byte or 2-byte instruction. When you execute a |
| 497 | "Found breakpoint type {} @ {:016X}, range: {:016X}" | 494 | // Thumb instruction with a 4-byte breakpoint set, it will set a breakpoint on |
| 498 | " - {:016X} ({:X} bytes)", | 495 | // two instructions instead of the single instruction you placed the breakpoint |
| 499 | static_cast<int>(type), addr, bp->second.addr, bp->second.addr + len, len); | 496 | // on. So, as a way to make sure that execution breakpoints are only breaking |
| 500 | return true; | 497 | // on the instruction that was specified, set the length of an execution |
| 501 | } | 498 | // breakpoint to 1. This should be fine since the CPU should never begin executing |
| 499 | // an instruction anywhere except the beginning of the instruction. | ||
| 500 | if (type == BreakpointType::Execute) { | ||
| 501 | len = 1; | ||
| 502 | } | ||
| 503 | |||
| 504 | if (bp->second.active && (addr >= bp->second.addr && addr < bp->second.addr + len)) { | ||
| 505 | LOG_DEBUG(Debug_GDBStub, | ||
| 506 | "Found breakpoint type {} @ {:016X}, range: {:016X}" | ||
| 507 | " - {:016X} ({:X} bytes)", | ||
| 508 | static_cast<int>(type), addr, bp->second.addr, bp->second.addr + len, len); | ||
| 509 | return true; | ||
| 502 | } | 510 | } |
| 503 | 511 | ||
| 504 | return false; | 512 | return false; |
| @@ -932,6 +940,7 @@ static void WriteMemory() { | |||
| 932 | 940 | ||
| 933 | GdbHexToMem(data.data(), len_pos + 1, len); | 941 | GdbHexToMem(data.data(), len_pos + 1, len); |
| 934 | Memory::WriteBlock(addr, data.data(), len); | 942 | Memory::WriteBlock(addr, data.data(), len); |
| 943 | Core::System::GetInstance().InvalidateCpuInstructionCaches(); | ||
| 935 | SendReply("OK"); | 944 | SendReply("OK"); |
| 936 | } | 945 | } |
| 937 | 946 | ||
| @@ -951,6 +960,7 @@ static void Step() { | |||
| 951 | step_loop = true; | 960 | step_loop = true; |
| 952 | halt_loop = true; | 961 | halt_loop = true; |
| 953 | send_trap = true; | 962 | send_trap = true; |
| 963 | Core::System::GetInstance().InvalidateCpuInstructionCaches(); | ||
| 954 | } | 964 | } |
| 955 | 965 | ||
| 956 | /// Tell the CPU if we hit a memory breakpoint. | 966 | /// Tell the CPU if we hit a memory breakpoint. |
| @@ -967,6 +977,7 @@ static void Continue() { | |||
| 967 | memory_break = false; | 977 | memory_break = false; |
| 968 | step_loop = false; | 978 | step_loop = false; |
| 969 | halt_loop = false; | 979 | halt_loop = false; |
| 980 | Core::System::GetInstance().InvalidateCpuInstructionCaches(); | ||
| 970 | } | 981 | } |
| 971 | 982 | ||
| 972 | /** | 983 | /** |
| @@ -976,13 +987,17 @@ static void Continue() { | |||
| 976 | * @param addr Address of breakpoint. | 987 | * @param addr Address of breakpoint. |
| 977 | * @param len Length of breakpoint. | 988 | * @param len Length of breakpoint. |
| 978 | */ | 989 | */ |
| 979 | static bool CommitBreakpoint(BreakpointType type, PAddr addr, u64 len) { | 990 | static bool CommitBreakpoint(BreakpointType type, VAddr addr, u64 len) { |
| 980 | std::map<u64, Breakpoint>& p = GetBreakpointList(type); | 991 | BreakpointMap& p = GetBreakpointMap(type); |
| 981 | 992 | ||
| 982 | Breakpoint breakpoint; | 993 | Breakpoint breakpoint; |
| 983 | breakpoint.active = true; | 994 | breakpoint.active = true; |
| 984 | breakpoint.addr = addr; | 995 | breakpoint.addr = addr; |
| 985 | breakpoint.len = len; | 996 | breakpoint.len = len; |
| 997 | Memory::ReadBlock(addr, breakpoint.inst.data(), breakpoint.inst.size()); | ||
| 998 | static constexpr std::array<u8, 4> btrap{{0xd4, 0x20, 0x7d, 0x0}}; | ||
| 999 | Memory::WriteBlock(addr, btrap.data(), btrap.size()); | ||
| 1000 | Core::System::GetInstance().InvalidateCpuInstructionCaches(); | ||
| 986 | p.insert({addr, breakpoint}); | 1001 | p.insert({addr, breakpoint}); |
| 987 | 1002 | ||
| 988 | LOG_DEBUG(Debug_GDBStub, "gdb: added {} breakpoint: {:016X} bytes at {:016X}", | 1003 | LOG_DEBUG(Debug_GDBStub, "gdb: added {} breakpoint: {:016X} bytes at {:016X}", |
| @@ -1016,7 +1031,7 @@ static void AddBreakpoint() { | |||
| 1016 | 1031 | ||
| 1017 | auto start_offset = command_buffer + 3; | 1032 | auto start_offset = command_buffer + 3; |
| 1018 | auto addr_pos = std::find(start_offset, command_buffer + command_length, ','); | 1033 | auto addr_pos = std::find(start_offset, command_buffer + command_length, ','); |
| 1019 | PAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset)); | 1034 | VAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset)); |
| 1020 | 1035 | ||
| 1021 | start_offset = addr_pos + 1; | 1036 | start_offset = addr_pos + 1; |
| 1022 | u64 len = | 1037 | u64 len = |
| @@ -1065,7 +1080,7 @@ static void RemoveBreakpoint() { | |||
| 1065 | 1080 | ||
| 1066 | auto start_offset = command_buffer + 3; | 1081 | auto start_offset = command_buffer + 3; |
| 1067 | auto addr_pos = std::find(start_offset, command_buffer + command_length, ','); | 1082 | auto addr_pos = std::find(start_offset, command_buffer + command_length, ','); |
| 1068 | PAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset)); | 1083 | VAddr addr = HexToLong(start_offset, static_cast<u64>(addr_pos - start_offset)); |
| 1069 | 1084 | ||
| 1070 | if (type == BreakpointType::Access) { | 1085 | if (type == BreakpointType::Access) { |
| 1071 | // Access is made up of Read and Write types, so add both breakpoints | 1086 | // Access is made up of Read and Write types, so add both breakpoints |
diff --git a/src/core/gdbstub/gdbstub.h b/src/core/gdbstub/gdbstub.h index a6b50c26c..5a36524b2 100644 --- a/src/core/gdbstub/gdbstub.h +++ b/src/core/gdbstub/gdbstub.h | |||
| @@ -22,7 +22,7 @@ enum class BreakpointType { | |||
| 22 | }; | 22 | }; |
| 23 | 23 | ||
| 24 | struct BreakpointAddress { | 24 | struct BreakpointAddress { |
| 25 | PAddr address; | 25 | VAddr address; |
| 26 | BreakpointType type; | 26 | BreakpointType type; |
| 27 | }; | 27 | }; |
| 28 | 28 | ||
| @@ -53,7 +53,7 @@ bool IsServerEnabled(); | |||
| 53 | bool IsConnected(); | 53 | bool IsConnected(); |
| 54 | 54 | ||
| 55 | /// Register module. | 55 | /// Register module. |
| 56 | void RegisterModule(std::string name, PAddr beg, PAddr end, bool add_elf_ext = true); | 56 | void RegisterModule(std::string name, VAddr beg, VAddr end, bool add_elf_ext = true); |
| 57 | 57 | ||
| 58 | /** | 58 | /** |
| 59 | * Signal to the gdbstub server that it should halt CPU execution. | 59 | * Signal to the gdbstub server that it should halt CPU execution. |
| @@ -74,7 +74,7 @@ void HandlePacket(); | |||
| 74 | * @param addr Address to search from. | 74 | * @param addr Address to search from. |
| 75 | * @param type Type of breakpoint. | 75 | * @param type Type of breakpoint. |
| 76 | */ | 76 | */ |
| 77 | BreakpointAddress GetNextBreakpointFromAddress(PAddr addr, GDBStub::BreakpointType type); | 77 | BreakpointAddress GetNextBreakpointFromAddress(VAddr addr, GDBStub::BreakpointType type); |
| 78 | 78 | ||
| 79 | /** | 79 | /** |
| 80 | * Check if a breakpoint of the specified type exists at the given address. | 80 | * Check if a breakpoint of the specified type exists at the given address. |
| @@ -82,7 +82,7 @@ BreakpointAddress GetNextBreakpointFromAddress(PAddr addr, GDBStub::BreakpointTy | |||
| 82 | * @param addr Address of breakpoint. | 82 | * @param addr Address of breakpoint. |
| 83 | * @param type Type of breakpoint. | 83 | * @param type Type of breakpoint. |
| 84 | */ | 84 | */ |
| 85 | bool CheckBreakpoint(PAddr addr, GDBStub::BreakpointType type); | 85 | bool CheckBreakpoint(VAddr addr, GDBStub::BreakpointType type); |
| 86 | 86 | ||
| 87 | /// If set to true, the CPU will halt at the beginning of the next CPU loop. | 87 | /// If set to true, the CPU will halt at the beginning of the next CPU loop. |
| 88 | bool GetCpuHaltFlag(); | 88 | bool GetCpuHaltFlag(); |
diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h index 7fb0da408..d3a734831 100644 --- a/src/core/hle/ipc_helpers.h +++ b/src/core/hle/ipc_helpers.h | |||
| @@ -5,15 +5,18 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <cstring> | ||
| 9 | #include <memory> | ||
| 8 | #include <tuple> | 10 | #include <tuple> |
| 9 | #include <type_traits> | 11 | #include <type_traits> |
| 10 | #include <utility> | 12 | #include <utility> |
| 13 | #include "common/assert.h" | ||
| 14 | #include "common/common_types.h" | ||
| 11 | #include "core/hle/ipc.h" | 15 | #include "core/hle/ipc.h" |
| 12 | #include "core/hle/kernel/client_port.h" | 16 | #include "core/hle/kernel/client_port.h" |
| 13 | #include "core/hle/kernel/client_session.h" | 17 | #include "core/hle/kernel/client_session.h" |
| 14 | #include "core/hle/kernel/handle_table.h" | ||
| 15 | #include "core/hle/kernel/hle_ipc.h" | 18 | #include "core/hle/kernel/hle_ipc.h" |
| 16 | #include "core/hle/kernel/kernel.h" | 19 | #include "core/hle/kernel/object.h" |
| 17 | #include "core/hle/kernel/server_port.h" | 20 | #include "core/hle/kernel/server_port.h" |
| 18 | 21 | ||
| 19 | namespace IPC { | 22 | namespace IPC { |
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index 233fdab25..03a954a9f 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp | |||
| @@ -2,15 +2,17 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <algorithm> | ||
| 6 | #include <vector> | ||
| 7 | |||
| 5 | #include "common/assert.h" | 8 | #include "common/assert.h" |
| 6 | #include "common/common_funcs.h" | ||
| 7 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 8 | #include "core/core.h" | 10 | #include "core/core.h" |
| 9 | #include "core/hle/kernel/errors.h" | 11 | #include "core/hle/kernel/errors.h" |
| 10 | #include "core/hle/kernel/kernel.h" | 12 | #include "core/hle/kernel/object.h" |
| 11 | #include "core/hle/kernel/process.h" | 13 | #include "core/hle/kernel/process.h" |
| 12 | #include "core/hle/kernel/thread.h" | 14 | #include "core/hle/kernel/thread.h" |
| 13 | #include "core/hle/lock.h" | 15 | #include "core/hle/result.h" |
| 14 | #include "core/memory.h" | 16 | #include "core/memory.h" |
| 15 | 17 | ||
| 16 | namespace Kernel { | 18 | namespace Kernel { |
| @@ -30,9 +32,8 @@ static ResultCode WaitForAddress(VAddr address, s64 timeout) { | |||
| 30 | } | 32 | } |
| 31 | 33 | ||
| 32 | // Gets the threads waiting on an address. | 34 | // Gets the threads waiting on an address. |
| 33 | static void GetThreadsWaitingOnAddress(std::vector<SharedPtr<Thread>>& waiting_threads, | 35 | static std::vector<SharedPtr<Thread>> GetThreadsWaitingOnAddress(VAddr address) { |
| 34 | VAddr address) { | 36 | const auto RetrieveWaitingThreads = |
| 35 | auto RetrieveWaitingThreads = | ||
| 36 | [](size_t core_index, std::vector<SharedPtr<Thread>>& waiting_threads, VAddr arb_addr) { | 37 | [](size_t core_index, std::vector<SharedPtr<Thread>>& waiting_threads, VAddr arb_addr) { |
| 37 | const auto& scheduler = Core::System::GetInstance().Scheduler(core_index); | 38 | const auto& scheduler = Core::System::GetInstance().Scheduler(core_index); |
| 38 | auto& thread_list = scheduler->GetThreadList(); | 39 | auto& thread_list = scheduler->GetThreadList(); |
| @@ -43,16 +44,20 @@ static void GetThreadsWaitingOnAddress(std::vector<SharedPtr<Thread>>& waiting_t | |||
| 43 | } | 44 | } |
| 44 | }; | 45 | }; |
| 45 | 46 | ||
| 46 | // Retrieve a list of all threads that are waiting for this address. | 47 | // Retrieve all threads that are waiting for this address. |
| 47 | RetrieveWaitingThreads(0, waiting_threads, address); | 48 | std::vector<SharedPtr<Thread>> threads; |
| 48 | RetrieveWaitingThreads(1, waiting_threads, address); | 49 | RetrieveWaitingThreads(0, threads, address); |
| 49 | RetrieveWaitingThreads(2, waiting_threads, address); | 50 | RetrieveWaitingThreads(1, threads, address); |
| 50 | RetrieveWaitingThreads(3, waiting_threads, address); | 51 | RetrieveWaitingThreads(2, threads, address); |
| 52 | RetrieveWaitingThreads(3, threads, address); | ||
| 53 | |||
| 51 | // Sort them by priority, such that the highest priority ones come first. | 54 | // Sort them by priority, such that the highest priority ones come first. |
| 52 | std::sort(waiting_threads.begin(), waiting_threads.end(), | 55 | std::sort(threads.begin(), threads.end(), |
| 53 | [](const SharedPtr<Thread>& lhs, const SharedPtr<Thread>& rhs) { | 56 | [](const SharedPtr<Thread>& lhs, const SharedPtr<Thread>& rhs) { |
| 54 | return lhs->current_priority < rhs->current_priority; | 57 | return lhs->current_priority < rhs->current_priority; |
| 55 | }); | 58 | }); |
| 59 | |||
| 60 | return threads; | ||
| 56 | } | 61 | } |
| 57 | 62 | ||
| 58 | // Wake up num_to_wake (or all) threads in a vector. | 63 | // Wake up num_to_wake (or all) threads in a vector. |
| @@ -74,9 +79,7 @@ static void WakeThreads(std::vector<SharedPtr<Thread>>& waiting_threads, s32 num | |||
| 74 | 79 | ||
| 75 | // Signals an address being waited on. | 80 | // Signals an address being waited on. |
| 76 | ResultCode SignalToAddress(VAddr address, s32 num_to_wake) { | 81 | ResultCode SignalToAddress(VAddr address, s32 num_to_wake) { |
| 77 | // Get threads waiting on the address. | 82 | std::vector<SharedPtr<Thread>> waiting_threads = GetThreadsWaitingOnAddress(address); |
| 78 | std::vector<SharedPtr<Thread>> waiting_threads; | ||
| 79 | GetThreadsWaitingOnAddress(waiting_threads, address); | ||
| 80 | 83 | ||
| 81 | WakeThreads(waiting_threads, num_to_wake); | 84 | WakeThreads(waiting_threads, num_to_wake); |
| 82 | return RESULT_SUCCESS; | 85 | return RESULT_SUCCESS; |
| @@ -108,12 +111,11 @@ ResultCode ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 valu | |||
| 108 | } | 111 | } |
| 109 | 112 | ||
| 110 | // Get threads waiting on the address. | 113 | // Get threads waiting on the address. |
| 111 | std::vector<SharedPtr<Thread>> waiting_threads; | 114 | std::vector<SharedPtr<Thread>> waiting_threads = GetThreadsWaitingOnAddress(address); |
| 112 | GetThreadsWaitingOnAddress(waiting_threads, address); | ||
| 113 | 115 | ||
| 114 | // Determine the modified value depending on the waiting count. | 116 | // Determine the modified value depending on the waiting count. |
| 115 | s32 updated_value; | 117 | s32 updated_value; |
| 116 | if (waiting_threads.size() == 0) { | 118 | if (waiting_threads.empty()) { |
| 117 | updated_value = value - 1; | 119 | updated_value = value - 1; |
| 118 | } else if (num_to_wake <= 0 || waiting_threads.size() <= static_cast<u32>(num_to_wake)) { | 120 | } else if (num_to_wake <= 0 || waiting_threads.size() <= static_cast<u32>(num_to_wake)) { |
| 119 | updated_value = value + 1; | 121 | updated_value = value + 1; |
diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h index f20f3dbc0..e3657b8e9 100644 --- a/src/core/hle/kernel/address_arbiter.h +++ b/src/core/hle/kernel/address_arbiter.h | |||
| @@ -4,7 +4,9 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include "core/hle/result.h" | 7 | #include "common/common_types.h" |
| 8 | |||
| 9 | union ResultCode; | ||
| 8 | 10 | ||
| 9 | namespace Kernel { | 11 | namespace Kernel { |
| 10 | 12 | ||
diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index fb2b6f7a3..134e41ebc 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp | |||
| @@ -2,19 +2,20 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "common/assert.h" | 5 | #include <tuple> |
| 6 | |||
| 6 | #include "core/hle/kernel/client_port.h" | 7 | #include "core/hle/kernel/client_port.h" |
| 7 | #include "core/hle/kernel/client_session.h" | 8 | #include "core/hle/kernel/client_session.h" |
| 8 | #include "core/hle/kernel/errors.h" | 9 | #include "core/hle/kernel/errors.h" |
| 9 | #include "core/hle/kernel/hle_ipc.h" | 10 | #include "core/hle/kernel/hle_ipc.h" |
| 10 | #include "core/hle/kernel/kernel.h" | 11 | #include "core/hle/kernel/object.h" |
| 11 | #include "core/hle/kernel/server_port.h" | 12 | #include "core/hle/kernel/server_port.h" |
| 12 | #include "core/hle/kernel/server_session.h" | 13 | #include "core/hle/kernel/server_session.h" |
| 13 | 14 | ||
| 14 | namespace Kernel { | 15 | namespace Kernel { |
| 15 | 16 | ||
| 16 | ClientPort::ClientPort() {} | 17 | ClientPort::ClientPort() = default; |
| 17 | ClientPort::~ClientPort() {} | 18 | ClientPort::~ClientPort() = default; |
| 18 | 19 | ||
| 19 | ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() { | 20 | ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() { |
| 20 | // Note: Threads do not wait for the server endpoint to call | 21 | // Note: Threads do not wait for the server endpoint to call |
| @@ -39,4 +40,12 @@ ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() { | |||
| 39 | return MakeResult(std::get<SharedPtr<ClientSession>>(sessions)); | 40 | return MakeResult(std::get<SharedPtr<ClientSession>>(sessions)); |
| 40 | } | 41 | } |
| 41 | 42 | ||
| 43 | void ClientPort::ConnectionClosed() { | ||
| 44 | if (active_sessions == 0) { | ||
| 45 | return; | ||
| 46 | } | ||
| 47 | |||
| 48 | --active_sessions; | ||
| 49 | } | ||
| 50 | |||
| 42 | } // namespace Kernel | 51 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/client_port.h b/src/core/hle/kernel/client_port.h index a829aeb6d..b1269ea5c 100644 --- a/src/core/hle/kernel/client_port.h +++ b/src/core/hle/kernel/client_port.h | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include <string> | 7 | #include <string> |
| 8 | #include "common/common_types.h" | 8 | #include "common/common_types.h" |
| 9 | #include "core/hle/kernel/kernel.h" | 9 | #include "core/hle/kernel/object.h" |
| 10 | #include "core/hle/result.h" | 10 | #include "core/hle/result.h" |
| 11 | 11 | ||
| 12 | namespace Kernel { | 12 | namespace Kernel { |
| @@ -37,14 +37,20 @@ public: | |||
| 37 | */ | 37 | */ |
| 38 | ResultVal<SharedPtr<ClientSession>> Connect(); | 38 | ResultVal<SharedPtr<ClientSession>> Connect(); |
| 39 | 39 | ||
| 40 | SharedPtr<ServerPort> server_port; ///< ServerPort associated with this client port. | 40 | /** |
| 41 | u32 max_sessions; ///< Maximum number of simultaneous sessions the port can have | 41 | * Signifies that a previously active connection has been closed, |
| 42 | u32 active_sessions; ///< Number of currently open sessions to this port | 42 | * decreasing the total number of active connections to this port. |
| 43 | std::string name; ///< Name of client port (optional) | 43 | */ |
| 44 | void ConnectionClosed(); | ||
| 44 | 45 | ||
| 45 | private: | 46 | private: |
| 46 | ClientPort(); | 47 | ClientPort(); |
| 47 | ~ClientPort() override; | 48 | ~ClientPort() override; |
| 49 | |||
| 50 | SharedPtr<ServerPort> server_port; ///< ServerPort associated with this client port. | ||
| 51 | u32 max_sessions = 0; ///< Maximum number of simultaneous sessions the port can have | ||
| 52 | u32 active_sessions = 0; ///< Number of currently open sessions to this port | ||
| 53 | std::string name; ///< Name of client port (optional) | ||
| 48 | }; | 54 | }; |
| 49 | 55 | ||
| 50 | } // namespace Kernel | 56 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/client_session.cpp b/src/core/hle/kernel/client_session.cpp index 72773d8b1..fdffc648d 100644 --- a/src/core/hle/kernel/client_session.cpp +++ b/src/core/hle/kernel/client_session.cpp | |||
| @@ -2,8 +2,6 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "common/assert.h" | ||
| 6 | |||
| 7 | #include "core/hle/kernel/client_session.h" | 5 | #include "core/hle/kernel/client_session.h" |
| 8 | #include "core/hle/kernel/errors.h" | 6 | #include "core/hle/kernel/errors.h" |
| 9 | #include "core/hle/kernel/hle_ipc.h" | 7 | #include "core/hle/kernel/hle_ipc.h" |
diff --git a/src/core/hle/kernel/client_session.h b/src/core/hle/kernel/client_session.h index 2258f95bc..dabd93ed7 100644 --- a/src/core/hle/kernel/client_session.h +++ b/src/core/hle/kernel/client_session.h | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <string> | 8 | #include <string> |
| 9 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 10 | #include "core/hle/kernel/kernel.h" | 10 | #include "core/hle/kernel/object.h" |
| 11 | #include "core/hle/result.h" | 11 | #include "core/hle/result.h" |
| 12 | 12 | ||
| 13 | namespace Kernel { | 13 | namespace Kernel { |
diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp index 9cae2369f..5623c4b6a 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/event.cpp | |||
| @@ -3,11 +3,9 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | #include <map> | ||
| 7 | #include <vector> | ||
| 8 | #include "common/assert.h" | 6 | #include "common/assert.h" |
| 9 | #include "core/hle/kernel/event.h" | 7 | #include "core/hle/kernel/event.h" |
| 10 | #include "core/hle/kernel/kernel.h" | 8 | #include "core/hle/kernel/object.h" |
| 11 | #include "core/hle/kernel/thread.h" | 9 | #include "core/hle/kernel/thread.h" |
| 12 | 10 | ||
| 13 | namespace Kernel { | 11 | namespace Kernel { |
diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/event.h index e5c924a75..3c20c05e8 100644 --- a/src/core/hle/kernel/event.h +++ b/src/core/hle/kernel/event.h | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 8 | #include "core/hle/kernel/kernel.h" | 8 | #include "core/hle/kernel/object.h" |
| 9 | #include "core/hle/kernel/wait_object.h" | 9 | #include "core/hle/kernel/wait_object.h" |
| 10 | 10 | ||
| 11 | namespace Kernel { | 11 | namespace Kernel { |
| @@ -31,10 +31,9 @@ public: | |||
| 31 | return HANDLE_TYPE; | 31 | return HANDLE_TYPE; |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | ResetType reset_type; ///< Current ResetType | 34 | ResetType GetResetType() const { |
| 35 | 35 | return reset_type; | |
| 36 | bool signaled; ///< Whether the event has already been signaled | 36 | } |
| 37 | std::string name; ///< Name of event (optional) | ||
| 38 | 37 | ||
| 39 | bool ShouldWait(Thread* thread) const override; | 38 | bool ShouldWait(Thread* thread) const override; |
| 40 | void Acquire(Thread* thread) override; | 39 | void Acquire(Thread* thread) override; |
| @@ -47,6 +46,11 @@ public: | |||
| 47 | private: | 46 | private: |
| 48 | Event(); | 47 | Event(); |
| 49 | ~Event() override; | 48 | ~Event() override; |
| 49 | |||
| 50 | ResetType reset_type; ///< Current ResetType | ||
| 51 | |||
| 52 | bool signaled; ///< Whether the event has already been signaled | ||
| 53 | std::string name; ///< Name of event (optional) | ||
| 50 | }; | 54 | }; |
| 51 | 55 | ||
| 52 | } // namespace Kernel | 56 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp index 7dd67f80f..28e21428a 100644 --- a/src/core/hle/kernel/handle_table.cpp +++ b/src/core/hle/kernel/handle_table.cpp | |||
| @@ -8,7 +8,6 @@ | |||
| 8 | #include "core/core.h" | 8 | #include "core/core.h" |
| 9 | #include "core/hle/kernel/errors.h" | 9 | #include "core/hle/kernel/errors.h" |
| 10 | #include "core/hle/kernel/handle_table.h" | 10 | #include "core/hle/kernel/handle_table.h" |
| 11 | #include "core/hle/kernel/kernel.h" | ||
| 12 | #include "core/hle/kernel/process.h" | 11 | #include "core/hle/kernel/process.h" |
| 13 | #include "core/hle/kernel/thread.h" | 12 | #include "core/hle/kernel/thread.h" |
| 14 | 13 | ||
diff --git a/src/core/hle/kernel/handle_table.h b/src/core/hle/kernel/handle_table.h index ba968c666..22ddda630 100644 --- a/src/core/hle/kernel/handle_table.h +++ b/src/core/hle/kernel/handle_table.h | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <cstddef> | 8 | #include <cstddef> |
| 9 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 10 | #include "core/hle/kernel/kernel.h" | 10 | #include "core/hle/kernel/object.h" |
| 11 | #include "core/hle/result.h" | 11 | #include "core/hle/result.h" |
| 12 | 12 | ||
| 13 | namespace Kernel { | 13 | namespace Kernel { |
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index f24392520..5dd1b68d7 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp | |||
| @@ -2,17 +2,22 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <algorithm> | ||
| 6 | #include <array> | ||
| 7 | #include <sstream> | ||
| 5 | #include <utility> | 8 | #include <utility> |
| 6 | 9 | ||
| 7 | #include <boost/range/algorithm_ext/erase.hpp> | 10 | #include <boost/range/algorithm_ext/erase.hpp> |
| 11 | |||
| 8 | #include "common/assert.h" | 12 | #include "common/assert.h" |
| 9 | #include "common/common_funcs.h" | 13 | #include "common/common_funcs.h" |
| 10 | #include "common/common_types.h" | 14 | #include "common/common_types.h" |
| 15 | #include "common/logging/log.h" | ||
| 11 | #include "core/hle/ipc_helpers.h" | 16 | #include "core/hle/ipc_helpers.h" |
| 12 | #include "core/hle/kernel/event.h" | 17 | #include "core/hle/kernel/event.h" |
| 13 | #include "core/hle/kernel/handle_table.h" | 18 | #include "core/hle/kernel/handle_table.h" |
| 14 | #include "core/hle/kernel/hle_ipc.h" | 19 | #include "core/hle/kernel/hle_ipc.h" |
| 15 | #include "core/hle/kernel/kernel.h" | 20 | #include "core/hle/kernel/object.h" |
| 16 | #include "core/hle/kernel/process.h" | 21 | #include "core/hle/kernel/process.h" |
| 17 | #include "core/hle/kernel/server_session.h" | 22 | #include "core/hle/kernel/server_session.h" |
| 18 | #include "core/memory.h" | 23 | #include "core/memory.h" |
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 84727f748..9ce52db24 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h | |||
| @@ -5,7 +5,6 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <iterator> | ||
| 9 | #include <memory> | 8 | #include <memory> |
| 10 | #include <string> | 9 | #include <string> |
| 11 | #include <type_traits> | 10 | #include <type_traits> |
| @@ -14,7 +13,7 @@ | |||
| 14 | #include "common/common_types.h" | 13 | #include "common/common_types.h" |
| 15 | #include "common/swap.h" | 14 | #include "common/swap.h" |
| 16 | #include "core/hle/ipc.h" | 15 | #include "core/hle/ipc.h" |
| 17 | #include "core/hle/kernel/kernel.h" | 16 | #include "core/hle/kernel/object.h" |
| 18 | #include "core/hle/kernel/server_session.h" | 17 | #include "core/hle/kernel/server_session.h" |
| 19 | #include "core/hle/kernel/thread.h" | 18 | #include "core/hle/kernel/thread.h" |
| 20 | 19 | ||
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 1beb98566..1b0cd0abf 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -4,8 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | #include "core/hle/kernel/handle_table.h" | 5 | #include "core/hle/kernel/handle_table.h" |
| 6 | #include "core/hle/kernel/kernel.h" | 6 | #include "core/hle/kernel/kernel.h" |
| 7 | #include "core/hle/kernel/memory.h" | ||
| 8 | #include "core/hle/kernel/object_address_table.h" | ||
| 9 | #include "core/hle/kernel/process.h" | 7 | #include "core/hle/kernel/process.h" |
| 10 | #include "core/hle/kernel/resource_limit.h" | 8 | #include "core/hle/kernel/resource_limit.h" |
| 11 | #include "core/hle/kernel/thread.h" | 9 | #include "core/hle/kernel/thread.h" |
| @@ -16,9 +14,7 @@ namespace Kernel { | |||
| 16 | unsigned int Object::next_object_id; | 14 | unsigned int Object::next_object_id; |
| 17 | 15 | ||
| 18 | /// Initialize the kernel | 16 | /// Initialize the kernel |
| 19 | void Init(u32 system_mode) { | 17 | void Init() { |
| 20 | Kernel::MemoryInit(system_mode); | ||
| 21 | |||
| 22 | Kernel::ResourceLimitsInit(); | 18 | Kernel::ResourceLimitsInit(); |
| 23 | Kernel::ThreadingInit(); | 19 | Kernel::ThreadingInit(); |
| 24 | Kernel::TimersInit(); | 20 | Kernel::TimersInit(); |
| @@ -33,13 +29,11 @@ void Init(u32 system_mode) { | |||
| 33 | void Shutdown() { | 29 | void Shutdown() { |
| 34 | // Free all kernel objects | 30 | // Free all kernel objects |
| 35 | g_handle_table.Clear(); | 31 | g_handle_table.Clear(); |
| 36 | g_object_address_table.Clear(); | ||
| 37 | 32 | ||
| 38 | Kernel::ThreadingShutdown(); | 33 | Kernel::ThreadingShutdown(); |
| 39 | 34 | ||
| 40 | Kernel::TimersShutdown(); | 35 | Kernel::TimersShutdown(); |
| 41 | Kernel::ResourceLimitsShutdown(); | 36 | Kernel::ResourceLimitsShutdown(); |
| 42 | Kernel::MemoryShutdown(); | ||
| 43 | } | 37 | } |
| 44 | 38 | ||
| 45 | } // namespace Kernel | 39 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 402ae900f..131311472 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -4,122 +4,12 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <cstddef> | ||
| 8 | #include <string> | ||
| 9 | #include <utility> | ||
| 10 | #include <boost/smart_ptr/intrusive_ptr.hpp> | ||
| 11 | #include "common/assert.h" | ||
| 12 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 13 | 8 | ||
| 14 | namespace Kernel { | 9 | namespace Kernel { |
| 15 | 10 | ||
| 16 | using Handle = u32; | ||
| 17 | |||
| 18 | enum class HandleType : u32 { | ||
| 19 | Unknown, | ||
| 20 | Event, | ||
| 21 | SharedMemory, | ||
| 22 | Thread, | ||
| 23 | Process, | ||
| 24 | AddressArbiter, | ||
| 25 | Timer, | ||
| 26 | ResourceLimit, | ||
| 27 | CodeSet, | ||
| 28 | ClientPort, | ||
| 29 | ServerPort, | ||
| 30 | ClientSession, | ||
| 31 | ServerSession, | ||
| 32 | }; | ||
| 33 | |||
| 34 | enum class ResetType { | ||
| 35 | OneShot, | ||
| 36 | Sticky, | ||
| 37 | Pulse, | ||
| 38 | }; | ||
| 39 | |||
| 40 | class Object : NonCopyable { | ||
| 41 | public: | ||
| 42 | virtual ~Object() {} | ||
| 43 | |||
| 44 | /// Returns a unique identifier for the object. For debugging purposes only. | ||
| 45 | unsigned int GetObjectId() const { | ||
| 46 | return object_id; | ||
| 47 | } | ||
| 48 | |||
| 49 | virtual std::string GetTypeName() const { | ||
| 50 | return "[BAD KERNEL OBJECT TYPE]"; | ||
| 51 | } | ||
| 52 | virtual std::string GetName() const { | ||
| 53 | return "[UNKNOWN KERNEL OBJECT]"; | ||
| 54 | } | ||
| 55 | virtual Kernel::HandleType GetHandleType() const = 0; | ||
| 56 | |||
| 57 | /** | ||
| 58 | * Check if a thread can wait on the object | ||
| 59 | * @return True if a thread can wait on the object, otherwise false | ||
| 60 | */ | ||
| 61 | bool IsWaitable() const { | ||
| 62 | switch (GetHandleType()) { | ||
| 63 | case HandleType::Event: | ||
| 64 | case HandleType::Thread: | ||
| 65 | case HandleType::Timer: | ||
| 66 | case HandleType::ServerPort: | ||
| 67 | case HandleType::ServerSession: | ||
| 68 | return true; | ||
| 69 | |||
| 70 | case HandleType::Unknown: | ||
| 71 | case HandleType::SharedMemory: | ||
| 72 | case HandleType::Process: | ||
| 73 | case HandleType::AddressArbiter: | ||
| 74 | case HandleType::ResourceLimit: | ||
| 75 | case HandleType::CodeSet: | ||
| 76 | case HandleType::ClientPort: | ||
| 77 | case HandleType::ClientSession: | ||
| 78 | return false; | ||
| 79 | } | ||
| 80 | |||
| 81 | UNREACHABLE(); | ||
| 82 | } | ||
| 83 | |||
| 84 | public: | ||
| 85 | static unsigned int next_object_id; | ||
| 86 | |||
| 87 | private: | ||
| 88 | friend void intrusive_ptr_add_ref(Object*); | ||
| 89 | friend void intrusive_ptr_release(Object*); | ||
| 90 | |||
| 91 | unsigned int ref_count = 0; | ||
| 92 | unsigned int object_id = next_object_id++; | ||
| 93 | }; | ||
| 94 | |||
| 95 | // Special functions used by boost::instrusive_ptr to do automatic ref-counting | ||
| 96 | inline void intrusive_ptr_add_ref(Object* object) { | ||
| 97 | ++object->ref_count; | ||
| 98 | } | ||
| 99 | |||
| 100 | inline void intrusive_ptr_release(Object* object) { | ||
| 101 | if (--object->ref_count == 0) { | ||
| 102 | delete object; | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | template <typename T> | ||
| 107 | using SharedPtr = boost::intrusive_ptr<T>; | ||
| 108 | |||
| 109 | /** | ||
| 110 | * Attempts to downcast the given Object pointer to a pointer to T. | ||
| 111 | * @return Derived pointer to the object, or `nullptr` if `object` isn't of type T. | ||
| 112 | */ | ||
| 113 | template <typename T> | ||
| 114 | inline SharedPtr<T> DynamicObjectCast(SharedPtr<Object> object) { | ||
| 115 | if (object != nullptr && object->GetHandleType() == T::HANDLE_TYPE) { | ||
| 116 | return boost::static_pointer_cast<T>(std::move(object)); | ||
| 117 | } | ||
| 118 | return nullptr; | ||
| 119 | } | ||
| 120 | |||
| 121 | /// Initialize the kernel with the specified system mode. | 11 | /// Initialize the kernel with the specified system mode. |
| 122 | void Init(u32 system_mode); | 12 | void Init(); |
| 123 | 13 | ||
| 124 | /// Shutdown the kernel | 14 | /// Shutdown the kernel |
| 125 | void Shutdown(); | 15 | void Shutdown(); |
diff --git a/src/core/hle/kernel/memory.cpp b/src/core/hle/kernel/memory.cpp deleted file mode 100644 index 94eac677c..000000000 --- a/src/core/hle/kernel/memory.cpp +++ /dev/null | |||
| @@ -1,92 +0,0 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | #include <cinttypes> | ||
| 7 | #include <map> | ||
| 8 | #include <memory> | ||
| 9 | #include <utility> | ||
| 10 | #include <vector> | ||
| 11 | #include "common/assert.h" | ||
| 12 | #include "common/common_types.h" | ||
| 13 | #include "common/logging/log.h" | ||
| 14 | #include "core/hle/kernel/memory.h" | ||
| 15 | #include "core/hle/kernel/vm_manager.h" | ||
| 16 | #include "core/hle/result.h" | ||
| 17 | #include "core/memory.h" | ||
| 18 | #include "core/memory_setup.h" | ||
| 19 | |||
| 20 | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 21 | |||
| 22 | namespace Kernel { | ||
| 23 | |||
| 24 | MemoryRegionInfo memory_regions[3]; | ||
| 25 | |||
| 26 | /// Size of the APPLICATION, SYSTEM and BASE memory regions (respectively) for each system | ||
| 27 | /// memory configuration type. | ||
| 28 | static const u32 memory_region_sizes[8][3] = { | ||
| 29 | // Old 3DS layouts | ||
| 30 | {0x04000000, 0x02C00000, 0x01400000}, // 0 | ||
| 31 | {/* This appears to be unused. */}, // 1 | ||
| 32 | {0x06000000, 0x00C00000, 0x01400000}, // 2 | ||
| 33 | {0x05000000, 0x01C00000, 0x01400000}, // 3 | ||
| 34 | {0x04800000, 0x02400000, 0x01400000}, // 4 | ||
| 35 | {0x02000000, 0x04C00000, 0x01400000}, // 5 | ||
| 36 | |||
| 37 | // New 3DS layouts | ||
| 38 | {0x07C00000, 0x06400000, 0x02000000}, // 6 | ||
| 39 | {0x0B200000, 0x02E00000, 0x02000000}, // 7 | ||
| 40 | }; | ||
| 41 | |||
| 42 | void MemoryInit(u32 mem_type) { | ||
| 43 | // TODO(yuriks): On the n3DS, all o3DS configurations (<=5) are forced to 6 instead. | ||
| 44 | ASSERT_MSG(mem_type <= 5, "New 3DS memory configuration aren't supported yet!"); | ||
| 45 | ASSERT(mem_type != 1); | ||
| 46 | |||
| 47 | // The kernel allocation regions (APPLICATION, SYSTEM and BASE) are laid out in sequence, with | ||
| 48 | // the sizes specified in the memory_region_sizes table. | ||
| 49 | VAddr base = 0; | ||
| 50 | for (int i = 0; i < 3; ++i) { | ||
| 51 | memory_regions[i].base = base; | ||
| 52 | memory_regions[i].size = memory_region_sizes[mem_type][i]; | ||
| 53 | memory_regions[i].used = 0; | ||
| 54 | memory_regions[i].linear_heap_memory = std::make_shared<std::vector<u8>>(); | ||
| 55 | // Reserve enough space for this region of FCRAM. | ||
| 56 | // We do not want this block of memory to be relocated when allocating from it. | ||
| 57 | memory_regions[i].linear_heap_memory->reserve(memory_regions[i].size); | ||
| 58 | |||
| 59 | base += memory_regions[i].size; | ||
| 60 | } | ||
| 61 | |||
| 62 | // We must've allocated the entire FCRAM by the end | ||
| 63 | ASSERT(base == Memory::FCRAM_SIZE); | ||
| 64 | } | ||
| 65 | |||
| 66 | void MemoryShutdown() { | ||
| 67 | for (auto& region : memory_regions) { | ||
| 68 | region.base = 0; | ||
| 69 | region.size = 0; | ||
| 70 | region.used = 0; | ||
| 71 | region.linear_heap_memory = nullptr; | ||
| 72 | } | ||
| 73 | } | ||
| 74 | |||
| 75 | MemoryRegionInfo* GetMemoryRegion(MemoryRegion region) { | ||
| 76 | switch (region) { | ||
| 77 | case MemoryRegion::APPLICATION: | ||
| 78 | return &memory_regions[0]; | ||
| 79 | case MemoryRegion::SYSTEM: | ||
| 80 | return &memory_regions[1]; | ||
| 81 | case MemoryRegion::BASE: | ||
| 82 | return &memory_regions[2]; | ||
| 83 | default: | ||
| 84 | UNREACHABLE(); | ||
| 85 | } | ||
| 86 | } | ||
| 87 | |||
| 88 | void HandleSpecialMapping(VMManager& address_space, const AddressMapping& mapping) {} | ||
| 89 | |||
| 90 | void MapSharedPages(VMManager& address_space) {} | ||
| 91 | |||
| 92 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/memory.h b/src/core/hle/kernel/memory.h deleted file mode 100644 index 61e30c679..000000000 --- a/src/core/hle/kernel/memory.h +++ /dev/null | |||
| @@ -1,31 +0,0 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | #include "common/common_types.h" | ||
| 9 | #include "core/hle/kernel/process.h" | ||
| 10 | |||
| 11 | namespace Kernel { | ||
| 12 | |||
| 13 | class VMManager; | ||
| 14 | |||
| 15 | struct MemoryRegionInfo { | ||
| 16 | u64 base; // Not an address, but offset from start of FCRAM | ||
| 17 | u64 size; | ||
| 18 | u64 used; | ||
| 19 | |||
| 20 | std::shared_ptr<std::vector<u8>> linear_heap_memory; | ||
| 21 | }; | ||
| 22 | |||
| 23 | void MemoryInit(u32 mem_type); | ||
| 24 | void MemoryShutdown(); | ||
| 25 | MemoryRegionInfo* GetMemoryRegion(MemoryRegion region); | ||
| 26 | |||
| 27 | void HandleSpecialMapping(VMManager& address_space, const AddressMapping& mapping); | ||
| 28 | void MapSharedPages(VMManager& address_space); | ||
| 29 | |||
| 30 | extern MemoryRegionInfo memory_regions[3]; | ||
| 31 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index feb7b88d2..cb7f58b35 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp | |||
| @@ -3,16 +3,19 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <map> | 5 | #include <map> |
| 6 | #include <utility> | ||
| 6 | #include <vector> | 7 | #include <vector> |
| 8 | |||
| 7 | #include <boost/range/algorithm_ext/erase.hpp> | 9 | #include <boost/range/algorithm_ext/erase.hpp> |
| 10 | |||
| 8 | #include "common/assert.h" | 11 | #include "common/assert.h" |
| 9 | #include "core/core.h" | 12 | #include "core/core.h" |
| 10 | #include "core/hle/kernel/errors.h" | 13 | #include "core/hle/kernel/errors.h" |
| 11 | #include "core/hle/kernel/handle_table.h" | 14 | #include "core/hle/kernel/handle_table.h" |
| 12 | #include "core/hle/kernel/kernel.h" | ||
| 13 | #include "core/hle/kernel/mutex.h" | 15 | #include "core/hle/kernel/mutex.h" |
| 14 | #include "core/hle/kernel/object_address_table.h" | 16 | #include "core/hle/kernel/object.h" |
| 15 | #include "core/hle/kernel/thread.h" | 17 | #include "core/hle/kernel/thread.h" |
| 18 | #include "core/hle/result.h" | ||
| 16 | 19 | ||
| 17 | namespace Kernel { | 20 | namespace Kernel { |
| 18 | 21 | ||
diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index 3117e7c70..45268bbe9 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h | |||
| @@ -4,12 +4,10 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <string> | ||
| 8 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 9 | #include "common/swap.h" | 8 | #include "core/hle/kernel/object.h" |
| 10 | #include "core/hle/kernel/kernel.h" | 9 | |
| 11 | #include "core/hle/kernel/wait_object.h" | 10 | union ResultCode; |
| 12 | #include "core/hle/result.h" | ||
| 13 | 11 | ||
| 14 | namespace Kernel { | 12 | namespace Kernel { |
| 15 | 13 | ||
diff --git a/src/core/hle/kernel/object.cpp b/src/core/hle/kernel/object.cpp new file mode 100644 index 000000000..cdba272f5 --- /dev/null +++ b/src/core/hle/kernel/object.cpp | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | // Copyright 2018 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/assert.h" | ||
| 6 | #include "core/hle/kernel/object.h" | ||
| 7 | |||
| 8 | namespace Kernel { | ||
| 9 | |||
| 10 | Object::~Object() = default; | ||
| 11 | |||
| 12 | bool Object::IsWaitable() const { | ||
| 13 | switch (GetHandleType()) { | ||
| 14 | case HandleType::Event: | ||
| 15 | case HandleType::Thread: | ||
| 16 | case HandleType::Timer: | ||
| 17 | case HandleType::ServerPort: | ||
| 18 | case HandleType::ServerSession: | ||
| 19 | return true; | ||
| 20 | |||
| 21 | case HandleType::Unknown: | ||
| 22 | case HandleType::SharedMemory: | ||
| 23 | case HandleType::Process: | ||
| 24 | case HandleType::AddressArbiter: | ||
| 25 | case HandleType::ResourceLimit: | ||
| 26 | case HandleType::CodeSet: | ||
| 27 | case HandleType::ClientPort: | ||
| 28 | case HandleType::ClientSession: | ||
| 29 | return false; | ||
| 30 | } | ||
| 31 | |||
| 32 | UNREACHABLE(); | ||
| 33 | } | ||
| 34 | |||
| 35 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h new file mode 100644 index 000000000..83df68dfd --- /dev/null +++ b/src/core/hle/kernel/object.h | |||
| @@ -0,0 +1,100 @@ | |||
| 1 | // Copyright 2018 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <string> | ||
| 8 | #include <utility> | ||
| 9 | |||
| 10 | #include <boost/smart_ptr/intrusive_ptr.hpp> | ||
| 11 | |||
| 12 | #include "common/common_types.h" | ||
| 13 | |||
| 14 | namespace Kernel { | ||
| 15 | |||
| 16 | using Handle = u32; | ||
| 17 | |||
| 18 | enum class HandleType : u32 { | ||
| 19 | Unknown, | ||
| 20 | Event, | ||
| 21 | SharedMemory, | ||
| 22 | Thread, | ||
| 23 | Process, | ||
| 24 | AddressArbiter, | ||
| 25 | Timer, | ||
| 26 | ResourceLimit, | ||
| 27 | CodeSet, | ||
| 28 | ClientPort, | ||
| 29 | ServerPort, | ||
| 30 | ClientSession, | ||
| 31 | ServerSession, | ||
| 32 | }; | ||
| 33 | |||
| 34 | enum class ResetType { | ||
| 35 | OneShot, | ||
| 36 | Sticky, | ||
| 37 | Pulse, | ||
| 38 | }; | ||
| 39 | |||
| 40 | class Object : NonCopyable { | ||
| 41 | public: | ||
| 42 | virtual ~Object(); | ||
| 43 | |||
| 44 | /// Returns a unique identifier for the object. For debugging purposes only. | ||
| 45 | unsigned int GetObjectId() const { | ||
| 46 | return object_id; | ||
| 47 | } | ||
| 48 | |||
| 49 | virtual std::string GetTypeName() const { | ||
| 50 | return "[BAD KERNEL OBJECT TYPE]"; | ||
| 51 | } | ||
| 52 | virtual std::string GetName() const { | ||
| 53 | return "[UNKNOWN KERNEL OBJECT]"; | ||
| 54 | } | ||
| 55 | virtual HandleType GetHandleType() const = 0; | ||
| 56 | |||
| 57 | /** | ||
| 58 | * Check if a thread can wait on the object | ||
| 59 | * @return True if a thread can wait on the object, otherwise false | ||
| 60 | */ | ||
| 61 | bool IsWaitable() const; | ||
| 62 | |||
| 63 | public: | ||
| 64 | static unsigned int next_object_id; | ||
| 65 | |||
| 66 | private: | ||
| 67 | friend void intrusive_ptr_add_ref(Object*); | ||
| 68 | friend void intrusive_ptr_release(Object*); | ||
| 69 | |||
| 70 | unsigned int ref_count = 0; | ||
| 71 | unsigned int object_id = next_object_id++; | ||
| 72 | }; | ||
| 73 | |||
| 74 | // Special functions used by boost::instrusive_ptr to do automatic ref-counting | ||
| 75 | inline void intrusive_ptr_add_ref(Object* object) { | ||
| 76 | ++object->ref_count; | ||
| 77 | } | ||
| 78 | |||
| 79 | inline void intrusive_ptr_release(Object* object) { | ||
| 80 | if (--object->ref_count == 0) { | ||
| 81 | delete object; | ||
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 85 | template <typename T> | ||
| 86 | using SharedPtr = boost::intrusive_ptr<T>; | ||
| 87 | |||
| 88 | /** | ||
| 89 | * Attempts to downcast the given Object pointer to a pointer to T. | ||
| 90 | * @return Derived pointer to the object, or `nullptr` if `object` isn't of type T. | ||
| 91 | */ | ||
| 92 | template <typename T> | ||
| 93 | inline SharedPtr<T> DynamicObjectCast(SharedPtr<Object> object) { | ||
| 94 | if (object != nullptr && object->GetHandleType() == T::HANDLE_TYPE) { | ||
| 95 | return boost::static_pointer_cast<T>(std::move(object)); | ||
| 96 | } | ||
| 97 | return nullptr; | ||
| 98 | } | ||
| 99 | |||
| 100 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/object_address_table.cpp b/src/core/hle/kernel/object_address_table.cpp deleted file mode 100644 index ca8a833a1..000000000 --- a/src/core/hle/kernel/object_address_table.cpp +++ /dev/null | |||
| @@ -1,36 +0,0 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <utility> | ||
| 6 | |||
| 7 | #include "common/assert.h" | ||
| 8 | #include "core/hle/kernel/object_address_table.h" | ||
| 9 | |||
| 10 | namespace Kernel { | ||
| 11 | |||
| 12 | ObjectAddressTable g_object_address_table; | ||
| 13 | |||
| 14 | void ObjectAddressTable::Insert(VAddr addr, SharedPtr<Object> obj) { | ||
| 15 | ASSERT_MSG(objects.find(addr) == objects.end(), "Object already exists with addr=0x{:X}", addr); | ||
| 16 | objects[addr] = std::move(obj); | ||
| 17 | } | ||
| 18 | |||
| 19 | void ObjectAddressTable::Close(VAddr addr) { | ||
| 20 | ASSERT_MSG(objects.find(addr) != objects.end(), "Object does not exist with addr=0x{:X}", addr); | ||
| 21 | objects.erase(addr); | ||
| 22 | } | ||
| 23 | |||
| 24 | SharedPtr<Object> ObjectAddressTable::GetGeneric(VAddr addr) const { | ||
| 25 | auto iter = objects.find(addr); | ||
| 26 | if (iter != objects.end()) { | ||
| 27 | return iter->second; | ||
| 28 | } | ||
| 29 | return {}; | ||
| 30 | } | ||
| 31 | |||
| 32 | void ObjectAddressTable::Clear() { | ||
| 33 | objects.clear(); | ||
| 34 | } | ||
| 35 | |||
| 36 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/object_address_table.h b/src/core/hle/kernel/object_address_table.h deleted file mode 100644 index a09004b32..000000000 --- a/src/core/hle/kernel/object_address_table.h +++ /dev/null | |||
| @@ -1,62 +0,0 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <map> | ||
| 8 | #include "common/common_types.h" | ||
| 9 | #include "core/hle/kernel/kernel.h" | ||
| 10 | |||
| 11 | namespace Kernel { | ||
| 12 | |||
| 13 | /** | ||
| 14 | * This class is used to keep a table of Kernel objects and their respective addresses in emulated | ||
| 15 | * memory. For certain Switch SVCs, Kernel objects are referenced by an address to an object the | ||
| 16 | * guest application manages, so we use this table to look these kernel objects up. This is similiar | ||
| 17 | * to the HandleTable class. | ||
| 18 | */ | ||
| 19 | class ObjectAddressTable final : NonCopyable { | ||
| 20 | public: | ||
| 21 | ObjectAddressTable() = default; | ||
| 22 | |||
| 23 | /** | ||
| 24 | * Inserts an object and address pair into the table. | ||
| 25 | */ | ||
| 26 | void Insert(VAddr addr, SharedPtr<Object> obj); | ||
| 27 | |||
| 28 | /** | ||
| 29 | * Closes an object by its address, removing it from the table and decreasing the object's | ||
| 30 | * ref-count. | ||
| 31 | * @return `RESULT_SUCCESS` or one of the following errors: | ||
| 32 | * - `ERR_INVALID_HANDLE`: an invalid handle was passed in. | ||
| 33 | */ | ||
| 34 | void Close(VAddr addr); | ||
| 35 | |||
| 36 | /** | ||
| 37 | * Looks up an object by its address. | ||
| 38 | * @return Pointer to the looked-up object, or `nullptr` if the handle is not valid. | ||
| 39 | */ | ||
| 40 | SharedPtr<Object> GetGeneric(VAddr addr) const; | ||
| 41 | |||
| 42 | /** | ||
| 43 | * Looks up an object by its address while verifying its type. | ||
| 44 | * @return Pointer to the looked-up object, or `nullptr` if the handle is not valid or its | ||
| 45 | * type differs from the requested one. | ||
| 46 | */ | ||
| 47 | template <class T> | ||
| 48 | SharedPtr<T> Get(VAddr addr) const { | ||
| 49 | return DynamicObjectCast<T>(GetGeneric(addr)); | ||
| 50 | } | ||
| 51 | |||
| 52 | /// Closes all addresses held in this table. | ||
| 53 | void Clear(); | ||
| 54 | |||
| 55 | private: | ||
| 56 | /// Stores the Object referenced by the address | ||
| 57 | std::map<VAddr, SharedPtr<Object>> objects; | ||
| 58 | }; | ||
| 59 | |||
| 60 | extern ObjectAddressTable g_object_address_table; | ||
| 61 | |||
| 62 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 0c0506085..edf34c5a3 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp | |||
| @@ -8,7 +8,6 @@ | |||
| 8 | #include "common/common_funcs.h" | 8 | #include "common/common_funcs.h" |
| 9 | #include "common/logging/log.h" | 9 | #include "common/logging/log.h" |
| 10 | #include "core/hle/kernel/errors.h" | 10 | #include "core/hle/kernel/errors.h" |
| 11 | #include "core/hle/kernel/memory.h" | ||
| 12 | #include "core/hle/kernel/process.h" | 11 | #include "core/hle/kernel/process.h" |
| 13 | #include "core/hle/kernel/resource_limit.h" | 12 | #include "core/hle/kernel/resource_limit.h" |
| 14 | #include "core/hle/kernel/thread.h" | 13 | #include "core/hle/kernel/thread.h" |
| @@ -125,14 +124,6 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) { | |||
| 125 | std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size, | 124 | std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size, |
| 126 | MemoryState::Mapped) | 125 | MemoryState::Mapped) |
| 127 | .Unwrap(); | 126 | .Unwrap(); |
| 128 | misc_memory_used += stack_size; | ||
| 129 | memory_region->used += stack_size; | ||
| 130 | |||
| 131 | // Map special address mappings | ||
| 132 | MapSharedPages(vm_manager); | ||
| 133 | for (const auto& mapping : address_mappings) { | ||
| 134 | HandleSpecialMapping(vm_manager, mapping); | ||
| 135 | } | ||
| 136 | 127 | ||
| 137 | vm_manager.LogLayout(); | 128 | vm_manager.LogLayout(); |
| 138 | status = ProcessStatus::Running; | 129 | status = ProcessStatus::Running; |
| @@ -141,37 +132,19 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) { | |||
| 141 | } | 132 | } |
| 142 | 133 | ||
| 143 | void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) { | 134 | void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) { |
| 144 | memory_region = GetMemoryRegion(flags.memory_region); | 135 | const auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions, |
| 145 | 136 | MemoryState memory_state) { | |
| 146 | auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions, | ||
| 147 | MemoryState memory_state) { | ||
| 148 | auto vma = vm_manager | 137 | auto vma = vm_manager |
| 149 | .MapMemoryBlock(segment.addr + base_addr, module_->memory, segment.offset, | 138 | .MapMemoryBlock(segment.addr + base_addr, module_->memory, segment.offset, |
| 150 | segment.size, memory_state) | 139 | segment.size, memory_state) |
| 151 | .Unwrap(); | 140 | .Unwrap(); |
| 152 | vm_manager.Reprotect(vma, permissions); | 141 | vm_manager.Reprotect(vma, permissions); |
| 153 | misc_memory_used += segment.size; | ||
| 154 | memory_region->used += segment.size; | ||
| 155 | }; | 142 | }; |
| 156 | 143 | ||
| 157 | // Map CodeSet segments | 144 | // Map CodeSet segments |
| 158 | MapSegment(module_->code, VMAPermission::ReadExecute, MemoryState::CodeStatic); | 145 | MapSegment(module_->CodeSegment(), VMAPermission::ReadExecute, MemoryState::CodeStatic); |
| 159 | MapSegment(module_->rodata, VMAPermission::Read, MemoryState::CodeMutable); | 146 | MapSegment(module_->RODataSegment(), VMAPermission::Read, MemoryState::CodeMutable); |
| 160 | MapSegment(module_->data, VMAPermission::ReadWrite, MemoryState::CodeMutable); | 147 | MapSegment(module_->DataSegment(), VMAPermission::ReadWrite, MemoryState::CodeMutable); |
| 161 | } | ||
| 162 | |||
| 163 | VAddr Process::GetLinearHeapAreaAddress() const { | ||
| 164 | // Starting from system version 8.0.0 a new linear heap layout is supported to allow usage of | ||
| 165 | // the extra RAM in the n3DS. | ||
| 166 | return kernel_version < 0x22C ? Memory::LINEAR_HEAP_VADDR : Memory::NEW_LINEAR_HEAP_VADDR; | ||
| 167 | } | ||
| 168 | |||
| 169 | VAddr Process::GetLinearHeapBase() const { | ||
| 170 | return GetLinearHeapAreaAddress() + memory_region->base; | ||
| 171 | } | ||
| 172 | |||
| 173 | VAddr Process::GetLinearHeapLimit() const { | ||
| 174 | return GetLinearHeapBase() + memory_region->size; | ||
| 175 | } | 148 | } |
| 176 | 149 | ||
| 177 | ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission perms) { | 150 | ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission perms) { |
| @@ -206,7 +179,6 @@ ResultVal<VAddr> Process::HeapAllocate(VAddr target, u64 size, VMAPermission per | |||
| 206 | vm_manager.Reprotect(vma, perms); | 179 | vm_manager.Reprotect(vma, perms); |
| 207 | 180 | ||
| 208 | heap_used = size; | 181 | heap_used = size; |
| 209 | memory_region->used += size; | ||
| 210 | 182 | ||
| 211 | return MakeResult<VAddr>(heap_end - size); | 183 | return MakeResult<VAddr>(heap_end - size); |
| 212 | } | 184 | } |
| @@ -226,52 +198,6 @@ ResultCode Process::HeapFree(VAddr target, u32 size) { | |||
| 226 | return result; | 198 | return result; |
| 227 | 199 | ||
| 228 | heap_used -= size; | 200 | heap_used -= size; |
| 229 | memory_region->used -= size; | ||
| 230 | |||
| 231 | return RESULT_SUCCESS; | ||
| 232 | } | ||
| 233 | |||
| 234 | ResultVal<VAddr> Process::LinearAllocate(VAddr target, u32 size, VMAPermission perms) { | ||
| 235 | UNIMPLEMENTED(); | ||
| 236 | return {}; | ||
| 237 | } | ||
| 238 | |||
| 239 | ResultCode Process::LinearFree(VAddr target, u32 size) { | ||
| 240 | auto& linheap_memory = memory_region->linear_heap_memory; | ||
| 241 | |||
| 242 | if (target < GetLinearHeapBase() || target + size > GetLinearHeapLimit() || | ||
| 243 | target + size < target) { | ||
| 244 | |||
| 245 | return ERR_INVALID_ADDRESS; | ||
| 246 | } | ||
| 247 | |||
| 248 | if (size == 0) { | ||
| 249 | return RESULT_SUCCESS; | ||
| 250 | } | ||
| 251 | |||
| 252 | VAddr heap_end = GetLinearHeapBase() + (u32)linheap_memory->size(); | ||
| 253 | if (target + size > heap_end) { | ||
| 254 | return ERR_INVALID_ADDRESS_STATE; | ||
| 255 | } | ||
| 256 | |||
| 257 | ResultCode result = vm_manager.UnmapRange(target, size); | ||
| 258 | if (result.IsError()) | ||
| 259 | return result; | ||
| 260 | |||
| 261 | linear_heap_used -= size; | ||
| 262 | memory_region->used -= size; | ||
| 263 | |||
| 264 | if (target + size == heap_end) { | ||
| 265 | // End of linear heap has been freed, so check what's the last allocated block in it and | ||
| 266 | // reduce the size. | ||
| 267 | auto vma = vm_manager.FindVMA(target); | ||
| 268 | ASSERT(vma != vm_manager.vma_map.end()); | ||
| 269 | ASSERT(vma->second.type == VMAType::Free); | ||
| 270 | VAddr new_end = vma->second.base; | ||
| 271 | if (new_end >= GetLinearHeapBase()) { | ||
| 272 | linheap_memory->resize(new_end - GetLinearHeapBase()); | ||
| 273 | } | ||
| 274 | } | ||
| 275 | 201 | ||
| 276 | return RESULT_SUCCESS; | 202 | return RESULT_SUCCESS; |
| 277 | } | 203 | } |
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 68e77a4d1..992689186 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | ||
| 7 | #include <bitset> | 8 | #include <bitset> |
| 8 | #include <cstddef> | 9 | #include <cstddef> |
| 9 | #include <memory> | 10 | #include <memory> |
| @@ -12,7 +13,7 @@ | |||
| 12 | #include <boost/container/static_vector.hpp> | 13 | #include <boost/container/static_vector.hpp> |
| 13 | #include "common/bit_field.h" | 14 | #include "common/bit_field.h" |
| 14 | #include "common/common_types.h" | 15 | #include "common/common_types.h" |
| 15 | #include "core/hle/kernel/kernel.h" | 16 | #include "core/hle/kernel/object.h" |
| 16 | #include "core/hle/kernel/thread.h" | 17 | #include "core/hle/kernel/thread.h" |
| 17 | #include "core/hle/kernel/vm_manager.h" | 18 | #include "core/hle/kernel/vm_manager.h" |
| 18 | 19 | ||
| @@ -53,9 +54,14 @@ union ProcessFlags { | |||
| 53 | enum class ProcessStatus { Created, Running, Exited }; | 54 | enum class ProcessStatus { Created, Running, Exited }; |
| 54 | 55 | ||
| 55 | class ResourceLimit; | 56 | class ResourceLimit; |
| 56 | struct MemoryRegionInfo; | ||
| 57 | 57 | ||
| 58 | struct CodeSet final : public Object { | 58 | struct CodeSet final : public Object { |
| 59 | struct Segment { | ||
| 60 | size_t offset = 0; | ||
| 61 | VAddr addr = 0; | ||
| 62 | u32 size = 0; | ||
| 63 | }; | ||
| 64 | |||
| 59 | static SharedPtr<CodeSet> Create(std::string name); | 65 | static SharedPtr<CodeSet> Create(std::string name); |
| 60 | 66 | ||
| 61 | std::string GetTypeName() const override { | 67 | std::string GetTypeName() const override { |
| @@ -70,24 +76,38 @@ struct CodeSet final : public Object { | |||
| 70 | return HANDLE_TYPE; | 76 | return HANDLE_TYPE; |
| 71 | } | 77 | } |
| 72 | 78 | ||
| 73 | /// Name of the process | 79 | Segment& CodeSegment() { |
| 74 | std::string name; | 80 | return segments[0]; |
| 81 | } | ||
| 75 | 82 | ||
| 76 | std::shared_ptr<std::vector<u8>> memory; | 83 | const Segment& CodeSegment() const { |
| 84 | return segments[0]; | ||
| 85 | } | ||
| 77 | 86 | ||
| 78 | struct Segment { | 87 | Segment& RODataSegment() { |
| 79 | size_t offset = 0; | 88 | return segments[1]; |
| 80 | VAddr addr = 0; | 89 | } |
| 81 | u32 size = 0; | 90 | |
| 82 | }; | 91 | const Segment& RODataSegment() const { |
| 92 | return segments[1]; | ||
| 93 | } | ||
| 94 | |||
| 95 | Segment& DataSegment() { | ||
| 96 | return segments[2]; | ||
| 97 | } | ||
| 98 | |||
| 99 | const Segment& DataSegment() const { | ||
| 100 | return segments[2]; | ||
| 101 | } | ||
| 83 | 102 | ||
| 84 | Segment segments[3]; | 103 | std::shared_ptr<std::vector<u8>> memory; |
| 85 | Segment& code = segments[0]; | ||
| 86 | Segment& rodata = segments[1]; | ||
| 87 | Segment& data = segments[2]; | ||
| 88 | 104 | ||
| 105 | std::array<Segment, 3> segments; | ||
| 89 | VAddr entrypoint; | 106 | VAddr entrypoint; |
| 90 | 107 | ||
| 108 | /// Name of the process | ||
| 109 | std::string name; | ||
| 110 | |||
| 91 | private: | 111 | private: |
| 92 | CodeSet(); | 112 | CodeSet(); |
| 93 | ~CodeSet() override; | 113 | ~CodeSet() override; |
| @@ -163,12 +183,11 @@ public: | |||
| 163 | // This makes deallocation and reallocation of holes fast and keeps process memory contiguous | 183 | // This makes deallocation and reallocation of holes fast and keeps process memory contiguous |
| 164 | // in the emulator address space, allowing Memory::GetPointer to be reasonably safe. | 184 | // in the emulator address space, allowing Memory::GetPointer to be reasonably safe. |
| 165 | std::shared_ptr<std::vector<u8>> heap_memory; | 185 | std::shared_ptr<std::vector<u8>> heap_memory; |
| 166 | // The left/right bounds of the address space covered by heap_memory. | ||
| 167 | VAddr heap_start = 0, heap_end = 0; | ||
| 168 | 186 | ||
| 169 | u64 heap_used = 0, linear_heap_used = 0, misc_memory_used = 0; | 187 | // The left/right bounds of the address space covered by heap_memory. |
| 170 | 188 | VAddr heap_start = 0; | |
| 171 | MemoryRegionInfo* memory_region = nullptr; | 189 | VAddr heap_end = 0; |
| 190 | u64 heap_used = 0; | ||
| 172 | 191 | ||
| 173 | /// The Thread Local Storage area is allocated as processes create threads, | 192 | /// The Thread Local Storage area is allocated as processes create threads, |
| 174 | /// each TLS area is 0x200 bytes, so one page (0x1000) is split up in 8 parts, and each part | 193 | /// each TLS area is 0x200 bytes, so one page (0x1000) is split up in 8 parts, and each part |
| @@ -179,16 +198,9 @@ public: | |||
| 179 | 198 | ||
| 180 | std::string name; | 199 | std::string name; |
| 181 | 200 | ||
| 182 | VAddr GetLinearHeapAreaAddress() const; | ||
| 183 | VAddr GetLinearHeapBase() const; | ||
| 184 | VAddr GetLinearHeapLimit() const; | ||
| 185 | |||
| 186 | ResultVal<VAddr> HeapAllocate(VAddr target, u64 size, VMAPermission perms); | 201 | ResultVal<VAddr> HeapAllocate(VAddr target, u64 size, VMAPermission perms); |
| 187 | ResultCode HeapFree(VAddr target, u32 size); | 202 | ResultCode HeapFree(VAddr target, u32 size); |
| 188 | 203 | ||
| 189 | ResultVal<VAddr> LinearAllocate(VAddr target, u32 size, VMAPermission perms); | ||
| 190 | ResultCode LinearFree(VAddr target, u32 size); | ||
| 191 | |||
| 192 | ResultCode MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size); | 204 | ResultCode MirrorMemory(VAddr dst_addr, VAddr src_addr, u64 size); |
| 193 | 205 | ||
| 194 | ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size); | 206 | ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size); |
diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h index cc689a27a..0fa141db3 100644 --- a/src/core/hle/kernel/resource_limit.h +++ b/src/core/hle/kernel/resource_limit.h | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 8 | #include "core/hle/kernel/kernel.h" | 8 | #include "core/hle/kernel/object.h" |
| 9 | 9 | ||
| 10 | namespace Kernel { | 10 | namespace Kernel { |
| 11 | 11 | ||
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index e307eec98..94065c736 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp | |||
| @@ -2,8 +2,12 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <algorithm> | ||
| 5 | #include <utility> | 6 | #include <utility> |
| 6 | 7 | ||
| 8 | #include "common/assert.h" | ||
| 9 | #include "common/logging/log.h" | ||
| 10 | #include "core/arm/arm_interface.h" | ||
| 7 | #include "core/core.h" | 11 | #include "core/core.h" |
| 8 | #include "core/core_timing.h" | 12 | #include "core/core_timing.h" |
| 9 | #include "core/hle/kernel/process.h" | 13 | #include "core/hle/kernel/process.h" |
diff --git a/src/core/hle/kernel/scheduler.h b/src/core/hle/kernel/scheduler.h index a3b5fb8ca..1a4ee8f36 100644 --- a/src/core/hle/kernel/scheduler.h +++ b/src/core/hle/kernel/scheduler.h | |||
| @@ -8,9 +8,11 @@ | |||
| 8 | #include <vector> | 8 | #include <vector> |
| 9 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 10 | #include "common/thread_queue_list.h" | 10 | #include "common/thread_queue_list.h" |
| 11 | #include "core/arm/arm_interface.h" | 11 | #include "core/hle/kernel/object.h" |
| 12 | #include "core/hle/kernel/thread.h" | 12 | #include "core/hle/kernel/thread.h" |
| 13 | 13 | ||
| 14 | class ARM_Interface; | ||
| 15 | |||
| 14 | namespace Kernel { | 16 | namespace Kernel { |
| 15 | 17 | ||
| 16 | class Scheduler final { | 18 | class Scheduler final { |
diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp index 0b7061403..7b6211fd8 100644 --- a/src/core/hle/kernel/server_port.cpp +++ b/src/core/hle/kernel/server_port.cpp | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | #include "common/assert.h" | 6 | #include "common/assert.h" |
| 7 | #include "core/hle/kernel/client_port.h" | 7 | #include "core/hle/kernel/client_port.h" |
| 8 | #include "core/hle/kernel/errors.h" | 8 | #include "core/hle/kernel/errors.h" |
| 9 | #include "core/hle/kernel/kernel.h" | 9 | #include "core/hle/kernel/object.h" |
| 10 | #include "core/hle/kernel/server_port.h" | 10 | #include "core/hle/kernel/server_port.h" |
| 11 | #include "core/hle/kernel/server_session.h" | 11 | #include "core/hle/kernel/server_session.h" |
| 12 | #include "core/hle/kernel/thread.h" | 12 | #include "core/hle/kernel/thread.h" |
diff --git a/src/core/hle/kernel/server_port.h b/src/core/hle/kernel/server_port.h index 9ef4ecc35..7f6d6b3eb 100644 --- a/src/core/hle/kernel/server_port.h +++ b/src/core/hle/kernel/server_port.h | |||
| @@ -7,8 +7,9 @@ | |||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <string> | 8 | #include <string> |
| 9 | #include <tuple> | 9 | #include <tuple> |
| 10 | #include <vector> | ||
| 10 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| 11 | #include "core/hle/kernel/kernel.h" | 12 | #include "core/hle/kernel/object.h" |
| 12 | #include "core/hle/kernel/wait_object.h" | 13 | #include "core/hle/kernel/wait_object.h" |
| 13 | 14 | ||
| 14 | namespace Kernel { | 15 | namespace Kernel { |
diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 29b163528..93560152f 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp | |||
| @@ -5,6 +5,8 @@ | |||
| 5 | #include <tuple> | 5 | #include <tuple> |
| 6 | #include <utility> | 6 | #include <utility> |
| 7 | 7 | ||
| 8 | #include "common/assert.h" | ||
| 9 | #include "common/logging/log.h" | ||
| 8 | #include "core/core.h" | 10 | #include "core/core.h" |
| 9 | #include "core/hle/ipc_helpers.h" | 11 | #include "core/hle/ipc_helpers.h" |
| 10 | #include "core/hle/kernel/client_port.h" | 12 | #include "core/hle/kernel/client_port.h" |
| @@ -25,7 +27,7 @@ ServerSession::~ServerSession() { | |||
| 25 | 27 | ||
| 26 | // Decrease the port's connection count. | 28 | // Decrease the port's connection count. |
| 27 | if (parent->port) | 29 | if (parent->port) |
| 28 | parent->port->active_sessions--; | 30 | parent->port->ConnectionClosed(); |
| 29 | 31 | ||
| 30 | // TODO(Subv): Wake up all the ClientSession's waiting threads and set | 32 | // TODO(Subv): Wake up all the ClientSession's waiting threads and set |
| 31 | // the SendSyncRequest result to 0xC920181A. | 33 | // the SendSyncRequest result to 0xC920181A. |
diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h index 2da807042..2bce54fee 100644 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/server_session.h | |||
| @@ -6,12 +6,12 @@ | |||
| 6 | 6 | ||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <string> | 8 | #include <string> |
| 9 | #include "common/assert.h" | 9 | #include <vector> |
| 10 | |||
| 10 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| 11 | #include "core/hle/kernel/kernel.h" | 12 | #include "core/hle/kernel/object.h" |
| 12 | #include "core/hle/kernel/wait_object.h" | 13 | #include "core/hle/kernel/wait_object.h" |
| 13 | #include "core/hle/result.h" | 14 | #include "core/hle/result.h" |
| 14 | #include "core/memory.h" | ||
| 15 | 15 | ||
| 16 | namespace Kernel { | 16 | namespace Kernel { |
| 17 | 17 | ||
diff --git a/src/core/hle/kernel/session.h b/src/core/hle/kernel/session.h index e69b034a7..7a551f5e4 100644 --- a/src/core/hle/kernel/session.h +++ b/src/core/hle/kernel/session.h | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include "core/hle/kernel/kernel.h" | 7 | #include "core/hle/kernel/object.h" |
| 8 | 8 | ||
| 9 | namespace Kernel { | 9 | namespace Kernel { |
| 10 | 10 | ||
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index 4bf11c7e2..21ddc2f7d 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp | |||
| @@ -3,10 +3,11 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <utility> | 5 | #include <utility> |
| 6 | |||
| 7 | #include "common/assert.h" | ||
| 6 | #include "common/logging/log.h" | 8 | #include "common/logging/log.h" |
| 7 | #include "core/core.h" | 9 | #include "core/core.h" |
| 8 | #include "core/hle/kernel/errors.h" | 10 | #include "core/hle/kernel/errors.h" |
| 9 | #include "core/hle/kernel/memory.h" | ||
| 10 | #include "core/hle/kernel/shared_memory.h" | 11 | #include "core/hle/kernel/shared_memory.h" |
| 11 | #include "core/memory.h" | 12 | #include "core/memory.h" |
| 12 | 13 | ||
| @@ -28,35 +29,17 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u | |||
| 28 | shared_memory->other_permissions = other_permissions; | 29 | shared_memory->other_permissions = other_permissions; |
| 29 | 30 | ||
| 30 | if (address == 0) { | 31 | if (address == 0) { |
| 31 | // We need to allocate a block from the Linear Heap ourselves. | 32 | shared_memory->backing_block = std::make_shared<std::vector<u8>>(size); |
| 32 | // We'll manually allocate some memory from the linear heap in the specified region. | 33 | shared_memory->backing_block_offset = 0; |
| 33 | MemoryRegionInfo* memory_region = GetMemoryRegion(region); | ||
| 34 | auto& linheap_memory = memory_region->linear_heap_memory; | ||
| 35 | |||
| 36 | ASSERT_MSG(linheap_memory->size() + size <= memory_region->size, | ||
| 37 | "Not enough space in region to allocate shared memory!"); | ||
| 38 | |||
| 39 | shared_memory->backing_block = linheap_memory; | ||
| 40 | shared_memory->backing_block_offset = linheap_memory->size(); | ||
| 41 | // Allocate some memory from the end of the linear heap for this region. | ||
| 42 | linheap_memory->insert(linheap_memory->end(), size, 0); | ||
| 43 | memory_region->used += size; | ||
| 44 | |||
| 45 | shared_memory->linear_heap_phys_address = | ||
| 46 | Memory::FCRAM_PADDR + memory_region->base + | ||
| 47 | static_cast<PAddr>(shared_memory->backing_block_offset); | ||
| 48 | |||
| 49 | // Increase the amount of used linear heap memory for the owner process. | ||
| 50 | if (shared_memory->owner_process != nullptr) { | ||
| 51 | shared_memory->owner_process->linear_heap_used += size; | ||
| 52 | } | ||
| 53 | 34 | ||
| 54 | // Refresh the address mappings for the current process. | 35 | // Refresh the address mappings for the current process. |
| 55 | if (Core::CurrentProcess() != nullptr) { | 36 | if (Core::CurrentProcess() != nullptr) { |
| 56 | Core::CurrentProcess()->vm_manager.RefreshMemoryBlockMappings(linheap_memory.get()); | 37 | Core::CurrentProcess()->vm_manager.RefreshMemoryBlockMappings( |
| 38 | shared_memory->backing_block.get()); | ||
| 57 | } | 39 | } |
| 58 | } else { | 40 | } else { |
| 59 | auto& vm_manager = shared_memory->owner_process->vm_manager; | 41 | auto& vm_manager = shared_memory->owner_process->vm_manager; |
| 42 | |||
| 60 | // The memory is already available and mapped in the owner process. | 43 | // The memory is already available and mapped in the owner process. |
| 61 | auto vma = vm_manager.FindVMA(address); | 44 | auto vma = vm_manager.FindVMA(address); |
| 62 | ASSERT_MSG(vma != vm_manager.vma_map.end(), "Invalid memory address"); | 45 | ASSERT_MSG(vma != vm_manager.vma_map.end(), "Invalid memory address"); |
| @@ -72,6 +55,7 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u | |||
| 72 | } | 55 | } |
| 73 | 56 | ||
| 74 | shared_memory->base_address = address; | 57 | shared_memory->base_address = address; |
| 58 | |||
| 75 | return shared_memory; | 59 | return shared_memory; |
| 76 | } | 60 | } |
| 77 | 61 | ||
| @@ -122,11 +106,6 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi | |||
| 122 | 106 | ||
| 123 | VAddr target_address = address; | 107 | VAddr target_address = address; |
| 124 | 108 | ||
| 125 | if (base_address == 0 && target_address == 0) { | ||
| 126 | // Calculate the address at which to map the memory block. | ||
| 127 | target_address = Memory::PhysicalToVirtualAddress(linear_heap_phys_address).value(); | ||
| 128 | } | ||
| 129 | |||
| 130 | // Map the memory block into the target process | 109 | // Map the memory block into the target process |
| 131 | auto result = target_process->vm_manager.MapMemoryBlock( | 110 | auto result = target_process->vm_manager.MapMemoryBlock( |
| 132 | target_address, backing_block, backing_block_offset, size, MemoryState::Shared); | 111 | target_address, backing_block, backing_block_offset, size, MemoryState::Shared); |
diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index 86f818e90..c50fee615 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h | |||
| @@ -4,9 +4,12 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <memory> | ||
| 7 | #include <string> | 8 | #include <string> |
| 9 | #include <vector> | ||
| 10 | |||
| 8 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| 9 | #include "core/hle/kernel/kernel.h" | 12 | #include "core/hle/kernel/object.h" |
| 10 | #include "core/hle/kernel/process.h" | 13 | #include "core/hle/kernel/process.h" |
| 11 | #include "core/hle/result.h" | 14 | #include "core/hle/result.h" |
| 12 | 15 | ||
| @@ -108,9 +111,6 @@ public: | |||
| 108 | SharedPtr<Process> owner_process; | 111 | SharedPtr<Process> owner_process; |
| 109 | /// Address of shared memory block in the owner process if specified. | 112 | /// Address of shared memory block in the owner process if specified. |
| 110 | VAddr base_address; | 113 | VAddr base_address; |
| 111 | /// Physical address of the shared memory block in the linear heap if no address was specified | ||
| 112 | /// during creation. | ||
| 113 | PAddr linear_heap_phys_address; | ||
| 114 | /// Backing memory for this shared memory block. | 114 | /// Backing memory for this shared memory block. |
| 115 | std::shared_ptr<std::vector<u8>> backing_block; | 115 | std::shared_ptr<std::vector<u8>> backing_block; |
| 116 | /// Offset into the backing block for this shared memory. | 116 | /// Offset into the backing block for this shared memory. |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 0b439401a..5db2db687 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -5,7 +5,10 @@ | |||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | #include <cinttypes> | 6 | #include <cinttypes> |
| 7 | #include <iterator> | 7 | #include <iterator> |
| 8 | #include <mutex> | ||
| 9 | #include <vector> | ||
| 8 | 10 | ||
| 11 | #include "common/assert.h" | ||
| 9 | #include "common/logging/log.h" | 12 | #include "common/logging/log.h" |
| 10 | #include "common/microprofile.h" | 13 | #include "common/microprofile.h" |
| 11 | #include "common/string_util.h" | 14 | #include "common/string_util.h" |
| @@ -17,7 +20,6 @@ | |||
| 17 | #include "core/hle/kernel/event.h" | 20 | #include "core/hle/kernel/event.h" |
| 18 | #include "core/hle/kernel/handle_table.h" | 21 | #include "core/hle/kernel/handle_table.h" |
| 19 | #include "core/hle/kernel/mutex.h" | 22 | #include "core/hle/kernel/mutex.h" |
| 20 | #include "core/hle/kernel/object_address_table.h" | ||
| 21 | #include "core/hle/kernel/process.h" | 23 | #include "core/hle/kernel/process.h" |
| 22 | #include "core/hle/kernel/resource_limit.h" | 24 | #include "core/hle/kernel/resource_limit.h" |
| 23 | #include "core/hle/kernel/shared_memory.h" | 25 | #include "core/hle/kernel/shared_memory.h" |
| @@ -265,7 +267,7 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) | |||
| 265 | LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id, | 267 | LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id, |
| 266 | info_sub_id, handle); | 268 | info_sub_id, handle); |
| 267 | 269 | ||
| 268 | auto& vm_manager = Core::CurrentProcess()->vm_manager; | 270 | const auto& vm_manager = Core::CurrentProcess()->vm_manager; |
| 269 | 271 | ||
| 270 | switch (static_cast<GetInfoType>(info_id)) { | 272 | switch (static_cast<GetInfoType>(info_id)) { |
| 271 | case GetInfoType::AllowedCpuIdBitmask: | 273 | case GetInfoType::AllowedCpuIdBitmask: |
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 94735c86e..b9022feae 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -4,8 +4,11 @@ | |||
| 4 | 4 | ||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | #include <cinttypes> | 6 | #include <cinttypes> |
| 7 | #include <list> | ||
| 8 | #include <vector> | 7 | #include <vector> |
| 8 | |||
| 9 | #include <boost/optional.hpp> | ||
| 10 | #include <boost/range/algorithm_ext/erase.hpp> | ||
| 11 | |||
| 9 | #include "common/assert.h" | 12 | #include "common/assert.h" |
| 10 | #include "common/common_types.h" | 13 | #include "common/common_types.h" |
| 11 | #include "common/logging/log.h" | 14 | #include "common/logging/log.h" |
| @@ -17,9 +20,7 @@ | |||
| 17 | #include "core/core_timing_util.h" | 20 | #include "core/core_timing_util.h" |
| 18 | #include "core/hle/kernel/errors.h" | 21 | #include "core/hle/kernel/errors.h" |
| 19 | #include "core/hle/kernel/handle_table.h" | 22 | #include "core/hle/kernel/handle_table.h" |
| 20 | #include "core/hle/kernel/kernel.h" | 23 | #include "core/hle/kernel/object.h" |
| 21 | #include "core/hle/kernel/memory.h" | ||
| 22 | #include "core/hle/kernel/mutex.h" | ||
| 23 | #include "core/hle/kernel/process.h" | 24 | #include "core/hle/kernel/process.h" |
| 24 | #include "core/hle/kernel/thread.h" | 25 | #include "core/hle/kernel/thread.h" |
| 25 | #include "core/hle/result.h" | 26 | #include "core/hle/result.h" |
| @@ -79,8 +80,8 @@ void Thread::Stop() { | |||
| 79 | wait_objects.clear(); | 80 | wait_objects.clear(); |
| 80 | 81 | ||
| 81 | // Mark the TLS slot in the thread's page as free. | 82 | // Mark the TLS slot in the thread's page as free. |
| 82 | u64 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE; | 83 | const u64 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE; |
| 83 | u64 tls_slot = | 84 | const u64 tls_slot = |
| 84 | ((tls_address - Memory::TLS_AREA_VADDR) % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE; | 85 | ((tls_address - Memory::TLS_AREA_VADDR) % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE; |
| 85 | Core::CurrentProcess()->tls_slots[tls_page].reset(tls_slot); | 86 | Core::CurrentProcess()->tls_slots[tls_page].reset(tls_slot); |
| 86 | } | 87 | } |
| @@ -250,13 +251,14 @@ void Thread::ResumeFromWait() { | |||
| 250 | * slot: The index of the first free slot in the indicated page. | 251 | * slot: The index of the first free slot in the indicated page. |
| 251 | * alloc_needed: Whether there's a need to allocate a new TLS page (All pages are full). | 252 | * alloc_needed: Whether there's a need to allocate a new TLS page (All pages are full). |
| 252 | */ | 253 | */ |
| 253 | std::tuple<u32, u32, bool> GetFreeThreadLocalSlot(std::vector<std::bitset<8>>& tls_slots) { | 254 | static std::tuple<std::size_t, std::size_t, bool> GetFreeThreadLocalSlot( |
| 255 | const std::vector<std::bitset<8>>& tls_slots) { | ||
| 254 | // Iterate over all the allocated pages, and try to find one where not all slots are used. | 256 | // Iterate over all the allocated pages, and try to find one where not all slots are used. |
| 255 | for (unsigned page = 0; page < tls_slots.size(); ++page) { | 257 | for (std::size_t page = 0; page < tls_slots.size(); ++page) { |
| 256 | const auto& page_tls_slots = tls_slots[page]; | 258 | const auto& page_tls_slots = tls_slots[page]; |
| 257 | if (!page_tls_slots.all()) { | 259 | if (!page_tls_slots.all()) { |
| 258 | // We found a page with at least one free slot, find which slot it is | 260 | // We found a page with at least one free slot, find which slot it is |
| 259 | for (unsigned slot = 0; slot < page_tls_slots.size(); ++slot) { | 261 | for (std::size_t slot = 0; slot < page_tls_slots.size(); ++slot) { |
| 260 | if (!page_tls_slots.test(slot)) { | 262 | if (!page_tls_slots.test(slot)) { |
| 261 | return std::make_tuple(page, slot, false); | 263 | return std::make_tuple(page, slot, false); |
| 262 | } | 264 | } |
| @@ -331,42 +333,22 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, | |||
| 331 | 333 | ||
| 332 | // Find the next available TLS index, and mark it as used | 334 | // Find the next available TLS index, and mark it as used |
| 333 | auto& tls_slots = owner_process->tls_slots; | 335 | auto& tls_slots = owner_process->tls_slots; |
| 334 | bool needs_allocation = true; | ||
| 335 | u32 available_page; // Which allocated page has free space | ||
| 336 | u32 available_slot; // Which slot within the page is free | ||
| 337 | |||
| 338 | std::tie(available_page, available_slot, needs_allocation) = GetFreeThreadLocalSlot(tls_slots); | ||
| 339 | 336 | ||
| 337 | auto [available_page, available_slot, needs_allocation] = GetFreeThreadLocalSlot(tls_slots); | ||
| 340 | if (needs_allocation) { | 338 | if (needs_allocation) { |
| 341 | // There are no already-allocated pages with free slots, lets allocate a new one. | ||
| 342 | // TLS pages are allocated from the BASE region in the linear heap. | ||
| 343 | MemoryRegionInfo* memory_region = GetMemoryRegion(MemoryRegion::BASE); | ||
| 344 | auto& linheap_memory = memory_region->linear_heap_memory; | ||
| 345 | |||
| 346 | if (linheap_memory->size() + Memory::PAGE_SIZE > memory_region->size) { | ||
| 347 | LOG_ERROR(Kernel_SVC, | ||
| 348 | "Not enough space in region to allocate a new TLS page for thread"); | ||
| 349 | return ERR_OUT_OF_MEMORY; | ||
| 350 | } | ||
| 351 | |||
| 352 | size_t offset = linheap_memory->size(); | ||
| 353 | |||
| 354 | // Allocate some memory from the end of the linear heap for this region. | ||
| 355 | linheap_memory->insert(linheap_memory->end(), Memory::PAGE_SIZE, 0); | ||
| 356 | memory_region->used += Memory::PAGE_SIZE; | ||
| 357 | owner_process->linear_heap_used += Memory::PAGE_SIZE; | ||
| 358 | |||
| 359 | tls_slots.emplace_back(0); // The page is completely available at the start | 339 | tls_slots.emplace_back(0); // The page is completely available at the start |
| 360 | available_page = static_cast<u32>(tls_slots.size() - 1); | 340 | available_page = tls_slots.size() - 1; |
| 361 | available_slot = 0; // Use the first slot in the new page | 341 | available_slot = 0; // Use the first slot in the new page |
| 362 | 342 | ||
| 343 | // Allocate some memory from the end of the linear heap for this region. | ||
| 344 | const size_t offset = thread->tls_memory->size(); | ||
| 345 | thread->tls_memory->insert(thread->tls_memory->end(), Memory::PAGE_SIZE, 0); | ||
| 346 | |||
| 363 | auto& vm_manager = owner_process->vm_manager; | 347 | auto& vm_manager = owner_process->vm_manager; |
| 364 | vm_manager.RefreshMemoryBlockMappings(linheap_memory.get()); | 348 | vm_manager.RefreshMemoryBlockMappings(thread->tls_memory.get()); |
| 365 | 349 | ||
| 366 | // Map the page to the current process' address space. | ||
| 367 | // TODO(Subv): Find the correct MemoryState for this region. | ||
| 368 | vm_manager.MapMemoryBlock(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE, | 350 | vm_manager.MapMemoryBlock(Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE, |
| 369 | linheap_memory, offset, Memory::PAGE_SIZE, | 351 | thread->tls_memory, 0, Memory::PAGE_SIZE, |
| 370 | MemoryState::ThreadLocal); | 352 | MemoryState::ThreadLocal); |
| 371 | } | 353 | } |
| 372 | 354 | ||
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 6218960d2..adc804248 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h | |||
| @@ -4,15 +4,14 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <functional> | ||
| 7 | #include <memory> | 8 | #include <memory> |
| 8 | #include <string> | 9 | #include <string> |
| 9 | #include <unordered_map> | ||
| 10 | #include <vector> | 10 | #include <vector> |
| 11 | #include <boost/container/flat_map.hpp> | 11 | |
| 12 | #include <boost/container/flat_set.hpp> | ||
| 13 | #include "common/common_types.h" | 12 | #include "common/common_types.h" |
| 14 | #include "core/arm/arm_interface.h" | 13 | #include "core/arm/arm_interface.h" |
| 15 | #include "core/hle/kernel/kernel.h" | 14 | #include "core/hle/kernel/object.h" |
| 16 | #include "core/hle/kernel/wait_object.h" | 15 | #include "core/hle/kernel/wait_object.h" |
| 17 | #include "core/hle/result.h" | 16 | #include "core/hle/result.h" |
| 18 | 17 | ||
| @@ -266,6 +265,8 @@ public: | |||
| 266 | private: | 265 | private: |
| 267 | Thread(); | 266 | Thread(); |
| 268 | ~Thread() override; | 267 | ~Thread() override; |
| 268 | |||
| 269 | std::shared_ptr<std::vector<u8>> tls_memory = std::make_shared<std::vector<u8>>(); | ||
| 269 | }; | 270 | }; |
| 270 | 271 | ||
| 271 | /** | 272 | /** |
| @@ -289,12 +290,6 @@ Thread* GetCurrentThread(); | |||
| 289 | void WaitCurrentThread_Sleep(); | 290 | void WaitCurrentThread_Sleep(); |
| 290 | 291 | ||
| 291 | /** | 292 | /** |
| 292 | * Waits the current thread from an ArbitrateAddress call | ||
| 293 | * @param wait_address Arbitration address used to resume from wait | ||
| 294 | */ | ||
| 295 | void WaitCurrentThread_ArbitrateAddress(VAddr wait_address); | ||
| 296 | |||
| 297 | /** | ||
| 298 | * Stops the current thread and removes it from the thread_list | 293 | * Stops the current thread and removes it from the thread_list |
| 299 | */ | 294 | */ |
| 300 | void ExitCurrentThread(); | 295 | void ExitCurrentThread(); |
diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index 904a3d0a5..282360745 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | #include "core/core_timing.h" | 8 | #include "core/core_timing.h" |
| 9 | #include "core/core_timing_util.h" | 9 | #include "core/core_timing_util.h" |
| 10 | #include "core/hle/kernel/handle_table.h" | 10 | #include "core/hle/kernel/handle_table.h" |
| 11 | #include "core/hle/kernel/kernel.h" | 11 | #include "core/hle/kernel/object.h" |
| 12 | #include "core/hle/kernel/thread.h" | 12 | #include "core/hle/kernel/thread.h" |
| 13 | #include "core/hle/kernel/timer.h" | 13 | #include "core/hle/kernel/timer.h" |
| 14 | 14 | ||
diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h index c63f0ed90..4dddc67e0 100644 --- a/src/core/hle/kernel/timer.h +++ b/src/core/hle/kernel/timer.h | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include "common/common_types.h" | 7 | #include "common/common_types.h" |
| 8 | #include "core/hle/kernel/kernel.h" | 8 | #include "core/hle/kernel/object.h" |
| 9 | #include "core/hle/kernel/wait_object.h" | 9 | #include "core/hle/kernel/wait_object.h" |
| 10 | 10 | ||
| 11 | namespace Kernel { | 11 | namespace Kernel { |
diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp index 9d26fd781..479cacb62 100644 --- a/src/core/hle/kernel/vm_manager.cpp +++ b/src/core/hle/kernel/vm_manager.cpp | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <algorithm> | ||
| 5 | #include <iterator> | 6 | #include <iterator> |
| 6 | #include <utility> | 7 | #include <utility> |
| 7 | #include "common/assert.h" | 8 | #include "common/assert.h" |
| @@ -175,9 +176,9 @@ VMManager::VMAIter VMManager::Unmap(VMAIter vma_handle) { | |||
| 175 | 176 | ||
| 176 | ResultCode VMManager::UnmapRange(VAddr target, u64 size) { | 177 | ResultCode VMManager::UnmapRange(VAddr target, u64 size) { |
| 177 | CASCADE_RESULT(VMAIter vma, CarveVMARange(target, size)); | 178 | CASCADE_RESULT(VMAIter vma, CarveVMARange(target, size)); |
| 178 | VAddr target_end = target + size; | 179 | const VAddr target_end = target + size; |
| 179 | 180 | ||
| 180 | VMAIter end = vma_map.end(); | 181 | const VMAIter end = vma_map.end(); |
| 181 | // The comparison against the end of the range must be done using addresses since VMAs can be | 182 | // The comparison against the end of the range must be done using addresses since VMAs can be |
| 182 | // merged during this process, causing invalidation of the iterators. | 183 | // merged during this process, causing invalidation of the iterators. |
| 183 | while (vma != end && vma->second.base < target_end) { | 184 | while (vma != end && vma->second.base < target_end) { |
| @@ -207,9 +208,9 @@ VMManager::VMAHandle VMManager::Reprotect(VMAHandle vma_handle, VMAPermission ne | |||
| 207 | 208 | ||
| 208 | ResultCode VMManager::ReprotectRange(VAddr target, u64 size, VMAPermission new_perms) { | 209 | ResultCode VMManager::ReprotectRange(VAddr target, u64 size, VMAPermission new_perms) { |
| 209 | CASCADE_RESULT(VMAIter vma, CarveVMARange(target, size)); | 210 | CASCADE_RESULT(VMAIter vma, CarveVMARange(target, size)); |
| 210 | VAddr target_end = target + size; | 211 | const VAddr target_end = target + size; |
| 211 | 212 | ||
| 212 | VMAIter end = vma_map.end(); | 213 | const VMAIter end = vma_map.end(); |
| 213 | // The comparison against the end of the range must be done using addresses since VMAs can be | 214 | // The comparison against the end of the range must be done using addresses since VMAs can be |
| 214 | // merged during this process, causing invalidation of the iterators. | 215 | // merged during this process, causing invalidation of the iterators. |
| 215 | while (vma != end && vma->second.base < target_end) { | 216 | while (vma != end && vma->second.base < target_end) { |
| @@ -258,14 +259,14 @@ ResultVal<VMManager::VMAIter> VMManager::CarveVMA(VAddr base, u64 size) { | |||
| 258 | return ERR_INVALID_ADDRESS; | 259 | return ERR_INVALID_ADDRESS; |
| 259 | } | 260 | } |
| 260 | 261 | ||
| 261 | VirtualMemoryArea& vma = vma_handle->second; | 262 | const VirtualMemoryArea& vma = vma_handle->second; |
| 262 | if (vma.type != VMAType::Free) { | 263 | if (vma.type != VMAType::Free) { |
| 263 | // Region is already allocated | 264 | // Region is already allocated |
| 264 | return ERR_INVALID_ADDRESS_STATE; | 265 | return ERR_INVALID_ADDRESS_STATE; |
| 265 | } | 266 | } |
| 266 | 267 | ||
| 267 | u64 start_in_vma = base - vma.base; | 268 | const VAddr start_in_vma = base - vma.base; |
| 268 | u64 end_in_vma = start_in_vma + size; | 269 | const VAddr end_in_vma = start_in_vma + size; |
| 269 | 270 | ||
| 270 | if (end_in_vma > vma.size) { | 271 | if (end_in_vma > vma.size) { |
| 271 | // Requested allocation doesn't fit inside VMA | 272 | // Requested allocation doesn't fit inside VMA |
| @@ -288,17 +289,16 @@ ResultVal<VMManager::VMAIter> VMManager::CarveVMARange(VAddr target, u64 size) { | |||
| 288 | ASSERT_MSG((size & Memory::PAGE_MASK) == 0, "non-page aligned size: 0x{:016X}", size); | 289 | ASSERT_MSG((size & Memory::PAGE_MASK) == 0, "non-page aligned size: 0x{:016X}", size); |
| 289 | ASSERT_MSG((target & Memory::PAGE_MASK) == 0, "non-page aligned base: 0x{:016X}", target); | 290 | ASSERT_MSG((target & Memory::PAGE_MASK) == 0, "non-page aligned base: 0x{:016X}", target); |
| 290 | 291 | ||
| 291 | VAddr target_end = target + size; | 292 | const VAddr target_end = target + size; |
| 292 | ASSERT(target_end >= target); | 293 | ASSERT(target_end >= target); |
| 293 | ASSERT(target_end <= MAX_ADDRESS); | 294 | ASSERT(target_end <= MAX_ADDRESS); |
| 294 | ASSERT(size > 0); | 295 | ASSERT(size > 0); |
| 295 | 296 | ||
| 296 | VMAIter begin_vma = StripIterConstness(FindVMA(target)); | 297 | VMAIter begin_vma = StripIterConstness(FindVMA(target)); |
| 297 | VMAIter i_end = vma_map.lower_bound(target_end); | 298 | const VMAIter i_end = vma_map.lower_bound(target_end); |
| 298 | for (auto i = begin_vma; i != i_end; ++i) { | 299 | if (std::any_of(begin_vma, i_end, |
| 299 | if (i->second.type == VMAType::Free) { | 300 | [](const auto& entry) { return entry.second.type == VMAType::Free; })) { |
| 300 | return ERR_INVALID_ADDRESS_STATE; | 301 | return ERR_INVALID_ADDRESS_STATE; |
| 301 | } | ||
| 302 | } | 302 | } |
| 303 | 303 | ||
| 304 | if (target != begin_vma->second.base) { | 304 | if (target != begin_vma->second.base) { |
| @@ -346,7 +346,7 @@ VMManager::VMAIter VMManager::SplitVMA(VMAIter vma_handle, u64 offset_in_vma) { | |||
| 346 | } | 346 | } |
| 347 | 347 | ||
| 348 | VMManager::VMAIter VMManager::MergeAdjacent(VMAIter iter) { | 348 | VMManager::VMAIter VMManager::MergeAdjacent(VMAIter iter) { |
| 349 | VMAIter next_vma = std::next(iter); | 349 | const VMAIter next_vma = std::next(iter); |
| 350 | if (next_vma != vma_map.end() && iter->second.CanBeMergedWith(next_vma->second)) { | 350 | if (next_vma != vma_map.end() && iter->second.CanBeMergedWith(next_vma->second)) { |
| 351 | iter->second.size += next_vma->second.size; | 351 | iter->second.size += next_vma->second.size; |
| 352 | vma_map.erase(next_vma); | 352 | vma_map.erase(next_vma); |
| @@ -382,22 +382,22 @@ void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) { | |||
| 382 | } | 382 | } |
| 383 | } | 383 | } |
| 384 | 384 | ||
| 385 | u64 VMManager::GetTotalMemoryUsage() { | 385 | u64 VMManager::GetTotalMemoryUsage() const { |
| 386 | LOG_WARNING(Kernel, "(STUBBED) called"); | 386 | LOG_WARNING(Kernel, "(STUBBED) called"); |
| 387 | return 0xF8000000; | 387 | return 0xF8000000; |
| 388 | } | 388 | } |
| 389 | 389 | ||
| 390 | u64 VMManager::GetTotalHeapUsage() { | 390 | u64 VMManager::GetTotalHeapUsage() const { |
| 391 | LOG_WARNING(Kernel, "(STUBBED) called"); | 391 | LOG_WARNING(Kernel, "(STUBBED) called"); |
| 392 | return 0x0; | 392 | return 0x0; |
| 393 | } | 393 | } |
| 394 | 394 | ||
| 395 | VAddr VMManager::GetAddressSpaceBaseAddr() { | 395 | VAddr VMManager::GetAddressSpaceBaseAddr() const { |
| 396 | LOG_WARNING(Kernel, "(STUBBED) called"); | 396 | LOG_WARNING(Kernel, "(STUBBED) called"); |
| 397 | return 0x8000000; | 397 | return 0x8000000; |
| 398 | } | 398 | } |
| 399 | 399 | ||
| 400 | u64 VMManager::GetAddressSpaceSize() { | 400 | u64 VMManager::GetAddressSpaceSize() const { |
| 401 | LOG_WARNING(Kernel, "(STUBBED) called"); | 401 | LOG_WARNING(Kernel, "(STUBBED) called"); |
| 402 | return MAX_ADDRESS; | 402 | return MAX_ADDRESS; |
| 403 | } | 403 | } |
diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index 38e4ebcd3..98bd04bea 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h | |||
| @@ -190,16 +190,16 @@ public: | |||
| 190 | void LogLayout() const; | 190 | void LogLayout() const; |
| 191 | 191 | ||
| 192 | /// Gets the total memory usage, used by svcGetInfo | 192 | /// Gets the total memory usage, used by svcGetInfo |
| 193 | u64 GetTotalMemoryUsage(); | 193 | u64 GetTotalMemoryUsage() const; |
| 194 | 194 | ||
| 195 | /// Gets the total heap usage, used by svcGetInfo | 195 | /// Gets the total heap usage, used by svcGetInfo |
| 196 | u64 GetTotalHeapUsage(); | 196 | u64 GetTotalHeapUsage() const; |
| 197 | 197 | ||
| 198 | /// Gets the total address space base address, used by svcGetInfo | 198 | /// Gets the total address space base address, used by svcGetInfo |
| 199 | VAddr GetAddressSpaceBaseAddr(); | 199 | VAddr GetAddressSpaceBaseAddr() const; |
| 200 | 200 | ||
| 201 | /// Gets the total address space address size, used by svcGetInfo | 201 | /// Gets the total address space address size, used by svcGetInfo |
| 202 | u64 GetAddressSpaceSize(); | 202 | u64 GetAddressSpaceSize() const; |
| 203 | 203 | ||
| 204 | /// Each VMManager has its own page table, which is set as the main one when the owning process | 204 | /// Each VMManager has its own page table, which is set as the main one when the owning process |
| 205 | /// is scheduled. | 205 | /// is scheduled. |
diff --git a/src/core/hle/kernel/wait_object.cpp b/src/core/hle/kernel/wait_object.cpp index 23af346d0..7681cdee7 100644 --- a/src/core/hle/kernel/wait_object.cpp +++ b/src/core/hle/kernel/wait_object.cpp | |||
| @@ -5,11 +5,8 @@ | |||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | #include "common/assert.h" | 6 | #include "common/assert.h" |
| 7 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 8 | #include "core/hle/kernel/errors.h" | 8 | #include "core/hle/kernel/object.h" |
| 9 | #include "core/hle/kernel/kernel.h" | ||
| 10 | #include "core/hle/kernel/memory.h" | ||
| 11 | #include "core/hle/kernel/process.h" | 9 | #include "core/hle/kernel/process.h" |
| 12 | #include "core/hle/kernel/resource_limit.h" | ||
| 13 | #include "core/hle/kernel/thread.h" | 10 | #include "core/hle/kernel/thread.h" |
| 14 | #include "core/hle/kernel/timer.h" | 11 | #include "core/hle/kernel/timer.h" |
| 15 | 12 | ||
diff --git a/src/core/hle/kernel/wait_object.h b/src/core/hle/kernel/wait_object.h index 78bfd8c6c..b5fbc647b 100644 --- a/src/core/hle/kernel/wait_object.h +++ b/src/core/hle/kernel/wait_object.h | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | #include <vector> | 7 | #include <vector> |
| 8 | #include <boost/smart_ptr/intrusive_ptr.hpp> | 8 | #include <boost/smart_ptr/intrusive_ptr.hpp> |
| 9 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 10 | #include "core/hle/kernel/kernel.h" | 10 | #include "core/hle/kernel/object.h" |
| 11 | 11 | ||
| 12 | namespace Kernel { | 12 | namespace Kernel { |
| 13 | 13 | ||
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 0b158e015..6d15b46ed 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #include "core/hle/service/acc/acc_su.h" | 10 | #include "core/hle/service/acc/acc_su.h" |
| 11 | #include "core/hle/service/acc/acc_u0.h" | 11 | #include "core/hle/service/acc/acc_u0.h" |
| 12 | #include "core/hle/service/acc/acc_u1.h" | 12 | #include "core/hle/service/acc/acc_u1.h" |
| 13 | #include "core/settings.h" | ||
| 13 | 14 | ||
| 14 | namespace Service::Account { | 15 | namespace Service::Account { |
| 15 | 16 | ||
| @@ -31,13 +32,14 @@ struct ProfileBase { | |||
| 31 | }; | 32 | }; |
| 32 | static_assert(sizeof(ProfileBase) == 0x38, "ProfileBase structure has incorrect size"); | 33 | static_assert(sizeof(ProfileBase) == 0x38, "ProfileBase structure has incorrect size"); |
| 33 | 34 | ||
| 35 | // TODO(ogniK): Generate a real user id based on username, md5(username) maybe? | ||
| 34 | static constexpr u128 DEFAULT_USER_ID{1ull, 0ull}; | 36 | static constexpr u128 DEFAULT_USER_ID{1ull, 0ull}; |
| 35 | 37 | ||
| 36 | class IProfile final : public ServiceFramework<IProfile> { | 38 | class IProfile final : public ServiceFramework<IProfile> { |
| 37 | public: | 39 | public: |
| 38 | explicit IProfile(u128 user_id) : ServiceFramework("IProfile"), user_id(user_id) { | 40 | explicit IProfile(u128 user_id) : ServiceFramework("IProfile"), user_id(user_id) { |
| 39 | static const FunctionInfo functions[] = { | 41 | static const FunctionInfo functions[] = { |
| 40 | {0, nullptr, "Get"}, | 42 | {0, &IProfile::Get, "Get"}, |
| 41 | {1, &IProfile::GetBase, "GetBase"}, | 43 | {1, &IProfile::GetBase, "GetBase"}, |
| 42 | {10, nullptr, "GetImageSize"}, | 44 | {10, nullptr, "GetImageSize"}, |
| 43 | {11, nullptr, "LoadImage"}, | 45 | {11, nullptr, "LoadImage"}, |
| @@ -46,14 +48,36 @@ public: | |||
| 46 | } | 48 | } |
| 47 | 49 | ||
| 48 | private: | 50 | private: |
| 51 | void Get(Kernel::HLERequestContext& ctx) { | ||
| 52 | LOG_WARNING(Service_ACC, "(STUBBED) called"); | ||
| 53 | ProfileBase profile_base{}; | ||
| 54 | profile_base.user_id = user_id; | ||
| 55 | if (Settings::values.username.size() > profile_base.username.size()) { | ||
| 56 | std::copy_n(Settings::values.username.begin(), profile_base.username.size(), | ||
| 57 | profile_base.username.begin()); | ||
| 58 | } else { | ||
| 59 | std::copy(Settings::values.username.begin(), Settings::values.username.end(), | ||
| 60 | profile_base.username.begin()); | ||
| 61 | } | ||
| 62 | |||
| 63 | IPC::ResponseBuilder rb{ctx, 16}; | ||
| 64 | rb.Push(RESULT_SUCCESS); | ||
| 65 | rb.PushRaw(profile_base); | ||
| 66 | } | ||
| 67 | |||
| 49 | void GetBase(Kernel::HLERequestContext& ctx) { | 68 | void GetBase(Kernel::HLERequestContext& ctx) { |
| 50 | LOG_WARNING(Service_ACC, "(STUBBED) called"); | 69 | LOG_WARNING(Service_ACC, "(STUBBED) called"); |
| 51 | 70 | ||
| 52 | // TODO(Subv): Retrieve this information from somewhere. | 71 | // TODO(Subv): Retrieve this information from somewhere. |
| 53 | ProfileBase profile_base{}; | 72 | ProfileBase profile_base{}; |
| 54 | profile_base.user_id = user_id; | 73 | profile_base.user_id = user_id; |
| 55 | profile_base.username = {'y', 'u', 'z', 'u'}; | 74 | if (Settings::values.username.size() > profile_base.username.size()) { |
| 56 | 75 | std::copy_n(Settings::values.username.begin(), profile_base.username.size(), | |
| 76 | profile_base.username.begin()); | ||
| 77 | } else { | ||
| 78 | std::copy(Settings::values.username.begin(), Settings::values.username.end(), | ||
| 79 | profile_base.username.begin()); | ||
| 80 | } | ||
| 57 | IPC::ResponseBuilder rb{ctx, 16}; | 81 | IPC::ResponseBuilder rb{ctx, 16}; |
| 58 | rb.Push(RESULT_SUCCESS); | 82 | rb.Push(RESULT_SUCCESS); |
| 59 | rb.PushRaw(profile_base); | 83 | rb.PushRaw(profile_base); |
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 97ef07bf9..9404d6b8c 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -11,6 +11,9 @@ | |||
| 11 | #include "core/hle/service/am/am.h" | 11 | #include "core/hle/service/am/am.h" |
| 12 | #include "core/hle/service/am/applet_ae.h" | 12 | #include "core/hle/service/am/applet_ae.h" |
| 13 | #include "core/hle/service/am/applet_oe.h" | 13 | #include "core/hle/service/am/applet_oe.h" |
| 14 | #include "core/hle/service/am/idle.h" | ||
| 15 | #include "core/hle/service/am/omm.h" | ||
| 16 | #include "core/hle/service/am/spsm.h" | ||
| 14 | #include "core/hle/service/apm/apm.h" | 17 | #include "core/hle/service/apm/apm.h" |
| 15 | #include "core/hle/service/filesystem/filesystem.h" | 18 | #include "core/hle/service/filesystem/filesystem.h" |
| 16 | #include "core/hle/service/nvflinger/nvflinger.h" | 19 | #include "core/hle/service/nvflinger/nvflinger.h" |
| @@ -649,7 +652,8 @@ void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) { | |||
| 649 | // TODO(bunnei): This should be configurable | 652 | // TODO(bunnei): This should be configurable |
| 650 | IPC::ResponseBuilder rb{ctx, 4}; | 653 | IPC::ResponseBuilder rb{ctx, 4}; |
| 651 | rb.Push(RESULT_SUCCESS); | 654 | rb.Push(RESULT_SUCCESS); |
| 652 | rb.Push(static_cast<u64>(Service::Set::LanguageCode::EN_US)); | 655 | rb.Push( |
| 656 | static_cast<u64>(Service::Set::GetLanguageCodeFromIndex(Settings::values.language_index))); | ||
| 653 | LOG_DEBUG(Service_AM, "called"); | 657 | LOG_DEBUG(Service_AM, "called"); |
| 654 | } | 658 | } |
| 655 | 659 | ||
| @@ -689,6 +693,9 @@ void InstallInterfaces(SM::ServiceManager& service_manager, | |||
| 689 | std::shared_ptr<NVFlinger::NVFlinger> nvflinger) { | 693 | std::shared_ptr<NVFlinger::NVFlinger> nvflinger) { |
| 690 | std::make_shared<AppletAE>(nvflinger)->InstallAsService(service_manager); | 694 | std::make_shared<AppletAE>(nvflinger)->InstallAsService(service_manager); |
| 691 | std::make_shared<AppletOE>(nvflinger)->InstallAsService(service_manager); | 695 | std::make_shared<AppletOE>(nvflinger)->InstallAsService(service_manager); |
| 696 | std::make_shared<IdleSys>()->InstallAsService(service_manager); | ||
| 697 | std::make_shared<OMM>()->InstallAsService(service_manager); | ||
| 698 | std::make_shared<SPSM>()->InstallAsService(service_manager); | ||
| 692 | } | 699 | } |
| 693 | 700 | ||
| 694 | IHomeMenuFunctions::IHomeMenuFunctions() : ServiceFramework("IHomeMenuFunctions") { | 701 | IHomeMenuFunctions::IHomeMenuFunctions() : ServiceFramework("IHomeMenuFunctions") { |
diff --git a/src/core/hle/service/am/idle.cpp b/src/core/hle/service/am/idle.cpp new file mode 100644 index 000000000..af46e9494 --- /dev/null +++ b/src/core/hle/service/am/idle.cpp | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/hle/service/am/idle.h" | ||
| 6 | |||
| 7 | namespace Service::AM { | ||
| 8 | |||
| 9 | IdleSys::IdleSys() : ServiceFramework{"idle:sys"} { | ||
| 10 | // clang-format off | ||
| 11 | static const FunctionInfo functions[] = { | ||
| 12 | {0, nullptr, "GetAutoPowerDownEvent"}, | ||
| 13 | {1, nullptr, "Unknown1"}, | ||
| 14 | {2, nullptr, "Unknown2"}, | ||
| 15 | {3, nullptr, "Unknown3"}, | ||
| 16 | {4, nullptr, "Unknown4"}, | ||
| 17 | {5, nullptr, "Unknown5"}, | ||
| 18 | }; | ||
| 19 | // clang-format on | ||
| 20 | |||
| 21 | RegisterHandlers(functions); | ||
| 22 | } | ||
| 23 | |||
| 24 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/idle.h b/src/core/hle/service/am/idle.h new file mode 100644 index 000000000..1eb68d2c9 --- /dev/null +++ b/src/core/hle/service/am/idle.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::AM { | ||
| 10 | |||
| 11 | class IdleSys final : public ServiceFramework<IdleSys> { | ||
| 12 | public: | ||
| 13 | explicit IdleSys(); | ||
| 14 | }; | ||
| 15 | |||
| 16 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/omm.cpp b/src/core/hle/service/am/omm.cpp new file mode 100644 index 000000000..447fe8669 --- /dev/null +++ b/src/core/hle/service/am/omm.cpp | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/hle/service/am/omm.h" | ||
| 6 | |||
| 7 | namespace Service::AM { | ||
| 8 | |||
| 9 | OMM::OMM() : ServiceFramework{"omm"} { | ||
| 10 | // clang-format off | ||
| 11 | static const FunctionInfo functions[] = { | ||
| 12 | {0, nullptr, "GetOperationMode"}, | ||
| 13 | {1, nullptr, "GetOperationModeChangeEvent"}, | ||
| 14 | {2, nullptr, "EnableAudioVisual"}, | ||
| 15 | {3, nullptr, "DisableAudioVisual"}, | ||
| 16 | {4, nullptr, "EnterSleepAndWait"}, | ||
| 17 | {5, nullptr, "GetCradleStatus"}, | ||
| 18 | {6, nullptr, "FadeInDisplay"}, | ||
| 19 | {7, nullptr, "FadeOutDisplay"}, | ||
| 20 | {8, nullptr, "Unknown1"}, | ||
| 21 | {9, nullptr, "Unknown2"}, | ||
| 22 | {10, nullptr, "Unknown3"}, | ||
| 23 | {11, nullptr, "Unknown4"}, | ||
| 24 | {12, nullptr, "Unknown5"}, | ||
| 25 | {13, nullptr, "Unknown6"}, | ||
| 26 | {14, nullptr, "Unknown7"}, | ||
| 27 | {15, nullptr, "Unknown8"}, | ||
| 28 | {16, nullptr, "Unknown9"}, | ||
| 29 | {17, nullptr, "Unknown10"}, | ||
| 30 | {18, nullptr, "Unknown11"}, | ||
| 31 | {19, nullptr, "Unknown12"}, | ||
| 32 | {20, nullptr, "Unknown13"}, | ||
| 33 | {21, nullptr, "Unknown14"}, | ||
| 34 | {22, nullptr, "Unknown15"}, | ||
| 35 | {23, nullptr, "Unknown16"}, | ||
| 36 | }; | ||
| 37 | // clang-format on | ||
| 38 | |||
| 39 | RegisterHandlers(functions); | ||
| 40 | } | ||
| 41 | |||
| 42 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/omm.h b/src/core/hle/service/am/omm.h new file mode 100644 index 000000000..49e5d331c --- /dev/null +++ b/src/core/hle/service/am/omm.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::AM { | ||
| 10 | |||
| 11 | class OMM final : public ServiceFramework<OMM> { | ||
| 12 | public: | ||
| 13 | explicit OMM(); | ||
| 14 | }; | ||
| 15 | |||
| 16 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/spsm.cpp b/src/core/hle/service/am/spsm.cpp new file mode 100644 index 000000000..a05d433d0 --- /dev/null +++ b/src/core/hle/service/am/spsm.cpp | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/hle/service/am/spsm.h" | ||
| 6 | |||
| 7 | namespace Service::AM { | ||
| 8 | |||
| 9 | SPSM::SPSM() : ServiceFramework{"spsm"} { | ||
| 10 | // clang-format off | ||
| 11 | static const FunctionInfo functions[] = { | ||
| 12 | {0, nullptr, "GetState"}, | ||
| 13 | {1, nullptr, "SleepSystemAndWaitAwake"}, | ||
| 14 | {2, nullptr, "Unknown1"}, | ||
| 15 | {3, nullptr, "Unknown2"}, | ||
| 16 | {4, nullptr, "GetNotificationMessageEventHandle"}, | ||
| 17 | {5, nullptr, "Unknown3"}, | ||
| 18 | {6, nullptr, "Unknown4"}, | ||
| 19 | {7, nullptr, "Unknown5"}, | ||
| 20 | {8, nullptr, "AnalyzePerformanceLogForLastSleepWakeSequence"}, | ||
| 21 | {9, nullptr, "ChangeHomeButtonLongPressingTime"}, | ||
| 22 | {10, nullptr, "Unknown6"}, | ||
| 23 | {11, nullptr, "Unknown7"}, | ||
| 24 | }; | ||
| 25 | // clang-format on | ||
| 26 | |||
| 27 | RegisterHandlers(functions); | ||
| 28 | } | ||
| 29 | |||
| 30 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/am/spsm.h b/src/core/hle/service/am/spsm.h new file mode 100644 index 000000000..57dde62e1 --- /dev/null +++ b/src/core/hle/service/am/spsm.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::AM { | ||
| 10 | |||
| 11 | class SPSM final : public ServiceFramework<SPSM> { | ||
| 12 | public: | ||
| 13 | explicit SPSM(); | ||
| 14 | }; | ||
| 15 | |||
| 16 | } // namespace Service::AM | ||
diff --git a/src/core/hle/service/apm/apm.cpp b/src/core/hle/service/apm/apm.cpp index 7a185c6c8..4109cb7f7 100644 --- a/src/core/hle/service/apm/apm.cpp +++ b/src/core/hle/service/apm/apm.cpp | |||
| @@ -13,6 +13,7 @@ void InstallInterfaces(SM::ServiceManager& service_manager) { | |||
| 13 | auto module_ = std::make_shared<Module>(); | 13 | auto module_ = std::make_shared<Module>(); |
| 14 | std::make_shared<APM>(module_, "apm")->InstallAsService(service_manager); | 14 | std::make_shared<APM>(module_, "apm")->InstallAsService(service_manager); |
| 15 | std::make_shared<APM>(module_, "apm:p")->InstallAsService(service_manager); | 15 | std::make_shared<APM>(module_, "apm:p")->InstallAsService(service_manager); |
| 16 | std::make_shared<APM_Sys>()->InstallAsService(service_manager); | ||
| 16 | } | 17 | } |
| 17 | 18 | ||
| 18 | } // namespace Service::APM | 19 | } // namespace Service::APM |
diff --git a/src/core/hle/service/apm/interface.cpp b/src/core/hle/service/apm/interface.cpp index ce943d829..4cd8132f5 100644 --- a/src/core/hle/service/apm/interface.cpp +++ b/src/core/hle/service/apm/interface.cpp | |||
| @@ -74,6 +74,31 @@ void APM::OpenSession(Kernel::HLERequestContext& ctx) { | |||
| 74 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 74 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 75 | rb.Push(RESULT_SUCCESS); | 75 | rb.Push(RESULT_SUCCESS); |
| 76 | rb.PushIpcInterface<ISession>(); | 76 | rb.PushIpcInterface<ISession>(); |
| 77 | |||
| 78 | LOG_DEBUG(Service_APM, "called"); | ||
| 79 | } | ||
| 80 | |||
| 81 | APM_Sys::APM_Sys() : ServiceFramework{"apm:sys"} { | ||
| 82 | // clang-format off | ||
| 83 | static const FunctionInfo functions[] = { | ||
| 84 | {0, nullptr, "RequestPerformanceMode"}, | ||
| 85 | {1, &APM_Sys::GetPerformanceEvent, "GetPerformanceEvent"}, | ||
| 86 | {2, nullptr, "GetThrottlingState"}, | ||
| 87 | {3, nullptr, "GetLastThrottlingState"}, | ||
| 88 | {4, nullptr, "ClearLastThrottlingState"}, | ||
| 89 | {5, nullptr, "LoadAndApplySettings"}, | ||
| 90 | }; | ||
| 91 | // clang-format on | ||
| 92 | |||
| 93 | RegisterHandlers(functions); | ||
| 94 | } | ||
| 95 | |||
| 96 | void APM_Sys::GetPerformanceEvent(Kernel::HLERequestContext& ctx) { | ||
| 97 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 98 | rb.Push(RESULT_SUCCESS); | ||
| 99 | rb.PushIpcInterface<ISession>(); | ||
| 100 | |||
| 101 | LOG_DEBUG(Service_APM, "called"); | ||
| 77 | } | 102 | } |
| 78 | 103 | ||
| 79 | } // namespace Service::APM | 104 | } // namespace Service::APM |
diff --git a/src/core/hle/service/apm/interface.h b/src/core/hle/service/apm/interface.h index fa68c7d93..d14264ad7 100644 --- a/src/core/hle/service/apm/interface.h +++ b/src/core/hle/service/apm/interface.h | |||
| @@ -19,4 +19,12 @@ private: | |||
| 19 | std::shared_ptr<Module> apm; | 19 | std::shared_ptr<Module> apm; |
| 20 | }; | 20 | }; |
| 21 | 21 | ||
| 22 | class APM_Sys final : public ServiceFramework<APM_Sys> { | ||
| 23 | public: | ||
| 24 | explicit APM_Sys(); | ||
| 25 | |||
| 26 | private: | ||
| 27 | void GetPerformanceEvent(Kernel::HLERequestContext& ctx); | ||
| 28 | }; | ||
| 29 | |||
| 22 | } // namespace Service::APM | 30 | } // namespace Service::APM |
diff --git a/src/core/hle/service/arp/arp.cpp b/src/core/hle/service/arp/arp.cpp new file mode 100644 index 000000000..358ef2576 --- /dev/null +++ b/src/core/hle/service/arp/arp.cpp | |||
| @@ -0,0 +1,75 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <memory> | ||
| 6 | |||
| 7 | #include "common/logging/log.h" | ||
| 8 | #include "core/hle/ipc_helpers.h" | ||
| 9 | #include "core/hle/kernel/hle_ipc.h" | ||
| 10 | #include "core/hle/service/arp/arp.h" | ||
| 11 | #include "core/hle/service/service.h" | ||
| 12 | #include "core/hle/service/sm/sm.h" | ||
| 13 | |||
| 14 | namespace Service::ARP { | ||
| 15 | |||
| 16 | class ARP_R final : public ServiceFramework<ARP_R> { | ||
| 17 | public: | ||
| 18 | explicit ARP_R() : ServiceFramework{"arp:r"} { | ||
| 19 | // clang-format off | ||
| 20 | static const FunctionInfo functions[] = { | ||
| 21 | {0, nullptr, "GetApplicationLaunchProperty"}, | ||
| 22 | {1, nullptr, "GetApplicationLaunchPropertyWithApplicationId"}, | ||
| 23 | {2, nullptr, "GetApplicationControlProperty"}, | ||
| 24 | {3, nullptr, "GetApplicationControlPropertyWithApplicationId"}, | ||
| 25 | }; | ||
| 26 | // clang-format on | ||
| 27 | |||
| 28 | RegisterHandlers(functions); | ||
| 29 | } | ||
| 30 | }; | ||
| 31 | |||
| 32 | class IRegistrar final : public ServiceFramework<IRegistrar> { | ||
| 33 | public: | ||
| 34 | explicit IRegistrar() : ServiceFramework{"IRegistrar"} { | ||
| 35 | // clang-format off | ||
| 36 | static const FunctionInfo functions[] = { | ||
| 37 | {0, nullptr, "Issue"}, | ||
| 38 | {1, nullptr, "SetApplicationLaunchProperty"}, | ||
| 39 | {2, nullptr, "SetApplicationControlProperty"}, | ||
| 40 | }; | ||
| 41 | // clang-format on | ||
| 42 | |||
| 43 | RegisterHandlers(functions); | ||
| 44 | } | ||
| 45 | }; | ||
| 46 | |||
| 47 | class ARP_W final : public ServiceFramework<ARP_W> { | ||
| 48 | public: | ||
| 49 | explicit ARP_W() : ServiceFramework{"arp:w"} { | ||
| 50 | // clang-format off | ||
| 51 | static const FunctionInfo functions[] = { | ||
| 52 | {0, &ARP_W::AcquireRegistrar, "AcquireRegistrar"}, | ||
| 53 | {1, nullptr, "DeleteProperties"}, | ||
| 54 | }; | ||
| 55 | // clang-format on | ||
| 56 | |||
| 57 | RegisterHandlers(functions); | ||
| 58 | } | ||
| 59 | |||
| 60 | private: | ||
| 61 | void AcquireRegistrar(Kernel::HLERequestContext& ctx) { | ||
| 62 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 63 | rb.Push(RESULT_SUCCESS); | ||
| 64 | rb.PushIpcInterface<IRegistrar>(); | ||
| 65 | |||
| 66 | LOG_DEBUG(Service_ARP, "called"); | ||
| 67 | } | ||
| 68 | }; | ||
| 69 | |||
| 70 | void InstallInterfaces(SM::ServiceManager& sm) { | ||
| 71 | std::make_shared<ARP_R>()->InstallAsService(sm); | ||
| 72 | std::make_shared<ARP_W>()->InstallAsService(sm); | ||
| 73 | } | ||
| 74 | |||
| 75 | } // namespace Service::ARP | ||
diff --git a/src/core/hle/service/arp/arp.h b/src/core/hle/service/arp/arp.h new file mode 100644 index 000000000..9d100187c --- /dev/null +++ b/src/core/hle/service/arp/arp.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | namespace Service::SM { | ||
| 8 | class ServiceManager; | ||
| 9 | } | ||
| 10 | |||
| 11 | namespace Service::ARP { | ||
| 12 | |||
| 13 | /// Registers all ARP services with the specified service manager. | ||
| 14 | void InstallInterfaces(SM::ServiceManager& sm); | ||
| 15 | |||
| 16 | } // namespace Service::ARP | ||
diff --git a/src/core/hle/service/audio/audctl.cpp b/src/core/hle/service/audio/audctl.cpp new file mode 100644 index 000000000..37c3fdcac --- /dev/null +++ b/src/core/hle/service/audio/audctl.cpp | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/hle/service/audio/audctl.h" | ||
| 6 | |||
| 7 | namespace Service::Audio { | ||
| 8 | |||
| 9 | AudCtl::AudCtl() : ServiceFramework{"audctl"} { | ||
| 10 | // clang-format off | ||
| 11 | static const FunctionInfo functions[] = { | ||
| 12 | {0, nullptr, "GetTargetVolume"}, | ||
| 13 | {1, nullptr, "SetTargetVolume"}, | ||
| 14 | {2, nullptr, "GetTargetVolumeMin"}, | ||
| 15 | {3, nullptr, "GetTargetVolumeMax"}, | ||
| 16 | {4, nullptr, "IsTargetMute"}, | ||
| 17 | {5, nullptr, "SetTargetMute"}, | ||
| 18 | {6, nullptr, "IsTargetConnected"}, | ||
| 19 | {7, nullptr, "SetDefaultTarget"}, | ||
| 20 | {8, nullptr, "GetDefaultTarget"}, | ||
| 21 | {9, nullptr, "GetAudioOutputMode"}, | ||
| 22 | {10, nullptr, "SetAudioOutputMode"}, | ||
| 23 | {11, nullptr, "SetForceMutePolicy"}, | ||
| 24 | {12, nullptr, "GetForceMutePolicy"}, | ||
| 25 | {13, nullptr, "GetOutputModeSetting"}, | ||
| 26 | {14, nullptr, "SetOutputModeSetting"}, | ||
| 27 | {15, nullptr, "SetOutputTarget"}, | ||
| 28 | {16, nullptr, "SetInputTargetForceEnabled"}, | ||
| 29 | {17, nullptr, "SetHeadphoneOutputLevelMode"}, | ||
| 30 | {18, nullptr, "GetHeadphoneOutputLevelMode"}, | ||
| 31 | {19, nullptr, "AcquireAudioVolumeUpdateEventForPlayReport"}, | ||
| 32 | {20, nullptr, "AcquireAudioOutputDeviceUpdateEventForPlayReport"}, | ||
| 33 | {21, nullptr, "GetAudioOutputTargetForPlayReport"}, | ||
| 34 | {22, nullptr, "NotifyHeadphoneVolumeWarningDisplayedEvent"}, | ||
| 35 | {23, nullptr, "SetSystemOutputMasterVolume"}, | ||
| 36 | {24, nullptr, "GetSystemOutputMasterVolume"}, | ||
| 37 | {25, nullptr, "GetAudioVolumeDataForPlayReport"}, | ||
| 38 | {26, nullptr, "UpdateHeadphoneSettings"}, | ||
| 39 | }; | ||
| 40 | // clang-format on | ||
| 41 | |||
| 42 | RegisterHandlers(functions); | ||
| 43 | } | ||
| 44 | |||
| 45 | } // namespace Service::Audio | ||
diff --git a/src/core/hle/service/audio/audctl.h b/src/core/hle/service/audio/audctl.h new file mode 100644 index 000000000..ed837bdf2 --- /dev/null +++ b/src/core/hle/service/audio/audctl.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::Audio { | ||
| 10 | |||
| 11 | class AudCtl final : public ServiceFramework<AudCtl> { | ||
| 12 | public: | ||
| 13 | explicit AudCtl(); | ||
| 14 | }; | ||
| 15 | |||
| 16 | } // namespace Service::Audio | ||
diff --git a/src/core/hle/service/audio/auddbg.cpp b/src/core/hle/service/audio/auddbg.cpp new file mode 100644 index 000000000..b08c21a20 --- /dev/null +++ b/src/core/hle/service/audio/auddbg.cpp | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/hle/service/audio/auddbg.h" | ||
| 6 | |||
| 7 | namespace Service::Audio { | ||
| 8 | |||
| 9 | AudDbg::AudDbg(const char* name) : ServiceFramework{name} { | ||
| 10 | // clang-format off | ||
| 11 | static const FunctionInfo functions[] = { | ||
| 12 | {0, nullptr, "RequestSuspendForDebug"}, | ||
| 13 | {1, nullptr, "RequestResumeForDebug"}, | ||
| 14 | }; | ||
| 15 | // clang-format on | ||
| 16 | |||
| 17 | RegisterHandlers(functions); | ||
| 18 | } | ||
| 19 | |||
| 20 | } // namespace Service::Audio | ||
diff --git a/src/core/hle/service/audio/auddbg.h b/src/core/hle/service/audio/auddbg.h new file mode 100644 index 000000000..a2f540b75 --- /dev/null +++ b/src/core/hle/service/audio/auddbg.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::Audio { | ||
| 10 | |||
| 11 | class AudDbg final : public ServiceFramework<AudDbg> { | ||
| 12 | public: | ||
| 13 | explicit AudDbg(const char* name); | ||
| 14 | }; | ||
| 15 | |||
| 16 | } // namespace Service::Audio | ||
diff --git a/src/core/hle/service/audio/audin_a.cpp b/src/core/hle/service/audio/audin_a.cpp new file mode 100644 index 000000000..a70d5bca4 --- /dev/null +++ b/src/core/hle/service/audio/audin_a.cpp | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/hle/service/audio/audin_a.h" | ||
| 6 | |||
| 7 | namespace Service::Audio { | ||
| 8 | |||
| 9 | AudInA::AudInA() : ServiceFramework{"audin:a"} { | ||
| 10 | // clang-format off | ||
| 11 | static const FunctionInfo functions[] = { | ||
| 12 | {0, nullptr, "RequestSuspendAudioIns"}, | ||
| 13 | {1, nullptr, "RequestResumeAudioIns"}, | ||
| 14 | {2, nullptr, "GetAudioInsProcessMasterVolume"}, | ||
| 15 | {3, nullptr, "SetAudioInsProcessMasterVolume"}, | ||
| 16 | }; | ||
| 17 | // clang-format on | ||
| 18 | |||
| 19 | RegisterHandlers(functions); | ||
| 20 | } | ||
| 21 | |||
| 22 | } // namespace Service::Audio | ||
diff --git a/src/core/hle/service/audio/audin_a.h b/src/core/hle/service/audio/audin_a.h new file mode 100644 index 000000000..e4c75510f --- /dev/null +++ b/src/core/hle/service/audio/audin_a.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::Audio { | ||
| 10 | |||
| 11 | class AudInA final : public ServiceFramework<AudInA> { | ||
| 12 | public: | ||
| 13 | explicit AudInA(); | ||
| 14 | }; | ||
| 15 | |||
| 16 | } // namespace Service::Audio | ||
diff --git a/src/core/hle/service/audio/audio.cpp b/src/core/hle/service/audio/audio.cpp index d231e91e1..6b5e15633 100644 --- a/src/core/hle/service/audio/audio.cpp +++ b/src/core/hle/service/audio/audio.cpp | |||
| @@ -2,10 +2,16 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "core/hle/service/audio/audctl.h" | ||
| 6 | #include "core/hle/service/audio/auddbg.h" | ||
| 7 | #include "core/hle/service/audio/audin_a.h" | ||
| 5 | #include "core/hle/service/audio/audin_u.h" | 8 | #include "core/hle/service/audio/audin_u.h" |
| 6 | #include "core/hle/service/audio/audio.h" | 9 | #include "core/hle/service/audio/audio.h" |
| 10 | #include "core/hle/service/audio/audout_a.h" | ||
| 7 | #include "core/hle/service/audio/audout_u.h" | 11 | #include "core/hle/service/audio/audout_u.h" |
| 12 | #include "core/hle/service/audio/audrec_a.h" | ||
| 8 | #include "core/hle/service/audio/audrec_u.h" | 13 | #include "core/hle/service/audio/audrec_u.h" |
| 14 | #include "core/hle/service/audio/audren_a.h" | ||
| 9 | #include "core/hle/service/audio/audren_u.h" | 15 | #include "core/hle/service/audio/audren_u.h" |
| 10 | #include "core/hle/service/audio/codecctl.h" | 16 | #include "core/hle/service/audio/codecctl.h" |
| 11 | #include "core/hle/service/audio/hwopus.h" | 17 | #include "core/hle/service/audio/hwopus.h" |
| @@ -13,12 +19,22 @@ | |||
| 13 | namespace Service::Audio { | 19 | namespace Service::Audio { |
| 14 | 20 | ||
| 15 | void InstallInterfaces(SM::ServiceManager& service_manager) { | 21 | void InstallInterfaces(SM::ServiceManager& service_manager) { |
| 22 | std::make_shared<AudCtl>()->InstallAsService(service_manager); | ||
| 23 | std::make_shared<AudOutA>()->InstallAsService(service_manager); | ||
| 16 | std::make_shared<AudOutU>()->InstallAsService(service_manager); | 24 | std::make_shared<AudOutU>()->InstallAsService(service_manager); |
| 25 | std::make_shared<AudInA>()->InstallAsService(service_manager); | ||
| 17 | std::make_shared<AudInU>()->InstallAsService(service_manager); | 26 | std::make_shared<AudInU>()->InstallAsService(service_manager); |
| 27 | std::make_shared<AudRecA>()->InstallAsService(service_manager); | ||
| 18 | std::make_shared<AudRecU>()->InstallAsService(service_manager); | 28 | std::make_shared<AudRecU>()->InstallAsService(service_manager); |
| 29 | std::make_shared<AudRenA>()->InstallAsService(service_manager); | ||
| 19 | std::make_shared<AudRenU>()->InstallAsService(service_manager); | 30 | std::make_shared<AudRenU>()->InstallAsService(service_manager); |
| 20 | std::make_shared<CodecCtl>()->InstallAsService(service_manager); | 31 | std::make_shared<CodecCtl>()->InstallAsService(service_manager); |
| 21 | std::make_shared<HwOpus>()->InstallAsService(service_manager); | 32 | std::make_shared<HwOpus>()->InstallAsService(service_manager); |
| 33 | |||
| 34 | std::make_shared<AudDbg>("audin:d")->InstallAsService(service_manager); | ||
| 35 | std::make_shared<AudDbg>("audout:d")->InstallAsService(service_manager); | ||
| 36 | std::make_shared<AudDbg>("audrec:d")->InstallAsService(service_manager); | ||
| 37 | std::make_shared<AudDbg>("audren:d")->InstallAsService(service_manager); | ||
| 22 | } | 38 | } |
| 23 | 39 | ||
| 24 | } // namespace Service::Audio | 40 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/audio/audout_a.cpp b/src/core/hle/service/audio/audout_a.cpp new file mode 100644 index 000000000..bf8d40157 --- /dev/null +++ b/src/core/hle/service/audio/audout_a.cpp | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/hle/service/audio/audout_a.h" | ||
| 6 | |||
| 7 | namespace Service::Audio { | ||
| 8 | |||
| 9 | AudOutA::AudOutA() : ServiceFramework{"audout:a"} { | ||
| 10 | // clang-format off | ||
| 11 | static const FunctionInfo functions[] = { | ||
| 12 | {0, nullptr, "RequestSuspendAudioOuts"}, | ||
| 13 | {1, nullptr, "RequestResumeAudioOuts"}, | ||
| 14 | {2, nullptr, "GetAudioOutsProcessMasterVolume"}, | ||
| 15 | {3, nullptr, "SetAudioOutsProcessMasterVolume"}, | ||
| 16 | {4, nullptr, "GetAudioOutsProcessRecordVolume"}, | ||
| 17 | {5, nullptr, "SetAudioOutsProcessRecordVolume"}, | ||
| 18 | }; | ||
| 19 | // clang-format on | ||
| 20 | |||
| 21 | RegisterHandlers(functions); | ||
| 22 | } | ||
| 23 | |||
| 24 | } // namespace Service::Audio | ||
diff --git a/src/core/hle/service/audio/audout_a.h b/src/core/hle/service/audio/audout_a.h new file mode 100644 index 000000000..91a069152 --- /dev/null +++ b/src/core/hle/service/audio/audout_a.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::Audio { | ||
| 10 | |||
| 11 | class AudOutA final : public ServiceFramework<AudOutA> { | ||
| 12 | public: | ||
| 13 | explicit AudOutA(); | ||
| 14 | }; | ||
| 15 | |||
| 16 | } // namespace Service::Audio | ||
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index 1dcd84d98..108a7c6eb 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp | |||
| @@ -4,9 +4,10 @@ | |||
| 4 | 4 | ||
| 5 | #include <array> | 5 | #include <array> |
| 6 | #include <vector> | 6 | #include <vector> |
| 7 | |||
| 8 | #include "audio_core/codec.h" | ||
| 7 | #include "common/logging/log.h" | 9 | #include "common/logging/log.h" |
| 8 | #include "core/core_timing.h" | 10 | #include "core/core.h" |
| 9 | #include "core/core_timing_util.h" | ||
| 10 | #include "core/hle/ipc_helpers.h" | 11 | #include "core/hle/ipc_helpers.h" |
| 11 | #include "core/hle/kernel/event.h" | 12 | #include "core/hle/kernel/event.h" |
| 12 | #include "core/hle/kernel/hle_ipc.h" | 13 | #include "core/hle/kernel/hle_ipc.h" |
| @@ -14,17 +15,21 @@ | |||
| 14 | 15 | ||
| 15 | namespace Service::Audio { | 16 | namespace Service::Audio { |
| 16 | 17 | ||
| 17 | /// Switch sample rate frequency | 18 | namespace ErrCodes { |
| 18 | constexpr u32 sample_rate{48000}; | 19 | enum { |
| 19 | /// TODO(st4rk): dynamic number of channels, as I think Switch has support | 20 | ErrorUnknown = 2, |
| 20 | /// to more audio channels (probably when Docked I guess) | 21 | BufferCountExceeded = 8, |
| 21 | constexpr u32 audio_channels{2}; | 22 | }; |
| 22 | /// TODO(st4rk): find a proper value for the audio_ticks | 23 | } |
| 23 | constexpr u64 audio_ticks{static_cast<u64>(CoreTiming::BASE_CLOCK_RATE / 500)}; | 24 | |
| 25 | constexpr std::array<char, 10> DefaultDevice{{"DeviceOut"}}; | ||
| 26 | constexpr int DefaultSampleRate{48000}; | ||
| 24 | 27 | ||
| 25 | class IAudioOut final : public ServiceFramework<IAudioOut> { | 28 | class IAudioOut final : public ServiceFramework<IAudioOut> { |
| 26 | public: | 29 | public: |
| 27 | IAudioOut() : ServiceFramework("IAudioOut"), audio_out_state(AudioState::Stopped) { | 30 | IAudioOut(AudoutParams audio_params, AudioCore::AudioOut& audio_core) |
| 31 | : ServiceFramework("IAudioOut"), audio_params(audio_params), audio_core(audio_core) { | ||
| 32 | |||
| 28 | static const FunctionInfo functions[] = { | 33 | static const FunctionInfo functions[] = { |
| 29 | {0, &IAudioOut::GetAudioOutState, "GetAudioOutState"}, | 34 | {0, &IAudioOut::GetAudioOutState, "GetAudioOutState"}, |
| 30 | {1, &IAudioOut::StartAudioOut, "StartAudioOut"}, | 35 | {1, &IAudioOut::StartAudioOut, "StartAudioOut"}, |
| @@ -32,66 +37,65 @@ public: | |||
| 32 | {3, &IAudioOut::AppendAudioOutBufferImpl, "AppendAudioOutBuffer"}, | 37 | {3, &IAudioOut::AppendAudioOutBufferImpl, "AppendAudioOutBuffer"}, |
| 33 | {4, &IAudioOut::RegisterBufferEvent, "RegisterBufferEvent"}, | 38 | {4, &IAudioOut::RegisterBufferEvent, "RegisterBufferEvent"}, |
| 34 | {5, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBuffer"}, | 39 | {5, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBuffer"}, |
| 35 | {6, nullptr, "ContainsAudioOutBuffer"}, | 40 | {6, &IAudioOut::ContainsAudioOutBuffer, "ContainsAudioOutBuffer"}, |
| 36 | {7, &IAudioOut::AppendAudioOutBufferImpl, "AppendAudioOutBufferAuto"}, | 41 | {7, &IAudioOut::AppendAudioOutBufferImpl, "AppendAudioOutBufferAuto"}, |
| 37 | {8, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBufferAuto"}, | 42 | {8, &IAudioOut::GetReleasedAudioOutBufferImpl, "GetReleasedAudioOutBufferAuto"}, |
| 38 | {9, nullptr, "GetAudioOutBufferCount"}, | 43 | {9, &IAudioOut::GetAudioOutBufferCount, "GetAudioOutBufferCount"}, |
| 39 | {10, nullptr, "GetAudioOutPlayedSampleCount"}, | 44 | {10, nullptr, "GetAudioOutPlayedSampleCount"}, |
| 40 | {11, nullptr, "FlushAudioOutBuffers"}, | 45 | {11, nullptr, "FlushAudioOutBuffers"}, |
| 41 | }; | 46 | }; |
| 42 | RegisterHandlers(functions); | 47 | RegisterHandlers(functions); |
| 43 | 48 | ||
| 44 | // This is the event handle used to check if the audio buffer was released | 49 | // This is the event handle used to check if the audio buffer was released |
| 45 | buffer_event = | 50 | buffer_event = Kernel::Event::Create(Kernel::ResetType::Sticky, "IAudioOutBufferReleased"); |
| 46 | Kernel::Event::Create(Kernel::ResetType::OneShot, "IAudioOutBufferReleasedEvent"); | ||
| 47 | |||
| 48 | // Register event callback to update the Audio Buffer | ||
| 49 | audio_event = CoreTiming::RegisterEvent( | ||
| 50 | "IAudioOut::UpdateAudioBuffersCallback", [this](u64 userdata, int cycles_late) { | ||
| 51 | UpdateAudioBuffersCallback(); | ||
| 52 | CoreTiming::ScheduleEvent(audio_ticks - cycles_late, audio_event); | ||
| 53 | }); | ||
| 54 | |||
| 55 | // Start the audio event | ||
| 56 | CoreTiming::ScheduleEvent(audio_ticks, audio_event); | ||
| 57 | } | ||
| 58 | 51 | ||
| 59 | ~IAudioOut() { | 52 | stream = audio_core.OpenStream(audio_params.sample_rate, audio_params.channel_count, |
| 60 | CoreTiming::UnscheduleEvent(audio_event, 0); | 53 | "IAudioOut", [=]() { buffer_event->Signal(); }); |
| 61 | } | 54 | } |
| 62 | 55 | ||
| 63 | private: | 56 | private: |
| 57 | struct AudioBuffer { | ||
| 58 | u64_le next; | ||
| 59 | u64_le buffer; | ||
| 60 | u64_le buffer_capacity; | ||
| 61 | u64_le buffer_size; | ||
| 62 | u64_le offset; | ||
| 63 | }; | ||
| 64 | static_assert(sizeof(AudioBuffer) == 0x28, "AudioBuffer is an invalid size"); | ||
| 65 | |||
| 64 | void GetAudioOutState(Kernel::HLERequestContext& ctx) { | 66 | void GetAudioOutState(Kernel::HLERequestContext& ctx) { |
| 65 | LOG_DEBUG(Service_Audio, "called"); | 67 | LOG_DEBUG(Service_Audio, "called"); |
| 66 | IPC::ResponseBuilder rb{ctx, 3}; | 68 | IPC::ResponseBuilder rb{ctx, 3}; |
| 67 | rb.Push(RESULT_SUCCESS); | 69 | rb.Push(RESULT_SUCCESS); |
| 68 | rb.Push(static_cast<u32>(audio_out_state)); | 70 | rb.Push(static_cast<u32>(stream->IsPlaying() ? AudioState::Started : AudioState::Stopped)); |
| 69 | } | 71 | } |
| 70 | 72 | ||
| 71 | void StartAudioOut(Kernel::HLERequestContext& ctx) { | 73 | void StartAudioOut(Kernel::HLERequestContext& ctx) { |
| 72 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 74 | LOG_DEBUG(Service_Audio, "called"); |
| 73 | 75 | ||
| 74 | // Start audio | 76 | if (stream->IsPlaying()) { |
| 75 | audio_out_state = AudioState::Started; | 77 | IPC::ResponseBuilder rb{ctx, 2}; |
| 78 | rb.Push(ResultCode(ErrorModule::Audio, ErrCodes::ErrorUnknown)); | ||
| 79 | return; | ||
| 80 | } | ||
| 81 | |||
| 82 | audio_core.StartStream(stream); | ||
| 76 | 83 | ||
| 77 | IPC::ResponseBuilder rb{ctx, 2}; | 84 | IPC::ResponseBuilder rb{ctx, 2}; |
| 78 | rb.Push(RESULT_SUCCESS); | 85 | rb.Push(RESULT_SUCCESS); |
| 79 | } | 86 | } |
| 80 | 87 | ||
| 81 | void StopAudioOut(Kernel::HLERequestContext& ctx) { | 88 | void StopAudioOut(Kernel::HLERequestContext& ctx) { |
| 82 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 89 | LOG_DEBUG(Service_Audio, "called"); |
| 83 | |||
| 84 | // Stop audio | ||
| 85 | audio_out_state = AudioState::Stopped; | ||
| 86 | 90 | ||
| 87 | queue_keys.clear(); | 91 | audio_core.StopStream(stream); |
| 88 | 92 | ||
| 89 | IPC::ResponseBuilder rb{ctx, 2}; | 93 | IPC::ResponseBuilder rb{ctx, 2}; |
| 90 | rb.Push(RESULT_SUCCESS); | 94 | rb.Push(RESULT_SUCCESS); |
| 91 | } | 95 | } |
| 92 | 96 | ||
| 93 | void RegisterBufferEvent(Kernel::HLERequestContext& ctx) { | 97 | void RegisterBufferEvent(Kernel::HLERequestContext& ctx) { |
| 94 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 98 | LOG_DEBUG(Service_Audio, "called"); |
| 95 | 99 | ||
| 96 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 100 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 97 | rb.Push(RESULT_SUCCESS); | 101 | rb.Push(RESULT_SUCCESS); |
| @@ -99,101 +103,107 @@ private: | |||
| 99 | } | 103 | } |
| 100 | 104 | ||
| 101 | void AppendAudioOutBufferImpl(Kernel::HLERequestContext& ctx) { | 105 | void AppendAudioOutBufferImpl(Kernel::HLERequestContext& ctx) { |
| 102 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 106 | LOG_DEBUG(Service_Audio, "(STUBBED) called {}", ctx.Description()); |
| 103 | IPC::RequestParser rp{ctx}; | 107 | IPC::RequestParser rp{ctx}; |
| 104 | 108 | ||
| 105 | const u64 key{rp.Pop<u64>()}; | 109 | const auto& input_buffer{ctx.ReadBuffer()}; |
| 106 | queue_keys.insert(queue_keys.begin(), key); | 110 | ASSERT_MSG(input_buffer.size() == sizeof(AudioBuffer), |
| 111 | "AudioBuffer input is an invalid size!"); | ||
| 112 | AudioBuffer audio_buffer{}; | ||
| 113 | std::memcpy(&audio_buffer, input_buffer.data(), sizeof(AudioBuffer)); | ||
| 114 | const u64 tag{rp.Pop<u64>()}; | ||
| 115 | |||
| 116 | std::vector<s16> samples(audio_buffer.buffer_size / sizeof(s16)); | ||
| 117 | Memory::ReadBlock(audio_buffer.buffer, samples.data(), audio_buffer.buffer_size); | ||
| 118 | |||
| 119 | if (!audio_core.QueueBuffer(stream, tag, std::move(samples))) { | ||
| 120 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 121 | rb.Push(ResultCode(ErrorModule::Audio, ErrCodes::BufferCountExceeded)); | ||
| 122 | } | ||
| 107 | 123 | ||
| 108 | IPC::ResponseBuilder rb{ctx, 2}; | 124 | IPC::ResponseBuilder rb{ctx, 2}; |
| 109 | rb.Push(RESULT_SUCCESS); | 125 | rb.Push(RESULT_SUCCESS); |
| 110 | } | 126 | } |
| 111 | 127 | ||
| 112 | void GetReleasedAudioOutBufferImpl(Kernel::HLERequestContext& ctx) { | 128 | void GetReleasedAudioOutBufferImpl(Kernel::HLERequestContext& ctx) { |
| 113 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 129 | LOG_DEBUG(Service_Audio, "called {}", ctx.Description()); |
| 114 | 130 | IPC::RequestParser rp{ctx}; | |
| 115 | // TODO(st4rk): This is how libtransistor currently implements the | 131 | const u64 max_count{ctx.GetWriteBufferSize() / sizeof(u64)}; |
| 116 | // GetReleasedAudioOutBuffer, it should return the key (a VAddr) to the app and this address | 132 | const auto released_buffers{audio_core.GetTagsAndReleaseBuffers(stream, max_count)}; |
| 117 | // is used to know which buffer should be filled with data and send again to the service | ||
| 118 | // through AppendAudioOutBuffer. Check if this is the proper way to do it. | ||
| 119 | u64 key{0}; | ||
| 120 | |||
| 121 | if (queue_keys.size()) { | ||
| 122 | key = queue_keys.back(); | ||
| 123 | queue_keys.pop_back(); | ||
| 124 | } | ||
| 125 | 133 | ||
| 126 | ctx.WriteBuffer(&key, sizeof(u64)); | 134 | std::vector<u64> tags{released_buffers}; |
| 135 | tags.resize(max_count); | ||
| 136 | ctx.WriteBuffer(tags); | ||
| 127 | 137 | ||
| 128 | IPC::ResponseBuilder rb{ctx, 3}; | 138 | IPC::ResponseBuilder rb{ctx, 3}; |
| 129 | rb.Push(RESULT_SUCCESS); | 139 | rb.Push(RESULT_SUCCESS); |
| 130 | // TODO(st4rk): This might be the total of released buffers, needs to be verified on | 140 | rb.Push<u32>(static_cast<u32>(released_buffers.size())); |
| 131 | // hardware | ||
| 132 | rb.Push<u32>(static_cast<u32>(queue_keys.size())); | ||
| 133 | } | 141 | } |
| 134 | 142 | ||
| 135 | void UpdateAudioBuffersCallback() { | 143 | void ContainsAudioOutBuffer(Kernel::HLERequestContext& ctx) { |
| 136 | if (audio_out_state != AudioState::Started) { | 144 | LOG_DEBUG(Service_Audio, "called"); |
| 137 | return; | 145 | IPC::RequestParser rp{ctx}; |
| 138 | } | 146 | const u64 tag{rp.Pop<u64>()}; |
| 139 | 147 | IPC::ResponseBuilder rb{ctx, 3}; | |
| 140 | if (queue_keys.empty()) { | 148 | rb.Push(RESULT_SUCCESS); |
| 141 | return; | 149 | rb.Push(stream->ContainsBuffer(tag)); |
| 142 | } | 150 | } |
| 143 | 151 | ||
| 144 | buffer_event->Signal(); | 152 | void GetAudioOutBufferCount(Kernel::HLERequestContext& ctx) { |
| 153 | LOG_DEBUG(Service_Audio, "called"); | ||
| 154 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 155 | rb.Push(RESULT_SUCCESS); | ||
| 156 | rb.Push(static_cast<u32>(stream->GetQueueSize())); | ||
| 145 | } | 157 | } |
| 146 | 158 | ||
| 147 | enum class AudioState : u32 { | 159 | AudioCore::AudioOut& audio_core; |
| 148 | Started, | 160 | AudioCore::StreamPtr stream; |
| 149 | Stopped, | ||
| 150 | }; | ||
| 151 | 161 | ||
| 152 | /// This is used to trigger the audio event callback that is going to read the samples from the | 162 | AudoutParams audio_params{}; |
| 153 | /// audio_buffer list and enqueue the samples using the sink (audio_core). | ||
| 154 | CoreTiming::EventType* audio_event; | ||
| 155 | 163 | ||
| 156 | /// This is the evend handle used to check if the audio buffer was released | 164 | /// This is the evend handle used to check if the audio buffer was released |
| 157 | Kernel::SharedPtr<Kernel::Event> buffer_event; | 165 | Kernel::SharedPtr<Kernel::Event> buffer_event; |
| 158 | |||
| 159 | /// (st4rk): This is just a temporary workaround for the future implementation. Libtransistor | ||
| 160 | /// uses the key as an address in the App, so we need to return when the | ||
| 161 | /// GetReleasedAudioOutBuffer_1 is called, otherwise we'll run in problems, because | ||
| 162 | /// libtransistor uses the key returned as an pointer. | ||
| 163 | std::vector<u64> queue_keys; | ||
| 164 | |||
| 165 | AudioState audio_out_state; | ||
| 166 | }; | 166 | }; |
| 167 | 167 | ||
| 168 | void AudOutU::ListAudioOutsImpl(Kernel::HLERequestContext& ctx) { | 168 | void AudOutU::ListAudioOutsImpl(Kernel::HLERequestContext& ctx) { |
| 169 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 169 | LOG_DEBUG(Service_Audio, "called"); |
| 170 | IPC::RequestParser rp{ctx}; | 170 | IPC::RequestParser rp{ctx}; |
| 171 | 171 | ||
| 172 | constexpr std::array<char, 15> audio_interface{{"AudioInterface"}}; | 172 | ctx.WriteBuffer(DefaultDevice); |
| 173 | ctx.WriteBuffer(audio_interface); | ||
| 174 | 173 | ||
| 175 | IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0); | 174 | IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0); |
| 176 | 175 | ||
| 177 | rb.Push(RESULT_SUCCESS); | 176 | rb.Push(RESULT_SUCCESS); |
| 178 | // TODO(st4rk): We're currently returning only one audio interface (stringlist size). However, | 177 | rb.Push<u32>(1); // Amount of audio devices |
| 179 | // it's highly possible to have more than one interface (despite that libtransistor requires | ||
| 180 | // only one). | ||
| 181 | rb.Push<u32>(1); | ||
| 182 | } | 178 | } |
| 183 | 179 | ||
| 184 | void AudOutU::OpenAudioOutImpl(Kernel::HLERequestContext& ctx) { | 180 | void AudOutU::OpenAudioOutImpl(Kernel::HLERequestContext& ctx) { |
| 185 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 181 | LOG_DEBUG(Service_Audio, "called"); |
| 186 | 182 | ||
| 187 | if (!audio_out_interface) { | 183 | ctx.WriteBuffer(DefaultDevice); |
| 188 | audio_out_interface = std::make_shared<IAudioOut>(); | 184 | IPC::RequestParser rp{ctx}; |
| 185 | auto params{rp.PopRaw<AudoutParams>()}; | ||
| 186 | if (params.channel_count <= 2) { | ||
| 187 | // Mono does not exist for audout | ||
| 188 | params.channel_count = 2; | ||
| 189 | } else { | ||
| 190 | params.channel_count = 6; | ||
| 189 | } | 191 | } |
| 192 | if (!params.sample_rate) { | ||
| 193 | params.sample_rate = DefaultSampleRate; | ||
| 194 | } | ||
| 195 | |||
| 196 | // TODO(bunnei): Support more than one IAudioOut interface. When we add this, ListAudioOutsImpl | ||
| 197 | // will likely need to be updated as well. | ||
| 198 | ASSERT_MSG(!audio_out_interface, "Unimplemented"); | ||
| 199 | audio_out_interface = std::make_shared<IAudioOut>(params, *audio_core); | ||
| 190 | 200 | ||
| 191 | IPC::ResponseBuilder rb{ctx, 6, 0, 1}; | 201 | IPC::ResponseBuilder rb{ctx, 6, 0, 1}; |
| 192 | rb.Push(RESULT_SUCCESS); | 202 | rb.Push(RESULT_SUCCESS); |
| 193 | rb.Push<u32>(sample_rate); | 203 | rb.Push<u32>(DefaultSampleRate); |
| 194 | rb.Push<u32>(audio_channels); | 204 | rb.Push<u32>(params.channel_count); |
| 195 | rb.Push<u32>(static_cast<u32>(PcmFormat::Int16)); | 205 | rb.Push<u32>(static_cast<u32>(AudioCore::Codec::PcmFormat::Int16)); |
| 196 | rb.Push<u32>(0); // This field is unknown | 206 | rb.Push<u32>(static_cast<u32>(AudioState::Stopped)); |
| 197 | rb.PushIpcInterface<Audio::IAudioOut>(audio_out_interface); | 207 | rb.PushIpcInterface<Audio::IAudioOut>(audio_out_interface); |
| 198 | } | 208 | } |
| 199 | 209 | ||
| @@ -203,6 +213,7 @@ AudOutU::AudOutU() : ServiceFramework("audout:u") { | |||
| 203 | {2, &AudOutU::ListAudioOutsImpl, "ListAudioOutsAuto"}, | 213 | {2, &AudOutU::ListAudioOutsImpl, "ListAudioOutsAuto"}, |
| 204 | {3, &AudOutU::OpenAudioOutImpl, "OpenAudioOutAuto"}}; | 214 | {3, &AudOutU::OpenAudioOutImpl, "OpenAudioOutAuto"}}; |
| 205 | RegisterHandlers(functions); | 215 | RegisterHandlers(functions); |
| 216 | audio_core = std::make_unique<AudioCore::AudioOut>(); | ||
| 206 | } | 217 | } |
| 207 | 218 | ||
| 208 | } // namespace Service::Audio | 219 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/audio/audout_u.h b/src/core/hle/service/audio/audout_u.h index 847d86aa6..fd491f65d 100644 --- a/src/core/hle/service/audio/audout_u.h +++ b/src/core/hle/service/audio/audout_u.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include "audio_core/audio_out.h" | ||
| 7 | #include "core/hle/service/service.h" | 8 | #include "core/hle/service/service.h" |
| 8 | 9 | ||
| 9 | namespace Kernel { | 10 | namespace Kernel { |
| @@ -12,6 +13,18 @@ class HLERequestContext; | |||
| 12 | 13 | ||
| 13 | namespace Service::Audio { | 14 | namespace Service::Audio { |
| 14 | 15 | ||
| 16 | struct AudoutParams { | ||
| 17 | s32_le sample_rate; | ||
| 18 | u16_le channel_count; | ||
| 19 | INSERT_PADDING_BYTES(2); | ||
| 20 | }; | ||
| 21 | static_assert(sizeof(AudoutParams) == 0x8, "AudoutParams is an invalid size"); | ||
| 22 | |||
| 23 | enum class AudioState : u32 { | ||
| 24 | Started, | ||
| 25 | Stopped, | ||
| 26 | }; | ||
| 27 | |||
| 15 | class IAudioOut; | 28 | class IAudioOut; |
| 16 | 29 | ||
| 17 | class AudOutU final : public ServiceFramework<AudOutU> { | 30 | class AudOutU final : public ServiceFramework<AudOutU> { |
| @@ -21,19 +34,10 @@ public: | |||
| 21 | 34 | ||
| 22 | private: | 35 | private: |
| 23 | std::shared_ptr<IAudioOut> audio_out_interface; | 36 | std::shared_ptr<IAudioOut> audio_out_interface; |
| 37 | std::unique_ptr<AudioCore::AudioOut> audio_core; | ||
| 24 | 38 | ||
| 25 | void ListAudioOutsImpl(Kernel::HLERequestContext& ctx); | 39 | void ListAudioOutsImpl(Kernel::HLERequestContext& ctx); |
| 26 | void OpenAudioOutImpl(Kernel::HLERequestContext& ctx); | 40 | void OpenAudioOutImpl(Kernel::HLERequestContext& ctx); |
| 27 | |||
| 28 | enum class PcmFormat : u32 { | ||
| 29 | Invalid = 0, | ||
| 30 | Int8 = 1, | ||
| 31 | Int16 = 2, | ||
| 32 | Int24 = 3, | ||
| 33 | Int32 = 4, | ||
| 34 | PcmFloat = 5, | ||
| 35 | Adpcm = 6, | ||
| 36 | }; | ||
| 37 | }; | 41 | }; |
| 38 | 42 | ||
| 39 | } // namespace Service::Audio | 43 | } // namespace Service::Audio |
diff --git a/src/core/hle/service/audio/audrec_a.cpp b/src/core/hle/service/audio/audrec_a.cpp new file mode 100644 index 000000000..016eabf53 --- /dev/null +++ b/src/core/hle/service/audio/audrec_a.cpp | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/hle/service/audio/audrec_a.h" | ||
| 6 | |||
| 7 | namespace Service::Audio { | ||
| 8 | |||
| 9 | AudRecA::AudRecA() : ServiceFramework{"audrec:a"} { | ||
| 10 | // clang-format off | ||
| 11 | static const FunctionInfo functions[] = { | ||
| 12 | {0, nullptr, "RequestSuspendFinalOutputRecorders"}, | ||
| 13 | {1, nullptr, "RequestResumeFinalOutputRecorders"}, | ||
| 14 | }; | ||
| 15 | // clang-format on | ||
| 16 | |||
| 17 | RegisterHandlers(functions); | ||
| 18 | } | ||
| 19 | |||
| 20 | } // namespace Service::Audio | ||
diff --git a/src/core/hle/service/audio/audrec_a.h b/src/core/hle/service/audio/audrec_a.h new file mode 100644 index 000000000..9685047f2 --- /dev/null +++ b/src/core/hle/service/audio/audrec_a.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::Audio { | ||
| 10 | |||
| 11 | class AudRecA final : public ServiceFramework<AudRecA> { | ||
| 12 | public: | ||
| 13 | explicit AudRecA(); | ||
| 14 | }; | ||
| 15 | |||
| 16 | } // namespace Service::Audio | ||
diff --git a/src/core/hle/service/audio/audren_a.cpp b/src/core/hle/service/audio/audren_a.cpp new file mode 100644 index 000000000..616ff3dc4 --- /dev/null +++ b/src/core/hle/service/audio/audren_a.cpp | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/hle/service/audio/audren_a.h" | ||
| 6 | |||
| 7 | namespace Service::Audio { | ||
| 8 | |||
| 9 | AudRenA::AudRenA() : ServiceFramework{"audren:a"} { | ||
| 10 | // clang-format off | ||
| 11 | static const FunctionInfo functions[] = { | ||
| 12 | {0, nullptr, "RequestSuspendAudioRenderers"}, | ||
| 13 | {1, nullptr, "RequestResumeAudioRenderers"}, | ||
| 14 | {2, nullptr, "GetAudioRenderersProcessMasterVolume"}, | ||
| 15 | {3, nullptr, "SetAudioRenderersProcessMasterVolume"}, | ||
| 16 | {4, nullptr, "RegisterAppletResourceUserId"}, | ||
| 17 | {5, nullptr, "UnregisterAppletResourceUserId"}, | ||
| 18 | {6, nullptr, "GetAudioRenderersProcessRecordVolume"}, | ||
| 19 | {7, nullptr, "SetAudioRenderersProcessRecordVolume"}, | ||
| 20 | }; | ||
| 21 | // clang-format on | ||
| 22 | |||
| 23 | RegisterHandlers(functions); | ||
| 24 | } | ||
| 25 | |||
| 26 | } // namespace Service::Audio | ||
diff --git a/src/core/hle/service/audio/audren_a.h b/src/core/hle/service/audio/audren_a.h new file mode 100644 index 000000000..5ecf2e184 --- /dev/null +++ b/src/core/hle/service/audio/audren_a.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::Audio { | ||
| 10 | |||
| 11 | class AudRenA final : public ServiceFramework<AudRenA> { | ||
| 12 | public: | ||
| 13 | explicit AudRenA(); | ||
| 14 | }; | ||
| 15 | |||
| 16 | } // namespace Service::Audio | ||
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index 6aed9e2fa..f99304de5 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp | |||
| @@ -15,13 +15,10 @@ | |||
| 15 | 15 | ||
| 16 | namespace Service::Audio { | 16 | namespace Service::Audio { |
| 17 | 17 | ||
| 18 | /// TODO(bunnei): Find a proper value for the audio_ticks | ||
| 19 | constexpr u64 audio_ticks{static_cast<u64>(CoreTiming::BASE_CLOCK_RATE / 200)}; | ||
| 20 | |||
| 21 | class IAudioRenderer final : public ServiceFramework<IAudioRenderer> { | 18 | class IAudioRenderer final : public ServiceFramework<IAudioRenderer> { |
| 22 | public: | 19 | public: |
| 23 | explicit IAudioRenderer(AudioRendererParameter audren_params) | 20 | explicit IAudioRenderer(AudioCore::AudioRendererParameter audren_params) |
| 24 | : ServiceFramework("IAudioRenderer"), worker_params(audren_params) { | 21 | : ServiceFramework("IAudioRenderer") { |
| 25 | static const FunctionInfo functions[] = { | 22 | static const FunctionInfo functions[] = { |
| 26 | {0, nullptr, "GetAudioRendererSampleRate"}, | 23 | {0, nullptr, "GetAudioRendererSampleRate"}, |
| 27 | {1, nullptr, "GetAudioRendererSampleCount"}, | 24 | {1, nullptr, "GetAudioRendererSampleCount"}, |
| @@ -39,21 +36,8 @@ public: | |||
| 39 | RegisterHandlers(functions); | 36 | RegisterHandlers(functions); |
| 40 | 37 | ||
| 41 | system_event = | 38 | system_event = |
| 42 | Kernel::Event::Create(Kernel::ResetType::OneShot, "IAudioRenderer:SystemEvent"); | 39 | Kernel::Event::Create(Kernel::ResetType::Sticky, "IAudioRenderer:SystemEvent"); |
| 43 | 40 | renderer = std::make_unique<AudioCore::AudioRenderer>(audren_params, system_event); | |
| 44 | // Register event callback to update the Audio Buffer | ||
| 45 | audio_event = CoreTiming::RegisterEvent( | ||
| 46 | "IAudioRenderer::UpdateAudioCallback", [this](u64 userdata, int cycles_late) { | ||
| 47 | UpdateAudioCallback(); | ||
| 48 | CoreTiming::ScheduleEvent(audio_ticks - cycles_late, audio_event); | ||
| 49 | }); | ||
| 50 | |||
| 51 | // Start the audio event | ||
| 52 | CoreTiming::ScheduleEvent(audio_ticks, audio_event); | ||
| 53 | voice_status_list.resize(worker_params.voice_count); | ||
| 54 | } | ||
| 55 | ~IAudioRenderer() { | ||
| 56 | CoreTiming::UnscheduleEvent(audio_event, 0); | ||
| 57 | } | 41 | } |
| 58 | 42 | ||
| 59 | private: | 43 | private: |
| @@ -62,60 +46,9 @@ private: | |||
| 62 | } | 46 | } |
| 63 | 47 | ||
| 64 | void RequestUpdateAudioRenderer(Kernel::HLERequestContext& ctx) { | 48 | void RequestUpdateAudioRenderer(Kernel::HLERequestContext& ctx) { |
| 65 | UpdateDataHeader config{}; | 49 | ctx.WriteBuffer(renderer->UpdateAudioRenderer(ctx.ReadBuffer())); |
| 66 | auto buf = ctx.ReadBuffer(); | ||
| 67 | std::memcpy(&config, buf.data(), sizeof(UpdateDataHeader)); | ||
| 68 | u32 memory_pool_count = worker_params.effect_count + (worker_params.voice_count * 4); | ||
| 69 | |||
| 70 | std::vector<MemoryPoolInfo> mem_pool_info(memory_pool_count); | ||
| 71 | std::memcpy(mem_pool_info.data(), | ||
| 72 | buf.data() + sizeof(UpdateDataHeader) + config.behavior_size, | ||
| 73 | memory_pool_count * sizeof(MemoryPoolInfo)); | ||
| 74 | |||
| 75 | std::vector<VoiceInfo> voice_info(worker_params.voice_count); | ||
| 76 | std::memcpy(voice_info.data(), | ||
| 77 | buf.data() + sizeof(UpdateDataHeader) + config.behavior_size + | ||
| 78 | config.memory_pools_size + config.voice_resource_size, | ||
| 79 | worker_params.voice_count * sizeof(VoiceInfo)); | ||
| 80 | |||
| 81 | UpdateDataHeader response_data{worker_params}; | ||
| 82 | |||
| 83 | ASSERT(ctx.GetWriteBufferSize() == response_data.total_size); | ||
| 84 | |||
| 85 | std::vector<u8> output(response_data.total_size); | ||
| 86 | std::memcpy(output.data(), &response_data, sizeof(UpdateDataHeader)); | ||
| 87 | std::vector<MemoryPoolEntry> memory_pool(memory_pool_count); | ||
| 88 | for (unsigned i = 0; i < memory_pool.size(); i++) { | ||
| 89 | if (mem_pool_info[i].pool_state == MemoryPoolStates::RequestAttach) | ||
| 90 | memory_pool[i].state = MemoryPoolStates::Attached; | ||
| 91 | else if (mem_pool_info[i].pool_state == MemoryPoolStates::RequestDetach) | ||
| 92 | memory_pool[i].state = MemoryPoolStates::Detached; | ||
| 93 | } | ||
| 94 | std::memcpy(output.data() + sizeof(UpdateDataHeader), memory_pool.data(), | ||
| 95 | response_data.memory_pools_size); | ||
| 96 | |||
| 97 | for (unsigned i = 0; i < voice_info.size(); i++) { | ||
| 98 | if (voice_info[i].is_new) { | ||
| 99 | voice_status_list[i].played_sample_count = 0; | ||
| 100 | voice_status_list[i].wave_buffer_consumed = 0; | ||
| 101 | } else if (voice_info[i].play_state == (u8)PlayStates::Started) { | ||
| 102 | for (u32 buff_idx = 0; buff_idx < voice_info[i].wave_buffer_count; buff_idx++) { | ||
| 103 | voice_status_list[i].played_sample_count += | ||
| 104 | (voice_info[i].wave_buffer[buff_idx].end_sample_offset - | ||
| 105 | voice_info[i].wave_buffer[buff_idx].start_sample_offset) / | ||
| 106 | 2; | ||
| 107 | voice_status_list[i].wave_buffer_consumed++; | ||
| 108 | } | ||
| 109 | } | ||
| 110 | } | ||
| 111 | std::memcpy(output.data() + sizeof(UpdateDataHeader) + response_data.memory_pools_size, | ||
| 112 | voice_status_list.data(), response_data.voices_size); | ||
| 113 | |||
| 114 | ctx.WriteBuffer(output); | ||
| 115 | |||
| 116 | IPC::ResponseBuilder rb{ctx, 2}; | 50 | IPC::ResponseBuilder rb{ctx, 2}; |
| 117 | rb.Push(RESULT_SUCCESS); | 51 | rb.Push(RESULT_SUCCESS); |
| 118 | |||
| 119 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 52 | LOG_WARNING(Service_Audio, "(STUBBED) called"); |
| 120 | } | 53 | } |
| 121 | 54 | ||
| @@ -136,8 +69,6 @@ private: | |||
| 136 | } | 69 | } |
| 137 | 70 | ||
| 138 | void QuerySystemEvent(Kernel::HLERequestContext& ctx) { | 71 | void QuerySystemEvent(Kernel::HLERequestContext& ctx) { |
| 139 | // system_event->Signal(); | ||
| 140 | |||
| 141 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 72 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 142 | rb.Push(RESULT_SUCCESS); | 73 | rb.Push(RESULT_SUCCESS); |
| 143 | rb.PushCopyObjects(system_event); | 74 | rb.PushCopyObjects(system_event); |
| @@ -145,131 +76,8 @@ private: | |||
| 145 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 76 | LOG_WARNING(Service_Audio, "(STUBBED) called"); |
| 146 | } | 77 | } |
| 147 | 78 | ||
| 148 | enum class MemoryPoolStates : u32 { // Should be LE | ||
| 149 | Invalid = 0x0, | ||
| 150 | Unknown = 0x1, | ||
| 151 | RequestDetach = 0x2, | ||
| 152 | Detached = 0x3, | ||
| 153 | RequestAttach = 0x4, | ||
| 154 | Attached = 0x5, | ||
| 155 | Released = 0x6, | ||
| 156 | }; | ||
| 157 | |||
| 158 | enum class PlayStates : u8 { | ||
| 159 | Started = 0, | ||
| 160 | Stopped = 1, | ||
| 161 | }; | ||
| 162 | |||
| 163 | struct MemoryPoolEntry { | ||
| 164 | MemoryPoolStates state; | ||
| 165 | u32_le unknown_4; | ||
| 166 | u32_le unknown_8; | ||
| 167 | u32_le unknown_c; | ||
| 168 | }; | ||
| 169 | static_assert(sizeof(MemoryPoolEntry) == 0x10, "MemoryPoolEntry has wrong size"); | ||
| 170 | |||
| 171 | struct MemoryPoolInfo { | ||
| 172 | u64_le pool_address; | ||
| 173 | u64_le pool_size; | ||
| 174 | MemoryPoolStates pool_state; | ||
| 175 | INSERT_PADDING_WORDS(3); // Unknown | ||
| 176 | }; | ||
| 177 | static_assert(sizeof(MemoryPoolInfo) == 0x20, "MemoryPoolInfo has wrong size"); | ||
| 178 | |||
| 179 | struct UpdateDataHeader { | ||
| 180 | UpdateDataHeader() {} | ||
| 181 | |||
| 182 | explicit UpdateDataHeader(const AudioRendererParameter& config) { | ||
| 183 | revision = Common::MakeMagic('R', 'E', 'V', '4'); // 5.1.0 Revision | ||
| 184 | behavior_size = 0xb0; | ||
| 185 | memory_pools_size = (config.effect_count + (config.voice_count * 4)) * 0x10; | ||
| 186 | voices_size = config.voice_count * 0x10; | ||
| 187 | voice_resource_size = 0x0; | ||
| 188 | effects_size = config.effect_count * 0x10; | ||
| 189 | mixes_size = 0x0; | ||
| 190 | sinks_size = config.sink_count * 0x20; | ||
| 191 | performance_manager_size = 0x10; | ||
| 192 | total_size = sizeof(UpdateDataHeader) + behavior_size + memory_pools_size + | ||
| 193 | voices_size + effects_size + sinks_size + performance_manager_size; | ||
| 194 | } | ||
| 195 | |||
| 196 | u32_le revision; | ||
| 197 | u32_le behavior_size; | ||
| 198 | u32_le memory_pools_size; | ||
| 199 | u32_le voices_size; | ||
| 200 | u32_le voice_resource_size; | ||
| 201 | u32_le effects_size; | ||
| 202 | u32_le mixes_size; | ||
| 203 | u32_le sinks_size; | ||
| 204 | u32_le performance_manager_size; | ||
| 205 | INSERT_PADDING_WORDS(6); | ||
| 206 | u32_le total_size; | ||
| 207 | }; | ||
| 208 | static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size"); | ||
| 209 | |||
| 210 | struct BiquadFilter { | ||
| 211 | u8 enable; | ||
| 212 | INSERT_PADDING_BYTES(1); | ||
| 213 | s16_le numerator[3]; | ||
| 214 | s16_le denominator[2]; | ||
| 215 | }; | ||
| 216 | static_assert(sizeof(BiquadFilter) == 0xc, "BiquadFilter has wrong size"); | ||
| 217 | |||
| 218 | struct WaveBuffer { | ||
| 219 | u64_le buffer_addr; | ||
| 220 | u64_le buffer_sz; | ||
| 221 | s32_le start_sample_offset; | ||
| 222 | s32_le end_sample_offset; | ||
| 223 | u8 loop; | ||
| 224 | u8 end_of_stream; | ||
| 225 | u8 sent_to_server; | ||
| 226 | INSERT_PADDING_BYTES(5); | ||
| 227 | u64 context_addr; | ||
| 228 | u64 context_sz; | ||
| 229 | INSERT_PADDING_BYTES(8); | ||
| 230 | }; | ||
| 231 | static_assert(sizeof(WaveBuffer) == 0x38, "WaveBuffer has wrong size"); | ||
| 232 | |||
| 233 | struct VoiceInfo { | ||
| 234 | u32_le id; | ||
| 235 | u32_le node_id; | ||
| 236 | u8 is_new; | ||
| 237 | u8 is_in_use; | ||
| 238 | u8 play_state; | ||
| 239 | u8 sample_format; | ||
| 240 | u32_le sample_rate; | ||
| 241 | u32_le priority; | ||
| 242 | u32_le sorting_order; | ||
| 243 | u32_le channel_count; | ||
| 244 | float_le pitch; | ||
| 245 | float_le volume; | ||
| 246 | BiquadFilter biquad_filter[2]; | ||
| 247 | u32_le wave_buffer_count; | ||
| 248 | u16_le wave_buffer_head; | ||
| 249 | INSERT_PADDING_BYTES(6); | ||
| 250 | u64_le additional_params_addr; | ||
| 251 | u64_le additional_params_sz; | ||
| 252 | u32_le mix_id; | ||
| 253 | u32_le splitter_info_id; | ||
| 254 | WaveBuffer wave_buffer[4]; | ||
| 255 | u32_le voice_channel_resource_ids[6]; | ||
| 256 | INSERT_PADDING_BYTES(24); | ||
| 257 | }; | ||
| 258 | static_assert(sizeof(VoiceInfo) == 0x170, "VoiceInfo is wrong size"); | ||
| 259 | |||
| 260 | struct VoiceOutStatus { | ||
| 261 | u64_le played_sample_count; | ||
| 262 | u32_le wave_buffer_consumed; | ||
| 263 | INSERT_PADDING_WORDS(1); | ||
| 264 | }; | ||
| 265 | static_assert(sizeof(VoiceOutStatus) == 0x10, "VoiceOutStatus has wrong size"); | ||
| 266 | |||
| 267 | /// This is used to trigger the audio event callback. | ||
| 268 | CoreTiming::EventType* audio_event; | ||
| 269 | |||
| 270 | Kernel::SharedPtr<Kernel::Event> system_event; | 79 | Kernel::SharedPtr<Kernel::Event> system_event; |
| 271 | AudioRendererParameter worker_params; | 80 | std::unique_ptr<AudioCore::AudioRenderer> renderer; |
| 272 | std::vector<VoiceOutStatus> voice_status_list; | ||
| 273 | }; | 81 | }; |
| 274 | 82 | ||
| 275 | class IAudioDevice final : public ServiceFramework<IAudioDevice> { | 83 | class IAudioDevice final : public ServiceFramework<IAudioDevice> { |
| @@ -368,7 +176,7 @@ AudRenU::AudRenU() : ServiceFramework("audren:u") { | |||
| 368 | 176 | ||
| 369 | void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) { | 177 | void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) { |
| 370 | IPC::RequestParser rp{ctx}; | 178 | IPC::RequestParser rp{ctx}; |
| 371 | auto params = rp.PopRaw<AudioRendererParameter>(); | 179 | auto params = rp.PopRaw<AudioCore::AudioRendererParameter>(); |
| 372 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 180 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 373 | 181 | ||
| 374 | rb.Push(RESULT_SUCCESS); | 182 | rb.Push(RESULT_SUCCESS); |
| @@ -379,7 +187,7 @@ void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) { | |||
| 379 | 187 | ||
| 380 | void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) { | 188 | void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) { |
| 381 | IPC::RequestParser rp{ctx}; | 189 | IPC::RequestParser rp{ctx}; |
| 382 | auto params = rp.PopRaw<AudioRendererParameter>(); | 190 | auto params = rp.PopRaw<AudioCore::AudioRendererParameter>(); |
| 383 | 191 | ||
| 384 | u64 buffer_sz = Common::AlignUp(4 * params.unknown_8, 0x40); | 192 | u64 buffer_sz = Common::AlignUp(4 * params.unknown_8, 0x40); |
| 385 | buffer_sz += params.unknown_c * 1024; | 193 | buffer_sz += params.unknown_c * 1024; |
diff --git a/src/core/hle/service/audio/audren_u.h b/src/core/hle/service/audio/audren_u.h index b9b81db4f..14907f8ae 100644 --- a/src/core/hle/service/audio/audren_u.h +++ b/src/core/hle/service/audio/audren_u.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include "audio_core/audio_renderer.h" | ||
| 7 | #include "core/hle/service/service.h" | 8 | #include "core/hle/service/service.h" |
| 8 | 9 | ||
| 9 | namespace Kernel { | 10 | namespace Kernel { |
| @@ -12,24 +13,6 @@ class HLERequestContext; | |||
| 12 | 13 | ||
| 13 | namespace Service::Audio { | 14 | namespace Service::Audio { |
| 14 | 15 | ||
| 15 | struct AudioRendererParameter { | ||
| 16 | u32_le sample_rate; | ||
| 17 | u32_le sample_count; | ||
| 18 | u32_le unknown_8; | ||
| 19 | u32_le unknown_c; | ||
| 20 | u32_le voice_count; | ||
| 21 | u32_le sink_count; | ||
| 22 | u32_le effect_count; | ||
| 23 | u32_le unknown_1c; | ||
| 24 | u8 unknown_20; | ||
| 25 | INSERT_PADDING_BYTES(3); | ||
| 26 | u32_le splitter_count; | ||
| 27 | u32_le unknown_2c; | ||
| 28 | INSERT_PADDING_WORDS(1); | ||
| 29 | u32_le revision; | ||
| 30 | }; | ||
| 31 | static_assert(sizeof(AudioRendererParameter) == 52, "AudioRendererParameter is an invalid size"); | ||
| 32 | |||
| 33 | class AudRenU final : public ServiceFramework<AudRenU> { | 16 | class AudRenU final : public ServiceFramework<AudRenU> { |
| 34 | public: | 17 | public: |
| 35 | explicit AudRenU(); | 18 | explicit AudRenU(); |
diff --git a/src/core/hle/service/audio/hwopus.cpp b/src/core/hle/service/audio/hwopus.cpp index 844df382c..371cd4997 100644 --- a/src/core/hle/service/audio/hwopus.cpp +++ b/src/core/hle/service/audio/hwopus.cpp | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <cstring> | ||
| 6 | #include <opus.h> | ||
| 5 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 6 | #include "core/hle/ipc_helpers.h" | 8 | #include "core/hle/ipc_helpers.h" |
| 7 | #include "core/hle/kernel/hle_ipc.h" | 9 | #include "core/hle/kernel/hle_ipc.h" |
| @@ -9,19 +11,142 @@ | |||
| 9 | 11 | ||
| 10 | namespace Service::Audio { | 12 | namespace Service::Audio { |
| 11 | 13 | ||
| 14 | struct OpusDeleter { | ||
| 15 | void operator()(void* ptr) const { | ||
| 16 | operator delete(ptr); | ||
| 17 | } | ||
| 18 | }; | ||
| 19 | |||
| 20 | class IHardwareOpusDecoderManager final : public ServiceFramework<IHardwareOpusDecoderManager> { | ||
| 21 | public: | ||
| 22 | IHardwareOpusDecoderManager(std::unique_ptr<OpusDecoder, OpusDeleter> decoder, u32 sample_rate, | ||
| 23 | u32 channel_count) | ||
| 24 | : ServiceFramework("IHardwareOpusDecoderManager"), decoder(std::move(decoder)), | ||
| 25 | sample_rate(sample_rate), channel_count(channel_count) { | ||
| 26 | static const FunctionInfo functions[] = { | ||
| 27 | {0, &IHardwareOpusDecoderManager::DecodeInterleaved, "DecodeInterleaved"}, | ||
| 28 | {1, nullptr, "SetContext"}, | ||
| 29 | {2, nullptr, "DecodeInterleavedForMultiStream"}, | ||
| 30 | {3, nullptr, "SetContextForMultiStream"}, | ||
| 31 | {4, nullptr, "Unknown4"}, | ||
| 32 | {5, nullptr, "Unknown5"}, | ||
| 33 | {6, nullptr, "Unknown6"}, | ||
| 34 | {7, nullptr, "Unknown7"}, | ||
| 35 | }; | ||
| 36 | RegisterHandlers(functions); | ||
| 37 | } | ||
| 38 | |||
| 39 | private: | ||
| 40 | void DecodeInterleaved(Kernel::HLERequestContext& ctx) { | ||
| 41 | u32 consumed = 0; | ||
| 42 | u32 sample_count = 0; | ||
| 43 | std::vector<opus_int16> samples(ctx.GetWriteBufferSize() / sizeof(opus_int16)); | ||
| 44 | if (!Decoder_DecodeInterleaved(consumed, sample_count, ctx.ReadBuffer(), samples)) { | ||
| 45 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 46 | // TODO(ogniK): Use correct error code | ||
| 47 | rb.Push(ResultCode(-1)); | ||
| 48 | return; | ||
| 49 | } | ||
| 50 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 51 | rb.Push(RESULT_SUCCESS); | ||
| 52 | rb.Push<u32>(consumed); | ||
| 53 | rb.Push<u32>(sample_count); | ||
| 54 | ctx.WriteBuffer(samples.data(), samples.size() * sizeof(s16)); | ||
| 55 | } | ||
| 56 | |||
| 57 | bool Decoder_DecodeInterleaved(u32& consumed, u32& sample_count, const std::vector<u8>& input, | ||
| 58 | std::vector<opus_int16>& output) { | ||
| 59 | size_t raw_output_sz = output.size() * sizeof(opus_int16); | ||
| 60 | if (sizeof(OpusHeader) > input.size()) | ||
| 61 | return false; | ||
| 62 | OpusHeader hdr{}; | ||
| 63 | std::memcpy(&hdr, input.data(), sizeof(OpusHeader)); | ||
| 64 | if (sizeof(OpusHeader) + static_cast<u32>(hdr.sz) > input.size()) { | ||
| 65 | return false; | ||
| 66 | } | ||
| 67 | auto frame = input.data() + sizeof(OpusHeader); | ||
| 68 | auto decoded_sample_count = opus_packet_get_nb_samples( | ||
| 69 | frame, static_cast<opus_int32>(input.size() - sizeof(OpusHeader)), | ||
| 70 | static_cast<opus_int32>(sample_rate)); | ||
| 71 | if (decoded_sample_count * channel_count * sizeof(u16) > raw_output_sz) | ||
| 72 | return false; | ||
| 73 | auto out_sample_count = | ||
| 74 | opus_decode(decoder.get(), frame, hdr.sz, output.data(), | ||
| 75 | (static_cast<int>(raw_output_sz / sizeof(s16) / channel_count)), 0); | ||
| 76 | if (out_sample_count < 0) | ||
| 77 | return false; | ||
| 78 | sample_count = out_sample_count; | ||
| 79 | consumed = static_cast<u32>(sizeof(OpusHeader) + hdr.sz); | ||
| 80 | return true; | ||
| 81 | } | ||
| 82 | |||
| 83 | struct OpusHeader { | ||
| 84 | u32_be sz; // Needs to be BE for some odd reason | ||
| 85 | INSERT_PADDING_WORDS(1); | ||
| 86 | }; | ||
| 87 | static_assert(sizeof(OpusHeader) == 0x8, "OpusHeader is an invalid size"); | ||
| 88 | |||
| 89 | std::unique_ptr<OpusDecoder, OpusDeleter> decoder; | ||
| 90 | u32 sample_rate; | ||
| 91 | u32 channel_count; | ||
| 92 | }; | ||
| 93 | |||
| 94 | static size_t WorkerBufferSize(u32 channel_count) { | ||
| 95 | ASSERT_MSG(channel_count == 1 || channel_count == 2, "Invalid channel count"); | ||
| 96 | return opus_decoder_get_size(static_cast<int>(channel_count)); | ||
| 97 | } | ||
| 98 | |||
| 12 | void HwOpus::GetWorkBufferSize(Kernel::HLERequestContext& ctx) { | 99 | void HwOpus::GetWorkBufferSize(Kernel::HLERequestContext& ctx) { |
| 13 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 100 | IPC::RequestParser rp{ctx}; |
| 101 | auto sample_rate = rp.Pop<u32>(); | ||
| 102 | auto channel_count = rp.Pop<u32>(); | ||
| 103 | ASSERT_MSG(sample_rate == 48000 || sample_rate == 24000 || sample_rate == 16000 || | ||
| 104 | sample_rate == 12000 || sample_rate == 8000, | ||
| 105 | "Invalid sample rate"); | ||
| 106 | ASSERT_MSG(channel_count == 1 || channel_count == 2, "Invalid channel count"); | ||
| 107 | u32 worker_buffer_sz = static_cast<u32>(WorkerBufferSize(channel_count)); | ||
| 108 | LOG_DEBUG(Audio, "called worker_buffer_sz={}", worker_buffer_sz); | ||
| 109 | |||
| 14 | IPC::ResponseBuilder rb{ctx, 3}; | 110 | IPC::ResponseBuilder rb{ctx, 3}; |
| 15 | rb.Push(RESULT_SUCCESS); | 111 | rb.Push(RESULT_SUCCESS); |
| 16 | rb.Push<u32>(0x4000); | 112 | rb.Push<u32>(worker_buffer_sz); |
| 113 | } | ||
| 114 | |||
| 115 | void HwOpus::OpenOpusDecoder(Kernel::HLERequestContext& ctx) { | ||
| 116 | IPC::RequestParser rp{ctx}; | ||
| 117 | auto sample_rate = rp.Pop<u32>(); | ||
| 118 | auto channel_count = rp.Pop<u32>(); | ||
| 119 | auto buffer_sz = rp.Pop<u32>(); | ||
| 120 | LOG_DEBUG(Audio, "called sample_rate={}, channel_count={}, buffer_size={}", sample_rate, | ||
| 121 | channel_count, buffer_sz); | ||
| 122 | ASSERT_MSG(sample_rate == 48000 || sample_rate == 24000 || sample_rate == 16000 || | ||
| 123 | sample_rate == 12000 || sample_rate == 8000, | ||
| 124 | "Invalid sample rate"); | ||
| 125 | ASSERT_MSG(channel_count == 1 || channel_count == 2, "Invalid channel count"); | ||
| 126 | |||
| 127 | size_t worker_sz = WorkerBufferSize(channel_count); | ||
| 128 | ASSERT_MSG(buffer_sz < worker_sz, "Worker buffer too large"); | ||
| 129 | std::unique_ptr<OpusDecoder, OpusDeleter> decoder{ | ||
| 130 | static_cast<OpusDecoder*>(operator new(worker_sz))}; | ||
| 131 | if (opus_decoder_init(decoder.get(), sample_rate, channel_count)) { | ||
| 132 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 133 | // TODO(ogniK): Use correct error code | ||
| 134 | rb.Push(ResultCode(-1)); | ||
| 135 | return; | ||
| 136 | } | ||
| 137 | |||
| 138 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 139 | rb.Push(RESULT_SUCCESS); | ||
| 140 | rb.PushIpcInterface<IHardwareOpusDecoderManager>(std::move(decoder), sample_rate, | ||
| 141 | channel_count); | ||
| 17 | } | 142 | } |
| 18 | 143 | ||
| 19 | HwOpus::HwOpus() : ServiceFramework("hwopus") { | 144 | HwOpus::HwOpus() : ServiceFramework("hwopus") { |
| 20 | static const FunctionInfo functions[] = { | 145 | static const FunctionInfo functions[] = { |
| 21 | {0, nullptr, "Initialize"}, | 146 | {0, &HwOpus::OpenOpusDecoder, "OpenOpusDecoder"}, |
| 22 | {1, &HwOpus::GetWorkBufferSize, "GetWorkBufferSize"}, | 147 | {1, &HwOpus::GetWorkBufferSize, "GetWorkBufferSize"}, |
| 23 | {2, nullptr, "InitializeMultiStream"}, | 148 | {2, nullptr, "OpenOpusDecoderForMultiStream"}, |
| 24 | {3, nullptr, "GetWorkBufferSizeMultiStream"}, | 149 | {3, nullptr, "GetWorkBufferSizeForMultiStream"}, |
| 25 | }; | 150 | }; |
| 26 | RegisterHandlers(functions); | 151 | RegisterHandlers(functions); |
| 27 | } | 152 | } |
diff --git a/src/core/hle/service/audio/hwopus.h b/src/core/hle/service/audio/hwopus.h index 090b8c825..5258d59f3 100644 --- a/src/core/hle/service/audio/hwopus.h +++ b/src/core/hle/service/audio/hwopus.h | |||
| @@ -14,6 +14,7 @@ public: | |||
| 14 | ~HwOpus() = default; | 14 | ~HwOpus() = default; |
| 15 | 15 | ||
| 16 | private: | 16 | private: |
| 17 | void OpenOpusDecoder(Kernel::HLERequestContext& ctx); | ||
| 17 | void GetWorkBufferSize(Kernel::HLERequestContext& ctx); | 18 | void GetWorkBufferSize(Kernel::HLERequestContext& ctx); |
| 18 | }; | 19 | }; |
| 19 | 20 | ||
diff --git a/src/core/hle/service/bpc/bpc.cpp b/src/core/hle/service/bpc/bpc.cpp new file mode 100644 index 000000000..1c1ecdb60 --- /dev/null +++ b/src/core/hle/service/bpc/bpc.cpp | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <memory> | ||
| 6 | |||
| 7 | #include "core/hle/service/bpc/bpc.h" | ||
| 8 | #include "core/hle/service/service.h" | ||
| 9 | #include "core/hle/service/sm/sm.h" | ||
| 10 | |||
| 11 | namespace Service::BPC { | ||
| 12 | |||
| 13 | class BPC final : public ServiceFramework<BPC> { | ||
| 14 | public: | ||
| 15 | explicit BPC() : ServiceFramework{"bpc"} { | ||
| 16 | // clang-format off | ||
| 17 | static const FunctionInfo functions[] = { | ||
| 18 | {0, nullptr, "ShutdownSystem"}, | ||
| 19 | {1, nullptr, "RebootSystem"}, | ||
| 20 | {2, nullptr, "GetWakeupReason"}, | ||
| 21 | {3, nullptr, "GetShutdownReason"}, | ||
| 22 | {4, nullptr, "GetAcOk"}, | ||
| 23 | {5, nullptr, "GetBoardPowerControlEvent"}, | ||
| 24 | {6, nullptr, "GetSleepButtonState"}, | ||
| 25 | {7, nullptr, "GetPowerEvent"}, | ||
| 26 | {8, nullptr, "Unknown1"}, | ||
| 27 | {9, nullptr, "Unknown2"}, | ||
| 28 | {10, nullptr, "Unknown3"}, | ||
| 29 | }; | ||
| 30 | // clang-format on | ||
| 31 | |||
| 32 | RegisterHandlers(functions); | ||
| 33 | } | ||
| 34 | }; | ||
| 35 | |||
| 36 | class BPC_R final : public ServiceFramework<BPC_R> { | ||
| 37 | public: | ||
| 38 | explicit BPC_R() : ServiceFramework{"bpc:r"} { | ||
| 39 | // clang-format off | ||
| 40 | static const FunctionInfo functions[] = { | ||
| 41 | {0, nullptr, "GetExternalRtcValue"}, | ||
| 42 | {1, nullptr, "SetExternalRtcValue"}, | ||
| 43 | {2, nullptr, "ReadExternalRtcResetFlag"}, | ||
| 44 | {3, nullptr, "ClearExternalRtcResetFlag"}, | ||
| 45 | }; | ||
| 46 | // clang-format on | ||
| 47 | |||
| 48 | RegisterHandlers(functions); | ||
| 49 | } | ||
| 50 | }; | ||
| 51 | |||
| 52 | void InstallInterfaces(SM::ServiceManager& sm) { | ||
| 53 | std::make_shared<BPC>()->InstallAsService(sm); | ||
| 54 | std::make_shared<BPC_R>()->InstallAsService(sm); | ||
| 55 | } | ||
| 56 | |||
| 57 | } // namespace Service::BPC | ||
diff --git a/src/core/hle/service/bpc/bpc.h b/src/core/hle/service/bpc/bpc.h new file mode 100644 index 000000000..eaa37be8d --- /dev/null +++ b/src/core/hle/service/bpc/bpc.h | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | namespace Service::SM { | ||
| 8 | class ServiceManager; | ||
| 9 | } | ||
| 10 | |||
| 11 | namespace Service::BPC { | ||
| 12 | |||
| 13 | void InstallInterfaces(SM::ServiceManager& sm); | ||
| 14 | |||
| 15 | } // namespace Service::BPC | ||
diff --git a/src/core/hle/service/btdrv/btdrv.cpp b/src/core/hle/service/btdrv/btdrv.cpp new file mode 100644 index 000000000..d0a15cc4c --- /dev/null +++ b/src/core/hle/service/btdrv/btdrv.cpp | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/hle/service/btdrv/btdrv.h" | ||
| 6 | #include "core/hle/service/service.h" | ||
| 7 | #include "core/hle/service/sm/sm.h" | ||
| 8 | |||
| 9 | namespace Service::BtDrv { | ||
| 10 | |||
| 11 | class BtDrv final : public ServiceFramework<BtDrv> { | ||
| 12 | public: | ||
| 13 | explicit BtDrv() : ServiceFramework{"btdrv"} { | ||
| 14 | // clang-format off | ||
| 15 | static const FunctionInfo functions[] = { | ||
| 16 | {0, nullptr, "Unknown"}, | ||
| 17 | {1, nullptr, "Init"}, | ||
| 18 | {2, nullptr, "Enable"}, | ||
| 19 | {3, nullptr, "Disable"}, | ||
| 20 | {4, nullptr, "CleanupAndShutdown"}, | ||
| 21 | {5, nullptr, "GetAdapterProperties"}, | ||
| 22 | {6, nullptr, "GetAdapterProperty"}, | ||
| 23 | {7, nullptr, "SetAdapterProperty"}, | ||
| 24 | {8, nullptr, "StartDiscovery"}, | ||
| 25 | {9, nullptr, "CancelDiscovery"}, | ||
| 26 | {10, nullptr, "CreateBond"}, | ||
| 27 | {11, nullptr, "RemoveBond"}, | ||
| 28 | {12, nullptr, "CancelBond"}, | ||
| 29 | {13, nullptr, "PinReply"}, | ||
| 30 | {14, nullptr, "SspReply"}, | ||
| 31 | {15, nullptr, "Unknown2"}, | ||
| 32 | {16, nullptr, "InitInterfaces"}, | ||
| 33 | {17, nullptr, "HidHostInterface_Connect"}, | ||
| 34 | {18, nullptr, "HidHostInterface_Disconnect"}, | ||
| 35 | {19, nullptr, "HidHostInterface_SendData"}, | ||
| 36 | {20, nullptr, "HidHostInterface_SendData2"}, | ||
| 37 | {21, nullptr, "HidHostInterface_SetReport"}, | ||
| 38 | {22, nullptr, "HidHostInterface_GetReport"}, | ||
| 39 | {23, nullptr, "HidHostInterface_WakeController"}, | ||
| 40 | {24, nullptr, "HidHostInterface_AddPairedDevice"}, | ||
| 41 | {25, nullptr, "HidHostInterface_GetPairedDevice"}, | ||
| 42 | {26, nullptr, "HidHostInterface_CleanupAndShutdown"}, | ||
| 43 | {27, nullptr, "Unknown3"}, | ||
| 44 | {28, nullptr, "ExtInterface_SetTSI"}, | ||
| 45 | {29, nullptr, "ExtInterface_SetBurstMode"}, | ||
| 46 | {30, nullptr, "ExtInterface_SetZeroRetran"}, | ||
| 47 | {31, nullptr, "ExtInterface_SetMcMode"}, | ||
| 48 | {32, nullptr, "ExtInterface_StartLlrMode"}, | ||
| 49 | {33, nullptr, "ExtInterface_ExitLlrMode"}, | ||
| 50 | {34, nullptr, "ExtInterface_SetRadio"}, | ||
| 51 | {35, nullptr, "ExtInterface_SetVisibility"}, | ||
| 52 | {36, nullptr, "Unknown4"}, | ||
| 53 | {37, nullptr, "Unknown5"}, | ||
| 54 | {38, nullptr, "HidHostInterface_GetLatestPlr"}, | ||
| 55 | {39, nullptr, "ExtInterface_GetPendingConnections"}, | ||
| 56 | {40, nullptr, "HidHostInterface_GetChannelMap"}, | ||
| 57 | {41, nullptr, "SetIsBluetoothBoostEnabled"}, | ||
| 58 | {42, nullptr, "GetIsBluetoothBoostEnabled"}, | ||
| 59 | {43, nullptr, "SetIsBluetoothAfhEnabled"}, | ||
| 60 | {44, nullptr, "GetIsBluetoothAfhEnabled"}, | ||
| 61 | }; | ||
| 62 | // clang-format on | ||
| 63 | |||
| 64 | RegisterHandlers(functions); | ||
| 65 | } | ||
| 66 | }; | ||
| 67 | |||
| 68 | void InstallInterfaces(SM::ServiceManager& sm) { | ||
| 69 | std::make_shared<BtDrv>()->InstallAsService(sm); | ||
| 70 | } | ||
| 71 | |||
| 72 | } // namespace Service::BtDrv | ||
diff --git a/src/core/hle/service/btdrv/btdrv.h b/src/core/hle/service/btdrv/btdrv.h new file mode 100644 index 000000000..164e56f43 --- /dev/null +++ b/src/core/hle/service/btdrv/btdrv.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | namespace Service::SM { | ||
| 8 | class ServiceManager; | ||
| 9 | } | ||
| 10 | |||
| 11 | namespace Service::BtDrv { | ||
| 12 | |||
| 13 | /// Registers all BtDrv services with the specified service manager. | ||
| 14 | void InstallInterfaces(SM::ServiceManager& sm); | ||
| 15 | |||
| 16 | } // namespace Service::BtDrv | ||
diff --git a/src/core/hle/service/btm/btm.cpp b/src/core/hle/service/btm/btm.cpp new file mode 100644 index 000000000..b949bfabd --- /dev/null +++ b/src/core/hle/service/btm/btm.cpp | |||
| @@ -0,0 +1,121 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <memory> | ||
| 6 | |||
| 7 | #include "common/logging/log.h" | ||
| 8 | #include "core/hle/ipc_helpers.h" | ||
| 9 | #include "core/hle/kernel/hle_ipc.h" | ||
| 10 | #include "core/hle/service/btm/btm.h" | ||
| 11 | #include "core/hle/service/service.h" | ||
| 12 | #include "core/hle/service/sm/sm.h" | ||
| 13 | |||
| 14 | namespace Service::BTM { | ||
| 15 | |||
| 16 | class BTM final : public ServiceFramework<BTM> { | ||
| 17 | public: | ||
| 18 | explicit BTM() : ServiceFramework{"btm"} { | ||
| 19 | // clang-format off | ||
| 20 | static const FunctionInfo functions[] = { | ||
| 21 | {0, nullptr, "Unknown1"}, | ||
| 22 | {1, nullptr, "Unknown2"}, | ||
| 23 | {2, nullptr, "RegisterSystemEventForConnectedDeviceConditionImpl"}, | ||
| 24 | {3, nullptr, "Unknown3"}, | ||
| 25 | {4, nullptr, "Unknown4"}, | ||
| 26 | {5, nullptr, "Unknown5"}, | ||
| 27 | {6, nullptr, "Unknown6"}, | ||
| 28 | {7, nullptr, "Unknown7"}, | ||
| 29 | {8, nullptr, "RegisterSystemEventForRegisteredDeviceInfoImpl"}, | ||
| 30 | {9, nullptr, "Unknown8"}, | ||
| 31 | {10, nullptr, "Unknown9"}, | ||
| 32 | {11, nullptr, "Unknown10"}, | ||
| 33 | {12, nullptr, "Unknown11"}, | ||
| 34 | {13, nullptr, "Unknown12"}, | ||
| 35 | {14, nullptr, "EnableRadioImpl"}, | ||
| 36 | {15, nullptr, "DisableRadioImpl"}, | ||
| 37 | {16, nullptr, "Unknown13"}, | ||
| 38 | {17, nullptr, "Unknown14"}, | ||
| 39 | {18, nullptr, "Unknown15"}, | ||
| 40 | {19, nullptr, "Unknown16"}, | ||
| 41 | {20, nullptr, "Unknown17"}, | ||
| 42 | {21, nullptr, "Unknown18"}, | ||
| 43 | }; | ||
| 44 | // clang-format on | ||
| 45 | |||
| 46 | RegisterHandlers(functions); | ||
| 47 | } | ||
| 48 | }; | ||
| 49 | |||
| 50 | class BTM_DBG final : public ServiceFramework<BTM_DBG> { | ||
| 51 | public: | ||
| 52 | explicit BTM_DBG() : ServiceFramework{"btm:dbg"} { | ||
| 53 | // clang-format off | ||
| 54 | static const FunctionInfo functions[] = { | ||
| 55 | {0, nullptr, "RegisterSystemEventForDiscoveryImpl"}, | ||
| 56 | {1, nullptr, "Unknown1"}, | ||
| 57 | {2, nullptr, "Unknown2"}, | ||
| 58 | {3, nullptr, "Unknown3"}, | ||
| 59 | {4, nullptr, "Unknown4"}, | ||
| 60 | {5, nullptr, "Unknown5"}, | ||
| 61 | {6, nullptr, "Unknown6"}, | ||
| 62 | {7, nullptr, "Unknown7"}, | ||
| 63 | {8, nullptr, "Unknown8"}, | ||
| 64 | }; | ||
| 65 | // clang-format on | ||
| 66 | |||
| 67 | RegisterHandlers(functions); | ||
| 68 | } | ||
| 69 | }; | ||
| 70 | |||
| 71 | class IBtmSystemCore final : public ServiceFramework<IBtmSystemCore> { | ||
| 72 | public: | ||
| 73 | explicit IBtmSystemCore() : ServiceFramework{"IBtmSystemCore"} { | ||
| 74 | // clang-format off | ||
| 75 | static const FunctionInfo functions[] = { | ||
| 76 | {0, nullptr, "StartGamepadPairingImpl"}, | ||
| 77 | {1, nullptr, "CancelGamepadPairingImpl"}, | ||
| 78 | {2, nullptr, "ClearGamepadPairingDatabaseImpl"}, | ||
| 79 | {3, nullptr, "GetPairedGamepadCountImpl"}, | ||
| 80 | {4, nullptr, "EnableRadioImpl"}, | ||
| 81 | {5, nullptr, "DisableRadioImpl"}, | ||
| 82 | {6, nullptr, "GetRadioOnOffImpl"}, | ||
| 83 | {7, nullptr, "AcquireRadioEventImpl"}, | ||
| 84 | {8, nullptr, "AcquireGamepadPairingEventImpl"}, | ||
| 85 | {9, nullptr, "IsGamepadPairingStartedImpl"}, | ||
| 86 | }; | ||
| 87 | // clang-format on | ||
| 88 | |||
| 89 | RegisterHandlers(functions); | ||
| 90 | } | ||
| 91 | }; | ||
| 92 | |||
| 93 | class BTM_SYS final : public ServiceFramework<BTM_SYS> { | ||
| 94 | public: | ||
| 95 | explicit BTM_SYS() : ServiceFramework{"btm:sys"} { | ||
| 96 | // clang-format off | ||
| 97 | static const FunctionInfo functions[] = { | ||
| 98 | {0, &BTM_SYS::GetCoreImpl, "GetCoreImpl"}, | ||
| 99 | }; | ||
| 100 | // clang-format on | ||
| 101 | |||
| 102 | RegisterHandlers(functions); | ||
| 103 | } | ||
| 104 | |||
| 105 | private: | ||
| 106 | void GetCoreImpl(Kernel::HLERequestContext& ctx) { | ||
| 107 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 108 | rb.Push(RESULT_SUCCESS); | ||
| 109 | rb.PushIpcInterface<IBtmSystemCore>(); | ||
| 110 | |||
| 111 | LOG_DEBUG(Service_BTM, "called"); | ||
| 112 | } | ||
| 113 | }; | ||
| 114 | |||
| 115 | void InstallInterfaces(SM::ServiceManager& sm) { | ||
| 116 | std::make_shared<BTM>()->InstallAsService(sm); | ||
| 117 | std::make_shared<BTM_DBG>()->InstallAsService(sm); | ||
| 118 | std::make_shared<BTM_SYS>()->InstallAsService(sm); | ||
| 119 | } | ||
| 120 | |||
| 121 | } // namespace Service::BTM | ||
diff --git a/src/core/hle/service/btm/btm.h b/src/core/hle/service/btm/btm.h new file mode 100644 index 000000000..e6425a7e3 --- /dev/null +++ b/src/core/hle/service/btm/btm.h | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | namespace Service::SM { | ||
| 8 | class ServiceManager; | ||
| 9 | } | ||
| 10 | |||
| 11 | namespace Service::BTM { | ||
| 12 | |||
| 13 | void InstallInterfaces(SM::ServiceManager& sm); | ||
| 14 | |||
| 15 | } // namespace Service::BTM | ||
diff --git a/src/core/hle/service/caps/caps.cpp b/src/core/hle/service/caps/caps.cpp new file mode 100644 index 000000000..ae7b0720b --- /dev/null +++ b/src/core/hle/service/caps/caps.cpp | |||
| @@ -0,0 +1,152 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <memory> | ||
| 6 | |||
| 7 | #include "core/hle/service/caps/caps.h" | ||
| 8 | #include "core/hle/service/service.h" | ||
| 9 | #include "core/hle/service/sm/sm.h" | ||
| 10 | |||
| 11 | namespace Service::Capture { | ||
| 12 | |||
| 13 | class CAPS_A final : public ServiceFramework<CAPS_A> { | ||
| 14 | public: | ||
| 15 | explicit CAPS_A() : ServiceFramework{"caps:a"} { | ||
| 16 | // clang-format off | ||
| 17 | static const FunctionInfo functions[] = { | ||
| 18 | {0, nullptr, "Unknown1"}, | ||
| 19 | {1, nullptr, "Unknown2"}, | ||
| 20 | {2, nullptr, "Unknown3"}, | ||
| 21 | {3, nullptr, "Unknown4"}, | ||
| 22 | {4, nullptr, "Unknown5"}, | ||
| 23 | {5, nullptr, "Unknown6"}, | ||
| 24 | {6, nullptr, "Unknown7"}, | ||
| 25 | {7, nullptr, "Unknown8"}, | ||
| 26 | {8, nullptr, "Unknown9"}, | ||
| 27 | {9, nullptr, "Unknown10"}, | ||
| 28 | {10, nullptr, "Unknown11"}, | ||
| 29 | {11, nullptr, "Unknown12"}, | ||
| 30 | {12, nullptr, "Unknown13"}, | ||
| 31 | {13, nullptr, "Unknown14"}, | ||
| 32 | {14, nullptr, "Unknown15"}, | ||
| 33 | {301, nullptr, "Unknown16"}, | ||
| 34 | {401, nullptr, "Unknown17"}, | ||
| 35 | {501, nullptr, "Unknown18"}, | ||
| 36 | {1001, nullptr, "Unknown19"}, | ||
| 37 | {1002, nullptr, "Unknown20"}, | ||
| 38 | {8001, nullptr, "Unknown21"}, | ||
| 39 | {8002, nullptr, "Unknown22"}, | ||
| 40 | {8011, nullptr, "Unknown23"}, | ||
| 41 | {8012, nullptr, "Unknown24"}, | ||
| 42 | {8021, nullptr, "Unknown25"}, | ||
| 43 | {10011, nullptr, "Unknown26"}, | ||
| 44 | }; | ||
| 45 | // clang-format on | ||
| 46 | |||
| 47 | RegisterHandlers(functions); | ||
| 48 | } | ||
| 49 | }; | ||
| 50 | |||
| 51 | class CAPS_C final : public ServiceFramework<CAPS_C> { | ||
| 52 | public: | ||
| 53 | explicit CAPS_C() : ServiceFramework{"caps:c"} { | ||
| 54 | // clang-format off | ||
| 55 | static const FunctionInfo functions[] = { | ||
| 56 | {2001, nullptr, "Unknown1"}, | ||
| 57 | {2002, nullptr, "Unknown2"}, | ||
| 58 | {2011, nullptr, "Unknown3"}, | ||
| 59 | {2012, nullptr, "Unknown4"}, | ||
| 60 | {2013, nullptr, "Unknown5"}, | ||
| 61 | {2014, nullptr, "Unknown6"}, | ||
| 62 | {2101, nullptr, "Unknown7"}, | ||
| 63 | {2102, nullptr, "Unknown8"}, | ||
| 64 | {2201, nullptr, "Unknown9"}, | ||
| 65 | {2301, nullptr, "Unknown10"}, | ||
| 66 | }; | ||
| 67 | // clang-format on | ||
| 68 | |||
| 69 | RegisterHandlers(functions); | ||
| 70 | } | ||
| 71 | }; | ||
| 72 | |||
| 73 | class CAPS_SC final : public ServiceFramework<CAPS_SC> { | ||
| 74 | public: | ||
| 75 | explicit CAPS_SC() : ServiceFramework{"caps:sc"} { | ||
| 76 | // clang-format off | ||
| 77 | static const FunctionInfo functions[] = { | ||
| 78 | {1, nullptr, "Unknown1"}, | ||
| 79 | {2, nullptr, "Unknown2"}, | ||
| 80 | {1001, nullptr, "Unknown3"}, | ||
| 81 | {1002, nullptr, "Unknown4"}, | ||
| 82 | {1003, nullptr, "Unknown5"}, | ||
| 83 | {1011, nullptr, "Unknown6"}, | ||
| 84 | {1012, nullptr, "Unknown7"}, | ||
| 85 | {1201, nullptr, "Unknown8"}, | ||
| 86 | {1202, nullptr, "Unknown9"}, | ||
| 87 | {1203, nullptr, "Unknown10"}, | ||
| 88 | }; | ||
| 89 | // clang-format on | ||
| 90 | |||
| 91 | RegisterHandlers(functions); | ||
| 92 | } | ||
| 93 | }; | ||
| 94 | |||
| 95 | class CAPS_SS final : public ServiceFramework<CAPS_SS> { | ||
| 96 | public: | ||
| 97 | explicit CAPS_SS() : ServiceFramework{"caps:ss"} { | ||
| 98 | // clang-format off | ||
| 99 | static const FunctionInfo functions[] = { | ||
| 100 | {201, nullptr, "Unknown1"}, | ||
| 101 | {202, nullptr, "Unknown2"}, | ||
| 102 | {203, nullptr, "Unknown3"}, | ||
| 103 | {204, nullptr, "Unknown4"}, | ||
| 104 | }; | ||
| 105 | // clang-format on | ||
| 106 | |||
| 107 | RegisterHandlers(functions); | ||
| 108 | } | ||
| 109 | }; | ||
| 110 | |||
| 111 | class CAPS_SU final : public ServiceFramework<CAPS_SU> { | ||
| 112 | public: | ||
| 113 | explicit CAPS_SU() : ServiceFramework{"caps:su"} { | ||
| 114 | // clang-format off | ||
| 115 | static const FunctionInfo functions[] = { | ||
| 116 | {201, nullptr, "SaveScreenShot"}, | ||
| 117 | {203, nullptr, "SaveScreenShotEx0"}, | ||
| 118 | }; | ||
| 119 | // clang-format on | ||
| 120 | |||
| 121 | RegisterHandlers(functions); | ||
| 122 | } | ||
| 123 | }; | ||
| 124 | |||
| 125 | class CAPS_U final : public ServiceFramework<CAPS_U> { | ||
| 126 | public: | ||
| 127 | explicit CAPS_U() : ServiceFramework{"caps:u"} { | ||
| 128 | // clang-format off | ||
| 129 | static const FunctionInfo functions[] = { | ||
| 130 | {102, nullptr, "GetAlbumFileListByAruid"}, | ||
| 131 | {103, nullptr, "DeleteAlbumFileByAruid"}, | ||
| 132 | {104, nullptr, "GetAlbumFileSizeByAruid"}, | ||
| 133 | {110, nullptr, "LoadAlbumScreenShotImageByAruid"}, | ||
| 134 | {120, nullptr, "LoadAlbumScreenShotThumbnailImageByAruid"}, | ||
| 135 | {60002, nullptr, "OpenAccessorSessionForApplication"}, | ||
| 136 | }; | ||
| 137 | // clang-format on | ||
| 138 | |||
| 139 | RegisterHandlers(functions); | ||
| 140 | } | ||
| 141 | }; | ||
| 142 | |||
| 143 | void InstallInterfaces(SM::ServiceManager& sm) { | ||
| 144 | std::make_shared<CAPS_A>()->InstallAsService(sm); | ||
| 145 | std::make_shared<CAPS_C>()->InstallAsService(sm); | ||
| 146 | std::make_shared<CAPS_SC>()->InstallAsService(sm); | ||
| 147 | std::make_shared<CAPS_SS>()->InstallAsService(sm); | ||
| 148 | std::make_shared<CAPS_SU>()->InstallAsService(sm); | ||
| 149 | std::make_shared<CAPS_U>()->InstallAsService(sm); | ||
| 150 | } | ||
| 151 | |||
| 152 | } // namespace Service::Capture | ||
diff --git a/src/core/hle/service/caps/caps.h b/src/core/hle/service/caps/caps.h new file mode 100644 index 000000000..471185dfa --- /dev/null +++ b/src/core/hle/service/caps/caps.h | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | namespace Service::SM { | ||
| 8 | class ServiceManager; | ||
| 9 | } | ||
| 10 | |||
| 11 | namespace Service::Capture { | ||
| 12 | |||
| 13 | void InstallInterfaces(SM::ServiceManager& sm); | ||
| 14 | |||
| 15 | } // namespace Service::Capture | ||
diff --git a/src/core/hle/service/fgm/fgm.cpp b/src/core/hle/service/fgm/fgm.cpp new file mode 100644 index 000000000..566fbf924 --- /dev/null +++ b/src/core/hle/service/fgm/fgm.cpp | |||
| @@ -0,0 +1,75 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <memory> | ||
| 6 | |||
| 7 | #include "core/hle/ipc_helpers.h" | ||
| 8 | #include "core/hle/kernel/hle_ipc.h" | ||
| 9 | #include "core/hle/service/fgm/fgm.h" | ||
| 10 | #include "core/hle/service/service.h" | ||
| 11 | #include "core/hle/service/sm/sm.h" | ||
| 12 | |||
| 13 | namespace Service::FGM { | ||
| 14 | |||
| 15 | class IRequest final : public ServiceFramework<IRequest> { | ||
| 16 | public: | ||
| 17 | explicit IRequest() : ServiceFramework{"IRequest"} { | ||
| 18 | // clang-format off | ||
| 19 | static const FunctionInfo functions[] = { | ||
| 20 | {0, nullptr, "Initialize"}, | ||
| 21 | {1, nullptr, "Set"}, | ||
| 22 | {2, nullptr, "Get"}, | ||
| 23 | {3, nullptr, "Cancel"}, | ||
| 24 | }; | ||
| 25 | // clang-format on | ||
| 26 | |||
| 27 | RegisterHandlers(functions); | ||
| 28 | } | ||
| 29 | }; | ||
| 30 | |||
| 31 | class FGM final : public ServiceFramework<FGM> { | ||
| 32 | public: | ||
| 33 | explicit FGM(const char* name) : ServiceFramework{name} { | ||
| 34 | // clang-format off | ||
| 35 | static const FunctionInfo functions[] = { | ||
| 36 | {0, &FGM::Initialize, "Initialize"}, | ||
| 37 | }; | ||
| 38 | // clang-format on | ||
| 39 | |||
| 40 | RegisterHandlers(functions); | ||
| 41 | } | ||
| 42 | |||
| 43 | private: | ||
| 44 | void Initialize(Kernel::HLERequestContext& ctx) { | ||
| 45 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 46 | rb.Push(RESULT_SUCCESS); | ||
| 47 | rb.PushIpcInterface<IRequest>(); | ||
| 48 | |||
| 49 | LOG_DEBUG(Service_FGM, "called"); | ||
| 50 | } | ||
| 51 | }; | ||
| 52 | |||
| 53 | class FGM_DBG final : public ServiceFramework<FGM_DBG> { | ||
| 54 | public: | ||
| 55 | explicit FGM_DBG() : ServiceFramework{"fgm:dbg"} { | ||
| 56 | // clang-format off | ||
| 57 | static const FunctionInfo functions[] = { | ||
| 58 | {0, nullptr, "Initialize"}, | ||
| 59 | {1, nullptr, "Read"}, | ||
| 60 | {2, nullptr, "Cancel"}, | ||
| 61 | }; | ||
| 62 | // clang-format on | ||
| 63 | |||
| 64 | RegisterHandlers(functions); | ||
| 65 | } | ||
| 66 | }; | ||
| 67 | |||
| 68 | void InstallInterfaces(SM::ServiceManager& sm) { | ||
| 69 | std::make_shared<FGM>("fgm")->InstallAsService(sm); | ||
| 70 | std::make_shared<FGM>("fgm:0")->InstallAsService(sm); | ||
| 71 | std::make_shared<FGM>("fgm:9")->InstallAsService(sm); | ||
| 72 | std::make_shared<FGM_DBG>()->InstallAsService(sm); | ||
| 73 | } | ||
| 74 | |||
| 75 | } // namespace Service::FGM | ||
diff --git a/src/core/hle/service/fgm/fgm.h b/src/core/hle/service/fgm/fgm.h new file mode 100644 index 000000000..e59691264 --- /dev/null +++ b/src/core/hle/service/fgm/fgm.h | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | namespace Service::SM { | ||
| 8 | class ServiceManager; | ||
| 9 | } | ||
| 10 | |||
| 11 | namespace Service::FGM { | ||
| 12 | |||
| 13 | void InstallInterfaces(SM::ServiceManager& sm); | ||
| 14 | |||
| 15 | } // namespace Service::FGM | ||
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index fdd2fda18..e17d637e4 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp | |||
| @@ -14,6 +14,8 @@ | |||
| 14 | #include "core/file_sys/vfs_offset.h" | 14 | #include "core/file_sys/vfs_offset.h" |
| 15 | #include "core/file_sys/vfs_real.h" | 15 | #include "core/file_sys/vfs_real.h" |
| 16 | #include "core/hle/service/filesystem/filesystem.h" | 16 | #include "core/hle/service/filesystem/filesystem.h" |
| 17 | #include "core/hle/service/filesystem/fsp_ldr.h" | ||
| 18 | #include "core/hle/service/filesystem/fsp_pr.h" | ||
| 17 | #include "core/hle/service/filesystem/fsp_srv.h" | 19 | #include "core/hle/service/filesystem/fsp_srv.h" |
| 18 | 20 | ||
| 19 | namespace Service::FileSystem { | 21 | namespace Service::FileSystem { |
| @@ -298,6 +300,8 @@ void RegisterFileSystems() { | |||
| 298 | 300 | ||
| 299 | void InstallInterfaces(SM::ServiceManager& service_manager) { | 301 | void InstallInterfaces(SM::ServiceManager& service_manager) { |
| 300 | RegisterFileSystems(); | 302 | RegisterFileSystems(); |
| 303 | std::make_shared<FSP_LDR>()->InstallAsService(service_manager); | ||
| 304 | std::make_shared<FSP_PR>()->InstallAsService(service_manager); | ||
| 301 | std::make_shared<FSP_SRV>()->InstallAsService(service_manager); | 305 | std::make_shared<FSP_SRV>()->InstallAsService(service_manager); |
| 302 | } | 306 | } |
| 303 | 307 | ||
diff --git a/src/core/hle/service/filesystem/fsp_ldr.cpp b/src/core/hle/service/filesystem/fsp_ldr.cpp new file mode 100644 index 000000000..0ab9c2606 --- /dev/null +++ b/src/core/hle/service/filesystem/fsp_ldr.cpp | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/hle/service/filesystem/fsp_ldr.h" | ||
| 6 | #include "core/hle/service/service.h" | ||
| 7 | |||
| 8 | namespace Service::FileSystem { | ||
| 9 | |||
| 10 | FSP_LDR::FSP_LDR() : ServiceFramework{"fsp:ldr"} { | ||
| 11 | // clang-format off | ||
| 12 | static const FunctionInfo functions[] = { | ||
| 13 | {0, nullptr, "OpenCodeFileSystem"}, | ||
| 14 | {1, nullptr, "IsArchivedProgram"}, | ||
| 15 | {2, nullptr, "SetCurrentProcess"}, | ||
| 16 | }; | ||
| 17 | // clang-format on | ||
| 18 | |||
| 19 | RegisterHandlers(functions); | ||
| 20 | } | ||
| 21 | |||
| 22 | } // namespace Service::FileSystem | ||
diff --git a/src/core/hle/service/filesystem/fsp_ldr.h b/src/core/hle/service/filesystem/fsp_ldr.h new file mode 100644 index 000000000..fa8e11b4c --- /dev/null +++ b/src/core/hle/service/filesystem/fsp_ldr.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::FileSystem { | ||
| 10 | |||
| 11 | class FSP_LDR final : public ServiceFramework<FSP_LDR> { | ||
| 12 | public: | ||
| 13 | explicit FSP_LDR(); | ||
| 14 | }; | ||
| 15 | |||
| 16 | } // namespace Service::FileSystem | ||
diff --git a/src/core/hle/service/filesystem/fsp_pr.cpp b/src/core/hle/service/filesystem/fsp_pr.cpp new file mode 100644 index 000000000..32b0ae454 --- /dev/null +++ b/src/core/hle/service/filesystem/fsp_pr.cpp | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/hle/service/filesystem/fsp_pr.h" | ||
| 6 | #include "core/hle/service/service.h" | ||
| 7 | |||
| 8 | namespace Service::FileSystem { | ||
| 9 | |||
| 10 | FSP_PR::FSP_PR() : ServiceFramework{"fsp:pr"} { | ||
| 11 | // clang-format off | ||
| 12 | static const FunctionInfo functions[] = { | ||
| 13 | {0, nullptr, "RegisterProgram"}, | ||
| 14 | {1, nullptr, "UnregisterProgram"}, | ||
| 15 | {2, nullptr, "SetCurrentProcess"}, | ||
| 16 | {256, nullptr, "SetEnabledProgramVerification"}, | ||
| 17 | }; | ||
| 18 | // clang-format on | ||
| 19 | |||
| 20 | RegisterHandlers(functions); | ||
| 21 | } | ||
| 22 | |||
| 23 | } // namespace Service::FileSystem | ||
diff --git a/src/core/hle/service/filesystem/fsp_pr.h b/src/core/hle/service/filesystem/fsp_pr.h new file mode 100644 index 000000000..62edcd08a --- /dev/null +++ b/src/core/hle/service/filesystem/fsp_pr.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::FileSystem { | ||
| 10 | |||
| 11 | class FSP_PR final : public ServiceFramework<FSP_PR> { | ||
| 12 | public: | ||
| 13 | explicit FSP_PR(); | ||
| 14 | }; | ||
| 15 | |||
| 16 | } // namespace Service::FileSystem | ||
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index e4619a547..8f0262e34 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -326,7 +326,7 @@ public: | |||
| 326 | {79, &Hid::SetGyroscopeZeroDriftMode, "SetGyroscopeZeroDriftMode"}, | 326 | {79, &Hid::SetGyroscopeZeroDriftMode, "SetGyroscopeZeroDriftMode"}, |
| 327 | {80, nullptr, "GetGyroscopeZeroDriftMode"}, | 327 | {80, nullptr, "GetGyroscopeZeroDriftMode"}, |
| 328 | {81, nullptr, "ResetGyroscopeZeroDriftMode"}, | 328 | {81, nullptr, "ResetGyroscopeZeroDriftMode"}, |
| 329 | {82, nullptr, "IsSixAxisSensorAtRest"}, | 329 | {82, &Hid::IsSixAxisSensorAtRest, "IsSixAxisSensorAtRest"}, |
| 330 | {91, nullptr, "ActivateGesture"}, | 330 | {91, nullptr, "ActivateGesture"}, |
| 331 | {100, &Hid::SetSupportedNpadStyleSet, "SetSupportedNpadStyleSet"}, | 331 | {100, &Hid::SetSupportedNpadStyleSet, "SetSupportedNpadStyleSet"}, |
| 332 | {101, &Hid::GetSupportedNpadStyleSet, "GetSupportedNpadStyleSet"}, | 332 | {101, &Hid::GetSupportedNpadStyleSet, "GetSupportedNpadStyleSet"}, |
| @@ -337,13 +337,14 @@ public: | |||
| 337 | "AcquireNpadStyleSetUpdateEventHandle"}, | 337 | "AcquireNpadStyleSetUpdateEventHandle"}, |
| 338 | {107, nullptr, "DisconnectNpad"}, | 338 | {107, nullptr, "DisconnectNpad"}, |
| 339 | {108, &Hid::GetPlayerLedPattern, "GetPlayerLedPattern"}, | 339 | {108, &Hid::GetPlayerLedPattern, "GetPlayerLedPattern"}, |
| 340 | {109, nullptr, "ActivateNpadWithRevision"}, | ||
| 340 | {120, &Hid::SetNpadJoyHoldType, "SetNpadJoyHoldType"}, | 341 | {120, &Hid::SetNpadJoyHoldType, "SetNpadJoyHoldType"}, |
| 341 | {121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"}, | 342 | {121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"}, |
| 342 | {122, &Hid::SetNpadJoyAssignmentModeSingleByDefault, | 343 | {122, &Hid::SetNpadJoyAssignmentModeSingleByDefault, |
| 343 | "SetNpadJoyAssignmentModeSingleByDefault"}, | 344 | "SetNpadJoyAssignmentModeSingleByDefault"}, |
| 344 | {123, nullptr, "SetNpadJoyAssignmentModeSingleByDefault"}, | 345 | {123, nullptr, "SetNpadJoyAssignmentModeSingleByDefault"}, |
| 345 | {124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"}, | 346 | {124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"}, |
| 346 | {125, nullptr, "MergeSingleJoyAsDualJoy"}, | 347 | {125, &Hid::MergeSingleJoyAsDualJoy, "MergeSingleJoyAsDualJoy"}, |
| 347 | {126, nullptr, "StartLrAssignmentMode"}, | 348 | {126, nullptr, "StartLrAssignmentMode"}, |
| 348 | {127, nullptr, "StopLrAssignmentMode"}, | 349 | {127, nullptr, "StopLrAssignmentMode"}, |
| 349 | {128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"}, | 350 | {128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"}, |
| @@ -455,6 +456,14 @@ private: | |||
| 455 | LOG_WARNING(Service_HID, "(STUBBED) called"); | 456 | LOG_WARNING(Service_HID, "(STUBBED) called"); |
| 456 | } | 457 | } |
| 457 | 458 | ||
| 459 | void IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx) { | ||
| 460 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 461 | rb.Push(RESULT_SUCCESS); | ||
| 462 | // TODO (Hexagon12): Properly implement reading gyroscope values from controllers. | ||
| 463 | rb.Push(true); | ||
| 464 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 465 | } | ||
| 466 | |||
| 458 | void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) { | 467 | void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) { |
| 459 | IPC::ResponseBuilder rb{ctx, 2}; | 468 | IPC::ResponseBuilder rb{ctx, 2}; |
| 460 | rb.Push(RESULT_SUCCESS); | 469 | rb.Push(RESULT_SUCCESS); |
| @@ -530,6 +539,12 @@ private: | |||
| 530 | LOG_WARNING(Service_HID, "(STUBBED) called"); | 539 | LOG_WARNING(Service_HID, "(STUBBED) called"); |
| 531 | } | 540 | } |
| 532 | 541 | ||
| 542 | void MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) { | ||
| 543 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 544 | rb.Push(RESULT_SUCCESS); | ||
| 545 | LOG_WARNING(Service_HID, "(STUBBED) called"); | ||
| 546 | } | ||
| 547 | |||
| 533 | void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) { | 548 | void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) { |
| 534 | IPC::ResponseBuilder rb{ctx, 2}; | 549 | IPC::ResponseBuilder rb{ctx, 2}; |
| 535 | rb.Push(RESULT_SUCCESS); | 550 | rb.Push(RESULT_SUCCESS); |
diff --git a/src/core/hle/service/lbl/lbl.cpp b/src/core/hle/service/lbl/lbl.cpp new file mode 100644 index 000000000..8fc8b1057 --- /dev/null +++ b/src/core/hle/service/lbl/lbl.cpp | |||
| @@ -0,0 +1,90 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <memory> | ||
| 6 | |||
| 7 | #include "common/logging/log.h" | ||
| 8 | #include "core/hle/ipc_helpers.h" | ||
| 9 | #include "core/hle/kernel/hle_ipc.h" | ||
| 10 | #include "core/hle/service/lbl/lbl.h" | ||
| 11 | #include "core/hle/service/service.h" | ||
| 12 | #include "core/hle/service/sm/sm.h" | ||
| 13 | |||
| 14 | namespace Service::LBL { | ||
| 15 | |||
| 16 | class LBL final : public ServiceFramework<LBL> { | ||
| 17 | public: | ||
| 18 | explicit LBL() : ServiceFramework{"lbl"} { | ||
| 19 | // clang-format off | ||
| 20 | static const FunctionInfo functions[] = { | ||
| 21 | {0, nullptr, "Unknown1"}, | ||
| 22 | {1, nullptr, "Unknown2"}, | ||
| 23 | {2, nullptr, "Unknown3"}, | ||
| 24 | {3, nullptr, "Unknown4"}, | ||
| 25 | {4, nullptr, "Unknown5"}, | ||
| 26 | {5, nullptr, "Unknown6"}, | ||
| 27 | {6, nullptr, "TurnOffBacklight"}, | ||
| 28 | {7, nullptr, "TurnOnBacklight"}, | ||
| 29 | {8, nullptr, "GetBacklightStatus"}, | ||
| 30 | {9, nullptr, "Unknown7"}, | ||
| 31 | {10, nullptr, "Unknown8"}, | ||
| 32 | {11, nullptr, "Unknown9"}, | ||
| 33 | {12, nullptr, "Unknown10"}, | ||
| 34 | {13, nullptr, "Unknown11"}, | ||
| 35 | {14, nullptr, "Unknown12"}, | ||
| 36 | {15, nullptr, "Unknown13"}, | ||
| 37 | {16, nullptr, "ReadRawLightSensor"}, | ||
| 38 | {17, nullptr, "Unknown14"}, | ||
| 39 | {18, nullptr, "Unknown15"}, | ||
| 40 | {19, nullptr, "Unknown16"}, | ||
| 41 | {20, nullptr, "Unknown17"}, | ||
| 42 | {21, nullptr, "Unknown18"}, | ||
| 43 | {22, nullptr, "Unknown19"}, | ||
| 44 | {23, nullptr, "Unknown20"}, | ||
| 45 | {24, nullptr, "Unknown21"}, | ||
| 46 | {25, nullptr, "Unknown22"}, | ||
| 47 | {26, &LBL::EnableVrMode, "EnableVrMode"}, | ||
| 48 | {27, &LBL::DisableVrMode, "DisableVrMode"}, | ||
| 49 | {28, &LBL::GetVrMode, "GetVrMode"}, | ||
| 50 | }; | ||
| 51 | // clang-format on | ||
| 52 | |||
| 53 | RegisterHandlers(functions); | ||
| 54 | } | ||
| 55 | |||
| 56 | private: | ||
| 57 | void EnableVrMode(Kernel::HLERequestContext& ctx) { | ||
| 58 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 59 | rb.Push(RESULT_SUCCESS); | ||
| 60 | |||
| 61 | vr_mode_enabled = true; | ||
| 62 | |||
| 63 | LOG_DEBUG(Service_LBL, "called"); | ||
| 64 | } | ||
| 65 | |||
| 66 | void DisableVrMode(Kernel::HLERequestContext& ctx) { | ||
| 67 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 68 | rb.Push(RESULT_SUCCESS); | ||
| 69 | |||
| 70 | vr_mode_enabled = false; | ||
| 71 | |||
| 72 | LOG_DEBUG(Service_LBL, "called"); | ||
| 73 | } | ||
| 74 | |||
| 75 | void GetVrMode(Kernel::HLERequestContext& ctx) { | ||
| 76 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 77 | rb.Push(RESULT_SUCCESS); | ||
| 78 | rb.Push(vr_mode_enabled); | ||
| 79 | |||
| 80 | LOG_DEBUG(Service_LBL, "called"); | ||
| 81 | } | ||
| 82 | |||
| 83 | bool vr_mode_enabled = false; | ||
| 84 | }; | ||
| 85 | |||
| 86 | void InstallInterfaces(SM::ServiceManager& sm) { | ||
| 87 | std::make_shared<LBL>()->InstallAsService(sm); | ||
| 88 | } | ||
| 89 | |||
| 90 | } // namespace Service::LBL | ||
diff --git a/src/core/hle/service/lbl/lbl.h b/src/core/hle/service/lbl/lbl.h new file mode 100644 index 000000000..bf6f400f8 --- /dev/null +++ b/src/core/hle/service/lbl/lbl.h | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | namespace Service::SM { | ||
| 8 | class ServiceManager; | ||
| 9 | } | ||
| 10 | |||
| 11 | namespace Service::LBL { | ||
| 12 | |||
| 13 | void InstallInterfaces(SM::ServiceManager& sm); | ||
| 14 | |||
| 15 | } // namespace Service::LBL | ||
diff --git a/src/core/hle/service/lm/lm.cpp b/src/core/hle/service/lm/lm.cpp index b497376d7..2e99ddf51 100644 --- a/src/core/hle/service/lm/lm.cpp +++ b/src/core/hle/service/lm/lm.cpp | |||
| @@ -13,11 +13,11 @@ | |||
| 13 | 13 | ||
| 14 | namespace Service::LM { | 14 | namespace Service::LM { |
| 15 | 15 | ||
| 16 | class Logger final : public ServiceFramework<Logger> { | 16 | class ILogger final : public ServiceFramework<ILogger> { |
| 17 | public: | 17 | public: |
| 18 | Logger() : ServiceFramework("Logger") { | 18 | ILogger() : ServiceFramework("ILogger") { |
| 19 | static const FunctionInfo functions[] = { | 19 | static const FunctionInfo functions[] = { |
| 20 | {0x00000000, &Logger::Initialize, "Initialize"}, | 20 | {0x00000000, &ILogger::Initialize, "Initialize"}, |
| 21 | {0x00000001, nullptr, "SetDestination"}, | 21 | {0x00000001, nullptr, "SetDestination"}, |
| 22 | }; | 22 | }; |
| 23 | RegisterHandlers(functions); | 23 | RegisterHandlers(functions); |
| @@ -182,7 +182,7 @@ public: | |||
| 182 | void OpenLogger(Kernel::HLERequestContext& ctx) { | 182 | void OpenLogger(Kernel::HLERequestContext& ctx) { |
| 183 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | 183 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; |
| 184 | rb.Push(RESULT_SUCCESS); | 184 | rb.Push(RESULT_SUCCESS); |
| 185 | rb.PushIpcInterface<Logger>(); | 185 | rb.PushIpcInterface<ILogger>(); |
| 186 | 186 | ||
| 187 | LOG_DEBUG(Service_LM, "called"); | 187 | LOG_DEBUG(Service_LM, "called"); |
| 188 | } | 188 | } |
diff --git a/src/core/hle/service/mig/mig.cpp b/src/core/hle/service/mig/mig.cpp new file mode 100644 index 000000000..d16367f2c --- /dev/null +++ b/src/core/hle/service/mig/mig.cpp | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <memory> | ||
| 6 | |||
| 7 | #include "core/hle/service/mig/mig.h" | ||
| 8 | #include "core/hle/service/service.h" | ||
| 9 | #include "core/hle/service/sm/sm.h" | ||
| 10 | |||
| 11 | namespace Service::Migration { | ||
| 12 | |||
| 13 | class MIG_USR final : public ServiceFramework<MIG_USR> { | ||
| 14 | public: | ||
| 15 | explicit MIG_USR() : ServiceFramework{"mig:usr"} { | ||
| 16 | // clang-format off | ||
| 17 | static const FunctionInfo functions[] = { | ||
| 18 | {10, nullptr, "TryGetLastMigrationInfo"}, | ||
| 19 | {100, nullptr, "CreateServer"}, | ||
| 20 | {101, nullptr, "ResumeServer"}, | ||
| 21 | {200, nullptr, "CreateClient"}, | ||
| 22 | {201, nullptr, "ResumeClient"}, | ||
| 23 | }; | ||
| 24 | // clang-format on | ||
| 25 | |||
| 26 | RegisterHandlers(functions); | ||
| 27 | } | ||
| 28 | }; | ||
| 29 | |||
| 30 | void InstallInterfaces(SM::ServiceManager& sm) { | ||
| 31 | std::make_shared<MIG_USR>()->InstallAsService(sm); | ||
| 32 | } | ||
| 33 | |||
| 34 | } // namespace Service::Migration | ||
diff --git a/src/core/hle/service/mig/mig.h b/src/core/hle/service/mig/mig.h new file mode 100644 index 000000000..288c1c1b3 --- /dev/null +++ b/src/core/hle/service/mig/mig.h | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | namespace Service::SM { | ||
| 8 | class ServiceManager; | ||
| 9 | } | ||
| 10 | |||
| 11 | namespace Service::Migration { | ||
| 12 | |||
| 13 | void InstallInterfaces(SM::ServiceManager& sm); | ||
| 14 | |||
| 15 | } // namespace Service::Migration | ||
diff --git a/src/core/hle/service/mii/mii.cpp b/src/core/hle/service/mii/mii.cpp new file mode 100644 index 000000000..a6197124a --- /dev/null +++ b/src/core/hle/service/mii/mii.cpp | |||
| @@ -0,0 +1,107 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <memory> | ||
| 6 | |||
| 7 | #include "common/logging/log.h" | ||
| 8 | #include "core/hle/ipc_helpers.h" | ||
| 9 | #include "core/hle/kernel/hle_ipc.h" | ||
| 10 | #include "core/hle/service/mii/mii.h" | ||
| 11 | #include "core/hle/service/service.h" | ||
| 12 | #include "core/hle/service/sm/sm.h" | ||
| 13 | |||
| 14 | namespace Service::Mii { | ||
| 15 | |||
| 16 | class IDatabaseService final : public ServiceFramework<IDatabaseService> { | ||
| 17 | public: | ||
| 18 | explicit IDatabaseService() : ServiceFramework{"IDatabaseService"} { | ||
| 19 | // clang-format off | ||
| 20 | static const FunctionInfo functions[] = { | ||
| 21 | {0, nullptr, "IsUpdated"}, | ||
| 22 | {1, nullptr, "IsFullDatabase"}, | ||
| 23 | {2, nullptr, "GetCount"}, | ||
| 24 | {3, nullptr, "Get"}, | ||
| 25 | {4, nullptr, "Get1"}, | ||
| 26 | {5, nullptr, "UpdateLatest"}, | ||
| 27 | {6, nullptr, "BuildRandom"}, | ||
| 28 | {7, nullptr, "BuildDefault"}, | ||
| 29 | {8, nullptr, "Get2"}, | ||
| 30 | {9, nullptr, "Get3"}, | ||
| 31 | {10, nullptr, "UpdateLatest1"}, | ||
| 32 | {11, nullptr, "FindIndex"}, | ||
| 33 | {12, nullptr, "Move"}, | ||
| 34 | {13, nullptr, "AddOrReplace"}, | ||
| 35 | {14, nullptr, "Delete"}, | ||
| 36 | {15, nullptr, "DestroyFile"}, | ||
| 37 | {16, nullptr, "DeleteFile"}, | ||
| 38 | {17, nullptr, "Format"}, | ||
| 39 | {18, nullptr, "Import"}, | ||
| 40 | {19, nullptr, "Export"}, | ||
| 41 | {20, nullptr, "IsBrokenDatabaseWithClearFlag"}, | ||
| 42 | {21, nullptr, "GetIndex"}, | ||
| 43 | {22, nullptr, "SetInterfaceVersion"}, | ||
| 44 | {23, nullptr, "Convert"}, | ||
| 45 | }; | ||
| 46 | // clang-format on | ||
| 47 | |||
| 48 | RegisterHandlers(functions); | ||
| 49 | } | ||
| 50 | }; | ||
| 51 | |||
| 52 | class MiiDBModule final : public ServiceFramework<MiiDBModule> { | ||
| 53 | public: | ||
| 54 | explicit MiiDBModule(const char* name) : ServiceFramework{name} { | ||
| 55 | // clang-format off | ||
| 56 | static const FunctionInfo functions[] = { | ||
| 57 | {0, &MiiDBModule::GetDatabaseService, "GetDatabaseService"}, | ||
| 58 | }; | ||
| 59 | // clang-format on | ||
| 60 | |||
| 61 | RegisterHandlers(functions); | ||
| 62 | } | ||
| 63 | |||
| 64 | private: | ||
| 65 | void GetDatabaseService(Kernel::HLERequestContext& ctx) { | ||
| 66 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 67 | rb.Push(RESULT_SUCCESS); | ||
| 68 | rb.PushIpcInterface<IDatabaseService>(); | ||
| 69 | |||
| 70 | LOG_DEBUG(Service_Mii, "called"); | ||
| 71 | } | ||
| 72 | }; | ||
| 73 | |||
| 74 | class MiiImg final : public ServiceFramework<MiiImg> { | ||
| 75 | public: | ||
| 76 | explicit MiiImg() : ServiceFramework{"miiimg"} { | ||
| 77 | // clang-format off | ||
| 78 | static const FunctionInfo functions[] = { | ||
| 79 | {0, nullptr, "Initialize"}, | ||
| 80 | {10, nullptr, "Reload"}, | ||
| 81 | {11, nullptr, "GetCount"}, | ||
| 82 | {12, nullptr, "IsEmpty"}, | ||
| 83 | {13, nullptr, "IsFull"}, | ||
| 84 | {14, nullptr, "GetAttribute"}, | ||
| 85 | {15, nullptr, "LoadImage"}, | ||
| 86 | {16, nullptr, "AddOrUpdateImage"}, | ||
| 87 | {17, nullptr, "DeleteImages"}, | ||
| 88 | {100, nullptr, "DeleteFile"}, | ||
| 89 | {101, nullptr, "DestroyFile"}, | ||
| 90 | {102, nullptr, "ImportFile"}, | ||
| 91 | {103, nullptr, "ExportFile"}, | ||
| 92 | {104, nullptr, "ForceInitialize"}, | ||
| 93 | }; | ||
| 94 | // clang-format on | ||
| 95 | |||
| 96 | RegisterHandlers(functions); | ||
| 97 | } | ||
| 98 | }; | ||
| 99 | |||
| 100 | void InstallInterfaces(SM::ServiceManager& sm) { | ||
| 101 | std::make_shared<MiiDBModule>("mii:e")->InstallAsService(sm); | ||
| 102 | std::make_shared<MiiDBModule>("mii:u")->InstallAsService(sm); | ||
| 103 | |||
| 104 | std::make_shared<MiiImg>()->InstallAsService(sm); | ||
| 105 | } | ||
| 106 | |||
| 107 | } // namespace Service::Mii | ||
diff --git a/src/core/hle/service/mii/mii.h b/src/core/hle/service/mii/mii.h new file mode 100644 index 000000000..7ce9be50e --- /dev/null +++ b/src/core/hle/service/mii/mii.h | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | namespace Service::SM { | ||
| 8 | class ServiceManager; | ||
| 9 | } | ||
| 10 | |||
| 11 | namespace Service::Mii { | ||
| 12 | |||
| 13 | void InstallInterfaces(SM::ServiceManager& sm); | ||
| 14 | |||
| 15 | } // namespace Service::Mii | ||
diff --git a/src/core/hle/service/ncm/ncm.cpp b/src/core/hle/service/ncm/ncm.cpp new file mode 100644 index 000000000..0297edca0 --- /dev/null +++ b/src/core/hle/service/ncm/ncm.cpp | |||
| @@ -0,0 +1,59 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <memory> | ||
| 6 | |||
| 7 | #include "core/hle/service/ncm/ncm.h" | ||
| 8 | #include "core/hle/service/service.h" | ||
| 9 | #include "core/hle/service/sm/sm.h" | ||
| 10 | |||
| 11 | namespace Service::NCM { | ||
| 12 | |||
| 13 | class LocationResolver final : public ServiceFramework<LocationResolver> { | ||
| 14 | public: | ||
| 15 | explicit LocationResolver() : ServiceFramework{"lr"} { | ||
| 16 | // clang-format off | ||
| 17 | static const FunctionInfo functions[] = { | ||
| 18 | {0, nullptr, "OpenLocationResolver"}, | ||
| 19 | {1, nullptr, "OpenRegisteredLocationResolver"}, | ||
| 20 | {2, nullptr, "RefreshLocationResolver"}, | ||
| 21 | {3, nullptr, "OpenAddOnContentLocationResolver"}, | ||
| 22 | }; | ||
| 23 | // clang-format on | ||
| 24 | |||
| 25 | RegisterHandlers(functions); | ||
| 26 | } | ||
| 27 | }; | ||
| 28 | |||
| 29 | class NCM final : public ServiceFramework<NCM> { | ||
| 30 | public: | ||
| 31 | explicit NCM() : ServiceFramework{"ncm"} { | ||
| 32 | // clang-format off | ||
| 33 | static const FunctionInfo functions[] = { | ||
| 34 | {0, nullptr, "CreateContentStorage"}, | ||
| 35 | {1, nullptr, "CreateContentMetaDatabase"}, | ||
| 36 | {2, nullptr, "VerifyContentStorage"}, | ||
| 37 | {3, nullptr, "VerifyContentMetaDatabase"}, | ||
| 38 | {4, nullptr, "OpenContentStorage"}, | ||
| 39 | {5, nullptr, "OpenContentMetaDatabase"}, | ||
| 40 | {6, nullptr, "CloseContentStorageForcibly"}, | ||
| 41 | {7, nullptr, "CloseContentMetaDatabaseForcibly"}, | ||
| 42 | {8, nullptr, "CleanupContentMetaDatabase"}, | ||
| 43 | {9, nullptr, "OpenContentStorage2"}, | ||
| 44 | {10, nullptr, "CloseContentStorage"}, | ||
| 45 | {11, nullptr, "OpenContentMetaDatabase2"}, | ||
| 46 | {12, nullptr, "CloseContentMetaDatabase"}, | ||
| 47 | }; | ||
| 48 | // clang-format on | ||
| 49 | |||
| 50 | RegisterHandlers(functions); | ||
| 51 | } | ||
| 52 | }; | ||
| 53 | |||
| 54 | void InstallInterfaces(SM::ServiceManager& sm) { | ||
| 55 | std::make_shared<LocationResolver>()->InstallAsService(sm); | ||
| 56 | std::make_shared<NCM>()->InstallAsService(sm); | ||
| 57 | } | ||
| 58 | |||
| 59 | } // namespace Service::NCM | ||
diff --git a/src/core/hle/service/ncm/ncm.h b/src/core/hle/service/ncm/ncm.h new file mode 100644 index 000000000..7bc8518a6 --- /dev/null +++ b/src/core/hle/service/ncm/ncm.h | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | namespace Service::SM { | ||
| 8 | class ServiceManager; | ||
| 9 | } | ||
| 10 | |||
| 11 | namespace Service::NCM { | ||
| 12 | |||
| 13 | void InstallInterfaces(SM::ServiceManager& sm); | ||
| 14 | |||
| 15 | } // namespace Service::NCM | ||
diff --git a/src/core/hle/service/nfc/nfc.cpp b/src/core/hle/service/nfc/nfc.cpp new file mode 100644 index 000000000..8fec97db8 --- /dev/null +++ b/src/core/hle/service/nfc/nfc.cpp | |||
| @@ -0,0 +1,222 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <memory> | ||
| 6 | |||
| 7 | #include "common/logging/log.h" | ||
| 8 | #include "core/hle/ipc_helpers.h" | ||
| 9 | #include "core/hle/kernel/hle_ipc.h" | ||
| 10 | #include "core/hle/service/nfc/nfc.h" | ||
| 11 | #include "core/hle/service/service.h" | ||
| 12 | #include "core/hle/service/sm/sm.h" | ||
| 13 | |||
| 14 | namespace Service::NFC { | ||
| 15 | |||
| 16 | class IAm final : public ServiceFramework<IAm> { | ||
| 17 | public: | ||
| 18 | explicit IAm() : ServiceFramework{"IAm"} { | ||
| 19 | // clang-format off | ||
| 20 | static const FunctionInfo functions[] = { | ||
| 21 | {0, nullptr, "Initialize"}, | ||
| 22 | {1, nullptr, "Finalize"}, | ||
| 23 | {2, nullptr, "NotifyForegroundApplet"}, | ||
| 24 | }; | ||
| 25 | // clang-format on | ||
| 26 | |||
| 27 | RegisterHandlers(functions); | ||
| 28 | } | ||
| 29 | }; | ||
| 30 | |||
| 31 | class NFC_AM final : public ServiceFramework<NFC_AM> { | ||
| 32 | public: | ||
| 33 | explicit NFC_AM() : ServiceFramework{"nfc:am"} { | ||
| 34 | // clang-format off | ||
| 35 | static const FunctionInfo functions[] = { | ||
| 36 | {0, &NFC_AM::CreateAmInterface, "CreateAmInterface"}, | ||
| 37 | }; | ||
| 38 | // clang-format on | ||
| 39 | |||
| 40 | RegisterHandlers(functions); | ||
| 41 | } | ||
| 42 | |||
| 43 | private: | ||
| 44 | void CreateAmInterface(Kernel::HLERequestContext& ctx) { | ||
| 45 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 46 | rb.Push(RESULT_SUCCESS); | ||
| 47 | rb.PushIpcInterface<IAm>(); | ||
| 48 | |||
| 49 | LOG_DEBUG(Service_NFC, "called"); | ||
| 50 | } | ||
| 51 | }; | ||
| 52 | |||
| 53 | class MFIUser final : public ServiceFramework<MFIUser> { | ||
| 54 | public: | ||
| 55 | explicit MFIUser() : ServiceFramework{"IUser"} { | ||
| 56 | // clang-format off | ||
| 57 | static const FunctionInfo functions[] = { | ||
| 58 | {0, nullptr, "Initialize"}, | ||
| 59 | {1, nullptr, "Finalize"}, | ||
| 60 | {2, nullptr, "ListDevices"}, | ||
| 61 | {3, nullptr, "StartDetection"}, | ||
| 62 | {4, nullptr, "StopDetection"}, | ||
| 63 | {5, nullptr, "Read"}, | ||
| 64 | {6, nullptr, "Write"}, | ||
| 65 | {7, nullptr, "GetTagInfo"}, | ||
| 66 | {8, nullptr, "GetActivateEventHandle"}, | ||
| 67 | {9, nullptr, "GetDeactivateEventHandle"}, | ||
| 68 | {10, nullptr, "GetState"}, | ||
| 69 | {11, nullptr, "GetDeviceState"}, | ||
| 70 | {12, nullptr, "GetNpadId"}, | ||
| 71 | {13, nullptr, "GetAvailabilityChangeEventHandle"}, | ||
| 72 | }; | ||
| 73 | // clang-format on | ||
| 74 | |||
| 75 | RegisterHandlers(functions); | ||
| 76 | } | ||
| 77 | }; | ||
| 78 | |||
| 79 | class NFC_MF_U final : public ServiceFramework<NFC_MF_U> { | ||
| 80 | public: | ||
| 81 | explicit NFC_MF_U() : ServiceFramework{"nfc:mf:u"} { | ||
| 82 | // clang-format off | ||
| 83 | static const FunctionInfo functions[] = { | ||
| 84 | {0, &NFC_MF_U::CreateUserInterface, "CreateUserInterface"}, | ||
| 85 | }; | ||
| 86 | // clang-format on | ||
| 87 | |||
| 88 | RegisterHandlers(functions); | ||
| 89 | } | ||
| 90 | |||
| 91 | private: | ||
| 92 | void CreateUserInterface(Kernel::HLERequestContext& ctx) { | ||
| 93 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 94 | rb.Push(RESULT_SUCCESS); | ||
| 95 | rb.PushIpcInterface<MFIUser>(); | ||
| 96 | |||
| 97 | LOG_DEBUG(Service_NFC, "called"); | ||
| 98 | } | ||
| 99 | }; | ||
| 100 | |||
| 101 | class IUser final : public ServiceFramework<IUser> { | ||
| 102 | public: | ||
| 103 | explicit IUser() : ServiceFramework{"IUser"} { | ||
| 104 | // clang-format off | ||
| 105 | static const FunctionInfo functions[] = { | ||
| 106 | {0, nullptr, "Initialize"}, | ||
| 107 | {1, nullptr, "Finalize"}, | ||
| 108 | {2, nullptr, "GetState"}, | ||
| 109 | {3, nullptr, "IsNfcEnabled"}, | ||
| 110 | {400, nullptr, "Initialize"}, | ||
| 111 | {401, nullptr, "Finalize"}, | ||
| 112 | {402, nullptr, "GetState"}, | ||
| 113 | {403, nullptr, "IsNfcEnabled"}, | ||
| 114 | {404, nullptr, "ListDevices"}, | ||
| 115 | {405, nullptr, "GetDeviceState"}, | ||
| 116 | {406, nullptr, "GetNpadId"}, | ||
| 117 | {407, nullptr, "AttachAvailabilityChangeEvent"}, | ||
| 118 | {408, nullptr, "StartDetection"}, | ||
| 119 | {409, nullptr, "StopDetection"}, | ||
| 120 | {410, nullptr, "GetTagInfo"}, | ||
| 121 | {411, nullptr, "AttachActivateEvent"}, | ||
| 122 | {412, nullptr, "AttachDeactivateEvent"}, | ||
| 123 | {1000, nullptr, "ReadMifare"}, | ||
| 124 | {1001, nullptr, "WriteMifare"}, | ||
| 125 | {1300, nullptr, "SendCommandByPassThrough"}, | ||
| 126 | {1301, nullptr, "KeepPassThroughSession"}, | ||
| 127 | {1302, nullptr, "ReleasePassThroughSession"}, | ||
| 128 | }; | ||
| 129 | // clang-format on | ||
| 130 | |||
| 131 | RegisterHandlers(functions); | ||
| 132 | } | ||
| 133 | }; | ||
| 134 | |||
| 135 | class NFC_U final : public ServiceFramework<NFC_U> { | ||
| 136 | public: | ||
| 137 | explicit NFC_U() : ServiceFramework{"nfc:u"} { | ||
| 138 | // clang-format off | ||
| 139 | static const FunctionInfo functions[] = { | ||
| 140 | {0, &NFC_U::CreateUserInterface, "CreateUserInterface"}, | ||
| 141 | }; | ||
| 142 | // clang-format on | ||
| 143 | |||
| 144 | RegisterHandlers(functions); | ||
| 145 | } | ||
| 146 | |||
| 147 | private: | ||
| 148 | void CreateUserInterface(Kernel::HLERequestContext& ctx) { | ||
| 149 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 150 | rb.Push(RESULT_SUCCESS); | ||
| 151 | rb.PushIpcInterface<IUser>(); | ||
| 152 | |||
| 153 | LOG_DEBUG(Service_NFC, "called"); | ||
| 154 | } | ||
| 155 | }; | ||
| 156 | |||
| 157 | class ISystem final : public ServiceFramework<ISystem> { | ||
| 158 | public: | ||
| 159 | explicit ISystem() : ServiceFramework{"ISystem"} { | ||
| 160 | // clang-format off | ||
| 161 | static const FunctionInfo functions[] = { | ||
| 162 | {0, nullptr, "Initialize"}, | ||
| 163 | {1, nullptr, "Finalize"}, | ||
| 164 | {2, nullptr, "GetState"}, | ||
| 165 | {3, nullptr, "IsNfcEnabled"}, | ||
| 166 | {100, nullptr, "SetNfcEnabled"}, | ||
| 167 | {400, nullptr, "InitializeSystem"}, | ||
| 168 | {401, nullptr, "FinalizeSystem"}, | ||
| 169 | {402, nullptr, "GetState"}, | ||
| 170 | {403, nullptr, "IsNfcEnabled"}, | ||
| 171 | {404, nullptr, "ListDevices"}, | ||
| 172 | {405, nullptr, "GetDeviceState"}, | ||
| 173 | {406, nullptr, "GetNpadId"}, | ||
| 174 | {407, nullptr, "AttachAvailabilityChangeEvent"}, | ||
| 175 | {408, nullptr, "StartDetection"}, | ||
| 176 | {409, nullptr, "StopDetection"}, | ||
| 177 | {410, nullptr, "GetTagInfo"}, | ||
| 178 | {411, nullptr, "AttachActivateEvent"}, | ||
| 179 | {412, nullptr, "AttachDeactivateEvent"}, | ||
| 180 | {500, nullptr, "SetNfcEnabled"}, | ||
| 181 | {1000, nullptr, "ReadMifare"}, | ||
| 182 | {1001, nullptr, "WriteMifare"}, | ||
| 183 | {1300, nullptr, "SendCommandByPassThrough"}, | ||
| 184 | {1301, nullptr, "KeepPassThroughSession"}, | ||
| 185 | {1302, nullptr, "ReleasePassThroughSession"}, | ||
| 186 | }; | ||
| 187 | // clang-format on | ||
| 188 | |||
| 189 | RegisterHandlers(functions); | ||
| 190 | } | ||
| 191 | }; | ||
| 192 | |||
| 193 | class NFC_SYS final : public ServiceFramework<NFC_SYS> { | ||
| 194 | public: | ||
| 195 | explicit NFC_SYS() : ServiceFramework{"nfc:sys"} { | ||
| 196 | // clang-format off | ||
| 197 | static const FunctionInfo functions[] = { | ||
| 198 | {0, &NFC_SYS::CreateSystemInterface, "CreateSystemInterface"}, | ||
| 199 | }; | ||
| 200 | // clang-format on | ||
| 201 | |||
| 202 | RegisterHandlers(functions); | ||
| 203 | } | ||
| 204 | |||
| 205 | private: | ||
| 206 | void CreateSystemInterface(Kernel::HLERequestContext& ctx) { | ||
| 207 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 208 | rb.Push(RESULT_SUCCESS); | ||
| 209 | rb.PushIpcInterface<ISystem>(); | ||
| 210 | |||
| 211 | LOG_DEBUG(Service_NFC, "called"); | ||
| 212 | } | ||
| 213 | }; | ||
| 214 | |||
| 215 | void InstallInterfaces(SM::ServiceManager& sm) { | ||
| 216 | std::make_shared<NFC_AM>()->InstallAsService(sm); | ||
| 217 | std::make_shared<NFC_MF_U>()->InstallAsService(sm); | ||
| 218 | std::make_shared<NFC_U>()->InstallAsService(sm); | ||
| 219 | std::make_shared<NFC_SYS>()->InstallAsService(sm); | ||
| 220 | } | ||
| 221 | |||
| 222 | } // namespace Service::NFC | ||
diff --git a/src/core/hle/service/nfc/nfc.h b/src/core/hle/service/nfc/nfc.h new file mode 100644 index 000000000..4d2d815f9 --- /dev/null +++ b/src/core/hle/service/nfc/nfc.h | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | namespace Service::SM { | ||
| 8 | class ServiceManager; | ||
| 9 | } | ||
| 10 | |||
| 11 | namespace Service::NFC { | ||
| 12 | |||
| 13 | void InstallInterfaces(SM::ServiceManager& sm); | ||
| 14 | |||
| 15 | } // namespace Service::NFC | ||
diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp index 89c703310..98017267c 100644 --- a/src/core/hle/service/ns/ns.cpp +++ b/src/core/hle/service/ns/ns.cpp | |||
| @@ -2,12 +2,459 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "core/hle/ipc_helpers.h" | ||
| 6 | #include "core/hle/kernel/hle_ipc.h" | ||
| 5 | #include "core/hle/service/ns/ns.h" | 7 | #include "core/hle/service/ns/ns.h" |
| 6 | #include "core/hle/service/ns/pl_u.h" | 8 | #include "core/hle/service/ns/pl_u.h" |
| 7 | 9 | ||
| 8 | namespace Service::NS { | 10 | namespace Service::NS { |
| 9 | 11 | ||
| 12 | class IAccountProxyInterface final : public ServiceFramework<IAccountProxyInterface> { | ||
| 13 | public: | ||
| 14 | explicit IAccountProxyInterface() : ServiceFramework{"IAccountProxyInterface"} { | ||
| 15 | // clang-format off | ||
| 16 | static const FunctionInfo functions[] = { | ||
| 17 | {0, nullptr, "CreateUserAccount"}, | ||
| 18 | }; | ||
| 19 | // clang-format on | ||
| 20 | |||
| 21 | RegisterHandlers(functions); | ||
| 22 | } | ||
| 23 | }; | ||
| 24 | |||
| 25 | class IApplicationManagerInterface final : public ServiceFramework<IApplicationManagerInterface> { | ||
| 26 | public: | ||
| 27 | explicit IApplicationManagerInterface() : ServiceFramework{"IApplicationManagerInterface"} { | ||
| 28 | // clang-format off | ||
| 29 | static const FunctionInfo functions[] = { | ||
| 30 | {0, nullptr, "ListApplicationRecord"}, | ||
| 31 | {1, nullptr, "GenerateApplicationRecordCount"}, | ||
| 32 | {2, nullptr, "GetApplicationRecordUpdateSystemEvent"}, | ||
| 33 | {3, nullptr, "GetApplicationViewDeprecated"}, | ||
| 34 | {4, nullptr, "DeleteApplicationEntity"}, | ||
| 35 | {5, nullptr, "DeleteApplicationCompletely"}, | ||
| 36 | {6, nullptr, "IsAnyApplicationEntityRedundant"}, | ||
| 37 | {7, nullptr, "DeleteRedundantApplicationEntity"}, | ||
| 38 | {8, nullptr, "IsApplicationEntityMovable"}, | ||
| 39 | {9, nullptr, "MoveApplicationEntity"}, | ||
| 40 | {11, nullptr, "CalculateApplicationOccupiedSize"}, | ||
| 41 | {16, nullptr, "PushApplicationRecord"}, | ||
| 42 | {17, nullptr, "ListApplicationRecordContentMeta"}, | ||
| 43 | {19, nullptr, "LaunchApplication"}, | ||
| 44 | {21, nullptr, "GetApplicationContentPath"}, | ||
| 45 | {22, nullptr, "TerminateApplication"}, | ||
| 46 | {23, nullptr, "ResolveApplicationContentPath"}, | ||
| 47 | {26, nullptr, "BeginInstallApplication"}, | ||
| 48 | {27, nullptr, "DeleteApplicationRecord"}, | ||
| 49 | {30, nullptr, "RequestApplicationUpdateInfo"}, | ||
| 50 | {32, nullptr, "CancelApplicationDownload"}, | ||
| 51 | {33, nullptr, "ResumeApplicationDownload"}, | ||
| 52 | {35, nullptr, "UpdateVersionList"}, | ||
| 53 | {36, nullptr, "PushLaunchVersion"}, | ||
| 54 | {37, nullptr, "ListRequiredVersion"}, | ||
| 55 | {38, nullptr, "CheckApplicationLaunchVersion"}, | ||
| 56 | {39, nullptr, "CheckApplicationLaunchRights"}, | ||
| 57 | {40, nullptr, "GetApplicationLogoData"}, | ||
| 58 | {41, nullptr, "CalculateApplicationDownloadRequiredSize"}, | ||
| 59 | {42, nullptr, "CleanupSdCard"}, | ||
| 60 | {43, nullptr, "CheckSdCardMountStatus"}, | ||
| 61 | {44, nullptr, "GetSdCardMountStatusChangedEvent"}, | ||
| 62 | {45, nullptr, "GetGameCardAttachmentEvent"}, | ||
| 63 | {46, nullptr, "GetGameCardAttachmentInfo"}, | ||
| 64 | {47, nullptr, "GetTotalSpaceSize"}, | ||
| 65 | {48, nullptr, "GetFreeSpaceSize"}, | ||
| 66 | {49, nullptr, "GetSdCardRemovedEvent"}, | ||
| 67 | {52, nullptr, "GetGameCardUpdateDetectionEvent"}, | ||
| 68 | {53, nullptr, "DisableApplicationAutoDelete"}, | ||
| 69 | {54, nullptr, "EnableApplicationAutoDelete"}, | ||
| 70 | {55, nullptr, "GetApplicationDesiredLanguage"}, | ||
| 71 | {56, nullptr, "SetApplicationTerminateResult"}, | ||
| 72 | {57, nullptr, "ClearApplicationTerminateResult"}, | ||
| 73 | {58, nullptr, "GetLastSdCardMountUnexpectedResult"}, | ||
| 74 | {59, nullptr, "ConvertApplicationLanguageToLanguageCode"}, | ||
| 75 | {60, nullptr, "ConvertLanguageCodeToApplicationLanguage"}, | ||
| 76 | {61, nullptr, "GetBackgroundDownloadStressTaskInfo"}, | ||
| 77 | {62, nullptr, "GetGameCardStopper"}, | ||
| 78 | {63, nullptr, "IsSystemProgramInstalled"}, | ||
| 79 | {64, nullptr, "StartApplyDeltaTask"}, | ||
| 80 | {65, nullptr, "GetRequestServerStopper"}, | ||
| 81 | {66, nullptr, "GetBackgroundApplyDeltaStressTaskInfo"}, | ||
| 82 | {67, nullptr, "CancelApplicationApplyDelta"}, | ||
| 83 | {68, nullptr, "ResumeApplicationApplyDelta"}, | ||
| 84 | {69, nullptr, "CalculateApplicationApplyDeltaRequiredSize"}, | ||
| 85 | {70, nullptr, "ResumeAll"}, | ||
| 86 | {71, nullptr, "GetStorageSize"}, | ||
| 87 | {80, nullptr, "RequestDownloadApplication"}, | ||
| 88 | {81, nullptr, "RequestDownloadAddOnContent"}, | ||
| 89 | {82, nullptr, "DownloadApplication"}, | ||
| 90 | {83, nullptr, "CheckApplicationResumeRights"}, | ||
| 91 | {84, nullptr, "GetDynamicCommitEvent"}, | ||
| 92 | {85, nullptr, "RequestUpdateApplication2"}, | ||
| 93 | {86, nullptr, "EnableApplicationCrashReport"}, | ||
| 94 | {87, nullptr, "IsApplicationCrashReportEnabled"}, | ||
| 95 | {90, nullptr, "BoostSystemMemoryResourceLimit"}, | ||
| 96 | {100, nullptr, "ResetToFactorySettings"}, | ||
| 97 | {101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"}, | ||
| 98 | {102, nullptr, "ResetToFactorySettingsForRefurbishment"}, | ||
| 99 | {200, nullptr, "CalculateUserSaveDataStatistics"}, | ||
| 100 | {201, nullptr, "DeleteUserSaveDataAll"}, | ||
| 101 | {210, nullptr, "DeleteUserSystemSaveData"}, | ||
| 102 | {220, nullptr, "UnregisterNetworkServiceAccount"}, | ||
| 103 | {300, nullptr, "GetApplicationShellEvent"}, | ||
| 104 | {301, nullptr, "PopApplicationShellEventInfo"}, | ||
| 105 | {302, nullptr, "LaunchLibraryApplet"}, | ||
| 106 | {303, nullptr, "TerminateLibraryApplet"}, | ||
| 107 | {304, nullptr, "LaunchSystemApplet"}, | ||
| 108 | {305, nullptr, "TerminateSystemApplet"}, | ||
| 109 | {306, nullptr, "LaunchOverlayApplet"}, | ||
| 110 | {307, nullptr, "TerminateOverlayApplet"}, | ||
| 111 | {400, nullptr, "GetApplicationControlData"}, | ||
| 112 | {401, nullptr, "InvalidateAllApplicationControlCache"}, | ||
| 113 | {402, nullptr, "RequestDownloadApplicationControlData"}, | ||
| 114 | {403, nullptr, "GetMaxApplicationControlCacheCount"}, | ||
| 115 | {404, nullptr, "InvalidateApplicationControlCache"}, | ||
| 116 | {405, nullptr, "ListApplicationControlCacheEntryInfo"}, | ||
| 117 | {502, nullptr, "RequestCheckGameCardRegistration"}, | ||
| 118 | {503, nullptr, "RequestGameCardRegistrationGoldPoint"}, | ||
| 119 | {504, nullptr, "RequestRegisterGameCard"}, | ||
| 120 | {505, nullptr, "GetGameCardMountFailureEvent"}, | ||
| 121 | {506, nullptr, "IsGameCardInserted"}, | ||
| 122 | {507, nullptr, "EnsureGameCardAccess"}, | ||
| 123 | {508, nullptr, "GetLastGameCardMountFailureResult"}, | ||
| 124 | {509, nullptr, "ListApplicationIdOnGameCard"}, | ||
| 125 | {600, nullptr, "CountApplicationContentMeta"}, | ||
| 126 | {601, nullptr, "ListApplicationContentMetaStatus"}, | ||
| 127 | {602, nullptr, "ListAvailableAddOnContent"}, | ||
| 128 | {603, nullptr, "GetOwnedApplicationContentMetaStatus"}, | ||
| 129 | {604, nullptr, "RegisterContentsExternalKey"}, | ||
| 130 | {605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"}, | ||
| 131 | {606, nullptr, "GetContentMetaStorage"}, | ||
| 132 | {700, nullptr, "PushDownloadTaskList"}, | ||
| 133 | {701, nullptr, "ClearTaskStatusList"}, | ||
| 134 | {702, nullptr, "RequestDownloadTaskList"}, | ||
| 135 | {703, nullptr, "RequestEnsureDownloadTask"}, | ||
| 136 | {704, nullptr, "ListDownloadTaskStatus"}, | ||
| 137 | {705, nullptr, "RequestDownloadTaskListData"}, | ||
| 138 | {800, nullptr, "RequestVersionList"}, | ||
| 139 | {801, nullptr, "ListVersionList"}, | ||
| 140 | {802, nullptr, "RequestVersionListData"}, | ||
| 141 | {900, nullptr, "GetApplicationRecord"}, | ||
| 142 | {901, nullptr, "GetApplicationRecordProperty"}, | ||
| 143 | {902, nullptr, "EnableApplicationAutoUpdate"}, | ||
| 144 | {903, nullptr, "DisableApplicationAutoUpdate"}, | ||
| 145 | {904, nullptr, "TouchApplication"}, | ||
| 146 | {905, nullptr, "RequestApplicationUpdate"}, | ||
| 147 | {906, nullptr, "IsApplicationUpdateRequested"}, | ||
| 148 | {907, nullptr, "WithdrawApplicationUpdateRequest"}, | ||
| 149 | {908, nullptr, "ListApplicationRecordInstalledContentMeta"}, | ||
| 150 | {909, nullptr, "WithdrawCleanupAddOnContentsWithNoRightsRecommendation"}, | ||
| 151 | {1000, nullptr, "RequestVerifyApplicationDeprecated"}, | ||
| 152 | {1001, nullptr, "CorruptApplicationForDebug"}, | ||
| 153 | {1002, nullptr, "RequestVerifyAddOnContentsRights"}, | ||
| 154 | {1003, nullptr, "RequestVerifyApplication"}, | ||
| 155 | {1004, nullptr, "CorruptContentForDebug"}, | ||
| 156 | {1200, nullptr, "NeedsUpdateVulnerability"}, | ||
| 157 | {1300, nullptr, "IsAnyApplicationEntityInstalled"}, | ||
| 158 | {1301, nullptr, "DeleteApplicationContentEntities"}, | ||
| 159 | {1302, nullptr, "CleanupUnrecordedApplicationEntity"}, | ||
| 160 | {1303, nullptr, "CleanupAddOnContentsWithNoRights"}, | ||
| 161 | {1304, nullptr, "DeleteApplicationContentEntity"}, | ||
| 162 | {1305, nullptr, "TryDeleteRunningApplicationEntity"}, | ||
| 163 | {1306, nullptr, "TryDeleteRunningApplicationCompletely"}, | ||
| 164 | {1307, nullptr, "TryDeleteRunningApplicationContentEntities"}, | ||
| 165 | {1400, nullptr, "PrepareShutdown"}, | ||
| 166 | {1500, nullptr, "FormatSdCard"}, | ||
| 167 | {1501, nullptr, "NeedsSystemUpdateToFormatSdCard"}, | ||
| 168 | {1502, nullptr, "GetLastSdCardFormatUnexpectedResult"}, | ||
| 169 | {1504, nullptr, "InsertSdCard"}, | ||
| 170 | {1505, nullptr, "RemoveSdCard"}, | ||
| 171 | {1600, nullptr, "GetSystemSeedForPseudoDeviceId"}, | ||
| 172 | {1601, nullptr, "ResetSystemSeedForPseudoDeviceId"}, | ||
| 173 | {1700, nullptr, "ListApplicationDownloadingContentMeta"}, | ||
| 174 | {1701, nullptr, "GetApplicationView"}, | ||
| 175 | {1702, nullptr, "GetApplicationDownloadTaskStatus"}, | ||
| 176 | {1703, nullptr, "GetApplicationViewDownloadErrorContext"}, | ||
| 177 | {1800, nullptr, "IsNotificationSetupCompleted"}, | ||
| 178 | {1801, nullptr, "GetLastNotificationInfoCount"}, | ||
| 179 | {1802, nullptr, "ListLastNotificationInfo"}, | ||
| 180 | {1803, nullptr, "ListNotificationTask"}, | ||
| 181 | {1900, nullptr, "IsActiveAccount"}, | ||
| 182 | {1901, nullptr, "RequestDownloadApplicationPrepurchasedRights"}, | ||
| 183 | {1902, nullptr, "GetApplicationTicketInfo"}, | ||
| 184 | {2000, nullptr, "GetSystemDeliveryInfo"}, | ||
| 185 | {2001, nullptr, "SelectLatestSystemDeliveryInfo"}, | ||
| 186 | {2002, nullptr, "VerifyDeliveryProtocolVersion"}, | ||
| 187 | {2003, nullptr, "GetApplicationDeliveryInfo"}, | ||
| 188 | {2004, nullptr, "HasAllContentsToDeliver"}, | ||
| 189 | {2005, nullptr, "CompareApplicationDeliveryInfo"}, | ||
| 190 | {2006, nullptr, "CanDeliverApplication"}, | ||
| 191 | {2007, nullptr, "ListContentMetaKeyToDeliverApplication"}, | ||
| 192 | {2008, nullptr, "NeedsSystemUpdateToDeliverApplication"}, | ||
| 193 | {2009, nullptr, "EstimateRequiredSize"}, | ||
| 194 | {2010, nullptr, "RequestReceiveApplication"}, | ||
| 195 | {2011, nullptr, "CommitReceiveApplication"}, | ||
| 196 | {2012, nullptr, "GetReceiveApplicationProgress"}, | ||
| 197 | {2013, nullptr, "RequestSendApplication"}, | ||
| 198 | {2014, nullptr, "GetSendApplicationProgress"}, | ||
| 199 | {2015, nullptr, "CompareSystemDeliveryInfo"}, | ||
| 200 | {2016, nullptr, "ListNotCommittedContentMeta"}, | ||
| 201 | {2017, nullptr, "CreateDownloadTask"}, | ||
| 202 | }; | ||
| 203 | // clang-format on | ||
| 204 | |||
| 205 | RegisterHandlers(functions); | ||
| 206 | } | ||
| 207 | }; | ||
| 208 | |||
| 209 | class IApplicationVersionInterface final : public ServiceFramework<IApplicationVersionInterface> { | ||
| 210 | public: | ||
| 211 | explicit IApplicationVersionInterface() : ServiceFramework{"IApplicationVersionInterface"} { | ||
| 212 | // clang-format off | ||
| 213 | static const FunctionInfo functions[] = { | ||
| 214 | {0, nullptr, "GetLaunchRequiredVersion"}, | ||
| 215 | {1, nullptr, "UpgradeLaunchRequiredVersion"}, | ||
| 216 | {35, nullptr, "UpdateVersionList"}, | ||
| 217 | {36, nullptr, "PushLaunchVersion"}, | ||
| 218 | {37, nullptr, "ListRequiredVersion"}, | ||
| 219 | {800, nullptr, "RequestVersionList"}, | ||
| 220 | {801, nullptr, "ListVersionList"}, | ||
| 221 | {802, nullptr, "RequestVersionListData"}, | ||
| 222 | {1000, nullptr, "PerformAutoUpdate"}, | ||
| 223 | }; | ||
| 224 | // clang-format on | ||
| 225 | |||
| 226 | RegisterHandlers(functions); | ||
| 227 | } | ||
| 228 | }; | ||
| 229 | |||
| 230 | class IContentManagerInterface final : public ServiceFramework<IContentManagerInterface> { | ||
| 231 | public: | ||
| 232 | explicit IContentManagerInterface() : ServiceFramework{"IContentManagerInterface"} { | ||
| 233 | // clang-format off | ||
| 234 | static const FunctionInfo functions[] = { | ||
| 235 | {11, nullptr, "CalculateApplicationOccupiedSize"}, | ||
| 236 | {43, nullptr, "CheckSdCardMountStatus"}, | ||
| 237 | {47, nullptr, "GetTotalSpaceSize"}, | ||
| 238 | {48, nullptr, "GetFreeSpaceSize"}, | ||
| 239 | {600, nullptr, "CountApplicationContentMeta"}, | ||
| 240 | {601, nullptr, "ListApplicationContentMetaStatus"}, | ||
| 241 | {605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"}, | ||
| 242 | {607, nullptr, "IsAnyApplicationRunning"}, | ||
| 243 | }; | ||
| 244 | // clang-format on | ||
| 245 | |||
| 246 | RegisterHandlers(functions); | ||
| 247 | } | ||
| 248 | }; | ||
| 249 | |||
| 250 | class IDocumentInterface final : public ServiceFramework<IDocumentInterface> { | ||
| 251 | public: | ||
| 252 | explicit IDocumentInterface() : ServiceFramework{"IDocumentInterface"} { | ||
| 253 | // clang-format off | ||
| 254 | static const FunctionInfo functions[] = { | ||
| 255 | {21, nullptr, "GetApplicationContentPath"}, | ||
| 256 | {23, nullptr, "ResolveApplicationContentPath"}, | ||
| 257 | }; | ||
| 258 | // clang-format on | ||
| 259 | |||
| 260 | RegisterHandlers(functions); | ||
| 261 | } | ||
| 262 | }; | ||
| 263 | |||
| 264 | class IDownloadTaskInterface final : public ServiceFramework<IDownloadTaskInterface> { | ||
| 265 | public: | ||
| 266 | explicit IDownloadTaskInterface() : ServiceFramework{"IDownloadTaskInterface"} { | ||
| 267 | // clang-format off | ||
| 268 | static const FunctionInfo functions[] = { | ||
| 269 | {701, nullptr, "ClearTaskStatusList"}, | ||
| 270 | {702, nullptr, "RequestDownloadTaskList"}, | ||
| 271 | {703, nullptr, "RequestEnsureDownloadTask"}, | ||
| 272 | {704, nullptr, "ListDownloadTaskStatus"}, | ||
| 273 | {705, nullptr, "RequestDownloadTaskListData"}, | ||
| 274 | {706, nullptr, "TryCommitCurrentApplicationDownloadTask"}, | ||
| 275 | {707, nullptr, "EnableAutoCommit"}, | ||
| 276 | {708, nullptr, "DisableAutoCommit"}, | ||
| 277 | {709, nullptr, "TriggerDynamicCommitEvent"}, | ||
| 278 | }; | ||
| 279 | // clang-format on | ||
| 280 | |||
| 281 | RegisterHandlers(functions); | ||
| 282 | } | ||
| 283 | }; | ||
| 284 | |||
| 285 | class IECommerceInterface final : public ServiceFramework<IECommerceInterface> { | ||
| 286 | public: | ||
| 287 | explicit IECommerceInterface() : ServiceFramework{"IECommerceInterface"} { | ||
| 288 | // clang-format off | ||
| 289 | static const FunctionInfo functions[] = { | ||
| 290 | {0, nullptr, "RequestLinkDevice"}, | ||
| 291 | }; | ||
| 292 | // clang-format on | ||
| 293 | |||
| 294 | RegisterHandlers(functions); | ||
| 295 | } | ||
| 296 | }; | ||
| 297 | |||
| 298 | class IFactoryResetInterface final : public ServiceFramework<IFactoryResetInterface> { | ||
| 299 | public: | ||
| 300 | explicit IFactoryResetInterface() : ServiceFramework{"IFactoryResetInterface"} { | ||
| 301 | // clang-format off | ||
| 302 | static const FunctionInfo functions[] = { | ||
| 303 | {100, nullptr, "ResetToFactorySettings"}, | ||
| 304 | {101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"}, | ||
| 305 | {102, nullptr, "ResetToFactorySettingsForRefurbishment "}, | ||
| 306 | }; | ||
| 307 | // clang-format on | ||
| 308 | |||
| 309 | RegisterHandlers(functions); | ||
| 310 | } | ||
| 311 | }; | ||
| 312 | |||
| 313 | class NS final : public ServiceFramework<NS> { | ||
| 314 | public: | ||
| 315 | explicit NS(const char* name) : ServiceFramework{name} { | ||
| 316 | // clang-format off | ||
| 317 | static const FunctionInfo functions[] = { | ||
| 318 | {7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"}, | ||
| 319 | {7993, &NS::PushInterface<IApplicationVersionInterface>, "GetApplicationVersionInterface"}, | ||
| 320 | {7994, &NS::PushInterface<IFactoryResetInterface>, "GetFactoryResetInterface"}, | ||
| 321 | {7995, &NS::PushInterface<IAccountProxyInterface>, "GetAccountProxyInterface"}, | ||
| 322 | {7996, &NS::PushInterface<IApplicationManagerInterface>, "GetApplicationManagerInterface"}, | ||
| 323 | {7997, &NS::PushInterface<IDownloadTaskInterface>, "GetDownloadTaskInterface"}, | ||
| 324 | {7998, &NS::PushInterface<IContentManagerInterface>, "GetContentManagementInterface"}, | ||
| 325 | {7999, &NS::PushInterface<IDocumentInterface>, "GetDocumentInterface"}, | ||
| 326 | }; | ||
| 327 | // clang-format on | ||
| 328 | |||
| 329 | RegisterHandlers(functions); | ||
| 330 | } | ||
| 331 | |||
| 332 | private: | ||
| 333 | template <typename T> | ||
| 334 | void PushInterface(Kernel::HLERequestContext& ctx) { | ||
| 335 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 336 | rb.Push(RESULT_SUCCESS); | ||
| 337 | rb.PushIpcInterface<T>(); | ||
| 338 | |||
| 339 | LOG_DEBUG(Service_NS, "called"); | ||
| 340 | } | ||
| 341 | }; | ||
| 342 | |||
| 343 | class NS_DEV final : public ServiceFramework<NS_DEV> { | ||
| 344 | public: | ||
| 345 | explicit NS_DEV() : ServiceFramework{"ns:dev"} { | ||
| 346 | // clang-format off | ||
| 347 | static const FunctionInfo functions[] = { | ||
| 348 | {0, nullptr, "LaunchProgram"}, | ||
| 349 | {1, nullptr, "TerminateProcess"}, | ||
| 350 | {2, nullptr, "TerminateProgram"}, | ||
| 351 | {3, nullptr, "GetShellEventHandle"}, | ||
| 352 | {4, nullptr, "GetShellEventInfo"}, | ||
| 353 | {5, nullptr, "TerminateApplication"}, | ||
| 354 | {6, nullptr, "PrepareLaunchProgramFromHost"}, | ||
| 355 | {7, nullptr, "LaunchApplication"}, | ||
| 356 | {8, nullptr, "LaunchApplicationWithStorageId"}, | ||
| 357 | }; | ||
| 358 | // clang-format on | ||
| 359 | |||
| 360 | RegisterHandlers(functions); | ||
| 361 | } | ||
| 362 | }; | ||
| 363 | |||
| 364 | class ISystemUpdateControl final : public ServiceFramework<ISystemUpdateControl> { | ||
| 365 | public: | ||
| 366 | explicit ISystemUpdateControl() : ServiceFramework{"ISystemUpdateControl"} { | ||
| 367 | // clang-format off | ||
| 368 | static const FunctionInfo functions[] = { | ||
| 369 | {0, nullptr, "HasDownloaded"}, | ||
| 370 | {1, nullptr, "RequestCheckLatestUpdate"}, | ||
| 371 | {2, nullptr, "RequestDownloadLatestUpdate"}, | ||
| 372 | {3, nullptr, "GetDownloadProgress"}, | ||
| 373 | {4, nullptr, "ApplyDownloadedUpdate"}, | ||
| 374 | {5, nullptr, "RequestPrepareCardUpdate"}, | ||
| 375 | {6, nullptr, "GetPrepareCardUpdateProgress"}, | ||
| 376 | {7, nullptr, "HasPreparedCardUpdate"}, | ||
| 377 | {8, nullptr, "ApplyCardUpdate"}, | ||
| 378 | {9, nullptr, "GetDownloadedEulaDataSize"}, | ||
| 379 | {10, nullptr, "GetDownloadedEulaData"}, | ||
| 380 | {11, nullptr, "SetupCardUpdate"}, | ||
| 381 | {12, nullptr, "GetPreparedCardUpdateEulaDataSize"}, | ||
| 382 | {13, nullptr, "GetPreparedCardUpdateEulaData"}, | ||
| 383 | {14, nullptr, "SetupCardUpdateViaSystemUpdater"}, | ||
| 384 | {15, nullptr, "HasReceived"}, | ||
| 385 | {16, nullptr, "RequestReceiveSystemUpdate"}, | ||
| 386 | {17, nullptr, "GetReceiveProgress"}, | ||
| 387 | {18, nullptr, "ApplyReceivedUpdate"}, | ||
| 388 | {19, nullptr, "GetReceivedEulaDataSize"}, | ||
| 389 | {20, nullptr, "GetReceivedEulaData"}, | ||
| 390 | {21, nullptr, "SetupToReceiveSystemUpdate"}, | ||
| 391 | }; | ||
| 392 | // clang-format on | ||
| 393 | |||
| 394 | RegisterHandlers(functions); | ||
| 395 | } | ||
| 396 | }; | ||
| 397 | |||
| 398 | class NS_SU final : public ServiceFramework<NS_SU> { | ||
| 399 | public: | ||
| 400 | explicit NS_SU() : ServiceFramework{"ns:su"} { | ||
| 401 | // clang-format off | ||
| 402 | static const FunctionInfo functions[] = { | ||
| 403 | {0, nullptr, "GetBackgroundNetworkUpdateState"}, | ||
| 404 | {1, &NS_SU::OpenSystemUpdateControl, "OpenSystemUpdateControl"}, | ||
| 405 | {2, nullptr, "NotifyExFatDriverRequired"}, | ||
| 406 | {3, nullptr, "ClearExFatDriverStatusForDebug"}, | ||
| 407 | {4, nullptr, "RequestBackgroundNetworkUpdate"}, | ||
| 408 | {5, nullptr, "NotifyBackgroundNetworkUpdate"}, | ||
| 409 | {6, nullptr, "NotifyExFatDriverDownloadedForDebug"}, | ||
| 410 | {9, nullptr, "GetSystemUpdateNotificationEventForContentDelivery"}, | ||
| 411 | {10, nullptr, "NotifySystemUpdateForContentDelivery"}, | ||
| 412 | {11, nullptr, "PrepareShutdown"}, | ||
| 413 | {16, nullptr, "DestroySystemUpdateTask"}, | ||
| 414 | {17, nullptr, "RequestSendSystemUpdate"}, | ||
| 415 | {18, nullptr, "GetSendSystemUpdateProgress"}, | ||
| 416 | }; | ||
| 417 | // clang-format on | ||
| 418 | |||
| 419 | RegisterHandlers(functions); | ||
| 420 | } | ||
| 421 | |||
| 422 | private: | ||
| 423 | void OpenSystemUpdateControl(Kernel::HLERequestContext& ctx) { | ||
| 424 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 425 | rb.Push(RESULT_SUCCESS); | ||
| 426 | rb.PushIpcInterface<ISystemUpdateControl>(); | ||
| 427 | |||
| 428 | LOG_DEBUG(Service_NS, "called"); | ||
| 429 | } | ||
| 430 | }; | ||
| 431 | |||
| 432 | class NS_VM final : public ServiceFramework<NS_VM> { | ||
| 433 | public: | ||
| 434 | explicit NS_VM() : ServiceFramework{"ns:vm"} { | ||
| 435 | // clang-format off | ||
| 436 | static const FunctionInfo functions[] = { | ||
| 437 | {1200, nullptr, "NeedsUpdateVulnerability"}, | ||
| 438 | {1201, nullptr, "UpdateSafeSystemVersionForDebug"}, | ||
| 439 | {1202, nullptr, "GetSafeSystemVersion"}, | ||
| 440 | }; | ||
| 441 | // clang-format on | ||
| 442 | |||
| 443 | RegisterHandlers(functions); | ||
| 444 | } | ||
| 445 | }; | ||
| 446 | |||
| 10 | void InstallInterfaces(SM::ServiceManager& service_manager) { | 447 | void InstallInterfaces(SM::ServiceManager& service_manager) { |
| 448 | std::make_shared<NS>("ns:am2")->InstallAsService(service_manager); | ||
| 449 | std::make_shared<NS>("ns:ec")->InstallAsService(service_manager); | ||
| 450 | std::make_shared<NS>("ns:rid")->InstallAsService(service_manager); | ||
| 451 | std::make_shared<NS>("ns:rt")->InstallAsService(service_manager); | ||
| 452 | std::make_shared<NS>("ns:web")->InstallAsService(service_manager); | ||
| 453 | |||
| 454 | std::make_shared<NS_DEV>()->InstallAsService(service_manager); | ||
| 455 | std::make_shared<NS_SU>()->InstallAsService(service_manager); | ||
| 456 | std::make_shared<NS_VM>()->InstallAsService(service_manager); | ||
| 457 | |||
| 11 | std::make_shared<PL_U>()->InstallAsService(service_manager); | 458 | std::make_shared<PL_U>()->InstallAsService(service_manager); |
| 12 | } | 459 | } |
| 13 | 460 | ||
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index ed69a4325..8bc49935a 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp | |||
| @@ -7,8 +7,8 @@ | |||
| 7 | #include "core/core.h" | 7 | #include "core/core.h" |
| 8 | #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" | 8 | #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" |
| 9 | #include "core/hle/service/nvdrv/devices/nvmap.h" | 9 | #include "core/hle/service/nvdrv/devices/nvmap.h" |
| 10 | #include "video_core/gpu.h" | ||
| 10 | #include "video_core/renderer_base.h" | 11 | #include "video_core/renderer_base.h" |
| 11 | #include "video_core/video_core.h" | ||
| 12 | 12 | ||
| 13 | namespace Service::Nvidia::Devices { | 13 | namespace Service::Nvidia::Devices { |
| 14 | 14 | ||
| @@ -30,9 +30,9 @@ void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u3 | |||
| 30 | addr, offset, width, height, stride, static_cast<PixelFormat>(format), | 30 | addr, offset, width, height, stride, static_cast<PixelFormat>(format), |
| 31 | transform, crop_rect}; | 31 | transform, crop_rect}; |
| 32 | 32 | ||
| 33 | Core::System::GetInstance().perf_stats.EndGameFrame(); | 33 | auto& instance = Core::System::GetInstance(); |
| 34 | 34 | instance.perf_stats.EndGameFrame(); | |
| 35 | VideoCore::g_renderer->SwapBuffers(framebuffer); | 35 | instance.Renderer().SwapBuffers(framebuffer); |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | } // namespace Service::Nvidia::Devices | 38 | } // namespace Service::Nvidia::Devices |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp index 57b128b40..be2b79256 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp | |||
| @@ -2,14 +2,15 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <cinttypes> | 5 | #include <cstring> |
| 6 | #include "common/assert.h" | 6 | #include "common/assert.h" |
| 7 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 8 | #include "core/core.h" | 8 | #include "core/core.h" |
| 9 | #include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" | 9 | #include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" |
| 10 | #include "core/hle/service/nvdrv/devices/nvmap.h" | 10 | #include "core/hle/service/nvdrv/devices/nvmap.h" |
| 11 | #include "video_core/memory_manager.h" | ||
| 12 | #include "video_core/rasterizer_interface.h" | ||
| 11 | #include "video_core/renderer_base.h" | 13 | #include "video_core/renderer_base.h" |
| 12 | #include "video_core/video_core.h" | ||
| 13 | 14 | ||
| 14 | namespace Service::Nvidia::Devices { | 15 | namespace Service::Nvidia::Devices { |
| 15 | 16 | ||
| @@ -150,15 +151,16 @@ u32 nvhost_as_gpu::UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& ou | |||
| 150 | 151 | ||
| 151 | LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset); | 152 | LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset); |
| 152 | 153 | ||
| 153 | auto& gpu = Core::System::GetInstance().GPU(); | 154 | const auto itr = buffer_mappings.find(params.offset); |
| 154 | |||
| 155 | auto itr = buffer_mappings.find(params.offset); | ||
| 156 | |||
| 157 | ASSERT_MSG(itr != buffer_mappings.end(), "Tried to unmap invalid mapping"); | 155 | ASSERT_MSG(itr != buffer_mappings.end(), "Tried to unmap invalid mapping"); |
| 158 | 156 | ||
| 157 | auto& system_instance = Core::System::GetInstance(); | ||
| 158 | |||
| 159 | // Remove this memory region from the rasterizer cache. | 159 | // Remove this memory region from the rasterizer cache. |
| 160 | VideoCore::g_renderer->Rasterizer()->FlushAndInvalidateRegion(params.offset, itr->second.size); | 160 | system_instance.Renderer().Rasterizer().FlushAndInvalidateRegion(params.offset, |
| 161 | itr->second.size); | ||
| 161 | 162 | ||
| 163 | auto& gpu = system_instance.GPU(); | ||
| 162 | params.offset = gpu.memory_manager->UnmapBuffer(params.offset, itr->second.size); | 164 | params.offset = gpu.memory_manager->UnmapBuffer(params.offset, itr->second.size); |
| 163 | 165 | ||
| 164 | buffer_mappings.erase(itr->second.offset); | 166 | buffer_mappings.erase(itr->second.offset); |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index 671b092e1..5685eb2be 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp | |||
| @@ -2,6 +2,9 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <cstdlib> | ||
| 6 | #include <cstring> | ||
| 7 | |||
| 5 | #include "common/assert.h" | 8 | #include "common/assert.h" |
| 6 | #include "common/logging/log.h" | 9 | #include "common/logging/log.h" |
| 7 | #include "core/hle/service/nvdrv/devices/nvhost_ctrl.h" | 10 | #include "core/hle/service/nvdrv/devices/nvhost_ctrl.h" |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h index 090261a60..6b496e9fe 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <cstdlib> | ||
| 9 | #include <cstring> | ||
| 10 | #include <vector> | 8 | #include <vector> |
| 11 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 12 | #include "core/hle/service/nvdrv/devices/nvdevice.h" | 10 | #include "core/hle/service/nvdrv/devices/nvdevice.h" |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp index 44e062f50..ae421247d 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <cinttypes> | 5 | #include <cstring> |
| 6 | #include "common/assert.h" | 6 | #include "common/assert.h" |
| 7 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 8 | #include "core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h" | 8 | #include "core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h" |
| @@ -97,7 +97,9 @@ u32 nvhost_ctrl_gpu::GetTPCMasks(const std::vector<u8>& input, std::vector<u8>& | |||
| 97 | u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::vector<u8>& output) { | 97 | u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::vector<u8>& output) { |
| 98 | LOG_DEBUG(Service_NVDRV, "called"); | 98 | LOG_DEBUG(Service_NVDRV, "called"); |
| 99 | IoctlActiveSlotMask params{}; | 99 | IoctlActiveSlotMask params{}; |
| 100 | std::memcpy(¶ms, input.data(), input.size()); | 100 | if (input.size() > 0) { |
| 101 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 102 | } | ||
| 101 | params.slot = 0x07; | 103 | params.slot = 0x07; |
| 102 | params.mask = 0x01; | 104 | params.mask = 0x01; |
| 103 | std::memcpy(output.data(), ¶ms, output.size()); | 105 | std::memcpy(output.data(), ¶ms, output.size()); |
| @@ -107,7 +109,9 @@ u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::vector | |||
| 107 | u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u8>& output) { | 109 | u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u8>& output) { |
| 108 | LOG_DEBUG(Service_NVDRV, "called"); | 110 | LOG_DEBUG(Service_NVDRV, "called"); |
| 109 | IoctlZcullGetCtxSize params{}; | 111 | IoctlZcullGetCtxSize params{}; |
| 110 | std::memcpy(¶ms, input.data(), input.size()); | 112 | if (input.size() > 0) { |
| 113 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 114 | } | ||
| 111 | params.size = 0x1; | 115 | params.size = 0x1; |
| 112 | std::memcpy(output.data(), ¶ms, output.size()); | 116 | std::memcpy(output.data(), ¶ms, output.size()); |
| 113 | return 0; | 117 | return 0; |
| @@ -116,7 +120,11 @@ u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u | |||
| 116 | u32 nvhost_ctrl_gpu::ZCullGetInfo(const std::vector<u8>& input, std::vector<u8>& output) { | 120 | u32 nvhost_ctrl_gpu::ZCullGetInfo(const std::vector<u8>& input, std::vector<u8>& output) { |
| 117 | LOG_DEBUG(Service_NVDRV, "called"); | 121 | LOG_DEBUG(Service_NVDRV, "called"); |
| 118 | IoctlNvgpuGpuZcullGetInfoArgs params{}; | 122 | IoctlNvgpuGpuZcullGetInfoArgs params{}; |
| 119 | std::memcpy(¶ms, input.data(), input.size()); | 123 | |
| 124 | if (input.size() > 0) { | ||
| 125 | std::memcpy(¶ms, input.data(), input.size()); | ||
| 126 | } | ||
| 127 | |||
| 120 | params.width_align_pixels = 0x20; | 128 | params.width_align_pixels = 0x20; |
| 121 | params.height_align_pixels = 0x20; | 129 | params.height_align_pixels = 0x20; |
| 122 | params.pixel_squares_by_aliquots = 0x400; | 130 | params.pixel_squares_by_aliquots = 0x400; |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index 126782573..116dabedb 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp | |||
| @@ -2,12 +2,14 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <cinttypes> | 5 | #include <cstring> |
| 6 | #include <map> | ||
| 7 | #include "common/assert.h" | 6 | #include "common/assert.h" |
| 8 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 9 | #include "core/core.h" | 8 | #include "core/core.h" |
| 10 | #include "core/hle/service/nvdrv/devices/nvhost_gpu.h" | 9 | #include "core/hle/service/nvdrv/devices/nvhost_gpu.h" |
| 10 | #include "core/memory.h" | ||
| 11 | #include "video_core/gpu.h" | ||
| 12 | #include "video_core/memory_manager.h" | ||
| 11 | 13 | ||
| 12 | namespace Service::Nvidia::Devices { | 14 | namespace Service::Nvidia::Devices { |
| 13 | 15 | ||
| @@ -132,9 +134,12 @@ u32 nvhost_gpu::SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& outp | |||
| 132 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo={:X}, num_entries={:X}, flags={:X}", | 134 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo={:X}, num_entries={:X}, flags={:X}", |
| 133 | params.address, params.num_entries, params.flags); | 135 | params.address, params.num_entries, params.flags); |
| 134 | 136 | ||
| 135 | auto entries = std::vector<IoctlGpfifoEntry>(); | 137 | ASSERT_MSG(input.size() == |
| 136 | entries.resize(params.num_entries); | 138 | sizeof(IoctlSubmitGpfifo) + params.num_entries * sizeof(IoctlGpfifoEntry), |
| 137 | std::memcpy(&entries[0], &input.data()[sizeof(IoctlSubmitGpfifo)], | 139 | "Incorrect input size"); |
| 140 | |||
| 141 | std::vector<IoctlGpfifoEntry> entries(params.num_entries); | ||
| 142 | std::memcpy(entries.data(), &input[sizeof(IoctlSubmitGpfifo)], | ||
| 138 | params.num_entries * sizeof(IoctlGpfifoEntry)); | 143 | params.num_entries * sizeof(IoctlGpfifoEntry)); |
| 139 | for (auto entry : entries) { | 144 | for (auto entry : entries) { |
| 140 | Tegra::GPUVAddr va_addr = entry.Address(); | 145 | Tegra::GPUVAddr va_addr = entry.Address(); |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h index aa8df2e6e..650ed8fbc 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <vector> | 8 | #include <vector> |
| 9 | #include "common/bit_field.h" | ||
| 9 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 10 | #include "common/swap.h" | 11 | #include "common/swap.h" |
| 11 | #include "core/hle/service/nvdrv/devices/nvdevice.h" | 12 | #include "core/hle/service/nvdrv/devices/nvdevice.h" |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp index b51c73ee8..364619e67 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <cstring> | ||
| 6 | |||
| 5 | #include "common/assert.h" | 7 | #include "common/assert.h" |
| 6 | #include "common/logging/log.h" | 8 | #include "common/logging/log.h" |
| 7 | #include "core/hle/service/nvdrv/devices/nvhost_nvdec.h" | 9 | #include "core/hle/service/nvdrv/devices/nvhost_nvdec.h" |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h index 0192aecdd..6ad74421b 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h | |||
| @@ -4,11 +4,9 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | ||
| 8 | #include <cstdlib> | ||
| 9 | #include <cstring> | ||
| 10 | #include <vector> | 7 | #include <vector> |
| 11 | #include "common/common_types.h" | 8 | #include "common/common_types.h" |
| 9 | #include "common/swap.h" | ||
| 12 | #include "core/hle/service/nvdrv/devices/nvdevice.h" | 10 | #include "core/hle/service/nvdrv/devices/nvdevice.h" |
| 13 | 11 | ||
| 14 | namespace Service::Nvidia::Devices { | 12 | namespace Service::Nvidia::Devices { |
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp index 724eeb139..e9305bfb3 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.cpp +++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | #include <cinttypes> | 6 | #include <cstring> |
| 7 | 7 | ||
| 8 | #include "common/assert.h" | 8 | #include "common/assert.h" |
| 9 | #include "common/logging/log.h" | 9 | #include "common/logging/log.h" |
diff --git a/src/core/hle/service/nvdrv/interface.h b/src/core/hle/service/nvdrv/interface.h index 959b5ba29..1c3529bb6 100644 --- a/src/core/hle/service/nvdrv/interface.h +++ b/src/core/hle/service/nvdrv/interface.h | |||
| @@ -5,7 +5,6 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <string> | ||
| 9 | #include "core/hle/kernel/event.h" | 8 | #include "core/hle/kernel/event.h" |
| 10 | #include "core/hle/service/nvdrv/nvdrv.h" | 9 | #include "core/hle/service/nvdrv/nvdrv.h" |
| 11 | #include "core/hle/service/service.h" | 10 | #include "core/hle/service/service.h" |
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp index 1555ea806..e8b30921a 100644 --- a/src/core/hle/service/nvdrv/nvdrv.cpp +++ b/src/core/hle/service/nvdrv/nvdrv.cpp | |||
| @@ -54,7 +54,7 @@ u32 Module::Open(const std::string& device_name) { | |||
| 54 | return fd; | 54 | return fd; |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | u32 Module::Ioctl(u32 fd, u32_le command, const std::vector<u8>& input, std::vector<u8>& output) { | 57 | u32 Module::Ioctl(u32 fd, u32 command, const std::vector<u8>& input, std::vector<u8>& output) { |
| 58 | auto itr = open_files.find(fd); | 58 | auto itr = open_files.find(fd); |
| 59 | ASSERT_MSG(itr != open_files.end(), "Tried to talk to an invalid device"); | 59 | ASSERT_MSG(itr != open_files.end(), "Tried to talk to an invalid device"); |
| 60 | 60 | ||
diff --git a/src/core/hle/service/nvdrv/nvmemp.cpp b/src/core/hle/service/nvdrv/nvmemp.cpp index 9ca6e5512..0e8e21bad 100644 --- a/src/core/hle/service/nvdrv/nvmemp.cpp +++ b/src/core/hle/service/nvdrv/nvmemp.cpp | |||
| @@ -4,8 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | #include "common/assert.h" | 5 | #include "common/assert.h" |
| 6 | #include "common/logging/log.h" | 6 | #include "common/logging/log.h" |
| 7 | #include "core/hle/ipc_helpers.h" | ||
| 8 | #include "core/hle/service/nvdrv/nvdrv.h" | ||
| 9 | #include "core/hle/service/nvdrv/nvmemp.h" | 7 | #include "core/hle/service/nvdrv/nvmemp.h" |
| 10 | 8 | ||
| 11 | namespace Service::Nvidia { | 9 | namespace Service::Nvidia { |
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index 7132b18ad..adf180509 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp | |||
| @@ -4,9 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | 6 | ||
| 7 | #include "common/alignment.h" | 7 | #include "common/assert.h" |
| 8 | #include "common/scope_exit.h" | 8 | #include "common/logging/log.h" |
| 9 | #include "core/core_timing.h" | ||
| 10 | #include "core/hle/service/nvflinger/buffer_queue.h" | 9 | #include "core/hle/service/nvflinger/buffer_queue.h" |
| 11 | 10 | ||
| 12 | namespace Service { | 11 | namespace Service { |
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index 5344441e1..570aa8493 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp | |||
| @@ -3,8 +3,11 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | #include <boost/optional.hpp> | ||
| 6 | 7 | ||
| 7 | #include "common/alignment.h" | 8 | #include "common/alignment.h" |
| 9 | #include "common/assert.h" | ||
| 10 | #include "common/logging/log.h" | ||
| 8 | #include "common/microprofile.h" | 11 | #include "common/microprofile.h" |
| 9 | #include "common/scope_exit.h" | 12 | #include "common/scope_exit.h" |
| 10 | #include "core/core.h" | 13 | #include "core/core.h" |
| @@ -31,7 +34,7 @@ NVFlinger::NVFlinger() { | |||
| 31 | 34 | ||
| 32 | // Schedule the screen composition events | 35 | // Schedule the screen composition events |
| 33 | composition_event = | 36 | composition_event = |
| 34 | CoreTiming::RegisterEvent("ScreenCompositioin", [this](u64 userdata, int cycles_late) { | 37 | CoreTiming::RegisterEvent("ScreenComposition", [this](u64 userdata, int cycles_late) { |
| 35 | Compose(); | 38 | Compose(); |
| 36 | CoreTiming::ScheduleEvent(frame_ticks - cycles_late, composition_event); | 39 | CoreTiming::ScheduleEvent(frame_ticks - cycles_late, composition_event); |
| 37 | }); | 40 | }); |
| @@ -43,7 +46,7 @@ NVFlinger::~NVFlinger() { | |||
| 43 | CoreTiming::UnscheduleEvent(composition_event, 0); | 46 | CoreTiming::UnscheduleEvent(composition_event, 0); |
| 44 | } | 47 | } |
| 45 | 48 | ||
| 46 | u64 NVFlinger::OpenDisplay(const std::string& name) { | 49 | u64 NVFlinger::OpenDisplay(std::string_view name) { |
| 47 | LOG_WARNING(Service, "Opening display {}", name); | 50 | LOG_WARNING(Service, "Opening display {}", name); |
| 48 | 51 | ||
| 49 | // TODO(Subv): Currently we only support the Default display. | 52 | // TODO(Subv): Currently we only support the Default display. |
| @@ -127,9 +130,11 @@ void NVFlinger::Compose() { | |||
| 127 | MicroProfileFlip(); | 130 | MicroProfileFlip(); |
| 128 | 131 | ||
| 129 | if (buffer == boost::none) { | 132 | if (buffer == boost::none) { |
| 133 | auto& system_instance = Core::System::GetInstance(); | ||
| 134 | |||
| 130 | // There was no queued buffer to draw, render previous frame | 135 | // There was no queued buffer to draw, render previous frame |
| 131 | Core::System::GetInstance().perf_stats.EndGameFrame(); | 136 | system_instance.perf_stats.EndGameFrame(); |
| 132 | VideoCore::g_renderer->SwapBuffers({}); | 137 | system_instance.Renderer().SwapBuffers({}); |
| 133 | continue; | 138 | continue; |
| 134 | } | 139 | } |
| 135 | 140 | ||
diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h index 2c908297b..5374df175 100644 --- a/src/core/hle/service/nvflinger/nvflinger.h +++ b/src/core/hle/service/nvflinger/nvflinger.h | |||
| @@ -5,7 +5,11 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <boost/optional.hpp> | 8 | #include <string> |
| 9 | #include <string_view> | ||
| 10 | #include <vector> | ||
| 11 | |||
| 12 | #include "common/common_types.h" | ||
| 9 | #include "core/hle/kernel/event.h" | 13 | #include "core/hle/kernel/event.h" |
| 10 | 14 | ||
| 11 | namespace CoreTiming { | 15 | namespace CoreTiming { |
| @@ -41,7 +45,7 @@ public: | |||
| 41 | ~NVFlinger(); | 45 | ~NVFlinger(); |
| 42 | 46 | ||
| 43 | /// Opens the specified display and returns the id. | 47 | /// Opens the specified display and returns the id. |
| 44 | u64 OpenDisplay(const std::string& name); | 48 | u64 OpenDisplay(std::string_view name); |
| 45 | 49 | ||
| 46 | /// Creates a layer on the specified display and returns the layer id. | 50 | /// Creates a layer on the specified display and returns the layer id. |
| 47 | u64 CreateLayer(u64 display_id); | 51 | u64 CreateLayer(u64 display_id); |
diff --git a/src/core/hle/service/pcie/pcie.cpp b/src/core/hle/service/pcie/pcie.cpp new file mode 100644 index 000000000..39cf05eba --- /dev/null +++ b/src/core/hle/service/pcie/pcie.cpp | |||
| @@ -0,0 +1,64 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <memory> | ||
| 6 | |||
| 7 | #include "core/hle/service/pcie/pcie.h" | ||
| 8 | #include "core/hle/service/service.h" | ||
| 9 | #include "core/hle/service/sm/sm.h" | ||
| 10 | |||
| 11 | namespace Service::PCIe { | ||
| 12 | |||
| 13 | class ISession final : public ServiceFramework<ISession> { | ||
| 14 | public: | ||
| 15 | explicit ISession() : ServiceFramework{"ISession"} { | ||
| 16 | // clang-format off | ||
| 17 | static const FunctionInfo functions[] = { | ||
| 18 | {0, nullptr, "QueryFunctions"}, | ||
| 19 | {1, nullptr, "AcquireFunction"}, | ||
| 20 | {2, nullptr, "ReleaseFunction"}, | ||
| 21 | {3, nullptr, "GetFunctionState"}, | ||
| 22 | {4, nullptr, "GetBarProfile"}, | ||
| 23 | {5, nullptr, "ReadConfig"}, | ||
| 24 | {6, nullptr, "WriteConfig"}, | ||
| 25 | {7, nullptr, "ReadBarRegion"}, | ||
| 26 | {8, nullptr, "WriteBarRegion"}, | ||
| 27 | {9, nullptr, "FindCapability"}, | ||
| 28 | {10, nullptr, "FindExtendedCapability"}, | ||
| 29 | {11, nullptr, "MapDma"}, | ||
| 30 | {12, nullptr, "UnmapDma"}, | ||
| 31 | {13, nullptr, "UnmapDmaBusAddress"}, | ||
| 32 | {14, nullptr, "GetDmaBusAddress"}, | ||
| 33 | {15, nullptr, "GetDmaBusAddressRange"}, | ||
| 34 | {16, nullptr, "SetDmaEnable"}, | ||
| 35 | {17, nullptr, "AcquireIrq"}, | ||
| 36 | {18, nullptr, "ReleaseIrq"}, | ||
| 37 | {19, nullptr, "SetIrqEnable"}, | ||
| 38 | {20, nullptr, "SetAspmEnable"}, | ||
| 39 | }; | ||
| 40 | // clang-format on | ||
| 41 | |||
| 42 | RegisterHandlers(functions); | ||
| 43 | } | ||
| 44 | }; | ||
| 45 | |||
| 46 | class PCIe final : public ServiceFramework<PCIe> { | ||
| 47 | public: | ||
| 48 | explicit PCIe() : ServiceFramework{"pcie"} { | ||
| 49 | // clang-format off | ||
| 50 | static const FunctionInfo functions[] = { | ||
| 51 | {0, nullptr, "RegisterClassDriver"}, | ||
| 52 | {1, nullptr, "QueryFunctionsUnregistered"}, | ||
| 53 | }; | ||
| 54 | // clang-format on | ||
| 55 | |||
| 56 | RegisterHandlers(functions); | ||
| 57 | } | ||
| 58 | }; | ||
| 59 | |||
| 60 | void InstallInterfaces(SM::ServiceManager& sm) { | ||
| 61 | std::make_shared<PCIe>()->InstallAsService(sm); | ||
| 62 | } | ||
| 63 | |||
| 64 | } // namespace Service::PCIe | ||
diff --git a/src/core/hle/service/pcie/pcie.h b/src/core/hle/service/pcie/pcie.h new file mode 100644 index 000000000..59c22ca45 --- /dev/null +++ b/src/core/hle/service/pcie/pcie.h | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | namespace Service::SM { | ||
| 8 | class ServiceManager; | ||
| 9 | } | ||
| 10 | |||
| 11 | namespace Service::PCIe { | ||
| 12 | |||
| 13 | void InstallInterfaces(SM::ServiceManager& sm); | ||
| 14 | |||
| 15 | } // namespace Service::PCIe | ||
diff --git a/src/core/hle/service/pcv/pcv.cpp b/src/core/hle/service/pcv/pcv.cpp new file mode 100644 index 000000000..d6891a659 --- /dev/null +++ b/src/core/hle/service/pcv/pcv.cpp | |||
| @@ -0,0 +1,84 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <memory> | ||
| 6 | |||
| 7 | #include "core/hle/service/pcv/pcv.h" | ||
| 8 | #include "core/hle/service/service.h" | ||
| 9 | #include "core/hle/service/sm/sm.h" | ||
| 10 | |||
| 11 | namespace Service::PCV { | ||
| 12 | |||
| 13 | class PCV final : public ServiceFramework<PCV> { | ||
| 14 | public: | ||
| 15 | explicit PCV() : ServiceFramework{"pcv"} { | ||
| 16 | // clang-format off | ||
| 17 | static const FunctionInfo functions[] = { | ||
| 18 | {0, nullptr, "SetPowerEnabled"}, | ||
| 19 | {1, nullptr, "SetClockEnabled"}, | ||
| 20 | {2, nullptr, "SetClockRate"}, | ||
| 21 | {3, nullptr, "GetClockRate"}, | ||
| 22 | {4, nullptr, "GetState"}, | ||
| 23 | {5, nullptr, "GetPossibleClockRates"}, | ||
| 24 | {6, nullptr, "SetMinVClockRate"}, | ||
| 25 | {7, nullptr, "SetReset"}, | ||
| 26 | {8, nullptr, "SetVoltageEnabled"}, | ||
| 27 | {9, nullptr, "GetVoltageEnabled"}, | ||
| 28 | {10, nullptr, "GetVoltageRange"}, | ||
| 29 | {11, nullptr, "SetVoltageValue"}, | ||
| 30 | {12, nullptr, "GetVoltageValue"}, | ||
| 31 | {13, nullptr, "GetTemperatureThresholds"}, | ||
| 32 | {14, nullptr, "SetTemperature"}, | ||
| 33 | {15, nullptr, "Initialize"}, | ||
| 34 | {16, nullptr, "IsInitialized"}, | ||
| 35 | {17, nullptr, "Finalize"}, | ||
| 36 | {18, nullptr, "PowerOn"}, | ||
| 37 | {19, nullptr, "PowerOff"}, | ||
| 38 | {20, nullptr, "ChangeVoltage"}, | ||
| 39 | {21, nullptr, "GetPowerClockInfoEvent"}, | ||
| 40 | {22, nullptr, "GetOscillatorClock"}, | ||
| 41 | {23, nullptr, "GetDvfsTable"}, | ||
| 42 | {24, nullptr, "GetModuleStateTable"}, | ||
| 43 | {25, nullptr, "GetPowerDomainStateTable"}, | ||
| 44 | {26, nullptr, "GetFuseInfo"}, | ||
| 45 | }; | ||
| 46 | // clang-format on | ||
| 47 | |||
| 48 | RegisterHandlers(functions); | ||
| 49 | } | ||
| 50 | }; | ||
| 51 | |||
| 52 | class PCV_ARB final : public ServiceFramework<PCV_ARB> { | ||
| 53 | public: | ||
| 54 | explicit PCV_ARB() : ServiceFramework{"pcv:arb"} { | ||
| 55 | // clang-format off | ||
| 56 | static const FunctionInfo functions[] = { | ||
| 57 | {0, nullptr, "ReleaseControl"}, | ||
| 58 | }; | ||
| 59 | // clang-format on | ||
| 60 | |||
| 61 | RegisterHandlers(functions); | ||
| 62 | } | ||
| 63 | }; | ||
| 64 | |||
| 65 | class PCV_IMM final : public ServiceFramework<PCV_IMM> { | ||
| 66 | public: | ||
| 67 | explicit PCV_IMM() : ServiceFramework{"pcv:imm"} { | ||
| 68 | // clang-format off | ||
| 69 | static const FunctionInfo functions[] = { | ||
| 70 | {0, nullptr, "SetClockRate"}, | ||
| 71 | }; | ||
| 72 | // clang-format on | ||
| 73 | |||
| 74 | RegisterHandlers(functions); | ||
| 75 | } | ||
| 76 | }; | ||
| 77 | |||
| 78 | void InstallInterfaces(SM::ServiceManager& sm) { | ||
| 79 | std::make_shared<PCV>()->InstallAsService(sm); | ||
| 80 | std::make_shared<PCV_ARB>()->InstallAsService(sm); | ||
| 81 | std::make_shared<PCV_IMM>()->InstallAsService(sm); | ||
| 82 | } | ||
| 83 | |||
| 84 | } // namespace Service::PCV | ||
diff --git a/src/core/hle/service/pcv/pcv.h b/src/core/hle/service/pcv/pcv.h new file mode 100644 index 000000000..219a893c3 --- /dev/null +++ b/src/core/hle/service/pcv/pcv.h | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | namespace Service::SM { | ||
| 8 | class ServiceManager; | ||
| 9 | } | ||
| 10 | |||
| 11 | namespace Service::PCV { | ||
| 12 | |||
| 13 | void InstallInterfaces(SM::ServiceManager& sm); | ||
| 14 | |||
| 15 | } // namespace Service::PCV | ||
diff --git a/src/core/hle/service/psc/psc.cpp b/src/core/hle/service/psc/psc.cpp new file mode 100644 index 000000000..bbad870a2 --- /dev/null +++ b/src/core/hle/service/psc/psc.cpp | |||
| @@ -0,0 +1,77 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <memory> | ||
| 6 | |||
| 7 | #include "common/logging/log.h" | ||
| 8 | #include "core/hle/ipc_helpers.h" | ||
| 9 | #include "core/hle/service/psc/psc.h" | ||
| 10 | #include "core/hle/service/service.h" | ||
| 11 | #include "core/hle/service/sm/sm.h" | ||
| 12 | |||
| 13 | namespace Service::PSC { | ||
| 14 | |||
| 15 | class PSC_C final : public ServiceFramework<PSC_C> { | ||
| 16 | public: | ||
| 17 | explicit PSC_C() : ServiceFramework{"psc:c"} { | ||
| 18 | // clang-format off | ||
| 19 | static const FunctionInfo functions[] = { | ||
| 20 | {0, nullptr, "Unknown1"}, | ||
| 21 | {1, nullptr, "Unknown2"}, | ||
| 22 | {2, nullptr, "Unknown3"}, | ||
| 23 | {3, nullptr, "Unknown4"}, | ||
| 24 | {4, nullptr, "Unknown5"}, | ||
| 25 | {5, nullptr, "Unknown6"}, | ||
| 26 | {6, nullptr, "Unknown7"}, | ||
| 27 | }; | ||
| 28 | // clang-format on | ||
| 29 | |||
| 30 | RegisterHandlers(functions); | ||
| 31 | } | ||
| 32 | }; | ||
| 33 | |||
| 34 | class IPmModule final : public ServiceFramework<IPmModule> { | ||
| 35 | public: | ||
| 36 | explicit IPmModule() : ServiceFramework{"IPmModule"} { | ||
| 37 | // clang-format off | ||
| 38 | static const FunctionInfo functions[] = { | ||
| 39 | {0, nullptr, "Initialize"}, | ||
| 40 | {1, nullptr, "GetRequest"}, | ||
| 41 | {2, nullptr, "Acknowledge"}, | ||
| 42 | {3, nullptr, "Unknown1"}, | ||
| 43 | }; | ||
| 44 | // clang-format on | ||
| 45 | |||
| 46 | RegisterHandlers(functions); | ||
| 47 | } | ||
| 48 | }; | ||
| 49 | |||
| 50 | class PSC_M final : public ServiceFramework<PSC_M> { | ||
| 51 | public: | ||
| 52 | explicit PSC_M() : ServiceFramework{"psc:m"} { | ||
| 53 | // clang-format off | ||
| 54 | static const FunctionInfo functions[] = { | ||
| 55 | {0, &PSC_M::GetPmModule, "GetPmModule"}, | ||
| 56 | }; | ||
| 57 | // clang-format on | ||
| 58 | |||
| 59 | RegisterHandlers(functions); | ||
| 60 | } | ||
| 61 | |||
| 62 | private: | ||
| 63 | void GetPmModule(Kernel::HLERequestContext& ctx) { | ||
| 64 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 65 | rb.Push(RESULT_SUCCESS); | ||
| 66 | rb.PushIpcInterface<IPmModule>(); | ||
| 67 | |||
| 68 | LOG_DEBUG(Service_PSC, "called"); | ||
| 69 | } | ||
| 70 | }; | ||
| 71 | |||
| 72 | void InstallInterfaces(SM::ServiceManager& sm) { | ||
| 73 | std::make_shared<PSC_C>()->InstallAsService(sm); | ||
| 74 | std::make_shared<PSC_M>()->InstallAsService(sm); | ||
| 75 | } | ||
| 76 | |||
| 77 | } // namespace Service::PSC | ||
diff --git a/src/core/hle/service/psc/psc.h b/src/core/hle/service/psc/psc.h new file mode 100644 index 000000000..5052eb02c --- /dev/null +++ b/src/core/hle/service/psc/psc.h | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | namespace Service::SM { | ||
| 8 | class ServiceManager; | ||
| 9 | } | ||
| 10 | |||
| 11 | namespace Service::PSC { | ||
| 12 | |||
| 13 | void InstallInterfaces(SM::ServiceManager& sm); | ||
| 14 | |||
| 15 | } // namespace Service::PSC | ||
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 8b84fd349..889cdd41a 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp | |||
| @@ -19,28 +19,42 @@ | |||
| 19 | #include "core/hle/service/am/am.h" | 19 | #include "core/hle/service/am/am.h" |
| 20 | #include "core/hle/service/aoc/aoc_u.h" | 20 | #include "core/hle/service/aoc/aoc_u.h" |
| 21 | #include "core/hle/service/apm/apm.h" | 21 | #include "core/hle/service/apm/apm.h" |
| 22 | #include "core/hle/service/arp/arp.h" | ||
| 22 | #include "core/hle/service/audio/audio.h" | 23 | #include "core/hle/service/audio/audio.h" |
| 23 | #include "core/hle/service/bcat/bcat.h" | 24 | #include "core/hle/service/bcat/bcat.h" |
| 25 | #include "core/hle/service/bpc/bpc.h" | ||
| 26 | #include "core/hle/service/btdrv/btdrv.h" | ||
| 27 | #include "core/hle/service/btm/btm.h" | ||
| 28 | #include "core/hle/service/caps/caps.h" | ||
| 24 | #include "core/hle/service/erpt/erpt.h" | 29 | #include "core/hle/service/erpt/erpt.h" |
| 25 | #include "core/hle/service/es/es.h" | 30 | #include "core/hle/service/es/es.h" |
| 26 | #include "core/hle/service/eupld/eupld.h" | 31 | #include "core/hle/service/eupld/eupld.h" |
| 27 | #include "core/hle/service/fatal/fatal.h" | 32 | #include "core/hle/service/fatal/fatal.h" |
| 33 | #include "core/hle/service/fgm/fgm.h" | ||
| 28 | #include "core/hle/service/filesystem/filesystem.h" | 34 | #include "core/hle/service/filesystem/filesystem.h" |
| 29 | #include "core/hle/service/friend/friend.h" | 35 | #include "core/hle/service/friend/friend.h" |
| 30 | #include "core/hle/service/grc/grc.h" | 36 | #include "core/hle/service/grc/grc.h" |
| 31 | #include "core/hle/service/hid/hid.h" | 37 | #include "core/hle/service/hid/hid.h" |
| 38 | #include "core/hle/service/lbl/lbl.h" | ||
| 32 | #include "core/hle/service/ldn/ldn.h" | 39 | #include "core/hle/service/ldn/ldn.h" |
| 33 | #include "core/hle/service/ldr/ldr.h" | 40 | #include "core/hle/service/ldr/ldr.h" |
| 34 | #include "core/hle/service/lm/lm.h" | 41 | #include "core/hle/service/lm/lm.h" |
| 42 | #include "core/hle/service/mig/mig.h" | ||
| 43 | #include "core/hle/service/mii/mii.h" | ||
| 35 | #include "core/hle/service/mm/mm_u.h" | 44 | #include "core/hle/service/mm/mm_u.h" |
| 45 | #include "core/hle/service/ncm/ncm.h" | ||
| 46 | #include "core/hle/service/nfc/nfc.h" | ||
| 36 | #include "core/hle/service/nfp/nfp.h" | 47 | #include "core/hle/service/nfp/nfp.h" |
| 37 | #include "core/hle/service/nifm/nifm.h" | 48 | #include "core/hle/service/nifm/nifm.h" |
| 38 | #include "core/hle/service/nim/nim.h" | 49 | #include "core/hle/service/nim/nim.h" |
| 39 | #include "core/hle/service/ns/ns.h" | 50 | #include "core/hle/service/ns/ns.h" |
| 40 | #include "core/hle/service/nvdrv/nvdrv.h" | 51 | #include "core/hle/service/nvdrv/nvdrv.h" |
| 52 | #include "core/hle/service/pcie/pcie.h" | ||
| 41 | #include "core/hle/service/pctl/pctl.h" | 53 | #include "core/hle/service/pctl/pctl.h" |
| 54 | #include "core/hle/service/pcv/pcv.h" | ||
| 42 | #include "core/hle/service/pm/pm.h" | 55 | #include "core/hle/service/pm/pm.h" |
| 43 | #include "core/hle/service/prepo/prepo.h" | 56 | #include "core/hle/service/prepo/prepo.h" |
| 57 | #include "core/hle/service/psc/psc.h" | ||
| 44 | #include "core/hle/service/service.h" | 58 | #include "core/hle/service/service.h" |
| 45 | #include "core/hle/service/set/settings.h" | 59 | #include "core/hle/service/set/settings.h" |
| 46 | #include "core/hle/service/sm/controller.h" | 60 | #include "core/hle/service/sm/controller.h" |
| @@ -49,7 +63,9 @@ | |||
| 49 | #include "core/hle/service/spl/module.h" | 63 | #include "core/hle/service/spl/module.h" |
| 50 | #include "core/hle/service/ssl/ssl.h" | 64 | #include "core/hle/service/ssl/ssl.h" |
| 51 | #include "core/hle/service/time/time.h" | 65 | #include "core/hle/service/time/time.h" |
| 66 | #include "core/hle/service/usb/usb.h" | ||
| 52 | #include "core/hle/service/vi/vi.h" | 67 | #include "core/hle/service/vi/vi.h" |
| 68 | #include "core/hle/service/wlan/wlan.h" | ||
| 53 | 69 | ||
| 54 | using Kernel::ClientPort; | 70 | using Kernel::ClientPort; |
| 55 | using Kernel::ServerPort; | 71 | using Kernel::ServerPort; |
| @@ -193,34 +209,50 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm) { | |||
| 193 | AM::InstallInterfaces(*sm, nv_flinger); | 209 | AM::InstallInterfaces(*sm, nv_flinger); |
| 194 | AOC::InstallInterfaces(*sm); | 210 | AOC::InstallInterfaces(*sm); |
| 195 | APM::InstallInterfaces(*sm); | 211 | APM::InstallInterfaces(*sm); |
| 196 | BCAT::InstallInterfaces(*sm); | 212 | ARP::InstallInterfaces(*sm); |
| 197 | Audio::InstallInterfaces(*sm); | 213 | Audio::InstallInterfaces(*sm); |
| 214 | BCAT::InstallInterfaces(*sm); | ||
| 215 | BPC::InstallInterfaces(*sm); | ||
| 216 | BtDrv::InstallInterfaces(*sm); | ||
| 217 | BTM::InstallInterfaces(*sm); | ||
| 218 | Capture::InstallInterfaces(*sm); | ||
| 198 | ERPT::InstallInterfaces(*sm); | 219 | ERPT::InstallInterfaces(*sm); |
| 199 | ES::InstallInterfaces(*sm); | 220 | ES::InstallInterfaces(*sm); |
| 200 | EUPLD::InstallInterfaces(*sm); | 221 | EUPLD::InstallInterfaces(*sm); |
| 201 | Fatal::InstallInterfaces(*sm); | 222 | Fatal::InstallInterfaces(*sm); |
| 223 | FGM::InstallInterfaces(*sm); | ||
| 202 | FileSystem::InstallInterfaces(*sm); | 224 | FileSystem::InstallInterfaces(*sm); |
| 203 | Friend::InstallInterfaces(*sm); | 225 | Friend::InstallInterfaces(*sm); |
| 204 | GRC::InstallInterfaces(*sm); | 226 | GRC::InstallInterfaces(*sm); |
| 205 | HID::InstallInterfaces(*sm); | 227 | HID::InstallInterfaces(*sm); |
| 228 | LBL::InstallInterfaces(*sm); | ||
| 206 | LDN::InstallInterfaces(*sm); | 229 | LDN::InstallInterfaces(*sm); |
| 207 | LDR::InstallInterfaces(*sm); | 230 | LDR::InstallInterfaces(*sm); |
| 208 | LM::InstallInterfaces(*sm); | 231 | LM::InstallInterfaces(*sm); |
| 232 | Migration::InstallInterfaces(*sm); | ||
| 233 | Mii::InstallInterfaces(*sm); | ||
| 209 | MM::InstallInterfaces(*sm); | 234 | MM::InstallInterfaces(*sm); |
| 235 | NCM::InstallInterfaces(*sm); | ||
| 236 | NFC::InstallInterfaces(*sm); | ||
| 210 | NFP::InstallInterfaces(*sm); | 237 | NFP::InstallInterfaces(*sm); |
| 211 | NIFM::InstallInterfaces(*sm); | 238 | NIFM::InstallInterfaces(*sm); |
| 212 | NIM::InstallInterfaces(*sm); | 239 | NIM::InstallInterfaces(*sm); |
| 213 | NS::InstallInterfaces(*sm); | 240 | NS::InstallInterfaces(*sm); |
| 214 | Nvidia::InstallInterfaces(*sm); | 241 | Nvidia::InstallInterfaces(*sm); |
| 242 | PCIe::InstallInterfaces(*sm); | ||
| 215 | PCTL::InstallInterfaces(*sm); | 243 | PCTL::InstallInterfaces(*sm); |
| 244 | PCV::InstallInterfaces(*sm); | ||
| 216 | PlayReport::InstallInterfaces(*sm); | 245 | PlayReport::InstallInterfaces(*sm); |
| 217 | PM::InstallInterfaces(*sm); | 246 | PM::InstallInterfaces(*sm); |
| 247 | PSC::InstallInterfaces(*sm); | ||
| 248 | Set::InstallInterfaces(*sm); | ||
| 218 | Sockets::InstallInterfaces(*sm); | 249 | Sockets::InstallInterfaces(*sm); |
| 219 | SPL::InstallInterfaces(*sm); | 250 | SPL::InstallInterfaces(*sm); |
| 220 | SSL::InstallInterfaces(*sm); | 251 | SSL::InstallInterfaces(*sm); |
| 221 | Time::InstallInterfaces(*sm); | 252 | Time::InstallInterfaces(*sm); |
| 253 | USB::InstallInterfaces(*sm); | ||
| 222 | VI::InstallInterfaces(*sm, nv_flinger); | 254 | VI::InstallInterfaces(*sm, nv_flinger); |
| 223 | Set::InstallInterfaces(*sm); | 255 | WLAN::InstallInterfaces(*sm); |
| 224 | 256 | ||
| 225 | LOG_DEBUG(Service, "initialized OK"); | 257 | LOG_DEBUG(Service, "initialized OK"); |
| 226 | } | 258 | } |
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 180f22703..046c5e18d 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h | |||
| @@ -8,10 +8,9 @@ | |||
| 8 | #include <string> | 8 | #include <string> |
| 9 | #include <unordered_map> | 9 | #include <unordered_map> |
| 10 | #include <boost/container/flat_map.hpp> | 10 | #include <boost/container/flat_map.hpp> |
| 11 | #include "common/bit_field.h" | ||
| 12 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| 13 | #include "core/hle/kernel/hle_ipc.h" | 12 | #include "core/hle/kernel/hle_ipc.h" |
| 14 | #include "core/hle/kernel/kernel.h" | 13 | #include "core/hle/kernel/object.h" |
| 15 | 14 | ||
| 16 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 15 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 17 | // Namespace Service | 16 | // Namespace Service |
diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp index 1651f6122..a461e72ec 100644 --- a/src/core/hle/service/set/set.cpp +++ b/src/core/hle/service/set/set.cpp | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include "core/hle/kernel/client_port.h" | 8 | #include "core/hle/kernel/client_port.h" |
| 9 | #include "core/hle/kernel/client_session.h" | 9 | #include "core/hle/kernel/client_session.h" |
| 10 | #include "core/hle/service/set/set.h" | 10 | #include "core/hle/service/set/set.h" |
| 11 | #include "core/settings.h" | ||
| 11 | 12 | ||
| 12 | namespace Service::Set { | 13 | namespace Service::Set { |
| 13 | 14 | ||
| @@ -31,6 +32,10 @@ constexpr std::array<LanguageCode, 17> available_language_codes = {{ | |||
| 31 | LanguageCode::ZH_HANT, | 32 | LanguageCode::ZH_HANT, |
| 32 | }}; | 33 | }}; |
| 33 | 34 | ||
| 35 | LanguageCode GetLanguageCodeFromIndex(size_t index) { | ||
| 36 | return available_language_codes.at(index); | ||
| 37 | } | ||
| 38 | |||
| 34 | void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) { | 39 | void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) { |
| 35 | ctx.WriteBuffer(available_language_codes); | 40 | ctx.WriteBuffer(available_language_codes); |
| 36 | 41 | ||
| @@ -49,9 +54,17 @@ void SET::GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx) { | |||
| 49 | LOG_DEBUG(Service_SET, "called"); | 54 | LOG_DEBUG(Service_SET, "called"); |
| 50 | } | 55 | } |
| 51 | 56 | ||
| 57 | void SET::GetLanguageCode(Kernel::HLERequestContext& ctx) { | ||
| 58 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 59 | rb.Push(RESULT_SUCCESS); | ||
| 60 | rb.Push(static_cast<u64>(available_language_codes[Settings::values.language_index])); | ||
| 61 | |||
| 62 | LOG_DEBUG(Service_SET, "called {}", Settings::values.language_index); | ||
| 63 | } | ||
| 64 | |||
| 52 | SET::SET() : ServiceFramework("set") { | 65 | SET::SET() : ServiceFramework("set") { |
| 53 | static const FunctionInfo functions[] = { | 66 | static const FunctionInfo functions[] = { |
| 54 | {0, nullptr, "GetLanguageCode"}, | 67 | {0, &SET::GetLanguageCode, "GetLanguageCode"}, |
| 55 | {1, &SET::GetAvailableLanguageCodes, "GetAvailableLanguageCodes"}, | 68 | {1, &SET::GetAvailableLanguageCodes, "GetAvailableLanguageCodes"}, |
| 56 | {2, nullptr, "MakeLanguageCode"}, | 69 | {2, nullptr, "MakeLanguageCode"}, |
| 57 | {3, &SET::GetAvailableLanguageCodeCount, "GetAvailableLanguageCodeCount"}, | 70 | {3, &SET::GetAvailableLanguageCodeCount, "GetAvailableLanguageCodeCount"}, |
diff --git a/src/core/hle/service/set/set.h b/src/core/hle/service/set/set.h index a2472ec4c..4232b6162 100644 --- a/src/core/hle/service/set/set.h +++ b/src/core/hle/service/set/set.h | |||
| @@ -28,6 +28,7 @@ enum class LanguageCode : u64 { | |||
| 28 | ZH_HANS = 0x00736E61482D687A, | 28 | ZH_HANS = 0x00736E61482D687A, |
| 29 | ZH_HANT = 0x00746E61482D687A, | 29 | ZH_HANT = 0x00746E61482D687A, |
| 30 | }; | 30 | }; |
| 31 | LanguageCode GetLanguageCodeFromIndex(size_t idx); | ||
| 31 | 32 | ||
| 32 | class SET final : public ServiceFramework<SET> { | 33 | class SET final : public ServiceFramework<SET> { |
| 33 | public: | 34 | public: |
| @@ -35,6 +36,7 @@ public: | |||
| 35 | ~SET() = default; | 36 | ~SET() = default; |
| 36 | 37 | ||
| 37 | private: | 38 | private: |
| 39 | void GetLanguageCode(Kernel::HLERequestContext& ctx); | ||
| 38 | void GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx); | 40 | void GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx); |
| 39 | void GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx); | 41 | void GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx); |
| 40 | }; | 42 | }; |
diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h index e2a00e4f6..e8ea62f08 100644 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h | |||
| @@ -4,9 +4,11 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <memory> | ||
| 7 | #include <string> | 8 | #include <string> |
| 8 | #include <unordered_map> | 9 | #include <unordered_map> |
| 9 | #include "core/hle/kernel/kernel.h" | 10 | |
| 11 | #include "core/hle/kernel/object.h" | ||
| 10 | #include "core/hle/result.h" | 12 | #include "core/hle/result.h" |
| 11 | #include "core/hle/service/service.h" | 13 | #include "core/hle/service/service.h" |
| 12 | 14 | ||
| @@ -19,6 +21,8 @@ class SessionRequestHandler; | |||
| 19 | 21 | ||
| 20 | namespace Service::SM { | 22 | namespace Service::SM { |
| 21 | 23 | ||
| 24 | class Controller; | ||
| 25 | |||
| 22 | /// Interface to "sm:" service | 26 | /// Interface to "sm:" service |
| 23 | class SM final : public ServiceFramework<SM> { | 27 | class SM final : public ServiceFramework<SM> { |
| 24 | public: | 28 | public: |
| @@ -32,8 +36,6 @@ private: | |||
| 32 | std::shared_ptr<ServiceManager> service_manager; | 36 | std::shared_ptr<ServiceManager> service_manager; |
| 33 | }; | 37 | }; |
| 34 | 38 | ||
| 35 | class Controller; | ||
| 36 | |||
| 37 | constexpr ResultCode ERR_SERVICE_NOT_REGISTERED(-1); | 39 | constexpr ResultCode ERR_SERVICE_NOT_REGISTERED(-1); |
| 38 | constexpr ResultCode ERR_MAX_CONNECTIONS_REACHED(-1); | 40 | constexpr ResultCode ERR_MAX_CONNECTIONS_REACHED(-1); |
| 39 | constexpr ResultCode ERR_INVALID_NAME_SIZE(-1); | 41 | constexpr ResultCode ERR_INVALID_NAME_SIZE(-1); |
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index 37b58bb77..2172c681b 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp | |||
| @@ -80,8 +80,8 @@ public: | |||
| 80 | {5, nullptr, "GetTimeZoneRuleVersion"}, | 80 | {5, nullptr, "GetTimeZoneRuleVersion"}, |
| 81 | {100, &ITimeZoneService::ToCalendarTime, "ToCalendarTime"}, | 81 | {100, &ITimeZoneService::ToCalendarTime, "ToCalendarTime"}, |
| 82 | {101, &ITimeZoneService::ToCalendarTimeWithMyRule, "ToCalendarTimeWithMyRule"}, | 82 | {101, &ITimeZoneService::ToCalendarTimeWithMyRule, "ToCalendarTimeWithMyRule"}, |
| 83 | {200, nullptr, "ToPosixTime"}, | 83 | {201, nullptr, "ToPosixTime"}, |
| 84 | {201, nullptr, "ToPosixTimeWithMyRule"}, | 84 | {202, nullptr, "ToPosixTimeWithMyRule"}, |
| 85 | }; | 85 | }; |
| 86 | RegisterHandlers(functions); | 86 | RegisterHandlers(functions); |
| 87 | } | 87 | } |
diff --git a/src/core/hle/service/usb/usb.cpp b/src/core/hle/service/usb/usb.cpp new file mode 100644 index 000000000..e7fb5a419 --- /dev/null +++ b/src/core/hle/service/usb/usb.cpp | |||
| @@ -0,0 +1,238 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <memory> | ||
| 6 | |||
| 7 | #include "common/logging/log.h" | ||
| 8 | #include "core/hle/ipc_helpers.h" | ||
| 9 | #include "core/hle/kernel/hle_ipc.h" | ||
| 10 | #include "core/hle/service/service.h" | ||
| 11 | #include "core/hle/service/sm/sm.h" | ||
| 12 | #include "core/hle/service/usb/usb.h" | ||
| 13 | |||
| 14 | namespace Service::USB { | ||
| 15 | |||
| 16 | class IDsInterface final : public ServiceFramework<IDsInterface> { | ||
| 17 | public: | ||
| 18 | explicit IDsInterface() : ServiceFramework{"IDsInterface"} { | ||
| 19 | // clang-format off | ||
| 20 | static const FunctionInfo functions[] = { | ||
| 21 | {0, nullptr, "GetDsEndpoint"}, | ||
| 22 | {1, nullptr, "GetSetupEvent"}, | ||
| 23 | {2, nullptr, "Unknown"}, | ||
| 24 | {3, nullptr, "EnableInterface"}, | ||
| 25 | {4, nullptr, "DisableInterface"}, | ||
| 26 | {5, nullptr, "CtrlInPostBufferAsync"}, | ||
| 27 | {6, nullptr, "CtrlOutPostBufferAsync"}, | ||
| 28 | {7, nullptr, "GetCtrlInCompletionEvent"}, | ||
| 29 | {8, nullptr, "GetCtrlInReportData"}, | ||
| 30 | {9, nullptr, "GetCtrlOutCompletionEvent"}, | ||
| 31 | {10, nullptr, "GetCtrlOutReportData"}, | ||
| 32 | {11, nullptr, "StallCtrl"}, | ||
| 33 | {12, nullptr, "AppendConfigurationData"}, | ||
| 34 | }; | ||
| 35 | // clang-format on | ||
| 36 | |||
| 37 | RegisterHandlers(functions); | ||
| 38 | } | ||
| 39 | }; | ||
| 40 | |||
| 41 | class USB_DS final : public ServiceFramework<USB_DS> { | ||
| 42 | public: | ||
| 43 | explicit USB_DS() : ServiceFramework{"usb:ds"} { | ||
| 44 | // clang-format off | ||
| 45 | static const FunctionInfo functions[] = { | ||
| 46 | {0, nullptr, "BindDevice"}, | ||
| 47 | {1, nullptr, "BindClientProcess"}, | ||
| 48 | {2, nullptr, "GetDsInterface"}, | ||
| 49 | {3, nullptr, "GetStateChangeEvent"}, | ||
| 50 | {4, nullptr, "GetState"}, | ||
| 51 | {5, nullptr, "ClearDeviceData"}, | ||
| 52 | {6, nullptr, "AddUsbStringDescriptor"}, | ||
| 53 | {7, nullptr, "DeleteUsbStringDescriptor"}, | ||
| 54 | {8, nullptr, "SetUsbDeviceDescriptor"}, | ||
| 55 | {9, nullptr, "SetBinaryObjectStore"}, | ||
| 56 | {10, nullptr, "Enable"}, | ||
| 57 | {11, nullptr, "Disable"}, | ||
| 58 | }; | ||
| 59 | // clang-format on | ||
| 60 | |||
| 61 | RegisterHandlers(functions); | ||
| 62 | } | ||
| 63 | }; | ||
| 64 | |||
| 65 | class IClientEpSession final : public ServiceFramework<IClientEpSession> { | ||
| 66 | public: | ||
| 67 | explicit IClientEpSession() : ServiceFramework{"IClientEpSession"} { | ||
| 68 | // clang-format off | ||
| 69 | static const FunctionInfo functions[] = { | ||
| 70 | {0, nullptr, "Unknown1"}, | ||
| 71 | {1, nullptr, "Unknown2"}, | ||
| 72 | {2, nullptr, "Unknown3"}, | ||
| 73 | {3, nullptr, "Unknown4"}, | ||
| 74 | {4, nullptr, "PostBufferAsync"}, | ||
| 75 | {5, nullptr, "Unknown5"}, | ||
| 76 | {6, nullptr, "Unknown6"}, | ||
| 77 | {7, nullptr, "Unknown7"}, | ||
| 78 | {8, nullptr, "Unknown8"}, | ||
| 79 | }; | ||
| 80 | // clang-format on | ||
| 81 | |||
| 82 | RegisterHandlers(functions); | ||
| 83 | } | ||
| 84 | }; | ||
| 85 | |||
| 86 | class IClientIfSession final : public ServiceFramework<IClientIfSession> { | ||
| 87 | public: | ||
| 88 | explicit IClientIfSession() : ServiceFramework{"IClientIfSession"} { | ||
| 89 | // clang-format off | ||
| 90 | static const FunctionInfo functions[] = { | ||
| 91 | {0, nullptr, "Unknown1"}, | ||
| 92 | {1, nullptr, "Unknown2"}, | ||
| 93 | {2, nullptr, "Unknown3"}, | ||
| 94 | {3, nullptr, "Unknown4"}, | ||
| 95 | {4, nullptr, "Unknown5"}, | ||
| 96 | {5, nullptr, "CtrlXferAsync"}, | ||
| 97 | {6, nullptr, "Unknown6"}, | ||
| 98 | {7, nullptr, "GetCtrlXferReport"}, | ||
| 99 | {8, nullptr, "Unknown7"}, | ||
| 100 | {9, nullptr, "GetClientEpSession"}, | ||
| 101 | }; | ||
| 102 | // clang-format on | ||
| 103 | |||
| 104 | RegisterHandlers(functions); | ||
| 105 | } | ||
| 106 | }; | ||
| 107 | |||
| 108 | class USB_HS final : public ServiceFramework<USB_HS> { | ||
| 109 | public: | ||
| 110 | explicit USB_HS() : ServiceFramework{"usb:hs"} { | ||
| 111 | // clang-format off | ||
| 112 | static const FunctionInfo functions[] = { | ||
| 113 | {0, nullptr, "BindClientProcess"}, | ||
| 114 | {1, nullptr, "Unknown1"}, | ||
| 115 | {2, nullptr, "Unknown2"}, | ||
| 116 | {3, nullptr, "Unknown3"}, | ||
| 117 | {4, nullptr, "Unknown4"}, | ||
| 118 | {5, nullptr, "Unknown5"}, | ||
| 119 | {6, nullptr, "GetInterfaceStateChangeEvent"}, | ||
| 120 | {7, nullptr, "GetClientIfSession"}, | ||
| 121 | }; | ||
| 122 | // clang-format on | ||
| 123 | |||
| 124 | RegisterHandlers(functions); | ||
| 125 | } | ||
| 126 | }; | ||
| 127 | |||
| 128 | class IPdSession final : public ServiceFramework<IPdSession> { | ||
| 129 | public: | ||
| 130 | explicit IPdSession() : ServiceFramework{"IPdSession"} { | ||
| 131 | // clang-format off | ||
| 132 | static const FunctionInfo functions[] = { | ||
| 133 | {0, nullptr, "BindNoticeEvent"}, | ||
| 134 | {1, nullptr, "Unknown1"}, | ||
| 135 | {2, nullptr, "GetStatus"}, | ||
| 136 | {3, nullptr, "GetNotice"}, | ||
| 137 | {4, nullptr, "Unknown2"}, | ||
| 138 | {5, nullptr, "Unknown3"}, | ||
| 139 | {6, nullptr, "ReplyPowerRequest"}, | ||
| 140 | }; | ||
| 141 | // clang-format on | ||
| 142 | |||
| 143 | RegisterHandlers(functions); | ||
| 144 | } | ||
| 145 | }; | ||
| 146 | |||
| 147 | class USB_PD final : public ServiceFramework<USB_PD> { | ||
| 148 | public: | ||
| 149 | explicit USB_PD() : ServiceFramework{"usb:pd"} { | ||
| 150 | // clang-format off | ||
| 151 | static const FunctionInfo functions[] = { | ||
| 152 | {0, &USB_PD::GetPdSession, "GetPdSession"}, | ||
| 153 | }; | ||
| 154 | // clang-format on | ||
| 155 | |||
| 156 | RegisterHandlers(functions); | ||
| 157 | } | ||
| 158 | |||
| 159 | private: | ||
| 160 | void GetPdSession(Kernel::HLERequestContext& ctx) { | ||
| 161 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 162 | rb.Push(RESULT_SUCCESS); | ||
| 163 | rb.PushIpcInterface<IPdSession>(); | ||
| 164 | |||
| 165 | LOG_DEBUG(Service_USB, "called"); | ||
| 166 | } | ||
| 167 | }; | ||
| 168 | |||
| 169 | class IPdCradleSession final : public ServiceFramework<IPdCradleSession> { | ||
| 170 | public: | ||
| 171 | explicit IPdCradleSession() : ServiceFramework{"IPdCradleSession"} { | ||
| 172 | // clang-format off | ||
| 173 | static const FunctionInfo functions[] = { | ||
| 174 | {0, nullptr, "VdmUserWrite"}, | ||
| 175 | {1, nullptr, "VdmUserRead"}, | ||
| 176 | {2, nullptr, "Vdm20Init"}, | ||
| 177 | {3, nullptr, "GetFwType"}, | ||
| 178 | {4, nullptr, "GetFwRevision"}, | ||
| 179 | {5, nullptr, "GetManufacturerId"}, | ||
| 180 | {6, nullptr, "GetDeviceId"}, | ||
| 181 | {7, nullptr, "Unknown1"}, | ||
| 182 | {8, nullptr, "Unknown2"}, | ||
| 183 | }; | ||
| 184 | // clang-format on | ||
| 185 | |||
| 186 | RegisterHandlers(functions); | ||
| 187 | } | ||
| 188 | }; | ||
| 189 | |||
| 190 | class USB_PD_C final : public ServiceFramework<USB_PD_C> { | ||
| 191 | public: | ||
| 192 | explicit USB_PD_C() : ServiceFramework{"usb:pd:c"} { | ||
| 193 | // clang-format off | ||
| 194 | static const FunctionInfo functions[] = { | ||
| 195 | {0, &USB_PD_C::GetPdCradleSession, "GetPdCradleSession"}, | ||
| 196 | }; | ||
| 197 | // clang-format on | ||
| 198 | |||
| 199 | RegisterHandlers(functions); | ||
| 200 | } | ||
| 201 | |||
| 202 | private: | ||
| 203 | void GetPdCradleSession(Kernel::HLERequestContext& ctx) { | ||
| 204 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 205 | rb.Push(RESULT_SUCCESS); | ||
| 206 | rb.PushIpcInterface<IPdCradleSession>(); | ||
| 207 | |||
| 208 | LOG_DEBUG(Service_USB, "called"); | ||
| 209 | } | ||
| 210 | }; | ||
| 211 | |||
| 212 | class USB_PM final : public ServiceFramework<USB_PM> { | ||
| 213 | public: | ||
| 214 | explicit USB_PM() : ServiceFramework{"usb:pm"} { | ||
| 215 | // clang-format off | ||
| 216 | static const FunctionInfo functions[] = { | ||
| 217 | {0, nullptr, "Unknown1"}, | ||
| 218 | {1, nullptr, "Unknown2"}, | ||
| 219 | {2, nullptr, "Unknown3"}, | ||
| 220 | {3, nullptr, "Unknown4"}, | ||
| 221 | {4, nullptr, "Unknown5"}, | ||
| 222 | {5, nullptr, "Unknown6"}, | ||
| 223 | }; | ||
| 224 | // clang-format on | ||
| 225 | |||
| 226 | RegisterHandlers(functions); | ||
| 227 | } | ||
| 228 | }; | ||
| 229 | |||
| 230 | void InstallInterfaces(SM::ServiceManager& sm) { | ||
| 231 | std::make_shared<USB_DS>()->InstallAsService(sm); | ||
| 232 | std::make_shared<USB_HS>()->InstallAsService(sm); | ||
| 233 | std::make_shared<USB_PD>()->InstallAsService(sm); | ||
| 234 | std::make_shared<USB_PD_C>()->InstallAsService(sm); | ||
| 235 | std::make_shared<USB_PM>()->InstallAsService(sm); | ||
| 236 | } | ||
| 237 | |||
| 238 | } // namespace Service::USB | ||
diff --git a/src/core/hle/service/usb/usb.h b/src/core/hle/service/usb/usb.h new file mode 100644 index 000000000..970a11fe8 --- /dev/null +++ b/src/core/hle/service/usb/usb.h | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | namespace Service::SM { | ||
| 8 | class ServiceManager; | ||
| 9 | } | ||
| 10 | |||
| 11 | namespace Service::USB { | ||
| 12 | |||
| 13 | void InstallInterfaces(SM::ServiceManager& sm); | ||
| 14 | |||
| 15 | } // namespace Service::USB | ||
diff --git a/src/core/hle/service/wlan/wlan.cpp b/src/core/hle/service/wlan/wlan.cpp new file mode 100644 index 000000000..2654594c1 --- /dev/null +++ b/src/core/hle/service/wlan/wlan.cpp | |||
| @@ -0,0 +1,172 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <memory> | ||
| 6 | |||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | #include "core/hle/service/sm/sm.h" | ||
| 9 | #include "core/hle/service/wlan/wlan.h" | ||
| 10 | |||
| 11 | namespace Service::WLAN { | ||
| 12 | |||
| 13 | class WLANInfra final : public ServiceFramework<WLANInfra> { | ||
| 14 | public: | ||
| 15 | explicit WLANInfra() : ServiceFramework{"wlan:inf"} { | ||
| 16 | // clang-format off | ||
| 17 | static const FunctionInfo functions[] = { | ||
| 18 | {0, nullptr, "Unknown1"}, | ||
| 19 | {1, nullptr, "Unknown2"}, | ||
| 20 | {2, nullptr, "GetMacAddress"}, | ||
| 21 | {3, nullptr, "StartScan"}, | ||
| 22 | {4, nullptr, "StopScan"}, | ||
| 23 | {5, nullptr, "Connect"}, | ||
| 24 | {6, nullptr, "CancelConnect"}, | ||
| 25 | {7, nullptr, "Disconnect"}, | ||
| 26 | {8, nullptr, "Unknown3"}, | ||
| 27 | {9, nullptr, "Unknown4"}, | ||
| 28 | {10, nullptr, "GetState"}, | ||
| 29 | {11, nullptr, "GetScanResult"}, | ||
| 30 | {12, nullptr, "GetRssi"}, | ||
| 31 | {13, nullptr, "ChangeRxAntenna"}, | ||
| 32 | {14, nullptr, "Unknown5"}, | ||
| 33 | {15, nullptr, "Unknown6"}, | ||
| 34 | {16, nullptr, "RequestWakeUp"}, | ||
| 35 | {17, nullptr, "RequestIfUpDown"}, | ||
| 36 | {18, nullptr, "Unknown7"}, | ||
| 37 | {19, nullptr, "Unknown8"}, | ||
| 38 | {20, nullptr, "Unknown9"}, | ||
| 39 | {21, nullptr, "Unknown10"}, | ||
| 40 | {22, nullptr, "Unknown11"}, | ||
| 41 | {23, nullptr, "Unknown12"}, | ||
| 42 | {24, nullptr, "Unknown13"}, | ||
| 43 | {25, nullptr, "Unknown14"}, | ||
| 44 | {26, nullptr, "Unknown15"}, | ||
| 45 | {27, nullptr, "Unknown16"}, | ||
| 46 | }; | ||
| 47 | // clang-format on | ||
| 48 | |||
| 49 | RegisterHandlers(functions); | ||
| 50 | } | ||
| 51 | }; | ||
| 52 | |||
| 53 | class WLANLocal final : public ServiceFramework<WLANLocal> { | ||
| 54 | public: | ||
| 55 | explicit WLANLocal() : ServiceFramework{"wlan:lcl"} { | ||
| 56 | // clang-format off | ||
| 57 | static const FunctionInfo functions[] = { | ||
| 58 | {0, nullptr, "Unknown1"}, | ||
| 59 | {1, nullptr, "Unknown2"}, | ||
| 60 | {2, nullptr, "Unknown3"}, | ||
| 61 | {3, nullptr, "Unknown4"}, | ||
| 62 | {4, nullptr, "Unknown5"}, | ||
| 63 | {5, nullptr, "Unknown6"}, | ||
| 64 | {6, nullptr, "GetMacAddress"}, | ||
| 65 | {7, nullptr, "CreateBss"}, | ||
| 66 | {8, nullptr, "DestroyBss"}, | ||
| 67 | {9, nullptr, "StartScan"}, | ||
| 68 | {10, nullptr, "StopScan"}, | ||
| 69 | {11, nullptr, "Connect"}, | ||
| 70 | {12, nullptr, "CancelConnect"}, | ||
| 71 | {13, nullptr, "Join"}, | ||
| 72 | {14, nullptr, "CancelJoin"}, | ||
| 73 | {15, nullptr, "Disconnect"}, | ||
| 74 | {16, nullptr, "SetBeaconLostCount"}, | ||
| 75 | {17, nullptr, "Unknown7"}, | ||
| 76 | {18, nullptr, "Unknown8"}, | ||
| 77 | {19, nullptr, "Unknown9"}, | ||
| 78 | {20, nullptr, "GetBssIndicationEvent"}, | ||
| 79 | {21, nullptr, "GetBssIndicationInfo"}, | ||
| 80 | {22, nullptr, "GetState"}, | ||
| 81 | {23, nullptr, "GetAllowedChannels"}, | ||
| 82 | {24, nullptr, "AddIe"}, | ||
| 83 | {25, nullptr, "DeleteIe"}, | ||
| 84 | {26, nullptr, "Unknown10"}, | ||
| 85 | {27, nullptr, "Unknown11"}, | ||
| 86 | {28, nullptr, "CreateRxEntry"}, | ||
| 87 | {29, nullptr, "DeleteRxEntry"}, | ||
| 88 | {30, nullptr, "Unknown12"}, | ||
| 89 | {31, nullptr, "Unknown13"}, | ||
| 90 | {32, nullptr, "AddMatchingDataToRxEntry"}, | ||
| 91 | {33, nullptr, "RemoveMatchingDataFromRxEntry"}, | ||
| 92 | {34, nullptr, "GetScanResult"}, | ||
| 93 | {35, nullptr, "Unknown14"}, | ||
| 94 | {36, nullptr, "SetActionFrameWithBeacon"}, | ||
| 95 | {37, nullptr, "CancelActionFrameWithBeacon"}, | ||
| 96 | {38, nullptr, "CreateRxEntryForActionFrame"}, | ||
| 97 | {39, nullptr, "DeleteRxEntryForActionFrame"}, | ||
| 98 | {40, nullptr, "Unknown15"}, | ||
| 99 | {41, nullptr, "Unknown16"}, | ||
| 100 | {42, nullptr, "CancelGetActionFrame"}, | ||
| 101 | {43, nullptr, "GetRssi"}, | ||
| 102 | {44, nullptr, "Unknown17"}, | ||
| 103 | {45, nullptr, "Unknown18"}, | ||
| 104 | {46, nullptr, "Unknown19"}, | ||
| 105 | {47, nullptr, "Unknown20"}, | ||
| 106 | {48, nullptr, "Unknown21"}, | ||
| 107 | }; | ||
| 108 | // clang-format on | ||
| 109 | |||
| 110 | RegisterHandlers(functions); | ||
| 111 | } | ||
| 112 | }; | ||
| 113 | |||
| 114 | class WLANLocalGetFrame final : public ServiceFramework<WLANLocalGetFrame> { | ||
| 115 | public: | ||
| 116 | explicit WLANLocalGetFrame() : ServiceFramework{"wlan:lg"} { | ||
| 117 | // clang-format off | ||
| 118 | static const FunctionInfo functions[] = { | ||
| 119 | {0, nullptr, "Unknown"}, | ||
| 120 | }; | ||
| 121 | // clang-format on | ||
| 122 | |||
| 123 | RegisterHandlers(functions); | ||
| 124 | } | ||
| 125 | }; | ||
| 126 | |||
| 127 | class WLANSocketGetFrame final : public ServiceFramework<WLANSocketGetFrame> { | ||
| 128 | public: | ||
| 129 | explicit WLANSocketGetFrame() : ServiceFramework{"wlan:sg"} { | ||
| 130 | // clang-format off | ||
| 131 | static const FunctionInfo functions[] = { | ||
| 132 | {0, nullptr, "Unknown"}, | ||
| 133 | }; | ||
| 134 | // clang-format on | ||
| 135 | |||
| 136 | RegisterHandlers(functions); | ||
| 137 | } | ||
| 138 | }; | ||
| 139 | |||
| 140 | class WLANSocketManager final : public ServiceFramework<WLANSocketManager> { | ||
| 141 | public: | ||
| 142 | explicit WLANSocketManager() : ServiceFramework{"wlan:soc"} { | ||
| 143 | // clang-format off | ||
| 144 | static const FunctionInfo functions[] = { | ||
| 145 | {0, nullptr, "Unknown1"}, | ||
| 146 | {1, nullptr, "Unknown2"}, | ||
| 147 | {2, nullptr, "Unknown3"}, | ||
| 148 | {3, nullptr, "Unknown4"}, | ||
| 149 | {4, nullptr, "Unknown5"}, | ||
| 150 | {5, nullptr, "Unknown6"}, | ||
| 151 | {6, nullptr, "GetMacAddress"}, | ||
| 152 | {7, nullptr, "SwitchTsfTimerFunction"}, | ||
| 153 | {8, nullptr, "Unknown7"}, | ||
| 154 | {9, nullptr, "Unknown8"}, | ||
| 155 | {10, nullptr, "Unknown9"}, | ||
| 156 | {11, nullptr, "Unknown10"}, | ||
| 157 | }; | ||
| 158 | // clang-format on | ||
| 159 | |||
| 160 | RegisterHandlers(functions); | ||
| 161 | } | ||
| 162 | }; | ||
| 163 | |||
| 164 | void InstallInterfaces(SM::ServiceManager& sm) { | ||
| 165 | std::make_shared<WLANInfra>()->InstallAsService(sm); | ||
| 166 | std::make_shared<WLANLocal>()->InstallAsService(sm); | ||
| 167 | std::make_shared<WLANLocalGetFrame>()->InstallAsService(sm); | ||
| 168 | std::make_shared<WLANSocketGetFrame>()->InstallAsService(sm); | ||
| 169 | std::make_shared<WLANSocketManager>()->InstallAsService(sm); | ||
| 170 | } | ||
| 171 | |||
| 172 | } // namespace Service::WLAN | ||
diff --git a/src/core/hle/service/wlan/wlan.h b/src/core/hle/service/wlan/wlan.h new file mode 100644 index 000000000..054ea928a --- /dev/null +++ b/src/core/hle/service/wlan/wlan.h | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | namespace Service::SM { | ||
| 8 | class ServiceManager; | ||
| 9 | } | ||
| 10 | |||
| 11 | namespace Service::WLAN { | ||
| 12 | |||
| 13 | void InstallInterfaces(SM::ServiceManager& sm); | ||
| 14 | |||
| 15 | } // namespace Service::WLAN | ||
diff --git a/src/core/hw/aes/ccm.cpp b/src/core/hw/aes/ccm.cpp deleted file mode 100644 index 1ee37aaa4..000000000 --- a/src/core/hw/aes/ccm.cpp +++ /dev/null | |||
| @@ -1,28 +0,0 @@ | |||
| 1 | // Copyright 2017 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | #include "common/alignment.h" | ||
| 7 | #include "common/assert.h" | ||
| 8 | #include "common/logging/log.h" | ||
| 9 | #include "core/hw/aes/ccm.h" | ||
| 10 | #include "core/hw/aes/key.h" | ||
| 11 | |||
| 12 | namespace HW { | ||
| 13 | namespace AES { | ||
| 14 | |||
| 15 | std::vector<u8> EncryptSignCCM(const std::vector<u8>& pdata, const CCMNonce& nonce, | ||
| 16 | size_t slot_id) { | ||
| 17 | UNIMPLEMENTED(); | ||
| 18 | return {}; | ||
| 19 | } | ||
| 20 | |||
| 21 | std::vector<u8> DecryptVerifyCCM(const std::vector<u8>& cipher, const CCMNonce& nonce, | ||
| 22 | size_t slot_id) { | ||
| 23 | UNIMPLEMENTED(); | ||
| 24 | return {}; | ||
| 25 | } | ||
| 26 | |||
| 27 | } // namespace AES | ||
| 28 | } // namespace HW | ||
diff --git a/src/core/hw/hw.cpp b/src/core/hw/hw.cpp deleted file mode 100644 index 2f48068c1..000000000 --- a/src/core/hw/hw.cpp +++ /dev/null | |||
| @@ -1,96 +0,0 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/common_types.h" | ||
| 6 | #include "common/logging/log.h" | ||
| 7 | #include "core/hw/hw.h" | ||
| 8 | #include "core/hw/lcd.h" | ||
| 9 | |||
| 10 | namespace HW { | ||
| 11 | |||
| 12 | template <typename T> | ||
| 13 | inline void Read(T& var, const u32 addr) { | ||
| 14 | switch (addr & 0xFFFFF000) { | ||
| 15 | case VADDR_GPU: | ||
| 16 | case VADDR_GPU + 0x1000: | ||
| 17 | case VADDR_GPU + 0x2000: | ||
| 18 | case VADDR_GPU + 0x3000: | ||
| 19 | case VADDR_GPU + 0x4000: | ||
| 20 | case VADDR_GPU + 0x5000: | ||
| 21 | case VADDR_GPU + 0x6000: | ||
| 22 | case VADDR_GPU + 0x7000: | ||
| 23 | case VADDR_GPU + 0x8000: | ||
| 24 | case VADDR_GPU + 0x9000: | ||
| 25 | case VADDR_GPU + 0xA000: | ||
| 26 | case VADDR_GPU + 0xB000: | ||
| 27 | case VADDR_GPU + 0xC000: | ||
| 28 | case VADDR_GPU + 0xD000: | ||
| 29 | case VADDR_GPU + 0xE000: | ||
| 30 | case VADDR_GPU + 0xF000: | ||
| 31 | break; | ||
| 32 | case VADDR_LCD: | ||
| 33 | LCD::Read(var, addr); | ||
| 34 | break; | ||
| 35 | default: | ||
| 36 | LOG_ERROR(HW_Memory, "Unknown Read{} @ 0x{:08X}", sizeof(var) * 8, addr); | ||
| 37 | break; | ||
| 38 | } | ||
| 39 | } | ||
| 40 | |||
| 41 | template <typename T> | ||
| 42 | inline void Write(u32 addr, const T data) { | ||
| 43 | switch (addr & 0xFFFFF000) { | ||
| 44 | case VADDR_GPU: | ||
| 45 | case VADDR_GPU + 0x1000: | ||
| 46 | case VADDR_GPU + 0x2000: | ||
| 47 | case VADDR_GPU + 0x3000: | ||
| 48 | case VADDR_GPU + 0x4000: | ||
| 49 | case VADDR_GPU + 0x5000: | ||
| 50 | case VADDR_GPU + 0x6000: | ||
| 51 | case VADDR_GPU + 0x7000: | ||
| 52 | case VADDR_GPU + 0x8000: | ||
| 53 | case VADDR_GPU + 0x9000: | ||
| 54 | case VADDR_GPU + 0xA000: | ||
| 55 | case VADDR_GPU + 0xB000: | ||
| 56 | case VADDR_GPU + 0xC000: | ||
| 57 | case VADDR_GPU + 0xD000: | ||
| 58 | case VADDR_GPU + 0xE000: | ||
| 59 | case VADDR_GPU + 0xF000: | ||
| 60 | break; | ||
| 61 | case VADDR_LCD: | ||
| 62 | LCD::Write(addr, data); | ||
| 63 | break; | ||
| 64 | default: | ||
| 65 | LOG_ERROR(HW_Memory, "Unknown Write{} 0x{:08X} @ 0x{:08X}", sizeof(data) * 8, data, addr); | ||
| 66 | break; | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | // Explicitly instantiate template functions because we aren't defining this in the header: | ||
| 71 | |||
| 72 | template void Read<u64>(u64& var, const u32 addr); | ||
| 73 | template void Read<u32>(u32& var, const u32 addr); | ||
| 74 | template void Read<u16>(u16& var, const u32 addr); | ||
| 75 | template void Read<u8>(u8& var, const u32 addr); | ||
| 76 | |||
| 77 | template void Write<u64>(u32 addr, const u64 data); | ||
| 78 | template void Write<u32>(u32 addr, const u32 data); | ||
| 79 | template void Write<u16>(u32 addr, const u16 data); | ||
| 80 | template void Write<u8>(u32 addr, const u8 data); | ||
| 81 | |||
| 82 | /// Update hardware | ||
| 83 | void Update() {} | ||
| 84 | |||
| 85 | /// Initialize hardware | ||
| 86 | void Init() { | ||
| 87 | LCD::Init(); | ||
| 88 | LOG_DEBUG(HW, "Initialized OK"); | ||
| 89 | } | ||
| 90 | |||
| 91 | /// Shutdown hardware | ||
| 92 | void Shutdown() { | ||
| 93 | LCD::Shutdown(); | ||
| 94 | LOG_DEBUG(HW, "Shutdown OK"); | ||
| 95 | } | ||
| 96 | } // namespace HW | ||
diff --git a/src/core/hw/hw.h b/src/core/hw/hw.h deleted file mode 100644 index 5890d2b5c..000000000 --- a/src/core/hw/hw.h +++ /dev/null | |||
| @@ -1,50 +0,0 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "common/common_types.h" | ||
| 8 | |||
| 9 | namespace HW { | ||
| 10 | |||
| 11 | /// Beginnings of IO register regions, in the user VA space. | ||
| 12 | enum : u32 { | ||
| 13 | VADDR_HASH = 0x1EC01000, | ||
| 14 | VADDR_CSND = 0x1EC03000, | ||
| 15 | VADDR_DSP = 0x1EC40000, | ||
| 16 | VADDR_PDN = 0x1EC41000, | ||
| 17 | VADDR_CODEC = 0x1EC41000, | ||
| 18 | VADDR_SPI = 0x1EC42000, | ||
| 19 | VADDR_SPI_2 = 0x1EC43000, // Only used under TWL_FIRM? | ||
| 20 | VADDR_I2C = 0x1EC44000, | ||
| 21 | VADDR_CODEC_2 = 0x1EC45000, | ||
| 22 | VADDR_HID = 0x1EC46000, | ||
| 23 | VADDR_GPIO = 0x1EC47000, | ||
| 24 | VADDR_I2C_2 = 0x1EC48000, | ||
| 25 | VADDR_SPI_3 = 0x1EC60000, | ||
| 26 | VADDR_I2C_3 = 0x1EC61000, | ||
| 27 | VADDR_MIC = 0x1EC62000, | ||
| 28 | VADDR_PXI = 0x1EC63000, | ||
| 29 | VADDR_LCD = 0x1ED02000, | ||
| 30 | VADDR_DSP_2 = 0x1ED03000, | ||
| 31 | VADDR_HASH_2 = 0x1EE01000, | ||
| 32 | VADDR_GPU = 0x1EF00000, | ||
| 33 | }; | ||
| 34 | |||
| 35 | template <typename T> | ||
| 36 | void Read(T& var, const u32 addr); | ||
| 37 | |||
| 38 | template <typename T> | ||
| 39 | void Write(u32 addr, const T data); | ||
| 40 | |||
| 41 | /// Update hardware | ||
| 42 | void Update(); | ||
| 43 | |||
| 44 | /// Initialize hardware | ||
| 45 | void Init(); | ||
| 46 | |||
| 47 | /// Shutdown hardware | ||
| 48 | void Shutdown(); | ||
| 49 | |||
| 50 | } // namespace HW | ||
diff --git a/src/core/hw/lcd.cpp b/src/core/hw/lcd.cpp deleted file mode 100644 index 0b62174d5..000000000 --- a/src/core/hw/lcd.cpp +++ /dev/null | |||
| @@ -1,67 +0,0 @@ | |||
| 1 | // Copyright 2015 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <cstring> | ||
| 6 | #include "common/common_types.h" | ||
| 7 | #include "common/logging/log.h" | ||
| 8 | #include "core/hw/hw.h" | ||
| 9 | #include "core/hw/lcd.h" | ||
| 10 | #include "core/tracer/recorder.h" | ||
| 11 | |||
| 12 | namespace LCD { | ||
| 13 | |||
| 14 | Regs g_regs; | ||
| 15 | |||
| 16 | template <typename T> | ||
| 17 | inline void Read(T& var, const u32 raw_addr) { | ||
| 18 | u32 addr = raw_addr - HW::VADDR_LCD; | ||
| 19 | u32 index = addr / 4; | ||
| 20 | |||
| 21 | // Reads other than u32 are untested, so I'd rather have them abort than silently fail | ||
| 22 | if (index >= 0x400 || !std::is_same<T, u32>::value) { | ||
| 23 | LOG_ERROR(HW_LCD, "Unknown Read{} @ 0x{:08X}", sizeof(var) * 8, addr); | ||
| 24 | return; | ||
| 25 | } | ||
| 26 | |||
| 27 | var = g_regs[index]; | ||
| 28 | } | ||
| 29 | |||
| 30 | template <typename T> | ||
| 31 | inline void Write(u32 addr, const T data) { | ||
| 32 | addr -= HW::VADDR_LCD; | ||
| 33 | u32 index = addr / 4; | ||
| 34 | |||
| 35 | // Writes other than u32 are untested, so I'd rather have them abort than silently fail | ||
| 36 | if (index >= 0x400 || !std::is_same<T, u32>::value) { | ||
| 37 | LOG_ERROR(HW_LCD, "Unknown Write{} 0x{:08X} @ 0x{:08X}", sizeof(data) * 8, data, addr); | ||
| 38 | return; | ||
| 39 | } | ||
| 40 | |||
| 41 | g_regs[index] = static_cast<u32>(data); | ||
| 42 | } | ||
| 43 | |||
| 44 | // Explicitly instantiate template functions because we aren't defining this in the header: | ||
| 45 | |||
| 46 | template void Read<u64>(u64& var, const u32 addr); | ||
| 47 | template void Read<u32>(u32& var, const u32 addr); | ||
| 48 | template void Read<u16>(u16& var, const u32 addr); | ||
| 49 | template void Read<u8>(u8& var, const u32 addr); | ||
| 50 | |||
| 51 | template void Write<u64>(u32 addr, const u64 data); | ||
| 52 | template void Write<u32>(u32 addr, const u32 data); | ||
| 53 | template void Write<u16>(u32 addr, const u16 data); | ||
| 54 | template void Write<u8>(u32 addr, const u8 data); | ||
| 55 | |||
| 56 | /// Initialize hardware | ||
| 57 | void Init() { | ||
| 58 | memset(&g_regs, 0, sizeof(g_regs)); | ||
| 59 | LOG_DEBUG(HW_LCD, "Initialized OK"); | ||
| 60 | } | ||
| 61 | |||
| 62 | /// Shutdown hardware | ||
| 63 | void Shutdown() { | ||
| 64 | LOG_DEBUG(HW_LCD, "Shutdown OK"); | ||
| 65 | } | ||
| 66 | |||
| 67 | } // namespace LCD | ||
diff --git a/src/core/hw/lcd.h b/src/core/hw/lcd.h deleted file mode 100644 index d2db9700f..000000000 --- a/src/core/hw/lcd.h +++ /dev/null | |||
| @@ -1,86 +0,0 @@ | |||
| 1 | // Copyright 2015 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <cstddef> | ||
| 8 | #include <type_traits> | ||
| 9 | #include "common/bit_field.h" | ||
| 10 | #include "common/common_funcs.h" | ||
| 11 | #include "common/common_types.h" | ||
| 12 | |||
| 13 | #define LCD_REG_INDEX(field_name) (offsetof(LCD::Regs, field_name) / sizeof(u32)) | ||
| 14 | |||
| 15 | namespace LCD { | ||
| 16 | |||
| 17 | struct Regs { | ||
| 18 | |||
| 19 | union ColorFill { | ||
| 20 | u32 raw; | ||
| 21 | |||
| 22 | BitField<0, 8, u32> color_r; | ||
| 23 | BitField<8, 8, u32> color_g; | ||
| 24 | BitField<16, 8, u32> color_b; | ||
| 25 | BitField<24, 1, u32> is_enabled; | ||
| 26 | }; | ||
| 27 | |||
| 28 | INSERT_PADDING_WORDS(0x81); | ||
| 29 | ColorFill color_fill_top; | ||
| 30 | INSERT_PADDING_WORDS(0xE); | ||
| 31 | u32 backlight_top; | ||
| 32 | |||
| 33 | INSERT_PADDING_WORDS(0x1F0); | ||
| 34 | |||
| 35 | ColorFill color_fill_bottom; | ||
| 36 | INSERT_PADDING_WORDS(0xE); | ||
| 37 | u32 backlight_bottom; | ||
| 38 | INSERT_PADDING_WORDS(0x16F); | ||
| 39 | |||
| 40 | static constexpr size_t NumIds() { | ||
| 41 | return sizeof(Regs) / sizeof(u32); | ||
| 42 | } | ||
| 43 | |||
| 44 | const u32& operator[](int index) const { | ||
| 45 | const u32* content = reinterpret_cast<const u32*>(this); | ||
| 46 | return content[index]; | ||
| 47 | } | ||
| 48 | |||
| 49 | u32& operator[](int index) { | ||
| 50 | u32* content = reinterpret_cast<u32*>(this); | ||
| 51 | return content[index]; | ||
| 52 | } | ||
| 53 | }; | ||
| 54 | static_assert(std::is_standard_layout<Regs>::value, "Structure does not use standard layout"); | ||
| 55 | |||
| 56 | // TODO: MSVC does not support using offsetof() on non-static data members even though this | ||
| 57 | // is technically allowed since C++11. This macro should be enabled once MSVC adds | ||
| 58 | // support for that. | ||
| 59 | #ifndef _MSC_VER | ||
| 60 | #define ASSERT_REG_POSITION(field_name, position) \ | ||
| 61 | static_assert(offsetof(Regs, field_name) == position * 4, \ | ||
| 62 | "Field " #field_name " has invalid position") | ||
| 63 | |||
| 64 | ASSERT_REG_POSITION(color_fill_top, 0x81); | ||
| 65 | ASSERT_REG_POSITION(backlight_top, 0x90); | ||
| 66 | ASSERT_REG_POSITION(color_fill_bottom, 0x281); | ||
| 67 | ASSERT_REG_POSITION(backlight_bottom, 0x290); | ||
| 68 | |||
| 69 | #undef ASSERT_REG_POSITION | ||
| 70 | #endif // !defined(_MSC_VER) | ||
| 71 | |||
| 72 | extern Regs g_regs; | ||
| 73 | |||
| 74 | template <typename T> | ||
| 75 | void Read(T& var, const u32 addr); | ||
| 76 | |||
| 77 | template <typename T> | ||
| 78 | void Write(u32 addr, const T data); | ||
| 79 | |||
| 80 | /// Initialize hardware | ||
| 81 | void Init(); | ||
| 82 | |||
| 83 | /// Shutdown hardware | ||
| 84 | void Shutdown(); | ||
| 85 | |||
| 86 | } // namespace LCD | ||
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index b0277a875..9a8cdd0ff 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp | |||
| @@ -20,6 +20,10 @@ namespace Loader { | |||
| 20 | AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file) | 20 | AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file) |
| 21 | : AppLoader(std::move(file)) {} | 21 | : AppLoader(std::move(file)) {} |
| 22 | 22 | ||
| 23 | AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory( | ||
| 24 | FileSys::VirtualDir directory) | ||
| 25 | : AppLoader(directory->GetFile("main")), dir(std::move(directory)) {} | ||
| 26 | |||
| 23 | FileType AppLoader_DeconstructedRomDirectory::IdentifyType(const FileSys::VirtualFile& file) { | 27 | FileType AppLoader_DeconstructedRomDirectory::IdentifyType(const FileSys::VirtualFile& file) { |
| 24 | if (FileSys::IsDirectoryExeFS(file->GetContainingDirectory())) { | 28 | if (FileSys::IsDirectoryExeFS(file->GetContainingDirectory())) { |
| 25 | return FileType::DeconstructedRomDirectory; | 29 | return FileType::DeconstructedRomDirectory; |
| @@ -34,7 +38,12 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load( | |||
| 34 | return ResultStatus::ErrorAlreadyLoaded; | 38 | return ResultStatus::ErrorAlreadyLoaded; |
| 35 | } | 39 | } |
| 36 | 40 | ||
| 37 | const FileSys::VirtualDir dir = file->GetContainingDirectory(); | 41 | if (dir == nullptr) { |
| 42 | if (file == nullptr) | ||
| 43 | return ResultStatus::ErrorInvalidFormat; | ||
| 44 | dir = file->GetContainingDirectory(); | ||
| 45 | } | ||
| 46 | |||
| 38 | const FileSys::VirtualFile npdm = dir->GetFile("main.npdm"); | 47 | const FileSys::VirtualFile npdm = dir->GetFile("main.npdm"); |
| 39 | if (npdm == nullptr) | 48 | if (npdm == nullptr) |
| 40 | return ResultStatus::ErrorInvalidFormat; | 49 | return ResultStatus::ErrorInvalidFormat; |
diff --git a/src/core/loader/deconstructed_rom_directory.h b/src/core/loader/deconstructed_rom_directory.h index 982a037f7..7d5433563 100644 --- a/src/core/loader/deconstructed_rom_directory.h +++ b/src/core/loader/deconstructed_rom_directory.h | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | #include <string> | 7 | #include <string> |
| 8 | #include "common/common_types.h" | 8 | #include "common/common_types.h" |
| 9 | #include "core/file_sys/program_metadata.h" | 9 | #include "core/file_sys/program_metadata.h" |
| 10 | #include "core/hle/kernel/kernel.h" | 10 | #include "core/hle/kernel/object.h" |
| 11 | #include "core/loader/loader.h" | 11 | #include "core/loader/loader.h" |
| 12 | 12 | ||
| 13 | namespace Loader { | 13 | namespace Loader { |
| @@ -22,6 +22,9 @@ class AppLoader_DeconstructedRomDirectory final : public AppLoader { | |||
| 22 | public: | 22 | public: |
| 23 | explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile main_file); | 23 | explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile main_file); |
| 24 | 24 | ||
| 25 | // Overload to accept exefs directory. Must contain 'main' and 'main.npdm' | ||
| 26 | explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualDir directory); | ||
| 27 | |||
| 25 | /** | 28 | /** |
| 26 | * Returns the type of the file | 29 | * Returns the type of the file |
| 27 | * @param file std::shared_ptr<VfsFile> open file | 30 | * @param file std::shared_ptr<VfsFile> open file |
| @@ -40,6 +43,7 @@ public: | |||
| 40 | private: | 43 | private: |
| 41 | FileSys::ProgramMetadata metadata; | 44 | FileSys::ProgramMetadata metadata; |
| 42 | FileSys::VirtualFile romfs; | 45 | FileSys::VirtualFile romfs; |
| 46 | FileSys::VirtualDir dir; | ||
| 43 | }; | 47 | }; |
| 44 | 48 | ||
| 45 | } // namespace Loader | 49 | } // namespace Loader |
diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index 352938dcb..a7133f5a6 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp | |||
| @@ -311,11 +311,11 @@ SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) { | |||
| 311 | CodeSet::Segment* codeset_segment; | 311 | CodeSet::Segment* codeset_segment; |
| 312 | u32 permission_flags = p->p_flags & (PF_R | PF_W | PF_X); | 312 | u32 permission_flags = p->p_flags & (PF_R | PF_W | PF_X); |
| 313 | if (permission_flags == (PF_R | PF_X)) { | 313 | if (permission_flags == (PF_R | PF_X)) { |
| 314 | codeset_segment = &codeset->code; | 314 | codeset_segment = &codeset->CodeSegment(); |
| 315 | } else if (permission_flags == (PF_R)) { | 315 | } else if (permission_flags == (PF_R)) { |
| 316 | codeset_segment = &codeset->rodata; | 316 | codeset_segment = &codeset->RODataSegment(); |
| 317 | } else if (permission_flags == (PF_R | PF_W)) { | 317 | } else if (permission_flags == (PF_R | PF_W)) { |
| 318 | codeset_segment = &codeset->data; | 318 | codeset_segment = &codeset->DataSegment(); |
| 319 | } else { | 319 | } else { |
| 320 | LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id {} with flags {:X}", i, | 320 | LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id {} with flags {:X}", i, |
| 321 | p->p_flags); | 321 | p->p_flags); |
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index cbc4177c6..57e6c0365 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include "core/loader/nca.h" | 13 | #include "core/loader/nca.h" |
| 14 | #include "core/loader/nro.h" | 14 | #include "core/loader/nro.h" |
| 15 | #include "core/loader/nso.h" | 15 | #include "core/loader/nso.h" |
| 16 | #include "core/loader/xci.h" | ||
| 16 | 17 | ||
| 17 | namespace Loader { | 18 | namespace Loader { |
| 18 | 19 | ||
| @@ -35,6 +36,7 @@ FileType IdentifyFile(FileSys::VirtualFile file) { | |||
| 35 | CHECK_TYPE(NSO) | 36 | CHECK_TYPE(NSO) |
| 36 | CHECK_TYPE(NRO) | 37 | CHECK_TYPE(NRO) |
| 37 | CHECK_TYPE(NCA) | 38 | CHECK_TYPE(NCA) |
| 39 | CHECK_TYPE(XCI) | ||
| 38 | 40 | ||
| 39 | #undef CHECK_TYPE | 41 | #undef CHECK_TYPE |
| 40 | 42 | ||
| @@ -60,6 +62,8 @@ FileType GuessFromFilename(const std::string& name) { | |||
| 60 | return FileType::NSO; | 62 | return FileType::NSO; |
| 61 | if (extension == "nca") | 63 | if (extension == "nca") |
| 62 | return FileType::NCA; | 64 | return FileType::NCA; |
| 65 | if (extension == "xci") | ||
| 66 | return FileType::XCI; | ||
| 63 | 67 | ||
| 64 | return FileType::Unknown; | 68 | return FileType::Unknown; |
| 65 | } | 69 | } |
| @@ -74,6 +78,8 @@ const char* GetFileTypeString(FileType type) { | |||
| 74 | return "NSO"; | 78 | return "NSO"; |
| 75 | case FileType::NCA: | 79 | case FileType::NCA: |
| 76 | return "NCA"; | 80 | return "NCA"; |
| 81 | case FileType::XCI: | ||
| 82 | return "XCI"; | ||
| 77 | case FileType::DeconstructedRomDirectory: | 83 | case FileType::DeconstructedRomDirectory: |
| 78 | return "Directory"; | 84 | return "Directory"; |
| 79 | case FileType::Error: | 85 | case FileType::Error: |
| @@ -111,6 +117,9 @@ static std::unique_ptr<AppLoader> GetFileLoader(FileSys::VirtualFile file, FileT | |||
| 111 | case FileType::NCA: | 117 | case FileType::NCA: |
| 112 | return std::make_unique<AppLoader_NCA>(std::move(file)); | 118 | return std::make_unique<AppLoader_NCA>(std::move(file)); |
| 113 | 119 | ||
| 120 | case FileType::XCI: | ||
| 121 | return std::make_unique<AppLoader_XCI>(std::move(file)); | ||
| 122 | |||
| 114 | // NX deconstructed ROM directory. | 123 | // NX deconstructed ROM directory. |
| 115 | case FileType::DeconstructedRomDirectory: | 124 | case FileType::DeconstructedRomDirectory: |
| 116 | return std::make_unique<AppLoader_DeconstructedRomDirectory>(std::move(file)); | 125 | return std::make_unique<AppLoader_DeconstructedRomDirectory>(std::move(file)); |
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index fbf11e5d0..e69ab85ef 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | #include "common/common_types.h" | 14 | #include "common/common_types.h" |
| 15 | #include "common/file_util.h" | 15 | #include "common/file_util.h" |
| 16 | #include "core/file_sys/vfs.h" | 16 | #include "core/file_sys/vfs.h" |
| 17 | #include "core/hle/kernel/kernel.h" | 17 | #include "core/hle/kernel/object.h" |
| 18 | 18 | ||
| 19 | namespace Kernel { | 19 | namespace Kernel { |
| 20 | struct AddressMapping; | 20 | struct AddressMapping; |
| @@ -31,6 +31,7 @@ enum class FileType { | |||
| 31 | NSO, | 31 | NSO, |
| 32 | NRO, | 32 | NRO, |
| 33 | NCA, | 33 | NCA, |
| 34 | XCI, | ||
| 34 | DeconstructedRomDirectory, | 35 | DeconstructedRomDirectory, |
| 35 | }; | 36 | }; |
| 36 | 37 | ||
| @@ -72,7 +73,8 @@ enum class ResultStatus { | |||
| 72 | ErrorNotUsed, | 73 | ErrorNotUsed, |
| 73 | ErrorAlreadyLoaded, | 74 | ErrorAlreadyLoaded, |
| 74 | ErrorMemoryAllocationFailed, | 75 | ErrorMemoryAllocationFailed, |
| 75 | ErrorEncrypted, | 76 | ErrorMissingKeys, |
| 77 | ErrorDecrypting, | ||
| 76 | ErrorUnsupportedArch, | 78 | ErrorUnsupportedArch, |
| 77 | }; | 79 | }; |
| 78 | 80 | ||
diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp index c80df23be..dbc67c0b5 100644 --- a/src/core/loader/nca.cpp +++ b/src/core/loader/nca.cpp | |||
| @@ -22,15 +22,14 @@ | |||
| 22 | 22 | ||
| 23 | namespace Loader { | 23 | namespace Loader { |
| 24 | 24 | ||
| 25 | AppLoader_NCA::AppLoader_NCA(FileSys::VirtualFile file) : AppLoader(std::move(file)) {} | 25 | AppLoader_NCA::AppLoader_NCA(FileSys::VirtualFile file_) |
| 26 | : AppLoader(std::move(file_)), nca(std::make_unique<FileSys::NCA>(file)) {} | ||
| 26 | 27 | ||
| 27 | FileType AppLoader_NCA::IdentifyType(const FileSys::VirtualFile& file) { | 28 | FileType AppLoader_NCA::IdentifyType(const FileSys::VirtualFile& file) { |
| 28 | // TODO(DarkLordZach): Assuming everything is decrypted. Add crypto support. | 29 | FileSys::NCA nca(file); |
| 29 | FileSys::NCAHeader header{}; | ||
| 30 | if (sizeof(FileSys::NCAHeader) != file->ReadObject(&header)) | ||
| 31 | return FileType::Error; | ||
| 32 | 30 | ||
| 33 | if (IsValidNCA(header) && header.content_type == FileSys::NCAContentType::Program) | 31 | if (nca.GetStatus() == ResultStatus::Success && |
| 32 | nca.GetType() == FileSys::NCAContentType::Program) | ||
| 34 | return FileType::NCA; | 33 | return FileType::NCA; |
| 35 | 34 | ||
| 36 | return FileType::Error; | 35 | return FileType::Error; |
| @@ -41,8 +40,7 @@ ResultStatus AppLoader_NCA::Load(Kernel::SharedPtr<Kernel::Process>& process) { | |||
| 41 | return ResultStatus::ErrorAlreadyLoaded; | 40 | return ResultStatus::ErrorAlreadyLoaded; |
| 42 | } | 41 | } |
| 43 | 42 | ||
| 44 | nca = std::make_unique<FileSys::NCA>(file); | 43 | const auto result = nca->GetStatus(); |
| 45 | ResultStatus result = nca->GetStatus(); | ||
| 46 | if (result != ResultStatus::Success) { | 44 | if (result != ResultStatus::Success) { |
| 47 | return result; | 45 | return result; |
| 48 | } | 46 | } |
| @@ -50,44 +48,16 @@ ResultStatus AppLoader_NCA::Load(Kernel::SharedPtr<Kernel::Process>& process) { | |||
| 50 | if (nca->GetType() != FileSys::NCAContentType::Program) | 48 | if (nca->GetType() != FileSys::NCAContentType::Program) |
| 51 | return ResultStatus::ErrorInvalidFormat; | 49 | return ResultStatus::ErrorInvalidFormat; |
| 52 | 50 | ||
| 53 | auto exefs = nca->GetExeFS(); | 51 | const auto exefs = nca->GetExeFS(); |
| 54 | 52 | ||
| 55 | if (exefs == nullptr) | 53 | if (exefs == nullptr) |
| 56 | return ResultStatus::ErrorInvalidFormat; | 54 | return ResultStatus::ErrorInvalidFormat; |
| 57 | 55 | ||
| 58 | result = metadata.Load(exefs->GetFile("main.npdm")); | 56 | directory_loader = std::make_unique<AppLoader_DeconstructedRomDirectory>(exefs); |
| 59 | if (result != ResultStatus::Success) { | ||
| 60 | return result; | ||
| 61 | } | ||
| 62 | metadata.Print(); | ||
| 63 | |||
| 64 | const FileSys::ProgramAddressSpaceType arch_bits{metadata.GetAddressSpaceType()}; | ||
| 65 | if (arch_bits == FileSys::ProgramAddressSpaceType::Is32Bit) { | ||
| 66 | return ResultStatus::ErrorUnsupportedArch; | ||
| 67 | } | ||
| 68 | 57 | ||
| 69 | VAddr next_load_addr{Memory::PROCESS_IMAGE_VADDR}; | 58 | const auto load_result = directory_loader->Load(process); |
| 70 | for (const auto& module : {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", "subsdk3", | 59 | if (load_result != ResultStatus::Success) |
| 71 | "subsdk4", "subsdk5", "subsdk6", "subsdk7", "sdk"}) { | 60 | return load_result; |
| 72 | const VAddr load_addr = next_load_addr; | ||
| 73 | |||
| 74 | next_load_addr = AppLoader_NSO::LoadModule(exefs->GetFile(module), load_addr); | ||
| 75 | if (next_load_addr) { | ||
| 76 | LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr); | ||
| 77 | // Register module with GDBStub | ||
| 78 | GDBStub::RegisterModule(module, load_addr, next_load_addr - 1, false); | ||
| 79 | } else { | ||
| 80 | next_load_addr = load_addr; | ||
| 81 | } | ||
| 82 | } | ||
| 83 | |||
| 84 | process->program_id = metadata.GetTitleID(); | ||
| 85 | process->svc_access_mask.set(); | ||
| 86 | process->address_mappings = default_address_mappings; | ||
| 87 | process->resource_limit = | ||
| 88 | Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); | ||
| 89 | process->Run(Memory::PROCESS_IMAGE_VADDR, metadata.GetMainThreadPriority(), | ||
| 90 | metadata.GetMainThreadStackSize()); | ||
| 91 | 61 | ||
| 92 | if (nca->GetRomFS() != nullptr && nca->GetRomFS()->GetSize() > 0) | 62 | if (nca->GetRomFS() != nullptr && nca->GetRomFS()->GetSize() > 0) |
| 93 | Service::FileSystem::RegisterRomFS(std::make_unique<FileSys::RomFSFactory>(*this)); | 63 | Service::FileSystem::RegisterRomFS(std::make_unique<FileSys::RomFSFactory>(*this)); |
| @@ -98,12 +68,21 @@ ResultStatus AppLoader_NCA::Load(Kernel::SharedPtr<Kernel::Process>& process) { | |||
| 98 | } | 68 | } |
| 99 | 69 | ||
| 100 | ResultStatus AppLoader_NCA::ReadRomFS(FileSys::VirtualFile& dir) { | 70 | ResultStatus AppLoader_NCA::ReadRomFS(FileSys::VirtualFile& dir) { |
| 101 | if (nca == nullptr || nca->GetRomFS() == nullptr || nca->GetRomFS()->GetSize() == 0) | 71 | if (nca == nullptr) |
| 72 | return ResultStatus::ErrorNotLoaded; | ||
| 73 | if (nca->GetRomFS() == nullptr || nca->GetRomFS()->GetSize() == 0) | ||
| 102 | return ResultStatus::ErrorNotUsed; | 74 | return ResultStatus::ErrorNotUsed; |
| 103 | dir = nca->GetRomFS(); | 75 | dir = nca->GetRomFS(); |
| 104 | return ResultStatus::Success; | 76 | return ResultStatus::Success; |
| 105 | } | 77 | } |
| 106 | 78 | ||
| 79 | ResultStatus AppLoader_NCA::ReadProgramId(u64& out_program_id) { | ||
| 80 | if (nca == nullptr) | ||
| 81 | return ResultStatus::ErrorNotLoaded; | ||
| 82 | out_program_id = nca->GetTitleId(); | ||
| 83 | return ResultStatus::Success; | ||
| 84 | } | ||
| 85 | |||
| 107 | AppLoader_NCA::~AppLoader_NCA() = default; | 86 | AppLoader_NCA::~AppLoader_NCA() = default; |
| 108 | 87 | ||
| 109 | } // namespace Loader | 88 | } // namespace Loader |
diff --git a/src/core/loader/nca.h b/src/core/loader/nca.h index 52c95953a..0fd2d0417 100644 --- a/src/core/loader/nca.h +++ b/src/core/loader/nca.h | |||
| @@ -8,8 +8,9 @@ | |||
| 8 | #include "common/common_types.h" | 8 | #include "common/common_types.h" |
| 9 | #include "core/file_sys/content_archive.h" | 9 | #include "core/file_sys/content_archive.h" |
| 10 | #include "core/file_sys/program_metadata.h" | 10 | #include "core/file_sys/program_metadata.h" |
| 11 | #include "core/hle/kernel/kernel.h" | 11 | #include "core/hle/kernel/object.h" |
| 12 | #include "core/loader/loader.h" | 12 | #include "core/loader/loader.h" |
| 13 | #include "deconstructed_rom_directory.h" | ||
| 13 | 14 | ||
| 14 | namespace Loader { | 15 | namespace Loader { |
| 15 | 16 | ||
| @@ -33,12 +34,15 @@ public: | |||
| 33 | 34 | ||
| 34 | ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; | 35 | ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; |
| 35 | 36 | ||
| 37 | ResultStatus ReadProgramId(u64& out_program_id) override; | ||
| 38 | |||
| 36 | ~AppLoader_NCA(); | 39 | ~AppLoader_NCA(); |
| 37 | 40 | ||
| 38 | private: | 41 | private: |
| 39 | FileSys::ProgramMetadata metadata; | 42 | FileSys::ProgramMetadata metadata; |
| 40 | 43 | ||
| 41 | std::unique_ptr<FileSys::NCA> nca; | 44 | std::unique_ptr<FileSys::NCA> nca; |
| 45 | std::unique_ptr<AppLoader_DeconstructedRomDirectory> directory_loader; | ||
| 42 | }; | 46 | }; |
| 43 | 47 | ||
| 44 | } // namespace Loader | 48 | } // namespace Loader |
diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp index 7d3ec2a76..dc053cdad 100644 --- a/src/core/loader/nro.cpp +++ b/src/core/loader/nro.cpp | |||
| @@ -159,7 +159,7 @@ bool AppLoader_NRO::LoadNro(FileSys::VirtualFile file, VAddr load_base) { | |||
| 159 | // Resize program image to include .bss section and page align each section | 159 | // Resize program image to include .bss section and page align each section |
| 160 | bss_size = PageAlignSize(mod_header.bss_end_offset - mod_header.bss_start_offset); | 160 | bss_size = PageAlignSize(mod_header.bss_end_offset - mod_header.bss_start_offset); |
| 161 | } | 161 | } |
| 162 | codeset->data.size += bss_size; | 162 | codeset->DataSegment().size += bss_size; |
| 163 | program_image.resize(static_cast<u32>(program_image.size()) + bss_size); | 163 | program_image.resize(static_cast<u32>(program_image.size()) + bss_size); |
| 164 | 164 | ||
| 165 | // Load codeset for current process | 165 | // Load codeset for current process |
diff --git a/src/core/loader/nro.h b/src/core/loader/nro.h index 04a0f497e..bb01c9e25 100644 --- a/src/core/loader/nro.h +++ b/src/core/loader/nro.h | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include <string> | 7 | #include <string> |
| 8 | #include "common/common_types.h" | 8 | #include "common/common_types.h" |
| 9 | #include "core/hle/kernel/kernel.h" | 9 | #include "core/hle/kernel/object.h" |
| 10 | #include "core/loader/linker.h" | 10 | #include "core/loader/linker.h" |
| 11 | #include "core/loader/loader.h" | 11 | #include "core/loader/loader.h" |
| 12 | 12 | ||
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index 06b1b33f4..fee7d58c6 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp | |||
| @@ -127,7 +127,7 @@ VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base) { | |||
| 127 | // Resize program image to include .bss section and page align each section | 127 | // Resize program image to include .bss section and page align each section |
| 128 | bss_size = PageAlignSize(mod_header.bss_end_offset - mod_header.bss_start_offset); | 128 | bss_size = PageAlignSize(mod_header.bss_end_offset - mod_header.bss_start_offset); |
| 129 | } | 129 | } |
| 130 | codeset->data.size += bss_size; | 130 | codeset->DataSegment().size += bss_size; |
| 131 | const u32 image_size{PageAlignSize(static_cast<u32>(program_image.size()) + bss_size)}; | 131 | const u32 image_size{PageAlignSize(static_cast<u32>(program_image.size()) + bss_size)}; |
| 132 | program_image.resize(image_size); | 132 | program_image.resize(image_size); |
| 133 | 133 | ||
diff --git a/src/core/loader/nso.h b/src/core/loader/nso.h index 3f7567500..aaeb1f2a9 100644 --- a/src/core/loader/nso.h +++ b/src/core/loader/nso.h | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include <string> | 7 | #include <string> |
| 8 | #include "common/common_types.h" | 8 | #include "common/common_types.h" |
| 9 | #include "core/hle/kernel/kernel.h" | 9 | #include "core/hle/kernel/object.h" |
| 10 | #include "core/loader/linker.h" | 10 | #include "core/loader/linker.h" |
| 11 | #include "core/loader/loader.h" | 11 | #include "core/loader/loader.h" |
| 12 | 12 | ||
diff --git a/src/core/loader/xci.cpp b/src/core/loader/xci.cpp new file mode 100644 index 000000000..eb4dee2c2 --- /dev/null +++ b/src/core/loader/xci.cpp | |||
| @@ -0,0 +1,74 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <vector> | ||
| 6 | |||
| 7 | #include "common/file_util.h" | ||
| 8 | #include "common/logging/log.h" | ||
| 9 | #include "common/string_util.h" | ||
| 10 | #include "common/swap.h" | ||
| 11 | #include "core/core.h" | ||
| 12 | #include "core/file_sys/content_archive.h" | ||
| 13 | #include "core/file_sys/control_metadata.h" | ||
| 14 | #include "core/file_sys/program_metadata.h" | ||
| 15 | #include "core/file_sys/romfs.h" | ||
| 16 | #include "core/gdbstub/gdbstub.h" | ||
| 17 | #include "core/hle/kernel/process.h" | ||
| 18 | #include "core/hle/kernel/resource_limit.h" | ||
| 19 | #include "core/hle/service/filesystem/filesystem.h" | ||
| 20 | #include "core/loader/nso.h" | ||
| 21 | #include "core/loader/xci.h" | ||
| 22 | #include "core/memory.h" | ||
| 23 | |||
| 24 | namespace Loader { | ||
| 25 | |||
| 26 | AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file) | ||
| 27 | : AppLoader(file), xci(std::make_unique<FileSys::XCI>(file)), | ||
| 28 | nca_loader(std::make_unique<AppLoader_NCA>( | ||
| 29 | xci->GetNCAFileByType(FileSys::NCAContentType::Program))) {} | ||
| 30 | |||
| 31 | AppLoader_XCI::~AppLoader_XCI() = default; | ||
| 32 | |||
| 33 | FileType AppLoader_XCI::IdentifyType(const FileSys::VirtualFile& file) { | ||
| 34 | FileSys::XCI xci(file); | ||
| 35 | |||
| 36 | if (xci.GetStatus() == ResultStatus::Success && | ||
| 37 | xci.GetNCAByType(FileSys::NCAContentType::Program) != nullptr && | ||
| 38 | AppLoader_NCA::IdentifyType(xci.GetNCAFileByType(FileSys::NCAContentType::Program)) == | ||
| 39 | FileType::NCA) { | ||
| 40 | return FileType::XCI; | ||
| 41 | } | ||
| 42 | |||
| 43 | return FileType::Error; | ||
| 44 | } | ||
| 45 | |||
| 46 | ResultStatus AppLoader_XCI::Load(Kernel::SharedPtr<Kernel::Process>& process) { | ||
| 47 | if (is_loaded) { | ||
| 48 | return ResultStatus::ErrorAlreadyLoaded; | ||
| 49 | } | ||
| 50 | |||
| 51 | if (xci->GetNCAFileByType(FileSys::NCAContentType::Program) == nullptr) { | ||
| 52 | if (!Core::Crypto::KeyManager::KeyFileExists(false)) | ||
| 53 | return ResultStatus::ErrorMissingKeys; | ||
| 54 | return ResultStatus::ErrorDecrypting; | ||
| 55 | } | ||
| 56 | |||
| 57 | auto result = nca_loader->Load(process); | ||
| 58 | if (result != ResultStatus::Success) | ||
| 59 | return result; | ||
| 60 | |||
| 61 | is_loaded = true; | ||
| 62 | |||
| 63 | return ResultStatus::Success; | ||
| 64 | } | ||
| 65 | |||
| 66 | ResultStatus AppLoader_XCI::ReadRomFS(FileSys::VirtualFile& dir) { | ||
| 67 | return nca_loader->ReadRomFS(dir); | ||
| 68 | } | ||
| 69 | |||
| 70 | ResultStatus AppLoader_XCI::ReadProgramId(u64& out_program_id) { | ||
| 71 | return nca_loader->ReadProgramId(out_program_id); | ||
| 72 | } | ||
| 73 | |||
| 74 | } // namespace Loader | ||
diff --git a/src/core/loader/xci.h b/src/core/loader/xci.h new file mode 100644 index 000000000..0dbcfbdf8 --- /dev/null +++ b/src/core/loader/xci.h | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | #include "common/common_types.h" | ||
| 9 | #include "core/file_sys/card_image.h" | ||
| 10 | #include "core/loader/loader.h" | ||
| 11 | #include "core/loader/nca.h" | ||
| 12 | |||
| 13 | namespace Loader { | ||
| 14 | |||
| 15 | /// Loads an XCI file | ||
| 16 | class AppLoader_XCI final : public AppLoader { | ||
| 17 | public: | ||
| 18 | explicit AppLoader_XCI(FileSys::VirtualFile file); | ||
| 19 | ~AppLoader_XCI(); | ||
| 20 | |||
| 21 | /** | ||
| 22 | * Returns the type of the file | ||
| 23 | * @param file std::shared_ptr<VfsFile> open file | ||
| 24 | * @return FileType found, or FileType::Error if this loader doesn't know it | ||
| 25 | */ | ||
| 26 | static FileType IdentifyType(const FileSys::VirtualFile& file); | ||
| 27 | |||
| 28 | FileType GetFileType() override { | ||
| 29 | return IdentifyType(file); | ||
| 30 | } | ||
| 31 | |||
| 32 | ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override; | ||
| 33 | |||
| 34 | ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; | ||
| 35 | ResultStatus ReadProgramId(u64& out_program_id) override; | ||
| 36 | |||
| 37 | private: | ||
| 38 | FileSys::ProgramMetadata metadata; | ||
| 39 | |||
| 40 | std::unique_ptr<FileSys::XCI> xci; | ||
| 41 | std::unique_ptr<AppLoader_NCA> nca_loader; | ||
| 42 | }; | ||
| 43 | |||
| 44 | } // namespace Loader | ||
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index e753e3436..1133bcbaf 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp | |||
| @@ -14,7 +14,6 @@ | |||
| 14 | #include "common/swap.h" | 14 | #include "common/swap.h" |
| 15 | #include "core/arm/arm_interface.h" | 15 | #include "core/arm/arm_interface.h" |
| 16 | #include "core/core.h" | 16 | #include "core/core.h" |
| 17 | #include "core/hle/kernel/memory.h" | ||
| 18 | #include "core/hle/kernel/process.h" | 17 | #include "core/hle/kernel/process.h" |
| 19 | #include "core/hle/lock.h" | 18 | #include "core/hle/lock.h" |
| 20 | #include "core/memory.h" | 19 | #include "core/memory.h" |
| @@ -24,8 +23,6 @@ | |||
| 24 | 23 | ||
| 25 | namespace Memory { | 24 | namespace Memory { |
| 26 | 25 | ||
| 27 | static std::array<u8, Memory::VRAM_SIZE> vram; | ||
| 28 | |||
| 29 | static PageTable* current_page_table = nullptr; | 26 | static PageTable* current_page_table = nullptr; |
| 30 | 27 | ||
| 31 | void SetCurrentPageTable(PageTable* page_table) { | 28 | void SetCurrentPageTable(PageTable* page_table) { |
| @@ -102,22 +99,6 @@ void RemoveDebugHook(PageTable& page_table, VAddr base, u64 size, MemoryHookPoin | |||
| 102 | } | 99 | } |
| 103 | 100 | ||
| 104 | /** | 101 | /** |
| 105 | * This function should only be called for virtual addreses with attribute `PageType::Special`. | ||
| 106 | */ | ||
| 107 | static std::set<MemoryHookPointer> GetSpecialHandlers(const PageTable& page_table, VAddr vaddr, | ||
| 108 | u64 size) { | ||
| 109 | std::set<MemoryHookPointer> result; | ||
| 110 | auto interval = boost::icl::discrete_interval<VAddr>::closed(vaddr, vaddr + size - 1); | ||
| 111 | auto interval_list = page_table.special_regions.equal_range(interval); | ||
| 112 | for (auto it = interval_list.first; it != interval_list.second; ++it) { | ||
| 113 | for (const auto& region : it->second) { | ||
| 114 | result.insert(region.handler); | ||
| 115 | } | ||
| 116 | } | ||
| 117 | return result; | ||
| 118 | } | ||
| 119 | |||
| 120 | /** | ||
| 121 | * Gets a pointer to the exact memory at the virtual address (i.e. not page aligned) | 102 | * Gets a pointer to the exact memory at the virtual address (i.e. not page aligned) |
| 122 | * using a VMA from the current process | 103 | * using a VMA from the current process |
| 123 | */ | 104 | */ |
| @@ -242,10 +223,6 @@ bool IsKernelVirtualAddress(const VAddr vaddr) { | |||
| 242 | return KERNEL_REGION_VADDR <= vaddr && vaddr < KERNEL_REGION_END; | 223 | return KERNEL_REGION_VADDR <= vaddr && vaddr < KERNEL_REGION_END; |
| 243 | } | 224 | } |
| 244 | 225 | ||
| 245 | bool IsValidPhysicalAddress(const PAddr paddr) { | ||
| 246 | return GetPhysicalPointer(paddr) != nullptr; | ||
| 247 | } | ||
| 248 | |||
| 249 | u8* GetPointer(const VAddr vaddr) { | 226 | u8* GetPointer(const VAddr vaddr) { |
| 250 | u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; | 227 | u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; |
| 251 | if (page_pointer) { | 228 | if (page_pointer) { |
| @@ -274,61 +251,6 @@ std::string ReadCString(VAddr vaddr, std::size_t max_length) { | |||
| 274 | return string; | 251 | return string; |
| 275 | } | 252 | } |
| 276 | 253 | ||
| 277 | u8* GetPhysicalPointer(PAddr address) { | ||
| 278 | struct MemoryArea { | ||
| 279 | PAddr paddr_base; | ||
| 280 | u32 size; | ||
| 281 | }; | ||
| 282 | |||
| 283 | static constexpr MemoryArea memory_areas[] = { | ||
| 284 | {VRAM_PADDR, VRAM_SIZE}, | ||
| 285 | {IO_AREA_PADDR, IO_AREA_SIZE}, | ||
| 286 | {DSP_RAM_PADDR, DSP_RAM_SIZE}, | ||
| 287 | {FCRAM_PADDR, FCRAM_N3DS_SIZE}, | ||
| 288 | }; | ||
| 289 | |||
| 290 | const auto area = | ||
| 291 | std::find_if(std::begin(memory_areas), std::end(memory_areas), [&](const auto& area) { | ||
| 292 | return address >= area.paddr_base && address < area.paddr_base + area.size; | ||
| 293 | }); | ||
| 294 | |||
| 295 | if (area == std::end(memory_areas)) { | ||
| 296 | LOG_ERROR(HW_Memory, "Unknown GetPhysicalPointer @ 0x{:016X}", address); | ||
| 297 | return nullptr; | ||
| 298 | } | ||
| 299 | |||
| 300 | if (area->paddr_base == IO_AREA_PADDR) { | ||
| 301 | LOG_ERROR(HW_Memory, "MMIO mappings are not supported yet. phys_addr={:016X}", address); | ||
| 302 | return nullptr; | ||
| 303 | } | ||
| 304 | |||
| 305 | u64 offset_into_region = address - area->paddr_base; | ||
| 306 | |||
| 307 | u8* target_pointer = nullptr; | ||
| 308 | switch (area->paddr_base) { | ||
| 309 | case VRAM_PADDR: | ||
| 310 | target_pointer = vram.data() + offset_into_region; | ||
| 311 | break; | ||
| 312 | case DSP_RAM_PADDR: | ||
| 313 | break; | ||
| 314 | case FCRAM_PADDR: | ||
| 315 | for (const auto& region : Kernel::memory_regions) { | ||
| 316 | if (offset_into_region >= region.base && | ||
| 317 | offset_into_region < region.base + region.size) { | ||
| 318 | target_pointer = | ||
| 319 | region.linear_heap_memory->data() + offset_into_region - region.base; | ||
| 320 | break; | ||
| 321 | } | ||
| 322 | } | ||
| 323 | ASSERT_MSG(target_pointer != nullptr, "Invalid FCRAM address"); | ||
| 324 | break; | ||
| 325 | default: | ||
| 326 | UNREACHABLE(); | ||
| 327 | } | ||
| 328 | |||
| 329 | return target_pointer; | ||
| 330 | } | ||
| 331 | |||
| 332 | void RasterizerMarkRegionCached(Tegra::GPUVAddr gpu_addr, u64 size, bool cached) { | 254 | void RasterizerMarkRegionCached(Tegra::GPUVAddr gpu_addr, u64 size, bool cached) { |
| 333 | if (gpu_addr == 0) { | 255 | if (gpu_addr == 0) { |
| 334 | return; | 256 | return; |
| @@ -404,43 +326,45 @@ void RasterizerMarkRegionCached(Tegra::GPUVAddr gpu_addr, u64 size, bool cached) | |||
| 404 | } | 326 | } |
| 405 | 327 | ||
| 406 | void RasterizerFlushVirtualRegion(VAddr start, u64 size, FlushMode mode) { | 328 | void RasterizerFlushVirtualRegion(VAddr start, u64 size, FlushMode mode) { |
| 329 | auto& system_instance = Core::System::GetInstance(); | ||
| 330 | |||
| 407 | // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be | 331 | // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be |
| 408 | // null here | 332 | // null here |
| 409 | if (VideoCore::g_renderer == nullptr) { | 333 | if (!system_instance.IsPoweredOn()) { |
| 410 | return; | 334 | return; |
| 411 | } | 335 | } |
| 412 | 336 | ||
| 413 | VAddr end = start + size; | 337 | VAddr end = start + size; |
| 414 | 338 | ||
| 415 | auto CheckRegion = [&](VAddr region_start, VAddr region_end) { | 339 | const auto CheckRegion = [&](VAddr region_start, VAddr region_end) { |
| 416 | if (start >= region_end || end <= region_start) { | 340 | if (start >= region_end || end <= region_start) { |
| 417 | // No overlap with region | 341 | // No overlap with region |
| 418 | return; | 342 | return; |
| 419 | } | 343 | } |
| 420 | 344 | ||
| 421 | VAddr overlap_start = std::max(start, region_start); | 345 | const VAddr overlap_start = std::max(start, region_start); |
| 422 | VAddr overlap_end = std::min(end, region_end); | 346 | const VAddr overlap_end = std::min(end, region_end); |
| 423 | 347 | ||
| 424 | std::vector<Tegra::GPUVAddr> gpu_addresses = | 348 | const std::vector<Tegra::GPUVAddr> gpu_addresses = |
| 425 | Core::System::GetInstance().GPU().memory_manager->CpuToGpuAddress(overlap_start); | 349 | system_instance.GPU().memory_manager->CpuToGpuAddress(overlap_start); |
| 426 | 350 | ||
| 427 | if (gpu_addresses.empty()) { | 351 | if (gpu_addresses.empty()) { |
| 428 | return; | 352 | return; |
| 429 | } | 353 | } |
| 430 | 354 | ||
| 431 | u64 overlap_size = overlap_end - overlap_start; | 355 | const u64 overlap_size = overlap_end - overlap_start; |
| 432 | 356 | ||
| 433 | for (const auto& gpu_address : gpu_addresses) { | 357 | for (const auto& gpu_address : gpu_addresses) { |
| 434 | auto* rasterizer = VideoCore::g_renderer->Rasterizer(); | 358 | auto& rasterizer = system_instance.Renderer().Rasterizer(); |
| 435 | switch (mode) { | 359 | switch (mode) { |
| 436 | case FlushMode::Flush: | 360 | case FlushMode::Flush: |
| 437 | rasterizer->FlushRegion(gpu_address, overlap_size); | 361 | rasterizer.FlushRegion(gpu_address, overlap_size); |
| 438 | break; | 362 | break; |
| 439 | case FlushMode::Invalidate: | 363 | case FlushMode::Invalidate: |
| 440 | rasterizer->InvalidateRegion(gpu_address, overlap_size); | 364 | rasterizer.InvalidateRegion(gpu_address, overlap_size); |
| 441 | break; | 365 | break; |
| 442 | case FlushMode::FlushAndInvalidate: | 366 | case FlushMode::FlushAndInvalidate: |
| 443 | rasterizer->FlushAndInvalidateRegion(gpu_address, overlap_size); | 367 | rasterizer.FlushAndInvalidateRegion(gpu_address, overlap_size); |
| 444 | break; | 368 | break; |
| 445 | } | 369 | } |
| 446 | } | 370 | } |
| @@ -666,48 +590,4 @@ void CopyBlock(VAddr dest_addr, VAddr src_addr, size_t size) { | |||
| 666 | CopyBlock(*Core::CurrentProcess(), dest_addr, src_addr, size); | 590 | CopyBlock(*Core::CurrentProcess(), dest_addr, src_addr, size); |
| 667 | } | 591 | } |
| 668 | 592 | ||
| 669 | boost::optional<PAddr> TryVirtualToPhysicalAddress(const VAddr addr) { | ||
| 670 | if (addr == 0) { | ||
| 671 | return 0; | ||
| 672 | } else if (addr >= VRAM_VADDR && addr < VRAM_VADDR_END) { | ||
| 673 | return addr - VRAM_VADDR + VRAM_PADDR; | ||
| 674 | } else if (addr >= LINEAR_HEAP_VADDR && addr < LINEAR_HEAP_VADDR_END) { | ||
| 675 | return addr - LINEAR_HEAP_VADDR + FCRAM_PADDR; | ||
| 676 | } else if (addr >= NEW_LINEAR_HEAP_VADDR && addr < NEW_LINEAR_HEAP_VADDR_END) { | ||
| 677 | return addr - NEW_LINEAR_HEAP_VADDR + FCRAM_PADDR; | ||
| 678 | } else if (addr >= DSP_RAM_VADDR && addr < DSP_RAM_VADDR_END) { | ||
| 679 | return addr - DSP_RAM_VADDR + DSP_RAM_PADDR; | ||
| 680 | } else if (addr >= IO_AREA_VADDR && addr < IO_AREA_VADDR_END) { | ||
| 681 | return addr - IO_AREA_VADDR + IO_AREA_PADDR; | ||
| 682 | } | ||
| 683 | |||
| 684 | return boost::none; | ||
| 685 | } | ||
| 686 | |||
| 687 | PAddr VirtualToPhysicalAddress(const VAddr addr) { | ||
| 688 | auto paddr = TryVirtualToPhysicalAddress(addr); | ||
| 689 | if (!paddr) { | ||
| 690 | LOG_ERROR(HW_Memory, "Unknown virtual address @ 0x{:016X}", addr); | ||
| 691 | // To help with debugging, set bit on address so that it's obviously invalid. | ||
| 692 | return addr | 0x80000000; | ||
| 693 | } | ||
| 694 | return *paddr; | ||
| 695 | } | ||
| 696 | |||
| 697 | boost::optional<VAddr> PhysicalToVirtualAddress(const PAddr addr) { | ||
| 698 | if (addr == 0) { | ||
| 699 | return 0; | ||
| 700 | } else if (addr >= VRAM_PADDR && addr < VRAM_PADDR_END) { | ||
| 701 | return addr - VRAM_PADDR + VRAM_VADDR; | ||
| 702 | } else if (addr >= FCRAM_PADDR && addr < FCRAM_PADDR_END) { | ||
| 703 | return addr - FCRAM_PADDR + Core::CurrentProcess()->GetLinearHeapAreaAddress(); | ||
| 704 | } else if (addr >= DSP_RAM_PADDR && addr < DSP_RAM_PADDR_END) { | ||
| 705 | return addr - DSP_RAM_PADDR + DSP_RAM_VADDR; | ||
| 706 | } else if (addr >= IO_AREA_PADDR && addr < IO_AREA_PADDR_END) { | ||
| 707 | return addr - IO_AREA_PADDR + IO_AREA_VADDR; | ||
| 708 | } | ||
| 709 | |||
| 710 | return boost::none; | ||
| 711 | } | ||
| 712 | |||
| 713 | } // namespace Memory | 593 | } // namespace Memory |
diff --git a/src/core/memory.h b/src/core/memory.h index 8d5d017a4..b7fb3b9ed 100644 --- a/src/core/memory.h +++ b/src/core/memory.h | |||
| @@ -6,12 +6,9 @@ | |||
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <cstddef> | 8 | #include <cstddef> |
| 9 | #include <map> | ||
| 10 | #include <string> | 9 | #include <string> |
| 11 | #include <tuple> | 10 | #include <tuple> |
| 12 | #include <vector> | ||
| 13 | #include <boost/icl/interval_map.hpp> | 11 | #include <boost/icl/interval_map.hpp> |
| 14 | #include <boost/optional.hpp> | ||
| 15 | #include "common/common_types.h" | 12 | #include "common/common_types.h" |
| 16 | #include "core/memory_hook.h" | 13 | #include "core/memory_hook.h" |
| 17 | #include "video_core/memory_manager.h" | 14 | #include "video_core/memory_manager.h" |
| @@ -85,40 +82,6 @@ struct PageTable { | |||
| 85 | std::array<PageType, PAGE_TABLE_NUM_ENTRIES> attributes; | 82 | std::array<PageType, PAGE_TABLE_NUM_ENTRIES> attributes; |
| 86 | }; | 83 | }; |
| 87 | 84 | ||
| 88 | /// Physical memory regions as seen from the ARM11 | ||
| 89 | enum : PAddr { | ||
| 90 | /// IO register area | ||
| 91 | IO_AREA_PADDR = 0x10100000, | ||
| 92 | IO_AREA_SIZE = 0x01000000, ///< IO area size (16MB) | ||
| 93 | IO_AREA_PADDR_END = IO_AREA_PADDR + IO_AREA_SIZE, | ||
| 94 | |||
| 95 | /// MPCore internal memory region | ||
| 96 | MPCORE_RAM_PADDR = 0x17E00000, | ||
| 97 | MPCORE_RAM_SIZE = 0x00002000, ///< MPCore internal memory size (8KB) | ||
| 98 | MPCORE_RAM_PADDR_END = MPCORE_RAM_PADDR + MPCORE_RAM_SIZE, | ||
| 99 | |||
| 100 | /// Video memory | ||
| 101 | VRAM_PADDR = 0x18000000, | ||
| 102 | VRAM_SIZE = 0x00600000, ///< VRAM size (6MB) | ||
| 103 | VRAM_PADDR_END = VRAM_PADDR + VRAM_SIZE, | ||
| 104 | |||
| 105 | /// DSP memory | ||
| 106 | DSP_RAM_PADDR = 0x1FF00000, | ||
| 107 | DSP_RAM_SIZE = 0x00080000, ///< DSP memory size (512KB) | ||
| 108 | DSP_RAM_PADDR_END = DSP_RAM_PADDR + DSP_RAM_SIZE, | ||
| 109 | |||
| 110 | /// AXI WRAM | ||
| 111 | AXI_WRAM_PADDR = 0x1FF80000, | ||
| 112 | AXI_WRAM_SIZE = 0x00080000, ///< AXI WRAM size (512KB) | ||
| 113 | AXI_WRAM_PADDR_END = AXI_WRAM_PADDR + AXI_WRAM_SIZE, | ||
| 114 | |||
| 115 | /// Main FCRAM | ||
| 116 | FCRAM_PADDR = 0x20000000, | ||
| 117 | FCRAM_SIZE = 0x08000000, ///< FCRAM size on the Old 3DS (128MB) | ||
| 118 | FCRAM_N3DS_SIZE = 0x10000000, ///< FCRAM size on the New 3DS (256MB) | ||
| 119 | FCRAM_PADDR_END = FCRAM_PADDR + FCRAM_SIZE, | ||
| 120 | }; | ||
| 121 | |||
| 122 | /// Virtual user-space memory regions | 85 | /// Virtual user-space memory regions |
| 123 | enum : VAddr { | 86 | enum : VAddr { |
| 124 | /// Where the application text, data and bss reside. | 87 | /// Where the application text, data and bss reside. |
| @@ -126,24 +89,6 @@ enum : VAddr { | |||
| 126 | PROCESS_IMAGE_MAX_SIZE = 0x08000000, | 89 | PROCESS_IMAGE_MAX_SIZE = 0x08000000, |
| 127 | PROCESS_IMAGE_VADDR_END = PROCESS_IMAGE_VADDR + PROCESS_IMAGE_MAX_SIZE, | 90 | PROCESS_IMAGE_VADDR_END = PROCESS_IMAGE_VADDR + PROCESS_IMAGE_MAX_SIZE, |
| 128 | 91 | ||
| 129 | /// Maps 1:1 to an offset in FCRAM. Used for HW allocations that need to be linear in physical | ||
| 130 | /// memory. | ||
| 131 | LINEAR_HEAP_VADDR = 0x14000000, | ||
| 132 | LINEAR_HEAP_SIZE = 0x08000000, | ||
| 133 | LINEAR_HEAP_VADDR_END = LINEAR_HEAP_VADDR + LINEAR_HEAP_SIZE, | ||
| 134 | |||
| 135 | /// Maps 1:1 to the IO register area. | ||
| 136 | IO_AREA_VADDR = 0x1EC00000, | ||
| 137 | IO_AREA_VADDR_END = IO_AREA_VADDR + IO_AREA_SIZE, | ||
| 138 | |||
| 139 | /// Maps 1:1 to VRAM. | ||
| 140 | VRAM_VADDR = 0x1F000000, | ||
| 141 | VRAM_VADDR_END = VRAM_VADDR + VRAM_SIZE, | ||
| 142 | |||
| 143 | /// Maps 1:1 to DSP memory. | ||
| 144 | DSP_RAM_VADDR = 0x1FF00000, | ||
| 145 | DSP_RAM_VADDR_END = DSP_RAM_VADDR + DSP_RAM_SIZE, | ||
| 146 | |||
| 147 | /// Read-only page containing kernel and system configuration values. | 92 | /// Read-only page containing kernel and system configuration values. |
| 148 | CONFIG_MEMORY_VADDR = 0x1FF80000, | 93 | CONFIG_MEMORY_VADDR = 0x1FF80000, |
| 149 | CONFIG_MEMORY_SIZE = 0x00001000, | 94 | CONFIG_MEMORY_SIZE = 0x00001000, |
| @@ -154,13 +99,8 @@ enum : VAddr { | |||
| 154 | SHARED_PAGE_SIZE = 0x00001000, | 99 | SHARED_PAGE_SIZE = 0x00001000, |
| 155 | SHARED_PAGE_VADDR_END = SHARED_PAGE_VADDR + SHARED_PAGE_SIZE, | 100 | SHARED_PAGE_VADDR_END = SHARED_PAGE_VADDR + SHARED_PAGE_SIZE, |
| 156 | 101 | ||
| 157 | /// Equivalent to LINEAR_HEAP_VADDR, but expanded to cover the extra memory in the New 3DS. | ||
| 158 | NEW_LINEAR_HEAP_VADDR = 0x30000000, | ||
| 159 | NEW_LINEAR_HEAP_SIZE = 0x10000000, | ||
| 160 | NEW_LINEAR_HEAP_VADDR_END = NEW_LINEAR_HEAP_VADDR + NEW_LINEAR_HEAP_SIZE, | ||
| 161 | |||
| 162 | /// Area where TLS (Thread-Local Storage) buffers are allocated. | 102 | /// Area where TLS (Thread-Local Storage) buffers are allocated. |
| 163 | TLS_AREA_VADDR = NEW_LINEAR_HEAP_VADDR_END, | 103 | TLS_AREA_VADDR = 0x40000000, |
| 164 | TLS_ENTRY_SIZE = 0x200, | 104 | TLS_ENTRY_SIZE = 0x200, |
| 165 | TLS_AREA_SIZE = 0x10000000, | 105 | TLS_AREA_SIZE = 0x10000000, |
| 166 | TLS_AREA_VADDR_END = TLS_AREA_VADDR + TLS_AREA_SIZE, | 106 | TLS_AREA_VADDR_END = TLS_AREA_VADDR + TLS_AREA_SIZE, |
| @@ -200,12 +140,10 @@ void SetCurrentPageTable(PageTable* page_table); | |||
| 200 | PageTable* GetCurrentPageTable(); | 140 | PageTable* GetCurrentPageTable(); |
| 201 | 141 | ||
| 202 | /// Determines if the given VAddr is valid for the specified process. | 142 | /// Determines if the given VAddr is valid for the specified process. |
| 203 | bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr); | 143 | bool IsValidVirtualAddress(const Kernel::Process& process, VAddr vaddr); |
| 204 | bool IsValidVirtualAddress(const VAddr addr); | 144 | bool IsValidVirtualAddress(VAddr vaddr); |
| 205 | /// Determines if the given VAddr is a kernel address | 145 | /// Determines if the given VAddr is a kernel address |
| 206 | bool IsKernelVirtualAddress(const VAddr addr); | 146 | bool IsKernelVirtualAddress(VAddr vaddr); |
| 207 | |||
| 208 | bool IsValidPhysicalAddress(const PAddr addr); | ||
| 209 | 147 | ||
| 210 | u8 Read8(VAddr addr); | 148 | u8 Read8(VAddr addr); |
| 211 | u16 Read16(VAddr addr); | 149 | u16 Read16(VAddr addr); |
| @@ -217,42 +155,17 @@ void Write16(VAddr addr, u16 data); | |||
| 217 | void Write32(VAddr addr, u32 data); | 155 | void Write32(VAddr addr, u32 data); |
| 218 | void Write64(VAddr addr, u64 data); | 156 | void Write64(VAddr addr, u64 data); |
| 219 | 157 | ||
| 220 | void ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_buffer, | 158 | void ReadBlock(const Kernel::Process& process, VAddr src_addr, void* dest_buffer, size_t size); |
| 221 | size_t size); | 159 | void ReadBlock(VAddr src_addr, void* dest_buffer, size_t size); |
| 222 | void ReadBlock(const VAddr src_addr, void* dest_buffer, size_t size); | 160 | void WriteBlock(const Kernel::Process& process, VAddr dest_addr, const void* src_buffer, |
| 223 | void WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const void* src_buffer, | ||
| 224 | size_t size); | 161 | size_t size); |
| 225 | void WriteBlock(const VAddr dest_addr, const void* src_buffer, size_t size); | 162 | void WriteBlock(VAddr dest_addr, const void* src_buffer, size_t size); |
| 226 | void ZeroBlock(const VAddr dest_addr, const size_t size); | 163 | void ZeroBlock(const Kernel::Process& process, VAddr dest_addr, size_t size); |
| 227 | void CopyBlock(VAddr dest_addr, VAddr src_addr, size_t size); | 164 | void CopyBlock(VAddr dest_addr, VAddr src_addr, size_t size); |
| 228 | 165 | ||
| 229 | u8* GetPointer(VAddr virtual_address); | 166 | u8* GetPointer(VAddr vaddr); |
| 230 | |||
| 231 | std::string ReadCString(VAddr virtual_address, std::size_t max_length); | ||
| 232 | |||
| 233 | /** | ||
| 234 | * Converts a virtual address inside a region with 1:1 mapping to physical memory to a physical | ||
| 235 | * address. This should be used by services to translate addresses for use by the hardware. | ||
| 236 | */ | ||
| 237 | boost::optional<PAddr> TryVirtualToPhysicalAddress(VAddr addr); | ||
| 238 | |||
| 239 | /** | ||
| 240 | * Converts a virtual address inside a region with 1:1 mapping to physical memory to a physical | ||
| 241 | * address. This should be used by services to translate addresses for use by the hardware. | ||
| 242 | * | ||
| 243 | * @deprecated Use TryVirtualToPhysicalAddress(), which reports failure. | ||
| 244 | */ | ||
| 245 | PAddr VirtualToPhysicalAddress(VAddr addr); | ||
| 246 | 167 | ||
| 247 | /** | 168 | std::string ReadCString(VAddr vaddr, std::size_t max_length); |
| 248 | * Undoes a mapping performed by VirtualToPhysicalAddress(). | ||
| 249 | */ | ||
| 250 | boost::optional<VAddr> PhysicalToVirtualAddress(PAddr addr); | ||
| 251 | |||
| 252 | /** | ||
| 253 | * Gets a pointer to the memory region beginning at the specified physical address. | ||
| 254 | */ | ||
| 255 | u8* GetPhysicalPointer(PAddr address); | ||
| 256 | 169 | ||
| 257 | enum class FlushMode { | 170 | enum class FlushMode { |
| 258 | /// Write back modified surfaces to RAM | 171 | /// Write back modified surfaces to RAM |
| @@ -266,7 +179,7 @@ enum class FlushMode { | |||
| 266 | /** | 179 | /** |
| 267 | * Mark each page touching the region as cached. | 180 | * Mark each page touching the region as cached. |
| 268 | */ | 181 | */ |
| 269 | void RasterizerMarkRegionCached(Tegra::GPUVAddr start, u64 size, bool cached); | 182 | void RasterizerMarkRegionCached(Tegra::GPUVAddr gpu_addr, u64 size, bool cached); |
| 270 | 183 | ||
| 271 | /** | 184 | /** |
| 272 | * Flushes and invalidates any externally cached rasterizer resources touching the given virtual | 185 | * Flushes and invalidates any externally cached rasterizer resources touching the given virtual |
diff --git a/src/core/perf_stats.cpp b/src/core/perf_stats.cpp index 5f53b16d3..8e09b9b63 100644 --- a/src/core/perf_stats.cpp +++ b/src/core/perf_stats.cpp | |||
| @@ -40,22 +40,21 @@ void PerfStats::EndGameFrame() { | |||
| 40 | game_frames += 1; | 40 | game_frames += 1; |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | PerfStats::Results PerfStats::GetAndResetStats(u64 current_system_time_us) { | 43 | PerfStats::Results PerfStats::GetAndResetStats(microseconds current_system_time_us) { |
| 44 | std::lock_guard<std::mutex> lock(object_mutex); | 44 | std::lock_guard<std::mutex> lock(object_mutex); |
| 45 | 45 | ||
| 46 | auto now = Clock::now(); | 46 | const auto now = Clock::now(); |
| 47 | // Walltime elapsed since stats were reset | 47 | // Walltime elapsed since stats were reset |
| 48 | auto interval = duration_cast<DoubleSecs>(now - reset_point).count(); | 48 | const auto interval = duration_cast<DoubleSecs>(now - reset_point).count(); |
| 49 | 49 | ||
| 50 | auto system_us_per_second = | 50 | const auto system_us_per_second = (current_system_time_us - reset_point_system_us) / interval; |
| 51 | static_cast<double>(current_system_time_us - reset_point_system_us) / interval; | ||
| 52 | 51 | ||
| 53 | Results results{}; | 52 | Results results{}; |
| 54 | results.system_fps = static_cast<double>(system_frames) / interval; | 53 | results.system_fps = static_cast<double>(system_frames) / interval; |
| 55 | results.game_fps = static_cast<double>(game_frames) / interval; | 54 | results.game_fps = static_cast<double>(game_frames) / interval; |
| 56 | results.frametime = duration_cast<DoubleSecs>(accumulated_frametime).count() / | 55 | results.frametime = duration_cast<DoubleSecs>(accumulated_frametime).count() / |
| 57 | static_cast<double>(system_frames); | 56 | static_cast<double>(system_frames); |
| 58 | results.emulation_speed = system_us_per_second / 1'000'000.0; | 57 | results.emulation_speed = system_us_per_second.count() / 1'000'000.0; |
| 59 | 58 | ||
| 60 | // Reset counters | 59 | // Reset counters |
| 61 | reset_point = now; | 60 | reset_point = now; |
| @@ -74,10 +73,10 @@ double PerfStats::GetLastFrameTimeScale() { | |||
| 74 | return duration_cast<DoubleSecs>(previous_frame_length).count() / FRAME_LENGTH; | 73 | return duration_cast<DoubleSecs>(previous_frame_length).count() / FRAME_LENGTH; |
| 75 | } | 74 | } |
| 76 | 75 | ||
| 77 | void FrameLimiter::DoFrameLimiting(u64 current_system_time_us) { | 76 | void FrameLimiter::DoFrameLimiting(microseconds current_system_time_us) { |
| 78 | // Max lag caused by slow frames. Can be adjusted to compensate for too many slow frames. Higher | 77 | // Max lag caused by slow frames. Can be adjusted to compensate for too many slow frames. Higher |
| 79 | // values increase the time needed to recover and limit framerate again after spikes. | 78 | // values increase the time needed to recover and limit framerate again after spikes. |
| 80 | constexpr microseconds MAX_LAG_TIME_US = 25ms; | 79 | constexpr microseconds MAX_LAG_TIME_US = 25us; |
| 81 | 80 | ||
| 82 | if (!Settings::values.toggle_framelimit) { | 81 | if (!Settings::values.toggle_framelimit) { |
| 83 | return; | 82 | return; |
| @@ -85,7 +84,7 @@ void FrameLimiter::DoFrameLimiting(u64 current_system_time_us) { | |||
| 85 | 84 | ||
| 86 | auto now = Clock::now(); | 85 | auto now = Clock::now(); |
| 87 | 86 | ||
| 88 | frame_limiting_delta_err += microseconds(current_system_time_us - previous_system_time_us); | 87 | frame_limiting_delta_err += current_system_time_us - previous_system_time_us; |
| 89 | frame_limiting_delta_err -= duration_cast<microseconds>(now - previous_walltime); | 88 | frame_limiting_delta_err -= duration_cast<microseconds>(now - previous_walltime); |
| 90 | frame_limiting_delta_err = | 89 | frame_limiting_delta_err = |
| 91 | std::clamp(frame_limiting_delta_err, -MAX_LAG_TIME_US, MAX_LAG_TIME_US); | 90 | std::clamp(frame_limiting_delta_err, -MAX_LAG_TIME_US, MAX_LAG_TIME_US); |
diff --git a/src/core/perf_stats.h b/src/core/perf_stats.h index 362b205c8..6e4619701 100644 --- a/src/core/perf_stats.h +++ b/src/core/perf_stats.h | |||
| @@ -33,7 +33,7 @@ public: | |||
| 33 | void EndSystemFrame(); | 33 | void EndSystemFrame(); |
| 34 | void EndGameFrame(); | 34 | void EndGameFrame(); |
| 35 | 35 | ||
| 36 | Results GetAndResetStats(u64 current_system_time_us); | 36 | Results GetAndResetStats(std::chrono::microseconds current_system_time_us); |
| 37 | 37 | ||
| 38 | /** | 38 | /** |
| 39 | * Gets the ratio between walltime and the emulated time of the previous system frame. This is | 39 | * Gets the ratio between walltime and the emulated time of the previous system frame. This is |
| @@ -47,7 +47,7 @@ private: | |||
| 47 | /// Point when the cumulative counters were reset | 47 | /// Point when the cumulative counters were reset |
| 48 | Clock::time_point reset_point = Clock::now(); | 48 | Clock::time_point reset_point = Clock::now(); |
| 49 | /// System time when the cumulative counters were reset | 49 | /// System time when the cumulative counters were reset |
| 50 | u64 reset_point_system_us = 0; | 50 | std::chrono::microseconds reset_point_system_us{0}; |
| 51 | 51 | ||
| 52 | /// Cumulative duration (excluding v-sync/frame-limiting) of frames since last reset | 52 | /// Cumulative duration (excluding v-sync/frame-limiting) of frames since last reset |
| 53 | Clock::duration accumulated_frametime = Clock::duration::zero(); | 53 | Clock::duration accumulated_frametime = Clock::duration::zero(); |
| @@ -68,11 +68,11 @@ class FrameLimiter { | |||
| 68 | public: | 68 | public: |
| 69 | using Clock = std::chrono::high_resolution_clock; | 69 | using Clock = std::chrono::high_resolution_clock; |
| 70 | 70 | ||
| 71 | void DoFrameLimiting(u64 current_system_time_us); | 71 | void DoFrameLimiting(std::chrono::microseconds current_system_time_us); |
| 72 | 72 | ||
| 73 | private: | 73 | private: |
| 74 | /// Emulated system time (in microseconds) at the last limiter invocation | 74 | /// Emulated system time (in microseconds) at the last limiter invocation |
| 75 | u64 previous_system_time_us = 0; | 75 | std::chrono::microseconds previous_system_time_us{0}; |
| 76 | /// Walltime at the last limiter invocation | 76 | /// Walltime at the last limiter invocation |
| 77 | Clock::time_point previous_walltime = Clock::now(); | 77 | Clock::time_point previous_walltime = Clock::now(); |
| 78 | 78 | ||
diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 444bcc387..a4623223d 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp | |||
| @@ -2,13 +2,13 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "core/core.h" | ||
| 5 | #include "core/gdbstub/gdbstub.h" | 6 | #include "core/gdbstub/gdbstub.h" |
| 6 | #include "core/hle/service/hid/hid.h" | 7 | #include "core/hle/service/hid/hid.h" |
| 7 | #include "core/settings.h" | 8 | #include "core/settings.h" |
| 9 | #include "video_core/renderer_base.h" | ||
| 8 | #include "video_core/video_core.h" | 10 | #include "video_core/video_core.h" |
| 9 | 11 | ||
| 10 | #include "core/frontend/emu_window.h" | ||
| 11 | |||
| 12 | namespace Settings { | 12 | namespace Settings { |
| 13 | 13 | ||
| 14 | Values values = {}; | 14 | Values values = {}; |
| @@ -20,9 +20,9 @@ void Apply() { | |||
| 20 | 20 | ||
| 21 | VideoCore::g_toggle_framelimit_enabled = values.toggle_framelimit; | 21 | VideoCore::g_toggle_framelimit_enabled = values.toggle_framelimit; |
| 22 | 22 | ||
| 23 | if (VideoCore::g_emu_window) { | 23 | auto& system_instance = Core::System::GetInstance(); |
| 24 | auto layout = VideoCore::g_emu_window->GetFramebufferLayout(); | 24 | if (system_instance.IsPoweredOn()) { |
| 25 | VideoCore::g_emu_window->UpdateCurrentFramebufferLayout(layout.width, layout.height); | 25 | system_instance.Renderer().UpdateCurrentFramebufferLayout(); |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | Service::HID::ReloadInputDevices(); | 28 | Service::HID::ReloadInputDevices(); |
diff --git a/src/core/settings.h b/src/core/settings.h index 7150d9755..73dc3061f 100644 --- a/src/core/settings.h +++ b/src/core/settings.h | |||
| @@ -112,6 +112,8 @@ static const std::array<const char*, NumAnalogs> mapping = {{ | |||
| 112 | struct Values { | 112 | struct Values { |
| 113 | // System | 113 | // System |
| 114 | bool use_docked_mode; | 114 | bool use_docked_mode; |
| 115 | std::string username; | ||
| 116 | int language_index; | ||
| 115 | 117 | ||
| 116 | // Controls | 118 | // Controls |
| 117 | std::array<std::string, NativeButton::NumButtons> buttons; | 119 | std::array<std::string, NativeButton::NumButtons> buttons; |
| @@ -137,6 +139,13 @@ struct Values { | |||
| 137 | 139 | ||
| 138 | std::string log_filter; | 140 | std::string log_filter; |
| 139 | 141 | ||
| 142 | bool use_dev_keys; | ||
| 143 | |||
| 144 | // Audio | ||
| 145 | std::string sink_id; | ||
| 146 | std::string audio_device_id; | ||
| 147 | float volume; | ||
| 148 | |||
| 140 | // Debugging | 149 | // Debugging |
| 141 | bool use_gdbstub; | 150 | bool use_gdbstub; |
| 142 | u16 gdbstub_port; | 151 | u16 gdbstub_port; |
diff --git a/src/input_common/keyboard.cpp b/src/input_common/keyboard.cpp index 0f0d10f23..525fe6abc 100644 --- a/src/input_common/keyboard.cpp +++ b/src/input_common/keyboard.cpp | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include <atomic> | 5 | #include <atomic> |
| 6 | #include <list> | 6 | #include <list> |
| 7 | #include <mutex> | 7 | #include <mutex> |
| 8 | #include <utility> | ||
| 8 | #include "input_common/keyboard.h" | 9 | #include "input_common/keyboard.h" |
| 9 | 10 | ||
| 10 | namespace InputCommon { | 11 | namespace InputCommon { |
| @@ -12,9 +13,9 @@ namespace InputCommon { | |||
| 12 | class KeyButton final : public Input::ButtonDevice { | 13 | class KeyButton final : public Input::ButtonDevice { |
| 13 | public: | 14 | public: |
| 14 | explicit KeyButton(std::shared_ptr<KeyButtonList> key_button_list_) | 15 | explicit KeyButton(std::shared_ptr<KeyButtonList> key_button_list_) |
| 15 | : key_button_list(key_button_list_) {} | 16 | : key_button_list(std::move(key_button_list_)) {} |
| 16 | 17 | ||
| 17 | ~KeyButton(); | 18 | ~KeyButton() override; |
| 18 | 19 | ||
| 19 | bool GetStatus() const override { | 20 | bool GetStatus() const override { |
| 20 | return status.load(); | 21 | return status.load(); |
diff --git a/src/input_common/motion_emu.cpp b/src/input_common/motion_emu.cpp index caffe48cb..9570c060e 100644 --- a/src/input_common/motion_emu.cpp +++ b/src/input_common/motion_emu.cpp | |||
| @@ -131,7 +131,7 @@ public: | |||
| 131 | device = std::make_shared<MotionEmuDevice>(update_millisecond, sensitivity); | 131 | device = std::make_shared<MotionEmuDevice>(update_millisecond, sensitivity); |
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | std::tuple<Math::Vec3<float>, Math::Vec3<float>> GetStatus() const { | 134 | std::tuple<Math::Vec3<float>, Math::Vec3<float>> GetStatus() const override { |
| 135 | return device->GetStatus(); | 135 | return device->GetStatus(); |
| 136 | } | 136 | } |
| 137 | 137 | ||
diff --git a/src/input_common/sdl/sdl.cpp b/src/input_common/sdl/sdl.cpp index 8d117c2d4..d1b960fd7 100644 --- a/src/input_common/sdl/sdl.cpp +++ b/src/input_common/sdl/sdl.cpp | |||
| @@ -82,7 +82,7 @@ private: | |||
| 82 | class SDLButton final : public Input::ButtonDevice { | 82 | class SDLButton final : public Input::ButtonDevice { |
| 83 | public: | 83 | public: |
| 84 | explicit SDLButton(std::shared_ptr<SDLJoystick> joystick_, int button_) | 84 | explicit SDLButton(std::shared_ptr<SDLJoystick> joystick_, int button_) |
| 85 | : joystick(joystick_), button(button_) {} | 85 | : joystick(std::move(joystick_)), button(button_) {} |
| 86 | 86 | ||
| 87 | bool GetStatus() const override { | 87 | bool GetStatus() const override { |
| 88 | return joystick->GetButton(button); | 88 | return joystick->GetButton(button); |
| @@ -96,7 +96,7 @@ private: | |||
| 96 | class SDLDirectionButton final : public Input::ButtonDevice { | 96 | class SDLDirectionButton final : public Input::ButtonDevice { |
| 97 | public: | 97 | public: |
| 98 | explicit SDLDirectionButton(std::shared_ptr<SDLJoystick> joystick_, int hat_, Uint8 direction_) | 98 | explicit SDLDirectionButton(std::shared_ptr<SDLJoystick> joystick_, int hat_, Uint8 direction_) |
| 99 | : joystick(joystick_), hat(hat_), direction(direction_) {} | 99 | : joystick(std::move(joystick_)), hat(hat_), direction(direction_) {} |
| 100 | 100 | ||
| 101 | bool GetStatus() const override { | 101 | bool GetStatus() const override { |
| 102 | return joystick->GetHatDirection(hat, direction); | 102 | return joystick->GetHatDirection(hat, direction); |
| @@ -112,7 +112,7 @@ class SDLAxisButton final : public Input::ButtonDevice { | |||
| 112 | public: | 112 | public: |
| 113 | explicit SDLAxisButton(std::shared_ptr<SDLJoystick> joystick_, int axis_, float threshold_, | 113 | explicit SDLAxisButton(std::shared_ptr<SDLJoystick> joystick_, int axis_, float threshold_, |
| 114 | bool trigger_if_greater_) | 114 | bool trigger_if_greater_) |
| 115 | : joystick(joystick_), axis(axis_), threshold(threshold_), | 115 | : joystick(std::move(joystick_)), axis(axis_), threshold(threshold_), |
| 116 | trigger_if_greater(trigger_if_greater_) {} | 116 | trigger_if_greater(trigger_if_greater_) {} |
| 117 | 117 | ||
| 118 | bool GetStatus() const override { | 118 | bool GetStatus() const override { |
| @@ -132,7 +132,7 @@ private: | |||
| 132 | class SDLAnalog final : public Input::AnalogDevice { | 132 | class SDLAnalog final : public Input::AnalogDevice { |
| 133 | public: | 133 | public: |
| 134 | SDLAnalog(std::shared_ptr<SDLJoystick> joystick_, int axis_x_, int axis_y_) | 134 | SDLAnalog(std::shared_ptr<SDLJoystick> joystick_, int axis_x_, int axis_y_) |
| 135 | : joystick(joystick_), axis_x(axis_x_), axis_y(axis_y_) {} | 135 | : joystick(std::move(joystick_)), axis_x(axis_x_), axis_y(axis_y_) {} |
| 136 | 136 | ||
| 137 | std::tuple<float, float> GetStatus() const override { | 137 | std::tuple<float, float> GetStatus() const override { |
| 138 | return joystick->GetAnalog(axis_x, axis_y); | 138 | return joystick->GetAnalog(axis_x, axis_y); |
| @@ -314,10 +314,6 @@ namespace Polling { | |||
| 314 | 314 | ||
| 315 | class SDLPoller : public InputCommon::Polling::DevicePoller { | 315 | class SDLPoller : public InputCommon::Polling::DevicePoller { |
| 316 | public: | 316 | public: |
| 317 | SDLPoller() = default; | ||
| 318 | |||
| 319 | ~SDLPoller() = default; | ||
| 320 | |||
| 321 | void Start() override { | 317 | void Start() override { |
| 322 | // SDL joysticks must be opened, otherwise they don't generate events | 318 | // SDL joysticks must be opened, otherwise they don't generate events |
| 323 | SDL_JoystickUpdate(); | 319 | SDL_JoystickUpdate(); |
| @@ -341,10 +337,6 @@ private: | |||
| 341 | 337 | ||
| 342 | class SDLButtonPoller final : public SDLPoller { | 338 | class SDLButtonPoller final : public SDLPoller { |
| 343 | public: | 339 | public: |
| 344 | SDLButtonPoller() = default; | ||
| 345 | |||
| 346 | ~SDLButtonPoller() = default; | ||
| 347 | |||
| 348 | Common::ParamPackage GetNextInput() override { | 340 | Common::ParamPackage GetNextInput() override { |
| 349 | SDL_Event event; | 341 | SDL_Event event; |
| 350 | while (SDL_PollEvent(&event)) { | 342 | while (SDL_PollEvent(&event)) { |
| @@ -364,10 +356,6 @@ public: | |||
| 364 | 356 | ||
| 365 | class SDLAnalogPoller final : public SDLPoller { | 357 | class SDLAnalogPoller final : public SDLPoller { |
| 366 | public: | 358 | public: |
| 367 | SDLAnalogPoller() = default; | ||
| 368 | |||
| 369 | ~SDLAnalogPoller() = default; | ||
| 370 | |||
| 371 | void Start() override { | 359 | void Start() override { |
| 372 | SDLPoller::Start(); | 360 | SDLPoller::Start(); |
| 373 | 361 | ||
diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 6a0a62ecc..4d74bb395 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt | |||
| @@ -3,7 +3,6 @@ add_executable(tests | |||
| 3 | core/arm/arm_test_common.cpp | 3 | core/arm/arm_test_common.cpp |
| 4 | core/arm/arm_test_common.h | 4 | core/arm/arm_test_common.h |
| 5 | core/core_timing.cpp | 5 | core/core_timing.cpp |
| 6 | core/memory/memory.cpp | ||
| 7 | glad.cpp | 6 | glad.cpp |
| 8 | tests.cpp | 7 | tests.cpp |
| 9 | ) | 8 | ) |
diff --git a/src/tests/core/memory/memory.cpp b/src/tests/core/memory/memory.cpp deleted file mode 100644 index 165496a54..000000000 --- a/src/tests/core/memory/memory.cpp +++ /dev/null | |||
| @@ -1,56 +0,0 @@ | |||
| 1 | // Copyright 2017 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <catch.hpp> | ||
| 6 | #include "core/hle/kernel/memory.h" | ||
| 7 | #include "core/hle/kernel/process.h" | ||
| 8 | #include "core/memory.h" | ||
| 9 | |||
| 10 | TEST_CASE("Memory::IsValidVirtualAddress", "[core][memory][!hide]") { | ||
| 11 | SECTION("these regions should not be mapped on an empty process") { | ||
| 12 | auto process = Kernel::Process::Create(""); | ||
| 13 | CHECK(Memory::IsValidVirtualAddress(*process, Memory::PROCESS_IMAGE_VADDR) == false); | ||
| 14 | CHECK(Memory::IsValidVirtualAddress(*process, Memory::HEAP_VADDR) == false); | ||
| 15 | CHECK(Memory::IsValidVirtualAddress(*process, Memory::LINEAR_HEAP_VADDR) == false); | ||
| 16 | CHECK(Memory::IsValidVirtualAddress(*process, Memory::VRAM_VADDR) == false); | ||
| 17 | CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == false); | ||
| 18 | CHECK(Memory::IsValidVirtualAddress(*process, Memory::SHARED_PAGE_VADDR) == false); | ||
| 19 | CHECK(Memory::IsValidVirtualAddress(*process, Memory::TLS_AREA_VADDR) == false); | ||
| 20 | } | ||
| 21 | |||
| 22 | SECTION("CONFIG_MEMORY_VADDR and SHARED_PAGE_VADDR should be valid after mapping them") { | ||
| 23 | auto process = Kernel::Process::Create(""); | ||
| 24 | Kernel::MapSharedPages(process->vm_manager); | ||
| 25 | CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == true); | ||
| 26 | CHECK(Memory::IsValidVirtualAddress(*process, Memory::SHARED_PAGE_VADDR) == true); | ||
| 27 | } | ||
| 28 | |||
| 29 | SECTION("special regions should be valid after mapping them") { | ||
| 30 | auto process = Kernel::Process::Create(""); | ||
| 31 | SECTION("VRAM") { | ||
| 32 | Kernel::HandleSpecialMapping(process->vm_manager, | ||
| 33 | {Memory::VRAM_VADDR, Memory::VRAM_SIZE, false, false}); | ||
| 34 | CHECK(Memory::IsValidVirtualAddress(*process, Memory::VRAM_VADDR) == true); | ||
| 35 | } | ||
| 36 | |||
| 37 | SECTION("IO (Not yet implemented)") { | ||
| 38 | Kernel::HandleSpecialMapping( | ||
| 39 | process->vm_manager, {Memory::IO_AREA_VADDR, Memory::IO_AREA_SIZE, false, false}); | ||
| 40 | CHECK_FALSE(Memory::IsValidVirtualAddress(*process, Memory::IO_AREA_VADDR) == true); | ||
| 41 | } | ||
| 42 | |||
| 43 | SECTION("DSP") { | ||
| 44 | Kernel::HandleSpecialMapping( | ||
| 45 | process->vm_manager, {Memory::DSP_RAM_VADDR, Memory::DSP_RAM_SIZE, false, false}); | ||
| 46 | CHECK(Memory::IsValidVirtualAddress(*process, Memory::DSP_RAM_VADDR) == true); | ||
| 47 | } | ||
| 48 | } | ||
| 49 | |||
| 50 | SECTION("Unmapping a VAddr should make it invalid") { | ||
| 51 | auto process = Kernel::Process::Create(""); | ||
| 52 | Kernel::MapSharedPages(process->vm_manager); | ||
| 53 | process->vm_manager.UnmapRange(Memory::CONFIG_MEMORY_VADDR, Memory::CONFIG_MEMORY_SIZE); | ||
| 54 | CHECK(Memory::IsValidVirtualAddress(*process, Memory::CONFIG_MEMORY_VADDR) == false); | ||
| 55 | } | ||
| 56 | } | ||
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 0e205ed72..5c0ae8009 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp | |||
| @@ -19,8 +19,8 @@ namespace Engines { | |||
| 19 | /// First register id that is actually a Macro call. | 19 | /// First register id that is actually a Macro call. |
| 20 | constexpr u32 MacroRegistersStart = 0xE00; | 20 | constexpr u32 MacroRegistersStart = 0xE00; |
| 21 | 21 | ||
| 22 | Maxwell3D::Maxwell3D(MemoryManager& memory_manager) | 22 | Maxwell3D::Maxwell3D(VideoCore::RasterizerInterface& rasterizer, MemoryManager& memory_manager) |
| 23 | : memory_manager(memory_manager), macro_interpreter(*this) {} | 23 | : memory_manager(memory_manager), rasterizer{rasterizer}, macro_interpreter(*this) {} |
| 24 | 24 | ||
| 25 | void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) { | 25 | void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) { |
| 26 | auto macro_code = uploaded_macros.find(method); | 26 | auto macro_code = uploaded_macros.find(method); |
| @@ -130,7 +130,7 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) { | |||
| 130 | break; | 130 | break; |
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | VideoCore::g_renderer->Rasterizer()->NotifyMaxwellRegisterChanged(method); | 133 | rasterizer.NotifyMaxwellRegisterChanged(method); |
| 134 | 134 | ||
| 135 | if (debug_context) { | 135 | if (debug_context) { |
| 136 | debug_context->OnEvent(Tegra::DebugContext::Event::MaxwellCommandProcessed, nullptr); | 136 | debug_context->OnEvent(Tegra::DebugContext::Event::MaxwellCommandProcessed, nullptr); |
| @@ -218,7 +218,7 @@ void Maxwell3D::DrawArrays() { | |||
| 218 | } | 218 | } |
| 219 | 219 | ||
| 220 | const bool is_indexed{regs.index_array.count && !regs.vertex_buffer.count}; | 220 | const bool is_indexed{regs.index_array.count && !regs.vertex_buffer.count}; |
| 221 | VideoCore::g_renderer->Rasterizer()->AccelerateDrawBatch(is_indexed); | 221 | rasterizer.AccelerateDrawBatch(is_indexed); |
| 222 | 222 | ||
| 223 | // TODO(bunnei): Below, we reset vertex count so that we can use these registers to determine if | 223 | // TODO(bunnei): Below, we reset vertex count so that we can use these registers to determine if |
| 224 | // the game is trying to draw indexed or direct mode. This needs to be verified on HW still - | 224 | // the game is trying to draw indexed or direct mode. This needs to be verified on HW still - |
| @@ -285,8 +285,6 @@ Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const { | |||
| 285 | 285 | ||
| 286 | // TODO(Subv): Different data types for separate components are not supported | 286 | // TODO(Subv): Different data types for separate components are not supported |
| 287 | ASSERT(r_type == g_type && r_type == b_type && r_type == a_type); | 287 | ASSERT(r_type == g_type && r_type == b_type && r_type == a_type); |
| 288 | // TODO(Subv): Only UNORM formats are supported for now. | ||
| 289 | ASSERT(r_type == Texture::ComponentType::UNORM); | ||
| 290 | 288 | ||
| 291 | return tic_entry; | 289 | return tic_entry; |
| 292 | } | 290 | } |
| @@ -393,7 +391,7 @@ void Maxwell3D::ProcessClearBuffers() { | |||
| 393 | regs.clear_buffers.R == regs.clear_buffers.B && | 391 | regs.clear_buffers.R == regs.clear_buffers.B && |
| 394 | regs.clear_buffers.R == regs.clear_buffers.A); | 392 | regs.clear_buffers.R == regs.clear_buffers.A); |
| 395 | 393 | ||
| 396 | VideoCore::g_renderer->Rasterizer()->Clear(); | 394 | rasterizer.Clear(); |
| 397 | } | 395 | } |
| 398 | 396 | ||
| 399 | } // namespace Engines | 397 | } // namespace Engines |
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 3c32f1067..4d0ff96a5 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -17,6 +17,10 @@ | |||
| 17 | #include "video_core/memory_manager.h" | 17 | #include "video_core/memory_manager.h" |
| 18 | #include "video_core/textures/texture.h" | 18 | #include "video_core/textures/texture.h" |
| 19 | 19 | ||
| 20 | namespace VideoCore { | ||
| 21 | class RasterizerInterface; | ||
| 22 | } | ||
| 23 | |||
| 20 | namespace Tegra::Engines { | 24 | namespace Tegra::Engines { |
| 21 | 25 | ||
| 22 | #define MAXWELL3D_REG_INDEX(field_name) \ | 26 | #define MAXWELL3D_REG_INDEX(field_name) \ |
| @@ -24,7 +28,7 @@ namespace Tegra::Engines { | |||
| 24 | 28 | ||
| 25 | class Maxwell3D final { | 29 | class Maxwell3D final { |
| 26 | public: | 30 | public: |
| 27 | explicit Maxwell3D(MemoryManager& memory_manager); | 31 | explicit Maxwell3D(VideoCore::RasterizerInterface& rasterizer, MemoryManager& memory_manager); |
| 28 | ~Maxwell3D() = default; | 32 | ~Maxwell3D() = default; |
| 29 | 33 | ||
| 30 | /// Register structure of the Maxwell3D engine. | 34 | /// Register structure of the Maxwell3D engine. |
| @@ -818,6 +822,8 @@ public: | |||
| 818 | Texture::FullTextureInfo GetStageTexture(Regs::ShaderStage stage, size_t offset) const; | 822 | Texture::FullTextureInfo GetStageTexture(Regs::ShaderStage stage, size_t offset) const; |
| 819 | 823 | ||
| 820 | private: | 824 | private: |
| 825 | VideoCore::RasterizerInterface& rasterizer; | ||
| 826 | |||
| 821 | std::unordered_map<u32, std::vector<u32>> uploaded_macros; | 827 | std::unordered_map<u32, std::vector<u32>> uploaded_macros; |
| 822 | 828 | ||
| 823 | /// Macro method that is currently being executed / being fed parameters. | 829 | /// Macro method that is currently being executed / being fed parameters. |
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 60c49d672..b2a83ce0b 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp | |||
| @@ -7,12 +7,13 @@ | |||
| 7 | #include "video_core/engines/maxwell_compute.h" | 7 | #include "video_core/engines/maxwell_compute.h" |
| 8 | #include "video_core/engines/maxwell_dma.h" | 8 | #include "video_core/engines/maxwell_dma.h" |
| 9 | #include "video_core/gpu.h" | 9 | #include "video_core/gpu.h" |
| 10 | #include "video_core/rasterizer_interface.h" | ||
| 10 | 11 | ||
| 11 | namespace Tegra { | 12 | namespace Tegra { |
| 12 | 13 | ||
| 13 | GPU::GPU() { | 14 | GPU::GPU(VideoCore::RasterizerInterface& rasterizer) { |
| 14 | memory_manager = std::make_unique<MemoryManager>(); | 15 | memory_manager = std::make_unique<MemoryManager>(); |
| 15 | maxwell_3d = std::make_unique<Engines::Maxwell3D>(*memory_manager); | 16 | maxwell_3d = std::make_unique<Engines::Maxwell3D>(rasterizer, *memory_manager); |
| 16 | fermi_2d = std::make_unique<Engines::Fermi2D>(*memory_manager); | 17 | fermi_2d = std::make_unique<Engines::Fermi2D>(*memory_manager); |
| 17 | maxwell_compute = std::make_unique<Engines::MaxwellCompute>(); | 18 | maxwell_compute = std::make_unique<Engines::MaxwellCompute>(); |
| 18 | maxwell_dma = std::make_unique<Engines::MaxwellDMA>(*memory_manager); | 19 | maxwell_dma = std::make_unique<Engines::MaxwellDMA>(*memory_manager); |
| @@ -40,6 +41,7 @@ u32 RenderTargetBytesPerPixel(RenderTargetFormat format) { | |||
| 40 | case RenderTargetFormat::RGBA8_UNORM: | 41 | case RenderTargetFormat::RGBA8_UNORM: |
| 41 | case RenderTargetFormat::RGB10_A2_UNORM: | 42 | case RenderTargetFormat::RGB10_A2_UNORM: |
| 42 | case RenderTargetFormat::BGRA8_UNORM: | 43 | case RenderTargetFormat::BGRA8_UNORM: |
| 44 | case RenderTargetFormat::R32_FLOAT: | ||
| 43 | return 4; | 45 | return 4; |
| 44 | default: | 46 | default: |
| 45 | UNIMPLEMENTED_MSG("Unimplemented render target format {}", static_cast<u32>(format)); | 47 | UNIMPLEMENTED_MSG("Unimplemented render target format {}", static_cast<u32>(format)); |
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index c464fc6d1..440505c9d 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h | |||
| @@ -11,6 +11,10 @@ | |||
| 11 | #include "core/hle/service/nvflinger/buffer_queue.h" | 11 | #include "core/hle/service/nvflinger/buffer_queue.h" |
| 12 | #include "video_core/memory_manager.h" | 12 | #include "video_core/memory_manager.h" |
| 13 | 13 | ||
| 14 | namespace VideoCore { | ||
| 15 | class RasterizerInterface; | ||
| 16 | } | ||
| 17 | |||
| 14 | namespace Tegra { | 18 | namespace Tegra { |
| 15 | 19 | ||
| 16 | enum class RenderTargetFormat : u32 { | 20 | enum class RenderTargetFormat : u32 { |
| @@ -29,6 +33,7 @@ enum class RenderTargetFormat : u32 { | |||
| 29 | RG16_UINT = 0xDD, | 33 | RG16_UINT = 0xDD, |
| 30 | RG16_FLOAT = 0xDE, | 34 | RG16_FLOAT = 0xDE, |
| 31 | R11G11B10_FLOAT = 0xE0, | 35 | R11G11B10_FLOAT = 0xE0, |
| 36 | R32_FLOAT = 0xE5, | ||
| 32 | R16_FLOAT = 0xF2, | 37 | R16_FLOAT = 0xF2, |
| 33 | R8_UNORM = 0xF3, | 38 | R8_UNORM = 0xF3, |
| 34 | }; | 39 | }; |
| @@ -97,7 +102,7 @@ enum class EngineID { | |||
| 97 | 102 | ||
| 98 | class GPU final { | 103 | class GPU final { |
| 99 | public: | 104 | public: |
| 100 | GPU(); | 105 | explicit GPU(VideoCore::RasterizerInterface& rasterizer); |
| 101 | ~GPU(); | 106 | ~GPU(); |
| 102 | 107 | ||
| 103 | /// Processes a command list stored at the specified address in GPU memory. | 108 | /// Processes a command list stored at the specified address in GPU memory. |
diff --git a/src/video_core/macro_interpreter.cpp b/src/video_core/macro_interpreter.cpp index 44ece01c1..377bd66ab 100644 --- a/src/video_core/macro_interpreter.cpp +++ b/src/video_core/macro_interpreter.cpp | |||
| @@ -102,11 +102,11 @@ bool MacroInterpreter::Step(const std::vector<u32>& code, bool is_delay_slot) { | |||
| 102 | if (taken) { | 102 | if (taken) { |
| 103 | // Ignore the delay slot if the branch has the annul bit. | 103 | // Ignore the delay slot if the branch has the annul bit. |
| 104 | if (opcode.branch_annul) { | 104 | if (opcode.branch_annul) { |
| 105 | pc = base_address + (opcode.immediate << 2); | 105 | pc = base_address + opcode.GetBranchTarget(); |
| 106 | return true; | 106 | return true; |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | delayed_pc = base_address + (opcode.immediate << 2); | 109 | delayed_pc = base_address + opcode.GetBranchTarget(); |
| 110 | // Execute one more instruction due to the delay slot. | 110 | // Execute one more instruction due to the delay slot. |
| 111 | return Step(code, true); | 111 | return Step(code, true); |
| 112 | } | 112 | } |
diff --git a/src/video_core/macro_interpreter.h b/src/video_core/macro_interpreter.h index a71e359d8..7d836b816 100644 --- a/src/video_core/macro_interpreter.h +++ b/src/video_core/macro_interpreter.h | |||
| @@ -91,6 +91,10 @@ private: | |||
| 91 | u32 GetBitfieldMask() const { | 91 | u32 GetBitfieldMask() const { |
| 92 | return (1 << bf_size) - 1; | 92 | return (1 << bf_size) - 1; |
| 93 | } | 93 | } |
| 94 | |||
| 95 | s32 GetBranchTarget() const { | ||
| 96 | return static_cast<s32>(immediate * sizeof(u32)); | ||
| 97 | } | ||
| 94 | }; | 98 | }; |
| 95 | 99 | ||
| 96 | union MethodAddress { | 100 | union MethodAddress { |
diff --git a/src/video_core/renderer_base.cpp b/src/video_core/renderer_base.cpp index 30075b23c..3ca350243 100644 --- a/src/video_core/renderer_base.cpp +++ b/src/video_core/renderer_base.cpp | |||
| @@ -2,14 +2,26 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <atomic> | ||
| 6 | #include <memory> | 5 | #include <memory> |
| 6 | #include "core/frontend/emu_window.h" | ||
| 7 | #include "video_core/renderer_base.h" | 7 | #include "video_core/renderer_base.h" |
| 8 | #include "video_core/renderer_opengl/gl_rasterizer.h" | 8 | #include "video_core/renderer_opengl/gl_rasterizer.h" |
| 9 | #include "video_core/video_core.h" | 9 | |
| 10 | namespace VideoCore { | ||
| 11 | |||
| 12 | RendererBase::RendererBase(EmuWindow& window) : render_window{window} {} | ||
| 13 | RendererBase::~RendererBase() = default; | ||
| 14 | |||
| 15 | void RendererBase::UpdateCurrentFramebufferLayout() { | ||
| 16 | const Layout::FramebufferLayout& layout = render_window.GetFramebufferLayout(); | ||
| 17 | |||
| 18 | render_window.UpdateCurrentFramebufferLayout(layout.width, layout.height); | ||
| 19 | } | ||
| 10 | 20 | ||
| 11 | void RendererBase::RefreshRasterizerSetting() { | 21 | void RendererBase::RefreshRasterizerSetting() { |
| 12 | if (rasterizer == nullptr) { | 22 | if (rasterizer == nullptr) { |
| 13 | rasterizer = std::make_unique<RasterizerOpenGL>(); | 23 | rasterizer = std::make_unique<RasterizerOpenGL>(render_window); |
| 14 | } | 24 | } |
| 15 | } | 25 | } |
| 26 | |||
| 27 | } // namespace VideoCore | ||
diff --git a/src/video_core/renderer_base.h b/src/video_core/renderer_base.h index 89a960eaf..235de23a1 100644 --- a/src/video_core/renderer_base.h +++ b/src/video_core/renderer_base.h | |||
| @@ -13,28 +13,28 @@ | |||
| 13 | 13 | ||
| 14 | class EmuWindow; | 14 | class EmuWindow; |
| 15 | 15 | ||
| 16 | namespace VideoCore { | ||
| 17 | |||
| 16 | class RendererBase : NonCopyable { | 18 | class RendererBase : NonCopyable { |
| 17 | public: | 19 | public: |
| 18 | /// Used to reference a framebuffer | 20 | /// Used to reference a framebuffer |
| 19 | enum kFramebuffer { kFramebuffer_VirtualXFB = 0, kFramebuffer_EFB, kFramebuffer_Texture }; | 21 | enum kFramebuffer { kFramebuffer_VirtualXFB = 0, kFramebuffer_EFB, kFramebuffer_Texture }; |
| 20 | 22 | ||
| 21 | virtual ~RendererBase() {} | 23 | explicit RendererBase(EmuWindow& window); |
| 24 | virtual ~RendererBase(); | ||
| 22 | 25 | ||
| 23 | /// Swap buffers (render frame) | 26 | /// Swap buffers (render frame) |
| 24 | virtual void SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) = 0; | 27 | virtual void SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) = 0; |
| 25 | 28 | ||
| 26 | /** | ||
| 27 | * Set the emulator window to use for renderer | ||
| 28 | * @param window EmuWindow handle to emulator window to use for rendering | ||
| 29 | */ | ||
| 30 | virtual void SetWindow(EmuWindow* window) = 0; | ||
| 31 | |||
| 32 | /// Initialize the renderer | 29 | /// Initialize the renderer |
| 33 | virtual bool Init() = 0; | 30 | virtual bool Init() = 0; |
| 34 | 31 | ||
| 35 | /// Shutdown the renderer | 32 | /// Shutdown the renderer |
| 36 | virtual void ShutDown() = 0; | 33 | virtual void ShutDown() = 0; |
| 37 | 34 | ||
| 35 | /// Updates the framebuffer layout of the contained render window handle. | ||
| 36 | void UpdateCurrentFramebufferLayout(); | ||
| 37 | |||
| 38 | // Getter/setter functions: | 38 | // Getter/setter functions: |
| 39 | // ------------------------ | 39 | // ------------------------ |
| 40 | 40 | ||
| @@ -46,16 +46,21 @@ public: | |||
| 46 | return m_current_frame; | 46 | return m_current_frame; |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | VideoCore::RasterizerInterface* Rasterizer() const { | 49 | RasterizerInterface& Rasterizer() { |
| 50 | return rasterizer.get(); | 50 | return *rasterizer; |
| 51 | } | ||
| 52 | |||
| 53 | const RasterizerInterface& Rasterizer() const { | ||
| 54 | return *rasterizer; | ||
| 51 | } | 55 | } |
| 52 | 56 | ||
| 53 | void RefreshRasterizerSetting(); | 57 | void RefreshRasterizerSetting(); |
| 54 | 58 | ||
| 55 | protected: | 59 | protected: |
| 56 | std::unique_ptr<VideoCore::RasterizerInterface> rasterizer; | 60 | EmuWindow& render_window; ///< Reference to the render window handle. |
| 61 | std::unique_ptr<RasterizerInterface> rasterizer; | ||
| 57 | f32 m_current_fps = 0.0f; ///< Current framerate, should be set by the renderer | 62 | f32 m_current_fps = 0.0f; ///< Current framerate, should be set by the renderer |
| 58 | int m_current_frame = 0; ///< Current frame, should be set by the renderer | 63 | int m_current_frame = 0; ///< Current frame, should be set by the renderer |
| 59 | |||
| 60 | private: | ||
| 61 | }; | 64 | }; |
| 65 | |||
| 66 | } // namespace VideoCore | ||
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index a1c47bae9..c2a931469 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -14,7 +14,6 @@ | |||
| 14 | #include "common/logging/log.h" | 14 | #include "common/logging/log.h" |
| 15 | #include "common/math_util.h" | 15 | #include "common/math_util.h" |
| 16 | #include "common/microprofile.h" | 16 | #include "common/microprofile.h" |
| 17 | #include "common/scope_exit.h" | ||
| 18 | #include "core/core.h" | 17 | #include "core/core.h" |
| 19 | #include "core/frontend/emu_window.h" | 18 | #include "core/frontend/emu_window.h" |
| 20 | #include "core/hle/kernel/process.h" | 19 | #include "core/hle/kernel/process.h" |
| @@ -37,7 +36,7 @@ MICROPROFILE_DEFINE(OpenGL_Drawing, "OpenGL", "Drawing", MP_RGB(128, 128, 192)); | |||
| 37 | MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(100, 100, 255)); | 36 | MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(100, 100, 255)); |
| 38 | MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100)); | 37 | MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100)); |
| 39 | 38 | ||
| 40 | RasterizerOpenGL::RasterizerOpenGL() { | 39 | RasterizerOpenGL::RasterizerOpenGL(EmuWindow& window) : emu_window{window} { |
| 41 | // Create sampler objects | 40 | // Create sampler objects |
| 42 | for (size_t i = 0; i < texture_samplers.size(); ++i) { | 41 | for (size_t i = 0; i < texture_samplers.size(); ++i) { |
| 43 | texture_samplers[i].Create(); | 42 | texture_samplers[i].Create(); |
| @@ -170,8 +169,14 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr, | |||
| 170 | ASSERT(buffer.IsEnabled()); | 169 | ASSERT(buffer.IsEnabled()); |
| 171 | 170 | ||
| 172 | glEnableVertexAttribArray(index); | 171 | glEnableVertexAttribArray(index); |
| 173 | glVertexAttribFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), | 172 | if (attrib.type == Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::SignedInt || |
| 174 | attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset); | 173 | attrib.type == Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::UnsignedInt) { |
| 174 | glVertexAttribIFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), | ||
| 175 | attrib.offset); | ||
| 176 | } else { | ||
| 177 | glVertexAttribFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), | ||
| 178 | attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset); | ||
| 179 | } | ||
| 175 | glVertexAttribBinding(index, attrib.buffer); | 180 | glVertexAttribBinding(index, attrib.buffer); |
| 176 | } | 181 | } |
| 177 | 182 | ||
| @@ -395,7 +400,7 @@ void RasterizerOpenGL::Clear() { | |||
| 395 | if (clear_mask == 0) | 400 | if (clear_mask == 0) |
| 396 | return; | 401 | return; |
| 397 | 402 | ||
| 398 | ScopeAcquireGLContext acquire_context; | 403 | ScopeAcquireGLContext acquire_context{emu_window}; |
| 399 | 404 | ||
| 400 | auto [dirty_color_surface, dirty_depth_surface] = | 405 | auto [dirty_color_surface, dirty_depth_surface] = |
| 401 | ConfigureFramebuffers(use_color_fb, use_depth_fb); | 406 | ConfigureFramebuffers(use_color_fb, use_depth_fb); |
| @@ -425,7 +430,7 @@ void RasterizerOpenGL::DrawArrays() { | |||
| 425 | MICROPROFILE_SCOPE(OpenGL_Drawing); | 430 | MICROPROFILE_SCOPE(OpenGL_Drawing); |
| 426 | const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; | 431 | const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; |
| 427 | 432 | ||
| 428 | ScopeAcquireGLContext acquire_context; | 433 | ScopeAcquireGLContext acquire_context{emu_window}; |
| 429 | 434 | ||
| 430 | auto [dirty_color_surface, dirty_depth_surface] = | 435 | auto [dirty_color_surface, dirty_depth_surface] = |
| 431 | ConfigureFramebuffers(true, regs.zeta.Address() != 0 && regs.zeta_enable != 0); | 436 | ConfigureFramebuffers(true, regs.zeta.Address() != 0 && regs.zeta_enable != 0); |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index e150be58f..6d6d85cc1 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -21,11 +21,12 @@ | |||
| 21 | #include "video_core/renderer_opengl/gl_state.h" | 21 | #include "video_core/renderer_opengl/gl_state.h" |
| 22 | #include "video_core/renderer_opengl/gl_stream_buffer.h" | 22 | #include "video_core/renderer_opengl/gl_stream_buffer.h" |
| 23 | 23 | ||
| 24 | class EmuWindow; | ||
| 24 | struct ScreenInfo; | 25 | struct ScreenInfo; |
| 25 | 26 | ||
| 26 | class RasterizerOpenGL : public VideoCore::RasterizerInterface { | 27 | class RasterizerOpenGL : public VideoCore::RasterizerInterface { |
| 27 | public: | 28 | public: |
| 28 | RasterizerOpenGL(); | 29 | explicit RasterizerOpenGL(EmuWindow& renderer); |
| 29 | ~RasterizerOpenGL() override; | 30 | ~RasterizerOpenGL() override; |
| 30 | 31 | ||
| 31 | void DrawArrays() override; | 32 | void DrawArrays() override; |
| @@ -144,6 +145,8 @@ private: | |||
| 144 | 145 | ||
| 145 | RasterizerCacheOpenGL res_cache; | 146 | RasterizerCacheOpenGL res_cache; |
| 146 | 147 | ||
| 148 | EmuWindow& emu_window; | ||
| 149 | |||
| 147 | std::unique_ptr<GLShader::ProgramManager> shader_program_manager; | 150 | std::unique_ptr<GLShader::ProgramManager> shader_program_manager; |
| 148 | OGLVertexArray sw_vao; | 151 | OGLVertexArray sw_vao; |
| 149 | OGLVertexArray hw_vao; | 152 | OGLVertexArray hw_vao; |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index a4d9707cb..257aa9571 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | |||
| @@ -46,6 +46,8 @@ struct FormatTuple { | |||
| 46 | params.height = Common::AlignUp(config.tic.Height(), GetCompressionFactor(params.pixel_format)); | 46 | params.height = Common::AlignUp(config.tic.Height(), GetCompressionFactor(params.pixel_format)); |
| 47 | params.unaligned_height = config.tic.Height(); | 47 | params.unaligned_height = config.tic.Height(); |
| 48 | params.size_in_bytes = params.SizeInBytes(); | 48 | params.size_in_bytes = params.SizeInBytes(); |
| 49 | params.cache_width = Common::AlignUp(params.width, 16); | ||
| 50 | params.cache_height = Common::AlignUp(params.height, 16); | ||
| 49 | return params; | 51 | return params; |
| 50 | } | 52 | } |
| 51 | 53 | ||
| @@ -63,6 +65,8 @@ struct FormatTuple { | |||
| 63 | params.height = config.height; | 65 | params.height = config.height; |
| 64 | params.unaligned_height = config.height; | 66 | params.unaligned_height = config.height; |
| 65 | params.size_in_bytes = params.SizeInBytes(); | 67 | params.size_in_bytes = params.SizeInBytes(); |
| 68 | params.cache_width = Common::AlignUp(params.width, 16); | ||
| 69 | params.cache_height = Common::AlignUp(params.height, 16); | ||
| 66 | return params; | 70 | return params; |
| 67 | } | 71 | } |
| 68 | 72 | ||
| @@ -82,6 +86,8 @@ struct FormatTuple { | |||
| 82 | params.height = zeta_height; | 86 | params.height = zeta_height; |
| 83 | params.unaligned_height = zeta_height; | 87 | params.unaligned_height = zeta_height; |
| 84 | params.size_in_bytes = params.SizeInBytes(); | 88 | params.size_in_bytes = params.SizeInBytes(); |
| 89 | params.cache_width = Common::AlignUp(params.width, 16); | ||
| 90 | params.cache_height = Common::AlignUp(params.height, 16); | ||
| 85 | return params; | 91 | return params; |
| 86 | } | 92 | } |
| 87 | 93 | ||
| @@ -118,6 +124,7 @@ static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_form | |||
| 118 | {GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT, ComponentType::UInt, false}, // RG16UI | 124 | {GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT, ComponentType::UInt, false}, // RG16UI |
| 119 | {GL_RG16I, GL_RG_INTEGER, GL_SHORT, ComponentType::SInt, false}, // RG16I | 125 | {GL_RG16I, GL_RG_INTEGER, GL_SHORT, ComponentType::SInt, false}, // RG16I |
| 120 | {GL_RG16_SNORM, GL_RG, GL_SHORT, ComponentType::SNorm, false}, // RG16S | 126 | {GL_RG16_SNORM, GL_RG, GL_SHORT, ComponentType::SNorm, false}, // RG16S |
| 127 | {GL_RGB32F, GL_RGB, GL_FLOAT, ComponentType::Float, false}, // RGB32F | ||
| 121 | {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // SRGBA8 | 128 | {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // SRGBA8 |
| 122 | 129 | ||
| 123 | // DepthStencil formats | 130 | // DepthStencil formats |
| @@ -218,9 +225,10 @@ static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr), | |||
| 218 | MortonCopy<true, PixelFormat::R16UNORM>, MortonCopy<true, PixelFormat::RG16>, | 225 | MortonCopy<true, PixelFormat::R16UNORM>, MortonCopy<true, PixelFormat::RG16>, |
| 219 | MortonCopy<true, PixelFormat::RG16F>, MortonCopy<true, PixelFormat::RG16UI>, | 226 | MortonCopy<true, PixelFormat::RG16F>, MortonCopy<true, PixelFormat::RG16UI>, |
| 220 | MortonCopy<true, PixelFormat::RG16I>, MortonCopy<true, PixelFormat::RG16S>, | 227 | MortonCopy<true, PixelFormat::RG16I>, MortonCopy<true, PixelFormat::RG16S>, |
| 221 | MortonCopy<true, PixelFormat::SRGBA8>, MortonCopy<true, PixelFormat::Z24S8>, | 228 | MortonCopy<true, PixelFormat::RGB32F>, MortonCopy<true, PixelFormat::SRGBA8>, |
| 222 | MortonCopy<true, PixelFormat::S8Z24>, MortonCopy<true, PixelFormat::Z32F>, | 229 | MortonCopy<true, PixelFormat::Z24S8>, MortonCopy<true, PixelFormat::S8Z24>, |
| 223 | MortonCopy<true, PixelFormat::Z16>, MortonCopy<true, PixelFormat::Z32FS8>, | 230 | MortonCopy<true, PixelFormat::Z32F>, MortonCopy<true, PixelFormat::Z16>, |
| 231 | MortonCopy<true, PixelFormat::Z32FS8>, | ||
| 224 | }; | 232 | }; |
| 225 | 233 | ||
| 226 | static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr), | 234 | static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr), |
| @@ -253,6 +261,7 @@ static constexpr std::array<void (*)(u32, u32, u32, u8*, Tegra::GPUVAddr), | |||
| 253 | MortonCopy<false, PixelFormat::RG16UI>, | 261 | MortonCopy<false, PixelFormat::RG16UI>, |
| 254 | MortonCopy<false, PixelFormat::RG16I>, | 262 | MortonCopy<false, PixelFormat::RG16I>, |
| 255 | MortonCopy<false, PixelFormat::RG16S>, | 263 | MortonCopy<false, PixelFormat::RG16S>, |
| 264 | MortonCopy<false, PixelFormat::RGB32F>, | ||
| 256 | MortonCopy<false, PixelFormat::SRGBA8>, | 265 | MortonCopy<false, PixelFormat::SRGBA8>, |
| 257 | MortonCopy<false, PixelFormat::Z24S8>, | 266 | MortonCopy<false, PixelFormat::Z24S8>, |
| 258 | MortonCopy<false, PixelFormat::S8Z24>, | 267 | MortonCopy<false, PixelFormat::S8Z24>, |
| @@ -677,12 +686,12 @@ Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params) { | |||
| 677 | // If use_accurate_framebuffers is enabled, always load from memory | 686 | // If use_accurate_framebuffers is enabled, always load from memory |
| 678 | FlushSurface(surface); | 687 | FlushSurface(surface); |
| 679 | UnregisterSurface(surface); | 688 | UnregisterSurface(surface); |
| 680 | } else if (surface->GetSurfaceParams() != params) { | 689 | } else if (surface->GetSurfaceParams().IsCompatibleSurface(params)) { |
| 681 | // If surface parameters changed, recreate the surface from the old one | ||
| 682 | return RecreateSurface(surface, params); | ||
| 683 | } else { | ||
| 684 | // Use the cached surface as-is | 690 | // Use the cached surface as-is |
| 685 | return surface; | 691 | return surface; |
| 692 | } else { | ||
| 693 | // If surface parameters changed, recreate the surface from the old one | ||
| 694 | return RecreateSurface(surface, params); | ||
| 686 | } | 695 | } |
| 687 | } | 696 | } |
| 688 | 697 | ||
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index bf0458b94..0c6652c7a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include <memory> | 9 | #include <memory> |
| 10 | #include <vector> | 10 | #include <vector> |
| 11 | #include <boost/icl/interval_map.hpp> | 11 | #include <boost/icl/interval_map.hpp> |
| 12 | |||
| 12 | #include "common/common_types.h" | 13 | #include "common/common_types.h" |
| 13 | #include "common/math_util.h" | 14 | #include "common/math_util.h" |
| 14 | #include "video_core/engines/maxwell_3d.h" | 15 | #include "video_core/engines/maxwell_3d.h" |
| @@ -48,16 +49,17 @@ struct SurfaceParams { | |||
| 48 | RG16UI = 23, | 49 | RG16UI = 23, |
| 49 | RG16I = 24, | 50 | RG16I = 24, |
| 50 | RG16S = 25, | 51 | RG16S = 25, |
| 51 | SRGBA8 = 26, | 52 | RGB32F = 26, |
| 53 | SRGBA8 = 27, | ||
| 52 | 54 | ||
| 53 | MaxColorFormat, | 55 | MaxColorFormat, |
| 54 | 56 | ||
| 55 | // DepthStencil formats | 57 | // DepthStencil formats |
| 56 | Z24S8 = 27, | 58 | Z24S8 = 28, |
| 57 | S8Z24 = 28, | 59 | S8Z24 = 29, |
| 58 | Z32F = 29, | 60 | Z32F = 30, |
| 59 | Z16 = 30, | 61 | Z16 = 31, |
| 60 | Z32FS8 = 31, | 62 | Z32FS8 = 32, |
| 61 | 63 | ||
| 62 | MaxDepthStencilFormat, | 64 | MaxDepthStencilFormat, |
| 63 | 65 | ||
| @@ -121,6 +123,7 @@ struct SurfaceParams { | |||
| 121 | 1, // RG16UI | 123 | 1, // RG16UI |
| 122 | 1, // RG16I | 124 | 1, // RG16I |
| 123 | 1, // RG16S | 125 | 1, // RG16S |
| 126 | 1, // RGB32F | ||
| 124 | 1, // SRGBA8 | 127 | 1, // SRGBA8 |
| 125 | 1, // Z24S8 | 128 | 1, // Z24S8 |
| 126 | 1, // S8Z24 | 129 | 1, // S8Z24 |
| @@ -164,6 +167,7 @@ struct SurfaceParams { | |||
| 164 | 32, // RG16UI | 167 | 32, // RG16UI |
| 165 | 32, // RG16I | 168 | 32, // RG16I |
| 166 | 32, // RG16S | 169 | 32, // RG16S |
| 170 | 96, // RGB32F | ||
| 167 | 32, // SRGBA8 | 171 | 32, // SRGBA8 |
| 168 | 32, // Z24S8 | 172 | 32, // Z24S8 |
| 169 | 32, // S8Z24 | 173 | 32, // S8Z24 |
| @@ -200,8 +204,9 @@ struct SurfaceParams { | |||
| 200 | 204 | ||
| 201 | static PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) { | 205 | static PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) { |
| 202 | switch (format) { | 206 | switch (format) { |
| 207 | // TODO (Hexagon12): Converting SRGBA to RGBA is a hack and doesn't completely correct the | ||
| 208 | // gamma. | ||
| 203 | case Tegra::RenderTargetFormat::RGBA8_SRGB: | 209 | case Tegra::RenderTargetFormat::RGBA8_SRGB: |
| 204 | return PixelFormat::SRGBA8; | ||
| 205 | case Tegra::RenderTargetFormat::RGBA8_UNORM: | 210 | case Tegra::RenderTargetFormat::RGBA8_UNORM: |
| 206 | return PixelFormat::ABGR8; | 211 | return PixelFormat::ABGR8; |
| 207 | case Tegra::RenderTargetFormat::BGRA8_UNORM: | 212 | case Tegra::RenderTargetFormat::BGRA8_UNORM: |
| @@ -232,6 +237,8 @@ struct SurfaceParams { | |||
| 232 | return PixelFormat::RG16S; | 237 | return PixelFormat::RG16S; |
| 233 | case Tegra::RenderTargetFormat::R16_FLOAT: | 238 | case Tegra::RenderTargetFormat::R16_FLOAT: |
| 234 | return PixelFormat::R16F; | 239 | return PixelFormat::R16F; |
| 240 | case Tegra::RenderTargetFormat::R32_FLOAT: | ||
| 241 | return PixelFormat::R32F; | ||
| 235 | default: | 242 | default: |
| 236 | LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); | 243 | LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); |
| 237 | UNREACHABLE(); | 244 | UNREACHABLE(); |
| @@ -270,6 +277,8 @@ struct SurfaceParams { | |||
| 270 | UNREACHABLE(); | 277 | UNREACHABLE(); |
| 271 | case Tegra::Texture::TextureFormat::R32_G32: | 278 | case Tegra::Texture::TextureFormat::R32_G32: |
| 272 | return PixelFormat::RG32F; | 279 | return PixelFormat::RG32F; |
| 280 | case Tegra::Texture::TextureFormat::R32_G32_B32: | ||
| 281 | return PixelFormat::RGB32F; | ||
| 273 | case Tegra::Texture::TextureFormat::R16: | 282 | case Tegra::Texture::TextureFormat::R16: |
| 274 | switch (component_type) { | 283 | switch (component_type) { |
| 275 | case Tegra::Texture::ComponentType::FLOAT: | 284 | case Tegra::Texture::ComponentType::FLOAT: |
| @@ -361,6 +370,8 @@ struct SurfaceParams { | |||
| 361 | return Tegra::Texture::TextureFormat::A8R8G8B8; | 370 | return Tegra::Texture::TextureFormat::A8R8G8B8; |
| 362 | case PixelFormat::RGBA32F: | 371 | case PixelFormat::RGBA32F: |
| 363 | return Tegra::Texture::TextureFormat::R32_G32_B32_A32; | 372 | return Tegra::Texture::TextureFormat::R32_G32_B32_A32; |
| 373 | case PixelFormat::RGB32F: | ||
| 374 | return Tegra::Texture::TextureFormat::R32_G32_B32; | ||
| 364 | case PixelFormat::RG32F: | 375 | case PixelFormat::RG32F: |
| 365 | return Tegra::Texture::TextureFormat::R32_G32; | 376 | return Tegra::Texture::TextureFormat::R32_G32; |
| 366 | case PixelFormat::R32F: | 377 | case PixelFormat::R32F: |
| @@ -439,6 +450,7 @@ struct SurfaceParams { | |||
| 439 | case Tegra::RenderTargetFormat::RG32_FLOAT: | 450 | case Tegra::RenderTargetFormat::RG32_FLOAT: |
| 440 | case Tegra::RenderTargetFormat::RG16_FLOAT: | 451 | case Tegra::RenderTargetFormat::RG16_FLOAT: |
| 441 | case Tegra::RenderTargetFormat::R16_FLOAT: | 452 | case Tegra::RenderTargetFormat::R16_FLOAT: |
| 453 | case Tegra::RenderTargetFormat::R32_FLOAT: | ||
| 442 | return ComponentType::Float; | 454 | return ComponentType::Float; |
| 443 | case Tegra::RenderTargetFormat::RGBA32_UINT: | 455 | case Tegra::RenderTargetFormat::RGBA32_UINT: |
| 444 | case Tegra::RenderTargetFormat::RG16_UINT: | 456 | case Tegra::RenderTargetFormat::RG16_UINT: |
| @@ -536,6 +548,12 @@ struct SurfaceParams { | |||
| 536 | return !operator==(other); | 548 | return !operator==(other); |
| 537 | } | 549 | } |
| 538 | 550 | ||
| 551 | /// Checks if surfaces are compatible for caching | ||
| 552 | bool IsCompatibleSurface(const SurfaceParams& other) const { | ||
| 553 | return std::tie(pixel_format, type, cache_width, cache_height) == | ||
| 554 | std::tie(other.pixel_format, other.type, other.cache_width, other.cache_height); | ||
| 555 | } | ||
| 556 | |||
| 539 | Tegra::GPUVAddr addr; | 557 | Tegra::GPUVAddr addr; |
| 540 | bool is_tiled; | 558 | bool is_tiled; |
| 541 | u32 block_height; | 559 | u32 block_height; |
| @@ -546,6 +564,10 @@ struct SurfaceParams { | |||
| 546 | u32 height; | 564 | u32 height; |
| 547 | u32 unaligned_height; | 565 | u32 unaligned_height; |
| 548 | size_t size_in_bytes; | 566 | size_t size_in_bytes; |
| 567 | |||
| 568 | // Parameters used for caching only | ||
| 569 | u32 cache_width; | ||
| 570 | u32 cache_height; | ||
| 549 | }; | 571 | }; |
| 550 | 572 | ||
| 551 | class CachedSurface final { | 573 | class CachedSurface final { |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index acf067050..e3217db81 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -412,7 +412,6 @@ public: | |||
| 412 | } | 412 | } |
| 413 | declarations.AddNewLine(); | 413 | declarations.AddNewLine(); |
| 414 | 414 | ||
| 415 | unsigned const_buffer_layout = 0; | ||
| 416 | for (const auto& entry : GetConstBuffersDeclarations()) { | 415 | for (const auto& entry : GetConstBuffersDeclarations()) { |
| 417 | declarations.AddLine("layout(std140) uniform " + entry.GetName()); | 416 | declarations.AddLine("layout(std140) uniform " + entry.GetName()); |
| 418 | declarations.AddLine('{'); | 417 | declarations.AddLine('{'); |
| @@ -420,7 +419,6 @@ public: | |||
| 420 | "[MAX_CONSTBUFFER_ELEMENTS];"); | 419 | "[MAX_CONSTBUFFER_ELEMENTS];"); |
| 421 | declarations.AddLine("};"); | 420 | declarations.AddLine("};"); |
| 422 | declarations.AddNewLine(); | 421 | declarations.AddNewLine(); |
| 423 | ++const_buffer_layout; | ||
| 424 | } | 422 | } |
| 425 | declarations.AddNewLine(); | 423 | declarations.AddNewLine(); |
| 426 | 424 | ||
| @@ -768,13 +766,16 @@ private: | |||
| 768 | // goes into gpr28+0 and gpr28+1 | 766 | // goes into gpr28+0 and gpr28+1 |
| 769 | size_t texs_offset{}; | 767 | size_t texs_offset{}; |
| 770 | 768 | ||
| 769 | size_t src_elem{}; | ||
| 771 | for (const auto& dest : {instr.gpr0.Value(), instr.gpr28.Value()}) { | 770 | for (const auto& dest : {instr.gpr0.Value(), instr.gpr28.Value()}) { |
| 771 | size_t dest_elem{}; | ||
| 772 | for (unsigned elem = 0; elem < 2; ++elem) { | 772 | for (unsigned elem = 0; elem < 2; ++elem) { |
| 773 | if (!instr.texs.IsComponentEnabled(elem)) { | 773 | if (!instr.texs.IsComponentEnabled(src_elem++)) { |
| 774 | // Skip disabled components | 774 | // Skip disabled components |
| 775 | continue; | 775 | continue; |
| 776 | } | 776 | } |
| 777 | regs.SetRegisterToFloat(dest, elem + texs_offset, texture, 1, 4, false, elem); | 777 | regs.SetRegisterToFloat(dest, elem + texs_offset, texture, 1, 4, false, |
| 778 | dest_elem++); | ||
| 778 | } | 779 | } |
| 779 | 780 | ||
| 780 | if (!instr.texs.HasTwoDestinations()) { | 781 | if (!instr.texs.HasTwoDestinations()) { |
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp index e81fcbbc4..415d42fda 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.cpp +++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp | |||
| @@ -13,15 +13,16 @@ namespace Impl { | |||
| 13 | static void SetShaderUniformBlockBinding(GLuint shader, const char* name, | 13 | static void SetShaderUniformBlockBinding(GLuint shader, const char* name, |
| 14 | Maxwell3D::Regs::ShaderStage binding, | 14 | Maxwell3D::Regs::ShaderStage binding, |
| 15 | size_t expected_size) { | 15 | size_t expected_size) { |
| 16 | GLuint ub_index = glGetUniformBlockIndex(shader, name); | 16 | const GLuint ub_index = glGetUniformBlockIndex(shader, name); |
| 17 | if (ub_index != GL_INVALID_INDEX) { | 17 | if (ub_index == GL_INVALID_INDEX) { |
| 18 | GLint ub_size = 0; | 18 | return; |
| 19 | glGetActiveUniformBlockiv(shader, ub_index, GL_UNIFORM_BLOCK_DATA_SIZE, &ub_size); | ||
| 20 | ASSERT_MSG(ub_size == expected_size, | ||
| 21 | "Uniform block size did not match! Got {}, expected {}", | ||
| 22 | static_cast<int>(ub_size), expected_size); | ||
| 23 | glUniformBlockBinding(shader, ub_index, static_cast<GLuint>(binding)); | ||
| 24 | } | 19 | } |
| 20 | |||
| 21 | GLint ub_size = 0; | ||
| 22 | glGetActiveUniformBlockiv(shader, ub_index, GL_UNIFORM_BLOCK_DATA_SIZE, &ub_size); | ||
| 23 | ASSERT_MSG(static_cast<size_t>(ub_size) == expected_size, | ||
| 24 | "Uniform block size did not match! Got {}, expected {}", ub_size, expected_size); | ||
| 25 | glUniformBlockBinding(shader, ub_index, static_cast<GLuint>(binding)); | ||
| 25 | } | 26 | } |
| 26 | 27 | ||
| 27 | void SetShaderUniformBlockBindings(GLuint shader) { | 28 | void SetShaderUniformBlockBindings(GLuint shader) { |
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h index e29d551e1..716933a0b 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.h +++ b/src/video_core/renderer_opengl/gl_shader_manager.h | |||
| @@ -105,20 +105,20 @@ public: | |||
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | ShaderEntries UseProgrammableVertexShader(const MaxwellVSConfig& config, | 107 | ShaderEntries UseProgrammableVertexShader(const MaxwellVSConfig& config, |
| 108 | const ShaderSetup setup) { | 108 | const ShaderSetup& setup) { |
| 109 | ShaderEntries result; | 109 | ShaderEntries result; |
| 110 | std::tie(current.vs, result) = vertex_shaders.Get(config, setup); | 110 | std::tie(current.vs, result) = vertex_shaders.Get(config, setup); |
| 111 | return result; | 111 | return result; |
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | ShaderEntries UseProgrammableFragmentShader(const MaxwellFSConfig& config, | 114 | ShaderEntries UseProgrammableFragmentShader(const MaxwellFSConfig& config, |
| 115 | const ShaderSetup setup) { | 115 | const ShaderSetup& setup) { |
| 116 | ShaderEntries result; | 116 | ShaderEntries result; |
| 117 | std::tie(current.fs, result) = fragment_shaders.Get(config, setup); | 117 | std::tie(current.fs, result) = fragment_shaders.Get(config, setup); |
| 118 | return result; | 118 | return result; |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | GLuint GetCurrentProgramStage(Maxwell3D::Regs::ShaderStage stage) { | 121 | GLuint GetCurrentProgramStage(Maxwell3D::Regs::ShaderStage stage) const { |
| 122 | switch (stage) { | 122 | switch (stage) { |
| 123 | case Maxwell3D::Regs::ShaderStage::Vertex: | 123 | case Maxwell3D::Regs::ShaderStage::Vertex: |
| 124 | return current.vs; | 124 | return current.vs; |
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index 3398d7c04..24b1d956b 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h | |||
| @@ -82,7 +82,7 @@ public: | |||
| 82 | GLenum logic_op; // GL_LOGIC_OP_MODE | 82 | GLenum logic_op; // GL_LOGIC_OP_MODE |
| 83 | 83 | ||
| 84 | // 3 texture units - one for each that is used in PICA fragment shader emulation | 84 | // 3 texture units - one for each that is used in PICA fragment shader emulation |
| 85 | struct { | 85 | struct TextureUnit { |
| 86 | GLuint texture_2d; // GL_TEXTURE_BINDING_2D | 86 | GLuint texture_2d; // GL_TEXTURE_BINDING_2D |
| 87 | GLuint sampler; // GL_SAMPLER_BINDING | 87 | GLuint sampler; // GL_SAMPLER_BINDING |
| 88 | struct { | 88 | struct { |
| @@ -104,7 +104,8 @@ public: | |||
| 104 | Unbind(); | 104 | Unbind(); |
| 105 | sampler = 0; | 105 | sampler = 0; |
| 106 | } | 106 | } |
| 107 | } texture_units[32]; | 107 | }; |
| 108 | std::array<TextureUnit, 32> texture_units; | ||
| 108 | 109 | ||
| 109 | struct { | 110 | struct { |
| 110 | GLuint read_framebuffer; // GL_READ_FRAMEBUFFER_BINDING | 111 | GLuint read_framebuffer; // GL_READ_FRAMEBUFFER_BINDING |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 7810b9147..bf9131193 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -92,23 +92,23 @@ static std::array<GLfloat, 3 * 2> MakeOrthographicMatrix(const float width, cons | |||
| 92 | return matrix; | 92 | return matrix; |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | ScopeAcquireGLContext::ScopeAcquireGLContext() { | 95 | ScopeAcquireGLContext::ScopeAcquireGLContext(EmuWindow& emu_window_) : emu_window{emu_window_} { |
| 96 | if (Settings::values.use_multi_core) { | 96 | if (Settings::values.use_multi_core) { |
| 97 | VideoCore::g_emu_window->MakeCurrent(); | 97 | emu_window.MakeCurrent(); |
| 98 | } | 98 | } |
| 99 | } | 99 | } |
| 100 | ScopeAcquireGLContext::~ScopeAcquireGLContext() { | 100 | ScopeAcquireGLContext::~ScopeAcquireGLContext() { |
| 101 | if (Settings::values.use_multi_core) { | 101 | if (Settings::values.use_multi_core) { |
| 102 | VideoCore::g_emu_window->DoneCurrent(); | 102 | emu_window.DoneCurrent(); |
| 103 | } | 103 | } |
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | RendererOpenGL::RendererOpenGL() = default; | 106 | RendererOpenGL::RendererOpenGL(EmuWindow& window) : VideoCore::RendererBase{window} {} |
| 107 | RendererOpenGL::~RendererOpenGL() = default; | 107 | RendererOpenGL::~RendererOpenGL() = default; |
| 108 | 108 | ||
| 109 | /// Swap buffers (render frame) | 109 | /// Swap buffers (render frame) |
| 110 | void RendererOpenGL::SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) { | 110 | void RendererOpenGL::SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) { |
| 111 | ScopeAcquireGLContext acquire_context; | 111 | ScopeAcquireGLContext acquire_context{render_window}; |
| 112 | 112 | ||
| 113 | Core::System::GetInstance().perf_stats.EndSystemFrame(); | 113 | Core::System::GetInstance().perf_stats.EndSystemFrame(); |
| 114 | 114 | ||
| @@ -130,10 +130,10 @@ void RendererOpenGL::SwapBuffers(boost::optional<const Tegra::FramebufferConfig& | |||
| 130 | // Load the framebuffer from memory, draw it to the screen, and swap buffers | 130 | // Load the framebuffer from memory, draw it to the screen, and swap buffers |
| 131 | LoadFBToScreenInfo(*framebuffer, screen_info); | 131 | LoadFBToScreenInfo(*framebuffer, screen_info); |
| 132 | DrawScreen(); | 132 | DrawScreen(); |
| 133 | render_window->SwapBuffers(); | 133 | render_window.SwapBuffers(); |
| 134 | } | 134 | } |
| 135 | 135 | ||
| 136 | render_window->PollEvents(); | 136 | render_window.PollEvents(); |
| 137 | 137 | ||
| 138 | Core::System::GetInstance().frame_limiter.DoFrameLimiting(CoreTiming::GetGlobalTimeUs()); | 138 | Core::System::GetInstance().frame_limiter.DoFrameLimiting(CoreTiming::GetGlobalTimeUs()); |
| 139 | Core::System::GetInstance().perf_stats.BeginSystemFrame(); | 139 | Core::System::GetInstance().perf_stats.BeginSystemFrame(); |
| @@ -160,8 +160,8 @@ void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuf | |||
| 160 | // only allows rows to have a memory alignement of 4. | 160 | // only allows rows to have a memory alignement of 4. |
| 161 | ASSERT(framebuffer.stride % 4 == 0); | 161 | ASSERT(framebuffer.stride % 4 == 0); |
| 162 | 162 | ||
| 163 | if (!Rasterizer()->AccelerateDisplay(framebuffer, framebuffer_addr, framebuffer.stride, | 163 | if (!rasterizer->AccelerateDisplay(framebuffer, framebuffer_addr, framebuffer.stride, |
| 164 | screen_info)) { | 164 | screen_info)) { |
| 165 | // Reset the screen info's display texture to its own permanent texture | 165 | // Reset the screen info's display texture to its own permanent texture |
| 166 | screen_info.display_texture = screen_info.texture.resource.handle; | 166 | screen_info.display_texture = screen_info.texture.resource.handle; |
| 167 | 167 | ||
| @@ -356,7 +356,7 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, | |||
| 356 | * Draws the emulated screens to the emulator window. | 356 | * Draws the emulated screens to the emulator window. |
| 357 | */ | 357 | */ |
| 358 | void RendererOpenGL::DrawScreen() { | 358 | void RendererOpenGL::DrawScreen() { |
| 359 | const auto& layout = render_window->GetFramebufferLayout(); | 359 | const auto& layout = render_window.GetFramebufferLayout(); |
| 360 | const auto& screen = layout.screen; | 360 | const auto& screen = layout.screen; |
| 361 | 361 | ||
| 362 | glViewport(0, 0, layout.width, layout.height); | 362 | glViewport(0, 0, layout.width, layout.height); |
| @@ -380,14 +380,6 @@ void RendererOpenGL::DrawScreen() { | |||
| 380 | /// Updates the framerate | 380 | /// Updates the framerate |
| 381 | void RendererOpenGL::UpdateFramerate() {} | 381 | void RendererOpenGL::UpdateFramerate() {} |
| 382 | 382 | ||
| 383 | /** | ||
| 384 | * Set the emulator window to use for renderer | ||
| 385 | * @param window EmuWindow handle to emulator window to use for rendering | ||
| 386 | */ | ||
| 387 | void RendererOpenGL::SetWindow(EmuWindow* window) { | ||
| 388 | render_window = window; | ||
| 389 | } | ||
| 390 | |||
| 391 | static const char* GetSource(GLenum source) { | 383 | static const char* GetSource(GLenum source) { |
| 392 | #define RET(s) \ | 384 | #define RET(s) \ |
| 393 | case GL_DEBUG_SOURCE_##s: \ | 385 | case GL_DEBUG_SOURCE_##s: \ |
| @@ -445,7 +437,7 @@ static void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum | |||
| 445 | 437 | ||
| 446 | /// Initialize the renderer | 438 | /// Initialize the renderer |
| 447 | bool RendererOpenGL::Init() { | 439 | bool RendererOpenGL::Init() { |
| 448 | ScopeAcquireGLContext acquire_context; | 440 | ScopeAcquireGLContext acquire_context{render_window}; |
| 449 | 441 | ||
| 450 | if (GLAD_GL_KHR_debug) { | 442 | if (GLAD_GL_KHR_debug) { |
| 451 | glEnable(GL_DEBUG_OUTPUT); | 443 | glEnable(GL_DEBUG_OUTPUT); |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index 59d92a3dc..428afa3b7 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h | |||
| @@ -34,24 +34,21 @@ struct ScreenInfo { | |||
| 34 | /// Helper class to acquire/release OpenGL context within a given scope | 34 | /// Helper class to acquire/release OpenGL context within a given scope |
| 35 | class ScopeAcquireGLContext : NonCopyable { | 35 | class ScopeAcquireGLContext : NonCopyable { |
| 36 | public: | 36 | public: |
| 37 | ScopeAcquireGLContext(); | 37 | explicit ScopeAcquireGLContext(EmuWindow& window); |
| 38 | ~ScopeAcquireGLContext(); | 38 | ~ScopeAcquireGLContext(); |
| 39 | |||
| 40 | private: | ||
| 41 | EmuWindow& emu_window; | ||
| 39 | }; | 42 | }; |
| 40 | 43 | ||
| 41 | class RendererOpenGL : public RendererBase { | 44 | class RendererOpenGL : public VideoCore::RendererBase { |
| 42 | public: | 45 | public: |
| 43 | RendererOpenGL(); | 46 | explicit RendererOpenGL(EmuWindow& window); |
| 44 | ~RendererOpenGL() override; | 47 | ~RendererOpenGL() override; |
| 45 | 48 | ||
| 46 | /// Swap buffers (render frame) | 49 | /// Swap buffers (render frame) |
| 47 | void SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) override; | 50 | void SwapBuffers(boost::optional<const Tegra::FramebufferConfig&> framebuffer) override; |
| 48 | 51 | ||
| 49 | /** | ||
| 50 | * Set the emulator window to use for renderer | ||
| 51 | * @param window EmuWindow handle to emulator window to use for rendering | ||
| 52 | */ | ||
| 53 | void SetWindow(EmuWindow* window) override; | ||
| 54 | |||
| 55 | /// Initialize the renderer | 52 | /// Initialize the renderer |
| 56 | bool Init() override; | 53 | bool Init() override; |
| 57 | 54 | ||
| @@ -72,8 +69,6 @@ private: | |||
| 72 | void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, u8 color_a, | 69 | void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, u8 color_a, |
| 73 | const TextureInfo& texture); | 70 | const TextureInfo& texture); |
| 74 | 71 | ||
| 75 | EmuWindow* render_window; ///< Handle to render window | ||
| 76 | |||
| 77 | OpenGLState state; | 72 | OpenGLState state; |
| 78 | 73 | ||
| 79 | // OpenGL object IDs | 74 | // OpenGL object IDs |
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index d794f8402..65db84ad3 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp | |||
| @@ -57,6 +57,8 @@ u32 BytesPerPixel(TextureFormat format) { | |||
| 57 | case TextureFormat::BC7U: | 57 | case TextureFormat::BC7U: |
| 58 | // In this case a 'pixel' actually refers to a 4x4 tile. | 58 | // In this case a 'pixel' actually refers to a 4x4 tile. |
| 59 | return 16; | 59 | return 16; |
| 60 | case TextureFormat::R32_G32_B32: | ||
| 61 | return 12; | ||
| 60 | case TextureFormat::ASTC_2D_4X4: | 62 | case TextureFormat::ASTC_2D_4X4: |
| 61 | case TextureFormat::A8R8G8B8: | 63 | case TextureFormat::A8R8G8B8: |
| 62 | case TextureFormat::A2B10G10R10: | 64 | case TextureFormat::A2B10G10R10: |
| @@ -131,6 +133,7 @@ std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, | |||
| 131 | case TextureFormat::R16_G16: | 133 | case TextureFormat::R16_G16: |
| 132 | case TextureFormat::BF10GF11RF11: | 134 | case TextureFormat::BF10GF11RF11: |
| 133 | case TextureFormat::ASTC_2D_4X4: | 135 | case TextureFormat::ASTC_2D_4X4: |
| 136 | case TextureFormat::R32_G32_B32: | ||
| 134 | CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data, | 137 | CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data, |
| 135 | unswizzled_data.data(), true, block_height); | 138 | unswizzled_data.data(), true, block_height); |
| 136 | break; | 139 | break; |
| @@ -190,6 +193,7 @@ std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat | |||
| 190 | case TextureFormat::R32: | 193 | case TextureFormat::R32: |
| 191 | case TextureFormat::R16: | 194 | case TextureFormat::R16: |
| 192 | case TextureFormat::R16_G16: | 195 | case TextureFormat::R16_G16: |
| 196 | case TextureFormat::R32_G32_B32: | ||
| 193 | // TODO(Subv): For the time being just forward the same data without any decoding. | 197 | // TODO(Subv): For the time being just forward the same data without any decoding. |
| 194 | rgba_data = texture_data; | 198 | rgba_data = texture_data; |
| 195 | break; | 199 | break; |
diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp index 289140f31..5085ef96b 100644 --- a/src/video_core/video_core.cpp +++ b/src/video_core/video_core.cpp | |||
| @@ -3,40 +3,16 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <memory> | 5 | #include <memory> |
| 6 | #include "common/logging/log.h" | ||
| 7 | #include "video_core/renderer_base.h" | 6 | #include "video_core/renderer_base.h" |
| 8 | #include "video_core/renderer_opengl/renderer_opengl.h" | 7 | #include "video_core/renderer_opengl/renderer_opengl.h" |
| 9 | #include "video_core/video_core.h" | 8 | #include "video_core/video_core.h" |
| 10 | 9 | ||
| 11 | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 12 | // Video Core namespace | ||
| 13 | |||
| 14 | namespace VideoCore { | 10 | namespace VideoCore { |
| 15 | 11 | ||
| 16 | EmuWindow* g_emu_window = nullptr; ///< Frontend emulator window | ||
| 17 | std::unique_ptr<RendererBase> g_renderer; ///< Renderer plugin | ||
| 18 | |||
| 19 | std::atomic<bool> g_toggle_framelimit_enabled; | 12 | std::atomic<bool> g_toggle_framelimit_enabled; |
| 20 | 13 | ||
| 21 | /// Initialize the video core | 14 | std::unique_ptr<RendererBase> CreateRenderer(EmuWindow& emu_window) { |
| 22 | bool Init(EmuWindow* emu_window) { | 15 | return std::make_unique<RendererOpenGL>(emu_window); |
| 23 | g_emu_window = emu_window; | ||
| 24 | g_renderer = std::make_unique<RendererOpenGL>(); | ||
| 25 | g_renderer->SetWindow(g_emu_window); | ||
| 26 | if (g_renderer->Init()) { | ||
| 27 | LOG_DEBUG(Render, "initialized OK"); | ||
| 28 | } else { | ||
| 29 | LOG_CRITICAL(Render, "initialization failed !"); | ||
| 30 | return false; | ||
| 31 | } | ||
| 32 | return true; | ||
| 33 | } | ||
| 34 | |||
| 35 | /// Shutdown the video core | ||
| 36 | void Shutdown() { | ||
| 37 | g_renderer.reset(); | ||
| 38 | |||
| 39 | LOG_DEBUG(Render, "shutdown OK"); | ||
| 40 | } | 16 | } |
| 41 | 17 | ||
| 42 | } // namespace VideoCore | 18 | } // namespace VideoCore |
diff --git a/src/video_core/video_core.h b/src/video_core/video_core.h index 37da62436..7c01c0b8d 100644 --- a/src/video_core/video_core.h +++ b/src/video_core/video_core.h | |||
| @@ -8,29 +8,23 @@ | |||
| 8 | #include <memory> | 8 | #include <memory> |
| 9 | 9 | ||
| 10 | class EmuWindow; | 10 | class EmuWindow; |
| 11 | class RendererBase; | ||
| 12 | |||
| 13 | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 14 | // Video Core namespace | ||
| 15 | 11 | ||
| 16 | namespace VideoCore { | 12 | namespace VideoCore { |
| 17 | 13 | ||
| 18 | enum class Renderer { Software, OpenGL }; | 14 | class RendererBase; |
| 19 | 15 | ||
| 20 | extern std::unique_ptr<RendererBase> g_renderer; ///< Renderer plugin | 16 | enum class Renderer { Software, OpenGL }; |
| 21 | extern EmuWindow* g_emu_window; ///< Emu window | ||
| 22 | 17 | ||
| 23 | // TODO: Wrap these in a user settings struct along with any other graphics settings (often set from | 18 | // TODO: Wrap these in a user settings struct along with any other graphics settings (often set from |
| 24 | // qt ui) | 19 | // qt ui) |
| 25 | extern std::atomic<bool> g_toggle_framelimit_enabled; | 20 | extern std::atomic<bool> g_toggle_framelimit_enabled; |
| 26 | 21 | ||
| 27 | /// Start the video core | 22 | /** |
| 28 | void Start(); | 23 | * Creates a renderer instance. |
| 29 | 24 | * | |
| 30 | /// Initialize the video core | 25 | * @note The returned renderer instance is simply allocated. Its Init() |
| 31 | bool Init(EmuWindow* emu_window); | 26 | * function still needs to be called to fully complete its setup. |
| 32 | 27 | */ | |
| 33 | /// Shutdown the video core | 28 | std::unique_ptr<RendererBase> CreateRenderer(EmuWindow& emu_window); |
| 34 | void Shutdown(); | ||
| 35 | 29 | ||
| 36 | } // namespace VideoCore | 30 | } // namespace VideoCore |
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 7de919a8e..475556806 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt | |||
| @@ -11,6 +11,8 @@ add_executable(yuzu | |||
| 11 | bootmanager.h | 11 | bootmanager.h |
| 12 | configuration/config.cpp | 12 | configuration/config.cpp |
| 13 | configuration/config.h | 13 | configuration/config.h |
| 14 | configuration/configure_audio.cpp | ||
| 15 | configuration/configure_audio.h | ||
| 14 | configuration/configure_debug.cpp | 16 | configuration/configure_debug.cpp |
| 15 | configuration/configure_debug.h | 17 | configuration/configure_debug.h |
| 16 | configuration/configure_dialog.cpp | 18 | configuration/configure_dialog.cpp |
| @@ -55,6 +57,7 @@ add_executable(yuzu | |||
| 55 | set(UIS | 57 | set(UIS |
| 56 | aboutdialog.ui | 58 | aboutdialog.ui |
| 57 | configuration/configure.ui | 59 | configuration/configure.ui |
| 60 | configuration/configure_audio.ui | ||
| 58 | configuration/configure_debug.ui | 61 | configuration/configure_debug.ui |
| 59 | configuration/configure_general.ui | 62 | configuration/configure_general.ui |
| 60 | configuration/configure_graphics.ui | 63 | configuration/configure_graphics.ui |
diff --git a/src/yuzu/about_dialog.cpp b/src/yuzu/about_dialog.cpp index d6647eeea..a81ad2888 100644 --- a/src/yuzu/about_dialog.cpp +++ b/src/yuzu/about_dialog.cpp | |||
| @@ -10,8 +10,9 @@ | |||
| 10 | AboutDialog::AboutDialog(QWidget* parent) : QDialog(parent), ui(new Ui::AboutDialog) { | 10 | AboutDialog::AboutDialog(QWidget* parent) : QDialog(parent), ui(new Ui::AboutDialog) { |
| 11 | ui->setupUi(this); | 11 | ui->setupUi(this); |
| 12 | ui->labelLogo->setPixmap(QIcon::fromTheme("yuzu").pixmap(200)); | 12 | ui->labelLogo->setPixmap(QIcon::fromTheme("yuzu").pixmap(200)); |
| 13 | ui->labelBuildInfo->setText(ui->labelBuildInfo->text().arg( | 13 | ui->labelBuildInfo->setText( |
| 14 | Common::g_build_name, Common::g_scm_branch, Common::g_scm_desc)); | 14 | ui->labelBuildInfo->text().arg(Common::g_build_name, Common::g_scm_branch, |
| 15 | Common::g_scm_desc, QString(Common::g_build_date).left(10))); | ||
| 15 | } | 16 | } |
| 16 | 17 | ||
| 17 | AboutDialog::~AboutDialog() {} | 18 | AboutDialog::~AboutDialog() = default; |
diff --git a/src/yuzu/about_dialog.h b/src/yuzu/about_dialog.h index 2eb6e28f5..18e8c11a7 100644 --- a/src/yuzu/about_dialog.h +++ b/src/yuzu/about_dialog.h | |||
| @@ -16,7 +16,7 @@ class AboutDialog : public QDialog { | |||
| 16 | 16 | ||
| 17 | public: | 17 | public: |
| 18 | explicit AboutDialog(QWidget* parent); | 18 | explicit AboutDialog(QWidget* parent); |
| 19 | ~AboutDialog(); | 19 | ~AboutDialog() override; |
| 20 | 20 | ||
| 21 | private: | 21 | private: |
| 22 | std::unique_ptr<Ui::AboutDialog> ui; | 22 | std::unique_ptr<Ui::AboutDialog> ui; |
diff --git a/src/yuzu/aboutdialog.ui b/src/yuzu/aboutdialog.ui index 2680480cc..f122ba39d 100644 --- a/src/yuzu/aboutdialog.ui +++ b/src/yuzu/aboutdialog.ui | |||
| @@ -70,7 +70,7 @@ | |||
| 70 | </sizepolicy> | 70 | </sizepolicy> |
| 71 | </property> | 71 | </property> |
| 72 | <property name="text"> | 72 | <property name="text"> |
| 73 | <string><html><head/><body><p>%1 | %2-%3</p></body></html></string> | 73 | <string><html><head/><body><p>%1 | %2-%3 (%4)</p></body></html></string> |
| 74 | </property> | 74 | </property> |
| 75 | </widget> | 75 | </widget> |
| 76 | </item> | 76 | </item> |
| @@ -115,7 +115,7 @@ p, li { white-space: pre-wrap; } | |||
| 115 | <item> | 115 | <item> |
| 116 | <widget class="QLabel" name="labelLinks"> | 116 | <widget class="QLabel" name="labelLinks"> |
| 117 | <property name="text"> | 117 | <property name="text"> |
| 118 | <string><html><head/><body><p><a href="https://yuzu-emu.org/"><span style=" text-decoration: underline; color:#0000ff;">Website</span></a> | <a href="https://github.com/yuzu-emu"><span style=" text-decoration: underline; color:#0000ff;">Source Code</span></a> | <a href="https://github.com/yuzu-emu/yuzu/graphs/contributors"><span style=" text-decoration: underline; color:#0000ff;">Contributors</span></a> | <a href="https://github.com/yuzu-emu/yuzu/blob/master/license.txt"><span style=" text-decoration: underline; color:#0000ff;">License</span></a></p></body></html></string> | 118 | <string><html><head/><body><p><a href="https://yuzu-emu.org/"><span style=" text-decoration: underline; color:#039be5;">Website</span></a> | <a href="https://github.com/yuzu-emu"><span style=" text-decoration: underline; color:#039be5;">Source Code</span></a> | <a href="https://github.com/yuzu-emu/yuzu/graphs/contributors"><span style=" text-decoration: underline; color:#039be5;">Contributors</span></a> | <a href="https://github.com/yuzu-emu/yuzu/blob/master/license.txt"><span style=" text-decoration: underline; color:#039be5;">License</span></a></p></body></html></string> |
| 119 | </property> | 119 | </property> |
| 120 | <property name="openExternalLinks"> | 120 | <property name="openExternalLinks"> |
| 121 | <bool>true</bool> | 121 | <bool>true</bool> |
diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h index 130bc613b..d0f990c64 100644 --- a/src/yuzu/bootmanager.h +++ b/src/yuzu/bootmanager.h | |||
| @@ -106,7 +106,7 @@ class GRenderWindow : public QWidget, public EmuWindow { | |||
| 106 | 106 | ||
| 107 | public: | 107 | public: |
| 108 | GRenderWindow(QWidget* parent, EmuThread* emu_thread); | 108 | GRenderWindow(QWidget* parent, EmuThread* emu_thread); |
| 109 | ~GRenderWindow(); | 109 | ~GRenderWindow() override; |
| 110 | 110 | ||
| 111 | // EmuWindow implementation | 111 | // EmuWindow implementation |
| 112 | void SwapBuffers() override; | 112 | void SwapBuffers() override; |
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 98969fe10..bf469ee73 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp | |||
| @@ -92,16 +92,26 @@ void Config::ReadValues() { | |||
| 92 | Settings::values.bg_blue = qt_config->value("bg_blue", 0.0).toFloat(); | 92 | Settings::values.bg_blue = qt_config->value("bg_blue", 0.0).toFloat(); |
| 93 | qt_config->endGroup(); | 93 | qt_config->endGroup(); |
| 94 | 94 | ||
| 95 | qt_config->beginGroup("Audio"); | ||
| 96 | Settings::values.sink_id = qt_config->value("output_engine", "auto").toString().toStdString(); | ||
| 97 | Settings::values.audio_device_id = | ||
| 98 | qt_config->value("output_device", "auto").toString().toStdString(); | ||
| 99 | Settings::values.volume = qt_config->value("volume", 1).toFloat(); | ||
| 100 | qt_config->endGroup(); | ||
| 101 | |||
| 95 | qt_config->beginGroup("Data Storage"); | 102 | qt_config->beginGroup("Data Storage"); |
| 96 | Settings::values.use_virtual_sd = qt_config->value("use_virtual_sd", true).toBool(); | 103 | Settings::values.use_virtual_sd = qt_config->value("use_virtual_sd", true).toBool(); |
| 97 | qt_config->endGroup(); | 104 | qt_config->endGroup(); |
| 98 | 105 | ||
| 99 | qt_config->beginGroup("System"); | 106 | qt_config->beginGroup("System"); |
| 100 | Settings::values.use_docked_mode = qt_config->value("use_docked_mode", false).toBool(); | 107 | Settings::values.use_docked_mode = qt_config->value("use_docked_mode", false).toBool(); |
| 108 | Settings::values.username = qt_config->value("username", "yuzu").toString().toStdString(); | ||
| 109 | Settings::values.language_index = qt_config->value("language_index", 1).toInt(); | ||
| 101 | qt_config->endGroup(); | 110 | qt_config->endGroup(); |
| 102 | 111 | ||
| 103 | qt_config->beginGroup("Miscellaneous"); | 112 | qt_config->beginGroup("Miscellaneous"); |
| 104 | Settings::values.log_filter = qt_config->value("log_filter", "*:Info").toString().toStdString(); | 113 | Settings::values.log_filter = qt_config->value("log_filter", "*:Info").toString().toStdString(); |
| 114 | Settings::values.use_dev_keys = qt_config->value("use_dev_keys", false).toBool(); | ||
| 105 | qt_config->endGroup(); | 115 | qt_config->endGroup(); |
| 106 | 116 | ||
| 107 | qt_config->beginGroup("Debugging"); | 117 | qt_config->beginGroup("Debugging"); |
| @@ -195,16 +205,25 @@ void Config::SaveValues() { | |||
| 195 | qt_config->setValue("bg_blue", (double)Settings::values.bg_blue); | 205 | qt_config->setValue("bg_blue", (double)Settings::values.bg_blue); |
| 196 | qt_config->endGroup(); | 206 | qt_config->endGroup(); |
| 197 | 207 | ||
| 208 | qt_config->beginGroup("Audio"); | ||
| 209 | qt_config->setValue("output_engine", QString::fromStdString(Settings::values.sink_id)); | ||
| 210 | qt_config->setValue("output_device", QString::fromStdString(Settings::values.audio_device_id)); | ||
| 211 | qt_config->setValue("volume", Settings::values.volume); | ||
| 212 | qt_config->endGroup(); | ||
| 213 | |||
| 198 | qt_config->beginGroup("Data Storage"); | 214 | qt_config->beginGroup("Data Storage"); |
| 199 | qt_config->setValue("use_virtual_sd", Settings::values.use_virtual_sd); | 215 | qt_config->setValue("use_virtual_sd", Settings::values.use_virtual_sd); |
| 200 | qt_config->endGroup(); | 216 | qt_config->endGroup(); |
| 201 | 217 | ||
| 202 | qt_config->beginGroup("System"); | 218 | qt_config->beginGroup("System"); |
| 203 | qt_config->setValue("use_docked_mode", Settings::values.use_docked_mode); | 219 | qt_config->setValue("use_docked_mode", Settings::values.use_docked_mode); |
| 220 | qt_config->setValue("username", QString::fromStdString(Settings::values.username)); | ||
| 221 | qt_config->setValue("language_index", Settings::values.language_index); | ||
| 204 | qt_config->endGroup(); | 222 | qt_config->endGroup(); |
| 205 | 223 | ||
| 206 | qt_config->beginGroup("Miscellaneous"); | 224 | qt_config->beginGroup("Miscellaneous"); |
| 207 | qt_config->setValue("log_filter", QString::fromStdString(Settings::values.log_filter)); | 225 | qt_config->setValue("log_filter", QString::fromStdString(Settings::values.log_filter)); |
| 226 | qt_config->setValue("use_dev_keys", Settings::values.use_dev_keys); | ||
| 208 | qt_config->endGroup(); | 227 | qt_config->endGroup(); |
| 209 | 228 | ||
| 210 | qt_config->beginGroup("Debugging"); | 229 | qt_config->beginGroup("Debugging"); |
diff --git a/src/yuzu/configuration/configure.ui b/src/yuzu/configuration/configure.ui index c5303851c..c8e0b88af 100644 --- a/src/yuzu/configuration/configure.ui +++ b/src/yuzu/configuration/configure.ui | |||
| @@ -34,11 +34,16 @@ | |||
| 34 | <string>Input</string> | 34 | <string>Input</string> |
| 35 | </attribute> | 35 | </attribute> |
| 36 | </widget> | 36 | </widget> |
| 37 | <widget class="ConfigureGraphics" name="graphicsTab"> | 37 | <widget class="ConfigureGraphics" name="graphicsTab"> |
| 38 | <attribute name="title"> | 38 | <attribute name="title"> |
| 39 | <string>Graphics</string> | 39 | <string>Graphics</string> |
| 40 | </attribute> | 40 | </attribute> |
| 41 | </widget> | 41 | </widget> |
| 42 | <widget class="ConfigureAudio" name="audioTab"> | ||
| 43 | <attribute name="title"> | ||
| 44 | <string>Audio</string> | ||
| 45 | </attribute> | ||
| 46 | </widget> | ||
| 42 | <widget class="ConfigureDebug" name="debugTab"> | 47 | <widget class="ConfigureDebug" name="debugTab"> |
| 43 | <attribute name="title"> | 48 | <attribute name="title"> |
| 44 | <string>Debug</string> | 49 | <string>Debug</string> |
| @@ -69,6 +74,12 @@ | |||
| 69 | <container>1</container> | 74 | <container>1</container> |
| 70 | </customwidget> | 75 | </customwidget> |
| 71 | <customwidget> | 76 | <customwidget> |
| 77 | <class>ConfigureAudio</class> | ||
| 78 | <extends>QWidget</extends> | ||
| 79 | <header>configuration/configure_audio.h</header> | ||
| 80 | <container>1</container> | ||
| 81 | </customwidget> | ||
| 82 | <customwidget> | ||
| 72 | <class>ConfigureDebug</class> | 83 | <class>ConfigureDebug</class> |
| 73 | <extends>QWidget</extends> | 84 | <extends>QWidget</extends> |
| 74 | <header>configuration/configure_debug.h</header> | 85 | <header>configuration/configure_debug.h</header> |
diff --git a/src/yuzu/configuration/configure_audio.cpp b/src/yuzu/configuration/configure_audio.cpp new file mode 100644 index 000000000..fbb813f6c --- /dev/null +++ b/src/yuzu/configuration/configure_audio.cpp | |||
| @@ -0,0 +1,90 @@ | |||
| 1 | // Copyright 2018 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <memory> | ||
| 6 | |||
| 7 | #include "audio_core/sink.h" | ||
| 8 | #include "audio_core/sink_details.h" | ||
| 9 | #include "core/core.h" | ||
| 10 | #include "core/settings.h" | ||
| 11 | #include "ui_configure_audio.h" | ||
| 12 | #include "yuzu/configuration/configure_audio.h" | ||
| 13 | |||
| 14 | ConfigureAudio::ConfigureAudio(QWidget* parent) | ||
| 15 | : QWidget(parent), ui(std::make_unique<Ui::ConfigureAudio>()) { | ||
| 16 | ui->setupUi(this); | ||
| 17 | |||
| 18 | ui->output_sink_combo_box->clear(); | ||
| 19 | ui->output_sink_combo_box->addItem("auto"); | ||
| 20 | for (const auto& sink_detail : AudioCore::g_sink_details) { | ||
| 21 | ui->output_sink_combo_box->addItem(sink_detail.id); | ||
| 22 | } | ||
| 23 | |||
| 24 | connect(ui->volume_slider, &QSlider::valueChanged, [this] { | ||
| 25 | ui->volume_indicator->setText(tr("%1 %").arg(ui->volume_slider->sliderPosition())); | ||
| 26 | }); | ||
| 27 | |||
| 28 | this->setConfiguration(); | ||
| 29 | connect(ui->output_sink_combo_box, | ||
| 30 | static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, | ||
| 31 | &ConfigureAudio::updateAudioDevices); | ||
| 32 | |||
| 33 | ui->output_sink_combo_box->setEnabled(!Core::System::GetInstance().IsPoweredOn()); | ||
| 34 | ui->audio_device_combo_box->setEnabled(!Core::System::GetInstance().IsPoweredOn()); | ||
| 35 | } | ||
| 36 | |||
| 37 | ConfigureAudio::~ConfigureAudio() = default; | ||
| 38 | |||
| 39 | void ConfigureAudio::setConfiguration() { | ||
| 40 | int new_sink_index = 0; | ||
| 41 | for (int index = 0; index < ui->output_sink_combo_box->count(); index++) { | ||
| 42 | if (ui->output_sink_combo_box->itemText(index).toStdString() == Settings::values.sink_id) { | ||
| 43 | new_sink_index = index; | ||
| 44 | break; | ||
| 45 | } | ||
| 46 | } | ||
| 47 | ui->output_sink_combo_box->setCurrentIndex(new_sink_index); | ||
| 48 | |||
| 49 | // The device list cannot be pre-populated (nor listed) until the output sink is known. | ||
| 50 | updateAudioDevices(new_sink_index); | ||
| 51 | |||
| 52 | int new_device_index = -1; | ||
| 53 | for (int index = 0; index < ui->audio_device_combo_box->count(); index++) { | ||
| 54 | if (ui->audio_device_combo_box->itemText(index).toStdString() == | ||
| 55 | Settings::values.audio_device_id) { | ||
| 56 | new_device_index = index; | ||
| 57 | break; | ||
| 58 | } | ||
| 59 | } | ||
| 60 | ui->audio_device_combo_box->setCurrentIndex(new_device_index); | ||
| 61 | |||
| 62 | ui->volume_slider->setValue(Settings::values.volume * ui->volume_slider->maximum()); | ||
| 63 | ui->volume_indicator->setText(tr("%1 %").arg(ui->volume_slider->sliderPosition())); | ||
| 64 | } | ||
| 65 | |||
| 66 | void ConfigureAudio::applyConfiguration() { | ||
| 67 | Settings::values.sink_id = | ||
| 68 | ui->output_sink_combo_box->itemText(ui->output_sink_combo_box->currentIndex()) | ||
| 69 | .toStdString(); | ||
| 70 | Settings::values.audio_device_id = | ||
| 71 | ui->audio_device_combo_box->itemText(ui->audio_device_combo_box->currentIndex()) | ||
| 72 | .toStdString(); | ||
| 73 | Settings::values.volume = | ||
| 74 | static_cast<float>(ui->volume_slider->sliderPosition()) / ui->volume_slider->maximum(); | ||
| 75 | } | ||
| 76 | |||
| 77 | void ConfigureAudio::updateAudioDevices(int sink_index) { | ||
| 78 | ui->audio_device_combo_box->clear(); | ||
| 79 | ui->audio_device_combo_box->addItem(AudioCore::auto_device_name); | ||
| 80 | |||
| 81 | std::string sink_id = ui->output_sink_combo_box->itemText(sink_index).toStdString(); | ||
| 82 | std::vector<std::string> device_list = AudioCore::GetSinkDetails(sink_id).list_devices(); | ||
| 83 | for (const auto& device : device_list) { | ||
| 84 | ui->audio_device_combo_box->addItem(device.c_str()); | ||
| 85 | } | ||
| 86 | } | ||
| 87 | |||
| 88 | void ConfigureAudio::retranslateUi() { | ||
| 89 | ui->retranslateUi(this); | ||
| 90 | } | ||
diff --git a/src/yuzu/configuration/configure_audio.h b/src/yuzu/configuration/configure_audio.h new file mode 100644 index 000000000..4f0af4163 --- /dev/null +++ b/src/yuzu/configuration/configure_audio.h | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | // Copyright 2018 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | #include <QWidget> | ||
| 9 | |||
| 10 | namespace Ui { | ||
| 11 | class ConfigureAudio; | ||
| 12 | } | ||
| 13 | |||
| 14 | class ConfigureAudio : public QWidget { | ||
| 15 | Q_OBJECT | ||
| 16 | |||
| 17 | public: | ||
| 18 | explicit ConfigureAudio(QWidget* parent = nullptr); | ||
| 19 | ~ConfigureAudio(); | ||
| 20 | |||
| 21 | void applyConfiguration(); | ||
| 22 | void retranslateUi(); | ||
| 23 | |||
| 24 | public slots: | ||
| 25 | void updateAudioDevices(int sink_index); | ||
| 26 | |||
| 27 | private: | ||
| 28 | void setConfiguration(); | ||
| 29 | |||
| 30 | std::unique_ptr<Ui::ConfigureAudio> ui; | ||
| 31 | }; | ||
diff --git a/src/yuzu/configuration/configure_audio.ui b/src/yuzu/configuration/configure_audio.ui new file mode 100644 index 000000000..ef67890dc --- /dev/null +++ b/src/yuzu/configuration/configure_audio.ui | |||
| @@ -0,0 +1,130 @@ | |||
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <ui version="4.0"> | ||
| 3 | <class>ConfigureAudio</class> | ||
| 4 | <widget class="QWidget" name="ConfigureAudio"> | ||
| 5 | <property name="geometry"> | ||
| 6 | <rect> | ||
| 7 | <x>0</x> | ||
| 8 | <y>0</y> | ||
| 9 | <width>188</width> | ||
| 10 | <height>246</height> | ||
| 11 | </rect> | ||
| 12 | </property> | ||
| 13 | <layout class="QVBoxLayout"> | ||
| 14 | <item> | ||
| 15 | <widget class="QGroupBox" name="groupBox"> | ||
| 16 | <property name="title"> | ||
| 17 | <string>Audio</string> | ||
| 18 | </property> | ||
| 19 | <layout class="QVBoxLayout"> | ||
| 20 | <item> | ||
| 21 | <layout class="QHBoxLayout"> | ||
| 22 | <item> | ||
| 23 | <widget class="QLabel" name="label"> | ||
| 24 | <property name="text"> | ||
| 25 | <string>Output Engine:</string> | ||
| 26 | </property> | ||
| 27 | </widget> | ||
| 28 | </item> | ||
| 29 | <item> | ||
| 30 | <widget class="QComboBox" name="output_sink_combo_box"/> | ||
| 31 | </item> | ||
| 32 | </layout> | ||
| 33 | </item> | ||
| 34 | <item> | ||
| 35 | <layout class="QHBoxLayout"> | ||
| 36 | <item> | ||
| 37 | <widget class="QLabel" name="label"> | ||
| 38 | <property name="text"> | ||
| 39 | <string>Audio Device:</string> | ||
| 40 | </property> | ||
| 41 | </widget> | ||
| 42 | </item> | ||
| 43 | <item> | ||
| 44 | <widget class="QComboBox" name="audio_device_combo_box"/> | ||
| 45 | </item> | ||
| 46 | </layout> | ||
| 47 | </item> | ||
| 48 | <item> | ||
| 49 | <layout class="QHBoxLayout" name="horizontalLayout_2"> | ||
| 50 | <property name="topMargin"> | ||
| 51 | <number>0</number> | ||
| 52 | </property> | ||
| 53 | <item> | ||
| 54 | <widget class="QLabel" name="label"> | ||
| 55 | <property name="text"> | ||
| 56 | <string>Volume:</string> | ||
| 57 | </property> | ||
| 58 | </widget> | ||
| 59 | </item> | ||
| 60 | <item> | ||
| 61 | <spacer name="horizontalSpacer"> | ||
| 62 | <property name="orientation"> | ||
| 63 | <enum>Qt::Horizontal</enum> | ||
| 64 | </property> | ||
| 65 | <property name="sizeHint" stdset="0"> | ||
| 66 | <size> | ||
| 67 | <width>40</width> | ||
| 68 | <height>20</height> | ||
| 69 | </size> | ||
| 70 | </property> | ||
| 71 | </spacer> | ||
| 72 | </item> | ||
| 73 | <item> | ||
| 74 | <widget class="QSlider" name="volume_slider"> | ||
| 75 | <property name="sizePolicy"> | ||
| 76 | <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> | ||
| 77 | <horstretch>0</horstretch> | ||
| 78 | <verstretch>0</verstretch> | ||
| 79 | </sizepolicy> | ||
| 80 | </property> | ||
| 81 | <property name="maximum"> | ||
| 82 | <number>100</number> | ||
| 83 | </property> | ||
| 84 | <property name="pageStep"> | ||
| 85 | <number>10</number> | ||
| 86 | </property> | ||
| 87 | <property name="orientation"> | ||
| 88 | <enum>Qt::Horizontal</enum> | ||
| 89 | </property> | ||
| 90 | </widget> | ||
| 91 | </item> | ||
| 92 | <item> | ||
| 93 | <widget class="QLabel" name="volume_indicator"> | ||
| 94 | <property name="minimumSize"> | ||
| 95 | <size> | ||
| 96 | <width>32</width> | ||
| 97 | <height>0</height> | ||
| 98 | </size> | ||
| 99 | </property> | ||
| 100 | <property name="text"> | ||
| 101 | <string>0 %</string> | ||
| 102 | </property> | ||
| 103 | <property name="alignment"> | ||
| 104 | <set>Qt::AlignCenter</set> | ||
| 105 | </property> | ||
| 106 | </widget> | ||
| 107 | </item> | ||
| 108 | </layout> | ||
| 109 | </item> | ||
| 110 | </layout> | ||
| 111 | </widget> | ||
| 112 | </item> | ||
| 113 | <item> | ||
| 114 | <spacer> | ||
| 115 | <property name="orientation"> | ||
| 116 | <enum>Qt::Vertical</enum> | ||
| 117 | </property> | ||
| 118 | <property name="sizeHint" stdset="0"> | ||
| 119 | <size> | ||
| 120 | <width>167</width> | ||
| 121 | <height>55</height> | ||
| 122 | </size> | ||
| 123 | </property> | ||
| 124 | </spacer> | ||
| 125 | </item> | ||
| 126 | </layout> | ||
| 127 | </widget> | ||
| 128 | <resources/> | ||
| 129 | <connections/> | ||
| 130 | </ui> | ||
diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp index 5e66239ff..45d84f19a 100644 --- a/src/yuzu/configuration/configure_debug.cpp +++ b/src/yuzu/configuration/configure_debug.cpp | |||
| @@ -24,7 +24,7 @@ ConfigureDebug::ConfigureDebug(QWidget* parent) : QWidget(parent), ui(new Ui::Co | |||
| 24 | }); | 24 | }); |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | ConfigureDebug::~ConfigureDebug() {} | 27 | ConfigureDebug::~ConfigureDebug() = default; |
| 28 | 28 | ||
| 29 | void ConfigureDebug::setConfiguration() { | 29 | void ConfigureDebug::setConfiguration() { |
| 30 | ui->toggle_gdbstub->setChecked(Settings::values.use_gdbstub); | 30 | ui->toggle_gdbstub->setChecked(Settings::values.use_gdbstub); |
| @@ -44,5 +44,4 @@ void ConfigureDebug::applyConfiguration() { | |||
| 44 | Log::Filter filter; | 44 | Log::Filter filter; |
| 45 | filter.ParseFilterString(Settings::values.log_filter); | 45 | filter.ParseFilterString(Settings::values.log_filter); |
| 46 | Log::SetGlobalFilter(filter); | 46 | Log::SetGlobalFilter(filter); |
| 47 | Settings::Apply(); | ||
| 48 | } | 47 | } |
diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui index 118e91cf1..5ae7276bd 100644 --- a/src/yuzu/configuration/configure_debug.ui +++ b/src/yuzu/configuration/configure_debug.ui | |||
| @@ -23,13 +23,6 @@ | |||
| 23 | </property> | 23 | </property> |
| 24 | <layout class="QVBoxLayout" name="verticalLayout_3"> | 24 | <layout class="QVBoxLayout" name="verticalLayout_3"> |
| 25 | <item> | 25 | <item> |
| 26 | <widget class="QLabel" name="label_1"> | ||
| 27 | <property name="text"> | ||
| 28 | <string>The GDB Stub only works correctly when the CPU JIT is off.</string> | ||
| 29 | </property> | ||
| 30 | </widget> | ||
| 31 | </item> | ||
| 32 | <item> | ||
| 33 | <layout class="QHBoxLayout" name="horizontalLayout_1"> | 26 | <layout class="QHBoxLayout" name="horizontalLayout_1"> |
| 34 | <item> | 27 | <item> |
| 35 | <widget class="QCheckBox" name="toggle_gdbstub"> | 28 | <widget class="QCheckBox" name="toggle_gdbstub"> |
diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp index 358f33005..cc4b326ae 100644 --- a/src/yuzu/configuration/configure_dialog.cpp +++ b/src/yuzu/configuration/configure_dialog.cpp | |||
| @@ -6,13 +6,16 @@ | |||
| 6 | #include "ui_configure.h" | 6 | #include "ui_configure.h" |
| 7 | #include "yuzu/configuration/config.h" | 7 | #include "yuzu/configuration/config.h" |
| 8 | #include "yuzu/configuration/configure_dialog.h" | 8 | #include "yuzu/configuration/configure_dialog.h" |
| 9 | #include "yuzu/hotkeys.h" | ||
| 9 | 10 | ||
| 10 | ConfigureDialog::ConfigureDialog(QWidget* parent) : QDialog(parent), ui(new Ui::ConfigureDialog) { | 11 | ConfigureDialog::ConfigureDialog(QWidget* parent, const HotkeyRegistry& registry) |
| 12 | : QDialog(parent), ui(new Ui::ConfigureDialog) { | ||
| 11 | ui->setupUi(this); | 13 | ui->setupUi(this); |
| 14 | ui->generalTab->PopulateHotkeyList(registry); | ||
| 12 | this->setConfiguration(); | 15 | this->setConfiguration(); |
| 13 | } | 16 | } |
| 14 | 17 | ||
| 15 | ConfigureDialog::~ConfigureDialog() {} | 18 | ConfigureDialog::~ConfigureDialog() = default; |
| 16 | 19 | ||
| 17 | void ConfigureDialog::setConfiguration() {} | 20 | void ConfigureDialog::setConfiguration() {} |
| 18 | 21 | ||
| @@ -21,6 +24,7 @@ void ConfigureDialog::applyConfiguration() { | |||
| 21 | ui->systemTab->applyConfiguration(); | 24 | ui->systemTab->applyConfiguration(); |
| 22 | ui->inputTab->applyConfiguration(); | 25 | ui->inputTab->applyConfiguration(); |
| 23 | ui->graphicsTab->applyConfiguration(); | 26 | ui->graphicsTab->applyConfiguration(); |
| 27 | ui->audioTab->applyConfiguration(); | ||
| 24 | ui->debugTab->applyConfiguration(); | 28 | ui->debugTab->applyConfiguration(); |
| 25 | Settings::Apply(); | 29 | Settings::Apply(); |
| 26 | } | 30 | } |
diff --git a/src/yuzu/configuration/configure_dialog.h b/src/yuzu/configuration/configure_dialog.h index 21fa1f501..bbbdacc29 100644 --- a/src/yuzu/configuration/configure_dialog.h +++ b/src/yuzu/configuration/configure_dialog.h | |||
| @@ -7,6 +7,8 @@ | |||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <QDialog> | 8 | #include <QDialog> |
| 9 | 9 | ||
| 10 | class HotkeyRegistry; | ||
| 11 | |||
| 10 | namespace Ui { | 12 | namespace Ui { |
| 11 | class ConfigureDialog; | 13 | class ConfigureDialog; |
| 12 | } | 14 | } |
| @@ -15,7 +17,7 @@ class ConfigureDialog : public QDialog { | |||
| 15 | Q_OBJECT | 17 | Q_OBJECT |
| 16 | 18 | ||
| 17 | public: | 19 | public: |
| 18 | explicit ConfigureDialog(QWidget* parent); | 20 | explicit ConfigureDialog(QWidget* parent, const HotkeyRegistry& registry); |
| 19 | ~ConfigureDialog(); | 21 | ~ConfigureDialog(); |
| 20 | 22 | ||
| 21 | void applyConfiguration(); | 23 | void applyConfiguration(); |
diff --git a/src/yuzu/configuration/configure_general.cpp b/src/yuzu/configuration/configure_general.cpp index baa558667..d8caee1e8 100644 --- a/src/yuzu/configuration/configure_general.cpp +++ b/src/yuzu/configuration/configure_general.cpp | |||
| @@ -24,7 +24,7 @@ ConfigureGeneral::ConfigureGeneral(QWidget* parent) | |||
| 24 | ui->use_docked_mode->setEnabled(!Core::System::GetInstance().IsPoweredOn()); | 24 | ui->use_docked_mode->setEnabled(!Core::System::GetInstance().IsPoweredOn()); |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | ConfigureGeneral::~ConfigureGeneral() {} | 27 | ConfigureGeneral::~ConfigureGeneral() = default; |
| 28 | 28 | ||
| 29 | void ConfigureGeneral::setConfiguration() { | 29 | void ConfigureGeneral::setConfiguration() { |
| 30 | ui->toggle_deepscan->setChecked(UISettings::values.gamedir_deepscan); | 30 | ui->toggle_deepscan->setChecked(UISettings::values.gamedir_deepscan); |
| @@ -35,6 +35,10 @@ void ConfigureGeneral::setConfiguration() { | |||
| 35 | ui->use_docked_mode->setChecked(Settings::values.use_docked_mode); | 35 | ui->use_docked_mode->setChecked(Settings::values.use_docked_mode); |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | void ConfigureGeneral::PopulateHotkeyList(const HotkeyRegistry& registry) { | ||
| 39 | ui->widget->Populate(registry); | ||
| 40 | } | ||
| 41 | |||
| 38 | void ConfigureGeneral::applyConfiguration() { | 42 | void ConfigureGeneral::applyConfiguration() { |
| 39 | UISettings::values.gamedir_deepscan = ui->toggle_deepscan->isChecked(); | 43 | UISettings::values.gamedir_deepscan = ui->toggle_deepscan->isChecked(); |
| 40 | UISettings::values.confirm_before_closing = ui->toggle_check_exit->isChecked(); | 44 | UISettings::values.confirm_before_closing = ui->toggle_check_exit->isChecked(); |
| @@ -44,5 +48,4 @@ void ConfigureGeneral::applyConfiguration() { | |||
| 44 | Settings::values.use_cpu_jit = ui->use_cpu_jit->isChecked(); | 48 | Settings::values.use_cpu_jit = ui->use_cpu_jit->isChecked(); |
| 45 | Settings::values.use_multi_core = ui->use_multi_core->isChecked(); | 49 | Settings::values.use_multi_core = ui->use_multi_core->isChecked(); |
| 46 | Settings::values.use_docked_mode = ui->use_docked_mode->isChecked(); | 50 | Settings::values.use_docked_mode = ui->use_docked_mode->isChecked(); |
| 47 | Settings::Apply(); | ||
| 48 | } | 51 | } |
diff --git a/src/yuzu/configuration/configure_general.h b/src/yuzu/configuration/configure_general.h index 447552d8c..4770034cc 100644 --- a/src/yuzu/configuration/configure_general.h +++ b/src/yuzu/configuration/configure_general.h | |||
| @@ -7,6 +7,8 @@ | |||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <QWidget> | 8 | #include <QWidget> |
| 9 | 9 | ||
| 10 | class HotkeyRegistry; | ||
| 11 | |||
| 10 | namespace Ui { | 12 | namespace Ui { |
| 11 | class ConfigureGeneral; | 13 | class ConfigureGeneral; |
| 12 | } | 14 | } |
| @@ -18,11 +20,11 @@ public: | |||
| 18 | explicit ConfigureGeneral(QWidget* parent = nullptr); | 20 | explicit ConfigureGeneral(QWidget* parent = nullptr); |
| 19 | ~ConfigureGeneral(); | 21 | ~ConfigureGeneral(); |
| 20 | 22 | ||
| 23 | void PopulateHotkeyList(const HotkeyRegistry& registry); | ||
| 21 | void applyConfiguration(); | 24 | void applyConfiguration(); |
| 22 | 25 | ||
| 23 | private: | 26 | private: |
| 24 | void setConfiguration(); | 27 | void setConfiguration(); |
| 25 | 28 | ||
| 26 | private: | ||
| 27 | std::unique_ptr<Ui::ConfigureGeneral> ui; | 29 | std::unique_ptr<Ui::ConfigureGeneral> ui; |
| 28 | }; | 30 | }; |
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp index 7664880d5..4afe0f81b 100644 --- a/src/yuzu/configuration/configure_graphics.cpp +++ b/src/yuzu/configuration/configure_graphics.cpp | |||
| @@ -14,7 +14,7 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent) | |||
| 14 | this->setConfiguration(); | 14 | this->setConfiguration(); |
| 15 | } | 15 | } |
| 16 | 16 | ||
| 17 | ConfigureGraphics::~ConfigureGraphics() {} | 17 | ConfigureGraphics::~ConfigureGraphics() = default; |
| 18 | 18 | ||
| 19 | enum class Resolution : int { | 19 | enum class Resolution : int { |
| 20 | Auto, | 20 | Auto, |
| @@ -67,5 +67,4 @@ void ConfigureGraphics::applyConfiguration() { | |||
| 67 | ToResolutionFactor(static_cast<Resolution>(ui->resolution_factor_combobox->currentIndex())); | 67 | ToResolutionFactor(static_cast<Resolution>(ui->resolution_factor_combobox->currentIndex())); |
| 68 | Settings::values.toggle_framelimit = ui->toggle_framelimit->isChecked(); | 68 | Settings::values.toggle_framelimit = ui->toggle_framelimit->isChecked(); |
| 69 | Settings::values.use_accurate_framebuffers = ui->use_accurate_framebuffers->isChecked(); | 69 | Settings::values.use_accurate_framebuffers = ui->use_accurate_framebuffers->isChecked(); |
| 70 | Settings::Apply(); | ||
| 71 | } | 70 | } |
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp index 78559e2bb..5e7badedf 100644 --- a/src/yuzu/configuration/configure_input.cpp +++ b/src/yuzu/configuration/configure_input.cpp | |||
| @@ -191,8 +191,6 @@ void ConfigureInput::applyConfiguration() { | |||
| 191 | [](const Common::ParamPackage& param) { return param.Serialize(); }); | 191 | [](const Common::ParamPackage& param) { return param.Serialize(); }); |
| 192 | std::transform(analogs_param.begin(), analogs_param.end(), Settings::values.analogs.begin(), | 192 | std::transform(analogs_param.begin(), analogs_param.end(), Settings::values.analogs.begin(), |
| 193 | [](const Common::ParamPackage& param) { return param.Serialize(); }); | 193 | [](const Common::ParamPackage& param) { return param.Serialize(); }); |
| 194 | |||
| 195 | Settings::Apply(); | ||
| 196 | } | 194 | } |
| 197 | 195 | ||
| 198 | void ConfigureInput::loadConfiguration() { | 196 | void ConfigureInput::loadConfiguration() { |
diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp index d09505a0f..e9ed9c38f 100644 --- a/src/yuzu/configuration/configure_system.cpp +++ b/src/yuzu/configuration/configure_system.cpp | |||
| @@ -4,9 +4,10 @@ | |||
| 4 | 4 | ||
| 5 | #include <QMessageBox> | 5 | #include <QMessageBox> |
| 6 | #include "core/core.h" | 6 | #include "core/core.h" |
| 7 | #include "core/settings.h" | ||
| 7 | #include "ui_configure_system.h" | 8 | #include "ui_configure_system.h" |
| 8 | #include "yuzu/configuration/configure_system.h" | 9 | #include "yuzu/configuration/configure_system.h" |
| 9 | #include "yuzu/ui_settings.h" | 10 | #include "yuzu/main.h" |
| 10 | 11 | ||
| 11 | static const std::array<int, 12> days_in_month = {{ | 12 | static const std::array<int, 12> days_in_month = {{ |
| 12 | 31, | 13 | 31, |
| @@ -34,10 +35,12 @@ ConfigureSystem::ConfigureSystem(QWidget* parent) : QWidget(parent), ui(new Ui:: | |||
| 34 | this->setConfiguration(); | 35 | this->setConfiguration(); |
| 35 | } | 36 | } |
| 36 | 37 | ||
| 37 | ConfigureSystem::~ConfigureSystem() {} | 38 | ConfigureSystem::~ConfigureSystem() = default; |
| 38 | 39 | ||
| 39 | void ConfigureSystem::setConfiguration() { | 40 | void ConfigureSystem::setConfiguration() { |
| 40 | enabled = !Core::System::GetInstance().IsPoweredOn(); | 41 | enabled = !Core::System::GetInstance().IsPoweredOn(); |
| 42 | ui->edit_username->setText(QString::fromStdString(Settings::values.username)); | ||
| 43 | ui->combo_language->setCurrentIndex(Settings::values.language_index); | ||
| 41 | } | 44 | } |
| 42 | 45 | ||
| 43 | void ConfigureSystem::ReadSystemSettings() {} | 46 | void ConfigureSystem::ReadSystemSettings() {} |
| @@ -45,6 +48,9 @@ void ConfigureSystem::ReadSystemSettings() {} | |||
| 45 | void ConfigureSystem::applyConfiguration() { | 48 | void ConfigureSystem::applyConfiguration() { |
| 46 | if (!enabled) | 49 | if (!enabled) |
| 47 | return; | 50 | return; |
| 51 | Settings::values.username = ui->edit_username->text().toStdString(); | ||
| 52 | Settings::values.language_index = ui->combo_language->currentIndex(); | ||
| 53 | Settings::Apply(); | ||
| 48 | } | 54 | } |
| 49 | 55 | ||
| 50 | void ConfigureSystem::updateBirthdayComboBox(int birthmonth_index) { | 56 | void ConfigureSystem::updateBirthdayComboBox(int birthmonth_index) { |
diff --git a/src/yuzu/configuration/configure_system.ui b/src/yuzu/configuration/configure_system.ui index 8caf49623..f3f8db038 100644 --- a/src/yuzu/configuration/configure_system.ui +++ b/src/yuzu/configuration/configure_system.ui | |||
| @@ -38,7 +38,7 @@ | |||
| 38 | </sizepolicy> | 38 | </sizepolicy> |
| 39 | </property> | 39 | </property> |
| 40 | <property name="maxLength"> | 40 | <property name="maxLength"> |
| 41 | <number>10</number> | 41 | <number>32</number> |
| 42 | </property> | 42 | </property> |
| 43 | </widget> | 43 | </widget> |
| 44 | </item> | 44 | </item> |
| @@ -164,7 +164,7 @@ | |||
| 164 | </item> | 164 | </item> |
| 165 | <item> | 165 | <item> |
| 166 | <property name="text"> | 166 | <property name="text"> |
| 167 | <string>Simplified Chinese (简体中文)</string> | 167 | <string>Chinese</string> |
| 168 | </property> | 168 | </property> |
| 169 | </item> | 169 | </item> |
| 170 | <item> | 170 | <item> |
| @@ -187,6 +187,31 @@ | |||
| 187 | <string>Russian (Русский)</string> | 187 | <string>Russian (Русский)</string> |
| 188 | </property> | 188 | </property> |
| 189 | </item> | 189 | </item> |
| 190 | <item> | ||
| 191 | <property name="text"> | ||
| 192 | <string>Taiwanese</string> | ||
| 193 | </property> | ||
| 194 | </item> | ||
| 195 | <item> | ||
| 196 | <property name="text"> | ||
| 197 | <string>British English</string> | ||
| 198 | </property> | ||
| 199 | </item> | ||
| 200 | <item> | ||
| 201 | <property name="text"> | ||
| 202 | <string>Canadian French</string> | ||
| 203 | </property> | ||
| 204 | </item> | ||
| 205 | <item> | ||
| 206 | <property name="text"> | ||
| 207 | <string>Latin American Spanish</string> | ||
| 208 | </property> | ||
| 209 | </item> | ||
| 210 | <item> | ||
| 211 | <property name="text"> | ||
| 212 | <string>Simplified Chinese</string> | ||
| 213 | </property> | ||
| 214 | </item> | ||
| 190 | <item> | 215 | <item> |
| 191 | <property name="text"> | 216 | <property name="text"> |
| 192 | <string>Traditional Chinese (正體中文)</string> | 217 | <string>Traditional Chinese (正體中文)</string> |
diff --git a/src/yuzu/debugger/graphics/graphics_breakpoint_observer.cpp b/src/yuzu/debugger/graphics/graphics_breakpoint_observer.cpp index d6d61a739..5f459ccfb 100644 --- a/src/yuzu/debugger/graphics/graphics_breakpoint_observer.cpp +++ b/src/yuzu/debugger/graphics/graphics_breakpoint_observer.cpp | |||
| @@ -10,12 +10,12 @@ BreakPointObserverDock::BreakPointObserverDock(std::shared_ptr<Tegra::DebugConte | |||
| 10 | : QDockWidget(title, parent), BreakPointObserver(debug_context) { | 10 | : QDockWidget(title, parent), BreakPointObserver(debug_context) { |
| 11 | qRegisterMetaType<Tegra::DebugContext::Event>("Tegra::DebugContext::Event"); | 11 | qRegisterMetaType<Tegra::DebugContext::Event>("Tegra::DebugContext::Event"); |
| 12 | 12 | ||
| 13 | connect(this, SIGNAL(Resumed()), this, SLOT(OnResumed())); | 13 | connect(this, &BreakPointObserverDock::Resumed, this, &BreakPointObserverDock::OnResumed); |
| 14 | 14 | ||
| 15 | // NOTE: This signal is emitted from a non-GUI thread, but connect() takes | 15 | // NOTE: This signal is emitted from a non-GUI thread, but connect() takes |
| 16 | // care of delaying its handling to the GUI thread. | 16 | // care of delaying its handling to the GUI thread. |
| 17 | connect(this, SIGNAL(BreakPointHit(Tegra::DebugContext::Event, void*)), this, | 17 | connect(this, &BreakPointObserverDock::BreakPointHit, this, |
| 18 | SLOT(OnBreakPointHit(Tegra::DebugContext::Event, void*)), Qt::BlockingQueuedConnection); | 18 | &BreakPointObserverDock::OnBreakPointHit, Qt::BlockingQueuedConnection); |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | void BreakPointObserverDock::OnMaxwellBreakPointHit(Tegra::DebugContext::Event event, void* data) { | 21 | void BreakPointObserverDock::OnMaxwellBreakPointHit(Tegra::DebugContext::Event event, void* data) { |
diff --git a/src/yuzu/debugger/graphics/graphics_breakpoint_observer.h b/src/yuzu/debugger/graphics/graphics_breakpoint_observer.h index 9d05493cf..ab32f0115 100644 --- a/src/yuzu/debugger/graphics/graphics_breakpoint_observer.h +++ b/src/yuzu/debugger/graphics/graphics_breakpoint_observer.h | |||
| @@ -23,11 +23,11 @@ public: | |||
| 23 | void OnMaxwellBreakPointHit(Tegra::DebugContext::Event event, void* data) override; | 23 | void OnMaxwellBreakPointHit(Tegra::DebugContext::Event event, void* data) override; |
| 24 | void OnMaxwellResume() override; | 24 | void OnMaxwellResume() override; |
| 25 | 25 | ||
| 26 | private slots: | ||
| 27 | virtual void OnBreakPointHit(Tegra::DebugContext::Event event, void* data) = 0; | ||
| 28 | virtual void OnResumed() = 0; | ||
| 29 | |||
| 30 | signals: | 26 | signals: |
| 31 | void Resumed(); | 27 | void Resumed(); |
| 32 | void BreakPointHit(Tegra::DebugContext::Event event, void* data); | 28 | void BreakPointHit(Tegra::DebugContext::Event event, void* data); |
| 29 | |||
| 30 | private: | ||
| 31 | virtual void OnBreakPointHit(Tegra::DebugContext::Event event, void* data) = 0; | ||
| 32 | virtual void OnResumed() = 0; | ||
| 33 | }; | 33 | }; |
diff --git a/src/yuzu/debugger/graphics/graphics_breakpoints.cpp b/src/yuzu/debugger/graphics/graphics_breakpoints.cpp index f98cc8152..eb16a38a0 100644 --- a/src/yuzu/debugger/graphics/graphics_breakpoints.cpp +++ b/src/yuzu/debugger/graphics/graphics_breakpoints.cpp | |||
| @@ -144,21 +144,25 @@ GraphicsBreakPointsWidget::GraphicsBreakPointsWidget( | |||
| 144 | 144 | ||
| 145 | qRegisterMetaType<Tegra::DebugContext::Event>("Tegra::DebugContext::Event"); | 145 | qRegisterMetaType<Tegra::DebugContext::Event>("Tegra::DebugContext::Event"); |
| 146 | 146 | ||
| 147 | connect(breakpoint_list, SIGNAL(doubleClicked(const QModelIndex&)), this, | 147 | connect(breakpoint_list, &QTreeView::doubleClicked, this, |
| 148 | SLOT(OnItemDoubleClicked(const QModelIndex&))); | 148 | &GraphicsBreakPointsWidget::OnItemDoubleClicked); |
| 149 | 149 | ||
| 150 | connect(resume_button, SIGNAL(clicked()), this, SLOT(OnResumeRequested())); | 150 | connect(resume_button, &QPushButton::clicked, this, |
| 151 | &GraphicsBreakPointsWidget::OnResumeRequested); | ||
| 151 | 152 | ||
| 152 | connect(this, SIGNAL(BreakPointHit(Tegra::DebugContext::Event, void*)), this, | 153 | connect(this, &GraphicsBreakPointsWidget::BreakPointHit, this, |
| 153 | SLOT(OnBreakPointHit(Tegra::DebugContext::Event, void*)), Qt::BlockingQueuedConnection); | 154 | &GraphicsBreakPointsWidget::OnBreakPointHit, Qt::BlockingQueuedConnection); |
| 154 | connect(this, SIGNAL(Resumed()), this, SLOT(OnResumed())); | 155 | connect(this, &GraphicsBreakPointsWidget::Resumed, this, &GraphicsBreakPointsWidget::OnResumed); |
| 155 | 156 | ||
| 156 | connect(this, SIGNAL(BreakPointHit(Tegra::DebugContext::Event, void*)), breakpoint_model, | 157 | connect(this, &GraphicsBreakPointsWidget::BreakPointHit, breakpoint_model, |
| 157 | SLOT(OnBreakPointHit(Tegra::DebugContext::Event)), Qt::BlockingQueuedConnection); | 158 | &BreakPointModel::OnBreakPointHit, Qt::BlockingQueuedConnection); |
| 158 | connect(this, SIGNAL(Resumed()), breakpoint_model, SLOT(OnResumed())); | 159 | connect(this, &GraphicsBreakPointsWidget::Resumed, breakpoint_model, |
| 160 | &BreakPointModel::OnResumed); | ||
| 159 | 161 | ||
| 160 | connect(this, SIGNAL(BreakPointsChanged(const QModelIndex&, const QModelIndex&)), | 162 | connect(this, &GraphicsBreakPointsWidget::BreakPointsChanged, |
| 161 | breakpoint_model, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&))); | 163 | [this](const QModelIndex& top_left, const QModelIndex& bottom_right) { |
| 164 | breakpoint_model->dataChanged(top_left, bottom_right); | ||
| 165 | }); | ||
| 162 | 166 | ||
| 163 | QWidget* main_widget = new QWidget; | 167 | QWidget* main_widget = new QWidget; |
| 164 | auto main_layout = new QVBoxLayout; | 168 | auto main_layout = new QVBoxLayout; |
diff --git a/src/yuzu/debugger/graphics/graphics_breakpoints.h b/src/yuzu/debugger/graphics/graphics_breakpoints.h index ae0ede2e8..a920a2ae5 100644 --- a/src/yuzu/debugger/graphics/graphics_breakpoints.h +++ b/src/yuzu/debugger/graphics/graphics_breakpoints.h | |||
| @@ -26,18 +26,17 @@ public: | |||
| 26 | void OnMaxwellBreakPointHit(Tegra::DebugContext::Event event, void* data) override; | 26 | void OnMaxwellBreakPointHit(Tegra::DebugContext::Event event, void* data) override; |
| 27 | void OnMaxwellResume() override; | 27 | void OnMaxwellResume() override; |
| 28 | 28 | ||
| 29 | public slots: | ||
| 30 | void OnBreakPointHit(Tegra::DebugContext::Event event, void* data); | ||
| 31 | void OnItemDoubleClicked(const QModelIndex&); | ||
| 32 | void OnResumeRequested(); | ||
| 33 | void OnResumed(); | ||
| 34 | |||
| 35 | signals: | 29 | signals: |
| 36 | void Resumed(); | 30 | void Resumed(); |
| 37 | void BreakPointHit(Tegra::DebugContext::Event event, void* data); | 31 | void BreakPointHit(Tegra::DebugContext::Event event, void* data); |
| 38 | void BreakPointsChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); | 32 | void BreakPointsChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight); |
| 39 | 33 | ||
| 40 | private: | 34 | private: |
| 35 | void OnBreakPointHit(Tegra::DebugContext::Event event, void* data); | ||
| 36 | void OnItemDoubleClicked(const QModelIndex&); | ||
| 37 | void OnResumeRequested(); | ||
| 38 | void OnResumed(); | ||
| 39 | |||
| 41 | QLabel* status_text; | 40 | QLabel* status_text; |
| 42 | QPushButton* resume_button; | 41 | QPushButton* resume_button; |
| 43 | 42 | ||
diff --git a/src/yuzu/debugger/graphics/graphics_breakpoints_p.h b/src/yuzu/debugger/graphics/graphics_breakpoints_p.h index 35a6876ae..7112b87e6 100644 --- a/src/yuzu/debugger/graphics/graphics_breakpoints_p.h +++ b/src/yuzu/debugger/graphics/graphics_breakpoints_p.h | |||
| @@ -25,7 +25,6 @@ public: | |||
| 25 | 25 | ||
| 26 | bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override; | 26 | bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override; |
| 27 | 27 | ||
| 28 | public slots: | ||
| 29 | void OnBreakPointHit(Tegra::DebugContext::Event event); | 28 | void OnBreakPointHit(Tegra::DebugContext::Event event); |
| 30 | void OnResumed(); | 29 | void OnResumed(); |
| 31 | 30 | ||
diff --git a/src/yuzu/debugger/graphics/graphics_surface.cpp b/src/yuzu/debugger/graphics/graphics_surface.cpp index c41ff693b..3f7103ab9 100644 --- a/src/yuzu/debugger/graphics/graphics_surface.cpp +++ b/src/yuzu/debugger/graphics/graphics_surface.cpp | |||
| @@ -34,7 +34,8 @@ static Tegra::Texture::TextureFormat ConvertToTextureFormat( | |||
| 34 | 34 | ||
| 35 | SurfacePicture::SurfacePicture(QWidget* parent, GraphicsSurfaceWidget* surface_widget_) | 35 | SurfacePicture::SurfacePicture(QWidget* parent, GraphicsSurfaceWidget* surface_widget_) |
| 36 | : QLabel(parent), surface_widget(surface_widget_) {} | 36 | : QLabel(parent), surface_widget(surface_widget_) {} |
| 37 | SurfacePicture::~SurfacePicture() {} | 37 | |
| 38 | SurfacePicture::~SurfacePicture() = default; | ||
| 38 | 39 | ||
| 39 | void SurfacePicture::mousePressEvent(QMouseEvent* event) { | 40 | void SurfacePicture::mousePressEvent(QMouseEvent* event) { |
| 40 | // Only do something while the left mouse button is held down | 41 | // Only do something while the left mouse button is held down |
| @@ -153,22 +154,24 @@ GraphicsSurfaceWidget::GraphicsSurfaceWidget(std::shared_ptr<Tegra::DebugContext | |||
| 153 | save_surface = new QPushButton(QIcon::fromTheme("document-save"), tr("Save")); | 154 | save_surface = new QPushButton(QIcon::fromTheme("document-save"), tr("Save")); |
| 154 | 155 | ||
| 155 | // Connections | 156 | // Connections |
| 156 | connect(this, SIGNAL(Update()), this, SLOT(OnUpdate())); | 157 | connect(this, &GraphicsSurfaceWidget::Update, this, &GraphicsSurfaceWidget::OnUpdate); |
| 157 | connect(surface_source_list, SIGNAL(currentIndexChanged(int)), this, | 158 | connect(surface_source_list, |
| 158 | SLOT(OnSurfaceSourceChanged(int))); | 159 | static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, |
| 159 | connect(surface_address_control, SIGNAL(ValueChanged(qint64)), this, | 160 | &GraphicsSurfaceWidget::OnSurfaceSourceChanged); |
| 160 | SLOT(OnSurfaceAddressChanged(qint64))); | 161 | connect(surface_address_control, &CSpinBox::ValueChanged, this, |
| 161 | connect(surface_width_control, SIGNAL(valueChanged(int)), this, | 162 | &GraphicsSurfaceWidget::OnSurfaceAddressChanged); |
| 162 | SLOT(OnSurfaceWidthChanged(int))); | 163 | connect(surface_width_control, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), |
| 163 | connect(surface_height_control, SIGNAL(valueChanged(int)), this, | 164 | this, &GraphicsSurfaceWidget::OnSurfaceWidthChanged); |
| 164 | SLOT(OnSurfaceHeightChanged(int))); | 165 | connect(surface_height_control, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), |
| 165 | connect(surface_format_control, SIGNAL(currentIndexChanged(int)), this, | 166 | this, &GraphicsSurfaceWidget::OnSurfaceHeightChanged); |
| 166 | SLOT(OnSurfaceFormatChanged(int))); | 167 | connect(surface_format_control, |
| 167 | connect(surface_picker_x_control, SIGNAL(valueChanged(int)), this, | 168 | static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, |
| 168 | SLOT(OnSurfacePickerXChanged(int))); | 169 | &GraphicsSurfaceWidget::OnSurfaceFormatChanged); |
| 169 | connect(surface_picker_y_control, SIGNAL(valueChanged(int)), this, | 170 | connect(surface_picker_x_control, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), |
| 170 | SLOT(OnSurfacePickerYChanged(int))); | 171 | this, &GraphicsSurfaceWidget::OnSurfacePickerXChanged); |
| 171 | connect(save_surface, SIGNAL(clicked()), this, SLOT(SaveSurface())); | 172 | connect(surface_picker_y_control, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), |
| 173 | this, &GraphicsSurfaceWidget::OnSurfacePickerYChanged); | ||
| 174 | connect(save_surface, &QPushButton::clicked, this, &GraphicsSurfaceWidget::SaveSurface); | ||
| 172 | 175 | ||
| 173 | auto main_widget = new QWidget; | 176 | auto main_widget = new QWidget; |
| 174 | auto main_layout = new QVBoxLayout; | 177 | auto main_layout = new QVBoxLayout; |
diff --git a/src/yuzu/debugger/graphics/graphics_surface.h b/src/yuzu/debugger/graphics/graphics_surface.h index 6a344bdfc..323e39d94 100644 --- a/src/yuzu/debugger/graphics/graphics_surface.h +++ b/src/yuzu/debugger/graphics/graphics_surface.h | |||
| @@ -22,11 +22,11 @@ class SurfacePicture : public QLabel { | |||
| 22 | public: | 22 | public: |
| 23 | explicit SurfacePicture(QWidget* parent = nullptr, | 23 | explicit SurfacePicture(QWidget* parent = nullptr, |
| 24 | GraphicsSurfaceWidget* surface_widget = nullptr); | 24 | GraphicsSurfaceWidget* surface_widget = nullptr); |
| 25 | ~SurfacePicture(); | 25 | ~SurfacePicture() override; |
| 26 | 26 | ||
| 27 | protected slots: | 27 | protected slots: |
| 28 | virtual void mouseMoveEvent(QMouseEvent* event); | 28 | void mouseMoveEvent(QMouseEvent* event) override; |
| 29 | virtual void mousePressEvent(QMouseEvent* event); | 29 | void mousePressEvent(QMouseEvent* event) override; |
| 30 | 30 | ||
| 31 | private: | 31 | private: |
| 32 | GraphicsSurfaceWidget* surface_widget; | 32 | GraphicsSurfaceWidget* surface_widget; |
| @@ -65,16 +65,15 @@ public slots: | |||
| 65 | void OnSurfacePickerYChanged(int new_value); | 65 | void OnSurfacePickerYChanged(int new_value); |
| 66 | void OnUpdate(); | 66 | void OnUpdate(); |
| 67 | 67 | ||
| 68 | private slots: | 68 | signals: |
| 69 | void Update(); | ||
| 70 | |||
| 71 | private: | ||
| 69 | void OnBreakPointHit(Tegra::DebugContext::Event event, void* data) override; | 72 | void OnBreakPointHit(Tegra::DebugContext::Event event, void* data) override; |
| 70 | void OnResumed() override; | 73 | void OnResumed() override; |
| 71 | 74 | ||
| 72 | void SaveSurface(); | 75 | void SaveSurface(); |
| 73 | 76 | ||
| 74 | signals: | ||
| 75 | void Update(); | ||
| 76 | |||
| 77 | private: | ||
| 78 | QComboBox* surface_source_list; | 77 | QComboBox* surface_source_list; |
| 79 | CSpinBox* surface_address_control; | 78 | CSpinBox* surface_address_control; |
| 80 | QSpinBox* surface_width_control; | 79 | QSpinBox* surface_width_control; |
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index f5a5697a0..d0926d723 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | #include "core/hle/kernel/timer.h" | 14 | #include "core/hle/kernel/timer.h" |
| 15 | #include "core/hle/kernel/wait_object.h" | 15 | #include "core/hle/kernel/wait_object.h" |
| 16 | 16 | ||
| 17 | WaitTreeItem::~WaitTreeItem() {} | 17 | WaitTreeItem::~WaitTreeItem() = default; |
| 18 | 18 | ||
| 19 | QColor WaitTreeItem::GetColor() const { | 19 | QColor WaitTreeItem::GetColor() const { |
| 20 | return QColor(Qt::GlobalColor::black); | 20 | return QColor(Qt::GlobalColor::black); |
| @@ -316,7 +316,7 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeEvent::GetChildren() const { | |||
| 316 | 316 | ||
| 317 | list.push_back(std::make_unique<WaitTreeText>( | 317 | list.push_back(std::make_unique<WaitTreeText>( |
| 318 | tr("reset type = %1") | 318 | tr("reset type = %1") |
| 319 | .arg(GetResetTypeQString(static_cast<const Kernel::Event&>(object).reset_type)))); | 319 | .arg(GetResetTypeQString(static_cast<const Kernel::Event&>(object).GetResetType())))); |
| 320 | return list; | 320 | return list; |
| 321 | } | 321 | } |
| 322 | 322 | ||
diff --git a/src/yuzu/debugger/wait_tree.h b/src/yuzu/debugger/wait_tree.h index 10fc9e968..513b3c45d 100644 --- a/src/yuzu/debugger/wait_tree.h +++ b/src/yuzu/debugger/wait_tree.h | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | #include <QTreeView> | 9 | #include <QTreeView> |
| 10 | #include <boost/container/flat_set.hpp> | 10 | #include <boost/container/flat_set.hpp> |
| 11 | #include "core/core.h" | 11 | #include "core/core.h" |
| 12 | #include "core/hle/kernel/kernel.h" | 12 | #include "core/hle/kernel/object.h" |
| 13 | 13 | ||
| 14 | class EmuThread; | 14 | class EmuThread; |
| 15 | 15 | ||
| @@ -25,11 +25,13 @@ class WaitTreeThread; | |||
| 25 | class WaitTreeItem : public QObject { | 25 | class WaitTreeItem : public QObject { |
| 26 | Q_OBJECT | 26 | Q_OBJECT |
| 27 | public: | 27 | public: |
| 28 | ~WaitTreeItem() override; | ||
| 29 | |||
| 28 | virtual bool IsExpandable() const; | 30 | virtual bool IsExpandable() const; |
| 29 | virtual std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const; | 31 | virtual std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const; |
| 30 | virtual QString GetText() const = 0; | 32 | virtual QString GetText() const = 0; |
| 31 | virtual QColor GetColor() const; | 33 | virtual QColor GetColor() const; |
| 32 | virtual ~WaitTreeItem(); | 34 | |
| 33 | void Expand(); | 35 | void Expand(); |
| 34 | WaitTreeItem* Parent() const; | 36 | WaitTreeItem* Parent() const; |
| 35 | const std::vector<std::unique_ptr<WaitTreeItem>>& Children() const; | 37 | const std::vector<std::unique_ptr<WaitTreeItem>>& Children() const; |
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index 99e6634a1..24f38a3c7 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp | |||
| @@ -162,15 +162,15 @@ void GameList::onTextChanged(const QString& newText) { | |||
| 162 | } | 162 | } |
| 163 | search_field->setFilterResult(rowCount, rowCount); | 163 | search_field->setFilterResult(rowCount, rowCount); |
| 164 | } else { | 164 | } else { |
| 165 | QStandardItem* child_file; | ||
| 166 | QString file_path, file_name, file_title, file_programmid; | ||
| 167 | int result_count = 0; | 165 | int result_count = 0; |
| 168 | for (int i = 0; i < rowCount; ++i) { | 166 | for (int i = 0; i < rowCount; ++i) { |
| 169 | child_file = item_model->item(i, 0); | 167 | const QStandardItem* child_file = item_model->item(i, 0); |
| 170 | file_path = child_file->data(GameListItemPath::FullPathRole).toString().toLower(); | 168 | const QString file_path = |
| 171 | file_name = file_path.mid(file_path.lastIndexOf("/") + 1); | 169 | child_file->data(GameListItemPath::FullPathRole).toString().toLower(); |
| 172 | file_title = child_file->data(GameListItemPath::TitleRole).toString().toLower(); | 170 | QString file_name = file_path.mid(file_path.lastIndexOf('/') + 1); |
| 173 | file_programmid = | 171 | const QString file_title = |
| 172 | child_file->data(GameListItemPath::TitleRole).toString().toLower(); | ||
| 173 | const QString file_programmid = | ||
| 174 | child_file->data(GameListItemPath::ProgramIdRole).toString().toLower(); | 174 | child_file->data(GameListItemPath::ProgramIdRole).toString().toLower(); |
| 175 | 175 | ||
| 176 | // Only items which filename in combination with its title contains all words | 176 | // Only items which filename in combination with its title contains all words |
| @@ -258,18 +258,20 @@ void GameList::AddEntry(const QList<QStandardItem*>& entry_items) { | |||
| 258 | 258 | ||
| 259 | void GameList::ValidateEntry(const QModelIndex& item) { | 259 | void GameList::ValidateEntry(const QModelIndex& item) { |
| 260 | // We don't care about the individual QStandardItem that was selected, but its row. | 260 | // We don't care about the individual QStandardItem that was selected, but its row. |
| 261 | int row = item_model->itemFromIndex(item)->row(); | 261 | const int row = item_model->itemFromIndex(item)->row(); |
| 262 | QStandardItem* child_file = item_model->invisibleRootItem()->child(row, COLUMN_NAME); | 262 | const QStandardItem* child_file = item_model->invisibleRootItem()->child(row, COLUMN_NAME); |
| 263 | QString file_path = child_file->data(GameListItemPath::FullPathRole).toString(); | 263 | const QString file_path = child_file->data(GameListItemPath::FullPathRole).toString(); |
| 264 | 264 | ||
| 265 | if (file_path.isEmpty()) | 265 | if (file_path.isEmpty()) |
| 266 | return; | 266 | return; |
| 267 | std::string std_file_path(file_path.toStdString()); | 267 | |
| 268 | if (!FileUtil::Exists(std_file_path)) | 268 | if (!QFileInfo::exists(file_path)) |
| 269 | return; | 269 | return; |
| 270 | if (FileUtil::IsDirectory(std_file_path)) { | 270 | |
| 271 | QDir dir(std_file_path.c_str()); | 271 | const QFileInfo file_info{file_path}; |
| 272 | QStringList matching_main = dir.entryList(QStringList("main"), QDir::Files); | 272 | if (file_info.isDir()) { |
| 273 | const QDir dir{file_path}; | ||
| 274 | const QStringList matching_main = dir.entryList(QStringList("main"), QDir::Files); | ||
| 273 | if (matching_main.size() == 1) { | 275 | if (matching_main.size() == 1) { |
| 274 | emit GameChosen(dir.path() + DIR_SEP + matching_main[0]); | 276 | emit GameChosen(dir.path() + DIR_SEP + matching_main[0]); |
| 275 | } | 277 | } |
| @@ -365,24 +367,26 @@ void GameList::LoadInterfaceLayout() { | |||
| 365 | item_model->sort(header->sortIndicatorSection(), header->sortIndicatorOrder()); | 367 | item_model->sort(header->sortIndicatorSection(), header->sortIndicatorOrder()); |
| 366 | } | 368 | } |
| 367 | 369 | ||
| 368 | const QStringList GameList::supported_file_extensions = {"nso", "nro", "nca"}; | 370 | const QStringList GameList::supported_file_extensions = {"nso", "nro", "nca", "xci"}; |
| 369 | 371 | ||
| 370 | static bool HasSupportedFileExtension(const std::string& file_name) { | 372 | static bool HasSupportedFileExtension(const std::string& file_name) { |
| 371 | QFileInfo file = QFileInfo(file_name.c_str()); | 373 | const QFileInfo file = QFileInfo(QString::fromStdString(file_name)); |
| 372 | return GameList::supported_file_extensions.contains(file.suffix(), Qt::CaseInsensitive); | 374 | return GameList::supported_file_extensions.contains(file.suffix(), Qt::CaseInsensitive); |
| 373 | } | 375 | } |
| 374 | 376 | ||
| 375 | static bool IsExtractedNCAMain(const std::string& file_name) { | 377 | static bool IsExtractedNCAMain(const std::string& file_name) { |
| 376 | return QFileInfo(file_name.c_str()).fileName() == "main"; | 378 | return QFileInfo(QString::fromStdString(file_name)).fileName() == "main"; |
| 377 | } | 379 | } |
| 378 | 380 | ||
| 379 | static QString FormatGameName(const std::string& physical_name) { | 381 | static QString FormatGameName(const std::string& physical_name) { |
| 380 | QFileInfo file_info(physical_name.c_str()); | 382 | const QString physical_name_as_qstring = QString::fromStdString(physical_name); |
| 383 | const QFileInfo file_info(physical_name_as_qstring); | ||
| 384 | |||
| 381 | if (IsExtractedNCAMain(physical_name)) { | 385 | if (IsExtractedNCAMain(physical_name)) { |
| 382 | return file_info.dir().path(); | 386 | return file_info.dir().path(); |
| 383 | } else { | ||
| 384 | return QString::fromStdString(physical_name); | ||
| 385 | } | 387 | } |
| 388 | |||
| 389 | return physical_name_as_qstring; | ||
| 386 | } | 390 | } |
| 387 | 391 | ||
| 388 | void GameList::RefreshGameDirectory() { | 392 | void GameList::RefreshGameDirectory() { |
diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h index a758b77aa..aa69a098f 100644 --- a/src/yuzu/game_list_p.h +++ b/src/yuzu/game_list_p.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <atomic> | 7 | #include <atomic> |
| 8 | #include <utility> | ||
| 8 | #include <QImage> | 9 | #include <QImage> |
| 9 | #include <QRunnable> | 10 | #include <QRunnable> |
| 10 | #include <QStandardItem> | 11 | #include <QStandardItem> |
| @@ -27,9 +28,8 @@ static QPixmap GetDefaultIcon(bool large) { | |||
| 27 | class GameListItem : public QStandardItem { | 28 | class GameListItem : public QStandardItem { |
| 28 | 29 | ||
| 29 | public: | 30 | public: |
| 30 | GameListItem() : QStandardItem() {} | 31 | GameListItem() = default; |
| 31 | GameListItem(const QString& string) : QStandardItem(string) {} | 32 | explicit GameListItem(const QString& string) : QStandardItem(string) {} |
| 32 | virtual ~GameListItem() override {} | ||
| 33 | }; | 33 | }; |
| 34 | 34 | ||
| 35 | /** | 35 | /** |
| @@ -45,9 +45,8 @@ public: | |||
| 45 | static const int TitleRole = Qt::UserRole + 2; | 45 | static const int TitleRole = Qt::UserRole + 2; |
| 46 | static const int ProgramIdRole = Qt::UserRole + 3; | 46 | static const int ProgramIdRole = Qt::UserRole + 3; |
| 47 | 47 | ||
| 48 | GameListItemPath() : GameListItem() {} | 48 | GameListItemPath() = default; |
| 49 | GameListItemPath(const QString& game_path, const std::vector<u8>& smdh_data, u64 program_id) | 49 | GameListItemPath(const QString& game_path, const std::vector<u8>& smdh_data, u64 program_id) { |
| 50 | : GameListItem() { | ||
| 51 | setData(game_path, FullPathRole); | 50 | setData(game_path, FullPathRole); |
| 52 | setData(qulonglong(program_id), ProgramIdRole); | 51 | setData(qulonglong(program_id), ProgramIdRole); |
| 53 | } | 52 | } |
| @@ -75,8 +74,8 @@ class GameListItemSize : public GameListItem { | |||
| 75 | public: | 74 | public: |
| 76 | static const int SizeRole = Qt::UserRole + 1; | 75 | static const int SizeRole = Qt::UserRole + 1; |
| 77 | 76 | ||
| 78 | GameListItemSize() : GameListItem() {} | 77 | GameListItemSize() = default; |
| 79 | GameListItemSize(const qulonglong size_bytes) : GameListItem() { | 78 | explicit GameListItemSize(const qulonglong size_bytes) { |
| 80 | setData(size_bytes, SizeRole); | 79 | setData(size_bytes, SizeRole); |
| 81 | } | 80 | } |
| 82 | 81 | ||
| @@ -111,7 +110,7 @@ class GameListWorker : public QObject, public QRunnable { | |||
| 111 | 110 | ||
| 112 | public: | 111 | public: |
| 113 | GameListWorker(QString dir_path, bool deep_scan) | 112 | GameListWorker(QString dir_path, bool deep_scan) |
| 114 | : QObject(), QRunnable(), dir_path(dir_path), deep_scan(deep_scan) {} | 113 | : dir_path(std::move(dir_path)), deep_scan(deep_scan) {} |
| 115 | 114 | ||
| 116 | public slots: | 115 | public slots: |
| 117 | /// Starts the processing of directory tree information. | 116 | /// Starts the processing of directory tree information. |
diff --git a/src/yuzu/hotkeys.cpp b/src/yuzu/hotkeys.cpp index 61acb38ee..dce399774 100644 --- a/src/yuzu/hotkeys.cpp +++ b/src/yuzu/hotkeys.cpp | |||
| @@ -10,58 +10,53 @@ | |||
| 10 | #include "yuzu/hotkeys.h" | 10 | #include "yuzu/hotkeys.h" |
| 11 | #include "yuzu/ui_settings.h" | 11 | #include "yuzu/ui_settings.h" |
| 12 | 12 | ||
| 13 | struct Hotkey { | 13 | HotkeyRegistry::HotkeyRegistry() = default; |
| 14 | Hotkey() : shortcut(nullptr), context(Qt::WindowShortcut) {} | 14 | HotkeyRegistry::~HotkeyRegistry() = default; |
| 15 | 15 | ||
| 16 | QKeySequence keyseq; | 16 | void HotkeyRegistry::LoadHotkeys() { |
| 17 | QShortcut* shortcut; | ||
| 18 | Qt::ShortcutContext context; | ||
| 19 | }; | ||
| 20 | |||
| 21 | typedef std::map<QString, Hotkey> HotkeyMap; | ||
| 22 | typedef std::map<QString, HotkeyMap> HotkeyGroupMap; | ||
| 23 | |||
| 24 | HotkeyGroupMap hotkey_groups; | ||
| 25 | |||
| 26 | void SaveHotkeys() { | ||
| 27 | UISettings::values.shortcuts.clear(); | ||
| 28 | for (auto group : hotkey_groups) { | ||
| 29 | for (auto hotkey : group.second) { | ||
| 30 | UISettings::values.shortcuts.emplace_back( | ||
| 31 | UISettings::Shortcut(group.first + "/" + hotkey.first, | ||
| 32 | UISettings::ContextualShortcut(hotkey.second.keyseq.toString(), | ||
| 33 | hotkey.second.context))); | ||
| 34 | } | ||
| 35 | } | ||
| 36 | } | ||
| 37 | |||
| 38 | void LoadHotkeys() { | ||
| 39 | // Make sure NOT to use a reference here because it would become invalid once we call | 17 | // Make sure NOT to use a reference here because it would become invalid once we call |
| 40 | // beginGroup() | 18 | // beginGroup() |
| 41 | for (auto shortcut : UISettings::values.shortcuts) { | 19 | for (auto shortcut : UISettings::values.shortcuts) { |
| 42 | QStringList cat = shortcut.first.split("/"); | 20 | const QStringList cat = shortcut.first.split('/'); |
| 43 | Q_ASSERT(cat.size() >= 2); | 21 | Q_ASSERT(cat.size() >= 2); |
| 44 | 22 | ||
| 45 | // RegisterHotkey assigns default keybindings, so use old values as default parameters | 23 | // RegisterHotkey assigns default keybindings, so use old values as default parameters |
| 46 | Hotkey& hk = hotkey_groups[cat[0]][cat[1]]; | 24 | Hotkey& hk = hotkey_groups[cat[0]][cat[1]]; |
| 47 | if (!shortcut.second.first.isEmpty()) { | 25 | if (!shortcut.second.first.isEmpty()) { |
| 48 | hk.keyseq = QKeySequence::fromString(shortcut.second.first); | 26 | hk.keyseq = QKeySequence::fromString(shortcut.second.first); |
| 49 | hk.context = (Qt::ShortcutContext)shortcut.second.second; | 27 | hk.context = static_cast<Qt::ShortcutContext>(shortcut.second.second); |
| 50 | } | 28 | } |
| 51 | if (hk.shortcut) | 29 | if (hk.shortcut) |
| 52 | hk.shortcut->setKey(hk.keyseq); | 30 | hk.shortcut->setKey(hk.keyseq); |
| 53 | } | 31 | } |
| 54 | } | 32 | } |
| 55 | 33 | ||
| 56 | void RegisterHotkey(const QString& group, const QString& action, const QKeySequence& default_keyseq, | 34 | void HotkeyRegistry::SaveHotkeys() { |
| 57 | Qt::ShortcutContext default_context) { | 35 | UISettings::values.shortcuts.clear(); |
| 58 | if (hotkey_groups[group].find(action) == hotkey_groups[group].end()) { | 36 | for (const auto& group : hotkey_groups) { |
| 59 | hotkey_groups[group][action].keyseq = default_keyseq; | 37 | for (const auto& hotkey : group.second) { |
| 60 | hotkey_groups[group][action].context = default_context; | 38 | UISettings::values.shortcuts.emplace_back( |
| 39 | UISettings::Shortcut(group.first + '/' + hotkey.first, | ||
| 40 | UISettings::ContextualShortcut(hotkey.second.keyseq.toString(), | ||
| 41 | hotkey.second.context))); | ||
| 42 | } | ||
| 61 | } | 43 | } |
| 62 | } | 44 | } |
| 63 | 45 | ||
| 64 | QShortcut* GetHotkey(const QString& group, const QString& action, QWidget* widget) { | 46 | void HotkeyRegistry::RegisterHotkey(const QString& group, const QString& action, |
| 47 | const QKeySequence& default_keyseq, | ||
| 48 | Qt::ShortcutContext default_context) { | ||
| 49 | auto& hotkey_group = hotkey_groups[group]; | ||
| 50 | if (hotkey_group.find(action) != hotkey_group.end()) { | ||
| 51 | return; | ||
| 52 | } | ||
| 53 | |||
| 54 | auto& hotkey_action = hotkey_groups[group][action]; | ||
| 55 | hotkey_action.keyseq = default_keyseq; | ||
| 56 | hotkey_action.context = default_context; | ||
| 57 | } | ||
| 58 | |||
| 59 | QShortcut* HotkeyRegistry::GetHotkey(const QString& group, const QString& action, QWidget* widget) { | ||
| 65 | Hotkey& hk = hotkey_groups[group][action]; | 60 | Hotkey& hk = hotkey_groups[group][action]; |
| 66 | 61 | ||
| 67 | if (!hk.shortcut) | 62 | if (!hk.shortcut) |
| @@ -72,10 +67,12 @@ QShortcut* GetHotkey(const QString& group, const QString& action, QWidget* widge | |||
| 72 | 67 | ||
| 73 | GHotkeysDialog::GHotkeysDialog(QWidget* parent) : QWidget(parent) { | 68 | GHotkeysDialog::GHotkeysDialog(QWidget* parent) : QWidget(parent) { |
| 74 | ui.setupUi(this); | 69 | ui.setupUi(this); |
| 70 | } | ||
| 75 | 71 | ||
| 76 | for (auto group : hotkey_groups) { | 72 | void GHotkeysDialog::Populate(const HotkeyRegistry& registry) { |
| 73 | for (const auto& group : registry.hotkey_groups) { | ||
| 77 | QTreeWidgetItem* toplevel_item = new QTreeWidgetItem(QStringList(group.first)); | 74 | QTreeWidgetItem* toplevel_item = new QTreeWidgetItem(QStringList(group.first)); |
| 78 | for (auto hotkey : group.second) { | 75 | for (const auto& hotkey : group.second) { |
| 79 | QStringList columns; | 76 | QStringList columns; |
| 80 | columns << hotkey.first << hotkey.second.keyseq.toString(); | 77 | columns << hotkey.first << hotkey.second.keyseq.toString(); |
| 81 | QTreeWidgetItem* item = new QTreeWidgetItem(columns); | 78 | QTreeWidgetItem* item = new QTreeWidgetItem(columns); |
diff --git a/src/yuzu/hotkeys.h b/src/yuzu/hotkeys.h index a4ccc193b..f38e6c002 100644 --- a/src/yuzu/hotkeys.h +++ b/src/yuzu/hotkeys.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <map> | ||
| 7 | #include "ui_hotkeys.h" | 8 | #include "ui_hotkeys.h" |
| 8 | 9 | ||
| 9 | class QDialog; | 10 | class QDialog; |
| @@ -11,47 +12,69 @@ class QKeySequence; | |||
| 11 | class QSettings; | 12 | class QSettings; |
| 12 | class QShortcut; | 13 | class QShortcut; |
| 13 | 14 | ||
| 14 | /** | 15 | class HotkeyRegistry final { |
| 15 | * Register a hotkey. | 16 | public: |
| 16 | * | 17 | friend class GHotkeysDialog; |
| 17 | * @param group General group this hotkey belongs to (e.g. "Main Window", "Debugger") | 18 | |
| 18 | * @param action Name of the action (e.g. "Start Emulation", "Load Image") | 19 | explicit HotkeyRegistry(); |
| 19 | * @param default_keyseq Default key sequence to assign if the hotkey wasn't present in the settings | 20 | ~HotkeyRegistry(); |
| 20 | * file before | 21 | |
| 21 | * @param default_context Default context to assign if the hotkey wasn't present in the settings | 22 | /** |
| 22 | * file before | 23 | * Loads hotkeys from the settings file. |
| 23 | * @warning Both the group and action strings will be displayed in the hotkey settings dialog | 24 | * |
| 24 | */ | 25 | * @note Yet unregistered hotkeys which are present in the settings will automatically be |
| 25 | void RegisterHotkey(const QString& group, const QString& action, | 26 | * registered. |
| 26 | const QKeySequence& default_keyseq = QKeySequence(), | 27 | */ |
| 27 | Qt::ShortcutContext default_context = Qt::WindowShortcut); | 28 | void LoadHotkeys(); |
| 28 | 29 | ||
| 29 | /** | 30 | /** |
| 30 | * Returns a QShortcut object whose activated() signal can be connected to other QObjects' slots. | 31 | * Saves all registered hotkeys to the settings file. |
| 31 | * | 32 | * |
| 32 | * @param group General group this hotkey belongs to (e.g. "Main Window", "Debugger"). | 33 | * @note Each hotkey group will be stored a settings group; For each hotkey inside that group, a |
| 33 | * @param action Name of the action (e.g. "Start Emulation", "Load Image"). | 34 | * settings group will be created to store the key sequence and the hotkey context. |
| 34 | * @param widget Parent widget of the returned QShortcut. | 35 | */ |
| 35 | * @warning If multiple QWidgets' call this function for the same action, the returned QShortcut | 36 | void SaveHotkeys(); |
| 36 | * will be the same. Thus, you shouldn't rely on the caller really being the QShortcut's parent. | 37 | |
| 37 | */ | 38 | /** |
| 38 | QShortcut* GetHotkey(const QString& group, const QString& action, QWidget* widget); | 39 | * Returns a QShortcut object whose activated() signal can be connected to other QObjects' |
| 39 | 40 | * slots. | |
| 40 | /** | 41 | * |
| 41 | * Saves all registered hotkeys to the settings file. | 42 | * @param group General group this hotkey belongs to (e.g. "Main Window", "Debugger"). |
| 42 | * | 43 | * @param action Name of the action (e.g. "Start Emulation", "Load Image"). |
| 43 | * @note Each hotkey group will be stored a settings group; For each hotkey inside that group, a | 44 | * @param widget Parent widget of the returned QShortcut. |
| 44 | * settings group will be created to store the key sequence and the hotkey context. | 45 | * @warning If multiple QWidgets' call this function for the same action, the returned QShortcut |
| 45 | */ | 46 | * will be the same. Thus, you shouldn't rely on the caller really being the |
| 46 | void SaveHotkeys(); | 47 | * QShortcut's parent. |
| 47 | 48 | */ | |
| 48 | /** | 49 | QShortcut* GetHotkey(const QString& group, const QString& action, QWidget* widget); |
| 49 | * Loads hotkeys from the settings file. | 50 | |
| 50 | * | 51 | /** |
| 51 | * @note Yet unregistered hotkeys which are present in the settings will automatically be | 52 | * Register a hotkey. |
| 52 | * registered. | 53 | * |
| 53 | */ | 54 | * @param group General group this hotkey belongs to (e.g. "Main Window", "Debugger") |
| 54 | void LoadHotkeys(); | 55 | * @param action Name of the action (e.g. "Start Emulation", "Load Image") |
| 56 | * @param default_keyseq Default key sequence to assign if the hotkey wasn't present in the | ||
| 57 | * settings file before | ||
| 58 | * @param default_context Default context to assign if the hotkey wasn't present in the settings | ||
| 59 | * file before | ||
| 60 | * @warning Both the group and action strings will be displayed in the hotkey settings dialog | ||
| 61 | */ | ||
| 62 | void RegisterHotkey(const QString& group, const QString& action, | ||
| 63 | const QKeySequence& default_keyseq = {}, | ||
| 64 | Qt::ShortcutContext default_context = Qt::WindowShortcut); | ||
| 65 | |||
| 66 | private: | ||
| 67 | struct Hotkey { | ||
| 68 | QKeySequence keyseq; | ||
| 69 | QShortcut* shortcut = nullptr; | ||
| 70 | Qt::ShortcutContext context = Qt::WindowShortcut; | ||
| 71 | }; | ||
| 72 | |||
| 73 | using HotkeyMap = std::map<QString, Hotkey>; | ||
| 74 | using HotkeyGroupMap = std::map<QString, HotkeyMap>; | ||
| 75 | |||
| 76 | HotkeyGroupMap hotkey_groups; | ||
| 77 | }; | ||
| 55 | 78 | ||
| 56 | class GHotkeysDialog : public QWidget { | 79 | class GHotkeysDialog : public QWidget { |
| 57 | Q_OBJECT | 80 | Q_OBJECT |
| @@ -59,6 +82,8 @@ class GHotkeysDialog : public QWidget { | |||
| 59 | public: | 82 | public: |
| 60 | explicit GHotkeysDialog(QWidget* parent = nullptr); | 83 | explicit GHotkeysDialog(QWidget* parent = nullptr); |
| 61 | 84 | ||
| 85 | void Populate(const HotkeyRegistry& registry); | ||
| 86 | |||
| 62 | private: | 87 | private: |
| 63 | Ui::hotkeys ui; | 88 | Ui::hotkeys ui; |
| 64 | }; | 89 | }; |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 97273f967..17ed62c72 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include "common/scope_exit.h" | 23 | #include "common/scope_exit.h" |
| 24 | #include "common/string_util.h" | 24 | #include "common/string_util.h" |
| 25 | #include "core/core.h" | 25 | #include "core/core.h" |
| 26 | #include "core/crypto/key_manager.h" | ||
| 26 | #include "core/gdbstub/gdbstub.h" | 27 | #include "core/gdbstub/gdbstub.h" |
| 27 | #include "core/loader/loader.h" | 28 | #include "core/loader/loader.h" |
| 28 | #include "core/settings.h" | 29 | #include "core/settings.h" |
| @@ -80,6 +81,8 @@ static void ShowCalloutMessage(const QString& message, CalloutFlag flag) { | |||
| 80 | 81 | ||
| 81 | void GMainWindow::ShowCallouts() {} | 82 | void GMainWindow::ShowCallouts() {} |
| 82 | 83 | ||
| 84 | const int GMainWindow::max_recent_files_item; | ||
| 85 | |||
| 83 | GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) { | 86 | GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) { |
| 84 | 87 | ||
| 85 | debug_context = Tegra::DebugContext::Construct(); | 88 | debug_context = Tegra::DebugContext::Construct(); |
| @@ -205,27 +208,46 @@ void GMainWindow::InitializeRecentFileMenuActions() { | |||
| 205 | } | 208 | } |
| 206 | 209 | ||
| 207 | void GMainWindow::InitializeHotkeys() { | 210 | void GMainWindow::InitializeHotkeys() { |
| 208 | RegisterHotkey("Main Window", "Load File", QKeySequence::Open); | 211 | hotkey_registry.RegisterHotkey("Main Window", "Load File", QKeySequence::Open); |
| 209 | RegisterHotkey("Main Window", "Start Emulation"); | 212 | hotkey_registry.RegisterHotkey("Main Window", "Start Emulation"); |
| 210 | RegisterHotkey("Main Window", "Fullscreen", QKeySequence::FullScreen); | 213 | hotkey_registry.RegisterHotkey("Main Window", "Continue/Pause", QKeySequence(Qt::Key_F4)); |
| 211 | RegisterHotkey("Main Window", "Exit Fullscreen", QKeySequence(Qt::Key_Escape), | 214 | hotkey_registry.RegisterHotkey("Main Window", "Fullscreen", QKeySequence::FullScreen); |
| 212 | Qt::ApplicationShortcut); | 215 | hotkey_registry.RegisterHotkey("Main Window", "Exit Fullscreen", QKeySequence(Qt::Key_Escape), |
| 213 | LoadHotkeys(); | 216 | Qt::ApplicationShortcut); |
| 214 | 217 | hotkey_registry.RegisterHotkey("Main Window", "Toggle Speed Limit", QKeySequence("CTRL+Z"), | |
| 215 | connect(GetHotkey("Main Window", "Load File", this), &QShortcut::activated, this, | 218 | Qt::ApplicationShortcut); |
| 216 | &GMainWindow::OnMenuLoadFile); | 219 | hotkey_registry.LoadHotkeys(); |
| 217 | connect(GetHotkey("Main Window", "Start Emulation", this), &QShortcut::activated, this, | 220 | |
| 218 | &GMainWindow::OnStartGame); | 221 | connect(hotkey_registry.GetHotkey("Main Window", "Load File", this), &QShortcut::activated, |
| 219 | connect(GetHotkey("Main Window", "Fullscreen", render_window), &QShortcut::activated, | 222 | this, &GMainWindow::OnMenuLoadFile); |
| 220 | ui.action_Fullscreen, &QAction::trigger); | 223 | connect(hotkey_registry.GetHotkey("Main Window", "Start Emulation", this), |
| 221 | connect(GetHotkey("Main Window", "Fullscreen", render_window), &QShortcut::activatedAmbiguously, | 224 | &QShortcut::activated, this, &GMainWindow::OnStartGame); |
| 222 | ui.action_Fullscreen, &QAction::trigger); | 225 | connect(hotkey_registry.GetHotkey("Main Window", "Continue/Pause", this), &QShortcut::activated, |
| 223 | connect(GetHotkey("Main Window", "Exit Fullscreen", this), &QShortcut::activated, this, [&] { | 226 | this, [&] { |
| 224 | if (emulation_running) { | 227 | if (emulation_running) { |
| 225 | ui.action_Fullscreen->setChecked(false); | 228 | if (emu_thread->IsRunning()) { |
| 226 | ToggleFullscreen(); | 229 | OnPauseGame(); |
| 227 | } | 230 | } else { |
| 228 | }); | 231 | OnStartGame(); |
| 232 | } | ||
| 233 | } | ||
| 234 | }); | ||
| 235 | connect(hotkey_registry.GetHotkey("Main Window", "Fullscreen", render_window), | ||
| 236 | &QShortcut::activated, ui.action_Fullscreen, &QAction::trigger); | ||
| 237 | connect(hotkey_registry.GetHotkey("Main Window", "Fullscreen", render_window), | ||
| 238 | &QShortcut::activatedAmbiguously, ui.action_Fullscreen, &QAction::trigger); | ||
| 239 | connect(hotkey_registry.GetHotkey("Main Window", "Exit Fullscreen", this), | ||
| 240 | &QShortcut::activated, this, [&] { | ||
| 241 | if (emulation_running) { | ||
| 242 | ui.action_Fullscreen->setChecked(false); | ||
| 243 | ToggleFullscreen(); | ||
| 244 | } | ||
| 245 | }); | ||
| 246 | connect(hotkey_registry.GetHotkey("Main Window", "Toggle Speed Limit", this), | ||
| 247 | &QShortcut::activated, this, [&] { | ||
| 248 | Settings::values.toggle_framelimit = !Settings::values.toggle_framelimit; | ||
| 249 | UpdateStatusBar(); | ||
| 250 | }); | ||
| 229 | } | 251 | } |
| 230 | 252 | ||
| 231 | void GMainWindow::SetDefaultUIGeometry() { | 253 | void GMainWindow::SetDefaultUIGeometry() { |
| @@ -304,7 +326,8 @@ void GMainWindow::ConnectMenuEvents() { | |||
| 304 | connect(ui.action_Show_Status_Bar, &QAction::triggered, statusBar(), &QStatusBar::setVisible); | 326 | connect(ui.action_Show_Status_Bar, &QAction::triggered, statusBar(), &QStatusBar::setVisible); |
| 305 | 327 | ||
| 306 | // Fullscreen | 328 | // Fullscreen |
| 307 | ui.action_Fullscreen->setShortcut(GetHotkey("Main Window", "Fullscreen", this)->key()); | 329 | ui.action_Fullscreen->setShortcut( |
| 330 | hotkey_registry.GetHotkey("Main Window", "Fullscreen", this)->key()); | ||
| 308 | connect(ui.action_Fullscreen, &QAction::triggered, this, &GMainWindow::ToggleFullscreen); | 331 | connect(ui.action_Fullscreen, &QAction::triggered, this, &GMainWindow::ToggleFullscreen); |
| 309 | 332 | ||
| 310 | // Help | 333 | // Help |
| @@ -386,7 +409,7 @@ bool GMainWindow::LoadROM(const QString& filename) { | |||
| 386 | 409 | ||
| 387 | system.SetGPUDebugContext(debug_context); | 410 | system.SetGPUDebugContext(debug_context); |
| 388 | 411 | ||
| 389 | const Core::System::ResultStatus result{system.Load(render_window, filename.toStdString())}; | 412 | const Core::System::ResultStatus result{system.Load(*render_window, filename.toStdString())}; |
| 390 | 413 | ||
| 391 | render_window->DoneCurrent(); | 414 | render_window->DoneCurrent(); |
| 392 | 415 | ||
| @@ -408,18 +431,49 @@ bool GMainWindow::LoadROM(const QString& filename) { | |||
| 408 | tr("Could not determine the system mode.")); | 431 | tr("Could not determine the system mode.")); |
| 409 | break; | 432 | break; |
| 410 | 433 | ||
| 411 | case Core::System::ResultStatus::ErrorLoader_ErrorEncrypted: { | 434 | case Core::System::ResultStatus::ErrorLoader_ErrorMissingKeys: { |
| 435 | const auto reg_found = Core::Crypto::KeyManager::KeyFileExists(false); | ||
| 436 | const auto title_found = Core::Crypto::KeyManager::KeyFileExists(true); | ||
| 437 | |||
| 438 | std::string file_text; | ||
| 439 | |||
| 440 | if (!reg_found && !title_found) { | ||
| 441 | file_text = "A proper key file (prod.keys, dev.keys, or title.keys) could not be " | ||
| 442 | "found. You will need to dump your keys from your switch to continue."; | ||
| 443 | } else if (reg_found && title_found) { | ||
| 444 | file_text = | ||
| 445 | "Both key files were found in your config directory, but the correct key could" | ||
| 446 | "not be found. You may be missing a titlekey or general key, depending on " | ||
| 447 | "the game."; | ||
| 448 | } else if (reg_found) { | ||
| 449 | file_text = | ||
| 450 | "The regular keys file (prod.keys/dev.keys) was found in your config, but the " | ||
| 451 | "titlekeys file (title.keys) was not. You are either missing the correct " | ||
| 452 | "titlekey or missing a general key required to decrypt the game."; | ||
| 453 | } else { | ||
| 454 | file_text = "The title keys file (title.keys) was found in your config, but " | ||
| 455 | "the regular keys file (prod.keys/dev.keys) was not. Unfortunately, " | ||
| 456 | "having the titlekey is not enough, you need additional general keys " | ||
| 457 | "to properly decrypt the game. You should double-check to make sure " | ||
| 458 | "your keys are correct."; | ||
| 459 | } | ||
| 460 | |||
| 412 | QMessageBox::critical( | 461 | QMessageBox::critical( |
| 413 | this, tr("Error while loading ROM!"), | 462 | this, tr("Error while loading ROM!"), |
| 414 | tr("The game that you are trying to load must be decrypted before being used with " | 463 | tr(("The game you are trying to load is encrypted and the required keys to load " |
| 415 | "yuzu. A real Switch is required.<br/><br/>" | 464 | "the game could not be found in your configuration. " + |
| 416 | "For more information on dumping and decrypting games, please see the following " | 465 | file_text + " Please refer to the yuzu wiki for help.") |
| 417 | "wiki pages: <ul>" | 466 | .c_str())); |
| 418 | "<li><a href='https://yuzu-emu.org/wiki/dumping-game-cartridges/'>Dumping Game " | 467 | break; |
| 419 | "Cartridges</a></li>" | 468 | } |
| 420 | "<li><a href='https://yuzu-emu.org/wiki/dumping-installed-titles/'>Dumping " | 469 | case Core::System::ResultStatus::ErrorLoader_ErrorDecrypting: { |
| 421 | "Installed Titles</a></li>" | 470 | QMessageBox::critical( |
| 422 | "</ul>")); | 471 | this, tr("Error while loading ROM!"), |
| 472 | tr("There was a general error while decrypting the game. This means that the keys " | ||
| 473 | "necessary were found, but were either incorrect, the game itself was not a " | ||
| 474 | "valid game or the game uses an unhandled cryptographic scheme. Please double " | ||
| 475 | "check that you have the correct " | ||
| 476 | "keys.")); | ||
| 423 | break; | 477 | break; |
| 424 | } | 478 | } |
| 425 | case Core::System::ResultStatus::ErrorLoader_ErrorInvalidFormat: | 479 | case Core::System::ResultStatus::ErrorLoader_ErrorInvalidFormat: |
| @@ -429,7 +483,7 @@ bool GMainWindow::LoadROM(const QString& filename) { | |||
| 429 | 483 | ||
| 430 | case Core::System::ResultStatus::ErrorVideoCore: | 484 | case Core::System::ResultStatus::ErrorVideoCore: |
| 431 | QMessageBox::critical( | 485 | QMessageBox::critical( |
| 432 | this, tr("An error occured in the video core."), | 486 | this, tr("An error occurred initializing the video core."), |
| 433 | tr("yuzu has encountered an error while running the video core, please see the " | 487 | tr("yuzu has encountered an error while running the video core, please see the " |
| 434 | "log for more details." | 488 | "log for more details." |
| 435 | "For more information on accessing the log, please see the following page: " | 489 | "For more information on accessing the log, please see the following page: " |
| @@ -443,7 +497,7 @@ bool GMainWindow::LoadROM(const QString& filename) { | |||
| 443 | default: | 497 | default: |
| 444 | QMessageBox::critical( | 498 | QMessageBox::critical( |
| 445 | this, tr("Error while loading ROM!"), | 499 | this, tr("Error while loading ROM!"), |
| 446 | tr("An unknown error occured. Please see the log for more details.")); | 500 | tr("An unknown error occurred. Please see the log for more details.")); |
| 447 | break; | 501 | break; |
| 448 | } | 502 | } |
| 449 | return false; | 503 | return false; |
| @@ -531,11 +585,11 @@ void GMainWindow::StoreRecentFile(const QString& filename) { | |||
| 531 | } | 585 | } |
| 532 | 586 | ||
| 533 | void GMainWindow::UpdateRecentFiles() { | 587 | void GMainWindow::UpdateRecentFiles() { |
| 534 | unsigned int num_recent_files = | 588 | const int num_recent_files = |
| 535 | std::min(UISettings::values.recent_files.size(), static_cast<int>(max_recent_files_item)); | 589 | std::min(UISettings::values.recent_files.size(), max_recent_files_item); |
| 536 | 590 | ||
| 537 | for (unsigned int i = 0; i < num_recent_files; i++) { | 591 | for (int i = 0; i < num_recent_files; i++) { |
| 538 | QString text = QString("&%1. %2").arg(i + 1).arg( | 592 | const QString text = QString("&%1. %2").arg(i + 1).arg( |
| 539 | QFileInfo(UISettings::values.recent_files[i]).fileName()); | 593 | QFileInfo(UISettings::values.recent_files[i]).fileName()); |
| 540 | actions_recent_files[i]->setText(text); | 594 | actions_recent_files[i]->setText(text); |
| 541 | actions_recent_files[i]->setData(UISettings::values.recent_files[i]); | 595 | actions_recent_files[i]->setData(UISettings::values.recent_files[i]); |
| @@ -547,12 +601,8 @@ void GMainWindow::UpdateRecentFiles() { | |||
| 547 | actions_recent_files[j]->setVisible(false); | 601 | actions_recent_files[j]->setVisible(false); |
| 548 | } | 602 | } |
| 549 | 603 | ||
| 550 | // Grey out the recent files menu if the list is empty | 604 | // Enable the recent files menu if the list isn't empty |
| 551 | if (num_recent_files == 0) { | 605 | ui.menu_recent_files->setEnabled(num_recent_files != 0); |
| 552 | ui.menu_recent_files->setEnabled(false); | ||
| 553 | } else { | ||
| 554 | ui.menu_recent_files->setEnabled(true); | ||
| 555 | } | ||
| 556 | } | 606 | } |
| 557 | 607 | ||
| 558 | void GMainWindow::OnGameListLoadFile(QString game_path) { | 608 | void GMainWindow::OnGameListLoadFile(QString game_path) { |
| @@ -583,9 +633,15 @@ void GMainWindow::OnMenuLoadFile() { | |||
| 583 | } | 633 | } |
| 584 | 634 | ||
| 585 | void GMainWindow::OnMenuLoadFolder() { | 635 | void GMainWindow::OnMenuLoadFolder() { |
| 586 | QDir dir = QFileDialog::getExistingDirectory(this, tr("Open Extracted ROM Directory")); | 636 | const QString dir_path = |
| 637 | QFileDialog::getExistingDirectory(this, tr("Open Extracted ROM Directory")); | ||
| 638 | |||
| 639 | if (dir_path.isNull()) { | ||
| 640 | return; | ||
| 641 | } | ||
| 587 | 642 | ||
| 588 | QStringList matching_main = dir.entryList(QStringList("main"), QDir::Files); | 643 | const QDir dir{dir_path}; |
| 644 | const QStringList matching_main = dir.entryList(QStringList("main"), QDir::Files); | ||
| 589 | if (matching_main.size() == 1) { | 645 | if (matching_main.size() == 1) { |
| 590 | BootGame(dir.path() + DIR_SEP + matching_main[0]); | 646 | BootGame(dir.path() + DIR_SEP + matching_main[0]); |
| 591 | } else { | 647 | } else { |
| @@ -606,9 +662,8 @@ void GMainWindow::OnMenuRecentFile() { | |||
| 606 | QAction* action = qobject_cast<QAction*>(sender()); | 662 | QAction* action = qobject_cast<QAction*>(sender()); |
| 607 | assert(action); | 663 | assert(action); |
| 608 | 664 | ||
| 609 | QString filename = action->data().toString(); | 665 | const QString filename = action->data().toString(); |
| 610 | QFileInfo file_info(filename); | 666 | if (QFileInfo::exists(filename)) { |
| 611 | if (file_info.exists()) { | ||
| 612 | BootGame(filename); | 667 | BootGame(filename); |
| 613 | } else { | 668 | } else { |
| 614 | // Display an error message and remove the file from the list. | 669 | // Display an error message and remove the file from the list. |
| @@ -706,11 +761,13 @@ void GMainWindow::ToggleWindowMode() { | |||
| 706 | } | 761 | } |
| 707 | 762 | ||
| 708 | void GMainWindow::OnConfigure() { | 763 | void GMainWindow::OnConfigure() { |
| 709 | ConfigureDialog configureDialog(this); | 764 | ConfigureDialog configureDialog(this, hotkey_registry); |
| 765 | auto old_theme = UISettings::values.theme; | ||
| 710 | auto result = configureDialog.exec(); | 766 | auto result = configureDialog.exec(); |
| 711 | if (result == QDialog::Accepted) { | 767 | if (result == QDialog::Accepted) { |
| 712 | configureDialog.applyConfiguration(); | 768 | configureDialog.applyConfiguration(); |
| 713 | UpdateUITheme(); | 769 | if (UISettings::values.theme != old_theme) |
| 770 | UpdateUITheme(); | ||
| 714 | config->Save(); | 771 | config->Save(); |
| 715 | } | 772 | } |
| 716 | } | 773 | } |
| @@ -843,7 +900,7 @@ void GMainWindow::closeEvent(QCloseEvent* event) { | |||
| 843 | UISettings::values.first_start = false; | 900 | UISettings::values.first_start = false; |
| 844 | 901 | ||
| 845 | game_list->SaveInterfaceLayout(); | 902 | game_list->SaveInterfaceLayout(); |
| 846 | SaveHotkeys(); | 903 | hotkey_registry.SaveHotkeys(); |
| 847 | 904 | ||
| 848 | // Shutdown session if the emu thread is active... | 905 | // Shutdown session if the emu thread is active... |
| 849 | if (emu_thread != nullptr) | 906 | if (emu_thread != nullptr) |
| @@ -897,15 +954,14 @@ void GMainWindow::UpdateUITheme() { | |||
| 897 | QStringList theme_paths(default_theme_paths); | 954 | QStringList theme_paths(default_theme_paths); |
| 898 | if (UISettings::values.theme != UISettings::themes[0].second && | 955 | if (UISettings::values.theme != UISettings::themes[0].second && |
| 899 | !UISettings::values.theme.isEmpty()) { | 956 | !UISettings::values.theme.isEmpty()) { |
| 900 | QString theme_uri(":" + UISettings::values.theme + "/style.qss"); | 957 | const QString theme_uri(":" + UISettings::values.theme + "/style.qss"); |
| 901 | QFile f(theme_uri); | 958 | QFile f(theme_uri); |
| 902 | if (!f.exists()) { | 959 | if (f.open(QFile::ReadOnly | QFile::Text)) { |
| 903 | LOG_ERROR(Frontend, "Unable to set style, stylesheet file not found"); | ||
| 904 | } else { | ||
| 905 | f.open(QFile::ReadOnly | QFile::Text); | ||
| 906 | QTextStream ts(&f); | 960 | QTextStream ts(&f); |
| 907 | qApp->setStyleSheet(ts.readAll()); | 961 | qApp->setStyleSheet(ts.readAll()); |
| 908 | GMainWindow::setStyleSheet(ts.readAll()); | 962 | GMainWindow::setStyleSheet(ts.readAll()); |
| 963 | } else { | ||
| 964 | LOG_ERROR(Frontend, "Unable to set style, stylesheet file not found"); | ||
| 909 | } | 965 | } |
| 910 | theme_paths.append(QStringList{":/icons/default", ":/icons/" + UISettings::values.theme}); | 966 | theme_paths.append(QStringList{":/icons/default", ":/icons/" + UISettings::values.theme}); |
| 911 | QIcon::setThemeName(":/icons/" + UISettings::values.theme); | 967 | QIcon::setThemeName(":/icons/" + UISettings::values.theme); |
| @@ -941,7 +997,6 @@ int main(int argc, char* argv[]) { | |||
| 941 | QCoreApplication::setOrganizationName("yuzu team"); | 997 | QCoreApplication::setOrganizationName("yuzu team"); |
| 942 | QCoreApplication::setApplicationName("yuzu"); | 998 | QCoreApplication::setApplicationName("yuzu"); |
| 943 | 999 | ||
| 944 | QApplication::setAttribute(Qt::AA_X11InitThreads); | ||
| 945 | QApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity); | 1000 | QApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity); |
| 946 | QApplication app(argc, argv); | 1001 | QApplication app(argc, argv); |
| 947 | 1002 | ||
diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 074bba3f9..6e335b8f8 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include <QTimer> | 9 | #include <QTimer> |
| 10 | #include "core/core.h" | 10 | #include "core/core.h" |
| 11 | #include "ui_main.h" | 11 | #include "ui_main.h" |
| 12 | #include "yuzu/hotkeys.h" | ||
| 12 | 13 | ||
| 13 | class Config; | 14 | class Config; |
| 14 | class EmuThread; | 15 | class EmuThread; |
| @@ -43,7 +44,7 @@ public: | |||
| 43 | void filterBarSetChecked(bool state); | 44 | void filterBarSetChecked(bool state); |
| 44 | void UpdateUITheme(); | 45 | void UpdateUITheme(); |
| 45 | GMainWindow(); | 46 | GMainWindow(); |
| 46 | ~GMainWindow(); | 47 | ~GMainWindow() override; |
| 47 | 48 | ||
| 48 | signals: | 49 | signals: |
| 49 | 50 | ||
| @@ -172,6 +173,8 @@ private: | |||
| 172 | // stores default icon theme search paths for the platform | 173 | // stores default icon theme search paths for the platform |
| 173 | QStringList default_theme_paths; | 174 | QStringList default_theme_paths; |
| 174 | 175 | ||
| 176 | HotkeyRegistry hotkey_registry; | ||
| 177 | |||
| 175 | protected: | 178 | protected: |
| 176 | void dropEvent(QDropEvent* event) override; | 179 | void dropEvent(QDropEvent* event) override; |
| 177 | void dragEnterEvent(QDragEnterEvent* event) override; | 180 | void dragEnterEvent(QDragEnterEvent* event) override; |
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp index cea1a5e62..9bf26717f 100644 --- a/src/yuzu_cmd/config.cpp +++ b/src/yuzu_cmd/config.cpp | |||
| @@ -105,6 +105,11 @@ void Config::ReadValues() { | |||
| 105 | Settings::values.bg_green = (float)sdl2_config->GetReal("Renderer", "bg_green", 0.0); | 105 | Settings::values.bg_green = (float)sdl2_config->GetReal("Renderer", "bg_green", 0.0); |
| 106 | Settings::values.bg_blue = (float)sdl2_config->GetReal("Renderer", "bg_blue", 0.0); | 106 | Settings::values.bg_blue = (float)sdl2_config->GetReal("Renderer", "bg_blue", 0.0); |
| 107 | 107 | ||
| 108 | // Audio | ||
| 109 | Settings::values.sink_id = sdl2_config->Get("Audio", "output_engine", "auto"); | ||
| 110 | Settings::values.audio_device_id = sdl2_config->Get("Audio", "output_device", "auto"); | ||
| 111 | Settings::values.volume = sdl2_config->GetReal("Audio", "volume", 1); | ||
| 112 | |||
| 108 | // Data Storage | 113 | // Data Storage |
| 109 | Settings::values.use_virtual_sd = | 114 | Settings::values.use_virtual_sd = |
| 110 | sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true); | 115 | sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true); |
| @@ -114,6 +119,7 @@ void Config::ReadValues() { | |||
| 114 | 119 | ||
| 115 | // Miscellaneous | 120 | // Miscellaneous |
| 116 | Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Trace"); | 121 | Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Trace"); |
| 122 | Settings::values.use_dev_keys = sdl2_config->GetBoolean("Miscellaneous", "use_dev_keys", false); | ||
| 117 | 123 | ||
| 118 | // Debugging | 124 | // Debugging |
| 119 | Settings::values.use_gdbstub = sdl2_config->GetBoolean("Debugging", "use_gdbstub", false); | 125 | Settings::values.use_gdbstub = sdl2_config->GetBoolean("Debugging", "use_gdbstub", false); |
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h index 567f23417..9a935a0d5 100644 --- a/src/yuzu_cmd/default_ini.h +++ b/src/yuzu_cmd/default_ini.h | |||
| @@ -143,19 +143,17 @@ swap_screen = | |||
| 143 | 143 | ||
| 144 | [Audio] | 144 | [Audio] |
| 145 | # Which audio output engine to use. | 145 | # Which audio output engine to use. |
| 146 | # auto (default): Auto-select, null: No audio output, sdl2: SDL2 (if available) | 146 | # auto (default): Auto-select, null: No audio output, cubeb: Cubeb audio engine (if available) |
| 147 | output_engine = | 147 | output_engine = |
| 148 | 148 | ||
| 149 | # Whether or not to enable the audio-stretching post-processing effect. | ||
| 150 | # This effect adjusts audio speed to match emulation speed and helps prevent audio stutter, | ||
| 151 | # at the cost of increasing audio latency. | ||
| 152 | # 0: No, 1 (default): Yes | ||
| 153 | enable_audio_stretching = | ||
| 154 | |||
| 155 | # Which audio device to use. | 149 | # Which audio device to use. |
| 156 | # auto (default): Auto-select | 150 | # auto (default): Auto-select |
| 157 | output_device = | 151 | output_device = |
| 158 | 152 | ||
| 153 | # Output volume. | ||
| 154 | # 1.0 (default): 100%, 0.0; mute | ||
| 155 | volume = | ||
| 156 | |||
| 159 | [Data Storage] | 157 | [Data Storage] |
| 160 | # Whether to create a virtual SD card. | 158 | # Whether to create a virtual SD card. |
| 161 | # 1 (default): Yes, 0: No | 159 | # 1 (default): Yes, 0: No |
| @@ -166,6 +164,16 @@ use_virtual_sd = | |||
| 166 | # 1: Yes, 0 (default): No | 164 | # 1: Yes, 0 (default): No |
| 167 | use_docked_mode = | 165 | use_docked_mode = |
| 168 | 166 | ||
| 167 | # Sets the account username, max length is 32 characters | ||
| 168 | # yuzu (default) | ||
| 169 | username = | ||
| 170 | |||
| 171 | # Sets the systems language index | ||
| 172 | # 0: Japanese, 1: English (default), 2: French, 3: German, 4: Italian, 5: Spanish, 6: Chinese, | ||
| 173 | # 7: Korean, 8: Dutch, 9: Portuguese, 10: Russian, 11: Taiwanese, 12: British English, 13: Canadian French, | ||
| 174 | # 14: Latin American Spanish, 15: Simplified Chinese, 16: Traditional Chinese | ||
| 175 | language_index = | ||
| 176 | |||
| 169 | # The system region that yuzu will use during emulation | 177 | # The system region that yuzu will use during emulation |
| 170 | # -1: Auto-select (default), 0: Japan, 1: USA, 2: Europe, 3: Australia, 4: China, 5: Korea, 6: Taiwan | 178 | # -1: Auto-select (default), 0: Japan, 1: USA, 2: Europe, 3: Australia, 4: China, 5: Korea, 6: Taiwan |
| 171 | region_value = | 179 | region_value = |
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index b5392c499..d637dbd0c 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include "yuzu_cmd/emu_window/emu_window_sdl2.h" | 23 | #include "yuzu_cmd/emu_window/emu_window_sdl2.h" |
| 24 | 24 | ||
| 25 | #include <getopt.h> | 25 | #include <getopt.h> |
| 26 | #include "core/crypto/key_manager.h" | ||
| 26 | #ifndef _MSC_VER | 27 | #ifndef _MSC_VER |
| 27 | #include <unistd.h> | 28 | #include <unistd.h> |
| 28 | #endif | 29 | #endif |
| @@ -71,6 +72,7 @@ static void InitializeLogging() { | |||
| 71 | /// Application entry point | 72 | /// Application entry point |
| 72 | int main(int argc, char** argv) { | 73 | int main(int argc, char** argv) { |
| 73 | Config config; | 74 | Config config; |
| 75 | |||
| 74 | int option_index = 0; | 76 | int option_index = 0; |
| 75 | bool use_gdbstub = Settings::values.use_gdbstub; | 77 | bool use_gdbstub = Settings::values.use_gdbstub; |
| 76 | u32 gdb_port = static_cast<u32>(Settings::values.gdbstub_port); | 78 | u32 gdb_port = static_cast<u32>(Settings::values.gdbstub_port); |
| @@ -162,7 +164,7 @@ int main(int argc, char** argv) { | |||
| 162 | 164 | ||
| 163 | SCOPE_EXIT({ system.Shutdown(); }); | 165 | SCOPE_EXIT({ system.Shutdown(); }); |
| 164 | 166 | ||
| 165 | const Core::System::ResultStatus load_result{system.Load(emu_window.get(), filepath)}; | 167 | const Core::System::ResultStatus load_result{system.Load(*emu_window, filepath)}; |
| 166 | 168 | ||
| 167 | switch (load_result) { | 169 | switch (load_result) { |
| 168 | case Core::System::ResultStatus::ErrorGetLoader: | 170 | case Core::System::ResultStatus::ErrorGetLoader: |
| @@ -171,11 +173,15 @@ int main(int argc, char** argv) { | |||
| 171 | case Core::System::ResultStatus::ErrorLoader: | 173 | case Core::System::ResultStatus::ErrorLoader: |
| 172 | LOG_CRITICAL(Frontend, "Failed to load ROM!"); | 174 | LOG_CRITICAL(Frontend, "Failed to load ROM!"); |
| 173 | return -1; | 175 | return -1; |
| 174 | case Core::System::ResultStatus::ErrorLoader_ErrorEncrypted: | 176 | case Core::System::ResultStatus::ErrorLoader_ErrorMissingKeys: |
| 175 | LOG_CRITICAL(Frontend, "The game that you are trying to load must be decrypted before " | 177 | LOG_CRITICAL(Frontend, "The game you are trying to load is encrypted and the keys required " |
| 176 | "being used with yuzu. \n\n For more information on dumping and " | 178 | "could not be found. Please refer to the yuzu wiki for help"); |
| 177 | "decrypting games, please refer to: " | 179 | return -1; |
| 178 | "https://yuzu-emu.org/wiki/dumping-game-cartridges/"); | 180 | case Core::System::ResultStatus::ErrorLoader_ErrorDecrypting: |
| 181 | LOG_CRITICAL(Frontend, "The game you are trying to load is encrypted and there was a " | ||
| 182 | "general error while decrypting. This could mean that the keys are " | ||
| 183 | "incorrect, game is invalid or game uses an unsupported method of " | ||
| 184 | "crypto. Please double-check your keys"); | ||
| 179 | return -1; | 185 | return -1; |
| 180 | case Core::System::ResultStatus::ErrorLoader_ErrorInvalidFormat: | 186 | case Core::System::ResultStatus::ErrorLoader_ErrorInvalidFormat: |
| 181 | LOG_CRITICAL(Frontend, "Error while loading ROM: The ROM format is not supported."); | 187 | LOG_CRITICAL(Frontend, "Error while loading ROM: The ROM format is not supported."); |
| @@ -187,7 +193,7 @@ int main(int argc, char** argv) { | |||
| 187 | LOG_CRITICAL(Frontend, "Failed to determine system mode!"); | 193 | LOG_CRITICAL(Frontend, "Failed to determine system mode!"); |
| 188 | return -1; | 194 | return -1; |
| 189 | case Core::System::ResultStatus::ErrorVideoCore: | 195 | case Core::System::ResultStatus::ErrorVideoCore: |
| 190 | LOG_CRITICAL(Frontend, "VideoCore not initialized"); | 196 | LOG_CRITICAL(Frontend, "Failed to initialize VideoCore!"); |
| 191 | return -1; | 197 | return -1; |
| 192 | case Core::System::ResultStatus::Success: | 198 | case Core::System::ResultStatus::Success: |
| 193 | break; // Expected case | 199 | break; // Expected case |