diff --git a/src/ARMeilleure/CodeGen/Arm64/HardwareCapabilities.cs b/src/ARMeilleure/CodeGen/Arm64/HardwareCapabilities.cs
index 639e4476b..a736733df 100644
--- a/src/ARMeilleure/CodeGen/Arm64/HardwareCapabilities.cs
+++ b/src/ARMeilleure/CodeGen/Arm64/HardwareCapabilities.cs
@@ -19,8 +19,7 @@ namespace ARMeilleure.CodeGen.Arm64
                 LinuxFeatureInfoHwCap = (LinuxFeatureFlagsHwCap)getauxval(AT_HWCAP);
                 LinuxFeatureInfoHwCap2 = (LinuxFeatureFlagsHwCap2)getauxval(AT_HWCAP2);
             }
-
-            if (OperatingSystem.IsMacOS())
+            if (OperatingSystem.IsMacOS() || OperatingSystem.IsIOS())
             {
                 for (int i = 0; i < _sysctlNames.Length; i++)
                 {
@@ -130,6 +129,7 @@ namespace ARMeilleure.CodeGen.Arm64
         private static unsafe partial int sysctlbyname([MarshalAs(UnmanagedType.LPStr)] string name, out int oldValue, ref ulong oldSize, nint newValue, ulong newValueSize);
 
         [SupportedOSPlatform("macos")]
+        [SupportedOSPlatform("ios")]
         private static bool CheckSysctlName(string name)
         {
             ulong size = sizeof(int);
diff --git a/src/ARMeilleure/Signal/NativeSignalHandlerGenerator.cs b/src/ARMeilleure/Signal/NativeSignalHandlerGenerator.cs
index 35747d7a4..0e0992609 100644
--- a/src/ARMeilleure/Signal/NativeSignalHandlerGenerator.cs
+++ b/src/ARMeilleure/Signal/NativeSignalHandlerGenerator.cs
@@ -87,13 +87,13 @@ namespace ARMeilleure.Signal
 
         private static Operand GenerateUnixFaultAddress(EmitterContext context, Operand sigInfoPtr)
         {
-            ulong structAddressOffset = OperatingSystem.IsMacOS() ? 24ul : 16ul; // si_addr
+            ulong structAddressOffset = (OperatingSystem.IsMacOS() || OperatingSystem.IsIOS()) ? 24ul : 16ul; // si_addr
             return context.Load(OperandType.I64, context.Add(sigInfoPtr, Const(structAddressOffset)));
         }
 
         private static Operand GenerateUnixWriteFlag(EmitterContext context, Operand ucontextPtr)
         {
-            if (OperatingSystem.IsMacOS())
+            if (OperatingSystem.IsMacOS() || OperatingSystem.IsIOS())
             {
                 const ulong McontextOffset = 48; // uc_mcontext
                 Operand ctxPtr = context.Load(OperandType.I64, context.Add(ucontextPtr, Const(McontextOffset)));
diff --git a/src/ARMeilleure/Translation/Cache/CacheMemoryAllocator.cs b/src/ARMeilleure/Translation/Cache/CacheMemoryAllocator.cs
index f36bf7a3d..a1bd3933a 100644
--- a/src/ARMeilleure/Translation/Cache/CacheMemoryAllocator.cs
+++ b/src/ARMeilleure/Translation/Cache/CacheMemoryAllocator.cs
@@ -30,21 +30,26 @@ namespace ARMeilleure.Translation.Cache
             _blocks.Add(new MemoryBlock(0, capacity));
         }
 
-        public int Allocate(int size)
+        public int Allocate(ref int size, int alignment)
         {
+            int alignM1 = alignment - 1;
             for (int i = 0; i < _blocks.Count; i++)
             {
                 MemoryBlock block = _blocks[i];
+                int misAlignment = ((block.Offset + alignM1) & (~alignM1)) - block.Offset;
+                int alignedSize = size + misAlignment;
 
-                if (block.Size > size)
+                if (block.Size > alignedSize)
                 {
-                    _blocks[i] = new MemoryBlock(block.Offset + size, block.Size - size);
-                    return block.Offset;
+                    size = alignedSize;
+                    _blocks[i] = new MemoryBlock(block.Offset + alignedSize, block.Size - alignedSize);
+                    return block.Offset + misAlignment;
                 }
-                else if (block.Size == size)
+                else if (block.Size == alignedSize)
                 {
+                    size = alignedSize;
                     _blocks.RemoveAt(i);
-                    return block.Offset;
+                    return block.Offset + misAlignment;
                 }
             }
 
diff --git a/src/ARMeilleure/Translation/Cache/JitCache.cs b/src/ARMeilleure/Translation/Cache/JitCache.cs
index 6515b89c4..ae2e30c0d 100644
--- a/src/ARMeilleure/Translation/Cache/JitCache.cs
+++ b/src/ARMeilleure/Translation/Cache/JitCache.cs
@@ -47,7 +47,7 @@ namespace ARMeilleure.Translation.Cache
                     return;
                 }
 
-                _jitRegion = new ReservedRegion(allocator, CacheSize);
+                _jitRegion = new ReservedRegion(allocator, (ulong)(OperatingSystem.IsIOS() ? CacheSizeIOS : CacheSize));
 
                 if (!OperatingSystem.IsWindows() && !OperatingSystem.IsMacOS() && !OperatingSystem.IsIOS())
                 {
@@ -80,6 +80,7 @@ namespace ARMeilleure.Translation.Cache
                 
                 if (OperatingSystem.IsIOS())
                 {
+                    ReprotectAsWritable(funcOffset, code.Length);
                     Marshal.Copy(code, 0, funcPtr, code.Length);
                     ReprotectAsExecutable(funcOffset, code.Length);
 
@@ -119,6 +120,13 @@ namespace ARMeilleure.Translation.Cache
 
         public static void Unmap(nint pointer)
         {
+
+            if (OperatingSystem.IsIOS())
+            {
+                return;
+            }
+
+
             lock (_lock)
             {
                 Debug.Assert(_initialized);
@@ -157,7 +165,18 @@ namespace ARMeilleure.Translation.Cache
         {
             codeSize = AlignCodeSize(codeSize);
 
-            int allocOffset = _cacheAllocator.Allocate(codeSize);
+            int alignment = CodeAlignment;
+
+            if (OperatingSystem.IsIOS())
+            {
+                alignment = 0x4000;
+            }
+
+            int allocOffset = _cacheAllocator.Allocate(ref codeSize, alignment);
+
+            //DEBUG: Show JIT Memory Allocation
+
+            //Console.WriteLine($"{allocOffset:x8}: {codeSize:x8} {alignment:x8}");
 
             if (allocOffset < 0)
             {
@@ -171,6 +190,13 @@ namespace ARMeilleure.Translation.Cache
 
         private static int AlignCodeSize(int codeSize)
         {
+            int alignment = CodeAlignment;
+
+            if (OperatingSystem.IsIOS())
+            {
+                alignment = 0x4000;
+            }
+
             return checked(codeSize + (CodeAlignment - 1)) & ~(CodeAlignment - 1);
         }
 
diff --git a/src/ARMeilleure/Translation/PTC/Ptc.cs b/src/ARMeilleure/Translation/PTC/Ptc.cs
index 841e5fefa..315efb634 100644
--- a/src/ARMeilleure/Translation/PTC/Ptc.cs
+++ b/src/ARMeilleure/Translation/PTC/Ptc.cs
@@ -1022,6 +1022,7 @@ namespace ARMeilleure.Translation.PTC
             osPlatform |= (OperatingSystem.IsLinux()   ? 1u : 0u) << 1;
             osPlatform |= (OperatingSystem.IsMacOS()   ? 1u : 0u) << 2;
             osPlatform |= (OperatingSystem.IsWindows() ? 1u : 0u) << 3;
+            osPlatform |= (OperatingSystem.IsIOS()     ? 1u : 0u) << 4;
 #pragma warning restore IDE0055
 
             return osPlatform;
diff --git a/src/MeloNX/MeloNX.xcodeproj/project.pbxproj b/src/MeloNX/MeloNX.xcodeproj/project.pbxproj
index 9c95d1966..d291e1153 100644
--- a/src/MeloNX/MeloNX.xcodeproj/project.pbxproj
+++ b/src/MeloNX/MeloNX.xcodeproj/project.pbxproj
@@ -62,7 +62,6 @@
 		4E6715F12CFEEB6E00425F0C /* Exceptions for "MeloNX" folder in "Embed Libraries" phase from "MeloNX" target */ = {
 			isa = PBXFileSystemSynchronizedGroupBuildPhaseMembershipExceptionSet;
 			attributesByRelativePath = {
-				"Dependencies/Dynamic Libraries/Ryujinx.Headless.SDL2.dylib" = (CodeSignOnCopy, );
 				"Dependencies/Dynamic Libraries/libMoltenVK.dylib" = (CodeSignOnCopy, );
 				"Dependencies/Dynamic Libraries/libavcodec.dylib" = (CodeSignOnCopy, );
 				"Dependencies/Dynamic Libraries/libavutil.dylib" = (CodeSignOnCopy, );
@@ -82,7 +81,6 @@
 				"Dependencies/Dynamic Libraries/libavcodec.dylib",
 				"Dependencies/Dynamic Libraries/libavutil.dylib",
 				"Dependencies/Dynamic Libraries/libMoltenVK.dylib",
-				"Dependencies/Dynamic Libraries/Ryujinx.Headless.SDL2.dylib",
 				Dependencies/XCFrameworks/libavcodec.xcframework,
 				Dependencies/XCFrameworks/libavfilter.xcframework,
 				Dependencies/XCFrameworks/libavformat.xcframework,
@@ -579,6 +577,16 @@
 					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
 					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
 					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
 				);
 				MARKETING_VERSION = 1.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.stossy11.MeloNX;
@@ -694,6 +702,16 @@
 					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
 					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
 					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
+					"$(PROJECT_DIR)/MeloNX/Dependencies/Dynamic\\ Libraries",
 				);
 				MARKETING_VERSION = 1.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.stossy11.MeloNX;
diff --git a/src/MeloNX/MeloNX/Core/DetectJIT/utils.h b/src/MeloNX/MeloNX/Core/DetectJIT/utils.h
new file mode 100644
index 000000000..380d18050
--- /dev/null
+++ b/src/MeloNX/MeloNX/Core/DetectJIT/utils.h
@@ -0,0 +1,27 @@
+#if __has_feature(modules)
+@import UIKit;
+@import Foundation;
+#else
+#import "UIKit/UIKit.h"
+#import "Foundation/Foundation.h"
+#endif
+
+#define DISPATCH_ASYNC_START dispatch_async(dispatch_get_main_queue(), ^{
+#define DISPATCH_ASYNC_CLOSE });
+
+#define PT_TRACE_ME 0
+extern int ptrace(int, pid_t, caddr_t, int);
+
+#define CS_DEBUGGED 0x10000000
+extern int csops(
+        pid_t pid, 
+        unsigned int ops,
+        void *useraddr, 
+        size_t usersize
+    );
+
+extern BOOL getEntitlementValue(NSString *key);
+extern BOOL isJITEnabled(void);
+
+#define DLOG(format, ...) ShowAlert(@"DEBUG", [NSString stringWithFormat:@"\n %s [Line %d] \n %@", __PRETTY_FUNCTION__, __LINE__, [NSString stringWithFormat:format, ##__VA_ARGS__]])
+void ShowAlert(NSString* title, NSString* message, _Bool* showok);
diff --git a/src/MeloNX/MeloNX/Core/DetectJIT/utils.m b/src/MeloNX/MeloNX/Core/DetectJIT/utils.m
new file mode 100644
index 000000000..664ad43f1
--- /dev/null
+++ b/src/MeloNX/MeloNX/Core/DetectJIT/utils.m
@@ -0,0 +1,91 @@
+#import "utils.h"
+
+typedef struct __SecTask * SecTaskRef;
+extern CFTypeRef SecTaskCopyValueForEntitlement(
+        SecTaskRef task, 
+        NSString* entitlement, 
+        CFErrorRef  _Nullable *error
+    ) 
+    __attribute__((weak_import));
+
+extern SecTaskRef SecTaskCreateFromSelf(CFAllocatorRef allocator)
+    __attribute__((weak_import));
+
+BOOL getEntitlementValue(NSString *key) 
+{
+    if (SecTaskCreateFromSelf == NULL || SecTaskCopyValueForEntitlement == NULL)
+        return NO;
+    SecTaskRef sec_task = SecTaskCreateFromSelf(NULL);
+    if(!sec_task) return NO;
+    CFTypeRef value = SecTaskCopyValueForEntitlement(sec_task, key, nil);
+    if (value != nil) 
+    {
+        CFRelease(value);
+    }
+    CFRelease(sec_task);
+    return value != nil && [(__bridge id)value boolValue];
+}
+
+BOOL isJITEnabled(void) 
+{
+    if (getEntitlementValue(@"dynamic-codesigning")) 
+    {
+        return YES;
+    }
+    
+    int flags;
+    csops(getpid(), 0, &flags, sizeof(flags));
+    return (flags & CS_DEBUGGED) != 0;
+}
+
+void ShowAlert(NSString* title, NSString* message, _Bool* showok)
+{
+    DISPATCH_ASYNC_START
+        UIWindow* mainWindow = [[UIApplication sharedApplication] windows].lastObject;
+        UIAlertController *alert = [UIAlertController alertControllerWithTitle:title
+                                                                    message:message
+                                                                preferredStyle:UIAlertControllerStyleAlert];
+    if (showok) {
+        [alert addAction:[UIAlertAction actionWithTitle:@"ok!"
+                                                  style:UIAlertActionStyleDefault
+                                                handler:nil]];
+    }
+        [mainWindow.rootViewController presentViewController:alert
+                                                    animated:true
+                                                completion:nil];
+    DISPATCH_ASYNC_CLOSE
+}
+
+#import <UIKit/UIKit.h>
+
+__attribute__((constructor)) static void entry(int argc, char **argv)
+{
+    if (isJITEnabled()) {
+        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+        [defaults setBool:YES forKey:@"JIT"];
+        [defaults synchronize]; // Ensure the value is saved immediately
+    } else {
+        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+        [defaults setBool:NO forKey:@"JIT"];
+        [defaults synchronize]; // Ensure the value is saved immediately
+    }
+    
+    if (getEntitlementValue(@"com.apple.developer.kernel.increased-memory-limit")) {
+        NSLog(@"Entitlement Does Exist");
+        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+        [defaults setBool:YES forKey:@"increased-memory-limit"];
+        [defaults synchronize]; // Ensure the value is saved immediately
+    }
+    
+    if (getEntitlementValue(@"com.apple.developer.kernel.increased-debugging-memory-limit")) {
+        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+        [defaults setBool:YES forKey:@"increased-debugging-memory-limit"];
+        [defaults synchronize]; // Ensure the value is saved immediately
+    }
+    if (getEntitlementValue(@"com.apple.developer.kernel.extended-virtual-addressing")) {
+        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+        [defaults setBool:YES forKey:@"extended-virtual-addressing"];
+        [defaults synchronize]; // Ensure the value is saved immediately
+    }
+        
+}
diff --git a/src/MeloNX/MeloNX/Core/Headers/Ryujinx-Header.h b/src/MeloNX/MeloNX/Core/Headers/Ryujinx-Header.h
index 89a1b6329..12cba91e5 100644
--- a/src/MeloNX/MeloNX/Core/Headers/Ryujinx-Header.h
+++ b/src/MeloNX/MeloNX/Core/Headers/Ryujinx-Header.h
@@ -8,13 +8,29 @@
 #ifndef RyujinxHeader
 #define RyujinxHeader
 
+
+#import "SDL2/SDL.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+struct GameInfo {
+    long FileSize;
+    char TitleName[512];
+    long TitleId;
+    char Developer[256];
+    int Version;
+    unsigned char* ImageData; 
+    unsigned int ImageSize;
+};
+
+// extern struct GameInfo get_game_info(int, char*);
 // Declare the main_ryujinx_sdl function, matching the signature
 int main_ryujinx_sdl(int argc, char **argv);
 
+// void initialize();
+
 const char* get_game_controllers();
 
 #ifdef __cplusplus
diff --git a/src/MeloNX/MeloNX/Core/MetalHUD/MTLHUD.swift b/src/MeloNX/MeloNX/Core/MetalHUD/MTLHUD.swift
index d8bc92770..e89e9f6f4 100644
--- a/src/MeloNX/MeloNX/Core/MetalHUD/MTLHUD.swift
+++ b/src/MeloNX/MeloNX/Core/MetalHUD/MTLHUD.swift
@@ -7,6 +7,7 @@
 
 import Foundation
 
+
 class MTLHud {
     
     var canMetalHud: Bool {
diff --git a/src/MeloNX/MeloNX/Core/Swift/Controller/VirtualController.swift b/src/MeloNX/MeloNX/Core/Swift/Controller/VirtualController.swift
index e55b51eab..11415e6d0 100644
--- a/src/MeloNX/MeloNX/Core/Swift/Controller/VirtualController.swift
+++ b/src/MeloNX/MeloNX/Core/Swift/Controller/VirtualController.swift
@@ -2,98 +2,188 @@
 //  VirtualController.swift
 //  MeloNX
 //
-//  Created by Stossy11 on 28/11/2024.
+//  Created by Stossy11 on 8/12/2024.
 //
 
 import Foundation
-import GameController
+import CoreHaptics
 import UIKit
 
-public var controllerCallback: (() -> Void)?
-
-var VirtualController: GCVirtualController!
-func showVirtualController() {
-    let config = GCVirtualController.Configuration()
-    if UserDefaults.standard.bool(forKey: "RyuDemoControls") {
-        config.elements = [
-            GCInputLeftThumbstick,
-            GCInputButtonA,
-            GCInputButtonB,
-            GCInputButtonX,
-            GCInputButtonY,
-            // GCInputRightThumbstick,
-            GCInputRightTrigger,
-            GCInputLeftTrigger,
-            GCInputLeftShoulder,
-            GCInputRightShoulder
-        ]
-    } else {
-        config.elements = [
-            GCInputLeftThumbstick,
-            GCInputButtonA,
-            GCInputButtonB,
-            GCInputButtonX,
-            GCInputButtonY,
-            GCInputRightThumbstick,
-            GCInputRightTrigger,
-            GCInputLeftTrigger,
-            GCInputLeftShoulder,
-            GCInputRightShoulder
-        ]
+class VirtualController {
+    private var instanceID: SDL_JoystickID = -1
+    private var controller: OpaquePointer?
+    
+    public let controllername = "MeloNX Touch Controller"
+    
+    init() {
+        setupVirtualController()
     }
-    VirtualController = GCVirtualController(configuration: config)
-    VirtualController.connect { err in
-        print("controller connect: \(String(describing: err))")
-        patchMakeKeyAndVisible()
-        if let controllerCallback {
-            controllerCallback()
+    
+    private func setupVirtualController() {
+        // Initialize SDL if not already initialized
+        if SDL_WasInit(Uint32(SDL_INIT_GAMECONTROLLER)) == 0 {
+            SDL_InitSubSystem(Uint32(SDL_INIT_GAMECONTROLLER))
         }
-    }
-}
-
-func waitforcontroller() {
-    Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in
         
-        if let window = UIApplication.shared.windows.first {
-            // Function to recursively search for GCControllerView
-            func findGCControllerView(in view: UIView) -> UIView? {
-                // Check if current view is GCControllerView
-                if String(describing: type(of: view)) == "GCControllerView" {
-                    return view
+        // Create virtual controller
+        var joystickDesc = SDL_VirtualJoystickDesc(
+            version: UInt16(SDL_VIRTUAL_JOYSTICK_DESC_VERSION),
+            type: Uint16(SDL_JOYSTICK_TYPE_GAMECONTROLLER.rawValue),
+                naxes: 6,
+                nbuttons: 15,
+                nhats: 1,
+                vendor_id: 0,
+                product_id: 0,
+                padding: 0,
+                button_mask: 0,
+                axis_mask: 0,
+                name: controllername.withCString { $0 },
+                userdata: nil,
+                Update: { userdata in
+                    // Update joystick state here
+                },
+                SetPlayerIndex: { userdata, playerIndex in
+                    print("Player index set to \(playerIndex)")
+                },
+                Rumble: { userdata, lowFreq, highFreq in
+                    print("Rumble with \(lowFreq), \(highFreq)")
+                    VirtualController.rumble(lowFreq: Float(lowFreq), highFreq: Float(highFreq))
+                    return 0
+                },
+                RumbleTriggers: { userdata, leftRumble, rightRumble in
+                    print("Trigger rumble with \(leftRumble), \(rightRumble)")
+                    return 0
+                },
+                SetLED: { userdata, red, green, blue in
+                    print("Set LED to RGB(\(red), \(green), \(blue))")
+                    return 0
+                },
+                SendEffect: { userdata, data, size in
+                    print("Effect sent with size \(size)")
+                    return 0
                 }
-                
-                // Search through subviews
-                for subview in view.subviews {
-                    if let found = findGCControllerView(in: subview) {
-                        return found
-                    }
-                }
-                
-                return nil
-            }
-            
-            if let gcControllerView = findGCControllerView(in: window) {
-                // Found the GCControllerView
-                print("Found GCControllerView:", gcControllerView)
-                
-                if let theWindow = theWindow, (findGCControllerView(in: theWindow) == nil) {
-                    theWindow.addSubview(gcControllerView)
-                    
-                    theWindow.bringSubviewToFront(gcControllerView)
-                }
-            }
+            )
+        
+        instanceID = SDL_JoystickAttachVirtualEx(&joystickDesc)// SDL_JoystickAttachVirtual(SDL_JoystickType(SDL_JOYSTICK_TYPE_GAMECONTROLLER.rawValue), 6, 15, 1)
+        if instanceID < 0 {
+            print("Failed to create virtual joystick: \(String(cString: SDL_GetError()))")
+            return
         }
+        
+        // Open a game controller for the virtual joystick
+        let joystick = SDL_JoystickFromInstanceID(instanceID)
+        controller = SDL_GameControllerOpen(Int32(instanceID))
+        
+        if controller == nil {
+            print("Failed to create virtual controller: \(String(cString: SDL_GetError()))")
+            return
+        }
+    }
+    
+    static func rumble(lowFreq: Float, highFreq: Float) {
+        do {
+            // Low-frequency haptic pattern
+            let lowFreqPattern = try CHHapticPattern(events: [
+                CHHapticEvent(eventType: .hapticTransient, parameters: [
+                    CHHapticEventParameter(parameterID: .hapticIntensity, value: lowFreq),
+                    CHHapticEventParameter(parameterID: .hapticSharpness, value: 0.5)
+                ], relativeTime: 0, duration: 0.2)
+            ], parameters: [])
+
+            // High-frequency haptic pattern
+            let highFreqPattern = try CHHapticPattern(events: [
+                CHHapticEvent(eventType: .hapticTransient, parameters: [
+                    CHHapticEventParameter(parameterID: .hapticIntensity, value: highFreq),
+                    CHHapticEventParameter(parameterID: .hapticSharpness, value: 1.0)
+                ], relativeTime: 0.2, duration: 0.2)
+            ], parameters: [])
+
+            // Create and start the haptic engine
+            let engine = try CHHapticEngine()
+            try engine.start()
+
+            // Create and play the low-frequency player
+            let lowFreqPlayer = try engine.makePlayer(with: lowFreqPattern)
+            try lowFreqPlayer.start(atTime: 0)
+
+            // Create and play the high-frequency player after a short delay
+            let highFreqPlayer = try engine.makePlayer(with: highFreqPattern)
+            try highFreqPlayer.start(atTime: 0.2)
+
+        } catch {
+            print("Error creating haptic patterns: \(error)")
+        }
+    }
+
+    
+    func updateAxisValue(value: Sint16, forAxis axis: SDL_GameControllerAxis) {
+        guard controller != nil else { return }
+        let joystick = SDL_JoystickFromInstanceID(instanceID)
+        SDL_JoystickSetVirtualAxis(joystick, axis.rawValue, value)
+    }
+    
+    func thumbstickMoved(_ stick: ThumbstickType, x: Double, y: Double) {
+        let scaleFactor = 32767.0 / 160
+
+        let scaledX = Int16(min(32767.0, max(-32768.0, x * scaleFactor)))
+        let scaledY = Int16(min(32767.0, max(-32768.0, y * scaleFactor)))
+        
+        if stick == .right {
+            updateAxisValue(value: scaledX, forAxis: SDL_GameControllerAxis(SDL_CONTROLLER_AXIS_RIGHTX.rawValue))
+            updateAxisValue(value: scaledY, forAxis: SDL_GameControllerAxis(SDL_CONTROLLER_AXIS_RIGHTY.rawValue))
+        } else {  // ThumbstickType.left
+            updateAxisValue(value: scaledX, forAxis: SDL_GameControllerAxis(SDL_CONTROLLER_AXIS_LEFTX.rawValue))
+            updateAxisValue(value: scaledY, forAxis: SDL_GameControllerAxis(SDL_CONTROLLER_AXIS_LEFTY.rawValue))
+        }
+    }
+    
+    func setButtonState(_ state: Uint8, for button: VirtualControllerButton) {
+        guard controller != nil else { return }
+        
+        print("Button: \(button.rawValue) {state: \(state)}")
+        if (button == .leftTrigger || button == .rightTrigger) && (state == 1 || state == 0) {
+            let axis: SDL_GameControllerAxis = (button == .leftTrigger) ? SDL_CONTROLLER_AXIS_TRIGGERLEFT : SDL_CONTROLLER_AXIS_TRIGGERRIGHT
+            let value: Int = (state == 1) ? 32767 : 0
+            updateAxisValue(value: Sint16(value), forAxis: axis)
+        } else {
+            let joystick = SDL_JoystickFromInstanceID(instanceID)
+            SDL_JoystickSetVirtualButton(joystick, Int32(button.rawValue), state)
+        }
+    }
+    
+    func cleanup() {
+        if let controller = controller {
+            SDL_GameControllerClose(controller)
+            self.controller = nil
+        }
+    }
+    
+    deinit {
+        cleanup()
     }
 }
 
-@available(iOS 15.0, *)
-func reconnectVirtualController() {
-    VirtualController.disconnect()
-    DispatchQueue.main.async {
-        VirtualController.connect { err in
-            print("reconnected: err \(String(describing: err))")
-        }
-    }
+enum VirtualControllerButton: Int {
+    case B
+    case A
+    case Y
+    case X
+    case back
+    case guide
+    case start
+    case leftStick
+    case rightStick
+    case leftShoulder
+    case rightShoulder
+    case dPadUp
+    case dPadDown
+    case dPadLeft
+    case dPadRight
+    case leftTrigger
+    case rightTrigger
 }
 
-
+enum ThumbstickType: Int {
+    case left
+    case right
+}
diff --git a/src/MeloNX/MeloNX/Core/Swift/Controller/WaitforVC.swift b/src/MeloNX/MeloNX/Core/Swift/Controller/WaitforVC.swift
new file mode 100644
index 000000000..43cf638f7
--- /dev/null
+++ b/src/MeloNX/MeloNX/Core/Swift/Controller/WaitforVC.swift
@@ -0,0 +1,65 @@
+//
+//  VirtualController.swift
+//  MeloNX
+//
+//  Created by Stossy11 on 28/11/2024.
+//
+
+import Foundation
+import GameController
+import UIKit
+import SwiftUI
+
+func waitforcontroller() {
+    if let window = theWindow {
+        
+        
+        
+        // Function to recursively search for GCControllerView
+        func findGCControllerView(in view: UIView) -> UIView? {
+            // Check if current view is GCControllerView
+            if String(describing: type(of: view)) == "ControllerView" {
+                return view
+            }
+            
+            // Search through subviews
+            for subview in view.subviews {
+                if let found = findGCControllerView(in: subview) {
+                    return found
+                }
+            }
+            
+            return nil
+        }
+        
+        let controllerView = ControllerView()
+        let controllerHostingController = UIHostingController(rootView: controllerView)
+        let containerView = TransparentHostingContainerView(frame: window.bounds)
+        containerView.backgroundColor = .clear
+
+        controllerHostingController.view.frame = containerView.bounds
+        controllerHostingController.view.backgroundColor = .clear
+        containerView.addSubview(controllerHostingController.view)
+
+        Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { timer in
+            if findGCControllerView(in: window) == nil {
+                window.addSubview(containerView)
+                
+            }
+            
+            window.bringSubviewToFront(containerView)
+        }
+
+    }
+}
+
+
+class TransparentHostingContainerView: UIView {
+    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
+        // Check if the point is within the subviews of this container
+        let view = super.hitTest(point, with: event)
+        
+        // Return nil if the touch is outside visible content (passes through to views below)
+        return view === self ? nil : view
+    }
+}
diff --git a/src/MeloNX/MeloNX/Core/Swift/Display/DisplayVisible.swift b/src/MeloNX/MeloNX/Core/Swift/Display/DisplayVisible.swift
index ef423ef42..6f1f9242f 100644
--- a/src/MeloNX/MeloNX/Core/Swift/Display/DisplayVisible.swift
+++ b/src/MeloNX/MeloNX/Core/Swift/Display/DisplayVisible.swift
@@ -19,13 +19,26 @@ extension UIWindow {
         }
         self.wdb_makeKeyAndVisible()
         theWindow = self
-        if #available(iOS 15.0, *) {
-            reconnectVirtualController()
-        }
         
         
-        if let window = theWindow {
-            waitforcontroller()
+        if UserDefaults.standard.bool(forKey: "isVirtualController") {
+            if let window = theWindow {
+                
+                class LandscapeViewController: UIViewController {
+                    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
+                        return .landscape
+                    }
+
+                    override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
+                        return .landscapeLeft
+                    }
+                }
+
+                let landscapeVC = LandscapeViewController()
+                landscapeVC.modalPresentationStyle = .fullScreen
+                theWindow?.rootViewController?.present(landscapeVC, animated: false, completion: nil)
+                waitforcontroller()
+            }
         }
     }
 }
@@ -38,3 +51,4 @@ func patchMakeKeyAndVisible() {
         method_exchangeImplementations(m1, m2)
     }
 }
+
diff --git a/src/MeloNX/MeloNX/Core/Swift/Ryujinx.swift b/src/MeloNX/MeloNX/Core/Swift/Ryujinx.swift
index 83fa39b3b..3b2574579 100644
--- a/src/MeloNX/MeloNX/Core/Swift/Ryujinx.swift
+++ b/src/MeloNX/MeloNX/Core/Swift/Ryujinx.swift
@@ -7,7 +7,6 @@
 
 import Foundation
 import SwiftUI
-import SDL2
 import GameController
 
 struct Controller: Identifiable, Hashable {
@@ -32,13 +31,15 @@ struct iOSNav<Content: View>: View {
 class Ryujinx {
     private var isRunning = false
     
+    let virtualController = VirtualController()
+    
     @Published var controllerMap: [Controller] = []
     
     static let shared = Ryujinx()
     
     private init() {}
     
-    public struct Configuration : Codable {
+    public struct Configuration : Codable, Equatable {
         var gamepath: String
         var inputids: [String]
         var resscale: Float
@@ -49,7 +50,6 @@ class Ryujinx {
         var listinputids: Bool
         var fullscreen: Bool
         var memoryManagerMode: String
-        var disableVSync: Bool
         var disableShaderCache: Bool
         var disableDockedMode: Bool
         var enableTextureRecompression: Bool
@@ -63,7 +63,6 @@ class Ryujinx {
              listinputids: Bool = false,
              fullscreen: Bool = true,
              memoryManagerMode: String = "HostMapped",
-             disableVSync: Bool = false,
              disableShaderCache: Bool = false,
              disableDockedMode: Bool = false,
              nintendoinput: Bool = true,
@@ -78,7 +77,6 @@ class Ryujinx {
             self.tracelogs = tracelogs
             self.listinputids = listinputids
             self.fullscreen = fullscreen
-            self.disableVSync = disableVSync
             self.disableShaderCache = disableShaderCache
             self.disableDockedMode = disableDockedMode
             self.enableTextureRecompression = enableTextureRecompression
@@ -99,7 +97,7 @@ class Ryujinx {
         isRunning = true
         
         // Start The Emulation on the main thread
-        DispatchQueue.main.async {
+        RunLoop.current.perform {
             do {
                 let args = self.buildCommandLineArgs(from: config)
                 
@@ -145,29 +143,25 @@ class Ryujinx {
         args.append("--graphics-backend")
         args.append("Vulkan")
         
-        // Fixes the Stubs.DispatchLoop Crash
-        args.append(contentsOf: ["--memory-manager-mode", config.memoryManagerMode])
-        if config.fullscreen {
-            args.append(contentsOf: ["--exclusive-fullscreen", String(config.fullscreen)])
-            args.append(contentsOf: ["--exclusive-fullscreen-width", "1280"])
-            args.append(contentsOf: ["--exclusive-fullscreen-height", "720"])
+        args.append(contentsOf: ["--memory-manager-mode", "SoftwarePageTable"])
+        
+        args.append(contentsOf: ["--exclusive-fullscreen", String(config.fullscreen)])
+        args.append(contentsOf: ["--exclusive-fullscreen-width", "\(Int(UIScreen.main.bounds.width))"])
+        args.append(contentsOf: ["--exclusive-fullscreen-height", "\(Int(UIScreen.main.bounds.height))"])
+        
+        
+        if config.nintendoinput {
+            // args.append("--correct-controller")
         }
         
-        if config.resscale != 1 {
+        
+        //args.append("--disable-vsync")
+        
+        
+        if config.resscale != 1.0 {
             args.append(contentsOf: ["--resolution-scale", String(config.resscale)])
         }
         
-        if config.nintendoinput {
-            // args.append("--correct-ons-controller")
-        }
-        if config.enableInternet {
-            args.append("--enable-internet-connection")
-        }
-        
-        // Adding default args directly into additionalArgs
-        if config.disableVSync {
-            // args.append("--disable-vsync")
-        }
         if config.disableShaderCache {
             args.append("--disable-shader-cache")
         }
@@ -204,9 +198,9 @@ class Ryujinx {
     }
     
     func getConnectedControllers() -> [Controller] {
-        var nill: String?
+        
 
-        guard let jsonPtr = nill else {//get_game_controllers() else {
+        guard let jsonPtr = get_game_controllers() else {
             return []
         }
         
diff --git a/src/MeloNX/MeloNX/Dependencies/Dynamic Libraries/libMoltenVK.dylib b/src/MeloNX/MeloNX/Dependencies/Dynamic Libraries/libMoltenVK.dylib
index 3253ff11f..7e3092cd5 100755
Binary files a/src/MeloNX/MeloNX/Dependencies/Dynamic Libraries/libMoltenVK.dylib and b/src/MeloNX/MeloNX/Dependencies/Dynamic Libraries/libMoltenVK.dylib differ
diff --git a/src/MeloNX/MeloNX/Dependencies/XCFrameworks/MoltenVK.xcframework/ios-arm64/MoltenVK.framework/MoltenVK b/src/MeloNX/MeloNX/Dependencies/XCFrameworks/MoltenVK.xcframework/ios-arm64/MoltenVK.framework/MoltenVK
index 3253ff11f..7e3092cd5 100755
Binary files a/src/MeloNX/MeloNX/Dependencies/XCFrameworks/MoltenVK.xcframework/ios-arm64/MoltenVK.framework/MoltenVK and b/src/MeloNX/MeloNX/Dependencies/XCFrameworks/MoltenVK.xcframework/ios-arm64/MoltenVK.framework/MoltenVK differ
diff --git a/src/MeloNX/MeloNX/Info.plist b/src/MeloNX/MeloNX/Info.plist
index ff579a6ca..8cc8fe67f 100644
--- a/src/MeloNX/MeloNX/Info.plist
+++ b/src/MeloNX/MeloNX/Info.plist
@@ -2,6 +2,8 @@
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 <plist version="1.0">
 <dict>
+	<key>MeloID</key>
+	<string></string>
 	<key>UIFileSharingEnabled</key>
 	<true/>
 </dict>
diff --git a/src/MeloNX/MeloNX/MeloNXApp.swift b/src/MeloNX/MeloNX/MeloNXApp.swift
index e14f820e7..d60a27413 100644
--- a/src/MeloNX/MeloNX/MeloNXApp.swift
+++ b/src/MeloNX/MeloNX/MeloNXApp.swift
@@ -6,12 +6,118 @@
 //
 
 import SwiftUI
+import UIKit
 
 @main
 struct MeloNXApp: App {
+    
+    @AppStorage("showeddrmcheck") var showed = true
+    
+    init() {
+        DispatchQueue.main.async { [self] in
+            // drmcheck()
+            if showed {
+                drmcheck() { bool in
+                    if bool {
+                        print("Yippee")
+                    } else {
+                       //  exit(0)
+                    }
+                }
+            } else {
+                showAlert()
+            }
+        }
+    }
+    
     var body: some Scene {
         WindowGroup {
-            ContentView()
+            if showed {
+                ContentView()
+            } else {
+                HStack {
+                    Text("Loading...")
+                    ProgressView()
+                }
+            }
+        }
+    }
+    
+    func showAlert() {
+        // Create the alert controller
+        if let mainWindow = UIApplication.shared.windows.last {
+            let alertController = UIAlertController(title: "Enter license", message: "Enter license key:", preferredStyle: .alert)
+            
+            // Add a text field to the alert
+            alertController.addTextField { textField in
+                textField.placeholder = "Enter key here"
+            }
+            
+            // Add the "OK" action
+            let okAction = UIAlertAction(title: "OK", style: .default) { _ in
+                // Get the text entered in the text field
+                if let textField = alertController.textFields?.first, let enteredText = textField.text {
+                    print("Entered text: \(enteredText)")
+                    UserDefaults.standard.set(enteredText, forKey: "MeloDRMID")
+                    drmcheck() { bool in
+                        if bool {
+                            showed = true
+                        } else {
+                            exit(0)
+                        }
+                    }
+                }
+            }
+            alertController.addAction(okAction)
+            
+            // Add a "Cancel" action
+            let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
+            alertController.addAction(cancelAction)
+            
+            // Present the alert
+            mainWindow.rootViewController!.present(alertController, animated: true, completion: nil)
+        } else {
+            exit(0)
         }
     }
 }
+
+
+func drmcheck(completion: @escaping (Bool) -> Void) {
+    if let deviceid = UIDevice.current.identifierForVendor?.uuidString, let base64device = deviceid.data(using: .utf8)?.base64EncodedString() {
+        if let value = UserDefaults.standard.string(forKey: "MeloDRMID") {
+            if let url = URL(string: "https://mx.stossy11.com/auth/\(value)/\(base64device)") {
+                print(url)
+                // Create a URLSession
+                let session = URLSession.shared
+                
+                // Create a data task
+                let task = session.dataTask(with: url) { data, response, error in
+                    // Handle errors
+                    if let error = error {
+                        exit(0)
+                    }
+                    
+                    // Check response and data
+                    if let response = response as? HTTPURLResponse, response.statusCode == 200 {
+                        print("Successfully Recieved API Data")
+                        completion(true)
+                    } else if let response = response as? HTTPURLResponse, response.statusCode == 201 {
+                        print("Successfully Created Auth UUID")
+                        completion(true)
+                    } else {
+                        completion(false)
+                    }
+                }
+                
+                // Start the task
+                task.resume()
+            }
+        } else {
+            completion(false)
+        }
+    } else {
+        completion(false)
+    }
+    
+}
diff --git a/src/MeloNX/MeloNX/Models/Game.swift b/src/MeloNX/MeloNX/Models/Game.swift
new file mode 100644
index 000000000..cc11c5aa5
--- /dev/null
+++ b/src/MeloNX/MeloNX/Models/Game.swift
@@ -0,0 +1,45 @@
+//
+//  GameInfo.swift
+//  MeloNX
+//
+//  Created by Stossy11 on 9/12/2024.
+//
+
+import SwiftUI
+import UniformTypeIdentifiers
+
+public struct Game: Identifiable, Equatable {
+    public var id = UUID()
+
+    var containerFolder: URL
+    var fileType: UTType
+    
+    var fileURL: URL
+
+    var titleName: String
+    var titleId: String
+    var developer: String
+    var version: String
+    var icon: UIImage?
+    
+    func createImage(from gameInfo: GameInfo) -> UIImage? {
+        // Access the struct
+        let gameInfoValue = gameInfo
+
+        // Get the image data
+        let imageSize = Int(gameInfoValue.ImageSize)
+        guard imageSize > 0, imageSize <= 1024 * 1024 else {
+            print("Invalid image size.")
+            return nil
+        }
+
+        // Convert the ImageData byte array to Swift's Data
+        let imageData = Data(bytes: gameInfoValue.ImageData, count: imageSize)
+
+        // Create a UIImage (or NSImage on macOS)
+        
+        print(imageData)
+        
+        return UIImage(data: imageData)
+    }
+}
diff --git a/src/MeloNX/MeloNX/Views/ContentView.swift b/src/MeloNX/MeloNX/Views/ContentView.swift
index ff163bbf1..d6280c9ea 100644
--- a/src/MeloNX/MeloNX/Views/ContentView.swift
+++ b/src/MeloNX/MeloNX/Views/ContentView.swift
@@ -6,13 +6,16 @@
 //
 
 import SwiftUI
-import SDL2
+// import SDL2
 import GameController
+import Darwin
+import UIKit
+import MetalKit
+// import SDL
 
 struct MoltenVKSettings: Codable, Hashable {
     let string: String
-    var bool: Bool?
-    var value: String?
+    var value: String
 }
 
 struct ContentView: View {
@@ -25,38 +28,36 @@ struct ContentView: View {
     @State private var config: Ryujinx.Configuration
     @State private var settings: [MoltenVKSettings]
     @State private var isVirtualControllerActive: Bool = false
+    @AppStorage("isVirtualController") var isVCA: Bool = true
     @State var onscreencontroller: Controller = Controller(id: "", name: "")
+    @AppStorage("JIT") var isJITEnabled: Bool = false
     
     // MARK: - Initialization
     init() {
-        let defaultConfig = Ryujinx.Configuration(gamepath: "")
+        let defaultConfig = loadSettings() ?? Ryujinx.Configuration(gamepath: "")
         _config = State(initialValue: defaultConfig)
         
         let defaultSettings: [MoltenVKSettings] = [
-            MoltenVKSettings(string: "MVK_CONFIG_MAX_ACTIVE_METAL_COMMAND_BUFFERS_PER_QUEUE", value: "1024"),
-            MoltenVKSettings(string: "MVK_CONFIG_USE_METAL_ARGUMENT_BUFFERS", value: "1"),
-            MoltenVKSettings(string: "MVK_CONFIG_RESUME_LOST_DEVICE", value: "1")
+            MoltenVKSettings(string: "MVK_CONFIG_MAX_ACTIVE_METAL_COMMAND_BUFFERS_PER_QUEUE", value: "192"),
+            MoltenVKSettings(string: "MVK_CONFIG_PREFILL_METAL_COMMAND_BUFFERS", value: "2"),
+            MoltenVKSettings(string: "MVK_USE_METAL_PRIVATE_API", value: "1"),
+            MoltenVKSettings(string: "MVK_CONFIG_RESUME_LOST_DEVICE", value: "1"),
+            MoltenVKSettings(string: "MVK_CONFIG_USE_METAL_PRIVATE_API", value: "1")
         ]
+        
         _settings = State(initialValue: defaultSettings)
         
+        print("JIT Enabled: \(isJITEnabled)")
+        
         initializeSDL()
     }
     
     // MARK: - Body
     var body: some View {
-        iOSNav {
-            if let game {
-                emulationView
-            } else {
-                mainMenuView
-            }
-        }
-        .onChange(of: isVirtualControllerActive) { newValue in
-            if newValue {
-                createVirtualController()
-            } else {
-                destroyVirtualController()
-            }
+        if let game {
+            emulationView
+        } else {
+            mainMenuView
         }
     }
     
@@ -69,138 +70,93 @@ struct ContentView: View {
     }
     
     private var mainMenuView: some View {
-        HStack {
-            GameListView(startemu: $game)
-                .onAppear {
-                    createVirtualController()
-                    refreshControllersList()
-                }
-            
-            settingsListView
-        }
-    }
-    
-    private var settingsListView: some View {
-        List {
-            Section("Settings") {
-                NavigationLink("Config") {
-                    SettingsView(config: $config, MoltenVKSettings: $settings)
-                        .onAppear() {
-                            virtualController?.disconnect()
-                        }
-                }
+        MainTabView(startemu: $game, config: $config, MVKconfig: $settings, controllersList: $controllersList, currentControllers: $currentControllers, onscreencontroller: $onscreencontroller)
+            .onAppear() {
+                refreshControllersList()
             }
-            
-            Section("Controller") {
-                Button("Refresh", action: refreshControllersList)
-                Divider()
-                ForEach(controllersList, id: \.self) { controller in
-                    controllerRow(for: controller)
-                }
-            }
-        }
-    }
-    
-    private func controllerRow(for controller: Controller) -> some View {
-        HStack {
-            Button(controller.name) {
-                toggleController(controller)
-            }
-            Spacer()
-            if currentControllers.contains(where: { $0.id == controller.id }) {
-                Image(systemName: "checkmark.circle.fill")
-            }
-        }
-    }
-    
-    // MARK: - Controller Management
-    private func createVirtualController() {
-        let configuration = GCVirtualController.Configuration()
-        configuration.elements = [
-            /*
-            GCInputLeftThumbstick,
-            GCInputRightThumbstick,
-            GCInputButtonA,
-            GCInputButtonB,
-            GCInputButtonX,
-            GCInputButtonY,
-             */
-        ]
-        
-        virtualController = GCVirtualController(configuration: configuration)
-        virtualController?.connect()
-        
-    }
-    
-    private func destroyVirtualController() {
-        virtualController?.disconnect()
-        virtualController = nil
     }
     
     // MARK: - Helper Methods
+    var SdlInitFlags: uint = SDL_INIT_EVENTS | SDL_INIT_GAMECONTROLLER | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO | SDL_INIT_VIDEO;
     private func initializeSDL() {
-        DispatchQueue.main.async {
-            setMoltenVKSettings()
-            SDL_SetMainReady()
-            SDL_iPhoneSetEventPump(SDL_TRUE)
-            SDL_Init(SDL_INIT_VIDEO)
-        }
+        setMoltenVKSettings()
+        SDL_SetMainReady()
+        SDL_iPhoneSetEventPump(SDL_TRUE)
+        SDL_Init(SdlInitFlags)
+        // initialize()
     }
     
     private func setupEmulation() {
         virtualController?.disconnect()
+        patchMakeKeyAndVisible()
         
-        if controllersList.first(where: { $0 == onscreencontroller}) != nil {
-            controllerCallback = {
-                DispatchQueue.main.async {
-                    controllersList = Ryujinx.shared.getConnectedControllers()
-                    
-                    print(currentControllers)
-                    start(displayid: 1)
-                }
-            }
+        if (currentControllers.first(where: { $0 == onscreencontroller }) != nil) {
             
-            
-            showVirtualController()
-        } else {
+            isVCA = true
             
             DispatchQueue.main.async {
-                print(currentControllers)
                 start(displayid: 1)
             }
+            
+            
+        } else {
+            isVCA = false
+            
+            DispatchQueue.main.async {
+                start(displayid: 1)
+            }
+            
+            
         }
     }
     
     private func refreshControllersList() {
-        Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false) { _ in
-            controllersList = Ryujinx.shared.getConnectedControllers()
-            var controller = controllersList.first(where: { $0.name.hasPrefix("Apple")})
-            self.onscreencontroller = (controller ?? Controller(id: "", name: ""))
-            if controllersList.count > 2 {
-                let controller = controllersList[2]
-                currentControllers.append(controller)
-                
-            } else if let controller = controllersList.first(where: { $0.id == onscreencontroller.id }), !controllersList.isEmpty {
-                currentControllers.append(controller)
-            }
+        
+        
+        if let onscreen = controllersList.first(where: { $0.name == Ryujinx.shared.virtualController.controllername }) {
+            self.onscreencontroller = onscreen
         }
-    }
-    
-    private func toggleController(_ controller: Controller) {
-        if currentControllers.contains(where: { $0.id == controller.id }) {
-            currentControllers.removeAll(where: { $0.id == controller.id })
-        } else {
+        
+        controllersList.removeAll(where: { $0.id == "0"})
+        
+        if controllersList.count > 2 {
+            let controller =  controllersList[2]
+            currentControllers.append(controller)
+        } else if let controller = controllersList.first(where: { $0.id == onscreencontroller.id }), !controllersList.isEmpty {
             currentControllers.append(controller)
         }
     }
+
+    func showAlert(title: String, message: String, showOk: Bool, completion: @escaping (Bool) -> Void) {
+        DispatchQueue.main.async {
+            if let mainWindow = UIApplication.shared.windows.last {
+                let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
+                
+                if showOk {
+                    let okAction = UIAlertAction(title: "OK", style: .default) { _ in
+                        completion(true)
+                    }
+
+                    alert.addAction(okAction)
+                } else {
+                    completion(false)
+                }
+                
+                mainWindow.rootViewController?.present(alert, animated: true, completion: nil)
+            }
+        }
+    }
+
     
     private func start(displayid: UInt32) {
         guard let game else { return }
         
         config.gamepath = game.path
-        config.inputids = currentControllers.map(\.id)
+        config.inputids = Array(Set(currentControllers.map(\.id)))
         
-        allocateMemory()
+        if config.inputids.isEmpty {
+            config.inputids.append("0")
+        }
         
         do {
             try Ryujinx.shared.start(with: config)
@@ -208,22 +164,9 @@ struct ContentView: View {
             print("Error: \(error.localizedDescription)")
         }
     }
-    
-    private func allocateMemory() {
-        let physicalMemory = ProcessInfo.processInfo.physicalMemory
-        let totalMemoryInGB = Double(physicalMemory) / (1024 * 1024 * 1024)
-        
-        let pointer = UnsafeMutableRawPointer.allocate(
-            byteCount: Int(totalMemoryInGB),
-            alignment: MemoryLayout<UInt8>.alignment
-        )
-        pointer.initializeMemory(as: UInt8.self, repeating: 0, count: Int(totalMemoryInGB))
-    }
+
     
     private func setMoltenVKSettings() {
-        if let configs = loadSettings() {
-            self.config = configs
-        }
         
         settings.forEach { setting in
             setenv(setting.string, setting.value, 1)
@@ -245,3 +188,4 @@ func loadSettings() -> Ryujinx.Configuration? {
         return nil
     }
 }
+
diff --git a/src/MeloNX/MeloNX/Views/ControllerView/ControllerView.swift b/src/MeloNX/MeloNX/Views/ControllerView/ControllerView.swift
new file mode 100644
index 000000000..03159c90d
--- /dev/null
+++ b/src/MeloNX/MeloNX/Views/ControllerView/ControllerView.swift
@@ -0,0 +1,268 @@
+//
+//  ControllerView.swift
+//  Pomelo-V2
+//
+//  Created by Stossy11 on 16/7/2024.
+//
+
+import SwiftUI
+import GameController
+import SwiftUIJoystick
+import CoreMotion
+
+struct ControllerView: View {
+    var body: some View {
+        GeometryReader { geometry in
+            if geometry.size.height > geometry.size.width && UIDevice.current.userInterfaceIdiom != .pad {
+                VStack {
+                    Spacer()
+                    VStack {
+                        HStack {
+                            VStack {
+                                ShoulderButtonsViewLeft()
+                                ZStack {
+                                    Joystick()
+                                    DPadView()
+                                }
+                            }
+                            .padding()
+                            VStack {
+                                ShoulderButtonsViewRight()
+                                ZStack {
+                                    Joystick(iscool: true) // hope this works
+                                    ABXYView()
+                                }
+                            }
+                            .padding()
+                        }
+                        
+                        HStack {
+                            ButtonView(button: .start) // Adding the + button
+                                .padding(.horizontal, 40)
+                            ButtonView(button: .back) // Adding the - button
+                                .padding(.horizontal, 40)
+                        }
+                    }
+                    .padding(.bottom, geometry.size.height / 3.2) // very broken
+                }
+            } else {
+                // could be landscape
+                VStack {
+                    Spacer()
+                    VStack {
+                        HStack {
+                            
+                            // gotta fuckin add + and - now
+                            VStack {
+                                ShoulderButtonsViewLeft()
+                                ZStack {
+                                    Joystick()
+                                    DPadView()
+                                }
+                            }
+                            HStack {
+                                // Spacer()
+                                VStack {
+                                    // Spacer()
+                                    ButtonView(button: .back) // Adding the + button
+                                }
+                                Spacer()
+                                VStack {
+                                    // Spacer()
+                                    ButtonView(button: .start) // Adding the - button
+                                }
+                                // Spacer()
+                            }
+                            VStack {
+                                ShoulderButtonsViewRight()
+                                ZStack {
+                                    Joystick(iscool: true) // hope this work s
+                                    ABXYView()
+                                }
+                            }
+                        }
+                        
+                    }
+                    // .padding(.bottom, geometry.size.height / 11) // also extremally broken (
+                }
+            }
+        }
+        .padding()
+    }
+}
+
+struct ShoulderButtonsViewLeft: View {
+    @State var width: CGFloat = 160
+    @State var height: CGFloat = 20
+    var body: some View {
+        HStack {
+            ButtonView(button: .leftTrigger)
+                .padding(.horizontal)
+            ButtonView(button: .leftShoulder)
+                .padding(.horizontal)
+        }
+        .frame(width: width, height: height)
+        .onAppear() {
+            if UIDevice.current.systemName.contains("iPadOS") {
+                width *= 1.2
+                height *= 1.2
+            }
+        }
+    }
+}
+
+struct ShoulderButtonsViewRight: View {
+    @State var width: CGFloat = 160
+    @State var height: CGFloat = 20
+    var body: some View {
+        HStack {
+            ButtonView(button: .rightShoulder)
+                .padding(.horizontal)
+            ButtonView(button: .rightTrigger)
+                .padding(.horizontal)
+        }
+        .frame(width: width, height: height)
+        .onAppear() {
+            if UIDevice.current.systemName.contains("iPadOS") {
+                width *= 1.2
+                height *= 1.2
+            }
+        }
+    }
+}
+
+struct DPadView: View {
+    @State var size: CGFloat = 145
+    var body: some View {
+        VStack {
+            ButtonView(button: .dPadUp)
+            HStack {
+                ButtonView(button: .dPadLeft)
+                Spacer(minLength: 20)
+                ButtonView(button: .dPadRight)
+            }
+            ButtonView(button: .dPadDown)
+                .padding(.horizontal)
+        }
+        .frame(width: size, height: size)
+        .onAppear() {
+            if UIDevice.current.systemName.contains("iPadOS") {
+                size *= 1.2
+            }
+        }
+    }
+}
+
+struct ABXYView: View {
+    @State var size: CGFloat = 145
+    var body: some View {
+        VStack {
+            ButtonView(button: .X)
+            HStack {
+                ButtonView(button: .Y)
+                Spacer(minLength: 20)
+                ButtonView(button: .A)
+            }
+            ButtonView(button: .B)
+                .padding(.horizontal)
+        }
+        .frame(width: size, height: size)
+        .onAppear() {
+            if UIDevice.current.systemName.contains("iPadOS") {
+                size *= 1.2
+            }
+        }
+    }
+}
+
+struct ButtonView: View {
+    var button: VirtualControllerButton
+    @State var width: CGFloat = 45
+    @State var height: CGFloat = 45
+    @State var isPressed = false
+    @AppStorage("onscreenhandheld") var onscreenjoy: Bool = false
+    @Environment(\.colorScheme) var colorScheme
+    @Environment(\.presentationMode) var presentationMode
+    
+
+    
+    var body: some View {
+        Image(systemName: buttonText)
+            .resizable()
+            .frame(width: width, height: height)
+            .foregroundColor(colorScheme == .dark ? Color.gray : Color.gray)
+            .opacity(isPressed ? 0.4 : 0.7)
+            .gesture(
+                DragGesture(minimumDistance: 0)
+                    .onChanged { _ in
+                        if !self.isPressed {
+                            self.isPressed = true
+                            Ryujinx.shared.virtualController.setButtonState(1, for: button)
+                            Haptics.shared.play(.heavy)
+                        }
+                    }
+                    .onEnded { _ in
+                        self.isPressed = false
+                        Ryujinx.shared.virtualController.setButtonState(0, for: button)
+                    }
+                )
+            .onAppear() {
+                if button == .leftTrigger || button == .rightTrigger || button == .leftShoulder || button == .rightShoulder {
+                    width = 65
+                }
+            
+                
+                if button == .back || button == .start || button == .guide {
+                    width = 35
+                    height = 35
+                }
+                
+                if UIDevice.current.systemName.contains("iPadOS") {
+                    width *= 1.2
+                    height *= 1.2
+                }
+            }
+    }
+    
+
+    
+    private var buttonText: String {
+        switch button {
+        case .A:
+            return "a.circle.fill"
+        case .B:
+            return "b.circle.fill"
+        case .X:
+            return "x.circle.fill"
+        case .Y:
+            return "y.circle.fill"
+        case .dPadUp:
+            return "arrowtriangle.up.circle.fill"
+        case .dPadDown:
+            return "arrowtriangle.down.circle.fill"
+        case .dPadLeft:
+            return "arrowtriangle.left.circle.fill"
+        case .dPadRight:
+            return "arrowtriangle.right.circle.fill"
+        case .leftTrigger:
+            return"zl.rectangle.roundedtop.fill"
+        case .rightTrigger:
+            return "zr.rectangle.roundedtop.fill"
+        case .leftShoulder:
+            return "l.rectangle.roundedbottom.fill"
+        case .rightShoulder:
+            return "r.rectangle.roundedbottom.fill"
+        case .start:
+            return "plus.circle.fill" // System symbol for +
+        case .back:
+            return "minus.circle.fill" // System symbol for -
+        case .guide:
+            return "house.circle.fill"
+        // This should be all the cases
+        default:
+            return ""
+        }
+    }
+}
+
+
diff --git a/src/MeloNX/MeloNX/Views/ControllerView/Haptics/Haptics.swift b/src/MeloNX/MeloNX/Views/ControllerView/Haptics/Haptics.swift
new file mode 100644
index 000000000..5dd555815
--- /dev/null
+++ b/src/MeloNX/MeloNX/Views/ControllerView/Haptics/Haptics.swift
@@ -0,0 +1,27 @@
+//
+//  Haptics.swift
+//  Pomelo
+//
+//  Created by Stossy11 on 11/9/2024.
+//  Copyright © 2024 Stossy11. All rights reserved.
+//
+
+import UIKit
+import SwiftUI
+
+class Haptics {
+    static let shared = Haptics()
+    
+    private init() { }
+
+    func play(_ feedbackStyle: UIImpactFeedbackGenerator.FeedbackStyle) {
+        print("haptics")
+        UIImpactFeedbackGenerator(style: feedbackStyle).impactOccurred()
+    }
+    
+    func notify(_ feedbackType: UINotificationFeedbackGenerator.FeedbackType) {
+        UINotificationFeedbackGenerator().notificationOccurred(feedbackType)
+    }
+}
+
+
diff --git a/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/Contents.json b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/Contents.json
new file mode 100644
index 000000000..da4a164c9
--- /dev/null
+++ b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}
\ No newline at end of file
diff --git a/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/DefaultBase.imageset/Contents.json b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/DefaultBase.imageset/Contents.json
new file mode 100644
index 000000000..3a763d2f9
--- /dev/null
+++ b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/DefaultBase.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "filename" : "JoyStickBase@1x.png",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "filename" : "JoyStickBase@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "filename" : "JoyStickBase@3x.png",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}
\ No newline at end of file
diff --git a/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/DefaultBase.imageset/JoyStickBase@1x.png b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/DefaultBase.imageset/JoyStickBase@1x.png
new file mode 100644
index 000000000..2e3903652
Binary files /dev/null and b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/DefaultBase.imageset/JoyStickBase@1x.png differ
diff --git a/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/DefaultBase.imageset/JoyStickBase@2x.png b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/DefaultBase.imageset/JoyStickBase@2x.png
new file mode 100644
index 000000000..49a14c122
Binary files /dev/null and b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/DefaultBase.imageset/JoyStickBase@2x.png differ
diff --git a/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/DefaultBase.imageset/JoyStickBase@3x.png b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/DefaultBase.imageset/JoyStickBase@3x.png
new file mode 100644
index 000000000..35851e642
Binary files /dev/null and b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/DefaultBase.imageset/JoyStickBase@3x.png differ
diff --git a/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/DefaultHandle.imageset/Contents.json b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/DefaultHandle.imageset/Contents.json
new file mode 100644
index 000000000..6c1bf409f
--- /dev/null
+++ b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/DefaultHandle.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "filename" : "JoyStickHandle@1x.png",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "filename" : "JoyStickHandle@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "filename" : "JoyStickHandle@3x.png",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}
\ No newline at end of file
diff --git a/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/DefaultHandle.imageset/JoyStickHandle@1x.png b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/DefaultHandle.imageset/JoyStickHandle@1x.png
new file mode 100644
index 000000000..d4555a959
Binary files /dev/null and b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/DefaultHandle.imageset/JoyStickHandle@1x.png differ
diff --git a/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/DefaultHandle.imageset/JoyStickHandle@2x.png b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/DefaultHandle.imageset/JoyStickHandle@2x.png
new file mode 100644
index 000000000..93c135334
Binary files /dev/null and b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/DefaultHandle.imageset/JoyStickHandle@2x.png differ
diff --git a/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/DefaultHandle.imageset/JoyStickHandle@3x.png b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/DefaultHandle.imageset/JoyStickHandle@3x.png
new file mode 100644
index 000000000..25e602e3f
Binary files /dev/null and b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/DefaultHandle.imageset/JoyStickHandle@3x.png differ
diff --git a/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/FancyBase.imageset/Contents.json b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/FancyBase.imageset/Contents.json
new file mode 100644
index 000000000..6f901e4e8
--- /dev/null
+++ b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/FancyBase.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "filename" : "JoyStickBaseCustom@1x.png",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "filename" : "JoyStickBaseCustom@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "filename" : "JoyStickBaseCustom@3x.png",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}
\ No newline at end of file
diff --git a/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/FancyBase.imageset/JoyStickBaseCustom@1x.png b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/FancyBase.imageset/JoyStickBaseCustom@1x.png
new file mode 100644
index 000000000..113ccadc4
Binary files /dev/null and b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/FancyBase.imageset/JoyStickBaseCustom@1x.png differ
diff --git a/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/FancyBase.imageset/JoyStickBaseCustom@2x.png b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/FancyBase.imageset/JoyStickBaseCustom@2x.png
new file mode 100644
index 000000000..bbdf7e4cd
Binary files /dev/null and b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/FancyBase.imageset/JoyStickBaseCustom@2x.png differ
diff --git a/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/FancyBase.imageset/JoyStickBaseCustom@3x.png b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/FancyBase.imageset/JoyStickBaseCustom@3x.png
new file mode 100644
index 000000000..949788e5f
Binary files /dev/null and b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/FancyBase.imageset/JoyStickBaseCustom@3x.png differ
diff --git a/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/FancyHandle.imageset/Contents.json b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/FancyHandle.imageset/Contents.json
new file mode 100644
index 000000000..4091d8b19
--- /dev/null
+++ b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/FancyHandle.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "filename" : "JoyStickHandleCustom@1x.png",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "filename" : "JoyStickHandleCustom@2x.png",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "universal",
+      "filename" : "JoyStickHandleCustom@3x.png",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}
\ No newline at end of file
diff --git a/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/FancyHandle.imageset/JoyStickHandleCustom@1x.png b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/FancyHandle.imageset/JoyStickHandleCustom@1x.png
new file mode 100644
index 000000000..9fb451158
Binary files /dev/null and b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/FancyHandle.imageset/JoyStickHandleCustom@1x.png differ
diff --git a/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/FancyHandle.imageset/JoyStickHandleCustom@2x.png b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/FancyHandle.imageset/JoyStickHandleCustom@2x.png
new file mode 100644
index 000000000..2c0f0d930
Binary files /dev/null and b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/FancyHandle.imageset/JoyStickHandleCustom@2x.png differ
diff --git a/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/FancyHandle.imageset/JoyStickHandleCustom@3x.png b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/FancyHandle.imageset/JoyStickHandleCustom@3x.png
new file mode 100644
index 000000000..edc88f2ee
Binary files /dev/null and b/src/MeloNX/MeloNX/Views/ControllerView/JoyStickView/Resources/Assets.xcassets/FancyHandle.imageset/JoyStickHandleCustom@3x.png differ
diff --git a/src/MeloNX/MeloNX/Views/ControllerView/Joystick/JoystickView.swift b/src/MeloNX/MeloNX/Views/ControllerView/Joystick/JoystickView.swift
new file mode 100644
index 000000000..dc1db3d8c
--- /dev/null
+++ b/src/MeloNX/MeloNX/Views/ControllerView/Joystick/JoystickView.swift
@@ -0,0 +1,53 @@
+//
+//  JoystickView.swift
+//  Pomelo
+//
+//  Created by Stossy11 on 30/9/2024.
+//  Copyright © 2024 Stossy11. All rights reserved.
+//
+
+import SwiftUI
+import SwiftUIJoystick
+
+public struct Joystick: View {
+    @State var iscool: Bool? = nil
+    
+    @ObservedObject public var joystickMonitor = JoystickMonitor()
+    var dragDiameter: CGFloat {
+        var selfs = CGFloat(160)
+        if UIDevice.current.systemName.contains("iPadOS") {
+            return selfs * 1.2
+        }
+        return selfs
+    }
+    private let shape: JoystickShape = .circle
+    
+    public var body: some View {
+        VStack{
+            JoystickBuilder(
+                monitor: self.joystickMonitor,
+                width: self.dragDiameter,
+                shape: .circle,
+                background: {
+                    Text("")
+                        .hidden()
+                },
+                foreground: {
+                    Circle().fill(Color.gray)
+                        .opacity(0.7)
+                },
+                locksInPlace: false)
+            .onChange(of: self.joystickMonitor.xyPoint) { newValue in
+                let scaledX = Float(newValue.x)
+                let scaledY = Float(newValue.y) // my dumbass broke this by having -y instead of y :/
+                print("Joystick Position: (\(scaledX), \(scaledY))")
+                
+                if iscool != nil {
+                    Ryujinx.shared.virtualController.thumbstickMoved(.right, x: newValue.x, y: newValue.y)
+                } else {
+                    Ryujinx.shared.virtualController.thumbstickMoved(.left, x: newValue.x, y: newValue.y)
+                }
+            }
+        }
+    }
+}
diff --git a/src/MeloNX/MeloNX/Views/GamesList/GameListView.swift b/src/MeloNX/MeloNX/Views/GamesList/GameListView.swift
index ec8891526..35d4c42c8 100644
--- a/src/MeloNX/MeloNX/Views/GamesList/GameListView.swift
+++ b/src/MeloNX/MeloNX/Views/GamesList/GameListView.swift
@@ -5,25 +5,147 @@
 //  Created by Stossy11 on 3/11/2024.
 //
 
-// MARK: - This will most likely not be used in prod
 import SwiftUI
+import UniformTypeIdentifiers
 
-struct GameListView: View {
+
+struct GameLibraryView: View {
     @Binding var startemu: URL?
-    @State private var games: [URL] = []
-
+    @State private var games: [Game] = []
+    @State private var searchText = ""
+    @State private var isSearching = false
+    @AppStorage("recentGames") private var recentGamesData: Data = Data()
+    @State private var recentGames: [Game] = []
+    @Environment(\.colorScheme) var colorScheme
+    
+    var filteredGames: [Game] {
+        if searchText.isEmpty {
+            return games
+        }
+        return games.filter {
+            $0.titleName.localizedCaseInsensitiveContains(searchText) ||
+            $0.developer.localizedCaseInsensitiveContains(searchText)
+        }
+    }
+    
     var body: some View {
-        List(games, id: \.self) { game in
-            Button {
-                startemu = game
-            } label: {
-                Text(game.lastPathComponent)
+        iOSNav {
+            ScrollView {
+                LazyVStack(alignment: .leading, spacing: 20) {
+                    if !isSearching {
+                        Text("Games")
+                            .font(.system(size: 34, weight: .bold))
+                            .padding(.horizontal)
+                            .padding(.top, 12)
+                    }
+                    
+                    if games.isEmpty {
+                        VStack(spacing: 16) {
+                            Image(systemName: "gamecontroller.fill")
+                                .font(.system(size: 64))
+                                .foregroundColor(.secondary.opacity(0.7))
+                                .padding(.top, 60)
+                            Text("No Games Found")
+                                .font(.title2.bold())
+                                .foregroundColor(.primary)
+                            Text("Add ROM, Keys and Firmware to get started")
+                                .font(.subheadline)
+                                .foregroundColor(.secondary)
+                        }
+                        .frame(maxWidth: .infinity)
+                        .padding(.top, 40)
+                    } else {
+                        if !isSearching && !recentGames.isEmpty {
+                            VStack(alignment: .leading, spacing: 12) {
+                                Text("Recent")
+                                    .font(.title2.bold())
+                                    .padding(.horizontal)
+                                
+                                ScrollView(.horizontal, showsIndicators: false) {
+                                    LazyHStack(spacing: 16) {
+                                        ForEach(recentGames) { game in
+                                            RecentGameCard(game: game, startemu: $startemu)
+                                                .onTapGesture {
+                                                    addToRecentGames(game)
+                                                    startemu = game.fileURL
+                                                }
+                                        }
+                                    }
+                                    .padding(.horizontal)
+                                }
+                            }
+                            
+                            VStack(alignment: .leading, spacing: 12) {
+                                Text("All Games")
+                                    .font(.title2.bold())
+                                    .padding(.horizontal)
+                                
+                                LazyVStack(spacing: 2) {
+                                    ForEach(filteredGames) { game in
+                                        GameListRow(game: game, startemu: $startemu)
+                                            .onTapGesture {
+                                                addToRecentGames(game)
+                                            }
+                                    }
+                                }
+                            }
+                        } else {
+                            LazyVStack(spacing: 2) {
+                                ForEach(filteredGames) { game in
+                                    GameListRow(game: game, startemu: $startemu)
+                                        .onTapGesture {
+                                            addToRecentGames(game)
+                                        }
+                                }
+                            }
+                        }
+                    }
+                }
+                .onAppear {
+                    loadGames()
+                    loadRecentGames()
+                }
             }
         }
-        .navigationTitle("Games")
-        .onAppear(perform: loadGames)
+        .background(Color(.systemGroupedBackground))
+        .searchable(text: $searchText)
+        .onChange(of: searchText) { _ in
+            isSearching = !searchText.isEmpty
+        }
     }
-
+    
+    private func addToRecentGames(_ game: Game) {
+        recentGames.removeAll { $0.id == game.id }
+        
+        recentGames.insert(game, at: 0)
+        
+        if recentGames.count > 5 {
+            recentGames = Array(recentGames.prefix(5))
+        }
+        
+        saveRecentGames()
+    }
+    
+    private func saveRecentGames() {
+        do {
+            let encoder = JSONEncoder()
+            let data = try encoder.encode(recentGames)
+            recentGamesData = data
+        } catch {
+            print("Error saving recent games: \(error)")
+        }
+    }
+    
+    private func loadRecentGames() {
+        do {
+            let decoder = JSONDecoder()
+            recentGames = try decoder.decode([Game].self, from: recentGamesData)
+        } catch {
+            print("Error loading recent games: \(error)")
+            recentGames = []
+        }
+    }
+    
     private func loadGames() {
         let fileManager = FileManager.default
         guard let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
@@ -38,13 +160,187 @@ struct GameListView: View {
                 print("Failed to create roms directory: \(error)")
             }
         }
-
+        games = []
         // Load games only from "roms" folder
         do {
             let files = try fileManager.contentsOfDirectory(at: romsDirectory, includingPropertiesForKeys: nil)
-            games = files
+            
+            files.forEach { fileURLCandidate in
+                do {
+                    let handle = try FileHandle(forReadingFrom: fileURLCandidate)
+                    let fileExtension = (fileURLCandidate.pathExtension as NSString).utf8String
+                    let extensionPtr = UnsafeMutablePointer<CChar>(mutating: fileExtension)
+                    
+                    
+                    var game = Game(containerFolder: romsDirectory, fileType: .item, fileURL: fileURLCandidate, titleName: fileURLCandidate.lastPathComponent, titleId: "", developer: "", version: "")
+                    
+                    /*
+                    game.titleName = withUnsafePointer(to: &gameInfo.TitleName) {
+                        $0.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout.size(ofValue: $0)) {
+                            String(cString: $0)
+                        }
+                    }
+                    
+                    game.developer = withUnsafePointer(to: &gameInfo.Developer) {
+                        $0.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout.size(ofValue: $0)) {
+                            String(cString: $0)
+                        }
+                    }
+                     */
+
+                    
+                    games.append(game)
+                } catch {
+                    print(error)
+                }
+            }
+            
         } catch {
             print("Error loading games from roms folder: \(error)")
         }
     }
 }
+
+// Make sure your Game model conforms to Codable
+extension Game: Codable {
+    enum CodingKeys: String, CodingKey {
+        case titleName, titleId, developer, version, fileURL
+    }
+    
+    public init(from decoder: Decoder) throws {
+        let container = try decoder.container(keyedBy: CodingKeys.self)
+        titleName = try container.decode(String.self, forKey: .titleName)
+        titleId = try container.decode(String.self, forKey: .titleId)
+        developer = try container.decode(String.self, forKey: .developer)
+        version = try container.decode(String.self, forKey: .version)
+        fileURL = try container.decode(URL.self, forKey: .fileURL)
+        
+        // Initialize other properties
+        self.containerFolder = fileURL.deletingLastPathComponent()
+        self.fileType = .item
+    }
+    
+    public func encode(to encoder: Encoder) throws {
+        var container = encoder.container(keyedBy: CodingKeys.self)
+        try container.encode(titleName, forKey: .titleName)
+        try container.encode(titleId, forKey: .titleId)
+        try container.encode(developer, forKey: .developer)
+        try container.encode(version, forKey: .version)
+        try container.encode(fileURL, forKey: .fileURL)
+    }
+}
+
+struct RecentGameCard: View {
+    let game: Game
+    @Binding var startemu: URL?
+    @Environment(\.colorScheme) var colorScheme
+    
+    var body: some View {
+        Button(action: {
+            startemu = game.fileURL
+        }) {
+            VStack(alignment: .leading, spacing: 8) {
+                if let icon = game.icon {
+                    Image(uiImage: icon)
+                        .resizable()
+                        .aspectRatio(contentMode: .fill)
+                        .frame(width: 140, height: 140)
+                        .cornerRadius(12)
+                } else {
+                    ZStack {
+                        RoundedRectangle(cornerRadius: 12)
+                            .fill(colorScheme == .dark ?
+                                  Color(.systemGray5) : Color(.systemGray6))
+                            .frame(width: 140, height: 140)
+                        
+                        Image(systemName: "gamecontroller.fill")
+                            .font(.system(size: 40))
+                            .foregroundColor(.gray)
+                    }
+                }
+                
+                VStack(alignment: .leading, spacing: 2) {
+                    Text(game.titleName)
+                        .font(.subheadline.bold())
+                        .lineLimit(1)
+                    
+                    Text(game.developer)
+                        .font(.caption)
+                        .foregroundColor(.secondary)
+                        .lineLimit(1)
+                }
+                .padding(.horizontal, 4)
+            }
+        }
+        .buttonStyle(.plain)
+    }
+}
+
+struct GameListRow: View {
+    let game: Game
+    @Binding var startemu: URL?
+    @Environment(\.colorScheme) var colorScheme
+    
+    var body: some View {
+        Button(action: {
+            startemu = game.fileURL
+        }) {
+            HStack(spacing: 16) {
+                // Game Icon
+                if let icon = game.icon {
+                    Image(uiImage: icon)
+                        .resizable()
+                        .aspectRatio(contentMode: .fill)
+                        .frame(width: 45, height: 45)
+                        .cornerRadius(8)
+                } else {
+                    ZStack {
+                        RoundedRectangle(cornerRadius: 8)
+                            .fill(colorScheme == .dark ?
+                                  Color(.systemGray5) : Color(.systemGray6))
+                            .frame(width: 45, height: 45)
+                        
+                        Image(systemName: "gamecontroller.fill")
+                            .font(.system(size: 20))
+                            .foregroundColor(.gray)
+                    }
+                }
+                
+                // Game Info
+                VStack(alignment: .leading, spacing: 2) {
+                    Text(game.titleName)
+                        .font(.body)
+                        .foregroundColor(.primary)
+                    
+                    Text(game.developer)
+                        .font(.subheadline)
+                        .foregroundColor(.secondary)
+                }
+                
+                Spacer()
+                
+                Image(systemName: "play.circle.fill")
+                    .font(.title2)
+                    .foregroundColor(.accentColor)
+                    .opacity(0.8)
+            }
+            .padding(.horizontal)
+            .padding(.vertical, 8)
+            .background(Color(.systemBackground))
+            .contextMenu {
+                Button {
+                    startemu = game.fileURL
+                } label: {
+                    Label("Play Now", systemImage: "play.fill")
+                }
+                
+                Button {
+                    // Add info action
+                } label: {
+                    Label("Game Info", systemImage: "info.circle")
+                }
+            }
+        }
+        .buttonStyle(.plain)
+    }
+}
diff --git a/src/MeloNX/MeloNX/Views/SDLView/SDLView.swift b/src/MeloNX/MeloNX/Views/SDLView/SDLView.swift
deleted file mode 100644
index 1f89ffaf8..000000000
--- a/src/MeloNX/MeloNX/Views/SDLView/SDLView.swift
+++ /dev/null
@@ -1,84 +0,0 @@
-//
-//  VulkanSDLView.swift
-//  MeloNX
-//
-//  Created by Stossy11 on 3/11/2024.
-//
-
-import UIKit
-import MetalKit
-import SDL2
-
-class SDLView: UIView {
-    var sdlwin: OpaquePointer?
-    
-    override init(frame: CGRect) {
-        super.init(frame: frame)
-        DispatchQueue.main.async { [self] in
-            makeSDLWindow()
-        }
-    }
-
-    required init?(coder: NSCoder) {
-        super.init(coder: coder)
-        DispatchQueue.main.async { [self] in
-            makeSDLWindow()
-        }
-    }
-
-    func getWindowFlags() -> UInt32 {
-        return SDL_WINDOW_VULKAN.rawValue
-    }
-
-    private func makeSDLWindow() {
-        let width: Int32 = 1280  // Replace with the desired width
-        let height: Int32 = 720  // Replace with the desired height
-        
-        let defaultFlags: UInt32 = SDL_WINDOW_SHOWN.rawValue
-        let fullscreenFlag: UInt32 = SDL_WINDOW_FULLSCREEN.rawValue // Or SDL_WINDOW_FULLSCREEN_DESKTOP if needed
-        
-        // Create the SDL window
-        sdlwin = SDL_CreateWindow(
-            "Ryujinx",
-            0,
-            0,
-            width,
-            height,
-            defaultFlags | getWindowFlags() // | fullscreenFlag | getWindowFlags()
-        )
-
-        // Check if we successfully retrieved the SDL window
-        guard sdlwin != nil else {
-            print("Error creating SDL window: \(String(cString: SDL_GetError()))")
-            return
-        }
-        
-        print("SDL window created successfully.")
-        
-        // Position SDL window over this UIView
-        self.syncSDLWindowPosition()
-    }
-    
-    private func syncSDLWindowPosition() {
-        guard let sdlwin = sdlwin else { return }
-        
-        
-        // Get the frame of the UIView in screen coordinates
-        let viewFrameInWindow = self.convert(self.bounds, to: nil)
-        
-        // Set the SDL window position and size to match the UIView frame
-        SDL_SetWindowPosition(sdlwin, Int32(viewFrameInWindow.origin.x), Int32(viewFrameInWindow.origin.y))
-        SDL_SetWindowSize(sdlwin, Int32(viewFrameInWindow.width), Int32(viewFrameInWindow.height))
-        
-        // Bring SDL window to the front
-        SDL_RaiseWindow(sdlwin)
-        
-        print("SDL window positioned over SDLView.")
-    }
-    
-    override func layoutSubviews() {
-        super.layoutSubviews()
-        // Adjust SDL window whenever layout changes
-        syncSDLWindowPosition()
-    }
-}
diff --git a/src/MeloNX/MeloNX/Views/SDLView/SDLViewRepresentable.swift b/src/MeloNX/MeloNX/Views/SDLView/SDLViewRepresentable.swift
deleted file mode 100644
index be04a2581..000000000
--- a/src/MeloNX/MeloNX/Views/SDLView/SDLViewRepresentable.swift
+++ /dev/null
@@ -1,27 +0,0 @@
-//
-//  VulkanSDLViewRepresentable.swift
-//  MeloNX
-//
-//  Created by Stossy11 on 3/11/2024.
-//
-
-import UIKit
-import SwiftUI
-import SDL2
-import GameController
-
-struct SDLViewRepresentable: UIViewRepresentable {
-    let configure: (UInt32) -> Void
-    func makeUIView(context: Context) -> SDLView {
-        // Configure (start ryu) before initialsing SDLView so SDLView can get the SDL_Window from Ryu
-        let view = SDLView(frame: .zero)
-        configure(SDL_GetWindowID(view.sdlwin))
-        return view
-            
-    }
-
-    func updateUIView(_ uiView: SDLView, context: Context) {
-        
-    }
-    
-}
diff --git a/src/MeloNX/MeloNX/Views/SettingsView/SettingsView.swift b/src/MeloNX/MeloNX/Views/SettingsView/SettingsView.swift
index ddd89965f..3defbcf63 100644
--- a/src/MeloNX/MeloNX/Views/SettingsView/SettingsView.swift
+++ b/src/MeloNX/MeloNX/Views/SettingsView/SettingsView.swift
@@ -11,6 +11,13 @@ struct SettingsView: View {
     @Binding var config: Ryujinx.Configuration
     @Binding var MoltenVKSettings: [MoltenVKSettings]
     
+    @Binding var controllersList: [Controller]
+    @Binding var currentControllers: [Controller]
+    
+    @Binding var onscreencontroller: Controller
+    
+    @AppStorage("ignoreJIT") var ignoreJIT: Bool = false
+    
     var memoryManagerModes = [
         ("HostMapped", "Host (fast)"),
         ("HostMappedUnsafe", "Host Unchecked (fast, unstable / unsafe)"),
@@ -18,166 +25,294 @@ struct SettingsView: View {
     ]
     
     @AppStorage("RyuDemoControls") var ryuDemo: Bool = false
-    
     @AppStorage("MTL_HUD_ENABLED") var metalHUDEnabled: Bool = false
     
+    @State private var showResolutionInfo = false
+    @State private var searchText = ""
+    
+    var filteredMemoryModes: [(String, String)] {
+        guard !searchText.isEmpty else { return memoryManagerModes }
+        return memoryManagerModes.filter { $0.1.localizedCaseInsensitiveContains(searchText) }
+    }
+    
     var body: some View {
-        ScrollView {
-            VStack {
-                Section(header: Title("Graphics and Performance")) {
-                    Toggle("Ryujinx Fullscreen", isOn: $config.fullscreen)
-                    Toggle("Disable V-Sync", isOn: $config.disableVSync)
-                    Toggle("Disable Shader Cache", isOn: $config.disableShaderCache)
-                    Toggle("Enable Texture Recompression", isOn: $config.enableTextureRecompression)
-                    Toggle("Disable Docked Mode", isOn: $config.disableDockedMode)
-                    Resolution(value: $config.resscale)
-                    Toggle("Enable Metal HUD", isOn: $metalHUDEnabled)
-                        .onChange(of: metalHUDEnabled) { newValue in
-                            if newValue {
-                                MTLHud.shared.enable()
-                            } else {
-                                MTLHud.shared.disable()
+        iOSNav {
+            List {
+                // Graphics & Performance
+                Section {
+                    Toggle(isOn: $config.fullscreen) {
+                        labelWithIcon("Fullscreen", iconName: "rectangle.expand.vertical")
+                    }
+                    .tint(.blue)
+
+                    Toggle(isOn: $config.disableShaderCache) {
+                        labelWithIcon("Disable Shader Cache", iconName: "memorychip")
+                    }
+                    .tint(.blue)
+
+                    Toggle(isOn: $config.enableTextureRecompression) {
+                        labelWithIcon("Texture Recompression", iconName: "rectangle.compress.vertical")
+                    }
+                    .tint(.blue)
+
+                    Toggle(isOn: $config.disableDockedMode) {
+                        labelWithIcon("Disable Docked Mode", iconName: "dock.rectangle")
+                    }
+                    .tint(.blue)
+
+                    VStack(alignment: .leading, spacing: 10) {
+                        HStack {
+                            labelWithIcon("Resolution Scale", iconName: "magnifyingglass")
+                                .font(.headline)
+                            Spacer()
+                            Button {
+                                showResolutionInfo.toggle()
+                            } label: {
+                                Image(systemName: "info.circle")
+                                    .symbolRenderingMode(.hierarchical)
+                                    .foregroundStyle(.secondary)
+                            }
+                            .buttonStyle(.plain)
+                            .help("Learn more about Resolution Scale")
+                            .alert(isPresented: $showResolutionInfo) {
+                                Alert(
+                                    title: Text("Resolution Scale"),
+                                    message: Text("Adjust the internal rendering resolution. Higher values improve visuals but may reduce performance."),
+                                    dismissButton: .default(Text("OK"))
+                                )
                             }
                         }
+
+                        Slider(value: $config.resscale, in: 0.1...3.0, step: 0.1) {
+                            Text("Resolution Scale")
+                        } minimumValueLabel: {
+                            Text("0.1x")
+                                .font(.footnote)
+                                .foregroundColor(.secondary)
+                        } maximumValueLabel: {
+                            Text("3.0x")
+                                .font(.footnote)
+                                .foregroundColor(.secondary)
+                        }
+                        Text("\(config.resscale, specifier: "%.2f")x")
+                            .font(.subheadline)
+                            .foregroundColor(.secondary)
+                    }
+                    .padding(.vertical, 8)
+
+                    Toggle(isOn: $metalHUDEnabled) {
+                        labelWithIcon("Metal HUD", iconName: "speedometer")
+                    }
+                    .tint(.blue)
+                    .onChange(of: metalHUDEnabled) { newValue in
+                        // Preserves original functionality
+                        if newValue {
+                            MTLHud.shared.enable()
+                        } else {
+                            MTLHud.shared.disable()
+                        }
+                    }
+                } header: {
+                    Text("Graphics & Performance")
+                        .font(.title3.weight(.semibold))
+                        .textCase(nil)
+                        .headerProminence(.increased)
+                } footer: {
+                    Text("Fine-tune graphics and performance to suit your device and preferences.")
                 }
                 
-                Section(header: Title("Input Settings")) {
-                    Toggle("List Input IDs", isOn: $config.listinputids)
-                    Toggle("Nintendo Controller Layout", isOn: $config.nintendoinput)
-                    Toggle("Ryujinx Demo On-Screen Controller", isOn: $ryuDemo)
-                    // Toggle("Host Mapped Memory", isOn: $config.hostMappedMemory)
+                // Input Selector
+                Section {
+                    ForEach(controllersList) { controller in
+                        var customBinding: Binding<Bool> {
+                            Binding(
+                                get: { currentControllers.contains(controller) },
+                                set: { bool in
+                                    if !bool {
+                                        currentControllers.removeAll(where: { $0.id == controller.id })
+                                    } else {
+                                        currentControllers.append(controller)
+                                    }
+                                    // toggleController(controller)
+                                }
+                            )
+                        }
+                        
+                        Toggle(isOn: customBinding) {
+                            labelWithIcon(controller.name, iconName: "")
+                        }
+                        .tint(.blue)
+                    }
+                } header: {
+                    Text("Input Selector")
+                        .font(.title3.weight(.semibold))
+                        .textCase(nil)
+                        .headerProminence(.increased)
+                } footer: {
+                    Text("Select input devices and on-screen controls to play with.")
                 }
-                
-                Section(header: Title("Logging Settings")) {
-                    Toggle("Enable Debug Logs", isOn: $config.debuglogs)
-                    Toggle("Enable Trace Logs", isOn: $config.tracelogs)
+
+                // Input Settings
+                Section {
+                    
+                    Toggle(isOn: $config.listinputids) {
+                        labelWithIcon("List Input IDs", iconName: "list.bullet")
+                    }
+                    .tint(.blue)
+
+                    Toggle(isOn: $ryuDemo) {
+                        labelWithIcon("On-Screen Controller (Demo)", iconName: "hand.draw")
+                    }
+                    .tint(.blue)
+                    .disabled(true)
+                } header: {
+                    Text("Input Settings")
+                        .font(.title3.weight(.semibold))
+                        .textCase(nil)
+                        .headerProminence(.increased)
+                } footer: {
+                    Text("Configure input devices and on-screen controls for easier navigation and play.")
                 }
-                Section(header: Title("CPU Mode")) {
-                    HStack {
-                        Spacer()
-                        Picker("Memory Manager Mode", selection: $config.memoryManagerMode) {
-                            ForEach(memoryManagerModes, id: \.0) { key, displayName in
+
+                // Logging
+                Section {
+                    Toggle(isOn: $config.debuglogs) {
+                        labelWithIcon("Debug Logs", iconName: "exclamationmark.bubble")
+                    }
+                    .tint(.blue)
+
+                    Toggle(isOn: $config.tracelogs) {
+                        labelWithIcon("Trace Logs", iconName: "waveform.path")
+                    }
+                    .tint(.blue)
+                } header: {
+                    Text("Logging")
+                        .font(.title3.weight(.semibold))
+                        .textCase(nil)
+                        .headerProminence(.increased)
+                } footer: {
+                    Text("Enable logs for troubleshooting or keep them off for a cleaner experience.")
+                }
+
+                // CPU Mode
+                Section {
+                    if filteredMemoryModes.isEmpty {
+                        Text("No matches for \"\(searchText)\"")
+                            .foregroundColor(.secondary)
+                    } else {
+                        Picker(selection: $config.memoryManagerMode) {
+                            ForEach(filteredMemoryModes, id: \.0) { key, displayName in
                                 Text(displayName).tag(key)
                             }
+                        } label: {
+                            labelWithIcon("Memory Manager Mode", iconName: "gearshape")
                         }
-                        .pickerStyle(MenuPickerStyle()) // Dropdown style
                     }
+                } header: {
+                    Text("CPU Mode")
+                        .font(.title3.weight(.semibold))
+                        .textCase(nil)
+                        .headerProminence(.increased)
+                } footer: {
+                    Text("Select how memory is managed. 'Host (fast)' is best for most users.")
                 }
-                
-                
-                
-                Section(header: Title("Additional Settings")) {
-                    //TextField("Game Path", text: $config.gamepath)
-                    
-                    Text("PageSize \(String(Int(getpagesize())))")
-                    
-                    TextField("Additional Arguments", text: Binding(
-                        get: {
-                            config.additionalArgs.joined(separator: ", ")
-                        },
-                        set: { newValue in
-                            config.additionalArgs = newValue.split(separator: ",").map { String($0).trimmingCharacters(in: .whitespaces) }
+
+                // Advanced
+                Section {
+                    DisclosureGroup {
+                        HStack {
+                            labelWithIcon("Page Size", iconName: "textformat.size")
+                            Spacer()
+                            Text("\(String(Int(getpagesize())))")
+                                .foregroundColor(.secondary)
                         }
-                    ))
+
+                        TextField("Additional Arguments", text: Binding(
+                            get: {
+                                config.additionalArgs.joined(separator: ", ")
+                            },
+                            set: { newValue in
+                                config.additionalArgs = newValue
+                                    .split(separator: ",")
+                                    .map { $0.trimmingCharacters(in: .whitespaces) }
+                            }
+                        ))
+                        .textInputAutocapitalization(.none)
+                        .disableAutocorrection(true)
+                    } label: {
+                        Text("Advanced Options")
+                    }
+                } header: {
+                    Text("Advanced")
+                        .font(.title3.weight(.semibold))
+                        .textCase(nil)
+                        .headerProminence(.increased)
+                } footer: {
+                    Text("For advanced users. See page size or add custom arguments for experimental features. (Please don't touch this if you don't know what you're doing)")
                 }
             }
-            .padding()
-        }
-        .onAppear {
-            if let configs = loadSettings() {
-                self.config = configs
-                print(configs)
+            .searchable(text: $searchText, placement: .navigationBarDrawer(displayMode: .always))
+            .navigationTitle("Settings")
+            .navigationBarTitleDisplayMode(.inline)
+            .listStyle(.insetGrouped)
+            .onAppear {
+                if let configs = loadSettings() {
+                    self.config = configs
+                }
+            }
+            .onChange(of: config) { _ in
+                saveSettings()
             }
         }
-        .navigationTitle("Settings")
-        .navigationBarItems(trailing: Button("Save") {
-            saveSettings()
-        })
+        .navigationViewStyle(.stack)
+    }
+    
+    private func toggleController(_ controller: Controller) {
+        if currentControllers.contains(where: { $0.id == controller.id }) {
+            currentControllers.removeAll(where: { $0.id == controller.id })
+        } else {
+            currentControllers.append(controller)
+        }
     }
     
     func saveSettings() {
         do {
             let encoder = JSONEncoder()
-            encoder.outputFormatting = .prettyPrinted // Optional: Makes the JSON easier to read
+            encoder.outputFormatting = .prettyPrinted
             let data = try encoder.encode(config)
             let jsonString = String(data: data, encoding: .utf8)
-            
-            // Save to UserDefaults
             UserDefaults.standard.set(jsonString, forKey: "config")
-            
-            print("Settings saved successfully!")
         } catch {
             print("Failed to save settings: \(error)")
         }
     }
-}
-
-
-struct Resolution: View {
-    @Binding var value: Float
-
-    var body: some View {
-        HStack {
-            Text("Resolution Scale (Custom):")
-            Spacer()
-            
-            Button(action: {
-                if value > 0.1 { // Prevent values going below 0.1
-                    value -= 0.10
-                    value = round(value * 1000) / 1000 // Round to two decimal places
-                }
-                print(value)
-            }) {
-                Text("-")
-                    .frame(width: 30, height: 30)
-                    .background(Color.gray.opacity(0.2))
-                    .cornerRadius(5)
-            }
-            
-            TextField("", value: $value, formatter: NumberFormatter.floatFormatter)
-                .multilineTextAlignment(.center)
-                .frame(width: 60)
-                .textFieldStyle(RoundedBorderTextFieldStyle())
-                .keyboardType(.decimalPad)
-            
-            Button(action: {
-                value += 0.10
-                value = round(value * 1000) / 1000 // Round to two decimal places
-                print(value)
-            }) {
-                Text("+")
-                    .frame(width: 30, height: 30)
-                    .background(Color.gray.opacity(0.2))
-                    .cornerRadius(5)
-            }
+    
+    // Original loadSettings function assumed to exist
+    func loadSettings() -> Ryujinx.Configuration? {
+        guard let jsonString = UserDefaults.standard.string(forKey: "config"),
+              let data = jsonString.data(using: .utf8) else {
+            return nil
+        }
+        do {
+            let decoder = JSONDecoder()
+            let configs = try decoder.decode(Ryujinx.Configuration.self, from: data)
+            return configs
+        } catch {
+            print("Failed to load settings: \(error)")
+            return nil
         }
     }
-}
-
-extension NumberFormatter {
-    static var floatFormatter: NumberFormatter {
-        let formatter = NumberFormatter()
-        formatter.numberStyle = .decimal
-        formatter.maximumFractionDigits = 2
-        formatter.minimumFractionDigits = 2
-        formatter.allowsFloats = true
-        return formatter
-    }
-}
-
-
-struct Title: View {
-    let string: String
     
-    init(_ string: String) {
-        self.string = string
-    }
-    
-    var body: some View {
-        VStack {
-            Text(string)
-                .font(.title2)
-            Divider()
+    @ViewBuilder
+    private func labelWithIcon(_ text: String, iconName: String) -> some View {
+        HStack(spacing: 8) {
+            if !iconName.isEmpty {
+                Image(systemName: iconName)
+                    .symbolRenderingMode(.hierarchical)
+                    .foregroundStyle(.blue)
+            }
+            Text(text)
         }
+        .font(.body)
     }
 }
diff --git a/src/MeloNX/MeloNX/Views/TabView/TabView.swift b/src/MeloNX/MeloNX/Views/TabView/TabView.swift
new file mode 100644
index 000000000..21b52e907
--- /dev/null
+++ b/src/MeloNX/MeloNX/Views/TabView/TabView.swift
@@ -0,0 +1,34 @@
+//
+//  TabView.swift
+//  MeloNX
+//
+//  Created by Stossy11 on 10/12/2024.
+//
+
+import SwiftUI
+import UniformTypeIdentifiers
+
+
+struct MainTabView: View {
+    @Binding var startemu: URL?
+    @Binding var config: Ryujinx.Configuration
+    @Binding var MVKconfig: [MoltenVKSettings]
+    @Binding var controllersList: [Controller]
+    @Binding var currentControllers: [Controller]
+    
+    @Binding var onscreencontroller: Controller
+    
+    var body: some View {
+        TabView {
+            GameLibraryView(startemu: $startemu)
+                .tabItem {
+                    Label("Games", systemImage: "gamecontroller.fill")
+                }
+            
+            SettingsView(config: $config, MoltenVKSettings: $MVKconfig, controllersList: $controllersList, currentControllers: $currentControllers, onscreencontroller: $onscreencontroller)
+                .tabItem {
+                    Label("Settings", systemImage: "gear")
+                }
+        }
+    }
+}
diff --git a/src/Ryujinx.Common/Configuration/AppDataManager.cs b/src/Ryujinx.Common/Configuration/AppDataManager.cs
index d0d811923..644b8cafa 100644
--- a/src/Ryujinx.Common/Configuration/AppDataManager.cs
+++ b/src/Ryujinx.Common/Configuration/AppDataManager.cs
@@ -65,7 +65,12 @@ namespace Ryujinx.Common.Configuration
                 appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
             }
 
-            string userProfilePath = Path.Combine(appDataPath, DefaultBaseDir);
+            string userProfilePath;
+            if (OperatingSystem.IsIOS()) {
+                userProfilePath = appDataPath;
+            } else {
+                userProfilePath = Path.Combine(appDataPath, DefaultBaseDir);
+            }
             string portablePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, DefaultPortableDir);
 
             // On macOS, check for a portable directory next to the app bundle as well.
diff --git a/src/Ryujinx.Common/SystemInterop/StdErrAdapter.cs b/src/Ryujinx.Common/SystemInterop/StdErrAdapter.cs
index a04c404d8..f2d1d857d 100644
--- a/src/Ryujinx.Common/SystemInterop/StdErrAdapter.cs
+++ b/src/Ryujinx.Common/SystemInterop/StdErrAdapter.cs
@@ -27,6 +27,7 @@ namespace Ryujinx.Common.SystemInterop
 
         [SupportedOSPlatform("linux")]
         [SupportedOSPlatform("macos")]
+        [SupportedOSPlatform("ios")]
         private void RegisterPosix()
         {
             const int StdErrFileno = 2;
@@ -44,6 +45,7 @@ namespace Ryujinx.Common.SystemInterop
 
         [SupportedOSPlatform("linux")]
         [SupportedOSPlatform("macos")]
+        [SupportedOSPlatform("ios")]
         private async Task EventWorkerAsync(CancellationToken cancellationToken)
         {
             using TextReader reader = new StreamReader(_pipeReader, leaveOpen: true);
@@ -92,6 +94,7 @@ namespace Ryujinx.Common.SystemInterop
 
         [SupportedOSPlatform("linux")]
         [SupportedOSPlatform("macos")]
+        [SupportedOSPlatform("ios")]
         private static Stream CreateFileDescriptorStream(int fd)
         {
             return new FileStream(
@@ -100,5 +103,6 @@ namespace Ryujinx.Common.SystemInterop
             );
         }
 
+
     }
 }
diff --git a/src/Ryujinx.Common/Utilities/EmbeddedResources.cs b/src/Ryujinx.Common/Utilities/EmbeddedResources.cs
index d7990ad58..7d4af43a1 100644
--- a/src/Ryujinx.Common/Utilities/EmbeddedResources.cs
+++ b/src/Ryujinx.Common/Utilities/EmbeddedResources.cs
@@ -134,20 +134,12 @@ namespace Ryujinx.Common
 
         private static (Assembly, string) ResolveManifestPath(string filename)
         {
-            CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
-            CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture;
-            CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.InvariantCulture;
             var segments = filename.Split('/', 2, StringSplitOptions.RemoveEmptyEntries);
 
             if (segments.Length >= 2)
             {
-                foreach (var assembly in System.Runtime.Loader.AssemblyLoadContext.Default.Assemblies)
-                {
-                    if (assembly.GetName().Name == segments[0])
-                    {
-                        return (assembly, segments[1]);
-                    }
-                }
+                var assembly = Assembly.GetExecutingAssembly();
+                return (assembly, segments[1]);
             }
 
             return (_resourceAssembly, filename);
diff --git a/src/Ryujinx.Cpu/Signal/NativeSignalHandler.cs b/src/Ryujinx.Cpu/Signal/NativeSignalHandler.cs
index 2985f1c21..59a5b4d74 100644
--- a/src/Ryujinx.Cpu/Signal/NativeSignalHandler.cs
+++ b/src/Ryujinx.Cpu/Signal/NativeSignalHandler.cs
@@ -88,7 +88,7 @@ namespace Ryujinx.Cpu.Signal
 
                 ref SignalHandlerConfig config = ref GetConfigRef();
 
-                if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS())
+                if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS() || OperatingSystem.IsIOS())
                 {
                     _signalHandlerPtr = MapCode(NativeSignalHandlerGenerator.GenerateUnixSignalHandler(_handlerConfig, rangeStructSize));
 
diff --git a/src/Ryujinx.Cpu/Signal/UnixSignalHandlerRegistration.cs b/src/Ryujinx.Cpu/Signal/UnixSignalHandlerRegistration.cs
index d40e7cdc9..c380f43fd 100644
--- a/src/Ryujinx.Cpu/Signal/UnixSignalHandlerRegistration.cs
+++ b/src/Ryujinx.Cpu/Signal/UnixSignalHandlerRegistration.cs
@@ -62,7 +62,7 @@ namespace Ryujinx.Cpu.Signal
                 throw new InvalidOperationException($"Could not register SIGSEGV sigaction. Error: {result}");
             }
 
-            if (OperatingSystem.IsMacOS())
+            if (OperatingSystem.IsMacOS() || OperatingSystem.IsIOS())
             {
                 result = sigaction(SIGBUS, ref sig, out _);
 
@@ -77,7 +77,7 @@ namespace Ryujinx.Cpu.Signal
 
         public static bool RestoreExceptionHandler(SigAction oldAction)
         {
-            return sigaction(SIGSEGV, ref oldAction, out SigAction _) == 0 && (!OperatingSystem.IsMacOS() || sigaction(SIGBUS, ref oldAction, out SigAction _) == 0);
+            return sigaction(SIGSEGV, ref oldAction, out SigAction _) == 0 && (!OperatingSystem.IsMacOS() || OperatingSystem.IsIOS() || sigaction(SIGBUS, ref oldAction, out SigAction _) == 0);
         }
     }
 }
diff --git a/src/Ryujinx.Graphics.Vulkan/MoltenVK/MVKInitialization.cs b/src/Ryujinx.Graphics.Vulkan/MoltenVK/MVKInitialization.cs
index 086c4e1df..931422279 100644
--- a/src/Ryujinx.Graphics.Vulkan/MoltenVK/MVKInitialization.cs
+++ b/src/Ryujinx.Graphics.Vulkan/MoltenVK/MVKInitialization.cs
@@ -7,6 +7,7 @@ using System.Runtime.Versioning;
 namespace Ryujinx.Graphics.Vulkan.MoltenVK
 {
     [SupportedOSPlatform("macos")]
+    [SupportedOSPlatform("ios")]
     public static partial class MVKInitialization
     {
         private const string VulkanLib = "libvulkan.dylib";
diff --git a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
index cc2bc36c2..a127c27ef 100644
--- a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
+++ b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
@@ -14,6 +14,14 @@ using System.Runtime.InteropServices;
 using Format = Ryujinx.Graphics.GAL.Format;
 using PrimitiveTopology = Ryujinx.Graphics.GAL.PrimitiveTopology;
 using SamplerCreateInfo = Ryujinx.Graphics.GAL.SamplerCreateInfo;
+using System.Globalization;
+using System.Threading;
+using System;
+using System.Globalization;
+using System.Threading;
+using System.Resources;
+using System.Reflection;
+
 
 namespace Ryujinx.Graphics.Vulkan
 {
@@ -498,6 +506,33 @@ namespace Ryujinx.Graphics.Vulkan
             Queue = queue;
             QueueLock = new object();
 
+            try 
+            {
+                // Set invariant culture
+                CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture;
+                CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.InvariantCulture;
+                Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
+                Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture;
+
+                AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
+                {
+                    var assemblyName = new AssemblyName(args.Name);
+                    assemblyName.CultureInfo = CultureInfo.InvariantCulture;
+                    try 
+                    {
+                        return Assembly.Load(assemblyName);
+                    }
+                    catch
+                    {
+                        return null;
+                    }
+                };
+            }
+            catch (Exception ex)
+            {
+                Console.WriteLine($"Failed to set culture: {ex.Message}");
+            }
+
             LoadFeatures(maxQueueCount, queueFamilyIndex);
 
             QueueFamilyIndex = queueFamilyIndex;
diff --git a/src/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs b/src/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs
index 87d88fc65..6bed14279 100644
--- a/src/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs
+++ b/src/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs
@@ -98,7 +98,6 @@ namespace Ryujinx.HLE.HOS.Applets.Error
                 SystemLanguage.CanadianFrench       => "fr-CA",
                 SystemLanguage.LatinAmericanSpanish => "es-419",
                 SystemLanguage.SimplifiedChinese    => "zh-Hans",
-                SystemLanguage.TraditionalChinese   => "zh-Hant",
                 SystemLanguage.BrazilianPortuguese  => "pt-BR",
                 _                                   => "en-US",
 #pragma warning restore IDE0055
diff --git a/src/Ryujinx.HLE/HOS/SystemState/SystemStateMgr.cs b/src/Ryujinx.HLE/HOS/SystemState/SystemStateMgr.cs
index c650fe036..8e68975f3 100644
--- a/src/Ryujinx.HLE/HOS/SystemState/SystemStateMgr.cs
+++ b/src/Ryujinx.HLE/HOS/SystemState/SystemStateMgr.cs
@@ -21,7 +21,6 @@ namespace Ryujinx.HLE.HOS.SystemState
             "fr-CA",
             "es-419",
             "zh-Hans",
-            "zh-Hant",
             "pt-BR",
         };
 
diff --git a/src/Ryujinx.Headless.SDL2/Program.cs b/src/Ryujinx.Headless.SDL2/Program.cs
index a58f4299f..d6bf938d3 100644
--- a/src/Ryujinx.Headless.SDL2/Program.cs
+++ b/src/Ryujinx.Headless.SDL2/Program.cs
@@ -102,10 +102,6 @@ namespace Ryujinx.Headless.SDL2
             Version = "1";
             // Make process DPI aware for proper window sizing on high-res screens.
             ForceDpiAware.Windows();
-            CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
-
-            CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture;
-            CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.InvariantCulture;
 
             Silk.NET.Core.Loader.SearchPathContainer.Platform = Silk.NET.Core.Loader.UnderlyingPlatform.MacOS;
 
diff --git a/src/Ryujinx.Headless.SDL2/WindowBase.cs b/src/Ryujinx.Headless.SDL2/WindowBase.cs
index c12ee5eb3..b6f1a67de 100644
--- a/src/Ryujinx.Headless.SDL2/WindowBase.cs
+++ b/src/Ryujinx.Headless.SDL2/WindowBase.cs
@@ -48,7 +48,7 @@ namespace Ryujinx.Headless.SDL2
 
         public NpadManager NpadManager { get; }
         public TouchScreenManager TouchScreenManager { get; }
-        public Switch Device { get; private set; }
+        public Switch Device;
         public IRenderer Renderer { get; private set; }
 
         public event EventHandler<StatusUpdatedEventArgs> StatusUpdatedEvent;
diff --git a/src/Ryujinx.Horizon/Sdk/Settings/LanguageCode.cs b/src/Ryujinx.Horizon/Sdk/Settings/LanguageCode.cs
index dc9712692..759453b69 100644
--- a/src/Ryujinx.Horizon/Sdk/Settings/LanguageCode.cs
+++ b/src/Ryujinx.Horizon/Sdk/Settings/LanguageCode.cs
@@ -26,7 +26,6 @@ namespace Ryujinx.Horizon.Sdk.Settings
             "fr-CA",
             "es-419",
             "zh-Hans",
-            "zh-Hant",
             "pt-BR"
         };
 
diff --git a/src/Ryujinx.Ui.Common/Helper/ValueFormatUtils.cs b/src/Ryujinx.Ui.Common/Helper/ValueFormatUtils.cs
index c203834f5..08e8f940f 100644
--- a/src/Ryujinx.Ui.Common/Helper/ValueFormatUtils.cs
+++ b/src/Ryujinx.Ui.Common/Helper/ValueFormatUtils.cs
@@ -73,7 +73,7 @@ namespace Ryujinx.UI.Common.Helper
         /// <returns>A formatted string that can be displayed in the UI.</returns>
         public static string FormatDateTime(DateTime? utcDateTime, CultureInfo culture = null)
         {
-            culture ??= CultureInfo.CurrentCulture;
+            culture ??= CultureInfo.InvariantCulture;
 
             return utcDateTime?.ToLocalTime().ToString(culture);
         }
@@ -159,7 +159,7 @@ namespace Ryujinx.UI.Common.Helper
         /// <returns>A <see cref="DateTime"/> object. If the input string couldn't be parsed, <see cref="DateTime.UnixEpoch"/> is returned.</returns>
         public static DateTime ParseDateTime(string dateTimeString)
         {
-            if (!DateTime.TryParse(dateTimeString, CultureInfo.CurrentCulture, out DateTime parsedDateTime))
+            if (!DateTime.TryParse(dateTimeString, CultureInfo.InvariantCulture, out DateTime parsedDateTime))
             {
                 // Games that were never played are supposed to appear before the oldest played games in the list,
                 // so returning DateTime.UnixEpoch here makes sense.
diff --git a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs
index 824fdd717..dce24e31d 100644
--- a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs
@@ -1154,7 +1154,7 @@ namespace Ryujinx.Ava.UI.ViewModels
                     return true;
                 }
 
-                CompareInfo compareInfo = CultureInfo.CurrentCulture.CompareInfo;
+                CompareInfo compareInfo = CultureInfo.InvariantCulture.CompareInfo;
 
                 return compareInfo.IndexOf(app.Name, _searchText, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace) >= 0;
             }