26 changed files with 80 additions and 435 deletions
-
77src/ios/AdvancedSettingsView.swift
-
0src/ios/Air.swift
-
0src/ios/AirPlay.swift
-
19src/ios/AppIconProvider.swift
-
26src/ios/BootOSView.swift
-
10src/ios/CMakeLists.txt
-
15src/ios/ContentView.swift
-
14src/ios/ControllerView.swift
-
88src/ios/CoreSettingsView.swift
-
26src/ios/DetectServer.swift
-
2src/ios/EmulationHandler.swift
-
2src/ios/EmulationScreenView.swift
-
2src/ios/EmulationView.swift
-
52src/ios/EnableJIT.swift
-
2src/ios/FileManager.swift
-
40src/ios/GameButtonListView.swift
-
1src/ios/GameButtonView.swift
-
34src/ios/GameListView.swift
-
23src/ios/Haptics.swift
-
46src/ios/InfoView.swift
-
2src/ios/JoystickView.swift
-
2src/ios/KeyboardHostingController.swift
-
2src/ios/LibraryView.swift
-
2src/ios/MetalView.swift
-
20src/ios/NavView.swift
-
8src/ios/PomeloApp.swift
@ -1,77 +0,0 @@ |
|||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project |
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later |
|
||||
// SPDX-FileCopyrightText: Copyright 2024 Pomelo, Stossy11 |
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later |
|
||||
|
|
||||
import SwiftUI |
|
||||
import UniformTypeIdentifiers |
|
||||
|
|
||||
struct AdvancedSettingsView: View { |
|
||||
@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 |
|
||||
var body: some View { |
|
||||
ScrollView { |
|
||||
Rectangle() |
|
||||
.fill(Color(uiColor: UIColor.secondarySystemBackground)) |
|
||||
.cornerRadius(10) |
|
||||
.frame(width: .infinity, height: 50) |
|
||||
.overlay() { |
|
||||
HStack { |
|
||||
Toggle("Exit Game Button", isOn: $exitgame) |
|
||||
.padding() |
|
||||
} |
|
||||
} |
|
||||
Text("This is very unstable and can lead to game freezing and overall bad preformance after you exit a game") |
|
||||
.padding(.bottom) |
|
||||
.font(.footnote) |
|
||||
.foregroundColor(.gray) |
|
||||
Rectangle() |
|
||||
.fill(Color(uiColor: UIColor.secondarySystemBackground)) |
|
||||
.cornerRadius(10) |
|
||||
.frame(width: .infinity, height: 50) |
|
||||
.overlay() { |
|
||||
HStack { |
|
||||
Toggle("Memory Usage Increase", isOn: $kpagetable) |
|
||||
.padding() |
|
||||
} |
|
||||
} |
|
||||
Text("This makes games way more stable but a lot of games will crash as you will run out of Memory way quicker. (Don't Enable this on devices with less then 8GB of memory as most games will crash)") |
|
||||
.padding(.bottom) |
|
||||
.font(.footnote) |
|
||||
.foregroundColor(.gray) |
|
||||
|
|
||||
Rectangle() |
|
||||
.fill(Color(uiColor: UIColor.secondarySystemBackground)) |
|
||||
.cornerRadius(10) |
|
||||
.frame(width: .infinity, height: 50) |
|
||||
.overlay() { |
|
||||
HStack { |
|
||||
Toggle("Check for Booting OS", isOn: $canGetFullPath) |
|
||||
.padding() |
|
||||
} |
|
||||
} |
|
||||
Text("If you do not have the neccesary files for Booting the Switch OS, it will just crash almost instantly.") |
|
||||
.padding(.bottom) |
|
||||
.font(.footnote) |
|
||||
.foregroundColor(.gray) |
|
||||
|
|
||||
Rectangle() |
|
||||
.fill(Color(uiColor: UIColor.secondarySystemBackground)) |
|
||||
.cornerRadius(10) |
|
||||
.frame(width: .infinity, height: 50) |
|
||||
.overlay() { |
|
||||
HStack { |
|
||||
Toggle("Set OnScreen Controls to Handheld", isOn: $onscreenjoy) |
|
||||
.padding() |
|
||||
} |
|
||||
} |
|
||||
Text("You need in Core Settings to set \"use_docked_mode = 0\"") |
|
||||
.padding(.bottom) |
|
||||
.font(.footnote) |
|
||||
.foregroundColor(.gray) |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,19 +0,0 @@ |
|||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project |
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later |
|
||||
// SPDX-FileCopyrightText: Copyright 2024 Pomelo, Stossy11 |
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later |
|
||||
|
|
||||
import Foundation |
|
||||
|
|
||||
enum AppIconProvider { |
|
||||
static func appIcon(in bundle: Bundle = .main) -> String { |
|
||||
guard let icons = bundle.object(forInfoDictionaryKey: "CFBundleIcons") as? [String: Any], |
|
||||
let primaryIcon = icons["CFBundlePrimaryIcon"] as? [String: Any], |
|
||||
let iconFiles = primaryIcon["CFBundleIconFiles"] as? [String], |
|
||||
let iconFileName = iconFiles.last else { |
|
||||
print("Could not find icons in bundle") |
|
||||
return "" |
|
||||
} |
|
||||
return iconFileName |
|
||||
} |
|
||||
} |
|
||||
@ -1,26 +0,0 @@ |
|||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project |
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later |
|
||||
// SPDX-FileCopyrightText: Copyright 2024 Pomelo, Stossy11 |
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later |
|
||||
|
|
||||
import SwiftUI |
|
||||
import AppUI |
|
||||
|
|
||||
struct BootOSView: View { |
|
||||
@Binding var core: Core |
|
||||
@Binding var currentnavigarion: Int |
|
||||
@State var appui = AppUI.shared |
|
||||
@AppStorage("cangetfullpath") var canGetFullPath: Bool = false |
|
||||
var body: some View { |
|
||||
if (appui.canGetFullPath() -- canGetFullPath) { |
|
||||
EmulationView(game: nil) |
|
||||
} else { |
|
||||
VStack { |
|
||||
Text("Unable Launch Switch OS") |
|
||||
.font(.largeTitle) |
|
||||
.padding() |
|
||||
Text("You do not have the Switch Home Menu Files Needed to launch the Ηome Menu") |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,15 +0,0 @@ |
|||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project |
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later |
|
||||
// SPDX-FileCopyrightText: Copyright 2024 Pomelo, Stossy11 |
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later |
|
||||
|
|
||||
import SwiftUI |
|
||||
import AppUI |
|
||||
|
|
||||
struct ContentView: View { |
|
||||
@State var core = Core(games: [], root: FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]) |
|
||||
var body: some View { |
|
||||
HomeView(core: core).onAppear() { |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,88 +0,0 @@ |
|||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project |
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later |
|
||||
// SPDX-FileCopyrightText: Copyright 2024 Pomelo, Stossy11 |
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later |
|
||||
|
|
||||
import SwiftUI |
|
||||
import Foundation |
|
||||
import AppUI |
|
||||
|
|
||||
struct CoreSettingsView: View { |
|
||||
@State private var text: String = "" |
|
||||
@State private var isLoading: Bool = true |
|
||||
@Environment(\.presentationMode) var presentationMode |
|
||||
|
|
||||
var body: some View { |
|
||||
VStack { |
|
||||
if isLoading { |
|
||||
ProgressView() |
|
||||
.progressViewStyle(CircularProgressViewStyle()) |
|
||||
} else { |
|
||||
TextEditor(text: $text) |
|
||||
.padding() |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
.toolbar { |
|
||||
ToolbarItem(placement: .navigationBarTrailing) { |
|
||||
Button { |
|
||||
let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] |
|
||||
let configfolder = documentDirectory.appendingPathComponent("config", conformingTo: .folder) |
|
||||
let fileURL = configfolder.appendingPathComponent("config.ini") |
|
||||
|
|
||||
presentationMode.wrappedValue.dismiss() |
|
||||
|
|
||||
do { |
|
||||
try FileManager.default.removeItem(at: fileURL) |
|
||||
} catch { |
|
||||
print("\(error.localizedDescription)") |
|
||||
} |
|
||||
|
|
||||
AppUI.shared.settingsSaved() |
|
||||
|
|
||||
} label: { |
|
||||
Text("Reset File") |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
.onAppear { |
|
||||
loadFile() |
|
||||
} |
|
||||
.onDisappear() { |
|
||||
saveFile() |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private func loadFile() { |
|
||||
let fileManager = FileManager.default |
|
||||
let documentDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0] |
|
||||
let configfolder = documentDirectory.appendingPathComponent("config", conformingTo: .folder) |
|
||||
let fileURL = configfolder.appendingPathComponent("config.ini") |
|
||||
|
|
||||
if fileManager.fileExists(atPath: fileURL.path) { |
|
||||
do { |
|
||||
text = try String(contentsOf: fileURL, encoding: .utf8) |
|
||||
} catch { |
|
||||
print("Error reading file: \(error)") |
|
||||
} |
|
||||
} else { |
|
||||
text = "" // Initialize with empty text if file doesn't exist |
|
||||
} |
|
||||
isLoading = false |
|
||||
} |
|
||||
|
|
||||
private func saveFile() { |
|
||||
let fileManager = FileManager.default |
|
||||
let documentDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0] |
|
||||
let configfolder = documentDirectory.appendingPathComponent("config", conformingTo: .folder) |
|
||||
let fileURL = configfolder.appendingPathComponent("config.ini") |
|
||||
|
|
||||
do { |
|
||||
try text.write(to: fileURL, atomically: true, encoding: .utf8) |
|
||||
AppUI.shared.settingsSaved() |
|
||||
print("File saved successfully!") |
|
||||
} catch { |
|
||||
print("Error saving file: \(error)") |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,26 +0,0 @@ |
|||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project |
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later |
|
||||
// SPDX-FileCopyrightText: Copyright 2024 Pomelo, Stossy11 |
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later |
|
||||
|
|
||||
import Foundation |
|
||||
|
|
||||
func isSideJITServerDetected(completion: @escaping (Result<Void, Error>) -> Void) { |
|
||||
let address = UserDefaults.standard.string(forKey: "sidejitserver") ?? "" |
|
||||
var SJSURL = address |
|
||||
if (address).isEmpty { |
|
||||
SJSURL = "http://sidejitserver._http._tcp.local:8080" |
|
||||
} |
|
||||
// Create a network operation at launch to Refresh SideJITServer |
|
||||
let url = URL(string: SJSURL)! |
|
||||
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in |
|
||||
if let error = error { |
|
||||
print("No SideJITServer on Network") |
|
||||
completion(.failure(error)) |
|
||||
return |
|
||||
} |
|
||||
completion(.success(())) |
|
||||
} |
|
||||
task.resume() |
|
||||
return |
|
||||
} |
|
||||
@ -1,52 +0,0 @@ |
|||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project |
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later |
|
||||
// SPDX-FileCopyrightText: Copyright 2024 Pomelo, Stossy11 |
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later |
|
||||
|
|
||||
import Foundation |
|
||||
|
|
||||
enum SideJITServerErrorType: Error { |
|
||||
case invalidURL |
|
||||
case errorConnecting |
|
||||
case deviceNotFound |
|
||||
case other(String) |
|
||||
} |
|
||||
|
|
||||
func sendrequestsidejit(url: String, completion: @escaping (Result<Void, SideJITServerErrorType>) -> Void) { |
|
||||
let url = URL(string: url)! |
|
||||
let task = URLSession.shared.dataTask(with: url) {(data, response, error) in |
|
||||
if let error = error { |
|
||||
completion(.failure(.errorConnecting)) |
|
||||
return |
|
||||
} |
|
||||
guard let data = data, let datastring = String(data: data, encoding: .utf8) else { return } |
|
||||
if datastring == "Enabled JIT" { |
|
||||
completion(.success(())) |
|
||||
} else { |
|
||||
let errorType: SideJITServerErrorType = datastring == "Could not find device!" ? .deviceNotFound : .other(datastring) |
|
||||
completion(.failure(errorType)) |
|
||||
} |
|
||||
} |
|
||||
task.resume() |
|
||||
} |
|
||||
|
|
||||
func sendrefresh(url: String, completion: @escaping (Result<Void, SideJITServerErrorType>) -> Void) { |
|
||||
let url = URL(string: url)! |
|
||||
|
|
||||
let task = URLSession.shared.dataTask(with: url) {(data, response, error) in |
|
||||
if let error = error { |
|
||||
completion(.failure(.errorConnecting)) |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
guard let data = data, let datastring = String(data: data, encoding: .utf8) else { return } |
|
||||
let inputText = "{\"OK\":\"Refreshed!\"}" |
|
||||
if datastring == inputText { |
|
||||
completion(.success(())) |
|
||||
} else { |
|
||||
let errorType: SideJITServerErrorType = datastring == "Could not find device!" ? .deviceNotFound : .other(datastring) |
|
||||
completion(.failure(errorType)) |
|
||||
} |
|
||||
} |
|
||||
task.resume() |
|
||||
} |
|
||||
@ -1,40 +0,0 @@ |
|||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project |
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later |
|
||||
// SPDX-FileCopyrightText: Copyright 2024 Pomelo, TechGuy |
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later |
|
||||
|
|
||||
import SwiftUI |
|
||||
import Foundation |
|
||||
import UIKit |
|
||||
|
|
||||
struct GameButtonListView: View { |
|
||||
var game: EmulationGame |
|
||||
@Environment(\.colorScheme) var colorScheme |
|
||||
|
|
||||
var body: some View { |
|
||||
HStack(spacing: 15) { |
|
||||
if let image = UIImage(data: game.imageData) { |
|
||||
Image(uiImage: image) |
|
||||
.resizable() |
|
||||
.frame(width: 60, height: 60) |
|
||||
.cornerRadius(8) |
|
||||
} else { |
|
||||
Image(systemName: "photo") |
|
||||
.resizable() |
|
||||
.frame(width: 60, height: 60) |
|
||||
.cornerRadius(8) |
|
||||
} |
|
||||
|
|
||||
VStack(alignment: .leading, spacing: 4) { |
|
||||
Text(game.title) |
|
||||
.font(.headline) |
|
||||
.foregroundColor(colorScheme == .dark ? Color.white : Color.black) |
|
||||
Text(game.developer) |
|
||||
.font(.subheadline) |
|
||||
.foregroundColor(.gray) |
|
||||
} |
|
||||
Spacer() |
|
||||
} |
|
||||
.padding(.vertical, 8) |
|
||||
} |
|
||||
} |
|
||||
@ -1,23 +0,0 @@ |
|||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project |
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later |
|
||||
// SPDX-FileCopyrightText: Copyright 2024 Pomelo, Stossy11 |
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later |
|
||||
|
|
||||
import UIKit |
|
||||
import SwiftUI |
|
||||
import AppUI |
|
||||
|
|
||||
class Haptics { |
|
||||
static let shared = Haptics() |
|
||||
|
|
||||
private init() { } |
|
||||
|
|
||||
func play(_ feedbackStyle: UIImpactFeedbackGenerator.FeedbackStyle) { |
|
||||
print("haptics") |
|
||||
UIImpactFeedbackGenerator(style: feedbackStyle).impactOccurred() |
|
||||
} |
|
||||
|
|
||||
func notify(_ feedbackType: UINotificationFeedbackGenerator.FeedbackType) { |
|
||||
UINotificationFeedbackGenerator().notificationOccurred(feedbackType) |
|
||||
} |
|
||||
} |
|
||||
@ -1,46 +0,0 @@ |
|||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project |
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later |
|
||||
// SPDX-FileCopyrightText: Copyright 2024 Yuzu, Stossy11 |
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later |
|
||||
|
|
||||
import SwiftUI |
|
||||
|
|
||||
struct InfoView: View { |
|
||||
@AppStorage("entitlementNotExists") private var entitlementNotExists: Bool = false |
|
||||
@AppStorage("increaseddebugmem") private var increaseddebugmem: Bool = false |
|
||||
@AppStorage("extended-virtual-addressing") private var extended: Bool = false |
|
||||
let infoDictionary = Bundle.main.infoDictionary |
|
||||
|
|
||||
var body: some View { |
|
||||
ScrollView { |
|
||||
VStack { |
|
||||
Text("Welcome").font(.largeTitle) |
|
||||
Divider() |
|
||||
Text("Entitlements:").font(.title).font(Font.headline.weight(.bold)) |
|
||||
Spacer().frame(height: 10) |
|
||||
Group { |
|
||||
Text("Required:").font(.title2).font(Font.headline.weight(.bold)) |
|
||||
Spacer().frame(height: 10) |
|
||||
Text("Limit: \(String(describing: !entitlementNotExists))") |
|
||||
Spacer().frame(height: 10) |
|
||||
} |
|
||||
Group { |
|
||||
Spacer().frame(height: 10) |
|
||||
Text("Reccomended:").font(.title2).font(Font.headline.weight(.bold)) |
|
||||
Spacer().frame(height: 10) |
|
||||
Text("Limit: \(String(describing: increaseddebugmem))").padding() |
|
||||
Text("Extended: \(String(describing: extended))") |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
.padding() |
|
||||
Text("Version: \(getAppVersion())").foregroundColor(.gray) |
|
||||
} |
|
||||
} |
|
||||
func getAppVersion() -> String { |
|
||||
guard let s = infoDictionary?["CFBundleShortVersionString"] as? String else { |
|
||||
return "Unknown" |
|
||||
} |
|
||||
return s |
|
||||
} |
|
||||
} |
|
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue