diff --git a/src/Ryujinx.Headless.SDL2/Program.cs.orig b/src/Ryujinx.Headless.SDL2/Program.cs.orig deleted file mode 100644 index 3dd71bd7c..000000000 --- a/src/Ryujinx.Headless.SDL2/Program.cs.orig +++ /dev/null @@ -1,755 +0,0 @@ -using CommandLine; -using LibHac.Tools.FsSystem; -using Ryujinx.Audio.Backends.SDL2; -using Ryujinx.Common; -using Ryujinx.Common.Configuration; -using Ryujinx.Common.Configuration.Hid; -using Ryujinx.Common.Configuration.Hid.Controller; -using Ryujinx.Common.Configuration.Hid.Controller.Motion; -using Ryujinx.Common.Configuration.Hid.Keyboard; -using Ryujinx.Common.GraphicsDriver; -using Ryujinx.Common.Logging; -using Ryujinx.Common.Logging.Targets; -using Ryujinx.Common.SystemInterop; -using Ryujinx.Common.Utilities; -using Ryujinx.Cpu; -using Ryujinx.Graphics.GAL; -using Ryujinx.Graphics.GAL.Multithreading; -using Ryujinx.Graphics.Gpu; -using Ryujinx.Graphics.Gpu.Shader; -using Ryujinx.Graphics.Metal; -using Ryujinx.Graphics.OpenGL; -using Ryujinx.Graphics.Vulkan; -<<<<<<< HEAD -using Ryujinx.Graphics.Vulkan.MoltenVK; -using Ryujinx.Graphics.Metal; -======= ->>>>>>> 137f5970f (Vertex Input Attributes) -using Ryujinx.Headless.SDL2.Metal; -using Ryujinx.Headless.SDL2.OpenGL; -using Ryujinx.Headless.SDL2.Vulkan; -using Ryujinx.HLE; -using Ryujinx.HLE.FileSystem; -using Ryujinx.HLE.HOS; -using Ryujinx.HLE.HOS.Services.Account.Acc; -using Ryujinx.Input; -using Ryujinx.Input.HLE; -using Ryujinx.Input.SDL2; -using Ryujinx.SDL2.Common; -using Silk.NET.Vulkan; -using System; -using System.Collections.Generic; -using System.IO; -using System.Text.Json; -using System.Threading; -using ConfigGamepadInputId = Ryujinx.Common.Configuration.Hid.Controller.GamepadInputId; -using ConfigStickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId; -using Key = Ryujinx.Common.Configuration.Hid.Key; - -namespace Ryujinx.Headless.SDL2 -{ - class Program - { - public static string Version { get; private set; } - - private static VirtualFileSystem _virtualFileSystem; - private static ContentManager _contentManager; - private static AccountManager _accountManager; - private static LibHacHorizonManager _libHacHorizonManager; - private static UserChannelPersistence _userChannelPersistence; - private static InputManager _inputManager; - private static Switch _emulationContext; - private static WindowBase _window; - private static WindowsMultimediaTimerResolution _windowsMultimediaTimerResolution; - private static List _inputConfiguration; - private static bool _enableKeyboard; - private static bool _enableMouse; - - private static readonly InputConfigJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions()); - - static void Main(string[] args) - { - Version = ReleaseInformation.Version; - - // Make process DPI aware for proper window sizing on high-res screens. - ForceDpiAware.Windows(); - - Console.Title = $"Ryujinx Console {Version} (Headless SDL2)"; - - if (OperatingSystem.IsMacOS() || OperatingSystem.IsLinux()) - { - AutoResetEvent invoked = new(false); - - // MacOS must perform SDL polls from the main thread. - SDL2Driver.MainThreadDispatcher = action => - { - invoked.Reset(); - - WindowBase.QueueMainThreadAction(() => - { - action(); - - invoked.Set(); - }); - - invoked.WaitOne(); - }; - } - - if (OperatingSystem.IsMacOS()) - { - MVKInitialization.InitializeResolver(); - } - - Parser.Default.ParseArguments(args) - .WithParsed(Load) - .WithNotParsed(errors => errors.Output()); - } - - private static InputConfig HandlePlayerConfiguration(string inputProfileName, string inputId, PlayerIndex index) - { - if (inputId == null) - { - if (index == PlayerIndex.Player1) - { - Logger.Info?.Print(LogClass.Application, $"{index} not configured, defaulting to default keyboard."); - - // Default to keyboard - inputId = "0"; - } - else - { - Logger.Info?.Print(LogClass.Application, $"{index} not configured"); - - return null; - } - } - - IGamepad gamepad; - - bool isKeyboard = true; - - gamepad = _inputManager.KeyboardDriver.GetGamepad(inputId); - - if (gamepad == null) - { - gamepad = _inputManager.GamepadDriver.GetGamepad(inputId); - isKeyboard = false; - - if (gamepad == null) - { - Logger.Error?.Print(LogClass.Application, $"{index} gamepad not found (\"{inputId}\")"); - - return null; - } - } - - string gamepadName = gamepad.Name; - - gamepad.Dispose(); - - InputConfig config; - - if (inputProfileName == null || inputProfileName.Equals("default")) - { - if (isKeyboard) - { - config = new StandardKeyboardInputConfig - { - Version = InputConfig.CurrentVersion, - Backend = InputBackendType.WindowKeyboard, - Id = null, - ControllerType = ControllerType.JoyconPair, - LeftJoycon = new LeftJoyconCommonConfig - { - DpadUp = Key.Up, - DpadDown = Key.Down, - DpadLeft = Key.Left, - DpadRight = Key.Right, - ButtonMinus = Key.Minus, - ButtonL = Key.E, - ButtonZl = Key.Q, - ButtonSl = Key.Unbound, - ButtonSr = Key.Unbound, - }, - - LeftJoyconStick = new JoyconConfigKeyboardStick - { - StickUp = Key.W, - StickDown = Key.S, - StickLeft = Key.A, - StickRight = Key.D, - StickButton = Key.F, - }, - - RightJoycon = new RightJoyconCommonConfig - { - ButtonA = Key.Z, - ButtonB = Key.X, - ButtonX = Key.C, - ButtonY = Key.V, - ButtonPlus = Key.Plus, - ButtonR = Key.U, - ButtonZr = Key.O, - ButtonSl = Key.Unbound, - ButtonSr = Key.Unbound, - }, - - RightJoyconStick = new JoyconConfigKeyboardStick - { - StickUp = Key.I, - StickDown = Key.K, - StickLeft = Key.J, - StickRight = Key.L, - StickButton = Key.H, - }, - }; - } - else - { - bool isNintendoStyle = gamepadName.Contains("Nintendo"); - - config = new StandardControllerInputConfig - { - Version = InputConfig.CurrentVersion, - Backend = InputBackendType.GamepadSDL2, - Id = null, - ControllerType = ControllerType.JoyconPair, - DeadzoneLeft = 0.1f, - DeadzoneRight = 0.1f, - RangeLeft = 1.0f, - RangeRight = 1.0f, - TriggerThreshold = 0.5f, - LeftJoycon = new LeftJoyconCommonConfig - { - DpadUp = ConfigGamepadInputId.DpadUp, - DpadDown = ConfigGamepadInputId.DpadDown, - DpadLeft = ConfigGamepadInputId.DpadLeft, - DpadRight = ConfigGamepadInputId.DpadRight, - ButtonMinus = ConfigGamepadInputId.Minus, - ButtonL = ConfigGamepadInputId.LeftShoulder, - ButtonZl = ConfigGamepadInputId.LeftTrigger, - ButtonSl = ConfigGamepadInputId.Unbound, - ButtonSr = ConfigGamepadInputId.Unbound, - }, - - LeftJoyconStick = new JoyconConfigControllerStick - { - Joystick = ConfigStickInputId.Left, - StickButton = ConfigGamepadInputId.LeftStick, - InvertStickX = false, - InvertStickY = false, - Rotate90CW = false, - }, - - RightJoycon = new RightJoyconCommonConfig - { - ButtonA = isNintendoStyle ? ConfigGamepadInputId.A : ConfigGamepadInputId.B, - ButtonB = isNintendoStyle ? ConfigGamepadInputId.B : ConfigGamepadInputId.A, - ButtonX = isNintendoStyle ? ConfigGamepadInputId.X : ConfigGamepadInputId.Y, - ButtonY = isNintendoStyle ? ConfigGamepadInputId.Y : ConfigGamepadInputId.X, - ButtonPlus = ConfigGamepadInputId.Plus, - ButtonR = ConfigGamepadInputId.RightShoulder, - ButtonZr = ConfigGamepadInputId.RightTrigger, - ButtonSl = ConfigGamepadInputId.Unbound, - ButtonSr = ConfigGamepadInputId.Unbound, - }, - - RightJoyconStick = new JoyconConfigControllerStick - { - Joystick = ConfigStickInputId.Right, - StickButton = ConfigGamepadInputId.RightStick, - InvertStickX = false, - InvertStickY = false, - Rotate90CW = false, - }, - - Motion = new StandardMotionConfigController - { - MotionBackend = MotionInputBackendType.GamepadDriver, - EnableMotion = true, - Sensitivity = 100, - GyroDeadzone = 1, - }, - Rumble = new RumbleConfigController - { - StrongRumble = 1f, - WeakRumble = 1f, - EnableRumble = false, - }, - }; - } - } - else - { - string profileBasePath; - - if (isKeyboard) - { - profileBasePath = Path.Combine(AppDataManager.ProfilesDirPath, "keyboard"); - } - else - { - profileBasePath = Path.Combine(AppDataManager.ProfilesDirPath, "controller"); - } - - string path = Path.Combine(profileBasePath, inputProfileName + ".json"); - - if (!File.Exists(path)) - { - Logger.Error?.Print(LogClass.Application, $"Input profile \"{inputProfileName}\" not found for \"{inputId}\""); - - return null; - } - - try - { - config = JsonHelper.DeserializeFromFile(path, _serializerContext.InputConfig); - } - catch (JsonException) - { - Logger.Error?.Print(LogClass.Application, $"Input profile \"{inputProfileName}\" parsing failed for \"{inputId}\""); - - return null; - } - } - - config.Id = inputId; - config.PlayerIndex = index; - - string inputTypeName = isKeyboard ? "Keyboard" : "Gamepad"; - - Logger.Info?.Print(LogClass.Application, $"{config.PlayerIndex} configured with {inputTypeName} \"{config.Id}\""); - - // If both stick ranges are 0 (usually indicative of an outdated profile load) then both sticks will be set to 1.0. - if (config is StandardControllerInputConfig controllerConfig) - { - if (controllerConfig.RangeLeft <= 0.0f && controllerConfig.RangeRight <= 0.0f) - { - controllerConfig.RangeLeft = 1.0f; - controllerConfig.RangeRight = 1.0f; - - Logger.Info?.Print(LogClass.Application, $"{config.PlayerIndex} stick range reset. Save the profile now to update your configuration"); - } - } - - return config; - } - - static void Load(Options option) - { - AppDataManager.Initialize(option.BaseDataDir); - - _virtualFileSystem = VirtualFileSystem.CreateInstance(); - _libHacHorizonManager = new LibHacHorizonManager(); - - _libHacHorizonManager.InitializeFsServer(_virtualFileSystem); - _libHacHorizonManager.InitializeArpServer(); - _libHacHorizonManager.InitializeBcatServer(); - _libHacHorizonManager.InitializeSystemClients(); - - _contentManager = new ContentManager(_virtualFileSystem); - _accountManager = new AccountManager(_libHacHorizonManager.RyujinxClient, option.UserProfile); - _userChannelPersistence = new UserChannelPersistence(); - - _inputManager = new InputManager(new SDL2KeyboardDriver(), new SDL2GamepadDriver()); - - GraphicsConfig.EnableShaderCache = true; - - if (OperatingSystem.IsMacOS()) - { - if (option.GraphicsBackend == GraphicsBackend.OpenGl) - { - option.GraphicsBackend = GraphicsBackend.Vulkan; - Logger.Warning?.Print(LogClass.Application, "OpenGL is not supported on macOS, switching to Vulkan!"); - } - } - - IGamepad gamepad; - - if (option.ListInputIds) - { - Logger.Info?.Print(LogClass.Application, "Input Ids:"); - - foreach (string id in _inputManager.KeyboardDriver.GamepadsIds) - { - gamepad = _inputManager.KeyboardDriver.GetGamepad(id); - - Logger.Info?.Print(LogClass.Application, $"- {id} (\"{gamepad.Name}\")"); - - gamepad.Dispose(); - } - - foreach (string id in _inputManager.GamepadDriver.GamepadsIds) - { - gamepad = _inputManager.GamepadDriver.GetGamepad(id); - - Logger.Info?.Print(LogClass.Application, $"- {id} (\"{gamepad.Name}\")"); - - gamepad.Dispose(); - } - - return; - } - - if (option.InputPath == null) - { - Logger.Error?.Print(LogClass.Application, "Please provide a file to load"); - - return; - } - - _inputConfiguration = new List(); - _enableKeyboard = option.EnableKeyboard; - _enableMouse = option.EnableMouse; - - static void LoadPlayerConfiguration(string inputProfileName, string inputId, PlayerIndex index) - { - InputConfig inputConfig = HandlePlayerConfiguration(inputProfileName, inputId, index); - - if (inputConfig != null) - { - _inputConfiguration.Add(inputConfig); - } - } - - LoadPlayerConfiguration(option.InputProfile1Name, option.InputId1, PlayerIndex.Player1); - LoadPlayerConfiguration(option.InputProfile2Name, option.InputId2, PlayerIndex.Player2); - LoadPlayerConfiguration(option.InputProfile3Name, option.InputId3, PlayerIndex.Player3); - LoadPlayerConfiguration(option.InputProfile4Name, option.InputId4, PlayerIndex.Player4); - LoadPlayerConfiguration(option.InputProfile5Name, option.InputId5, PlayerIndex.Player5); - LoadPlayerConfiguration(option.InputProfile6Name, option.InputId6, PlayerIndex.Player6); - LoadPlayerConfiguration(option.InputProfile7Name, option.InputId7, PlayerIndex.Player7); - LoadPlayerConfiguration(option.InputProfile8Name, option.InputId8, PlayerIndex.Player8); - LoadPlayerConfiguration(option.InputProfileHandheldName, option.InputIdHandheld, PlayerIndex.Handheld); - - if (_inputConfiguration.Count == 0) - { - return; - } - - // Setup logging level - Logger.SetEnable(LogLevel.Debug, option.LoggingEnableDebug); - Logger.SetEnable(LogLevel.Stub, !option.LoggingDisableStub); - Logger.SetEnable(LogLevel.Info, !option.LoggingDisableInfo); - Logger.SetEnable(LogLevel.Warning, !option.LoggingDisableWarning); - Logger.SetEnable(LogLevel.Error, option.LoggingEnableError); - Logger.SetEnable(LogLevel.Trace, option.LoggingEnableTrace); - Logger.SetEnable(LogLevel.Guest, !option.LoggingDisableGuest); - Logger.SetEnable(LogLevel.AccessLog, option.LoggingEnableFsAccessLog); - - if (!option.DisableFileLog) - { - string logDir = AppDataManager.LogsDirPath; - FileStream logFile = null; - - if (!string.IsNullOrEmpty(logDir)) - { - logFile = FileLogTarget.PrepareLogFile(logDir); - } - - if (logFile != null) - { - Logger.AddTarget(new AsyncLogTargetWrapper( - new FileLogTarget("file", logFile), - 1000, - AsyncLogTargetOverflowAction.Block - )); - } - else - { - Logger.Error?.Print(LogClass.Application, "No writable log directory available. Make sure either the Logs directory, Application Data, or the Ryujinx directory is writable."); - } - } - - // Setup graphics configuration - GraphicsConfig.EnableShaderCache = !option.DisableShaderCache; - GraphicsConfig.EnableTextureRecompression = option.EnableTextureRecompression; - GraphicsConfig.ResScale = option.ResScale; - GraphicsConfig.MaxAnisotropy = option.MaxAnisotropy; - GraphicsConfig.ShadersDumpPath = option.GraphicsShadersDumpPath; - GraphicsConfig.EnableMacroHLE = !option.DisableMacroHLE; - - DriverUtilities.InitDriverConfig(option.BackendThreading == BackendThreading.Off); - - while (true) - { - LoadApplication(option); - - if (_userChannelPersistence.PreviousIndex == -1 || !_userChannelPersistence.ShouldRestart) - { - break; - } - - _userChannelPersistence.ShouldRestart = false; - } - - _inputManager.Dispose(); - } - - private static void SetupProgressHandler() - { - if (_emulationContext.Processes.ActiveApplication.DiskCacheLoadState != null) - { - _emulationContext.Processes.ActiveApplication.DiskCacheLoadState.StateChanged -= ProgressHandler; - _emulationContext.Processes.ActiveApplication.DiskCacheLoadState.StateChanged += ProgressHandler; - } - - _emulationContext.Gpu.ShaderCacheStateChanged -= ProgressHandler; - _emulationContext.Gpu.ShaderCacheStateChanged += ProgressHandler; - } - - private static void ProgressHandler(T state, int current, int total) where T : Enum - { - string label = state switch - { - LoadState => $"PTC : {current}/{total}", - ShaderCacheState => $"Shaders : {current}/{total}", - _ => throw new ArgumentException($"Unknown Progress Handler type {typeof(T)}"), - }; - - Logger.Info?.Print(LogClass.Application, label); - } - - private static WindowBase CreateWindow(Options options) - { - return options.GraphicsBackend switch - { - GraphicsBackend.Vulkan => new VulkanWindow(_inputManager, options.LoggingGraphicsDebugLevel, options.AspectRatio, options.EnableMouse, options.HideCursorMode), - GraphicsBackend.Metal => new MetalWindow(_inputManager, options.LoggingGraphicsDebugLevel, options.AspectRatio, options.EnableKeyboard, options.HideCursorMode), - _ => new OpenGLWindow(_inputManager, options.LoggingGraphicsDebugLevel, options.AspectRatio, options.EnableMouse, options.HideCursorMode) - }; - } - - private static IRenderer CreateRenderer(Options options, WindowBase window) - { - if (options.GraphicsBackend == GraphicsBackend.Vulkan && window is VulkanWindow vulkanWindow) - { - string preferredGpuId = string.Empty; - Vk api = Vk.GetApi(); - - if (!string.IsNullOrEmpty(options.PreferredGPUVendor)) - { - string preferredGpuVendor = options.PreferredGPUVendor.ToLowerInvariant(); - var devices = VulkanRenderer.GetPhysicalDevices(api); - - foreach (var device in devices) - { - if (device.Vendor.ToLowerInvariant() == preferredGpuVendor) - { - preferredGpuId = device.Id; - break; - } - } - } - - return new VulkanRenderer( - api, - (instance, vk) => new SurfaceKHR((ulong)(vulkanWindow.CreateWindowSurface(instance.Handle))), - vulkanWindow.GetRequiredInstanceExtensions, - preferredGpuId); - } - - if (options.GraphicsBackend == GraphicsBackend.Metal && window is MetalWindow metalWindow && OperatingSystem.IsMacOS()) - { - return new MetalRenderer(metalWindow.GetLayer); - } - - return new OpenGLRenderer(); - } - - private static Switch InitializeEmulationContext(WindowBase window, IRenderer renderer, Options options) - { - BackendThreading threadingMode = options.BackendThreading; - - bool threadedGAL = threadingMode == BackendThreading.On || (threadingMode == BackendThreading.Auto && renderer.PreferThreading); - - if (threadedGAL) - { - renderer = new ThreadedRenderer(renderer); - } - - HLEConfiguration configuration = new(_virtualFileSystem, - _libHacHorizonManager, - _contentManager, - _accountManager, - _userChannelPersistence, - renderer, - new SDL2HardwareDeviceDriver(), - options.ExpandRAM ? MemoryConfiguration.MemoryConfiguration6GiB : MemoryConfiguration.MemoryConfiguration4GiB, - window, - options.SystemLanguage, - options.SystemRegion, - !options.DisableVSync, - !options.DisableDockedMode, - !options.DisablePTC, - options.EnableInternetAccess, - !options.DisableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None, - options.FsGlobalAccessLogMode, - options.SystemTimeOffset, - options.SystemTimeZone, - options.MemoryManagerMode, - options.IgnoreMissingServices, - options.AspectRatio, - options.AudioVolume, - options.UseHypervisor ?? true, - options.MultiplayerLanInterfaceId, - Common.Configuration.Multiplayer.MultiplayerMode.Disabled); - - return new Switch(configuration); - } - - private static void ExecutionEntrypoint() - { - if (OperatingSystem.IsWindows()) - { - _windowsMultimediaTimerResolution = new WindowsMultimediaTimerResolution(1); - } - - DisplaySleep.Prevent(); - - _window.Initialize(_emulationContext, _inputConfiguration, _enableKeyboard, _enableMouse); - - _window.Execute(); - - _emulationContext.Dispose(); - _window.Dispose(); - - if (OperatingSystem.IsWindows()) - { - _windowsMultimediaTimerResolution?.Dispose(); - _windowsMultimediaTimerResolution = null; - } - } - - private static bool LoadApplication(Options options) - { - string path = options.InputPath; - - Logger.RestartTime(); - - WindowBase window = CreateWindow(options); - IRenderer renderer = CreateRenderer(options, window); - - _window = window; - - _window.IsFullscreen = options.IsFullscreen; - _window.DisplayId = options.DisplayId; - _window.IsExclusiveFullscreen = options.IsExclusiveFullscreen; - _window.ExclusiveFullscreenWidth = options.ExclusiveFullscreenWidth; - _window.ExclusiveFullscreenHeight = options.ExclusiveFullscreenHeight; - _window.AntiAliasing = options.AntiAliasing; - _window.ScalingFilter = options.ScalingFilter; - _window.ScalingFilterLevel = options.ScalingFilterLevel; - - _emulationContext = InitializeEmulationContext(window, renderer, options); - - SystemVersion firmwareVersion = _contentManager.GetCurrentFirmwareVersion(); - - Logger.Notice.Print(LogClass.Application, $"Using Firmware Version: {firmwareVersion?.VersionString}"); - - if (Directory.Exists(path)) - { - string[] romFsFiles = Directory.GetFiles(path, "*.istorage"); - - if (romFsFiles.Length == 0) - { - romFsFiles = Directory.GetFiles(path, "*.romfs"); - } - - if (romFsFiles.Length > 0) - { - Logger.Info?.Print(LogClass.Application, "Loading as cart with RomFS."); - - if (!_emulationContext.LoadCart(path, romFsFiles[0])) - { - _emulationContext.Dispose(); - - return false; - } - } - else - { - Logger.Info?.Print(LogClass.Application, "Loading as cart WITHOUT RomFS."); - - if (!_emulationContext.LoadCart(path)) - { - _emulationContext.Dispose(); - - return false; - } - } - } - else if (File.Exists(path)) - { - switch (Path.GetExtension(path).ToLowerInvariant()) - { - case ".xci": - Logger.Info?.Print(LogClass.Application, "Loading as XCI."); - - if (!_emulationContext.LoadXci(path)) - { - _emulationContext.Dispose(); - - return false; - } - break; - case ".nca": - Logger.Info?.Print(LogClass.Application, "Loading as NCA."); - - if (!_emulationContext.LoadNca(path)) - { - _emulationContext.Dispose(); - - return false; - } - break; - case ".nsp": - case ".pfs0": - Logger.Info?.Print(LogClass.Application, "Loading as NSP."); - - if (!_emulationContext.LoadNsp(path)) - { - _emulationContext.Dispose(); - - return false; - } - break; - default: - Logger.Info?.Print(LogClass.Application, "Loading as Homebrew."); - try - { - if (!_emulationContext.LoadProgram(path)) - { - _emulationContext.Dispose(); - - return false; - } - } - catch (ArgumentOutOfRangeException) - { - Logger.Error?.Print(LogClass.Application, "The specified file is not supported by Ryujinx."); - - _emulationContext.Dispose(); - - return false; - } - break; - } - } - else - { - Logger.Warning?.Print(LogClass.Application, $"Couldn't load '{options.InputPath}'. Please specify a valid XCI/NCA/NSP/PFS0/NRO file."); - - _emulationContext.Dispose(); - - return false; - } - - SetupProgressHandler(); - ExecutionEntrypoint(); - - return true; - } - } -}