summaryrefslogtreecommitdiffstats
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.cpp50
-rw-r--r--src/citra_qt/game_list.h4
-rw-r--r--src/citra_qt/main.cpp180
-rw-r--r--src/citra_qt/main.h21
-rw-r--r--src/citra_qt/main.ui55
-rw-r--r--src/common/CMakeLists.txt23
-rw-r--r--src/common/logging/backend.cpp1
-rw-r--r--src/common/logging/log.h1
-rw-r--r--src/common/scm_rev.cpp.in2
-rw-r--r--src/common/scm_rev.h1
-rw-r--r--src/core/CMakeLists.txt1
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp8
-rw-r--r--src/core/hle/ipc.h6
-rw-r--r--src/core/hle/kernel/timer.cpp39
-rw-r--r--src/core/hle/kernel/timer.h8
-rw-r--r--src/core/hle/service/hid/hid.cpp7
-rw-r--r--src/core/hle/service/ir/ir_u.cpp2
-rw-r--r--src/core/hle/service/nim/nim.cpp2
-rw-r--r--src/core/hle/svc.cpp5
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp59
-rw-r--r--src/video_core/texture/etc1.cpp2
-rw-r--r--src/video_core/texture/texture_decode.cpp2
29 files changed, 314 insertions, 207 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
if [ "$TRAVIS_OS_NAME" = "linux" -o -z "$TRAVIS_OS_NAME" ]; then
REV_NAME="citra-linux-${GITDATE}-${GITREV}"
+ ARCHIVE_NAME="${REV_NAME}.tar.xz"
mkdir "$REV_NAME"
cp build/src/citra/citra "$REV_NAME"
cp build/src/citra_qt/citra-qt "$REV_NAME"
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
REV_NAME="citra-osx-${GITDATE}-${GITREV}"
+ ARCHIVE_NAME="${REV_NAME}.tar.gz"
mkdir "$REV_NAME"
cp build/src/citra/Release/citra "$REV_NAME"
@@ -118,8 +120,7 @@ EOL
cp license.txt "$REV_NAME"
cp README.md "$REV_NAME"
- ARCHIVE_NAME="${REV_NAME}.tar.xz"
- tar -cJvf "$ARCHIVE_NAME" "$REV_NAME"
+ tar -cavf "$ARCHIVE_NAME" "$REV_NAME"
# move the compiled archive into the artifacts directory to be uploaded by travis releases
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:
api_key:
secure: Mck15DIWaJdxDiS3aYVlM9N3G6y8VKUI1rnwII7/iolfm1s94U+tgvbheZDmT7SSbFyaGaYO/E8HrV/uZR9Vvs7ev20sHsTN1u60OTWfDIIyHs9SqjhcGbtq95m9/dMFschOYqTOR+gAs5BsxjuoeAotHdhpQEwvkO2oo5oR0zhGy45gjFnVvtcxT/IfpZBIpVgcK3aLb9zT6ekcJbSiPmEB15iLq3xXd0nFUNtEZdX3D6Veye4n5jB6n72qN8JVoKvPZAwaC2K0pZxpcGJaXDchLsw1q+4eCvdz6UJfUemeQ/uMAmjfeQ3wrzYGXe3nCM3WmX5wosCsB0mw4zYatzl3si6CZ1W+0GkV4Rwlx03dfp7v3EeFhTsXYCaXqhwuLZnWOLUik8t9vaSoFUx4nUIRwfO9kAMUJQSpLuHNO2nT01s3GxvqxzczuLQ9he5nGSi0RRodUzDwek1qUp6I4uV3gRHKz4B07YIc1i2fK88NLXjyQ0uLVZ+7Oq1+kgDp6+N7vvXXZ5qZ17tdaysSbKEE0Y8zsoXw7Rk1tPN19vrCS+TSpomNMyQyne1k+I5iZ/qkxPTLAS5qI6Utc2dL3GJdxWRAEfGNO9AIX3GV/jmmKfdcvwGsCYP8hxqs5vLYfgacw3D8NLf1941lQUwavC17jm9EV9g5G3Pn1Cp516E=
file_glob: true
- file: "artifacts/*.tar.xz"
+ file: "artifacts/*.tar.*"
skip_cleanup: true
on:
- repo: citra-emu/citra-nightly \ No newline at end of file
+ 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
END
exit 1
fi
-
-for f in $(git diff --name-only --diff-filter=ACMRTUXB --cached); do
- if ! echo "$f" | egrep -q "[.](cpp|h)$"; then
- continue
- fi
- if ! echo "$f" | egrep -q "^src/"; then
- continue
- fi
- d=$(clang-format "$f" | diff -u "$f" -)
- if ! [ -z "$d" ]; then
- echo "!!! $f not compliant to coding style, here is the fix:"
- echo "$d"
- fail=1
- fi
-done
-
-exit "${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() {
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);
- std::string window_title =
- Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc);
+ std::string window_title = Common::StringFromFormat("Citra %s| %s-%s ", Common::g_build_name,
+ Common::g_scm_branch, Common::g_scm_desc);
render_window = SDL_CreateWindow(
window_title.c_str(),
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:
GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread)
: QWidget(parent), child(nullptr), keyboard_id(0), emu_thread(emu_thread) {
- std::string window_title =
- Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc);
+ std::string window_title = Common::StringFromFormat("Citra %s| %s-%s", Common::g_build_name,
+ Common::g_scm_branch, Common::g_scm_desc);
setWindowTitle(QString::fromStdString(window_title));
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 @@
<item>
<widget class="QCheckBox" name="toggle_deepscan">
<property name="text">
- <string>Recursive scan for game folder</string>
+ <string>Search sub-directories for games</string>
</property>
</widget>
</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:
explicit GraphicsTracingWidget(std::shared_ptr<Pica::DebugContext> debug_context,
QWidget* parent = nullptr);
+ void OnEmulationStarting(EmuThread* emu_thread);
+ void OnEmulationStopping();
+
private slots:
void StartRecording();
void StopRecording();
@@ -23,9 +26,6 @@ private slots:
void OnBreakPointHit(Pica::DebugContext::Event event, void* data) override;
void OnResumed() override;
- void OnEmulationStarting(EmuThread* emu_thread);
- void OnEmulationStopping();
-
signals:
void SetStartTracingButtonEnabled(bool enable);
void SetStopTracingButtonEnabled(bool enable);
diff --git a/src/citra_qt/game_list.cpp b/src/citra_qt/game_list.cpp
index 28e01d81a..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} {
connect(tree_view, &QTreeView::activated, this, &GameList::ValidateEntry);
connect(tree_view, &QTreeView::customContextMenuRequested, this, &GameList::PopupContextMenu);
+ connect(&watcher, &QFileSystemWatcher::directoryChanged, this, &GameList::RefreshGameDirectory);
// We must register all custom types with the Qt Automoc system so that we are able to use it
// 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) {
item_model->removeRows(0, item_model->rowCount());
emit ShouldCancelWorker();
+
+ auto watch_dirs = watcher.directories();
+ if (!watch_dirs.isEmpty()) {
+ watcher.removePaths(watch_dirs);
+ }
+ UpdateWatcherList(dir_path.toStdString(), deep_scan ? 256 : 0);
GameListWorker* worker = new GameListWorker(dir_path, deep_scan);
connect(worker, &GameListWorker::EntryReady, this, &GameList::AddEntry, Qt::QueuedConnection);
@@ -137,7 +144,46 @@ const QStringList GameList::supported_file_extensions = {"3ds", "3dsx", "elf", "
static bool HasSupportedFileExtension(const std::string& file_name) {
QFileInfo file = QFileInfo(file_name.c_str());
- return GameList::supported_file_extensions.contains(file.completeSuffix(), Qt::CaseInsensitive);
+ return GameList::supported_file_extensions.contains(file.suffix(), Qt::CaseInsensitive);
+}
+
+void GameList::RefreshGameDirectory() {
+ if (!UISettings::values.gamedir.isEmpty() && current_worker != nullptr) {
+ LOG_INFO(Frontend, "Change detected in the games directory. Reloading game list.");
+ PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan);
+ }
+}
+
+/**
+ * Adds the game list folder to the QFileSystemWatcher to check for updates.
+ *
+ * The file watcher will fire off an update to the game list when a change is detected in the game
+ * list folder.
+ *
+ * Notice: This method is run on the UI thread because QFileSystemWatcher is not thread safe and
+ * this function is fast enough to not stall the UI thread. If performance is an issue, it should
+ * be moved to another thread and properly locked to prevent concurrency issues.
+ *
+ * @param dir folder to check for changes in
+ * @param recursion 0 if recursion is disabled. Any positive number passed to this will add each
+ * directory recursively to the watcher and will update the file list if any of the folders
+ * change. The number determines how deep the recursion should traverse.
+ */
+void GameList::UpdateWatcherList(const std::string& dir, unsigned int recursion) {
+ const auto callback = [this, recursion](unsigned* num_entries_out, const std::string& directory,
+ const std::string& virtual_name) -> bool {
+ std::string physical_name = directory + DIR_SEP + virtual_name;
+
+ if (FileUtil::IsDirectory(physical_name)) {
+ UpdateWatcherList(physical_name, recursion - 1);
+ }
+ return true;
+ };
+
+ watcher.addPath(QString::fromStdString(dir));
+ if (recursion > 0) {
+ FileUtil::ForeachDirectoryEntry(nullptr, dir, callback);
+ }
}
void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsigned int recursion) {
@@ -182,6 +228,6 @@ void GameListWorker::run() {
}
void GameListWorker::Cancel() {
- disconnect(this, nullptr, nullptr, nullptr);
+ this->disconnect();
stop_processing = true;
}
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 @@
#pragma once
+#include <QFileSystemWatcher>
#include <QModelIndex>
#include <QSettings>
#include <QStandardItem>
@@ -46,8 +47,11 @@ private:
void DonePopulating();
void PopupContextMenu(const QPoint& menu_location);
+ void UpdateWatcherList(const std::string& path, unsigned int recursion);
+ void RefreshGameDirectory();
QTreeView* tree_view = nullptr;
QStandardItemModel* item_model = nullptr;
GameListWorker* current_worker = nullptr;
+ QFileSystemWatcher watcher;
};
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp
index 3c2e19344..7a80af890 100644
--- a/src/citra_qt/main.cpp
+++ b/src/citra_qt/main.cpp
@@ -54,28 +54,30 @@ Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) {
Pica::g_debug_context = Pica::DebugContext::Construct();
-
+ setAcceptDrops(true);
ui.setupUi(this);
statusBar()->hide();
InitializeWidgets();
- InitializeDebugMenuActions();
+ InitializeDebugWidgets();
InitializeRecentFileMenuActions();
InitializeHotkeys();
SetDefaultUIGeometry();
RestoreUIState();
+ ConnectMenuEvents();
ConnectWidgetEvents();
- setWindowTitle(QString("Citra | %1-%2").arg(Common::g_scm_branch, Common::g_scm_desc));
+ setWindowTitle(QString("Citra %1| %2-%3")
+ .arg(Common::g_build_name, Common::g_scm_branch, Common::g_scm_desc));
show();
game_list->PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan);
QStringList args = QApplication::arguments();
if (args.length() >= 2) {
- BootGame(args[1].toStdString());
+ BootGame(args[1]);
}
}
@@ -93,74 +95,85 @@ void GMainWindow::InitializeWidgets() {
game_list = new GameList();
ui.horizontalLayout->addWidget(game_list);
+}
+
+void GMainWindow::InitializeDebugWidgets() {
+ connect(ui.action_Create_Pica_Surface_Viewer, &QAction::triggered, this,
+ &GMainWindow::OnCreateGraphicsSurfaceViewer);
+
+ QMenu* debug_menu = ui.menu_View_Debugging;
profilerWidget = new ProfilerWidget(this);
addDockWidget(Qt::BottomDockWidgetArea, profilerWidget);
profilerWidget->hide();
+ debug_menu->addAction(profilerWidget->toggleViewAction());
#if MICROPROFILE_ENABLED
microProfileDialog = new MicroProfileDialog(this);
microProfileDialog->hide();
+ debug_menu->addAction(microProfileDialog->toggleViewAction());
#endif
disasmWidget = new DisassemblerWidget(this, emu_thread.get());
addDockWidget(Qt::BottomDockWidgetArea, disasmWidget);
disasmWidget->hide();
+ debug_menu->addAction(disasmWidget->toggleViewAction());
+ connect(this, &GMainWindow::EmulationStarting, disasmWidget,
+ &DisassemblerWidget::OnEmulationStarting);
+ connect(this, &GMainWindow::EmulationStopping, disasmWidget,
+ &DisassemblerWidget::OnEmulationStopping);
registersWidget = new RegistersWidget(this);
addDockWidget(Qt::RightDockWidgetArea, registersWidget);
registersWidget->hide();
+ debug_menu->addAction(registersWidget->toggleViewAction());
+ connect(this, &GMainWindow::EmulationStarting, registersWidget,
+ &RegistersWidget::OnEmulationStarting);
+ connect(this, &GMainWindow::EmulationStopping, registersWidget,
+ &RegistersWidget::OnEmulationStopping);
callstackWidget = new CallstackWidget(this);
addDockWidget(Qt::RightDockWidgetArea, callstackWidget);
callstackWidget->hide();
+ debug_menu->addAction(callstackWidget->toggleViewAction());
graphicsWidget = new GPUCommandStreamWidget(this);
addDockWidget(Qt::RightDockWidgetArea, graphicsWidget);
graphicsWidget->hide();
+ debug_menu->addAction(graphicsWidget->toggleViewAction());
graphicsCommandsWidget = new GPUCommandListWidget(this);
addDockWidget(Qt::RightDockWidgetArea, graphicsCommandsWidget);
graphicsCommandsWidget->hide();
+ debug_menu->addAction(graphicsCommandsWidget->toggleViewAction());
graphicsBreakpointsWidget = new GraphicsBreakPointsWidget(Pica::g_debug_context, this);
addDockWidget(Qt::RightDockWidgetArea, graphicsBreakpointsWidget);
graphicsBreakpointsWidget->hide();
+ debug_menu->addAction(graphicsBreakpointsWidget->toggleViewAction());
graphicsVertexShaderWidget = new GraphicsVertexShaderWidget(Pica::g_debug_context, this);
addDockWidget(Qt::RightDockWidgetArea, graphicsVertexShaderWidget);
graphicsVertexShaderWidget->hide();
+ debug_menu->addAction(graphicsVertexShaderWidget->toggleViewAction());
graphicsTracingWidget = new GraphicsTracingWidget(Pica::g_debug_context, this);
addDockWidget(Qt::RightDockWidgetArea, graphicsTracingWidget);
graphicsTracingWidget->hide();
+ debug_menu->addAction(graphicsTracingWidget->toggleViewAction());
+ connect(this, &GMainWindow::EmulationStarting, graphicsTracingWidget,
+ &GraphicsTracingWidget::OnEmulationStarting);
+ connect(this, &GMainWindow::EmulationStopping, graphicsTracingWidget,
+ &GraphicsTracingWidget::OnEmulationStopping);
waitTreeWidget = new WaitTreeWidget(this);
addDockWidget(Qt::LeftDockWidgetArea, waitTreeWidget);
waitTreeWidget->hide();
-}
-
-void GMainWindow::InitializeDebugMenuActions() {
- auto graphicsSurfaceViewerAction = new QAction(tr("Create Pica Surface Viewer"), this);
- connect(graphicsSurfaceViewerAction, SIGNAL(triggered()), this,
- SLOT(OnCreateGraphicsSurfaceViewer()));
-
- QMenu* debug_menu = ui.menu_View->addMenu(tr("Debugging"));
- debug_menu->addAction(graphicsSurfaceViewerAction);
- debug_menu->addSeparator();
- debug_menu->addAction(profilerWidget->toggleViewAction());
-#if MICROPROFILE_ENABLED
- debug_menu->addAction(microProfileDialog->toggleViewAction());
-#endif
- debug_menu->addAction(disasmWidget->toggleViewAction());
- debug_menu->addAction(registersWidget->toggleViewAction());
- debug_menu->addAction(callstackWidget->toggleViewAction());
- debug_menu->addAction(graphicsWidget->toggleViewAction());
- debug_menu->addAction(graphicsCommandsWidget->toggleViewAction());
- debug_menu->addAction(graphicsBreakpointsWidget->toggleViewAction());
- debug_menu->addAction(graphicsVertexShaderWidget->toggleViewAction());
- debug_menu->addAction(graphicsTracingWidget->toggleViewAction());
debug_menu->addAction(waitTreeWidget->toggleViewAction());
+ connect(this, &GMainWindow::EmulationStarting, waitTreeWidget,
+ &WaitTreeWidget::OnEmulationStarting);
+ connect(this, &GMainWindow::EmulationStopping, waitTreeWidget,
+ &WaitTreeWidget::OnEmulationStopping);
}
void GMainWindow::InitializeRecentFileMenuActions() {
@@ -215,41 +228,40 @@ void GMainWindow::RestoreUIState() {
ui.action_Single_Window_Mode->setChecked(UISettings::values.single_window_mode);
ToggleWindowMode();
- ui.actionDisplay_widget_title_bars->setChecked(UISettings::values.display_titlebar);
- OnDisplayTitleBars(ui.actionDisplay_widget_title_bars->isChecked());
+ ui.action_Display_Dock_Widget_Headers->setChecked(UISettings::values.display_titlebar);
+ OnDisplayTitleBars(ui.action_Display_Dock_Widget_Headers->isChecked());
}
void GMainWindow::ConnectWidgetEvents() {
- connect(game_list, SIGNAL(GameChosen(QString)), this, SLOT(OnGameListLoadFile(QString)),
- Qt::DirectConnection);
+ connect(game_list, SIGNAL(GameChosen(QString)), this, SLOT(OnGameListLoadFile(QString)));
connect(game_list, SIGNAL(OpenSaveFolderRequested(u64)), this,
- SLOT(OnGameListOpenSaveFolder(u64)), Qt::DirectConnection);
- connect(ui.action_Configure, SIGNAL(triggered()), this, SLOT(OnConfigure()));
- connect(ui.action_Load_File, SIGNAL(triggered()), this, SLOT(OnMenuLoadFile()),
- Qt::DirectConnection);
- connect(ui.action_Load_Symbol_Map, SIGNAL(triggered()), this, SLOT(OnMenuLoadSymbolMap()));
- connect(ui.action_Select_Game_List_Root, SIGNAL(triggered()), this,
- SLOT(OnMenuSelectGameListRoot()));
- connect(ui.action_Start, SIGNAL(triggered()), this, SLOT(OnStartGame()));
- connect(ui.action_Pause, SIGNAL(triggered()), this, SLOT(OnPauseGame()));
- connect(ui.action_Stop, SIGNAL(triggered()), this, SLOT(OnStopGame()));
- connect(ui.action_Single_Window_Mode, SIGNAL(triggered(bool)), this, SLOT(ToggleWindowMode()));
-
- connect(this, SIGNAL(EmulationStarting(EmuThread*)), disasmWidget,
- SLOT(OnEmulationStarting(EmuThread*)));
- connect(this, SIGNAL(EmulationStopping()), disasmWidget, SLOT(OnEmulationStopping()));
- connect(this, SIGNAL(EmulationStarting(EmuThread*)), registersWidget,
- SLOT(OnEmulationStarting(EmuThread*)));
- connect(this, SIGNAL(EmulationStopping()), registersWidget, SLOT(OnEmulationStopping()));
+ SLOT(OnGameListOpenSaveFolder(u64)));
+
connect(this, SIGNAL(EmulationStarting(EmuThread*)), render_window,
SLOT(OnEmulationStarting(EmuThread*)));
connect(this, SIGNAL(EmulationStopping()), render_window, SLOT(OnEmulationStopping()));
- connect(this, SIGNAL(EmulationStarting(EmuThread*)), graphicsTracingWidget,
- SLOT(OnEmulationStarting(EmuThread*)));
- connect(this, SIGNAL(EmulationStopping()), graphicsTracingWidget, SLOT(OnEmulationStopping()));
- connect(this, SIGNAL(EmulationStarting(EmuThread*)), waitTreeWidget,
- SLOT(OnEmulationStarting(EmuThread*)));
- connect(this, SIGNAL(EmulationStopping()), waitTreeWidget, SLOT(OnEmulationStopping()));
+}
+
+void GMainWindow::ConnectMenuEvents() {
+ // File
+ connect(ui.action_Load_File, &QAction::triggered, this, &GMainWindow::OnMenuLoadFile);
+ connect(ui.action_Load_Symbol_Map, &QAction::triggered, this,
+ &GMainWindow::OnMenuLoadSymbolMap);
+ connect(ui.action_Select_Game_List_Root, &QAction::triggered, this,
+ &GMainWindow::OnMenuSelectGameListRoot);
+ connect(ui.action_Exit, &QAction::triggered, this, &QMainWindow::close);
+
+ // Emulation
+ connect(ui.action_Start, &QAction::triggered, this, &GMainWindow::OnStartGame);
+ connect(ui.action_Pause, &QAction::triggered, this, &GMainWindow::OnPauseGame);
+ connect(ui.action_Stop, &QAction::triggered, this, &GMainWindow::OnStopGame);
+ connect(ui.action_Configure, &QAction::triggered, this, &GMainWindow::OnConfigure);
+
+ // View
+ connect(ui.action_Single_Window_Mode, &QAction::triggered, this,
+ &GMainWindow::ToggleWindowMode);
+ connect(ui.action_Display_Dock_Widget_Headers, &QAction::triggered, this,
+ &GMainWindow::OnDisplayTitleBars);
}
void GMainWindow::OnDisplayTitleBars(bool show) {
@@ -272,7 +284,7 @@ void GMainWindow::OnDisplayTitleBars(bool show) {
}
}
-bool GMainWindow::LoadROM(const std::string& filename) {
+bool GMainWindow::LoadROM(const QString& filename) {
// Shutdown previous session if the emu thread is still active...
if (emu_thread != nullptr)
ShutdownGame();
@@ -290,12 +302,13 @@ bool GMainWindow::LoadROM(const std::string& filename) {
Core::System& system{Core::System::GetInstance()};
- const Core::System::ResultStatus result{system.Load(render_window, filename)};
+ const Core::System::ResultStatus result{system.Load(render_window, filename.toStdString())};
if (result != Core::System::ResultStatus::Success) {
switch (result) {
case Core::System::ResultStatus::ErrorGetLoader:
- LOG_CRITICAL(Frontend, "Failed to obtain loader for %s!", filename.c_str());
+ LOG_CRITICAL(Frontend, "Failed to obtain loader for %s!",
+ filename.toStdString().c_str());
QMessageBox::critical(this, tr("Error while loading ROM!"),
tr("The ROM format is not supported."));
break;
@@ -335,7 +348,7 @@ bool GMainWindow::LoadROM(const std::string& filename) {
return true;
}
-void GMainWindow::BootGame(const std::string& filename) {
+void GMainWindow::BootGame(const QString& filename) {
LOG_INFO(Frontend, "Citra starting...");
StoreRecentFile(filename); // Put the filename on top of the list
@@ -411,8 +424,8 @@ void GMainWindow::ShutdownGame() {
emulation_running = false;
}
-void GMainWindow::StoreRecentFile(const std::string& filename) {
- UISettings::values.recent_files.prepend(QString::fromStdString(filename));
+void GMainWindow::StoreRecentFile(const QString& filename) {
+ UISettings::values.recent_files.prepend(filename);
UISettings::values.recent_files.removeDuplicates();
while (UISettings::values.recent_files.size() > max_recent_files_item) {
UISettings::values.recent_files.removeLast();
@@ -447,7 +460,7 @@ void GMainWindow::UpdateRecentFiles() {
}
void GMainWindow::OnGameListLoadFile(QString game_path) {
- BootGame(game_path.toStdString());
+ BootGame(game_path);
}
void GMainWindow::OnGameListOpenSaveFolder(u64 program_id) {
@@ -470,20 +483,21 @@ void GMainWindow::OnMenuLoadFile() {
for (const auto& piece : game_list->supported_file_extensions)
extensions += "*." + piece + " ";
- QString file_filter = tr("3DS executable") + " (" + extensions + ")";
+ QString file_filter = tr("3DS Executable") + " (" + extensions + ")";
+ file_filter += ";;" + tr("All Files (*.*)");
QString filename = QFileDialog::getOpenFileName(this, tr("Load File"),
UISettings::values.roms_path, file_filter);
if (!filename.isEmpty()) {
UISettings::values.roms_path = QFileInfo(filename).path();
- BootGame(filename.toStdString());
+ BootGame(filename);
}
}
void GMainWindow::OnMenuLoadSymbolMap() {
QString filename = QFileDialog::getOpenFileName(
- this, tr("Load Symbol Map"), UISettings::values.symbols_path, tr("Symbol map (*)"));
+ this, tr("Load Symbol Map"), UISettings::values.symbols_path, tr("Symbol Map (*.*)"));
if (!filename.isEmpty()) {
UISettings::values.symbols_path = QFileInfo(filename).path();
@@ -506,7 +520,7 @@ void GMainWindow::OnMenuRecentFile() {
QString filename = action->data().toString();
QFileInfo file_info(filename);
if (file_info.exists()) {
- BootGame(filename.toStdString());
+ BootGame(filename);
} else {
// Display an error message and remove the file from the list.
QMessageBox::information(this, tr("File not found"),
@@ -610,7 +624,7 @@ void GMainWindow::closeEvent(QCloseEvent* event) {
UISettings::values.microprofile_visible = microProfileDialog->isVisible();
#endif
UISettings::values.single_window_mode = ui.action_Single_Window_Mode->isChecked();
- UISettings::values.display_titlebar = ui.actionDisplay_widget_title_bars->isChecked();
+ UISettings::values.display_titlebar = ui.action_Display_Dock_Widget_Headers->isChecked();
UISettings::values.first_start = false;
game_list->SaveInterfaceLayout();
@@ -625,6 +639,40 @@ void GMainWindow::closeEvent(QCloseEvent* event) {
QWidget::closeEvent(event);
}
+static bool IsSingleFileDropEvent(QDropEvent* event) {
+ const QMimeData* mimeData = event->mimeData();
+ return mimeData->hasUrls() && mimeData->urls().length() == 1;
+}
+
+void GMainWindow::dropEvent(QDropEvent* event) {
+ if (IsSingleFileDropEvent(event) && ConfirmChangeGame()) {
+ const QMimeData* mimeData = event->mimeData();
+ QString filename = mimeData->urls().at(0).toLocalFile();
+ BootGame(filename);
+ }
+}
+
+void GMainWindow::dragEnterEvent(QDragEnterEvent* event) {
+ if (IsSingleFileDropEvent(event)) {
+ event->acceptProposedAction();
+ }
+}
+
+void GMainWindow::dragMoveEvent(QDragMoveEvent* event) {
+ event->acceptProposedAction();
+}
+
+bool GMainWindow::ConfirmChangeGame() {
+ if (emu_thread == nullptr)
+ return true;
+
+ auto answer = QMessageBox::question(
+ this, tr("Citra"),
+ tr("Are you sure you want to stop the emulation? Any unsaved progress will be lost."),
+ QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
+ return answer != QMessageBox::No;
+}
+
#ifdef main
#undef main
#endif
diff --git a/src/citra_qt/main.h b/src/citra_qt/main.h
index a2fd45c47..87637b92b 100644
--- a/src/citra_qt/main.h
+++ b/src/citra_qt/main.h
@@ -64,7 +64,7 @@ signals:
private:
void InitializeWidgets();
- void InitializeDebugMenuActions();
+ void InitializeDebugWidgets();
void InitializeRecentFileMenuActions();
void InitializeHotkeys();
@@ -72,15 +72,10 @@ private:
void RestoreUIState();
void ConnectWidgetEvents();
+ void ConnectMenuEvents();
- /**
- * Initializes the emulation system.
- * @param system_mode The system mode with which to intialize the kernel.
- * @returns Whether the system was properly initialized.
- */
- bool InitializeSystem(u32 system_mode);
- bool LoadROM(const std::string& filename);
- void BootGame(const std::string& filename);
+ bool LoadROM(const QString& filename);
+ void BootGame(const QString& filename);
void ShutdownGame();
/**
@@ -94,7 +89,7 @@ private:
*
* @param filename the filename to store
*/
- void StoreRecentFile(const std::string& filename);
+ void StoreRecentFile(const QString& filename);
/**
* Updates the recent files menu.
@@ -110,6 +105,7 @@ private:
* @return true if the user confirmed
*/
bool ConfirmClose();
+ bool ConfirmChangeGame();
void closeEvent(QCloseEvent* event) override;
private slots:
@@ -155,6 +151,11 @@ private:
WaitTreeWidget* waitTreeWidget;
QAction* actions_recent_files[max_recent_files_item];
+
+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/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 @@
<property name="title">
<string>&amp;View</string>
</property>
+ <widget class="QMenu" name="menu_View_Debugging">
+ <property name="title">
+ <string>Debugging</string>
+ </property>
+ <addaction name="action_Create_Pica_Surface_Viewer"/>
+ <addaction name="separator"/>
+ </widget>
<addaction name="action_Single_Window_Mode"/>
- <addaction name="actionDisplay_widget_title_bars"/>
+ <addaction name="action_Display_Dock_Widget_Headers"/>
+ <addaction name="menu_View_Debugging"/>
</widget>
<widget class="QMenu" name="menu_Help">
<property name="title">
@@ -151,7 +159,7 @@
<string>Configure...</string>
</property>
</action>
- <action name="actionDisplay_widget_title_bars">
+ <action name="action_Display_Dock_Widget_Headers">
<property name="checkable">
<bool>true</bool>
</property>
@@ -167,44 +175,11 @@
<string>Selects a folder to display in the game list</string>
</property>
</action>
+ <action name="action_Create_Pica_Surface_Viewer">
+ <property name="text">
+ <string>Create Pica Surface Viewer</string>
+ </property>
+ </action>
</widget>
<resources/>
- <connections>
- <connection>
- <sender>action_Exit</sender>
- <signal>triggered()</signal>
- <receiver>MainWindow</receiver>
- <slot>close()</slot>
- <hints>
- <hint type="sourcelabel">
- <x>-1</x>
- <y>-1</y>
- </hint>
- <hint type="destinationlabel">
- <x>367</x>
- <y>314</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>actionDisplay_widget_title_bars</sender>
- <signal>triggered(bool)</signal>
- <receiver>MainWindow</receiver>
- <slot>OnDisplayTitleBars(bool)</slot>
- <hints>
- <hint type="sourcelabel">
- <x>-1</x>
- <y>-1</y>
- </hint>
- <hint type="destinationlabel">
- <x>540</x>
- <y>364</y>
- </hint>
- </hints>
- </connection>
- </connections>
- <slots>
- <slot>OnConfigure()</slot>
- <slot>OnDisplayTitleBars(bool)</slot>
- </slots>
</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 @@
# Generate cpp with Git revision from template
+# Also if this is a CI build, add the build name (ie: Nightly, Bleeding Edge) to the scm_rev file as well
+set(REPO_NAME "")
+if ($ENV{CI})
+ if ($ENV{TRAVIS})
+ set(BUILD_REPOSITORY $ENV{TRAVIS_REPO_SLUG})
+ elseif($ENV{APPVEYOR})
+ set(BUILD_REPOSITORY $ENV{APPVEYOR_REPO_NAME})
+ endif()
+ # regex capture the string nightly or bleeding-edge into CMAKE_MATCH_1
+ string(REGEX MATCH "citra-emu/citra-?(.*)" OUTVAR ${BUILD_REPOSITORY})
+ if (${CMAKE_MATCH_COUNT} GREATER 0)
+ # capitalize the first letter of each word in the repo name.
+ string(REPLACE "-" ";" REPO_NAME_LIST ${CMAKE_MATCH_1})
+ foreach(WORD ${REPO_NAME_LIST})
+ string(SUBSTRING ${WORD} 0 1 FIRST_LETTER)
+ string(SUBSTRING ${WORD} 1 -1 REMAINDER)
+ string(TOUPPER ${FIRST_LETTER} FIRST_LETTER)
+ # this leaves a trailing space on the last word, but we actually want that
+ # because of how its styled in the title bar.
+ set(REPO_NAME "${REPO_NAME}${FIRST_LETTER}${REMAINDER} ")
+ endforeach()
+ endif()
+endif()
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scm_rev.cpp.in" "${CMAKE_CURRENT_SOURCE_DIR}/scm_rev.cpp" @ONLY)
set(SRCS
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index 0ea65e817..737e1d57f 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -55,6 +55,7 @@ namespace Log {
SUB(Service, DSP) \
SUB(Service, DLP) \
SUB(Service, HID) \
+ SUB(Service, HTTP) \
SUB(Service, SOC) \
SUB(Service, IR) \
SUB(Service, Y2R) \
diff --git a/src/common/logging/log.h b/src/common/logging/log.h
index a590d39ff..4b0f8ff03 100644
--- a/src/common/logging/log.h
+++ b/src/common/logging/log.h
@@ -72,6 +72,7 @@ enum class Class : ClassType {
Service_DSP, ///< The DSP (DSP control) service
Service_DLP, ///< The DLP (Download Play) service
Service_HID, ///< The HID (Human interface device) service
+ Service_HTTP, ///< The HTTP service
Service_SOC, ///< The SOC (Socket) service
Service_IR, ///< The IR service
Service_Y2R, ///< The Y2R (YUV to RGB conversion) service
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 @@
#define GIT_REV "@GIT_REV@"
#define GIT_BRANCH "@GIT_BRANCH@"
#define GIT_DESC "@GIT_DESC@"
+#define BUILD_NAME "@REPO_NAME@"
namespace Common {
const char g_scm_rev[] = GIT_REV;
const char g_scm_branch[] = GIT_BRANCH;
const char g_scm_desc[] = GIT_DESC;
+const char g_build_name[] = BUILD_NAME;
} // namespace
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 {
extern const char g_scm_rev[];
extern const char g_scm_branch[];
extern const char g_scm_desc[];
+extern const char g_build_name[];
} // namespace
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index da3d024bb..8334fece9 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -208,6 +208,7 @@ set(HEADERS
file_sys/archive_systemsavedata.h
file_sys/directory_backend.h
file_sys/disk_archive.h
+ file_sys/errors.h
file_sys/file_backend.h
file_sys/ivfc_archive.h
file_sys/path_parser.h
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 : {
if (inst_cream->Rn == 15) {
u32 lo = (u32)(s8)rm_val;
u32 hi = (u32)(s8)(rm_val >> 16);
- RD = (lo | (hi << 16));
+ RD = (lo & 0xFFFF) | (hi << 16);
}
// SXTAB16
else {
- u32 lo = (rn_val & 0xFFFF) + (u32)(s8)(rm_val & 0xFF);
- u32 hi = ((rn_val >> 16) & 0xFFFF) + (u32)(s8)((rm_val >> 16) & 0xFF);
- RD = (lo | (hi << 16));
+ u32 lo = rn_val + (u32)(s8)(rm_val & 0xFF);
+ u32 hi = (rn_val >> 16) + (u32)(s8)((rm_val >> 16) & 0xFF);
+ RD = (lo & 0xFFFF) | (hi << 16);
}
}
diff --git a/src/core/hle/ipc.h b/src/core/hle/ipc.h
index 4535b61c0..bbaae8b79 100644
--- a/src/core/hle/ipc.h
+++ b/src/core/hle/ipc.h
@@ -77,7 +77,7 @@ union Header {
*/
inline u32 MakeHeader(u16 command_id, unsigned int normal_params_size,
unsigned int translate_params_size) {
- Header header;
+ Header header{};
header.command_id.Assign(command_id);
header.normal_params_size.Assign(normal_params_size);
header.translate_params_size.Assign(translate_params_size);
@@ -112,7 +112,7 @@ union StaticBufferDescInfo {
};
inline u32 StaticBufferDesc(u32 size, u8 buffer_id) {
- StaticBufferDescInfo info;
+ StaticBufferDescInfo info{};
info.descriptor_type.Assign(StaticBuffer);
info.buffer_id.Assign(buffer_id);
info.size.Assign(size);
@@ -150,7 +150,7 @@ union MappedBufferDescInfo {
};
inline u32 MappedBufferDesc(u32 size, MappedBufferPermissions perms) {
- MappedBufferDescInfo info;
+ MappedBufferDescInfo info{};
info.flags.Assign(MappedBuffer);
info.perms.Assign(perms);
info.size.Assign(size);
diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp
index 60537f355..c42003e9d 100644
--- a/src/core/hle/kernel/timer.cpp
+++ b/src/core/hle/kernel/timer.cpp
@@ -52,9 +52,14 @@ void Timer::Set(s64 initial, s64 interval) {
initial_delay = initial;
interval_delay = interval;
- u64 initial_microseconds = initial / 1000;
- CoreTiming::ScheduleEvent(usToCycles(initial_microseconds), timer_callback_event_type,
- callback_handle);
+ if (initial == 0) {
+ // Immediately invoke the callback
+ Signal(0);
+ } else {
+ u64 initial_microseconds = initial / 1000;
+ CoreTiming::ScheduleEvent(usToCycles(initial_microseconds), timer_callback_event_type,
+ callback_handle);
+ }
}
void Timer::Cancel() {
@@ -72,6 +77,20 @@ void Timer::WakeupAllWaitingThreads() {
signaled = false;
}
+void Timer::Signal(int cycles_late) {
+ LOG_TRACE(Kernel, "Timer %08" PRIx64 " fired", timer_handle);
+
+ // Resume all waiting threads
+ WakeupAllWaitingThreads();
+
+ if (interval_delay != 0) {
+ // Reschedule the timer with the interval delay
+ u64 interval_microseconds = interval_delay / 1000;
+ CoreTiming::ScheduleEvent(usToCycles(interval_microseconds) - cycles_late,
+ timer_callback_event_type, callback_handle);
+ }
+}
+
/// The timer callback event, called when a timer is fired
static void TimerCallback(u64 timer_handle, int cycles_late) {
SharedPtr<Timer> timer =
@@ -82,19 +101,7 @@ static void TimerCallback(u64 timer_handle, int cycles_late) {
return;
}
- LOG_TRACE(Kernel, "Timer %08" PRIx64 " fired", timer_handle);
-
- timer->signaled = true;
-
- // Resume all waiting threads
- timer->WakeupAllWaitingThreads();
-
- if (timer->interval_delay != 0) {
- // Reschedule the timer with the interval delay
- u64 interval_microseconds = timer->interval_delay / 1000;
- CoreTiming::ScheduleEvent(usToCycles(interval_microseconds) - cycles_late,
- timer_callback_event_type, timer_handle);
- }
+ timer->Signal(cycles_late);
}
void TimersInit() {
diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h
index c174f5664..b0f818933 100644
--- a/src/core/hle/kernel/timer.h
+++ b/src/core/hle/kernel/timer.h
@@ -54,6 +54,14 @@ public:
void Cancel();
void Clear();
+ /**
+ * Signals the timer, waking up any waiting threads and rescheduling it
+ * for the next interval.
+ * This method should not be called from outside the timer callback handler,
+ * lest multiple callback events get scheduled.
+ */
+ void Signal(int cycles_late);
+
private:
Timer();
~Timer() override;
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index f14ab3811..fb3acb507 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -32,8 +32,8 @@ static u32 next_touch_index;
static u32 next_accelerometer_index;
static u32 next_gyroscope_index;
-static int enable_accelerometer_count = 0; // positive means enabled
-static int enable_gyroscope_count = 0; // positive means enabled
+static int enable_accelerometer_count; // positive means enabled
+static int enable_gyroscope_count; // positive means enabled
static int pad_update_event;
static int accelerometer_update_event;
@@ -323,6 +323,9 @@ void Init() {
next_accelerometer_index = 0;
next_gyroscope_index = 0;
+ enable_accelerometer_count = 0;
+ enable_gyroscope_count = 0;
+
// Create event handles
event_pad_or_touch_1 = Event::Create(ResetType::OneShot, "HID:EventPadOrTouch1");
event_pad_or_touch_2 = Event::Create(ResetType::OneShot, "HID:EventPadOrTouch2");
diff --git a/src/core/hle/service/ir/ir_u.cpp b/src/core/hle/service/ir/ir_u.cpp
index 429615f31..ce00d5732 100644
--- a/src/core/hle/service/ir/ir_u.cpp
+++ b/src/core/hle/service/ir/ir_u.cpp
@@ -27,7 +27,7 @@ const Interface::FunctionInfo FunctionTable[] = {
{0x00100000, nullptr, "GetErrorStatus"},
{0x00110040, nullptr, "SetSleepModeActive"},
{0x00120040, nullptr, "SetSleepModeState"},
- // clang-format off
+ // clang-format on
};
IR_U_Interface::IR_U_Interface() {
diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp
index 0be94322c..63c334cb2 100644
--- a/src/core/hle/service/nim/nim.cpp
+++ b/src/core/hle/service/nim/nim.cpp
@@ -19,7 +19,7 @@ void CheckSysUpdateAvailable(Service::Interface* self) {
cmd_buff[1] = RESULT_SUCCESS.raw;
cmd_buff[2] = 0; // No update available
- LOG_WARNING(Service_NWM, "(STUBBED) called");
+ LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void Init() {
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 96db39ad9..1baa80671 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -837,6 +837,11 @@ static ResultCode SetTimer(Kernel::Handle handle, s64 initial, s64 interval) {
LOG_TRACE(Kernel_SVC, "called timer=0x%08X", handle);
+ if (initial < 0 || interval < 0) {
+ return ResultCode(ErrorDescription::OutOfRange, ErrorModule::Kernel,
+ ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
+ }
+
SharedPtr<Timer> timer = Kernel::g_handle_table.Get<Timer>(handle);
if (timer == nullptr)
return ERR_INVALID_HANDLE;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 4b1948a71..de1d5eba7 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -1071,37 +1071,38 @@ void RasterizerOpenGL::SetShader() {
current_shader = shader_cache.emplace(config, std::move(shader)).first->second.get();
- unsigned int block_index =
- glGetUniformBlockIndex(current_shader->shader.handle, "shader_data");
- GLint block_size;
- glGetActiveUniformBlockiv(current_shader->shader.handle, block_index,
- GL_UNIFORM_BLOCK_DATA_SIZE, &block_size);
- ASSERT_MSG(block_size == sizeof(UniformData),
- "Uniform block size did not match! Got %d, expected %zu",
- static_cast<int>(block_size), sizeof(UniformData));
- glUniformBlockBinding(current_shader->shader.handle, block_index, 0);
-
- // Update uniforms
- SyncDepthScale();
- SyncDepthOffset();
- SyncAlphaTest();
- SyncCombinerColor();
- auto& tev_stages = Pica::g_state.regs.texturing.GetTevStages();
- for (int index = 0; index < tev_stages.size(); ++index)
- SyncTevConstColor(index, tev_stages[index]);
+ GLuint block_index = glGetUniformBlockIndex(current_shader->shader.handle, "shader_data");
+ if (block_index != GL_INVALID_INDEX) {
+ GLint block_size;
+ glGetActiveUniformBlockiv(current_shader->shader.handle, block_index,
+ GL_UNIFORM_BLOCK_DATA_SIZE, &block_size);
+ ASSERT_MSG(block_size == sizeof(UniformData),
+ "Uniform block size did not match! Got %d, expected %zu",
+ static_cast<int>(block_size), sizeof(UniformData));
+ glUniformBlockBinding(current_shader->shader.handle, block_index, 0);
+
+ // Update uniforms
+ SyncDepthScale();
+ SyncDepthOffset();
+ SyncAlphaTest();
+ SyncCombinerColor();
+ auto& tev_stages = Pica::g_state.regs.texturing.GetTevStages();
+ for (int index = 0; index < tev_stages.size(); ++index)
+ SyncTevConstColor(index, tev_stages[index]);
+
+ SyncGlobalAmbient();
+ for (int light_index = 0; light_index < 8; light_index++) {
+ SyncLightSpecular0(light_index);
+ SyncLightSpecular1(light_index);
+ SyncLightDiffuse(light_index);
+ SyncLightAmbient(light_index);
+ SyncLightPosition(light_index);
+ SyncLightDistanceAttenuationBias(light_index);
+ SyncLightDistanceAttenuationScale(light_index);
+ }
- SyncGlobalAmbient();
- for (int light_index = 0; light_index < 8; light_index++) {
- SyncLightSpecular0(light_index);
- SyncLightSpecular1(light_index);
- SyncLightDiffuse(light_index);
- SyncLightAmbient(light_index);
- SyncLightPosition(light_index);
- SyncLightDistanceAttenuationBias(light_index);
- SyncLightDistanceAttenuationScale(light_index);
+ SyncFogColor();
}
-
- SyncFogColor();
}
}
diff --git a/src/video_core/texture/etc1.cpp b/src/video_core/texture/etc1.cpp
index 2b7d26f91..43f7f56db 100644
--- a/src/video_core/texture/etc1.cpp
+++ b/src/video_core/texture/etc1.cpp
@@ -2,8 +2,6 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#pragma once
-
#include <array>
#include "common/bit_field.h"
#include "common/color.h"
diff --git a/src/video_core/texture/texture_decode.cpp b/src/video_core/texture/texture_decode.cpp
index 40d363184..0818d652c 100644
--- a/src/video_core/texture/texture_decode.cpp
+++ b/src/video_core/texture/texture_decode.cpp
@@ -2,8 +2,6 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-#pragma once
-
#include "common/assert.h"
#include "common/color.h"
#include "common/logging/log.h"