diff --git a/src/MeloNX/MeloNX.xcodeproj/project.pbxproj b/src/MeloNX/MeloNX.xcodeproj/project.pbxproj index 303ceca68..a2f79c52a 100644 --- a/src/MeloNX/MeloNX.xcodeproj/project.pbxproj +++ b/src/MeloNX/MeloNX.xcodeproj/project.pbxproj @@ -526,6 +526,7 @@ INFOPLIST_KEY_UILaunchScreen_Generation = YES; INFOPLIST_KEY_UIRequiresFullScreen = YES; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait"; INFOPLIST_KEY_UISupportsDocumentBrowser = YES; IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( @@ -668,6 +669,7 @@ INFOPLIST_KEY_UILaunchScreen_Generation = YES; INFOPLIST_KEY_UIRequiresFullScreen = YES; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait"; INFOPLIST_KEY_UISupportsDocumentBrowser = YES; IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( diff --git a/src/MeloNX/MeloNX.xcodeproj/project.xcworkspace/xcuserdata/stossy11.xcuserdatad/UserInterfaceState.xcuserstate b/src/MeloNX/MeloNX.xcodeproj/project.xcworkspace/xcuserdata/stossy11.xcuserdatad/UserInterfaceState.xcuserstate index ede918aa3..460d69cb1 100644 Binary files a/src/MeloNX/MeloNX.xcodeproj/project.xcworkspace/xcuserdata/stossy11.xcuserdatad/UserInterfaceState.xcuserstate and b/src/MeloNX/MeloNX.xcodeproj/project.xcworkspace/xcuserdata/stossy11.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/src/MeloNX/MeloNX/Core/Swift/Controller/VirtualController.swift b/src/MeloNX/MeloNX/Core/Swift/Controller/VirtualController.swift index 7809ee7ec..3c4a8419e 100644 --- a/src/MeloNX/MeloNX/Core/Swift/Controller/VirtualController.swift +++ b/src/MeloNX/MeloNX/Core/Swift/Controller/VirtualController.swift @@ -123,13 +123,8 @@ class VirtualController { } func thumbstickMoved(_ stick: ThumbstickType, x: Double, y: Double) { - // Convert float values (-1.0 to 1.0) to SDL axis values (-32768 to 32767) - var scaleFactor = 32767.0 - if UIDevice.current.systemName.contains("iPadOS") { - scaleFactor /= (160 * 1.2) - } else { - scaleFactor /= 160 - } + var 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))) diff --git a/src/MeloNX/MeloNX/Core/Swift/Ryujinx.swift b/src/MeloNX/MeloNX/Core/Swift/Ryujinx.swift index 33e9a09fe..4b7212a3d 100644 --- a/src/MeloNX/MeloNX/Core/Swift/Ryujinx.swift +++ b/src/MeloNX/MeloNX/Core/Swift/Ryujinx.swift @@ -39,7 +39,7 @@ class Ryujinx { private init() {} - public struct Configuration : Codable { + public struct Configuration : Codable, Equatable { var gamepath: String var inputids: [String] var resscale: Float diff --git a/src/MeloNX/MeloNX/Models/Game.swift b/src/MeloNX/MeloNX/Models/Game.swift new file mode 100644 index 000000000..e5f0daf0d --- /dev/null +++ b/src/MeloNX/MeloNX/Models/Game.swift @@ -0,0 +1,24 @@ +// +// 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: Image? +} diff --git a/src/MeloNX/MeloNX/Views/ContentView.swift b/src/MeloNX/MeloNX/Views/ContentView.swift index 2516b7e5c..526794279 100644 --- a/src/MeloNX/MeloNX/Views/ContentView.swift +++ b/src/MeloNX/MeloNX/Views/ContentView.swift @@ -10,6 +10,7 @@ import SwiftUI import GameController import Darwin import UIKit +import MetalKit // import SDL struct MoltenVKSettings: Codable, Hashable { @@ -55,12 +56,10 @@ struct ContentView: View { // MARK: - Body var body: some View { - iOSNav { - if let game { - emulationView - } else { - mainMenuView - } + if let game { + emulationView + } else { + mainMenuView } } @@ -73,53 +72,10 @@ struct ContentView: View { } private var mainMenuView: some View { - HStack { - GameListView(startemu: $game) - .onAppear { - 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 { - Button("Refresh", action: refreshControllersList) - ForEach(controllersList, id: \.self) { controller in - controllerRow(for: controller) - } - } header: { - Text("Controllers") - } footer: { - Text("If no controllers are selected, the keyboard will be used.") - .font(.footnote) - .foregroundColor(.gray) - } - } - } - - 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") - } - } } @@ -155,36 +111,24 @@ struct ContentView: View { } - // controllerCallback!() } private func refreshControllersList() { - Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false) { _ in - controllersList = Ryujinx.shared.getConnectedControllers() - - if let onscreen = controllersList.first(where: { $0.name == Ryujinx.shared.virtualController.controllername }) { - self.onscreencontroller = onscreen - } - - 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) - } + controllersList = Ryujinx.shared.getConnectedControllers() + + 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 { diff --git a/src/MeloNX/MeloNX/Views/ControllerView/ControllerView.swift b/src/MeloNX/MeloNX/Views/ControllerView/ControllerView.swift index 0301b75cf..03159c90d 100644 --- a/src/MeloNX/MeloNX/Views/ControllerView/ControllerView.swift +++ b/src/MeloNX/MeloNX/Views/ControllerView/ControllerView.swift @@ -64,12 +64,12 @@ struct ControllerView: View { // Spacer() VStack { // Spacer() - ButtonView(button: .start) // Adding the + button + ButtonView(button: .back) // Adding the + button } Spacer() VStack { // Spacer() - ButtonView(button: .back) // Adding the - button + ButtonView(button: .start) // Adding the - button } // Spacer() } diff --git a/src/MeloNX/MeloNX/Views/GamesList/GameListView.swift b/src/MeloNX/MeloNX/Views/GamesList/GameListView.swift index 71f912bee..28339debd 100644 --- a/src/MeloNX/MeloNX/Views/GamesList/GameListView.swift +++ b/src/MeloNX/MeloNX/Views/GamesList/GameListView.swift @@ -5,41 +5,176 @@ // Created by Stossy11 on 3/11/2024. // -// MARK: - This will most likely not be used in prod import SwiftUI import UniformTypeIdentifiers -public struct Game: Identifiable, Equatable { - public var id = UUID() - var containerFolder: URL - var fileType: UTType +struct MainTabView: View { + @Binding var startemu: URL? + @Binding var config: Ryujinx.Configuration + @Binding var MVKconfig: [MoltenVKSettings] + @Binding var controllersList: [Controller] + @Binding var currentControllers: [Controller] - var fileURL: URL - - var titleName: String - var titleId: String - var developer: String - var version: String - var icon: Image? + @Binding var onscreencontroller: Controller + + var body: some View { + TabView { + GameLibraryView(startemu: $startemu) + .tabItem { + Label("Games", systemImage: "gamecontroller.fill") + } + + SelectControllerView(controllersList: $controllersList, currentControllers: $currentControllers, onscreencontroller: $onscreencontroller) + .tabItem { + Label("Controllers", systemImage: "gamecontroller.fill") + } + + SettingsView(config: $config, MoltenVKSettings: $MVKconfig) + .tabItem { + Label("Settings", systemImage: "gear") + } + } + } } -struct GameListView: View { +struct GameLibraryView: View { @Binding var startemu: 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: \.id) { $game in - Button { - startemu = $game.wrappedValue.fileURL - } label: { - Text(game.titleName) + 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 } @@ -54,7 +189,7 @@ 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) @@ -98,3 +233,147 @@ struct GameListView: View { } } } + +// 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 { + 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 { + 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 0a6b7cf4f..000000000 --- a/src/MeloNX/MeloNX/Views/SDLView/SDLView.swift +++ /dev/null @@ -1,87 +0,0 @@ -// -// VulkanSDLView.swift -// MeloNX -// -// Created by Stossy11 on 3/11/2024. -// - -import UIKit -import MetalKit - -/* -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 dca3452b6..000000000 --- a/src/MeloNX/MeloNX/Views/SDLView/SDLViewRepresentable.swift +++ /dev/null @@ -1,28 +0,0 @@ -// -// VulkanSDLViewRepresentable.swift -// MeloNX -// -// Created by Stossy11 on 3/11/2024. -// - -import UIKit -import SwiftUI -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/SelectController/SelectControllerView.swift b/src/MeloNX/MeloNX/Views/SelectController/SelectControllerView.swift new file mode 100644 index 000000000..d03a0e3e6 --- /dev/null +++ b/src/MeloNX/MeloNX/Views/SelectController/SelectControllerView.swift @@ -0,0 +1,53 @@ +// +// SelectControllerView.swift +// MeloNX +// +// Created by Stossy11 on 9/12/2024. +// + +import SwiftUI + +struct SelectControllerView: View { + + @Binding var controllersList: [Controller] + @Binding var currentControllers: [Controller] + + @Binding var onscreencontroller: Controller + + var body: some View { + List { + + Section { + ForEach(controllersList, id: \.self) { controller in + controllerRow(for: controller) + } + } footer: { + Text("If no controllers are selected, the keyboard will be used.") + .font(.footnote) + .foregroundColor(.gray) + } + } + } + + + 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") + } + } + } + + private func toggleController(_ controller: Controller) { + if currentControllers.contains(where: { $0.id == controller.id }) { + currentControllers.removeAll(where: { $0.id == controller.id }) + } else { + currentControllers.append(controller) + } + } + +} diff --git a/src/MeloNX/MeloNX/Views/SettingsView/SettingsView.swift b/src/MeloNX/MeloNX/Views/SettingsView/SettingsView.swift index bd22061cd..dcd013125 100644 --- a/src/MeloNX/MeloNX/Views/SettingsView/SettingsView.swift +++ b/src/MeloNX/MeloNX/Views/SettingsView/SettingsView.swift @@ -44,7 +44,6 @@ struct SettingsView: View { 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) } @@ -89,10 +88,10 @@ struct SettingsView: View { print(configs) } } - .navigationTitle("Settings") - .navigationBarItems(trailing: Button("Save") { + .onChange(of: config) { newValue in + print(newValue) saveSettings() - }) + } } func saveSettings() { diff --git a/src/Ryujinx.Common/Configuration/AppDataManager.cs b/src/Ryujinx.Common/Configuration/AppDataManager.cs index 010b39dbf..2e7765a15 100644 --- a/src/Ryujinx.Common/Configuration/AppDataManager.cs +++ b/src/Ryujinx.Common/Configuration/AppDataManager.cs @@ -63,8 +63,16 @@ namespace Ryujinx.Common.Configuration { appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); } + string userProfilePath; + if (OperatingSystem.IsIOS()) + { + userProfilePath = appDataPath; + } + else + { + userProfilePath = Path.Combine(appDataPath, DefaultBaseDir); + } - string userProfilePath = Path.Combine(appDataPath, DefaultBaseDir); string portablePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, DefaultPortableDir); if (Directory.Exists(portablePath)) diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRendererBase.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRendererBase.cs index d3831d8f3..43a5df758 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRendererBase.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRendererBase.cs @@ -116,10 +116,10 @@ private void CreateFonts(string uiThemeFontFamily) if (OperatingSystem.IsIOS()) { availableFonts = new string[] { - "Chalkboard", - "Chalkboard", // San Francisco is the default font on iOS - "Chalkboard", // Legacy iOS font - "Chalkboard" // Common system font + "SF Pro", + "New York", + "Helvetica Neue", + "Avenir" }; } else diff --git a/src/Ryujinx.Headless.SDL2/Program.cs b/src/Ryujinx.Headless.SDL2/Program.cs index 79d96eedd..1315c5873 100644 --- a/src/Ryujinx.Headless.SDL2/Program.cs +++ b/src/Ryujinx.Headless.SDL2/Program.cs @@ -958,7 +958,6 @@ namespace Ryujinx.Headless.SDL2 static void Load(Options option) { - AppDataManager.Initialize(option.BaseDataDir); if (_virtualFileSystem == null) {