diff --git a/CONFIG.md b/CONFIG.md
index 764eb528da..b5de9fa6dc 100644
--- a/CONFIG.md
+++ b/CONFIG.md
@@ -8,23 +8,23 @@
 
 - `Logging_Enable_Trace` *(bool)*
 
-  Enable the Trace Logging (Enabled in Debug recommanded).
+  Enable the Trace Logging (Enabled in Debug recommended).
   
 - `Logging_Enable_Debug` *(bool)*
 
-   Enable the Debug Logging (Enabled in Debug recommanded).
+   Enable the Debug Logging (Enabled in Debug recommended).
 
 - `Logging_Enable_Warn` *(bool)*
 
-  Enable the Warning Logging (Enabled in Debug recommanded).
+  Enable the Warning Logging (Enabled in Debug recommended).
 
 - `Logging_Enable_Error` *(bool)*
 
-  Enable the Error Logging (Enabled in Debug recommanded).
+  Enable the Error Logging (Enabled in Debug recommended).
 
 - `Logging_Enable_Fatal` *(bool)*
 
-  Enable the Fatal Logging (Enabled in Debug recommanded).
+  Enable the Fatal Logging (Enabled in Debug recommended).
 
 - `Logging_Enable_Ipc` *(bool)*
 
@@ -34,46 +34,107 @@
 
   Enable writing the logging inside a Ryujinx.log file.
   
