Adding some logic to Objective-C++ wrapper

This commit is contained in:
Selim Mustafaev 2023-09-28 18:26:39 +03:00
parent 83bb16b28b
commit be7d432f6d
5 changed files with 107 additions and 2 deletions

24
NesKit/NesLayer.h Normal file
View File

@ -0,0 +1,24 @@
//
// NesLayer.h
//
//
// Created by Мустафаев Селим Мустафаевич on 28.09.2023.
//
#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>
#import "NesSystem.h"
NS_ASSUME_NONNULL_BEGIN
@interface NesLayer : CALayer
@property NesSystem* system;
- (instancetype)initWithNesSystem:(NesSystem*)system;
@end
NS_ASSUME_NONNULL_END

27
NesKit/NesLayer.m Normal file
View File

@ -0,0 +1,27 @@
//
// NesLayer.m
//
//
// Created by Мустафаев Селим Мустафаевич on 28.09.2023.
//
#import "NesLayer.h"
@implementation NesLayer {
NSTimer* _timer;
}
- (instancetype)initWithNesSystem:(NesSystem*)system {
if(self = [super init]) {
self.system = system;
_timer = [NSTimer timerWithTimeInterval:1.0/60.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
if(self.system) {
self.contents = self.system.frame;
[self.system stepToNextFrame];
}
}];
}
return self;
}
@end

View File

@ -6,12 +6,17 @@
// //
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <CoreGraphics/CoreGraphics.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@interface NesSystem : NSObject @interface NesSystem : NSObject
@property CGImageRef frame;
- (instancetype)init; - (instancetype)init;
- (void)runRom:(NSString*)path;
- (void)stepToNextFrame;
@end @end

View File

@ -1,5 +1,5 @@
// //
// NesSystem.m // NesSystem.mm
// //
// //
// Created by Selim Mustafaev on 27.09.2023. // Created by Selim Mustafaev on 27.09.2023.
@ -16,13 +16,62 @@
@implementation NesSystem { @implementation NesSystem {
std::unique_ptr<nes::System> _system; std::unique_ptr<nes::System> _system;
NSCondition* _condition;
BOOL _runEmulation;
} }
- (instancetype)init { - (instancetype)init {
if(self = [super init]) { if(self = [super init]) {
_system = std::make_unique<nes::System>(); _system = std::make_unique<nes::System>();
_condition = [NSCondition new];
_runEmulation = YES;
size_t frameBufferSize = nes::Ppu::SCREEN_WIDTH * nes::Ppu::SCREEN_HEIGHT * sizeof(nes::Pixel);
_system->setNewFrameCallback([&](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);
CGDataProviderRelease(dataProvider);
CGColorSpaceRelease(colorspace);
});
} }
return self; return self;
} }
- (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(_runEmulation) {
_system->tick();
}
[_condition unlock];
});
}
- (void)stepToNextFrame {
[_condition lock];
_runEmulation = YES;
[_condition signal];
[_condition unlock];
}
@end @end

View File

@ -1,4 +1,4 @@
// swift-tools-version: 5.9 // swift-tools-version: 5.8
// The swift-tools-version declares the minimum version of Swift required to build this package. // The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription import PackageDescription