File: GBCPUView.m

package info (click to toggle)
sameboy 1.0.2%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 10,632 kB
  • sloc: ansic: 29,954; objc: 22,249; asm: 1,424; pascal: 1,373; makefile: 1,064; xml: 111
file content (126 lines) | stat: -rw-r--r-- 5,199 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#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