Some fixes for iOS
This commit is contained in:
parent
be7d432f6d
commit
e2c33d36f7
@ -14,12 +14,16 @@
|
|||||||
- (instancetype)initWithNesSystem:(NesSystem*)system {
|
- (instancetype)initWithNesSystem:(NesSystem*)system {
|
||||||
if(self = [super init]) {
|
if(self = [super init]) {
|
||||||
self.system = system;
|
self.system = system;
|
||||||
|
self.contentsGravity = kCAGravityResizeAspect;
|
||||||
|
|
||||||
_timer = [NSTimer timerWithTimeInterval:1.0/60.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
|
_timer = [NSTimer timerWithTimeInterval:1.0/60.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
|
||||||
if(self.system) {
|
if(self.system) {
|
||||||
self.contents = self.system.frame;
|
self.contents = (__bridge id _Nullable)(self.system.frame);
|
||||||
[self.system stepToNextFrame];
|
[self.system stepToNextFrame];
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSDefaultRunLoopMode];
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,24 +28,28 @@
|
|||||||
|
|
||||||
size_t frameBufferSize = nes::Ppu::SCREEN_WIDTH * nes::Ppu::SCREEN_HEIGHT * sizeof(nes::Pixel);
|
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;
|
_runEmulation = NO;
|
||||||
|
|
||||||
CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, (void*)frameBuffer, frameBufferSize, NULL);
|
CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, (void*)frameBuffer, frameBufferSize, NULL);
|
||||||
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
|
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
|
||||||
_frame = CGImageCreate(nes::Ppu::SCREEN_WIDTH,
|
CGImageRef image = CGImageCreate(nes::Ppu::SCREEN_WIDTH,
|
||||||
nes::Ppu::SCREEN_HEIGHT,
|
nes::Ppu::SCREEN_HEIGHT,
|
||||||
8,
|
8,
|
||||||
sizeof(nes::Pixel)*8,
|
sizeof(nes::Pixel)*8,
|
||||||
nes::Ppu::SCREEN_WIDTH * sizeof(nes::Pixel),
|
nes::Ppu::SCREEN_WIDTH * sizeof(nes::Pixel),
|
||||||
colorspace,
|
colorspace,
|
||||||
kCGBitmapByteOrderDefault,
|
kCGImageAlphaPremultipliedLast,
|
||||||
dataProvider,
|
dataProvider,
|
||||||
NULL,
|
NULL,
|
||||||
true,
|
true,
|
||||||
kCGRenderingIntentDefault);
|
kCGRenderingIntentDefault);
|
||||||
CGDataProviderRelease(dataProvider);
|
CGDataProviderRelease(dataProvider);
|
||||||
CGColorSpaceRelease(colorspace);
|
CGColorSpaceRelease(colorspace);
|
||||||
|
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
_frame = image;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
@ -54,6 +58,7 @@
|
|||||||
- (void)runRom:(NSURL*)url {
|
- (void)runRom:(NSURL*)url {
|
||||||
_system->insertCartridge([url fileSystemRepresentation]);
|
_system->insertCartridge([url fileSystemRepresentation]);
|
||||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
|
while(TRUE) {
|
||||||
[_condition lock];
|
[_condition lock];
|
||||||
while (!_runEmulation) {
|
while (!_runEmulation) {
|
||||||
[_condition wait];
|
[_condition wait];
|
||||||
@ -64,6 +69,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
[_condition unlock];
|
[_condition unlock];
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,5 +9,6 @@
|
|||||||
#define NesKit_h
|
#define NesKit_h
|
||||||
|
|
||||||
#import "../NesSystem.h"
|
#import "../NesSystem.h"
|
||||||
|
#import "../NesLayer.h"
|
||||||
|
|
||||||
#endif /* Header_h */
|
#endif /* Header_h */
|
||||||
|
|||||||
@ -8,14 +8,65 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
import NesKit
|
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 {
|
class ViewController: UIViewController {
|
||||||
|
|
||||||
var system = NesSystem()
|
let system = NesSystem()
|
||||||
|
lazy var nesView = NesView(system: system)
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.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);
|
_chrRom = std::span<uint8_t>(_romData.get() + sizeof(RomHeader) + prgSize, chrSize);
|
||||||
|
|
||||||
_mapper = std::make_unique<Mapper0>(_header->prgChunks, _header->chrChunks);
|
_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) {
|
uint8_t Cartridge::readPrg(uint16_t address) {
|
||||||
@ -41,7 +42,7 @@ namespace nes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Cartridge::Mirroring Cartridge::mirroring() const {
|
Cartridge::Mirroring Cartridge::mirroring() const {
|
||||||
return _header->flags.mirroring == 0 ? Mirroring::Horizontal : Mirroring::Vertical;
|
return _mirroring;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,6 +53,9 @@ namespace nes {
|
|||||||
RomHeader* _header;
|
RomHeader* _header;
|
||||||
std::span<uint8_t> _prgRom;
|
std::span<uint8_t> _prgRom;
|
||||||
std::span<uint8_t> _chrRom;
|
std::span<uint8_t> _chrRom;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Mirroring _mirroring;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user