From 7276c770272bb9d48c293d27d119e68fe935c9b8 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 23 Jul 2015 20:45:07 -0400 Subject: [PATCH] A full communication pathway now leads to Atari2600.mm (for now) being in possession of a frame and receiving a command to draw, with a suitable OpenGL context being active and whatever is drawn subsequently appearing. --- OSBindings/Mac/Clock Signal/Atari2600.h | 9 +++++ OSBindings/Mac/Clock Signal/Atari2600.mm | 40 +++++++++++++------ .../Mac/Clock Signal/Atari2600Document.swift | 17 +++++++- OSBindings/Mac/Clock Signal/OpenGLView.h | 1 + OSBindings/Mac/Clock Signal/OpenGLView.m | 16 +++++++- 5 files changed, 66 insertions(+), 17 deletions(-) diff --git a/OSBindings/Mac/Clock Signal/Atari2600.h b/OSBindings/Mac/Clock Signal/Atari2600.h index 8e7ff6006..8e317f15b 100644 --- a/OSBindings/Mac/Clock Signal/Atari2600.h +++ b/OSBindings/Mac/Clock Signal/Atari2600.h @@ -8,9 +8,18 @@ #import +@class CSAtari2600; +@protocol CSAtari2600Delegate +- (void)atari2600NeedsRedraw:(CSAtari2600 *)atari2600; +@end + @interface CSAtari2600 : NSObject +@property (nonatomic, weak) id delegate; + - (void)runForNumberOfCycles:(int)cycles; - (void)setROM:(NSData *)rom; +- (void)draw; + @end diff --git a/OSBindings/Mac/Clock Signal/Atari2600.mm b/OSBindings/Mac/Clock Signal/Atari2600.mm index e9acd17fc..1a51972fc 100644 --- a/OSBindings/Mac/Clock Signal/Atari2600.mm +++ b/OSBindings/Mac/Clock Signal/Atari2600.mm @@ -8,6 +8,7 @@ #import "Atari2600.h" #import "Atari2600.hpp" +#import @interface CSAtari2600 (Callbacks) - (void)crtDidEndFrame:(Outputs::CRTFrame *)frame; @@ -23,18 +24,35 @@ struct Atari2600CRTDelegate: public Outputs::CRT::CRTDelegate { Atari2600CRTDelegate _crtDelegate; dispatch_queue_t _serialDispatchQueue; + Outputs::CRTFrame *_queuedFrame; } - (void)crtDidEndFrame:(Outputs::CRTFrame *)frame { dispatch_async(dispatch_get_main_queue(), ^{ + if(_queuedFrame) { + dispatch_async(_serialDispatchQueue, ^{ + _atari2600.get_crt()->return_frame(); + }); + } + _queuedFrame = frame; - printf("\n\n===\n\n"); + [self.delegate atari2600NeedsRedraw:self]; + }); +} + +- (void)draw { + + if(_queuedFrame) + { + glClearColor(1.0, 0.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); +/* printf("\n\n===\n\n"); int c = 0; - for(int run = 0; run < frame->number_of_runs; run++) + for(int run = 0; run < _queuedFrame->number_of_runs; run++) { char character = ' '; - switch(frame->runs[run].type) + switch(_queuedFrame->runs[run].type) { case Outputs::CRTRun::Type::Sync: character = '<'; break; case Outputs::CRTRun::Type::Level: character = '_'; break; @@ -42,14 +60,14 @@ struct Atari2600CRTDelegate: public Outputs::CRT::CRTDelegate { case Outputs::CRTRun::Type::Blank: character = ' '; break; } - if(frame->runs[run].start_point.dst_x < 1.0 / 224.0) + if(_queuedFrame->runs[run].start_point.dst_x < 1.0 / 224.0) { - printf("\n[%0.2f]: ", frame->runs[run].start_point.dst_y); + printf("\n[%0.2f]: ", _queuedFrame->runs[run].start_point.dst_y); c++; } - printf("(%0.2f): ", frame->runs[run].start_point.dst_x); - float length = fabsf(frame->runs[run].end_point.dst_x - frame->runs[run].start_point.dst_x); + printf("(%0.2f): ", _queuedFrame->runs[run].start_point.dst_x); + float length = fabsf(_queuedFrame->runs[run].end_point.dst_x - _queuedFrame->runs[run].start_point.dst_x); int iLength = (int)(length * 64.0); for(int c = 0; c < iLength; c++) { @@ -57,12 +75,8 @@ struct Atari2600CRTDelegate: public Outputs::CRT::CRTDelegate { } } - printf("\n\n[%d]\n\n", c); - - dispatch_async(_serialDispatchQueue, ^{ - _atari2600.get_crt()->return_frame(); - }); - }); + printf("\n\n[%d]\n\n", c);*/ + } } - (void)runForNumberOfCycles:(int)cycles { diff --git a/OSBindings/Mac/Clock Signal/Atari2600Document.swift b/OSBindings/Mac/Clock Signal/Atari2600Document.swift index 49f981b54..414b4f0c4 100644 --- a/OSBindings/Mac/Clock Signal/Atari2600Document.swift +++ b/OSBindings/Mac/Clock Signal/Atari2600Document.swift @@ -8,7 +8,7 @@ import Cocoa -class Atari2600Document: NSDocument, CSOpenGLViewDelegate { +class Atari2600Document: NSDocument, CSOpenGLViewDelegate, CSAtari2600Delegate { override init() { super.init() @@ -44,9 +44,12 @@ class Atari2600Document: NSDocument, CSOpenGLViewDelegate { // You can also choose to override readFromFileWrapper:ofType:error: or readFromURL:ofType:error: instead. // If you override either of these, you should also override -isEntireFileLoaded to return false if the contents are lazily loaded. atari2600 = CSAtari2600() - atari2600?.setROM(data) + atari2600!.setROM(data) + atari2600!.delegate = self } + // MARK: CSOpenGLViewDelegate + private var lastCycleCount: Int64? func openGLView(view: CSOpenGLView!, didUpdateToTime time: CVTimeStamp) { @@ -66,4 +69,14 @@ class Atari2600Document: NSDocument, CSOpenGLViewDelegate { } lastCycleCount = cycleCount } + + func openGLViewDrawView(view: CSOpenGLView!) { + atari2600!.draw() + } + + // MARK: CSAtari2600Delegate + + func atari2600NeedsRedraw(atari2600: CSAtari2600!) { + openGLView?.needsDisplay = true + } } \ No newline at end of file diff --git a/OSBindings/Mac/Clock Signal/OpenGLView.h b/OSBindings/Mac/Clock Signal/OpenGLView.h index 1c91803df..f1add96a3 100644 --- a/OSBindings/Mac/Clock Signal/OpenGLView.h +++ b/OSBindings/Mac/Clock Signal/OpenGLView.h @@ -13,6 +13,7 @@ @protocol CSOpenGLViewDelegate - (void)openGLView:(CSOpenGLView *)view didUpdateToTime:(CVTimeStamp)time; +- (void)openGLViewDrawView:(CSOpenGLView *)view; @end @interface CSOpenGLView : NSOpenGLView diff --git a/OSBindings/Mac/Clock Signal/OpenGLView.m b/OSBindings/Mac/Clock Signal/OpenGLView.m index 428032ac8..a56a22430 100644 --- a/OSBindings/Mac/Clock Signal/OpenGLView.m +++ b/OSBindings/Mac/Clock Signal/OpenGLView.m @@ -8,6 +8,7 @@ #import "OpenGLView.h" @import CoreVideo; +#import @implementation CSOpenGLView { CVDisplayLinkRef displayLink; @@ -23,7 +24,7 @@ CVDisplayLinkCreateWithActiveCGDisplays(&displayLink); // Set the renderer output callback function - CVDisplayLinkSetOutputCallback(displayLink, &MyDisplayLinkCallback, (__bridge void * __nullable)(self)); + CVDisplayLinkSetOutputCallback(displayLink, DisplayLinkCallback, (__bridge void * __nullable)(self)); // Set the display link for the current renderer CGLContextObj cglContext = [[self openGLContext] CGLContextObj]; @@ -34,7 +35,7 @@ CVDisplayLinkStart(displayLink); } -static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext) +static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext) { CSOpenGLView *view = (__bridge CSOpenGLView *)displayLinkContext; [view.delegate openGLView:view didUpdateToTime:*now]; @@ -47,4 +48,15 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime CVDisplayLinkRelease(displayLink); } +- (void)drawRect:(NSRect)dirtyRect +{ + [self.openGLContext makeCurrentContext]; + + CGSize viewSize = [self convertSize:self.bounds.size toView:self]; + glViewport((GLint)0, (GLint)0, (GLsizei)viewSize.width, (GLsizei)viewSize.height); + [self.delegate openGLViewDrawView:self]; + + glSwapAPPLE(); +} + @end