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