git.y1.nz

SameBoy

Accurate GB/GBC emulator
download: https://git.y1.nz/archives/sameboy.tar.gz
README | Files | Log | Refs | LICENSE

Cocoa/GBCPUView.m

      1 #import "GBCPUView.h"
      2 
      3 #define SAMPLE_COUNT 0x100 // ~4 seconds
      4 
      5 @implementation GBCPUView
      6 {
      7     double _samples[SAMPLE_COUNT];
      8     size_t _position;
      9 }
     10 
     11 - (void)drawRect:(NSRect)dirtyRect
     12 {
     13     CGRect bounds = self.bounds;
     14     NSSize size = bounds.size;
     15     unsigned factor = [[self.window screen] backingScaleFactor];
     16     
     17     NSBitmapImageRep *maskBitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
     18                                                                            pixelsWide:(unsigned)size.width * factor
     19                                                                            pixelsHigh:(unsigned)size.height * factor
     20                                                                         bitsPerSample:8
     21                                                                       samplesPerPixel:2
     22                                                                              hasAlpha:true
     23                                                                              isPlanar:false
     24                                                                        colorSpaceName:NSDeviceWhiteColorSpace
     25                                                                           bytesPerRow:size.width * 2 * factor
     26                                                                          bitsPerPixel:16];
     27     
     28 
     29     
     30     NSGraphicsContext *mainContext = [NSGraphicsContext currentContext];
     31     
     32     
     33     NSColor *greenColor, *redColor;
     34     if (@available(macOS 10.10, *)) {
     35         greenColor = [NSColor systemGreenColor];
     36         redColor = [NSColor systemRedColor];
     37     }
     38     else {
     39         greenColor = [NSColor colorWithRed:3.0 / 16 green:0.5 blue:5.0 / 16 alpha:1.0];
     40         redColor = [NSColor colorWithRed:13.0 / 16 green:0.25 blue:0.25 alpha:1.0];
     41     }
     42     
     43 
     44     NSBitmapImageRep *colorBitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
     45                                                                             pixelsWide:SAMPLE_COUNT
     46                                                                             pixelsHigh:1
     47                                                                          bitsPerSample:8
     48                                                                        samplesPerPixel:3
     49                                                                               hasAlpha:false
     50                                                                               isPlanar:false
     51                                                                         colorSpaceName:NSDeviceRGBColorSpace
     52                                                                            bytesPerRow:SAMPLE_COUNT * 4
     53                                                                           bitsPerPixel:32];
     54 
     55     unsigned lastFill = 0;
     56     NSBezierPath *line = [NSBezierPath bezierPath];
     57     bool isRed = false;
     58     {
     59         double sample = _samples[_position % SAMPLE_COUNT];
     60         [line moveToPoint:NSMakePoint(0,
     61                                       (sample * (size.height - 1) + 0.5) * factor)];
     62         isRed = sample == 1;
     63     }
     64     
     65     
     66     [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:colorBitmap]];
     67     for (unsigned i = 1; i < SAMPLE_COUNT; i++) {
     68         double sample = _samples[(i + _position) % SAMPLE_COUNT];
     69         [line lineToPoint:NSMakePoint(size.width * i * factor / (SAMPLE_COUNT - 1),
     70                                       (sample * (size.height - 1) + 0.5) * factor)];
     71         
     72         if (isRed != (sample == 1)) {
     73             // Color changed
     74             [(isRed? redColor : greenColor) setFill];
     75             NSRectFill(CGRectMake(lastFill, 0, i - lastFill, 1));
     76             lastFill = i;
     77             
     78             isRed ^= true;
     79         }
     80     }
     81     [(isRed? redColor : greenColor) setFill];
     82     NSRectFill(CGRectMake(lastFill, 0, SAMPLE_COUNT - lastFill, 1));
     83     
     84     NSBezierPath *fill = [line copy];
     85     [fill lineToPoint:NSMakePoint(size.width * factor, 0)];
     86     [fill lineToPoint:NSMakePoint(0, 0)];
     87     
     88     NSColor *strokeColor = [NSColor whiteColor];
     89     NSColor *fillColor = [strokeColor colorWithAlphaComponent:1 / 3.0];
     90     
     91     [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:maskBitmap]];
     92     [fillColor setFill];
     93     [fill fill];
     94     
     95     [strokeColor setStroke];
     96     [line setLineWidth:factor];
     97     [line stroke];
     98     
     99     CGContextRef maskContext = CGContextRetain([NSGraphicsContext currentContext].graphicsPort);
    100     [NSGraphicsContext setCurrentContext:mainContext];
    101     CGContextSaveGState(mainContext.graphicsPort);
    102     
    103     CGImageRef maskImage = CGBitmapContextCreateImage(maskContext);
    104     CGContextClipToMask(mainContext.graphicsPort, bounds, maskImage);
    105     CGImageRelease(maskImage);
    106     
    107     NSImage *colors = [[NSImage alloc] initWithSize:NSMakeSize(SAMPLE_COUNT, 1)];
    108     [colors addRepresentation:colorBitmap];
    109     [colors drawInRect:bounds];
    110     
    111     CGContextRestoreGState(mainContext.graphicsPort);
    112     CGContextRelease(maskContext);
    113     
    114     
    115     [super drawRect:dirtyRect];
    116 }
    117 
    118 - (void)addSample:(double)sample
    119 {
    120     _samples[_position++] = sample;
    121     if (_position == SAMPLE_COUNT) {
    122         _position = 0;
    123     }
    124 }
    125 
    126 @end

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.