diff --git a/Cocoa/Document.h b/Cocoa/Document.h index 0b1d81c..e92c180 100644 --- a/Cocoa/Document.h +++ b/Cocoa/Document.h @@ -6,9 +6,10 @@ #include "GBOSDView.h" @class GBCheatWindowController; +@class GBPaletteView; @class GBObjectView; -@interface Document : NSDocument +@interface Document : NSDocument @property (nonatomic, readonly) GB_gameboy_t *gb; @property (nonatomic, strong) IBOutlet GBView *view; @property (nonatomic, strong) IBOutlet NSTextView *consoleOutput; @@ -30,7 +31,7 @@ @property (nonatomic, strong) IBOutlet NSTabView *vramTabView; @property (nonatomic, strong) IBOutlet NSPanel *vramWindow; @property (nonatomic, strong) IBOutlet NSTextField *vramStatusLabel; -@property (nonatomic, strong) IBOutlet NSTableView *paletteTableView; +@property (nonatomic, strong) IBOutlet GBPaletteView *paletteView; @property (nonatomic, strong) IBOutlet GBObjectView *objectView; @property (nonatomic, strong) IBOutlet NSPanel *printerFeedWindow; @property (nonatomic, strong) IBOutlet NSImageView *feedImageView; diff --git a/Cocoa/Document.m b/Cocoa/Document.m index e2dfb43..8f02f86 100644 --- a/Cocoa/Document.m +++ b/Cocoa/Document.m @@ -12,7 +12,7 @@ #import "BigSurToolbar.h" #import "GBPaletteEditorController.h" #import "GBObjectView.h" - +#import "GBPaletteView.h" #define GB_MODEL_PAL_BIT_OLD 0x1000 @@ -1477,7 +1477,7 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency) /* Palettes */ { dispatch_async(dispatch_get_main_queue(), ^{ - [self.paletteTableView reloadData]; + [self.paletteView reloadData:self]; }); } break; @@ -1751,7 +1751,7 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency) window_rect.size.height = 512 + height_diff + 48; break; case 3: - window_rect.size.height = 20 * 16 + height_diff + 34; + window_rect.size.height = 24 * 16 + height_diff; break; default: @@ -1824,45 +1824,11 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency) } } -- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView -{ - if (tableView == self.paletteTableView) { - return 16; /* 8 BG palettes, 8 OBJ palettes*/ - } - return 0; -} - - (GB_oam_info_t *)oamInfo { return _oamInfo; } -- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row -{ - NSUInteger columnIndex = [[tableView tableColumns] indexOfObject:tableColumn]; - if (tableView == self.paletteTableView) { - if (columnIndex == 0) { - return [NSString stringWithFormat:@"%s %u", row >= 8 ? "Object" : "Background", (unsigned)(row & 7)]; - } - - uint8_t *palette_data = GB_get_direct_access(&gb, row >= 8? GB_DIRECT_ACCESS_OBP : GB_DIRECT_ACCESS_BGP, NULL, NULL); - - uint16_t index = columnIndex - 1 + (row & 7) * 4; - return @((palette_data[(index << 1) + 1] << 8) | palette_data[(index << 1)]); - } - return nil; -} - -- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(NSInteger)row -{ - return false; -} - -- (BOOL)tableView:(NSTableView *)tableView shouldEditTableColumn:(nullable NSTableColumn *)tableColumn row:(NSInteger)row -{ - return false; -} - - (IBAction)showVRAMViewer:(id)sender { [self.vramWindow makeKeyAndOrderFront:sender]; diff --git a/Cocoa/Document.xib b/Cocoa/Document.xib index be5cdea..e0b6262 100644 --- a/Cocoa/Document.xib +++ b/Cocoa/Document.xib @@ -27,7 +27,7 @@ - + @@ -341,17 +341,17 @@ - + - + - + @@ -360,7 +360,7 @@ - + @@ -392,7 +392,7 @@ - + @@ -431,7 +431,7 @@ - + @@ -464,7 +464,7 @@ - + @@ -482,7 +482,7 @@ - + @@ -504,18 +504,18 @@ - + - + - + - + @@ -523,11 +523,11 @@ - + - + @@ -536,106 +536,13 @@ - + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/Cocoa/GBColorCell.h b/Cocoa/GBColorCell.h deleted file mode 100644 index a622c78..0000000 --- a/Cocoa/GBColorCell.h +++ /dev/null @@ -1,5 +0,0 @@ -#import - -@interface GBColorCell : NSTextFieldCell - -@end diff --git a/Cocoa/GBColorCell.m b/Cocoa/GBColorCell.m deleted file mode 100644 index be8b4a9..0000000 --- a/Cocoa/GBColorCell.m +++ /dev/null @@ -1,49 +0,0 @@ -#import "GBColorCell.h" - -static inline double scale_channel(uint8_t x) -{ - x &= 0x1F; - return x / 31.0; -} - -@implementation GBColorCell -{ - NSInteger _integerValue; -} - -- (void)setObjectValue:(id)objectValue -{ - _integerValue = [objectValue integerValue]; - uint8_t r = _integerValue & 0x1F, - g = (_integerValue >> 5) & 0x1F, - b = (_integerValue >> 10) & 0x1F; - super.objectValue = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"$%04x", (uint16_t)(_integerValue & 0x7FFF)] attributes:@{ - NSForegroundColorAttributeName: r * 3 + g * 4 + b * 2 > 120? [NSColor blackColor] : [NSColor whiteColor], - NSFontAttributeName: [NSFont userFixedPitchFontOfSize:12] - }]; -} - -- (NSInteger)integerValue -{ - return _integerValue; -} - -- (int)intValue -{ - return (int)_integerValue; -} - - -- (NSColor *) backgroundColor -{ - /* Todo: color correction */ - uint16_t color = self.integerValue; - return [NSColor colorWithRed:scale_channel(color) green:scale_channel(color >> 5) blue:scale_channel(color >> 10) alpha:1.0]; -} - -- (BOOL)drawsBackground -{ - return true; -} - -@end diff --git a/Cocoa/GBObjectView.m b/Cocoa/GBObjectView.m index ee09d64..0fb22a1 100644 --- a/Cocoa/GBObjectView.m +++ b/Cocoa/GBObjectView.m @@ -102,7 +102,7 @@ } NSRect frame = self.frame; - CGFloat newHeight = MAX(68 * ((length + 3) / 4), 408); + CGFloat newHeight = MAX(68 * ((length + 3) / 4), self.superview.frame.size.height); frame.origin.y -= newHeight - frame.size.height; frame.size.height = newHeight; self.frame = frame; diff --git a/Cocoa/GBPaletteView.h b/Cocoa/GBPaletteView.h new file mode 100644 index 0000000..d92cb5f --- /dev/null +++ b/Cocoa/GBPaletteView.h @@ -0,0 +1,6 @@ +#import +#import "Document.h" + +@interface GBPaletteView : NSView +- (void)reloadData:(Document *)document; +@end diff --git a/Cocoa/GBPaletteView.m b/Cocoa/GBPaletteView.m new file mode 100644 index 0000000..6aeddc0 --- /dev/null +++ b/Cocoa/GBPaletteView.m @@ -0,0 +1,91 @@ +#import "GBPaletteView.h" + +@interface GBPaletteViewItem : NSObject +@property IBOutlet NSView *view; +@property (strong) IBOutlet NSTextField *label; +@property (strong) IBOutlet NSTextField *color0; +@property (strong) IBOutlet NSTextField *color1; +@property (strong) IBOutlet NSTextField *color2; +@property (strong) IBOutlet NSTextField *color3; +@end + +@implementation GBPaletteViewItem +@end + +@implementation GBPaletteView +{ + NSMutableArray *_colors; +} + +- (instancetype)initWithCoder:(NSCoder *)coder +{ + self = [super initWithCoder:coder]; + _colors = [NSMutableArray array]; + CGFloat height = self.frame.size.height; + for (unsigned i = 0; i < 16; i++) { + GBPaletteViewItem *item = [[GBPaletteViewItem alloc] init]; + [[NSBundle mainBundle] loadNibNamed:@"GBPaletteViewRow" owner:item topLevelObjects:nil]; + [self addSubview:item.view]; + [item.view setFrameOrigin:NSMakePoint(0, height - (i * 24) - 24)]; + item.label.stringValue = [NSString stringWithFormat:@"%@ %d", i < 8? @"Background" : @"Object", i % 8]; + item.view.autoresizingMask = NSViewMaxXMargin | NSViewMinYMargin; + [_colors addObject:item.color0]; + [_colors addObject:item.color1]; + [_colors addObject:item.color2]; + [_colors addObject:item.color3]; + + } + return self; +} + +- (void)reloadData:(Document *)document +{ + GB_gameboy_t *gb = document.gb; + uint8_t *bg = GB_get_direct_access(gb, GB_DIRECT_ACCESS_BGP, NULL, NULL); + uint8_t *obj = GB_get_direct_access(gb, GB_DIRECT_ACCESS_OBP, NULL, NULL); + + for (unsigned i = 0; i < 4 * 8 * 2; i++) { + uint8_t index = i % (4 * 8); + uint8_t *palette = i >= 4 * 8 ? obj : bg; + uint16_t color = (palette[(index << 1) + 1] << 8) | palette[(index << 1)]; + uint32_t nativeColor = GB_convert_rgb15(gb, color, false); + + uint8_t r = color & 0x1F, + g = (color >> 5) & 0x1F, + b = (color >> 10) & 0x1F; + + NSTextField *field = _colors[i]; + field.stringValue = [NSString stringWithFormat:@"$%04X", color]; + field.textColor = r * 3 + g * 4 + b * 2 > 120? [NSColor blackColor] : [NSColor whiteColor]; + field.toolTip = [NSString stringWithFormat:@"Red: %d, Green: %d, Blue: %d", r, g, b]; + field.backgroundColor = [NSColor colorWithRed:(nativeColor & 0xFF) / 255.0 + green:((nativeColor >> 8) & 0xFF) / 255.0 + blue:((nativeColor >> 16) & 0xFF) / 255.0 + alpha:1.0]; + } +} + +- (void)drawRect:(NSRect)dirtyRect +{ + NSRect frame = self.frame; + if (@available(macOS 10.14, *)) { + [[NSColor alternatingContentBackgroundColors].lastObject setFill]; + } + else { + [[NSColor colorWithDeviceWhite:0.96 alpha:1] setFill]; + } + for (unsigned i = 1; i <= 8; i++) { + NSRectFill(NSMakeRect(0, frame.size.height - i * 24 * 2, frame.size.width, 24)); + } + + if (@available(macOS 10.14, *)) { + [[NSColor alternatingContentBackgroundColors].firstObject setFill]; + } + else { + [[NSColor controlBackgroundColor] setFill]; + } + for (unsigned i = 0; i < 8; i++) { + NSRectFill(NSMakeRect(0, frame.size.height - i * 24 * 2 - 24, frame.size.width, 24)); + } +} +@end diff --git a/Cocoa/GBPaletteViewRow.xib b/Cocoa/GBPaletteViewRow.xib new file mode 100644 index 0000000..950b199 --- /dev/null +++ b/Cocoa/GBPaletteViewRow.xib @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +