summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--dist/icons/icons.qrc5
-rw-r--r--dist/icons/yuzu.pngbin7719 -> 0 bytes
-rw-r--r--dist/qt_themes/default/default.qrc11
-rw-r--r--dist/qt_themes/default/icons/16x16/checked.pngbin0 -> 451 bytes
-rw-r--r--dist/qt_themes/default/icons/16x16/failed.pngbin0 -> 428 bytes
-rw-r--r--dist/qt_themes/default/icons/256x256/yuzu.pngbin0 -> 9198 bytes
-rw-r--r--dist/qt_themes/default/icons/index.theme10
-rw-r--r--dist/qt_themes/qdarkstyle/icons/index.theme11
-rw-r--r--dist/qt_themes/qdarkstyle/rc/Hmovetoolbar.pngbin0 -> 220 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/Hsepartoolbar.pngbin0 -> 172 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/Vmovetoolbar.pngbin0 -> 228 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/Vsepartoolbar.pngbin0 -> 187 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/branch_closed-on.pngbin0 -> 147 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/branch_closed.pngbin0 -> 160 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/branch_open-on.pngbin0 -> 150 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/branch_open.pngbin0 -> 166 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/checkbox_checked.pngbin0 -> 492 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/checkbox_checked_disabled.pngbin0 -> 491 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/checkbox_checked_focus.pngbin0 -> 252 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate.pngbin0 -> 493 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate_disabled.pngbin0 -> 492 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate_focus.pngbin0 -> 249 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/checkbox_unchecked.pngbin0 -> 464 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/checkbox_unchecked_disabled.pngbin0 -> 464 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/checkbox_unchecked_focus.pngbin0 -> 240 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/close-hover.pngbin0 -> 598 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/close-pressed.pngbin0 -> 598 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/close.pngbin0 -> 586 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/down_arrow.pngbin0 -> 165 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/down_arrow_disabled.pngbin0 -> 166 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/left_arrow.pngbin0 -> 166 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/left_arrow_disabled.pngbin0 -> 166 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/radio_checked.pngbin0 -> 940 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/radio_checked_disabled.pngbin0 -> 972 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/radio_checked_focus.pngbin0 -> 846 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/radio_unchecked.pngbin0 -> 728 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/radio_unchecked_disabled.pngbin0 -> 760 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/radio_unchecked_focus.pngbin0 -> 646 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/right_arrow.pngbin0 -> 160 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/right_arrow_disabled.pngbin0 -> 160 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/sizegrip.pngbin0 -> 129 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/stylesheet-branch-end.pngbin0 -> 224 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/stylesheet-branch-more.pngbin0 -> 182 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/stylesheet-vline.pngbin0 -> 239 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/transparent.pngbin0 -> 195 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/undock.pngbin0 -> 578 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/up_arrow.pngbin0 -> 158 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/rc/up_arrow_disabled.pngbin0 -> 159 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/style.qrc49
-rw-r--r--dist/qt_themes/qdarkstyle/style.qss1268
-rw-r--r--externals/CMakeLists.txt1
m---------externals/dynarmic0
m---------externals/fmt0
-rw-r--r--src/common/logging/backend.cpp1
-rw-r--r--src/common/logging/log.h1
-rw-r--r--src/common/swap.h14
-rw-r--r--src/core/CMakeLists.txt4
-rw-r--r--src/core/core.cpp10
-rw-r--r--src/core/file_sys/disk_filesystem.cpp5
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp7
-rw-r--r--src/core/hle/kernel/process.cpp5
-rw-r--r--src/core/hle/kernel/svc.cpp14
-rw-r--r--src/core/hle/kernel/svc_wrap.h15
-rw-r--r--src/core/hle/kernel/thread.cpp2
-rw-r--r--src/core/hle/result.h3
-rw-r--r--src/core/hle/service/am/am.cpp8
-rw-r--r--src/core/hle/service/audio/audren_u.cpp44
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.cpp23
-rw-r--r--src/core/hle/service/hid/hid.cpp34
-rw-r--r--src/core/hle/service/nfp/nfp.cpp28
-rw-r--r--src/core/hle/service/nfp/nfp.h28
-rw-r--r--src/core/hle/service/nfp/nfp_user.cpp19
-rw-r--r--src/core/hle/service/nfp/nfp_user.h18
-rw-r--r--src/core/hle/service/service.cpp14
-rw-r--r--src/core/loader/deconstructed_rom_directory.cpp2
-rw-r--r--src/core/loader/elf.cpp2
-rw-r--r--src/core/loader/nro.cpp2
-rw-r--r--src/core/loader/nso.cpp2
-rw-r--r--src/core/memory.h9
-rw-r--r--src/core/settings.h10
-rw-r--r--src/core/telemetry_session.cpp5
-rw-r--r--src/video_core/CMakeLists.txt2
-rw-r--r--src/video_core/engines/maxwell_3d.cpp113
-rw-r--r--src/video_core/engines/maxwell_3d.h29
-rw-r--r--src/video_core/macro_interpreter.cpp257
-rw-r--r--src/video_core/macro_interpreter.h164
-rw-r--r--src/yuzu/about_dialog.cpp2
-rw-r--r--src/yuzu/configuration/config.cpp15
-rw-r--r--src/yuzu/configuration/configure_general.cpp18
-rw-r--r--src/yuzu/configuration/configure_general.ui104
-rw-r--r--src/yuzu/main.cpp30
-rw-r--r--src/yuzu/main.h13
-rw-r--r--src/yuzu/ui_settings.h4
-rw-r--r--src/yuzu_cmd/config.cpp6
-rw-r--r--src/yuzu_cmd/default_ini.h10
96 files changed, 2220 insertions, 233 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index bcd169643..86d2423ed 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -278,7 +278,7 @@ endif()
if (ENABLE_QT)
if (YUZU_USE_BUNDLED_QT)
if (MSVC14 AND ARCHITECTURE_x86_64)
- set(QT_VER qt-5.7-msvc2015_64)
+ set(QT_VER qt-5.10.0-msvc2015_64)
else()
message(FATAL_ERROR "No bundled Qt binaries for your toolchain. Disable YUZU_USE_BUNDLED_QT and provide your own.")
endif()
diff --git a/dist/icons/icons.qrc b/dist/icons/icons.qrc
deleted file mode 100644
index 575cd0861..000000000
--- a/dist/icons/icons.qrc
+++ /dev/null
@@ -1,5 +0,0 @@
-<RCC>
- <qresource prefix="icons">
- <file>yuzu.png</file>
- </qresource>
-</RCC> \ No newline at end of file
diff --git a/dist/icons/yuzu.png b/dist/icons/yuzu.png
deleted file mode 100644
index 81a745344..000000000
--- a/dist/icons/yuzu.png
+++ /dev/null
Binary files differ
diff --git a/dist/qt_themes/default/default.qrc b/dist/qt_themes/default/default.qrc
new file mode 100644
index 000000000..14a0cf6f9
--- /dev/null
+++ b/dist/qt_themes/default/default.qrc
@@ -0,0 +1,11 @@
+<RCC>
+ <qresource prefix="icons/default">
+ <file alias="index.theme">icons/index.theme</file>
+
+ <file alias="16x16/checked.png">icons/16x16/checked.png</file>
+
+ <file alias="16x16/failed.png">icons/16x16/failed.png</file>
+
+ <file alias="256x256/yuzu.png">icons/256x256/yuzu.png</file>
+ </qresource>
+</RCC>
diff --git a/dist/qt_themes/default/icons/16x16/checked.png b/dist/qt_themes/default/icons/16x16/checked.png
new file mode 100644
index 000000000..c277e6b40
--- /dev/null
+++ b/dist/qt_themes/default/icons/16x16/checked.png
Binary files differ
diff --git a/dist/qt_themes/default/icons/16x16/failed.png b/dist/qt_themes/default/icons/16x16/failed.png
new file mode 100644
index 000000000..ac10f174a
--- /dev/null
+++ b/dist/qt_themes/default/icons/16x16/failed.png
Binary files differ
diff --git a/dist/qt_themes/default/icons/256x256/yuzu.png b/dist/qt_themes/default/icons/256x256/yuzu.png
new file mode 100644
index 000000000..8fd4dc259
--- /dev/null
+++ b/dist/qt_themes/default/icons/256x256/yuzu.png
Binary files differ
diff --git a/dist/qt_themes/default/icons/index.theme b/dist/qt_themes/default/icons/index.theme
new file mode 100644
index 000000000..ac67cb236
--- /dev/null
+++ b/dist/qt_themes/default/icons/index.theme
@@ -0,0 +1,10 @@
+[Icon Theme]
+Name=default
+Comment=default theme
+Directories=16x16,256x256
+
+[16x16]
+Size=16
+
+[256x256]
+Size=256 \ No newline at end of file
diff --git a/dist/qt_themes/qdarkstyle/icons/index.theme b/dist/qt_themes/qdarkstyle/icons/index.theme
new file mode 100644
index 000000000..558ece40b
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/icons/index.theme
@@ -0,0 +1,11 @@
+[Icon Theme]
+Name=qdarkstyle
+Comment=dark theme
+Inherits=default
+Directories=16x16,256x256
+
+[16x16]
+Size=16
+
+[256x256]
+Size=256 \ No newline at end of file
diff --git a/dist/qt_themes/qdarkstyle/rc/Hmovetoolbar.png b/dist/qt_themes/qdarkstyle/rc/Hmovetoolbar.png
new file mode 100644
index 000000000..cead99ed1
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/Hmovetoolbar.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/Hsepartoolbar.png b/dist/qt_themes/qdarkstyle/rc/Hsepartoolbar.png
new file mode 100644
index 000000000..7f183c8b3
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/Hsepartoolbar.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/Vmovetoolbar.png b/dist/qt_themes/qdarkstyle/rc/Vmovetoolbar.png
new file mode 100644
index 000000000..512edcecd
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/Vmovetoolbar.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/Vsepartoolbar.png b/dist/qt_themes/qdarkstyle/rc/Vsepartoolbar.png
new file mode 100644
index 000000000..d9dc1561b
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/Vsepartoolbar.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/branch_closed-on.png b/dist/qt_themes/qdarkstyle/rc/branch_closed-on.png
new file mode 100644
index 000000000..d081e9b3b
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/branch_closed-on.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/branch_closed.png b/dist/qt_themes/qdarkstyle/rc/branch_closed.png
new file mode 100644
index 000000000..d652159a3
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/branch_closed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/branch_open-on.png b/dist/qt_themes/qdarkstyle/rc/branch_open-on.png
new file mode 100644
index 000000000..ec372b27d
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/branch_open-on.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/branch_open.png b/dist/qt_themes/qdarkstyle/rc/branch_open.png
new file mode 100644
index 000000000..66f8e1ac6
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/branch_open.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/checkbox_checked.png b/dist/qt_themes/qdarkstyle/rc/checkbox_checked.png
new file mode 100644
index 000000000..830cfee65
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/checkbox_checked.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/checkbox_checked_disabled.png b/dist/qt_themes/qdarkstyle/rc/checkbox_checked_disabled.png
new file mode 100644
index 000000000..cb63cc2fa
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/checkbox_checked_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/checkbox_checked_focus.png b/dist/qt_themes/qdarkstyle/rc/checkbox_checked_focus.png
new file mode 100644
index 000000000..671be273b
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/checkbox_checked_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate.png b/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate.png
new file mode 100644
index 000000000..41024f768
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate_disabled.png b/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate_disabled.png
new file mode 100644
index 000000000..abdc01d90
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate_focus.png b/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate_focus.png
new file mode 100644
index 000000000..415f9b6e1
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/checkbox_indeterminate_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/checkbox_unchecked.png b/dist/qt_themes/qdarkstyle/rc/checkbox_unchecked.png
new file mode 100644
index 000000000..2159aca9a
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/checkbox_unchecked.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/checkbox_unchecked_disabled.png b/dist/qt_themes/qdarkstyle/rc/checkbox_unchecked_disabled.png
new file mode 100644
index 000000000..ade721e81
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/checkbox_unchecked_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/checkbox_unchecked_focus.png b/dist/qt_themes/qdarkstyle/rc/checkbox_unchecked_focus.png
new file mode 100644
index 000000000..e4258cc47
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/checkbox_unchecked_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/close-hover.png b/dist/qt_themes/qdarkstyle/rc/close-hover.png
new file mode 100644
index 000000000..657943a66
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/close-hover.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/close-pressed.png b/dist/qt_themes/qdarkstyle/rc/close-pressed.png
new file mode 100644
index 000000000..937d00598
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/close-pressed.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/close.png b/dist/qt_themes/qdarkstyle/rc/close.png
new file mode 100644
index 000000000..bc0f57610
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/close.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/down_arrow.png b/dist/qt_themes/qdarkstyle/rc/down_arrow.png
new file mode 100644
index 000000000..e271f7f90
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/down_arrow.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/down_arrow_disabled.png b/dist/qt_themes/qdarkstyle/rc/down_arrow_disabled.png
new file mode 100644
index 000000000..5805d9842
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/down_arrow_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/left_arrow.png b/dist/qt_themes/qdarkstyle/rc/left_arrow.png
new file mode 100644
index 000000000..f808d2d72
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/left_arrow.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/left_arrow_disabled.png b/dist/qt_themes/qdarkstyle/rc/left_arrow_disabled.png
new file mode 100644
index 000000000..f5b9af8a3
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/left_arrow_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/radio_checked.png b/dist/qt_themes/qdarkstyle/rc/radio_checked.png
new file mode 100644
index 000000000..235e6b0ba
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/radio_checked.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/radio_checked_disabled.png b/dist/qt_themes/qdarkstyle/rc/radio_checked_disabled.png
new file mode 100644
index 000000000..bf0051ede
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/radio_checked_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/radio_checked_focus.png b/dist/qt_themes/qdarkstyle/rc/radio_checked_focus.png
new file mode 100644
index 000000000..700c6b525
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/radio_checked_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/radio_unchecked.png b/dist/qt_themes/qdarkstyle/rc/radio_unchecked.png
new file mode 100644
index 000000000..9a4def65c
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/radio_unchecked.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/radio_unchecked_disabled.png b/dist/qt_themes/qdarkstyle/rc/radio_unchecked_disabled.png
new file mode 100644
index 000000000..6ece890e7
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/radio_unchecked_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/radio_unchecked_focus.png b/dist/qt_themes/qdarkstyle/rc/radio_unchecked_focus.png
new file mode 100644
index 000000000..564e022d3
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/radio_unchecked_focus.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/right_arrow.png b/dist/qt_themes/qdarkstyle/rc/right_arrow.png
new file mode 100644
index 000000000..9b0a4e6a7
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/right_arrow.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/right_arrow_disabled.png b/dist/qt_themes/qdarkstyle/rc/right_arrow_disabled.png
new file mode 100644
index 000000000..5c0bee402
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/right_arrow_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/sizegrip.png b/dist/qt_themes/qdarkstyle/rc/sizegrip.png
new file mode 100644
index 000000000..350583aaa
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/sizegrip.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/stylesheet-branch-end.png b/dist/qt_themes/qdarkstyle/rc/stylesheet-branch-end.png
new file mode 100644
index 000000000..cb5d3b51f
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/stylesheet-branch-end.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/stylesheet-branch-more.png b/dist/qt_themes/qdarkstyle/rc/stylesheet-branch-more.png
new file mode 100644
index 000000000..62711409d
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/stylesheet-branch-more.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/stylesheet-vline.png b/dist/qt_themes/qdarkstyle/rc/stylesheet-vline.png
new file mode 100644
index 000000000..87536cce1
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/stylesheet-vline.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/transparent.png b/dist/qt_themes/qdarkstyle/rc/transparent.png
new file mode 100644
index 000000000..483df2513
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/transparent.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/undock.png b/dist/qt_themes/qdarkstyle/rc/undock.png
new file mode 100644
index 000000000..88691d779
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/undock.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/up_arrow.png b/dist/qt_themes/qdarkstyle/rc/up_arrow.png
new file mode 100644
index 000000000..abcc72452
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/up_arrow.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/rc/up_arrow_disabled.png b/dist/qt_themes/qdarkstyle/rc/up_arrow_disabled.png
new file mode 100644
index 000000000..b9c8e3b53
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/rc/up_arrow_disabled.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/style.qrc b/dist/qt_themes/qdarkstyle/style.qrc
new file mode 100644
index 000000000..efbd0b9dc
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/style.qrc
@@ -0,0 +1,49 @@
+<RCC>
+ <qresource prefix="icons/qdarkstyle">
+ <file alias="index.theme">icons/index.theme</file>
+ </qresource>
+ <qresource prefix="qss_icons">
+ <file>rc/up_arrow_disabled.png</file>
+ <file>rc/Hmovetoolbar.png</file>
+ <file>rc/stylesheet-branch-end.png</file>
+ <file>rc/branch_closed-on.png</file>
+ <file>rc/stylesheet-vline.png</file>
+ <file>rc/branch_closed.png</file>
+ <file>rc/branch_open-on.png</file>
+ <file>rc/transparent.png</file>
+ <file>rc/right_arrow_disabled.png</file>
+ <file>rc/sizegrip.png</file>
+ <file>rc/close.png</file>
+ <file>rc/close-hover.png</file>
+ <file>rc/close-pressed.png</file>
+ <file>rc/down_arrow.png</file>
+ <file>rc/Vmovetoolbar.png</file>
+ <file>rc/left_arrow.png</file>
+ <file>rc/stylesheet-branch-more.png</file>
+ <file>rc/up_arrow.png</file>
+ <file>rc/right_arrow.png</file>
+ <file>rc/left_arrow_disabled.png</file>
+ <file>rc/Hsepartoolbar.png</file>
+ <file>rc/branch_open.png</file>
+ <file>rc/Vsepartoolbar.png</file>
+ <file>rc/down_arrow_disabled.png</file>
+ <file>rc/undock.png</file>
+ <file>rc/checkbox_checked_disabled.png</file>
+ <file>rc/checkbox_checked_focus.png</file>
+ <file>rc/checkbox_checked.png</file>
+ <file>rc/checkbox_indeterminate.png</file>
+ <file>rc/checkbox_indeterminate_focus.png</file>
+ <file>rc/checkbox_unchecked_disabled.png</file>
+ <file>rc/checkbox_unchecked_focus.png</file>
+ <file>rc/checkbox_unchecked.png</file>
+ <file>rc/radio_checked_disabled.png</file>
+ <file>rc/radio_checked_focus.png</file>
+ <file>rc/radio_checked.png</file>
+ <file>rc/radio_unchecked_disabled.png</file>
+ <file>rc/radio_unchecked_focus.png</file>
+ <file>rc/radio_unchecked.png</file>
+ </qresource>
+ <qresource prefix="qdarkstyle">
+ <file>style.qss</file>
+ </qresource>
+</RCC>
diff --git a/dist/qt_themes/qdarkstyle/style.qss b/dist/qt_themes/qdarkstyle/style.qss
new file mode 100644
index 000000000..c8e50312a
--- /dev/null
+++ b/dist/qt_themes/qdarkstyle/style.qss
@@ -0,0 +1,1268 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) <2013-2014> <Colin Duquesnoy>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+QToolTip
+{
+ border: 1px solid #76797C;
+ background-color: rgb(90, 102, 117);;
+ color: white;
+ padding: 5px;
+ opacity: 200;
+}
+
+QWidget
+{
+ color: #eff0f1;
+ background-color: #31363b;
+ selection-background-color:#3daee9;
+ selection-color: #eff0f1;
+ background-clip: border;
+ border-image: none;
+ border: 0px transparent black;
+ outline: 0;
+}
+
+QWidget:item:hover
+{
+ background-color: #18465d;
+ color: #eff0f1;
+}
+
+QWidget:item:selected
+{
+ background-color: #18465d;
+}
+
+QCheckBox
+{
+ spacing: 5px;
+ outline: none;
+ color: #eff0f1;
+ margin-bottom: 2px;
+}
+
+QCheckBox:disabled
+{
+ color: #76797C;
+}
+
+QCheckBox::indicator,
+QGroupBox::indicator
+{
+ width: 18px;
+ height: 18px;
+}
+QGroupBox::indicator
+{
+ margin-left: 2px;
+}
+
+QCheckBox::indicator:unchecked
+{
+ image: url(:/qss_icons/rc/checkbox_unchecked.png);
+}
+
+QCheckBox::indicator:unchecked:hover,
+QCheckBox::indicator:unchecked:focus,
+QCheckBox::indicator:unchecked:pressed,
+QGroupBox::indicator:unchecked:hover,
+QGroupBox::indicator:unchecked:focus,
+QGroupBox::indicator:unchecked:pressed
+{
+ border: none;
+ image: url(:/qss_icons/rc/checkbox_unchecked_focus.png);
+}
+
+QCheckBox::indicator:checked
+{
+ image: url(:/qss_icons/rc/checkbox_checked.png);
+}
+
+QCheckBox::indicator:checked:hover,
+QCheckBox::indicator:checked:focus,
+QCheckBox::indicator:checked:pressed,
+QGroupBox::indicator:checked:hover,
+QGroupBox::indicator:checked:focus,
+QGroupBox::indicator:checked:pressed
+{
+ border: none;
+ image: url(:/qss_icons/rc/checkbox_checked_focus.png);
+}
+
+
+QCheckBox::indicator:indeterminate
+{
+ image: url(:/qss_icons/rc/checkbox_indeterminate.png);
+}
+
+QCheckBox::indicator:indeterminate:focus,
+QCheckBox::indicator:indeterminate:hover,
+QCheckBox::indicator:indeterminate:pressed
+{
+ image: url(:/qss_icons/rc/checkbox_indeterminate_focus.png);
+}
+
+QCheckBox::indicator:checked:disabled,
+QGroupBox::indicator:checked:disabled
+{
+ image: url(:/qss_icons/rc/checkbox_checked_disabled.png);
+}
+
+QCheckBox::indicator:unchecked:disabled,
+QGroupBox::indicator:unchecked:disabled
+{
+ image: url(:/qss_icons/rc/checkbox_unchecked_disabled.png);
+}
+
+QRadioButton
+{
+ spacing: 5px;
+ outline: none;
+ color: #eff0f1;
+ margin-bottom: 2px;
+}
+
+QRadioButton:disabled
+{
+ color: #76797C;
+}
+QRadioButton::indicator
+{
+ width: 21px;
+ height: 21px;
+}
+
+QRadioButton::indicator:unchecked
+{
+ image: url(:/qss_icons/rc/radio_unchecked.png);
+}
+
+
+QRadioButton::indicator:unchecked:hover,
+QRadioButton::indicator:unchecked:focus,
+QRadioButton::indicator:unchecked:pressed
+{
+ border: none;
+ outline: none;
+ image: url(:/qss_icons/rc/radio_unchecked_focus.png);
+}
+
+QRadioButton::indicator:checked
+{
+ border: none;
+ outline: none;
+ image: url(:/qss_icons/rc/radio_checked.png);
+}
+
+QRadioButton::indicator:checked:hover,
+QRadioButton::indicator:checked:focus,
+QRadioButton::indicator:checked:pressed
+{
+ border: none;
+ outline: none;
+ image: url(:/qss_icons/rc/radio_checked_focus.png);
+}
+
+QRadioButton::indicator:checked:disabled
+{
+ outline: none;
+ image: url(:/qss_icons/rc/radio_checked_disabled.png);
+}
+
+QRadioButton::indicator:unchecked:disabled
+{
+ image: url(:/qss_icons/rc/radio_unchecked_disabled.png);
+}
+
+
+QMenuBar
+{
+ background-color: #31363b;
+ color: #eff0f1;
+}
+
+QMenuBar::item
+{
+ background: transparent;
+}
+
+QMenuBar::item:selected
+{
+ background: transparent;
+ border: 1px solid #76797C;
+}
+
+QMenuBar::item:pressed
+{
+ border: 1px solid #76797C;
+ background-color: #3daee9;
+ color: #eff0f1;
+ margin-bottom:-1px;
+ padding-bottom:1px;
+}
+
+QMenu
+{
+ border: 1px solid #76797C;
+ color: #eff0f1;
+ margin: 2px;
+}
+
+QMenu::icon
+{
+ margin: 5px;
+}
+
+QMenu::item
+{
+ padding: 5px 30px 5px 30px;
+ margin-left: 5px;
+ border: 1px solid transparent; /* reserve space for selection border */
+}
+
+QMenu::item:selected
+{
+ color: #eff0f1;
+}
+
+QMenu::separator {
+ height: 2px;
+ background: lightblue;
+ margin-left: 10px;
+ margin-right: 5px;
+}
+
+QMenu::indicator {
+ width: 18px;
+ height: 18px;
+}
+
+/* non-exclusive indicator = check box style indicator
+ (see QActionGroup::setExclusive) */
+QMenu::indicator:non-exclusive:unchecked {
+ image: url(:/qss_icons/rc/checkbox_unchecked.png);
+}
+
+QMenu::indicator:non-exclusive:unchecked:selected {
+ image: url(:/qss_icons/rc/checkbox_unchecked_disabled.png);
+}
+
+QMenu::indicator:non-exclusive:checked {
+ image: url(:/qss_icons/rc/checkbox_checked.png);
+}
+
+QMenu::indicator:non-exclusive:checked:selected {
+ image: url(:/qss_icons/rc/checkbox_checked_disabled.png);
+}
+
+/* exclusive indicator = radio button style indicator (see QActionGroup::setExclusive) */
+QMenu::indicator:exclusive:unchecked {
+ image: url(:/qss_icons/rc/radio_unchecked.png);
+}
+
+QMenu::indicator:exclusive:unchecked:selected {
+ image: url(:/qss_icons/rc/radio_unchecked_disabled.png);
+}
+
+QMenu::indicator:exclusive:checked {
+ image: url(:/qss_icons/rc/radio_checked.png);
+}
+
+QMenu::indicator:exclusive:checked:selected {
+ image: url(:/qss_icons/rc/radio_checked_disabled.png);
+}
+
+QMenu::right-arrow {
+ margin: 5px;
+ image: url(:/qss_icons/rc/right_arrow.png)
+}
+
+
+QWidget:disabled
+{
+ color: #454545;
+ background-color: #31363b;
+}
+
+QAbstractItemView
+{
+ alternate-background-color: #31363b;
+ color: #eff0f1;
+ border: 1px solid 3A3939;
+ border-radius: 2px;
+}
+
+QWidget:focus, QMenuBar:focus
+{
+ border: 1px solid #3daee9;
+}
+
+QTabWidget:focus, QCheckBox:focus, QRadioButton:focus, QSlider:focus
+{
+ border: none;
+}
+
+QLineEdit
+{
+ background-color: #232629;
+ padding: 5px;
+ border-style: solid;
+ border: 1px solid #76797C;
+ border-radius: 2px;
+ color: #eff0f1;
+}
+
+QAbstractItemView QLineEdit
+{
+ padding: 0;
+}
+
+QGroupBox {
+ border:1px solid #76797C;
+ border-radius: 2px;
+ margin-top: 20px;
+}
+
+QGroupBox::title {
+ subcontrol-origin: margin;
+ subcontrol-position: top center;
+ padding-left: 10px;
+ padding-right: 10px;
+ padding-top: 10px;
+}
+
+QAbstractScrollArea
+{
+ border-radius: 2px;
+ border: 1px solid #76797C;
+ background-color: transparent;
+}
+
+QScrollBar:horizontal
+{
+ height: 15px;
+ margin: 3px 15px 3px 15px;
+ border: 1px transparent #2A2929;
+ border-radius: 4px;
+ background-color: #2A2929;
+}
+
+QScrollBar::handle:horizontal
+{
+ background-color: #605F5F;
+ min-width: 5px;
+ border-radius: 4px;
+}
+
+QScrollBar::add-line:horizontal
+{
+ margin: 0px 3px 0px 3px;
+ border-image: url(:/qss_icons/rc/right_arrow_disabled.png);
+ width: 10px;
+ height: 10px;
+ subcontrol-position: right;
+ subcontrol-origin: margin;
+}
+
+QScrollBar::sub-line:horizontal
+{
+ margin: 0px 3px 0px 3px;
+ border-image: url(:/qss_icons/rc/left_arrow_disabled.png);
+ height: 10px;
+ width: 10px;
+ subcontrol-position: left;
+ subcontrol-origin: margin;
+}
+
+QScrollBar::add-line:horizontal:hover,QScrollBar::add-line:horizontal:on
+{
+ border-image: url(:/qss_icons/rc/right_arrow.png);
+ height: 10px;
+ width: 10px;
+ subcontrol-position: right;
+ subcontrol-origin: margin;
+}
+
+
+QScrollBar::sub-line:horizontal:hover, QScrollBar::sub-line:horizontal:on
+{
+ border-image: url(:/qss_icons/rc/left_arrow.png);
+ height: 10px;
+ width: 10px;
+ subcontrol-position: left;
+ subcontrol-origin: margin;
+}
+
+QScrollBar::up-arrow:horizontal, QScrollBar::down-arrow:horizontal
+{
+ background: none;
+}
+
+
+QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal
+{
+ background: none;
+}
+
+QScrollBar:vertical
+{
+ background-color: #2A2929;
+ width: 15px;
+ margin: 15px 3px 15px 3px;
+ border: 1px transparent #2A2929;
+ border-radius: 4px;
+}
+
+QScrollBar::handle:vertical
+{
+ background-color: #605F5F;
+ min-height: 5px;
+ border-radius: 4px;
+}
+
+QScrollBar::sub-line:vertical
+{
+ margin: 3px 0px 3px 0px;
+ border-image: url(:/qss_icons/rc/up_arrow_disabled.png);
+ height: 10px;
+ width: 10px;
+ subcontrol-position: top;
+ subcontrol-origin: margin;
+}
+
+QScrollBar::add-line:vertical
+{
+ margin: 3px 0px 3px 0px;
+ border-image: url(:/qss_icons/rc/down_arrow_disabled.png);
+ height: 10px;
+ width: 10px;
+ subcontrol-position: bottom;
+ subcontrol-origin: margin;
+}
+
+QScrollBar::sub-line:vertical:hover,QScrollBar::sub-line:vertical:on
+{
+
+ border-image: url(:/qss_icons/rc/up_arrow.png);
+ height: 10px;
+ width: 10px;
+ subcontrol-position: top;
+ subcontrol-origin: margin;
+}
+
+
+QScrollBar::add-line:vertical:hover, QScrollBar::add-line:vertical:on
+{
+ border-image: url(:/qss_icons/rc/down_arrow.png);
+ height: 10px;
+ width: 10px;
+ subcontrol-position: bottom;
+ subcontrol-origin: margin;
+}
+
+QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical
+{
+ background: none;
+}
+
+
+QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical
+{
+ background: none;
+}
+
+QTextEdit
+{
+ background-color: #232629;
+ color: #eff0f1;
+ border: 1px solid #76797C;
+}
+
+QPlainTextEdit
+{
+ background-color: #232629;;
+ color: #eff0f1;
+ border-radius: 2px;
+ border: 1px solid #76797C;
+}
+
+QHeaderView::section
+{
+ background-color: #76797C;
+ color: #eff0f1;
+ padding: 5px;
+ border: 1px solid #76797C;
+}
+
+QSizeGrip {
+ image: url(:/qss_icons/rc/sizegrip.png);
+ width: 12px;
+ height: 12px;
+}
+
+
+QMainWindow::separator
+{
+ background-color: #31363b;
+ color: white;
+ padding-left: 4px;
+ spacing: 2px;
+ border: 1px dashed #76797C;
+}
+
+QMainWindow::separator:hover
+{
+
+ background-color: #787876;
+ color: white;
+ padding-left: 4px;
+ border: 1px solid #76797C;
+ spacing: 2px;
+}
+
+
+QMenu::separator
+{
+ height: 1px;
+ background-color: #76797C;
+ color: white;
+ padding-left: 4px;
+ margin-left: 10px;
+ margin-right: 5px;
+}
+
+
+QFrame
+{
+ border-radius: 2px;
+ border: 1px solid #76797C;
+}
+
+QFrame[frameShape="0"]
+{
+ border-radius: 2px;
+ border: 1px transparent #76797C;
+}
+
+QStackedWidget
+{
+ border: 1px transparent black;
+}
+
+QToolBar {
+ border: 1px transparent #393838;
+ background: 1px solid #31363b;
+ font-weight: bold;
+}
+
+QToolBar::handle:horizontal {
+ image: url(:/qss_icons/rc/Hmovetoolbar.png);
+}
+QToolBar::handle:vertical {
+ image: url(:/qss_icons/rc/Vmovetoolbar.png);
+}
+QToolBar::separator:horizontal {
+ image: url(:/qss_icons/rc/Hsepartoolbar.png);
+}
+QToolBar::separator:vertical {
+ image: url(:/qss_icons/rc/Vsepartoolbar.png);
+}
+QToolButton#qt_toolbar_ext_button {
+ background: #58595a
+}
+
+QPushButton
+{
+ color: #eff0f1;
+ background-color: #31363b;
+ border-width: 1px;
+ border-color: #76797C;
+ border-style: solid;
+ padding: 5px;
+ border-radius: 2px;
+ outline: none;
+}
+
+QPushButton:disabled
+{
+ background-color: #31363b;
+ border-width: 1px;
+ border-color: #454545;
+ border-style: solid;
+ padding-top: 5px;
+ padding-bottom: 5px;
+ padding-left: 10px;
+ padding-right: 10px;
+ border-radius: 2px;
+ color: #454545;
+}
+
+QPushButton:focus {
+ background-color: #3daee9;
+ color: white;
+}
+
+QPushButton:pressed
+{
+ background-color: #3daee9;
+ padding-top: -15px;
+ padding-bottom: -17px;
+}
+
+QComboBox
+{
+ selection-background-color: #3daee9;
+ border-style: solid;
+ border: 1px solid #76797C;
+ border-radius: 2px;
+ padding: 5px;
+ min-width: 75px;
+}
+
+QPushButton:checked{
+ background-color: #76797C;
+ border-color: #6A6969;
+}
+
+QComboBox:hover,QPushButton:hover,QAbstractSpinBox:hover,QLineEdit:hover,QTextEdit:hover,QPlainTextEdit:hover,QAbstractView:hover,QTreeView:hover
+{
+ border: 1px solid #3daee9;
+ color: #eff0f1;
+}
+
+QComboBox:on
+{
+ padding-top: 3px;
+ padding-left: 4px;
+ selection-background-color: #4a4a4a;
+}
+
+QComboBox QAbstractItemView
+{
+ background-color: #232629;
+ border-radius: 2px;
+ border: 1px solid #76797C;
+ selection-background-color: #18465d;
+}
+
+QComboBox::drop-down
+{
+ subcontrol-origin: padding;
+ subcontrol-position: top right;
+ width: 15px;
+
+ border-left-width: 0px;
+ border-left-color: darkgray;
+ border-left-style: solid;
+ border-top-right-radius: 3px;
+ border-bottom-right-radius: 3px;
+}
+
+QComboBox::down-arrow
+{
+ image: url(:/qss_icons/rc/down_arrow_disabled.png);
+}
+
+QComboBox::down-arrow:on, QComboBox::down-arrow:hover,
+QComboBox::down-arrow:focus
+{
+ image: url(:/qss_icons/rc/down_arrow.png);
+}
+
+QAbstractSpinBox {
+ padding: 5px;
+ border: 1px solid #76797C;
+ background-color: #232629;
+ color: #eff0f1;
+ border-radius: 2px;
+ min-width: 75px;
+}
+
+QAbstractSpinBox:up-button
+{
+ background-color: transparent;
+ subcontrol-origin: border;
+ subcontrol-position: center right;
+}
+
+QAbstractSpinBox:down-button
+{
+ background-color: transparent;
+ subcontrol-origin: border;
+ subcontrol-position: center left;
+}
+
+QAbstractSpinBox::up-arrow,QAbstractSpinBox::up-arrow:disabled,QAbstractSpinBox::up-arrow:off {
+ image: url(:/qss_icons/rc/up_arrow_disabled.png);
+ width: 10px;
+ height: 10px;
+}
+QAbstractSpinBox::up-arrow:hover
+{
+ image: url(:/qss_icons/rc/up_arrow.png);
+}
+
+
+QAbstractSpinBox::down-arrow,QAbstractSpinBox::down-arrow:disabled,QAbstractSpinBox::down-arrow:off
+{
+ image: url(:/qss_icons/rc/down_arrow_disabled.png);
+ width: 10px;
+ height: 10px;
+}
+QAbstractSpinBox::down-arrow:hover
+{
+ image: url(:/qss_icons/rc/down_arrow.png);
+}
+
+
+QLabel
+{
+ border: 0px solid black;
+}
+
+QTabWidget{
+ border: 0px transparent black;
+}
+
+QTabWidget::pane {
+ border: 1px solid #76797C;
+ padding: 5px;
+ margin: 0px;
+}
+
+QTabWidget::tab-bar {
+ left: 5px; /* move to the right by 5px */
+}
+
+QTabBar
+{
+ qproperty-drawBase: 0;
+ border-radius: 3px;
+}
+
+QTabBar:focus
+{
+ border: 0px transparent black;
+}
+
+QTabBar::close-button {
+ image: url(:/qss_icons/rc/close.png);
+ background: transparent;
+}
+
+QTabBar::close-button:hover
+{
+ image: url(:/qss_icons/rc/close-hover.png);
+ background: transparent;
+}
+
+QTabBar::close-button:pressed {
+ image: url(:/qss_icons/rc/close-pressed.png);
+ background: transparent;
+}
+
+/* TOP TABS */
+QTabBar::tab:top {
+ color: #eff0f1;
+ border: 1px solid #76797C;
+ border-bottom: 1px transparent black;
+ background-color: #31363b;
+ padding: 5px;
+ min-width: 50px;
+ border-top-left-radius: 2px;
+ border-top-right-radius: 2px;
+}
+
+QTabBar::tab:top:!selected
+{
+ color: #eff0f1;
+ background-color: #54575B;
+ border: 1px solid #76797C;
+ border-bottom: 1px transparent black;
+ border-top-left-radius: 2px;
+ border-top-right-radius: 2px;
+}
+
+QTabBar::tab:top:!selected:hover {
+ background-color: #3daee9;
+}
+
+/* BOTTOM TABS */
+QTabBar::tab:bottom {
+ color: #eff0f1;
+ border: 1px solid #76797C;
+ border-top: 1px transparent black;
+ background-color: #31363b;
+ padding: 5px;
+ border-bottom-left-radius: 2px;
+ border-bottom-right-radius: 2px;
+ min-width: 50px;
+}
+
+QTabBar::tab:bottom:!selected
+{
+ color: #eff0f1;
+ background-color: #54575B;
+ border: 1px solid #76797C;
+ border-top: 1px transparent black;
+ border-bottom-left-radius: 2px;
+ border-bottom-right-radius: 2px;
+}
+
+QTabBar::tab:bottom:!selected:hover {
+ background-color: #3daee9;
+}
+
+/* LEFT TABS */
+QTabBar::tab:left {
+ color: #eff0f1;
+ border: 1px solid #76797C;
+ border-left: 1px transparent black;
+ background-color: #31363b;
+ padding: 5px;
+ border-top-right-radius: 2px;
+ border-bottom-right-radius: 2px;
+ min-height: 50px;
+}
+
+QTabBar::tab:left:!selected
+{
+ color: #eff0f1;
+ background-color: #54575B;
+ border: 1px solid #76797C;
+ border-left: 1px transparent black;
+ border-top-right-radius: 2px;
+ border-bottom-right-radius: 2px;
+}
+
+QTabBar::tab:left:!selected:hover {
+ background-color: #3daee9;
+}
+
+
+/* RIGHT TABS */
+QTabBar::tab:right {
+ color: #eff0f1;
+ border: 1px solid #76797C;
+ border-right: 1px transparent black;
+ background-color: #31363b;
+ padding: 5px;
+ border-top-left-radius: 2px;
+ border-bottom-left-radius: 2px;
+ min-height: 50px;
+}
+
+QTabBar::tab:right:!selected
+{
+ color: #eff0f1;
+ background-color: #54575B;
+ border: 1px solid #76797C;
+ border-right: 1px transparent black;
+ border-top-left-radius: 2px;
+ border-bottom-left-radius: 2px;
+}
+
+QTabBar::tab:right:!selected:hover {
+ background-color: #3daee9;
+}
+
+QTabBar QToolButton::right-arrow:enabled {
+ image: url(:/qss_icons/rc/right_arrow.png);
+ }
+
+ QTabBar QToolButton::left-arrow:enabled {
+ image: url(:/qss_icons/rc/left_arrow.png);
+ }
+
+QTabBar QToolButton::right-arrow:disabled {
+ image: url(:/qss_icons/rc/right_arrow_disabled.png);
+ }
+
+ QTabBar QToolButton::left-arrow:disabled {
+ image: url(:/qss_icons/rc/left_arrow_disabled.png);
+ }
+
+
+QDockWidget {
+ background: #31363b;
+ border: 1px solid #403F3F;
+ titlebar-close-icon: url(:/qss_icons/rc/close.png);
+ titlebar-normal-icon: url(:/qss_icons/rc/undock.png);
+}
+
+QDockWidget::close-button, QDockWidget::float-button {
+ border: 1px solid transparent;
+ border-radius: 2px;
+ background: transparent;
+}
+
+QDockWidget::close-button:hover, QDockWidget::float-button:hover {
+ background: rgba(255, 255, 255, 10);
+}
+
+QDockWidget::close-button:pressed, QDockWidget::float-button:pressed {
+ padding: 1px -1px -1px 1px;
+ background: rgba(255, 255, 255, 10);
+}
+
+QTreeView, QListView
+{
+ border: 1px solid #76797C;
+ background-color: #232629;
+}
+
+QTreeView:branch:selected, QTreeView:branch:hover
+{
+ background: url(:/qss_icons/rc/transparent.png);
+}
+
+QTreeView::branch:has-siblings:!adjoins-item {
+ border-image: url(:/qss_icons/rc/transparent.png);
+}
+
+QTreeView::branch:has-siblings:adjoins-item {
+ border-image: url(:/qss_icons/rc/transparent.png);
+}
+
+QTreeView::branch:!has-children:!has-siblings:adjoins-item {
+ border-image: url(:/qss_icons/rc/transparent.png);
+}
+
+QTreeView::branch:has-children:!has-siblings:closed,
+QTreeView::branch:closed:has-children:has-siblings {
+ image: url(:/qss_icons/rc/branch_closed.png);
+}
+
+QTreeView::branch:open:has-children:!has-siblings,
+QTreeView::branch:open:has-children:has-siblings {
+ image: url(:/qss_icons/rc/branch_open.png);
+}
+
+QTreeView::branch:has-children:!has-siblings:closed:hover,
+QTreeView::branch:closed:has-children:has-siblings:hover {
+ image: url(:/qss_icons/rc/branch_closed-on.png);
+ }
+
+QTreeView::branch:open:has-children:!has-siblings:hover,
+QTreeView::branch:open:has-children:has-siblings:hover {
+ image: url(:/qss_icons/rc/branch_open-on.png);
+ }
+
+QListView::item:!selected:hover, QTreeView::item:!selected:hover {
+ background: #18465d;
+ outline: 0;
+ color: #eff0f1
+}
+
+QListView::item:selected:hover, QTreeView::item:selected:hover {
+ background: #287399;
+ color: #eff0f1;
+}
+
+QSlider::groove:horizontal {
+ border: 1px solid #565a5e;
+ height: 4px;
+ background: #565a5e;
+ margin: 0px;
+ border-radius: 2px;
+}
+
+QSlider::handle:horizontal {
+ background: #232629;
+ border: 1px solid #565a5e;
+ width: 16px;
+ height: 16px;
+ margin: -8px 0;
+ border-radius: 9px;
+}
+
+QSlider::groove:vertical {
+ border: 1px solid #565a5e;
+ width: 4px;
+ background: #565a5e;
+ margin: 0px;
+ border-radius: 3px;
+}
+
+QSlider::handle:vertical {
+ background: #232629;
+ border: 1px solid #565a5e;
+ width: 16px;
+ height: 16px;
+ margin: 0 -8px;
+ border-radius: 9px;
+}
+
+QToolButton {
+ background-color: transparent;
+ border: 1px transparent #76797C;
+ border-radius: 2px;
+ margin: 3px;
+ padding: 5px;
+}
+
+QToolButton[popupMode="1"] { /* only for MenuButtonPopup */
+ padding-right: 20px; /* make way for the popup button */
+ border: 1px #76797C;
+ border-radius: 5px;
+}
+
+QToolButton[popupMode="2"] { /* only for InstantPopup */
+ padding-right: 10px; /* make way for the popup button */
+ border: 1px #76797C;
+}
+
+
+QToolButton:hover, QToolButton::menu-button:hover {
+ background-color: transparent;
+ border: 1px solid #3daee9;
+ padding: 5px;
+}
+
+QToolButton:checked, QToolButton:pressed,
+ QToolButton::menu-button:pressed {
+ background-color: #3daee9;
+ border: 1px solid #3daee9;
+ padding: 5px;
+}
+
+/* the subcontrol below is used only in the InstantPopup or DelayedPopup mode */
+QToolButton::menu-indicator {
+ image: url(:/qss_icons/rc/down_arrow.png);
+ top: -7px; left: -2px; /* shift it a bit */
+}
+
+/* the subcontrols below are used only in the MenuButtonPopup mode */
+QToolButton::menu-button {
+ border: 1px transparent #76797C;
+ border-top-right-radius: 6px;
+ border-bottom-right-radius: 6px;
+ /* 16px width + 4px for border = 20px allocated above */
+ width: 16px;
+ outline: none;
+}
+
+QToolButton::menu-arrow {
+ image: url(:/qss_icons/rc/down_arrow.png);
+}
+
+QToolButton::menu-arrow:open {
+ border: 1px solid #76797C;
+}
+
+QPushButton::menu-indicator {
+ subcontrol-origin: padding;
+ subcontrol-position: bottom right;
+ left: 8px;
+}
+
+QTableView
+{
+ border: 1px solid #76797C;
+ gridline-color: #31363b;
+ background-color: #232629;
+}
+
+
+QTableView, QHeaderView
+{
+ border-radius: 0px;
+}
+
+QTableView::item:pressed, QListView::item:pressed, QTreeView::item:pressed {
+ background: #18465d;
+ color: #eff0f1;
+}
+
+QTableView::item:selected:active, QTreeView::item:selected:active, QListView::item:selected:active {
+ background: #287399;
+ color: #eff0f1;
+}
+
+
+QHeaderView
+{
+ background-color: #31363b;
+ border: 1px transparent;
+ border-radius: 0px;
+ margin: 0px;
+ padding: 0px;
+
+}
+
+QHeaderView::section {
+ background-color: #31363b;
+ color: #eff0f1;
+ padding: 5px;
+ border: 1px solid #76797C;
+ border-radius: 0px;
+ text-align: center;
+}
+
+QHeaderView::section::vertical::first, QHeaderView::section::vertical::only-one
+{
+ border-top: 1px solid #76797C;
+}
+
+QHeaderView::section::vertical
+{
+ border-top: transparent;
+}
+
+QHeaderView::section::horizontal::first, QHeaderView::section::horizontal::only-one
+{
+ border-left: 1px solid #76797C;
+}
+
+QHeaderView::section::horizontal
+{
+ border-left: transparent;
+}
+
+
+QHeaderView::section:checked
+ {
+ color: white;
+ background-color: #334e5e;
+ }
+
+ /* style the sort indicator */
+QHeaderView::down-arrow {
+ image: url(:/qss_icons/rc/down_arrow.png);
+}
+
+QHeaderView::up-arrow {
+ image: url(:/qss_icons/rc/up_arrow.png);
+}
+
+
+QTableCornerButton::section {
+ background-color: #31363b;
+ border: 1px transparent #76797C;
+ border-radius: 0px;
+}
+
+QToolBox {
+ padding: 5px;
+ border: 1px transparent black;
+}
+
+QToolBox::tab {
+ color: #eff0f1;
+ background-color: #31363b;
+ border: 1px solid #76797C;
+ border-bottom: 1px transparent #31363b;
+ border-top-left-radius: 5px;
+ border-top-right-radius: 5px;
+}
+
+QToolBox::tab:selected { /* italicize selected tabs */
+ font: italic;
+ background-color: #31363b;
+ border-color: #3daee9;
+ }
+
+QStatusBar::item {
+ border: 0px transparent dark;
+ }
+
+
+QFrame[height="3"], QFrame[width="3"] {
+ background-color: #76797C;
+}
+
+
+QSplitter::handle {
+ border: 1px dashed #76797C;
+}
+
+QSplitter::handle:hover {
+ background-color: #787876;
+ border: 1px solid #76797C;
+}
+
+QSplitter::handle:horizontal {
+ width: 1px;
+}
+
+QSplitter::handle:vertical {
+ height: 1px;
+}
+
+QProgressBar {
+ border: 1px solid #76797C;
+ border-radius: 5px;
+ text-align: center;
+}
+
+QProgressBar::chunk {
+ background-color: #05B8CC;
+}
+
+QDateEdit
+{
+ selection-background-color: #3daee9;
+ border-style: solid;
+ border: 1px solid #3375A3;
+ border-radius: 2px;
+ padding: 1px;
+ min-width: 75px;
+}
+
+QDateEdit:on
+{
+ padding-top: 3px;
+ padding-left: 4px;
+ selection-background-color: #4a4a4a;
+}
+
+QDateEdit QAbstractItemView
+{
+ background-color: #232629;
+ border-radius: 2px;
+ border: 1px solid #3375A3;
+ selection-background-color: #3daee9;
+}
+
+QDateEdit::drop-down
+{
+ subcontrol-origin: padding;
+ subcontrol-position: top right;
+ width: 15px;
+ border-left-width: 0px;
+ border-left-color: darkgray;
+ border-left-style: solid;
+ border-top-right-radius: 3px;
+ border-bottom-right-radius: 3px;
+}
+
+QDateEdit::down-arrow
+{
+ image: url(:/qss_icons/rc/down_arrow_disabled.png);
+}
+
+QDateEdit::down-arrow:on, QDateEdit::down-arrow:hover,
+QDateEdit::down-arrow:focus
+{
+ image: url(:/qss_icons/rc/down_arrow.png);
+}
diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt
index ec3c70779..d2b0652a5 100644
--- a/externals/CMakeLists.txt
+++ b/externals/CMakeLists.txt
@@ -17,6 +17,7 @@ endif()
# libfmt
add_subdirectory(fmt)
+add_library(fmt::fmt ALIAS fmt)
# getopt
if (MSVC)
diff --git a/externals/dynarmic b/externals/dynarmic
-Subproject 6b4c6b06a94290690d2132adfa45a8087958c2c
+Subproject 9cc12d80b984be5a383af8f471e65b52cc1895f
diff --git a/externals/fmt b/externals/fmt
-Subproject ac5484c4e7365b59d8c7e14db6778de26635e42
+Subproject 4d35f94133ed14794e53c9f8627d047b408e0dc
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index 9bfac5e7f..a763f4abf 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -42,6 +42,7 @@ namespace Log {
SUB(Service, FS) \
SUB(Service, HID) \
SUB(Service, LM) \
+ SUB(Service, NFP) \
SUB(Service, NIFM) \
SUB(Service, NS) \
SUB(Service, NVDRV) \
diff --git a/src/common/logging/log.h b/src/common/logging/log.h
index 6913f6b10..7f079b20f 100644
--- a/src/common/logging/log.h
+++ b/src/common/logging/log.h
@@ -59,6 +59,7 @@ enum class Class : ClassType {
Service_FS, ///< The FS (Filesystem) service
Service_HID, ///< The HID (Human interface device) service
Service_LM, ///< The LM (Logger) service
+ Service_NFP, ///< The NFP service
Service_NIFM, ///< The NIFM (Network interface) service
Service_NS, ///< The NS services
Service_NVDRV, ///< The NVDRV (Nvidia driver) service
diff --git a/src/common/swap.h b/src/common/swap.h
index d94cbe6b2..4a4012d1a 100644
--- a/src/common/swap.h
+++ b/src/common/swap.h
@@ -103,7 +103,19 @@ inline __attribute__((always_inline)) u64 swap64(u64 _data) {
return __builtin_bswap64(_data);
}
#elif defined(__Bitrig__) || defined(__OpenBSD__)
-// swap16, swap32, swap64 are left as is
+// redefine swap16, swap32, swap64 as inline functions
+#undef swap16
+#undef swap32
+#undef swap64
+inline u16 swap16(u16 _data) {
+ return __swap16(_data);
+}
+inline u32 swap32(u32 _data) {
+ return __swap32(_data);
+}
+inline u64 swap64(u64 _data) {
+ return __swap64(_data);
+}
#elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__)
inline u16 swap16(u16 _data) {
return bswap16(_data);
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 3d187cd40..6f8104516 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -142,6 +142,10 @@ add_library(core STATIC
hle/service/nifm/nifm_s.h
hle/service/nifm/nifm_u.cpp
hle/service/nifm/nifm_u.h
+ hle/service/nfp/nfp.cpp
+ hle/service/nfp/nfp.h
+ hle/service/nfp/nfp_user.cpp
+ hle/service/nfp/nfp_user.h
hle/service/ns/ns.cpp
hle/service/ns/ns.h
hle/service/ns/pl_u.cpp
diff --git a/src/core/core.cpp b/src/core/core.cpp
index d55621de8..11654d4da 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -148,19 +148,15 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
current_process = Kernel::Process::Create("main");
- switch (Settings::values.cpu_core) {
- case Settings::CpuCore::Unicorn:
- cpu_core = std::make_shared<ARM_Unicorn>();
- break;
- case Settings::CpuCore::Dynarmic:
- default:
+ if (Settings::values.use_cpu_jit) {
#ifdef ARCHITECTURE_x86_64
cpu_core = std::make_shared<ARM_Dynarmic>();
#else
cpu_core = std::make_shared<ARM_Unicorn>();
LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available");
#endif
- break;
+ } else {
+ cpu_core = std::make_shared<ARM_Unicorn>();
}
gpu_core = std::make_unique<Tegra::GPU>();
diff --git a/src/core/file_sys/disk_filesystem.cpp b/src/core/file_sys/disk_filesystem.cpp
index 3a4b45721..4235f3935 100644
--- a/src/core/file_sys/disk_filesystem.cpp
+++ b/src/core/file_sys/disk_filesystem.cpp
@@ -174,8 +174,9 @@ u64 Disk_Storage::GetSize() const {
}
bool Disk_Storage::SetSize(const u64 size) const {
- LOG_WARNING(Service_FS, "(STUBBED) called");
- return false;
+ file->Resize(size);
+ file->Flush();
+ return true;
}
Disk_Directory::Disk_Directory(const std::string& path) : directory() {
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index ffcbfe64f..bef4f15f5 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -268,8 +268,11 @@ std::vector<u8> HLERequestContext::ReadBuffer() const {
size_t HLERequestContext::WriteBuffer(const void* buffer, size_t size) const {
const bool is_buffer_b{BufferDescriptorB().size() && BufferDescriptorB()[0].Size()};
-
- ASSERT_MSG(size <= GetWriteBufferSize(), "Size %lx is too big", size);
+ const size_t buffer_size{GetWriteBufferSize()};
+ if (size > buffer_size) {
+ LOG_CRITICAL(Core, "size (%016zx) is greater than buffer_size (%016zx)", size, buffer_size);
+ size = buffer_size; // TODO(bunnei): This needs to be HW tested
+ }
if (is_buffer_b) {
Memory::WriteBlock(BufferDescriptorB()[0].Address(), buffer, size);
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 3694afc60..2cffec198 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -121,8 +121,9 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) {
// TODO(bunnei): This is heap area that should be allocated by the kernel and not mapped as part
// of the user address space.
vm_manager
- .MapMemoryBlock(Memory::STACK_VADDR, std::make_shared<std::vector<u8>>(stack_size, 0), 0,
- stack_size, MemoryState::Mapped)
+ .MapMemoryBlock(Memory::STACK_AREA_VADDR_END - stack_size,
+ std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size,
+ MemoryState::Mapped)
.Unwrap();
misc_memory_used += stack_size;
memory_region->used += stack_size;
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 311ab4187..171bbd956 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -756,8 +756,16 @@ static ResultCode CreateTransferMemory(Handle* handle, VAddr addr, u64 size, u32
return RESULT_SUCCESS;
}
-static ResultCode SetThreadCoreMask(u64, u64, u64) {
- LOG_WARNING(Kernel_SVC, "(STUBBED) called");
+static ResultCode GetThreadCoreMask(Handle handle, u32* mask, u64* unknown) {
+ LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x%08X", handle);
+ *mask = 0x0;
+ *unknown = 0xf;
+ return RESULT_SUCCESS;
+}
+
+static ResultCode SetThreadCoreMask(Handle handle, u32 mask, u64 unknown) {
+ LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x%08X, mask=0x%08X, unknown=0x%lx", handle,
+ mask, unknown);
return RESULT_SUCCESS;
}
@@ -809,7 +817,7 @@ static const FunctionDef SVC_Table[] = {
{0x0B, SvcWrap<SleepThread>, "SleepThread"},
{0x0C, SvcWrap<GetThreadPriority>, "GetThreadPriority"},
{0x0D, SvcWrap<SetThreadPriority>, "SetThreadPriority"},
- {0x0E, nullptr, "GetThreadCoreMask"},
+ {0x0E, SvcWrap<GetThreadCoreMask>, "GetThreadCoreMask"},
{0x0F, SvcWrap<SetThreadCoreMask>, "SetThreadCoreMask"},
{0x10, SvcWrap<GetCurrentProcessorNumber>, "GetCurrentProcessorNumber"},
{0x11, nullptr, "SignalEvent"},
diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h
index b224f5e67..5da4f5269 100644
--- a/src/core/hle/kernel/svc_wrap.h
+++ b/src/core/hle/kernel/svc_wrap.h
@@ -70,6 +70,21 @@ void SvcWrap() {
FuncReturn(retval);
}
+template <ResultCode func(u32, u32, u64)>
+void SvcWrap() {
+ FuncReturn(func((u32)(PARAM(0) & 0xFFFFFFFF), (u32)(PARAM(1) & 0xFFFFFFFF), PARAM(2)).raw);
+}
+
+template <ResultCode func(u32, u32*, u64*)>
+void SvcWrap() {
+ u32 param_1 = 0;
+ u64 param_2 = 0;
+ ResultCode retval = func((u32)(PARAM(2) & 0xFFFFFFFF), &param_1, &param_2);
+ Core::CPU().SetReg(1, param_1);
+ Core::CPU().SetReg(2, param_2);
+ FuncReturn(retval.raw);
+}
+
template <ResultCode func(u64, u64, u32, u32)>
void SvcWrap() {
FuncReturn(
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 145f50887..f3a8aa4aa 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -342,7 +342,7 @@ SharedPtr<Thread> SetupMainThread(VAddr entry_point, u32 priority,
// Initialize new "main" thread
auto thread_res = Thread::Create("main", entry_point, priority, 0, THREADPROCESSORID_0,
- Memory::STACK_VADDR_END, owner_process);
+ Memory::STACK_AREA_VADDR_END, owner_process);
SharedPtr<Thread> thread = std::move(thread_res).Unwrap();
diff --git a/src/core/hle/result.h b/src/core/hle/result.h
index 97fef7a48..052f49979 100644
--- a/src/core/hle/result.h
+++ b/src/core/hle/result.h
@@ -200,6 +200,9 @@ public:
}
ResultVal& operator=(const ResultVal& o) {
+ if (this == &o) {
+ return *this;
+ }
if (!empty()) {
if (!o.empty()) {
object = o.object;
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index d9f003ed4..bab338205 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -12,6 +12,7 @@
#include "core/hle/service/apm/apm.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/nvflinger/nvflinger.h"
+#include "core/settings.h"
namespace Service {
namespace AM {
@@ -241,17 +242,20 @@ void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) {
}
void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) {
+ const bool use_docked_mode{Settings::values.use_docked_mode};
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
- rb.Push(static_cast<u8>(OperationMode::Handheld));
+ rb.Push(static_cast<u8>(use_docked_mode ? OperationMode::Docked : OperationMode::Handheld));
LOG_WARNING(Service_AM, "(STUBBED) called");
}
void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
+ const bool use_docked_mode{Settings::values.use_docked_mode};
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
- rb.Push(static_cast<u32>(APM::PerformanceMode::Handheld));
+ rb.Push(static_cast<u32>(use_docked_mode ? APM::PerformanceMode::Docked
+ : APM::PerformanceMode::Handheld));
LOG_WARNING(Service_AM, "(STUBBED) called");
}
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index f52cd7d90..6d0461bbc 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -59,12 +59,12 @@ private:
AudioRendererResponseData response_data{};
response_data.section_0_size =
- response_data.state_entries.size() * sizeof(AudioRendererStateEntry);
- response_data.section_1_size = response_data.section_1.size();
- response_data.section_2_size = response_data.section_2.size();
- response_data.section_3_size = response_data.section_3.size();
- response_data.section_4_size = response_data.section_4.size();
- response_data.section_5_size = response_data.section_5.size();
+ static_cast<u32>(response_data.state_entries.size() * sizeof(AudioRendererStateEntry));
+ response_data.section_1_size = static_cast<u32>(response_data.section_1.size());
+ response_data.section_2_size = static_cast<u32>(response_data.section_2.size());
+ response_data.section_3_size = static_cast<u32>(response_data.section_3.size());
+ response_data.section_4_size = static_cast<u32>(response_data.section_4.size());
+ response_data.section_5_size = static_cast<u32>(response_data.section_5.size());
response_data.total_size = sizeof(AudioRendererResponseData);
for (unsigned i = 0; i < response_data.state_entries.size(); i++) {
@@ -156,7 +156,17 @@ public:
IAudioDevice() : ServiceFramework("IAudioDevice") {
static const FunctionInfo functions[] = {
{0x0, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceName"},
- {0x1, &IAudioDevice::SetAudioDeviceOutputVolume, "SetAudioDeviceOutputVolume"}};
+ {0x1, &IAudioDevice::SetAudioDeviceOutputVolume, "SetAudioDeviceOutputVolume"},
+ {0x2, nullptr, "GetAudioDeviceOutputVolume"},
+ {0x3, nullptr, "GetActiveAudioDeviceName"},
+ {0x4, &IAudioDevice::QueryAudioDeviceSystemEvent, "QueryAudioDeviceSystemEvent"},
+ {0x5, &IAudioDevice::GetActiveChannelCount, "GetActiveChannelCount"},
+ {0x6, nullptr, "ListAudioDeviceNameAuto"},
+ {0x7, nullptr, "SetAudioDeviceOutputVolumeAuto"},
+ {0x8, nullptr, "GetAudioDeviceOutputVolumeAuto"},
+ {0x10, nullptr, "GetActiveAudioDeviceNameAuto"},
+ {0x11, nullptr, "QueryAudioDeviceInputEvent"},
+ {0x12, nullptr, "QueryAudioDeviceOutputEvent"}};
RegisterHandlers(functions);
buffer_event =
@@ -189,8 +199,26 @@ private:
rb.Push(RESULT_SUCCESS);
}
+ void QueryAudioDeviceSystemEvent(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_Audio, "(STUBBED) called");
+
+ buffer_event->Signal();
+
+ IPC::ResponseBuilder rb{ctx, 2, 1};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushCopyObjects(buffer_event);
+ }
+
+ void GetActiveChannelCount(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_Audio, "(STUBBED) called");
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push<u32>(1);
+ }
+
Kernel::SharedPtr<Kernel::Event> buffer_event;
-};
+
+}; // namespace Audio
AudRenU::AudRenU() : ServiceFramework("audren:u") {
static const FunctionInfo functions[] = {
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp
index 41b8cbfd2..89fa70ae6 100644
--- a/src/core/hle/service/filesystem/fsp_srv.cpp
+++ b/src/core/hle/service/filesystem/fsp_srv.cpp
@@ -72,8 +72,8 @@ public:
explicit IFile(std::unique_ptr<FileSys::StorageBackend>&& backend)
: ServiceFramework("IFile"), backend(std::move(backend)) {
static const FunctionInfo functions[] = {
- {0, &IFile::Read, "Read"}, {1, &IFile::Write, "Write"}, {2, nullptr, "Flush"},
- {3, nullptr, "SetSize"}, {4, nullptr, "GetSize"},
+ {0, &IFile::Read, "Read"}, {1, &IFile::Write, "Write"}, {2, nullptr, "Flush"},
+ {3, &IFile::SetSize, "SetSize"}, {4, &IFile::GetSize, "GetSize"},
};
RegisterHandlers(functions);
}
@@ -150,6 +150,25 @@ private:
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
+
+ void SetSize(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const u64 size = rp.Pop<u64>();
+ backend->SetSize(size);
+ LOG_DEBUG(Service_FS, "called, size=%" PRIu64, size);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+ }
+
+ void GetSize(Kernel::HLERequestContext& ctx) {
+ const u64 size = backend->GetSize();
+ LOG_DEBUG(Service_FS, "called, size=%" PRIu64, size);
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push<u64>(size);
+ }
};
class IDirectory final : public ServiceFramework<IDirectory> {
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index a0b8c6243..019a09444 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -65,13 +65,14 @@ private:
}
void UpdatePadCallback(u64 userdata, int cycles_late) {
- SharedMemory* mem = reinterpret_cast<SharedMemory*>(shared_mem->GetPointer());
+ SharedMemory mem{};
+ std::memcpy(&mem, shared_mem->GetPointer(), sizeof(SharedMemory));
if (is_device_reload_pending.exchange(false))
LoadInputDevices();
// Set up controllers as neon red+blue Joy-Con attached to console
- ControllerHeader& controller_header = mem->controllers[Controller_Handheld].header;
+ ControllerHeader& controller_header = mem.controllers[Controller_Handheld].header;
controller_header.type = ControllerType_Handheld | ControllerType_JoyconPair;
controller_header.single_colors_descriptor = ColorDesc_ColorsNonexistent;
controller_header.right_color_body = JOYCON_BODY_NEON_RED;
@@ -79,8 +80,8 @@ private:
controller_header.left_color_body = JOYCON_BODY_NEON_BLUE;
controller_header.left_color_buttons = JOYCON_BUTTONS_NEON_BLUE;
- for (int layoutIdx = 0; layoutIdx < HID_NUM_LAYOUTS; layoutIdx++) {
- ControllerLayout& layout = mem->controllers[Controller_Handheld].layouts[layoutIdx];
+ for (int index = 0; index < HID_NUM_LAYOUTS; index++) {
+ ControllerLayout& layout = mem.controllers[Controller_Handheld].layouts[index];
layout.header.num_entries = HID_NUM_ENTRIES;
layout.header.max_entry_index = HID_NUM_ENTRIES - 1;
@@ -136,10 +137,25 @@ private:
// layouts)
}
- // TODO(shinyquagsire23): Update touch info
+ // TODO(bunnei): Properly implement the touch screen, the below will just write empty data
+
+ TouchScreen& touchscreen = mem.touchscreen;
+ const u64 last_entry = touchscreen.header.latest_entry;
+ const u64 curr_entry = (last_entry + 1) % touchscreen.entries.size();
+ const u64 timestamp = CoreTiming::GetTicks();
+ const u64 sample_counter = touchscreen.entries[last_entry].header.timestamp + 1;
+ touchscreen.header.timestamp_ticks = timestamp;
+ touchscreen.header.num_entries = touchscreen.entries.size();
+ touchscreen.header.latest_entry = curr_entry;
+ touchscreen.header.max_entry_index = touchscreen.entries.size();
+ touchscreen.header.timestamp = timestamp;
+ touchscreen.entries[curr_entry].header.timestamp = sample_counter;
+ touchscreen.entries[curr_entry].header.num_touches = 0;
// TODO(shinyquagsire23): Signal events
+ std::memcpy(shared_mem->GetPointer(), &mem, sizeof(SharedMemory));
+
// Reschedule recurrent event
CoreTiming::ScheduleEvent(pad_update_ticks - cycles_late, pad_update_event);
}
@@ -185,6 +201,7 @@ public:
{66, &Hid::StartSixAxisSensor, "StartSixAxisSensor"},
{79, &Hid::SetGyroscopeZeroDriftMode, "SetGyroscopeZeroDriftMode"},
{100, &Hid::SetSupportedNpadStyleSet, "SetSupportedNpadStyleSet"},
+ {101, &Hid::GetSupportedNpadStyleSet, "GetSupportedNpadStyleSet"},
{102, &Hid::SetSupportedNpadIdType, "SetSupportedNpadIdType"},
{103, &Hid::ActivateNpad, "ActivateNpad"},
{106, &Hid::AcquireNpadStyleSetUpdateEventHandle,
@@ -265,6 +282,13 @@ private:
LOG_WARNING(Service_HID, "(STUBBED) called");
}
+ void GetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) {
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(RESULT_SUCCESS);
+ rb.Push<u32>(0);
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+ }
+
void SetSupportedNpadIdType(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp
new file mode 100644
index 000000000..49870841c
--- /dev/null
+++ b/src/core/hle/service/nfp/nfp.cpp
@@ -0,0 +1,28 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/logging/log.h"
+#include "core/hle/ipc_helpers.h"
+#include "core/hle/service/nfp/nfp.h"
+#include "core/hle/service/nfp/nfp_user.h"
+
+namespace Service {
+namespace NFP {
+
+Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
+ : ServiceFramework(name), module(std::move(module)) {}
+
+void Module::Interface::Unknown(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_NFP, "(STUBBED) called");
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+}
+
+void InstallInterfaces(SM::ServiceManager& service_manager) {
+ auto module = std::make_shared<Module>();
+ std::make_shared<NFP_User>(module)->InstallAsService(service_manager);
+}
+
+} // namespace NFP
+} // namespace Service
diff --git a/src/core/hle/service/nfp/nfp.h b/src/core/hle/service/nfp/nfp.h
new file mode 100644
index 000000000..1163e9954
--- /dev/null
+++ b/src/core/hle/service/nfp/nfp.h
@@ -0,0 +1,28 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Service {
+namespace NFP {
+
+class Module final {
+public:
+ class Interface : public ServiceFramework<Interface> {
+ public:
+ Interface(std::shared_ptr<Module> module, const char* name);
+
+ void Unknown(Kernel::HLERequestContext& ctx);
+
+ protected:
+ std::shared_ptr<Module> module;
+ };
+};
+
+void InstallInterfaces(SM::ServiceManager& service_manager);
+
+} // namespace NFP
+} // namespace Service
diff --git a/src/core/hle/service/nfp/nfp_user.cpp b/src/core/hle/service/nfp/nfp_user.cpp
new file mode 100644
index 000000000..14e5647c4
--- /dev/null
+++ b/src/core/hle/service/nfp/nfp_user.cpp
@@ -0,0 +1,19 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/service/nfp/nfp_user.h"
+
+namespace Service {
+namespace NFP {
+
+NFP_User::NFP_User(std::shared_ptr<Module> module)
+ : Module::Interface(std::move(module), "nfp:user") {
+ static const FunctionInfo functions[] = {
+ {0, &NFP_User::Unknown, "Unknown"},
+ };
+ RegisterHandlers(functions);
+}
+
+} // namespace NFP
+} // namespace Service
diff --git a/src/core/hle/service/nfp/nfp_user.h b/src/core/hle/service/nfp/nfp_user.h
new file mode 100644
index 000000000..1606444ca
--- /dev/null
+++ b/src/core/hle/service/nfp/nfp_user.h
@@ -0,0 +1,18 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/nfp/nfp.h"
+
+namespace Service {
+namespace NFP {
+
+class NFP_User final : public Module::Interface {
+public:
+ explicit NFP_User(std::shared_ptr<Module> module);
+};
+
+} // namespace NFP
+} // namespace Service
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index b224b89da..c5490c1ae 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -25,6 +25,7 @@
#include "core/hle/service/friend/friend.h"
#include "core/hle/service/hid/hid.h"
#include "core/hle/service/lm/lm.h"
+#include "core/hle/service/nfp/nfp.h"
#include "core/hle/service/nifm/nifm.h"
#include "core/hle/service/ns/ns.h"
#include "core/hle/service/nvdrv/nvdrv.h"
@@ -111,15 +112,15 @@ void ServiceFrameworkBase::ReportUnimplementedFunction(Kernel::HLERequestContext
auto cmd_buf = ctx.CommandBuffer();
std::string function_name = info == nullptr ? fmt::format("{}", ctx.GetCommand()) : info->name;
- fmt::MemoryWriter w;
- w.write("function '{}': port='{}' cmd_buf={{[0]={:#x}", function_name, service_name,
- cmd_buf[0]);
+ fmt::memory_buffer buf;
+ fmt::format_to(buf, "function '{}': port='{}' cmd_buf={{[0]={:#x}", function_name, service_name,
+ cmd_buf[0]);
for (int i = 1; i <= 8; ++i) {
- w.write(", [{}]={:#x}", i, cmd_buf[i]);
+ fmt::format_to(buf, ", [{}]={:#x}", i, cmd_buf[i]);
}
- w << '}';
+ buf.push_back('}');
- LOG_ERROR(Service, "unknown / unimplemented %s", w.c_str());
+ LOG_ERROR(Service, "unknown / unimplemented %s", fmt::to_string(buf).c_str());
UNIMPLEMENTED();
}
@@ -187,6 +188,7 @@ void Init() {
Friend::InstallInterfaces(*SM::g_service_manager);
HID::InstallInterfaces(*SM::g_service_manager);
LM::InstallInterfaces(*SM::g_service_manager);
+ NFP::InstallInterfaces(*SM::g_service_manager);
NIFM::InstallInterfaces(*SM::g_service_manager);
NS::InstallInterfaces(*SM::g_service_manager);
Nvidia::InstallInterfaces(*SM::g_service_manager);
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp
index aa09ed323..8b4ee970f 100644
--- a/src/core/loader/deconstructed_rom_directory.cpp
+++ b/src/core/loader/deconstructed_rom_directory.cpp
@@ -76,7 +76,7 @@ FileType AppLoader_DeconstructedRomDirectory::IdentifyType(FileUtil::IOFile& fil
} else if (Common::ToLower(virtual_name) == "sdk") {
is_sdk_found = true;
} else {
- // Contrinue searching
+ // Continue searching
return true;
}
diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp
index 0ba8c6fd2..e9f462196 100644
--- a/src/core/loader/elf.cpp
+++ b/src/core/loader/elf.cpp
@@ -414,7 +414,7 @@ ResultStatus AppLoader_ELF::Load(Kernel::SharedPtr<Kernel::Process>& process) {
process->resource_limit =
Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
- process->Run(codeset->entrypoint, 48, Memory::STACK_SIZE);
+ process->Run(codeset->entrypoint, 48, Memory::DEFAULT_STACK_SIZE);
is_loaded = true;
return ResultStatus::Success;
diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp
index 6dcd1ce48..b5133e4d6 100644
--- a/src/core/loader/nro.cpp
+++ b/src/core/loader/nro.cpp
@@ -137,7 +137,7 @@ ResultStatus AppLoader_NRO::Load(Kernel::SharedPtr<Kernel::Process>& process) {
process->address_mappings = default_address_mappings;
process->resource_limit =
Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
- process->Run(base_addr, 48, Memory::STACK_SIZE);
+ process->Run(base_addr, 48, Memory::DEFAULT_STACK_SIZE);
is_loaded = true;
return ResultStatus::Success;
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp
index 100aa022e..3bc10ed0d 100644
--- a/src/core/loader/nso.cpp
+++ b/src/core/loader/nso.cpp
@@ -165,7 +165,7 @@ ResultStatus AppLoader_NSO::Load(Kernel::SharedPtr<Kernel::Process>& process) {
process->address_mappings = default_address_mappings;
process->resource_limit =
Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION);
- process->Run(Memory::PROCESS_IMAGE_VADDR, 48, Memory::STACK_SIZE);
+ process->Run(Memory::PROCESS_IMAGE_VADDR, 48, Memory::DEFAULT_STACK_SIZE);
is_loaded = true;
return ResultStatus::Success;
diff --git a/src/core/memory.h b/src/core/memory.h
index 413a7b4e8..e9b8ca873 100644
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -162,12 +162,13 @@ enum : VAddr {
TLS_AREA_VADDR = NEW_LINEAR_HEAP_VADDR_END,
TLS_ENTRY_SIZE = 0x200,
TLS_AREA_SIZE = 0x10000000,
- TLS_ADREA_VADDR_END = TLS_AREA_VADDR + TLS_AREA_SIZE,
+ TLS_AREA_VADDR_END = TLS_AREA_VADDR + TLS_AREA_SIZE,
/// Application stack
- STACK_VADDR = TLS_ADREA_VADDR_END,
- STACK_SIZE = 0x10000,
- STACK_VADDR_END = STACK_VADDR + STACK_SIZE,
+ STACK_AREA_VADDR = TLS_AREA_VADDR_END,
+ STACK_AREA_SIZE = 0x10000000,
+ STACK_AREA_VADDR_END = STACK_AREA_VADDR + STACK_AREA_SIZE,
+ DEFAULT_STACK_SIZE = 0x100000,
/// Application heap
/// Size is confirmed to be a static value on fw 3.0.0
diff --git a/src/core/settings.h b/src/core/settings.h
index 6f8cd0f03..2c94caab7 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -105,12 +105,10 @@ static const std::array<const char*, NumAnalogs> mapping = {{
}};
} // namespace NativeAnalog
-enum class CpuCore {
- Unicorn,
- Dynarmic,
-};
-
struct Values {
+ // System
+ bool use_docked_mode;
+
// Controls
std::array<std::string, NativeButton::NumButtons> buttons;
std::array<std::string, NativeAnalog::NumAnalogs> analogs;
@@ -118,7 +116,7 @@ struct Values {
std::string touch_device;
// Core
- CpuCore cpu_core;
+ bool use_cpu_jit;
// Data Storage
bool use_virtual_sd;
diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp
index 970c0a817..cecf0a5cb 100644
--- a/src/core/telemetry_session.cpp
+++ b/src/core/telemetry_session.cpp
@@ -154,12 +154,13 @@ TelemetrySession::TelemetrySession() {
#endif
// Log user configuration information
- AddField(Telemetry::FieldType::UserConfig, "Core_CpuCore",
- static_cast<int>(Settings::values.cpu_core));
+ AddField(Telemetry::FieldType::UserConfig, "Core_UseCpuJit", Settings::values.use_cpu_jit);
AddField(Telemetry::FieldType::UserConfig, "Renderer_ResolutionFactor",
Settings::values.resolution_factor);
AddField(Telemetry::FieldType::UserConfig, "Renderer_ToggleFramelimit",
Settings::values.toggle_framelimit);
+ AddField(Telemetry::FieldType::UserConfig, "System_UseDockedMode",
+ Settings::values.use_docked_mode);
}
TelemetrySession::~TelemetrySession() {
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index 841f27d7f..a710c4bc5 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -11,6 +11,8 @@ add_library(video_core STATIC
engines/maxwell_compute.h
gpu.cpp
gpu.h
+ macro_interpreter.cpp
+ macro_interpreter.h
memory_manager.cpp
memory_manager.h
rasterizer_interface.h
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 5359d21a2..124753032 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -19,35 +19,21 @@ namespace Engines {
/// First register id that is actually a Macro call.
constexpr u32 MacroRegistersStart = 0xE00;
-const std::unordered_map<u32, Maxwell3D::MethodInfo> Maxwell3D::method_handlers = {
- {0xE1A, {"BindTextureInfoBuffer", 1, &Maxwell3D::BindTextureInfoBuffer}},
- {0xE24, {"SetShader", 5, &Maxwell3D::SetShader}},
- {0xE2A, {"BindStorageBuffer", 1, &Maxwell3D::BindStorageBuffer}},
-};
-
-Maxwell3D::Maxwell3D(MemoryManager& memory_manager) : memory_manager(memory_manager) {}
+Maxwell3D::Maxwell3D(MemoryManager& memory_manager)
+ : memory_manager(memory_manager), macro_interpreter(*this) {}
void Maxwell3D::SubmitMacroCode(u32 entry, std::vector<u32> code) {
uploaded_macros[entry * 2 + MacroRegistersStart] = std::move(code);
}
-void Maxwell3D::CallMacroMethod(u32 method, const std::vector<u32>& parameters) {
- // TODO(Subv): Write an interpreter for the macros uploaded via registers 0x45 and 0x47
-
+void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) {
+ auto macro_code = uploaded_macros.find(method);
// The requested macro must have been uploaded already.
- ASSERT_MSG(uploaded_macros.find(method) != uploaded_macros.end(), "Macro %08X was not uploaded",
- method);
-
- auto itr = method_handlers.find(method);
- ASSERT_MSG(itr != method_handlers.end(), "Unhandled method call %08X", method);
-
- ASSERT(itr->second.arguments == parameters.size());
-
- (this->*itr->second.handler)(parameters);
+ ASSERT_MSG(macro_code != uploaded_macros.end(), "Macro %08X was not uploaded", method);
- // Reset the current macro and its parameters.
+ // Reset the current macro and execute it.
executing_macro = 0;
- macro_params.clear();
+ macro_interpreter.Execute(macro_code->second, std::move(parameters));
}
void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) {
@@ -77,7 +63,7 @@ void Maxwell3D::WriteReg(u32 method, u32 value, u32 remaining_params) {
// Call the macro when there are no more parameters in the command buffer
if (remaining_params == 0) {
- CallMacroMethod(executing_macro, macro_params);
+ CallMacroMethod(executing_macro, std::move(macro_params));
}
return;
}
@@ -193,84 +179,6 @@ void Maxwell3D::DrawArrays() {
VideoCore::g_renderer->Rasterizer()->AccelerateDrawBatch(false /*is_indexed*/);
}
-void Maxwell3D::BindTextureInfoBuffer(const std::vector<u32>& parameters) {
- /**
- * Parameters description:
- * [0] = Shader stage, usually 4 for FragmentShader
- */
-
- u32 stage = parameters[0];
-
- // Perform the same operations as the real macro code.
- GPUVAddr address = static_cast<GPUVAddr>(regs.tex_info_buffers.address[stage]) << 8;
- u32 size = regs.tex_info_buffers.size[stage];
-
- regs.const_buffer.cb_size = size;
- regs.const_buffer.cb_address_high = address >> 32;
- regs.const_buffer.cb_address_low = address & 0xFFFFFFFF;
-}
-
-void Maxwell3D::SetShader(const std::vector<u32>& parameters) {
- /**
- * Parameters description:
- * [0] = Shader Program.
- * [1] = Unknown, presumably the shader id.
- * [2] = Offset to the start of the shader, after the 0x30 bytes header.
- * [3] = Shader Stage.
- * [4] = Const Buffer Address >> 8.
- */
- auto shader_program = static_cast<Regs::ShaderProgram>(parameters[0]);
- // TODO(Subv): This address is probably an offset from the CODE_ADDRESS register.
- GPUVAddr address = parameters[2];
- auto shader_stage = static_cast<Regs::ShaderStage>(parameters[3]);
- GPUVAddr cb_address = parameters[4] << 8;
-
- auto& shader = state.shader_programs[static_cast<size_t>(shader_program)];
- shader.program = shader_program;
- shader.stage = shader_stage;
- shader.address = address;
-
- // Perform the same operations as the real macro code.
- // TODO(Subv): Early exit if register 0xD1C + shader_program contains the same as params[1].
- auto& shader_regs = regs.shader_config[static_cast<size_t>(shader_program)];
- shader_regs.start_id = address;
- // TODO(Subv): Write params[1] to register 0xD1C + shader_program.
- // TODO(Subv): Write params[2] to register 0xD22 + shader_program.
-
- // Note: This value is hardcoded in the macro's code.
- static constexpr u32 DefaultCBSize = 0x10000;
- regs.const_buffer.cb_size = DefaultCBSize;
- regs.const_buffer.cb_address_high = cb_address >> 32;
- regs.const_buffer.cb_address_low = cb_address & 0xFFFFFFFF;
-
- // Write a hardcoded 0x11 to CB_BIND, this binds the current const buffer to buffer c1[] in the
- // shader. It's likely that these are the constants for the shader.
- regs.cb_bind[static_cast<size_t>(shader_stage)].valid.Assign(1);
- regs.cb_bind[static_cast<size_t>(shader_stage)].index.Assign(1);
-
- ProcessCBBind(shader_stage);
-}
-
-void Maxwell3D::BindStorageBuffer(const std::vector<u32>& parameters) {
- /**
- * Parameters description:
- * [0] = Buffer offset >> 2
- */
-
- u32 buffer_offset = parameters[0] << 2;
-
- // Perform the same operations as the real macro code.
- // Note: This value is hardcoded in the macro's code.
- static constexpr u32 DefaultCBSize = 0x5F00;
- regs.const_buffer.cb_size = DefaultCBSize;
-
- GPUVAddr address = regs.ssbo_info.BufferAddress();
- regs.const_buffer.cb_address_high = address >> 32;
- regs.const_buffer.cb_address_low = address & 0xFFFFFFFF;
-
- regs.const_buffer.cb_pos = buffer_offset;
-}
-
void Maxwell3D::ProcessCBBind(Regs::ShaderStage stage) {
// Bind the buffer currently in CB_ADDRESS to the specified index in the desired shader stage.
auto& shader = state.shader_stages[static_cast<size_t>(stage)];
@@ -386,5 +294,10 @@ std::vector<Texture::FullTextureInfo> Maxwell3D::GetStageTextures(Regs::ShaderSt
return textures;
}
+u32 Maxwell3D::GetRegisterValue(u32 method) const {
+ ASSERT_MSG(method < Regs::NUM_REGS, "Invalid Maxwell3D register");
+ return regs.reg_array[method];
+}
+
} // namespace Engines
} // namespace Tegra
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 3066bc606..98b39b2ff 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -13,6 +13,7 @@
#include "common/common_types.h"
#include "common/math_util.h"
#include "video_core/gpu.h"
+#include "video_core/macro_interpreter.h"
#include "video_core/memory_manager.h"
#include "video_core/textures/texture.h"
@@ -498,22 +499,18 @@ public:
bool enabled;
};
- struct ShaderProgramInfo {
- Regs::ShaderStage stage;
- Regs::ShaderProgram program;
- GPUVAddr address;
- };
-
struct ShaderStageInfo {
std::array<ConstBufferInfo, Regs::MaxConstBuffers> const_buffers;
};
std::array<ShaderStageInfo, Regs::MaxShaderStage> shader_stages;
- std::array<ShaderProgramInfo, Regs::MaxShaderProgram> shader_programs;
};
State state{};
+ /// Reads a register value located at the input method address
+ u32 GetRegisterValue(u32 method) const;
+
/// Write the value to the register identified by method.
void WriteReg(u32 method, u32 value, u32 remaining_params);
@@ -533,6 +530,9 @@ private:
/// Parameters that have been submitted to the macro call so far.
std::vector<u32> macro_params;
+ /// Interpreter for the macro codes uploaded to the GPU.
+ MacroInterpreter macro_interpreter;
+
/// Retrieves information about a specific TIC entry from the TIC buffer.
Texture::TICEntry GetTICEntry(u32 tic_index) const;
@@ -544,7 +544,7 @@ private:
* @param method Method to call
* @param parameters Arguments to the method call
*/
- void CallMacroMethod(u32 method, const std::vector<u32>& parameters);
+ void CallMacroMethod(u32 method, std::vector<u32> parameters);
/// Handles a write to the QUERY_GET register.
void ProcessQueryGet();
@@ -557,19 +557,6 @@ private:
/// Handles a write to the VERTEX_END_GL register, triggering a draw.
void DrawArrays();
-
- /// Method call handlers
- void BindTextureInfoBuffer(const std::vector<u32>& parameters);
- void SetShader(const std::vector<u32>& parameters);
- void BindStorageBuffer(const std::vector<u32>& parameters);
-
- struct MethodInfo {
- const char* name;
- u32 arguments;
- void (Maxwell3D::*handler)(const std::vector<u32>& parameters);
- };
-
- static const std::unordered_map<u32, MethodInfo> method_handlers;
};
#define ASSERT_REG_POSITION(field_name, position) \
diff --git a/src/video_core/macro_interpreter.cpp b/src/video_core/macro_interpreter.cpp
new file mode 100644
index 000000000..993a67746
--- /dev/null
+++ b/src/video_core/macro_interpreter.cpp
@@ -0,0 +1,257 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/assert.h"
+#include "common/logging/log.h"
+#include "video_core/engines/maxwell_3d.h"
+#include "video_core/macro_interpreter.h"
+
+namespace Tegra {
+
+MacroInterpreter::MacroInterpreter(Engines::Maxwell3D& maxwell3d) : maxwell3d(maxwell3d) {}
+
+void MacroInterpreter::Execute(const std::vector<u32>& code, std::vector<u32> parameters) {
+ Reset();
+ registers[1] = parameters[0];
+ this->parameters = std::move(parameters);
+
+ // Execute the code until we hit an exit condition.
+ bool keep_executing = true;
+ while (keep_executing) {
+ keep_executing = Step(code, false);
+ }
+
+ // Assert the the macro used all the input parameters
+ ASSERT(next_parameter_index == this->parameters.size());
+}
+
+void MacroInterpreter::Reset() {
+ registers = {};
+ pc = 0;
+ delayed_pc = boost::none;
+ method_address.raw = 0;
+ parameters.clear();
+ // The next parameter index starts at 1, because $r1 already has the value of the first
+ // parameter.
+ next_parameter_index = 1;
+}
+
+bool MacroInterpreter::Step(const std::vector<u32>& code, bool is_delay_slot) {
+ u32 base_address = pc;
+
+ Opcode opcode = GetOpcode(code);
+ pc += 4;
+
+ // Update the program counter if we were delayed
+ if (delayed_pc != boost::none) {
+ ASSERT(is_delay_slot);
+ pc = *delayed_pc;
+ delayed_pc = boost::none;
+ }
+
+ switch (opcode.operation) {
+ case Operation::ALU: {
+ u32 result = GetALUResult(opcode.alu_operation, GetRegister(opcode.src_a),
+ GetRegister(opcode.src_b));
+ ProcessResult(opcode.result_operation, opcode.dst, result);
+ break;
+ }
+ case Operation::AddImmediate: {
+ ProcessResult(opcode.result_operation, opcode.dst,
+ GetRegister(opcode.src_a) + opcode.immediate);
+ break;
+ }
+ case Operation::ExtractInsert: {
+ u32 dst = GetRegister(opcode.src_a);
+ u32 src = GetRegister(opcode.src_b);
+
+ src = (src >> opcode.bf_src_bit) & opcode.GetBitfieldMask();
+ dst &= ~(opcode.GetBitfieldMask() << opcode.bf_dst_bit);
+ dst |= src << opcode.bf_dst_bit;
+ ProcessResult(opcode.result_operation, opcode.dst, dst);
+ break;
+ }
+ case Operation::ExtractShiftLeftImmediate: {
+ u32 dst = GetRegister(opcode.src_a);
+ u32 src = GetRegister(opcode.src_b);
+
+ u32 result = ((src >> dst) & opcode.GetBitfieldMask()) << opcode.bf_dst_bit;
+
+ ProcessResult(opcode.result_operation, opcode.dst, result);
+ break;
+ }
+ case Operation::ExtractShiftLeftRegister: {
+ u32 dst = GetRegister(opcode.src_a);
+ u32 src = GetRegister(opcode.src_b);
+
+ u32 result = ((src >> opcode.bf_src_bit) & opcode.GetBitfieldMask()) << dst;
+
+ ProcessResult(opcode.result_operation, opcode.dst, result);
+ break;
+ }
+ case Operation::Read: {
+ u32 result = Read(GetRegister(opcode.src_a) + opcode.immediate);
+ ProcessResult(opcode.result_operation, opcode.dst, result);
+ break;
+ }
+ case Operation::Branch: {
+ ASSERT_MSG(!is_delay_slot, "Executing a branch in a delay slot is not valid");
+ u32 value = GetRegister(opcode.src_a);
+ bool taken = EvaluateBranchCondition(opcode.branch_condition, value);
+ if (taken) {
+ // Ignore the delay slot if the branch has the annul bit.
+ if (opcode.branch_annul) {
+ pc = base_address + (opcode.immediate << 2);
+ return true;
+ }
+
+ delayed_pc = base_address + (opcode.immediate << 2);
+ // Execute one more instruction due to the delay slot.
+ return Step(code, true);
+ }
+ break;
+ }
+ default:
+ UNIMPLEMENTED_MSG("Unimplemented macro operation %u",
+ static_cast<u32>(opcode.operation.Value()));
+ }
+
+ if (opcode.is_exit) {
+ // Exit has a delay slot, execute the next instruction
+ // Note: Executing an exit during a branch delay slot will cause the instruction at the
+ // branch target to be executed before exiting.
+ Step(code, true);
+ return false;
+ }
+
+ return true;
+}
+
+MacroInterpreter::Opcode MacroInterpreter::GetOpcode(const std::vector<u32>& code) const {
+ ASSERT((pc % sizeof(u32)) == 0);
+ ASSERT(pc < code.size() * sizeof(u32));
+ return {code[pc / sizeof(u32)]};
+}
+
+u32 MacroInterpreter::GetALUResult(ALUOperation operation, u32 src_a, u32 src_b) const {
+ switch (operation) {
+ case ALUOperation::Add:
+ return src_a + src_b;
+ // TODO(Subv): Implement AddWithCarry
+ case ALUOperation::Subtract:
+ return src_a - src_b;
+ // TODO(Subv): Implement SubtractWithBorrow
+ case ALUOperation::Xor:
+ return src_a ^ src_b;
+ case ALUOperation::Or:
+ return src_a | src_b;
+ case ALUOperation::And:
+ return src_a & src_b;
+ case ALUOperation::AndNot:
+ return src_a & ~src_b;
+ case ALUOperation::Nand:
+ return ~(src_a & src_b);
+
+ default:
+ UNIMPLEMENTED_MSG("Unimplemented ALU operation %u", static_cast<u32>(operation));
+ }
+}
+
+void MacroInterpreter::ProcessResult(ResultOperation operation, u32 reg, u32 result) {
+ switch (operation) {
+ case ResultOperation::IgnoreAndFetch:
+ // Fetch parameter and ignore result.
+ SetRegister(reg, FetchParameter());
+ break;
+ case ResultOperation::Move:
+ // Move result.
+ SetRegister(reg, result);
+ break;
+ case ResultOperation::MoveAndSetMethod:
+ // Move result and use as Method Address.
+ SetRegister(reg, result);
+ SetMethodAddress(result);
+ break;
+ case ResultOperation::FetchAndSend:
+ // Fetch parameter and send result.
+ SetRegister(reg, FetchParameter());
+ Send(result);
+ break;
+ case ResultOperation::MoveAndSend:
+ // Move and send result.
+ SetRegister(reg, result);
+ Send(result);
+ break;
+ case ResultOperation::FetchAndSetMethod:
+ // Fetch parameter and use result as Method Address.
+ SetRegister(reg, FetchParameter());
+ SetMethodAddress(result);
+ break;
+ case ResultOperation::MoveAndSetMethodFetchAndSend:
+ // Move result and use as Method Address, then fetch and send parameter.
+ SetRegister(reg, result);
+ SetMethodAddress(result);
+ Send(FetchParameter());
+ break;
+ case ResultOperation::MoveAndSetMethodSend:
+ // Move result and use as Method Address, then send bits 12:17 of result.
+ SetRegister(reg, result);
+ SetMethodAddress(result);
+ Send((result >> 12) & 0b111111);
+ break;
+ default:
+ UNIMPLEMENTED_MSG("Unimplemented result operation %u", static_cast<u32>(operation));
+ }
+}
+
+u32 MacroInterpreter::FetchParameter() {
+ ASSERT(next_parameter_index < parameters.size());
+ return parameters[next_parameter_index++];
+}
+
+u32 MacroInterpreter::GetRegister(u32 register_id) const {
+ // Register 0 is supposed to always return 0.
+ if (register_id == 0)
+ return 0;
+
+ ASSERT(register_id < registers.size());
+ return registers[register_id];
+}
+
+void MacroInterpreter::SetRegister(u32 register_id, u32 value) {
+ // Register 0 is supposed to always return 0. NOP is implemented as a store to the zero
+ // register.
+ if (register_id == 0)
+ return;
+
+ ASSERT(register_id < registers.size());
+ registers[register_id] = value;
+}
+
+void MacroInterpreter::SetMethodAddress(u32 address) {
+ method_address.raw = address;
+}
+
+void MacroInterpreter::Send(u32 value) {
+ maxwell3d.WriteReg(method_address.address, value, 0);
+ // Increment the method address by the method increment.
+ method_address.address.Assign(method_address.address.Value() +
+ method_address.increment.Value());
+}
+
+u32 MacroInterpreter::Read(u32 method) const {
+ return maxwell3d.GetRegisterValue(method);
+}
+
+bool MacroInterpreter::EvaluateBranchCondition(BranchCondition cond, u32 value) const {
+ switch (cond) {
+ case BranchCondition::Zero:
+ return value == 0;
+ case BranchCondition::NotZero:
+ return value != 0;
+ }
+ UNREACHABLE();
+}
+
+} // namespace Tegra
diff --git a/src/video_core/macro_interpreter.h b/src/video_core/macro_interpreter.h
new file mode 100644
index 000000000..a71e359d8
--- /dev/null
+++ b/src/video_core/macro_interpreter.h
@@ -0,0 +1,164 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <array>
+#include <vector>
+#include <boost/optional.hpp>
+#include "common/bit_field.h"
+#include "common/common_types.h"
+
+namespace Tegra {
+namespace Engines {
+class Maxwell3D;
+}
+
+class MacroInterpreter final {
+public:
+ explicit MacroInterpreter(Engines::Maxwell3D& maxwell3d);
+
+ /**
+ * Executes the macro code with the specified input parameters.
+ * @param code The macro byte code to execute
+ * @param parameters The parameters of the macro
+ */
+ void Execute(const std::vector<u32>& code, std::vector<u32> parameters);
+
+private:
+ enum class Operation : u32 {
+ ALU = 0,
+ AddImmediate = 1,
+ ExtractInsert = 2,
+ ExtractShiftLeftImmediate = 3,
+ ExtractShiftLeftRegister = 4,
+ Read = 5,
+ Unused = 6, // This operation doesn't seem to be a valid encoding.
+ Branch = 7,
+ };
+
+ enum class ALUOperation : u32 {
+ Add = 0,
+ AddWithCarry = 1,
+ Subtract = 2,
+ SubtractWithBorrow = 3,
+ // Operations 4-7 don't seem to be valid encodings.
+ Xor = 8,
+ Or = 9,
+ And = 10,
+ AndNot = 11,
+ Nand = 12
+ };
+
+ enum class ResultOperation : u32 {
+ IgnoreAndFetch = 0,
+ Move = 1,
+ MoveAndSetMethod = 2,
+ FetchAndSend = 3,
+ MoveAndSend = 4,
+ FetchAndSetMethod = 5,
+ MoveAndSetMethodFetchAndSend = 6,
+ MoveAndSetMethodSend = 7
+ };
+
+ enum class BranchCondition : u32 {
+ Zero = 0,
+ NotZero = 1,
+ };
+
+ union Opcode {
+ u32 raw;
+ BitField<0, 3, Operation> operation;
+ BitField<4, 3, ResultOperation> result_operation;
+ BitField<4, 1, BranchCondition> branch_condition;
+ BitField<5, 1, u32>
+ branch_annul; // If set on a branch, then the branch doesn't have a delay slot.
+ BitField<7, 1, u32> is_exit;
+ BitField<8, 3, u32> dst;
+ BitField<11, 3, u32> src_a;
+ BitField<14, 3, u32> src_b;
+ // The signed immediate overlaps the second source operand and the alu operation.
+ BitField<14, 18, s32> immediate;
+
+ BitField<17, 5, ALUOperation> alu_operation;
+
+ // Bitfield instructions data
+ BitField<17, 5, u32> bf_src_bit;
+ BitField<22, 5, u32> bf_size;
+ BitField<27, 5, u32> bf_dst_bit;
+
+ u32 GetBitfieldMask() const {
+ return (1 << bf_size) - 1;
+ }
+ };
+
+ union MethodAddress {
+ u32 raw;
+ BitField<0, 12, u32> address;
+ BitField<12, 6, u32> increment;
+ };
+
+ /// Resets the execution engine state, zeroing registers, etc.
+ void Reset();
+
+ /**
+ * Executes a single macro instruction located at the current program counter. Returns whether
+ * the interpreter should keep running.
+ * @param code The macro code to execute.
+ * @param is_delay_slot Whether the current step is being executed due to a delay slot in a
+ * previous instruction.
+ */
+ bool Step(const std::vector<u32>& code, bool is_delay_slot);
+
+ /// Calculates the result of an ALU operation. src_a OP src_b;
+ u32 GetALUResult(ALUOperation operation, u32 src_a, u32 src_b) const;
+
+ /// Performs the result operation on the input result and stores it in the specified register
+ /// (if necessary).
+ void ProcessResult(ResultOperation operation, u32 reg, u32 result);
+
+ /// Evaluates the branch condition and returns whether the branch should be taken or not.
+ bool EvaluateBranchCondition(BranchCondition cond, u32 value) const;
+
+ /// Reads an opcode at the current program counter location.
+ Opcode GetOpcode(const std::vector<u32>& code) const;
+
+ /// Returns the specified register's value. Register 0 is hardcoded to always return 0.
+ u32 GetRegister(u32 register_id) const;
+
+ /// Sets the register to the input value.
+ void SetRegister(u32 register_id, u32 value);
+
+ /// Sets the method address to use for the next Send instruction.
+ void SetMethodAddress(u32 address);
+
+ /// Calls a GPU Engine method with the input parameter.
+ void Send(u32 value);
+
+ /// Reads a GPU register located at the method address.
+ u32 Read(u32 method) const;
+
+ /// Returns the next parameter in the parameter queue.
+ u32 FetchParameter();
+
+ Engines::Maxwell3D& maxwell3d;
+
+ u32 pc; ///< Current program counter
+ boost::optional<u32>
+ delayed_pc; ///< Program counter to execute at after the delay slot is executed.
+
+ static constexpr size_t NumMacroRegisters = 8;
+
+ /// General purpose macro registers.
+ std::array<u32, NumMacroRegisters> registers = {};
+
+ /// Method address to use for the next Send instruction.
+ MethodAddress method_address = {};
+
+ /// Input parameters of the current macro.
+ std::vector<u32> parameters;
+ /// Index of the next parameter that will be fetched by the 'parm' instruction.
+ u32 next_parameter_index = 0;
+};
+} // namespace Tegra
diff --git a/src/yuzu/about_dialog.cpp b/src/yuzu/about_dialog.cpp
index da3429822..d6647eeea 100644
--- a/src/yuzu/about_dialog.cpp
+++ b/src/yuzu/about_dialog.cpp
@@ -2,12 +2,14 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <QIcon>
#include "common/scm_rev.h"
#include "ui_aboutdialog.h"
#include "yuzu/about_dialog.h"
AboutDialog::AboutDialog(QWidget* parent) : QDialog(parent), ui(new Ui::AboutDialog) {
ui->setupUi(this);
+ ui->labelLogo->setPixmap(QIcon::fromTheme("yuzu").pixmap(200));
ui->labelBuildInfo->setText(ui->labelBuildInfo->text().arg(
Common::g_build_name, Common::g_scm_branch, Common::g_scm_desc));
}
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 71dc58e5d..8843f2078 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -77,8 +77,7 @@ void Config::ReadValues() {
qt_config->endGroup();
qt_config->beginGroup("Core");
- Settings::values.cpu_core =
- static_cast<Settings::CpuCore>(qt_config->value("cpu_core", 1).toInt());
+ Settings::values.use_cpu_jit = qt_config->value("use_cpu_jit", true).toBool();
qt_config->endGroup();
qt_config->beginGroup("Renderer");
@@ -94,6 +93,10 @@ void Config::ReadValues() {
Settings::values.use_virtual_sd = qt_config->value("use_virtual_sd", true).toBool();
qt_config->endGroup();
+ qt_config->beginGroup("System");
+ Settings::values.use_docked_mode = qt_config->value("use_docked_mode", true).toBool();
+ qt_config->endGroup();
+
qt_config->beginGroup("Miscellaneous");
Settings::values.log_filter = qt_config->value("log_filter", "*:Info").toString().toStdString();
qt_config->endGroup();
@@ -104,6 +107,8 @@ void Config::ReadValues() {
qt_config->endGroup();
qt_config->beginGroup("UI");
+ UISettings::values.theme = qt_config->value("theme", UISettings::themes[0].second).toString();
+
qt_config->beginGroup("UILayout");
UISettings::values.geometry = qt_config->value("geometry").toByteArray();
UISettings::values.state = qt_config->value("state").toByteArray();
@@ -171,7 +176,7 @@ void Config::SaveValues() {
qt_config->endGroup();
qt_config->beginGroup("Core");
- qt_config->setValue("cpu_core", static_cast<int>(Settings::values.cpu_core));
+ qt_config->setValue("use_cpu_jit", Settings::values.use_cpu_jit);
qt_config->endGroup();
qt_config->beginGroup("Renderer");
@@ -188,6 +193,10 @@ void Config::SaveValues() {
qt_config->setValue("use_virtual_sd", Settings::values.use_virtual_sd);
qt_config->endGroup();
+ qt_config->beginGroup("System");
+ qt_config->setValue("use_docked_mode", Settings::values.use_docked_mode);
+ qt_config->endGroup();
+
qt_config->beginGroup("Miscellaneous");
qt_config->setValue("log_filter", QString::fromStdString(Settings::values.log_filter));
qt_config->endGroup();
diff --git a/src/yuzu/configuration/configure_general.cpp b/src/yuzu/configuration/configure_general.cpp
index 92fd6ab02..2d73fc5aa 100644
--- a/src/yuzu/configuration/configure_general.cpp
+++ b/src/yuzu/configuration/configure_general.cpp
@@ -13,9 +13,14 @@ ConfigureGeneral::ConfigureGeneral(QWidget* parent)
ui->setupUi(this);
+ for (auto theme : UISettings::themes) {
+ ui->theme_combobox->addItem(theme.first, theme.second);
+ }
+
this->setConfiguration();
- ui->cpu_core_combobox->setEnabled(!Core::System::GetInstance().IsPoweredOn());
+ ui->use_cpu_jit->setEnabled(!Core::System::GetInstance().IsPoweredOn());
+ ui->use_docked_mode->setEnabled(!Core::System::GetInstance().IsPoweredOn());
}
ConfigureGeneral::~ConfigureGeneral() {}
@@ -23,13 +28,18 @@ ConfigureGeneral::~ConfigureGeneral() {}
void ConfigureGeneral::setConfiguration() {
ui->toggle_deepscan->setChecked(UISettings::values.gamedir_deepscan);
ui->toggle_check_exit->setChecked(UISettings::values.confirm_before_closing);
- ui->cpu_core_combobox->setCurrentIndex(static_cast<int>(Settings::values.cpu_core));
+ ui->theme_combobox->setCurrentIndex(ui->theme_combobox->findData(UISettings::values.theme));
+ ui->use_cpu_jit->setChecked(Settings::values.use_cpu_jit);
+ ui->use_docked_mode->setChecked(Settings::values.use_docked_mode);
}
void ConfigureGeneral::applyConfiguration() {
UISettings::values.gamedir_deepscan = ui->toggle_deepscan->isChecked();
UISettings::values.confirm_before_closing = ui->toggle_check_exit->isChecked();
- Settings::values.cpu_core =
- static_cast<Settings::CpuCore>(ui->cpu_core_combobox->currentIndex());
+ UISettings::values.theme =
+ ui->theme_combobox->itemData(ui->theme_combobox->currentIndex()).toString();
+
+ Settings::values.use_cpu_jit = ui->use_cpu_jit->isChecked();
+ Settings::values.use_docked_mode = ui->use_docked_mode->isChecked();
Settings::Apply();
}
diff --git a/src/yuzu/configuration/configure_general.ui b/src/yuzu/configuration/configure_general.ui
index 573c4cb0e..1775c4d40 100644
--- a/src/yuzu/configuration/configure_general.ui
+++ b/src/yuzu/configuration/configure_general.ui
@@ -13,17 +13,17 @@
<property name="windowTitle">
<string>Form</string>
</property>
- <layout class="QHBoxLayout" name="horizontalLayout">
+ <layout class="QHBoxLayout" name="HorizontalLayout">
<item>
- <layout class="QVBoxLayout" name="verticalLayout">
+ <layout class="QVBoxLayout" name="VerticalLayout">
<item>
- <widget class="QGroupBox" name="groupBox">
+ <widget class="QGroupBox" name="GeneralGroupBox">
<property name="title">
<string>General</string>
</property>
- <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <layout class="QHBoxLayout" name="GeneralHorizontalLayout">
<item>
- <layout class="QVBoxLayout" name="verticalLayout_2">
+ <layout class="QVBoxLayout" name="GeneralVerticalLayout">
<item>
<widget class="QCheckBox" name="toggle_deepscan">
<property name="text">
@@ -44,40 +44,80 @@
</widget>
</item>
<item>
- <widget class="QGroupBox" name="groupBox_2">
- <property name="title">
- <string>CPU Core</string>
- </property>
- <layout class="QHBoxLayout" name="horizontalLayout_7">
- <item>
- <layout class="QVBoxLayout" name="verticalLayout_5">
- <item>
- <widget class="QComboBox" name="cpu_core_combobox">
- <item>
- <property name="text">
- <string>Unicorn</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Dynarmic</string>
- </property>
- </item>
- </widget>
- </item>
- </layout>
- </item>
+ <widget class="QGroupBox" name="PerformanceGroupBox">
+ <property name="title">
+ <string>Performance</string>
+ </property>
+ <layout class="QHBoxLayout" name="PerformanceHorizontalLayout">
+ <item>
+ <layout class="QVBoxLayout" name="PerformanceVerticalLayout">
+ <item>
+ <widget class="QCheckBox" name="use_cpu_jit">
+ <property name="text">
+ <string>Enable CPU JIT</string>
+ </property>
+ </widget>
+ </item>
</layout>
- </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="EmulationGroupBox">
+ <property name="title">
+ <string>Emulation</string>
+ </property>
+ <layout class="QHBoxLayout" name="EmulationHorizontalLayout">
+ <item>
+ <layout class="QVBoxLayout" name="EmulationVerticalLayout">
+ <item>
+ <widget class="QCheckBox" name="use_docked_mode">
+ <property name="text">
+ <string>Enable docked mode</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="theme_group_box">
+ <property name="title">
+ <string>Theme</string>
+ </property>
+ <layout class="QHBoxLayout" name="theme_qhbox_layout">
+ <item>
+ <layout class="QVBoxLayout" name="theme_qvbox_layout">
+ <item>
+ <layout class="QHBoxLayout" name="theme_qhbox_layout_2">
+ <item>
+ <widget class="QLabel" name="theme_label">
+ <property name="text">
+ <string>Theme:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="theme_combobox"/>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
</item>
<item>
- <widget class="QGroupBox" name="groupBox_3">
+ <widget class="QGroupBox" name="HotKeysGroupBox">
<property name="title">
<string>Hotkeys</string>
</property>
- <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <layout class="QHBoxLayout" name="HotKeysHorizontalLayout">
<item>
- <layout class="QVBoxLayout" name="verticalLayout_4">
+ <layout class="QVBoxLayout" name="HotKeysVerticalLayout">
<item>
<widget class="GHotkeysDialog" name="widget" native="true"/>
</item>
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index bd323870b..265502c2a 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -78,6 +78,9 @@ GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) {
ui.setupUi(this);
statusBar()->hide();
+ default_theme_paths = QIcon::themeSearchPaths();
+ UpdateUITheme();
+
InitializeWidgets();
InitializeDebugWidgets();
InitializeRecentFileMenuActions();
@@ -653,6 +656,7 @@ void GMainWindow::OnConfigure() {
auto result = configureDialog.exec();
if (result == QDialog::Accepted) {
configureDialog.applyConfiguration();
+ UpdateUITheme();
config->Save();
}
}
@@ -833,6 +837,32 @@ void GMainWindow::filterBarSetChecked(bool state) {
emit(OnToggleFilterBar());
}
+void GMainWindow::UpdateUITheme() {
+ QStringList theme_paths(default_theme_paths);
+ if (UISettings::values.theme != UISettings::themes[0].second &&
+ !UISettings::values.theme.isEmpty()) {
+ QString theme_uri(":" + UISettings::values.theme + "/style.qss");
+ QFile f(theme_uri);
+ if (!f.exists()) {
+ LOG_ERROR(Frontend, "Unable to set style, stylesheet file not found");
+ } else {
+ f.open(QFile::ReadOnly | QFile::Text);
+ QTextStream ts(&f);
+ qApp->setStyleSheet(ts.readAll());
+ GMainWindow::setStyleSheet(ts.readAll());
+ }
+ theme_paths.append(QStringList{":/icons/default", ":/icons/" + UISettings::values.theme});
+ QIcon::setThemeName(":/icons/" + UISettings::values.theme);
+ } else {
+ qApp->setStyleSheet("");
+ GMainWindow::setStyleSheet("");
+ theme_paths.append(QStringList{":/icons/default"});
+ QIcon::setThemeName(":/icons/default");
+ }
+ QIcon::setThemeSearchPaths(theme_paths);
+ emit UpdateThemedIcons();
+}
+
#ifdef main
#undef main
#endif
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index 2471caf83..20ff65314 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -2,8 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#ifndef _CITRA_QT_MAIN_HXX_
-#define _CITRA_QT_MAIN_HXX_
+#pragma once
#include <memory>
#include <QMainWindow>
@@ -65,6 +64,9 @@ signals:
*/
void EmulationStopping();
+ // Signal that tells widgets to update icons to use the current theme
+ void UpdateThemedIcons();
+
private:
void InitializeWidgets();
void InitializeDebugWidgets();
@@ -153,7 +155,7 @@ private:
std::unique_ptr<Config> config;
- // Whether emulation is currently running in Citra.
+ // Whether emulation is currently running in yuzu.
bool emulation_running = false;
std::unique_ptr<EmuThread> emu_thread;
@@ -167,10 +169,11 @@ private:
QAction* actions_recent_files[max_recent_files_item];
+ // stores default icon theme search paths for the platform
+ QStringList default_theme_paths;
+
protected:
void dropEvent(QDropEvent* event) override;
void dragEnterEvent(QDragEnterEvent* event) override;
void dragMoveEvent(QDragMoveEvent* event) override;
};
-
-#endif // _CITRA_QT_MAIN_HXX_
diff --git a/src/yuzu/ui_settings.h b/src/yuzu/ui_settings.h
index 9036ce2c1..8e215a002 100644
--- a/src/yuzu/ui_settings.h
+++ b/src/yuzu/ui_settings.h
@@ -15,6 +15,10 @@ namespace UISettings {
using ContextualShortcut = std::pair<QString, int>;
using Shortcut = std::pair<QString, ContextualShortcut>;
+static const std::array<std::pair<QString, QString>, 2> themes = {
+ {std::make_pair(QString("Default"), QString("default")),
+ std::make_pair(QString("Dark"), QString("qdarkstyle"))}};
+
struct Values {
QByteArray geometry;
QByteArray state;
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index 342ad3850..8b479bc6d 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -90,8 +90,7 @@ void Config::ReadValues() {
sdl2_config->Get("Controls", "touch_device", "engine:emu_window");
// Core
- Settings::values.cpu_core =
- static_cast<Settings::CpuCore>(sdl2_config->GetInteger("Core", "cpu_core", 1));
+ Settings::values.use_cpu_jit = sdl2_config->GetBoolean("Core", "use_cpu_jit", true);
// Renderer
Settings::values.resolution_factor =
@@ -107,6 +106,9 @@ void Config::ReadValues() {
Settings::values.use_virtual_sd =
sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true);
+ // System
+ Settings::values.use_docked_mode = sdl2_config->GetBoolean("System", "use_docked_mode", true);
+
// Miscellaneous
Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Trace");
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h
index a0b199f95..895a42c39 100644
--- a/src/yuzu_cmd/default_ini.h
+++ b/src/yuzu_cmd/default_ini.h
@@ -76,9 +76,9 @@ motion_device=
touch_device=
[Core]
-# Which CPU core to use for CPU emulation
-# 0: Unicorn (slow), 1 (default): Dynarmic (faster)
-cpu_core =
+# Whether to use the Just-In-Time (JIT) compiler for CPU emulation
+# 0: Interpreter (slow), 1 (default): JIT (fast)
+use_cpu_jit =
[Renderer]
# Whether to use software or hardware rendering.
@@ -154,6 +154,10 @@ output_device =
use_virtual_sd =
[System]
+# Whether the system is docked
+# 1 (default): Yes, 0: No
+use_docked_mode =
+
# The system region that Citra will use during emulation
# -1: Auto-select (default), 0: Japan, 1: USA, 2: Europe, 3: Australia, 4: China, 5: Korea, 6: Taiwan
region_value =