summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules6
-rw-r--r--CMakeLists.txt2
-rw-r--r--dist/qt_themes/qdarkstyle/LICENSE.md183
-rw-r--r--dist/qt_themes/qdarkstyle/style.qss607
-rw-r--r--externals/CMakeLists.txt10
m---------externals/cubeb0
m---------externals/dynarmic0
m---------externals/opus0
-rw-r--r--src/audio_core/CMakeLists.txt12
-rw-r--r--src/audio_core/audio_out.cpp17
-rw-r--r--src/audio_core/audio_out.h8
-rw-r--r--src/audio_core/buffer.h3
-rw-r--r--src/audio_core/cubeb_sink.cpp190
-rw-r--r--src/audio_core/cubeb_sink.h31
-rw-r--r--src/audio_core/null_sink.h27
-rw-r--r--src/audio_core/sink.h29
-rw-r--r--src/audio_core/sink_details.cpp44
-rw-r--r--src/audio_core/sink_details.h32
-rw-r--r--src/audio_core/sink_stream.h32
-rw-r--r--src/audio_core/stream.cpp35
-rw-r--r--src/audio_core/stream.h22
-rw-r--r--src/common/common_funcs.h4
-rw-r--r--src/common/logging/backend.cpp4
-rw-r--r--src/common/logging/log.h4
-rw-r--r--src/common/logging/text_formatter.h1
-rw-r--r--src/common/string_util.cpp8
-rw-r--r--src/common/swap.h2
-rw-r--r--src/common/timer.cpp95
-rw-r--r--src/common/timer.h17
-rw-r--r--src/core/CMakeLists.txt16
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.cpp16
-rw-r--r--src/core/core.cpp2
-rw-r--r--src/core/core.h7
-rw-r--r--src/core/file_sys/partition_filesystem.cpp5
-rw-r--r--src/core/hle/service/am/am.cpp6
-rw-r--r--src/core/hle/service/am/idle.cpp24
-rw-r--r--src/core/hle/service/am/idle.h16
-rw-r--r--src/core/hle/service/am/omm.cpp42
-rw-r--r--src/core/hle/service/am/omm.h16
-rw-r--r--src/core/hle/service/am/spsm.cpp30
-rw-r--r--src/core/hle/service/am/spsm.h16
-rw-r--r--src/core/hle/service/audio/audout_u.cpp8
-rw-r--r--src/core/hle/service/audio/audout_u.h2
-rw-r--r--src/core/hle/service/audio/hwopus.cpp135
-rw-r--r--src/core/hle/service/audio/hwopus.h1
-rw-r--r--src/core/hle/service/btm/btm.cpp121
-rw-r--r--src/core/hle/service/btm/btm.h15
-rw-r--r--src/core/hle/service/fgm/fgm.cpp75
-rw-r--r--src/core/hle/service/fgm/fgm.h15
-rw-r--r--src/core/hle/service/hid/hid.cpp18
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp14
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp9
-rw-r--r--src/core/hle/service/pcie/pcie.cpp64
-rw-r--r--src/core/hle/service/pcie/pcie.h15
-rw-r--r--src/core/hle/service/service.cpp10
-rw-r--r--src/core/hle/service/wlan/wlan.cpp172
-rw-r--r--src/core/hle/service/wlan/wlan.h15
-rw-r--r--src/video_core/macro_interpreter.cpp4
-rw-r--r--src/video_core/macro_interpreter.h4
-rw-r--r--src/yuzu/about_dialog.cpp5
-rw-r--r--src/yuzu/aboutdialog.ui4
-rw-r--r--src/yuzu/configuration/configure_debug.cpp1
-rw-r--r--src/yuzu/configuration/configure_general.cpp1
-rw-r--r--src/yuzu/configuration/configure_graphics.cpp1
-rw-r--r--src/yuzu/configuration/configure_input.cpp2
-rw-r--r--src/yuzu/main.cpp5
66 files changed, 1850 insertions, 487 deletions
diff --git a/.gitmodules b/.gitmodules
index a08850c1a..0f94613c4 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,6 @@
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 "opus"]
29 path = externals/opus
30 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
18option(YUZU_USE_BUNDLED_UNICORN "Build/Download bundled Unicorn" ON) 18option(YUZU_USE_BUNDLED_UNICORN "Build/Download bundled Unicorn" ON)
19 19
20option(ENABLE_CUBEB "Enables the cubeb audio backend" ON)
21
20if(NOT EXISTS ${CMAKE_SOURCE_DIR}/.git/hooks/pre-commit) 22if(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
5Copyright (c) 2013-2018 Colin Duquesnoy
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in
15all copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23THE SOFTWARE.
24
25## Creative Commons Attribution International 4.0 - Images
26
27QDarkStyle (c) 2013-2018 Colin Duquesnoy
28
29Creative 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
33Creative 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
41By 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
45a. __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
47b. __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
49c. __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
51d. __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
53e. __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
55f. __Licensed Material__ means the artistic or literary work, database, or other material to which the Licensor applied this Public License.
56
57g. __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
59h. __Licensor__ means the individual(s) or entity(ies) granting rights under this Public License.
60
61i. __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
63j. __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
65k. __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
69a. ___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
91b. ___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
101Your exercise of the Licensed Rights is expressly made subject to the following conditions.
102
103a. ___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
131Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material:
132
133a. 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
135b. 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
137c. 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
139For 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
143a. __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
145b. __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
147c. 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
151a. 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
153b. 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
161c. 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
163d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
164
165### Section 7 – Other Terms and Conditions
166
167a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed.
168
169b. 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
173a. 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
175b. 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
177c. 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
179d. 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/* 1QToolTip {
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 */
24QToolTip
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
33QWidget 9QWidget {
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
45QWidget:item:hover 20QWidget:item:hover {
46{
47 background-color: #18465d; 21 background-color: #18465d;
48 color: #eff0f1; 22 color: #eff0f1;
49} 23}
50 24
51QWidget:item:selected 25QWidget:item:selected {
52{
53 background-color: #18465d; 26 background-color: #18465d;
54} 27}
55 28
56QCheckBox 29QCheckBox {
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
64QCheckBox:disabled 36QCheckBox:disabled {
65{
66 color: #76797C; 37 color: #76797C;
67} 38}
68 39
69QCheckBox::indicator, 40QCheckBox::indicator,
70QGroupBox::indicator 41QGroupBox::indicator {
71{
72 width: 18px; 42 width: 18px;
73 height: 18px; 43 height: 18px;
74} 44}
75QGroupBox::indicator 45
76{ 46QGroupBox::indicator {
77 margin-left: 2px; 47 margin-left: 2px;
78} 48}
79 49
80QCheckBox::indicator:unchecked 50QCheckBox::indicator:unchecked,
81{ 51QGroupBox::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,
87QCheckBox::indicator:unchecked:pressed, 57QCheckBox::indicator:unchecked:pressed,
88QGroupBox::indicator:unchecked:hover, 58QGroupBox::indicator:unchecked:hover,
89QGroupBox::indicator:unchecked:focus, 59QGroupBox::indicator:unchecked:focus,
90QGroupBox::indicator:unchecked:pressed 60QGroupBox::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
96QCheckBox::indicator:checked 65QCheckBox::indicator:checked,
97{ 66QGroupBox::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,
103QCheckBox::indicator:checked:pressed, 72QCheckBox::indicator:checked:pressed,
104QGroupBox::indicator:checked:hover, 73QGroupBox::indicator:checked:hover,
105QGroupBox::indicator:checked:focus, 74QGroupBox::indicator:checked:focus,
106QGroupBox::indicator:checked:pressed 75QGroupBox::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 80QCheckBox::indicator:indeterminate {
113QCheckBox::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
118QCheckBox::indicator:indeterminate:focus, 84QCheckBox::indicator:indeterminate:focus,
119QCheckBox::indicator:indeterminate:hover, 85QCheckBox::indicator:indeterminate:hover,
120QCheckBox::indicator:indeterminate:pressed 86QCheckBox::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
125QCheckBox::indicator:checked:disabled, 90QCheckBox::indicator:checked:disabled,
126QGroupBox::indicator:checked:disabled 91QGroupBox::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
131QCheckBox::indicator:unchecked:disabled, 95QCheckBox::indicator:unchecked:disabled,
132QGroupBox::indicator:unchecked:disabled 96QGroupBox::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
137QRadioButton 100QRadioButton {
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
145QRadioButton:disabled 107QRadioButton:disabled {
146{
147 color: #76797C; 108 color: #76797C;
148} 109}
149QRadioButton::indicator 110
150{ 111QRadioButton::indicator {
151 width: 21px; 112 width: 21px;
152 height: 21px; 113 height: 21px;
153} 114}
154 115
155QRadioButton::indicator:unchecked 116QRadioButton::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
161QRadioButton::indicator:unchecked:hover, 120QRadioButton::indicator:unchecked:hover,
162QRadioButton::indicator:unchecked:focus, 121QRadioButton::indicator:unchecked:focus,
163QRadioButton::indicator:unchecked:pressed 122QRadioButton::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
170QRadioButton::indicator:checked 128QRadioButton::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
177QRadioButton::indicator:checked:hover, 134QRadioButton::indicator:checked:hover,
178QRadioButton::indicator:checked:focus, 135QRadioButton::indicator:checked:focus,
179QRadioButton::indicator:checked:pressed 136QRadioButton::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
186QRadioButton::indicator:checked:disabled 142QRadioButton::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
192QRadioButton::indicator:unchecked:disabled 147QRadioButton::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 151QMenuBar {
198QMenuBar
199{
200 background-color: #31363b; 152 background-color: #31363b;
201 color: #eff0f1; 153 color: #eff0f1;
202} 154}
203 155
204QMenuBar::item 156QMenuBar::item {
205{
206 background: transparent; 157 background: transparent;
207} 158}
208 159
209QMenuBar::item:selected 160QMenuBar::item:selected {
210{
211 background: transparent; 161 background: transparent;
212 border: 1px solid #76797C; 162 border: 1px solid #76797C;
213} 163}
214 164
215QMenuBar::item:pressed 165QMenuBar::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
224QMenu 173QMenu {
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
231QMenu::icon 179QMenu::icon {
232{
233 margin: 5px; 180 margin: 5px;
234} 181}
235 182
236QMenu::item 183QMenu::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
243QMenu::item:selected 189QMenu::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
262QMenu::indicator:non-exclusive:unchecked { 209QMenu::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
279QMenu::indicator:exclusive:unchecked { 228QMenu::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 249QWidget:disabled {
301QWidget:disabled
302{
303 color: #454545; 250 color: #454545;
304 background-color: #31363b; 251 background-color: #31363b;
305} 252}
306 253
307QAbstractItemView 254QAbstractItemView {
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
315QWidget:focus, QMenuBar:focus 261QWidget:focus,
316{ 262QMenuBar:focus {
317 border: 1px solid #3daee9; 263 border: 1px solid #3daee9;
318} 264}
319 265
320QTabWidget:focus, QCheckBox:focus, QRadioButton:focus, QSlider:focus 266QTabWidget:focus,
321{ 267QCheckBox:focus,
268QRadioButton:focus,
269QSlider:focus {
322 border: none; 270 border: none;
323} 271}
324 272
325QLineEdit 273QLineEdit {
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
335QAbstractItemView QLineEdit 282QAbstractItemView QLineEdit {
336{
337 padding: 0; 283 padding: 0;
338} 284}
339 285
340QGroupBox { 286QGroupBox {
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
354QAbstractScrollArea 300QAbstractScrollArea {
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
361QScrollBar:horizontal 306QScrollBar: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
370QScrollBar::handle:horizontal 314QScrollBar::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
377QScrollBar::add-line:horizontal 320QScrollBar::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
387QScrollBar::sub-line:horizontal 329QScrollBar::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
397QScrollBar::add-line:horizontal:hover,QScrollBar::add-line:horizontal:on 338QScrollBar::add-line:horizontal:hover,
398{ 339QScrollBar::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 347QScrollBar::sub-line:horizontal:hover,
407QScrollBar::sub-line:horizontal:hover, QScrollBar::sub-line:horizontal:on 348QScrollBar::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
416QScrollBar::up-arrow:horizontal, QScrollBar::down-arrow:horizontal 356QScrollBar::up-arrow:horizontal,
417{ 357QScrollBar::down-arrow:horizontal {
418 background: none; 358 background: none;
419} 359}
420 360
421 361QScrollBar::add-page:horizontal,
422QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal 362QScrollBar::sub-page:horizontal {
423{
424 background: none; 363 background: none;
425} 364}
426 365
427QScrollBar:vertical 366QScrollBar: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
436QScrollBar::handle:vertical 374QScrollBar::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
443QScrollBar::sub-line:vertical 380QScrollBar::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
453QScrollBar::add-line:vertical 389QScrollBar::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
463QScrollBar::sub-line:vertical:hover,QScrollBar::sub-line:vertical:on 398QScrollBar::sub-line:vertical:hover,
464{ 399QScrollBar::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 407QScrollBar::add-line:vertical:hover,
474QScrollBar::add-line:vertical:hover, QScrollBar::add-line:vertical:on 408QScrollBar::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
483QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical 416QScrollBar::up-arrow:vertical,
484{ 417QScrollBar::down-arrow:vertical {
485 background: none; 418 background: none;
486} 419}
487 420
488 421QScrollBar::add-page:vertical,
489QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical 422QScrollBar::sub-page:vertical {
490{
491 background: none; 423 background: none;
492} 424}
493 425
494QTextEdit 426QTextEdit {
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
501QPlainTextEdit 432QPlainTextEdit {
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
509QHeaderView::section 440QHeaderView::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 453QMainWindow::separator {
524QMainWindow::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
533QMainWindow::separator:hover 461QMainWindow::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 469QMenu::separator {
544QMenu::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 478QFrame {
555QFrame
556{
557 border-radius: 2px; 479 border-radius: 2px;
558 border: 1px solid #76797C; 480 border: 1px solid #76797C;
559} 481}
560 482
561QFrame[frameShape="0"] 483QFrame[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
567QStackedWidget 488QStackedWidget {
568{
569 border: 1px transparent black; 489 border: 1px transparent black;
570} 490}
571 491
@@ -578,21 +498,24 @@ QToolBar {
578QToolBar::handle:horizontal { 498QToolBar::handle:horizontal {
579 image: url(:/qss_icons/rc/Hmovetoolbar.png); 499 image: url(:/qss_icons/rc/Hmovetoolbar.png);
580} 500}
501
581QToolBar::handle:vertical { 502QToolBar::handle:vertical {
582 image: url(:/qss_icons/rc/Vmovetoolbar.png); 503 image: url(:/qss_icons/rc/Vmovetoolbar.png);
583} 504}
505
584QToolBar::separator:horizontal { 506QToolBar::separator:horizontal {
585 image: url(:/qss_icons/rc/Hsepartoolbar.png); 507 image: url(:/qss_icons/rc/Hsepartoolbar.png);
586} 508}
509
587QToolBar::separator:vertical { 510QToolBar::separator:vertical {
588 image: url(:/qss_icons/rc/Vsepartoolbar.png); 511 image: url(:/qss_icons/rc/Vsepartoolbar.png);
589} 512}
513
590QToolButton#qt_toolbar_ext_button { 514QToolButton#qt_toolbar_ext_button {
591 background: #58595a 515 background: #58595a
592} 516}
593 517
594QPushButton 518QPushButton {
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
606QPushButton:disabled 529QPushButton: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
625QPushButton:pressed 547QPushButton: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
632QComboBox 553QComboBox {
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
642QPushButton:checked{ 562QPushButton:checked {
643 background-color: #76797C; 563 background-color: #76797C;
644 border-color: #6A6969; 564 border-color: #6A6969;
645} 565}
646 566
647QComboBox:hover,QPushButton:hover,QAbstractSpinBox:hover,QLineEdit:hover,QTextEdit:hover,QPlainTextEdit:hover,QAbstractView:hover,QTreeView:hover 567QComboBox:hover,
648{ 568QPushButton:hover,
569QAbstractSpinBox:hover,
570QLineEdit:hover,
571QTextEdit:hover,
572QPlainTextEdit:hover,
573QAbstractView:hover,
574QTreeView:hover {
649 border: 1px solid #3daee9; 575 border: 1px solid #3daee9;
650 color: #eff0f1; 576 color: #eff0f1;
651} 577}
652 578
653QComboBox:on 579QComboBox: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
660QComboBox QAbstractItemView 585QComboBox 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
668QComboBox::drop-down 592QComboBox::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
681QComboBox::down-arrow 603QComboBox::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
686QComboBox::down-arrow:on, QComboBox::down-arrow:hover, 607QComboBox::down-arrow:on,
687QComboBox::down-arrow:focus 608QComboBox::down-arrow:hover,
688{ 609QComboBox::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
701QAbstractSpinBox:up-button 622QAbstractSpinBox: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
708QAbstractSpinBox:down-button 628QAbstractSpinBox: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
715QAbstractSpinBox::up-arrow,QAbstractSpinBox::up-arrow:disabled,QAbstractSpinBox::up-arrow:off { 634QAbstractSpinBox::up-arrow,
635QAbstractSpinBox::up-arrow:disabled,
636QAbstractSpinBox::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}
720QAbstractSpinBox::up-arrow:hover 641
721{ 642QAbstractSpinBox::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 646QAbstractSpinBox::down-arrow,
726QAbstractSpinBox::down-arrow,QAbstractSpinBox::down-arrow:disabled,QAbstractSpinBox::down-arrow:off 647QAbstractSpinBox::down-arrow:disabled,
727{ 648QAbstractSpinBox::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}
732QAbstractSpinBox::down-arrow:hover 653
733{ 654QAbstractSpinBox::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 658QLabel {
738QLabel
739{
740 border: 0px solid black; 659 border: 0px solid black;
741} 660}
742 661
743QTabWidget{ 662QTabWidget {
744 border: 0px transparent black; 663 border: 0px transparent black;
745} 664}
746 665
@@ -751,27 +670,24 @@ QTabWidget::pane {
751} 670}
752 671
753QTabWidget::tab-bar { 672QTabWidget::tab-bar {
754 left: 5px; /* move to the right by 5px */ 673 /* left: 5px; move to the right by 5px */
755} 674}
756 675
757QTabBar 676QTabBar {
758{
759 qproperty-drawBase: 0; 677 qproperty-drawBase: 0;
760 border-radius: 3px; 678 border-radius: 3px;
761} 679}
762 680
763QTabBar:focus 681QTabBar:focus {
764{
765 border: 0px transparent black; 682 border: 0px transparent black;
766} 683}
767 684
768QTabBar::close-button { 685QTabBar::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
773QTabBar::close-button:hover 690QTabBar::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
785QTabBar::tab:top { 703QTabBar::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
796QTabBar::tab:top:!selected 714QTabBar::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
811QTabBar::tab:bottom { 730QTabBar::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
822QTabBar::tab:bottom:!selected 741QTabBar::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
837QTabBar::tab:left { 757QTabBar::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
848QTabBar::tab:left:!selected 768QTabBar::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
864QTabBar::tab:right { 784QTabBar::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
875QTabBar::tab:right:!selected 795QTabBar::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
889QTabBar QToolButton::right-arrow:enabled { 808QTabBar 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 { 812QTabBar 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
897QTabBar QToolButton::right-arrow:disabled { 816QTabBar 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
820QTabBar QToolButton::left-arrow:disabled {
821 image: url(:/qss_icons/rc/left_arrow_disabled.png);
822}
905 823
906QDockWidget { 824QDockWidget {
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
913QDockWidget::close-button, QDockWidget::float-button { 831QDockWidget::close-button,
832QDockWidget::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
919QDockWidget::close-button:hover, QDockWidget::float-button:hover { 838QDockWidget::close-button:hover,
839QDockWidget::float-button:hover {
920 background: rgba(255, 255, 255, 10); 840 background: rgba(255, 255, 255, 10);
921} 841}
922 842
923QDockWidget::close-button:pressed, QDockWidget::float-button:pressed { 843QDockWidget::close-button:pressed,
844QDockWidget::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
928QTreeView, QListView 849QTreeView,
929{ 850QListView {
930 border: 1px solid #76797C; 851 border: 1px solid #76797C;
931 background-color: #232629; 852 background-color: #232629;
932} 853}
933 854
934QTreeView:branch:selected, QTreeView:branch:hover 855QTreeView:branch:selected,
935{ 856QTreeView: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
956QTreeView::branch:open:has-children:!has-siblings, 877QTreeView::branch:open:has-children:!has-siblings,
957QTreeView::branch:open:has-children:has-siblings { 878QTreeView::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
961QTreeView::branch:has-children:!has-siblings:closed:hover, 882QTreeView::branch:has-children:!has-siblings:closed:hover,
962QTreeView::branch:closed:has-children:has-siblings:hover { 883QTreeView::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
966QTreeView::branch:open:has-children:!has-siblings:hover, 887QTreeView::branch:open:has-children:!has-siblings:hover,
967QTreeView::branch:open:has-children:has-siblings:hover { 888QTreeView::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
971QListView::item:!selected:hover, QTreeView::item:!selected:hover { 892QListView::item:!selected:hover,
893QTreeView::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
977QListView::item:selected:hover, QTreeView::item:selected:hover { 899QListView::item:selected:hover,
900QTreeView::item:selected:hover {
978 background: #287399; 901 background: #287399;
979 color: #eff0f1; 902 color: #eff0f1;
980} 903}
981 904
905QTreeView::indicator:checked,
906QListView::indicator:checked {
907 image: url(:/qss_icons/rc/checkbox_checked.png);
908}
909
910QTreeView::indicator:unchecked,
911QListView::indicator:unchecked {
912 image: url(:/qss_icons/rc/checkbox_unchecked.png);
913}
914
915QTreeView::indicator:indeterminate,
916QListView::indicator:indeterminate {
917 image: url(:/qss_icons/rc/checkbox_indeterminate.png);
918}
919
920QTreeView::indicator:checked:hover,
921QTreeView::indicator:checked:focus,
922QTreeView::indicator:checked:pressed,
923QListView::indicator:checked:hover,
924QListView::indicator:checked:focus,
925QListView::indicator:checked:pressed {
926 image: url(:/qss_icons/rc/checkbox_checked_focus.png);
927}
928
929QTreeView::indicator:unchecked:hover,
930QTreeView::indicator:unchecked:focus,
931QTreeView::indicator:unchecked:pressed,
932QListView::indicator:unchecked:hover,
933QListView::indicator:unchecked:focus,
934QListView::indicator:unchecked:pressed {
935 image: url(:/qss_icons/rc/checkbox_unchecked_focus.png);
936}
937
938QTreeView::indicator:indeterminate:hover,
939QTreeView::indicator:indeterminate:focus,
940QTreeView::indicator:indeterminate:pressed,
941QListView::indicator:indeterminate:hover,
942QListView::indicator:indeterminate:focus,
943QListView::indicator:indeterminate:pressed {
944 image: url(:/qss_icons/rc/checkbox_indeterminate_focus.png);
945}
946
982QSlider::groove:horizontal { 947QSlider::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
1024QToolButton[popupMode="1"] { /* only for MenuButtonPopup */ 989QToolButton[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
1030QToolButton[popupMode="2"] { /* only for InstantPopup */ 997QToolButton[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 1004QToolButton:hover,
1036QToolButton:hover, QToolButton::menu-button:hover { 1005QToolButton::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
1042QToolButton:checked, QToolButton:pressed, 1011QToolButton:checked,
1043 QToolButton::menu-button:pressed { 1012QToolButton:pressed,
1013QToolButton::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
1050QToolButton::menu-indicator { 1022QToolButton::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
1056QToolButton::menu-button { 1032QToolButton::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
1073QPushButton::menu-indicator { 1049QPushButton::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
1079QTableView 1055QTableView {
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 1061QTableView,
1087QTableView, QHeaderView 1062QHeaderView {
1088{
1089 border-radius: 0px; 1063 border-radius: 0px;
1090} 1064}
1091 1065
1092QTableView::item:pressed, QListView::item:pressed, QTreeView::item:pressed { 1066QTableView::item:pressed,
1067QListView::item:pressed,
1068QTreeView::item:pressed {
1093 background: #18465d; 1069 background: #18465d;
1094 color: #eff0f1; 1070 color: #eff0f1;
1095} 1071}
1096 1072
1097QTableView::item:selected:active, QTreeView::item:selected:active, QListView::item:selected:active { 1073QTableView::item:selected:active,
1074QTreeView::item:selected:active,
1075QListView::item:selected:active {
1098 background: #287399; 1076 background: #287399;
1099 color: #eff0f1; 1077 color: #eff0f1;
1100} 1078}
1101 1079
1102 1080QHeaderView {
1103QHeaderView
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
1113QHeaderView::section { 1088QHeaderView::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
1122QHeaderView::section::vertical::first, QHeaderView::section::vertical::only-one 1097QHeaderView::section::vertical::first,
1123{ 1098QHeaderView::section::vertical::only-one {
1124 border-top: 1px solid #76797C; 1099 border-top: 1px solid #76797C;
1125} 1100}
1126 1101
1127QHeaderView::section::vertical 1102QHeaderView::section::vertical {
1128{
1129 border-top: transparent; 1103 border-top: transparent;
1130} 1104}
1131 1105
1132QHeaderView::section::horizontal::first, QHeaderView::section::horizontal::only-one 1106QHeaderView::section::horizontal::first,
1133{ 1107QHeaderView::section::horizontal::only-one {
1134 border-left: 1px solid #76797C; 1108 border-left: 1px solid #76797C;
1135} 1109}
1136 1110
1137QHeaderView::section::horizontal 1111QHeaderView::section::horizontal {
1138{
1139 border-left: transparent; 1112 border-left: transparent;
1140} 1113}
1141 1114
1142 1115QHeaderView::section:checked {
1143QHeaderView::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 */
1150QHeaderView::down-arrow { 1123QHeaderView::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
1159QTableCornerButton::section { 1131QTableCornerButton::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
1165QToolBox { 1137QToolBox {
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
1179QToolBox::tab:selected { /* italicize selected tabs */ 1151QToolBox::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
1185QStatusBar::item { 1158QStatusBar::item {
1186 border: 0px transparent dark; 1159 border: 0px transparent dark;
1187 } 1160}
1188
1189 1161
1190QFrame[height="3"], QFrame[width="3"] { 1162QFrame[height="3"],
1163QFrame[width="3"] {
1191 background-color: #76797C; 1164 background-color: #76797C;
1192} 1165}
1193 1166
1194
1195QSplitter::handle { 1167QSplitter::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
1222QDateEdit 1194QDateEdit {
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
1232QDateEdit:on 1203QDateEdit: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
1239QDateEdit QAbstractItemView 1209QDateEdit 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
1247QDateEdit::drop-down 1216QDateEdit::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
1259QDateEdit::down-arrow 1227QDateEdit::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
1264QDateEdit::down-arrow:on, QDateEdit::down-arrow:hover, 1231QDateEdit::down-arrow:on,
1265QDateEdit::down-arrow:focus 1232QDateEdit::down-arrow:hover,
1266{ 1233QDateEdit::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..4636761e5 100644
--- a/externals/CMakeLists.txt
+++ b/externals/CMakeLists.txt
@@ -50,3 +50,13 @@ if (ARCHITECTURE_x86_64)
50 target_include_directories(xbyak INTERFACE ./xbyak/xbyak) 50 target_include_directories(xbyak INTERFACE ./xbyak/xbyak)
51 target_compile_definitions(xbyak INTERFACE XBYAK_NO_OP_NAMES) 51 target_compile_definitions(xbyak INTERFACE XBYAK_NO_OP_NAMES)
52endif() 52endif()
53
54# Opus
55add_subdirectory(opus)
56target_include_directories(opus INTERFACE ./opus/include)
57
58# Cubeb
59if(ENABLE_CUBEB)
60 set(BUILD_TESTS OFF CACHE BOOL "")
61 add_subdirectory(cubeb)
62endif()
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 73d3efc3e03887fb89c6a7b655d2f79d0e0711a
diff --git a/externals/opus b/externals/opus
new file mode 160000
Subproject b2871922a12abb49579512d604cabc471a59ad9
diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt
index f00a55994..81121167d 100644
--- a/src/audio_core/CMakeLists.txt
+++ b/src/audio_core/CMakeLists.txt
@@ -2,10 +2,22 @@ add_library(audio_core STATIC
2 audio_out.cpp 2 audio_out.cpp
3 audio_out.h 3 audio_out.h
4 buffer.h 4 buffer.h
5 cubeb_sink.cpp
6 cubeb_sink.h
7 null_sink.h
5 stream.cpp 8 stream.cpp
6 stream.h 9 stream.h
10 sink.h
11 sink_details.cpp
12 sink_details.h
13 sink_stream.h
7) 14)
8 15
9create_target_directory_groups(audio_core) 16create_target_directory_groups(audio_core)
10 17
11target_link_libraries(audio_core PUBLIC common core) 18target_link_libraries(audio_core PUBLIC common core)
19
20if(ENABLE_CUBEB)
21 target_link_libraries(audio_core PRIVATE cubeb)
22 target_compile_definitions(audio_core PRIVATE -DHAVE_CUBEB=1)
23endif()
diff --git a/src/audio_core/audio_out.cpp b/src/audio_core/audio_out.cpp
index 6d418a05b..77cedb6ba 100644
--- a/src/audio_core/audio_out.cpp
+++ b/src/audio_core/audio_out.cpp
@@ -3,13 +3,15 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "audio_core/audio_out.h" 5#include "audio_core/audio_out.h"
6#include "audio_core/sink.h"
7#include "audio_core/sink_details.h"
6#include "common/assert.h" 8#include "common/assert.h"
7#include "common/logging/log.h" 9#include "common/logging/log.h"
8 10
9namespace AudioCore { 11namespace AudioCore {
10 12
11/// Returns the stream format from the specified number of channels 13/// Returns the stream format from the specified number of channels
12static Stream::Format ChannelsToStreamFormat(int num_channels) { 14static Stream::Format ChannelsToStreamFormat(u32 num_channels) {
13 switch (num_channels) { 15 switch (num_channels) {
14 case 1: 16 case 1:
15 return Stream::Format::Mono16; 17 return Stream::Format::Mono16;
@@ -24,11 +26,16 @@ static Stream::Format ChannelsToStreamFormat(int num_channels) {
24 return {}; 26 return {};
25} 27}
26 28
27StreamPtr AudioOut::OpenStream(int sample_rate, int num_channels, 29StreamPtr AudioOut::OpenStream(u32 sample_rate, u32 num_channels,
28 Stream::ReleaseCallback&& release_callback) { 30 Stream::ReleaseCallback&& release_callback) {
29 streams.push_back(std::make_shared<Stream>(sample_rate, ChannelsToStreamFormat(num_channels), 31 if (!sink) {
30 std::move(release_callback))); 32 const SinkDetails& sink_details = GetSinkDetails("auto");
31 return streams.back(); 33 sink = sink_details.factory("");
34 }
35
36 return std::make_shared<Stream>(sample_rate, ChannelsToStreamFormat(num_channels),
37 std::move(release_callback),
38 sink->AcquireSinkStream(sample_rate, num_channels));
32} 39}
33 40
34std::vector<u64> AudioOut::GetTagsAndReleaseBuffers(StreamPtr stream, size_t max_count) { 41std::vector<u64> AudioOut::GetTagsAndReleaseBuffers(StreamPtr stream, size_t max_count) {
diff --git a/src/audio_core/audio_out.h b/src/audio_core/audio_out.h
index a86499d10..8d9b695d4 100644
--- a/src/audio_core/audio_out.h
+++ b/src/audio_core/audio_out.h
@@ -8,20 +8,19 @@
8#include <vector> 8#include <vector>
9 9
10#include "audio_core/buffer.h" 10#include "audio_core/buffer.h"
11#include "audio_core/sink.h"
11#include "audio_core/stream.h" 12#include "audio_core/stream.h"
12#include "common/common_types.h" 13#include "common/common_types.h"
13 14
14namespace AudioCore { 15namespace AudioCore {
15 16
16using StreamPtr = std::shared_ptr<Stream>;
17
18/** 17/**
19 * Represents an audio playback interface, used to open and play audio streams 18 * Represents an audio playback interface, used to open and play audio streams
20 */ 19 */
21class AudioOut { 20class AudioOut {
22public: 21public:
23 /// Opens a new audio stream 22 /// Opens a new audio stream
24 StreamPtr OpenStream(int sample_rate, int num_channels, 23 StreamPtr OpenStream(u32 sample_rate, u32 num_channels,
25 Stream::ReleaseCallback&& release_callback); 24 Stream::ReleaseCallback&& release_callback);
26 25
27 /// Returns a vector of recently released buffers specified by tag for the specified stream 26 /// Returns a vector of recently released buffers specified by tag for the specified stream
@@ -37,8 +36,7 @@ public:
37 bool QueueBuffer(StreamPtr stream, Buffer::Tag tag, std::vector<u8>&& data); 36 bool QueueBuffer(StreamPtr stream, Buffer::Tag tag, std::vector<u8>&& data);
38 37
39private: 38private:
40 /// Active audio streams on the interface 39 SinkPtr sink;
41 std::vector<StreamPtr> streams;
42}; 40};
43 41
44} // namespace AudioCore 42} // namespace AudioCore
diff --git a/src/audio_core/buffer.h b/src/audio_core/buffer.h
index 874ec787e..4bf5fd58a 100644
--- a/src/audio_core/buffer.h
+++ b/src/audio_core/buffer.h
@@ -4,6 +4,7 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <memory>
7#include <vector> 8#include <vector>
8 9
9#include "common/common_types.h" 10#include "common/common_types.h"
@@ -34,4 +35,6 @@ private:
34 std::vector<u8> data; 35 std::vector<u8> data;
35}; 36};
36 37
38using BufferPtr = std::shared_ptr<Buffer>;
39
37} // namespace AudioCore 40} // namespace AudioCore
diff --git a/src/audio_core/cubeb_sink.cpp b/src/audio_core/cubeb_sink.cpp
new file mode 100644
index 000000000..34ae5b062
--- /dev/null
+++ b/src/audio_core/cubeb_sink.cpp
@@ -0,0 +1,190 @@
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
12namespace AudioCore {
13
14class SinkStreamImpl final : public SinkStream {
15public:
16 SinkStreamImpl(cubeb* ctx, cubeb_devid output_device) : ctx{ctx} {
17 cubeb_stream_params params;
18 params.rate = 48000;
19 params.channels = GetNumChannels();
20 params.format = CUBEB_SAMPLE_S16NE;
21 params.layout = CUBEB_LAYOUT_STEREO;
22
23 u32 minimum_latency = 0;
24 if (cubeb_get_min_latency(ctx, &params, &minimum_latency) != CUBEB_OK) {
25 LOG_CRITICAL(Audio_Sink, "Error getting minimum latency");
26 }
27
28 if (cubeb_stream_init(ctx, &stream_backend, "yuzu Audio Output", nullptr, nullptr,
29 output_device, &params, std::max(512u, minimum_latency),
30 &SinkStreamImpl::DataCallback, &SinkStreamImpl::StateCallback,
31 this) != CUBEB_OK) {
32 LOG_CRITICAL(Audio_Sink, "Error initializing cubeb stream");
33 return;
34 }
35
36 if (cubeb_stream_start(stream_backend) != CUBEB_OK) {
37 LOG_CRITICAL(Audio_Sink, "Error starting cubeb stream");
38 return;
39 }
40 }
41
42 ~SinkStreamImpl() {
43 if (!ctx) {
44 return;
45 }
46
47 if (cubeb_stream_stop(stream_backend) != CUBEB_OK) {
48 LOG_CRITICAL(Audio_Sink, "Error stopping cubeb stream");
49 }
50
51 cubeb_stream_destroy(stream_backend);
52 }
53
54 void EnqueueSamples(u32 num_channels, const s16* samples, size_t sample_count) override {
55 if (!ctx) {
56 return;
57 }
58
59 queue.reserve(queue.size() + sample_count * GetNumChannels());
60
61 if (num_channels == 2) {
62 // Copy as-is
63 std::copy(samples, samples + sample_count * GetNumChannels(),
64 std::back_inserter(queue));
65 } else if (num_channels == 6) {
66 // Downsample 6 channels to 2
67 const size_t sample_count_copy_size = sample_count * num_channels * 2;
68 queue.reserve(sample_count_copy_size);
69 for (size_t i = 0; i < sample_count * num_channels; i += num_channels) {
70 queue.push_back(samples[i]);
71 queue.push_back(samples[i + 1]);
72 }
73 } else {
74 ASSERT_MSG(false, "Unimplemented");
75 }
76 }
77
78 u32 GetNumChannels() const {
79 // Only support 2-channel stereo output for now
80 return 2;
81 }
82
83private:
84 std::vector<std::string> device_list;
85
86 cubeb* ctx{};
87 cubeb_stream* stream_backend{};
88
89 std::vector<s16> queue;
90
91 static long DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer,
92 void* output_buffer, long num_frames);
93 static void StateCallback(cubeb_stream* stream, void* user_data, cubeb_state state);
94};
95
96CubebSink::CubebSink(std::string target_device_name) {
97 if (cubeb_init(&ctx, "yuzu", nullptr) != CUBEB_OK) {
98 LOG_CRITICAL(Audio_Sink, "cubeb_init failed");
99 return;
100 }
101
102 if (target_device_name != auto_device_name && !target_device_name.empty()) {
103 cubeb_device_collection collection;
104 if (cubeb_enumerate_devices(ctx, CUBEB_DEVICE_TYPE_OUTPUT, &collection) != CUBEB_OK) {
105 LOG_WARNING(Audio_Sink, "Audio output device enumeration not supported");
106 } else {
107 const auto collection_end{collection.device + collection.count};
108 const auto device{std::find_if(collection.device, collection_end,
109 [&](const cubeb_device_info& device) {
110 return target_device_name == device.friendly_name;
111 })};
112 if (device != collection_end) {
113 output_device = device->devid;
114 }
115 cubeb_device_collection_destroy(ctx, &collection);
116 }
117 }
118}
119
120CubebSink::~CubebSink() {
121 if (!ctx) {
122 return;
123 }
124
125 for (auto& sink_stream : sink_streams) {
126 sink_stream.reset();
127 }
128
129 cubeb_destroy(ctx);
130}
131
132SinkStream& CubebSink::AcquireSinkStream(u32 sample_rate, u32 num_channels) {
133 sink_streams.push_back(std::make_unique<SinkStreamImpl>(ctx, output_device));
134 return *sink_streams.back();
135}
136
137long SinkStreamImpl::DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer,
138 void* output_buffer, long num_frames) {
139 SinkStreamImpl* impl = static_cast<SinkStreamImpl*>(user_data);
140 u8* buffer = reinterpret_cast<u8*>(output_buffer);
141
142 if (!impl) {
143 return {};
144 }
145
146 const size_t frames_to_write{
147 std::min(impl->queue.size() / impl->GetNumChannels(), static_cast<size_t>(num_frames))};
148
149 memcpy(buffer, impl->queue.data(), frames_to_write * sizeof(s16) * impl->GetNumChannels());
150 impl->queue.erase(impl->queue.begin(),
151 impl->queue.begin() + frames_to_write * impl->GetNumChannels());
152
153 if (frames_to_write < num_frames) {
154 // Fill the rest of the frames with silence
155 memset(buffer + frames_to_write * sizeof(s16) * impl->GetNumChannels(), 0,
156 (num_frames - frames_to_write) * sizeof(s16) * impl->GetNumChannels());
157 }
158
159 return num_frames;
160}
161
162void SinkStreamImpl::StateCallback(cubeb_stream* stream, void* user_data, cubeb_state state) {}
163
164std::vector<std::string> ListCubebSinkDevices() {
165 std::vector<std::string> device_list;
166 cubeb* ctx;
167
168 if (cubeb_init(&ctx, "Citra Device Enumerator", nullptr) != CUBEB_OK) {
169 LOG_CRITICAL(Audio_Sink, "cubeb_init failed");
170 return {};
171 }
172
173 cubeb_device_collection collection;
174 if (cubeb_enumerate_devices(ctx, CUBEB_DEVICE_TYPE_OUTPUT, &collection) != CUBEB_OK) {
175 LOG_WARNING(Audio_Sink, "Audio output device enumeration not supported");
176 } else {
177 for (size_t i = 0; i < collection.count; i++) {
178 const cubeb_device_info& device = collection.device[i];
179 if (device.friendly_name) {
180 device_list.emplace_back(device.friendly_name);
181 }
182 }
183 cubeb_device_collection_destroy(ctx, &collection);
184 }
185
186 cubeb_destroy(ctx);
187 return device_list;
188}
189
190} // namespace AudioCore
diff --git a/src/audio_core/cubeb_sink.h b/src/audio_core/cubeb_sink.h
new file mode 100644
index 000000000..d07113f1f
--- /dev/null
+++ b/src/audio_core/cubeb_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 <string>
8#include <vector>
9
10#include <cubeb/cubeb.h>
11
12#include "audio_core/sink.h"
13
14namespace AudioCore {
15
16class CubebSink final : public Sink {
17public:
18 explicit CubebSink(std::string device_id);
19 ~CubebSink() override;
20
21 SinkStream& AcquireSinkStream(u32 sample_rate, u32 num_channels) override;
22
23private:
24 cubeb* ctx{};
25 cubeb_devid output_device{};
26 std::vector<SinkStreamPtr> sink_streams;
27};
28
29std::vector<std::string> ListCubebSinkDevices();
30
31} // namespace AudioCore
diff --git a/src/audio_core/null_sink.h b/src/audio_core/null_sink.h
new file mode 100644
index 000000000..2e04438f7
--- /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
9namespace AudioCore {
10
11class NullSink final : public Sink {
12public:
13 explicit NullSink(std::string){};
14 ~NullSink() override = default;
15
16 SinkStream& AcquireSinkStream(u32 /*sample_rate*/, u32 /*num_channels*/) override {
17 return null_sink_stream;
18 }
19
20private:
21 struct NullSinkStreamImpl final : SinkStream {
22 void EnqueueSamples(u32 /*num_channels*/, const s16* /*samples*/,
23 size_t /*sample_count*/) 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..d1bb98c3d
--- /dev/null
+++ b/src/audio_core/sink.h
@@ -0,0 +1,29 @@
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
9#include "audio_core/sink_stream.h"
10#include "common/common_types.h"
11
12namespace AudioCore {
13
14constexpr char auto_device_name[] = "auto";
15
16/**
17 * This class is an interface for an audio sink. An audio sink accepts samples in stereo signed
18 * PCM16 format to be output. Sinks *do not* handle resampling and expect the correct sample rate.
19 * They are dumb outputs.
20 */
21class Sink {
22public:
23 virtual ~Sink() = default;
24 virtual SinkStream& AcquireSinkStream(u32 sample_rate, u32 num_channels) = 0;
25};
26
27using SinkPtr = std::unique_ptr<Sink>;
28
29} // 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
16namespace AudioCore {
17
18// g_sink_details is ordered in terms of desirability, with the best choice at the top.
19const 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
27const 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..aa8aae1a9
--- /dev/null
+++ b/src/audio_core/sink_details.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 <functional>
8#include <memory>
9#include <vector>
10
11namespace AudioCore {
12
13class Sink;
14
15struct SinkDetails {
16 SinkDetails(const char* id_, std::function<std::unique_ptr<Sink>(std::string)> factory_,
17 std::function<std::vector<std::string>()> list_devices_)
18 : id(id_), factory(factory_), list_devices(list_devices_) {}
19
20 /// Name for this sink.
21 const char* id;
22 /// A method to call to construct an instance of this type of sink.
23 std::function<std::unique_ptr<Sink>(std::string device_id)> factory;
24 /// A method to call to list available devices.
25 std::function<std::vector<std::string>()> list_devices;
26};
27
28extern const std::vector<SinkDetails> g_sink_details;
29
30const SinkDetails& GetSinkDetails(std::string sink_id);
31
32} // namespace AudioCore
diff --git a/src/audio_core/sink_stream.h b/src/audio_core/sink_stream.h
new file mode 100644
index 000000000..e7a3f01b0
--- /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
9#include "common/common_types.h"
10
11namespace AudioCore {
12
13/**
14 * Accepts samples in stereo signed PCM16 format to be output. Sinks *do not* handle resampling and
15 * expect the correct sample rate. They are dumb outputs.
16 */
17class SinkStream {
18public:
19 virtual ~SinkStream() = default;
20
21 /**
22 * Feed stereo samples to sink.
23 * @param num_channels Number of channels used.
24 * @param samples Samples in interleaved stereo PCM16 format.
25 * @param sample_count Number of samples.
26 */
27 virtual void EnqueueSamples(u32 num_channels, const s16* samples, size_t sample_count) = 0;
28};
29
30using SinkStreamPtr = std::unique_ptr<SinkStream>;
31
32} // namespace AudioCore
diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp
index 82bff4b9e..689f51a1d 100644
--- a/src/audio_core/stream.cpp
+++ b/src/audio_core/stream.cpp
@@ -7,30 +7,37 @@
7#include "core/core_timing.h" 7#include "core/core_timing.h"
8#include "core/core_timing_util.h" 8#include "core/core_timing_util.h"
9 9
10#include "audio_core/sink.h"
11#include "audio_core/sink_details.h"
10#include "audio_core/stream.h" 12#include "audio_core/stream.h"
11 13
12namespace AudioCore { 14namespace AudioCore {
13 15
14constexpr size_t MaxAudioBufferCount{32}; 16constexpr size_t MaxAudioBufferCount{32};
15 17
16/// Returns the sample size for the specified audio stream format 18u32 Stream::GetNumChannels() const {
17static size_t SampleSizeFromFormat(Stream::Format format) {
18 switch (format) { 19 switch (format) {
19 case Stream::Format::Mono16: 20 case Format::Mono16:
21 return 1;
22 case Format::Stereo16:
20 return 2; 23 return 2;
21 case Stream::Format::Stereo16: 24 case Format::Multi51Channel16:
22 return 4; 25 return 6;
23 case Stream::Format::Multi51Channel16: 26 }
24 return 12;
25 };
26
27 LOG_CRITICAL(Audio, "Unimplemented format={}", static_cast<u32>(format)); 27 LOG_CRITICAL(Audio, "Unimplemented format={}", static_cast<u32>(format));
28 UNREACHABLE(); 28 UNREACHABLE();
29 return {}; 29 return {};
30} 30}
31 31
32Stream::Stream(int sample_rate, Format format, ReleaseCallback&& release_callback) 32u32 Stream::GetSampleSize() const {
33 : sample_rate{sample_rate}, format{format}, release_callback{std::move(release_callback)} { 33 return GetNumChannels() * 2;
34}
35
36Stream::Stream(u32 sample_rate, Format format, ReleaseCallback&& release_callback,
37 SinkStream& sink_stream)
38 : sample_rate{sample_rate}, format{format}, release_callback{std::move(release_callback)},
39 sink_stream{sink_stream} {
40
34 release_event = CoreTiming::RegisterEvent( 41 release_event = CoreTiming::RegisterEvent(
35 "Stream::Release", [this](u64 userdata, int cycles_late) { ReleaseActiveBuffer(); }); 42 "Stream::Release", [this](u64 userdata, int cycles_late) { ReleaseActiveBuffer(); });
36} 43}
@@ -45,7 +52,7 @@ void Stream::Stop() {
45} 52}
46 53
47s64 Stream::GetBufferReleaseCycles(const Buffer& buffer) const { 54s64 Stream::GetBufferReleaseCycles(const Buffer& buffer) const {
48 const size_t num_samples{buffer.GetData().size() / SampleSizeFromFormat(format)}; 55 const size_t num_samples{buffer.GetData().size() / GetSampleSize()};
49 return CoreTiming::usToCycles((static_cast<u64>(num_samples) * 1000000) / sample_rate); 56 return CoreTiming::usToCycles((static_cast<u64>(num_samples) * 1000000) / sample_rate);
50} 57}
51 58
@@ -68,6 +75,10 @@ void Stream::PlayNextBuffer() {
68 active_buffer = queued_buffers.front(); 75 active_buffer = queued_buffers.front();
69 queued_buffers.pop(); 76 queued_buffers.pop();
70 77
78 sink_stream.EnqueueSamples(GetNumChannels(),
79 reinterpret_cast<const s16*>(active_buffer->GetData().data()),
80 active_buffer->GetData().size() / GetSampleSize());
81
71 CoreTiming::ScheduleEventThreadsafe(GetBufferReleaseCycles(*active_buffer), release_event, {}); 82 CoreTiming::ScheduleEventThreadsafe(GetBufferReleaseCycles(*active_buffer), release_event, {});
72} 83}
73 84
diff --git a/src/audio_core/stream.h b/src/audio_core/stream.h
index 5f43b0798..35253920e 100644
--- a/src/audio_core/stream.h
+++ b/src/audio_core/stream.h
@@ -10,14 +10,13 @@
10#include <queue> 10#include <queue>
11 11
12#include "audio_core/buffer.h" 12#include "audio_core/buffer.h"
13#include "audio_core/sink_stream.h"
13#include "common/assert.h" 14#include "common/assert.h"
14#include "common/common_types.h" 15#include "common/common_types.h"
15#include "core/core_timing.h" 16#include "core/core_timing.h"
16 17
17namespace AudioCore { 18namespace AudioCore {
18 19
19using BufferPtr = std::shared_ptr<Buffer>;
20
21/** 20/**
22 * Represents an audio stream, which is a sequence of queued buffers, to be outputed by AudioOut 21 * Represents an audio stream, which is a sequence of queued buffers, to be outputed by AudioOut
23 */ 22 */
@@ -33,7 +32,8 @@ public:
33 /// Callback function type, used to change guest state on a buffer being released 32 /// Callback function type, used to change guest state on a buffer being released
34 using ReleaseCallback = std::function<void()>; 33 using ReleaseCallback = std::function<void()>;
35 34
36 Stream(int sample_rate, Format format, ReleaseCallback&& release_callback); 35 Stream(u32 sample_rate, Format format, ReleaseCallback&& release_callback,
36 SinkStream& sink_stream);
37 37
38 /// Plays the audio stream 38 /// Plays the audio stream
39 void Play(); 39 void Play();
@@ -60,6 +60,17 @@ public:
60 return queued_buffers.size(); 60 return queued_buffers.size();
61 } 61 }
62 62
63 /// Gets the sample rate
64 u32 GetSampleRate() const {
65 return sample_rate;
66 }
67
68 /// Gets the number of channels
69 u32 GetNumChannels() const;
70
71 /// Gets the sample size in bytes
72 u32 GetSampleSize() const;
73
63private: 74private:
64 /// Current state of the stream 75 /// Current state of the stream
65 enum class State { 76 enum class State {
@@ -76,7 +87,7 @@ private:
76 /// Gets the number of core cycles when the specified buffer will be released 87 /// Gets the number of core cycles when the specified buffer will be released
77 s64 GetBufferReleaseCycles(const Buffer& buffer) const; 88 s64 GetBufferReleaseCycles(const Buffer& buffer) const;
78 89
79 int sample_rate; ///< Sample rate of the stream 90 u32 sample_rate; ///< Sample rate of the stream
80 Format format; ///< Format of the stream 91 Format format; ///< Format of the stream
81 ReleaseCallback release_callback; ///< Buffer release callback for the stream 92 ReleaseCallback release_callback; ///< Buffer release callback for the stream
82 State state{State::Stopped}; ///< Playback state of the stream 93 State state{State::Stopped}; ///< Playback state of the stream
@@ -84,6 +95,9 @@ private:
84 BufferPtr active_buffer; ///< Actively playing buffer in the stream 95 BufferPtr active_buffer; ///< Actively playing buffer in the stream
85 std::queue<BufferPtr> queued_buffers; ///< Buffers queued to be played in the stream 96 std::queue<BufferPtr> queued_buffers; ///< Buffers queued to be played in the stream
86 std::queue<BufferPtr> released_buffers; ///< Buffers recently released from the stream 97 std::queue<BufferPtr> released_buffers; ///< Buffers recently released from the stream
98 SinkStream& sink_stream; ///< Output sink for the stream
87}; 99};
88 100
101using StreamPtr = std::shared_ptr<Stream>;
102
89} // namespace AudioCore 103} // 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/logging/backend.cpp b/src/common/logging/backend.cpp
index 38cc85e23..d86c40d26 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -169,7 +169,9 @@ void FileBackend::Write(const Entry& entry) {
169 SUB(Service, AOC) \ 169 SUB(Service, AOC) \
170 SUB(Service, APM) \ 170 SUB(Service, APM) \
171 SUB(Service, BCAT) \ 171 SUB(Service, BCAT) \
172 SUB(Service, BTM) \
172 SUB(Service, Fatal) \ 173 SUB(Service, Fatal) \
174 SUB(Service, FGM) \
173 SUB(Service, Friend) \ 175 SUB(Service, Friend) \
174 SUB(Service, FS) \ 176 SUB(Service, FS) \
175 SUB(Service, HID) \ 177 SUB(Service, HID) \
@@ -184,6 +186,7 @@ void FileBackend::Write(const Entry& entry) {
184 SUB(Service, NIFM) \ 186 SUB(Service, NIFM) \
185 SUB(Service, NS) \ 187 SUB(Service, NS) \
186 SUB(Service, NVDRV) \ 188 SUB(Service, NVDRV) \
189 SUB(Service, PCIE) \
187 SUB(Service, PCTL) \ 190 SUB(Service, PCTL) \
188 SUB(Service, PREPO) \ 191 SUB(Service, PREPO) \
189 SUB(Service, SET) \ 192 SUB(Service, SET) \
@@ -192,6 +195,7 @@ void FileBackend::Write(const Entry& entry) {
192 SUB(Service, SSL) \ 195 SUB(Service, SSL) \
193 SUB(Service, Time) \ 196 SUB(Service, Time) \
194 SUB(Service, VI) \ 197 SUB(Service, VI) \
198 SUB(Service, WLAN) \
195 CLS(HW) \ 199 CLS(HW) \
196 SUB(HW, Memory) \ 200 SUB(HW, Memory) \
197 SUB(HW, LCD) \ 201 SUB(HW, LCD) \
diff --git a/src/common/logging/log.h b/src/common/logging/log.h
index db4a80d0a..140cd8e47 100644
--- a/src/common/logging/log.h
+++ b/src/common/logging/log.h
@@ -56,7 +56,9 @@ enum class Class : ClassType {
56 Service_APM, ///< The APM (Performance) service 56 Service_APM, ///< The APM (Performance) service
57 Service_Audio, ///< The Audio (Audio control) service 57 Service_Audio, ///< The Audio (Audio control) service
58 Service_BCAT, ///< The BCAT service 58 Service_BCAT, ///< The BCAT service
59 Service_BTM, ///< The BTM service
59 Service_Fatal, ///< The Fatal service 60 Service_Fatal, ///< The Fatal service
61 Service_FGM, ///< The FGM service
60 Service_Friend, ///< The friend service 62 Service_Friend, ///< The friend service
61 Service_FS, ///< The FS (Filesystem) service 63 Service_FS, ///< The FS (Filesystem) service
62 Service_HID, ///< The HID (Human interface device) service 64 Service_HID, ///< The HID (Human interface device) service
@@ -71,6 +73,7 @@ enum class Class : ClassType {
71 Service_NIFM, ///< The NIFM (Network interface) service 73 Service_NIFM, ///< The NIFM (Network interface) service
72 Service_NS, ///< The NS services 74 Service_NS, ///< The NS services
73 Service_NVDRV, ///< The NVDRV (Nvidia driver) service 75 Service_NVDRV, ///< The NVDRV (Nvidia driver) service
76 Service_PCIE, ///< The PCIe service
74 Service_PCTL, ///< The PCTL (Parental control) service 77 Service_PCTL, ///< The PCTL (Parental control) service
75 Service_PREPO, ///< The PREPO (Play report) service 78 Service_PREPO, ///< The PREPO (Play report) service
76 Service_SET, ///< The SET (Settings) service 79 Service_SET, ///< The SET (Settings) service
@@ -79,6 +82,7 @@ enum class Class : ClassType {
79 Service_SSL, ///< The SSL service 82 Service_SSL, ///< The SSL service
80 Service_Time, ///< The time service 83 Service_Time, ///< The time service
81 Service_VI, ///< The VI (Video interface) service 84 Service_VI, ///< The VI (Video interface) service
85 Service_WLAN, ///< The WLAN (Wireless local area network) service
82 HW, ///< Low-level hardware emulation 86 HW, ///< Low-level hardware emulation
83 HW_Memory, ///< Memory-map and address translation 87 HW_Memory, ///< Memory-map and address translation
84 HW_LCD, ///< LCD register emulation 88 HW_LCD, ///< LCD register emulation
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
9namespace Log { 10namespace Log {
10 11
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
26std::string ToLower(std::string str) { 26std::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
32std::string ToUpper(std::string str) { 33std::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) {
69inline u64 swap64(u64 _data) { 69inline 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)
73inline u16 swap16(u16 _data) { 73inline 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/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
21namespace Common { 11namespace Common {
22 12
23u32 Timer::GetTimeMs() { 13std::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()
66u64 Timer::GetTimeDifference() { 51std::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()
77u64 Timer::GetTimeElapsed() { 62std::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()
91std::string Timer::GetTimeElapsedFormatted() const { 76std::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
116void Timer::IncreaseResolution() {
117#ifdef _WIN32
118 timeBeginPeriod(1);
119#endif
120}
121
122void 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
129u64 Timer::GetTimeSinceJan1970() { 101std::chrono::seconds Timer::GetTimeSinceJan1970() {
130 time_t ltime; 102 return std::chrono::duration_cast<std::chrono::seconds>(GetTimeMs());
131 time(&ltime);
132 return ((u64)ltime);
133} 103}
134 104
135u64 Timer::GetLocalTimeSinceJan1970() { 105std::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// ----------------
181double Timer::GetDoubleTime() { 143double 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
36private: 35private:
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 f1e7e2593..3e13fc25b 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -114,6 +114,12 @@ add_library(core STATIC
114 hle/service/am/applet_ae.h 114 hle/service/am/applet_ae.h
115 hle/service/am/applet_oe.cpp 115 hle/service/am/applet_oe.cpp
116 hle/service/am/applet_oe.h 116 hle/service/am/applet_oe.h
117 hle/service/am/idle.cpp
118 hle/service/am/idle.h
119 hle/service/am/omm.cpp
120 hle/service/am/omm.h
121 hle/service/am/spsm.cpp
122 hle/service/am/spsm.h
117 hle/service/aoc/aoc_u.cpp 123 hle/service/aoc/aoc_u.cpp
118 hle/service/aoc/aoc_u.h 124 hle/service/aoc/aoc_u.h
119 hle/service/apm/apm.cpp 125 hle/service/apm/apm.cpp
@@ -142,6 +148,8 @@ add_library(core STATIC
142 hle/service/bcat/module.h 148 hle/service/bcat/module.h
143 hle/service/btdrv/btdrv.cpp 149 hle/service/btdrv/btdrv.cpp
144 hle/service/btdrv/btdrv.h 150 hle/service/btdrv/btdrv.h
151 hle/service/btm/btm.cpp
152 hle/service/btm/btm.h
145 hle/service/erpt/erpt.cpp 153 hle/service/erpt/erpt.cpp
146 hle/service/erpt/erpt.h 154 hle/service/erpt/erpt.h
147 hle/service/es/es.cpp 155 hle/service/es/es.cpp
@@ -158,6 +166,8 @@ add_library(core STATIC
158 hle/service/filesystem/filesystem.h 166 hle/service/filesystem/filesystem.h
159 hle/service/filesystem/fsp_srv.cpp 167 hle/service/filesystem/fsp_srv.cpp
160 hle/service/filesystem/fsp_srv.h 168 hle/service/filesystem/fsp_srv.h
169 hle/service/fgm/fgm.cpp
170 hle/service/fgm/fgm.h
161 hle/service/friend/friend.cpp 171 hle/service/friend/friend.cpp
162 hle/service/friend/friend.h 172 hle/service/friend/friend.h
163 hle/service/friend/interface.cpp 173 hle/service/friend/interface.cpp
@@ -223,6 +233,8 @@ add_library(core STATIC
223 hle/service/nvflinger/buffer_queue.h 233 hle/service/nvflinger/buffer_queue.h
224 hle/service/nvflinger/nvflinger.cpp 234 hle/service/nvflinger/nvflinger.cpp
225 hle/service/nvflinger/nvflinger.h 235 hle/service/nvflinger/nvflinger.h
236 hle/service/pcie/pcie.cpp
237 hle/service/pcie/pcie.h
226 hle/service/pctl/module.cpp 238 hle/service/pctl/module.cpp
227 hle/service/pctl/module.h 239 hle/service/pctl/module.h
228 hle/service/pctl/pctl.cpp 240 hle/service/pctl/pctl.cpp
@@ -277,6 +289,8 @@ add_library(core STATIC
277 hle/service/vi/vi_s.h 289 hle/service/vi/vi_s.h
278 hle/service/vi/vi_u.cpp 290 hle/service/vi/vi_u.cpp
279 hle/service/vi/vi_u.h 291 hle/service/vi/vi_u.h
292 hle/service/wlan/wlan.cpp
293 hle/service/wlan/wlan.h
280 hw/hw.cpp 294 hw/hw.cpp
281 hw/hw.h 295 hw/hw.h
282 hw/lcd.cpp 296 hw/lcd.cpp
@@ -314,7 +328,7 @@ add_library(core STATIC
314create_target_directory_groups(core) 328create_target_directory_groups(core)
315 329
316target_link_libraries(core PUBLIC common PRIVATE audio_core video_core) 330target_link_libraries(core PUBLIC common PRIVATE audio_core video_core)
317target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt lz4_static unicorn) 331target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt lz4_static opus unicorn)
318 332
319if (ARCHITECTURE_x86_64) 333if (ARCHITECTURE_x86_64)
320 target_sources(core PRIVATE 334 target_sources(core PRIVATE
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp
index 57b8634b9..1d8c15d97 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic.cpp
@@ -139,14 +139,12 @@ void ARM_Dynarmic::Step() {
139} 139}
140 140
141ARM_Dynarmic::ARM_Dynarmic(std::shared_ptr<ExclusiveMonitor> exclusive_monitor, size_t core_index) 141ARM_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
152ARM_Dynarmic::~ARM_Dynarmic() = default; 150ARM_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
208void ARM_Dynarmic::SetTlsAddress(u64 address) { 206void 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
220void ARM_Dynarmic::SaveContext(ARM_Interface::ThreadContext& ctx) { 218void 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
229void ARM_Dynarmic::LoadContext(const ARM_Interface::ThreadContext& ctx) { 227void 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/core.cpp b/src/core/core.cpp
index 186fa46df..b7f4b4532 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -177,7 +177,6 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
177 } 177 }
178 178
179 gpu_core = std::make_unique<Tegra::GPU>(); 179 gpu_core = std::make_unique<Tegra::GPU>();
180 audio_core = std::make_unique<AudioCore::AudioOut>();
181 telemetry_session = std::make_unique<Core::TelemetrySession>(); 180 telemetry_session = std::make_unique<Core::TelemetrySession>();
182 service_manager = std::make_shared<Service::SM::ServiceManager>(); 181 service_manager = std::make_shared<Service::SM::ServiceManager>();
183 182
@@ -229,7 +228,6 @@ void System::Shutdown() {
229 service_manager.reset(); 228 service_manager.reset();
230 telemetry_session.reset(); 229 telemetry_session.reset();
231 gpu_core.reset(); 230 gpu_core.reset();
232 audio_core.reset();
233 231
234 // Close all CPU/threading state 232 // Close all CPU/threading state
235 cpu_barrier->NotifyEnd(); 233 cpu_barrier->NotifyEnd();
diff --git a/src/core/core.h b/src/core/core.h
index 6f4df775f..c123fe401 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -8,7 +8,6 @@
8#include <memory> 8#include <memory>
9#include <string> 9#include <string>
10#include <thread> 10#include <thread>
11#include "audio_core/audio_out.h"
12#include "common/common_types.h" 11#include "common/common_types.h"
13#include "core/arm/exclusive_monitor.h" 12#include "core/arm/exclusive_monitor.h"
14#include "core/core_cpu.h" 13#include "core/core_cpu.h"
@@ -132,11 +131,6 @@ public:
132 return *gpu_core; 131 return *gpu_core;
133 } 132 }
134 133
135 /// Gets the AudioCore interface
136 AudioCore::AudioOut& AudioCore() {
137 return *audio_core;
138 }
139
140 /// Gets the scheduler for the CPU core that is currently running 134 /// Gets the scheduler for the CPU core that is currently running
141 Kernel::Scheduler& CurrentScheduler() { 135 Kernel::Scheduler& CurrentScheduler() {
142 return *CurrentCpuCore().Scheduler(); 136 return *CurrentCpuCore().Scheduler();
@@ -201,7 +195,6 @@ private:
201 /// AppLoader used to load the current executing application 195 /// AppLoader used to load the current executing application
202 std::unique_ptr<Loader::AppLoader> app_loader; 196 std::unique_ptr<Loader::AppLoader> app_loader;
203 std::unique_ptr<Tegra::GPU> gpu_core; 197 std::unique_ptr<Tegra::GPU> gpu_core;
204 std::unique_ptr<AudioCore::AudioOut> audio_core;
205 std::shared_ptr<Tegra::DebugContext> debug_context; 198 std::shared_ptr<Tegra::DebugContext> debug_context;
206 Kernel::SharedPtr<Kernel::Process> current_process; 199 Kernel::SharedPtr<Kernel::Process> current_process;
207 std::shared_ptr<ExclusiveMonitor> cpu_exclusive_monitor; 200 std::shared_ptr<ExclusiveMonitor> cpu_exclusive_monitor;
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/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 97ef07bf9..94d2a973d 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"
@@ -689,6 +692,9 @@ void InstallInterfaces(SM::ServiceManager& service_manager,
689 std::shared_ptr<NVFlinger::NVFlinger> nvflinger) { 692 std::shared_ptr<NVFlinger::NVFlinger> nvflinger) {
690 std::make_shared<AppletAE>(nvflinger)->InstallAsService(service_manager); 693 std::make_shared<AppletAE>(nvflinger)->InstallAsService(service_manager);
691 std::make_shared<AppletOE>(nvflinger)->InstallAsService(service_manager); 694 std::make_shared<AppletOE>(nvflinger)->InstallAsService(service_manager);
695 std::make_shared<IdleSys>()->InstallAsService(service_manager);
696 std::make_shared<OMM>()->InstallAsService(service_manager);
697 std::make_shared<SPSM>()->InstallAsService(service_manager);
692} 698}
693 699
694IHomeMenuFunctions::IHomeMenuFunctions() : ServiceFramework("IHomeMenuFunctions") { 700IHomeMenuFunctions::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
7namespace Service::AM {
8
9IdleSys::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
9namespace Service::AM {
10
11class IdleSys final : public ServiceFramework<IdleSys> {
12public:
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
7namespace Service::AM {
8
9OMM::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
9namespace Service::AM {
10
11class OMM final : public ServiceFramework<OMM> {
12public:
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
7namespace Service::AM {
8
9SPSM::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
9namespace Service::AM {
10
11class SPSM final : public ServiceFramework<SPSM> {
12public:
13 explicit SPSM();
14};
15
16} // namespace Service::AM
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp
index a15d53ff8..ab37c2a69 100644
--- a/src/core/hle/service/audio/audout_u.cpp
+++ b/src/core/hle/service/audio/audout_u.cpp
@@ -25,9 +25,8 @@ constexpr int DefaultSampleRate{48000};
25 25
26class IAudioOut final : public ServiceFramework<IAudioOut> { 26class IAudioOut final : public ServiceFramework<IAudioOut> {
27public: 27public:
28 IAudioOut(AudoutParams audio_params) 28 IAudioOut(AudoutParams audio_params, AudioCore::AudioOut& audio_core)
29 : ServiceFramework("IAudioOut"), audio_params(audio_params), 29 : ServiceFramework("IAudioOut"), audio_params(audio_params), audio_core(audio_core) {
30 audio_core(Core::System::GetInstance().AudioCore()) {
31 30
32 static const FunctionInfo functions[] = { 31 static const FunctionInfo functions[] = {
33 {0, &IAudioOut::GetAudioOutState, "GetAudioOutState"}, 32 {0, &IAudioOut::GetAudioOutState, "GetAudioOutState"},
@@ -195,7 +194,7 @@ void AudOutU::OpenAudioOutImpl(Kernel::HLERequestContext& ctx) {
195 // TODO(bunnei): Support more than one IAudioOut interface. When we add this, ListAudioOutsImpl 194 // TODO(bunnei): Support more than one IAudioOut interface. When we add this, ListAudioOutsImpl
196 // will likely need to be updated as well. 195 // will likely need to be updated as well.
197 ASSERT_MSG(!audio_out_interface, "Unimplemented"); 196 ASSERT_MSG(!audio_out_interface, "Unimplemented");
198 audio_out_interface = std::make_shared<IAudioOut>(std::move(params)); 197 audio_out_interface = std::make_shared<IAudioOut>(std::move(params), *audio_core);
199 198
200 IPC::ResponseBuilder rb{ctx, 6, 0, 1}; 199 IPC::ResponseBuilder rb{ctx, 6, 0, 1};
201 rb.Push(RESULT_SUCCESS); 200 rb.Push(RESULT_SUCCESS);
@@ -212,6 +211,7 @@ AudOutU::AudOutU() : ServiceFramework("audout:u") {
212 {2, &AudOutU::ListAudioOutsImpl, "ListAudioOutsAuto"}, 211 {2, &AudOutU::ListAudioOutsImpl, "ListAudioOutsAuto"},
213 {3, &AudOutU::OpenAudioOutImpl, "OpenAudioOutAuto"}}; 212 {3, &AudOutU::OpenAudioOutImpl, "OpenAudioOutAuto"}};
214 RegisterHandlers(functions); 213 RegisterHandlers(functions);
214 audio_core = std::make_unique<AudioCore::AudioOut>();
215} 215}
216 216
217} // namespace Service::Audio 217} // namespace Service::Audio
diff --git a/src/core/hle/service/audio/audout_u.h b/src/core/hle/service/audio/audout_u.h
index bc43f1f44..e5c2184d5 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
9namespace Kernel { 10namespace Kernel {
@@ -33,6 +34,7 @@ public:
33 34
34private: 35private:
35 std::shared_ptr<IAudioOut> audio_out_interface; 36 std::shared_ptr<IAudioOut> audio_out_interface;
37 std::unique_ptr<AudioCore::AudioOut> audio_core;
36 38
37 void ListAudioOutsImpl(Kernel::HLERequestContext& ctx); 39 void ListAudioOutsImpl(Kernel::HLERequestContext& ctx);
38 void OpenAudioOutImpl(Kernel::HLERequestContext& ctx); 40 void OpenAudioOutImpl(Kernel::HLERequestContext& ctx);
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
10namespace Service::Audio { 12namespace Service::Audio {
11 13
14struct OpusDeleter {
15 void operator()(void* ptr) const {
16 operator delete(ptr);
17 }
18};
19
20class IHardwareOpusDecoderManager final : public ServiceFramework<IHardwareOpusDecoderManager> {
21public:
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
39private:
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
94static 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
12void HwOpus::GetWorkBufferSize(Kernel::HLERequestContext& ctx) { 99void 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
115void 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
19HwOpus::HwOpus() : ServiceFramework("hwopus") { 144HwOpus::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
16private: 16private:
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/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
14namespace Service::BTM {
15
16class BTM final : public ServiceFramework<BTM> {
17public:
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
50class BTM_DBG final : public ServiceFramework<BTM_DBG> {
51public:
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
71class IBtmSystemCore final : public ServiceFramework<IBtmSystemCore> {
72public:
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
93class BTM_SYS final : public ServiceFramework<BTM_SYS> {
94public:
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
105private:
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
115void 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
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Service::BTM {
12
13void InstallInterfaces(SM::ServiceManager& sm);
14
15} // namespace Service::BTM
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
13namespace Service::FGM {
14
15class IRequest final : public ServiceFramework<IRequest> {
16public:
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
31class FGM final : public ServiceFramework<FGM> {
32public:
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
43private:
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
53class FGM_DBG final : public ServiceFramework<FGM_DBG> {
54public:
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
68void 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
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Service::FGM {
12
13void InstallInterfaces(SM::ServiceManager& sm);
14
15} // namespace Service::FGM
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index e4619a547..ed53f96c5 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"},
@@ -343,7 +343,7 @@ public:
343 "SetNpadJoyAssignmentModeSingleByDefault"}, 343 "SetNpadJoyAssignmentModeSingleByDefault"},
344 {123, nullptr, "SetNpadJoyAssignmentModeSingleByDefault"}, 344 {123, nullptr, "SetNpadJoyAssignmentModeSingleByDefault"},
345 {124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"}, 345 {124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"},
346 {125, nullptr, "MergeSingleJoyAsDualJoy"}, 346 {125, &Hid::MergeSingleJoyAsDualJoy, "MergeSingleJoyAsDualJoy"},
347 {126, nullptr, "StartLrAssignmentMode"}, 347 {126, nullptr, "StartLrAssignmentMode"},
348 {127, nullptr, "StopLrAssignmentMode"}, 348 {127, nullptr, "StopLrAssignmentMode"},
349 {128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"}, 349 {128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"},
@@ -455,6 +455,14 @@ private:
455 LOG_WARNING(Service_HID, "(STUBBED) called"); 455 LOG_WARNING(Service_HID, "(STUBBED) called");
456 } 456 }
457 457
458 void IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx) {
459 IPC::ResponseBuilder rb{ctx, 2};
460 rb.Push(RESULT_SUCCESS);
461 // TODO (Hexagon12): Properly implement reading gyroscope values from controllers.
462 rb.Push(true);
463 LOG_WARNING(Service_HID, "(STUBBED) called");
464 }
465
458 void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) { 466 void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) {
459 IPC::ResponseBuilder rb{ctx, 2}; 467 IPC::ResponseBuilder rb{ctx, 2};
460 rb.Push(RESULT_SUCCESS); 468 rb.Push(RESULT_SUCCESS);
@@ -530,6 +538,12 @@ private:
530 LOG_WARNING(Service_HID, "(STUBBED) called"); 538 LOG_WARNING(Service_HID, "(STUBBED) called");
531 } 539 }
532 540
541 void MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) {
542 IPC::ResponseBuilder rb{ctx, 2};
543 rb.Push(RESULT_SUCCESS);
544 LOG_WARNING(Service_HID, "(STUBBED) called");
545 }
546
533 void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) { 547 void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) {
534 IPC::ResponseBuilder rb{ctx, 2}; 548 IPC::ResponseBuilder rb{ctx, 2};
535 rb.Push(RESULT_SUCCESS); 549 rb.Push(RESULT_SUCCESS);
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..010072a5b 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
@@ -97,7 +97,9 @@ u32 nvhost_ctrl_gpu::GetTPCMasks(const std::vector<u8>& input, std::vector<u8>&
97u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::vector<u8>& output) { 97u32 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(&params, input.data(), input.size()); 100 if (input.size() > 0) {
101 std::memcpy(&params, 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(), &params, output.size()); 105 std::memcpy(output.data(), &params, output.size());
@@ -107,7 +109,9 @@ u32 nvhost_ctrl_gpu::GetActiveSlotMask(const std::vector<u8>& input, std::vector
107u32 nvhost_ctrl_gpu::ZCullGetCtxSize(const std::vector<u8>& input, std::vector<u8>& output) { 109u32 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(&params, input.data(), input.size()); 112 if (input.size() > 0) {
113 std::memcpy(&params, input.data(), input.size());
114 }
111 params.size = 0x1; 115 params.size = 0x1;
112 std::memcpy(output.data(), &params, output.size()); 116 std::memcpy(output.data(), &params, 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
116u32 nvhost_ctrl_gpu::ZCullGetInfo(const std::vector<u8>& input, std::vector<u8>& output) { 120u32 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(&params, input.data(), input.size()); 123
124 if (input.size() > 0) {
125 std::memcpy(&params, 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..5a1123ad2 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
@@ -132,9 +132,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}", 132 LOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo={:X}, num_entries={:X}, flags={:X}",
133 params.address, params.num_entries, params.flags); 133 params.address, params.num_entries, params.flags);
134 134
135 auto entries = std::vector<IoctlGpfifoEntry>(); 135 ASSERT_MSG(input.size() ==
136 entries.resize(params.num_entries); 136 sizeof(IoctlSubmitGpfifo) + params.num_entries * sizeof(IoctlGpfifoEntry),
137 std::memcpy(&entries[0], &input.data()[sizeof(IoctlSubmitGpfifo)], 137 "Incorrect input size");
138
139 std::vector<IoctlGpfifoEntry> entries(params.num_entries);
140 std::memcpy(entries.data(), &input[sizeof(IoctlSubmitGpfifo)],
138 params.num_entries * sizeof(IoctlGpfifoEntry)); 141 params.num_entries * sizeof(IoctlGpfifoEntry));
139 for (auto entry : entries) { 142 for (auto entry : entries) {
140 Tegra::GPUVAddr va_addr = entry.Address(); 143 Tegra::GPUVAddr va_addr = entry.Address();
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
11namespace Service::PCIe {
12
13class ISession final : public ServiceFramework<ISession> {
14public:
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
46class PCIe final : public ServiceFramework<PCIe> {
47public:
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
60void 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
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Service::PCIe {
12
13void InstallInterfaces(SM::ServiceManager& sm);
14
15} // namespace Service::PCIe
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 5180a0c93..fccc4c461 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -22,10 +22,12 @@
22#include "core/hle/service/audio/audio.h" 22#include "core/hle/service/audio/audio.h"
23#include "core/hle/service/bcat/bcat.h" 23#include "core/hle/service/bcat/bcat.h"
24#include "core/hle/service/btdrv/btdrv.h" 24#include "core/hle/service/btdrv/btdrv.h"
25#include "core/hle/service/btm/btm.h"
25#include "core/hle/service/erpt/erpt.h" 26#include "core/hle/service/erpt/erpt.h"
26#include "core/hle/service/es/es.h" 27#include "core/hle/service/es/es.h"
27#include "core/hle/service/eupld/eupld.h" 28#include "core/hle/service/eupld/eupld.h"
28#include "core/hle/service/fatal/fatal.h" 29#include "core/hle/service/fatal/fatal.h"
30#include "core/hle/service/fgm/fgm.h"
29#include "core/hle/service/filesystem/filesystem.h" 31#include "core/hle/service/filesystem/filesystem.h"
30#include "core/hle/service/friend/friend.h" 32#include "core/hle/service/friend/friend.h"
31#include "core/hle/service/grc/grc.h" 33#include "core/hle/service/grc/grc.h"
@@ -43,6 +45,7 @@
43#include "core/hle/service/nim/nim.h" 45#include "core/hle/service/nim/nim.h"
44#include "core/hle/service/ns/ns.h" 46#include "core/hle/service/ns/ns.h"
45#include "core/hle/service/nvdrv/nvdrv.h" 47#include "core/hle/service/nvdrv/nvdrv.h"
48#include "core/hle/service/pcie/pcie.h"
46#include "core/hle/service/pctl/pctl.h" 49#include "core/hle/service/pctl/pctl.h"
47#include "core/hle/service/pm/pm.h" 50#include "core/hle/service/pm/pm.h"
48#include "core/hle/service/prepo/prepo.h" 51#include "core/hle/service/prepo/prepo.h"
@@ -55,6 +58,7 @@
55#include "core/hle/service/ssl/ssl.h" 58#include "core/hle/service/ssl/ssl.h"
56#include "core/hle/service/time/time.h" 59#include "core/hle/service/time/time.h"
57#include "core/hle/service/vi/vi.h" 60#include "core/hle/service/vi/vi.h"
61#include "core/hle/service/wlan/wlan.h"
58 62
59using Kernel::ClientPort; 63using Kernel::ClientPort;
60using Kernel::ServerPort; 64using Kernel::ServerPort;
@@ -201,10 +205,12 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm) {
201 Audio::InstallInterfaces(*sm); 205 Audio::InstallInterfaces(*sm);
202 BCAT::InstallInterfaces(*sm); 206 BCAT::InstallInterfaces(*sm);
203 BtDrv::InstallInterfaces(*sm); 207 BtDrv::InstallInterfaces(*sm);
208 BTM::InstallInterfaces(*sm);
204 ERPT::InstallInterfaces(*sm); 209 ERPT::InstallInterfaces(*sm);
205 ES::InstallInterfaces(*sm); 210 ES::InstallInterfaces(*sm);
206 EUPLD::InstallInterfaces(*sm); 211 EUPLD::InstallInterfaces(*sm);
207 Fatal::InstallInterfaces(*sm); 212 Fatal::InstallInterfaces(*sm);
213 FGM::InstallInterfaces(*sm);
208 FileSystem::InstallInterfaces(*sm); 214 FileSystem::InstallInterfaces(*sm);
209 Friend::InstallInterfaces(*sm); 215 Friend::InstallInterfaces(*sm);
210 GRC::InstallInterfaces(*sm); 216 GRC::InstallInterfaces(*sm);
@@ -222,15 +228,17 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm) {
222 NIM::InstallInterfaces(*sm); 228 NIM::InstallInterfaces(*sm);
223 NS::InstallInterfaces(*sm); 229 NS::InstallInterfaces(*sm);
224 Nvidia::InstallInterfaces(*sm); 230 Nvidia::InstallInterfaces(*sm);
231 PCIe::InstallInterfaces(*sm);
225 PCTL::InstallInterfaces(*sm); 232 PCTL::InstallInterfaces(*sm);
226 PlayReport::InstallInterfaces(*sm); 233 PlayReport::InstallInterfaces(*sm);
227 PM::InstallInterfaces(*sm); 234 PM::InstallInterfaces(*sm);
235 Set::InstallInterfaces(*sm);
228 Sockets::InstallInterfaces(*sm); 236 Sockets::InstallInterfaces(*sm);
229 SPL::InstallInterfaces(*sm); 237 SPL::InstallInterfaces(*sm);
230 SSL::InstallInterfaces(*sm); 238 SSL::InstallInterfaces(*sm);
231 Time::InstallInterfaces(*sm); 239 Time::InstallInterfaces(*sm);
232 VI::InstallInterfaces(*sm, nv_flinger); 240 VI::InstallInterfaces(*sm, nv_flinger);
233 Set::InstallInterfaces(*sm); 241 WLAN::InstallInterfaces(*sm);
234 242
235 LOG_DEBUG(Service, "initialized OK"); 243 LOG_DEBUG(Service, "initialized OK");
236} 244}
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
11namespace Service::WLAN {
12
13class WLANInfra final : public ServiceFramework<WLANInfra> {
14public:
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
53class WLANLocal final : public ServiceFramework<WLANLocal> {
54public:
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
114class WLANLocalGetFrame final : public ServiceFramework<WLANLocalGetFrame> {
115public:
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
127class WLANSocketGetFrame final : public ServiceFramework<WLANSocketGetFrame> {
128public:
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
140class WLANSocketManager final : public ServiceFramework<WLANSocketManager> {
141public:
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
164void 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
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Service::WLAN {
12
13void InstallInterfaces(SM::ServiceManager& sm);
14
15} // namespace Service::WLAN
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/yuzu/about_dialog.cpp b/src/yuzu/about_dialog.cpp
index d6647eeea..39ed3bccf 100644
--- a/src/yuzu/about_dialog.cpp
+++ b/src/yuzu/about_dialog.cpp
@@ -10,8 +10,9 @@
10AboutDialog::AboutDialog(QWidget* parent) : QDialog(parent), ui(new Ui::AboutDialog) { 10AboutDialog::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
17AboutDialog::~AboutDialog() {} 18AboutDialog::~AboutDialog() {}
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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;%1 | %2-%3&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> 73 <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;%1 | %2-%3 (%4)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://yuzu-emu.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Website&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Source Code&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/graphs/contributors&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Contributors&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/blob/master/license.txt&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;License&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> 118 <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://yuzu-emu.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Website&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Source Code&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/graphs/contributors&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Contributors&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/blob/master/license.txt&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;License&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp
index 5e66239ff..7fd07539a 100644
--- a/src/yuzu/configuration/configure_debug.cpp
+++ b/src/yuzu/configuration/configure_debug.cpp
@@ -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_general.cpp b/src/yuzu/configuration/configure_general.cpp
index baa558667..cb7d3f8bf 100644
--- a/src/yuzu/configuration/configure_general.cpp
+++ b/src/yuzu/configuration/configure_general.cpp
@@ -44,5 +44,4 @@ void ConfigureGeneral::applyConfiguration() {
44 Settings::values.use_cpu_jit = ui->use_cpu_jit->isChecked(); 44 Settings::values.use_cpu_jit = ui->use_cpu_jit->isChecked();
45 Settings::values.use_multi_core = ui->use_multi_core->isChecked(); 45 Settings::values.use_multi_core = ui->use_multi_core->isChecked();
46 Settings::values.use_docked_mode = ui->use_docked_mode->isChecked(); 46 Settings::values.use_docked_mode = ui->use_docked_mode->isChecked();
47 Settings::Apply();
48} 47}
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp
index 7664880d5..3379b7963 100644
--- a/src/yuzu/configuration/configure_graphics.cpp
+++ b/src/yuzu/configuration/configure_graphics.cpp
@@ -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
198void ConfigureInput::loadConfiguration() { 196void ConfigureInput::loadConfiguration() {
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 96998643e..be38cfa9b 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -723,10 +723,12 @@ void GMainWindow::ToggleWindowMode() {
723 723
724void GMainWindow::OnConfigure() { 724void GMainWindow::OnConfigure() {
725 ConfigureDialog configureDialog(this); 725 ConfigureDialog configureDialog(this);
726 auto old_theme = UISettings::values.theme;
726 auto result = configureDialog.exec(); 727 auto result = configureDialog.exec();
727 if (result == QDialog::Accepted) { 728 if (result == QDialog::Accepted) {
728 configureDialog.applyConfiguration(); 729 configureDialog.applyConfiguration();
729 UpdateUITheme(); 730 if (UISettings::values.theme != old_theme)
731 UpdateUITheme();
730 config->Save(); 732 config->Save();
731 } 733 }
732} 734}
@@ -957,7 +959,6 @@ int main(int argc, char* argv[]) {
957 QCoreApplication::setOrganizationName("yuzu team"); 959 QCoreApplication::setOrganizationName("yuzu team");
958 QCoreApplication::setApplicationName("yuzu"); 960 QCoreApplication::setApplicationName("yuzu");
959 961
960 QApplication::setAttribute(Qt::AA_X11InitThreads);
961 QApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity); 962 QApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity);
962 QApplication app(argc, argv); 963 QApplication app(argc, argv);
963 964