diff --git a/Pomelo/ContentView.swift b/Pomelo/ContentView.swift index 1728047..57af733 100644 --- a/Pomelo/ContentView.swift +++ b/Pomelo/ContentView.swift @@ -7,9 +7,13 @@ import SwiftUI import Sudachi +import Foundation +import UIKit struct ContentView: View { + @AppStorage("icloudsaves") var icloudsaves: Bool = false + @AppStorage("useTrollStore") var useTrollStore: Bool = false @State var core = Core(games: [], root: FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]) var body: some View { //NavView(core: $core) // pain and suffering @@ -23,10 +27,11 @@ struct ContentView: View { let isJIT = UserDefaults.standard.bool(forKey: "JIT-ENABLED") - if !isJIT { + if !isJIT, useTrollStore { askForJIT() } + // checkFoldersInICloud() do { try PomeloFileManager.shared.createdirectories() // this took a while to create the proper directories @@ -43,5 +48,6 @@ struct ContentView: View { } } } -} + +} diff --git a/Pomelo/Emulation/ControllerView/ControllerView.swift b/Pomelo/Emulation/ControllerView/ControllerView.swift index b2be8fb..4868ef9 100644 --- a/Pomelo/Emulation/ControllerView/ControllerView.swift +++ b/Pomelo/Emulation/ControllerView/ControllerView.swift @@ -189,7 +189,7 @@ struct ControllerView: View { let accelY = motion.gravity.y + motion.userAcceleration.y let accelZ = motion.gravity.z + motion.userAcceleration.z - print("\(gyroX), \(gyroY), \(gyroZ), \(accelX), \(accelY), \(accelZ)") + // print("\(gyroX), \(gyroY), \(gyroZ), \(accelX), \(accelY), \(accelZ)") // Call your gyroMoved function with the motion data sudachi.gyroMoved(x: Float(gyroX), y: Float(gyroY), z: Float(gyroZ), accelX: Float(accelX), accelY: Float(accelY), accelZ: Float(accelZ), controllerId: Int32(controllerId), deltaTimestamp: Int32(lastTimestamp)) @@ -306,7 +306,7 @@ struct OnScreenController: View { } } - // .                                                                                                     padding(.bottom, geometry.size.height / 11) // also extremally broken ( + // .padding(.bottom, geometry.size.height / 11) // also extremally broken ( } } } @@ -394,7 +394,7 @@ struct ButtonView: View { .resizable() .frame(width: width, height: height) .foregroundColor(colorScheme == .dark ? Color.gray : Color.gray) - .opacity(isPressed ? 0.5 : 1) + .opacity(isPressed ? 0.4 : 0.7) .gesture( DragGesture(minimumDistance: 0) .onChanged { _ in diff --git a/Pomelo/Emulation/ControllerView/Joystick/JoystickView.swift b/Pomelo/Emulation/ControllerView/Joystick/JoystickView.swift index 4979238..433a5d0 100644 --- a/Pomelo/Emulation/ControllerView/Joystick/JoystickView.swift +++ b/Pomelo/Emulation/ControllerView/Joystick/JoystickView.swift @@ -33,17 +33,14 @@ public struct Joystick: View { width: self.dragDiameter, shape: .circle, background: { - // Example Background - RoundedRectangle(cornerRadius: 8).fill(Color.gray.opacity(0)) + Text("") + .hidden() }, foreground: { - // Example Thumb Circle().fill(Color.gray) + .opacity(0.7) }, locksInPlace: false) - .onTapGesture { - Haptics.shared.play(.light) - } .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 :/ (well it appears that with the new joystick code, its supposed to be -y) diff --git a/Pomelo/Emulation/EmulationHandlers/SudachiEmulationHandler.swift b/Pomelo/Emulation/EmulationHandlers/SudachiEmulationHandler.swift index 22a79c5..8b690f4 100644 --- a/Pomelo/Emulation/EmulationHandlers/SudachiEmulationHandler.swift +++ b/Pomelo/Emulation/EmulationHandlers/SudachiEmulationHandler.swift @@ -39,7 +39,11 @@ class SudachiEmulationViewModel: ObservableObject { DispatchQueue.global(qos: .userInitiated).async { [self] in if let sudachiGame = self.sudachiGame { - self.sudachi.insert(game: sudachiGame.fileURL) + if sudachiGame.fileURL == URL(string: "BootMii") { + self.sudachi.bootMii() + } else { + self.sudachi.insert(game: sudachiGame.fileURL) + } } else { self.sudachi.bootOS() } diff --git a/Pomelo/FilesManager/FileManager.swift b/Pomelo/FilesManager/FileManager.swift index 69074bf..17134d4 100644 --- a/Pomelo/FilesManager/FileManager.swift +++ b/Pomelo/FilesManager/FileManager.swift @@ -48,7 +48,8 @@ class PomeloFileManager { static var shared = PomeloFileManager() func directories() -> [String : [String : String]] { - [ + + var folders: [String : [String : String]] = [ "themes" : [:], "amiibo" : [:], "cache" : [:], @@ -67,6 +68,29 @@ class PomeloFileManager { "tas" : [:], "icons" : [:] ] + + if UserDefaults.standard.bool(forKey: "icloudsaves") { + folders = [ + "themes" : [:], + "amiibo" : [:], + "cache" : [:], + "config" : [:], + "crash_dumps" : [:], + "dump" : [:], + "keys" : [:], + "load" : [:], + "log" : [:], + "play_time" : [:], + "roms" : [:], + "screenshots" : [:], + "sdmc" : [:], + "shader" : [:], + "tas" : [:], + "icons" : [:] + ] + + } + return folders as! [String : [String : String]] } func createdirectories() throws { diff --git a/Pomelo/JITClasses/Trollstore/AskForJIT.swift b/Pomelo/JITClasses/Trollstore/AskForJIT.swift index 2c4f36f..8603ef6 100644 --- a/Pomelo/JITClasses/Trollstore/AskForJIT.swift +++ b/Pomelo/JITClasses/Trollstore/AskForJIT.swift @@ -10,20 +10,14 @@ import Foundation import UIKit func askForJIT() { - let bundlePath = Bundle.main.bundleURL.deletingLastPathComponent() - let tsPath = bundlePath.appendingPathComponent("_TrollStore").path - // Check if TrollStore exists by checking the presence of the directory - if FileManager.default.fileExists(atPath: tsPath) { - // Construct the URL scheme for enabling JIT - let urlScheme = "apple-magnifier://enable-jit?bundle-id=\(Bundle.main.bundleIdentifier!)" - if let launchURL = URL(string: urlScheme) { - if UIApplication.shared.canOpenURL(launchURL) { - // Open the URL to enable JIT - UIApplication.shared.open(launchURL, options: [:], completionHandler: nil) - - return - } + let urlScheme = "apple-magnifier://enable-jit?bundle-id=\(Bundle.main.bundleIdentifier!)" + if let launchURL = URL(string: urlScheme) { + if UIApplication.shared.canOpenURL(launchURL) { + // Open the URL to enable JIT + UIApplication.shared.open(launchURL, options: [:], completionHandler: nil) + + return } } diff --git a/Pomelo/LibraryViews/LibraryView.swift b/Pomelo/LibraryViews/LibraryView.swift index f0ce07d..4b3a355 100644 --- a/Pomelo/LibraryViews/LibraryView.swift +++ b/Pomelo/LibraryViews/LibraryView.swift @@ -22,7 +22,6 @@ struct LibraryView: View { print("Getting Roms...") do { _core = State(wrappedValue: try LibraryManager.shared.library()) - print(core.games) } catch { print("Failed to fetch library: \(error)") } @@ -70,7 +69,6 @@ struct LibraryView: View { print("Getting Roms...") do { core = try LibraryManager.shared.library() - print(core.games) } catch { print("Failed to fetch library: \(error)") return diff --git a/Pomelo/LibraryViews/Menu/TopBarView.swift b/Pomelo/LibraryViews/Menu/TopBarView.swift index 3ff1d95..f687cfc 100644 --- a/Pomelo/LibraryViews/Menu/TopBarView.swift +++ b/Pomelo/LibraryViews/Menu/TopBarView.swift @@ -8,11 +8,14 @@ import SwiftUI import Combine +import Sudachi struct TopBarView: View { @State private var currentDate: Date = Date() @State private var batteryLevel: Float = UIDevice.current.batteryLevel @State private var batteryState: UIDevice.BatteryState = UIDevice.current.batteryState + @State private var creatinguser: Bool = false + @State private var username: String = "" private var timer: Publishers.Autoconnect { Timer.publish(every: 60, on: .main, in: .common).autoconnect() // Update every minute @@ -23,10 +26,35 @@ struct TopBarView: View { let minutes = Calendar.current.component(.minute, from: currentDate) HStack { - Image(systemName: "person.crop.circle.fill") - .resizable() - .frame(width: 40, height: 40) + NavigationLink { + SudachiEmulationView(game: PomeloGame(developer: "", fileURL: URL(string: "BootMii")!, imageData: Data(), title: "BootOS")) + } label: { + Image(systemName: "person.crop.circle.fill") + .resizable() + .frame(width: 40, height: 40) + } + + /* + Button { + creatinguser.toggle() + } label: { + Image(systemName: "person.crop.circle.fill") + .resizable() + .frame(width: 40, height: 40) + } + .alert("Create User", isPresented: $creatinguser) { + TextField("username", text: $username) + .onSubmit { + let sudachi = Sudachi.shared + if sudachi.createUser(uuid: UUID(), username: username) { + print("Created User \(username)") + } else { + print("Failed to Create User \(username)") + } + } + } + */ Spacer() Text("\(hour % 12 == 0 ? 12 : hour % 12):\(String(format: "%02d", minutes)) \(hour >= 12 ? "PM" : "AM")") diff --git a/Pomelo/Pomelo.entitlements b/Pomelo/Pomelo.entitlements index 5f13871..e3c95ee 100644 --- a/Pomelo/Pomelo.entitlements +++ b/Pomelo/Pomelo.entitlements @@ -2,8 +2,20 @@ + com.apple.developer.icloud-container-identifiers + + iCloud.com.stossy11.Pomelo + + com.apple.developer.icloud-services + + CloudDocuments + com.apple.developer.kernel.increased-memory-limit + com.apple.developer.ubiquity-container-identifiers + + iCloud.com.stossy11.Pomelo + com.apple.security.app-sandbox com.apple.security.files.user-selected.read-only diff --git a/Pomelo/PomeloDebug.entitlements b/Pomelo/PomeloDebug.entitlements index 5f13871..e3c95ee 100644 --- a/Pomelo/PomeloDebug.entitlements +++ b/Pomelo/PomeloDebug.entitlements @@ -2,8 +2,20 @@ + com.apple.developer.icloud-container-identifiers + + iCloud.com.stossy11.Pomelo + + com.apple.developer.icloud-services + + CloudDocuments + com.apple.developer.kernel.increased-memory-limit + com.apple.developer.ubiquity-container-identifiers + + iCloud.com.stossy11.Pomelo + com.apple.security.app-sandbox com.apple.security.files.user-selected.read-only diff --git a/Pomelo/ScreenshotManager/ScreenShotListView.swift b/Pomelo/ScreenshotManager/ScreenShotListView.swift index 897fc6c..2a8ed60 100644 --- a/Pomelo/ScreenshotManager/ScreenShotListView.swift +++ b/Pomelo/ScreenshotManager/ScreenShotListView.swift @@ -89,7 +89,6 @@ struct ScreenshotGridView: View { } print(gameID) - print(core.games) // Decode the date string from URL encoding let decodedDateString = dateString.replacingOccurrences(of: "%20", with: " ") diff --git a/Pomelo/SettingsViews/AdvancedSettings/AdvancedSettingsView.swift b/Pomelo/SettingsViews/AdvancedSettings/AdvancedSettingsView.swift index 4882ce5..7140a2c 100644 --- a/Pomelo/SettingsViews/AdvancedSettings/AdvancedSettingsView.swift +++ b/Pomelo/SettingsViews/AdvancedSettings/AdvancedSettingsView.swift @@ -7,14 +7,19 @@ import SwiftUI import UniformTypeIdentifiers +import Foundation struct AdvancedSettingsView: View { + @AppStorage("icloudsaves2") var icloudsaves: Bool = false @AppStorage("isfullscreen") var isFullScreen: Bool = false @AppStorage("exitgame") var exitgame: Bool = false @AppStorage("ClearBackingRegion") var kpagetable: Bool = false @AppStorage("WaitingforJIT") var waitingJIT: Bool = false @AppStorage("cangetfullpath") var canGetFullPath: Bool = false @AppStorage("onscreenhandheld") var onscreenjoy: Bool = false + + @State var isshowing = false + var body: some View { ScrollView { Rectangle() @@ -31,6 +36,30 @@ struct AdvancedSettingsView: View { .padding(.bottom) .font(.footnote) .foregroundColor(.gray) + /* + Rectangle() + .fill(Color(uiColor: UIColor.secondarySystemBackground)) + .cornerRadius(10) + .frame(width: .infinity, height: 50) + .overlay() { + HStack { + Toggle("iCloud Saves", isOn: $icloudsaves) + .padding() + .onChange(of: icloudsaves) { value in + if value { + // moveFoldersToICloud() + } else { + // restoreFoldersFromiCloud() + } + } + } + } + Text("This enables iCloud storage for game saves, ensuring your progress syncs seamlessly across all your devices. WARNING: You will loose all your game saves on other devices.") + .padding(.bottom) + .font(.footnote) + .foregroundColor(.gray) + */ + Rectangle() .fill(Color(uiColor: UIColor.secondarySystemBackground)) .cornerRadius(10) @@ -90,5 +119,96 @@ struct AdvancedSettingsView: View { .font(.footnote) .foregroundColor(.gray) } + .onAppear() { + // isshowing = true + } + .onDisappear() { + // isshowing = false + } + } +} + +func moveFoldersToICloud() { + let fileManager = FileManager.default + + // Get the app's Documents directory + let documentsPath = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first! + + // Paths to your original folders in your app's Documents directory + let nandOriginalPath = documentsPath.appendingPathComponent("nand").path + + // Create backup directory path + let backupPath = documentsPath.appendingPathComponent("backup").path + + // iCloud Documents directory + if let iCloudURL = fileManager.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents") { + let nandICloudPath = iCloudURL.appendingPathComponent("nand") + + do { + // Create backup folder if it doesn't exist + if !fileManager.fileExists(atPath: backupPath) { + try fileManager.createDirectory(atPath: backupPath, withIntermediateDirectories: true, attributes: nil) + } + + // Backup the nand folder + let nandBackupPath = backupPath + "/nand" + if !fileManager.fileExists(atPath: nandBackupPath) { + try fileManager.copyItem(atPath: nandOriginalPath, toPath: nandBackupPath) + print("Backup created for nand folder at \(nandBackupPath)") + } + + // Backup the shader folder + + // Move the nand folder to iCloud + try fileManager.moveItem(atPath: nandOriginalPath, toPath: nandICloudPath.path) + print("Moved nand folder to iCloud.") + + // Move the shader folder to iCloud + + // Create symlink for nand + try fileManager.createSymbolicLink(atPath: nandOriginalPath, withDestinationPath: nandICloudPath.path) + print("Created symlink for nand.") + + // Create symlink for shader + print("Folders moved to iCloud and symlinks created successfully.") + + } catch { + print("Error: \(error.localizedDescription)") + } + } else { + print("Could not find iCloud Drive.") + } +} + + +func restoreFoldersFromiCloud() { + let fileManager = FileManager.default + + // Get the app's Documents directory + let documentsPath = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first! + + // Paths to your original folders in your app's Documents directory + let nandOriginalPath = documentsPath.appendingPathComponent("nand").path + + // iCloud Documents directory + if let iCloudURL = fileManager.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents") { + let nandICloudPath = iCloudURL.appendingPathComponent("nand") + + do { + // Remove the symlink for nand if it exists + if fileManager.fileExists(atPath: nandOriginalPath) { + try fileManager.removeItem(atPath: nandOriginalPath) + } + + // Move the nand folder back to Documents + try fileManager.moveItem(atPath: nandICloudPath.path, toPath: nandOriginalPath) + + print("Folders restored from iCloud successfully.") + + } catch { + print("Error: \(error.localizedDescription)") + } + } else { + print("Could not find iCloud Drive.") } } diff --git a/Pomelo/SettingsViews/SettingsView.swift b/Pomelo/SettingsViews/SettingsView.swift index e1319b6..db4aa4e 100644 --- a/Pomelo/SettingsViews/SettingsView.swift +++ b/Pomelo/SettingsViews/SettingsView.swift @@ -10,8 +10,10 @@ import SwiftUI struct SettingsView: View { @State var core: Core @State var showprompt = false - @AppStorage("icon") var iconused = 1 + @AppStorage("cantouchapplepen") var applepen: Bool = false + + @AppStorage("useTrollStore") var useTrollStore: Bool = false var body: some View { NavigationStack { ScrollView { @@ -69,30 +71,21 @@ struct SettingsView: View { .padding() if UIDevice.current.systemVersion <= "17.0.1" { - Button(action: { - if UserDefaults.standard.bool(forKey: "useTrollStore") { - UserDefaults.standard.set(false, forKey: "useTrollStore") - } else { - UserDefaults.standard.set(true, forKey: "useTrollStore") - } - }) { - Rectangle() - .fill(Color(uiColor: UIColor.secondarySystemBackground)) // Set the fill color (optional) - .cornerRadius(10) // Apply rounded corners - .frame(width: .infinity, height: 50) // Set the desired dimensions - .overlay() { - HStack { + Rectangle() + .fill(Color(uiColor: UIColor.secondarySystemBackground)) // Set the fill color (optional) + .cornerRadius(10) // Apply rounded corners + .frame(width: .infinity, height: 50) // Set the desired dimensions + .overlay() { + HStack { + Toggle(isOn: $useTrollStore) { Text("TrollStore") .foregroundColor(.primary) .padding() - Image(systemName: UserDefaults.standard.bool(forKey: "useTrollStore") ? "checkmark" : "") - .foregroundColor(.primary) - Spacer() } } - } - .foregroundColor(.primary) - .padding() + } + .foregroundColor(.primary) + .padding() } /* @@ -130,7 +123,7 @@ struct SettingsView: View { } .padding() - + HStack(alignment: .center) { Spacer() Text("By \(getDeveloperNames())") diff --git a/Sudachi/Sudachi/Core/core/hle/service/acc/profile_manager.cpp b/Sudachi/Sudachi/Core/core/hle/service/acc/profile_manager.cpp index 4b2d094..3a57d16 100644 --- a/Sudachi/Sudachi/Core/core/hle/service/acc/profile_manager.cpp +++ b/Sudachi/Sudachi/Core/core/hle/service/acc/profile_manager.cpp @@ -451,6 +451,9 @@ void ProfileManager::WriteUserSaveFile() { "made in current session will be saved."); return; } + + LOG_WARNING(Service_ACC, "File Saved (hopefully)"); + is_save_needed = false; } diff --git a/Sudachi/Sudachi/Core/core/hle/service/am/service/application_creator.cpp b/Sudachi/Sudachi/Core/core/hle/service/am/service/application_creator.cpp index 568bb01..2b0ecca 100644 --- a/Sudachi/Sudachi/Core/core/hle/service/am/service/application_creator.cpp +++ b/Sudachi/Sudachi/Core/core/hle/service/am/service/application_creator.cpp @@ -28,8 +28,9 @@ IApplicationCreator::~IApplicationCreator() = default; Result IApplicationCreator::CreateApplication( Out> out_application_accessor, u64 application_id) { - LOG_ERROR(Service_NS, "called, application_id={:x}", application_id); + LOG_ERROR(Service_NS, "CreateApplication called, application_id={:x}", application_id); R_THROW(ResultUnknown); } + } // namespace Service::AM diff --git a/Sudachi/Sudachi/Sudachi.swift b/Sudachi/Sudachi/Sudachi.swift index bd057b0..2aa331e 100644 --- a/Sudachi/Sudachi/Sudachi.swift +++ b/Sudachi/Sudachi/Sudachi.swift @@ -34,6 +34,9 @@ public struct Sudachi { sudachiObjC.bootOS() } + public func bootMii() { + sudachiObjC.bootMii() + } public func pause() { sudachiObjC.pause() } diff --git a/Sudachi/Sudachi/Wrapper/Config/Config.mm b/Sudachi/Sudachi/Wrapper/Config/Config.mm index 2bc15f6..b1b48d8 100644 --- a/Sudachi/Sudachi/Wrapper/Config/Config.mm +++ b/Sudachi/Sudachi/Wrapper/Config/Config.mm @@ -7,9 +7,6 @@ #import "Config.h" -// SPDX-FileCopyrightText: 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - #include #include #include diff --git a/Sudachi/Sudachi/Wrapper/EmulationSession/EmulationSession.h b/Sudachi/Sudachi/Wrapper/EmulationSession/EmulationSession.h index 02f1572..82d7560 100644 --- a/Sudachi/Sudachi/Wrapper/EmulationSession/EmulationSession.h +++ b/Sudachi/Sudachi/Wrapper/EmulationSession/EmulationSession.h @@ -55,6 +55,7 @@ public: const std::size_t program_index, const bool frontend_initiated); Core::SystemResultStatus BootOS(); + Core::SystemResultStatus MiiEditor(); static void OnEmulationStarted(); static u64 GetProgramId(std::string programId); diff --git a/Sudachi/Sudachi/Wrapper/EmulationSession/EmulationSession.mm b/Sudachi/Sudachi/Wrapper/EmulationSession/EmulationSession.mm index 0a2f770..2f65191 100644 --- a/Sudachi/Sudachi/Wrapper/EmulationSession/EmulationSession.mm +++ b/Sudachi/Sudachi/Wrapper/EmulationSession/EmulationSession.mm @@ -208,6 +208,10 @@ Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string m_system.ApplySettings(); YuzuSettings::LogSettings(); m_system.HIDCore().ReloadInputDevices(); + + + auto software_keyboard_applet = std::make_unique(); // Use the concrete implementation + m_system.SetFrontendAppletSet({ nullptr, // Amiibo Settings nullptr, // Controller Selector @@ -216,7 +220,7 @@ Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string nullptr, // Parental Controls nullptr, // Photo Viewer nullptr, // Profile Selector - nullptr, // std::move(android_keyboard), // Software Keyboard + std::move(software_keyboard_applet), // std::move(android_keyboard), // Software Keyboard nullptr, // Web Browser }); @@ -258,6 +262,75 @@ Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string } +Core::SystemResultStatus EmulationSession::MiiEditor() { + std::scoped_lock lock(m_mutex); + + // Create the render window. + m_window = std::make_unique(&m_input_subsystem, m_native_window, m_size, m_vulkan_library); + + // Initialize system. + m_system.SetShuttingDown(false); + m_system.ApplySettings(); + YuzuSettings::LogSettings(); + m_system.HIDCore().ReloadInputDevices(); + auto software_keyboard_applet = std::make_unique(); // Use the concrete implementation + + m_system.SetFrontendAppletSet({ + nullptr, // Amiibo Settings + nullptr, // Controller Selector + nullptr, // Error Display + nullptr, // Mii Editor + nullptr, // Parental Controls + nullptr, // Photo Viewer + nullptr, // Profile Selector + std::move(software_keyboard_applet), // std::move(android_keyboard), // Software Keyboard + nullptr, // Web Browser + }); + + constexpr u64 QLaunchId = static_cast(Service::AM::AppletProgramId::OfflineWeb); + auto bis_system = m_system.GetFileSystemController().GetSystemNANDContents(); + + auto qlaunch_applet_nca = bis_system->GetEntry(QLaunchId, FileSys::ContentRecordType::Program); + + m_system.GetFrontendAppletHolder().SetCurrentAppletId(Service::AM::AppletId::OfflineWeb); + + const auto filename = qlaunch_applet_nca->GetFullPath(); + + auto params = Service::AM::FrontendAppletParameters { + .program_id = QLaunchId, + .applet_id = Service::AM::AppletId::OfflineWeb, + .applet_type = Service::AM::AppletType::SystemApplet + }; + + m_load_result = m_system.Load(EmulationSession::GetInstance().Window(), filename, params); + + if (m_load_result != Core::SystemResultStatus::Success) { + return m_load_result; + } + + // Complete initialization. + m_system.GPU().Start(); + m_system.GetCpuManager().OnGpuReady(); + m_system.RegisterExitCallback([&] { HaltEmulation(); }); + + if (YuzuSettings::values.use_disk_shader_cache.GetValue()) { + m_system.Renderer().ReadRasterizer()->LoadDiskResources( + m_system.GetApplicationProcessProgramID(), std::stop_token{}, + [](VideoCore::LoadCallbackStage, size_t value, size_t total) {}); + } + + // Register an ExecuteProgram callback such that Core can execute a sub-program + m_system.RegisterExecuteProgramCallback([&](std::size_t program_index_) { + m_next_program_index = program_index_; + EmulationSession::GetInstance().HaltEmulation(); + }); + + OnEmulationStarted(); + return Core::SystemResultStatus::Success; +} + + + Core::SystemResultStatus EmulationSession::BootOS() { std::scoped_lock lock(m_mutex); @@ -269,6 +342,8 @@ Core::SystemResultStatus EmulationSession::BootOS() { m_system.ApplySettings(); YuzuSettings::LogSettings(); m_system.HIDCore().ReloadInputDevices(); + auto software_keyboard_applet = std::make_unique(); // Use the concrete implementation + m_system.SetFrontendAppletSet({ nullptr, // Amiibo Settings nullptr, // Controller Selector @@ -277,7 +352,7 @@ Core::SystemResultStatus EmulationSession::BootOS() { nullptr, // Parental Controls nullptr, // Photo Viewer nullptr, // Profile Selector - nullptr, // std::move(android_keyboard), // Software Keyboard + std::move(software_keyboard_applet), // std::move(android_keyboard), // Software Keyboard nullptr, // Web Browser }); diff --git a/Sudachi/Sudachi/Wrapper/SudachiObjC.h b/Sudachi/Sudachi/Wrapper/SudachiObjC.h index 6b51a1e..74f7c69 100644 --- a/Sudachi/Sudachi/Wrapper/SudachiObjC.h +++ b/Sudachi/Sudachi/Wrapper/SudachiObjC.h @@ -54,6 +54,7 @@ typedef NS_ENUM(NSUInteger, VirtualControllerButtonType) { -(void) play; -(BOOL) ispaused; -(BOOL) canGetFullPath; +-(void) bootMii; -(void) quit; -(void) insertGame:(NSURL *)url NS_SWIFT_NAME(insert(game:)); -(void) insertGames:(NSArray *)games NS_SWIFT_NAME(insert(games:)); diff --git a/Sudachi/Sudachi/Wrapper/SudachiObjC.mm b/Sudachi/Sudachi/Wrapper/SudachiObjC.mm index 578e7b8..a70f406 100644 --- a/Sudachi/Sudachi/Wrapper/SudachiObjC.mm +++ b/Sudachi/Sudachi/Wrapper/SudachiObjC.mm @@ -24,6 +24,13 @@ #include "common/announce_multiplayer_room.h" #include "network/network.h" + +#include "common/common_types.h" +#include "common/settings_common.h" +#include "common/settings_enums.h" +#include "common/settings_input.h" +#include "common/settings_setting.h" + #include "common/detached_tasks.h" #include "common/dynamic_library.h" #include "common/fs/path_util.h" @@ -105,15 +112,10 @@ } -(void) pause { - EmulationSession::GetInstance().System().Pause(); - EmulationSession::GetInstance().HaltEmulation(); EmulationSession::GetInstance().PauseEmulation(); } -(void) play { - - EmulationSession::GetInstance().System().Run(); - EmulationSession::GetInstance().RunEmulation(); EmulationSession::GetInstance().UnPauseEmulation(); } @@ -150,16 +152,21 @@ const auto filename = qlaunch_applet_nca->GetFullPath(); - // If GetFullPath() is successful return YES; } @catch (NSException *exception) { - // Handle the exception if needed return NO; } } +-(void) bootMii { + EmulationSession::GetInstance().MiiEditor(); +} + -(void) quit { - EmulationSession::GetInstance().ShutdownEmulation(); + EmulationSession::GetInstance().PauseEmulation(); // First, pause emulation + EmulationSession::GetInstance().HaltEmulation(); // Then, halt any ongoing processes + EmulationSession::GetInstance().ShutdownEmulation(); // Shutdown the emulation session + EmulationSession::GetInstance().System().Exit(); // Finally, exit the system } -(void) configureLayer:(CAMetalLayer *)layer withSize:(CGSize)size { @@ -231,8 +238,7 @@ gyroZ:(float)gyro_z accelX:(float)accel_x accelY:(float)accel_y - accelZ:(float)accel_z -{ + accelZ:(float)accel_z { EmulationSession::GetInstance().OnGamepadConnectEvent(controllerId); EmulationSession::GetInstance().Window().OnGamepadMotionEvent(controllerId, delta_timestamp, gyro_x, gyro_y, gyro_z, accel_x, accel_y, accel_z); } @@ -255,6 +261,4 @@ Config{"config", Config::ConfigType::GlobalConfig}; } - - @end