diff --git a/README.md b/README.md
index 253d246d7..e80e9dbfa 100755
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
yuzu emulator early access
=============
-This is the source code for early-access 1555.
+This is the source code for early-access 1559.
## Legal Notice
diff --git a/dist/qt_themes/default/style.qss b/dist/qt_themes/default/style.qss
index 836dd25ca..3bc92b69d 100755
--- a/dist/qt_themes/default/style.qss
+++ b/dist/qt_themes/default/style.qss
@@ -281,3 +281,380 @@ 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 {
+ background-position: right top;
+ background-repeat: no-repeat;
+ background-origin: content;
+ background-image: url(:/overlay/osk_button_B.png);
+ qproperty-icon: url(:/overlay/osk_button_backspace.png);
+ qproperty-iconSize: 36px;
+}
+
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_space,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift {
+ background-position: right top;
+ background-repeat: no-repeat;
+ background-origin: content;
+ background-image: url(:/overlay/osk_button_Y.png);
+}
+
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num {
+ background-position: right top;
+ background-repeat: no-repeat;
+ background-origin: content;
+ background-image: url(:/overlay/osk_button_plus.png);
+}
+
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift {
+ background-position: left top;
+ background-repeat: no-repeat;
+ background-origin: content;
+ background-image: url(:/overlay/osk_button_shift_lock_off.png);
+ qproperty-icon: url(:/overlay/osk_button_shift.png);
+ qproperty-iconSize: 36px;
+}
+
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift {
+ background-position: left top;
+ background-repeat: no-repeat;
+ background-origin: content;
+ background-image: url(:/overlay/osk_button_shift_lock_off.png);
+ 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 {
+ background-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 {
+ background-image: url(:/overlay/osk_button_B_disabled.png);
+}
+
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:disabled,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:disabled {
+ background-image: url(:/overlay/osk_button_Y_disabled.png);
+}
diff --git a/dist/qt_themes/qdarkstyle/style.qss b/dist/qt_themes/qdarkstyle/style.qss
index 2a1e8ddeb..8ce6d75f7 100755
--- a/dist/qt_themes/qdarkstyle/style.qss
+++ b/dist/qt_themes/qdarkstyle/style.qss
@@ -1560,7 +1560,400 @@ QWidget#controllerPlayer8 {
background: transparent;
}
-/* touchscreen mapping widget */
-TouchScreenPreview {
- qproperty-dotHighlightColor: #3daee9;
+QDialog#QtSoftwareKeyboardDialog,
+QStackedWidget#topOSK {
+ background: rgba(41, 41, 41, .9);
+}
+
+
+QDialog#OverlayDialog,
+QStackedWidget#stackedDialog {
+ background: rgba(41, 41, 41, .7);
+}
+
+QWidget#boxOSK,
+QWidget#lineOSK,
+QWidget#richDialog,
+QWidget#lineDialog {
+ background: transparent;
+}
+
+QStackedWidget#bottomOSK,
+QWidget#contentDialog,
+QWidget#contentRichDialog {
+ background: rgba(71, 69, 71, 1);
+}
+
+QWidget#contentDialog,
+QWidget#contentRichDialog {
+ margin: 5px;
+ border-radius: 6px;
+}
+
+QWidget#buttonsDialog,
+QWidget#buttonsRichDialog {
+ margin: 5px;
+ border-top: 2px solid rgba(255, 255, 255, .9);
+}
+
+QWidget#legendOSKnum {
+ border-top: 1px solid rgba(255, 255, 255, 1);
+}
+
+QStackedWidget#stackedDialog QTextBrowser QWidget {
+ background: transparent;
+}
+
+QStackedWidget#stackedDialog QTextBrowser QScrollBar {
+ background: #2a2929;
+}
+
+QStackedWidget#stackedDialog QTextBrowser QScrollBar::sub-line,
+QStackedWidget#stackedDialog QTextBrowser QScrollBar::add-line {
+ border-image: none;
+}
+
+QWidget#inputOSK {
+ border-bottom: 3px solid rgba(255, 255, 255, .9);
+}
+
+QWidget#inputOSK QLineEdit {
+ background: transparent;
+ border: none;
+ color: #ccc;
+ padding: 0px;
+}
+
+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;
+ color: #fff;
+ padding: 35px 65px;
+}
+
+QWidget#lineOSK QLabel#label_header {
+ color: #f0f0f0;
+}
+
+QWidget#lineOSK QLabel#label_sub,
+QWidget#lineOSK QLabel#label_characters,
+QWidget#contentDialog QLabel#label_title,
+QWidget#contentRichDialog QLabel#label_title_rich,
+QWidget#boxOSK QLabel#label_characters_box {
+ color: #ccc;
+}
+
+QWidget#buttonsDialog,
+QWidget#buttonsRichDialog,
+QWidget#mainOSK,
+QWidget#headerOSK,
+QWidget#normalOSK,
+QWidget#shiftOSK,
+QWidget#numOSK,
+QWidget#subOSK,
+QWidget#inputOSK,
+QWidget#inputBoxOSK,
+QWidget#charactersOSK,
+QWidget#charactersBoxOSK,
+QWidget#legendOSK,
+QWidget#legendOSK QWidget,
+QWidget#legendOSKshift,
+QWidget#legendOSKshift QWidget,
+QWidget#legendOSKnum,
+QWidget#legendOSKnum QWidget {
+ background: transparent;
+}
+
+QWidget#contentDialog QLabel,
+QWidget#legendOSK QLabel,
+QWidget#legendOSKshift QLabel,
+QWidget#legendOSKnum QLabel {
+ color: rgba(255, 255, 255, 1);
+}
+
+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(1, 253, 201, 1);
+ background: transparent;
+ border: none;
+ padding: 0px;
+ min-width: 0px;
+}
+
+QDialog#OverlayDialog QPushButton:focus,
+QDialog#OverlayDialog QPushButton:hover {
+ color: rgba(1, 253, 201, 1);
+ background: rgba(58, 61, 66, 1);
+ border: 5px solid rgba(56, 189, 225, 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(56, 189, 225, 1);
+ border-radius: 6px;
+ outline: none;
+}
+
+QDialog#QtSoftwareKeyboardDialog QPushButton {
+ color: rgba(255, 255, 255, 1);
+ background: rgba(80, 79, 80, 1);
+ border: 2px solid rgba(71, 69, 71, 1);
+ padding: 0px;
+ min-width: 0px;
+}
+
+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(95, 94, 95, 1);
+ border: 2px solid rgba(71, 69, 71, 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(255, 255, 255, 1);
+ border: 2px solid rgba(71, 69, 71, 1);
+}
+
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num {
+ color: rgba(0, 0, 0, 1);
+ background: rgba(1, 253, 201, 1);
+ border: 2px solid rgba(71, 69, 71, 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(255, 255, 255, 1);
+ background: rgba(58, 61, 66, 1);
+ border: 5px solid rgba(56, 189, 225, 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(56, 189, 225, 1);
+ border-radius: 6px;
+}
+
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num {
+ background-position: right top;
+ background-repeat: no-repeat;
+ background-origin: content;
+ background-image: url(:/overlay/osk_button_B_dark.png);
+ qproperty-icon: url(:/overlay/osk_button_backspace_dark.png);
+ qproperty-iconSize: 36px;
+}
+
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_space,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift {
+ background-position: right top;
+ background-repeat: no-repeat;
+ background-origin: content;
+ background-image: url(:/overlay/osk_button_Y_dark.png);
+}
+
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num {
+ color: rgba(44, 44, 44, 1);
+ background-position: right top;
+ background-repeat: no-repeat;
+ background-origin: content;
+ background-image: url(:/overlay/osk_button_plus_dark.png);
+}
+
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift {
+ background-position: left top;
+ background-repeat: no-repeat;
+ background-origin: content;
+ background-image: url(:/overlay/osk_button_shift_lock_off.png);
+ qproperty-icon: url(:/overlay/osk_button_shift_dark.png);
+ qproperty-iconSize: 36px;
+}
+
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift {
+ background-position: left top;
+ background-repeat: no-repeat;
+ background-origin: content;
+ background-image: url(:/overlay/osk_button_shift_lock_off.png);
+ qproperty-icon: url(:/overlay/osk_button_shift_on_dark.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_dark.png);
+}
+
+QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left,
+QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left_shift,
+QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left_num {
+ image: url(:/overlay/arrow_left_dark.png);
+}
+
+QDialog#QtSoftwareKeyboardDialog QWidget#button_R,
+QDialog#QtSoftwareKeyboardDialog QWidget#button_R_shift,
+QDialog#QtSoftwareKeyboardDialog QWidget#button_R_num {
+ image: url(:/overlay/button_R_dark.png);
+}
+
+QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right,
+QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right_shift,
+QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right_num {
+ image: url(:/overlay/arrow_right_dark.png);
+}
+
+QDialog#QtSoftwareKeyboardDialog QWidget#button_press_stick,
+QDialog#QtSoftwareKeyboardDialog QWidget#button_press_stick_shift {
+ image: url(:/overlay/button_press_stick_dark.png);
+}
+
+QDialog#QtSoftwareKeyboardDialog QWidget#button_X,
+QDialog#QtSoftwareKeyboardDialog QWidget#button_X_shift,
+QDialog#QtSoftwareKeyboardDialog QWidget#button_X_num {
+ image: url(:/overlay/button_X_dark.png);
+}
+
+QDialog#QtSoftwareKeyboardDialog QWidget#button_A,
+QDialog#QtSoftwareKeyboardDialog QWidget#button_A_shift,
+QDialog#QtSoftwareKeyboardDialog QWidget#button_A_num {
+ image: url(:/overlay/button_A_dark.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(144, 144, 144, 1);
+ background-color: rgba(95, 94, 95, 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(144, 144, 144, 1);
+}
+
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:disabled,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:disabled,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:disabled {
+ background-image: url(:/overlay/osk_button_plus_dark_disabled.png);
+}
+
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:disabled,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:disabled,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:disabled {
+ background-image: url(:/overlay/osk_button_B_dark_disabled.png);
+}
+
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:disabled,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:disabled {
+ background-image: url(:/overlay/osk_button_Y_dark_disabled.png);
+}
+
+QDialog#QtSoftwareKeyboardDialog QFrame,
+QDialog#QtSoftwareKeyboardDialog QFrame[frameShape="0"],
+QDialog#OverlayDialog QFrame,
+QDialog#OverlayDialog QFrame[frameShape="0"] {
+ border-radius: 0px;
+ border: none;
}
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/style.qss b/dist/qt_themes/qdarkstyle_midnight_blue/style.qss
index a64037455..64e1ecbcc 100755
--- a/dist/qt_themes/qdarkstyle_midnight_blue/style.qss
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/style.qss
@@ -1,10 +1,10 @@
/* ---------------------------------------------------------------------------
- Created by the qtsass compiler v0.1.1
+ Created by the qtsass compiler v0.1.1
- The definitions are in the "qdarkstyle.qss._styles.scss" module
+ The definitions are in the "qdarkstyle.qss._styles.scss" module
- WARNING! All changes made in this file will be lost!
+ WARNING! All changes made in this file will be lost!
--------------------------------------------------------------------------- */
/* QDarkStyleSheet -----------------------------------------------------------
@@ -15,34 +15,34 @@ It is based on three selecting colors, three greyish (background) colors
plus three whitish (foreground) colors. Each set of widgets of the same
type have a header like this:
- ------------------
- GroupName --------
- ------------------
+ ------------------
+ GroupName --------
+ ------------------
And each widget is separated with a header like this:
- QWidgetName ------
+ QWidgetName ------
This makes more easy to find and change some css field. The basic
configuration is described bellow.
- BACKGROUND -----------
+ BACKGROUND -----------
- Light (unpressed)
- Normal (border, disabled, pressed, checked, toolbars, menus)
- Dark (background)
+ Light (unpressed)
+ Normal (border, disabled, pressed, checked, toolbars, menus)
+ Dark (background)
- FOREGROUND -----------
+ FOREGROUND -----------
- Light (texts/labels)
- Normal (not used yet)
- Dark (disabled texts)
+ Light (texts/labels)
+ Normal (not used yet)
+ Dark (disabled texts)
- SELECTION ------------
+ SELECTION ------------
- Light (selection/hover/active)
- Normal (selected)
- Dark (selected disabled)
+ Light (selection/hover/active)
+ Normal (selected)
+ Dark (selected disabled)
If a stranger configuration is required because of a bugfix or anything
else, keep the comment on the line above so nobody changes it, including the
@@ -2483,3 +2483,404 @@ QWidget#controllerPlayer7,
QWidget#controllerPlayer8 {
background: transparent;
}
+
+QDialog#QtSoftwareKeyboardDialog,
+QStackedWidget#topOSK {
+ background: rgba(15, 25, 34, .9);
+}
+
+QDialog#OverlayDialog,
+QStackedWidget#stackedDialog {
+ background: rgba(15, 25, 34, .7);
+}
+
+QWidget#boxOSK,
+QWidget#lineOSK,
+QWidget#richDialog,
+QWidget#lineDialog {
+ background: transparent;
+}
+
+QStackedWidget#bottomOSK,
+QWidget#contentDialog,
+QWidget#contentRichDialog {
+ background: rgba(31, 41, 51, 1);
+}
+
+QWidget#contentDialog,
+QWidget#contentRichDialog {
+ margin: 5px;
+ border-radius: 6px;
+}
+
+QWidget#buttonsDialog,
+QWidget#buttonsRichDialog {
+ margin: 5px;
+ border-top: 2px solid rgba(255, 255, 255, .9);
+}
+
+QWidget#legendOSKnum {
+ border-top: 1px solid rgba(255, 255, 255, 1);
+}
+
+QStackedWidget#stackedDialog QTextBrowser QWidget {
+ background: transparent;
+}
+
+QStackedWidget#stackedDialog QTextBrowser QScrollBar {
+ background: #19232d;
+ border: none;
+}
+
+QStackedWidget#stackedDialog QTextBrowser QScrollBar::sub-line,
+QStackedWidget#stackedDialog QTextBrowser QScrollBar::add-line {
+ border-image: none;
+}
+
+QWidget#mainOSK QStackedWidget,
+QDialog#OverlayDialog QStackedWidget {
+ border: none;
+ padding: 0px;
+}
+
+QWidget#inputOSK {
+ border-bottom: 3px solid rgba(255, 255, 255, .9);
+}
+
+QWidget#inputOSK QLineEdit {
+ background: transparent;
+ border: none;
+ color: #ccc;
+ padding: 0px;
+}
+
+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;
+ color: #fff;
+ padding: 35px 65px;
+}
+
+QWidget#lineOSK QLabel#label_header {
+ color: #f0f0f0;
+}
+
+QWidget#lineOSK QLabel#label_sub,
+QWidget#lineOSK QLabel#label_characters,
+QWidget#contentDialog QLabel#label_title,
+QWidget#contentRichDialog QLabel#label_title_rich,
+QWidget#boxOSK QLabel#label_characters_box {
+ color: #ccc;
+}
+
+QWidget#buttonsDialog,
+QWidget#buttonsRichDialog,
+QWidget#mainOSK,
+QWidget#headerOSK,
+QWidget#normalOSK,
+QWidget#shiftOSK,
+QWidget#numOSK,
+QWidget#subOSK,
+QWidget#inputOSK,
+QWidget#inputBoxOSK,
+QWidget#charactersOSK,
+QWidget#charactersBoxOSK,
+QWidget#legendOSK,
+QWidget#legendOSK QWidget,
+QWidget#legendOSKshift,
+QWidget#legendOSKshift QWidget,
+QWidget#legendOSKnum,
+QWidget#legendOSKnum QWidget {
+ background: transparent;
+}
+
+QWidget#contentDialog QLabel,
+QWidget#legendOSK QLabel,
+QWidget#legendOSKshift QLabel,
+QWidget#legendOSKnum QLabel {
+ color: rgba(255, 255, 255, 1);
+}
+
+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(1, 253, 201, 1);
+ background: transparent;
+ border: none;
+ padding: 0px;
+ min-width: 0px;
+}
+
+QDialog#OverlayDialog QPushButton:focus,
+QDialog#OverlayDialog QPushButton:hover {
+ color: rgba(1, 253, 201, 1);
+ background: rgba(18, 33, 46, 1);
+ border: 5px solid rgba(56, 189, 225, 1);
+ border-radius: 6px;
+ outline: none;
+}
+
+QDialog#OverlayDialog QPushButton:pressed {
+ color: rgba(240, 240, 240, 1);
+ background: rgba(110, 122, 130, 1);
+ border: 5px solid rgba(56, 189, 225, 1);
+ border-radius: 6px;
+ outline: none;
+}
+
+QDialog#QtSoftwareKeyboardDialog QLabel {
+ padding: 0px;
+}
+
+QDialog#QtSoftwareKeyboardDialog QPushButton {
+ color: rgba(255, 255, 255, 1);
+ background: rgba(40, 51, 60, 1);
+ border: 2px solid rgba(31, 41, 51, 1);
+ border-radius: 0px;
+ padding: 0px;
+ min-width: 0px;
+}
+
+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(55, 66, 75, 1);
+ border: 2px solid rgba(31, 41, 51, 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(255, 255, 255, 1);
+ border: 2px solid rgba(31, 41, 51, 1);
+}
+
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num {
+ color: rgba(0, 0, 0, 1);
+ background: rgba(1, 253, 201, 1);
+ border: 2px solid rgba(31, 41, 51, 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(255, 255, 255, 1);
+ background: rgba(18, 33, 46, 1);
+ border: 5px solid rgba(56, 189, 225, 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(110, 122, 130, 1);
+ border: 5px solid rgba(56, 189, 225, 1);
+ border-radius: 6px;
+}
+
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num {
+ background-position: right top;
+ background-repeat: no-repeat;
+ background-origin: content;
+ background-image: url(:/overlay/osk_button_B_dark.png);
+ qproperty-icon: url(:/overlay/osk_button_backspace_dark.png);
+ qproperty-iconSize: 36px;
+}
+
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_space,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift {
+ background-position: right top;
+ background-repeat: no-repeat;
+ background-origin: content;
+ background-image: url(:/overlay/osk_button_Y_dark.png);
+}
+
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num {
+ color: rgba(44, 44, 44, 1);
+ background-position: right top;
+ background-repeat: no-repeat;
+ background-origin: content;
+ background-image: url(:/overlay/osk_button_plus_dark.png);
+}
+
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift {
+ background-position: left top;
+ background-repeat: no-repeat;
+ background-origin: content;
+ background-image: url(:/overlay/osk_button_shift_lock_off.png);
+ qproperty-icon: url(:/overlay/osk_button_shift_dark.png);
+ qproperty-iconSize: 36px;
+}
+
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_shift_shift {
+ background-position: left top;
+ background-repeat: no-repeat;
+ background-origin: content;
+ background-image: url(:/overlay/osk_button_shift_lock_off.png);
+ qproperty-icon: url(:/overlay/osk_button_shift_on_dark.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_dark.png);
+}
+
+QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left,
+QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left_shift,
+QDialog#QtSoftwareKeyboardDialog QWidget#arrow_left_num {
+ image: url(:/overlay/arrow_left_dark.png);
+}
+
+QDialog#QtSoftwareKeyboardDialog QWidget#button_R,
+QDialog#QtSoftwareKeyboardDialog QWidget#button_R_shift,
+QDialog#QtSoftwareKeyboardDialog QWidget#button_R_num {
+ image: url(:/overlay/button_R_dark.png);
+}
+
+QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right,
+QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right_shift,
+QDialog#QtSoftwareKeyboardDialog QWidget#arrow_right_num {
+ image: url(:/overlay/arrow_right_dark.png);
+}
+
+QDialog#QtSoftwareKeyboardDialog QWidget#button_press_stick,
+QDialog#QtSoftwareKeyboardDialog QWidget#button_press_stick_shift {
+ image: url(:/overlay/button_press_stick_dark.png);
+}
+
+QDialog#QtSoftwareKeyboardDialog QWidget#button_X,
+QDialog#QtSoftwareKeyboardDialog QWidget#button_X_shift,
+QDialog#QtSoftwareKeyboardDialog QWidget#button_X_num {
+ image: url(:/overlay/button_X_dark.png);
+}
+
+QDialog#QtSoftwareKeyboardDialog QWidget#button_A,
+QDialog#QtSoftwareKeyboardDialog QWidget#button_A_shift,
+QDialog#QtSoftwareKeyboardDialog QWidget#button_A_num {
+ image: url(:/overlay/button_A_dark.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(144, 144, 144, 1);
+ background-color: rgba(55, 66, 75, 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(144, 144, 144, 1);
+}
+
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok:disabled,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_shift:disabled,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_ok_num:disabled {
+ background-image: url(:/overlay/osk_button_plus_dark_disabled.png);
+}
+
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace:disabled,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_shift:disabled,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_backspace_num:disabled {
+ background-image: url(:/overlay/osk_button_B_dark_disabled.png);
+}
+
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_space:disabled,
+QDialog#QtSoftwareKeyboardDialog QPushButton#button_space_shift:disabled {
+ background-image: url(:/overlay/osk_button_Y_dark_disabled.png);
+}
diff --git a/dist/yuzu.ico b/dist/yuzu.ico
index df3be8464..7c998a5c5 100755
Binary files a/dist/yuzu.ico and b/dist/yuzu.ico differ
diff --git a/dist/yuzu.svg b/dist/yuzu.svg
index 93171d1bf..98ded2d8f 100755
--- a/dist/yuzu.svg
+++ b/dist/yuzu.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 788516ded..7253c0f4d 100755
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -109,6 +109,7 @@ add_library(common STATIC
cityhash.h
common_funcs.h
common_paths.h
+ common_sizes.h
common_types.h
concepts.h
div_ceil.h
diff --git a/src/common/assert.h b/src/common/assert.h
index 06d7b5612..48c09b530 100755
--- a/src/common/assert.h
+++ b/src/common/assert.h
@@ -29,22 +29,19 @@ assert_noinline_call(const Fn& fn) {
}
#define ASSERT(_a_) \
- do \
- if (!(_a_)) { \
- assert_noinline_call([] { LOG_CRITICAL(Debug, "Assertion Failed!"); }); \
- } \
- while (0)
+ if (!(_a_)) { \
+ LOG_CRITICAL(Debug, "Assertion Failed!"); \
+ }
#define ASSERT_MSG(_a_, ...) \
- do \
- if (!(_a_)) { \
- assert_noinline_call([&] { LOG_CRITICAL(Debug, "Assertion Failed!\n" __VA_ARGS__); }); \
- } \
- while (0)
+ if (!(_a_)) { \
+ LOG_CRITICAL(Debug, "Assertion Failed! " __VA_ARGS__); \
+ }
-#define UNREACHABLE() assert_noinline_call([] { LOG_CRITICAL(Debug, "Unreachable code!"); })
+#define UNREACHABLE() \
+ { LOG_CRITICAL(Debug, "Unreachable code!"); }
#define UNREACHABLE_MSG(...) \
- assert_noinline_call([&] { LOG_CRITICAL(Debug, "Unreachable code!\n" __VA_ARGS__); })
+ { LOG_CRITICAL(Debug, "Unreachable code!\n" __VA_ARGS__); }
#ifdef _DEBUG
#define DEBUG_ASSERT(_a_) ASSERT(_a_)
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 17f251c37..a81d30032 100755
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -141,6 +141,9 @@ add_library(core STATIC
hardware_interrupt_manager.h
hle/ipc.h
hle/ipc_helpers.h
+ hle/kernel/board/nintendo/nx/k_system_control.cpp
+ hle/kernel/board/nintendo/nx/k_system_control.h
+ hle/kernel/board/nintendo/nx/secure_monitor.h
hle/kernel/client_port.cpp
hle/kernel/client_port.h
hle/kernel/client_session.cpp
@@ -169,9 +172,13 @@ add_library(core STATIC
hle/kernel/k_memory_block.h
hle/kernel/k_memory_block_manager.cpp
hle/kernel/k_memory_block_manager.h
+ hle/kernel/k_memory_layout.cpp
+ hle/kernel/k_memory_layout.board.nintendo_nx.cpp
hle/kernel/k_memory_layout.h
hle/kernel/k_memory_manager.cpp
hle/kernel/k_memory_manager.h
+ hle/kernel/k_memory_region.h
+ hle/kernel/k_memory_region_type.h
hle/kernel/k_page_bitmap.h
hle/kernel/k_page_heap.cpp
hle/kernel/k_page_heap.h
@@ -196,11 +203,11 @@ add_library(core STATIC
hle/kernel/k_spin_lock.h
hle/kernel/k_synchronization_object.cpp
hle/kernel/k_synchronization_object.h
- hle/kernel/k_system_control.cpp
hle/kernel/k_system_control.h
hle/kernel/k_thread.cpp
hle/kernel/k_thread.h
hle/kernel/k_thread_queue.h
+ hle/kernel/k_trace.h
hle/kernel/k_writable_event.cpp
hle/kernel/k_writable_event.h
hle/kernel/kernel.cpp
@@ -264,6 +271,7 @@ add_library(core STATIC
hle/service/am/applets/general_backend.h
hle/service/am/applets/profile_select.cpp
hle/service/am/applets/profile_select.h
+ hle/service/am/applets/software_keyboard_types.h
hle/service/am/applets/software_keyboard.cpp
hle/service/am/applets/software_keyboard.h
hle/service/am/applets/web_browser.cpp
diff --git a/src/core/file_sys/control_metadata.cpp b/src/core/file_sys/control_metadata.cpp
index b0a130345..f66759815 100755
--- a/src/core/file_sys/control_metadata.cpp
+++ b/src/core/file_sys/control_metadata.cpp
@@ -100,6 +100,14 @@ u64 NACP::GetDeviceSaveDataSize() const {
return raw.device_save_data_size;
}
+u32 NACP::GetParentalControlFlag() const {
+ return raw.parental_control;
+}
+
+const std::array& NACP::GetRatingAge() const {
+ return raw.rating_age;
+}
+
std::vector NACP::GetRawBytes() const {
std::vector out(sizeof(RawNACP));
std::memcpy(out.data(), &raw, sizeof(RawNACP));
diff --git a/src/core/file_sys/control_metadata.h b/src/core/file_sys/control_metadata.h
index 403c4219a..dd9837cf5 100755
--- a/src/core/file_sys/control_metadata.h
+++ b/src/core/file_sys/control_metadata.h
@@ -114,6 +114,8 @@ public:
std::vector GetRawBytes() const;
bool GetUserAccountSwitchLock() const;
u64 GetDeviceSaveDataSize() const;
+ u32 GetParentalControlFlag() const;
+ const std::array& GetRatingAge() const;
private:
RawNACP raw{};
diff --git a/src/core/frontend/applets/software_keyboard.cpp b/src/core/frontend/applets/software_keyboard.cpp
index 856ed33da..12c76c9ee 100755
--- a/src/core/frontend/applets/software_keyboard.cpp
+++ b/src/core/frontend/applets/software_keyboard.cpp
@@ -1,29 +1,149 @@
-// Copyright 2018 yuzu emulator team
+// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#include "common/logging/backend.h"
+#include
+
+#include "common/logging/log.h"
#include "common/string_util.h"
#include "core/frontend/applets/software_keyboard.h"
namespace Core::Frontend {
+
SoftwareKeyboardApplet::~SoftwareKeyboardApplet() = default;
-void DefaultSoftwareKeyboardApplet::RequestText(
- std::function)> out,
- SoftwareKeyboardParameters parameters) const {
- if (parameters.initial_text.empty())
- out(u"yuzu");
+DefaultSoftwareKeyboardApplet::~DefaultSoftwareKeyboardApplet() = default;
- out(parameters.initial_text);
+void DefaultSoftwareKeyboardApplet::InitializeKeyboard(
+ bool is_inline, KeyboardInitializeParameters initialize_parameters,
+ std::function submit_normal_callback_,
+ std::function
+ submit_inline_callback_) {
+ if (is_inline) {
+ LOG_WARNING(
+ Service_AM,
+ "(STUBBED) called, backend requested to initialize the inline software keyboard.");
+
+ submit_inline_callback = std::move(submit_inline_callback_);
+ } else {
+ LOG_WARNING(
+ Service_AM,
+ "(STUBBED) called, backend requested to initialize the normal software keyboard.");
+
+ submit_normal_callback = std::move(submit_normal_callback_);
+ }
+
+ parameters = std::move(initialize_parameters);
+
+ LOG_INFO(Service_AM,
+ "\nKeyboardInitializeParameters:"
+ "\nok_text={}"
+ "\nheader_text={}"
+ "\nsub_text={}"
+ "\nguide_text={}"
+ "\ninitial_text={}"
+ "\nmax_text_length={}"
+ "\nmin_text_length={}"
+ "\ninitial_cursor_position={}"
+ "\ntype={}"
+ "\npassword_mode={}"
+ "\ntext_draw_type={}"
+ "\nkey_disable_flags={}"
+ "\nuse_blur_background={}"
+ "\nenable_backspace_button={}"
+ "\nenable_return_button={}"
+ "\ndisable_cancel_button={}",
+ Common::UTF16ToUTF8(parameters.ok_text), Common::UTF16ToUTF8(parameters.header_text),
+ Common::UTF16ToUTF8(parameters.sub_text), Common::UTF16ToUTF8(parameters.guide_text),
+ Common::UTF16ToUTF8(parameters.initial_text), parameters.max_text_length,
+ parameters.min_text_length, parameters.initial_cursor_position, parameters.type,
+ parameters.password_mode, parameters.text_draw_type, parameters.key_disable_flags.raw,
+ parameters.use_blur_background, parameters.enable_backspace_button,
+ parameters.enable_return_button, parameters.disable_cancel_button);
}
-void DefaultSoftwareKeyboardApplet::SendTextCheckDialog(
- std::u16string error_message, std::function finished_check) const {
+void DefaultSoftwareKeyboardApplet::ShowNormalKeyboard() const {
LOG_WARNING(Service_AM,
- "(STUBBED) called - Default fallback software keyboard does not support text "
- "check! (error_message={})",
- Common::UTF16ToUTF8(error_message));
- finished_check();
+ "(STUBBED) called, backend requested to show the normal software keyboard.");
+
+ SubmitNormalText(u"yuzu");
}
+
+void DefaultSoftwareKeyboardApplet::ShowTextCheckDialog(
+ Service::AM::Applets::SwkbdTextCheckResult text_check_result,
+ std::u16string text_check_message) const {
+ LOG_WARNING(Service_AM, "(STUBBED) called, backend requested to show the text check dialog.");
+}
+
+void DefaultSoftwareKeyboardApplet::ShowInlineKeyboard(
+ InlineAppearParameters appear_parameters) const {
+ LOG_WARNING(Service_AM,
+ "(STUBBED) called, backend requested to show the inline software keyboard.");
+
+ LOG_INFO(Service_AM,
+ "\nInlineAppearParameters:"
+ "\nmax_text_length={}"
+ "\nmin_text_length={}"
+ "\nkey_top_scale_x={}"
+ "\nkey_top_scale_y={}"
+ "\nkey_top_translate_x={}"
+ "\nkey_top_translate_y={}"
+ "\ntype={}"
+ "\nkey_disable_flags={}"
+ "\nkey_top_as_floating={}"
+ "\nenable_backspace_button={}"
+ "\nenable_return_button={}"
+ "\ndisable_cancel_button={}",
+ appear_parameters.max_text_length, appear_parameters.min_text_length,
+ appear_parameters.key_top_scale_x, appear_parameters.key_top_scale_y,
+ appear_parameters.key_top_translate_x, appear_parameters.key_top_translate_y,
+ appear_parameters.type, appear_parameters.key_disable_flags.raw,
+ appear_parameters.key_top_as_floating, appear_parameters.enable_backspace_button,
+ appear_parameters.enable_return_button, appear_parameters.disable_cancel_button);
+
+ std::thread([this] { SubmitInlineText(u"yuzu"); }).detach();
+}
+
+void DefaultSoftwareKeyboardApplet::HideInlineKeyboard() const {
+ LOG_WARNING(Service_AM,
+ "(STUBBED) called, backend requested to hide the inline software keyboard.");
+}
+
+void DefaultSoftwareKeyboardApplet::InlineTextChanged(InlineTextParameters text_parameters) const {
+ LOG_WARNING(Service_AM,
+ "(STUBBED) called, backend requested to change the inline keyboard text.");
+
+ LOG_INFO(Service_AM,
+ "\nInlineTextParameters:"
+ "\ninput_text={}"
+ "\ncursor_position={}",
+ Common::UTF16ToUTF8(text_parameters.input_text), text_parameters.cursor_position);
+
+ submit_inline_callback(Service::AM::Applets::SwkbdReplyType::ChangedString,
+ text_parameters.input_text, text_parameters.cursor_position);
+}
+
+void DefaultSoftwareKeyboardApplet::ExitKeyboard() const {
+ LOG_WARNING(Service_AM, "(STUBBED) called, backend requested to exit the software keyboard.");
+}
+
+void DefaultSoftwareKeyboardApplet::SubmitNormalText(std::u16string text) const {
+ submit_normal_callback(Service::AM::Applets::SwkbdResult::Ok, text);
+}
+
+void DefaultSoftwareKeyboardApplet::SubmitInlineText(std::u16string_view text) const {
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+
+ for (std::size_t index = 0; index < text.size(); ++index) {
+ submit_inline_callback(Service::AM::Applets::SwkbdReplyType::ChangedString,
+ std::u16string(text.data(), text.data() + index + 1),
+ static_cast(index) + 1);
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(250));
+ }
+
+ submit_inline_callback(Service::AM::Applets::SwkbdReplyType::DecidedEnter, std::u16string(text),
+ static_cast(text.size()));
+}
+
} // namespace Core::Frontend
diff --git a/src/core/frontend/applets/software_keyboard.h b/src/core/frontend/applets/software_keyboard.h
index f9b202664..506eb35bb 100755
--- a/src/core/frontend/applets/software_keyboard.h
+++ b/src/core/frontend/applets/software_keyboard.h
@@ -1,54 +1,116 @@
-// Copyright 2018 yuzu emulator team
+// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include
-#include
-#include
-#include "common/bit_field.h"
+#include
+
#include "common/common_types.h"
+#include "core/hle/service/am/applets/software_keyboard_types.h"
+
namespace Core::Frontend {
-struct SoftwareKeyboardParameters {
- std::u16string submit_text;
+
+struct KeyboardInitializeParameters {
+ std::u16string ok_text;
std::u16string header_text;
std::u16string sub_text;
std::u16string guide_text;
std::u16string initial_text;
- std::size_t max_length;
- bool password;
- bool cursor_at_beginning;
+ u32 max_text_length;
+ u32 min_text_length;
+ s32 initial_cursor_position;
+ Service::AM::Applets::SwkbdType type;
+ Service::AM::Applets::SwkbdPasswordMode password_mode;
+ Service::AM::Applets::SwkbdTextDrawType text_draw_type;
+ Service::AM::Applets::SwkbdKeyDisableFlags key_disable_flags;
+ bool use_blur_background;
+ bool enable_backspace_button;
+ bool enable_return_button;
+ bool disable_cancel_button;
+};
- union {
- u8 value;
+struct InlineAppearParameters {
+ u32 max_text_length;
+ u32 min_text_length;
+ f32 key_top_scale_x;
+ f32 key_top_scale_y;
+ f32 key_top_translate_x;
+ f32 key_top_translate_y;
+ Service::AM::Applets::SwkbdType type;
+ Service::AM::Applets::SwkbdKeyDisableFlags key_disable_flags;
+ bool key_top_as_floating;
+ bool enable_backspace_button;
+ bool enable_return_button;
+ bool disable_cancel_button;
+};
- BitField<1, 1, u8> disable_space;
- BitField<2, 1, u8> disable_address;
- BitField<3, 1, u8> disable_percent;
- BitField<4, 1, u8> disable_slash;
- BitField<6, 1, u8> disable_number;
- BitField<7, 1, u8> disable_download_code;
- };
+struct InlineTextParameters {
+ std::u16string input_text;
+ s32 cursor_position;
};
class SoftwareKeyboardApplet {
public:
virtual ~SoftwareKeyboardApplet();
- virtual void RequestText(std::function)> out,
- SoftwareKeyboardParameters parameters) const = 0;
- virtual void SendTextCheckDialog(std::u16string error_message,
- std::function finished_check) const = 0;
+ virtual void InitializeKeyboard(
+ bool is_inline, KeyboardInitializeParameters initialize_parameters,
+ std::function
+ submit_normal_callback_,
+ std::function
+ submit_inline_callback_) = 0;
+
+ virtual void ShowNormalKeyboard() const = 0;
+
+ virtual void ShowTextCheckDialog(Service::AM::Applets::SwkbdTextCheckResult text_check_result,
+ std::u16string text_check_message) const = 0;
+
+ virtual void ShowInlineKeyboard(InlineAppearParameters appear_parameters) const = 0;
+
+ virtual void HideInlineKeyboard() const = 0;
+
+ virtual void InlineTextChanged(InlineTextParameters text_parameters) const = 0;
+
+ virtual void ExitKeyboard() const = 0;
};
class DefaultSoftwareKeyboardApplet final : public SoftwareKeyboardApplet {
public:
- void RequestText(std::function)> out,
- SoftwareKeyboardParameters parameters) const override;
- void SendTextCheckDialog(std::u16string error_message,
- std::function finished_check) const override;
+ ~DefaultSoftwareKeyboardApplet() override;
+
+ void InitializeKeyboard(
+ bool is_inline, KeyboardInitializeParameters initialize_parameters,
+ std::function
+ submit_normal_callback_,
+ std::function
+ submit_inline_callback_) override;
+
+ void ShowNormalKeyboard() const override;
+
+ void ShowTextCheckDialog(Service::AM::Applets::SwkbdTextCheckResult text_check_result,
+ std::u16string text_check_message) const override;
+
+ void ShowInlineKeyboard(InlineAppearParameters appear_parameters) const override;
+
+ void HideInlineKeyboard() const override;
+
+ void InlineTextChanged(InlineTextParameters text_parameters) const override;
+
+ void ExitKeyboard() const override;
+
+private:
+ void SubmitNormalText(std::u16string text) const;
+ void SubmitInlineText(std::u16string_view text) const;
+
+ KeyboardInitializeParameters parameters;
+
+ mutable std::function
+ submit_normal_callback;
+ mutable std::function
+ submit_inline_callback;
};
} // namespace Core::Frontend
diff --git a/src/core/frontend/input_interpreter.cpp b/src/core/frontend/input_interpreter.cpp
index ec5fe660e..9f6a90e8f 100755
--- a/src/core/frontend/input_interpreter.cpp
+++ b/src/core/frontend/input_interpreter.cpp
@@ -12,7 +12,9 @@ InputInterpreter::InputInterpreter(Core::System& system)
: npad{system.ServiceManager()
.GetService("hid")
->GetAppletResource()
- ->GetController(Service::HID::HidController::NPad)} {}
+ ->GetController(Service::HID::HidController::NPad)} {
+ ResetButtonStates();
+}
InputInterpreter::~InputInterpreter() = default;
@@ -25,6 +27,17 @@ void InputInterpreter::PollInput() {
button_states[current_index] = button_state;
}
+void InputInterpreter::ResetButtonStates() {
+ previous_index = 0;
+ current_index = 0;
+
+ button_states[0] = 0xFFFFFFFF;
+
+ for (std::size_t i = 1; i < button_states.size(); ++i) {
+ button_states[i] = 0;
+ }
+}
+
bool InputInterpreter::IsButtonPressed(HIDButton button) const {
return (button_states[current_index] & (1U << static_cast(button))) != 0;
}
diff --git a/src/core/frontend/input_interpreter.h b/src/core/frontend/input_interpreter.h
index 73fc47ffb..9495e3daf 100755
--- a/src/core/frontend/input_interpreter.h
+++ b/src/core/frontend/input_interpreter.h
@@ -66,6 +66,9 @@ public:
/// Gets a button state from HID and inserts it into the array of button states.
void PollInput();
+ /// Resets all the button states to their defaults.
+ void ResetButtonStates();
+
/**
* Checks whether the button is pressed.
*
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index 161d9f782..2b363b1d9 100755
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -75,10 +75,14 @@ void HLERequestContext::ParseCommandBuffer(const HandleTable& handle_table, u32_
if (incoming) {
// Populate the object lists with the data in the IPC request.
for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_copy; ++handle) {
- copy_objects.push_back(handle_table.GetGeneric(rp.Pop()));
+ const u32 copy_handle{rp.Pop()};
+ copy_handles.push_back(copy_handle);
+ copy_objects.push_back(handle_table.GetGeneric(copy_handle));
}
for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_move; ++handle) {
- move_objects.push_back(handle_table.GetGeneric(rp.Pop()));
+ const u32 move_handle{rp.Pop()};
+ move_handles.push_back(move_handle);
+ move_objects.push_back(handle_table.GetGeneric(move_handle));
}
} else {
// For responses we just ignore the handles, they're empty and will be populated when
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h
index 9a769781b..6fba42615 100755
--- a/src/core/hle/kernel/hle_ipc.h
+++ b/src/core/hle/kernel/hle_ipc.h
@@ -210,6 +210,14 @@ public:
/// Helper function to test whether the output buffer at buffer_index can be written
bool CanWriteBuffer(std::size_t buffer_index = 0) const;
+ Handle GetCopyHandle(std::size_t index) const {
+ return copy_handles.at(index);
+ }
+
+ Handle GetMoveHandle(std::size_t index) const {
+ return move_handles.at(index);
+ }
+
template
std::shared_ptr GetCopyObject(std::size_t index) {
return DynamicObjectCast(copy_objects.at(index));
@@ -285,6 +293,8 @@ private:
std::shared_ptr server_session;
std::shared_ptr thread;
// TODO(yuriks): Check common usage of this and optimize size accordingly
+ boost::container::small_vector move_handles;
+ boost::container::small_vector copy_handles;
boost::container::small_vector, 8> move_objects;
boost::container::small_vector, 8> copy_objects;
boost::container::small_vector, 8> domain_objects;
diff --git a/src/core/hle/kernel/k_address_space_info.cpp b/src/core/hle/kernel/k_address_space_info.cpp
index 24944d15b..c7549f7a2 100755
--- a/src/core/hle/kernel/k_address_space_info.cpp
+++ b/src/core/hle/kernel/k_address_space_info.cpp
@@ -5,45 +5,34 @@
#include
#include "common/assert.h"
+#include "common/common_sizes.h"
#include "core/hle/kernel/k_address_space_info.h"
namespace Kernel {
namespace {
-enum : u64 {
- Size_1_MB = 0x100000,
- Size_2_MB = 2 * Size_1_MB,
- Size_128_MB = 128 * Size_1_MB,
- Size_1_GB = 0x40000000,
- Size_2_GB = 2 * Size_1_GB,
- Size_4_GB = 4 * Size_1_GB,
- Size_6_GB = 6 * Size_1_GB,
- Size_64_GB = 64 * Size_1_GB,
- Size_512_GB = 512 * Size_1_GB,
- Invalid = std::numeric_limits::max(),
-};
-
// clang-format off
constexpr std::array AddressSpaceInfos{{
- { .bit_width = 32, .address = Size_2_MB , .size = Size_1_GB - Size_2_MB , .type = KAddressSpaceInfo::Type::MapSmall, },
- { .bit_width = 32, .address = Size_1_GB , .size = Size_4_GB - Size_1_GB , .type = KAddressSpaceInfo::Type::MapLarge, },
- { .bit_width = 32, .address = Invalid , .size = Size_1_GB , .type = KAddressSpaceInfo::Type::Heap, },
- { .bit_width = 32, .address = Invalid , .size = Size_1_GB , .type = KAddressSpaceInfo::Type::Alias, },
- { .bit_width = 36, .address = Size_128_MB, .size = Size_2_GB - Size_128_MB, .type = KAddressSpaceInfo::Type::MapSmall, },
- { .bit_width = 36, .address = Size_2_GB , .size = Size_64_GB - Size_2_GB , .type = KAddressSpaceInfo::Type::MapLarge, },
- { .bit_width = 36, .address = Invalid , .size = Size_6_GB , .type = KAddressSpaceInfo::Type::Heap, },
- { .bit_width = 36, .address = Invalid , .size = Size_6_GB , .type = KAddressSpaceInfo::Type::Alias, },
- { .bit_width = 39, .address = Size_128_MB, .size = Size_512_GB - Size_128_MB, .type = KAddressSpaceInfo::Type::Map39Bit, },
- { .bit_width = 39, .address = Invalid , .size = Size_64_GB , .type = KAddressSpaceInfo::Type::MapSmall },
- { .bit_width = 39, .address = Invalid , .size = Size_6_GB , .type = KAddressSpaceInfo::Type::Heap, },
- { .bit_width = 39, .address = Invalid , .size = Size_64_GB , .type = KAddressSpaceInfo::Type::Alias, },
- { .bit_width = 39, .address = Invalid , .size = Size_2_GB , .type = KAddressSpaceInfo::Type::Stack, },
+ { .bit_width = 32, .address = Common::Size_2_MB , .size = Common::Size_1_GB - Common::Size_2_MB , .type = KAddressSpaceInfo::Type::MapSmall, },
+ { .bit_width = 32, .address = Common::Size_1_GB , .size = Common::Size_4_GB - Common::Size_1_GB , .type = KAddressSpaceInfo::Type::MapLarge, },
+ { .bit_width = 32, .address = Common::Size_Invalid, .size = Common::Size_1_GB , .type = KAddressSpaceInfo::Type::Alias, },
+ { .bit_width = 32, .address = Common::Size_Invalid, .size = Common::Size_1_GB , .type = KAddressSpaceInfo::Type::Heap, },
+ { .bit_width = 36, .address = Common::Size_128_MB , .size = Common::Size_2_GB - Common::Size_128_MB, .type = KAddressSpaceInfo::Type::MapSmall, },
+ { .bit_width = 36, .address = Common::Size_2_GB , .size = Common::Size_64_GB - Common::Size_2_GB , .type = KAddressSpaceInfo::Type::MapLarge, },
+ { .bit_width = 36, .address = Common::Size_Invalid, .size = Common::Size_6_GB , .type = KAddressSpaceInfo::Type::Heap, },
+ { .bit_width = 36, .address = Common::Size_Invalid, .size = Common::Size_6_GB , .type = KAddressSpaceInfo::Type::Alias, },
+ { .bit_width = 39, .address = Common::Size_128_MB , .size = Common::Size_512_GB - Common::Size_128_MB, .type = KAddressSpaceInfo::Type::Map39Bit, },
+ { .bit_width = 39, .address = Common::Size_Invalid, .size = Common::Size_64_GB , .type = KAddressSpaceInfo::Type::MapSmall },
+ { .bit_width = 39, .address = Common::Size_Invalid, .size = Common::Size_6_GB , .type = KAddressSpaceInfo::Type::Heap, },
+ { .bit_width = 39, .address = Common::Size_Invalid, .size = Common::Size_64_GB , .type = KAddressSpaceInfo::Type::Alias, },
+ { .bit_width = 39, .address = Common::Size_Invalid, .size = Common::Size_2_GB , .type = KAddressSpaceInfo::Type::Stack, },
}};
// clang-format on
constexpr bool IsAllowedIndexForAddress(std::size_t index) {
- return index < AddressSpaceInfos.size() && AddressSpaceInfos[index].address != Invalid;
+ return index < AddressSpaceInfos.size() &&
+ AddressSpaceInfos[index].address != Common::Size_Invalid;
}
using IndexArray =
diff --git a/src/core/hle/kernel/k_memory_layout.h b/src/core/hle/kernel/k_memory_layout.h
index 0821d2d8c..288642d9a 100755
--- a/src/core/hle/kernel/k_memory_layout.h
+++ b/src/core/hle/kernel/k_memory_layout.h
@@ -1,23 +1,69 @@
-// Copyright 2020 yuzu Emulator Project
+// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
+#include
+
+#include "common/alignment.h"
+#include "common/common_sizes.h"
#include "common/common_types.h"
#include "core/device_memory.h"
+#include "core/hle/kernel/k_memory_region.h"
+#include "core/hle/kernel/k_memory_region_type.h"
+#include "core/hle/kernel/memory_types.h"
namespace Kernel {
-constexpr std::size_t KernelAslrAlignment = 2 * 1024 * 1024;
+constexpr std::size_t L1BlockSize = Common::Size_1_GB;
+constexpr std::size_t L2BlockSize = Common::Size_2_MB;
+
+constexpr std::size_t GetMaximumOverheadSize(std::size_t size) {
+ return (Common::DivideUp(size, L1BlockSize) + Common::DivideUp(size, L2BlockSize)) * PageSize;
+}
+
+constexpr std::size_t MainMemorySize = Common::Size_4_GB;
+constexpr std::size_t MainMemorySizeMax = Common::Size_8_GB;
+
+constexpr std::size_t ReservedEarlyDramSize = 0x60000;
+constexpr std::size_t DramPhysicalAddress = 0x80000000;
+
+constexpr std::size_t KernelAslrAlignment = Common::Size_2_MB;
constexpr std::size_t KernelVirtualAddressSpaceWidth = 1ULL << 39;
constexpr std::size_t KernelPhysicalAddressSpaceWidth = 1ULL << 48;
+
constexpr std::size_t KernelVirtualAddressSpaceBase = 0ULL - KernelVirtualAddressSpaceWidth;
constexpr std::size_t KernelVirtualAddressSpaceEnd =
KernelVirtualAddressSpaceBase + (KernelVirtualAddressSpaceWidth - KernelAslrAlignment);
-constexpr std::size_t KernelVirtualAddressSpaceLast = KernelVirtualAddressSpaceEnd - 1;
+constexpr std::size_t KernelVirtualAddressSpaceLast = KernelVirtualAddressSpaceEnd - 1ULL;
constexpr std::size_t KernelVirtualAddressSpaceSize =
KernelVirtualAddressSpaceEnd - KernelVirtualAddressSpaceBase;
+constexpr std::size_t KernelVirtualAddressCodeBase = KernelVirtualAddressSpaceBase;
+constexpr std::size_t KernelVirtualAddressCodeSize = 0x62000;
+constexpr std::size_t KernelVirtualAddressCodeEnd =
+ KernelVirtualAddressCodeBase + KernelVirtualAddressCodeSize;
+
+constexpr std::size_t KernelPhysicalAddressSpaceBase = 0ULL;
+constexpr std::size_t KernelPhysicalAddressSpaceEnd =
+ KernelPhysicalAddressSpaceBase + KernelPhysicalAddressSpaceWidth;
+constexpr std::size_t KernelPhysicalAddressSpaceLast = KernelPhysicalAddressSpaceEnd - 1ULL;
+constexpr std::size_t KernelPhysicalAddressSpaceSize =
+ KernelPhysicalAddressSpaceEnd - KernelPhysicalAddressSpaceBase;
+constexpr std::size_t KernelPhysicalAddressCodeBase = DramPhysicalAddress + ReservedEarlyDramSize;
+
+constexpr std::size_t KernelPageTableHeapSize = GetMaximumOverheadSize(MainMemorySizeMax);
+constexpr std::size_t KernelInitialPageHeapSize = Common::Size_128_KB;
+
+constexpr std::size_t KernelSlabHeapDataSize = Common::Size_5_MB;
+constexpr std::size_t KernelSlabHeapGapsSize = Common::Size_2_MB - Common::Size_64_KB;
+constexpr std::size_t KernelSlabHeapSize = KernelSlabHeapDataSize + KernelSlabHeapGapsSize;
+
+// NOTE: This is calculated from KThread slab counts, assuming KThread size <= 0x860.
+constexpr std::size_t KernelSlabHeapAdditionalSize = 0x68000ULL;
+
+constexpr std::size_t KernelResourceSize =
+ KernelPageTableHeapSize + KernelInitialPageHeapSize + KernelSlabHeapSize;
constexpr bool IsKernelAddressKey(VAddr key) {
return KernelVirtualAddressSpaceBase <= key && key <= KernelVirtualAddressSpaceLast;
@@ -27,64 +73,327 @@ constexpr bool IsKernelAddress(VAddr address) {
return KernelVirtualAddressSpaceBase <= address && address < KernelVirtualAddressSpaceEnd;
}
-class KMemoryRegion final {
- friend class KMemoryLayout;
-
-public:
- constexpr PAddr StartAddress() const {
- return start_address;
- }
-
- constexpr PAddr EndAddress() const {
- return end_address;
- }
-
-private:
- constexpr KMemoryRegion() = default;
- constexpr KMemoryRegion(PAddr start_address, PAddr end_address)
- : start_address{start_address}, end_address{end_address} {}
-
- const PAddr start_address{};
- const PAddr end_address{};
-};
-
class KMemoryLayout final {
public:
- constexpr const KMemoryRegion& Application() const {
- return application;
+ KMemoryLayout();
+
+ KMemoryRegionTree& GetVirtualMemoryRegionTree() {
+ return virtual_tree;
+ }
+ const KMemoryRegionTree& GetVirtualMemoryRegionTree() const {
+ return virtual_tree;
+ }
+ KMemoryRegionTree& GetPhysicalMemoryRegionTree() {
+ return physical_tree;
+ }
+ const KMemoryRegionTree& GetPhysicalMemoryRegionTree() const {
+ return physical_tree;
+ }
+ KMemoryRegionTree& GetVirtualLinearMemoryRegionTree() {
+ return virtual_linear_tree;
+ }
+ const KMemoryRegionTree& GetVirtualLinearMemoryRegionTree() const {
+ return virtual_linear_tree;
+ }
+ KMemoryRegionTree& GetPhysicalLinearMemoryRegionTree() {
+ return physical_linear_tree;
+ }
+ const KMemoryRegionTree& GetPhysicalLinearMemoryRegionTree() const {
+ return physical_linear_tree;
}
- constexpr const KMemoryRegion& Applet() const {
- return applet;
+ VAddr GetLinearVirtualAddress(PAddr address) const {
+ return address + linear_phys_to_virt_diff;
+ }
+ PAddr GetLinearPhysicalAddress(VAddr address) const {
+ return address + linear_virt_to_phys_diff;
}
- constexpr const KMemoryRegion& System() const {
- return system;
+ const KMemoryRegion* FindVirtual(VAddr address) const {
+ return Find(address, GetVirtualMemoryRegionTree());
+ }
+ const KMemoryRegion* FindPhysical(PAddr address) const {
+ return Find(address, GetPhysicalMemoryRegionTree());
}
- static constexpr KMemoryLayout GetDefaultLayout() {
- constexpr std::size_t application_size{0xcd500000};
- constexpr std::size_t applet_size{0x1fb00000};
- constexpr PAddr application_start_address{Core::DramMemoryMap::End - application_size};
- constexpr PAddr application_end_address{Core::DramMemoryMap::End};
- constexpr PAddr applet_start_address{application_start_address - applet_size};
- constexpr PAddr applet_end_address{applet_start_address + applet_size};
- constexpr PAddr system_start_address{Core::DramMemoryMap::SlabHeapEnd};
- constexpr PAddr system_end_address{applet_start_address};
- return {application_start_address, application_end_address, applet_start_address,
- applet_end_address, system_start_address, system_end_address};
+ const KMemoryRegion* FindVirtualLinear(VAddr address) const {
+ return Find(address, GetVirtualLinearMemoryRegionTree());
+ }
+ const KMemoryRegion* FindPhysicalLinear(PAddr address) const {
+ return Find(address, GetPhysicalLinearMemoryRegionTree());
+ }
+
+ VAddr GetMainStackTopAddress(s32 core_id) const {
+ return GetStackTopAddress(core_id, KMemoryRegionType_KernelMiscMainStack);
+ }
+ VAddr GetIdleStackTopAddress(s32 core_id) const {
+ return GetStackTopAddress(core_id, KMemoryRegionType_KernelMiscIdleStack);
+ }
+ VAddr GetExceptionStackTopAddress(s32 core_id) const {
+ return GetStackTopAddress(core_id, KMemoryRegionType_KernelMiscExceptionStack);
+ }
+
+ VAddr GetSlabRegionAddress() const {
+ return Dereference(GetVirtualMemoryRegionTree().FindByType(KMemoryRegionType_KernelSlab))
+ .GetAddress();
+ }
+
+ const KMemoryRegion& GetDeviceRegion(KMemoryRegionType type) const {
+ return Dereference(GetPhysicalMemoryRegionTree().FindFirstDerived(type));
+ }
+ PAddr GetDevicePhysicalAddress(KMemoryRegionType type) const {
+ return GetDeviceRegion(type).GetAddress();
+ }
+ VAddr GetDeviceVirtualAddress(KMemoryRegionType type) const {
+ return GetDeviceRegion(type).GetPairAddress();
+ }
+
+ const KMemoryRegion& GetPoolManagementRegion() const {
+ return Dereference(
+ GetVirtualMemoryRegionTree().FindByType(KMemoryRegionType_VirtualDramPoolManagement));
+ }
+ const KMemoryRegion& GetPageTableHeapRegion() const {
+ return Dereference(
+ GetVirtualMemoryRegionTree().FindByType(KMemoryRegionType_VirtualDramKernelPtHeap));
+ }
+ const KMemoryRegion& GetKernelStackRegion() const {
+ return Dereference(GetVirtualMemoryRegionTree().FindByType(KMemoryRegionType_KernelStack));
+ }
+ const KMemoryRegion& GetTempRegion() const {
+ return Dereference(GetVirtualMemoryRegionTree().FindByType(KMemoryRegionType_KernelTemp));
+ }
+
+ const KMemoryRegion& GetKernelTraceBufferRegion() const {
+ return Dereference(GetVirtualLinearMemoryRegionTree().FindByType(
+ KMemoryRegionType_VirtualDramKernelTraceBuffer));
+ }
+
+ const KMemoryRegion& GetVirtualLinearRegion(VAddr address) const {
+ return Dereference(FindVirtualLinear(address));
+ }
+
+ const KMemoryRegion* GetPhysicalKernelTraceBufferRegion() const {
+ return GetPhysicalMemoryRegionTree().FindFirstDerived(KMemoryRegionType_KernelTraceBuffer);
+ }
+ const KMemoryRegion* GetPhysicalOnMemoryBootImageRegion() const {
+ return GetPhysicalMemoryRegionTree().FindFirstDerived(KMemoryRegionType_OnMemoryBootImage);
+ }
+ const KMemoryRegion* GetPhysicalDTBRegion() const {
+ return GetPhysicalMemoryRegionTree().FindFirstDerived(KMemoryRegionType_DTB);
+ }
+
+ bool IsHeapPhysicalAddress(const KMemoryRegion*& region, PAddr address) const {
+ return IsTypedAddress(region, address, GetPhysicalLinearMemoryRegionTree(),
+ KMemoryRegionType_DramUserPool);
+ }
+ bool IsHeapVirtualAddress(const KMemoryRegion*& region, VAddr address) const {
+ return IsTypedAddress(region, address, GetVirtualLinearMemoryRegionTree(),
+ KMemoryRegionType_VirtualDramUserPool);
+ }
+
+ bool IsHeapPhysicalAddress(const KMemoryRegion*& region, PAddr address, size_t size) const {
+ return IsTypedAddress(region, address, size, GetPhysicalLinearMemoryRegionTree(),
+ KMemoryRegionType_DramUserPool);
+ }
+ bool IsHeapVirtualAddress(const KMemoryRegion*& region, VAddr address, size_t size) const {
+ return IsTypedAddress(region, address, size, GetVirtualLinearMemoryRegionTree(),
+ KMemoryRegionType_VirtualDramUserPool);
+ }
+
+ bool IsLinearMappedPhysicalAddress(const KMemoryRegion*& region, PAddr address) const {
+ return IsTypedAddress(region, address, GetPhysicalLinearMemoryRegionTree(),
+ static_cast(KMemoryRegionAttr_LinearMapped));
+ }
+ bool IsLinearMappedPhysicalAddress(const KMemoryRegion*& region, PAddr address,
+ size_t size) const {
+ return IsTypedAddress(region, address, size, GetPhysicalLinearMemoryRegionTree(),
+ static_cast(KMemoryRegionAttr_LinearMapped));
+ }
+
+ std::pair GetTotalAndKernelMemorySizes() const {
+ size_t total_size = 0, kernel_size = 0;
+ for (const auto& region : GetPhysicalMemoryRegionTree()) {
+ if (region.IsDerivedFrom(KMemoryRegionType_Dram)) {
+ total_size += region.GetSize();
+ if (!region.IsDerivedFrom(KMemoryRegionType_DramUserPool)) {
+ kernel_size += region.GetSize();
+ }
+ }
+ }
+ return std::make_pair(total_size, kernel_size);
+ }
+
+ void InitializeLinearMemoryRegionTrees(PAddr aligned_linear_phys_start,
+ VAddr linear_virtual_start);
+ static size_t GetResourceRegionSizeForInit();
+
+ auto GetKernelRegionExtents() const {
+ return GetVirtualMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_Kernel);
+ }
+ auto GetKernelCodeRegionExtents() const {
+ return GetVirtualMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_KernelCode);
+ }
+ auto GetKernelStackRegionExtents() const {
+ return GetVirtualMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_KernelStack);
+ }
+ auto GetKernelMiscRegionExtents() const {
+ return GetVirtualMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_KernelMisc);
+ }
+ auto GetKernelSlabRegionExtents() const {
+ return GetVirtualMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_KernelSlab);
+ }
+
+ auto GetLinearRegionPhysicalExtents() const {
+ return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
+ KMemoryRegionAttr_LinearMapped);
+ }
+
+ auto GetLinearRegionVirtualExtents() const {
+ const auto physical = GetLinearRegionPhysicalExtents();
+ return KMemoryRegion(GetLinearVirtualAddress(physical.GetAddress()),
+ GetLinearVirtualAddress(physical.GetLastAddress()), 0,
+ KMemoryRegionType_None);
+ }
+
+ auto GetMainMemoryPhysicalExtents() const {
+ return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(KMemoryRegionType_Dram);
+ }
+ auto GetCarveoutRegionExtents() const {
+ return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
+ KMemoryRegionAttr_CarveoutProtected);
+ }
+
+ auto GetKernelRegionPhysicalExtents() const {
+ return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
+ KMemoryRegionType_DramKernelBase);
+ }
+ auto GetKernelCodeRegionPhysicalExtents() const {
+ return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
+ KMemoryRegionType_DramKernelCode);
+ }
+ auto GetKernelSlabRegionPhysicalExtents() const {
+ return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
+ KMemoryRegionType_DramKernelSlab);
+ }
+ auto GetKernelPageTableHeapRegionPhysicalExtents() const {
+ return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
+ KMemoryRegionType_DramKernelPtHeap);
+ }
+ auto GetKernelInitPageTableRegionPhysicalExtents() const {
+ return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
+ KMemoryRegionType_DramKernelInitPt);
+ }
+
+ auto GetKernelPoolManagementRegionPhysicalExtents() const {
+ return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
+ KMemoryRegionType_DramPoolManagement);
+ }
+ auto GetKernelPoolPartitionRegionPhysicalExtents() const {
+ return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
+ KMemoryRegionType_DramPoolPartition);
+ }
+ auto GetKernelSystemPoolRegionPhysicalExtents() const {
+ return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
+ KMemoryRegionType_DramSystemPool);
+ }
+ auto GetKernelSystemNonSecurePoolRegionPhysicalExtents() const {
+ return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
+ KMemoryRegionType_DramSystemNonSecurePool);
+ }
+ auto GetKernelAppletPoolRegionPhysicalExtents() const {
+ return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
+ KMemoryRegionType_DramAppletPool);
+ }
+ auto GetKernelApplicationPoolRegionPhysicalExtents() const {
+ return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
+ KMemoryRegionType_DramApplicationPool);
+ }
+
+ auto GetKernelTraceBufferRegionPhysicalExtents() const {
+ return GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
+ KMemoryRegionType_KernelTraceBuffer);
}
private:
- constexpr KMemoryLayout(PAddr application_start_address, std::size_t application_size,
- PAddr applet_start_address, std::size_t applet_size,
- PAddr system_start_address, std::size_t system_size)
- : application{application_start_address, application_size},
- applet{applet_start_address, applet_size}, system{system_start_address, system_size} {}
+ template
+ static bool IsTypedAddress(const KMemoryRegion*& region, AddressType address,
+ const KMemoryRegionTree& tree, KMemoryRegionType type) {
+ // Check if the cached region already contains the address.
+ if (region != nullptr && region->Contains(address)) {
+ return true;
+ }
- const KMemoryRegion application;
- const KMemoryRegion applet;
- const KMemoryRegion system;
+ // Find the containing region, and update the cache.
+ if (const KMemoryRegion* found = tree.Find(address);
+ found != nullptr && found->IsDerivedFrom(type)) {
+ region = found;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ template
+ static bool IsTypedAddress(const KMemoryRegion*& region, AddressType address, size_t size,
+ const KMemoryRegionTree& tree, KMemoryRegionType type) {
+ // Get the end of the checked region.
+ const u64 last_address = address + size - 1;
+
+ // Walk the tree to verify the region is correct.
+ const KMemoryRegion* cur =
+ (region != nullptr && region->Contains(address)) ? region : tree.Find(address);
+ while (cur != nullptr && cur->IsDerivedFrom(type)) {
+ if (last_address <= cur->GetLastAddress()) {
+ region = cur;
+ return true;
+ }
+
+ cur = cur->GetNext();
+ }
+ return false;
+ }
+
+ template
+ static const KMemoryRegion* Find(AddressType address, const KMemoryRegionTree& tree) {
+ return tree.Find(address);
+ }
+
+ static KMemoryRegion& Dereference(KMemoryRegion* region) {
+ ASSERT(region != nullptr);
+ return *region;
+ }
+
+ static const KMemoryRegion& Dereference(const KMemoryRegion* region) {
+ ASSERT(region != nullptr);
+ return *region;
+ }
+
+ VAddr GetStackTopAddress(s32 core_id, KMemoryRegionType type) const {
+ const auto& region = Dereference(
+ GetVirtualMemoryRegionTree().FindByTypeAndAttribute(type, static_cast(core_id)));
+ ASSERT(region.GetEndAddress() != 0);
+ return region.GetEndAddress();
+ }
+
+private:
+ u64 linear_phys_to_virt_diff{};
+ u64 linear_virt_to_phys_diff{};
+ KMemoryRegionAllocator memory_region_allocator;
+ KMemoryRegionTree virtual_tree;
+ KMemoryRegionTree physical_tree;
+ KMemoryRegionTree virtual_linear_tree;
+ KMemoryRegionTree physical_linear_tree;
};
+namespace Init {
+
+// These should be generic, regardless of board.
+void SetupPoolPartitionMemoryRegions(KMemoryLayout& memory_layout);
+
+// These may be implemented in a board-specific manner.
+void SetupDevicePhysicalMemoryRegions(KMemoryLayout& memory_layout);
+void SetupDramPhysicalMemoryRegions(KMemoryLayout& memory_layout);
+
+} // namespace Init
+
} // namespace Kernel
diff --git a/src/core/hle/kernel/k_memory_manager.cpp b/src/core/hle/kernel/k_memory_manager.cpp
index 9027602bf..aa71697b2 100755
--- a/src/core/hle/kernel/k_memory_manager.cpp
+++ b/src/core/hle/kernel/k_memory_manager.cpp
@@ -173,4 +173,16 @@ ResultCode KMemoryManager::Free(KPageLinkedList& page_list, std::size_t num_page
return RESULT_SUCCESS;
}
+std::size_t KMemoryManager::Impl::CalculateManagementOverheadSize(std::size_t region_size) {
+ const std::size_t ref_count_size = (region_size / PageSize) * sizeof(u16);
+ const std::size_t optimize_map_size =
+ (Common::AlignUp((region_size / PageSize), Common::BitSize()) /
+ Common::BitSize()) *
+ sizeof(u64);
+ const std::size_t manager_meta_size =
+ Common::AlignUp(optimize_map_size + ref_count_size, PageSize);
+ const std::size_t page_heap_size = KPageHeap::CalculateManagementOverheadSize(region_size);
+ return manager_meta_size + page_heap_size;
+}
+
} // namespace Kernel
diff --git a/src/core/hle/kernel/k_memory_manager.h b/src/core/hle/kernel/k_memory_manager.h
index ae9f683b8..ac840b3d0 100755
--- a/src/core/hle/kernel/k_memory_manager.h
+++ b/src/core/hle/kernel/k_memory_manager.h
@@ -29,6 +29,10 @@ public:
Shift = 4,
Mask = (0xF << Shift),
+
+ // Aliases.
+ Unsafe = Application,
+ Secure = System,
};
enum class Direction : u32 {
@@ -56,6 +60,10 @@ public:
static constexpr std::size_t MaxManagerCount = 10;
public:
+ static std::size_t CalculateManagementOverheadSize(std::size_t region_size) {
+ return Impl::CalculateManagementOverheadSize(region_size);
+ }
+
static constexpr u32 EncodeOption(Pool pool, Direction dir) {
return (static_cast(pool) << static_cast(Pool::Shift)) |
(static_cast(dir) << static_cast(Direction::Shift));
@@ -85,6 +93,16 @@ private:
KPageHeap heap;
Pool pool{};
+ public:
+ static std::size_t CalculateManagementOverheadSize(std::size_t region_size);
+
+ static constexpr std::size_t CalculateOptimizedProcessOverheadSize(
+ std::size_t region_size) {
+ return (Common::AlignUp((region_size / PageSize), Common::BitSize()) /
+ Common::BitSize()) *
+ sizeof(u64);
+ }
+
public:
Impl() = default;
diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp
index e7de48476..d1df97305 100755
--- a/src/core/hle/kernel/k_scheduler.cpp
+++ b/src/core/hle/kernel/k_scheduler.cpp
@@ -62,7 +62,7 @@ void KScheduler::RescheduleCores(KernelCore& kernel, u64 cores_pending_reschedul
}
u64 KScheduler::UpdateHighestPriorityThread(KThread* highest_thread) {
- std::scoped_lock lock{guard};
+ KScopedSpinLock lk{guard};
if (KThread* prev_highest_thread = state.highest_priority_thread;
prev_highest_thread != highest_thread) {
if (prev_highest_thread != nullptr) {
@@ -637,11 +637,11 @@ void KScheduler::RescheduleCurrentCore() {
if (phys_core.IsInterrupted()) {
phys_core.ClearInterrupt();
}
- guard.lock();
+ guard.Lock();
if (state.needs_scheduling.load()) {
Schedule();
} else {
- guard.unlock();
+ guard.Unlock();
}
}
@@ -669,7 +669,7 @@ void KScheduler::Unload(KThread* thread) {
} else {
prev_thread = nullptr;
}
- thread->context_guard.unlock();
+ thread->context_guard.Unlock();
}
}
@@ -713,7 +713,7 @@ void KScheduler::ScheduleImpl() {
// If we're not actually switching thread, there's nothing to do.
if (next_thread == current_thread.load()) {
- guard.unlock();
+ guard.Unlock();
return;
}
@@ -732,7 +732,7 @@ void KScheduler::ScheduleImpl() {
} else {
old_context = &idle_thread->GetHostContext();
}
- guard.unlock();
+ guard.Unlock();
Common::Fiber::YieldTo(*old_context, *switch_fiber);
/// When a thread wakes up, the scheduler may have changed to other in another core.
@@ -748,24 +748,24 @@ void KScheduler::OnSwitch(void* this_scheduler) {
void KScheduler::SwitchToCurrent() {
while (true) {
{
- std::scoped_lock lock{guard};
+ KScopedSpinLock lk{guard};
current_thread.store(state.highest_priority_thread);
state.needs_scheduling.store(false);
}
const auto is_switch_pending = [this] {
- std::scoped_lock lock{guard};
+ KScopedSpinLock lk{guard};
return state.needs_scheduling.load();
};
do {
auto next_thread = current_thread.load();
if (next_thread != nullptr) {
- next_thread->context_guard.lock();
+ next_thread->context_guard.Lock();
if (next_thread->GetRawState() != ThreadState::Runnable) {
- next_thread->context_guard.unlock();
+ next_thread->context_guard.Unlock();
break;
}
if (next_thread->GetActiveCore() != core_id) {
- next_thread->context_guard.unlock();
+ next_thread->context_guard.Unlock();
break;
}
}
diff --git a/src/core/hle/kernel/k_scheduler.h b/src/core/hle/kernel/k_scheduler.h
index f595b9a5c..f1cca51dc 100755
--- a/src/core/hle/kernel/k_scheduler.h
+++ b/src/core/hle/kernel/k_scheduler.h
@@ -2,19 +2,16 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-// This file references various implementation details from Atmosphere, an open-source firmware for
-// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
-
#pragma once
#include
#include "common/common_types.h"
-#include "common/spin_lock.h"
#include "core/hle/kernel/global_scheduler_context.h"
#include "core/hle/kernel/k_priority_queue.h"
#include "core/hle/kernel/k_scheduler_lock.h"
#include "core/hle/kernel/k_scoped_lock.h"
+#include "core/hle/kernel/k_spin_lock.h"
namespace Common {
class Fiber;
@@ -195,7 +192,7 @@ private:
u64 last_context_switch_time{};
const s32 core_id;
- Common::SpinLock guard{};
+ KSpinLock guard{};
};
class KScopedSchedulerLock : KScopedLock {
diff --git a/src/core/hle/kernel/k_scheduler_lock.h b/src/core/hle/kernel/k_scheduler_lock.h
index 169455d18..47e315555 100755
--- a/src/core/hle/kernel/k_scheduler_lock.h
+++ b/src/core/hle/kernel/k_scheduler_lock.h
@@ -2,14 +2,11 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-// This file references various implementation details from Atmosphere, an open-source firmware for
-// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX.
-
#pragma once
#include "common/assert.h"
-#include "common/spin_lock.h"
#include "core/hardware_properties.h"
+#include "core/hle/kernel/k_spin_lock.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/kernel.h"
@@ -34,7 +31,7 @@ public:
} else {
// Otherwise, we want to disable scheduling and acquire the spinlock.
SchedulerType::DisableScheduling(kernel);
- spin_lock.lock();
+ spin_lock.Lock();
// For debug, ensure that our state is valid.
ASSERT(lock_count == 0);
@@ -58,7 +55,7 @@ public:
// Note that we no longer hold the lock, and unlock the spinlock.
owner_thread = nullptr;
- spin_lock.unlock();
+ spin_lock.Unlock();
// Enable scheduling, and perform a rescheduling operation.
SchedulerType::EnableScheduling(kernel, cores_needing_scheduling);
@@ -67,7 +64,7 @@ public:
private:
KernelCore& kernel;
- Common::SpinLock spin_lock{};
+ KAlignedSpinLock spin_lock{};
s32 lock_count{};
KThread* owner_thread{};
};
diff --git a/src/core/hle/kernel/k_spin_lock.h b/src/core/hle/kernel/k_spin_lock.h
index 12c4b2e88..4d87d006a 100755
--- a/src/core/hle/kernel/k_spin_lock.h
+++ b/src/core/hle/kernel/k_spin_lock.h
@@ -28,6 +28,12 @@ private:
std::atomic_flag lck = ATOMIC_FLAG_INIT;
};
+// TODO(bunnei): Alias for now, in case we want to implement these accurately in the future.
+using KAlignedSpinLock = KSpinLock;
+using KNotAlignedSpinLock = KSpinLock;
+
using KScopedSpinLock = KScopedLock;
+using KScopedAlignedSpinLock = KScopedLock;
+using KScopedNotAlignedSpinLock = KScopedLock;
} // namespace Kernel
diff --git a/src/core/hle/kernel/k_system_control.h b/src/core/hle/kernel/k_system_control.h
index 1d5b64ffa..d755082c2 100755
--- a/src/core/hle/kernel/k_system_control.h
+++ b/src/core/hle/kernel/k_system_control.h
@@ -6,14 +6,18 @@
#include "common/common_types.h"
+#define BOARD_NINTENDO_NX
+
+#ifdef BOARD_NINTENDO_NX
+
+#include "core/hle/kernel/board/nintendo/nx/k_system_control.h"
+
namespace Kernel {
-class KSystemControl {
-public:
- KSystemControl() = default;
-
- static u64 GenerateRandomRange(u64 min, u64 max);
- static u64 GenerateRandomU64();
-};
+using Kernel::Board::Nintendo::Nx::KSystemControl;
} // namespace Kernel
+
+#else
+#error "Unknown board for KSystemControl"
+#endif
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h
index 1c19b23dc..1c86fdd20 100755
--- a/src/core/hle/kernel/k_thread.h
+++ b/src/core/hle/kernel/k_thread.h
@@ -14,10 +14,10 @@
#include "common/common_types.h"
#include "common/intrusive_red_black_tree.h"
-#include "common/spin_lock.h"
#include "core/arm/arm_interface.h"
#include "core/hle/kernel/k_affinity_mask.h"
#include "core/hle/kernel/k_light_lock.h"
+#include "core/hle/kernel/k_spin_lock.h"
#include "core/hle/kernel/k_synchronization_object.h"
#include "core/hle/kernel/object.h"
#include "core/hle/kernel/svc_common.h"
@@ -732,7 +732,7 @@ private:
s8 priority_inheritance_count{};
bool resource_limit_release_hint{};
StackParameters stack_parameters{};
- Common::SpinLock context_guard{};
+ KSpinLock context_guard{};
// For emulation
std::shared_ptr host_context{};
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 5b6c7792e..aa501efe4 100755
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -1,4 +1,4 @@
-// Copyright 2014 Citra Emulator Project
+// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
@@ -12,6 +12,7 @@
#include
#include "common/assert.h"
+#include "common/common_sizes.h"
#include "common/logging/log.h"
#include "common/microprofile.h"
#include "common/thread.h"
@@ -268,45 +269,314 @@ struct KernelCore::Impl {
return schedulers[thread_id]->GetCurrentThread();
}
+ void DeriveInitialMemoryLayout(KMemoryLayout& memory_layout) {
+ // Insert the root region for the virtual memory tree, from which all other regions will
+ // derive.
+ memory_layout.GetVirtualMemoryRegionTree().InsertDirectly(
+ KernelVirtualAddressSpaceBase,
+ KernelVirtualAddressSpaceBase + KernelVirtualAddressSpaceSize - 1);
+
+ // Insert the root region for the physical memory tree, from which all other regions will
+ // derive.
+ memory_layout.GetPhysicalMemoryRegionTree().InsertDirectly(
+ KernelPhysicalAddressSpaceBase,
+ KernelPhysicalAddressSpaceBase + KernelPhysicalAddressSpaceSize - 1);
+
+ // Save start and end for ease of use.
+ const VAddr code_start_virt_addr = KernelVirtualAddressCodeBase;
+ const VAddr code_end_virt_addr = KernelVirtualAddressCodeEnd;
+
+ // Setup the containing kernel region.
+ constexpr size_t KernelRegionSize = Common::Size_1_GB;
+ constexpr size_t KernelRegionAlign = Common::Size_1_GB;
+ constexpr VAddr kernel_region_start =
+ Common::AlignDown(code_start_virt_addr, KernelRegionAlign);
+ size_t kernel_region_size = KernelRegionSize;
+ if (!(kernel_region_start + KernelRegionSize - 1 <= KernelVirtualAddressSpaceLast)) {
+ kernel_region_size = KernelVirtualAddressSpaceEnd - kernel_region_start;
+ }
+ ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert(
+ kernel_region_start, kernel_region_size, KMemoryRegionType_Kernel));
+
+ // Setup the code region.
+ constexpr size_t CodeRegionAlign = PageSize;
+ constexpr VAddr code_region_start =
+ Common::AlignDown(code_start_virt_addr, CodeRegionAlign);
+ constexpr VAddr code_region_end = Common::AlignUp(code_end_virt_addr, CodeRegionAlign);
+ constexpr size_t code_region_size = code_region_end - code_region_start;
+ ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert(
+ code_region_start, code_region_size, KMemoryRegionType_KernelCode));
+
+ // Setup board-specific device physical regions.
+ Init::SetupDevicePhysicalMemoryRegions(memory_layout);
+
+ // Determine the amount of space needed for the misc region.
+ size_t misc_region_needed_size;
+ {
+ // Each core has a one page stack for all three stack types (Main, Idle, Exception).
+ misc_region_needed_size = Core::Hardware::NUM_CPU_CORES * (3 * (PageSize + PageSize));
+
+ // Account for each auto-map device.
+ for (const auto& region : memory_layout.GetPhysicalMemoryRegionTree()) {
+ if (region.HasTypeAttribute(KMemoryRegionAttr_ShouldKernelMap)) {
+ // Check that the region is valid.
+ ASSERT(region.GetEndAddress() != 0);
+
+ // Account for the region.
+ misc_region_needed_size +=
+ PageSize + (Common::AlignUp(region.GetLastAddress(), PageSize) -
+ Common::AlignDown(region.GetAddress(), PageSize));
+ }
+ }
+
+ // Multiply the needed size by three, to account for the need for guard space.
+ misc_region_needed_size *= 3;
+ }
+
+ // Decide on the actual size for the misc region.
+ constexpr size_t MiscRegionAlign = KernelAslrAlignment;
+ constexpr size_t MiscRegionMinimumSize = Common::Size_32_MB;
+ const size_t misc_region_size = Common::AlignUp(
+ std::max(misc_region_needed_size, MiscRegionMinimumSize), MiscRegionAlign);
+ ASSERT(misc_region_size > 0);
+
+ // Setup the misc region.
+ const VAddr misc_region_start =
+ memory_layout.GetVirtualMemoryRegionTree().GetRandomAlignedRegion(
+ misc_region_size, MiscRegionAlign, KMemoryRegionType_Kernel);
+ ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert(
+ misc_region_start, misc_region_size, KMemoryRegionType_KernelMisc));
+
+ // Setup the stack region.
+ constexpr size_t StackRegionSize = Common::Size_14_MB;
+ constexpr size_t StackRegionAlign = KernelAslrAlignment;
+ const VAddr stack_region_start =
+ memory_layout.GetVirtualMemoryRegionTree().GetRandomAlignedRegion(
+ StackRegionSize, StackRegionAlign, KMemoryRegionType_Kernel);
+ ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert(
+ stack_region_start, StackRegionSize, KMemoryRegionType_KernelStack));
+
+ // Determine the size of the resource region.
+ const size_t resource_region_size = memory_layout.GetResourceRegionSizeForInit();
+
+ // Determine the size of the slab region.
+ const size_t slab_region_size = Common::AlignUp(KernelSlabHeapSize, PageSize);
+ ASSERT(slab_region_size <= resource_region_size);
+
+ // Setup the slab region.
+ const PAddr code_start_phys_addr = KernelPhysicalAddressCodeBase;
+ const PAddr code_end_phys_addr = code_start_phys_addr + code_region_size;
+ const PAddr slab_start_phys_addr = code_end_phys_addr;
+ const PAddr slab_end_phys_addr = slab_start_phys_addr + slab_region_size;
+ constexpr size_t SlabRegionAlign = KernelAslrAlignment;
+ const size_t slab_region_needed_size =
+ Common::AlignUp(code_end_phys_addr + slab_region_size, SlabRegionAlign) -
+ Common::AlignDown(code_end_phys_addr, SlabRegionAlign);
+ const VAddr slab_region_start =
+ memory_layout.GetVirtualMemoryRegionTree().GetRandomAlignedRegion(
+ slab_region_needed_size, SlabRegionAlign, KMemoryRegionType_Kernel) +
+ (code_end_phys_addr % SlabRegionAlign);
+ ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert(
+ slab_region_start, slab_region_size, KMemoryRegionType_KernelSlab));
+
+ // Setup the temp region.
+ constexpr size_t TempRegionSize = Common::Size_128_MB;
+ constexpr size_t TempRegionAlign = KernelAslrAlignment;
+ const VAddr temp_region_start =
+ memory_layout.GetVirtualMemoryRegionTree().GetRandomAlignedRegion(
+ TempRegionSize, TempRegionAlign, KMemoryRegionType_Kernel);
+ ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert(temp_region_start, TempRegionSize,
+ KMemoryRegionType_KernelTemp));
+
+ // Automatically map in devices that have auto-map attributes.
+ for (auto& region : memory_layout.GetPhysicalMemoryRegionTree()) {
+ // We only care about kernel regions.
+ if (!region.IsDerivedFrom(KMemoryRegionType_Kernel)) {
+ continue;
+ }
+
+ // Check whether we should map the region.
+ if (!region.HasTypeAttribute(KMemoryRegionAttr_ShouldKernelMap)) {
+ continue;
+ }
+
+ // If this region has already been mapped, no need to consider it.
+ if (region.HasTypeAttribute(KMemoryRegionAttr_DidKernelMap)) {
+ continue;
+ }
+
+ // Check that the region is valid.
+ ASSERT(region.GetEndAddress() != 0);
+
+ // Set the attribute to note we've mapped this region.
+ region.SetTypeAttribute(KMemoryRegionAttr_DidKernelMap);
+
+ // Create a virtual pair region and insert it into the tree.
+ const PAddr map_phys_addr = Common::AlignDown(region.GetAddress(), PageSize);
+ const size_t map_size =
+ Common::AlignUp(region.GetEndAddress(), PageSize) - map_phys_addr;
+ const VAddr map_virt_addr =
+ memory_layout.GetVirtualMemoryRegionTree().GetRandomAlignedRegionWithGuard(
+ map_size, PageSize, KMemoryRegionType_KernelMisc, PageSize);
+ ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert(
+ map_virt_addr, map_size, KMemoryRegionType_KernelMiscMappedDevice));
+ region.SetPairAddress(map_virt_addr + region.GetAddress() - map_phys_addr);
+ }
+
+ Init::SetupDramPhysicalMemoryRegions(memory_layout);
+
+ // Insert a physical region for the kernel code region.
+ ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(
+ code_start_phys_addr, code_region_size, KMemoryRegionType_DramKernelCode));
+
+ // Insert a physical region for the kernel slab region.
+ ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(
+ slab_start_phys_addr, slab_region_size, KMemoryRegionType_DramKernelSlab));
+
+ // Determine size available for kernel page table heaps, requiring > 8 MB.
+ const PAddr resource_end_phys_addr = slab_start_phys_addr + resource_region_size;
+ const size_t page_table_heap_size = resource_end_phys_addr - slab_end_phys_addr;
+ ASSERT(page_table_heap_size / Common::Size_4_MB > 2);
+
+ // Insert a physical region for the kernel page table heap region
+ ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(
+ slab_end_phys_addr, page_table_heap_size, KMemoryRegionType_DramKernelPtHeap));
+
+ // All DRAM regions that we haven't tagged by this point will be mapped under the linear
+ // mapping. Tag them.
+ for (auto& region : memory_layout.GetPhysicalMemoryRegionTree()) {
+ if (region.GetType() == KMemoryRegionType_Dram) {
+ // Check that the region is valid.
+ ASSERT(region.GetEndAddress() != 0);
+
+ // Set the linear map attribute.
+ region.SetTypeAttribute(KMemoryRegionAttr_LinearMapped);
+ }
+ }
+
+ // Get the linear region extents.
+ const auto linear_extents =
+ memory_layout.GetPhysicalMemoryRegionTree().GetDerivedRegionExtents(
+ KMemoryRegionAttr_LinearMapped);
+ ASSERT(linear_extents.GetEndAddress() != 0);
+
+ // Setup the linear mapping region.
+ constexpr size_t LinearRegionAlign = Common::Size_1_GB;
+ const PAddr aligned_linear_phys_start =
+ Common::AlignDown(linear_extents.GetAddress(), LinearRegionAlign);
+ const size_t linear_region_size =
+ Common::AlignUp(linear_extents.GetEndAddress(), LinearRegionAlign) -
+ aligned_linear_phys_start;
+ const VAddr linear_region_start =
+ memory_layout.GetVirtualMemoryRegionTree().GetRandomAlignedRegionWithGuard(
+ linear_region_size, LinearRegionAlign, KMemoryRegionType_None, LinearRegionAlign);
+
+ const u64 linear_region_phys_to_virt_diff = linear_region_start - aligned_linear_phys_start;
+
+ // Map and create regions for all the linearly-mapped data.
+ {
+ PAddr cur_phys_addr = 0;
+ u64 cur_size = 0;
+ for (auto& region : memory_layout.GetPhysicalMemoryRegionTree()) {
+ if (!region.HasTypeAttribute(KMemoryRegionAttr_LinearMapped)) {
+ continue;
+ }
+
+ ASSERT(region.GetEndAddress() != 0);
+
+ if (cur_size == 0) {
+ cur_phys_addr = region.GetAddress();
+ cur_size = region.GetSize();
+ } else if (cur_phys_addr + cur_size == region.GetAddress()) {
+ cur_size += region.GetSize();
+ } else {
+ cur_phys_addr = region.GetAddress();
+ cur_size = region.GetSize();
+ }
+
+ const VAddr region_virt_addr =
+ region.GetAddress() + linear_region_phys_to_virt_diff;
+ ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert(
+ region_virt_addr, region.GetSize(),
+ GetTypeForVirtualLinearMapping(region.GetType())));
+ region.SetPairAddress(region_virt_addr);
+
+ KMemoryRegion* virt_region =
+ memory_layout.GetVirtualMemoryRegionTree().FindModifiable(region_virt_addr);
+ ASSERT(virt_region != nullptr);
+ virt_region->SetPairAddress(region.GetAddress());
+ }
+ }
+
+ // Insert regions for the initial page table region.
+ ASSERT(memory_layout.GetPhysicalMemoryRegionTree().Insert(
+ resource_end_phys_addr, KernelPageTableHeapSize, KMemoryRegionType_DramKernelInitPt));
+ ASSERT(memory_layout.GetVirtualMemoryRegionTree().Insert(
+ resource_end_phys_addr + linear_region_phys_to_virt_diff, KernelPageTableHeapSize,
+ KMemoryRegionType_VirtualDramKernelInitPt));
+
+ // All linear-mapped DRAM regions that we haven't tagged by this point will be allocated to
+ // some pool partition. Tag them.
+ for (auto& region : memory_layout.GetPhysicalMemoryRegionTree()) {
+ if (region.GetType() == (KMemoryRegionType_Dram | KMemoryRegionAttr_LinearMapped)) {
+ region.SetType(KMemoryRegionType_DramPoolPartition);
+ }
+ }
+
+ // Setup all other memory regions needed to arrange the pool partitions.
+ Init::SetupPoolPartitionMemoryRegions(memory_layout);
+
+ // Cache all linear regions in their own trees for faster access, later.
+ memory_layout.InitializeLinearMemoryRegionTrees(aligned_linear_phys_start,
+ linear_region_start);
+ }
+
void InitializeMemoryLayout() {
- // Initialize memory layout
- constexpr KMemoryLayout layout{KMemoryLayout::GetDefaultLayout()};
+ // Derive the initial memory layout from the emulated board
+ KMemoryLayout memory_layout;
+ DeriveInitialMemoryLayout(memory_layout);
+
+ const auto system_pool = memory_layout.GetKernelSystemPoolRegionPhysicalExtents();
+ const auto applet_pool = memory_layout.GetKernelAppletPoolRegionPhysicalExtents();
+ const auto application_pool = memory_layout.GetKernelApplicationPoolRegionPhysicalExtents();
+
+ // Initialize memory managers
+ memory_manager = std::make_unique();
+ memory_manager->InitializeManager(KMemoryManager::Pool::Application,
+ application_pool.GetAddress(),
+ application_pool.GetEndAddress());
+ memory_manager->InitializeManager(KMemoryManager::Pool::Applet, applet_pool.GetAddress(),
+ applet_pool.GetEndAddress());
+ memory_manager->InitializeManager(KMemoryManager::Pool::System, system_pool.GetAddress(),
+ system_pool.GetEndAddress());
+
+ // Setup memory regions for emulated processes
+ // TODO(bunnei): These should not be hardcoded regions initialized within the kernel
constexpr std::size_t hid_size{0x40000};
constexpr std::size_t font_size{0x1100000};
constexpr std::size_t irs_size{0x8000};
constexpr std::size_t time_size{0x1000};
- constexpr PAddr hid_addr{layout.System().StartAddress()};
- constexpr PAddr font_pa{layout.System().StartAddress() + hid_size};
- constexpr PAddr irs_addr{layout.System().StartAddress() + hid_size + font_size};
- constexpr PAddr time_addr{layout.System().StartAddress() + hid_size + font_size + irs_size};
- // Initialize memory manager
- memory_manager = std::make_unique();
- memory_manager->InitializeManager(KMemoryManager::Pool::Application,
- layout.Application().StartAddress(),
- layout.Application().EndAddress());
- memory_manager->InitializeManager(KMemoryManager::Pool::Applet,
- layout.Applet().StartAddress(),
- layout.Applet().EndAddress());
- memory_manager->InitializeManager(KMemoryManager::Pool::System,
- layout.System().StartAddress(),
- layout.System().EndAddress());
+ const PAddr hid_phys_addr{system_pool.GetAddress()};
+ const PAddr font_phys_addr{system_pool.GetAddress() + hid_size};
+ const PAddr irs_phys_addr{system_pool.GetAddress() + hid_size + font_size};
+ const PAddr time_phys_addr{system_pool.GetAddress() + hid_size + font_size + irs_size};
hid_shared_mem = Kernel::KSharedMemory::Create(
- system.Kernel(), system.DeviceMemory(), nullptr, {hid_addr, hid_size / PageSize},
- KMemoryPermission::None, KMemoryPermission::Read, hid_addr, hid_size,
+ system.Kernel(), system.DeviceMemory(), nullptr, {hid_phys_addr, hid_size / PageSize},
+ KMemoryPermission::None, KMemoryPermission::Read, hid_phys_addr, hid_size,
"HID:SharedMemory");
font_shared_mem = Kernel::KSharedMemory::Create(
- system.Kernel(), system.DeviceMemory(), nullptr, {font_pa, font_size / PageSize},
- KMemoryPermission::None, KMemoryPermission::Read, font_pa, font_size,
+ system.Kernel(), system.DeviceMemory(), nullptr, {font_phys_addr, font_size / PageSize},
+ KMemoryPermission::None, KMemoryPermission::Read, font_phys_addr, font_size,
"Font:SharedMemory");
irs_shared_mem = Kernel::KSharedMemory::Create(
- system.Kernel(), system.DeviceMemory(), nullptr, {irs_addr, irs_size / PageSize},
- KMemoryPermission::None, KMemoryPermission::Read, irs_addr, irs_size,
+ system.Kernel(), system.DeviceMemory(), nullptr, {irs_phys_addr, irs_size / PageSize},
+ KMemoryPermission::None, KMemoryPermission::Read, irs_phys_addr, irs_size,
"IRS:SharedMemory");
time_shared_mem = Kernel::KSharedMemory::Create(
- system.Kernel(), system.DeviceMemory(), nullptr, {time_addr, time_size / PageSize},
- KMemoryPermission::None, KMemoryPermission::Read, time_addr, time_size,
+ system.Kernel(), system.DeviceMemory(), nullptr, {time_phys_addr, time_size / PageSize},
+ KMemoryPermission::None, KMemoryPermission::Read, time_phys_addr, time_size,
"Time:SharedMemory");
// Allocate slab heaps
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 56906f2da..a500e63bc 100755
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -1,4 +1,4 @@
-// Copyright 2014 Citra Emulator Project / PPSSPP Project
+// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index d91237cba..27633d6e4 100755
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -959,7 +959,7 @@ private:
auto storage = applet->GetBroker().PopNormalDataToGame();
if (storage == nullptr) {
- LOG_ERROR(Service_AM,
+ LOG_DEBUG(Service_AM,
"storage is a nullptr. There is no data in the current normal channel");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ERR_NO_DATA_IN_CHANNEL);
@@ -990,7 +990,7 @@ private:
auto storage = applet->GetBroker().PopInteractiveDataToGame();
if (storage == nullptr) {
- LOG_ERROR(Service_AM,
+ LOG_DEBUG(Service_AM,
"storage is a nullptr. There is no data in the current interactive channel");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ERR_NO_DATA_IN_CHANNEL);
@@ -1113,7 +1113,7 @@ ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_)
{2, nullptr, "AreAnyLibraryAppletsLeft"},
{10, &ILibraryAppletCreator::CreateStorage, "CreateStorage"},
{11, &ILibraryAppletCreator::CreateTransferMemoryStorage, "CreateTransferMemoryStorage"},
- {12, nullptr, "CreateHandleStorage"},
+ {12, &ILibraryAppletCreator::CreateHandleStorage, "CreateHandleStorage"},
};
RegisterHandlers(functions);
}
@@ -1122,14 +1122,15 @@ ILibraryAppletCreator::~ILibraryAppletCreator() = default;
void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
+
const auto applet_id = rp.PopRaw();
- const auto applet_mode = rp.PopRaw();
+ const auto applet_mode = rp.PopRaw();
LOG_DEBUG(Service_AM, "called with applet_id={:08X}, applet_mode={:08X}", applet_id,
applet_mode);
const auto& applet_manager{system.GetAppletManager()};
- const auto applet = applet_manager.GetApplet(applet_id);
+ const auto applet = applet_manager.GetApplet(applet_id, applet_mode);
if (applet == nullptr) {
LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id);
@@ -1147,9 +1148,18 @@ void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx)
void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const u64 size{rp.Pop()};
+
+ const s64 size{rp.Pop()};
+
LOG_DEBUG(Service_AM, "called, size={}", size);
+ if (size <= 0) {
+ LOG_ERROR(Service_AM, "size is less than or equal to 0");
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_UNKNOWN);
+ return;
+ }
+
std::vector buffer(size);
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -1158,18 +1168,65 @@ void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) {
}
void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx) {
- LOG_DEBUG(Service_AM, "called");
-
IPC::RequestParser rp{ctx};
- rp.SetCurrentOffset(3);
- const auto handle{rp.Pop()};
+ struct Parameters {
+ u8 permissions;
+ s64 size;
+ };
+
+ const auto parameters{rp.PopRaw()};
+ const auto handle{ctx.GetCopyHandle(0)};
+
+ LOG_DEBUG(Service_AM, "called, permissions={}, size={}, handle={:08X}", parameters.permissions,
+ parameters.size, handle);
+
+ if (parameters.size <= 0) {
+ LOG_ERROR(Service_AM, "size is less than or equal to 0");
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_UNKNOWN);
+ return;
+ }
auto transfer_mem =
system.CurrentProcess()->GetHandleTable().Get(handle);
if (transfer_mem == nullptr) {
- LOG_ERROR(Service_AM, "shared_mem is a nullpr for handle={:08X}", handle);
+ LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle);
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_UNKNOWN);
+ return;
+ }
+
+ const u8* const mem_begin = transfer_mem->GetPointer();
+ const u8* const mem_end = mem_begin + transfer_mem->GetSize();
+ std::vector memory{mem_begin, mem_end};
+
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushIpcInterface(system, std::move(memory));
+}
+
+void ILibraryAppletCreator::CreateHandleStorage(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+
+ const s64 size{rp.Pop()};
+ const auto handle{ctx.GetCopyHandle(0)};
+
+ LOG_DEBUG(Service_AM, "called, size={}, handle={:08X}", size, handle);
+
+ if (size <= 0) {
+ LOG_ERROR(Service_AM, "size is less than or equal to 0");
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_UNKNOWN);
+ return;
+ }
+
+ auto transfer_mem =
+ system.CurrentProcess()->GetHandleTable().Get(handle);
+
+ if (transfer_mem == nullptr) {
+ LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_UNKNOWN);
return;
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index f6a453ab7..aefbdf0d5 100755
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -254,6 +254,7 @@ private:
void CreateLibraryApplet(Kernel::HLERequestContext& ctx);
void CreateStorage(Kernel::HLERequestContext& ctx);
void CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx);
+ void CreateHandleStorage(Kernel::HLERequestContext& ctx);
};
class IApplicationFunctions final : public ServiceFramework {
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp
index e2f3b7563..5ddad851a 100755
--- a/src/core/hle/service/am/applets/applets.cpp
+++ b/src/core/hle/service/am/applets/applets.cpp
@@ -241,31 +241,31 @@ void AppletManager::ClearAll() {
frontend = {};
}
-std::shared_ptr