mirror of https://github.com/LIJI32/SameBoy.git
127 lines
5.1 KiB
Objective-C
127 lines
5.1 KiB
Objective-C
#import "GBCPUView.h"
|
|
|
|
#define SAMPLE_COUNT 0x100 // ~4 seconds
|
|
|
|
@implementation GBCPUView
|
|
{
|
|
double _samples[SAMPLE_COUNT];
|
|
size_t _position;
|
|
}
|
|
|
|
- (void)drawRect:(NSRect)dirtyRect
|
|
{
|
|
CGRect bounds = self.bounds;
|
|
NSSize size = bounds.size;
|
|
unsigned factor = [[self.window screen] backingScaleFactor];
|
|
|
|
NSBitmapImageRep *maskBitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
|
|
pixelsWide:(unsigned)size.width * factor
|
|
pixelsHigh:(unsigned)size.height * factor
|
|
bitsPerSample:8
|
|
samplesPerPixel:2
|
|
hasAlpha:true
|
|
isPlanar:false
|
|
colorSpaceName:NSDeviceWhiteColorSpace
|
|
bytesPerRow:size.width * 2 * factor
|
|
bitsPerPixel:16];
|
|
|
|
|
|
|
|
NSGraphicsContext *mainContext = [NSGraphicsContext currentContext];
|
|
|
|
|
|
NSColor *greenColor, *redColor;
|
|
if (@available(macOS 10.10, *)) {
|
|
greenColor = [NSColor systemGreenColor];
|
|
redColor = [NSColor systemRedColor];
|
|
}
|
|
else {
|
|
greenColor = [NSColor colorWithRed:3.0 / 16 green:0.5 blue:5.0 / 16 alpha:1.0];
|
|
redColor = [NSColor colorWithRed:13.0 / 16 green:0.25 blue:0.25 alpha:1.0];
|
|
}
|
|
|
|
|
|
NSBitmapImageRep *colorBitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
|
|
pixelsWide:SAMPLE_COUNT
|
|
pixelsHigh:1
|
|
bitsPerSample:8
|
|
samplesPerPixel:3
|
|
hasAlpha:false
|
|
isPlanar:false
|
|
colorSpaceName:NSDeviceRGBColorSpace
|
|
bytesPerRow:SAMPLE_COUNT * 4
|
|
bitsPerPixel:32];
|
|
|
|
unsigned lastFill = 0;
|
|
NSBezierPath *line = [NSBezierPath bezierPath];
|
|
bool isRed = false;
|
|
{
|
|
double sample = _samples[_position % SAMPLE_COUNT];
|
|
[line moveToPoint:NSMakePoint(0,
|
|
(sample * (size.height - 1) + 0.5) * factor)];
|
|
isRed = sample == 1;
|
|
}
|
|
|
|
|
|
[NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:colorBitmap]];
|
|
for (unsigned i = 1; i < SAMPLE_COUNT; i++) {
|
|
double sample = _samples[(i + _position) % SAMPLE_COUNT];
|
|
[line lineToPoint:NSMakePoint(size.width * i * factor / (SAMPLE_COUNT - 1),
|
|
(sample * (size.height - 1) + 0.5) * factor)];
|
|
|
|
if (isRed != (sample == 1)) {
|
|
// Color changed
|
|
[(isRed? redColor : greenColor) setFill];
|
|
NSRectFill(CGRectMake(lastFill, 0, i - lastFill, 1));
|
|
lastFill = i;
|
|
|
|
isRed ^= true;
|
|
}
|
|
}
|
|
[(isRed? redColor : greenColor) setFill];
|
|
NSRectFill(CGRectMake(lastFill, 0, SAMPLE_COUNT - lastFill, 1));
|
|
|
|
NSBezierPath *fill = [line copy];
|
|
[fill lineToPoint:NSMakePoint(size.width * factor, 0)];
|
|
[fill lineToPoint:NSMakePoint(0, 0)];
|
|
|
|
NSColor *strokeColor = [NSColor whiteColor];
|
|
NSColor *fillColor = [strokeColor colorWithAlphaComponent:1 / 3.0];
|
|
|
|
[NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:maskBitmap]];
|
|
[fillColor setFill];
|
|
[fill fill];
|
|
|
|
[strokeColor setStroke];
|
|
[line setLineWidth:factor];
|
|
[line stroke];
|
|
|
|
CGContextRef maskContext = CGContextRetain([NSGraphicsContext currentContext].graphicsPort);
|
|
[NSGraphicsContext setCurrentContext:mainContext];
|
|
CGContextSaveGState(mainContext.graphicsPort);
|
|
|
|
CGImageRef maskImage = CGBitmapContextCreateImage(maskContext);
|
|
CGContextClipToMask(mainContext.graphicsPort, bounds, maskImage);
|
|
CGImageRelease(maskImage);
|
|
|
|
NSImage *colors = [[NSImage alloc] initWithSize:NSMakeSize(SAMPLE_COUNT, 1)];
|
|
[colors addRepresentation:colorBitmap];
|
|
[colors drawInRect:bounds];
|
|
|
|
CGContextRestoreGState(mainContext.graphicsPort);
|
|
CGContextRelease(maskContext);
|
|
|
|
|
|
[super drawRect:dirtyRect];
|
|
}
|
|
|
|
- (void)addSample:(double)sample
|
|
{
|
|
_samples[_position++] = sample;
|
|
if (_position == SAMPLE_COUNT) {
|
|
_position = 0;
|
|
}
|
|
}
|
|
|
|
@end
|