From b1b20ad84a5e966bb13f01de037bbfe88ac985cc Mon Sep 17 00:00:00 2001
From: ameerj <52414509+ameerj@users.noreply.github.com>
Date: Thu, 17 Nov 2022 20:11:47 -0500
Subject: [PATCH] configure_input_per_game: Allow configuring all 8 players

---
 .../configure_input_per_game.cpp              | 108 +++++++++++-------
 .../configuration/configure_input_per_game.h  |  14 +--
 .../configuration/configure_input_per_game.ui |  49 ++++++--
 3 files changed, 115 insertions(+), 56 deletions(-)

diff --git a/src/yuzu/configuration/configure_input_per_game.cpp b/src/yuzu/configuration/configure_input_per_game.cpp
index 5773c268de..af5cee542d 100644
--- a/src/yuzu/configuration/configure_input_per_game.cpp
+++ b/src/yuzu/configuration/configure_input_per_game.cpp
@@ -13,64 +13,90 @@ ConfigureInputPerGame::ConfigureInputPerGame(Core::System& system_, QWidget* par
     : QWidget(parent), ui(std::make_unique<Ui::ConfigureInputPerGame>()),
       profiles(std::make_unique<InputProfiles>()), system{system_} {
     ui->setupUi(this);
-
-    Settings::values.players.SetGlobal(false);
-    const auto previous_profile = Settings::values.players.GetValue()[0].profile_name;
+    const std::array labels = {
+        ui->label_player_1, ui->label_player_2, ui->label_player_3, ui->label_player_4,
+        ui->label_player_5, ui->label_player_6, ui->label_player_7, ui->label_player_8,
+    };
+    profile_comboboxes = {
+        ui->profile_player_1, ui->profile_player_2, ui->profile_player_3, ui->profile_player_4,
+        ui->profile_player_5, ui->profile_player_6, ui->profile_player_7, ui->profile_player_8,
+    };
 
     const auto& profile_names = profiles->GetInputProfileNames();
+    const auto populate_profiles = [this, &profile_names](size_t player_index) {
+        const auto previous_profile =
+            Settings::values.players.GetValue()[player_index].profile_name;
 
-    ui->profile_player_1->addItem(QString::fromStdString("Use global configuration"));
-    for (size_t index = 0; index < profile_names.size(); ++index) {
-        const auto& profile_name = profile_names[index];
-        ui->profile_player_1->addItem(QString::fromStdString(profile_name));
-        if (profile_name == previous_profile) {
-            // offset by 1 since the first element is the global config
-            ui->profile_player_1->setCurrentIndex(static_cast<int>(index + 1));
+        auto* const player_combobox = profile_comboboxes[player_index];
+        player_combobox->addItem(tr("Use global input configuration"));
+        for (size_t index = 0; index < profile_names.size(); ++index) {
+            const auto& profile_name = profile_names[index];
+            player_combobox->addItem(QString::fromStdString(profile_name));
+            if (profile_name == previous_profile) {
+                // offset by 1 since the first element is the global config
+                player_combobox->setCurrentIndex(static_cast<int>(index + 1));
+            }
         }
+    };
+
+    for (size_t index = 0; index < profile_comboboxes.size(); ++index) {
+        labels[index]->setText(tr("Player %1 profile").arg(index + 1));
+        populate_profiles(index);
     }
+
     LoadConfiguration();
 }
 
 void ConfigureInputPerGame::ApplyConfiguration() {
     LoadConfiguration();
-
-    auto& hid_core = system.HIDCore();
-    auto* emulated_controller = hid_core.GetEmulatedControllerByIndex(0);
-
-    const auto selection_index = ui->profile_player_1->currentIndex();
-    if (selection_index == 0) {
-        Settings::values.players.SetGlobal(true);
-        emulated_controller->ReloadFromSettings();
-        return;
-    } else {
-        Settings::values.players.SetGlobal(false);
-    }
-    const QString profile_name = ui->profile_player_1->itemText(selection_index);
-    if (profile_name.isEmpty()) {
-        return;
-    }
-    profiles->SaveProfile(Settings::values.players.GetValue()[0].profile_name, 0);
-    emulated_controller->ReloadFromSettings();
+    SaveConfiguration();
 }
 
 void ConfigureInputPerGame::LoadConfiguration() {
     auto& hid_core = system.HIDCore();
-    auto* emulated_controller = hid_core.GetEmulatedControllerByIndex(0);
+    const auto load_player_profile = [this, &hid_core](size_t player_index) {
+        Settings::values.players.SetGlobal(false);
 
+        auto* emulated_controller = hid_core.GetEmulatedControllerByIndex(player_index);
+        auto* const player_combobox = profile_comboboxes[player_index];
+
+        const auto selection_index = player_combobox->currentIndex();
+        if (selection_index == 0) {
+            Settings::values.players.GetValue()[player_index].profile_name = "";
+            Settings::values.players.SetGlobal(true);
+            emulated_controller->ReloadFromSettings();
+            return;
+        }
+        const auto profile_name = player_combobox->itemText(selection_index).toStdString();
+        if (profile_name.empty()) {
+            return;
+        }
+        profiles->LoadProfile(profile_name, player_index);
+        Settings::values.players.GetValue()[player_index].profile_name = profile_name;
+        emulated_controller->ReloadFromSettings();
+    };
+
+    for (size_t index = 0; index < profile_comboboxes.size(); ++index) {
+        load_player_profile(index);
+    }
+}
+
+void ConfigureInputPerGame::SaveConfiguration() {
     Settings::values.players.SetGlobal(false);
 
-    const auto selection_index = ui->profile_player_1->currentIndex();
-    if (selection_index == 0) {
-        Settings::values.players.GetValue()[0].profile_name = "";
-        Settings::values.players.SetGlobal(true);
+    auto& hid_core = system.HIDCore();
+    const auto save_player_profile = [this, &hid_core](size_t player_index) {
+        const auto selection_index = profile_comboboxes[player_index]->currentIndex();
+        if (selection_index == 0) {
+            return;
+        }
+        auto* emulated_controller = hid_core.GetEmulatedControllerByIndex(player_index);
+        profiles->SaveProfile(Settings::values.players.GetValue()[player_index].profile_name,
+                              player_index);
         emulated_controller->ReloadFromSettings();
-        return;
+    };
+
+    for (size_t index = 0; index < profile_comboboxes.size(); ++index) {
+        save_player_profile(index);
     }
-    const QString profile_name = ui->profile_player_1->itemText(selection_index);
-    if (profile_name.isEmpty()) {
-        return;
-    }
-    profiles->LoadProfile(profile_name.toStdString(), 0);
-    Settings::values.players.GetValue()[0].profile_name = profile_name.toStdString();
-    emulated_controller->ReloadFromSettings();
 }
diff --git a/src/yuzu/configuration/configure_input_per_game.h b/src/yuzu/configuration/configure_input_per_game.h
index 6feb608b7a..a586ec07c8 100644
--- a/src/yuzu/configuration/configure_input_per_game.h
+++ b/src/yuzu/configuration/configure_input_per_game.h
@@ -11,10 +11,6 @@ namespace Core {
 class System;
 }
 
-namespace InputCommon {
-class InputSubsystem;
-}
-
 namespace Ui {
 class ConfigureInputPerGame;
 }
@@ -27,18 +23,20 @@ class ConfigureInputPerGame : public QWidget {
 public:
     explicit ConfigureInputPerGame(Core::System& system_, QWidget* parent = nullptr);
 
-    /// Initializes the input dialog with the given input subsystem.
-    // void Initialize(InputCommon::InputSubsystem* input_subsystem_, std::size_t max_players = 8);
-
-    /// Save configurations to settings file.
+    /// Load and Save configurations to settings file.
     void ApplyConfiguration();
 
 private:
     /// Load configuration from settings file.
     void LoadConfiguration();
 
+    /// Save configuration to settings file.
+    void SaveConfiguration();
+
     std::unique_ptr<Ui::ConfigureInputPerGame> ui;
     std::unique_ptr<InputProfiles> profiles;
 
+    std::array<QComboBox*, 8> profile_comboboxes;
+
     Core::System& system;
 };
diff --git a/src/yuzu/configuration/configure_input_per_game.ui b/src/yuzu/configuration/configure_input_per_game.ui
index 8a384c0df7..fbd8eab1ca 100644
--- a/src/yuzu/configuration/configure_input_per_game.ui
+++ b/src/yuzu/configuration/configure_input_per_game.ui
@@ -30,7 +30,7 @@
        <layout class="QVBoxLayout" name="verticalLayout_4">
         <item>
          <widget class="QWidget" name="player_1" native="true">
-          <layout class="QHBoxLayout" name="input_profile_layout">
+          <layout class="QHBoxLayout" name="input_profile_layout_1">
            <property name="leftMargin">
             <number>0</number>
            </property>
@@ -63,9 +63,44 @@
           </layout>
          </widget>
         </item>
+        <item>
+         <widget class="QWidget" name="player_2" native="true">
+          <layout class="QHBoxLayout" name="input_profile_layout_2">
+           <property name="leftMargin">
+            <number>0</number>
+           </property>
+           <property name="topMargin">
+            <number>0</number>
+           </property>
+           <property name="rightMargin">
+            <number>0</number>
+           </property>
+           <property name="bottomMargin">
+            <number>0</number>
+           </property>
+           <item>
+            <widget class="QLabel" name="label_player_2">
+             <property name="text">
+              <string>Player 2 Profile</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <widget class="QComboBox" name="profile_player_2">
+             <property name="sizePolicy">
+              <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+               <horstretch>0</horstretch>
+               <verstretch>0</verstretch>
+              </sizepolicy>
+             </property>
+            </widget>
+           </item>
+          </layout>
+         </widget>
+        </item>
         <item>
          <widget class="QWidget" name="player_3" native="true">
-          <layout class="QHBoxLayout" name="input_profile_layout">
+          <layout class="QHBoxLayout" name="input_profile_layout_3">
            <property name="leftMargin">
             <number>0</number>
            </property>
@@ -100,7 +135,7 @@
         </item>
         <item>
          <widget class="QWidget" name="player_4" native="true">
-          <layout class="QHBoxLayout" name="input_profile_layout">
+          <layout class="QHBoxLayout" name="input_profile_layout_4">
            <property name="leftMargin">
             <number>0</number>
            </property>
@@ -135,7 +170,7 @@
         </item>
         <item>
          <widget class="QWidget" name="player_5" native="true">
-          <layout class="QHBoxLayout" name="input_profile_layout">
+          <layout class="QHBoxLayout" name="input_profile_layout_5">
            <property name="leftMargin">
             <number>0</number>
            </property>
@@ -170,7 +205,7 @@
         </item>
         <item>
          <widget class="QWidget" name="player_6" native="true">
-          <layout class="QHBoxLayout" name="input_profile_layout">
+          <layout class="QHBoxLayout" name="input_profile_layout_6">
            <property name="leftMargin">
             <number>0</number>
            </property>
@@ -205,7 +240,7 @@
         </item>
         <item>
          <widget class="QWidget" name="player_7" native="true">
-          <layout class="QHBoxLayout" name="input_profile_layout">
+          <layout class="QHBoxLayout" name="input_profile_layout_7">
            <property name="leftMargin">
             <number>0</number>
            </property>
@@ -240,7 +275,7 @@
         </item>
         <item>
          <widget class="QWidget" name="player_8" native="true">
-          <layout class="QHBoxLayout" name="input_profile_layout">
+          <layout class="QHBoxLayout" name="input_profile_layout_8">
            <property name="leftMargin">
             <number>0</number>
            </property>