-- `Controls_Left_FakeJoycon_XX` *(int)*
+- `GamePad_Index` *(int)*
+
+  The index of the Controller Device.
+  
+- `GamePad_Deadzone` *(float)*
+
+  The deadzone of both analog sticks on the Controller.
+
+- `GamePad_Enable` *(bool)*
+  
+  Whether or not to enable Controller Support.
+  
+- `Controls_Left_JoyConKeyboard_XX` *(int)*
   ```
-  Controls_Left_FakeJoycon_Stick_Up (int)
-  Controls_Left_FakeJoycon_Stick_Down (int)
-  Controls_Left_FakeJoycon_Stick_Left (int)
-  Controls_Left_FakeJoycon_Stick_Right (int)
-  Controls_Left_FakeJoycon_Stick_Button (int)
-  Controls_Left_FakeJoycon_DPad_Up (int)
-  Controls_Left_FakeJoycon_DPad_Down (int)
-  Controls_Left_FakeJoycon_DPad_Left (int)
-  Controls_Left_FakeJoycon_DPad_Right (int)
-  Controls_Left_FakeJoycon_Button_Minus (int)
-  Controls_Left_FakeJoycon_Button_L (int)
-  Controls_Left_FakeJoycon_Button_ZL (int)
+  Controls_Left_JoyConKeyboard_Stick_Up (int)
+  Controls_Left_JoyConKeyboard_Stick_Down (int)
+  Controls_Left_JoyConKeyboard_Stick_Left (int)
+  Controls_Left_JoyConKeyboard_Stick_Right (int)
+  Controls_Left_JoyConKeyboard_Stick_Button (int)
+  Controls_Left_JoyConKeyboard_DPad_Up (int)
+  Controls_Left_JoyConKeyboard_DPad_Down (int)
+  Controls_Left_JoyConKeyboard_DPad_Left (int)
+  Controls_Left_JoyConKeyboard_DPad_Right (int)
+  Controls_Left_JoyConKeyboard_Button_Minus (int)
+  Controls_Left_JoyConKeyboard_Button_L (int)
+  Controls_Left_JoyConKeyboard_Button_ZL (int)
   ```
   
   Keys of the Left Emulated Joycon, the values depend of the [OpenTK Enum Keys](https://github.com/opentk/opentk/blob/develop/src/OpenTK/Input/Key.cs).
   
   OpenTK use a QWERTY layout, so pay attention if you use another Keyboard Layout.
   
-  Ex: `Controls_Left_FakeJoycon_Button_Minus = 52` > Tab key (All Layout).
+  Ex: `Controls_Left_JoyConKeyboard_Button_Minus = 52` > Tab key (All Layout).
 
-- `Controls_Right_FakeJoycon_XX` *(int)*
+- `Controls_Right_JoyConKeyboard_XX` *(int)*
   ```
-  Controls_Right_FakeJoycon_Stick_Up (int)
-  Controls_Right_FakeJoycon_Stick_Down (int)
-  Controls_Right_FakeJoycon_Stick_Left (int)
-  Controls_Right_FakeJoycon_Stick_Right (int)
-  Controls_Right_FakeJoycon_Stick_Button (int)
-  Controls_Right_FakeJoycon_Button_A (int)
-  Controls_Right_FakeJoycon_Button_B (int)
-  Controls_Right_FakeJoycon_Button_X (int)
-  Controls_Right_FakeJoycon_Button_Y (int)
-  Controls_Right_FakeJoycon_Button_Plus (int)
-  Controls_Right_FakeJoycon_Button_R (int)
-  Controls_Right_FakeJoycon_Button_ZR (int)
+  Controls_Right_JoyConKeyboard_Stick_Up (int)
+  Controls_Right_JoyConKeyboard_Stick_Down (int)
+  Controls_Right_JoyConKeyboard_Stick_Left (int)
+  Controls_Right_JoyConKeyboard_Stick_Right (int)
+  Controls_Right_JoyConKeyboard_Stick_Button (int)
+  Controls_Right_JoyConKeyboard_Button_A (int)
+  Controls_Right_JoyConKeyboard_Button_B (int)
+  Controls_Right_JoyConKeyboard_Button_X (int)
+  Controls_Right_JoyConKeyboard_Button_Y (int)
+  Controls_Right_JoyConKeyboard_Button_Plus (int)
+  Controls_Right_JoyConKeyboard_Button_R (int)
+  Controls_Right_JoyConKeyboard_Button_ZR (int)
   ```
 
   Keys of the right Emulated Joycon, the values depend of the [OpenTK Enum Keys](https://github.com/opentk/opentk/blob/develop/src/OpenTK/Input/Key.cs).
   
   OpenTK use a QWERTY layout, so pay attention if you use another Keyboard Layout.
   
-  Ex: `Controls_Right_FakeJoycon_Button_A = 83` > A key (QWERTY Layout) / Q key (AZERTY Layout).
+  Ex: `Controls_Right_JoyConKeyboard_Button_A = 83` > A key (QWERTY Layout) / Q key (AZERTY Layout).
+  
+- `Controls_Left_JoyConController_XX` *(String)*
+  ```
+  Controls_Left_JoyConController_Stick (String)
+  Controls_Left_JoyConController_Stick_Button (String)
+  Controls_Left_JoyConController_DPad_Up (String)
+  Controls_Left_JoyConController_DPad_Down (String)
+  Controls_Left_JoyConController_DPad_Left (String)
+  Controls_Left_JoyConController_DPad_Right (String)
+  Controls_Left_JoyConController_Button_Minus (String)
+  Controls_Left_JoyConController_Button_L (String)
+  Controls_Left_JoyConController_Button_ZL (String)
+  ```
+  
+- `Controls_Right_JoyConController_XX` *(String)*
+  ```
+  Controls_Right_JoyConController_Stick (String)
+  Controls_Right_JoyConController_Stick_Button (String)
+  Controls_Right_JoyConController_Button_A (String)
+  Controls_Right_JoyConController_Button_B (String)
+  Controls_Right_JoyConController_Button_X (String)
+  Controls_Right_JoyConController_Button_Y (String)
+  Controls_Right_JoyConController_Button_Plus (String)
+  Controls_Right_JoyConController_Button_R (String)
+  Controls_Right_JoyConController_Button_ZR (String)
+  ```
+
+- Valid Button Mappings
+  - A = The A / Cross Button
+  - B = The B / Circle Button
+  - X = The X / Square Button
+  - Y = The Y / Triangle Button
+  - LStick = The Left Analog Stick when Pressed Down
+  - RStick = The Right Analog Stick when Pressed Down
+  - Start = The Start / Options Button
+  - Back = The Select / Back / Share Button
+  - RShoulder = The Right Shoulder Button
+  - LShoulder = The Left Shoulder Button
+  - RTrigger = The Right Trigger
+  - LTrigger = The Left Trigger
+  - DPadUp = Up on the DPad
+  - DPadDown = Down on the DPad
+  - DPadLeft = Left on the DPad
+  - DpadRight = Right on the DPad
+- Valid Joystick Mappings
+  - LJoystick = The Left Analog Stick
+  - RJoystick = The Right Analog Stick
+
+  On more obscure / weird controllers this can vary, so if this list doesn't work, trial and error will.
\ No newline at end of file
diff --git a/README.md b/README.md
index 3efd347a85..71dad9ce29 100644
--- a/README.md
+++ b/README.md
@@ -46,9 +46,32 @@ https://openal.org/downloads/OpenAL11CoreSDK.zip
 	 - Plus = +
 	 - R = U
 	 - ZR = O
+   - For more information on how to configure these buttons see [CONFIG.md](CONFIG.md)
+
+ - Controller Input is partially supported:
+   - Left Joycon:
+     - Analog Stick = Left Analog Stick
+	 - DPad Up = DPad Up
+	 - DPad Down = DPad Down
+	 - DPad Left = DPad Left
+	 - DPad Right = DPad Right
+	 - Minus = Select / Back / Share
+	 - L = Left Shoulder Button
+	 - ZL = Left Trigger
+	 
+   - Right Joycon:
+	 - Analog Stick = Right Analog Stick
+	 - A = B / Circle
+	 - B = A / Cross
+	 - X = Y / Triangle
+	 - Y = X / Square
+	 - Plus = Start / Options
+	 - R = Right Shoulder Button
+	 - ZR = Right Trigger
+   - For more information on how to configure these buttons see [CONFIG.md](CONFIG.md)
 
  - Config File: `Ryujinx.conf` should be present in executable folder.
-   For more informations [you can go here](CONFIG.md).
+   For more information [you can go here](CONFIG.md).
 
  - If you are a Windows user, you can configure your keys, the logs, install OpenAL, etc... with Ryujinx-Setting.
  [Download it, right here](https://github.com/AcK77/Ryujinx-Settings)
diff --git a/Ryujinx/Config.cs b/Ryujinx/Config.cs
index b437a006dd..940753ba53 100644
--- a/Ryujinx/Config.cs
+++ b/Ryujinx/Config.cs
@@ -1,6 +1,7 @@
-using Ryujinx.HLE.Input;
+using Ryujinx.UI.Input;
 using Ryujinx.HLE.Logging;
 using System;
+using System.Globalization;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
@@ -10,7 +11,13 @@ namespace Ryujinx
 {
     public static class Config
     {
-        public static JoyCon FakeJoyCon { get; private set; }
+        public static JoyConKeyboard   JoyConKeyboard   { get; private set; }
+        public static JoyConController JoyConController { get; private set; }
+
+        public static float GamePadDeadzone             { get; private set; }
+        public static bool  GamePadEnable               { get; private set; }
+        public static int   GamePadIndex                { get; private set; }
+        public static float GamePadTriggerThreshold     { get; private set; }
 
         public static void Read(Logger Log)
         {
@@ -28,6 +35,11 @@ namespace Ryujinx
             Log.SetEnable(LogLevel.Warning, Convert.ToBoolean(Parser.Value("Logging_Enable_Warn")));
             Log.SetEnable(LogLevel.Error,   Convert.ToBoolean(Parser.Value("Logging_Enable_Error")));
 
+            GamePadEnable            =        Convert.ToBoolean(Parser.Value("GamePad_Enable"));
+            GamePadIndex             =        Convert.ToInt32  (Parser.Value("GamePad_Index"));
+            GamePadDeadzone          = (float)Convert.ToDouble (Parser.Value("GamePad_Deadzone"),          CultureInfo.InvariantCulture);
+            GamePadTriggerThreshold  = (float)Convert.ToDouble (Parser.Value("GamePad_Trigger_Threshold"), CultureInfo.InvariantCulture);
+
             string[] FilteredLogClasses = Parser.Value("Logging_Filtered_Classes").Split(',', StringSplitOptions.RemoveEmptyEntries);
 
             //When the classes are specified on the list, we only
@@ -56,44 +68,73 @@ namespace Ryujinx
                 }
             }
 
-            FakeJoyCon = new JoyCon
+            JoyConKeyboard = new JoyConKeyboard
             {
-                Left = new JoyConLeft
+                Left = new JoyConKeyboardLeft
                 {
-                    StickUp     = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_Stick_Up")),
-                    StickDown   = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_Stick_Down")),
-                    StickLeft   = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_Stick_Left")),
-                    StickRight  = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_Stick_Right")),
-                    StickButton = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_Stick_Button")),
-                    DPadUp      = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_DPad_Up")),
-                    DPadDown    = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_DPad_Down")),
-                    DPadLeft    = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_DPad_Left")),
-                    DPadRight   = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_DPad_Right")),
-                    ButtonMinus = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_Button_Minus")),
-                    ButtonL     = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_Button_L")),
-                    ButtonZL    = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_Button_ZL"))
+                    StickUp     = Convert.ToInt16(Parser.Value("Controls_Left_JoyConKeyboard_Stick_Up")),
+                    StickDown   = Convert.ToInt16(Parser.Value("Controls_Left_JoyConKeyboard_Stick_Down")),
+                    StickLeft   = Convert.ToInt16(Parser.Value("Controls_Left_JoyConKeyboard_Stick_Left")),
+                    StickRight  = Convert.ToInt16(Parser.Value("Controls_Left_JoyConKeyboard_Stick_Right")),
+                    StickButton = Convert.ToInt16(Parser.Value("Controls_Left_JoyConKeyboard_Stick_Button")),
+                    DPadUp      = Convert.ToInt16(Parser.Value("Controls_Left_JoyConKeyboard_DPad_Up")),
+                    DPadDown    = Convert.ToInt16(Parser.Value("Controls_Left_JoyConKeyboard_DPad_Down")),
+                    DPadLeft    = Convert.ToInt16(Parser.Value("Controls_Left_JoyConKeyboard_DPad_Left")),
+                    DPadRight   = Convert.ToInt16(Parser.Value("Controls_Left_JoyConKeyboard_DPad_Right")),
+                    ButtonMinus = Convert.ToInt16(Parser.Value("Controls_Left_JoyConKeyboard_Button_Minus")),
+                    ButtonL     = Convert.ToInt16(Parser.Value("Controls_Left_JoyConKeyboard_Button_L")),
+                    ButtonZL    = Convert.ToInt16(Parser.Value("Controls_Left_JoyConKeyboard_Button_ZL"))
                 },
 
-                Right = new JoyConRight
+                Right = new JoyConKeyboardRight
                 {
-                    StickUp     = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Stick_Up")),
-                    StickDown   = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Stick_Down")),
-                    StickLeft   = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Stick_Left")),
-                    StickRight  = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Stick_Right")),
-                    StickButton = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Stick_Button")),
-                    ButtonA     = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Button_A")),
-                    ButtonB     = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Button_B")),
-                    ButtonX     = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Button_X")),
-                    ButtonY     = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Button_Y")),
-                    ButtonPlus  = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Button_Plus")),
-                    ButtonR     = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Button_R")),
-                    ButtonZR    = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Button_ZR"))
+                    StickUp     = Convert.ToInt16(Parser.Value("Controls_Right_JoyConKeyboard_Stick_Up")),
+                    StickDown   = Convert.ToInt16(Parser.Value("Controls_Right_JoyConKeyboard_Stick_Down")),
+                    StickLeft   = Convert.ToInt16(Parser.Value("Controls_Right_JoyConKeyboard_Stick_Left")),
+                    StickRight  = Convert.ToInt16(Parser.Value("Controls_Right_JoyConKeyboard_Stick_Right")),
+                    StickButton = Convert.ToInt16(Parser.Value("Controls_Right_JoyConKeyboard_Stick_Button")),
+                    ButtonA     = Convert.ToInt16(Parser.Value("Controls_Right_JoyConKeyboard_Button_A")),
+                    ButtonB     = Convert.ToInt16(Parser.Value("Controls_Right_JoyConKeyboard_Button_B")),
+                    ButtonX     = Convert.ToInt16(Parser.Value("Controls_Right_JoyConKeyboard_Button_X")),
+                    ButtonY     = Convert.ToInt16(Parser.Value("Controls_Right_JoyConKeyboard_Button_Y")),
+                    ButtonPlus  = Convert.ToInt16(Parser.Value("Controls_Right_JoyConKeyboard_Button_Plus")),
+                    ButtonR     = Convert.ToInt16(Parser.Value("Controls_Right_JoyConKeyboard_Button_R")),
+                    ButtonZR    = Convert.ToInt16(Parser.Value("Controls_Right_JoyConKeyboard_Button_ZR"))
+                }
+            };
+
+            JoyConController = new JoyConController
+            {
+                Left = new JoyConControllerLeft
+                {
+                    Stick       = Parser.Value("Controls_Left_JoyConController_Stick"),
+                    StickButton = Parser.Value("Controls_Left_JoyConController_Stick_Button"),
+                    DPadUp      = Parser.Value("Controls_Left_JoyConController_DPad_Up"),
+                    DPadDown    = Parser.Value("Controls_Left_JoyConController_DPad_Down"),
+                    DPadLeft    = Parser.Value("Controls_Left_JoyConController_DPad_Left"),
+                    DPadRight   = Parser.Value("Controls_Left_JoyConController_DPad_Right"),
+                    ButtonMinus = Parser.Value("Controls_Left_JoyConController_Button_Minus"),
+                    ButtonL     = Parser.Value("Controls_Left_JoyConController_Button_L"),
+                    ButtonZL    = Parser.Value("Controls_Left_JoyConController_Button_ZL")
+                },
+
+                Right = new JoyConControllerRight
+                {
+                    Stick       = Parser.Value("Controls_Right_JoyConController_Stick"),
+                    StickButton = Parser.Value("Controls_Right_JoyConController_Stick_Button"),
+                    ButtonA     = Parser.Value("Controls_Right_JoyConController_Button_A"),
+                    ButtonB     = Parser.Value("Controls_Right_JoyConController_Button_B"),
+                    ButtonX     = Parser.Value("Controls_Right_JoyConController_Button_X"),
+                    ButtonY     = Parser.Value("Controls_Right_JoyConController_Button_Y"),
+                    ButtonPlus  = Parser.Value("Controls_Right_JoyConController_Button_Plus"),
+                    ButtonR     = Parser.Value("Controls_Right_JoyConController_Button_R"),
+                    ButtonZR    = Parser.Value("Controls_Right_JoyConController_Button_ZR")
                 }
             };
         }
     }
 
-    // https://stackoverflow.com/a/37772571
+    //https://stackoverflow.com/a/37772571
     public class IniParser
     {
         private readonly Dictionary<string, string> Values;
diff --git a/Ryujinx/Ryujinx.conf b/Ryujinx/Ryujinx.conf
index 611f320717..59f7f859e7 100644
--- a/Ryujinx/Ryujinx.conf
+++ b/Ryujinx/Ryujinx.conf
@@ -19,29 +19,64 @@ Logging_Enable_Error = true
 #Filtered log classes, seperated by ", ", eg. `Logging_Filtered_Classes = Loader, ServiceFS`
 Logging_Filtered_Classes =
 
-#https://github.com/opentk/opentk/blob/develop/src/OpenTK/Input/Key.cs
-Controls_Left_FakeJoycon_Stick_Up = 105
-Controls_Left_FakeJoycon_Stick_Down = 101
-Controls_Left_FakeJoycon_Stick_Left = 83
-Controls_Left_FakeJoycon_Stick_Right = 86
-Controls_Left_FakeJoycon_Stick_Button = 88
-Controls_Left_FakeJoycon_DPad_Up = 45
-Controls_Left_FakeJoycon_DPad_Down = 46
-Controls_Left_FakeJoycon_DPad_Left = 47
-Controls_Left_FakeJoycon_DPad_Right = 48
-Controls_Left_FakeJoycon_Button_Minus = 120
-Controls_Left_FakeJoycon_Button_L = 87
-Controls_Left_FakeJoycon_Button_ZL = 99
+#Controller Device Index
+GamePad_Index = 0
 
-Controls_Right_FakeJoycon_Stick_Up = 91
-Controls_Right_FakeJoycon_Stick_Down = 93
-Controls_Right_FakeJoycon_Stick_Left = 92
-Controls_Right_FakeJoycon_Stick_Right = 94
-Controls_Right_FakeJoycon_Stick_Button = 90
-Controls_Right_FakeJoycon_Button_A = 108
-Controls_Right_FakeJoycon_Button_B = 106
-Controls_Right_FakeJoycon_Button_X = 85
-Controls_Right_FakeJoycon_Button_Y = 104
-Controls_Right_FakeJoycon_Button_Plus = 121
-Controls_Right_FakeJoycon_Button_R = 103
-Controls_Right_FakeJoycon_Button_ZR = 97
\ No newline at end of file
+#Controller Analog Stick Deadzone
+GamePad_Deadzone = 0.05
+
+#The value of how pressed down each trigger has to be in order to register a button press
+GamePad_Trigger_Threshold = 0.5
+
+#Whether or not to enable Controller support
+GamePad_Enable = true
+
+#https://github.com/opentk/opentk/blob/develop/src/OpenTK/Input/Key.cs
+Controls_Left_JoyConKeyboard_Stick_Up = 105
+Controls_Left_JoyConKeyboard_Stick_Down = 101
+Controls_Left_JoyConKeyboard_Stick_Left = 83
+Controls_Left_JoyConKeyboard_Stick_Right = 86
+Controls_Left_JoyConKeyboard_Stick_Button = 88
+Controls_Left_JoyConKeyboard_DPad_Up = 45
+Controls_Left_JoyConKeyboard_DPad_Down = 46
+Controls_Left_JoyConKeyboard_DPad_Left = 47
+Controls_Left_JoyConKeyboard_DPad_Right = 48
+Controls_Left_JoyConKeyboard_Button_Minus = 120
+Controls_Left_JoyConKeyboard_Button_L = 87
+Controls_Left_JoyConKeyboard_Button_ZL = 99
+
+Controls_Right_JoyConKeyboard_Stick_Up = 91
+Controls_Right_JoyConKeyboard_Stick_Down = 93
+Controls_Right_JoyConKeyboard_Stick_Left = 92
+Controls_Right_JoyConKeyboard_Stick_Right = 94
+Controls_Right_JoyConKeyboard_Stick_Button = 90
+Controls_Right_JoyConKeyboard_Button_A = 108
+Controls_Right_JoyConKeyboard_Button_B = 106
+Controls_Right_JoyConKeyboard_Button_X = 85
+Controls_Right_JoyConKeyboard_Button_Y = 104
+Controls_Right_JoyConKeyboard_Button_Plus = 121
+Controls_Right_JoyConKeyboard_Button_R = 103
+Controls_Right_JoyConKeyboard_Button_ZR = 97
+
+#Controller Controls
+
+Controls_Left_JoyConController_Stick_Button = LStick
+Controls_Left_JoyConController_DPad_Up = DPadUp
+Controls_Left_JoyConController_DPad_Down = DPadDown
+Controls_Left_JoyConController_DPad_Left = DPadLeft
+Controls_Left_JoyConController_DPad_Right = DPadRight
+Controls_Left_JoyConController_Button_Minus = Back
+Controls_Left_JoyConController_Button_L = LShoulder
+Controls_Left_JoyConController_Button_ZL = LTrigger
+
+Controls_Right_JoyConController_Stick_Button = RStick
+Controls_Right_JoyConController_Button_A = B
+Controls_Right_JoyConController_Button_B = A
+Controls_Right_JoyConController_Button_X = Y
+Controls_Right_JoyConController_Button_Y = X
+Controls_Right_JoyConController_Button_Plus = Start
+Controls_Right_JoyConController_Button_R = RShoulder
+Controls_Right_JoyConController_Button_ZR = RTrigger
+
+Controls_Left_JoyConController_Stick = LJoystick
+Controls_Right_JoyConController_Stick = RJoystick
\ No newline at end of file
diff --git a/Ryujinx/Ui/GLScreen.cs b/Ryujinx/Ui/GLScreen.cs
index ab5eaa0f52..7a4e42e9e2 100644
--- a/Ryujinx/Ui/GLScreen.cs
+++ b/Ryujinx/Ui/GLScreen.cs
@@ -44,55 +44,154 @@ namespace Ryujinx
 
             Renderer.FrameBuffer.SetWindowSize(Width, Height);
         }
+        
+        private bool IsGamePadButtonPressedFromString(GamePadState GamePad, string Button)
+        {
+            if (Button.ToUpper() == "LTRIGGER" || Button.ToUpper() == "RTRIGGER")
+            {
+                return GetGamePadTriggerFromString(GamePad, Button) >= Config.GamePadTriggerThreshold;
+            }
+            else
+            {
+                return (GetGamePadButtonFromString(GamePad, Button) == ButtonState.Pressed);
+            }
+        }
+
+        private ButtonState GetGamePadButtonFromString(GamePadState GamePad, string Button)
+        {
+            switch (Button.ToUpper())
+            {
+                case "A":         return GamePad.Buttons.A;
+                case "B":         return GamePad.Buttons.B;
+                case "X":         return GamePad.Buttons.X;
+                case "Y":         return GamePad.Buttons.Y;
+                case "LSTICK":    return GamePad.Buttons.LeftStick;
+                case "RSTICK":    return GamePad.Buttons.RightStick;
+                case "LSHOULDER": return GamePad.Buttons.LeftShoulder;
+                case "RSHOULDER": return GamePad.Buttons.RightShoulder;
+                case "DPADUP":    return GamePad.DPad.Up;
+                case "DPADDOWN":  return GamePad.DPad.Down;
+                case "DPADLEFT":  return GamePad.DPad.Left;
+                case "DPADRIGHT": return GamePad.DPad.Right;
+                case "START":     return GamePad.Buttons.Start;
+                case "BACK":      return GamePad.Buttons.Back;
+                default:          throw  new ArgumentException();
+            }
+        }
+
+        private float GetGamePadTriggerFromString(GamePadState GamePad, string Trigger)
+        {
+            switch (Trigger.ToUpper())
+            {
+                case "LTRIGGER": return GamePad.Triggers.Left;
+                case "RTRIGGER": return GamePad.Triggers.Right;
+                default:         throw  new ArgumentException();
+            }
+        }
+
+        private Vector2 GetJoystickAxisFromString(GamePadState GamePad, string Joystick)
+        {
+            switch (Joystick.ToUpper())
+            {
+                case "LJOYSTICK": return GamePad.ThumbSticks.Left;
+                case "RJOYSTICK": return new Vector2(-GamePad.ThumbSticks.Right.Y, -GamePad.ThumbSticks.Right.X);
+                default:          throw  new ArgumentException();
+            }
+        }
 
         protected override void OnUpdateFrame(FrameEventArgs e)
         {
             HidControllerButtons CurrentButton = 0;
-            HidJoystickPosition LeftJoystick;
-            HidJoystickPosition RightJoystick;
+            HidJoystickPosition  LeftJoystick;
+            HidJoystickPosition  RightJoystick;
 
-            int LeftJoystickDX = 0;
-            int LeftJoystickDY = 0;
-            int RightJoystickDX = 0;
-            int RightJoystickDY = 0;
+            int LeftJoystickDX        = 0;
+            int LeftJoystickDY        = 0;
+            int RightJoystickDX       = 0;
+            int RightJoystickDY       = 0;
+            float AnalogStickDeadzone = Config.GamePadDeadzone;
 
+            //Keyboard Input
             if (Keyboard.HasValue)
             {
                 KeyboardState Keyboard = this.Keyboard.Value;
 
                 if (Keyboard[Key.Escape]) this.Exit();
 
-                //RightJoystick
-                if (Keyboard[(Key)Config.FakeJoyCon.Left.StickUp])    LeftJoystickDY = short.MaxValue;
-                if (Keyboard[(Key)Config.FakeJoyCon.Left.StickDown])  LeftJoystickDY = -short.MaxValue;
-                if (Keyboard[(Key)Config.FakeJoyCon.Left.StickLeft])  LeftJoystickDX = -short.MaxValue;
-                if (Keyboard[(Key)Config.FakeJoyCon.Left.StickRight]) LeftJoystickDX = short.MaxValue;
+                //LeftJoystick
+                if (Keyboard[(Key)Config.JoyConKeyboard.Left.StickUp])    LeftJoystickDY = short.MaxValue;
+                if (Keyboard[(Key)Config.JoyConKeyboard.Left.StickDown])  LeftJoystickDY = -short.MaxValue;
+                if (Keyboard[(Key)Config.JoyConKeyboard.Left.StickLeft])  LeftJoystickDX = -short.MaxValue;
+                if (Keyboard[(Key)Config.JoyConKeyboard.Left.StickRight]) LeftJoystickDX = short.MaxValue;
 
                 //LeftButtons
-                if (Keyboard[(Key)Config.FakeJoyCon.Left.StickButton]) CurrentButton |= HidControllerButtons.KEY_LSTICK;
-                if (Keyboard[(Key)Config.FakeJoyCon.Left.DPadUp])      CurrentButton |= HidControllerButtons.KEY_DUP;
-                if (Keyboard[(Key)Config.FakeJoyCon.Left.DPadDown])    CurrentButton |= HidControllerButtons.KEY_DDOWN;
-                if (Keyboard[(Key)Config.FakeJoyCon.Left.DPadLeft])    CurrentButton |= HidControllerButtons.KEY_DLEFT;
-                if (Keyboard[(Key)Config.FakeJoyCon.Left.DPadRight])   CurrentButton |= HidControllerButtons.KEY_DRIGHT;
-                if (Keyboard[(Key)Config.FakeJoyCon.Left.ButtonMinus]) CurrentButton |= HidControllerButtons.KEY_MINUS;
-                if (Keyboard[(Key)Config.FakeJoyCon.Left.ButtonL])     CurrentButton |= HidControllerButtons.KEY_L;
-                if (Keyboard[(Key)Config.FakeJoyCon.Left.ButtonZL])    CurrentButton |= HidControllerButtons.KEY_ZL;
+                if (Keyboard[(Key)Config.JoyConKeyboard.Left.StickButton]) CurrentButton |= HidControllerButtons.KEY_LSTICK;
+                if (Keyboard[(Key)Config.JoyConKeyboard.Left.DPadUp])      CurrentButton |= HidControllerButtons.KEY_DUP;
+                if (Keyboard[(Key)Config.JoyConKeyboard.Left.DPadDown])    CurrentButton |= HidControllerButtons.KEY_DDOWN;
+                if (Keyboard[(Key)Config.JoyConKeyboard.Left.DPadLeft])    CurrentButton |= HidControllerButtons.KEY_DLEFT;
+                if (Keyboard[(Key)Config.JoyConKeyboard.Left.DPadRight])   CurrentButton |= HidControllerButtons.KEY_DRIGHT;
+                if (Keyboard[(Key)Config.JoyConKeyboard.Left.ButtonMinus]) CurrentButton |= HidControllerButtons.KEY_MINUS;
+                if (Keyboard[(Key)Config.JoyConKeyboard.Left.ButtonL])     CurrentButton |= HidControllerButtons.KEY_L;
+                if (Keyboard[(Key)Config.JoyConKeyboard.Left.ButtonZL])    CurrentButton |= HidControllerButtons.KEY_ZL;
 
                 //RightJoystick
-                if (Keyboard[(Key)Config.FakeJoyCon.Right.StickUp])    RightJoystickDY = short.MaxValue;
-                if (Keyboard[(Key)Config.FakeJoyCon.Right.StickDown])  RightJoystickDY = -short.MaxValue;
-                if (Keyboard[(Key)Config.FakeJoyCon.Right.StickLeft])  RightJoystickDX = -short.MaxValue;
-                if (Keyboard[(Key)Config.FakeJoyCon.Right.StickRight]) RightJoystickDX = short.MaxValue;
+                if (Keyboard[(Key)Config.JoyConKeyboard.Right.StickUp])    RightJoystickDY = short.MaxValue;
+                if (Keyboard[(Key)Config.JoyConKeyboard.Right.StickDown])  RightJoystickDY = -short.MaxValue;
+                if (Keyboard[(Key)Config.JoyConKeyboard.Right.StickLeft])  RightJoystickDX = -short.MaxValue;
+                if (Keyboard[(Key)Config.JoyConKeyboard.Right.StickRight]) RightJoystickDX = short.MaxValue;
 
                 //RightButtons
-                if (Keyboard[(Key)Config.FakeJoyCon.Right.StickButton]) CurrentButton |= HidControllerButtons.KEY_RSTICK;
-                if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonA])     CurrentButton |= HidControllerButtons.KEY_A;
-                if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonB])     CurrentButton |= HidControllerButtons.KEY_B;
-                if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonX])     CurrentButton |= HidControllerButtons.KEY_X;
-                if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonY])     CurrentButton |= HidControllerButtons.KEY_Y;
-                if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonPlus])  CurrentButton |= HidControllerButtons.KEY_PLUS;
-                if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonR])     CurrentButton |= HidControllerButtons.KEY_R;
-                if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonZR])    CurrentButton |= HidControllerButtons.KEY_ZR;
+                if (Keyboard[(Key)Config.JoyConKeyboard.Right.StickButton]) CurrentButton |= HidControllerButtons.KEY_RSTICK;
+                if (Keyboard[(Key)Config.JoyConKeyboard.Right.ButtonA])     CurrentButton |= HidControllerButtons.KEY_A;
+                if (Keyboard[(Key)Config.JoyConKeyboard.Right.ButtonB])     CurrentButton |= HidControllerButtons.KEY_B;
+                if (Keyboard[(Key)Config.JoyConKeyboard.Right.ButtonX])     CurrentButton |= HidControllerButtons.KEY_X;
+                if (Keyboard[(Key)Config.JoyConKeyboard.Right.ButtonY])     CurrentButton |= HidControllerButtons.KEY_Y;
+                if (Keyboard[(Key)Config.JoyConKeyboard.Right.ButtonPlus])  CurrentButton |= HidControllerButtons.KEY_PLUS;
+                if (Keyboard[(Key)Config.JoyConKeyboard.Right.ButtonR])     CurrentButton |= HidControllerButtons.KEY_R;
+                if (Keyboard[(Key)Config.JoyConKeyboard.Right.ButtonZR])    CurrentButton |= HidControllerButtons.KEY_ZR;
+            }
+
+            //Controller Input
+            if (Config.GamePadEnable)
+            {
+                GamePadState GamePad = OpenTK.Input.GamePad.GetState(Config.GamePadIndex);
+                //LeftButtons
+                if (IsGamePadButtonPressedFromString(GamePad, Config.JoyConController.Left.DPadUp))       CurrentButton |= HidControllerButtons.KEY_DUP;
+                if (IsGamePadButtonPressedFromString(GamePad, Config.JoyConController.Left.DPadDown))     CurrentButton |= HidControllerButtons.KEY_DDOWN;
+                if (IsGamePadButtonPressedFromString(GamePad, Config.JoyConController.Left.DPadLeft))     CurrentButton |= HidControllerButtons.KEY_DLEFT;
+                if (IsGamePadButtonPressedFromString(GamePad, Config.JoyConController.Left.DPadRight))    CurrentButton |= HidControllerButtons.KEY_DRIGHT;
+                if (IsGamePadButtonPressedFromString(GamePad, Config.JoyConController.Left.StickButton))  CurrentButton |= HidControllerButtons.KEY_LSTICK;
+                if (IsGamePadButtonPressedFromString(GamePad, Config.JoyConController.Left.ButtonMinus))  CurrentButton |= HidControllerButtons.KEY_MINUS;
+                if (IsGamePadButtonPressedFromString(GamePad, Config.JoyConController.Left.ButtonL))      CurrentButton |= HidControllerButtons.KEY_L;
+                if (IsGamePadButtonPressedFromString(GamePad, Config.JoyConController.Left.ButtonZL))     CurrentButton |= HidControllerButtons.KEY_ZL;
+
+                //RightButtons
+                if (IsGamePadButtonPressedFromString(GamePad, Config.JoyConController.Right.ButtonA))     CurrentButton |= HidControllerButtons.KEY_A;
+                if (IsGamePadButtonPressedFromString(GamePad, Config.JoyConController.Right.ButtonB))     CurrentButton |= HidControllerButtons.KEY_B;
+                if (IsGamePadButtonPressedFromString(GamePad, Config.JoyConController.Right.ButtonX))     CurrentButton |= HidControllerButtons.KEY_X;
+                if (IsGamePadButtonPressedFromString(GamePad, Config.JoyConController.Right.ButtonY))     CurrentButton |= HidControllerButtons.KEY_Y;
+                if (IsGamePadButtonPressedFromString(GamePad, Config.JoyConController.Right.StickButton)) CurrentButton |= HidControllerButtons.KEY_RSTICK;
+                if (IsGamePadButtonPressedFromString(GamePad, Config.JoyConController.Right.ButtonPlus))  CurrentButton |= HidControllerButtons.KEY_PLUS;
+                if (IsGamePadButtonPressedFromString(GamePad, Config.JoyConController.Right.ButtonR))     CurrentButton |= HidControllerButtons.KEY_R;
+                if (IsGamePadButtonPressedFromString(GamePad, Config.JoyConController.Right.ButtonZR))    CurrentButton |= HidControllerButtons.KEY_ZR;
+
+                //LeftJoystick
+                if (GetJoystickAxisFromString(GamePad, Config.JoyConController.Left.Stick).X >= AnalogStickDeadzone
+                 || GetJoystickAxisFromString(GamePad, Config.JoyConController.Left.Stick).X <= -AnalogStickDeadzone)
+                    LeftJoystickDX = (int)(GetJoystickAxisFromString(GamePad, Config.JoyConController.Left.Stick).X * short.MaxValue);
+
+                if (GetJoystickAxisFromString(GamePad, Config.JoyConController.Left.Stick).Y >= AnalogStickDeadzone
+                 || GetJoystickAxisFromString(GamePad, Config.JoyConController.Left.Stick).Y <= -AnalogStickDeadzone)
+                    LeftJoystickDY = (int)(GetJoystickAxisFromString(GamePad, Config.JoyConController.Left.Stick).Y * short.MaxValue);
+
+                //RightJoystick
+                if (GetJoystickAxisFromString(GamePad, Config.JoyConController.Right.Stick).X >= AnalogStickDeadzone
+                 || GetJoystickAxisFromString(GamePad, Config.JoyConController.Right.Stick).X <= -AnalogStickDeadzone)
+                    RightJoystickDX = (int)(GetJoystickAxisFromString(GamePad, Config.JoyConController.Right.Stick).X * short.MaxValue);
+
+                if (GetJoystickAxisFromString(GamePad, Config.JoyConController.Right.Stick).Y >= AnalogStickDeadzone
+                 || GetJoystickAxisFromString(GamePad, Config.JoyConController.Right.Stick).Y <= -AnalogStickDeadzone)
+                    RightJoystickDY = (int)(GetJoystickAxisFromString(GamePad, Config.JoyConController.Right.Stick).Y * short.MaxValue);
             }
 
             LeftJoystick = new HidJoystickPosition
