diff --git a/.gitignore b/.gitignore index 9970017..be36e49 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ out/ build/ CMakeLists.txt.user **/.DS_Store +xcuserdata/ .swiftpm/ diff --git a/NesKit/NesSystem.h b/NesKit/NesSystem.h index 3a025d9..8f9f5e5 100644 --- a/NesKit/NesSystem.h +++ b/NesKit/NesSystem.h @@ -15,7 +15,7 @@ NS_ASSUME_NONNULL_BEGIN @property CGImageRef frame; - (instancetype)init; -- (void)runRom:(NSString*)path; +- (void)runRom:(NSURL*)url; - (void)stepToNextFrame; @end diff --git a/NesKit/NesSystem.mm b/NesKit/NesSystem.mm index 98a3988..2b15c9a 100644 --- a/NesKit/NesSystem.mm +++ b/NesKit/NesSystem.mm @@ -30,7 +30,11 @@ } - (void)runRom:(NSURL*)url { + + [url startAccessingSecurityScopedResource]; _system->insertCartridge([url fileSystemRepresentation]); + [url stopAccessingSecurityScopedResource]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ while(TRUE) { [_condition lock]; diff --git a/NesKitSwift/NesSystemSwift.swift b/NesKitSwift/NesSystemSwift.swift index 5bda4a7..4fa4cd1 100644 --- a/NesKitSwift/NesSystemSwift.swift +++ b/NesKitSwift/NesSystemSwift.swift @@ -10,14 +10,10 @@ import NesKitCpp class NesSystemSwift { - var nesSystem: nes.System? - - init() { - - let frameBufferSize = nes.Ppu.SCREEN_WIDTH * nes.Ppu.SCREEN_HEIGHT * MemoryLayout.stride - - nesSystem?.setNewFrameCallback({ frameBuffer in - - }) - } +// var nesSystem: nes.System? +// +// init() { +// +// let frameBufferSize = nes.Ppu.SCREEN_WIDTH * nes.Ppu.SCREEN_HEIGHT * MemoryLayout.stride +// } } diff --git a/examples/NesApp/NesApp.xcodeproj/project.xcworkspace/xcuserdata/selim.xcuserdatad/UserInterfaceState.xcuserstate b/examples/NesApp/NesApp.xcodeproj/project.xcworkspace/xcuserdata/selim.xcuserdatad/UserInterfaceState.xcuserstate deleted file mode 100644 index 59f273e..0000000 Binary files a/examples/NesApp/NesApp.xcodeproj/project.xcworkspace/xcuserdata/selim.xcuserdatad/UserInterfaceState.xcuserstate and /dev/null differ diff --git a/examples/NesApp/NesApp/ContentView.swift b/examples/NesApp/NesApp/ContentView.swift index 4f01f6b..848b1cd 100644 --- a/examples/NesApp/NesApp/ContentView.swift +++ b/examples/NesApp/NesApp/ContentView.swift @@ -6,16 +6,36 @@ // import SwiftUI +import NesKit +import UniformTypeIdentifiers struct ContentView: View { + + @State var system = NesSystem() + @State var showFileImporter = false + var body: some View { - VStack { - Image(systemName: "globe") - .imageScale(.large) - .foregroundStyle(.tint) - Text("Hello, world!") - } - .padding() + NesView(system: system) + .fileImporter( + isPresented: $showFileImporter, + allowedContentTypes: [.init(filenameExtension: "nes") ?? .data], + allowsMultipleSelection: false) { result in + switch result { + case .success(let urls): + if let url = urls.first { + system.runRom(url) + } + case .failure(let error): + print("error: \(error)") + } + } + .toolbar { + Button { + showFileImporter = true + } label: { + Image(systemName: "document.badge.plus") + } + } } } diff --git a/examples/NesApp/NesApp/NesView/NesSystemView.swift b/examples/NesApp/NesApp/NesView/NesSystemView.swift new file mode 100644 index 0000000..8a4c0b3 --- /dev/null +++ b/examples/NesApp/NesApp/NesView/NesSystemView.swift @@ -0,0 +1,23 @@ +// +// NesSystemView.swift +// NesApp +// +// Created by Selim Mustafaev on 04.10.2025. +// + +import AppKit +import NesKit + +class NesSystemView: NSView { + + init(system: NesSystem) { + super.init(frame: .zero) + + self.layer = NesLayer(nesSystem: system) + self.wantsLayer = true + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} diff --git a/examples/NesApp/NesApp/NesView/NesView.swift b/examples/NesApp/NesApp/NesView/NesView.swift index 0ba1a74..7d31e34 100644 --- a/examples/NesApp/NesApp/NesView/NesView.swift +++ b/examples/NesApp/NesApp/NesView/NesView.swift @@ -5,27 +5,20 @@ // Created by Selim Mustafaev on 04.10.2025. // -import UIKit +import AppKit +import SwiftUI import NesKit -class NesView: UIView { +struct NesView: NSViewRepresentable { - let nesLayer: NesLayer + @State var system: NesSystem - init(system: NesSystem) { - self.nesLayer = NesLayer(nesSystem: system) - super.init(frame: .zero) + func makeNSView(context: Context) -> NesSystemView { - self.layer.addSublayer(self.nesLayer) + NesSystemView(system: system) } - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override func layoutSubviews() { - super.layoutSubviews() + func updateNSView(_ nsView: NesSystemView, context: Context) { - self.nesLayer.frame = self.layer.frame } }