add 2.1 code

This commit is contained in:
stossy11 2024-10-15 16:25:31 +11:00
parent 9179e656e0
commit 5bfb14136b
21 changed files with 343 additions and 71 deletions

View File

@ -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 {
}
}
}
}
}

View File

@ -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

View File

@ -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)

View File

@ -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()
}

View File

@ -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 {

View File

@ -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
}
}

View File

@ -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

View File

@ -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.TimerPublisher> {
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")")

View File

@ -2,8 +2,20 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.icloud-container-identifiers</key>
<array>
<string>iCloud.com.stossy11.Pomelo</string>
</array>
<key>com.apple.developer.icloud-services</key>
<array>
<string>CloudDocuments</string>
</array>
<key>com.apple.developer.kernel.increased-memory-limit</key>
<true/>
<key>com.apple.developer.ubiquity-container-identifiers</key>
<array>
<string>iCloud.com.stossy11.Pomelo</string>
</array>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>

View File

@ -2,8 +2,20 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.icloud-container-identifiers</key>
<array>
<string>iCloud.com.stossy11.Pomelo</string>
</array>
<key>com.apple.developer.icloud-services</key>
<array>
<string>CloudDocuments</string>
</array>
<key>com.apple.developer.kernel.increased-memory-limit</key>
<true/>
<key>com.apple.developer.ubiquity-container-identifiers</key>
<array>
<string>iCloud.com.stossy11.Pomelo</string>
</array>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>

View File

@ -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: " ")

View File

@ -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.")
}
}

View File

@ -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())")

View File

@ -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;
}

View File

@ -28,8 +28,9 @@ IApplicationCreator::~IApplicationCreator() = default;
Result IApplicationCreator::CreateApplication(
Out<SharedPointer<IApplicationAccessor>> 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

View File

@ -34,6 +34,9 @@ public struct Sudachi {
sudachiObjC.bootOS()
}
public func bootMii() {
sudachiObjC.bootMii()
}
public func pause() {
sudachiObjC.pause()
}

View File

@ -7,9 +7,6 @@
#import "Config.h"
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <memory>
#include <optional>
#include <sstream>

View File

@ -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);

View File

@ -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<Core::Frontend::DefaultSoftwareKeyboardApplet>(); // 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<EmulationWindow>(&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<Core::Frontend::DefaultSoftwareKeyboardApplet>(); // 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<u64>(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<Core::Frontend::DefaultSoftwareKeyboardApplet>(); // 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
});

View File

@ -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<NSURL *> *)games NS_SWIFT_NAME(insert(games:));

View File

@ -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