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.