From ef84e19d5595dcb2b5571f3eb711285491b81ecd Mon Sep 17 00:00:00 2001
From: Giancarlo Saraceni <ghsaraceni@yahoo.com>
Date: Tue, 6 Jun 2017 02:12:02 -0700
Subject: [PATCH 01/57] Implement slider bar present on GHWT and GH5
 controllers

---
 .../Core/HW/WiimoteCommon/WiimoteReport.h     |  2 +-
 .../Core/HW/WiimoteEmu/Attachment/Guitar.cpp  | 33 +++++++++++++++++--
 .../Core/HW/WiimoteEmu/Attachment/Guitar.h    |  2 ++
 Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h   |  3 +-
 .../DolphinWX/Input/GuitarInputConfigDiag.cpp | 14 +++++---
 5 files changed, 45 insertions(+), 9 deletions(-)

diff --git a/Source/Core/Core/HW/WiimoteCommon/WiimoteReport.h b/Source/Core/Core/HW/WiimoteCommon/WiimoteReport.h
index cfcc11b102..64044046af 100644
--- a/Source/Core/Core/HW/WiimoteCommon/WiimoteReport.h
+++ b/Source/Core/Core/HW/WiimoteCommon/WiimoteReport.h
@@ -260,7 +260,7 @@ struct wm_guitar_extension
   u8 sy : 6;
   u8 pad2 : 2;  // 1 on gh3, 0 on ghwt
 
-  u8 tb : 5;    // not used in gh3
+  u8 sb : 5;    // not used in gh3
   u8 pad3 : 3;  // always 0
 
   u8 whammy : 5;
diff --git a/Source/Core/Core/HW/WiimoteEmu/Attachment/Guitar.cpp b/Source/Core/Core/HW/WiimoteEmu/Attachment/Guitar.cpp
index df06e23eac..73218cbed7 100644
--- a/Source/Core/Core/HW/WiimoteEmu/Attachment/Guitar.cpp
+++ b/Source/Core/Core/HW/WiimoteEmu/Attachment/Guitar.cpp
@@ -7,6 +7,8 @@
 #include <array>
 #include <cassert>
 
+#include <map>
+
 #include "Common/Common.h"
 #include "Common/CommonTypes.h"
 #include "Core/HW/WiimoteEmu/WiimoteEmu.h"
@@ -15,10 +17,22 @@
 #include "InputCommon/ControllerEmu/ControlGroup/AnalogStick.h"
 #include "InputCommon/ControllerEmu/ControlGroup/Buttons.h"
 #include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h"
+#include "InputCommon/ControllerEmu/ControlGroup/Slider.h"
 #include "InputCommon/ControllerEmu/ControlGroup/Triggers.h"
 
 namespace WiimoteEmu
 {
+static const std::map<const ControlState, const u8> s_slider_bar_control_codes{
+    // values determined using a PS3 Guitar Hero 5 controller, which maps the touchbar to Zr on
+    // Windows
+    {0.0, 0x0F},        // not touching
+    {-0.4375, 0x04},    // top fret
+    {-0.097656, 0x0A},  // second fret
+    {0.203125, 0x12},   // third fret
+    {0.578125, 0x17},   // fourth fret
+    {1.0, 0x1F}         // bottom fret
+};
+
 constexpr std::array<u8, 6> guitar_id{{0x00, 0x00, 0xa4, 0x20, 0x01, 0x03}};
 
 constexpr std::array<u16, 5> guitar_fret_bitmasks{{
@@ -63,6 +77,9 @@ Guitar::Guitar(ExtensionReg& reg) : Attachment(_trans("Guitar"), reg)
   groups.emplace_back(m_whammy = new ControllerEmu::Triggers(_trans("Whammy")));
   m_whammy->controls.emplace_back(new ControllerEmu::Input(_trans("Bar")));
 
+  // slider bar
+  groups.emplace_back(m_slider_bar = new ControllerEmu::Slider(_trans("Slider Bar")));
+
   // set up register
   m_id = guitar_id;
 }
@@ -83,8 +100,18 @@ void Guitar::GetState(u8* const data)
     gdata->sy = static_cast<u8>((y * 0x1F) + 0x20);
   }
 
-  // TODO: touch bar, probably not
-  gdata->tb = 0x0F;  // not touched
+  // slider bar
+  if (m_slider_bar->controls[0]->control_ref->BoundCount())
+  {
+    ControlState slider_bar;
+    m_slider_bar->GetState(&slider_bar);
+    gdata->sb = s_slider_bar_control_codes.lower_bound(slider_bar)->second;
+  }
+  else
+  {
+    // if user has not mapped controls for slider bar, tell game it's untouched
+    gdata->sb = 0x0F;
+  }
 
   // whammy bar
   ControlState whammy;
@@ -125,6 +152,8 @@ ControllerEmu::ControlGroup* Guitar::GetGroup(GuitarGroup group)
     return m_whammy;
   case GuitarGroup::Stick:
     return m_stick;
+  case GuitarGroup::SliderBar:
+    return m_slider_bar;
   default:
     assert(false);
     return nullptr;
diff --git a/Source/Core/Core/HW/WiimoteEmu/Attachment/Guitar.h b/Source/Core/Core/HW/WiimoteEmu/Attachment/Guitar.h
index 169818bff5..36fd809af8 100644
--- a/Source/Core/Core/HW/WiimoteEmu/Attachment/Guitar.h
+++ b/Source/Core/Core/HW/WiimoteEmu/Attachment/Guitar.h
@@ -12,6 +12,7 @@ class AnalogStick;
 class Buttons;
 class ControlGroup;
 class Triggers;
+class Slider;
 }
 
 namespace WiimoteEmu
@@ -48,5 +49,6 @@ private:
   ControllerEmu::Buttons* m_strum;
   ControllerEmu::Triggers* m_whammy;
   ControllerEmu::AnalogStick* m_stick;
+  ControllerEmu::Slider* m_slider_bar;
 };
 }
diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h
index c998aa7409..44ea750605 100644
--- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h
+++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h
@@ -91,7 +91,8 @@ enum class GuitarGroup
   Frets,
   Strum,
   Whammy,
-  Stick
+  Stick,
+  SliderBar
 };
 
 enum class DrumsGroup
diff --git a/Source/Core/DolphinWX/Input/GuitarInputConfigDiag.cpp b/Source/Core/DolphinWX/Input/GuitarInputConfigDiag.cpp
index aee2f5dedf..13f52fecb8 100644
--- a/Source/Core/DolphinWX/Input/GuitarInputConfigDiag.cpp
+++ b/Source/Core/DolphinWX/Input/GuitarInputConfigDiag.cpp
@@ -20,11 +20,15 @@ GuitarInputConfigDialog::GuitarInputConfigDialog(wxWindow* const parent, InputCo
       Wiimote::GetGuitarGroup(port_num, WiimoteEmu::GuitarGroup::Buttons), this, this);
   auto* const group_left_strum = new ControlGroupBox(
       Wiimote::GetGuitarGroup(port_num, WiimoteEmu::GuitarGroup::Strum), this, this);
+  auto* const group_slider_bar = new ControlGroupBox(
+      Wiimote::GetGuitarGroup(port_num, WiimoteEmu::GuitarGroup::SliderBar), this, this);
 
-  auto* const buttons_strum_sizer = new wxBoxSizer(wxVERTICAL);
-  buttons_strum_sizer->Add(group_box_buttons, 0, wxEXPAND);
-  buttons_strum_sizer->AddSpacer(space5);
-  buttons_strum_sizer->Add(group_left_strum, 0, wxEXPAND);
+  auto* const buttons_strum_slider_bar_sizer = new wxBoxSizer(wxVERTICAL);
+  buttons_strum_slider_bar_sizer->Add(group_box_buttons, 0, wxEXPAND);
+  buttons_strum_slider_bar_sizer->AddSpacer(space5);
+  buttons_strum_slider_bar_sizer->Add(group_left_strum, 0, wxEXPAND);
+  buttons_strum_slider_bar_sizer->AddSpacer(space5);
+  buttons_strum_slider_bar_sizer->Add(group_slider_bar, 0, wxEXPAND);
 
   auto* const group_box_frets = new ControlGroupBox(
       Wiimote::GetGuitarGroup(port_num, WiimoteEmu::GuitarGroup::Frets), this, this);
@@ -41,7 +45,7 @@ GuitarInputConfigDialog::GuitarInputConfigDialog(wxWindow* const parent, InputCo
 
   auto* const controls_sizer = new wxBoxSizer(wxHORIZONTAL);
   controls_sizer->AddSpacer(space5);
-  controls_sizer->Add(buttons_strum_sizer, 0, wxEXPAND);
+  controls_sizer->Add(buttons_strum_slider_bar_sizer, 0, wxEXPAND);
   controls_sizer->AddSpacer(space5);
   controls_sizer->Add(frets_whammy_sizer, 0, wxEXPAND);
   controls_sizer->AddSpacer(space5);

From 151ae38a568a518458e57ac0c72d6b15172f0462 Mon Sep 17 00:00:00 2001
From: spycrab <spycrab@users.noreply.github.com>
Date: Tue, 6 Jun 2017 13:49:49 +0200
Subject: [PATCH 02/57] Qt: Implement hotkeys (+ configuration)

---
 Source/Core/DolphinQt2/CMakeLists.txt         |   8 +
 .../DolphinQt2/Config/Mapping/Hotkey3D.cpp    |  42 ++
 .../Core/DolphinQt2/Config/Mapping/Hotkey3D.h |  25 ++
 .../Config/Mapping/HotkeyGeneral.cpp          |  47 +++
 .../DolphinQt2/Config/Mapping/HotkeyGeneral.h |  25 ++
 .../Config/Mapping/HotkeyGraphics.cpp         |  48 +++
 .../Config/Mapping/HotkeyGraphics.h           |  25 ++
 .../Config/Mapping/HotkeyStates.cpp           |  42 ++
 .../DolphinQt2/Config/Mapping/HotkeyStates.h  |  25 ++
 .../DolphinQt2/Config/Mapping/HotkeyTAS.cpp   |  42 ++
 .../DolphinQt2/Config/Mapping/HotkeyTAS.h     |  25 ++
 .../DolphinQt2/Config/Mapping/HotkeyWii.cpp   |  39 ++
 .../DolphinQt2/Config/Mapping/HotkeyWii.h     |  25 ++
 .../Config/Mapping/MappingWindow.cpp          |  18 +
 .../DolphinQt2/Config/Mapping/MappingWindow.h |   4 +-
 Source/Core/DolphinQt2/DolphinQt2.vcxproj     |  12 +
 Source/Core/DolphinQt2/HotkeyScheduler.cpp    | 363 ++++++++++++++++++
 Source/Core/DolphinQt2/HotkeyScheduler.h      |  37 ++
 Source/Core/DolphinQt2/MainWindow.cpp         |  54 ++-
 Source/Core/DolphinQt2/MainWindow.h           |   6 +
 Source/Core/DolphinQt2/MenuBar.cpp            |   8 +-
 Source/Core/DolphinQt2/MenuBar.h              |   4 +
 .../DolphinQt2/QtUtils/FocusEventFilter.cpp   |  19 +
 .../DolphinQt2/QtUtils/FocusEventFilter.h     |  18 +
 24 files changed, 958 insertions(+), 3 deletions(-)
 create mode 100644 Source/Core/DolphinQt2/Config/Mapping/Hotkey3D.cpp
 create mode 100644 Source/Core/DolphinQt2/Config/Mapping/Hotkey3D.h
 create mode 100644 Source/Core/DolphinQt2/Config/Mapping/HotkeyGeneral.cpp
 create mode 100644 Source/Core/DolphinQt2/Config/Mapping/HotkeyGeneral.h
 create mode 100644 Source/Core/DolphinQt2/Config/Mapping/HotkeyGraphics.cpp
 create mode 100644 Source/Core/DolphinQt2/Config/Mapping/HotkeyGraphics.h
 create mode 100644 Source/Core/DolphinQt2/Config/Mapping/HotkeyStates.cpp
 create mode 100644 Source/Core/DolphinQt2/Config/Mapping/HotkeyStates.h
 create mode 100644 Source/Core/DolphinQt2/Config/Mapping/HotkeyTAS.cpp
 create mode 100644 Source/Core/DolphinQt2/Config/Mapping/HotkeyTAS.h
 create mode 100644 Source/Core/DolphinQt2/Config/Mapping/HotkeyWii.cpp
 create mode 100644 Source/Core/DolphinQt2/Config/Mapping/HotkeyWii.h
 create mode 100644 Source/Core/DolphinQt2/HotkeyScheduler.cpp
 create mode 100644 Source/Core/DolphinQt2/HotkeyScheduler.h
 create mode 100644 Source/Core/DolphinQt2/QtUtils/FocusEventFilter.cpp
 create mode 100644 Source/Core/DolphinQt2/QtUtils/FocusEventFilter.h

diff --git a/Source/Core/DolphinQt2/CMakeLists.txt b/Source/Core/DolphinQt2/CMakeLists.txt
index 42a42bfaa8..e5ff552b6c 100644
--- a/Source/Core/DolphinQt2/CMakeLists.txt
+++ b/Source/Core/DolphinQt2/CMakeLists.txt
@@ -9,6 +9,7 @@ set(CMAKE_AUTOMOC ON)
 
 set(SRCS
   AboutDialog.cpp
+  HotkeyScheduler.cpp
   Host.cpp
   InDevelopmentWarning.cpp
   Main.cpp
@@ -24,6 +25,12 @@ set(SRCS
   Config/Mapping/GCKeyboardEmu.cpp
   Config/Mapping/GCPadEmu.cpp
   Config/Mapping/GCPadWiiU.cpp
+  Config/Mapping/Hotkey3D.cpp
+  Config/Mapping/HotkeyGeneral.cpp
+  Config/Mapping/HotkeyGraphics.cpp
+  Config/Mapping/HotkeyStates.cpp
+  Config/Mapping/HotkeyTAS.cpp
+  Config/Mapping/HotkeyWii.cpp
   Config/Mapping/MappingBool.cpp
   Config/Mapping/MappingButton.cpp
   Config/Mapping/MappingNumeric.cpp
@@ -41,6 +48,7 @@ set(SRCS
   GameList/ListProxyModel.cpp
   QtUtils/DoubleClickEventFilter.cpp
   QtUtils/ElidedButton.cpp
+  QtUtils/FocusEventFilter.cpp
   Settings/GeneralPane.cpp
   Settings/InterfacePane.cpp
   Settings/PathPane.cpp
diff --git a/Source/Core/DolphinQt2/Config/Mapping/Hotkey3D.cpp b/Source/Core/DolphinQt2/Config/Mapping/Hotkey3D.cpp
new file mode 100644
index 0000000000..c144d53f76
--- /dev/null
+++ b/Source/Core/DolphinQt2/Config/Mapping/Hotkey3D.cpp
@@ -0,0 +1,42 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "DolphinQt2/Config/Mapping/Hotkey3D.h"
+
+#include <QGroupBox>
+#include <QHBoxLayout>
+
+#include "Core/HotkeyManager.h"
+
+Hotkey3D::Hotkey3D(MappingWindow* window) : MappingWidget(window)
+{
+  CreateMainLayout();
+}
+
+void Hotkey3D::CreateMainLayout()
+{
+  m_main_layout = new QHBoxLayout();
+
+  m_main_layout->addWidget(
+      CreateGroupBox(tr("3D"), HotkeyManagerEmu::GetHotkeyGroup(HKGP_3D_TOGGLE)));
+  m_main_layout->addWidget(
+      CreateGroupBox(tr("3D Depth"), HotkeyManagerEmu::GetHotkeyGroup(HKGP_3D_DEPTH)));
+
+  setLayout(m_main_layout);
+}
+
+InputConfig* Hotkey3D::GetConfig()
+{
+  return HotkeyManagerEmu::GetConfig();
+}
+
+void Hotkey3D::LoadSettings()
+{
+  HotkeyManagerEmu::LoadConfig();
+}
+
+void Hotkey3D::SaveSettings()
+{
+  HotkeyManagerEmu::GetConfig()->SaveConfig();
+}
diff --git a/Source/Core/DolphinQt2/Config/Mapping/Hotkey3D.h b/Source/Core/DolphinQt2/Config/Mapping/Hotkey3D.h
new file mode 100644
index 0000000000..b7e78822f2
--- /dev/null
+++ b/Source/Core/DolphinQt2/Config/Mapping/Hotkey3D.h
@@ -0,0 +1,25 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "DolphinQt2/Config/Mapping/MappingWidget.h"
+
+class QHBoxLayout;
+
+class Hotkey3D final : public MappingWidget
+{
+public:
+  explicit Hotkey3D(MappingWindow* window);
+
+  InputConfig* GetConfig() override;
+
+private:
+  void LoadSettings() override;
+  void SaveSettings() override;
+  void CreateMainLayout();
+
+  // Main
+  QHBoxLayout* m_main_layout;
+};
diff --git a/Source/Core/DolphinQt2/Config/Mapping/HotkeyGeneral.cpp b/Source/Core/DolphinQt2/Config/Mapping/HotkeyGeneral.cpp
new file mode 100644
index 0000000000..fc111f745c
--- /dev/null
+++ b/Source/Core/DolphinQt2/Config/Mapping/HotkeyGeneral.cpp
@@ -0,0 +1,47 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "DolphinQt2/Config/Mapping/HotkeyGeneral.h"
+
+#include <QGroupBox>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+
+#include "Core/HotkeyManager.h"
+
+HotkeyGeneral::HotkeyGeneral(MappingWindow* window) : MappingWidget(window)
+{
+  CreateMainLayout();
+}
+
+void HotkeyGeneral::CreateMainLayout()
+{
+  m_main_layout = new QHBoxLayout();
+
+  m_main_layout->addWidget(
+      CreateGroupBox(tr("General"), HotkeyManagerEmu::GetHotkeyGroup(HKGP_GENERAL)));
+
+  auto* vbox = new QVBoxLayout();
+  vbox->addWidget(CreateGroupBox(tr("Volume"), HotkeyManagerEmu::GetHotkeyGroup(HKGP_VOLUME)));
+  vbox->addWidget(
+      CreateGroupBox(tr("Emulation Speed"), HotkeyManagerEmu::GetHotkeyGroup(HKGP_SPEED)));
+  m_main_layout->addItem(vbox);
+
+  setLayout(m_main_layout);
+}
+
+InputConfig* HotkeyGeneral::GetConfig()
+{
+  return HotkeyManagerEmu::GetConfig();
+}
+
+void HotkeyGeneral::LoadSettings()
+{
+  HotkeyManagerEmu::LoadConfig();
+}
+
+void HotkeyGeneral::SaveSettings()
+{
+  HotkeyManagerEmu::GetConfig()->SaveConfig();
+}
diff --git a/Source/Core/DolphinQt2/Config/Mapping/HotkeyGeneral.h b/Source/Core/DolphinQt2/Config/Mapping/HotkeyGeneral.h
new file mode 100644
index 0000000000..15c6dd04b3
--- /dev/null
+++ b/Source/Core/DolphinQt2/Config/Mapping/HotkeyGeneral.h
@@ -0,0 +1,25 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "DolphinQt2/Config/Mapping/MappingWidget.h"
+
+class QHBoxLayout;
+
+class HotkeyGeneral final : public MappingWidget
+{
+public:
+  explicit HotkeyGeneral(MappingWindow* window);
+
+  InputConfig* GetConfig() override;
+
+private:
+  void LoadSettings() override;
+  void SaveSettings() override;
+  void CreateMainLayout();
+
+  // Main
+  QHBoxLayout* m_main_layout;
+};
diff --git a/Source/Core/DolphinQt2/Config/Mapping/HotkeyGraphics.cpp b/Source/Core/DolphinQt2/Config/Mapping/HotkeyGraphics.cpp
new file mode 100644
index 0000000000..fe4cc8cdba
--- /dev/null
+++ b/Source/Core/DolphinQt2/Config/Mapping/HotkeyGraphics.cpp
@@ -0,0 +1,48 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "DolphinQt2/Config/Mapping/HotkeyGraphics.h"
+
+#include <QGroupBox>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+
+#include "Core/HotkeyManager.h"
+
+HotkeyGraphics::HotkeyGraphics(MappingWindow* window) : MappingWidget(window)
+{
+  CreateMainLayout();
+}
+
+void HotkeyGraphics::CreateMainLayout()
+{
+  m_main_layout = new QHBoxLayout();
+
+  m_main_layout->addWidget(
+      CreateGroupBox(tr("Freelook"), HotkeyManagerEmu::GetHotkeyGroup(HKGP_FREELOOK)));
+
+  auto* vbox = new QVBoxLayout();
+  vbox->addWidget(CreateGroupBox(tr("Graphics Toggles"),
+                                 HotkeyManagerEmu::GetHotkeyGroup(HKGP_GRAPHICS_TOGGLES)));
+  vbox->addWidget(
+      CreateGroupBox(tr("Internal Resolution"), HotkeyManagerEmu::GetHotkeyGroup(HKGP_IR)));
+  m_main_layout->addItem(vbox);
+
+  setLayout(m_main_layout);
+}
+
+InputConfig* HotkeyGraphics::GetConfig()
+{
+  return HotkeyManagerEmu::GetConfig();
+}
+
+void HotkeyGraphics::LoadSettings()
+{
+  HotkeyManagerEmu::LoadConfig();
+}
+
+void HotkeyGraphics::SaveSettings()
+{
+  HotkeyManagerEmu::GetConfig()->SaveConfig();
+}
diff --git a/Source/Core/DolphinQt2/Config/Mapping/HotkeyGraphics.h b/Source/Core/DolphinQt2/Config/Mapping/HotkeyGraphics.h
new file mode 100644
index 0000000000..63837202b3
--- /dev/null
+++ b/Source/Core/DolphinQt2/Config/Mapping/HotkeyGraphics.h
@@ -0,0 +1,25 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "DolphinQt2/Config/Mapping/MappingWidget.h"
+
+class QHBoxLayout;
+
+class HotkeyGraphics final : public MappingWidget
+{
+public:
+  explicit HotkeyGraphics(MappingWindow* window);
+
+  InputConfig* GetConfig() override;
+
+private:
+  void LoadSettings() override;
+  void SaveSettings() override;
+  void CreateMainLayout();
+
+  // Main
+  QHBoxLayout* m_main_layout;
+};
diff --git a/Source/Core/DolphinQt2/Config/Mapping/HotkeyStates.cpp b/Source/Core/DolphinQt2/Config/Mapping/HotkeyStates.cpp
new file mode 100644
index 0000000000..20d85cd544
--- /dev/null
+++ b/Source/Core/DolphinQt2/Config/Mapping/HotkeyStates.cpp
@@ -0,0 +1,42 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "DolphinQt2/Config/Mapping/HotkeyStates.h"
+
+#include <QGroupBox>
+#include <QHBoxLayout>
+
+#include "Core/HotkeyManager.h"
+
+HotkeyStates::HotkeyStates(MappingWindow* window) : MappingWidget(window)
+{
+  CreateMainLayout();
+}
+
+void HotkeyStates::CreateMainLayout()
+{
+  m_main_layout = new QHBoxLayout();
+
+  m_main_layout->addWidget(
+      CreateGroupBox(tr("Save"), HotkeyManagerEmu::GetHotkeyGroup(HKGP_SAVE_STATE)));
+  m_main_layout->addWidget(
+      CreateGroupBox(tr("Load"), HotkeyManagerEmu::GetHotkeyGroup(HKGP_LOAD_STATE)));
+
+  setLayout(m_main_layout);
+}
+
+InputConfig* HotkeyStates::GetConfig()
+{
+  return HotkeyManagerEmu::GetConfig();
+}
+
+void HotkeyStates::LoadSettings()
+{
+  HotkeyManagerEmu::LoadConfig();
+}
+
+void HotkeyStates::SaveSettings()
+{
+  HotkeyManagerEmu::GetConfig()->SaveConfig();
+}
diff --git a/Source/Core/DolphinQt2/Config/Mapping/HotkeyStates.h b/Source/Core/DolphinQt2/Config/Mapping/HotkeyStates.h
new file mode 100644
index 0000000000..bf36ec96f3
--- /dev/null
+++ b/Source/Core/DolphinQt2/Config/Mapping/HotkeyStates.h
@@ -0,0 +1,25 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "DolphinQt2/Config/Mapping/MappingWidget.h"
+
+class QHBoxLayout;
+
+class HotkeyStates final : public MappingWidget
+{
+public:
+  explicit HotkeyStates(MappingWindow* window);
+
+  InputConfig* GetConfig() override;
+
+private:
+  void LoadSettings() override;
+  void SaveSettings() override;
+  void CreateMainLayout();
+
+  // Main
+  QHBoxLayout* m_main_layout;
+};
diff --git a/Source/Core/DolphinQt2/Config/Mapping/HotkeyTAS.cpp b/Source/Core/DolphinQt2/Config/Mapping/HotkeyTAS.cpp
new file mode 100644
index 0000000000..2586ff2d2a
--- /dev/null
+++ b/Source/Core/DolphinQt2/Config/Mapping/HotkeyTAS.cpp
@@ -0,0 +1,42 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "DolphinQt2/Config/Mapping/HotkeyTAS.h"
+
+#include <QGroupBox>
+#include <QHBoxLayout>
+
+#include "Core/HotkeyManager.h"
+
+HotkeyTAS::HotkeyTAS(MappingWindow* window) : MappingWidget(window)
+{
+  CreateMainLayout();
+}
+
+void HotkeyTAS::CreateMainLayout()
+{
+  m_main_layout = new QHBoxLayout();
+
+  m_main_layout->addWidget(
+      CreateGroupBox(tr("Frame Advance"), HotkeyManagerEmu::GetHotkeyGroup(HKGP_FRAME_ADVANCE)));
+  m_main_layout->addWidget(
+      CreateGroupBox(tr("Movie"), HotkeyManagerEmu::GetHotkeyGroup(HKGP_MOVIE)));
+
+  setLayout(m_main_layout);
+}
+
+InputConfig* HotkeyTAS::GetConfig()
+{
+  return HotkeyManagerEmu::GetConfig();
+}
+
+void HotkeyTAS::LoadSettings()
+{
+  HotkeyManagerEmu::LoadConfig();
+}
+
+void HotkeyTAS::SaveSettings()
+{
+  HotkeyManagerEmu::GetConfig()->SaveConfig();
+}
diff --git a/Source/Core/DolphinQt2/Config/Mapping/HotkeyTAS.h b/Source/Core/DolphinQt2/Config/Mapping/HotkeyTAS.h
new file mode 100644
index 0000000000..d6fabc1294
--- /dev/null
+++ b/Source/Core/DolphinQt2/Config/Mapping/HotkeyTAS.h
@@ -0,0 +1,25 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "DolphinQt2/Config/Mapping/MappingWidget.h"
+
+class QHBoxLayout;
+
+class HotkeyTAS final : public MappingWidget
+{
+public:
+  explicit HotkeyTAS(MappingWindow* window);
+
+  InputConfig* GetConfig() override;
+
+private:
+  void LoadSettings() override;
+  void SaveSettings() override;
+  void CreateMainLayout();
+
+  // Main
+  QHBoxLayout* m_main_layout;
+};
diff --git a/Source/Core/DolphinQt2/Config/Mapping/HotkeyWii.cpp b/Source/Core/DolphinQt2/Config/Mapping/HotkeyWii.cpp
new file mode 100644
index 0000000000..7cfebf5705
--- /dev/null
+++ b/Source/Core/DolphinQt2/Config/Mapping/HotkeyWii.cpp
@@ -0,0 +1,39 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "DolphinQt2/Config/Mapping/HotkeyWii.h"
+
+#include <QGroupBox>
+#include <QHBoxLayout>
+
+#include "Core/HotkeyManager.h"
+
+HotkeyWii::HotkeyWii(MappingWindow* window) : MappingWidget(window)
+{
+  CreateMainLayout();
+}
+
+void HotkeyWii::CreateMainLayout()
+{
+  m_main_layout = new QHBoxLayout();
+
+  m_main_layout->addWidget(CreateGroupBox(tr("Wii"), HotkeyManagerEmu::GetHotkeyGroup(HKGP_WII)));
+
+  setLayout(m_main_layout);
+}
+
+InputConfig* HotkeyWii::GetConfig()
+{
+  return HotkeyManagerEmu::GetConfig();
+}
+
+void HotkeyWii::LoadSettings()
+{
+  HotkeyManagerEmu::LoadConfig();
+}
+
+void HotkeyWii::SaveSettings()
+{
+  HotkeyManagerEmu::GetConfig()->SaveConfig();
+}
diff --git a/Source/Core/DolphinQt2/Config/Mapping/HotkeyWii.h b/Source/Core/DolphinQt2/Config/Mapping/HotkeyWii.h
new file mode 100644
index 0000000000..56906e8770
--- /dev/null
+++ b/Source/Core/DolphinQt2/Config/Mapping/HotkeyWii.h
@@ -0,0 +1,25 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "DolphinQt2/Config/Mapping/MappingWidget.h"
+
+class QHBoxLayout;
+
+class HotkeyWii final : public MappingWidget
+{
+public:
+  explicit HotkeyWii(MappingWindow* window);
+
+  InputConfig* GetConfig() override;
+
+private:
+  void LoadSettings() override;
+  void SaveSettings() override;
+  void CreateMainLayout();
+
+  // Main
+  QHBoxLayout* m_main_layout;
+};
diff --git a/Source/Core/DolphinQt2/Config/Mapping/MappingWindow.cpp b/Source/Core/DolphinQt2/Config/Mapping/MappingWindow.cpp
index 04e20485b2..33e30a9b93 100644
--- a/Source/Core/DolphinQt2/Config/Mapping/MappingWindow.cpp
+++ b/Source/Core/DolphinQt2/Config/Mapping/MappingWindow.cpp
@@ -20,6 +20,12 @@
 #include "DolphinQt2/Config/Mapping/GCKeyboardEmu.h"
 #include "DolphinQt2/Config/Mapping/GCPadEmu.h"
 #include "DolphinQt2/Config/Mapping/GCPadWiiU.h"
+#include "DolphinQt2/Config/Mapping/Hotkey3D.h"
+#include "DolphinQt2/Config/Mapping/HotkeyGeneral.h"
+#include "DolphinQt2/Config/Mapping/HotkeyGraphics.h"
+#include "DolphinQt2/Config/Mapping/HotkeyStates.h"
+#include "DolphinQt2/Config/Mapping/HotkeyTAS.h"
+#include "DolphinQt2/Config/Mapping/HotkeyWii.h"
 #include "DolphinQt2/Config/Mapping/WiimoteEmuExtension.h"
 #include "DolphinQt2/Config/Mapping/WiimoteEmuGeneral.h"
 #include "DolphinQt2/Config/Mapping/WiimoteEmuMotionControl.h"
@@ -285,6 +291,18 @@ void MappingWindow::ChangeMappingType(MappingWindow::Type type)
     AddWidget(tr("Extension"), extension);
     break;
   }
+  case Type::MAPPING_HOTKEYS:
+  {
+    widget = new HotkeyGeneral(this);
+    AddWidget(tr("General"), widget);
+    AddWidget(tr("TAS Tools"), new HotkeyTAS(this));
+    AddWidget(tr("Wii (Remote)"), new HotkeyWii(this));
+    AddWidget(tr("Graphics"), new HotkeyGraphics(this));
+    AddWidget(tr("3D"), new Hotkey3D(this));
+    AddWidget(tr("Save States"), new HotkeyStates(this));
+    setWindowTitle(tr("Hotkey Settings"));
+    break;
+  }
   default:
     return;
   }
diff --git a/Source/Core/DolphinQt2/Config/Mapping/MappingWindow.h b/Source/Core/DolphinQt2/Config/Mapping/MappingWindow.h
index c181f642b3..8e6fd82d7c 100644
--- a/Source/Core/DolphinQt2/Config/Mapping/MappingWindow.h
+++ b/Source/Core/DolphinQt2/Config/Mapping/MappingWindow.h
@@ -41,7 +41,9 @@ public:
     MAPPING_GC_STEERINGWHEEL,
     // Wii
     MAPPING_WIIMOTE_EMU,
-    MAPPING_WIIMOTE_HYBRID
+    MAPPING_WIIMOTE_HYBRID,
+    // Hotkeys
+    MAPPING_HOTKEYS
   };
 
   explicit MappingWindow(QWidget* parent, int port_num);
diff --git a/Source/Core/DolphinQt2/DolphinQt2.vcxproj b/Source/Core/DolphinQt2/DolphinQt2.vcxproj
index 3e5ba69f0e..f1bce1701c 100644
--- a/Source/Core/DolphinQt2/DolphinQt2.vcxproj
+++ b/Source/Core/DolphinQt2/DolphinQt2.vcxproj
@@ -83,11 +83,13 @@
     <QtMoc Include="GameList\GameTracker.h" />
     <QtMoc Include="GameList\ListProxyModel.h" />
     <QtMoc Include="Host.h" />
+    <QtMoc Include="HotkeyScheduler.h" />
     <QtMoc Include="InDevelopmentWarning.h" />
     <QtMoc Include="Settings\InterfacePane.h" />
     <QtMoc Include="MainWindow.h" />
     <QtMoc Include="MenuBar.h" />
     <QtMoc Include="QtUtils\DoubleClickEventFilter.h" />
+    <QtMoc Include="QtUtils\FocusEventFilter.h" />
     <QtMoc Include="RenderWidget.h" />
     <QtMoc Include="Settings.h" />
     <QtMoc Include="Settings\GeneralPane.h" />
@@ -98,12 +100,14 @@
     <ClCompile Include="$(QtMocOutPrefix)AboutDialog.cpp" />
     <ClCompile Include="$(QtMocOutPrefix)ControllersWindow.cpp" />
     <ClCompile Include="$(QtMocOutPrefix)FilesystemWidget.cpp" />
+    <ClCompile Include="$(QtMocOutPrefix)FocusEventFilter.cpp" />
     <ClCompile Include="$(QtMocOutPrefix)GameFile.cpp" />
     <ClCompile Include="$(QtMocOutPrefix)GameList.cpp" />
     <ClCompile Include="$(QtMocOutPrefix)GameListModel.cpp" />
     <ClCompile Include="$(QtMocOutPrefix)GameTracker.cpp" />
     <ClCompile Include="$(QtMocOutPrefix)GeneralPane.cpp" />
     <ClCompile Include="$(QtMocOutPrefix)Host.cpp" />
+    <ClCompile Include="$(QtMocOutPrefix)HotkeyScheduler.cpp" />
     <ClCompile Include="$(QtMocOutPrefix)InDevelopmentWarning.cpp" />
     <ClCompile Include="$(QtMocOutPrefix)InfoWidget.cpp" />
     <ClCompile Include="$(QtMocOutPrefix)InterfacePane.cpp" />
@@ -125,6 +129,12 @@
     <ClCompile Include="Config\Mapping\GCKeyboardEmu.cpp" />
     <ClCompile Include="Config\Mapping\GCPadEmu.cpp" />
     <ClCompile Include="Config\Mapping\GCPadWiiU.cpp" />
+    <ClCompile Include="Config\Mapping\Hotkey3D.cpp" />
+    <ClCompile Include="Config\Mapping\HotkeyGeneral.cpp" />
+    <ClCompile Include="Config\Mapping\HotkeyGraphics.cpp" />
+    <ClCompile Include="Config\Mapping\HotkeyStates.cpp" />
+    <ClCompile Include="Config\Mapping\HotkeyTAS.cpp" />
+    <ClCompile Include="Config\Mapping\HotkeyWii.cpp" />
     <ClCompile Include="Config\Mapping\MappingBool.cpp" />
     <ClCompile Include="Config\Mapping\MappingButton.cpp" />
     <ClCompile Include="Config\Mapping\MappingNumeric.cpp" />
@@ -140,6 +150,7 @@
     <ClCompile Include="GameList\GameListModel.cpp" />
     <ClCompile Include="GameList\GameTracker.cpp" />
     <ClCompile Include="GameList\ListProxyModel.cpp" />
+    <ClCompile Include="HotkeyScheduler.cpp" />
     <ClCompile Include="Host.cpp" />
     <ClCompile Include="InDevelopmentWarning.cpp" />
     <ClCompile Include="Main.cpp" />
@@ -147,6 +158,7 @@
     <ClCompile Include="MenuBar.cpp" />
     <ClCompile Include="QtUtils\DoubleClickEventFilter.cpp" />
     <ClCompile Include="QtUtils\ElidedButton.cpp" />
+    <ClCompile Include="QtUtils\FocusEventFilter.cpp" />
     <ClCompile Include="RenderWidget.cpp" />
     <ClCompile Include="Resources.cpp" />
     <ClCompile Include="Settings.cpp" />
diff --git a/Source/Core/DolphinQt2/HotkeyScheduler.cpp b/Source/Core/DolphinQt2/HotkeyScheduler.cpp
new file mode 100644
index 0000000000..3be862f8e1
--- /dev/null
+++ b/Source/Core/DolphinQt2/HotkeyScheduler.cpp
@@ -0,0 +1,363 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "DolphinQt2/HotkeyScheduler.h"
+
+#include <algorithm>
+#include <thread>
+
+#include <QCoreApplication>
+
+#include "AudioCommon/AudioCommon.h"
+#include "Common/Thread.h"
+#include "Core/Core.h"
+#include "Core/HotkeyManager.h"
+#include "Core/IOS/IOS.h"
+#include "Core/IOS/USB/Bluetooth/BTBase.h"
+#include "Core/State.h"
+#include "DolphinQt2/MainWindow.h"
+#include "DolphinQt2/Settings.h"
+#include "InputCommon/ControllerInterface/ControllerInterface.h"
+#include "VideoCommon/VertexShaderManager.h"
+#include "VideoCommon/VideoConfig.h"
+
+constexpr const char* DUBOIS_ALGORITHM_SHADER = "dubois";
+
+HotkeyScheduler::HotkeyScheduler() : m_stop_requested(false)
+{
+  HotkeyManagerEmu::Initialize();
+  HotkeyManagerEmu::LoadConfig();
+  HotkeyManagerEmu::Enable(true);
+}
+
+HotkeyScheduler::~HotkeyScheduler()
+{
+  Stop();
+}
+
+void HotkeyScheduler::Start()
+{
+  m_stop_requested.Set(false);
+  m_thread = std::thread(&HotkeyScheduler::Run, this);
+}
+
+void HotkeyScheduler::Stop()
+{
+  m_stop_requested.Set(true);
+
+  if (m_thread.joinable())
+    m_thread.join();
+}
+
+static bool IsHotkey(int id, bool held = false)
+{
+  return HotkeyManagerEmu::IsPressed(id, held);
+}
+
+static void HandleFrameskipHotkeys()
+{
+  constexpr int MAX_FRAME_SKIP_DELAY = 60;
+  constexpr int FRAME_STEP_DELAY = 30;
+
+  static int frame_step_count = 0;
+  static int frame_step_delay = 1;
+  static int frame_step_delay_count = 0;
+  static bool frame_step_hold = false;
+
+  if (IsHotkey(HK_FRAME_ADVANCE_INCREASE_SPEED))
+  {
+    frame_step_delay = std::min(frame_step_delay + 1, MAX_FRAME_SKIP_DELAY);
+    return;
+  }
+
+  if (IsHotkey(HK_FRAME_ADVANCE_DECREASE_SPEED))
+  {
+    frame_step_delay = std::max(frame_step_delay - 1, 0);
+    return;
+  }
+
+  if (IsHotkey(HK_FRAME_ADVANCE_RESET_SPEED))
+  {
+    frame_step_delay = 1;
+    return;
+  }
+
+  if (IsHotkey(HK_FRAME_ADVANCE, true))
+  {
+    if (frame_step_delay_count < frame_step_delay && frame_step_hold)
+      frame_step_delay_count++;
+
+    // TODO GUI Update (Depends on an unimplemented feature)
+    // if ((frame_step_count == 0 || frame_step_count == FRAME_STEP_DELAY) && !frame_step_hold)
+
+    if (frame_step_count < FRAME_STEP_DELAY)
+    {
+      ++frame_step_count;
+      if (frame_step_hold)
+        frame_step_hold = false;
+    }
+
+    if (frame_step_count == FRAME_STEP_DELAY && frame_step_hold &&
+        frame_step_delay_count >= frame_step_delay)
+    {
+      frame_step_hold = false;
+      frame_step_delay_count = 0;
+    }
+
+    return;
+  }
+
+  if (frame_step_count > 0)
+  {
+    // Reset frame advance
+    frame_step_count = 0;
+    frame_step_hold = false;
+    frame_step_delay_count = 0;
+  }
+}
+
+void HotkeyScheduler::Run()
+{
+  while (!m_stop_requested.IsSet())
+  {
+    Common::SleepCurrentThread(1000 / 60);
+
+    if (!HotkeyManagerEmu::IsEnabled())
+      continue;
+
+    if (Core::GetState() == Core::State::Uninitialized || Core::GetState() == Core::State::Paused)
+      g_controller_interface.UpdateInput();
+
+    if (Core::GetState() != Core::State::Stopping)
+    {
+      HotkeyManagerEmu::GetStatus();
+
+      if (!Core::IsRunningAndStarted())
+        continue;
+
+      // Fullscreen
+      if (IsHotkey(HK_FULLSCREEN))
+        emit FullScreenHotkey();
+
+      // Pause and Unpause
+      if (IsHotkey(HK_PLAY_PAUSE))
+        emit PauseHotkey();
+
+      // Stop
+      if (IsHotkey(HK_STOP))
+        emit StopHotkey();
+
+      // Frameskipping
+      HandleFrameskipHotkeys();
+
+      // Screenshot
+      if (IsHotkey(HK_SCREENSHOT))
+        emit ScreenShotHotkey();
+
+      // Exit
+      if (IsHotkey(HK_EXIT))
+        emit ExitHotkey();
+
+      // Volume
+      if (IsHotkey(HK_VOLUME_DOWN))
+        AudioCommon::DecreaseVolume(3);
+
+      if (IsHotkey(HK_VOLUME_UP))
+        AudioCommon::IncreaseVolume(3);
+
+      if (IsHotkey(HK_VOLUME_TOGGLE_MUTE))
+        AudioCommon::ToggleMuteVolume();
+
+      auto& settings = Settings::Instance();
+
+      // Wiimote
+      if (settings.IsBluetoothPassthroughEnabled())
+      {
+        const auto ios = IOS::HLE::GetIOS();
+        auto device = ios ? ios->GetDeviceByName("/dev/usb/oh1/57e/305") : nullptr;
+
+        if (device != nullptr)
+          std::static_pointer_cast<IOS::HLE::Device::BluetoothBase>(device)->UpdateSyncButtonState(
+              IsHotkey(HK_TRIGGER_SYNC_BUTTON, true));
+      }
+
+      // TODO Debugging shortcuts (Separate PR)
+
+      if (settings.IsWiiGameRunning())
+      {
+        int wiimote_id = -1;
+        if (IsHotkey(HK_WIIMOTE1_CONNECT))
+          wiimote_id = 0;
+        if (IsHotkey(HK_WIIMOTE2_CONNECT))
+          wiimote_id = 1;
+        if (IsHotkey(HK_WIIMOTE3_CONNECT))
+          wiimote_id = 2;
+        if (IsHotkey(HK_WIIMOTE4_CONNECT))
+          wiimote_id = 3;
+        if (IsHotkey(HK_BALANCEBOARD_CONNECT))
+          wiimote_id = 4;
+
+        // TODO Implement Wiimote connecting / disconnecting (Separate PR)
+        // if (wiimote_id > -1)
+      }
+
+      // Graphics
+      if (IsHotkey(HK_INCREASE_IR))
+        ++g_Config.iEFBScale;
+      if (IsHotkey(HK_DECREASE_IR))
+        g_Config.iEFBScale = std::max(g_Config.iEFBScale - 1, static_cast<int>(SCALE_AUTO));
+      if (IsHotkey(HK_TOGGLE_CROP))
+        g_Config.bCrop = !g_Config.bCrop;
+      if (IsHotkey(HK_TOGGLE_AR))
+        g_Config.iAspectRatio = (g_Config.iAspectRatio + 1) & 3;
+      if (IsHotkey(HK_TOGGLE_EFBCOPIES))
+        g_Config.bSkipEFBCopyToRam = !g_Config.bSkipEFBCopyToRam;
+      if (IsHotkey(HK_TOGGLE_FOG))
+        g_Config.bDisableFog = !g_Config.bDisableFog;
+      if (IsHotkey(HK_TOGGLE_DUMPTEXTURES))
+        g_Config.bDumpTextures = !g_Config.bDumpTextures;
+      if (IsHotkey(HK_TOGGLE_TEXTURES))
+        g_Config.bHiresTextures = !g_Config.bHiresTextures;
+
+      Core::SetIsThrottlerTempDisabled(IsHotkey(HK_TOGGLE_THROTTLE, true));
+
+      if (IsHotkey(HK_DECREASE_EMULATION_SPEED))
+      {
+        auto speed = settings.GetEmulationSpeed() - 0.1;
+        speed = (speed <= 0 || (speed >= 0.95 && speed <= 1.05)) ? 1.0 : speed;
+        settings.SetEmulationSpeed(speed);
+      }
+
+      if (IsHotkey(HK_INCREASE_EMULATION_SPEED))
+      {
+        auto speed = settings.GetEmulationSpeed() + 0.1;
+        speed = (speed >= 0.95 && speed <= 1.05) ? 1.0 : speed;
+        settings.SetEmulationSpeed(speed);
+      }
+
+      // Slot Saving / Loading
+      if (IsHotkey(HK_SAVE_STATE_SLOT_SELECTED))
+        emit StateSaveSlotHotkey();
+
+      if (IsHotkey(HK_LOAD_STATE_SLOT_SELECTED))
+        emit StateLoadSlotHotkey();
+
+      // Stereoscopy
+      if (IsHotkey(HK_TOGGLE_STEREO_SBS) || IsHotkey(HK_TOGGLE_STEREO_TAB))
+      {
+        if (g_Config.iStereoMode != STEREO_SBS)
+        {
+          // Disable post-processing shader, as stereoscopy itself is currently a shader
+          if (g_Config.sPostProcessingShader == DUBOIS_ALGORITHM_SHADER)
+            g_Config.sPostProcessingShader = "";
+
+          g_Config.iStereoMode = IsHotkey(HK_TOGGLE_STEREO_SBS) ? STEREO_SBS : STEREO_TAB;
+        }
+        else
+        {
+          g_Config.iStereoMode = STEREO_OFF;
+        }
+      }
+
+      if (IsHotkey(HK_TOGGLE_STEREO_ANAGLYPH))
+      {
+        if (g_Config.iStereoMode != STEREO_ANAGLYPH)
+        {
+          g_Config.iStereoMode = STEREO_ANAGLYPH;
+          g_Config.sPostProcessingShader = DUBOIS_ALGORITHM_SHADER;
+        }
+        else
+        {
+          g_Config.iStereoMode = STEREO_OFF;
+          g_Config.sPostProcessingShader = "";
+        }
+      }
+
+      if (IsHotkey(HK_TOGGLE_STEREO_3DVISION))
+      {
+        if (g_Config.iStereoMode != STEREO_3DVISION)
+        {
+          if (g_Config.sPostProcessingShader == DUBOIS_ALGORITHM_SHADER)
+            g_Config.sPostProcessingShader = "";
+
+          g_Config.iStereoMode = STEREO_3DVISION;
+        }
+        else
+        {
+          g_Config.iStereoMode = STEREO_OFF;
+        }
+      }
+    }
+
+    if (IsHotkey(HK_DECREASE_DEPTH, true))
+      g_Config.iStereoDepth = std::max(g_Config.iStereoDepth - 1, 0);
+
+    if (IsHotkey(HK_INCREASE_DEPTH, true))
+      g_Config.iStereoDepth = std::min(g_Config.iStereoDepth + 1, 100);
+
+    if (IsHotkey(HK_DECREASE_CONVERGENCE, true))
+      g_Config.iStereoConvergence = std::max(g_Config.iStereoConvergence - 5, 0);
+
+    if (IsHotkey(HK_INCREASE_CONVERGENCE, true))
+      g_Config.iStereoConvergence = std::min(g_Config.iStereoConvergence + 5, 500);
+
+    // Freelook
+    static float fl_speed = 1.0;
+
+    if (IsHotkey(HK_FREELOOK_DECREASE_SPEED, true))
+      fl_speed /= 1.1f;
+
+    if (IsHotkey(HK_FREELOOK_INCREASE_SPEED, true))
+      fl_speed *= 1.1f;
+
+    if (IsHotkey(HK_FREELOOK_RESET_SPEED, true))
+      fl_speed = 1.0;
+
+    if (IsHotkey(HK_FREELOOK_UP, true))
+      VertexShaderManager::TranslateView(0.0, 0.0, -fl_speed);
+
+    if (IsHotkey(HK_FREELOOK_DOWN, true))
+      VertexShaderManager::TranslateView(0.0, 0.0, fl_speed);
+
+    if (IsHotkey(HK_FREELOOK_LEFT, true))
+      VertexShaderManager::TranslateView(fl_speed, 0.0);
+
+    if (IsHotkey(HK_FREELOOK_RIGHT, true))
+      VertexShaderManager::TranslateView(-fl_speed, 0.0);
+
+    if (IsHotkey(HK_FREELOOK_ZOOM_IN, true))
+      VertexShaderManager::TranslateView(0.0, fl_speed);
+
+    if (IsHotkey(HK_FREELOOK_ZOOM_OUT, true))
+      VertexShaderManager::TranslateView(0.0, -fl_speed);
+
+    if (IsHotkey(HK_FREELOOK_RESET, true))
+      VertexShaderManager::ResetView();
+
+    // Savestates
+    for (u32 i = 0; i < State::NUM_STATES; i++)
+    {
+      if (IsHotkey(HK_LOAD_STATE_SLOT_1 + i))
+        State::Load(i + 1);
+
+      if (IsHotkey(HK_SAVE_STATE_SLOT_1 + i))
+        State::Save(i + 1);
+
+      if (IsHotkey(HK_LOAD_LAST_STATE_1 + i))
+        State::LoadLastSaved(i + 1);
+
+      if (IsHotkey(HK_SELECT_STATE_SLOT_1 + i))
+        emit SetStateSlotHotkey(i + 1);
+    }
+
+    if (IsHotkey(HK_SAVE_FIRST_STATE))
+      State::SaveFirstSaved();
+
+    if (IsHotkey(HK_UNDO_LOAD_STATE))
+      State::UndoLoadState();
+
+    if (IsHotkey(HK_UNDO_SAVE_STATE))
+      State::UndoSaveState();
+  }
+}
diff --git a/Source/Core/DolphinQt2/HotkeyScheduler.h b/Source/Core/DolphinQt2/HotkeyScheduler.h
new file mode 100644
index 0000000000..2deebbce16
--- /dev/null
+++ b/Source/Core/DolphinQt2/HotkeyScheduler.h
@@ -0,0 +1,37 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <thread>
+
+#include <QObject>
+
+#include "Common/Flag.h"
+
+class HotkeyScheduler : public QObject
+{
+  Q_OBJECT
+public:
+  explicit HotkeyScheduler();
+  ~HotkeyScheduler();
+
+  void Start();
+  void Stop();
+signals:
+  void ExitHotkey();
+  void FullScreenHotkey();
+  void StopHotkey();
+  void PauseHotkey();
+  void ScreenShotHotkey();
+  void SetStateSlotHotkey(int slot);
+  void StateLoadSlotHotkey();
+  void StateSaveSlotHotkey();
+
+private:
+  void Run();
+
+  Common::Flag m_stop_requested;
+  std::thread m_thread;
+};
diff --git a/Source/Core/DolphinQt2/MainWindow.cpp b/Source/Core/DolphinQt2/MainWindow.cpp
index a8049826f2..a487e37b2a 100644
--- a/Source/Core/DolphinQt2/MainWindow.cpp
+++ b/Source/Core/DolphinQt2/MainWindow.cpp
@@ -24,9 +24,13 @@
 
 #include "DolphinQt2/AboutDialog.h"
 #include "DolphinQt2/Config/ControllersWindow.h"
+
+#include "DolphinQt2/Config/Mapping/MappingWindow.h"
 #include "DolphinQt2/Config/SettingsWindow.h"
 #include "DolphinQt2/Host.h"
+#include "DolphinQt2/HotkeyScheduler.h"
 #include "DolphinQt2/MainWindow.h"
+#include "DolphinQt2/QtUtils/FocusEventFilter.h"
 #include "DolphinQt2/Resources.h"
 #include "DolphinQt2/Settings.h"
 
@@ -64,16 +68,32 @@ void MainWindow::InitControllers()
   Pad::Initialize();
   Keyboard::Initialize();
   Wiimote::Initialize(Wiimote::InitializeMode::DO_NOT_WAIT_FOR_WIIMOTES);
-  HotkeyManagerEmu::Initialize();
+  m_hotkey_scheduler = new HotkeyScheduler();
+  m_hotkey_scheduler->Start();
+
+  ConnectHotkeys();
 }
 
 void MainWindow::ShutdownControllers()
 {
+  m_hotkey_scheduler->Stop();
+
   g_controller_interface.Shutdown();
   Pad::Shutdown();
   Keyboard::Shutdown();
   Wiimote::Shutdown();
   HotkeyManagerEmu::Shutdown();
+
+  m_hotkey_scheduler->deleteLater();
+}
+
+static void InstallHotkeyFilter(QDialog* dialog)
+{
+  auto* filter = new FocusEventFilter();
+  dialog->installEventFilter(filter);
+
+  filter->connect(filter, &FocusEventFilter::focusOutEvent, [] { HotkeyManagerEmu::Enable(true); });
+  filter->connect(filter, &FocusEventFilter::focusInEvent, [] { HotkeyManagerEmu::Enable(false); });
 }
 
 void MainWindow::CreateComponents()
@@ -85,6 +105,11 @@ void MainWindow::CreateComponents()
   m_stack = new QStackedWidget(this);
   m_controllers_window = new ControllersWindow(this);
   m_settings_window = new SettingsWindow(this);
+  m_hotkey_window = new MappingWindow(this, 0);
+
+  InstallHotkeyFilter(m_hotkey_window);
+  InstallHotkeyFilter(m_controllers_window);
+  InstallHotkeyFilter(m_settings_window);
 }
 
 void MainWindow::ConnectMenuBar()
@@ -113,6 +138,9 @@ void MainWindow::ConnectMenuBar()
   connect(m_menu_bar, &MenuBar::StateSaveOldest, this, &MainWindow::StateSaveOldest);
   connect(m_menu_bar, &MenuBar::SetStateSlot, this, &MainWindow::SetStateSlot);
 
+  // Options
+  connect(m_menu_bar, &MenuBar::ConfigureHotkeys, this, &MainWindow::ShowHotkeyDialog);
+
   // View
   connect(m_menu_bar, &MenuBar::ShowTable, m_game_list, &GameList::SetTableView);
   connect(m_menu_bar, &MenuBar::ShowList, m_game_list, &GameList::SetListView);
@@ -130,6 +158,22 @@ void MainWindow::ConnectMenuBar()
           [=]() { m_controllers_window->OnEmulationStateChanged(false); });
 }
 
+void MainWindow::ConnectHotkeys()
+{
+  connect(m_hotkey_scheduler, &HotkeyScheduler::ExitHotkey, this, &MainWindow::close);
+  connect(m_hotkey_scheduler, &HotkeyScheduler::PauseHotkey, this, &MainWindow::Pause);
+  connect(m_hotkey_scheduler, &HotkeyScheduler::StopHotkey, this, &MainWindow::Stop);
+  connect(m_hotkey_scheduler, &HotkeyScheduler::ScreenShotHotkey, this, &MainWindow::ScreenShot);
+  connect(m_hotkey_scheduler, &HotkeyScheduler::FullScreenHotkey, this, &MainWindow::FullScreen);
+
+  connect(m_hotkey_scheduler, &HotkeyScheduler::StateLoadSlotHotkey, this,
+          &MainWindow::StateLoadSlot);
+  connect(m_hotkey_scheduler, &HotkeyScheduler::StateSaveSlotHotkey, this,
+          &MainWindow::StateSaveSlot);
+  connect(m_hotkey_scheduler, &HotkeyScheduler::SetStateSlotHotkey, this,
+          &MainWindow::SetStateSlot);
+}
+
 void MainWindow::ConnectToolBar()
 {
   addToolBar(m_tool_bar);
@@ -364,6 +408,14 @@ void MainWindow::ShowAboutDialog()
   about->show();
 }
 
+void MainWindow::ShowHotkeyDialog()
+{
+  m_hotkey_window->ChangeMappingType(MappingWindow::Type::MAPPING_HOTKEYS);
+  m_hotkey_window->show();
+  m_hotkey_window->raise();
+  m_hotkey_window->activateWindow();
+}
+
 void MainWindow::StateLoad()
 {
   QString path = QFileDialog::getOpenFileName(this, tr("Select a File"), QDir::currentPath(),
diff --git a/Source/Core/DolphinQt2/MainWindow.h b/Source/Core/DolphinQt2/MainWindow.h
index 5e089c2572..2b9b2c4e90 100644
--- a/Source/Core/DolphinQt2/MainWindow.h
+++ b/Source/Core/DolphinQt2/MainWindow.h
@@ -14,6 +14,8 @@
 #include "DolphinQt2/RenderWidget.h"
 #include "DolphinQt2/ToolBar.h"
 
+class HotkeyScheduler;
+class MappingWindow;
 class SettingsWindow;
 class ControllersWindow;
 
@@ -58,6 +60,7 @@ private:
   void CreateComponents();
 
   void ConnectGameList();
+  void ConnectHotkeys();
   void ConnectMenuBar();
   void ConnectRenderWidget();
   void ConnectStack();
@@ -73,6 +76,7 @@ private:
   void ShowSettingsWindow();
   void ShowControllersWindow();
   void ShowAboutDialog();
+  void ShowHotkeyDialog();
 
   QStackedWidget* m_stack;
   ToolBar* m_tool_bar;
@@ -82,6 +86,8 @@ private:
   bool m_rendering_to_main;
   int m_state_slot = 1;
 
+  HotkeyScheduler* m_hotkey_scheduler;
   ControllersWindow* m_controllers_window;
   SettingsWindow* m_settings_window;
+  MappingWindow* m_hotkey_window;
 };
diff --git a/Source/Core/DolphinQt2/MenuBar.cpp b/Source/Core/DolphinQt2/MenuBar.cpp
index ef9a449621..011649e0e1 100644
--- a/Source/Core/DolphinQt2/MenuBar.cpp
+++ b/Source/Core/DolphinQt2/MenuBar.cpp
@@ -20,7 +20,7 @@ MenuBar::MenuBar(QWidget* parent) : QMenuBar(parent)
   AddFileMenu();
   AddEmulationMenu();
   addMenu(tr("Movie"));
-  addMenu(tr("Options"));
+  AddOptionsMenu();
   AddToolsMenu();
   AddViewMenu();
   AddHelpMenu();
@@ -171,6 +171,12 @@ void MenuBar::AddViewMenu()
   AddTableColumnsMenu(view_menu);
 }
 
+void MenuBar::AddOptionsMenu()
+{
+  QMenu* options_menu = addMenu(tr("Options"));
+  options_menu->addAction(tr("Hotkey Settings"), this, &MenuBar::ConfigureHotkeys);
+}
+
 void MenuBar::AddHelpMenu()
 {
   QMenu* help_menu = addMenu(tr("Help"));
diff --git a/Source/Core/DolphinQt2/MenuBar.h b/Source/Core/DolphinQt2/MenuBar.h
index fa8c67cc38..a0346f4277 100644
--- a/Source/Core/DolphinQt2/MenuBar.h
+++ b/Source/Core/DolphinQt2/MenuBar.h
@@ -38,6 +38,9 @@ signals:
   void StateSaveOldest();
   void SetStateSlot(int slot);
 
+  // Options
+  void ConfigureHotkeys();
+
   // View
   void ShowTable();
   void ShowList();
@@ -66,6 +69,7 @@ private:
   void AddGameListTypeSection(QMenu* view_menu);
   void AddTableColumnsMenu(QMenu* view_menu);
 
+  void AddOptionsMenu();
   void AddToolsMenu();
   void AddHelpMenu();
 
diff --git a/Source/Core/DolphinQt2/QtUtils/FocusEventFilter.cpp b/Source/Core/DolphinQt2/QtUtils/FocusEventFilter.cpp
new file mode 100644
index 0000000000..c6023f4ff7
--- /dev/null
+++ b/Source/Core/DolphinQt2/QtUtils/FocusEventFilter.cpp
@@ -0,0 +1,19 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include <QEvent>
+#include <QObject>
+
+#include "DolphinQt2/QtUtils/FocusEventFilter.h"
+
+bool FocusEventFilter::eventFilter(QObject* object, QEvent* event)
+{
+  if (event->type() == QEvent::FocusOut)
+    emit focusOutEvent();
+
+  if (event->type() == QEvent::FocusIn)
+    emit focusInEvent();
+
+  return false;
+}
diff --git a/Source/Core/DolphinQt2/QtUtils/FocusEventFilter.h b/Source/Core/DolphinQt2/QtUtils/FocusEventFilter.h
new file mode 100644
index 0000000000..0783622b0f
--- /dev/null
+++ b/Source/Core/DolphinQt2/QtUtils/FocusEventFilter.h
@@ -0,0 +1,18 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <QObject>
+
+class FocusEventFilter : public QObject
+{
+  Q_OBJECT
+signals:
+  void focusInEvent();
+  void focusOutEvent();
+
+private:
+  bool eventFilter(QObject* object, QEvent* event) override;
+};

From 4d2fb9b9ba857239187f3cffaa0739abac818874 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?L=C3=A9o=20Lam?= <leo@innovatetechnologi.es>
Date: Sat, 27 May 2017 12:32:45 +0200
Subject: [PATCH 03/57] Core: Replace BOOT_MIOS with an explicit "is MIOS" flag

I didn't know better back then, but the boot type is only supposed to
be used for the actual boot params. It shouldn't be used or changed
after booting.
---
 Source/Core/Core/ConfigManager.h          | 2 +-
 Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp | 4 +---
 Source/Core/Core/IOS/MIOS.cpp             | 2 +-
 Source/Core/Core/State.cpp                | 3 +--
 4 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/Source/Core/Core/ConfigManager.h b/Source/Core/Core/ConfigManager.h
index 33e6009ec6..5102d400ba 100644
--- a/Source/Core/Core/ConfigManager.h
+++ b/Source/Core/Core/ConfigManager.h
@@ -129,6 +129,7 @@ struct SConfig : NonCopyable
   bool bOverrideGCLanguage = false;
 
   bool bWii = false;
+  bool m_is_mios = false;
 
   // Interface settings
   bool bConfirmStop = false;
@@ -195,7 +196,6 @@ struct SConfig : NonCopyable
     BOOT_ELF,
     BOOT_DOL,
     BOOT_WII_NAND,
-    BOOT_MIOS,
     BOOT_BS2,
     BOOT_DFF
   };
diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp b/Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp
index a4c9c3ad1b..22544118c5 100644
--- a/Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp
+++ b/Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp
@@ -236,9 +236,7 @@ void CEXIIPL::SetCS(int _iCS)
 void CEXIIPL::UpdateRTC()
 {
   u32 epoch =
-      (SConfig::GetInstance().bWii || SConfig::GetInstance().m_BootType == SConfig::BOOT_MIOS) ?
-          WII_EPOCH :
-          GC_EPOCH;
+      (SConfig::GetInstance().bWii || SConfig::GetInstance().m_is_mios) ? WII_EPOCH : GC_EPOCH;
   u32 rtc = Common::swap32(GetEmulatedTime(epoch));
   std::memcpy(m_RTC, &rtc, sizeof(u32));
 }
diff --git a/Source/Core/Core/IOS/MIOS.cpp b/Source/Core/Core/IOS/MIOS.cpp
index ceb51f6f75..57f9451d43 100644
--- a/Source/Core/Core/IOS/MIOS.cpp
+++ b/Source/Core/Core/IOS/MIOS.cpp
@@ -168,7 +168,7 @@ bool Load()
 
   Memory::Write_U32(0x00000000, ADDRESS_INIT_SEMAPHORE);
   NOTICE_LOG(IOS, "IPL ready.");
-  SConfig::GetInstance().m_BootType = SConfig::BOOT_MIOS;
+  SConfig::GetInstance().m_is_mios = true;
   DVDInterface::UpdateRunningGameMetadata();
   return true;
 }
diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp
index a3fffacea6..01cbd1d2fe 100644
--- a/Source/Core/Core/State.cpp
+++ b/Source/Core/Core/State.cpp
@@ -156,8 +156,7 @@ static std::string DoState(PointerWrap& p)
     return version_created_by;
   }
 
-  bool is_wii =
-      SConfig::GetInstance().bWii || SConfig::GetInstance().m_BootType == SConfig::BOOT_MIOS;
+  bool is_wii = SConfig::GetInstance().bWii || SConfig::GetInstance().m_is_mios;
   const bool is_wii_currently = is_wii;
   p.Do(is_wii);
   if (is_wii != is_wii_currently)

From 22992ae41e8f979149f5a1ec895519397fce490a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?L=C3=A9o=20Lam?= <leo@innovatetechnologi.es>
Date: Sat, 27 May 2017 15:43:40 +0200
Subject: [PATCH 04/57] Boot: Clean up the boot code

* Move out boot parameters to a separate struct, which is not part
  of SConfig/ConfigManager because there is no reason for it to
  be there.

* Move out file name parsing and constructing the appropriate params
  from paths to a separate function that does that, and only that.

* For every different boot type we support, add a proper struct with
  only the required parameters, with descriptive names and use
  std::variant to only store what we need.

* Clean up the bHLE_BS2 stuff which made no sense sometimes. Now
  instead of using bHLE_BS2 for two different things, both for storing
  the user config setting and as a runtime boot parameter,
  we simply replace the Disc boot params with BootParameters::IPL.

* Const correctness so it's clear what can or cannot update the config.

* Drop unused parameters and unneeded checks.

* Make a few checks a lot more concise. (Looking at you, extension
  checks for disc images.)

* Remove a mildly terrible workaround where we needed to pass an empty
  string in order to boot the GC IPL without any game inserted.
  (Not required anymore thanks to std::variant and std::optional.)

The motivation for this are multiple: cleaning up and being able to add
support for booting an installed NAND title. Without this change, it'd
be pretty much impossible to implement that.

Also, using std::visit with std::variant makes the compiler do
additional type checks: now we're guaranteed that the boot code will
handle all boot types and no invalid boot type will be possible.
---
 Source/Android/jni/MainAndroid.cpp        |   3 +-
 Source/Core/Core/Boot/Boot.cpp            | 431 ++++++++++++----------
 Source/Core/Core/Boot/Boot.h              |  59 ++-
 Source/Core/Core/Boot/Boot_WiiWAD.cpp     |   8 +
 Source/Core/Core/BootManager.cpp          |  26 +-
 Source/Core/Core/BootManager.h            |   5 +-
 Source/Core/Core/ConfigManager.cpp        | 231 ++++--------
 Source/Core/Core/ConfigManager.h          |  28 +-
 Source/Core/Core/Core.cpp                 |  48 ++-
 Source/Core/Core/Core.h                   |   5 +-
 Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp |   3 +-
 Source/Core/Core/IOS/ES/Views.cpp         |   2 +-
 Source/Core/Core/Movie.cpp                |  28 +-
 Source/Core/Core/Movie.h                  |   6 +-
 Source/Core/DolphinNoGUI/MainNoGUI.cpp    |   3 +-
 Source/Core/DolphinQt2/MainWindow.cpp     |   3 +-
 Source/Core/DolphinWX/Frame.h             |   5 +-
 Source/Core/DolphinWX/FrameTools.cpp      |  14 +-
 18 files changed, 468 insertions(+), 440 deletions(-)

diff --git a/Source/Android/jni/MainAndroid.cpp b/Source/Android/jni/MainAndroid.cpp
index 9d3dff94c4..350b78b361 100644
--- a/Source/Android/jni/MainAndroid.cpp
+++ b/Source/Android/jni/MainAndroid.cpp
@@ -25,6 +25,7 @@
 #include "Common/Logging/LogManager.h"
 #include "Common/MsgHandler.h"
 
+#include "Core/Boot/Boot.h"
 #include "Core/BootManager.h"
 #include "Core/ConfigManager.h"
 #include "Core/Core.h"
@@ -794,7 +795,7 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run(JNIEnv*
 
   // No use running the loop when booting fails
   s_have_wm_user_stop = false;
-  if (BootManager::BootCore(s_filename.c_str(), SConfig::BOOT_DEFAULT))
+  if (BootManager::BootCore(BootParameters::GenerateFromFile(s_filename)))
   {
     static constexpr int TIMEOUT = 10000;
     static constexpr int WAIT_STEP = 25;
diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp
index 9ca576721b..43296eb784 100644
--- a/Source/Core/Core/Boot/Boot.cpp
+++ b/Source/Core/Core/Boot/Boot.cpp
@@ -4,13 +4,16 @@
 
 #include "Core/Boot/Boot.h"
 
+#include <algorithm>
 #include <optional>
 #include <string>
+#include <unordered_set>
 #include <vector>
 
 #include <zlib.h>
 
 #include "Common/Align.h"
+#include "Common/CDUtils.h"
 #include "Common/CommonPaths.h"
 #include "Common/CommonTypes.h"
 #include "Common/FileUtil.h"
@@ -22,6 +25,7 @@
 #include "Core/ConfigManager.h"
 #include "Core/Core.h"
 #include "Core/Debugger/Debugger_SymbolMap.h"
+#include "Core/FifoPlayer/FifoPlayer.h"
 #include "Core/HLE/HLE.h"
 #include "Core/HW/DVD/DVDInterface.h"
 #include "Core/HW/EXI/EXI_DeviceIPL.h"
@@ -39,6 +43,76 @@
 #include "DiscIO/NANDContentLoader.h"
 #include "DiscIO/Volume.h"
 
+BootParameters::BootParameters(Parameters&& parameters_) : parameters(std::move(parameters_))
+{
+}
+
+std::unique_ptr<BootParameters> BootParameters::GenerateFromFile(const std::string& path)
+{
+  const bool is_drive = cdio_is_cdrom(path);
+  // Check if the file exist, we may have gotten it from a --elf command line
+  // that gave an incorrect file name
+  if (!is_drive && !File::Exists(path))
+  {
+    PanicAlertT("The specified file \"%s\" does not exist", path.c_str());
+    return {};
+  }
+
+  std::string extension;
+  SplitPath(path, nullptr, nullptr, &extension);
+  std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
+
+  static const std::unordered_set<std::string> disc_image_extensions = {
+      {".gcm", ".iso", ".tgc", ".wbfs", ".ciso", ".gcz"}};
+  if (disc_image_extensions.find(extension) != disc_image_extensions.end() || is_drive)
+  {
+    auto volume = DiscIO::CreateVolumeFromFilename(path);
+    if (!volume)
+    {
+      if (is_drive)
+      {
+        PanicAlertT("Could not read \"%s\". "
+                    "There is no disc in the drive or it is not a GameCube/Wii backup. "
+                    "Please note that Dolphin cannot play games directly from the original "
+                    "GameCube and Wii discs.",
+                    path.c_str());
+      }
+      else
+      {
+        PanicAlertT("\"%s\" is an invalid GCM/ISO file, or is not a GC/Wii ISO.", path.c_str());
+      }
+      return {};
+    }
+    return std::make_unique<BootParameters>(Disc{path, std::move(volume)});
+  }
+
+  if (extension == ".elf" || extension == ".dol")
+  {
+    return std::make_unique<BootParameters>(
+        Executable{path, extension == ".elf" ? Executable::Type::ELF : Executable::Type::DOL});
+  }
+
+  if (extension == ".dff")
+    return std::make_unique<BootParameters>(DFF{path});
+
+  if (DiscIO::NANDContentManager::Access().GetNANDLoader(path).IsValid())
+    return std::make_unique<BootParameters>(NAND{path});
+
+  PanicAlertT("Could not recognize file %s", path.c_str());
+  return {};
+}
+
+BootParameters::IPL::IPL(DiscIO::Region region_) : region(region_)
+{
+  const std::string directory = SConfig::GetInstance().GetDirectoryForRegion(region);
+  path = SConfig::GetInstance().GetBootROMPath(directory);
+}
+
+BootParameters::IPL::IPL(DiscIO::Region region_, Disc&& disc_) : IPL(region_)
+{
+  disc = std::move(disc_);
+}
+
 // Inserts a disc into the emulated disc drive and returns a pointer to it.
 // The returned pointer must only be used while we are still booting,
 // because DVDThread can do whatever it wants to the disc after that.
@@ -102,57 +176,24 @@ void CBoot::UpdateDebugger_MapLoaded()
   Host_NotifyMapLoaded();
 }
 
+// Get map file paths for the active title.
 bool CBoot::FindMapFile(std::string* existing_map_file, std::string* writable_map_file,
                         std::string* title_id)
 {
-  std::string title_id_str;
-  size_t name_begin_index;
-
-  SConfig& _StartupPara = SConfig::GetInstance();
-  switch (_StartupPara.m_BootType)
-  {
-  case SConfig::BOOT_WII_NAND:
-  {
-    const DiscIO::NANDContentLoader& Loader =
-        DiscIO::NANDContentManager::Access().GetNANDLoader(_StartupPara.m_strFilename);
-    if (Loader.IsValid())
-    {
-      u64 TitleID = Loader.GetTMD().GetTitleId();
-      title_id_str = StringFromFormat("%08X_%08X", (u32)(TitleID >> 32) & 0xFFFFFFFF,
-                                      (u32)TitleID & 0xFFFFFFFF);
-    }
-    break;
-  }
-
-  case SConfig::BOOT_ELF:
-  case SConfig::BOOT_DOL:
-    // Strip the .elf/.dol file extension and directories before the name
-    name_begin_index = _StartupPara.m_strFilename.find_last_of("/") + 1;
-    if ((_StartupPara.m_strFilename.find_last_of("\\") + 1) > name_begin_index)
-    {
-      name_begin_index = _StartupPara.m_strFilename.find_last_of("\\") + 1;
-    }
-    title_id_str = _StartupPara.m_strFilename.substr(
-        name_begin_index, _StartupPara.m_strFilename.size() - 4 - name_begin_index);
-    break;
-
-  default:
-    title_id_str = _StartupPara.GetGameID();
-    break;
-  }
+  const std::string game_id = SConfig::GetInstance().GetGameID();
 
   if (writable_map_file)
-    *writable_map_file = File::GetUserPath(D_MAPS_IDX) + title_id_str + ".map";
+    *writable_map_file = File::GetUserPath(D_MAPS_IDX) + game_id + ".map";
 
   if (title_id)
-    *title_id = title_id_str;
+    *title_id = game_id;
 
   bool found = false;
   static const std::string maps_directories[] = {File::GetUserPath(D_MAPS_IDX),
                                                  File::GetSysDirectory() + MAPS_DIR DIR_SEP};
   for (size_t i = 0; !found && i < ArraySize(maps_directories); ++i)
   {
-    std::string path = maps_directories[i] + title_id_str + ".map";
+    std::string path = maps_directories[i] + game_id + ".map";
     if (File::Exists(path))
     {
       found = true;
@@ -270,199 +311,187 @@ bool CBoot::Load_BS2(const std::string& boot_rom_filename)
   return true;
 }
 
-// Third boot step after BootManager and Core. See Call schedule in BootManager.cpp
-bool CBoot::BootUp()
+static const DiscIO::Volume* SetDefaultDisc()
 {
-  SConfig& _StartupPara = SConfig::GetInstance();
+  const SConfig& config = SConfig::GetInstance();
+  // load default image or create virtual drive from directory
+  if (!config.m_strDVDRoot.empty())
+    return SetDisc(DiscIO::CreateVolumeFromDirectory(config.m_strDVDRoot, config.bWii));
+  if (!config.m_strDefaultISO.empty())
+    return SetDisc(DiscIO::CreateVolumeFromFilename(config.m_strDefaultISO));
+  return nullptr;
+}
 
-  if (_StartupPara.m_BootType == SConfig::BOOT_BS2)
-    NOTICE_LOG(BOOT, "Booting %s", _StartupPara.m_strBootROM.c_str());
-  else
-    NOTICE_LOG(BOOT, "Booting %s", _StartupPara.m_strFilename.c_str());
+// Third boot step after BootManager and Core. See Call schedule in BootManager.cpp
+bool CBoot::BootUp(std::unique_ptr<BootParameters> boot)
+{
+  SConfig& config = SConfig::GetInstance();
 
   g_symbolDB.Clear();
 
   // PAL Wii uses NTSC framerate and linecount in 60Hz modes
-  VideoInterface::Preset(DiscIO::IsNTSC(_StartupPara.m_region) ||
-                         (_StartupPara.bWii && _StartupPara.bPAL60));
+  VideoInterface::Preset(DiscIO::IsNTSC(config.m_region) || (config.bWii && config.bPAL60));
 
-  switch (_StartupPara.m_BootType)
+  struct BootTitle
   {
-  case SConfig::BOOT_ISO:
-  {
-    const DiscIO::Volume* volume =
-        SetDisc(DiscIO::CreateVolumeFromFilename(_StartupPara.m_strFilename));
-
-    if (!volume)
-      return false;
-
-    if ((volume->GetVolumeType() == DiscIO::Platform::WII_DISC) != _StartupPara.bWii)
+    BootTitle() : config(SConfig::GetInstance()) {}
+    bool operator()(const BootParameters::Disc& disc) const
     {
-      PanicAlertT("Warning - starting ISO in wrong console mode!");
-    }
+      NOTICE_LOG(BOOT, "Booting from disc: %s", disc.path.c_str());
+      const DiscIO::Volume* volume = SetDisc(DiscIO::CreateVolumeFromFilename(disc.path));
 
-    _StartupPara.bWii = volume->GetVolumeType() == DiscIO::Platform::WII_DISC;
+      if (!volume)
+        return false;
 
-    // We HLE the bootrom if requested or if LLEing it fails
-    if (_StartupPara.bHLE_BS2 || !Load_BS2(_StartupPara.m_strBootROM))
-      EmulatedBS2(_StartupPara.bWii, volume);
+      if (!EmulatedBS2(config.bWii, volume))
+        return false;
 
-    PatchEngine::LoadPatches();
-
-    // Scan for common HLE functions
-    if (_StartupPara.bHLE_BS2 && !_StartupPara.bEnableDebugging)
-    {
-      PPCAnalyst::FindFunctions(0x80004000, 0x811fffff, &g_symbolDB);
-      SignatureDB db(SignatureDB::HandlerType::DSY);
-      if (db.Load(File::GetSysDirectory() + TOTALDB))
+      // Scan for common HLE functions
+      if (!config.bEnableDebugging)
       {
-        db.Apply(&g_symbolDB);
-        HLE::PatchFunctions();
-        db.Clear();
+        PPCAnalyst::FindFunctions(0x80004000, 0x811fffff, &g_symbolDB);
+        SignatureDB db(SignatureDB::HandlerType::DSY);
+        if (db.Load(File::GetSysDirectory() + TOTALDB))
+        {
+          db.Apply(&g_symbolDB);
+          HLE::PatchFunctions();
+          db.Clear();
+        }
       }
+
+      // Try to load the symbol map if there is one, and then scan it for
+      // and eventually replace code
+      if (LoadMapFromFilename())
+        HLE::PatchFunctions();
+
+      return true;
     }
 
-    // Try to load the symbol map if there is one, and then scan it for
-    // and eventually replace code
-    if (LoadMapFromFilename())
-      HLE::PatchFunctions();
-
-    break;
-  }
-
-  case SConfig::BOOT_DOL:
-  {
-    CDolLoader dolLoader(_StartupPara.m_strFilename);
-    if (!dolLoader.IsValid())
-      return false;
-
-    // Check if we have gotten a Wii file or not
-    bool dolWii = dolLoader.IsWii();
-    if (dolWii != _StartupPara.bWii)
+    bool operator()(const BootParameters::Executable& executable) const
     {
-      PanicAlertT("Warning - starting DOL in wrong console mode!");
+      NOTICE_LOG(BOOT, "Booting from executable: %s", executable.path.c_str());
+
+      // TODO: needs more cleanup.
+      if (executable.type == BootParameters::Executable::Type::DOL)
+      {
+        CDolLoader dolLoader(executable.path);
+        if (!dolLoader.IsValid())
+          return false;
+
+        const DiscIO::Volume* volume = nullptr;
+        if (!config.m_strDVDRoot.empty())
+        {
+          NOTICE_LOG(BOOT, "Setting DVDRoot %s", config.m_strDVDRoot.c_str());
+          volume = SetDisc(DiscIO::CreateVolumeFromDirectory(
+              config.m_strDVDRoot, config.bWii, config.m_strApploader, executable.path));
+        }
+        else if (!config.m_strDefaultISO.empty())
+        {
+          NOTICE_LOG(BOOT, "Loading default ISO %s", config.m_strDefaultISO.c_str());
+          volume = SetDisc(DiscIO::CreateVolumeFromFilename(config.m_strDefaultISO));
+        }
+
+        // Poor man's bootup
+        if (config.bWii)
+        {
+          HID4.SBE = 1;
+          SetupMSR();
+          SetupBAT(config.bWii);
+
+          // Because there is no TMD to get the requested system (IOS) version from,
+          // we default to IOS58, which is the version used by the Homebrew Channel.
+          SetupWiiMemory(volume, 0x000000010000003a);
+        }
+        else
+        {
+          EmulatedBS2_GC(volume, true);
+        }
+
+        Load_FST(config.bWii, volume);
+        dolLoader.Load();
+        PC = dolLoader.GetEntryPoint();
+
+        if (LoadMapFromFilename())
+          HLE::PatchFunctions();
+      }
+
+      if (executable.type == BootParameters::Executable::Type::ELF)
+      {
+        const DiscIO::Volume* volume = SetDefaultDisc();
+
+        // Poor man's bootup
+        if (config.bWii)
+        {
+          // Because there is no TMD to get the requested system (IOS) version from,
+          // we default to IOS58, which is the version used by the Homebrew Channel.
+          SetupWiiMemory(volume, 0x000000010000003a);
+        }
+        else
+        {
+          EmulatedBS2_GC(volume, true);
+        }
+
+        Load_FST(config.bWii, volume);
+        if (!Boot_ELF(executable.path))
+          return false;
+
+        // Note: Boot_ELF calls HLE::PatchFunctions()
+
+        UpdateDebugger_MapLoaded();
+        Dolphin_Debugger::AddAutoBreakpoints();
+      }
+
+      return true;
     }
 
-    const DiscIO::Volume* volume = nullptr;
-    if (!_StartupPara.m_strDVDRoot.empty())
+    bool operator()(const BootParameters::NAND& nand) const
     {
-      NOTICE_LOG(BOOT, "Setting DVDRoot %s", _StartupPara.m_strDVDRoot.c_str());
-      volume = SetDisc(DiscIO::CreateVolumeFromDirectory(_StartupPara.m_strDVDRoot, dolWii,
-                                                         _StartupPara.m_strApploader,
-                                                         _StartupPara.m_strFilename));
+      NOTICE_LOG(BOOT, "Booting from NAND: %s", nand.content_path.c_str());
+      SetDefaultDisc();
+      return Boot_WiiWAD(nand.content_path);
     }
-    else if (!_StartupPara.m_strDefaultISO.empty())
+
+    bool operator()(const BootParameters::IPL& ipl) const
     {
-      NOTICE_LOG(BOOT, "Loading default ISO %s", _StartupPara.m_strDefaultISO.c_str());
-      volume = SetDisc(DiscIO::CreateVolumeFromFilename(_StartupPara.m_strDefaultISO));
+      NOTICE_LOG(BOOT, "Booting GC IPL: %s", ipl.path.c_str());
+      if (!File::Exists(ipl.path))
+      {
+        if (ipl.disc)
+          PanicAlertT("Cannot start the game, because the GC IPL could not be found.");
+        else
+          PanicAlertT("Cannot find the GC IPL.");
+        return false;
+      }
+
+      if (!Load_BS2(ipl.path))
+        return false;
+
+      if (ipl.disc)
+      {
+        NOTICE_LOG(BOOT, "Inserting disc: %s", ipl.disc->path.c_str());
+        SetDisc(DiscIO::CreateVolumeFromFilename(ipl.disc->path));
+      }
+
+      if (LoadMapFromFilename())
+        HLE::PatchFunctions();
+
+      return true;
     }
 
-    // Poor man's bootup
-    if (dolWii)
+    bool operator()(const BootParameters::DFF& dff) const
     {
-      HID4.SBE = 1;
-      SetupMSR();
-      SetupBAT(dolWii);
-
-      // Because there is no TMD to get the requested system (IOS) version from,
-      // we default to IOS58, which is the version used by the Homebrew Channel.
-      SetupWiiMemory(volume, 0x000000010000003a);
-    }
-    else
-    {
-      EmulatedBS2_GC(volume, true);
+      NOTICE_LOG(BOOT, "Booting DFF: %s", dff.dff_path.c_str());
+      return FifoPlayer::GetInstance().Open(dff.dff_path);
     }
 
-    Load_FST(dolWii, volume);
-    dolLoader.Load();
-    PC = dolLoader.GetEntryPoint();
+  private:
+    const SConfig& config;
+  };
 
-    if (LoadMapFromFilename())
-      HLE::PatchFunctions();
-
-    break;
-  }
-
-  case SConfig::BOOT_ELF:
-  {
-    const DiscIO::Volume* volume = nullptr;
-
-    // load image or create virtual drive from directory
-    if (!_StartupPara.m_strDVDRoot.empty())
-    {
-      NOTICE_LOG(BOOT, "Setting DVDRoot %s", _StartupPara.m_strDVDRoot.c_str());
-      volume =
-          SetDisc(DiscIO::CreateVolumeFromDirectory(_StartupPara.m_strDVDRoot, _StartupPara.bWii));
-    }
-    else if (!_StartupPara.m_strDefaultISO.empty())
-    {
-      NOTICE_LOG(BOOT, "Loading default ISO %s", _StartupPara.m_strDefaultISO.c_str());
-      volume = SetDisc(DiscIO::CreateVolumeFromFilename(_StartupPara.m_strDefaultISO));
-    }
-
-    // Poor man's bootup
-    if (_StartupPara.bWii)
-    {
-      // Because there is no TMD to get the requested system (IOS) version from,
-      // we default to IOS58, which is the version used by the Homebrew Channel.
-      SetupWiiMemory(volume, 0x000000010000003a);
-    }
-    else
-    {
-      EmulatedBS2_GC(volume, true);
-    }
-
-    Load_FST(_StartupPara.bWii, volume);
-    if (!Boot_ELF(_StartupPara.m_strFilename))
-      return false;
-
-    // Note: Boot_ELF calls HLE::PatchFunctions()
-
-    UpdateDebugger_MapLoaded();
-    Dolphin_Debugger::AddAutoBreakpoints();
-    break;
-  }
-
-  case SConfig::BOOT_WII_NAND:
-    Boot_WiiWAD(_StartupPara.m_strFilename);
-
-    PatchEngine::LoadPatches();
-
-    // Not bootstrapped yet, can't translate memory addresses. Thus, prevents Symbol Map usage.
-    // if (LoadMapFromFilename())
-    //   HLE::PatchFunctions();
-
-    // load default image or create virtual drive from directory
-    if (!_StartupPara.m_strDVDRoot.empty())
-      SetDisc(DiscIO::CreateVolumeFromDirectory(_StartupPara.m_strDVDRoot, true));
-    else if (!_StartupPara.m_strDefaultISO.empty())
-      SetDisc(DiscIO::CreateVolumeFromFilename(_StartupPara.m_strDefaultISO));
-
-    break;
-
-  // Bootstrap 2 (AKA: Initial Program Loader, "BIOS")
-  case SConfig::BOOT_BS2:
-  {
-    if (!Load_BS2(_StartupPara.m_strBootROM))
-      return false;
-
-    if (LoadMapFromFilename())
-      HLE::PatchFunctions();
-
-    break;
-  }
-
-  case SConfig::BOOT_DFF:
-    // do nothing
-    break;
-
-  default:
-  {
-    PanicAlertT("Tried to load an unknown file type.");
+  if (!std::visit(BootTitle(), boot->parameters))
     return false;
-  }
-  }
 
+  PatchEngine::LoadPatches();
   HLE::PatchFixedFunctions();
   return true;
 }
diff --git a/Source/Core/Core/Boot/Boot.h b/Source/Core/Core/Boot/Boot.h
index 42c71b199f..742bb056e5 100644
--- a/Source/Core/Core/Boot/Boot.h
+++ b/Source/Core/Core/Boot/Boot.h
@@ -5,15 +5,13 @@
 #pragma once
 
 #include <cstdlib>
+#include <optional>
 #include <string>
+#include <variant>
 
 #include "Common/CommonTypes.h"
-
-namespace DiscIO
-{
-class Volume;
-struct Partition;
-}
+#include "DiscIO/Enums.h"
+#include "DiscIO/Volume.h"
 
 struct RegionSetting
 {
@@ -23,10 +21,57 @@ struct RegionSetting
   const std::string code;
 };
 
+struct BootParameters
+{
+  struct Disc
+  {
+    std::string path;
+    std::unique_ptr<DiscIO::Volume> volume;
+  };
+
+  struct Executable
+  {
+    enum class Type
+    {
+      DOL,
+      ELF,
+    };
+    std::string path;
+    Type type;
+  };
+
+  struct NAND
+  {
+    std::string content_path;
+  };
+
+  struct IPL
+  {
+    explicit IPL(DiscIO::Region region_);
+    IPL(DiscIO::Region region_, Disc&& disc_);
+    std::string path;
+    DiscIO::Region region;
+    // It is possible to boot the IPL with a disc inserted (with "skip IPL" disabled).
+    std::optional<Disc> disc;
+  };
+
+  struct DFF
+  {
+    std::string dff_path;
+  };
+
+  static std::unique_ptr<BootParameters> GenerateFromFile(const std::string& path);
+
+  using Parameters = std::variant<Disc, Executable, NAND, IPL, DFF>;
+  BootParameters(Parameters&& parameters_);
+
+  Parameters parameters;
+};
+
 class CBoot
 {
 public:
-  static bool BootUp();
+  static bool BootUp(std::unique_ptr<BootParameters> boot);
   static bool IsElfWii(const std::string& filename);
 
   // Tries to find a map file for the current game by looking first in the
diff --git a/Source/Core/Core/Boot/Boot_WiiWAD.cpp b/Source/Core/Core/Boot/Boot_WiiWAD.cpp
index 54501a1638..889496ccb2 100644
--- a/Source/Core/Core/Boot/Boot_WiiWAD.cpp
+++ b/Source/Core/Core/Boot/Boot_WiiWAD.cpp
@@ -11,6 +11,7 @@
 #include "Common/CommonPaths.h"
 #include "Common/CommonTypes.h"
 #include "Common/FileUtil.h"
+#include "Common/MsgHandler.h"
 #include "Common/NandPaths.h"
 
 #include "Core/Boot/Boot.h"
@@ -78,6 +79,13 @@ bool CBoot::Boot_WiiWAD(const std::string& _pFilename)
     return false;
 
   u64 titleID = ContentLoader.GetTMD().GetTitleId();
+
+  if (!IOS::ES::IsChannel(titleID))
+  {
+    PanicAlertT("This WAD is not bootable.");
+    return false;
+  }
+
   // create data directory
   File::CreateFullPath(Common::GetTitleDataPath(titleID, Common::FROM_SESSION_ROOT));
 
diff --git a/Source/Core/Core/BootManager.cpp b/Source/Core/Core/BootManager.cpp
index 6262fd94dd..7738e0897c 100644
--- a/Source/Core/Core/BootManager.cpp
+++ b/Source/Core/Core/BootManager.cpp
@@ -31,6 +31,7 @@
 #include "Common/MsgHandler.h"
 #include "Common/StringUtil.h"
 
+#include "Core/Boot/Boot.h"
 #include "Core/Config/Config.h"
 #include "Core/ConfigLoaders/GameConfigLoader.h"
 #include "Core/ConfigLoaders/NetPlayConfigLoader.h"
@@ -222,23 +223,23 @@ static GPUDeterminismMode ParseGPUDeterminismMode(const std::string& mode)
 }
 
 // Boot the ISO or file
-bool BootCore(const std::string& filename, SConfig::EBootBS2 type)
+bool BootCore(std::unique_ptr<BootParameters> boot)
 {
+  if (!boot)
+    return false;
+
   SConfig& StartUp = SConfig::GetInstance();
 
-  StartUp.m_BootType = SConfig::BOOT_ISO;
-  StartUp.m_strFilename = filename;
   StartUp.bRunCompareClient = false;
   StartUp.bRunCompareServer = false;
 
   config_cache.SaveConfig(StartUp);
 
-  // If for example the ISO file is bad we return here
-  if (!StartUp.AutoSetup(type))
+  if (!StartUp.SetPathsAndGameMetadata(*boot))
     return false;
 
   // Load game specific settings
-  if (type == SConfig::BOOT_DEFAULT)
+  if (!std::holds_alternative<BootParameters::IPL>(boot->parameters))
   {
     std::string game_id = SConfig::GetInstance().GetGameID();
     u16 revision = SConfig::GetInstance().GetRevision();
@@ -400,15 +401,14 @@ bool BootCore(const std::string& filename, SConfig::EBootBS2 type)
   if (StartUp.bWii)
     StartUp.SaveSettingsToSysconf();
 
-  // Run the game
-  // Init the core
-  if (!Core::Init())
+  const bool load_ipl = !StartUp.bWii && !StartUp.bHLE_BS2 &&
+                        std::holds_alternative<BootParameters::Disc>(boot->parameters);
+  if (load_ipl)
   {
-    PanicAlertT("Couldn't init the core.\nCheck your configuration.");
-    return false;
+    return Core::Init(std::make_unique<BootParameters>(BootParameters::IPL{
+        StartUp.m_region, std::move(std::get<BootParameters::Disc>(boot->parameters))}));
   }
-
-  return true;
+  return Core::Init(std::move(boot));
 }
 
 void Stop()
diff --git a/Source/Core/Core/BootManager.h b/Source/Core/Core/BootManager.h
index bb7b7cae99..a068247e50 100644
--- a/Source/Core/Core/BootManager.h
+++ b/Source/Core/Core/BootManager.h
@@ -4,13 +4,16 @@
 
 #pragma once
 
+#include <memory>
 #include <string>
 
 #include "Core/ConfigManager.h"
 
+struct BootParameters;
+
 namespace BootManager
 {
-bool BootCore(const std::string& filename, SConfig::EBootBS2 type);
+bool BootCore(std::unique_ptr<BootParameters> parameters);
 
 // Stop the emulation core and restore the configuration.
 void Stop();
diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp
index 400bbfc581..342cb60527 100644
--- a/Source/Core/Core/ConfigManager.cpp
+++ b/Source/Core/Core/ConfigManager.cpp
@@ -6,6 +6,7 @@
 #include <climits>
 #include <memory>
 #include <optional>
+#include <variant>
 
 #include "AudioCommon/AudioCommon.h"
 
@@ -881,165 +882,95 @@ std::string SConfig::GetBootROMPath(const std::string& region_directory) const
   return path;
 }
 
-// Sets m_region to the region parameter, or to PAL if the region parameter
-// is invalid. Set directory_name to the value returned by GetDirectoryForRegion
-// for m_region. Returns false if the region parameter is invalid.
-bool SConfig::SetRegion(DiscIO::Region region, std::string* directory_name)
+struct SetGameMetadata
 {
+  SetGameMetadata(SConfig* config_, DiscIO::Region* region_) : config(config_), region(region_) {}
+  bool operator()(const BootParameters::Disc& disc) const
+  {
+    config->SetRunningGameMetadata(*disc.volume, disc.volume->GetGamePartition());
+    config->bWii = disc.volume->GetVolumeType() == DiscIO::Platform::WII_DISC;
+    config->m_disc_booted_from_game_list = true;
+    *region = disc.volume->GetRegion();
+    return true;
+  }
+
+  bool operator()(const BootParameters::Executable& executable) const
+  {
+    if (executable.type == BootParameters::Executable::Type::DOL)
+      config->bWii = CDolLoader{executable.path}.IsWii();
+    if (executable.type == BootParameters::Executable::Type::ELF)
+      config->bWii = CBoot::IsElfWii(executable.path);
+
+    // TODO: Right now GC homebrew boots in NTSC and Wii homebrew in PAL.
+    // This is intentional so that Wii homebrew can boot in both 50Hz and 60Hz,
+    // without forcing all GC homebrew to 50Hz.
+    // In the future, it probably makes sense to add a Region setting for homebrew somewhere in
+    // the emulator config.
+    *region = config->bWii ? DiscIO::Region::PAL : DiscIO::Region::NTSC_U;
+    return true;
+  }
+
+  bool operator()(const BootParameters::NAND& nand) const
+  {
+    const auto& loader = DiscIO::NANDContentManager::Access().GetNANDLoader(nand.content_path);
+    if (!loader.IsValid())
+      return false;
+
+    const IOS::ES::TMDReader& tmd = loader.GetTMD();
+
+    config->SetRunningGameMetadata(tmd);
+    config->bWii = true;
+    *region = tmd.GetRegion();
+    return true;
+  }
+
+  bool operator()(const BootParameters::IPL& ipl) const
+  {
+    config->bWii = false;
+    *region = ipl.region;
+    return true;
+  }
+
+  bool operator()(const BootParameters::DFF& dff) const
+  {
+    std::unique_ptr<FifoDataFile> dff_file(FifoDataFile::Load(dff.dff_path, true));
+    if (!dff_file)
+      return false;
+
+    config->bWii = dff_file->GetIsWii();
+    *region = DiscIO::Region::NTSC_U;
+    return true;
+  }
+
+private:
+  SConfig* config;
+  DiscIO::Region* region;
+};
+
+bool SConfig::SetPathsAndGameMetadata(const BootParameters& boot)
+{
+  m_is_mios = false;
+  m_disc_booted_from_game_list = false;
+  DiscIO::Region region;
+  if (!std::visit(SetGameMetadata(this, &region), boot.parameters))
+    return false;
+
+  // Set up region
   const char* retrieved_region_dir = GetDirectoryForRegion(region);
   m_region = retrieved_region_dir ? region : DiscIO::Region::PAL;
-  *directory_name = retrieved_region_dir ? retrieved_region_dir : EUR_DIR;
-  return !!retrieved_region_dir;
-}
-
-bool SConfig::AutoSetup(EBootBS2 _BootBS2)
-{
-  std::string set_region_dir(EUR_DIR);
-
-  switch (_BootBS2)
+  const std::string set_region_dir = retrieved_region_dir ? retrieved_region_dir : EUR_DIR;
+  if (!retrieved_region_dir &&
+      !PanicYesNoT("Your GCM/ISO file seems to be invalid (invalid country)."
+                   "\nContinue with PAL region?"))
   {
-  case BOOT_DEFAULT:
-  {
-    bool bootDrive = cdio_is_cdrom(m_strFilename);
-    // Check if the file exist, we may have gotten it from a --elf command line
-    // that gave an incorrect file name
-    if (!bootDrive && !File::Exists(m_strFilename))
-    {
-      PanicAlertT("The specified file \"%s\" does not exist", m_strFilename.c_str());
-      return false;
-    }
-
-    std::string Extension;
-    SplitPath(m_strFilename, nullptr, nullptr, &Extension);
-    if (!strcasecmp(Extension.c_str(), ".gcm") || !strcasecmp(Extension.c_str(), ".iso") ||
-        !strcasecmp(Extension.c_str(), ".tgc") || !strcasecmp(Extension.c_str(), ".wbfs") ||
-        !strcasecmp(Extension.c_str(), ".ciso") || !strcasecmp(Extension.c_str(), ".gcz") ||
-        bootDrive)
-    {
-      m_BootType = BOOT_ISO;
-      std::unique_ptr<DiscIO::Volume> pVolume(DiscIO::CreateVolumeFromFilename(m_strFilename));
-      if (pVolume == nullptr)
-      {
-        if (bootDrive)
-          PanicAlertT("Could not read \"%s\". "
-                      "There is no disc in the drive or it is not a GameCube/Wii backup. "
-                      "Please note that Dolphin cannot play games directly from the original "
-                      "GameCube and Wii discs.",
-                      m_strFilename.c_str());
-        else
-          PanicAlertT("\"%s\" is an invalid GCM/ISO file, or is not a GC/Wii ISO.",
-                      m_strFilename.c_str());
-        return false;
-      }
-      SetRunningGameMetadata(*pVolume, pVolume->GetGamePartition());
-
-      // Check if we have a Wii disc
-      bWii = pVolume->GetVolumeType() == DiscIO::Platform::WII_DISC;
-
-      if (!SetRegion(pVolume->GetRegion(), &set_region_dir))
-        if (!PanicYesNoT("Your GCM/ISO file seems to be invalid (invalid country)."
-                         "\nContinue with PAL region?"))
-          return false;
-    }
-    else if (!strcasecmp(Extension.c_str(), ".elf"))
-    {
-      bWii = CBoot::IsElfWii(m_strFilename);
-      // TODO: Right now GC homebrew boots in NTSC and Wii homebrew in PAL.
-      // This is intentional so that Wii homebrew can boot in both 50Hz and 60Hz, without forcing
-      // all GC homebrew to 50Hz.
-      // In the future, it probably makes sense to add a Region setting for homebrew somewhere in
-      // the emulator config.
-      SetRegion(bWii ? DiscIO::Region::PAL : DiscIO::Region::NTSC_U, &set_region_dir);
-      m_BootType = BOOT_ELF;
-    }
-    else if (!strcasecmp(Extension.c_str(), ".dol"))
-    {
-      CDolLoader dolfile(m_strFilename);
-      bWii = dolfile.IsWii();
-      // TODO: See the ELF code above.
-      SetRegion(bWii ? DiscIO::Region::PAL : DiscIO::Region::NTSC_U, &set_region_dir);
-      m_BootType = BOOT_DOL;
-    }
-    else if (!strcasecmp(Extension.c_str(), ".dff"))
-    {
-      bWii = true;
-      SetRegion(DiscIO::Region::NTSC_U, &set_region_dir);
-      m_BootType = BOOT_DFF;
-
-      std::unique_ptr<FifoDataFile> ddfFile(FifoDataFile::Load(m_strFilename, true));
-
-      if (ddfFile)
-      {
-        bWii = ddfFile->GetIsWii();
-      }
-    }
-    else if (DiscIO::NANDContentManager::Access().GetNANDLoader(m_strFilename).IsValid())
-    {
-      const DiscIO::NANDContentLoader& content_loader =
-          DiscIO::NANDContentManager::Access().GetNANDLoader(m_strFilename);
-      const IOS::ES::TMDReader& tmd = content_loader.GetTMD();
-
-      if (!IOS::ES::IsChannel(tmd.GetTitleId()))
-      {
-        PanicAlertT("This WAD is not bootable.");
-        return false;
-      }
-
-      SetRegion(tmd.GetRegion(), &set_region_dir);
-      SetRunningGameMetadata(tmd);
-
-      bWii = true;
-      m_BootType = BOOT_WII_NAND;
-    }
-    else
-    {
-      PanicAlertT("Could not recognize ISO file %s", m_strFilename.c_str());
-      return false;
-    }
-  }
-  break;
-
-  case BOOT_BS2_USA:
-    SetRegion(DiscIO::Region::NTSC_U, &set_region_dir);
-    m_strFilename.clear();
-    m_BootType = SConfig::BOOT_BS2;
-    break;
-
-  case BOOT_BS2_JAP:
-    SetRegion(DiscIO::Region::NTSC_J, &set_region_dir);
-    m_strFilename.clear();
-    m_BootType = SConfig::BOOT_BS2;
-    break;
-
-  case BOOT_BS2_EUR:
-    SetRegion(DiscIO::Region::PAL, &set_region_dir);
-    m_strFilename.clear();
-    m_BootType = SConfig::BOOT_BS2;
-    break;
+    return false;
   }
 
-  // Setup paths
+  // Set up paths
   CheckMemcardPath(SConfig::GetInstance().m_strMemoryCardA, set_region_dir, true);
   CheckMemcardPath(SConfig::GetInstance().m_strMemoryCardB, set_region_dir, false);
   m_strSRAM = File::GetUserPath(F_GCSRAM_IDX);
-  if (!bWii)
-  {
-    if (!bHLE_BS2)
-    {
-      m_strBootROM = GetBootROMPath(set_region_dir);
-
-      if (!File::Exists(m_strBootROM))
-      {
-        WARN_LOG(BOOT, "Bootrom file %s not found - using HLE.", m_strBootROM.c_str());
-        bHLE_BS2 = true;
-      }
-    }
-  }
-  else if (bWii && !bHLE_BS2)
-  {
-    WARN_LOG(BOOT, "GC bootrom file will not be loaded for Wii mode.");
-    bHLE_BS2 = true;
-  }
+  m_strBootROM = GetBootROMPath(set_region_dir);
 
   return true;
 }
diff --git a/Source/Core/Core/ConfigManager.h b/Source/Core/Core/ConfigManager.h
index 5102d400ba..3fd85fdfb9 100644
--- a/Source/Core/Core/ConfigManager.h
+++ b/Source/Core/Core/ConfigManager.h
@@ -51,6 +51,8 @@ enum GPUDeterminismMode
   GPU_DETERMINISM_FAKE_COMPLETION,
 };
 
+struct BootParameters;
+
 struct SConfig : NonCopyable
 {
   // Wii Devices
@@ -182,25 +184,6 @@ struct SConfig : NonCopyable
   bool bEnableCustomRTC;
   u32 m_customRTCValue;
 
-  enum EBootBS2
-  {
-    BOOT_DEFAULT,
-    BOOT_BS2_JAP,
-    BOOT_BS2_USA,
-    BOOT_BS2_EUR,
-  };
-
-  enum EBootType
-  {
-    BOOT_ISO,
-    BOOT_ELF,
-    BOOT_DOL,
-    BOOT_WII_NAND,
-    BOOT_BS2,
-    BOOT_DFF
-  };
-
-  EBootType m_BootType;
   DiscIO::Region m_region;
 
   std::string m_strVideoBackend;
@@ -210,7 +193,6 @@ struct SConfig : NonCopyable
   GPUDeterminismMode m_GPUDeterminismMode;
 
   // files
-  std::string m_strFilename;
   std::string m_strBootROM;
   std::string m_strSRAM;
   std::string m_strDefaultISO;
@@ -220,6 +202,9 @@ struct SConfig : NonCopyable
 
   std::string m_perfDir;
 
+  // TODO: remove this as soon as the ticket view hack in IOS/ES/Views is dropped.
+  bool m_disc_booted_from_game_list = false;
+
   const std::string& GetGameID() const { return m_game_id; }
   const std::string& GetTitleDescription() const { return m_title_description; }
   u64 GetTitleID() const { return m_title_id; }
@@ -231,7 +216,7 @@ struct SConfig : NonCopyable
   void LoadDefaults();
   static const char* GetDirectoryForRegion(DiscIO::Region region);
   std::string GetBootROMPath(const std::string& region_directory) const;
-  bool AutoSetup(EBootBS2 _BootBS2);
+  bool SetPathsAndGameMetadata(const BootParameters& boot);
   void CheckMemcardPath(std::string& memcardPath, const std::string& gameRegion, bool isSlotA);
   DiscIO::Language GetCurrentLanguage(bool wii) const;
 
@@ -389,7 +374,6 @@ private:
 
   void SetRunningGameMetadata(const std::string& game_id, u64 title_id, u16 revision,
                               Core::TitleDatabase::TitleType type);
-  bool SetRegion(DiscIO::Region region, std::string* directory_name);
 
   static SConfig* m_Instance;
 
diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp
index 122289c5b0..bdddfbadb4 100644
--- a/Source/Core/Core/Core.cpp
+++ b/Source/Core/Core/Core.cpp
@@ -10,6 +10,7 @@
 #include <mutex>
 #include <queue>
 #include <utility>
+#include <variant>
 
 #ifdef _WIN32
 #include <windows.h>
@@ -122,7 +123,7 @@ static void InitIsCPUKey()
 }
 #endif
 
-static void EmuThread();
+static void EmuThread(std::unique_ptr<BootParameters> boot);
 
 bool GetIsThrottlerTempDisabled()
 {
@@ -221,7 +222,7 @@ bool WantsDeterminism()
 
 // This is called from the GUI thread. See the booting call schedule in
 // BootManager.cpp
-bool Init()
+bool Init(std::unique_ptr<BootParameters> boot)
 {
   if (s_emu_thread.joinable())
   {
@@ -248,7 +249,7 @@ bool Init()
   s_window_handle = Host_GetRenderHandle();
 
   // Start the emu thread
-  s_emu_thread = std::thread(EmuThread);
+  s_emu_thread = std::thread(EmuThread, std::move(boot));
 
   return true;
 }
@@ -412,21 +413,18 @@ static void FifoPlayerThread()
   }
 
   // Enter CPU run loop. When we leave it - we are done.
-  if (FifoPlayer::GetInstance().Open(_CoreParameter.m_strFilename))
+  if (auto cpu_core = FifoPlayer::GetInstance().GetCPUCore())
   {
-    if (auto cpu_core = FifoPlayer::GetInstance().GetCPUCore())
-    {
-      PowerPC::InjectExternalCPUCore(cpu_core.get());
-      s_is_started = true;
+    PowerPC::InjectExternalCPUCore(cpu_core.get());
+    s_is_started = true;
 
-      CPUSetInitialExecutionState();
-      CPU::Run();
+    CPUSetInitialExecutionState();
+    CPU::Run();
 
-      s_is_started = false;
-      PowerPC::InjectExternalCPUCore(nullptr);
-    }
-    FifoPlayer::GetInstance().Close();
+    s_is_started = false;
+    PowerPC::InjectExternalCPUCore(nullptr);
   }
+  FifoPlayer::GetInstance().Close();
 
   // If we did not enter the CPU Run Loop above then run a fake one instead.
   // We need to be IsRunningAndStarted() for DolphinWX to stop us.
@@ -450,7 +448,7 @@ static void FifoPlayerThread()
 // Initialize and create emulation thread
 // Call browser: Init():s_emu_thread().
 // See the BootManager.cpp file description for a complete call schedule.
-static void EmuThread()
+static void EmuThread(std::unique_ptr<BootParameters> boot)
 {
   const SConfig& core_parameter = SConfig::GetInstance();
   s_is_booting.Set();
@@ -474,12 +472,11 @@ static void EmuThread()
     DisplayMessage("WARNING: running at non-native CPU clock! Game may not be stable.", 8000);
   DisplayMessage(cpu_info.brand_string, 8000);
   DisplayMessage(cpu_info.Summarize(), 8000);
-  DisplayMessage(core_parameter.m_strFilename, 3000);
 
   // For a time this acts as the CPU thread...
   DeclareAsCPUThread();
 
-  Movie::Init();
+  Movie::Init(*boot);
   Common::ScopeGuard movie_guard{Movie::Shutdown};
 
   HW::Init();
@@ -560,7 +557,15 @@ static void EmuThread()
   // Load GCM/DOL/ELF whatever ... we boot with the interpreter core
   PowerPC::SetMode(PowerPC::CoreMode::Interpreter);
 
-  CBoot::BootUp();
+  // Determine the CPU thread function
+  void (*cpuThreadFunc)();
+  if (std::holds_alternative<BootParameters::DFF>(boot->parameters))
+    cpuThreadFunc = FifoPlayerThread;
+  else
+    cpuThreadFunc = CpuThread;
+
+  if (!CBoot::BootUp(std::move(boot)))
+    return;
 
   // This adds the SyncGPU handler to CoreTiming, so now CoreTiming::Advance might block.
   Fifo::Prepare();
@@ -583,13 +588,6 @@ static void EmuThread()
   Host_UpdateDisasmDialog();
   Host_UpdateMainFrame();
 
-  // Determine the CPU thread function
-  void (*cpuThreadFunc)(void);
-  if (core_parameter.m_BootType == SConfig::BOOT_DFF)
-    cpuThreadFunc = FifoPlayerThread;
-  else
-    cpuThreadFunc = CpuThread;
-
   // ENTER THE VIDEO THREAD LOOP
   if (core_parameter.bCPUThread)
   {
diff --git a/Source/Core/Core/Core.h b/Source/Core/Core/Core.h
index 89bdedb25c..78b5f5d6c7 100644
--- a/Source/Core/Core/Core.h
+++ b/Source/Core/Core/Core.h
@@ -11,11 +11,14 @@
 #pragma once
 
 #include <functional>
+#include <memory>
 #include <string>
 #include <vector>
 
 #include "Common/CommonTypes.h"
 
+struct BootParameters;
+
 namespace Core
 {
 bool GetIsThrottlerTempDisabled();
@@ -31,7 +34,7 @@ enum class State
   Stopping
 };
 
-bool Init();
+bool Init(std::unique_ptr<BootParameters> boot);
 void Stop();
 void Shutdown();
 
diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp b/Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp
index 22544118c5..528ed351f5 100644
--- a/Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp
+++ b/Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp
@@ -98,7 +98,8 @@ CEXIIPL::CEXIIPL() : m_uPosition(0), m_uAddress(0), m_uRWOffset(0), m_FontsLoade
   // Create the IPL
   m_pIPL = static_cast<u8*>(Common::AllocateMemoryPages(ROM_SIZE));
 
-  if (SConfig::GetInstance().bHLE_BS2)
+  // The Wii doesn't have a copy of the IPL, only fonts.
+  if (SConfig::GetInstance().bWii || SConfig::GetInstance().bHLE_BS2)
   {
     // Copy header
     if (DiscIO::IsNTSC(SConfig::GetInstance().m_region))
diff --git a/Source/Core/Core/IOS/ES/Views.cpp b/Source/Core/Core/IOS/ES/Views.cpp
index 6bdd730c20..9d1369ca79 100644
--- a/Source/Core/Core/IOS/ES/Views.cpp
+++ b/Source/Core/Core/IOS/ES/Views.cpp
@@ -38,7 +38,7 @@ static bool ShouldReturnFakeViewsForIOSes(u64 title_id, const TitleContext& cont
   const bool ios = IsTitleType(title_id, IOS::ES::TitleType::System) && title_id != TITLEID_SYSMENU;
   const bool disc_title = context.active && IOS::ES::IsDiscTitle(context.tmd.GetTitleId());
   return Core::WantsDeterminism() ||
-         (ios && SConfig::GetInstance().m_BootType == SConfig::BOOT_ISO && disc_title);
+         (ios && SConfig::GetInstance().m_disc_booted_from_game_list && disc_title);
 }
 
 IPCCommandResult ES::GetTicketViewCount(const IOCtlVRequest& request)
diff --git a/Source/Core/Core/Movie.cpp b/Source/Core/Core/Movie.cpp
index 207a047079..608638c39a 100644
--- a/Source/Core/Core/Movie.cpp
+++ b/Source/Core/Core/Movie.cpp
@@ -13,6 +13,7 @@
 #include <mutex>
 #include <thread>
 #include <utility>
+#include <variant>
 #include <vector>
 
 #include "Common/Assert.h"
@@ -23,6 +24,7 @@
 #include "Common/NandPaths.h"
 #include "Common/StringUtil.h"
 #include "Common/Timer.h"
+#include "Core/Boot/Boot.h"
 #include "Core/ConfigManager.h"
 #include "Core/Core.h"
 #include "Core/CoreTiming.h"
@@ -97,6 +99,8 @@ static std::string s_InputDisplay[8];
 static GCManipFunction s_gc_manip_func;
 static WiiManipFunction s_wii_manip_func;
 
+static std::string s_current_file_name;
+
 // NOTE: Host / CPU Thread
 static void EnsureTmpInputSize(size_t bound)
 {
@@ -216,11 +220,19 @@ void FrameUpdate()
   s_bPolled = false;
 }
 
+static void CheckMD5();
+static void GetMD5();
+
 // called when game is booting up, even if no movie is active,
 // but potentially after BeginRecordingInput or PlayInput has been called.
 // NOTE: EmuThread
-void Init()
+void Init(const BootParameters& boot)
 {
+  if (std::holds_alternative<BootParameters::Disc>(boot.parameters))
+    s_current_file_name = std::get<BootParameters::Disc>(boot.parameters).path;
+  else
+    s_current_file_name.clear();
+
   s_bPolled = false;
   s_bFrameStep = false;
   s_bSaveConfig = false;
@@ -1551,8 +1563,11 @@ void GetSettings()
 static const mbedtls_md_info_t* s_md5_info = mbedtls_md_info_from_type(MBEDTLS_MD_MD5);
 
 // NOTE: Entrypoint for own thread
-void CheckMD5()
+static void CheckMD5()
 {
+  if (s_current_file_name.empty())
+    return;
+
   for (int i = 0, n = 0; i < 16; ++i)
   {
     if (tmpHeader.md5[i] != 0)
@@ -1564,7 +1579,7 @@ void CheckMD5()
   Core::DisplayMessage("Verifying checksum...", 2000);
 
   unsigned char gameMD5[16];
-  mbedtls_md_file(s_md5_info, SConfig::GetInstance().m_strFilename.c_str(), gameMD5);
+  mbedtls_md_file(s_md5_info, s_current_file_name.c_str(), gameMD5);
 
   if (memcmp(gameMD5, s_MD5, 16) == 0)
     Core::DisplayMessage("Checksum of current game matches the recorded game.", 2000);
@@ -1573,11 +1588,14 @@ void CheckMD5()
 }
 
 // NOTE: Entrypoint for own thread
-void GetMD5()
+static void GetMD5()
 {
+  if (s_current_file_name.empty())
+    return;
+
   Core::DisplayMessage("Calculating checksum of game file...", 2000);
   memset(s_MD5, 0, sizeof(s_MD5));
-  mbedtls_md_file(s_md5_info, SConfig::GetInstance().m_strFilename.c_str(), s_MD5);
+  mbedtls_md_file(s_md5_info, s_current_file_name.c_str(), s_MD5);
   Core::DisplayMessage("Finished calculating checksum.", 2000);
 }
 
diff --git a/Source/Core/Core/Movie.h b/Source/Core/Core/Movie.h
index 84326dcdb6..d56e61eaad 100644
--- a/Source/Core/Core/Movie.h
+++ b/Source/Core/Core/Movie.h
@@ -9,6 +9,8 @@
 
 #include "Common/CommonTypes.h"
 
+struct BootParameters;
+
 struct GCPadStatus;
 class PointerWrap;
 struct wiimote_key;
@@ -110,7 +112,7 @@ static_assert(sizeof(DTMHeader) == 256, "DTMHeader should be 256 bytes");
 
 void FrameUpdate();
 void InputUpdate();
-void Init();
+void Init(const BootParameters& boot);
 
 void SetPolledDevice();
 
@@ -171,8 +173,6 @@ bool PlayWiimote(int wiimote, u8* data, const struct WiimoteEmu::ReportFeatures&
 void EndPlayInput(bool cont);
 void SaveRecording(const std::string& filename);
 void DoState(PointerWrap& p);
-void CheckMD5();
-void GetMD5();
 void Shutdown();
 void CheckPadStatus(GCPadStatus* PadStatus, int controllerID);
 void CheckWiimoteStatus(int wiimote, u8* data, const struct WiimoteEmu::ReportFeatures& rptf,
diff --git a/Source/Core/DolphinNoGUI/MainNoGUI.cpp b/Source/Core/DolphinNoGUI/MainNoGUI.cpp
index 528f2aa0e0..988518724a 100644
--- a/Source/Core/DolphinNoGUI/MainNoGUI.cpp
+++ b/Source/Core/DolphinNoGUI/MainNoGUI.cpp
@@ -18,6 +18,7 @@
 #include "Common/MsgHandler.h"
 
 #include "Core/Analytics.h"
+#include "Core/Boot/Boot.h"
 #include "Core/BootManager.h"
 #include "Core/ConfigManager.h"
 #include "Core/Core.h"
@@ -422,7 +423,7 @@ int main(int argc, char* argv[])
 
   DolphinAnalytics::Instance()->ReportDolphinStart("nogui");
 
-  if (!BootManager::BootCore(boot_filename, SConfig::BOOT_DEFAULT))
+  if (!BootManager::BootCore(BootParameters::GenerateFromFile(boot_filename)))
   {
     fprintf(stderr, "Could not boot %s\n", boot_filename.c_str());
     return 1;
diff --git a/Source/Core/DolphinQt2/MainWindow.cpp b/Source/Core/DolphinQt2/MainWindow.cpp
index a8049826f2..0c8b14ef8c 100644
--- a/Source/Core/DolphinQt2/MainWindow.cpp
+++ b/Source/Core/DolphinQt2/MainWindow.cpp
@@ -9,6 +9,7 @@
 
 #include "Common/Common.h"
 
+#include "Core/Boot/Boot.h"
 #include "Core/BootManager.h"
 #include "Core/ConfigManager.h"
 #include "Core/Core.h"
@@ -287,7 +288,7 @@ void MainWindow::StartGame(const QString& path)
       return;
   }
   // Boot up, show an error if it fails to load the game.
-  if (!BootManager::BootCore(path.toStdString(), SConfig::BOOT_DEFAULT))
+  if (!BootManager::BootCore(BootParameters::GenerateFromFile(path.toStdString())))
   {
     QMessageBox::critical(this, tr("Error"), tr("Failed to init core"), QMessageBox::Ok);
     return;
diff --git a/Source/Core/DolphinWX/Frame.h b/Source/Core/DolphinWX/Frame.h
index a0635321f8..4d5a7282dd 100644
--- a/Source/Core/DolphinWX/Frame.h
+++ b/Source/Core/DolphinWX/Frame.h
@@ -6,6 +6,7 @@
 
 #include <array>
 #include <cstddef>
+#include <memory>
 #include <mutex>
 #include <string>
 #include <vector>
@@ -28,6 +29,8 @@
 #include <IOKit/pwr_mgt/IOPMLib.h>
 #endif
 
+struct BootParameters;
+
 // Class declarations
 class CGameListCtrl;
 class CCodeWindow;
@@ -184,7 +187,7 @@ private:
   void InitializeTASDialogs();
   void InitializeCoreCallbacks();
 
-  void StartGame(const std::string& filename, SConfig::EBootBS2 type = SConfig::BOOT_DEFAULT);
+  void StartGame(std::unique_ptr<BootParameters> boot);
   void SetDebuggerStartupParameters() const;
 
   // Utility
diff --git a/Source/Core/DolphinWX/FrameTools.cpp b/Source/Core/DolphinWX/FrameTools.cpp
index 22f0096cb6..8ac6fd7e08 100644
--- a/Source/Core/DolphinWX/FrameTools.cpp
+++ b/Source/Core/DolphinWX/FrameTools.cpp
@@ -30,6 +30,7 @@
 #include "Common/NandPaths.h"
 #include "Common/StringUtil.h"
 
+#include "Core/Boot/Boot.h"
 #include "Core/BootManager.h"
 #include "Core/ConfigManager.h"
 #include "Core/Core.h"
@@ -53,6 +54,7 @@
 #include "Core/PowerPC/PowerPC.h"
 #include "Core/State.h"
 
+#include "DiscIO/Enums.h"
 #include "DiscIO/NANDContentLoader.h"
 #include "DiscIO/NANDImporter.h"
 #include "DiscIO/VolumeWad.h"
@@ -315,7 +317,7 @@ void CFrame::BootGame(const std::string& filename)
   }
   if (!bootfile.empty())
   {
-    StartGame(bootfile);
+    StartGame(BootParameters::GenerateFromFile(bootfile));
   }
 }
 
@@ -627,7 +629,7 @@ void CFrame::ToggleDisplayMode(bool bFullscreen)
 }
 
 // Prepare the GUI to start the game.
-void CFrame::StartGame(const std::string& filename, SConfig::EBootBS2 type)
+void CFrame::StartGame(std::unique_ptr<BootParameters> boot)
 {
   if (m_is_game_loading)
     return;
@@ -705,7 +707,7 @@ void CFrame::StartGame(const std::string& filename, SConfig::EBootBS2 type)
 
   SetDebuggerStartupParameters();
 
-  if (!BootManager::BootCore(filename, type))
+  if (!BootManager::BootCore(std::move(boot)))
   {
     DoFullscreen(false);
 
@@ -1169,17 +1171,17 @@ void CFrame::OnMemcard(wxCommandEvent& WXUNUSED(event))
 
 void CFrame::OnLoadGameCubeIPLJAP(wxCommandEvent&)
 {
-  StartGame("", SConfig::BOOT_BS2_JAP);
+  StartGame(std::make_unique<BootParameters>(BootParameters::IPL{DiscIO::Region::NTSC_J}));
 }
 
 void CFrame::OnLoadGameCubeIPLUSA(wxCommandEvent&)
 {
-  StartGame("", SConfig::BOOT_BS2_USA);
+  StartGame(std::make_unique<BootParameters>(BootParameters::IPL{DiscIO::Region::NTSC_U}));
 }
 
 void CFrame::OnLoadGameCubeIPLEUR(wxCommandEvent&)
 {
-  StartGame("", SConfig::BOOT_BS2_EUR);
+  StartGame(std::make_unique<BootParameters>(BootParameters::IPL{DiscIO::Region::PAL}));
 }
 
 void CFrame::OnExportAllSaves(wxCommandEvent& WXUNUSED(event))

From 065261dbadab5793d245faed996b4cd26ff58321 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?L=C3=A9o=20Lam?= <leo@innovatetechnologi.es>
Date: Sun, 28 May 2017 17:12:38 +0200
Subject: [PATCH 05/57] Boot: Unify the ELF and DOL code paths

They're essentially the same. To achieve this, this commit unifies
DolReader and ElfReader into a common interface for boot executable
readers, so the only remaining difference between ELF and DOL is
how which volume is inserted.
---
 Source/Core/Core/Boot/Boot.cpp                | 117 +++++++++---------
 Source/Core/Core/Boot/Boot.h                  |  30 +++--
 Source/Core/Core/Boot/Boot_ELF.cpp            |  89 -------------
 .../Core/Boot/{Boot_DOL.cpp => DolReader.cpp} |  41 +++---
 .../Core/Boot/{Boot_DOL.h => DolReader.h}     |  20 +--
 Source/Core/Core/Boot/ElfReader.cpp           |  49 +++++++-
 Source/Core/Core/Boot/ElfReader.h             |  42 ++++---
 Source/Core/Core/CMakeLists.txt               |   3 +-
 Source/Core/Core/ConfigManager.cpp            |   9 +-
 Source/Core/Core/Core.vcxproj                 |   7 +-
 Source/Core/Core/Core.vcxproj.filters         |  11 +-
 Source/Core/Core/IOS/IOS.cpp                  |   7 +-
 Source/Core/Core/IOS/MIOS.cpp                 |   3 +-
 13 files changed, 195 insertions(+), 233 deletions(-)
 delete mode 100644 Source/Core/Core/Boot/Boot_ELF.cpp
 rename Source/Core/Core/Boot/{Boot_DOL.cpp => DolReader.cpp} (75%)
 rename Source/Core/Core/Boot/{Boot_DOL.h => DolReader.h} (63%)

diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp
index 43296eb784..65394fd05f 100644
--- a/Source/Core/Core/Boot/Boot.cpp
+++ b/Source/Core/Core/Boot/Boot.cpp
@@ -21,7 +21,8 @@
 #include "Common/MsgHandler.h"
 #include "Common/StringUtil.h"
 
-#include "Core/Boot/Boot_DOL.h"
+#include "Core/Boot/DolReader.h"
+#include "Core/Boot/ElfReader.h"
 #include "Core/ConfigManager.h"
 #include "Core/Core.h"
 #include "Core/Debugger/Debugger_SymbolMap.h"
@@ -86,11 +87,11 @@ std::unique_ptr<BootParameters> BootParameters::GenerateFromFile(const std::stri
     return std::make_unique<BootParameters>(Disc{path, std::move(volume)});
   }
 
-  if (extension == ".elf" || extension == ".dol")
-  {
-    return std::make_unique<BootParameters>(
-        Executable{path, extension == ".elf" ? Executable::Type::ELF : Executable::Type::DOL});
-  }
+  if (extension == ".elf")
+    return std::make_unique<BootParameters>(Executable{path, std::make_unique<ElfReader>(path)});
+
+  if (extension == ".dol")
+    return std::make_unique<BootParameters>(Executable{path, std::make_unique<DolReader>(path)});
 
   if (extension == ".dff")
     return std::make_unique<BootParameters>(DFF{path});
@@ -371,14 +372,13 @@ bool CBoot::BootUp(std::unique_ptr<BootParameters> boot)
     {
       NOTICE_LOG(BOOT, "Booting from executable: %s", executable.path.c_str());
 
-      // TODO: needs more cleanup.
-      if (executable.type == BootParameters::Executable::Type::DOL)
-      {
-        CDolLoader dolLoader(executable.path);
-        if (!dolLoader.IsValid())
-          return false;
+      if (!executable.reader->IsValid())
+        return false;
 
-        const DiscIO::Volume* volume = nullptr;
+      const DiscIO::Volume* volume = nullptr;
+      // VolumeDirectory only works with DOLs.
+      if (StringEndsWith(executable.path, ".dol"))
+      {
         if (!config.m_strDVDRoot.empty())
         {
           NOTICE_LOG(BOOT, "Setting DVDRoot %s", config.m_strDVDRoot.c_str());
@@ -390,57 +390,41 @@ bool CBoot::BootUp(std::unique_ptr<BootParameters> boot)
           NOTICE_LOG(BOOT, "Loading default ISO %s", config.m_strDefaultISO.c_str());
           volume = SetDisc(DiscIO::CreateVolumeFromFilename(config.m_strDefaultISO));
         }
-
-        // Poor man's bootup
-        if (config.bWii)
-        {
-          HID4.SBE = 1;
-          SetupMSR();
-          SetupBAT(config.bWii);
-
-          // Because there is no TMD to get the requested system (IOS) version from,
-          // we default to IOS58, which is the version used by the Homebrew Channel.
-          SetupWiiMemory(volume, 0x000000010000003a);
-        }
-        else
-        {
-          EmulatedBS2_GC(volume, true);
-        }
-
-        Load_FST(config.bWii, volume);
-        dolLoader.Load();
-        PC = dolLoader.GetEntryPoint();
-
-        if (LoadMapFromFilename())
-          HLE::PatchFunctions();
       }
-
-      if (executable.type == BootParameters::Executable::Type::ELF)
+      else
       {
-        const DiscIO::Volume* volume = SetDefaultDisc();
-
-        // Poor man's bootup
-        if (config.bWii)
-        {
-          // Because there is no TMD to get the requested system (IOS) version from,
-          // we default to IOS58, which is the version used by the Homebrew Channel.
-          SetupWiiMemory(volume, 0x000000010000003a);
-        }
-        else
-        {
-          EmulatedBS2_GC(volume, true);
-        }
-
-        Load_FST(config.bWii, volume);
-        if (!Boot_ELF(executable.path))
-          return false;
-
-        // Note: Boot_ELF calls HLE::PatchFunctions()
-
-        UpdateDebugger_MapLoaded();
-        Dolphin_Debugger::AddAutoBreakpoints();
+        volume = SetDefaultDisc();
       }
 
+      if (!executable.reader->LoadIntoMemory())
+      {
+        PanicAlertT("Failed to load the executable to memory.");
+        return false;
+      }
+
+      // Poor man's bootup
+      if (config.bWii)
+      {
+        HID4.SBE = 1;
+        SetupMSR();
+        SetupBAT(config.bWii);
+        // Because there is no TMD to get the requested system (IOS) version from,
+        // we default to IOS58, which is the version used by the Homebrew Channel.
+        SetupWiiMemory(volume, 0x000000010000003a);
+      }
+      else
+      {
+        EmulatedBS2_GC(volume, true);
+      }
+
+      Load_FST(config.bWii, volume);
+      PC = executable.reader->GetEntryPoint();
+
+      if (executable.reader->LoadSymbols() || LoadMapFromFilename())
+      {
+        UpdateDebugger_MapLoaded();
+        HLE::PatchFunctions();
+      }
       return true;
     }
 
@@ -495,3 +479,16 @@ bool CBoot::BootUp(std::unique_ptr<BootParameters> boot)
   HLE::PatchFixedFunctions();
   return true;
 }
+
+BootExecutableReader::BootExecutableReader(const std::string& file_name)
+{
+  m_bytes.resize(File::GetSize(file_name));
+  File::IOFile file{file_name, "rb"};
+  file.ReadBytes(m_bytes.data(), m_bytes.size());
+}
+
+BootExecutableReader::BootExecutableReader(const std::vector<u8>& bytes) : m_bytes(bytes)
+{
+}
+
+BootExecutableReader::~BootExecutableReader() = default;
diff --git a/Source/Core/Core/Boot/Boot.h b/Source/Core/Core/Boot/Boot.h
index 742bb056e5..562c067685 100644
--- a/Source/Core/Core/Boot/Boot.h
+++ b/Source/Core/Core/Boot/Boot.h
@@ -5,9 +5,11 @@
 #pragma once
 
 #include <cstdlib>
+#include <memory>
 #include <optional>
 #include <string>
 #include <variant>
+#include <vector>
 
 #include "Common/CommonTypes.h"
 #include "DiscIO/Enums.h"
@@ -21,6 +23,8 @@ struct RegionSetting
   const std::string code;
 };
 
+class BootExecutableReader;
+
 struct BootParameters
 {
   struct Disc
@@ -31,13 +35,8 @@ struct BootParameters
 
   struct Executable
   {
-    enum class Type
-    {
-      DOL,
-      ELF,
-    };
     std::string path;
-    Type type;
+    std::unique_ptr<BootExecutableReader> reader;
   };
 
   struct NAND
@@ -72,7 +71,6 @@ class CBoot
 {
 public:
   static bool BootUp(std::unique_ptr<BootParameters> boot);
-  static bool IsElfWii(const std::string& filename);
 
   // Tries to find a map file for the current game by looking first in the
   // local user directory, then in the shared user directory.
@@ -97,7 +95,6 @@ private:
 
   static void UpdateDebugger_MapLoaded();
 
-  static bool Boot_ELF(const std::string& filename);
   static bool Boot_WiiWAD(const std::string& filename);
 
   static void SetupMSR();
@@ -111,3 +108,20 @@ private:
 
   static bool SetupWiiMemory(const DiscIO::Volume* volume, u64 ios_title_id);
 };
+
+class BootExecutableReader
+{
+public:
+  BootExecutableReader(const std::string& file_name);
+  BootExecutableReader(const std::vector<u8>& buffer);
+  virtual ~BootExecutableReader();
+
+  virtual u32 GetEntryPoint() const = 0;
+  virtual bool IsValid() const = 0;
+  virtual bool IsWii() const = 0;
+  virtual bool LoadIntoMemory(bool only_in_mem1 = false) const = 0;
+  virtual bool LoadSymbols() const = 0;
+
+protected:
+  std::vector<u8> m_bytes;
+};
diff --git a/Source/Core/Core/Boot/Boot_ELF.cpp b/Source/Core/Core/Boot/Boot_ELF.cpp
deleted file mode 100644
index 1cef0937ba..0000000000
--- a/Source/Core/Core/Boot/Boot_ELF.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2008 Dolphin Emulator Project
-// Licensed under GPLv2+
-// Refer to the license.txt file included.
-
-#include <memory>
-
-#include "Common/FileUtil.h"
-#include "Common/Swap.h"
-#include "Core/Boot/Boot.h"
-#include "Core/Boot/ElfReader.h"
-#include "Core/HLE/HLE.h"
-#include "Core/PowerPC/PowerPC.h"
-
-bool CBoot::IsElfWii(const std::string& filename)
-{
-  /* We already check if filename existed before we called this function, so
-     there is no need for another check, just read the file right away */
-
-  size_t filesize = File::GetSize(filename);
-  auto elf = std::make_unique<u8[]>(filesize);
-
-  {
-    File::IOFile f(filename, "rb");
-    f.ReadBytes(elf.get(), filesize);
-  }
-
-  // Use the same method as the DOL loader uses: search for mfspr from HID4,
-  // which should only be used in Wii ELFs.
-  //
-  // Likely to have some false positives/negatives, patches implementing a
-  // better heuristic are welcome.
-
-  // Swap these once, instead of swapping every word in the file.
-  u32 HID4_pattern = Common::swap32(0x7c13fba6);
-  u32 HID4_mask = Common::swap32(0xfc1fffff);
-  ElfReader reader(elf.get());
-
-  for (int i = 0; i < reader.GetNumSegments(); ++i)
-  {
-    if (reader.IsCodeSegment(i))
-    {
-      u32* code = (u32*)reader.GetSegmentPtr(i);
-      for (u32 j = 0; j < reader.GetSegmentSize(i) / sizeof(u32); ++j)
-      {
-        if ((code[j] & HID4_mask) == HID4_pattern)
-          return true;
-      }
-    }
-  }
-
-  return false;
-}
-
-bool CBoot::Boot_ELF(const std::string& filename)
-{
-  // Read ELF from file
-  size_t filesize = File::GetSize(filename);
-  auto elf = std::make_unique<u8[]>(filesize);
-
-  {
-    File::IOFile f(filename, "rb");
-    f.ReadBytes(elf.get(), filesize);
-  }
-
-  // Load ELF into GameCube Memory
-  ElfReader reader(elf.get());
-  if (!reader.LoadIntoMemory())
-    return false;
-
-  const bool is_wii = IsElfWii(filename);
-  if (is_wii)
-    HID4.SBE = 1;
-  SetupMSR();
-  SetupBAT(is_wii);
-
-  if (!reader.LoadSymbols())
-  {
-    if (LoadMapFromFilename())
-      HLE::PatchFunctions();
-  }
-  else
-  {
-    HLE::PatchFunctions();
-  }
-
-  PC = reader.GetEntryPoint();
-
-  return true;
-}
diff --git a/Source/Core/Core/Boot/Boot_DOL.cpp b/Source/Core/Core/Boot/DolReader.cpp
similarity index 75%
rename from Source/Core/Core/Boot/Boot_DOL.cpp
rename to Source/Core/Core/Boot/DolReader.cpp
index b86169744d..7f17696240 100644
--- a/Source/Core/Core/Boot/Boot_DOL.cpp
+++ b/Source/Core/Core/Boot/DolReader.cpp
@@ -2,7 +2,7 @@
 // Licensed under GPLv2+
 // Refer to the license.txt file included.
 
-#include "Core/Boot/Boot_DOL.h"
+#include "Core/Boot/DolReader.h"
 
 #include <cstring>
 #include <string>
@@ -12,29 +12,19 @@
 #include "Common/Swap.h"
 #include "Core/HW/Memmap.h"
 
-CDolLoader::CDolLoader(const std::vector<u8>& buffer)
+DolReader::DolReader(const std::vector<u8>& buffer) : BootExecutableReader(buffer)
 {
   m_is_valid = Initialize(buffer);
 }
 
-CDolLoader::CDolLoader(const std::string& filename)
+DolReader::DolReader(const std::string& filename) : BootExecutableReader(filename)
 {
-  const u64 size = File::GetSize(filename);
-  std::vector<u8> temp_buffer(size);
-
-  {
-    File::IOFile pStream(filename, "rb");
-    pStream.ReadBytes(temp_buffer.data(), temp_buffer.size());
-  }
-
-  m_is_valid = Initialize(temp_buffer);
+  m_is_valid = Initialize(m_bytes);
 }
 
-CDolLoader::~CDolLoader()
-{
-}
+DolReader::~DolReader() = default;
 
-bool CDolLoader::Initialize(const std::vector<u8>& buffer)
+bool DolReader::Initialize(const std::vector<u8>& buffer)
 {
   if (buffer.size() < sizeof(SDolHeader))
     return false;
@@ -97,17 +87,30 @@ bool CDolLoader::Initialize(const std::vector<u8>& buffer)
   return true;
 }
 
-void CDolLoader::Load() const
+bool DolReader::LoadIntoMemory(bool only_in_mem1) const
 {
+  if (!m_is_valid)
+    return false;
+
   // load all text (code) sections
   for (size_t i = 0; i < m_text_sections.size(); ++i)
-    if (!m_text_sections[i].empty())
+    if (!m_text_sections[i].empty() &&
+        !(only_in_mem1 &&
+          m_dolheader.textAddress[i] + m_text_sections[i].size() >= Memory::REALRAM_SIZE))
+    {
       Memory::CopyToEmu(m_dolheader.textAddress[i], m_text_sections[i].data(),
                         m_text_sections[i].size());
+    }
 
   // load all data sections
   for (size_t i = 0; i < m_data_sections.size(); ++i)
-    if (!m_data_sections[i].empty())
+    if (!m_data_sections[i].empty() &&
+        !(only_in_mem1 &&
+          m_dolheader.dataAddress[i] + m_data_sections[i].size() >= Memory::REALRAM_SIZE))
+    {
       Memory::CopyToEmu(m_dolheader.dataAddress[i], m_data_sections[i].data(),
                         m_data_sections[i].size());
+    }
+
+  return true;
 }
diff --git a/Source/Core/Core/Boot/Boot_DOL.h b/Source/Core/Core/Boot/DolReader.h
similarity index 63%
rename from Source/Core/Core/Boot/Boot_DOL.h
rename to Source/Core/Core/Boot/DolReader.h
index f415e35705..43b1c0f354 100644
--- a/Source/Core/Core/Boot/Boot_DOL.h
+++ b/Source/Core/Core/Boot/DolReader.h
@@ -8,20 +8,20 @@
 #include <vector>
 
 #include "Common/CommonTypes.h"
+#include "Core/Boot/Boot.h"
 
-class CDolLoader
+class DolReader final : public BootExecutableReader
 {
 public:
-  CDolLoader(const std::string& filename);
-  CDolLoader(const std::vector<u8>& buffer);
-  ~CDolLoader();
-
-  bool IsValid() const { return m_is_valid; }
-  bool IsWii() const { return m_is_wii; }
-  u32 GetEntryPoint() const { return m_dolheader.entryPoint; }
-  // Load into emulated memory
-  void Load() const;
+  DolReader(const std::string& filename);
+  DolReader(const std::vector<u8>& buffer);
+  ~DolReader();
 
+  bool IsValid() const override { return m_is_valid; }
+  bool IsWii() const override { return m_is_wii; }
+  u32 GetEntryPoint() const override { return m_dolheader.entryPoint; }
+  bool LoadIntoMemory(bool only_in_mem1 = false) const override;
+  bool LoadSymbols() const override { return false; }
 private:
   enum
   {
diff --git a/Source/Core/Core/Boot/ElfReader.cpp b/Source/Core/Core/Boot/ElfReader.cpp
index 91eeba7487..4f9297b06d 100644
--- a/Source/Core/Core/Boot/ElfReader.cpp
+++ b/Source/Core/Core/Boot/ElfReader.cpp
@@ -66,7 +66,17 @@ static void byteswapSection(Elf32_Shdr& sec)
   bswap(sec.sh_type);
 }
 
-ElfReader::ElfReader(void* ptr)
+ElfReader::ElfReader(const std::vector<u8>& buffer) : BootExecutableReader(buffer)
+{
+  Initialize(m_bytes.data());
+}
+
+ElfReader::ElfReader(const std::string& filename) : BootExecutableReader(filename)
+{
+  Initialize(m_bytes.data());
+}
+
+void ElfReader::Initialize(u8* ptr)
 {
   base = (char*)ptr;
   base32 = (u32*)ptr;
@@ -86,6 +96,8 @@ ElfReader::ElfReader(void* ptr)
     byteswapSection(sections[i]);
   }
   entryPoint = header->e_entry;
+
+  bRelocate = (header->e_type != ET_EXEC);
 }
 
 const char* ElfReader::GetSectionName(int section) const
@@ -103,13 +115,10 @@ const char* ElfReader::GetSectionName(int section) const
 }
 
 // This is just a simple elf loader, good enough to load elfs generated by devkitPPC
-bool ElfReader::LoadIntoMemory(bool only_in_mem1)
+bool ElfReader::LoadIntoMemory(bool only_in_mem1) const
 {
   INFO_LOG(MASTER_LOG, "String section: %i", header->e_shstrndx);
 
-  // Should we relocate?
-  bRelocate = (header->e_type != ET_EXEC);
-
   if (bRelocate)
   {
     PanicAlert("Error: Dolphin doesn't know how to load a relocatable elf.");
@@ -160,7 +169,7 @@ SectionID ElfReader::GetSectionByName(const char* name, int firstSection) const
   return -1;
 }
 
-bool ElfReader::LoadSymbols()
+bool ElfReader::LoadSymbols() const
 {
   bool hasSymbols = false;
   SectionID sec = GetSectionByName(".symtab");
@@ -205,3 +214,31 @@ bool ElfReader::LoadSymbols()
   g_symbolDB.Index();
   return hasSymbols;
 }
+
+bool ElfReader::IsWii() const
+{
+  // Use the same method as the DOL loader uses: search for mfspr from HID4,
+  // which should only be used in Wii ELFs.
+  //
+  // Likely to have some false positives/negatives, patches implementing a
+  // better heuristic are welcome.
+
+  // Swap these once, instead of swapping every word in the file.
+  u32 HID4_pattern = Common::swap32(0x7c13fba6);
+  u32 HID4_mask = Common::swap32(0xfc1fffff);
+
+  for (int i = 0; i < GetNumSegments(); ++i)
+  {
+    if (IsCodeSegment(i))
+    {
+      u32* code = (u32*)GetSegmentPtr(i);
+      for (u32 j = 0; j < GetSegmentSize(i) / sizeof(u32); ++j)
+      {
+        if ((code[j] & HID4_mask) == HID4_pattern)
+          return true;
+      }
+    }
+  }
+
+  return false;
+}
diff --git a/Source/Core/Core/Boot/ElfReader.h b/Source/Core/Core/Boot/ElfReader.h
index e3d7c257a8..014d0667c3 100644
--- a/Source/Core/Core/Boot/ElfReader.h
+++ b/Source/Core/Core/Boot/ElfReader.h
@@ -5,6 +5,7 @@
 #pragma once
 
 #include "Common/CommonTypes.h"
+#include "Core/Boot/Boot.h"
 #include "Core/Boot/ElfTypes.h"
 
 enum KnownElfTypes
@@ -17,31 +18,23 @@ enum KnownElfTypes
 
 typedef int SectionID;
 
-class ElfReader
+class ElfReader final : public BootExecutableReader
 {
-private:
-  char* base;
-  u32* base32;
-
-  Elf32_Ehdr* header;
-  Elf32_Phdr* segments;
-  Elf32_Shdr* sections;
-
-  u32* sectionAddrs;
-  bool bRelocate;
-  u32 entryPoint;
-
 public:
-  explicit ElfReader(void* ptr);
+  ElfReader(const std::string& filename);
+  ElfReader(const std::vector<u8>& buffer);
   ~ElfReader() {}
   u32 Read32(int off) const { return base32[off >> 2]; }
   // Quick accessors
   ElfType GetType() const { return (ElfType)(header->e_type); }
   ElfMachine GetMachine() const { return (ElfMachine)(header->e_machine); }
-  u32 GetEntryPoint() const { return entryPoint; }
+  u32 GetEntryPoint() const override { return entryPoint; }
   u32 GetFlags() const { return (u32)(header->e_flags); }
-  bool LoadIntoMemory(bool only_in_mem1 = false);
-  bool LoadSymbols();
+  bool LoadIntoMemory(bool only_in_mem1 = false) const override;
+  bool LoadSymbols() const override;
+  // TODO: actually check for validity.
+  bool IsValid() const override { return true; }
+  bool IsWii() const override;
 
   int GetNumSegments() const { return (int)(header->e_phnum); }
   int GetNumSections() const { return (int)(header->e_shnum); }
@@ -57,11 +50,24 @@ public:
       return nullptr;
   }
   bool IsCodeSegment(int segment) const { return segments[segment].p_flags & PF_X; }
-  const u8* GetSegmentPtr(int segment) { return GetPtr(segments[segment].p_offset); }
+  const u8* GetSegmentPtr(int segment) const { return GetPtr(segments[segment].p_offset); }
   int GetSegmentSize(int segment) const { return segments[segment].p_filesz; }
   u32 GetSectionAddr(SectionID section) const { return sectionAddrs[section]; }
   int GetSectionSize(SectionID section) const { return sections[section].sh_size; }
   SectionID GetSectionByName(const char* name, int firstSection = 0) const;  //-1 for not found
 
   bool DidRelocate() const { return bRelocate; }
+private:
+  void Initialize(u8* bytes);
+
+  char* base;
+  u32* base32;
+
+  Elf32_Ehdr* header;
+  Elf32_Phdr* segments;
+  Elf32_Shdr* sections;
+
+  u32* sectionAddrs;
+  bool bRelocate;
+  u32 entryPoint;
 };
diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt
index e3684b891d..b29f42fef8 100644
--- a/Source/Core/Core/CMakeLists.txt
+++ b/Source/Core/Core/CMakeLists.txt
@@ -21,9 +21,8 @@ set(SRCS
   WiiRoot.cpp
   Boot/Boot_BS2Emu.cpp
   Boot/Boot.cpp
-  Boot/Boot_DOL.cpp
-  Boot/Boot_ELF.cpp
   Boot/Boot_WiiWAD.cpp
+  Boot/DolReader.cpp
   Boot/ElfReader.cpp
   Config/Config.cpp
   Config/GraphicsSettings.cpp
diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp
index 342cb60527..b94f06e820 100644
--- a/Source/Core/Core/ConfigManager.cpp
+++ b/Source/Core/Core/ConfigManager.cpp
@@ -23,7 +23,6 @@
 
 #include "Core/Analytics.h"
 #include "Core/Boot/Boot.h"
-#include "Core/Boot/Boot_DOL.h"
 #include "Core/Config/Config.h"
 #include "Core/ConfigManager.h"
 #include "Core/Core.h"
@@ -896,10 +895,10 @@ struct SetGameMetadata
 
   bool operator()(const BootParameters::Executable& executable) const
   {
-    if (executable.type == BootParameters::Executable::Type::DOL)
-      config->bWii = CDolLoader{executable.path}.IsWii();
-    if (executable.type == BootParameters::Executable::Type::ELF)
-      config->bWii = CBoot::IsElfWii(executable.path);
+    if (!executable.reader->IsValid())
+      return false;
+
+    config->bWii = executable.reader->IsWii();
 
     // TODO: Right now GC homebrew boots in NTSC and Wii homebrew in PAL.
     // This is intentional so that Wii homebrew can boot in both 50Hz and 60Hz,
diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj
index 6616031f96..7fccbc5fed 100644
--- a/Source/Core/Core/Core.vcxproj
+++ b/Source/Core/Core/Core.vcxproj
@@ -52,9 +52,8 @@
     <ClCompile Include="BootManager.cpp" />
     <ClCompile Include="Boot\Boot.cpp" />
     <ClCompile Include="Boot\Boot_BS2Emu.cpp" />
-    <ClCompile Include="Boot\Boot_DOL.cpp" />
-    <ClCompile Include="Boot\Boot_ELF.cpp" />
     <ClCompile Include="Boot\Boot_WiiWAD.cpp" />
+    <ClCompile Include="Boot\DolReader.cpp" />
     <ClCompile Include="Boot\ElfReader.cpp" />
     <ClCompile Include="Config\Config.cpp" />
     <ClCompile Include="Config\GraphicsSettings.cpp" />
@@ -308,7 +307,7 @@
     <ClInclude Include="ARDecrypt.h" />
     <ClInclude Include="BootManager.h" />
     <ClInclude Include="Boot\Boot.h" />
-    <ClInclude Include="Boot\Boot_DOL.h" />
+    <ClInclude Include="Boot\DolReader.h" />
     <ClInclude Include="Boot\ElfReader.h" />
     <ClInclude Include="Boot\ElfTypes.h" />
     <ClInclude Include="Config\Config.h" />
@@ -583,4 +582,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters
index 27485da41f..a0a74fc073 100644
--- a/Source/Core/Core/Core.vcxproj.filters
+++ b/Source/Core/Core/Core.vcxproj.filters
@@ -182,15 +182,12 @@
     <ClCompile Include="Boot\Boot_BS2Emu.cpp">
       <Filter>Boot</Filter>
     </ClCompile>
-    <ClCompile Include="Boot\Boot_DOL.cpp">
-      <Filter>Boot</Filter>
-    </ClCompile>
-    <ClCompile Include="Boot\Boot_ELF.cpp">
-      <Filter>Boot</Filter>
-    </ClCompile>
     <ClCompile Include="Boot\Boot_WiiWAD.cpp">
       <Filter>Boot</Filter>
     </ClCompile>
+    <ClCompile Include="Boot\DolReader.cpp">
+      <Filter>Boot</Filter>
+    </ClCompile>
     <ClCompile Include="Boot\ElfReader.cpp">
       <Filter>Boot</Filter>
     </ClCompile>
@@ -888,7 +885,7 @@
     <ClInclude Include="Boot\Boot.h">
       <Filter>Boot</Filter>
     </ClInclude>
-    <ClInclude Include="Boot\Boot_DOL.h">
+    <ClInclude Include="Boot\DolReader.h">
       <Filter>Boot</Filter>
     </ClInclude>
     <ClInclude Include="Boot\ElfReader.h">
diff --git a/Source/Core/Core/IOS/IOS.cpp b/Source/Core/Core/IOS/IOS.cpp
index abbc7b2444..56cb56ae10 100644
--- a/Source/Core/Core/IOS/IOS.cpp
+++ b/Source/Core/Core/IOS/IOS.cpp
@@ -18,7 +18,7 @@
 #include "Common/ChunkFile.h"
 #include "Common/CommonTypes.h"
 #include "Common/Logging/Log.h"
-#include "Core/Boot/Boot_DOL.h"
+#include "Core/Boot/DolReader.h"
 #include "Core/ConfigManager.h"
 #include "Core/Core.h"
 #include "Core/CoreTiming.h"
@@ -282,14 +282,15 @@ bool Kernel::BootstrapPPC(const DiscIO::NANDContentLoader& content_loader)
   if (!content)
     return false;
 
-  const auto dol_loader = std::make_unique<CDolLoader>(content->m_Data->Get());
+  const auto dol_loader = std::make_unique<DolReader>(content->m_Data->Get());
   if (!dol_loader->IsValid())
     return false;
 
   if (!SetupMemory(m_title_id, MemorySetupType::Full))
     return false;
 
-  dol_loader->Load();
+  if (!dol_loader->LoadIntoMemory())
+    return false;
 
   // NAND titles start with address translation off at 0x3400 (via the PPC bootstub)
   // The state of other CPU registers (like the BAT registers) doesn't matter much
diff --git a/Source/Core/Core/IOS/MIOS.cpp b/Source/Core/Core/IOS/MIOS.cpp
index 57f9451d43..47a4fd5f6d 100644
--- a/Source/Core/Core/IOS/MIOS.cpp
+++ b/Source/Core/Core/IOS/MIOS.cpp
@@ -134,8 +134,7 @@ bool Load()
     return false;
   }
 
-  std::vector<u8> elf_bytes = mios.GetElf();
-  ElfReader elf{elf_bytes.data()};
+  ElfReader elf{mios.GetElf()};
   if (!elf.LoadIntoMemory(true))
   {
     PanicAlertT("Failed to load MIOS ELF into memory.");

From 6f6a18b1b0390a8def05f34b14ffcb99d7baa365 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?L=C3=A9o=20Lam?= <leo@innovatetechnologi.es>
Date: Sun, 28 May 2017 17:15:30 +0200
Subject: [PATCH 06/57] Boot: Remove unneeded manual HLE function scan

Not needed. And the symbols would get overwritten by the symbol map
load that is just below.
---
 Source/Core/Core/Boot/Boot.cpp | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp
index 65394fd05f..63d249d625 100644
--- a/Source/Core/Core/Boot/Boot.cpp
+++ b/Source/Core/Core/Boot/Boot.cpp
@@ -347,19 +347,6 @@ bool CBoot::BootUp(std::unique_ptr<BootParameters> boot)
       if (!EmulatedBS2(config.bWii, volume))
         return false;
 
-      // Scan for common HLE functions
-      if (!config.bEnableDebugging)
-      {
-        PPCAnalyst::FindFunctions(0x80004000, 0x811fffff, &g_symbolDB);
-        SignatureDB db(SignatureDB::HandlerType::DSY);
-        if (db.Load(File::GetSysDirectory() + TOTALDB))
-        {
-          db.Apply(&g_symbolDB);
-          HLE::PatchFunctions();
-          db.Clear();
-        }
-      }
-
       // Try to load the symbol map if there is one, and then scan it for
       // and eventually replace code
       if (LoadMapFromFilename())

From d0169fe8db0f11c7837f704241ac7e3f4b327724 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?L=C3=A9o=20Lam?= <leo@innovatetechnologi.es>
Date: Tue, 30 May 2017 11:16:20 +0200
Subject: [PATCH 07/57] Boot: Re-use the disc volume

Saves some disc IO.
---
 Source/Core/Core/Boot/Boot.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp
index 63d249d625..aec784cec3 100644
--- a/Source/Core/Core/Boot/Boot.cpp
+++ b/Source/Core/Core/Boot/Boot.cpp
@@ -336,10 +336,10 @@ bool CBoot::BootUp(std::unique_ptr<BootParameters> boot)
   struct BootTitle
   {
     BootTitle() : config(SConfig::GetInstance()) {}
-    bool operator()(const BootParameters::Disc& disc) const
+    bool operator()(BootParameters::Disc& disc) const
     {
       NOTICE_LOG(BOOT, "Booting from disc: %s", disc.path.c_str());
-      const DiscIO::Volume* volume = SetDisc(DiscIO::CreateVolumeFromFilename(disc.path));
+      const DiscIO::Volume* volume = SetDisc(std::move(disc.volume));
 
       if (!volume)
         return false;

From 9a3fb858f31e159ab76bee4cb8944489997a44fa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?L=C3=A9o=20Lam?= <leo@innovatetechnologi.es>
Date: Mon, 5 Jun 2017 00:08:58 +0200
Subject: [PATCH 08/57] EXI: Always try to load IPL in GameCube mode

I don't see any reason to disable loading the IPL if bHLE_BS2 is
disabled. bHLE_BS2 should only cause us not to run the IPL, but not
skip loading it in the first place. More importantly, without always
loading it, this causes issues when trying to launch only the GC IPL
while having bHLE_BS2 = false.
---
 Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp | 29 +++++++++++++----------
 Source/Core/Core/HW/EXI/EXI_DeviceIPL.h   |  2 +-
 2 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp b/Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp
index 528ed351f5..0cf6bbfc38 100644
--- a/Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp
+++ b/Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp
@@ -98,9 +98,18 @@ CEXIIPL::CEXIIPL() : m_uPosition(0), m_uAddress(0), m_uRWOffset(0), m_FontsLoade
   // Create the IPL
   m_pIPL = static_cast<u8*>(Common::AllocateMemoryPages(ROM_SIZE));
 
-  // The Wii doesn't have a copy of the IPL, only fonts.
-  if (SConfig::GetInstance().bWii || SConfig::GetInstance().bHLE_BS2)
+  // Load whole ROM dump
+  // Note: The Wii doesn't have a copy of the IPL, only fonts.
+  if (!SConfig::GetInstance().bWii && LoadFileToIPL(SConfig::GetInstance().m_strBootROM, 0))
   {
+    // Descramble the encrypted section (contains BS1 and BS2)
+    Descrambler(m_pIPL + 0x100, 0x1afe00);
+    INFO_LOG(BOOT, "Loaded bootrom: %s", m_pIPL);  // yay for null-terminated strings ;p
+  }
+  else
+  {
+    // If we are in Wii mode or if loading the GC IPL fails, we should still try to load fonts.
+
     // Copy header
     if (DiscIO::IsNTSC(SConfig::GetInstance().m_region))
       memcpy(m_pIPL, iplverNTSC, sizeof(iplverNTSC));
@@ -111,14 +120,6 @@ CEXIIPL::CEXIIPL() : m_uPosition(0), m_uAddress(0), m_uRWOffset(0), m_FontsLoade
     LoadFontFile((File::GetSysDirectory() + GC_SYS_DIR + DIR_SEP + FONT_SHIFT_JIS), 0x1aff00);
     LoadFontFile((File::GetSysDirectory() + GC_SYS_DIR + DIR_SEP + FONT_WINDOWS_1252), 0x1fcf00);
   }
-  else
-  {
-    // Load whole ROM dump
-    LoadFileToIPL(SConfig::GetInstance().m_strBootROM, 0);
-    // Descramble the encrypted section (contains BS1 and BS2)
-    Descrambler(m_pIPL + 0x100, 0x1afe00);
-    INFO_LOG(BOOT, "Loaded bootrom: %s", m_pIPL);  // yay for null-terminated strings ;p
-  }
 
   // Clear RTC
   memset(m_RTC, 0, sizeof(m_RTC));
@@ -158,17 +159,19 @@ void CEXIIPL::DoState(PointerWrap& p)
   p.Do(m_FontsLoaded);
 }
 
-void CEXIIPL::LoadFileToIPL(const std::string& filename, u32 offset)
+bool CEXIIPL::LoadFileToIPL(const std::string& filename, u32 offset)
 {
   File::IOFile stream(filename, "rb");
   if (!stream)
-    return;
+    return false;
 
   u64 filesize = stream.GetSize();
 
-  stream.ReadBytes(m_pIPL + offset, filesize);
+  if (!stream.ReadBytes(m_pIPL + offset, filesize))
+    return false;
 
   m_FontsLoaded = true;
+  return true;
 }
 
 std::string CEXIIPL::FindIPLDump(const std::string& path_prefix)
diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceIPL.h b/Source/Core/Core/HW/EXI/EXI_DeviceIPL.h
index 031001e6f6..ea2d7093e2 100644
--- a/Source/Core/Core/HW/EXI/EXI_DeviceIPL.h
+++ b/Source/Core/Core/HW/EXI/EXI_DeviceIPL.h
@@ -74,7 +74,7 @@ private:
   void TransferByte(u8& _uByte) override;
   bool IsWriteCommand() const { return !!(m_uAddress & (1 << 31)); }
   u32 CommandRegion() const { return (m_uAddress & ~(1 << 31)) >> 8; }
-  void LoadFileToIPL(const std::string& filename, u32 offset);
+  bool LoadFileToIPL(const std::string& filename, u32 offset);
   void LoadFontFile(const std::string& filename, u32 offset);
   std::string FindIPLDump(const std::string& path_prefix);
 };

From d50b4406a66f1d9e09ad095df38fae9d57a3a729 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?L=C3=A9o=20Lam?= <leo@innovatetechnologi.es>
Date: Mon, 5 Jun 2017 13:55:54 +0200
Subject: [PATCH 09/57] Boot: Restore symbol map loading

---
 Source/Core/Core/Boot/Boot.cpp                  |  8 ++------
 Source/Core/Core/Boot/Boot.h                    |  5 +----
 Source/Core/Core/ConfigManager.cpp              | 17 +++++++++++++++++
 Source/Core/Core/ConfigManager.h                |  1 +
 .../DolphinWX/Debugger/CodeWindowFunctions.cpp  |  5 +++--
 5 files changed, 24 insertions(+), 12 deletions(-)

diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp
index aec784cec3..e428129226 100644
--- a/Source/Core/Core/Boot/Boot.cpp
+++ b/Source/Core/Core/Boot/Boot.cpp
@@ -178,17 +178,13 @@ void CBoot::UpdateDebugger_MapLoaded()
 }
 
 // Get map file paths for the active title.
-bool CBoot::FindMapFile(std::string* existing_map_file, std::string* writable_map_file,
-                        std::string* title_id)
+bool CBoot::FindMapFile(std::string* existing_map_file, std::string* writable_map_file)
 {
-  const std::string game_id = SConfig::GetInstance().GetGameID();
+  const std::string& game_id = SConfig::GetInstance().m_debugger_game_id;
 
   if (writable_map_file)
     *writable_map_file = File::GetUserPath(D_MAPS_IDX) + game_id + ".map";
 
-  if (title_id)
-    *title_id = game_id;
-
   bool found = false;
   static const std::string maps_directories[] = {File::GetUserPath(D_MAPS_IDX),
                                                  File::GetSysDirectory() + MAPS_DIR DIR_SEP};
diff --git a/Source/Core/Core/Boot/Boot.h b/Source/Core/Core/Boot/Boot.h
index 562c067685..a178edaf75 100644
--- a/Source/Core/Core/Boot/Boot.h
+++ b/Source/Core/Core/Boot/Boot.h
@@ -81,11 +81,8 @@ public:
   // If writable_map_file is not nullptr, it is set to the path to where a map
   // file should be saved.
   //
-  // If title_id is not nullptr, it is set to the title id
-  //
   // Returns true if a map file exists, false if none could be found.
-  static bool FindMapFile(std::string* existing_map_file, std::string* writable_map_file,
-                          std::string* title_id = nullptr);
+  static bool FindMapFile(std::string* existing_map_file, std::string* writable_map_file);
   static bool LoadMapFromFilename();
 
 private:
diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp
index b94f06e820..b63702b6d2 100644
--- a/Source/Core/Core/ConfigManager.cpp
+++ b/Source/Core/Core/ConfigManager.cpp
@@ -753,6 +753,20 @@ void SConfig::SetRunningGameMetadata(const std::string& game_id, u64 title_id, u
   m_title_id = title_id;
   m_revision = revision;
 
+  if (game_id.length() == 6)
+  {
+    m_debugger_game_id = game_id;
+  }
+  else if (title_id != 0)
+  {
+    m_debugger_game_id =
+        StringFromFormat("%08X_%08X", static_cast<u32>(title_id >> 32), static_cast<u32>(title_id));
+  }
+  else
+  {
+    m_debugger_game_id.clear();
+  }
+
   if (!was_changed)
     return;
 
@@ -906,6 +920,9 @@ struct SetGameMetadata
     // In the future, it probably makes sense to add a Region setting for homebrew somewhere in
     // the emulator config.
     *region = config->bWii ? DiscIO::Region::PAL : DiscIO::Region::NTSC_U;
+
+    // Strip the .elf/.dol file extension and directories before the name
+    SplitPath(executable.path, nullptr, &config->m_debugger_game_id, nullptr);
     return true;
   }
 
diff --git a/Source/Core/Core/ConfigManager.h b/Source/Core/Core/ConfigManager.h
index 3fd85fdfb9..69947125fc 100644
--- a/Source/Core/Core/ConfigManager.h
+++ b/Source/Core/Core/ConfigManager.h
@@ -202,6 +202,7 @@ struct SConfig : NonCopyable
 
   std::string m_perfDir;
 
+  std::string m_debugger_game_id;
   // TODO: remove this as soon as the ticket view hack in IOS/ES/Views is dropped.
   bool m_disc_booted_from_game_list = false;
 
diff --git a/Source/Core/DolphinWX/Debugger/CodeWindowFunctions.cpp b/Source/Core/DolphinWX/Debugger/CodeWindowFunctions.cpp
index ffca4d0273..2452e85b38 100644
--- a/Source/Core/DolphinWX/Debugger/CodeWindowFunctions.cpp
+++ b/Source/Core/DolphinWX/Debugger/CodeWindowFunctions.cpp
@@ -173,8 +173,9 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event)
   if (!Core::IsRunning())
     return;
 
-  std::string existing_map_file, writable_map_file, title_id_str;
-  bool map_exists = CBoot::FindMapFile(&existing_map_file, &writable_map_file, &title_id_str);
+  const std::string& title_id_str = SConfig::GetInstance().m_debugger_game_id;
+  std::string existing_map_file, writable_map_file;
+  bool map_exists = CBoot::FindMapFile(&existing_map_file, &writable_map_file);
   switch (event.GetId())
   {
   case IDM_CLEAR_SYMBOLS:

From a2dfd9750f056e9fdb6c2fd5184abf3086773015 Mon Sep 17 00:00:00 2001
From: Brayden Banks <bb010g@gmail.com>
Date: Tue, 6 Jun 2017 09:45:44 -0700
Subject: [PATCH 10/57] EditorConfig: Don't enforce a specific line ending

---
 .editorconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/.editorconfig b/.editorconfig
index a2ef9da067..a42588d1a6 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,7 +1,6 @@
 root = true
 
 [*]
-end_of_line = lf
 indent_size = 2
 trim_trailing_whitespace = true
 

From c07058a4ada4ca28c1621b50c9af3da7c70a0a65 Mon Sep 17 00:00:00 2001
From: Leo Lam <leolino.lam@gmail.com>
Date: Tue, 6 Jun 2017 22:14:30 +0200
Subject: [PATCH 11/57] Don't show CPU and file related OSD messages on boot
 (#5533)

They have been broken since 2 years and no one has noticed,
which shows that no one really cares.

And it's arguable whether showing the CPU info is really useful.
---
 Source/Core/Core/Core.cpp | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp
index bdddfbadb4..5c2be41259 100644
--- a/Source/Core/Core/Core.cpp
+++ b/Source/Core/Core/Core.cpp
@@ -468,11 +468,6 @@ static void EmuThread(std::unique_ptr<BootParameters> boot)
 
   Common::SetCurrentThreadName("Emuthread - Starting");
 
-  if (SConfig::GetInstance().m_OCEnable)
-    DisplayMessage("WARNING: running at non-native CPU clock! Game may not be stable.", 8000);
-  DisplayMessage(cpu_info.brand_string, 8000);
-  DisplayMessage(cpu_info.Summarize(), 8000);
-
   // For a time this acts as the CPU thread...
   DeclareAsCPUThread();
 

From 3bfebf396a040ebec81d87fb15fa6ab27cc9241b Mon Sep 17 00:00:00 2001
From: Michael Maltese <mchtly@gmail.com>
Date: Thu, 30 Mar 2017 13:52:38 -0700
Subject: [PATCH 12/57] Fix OpenAL backend on macOS

OpenALStream was querying the backend for AL_EXT_float32 support (which
suceeds), but AL_FORMAT_STEREO_FLOAT32 was defined incorrectly.

Also changes OpenALStream to query for AL_EXT_MCFORMATS (multichannel
support) rather than hard-coding that it doesn't work on macOS.
---
 Source/Core/AudioCommon/OpenALStream.cpp | 22 +++++++---------------
 Source/Core/AudioCommon/OpenALStream.h   | 24 ++++++++++++++----------
 2 files changed, 21 insertions(+), 25 deletions(-)

diff --git a/Source/Core/AudioCommon/OpenALStream.cpp b/Source/Core/AudioCommon/OpenALStream.cpp
index ca343be005..b923522799 100644
--- a/Source/Core/AudioCommon/OpenALStream.cpp
+++ b/Source/Core/AudioCommon/OpenALStream.cpp
@@ -159,13 +159,14 @@ void OpenALStream::SoundLoop()
 {
   Common::SetCurrentThreadName("Audio thread - openal");
 
-  bool surround_capable = SConfig::GetInstance().bDPL2Decoder;
-  bool float32_capable = false;
-  bool fixed32_capable = false;
+  bool float32_capable = alIsExtensionPresent("AL_EXT_float32") != 0;
+  bool surround_capable =
+      SConfig::GetInstance().bDPL2Decoder && alIsExtensionPresent("AL_EXT_MCFORMATS");
 
-#if defined(__APPLE__)
-  surround_capable = false;
-#endif
+  // As there is no extension to check for 32-bit fixed point support
+  // and we know that only a X-Fi with hardware OpenAL supports it,
+  // we just check if one is being used.
+  bool fixed32_capable = strstr(alGetString(AL_RENDERER), "X-Fi") != nullptr;
 
   u32 ulFrequency = m_mixer->GetSampleRate();
   numBuffers = SConfig::GetInstance().iLatency + 2;  // OpenAL requires a minimum of two buffers
@@ -173,15 +174,6 @@ void OpenALStream::SoundLoop()
   memset(uiBuffers, 0, numBuffers * sizeof(ALuint));
   uiSource = 0;
 
-  if (alIsExtensionPresent("AL_EXT_float32"))
-    float32_capable = true;
-
-  // As there is no extension to check for 32-bit fixed point support
-  // and we know that only a X-Fi with hardware OpenAL supports it,
-  // we just check if one is being used.
-  if (strstr(alGetString(AL_RENDERER), "X-Fi"))
-    fixed32_capable = true;
-
   // Clear error state before querying or else we get false positives.
   ALenum err = alGetError();
 
diff --git a/Source/Core/AudioCommon/OpenALStream.h b/Source/Core/AudioCommon/OpenALStream.h
index 6d32a37adb..5e4b49c027 100644
--- a/Source/Core/AudioCommon/OpenALStream.h
+++ b/Source/Core/AudioCommon/OpenALStream.h
@@ -42,19 +42,23 @@
 #define FRAME_SURROUND_INT32 SURROUND_CHANNELS* SIZE_INT32
 #endif
 
-#if defined(__APPLE__)
-// OS X does not have the alext AL_FORMAT_STEREO_FLOAT32, AL_FORMAT_STEREO32,
-// AL_FORMAT_51CHN32 and AL_FORMAT_51CHN16 yet.
-#define AL_FORMAT_STEREO_FLOAT32 0
-#define AL_FORMAT_STEREO32 0
-#define AL_FORMAT_51CHN32 0
-#define AL_FORMAT_51CHN16 0
-#elif defined(_WIN32)
+// From AL_EXT_float32
+#ifndef AL_FORMAT_STEREO_FLOAT32
+#define AL_FORMAT_STEREO_FLOAT32 0x10011
+#endif
+
+// From AL_EXT_MCFORMATS
+#ifndef AL_FORMAT_51CHN16
+#define AL_FORMAT_51CHN16 0x120B
+#endif
+#ifndef AL_FORMAT_51CHN32
+#define AL_FORMAT_51CHN32 0x120C
+#endif
+
 // Only X-Fi on Windows supports the alext AL_FORMAT_STEREO32 alext for now,
 // but it is not documented or in "OpenAL/include/al.h".
+#ifndef AL_FORMAT_STEREO32
 #define AL_FORMAT_STEREO32 0x1203
-#else
-#define AL_FORMAT_STEREO32 0
 #endif
 
 class OpenALStream final : public SoundStream

From 60f4f499e8587514409b6de91013e725adce3ce4 Mon Sep 17 00:00:00 2001
From: Michael Maltese <mchtly@gmail.com>
Date: Tue, 6 Jun 2017 15:21:22 -0700
Subject: [PATCH 13/57] OpenAL: hardcode that X-Fi supports surround

---
 Source/Core/AudioCommon/OpenALStream.cpp | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/Source/Core/AudioCommon/OpenALStream.cpp b/Source/Core/AudioCommon/OpenALStream.cpp
index b923522799..25dd14e7b2 100644
--- a/Source/Core/AudioCommon/OpenALStream.cpp
+++ b/Source/Core/AudioCommon/OpenALStream.cpp
@@ -155,18 +155,23 @@ static ALenum CheckALError(const char* desc)
   return err;
 }
 
+static bool IsCreativeXFi()
+{
+  return strstr(alGetString(AL_RENDERER), "X-Fi") != nullptr;
+}
+
 void OpenALStream::SoundLoop()
 {
   Common::SetCurrentThreadName("Audio thread - openal");
 
   bool float32_capable = alIsExtensionPresent("AL_EXT_float32") != 0;
-  bool surround_capable =
-      SConfig::GetInstance().bDPL2Decoder && alIsExtensionPresent("AL_EXT_MCFORMATS");
+  bool surround_capable = alIsExtensionPresent("AL_EXT_MCFORMATS") || IsCreativeXFi();
+  bool use_surround = SConfig::GetInstance().bDPL2Decoder && surround_capable;
 
   // As there is no extension to check for 32-bit fixed point support
   // and we know that only a X-Fi with hardware OpenAL supports it,
   // we just check if one is being used.
-  bool fixed32_capable = strstr(alGetString(AL_RENDERER), "X-Fi") != nullptr;
+  bool fixed32_capable = IsCreativeXFi();
 
   u32 ulFrequency = m_mixer->GetSampleRate();
   numBuffers = SConfig::GetInstance().iLatency + 2;  // OpenAL requires a minimum of two buffers
@@ -218,7 +223,7 @@ void OpenALStream::SoundLoop()
 
     unsigned int numSamples = OAL_MAX_SAMPLES;
 
-    if (surround_capable)
+    if (use_surround)
     {
       // DPL2 accepts 240 samples minimum (FWRDURATION)
       unsigned int minSamples = 240;
@@ -289,7 +294,7 @@ void OpenALStream::SoundLoop()
         // 5.1 is not supported by the host, fallback to stereo
         WARN_LOG(AUDIO,
                  "Unable to set 5.1 surround mode.  Updating OpenAL Soft might fix this issue.");
-        surround_capable = false;
+        use_surround = false;
       }
     }
     else

From 1ffc311bf32fa66188bc3551a92ed467bbff84fa Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Tue, 6 Jun 2017 20:27:40 -0400
Subject: [PATCH 14/57] Core: Fix vcxproj filter

This would cause the core project to fail to load.
---
 Source/Core/Core/Core.vcxproj.filters | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters
index a0a74fc073..b35e104119 100644
--- a/Source/Core/Core/Core.vcxproj.filters
+++ b/Source/Core/Core/Core.vcxproj.filters
@@ -290,7 +290,7 @@
     <ClCompile Include="HLE\HLE_OS.cpp">
       <Filter>HLE</Filter>
     </ClCompile>
-    <ClCompile Include="HLE\HLE_VarArgs.cpp" />
+    <ClCompile Include="HLE\HLE_VarArgs.cpp">
       <Filter>HLE</Filter>
     </ClCompile>
     <ClCompile Include="PowerPC\BreakPoints.cpp">

From e5260dee6bed97f1f59eba65407fe767f5ac5c71 Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Tue, 6 Jun 2017 20:36:47 -0400
Subject: [PATCH 15/57] ec_wii: Add missing <string> header

---
 Source/Core/Core/ec_wii.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Source/Core/Core/ec_wii.cpp b/Source/Core/Core/ec_wii.cpp
index 7237512b86..9049b0a493 100644
--- a/Source/Core/Core/ec_wii.cpp
+++ b/Source/Core/Core/ec_wii.cpp
@@ -12,6 +12,7 @@
 #include <cinttypes>
 #include <cstdio>
 #include <cstring>
+#include <string>
 
 #include <mbedtls/sha1.h>
 

From acac2aeb9b6d5426cc6516aa3b0a78539208a5d8 Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Tue, 6 Jun 2017 20:56:01 -0400
Subject: [PATCH 16/57] Movie: Use std::put_time in GetRTCDisplay()

No need for a fixed buffer.
---
 Source/Core/Core/Movie.cpp | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/Source/Core/Core/Movie.cpp b/Source/Core/Core/Movie.cpp
index 608638c39a..8b31b029e7 100644
--- a/Source/Core/Core/Movie.cpp
+++ b/Source/Core/Core/Movie.cpp
@@ -7,10 +7,12 @@
 #include <algorithm>
 #include <array>
 #include <cctype>
+#include <iomanip>
 #include <iterator>
 #include <mbedtls/config.h>
 #include <mbedtls/md.h>
 #include <mutex>
+#include <sstream>
 #include <thread>
 #include <utility>
 #include <variant>
@@ -187,13 +189,13 @@ std::string GetInputDisplay()
 // NOTE: GPU Thread
 std::string GetRTCDisplay()
 {
-  time_t current_time =
-      ExpansionInterface::CEXIIPL::GetEmulatedTime(ExpansionInterface::CEXIIPL::UNIX_EPOCH);
-  tm* gm_time = gmtime(&current_time);
-  char buffer[256];
-  strftime(buffer, sizeof(buffer), "Date/Time: %c\n", gm_time);
+  using ExpansionInterface::CEXIIPL;
+
+  const time_t current_time = CEXIIPL::GetEmulatedTime(CEXIIPL::UNIX_EPOCH);
+  const tm* const gm_time = gmtime(&current_time);
+
   std::stringstream format_time;
-  format_time << buffer;
+  format_time << std::put_time(gm_time, "Date/Time: %c\n");
   return format_time.str();
 }
 

From 0c241629281ed319b7c639d711ae0b61381ea0db Mon Sep 17 00:00:00 2001
From: Starsam80 <samraskauskas@gmail.com>
Date: Tue, 6 Jun 2017 16:44:42 -0600
Subject: [PATCH 17/57] Qt: Use TitleDatabase for better names in the game list

---
 Source/Core/DolphinQt2/GameList/GameListModel.cpp | 15 ++++++++++++++-
 Source/Core/DolphinQt2/GameList/GameListModel.h   |  2 ++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/Source/Core/DolphinQt2/GameList/GameListModel.cpp b/Source/Core/DolphinQt2/GameList/GameListModel.cpp
index 07f23c1b94..78f13928fb 100644
--- a/Source/Core/DolphinQt2/GameList/GameListModel.cpp
+++ b/Source/Core/DolphinQt2/GameList/GameListModel.cpp
@@ -3,6 +3,8 @@
 // Refer to the license.txt file included.
 
 #include "DolphinQt2/GameList/GameListModel.h"
+
+#include "DiscIO/Enums.h"
 #include "DolphinQt2/Resources.h"
 #include "DolphinQt2/Settings.h"
 
@@ -21,6 +23,8 @@ GameListModel::GameListModel(QObject* parent) : QAbstractTableModel(parent)
     emit layoutAboutToBeChanged();
     emit layoutChanged();
   });
+
+  // TODO: Reload m_title_database when the language changes
 }
 
 QVariant GameListModel::data(const QModelIndex& index, int role) const
@@ -63,7 +67,16 @@ QVariant GameListModel::data(const QModelIndex& index, int role) const
     break;
   case COL_TITLE:
     if (role == Qt::DisplayRole || role == Qt::InitialSortOrderRole)
-      return game->GetLongName();
+    {
+      QString display_name = QString::fromStdString(m_title_database.GetTitleName(
+          game->GetGameID().toStdString(), game->GetPlatformID() == DiscIO::Platform::WII_WAD ?
+                                               Core::TitleDatabase::TitleType::Channel :
+                                               Core::TitleDatabase::TitleType::Other));
+      if (display_name.isEmpty())
+        return game->GetLongName();
+
+      return display_name;
+    }
     break;
   case COL_ID:
     if (role == Qt::DisplayRole || role == Qt::InitialSortOrderRole)
diff --git a/Source/Core/DolphinQt2/GameList/GameListModel.h b/Source/Core/DolphinQt2/GameList/GameListModel.h
index ab6a149cde..bd49c348d3 100644
--- a/Source/Core/DolphinQt2/GameList/GameListModel.h
+++ b/Source/Core/DolphinQt2/GameList/GameListModel.h
@@ -7,6 +7,7 @@
 #include <QAbstractTableModel>
 #include <QString>
 
+#include "Core/TitleDatabase.h"
 #include "DolphinQt2/GameList/GameFile.h"
 #include "DolphinQt2/GameList/GameTracker.h"
 
@@ -54,4 +55,5 @@ private:
 
   GameTracker m_tracker;
   QList<QSharedPointer<GameFile>> m_games;
+  Core::TitleDatabase m_title_database;
 };

From 927a4a16f852e4b5b465c9ed260dca0dcb27987c Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Tue, 6 Jun 2017 22:53:38 -0400
Subject: [PATCH 18/57] Boot: Make BootExecutableReader constructors explicit

---
 Source/Core/Core/Boot/Boot.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Source/Core/Core/Boot/Boot.h b/Source/Core/Core/Boot/Boot.h
index a178edaf75..1f52daa1c5 100644
--- a/Source/Core/Core/Boot/Boot.h
+++ b/Source/Core/Core/Boot/Boot.h
@@ -109,8 +109,8 @@ private:
 class BootExecutableReader
 {
 public:
-  BootExecutableReader(const std::string& file_name);
-  BootExecutableReader(const std::vector<u8>& buffer);
+  explicit BootExecutableReader(const std::string& file_name);
+  explicit BootExecutableReader(const std::vector<u8>& buffer);
   virtual ~BootExecutableReader();
 
   virtual u32 GetEntryPoint() const = 0;

From 187650570783c723ff4e76d72a8513c917c10ccc Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Tue, 6 Jun 2017 22:56:40 -0400
Subject: [PATCH 19/57] DolReader: Make constructors explicit

---
 Source/Core/Core/Boot/DolReader.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Source/Core/Core/Boot/DolReader.h b/Source/Core/Core/Boot/DolReader.h
index 43b1c0f354..e2daa04733 100644
--- a/Source/Core/Core/Boot/DolReader.h
+++ b/Source/Core/Core/Boot/DolReader.h
@@ -13,8 +13,8 @@
 class DolReader final : public BootExecutableReader
 {
 public:
-  DolReader(const std::string& filename);
-  DolReader(const std::vector<u8>& buffer);
+  explicit DolReader(const std::string& filename);
+  explicit DolReader(const std::vector<u8>& buffer);
   ~DolReader();
 
   bool IsValid() const override { return m_is_valid; }

From 1af1795695bbda672fb2671a2290b571b7550b7e Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Tue, 6 Jun 2017 22:58:06 -0400
Subject: [PATCH 20/57] ElfReader: Make constructors explicit

---
 Source/Core/Core/Boot/ElfReader.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Source/Core/Core/Boot/ElfReader.h b/Source/Core/Core/Boot/ElfReader.h
index 014d0667c3..a73a18a536 100644
--- a/Source/Core/Core/Boot/ElfReader.h
+++ b/Source/Core/Core/Boot/ElfReader.h
@@ -21,8 +21,8 @@ typedef int SectionID;
 class ElfReader final : public BootExecutableReader
 {
 public:
-  ElfReader(const std::string& filename);
-  ElfReader(const std::vector<u8>& buffer);
+  explicit ElfReader(const std::string& filename);
+  explicit ElfReader(const std::vector<u8>& buffer);
   ~ElfReader() {}
   u32 Read32(int off) const { return base32[off >> 2]; }
   // Quick accessors

From b0427731b3b122f45079dc4520d47a2c62c6bd18 Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Tue, 6 Jun 2017 22:59:12 -0400
Subject: [PATCH 21/57] ElfReader: default the destructor

---
 Source/Core/Core/Boot/ElfReader.cpp | 2 ++
 Source/Core/Core/Boot/ElfReader.h   | 2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/Source/Core/Core/Boot/ElfReader.cpp b/Source/Core/Core/Boot/ElfReader.cpp
index 4f9297b06d..78a77954ed 100644
--- a/Source/Core/Core/Boot/ElfReader.cpp
+++ b/Source/Core/Core/Boot/ElfReader.cpp
@@ -76,6 +76,8 @@ ElfReader::ElfReader(const std::string& filename) : BootExecutableReader(filenam
   Initialize(m_bytes.data());
 }
 
+ElfReader::~ElfReader() = default;
+
 void ElfReader::Initialize(u8* ptr)
 {
   base = (char*)ptr;
diff --git a/Source/Core/Core/Boot/ElfReader.h b/Source/Core/Core/Boot/ElfReader.h
index a73a18a536..951f5a7b57 100644
--- a/Source/Core/Core/Boot/ElfReader.h
+++ b/Source/Core/Core/Boot/ElfReader.h
@@ -23,7 +23,7 @@ class ElfReader final : public BootExecutableReader
 public:
   explicit ElfReader(const std::string& filename);
   explicit ElfReader(const std::vector<u8>& buffer);
-  ~ElfReader() {}
+  ~ElfReader();
   u32 Read32(int off) const { return base32[off >> 2]; }
   // Quick accessors
   ElfType GetType() const { return (ElfType)(header->e_type); }

From b676edd80c2d1056f0cb28383120e9284336866c Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Tue, 6 Jun 2017 23:36:16 -0400
Subject: [PATCH 22/57] Core: include what you use

Eliminates a swath of indirectly included standard headers
---
 Source/Core/Core/ARDecrypt.cpp                           | 2 ++
 Source/Core/Core/ActionReplay.cpp                        | 1 +
 Source/Core/Core/Boot/Boot.cpp                           | 1 +
 Source/Core/Core/ConfigLoaders/BaseConfigLoader.cpp      | 1 +
 Source/Core/Core/ConfigLoaders/GameConfigLoader.cpp      | 2 ++
 Source/Core/Core/ConfigLoaders/MovieConfigLoader.cpp     | 1 +
 Source/Core/Core/ConfigLoaders/NetPlayConfigLoader.cpp   | 2 ++
 Source/Core/Core/ConfigManager.cpp                       | 1 +
 Source/Core/Core/DSP/DSPAssembler.cpp                    | 4 +++-
 Source/Core/Core/DSP/DSPCaptureLogger.cpp                | 1 +
 Source/Core/Core/DSP/DSPDisassembler.cpp                 | 1 +
 Source/Core/Core/DSP/DSPHWInterface.cpp                  | 1 +
 Source/Core/Core/DSP/LabelMap.cpp                        | 4 ++++
 Source/Core/Core/Debugger/Debugger_SymbolMap.cpp         | 1 +
 Source/Core/Core/Debugger/RSO.cpp                        | 4 ++++
 Source/Core/Core/FifoPlayer/FifoDataFile.cpp             | 2 ++
 Source/Core/Core/FifoPlayer/FifoPlaybackAnalyzer.cpp     | 2 ++
 Source/Core/Core/FifoPlayer/FifoRecorder.cpp             | 1 +
 Source/Core/Core/GeckoCodeConfig.cpp                     | 1 +
 Source/Core/Core/HW/DSPHLE/MailHandler.cpp               | 3 +++
 Source/Core/Core/HW/DSPHLE/UCodes/UCodes.cpp             | 1 +
 Source/Core/Core/HW/DSPHLE/UCodes/Zelda.cpp              | 1 +
 Source/Core/Core/HW/DSPLLE/DSPHost.cpp                   | 3 +++
 Source/Core/Core/HW/DVD/DVDInterface.cpp                 | 1 +
 Source/Core/Core/HW/EXI/EXI_DeviceAGP.cpp                | 2 ++
 Source/Core/Core/HW/EXI/EXI_DeviceDummy.cpp              | 2 ++
 Source/Core/Core/HW/EXI/EXI_DeviceEthernet.cpp           | 1 +
 Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp                | 1 +
 Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp         | 1 +
 Source/Core/Core/HW/EXI/EXI_DeviceMic.cpp                | 5 +++--
 Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp     | 2 ++
 Source/Core/Core/HW/GCMemcard/GCMemcardRaw.cpp           | 2 ++
 Source/Core/Core/HW/GPFifo.cpp                           | 1 +
 Source/Core/Core/HW/Memmap.cpp                           | 1 +
 Source/Core/Core/HW/ProcessorInterface.cpp               | 1 +
 Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp        | 1 +
 Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp            | 2 ++
 Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp          | 1 +
 Source/Core/Core/HotkeyManager.cpp                       | 2 ++
 Source/Core/Core/IOS/ES/Formats.cpp                      | 2 ++
 Source/Core/Core/IOS/IOSC.cpp                            | 3 +++
 Source/Core/Core/IOS/MemoryValues.cpp                    | 3 +++
 Source/Core/Core/IOS/USB/Bluetooth/BTEmu.cpp             | 1 +
 Source/Core/Core/IOS/USB/Bluetooth/BTReal.cpp            | 3 +++
 Source/Core/Core/IOS/USB/Host.cpp                        | 3 +++
 Source/Core/Core/IOS/USB/LibusbDevice.cpp                | 4 ++++
 Source/Core/Core/IOS/USB/OH0/OH0Device.cpp               | 2 ++
 Source/Core/Core/IOS/USB/USBV5.cpp                       | 1 +
 Source/Core/Core/IOS/USB/USB_HID/HIDv4.cpp               | 3 +++
 Source/Core/Core/IOS/USB/USB_KBD.cpp                     | 1 +
 Source/Core/Core/IOS/USB/USB_VEN/VEN.cpp                 | 4 ++++
 Source/Core/Core/NetPlayClient.cpp                       | 7 ++++++-
 Source/Core/Core/NetPlayServer.cpp                       | 6 ++++++
 Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp     | 3 ++-
 Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.cpp    | 3 +++
 Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.cpp  | 3 +++
 Source/Core/Core/PowerPC/JitCommon/JitCache.cpp          | 3 +++
 Source/Core/Core/PowerPC/JitInterface.cpp                | 1 +
 Source/Core/Core/PowerPC/MMU.cpp                         | 1 +
 Source/Core/Core/PowerPC/PPCAnalyst.cpp                  | 2 ++
 Source/Core/Core/PowerPC/SignatureDB/DSYSignatureDB.cpp  | 1 +
 Source/Core/Core/PowerPC/SignatureDB/MEGASignatureDB.cpp | 1 +
 Source/Core/Core/PowerPC/SignatureDB/SignatureDB.cpp     | 1 +
 Source/Core/Core/TitleDatabase.cpp                       | 1 +
 64 files changed, 125 insertions(+), 5 deletions(-)

diff --git a/Source/Core/Core/ARDecrypt.cpp b/Source/Core/Core/ARDecrypt.cpp
index c4bd4f203d..40d43a3619 100644
--- a/Source/Core/Core/ARDecrypt.cpp
+++ b/Source/Core/Core/ARDecrypt.cpp
@@ -10,6 +10,8 @@
 
 #include <algorithm>
 #include <cstring>
+#include <string>
+#include <vector>
 
 #ifdef _WIN32
 #include <windows.h>
diff --git a/Source/Core/Core/ActionReplay.cpp b/Source/Core/Core/ActionReplay.cpp
index f8ec23175f..58146d7506 100644
--- a/Source/Core/Core/ActionReplay.cpp
+++ b/Source/Core/Core/ActionReplay.cpp
@@ -21,6 +21,7 @@
 
 #include <algorithm>
 #include <atomic>
+#include <cstdarg>
 #include <iterator>
 #include <mutex>
 #include <string>
diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp
index e428129226..a703716abb 100644
--- a/Source/Core/Core/Boot/Boot.cpp
+++ b/Source/Core/Core/Boot/Boot.cpp
@@ -5,6 +5,7 @@
 #include "Core/Boot/Boot.h"
 
 #include <algorithm>
+#include <memory>
 #include <optional>
 #include <string>
 #include <unordered_set>
diff --git a/Source/Core/Core/ConfigLoaders/BaseConfigLoader.cpp b/Source/Core/Core/ConfigLoaders/BaseConfigLoader.cpp
index 25cb3f358b..189e69a28a 100644
--- a/Source/Core/Core/ConfigLoaders/BaseConfigLoader.cpp
+++ b/Source/Core/Core/ConfigLoaders/BaseConfigLoader.cpp
@@ -5,6 +5,7 @@
 #include <cstring>
 #include <list>
 #include <map>
+#include <memory>
 #include <string>
 
 #include "Common/CommonPaths.h"
diff --git a/Source/Core/Core/ConfigLoaders/GameConfigLoader.cpp b/Source/Core/Core/ConfigLoaders/GameConfigLoader.cpp
index 1143da3111..39af481ae1 100644
--- a/Source/Core/Core/ConfigLoaders/GameConfigLoader.cpp
+++ b/Source/Core/Core/ConfigLoaders/GameConfigLoader.cpp
@@ -4,7 +4,9 @@
 
 #include <algorithm>
 #include <array>
+#include <list>
 #include <map>
+#include <sstream>
 #include <string>
 #include <tuple>
 #include <utility>
diff --git a/Source/Core/Core/ConfigLoaders/MovieConfigLoader.cpp b/Source/Core/Core/ConfigLoaders/MovieConfigLoader.cpp
index dc115e1bb4..53e4d83399 100644
--- a/Source/Core/Core/ConfigLoaders/MovieConfigLoader.cpp
+++ b/Source/Core/Core/ConfigLoaders/MovieConfigLoader.cpp
@@ -3,6 +3,7 @@
 // Refer to the license.txt file included.
 
 #include <cstring>
+#include <memory>
 #include <string>
 
 #include "Common/CommonFuncs.h"
diff --git a/Source/Core/Core/ConfigLoaders/NetPlayConfigLoader.cpp b/Source/Core/Core/ConfigLoaders/NetPlayConfigLoader.cpp
index ffd84edfac..5f01159b60 100644
--- a/Source/Core/Core/ConfigLoaders/NetPlayConfigLoader.cpp
+++ b/Source/Core/Core/ConfigLoaders/NetPlayConfigLoader.cpp
@@ -2,6 +2,8 @@
 // Licensed under GPLv2+
 // Refer to the license.txt file included.
 
+#include <memory>
+
 #include "Common/CommonPaths.h"
 #include "Common/Config/Config.h"
 #include "Common/FileUtil.h"
diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp
index b63702b6d2..fd637afd0b 100644
--- a/Source/Core/Core/ConfigManager.cpp
+++ b/Source/Core/Core/ConfigManager.cpp
@@ -6,6 +6,7 @@
 #include <climits>
 #include <memory>
 #include <optional>
+#include <sstream>
 #include <variant>
 
 #include "AudioCommon/AudioCommon.h"
diff --git a/Source/Core/Core/DSP/DSPAssembler.cpp b/Source/Core/Core/DSP/DSPAssembler.cpp
index bb00023941..50ed09337d 100644
--- a/Source/Core/Core/DSP/DSPAssembler.cpp
+++ b/Source/Core/Core/DSP/DSPAssembler.cpp
@@ -5,15 +5,17 @@
 
 #include "Core/DSP/DSPAssembler.h"
 
+#include <algorithm>
 #include <cstddef>
 #include <cstdio>
 #include <cstdlib>
 #include <cstring>
 #include <fstream>
-#include <iostream>
 #include <map>
+#include <sstream>
 #include <string>
 #include <utility>
+#include <vector>
 
 #include "Common/CommonTypes.h"
 #include "Common/FileUtil.h"
diff --git a/Source/Core/Core/DSP/DSPCaptureLogger.cpp b/Source/Core/Core/DSP/DSPCaptureLogger.cpp
index 4050379ec9..4b36b2ff41 100644
--- a/Source/Core/Core/DSP/DSPCaptureLogger.cpp
+++ b/Source/Core/Core/DSP/DSPCaptureLogger.cpp
@@ -4,6 +4,7 @@
 
 #include <cstring>
 #include <memory>
+#include <string>
 
 #include "Common/CommonTypes.h"
 #include "Common/FileUtil.h"
diff --git a/Source/Core/Core/DSP/DSPDisassembler.cpp b/Source/Core/Core/DSP/DSPDisassembler.cpp
index 972db90ec4..c9627de3af 100644
--- a/Source/Core/Core/DSP/DSPDisassembler.cpp
+++ b/Source/Core/Core/DSP/DSPDisassembler.cpp
@@ -9,6 +9,7 @@
 #include <cstdlib>
 #include <fstream>
 #include <string>
+#include <vector>
 
 #include "Common/CommonTypes.h"
 #include "Common/FileUtil.h"
diff --git a/Source/Core/Core/DSP/DSPHWInterface.cpp b/Source/Core/Core/DSP/DSPHWInterface.cpp
index 09b66f42e2..fa18c96968 100644
--- a/Source/Core/Core/DSP/DSPHWInterface.cpp
+++ b/Source/Core/Core/DSP/DSPHWInterface.cpp
@@ -5,6 +5,7 @@
 
 #include "Core/DSP/DSPHWInterface.h"
 
+#include <atomic>
 #include <cstddef>
 #include <cstring>
 
diff --git a/Source/Core/Core/DSP/LabelMap.cpp b/Source/Core/Core/DSP/LabelMap.cpp
index d0137d9c35..e2e157ba79 100644
--- a/Source/Core/Core/DSP/LabelMap.cpp
+++ b/Source/Core/Core/DSP/LabelMap.cpp
@@ -3,6 +3,10 @@
 // Refer to the license.txt file included.
 
 #include "Core/DSP/LabelMap.h"
+
+#include <string>
+#include <vector>
+
 #include "Core/DSP/DSPTables.h"
 
 namespace DSP
diff --git a/Source/Core/Core/Debugger/Debugger_SymbolMap.cpp b/Source/Core/Core/Debugger/Debugger_SymbolMap.cpp
index f431390991..bd2a71a2bd 100644
--- a/Source/Core/Core/Debugger/Debugger_SymbolMap.cpp
+++ b/Source/Core/Core/Debugger/Debugger_SymbolMap.cpp
@@ -2,6 +2,7 @@
 // Licensed under GPLv2+
 // Refer to the license.txt file included.
 
+#include <cstdio>
 #include <functional>
 #include <string>
 
diff --git a/Source/Core/Core/Debugger/RSO.cpp b/Source/Core/Core/Debugger/RSO.cpp
index bfab731032..013a9209a6 100644
--- a/Source/Core/Core/Debugger/RSO.cpp
+++ b/Source/Core/Core/Debugger/RSO.cpp
@@ -4,7 +4,11 @@
 
 #include "Core/Debugger/RSO.h"
 
+#include <cstddef>
+#include <list>
+#include <string>
 #include <utility>
+#include <vector>
 
 #include "Common/CommonFuncs.h"
 #include "Common/Logging/Log.h"
diff --git a/Source/Core/Core/FifoPlayer/FifoDataFile.cpp b/Source/Core/Core/FifoPlayer/FifoDataFile.cpp
index 3cb0d25493..6e7899a78c 100644
--- a/Source/Core/Core/FifoPlayer/FifoDataFile.cpp
+++ b/Source/Core/Core/FifoPlayer/FifoDataFile.cpp
@@ -4,7 +4,9 @@
 
 #include <algorithm>
 #include <cstring>
+#include <memory>
 #include <string>
+#include <vector>
 
 #include "Common/FileUtil.h"
 
diff --git a/Source/Core/Core/FifoPlayer/FifoPlaybackAnalyzer.cpp b/Source/Core/Core/FifoPlayer/FifoPlaybackAnalyzer.cpp
index 6e70078c10..0458fe2fde 100644
--- a/Source/Core/Core/FifoPlayer/FifoPlaybackAnalyzer.cpp
+++ b/Source/Core/Core/FifoPlayer/FifoPlaybackAnalyzer.cpp
@@ -4,6 +4,8 @@
 
 #include "Core/FifoPlayer/FifoPlaybackAnalyzer.h"
 
+#include <vector>
+
 #include "Common/CommonTypes.h"
 #include "Core/FifoPlayer/FifoAnalyzer.h"
 #include "Core/FifoPlayer/FifoDataFile.h"
diff --git a/Source/Core/Core/FifoPlayer/FifoRecorder.cpp b/Source/Core/Core/FifoPlayer/FifoRecorder.cpp
index 378ad29290..3b6ac26446 100644
--- a/Source/Core/Core/FifoPlayer/FifoRecorder.cpp
+++ b/Source/Core/Core/FifoPlayer/FifoRecorder.cpp
@@ -3,6 +3,7 @@
 // Refer to the license.txt file included.
 
 #include <algorithm>
+#include <cstring>
 #include <mutex>
 
 #include "Core/FifoPlayer/FifoRecorder.h"
diff --git a/Source/Core/Core/GeckoCodeConfig.cpp b/Source/Core/Core/GeckoCodeConfig.cpp
index b3139e4945..eac79d099f 100644
--- a/Source/Core/Core/GeckoCodeConfig.cpp
+++ b/Source/Core/Core/GeckoCodeConfig.cpp
@@ -5,6 +5,7 @@
 #include "Core/GeckoCodeConfig.h"
 
 #include <algorithm>
+#include <memory>
 #include <sstream>
 #include <string>
 #include <vector>
diff --git a/Source/Core/Core/HW/DSPHLE/MailHandler.cpp b/Source/Core/Core/HW/DSPHLE/MailHandler.cpp
index da1ccfd29b..6d8de40b54 100644
--- a/Source/Core/Core/HW/DSPHLE/MailHandler.cpp
+++ b/Source/Core/Core/HW/DSPHLE/MailHandler.cpp
@@ -3,6 +3,9 @@
 // Refer to the license.txt file included.
 
 #include "Core/HW/DSPHLE/MailHandler.h"
+
+#include <queue>
+
 #include "Common/ChunkFile.h"
 #include "Common/CommonTypes.h"
 #include "Common/Logging/Log.h"
diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/UCodes.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/UCodes.cpp
index 625e5969ed..dff0f541b8 100644
--- a/Source/Core/Core/HW/DSPHLE/UCodes/UCodes.cpp
+++ b/Source/Core/Core/HW/DSPHLE/UCodes/UCodes.cpp
@@ -5,6 +5,7 @@
 #include "Core/HW/DSPHLE/UCodes/UCodes.h"
 
 #include <cstring>
+#include <memory>
 #include <string>
 
 #ifdef _WIN32
diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/Zelda.cpp b/Source/Core/Core/HW/DSPHLE/UCodes/Zelda.cpp
index 9ca15f9d17..ae1cc5496a 100644
--- a/Source/Core/Core/HW/DSPHLE/UCodes/Zelda.cpp
+++ b/Source/Core/Core/HW/DSPHLE/UCodes/Zelda.cpp
@@ -5,6 +5,7 @@
 #include "Core/HW/DSPHLE/UCodes/Zelda.h"
 
 #include <array>
+#include <map>
 
 #include "Common/ChunkFile.h"
 #include "Common/CommonTypes.h"
diff --git a/Source/Core/Core/HW/DSPLLE/DSPHost.cpp b/Source/Core/Core/HW/DSPLLE/DSPHost.cpp
index 892d0d245e..281db0698b 100644
--- a/Source/Core/Core/HW/DSPLLE/DSPHost.cpp
+++ b/Source/Core/Core/HW/DSPLLE/DSPHost.cpp
@@ -3,6 +3,9 @@
 // Refer to the license.txt file included.
 
 #include "Core/DSP/DSPHost.h"
+
+#include <string>
+
 #include "Common/CommonTypes.h"
 #include "Common/Hash.h"
 #include "Common/Logging/Log.h"
diff --git a/Source/Core/Core/HW/DVD/DVDInterface.cpp b/Source/Core/Core/HW/DVD/DVDInterface.cpp
index 9faed66142..828157d744 100644
--- a/Source/Core/Core/HW/DVD/DVDInterface.cpp
+++ b/Source/Core/Core/HW/DVD/DVDInterface.cpp
@@ -7,6 +7,7 @@
 #include <memory>
 #include <optional>
 #include <string>
+#include <vector>
 
 #include "AudioCommon/AudioCommon.h"
 
diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceAGP.cpp b/Source/Core/Core/HW/EXI/EXI_DeviceAGP.cpp
index f02b61ec30..722f131603 100644
--- a/Source/Core/Core/HW/EXI/EXI_DeviceAGP.cpp
+++ b/Source/Core/Core/HW/EXI/EXI_DeviceAGP.cpp
@@ -4,8 +4,10 @@
 
 #include "Core/HW/EXI/EXI_DeviceAGP.h"
 
+#include <algorithm>
 #include <memory>
 #include <string>
+#include <vector>
 
 #include "Common/ChunkFile.h"
 #include "Common/CommonTypes.h"
diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceDummy.cpp b/Source/Core/Core/HW/EXI/EXI_DeviceDummy.cpp
index 6969ec31d0..ee89644b53 100644
--- a/Source/Core/Core/HW/EXI/EXI_DeviceDummy.cpp
+++ b/Source/Core/Core/HW/EXI/EXI_DeviceDummy.cpp
@@ -4,6 +4,8 @@
 
 #include "Core/HW/EXI/EXI_DeviceDummy.h"
 
+#include <string>
+
 #include "Common/CommonTypes.h"
 #include "Common/Logging/Log.h"
 
diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceEthernet.cpp b/Source/Core/Core/HW/EXI/EXI_DeviceEthernet.cpp
index 1af3a6b039..cc99b7d925 100644
--- a/Source/Core/Core/HW/EXI/EXI_DeviceEthernet.cpp
+++ b/Source/Core/Core/HW/EXI/EXI_DeviceEthernet.cpp
@@ -4,6 +4,7 @@
 
 #include "Core/HW/EXI/EXI_DeviceEthernet.h"
 
+#include <memory>
 #include <string>
 
 #include "Common/ChunkFile.h"
diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp b/Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp
index 0cf6bbfc38..7df96147b4 100644
--- a/Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp
+++ b/Source/Core/Core/HW/EXI/EXI_DeviceIPL.cpp
@@ -5,6 +5,7 @@
 #include "Core/HW/EXI/EXI_DeviceIPL.h"
 
 #include <cstring>
+#include <string>
 
 #include "Common/Assert.h"
 #include "Common/ChunkFile.h"
diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp b/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp
index 55299a9663..8da1bd2c4d 100644
--- a/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp
+++ b/Source/Core/Core/HW/EXI/EXI_DeviceMemoryCard.cpp
@@ -6,6 +6,7 @@
 
 #include <array>
 #include <cstring>
+#include <functional>
 #include <memory>
 #include <string>
 
diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceMic.cpp b/Source/Core/Core/HW/EXI/EXI_DeviceMic.cpp
index 0ad3a263a3..eca7eb2637 100644
--- a/Source/Core/Core/HW/EXI/EXI_DeviceMic.cpp
+++ b/Source/Core/Core/HW/EXI/EXI_DeviceMic.cpp
@@ -2,9 +2,12 @@
 // Licensed under GPLv2+
 // Refer to the license.txt file included.
 
+#include <algorithm>
 #include <cstring>
 #include <mutex>
 
+#include <cubeb/cubeb.h>
+
 #include "AudioCommon/CubebUtils.h"
 #include "Common/Common.h"
 #include "Common/CommonTypes.h"
@@ -17,8 +20,6 @@
 #include "Core/HW/GCPad.h"
 #include "Core/HW/SystemTimers.h"
 
-#include <cubeb/cubeb.h>
-
 namespace ExpansionInterface
 {
 void CEXIMic::StreamInit()
diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp b/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp
index 2cf7399e3d..0fc0a18b3d 100644
--- a/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp
+++ b/Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp
@@ -4,12 +4,14 @@
 
 #include "Core/HW/GCMemcard/GCMemcardDirectory.h"
 
+#include <algorithm>
 #include <chrono>
 #include <cinttypes>
 #include <cstring>
 #include <memory>
 #include <mutex>
 #include <string>
+#include <vector>
 
 #include "Common/Assert.h"
 #include "Common/ChunkFile.h"
diff --git a/Source/Core/Core/HW/GCMemcard/GCMemcardRaw.cpp b/Source/Core/Core/HW/GCMemcard/GCMemcardRaw.cpp
index 894a922db7..6895ff327c 100644
--- a/Source/Core/Core/HW/GCMemcard/GCMemcardRaw.cpp
+++ b/Source/Core/Core/HW/GCMemcard/GCMemcardRaw.cpp
@@ -7,7 +7,9 @@
 #include <chrono>
 #include <cstring>
 #include <memory>
+#include <mutex>
 #include <string>
+#include <thread>
 
 #include "Common/ChunkFile.h"
 #include "Common/CommonTypes.h"
diff --git a/Source/Core/Core/HW/GPFifo.cpp b/Source/Core/Core/HW/GPFifo.cpp
index 174a284f11..403321fe37 100644
--- a/Source/Core/Core/HW/GPFifo.cpp
+++ b/Source/Core/Core/HW/GPFifo.cpp
@@ -4,6 +4,7 @@
 
 #include "Core/HW/GPFifo.h"
 
+#include <cstddef>
 #include <cstring>
 
 #include "Common/ChunkFile.h"
diff --git a/Source/Core/Core/HW/Memmap.cpp b/Source/Core/Core/HW/Memmap.cpp
index 452f198884..9be01f9612 100644
--- a/Source/Core/Core/HW/Memmap.cpp
+++ b/Source/Core/Core/HW/Memmap.cpp
@@ -7,6 +7,7 @@
 // However, if a JITed instruction (for example lwz) wants to access a bad memory area that call
 // may be redirected here (for example to Read_U32()).
 
+#include <algorithm>
 #include <cstring>
 #include <memory>
 
diff --git a/Source/Core/Core/HW/ProcessorInterface.cpp b/Source/Core/Core/HW/ProcessorInterface.cpp
index b88bf05a49..4f0d7e8c65 100644
--- a/Source/Core/Core/HW/ProcessorInterface.cpp
+++ b/Source/Core/Core/HW/ProcessorInterface.cpp
@@ -3,6 +3,7 @@
 // Refer to the license.txt file included.
 
 #include <cstdio>
+#include <memory>
 
 #include "Common/ChunkFile.h"
 #include "Common/CommonTypes.h"
diff --git a/Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp b/Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp
index c12a983aba..0e45f869b4 100644
--- a/Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp
+++ b/Source/Core/Core/HW/WiimoteEmu/EmuSubroutines.cpp
@@ -16,6 +16,7 @@
    0x30 - 0x3f   Input    This file: Update() */
 
 #include <fstream>
+#include <mutex>
 #include <queue>
 #include <string>
 #include <vector>
diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp
index ff05c5c81c..8fcdb19fc3 100644
--- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp
+++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp
@@ -4,9 +4,11 @@
 
 #include "Core/HW/WiimoteEmu/WiimoteEmu.h"
 
+#include <algorithm>
 #include <cassert>
 #include <cmath>
 #include <cstring>
+#include <mutex>
 
 #include "Common/ChunkFile.h"
 #include "Common/CommonTypes.h"
diff --git a/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp
index 392dfe9caf..60a0e28c6e 100644
--- a/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp
+++ b/Source/Core/Core/HW/WiimoteReal/WiimoteReal.cpp
@@ -6,6 +6,7 @@
 
 #include <algorithm>
 #include <cstdlib>
+#include <mutex>
 #include <queue>
 #include <unordered_set>
 
diff --git a/Source/Core/Core/HotkeyManager.cpp b/Source/Core/Core/HotkeyManager.cpp
index 98d1b47cbe..5ea2b48619 100644
--- a/Source/Core/Core/HotkeyManager.cpp
+++ b/Source/Core/Core/HotkeyManager.cpp
@@ -4,6 +4,8 @@
 
 #include "Core/HotkeyManager.h"
 
+#include <algorithm>
+#include <array>
 #include <string>
 #include <vector>
 
diff --git a/Source/Core/Core/IOS/ES/Formats.cpp b/Source/Core/Core/IOS/ES/Formats.cpp
index 224776dcaf..ba99dc77a6 100644
--- a/Source/Core/Core/IOS/ES/Formats.cpp
+++ b/Source/Core/Core/IOS/ES/Formats.cpp
@@ -5,10 +5,12 @@
 #include "Core/IOS/ES/Formats.h"
 
 #include <algorithm>
+#include <array>
 #include <cinttypes>
 #include <cstddef>
 #include <cstring>
 #include <locale>
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
diff --git a/Source/Core/Core/IOS/IOSC.cpp b/Source/Core/Core/IOS/IOSC.cpp
index ce47785ba9..129d0c485c 100644
--- a/Source/Core/Core/IOS/IOSC.cpp
+++ b/Source/Core/Core/IOS/IOSC.cpp
@@ -3,7 +3,10 @@
 // Refer to the license.txt file included.
 
 #include <algorithm>
+#include <array>
+#include <cstddef>
 #include <cstring>
+#include <vector>
 
 #include <mbedtls/sha1.h>
 
diff --git a/Source/Core/Core/IOS/MemoryValues.cpp b/Source/Core/Core/IOS/MemoryValues.cpp
index 2d0bca4626..1fe60dfd29 100644
--- a/Source/Core/Core/IOS/MemoryValues.cpp
+++ b/Source/Core/Core/IOS/MemoryValues.cpp
@@ -3,6 +3,9 @@
 // Refer to the license.txt file included.
 
 #include "Core/IOS/MemoryValues.h"
+
+#include <array>
+
 #include "Common/CommonTypes.h"
 
 namespace IOS
diff --git a/Source/Core/Core/IOS/USB/Bluetooth/BTEmu.cpp b/Source/Core/Core/IOS/USB/Bluetooth/BTEmu.cpp
index c0c9379979..c0296abcdf 100644
--- a/Source/Core/Core/IOS/USB/Bluetooth/BTEmu.cpp
+++ b/Source/Core/Core/IOS/USB/Bluetooth/BTEmu.cpp
@@ -6,6 +6,7 @@
 #include <cstdint>
 #include <cstring>
 #include <memory>
+#include <string>
 
 #include "Common/Assert.h"
 #include "Common/CommonPaths.h"
diff --git a/Source/Core/Core/IOS/USB/Bluetooth/BTReal.cpp b/Source/Core/Core/IOS/USB/Bluetooth/BTReal.cpp
index a23c236ab8..caf3136ff4 100644
--- a/Source/Core/Core/IOS/USB/Bluetooth/BTReal.cpp
+++ b/Source/Core/Core/IOS/USB/Bluetooth/BTReal.cpp
@@ -7,7 +7,10 @@
 #include <cstring>
 #include <iomanip>
 #include <iterator>
+#include <memory>
+#include <mutex>
 #include <sstream>
+#include <string>
 #include <utility>
 #include <vector>
 
diff --git a/Source/Core/Core/IOS/USB/Host.cpp b/Source/Core/Core/IOS/USB/Host.cpp
index e440494460..cba1cc4c95 100644
--- a/Source/Core/Core/IOS/USB/Host.cpp
+++ b/Source/Core/Core/IOS/USB/Host.cpp
@@ -4,6 +4,9 @@
 
 #include <algorithm>
 #include <memory>
+#include <mutex>
+#include <set>
+#include <string>
 #include <utility>
 
 #ifdef __LIBUSB__
diff --git a/Source/Core/Core/IOS/USB/LibusbDevice.cpp b/Source/Core/Core/IOS/USB/LibusbDevice.cpp
index 9b57062336..3c8476174e 100644
--- a/Source/Core/Core/IOS/USB/LibusbDevice.cpp
+++ b/Source/Core/Core/IOS/USB/LibusbDevice.cpp
@@ -5,8 +5,12 @@
 #include <algorithm>
 #include <cstddef>
 #include <cstring>
+#include <functional>
 #include <map>
+#include <memory>
+#include <mutex>
 #include <utility>
+#include <vector>
 
 #include <libusb.h>
 
diff --git a/Source/Core/Core/IOS/USB/OH0/OH0Device.cpp b/Source/Core/Core/IOS/USB/OH0/OH0Device.cpp
index e72de9cdfe..72e9908b38 100644
--- a/Source/Core/Core/IOS/USB/OH0/OH0Device.cpp
+++ b/Source/Core/Core/IOS/USB/OH0/OH0Device.cpp
@@ -2,7 +2,9 @@
 // Licensed under GPLv2+
 // Refer to the license.txt file included.
 
+#include <memory>
 #include <sstream>
+#include <string>
 #include <tuple>
 #include <vector>
 
diff --git a/Source/Core/Core/IOS/USB/USBV5.cpp b/Source/Core/Core/IOS/USB/USBV5.cpp
index 357676fe08..aa6d9bf98b 100644
--- a/Source/Core/Core/IOS/USB/USBV5.cpp
+++ b/Source/Core/Core/IOS/USB/USBV5.cpp
@@ -2,6 +2,7 @@
 // Licensed under GPLv2+
 // Refer to the license.txt file included.
 
+#include <cstddef>
 #include <numeric>
 #include <vector>
 
diff --git a/Source/Core/Core/IOS/USB/USB_HID/HIDv4.cpp b/Source/Core/Core/IOS/USB/USB_HID/HIDv4.cpp
index 897f588809..edcf8b18c3 100644
--- a/Source/Core/Core/IOS/USB/USB_HID/HIDv4.cpp
+++ b/Source/Core/Core/IOS/USB/USB_HID/HIDv4.cpp
@@ -5,7 +5,10 @@
 #include "Core/IOS/USB/USB_HID/HIDv4.h"
 
 #include <cstring>
+#include <mutex>
+#include <string>
 #include <utility>
+#include <vector>
 
 #include "Common/Align.h"
 #include "Common/ChunkFile.h"
diff --git a/Source/Core/Core/IOS/USB/USB_KBD.cpp b/Source/Core/Core/IOS/USB/USB_KBD.cpp
index a9f361a1a7..185353a150 100644
--- a/Source/Core/Core/IOS/USB/USB_KBD.cpp
+++ b/Source/Core/Core/IOS/USB/USB_KBD.cpp
@@ -5,6 +5,7 @@
 #include "Core/IOS/USB/USB_KBD.h"
 
 #include <cstring>
+#include <queue>
 
 #include "Common/FileUtil.h"
 #include "Common/IniFile.h"
diff --git a/Source/Core/Core/IOS/USB/USB_VEN/VEN.cpp b/Source/Core/Core/IOS/USB/USB_VEN/VEN.cpp
index f9bb7a1583..955710f176 100644
--- a/Source/Core/Core/IOS/USB/USB_VEN/VEN.cpp
+++ b/Source/Core/Core/IOS/USB/USB_VEN/VEN.cpp
@@ -4,7 +4,11 @@
 
 #include "Core/IOS/USB/USB_VEN/VEN.h"
 
+#include <cstddef>
 #include <cstring>
+#include <memory>
+#include <mutex>
+#include <string>
 
 #include "Common/ChunkFile.h"
 #include "Common/Logging/Log.h"
diff --git a/Source/Core/Core/NetPlayClient.cpp b/Source/Core/Core/NetPlayClient.cpp
index f6a335eac8..6774e323c6 100644
--- a/Source/Core/Core/NetPlayClient.cpp
+++ b/Source/Core/Core/NetPlayClient.cpp
@@ -3,11 +3,16 @@
 // Refer to the license.txt file included.
 
 #include "Core/NetPlayClient.h"
+
 #include <algorithm>
 #include <fstream>
-#include <mbedtls/md5.h>
 #include <memory>
+#include <mutex>
+#include <sstream>
 #include <thread>
+
+#include <mbedtls/md5.h>
+
 #include "Common/Common.h"
 #include "Common/CommonPaths.h"
 #include "Common/CommonTypes.h"
diff --git a/Source/Core/Core/NetPlayServer.cpp b/Source/Core/Core/NetPlayServer.cpp
index a77a6657bf..3b0112772a 100644
--- a/Source/Core/Core/NetPlayServer.cpp
+++ b/Source/Core/Core/NetPlayServer.cpp
@@ -3,9 +3,15 @@
 // Refer to the license.txt file included.
 
 #include "Core/NetPlayServer.h"
+
+#include <algorithm>
 #include <memory>
+#include <mutex>
 #include <string>
+#include <thread>
+#include <unordered_set>
 #include <vector>
+
 #include "Common/Common.h"
 #include "Common/ENetUtil.h"
 #include "Common/FileUtil.h"
diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp
index 5cacf63a4f..f1e24b6113 100644
--- a/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp
+++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp
@@ -2,7 +2,8 @@
 // Licensed under GPLv2+
 // Refer to the license.txt file included.
 
-#include <assert.h>
+#include <array>
+#include <cassert>
 #include <cinttypes>
 #include <string>
 
diff --git a/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.cpp b/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.cpp
index 2fe4ea9f65..a3054f7509 100644
--- a/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.cpp
+++ b/Source/Core/Core/PowerPC/Jit64Common/EmuCodeBlock.cpp
@@ -4,6 +4,9 @@
 
 #include "Core/PowerPC/Jit64Common/EmuCodeBlock.h"
 
+#include <functional>
+#include <limits>
+
 #include "Common/Assert.h"
 #include "Common/CPUDetect.h"
 #include "Common/Intrinsics.h"
diff --git a/Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.cpp b/Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.cpp
index d2d8873e90..57901bdb0f 100644
--- a/Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.cpp
+++ b/Source/Core/Core/PowerPC/Jit64Common/Jit64AsmCommon.cpp
@@ -3,6 +3,9 @@
 // Refer to the license.txt file included.
 
 #include "Core/PowerPC/Jit64Common/Jit64AsmCommon.h"
+
+#include <array>
+
 #include "Common/Assert.h"
 #include "Common/CPUDetect.h"
 #include "Common/CommonTypes.h"
diff --git a/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp b/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp
index 6c19a81c22..efad560110 100644
--- a/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp
+++ b/Source/Core/Core/PowerPC/JitCommon/JitCache.cpp
@@ -10,8 +10,11 @@
 // locating performance issues.
 
 #include <algorithm>
+#include <array>
 #include <cstring>
+#include <functional>
 #include <map>
+#include <set>
 #include <utility>
 
 #include "Common/CommonTypes.h"
diff --git a/Source/Core/Core/PowerPC/JitInterface.cpp b/Source/Core/Core/PowerPC/JitInterface.cpp
index e427671f6f..6f602ec3da 100644
--- a/Source/Core/Core/PowerPC/JitInterface.cpp
+++ b/Source/Core/Core/PowerPC/JitInterface.cpp
@@ -8,6 +8,7 @@
 #include <cinttypes>
 #include <cstdio>
 #include <string>
+#include <unordered_set>
 
 #ifdef _WIN32
 #include <windows.h>
diff --git a/Source/Core/Core/PowerPC/MMU.cpp b/Source/Core/Core/PowerPC/MMU.cpp
index 7716ccf3fc..9df3483223 100644
--- a/Source/Core/Core/PowerPC/MMU.cpp
+++ b/Source/Core/Core/PowerPC/MMU.cpp
@@ -4,6 +4,7 @@
 
 #include <cstddef>
 #include <cstring>
+#include <string>
 
 #include "Common/Atomic.h"
 #include "Common/BitSet.h"
diff --git a/Source/Core/Core/PowerPC/PPCAnalyst.cpp b/Source/Core/Core/PowerPC/PPCAnalyst.cpp
index 312cf96ddd..733bf6d3b1 100644
--- a/Source/Core/Core/PowerPC/PPCAnalyst.cpp
+++ b/Source/Core/Core/PowerPC/PPCAnalyst.cpp
@@ -3,8 +3,10 @@
 // Refer to the license.txt file included.
 
 #include <algorithm>
+#include <map>
 #include <queue>
 #include <string>
+#include <vector>
 
 #include "Common/Assert.h"
 #include "Common/CommonTypes.h"
diff --git a/Source/Core/Core/PowerPC/SignatureDB/DSYSignatureDB.cpp b/Source/Core/Core/PowerPC/SignatureDB/DSYSignatureDB.cpp
index 1aea672ab6..f8f1fa7153 100644
--- a/Source/Core/Core/PowerPC/SignatureDB/DSYSignatureDB.cpp
+++ b/Source/Core/Core/PowerPC/SignatureDB/DSYSignatureDB.cpp
@@ -4,6 +4,7 @@
 
 #include <cstddef>
 #include <cstring>
+#include <string>
 
 #include "Common/CommonTypes.h"
 #include "Common/FileUtil.h"
diff --git a/Source/Core/Core/PowerPC/SignatureDB/MEGASignatureDB.cpp b/Source/Core/Core/PowerPC/SignatureDB/MEGASignatureDB.cpp
index 91ff8eb0e1..9e1a924667 100644
--- a/Source/Core/Core/PowerPC/SignatureDB/MEGASignatureDB.cpp
+++ b/Source/Core/Core/PowerPC/SignatureDB/MEGASignatureDB.cpp
@@ -9,6 +9,7 @@
 #include <fstream>
 #include <limits>
 #include <sstream>
+#include <string>
 #include <utility>
 
 #include "Common/FileUtil.h"
diff --git a/Source/Core/Core/PowerPC/SignatureDB/SignatureDB.cpp b/Source/Core/Core/PowerPC/SignatureDB/SignatureDB.cpp
index 4dfd5f64a0..fc9ab89f87 100644
--- a/Source/Core/Core/PowerPC/SignatureDB/SignatureDB.cpp
+++ b/Source/Core/Core/PowerPC/SignatureDB/SignatureDB.cpp
@@ -2,6 +2,7 @@
 // Licensed under GPLv2+
 // Refer to the license.txt file included.
 
+#include <memory>
 #include <string>
 
 #include "Common/CommonTypes.h"
diff --git a/Source/Core/Core/TitleDatabase.cpp b/Source/Core/Core/TitleDatabase.cpp
index 9225d6705d..286aba930e 100644
--- a/Source/Core/Core/TitleDatabase.cpp
+++ b/Source/Core/Core/TitleDatabase.cpp
@@ -5,6 +5,7 @@
 #include <cstddef>
 #include <fstream>
 #include <functional>
+#include <unordered_map>
 #include <utility>
 
 #include "Core/TitleDatabase.h"

From d9bb2ce3afa234a4abcde64b35809cd224982d84 Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Wed, 7 Jun 2017 01:07:43 -0400
Subject: [PATCH 23/57] DVDInterface: Amend lint formatting issues

---
 Source/Core/Core/HW/DVD/DVDInterface.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/Source/Core/Core/HW/DVD/DVDInterface.cpp b/Source/Core/Core/HW/DVD/DVDInterface.cpp
index 828157d744..2ea86942da 100644
--- a/Source/Core/Core/HW/DVD/DVDInterface.cpp
+++ b/Source/Core/Core/HW/DVD/DVDInterface.cpp
@@ -1214,9 +1214,8 @@ void ScheduleReads(u64 offset, u32 length, const DiscIO::Partition& partition, u
   u32 buffered_blocks = 0;
   u32 unbuffered_blocks = 0;
 
-  const u32 bytes_per_chunk = partition == DiscIO::PARTITION_NONE ?
-                                  DVD_ECC_BLOCK_SIZE :
-                                  DiscIO::VolumeWii::BLOCK_DATA_SIZE;
+  const u32 bytes_per_chunk =
+      partition == DiscIO::PARTITION_NONE ? DVD_ECC_BLOCK_SIZE : DiscIO::VolumeWii::BLOCK_DATA_SIZE;
 
   while (length > 0)
   {

From 7b490d7cb0d8ffb5b87cf724b964920650c549ca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?L=C3=A9o=20Lam?= <leo@innovatetechnologi.es>
Date: Wed, 7 Jun 2017 12:49:24 +0200
Subject: [PATCH 24/57] HW/WiiSaveCrypted: Don't use new/delete

---
 Source/Core/Core/HW/WiiSaveCrypted.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/Source/Core/Core/HW/WiiSaveCrypted.cpp b/Source/Core/Core/HW/WiiSaveCrypted.cpp
index d646fae570..46ba3fd33a 100644
--- a/Source/Core/Core/HW/WiiSaveCrypted.cpp
+++ b/Source/Core/Core/HW/WiiSaveCrypted.cpp
@@ -88,10 +88,9 @@ void CWiiSaveCrypted::ExportAllSaves()
   u32 success = 0;
   for (const u64& title : titles)
   {
-    CWiiSaveCrypted* export_save = new CWiiSaveCrypted("", title);
-    if (export_save->m_valid)
+    CWiiSaveCrypted export_save{"", title};
+    if (export_save.m_valid)
       success++;
-    delete export_save;
   }
   SuccessAlertT("Successfully exported %u saves to %s", success,
                 (File::GetUserPath(D_USER_IDX) + "private/wii/title/").c_str());

From 0b71b60ef0507cc919c03fdf8fb40cd57a2b312c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?L=C3=A9o=20Lam?= <leo@innovatetechnologi.es>
Date: Wed, 7 Jun 2017 22:40:51 +0200
Subject: [PATCH 25/57] DiscIO: Fix formatting

---
 Source/Core/DiscIO/FileSystemGCWii.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/Source/Core/DiscIO/FileSystemGCWii.cpp b/Source/Core/DiscIO/FileSystemGCWii.cpp
index cf14144f50..8cc55aabab 100644
--- a/Source/Core/DiscIO/FileSystemGCWii.cpp
+++ b/Source/Core/DiscIO/FileSystemGCWii.cpp
@@ -77,10 +77,10 @@ u64 FileSystemGCWii::ReadFile(const std::string& _rFullPath, u8* _pBuffer, u64 _
 
   u64 read_length = std::min(_MaxBufferSize, pFileInfo->m_FileSize - _OffsetInFile);
 
-  DEBUG_LOG(
-      DISCIO,
-      "Reading %" PRIx64 " bytes at %" PRIx64 " from file %s. Offset: %" PRIx64 " Size: %" PRIx64,
-      read_length, _OffsetInFile, _rFullPath.c_str(), pFileInfo->m_Offset, pFileInfo->m_FileSize);
+  DEBUG_LOG(DISCIO, "Reading %" PRIx64 " bytes at %" PRIx64 " from file %s. Offset: %" PRIx64
+                    " Size: %" PRIx64,
+            read_length, _OffsetInFile, _rFullPath.c_str(), pFileInfo->m_Offset,
+            pFileInfo->m_FileSize);
 
   m_rVolume->Read(pFileInfo->m_Offset + _OffsetInFile, read_length, _pBuffer, m_partition);
   return read_length;

From 0ddb6f9328933fd00e9070491c913dbfd5734b4c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?L=C3=A9o=20Lam?= <leo@innovatetechnologi.es>
Date: Wed, 7 Jun 2017 22:41:00 +0200
Subject: [PATCH 26/57] DiscIO: Use the correct offset shift for DOL exports

---
 Source/Core/DiscIO/FileSystemGCWii.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Source/Core/DiscIO/FileSystemGCWii.cpp b/Source/Core/DiscIO/FileSystemGCWii.cpp
index 8cc55aabab..b809047679 100644
--- a/Source/Core/DiscIO/FileSystemGCWii.cpp
+++ b/Source/Core/DiscIO/FileSystemGCWii.cpp
@@ -155,7 +155,7 @@ bool FileSystemGCWii::ExportApploader(const std::string& _rExportFolder) const
 std::optional<u64> FileSystemGCWii::GetBootDOLOffset() const
 {
   std::optional<u32> offset = m_rVolume->ReadSwapped<u32>(0x420, m_partition);
-  return offset ? static_cast<u64>(*offset) << 2 : std::optional<u64>();
+  return offset ? static_cast<u64>(*offset) << m_offset_shift : std::optional<u64>();
 }
 
 std::optional<u32> FileSystemGCWii::GetBootDOLSize(u64 dol_offset) const

From 4371dd201fedfd2fd878829a32f1ce0cbd36e142 Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Tue, 6 Jun 2017 17:41:55 -0700
Subject: [PATCH 27/57] msbuild: remove some remnants of Qt .ui/.qrc support

---
 Source/Core/DolphinQt2/DolphinQt2.vcxproj | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/Source/Core/DolphinQt2/DolphinQt2.vcxproj b/Source/Core/DolphinQt2/DolphinQt2.vcxproj
index f1bce1701c..8cfab8c065 100644
--- a/Source/Core/DolphinQt2/DolphinQt2.vcxproj
+++ b/Source/Core/DolphinQt2/DolphinQt2.vcxproj
@@ -58,14 +58,6 @@
       <AdditionalManifestFiles>DolphinQt2.manifest;%(AdditionalManifestFiles)</AdditionalManifestFiles>
     </Manifest>
   </ItemDefinitionGroup>
-  <!--QRC and UI files are handled automatically-->
-  <ItemGroup>
-    <QtResource Include="*.qrc" />
-  </ItemGroup>
-  <ItemGroup>
-    <QtUi Include="*.ui" />
-    <QtUi Include="GameList\*.ui" />
-  </ItemGroup>
   <!--MOC files need to be listed. Perhaps scan for Q_OBJECT in the future? (like automoc)-->
   <!--NOTE: When adding moc'd files, you must list the outputs in the following ItemGroup!-->
   <ItemGroup>

From 6b698948770478b2492591656a0d3026654c3873 Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Tue, 6 Jun 2017 17:49:11 -0700
Subject: [PATCH 28/57] msbuild: simplify Languages.vcxproj a bit

---
 Languages/Languages.vcxproj | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/Languages/Languages.vcxproj b/Languages/Languages.vcxproj
index 1bc6a6381a..c7d380a783 100644
--- a/Languages/Languages.vcxproj
+++ b/Languages/Languages.vcxproj
@@ -45,15 +45,15 @@
     <WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+  <PropertyGroup Label="Configuration">
     <ConfigurationType>Utility</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
     <PlatformToolset>v141</PlatformToolset>
   </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
-    <ConfigurationType>Utility</ConfigurationType>
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
+    <UseDebugLibraries>true</UseDebugLibraries>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
     <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v141</PlatformToolset>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">

From 0594f7db02fb1b7d5bccb05e25b7101dc7f2e5ca Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Tue, 6 Jun 2017 18:53:15 -0700
Subject: [PATCH 29/57] msbuild/DolphinQt: remove extra /INCREMENTAL. Already
 enabled for Debug.

---
 Source/Core/DolphinQt2/DolphinQt2.vcxproj | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/Source/Core/DolphinQt2/DolphinQt2.vcxproj b/Source/Core/DolphinQt2/DolphinQt2.vcxproj
index 8cfab8c065..9dbf6f2cd3 100644
--- a/Source/Core/DolphinQt2/DolphinQt2.vcxproj
+++ b/Source/Core/DolphinQt2/DolphinQt2.vcxproj
@@ -41,9 +41,6 @@
   </ImportGroup>
   <PropertyGroup Label="UserMacros">
   </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <LinkIncremental>true</LinkIncremental>
-  </PropertyGroup>
   <ItemDefinitionGroup>
     <Link>
       <AdditionalLibraryDirectories>$(ExternalsDir)ffmpeg\lib;$(ExternalsDir)OpenAL\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>

From 1bb26dddb1f4bb3f3bc77ebe760a8e796bdbbba1 Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Tue, 6 Jun 2017 21:41:20 -0700
Subject: [PATCH 30/57] msbuild: only set /NODEFAULTLIB in one place

---
 Source/Core/DolphinQt2/DolphinQt2.vcxproj | 2 --
 Source/Core/DolphinWX/DolphinWX.vcxproj   | 2 --
 Source/UnitTests/UnitTests.vcxproj        | 2 --
 Source/VSProps/Base.props                 | 2 ++
 4 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/Source/Core/DolphinQt2/DolphinQt2.vcxproj b/Source/Core/DolphinQt2/DolphinQt2.vcxproj
index 9dbf6f2cd3..a27fbff715 100644
--- a/Source/Core/DolphinQt2/DolphinQt2.vcxproj
+++ b/Source/Core/DolphinQt2/DolphinQt2.vcxproj
@@ -45,8 +45,6 @@
     <Link>
       <AdditionalLibraryDirectories>$(ExternalsDir)ffmpeg\lib;$(ExternalsDir)OpenAL\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalDependencies>avrt.lib;iphlpapi.lib;winmm.lib;setupapi.lib;opengl32.lib;glu32.lib;rpcrt4.lib;comctl32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <!--TODO fix up ffmpeg garbage-->
-      <AdditionalOptions>/NODEFAULTLIB:libcmt %(AdditionalOptions)</AdditionalOptions>
     </Link>
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\VideoInterface;$(ProjectDir)\GameList;$(ProjectDir)\Settings;$(ProjectDir)\Config;$(ProjectDir)\Config\Mapping;$(ProjectDir)\QtUtils;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
diff --git a/Source/Core/DolphinWX/DolphinWX.vcxproj b/Source/Core/DolphinWX/DolphinWX.vcxproj
index 5846e30916..08d8a1770c 100644
--- a/Source/Core/DolphinWX/DolphinWX.vcxproj
+++ b/Source/Core/DolphinWX/DolphinWX.vcxproj
@@ -40,8 +40,6 @@
     <Link>
       <AdditionalLibraryDirectories>$(ExternalsDir)ffmpeg\lib;$(ExternalsDir)OpenAL\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalDependencies>avrt.lib;iphlpapi.lib;winmm.lib;setupapi.lib;opengl32.lib;glu32.lib;rpcrt4.lib;comctl32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <!--TODO fix up ffmpeg garbage-->
-      <AdditionalOptions>/NODEFAULTLIB:libcmt %(AdditionalOptions)</AdditionalOptions>
     </Link>
     <ResourceCompile>
       <AdditionalIncludeDirectories>$(ExternalsDir)wxWidgets3\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
diff --git a/Source/UnitTests/UnitTests.vcxproj b/Source/UnitTests/UnitTests.vcxproj
index a0d9c67f24..ac927cea75 100644
--- a/Source/UnitTests/UnitTests.vcxproj
+++ b/Source/UnitTests/UnitTests.vcxproj
@@ -48,8 +48,6 @@
       <AdditionalLibraryDirectories>$(ExternalsDir)OpenAL\lib;$(ExternalsDir)ffmpeg\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalDependencies>avrt.lib;iphlpapi.lib;winmm.lib;setupapi.lib;opengl32.lib;glu32.lib;rpcrt4.lib;comctl32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <SubSystem>Console</SubSystem>
-      <!--TODO fix up ffmpeg garbage-->
-      <AdditionalOptions>/NODEFAULTLIB:libcmt %(AdditionalOptions)</AdditionalOptions>
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
diff --git a/Source/VSProps/Base.props b/Source/VSProps/Base.props
index 00e4d41af2..4fe3f0e379 100644
--- a/Source/VSProps/Base.props
+++ b/Source/VSProps/Base.props
@@ -137,6 +137,8 @@
     <Link Condition="'$(ConfigurationType)'=='Application'">
       <!--See Common/ucrtFreadWorkaround.cpp-->
       <ForceSymbolReferences>ucrtFreadWorkaround</ForceSymbolReferences>
+      <!--TODO fix up ffmpeg garbage-->
+      <AdditionalOptions>/NODEFAULTLIB:libcmt %(AdditionalOptions)</AdditionalOptions>
     </Link>
     <Lib>
       <TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>

From 8d37301b19c489b0ddb9d3b9fd5790be2dc72f0f Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Tue, 6 Jun 2017 22:02:38 -0700
Subject: [PATCH 31/57] msbuild: Remove hack for ObjectFileName (reduces build
 parallelism).

---
 Source/Core/Core/CMakeLists.txt                  |  2 +-
 Source/Core/Core/Core.vcxproj                    | 16 +++-------------
 Source/Core/Core/Core.vcxproj.filters            | 14 +++++++-------
 Source/Core/Core/IOS/Network/NCD/Manage.h        |  2 +-
 .../Network/NCD/{Config.cpp => WiiNetConfig.cpp} |  2 +-
 .../IOS/Network/NCD/{Config.h => WiiNetConfig.h} |  0
 6 files changed, 13 insertions(+), 23 deletions(-)
 rename Source/Core/Core/IOS/Network/NCD/{Config.cpp => WiiNetConfig.cpp} (97%)
 rename Source/Core/Core/IOS/Network/NCD/{Config.h => WiiNetConfig.h} (100%)

diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt
index b29f42fef8..00de803378 100644
--- a/Source/Core/Core/CMakeLists.txt
+++ b/Source/Core/Core/CMakeLists.txt
@@ -173,7 +173,7 @@ set(SRCS
   IOS/Network/KD/NetKDRequest.cpp
   IOS/Network/KD/NetKDTime.cpp
   IOS/Network/KD/NWC24Config.cpp
-  IOS/Network/NCD/Config.cpp
+  IOS/Network/NCD/WiiNetConfig.cpp
   IOS/Network/NCD/Manage.cpp
   IOS/Network/WD/Command.cpp
   IOS/SDIO/SDIOSlot0.cpp
diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj
index 7fccbc5fed..8dd469620c 100644
--- a/Source/Core/Core/Core.vcxproj
+++ b/Source/Core/Core/Core.vcxproj
@@ -35,16 +35,6 @@
     <Import Project="..\..\VSProps\PCHUse.props" />
   </ImportGroup>
   <PropertyGroup Label="UserMacros" />
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <ObjectFileName>$(IntDir)/%(RelativeDir)/</ObjectFileName>
-    </ClCompile>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <ObjectFileName>$(IntDir)/%(RelativeDir)/</ObjectFileName>
-    </ClCompile>
-  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="ActionReplay.cpp" />
     <ClCompile Include="Analytics.cpp" />
@@ -214,7 +204,7 @@
     <ClCompile Include="IOS\Network\KD\NetKDRequest.cpp" />
     <ClCompile Include="IOS\Network\KD\NetKDTime.cpp" />
     <ClCompile Include="IOS\Network\KD\NWC24Config.cpp" />
-    <ClCompile Include="IOS\Network\NCD\Config.cpp" />
+    <ClCompile Include="IOS\Network\NCD\WiiNetConfig.cpp" />
     <ClCompile Include="IOS\Network\NCD\Manage.cpp" />
     <ClCompile Include="IOS\Network\WD\Command.cpp" />
     <ClCompile Include="IOS\SDIO\SDIOSlot0.cpp" />
@@ -460,7 +450,7 @@
     <ClInclude Include="IOS\Network\KD\NetKDRequest.h" />
     <ClInclude Include="IOS\Network\KD\NetKDTime.h" />
     <ClInclude Include="IOS\Network\KD\NWC24Config.h" />
-    <ClInclude Include="IOS\Network\NCD\Config.h" />
+    <ClInclude Include="IOS\Network\NCD\WiiNetConfig.h" />
     <ClInclude Include="IOS\Network\NCD\Manage.h" />
     <ClInclude Include="IOS\Network\WD\Command.h" />
     <ClInclude Include="IOS\SDIO\SDIOSlot0.h" />
@@ -582,4 +572,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>
\ No newline at end of file
diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters
index b35e104119..421dd7e78b 100644
--- a/Source/Core/Core/Core.vcxproj.filters
+++ b/Source/Core/Core/Core.vcxproj.filters
@@ -778,9 +778,6 @@
     <ClCompile Include="IOS\Network\KD\NWC24Config.cpp">
       <Filter>IOS\Network\KD</Filter>
     </ClCompile>
-    <ClCompile Include="IOS\Network\NCD\Config.cpp">
-      <Filter>IOS\Network\NCD</Filter>
-    </ClCompile>
     <ClCompile Include="IOS\Network\NCD\Manage.cpp">
       <Filter>IOS\Network\NCD</Filter>
     </ClCompile>
@@ -858,6 +855,9 @@
     </ClCompile>
     <ClCompile Include="Config\Config.cpp" />
     <ClCompile Include="Config\GraphicsSettings.cpp" />
+    <ClCompile Include="IOS\Network\NCD\WiiNetConfig.cpp">
+      <Filter>IOS\Network\NCD</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="BootManager.h" />
@@ -1404,9 +1404,6 @@
     <ClInclude Include="IOS\Network\KD\NWC24Config.h">
       <Filter>IOS\Network\KD</Filter>
     </ClInclude>
-    <ClInclude Include="IOS\Network\NCD\Config.h">
-      <Filter>IOS\Network\NCD</Filter>
-    </ClInclude>
     <ClInclude Include="IOS\Network\NCD\Manage.h">
       <Filter>IOS\Network\NCD</Filter>
     </ClInclude>
@@ -1499,8 +1496,11 @@
     <ClInclude Include="ConfigLoaders\IsSettingSaveable.h">
       <Filter>ConfigLoader</Filter>
     </ClInclude>
+    <ClInclude Include="IOS\Network\NCD\WiiNetConfig.h">
+      <Filter>IOS\Network\NCD</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <Text Include="CMakeLists.txt" />
   </ItemGroup>
-</Project>
+</Project>
\ No newline at end of file
diff --git a/Source/Core/Core/IOS/Network/NCD/Manage.h b/Source/Core/Core/IOS/Network/NCD/Manage.h
index c4ce453697..2724d75577 100644
--- a/Source/Core/Core/IOS/Network/NCD/Manage.h
+++ b/Source/Core/Core/IOS/Network/NCD/Manage.h
@@ -8,7 +8,7 @@
 
 #include "Common/CommonTypes.h"
 #include "Core/IOS/Device.h"
-#include "Core/IOS/Network/NCD/Config.h"
+#include "Core/IOS/Network/NCD/WiiNetConfig.h"
 
 namespace IOS
 {
diff --git a/Source/Core/Core/IOS/Network/NCD/Config.cpp b/Source/Core/Core/IOS/Network/NCD/WiiNetConfig.cpp
similarity index 97%
rename from Source/Core/Core/IOS/Network/NCD/Config.cpp
rename to Source/Core/Core/IOS/Network/NCD/WiiNetConfig.cpp
index 489ba97ca9..e101f5be6c 100644
--- a/Source/Core/Core/IOS/Network/NCD/Config.cpp
+++ b/Source/Core/Core/IOS/Network/NCD/WiiNetConfig.cpp
@@ -2,7 +2,7 @@
 // Licensed under GPLv2+
 // Refer to the license.txt file included.
 
-#include "Core/IOS/Network/NCD/Config.h"
+#include "Core/IOS/Network/NCD/WiiNetConfig.h"
 
 #include <cstring>
 
diff --git a/Source/Core/Core/IOS/Network/NCD/Config.h b/Source/Core/Core/IOS/Network/NCD/WiiNetConfig.h
similarity index 100%
rename from Source/Core/Core/IOS/Network/NCD/Config.h
rename to Source/Core/Core/IOS/Network/NCD/WiiNetConfig.h

From 5dc7318281143edcc4196683f0862feab24ee370 Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Tue, 6 Jun 2017 23:01:34 -0700
Subject: [PATCH 32/57] msbuild: cleanup some old comments in
 DolphinQt2.vcxproj

---
 Source/Core/DolphinQt2/DolphinQt2.vcxproj | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/Source/Core/DolphinQt2/DolphinQt2.vcxproj b/Source/Core/DolphinQt2/DolphinQt2.vcxproj
index a27fbff715..3df174a646 100644
--- a/Source/Core/DolphinQt2/DolphinQt2.vcxproj
+++ b/Source/Core/DolphinQt2/DolphinQt2.vcxproj
@@ -155,11 +155,9 @@
     <ClCompile Include="ToolBar.cpp" />
   </ItemGroup>
   <!--Put standard C/C++ headers here-->
-  <!--
   <ItemGroup>
-    <ClInclude Include="Main.h" />
+    <ClInclude Include="Resources.h" />
   </ItemGroup>
-  -->
   <ItemGroup>
     <Text Include="CMakeLists.txt" />
   </ItemGroup>
@@ -234,10 +232,6 @@
     <BinaryFiles Include="$(TargetPath)" />
     <AllInputFiles Include="@(DataSysFiles);@(DataTxtFiles);@(ExternalDlls);@(BinaryFiles)" />
   </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="Resources.h" />
-  </ItemGroup>
-  <!--Disable copying to binary dir for now on the buildbot to prevent packaging of the outputs-->
   <Target Name="AfterBuild" Inputs="@(AllInputFiles)" Outputs="@(AllInputFiles -> '$(BinaryOutputDir)%(RecursiveDir)%(Filename)%(Extension)')">
     <Message Text="Copying Data directory..." Importance="High" />
     <Copy SourceFiles="@(DataSysFiles)" DestinationFolder="$(BinaryOutputDir)%(RecursiveDir)" Condition="!Exists('$(BinaryOutputDir)%(RecursiveDir)%(Filename)%(DataSysFiles.Extension)') OR $([System.DateTime]::Parse('%(ModifiedTime)').Ticks) &gt; $([System.IO.File]::GetLastWriteTime('$(BinaryOutputDir)%(RecursiveDir)%(Filename)%(DataSysFiles.Extension)').Ticks)" />
@@ -247,4 +241,4 @@
     <Message Text="Copy: @(BinaryFiles) -&gt; $(BinaryOutputDir)" Importance="High" />
     <Copy SourceFiles="@(BinaryFiles)" DestinationFolder="$(BinaryOutputDir)" />
   </Target>
-</Project>
+</Project>
\ No newline at end of file

From 4000009e8b66a904b51072e9e67a273bfef317a3 Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Wed, 7 Jun 2017 04:06:04 -0700
Subject: [PATCH 33/57] msbuild: disable warnings from Externals\enet

---
 Externals/enet/enet.vcxproj | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Externals/enet/enet.vcxproj b/Externals/enet/enet.vcxproj
index 71e0086faf..ac6fe790b1 100644
--- a/Externals/enet/enet.vcxproj
+++ b/Externals/enet/enet.vcxproj
@@ -61,6 +61,7 @@
   <ImportGroup Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
     <Import Project="..\..\Source\VSProps\Base.props" />
+    <Import Project="..\..\Source\VSProps\ClDisableAllWarnings.props" />
   </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup />

From 4f9dd7277b8d2f1f56071f753081451d361bb7e2 Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Wed, 7 Jun 2017 04:09:26 -0700
Subject: [PATCH 34/57] msvc: disable unused symbol warning in
 Core/Common/Crypto/ec.cpp

---
 Source/Core/Common/Crypto/ec.cpp | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/Source/Core/Common/Crypto/ec.cpp b/Source/Core/Common/Crypto/ec.cpp
index 9dca32878b..5fe7e9bb2b 100644
--- a/Source/Core/Common/Crypto/ec.cpp
+++ b/Source/Core/Common/Crypto/ec.cpp
@@ -15,6 +15,11 @@
 #include "Common/Crypto/bn.h"
 #include "Common/Crypto/ec.h"
 
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4505)
+#endif
+
 // y**2 + x*y = x**3 + x + b
 UNUSED static const u8 ec_b[30] = {0x00, 0x66, 0x64, 0x7e, 0xde, 0x6c, 0x33, 0x2c, 0x7f, 0x8c,
                                    0x09, 0x23, 0xbb, 0x58, 0x21, 0x3b, 0x33, 0x3b, 0x20, 0xe9,
@@ -404,3 +409,7 @@ void ec_priv_to_pub(const u8* k, u8* Q)
 {
   point_mul(Q, k, ec_G);
 }
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif

From f7f1d5d2ca1e5de5eda350a7af3bd46519bde2f8 Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Wed, 7 Jun 2017 04:10:23 -0700
Subject: [PATCH 35/57] msvc: disable meaningless constant truncation warnings
 in SDCardUtil

---
 Source/Core/Common/SDCardUtil.cpp | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/Source/Core/Common/SDCardUtil.cpp b/Source/Core/Common/SDCardUtil.cpp
index 1bb09878b6..9e72990747 100644
--- a/Source/Core/Common/SDCardUtil.cpp
+++ b/Source/Core/Common/SDCardUtil.cpp
@@ -49,6 +49,11 @@
 #include <unistd.h>  // for unlink()
 #endif
 
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4310)
+#endif
+
 /* Believe me, you *don't* want to change these constants !! */
 #define BYTES_PER_SECTOR 512
 #define RESERVED_SECTORS 32
@@ -289,3 +294,7 @@ FailWrite:
     ERROR_LOG(COMMON, "unlink(%s) failed: %s", filename.c_str(), GetLastErrorMsg().c_str());
   return false;
 }
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif

From a093b58aadff6e3515da27f8e35fcc7861b255b4 Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Wed, 7 Jun 2017 21:57:45 -0400
Subject: [PATCH 36/57] Core: Move SignatureDB and Config source files into
 filters

Keeps things organized instead of being in the root of Core's source
tree when using the filter view.
---
 Source/Core/Core/Core.vcxproj.filters | 54 +++++++++++++++++++++------
 1 file changed, 42 insertions(+), 12 deletions(-)

diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters
index 421dd7e78b..8163603ae9 100644
--- a/Source/Core/Core/Core.vcxproj.filters
+++ b/Source/Core/Core/Core.vcxproj.filters
@@ -154,6 +154,12 @@
     <Filter Include="IOS\WFS">
       <UniqueIdentifier>{1fa9df3e-6741-4045-b2f6-457b4a0540a9}</UniqueIdentifier>
     </Filter>
+    <Filter Include="Config">
+      <UniqueIdentifier>{a3d4778e-1891-458e-9bd1-009c2f5e8ed9}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="PowerPC\SignatureDB">
+      <UniqueIdentifier>{f0b52c84-49f4-470a-b037-edeea5634b9e}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="BootManager.cpp" />
@@ -687,10 +693,18 @@
       <Filter>PowerPC\Jit64Common</Filter>
     </ClCompile>
     <ClCompile Include="Analytics.cpp" />
-    <ClCompile Include="PowerPC\SignatureDB\CSVSignatureDB.cpp" />
-    <ClCompile Include="PowerPC\SignatureDB\DSYSignatureDB.cpp" />
-    <ClCompile Include="PowerPC\SignatureDB\MEGASignatureDB.cpp" />
-    <ClCompile Include="PowerPC\SignatureDB\SignatureDB.cpp" />
+    <ClCompile Include="PowerPC\SignatureDB\CSVSignatureDB.cpp">
+      <Filter>PowerPC\SignatureDB</Filter>
+    </ClCompile>
+    <ClCompile Include="PowerPC\SignatureDB\DSYSignatureDB.cpp">
+      <Filter>PowerPC\SignatureDB</Filter>
+    </ClCompile>
+    <ClCompile Include="PowerPC\SignatureDB\MEGASignatureDB.cpp">
+      <Filter>PowerPC\SignatureDB</Filter>
+    </ClCompile>
+    <ClCompile Include="PowerPC\SignatureDB\SignatureDB.cpp">
+      <Filter>PowerPC\SignatureDB</Filter>
+    </ClCompile>
     <ClCompile Include="IOS\USB\Bluetooth\BTBase.cpp">
       <Filter>IOS\USB\Bluetooth</Filter>
     </ClCompile>
@@ -853,8 +867,12 @@
     <ClCompile Include="ConfigLoaders\IsSettingSaveable.cpp">
       <Filter>ConfigLoader</Filter>
     </ClCompile>
-    <ClCompile Include="Config\Config.cpp" />
-    <ClCompile Include="Config\GraphicsSettings.cpp" />
+    <ClCompile Include="Config\Config.cpp">
+      <Filter>Config</Filter>
+    </ClCompile>
+    <ClCompile Include="Config\GraphicsSettings.cpp">
+      <Filter>Config</Filter>
+    </ClCompile>
     <ClCompile Include="IOS\Network\NCD\WiiNetConfig.cpp">
       <Filter>IOS\Network\NCD</Filter>
     </ClCompile>
@@ -1334,10 +1352,18 @@
       <Filter>PowerPC\Jit64Common</Filter>
     </ClInclude>
     <ClInclude Include="Analytics.h" />
-    <ClInclude Include="PowerPC\SignatureDB\CSVSignatureDB.h" />
-    <ClInclude Include="PowerPC\SignatureDB\DSYSignatureDB.h" />
-    <ClInclude Include="PowerPC\SignatureDB\MEGASignatureDB.h" />
-    <ClInclude Include="PowerPC\SignatureDB\SignatureDB.h" />
+    <ClInclude Include="PowerPC\SignatureDB\CSVSignatureDB.h">
+      <Filter>PowerPC\SignatureDB</Filter>
+    </ClInclude>
+    <ClInclude Include="PowerPC\SignatureDB\DSYSignatureDB.h">
+      <Filter>PowerPC\SignatureDB</Filter>
+    </ClInclude>
+    <ClInclude Include="PowerPC\SignatureDB\MEGASignatureDB.h">
+      <Filter>PowerPC\SignatureDB</Filter>
+    </ClInclude>
+    <ClInclude Include="PowerPC\SignatureDB\SignatureDB.h">
+      <Filter>PowerPC\SignatureDB</Filter>
+    </ClInclude>
     <ClInclude Include="IOS\USB\Bluetooth\BTBase.h">
       <Filter>IOS\USB\Bluetooth</Filter>
     </ClInclude>
@@ -1491,11 +1517,15 @@
     <ClInclude Include="ConfigLoaders\NetPlayConfigLoader.h">
       <Filter>ConfigLoader</Filter>
     </ClInclude>
-    <ClInclude Include="Config\Config.h" />
-    <ClInclude Include="Config\GraphicsSettings.h" />
     <ClInclude Include="ConfigLoaders\IsSettingSaveable.h">
       <Filter>ConfigLoader</Filter>
     </ClInclude>
+    <ClInclude Include="Config\Config.h">
+      <Filter>Config</Filter>
+    </ClInclude>
+    <ClInclude Include="Config\GraphicsSettings.h">
+      <Filter>Config</Filter>
+    </ClInclude>
     <ClInclude Include="IOS\Network\NCD\WiiNetConfig.h">
       <Filter>IOS\Network\NCD</Filter>
     </ClInclude>

From be7c6a081918ac2240f6a2e4e51ca6e3daa0f032 Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Wed, 7 Jun 2017 04:11:23 -0700
Subject: [PATCH 37/57] msvc: disable warning about using setjmp w/c++ objects
 in scope

---
 Source/Core/VideoCommon/ImageWrite.cpp | 31 +++++++++++++++++++++-----
 1 file changed, 25 insertions(+), 6 deletions(-)

diff --git a/Source/Core/VideoCommon/ImageWrite.cpp b/Source/Core/VideoCommon/ImageWrite.cpp
index 6156ca2cb1..e7930a18c6 100644
--- a/Source/Core/VideoCommon/ImageWrite.cpp
+++ b/Source/Core/VideoCommon/ImageWrite.cpp
@@ -21,6 +21,11 @@ bool SaveData(const std::string& filename, const std::string& data)
   return true;
 }
 
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4611)
+#endif
+
 /*
 TextureToPng
 
@@ -31,20 +36,16 @@ row_stride: Determines the amount of bytes per row of pixels.
 bool TextureToPng(const u8* data, int row_stride, const std::string& filename, int width,
                   int height, bool saveAlpha)
 {
-  bool success = false;
-
   if (!data)
     return false;
 
+  bool success = false;
   char title[] = "Dolphin Screenshot";
   char title_key[] = "Title";
   png_structp png_ptr = nullptr;
   png_infop info_ptr = nullptr;
   std::vector<u8> buffer;
 
-  if (!saveAlpha)
-    buffer.resize(width * 4);
-
   // Open file for writing (binary mode)
   File::IOFile fp(filename, "wb");
   if (!fp.IsOpen())
@@ -70,13 +71,22 @@ bool TextureToPng(const u8* data, int row_stride, const std::string& filename, i
     goto finalise;
   }
 
-  // Setup Exception handling
+  // Classical libpng error handling uses longjmp to do C-style unwind.
+  // Modern libpng does support a user callback, but it's required to operate
+  // in the same way (just gives a chance to do stuff before the longjmp).
+  // Instead of futzing with it, we use gotos specifically so the compiler
+  // will still generate proper destructor calls for us (hopefully).
+  // We also do not use any local variables outside the region longjmp may
+  // have been called from if they were modified inside that region (they
+  // would need to be volatile).
   if (setjmp(png_jmpbuf(png_ptr)))
   {
     PanicAlert("Screenshot failed: Error during PNG creation");
     goto finalise;
   }
 
+  // Begin region which may call longjmp
+
   png_init_io(png_ptr, fp.GetHandle());
 
   // Write header (8 bit color depth)
@@ -91,6 +101,9 @@ bool TextureToPng(const u8* data, int row_stride, const std::string& filename, i
 
   png_write_info(png_ptr, info_ptr);
 
+  if (!saveAlpha)
+    buffer.resize(width * 4);
+
   // Write image data
   for (auto y = 0; y < height; ++y)
   {
@@ -114,6 +127,8 @@ bool TextureToPng(const u8* data, int row_stride, const std::string& filename, i
   // End write
   png_write_end(png_ptr, nullptr);
 
+  // End region which may call longjmp
+
   success = true;
 
 finalise:
@@ -124,3 +139,7 @@ finalise:
 
   return success;
 }
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif

From e1a3e41bf33bf6a366760ede17c2e3bd2b106116 Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Wed, 7 Jun 2017 04:16:02 -0700
Subject: [PATCH 38/57] fix various instances of -1 being assigned to unsigned
 types

---
 Source/Core/Common/FileUtil.cpp                          | 2 +-
 Source/Core/Common/MathUtil.h                            | 2 +-
 Source/Core/Common/Profiler.cpp                          | 6 +++---
 Source/Core/Common/Thread.cpp                            | 9 +++------
 Source/Core/Core/Debugger/Dump.cpp                       | 4 ++--
 .../Core/PowerPC/Interpreter/Interpreter_Integer.cpp     | 2 +-
 Source/Core/Core/PowerPC/PPCAnalyst.cpp                  | 4 ++--
 Source/Core/DiscIO/CISOBlob.h                            | 2 +-
 Source/Core/DiscIO/VolumeDirectory.cpp                   | 2 +-
 Source/Core/DiscIO/VolumeWii.cpp                         | 3 ++-
 Source/Core/DolphinWX/Debugger/DSPDebugWindow.cpp        | 2 +-
 Source/Core/VideoBackends/OGL/TextureCache.cpp           | 8 ++++----
 Source/Core/VideoCommon/IndexGenerator.cpp               | 2 +-
 Source/Core/VideoCommon/TextureCacheBase.cpp             | 2 +-
 Source/Core/VideoCommon/VertexLoaderBase.h               | 2 +-
 15 files changed, 25 insertions(+), 27 deletions(-)

diff --git a/Source/Core/Common/FileUtil.cpp b/Source/Core/Common/FileUtil.cpp
index ebab9e9c48..2ae063673f 100644
--- a/Source/Core/Common/FileUtil.cpp
+++ b/Source/Core/Common/FileUtil.cpp
@@ -986,7 +986,7 @@ u64 IOFile::Tell() const
   if (IsOpen())
     return ftello(m_file);
   else
-    return -1;
+    return UINT64_MAX;
 }
 
 bool IOFile::Flush()
diff --git a/Source/Core/Common/MathUtil.h b/Source/Core/Common/MathUtil.h
index 7e48e38d80..becaf09792 100644
--- a/Source/Core/Common/MathUtil.h
+++ b/Source/Core/Common/MathUtil.h
@@ -198,7 +198,7 @@ inline int IntLog2(u64 val)
   return 63 - __builtin_clzll(val);
 
 #elif defined(_MSC_VER)
-  unsigned long result = -1;
+  unsigned long result = ULONG_MAX;
   _BitScanReverse64(&result, val);
   return result;
 
diff --git a/Source/Core/Common/Profiler.cpp b/Source/Core/Common/Profiler.cpp
index fdc356a164..0be14073bd 100644
--- a/Source/Core/Common/Profiler.cpp
+++ b/Source/Core/Common/Profiler.cpp
@@ -29,8 +29,8 @@ std::string Profiler::s_lazy_result = "";
 int Profiler::s_lazy_delay = 0;
 
 Profiler::Profiler(const std::string& name)
-    : m_name(name), m_usecs(0), m_usecs_min(-1), m_usecs_max(0), m_usecs_quad(0), m_calls(0),
-      m_depth(0)
+    : m_name(name), m_usecs(0), m_usecs_min(UINT64_MAX), m_usecs_max(0), m_usecs_quad(0),
+      m_calls(0), m_depth(0)
 {
   m_time = Common::Timer::GetTimeUs();
   s_max_length = std::max<u32>(s_max_length, u32(m_name.length()));
@@ -154,7 +154,7 @@ std::string Profiler::Read()
   buffer << std::setw(PROFILER_FIELD_LENGTH) << std::right << m_usecs_max;
 
   m_usecs = 0;
-  m_usecs_min = -1;
+  m_usecs_min = UINT64_MAX;
   m_usecs_max = 0;
   m_usecs_quad = 0;
   m_calls = 0;
diff --git a/Source/Core/Common/Thread.cpp b/Source/Core/Common/Thread.cpp
index 190653ee31..fa81314795 100644
--- a/Source/Core/Common/Thread.cpp
+++ b/Source/Core/Common/Thread.cpp
@@ -62,11 +62,8 @@ void SwitchCurrentThread()
 }
 
 // Sets the debugger-visible name of the current thread.
-// Uses undocumented (actually, it is now documented) trick.
-// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsdebug/html/vxtsksettingthreadname.asp
-
-// This is implemented much nicer in upcoming msvc++, see:
-// http://msdn.microsoft.com/en-us/library/xcb2z8hs(VS.100).aspx
+// Uses trick documented in:
+// https://docs.microsoft.com/en-us/visualstudio/debugger/how-to-set-a-thread-name-in-native-code
 void SetCurrentThreadName(const char* szThreadName)
 {
   static const DWORD MS_VC_EXCEPTION = 0x406D1388;
@@ -83,7 +80,7 @@ void SetCurrentThreadName(const char* szThreadName)
 
   info.dwType = 0x1000;
   info.szName = szThreadName;
-  info.dwThreadID = -1;  // dwThreadID;
+  info.dwThreadID = static_cast<DWORD>(-1);
   info.dwFlags = 0;
 
   __try
diff --git a/Source/Core/Core/Debugger/Dump.cpp b/Source/Core/Core/Debugger/Dump.cpp
index 45f8fde926..a7ee736caf 100644
--- a/Source/Core/Core/Debugger/Dump.cpp
+++ b/Source/Core/Core/Debugger/Dump.cpp
@@ -42,7 +42,7 @@ u32 CDump::GetGPR(int _step, int _gpr)
   u32 offset = _step * STRUCTUR_SIZE;
 
   if (offset >= m_size)
-    return -1;
+    return UINT32_MAX;
 
   return Read32(offset + OFFSET_GPR + (_gpr * 4));
 }
@@ -52,7 +52,7 @@ u32 CDump::GetPC(int _step)
   u32 offset = _step * STRUCTUR_SIZE;
 
   if (offset >= m_size)
-    return -1;
+    return UINT32_MAX;
 
   return Read32(offset + OFFSET_PC);
 }
diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp
index 480ee662da..65b8547b98 100644
--- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp
+++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp
@@ -495,7 +495,7 @@ void Interpreter::divwx(UGeckoInstruction inst)
     }
 
     if (((u32)a & 0x80000000) && b == 0)
-      rGPR[inst.RD] = -1;
+      rGPR[inst.RD] = UINT32_MAX;
     else
       rGPR[inst.RD] = 0;
   }
diff --git a/Source/Core/Core/PowerPC/PPCAnalyst.cpp b/Source/Core/Core/PowerPC/PPCAnalyst.cpp
index 733bf6d3b1..c34cfd72fc 100644
--- a/Source/Core/Core/PowerPC/PPCAnalyst.cpp
+++ b/Source/Core/Core/PowerPC/PPCAnalyst.cpp
@@ -730,8 +730,8 @@ u32 PPCAnalyzer::Analyze(u32 address, CodeBlock* block, CodeBuffer* buffer, u32
     code[i].opinfo = opinfo;
     code[i].address = address;
     code[i].inst = inst;
-    code[i].branchTo = -1;
-    code[i].branchToIndex = -1;
+    code[i].branchTo = UINT32_MAX;
+    code[i].branchToIndex = UINT32_MAX;
     code[i].skip = false;
     block->m_stats->numCycles += opinfo->numCycles;
     block->m_physical_addresses.insert(result.physical_address);
diff --git a/Source/Core/DiscIO/CISOBlob.h b/Source/Core/DiscIO/CISOBlob.h
index b674dedc18..a1c8c97b40 100644
--- a/Source/Core/DiscIO/CISOBlob.h
+++ b/Source/Core/DiscIO/CISOBlob.h
@@ -48,7 +48,7 @@ private:
   CISOFileReader(File::IOFile file);
 
   typedef u16 MapType;
-  static const MapType UNUSED_BLOCK_ID = -1;
+  static const MapType UNUSED_BLOCK_ID = UINT16_MAX;
 
   File::IOFile m_file;
   u64 m_size;
diff --git a/Source/Core/DiscIO/VolumeDirectory.cpp b/Source/Core/DiscIO/VolumeDirectory.cpp
index ed965983e6..f6f603d8ff 100644
--- a/Source/Core/DiscIO/VolumeDirectory.cpp
+++ b/Source/Core/DiscIO/VolumeDirectory.cpp
@@ -35,7 +35,7 @@ const size_t VolumeDirectory::MAX_ID_LENGTH;
 
 VolumeDirectory::VolumeDirectory(const std::string& directory, bool is_wii,
                                  const std::string& apploader, const std::string& dol)
-    : m_data_start_address(-1), m_disk_header(DISKHEADERINFO_ADDRESS),
+    : m_data_start_address(UINT64_MAX), m_disk_header(DISKHEADERINFO_ADDRESS),
       m_disk_header_info(std::make_unique<SDiskHeaderInfo>()), m_fst_address(0), m_dol_address(0)
 {
   m_root_directory = ExtractDirectoryName(directory);
diff --git a/Source/Core/DiscIO/VolumeWii.cpp b/Source/Core/DiscIO/VolumeWii.cpp
index f928bbcdf3..4b6ef56539 100644
--- a/Source/Core/DiscIO/VolumeWii.cpp
+++ b/Source/Core/DiscIO/VolumeWii.cpp
@@ -32,7 +32,8 @@ namespace DiscIO
 constexpr u64 PARTITION_DATA_OFFSET = 0x20000;
 
 VolumeWii::VolumeWii(std::unique_ptr<BlobReader> reader)
-    : m_pReader(std::move(reader)), m_game_partition(PARTITION_NONE), m_last_decrypted_block(-1)
+    : m_pReader(std::move(reader)), m_game_partition(PARTITION_NONE),
+      m_last_decrypted_block(UINT64_MAX)
 {
   _assert_(m_pReader);
 
diff --git a/Source/Core/DolphinWX/Debugger/DSPDebugWindow.cpp b/Source/Core/DolphinWX/Debugger/DSPDebugWindow.cpp
index 922fd3c0c7..8c4be0c3f4 100644
--- a/Source/Core/DolphinWX/Debugger/DSPDebugWindow.cpp
+++ b/Source/Core/DolphinWX/Debugger/DSPDebugWindow.cpp
@@ -32,7 +32,7 @@ static DSPDebuggerLLE* m_DebuggerFrame = nullptr;
 
 DSPDebuggerLLE::DSPDebuggerLLE(wxWindow* parent, wxWindowID id)
     : wxPanel(parent, id, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, _("DSP LLE Debugger")),
-      m_CachedStepCounter(-1), m_toolbar_item_size(FromDIP(wxSize(16, 16)))
+      m_CachedStepCounter(UINT64_MAX), m_toolbar_item_size(FromDIP(wxSize(16, 16)))
 {
   Bind(wxEVT_MENU, &DSPDebuggerLLE::OnChangeState, this, ID_RUNTOOL, ID_SHOWPCTOOL);
 
diff --git a/Source/Core/VideoBackends/OGL/TextureCache.cpp b/Source/Core/VideoBackends/OGL/TextureCache.cpp
index 2031d7e220..169dec0bc5 100644
--- a/Source/Core/VideoBackends/OGL/TextureCache.cpp
+++ b/Source/Core/VideoBackends/OGL/TextureCache.cpp
@@ -370,9 +370,9 @@ TextureCache::TextureCache()
 {
   CompileShaders();
 
-  s_ActiveTexture = -1;
+  s_ActiveTexture = UINT32_MAX;
   for (auto& gtex : s_Textures)
-    gtex = -1;
+    gtex = UINT32_MAX;
 
   if (g_ActiveConfig.backend_info.bSupportsPaletteConversion)
   {
@@ -519,8 +519,8 @@ bool TextureCache::CompileShaders()
 
   s_ColorMatrixUniform = glGetUniformLocation(s_ColorMatrixProgram.glprogid, "colmat");
   s_DepthMatrixUniform = glGetUniformLocation(s_DepthMatrixProgram.glprogid, "colmat");
-  s_ColorCbufid = -1;
-  s_DepthCbufid = -1;
+  s_ColorCbufid = UINT32_MAX;
+  s_DepthCbufid = UINT32_MAX;
 
   s_ColorCopyPositionUniform = glGetUniformLocation(s_ColorCopyProgram.glprogid, "copy_position");
   s_ColorMatrixPositionUniform =
diff --git a/Source/Core/VideoCommon/IndexGenerator.cpp b/Source/Core/VideoCommon/IndexGenerator.cpp
index 79dbc92597..74f6a8a728 100644
--- a/Source/Core/VideoCommon/IndexGenerator.cpp
+++ b/Source/Core/VideoCommon/IndexGenerator.cpp
@@ -16,7 +16,7 @@ u16* IndexGenerator::index_buffer_current;
 u16* IndexGenerator::BASEIptr;
 u32 IndexGenerator::base_index;
 
-static const u16 s_primitive_restart = -1;
+static const u16 s_primitive_restart = UINT16_MAX;
 
 static u16* (*primitive_table[8])(u16*, u32, u32);
 
diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp
index 613f2dfed9..72978f6752 100644
--- a/Source/Core/VideoCommon/TextureCacheBase.cpp
+++ b/Source/Core/VideoCommon/TextureCacheBase.cpp
@@ -994,7 +994,7 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFo
   float* const ColorMask = colmat + 20;
   ColorMask[0] = ColorMask[1] = ColorMask[2] = ColorMask[3] = 255.0f;
   ColorMask[4] = ColorMask[5] = ColorMask[6] = ColorMask[7] = 1.0f / 255.0f;
-  unsigned int cbufid = -1;
+  unsigned int cbufid = UINT_MAX;
   u32 srcFormat = bpmem.zcontrol.pixel_format;
   bool efbHasAlpha = srcFormat == PEControl::RGBA6_Z24;
 
diff --git a/Source/Core/VideoCommon/VertexLoaderBase.h b/Source/Core/VideoCommon/VertexLoaderBase.h
index a895300466..509ccb4310 100644
--- a/Source/Core/VideoCommon/VertexLoaderBase.h
+++ b/Source/Core/VideoCommon/VertexLoaderBase.h
@@ -36,7 +36,7 @@ public:
 private:
   size_t CalculateHash() const
   {
-    size_t h = -1;
+    size_t h = SIZE_MAX;
 
     for (auto word : vid)
     {

From f730b775b6663d7957c51b0cd234dfe73c189905 Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Wed, 7 Jun 2017 04:17:34 -0700
Subject: [PATCH 39/57] quiet warnings about possibly-uninitialized variable
 usage

---
 Source/Core/Core/HW/DVD/DVDInterface.cpp          | 4 ++--
 Source/Core/Core/IOS/USB/Bluetooth/BTReal.cpp     | 2 +-
 Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp  | 2 +-
 Source/Core/DolphinWX/Debugger/MemoryCheckDlg.cpp | 2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/Source/Core/Core/HW/DVD/DVDInterface.cpp b/Source/Core/Core/HW/DVD/DVDInterface.cpp
index 2ea86942da..ee02b90533 100644
--- a/Source/Core/Core/HW/DVD/DVDInterface.cpp
+++ b/Source/Core/Core/HW/DVD/DVDInterface.cpp
@@ -349,8 +349,8 @@ static void DTKStreamingCallback(const std::vector<u8>& audio_data, s64 cycles_l
 
   // Determine which audio data to read next.
   static const int MAXIMUM_SAMPLES = 48000 / 2000 * 7;  // 3.5ms of 48kHz samples
-  u64 read_offset;
-  u32 read_length;
+  u64 read_offset = 0;
+  u32 read_length = 0;
   if (s_stream && AudioInterface::IsPlaying())
   {
     read_offset = s_audio_position;
diff --git a/Source/Core/Core/IOS/USB/Bluetooth/BTReal.cpp b/Source/Core/Core/IOS/USB/Bluetooth/BTReal.cpp
index caf3136ff4..d3aa66fc7c 100644
--- a/Source/Core/Core/IOS/USB/Bluetooth/BTReal.cpp
+++ b/Source/Core/Core/IOS/USB/Bluetooth/BTReal.cpp
@@ -533,7 +533,7 @@ void BluetoothReal::LoadLinkKeys()
     std::reverse(address.begin(), address.end());
 
     const std::string& key_string = pair.substr(index + 1);
-    linkkey_t key;
+    linkkey_t key{};
     size_t pos = 0;
     for (size_t i = 0; i < key_string.length(); i = i + 2)
     {
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp
index 1d34bf4796..fc6e1f262a 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit_LoadStore.cpp
@@ -202,7 +202,7 @@ void Jit64::lXXx(UGeckoInstruction inst)
       // If we're using reg+reg mode and b is an immediate, pretend we're using constant offset mode
       bool use_constant_offset = inst.OPCD != 31 || gpr.R(b).IsImm();
 
-      s32 offset;
+      s32 offset = 0;
       if (use_constant_offset)
         offset = inst.OPCD == 31 ? gpr.R(b).SImm32() : (s32)inst.SIMM_16;
       // Depending on whether we have an immediate and/or update, find the optimum way to calculate
diff --git a/Source/Core/DolphinWX/Debugger/MemoryCheckDlg.cpp b/Source/Core/DolphinWX/Debugger/MemoryCheckDlg.cpp
index 6d6b1450e7..ac870c8804 100644
--- a/Source/Core/DolphinWX/Debugger/MemoryCheckDlg.cpp
+++ b/Source/Core/DolphinWX/Debugger/MemoryCheckDlg.cpp
@@ -154,7 +154,7 @@ void MemoryCheckDlg::OnOK(wxCommandEvent& event)
   bool Log = m_radioLog->GetValue() || m_radioBreakLog->GetValue();
   bool Break = m_radioBreak->GetValue() || m_radioBreakLog->GetValue();
 
-  u32 StartAddress, EndAddress;
+  u32 StartAddress = UINT32_MAX, EndAddress = 0;
   bool EndAddressOK =
       EndAddressString.Len() && AsciiToHex(WxStrToStr(EndAddressString), EndAddress);
 

From 90f863a7a301558a3da553f06d4c1d3ff162eac0 Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Wed, 7 Jun 2017 04:18:23 -0700
Subject: [PATCH 40/57] HLE: fix unreachable code warning

---
 Source/Core/Core/HLE/HLE.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Source/Core/Core/HLE/HLE.cpp b/Source/Core/Core/HLE/HLE.cpp
index cc166768da..5fb7fac59c 100644
--- a/Source/Core/Core/HLE/HLE.cpp
+++ b/Source/Core/Core/HLE/HLE.cpp
@@ -247,8 +247,10 @@ u32 UnPatch(const std::string& patch_name)
     return addr;
   }
 
-  for (const auto& symbol : g_symbolDB.GetSymbolsFromName(patch_name))
+  const auto& symbols = g_symbolDB.GetSymbolsFromName(patch_name);
+  if (symbols.size())
   {
+    const auto& symbol = symbols[0];
     for (u32 addr = symbol->address; addr < symbol->address + symbol->size; addr += 4)
     {
       s_original_instructions.erase(addr);

From 7e75a052a4877c876f9ab8c48ecbd009d4e6637d Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Wed, 7 Jun 2017 04:19:28 -0700
Subject: [PATCH 41/57] windows/bba: pass c_str() instead of std::string object
 through a va_list

---
 Source/Core/Core/HW/EXI/BBA-TAP/TAP_Win32.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Source/Core/Core/HW/EXI/BBA-TAP/TAP_Win32.cpp b/Source/Core/Core/HW/EXI/BBA-TAP/TAP_Win32.cpp
index f825f5eef6..58e497a8fb 100644
--- a/Source/Core/Core/HW/EXI/BBA-TAP/TAP_Win32.cpp
+++ b/Source/Core/Core/HW/EXI/BBA-TAP/TAP_Win32.cpp
@@ -157,7 +157,7 @@ bool OpenTAP(HANDLE& adapter, const std::basic_string<TCHAR>& device_guid)
 
   if (adapter == INVALID_HANDLE_VALUE)
   {
-    INFO_LOG(SP1, "Failed to open TAP at %s", device_path);
+    INFO_LOG(SP1, "Failed to open TAP at %s", device_path.c_str());
     return false;
   }
   return true;

From 4a1b32afe4e2ab41be63b9d145100e6a0bffc424 Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Wed, 7 Jun 2017 04:20:26 -0700
Subject: [PATCH 42/57] windows: use proper type/constant for NET_IFINDEX in
 ios hle

---
 Source/Core/Core/IOS/Network/IP/Top.cpp | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/Source/Core/Core/IOS/Network/IP/Top.cpp b/Source/Core/Core/IOS/Network/IP/Top.cpp
index cd25283e1a..2b15ae6e46 100644
--- a/Source/Core/Core/IOS/Network/IP/Top.cpp
+++ b/Source/Core/Core/IOS/Network/IP/Top.cpp
@@ -431,7 +431,7 @@ IPCCommandResult NetIPTop::HandleGetHostIDRequest(const IOCtlRequest& request)
 
 #ifdef _WIN32
   DWORD forwardTableSize, ipTableSize, result;
-  DWORD ifIndex = -1;
+  NET_IFINDEX ifIndex = NET_IFINDEX_UNSPECIFIED;
   std::unique_ptr<MIB_IPFORWARDTABLE> forwardTable;
   std::unique_ptr<MIB_IPADDRTABLE> ipTable;
 
@@ -462,13 +462,14 @@ IPCCommandResult NetIPTop::HandleGetHostIDRequest(const IOCtlRequest& request)
       }
     }
 
-    if (result == NO_ERROR || ifIndex != -1)
+    if (result == NO_ERROR || ifIndex != NET_IFINDEX_UNSPECIFIED)
       break;
 
     result = GetIpForwardTable(forwardTable.get(), &forwardTableSize, FALSE);
   }
 
-  if (ifIndex != -1 && GetIpAddrTable(ipTable.get(), &ipTableSize, FALSE) == NO_ERROR)
+  if (ifIndex != NET_IFINDEX_UNSPECIFIED &&
+      GetIpAddrTable(ipTable.get(), &ipTableSize, FALSE) == NO_ERROR)
   {
     for (DWORD i = 0; i < ipTable->dwNumEntries; ++i)
     {

From 8f12d7fb3cdb5138d28ede4bdcd6fa5a7cc9537e Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Wed, 7 Jun 2017 04:22:07 -0700
Subject: [PATCH 43/57] ios/net/ip/top: introduce a helper to write ip addr
 (quiets warning)

---
 Source/Core/Core/IOS/Network/IP/Top.cpp | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/Source/Core/Core/IOS/Network/IP/Top.cpp b/Source/Core/Core/IOS/Network/IP/Top.cpp
index 2b15ae6e46..b11800e12d 100644
--- a/Source/Core/Core/IOS/Network/IP/Top.cpp
+++ b/Source/Core/Core/IOS/Network/IP/Top.cpp
@@ -76,6 +76,11 @@ NetIPTop::~NetIPTop()
 #endif
 }
 
+static constexpr u32 inet_addr(u8 a, u8 b, u8 c, u8 d)
+{
+  return (static_cast<u32>(a) << 24) | (static_cast<u32>(b) << 16) | (static_cast<u32>(c) << 8) | d;
+}
+
 static int inet_pton(const char* src, unsigned char* dst)
 {
   int saw_digit, octets;
@@ -818,9 +823,9 @@ IPCCommandResult NetIPTop::HandleGetInterfaceOptRequest(const IOCtlVRequest& req
 
   case 0x4003:  // ip addr table
     Memory::Write_U32(0xC, request.io_vectors[1].address);
-    Memory::Write_U32(10 << 24 | 1 << 8 | 30, request.io_vectors[0].address);
-    Memory::Write_U32(255 << 24 | 255 << 16 | 255 << 8 | 0, request.io_vectors[0].address + 4);
-    Memory::Write_U32(10 << 24 | 0 << 16 | 255 << 8 | 255, request.io_vectors[0].address + 8);
+    Memory::Write_U32(inet_addr(10, 0, 1, 30), request.io_vectors[0].address);
+    Memory::Write_U32(inet_addr(255, 255, 255, 0), request.io_vectors[0].address + 4);
+    Memory::Write_U32(inet_addr(10, 0, 255, 255), request.io_vectors[0].address + 8);
     break;
 
   case 0x4005:  // hardcoded value

From ebd3d43b7d8b338f179378b600083e96e46e09d1 Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Wed, 7 Jun 2017 04:25:30 -0700
Subject: [PATCH 44/57] ios/es: make fd s32 -> quiets warnings

---
 Source/Core/Core/IOS/ES/ES.cpp | 2 +-
 Source/Core/Core/IOS/ES/ES.h   | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/Source/Core/Core/IOS/ES/ES.cpp b/Source/Core/Core/IOS/ES/ES.cpp
index 430045705a..6023325681 100644
--- a/Source/Core/Core/IOS/ES/ES.cpp
+++ b/Source/Core/Core/IOS/ES/ES.cpp
@@ -328,7 +328,7 @@ void ES::DoState(PointerWrap& p)
   }
 }
 
-ES::ContextArray::iterator ES::FindActiveContext(u32 fd)
+ES::ContextArray::iterator ES::FindActiveContext(s32 fd)
 {
   return std::find_if(m_contexts.begin(), m_contexts.end(),
                       [fd](const auto& context) { return context.ipc_fd == fd && context.active; });
diff --git a/Source/Core/Core/IOS/ES/ES.h b/Source/Core/Core/IOS/ES/ES.h
index 1deb3919d7..b56ac57b69 100644
--- a/Source/Core/Core/IOS/ES/ES.h
+++ b/Source/Core/Core/IOS/ES/ES.h
@@ -94,7 +94,7 @@ public:
     TitleExportContext title_export;
     bool active = false;
     // We use this to associate an IPC fd with an ES context.
-    u32 ipc_fd = -1;
+    s32 ipc_fd = -1;
   };
 
   // Title management
@@ -277,7 +277,7 @@ private:
   IPCCommandResult DIGetTMDSize(const IOCtlVRequest& request);
   IPCCommandResult DIGetTMD(const IOCtlVRequest& request);
 
-  ContextArray::iterator FindActiveContext(u32 fd);
+  ContextArray::iterator FindActiveContext(s32 fd);
   ContextArray::iterator FindInactiveContext();
 
   bool LaunchIOS(u64 ios_title_id);

From 5b5c630afb14178e17385229ea4675f155a4ec7c Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Wed, 7 Jun 2017 04:26:36 -0700
Subject: [PATCH 45/57] set underlying type of some enums to quiet warnings

---
 Source/Core/Core/HW/DSPHLE/UCodes/UCodes.h | 2 +-
 Source/Core/Core/HW/Memmap.cpp             | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Source/Core/Core/HW/DSPHLE/UCodes/UCodes.h b/Source/Core/Core/HW/DSPHLE/UCodes/UCodes.h
index 6cc8b45242..07dc0f3e1d 100644
--- a/Source/Core/Core/HW/DSPHLE/UCodes/UCodes.h
+++ b/Source/Core/Core/HW/DSPHLE/UCodes/UCodes.h
@@ -63,7 +63,7 @@ protected:
 
   CMailHandler& m_mail_handler;
 
-  enum EDSP_Codes
+  enum EDSP_Codes : u32
   {
     DSP_INIT = 0xDCD10000,
     DSP_RESUME = 0xDCD10001,
diff --git a/Source/Core/Core/HW/Memmap.cpp b/Source/Core/Core/HW/Memmap.cpp
index 9be01f9612..ac69e4cd6c 100644
--- a/Source/Core/Core/HW/Memmap.cpp
+++ b/Source/Core/Core/HW/Memmap.cpp
@@ -99,7 +99,7 @@ struct PhysicalMemoryRegion
   u8** out_pointer;
   u32 physical_address;
   u32 size;
-  enum
+  enum : u32
   {
     ALWAYS = 0,
     FAKE_VMEM = 1,

From 983f70c9eaae4eb4028339624bbb0c9a52a1f8d3 Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Wed, 7 Jun 2017 04:27:32 -0700
Subject: [PATCH 46/57] ios: treat return values as s32

---
 Source/Core/Core/IOS/IOS.h                    |  7 +++
 Source/Core/Core/IOS/Network/KD/NWC24Config.h |  2 +-
 .../Core/Core/IOS/Network/KD/NetKDRequest.cpp | 16 +++----
 Source/Core/Core/IOS/Network/SSL.cpp          | 48 +++++++++----------
 Source/Core/Core/IOS/Network/SSL.h            |  2 +-
 Source/Core/Core/IOS/Network/Socket.cpp       | 28 +++++------
 Source/Core/Core/IOS/SDIO/SDIOSlot0.cpp       |  4 +-
 Source/Core/Core/IOS/SDIO/SDIOSlot0.h         |  2 +-
 Source/Core/Core/IOS/WFS/WFSI.cpp             |  2 +-
 9 files changed, 59 insertions(+), 52 deletions(-)

diff --git a/Source/Core/Core/IOS/IOS.h b/Source/Core/Core/IOS/IOS.h
index 32bcdc1694..6c49a70ec4 100644
--- a/Source/Core/Core/IOS/IOS.h
+++ b/Source/Core/Core/IOS/IOS.h
@@ -14,6 +14,7 @@
 
 #include "Common/CommonTypes.h"
 #include "Core/CoreTiming.h"
+#include "Core/HW/Memmap.h"
 #include "Core/HW/SystemTimers.h"
 #include "Core/IOS/IOSC.h"
 
@@ -82,6 +83,12 @@ enum ProcessId : u32
   PID_UNKNOWN = 19,
 };
 
+template <typename T>
+void WriteReturnValue(T value, u32 address)
+{
+  Memory::Write_U32(static_cast<u32>(value), address);
+}
+
 // HLE for the IOS kernel: IPC, device management, syscalls, and Dolphin-specific, IOS-wide calls.
 class Kernel
 {
diff --git a/Source/Core/Core/IOS/Network/KD/NWC24Config.h b/Source/Core/Core/IOS/Network/KD/NWC24Config.h
index 8aa07fc979..f25fb7b5fb 100644
--- a/Source/Core/Core/IOS/Network/KD/NWC24Config.h
+++ b/Source/Core/Core/IOS/Network/KD/NWC24Config.h
@@ -13,7 +13,7 @@ namespace HLE
 {
 namespace NWC24
 {
-enum ErrorCode : int
+enum ErrorCode : s32
 {
   WC24_OK = 0,
   WC24_ERR_FATAL = -1,
diff --git a/Source/Core/Core/IOS/Network/KD/NetKDRequest.cpp b/Source/Core/Core/IOS/Network/KD/NetKDRequest.cpp
index 48c9e27da0..cbcf245fe9 100644
--- a/Source/Core/Core/IOS/Network/KD/NetKDRequest.cpp
+++ b/Source/Core/Core/IOS/Network/KD/NetKDRequest.cpp
@@ -41,7 +41,7 @@ IPCCommandResult NetKDRequest::IOCtl(const IOCtlRequest& request)
   case IOCTL_NWC24_SUSPEND_SCHEDULAR:
     // NWC24iResumeForCloseLib  from NWC24SuspendScheduler (Input: none, Output: 32 bytes)
     INFO_LOG(IOS_WC24, "NET_KD_REQ: IOCTL_NWC24_SUSPEND_SCHEDULAR - NI");
-    Memory::Write_U32(0, request.buffer_out);  // no error
+    WriteReturnValue(0, request.buffer_out);  // no error
     break;
 
   case IOCTL_NWC24_EXEC_TRY_SUSPEND_SCHEDULAR:  // NWC24iResumeForCloseLib
@@ -50,11 +50,11 @@ IPCCommandResult NetKDRequest::IOCtl(const IOCtlRequest& request)
 
   case IOCTL_NWC24_EXEC_RESUME_SCHEDULAR:  // NWC24iResumeForCloseLib
     INFO_LOG(IOS_WC24, "NET_KD_REQ: IOCTL_NWC24_EXEC_RESUME_SCHEDULAR - NI");
-    Memory::Write_U32(0, request.buffer_out);  // no error
+    WriteReturnValue(0, request.buffer_out);  // no error
     break;
 
   case IOCTL_NWC24_STARTUP_SOCKET:  // NWC24iStartupSocket
-    Memory::Write_U32(0, request.buffer_out);
+    WriteReturnValue(0, request.buffer_out);
     Memory::Write_U32(0, request.buffer_out + 4);
     return_value = 0;
     INFO_LOG(IOS_WC24, "NET_KD_REQ: IOCTL_NWC24_STARTUP_SOCKET - NI");
@@ -74,7 +74,7 @@ IPCCommandResult NetKDRequest::IOCtl(const IOCtlRequest& request)
 
   case IOCTL_NWC24_REQUEST_REGISTER_USER_ID:
     INFO_LOG(IOS_WC24, "NET_KD_REQ: IOCTL_NWC24_REQUEST_REGISTER_USER_ID");
-    Memory::Write_U32(0, request.buffer_out);
+    WriteReturnValue(0, request.buffer_out);
     Memory::Write_U32(0, request.buffer_out + 4);
     break;
 
@@ -110,20 +110,20 @@ IPCCommandResult NetKDRequest::IOCtl(const IOCtlRequest& request)
         config.SetCreationStage(NWC24::NWC24Config::NWC24_IDCS_GENERATED);
         config.WriteConfig();
 
-        Memory::Write_U32(ret, request.buffer_out);
+        WriteReturnValue(ret, request.buffer_out);
       }
       else
       {
-        Memory::Write_U32(NWC24::WC24_ERR_FATAL, request.buffer_out);
+        WriteReturnValue(NWC24::WC24_ERR_FATAL, request.buffer_out);
       }
     }
     else if (config.CreationStage() == NWC24::NWC24Config::NWC24_IDCS_GENERATED)
     {
-      Memory::Write_U32(NWC24::WC24_ERR_ID_GENERATED, request.buffer_out);
+      WriteReturnValue(NWC24::WC24_ERR_ID_GENERATED, request.buffer_out);
     }
     else if (config.CreationStage() == NWC24::NWC24Config::NWC24_IDCS_REGISTERED)
     {
-      Memory::Write_U32(NWC24::WC24_ERR_ID_REGISTERED, request.buffer_out);
+      WriteReturnValue(NWC24::WC24_ERR_ID_REGISTERED, request.buffer_out);
     }
     Memory::Write_U64(config.Id(), request.buffer_out + 4);
     Memory::Write_U32(config.CreationStage(), request.buffer_out + 0xC);
diff --git a/Source/Core/Core/IOS/Network/SSL.cpp b/Source/Core/Core/IOS/Network/SSL.cpp
index ef826a7a58..925ab34f56 100644
--- a/Source/Core/Core/IOS/Network/SSL.cpp
+++ b/Source/Core/Core/IOS/Network/SSL.cpp
@@ -221,12 +221,12 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
       mbedtls_ssl_set_hostname(&ssl->ctx, ssl->hostname.c_str());
 
       ssl->active = true;
-      Memory::Write_U32(freeSSL, BufferIn);
+      WriteReturnValue(freeSSL, BufferIn);
     }
     else
     {
     _SSL_NEW_ERROR:
-      Memory::Write_U32(SSL_ERR_FAILED, BufferIn);
+      WriteReturnValue(SSL_ERR_FAILED, BufferIn);
     }
 
     INFO_LOG(IOS_SSL, "IOCTLV_NET_SSL_NEW (%d, %s) "
@@ -260,11 +260,11 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
 
       ssl->active = false;
 
-      Memory::Write_U32(SSL_OK, BufferIn);
+      WriteReturnValue(SSL_OK, BufferIn);
     }
     else
     {
-      Memory::Write_U32(SSL_ERR_ID, BufferIn);
+      WriteReturnValue(SSL_ERR_ID, BufferIn);
     }
     INFO_LOG(IOS_SSL, "IOCTLV_NET_SSL_SHUTDOWN "
                       "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
@@ -298,19 +298,19 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
 
       if (ret)
       {
-        Memory::Write_U32(SSL_ERR_FAILED, BufferIn);
+        WriteReturnValue(SSL_ERR_FAILED, BufferIn);
       }
       else
       {
         mbedtls_ssl_conf_ca_chain(&ssl->config, &ssl->cacert, nullptr);
-        Memory::Write_U32(SSL_OK, BufferIn);
+        WriteReturnValue(SSL_OK, BufferIn);
       }
 
       INFO_LOG(IOS_SSL, "IOCTLV_NET_SSL_SETROOTCA = %d", ret);
     }
     else
     {
-      Memory::Write_U32(SSL_ERR_ID, BufferIn);
+      WriteReturnValue(SSL_ERR_ID, BufferIn);
     }
     break;
   }
@@ -339,19 +339,19 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
       {
         mbedtls_x509_crt_free(&ssl->clicert);
         mbedtls_pk_free(&ssl->pk);
-        Memory::Write_U32(SSL_ERR_FAILED, BufferIn);
+        WriteReturnValue(SSL_ERR_FAILED, BufferIn);
       }
       else
       {
         mbedtls_ssl_conf_own_cert(&ssl->config, &ssl->clicert, &ssl->pk);
-        Memory::Write_U32(SSL_OK, BufferIn);
+        WriteReturnValue(SSL_OK, BufferIn);
       }
 
       INFO_LOG(IOS_SSL, "IOCTLV_NET_SSL_SETBUILTINCLIENTCERT = (%d, %d)", ret, pk_ret);
     }
     else
     {
-      Memory::Write_U32(SSL_ERR_ID, BufferIn);
+      WriteReturnValue(SSL_ERR_ID, BufferIn);
       INFO_LOG(IOS_SSL, "IOCTLV_NET_SSL_SETBUILTINCLIENTCERT invalid sslID = %d", sslID);
     }
     break;
@@ -373,11 +373,11 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
       mbedtls_pk_free(&ssl->pk);
 
       mbedtls_ssl_conf_own_cert(&ssl->config, nullptr, nullptr);
-      Memory::Write_U32(SSL_OK, BufferIn);
+      WriteReturnValue(SSL_OK, BufferIn);
     }
     else
     {
-      Memory::Write_U32(SSL_ERR_ID, BufferIn);
+      WriteReturnValue(SSL_ERR_ID, BufferIn);
       INFO_LOG(IOS_SSL, "IOCTLV_NET_SSL_SETBUILTINCLIENTCERT invalid sslID = %d", sslID);
     }
     break;
@@ -395,18 +395,18 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
       if (ret)
       {
         mbedtls_x509_crt_free(&ssl->clicert);
-        Memory::Write_U32(SSL_ERR_FAILED, BufferIn);
+        WriteReturnValue(SSL_ERR_FAILED, BufferIn);
       }
       else
       {
         mbedtls_ssl_conf_ca_chain(&ssl->config, &ssl->cacert, nullptr);
-        Memory::Write_U32(SSL_OK, BufferIn);
+        WriteReturnValue(SSL_OK, BufferIn);
       }
       INFO_LOG(IOS_SSL, "IOCTLV_NET_SSL_SETBUILTINROOTCA = %d", ret);
     }
     else
     {
-      Memory::Write_U32(SSL_ERR_ID, BufferIn);
+      WriteReturnValue(SSL_ERR_ID, BufferIn);
     }
     INFO_LOG(IOS_SSL, "IOCTLV_NET_SSL_SETBUILTINROOTCA "
                       "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
@@ -428,11 +428,11 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
       ssl->hostfd = sm.GetHostSocket(ssl->sockfd);
       INFO_LOG(IOS_SSL, "IOCTLV_NET_SSL_CONNECT socket = %d", ssl->sockfd);
       mbedtls_ssl_set_bio(&ssl->ctx, &ssl->hostfd, mbedtls_net_send, mbedtls_net_recv, nullptr);
-      Memory::Write_U32(SSL_OK, BufferIn);
+      WriteReturnValue(SSL_OK, BufferIn);
     }
     else
     {
-      Memory::Write_U32(SSL_ERR_ID, BufferIn);
+      WriteReturnValue(SSL_ERR_ID, BufferIn);
     }
     INFO_LOG(IOS_SSL, "IOCTLV_NET_SSL_CONNECT "
                       "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
@@ -453,7 +453,7 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
     }
     else
     {
-      Memory::Write_U32(SSL_ERR_ID, BufferIn);
+      WriteReturnValue(SSL_ERR_ID, BufferIn);
     }
     break;
   }
@@ -468,7 +468,7 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
     }
     else
     {
-      Memory::Write_U32(SSL_ERR_ID, BufferIn);
+      WriteReturnValue(SSL_ERR_ID, BufferIn);
     }
     INFO_LOG(IOS_SSL, "IOCTLV_NET_SSL_WRITE "
                       "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
@@ -491,7 +491,7 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
     }
     else
     {
-      Memory::Write_U32(SSL_ERR_ID, BufferIn);
+      WriteReturnValue(SSL_ERR_ID, BufferIn);
     }
 
     INFO_LOG(IOS_SSL, "IOCTLV_NET_SSL_READ(%d)"
@@ -507,11 +507,11 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
     int sslID = Memory::Read_U32(BufferOut) - 1;
     if (SSLID_VALID(sslID))
     {
-      Memory::Write_U32(SSL_OK, BufferIn);
+      WriteReturnValue(SSL_OK, BufferIn);
     }
     else
     {
-      Memory::Write_U32(SSL_ERR_ID, BufferIn);
+      WriteReturnValue(SSL_ERR_ID, BufferIn);
     }
     INFO_LOG(IOS_SSL, "IOCTLV_NET_SSL_SETROOTCADEFAULT "
                       "BufferIn: (%08x, %i), BufferIn2: (%08x, %i), "
@@ -533,11 +533,11 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
     int sslID = Memory::Read_U32(BufferOut) - 1;
     if (SSLID_VALID(sslID))
     {
-      Memory::Write_U32(SSL_OK, BufferIn);
+      WriteReturnValue(SSL_OK, BufferIn);
     }
     else
     {
-      Memory::Write_U32(SSL_ERR_ID, BufferIn);
+      WriteReturnValue(SSL_ERR_ID, BufferIn);
     }
     break;
   }
diff --git a/Source/Core/Core/IOS/Network/SSL.h b/Source/Core/Core/IOS/Network/SSL.h
index c1253e8189..a8a8d55bd2 100644
--- a/Source/Core/Core/IOS/Network/SSL.h
+++ b/Source/Core/Core/IOS/Network/SSL.h
@@ -32,7 +32,7 @@ namespace HLE
 #define SSLID_VALID(x)                                                                             \
   (x >= 0 && x < NET_SSL_MAXINSTANCES && ::IOS::HLE::Device::NetSSL::_SSL[x].active)
 
-enum ssl_err_t
+enum ssl_err_t : s32
 {
   SSL_OK = 0,
   SSL_ERR_FAILED = -1,
diff --git a/Source/Core/Core/IOS/Network/Socket.cpp b/Source/Core/Core/IOS/Network/Socket.cpp
index b5968568a1..ce79f8dfcb 100644
--- a/Source/Core/Core/IOS/Network/Socket.cpp
+++ b/Source/Core/Core/IOS/Network/Socket.cpp
@@ -335,15 +335,15 @@ void WiiSocket::Update(bool read, bool write, bool except)
             switch (ret)
             {
             case 0:
-              Memory::Write_U32(SSL_OK, BufferIn);
+              WriteReturnValue(SSL_OK, BufferIn);
               break;
             case MBEDTLS_ERR_SSL_WANT_READ:
-              Memory::Write_U32(SSL_ERR_RAGAIN, BufferIn);
+              WriteReturnValue(SSL_ERR_RAGAIN, BufferIn);
               if (!nonBlock)
                 ReturnValue = SSL_ERR_RAGAIN;
               break;
             case MBEDTLS_ERR_SSL_WANT_WRITE:
-              Memory::Write_U32(SSL_ERR_WAGAIN, BufferIn);
+              WriteReturnValue(SSL_ERR_WAGAIN, BufferIn);
               if (!nonBlock)
                 ReturnValue = SSL_ERR_WAGAIN;
               break;
@@ -366,13 +366,13 @@ void WiiSocket::Update(bool read, bool write, bool except)
               else
                 res = SSL_ERR_FAILED;
 
-              Memory::Write_U32(res, BufferIn);
+              WriteReturnValue(res, BufferIn);
               if (!nonBlock)
                 ReturnValue = res;
               break;
             }
             default:
-              Memory::Write_U32(SSL_ERR_FAILED, BufferIn);
+              WriteReturnValue(SSL_ERR_FAILED, BufferIn);
               break;
             }
 
@@ -412,24 +412,24 @@ void WiiSocket::Update(bool read, bool write, bool except)
             if (ret >= 0)
             {
               // Return bytes written or SSL_ERR_ZERO if none
-              Memory::Write_U32((ret == 0) ? SSL_ERR_ZERO : ret, BufferIn);
+              WriteReturnValue((ret == 0) ? SSL_ERR_ZERO : ret, BufferIn);
             }
             else
             {
               switch (ret)
               {
               case MBEDTLS_ERR_SSL_WANT_READ:
-                Memory::Write_U32(SSL_ERR_RAGAIN, BufferIn);
+                WriteReturnValue(SSL_ERR_RAGAIN, BufferIn);
                 if (!nonBlock)
                   ReturnValue = SSL_ERR_RAGAIN;
                 break;
               case MBEDTLS_ERR_SSL_WANT_WRITE:
-                Memory::Write_U32(SSL_ERR_WAGAIN, BufferIn);
+                WriteReturnValue(SSL_ERR_WAGAIN, BufferIn);
                 if (!nonBlock)
                   ReturnValue = SSL_ERR_WAGAIN;
                 break;
               default:
-                Memory::Write_U32(SSL_ERR_FAILED, BufferIn);
+                WriteReturnValue(SSL_ERR_FAILED, BufferIn);
                 break;
               }
             }
@@ -450,24 +450,24 @@ void WiiSocket::Update(bool read, bool write, bool except)
             if (ret >= 0)
             {
               // Return bytes read or SSL_ERR_ZERO if none
-              Memory::Write_U32((ret == 0) ? SSL_ERR_ZERO : ret, BufferIn);
+              WriteReturnValue((ret == 0) ? SSL_ERR_ZERO : ret, BufferIn);
             }
             else
             {
               switch (ret)
               {
               case MBEDTLS_ERR_SSL_WANT_READ:
-                Memory::Write_U32(SSL_ERR_RAGAIN, BufferIn);
+                WriteReturnValue(SSL_ERR_RAGAIN, BufferIn);
                 if (!nonBlock)
                   ReturnValue = SSL_ERR_RAGAIN;
                 break;
               case MBEDTLS_ERR_SSL_WANT_WRITE:
-                Memory::Write_U32(SSL_ERR_WAGAIN, BufferIn);
+                WriteReturnValue(SSL_ERR_WAGAIN, BufferIn);
                 if (!nonBlock)
                   ReturnValue = SSL_ERR_WAGAIN;
                 break;
               default:
-                Memory::Write_U32(SSL_ERR_FAILED, BufferIn);
+                WriteReturnValue(SSL_ERR_FAILED, BufferIn);
                 break;
               }
             }
@@ -479,7 +479,7 @@ void WiiSocket::Update(bool read, bool write, bool except)
         }
         else
         {
-          Memory::Write_U32(SSL_ERR_ID, BufferIn);
+          WriteReturnValue(SSL_ERR_ID, BufferIn);
         }
       }
       else
diff --git a/Source/Core/Core/IOS/SDIO/SDIOSlot0.cpp b/Source/Core/Core/IOS/SDIO/SDIOSlot0.cpp
index 3884baefdb..14a739e601 100644
--- a/Source/Core/Core/IOS/SDIO/SDIOSlot0.cpp
+++ b/Source/Core/Core/IOS/SDIO/SDIOSlot0.cpp
@@ -134,7 +134,7 @@ IPCCommandResult SDIOSlot0::IOCtlV(const IOCtlVRequest& request)
   return GetDefaultReply(IPC_SUCCESS);
 }
 
-u32 SDIOSlot0::ExecuteCommand(const Request& request, u32 _BufferIn, u32 _BufferInSize,
+s32 SDIOSlot0::ExecuteCommand(const Request& request, u32 _BufferIn, u32 _BufferInSize,
                               u32 _rwBuffer, u32 _rwBufferSize, u32 _BufferOut, u32 _BufferOutSize)
 {
   // The game will send us a SendCMD with this information. To be able to read and write
@@ -164,7 +164,7 @@ u32 SDIOSlot0::ExecuteCommand(const Request& request, u32 _BufferIn, u32 _Buffer
 
   // Note: req.addr is the virtual address of _rwBuffer
 
-  u32 ret = RET_OK;
+  s32 ret = RET_OK;
 
   switch (req.command)
   {
diff --git a/Source/Core/Core/IOS/SDIO/SDIOSlot0.h b/Source/Core/Core/IOS/SDIO/SDIOSlot0.h
index 55bfabf8da..5e69389b30 100644
--- a/Source/Core/Core/IOS/SDIO/SDIOSlot0.h
+++ b/Source/Core/Core/IOS/SDIO/SDIOSlot0.h
@@ -128,7 +128,7 @@ private:
 
   IPCCommandResult SendCommand(const IOCtlVRequest& request);
 
-  u32 ExecuteCommand(const Request& request, u32 BufferIn, u32 BufferInSize, u32 BufferIn2,
+  s32 ExecuteCommand(const Request& request, u32 BufferIn, u32 BufferInSize, u32 BufferIn2,
                      u32 BufferInSize2, u32 _BufferOut, u32 BufferOutSize);
   void OpenInternal();
 
diff --git a/Source/Core/Core/IOS/WFS/WFSI.cpp b/Source/Core/Core/IOS/WFS/WFSI.cpp
index a5464151b6..34e4d4e8b7 100644
--- a/Source/Core/Core/IOS/WFS/WFSI.cpp
+++ b/Source/Core/Core/IOS/WFS/WFSI.cpp
@@ -86,7 +86,7 @@ WFSI::WFSI(Kernel& ios, const std::string& device_name) : Device(ios, device_nam
 
 IPCCommandResult WFSI::IOCtl(const IOCtlRequest& request)
 {
-  u32 return_error_code = IPC_SUCCESS;
+  s32 return_error_code = IPC_SUCCESS;
 
   switch (request.request)
   {

From ead4f19654d23b77c56b7d072bc4437db65df4a0 Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Wed, 7 Jun 2017 04:28:48 -0700
Subject: [PATCH 47/57] ios/usbv4: initialize TransferCommand::data_address to
 0

---
 Source/Core/Core/IOS/USB/USBV4.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/Source/Core/Core/IOS/USB/USBV4.cpp b/Source/Core/Core/IOS/USB/USBV4.cpp
index c2b9825cd6..3d963c9598 100644
--- a/Source/Core/Core/IOS/USB/USBV4.cpp
+++ b/Source/Core/Core/IOS/USB/USBV4.cpp
@@ -49,7 +49,7 @@ struct HIDRequest
 };
 #pragma pack(pop)
 
-V4CtrlMessage::V4CtrlMessage(Kernel& ios, const IOCtlRequest& ioctl) : CtrlMessage(ios, ioctl, -1)
+V4CtrlMessage::V4CtrlMessage(Kernel& ios, const IOCtlRequest& ioctl) : CtrlMessage(ios, ioctl, 0)
 {
   HIDRequest hid_request;
   Memory::CopyFromEmu(&hid_request, ioctl.buffer_in, sizeof(hid_request));
@@ -65,7 +65,7 @@ V4CtrlMessage::V4CtrlMessage(Kernel& ios, const IOCtlRequest& ioctl) : CtrlMessa
 // (US for the language and replacing non-ASCII characters with '?'),
 // we can simply submit it as a usual control request.
 V4GetUSStringMessage::V4GetUSStringMessage(Kernel& ios, const IOCtlRequest& ioctl)
-    : CtrlMessage(ios, ioctl, -1)
+    : CtrlMessage(ios, ioctl, 0)
 {
   HIDRequest hid_request;
   Memory::CopyFromEmu(&hid_request, ioctl.buffer_in, sizeof(hid_request));
@@ -87,7 +87,7 @@ void V4GetUSStringMessage::OnTransferComplete(s32 return_value) const
   TransferCommand::OnTransferComplete(return_value);
 }
 
-V4IntrMessage::V4IntrMessage(Kernel& ios, const IOCtlRequest& ioctl) : IntrMessage(ios, ioctl, -1)
+V4IntrMessage::V4IntrMessage(Kernel& ios, const IOCtlRequest& ioctl) : IntrMessage(ios, ioctl, 0)
 {
   HIDRequest hid_request;
   Memory::CopyFromEmu(&hid_request, ioctl.buffer_in, sizeof(hid_request));

From ab4a785f1b9f5d52071c0ba2414f7fa3c64c72ab Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Wed, 7 Jun 2017 04:30:57 -0700
Subject: [PATCH 48/57] d3d: silence variable shadowing warning

---
 Source/Core/VideoBackends/D3D/D3DBase.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/Source/Core/VideoBackends/D3D/D3DBase.cpp b/Source/Core/VideoBackends/D3D/D3DBase.cpp
index 8000f15a31..b1ba228b96 100644
--- a/Source/Core/VideoBackends/D3D/D3DBase.cpp
+++ b/Source/Core/VideoBackends/D3D/D3DBase.cpp
@@ -240,12 +240,12 @@ D3D_FEATURE_LEVEL GetFeatureLevel(IDXGIAdapter* adapter)
   return feat_level;
 }
 
-static bool SupportsS3TCTextures(ID3D11Device* device)
+static bool SupportsS3TCTextures(ID3D11Device* dev)
 {
   UINT bc1_support, bc2_support, bc3_support;
-  if (FAILED(device->CheckFormatSupport(DXGI_FORMAT_BC1_UNORM, &bc1_support)) ||
-      FAILED(device->CheckFormatSupport(DXGI_FORMAT_BC2_UNORM, &bc2_support)) ||
-      FAILED(device->CheckFormatSupport(DXGI_FORMAT_BC3_UNORM, &bc3_support)))
+  if (FAILED(dev->CheckFormatSupport(DXGI_FORMAT_BC1_UNORM, &bc1_support)) ||
+      FAILED(dev->CheckFormatSupport(DXGI_FORMAT_BC2_UNORM, &bc2_support)) ||
+      FAILED(dev->CheckFormatSupport(DXGI_FORMAT_BC3_UNORM, &bc3_support)))
   {
     return false;
   }

From e6c15e993bb351ea5414506440174a93e4fa0703 Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Wed, 7 Jun 2017 04:33:15 -0700
Subject: [PATCH 49/57] quiet some sign-conversion-in-parameter warnings

---
 Source/Core/Core/NetPlayServer.cpp | 2 +-
 Source/Core/VideoCommon/Fifo.cpp   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Source/Core/Core/NetPlayServer.cpp b/Source/Core/Core/NetPlayServer.cpp
index 3b0112772a..1e86cf0e2d 100644
--- a/Source/Core/Core/NetPlayServer.cpp
+++ b/Source/Core/Core/NetPlayServer.cpp
@@ -367,7 +367,7 @@ unsigned int NetPlayServer::OnDisconnect(const Client& player)
         sf::Packet spac;
         spac << (MessageId)NP_MSG_DISABLE_GAME;
         // this thread doesn't need players lock
-        SendToClients(spac, -1);
+        SendToClients(spac, static_cast<PlayerId>(-1));
         break;
       }
     }
diff --git a/Source/Core/VideoCommon/Fifo.cpp b/Source/Core/VideoCommon/Fifo.cpp
index 377d7d5010..cedbea5432 100644
--- a/Source/Core/VideoCommon/Fifo.cpp
+++ b/Source/Core/VideoCommon/Fifo.cpp
@@ -353,7 +353,7 @@ void RunGpuLoop()
                 DataReader(s_video_buffer_read_ptr, write_ptr), &cyclesExecuted, false);
 
             Common::AtomicStore(fifo.CPReadPointer, readPtr);
-            Common::AtomicAdd(fifo.CPReadWriteDistance, -32);
+            Common::AtomicAdd(fifo.CPReadWriteDistance, static_cast<u32>(-32));
             if ((write_ptr - s_video_buffer_read_ptr) == 0)
               Common::AtomicStore(fifo.SafeCPReadPointer, fifo.CPReadPointer);
 

From a97d07913891c29db135994dbd52488d3ccc37aa Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Wed, 7 Jun 2017 04:33:41 -0700
Subject: [PATCH 50/57] jit64: quiet variable init warnings

---
 Source/Core/Core/PowerPC/Jit64/JitRegCache.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/Source/Core/Core/PowerPC/Jit64/JitRegCache.cpp b/Source/Core/Core/PowerPC/Jit64/JitRegCache.cpp
index 601bf42248..e9db74a0ad 100644
--- a/Source/Core/Core/PowerPC/Jit64/JitRegCache.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/JitRegCache.cpp
@@ -30,7 +30,7 @@ void RegCache::Start()
     xreg.free = true;
     xreg.dirty = false;
     xreg.locked = false;
-    xreg.ppcReg = INVALID_REG;
+    xreg.ppcReg = static_cast<size_t>(INVALID_REG);
   }
   for (size_t i = 0; i < m_regs.size(); i++)
   {
@@ -63,7 +63,7 @@ void RegCache::DiscardRegContentsIfCached(size_t preg)
     X64Reg xr = m_regs[preg].location.GetSimpleReg();
     m_xregs[xr].free = true;
     m_xregs[xr].dirty = false;
-    m_xregs[xr].ppcReg = INVALID_REG;
+    m_xregs[xr].ppcReg = static_cast<size_t>(INVALID_REG);
     m_regs[preg].away = false;
     m_regs[preg].location = GetDefaultLocation(preg);
   }
@@ -216,7 +216,7 @@ void RegCache::StoreFromRegister(size_t i, FlushMode mode)
       if (mode == FlushMode::All)
       {
         m_xregs[xr].free = true;
-        m_xregs[xr].ppcReg = INVALID_REG;
+        m_xregs[xr].ppcReg = static_cast<size_t>(INVALID_REG);
         m_xregs[xr].dirty = false;
       }
     }

From ef9090d7da50d6ef7ac90d365d1c5e2549ce30ce Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Wed, 7 Jun 2017 04:34:34 -0700
Subject: [PATCH 51/57] powerpc: silence an int->u32 init warning

---
 Source/Core/Core/PowerPC/PowerPC.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Source/Core/Core/PowerPC/PowerPC.h b/Source/Core/Core/PowerPC/PowerPC.h
index 1ca6e6aa61..9e53c239b9 100644
--- a/Source/Core/Core/PowerPC/PowerPC.h
+++ b/Source/Core/Core/PowerPC/PowerPC.h
@@ -296,7 +296,7 @@ constexpr int BAT_INDEX_SHIFT = 17;
 constexpr u32 BAT_PAGE_SIZE = 1 << BAT_INDEX_SHIFT;
 constexpr u32 BAT_MAPPED_BIT = 0x1;
 constexpr u32 BAT_PHYSICAL_BIT = 0x2;
-constexpr u32 BAT_RESULT_MASK = ~0x3;
+constexpr u32 BAT_RESULT_MASK = UINT32_C(~0x3);
 using BatTable = std::array<u32, 1 << (32 - BAT_INDEX_SHIFT)>;  // 128 KB
 extern BatTable ibat_table;
 extern BatTable dbat_table;

From 50f34f8b05ea64c42f465d6bd384208e886ba88f Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Wed, 7 Jun 2017 04:35:07 -0700
Subject: [PATCH 52/57] jit64: silence signedness comparison warnings

---
 Source/Core/Core/PowerPC/Jit64/Jit.h                 | 2 +-
 Source/Core/Core/PowerPC/Jit64/Jit_FloatingPoint.cpp | 2 +-
 Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp       | 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.h b/Source/Core/Core/PowerPC/Jit64/Jit.h
index 4fe96f5bfc..97ca0af716 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit.h
+++ b/Source/Core/Core/PowerPC/Jit64/Jit.h
@@ -87,7 +87,7 @@ public:
   // Use to extract bytes from a register using the regcache. offset is in bytes.
   Gen::OpArg ExtractFromReg(int reg, int offset);
   void AndWithMask(Gen::X64Reg reg, u32 mask);
-  bool CheckMergedBranch(int crf);
+  bool CheckMergedBranch(u32 crf);
   void DoMergedBranch();
   void DoMergedBranchCondition();
   void DoMergedBranchImmediate(s64 val);
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_FloatingPoint.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_FloatingPoint.cpp
index 63ac8ff7d5..12da80f64a 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit_FloatingPoint.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit_FloatingPoint.cpp
@@ -486,7 +486,7 @@ void Jit64::FloatCompare(UGeckoInstruction inst, bool upper)
   // bool ordered = !!(inst.SUBOP10 & 32);
   int a = inst.FA;
   int b = inst.FB;
-  int crf = inst.CRFD;
+  u32 crf = inst.CRFD;
   int output[4] = {CR_SO, CR_EQ, CR_GT, CR_LT};
 
   // Merge neighboring fcmp and cror (the primary use of cror).
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
index 5f25fd5d22..2ff5e1bffe 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
@@ -339,7 +339,7 @@ void Jit64::reg_imm(UGeckoInstruction inst)
   }
 }
 
-bool Jit64::CheckMergedBranch(int crf)
+bool Jit64::CheckMergedBranch(u32 crf)
 {
   if (!analyzer.HasOption(PPCAnalyst::PPCAnalyzer::OPTION_BRANCH_MERGE))
     return false;
@@ -473,7 +473,7 @@ void Jit64::cmpXX(UGeckoInstruction inst)
   JITDISABLE(bJITIntegerOff);
   int a = inst.RA;
   int b = inst.RB;
-  int crf = inst.CRFD;
+  u32 crf = inst.CRFD;
   bool merge_branch = CheckMergedBranch(crf);
 
   OpArg comparand;

From 9357cee2ef96fbe345a82ac2f6af7c715d1e6027 Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Wed, 7 Jun 2017 04:42:41 -0700
Subject: [PATCH 53/57] do not assign in conditional statements

---
 Source/Core/Common/FileUtil.cpp               |  4 ++--
 Source/Core/Common/GL/GLInterface/WGL.cpp     |  7 ++++---
 Source/Core/Core/ARDecrypt.cpp                |  3 ++-
 .../Debugger/CodeWindowFunctions.cpp          |  7 ++++---
 Source/Core/InputCommon/GCAdapter.cpp         | 19 +++++++++----------
 Source/Core/VideoCommon/AVIDump.cpp           | 16 +++++++++-------
 6 files changed, 30 insertions(+), 26 deletions(-)

diff --git a/Source/Core/Common/FileUtil.cpp b/Source/Core/Common/FileUtil.cpp
index 2ae063673f..203ddbac4b 100644
--- a/Source/Core/Common/FileUtil.cpp
+++ b/Source/Core/Common/FileUtil.cpp
@@ -631,9 +631,9 @@ void CopyDir(const std::string& source_path, const std::string& dest_path)
 // Returns the current directory
 std::string GetCurrentDir()
 {
-  char* dir;
   // Get the current working directory (getcwd uses malloc)
-  if (!(dir = __getcwd(nullptr, 0)))
+  char* dir = __getcwd(nullptr, 0);
+  if (!dir)
   {
     ERROR_LOG(COMMON, "GetCurrentDirectory failed: %s", GetLastErrorMsg().c_str());
     return nullptr;
diff --git a/Source/Core/Common/GL/GLInterface/WGL.cpp b/Source/Core/Common/GL/GLInterface/WGL.cpp
index 57c46cb42b..3e500f5866 100644
--- a/Source/Core/Common/GL/GLInterface/WGL.cpp
+++ b/Source/Core/Common/GL/GLInterface/WGL.cpp
@@ -248,8 +248,8 @@ bool cInterfaceWGL::Create(void* window_handle, bool core)
     return false;
   }
 
-  int pixel_format;
-  if (!(pixel_format = ChoosePixelFormat(m_dc, &pfd)))
+  int pixel_format = ChoosePixelFormat(m_dc, &pfd);
+  if (!pixel_format)
   {
     PanicAlert("(2) Can't find a suitable PixelFormat.");
     return false;
@@ -261,7 +261,8 @@ bool cInterfaceWGL::Create(void* window_handle, bool core)
     return false;
   }
 
-  if (!(m_rc = wglCreateContext(m_dc)))
+  m_rc = wglCreateContext(m_dc);
+  if (!m_rc)
   {
     PanicAlert("(4) Can't create an OpenGL rendering context.");
     return false;
diff --git a/Source/Core/Core/ARDecrypt.cpp b/Source/Core/Core/ARDecrypt.cpp
index 40d43a3619..77bfc175d3 100644
--- a/Source/Core/Core/ARDecrypt.cpp
+++ b/Source/Core/Core/ARDecrypt.cpp
@@ -471,7 +471,8 @@ void DecryptARCode(std::vector<std::string> vCodes, std::vector<AREntry>* ops)
     std::transform(s.begin(), s.end(), s.begin(), toupper);
   }
 
-  if ((ret = alphatobin(uCodes, vCodes, (int)vCodes.size())))
+  ret = alphatobin(uCodes, vCodes, (int)vCodes.size());
+  if (ret)
   {
     // Return value is index + 1, 0 being the success flag value.
     PanicAlertT("Action Replay Code Decryption Error:\nParity Check Failed\n\nCulprit Code:\n%s",
diff --git a/Source/Core/DolphinWX/Debugger/CodeWindowFunctions.cpp b/Source/Core/DolphinWX/Debugger/CodeWindowFunctions.cpp
index 2452e85b38..2a536c95e6 100644
--- a/Source/Core/DolphinWX/Debugger/CodeWindowFunctions.cpp
+++ b/Source/Core/DolphinWX/Debugger/CodeWindowFunctions.cpp
@@ -146,11 +146,12 @@ void CCodeWindow::OnProfilerMenu(wxCommandEvent& event)
       File::CreateFullPath(filename);
       Profiler::WriteProfileResults(filename);
 
-      wxFileType* filetype = nullptr;
-      if (!(filetype = wxTheMimeTypesManager->GetFileTypeFromExtension("txt")))
+      wxFileType* filetype = wxTheMimeTypesManager->GetFileTypeFromExtension("txt");
+      if (!filetype)
       {
         // From extension failed, trying with MIME type now
-        if (!(filetype = wxTheMimeTypesManager->GetFileTypeFromMimeType("text/plain")))
+        filetype = wxTheMimeTypesManager->GetFileTypeFromMimeType("text/plain");
+        if (!filetype)
           // MIME type failed, aborting mission
           break;
       }
diff --git a/Source/Core/InputCommon/GCAdapter.cpp b/Source/Core/InputCommon/GCAdapter.cpp
index 2cb7819d9d..a422e2635e 100644
--- a/Source/Core/InputCommon/GCAdapter.cpp
+++ b/Source/Core/InputCommon/GCAdapter.cpp
@@ -266,27 +266,26 @@ static bool CheckDeviceAccess(libusb_device* device)
       }
       return false;
     }
-    else if ((ret = libusb_kernel_driver_active(s_handle, 0)) == 1)
+    else
     {
-      if ((ret = libusb_detach_kernel_driver(s_handle, 0)) && ret != LIBUSB_ERROR_NOT_SUPPORTED)
+      ret = libusb_kernel_driver_active(s_handle, 0);
+      if (ret == 1)
       {
-        ERROR_LOG(SERIALINTERFACE, "libusb_detach_kernel_driver failed with error: %d", ret);
+        ret = libusb_detach_kernel_driver(s_handle, 0);
+        if (ret != 0 && ret != LIBUSB_ERROR_NOT_SUPPORTED)
+          ERROR_LOG(SERIALINTERFACE, "libusb_detach_kernel_driver failed with error: %d", ret);
       }
     }
     // this split is needed so that we don't avoid claiming the interface when
     // detaching the kernel driver is successful
     if (ret != 0 && ret != LIBUSB_ERROR_NOT_SUPPORTED)
-    {
       return false;
-    }
-    else if ((ret = libusb_claim_interface(s_handle, 0)))
-    {
+
+    ret = libusb_claim_interface(s_handle, 0);
+    if (ret)
       ERROR_LOG(SERIALINTERFACE, "libusb_claim_interface failed with error: %d", ret);
-    }
     else
-    {
       return true;
-    }
   }
   return false;
 }
diff --git a/Source/Core/VideoCommon/AVIDump.cpp b/Source/Core/VideoCommon/AVIDump.cpp
index dc4e806f6a..6a7590f034 100644
--- a/Source/Core/VideoCommon/AVIDump.cpp
+++ b/Source/Core/VideoCommon/AVIDump.cpp
@@ -159,8 +159,9 @@ bool AVIDump::CreateVideoFile()
 
   const AVCodec* codec = nullptr;
 
-  if (!(codec = avcodec_find_encoder(codec_id)) ||
-      !(s_codec_context = avcodec_alloc_context3(codec)))
+  codec = avcodec_find_encoder(codec_id);
+  s_codec_context = avcodec_alloc_context3(codec);
+  if (!codec || !s_codec_context)
   {
     ERROR_LOG(VIDEO, "Could not find encoder or allocate codec context");
     return false;
@@ -203,8 +204,8 @@ bool AVIDump::CreateVideoFile()
     return false;
 #endif
 
-  if (!(s_stream = avformat_new_stream(s_format_context, codec)) ||
-      !AVStreamCopyContext(s_stream, s_codec_context))
+  s_stream = avformat_new_stream(s_format_context, codec);
+  if (!s_stream || !AVStreamCopyContext(s_stream, s_codec_context))
   {
     ERROR_LOG(VIDEO, "Could not create stream");
     return false;
@@ -299,9 +300,10 @@ void AVIDump::AddFrame(const u8* data, int width, int height, int stride, const
   s_src_frame->height = s_height;
 
   // Convert image from {BGR24, RGBA} to desired pixel format
-  if ((s_sws_context =
-           sws_getCachedContext(s_sws_context, width, height, s_pix_fmt, s_width, s_height,
-                                s_codec_context->pix_fmt, SWS_BICUBIC, nullptr, nullptr, nullptr)))
+  s_sws_context =
+      sws_getCachedContext(s_sws_context, width, height, s_pix_fmt, s_width, s_height,
+                           s_codec_context->pix_fmt, SWS_BICUBIC, nullptr, nullptr, nullptr);
+  if (s_sws_context)
   {
     sws_scale(s_sws_context, s_src_frame->data, s_src_frame->linesize, 0, height,
               s_scaled_frame->data, s_scaled_frame->linesize);

From 5480efdff2f6e51245aa690a0ccb152a2b0a438e Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Wed, 7 Jun 2017 04:30:39 -0700
Subject: [PATCH 54/57] video: change multisample/AA setting to u32

---
 Source/Core/Core/Config/GraphicsSettings.cpp  | 2 +-
 Source/Core/Core/Config/GraphicsSettings.h    | 2 +-
 Source/Core/DolphinWX/VideoConfigDiag.cpp     | 6 +++---
 Source/Core/VideoBackends/D3D/D3DBase.cpp     | 2 +-
 Source/Core/VideoBackends/OGL/Render.cpp      | 4 ++--
 Source/Core/VideoBackends/Vulkan/Renderer.cpp | 2 +-
 Source/Core/VideoCommon/VideoConfig.h         | 4 ++--
 7 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/Source/Core/Core/Config/GraphicsSettings.cpp b/Source/Core/Core/Config/GraphicsSettings.cpp
index dcde16a17d..870fb1971c 100644
--- a/Source/Core/Core/Config/GraphicsSettings.cpp
+++ b/Source/Core/Core/Config/GraphicsSettings.cpp
@@ -57,7 +57,7 @@ const ConfigInfo<bool> GFX_ENABLE_GPU_TEXTURE_DECODING{
 const ConfigInfo<bool> GFX_ENABLE_PIXEL_LIGHTING{{System::GFX, "Settings", "EnablePixelLighting"},
                                                  false};
 const ConfigInfo<bool> GFX_FAST_DEPTH_CALC{{System::GFX, "Settings", "FastDepthCalc"}, true};
-const ConfigInfo<int> GFX_MSAA{{System::GFX, "Settings", "MSAA"}, 1};
+const ConfigInfo<u32> GFX_MSAA{{System::GFX, "Settings", "MSAA"}, 1};
 const ConfigInfo<bool> GFX_SSAA{{System::GFX, "Settings", "SSAA"}, false};
 const ConfigInfo<int> GFX_EFB_SCALE{{System::GFX, "Settings", "EFBScale"},
                                     static_cast<int>(SCALE_1X)};
diff --git a/Source/Core/Core/Config/GraphicsSettings.h b/Source/Core/Core/Config/GraphicsSettings.h
index 7ff7b2b667..0b3b98ee06 100644
--- a/Source/Core/Core/Config/GraphicsSettings.h
+++ b/Source/Core/Core/Config/GraphicsSettings.h
@@ -47,7 +47,7 @@ extern const ConfigInfo<bool> GFX_INTERNAL_RESOLUTION_FRAME_DUMPS;
 extern const ConfigInfo<bool> GFX_ENABLE_GPU_TEXTURE_DECODING;
 extern const ConfigInfo<bool> GFX_ENABLE_PIXEL_LIGHTING;
 extern const ConfigInfo<bool> GFX_FAST_DEPTH_CALC;
-extern const ConfigInfo<int> GFX_MSAA;
+extern const ConfigInfo<u32> GFX_MSAA;
 extern const ConfigInfo<bool> GFX_SSAA;
 extern const ConfigInfo<int> GFX_EFB_SCALE;
 extern const ConfigInfo<bool> GFX_TEXFMT_OVERLAY_ENABLE;
diff --git a/Source/Core/DolphinWX/VideoConfigDiag.cpp b/Source/Core/DolphinWX/VideoConfigDiag.cpp
index 65dc4c3603..22490e4ad5 100644
--- a/Source/Core/DolphinWX/VideoConfigDiag.cpp
+++ b/Source/Core/DolphinWX/VideoConfigDiag.cpp
@@ -1322,11 +1322,11 @@ void VideoConfigDiag::PopulatePostProcessingShaders()
 
 void VideoConfigDiag::PopulateAAList()
 {
-  const std::vector<int>& aa_modes = vconfig.backend_info.AAModes;
+  const auto& aa_modes = vconfig.backend_info.AAModes;
   const bool supports_ssaa = vconfig.backend_info.bSupportsSSAA;
   m_msaa_modes = 0;
 
-  for (int mode : aa_modes)
+  for (auto mode : aa_modes)
   {
     if (mode == 1)
     {
@@ -1342,7 +1342,7 @@ void VideoConfigDiag::PopulateAAList()
 
   if (supports_ssaa)
   {
-    for (int mode : aa_modes)
+    for (auto mode : aa_modes)
     {
       if (mode != 1)
         choice_aamode->AppendString(std::to_string(mode) + "x SSAA");
diff --git a/Source/Core/VideoBackends/D3D/D3DBase.cpp b/Source/Core/VideoBackends/D3D/D3DBase.cpp
index b1ba228b96..327fece109 100644
--- a/Source/Core/VideoBackends/D3D/D3DBase.cpp
+++ b/Source/Core/VideoBackends/D3D/D3DBase.cpp
@@ -320,7 +320,7 @@ HRESULT Create(HWND wnd)
         return desc.Count == g_Config.iMultisamples;
       }) == aa_modes.end())
   {
-    Config::SetCurrent(Config::GFX_MSAA, 1);
+    Config::SetCurrent(Config::GFX_MSAA, UINT32_C(1));
     UpdateActiveConfig();
   }
 
diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp
index ebec5e98a9..ec709c152b 100644
--- a/Source/Core/VideoBackends/OGL/Render.cpp
+++ b/Source/Core/VideoBackends/OGL/Render.cpp
@@ -63,7 +63,7 @@ static std::unique_ptr<RasterFont> s_raster_font;
 
 // 1 for no MSAA. Use s_MSAASamples > 1 to check for MSAA.
 static int s_MSAASamples = 1;
-static int s_last_multisamples = 1;
+static u32 s_last_multisamples = 1;
 static bool s_last_stereo_mode = false;
 static bool s_last_xfb_mode = false;
 
@@ -519,7 +519,7 @@ Renderer::Renderer()
       {
         // GLES 3.1 can't support stereo rendering and MSAA
         OSD::AddMessage("MSAA Stereo rendering isn't supported by your GPU.", 10000);
-        Config::SetCurrent(Config::GFX_MSAA, 1);
+        Config::SetCurrent(Config::GFX_MSAA, UINT32_C(1));
       }
     }
     else
diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.cpp b/Source/Core/VideoBackends/Vulkan/Renderer.cpp
index 94087bdc1f..81bd7671cd 100644
--- a/Source/Core/VideoBackends/Vulkan/Renderer.cpp
+++ b/Source/Core/VideoBackends/Vulkan/Renderer.cpp
@@ -1106,7 +1106,7 @@ void Renderer::CheckForSurfaceChange()
 void Renderer::CheckForConfigChanges()
 {
   // Save the video config so we can compare against to determine which settings have changed.
-  int old_multisamples = g_ActiveConfig.iMultisamples;
+  u32 old_multisamples = g_ActiveConfig.iMultisamples;
   int old_anisotropy = g_ActiveConfig.iMaxAnisotropy;
   int old_stereo_mode = g_ActiveConfig.iStereoMode;
   int old_aspect_ratio = g_ActiveConfig.iAspectRatio;
diff --git a/Source/Core/VideoCommon/VideoConfig.h b/Source/Core/VideoCommon/VideoConfig.h
index 707afae84c..03d102eb62 100644
--- a/Source/Core/VideoCommon/VideoConfig.h
+++ b/Source/Core/VideoCommon/VideoConfig.h
@@ -70,7 +70,7 @@ struct VideoConfig final
   bool bShaderCache;
 
   // Enhancements
-  int iMultisamples;
+  u32 iMultisamples;
   bool bSSAA;
   int iEFBScale;
   bool bForceFiltering;
@@ -167,7 +167,7 @@ struct VideoConfig final
     APIType api_type;
 
     std::vector<std::string> Adapters;  // for D3D
-    std::vector<int> AAModes;
+    std::vector<u32> AAModes;
 
     // TODO: merge AdapterName and Adapters array
     std::string AdapterName;  // for OpenGL

From 1065dc44384675f35df1b3a62f0173c4f9cc0d5a Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Wed, 7 Jun 2017 04:43:08 -0700
Subject: [PATCH 55/57] msbuild: set warning level 4

---
 Source/VSProps/Base.props | 27 +++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/Source/VSProps/Base.props b/Source/VSProps/Base.props
index 4fe3f0e379..77732dc364 100644
--- a/Source/VSProps/Base.props
+++ b/Source/VSProps/Base.props
@@ -76,7 +76,7 @@
       higher declaration can be contained to just the XAudio2/XInput related code.
       -->
       <PreprocessorDefinitions>_WIN32_WINNT=0x0602;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <WarningLevel>Level3</WarningLevel>
+      <WarningLevel>Level4</WarningLevel>
       <TreatWarningAsError>true</TreatWarningAsError>
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <RuntimeTypeInfo>false</RuntimeTypeInfo>
@@ -95,13 +95,28 @@
       <DebugInformationFormat>OldStyle</DebugInformationFormat>
       <DiagnosticsFormat>Caret</DiagnosticsFormat>
       <!--
-      4996 is for GetVersionEx being marked as depreciated - which is idiotic and there's
-        not much else we can do since many externals use it. The bad part is that there doesn't
-        seem to be a way to only ignore the specific instance we don't care about...
-      4351 squashes a warning telling us the compiler is behaving as expected (instead of old,
-        broken behavior).
+      4996  is for GetVersionEx being marked as deprecated - which is idiotic and there's not much
+                else we can do since many externals use it. The bad part is that there doesn't
+                seem to be a way to only ignore the specific instance we don't care about...
+      4351  new behavior: elements of array 'array' will be default initialized
       -->
       <DisableSpecificWarnings>4996;4351</DisableSpecificWarnings>
+      <!-- Warnings one may want to ignore when using Level4.
+      4201  nonstandard extension used : nameless struct/union
+      4127  conditional expression is constant
+      4100  'identifier' : unreferenced formal parameter
+      4244  'conversion' conversion from 'type1' to 'type2', possible loss of data
+                Level4 warns if type1==int and there is narrowing
+      4121  'symbol' : alignment of a member was sensitive to packing
+      4324  Padding was added at the end of a structure because you specified a __declspec(align) value.
+      4714  function 'function' marked as __forceinline not inlined
+      -->
+      <DisableSpecificWarnings>4201;4127;4100;4244;4121;4324;4714;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <!-- Level4 warnings which should eventually be enabled
+      4245  'conversion' : conversion from 'type1' to 'type2', signed/unsigned mismatch
+                Currently jits use some annoying code patterns which makes this common
+      -->
+      <DisableSpecificWarnings>4245;%(DisableSpecificWarnings)</DisableSpecificWarnings>
     </ClCompile>
     <!--ClCompile Debug-->
     <ClCompile Condition="'$(Configuration)'=='Debug'">

From fd166032abec349b9fae7240830133bf7e0c77b5 Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Wed, 7 Jun 2017 15:25:13 -0700
Subject: [PATCH 56/57] msbuild: obey some warnings about missing virtual
 destructors

---
 Source/Core/AudioCommon/XAudio2Stream.cpp   |  3 +--
 Source/Core/AudioCommon/XAudio2_7Stream.cpp |  3 +--
 Source/Core/Common/Config/Section.h         |  1 +
 Source/Core/Core/HW/MMIO.cpp                | 16 ++++++++++------
 Source/VSProps/Base.props                   |  8 ++++++++
 5 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/Source/Core/AudioCommon/XAudio2Stream.cpp b/Source/Core/AudioCommon/XAudio2Stream.cpp
index 12954fc5bf..69c503f310 100644
--- a/Source/Core/AudioCommon/XAudio2Stream.cpp
+++ b/Source/Core/AudioCommon/XAudio2Stream.cpp
@@ -25,8 +25,7 @@ private:
 
 public:
   StreamingVoiceContext(IXAudio2* pXAudio2, CMixer* pMixer, Common::Event& pSyncEvent);
-
-  ~StreamingVoiceContext();
+  virtual ~StreamingVoiceContext();
 
   void Stop();
   void Play();
diff --git a/Source/Core/AudioCommon/XAudio2_7Stream.cpp b/Source/Core/AudioCommon/XAudio2_7Stream.cpp
index 06fb645c95..1abf6d2096 100644
--- a/Source/Core/AudioCommon/XAudio2_7Stream.cpp
+++ b/Source/Core/AudioCommon/XAudio2_7Stream.cpp
@@ -25,8 +25,7 @@ private:
 
 public:
   StreamingVoiceContext2_7(IXAudio2* pXAudio2, CMixer* pMixer, Common::Event& pSyncEvent);
-
-  ~StreamingVoiceContext2_7();
+  virtual ~StreamingVoiceContext2_7();
 
   void Stop();
   void Play();
diff --git a/Source/Core/Common/Config/Section.h b/Source/Core/Common/Config/Section.h
index 8b36ce157e..0a4662d156 100644
--- a/Source/Core/Common/Config/Section.h
+++ b/Source/Core/Common/Config/Section.h
@@ -27,6 +27,7 @@ class Section
 
 public:
   Section(LayerType layer, System system, const std::string& name);
+  virtual ~Section() = default;
 
   virtual bool Exists(const std::string& key) const;
   bool Delete(const std::string& key);
diff --git a/Source/Core/Core/HW/MMIO.cpp b/Source/Core/Core/HW/MMIO.cpp
index 8ee341554d..a6dcdeebd6 100644
--- a/Source/Core/Core/HW/MMIO.cpp
+++ b/Source/Core/Core/HW/MMIO.cpp
@@ -20,14 +20,14 @@ template <typename T>
 class ReadHandlingMethod
 {
 public:
-  virtual ~ReadHandlingMethod() {}
+  virtual ~ReadHandlingMethod() = default;
   virtual void AcceptReadVisitor(ReadHandlingMethodVisitor<T>& v) const = 0;
 };
 template <typename T>
 class WriteHandlingMethod
 {
 public:
-  virtual ~WriteHandlingMethod() {}
+  virtual ~WriteHandlingMethod() = default;
   virtual void AcceptWriteVisitor(WriteHandlingMethodVisitor<T>& v) const = 0;
 };
 
@@ -39,7 +39,7 @@ class ConstantHandlingMethod : public ReadHandlingMethod<T>
 {
 public:
   explicit ConstantHandlingMethod(T value) : value_(value) {}
-  virtual ~ConstantHandlingMethod() {}
+  virtual ~ConstantHandlingMethod() = default;
   void AcceptReadVisitor(ReadHandlingMethodVisitor<T>& v) const override
   {
     v.VisitConstant(value_);
@@ -62,7 +62,7 @@ class NopHandlingMethod : public WriteHandlingMethod<T>
 {
 public:
   NopHandlingMethod() {}
-  virtual ~NopHandlingMethod() {}
+  virtual ~NopHandlingMethod() = default;
   void AcceptWriteVisitor(WriteHandlingMethodVisitor<T>& v) const override { v.VisitNop(); }
 };
 template <typename T>
@@ -79,7 +79,7 @@ class DirectHandlingMethod : public ReadHandlingMethod<T>, public WriteHandlingM
 {
 public:
   DirectHandlingMethod(T* addr, u32 mask) : addr_(addr), mask_(mask) {}
-  virtual ~DirectHandlingMethod() {}
+  virtual ~DirectHandlingMethod() = default;
   void AcceptReadVisitor(ReadHandlingMethodVisitor<T>& v) const override
   {
     v.VisitDirect(addr_, mask_);
@@ -132,7 +132,7 @@ public:
   {
   }
 
-  virtual ~ComplexHandlingMethod() {}
+  virtual ~ComplexHandlingMethod() = default;
   void AcceptReadVisitor(ReadHandlingMethodVisitor<T>& v) const override
   {
     v.VisitComplex(&read_lambda_);
@@ -304,6 +304,8 @@ void ReadHandler<T>::ResetMethod(ReadHandlingMethod<T>* method)
 
   struct FuncCreatorVisitor : public ReadHandlingMethodVisitor<T>
   {
+    virtual ~FuncCreatorVisitor() = default;
+
     std::function<T(u32)> ret;
 
     void VisitConstant(T value) override
@@ -356,6 +358,8 @@ void WriteHandler<T>::ResetMethod(WriteHandlingMethod<T>* method)
 
   struct FuncCreatorVisitor : public WriteHandlingMethodVisitor<T>
   {
+    virtual ~FuncCreatorVisitor() = default;
+
     std::function<void(u32, T)> ret;
 
     void VisitNop() override
diff --git a/Source/VSProps/Base.props b/Source/VSProps/Base.props
index 77732dc364..31336f3c07 100644
--- a/Source/VSProps/Base.props
+++ b/Source/VSProps/Base.props
@@ -117,6 +117,14 @@
                 Currently jits use some annoying code patterns which makes this common
       -->
       <DisableSpecificWarnings>4245;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      <!-- Enable some off-by-default warnings
+      4263  Non-virtual member function hides base class virtual function
+      4265  Class has virtual functions, but destructor is not virtual
+      4946  Reinterpret cast between related types
+      -->
+      <!-- Externals are currently not compatible with this. Can still uncomment locally.
+      <AdditionalOptions>/we4263 /we4265 /we4946 %(AdditionalOptions)</AdditionalOptions>
+      -->
     </ClCompile>
     <!--ClCompile Debug-->
     <ClCompile Condition="'$(Configuration)'=='Debug'">

From 602b97277390aac9f9b5117f24b78efe55411ccc Mon Sep 17 00:00:00 2001
From: Shawn Hoffman <godisgovernment@gmail.com>
Date: Wed, 7 Jun 2017 21:03:02 -0700
Subject: [PATCH 57/57] msvc: enable some default-off warnings

---
 Source/Core/DolphinQt2/DolphinQt2.vcxproj | 6 +++---
 Source/VSProps/Base.props                 | 4 +---
 Source/VSProps/QtCompile.props            | 5 +++++
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/Source/Core/DolphinQt2/DolphinQt2.vcxproj b/Source/Core/DolphinQt2/DolphinQt2.vcxproj
index 3df174a646..55e74a42cd 100644
--- a/Source/Core/DolphinQt2/DolphinQt2.vcxproj
+++ b/Source/Core/DolphinQt2/DolphinQt2.vcxproj
@@ -47,7 +47,7 @@
       <AdditionalDependencies>avrt.lib;iphlpapi.lib;winmm.lib;setupapi.lib;opengl32.lib;glu32.lib;rpcrt4.lib;comctl32.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
     <ClCompile>
-      <AdditionalIncludeDirectories>$(ProjectDir)\VideoInterface;$(ProjectDir)\GameList;$(ProjectDir)\Settings;$(ProjectDir)\Config;$(ProjectDir)\Config\Mapping;$(ProjectDir)\QtUtils;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>$(ProjectDir)VideoInterface;$(ProjectDir)GameList;$(ProjectDir)Settings;$(ProjectDir)Config;$(ProjectDir)Config\Mapping;$(ProjectDir)QtUtils;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Manifest>
       <AdditionalManifestFiles>DolphinQt2.manifest;%(AdditionalManifestFiles)</AdditionalManifestFiles>
@@ -213,10 +213,10 @@
     <ProjectReference Include="$(CoreDir)UICommon\UICommon.vcxproj">
       <Project>{604C8368-F34A-4D55-82C8-CC92A0C13254}</Project>
     </ProjectReference>
-    <ProjectReference Include="..\..\..\Languages\Languages.vcxproj">
+    <ProjectReference Include="$(DolphinRootDir)Languages\Languages.vcxproj">
       <Project>{0e033be3-2e08-428e-9ae9-bc673efa12b5}</Project>
     </ProjectReference>
-    <ProjectReference Include="..\VideoBackends\Vulkan\Vulkan.vcxproj">
+    <ProjectReference Include="$(CoreDir)VideoBackends\Vulkan\Vulkan.vcxproj">
       <Project>{29f29a19-f141-45ad-9679-5a2923b49da3}</Project>
     </ProjectReference>
   </ItemGroup>
diff --git a/Source/VSProps/Base.props b/Source/VSProps/Base.props
index 31336f3c07..300dbda26b 100644
--- a/Source/VSProps/Base.props
+++ b/Source/VSProps/Base.props
@@ -122,9 +122,7 @@
       4265  Class has virtual functions, but destructor is not virtual
       4946  Reinterpret cast between related types
       -->
-      <!-- Externals are currently not compatible with this. Can still uncomment locally.
-      <AdditionalOptions>/we4263 /we4265 /we4946 %(AdditionalOptions)</AdditionalOptions>
-      -->
+      <AdditionalOptions>/w44263 /w44265 /w44946 %(AdditionalOptions)</AdditionalOptions>
     </ClCompile>
     <!--ClCompile Debug-->
     <ClCompile Condition="'$(Configuration)'=='Debug'">
diff --git a/Source/VSProps/QtCompile.props b/Source/VSProps/QtCompile.props
index ac6c57a73f..63e414a148 100644
--- a/Source/VSProps/QtCompile.props
+++ b/Source/VSProps/QtCompile.props
@@ -27,6 +27,11 @@
       <AdditionalIncludeDirectories>$(QtIncludeDir)QtCore;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalIncludeDirectories>$(QtIncludeDir)QtGui;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalIncludeDirectories>$(QtIncludeDir)QtWidgets;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <!--
+      Negate the previously enabled warning (set in Base.props). Not compatible with QtCore\qtmap.h
+      This isn't too bad since we live with the fact that Qt-using projects will have different compiler args already.
+      -->
+      <AdditionalOptions>%(AdditionalOptions) /wd4946</AdditionalOptions>
     </ClCompile>
     <Link>
       <AdditionalLibraryDirectories>$(QtLibDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>