summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.travis-upload.sh5
-rw-r--r--.travis.yml4
-rwxr-xr-xhooks/pre-commit17
-rw-r--r--src/citra/emu_window/emu_window_sdl2.cpp4
-rw-r--r--src/citra_qt/bootmanager.cpp4
-rw-r--r--src/citra_qt/configure_general.ui2
-rw-r--r--src/citra_qt/debugger/graphics/graphics_tracing.h6
-rw-r--r--src/citra_qt/game_list.cpp48
-rw-r--r--src/citra_qt/game_list.h4
-rw-r--r--src/citra_qt/main.cpp118
-rw-r--r--src/citra_qt/main.h3
-rw-r--r--src/citra_qt/main.ui55
-rw-r--r--src/common/CMakeLists.txt23
-rw-r--r--src/common/scm_rev.cpp.in2
-rw-r--r--src/common/scm_rev.h1
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp8
16 files changed, 176 insertions, 128 deletions
diff --git a/.travis-upload.sh b/.travis-upload.sh
index 9aed815d4..262259678 100755
--- a/.travis-upload.sh
+++ b/.travis-upload.sh
@@ -5,12 +5,14 @@ if [ "$TRAVIS_EVENT_TYPE" = "push" ]&&[ "$TRAVIS_BRANCH" = "master" ]; then
5 5
6 if [ "$TRAVIS_OS_NAME" = "linux" -o -z "$TRAVIS_OS_NAME" ]; then 6 if [ "$TRAVIS_OS_NAME" = "linux" -o -z "$TRAVIS_OS_NAME" ]; then
7 REV_NAME="citra-linux-${GITDATE}-${GITREV}" 7 REV_NAME="citra-linux-${GITDATE}-${GITREV}"
8 ARCHIVE_NAME="${REV_NAME}.tar.xz"
8 mkdir "$REV_NAME" 9 mkdir "$REV_NAME"
9 10
10 cp build/src/citra/citra "$REV_NAME" 11 cp build/src/citra/citra "$REV_NAME"
11 cp build/src/citra_qt/citra-qt "$REV_NAME" 12 cp build/src/citra_qt/citra-qt "$REV_NAME"
12 elif [ "$TRAVIS_OS_NAME" = "osx" ]; then 13 elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
13 REV_NAME="citra-osx-${GITDATE}-${GITREV}" 14 REV_NAME="citra-osx-${GITDATE}-${GITREV}"
15 ARCHIVE_NAME="${REV_NAME}.tar.gz"
14 mkdir "$REV_NAME" 16 mkdir "$REV_NAME"
15 17
16 cp build/src/citra/Release/citra "$REV_NAME" 18 cp build/src/citra/Release/citra "$REV_NAME"
@@ -118,8 +120,7 @@ EOL
118 cp license.txt "$REV_NAME" 120 cp license.txt "$REV_NAME"
119 cp README.md "$REV_NAME" 121 cp README.md "$REV_NAME"
120 122
121 ARCHIVE_NAME="${REV_NAME}.tar.xz" 123 tar -cavf "$ARCHIVE_NAME" "$REV_NAME"
122 tar -cJvf "$ARCHIVE_NAME" "$REV_NAME"
123 124
124 # move the compiled archive into the artifacts directory to be uploaded by travis releases 125 # move the compiled archive into the artifacts directory to be uploaded by travis releases
125 mv "$ARCHIVE_NAME" artifacts/ 126 mv "$ARCHIVE_NAME" artifacts/
diff --git a/.travis.yml b/.travis.yml
index cf1e1e26c..cdb638f7a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -33,7 +33,7 @@ deploy:
33 api_key: 33 api_key:
34 secure: Mck15DIWaJdxDiS3aYVlM9N3G6y8VKUI1rnwII7/iolfm1s94U+tgvbheZDmT7SSbFyaGaYO/E8HrV/uZR9Vvs7ev20sHsTN1u60OTWfDIIyHs9SqjhcGbtq95m9/dMFschOYqTOR+gAs5BsxjuoeAotHdhpQEwvkO2oo5oR0zhGy45gjFnVvtcxT/IfpZBIpVgcK3aLb9zT6ekcJbSiPmEB15iLq3xXd0nFUNtEZdX3D6Veye4n5jB6n72qN8JVoKvPZAwaC2K0pZxpcGJaXDchLsw1q+4eCvdz6UJfUemeQ/uMAmjfeQ3wrzYGXe3nCM3WmX5wosCsB0mw4zYatzl3si6CZ1W+0GkV4Rwlx03dfp7v3EeFhTsXYCaXqhwuLZnWOLUik8t9vaSoFUx4nUIRwfO9kAMUJQSpLuHNO2nT01s3GxvqxzczuLQ9he5nGSi0RRodUzDwek1qUp6I4uV3gRHKz4B07YIc1i2fK88NLXjyQ0uLVZ+7Oq1+kgDp6+N7vvXXZ5qZ17tdaysSbKEE0Y8zsoXw7Rk1tPN19vrCS+TSpomNMyQyne1k+I5iZ/qkxPTLAS5qI6Utc2dL3GJdxWRAEfGNO9AIX3GV/jmmKfdcvwGsCYP8hxqs5vLYfgacw3D8NLf1941lQUwavC17jm9EV9g5G3Pn1Cp516E= 34 secure: Mck15DIWaJdxDiS3aYVlM9N3G6y8VKUI1rnwII7/iolfm1s94U+tgvbheZDmT7SSbFyaGaYO/E8HrV/uZR9Vvs7ev20sHsTN1u60OTWfDIIyHs9SqjhcGbtq95m9/dMFschOYqTOR+gAs5BsxjuoeAotHdhpQEwvkO2oo5oR0zhGy45gjFnVvtcxT/IfpZBIpVgcK3aLb9zT6ekcJbSiPmEB15iLq3xXd0nFUNtEZdX3D6Veye4n5jB6n72qN8JVoKvPZAwaC2K0pZxpcGJaXDchLsw1q+4eCvdz6UJfUemeQ/uMAmjfeQ3wrzYGXe3nCM3WmX5wosCsB0mw4zYatzl3si6CZ1W+0GkV4Rwlx03dfp7v3EeFhTsXYCaXqhwuLZnWOLUik8t9vaSoFUx4nUIRwfO9kAMUJQSpLuHNO2nT01s3GxvqxzczuLQ9he5nGSi0RRodUzDwek1qUp6I4uV3gRHKz4B07YIc1i2fK88NLXjyQ0uLVZ+7Oq1+kgDp6+N7vvXXZ5qZ17tdaysSbKEE0Y8zsoXw7Rk1tPN19vrCS+TSpomNMyQyne1k+I5iZ/qkxPTLAS5qI6Utc2dL3GJdxWRAEfGNO9AIX3GV/jmmKfdcvwGsCYP8hxqs5vLYfgacw3D8NLf1941lQUwavC17jm9EV9g5G3Pn1Cp516E=
35 file_glob: true 35 file_glob: true
36 file: "artifacts/*.tar.xz" 36 file: "artifacts/*.tar.*"
37 skip_cleanup: true 37 skip_cleanup: true
38 on: 38 on:
39 repo: citra-emu/citra-nightly \ No newline at end of file 39 repo: citra-emu/citra-nightly
diff --git a/hooks/pre-commit b/hooks/pre-commit
index 04fdaf8ec..098a99216 100755
--- a/hooks/pre-commit
+++ b/hooks/pre-commit
@@ -24,20 +24,3 @@ If you know what you are doing, you can try 'git commit --no-verify' to bypass t
24END 24END
25 exit 1 25 exit 1
26fi 26fi
27
28for f in $(git diff --name-only --diff-filter=ACMRTUXB --cached); do
29 if ! echo "$f" | egrep -q "[.](cpp|h)$"; then
30 continue
31 fi
32 if ! echo "$f" | egrep -q "^src/"; then
33 continue
34 fi
35 d=$(clang-format "$f" | diff -u "$f" -)
36 if ! [ -z "$d" ]; then
37 echo "!!! $f not compliant to coding style, here is the fix:"
38 echo "$d"
39 fail=1
40 fi
41done
42
43exit "${fail-0}"
diff --git a/src/citra/emu_window/emu_window_sdl2.cpp b/src/citra/emu_window/emu_window_sdl2.cpp
index 81a3abe3f..00d00905a 100644
--- a/src/citra/emu_window/emu_window_sdl2.cpp
+++ b/src/citra/emu_window/emu_window_sdl2.cpp
@@ -79,8 +79,8 @@ EmuWindow_SDL2::EmuWindow_SDL2() {
79 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); 79 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
80 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0); 80 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);
81 81
82 std::string window_title = 82 std::string window_title = Common::StringFromFormat("Citra %s| %s-%s ", Common::g_build_name,
83 Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc); 83 Common::g_scm_branch, Common::g_scm_desc);
84 render_window = SDL_CreateWindow( 84 render_window = SDL_CreateWindow(
85 window_title.c_str(), 85 window_title.c_str(),
86 SDL_WINDOWPOS_UNDEFINED, // x position 86 SDL_WINDOWPOS_UNDEFINED, // x position
diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp
index 948db384d..69d18cf0c 100644
--- a/src/citra_qt/bootmanager.cpp
+++ b/src/citra_qt/bootmanager.cpp
@@ -101,8 +101,8 @@ private:
101GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread) 101GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread)
102 : QWidget(parent), child(nullptr), keyboard_id(0), emu_thread(emu_thread) { 102 : QWidget(parent), child(nullptr), keyboard_id(0), emu_thread(emu_thread) {
103 103
104 std::string window_title = 104 std::string window_title = Common::StringFromFormat("Citra %s| %s-%s", Common::g_build_name,
105 Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc); 105 Common::g_scm_branch, Common::g_scm_desc);
106 setWindowTitle(QString::fromStdString(window_title)); 106 setWindowTitle(QString::fromStdString(window_title));
107 107
108 keyboard_id = KeyMap::NewDeviceId(); 108 keyboard_id = KeyMap::NewDeviceId();
diff --git a/src/citra_qt/configure_general.ui b/src/citra_qt/configure_general.ui
index 0f3352a1d..c739605a4 100644
--- a/src/citra_qt/configure_general.ui
+++ b/src/citra_qt/configure_general.ui
@@ -27,7 +27,7 @@
27 <item> 27 <item>
28 <widget class="QCheckBox" name="toggle_deepscan"> 28 <widget class="QCheckBox" name="toggle_deepscan">
29 <property name="text"> 29 <property name="text">
30 <string>Recursive scan for game folder</string> 30 <string>Search sub-directories for games</string>
31 </property> 31 </property>
32 </widget> 32 </widget>
33 </item> 33 </item>
diff --git a/src/citra_qt/debugger/graphics/graphics_tracing.h b/src/citra_qt/debugger/graphics/graphics_tracing.h
index 3f73bcd2e..eb1292c29 100644
--- a/src/citra_qt/debugger/graphics/graphics_tracing.h
+++ b/src/citra_qt/debugger/graphics/graphics_tracing.h
@@ -15,6 +15,9 @@ public:
15 explicit GraphicsTracingWidget(std::shared_ptr<Pica::DebugContext> debug_context, 15 explicit GraphicsTracingWidget(std::shared_ptr<Pica::DebugContext> debug_context,
16 QWidget* parent = nullptr); 16 QWidget* parent = nullptr);
17 17
18 void OnEmulationStarting(EmuThread* emu_thread);
19 void OnEmulationStopping();
20
18private slots: 21private slots:
19 void StartRecording(); 22 void StartRecording();
20 void StopRecording(); 23 void StopRecording();
@@ -23,9 +26,6 @@ private slots:
23 void OnBreakPointHit(Pica::DebugContext::Event event, void* data) override; 26 void OnBreakPointHit(Pica::DebugContext::Event event, void* data) override;
24 void OnResumed() override; 27 void OnResumed() override;
25 28
26 void OnEmulationStarting(EmuThread* emu_thread);
27 void OnEmulationStopping();
28
29signals: 29signals:
30 void SetStartTracingButtonEnabled(bool enable); 30 void SetStartTracingButtonEnabled(bool enable);
31 void SetStopTracingButtonEnabled(bool enable); 31 void SetStopTracingButtonEnabled(bool enable);
diff --git a/src/citra_qt/game_list.cpp b/src/citra_qt/game_list.cpp
index 222c82b1c..db6f920ff 100644
--- a/src/citra_qt/game_list.cpp
+++ b/src/citra_qt/game_list.cpp
@@ -39,6 +39,7 @@ GameList::GameList(QWidget* parent) : QWidget{parent} {
39 39
40 connect(tree_view, &QTreeView::activated, this, &GameList::ValidateEntry); 40 connect(tree_view, &QTreeView::activated, this, &GameList::ValidateEntry);
41 connect(tree_view, &QTreeView::customContextMenuRequested, this, &GameList::PopupContextMenu); 41 connect(tree_view, &QTreeView::customContextMenuRequested, this, &GameList::PopupContextMenu);
42 connect(&watcher, &QFileSystemWatcher::directoryChanged, this, &GameList::RefreshGameDirectory);
42 43
43 // We must register all custom types with the Qt Automoc system so that we are able to use it 44 // We must register all custom types with the Qt Automoc system so that we are able to use it
44 // with signals/slots. In this case, QList falls under the umbrells of custom types. 45 // with signals/slots. In this case, QList falls under the umbrells of custom types.
@@ -103,6 +104,12 @@ void GameList::PopulateAsync(const QString& dir_path, bool deep_scan) {
103 item_model->removeRows(0, item_model->rowCount()); 104 item_model->removeRows(0, item_model->rowCount());
104 105
105 emit ShouldCancelWorker(); 106 emit ShouldCancelWorker();
107
108 auto watch_dirs = watcher.directories();
109 if (!watch_dirs.isEmpty()) {
110 watcher.removePaths(watch_dirs);
111 }
112 UpdateWatcherList(dir_path.toStdString(), deep_scan ? 256 : 0);
106 GameListWorker* worker = new GameListWorker(dir_path, deep_scan); 113 GameListWorker* worker = new GameListWorker(dir_path, deep_scan);
107 114
108 connect(worker, &GameListWorker::EntryReady, this, &GameList::AddEntry, Qt::QueuedConnection); 115 connect(worker, &GameListWorker::EntryReady, this, &GameList::AddEntry, Qt::QueuedConnection);
@@ -140,6 +147,45 @@ static bool HasSupportedFileExtension(const std::string& file_name) {
140 return GameList::supported_file_extensions.contains(file.suffix(), Qt::CaseInsensitive); 147 return GameList::supported_file_extensions.contains(file.suffix(), Qt::CaseInsensitive);
141} 148}
142 149
150void GameList::RefreshGameDirectory() {
151 if (!UISettings::values.gamedir.isEmpty() && current_worker != nullptr) {
152 LOG_INFO(Frontend, "Change detected in the games directory. Reloading game list.");
153 PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan);
154 }
155}
156
157/**
158 * Adds the game list folder to the QFileSystemWatcher to check for updates.
159 *
160 * The file watcher will fire off an update to the game list when a change is detected in the game
161 * list folder.
162 *
163 * Notice: This method is run on the UI thread because QFileSystemWatcher is not thread safe and
164 * this function is fast enough to not stall the UI thread. If performance is an issue, it should
165 * be moved to another thread and properly locked to prevent concurrency issues.
166 *
167 * @param dir folder to check for changes in
168 * @param recursion 0 if recursion is disabled. Any positive number passed to this will add each
169 * directory recursively to the watcher and will update the file list if any of the folders
170 * change. The number determines how deep the recursion should traverse.
171 */
172void GameList::UpdateWatcherList(const std::string& dir, unsigned int recursion) {
173 const auto callback = [this, recursion](unsigned* num_entries_out, const std::string& directory,
174 const std::string& virtual_name) -> bool {
175 std::string physical_name = directory + DIR_SEP + virtual_name;
176
177 if (FileUtil::IsDirectory(physical_name)) {
178 UpdateWatcherList(physical_name, recursion - 1);
179 }
180 return true;
181 };
182
183 watcher.addPath(QString::fromStdString(dir));
184 if (recursion > 0) {
185 FileUtil::ForeachDirectoryEntry(nullptr, dir, callback);
186 }
187}
188
143void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsigned int recursion) { 189void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsigned int recursion) {
144 const auto callback = [this, recursion](unsigned* num_entries_out, const std::string& directory, 190 const auto callback = [this, recursion](unsigned* num_entries_out, const std::string& directory,
145 const std::string& virtual_name) -> bool { 191 const std::string& virtual_name) -> bool {
@@ -182,6 +228,6 @@ void GameListWorker::run() {
182} 228}
183 229
184void GameListWorker::Cancel() { 230void GameListWorker::Cancel() {
185 disconnect(this, nullptr, nullptr, nullptr); 231 this->disconnect();
186 stop_processing = true; 232 stop_processing = true;
187} 233}
diff --git a/src/citra_qt/game_list.h b/src/citra_qt/game_list.h
index e6b7eea0b..b141fa3a5 100644
--- a/src/citra_qt/game_list.h
+++ b/src/citra_qt/game_list.h
@@ -4,6 +4,7 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <QFileSystemWatcher>
7#include <QModelIndex> 8#include <QModelIndex>
8#include <QSettings> 9#include <QSettings>
9#include <QStandardItem> 10#include <QStandardItem>
@@ -46,8 +47,11 @@ private:
46 void DonePopulating(); 47 void DonePopulating();
47 48
48 void PopupContextMenu(const QPoint& menu_location); 49 void PopupContextMenu(const QPoint& menu_location);
50 void UpdateWatcherList(const std::string& path, unsigned int recursion);
51 void RefreshGameDirectory();
49 52
50 QTreeView* tree_view = nullptr; 53 QTreeView* tree_view = nullptr;
51 QStandardItemModel* item_model = nullptr; 54 QStandardItemModel* item_model = nullptr;
52 GameListWorker* current_worker = nullptr; 55 GameListWorker* current_worker = nullptr;
56 QFileSystemWatcher watcher;
53}; 57};
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp
index 717552468..7a80af890 100644
--- a/src/citra_qt/main.cpp
+++ b/src/citra_qt/main.cpp
@@ -59,16 +59,18 @@ GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) {
59 statusBar()->hide(); 59 statusBar()->hide();
60 60
61 InitializeWidgets(); 61 InitializeWidgets();
62 InitializeDebugMenuActions(); 62 InitializeDebugWidgets();
63 InitializeRecentFileMenuActions(); 63 InitializeRecentFileMenuActions();
64 InitializeHotkeys(); 64 InitializeHotkeys();
65 65
66 SetDefaultUIGeometry(); 66 SetDefaultUIGeometry();
67 RestoreUIState(); 67 RestoreUIState();
68 68
69 ConnectMenuEvents();
69 ConnectWidgetEvents(); 70 ConnectWidgetEvents();
70 71
71 setWindowTitle(QString("Citra | %1-%2").arg(Common::g_scm_branch, Common::g_scm_desc)); 72 setWindowTitle(QString("Citra %1| %2-%3")
73 .arg(Common::g_build_name, Common::g_scm_branch, Common::g_scm_desc));
72 show(); 74 show();
73 75
74 game_list->PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan); 76 game_list->PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan);
@@ -93,74 +95,85 @@ void GMainWindow::InitializeWidgets() {
93 95
94 game_list = new GameList(); 96 game_list = new GameList();
95 ui.horizontalLayout->addWidget(game_list); 97 ui.horizontalLayout->addWidget(game_list);
98}
99
100void GMainWindow::InitializeDebugWidgets() {
101 connect(ui.action_Create_Pica_Surface_Viewer, &QAction::triggered, this,
102 &GMainWindow::OnCreateGraphicsSurfaceViewer);
103
104 QMenu* debug_menu = ui.menu_View_Debugging;
96 105
97 profilerWidget = new ProfilerWidget(this); 106 profilerWidget = new ProfilerWidget(this);
98 addDockWidget(Qt::BottomDockWidgetArea, profilerWidget); 107 addDockWidget(Qt::BottomDockWidgetArea, profilerWidget);
99 profilerWidget->hide(); 108 profilerWidget->hide();
109 debug_menu->addAction(profilerWidget->toggleViewAction());
100 110
101#if MICROPROFILE_ENABLED 111#if MICROPROFILE_ENABLED
102 microProfileDialog = new MicroProfileDialog(this); 112 microProfileDialog = new MicroProfileDialog(this);
103 microProfileDialog->hide(); 113 microProfileDialog->hide();
114 debug_menu->addAction(microProfileDialog->toggleViewAction());
104#endif 115#endif
105 116
106 disasmWidget = new DisassemblerWidget(this, emu_thread.get()); 117 disasmWidget = new DisassemblerWidget(this, emu_thread.get());
107 addDockWidget(Qt::BottomDockWidgetArea, disasmWidget); 118 addDockWidget(Qt::BottomDockWidgetArea, disasmWidget);
108 disasmWidget->hide(); 119 disasmWidget->hide();
120 debug_menu->addAction(disasmWidget->toggleViewAction());
121 connect(this, &GMainWindow::EmulationStarting, disasmWidget,
122 &DisassemblerWidget::OnEmulationStarting);
123 connect(this, &GMainWindow::EmulationStopping, disasmWidget,
124 &DisassemblerWidget::OnEmulationStopping);
109 125
110 registersWidget = new RegistersWidget(this); 126 registersWidget = new RegistersWidget(this);
111 addDockWidget(Qt::RightDockWidgetArea, registersWidget); 127 addDockWidget(Qt::RightDockWidgetArea, registersWidget);
112 registersWidget->hide(); 128 registersWidget->hide();
129 debug_menu->addAction(registersWidget->toggleViewAction());
130 connect(this, &GMainWindow::EmulationStarting, registersWidget,
131 &RegistersWidget::OnEmulationStarting);
132 connect(this, &GMainWindow::EmulationStopping, registersWidget,
133 &RegistersWidget::OnEmulationStopping);
113 134
114 callstackWidget = new CallstackWidget(this); 135 callstackWidget = new CallstackWidget(this);
115 addDockWidget(Qt::RightDockWidgetArea, callstackWidget); 136 addDockWidget(Qt::RightDockWidgetArea, callstackWidget);
116 callstackWidget->hide(); 137 callstackWidget->hide();
138 debug_menu->addAction(callstackWidget->toggleViewAction());
117 139
118 graphicsWidget = new GPUCommandStreamWidget(this); 140 graphicsWidget = new GPUCommandStreamWidget(this);
119 addDockWidget(Qt::RightDockWidgetArea, graphicsWidget); 141 addDockWidget(Qt::RightDockWidgetArea, graphicsWidget);
120 graphicsWidget->hide(); 142 graphicsWidget->hide();
143 debug_menu->addAction(graphicsWidget->toggleViewAction());
121 144
122 graphicsCommandsWidget = new GPUCommandListWidget(this); 145 graphicsCommandsWidget = new GPUCommandListWidget(this);
123 addDockWidget(Qt::RightDockWidgetArea, graphicsCommandsWidget); 146 addDockWidget(Qt::RightDockWidgetArea, graphicsCommandsWidget);
124 graphicsCommandsWidget->hide(); 147 graphicsCommandsWidget->hide();
148 debug_menu->addAction(graphicsCommandsWidget->toggleViewAction());
125 149
126 graphicsBreakpointsWidget = new GraphicsBreakPointsWidget(Pica::g_debug_context, this); 150 graphicsBreakpointsWidget = new GraphicsBreakPointsWidget(Pica::g_debug_context, this);
127 addDockWidget(Qt::RightDockWidgetArea, graphicsBreakpointsWidget); 151 addDockWidget(Qt::RightDockWidgetArea, graphicsBreakpointsWidget);
128 graphicsBreakpointsWidget->hide(); 152 graphicsBreakpointsWidget->hide();
153 debug_menu->addAction(graphicsBreakpointsWidget->toggleViewAction());
129 154
130 graphicsVertexShaderWidget = new GraphicsVertexShaderWidget(Pica::g_debug_context, this); 155 graphicsVertexShaderWidget = new GraphicsVertexShaderWidget(Pica::g_debug_context, this);
131 addDockWidget(Qt::RightDockWidgetArea, graphicsVertexShaderWidget); 156 addDockWidget(Qt::RightDockWidgetArea, graphicsVertexShaderWidget);
132 graphicsVertexShaderWidget->hide(); 157 graphicsVertexShaderWidget->hide();
158 debug_menu->addAction(graphicsVertexShaderWidget->toggleViewAction());
133 159
134 graphicsTracingWidget = new GraphicsTracingWidget(Pica::g_debug_context, this); 160 graphicsTracingWidget = new GraphicsTracingWidget(Pica::g_debug_context, this);
135 addDockWidget(Qt::RightDockWidgetArea, graphicsTracingWidget); 161 addDockWidget(Qt::RightDockWidgetArea, graphicsTracingWidget);
136 graphicsTracingWidget->hide(); 162 graphicsTracingWidget->hide();
163 debug_menu->addAction(graphicsTracingWidget->toggleViewAction());
164 connect(this, &GMainWindow::EmulationStarting, graphicsTracingWidget,
165 &GraphicsTracingWidget::OnEmulationStarting);
166 connect(this, &GMainWindow::EmulationStopping, graphicsTracingWidget,
167 &GraphicsTracingWidget::OnEmulationStopping);
137 168
138 waitTreeWidget = new WaitTreeWidget(this); 169 waitTreeWidget = new WaitTreeWidget(this);
139 addDockWidget(Qt::LeftDockWidgetArea, waitTreeWidget); 170 addDockWidget(Qt::LeftDockWidgetArea, waitTreeWidget);
140 waitTreeWidget->hide(); 171 waitTreeWidget->hide();
141}
142
143void GMainWindow::InitializeDebugMenuActions() {
144 auto graphicsSurfaceViewerAction = new QAction(tr("Create Pica Surface Viewer"), this);
145 connect(graphicsSurfaceViewerAction, SIGNAL(triggered()), this,
146 SLOT(OnCreateGraphicsSurfaceViewer()));
147
148 QMenu* debug_menu = ui.menu_View->addMenu(tr("Debugging"));
149 debug_menu->addAction(graphicsSurfaceViewerAction);
150 debug_menu->addSeparator();
151 debug_menu->addAction(profilerWidget->toggleViewAction());
152#if MICROPROFILE_ENABLED
153 debug_menu->addAction(microProfileDialog->toggleViewAction());
154#endif
155 debug_menu->addAction(disasmWidget->toggleViewAction());
156 debug_menu->addAction(registersWidget->toggleViewAction());
157 debug_menu->addAction(callstackWidget->toggleViewAction());
158 debug_menu->addAction(graphicsWidget->toggleViewAction());
159 debug_menu->addAction(graphicsCommandsWidget->toggleViewAction());
160 debug_menu->addAction(graphicsBreakpointsWidget->toggleViewAction());
161 debug_menu->addAction(graphicsVertexShaderWidget->toggleViewAction());
162 debug_menu->addAction(graphicsTracingWidget->toggleViewAction());
163 debug_menu->addAction(waitTreeWidget->toggleViewAction()); 172 debug_menu->addAction(waitTreeWidget->toggleViewAction());
173 connect(this, &GMainWindow::EmulationStarting, waitTreeWidget,
174 &WaitTreeWidget::OnEmulationStarting);
175 connect(this, &GMainWindow::EmulationStopping, waitTreeWidget,
176 &WaitTreeWidget::OnEmulationStopping);
164} 177}
165 178
166void GMainWindow::InitializeRecentFileMenuActions() { 179void GMainWindow::InitializeRecentFileMenuActions() {
@@ -215,41 +228,40 @@ void GMainWindow::RestoreUIState() {
215 ui.action_Single_Window_Mode->setChecked(UISettings::values.single_window_mode); 228 ui.action_Single_Window_Mode->setChecked(UISettings::values.single_window_mode);
216 ToggleWindowMode(); 229 ToggleWindowMode();
217 230
218 ui.actionDisplay_widget_title_bars->setChecked(UISettings::values.display_titlebar); 231 ui.action_Display_Dock_Widget_Headers->setChecked(UISettings::values.display_titlebar);
219 OnDisplayTitleBars(ui.actionDisplay_widget_title_bars->isChecked()); 232 OnDisplayTitleBars(ui.action_Display_Dock_Widget_Headers->isChecked());
220} 233}
221 234
222void GMainWindow::ConnectWidgetEvents() { 235void GMainWindow::ConnectWidgetEvents() {
223 connect(game_list, SIGNAL(GameChosen(QString)), this, SLOT(OnGameListLoadFile(QString)), 236 connect(game_list, SIGNAL(GameChosen(QString)), this, SLOT(OnGameListLoadFile(QString)));
224 Qt::DirectConnection);
225 connect(game_list, SIGNAL(OpenSaveFolderRequested(u64)), this, 237 connect(game_list, SIGNAL(OpenSaveFolderRequested(u64)), this,
226 SLOT(OnGameListOpenSaveFolder(u64)), Qt::DirectConnection); 238 SLOT(OnGameListOpenSaveFolder(u64)));
227 connect(ui.action_Configure, SIGNAL(triggered()), this, SLOT(OnConfigure())); 239
228 connect(ui.action_Load_File, SIGNAL(triggered()), this, SLOT(OnMenuLoadFile()),
229 Qt::DirectConnection);
230 connect(ui.action_Load_Symbol_Map, SIGNAL(triggered()), this, SLOT(OnMenuLoadSymbolMap()));
231 connect(ui.action_Select_Game_List_Root, SIGNAL(triggered()), this,
232 SLOT(OnMenuSelectGameListRoot()));
233 connect(ui.action_Start, SIGNAL(triggered()), this, SLOT(OnStartGame()));
234 connect(ui.action_Pause, SIGNAL(triggered()), this, SLOT(OnPauseGame()));
235 connect(ui.action_Stop, SIGNAL(triggered()), this, SLOT(OnStopGame()));
236 connect(ui.action_Single_Window_Mode, SIGNAL(triggered(bool)), this, SLOT(ToggleWindowMode()));
237
238 connect(this, SIGNAL(EmulationStarting(EmuThread*)), disasmWidget,
239 SLOT(OnEmulationStarting(EmuThread*)));
240 connect(this, SIGNAL(EmulationStopping()), disasmWidget, SLOT(OnEmulationStopping()));
241 connect(this, SIGNAL(EmulationStarting(EmuThread*)), registersWidget,
242 SLOT(OnEmulationStarting(EmuThread*)));
243 connect(this, SIGNAL(EmulationStopping()), registersWidget, SLOT(OnEmulationStopping()));
244 connect(this, SIGNAL(EmulationStarting(EmuThread*)), render_window, 240 connect(this, SIGNAL(EmulationStarting(EmuThread*)), render_window,
245 SLOT(OnEmulationStarting(EmuThread*))); 241 SLOT(OnEmulationStarting(EmuThread*)));
246 connect(this, SIGNAL(EmulationStopping()), render_window, SLOT(OnEmulationStopping())); 242 connect(this, SIGNAL(EmulationStopping()), render_window, SLOT(OnEmulationStopping()));
247 connect(this, SIGNAL(EmulationStarting(EmuThread*)), graphicsTracingWidget, 243}
248 SLOT(OnEmulationStarting(EmuThread*))); 244
249 connect(this, SIGNAL(EmulationStopping()), graphicsTracingWidget, SLOT(OnEmulationStopping())); 245void GMainWindow::ConnectMenuEvents() {
250 connect(this, SIGNAL(EmulationStarting(EmuThread*)), waitTreeWidget, 246 // File
251 SLOT(OnEmulationStarting(EmuThread*))); 247 connect(ui.action_Load_File, &QAction::triggered, this, &GMainWindow::OnMenuLoadFile);
252 connect(this, SIGNAL(EmulationStopping()), waitTreeWidget, SLOT(OnEmulationStopping())); 248 connect(ui.action_Load_Symbol_Map, &QAction::triggered, this,
249 &GMainWindow::OnMenuLoadSymbolMap);
250 connect(ui.action_Select_Game_List_Root, &QAction::triggered, this,
251 &GMainWindow::OnMenuSelectGameListRoot);
252 connect(ui.action_Exit, &QAction::triggered, this, &QMainWindow::close);
253
254 // Emulation
255 connect(ui.action_Start, &QAction::triggered, this, &GMainWindow::OnStartGame);
256 connect(ui.action_Pause, &QAction::triggered, this, &GMainWindow::OnPauseGame);
257 connect(ui.action_Stop, &QAction::triggered, this, &GMainWindow::OnStopGame);
258 connect(ui.action_Configure, &QAction::triggered, this, &GMainWindow::OnConfigure);
259
260 // View
261 connect(ui.action_Single_Window_Mode, &QAction::triggered, this,
262 &GMainWindow::ToggleWindowMode);
263 connect(ui.action_Display_Dock_Widget_Headers, &QAction::triggered, this,
264 &GMainWindow::OnDisplayTitleBars);
253} 265}
254 266
255void GMainWindow::OnDisplayTitleBars(bool show) { 267void GMainWindow::OnDisplayTitleBars(bool show) {
@@ -612,7 +624,7 @@ void GMainWindow::closeEvent(QCloseEvent* event) {
612 UISettings::values.microprofile_visible = microProfileDialog->isVisible(); 624 UISettings::values.microprofile_visible = microProfileDialog->isVisible();
613#endif 625#endif
614 UISettings::values.single_window_mode = ui.action_Single_Window_Mode->isChecked(); 626 UISettings::values.single_window_mode = ui.action_Single_Window_Mode->isChecked();
615 UISettings::values.display_titlebar = ui.actionDisplay_widget_title_bars->isChecked(); 627 UISettings::values.display_titlebar = ui.action_Display_Dock_Widget_Headers->isChecked();
616 UISettings::values.first_start = false; 628 UISettings::values.first_start = false;
617 629
618 game_list->SaveInterfaceLayout(); 630 game_list->SaveInterfaceLayout();
diff --git a/src/citra_qt/main.h b/src/citra_qt/main.h
index debc35c92..87637b92b 100644
--- a/src/citra_qt/main.h
+++ b/src/citra_qt/main.h
@@ -64,7 +64,7 @@ signals:
64 64
65private: 65private:
66 void InitializeWidgets(); 66 void InitializeWidgets();
67 void InitializeDebugMenuActions(); 67 void InitializeDebugWidgets();
68 void InitializeRecentFileMenuActions(); 68 void InitializeRecentFileMenuActions();
69 void InitializeHotkeys(); 69 void InitializeHotkeys();
70 70
@@ -72,6 +72,7 @@ private:
72 void RestoreUIState(); 72 void RestoreUIState();
73 73
74 void ConnectWidgetEvents(); 74 void ConnectWidgetEvents();
75 void ConnectMenuEvents();
75 76
76 bool LoadROM(const QString& filename); 77 bool LoadROM(const QString& filename);
77 void BootGame(const QString& filename); 78 void BootGame(const QString& filename);
diff --git a/src/citra_qt/main.ui b/src/citra_qt/main.ui
index adfa3689e..4a95cda9a 100644
--- a/src/citra_qt/main.ui
+++ b/src/citra_qt/main.ui
@@ -79,8 +79,16 @@
79 <property name="title"> 79 <property name="title">
80 <string>&amp;View</string> 80 <string>&amp;View</string>
81 </property> 81 </property>
82 <widget class="QMenu" name="menu_View_Debugging">
83 <property name="title">
84 <string>Debugging</string>
85 </property>
86 <addaction name="action_Create_Pica_Surface_Viewer"/>
87 <addaction name="separator"/>
88 </widget>
82 <addaction name="action_Single_Window_Mode"/> 89 <addaction name="action_Single_Window_Mode"/>
83 <addaction name="actionDisplay_widget_title_bars"/> 90 <addaction name="action_Display_Dock_Widget_Headers"/>
91 <addaction name="menu_View_Debugging"/>
84 </widget> 92 </widget>
85 <widget class="QMenu" name="menu_Help"> 93 <widget class="QMenu" name="menu_Help">
86 <property name="title"> 94 <property name="title">
@@ -151,7 +159,7 @@
151 <string>Configure...</string> 159 <string>Configure...</string>
152 </property> 160 </property>
153 </action> 161 </action>
154 <action name="actionDisplay_widget_title_bars"> 162 <action name="action_Display_Dock_Widget_Headers">
155 <property name="checkable"> 163 <property name="checkable">
156 <bool>true</bool> 164 <bool>true</bool>
157 </property> 165 </property>
@@ -167,44 +175,11 @@
167 <string>Selects a folder to display in the game list</string> 175 <string>Selects a folder to display in the game list</string>
168 </property> 176 </property>
169 </action> 177 </action>
178 <action name="action_Create_Pica_Surface_Viewer">
179 <property name="text">
180 <string>Create Pica Surface Viewer</string>
181 </property>
182 </action>
170 </widget> 183 </widget>
171 <resources/> 184 <resources/>
172 <connections>
173 <connection>
174 <sender>action_Exit</sender>
175 <signal>triggered()</signal>
176 <receiver>MainWindow</receiver>
177 <slot>close()</slot>
178 <hints>
179 <hint type="sourcelabel">
180 <x>-1</x>
181 <y>-1</y>
182 </hint>
183 <hint type="destinationlabel">
184 <x>367</x>
185 <y>314</y>
186 </hint>
187 </hints>
188 </connection>
189 <connection>
190 <sender>actionDisplay_widget_title_bars</sender>
191 <signal>triggered(bool)</signal>
192 <receiver>MainWindow</receiver>
193 <slot>OnDisplayTitleBars(bool)</slot>
194 <hints>
195 <hint type="sourcelabel">
196 <x>-1</x>
197 <y>-1</y>
198 </hint>
199 <hint type="destinationlabel">
200 <x>540</x>
201 <y>364</y>
202 </hint>
203 </hints>
204 </connection>
205 </connections>
206 <slots>
207 <slot>OnConfigure()</slot>
208 <slot>OnDisplayTitleBars(bool)</slot>
209 </slots>
210</ui> 185</ui>
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 592911c2b..26c83efda 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -1,4 +1,27 @@
1# Generate cpp with Git revision from template 1# Generate cpp with Git revision from template
2# Also if this is a CI build, add the build name (ie: Nightly, Bleeding Edge) to the scm_rev file as well
3set(REPO_NAME "")
4if ($ENV{CI})
5 if ($ENV{TRAVIS})
6 set(BUILD_REPOSITORY $ENV{TRAVIS_REPO_SLUG})
7 elseif($ENV{APPVEYOR})
8 set(BUILD_REPOSITORY $ENV{APPVEYOR_REPO_NAME})
9 endif()
10 # regex capture the string nightly or bleeding-edge into CMAKE_MATCH_1
11 string(REGEX MATCH "citra-emu/citra-?(.*)" OUTVAR ${BUILD_REPOSITORY})
12 if (${CMAKE_MATCH_COUNT} GREATER 0)
13 # capitalize the first letter of each word in the repo name.
14 string(REPLACE "-" ";" REPO_NAME_LIST ${CMAKE_MATCH_1})
15 foreach(WORD ${REPO_NAME_LIST})
16 string(SUBSTRING ${WORD} 0 1 FIRST_LETTER)
17 string(SUBSTRING ${WORD} 1 -1 REMAINDER)
18 string(TOUPPER ${FIRST_LETTER} FIRST_LETTER)
19 # this leaves a trailing space on the last word, but we actually want that
20 # because of how its styled in the title bar.
21 set(REPO_NAME "${REPO_NAME}${FIRST_LETTER}${REMAINDER} ")
22 endforeach()
23 endif()
24endif()
2configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scm_rev.cpp.in" "${CMAKE_CURRENT_SOURCE_DIR}/scm_rev.cpp" @ONLY) 25configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scm_rev.cpp.in" "${CMAKE_CURRENT_SOURCE_DIR}/scm_rev.cpp" @ONLY)
3 26
4set(SRCS 27set(SRCS
diff --git a/src/common/scm_rev.cpp.in b/src/common/scm_rev.cpp.in
index 79b404bb8..0080db5d5 100644
--- a/src/common/scm_rev.cpp.in
+++ b/src/common/scm_rev.cpp.in
@@ -7,12 +7,14 @@
7#define GIT_REV "@GIT_REV@" 7#define GIT_REV "@GIT_REV@"
8#define GIT_BRANCH "@GIT_BRANCH@" 8#define GIT_BRANCH "@GIT_BRANCH@"
9#define GIT_DESC "@GIT_DESC@" 9#define GIT_DESC "@GIT_DESC@"
10#define BUILD_NAME "@REPO_NAME@"
10 11
11namespace Common { 12namespace Common {
12 13
13const char g_scm_rev[] = GIT_REV; 14const char g_scm_rev[] = GIT_REV;
14const char g_scm_branch[] = GIT_BRANCH; 15const char g_scm_branch[] = GIT_BRANCH;
15const char g_scm_desc[] = GIT_DESC; 16const char g_scm_desc[] = GIT_DESC;
17const char g_build_name[] = BUILD_NAME;
16 18
17} // namespace 19} // namespace
18 20
diff --git a/src/common/scm_rev.h b/src/common/scm_rev.h
index 0ef190afa..e22389803 100644
--- a/src/common/scm_rev.h
+++ b/src/common/scm_rev.h
@@ -9,5 +9,6 @@ namespace Common {
9extern const char g_scm_rev[]; 9extern const char g_scm_rev[];
10extern const char g_scm_branch[]; 10extern const char g_scm_branch[];
11extern const char g_scm_desc[]; 11extern const char g_scm_desc[];
12extern const char g_build_name[];
12 13
13} // namespace 14} // namespace
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index 67c45640a..273bc8167 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -3928,13 +3928,13 @@ SXTB16_INST : {
3928 if (inst_cream->Rn == 15) { 3928 if (inst_cream->Rn == 15) {
3929 u32 lo = (u32)(s8)rm_val; 3929 u32 lo = (u32)(s8)rm_val;
3930 u32 hi = (u32)(s8)(rm_val >> 16); 3930 u32 hi = (u32)(s8)(rm_val >> 16);
3931 RD = (lo | (hi << 16)); 3931 RD = (lo & 0xFFFF) | (hi << 16);
3932 } 3932 }
3933 // SXTAB16 3933 // SXTAB16
3934 else { 3934 else {
3935 u32 lo = (rn_val & 0xFFFF) + (u32)(s8)(rm_val & 0xFF); 3935 u32 lo = rn_val + (u32)(s8)(rm_val & 0xFF);
3936 u32 hi = ((rn_val >> 16) & 0xFFFF) + (u32)(s8)((rm_val >> 16) & 0xFF); 3936 u32 hi = (rn_val >> 16) + (u32)(s8)((rm_val >> 16) & 0xFF);
3937 RD = (lo | (hi << 16)); 3937 RD = (lo & 0xFFFF) | (hi << 16);
3938 } 3938 }
3939 } 3939 }
3940 3940