diff options
Diffstat (limited to '')
42 files changed, 1542 insertions, 101 deletions
diff --git a/.reuse/dep5 b/.reuse/dep5 index d72233e8c..5f31a4f55 100644 --- a/.reuse/dep5 +++ b/.reuse/dep5 @@ -42,20 +42,18 @@ Files: dist/qt_themes/*/icons/16x16/connected.png dist/qt_themes/*/icons/48x48/sd_card.png dist/qt_themes/*/icons/48x48/star.png dist/qt_themes/*/icons/256x256/plus_folder.png - dist/qt_themes/colorful/icons/48x48/plus.png + dist/qt_themes/colorful/icons/48x48/list-add.png dist/qt_themes/default/icons/16x16/checked.png dist/qt_themes/default/icons/16x16/failed.png Copyright: https://icons8.com License: CC-BY-ND-3.0 -Files: dist/qt_themes/*/icons/16x16/refresh.png - dist/qt_themes/*/icons/16x16/view-refresh.png +Files: dist/qt_themes/*/icons/16x16/view-refresh.png Copyright: Google, Inc. License: Apache-2.0 -Files: dist/qt_themes/default/icons/48x48/plus.png - dist/qt_themes/qdarkstyle/icons/48x48/plus.png - dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/plus.png +Files: dist/qt_themes/default/icons/48x48/list-add.png + dist/qt_themes/qdarkstyle/icons/48x48/list-add.png Copyright: BreadFish64 License: CC0-1.0 diff --git a/dist/qt_themes/colorful/icons/48x48/plus.png b/dist/qt_themes/colorful/icons/48x48/list-add.png Binary files differindex bc2c47c91..bc2c47c91 100644 --- a/dist/qt_themes/colorful/icons/48x48/plus.png +++ b/dist/qt_themes/colorful/icons/48x48/list-add.png diff --git a/dist/qt_themes/colorful/style.qrc b/dist/qt_themes/colorful/style.qrc index 4b3f28d89..507e0e58b 100644 --- a/dist/qt_themes/colorful/style.qrc +++ b/dist/qt_themes/colorful/style.qrc @@ -13,7 +13,7 @@ SPDX-License-Identifier: GPL-2.0-or-later <file alias="48x48/bad_folder.png">icons/48x48/bad_folder.png</file> <file alias="48x48/chip.png">icons/48x48/chip.png</file> <file alias="48x48/folder.png">icons/48x48/folder.png</file> - <file alias="48x48/plus.png">icons/48x48/plus.png</file> + <file alias="48x48/list-add.png">icons/48x48/list-add.png</file> <file alias="48x48/sd_card.png">icons/48x48/sd_card.png</file> <file alias="48x48/star.png">icons/48x48/star.png</file> <file alias="256x256/plus_folder.png">icons/256x256/plus_folder.png</file> diff --git a/dist/qt_themes/colorful_dark/icons/16x16/refresh.png b/dist/qt_themes/colorful_dark/icons/16x16/refresh.png Binary files differdeleted file mode 100644 index d4afd76f9..000000000 --- a/dist/qt_themes/colorful_dark/icons/16x16/refresh.png +++ /dev/null diff --git a/dist/qt_themes/colorful_dark/icons/index.theme b/dist/qt_themes/colorful_dark/icons/index.theme index 19dc0369a..b37a06df7 100644 --- a/dist/qt_themes/colorful_dark/icons/index.theme +++ b/dist/qt_themes/colorful_dark/icons/index.theme @@ -3,6 +3,6 @@ Name=colorful_dark Comment=Colorful theme (Dark style) Inherits=colorful Directories=16x16 - + [16x16] Size=16 diff --git a/dist/qt_themes/colorful_dark/style.qrc b/dist/qt_themes/colorful_dark/style.qrc index 50e78c37b..9853fd438 100644 --- a/dist/qt_themes/colorful_dark/style.qrc +++ b/dist/qt_themes/colorful_dark/style.qrc @@ -15,7 +15,7 @@ SPDX-License-Identifier: GPL-2.0-or-later <file alias="48x48/chip.png">../colorful/icons/48x48/chip.png</file> <file alias="48x48/folder.png">../colorful/icons/48x48/folder.png</file> <file alias="48x48/no_avatar.png">../qdarkstyle/icons/48x48/no_avatar.png</file> - <file alias="48x48/plus.png">../colorful/icons/48x48/plus.png</file> + <file alias="48x48/list-add.png">../colorful/icons/48x48/list-add.png</file> <file alias="48x48/sd_card.png">../colorful/icons/48x48/sd_card.png</file> <file alias="256x256/plus_folder.png">../colorful/icons/256x256/plus_folder.png</file> </qresource> diff --git a/dist/qt_themes/colorful_midnight_blue/icons/16x16/refresh.png b/dist/qt_themes/colorful_midnight_blue/icons/16x16/refresh.png Binary files differdeleted file mode 100644 index d4afd76f9..000000000 --- a/dist/qt_themes/colorful_midnight_blue/icons/16x16/refresh.png +++ /dev/null diff --git a/dist/qt_themes/colorful_midnight_blue/style.qrc b/dist/qt_themes/colorful_midnight_blue/style.qrc index ac8cb0d49..1081d281d 100644 --- a/dist/qt_themes/colorful_midnight_blue/style.qrc +++ b/dist/qt_themes/colorful_midnight_blue/style.qrc @@ -11,7 +11,7 @@ SPDX-License-Identifier: GPL-2.0-or-later <file alias="48x48/bad_folder.png">../colorful/icons/48x48/bad_folder.png</file> <file alias="48x48/chip.png">../colorful/icons/48x48/chip.png</file> <file alias="48x48/folder.png">../colorful/icons/48x48/folder.png</file> - <file alias="48x48/plus.png">../colorful/icons/48x48/plus.png</file> + <file alias="48x48/list-add.png">../colorful/icons/48x48/list-add.png</file> <file alias="48x48/sd_card.png">../colorful/icons/48x48/sd_card.png</file> <file alias="256x256/plus_folder.png">../colorful/icons/256x256/plus_folder.png</file> </qresource> diff --git a/dist/qt_themes/default/default.qrc b/dist/qt_themes/default/default.qrc index ef080c221..a07f2a9c1 100644 --- a/dist/qt_themes/default/default.qrc +++ b/dist/qt_themes/default/default.qrc @@ -17,7 +17,7 @@ SPDX-License-Identifier: GPL-2.0-or-later <file alias="48x48/chip.png">icons/48x48/chip.png</file> <file alias="48x48/folder.png">icons/48x48/folder.png</file> <file alias="48x48/no_avatar.png">icons/48x48/no_avatar.png</file> - <file alias="48x48/plus.png">icons/48x48/plus.png</file> + <file alias="48x48/list-add.png">icons/48x48/list-add.png</file> <file alias="48x48/sd_card.png">icons/48x48/sd_card.png</file> <file alias="48x48/star.png">icons/48x48/star.png</file> <file alias="256x256/yuzu.png">icons/256x256/yuzu.png</file> diff --git a/dist/qt_themes/default/icons/16x16/refresh.png b/dist/qt_themes/default/icons/16x16/refresh.png Binary files differdeleted file mode 100644 index 69f9474ac..000000000 --- a/dist/qt_themes/default/icons/16x16/refresh.png +++ /dev/null diff --git a/dist/qt_themes/default/icons/48x48/plus.png b/dist/qt_themes/default/icons/48x48/list-add.png Binary files differindex dbc74687b..dbc74687b 100644 --- a/dist/qt_themes/default/icons/48x48/plus.png +++ b/dist/qt_themes/default/icons/48x48/list-add.png diff --git a/dist/qt_themes/default_dark/icons/index.theme b/dist/qt_themes/default_dark/icons/index.theme new file mode 100644 index 000000000..60a072d1d --- /dev/null +++ b/dist/qt_themes/default_dark/icons/index.theme @@ -0,0 +1,8 @@ +[Icon Theme] +Name=default_dark +Comment=Colorful theme (Dark style) +Inherits=colorful +Directories=16x16 + +[16x16] +Size=16 diff --git a/dist/qt_themes/default_dark/style.qrc b/dist/qt_themes/default_dark/style.qrc new file mode 100644 index 000000000..7de4737c2 --- /dev/null +++ b/dist/qt_themes/default_dark/style.qrc @@ -0,0 +1,25 @@ +<!-- +SPDX-FileCopyrightText: 2022 yuzu Emulator Project +SPDX-License-Identifier: GPL-2.0-or-later +--> +<RCC> + <qresource prefix="icons/default_dark"> + <file alias="16x16/connected.png">../colorful/icons/16x16/connected.png</file> + <file alias="16x16/connected_notification.png">../colorful/icons/16x16/connected_notification.png</file> + <file alias="16x16/disconnected.png">../colorful/icons/16x16/disconnected.png</file> + <file alias="index.theme">icons/index.theme</file> + <file alias="16x16/lock.png">../colorful_dark/icons/16x16/lock.png</file> + <file alias="16x16/view-refresh.png">../colorful_dark/icons/16x16/view-refresh.png</file> + <file alias="48x48/bad_folder.png">../colorful/icons/48x48/bad_folder.png</file> + <file alias="48x48/chip.png">../colorful/icons/48x48/chip.png</file> + <file alias="48x48/folder.png">../colorful/icons/48x48/folder.png</file> + <file alias="48x48/no_avatar.png">../qdarkstyle/icons/48x48/no_avatar.png</file> + <file alias="48x48/list-add.png">../colorful/icons/48x48/list-add.png</file> + <file alias="48x48/sd_card.png">../colorful/icons/48x48/sd_card.png</file> + <file alias="256x256/plus_folder.png">../colorful/icons/256x256/plus_folder.png</file> + </qresource> + + <qresource prefix="default_dark"> + <file>style.qss</file> + </qresource> +</RCC> diff --git a/dist/qt_themes/default_dark/style.qss b/dist/qt_themes/default_dark/style.qss new file mode 100644 index 000000000..ca6daa2d5 --- /dev/null +++ b/dist/qt_themes/default_dark/style.qss @@ -0,0 +1,687 @@ +/* +* SPDX-FileCopyrightText: 2018 yuzu Emulator Project +* SPDX-License-Identifier: GPL-2.0-or-later +*/ +QAbstractSpinBox { + min-height: 19px; +} + +QPushButton#TogglableStatusBarButton { + color: #959595; + border: 1px solid transparent; + background-color: transparent; + padding: 0px 3px 0px 3px; + text-align: center; +} + +QPushButton#TogglableStatusBarButton:checked { + color: palette(text); +} + +QPushButton#TogglableStatusBarButton:hover { + border: 1px solid #76797C; +} + +QPushButton#RendererStatusBarButton { + color: #656565; + border: 1px solid transparent; + background-color: transparent; + padding: 0px 3px 0px 3px; + text-align: center; +} + +QPushButton#RendererStatusBarButton:hover { + border: 1px solid #76797C; +} + +QPushButton#RendererStatusBarButton:checked { + color: #e85c00; +} + +QPushButton#RendererStatusBarButton:!checked { + color: #00ccdd; +} + +QPushButton#GPUStatusBarButton { + color: #656565; + border: 1px solid transparent; + background-color: transparent; + padding: 0px 3px 0px 3px; + text-align: center; +} + +QPushButton#GPUStatusBarButton:hover { + border: 1px solid #76797C; +} + +QPushButton#GPUStatusBarButton:checked { + color: #ff8040; +} + +QPushButton#GPUStatusBarButton:!checked { + color: #40dd40; +} + +QPushButton#DockingStatusBarButton { + min-width: 0px; + color: palette(text); + border: 1px solid transparent; + background-color: transparent; + padding: 0px 3px 0px 3px; + text-align: center; +} + +QPushButton#DockingStatusBarButton:hover { + border: 1px solid #76797C; +} + +QPushButton#buttonRefreshDevices { + min-width: 21px; + min-height: 21px; + max-width: 21px; + max-height: 21px; +} + +QWidget#bottomPerGameInput, +QWidget#topControllerApplet, +QWidget#bottomControllerApplet, +QGroupBox#groupPlayer1Connected:checked, +QGroupBox#groupPlayer2Connected:checked, +QGroupBox#groupPlayer3Connected:checked, +QGroupBox#groupPlayer4Connected:checked, +QGroupBox#groupPlayer5Connected:checked, +QGroupBox#groupPlayer6Connected:checked, +QGroupBox#groupPlayer7Connected:checked, +QGroupBox#groupPlayer8Connected:checked { + background-color: #f5f5f5; +} + +QWidget#topControllerApplet { + border-bottom: 1px solid #828790 +} + +QWidget#bottomPerGameInput, +QWidget#bottomControllerApplet { + border-top: 1px solid #828790 +} + +QWidget#topPerGameInput, +QWidget#middleControllerApplet { + background-color: #fff; +} + +QWidget#topPerGameInput QComboBox, +QWidget#middleControllerApplet QComboBox { + width: 120px; +} + +QWidget#connectedControllers { + background: transparent; +} + +QWidget#playersSupported, +QWidget#controllersSupported, +QWidget#controllerSupported1, +QWidget#controllerSupported2, +QWidget#controllerSupported3, +QWidget#controllerSupported4, +QWidget#controllerSupported5, +QWidget#controllerSupported6 { + border: none; + background: transparent; +} + +QGroupBox#groupPlayer1Connected, +QGroupBox#groupPlayer2Connected, +QGroupBox#groupPlayer3Connected, +QGroupBox#groupPlayer4Connected, +QGroupBox#groupPlayer5Connected, +QGroupBox#groupPlayer6Connected, +QGroupBox#groupPlayer7Connected, +QGroupBox#groupPlayer8Connected { + border: 1px solid #828790; + border-radius: 3px; + padding: 0px; + min-height: 98px; + max-height: 98px; +} + +QGroupBox#groupPlayer1Connected:unchecked, +QGroupBox#groupPlayer2Connected:unchecked, +QGroupBox#groupPlayer3Connected:unchecked, +QGroupBox#groupPlayer4Connected:unchecked, +QGroupBox#groupPlayer5Connected:unchecked, +QGroupBox#groupPlayer6Connected:unchecked, +QGroupBox#groupPlayer7Connected:unchecked, +QGroupBox#groupPlayer8Connected:unchecked { + border: 1px solid #d9d9d9; +} + +QGroupBox#groupPlayer1Connected::title, +QGroupBox#groupPlayer2Connected::title, +QGroupBox#groupPlayer3Connected::title, +QGroupBox#groupPlayer4Connected::title, +QGroupBox#groupPlayer5Connected::title, +QGroupBox#groupPlayer6Connected::title, +QGroupBox#groupPlayer7Connected::title, +QGroupBox#groupPlayer8Connected::title { + subcontrol-origin: margin; + subcontrol-position: top left; + padding-left: 0px; + padding-right: 0px; + padding-top: 1px; + margin-left: 0px; + margin-right: -4px; + margin-bottom: 4px; +} + +QCheckBox#checkboxPlayer1Connected, +QCheckBox#checkboxPlayer2Connected, +QCheckBox#checkboxPlayer3Connected, +QCheckBox#checkboxPlayer4Connected, +QCheckBox#checkboxPlayer5Connected, +QCheckBox#checkboxPlayer6Connected, +QCheckBox#checkboxPlayer7Connected, +QCheckBox#checkboxPlayer8Connected { + spacing: 0px; +} + +QWidget#Player1LEDs QCheckBox, +QWidget#Player2LEDs QCheckBox, +QWidget#Player3LEDs QCheckBox, +QWidget#Player4LEDs QCheckBox, +QWidget#Player5LEDs QCheckBox, +QWidget#Player6LEDs QCheckBox, +QWidget#Player7LEDs QCheckBox, +QWidget#Player8LEDs QCheckBox { + spacing: 0px; +} + +QWidget#Player1LEDs QCheckBox::indicator, +QWidget#Player2LEDs QCheckBox::indicator, +QWidget#Player3LEDs QCheckBox::indicator, +QWidget#Player4LEDs QCheckBox::indicator, +QWidget#Player5LEDs QCheckBox::indicator, +QWidget#Player6LEDs QCheckBox::indicator, +QWidget#Player7LEDs QCheckBox::indicator, +QWidget#Player8LEDs QCheckBox::indicator { + width: 6px; + height: 6px; + margin-left: 0px; +} + +QWidget#bottomPerGameInput QCheckBox#checkboxPlayer1Connected::indicator, +QWidget#bottomPerGameInput QCheckBox#checkboxPlayer2Connected::indicator, +QWidget#bottomPerGameInput QCheckBox#checkboxPlayer3Connected::indicator, +QWidget#bottomPerGameInput QCheckBox#checkboxPlayer4Connected::indicator, +QWidget#bottomPerGameInput QCheckBox#checkboxPlayer5Connected::indicator, +QWidget#bottomPerGameInput QCheckBox#checkboxPlayer6Connected::indicator, +QWidget#bottomPerGameInput QCheckBox#checkboxPlayer7Connected::indicator, +QWidget#bottomPerGameInput QCheckBox#checkboxPlayer8Connected::indicator { + width: 12px; + height: 12px; +} + +QCheckBox#checkboxPlayer1Connected::indicator, +QCheckBox#checkboxPlayer2Connected::indicator, +QCheckBox#checkboxPlayer3Connected::indicator, +QCheckBox#checkboxPlayer4Connected::indicator, +QCheckBox#checkboxPlayer5Connected::indicator, +QCheckBox#checkboxPlayer6Connected::indicator, +QCheckBox#checkboxPlayer7Connected::indicator, +QCheckBox#checkboxPlayer8Connected::indicator { + width: 14px; + height: 14px; +} + +QGroupBox#groupPlayer1Connected::indicator, +QGroupBox#groupPlayer2Connected::indicator, +QGroupBox#groupPlayer3Connected::indicator, +QGroupBox#groupPlayer4Connected::indicator, +QGroupBox#groupPlayer5Connected::indicator, +QGroupBox#groupPlayer6Connected::indicator, +QGroupBox#groupPlayer7Connected::indicator, +QGroupBox#groupPlayer8Connected::indicator { + width: 16px; + height: 16px; +} + +QWidget#Player1LEDs QCheckBox::indicator:checked, +QWidget#Player2LEDs QCheckBox::indicator:checked, +QWidget#Player3LEDs QCheckBox::indicator:checked, +QWidget#Player4LEDs QCheckBox::indicator:checked, +QWidget#Player5LEDs QCheckBox::indicator:checked, +QWidget#Player6LEDs QCheckBox::indicator:checked, +QWidget#Player7LEDs QCheckBox::indicator:checked, +QWidget#Player8LEDs QCheckBox::indicator:checked, +QGroupBox#groupPlayer1Connected::indicator:checked, +QGroupBox#groupPlayer2Connected::indicator:checked, +QGroupBox#groupPlayer3Connected::indicator:checked, +QGroupBox#groupPlayer4Connected::indicator:checked, +QGroupBox#groupPlayer5Connected::indicator:checked, +QGroupBox#groupPlayer6Connected::indicator:checked, +QGroupBox#groupPlayer7Connected::indicator:checked, +QGroupBox#groupPlayer8Connected::indicator:checked, +QCheckBox#checkboxPlayer1Connected::indicator:checked, +QCheckBox#checkboxPlayer2Connected::indicator:checked, +QCheckBox#checkboxPlayer3Connected::indicator:checked, +QCheckBox#checkboxPlayer4Connected::indicator:checked, +QCheckBox#checkboxPlayer5Connected::indicator:checked, +QCheckBox#checkboxPlayer6Connected::indicator:checked, +QCheckBox#checkboxPlayer7Connected::indicator:checked, +QCheckBox#checkboxPlayer8Connected::indicator:checked, +QGroupBox#groupConnectedController::indicator:checked { + border-radius: 2px; + border: 1px solid #929192; + background: #39ff14; + image: none; +} + +QWidget#Player1LEDs QCheckBox::indicator:unchecked, +QWidget#Player2LEDs QCheckBox::indicator:unchecked, +QWidget#Player3LEDs QCheckBox::indicator:unchecked, +QWidget#Player4LEDs QCheckBox::indicator:unchecked, +QWidget#Player5LEDs QCheckBox::indicator:unchecked, +QWidget#Player6LEDs QCheckBox::indicator:unchecked, +QWidget#Player7LEDs QCheckBox::indicator:unchecked, +QWidget#Player8LEDs QCheckBox::indicator:unchecked, +QGroupBox#groupPlayer1Connected::indicator:unchecked, +QGroupBox#groupPlayer2Connected::indicator:unchecked, +QGroupBox#groupPlayer3Connected::indicator:unchecked, +QGroupBox#groupPlayer4Connected::indicator:unchecked, +QGroupBox#groupPlayer5Connected::indicator:unchecked, +QGroupBox#groupPlayer6Connected::indicator:unchecked, +QGroupBox#groupPlayer7Connected::indicator:unchecked, +QGroupBox#groupPlayer8Connected::indicator:unchecked, +QCheckBox#checkboxPlayer1Connected::indicator:unchecked, +QCheckBox#checkboxPlayer2Connected::indicator:unchecked, +QCheckBox#checkboxPlayer3Connected::indicator:unchecked, +QCheckBox#checkboxPlayer4Connected::indicator:unchecked, +QCheckBox#checkboxPlayer5Connected::indicator:unchecked, +QCheckBox#checkboxPlayer6Connected::indicator:unchecked, +QCheckBox#checkboxPlayer7Connected::indicator:unchecked, +QCheckBox#checkboxPlayer8Connected::indicator:unchecked, +QGroupBox#groupConnectedController::indicator:unchecked { + border-radius: 2px; + border: 1px solid #929192; + background: transparent; + image: none; +} + +QWidget#controllerPlayer1, +QWidget#controllerPlayer2, +QWidget#controllerPlayer3, +QWidget#controllerPlayer4, +QWidget#controllerPlayer5, +QWidget#controllerPlayer6, +QWidget#controllerPlayer7, +QWidget#controllerPlayer8 { + background: transparent; +} + +QDialog#QtSoftwareKeyboardDialog, +QStackedWidget#topOSK { + background: rgba(51, 51, 51, .9); +} + + +QDialog#OverlayDialog, +QStackedWidget#stackedDialog { + background: rgba(51, 51, 51, .7); +} + +QWidget#boxOSK, +QWidget#lineOSK, +QWidget#richDialog, +QWidget#lineDialog { + background: transparent; +} + +QStackedWidget#bottomOSK, +QWidget#contentDialog, +QWidget#contentRichDialog { + background: rgba(240, 240, 240, 1); +} + +QWidget#contentDialog, +QWidget#contentRichDialog { + margin: 5px; + border-radius: 6px; +} + +QWidget#buttonsDialog, +QWidget#buttonsRichDialog { + margin: 5px; + border-top: 2px solid rgba(44, 44, 44, 1); +} + +QWidget#legendOSKnum { + border-top: 1px solid rgba(44, 44, 44, 1); +} + +QStackedWidget#stackedDialog QTextBrowser QScrollBar::vertical { + background: #cdcdcd; + width: 15px; + margin: 15px 3px 15px 3px; + border: 1px transparent; + border-radius: 4px; +} + +QStackedWidget#stackedDialog QTextBrowser QScrollBar::horizoncal { + background: #cdcdcd; + height: 15px; + margin: 3px 15px 3px 15px; + border: 1px transparent; + border-radius: 4px; +} + +QStackedWidget#stackedDialog QTextBrowser QScrollBar::handle { + background: #fff; + border-radius: 4px; + min-height: 5px; + min-width: 5px; +} + +QStackedWidget#stackedDialog QTextBrowser QScrollBar::add-line, +QStackedWidget#stackedDialog QTextBrowser QScrollBar::sub-line, +QStackedWidget#stackedDialog QTextBrowser QScrollBar::add-page, +QStackedWidget#stackedDialog QTextBrowser QScrollBar::sub-page { + background: none; +} + +QWidget#inputOSK { + border-bottom: 3px solid rgba(255, 255, 255, .9); +} + +QWidget#inputOSK QLineEdit { + background: transparent; + border: none; + color: #ccc; +} + +QWidget#inputBoxOSK { + border: 2px solid rgba(255, 255, 255, .9); +} + +QWidget#inputBoxOSK QTextEdit { + background: transparent; + border: none; + color: #ccc; +} + +QWidget#richDialog QTextBrowser { + background: transparent; + border: none; + padding: 35px 65px; +} + + +QWidget#lineOSK QLabel#label_header { + color: #f0f0f0; +} + +QWidget#lineOSK QLabel#label_sub, +QWidget#lineOSK QLabel#label_characters, +QWidget#boxOSK QLabel#label_characters_box { + color: #ccc; +} + +QWidget#contentDialog QLabel#label_title, +QWidget#contentRichDialog QLabel#label_title_rich { + color: #888; +} + +QWidget#contentDialog QLabel#label_dialog { + padding: 20px 65px; +} + +QWidget#contentDialog QLabel#label_title, +QWidget#contentRichDialog QLabel#label_title_rich { + padding: 0px 65px; +} + +QDialog#OverlayDialog QPushButton { + color: rgba(49, 79, 239, 1); + background: transparent; + border: none; + padding: 0px; + min-width: 0px; +} + +QDialog#OverlayDialog QPushButton:focus, +QDialog#OverlayDialog QPushButton:hover { + color: rgba(49, 79, 239, 1); + background: rgba(255, 255, 255, 1); + border: 5px solid rgba(148, 250, 202, 1); + border-radius: 6px; + outline: none; +} + +QDialog#OverlayDialog QPushButton:pressed { + color: rgba(240, 240, 240, 1); + background: rgba(150, 150, 150, 1); + border: 5px solid rgba(148, 250, 202, 1); + border-radius: 6px; + outline: none; +} + +QDialog#QtSoftwareKeyboardDialog QPushButton { + background: rgba(232, 232, 232, 1); + border: 2px solid rgba(240, 240, 240, 1); +} + +QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_return, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_space, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift { + background: rgba(218, 218, 218, 1); + border: 2px solid rgba(240, 240, 240, 1); +} + +QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num { + color: rgba(240, 240, 240, 1); + background: rgba(44, 44, 44, 1); + border: 2px solid rgba(240, 240, 240, 1); +} + +QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num { + color: rgba(240, 240, 240, 1); + background: rgba(49, 79, 239, 1); + border: 2px solid rgba(240, 240, 240, 1); +} + +QDialog#QtSoftwareKeyboardDialog QPushButton:focus, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:focus, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift:focus, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:focus, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:focus, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:focus, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:focus, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift:focus, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:focus, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:focus, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:focus, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:focus, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:focus, + +QDialog#QtSoftwareKeyboardDialog QPushButton:hover, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:hover, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift:hover, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:hover, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:hover, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:hover, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:hover, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift:hover, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:hover, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:hover, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:hover, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:hover, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:hover { + color: rgba(0, 0, 0, 1); + background: rgba(255, 255, 255, 1); + border: 5px solid rgba(148, 250, 202, 1); + border-radius: 6px; + outline: none; +} + +QDialog#QtSoftwareKeyboardDialog QPushButton:pressed, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:pressed, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift:pressed, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:pressed, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:pressed, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:pressed, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:pressed, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift:pressed, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:pressed, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:pressed, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:pressed, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:pressed, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:pressed { + color: rgba(240, 240, 240, 1); + background: rgba(150, 150, 150, 1); + border: 5px solid rgba(148, 250, 202, 1); + border-radius: 6px; +} + +QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num { + image: url(:/overlay/osk_button_B.png); + image-position: right; + qproperty-icon: url(:/overlay/osk_button_backspace.png); + qproperty-iconSize: 36px; +} + +QDialog#QtSoftwareKeyboardDialog QPushButton#button_space, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift { + image: url(:/overlay/osk_button_Y.png); + image-position: right; +} + +QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num { + image: url(:/overlay/osk_button_plus.png); + image-position: right; +} + +QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift { + image: url(:/overlay/osk_button_shift_lock_off.png); + image-position: left; + qproperty-icon: url(:/overlay/osk_button_shift.png); + qproperty-iconSize: 36px; +} + +QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift { + image: url(:/overlay/osk_button_shift_lock_off.png); + image-position: left; + qproperty-icon: url(:/overlay/osk_button_shift_on.png); + qproperty-iconSize: 36px; +} + +QDialog#QtSoftwareKeyboardDialog QPushButton#button_left_bracket, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_right_bracket, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_left_parenthesis, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_right_parenthesis { + padding-bottom: 7px; +} + +QDialog#QtSoftwareKeyboardDialog QWidget#titleOSK QLabel { + background: transparent; + color: #ccc; +} + +QDialog#QtSoftwareKeyboardDialog QWidget#button_L, +QDialog#QtSoftwareKeyboardDialog QWidget#button_L_shift, +QDialog#QtSoftwareKeyboardDialog QWidget#button_L_num { + image: url(:/overlay/button_L.png); +} + +QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left, +QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left_shift, +QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left_num { + image: url(:/overlay/arrow_left.png); +} + +QDialog#QtSoftwareKeyboardDialog QWidget#button_R, +QDialog#QtSoftwareKeyboardDialog QWidget#button_R_shift, +QDialog#QtSoftwareKeyboardDialog QWidget#button_R_num { + image: url(:/overlay/button_R.png); +} + +QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right, +QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right_shift, +QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right_num { + image: url(:/overlay/arrow_right.png); +} + +QDialog#QtSoftwareKeyboardDialog QWidget#button_press_stick, +QDialog#QtSoftwareKeyboardDialog QWidget#button_press_stick_shift { + image: url(:/overlay/button_press_stick.png); +} + +QDialog#QtSoftwareKeyboardDialog QWidget#button_X, +QDialog#QtSoftwareKeyboardDialog QWidget#button_X_shift, +QDialog#QtSoftwareKeyboardDialog QWidget#button_X_num { + image: url(:/overlay/button_X.png); +} + +QDialog#QtSoftwareKeyboardDialog QWidget#button_A, +QDialog#QtSoftwareKeyboardDialog QWidget#button_A_shift, +QDialog#QtSoftwareKeyboardDialog QWidget#button_A_num { + image: url(:/overlay/button_A.png); +} + +QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:disabled, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:disabled, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:disabled, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:disabled, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:disabled, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:disabled, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_return_shift:disabled, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:disabled, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:disabled, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:disabled { + color: rgba(164, 164, 164, 1); + background-color: rgba(218, 218, 218, 1); +} + +QDialog#QtSoftwareKeyboardDialog QPushButton#button_at:disabled, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_slash:disabled, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_percent:disabled, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_1:disabled, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_2:disabled, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_3:disabled, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_4:disabled, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_5:disabled, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_6:disabled, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_7:disabled, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_8:disabled, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_9:disabled, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_0:disabled, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_return:disabled { + color: rgba(164, 164, 164, 1); +} + +QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:disabled, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:disabled, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:disabled { + image: url(:/overlay/osk_button_plus_disabled.png); +} + +QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:disabled, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:disabled, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:disabled { + image: url(:/overlay/osk_button_B_disabled.png); +} + +QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:disabled, +QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:disabled { + image: url(:/overlay/osk_button_Y_disabled.png); +} diff --git a/dist/qt_themes/qdarkstyle/icons/16x16/refresh.png b/dist/qt_themes/qdarkstyle/icons/16x16/refresh.png Binary files differdeleted file mode 100644 index d4afd76f9..000000000 --- a/dist/qt_themes/qdarkstyle/icons/16x16/refresh.png +++ /dev/null diff --git a/dist/qt_themes/qdarkstyle/icons/48x48/plus.png b/dist/qt_themes/qdarkstyle/icons/48x48/list-add.png Binary files differindex 16cc8b4f4..16cc8b4f4 100644 --- a/dist/qt_themes/qdarkstyle/icons/48x48/plus.png +++ b/dist/qt_themes/qdarkstyle/icons/48x48/list-add.png diff --git a/dist/qt_themes/qdarkstyle/style.qrc b/dist/qt_themes/qdarkstyle/style.qrc index f770e09fd..a89fb26c6 100644 --- a/dist/qt_themes/qdarkstyle/style.qrc +++ b/dist/qt_themes/qdarkstyle/style.qrc @@ -10,7 +10,7 @@ <file alias="48x48/chip.png">icons/48x48/chip.png</file> <file alias="48x48/folder.png">icons/48x48/folder.png</file> <file alias="48x48/no_avatar.png">icons/48x48/no_avatar.png</file> - <file alias="48x48/plus.png">icons/48x48/plus.png</file> + <file alias="48x48/list-add.png">icons/48x48/list-add.png</file> <file alias="48x48/sd_card.png">icons/48x48/sd_card.png</file> <file alias="48x48/star.png">icons/48x48/star.png</file> <file alias="256x256/plus_folder.png">icons/256x256/plus_folder.png</file> diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/icons/16x16/lock.png b/dist/qt_themes/qdarkstyle_midnight_blue/icons/16x16/lock.png Binary files differdeleted file mode 100644 index c750a39e8..000000000 --- a/dist/qt_themes/qdarkstyle_midnight_blue/icons/16x16/lock.png +++ /dev/null diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/icons/16x16/refresh.png b/dist/qt_themes/qdarkstyle_midnight_blue/icons/16x16/refresh.png Binary files differdeleted file mode 100644 index d4afd76f9..000000000 --- a/dist/qt_themes/qdarkstyle_midnight_blue/icons/16x16/refresh.png +++ /dev/null diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/icons/16x16/view-refresh.png b/dist/qt_themes/qdarkstyle_midnight_blue/icons/16x16/view-refresh.png Binary files differdeleted file mode 100644 index d4afd76f9..000000000 --- a/dist/qt_themes/qdarkstyle_midnight_blue/icons/16x16/view-refresh.png +++ /dev/null diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/icons/256x256/plus_folder.png b/dist/qt_themes/qdarkstyle_midnight_blue/icons/256x256/plus_folder.png Binary files differdeleted file mode 100644 index 303f9a321..000000000 --- a/dist/qt_themes/qdarkstyle_midnight_blue/icons/256x256/plus_folder.png +++ /dev/null diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/bad_folder.png b/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/bad_folder.png Binary files differdeleted file mode 100644 index 4a9709623..000000000 --- a/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/bad_folder.png +++ /dev/null diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/chip.png b/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/chip.png Binary files differdeleted file mode 100644 index 973fabd05..000000000 --- a/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/chip.png +++ /dev/null diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/folder.png b/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/folder.png Binary files differdeleted file mode 100644 index 0f1e987d6..000000000 --- a/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/folder.png +++ /dev/null diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/plus.png b/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/plus.png Binary files differdeleted file mode 100644 index 16cc8b4f4..000000000 --- a/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/plus.png +++ /dev/null diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/sd_card.png b/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/sd_card.png Binary files differdeleted file mode 100644 index 0291c6542..000000000 --- a/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/sd_card.png +++ /dev/null diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/star.png b/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/star.png Binary files differdeleted file mode 100644 index 90d423a1d..000000000 --- a/dist/qt_themes/qdarkstyle_midnight_blue/icons/48x48/star.png +++ /dev/null diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/style.qrc b/dist/qt_themes/qdarkstyle_midnight_blue/style.qrc index 142dd3288..dc3d7fecb 100644 --- a/dist/qt_themes/qdarkstyle_midnight_blue/style.qrc +++ b/dist/qt_themes/qdarkstyle_midnight_blue/style.qrc @@ -1,15 +1,16 @@ <RCC> <qresource prefix="icons/qdarkstyle_midnight_blue"> <file alias="index.theme">icons/index.theme</file> - <file alias="16x16/lock.png">icons/16x16/lock.png</file> - <file alias="16x16/view-refresh.png">icons/16x16/view-refresh.png</file> - <file alias="48x48/bad_folder.png">icons/48x48/bad_folder.png</file> - <file alias="48x48/chip.png">icons/48x48/chip.png</file> - <file alias="48x48/folder.png">icons/48x48/folder.png</file> - <file alias="48x48/plus.png">icons/48x48/plus.png</file> - <file alias="48x48/sd_card.png">icons/48x48/sd_card.png</file> - <file alias="48x48/star.png">icons/48x48/star.png</file> - <file alias="256x256/plus_folder.png">icons/256x256/plus_folder.png</file> + <file alias="16x16/lock.png">../qdarkstyle/icons/16x16/lock.png</file> + <file alias="16x16/view-refresh.png">../qdarkstyle/icons/16x16/view-refresh.png</file> + <file alias="48x48/bad_folder.png">../qdarkstyle/icons/48x48/bad_folder.png</file> + <file alias="48x48/chip.png">../qdarkstyle/icons/48x48/chip.png</file> + <file alias="48x48/folder.png">../qdarkstyle/icons/48x48/folder.png</file> + <file alias="48x48/no_avatar.png">../qdarkstyle/icons/48x48/no_avatar.png</file> + <file alias="48x48/list-add.png">../qdarkstyle/icons/48x48/list-add.png</file> + <file alias="48x48/sd_card.png">../qdarkstyle/icons/48x48/sd_card.png</file> + <file alias="48x48/star.png">../qdarkstyle/icons/48x48/star.png</file> + <file alias="256x256/plus_folder.png">../qdarkstyle/icons/256x256/plus_folder.png</file> </qresource> <qresource prefix="qss_icons"> <file>rc/arrow_down.png</file> diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 052357be4..4e39649a8 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -502,9 +502,10 @@ add_library(core STATIC hle/service/jit/jit.h hle/service/lbl/lbl.cpp hle/service/lbl/lbl.h - hle/service/ldn/errors.h + hle/service/ldn/ldn_results.h hle/service/ldn/ldn.cpp hle/service/ldn/ldn.h + hle/service/ldn/ldn_types.h hle/service/ldr/ldr.cpp hle/service/ldr/ldr.h hle/service/lm/lm.cpp diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index 1638bc41d..3b8b43994 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp @@ -195,14 +195,16 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable* if (page_table) { config.page_table = reinterpret_cast<std::array<std::uint8_t*, NUM_PAGE_TABLE_ENTRIES>*>( page_table->pointers.data()); + config.absolute_offset_page_table = true; + config.page_table_pointer_mask_bits = Common::PageTable::ATTRIBUTE_BITS; + config.detect_misaligned_access_via_page_table = 16 | 32 | 64 | 128; + config.only_detect_misalignment_via_page_table_on_page_boundary = true; + config.fastmem_pointer = page_table->fastmem_arena; + + config.fastmem_exclusive_access = config.fastmem_pointer != nullptr; + config.recompile_on_exclusive_fastmem_failure = true; } - config.absolute_offset_page_table = true; - config.page_table_pointer_mask_bits = Common::PageTable::ATTRIBUTE_BITS; - config.detect_misaligned_access_via_page_table = 16 | 32 | 64 | 128; - config.only_detect_misalignment_via_page_table_on_page_boundary = true; - config.fastmem_exclusive_access = true; - config.recompile_on_exclusive_fastmem_failure = true; // Multi-process state config.processor_id = core_index; @@ -254,6 +256,7 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable* } if (!Settings::values.cpuopt_fastmem) { config.fastmem_pointer = nullptr; + config.fastmem_exclusive_access = false; } if (!Settings::values.cpuopt_fastmem_exclusives) { config.fastmem_exclusive_access = false; diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index 921a5a734..1d46f6d40 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -250,7 +250,7 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable* config.fastmem_address_space_bits = address_space_bits; config.silently_mirror_fastmem = false; - config.fastmem_exclusive_access = true; + config.fastmem_exclusive_access = config.fastmem_pointer != nullptr; config.recompile_on_exclusive_fastmem_failure = true; } @@ -314,6 +314,7 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable* } if (!Settings::values.cpuopt_fastmem) { config.fastmem_pointer = nullptr; + config.fastmem_exclusive_access = false; } if (!Settings::values.cpuopt_fastmem_exclusives) { config.fastmem_exclusive_access = false; diff --git a/src/core/hle/service/ldn/errors.h b/src/core/hle/service/ldn/errors.h deleted file mode 100644 index 972a74806..000000000 --- a/src/core/hle/service/ldn/errors.h +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/result.h" - -namespace Service::LDN { - -constexpr Result ERROR_DISABLED{ErrorModule::LDN, 22}; - -} // namespace Service::LDN diff --git a/src/core/hle/service/ldn/ldn.cpp b/src/core/hle/service/ldn/ldn.cpp index 125d4dc4c..c11daff54 100644 --- a/src/core/hle/service/ldn/ldn.cpp +++ b/src/core/hle/service/ldn/ldn.cpp @@ -3,11 +3,15 @@ #include <memory> -#include "core/hle/ipc_helpers.h" -#include "core/hle/result.h" -#include "core/hle/service/ldn/errors.h" +#include "core/core.h" #include "core/hle/service/ldn/ldn.h" -#include "core/hle/service/sm/sm.h" +#include "core/hle/service/ldn/ldn_results.h" +#include "core/hle/service/ldn/ldn_types.h" +#include "core/internal_network/network.h" +#include "core/internal_network/network_interface.h" + +// This is defined by synchapi.h and conflicts with ServiceContext::CreateEvent +#undef CreateEvent namespace Service::LDN { @@ -100,74 +104,418 @@ class IUserLocalCommunicationService final : public ServiceFramework<IUserLocalCommunicationService> { public: explicit IUserLocalCommunicationService(Core::System& system_) - : ServiceFramework{system_, "IUserLocalCommunicationService"} { + : ServiceFramework{system_, "IUserLocalCommunicationService", ServiceThreadType::CreateNew}, + service_context{system, "IUserLocalCommunicationService"}, room_network{ + system_.GetRoomNetwork()} { // clang-format off static const FunctionInfo functions[] = { {0, &IUserLocalCommunicationService::GetState, "GetState"}, - {1, nullptr, "GetNetworkInfo"}, + {1, &IUserLocalCommunicationService::GetNetworkInfo, "GetNetworkInfo"}, {2, nullptr, "GetIpv4Address"}, - {3, nullptr, "GetDisconnectReason"}, - {4, nullptr, "GetSecurityParameter"}, - {5, nullptr, "GetNetworkConfig"}, - {100, nullptr, "AttachStateChangeEvent"}, - {101, nullptr, "GetNetworkInfoLatestUpdate"}, - {102, nullptr, "Scan"}, - {103, nullptr, "ScanPrivate"}, + {3, &IUserLocalCommunicationService::GetDisconnectReason, "GetDisconnectReason"}, + {4, &IUserLocalCommunicationService::GetSecurityParameter, "GetSecurityParameter"}, + {5, &IUserLocalCommunicationService::GetNetworkConfig, "GetNetworkConfig"}, + {100, &IUserLocalCommunicationService::AttachStateChangeEvent, "AttachStateChangeEvent"}, + {101, &IUserLocalCommunicationService::GetNetworkInfoLatestUpdate, "GetNetworkInfoLatestUpdate"}, + {102, &IUserLocalCommunicationService::Scan, "Scan"}, + {103, &IUserLocalCommunicationService::ScanPrivate, "ScanPrivate"}, {104, nullptr, "SetWirelessControllerRestriction"}, - {200, nullptr, "OpenAccessPoint"}, - {201, nullptr, "CloseAccessPoint"}, - {202, nullptr, "CreateNetwork"}, - {203, nullptr, "CreateNetworkPrivate"}, - {204, nullptr, "DestroyNetwork"}, + {200, &IUserLocalCommunicationService::OpenAccessPoint, "OpenAccessPoint"}, + {201, &IUserLocalCommunicationService::CloseAccessPoint, "CloseAccessPoint"}, + {202, &IUserLocalCommunicationService::CreateNetwork, "CreateNetwork"}, + {203, &IUserLocalCommunicationService::CreateNetworkPrivate, "CreateNetworkPrivate"}, + {204, &IUserLocalCommunicationService::DestroyNetwork, "DestroyNetwork"}, {205, nullptr, "Reject"}, - {206, nullptr, "SetAdvertiseData"}, - {207, nullptr, "SetStationAcceptPolicy"}, - {208, nullptr, "AddAcceptFilterEntry"}, + {206, &IUserLocalCommunicationService::SetAdvertiseData, "SetAdvertiseData"}, + {207, &IUserLocalCommunicationService::SetStationAcceptPolicy, "SetStationAcceptPolicy"}, + {208, &IUserLocalCommunicationService::AddAcceptFilterEntry, "AddAcceptFilterEntry"}, {209, nullptr, "ClearAcceptFilter"}, - {300, nullptr, "OpenStation"}, - {301, nullptr, "CloseStation"}, - {302, nullptr, "Connect"}, + {300, &IUserLocalCommunicationService::OpenStation, "OpenStation"}, + {301, &IUserLocalCommunicationService::CloseStation, "CloseStation"}, + {302, &IUserLocalCommunicationService::Connect, "Connect"}, {303, nullptr, "ConnectPrivate"}, - {304, nullptr, "Disconnect"}, - {400, nullptr, "Initialize"}, - {401, nullptr, "Finalize"}, - {402, &IUserLocalCommunicationService::Initialize2, "Initialize2"}, // 7.0.0+ + {304, &IUserLocalCommunicationService::Disconnect, "Disconnect"}, + {400, &IUserLocalCommunicationService::Initialize, "Initialize"}, + {401, &IUserLocalCommunicationService::Finalize, "Finalize"}, + {402, &IUserLocalCommunicationService::Initialize2, "Initialize2"}, }; // clang-format on RegisterHandlers(functions); + + state_change_event = + service_context.CreateEvent("IUserLocalCommunicationService:StateChangeEvent"); + } + + ~IUserLocalCommunicationService() { + service_context.CloseEvent(state_change_event); + } + + void OnEventFired() { + state_change_event->GetWritableEvent().Signal(); } void GetState(Kernel::HLERequestContext& ctx) { + State state = State::Error; + LOG_WARNING(Service_LDN, "(STUBBED) called, state = {}", state); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.PushEnum(state); + } + + void GetNetworkInfo(Kernel::HLERequestContext& ctx) { + const auto write_buffer_size = ctx.GetWriteBufferSize(); + + if (write_buffer_size != sizeof(NetworkInfo)) { + LOG_ERROR(Service_LDN, "Invalid buffer size {}", write_buffer_size); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultBadInput); + return; + } + + NetworkInfo network_info{}; + const auto rc = ResultSuccess; + if (rc.IsError()) { + LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(rc); + return; + } + + LOG_WARNING(Service_LDN, "(STUBBED) called, ssid='{}', nodes={}", + network_info.common.ssid.GetStringValue(), network_info.ldn.node_count); + + ctx.WriteBuffer<NetworkInfo>(network_info); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(rc); + } + + void GetDisconnectReason(Kernel::HLERequestContext& ctx) { + const auto disconnect_reason = DisconnectReason::None; + + LOG_WARNING(Service_LDN, "(STUBBED) called, disconnect_reason={}", disconnect_reason); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.PushEnum(disconnect_reason); + } + + void GetSecurityParameter(Kernel::HLERequestContext& ctx) { + SecurityParameter security_parameter{}; + NetworkInfo info{}; + const Result rc = ResultSuccess; + + if (rc.IsError()) { + LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(rc); + return; + } + + security_parameter.session_id = info.network_id.session_id; + std::memcpy(security_parameter.data.data(), info.ldn.security_parameter.data(), + sizeof(SecurityParameter::data)); + LOG_WARNING(Service_LDN, "(STUBBED) called"); + IPC::ResponseBuilder rb{ctx, 10}; + rb.Push(rc); + rb.PushRaw<SecurityParameter>(security_parameter); + } + + void GetNetworkConfig(Kernel::HLERequestContext& ctx) { + NetworkConfig config{}; + NetworkInfo info{}; + const Result rc = ResultSuccess; + + if (rc.IsError()) { + LOG_ERROR(Service_LDN, "NetworkConfig is not valid {}", rc.raw); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(rc); + return; + } + + config.intent_id = info.network_id.intent_id; + config.channel = info.common.channel; + config.node_count_max = info.ldn.node_count_max; + config.local_communication_version = info.ldn.nodes[0].local_communication_version; + + LOG_WARNING(Service_LDN, + "(STUBBED) called, intent_id={}/{}, channel={}, node_count_max={}, " + "local_communication_version={}", + config.intent_id.local_communication_id, config.intent_id.scene_id, + config.channel, config.node_count_max, config.local_communication_version); + + IPC::ResponseBuilder rb{ctx, 10}; + rb.Push(rc); + rb.PushRaw<NetworkConfig>(config); + } + + void AttachStateChangeEvent(Kernel::HLERequestContext& ctx) { + LOG_INFO(Service_LDN, "called"); + + IPC::ResponseBuilder rb{ctx, 2, 1}; + rb.Push(ResultSuccess); + rb.PushCopyObjects(state_change_event->GetReadableEvent()); + } + + void GetNetworkInfoLatestUpdate(Kernel::HLERequestContext& ctx) { + const std::size_t network_buffer_size = ctx.GetWriteBufferSize(0); + const std::size_t node_buffer_count = ctx.GetWriteBufferSize(1) / sizeof(NodeLatestUpdate); + + if (node_buffer_count == 0 || network_buffer_size != sizeof(NetworkInfo)) { + LOG_ERROR(Service_LDN, "Invalid buffer size {}, {}", network_buffer_size, + node_buffer_count); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultBadInput); + return; + } + + NetworkInfo info; + std::vector<NodeLatestUpdate> latest_update(node_buffer_count); + + const auto rc = ResultSuccess; + if (rc.IsError()) { + LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(rc); + return; + } + + LOG_WARNING(Service_LDN, "(STUBBED) called, ssid='{}', nodes={}", + info.common.ssid.GetStringValue(), info.ldn.node_count); + + ctx.WriteBuffer(info, 0); + ctx.WriteBuffer(latest_update, 1); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void Scan(Kernel::HLERequestContext& ctx) { + ScanImpl(ctx); + } + + void ScanPrivate(Kernel::HLERequestContext& ctx) { + ScanImpl(ctx, true); + } + + void ScanImpl(Kernel::HLERequestContext& ctx, bool is_private = false) { + IPC::RequestParser rp{ctx}; + const auto channel{rp.PopEnum<WifiChannel>()}; + const auto scan_filter{rp.PopRaw<ScanFilter>()}; + + const std::size_t network_info_size = ctx.GetWriteBufferSize() / sizeof(NetworkInfo); + + if (network_info_size == 0) { + LOG_ERROR(Service_LDN, "Invalid buffer size {}", network_info_size); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultBadInput); + return; + } + + u16 count = 0; + std::vector<NetworkInfo> network_infos(network_info_size); + + LOG_WARNING(Service_LDN, + "(STUBBED) called, channel={}, filter_scan_flag={}, filter_network_type={}", + channel, scan_filter.flag, scan_filter.network_type); + + ctx.WriteBuffer(network_infos); + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push<u32>(count); + } + + void OpenAccessPoint(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void CloseAccessPoint(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void CreateNetwork(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + struct Parameters { + SecurityConfig security_config; + UserConfig user_config; + INSERT_PADDING_WORDS_NOINIT(1); + NetworkConfig network_config; + }; + static_assert(sizeof(Parameters) == 0x98, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + + LOG_WARNING(Service_LDN, + "(STUBBED) called, passphrase_size={}, security_mode={}, " + "local_communication_version={}", + parameters.security_config.passphrase_size, + parameters.security_config.security_mode, + parameters.network_config.local_communication_version); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void CreateNetworkPrivate(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + struct Parameters { + SecurityConfig security_config; + SecurityParameter security_parameter; + UserConfig user_config; + NetworkConfig network_config; + }; + static_assert(sizeof(Parameters) == 0xB8, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + + LOG_WARNING(Service_LDN, + "(STUBBED) called, passphrase_size={}, security_mode={}, " + "local_communication_version={}", + parameters.security_config.passphrase_size, + parameters.security_config.security_mode, + parameters.network_config.local_communication_version); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void DestroyNetwork(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void SetAdvertiseData(Kernel::HLERequestContext& ctx) { + std::vector<u8> read_buffer = ctx.ReadBuffer(); + + LOG_WARNING(Service_LDN, "(STUBBED) called, size {}", read_buffer.size()); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void SetStationAcceptPolicy(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } - // Indicate a network error, as we do not actually emulate LDN - rb.Push(static_cast<u32>(State::Error)); + void AddAcceptFilterEntry(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void OpenStation(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void CloseStation(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void Connect(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + struct Parameters { + SecurityConfig security_config; + UserConfig user_config; + u32 local_communication_version; + u32 option; + }; + static_assert(sizeof(Parameters) == 0x7C, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw<Parameters>()}; + + LOG_WARNING(Service_LDN, + "(STUBBED) called, passphrase_size={}, security_mode={}, " + "local_communication_version={}", + parameters.security_config.passphrase_size, + parameters.security_config.security_mode, + parameters.local_communication_version); + + const std::vector<u8> read_buffer = ctx.ReadBuffer(); + NetworkInfo network_info{}; + + if (read_buffer.size() != sizeof(NetworkInfo)) { + LOG_ERROR(Frontend, "NetworkInfo doesn't match read_buffer size!"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultBadInput); + return; + } + + std::memcpy(&network_info, read_buffer.data(), read_buffer.size()); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void Disconnect(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + void Initialize(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + const auto rc = InitializeImpl(ctx); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(rc); + } + + void Finalize(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + is_initialized = false; + + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void Initialize2(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_LDN, "called"); + LOG_WARNING(Service_LDN, "(STUBBED) called"); - is_initialized = true; + const auto rc = InitializeImpl(ctx); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_DISABLED); + rb.Push(rc); + } + + Result InitializeImpl(Kernel::HLERequestContext& ctx) { + const auto network_interface = Network::GetSelectedNetworkInterface(); + if (!network_interface) { + LOG_ERROR(Service_LDN, "No network interface is set"); + return ResultAirplaneModeEnabled; + } + + is_initialized = true; + // TODO (flTobi): Change this to ResultSuccess when LDN is fully implemented + return ResultAirplaneModeEnabled; } -private: - enum class State { - None, - Initialized, - AccessPointOpened, - AccessPointCreated, - StationOpened, - StationConnected, - Error, - }; + KernelHelpers::ServiceContext service_context; + Kernel::KEvent* state_change_event; + Network::RoomNetwork& room_network; bool is_initialized{}; }; @@ -273,7 +621,7 @@ public: LOG_WARNING(Service_LDN, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_DISABLED); + rb.Push(ResultDisabled); } }; diff --git a/src/core/hle/service/ldn/ldn.h b/src/core/hle/service/ldn/ldn.h index a0031ac71..6afe2ea6f 100644 --- a/src/core/hle/service/ldn/ldn.h +++ b/src/core/hle/service/ldn/ldn.h @@ -3,6 +3,12 @@ #pragma once +#include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/k_event.h" +#include "core/hle/result.h" +#include "core/hle/service/kernel_helpers.h" +#include "core/hle/service/sm/sm.h" + namespace Core { class System; } diff --git a/src/core/hle/service/ldn/ldn_results.h b/src/core/hle/service/ldn/ldn_results.h new file mode 100644 index 000000000..f340bda42 --- /dev/null +++ b/src/core/hle/service/ldn/ldn_results.h @@ -0,0 +1,27 @@ +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "core/hle/result.h" + +namespace Service::LDN { + +constexpr Result ResultAdvertiseDataTooLarge{ErrorModule::LDN, 10}; +constexpr Result ResultAuthenticationFailed{ErrorModule::LDN, 20}; +constexpr Result ResultDisabled{ErrorModule::LDN, 22}; +constexpr Result ResultAirplaneModeEnabled{ErrorModule::LDN, 23}; +constexpr Result ResultInvalidNodeCount{ErrorModule::LDN, 30}; +constexpr Result ResultConnectionFailed{ErrorModule::LDN, 31}; +constexpr Result ResultBadState{ErrorModule::LDN, 32}; +constexpr Result ResultNoIpAddress{ErrorModule::LDN, 33}; +constexpr Result ResultInvalidBufferCount{ErrorModule::LDN, 50}; +constexpr Result ResultAccessPointConnectionFailed{ErrorModule::LDN, 65}; +constexpr Result ResultAuthenticationTimeout{ErrorModule::LDN, 66}; +constexpr Result ResultMaximumNodeCount{ErrorModule::LDN, 67}; +constexpr Result ResultBadInput{ErrorModule::LDN, 96}; +constexpr Result ResultLocalCommunicationIdNotFound{ErrorModule::LDN, 97}; +constexpr Result ResultLocalCommunicationVersionTooLow{ErrorModule::LDN, 113}; +constexpr Result ResultLocalCommunicationVersionTooHigh{ErrorModule::LDN, 114}; + +} // namespace Service::LDN diff --git a/src/core/hle/service/ldn/ldn_types.h b/src/core/hle/service/ldn/ldn_types.h new file mode 100644 index 000000000..0c07a7397 --- /dev/null +++ b/src/core/hle/service/ldn/ldn_types.h @@ -0,0 +1,284 @@ +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include <fmt/format.h> + +#include "common/common_funcs.h" +#include "common/common_types.h" +#include "network/network.h" + +namespace Service::LDN { + +constexpr size_t SsidLengthMax = 32; +constexpr size_t AdvertiseDataSizeMax = 384; +constexpr size_t UserNameBytesMax = 32; +constexpr int NodeCountMax = 8; +constexpr int StationCountMax = NodeCountMax - 1; +constexpr size_t PassphraseLengthMax = 64; + +enum class SecurityMode : u16 { + All, + Retail, + Debug, +}; + +enum class NodeStateChange : u8 { + None, + Connect, + Disconnect, + DisconnectAndConnect, +}; + +enum class ScanFilterFlag : u32 { + None = 0, + LocalCommunicationId = 1 << 0, + SessionId = 1 << 1, + NetworkType = 1 << 2, + Ssid = 1 << 4, + SceneId = 1 << 5, + IntentId = LocalCommunicationId | SceneId, + NetworkId = IntentId | SessionId, +}; + +enum class NetworkType : u32 { + None, + General, + Ldn, + All, +}; + +enum class PackedNetworkType : u8 { + None, + General, + Ldn, + All, +}; + +enum class State : u32 { + None, + Initialized, + AccessPointOpened, + AccessPointCreated, + StationOpened, + StationConnected, + Error, +}; + +enum class DisconnectReason : s16 { + Unknown = -1, + None, + DisconnectedByUser, + DisconnectedBySystem, + DestroyedByUser, + DestroyedBySystem, + Rejected, + SignalLost, +}; + +enum class NetworkError { + Unknown = -1, + None = 0, + PortUnreachable, + TooManyPlayers, + VersionTooLow, + VersionTooHigh, + ConnectFailure, + ConnectNotFound, + ConnectTimeout, + ConnectRejected, + RejectFailed, +}; + +enum class AcceptPolicy : u8 { + AcceptAll, + RejectAll, + BlackList, + WhiteList, +}; + +enum class WifiChannel : s16 { + Default = 0, + wifi24_1 = 1, + wifi24_6 = 6, + wifi24_11 = 11, + wifi50_36 = 36, + wifi50_40 = 40, + wifi50_44 = 44, + wifi50_48 = 48, +}; + +enum class LinkLevel : s8 { + Bad, + Low, + Good, + Excelent, +}; + +struct NodeLatestUpdate { + NodeStateChange state_change; + INSERT_PADDING_BYTES(0x7); // Unknown +}; +static_assert(sizeof(NodeLatestUpdate) == 0x8, "NodeLatestUpdate is an invalid size"); + +struct SessionId { + u64 high; + u64 low; + + bool operator==(const SessionId&) const = default; +}; +static_assert(sizeof(SessionId) == 0x10, "SessionId is an invalid size"); + +struct IntentId { + u64 local_communication_id; + INSERT_PADDING_BYTES(0x2); // Reserved + u16 scene_id; + INSERT_PADDING_BYTES(0x4); // Reserved +}; +static_assert(sizeof(IntentId) == 0x10, "IntentId is an invalid size"); + +struct NetworkId { + IntentId intent_id; + SessionId session_id; +}; +static_assert(sizeof(NetworkId) == 0x20, "NetworkId is an invalid size"); + +struct Ssid { + u8 length; + std::array<char, SsidLengthMax + 1> raw; + + std::string GetStringValue() const { + return std::string(raw.data(), length); + } +}; +static_assert(sizeof(Ssid) == 0x22, "Ssid is an invalid size"); + +struct Ipv4Address { + union { + u32 raw{}; + std::array<u8, 4> bytes; + }; + + std::string GetStringValue() const { + return fmt::format("{}.{}.{}.{}", bytes[3], bytes[2], bytes[1], bytes[0]); + } +}; +static_assert(sizeof(Ipv4Address) == 0x4, "Ipv4Address is an invalid size"); + +struct MacAddress { + std::array<u8, 6> raw{}; + + friend bool operator==(const MacAddress& lhs, const MacAddress& rhs) = default; +}; +static_assert(sizeof(MacAddress) == 0x6, "MacAddress is an invalid size"); + +struct ScanFilter { + NetworkId network_id; + NetworkType network_type; + MacAddress mac_address; + Ssid ssid; + INSERT_PADDING_BYTES(0x10); + ScanFilterFlag flag; +}; +static_assert(sizeof(ScanFilter) == 0x60, "ScanFilter is an invalid size"); + +struct CommonNetworkInfo { + MacAddress bssid; + Ssid ssid; + WifiChannel channel; + LinkLevel link_level; + PackedNetworkType network_type; + INSERT_PADDING_BYTES(0x4); +}; +static_assert(sizeof(CommonNetworkInfo) == 0x30, "CommonNetworkInfo is an invalid size"); + +struct NodeInfo { + Ipv4Address ipv4_address; + MacAddress mac_address; + s8 node_id; + u8 is_connected; + std::array<u8, UserNameBytesMax + 1> user_name; + INSERT_PADDING_BYTES(0x1); // Reserved + s16 local_communication_version; + INSERT_PADDING_BYTES(0x10); // Reserved +}; +static_assert(sizeof(NodeInfo) == 0x40, "NodeInfo is an invalid size"); + +struct LdnNetworkInfo { + std::array<u8, 0x10> security_parameter; + SecurityMode security_mode; + AcceptPolicy station_accept_policy; + u8 has_action_frame; + INSERT_PADDING_BYTES(0x2); // Padding + u8 node_count_max; + u8 node_count; + std::array<NodeInfo, NodeCountMax> nodes; + INSERT_PADDING_BYTES(0x2); // Reserved + u16 advertise_data_size; + std::array<u8, AdvertiseDataSizeMax> advertise_data; + INSERT_PADDING_BYTES(0x8C); // Reserved + u64 random_authentication_id; +}; +static_assert(sizeof(LdnNetworkInfo) == 0x430, "LdnNetworkInfo is an invalid size"); + +struct NetworkInfo { + NetworkId network_id; + CommonNetworkInfo common; + LdnNetworkInfo ldn; +}; +static_assert(sizeof(NetworkInfo) == 0x480, "NetworkInfo is an invalid size"); + +struct SecurityConfig { + SecurityMode security_mode; + u16 passphrase_size; + std::array<u8, PassphraseLengthMax> passphrase; +}; +static_assert(sizeof(SecurityConfig) == 0x44, "SecurityConfig is an invalid size"); + +struct UserConfig { + std::array<u8, UserNameBytesMax + 1> user_name; + INSERT_PADDING_BYTES(0xF); // Reserved +}; +static_assert(sizeof(UserConfig) == 0x30, "UserConfig is an invalid size"); + +#pragma pack(push, 4) +struct ConnectRequest { + SecurityConfig security_config; + UserConfig user_config; + u32 local_communication_version; + u32 option_unknown; + NetworkInfo network_info; +}; +static_assert(sizeof(ConnectRequest) == 0x4FC, "ConnectRequest is an invalid size"); +#pragma pack(pop) + +struct SecurityParameter { + std::array<u8, 0x10> data; // Data, used with the same key derivation as SecurityConfig + SessionId session_id; +}; +static_assert(sizeof(SecurityParameter) == 0x20, "SecurityParameter is an invalid size"); + +struct NetworkConfig { + IntentId intent_id; + WifiChannel channel; + u8 node_count_max; + INSERT_PADDING_BYTES(0x1); // Reserved + u16 local_communication_version; + INSERT_PADDING_BYTES(0xA); // Reserved +}; +static_assert(sizeof(NetworkConfig) == 0x20, "NetworkConfig is an invalid size"); + +struct AddressEntry { + Ipv4Address ipv4_address; + MacAddress mac_address; + INSERT_PADDING_BYTES(0x2); // Reserved +}; +static_assert(sizeof(AddressEntry) == 0xC, "AddressEntry is an invalid size"); + +struct AddressList { + std::array<AddressEntry, 0x8> addresses; +}; +static_assert(sizeof(AddressList) == 0x60, "AddressList is an invalid size"); + +} // namespace Service::LDN diff --git a/src/yuzu/aboutdialog.ui b/src/yuzu/aboutdialog.ui index c4ffb293e..aea82809d 100644 --- a/src/yuzu/aboutdialog.ui +++ b/src/yuzu/aboutdialog.ui @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>616</width> - <height>261</height> + <height>294</height> </rect> </property> <property name="windowTitle"> @@ -165,6 +165,7 @@ p, li { white-space: pre-wrap; } </widget> <resources> <include location="../../dist/qt_themes_default/default/default.qrc"/> + <include location="../../dist/qt_themes/default/default.qrc"/> </resources> <connections> <connection> diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index 041e6ac11..c4b1f65bd 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp @@ -286,7 +286,7 @@ void GameList::OnUpdateThemedIcons() { } case GameListItemType::AddDir: child->setData( - QIcon::fromTheme(QStringLiteral("plus")) + QIcon::fromTheme(QStringLiteral("list-add")) .pixmap(icon_size) .scaled(icon_size, icon_size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), Qt::DecorationRole); diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h index e7667cf60..0e19be22d 100644 --- a/src/yuzu/game_list_p.h +++ b/src/yuzu/game_list_p.h @@ -294,7 +294,7 @@ public: const int icon_size = UISettings::values.folder_icon_size.GetValue(); - setData(QIcon::fromTheme(QStringLiteral("plus")) + setData(QIcon::fromTheme(QStringLiteral("list-add")) .pixmap(icon_size) .scaled(icon_size, icon_size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), Qt::DecorationRole); diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index f82bec3b7..44d7feddc 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -257,6 +257,18 @@ static QString PrettyProductName() { return QSysInfo::prettyProductName(); } +bool GMainWindow::CheckDarkMode() { +#ifdef __linux__ + const QPalette test_palette(qApp->palette()); + const QColor text_color = test_palette.color(QPalette::Active, QPalette::Text); + const QColor window_color = test_palette.color(QPalette::Active, QPalette::Window); + return (text_color.value() > window_color.value()); +#else + // TODO: Windows + return false; +#endif // __linux__ +} + GMainWindow::GMainWindow(bool has_broken_vulkan) : ui{std::make_unique<Ui::MainWindow>()}, system{std::make_unique<Core::System>()}, input_subsystem{std::make_shared<InputCommon::InputSubsystem>()}, @@ -274,6 +286,13 @@ GMainWindow::GMainWindow(bool has_broken_vulkan) ui->setupUi(this); statusBar()->hide(); + // Check dark mode before a theme is loaded + os_dark_mode = CheckDarkMode(); + startup_icon_theme = QIcon::themeName(); + // fallback can only be set once, colorful theme icons are okay on both light/dark + QIcon::setFallbackThemeName(QStringLiteral("colorful")); + QIcon::setFallbackSearchPaths(QStringList(QStringLiteral(":/icons"))); + default_theme_paths = QIcon::themeSearchPaths(); UpdateUITheme(); @@ -3935,8 +3954,21 @@ void GMainWindow::filterBarSetChecked(bool state) { emit(OnToggleFilterBar()); } +static void AdjustLinkColor() { + QPalette new_pal(qApp->palette()); + if (UISettings::IsDarkTheme()) { + new_pal.setColor(QPalette::Link, QColor(0, 190, 255, 255)); + } else { + new_pal.setColor(QPalette::Link, QColor(0, 140, 200, 255)); + } + if (qApp->palette().color(QPalette::Link) != new_pal.color(QPalette::Link)) { + qApp->setPalette(new_pal); + } +} + void GMainWindow::UpdateUITheme() { - const QString default_theme = QStringLiteral("default"); + const QString default_theme = + QString::fromUtf8(UISettings::themes[static_cast<size_t>(Config::default_theme)].second); QString current_theme = UISettings::values.theme; QStringList theme_paths(default_theme_paths); @@ -3944,6 +3976,23 @@ void GMainWindow::UpdateUITheme() { current_theme = default_theme; } +#ifdef _WIN32 + QIcon::setThemeName(current_theme); + AdjustLinkColor(); +#else + if (current_theme == QStringLiteral("default") || current_theme == QStringLiteral("colorful")) { + QIcon::setThemeName(current_theme == QStringLiteral("colorful") ? current_theme + : startup_icon_theme); + QIcon::setThemeSearchPaths(theme_paths); + if (CheckDarkMode()) { + current_theme = QStringLiteral("default_dark"); + } + } else { + QIcon::setThemeName(current_theme); + QIcon::setThemeSearchPaths(QStringList(QStringLiteral(":/icons"))); + AdjustLinkColor(); + } +#endif if (current_theme != default_theme) { QString theme_uri{QStringLiteral(":%1/style.qss").arg(current_theme)}; QFile f(theme_uri); @@ -3966,17 +4015,6 @@ void GMainWindow::UpdateUITheme() { qApp->setStyleSheet({}); setStyleSheet({}); } - - QPalette new_pal(qApp->palette()); - if (UISettings::IsDarkTheme()) { - new_pal.setColor(QPalette::Link, QColor(0, 190, 255, 255)); - } else { - new_pal.setColor(QPalette::Link, QColor(0, 140, 200, 255)); - } - qApp->setPalette(new_pal); - - QIcon::setThemeName(current_theme); - QIcon::setThemeSearchPaths(theme_paths); } void GMainWindow::LoadTranslation() { @@ -4022,6 +4060,26 @@ void GMainWindow::SetDiscordEnabled([[maybe_unused]] bool state) { discord_rpc->Update(); } +void GMainWindow::changeEvent(QEvent* event) { +#ifdef __linux__ + // PaletteChange event appears to only reach so far into the GUI, explicitly asking to + // UpdateUITheme is a decent work around + if (event->type() == QEvent::PaletteChange) { + const QPalette test_palette(qApp->palette()); + const QString current_theme = UISettings::values.theme; + // Keeping eye on QPalette::Window to avoid looping. QPalette::Text might be useful too + static QColor last_window_color; + const QColor window_color = test_palette.color(QPalette::Active, QPalette::Window); + if (last_window_color != window_color && (current_theme == QStringLiteral("default") || + current_theme == QStringLiteral("colorful"))) { + UpdateUITheme(); + } + last_window_color = window_color; + } +#endif // __linux__ + QWidget::changeEvent(event); +} + #ifdef main #undef main #endif diff --git a/src/yuzu/main.h b/src/yuzu/main.h index e13b38b24..1ae2b93d9 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -251,6 +251,7 @@ private: bool ConfirmForceLockedExit(); void RequestGameExit(); void RequestGameResume(); + void changeEvent(QEvent* event) override; void closeEvent(QCloseEvent* event) override; #ifdef __linux__ @@ -347,6 +348,7 @@ private: void OpenURL(const QUrl& url); void LoadTranslation(); void OpenPerGameConfiguration(u64 title_id, const std::string& file_name); + bool CheckDarkMode(); QString GetTasStateDescription() const; @@ -392,6 +394,9 @@ private: QTimer mouse_hide_timer; QTimer mouse_center_timer; + QString startup_icon_theme; + bool os_dark_mode = false; + // FS std::shared_ptr<FileSys::VfsFilesystem> vfs; std::unique_ptr<FileSys::ManualContentProvider> provider; diff --git a/src/yuzu/multiplayer/direct_connect.ui b/src/yuzu/multiplayer/direct_connect.ui index 681b6bf69..57d6ec25a 100644 --- a/src/yuzu/multiplayer/direct_connect.ui +++ b/src/yuzu/multiplayer/direct_connect.ui @@ -83,7 +83,7 @@ <number>5</number> </property> <property name="placeholderText"> - <string>24872</string> + <string notr="true" extracomment="placeholder string that tells user default port">24872</string> </property> </widget> </item> |