Added visualizer to the GBS player, various GBS UI improvements
This commit is contained in:
parent
77384a5f6a
commit
6ddfcc9725
@ -2,6 +2,7 @@
|
|||||||
#include "GBView.h"
|
#include "GBView.h"
|
||||||
#include "GBImageView.h"
|
#include "GBImageView.h"
|
||||||
#include "GBSplitView.h"
|
#include "GBSplitView.h"
|
||||||
|
#include "GBVisualizerView.h"
|
||||||
|
|
||||||
@class GBCheatWindowController;
|
@class GBCheatWindowController;
|
||||||
|
|
||||||
@ -47,6 +48,7 @@
|
|||||||
@property (strong) IBOutlet NSButton *gbsPlayPauseButton;
|
@property (strong) IBOutlet NSButton *gbsPlayPauseButton;
|
||||||
@property (strong) IBOutlet NSButton *gbsRewindButton;
|
@property (strong) IBOutlet NSButton *gbsRewindButton;
|
||||||
@property (strong) IBOutlet NSSegmentedControl *gbsNextPrevButton;
|
@property (strong) IBOutlet NSSegmentedControl *gbsNextPrevButton;
|
||||||
|
@property (strong) IBOutlet GBVisualizerView *gbsVisualizer;
|
||||||
|
|
||||||
-(uint8_t) readMemory:(uint16_t) addr;
|
-(uint8_t) readMemory:(uint16_t) addr;
|
||||||
-(void) writeMemory:(uint16_t) addr value:(uint8_t)value;
|
-(void) writeMemory:(uint16_t) addr value:(uint8_t)value;
|
||||||
|
@ -318,6 +318,11 @@ static void infraredStateChanged(GB_gameboy_t *gb, bool on)
|
|||||||
|
|
||||||
- (void) vblank
|
- (void) vblank
|
||||||
{
|
{
|
||||||
|
if (_gbsVisualizer) {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[_gbsVisualizer setNeedsDisplay:YES];
|
||||||
|
});
|
||||||
|
}
|
||||||
[self.view flip];
|
[self.view flip];
|
||||||
if (borderModeChanged) {
|
if (borderModeChanged) {
|
||||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||||
@ -344,6 +349,9 @@ static void infraredStateChanged(GB_gameboy_t *gb, bool on)
|
|||||||
|
|
||||||
- (void)gotNewSample:(GB_sample_t *)sample
|
- (void)gotNewSample:(GB_sample_t *)sample
|
||||||
{
|
{
|
||||||
|
if (_gbsVisualizer) {
|
||||||
|
[_gbsVisualizer addSample:sample];
|
||||||
|
}
|
||||||
[audioLock lock];
|
[audioLock lock];
|
||||||
if (self.audioClient.isPlaying) {
|
if (self.audioClient.isPlaying) {
|
||||||
if (audioBufferPosition == audioBufferSize) {
|
if (audioBufferPosition == audioBufferSize) {
|
||||||
@ -837,6 +845,9 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
|
|||||||
|
|
||||||
- (IBAction)changeGBSTrack:(id)sender
|
- (IBAction)changeGBSTrack:(id)sender
|
||||||
{
|
{
|
||||||
|
if (!running) {
|
||||||
|
[self start];
|
||||||
|
}
|
||||||
[self performAtomicBlock:^{
|
[self performAtomicBlock:^{
|
||||||
GB_gbs_switch_track(&gb, self.gbsTracks.indexOfSelectedItem);
|
GB_gbs_switch_track(&gb, self.gbsTracks.indexOfSelectedItem);
|
||||||
}];
|
}];
|
||||||
@ -878,7 +889,9 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
|
|||||||
[_mainWindow standardWindowButton:NSWindowZoomButton].enabled = false;
|
[_mainWindow standardWindowButton:NSWindowZoomButton].enabled = false;
|
||||||
});
|
});
|
||||||
[_mainWindow.contentView addSubview:self.gbsPlayerView];
|
[_mainWindow.contentView addSubview:self.gbsPlayerView];
|
||||||
|
_mainWindow.movableByWindowBackground = true;
|
||||||
|
[_mainWindow setContentBorderThickness:24 forEdge:NSRectEdgeMinY];
|
||||||
|
|
||||||
self.gbsTitle.stringValue = [NSString stringWithCString:info->title encoding:NSISOLatin1StringEncoding] ?: @"GBS Player";
|
self.gbsTitle.stringValue = [NSString stringWithCString:info->title encoding:NSISOLatin1StringEncoding] ?: @"GBS Player";
|
||||||
self.gbsAuthor.stringValue = [NSString stringWithCString:info->author encoding:NSISOLatin1StringEncoding] ?: @"Unknown Composer";
|
self.gbsAuthor.stringValue = [NSString stringWithCString:info->author encoding:NSISOLatin1StringEncoding] ?: @"Unknown Composer";
|
||||||
NSString *copyright = [NSString stringWithCString:info->copyright encoding:NSISOLatin1StringEncoding];
|
NSString *copyright = [NSString stringWithCString:info->copyright encoding:NSISOLatin1StringEncoding];
|
||||||
|
@ -16,44 +16,36 @@
|
|||||||
<outlet property="gbsRewindButton" destination="0yD-Sp-Ilo" id="FgR-xd-JW5"/>
|
<outlet property="gbsRewindButton" destination="0yD-Sp-Ilo" id="FgR-xd-JW5"/>
|
||||||
<outlet property="gbsTitle" destination="H3v-X3-48q" id="DCl-wL-oy8"/>
|
<outlet property="gbsTitle" destination="H3v-X3-48q" id="DCl-wL-oy8"/>
|
||||||
<outlet property="gbsTracks" destination="I1T-VS-Vse" id="Vk4-GP-RjB"/>
|
<outlet property="gbsTracks" destination="I1T-VS-Vse" id="Vk4-GP-RjB"/>
|
||||||
|
<outlet property="gbsVisualizer" destination="Q3o-bK-DIN" id="1YC-C5-Je6"/>
|
||||||
</connections>
|
</connections>
|
||||||
</customObject>
|
</customObject>
|
||||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||||
<customView id="c22-O7-iKe">
|
<customView id="c22-O7-iKe">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="332" height="142"/>
|
<rect key="frame" x="0.0" y="0.0" width="332" height="221"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="H3v-X3-48q">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="H3v-X3-48q">
|
||||||
<rect key="frame" x="19.5" y="103" width="296" height="19"/>
|
<rect key="frame" x="18" y="192" width="296" height="19"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="clipping" selectable="YES" alignment="center" title="Title" id="BwZ-Zj-sP6">
|
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="Title" id="BwZ-Zj-sP6">
|
||||||
<font key="font" metaFont="systemBold" size="16"/>
|
<font key="font" metaFont="systemBold" size="16"/>
|
||||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="gaD-ZH-Beh">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="gaD-ZH-Beh">
|
||||||
<rect key="frame" x="19.5" y="79" width="296" height="16"/>
|
<rect key="frame" x="18" y="166" width="296" height="16"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" lineBreakMode="clipping" selectable="YES" alignment="center" title="Author" id="IgT-r1-T38">
|
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="Author" id="IgT-r1-T38">
|
||||||
<font key="font" metaFont="system"/>
|
|
||||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
|
||||||
</textFieldCell>
|
|
||||||
</textField>
|
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="2dl-dH-E3J">
|
|
||||||
<rect key="frame" x="18.5" y="24" width="296" height="16"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxY="YES"/>
|
|
||||||
<textFieldCell key="cell" lineBreakMode="clipping" selectable="YES" title="Copyright" id="nM9-oF-OV9">
|
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<button focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="qxJ-pH-d0y">
|
<button focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="qxJ-pH-d0y">
|
||||||
<rect key="frame" x="61.5" y="48" width="39" height="23"/>
|
<rect key="frame" x="61.5" y="127" width="39" height="23"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="Play" imagePosition="only" alignment="center" alternateImage="Pause" state="on" borderStyle="border" focusRingType="none" inset="2" id="3ZK-br-UrS">
|
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="Play" imagePosition="only" alignment="center" alternateImage="Pause" state="on" borderStyle="border" focusRingType="none" inset="2" id="3ZK-br-UrS">
|
||||||
<behavior key="behavior" pushIn="YES" changeContents="YES" lightByContents="YES"/>
|
<behavior key="behavior" pushIn="YES" changeContents="YES" lightByContents="YES"/>
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
@ -63,8 +55,8 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0yD-Sp-Ilo">
|
<button focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0yD-Sp-Ilo">
|
||||||
<rect key="frame" x="19.5" y="48" width="38" height="23"/>
|
<rect key="frame" x="19.5" y="127" width="38" height="23"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="Rewind" imagePosition="only" alignment="center" state="on" borderStyle="border" focusRingType="none" inset="2" id="ZIF-TP-Fqn">
|
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="Rewind" imagePosition="only" alignment="center" state="on" borderStyle="border" focusRingType="none" inset="2" id="ZIF-TP-Fqn">
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
@ -74,8 +66,8 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<popUpButton focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="I1T-VS-Vse">
|
<popUpButton focusRingType="none" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="I1T-VS-Vse">
|
||||||
<rect key="frame" x="105.5" y="48" width="131" height="23"/>
|
<rect key="frame" x="106" y="127" width="131" height="23"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<popUpButtonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="border" focusRingType="none" imageScaling="proportionallyDown" inset="2" id="YJh-dI-A5D">
|
<popUpButtonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="border" focusRingType="none" imageScaling="proportionallyDown" inset="2" id="YJh-dI-A5D">
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
<font key="font" metaFont="menu"/>
|
<font key="font" metaFont="menu"/>
|
||||||
@ -86,8 +78,8 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</popUpButton>
|
</popUpButton>
|
||||||
<segmentedControl verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="SRS-M5-VVL">
|
<segmentedControl verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="SRS-M5-VVL">
|
||||||
<rect key="frame" x="240.5" y="48" width="72" height="23"/>
|
<rect key="frame" x="240.5" y="127" width="72" height="23"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<segmentedCell key="cell" borderStyle="border" alignment="left" style="texturedRounded" trackingMode="momentary" id="cmq-I8-cFL">
|
<segmentedCell key="cell" borderStyle="border" alignment="left" style="texturedRounded" trackingMode="momentary" id="cmq-I8-cFL">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<segments>
|
<segments>
|
||||||
@ -99,8 +91,31 @@
|
|||||||
<action selector="gbsNextPrevPushed:" target="-2" id="roN-Iy-tDQ"/>
|
<action selector="gbsNextPrevPushed:" target="-2" id="roN-Iy-tDQ"/>
|
||||||
</connections>
|
</connections>
|
||||||
</segmentedControl>
|
</segmentedControl>
|
||||||
|
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="b9A-cd-ias">
|
||||||
|
<rect key="frame" x="0.0" y="117" width="332" height="5"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
|
</box>
|
||||||
|
<customView appearanceType="darkAqua" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="tRy-Gw-IaG" customClass="GBOptionalVisualEffectView">
|
||||||
|
<rect key="frame" x="0.0" y="24" width="332" height="95"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
|
<subviews>
|
||||||
|
<customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Q3o-bK-DIN" customClass="GBVisualizerView">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="332" height="95"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
|
</customView>
|
||||||
|
</subviews>
|
||||||
|
</customView>
|
||||||
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="2dl-dH-E3J">
|
||||||
|
<rect key="frame" x="18" y="5" width="296" height="14"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMinY="YES"/>
|
||||||
|
<textFieldCell key="cell" controlSize="small" lineBreakMode="clipping" alignment="center" title="Copyright" id="nM9-oF-OV9">
|
||||||
|
<font key="font" metaFont="smallSystem"/>
|
||||||
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
</textField>
|
||||||
</subviews>
|
</subviews>
|
||||||
<point key="canvasLocation" x="67" y="253"/>
|
<point key="canvasLocation" x="67" y="292.5"/>
|
||||||
</customView>
|
</customView>
|
||||||
</objects>
|
</objects>
|
||||||
<resources>
|
<resources>
|
||||||
|
@ -123,7 +123,7 @@ static const vector_float2 rect[] =
|
|||||||
command_queue = [device newCommandQueue];
|
command_queue = [device newCommandQueue];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size
|
- (void)mtkView:(MTKView *)view drawableSizeWillChange:(CGSize)size
|
||||||
{
|
{
|
||||||
output_resolution = (vector_float2){size.width, size.height};
|
output_resolution = (vector_float2){size.width, size.height};
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
@ -131,7 +131,7 @@ static const vector_float2 rect[] =
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)drawInMTKView:(nonnull MTKView *)view
|
- (void)drawInMTKView:(MTKView *)view
|
||||||
{
|
{
|
||||||
if (!(view.window.occlusionState & NSWindowOcclusionStateVisible)) return;
|
if (!(view.window.occlusionState & NSWindowOcclusionStateVisible)) return;
|
||||||
if (!self.gb) return;
|
if (!self.gb) return;
|
||||||
|
14
Cocoa/GBVisualizerView.h
Normal file
14
Cocoa/GBVisualizerView.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
//
|
||||||
|
// GBVisualizerView.h
|
||||||
|
// SameBoySDL
|
||||||
|
//
|
||||||
|
// Created by Lior Halphon on 7/4/21.
|
||||||
|
// Copyright © 2021 Lior Halphon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#include <Core/gb.h>
|
||||||
|
|
||||||
|
@interface GBVisualizerView : NSView
|
||||||
|
- (void)addSample:(GB_sample_t *)sample;
|
||||||
|
@end
|
95
Cocoa/GBVisualizerView.m
Normal file
95
Cocoa/GBVisualizerView.m
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
//
|
||||||
|
// GBVisualizerView.m
|
||||||
|
// SameBoySDL
|
||||||
|
//
|
||||||
|
// Created by Lior Halphon on 7/4/21.
|
||||||
|
// Copyright © 2021 Lior Halphon. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "GBVisualizerView.h"
|
||||||
|
#include <Core/gb.h>
|
||||||
|
|
||||||
|
#define SAMPLE_COUNT 1024
|
||||||
|
|
||||||
|
static NSColor *color_to_effect_color(typeof(GB_PALETTE_DMG.colors[0]) color)
|
||||||
|
{
|
||||||
|
if (@available(macOS 10.10, *)) {
|
||||||
|
double tint = MAX(color.r, MAX(color.g, color.b)) + 64;
|
||||||
|
|
||||||
|
return [NSColor colorWithRed:color.r / tint
|
||||||
|
green:color.g / tint
|
||||||
|
blue:color.b / tint
|
||||||
|
alpha:tint/(255 + 64)];
|
||||||
|
|
||||||
|
}
|
||||||
|
return [NSColor colorWithRed:color.r / 255.0
|
||||||
|
green:color.g / 255.0
|
||||||
|
blue:color.b / 255.0
|
||||||
|
alpha:1.0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@implementation GBVisualizerView
|
||||||
|
{
|
||||||
|
GB_sample_t _samples[SAMPLE_COUNT];
|
||||||
|
size_t _position;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)drawRect:(NSRect)dirtyRect
|
||||||
|
{
|
||||||
|
const GB_palette_t *palette;
|
||||||
|
switch ([[NSUserDefaults standardUserDefaults] integerForKey:@"GBColorPalette"]) {
|
||||||
|
case 1:
|
||||||
|
palette = &GB_PALETTE_DMG;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
palette = &GB_PALETTE_MGB;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
palette = &GB_PALETTE_GBL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
palette = &GB_PALETTE_GREY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
NSSize size = self.bounds.size;
|
||||||
|
|
||||||
|
[color_to_effect_color(palette->colors[0]) setFill];
|
||||||
|
NSRectFill(self.bounds);
|
||||||
|
|
||||||
|
NSBezierPath *line = [NSBezierPath bezierPath];
|
||||||
|
[line moveToPoint:NSMakePoint(0, size.height / 2)];
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < SAMPLE_COUNT; i++) {
|
||||||
|
GB_sample_t *sample = _samples + ((i + _position) % SAMPLE_COUNT);
|
||||||
|
double volume = ((signed)sample->left + (signed)sample->right) / 32768.0;
|
||||||
|
[line lineToPoint:NSMakePoint(size.width * (i + 0.5) / SAMPLE_COUNT,
|
||||||
|
(volume + 1) * size.height / 2)];
|
||||||
|
}
|
||||||
|
|
||||||
|
[line lineToPoint:NSMakePoint(size.width, size.height / 2)];
|
||||||
|
[line setLineWidth:1.0];
|
||||||
|
|
||||||
|
[color_to_effect_color(palette->colors[2]) setFill];
|
||||||
|
[line fill];
|
||||||
|
|
||||||
|
[color_to_effect_color(palette->colors[1]) setFill];
|
||||||
|
NSRectFill(NSMakeRect(0, size.height / 2 - 0.5, size.width, 1));
|
||||||
|
|
||||||
|
[color_to_effect_color(palette->colors[3]) setStroke];
|
||||||
|
[line stroke];
|
||||||
|
|
||||||
|
[super drawRect:dirtyRect];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)addSample:(GB_sample_t *)sample
|
||||||
|
{
|
||||||
|
_samples[_position++] = *sample;
|
||||||
|
if (_position == SAMPLE_COUNT) {
|
||||||
|
_position = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
Loading…
Reference in New Issue
Block a user