diff options
| author | Hannes Schulze <haschu0103@outlook.de> | 2025-01-13 22:03:10 +0100 |
|---|---|---|
| committer | Hannes Schulze <haschu0103@outlook.de> | 2025-01-13 22:03:10 +0100 |
| commit | 02f963a4bab95b3a328b6a792c9a7e027ade0e26 (patch) | |
| tree | 70b73691547e756e77eb30f29d7ea16811bae1e3 /src/scene.mm | |
| parent | 4366e924e44d4294b9791533486f3ab81317ec71 (diff) | |
implement display
Diffstat (limited to 'src/scene.mm')
| -rw-r--r-- | src/scene.mm | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/src/scene.mm b/src/scene.mm new file mode 100644 index 0000000..944d01a --- /dev/null +++ b/src/scene.mm @@ -0,0 +1,96 @@ +#import "scene.hh" +#import "nes/nes.hh" +#import "nes/display.hh" +#import "nes/util/rgb.hh" +#import <memory> + +namespace +{ + class display_impl : public nes::display + { + SKSpriteNode* node_; + NSMutableData* buffer_front_; + NSMutableData* buffer_back_; + std::uint8_t* bytes_back_; + + public: + explicit display_impl(SKSpriteNode* node) + : node_{ node } + , buffer_front_{ make_buffer() } + , buffer_back_{ make_buffer() } + , bytes_back_{ static_cast<std::uint8_t*>([buffer_back_ mutableBytes]) } + { + } + + ~display_impl() = default; + + virtual auto switch_buffers() -> void override + { + auto tmp = buffer_back_; + buffer_back_ = buffer_front_; + buffer_front_ = tmp; + bytes_back_ = static_cast<std::uint8_t*>([buffer_back_ mutableBytes]); + + auto texture = [SKTexture textureWithData:buffer_front_ size:CGSizeMake(width, height)]; + [texture setFilteringMode:SKTextureFilteringNearest]; + [node_ setTexture:texture]; + } + + virtual auto set(unsigned x, unsigned y, nes::rgb value) -> void override + { + auto const offset = (y * width + x) * 4; + bytes_back_[offset + 0] = value.r; + bytes_back_[offset + 1] = value.g; + bytes_back_[offset + 2] = value.b; + bytes_back_[offset + 3] = 255; + } + + virtual auto get(unsigned x, unsigned y) const -> nes::rgb override + { + auto const offset = (y * width + x) * 4; + auto res = nes::rgb{}; + res.r = bytes_back_[offset + 0]; + res.g = bytes_back_[offset + 1]; + res.b = bytes_back_[offset + 2]; + return res; + } + + private: + static auto make_buffer() -> NSMutableData* + { + auto const length = NSUInteger{ width * height * 4 }; + return [NSMutableData dataWithLength:length]; + } + }; +} // namespace + +@implementation Scene +{ + std::unique_ptr<display_impl> display_; + std::unique_ptr<nes::nes> nes_; +} + +- (instancetype)init +{ + self = [super initWithSize:CGSizeMake(nes::display::width, nes::display::height)]; + if (self) + { + SKSpriteNode* node = [[SKSpriteNode alloc] init]; + [node setAnchorPoint:CGPointZero]; + [node setSize:[self size]]; + + [self setScaleMode:SKSceneScaleModeAspectFit]; + [self addChild:node]; + + self->display_ = std::make_unique<display_impl>(node); + self->nes_ = std::make_unique<nes::nes>(*self->display_); + } + return self; +} + +- (void)update:(NSTimeInterval)currentTime +{ + [super update:currentTime]; +} + +@end
\ No newline at end of file |
