New and faster OAM viewer

This commit is contained in:
Lior Halphon 2022-02-20 01:58:59 +02:00
parent 3c6a46830d
commit f02bb2f0e6
8 changed files with 259 additions and 209 deletions

View File

@ -6,6 +6,7 @@
#include "GBOSDView.h" #include "GBOSDView.h"
@class GBCheatWindowController; @class GBCheatWindowController;
@class GBObjectView;
@interface Document : NSDocument <NSWindowDelegate, GBImageViewDelegate, NSTableViewDataSource, NSTableViewDelegate, NSSplitViewDelegate> @interface Document : NSDocument <NSWindowDelegate, GBImageViewDelegate, NSTableViewDataSource, NSTableViewDelegate, NSSplitViewDelegate>
@property (nonatomic, readonly) GB_gameboy_t *gb; @property (nonatomic, readonly) GB_gameboy_t *gb;
@ -30,7 +31,7 @@
@property (nonatomic, strong) IBOutlet NSPanel *vramWindow; @property (nonatomic, strong) IBOutlet NSPanel *vramWindow;
@property (nonatomic, strong) IBOutlet NSTextField *vramStatusLabel; @property (nonatomic, strong) IBOutlet NSTextField *vramStatusLabel;
@property (nonatomic, strong) IBOutlet NSTableView *paletteTableView; @property (nonatomic, strong) IBOutlet NSTableView *paletteTableView;
@property (nonatomic, strong) IBOutlet NSTableView *objectsTableView; @property (nonatomic, strong) IBOutlet GBObjectView *objectView;
@property (nonatomic, strong) IBOutlet NSPanel *printerFeedWindow; @property (nonatomic, strong) IBOutlet NSPanel *printerFeedWindow;
@property (nonatomic, strong) IBOutlet NSImageView *feedImageView; @property (nonatomic, strong) IBOutlet NSImageView *feedImageView;
@property (nonatomic, strong) IBOutlet NSTextView *debuggerSideViewInput; @property (nonatomic, strong) IBOutlet NSTextView *debuggerSideViewInput;
@ -51,7 +52,11 @@
@property (strong) IBOutlet NSSegmentedControl *gbsNextPrevButton; @property (strong) IBOutlet NSSegmentedControl *gbsNextPrevButton;
@property (strong) IBOutlet GBVisualizerView *gbsVisualizer; @property (strong) IBOutlet GBVisualizerView *gbsVisualizer;
@property (strong) IBOutlet GBOSDView *osdView; @property (strong) IBOutlet GBOSDView *osdView;
@property (readonly) GB_oam_info_t *oamInfo;
@property uint8_t oamCount;
@property uint8_t oamHeight;
+ (NSImage *) imageFromData:(NSData *)data width:(NSUInteger) width height:(NSUInteger) height scale:(double) scale;
-(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;
-(void) performAtomicBlock: (void (^)())block; -(void) performAtomicBlock: (void (^)())block;

View File

@ -1,16 +1,18 @@
#include <AVFoundation/AVFoundation.h> #import <AVFoundation/AVFoundation.h>
#include <CoreAudio/CoreAudio.h> #import <CoreAudio/CoreAudio.h>
#include <Core/gb.h> #import <Core/gb.h>
#include "GBAudioClient.h" #import "GBAudioClient.h"
#include "Document.h" #import "Document.h"
#include "AppDelegate.h" #import "AppDelegate.h"
#include "HexFiend/HexFiend.h" #import "HexFiend/HexFiend.h"
#include "GBMemoryByteArray.h" #import "GBMemoryByteArray.h"
#include "GBWarningPopover.h" #import "GBWarningPopover.h"
#include "GBCheatWindowController.h" #import "GBCheatWindowController.h"
#include "GBTerminalTextFieldCell.h" #import "GBTerminalTextFieldCell.h"
#include "BigSurToolbar.h" #import "BigSurToolbar.h"
#import "GBPaletteEditorController.h" #import "GBPaletteEditorController.h"
#import "GBObjectView.h"
#define GB_MODEL_PAL_BIT_OLD 0x1000 #define GB_MODEL_PAL_BIT_OLD 0x1000
@ -46,10 +48,7 @@ enum model {
AVCaptureConnection *cameraConnection; AVCaptureConnection *cameraConnection;
AVCaptureStillImageOutput *cameraOutput; AVCaptureStillImageOutput *cameraOutput;
GB_oam_info_t oamInfo[40]; GB_oam_info_t _oamInfo[40];
uint16_t oamCount;
uint8_t oamHeight;
bool oamUpdating;
NSMutableData *currentPrinterImageData; NSMutableData *currentPrinterImageData;
enum {GBAccessoryNone, GBAccessoryPrinter, GBAccessoryWorkboy, GBAccessoryLinkCable} accessory; enum {GBAccessoryNone, GBAccessoryPrinter, GBAccessoryWorkboy, GBAccessoryLinkCable} accessory;
@ -1467,13 +1466,9 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
case 2: case 2:
/* OAM */ /* OAM */
{ {
oamCount = GB_get_oam_info(&gb, oamInfo, &oamHeight); _oamCount = GB_get_oam_info(&gb, _oamInfo, &_oamHeight);
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
if (!oamUpdating) { [self.objectView reloadData:self];
oamUpdating = true;
[self.objectsTableView reloadData];
oamUpdating = false;
}
}); });
} }
break; break;
@ -1749,10 +1744,10 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
window_rect.origin.y += window_rect.size.height; window_rect.origin.y += window_rect.size.height;
switch ([sender selectedSegment]) { switch ([sender selectedSegment]) {
case 0: case 0:
case 2:
window_rect.size.height = 384 + height_diff + 48; window_rect.size.height = 384 + height_diff + 48;
break; break;
case 1: case 1:
case 2:
window_rect.size.height = 512 + height_diff + 48; window_rect.size.height = 512 + height_diff + 48;
break; break;
case 3: case 3:
@ -1834,12 +1829,14 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
if (tableView == self.paletteTableView) { if (tableView == self.paletteTableView) {
return 16; /* 8 BG palettes, 8 OBJ palettes*/ return 16; /* 8 BG palettes, 8 OBJ palettes*/
} }
else if (tableView == self.objectsTableView) {
return oamCount;
}
return 0; return 0;
} }
- (GB_oam_info_t *)oamInfo
{
return _oamInfo;
}
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row - (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{ {
NSUInteger columnIndex = [[tableView tableColumns] indexOfObject:tableColumn]; NSUInteger columnIndex = [[tableView tableColumns] indexOfObject:tableColumn];
@ -1853,50 +1850,12 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency)
uint16_t index = columnIndex - 1 + (row & 7) * 4; uint16_t index = columnIndex - 1 + (row & 7) * 4;
return @((palette_data[(index << 1) + 1] << 8) | palette_data[(index << 1)]); return @((palette_data[(index << 1) + 1] << 8) | palette_data[(index << 1)]);
} }
else if (tableView == self.objectsTableView) {
switch (columnIndex) {
case 0:
return [Document imageFromData:[NSData dataWithBytesNoCopy:oamInfo[row].image
length:64 * 4 * 2
freeWhenDone:false]
width:8
height:oamHeight
scale:16.0/oamHeight];
case 1:
return @((signed)((unsigned)oamInfo[row].x - 8));
case 2:
return @((signed)((unsigned)oamInfo[row].y - 16));
case 3:
return [NSString stringWithFormat:@"$%02x", oamInfo[row].tile];
case 4:
return [NSString stringWithFormat:@"$%04x", 0x8000 + oamInfo[row].tile * 0x10];
case 5:
return [NSString stringWithFormat:@"$%04x", oamInfo[row].oam_addr];
case 6:
if (GB_is_cgb(&gb)) {
return [NSString stringWithFormat:@"%c%c%c%d%d",
oamInfo[row].flags & 0x80? 'P' : '-',
oamInfo[row].flags & 0x40? 'Y' : '-',
oamInfo[row].flags & 0x20? 'X' : '-',
oamInfo[row].flags & 0x08? 1 : 0,
oamInfo[row].flags & 0x07];
}
return [NSString stringWithFormat:@"%c%c%c%d",
oamInfo[row].flags & 0x80? 'P' : '-',
oamInfo[row].flags & 0x40? 'Y' : '-',
oamInfo[row].flags & 0x20? 'X' : '-',
oamInfo[row].flags & 0x10? 1 : 0];
case 7:
return oamInfo[row].obscured_by_line_limit? @"Dropped: Too many objects in line": @"";
}
}
return nil; return nil;
} }
- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(NSInteger)row - (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(NSInteger)row
{ {
return tableView == self.objectsTableView; return false;
} }
- (BOOL)tableView:(NSTableView *)tableView shouldEditTableColumn:(nullable NSTableColumn *)tableColumn row:(NSInteger)row - (BOOL)tableView:(NSTableView *)tableView shouldEditTableColumn:(nullable NSTableColumn *)tableColumn row:(NSInteger)row

View File

@ -25,7 +25,7 @@
<outlet property="memoryBankItem" destination="bWC-FW-IYP" id="Lf2-dh-z32"/> <outlet property="memoryBankItem" destination="bWC-FW-IYP" id="Lf2-dh-z32"/>
<outlet property="memoryView" destination="8hr-8o-3rN" id="fF0-rh-8ND"/> <outlet property="memoryView" destination="8hr-8o-3rN" id="fF0-rh-8ND"/>
<outlet property="memoryWindow" destination="mRm-dL-mCj" id="VPR-lu-vtI"/> <outlet property="memoryWindow" destination="mRm-dL-mCj" id="VPR-lu-vtI"/>
<outlet property="objectsTableView" destination="TOc-XJ-w9w" id="O4R-4Z-9hU"/> <outlet property="objectView" destination="fIM-GT-QXJ" id="jzs-q8-Z2U"/>
<outlet property="osdView" destination="MX4-l2-7NE" id="Am7-fq-uvu"/> <outlet property="osdView" destination="MX4-l2-7NE" id="Am7-fq-uvu"/>
<outlet property="paletteTableView" destination="gfC-d3-dmq" id="fTC-eL-Qg3"/> <outlet property="paletteTableView" destination="gfC-d3-dmq" id="fTC-eL-Qg3"/>
<outlet property="printerFeedWindow" destination="NdE-0B-WCf" id="yVK-cS-NOJ"/> <outlet property="printerFeedWindow" destination="NdE-0B-WCf" id="yVK-cS-NOJ"/>
@ -346,7 +346,7 @@
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<tabViewItems> <tabViewItems>
<tabViewItem label="Tileset" identifier="1" id="pXb-od-Wb1"> <tabViewItem label="Tileset" identifier="1" id="pXb-od-Wb1">
<view key="view" ambiguous="YES" id="lCG-Gt-XMF"> <view key="view" id="lCG-Gt-XMF">
<rect key="frame" x="0.0" y="0.0" width="512" height="408"/> <rect key="frame" x="0.0" y="0.0" width="512" height="408"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
@ -503,145 +503,33 @@
</view> </view>
</tabViewItem> </tabViewItem>
<tabViewItem label="Objects" identifier="" id="a08-eg-Maw"> <tabViewItem label="Objects" identifier="" id="a08-eg-Maw">
<view key="view" id="EiO-p0-3xn"> <view key="view" ambiguous="YES" id="EiO-p0-3xn">
<rect key="frame" x="0.0" y="0.0" width="512" height="408"/> <rect key="frame" x="0.0" y="0.0" width="512" height="408"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<scrollView fixedFrame="YES" borderType="none" autohidesScrollers="YES" horizontalLineScroll="20" horizontalPageScroll="10" verticalLineScroll="20" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="krD-gH-o5I"> <scrollView fixedFrame="YES" borderType="none" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Vhq-K4-baH">
<rect key="frame" x="0.0" y="0.0" width="512" height="408"/> <rect key="frame" x="0.0" y="0.0" width="512" height="408"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<clipView key="contentView" ambiguous="YES" drawsBackground="NO" id="3VT-AA-xVT"> <clipView key="contentView" ambiguous="YES" id="JYu-CM-49p">
<rect key="frame" x="0.0" y="0.0" width="512" height="408"/> <rect key="frame" x="0.0" y="0.0" width="512" height="408"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="none" alternatingRowBackgroundColors="YES" columnReordering="NO" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="18" headerView="of1-KC-dXC" id="TOc-XJ-w9w"> <view ambiguous="YES" id="fIM-GT-QXJ" customClass="GBObjectView">
<rect key="frame" x="0.0" y="0.0" width="512" height="391"/> <rect key="frame" x="0.0" y="0.0" width="512" height="682"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="3" height="2"/> </view>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn width="32" minWidth="32" maxWidth="1000" id="hRp-Kh-nWC">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
<imageCell key="dataCell" scrollable="YES" lineBreakMode="clipping" refusesFirstResponder="YES" alignment="left" id="Jhk-KW-Hoc" customClass="GBImageCell"/>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
</tableColumn>
<tableColumn width="28" minWidth="28" maxWidth="1000" id="Vrl-in-npm">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="center" title="X">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
<textFieldCell key="dataCell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" id="czf-Bn-nZN">
<font key="font" metaFont="system"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
</tableColumn>
<tableColumn width="28" minWidth="28" maxWidth="1000" id="636-Td-Zcm">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="center" title="Y">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
<textFieldCell key="dataCell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" id="zh6-hI-Ss8">
<font key="font" metaFont="system"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
</tableColumn>
<tableColumn width="28" minWidth="28" maxWidth="1000" id="vMj-ya-pGG">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="center" title="Tile">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
<textFieldCell key="dataCell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" id="0s8-eF-rgd">
<font key="font" metaFont="system"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
</tableColumn>
<tableColumn width="68" minWidth="40" maxWidth="1000" id="U5B-eh-aer">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="center" title="Tile Addr.">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
<textFieldCell key="dataCell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" id="PtW-wF-c0o">
<font key="font" metaFont="system"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
</tableColumn>
<tableColumn width="68" minWidth="40" maxWidth="1000" id="LSg-Sc-Sdr">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="center" title="OAM Addr.">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
<textFieldCell key="dataCell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" id="a7k-83-iPE">
<font key="font" metaFont="system"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
</tableColumn>
<tableColumn width="65" minWidth="40" maxWidth="1000" id="S9B-Hc-6Ee">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="center" title="Attributes">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
<textFieldCell key="dataCell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" id="sJa-oU-QZp">
<font key="font" metaFont="system"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
</tableColumn>
<tableColumn width="168" minWidth="40" maxWidth="1000" id="8fQ-EC-E5K">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="center">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
<textFieldCell key="dataCell" selectable="YES" editable="YES" id="YSL-O0-ZwU">
<font key="font" metaFont="miniSystem"/>
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
</tableColumn>
</tableColumns>
<connections>
<outlet property="dataSource" destination="-2" id="ypl-SU-g5n"/>
<outlet property="delegate" destination="-2" id="HzE-pT-cX5"/>
</connections>
</tableView>
</subviews> </subviews>
<nil key="backgroundColor"/> <edgeInsets key="contentInsets" left="0.0" right="0.0" top="0.0" bottom="0.0"/>
</clipView> </clipView>
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="n53-qA-NpY"> <edgeInsets key="contentInsets" left="0.0" right="0.0" top="0.0" bottom="0.0"/>
<scroller key="horizontalScroller" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="zUB-xg-cXq">
<rect key="frame" x="0.0" y="392" width="512" height="16"/> <rect key="frame" x="0.0" y="392" width="512" height="16"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
</scroller> </scroller>
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="mqp-NY-g8d"> <scroller key="verticalScroller" wantsLayer="YES" verticalHuggingPriority="750" doubleValue="1" horizontal="NO" id="jMe-gO-ERw">
<rect key="frame" x="224" y="17" width="15" height="102"/> <rect key="frame" x="496" y="0.0" width="16" height="408"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
</scroller> </scroller>
<tableHeaderView key="headerView" id="of1-KC-dXC">
<rect key="frame" x="0.0" y="0.0" width="512" height="17"/>
<autoresizingMask key="autoresizingMask"/>
</tableHeaderView>
</scrollView> </scrollView>
</subviews> </subviews>
</view> </view>
@ -983,7 +871,7 @@
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" flexibleMinX="YES" heightSizable="YES"/>
<clipView key="contentView" id="mzf-yu-RID"> <clipView key="contentView" id="mzf-yu-RID">
<rect key="frame" x="1" y="0.0" width="398" height="274"/> <rect key="frame" x="1" y="0.0" width="398" height="274"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="none" alternatingRowBackgroundColors="YES" columnReordering="NO" columnResizing="NO" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" typeSelect="NO" headerView="pvX-uJ-qK5" id="tA3-8T-bxb"> <tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="none" alternatingRowBackgroundColors="YES" columnReordering="NO" columnResizing="NO" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" typeSelect="NO" headerView="pvX-uJ-qK5" id="tA3-8T-bxb">
<rect key="frame" x="0.0" y="0.0" width="398" height="249"/> <rect key="frame" x="0.0" y="0.0" width="398" height="249"/>

View File

@ -1,5 +0,0 @@
#import <Cocoa/Cocoa.h>
@interface GBImageCell : NSImageCell
@end

View File

@ -1,10 +0,0 @@
#import "GBImageCell.h"
@implementation GBImageCell
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
CGContextSetInterpolationQuality(context, kCGInterpolationNone);
[super drawWithFrame:cellFrame inView:controlView];
}
@end