diff --git a/Ryujinx/Ui/JoyConController.cs b/Ryujinx/Ui/JoyConController.cs
new file mode 100644
index 0000000000..e525017d3e
--- /dev/null
+++ b/Ryujinx/Ui/JoyConController.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Ryujinx.UI.Input
+{
+    public struct JoyConControllerLeft
+    {
+        public string Stick;
+        public string StickButton;
+        public string DPadUp;
+        public string DPadDown;
+        public string DPadLeft;
+        public string DPadRight;
+        public string ButtonMinus;
+        public string ButtonL;
+        public string ButtonZL;
+    }
+
+    public struct JoyConControllerRight
+    {
+        public string Stick;
+        public string StickButton;
+        public string ButtonA;
+        public string ButtonB;
+        public string ButtonX;
+        public string ButtonY;
+        public string ButtonPlus;
+        public string ButtonR;
+        public string ButtonZR;
+    }
+
+    public struct JoyConController
+    {
+        public JoyConControllerLeft Left;
+        public JoyConControllerRight Right;
+    }
+}
diff --git a/Ryujinx.HLE/Hid/JoyCon.cs b/Ryujinx/Ui/JoyConKeyboard.cs
similarity index 67%
rename from Ryujinx.HLE/Hid/JoyCon.cs
rename to Ryujinx/Ui/JoyConKeyboard.cs
index e45e1a47e4..b329d9ecd1 100644
--- a/Ryujinx.HLE/Hid/JoyCon.cs
+++ b/Ryujinx/Ui/JoyConKeyboard.cs
@@ -1,7 +1,6 @@
-//TODO: This is only used by Config, it doesn't belong to Core.
-namespace Ryujinx.HLE.Input
+namespace Ryujinx.UI.Input
 {
-    public struct JoyConLeft
+    public struct JoyConKeyboardLeft
     {
         public int StickUp;
         public int StickDown;
@@ -15,11 +14,9 @@ namespace Ryujinx.HLE.Input
         public int ButtonMinus;
         public int ButtonL;
         public int ButtonZL;
-        public int ButtonSL;
-        public int ButtonSR;
     }
 
-    public struct JoyConRight
+    public struct JoyConKeyboardRight
     {
         public int StickUp;
         public int StickDown;
@@ -33,13 +30,11 @@ namespace Ryujinx.HLE.Input
         public int ButtonPlus;
         public int ButtonR;
         public int ButtonZR;
-        public int ButtonSL;
-        public int ButtonSR;
     }
 
-    public struct JoyCon
+    public struct JoyConKeyboard
     {
-        public JoyConLeft Left;
-        public JoyConRight Right;
+        public JoyConKeyboardLeft Left;
+        public JoyConKeyboardRight Right;
     }
 }