Some fixes for iOS
This commit is contained in:
parent
be7d432f6d
commit
e2c33d36f7
@ -14,12 +14,16 @@
|
||||
- (instancetype)initWithNesSystem:(NesSystem*)system {
|
||||
if(self = [super init]) {
|
||||
self.system = system;
|
||||
self.contentsGravity = kCAGravityResizeAspect;
|
||||
|
||||
_timer = [NSTimer timerWithTimeInterval:1.0/60.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
|
||||
if(self.system) {
|
||||
self.contents = self.system.frame;
|
||||
self.contents = (__bridge id _Nullable)(self.system.frame);
|
||||
[self.system stepToNextFrame];
|
||||
}
|
||||
}];
|
||||
|
||||
[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSDefaultRunLoopMode];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@ -28,24 +28,28 @@
|
||||
|
||||
size_t frameBufferSize = nes::Ppu::SCREEN_WIDTH * nes::Ppu::SCREEN_HEIGHT * sizeof(nes::Pixel);
|
||||
|
||||
_system->setNewFrameCallback([&](auto frameBuffer) {
|
||||
_system->setNewFrameCallback([frameBufferSize, self](auto frameBuffer) {
|
||||
_runEmulation = NO;
|
||||
|
||||
CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, (void*)frameBuffer, frameBufferSize, NULL);
|
||||
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
|
||||
_frame = CGImageCreate(nes::Ppu::SCREEN_WIDTH,
|
||||
nes::Ppu::SCREEN_HEIGHT,
|
||||
8,
|
||||
sizeof(nes::Pixel)*8,
|
||||
nes::Ppu::SCREEN_WIDTH * sizeof(nes::Pixel),
|
||||
colorspace,
|
||||
kCGBitmapByteOrderDefault,
|
||||
dataProvider,
|
||||
NULL,
|
||||
true,
|
||||
kCGRenderingIntentDefault);
|
||||
CGImageRef image = CGImageCreate(nes::Ppu::SCREEN_WIDTH,
|
||||
nes::Ppu::SCREEN_HEIGHT,
|
||||
8,
|
||||
sizeof(nes::Pixel)*8,
|
||||
nes::Ppu::SCREEN_WIDTH * sizeof(nes::Pixel),
|
||||
colorspace,
|
||||
kCGImageAlphaPremultipliedLast,
|
||||
dataProvider,
|
||||
NULL,
|
||||
true,
|
||||
kCGRenderingIntentDefault);
|
||||
CGDataProviderRelease(dataProvider);
|
||||
CGColorSpaceRelease(colorspace);
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
_frame = image;
|
||||
});
|
||||
});
|
||||
}
|
||||
return self;
|
||||
@ -54,16 +58,18 @@
|
||||
- (void)runRom:(NSURL*)url {
|
||||
_system->insertCartridge([url fileSystemRepresentation]);
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
[_condition lock];
|
||||
while (!_runEmulation) {
|
||||
[_condition wait];
|
||||
while(TRUE) {
|
||||
[_condition lock];
|
||||
while (!_runEmulation) {
|
||||
[_condition wait];
|
||||
}
|
||||
|
||||
while(_runEmulation) {
|
||||
_system->tick();
|
||||
}
|
||||
|
||||
[_condition unlock];
|
||||
}
|
||||
|
||||
while(_runEmulation) {
|
||||
_system->tick();
|
||||
}
|
||||
|
||||
[_condition unlock];
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -9,5 +9,6 @@
|
||||
#define NesKit_h
|
||||
|
||||
#import "../NesSystem.h"
|
||||
#import "../NesLayer.h"
|
||||
|
||||
#endif /* Header_h */
|
||||
|
||||
@ -8,14 +8,65 @@
|
||||
import UIKit
|
||||
import NesKit
|
||||
|
||||
class NesView: UIView {
|
||||
|
||||
let nesLayer: NesLayer
|
||||
|
||||
init(system: NesSystem) {
|
||||
self.nesLayer = NesLayer(nesSystem: system)
|
||||
super.init(frame: .zero)
|
||||
|
||||
self.layer.addSublayer(self.nesLayer)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
self.nesLayer.frame = self.layer.frame
|
||||
}
|
||||
}
|
||||
|
||||
class ViewController: UIViewController {
|
||||
|
||||
var system = NesSystem()
|
||||
let system = NesSystem()
|
||||
lazy var nesView = NesView(system: system)
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
view.addSubview(nesView)
|
||||
|
||||
nesView.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
nesView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||
nesView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
||||
nesView.topAnchor.constraint(equalTo: view.topAnchor),
|
||||
nesView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
|
||||
])
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||
self.openFilePicker()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func openFilePicker() {
|
||||
let documentPicker = UIDocumentPickerViewController(forOpeningContentTypes: [.data])
|
||||
documentPicker.delegate = self
|
||||
documentPicker.modalPresentationStyle = .overFullScreen
|
||||
documentPicker.allowsMultipleSelection = false
|
||||
present(documentPicker, animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
extension ViewController: UIDocumentPickerDelegate {
|
||||
|
||||
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) {
|
||||
print("Did pick document at: ", url)
|
||||
system.runRom(url.path(percentEncoded: false))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -28,6 +28,7 @@ namespace nes {
|
||||
_chrRom = std::span<uint8_t>(_romData.get() + sizeof(RomHeader) + prgSize, chrSize);
|
||||
|
||||
_mapper = std::make_unique<Mapper0>(_header->prgChunks, _header->chrChunks);
|
||||
_mirroring = _header->flags.mirroring == 0 ? Mirroring::Horizontal : Mirroring::Vertical;
|
||||
}
|
||||
|
||||
uint8_t Cartridge::readPrg(uint16_t address) {
|
||||
@ -41,7 +42,7 @@ namespace nes {
|
||||
}
|
||||
|
||||
Cartridge::Mirroring Cartridge::mirroring() const {
|
||||
return _header->flags.mirroring == 0 ? Mirroring::Horizontal : Mirroring::Vertical;
|
||||
return _mirroring;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -53,6 +53,9 @@ namespace nes {
|
||||
RomHeader* _header;
|
||||
std::span<uint8_t> _prgRom;
|
||||
std::span<uint8_t> _chrRom;
|
||||
|
||||
private:
|
||||
Mirroring _mirroring;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user