6
Cocoa/GBObjectView.h Normal file
View File

@ -0,0 +1,6 @@
#import <Cocoa/Cocoa.h>
#import "Document.h"
@interface GBObjectView : NSView
- (void)reloadData:(Document *)document;
@end

113
Cocoa/GBObjectView.m Normal file
View File

@ -0,0 +1,113 @@
#import "GBObjectView.h"
@interface GBObjectViewItem : NSObject
@property IBOutlet NSView *view;
@property IBOutlet NSImageView *image;
@property IBOutlet NSTextField *oamAddress;
@property IBOutlet NSTextField *position;
@property IBOutlet NSTextField *attributes;
@property IBOutlet NSTextField *tile;
@property IBOutlet NSTextField *tileAddress;
@property IBOutlet NSImageView *warningIcon;
@property IBOutlet NSBox *verticalLine;
@end
@implementation GBObjectViewItem
@end
@implementation GBObjectView
{
NSMutableArray<GBObjectViewItem *> *_items;
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
_items = [NSMutableArray array];
CGFloat height = self.frame.size.height;
for (unsigned i = 0; i < 40; i++) {
GBObjectViewItem *item = [[GBObjectViewItem alloc] init];
[_items addObject:item];
[[NSBundle mainBundle] loadNibNamed:@"GBObjectViewItem" owner:item topLevelObjects:nil];
item.view.hidden = true;
[self addSubview:item.view];
[item.view setFrameOrigin:NSMakePoint((i % 4) * 120, height - (i / 4 * 68) - 68)];
item.oamAddress.toolTip = @"OAM address";
item.position.toolTip = @"Position";
item.attributes.toolTip = @"Attributes";
item.tile.toolTip = @"Tile index";
item.tileAddress.toolTip = @"Tile address";
item.warningIcon.toolTip = @"Dropped: too many objects in line";
if ((i % 4) == 3) {
[item.verticalLine removeFromSuperview];
}
item.view.autoresizingMask = NSViewMaxXMargin | NSViewMinYMargin;
}
return self;
}
- (void)reloadData:(Document *)document
{
GB_oam_info_t *info = document.oamInfo;
uint8_t length = document.oamCount;
bool cgb = GB_is_cgb(document.gb);
uint8_t height = document.oamHeight;
for (unsigned i = 0; i < 40; i++) {
GBObjectViewItem *item = _items[i];
if (i >= length) {
item.view.hidden = true;
}
else {
item.view.hidden = false;
item.oamAddress.stringValue = [NSString stringWithFormat:@"$%04X", info[i].oam_addr];
item.position.stringValue = [NSString stringWithFormat:@"(%d, %d)",
((signed)(unsigned)info[i].x) - 8,
((signed)(unsigned)info[i].y) - 16];
item.tile.stringValue = [NSString stringWithFormat:@"$%02X", info[i].tile];
item.tileAddress.stringValue = [NSString stringWithFormat:@"$%04X", 0x8000 + info[i].tile * 0x10];
item.warningIcon.hidden = !info[i].obscured_by_line_limit;
if (cgb) {
item.attributes.stringValue = [NSString stringWithFormat:@"%c%c%c%d%d",
info[i].flags & 0x80? 'P' : '-',
info[i].flags & 0x40? 'Y' : '-',
info[i].flags & 0x20? 'X' : '-',
info[i].flags & 0x08? 1 : 0,
info[i].flags & 0x07];
}
else {
item.attributes.stringValue = [NSString stringWithFormat:@"%c%c%c%d",
info[i].flags & 0x80? 'P' : '-',
info[i].flags & 0x40? 'Y' : '-',
info[i].flags & 0x20? 'X' : '-',
info[i].flags & 0x10? 1 : 0];
}
item.image.image = [Document imageFromData:[NSData dataWithBytesNoCopy:info[i].image
length:64 * 4 * 2
freeWhenDone:false]
width:8
height:height
scale:32.0 / height];
}
}
NSRect frame = self.frame;
CGFloat newHeight = MAX(68 * ((length + 3) / 4), 408);
frame.origin.y -= newHeight - frame.size.height;
frame.size.height = newHeight;
self.frame = frame;
}
- (void)drawRect:(NSRect)dirtyRect
{
if (@available(macOS 10.14, *)) {
[[NSColor alternatingContentBackgroundColors].lastObject setFill];
}
else {
[[NSColor colorWithDeviceWhite:0.96 alpha:1] setFill];
}
NSRect frame = self.frame;
for (unsigned i = 1; i <= 5; i++) {
NSRectFill(NSMakeRect(0, frame.size.height - i * 68 * 2, frame.size.width, 68));
}
}
@end

View File

@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14868" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14868"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="GBObjectViewItem">
<connections>
<outlet property="attributes" destination="AVH-lh-aVu" id="F5l-vc-9YB"/>
<outlet property="image" destination="GWF-Vk-eLx" id="cQa-lM-SqU"/>
<outlet property="oamAddress" destination="HiB-x7-HCb" id="LLX-HU-t00"/>
<outlet property="position" destination="bxJ-ig-rox" id="woq-X2-lCK"/>
<outlet property="tile" destination="Kco-1J-bKc" id="C8u-jH-bCh"/>
<outlet property="tileAddress" destination="ptE-vl-9HD" id="9K3-Oq-1vs"/>
<outlet property="verticalLine" destination="Q91-eq-oeo" id="6kc-qh-cFx"/>
<outlet property="view" destination="c22-O7-iKe" id="50f-xf-9Gg"/>
<outlet property="warningIcon" destination="dQV-cO-218" id="Rxi-Wq-Upl"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView id="c22-O7-iKe">
<rect key="frame" x="0.0" y="0.0" width="120" height="68"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Kco-1J-bKc">
<rect key="frame" x="44" y="4" width="58" height="16"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" selectable="YES" alignment="left" title="$32" id="Aps-81-wR7">
<font key="font" size="11" name="Menlo-Regular"/>
<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" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ptE-vl-9HD">
<rect key="frame" x="0.0" y="4" width="44" height="16"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" selectable="YES" alignment="center" title="$8320" id="t2G-E2-vt5">
<font key="font" size="11" name="Menlo-Regular"/>
<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" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="bxJ-ig-rox">
<rect key="frame" x="44" y="36" width="76" height="16"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" selectable="YES" title="(32,16)" id="oac-yZ-h47">
<font key="font" size="11" name="Menlo-Regular"/>
<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" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="AVH-lh-aVu">
<rect key="frame" x="44" y="20" width="76" height="16"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" selectable="YES" title="---04" id="tJX-6t-5Kx">
<font key="font" size="11" name="Menlo-Regular"/>
<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" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="HiB-x7-HCb">
<rect key="frame" x="44" y="52" width="76" height="16"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" selectable="YES" alignment="left" title="$FE32" id="ysm-jq-PKy">
<font key="font" size="11" name="Menlo-Bold"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" id="GWF-Vk-eLx" customClass="GBImageView">
<rect key="frame" x="2" y="24" width="40" height="40"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" id="AJz-KH-eeo"/>
</imageView>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dQV-cO-218">
<rect key="frame" x="100" y="4" width="16" height="16"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NSCaution" id="TQB-Vp-9Jm"/>
</imageView>
<box horizontalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="Q91-eq-oeo">
<rect key="frame" x="116" y="4" width="5" height="60"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
</box>
</subviews>
<point key="canvasLocation" x="132" y="149"/>
</customView>
</objects>
<resources>
<image name="NSCaution" width="32" height="32"/>
</resources>
</document>