Added VRAM-debugging APIs, added VRAM viewer to Cocoa Port, fixed uninitialized VRAM, fixed memory viewer crash
This commit is contained in:
parent
47aaf44017
commit
388fb600de
@ -1,7 +1,8 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#include "GBView.h"
|
||||
#include "GBImageView.h"
|
||||
|
||||
@interface Document : NSDocument <NSWindowDelegate>
|
||||
@interface Document : NSDocument <NSWindowDelegate, GBImageViewDelegate, NSTableViewDataSource, NSTableViewDelegate>
|
||||
@property (strong) IBOutlet GBView *view;
|
||||
@property (strong) IBOutlet NSTextView *consoleOutput;
|
||||
@property (strong) IBOutlet NSPanel *consoleWindow;
|
||||
@ -12,6 +13,18 @@
|
||||
@property (readonly) GB_gameboy_t *gameboy;
|
||||
@property (strong) IBOutlet NSTextField *memoryBankInput;
|
||||
@property (strong) IBOutlet NSToolbarItem *memoryBankItem;
|
||||
@property (strong) IBOutlet GBImageView *tilesetImageView;
|
||||
@property (strong) IBOutlet NSPopUpButton *tilesetPaletteButton;
|
||||
@property (strong) IBOutlet GBImageView *tilemapImageView;
|
||||
@property (strong) IBOutlet NSPopUpButton *tilemapPaletteButton;
|
||||
@property (strong) IBOutlet NSPopUpButton *tilemapMapButton;
|
||||
@property (strong) IBOutlet NSPopUpButton *TilemapSetButton;
|
||||
@property (strong) IBOutlet NSButton *gridButton;
|
||||
@property (strong) IBOutlet NSTabView *vramTabView;
|
||||
@property (strong) IBOutlet NSPanel *vramWindow;
|
||||
@property (strong) IBOutlet NSTextField *vramStatusLabel;
|
||||
@property (strong) IBOutlet NSTableView *paletteTableView;
|
||||
@property (strong) IBOutlet NSTableView *spritesTableView;
|
||||
|
||||
-(uint8_t) readMemory:(uint16_t) addr;
|
||||
-(void) writeMemory:(uint16_t) addr value:(uint8_t)value;
|
||||
|
296
Cocoa/Document.m
296
Cocoa/Document.m
@ -7,10 +7,12 @@
|
||||
#include "debugger.h"
|
||||
#include "memory.h"
|
||||
#include "camera.h"
|
||||
#include "display.h"
|
||||
#include "HexFiend/HexFiend.h"
|
||||
#include "GBMemoryByteArray.h"
|
||||
|
||||
/* Todo: The general Objective-C coding style conflicts with SameBoy's. This file needs a cleanup. */
|
||||
/* Todo: Split into category files! This is so messy!!! */
|
||||
|
||||
@interface Document ()
|
||||
{
|
||||
@ -30,6 +32,11 @@
|
||||
AVCaptureSession *cameraSession;
|
||||
AVCaptureConnection *cameraConnection;
|
||||
AVCaptureStillImageOutput *cameraOutput;
|
||||
|
||||
GB_oam_info_t oamInfo[40];
|
||||
uint16_t oamCount;
|
||||
uint8_t oamHeight;
|
||||
bool oamUpdating;
|
||||
}
|
||||
|
||||
@property GBAudioClient *audioClient;
|
||||
@ -140,6 +147,7 @@ static uint8_t cameraGetPixel(GB_gameboy_t *gb, uint8_t x, uint8_t y)
|
||||
self.view.mouseHidingEnabled = (self.mainWindow.styleMask & NSFullScreenWindowMask) != 0;
|
||||
[self.view flip];
|
||||
GB_set_pixels_output(&gb, self.view.pixels);
|
||||
[self reloadVRAMData: nil];
|
||||
}
|
||||
|
||||
- (void) run
|
||||
@ -262,6 +270,7 @@ static uint8_t cameraGetPixel(GB_gameboy_t *gb, uint8_t x, uint8_t y)
|
||||
window_frame.size.height = MAX([[NSUserDefaults standardUserDefaults] integerForKey:@"LastWindowHeight"],
|
||||
window_frame.size.height);
|
||||
[self.mainWindow setFrame:window_frame display:YES];
|
||||
self.vramStatusLabel.cell.backgroundStyle = NSBackgroundStyleRaised;
|
||||
[self start];
|
||||
|
||||
}
|
||||
@ -450,6 +459,7 @@ static uint8_t cameraGetPixel(GB_gameboy_t *gb, uint8_t x, uint8_t y)
|
||||
NSString *nsstring = @(string); // For ref-counting
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[hex_controller reloadData];
|
||||
[self reloadVRAMData: nil];
|
||||
|
||||
NSFont *font = [NSFont userFixedPitchFontOfSize:12];
|
||||
NSUnderlineStyle underline = NSUnderlineStyleNone;
|
||||
@ -595,6 +605,28 @@ static uint8_t cameraGetPixel(GB_gameboy_t *gb, uint8_t x, uint8_t y)
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSImage *) imageFromData:(NSData *)data width:(NSUInteger) width height:(NSUInteger) height scale:(double) scale
|
||||
{
|
||||
CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef) data);
|
||||
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
|
||||
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
|
||||
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
|
||||
|
||||
CGImageRef iref = CGImageCreate(width,
|
||||
height,
|
||||
8,
|
||||
32,
|
||||
4 * width,
|
||||
colorSpaceRef,
|
||||
bitmapInfo,
|
||||
provider,
|
||||
NULL,
|
||||
YES,
|
||||
renderingIntent);
|
||||
|
||||
return [[NSImage alloc] initWithCGImage:iref size:NSMakeSize(width * scale, height * scale)];
|
||||
}
|
||||
|
||||
- (void) reloadMemoryView
|
||||
{
|
||||
if (self.memoryWindow.isVisible) {
|
||||
@ -602,6 +634,79 @@ static uint8_t cameraGetPixel(GB_gameboy_t *gb, uint8_t x, uint8_t y)
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction) reloadVRAMData: (id) sender
|
||||
{
|
||||
if (self.vramWindow.isVisible) {
|
||||
switch ([self.vramTabView.tabViewItems indexOfObject:self.vramTabView.selectedTabViewItem]) {
|
||||
case 0:
|
||||
/* Tileset */
|
||||
{
|
||||
GB_palette_type_t palette_type = GB_PALETTE_NONE;
|
||||
NSUInteger palette_menu_index = self.tilesetPaletteButton.indexOfSelectedItem;
|
||||
if (palette_menu_index) {
|
||||
palette_type = palette_menu_index > 8? GB_PALETTE_OAM : GB_PALETTE_BACKGROUND;
|
||||
}
|
||||
size_t bufferLength = 256 * 192 * 4;
|
||||
NSMutableData *data = [NSMutableData dataWithCapacity:bufferLength];
|
||||
data.length = bufferLength;
|
||||
GB_draw_tileset(&gb, (uint32_t *)data.mutableBytes, palette_type, (palette_menu_index - 1) & 7);
|
||||
|
||||
self.tilesetImageView.image = [Document imageFromData:data width:256 height:192 scale:1.0];
|
||||
self.tilesetImageView.layer.magnificationFilter = kCAFilterNearest;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* Tilemap */
|
||||
{
|
||||
GB_palette_type_t palette_type = GB_PALETTE_NONE;
|
||||
NSUInteger palette_menu_index = self.tilemapPaletteButton.indexOfSelectedItem;
|
||||
if (palette_menu_index > 1) {
|
||||
palette_type = palette_menu_index > 9? GB_PALETTE_OAM : GB_PALETTE_BACKGROUND;
|
||||
}
|
||||
else if (palette_menu_index == 1) {
|
||||
palette_type = GB_PALETTE_AUTO;
|
||||
}
|
||||
|
||||
size_t bufferLength = 256 * 256 * 4;
|
||||
NSMutableData *data = [NSMutableData dataWithCapacity:bufferLength];
|
||||
data.length = bufferLength;
|
||||
GB_draw_tilemap(&gb, (uint32_t *)data.mutableBytes, palette_type, (palette_menu_index - 2) & 7,
|
||||
(GB_map_type_t) self.tilemapMapButton.indexOfSelectedItem,
|
||||
(GB_tileset_type_t) self.TilemapSetButton.indexOfSelectedItem);
|
||||
|
||||
self.tilemapImageView.image = [Document imageFromData:data width:256 height:256 scale:1.0];
|
||||
self.tilemapImageView.layer.magnificationFilter = kCAFilterNearest;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* OAM */
|
||||
{
|
||||
oamCount = GB_get_oam_info(&gb, oamInfo);
|
||||
oamHeight = (gb.io_registers[GB_IO_LCDC] & 4) ? 16:8;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (!oamUpdating) {
|
||||
oamUpdating = true;
|
||||
[self.spritesTableView reloadData];
|
||||
oamUpdating = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
/* Palettes */
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self.paletteTableView reloadData];
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction) showMemory:(id)sender
|
||||
{
|
||||
if (!hex_controller) {
|
||||
@ -777,4 +882,195 @@ static uint8_t cameraGetPixel(GB_gameboy_t *gb, uint8_t x, uint8_t y)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
- (IBAction)toggleTilesetGrid:(NSButton *)sender
|
||||
{
|
||||
if (sender.state) {
|
||||
self.tilesetImageView.horizontalGrids = @[
|
||||
[[GBImageViewGridConfiguration alloc] initWithColor:[NSColor colorWithCalibratedRed:0 green:0 blue:0 alpha:0.25] size:8],
|
||||
[[GBImageViewGridConfiguration alloc] initWithColor:[NSColor colorWithCalibratedRed:0 green:0 blue:0 alpha:0.5] size:128],
|
||||
|
||||
];
|
||||
self.tilesetImageView.verticalGrids = @[
|
||||
[[GBImageViewGridConfiguration alloc] initWithColor:[NSColor colorWithCalibratedRed:0 green:0 blue:0 alpha:0.25] size:8],
|
||||
[[GBImageViewGridConfiguration alloc] initWithColor:[NSColor colorWithCalibratedRed:0 green:0 blue:0 alpha:0.5] size:64],
|
||||
];
|
||||
self.tilemapImageView.horizontalGrids = @[
|
||||
[[GBImageViewGridConfiguration alloc] initWithColor:[NSColor colorWithCalibratedRed:0 green:0 blue:0 alpha:0.25] size:8],
|
||||
];
|
||||
self.tilemapImageView.verticalGrids = @[
|
||||
[[GBImageViewGridConfiguration alloc] initWithColor:[NSColor colorWithCalibratedRed:0 green:0 blue:0 alpha:0.25] size:8],
|
||||
];
|
||||
}
|
||||
else {
|
||||
self.tilesetImageView.horizontalGrids = nil;
|
||||
self.tilesetImageView.verticalGrids = nil;
|
||||
self.tilemapImageView.horizontalGrids = nil;
|
||||
self.tilemapImageView.verticalGrids = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction)vramTabChanged:(NSSegmentedControl *)sender
|
||||
{
|
||||
[self.vramTabView selectTabViewItemAtIndex:[sender selectedSegment]];
|
||||
[self reloadVRAMData:sender];
|
||||
[self.vramTabView.selectedTabViewItem.view addSubview:self.gridButton];
|
||||
self.gridButton.hidden = [sender selectedSegment] >= 2;
|
||||
|
||||
NSUInteger height_diff = self.vramWindow.frame.size.height - self.vramWindow.contentView.frame.size.height;
|
||||
CGRect window_rect = self.vramWindow.frame;
|
||||
window_rect.origin.y += window_rect.size.height;
|
||||
switch ([sender selectedSegment]) {
|
||||
case 0:
|
||||
window_rect.size.height = 384 + height_diff + 48;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
window_rect.size.height = 512 + height_diff + 48;
|
||||
break;
|
||||
case 3:
|
||||
window_rect.size.height = 20 * 16 + height_diff + 24;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
window_rect.origin.y -= window_rect.size.height;
|
||||
[self.vramWindow setFrame:window_rect display:YES animate:YES];
|
||||
}
|
||||
|
||||
- (void)mouseDidLeaveImageView:(GBImageView *)view
|
||||
{
|
||||
self.vramStatusLabel.stringValue = @"";
|
||||
}
|
||||
|
||||
- (void)imageView:(GBImageView *)view mouseMovedToX:(NSUInteger)x Y:(NSUInteger)y
|
||||
{
|
||||
if (view == self.tilesetImageView) {
|
||||
uint8_t bank = x >= 128? 1 : 0;
|
||||
x &= 127;
|
||||
uint16_t tile = x / 8 + y / 8 * 16;
|
||||
self.vramStatusLabel.stringValue = [NSString stringWithFormat:@"Tile number $%02x at %d:$%04x", tile & 0xFF, bank, 0x8000 + tile * 0x10];
|
||||
}
|
||||
else if (view == self.tilemapImageView) {
|
||||
uint16_t map_offset = x / 8 + y / 8 * 32;
|
||||
uint16_t map_base = 0x1800;
|
||||
GB_map_type_t map_type = (GB_map_type_t) self.tilemapMapButton.indexOfSelectedItem;
|
||||
GB_tileset_type_t tileset_type = (GB_tileset_type_t) self.TilemapSetButton.indexOfSelectedItem;
|
||||
|
||||
if (map_type == GB_MAP_9C00 || (map_type == GB_MAP_AUTO && gb.io_registers[GB_IO_LCDC] & 0x08)) {
|
||||
map_base = 0x1c00;
|
||||
}
|
||||
|
||||
if (tileset_type == GB_TILESET_AUTO) {
|
||||
tileset_type = (gb.io_registers[GB_IO_LCDC] & 0x10)? GB_TILESET_8800 : GB_TILESET_8000;
|
||||
}
|
||||
|
||||
uint8_t tile = gb.vram[map_base + map_offset];
|
||||
uint16_t tile_address = 0;
|
||||
if (tileset_type == GB_TILESET_8000) {
|
||||
tile_address = 0x8000 + tile * 0x10;
|
||||
}
|
||||
else {
|
||||
tile_address = 0x9000 + (int8_t)tile * 0x10;
|
||||
}
|
||||
|
||||
if (gb.is_cgb) {
|
||||
uint8_t attributes = gb.vram[map_base + map_offset + 0x2000];
|
||||
self.vramStatusLabel.stringValue = [NSString stringWithFormat:@"Tile number $%02x (%d:$%04x) at map address $%04x (Attributes: %c%c%c%d%d)",
|
||||
tile,
|
||||
attributes & 0x8? 1 : 0,
|
||||
tile_address,
|
||||
0x8000 + map_base + map_offset,
|
||||
(attributes & 0x80) ? 'P' : '-',
|
||||
(attributes & 0x40) ? 'V' : '-',
|
||||
(attributes & 0x20) ? 'H' : '-',
|
||||
attributes & 0x8? 1 : 0,
|
||||
attributes & 0x7
|
||||
];
|
||||
}
|
||||
else {
|
||||
self.vramStatusLabel.stringValue = [NSString stringWithFormat:@"Tile number $%02x ($%04x) at map address $%04x",
|
||||
tile,
|
||||
tile_address,
|
||||
0x8000 + map_base + map_offset
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
|
||||
{
|
||||
if (tableView == self.paletteTableView) {
|
||||
return 16; /* 8 BG palettes, 8 OBJ palettes*/
|
||||
}
|
||||
else if (tableView == self.spritesTableView) {
|
||||
return oamCount;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (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 %d", row >=8? "Object" : "Background", (int)(row & 7)];
|
||||
}
|
||||
|
||||
uint16_t index = columnIndex - 1 + (row & 7) * 4;
|
||||
return @(((row >= 8? gb.sprite_palletes_data : gb.background_palletes_data)[(index << 1) + 1] << 8) |
|
||||
(row >= 8? gb.sprite_palletes_data : gb.background_palletes_data)[(index << 1)]);
|
||||
}
|
||||
else if (tableView == self.spritesTableView) {
|
||||
switch (columnIndex) {
|
||||
case 0:
|
||||
return [Document imageFromData:[NSData dataWithBytesNoCopy:oamInfo[row].image length:64 * 4] width:8 height:oamHeight scale:16.0/oamHeight];
|
||||
case 1:
|
||||
return @((int)oamInfo[row].x - 8);
|
||||
case 2:
|
||||
return @((int)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.cgb_mode) {
|
||||
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 sprites in line": @"";
|
||||
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(NSInteger)row
|
||||
{
|
||||
return tableView == self.spritesTableView;
|
||||
}
|
||||
|
||||
- (BOOL)tableView:(NSTableView *)tableView shouldEditTableColumn:(nullable NSTableColumn *)tableColumn row:(NSInteger)row
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (IBAction)showVRAMViewer:(id)sender
|
||||
{
|
||||
[self.vramWindow makeKeyAndOrderFront:sender];
|
||||
}
|
||||
@end
|
@ -6,15 +6,27 @@
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="Document">
|
||||
<connections>
|
||||
<outlet property="TilemapSetButton" destination="k4c-Vg-MBu" id="Ak1-6d-B1N"/>
|
||||
<outlet property="consoleInput" destination="l22-S8-uji" id="Heu-am-YgB"/>
|
||||
<outlet property="consoleOutput" destination="doS-dM-hnl" id="Gn5-ju-Wb0"/>
|
||||
<outlet property="consoleWindow" destination="21F-Ah-yHX" id="eQ4-ug-LsT"/>
|
||||
<outlet property="gridButton" destination="fL6-2S-Rgd" id="jtV-jh-GHC"/>
|
||||
<outlet property="mainWindow" destination="xOd-HO-29H" id="h8M-YB-vcC"/>
|
||||
<outlet property="memoryBankInput" destination="rdV-q6-hc6" id="KBx-9T-2mX"/>
|
||||
<outlet property="memoryBankItem" destination="bWC-FW-IYP" id="Lf2-dh-z32"/>
|
||||
<outlet property="memoryView" destination="8hr-8o-3rN" id="fF0-rh-8ND"/>
|
||||
<outlet property="memoryWindow" destination="mRm-dL-mCj" id="VPR-lu-vtI"/>
|
||||
<outlet property="paletteTableView" destination="gfC-d3-dmq" id="fTC-eL-Qg3"/>
|
||||
<outlet property="spritesTableView" destination="TOc-XJ-w9w" id="O4R-4Z-9hU"/>
|
||||
<outlet property="tilemapImageView" destination="LlK-tV-bjv" id="nSY-Xd-BjZ"/>
|
||||
<outlet property="tilemapMapButton" destination="YIJ-Qc-SIZ" id="BB7-Gg-7XP"/>
|
||||
<outlet property="tilemapPaletteButton" destination="loB-0k-Qff" id="2Or-7l-6vn"/>
|
||||
<outlet property="tilesetImageView" destination="QcQ-ex-36R" id="8SY-Ag-eIf"/>
|
||||
<outlet property="tilesetPaletteButton" destination="TLv-xS-X5K" id="uE2-K1-5sj"/>
|
||||
<outlet property="view" destination="uqf-pe-VAF" id="HMP-rf-Yqk"/>
|
||||
<outlet property="vramStatusLabel" destination="6vK-IP-PmP" id="A2d-dI-R3J"/>
|
||||
<outlet property="vramTabView" destination="AZz-Mh-rPA" id="ZCG-SP-Lfw"/>
|
||||
<outlet property="vramWindow" destination="mbr-db-iZh" id="VZj-IV-t6O"/>
|
||||
<outlet property="window" destination="xOd-HO-29H" id="JIz-fz-R2o"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
@ -50,6 +62,7 @@
|
||||
</window>
|
||||
<window title="Debug Console" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" hidesOnDeactivate="YES" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" animationBehavior="default" id="21F-Ah-yHX" customClass="NSPanel">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" resizable="YES" utility="YES" HUD="YES"/>
|
||||
<windowCollectionBehavior key="collectionBehavior" fullScreenAuxiliary="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="272" y="172" width="600" height="400"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||
@ -201,5 +214,470 @@
|
||||
<point key="canvasLocation" x="-185" y="61"/>
|
||||
</window>
|
||||
<menuItem title="Cartridge RAM" id="ylM-ah-PNQ"/>
|
||||
<window title="VRAM Viewer" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" hidesOnDeactivate="YES" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" animationBehavior="default" id="mbr-db-iZh" customClass="NSPanel">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" unifiedTitleAndToolbar="YES"/>
|
||||
<windowCollectionBehavior key="collectionBehavior" fullScreenAuxiliary="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="283" y="305" width="512" height="432"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||
<view key="contentView" id="GYW-dv-Um1">
|
||||
<rect key="frame" x="0.0" y="0.0" width="512" height="432"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<box verticalHuggingPriority="750" title="Box" boxType="separator" titlePosition="noTitle" id="ucG-cD-wfs">
|
||||
<rect key="frame" x="0.0" y="406" width="512" height="5"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
|
||||
<color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
<font key="titleFont" metaFont="system"/>
|
||||
</box>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="6vK-IP-PmP">
|
||||
<rect key="frame" x="-2" y="4" width="516" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="center" id="umk-4r-VNg">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<tabView drawsBackground="NO" type="noTabsNoBorder" initialItem="pXb-od-Wb1" id="AZz-Mh-rPA">
|
||||
<rect key="frame" x="0.0" y="24" width="512" height="408"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<tabViewItems>
|
||||
<tabViewItem label="Tileset" identifier="1" id="pXb-od-Wb1">
|
||||
<view key="view" id="lCG-Gt-XMF">
|
||||
<rect key="frame" x="0.0" y="0.0" width="512" height="408"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" id="QcQ-ex-36R" customClass="GBImageView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="512" height="384"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="axesIndependently" id="pXc-O8-jg5"/>
|
||||
<connections>
|
||||
<action selector="reloadVRAMData:" target="-2" id="jGo-SC-0uA"/>
|
||||
<outlet property="delegate" destination="-2" id="xoo-Uo-872"/>
|
||||
</connections>
|
||||
</imageView>
|
||||
<popUpButton focusRingType="none" verticalHuggingPriority="750" id="TLv-xS-X5K">
|
||||
<rect key="frame" x="4" y="388" width="128" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="roundRect" title="None" bezelStyle="roundedRect" alignment="left" controlSize="mini" lineBreakMode="truncatingTail" state="on" borderStyle="border" focusRingType="none" imageScaling="proportionallyDown" inset="2" selectedItem="G8p-CH-PlV" id="1jI-s4-4YY">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="miniSystem"/>
|
||||
<menu key="menu" id="S6C-6Y-U3e">
|
||||
<items>
|
||||
<menuItem title="None" state="on" id="G8p-CH-PlV"/>
|
||||
<menuItem title="Background Palette 0" id="Vf5-1r-wB0"/>
|
||||
<menuItem title="Background Palette 1" id="Hnm-oM-jIq"/>
|
||||
<menuItem title="Background Palette 2" id="IBU-wD-IfI"/>
|
||||
<menuItem title="Background Palette 3" id="Pje-be-VHT"/>
|
||||
<menuItem title="Background Palette 4" id="E1K-4g-hvR"/>
|
||||
<menuItem title="Background Palette 5" id="juQ-bJ-lIt"/>
|
||||
<menuItem title="Background Palette 6" id="T1z-Jc-wIg"/>
|
||||
<menuItem title="Background Palette 7" id="oxC-qV-3EG"/>
|
||||
<menuItem title="Object Palette 0" id="nnZ-qm-fjY"/>
|
||||
<menuItem title="Object Palette 1" id="B9u-1l-0j9"/>
|
||||
<menuItem title="Object Palette 2" id="XVN-y3-Wp5"/>
|
||||
<menuItem title="Object Palette 3" id="bDp-1h-ShO"/>
|
||||
<menuItem title="Object Palette 4" id="Idr-Th-IVi"/>
|
||||
<menuItem title="Object Palette 5" id="NRU-gL-bIa"/>
|
||||
<menuItem title="Object Palette 6" id="HtN-zW-2PB"/>
|
||||
<menuItem title="Object Palette 7" id="HWA-Tl-Egd"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="reloadVRAMData:" target="-2" id="Qtf-p4-Rqh"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<button verticalHuggingPriority="750" id="fL6-2S-Rgd">
|
||||
<rect key="frame" x="452" y="388" width="56" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="roundRect" title="Grid" bezelStyle="roundedRect" alignment="center" controlSize="mini" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="pDn-9a-Se6">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES" changeBackground="YES" changeGray="YES"/>
|
||||
<font key="font" metaFont="miniSystem"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="toggleTilesetGrid:" target="-2" id="Nth-BU-nhl"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
</view>
|
||||
</tabViewItem>
|
||||
<tabViewItem label="Tilemap" identifier="2" id="kaY-Wy-Yt1">
|
||||
<view key="view" id="c6j-cM-dDx">
|
||||
<rect key="frame" x="0.0" y="0.0" width="512" height="408"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" id="LlK-tV-bjv" customClass="GBImageView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="512" height="384"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="axesIndependently" id="RvP-El-ILj"/>
|
||||
<connections>
|
||||
<action selector="reloadVRAMData:" target="-2" id="bz5-IW-cDd"/>
|
||||
<outlet property="delegate" destination="-2" id="EAG-Zh-oRi"/>
|
||||
</connections>
|
||||
</imageView>
|
||||
<popUpButton focusRingType="none" verticalHuggingPriority="750" id="loB-0k-Qff">
|
||||
<rect key="frame" x="4" y="387" width="128" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="roundRect" title="Effective Palettes" bezelStyle="roundedRect" alignment="left" controlSize="mini" lineBreakMode="truncatingTail" state="on" borderStyle="border" focusRingType="none" imageScaling="proportionallyDown" inset="2" selectedItem="oUH-Sa-Ec1" id="Eij-Cp-URa">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="miniSystem"/>
|
||||
<menu key="menu" id="KYk-85-hF3">
|
||||
<items>
|
||||
<menuItem title="None" id="BhZ-lk-ned"/>
|
||||
<menuItem title="Effective Palettes" state="on" id="oUH-Sa-Ec1"/>
|
||||
<menuItem title="Background Palette 0" id="q5g-HD-mPF"/>
|
||||
<menuItem title="Background Palette 1" id="1qY-bS-27N"/>
|
||||
<menuItem title="Background Palette 2" id="4JV-8v-9q6"/>
|
||||
<menuItem title="Background Palette 3" id="58P-TR-RjD"/>
|
||||
<menuItem title="Background Palette 4" id="voq-Pf-ZKh"/>
|
||||
<menuItem title="Background Palette 5" id="e7w-HT-Q5N"/>
|
||||
<menuItem title="Background Palette 6" id="Tgx-oy-4YI"/>
|
||||
<menuItem title="Background Palette 7" id="3lv-Bj-iqf"/>
|
||||
<menuItem title="Object Palette 0" id="z29-eH-Mq8"/>
|
||||
<menuItem title="Object Palette 1" id="2Ef-30-IRL"/>
|
||||
<menuItem title="Object Palette 2" id="Rrs-nT-Zpe"/>
|
||||
<menuItem title="Object Palette 3" id="C1P-ei-elS"/>
|
||||
<menuItem title="Object Palette 4" id="DeX-Ey-45n"/>
|
||||
<menuItem title="Object Palette 5" id="luQ-S6-lpg"/>
|
||||
<menuItem title="Object Palette 6" id="pWP-64-0lY"/>
|
||||
<menuItem title="Object Palette 7" id="qGs-73-oac"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="reloadVRAMData:" target="-2" id="BmB-JE-W8g"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<popUpButton focusRingType="none" verticalHuggingPriority="750" id="YIJ-Qc-SIZ">
|
||||
<rect key="frame" x="135" y="387" width="96" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="roundRect" title="Effective Tilemap" bezelStyle="roundedRect" alignment="left" controlSize="mini" lineBreakMode="truncatingTail" state="on" borderStyle="border" focusRingType="none" imageScaling="proportionallyDown" inset="2" selectedItem="XRF-Vj-3gs" id="3W1-Db-wDn">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="miniSystem"/>
|
||||
<menu key="menu" id="3J9-rv-1Q7">
|
||||
<items>
|
||||
<menuItem title="Effective Tilemap" state="on" id="XRF-Vj-3gs"/>
|
||||
<menuItem title="Tilemap at $9800" id="mDI-Ed-ziW"/>
|
||||
<menuItem title="Tilemap at $9C00" id="7yJ-ih-44c"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="reloadVRAMData:" target="-2" id="xwp-Ju-p00"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<popUpButton focusRingType="none" verticalHuggingPriority="750" id="k4c-Vg-MBu">
|
||||
<rect key="frame" x="235" y="387" width="96" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="roundRect" title="Effective Tileset" bezelStyle="roundedRect" alignment="left" controlSize="mini" lineBreakMode="truncatingTail" state="on" borderStyle="border" focusRingType="none" imageScaling="proportionallyDown" inset="2" selectedItem="CRe-dX-rzY" id="h53-sb-Odg">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="miniSystem"/>
|
||||
<menu key="menu" id="ztO-sk-5BM">
|
||||
<items>
|
||||
<menuItem title="Effective Tileset" state="on" id="CRe-dX-rzY"/>
|
||||
<menuItem title="Tileset at $8800" id="OU7-CN-Spr"/>
|
||||
<menuItem title="Tileset at $8000" id="5Af-BS-Ljj"/>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="reloadVRAMData:" target="-2" id="BfH-bq-6Px"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
</subviews>
|
||||
</view>
|
||||
</tabViewItem>
|
||||
<tabViewItem label="Sprites" identifier="" id="a08-eg-Maw">
|
||||
<view key="view" id="EiO-p0-3xn">
|
||||
<rect key="frame" x="0.0" y="0.0" width="512" height="408"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="20" horizontalPageScroll="10" verticalLineScroll="20" verticalPageScroll="10" usesPredominantAxisScrolling="NO" id="krD-gH-o5I">
|
||||
<rect key="frame" x="0.0" y="0.0" width="512" height="408"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<clipView key="contentView" drawsBackground="NO" id="3VT-AA-xVT">
|
||||
<rect key="frame" x="0.0" y="17" width="512" height="391"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView appearanceType="vibrantLight" 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">
|
||||
<rect key="frame" x="0.0" y="0.0" width="512" height="391"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<size key="intercellSpacing" width="3" height="2"/>
|
||||
<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" lineBreakMode="truncatingTail" 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>
|
||||
<nil key="backgroundColor"/>
|
||||
</clipView>
|
||||
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="n53-qA-NpY">
|
||||
<rect key="frame" x="0.0" y="392" width="512" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="mqp-NY-g8d">
|
||||
<rect key="frame" x="224" y="17" width="15" height="102"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</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>
|
||||
</subviews>
|
||||
</view>
|
||||
</tabViewItem>
|
||||
<tabViewItem label="Palettes" identifier="" id="vLb-Nh-UYE">
|
||||
<view key="view" id="qIg-ci-WTA">
|
||||
<rect key="frame" x="0.0" y="0.0" width="512" height="408"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<scrollView borderType="none" horizontalLineScroll="20" horizontalPageScroll="10" verticalLineScroll="20" verticalPageScroll="10" hasHorizontalScroller="NO" hasVerticalScroller="NO" usesPredominantAxisScrolling="NO" horizontalScrollElasticity="none" verticalScrollElasticity="none" id="iSs-Ow-wwb">
|
||||
<rect key="frame" x="0.0" y="0.0" width="512" height="408"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<clipView key="contentView" id="bP9-su-zQw">
|
||||
<rect key="frame" x="0.0" y="0.0" width="512" height="408"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnReordering="NO" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="18" id="gfC-d3-dmq">
|
||||
<rect key="frame" x="0.0" y="0.0" width="512" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<size key="intercellSpacing" width="3" height="2"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
<tableViewGridLines key="gridStyleMask" dashed="YES"/>
|
||||
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
|
||||
<tableColumns>
|
||||
<tableColumn width="125" minWidth="40" maxWidth="1000" id="Aje-FQ-fUw">
|
||||
<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>
|
||||
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" refusesFirstResponder="YES" title="Text Cell" id="Ygb-xo-X8v">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
</tableColumn>
|
||||
<tableColumn width="93" minWidth="40" maxWidth="1000" id="4EN-0j-lda">
|
||||
<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>
|
||||
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" refusesFirstResponder="YES" title="Text Cell" id="3a2-A4-XQW" customClass="GBColorCell">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
</tableColumn>
|
||||
<tableColumn identifier="" width="93" minWidth="10" maxWidth="3.4028234663852886e+38" id="syl-os-nSf">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
|
||||
<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" lineBreakMode="truncatingTail" selectable="YES" editable="YES" refusesFirstResponder="YES" alignment="left" title="Text Cell" id="3ql-bn-AxP" customClass="GBColorCell">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
</tableColumn>
|
||||
<tableColumn identifier="" width="93" minWidth="10" maxWidth="3.4028234663852886e+38" id="Qw3-u2-c1s">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
|
||||
<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" lineBreakMode="truncatingTail" selectable="YES" editable="YES" refusesFirstResponder="YES" title="Text Cell" id="9at-mH-PWc" customClass="GBColorCell">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
</tableColumn>
|
||||
<tableColumn identifier="" width="93" minWidth="10" maxWidth="3.4028234663852886e+38" id="gTl-gN-qLn">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
|
||||
<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" lineBreakMode="truncatingTail" selectable="YES" editable="YES" refusesFirstResponder="YES" alignment="left" title="Text Cell" id="dY8-Zu-d4t" customClass="GBColorCell">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" 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="F2f-nK-QTN"/>
|
||||
<outlet property="delegate" destination="-2" id="7hn-MM-DDD"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</clipView>
|
||||
<scroller key="horizontalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="YES" id="OS3-sw-bjv">
|
||||
<rect key="frame" x="-100" y="-100" width="510" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" hidden="YES" verticalHuggingPriority="750" horizontal="NO" id="4HA-2m-8TZ">
|
||||
<rect key="frame" x="-100" y="-100" width="15" height="102"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
</scrollView>
|
||||
</subviews>
|
||||
</view>
|
||||
</tabViewItem>
|
||||
</tabViewItems>
|
||||
</tabView>
|
||||
</subviews>
|
||||
</view>
|
||||
<toolbar key="toolbar" implicitIdentifier="7FF8B5E5-F61B-408C-9634-A5D496FE5E70" autosavesConfiguration="NO" allowsUserCustomization="NO" displayMode="iconOnly" sizeMode="regular" id="SVR-To-n7n">
|
||||
<allowedToolbarItems>
|
||||
<toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="hnI-48-dYt"/>
|
||||
<toolbarItem implicitItemIdentifier="B9D3CF98-8020-4389-9372-F99361440794" label="" paletteLabel="" id="fmK-Jl-Koj">
|
||||
<nil key="toolTip"/>
|
||||
<size key="minSize" width="100" height="25"/>
|
||||
<size key="maxSize" width="268" height="25"/>
|
||||
<segmentedControl key="view" verticalHuggingPriority="750" id="Aul-vO-dCK">
|
||||
<rect key="frame" x="0.0" y="14" width="268" height="25"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<segmentedCell key="cell" borderStyle="border" alignment="left" style="texturedSquare" trackingMode="selectOne" id="HhR-ky-5NN">
|
||||
<font key="font" metaFont="system"/>
|
||||
<segments>
|
||||
<segment label="Tileset" selected="YES"/>
|
||||
<segment label="Tilemap" tag="1"/>
|
||||
<segment label="Sprites"/>
|
||||
<segment label="Palettes"/>
|
||||
</segments>
|
||||
</segmentedCell>
|
||||
</segmentedControl>
|
||||
<connections>
|
||||
<action selector="vramTabChanged:" target="-2" id="r3e-95-wEJ"/>
|
||||
</connections>
|
||||
</toolbarItem>
|
||||
</allowedToolbarItems>
|
||||
<defaultToolbarItems>
|
||||
<toolbarItem reference="hnI-48-dYt"/>
|
||||
<toolbarItem reference="fmK-Jl-Koj"/>
|
||||
<toolbarItem reference="hnI-48-dYt"/>
|
||||
</defaultToolbarItems>
|
||||
</toolbar>
|
||||
<contentBorderThickness minY="24"/>
|
||||
<point key="canvasLocation" x="182" y="760"/>
|
||||
</window>
|
||||
</objects>
|
||||
</document>
|
||||
|
5
Cocoa/GBColorCell.h
Normal file
5
Cocoa/GBColorCell.h
Normal file
@ -0,0 +1,5 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface GBColorCell : NSTextFieldCell
|
||||
|
||||
@end
|
42
Cocoa/GBColorCell.m
Normal file
42
Cocoa/GBColorCell.m
Normal file
@ -0,0 +1,42 @@
|
||||
#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];
|
||||
super.objectValue = [NSString stringWithFormat:@"$%04x", (uint16_t)(_integerValue & 0x7FFF)];
|
||||
}
|
||||
|
||||
- (NSInteger)integerValue
|
||||
{
|
||||
return _integerValue;
|
||||
}
|
||||
|
||||
- (int)intValue
|
||||
{
|
||||
return (int)_integerValue;
|
||||
}
|
||||
|
||||
|
||||
- (NSColor *) backgroundColor
|
||||
{
|
||||
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 YES;
|
||||
}
|
||||
|
||||
@end
|
5
Cocoa/GBImageCell.h
Normal file
5
Cocoa/GBImageCell.h
Normal file
@ -0,0 +1,5 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface GBImageCell : NSImageCell
|
||||
|
||||
@end
|
10
Cocoa/GBImageCell.m
Normal file
10
Cocoa/GBImageCell.m
Normal file
@ -0,0 +1,10 @@
|
||||
#import "GBImageCell.h"
|
||||
|
||||
@implementation GBImageCell
|
||||
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
|
||||
{
|
||||
CGContextRef context = [[NSGraphicsContext currentContext] CGContext];
|
||||
CGContextSetInterpolationQuality(context, kCGInterpolationNone);
|
||||
[super drawWithFrame:cellFrame inView:controlView];
|
||||
}
|
||||
@end
|
21
Cocoa/GBImageView.h
Normal file
21
Cocoa/GBImageView.h
Normal file
@ -0,0 +1,21 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@protocol GBImageViewDelegate;
|
||||
|
||||
@interface GBImageViewGridConfiguration : NSObject
|
||||
@property NSColor *color;
|
||||
@property NSUInteger size;
|
||||
- (instancetype) initWithColor: (NSColor *) color size: (NSUInteger) size;
|
||||
@end
|
||||
|
||||
@interface GBImageView : NSImageView
|
||||
@property (nonatomic) NSArray *horizontalGrids;
|
||||
@property (nonatomic) NSArray *verticalGrids;
|
||||
@property (weak) IBOutlet id<GBImageViewDelegate> delegate;
|
||||
@end
|
||||
|
||||
@protocol GBImageViewDelegate <NSObject>
|
||||
@optional
|
||||
- (void) mouseDidLeaveImageView: (GBImageView *)view;
|
||||
- (void) imageView: (GBImageView *)view mouseMovedToX:(NSUInteger) x Y:(NSUInteger) y;
|
||||
@end
|
92
Cocoa/GBImageView.m
Normal file
92
Cocoa/GBImageView.m
Normal file
@ -0,0 +1,92 @@
|
||||
#import "GBImageView.h"
|
||||
|
||||
@implementation GBImageViewGridConfiguration
|
||||
- (instancetype)initWithColor:(NSColor *)color size:(NSUInteger)size
|
||||
{
|
||||
self = [super init];
|
||||
self.color = color;
|
||||
self.size = size;
|
||||
return self;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation GBImageView
|
||||
{
|
||||
NSTrackingArea *trackingArea;
|
||||
}
|
||||
- (void)drawRect:(NSRect)dirtyRect
|
||||
{
|
||||
CGContextRef context = [[NSGraphicsContext currentContext] CGContext];
|
||||
CGContextSetInterpolationQuality(context, kCGInterpolationNone);
|
||||
[super drawRect:dirtyRect];
|
||||
CGFloat y_ratio = self.frame.size.height / self.image.size.height;
|
||||
CGFloat x_ratio = self.frame.size.width / self.image.size.width;
|
||||
for (GBImageViewGridConfiguration *conf in self.verticalGrids) {
|
||||
[conf.color set];
|
||||
for (CGFloat y = conf.size * y_ratio; y < self.frame.size.height; y += conf.size * y_ratio) {
|
||||
NSBezierPath *line = [NSBezierPath bezierPath];
|
||||
[line moveToPoint:NSMakePoint(0, y + 0.5)];
|
||||
[line lineToPoint:NSMakePoint(self.frame.size.width, y + 0.5)];
|
||||
[line setLineWidth:1.0];
|
||||
[line stroke];
|
||||
}
|
||||
}
|
||||
|
||||
for (GBImageViewGridConfiguration *conf in self.horizontalGrids) {
|
||||
[conf.color set];
|
||||
for (CGFloat x = conf.size * x_ratio; x < self.frame.size.width; x += conf.size * x_ratio) {
|
||||
NSBezierPath *line = [NSBezierPath bezierPath];
|
||||
[line moveToPoint:NSMakePoint(x + 0.5, 0)];
|
||||
[line lineToPoint:NSMakePoint(x + 0.5, self.frame.size.height)];
|
||||
[line setLineWidth:1.0];
|
||||
[line stroke];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setHorizontalGrids:(NSArray *)horizontalGrids
|
||||
{
|
||||
self->_horizontalGrids = horizontalGrids;
|
||||
[self setNeedsDisplay];
|
||||
}
|
||||
|
||||
- (void)setVerticalGrids:(NSArray *)verticalGrids
|
||||
{
|
||||
self->_verticalGrids = verticalGrids;
|
||||
[self setNeedsDisplay];
|
||||
}
|
||||
|
||||
- (void)updateTrackingAreas
|
||||
{
|
||||
if(trackingArea != nil) {
|
||||
[self removeTrackingArea:trackingArea];
|
||||
}
|
||||
|
||||
trackingArea = [ [NSTrackingArea alloc] initWithRect:[self bounds]
|
||||
options:NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways | NSTrackingMouseMoved
|
||||
owner:self
|
||||
userInfo:nil];
|
||||
[self addTrackingArea:trackingArea];
|
||||
}
|
||||
|
||||
- (void)mouseExited:(NSEvent *)theEvent
|
||||
{
|
||||
if ([self.delegate respondsToSelector:@selector(mouseDidLeaveImageView:)]) {
|
||||
[self.delegate mouseDidLeaveImageView:self];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mouseMoved:(NSEvent *)theEvent
|
||||
{
|
||||
if ([self.delegate respondsToSelector:@selector(imageView:mouseMovedToX:Y:)]) {
|
||||
NSPoint location = [self convertPoint:theEvent.locationInWindow fromView:nil];
|
||||
location.x /= self.bounds.size.width;
|
||||
location.y /= self.bounds.size.height;
|
||||
location.y = 1 - location.y;
|
||||
location.x *= self.image.size.width;
|
||||
location.y *= self.image.size.height;
|
||||
[self.delegate imageView:self mouseMovedToX:(NSUInteger)location.x Y:(NSUInteger)location.y];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
@ -375,6 +375,12 @@
|
||||
<action selector="showMemory:" target="-1" id="Ngn-2u-n12"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Show VRAM Viewer" id="EYc-et-cG0">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="showVRAMViewer:" target="-1" id="nhw-4h-Sl4"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
|
179
Core/display.c
179
Core/display.c
@ -11,14 +11,12 @@
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t y;
|
||||
uint8_t x;
|
||||
uint8_t tile;
|
||||
uint8_t flags;
|
||||
} GB_sprite_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
static uint32_t get_pixel(GB_gameboy_t *gb, uint8_t x, uint8_t y)
|
||||
{
|
||||
@ -439,3 +437,178 @@ updateSTAT:
|
||||
gb->io_registers[GB_IO_IF] |= 2;
|
||||
}
|
||||
}
|
||||
|
||||
void GB_draw_tileset(GB_gameboy_t *gb, uint32_t *dest, GB_palette_type_t palette_type, uint8_t palette_index)
|
||||
{
|
||||
uint32_t none_palette[4];
|
||||
uint32_t *palette = NULL;
|
||||
|
||||
switch (gb->is_cgb? palette_type : GB_PALETTE_NONE) {
|
||||
default:
|
||||
case GB_PALETTE_NONE:
|
||||
none_palette[0] = gb->rgb_encode_callback(gb, 0xFF, 0xFF, 0xFF);
|
||||
none_palette[1] = gb->rgb_encode_callback(gb, 0xAA, 0xAA, 0xAA);
|
||||
none_palette[2] = gb->rgb_encode_callback(gb, 0x55, 0x55, 0x55);
|
||||
none_palette[3] = gb->rgb_encode_callback(gb, 0, 0, 0 );
|
||||
palette = none_palette;
|
||||
break;
|
||||
case GB_PALETTE_BACKGROUND:
|
||||
palette = gb->background_palletes_rgb + (4 * (palette_index & 7));
|
||||
break;
|
||||
case GB_PALETTE_OAM:
|
||||
palette = gb->sprite_palletes_rgb + (4 * (palette_index & 7));
|
||||
break;
|
||||
}
|
||||
|
||||
for (unsigned y = 0; y < 192; y++) {
|
||||
for (unsigned x = 0; x < 256; x++) {
|
||||
if (x >= 128 && !gb->is_cgb) {
|
||||
*(dest++) = gb->background_palletes_rgb[0];
|
||||
continue;
|
||||
}
|
||||
uint16_t tile = (x % 128) / 8 + y / 8 * 16;
|
||||
uint16_t tile_address = tile * 0x10 + (x >= 128? 0x2000 : 0);
|
||||
uint8_t pixel = (((gb->vram[tile_address + (y & 7) * 2 ] >> ((~x)&7)) & 1 ) |
|
||||
((gb->vram[tile_address + (y & 7) * 2 + 1] >> ((~x)&7)) & 1) << 1);
|
||||
|
||||
if (!gb->cgb_mode) {
|
||||
if (palette_type == GB_PALETTE_BACKGROUND) {
|
||||
pixel = ((gb->io_registers[GB_IO_BGP] >> (pixel << 1)) & 3);
|
||||
}
|
||||
else if (!gb->cgb_mode) {
|
||||
if (palette_type == GB_PALETTE_OAM) {
|
||||
pixel = ((gb->io_registers[palette_index == 0? GB_IO_OBP0 : GB_IO_OBP1] >> (pixel << 1)) & 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
*(dest++) = palette[pixel];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GB_draw_tilemap(GB_gameboy_t *gb, uint32_t *dest, GB_palette_type_t palette_type, uint8_t palette_index, GB_map_type_t map_type, GB_tileset_type_t tileset_type)
|
||||
{
|
||||
uint32_t none_palette[4];
|
||||
uint32_t *palette = NULL;
|
||||
uint16_t map = 0x1800;
|
||||
|
||||
switch (gb->is_cgb? palette_type : GB_PALETTE_NONE) {
|
||||
case GB_PALETTE_NONE:
|
||||
none_palette[0] = gb->rgb_encode_callback(gb, 0xFF, 0xFF, 0xFF);
|
||||
none_palette[1] = gb->rgb_encode_callback(gb, 0xAA, 0xAA, 0xAA);
|
||||
none_palette[2] = gb->rgb_encode_callback(gb, 0x55, 0x55, 0x55);
|
||||
none_palette[3] = gb->rgb_encode_callback(gb, 0, 0, 0 );
|
||||
palette = none_palette;
|
||||
break;
|
||||
case GB_PALETTE_BACKGROUND:
|
||||
palette = gb->background_palletes_rgb + (4 * (palette_index & 7));
|
||||
break;
|
||||
case GB_PALETTE_OAM:
|
||||
palette = gb->sprite_palletes_rgb + (4 * (palette_index & 7));
|
||||
break;
|
||||
case GB_PALETTE_AUTO:
|
||||
break;
|
||||
}
|
||||
|
||||
if (map_type == GB_MAP_9C00 || (map_type == GB_MAP_AUTO && gb->io_registers[GB_IO_LCDC] & 0x08)) {
|
||||
map = 0x1c00;
|
||||
}
|
||||
|
||||
if (tileset_type == GB_TILESET_AUTO) {
|
||||
tileset_type = (gb->io_registers[GB_IO_LCDC] & 0x10)? GB_TILESET_8800 : GB_TILESET_8000;
|
||||
}
|
||||
|
||||
for (unsigned y = 0; y < 256; y++) {
|
||||
for (unsigned x = 0; x < 256; x++) {
|
||||
uint8_t tile = gb->vram[map + x/8 + y/8 * 32];
|
||||
uint16_t tile_address;
|
||||
uint8_t attributes = 0;
|
||||
|
||||
if (tileset_type == GB_TILESET_8800) {
|
||||
tile_address = tile * 0x10;
|
||||
}
|
||||
else {
|
||||
tile_address = (int8_t) tile * 0x10 + 0x1000;
|
||||
}
|
||||
|
||||
if (gb->cgb_mode) {
|
||||
attributes = gb->vram[map + x/8 + y/8 * 32 + 0x2000];
|
||||
}
|
||||
|
||||
if (attributes & 0x8) {
|
||||
tile_address += 0x2000;
|
||||
}
|
||||
|
||||
uint8_t pixel = (((gb->vram[tile_address + (((attributes & 0x40)? ~y : y) & 7) * 2 ] >> (((attributes & 0x20)? x : ~x)&7)) & 1 ) |
|
||||
((gb->vram[tile_address + (((attributes & 0x40)? ~y : y) & 7) * 2 + 1] >> (((attributes & 0x20)? x : ~x)&7)) & 1) << 1);
|
||||
|
||||
if (!gb->cgb_mode && (palette_type == GB_PALETTE_BACKGROUND || palette_type == GB_PALETTE_AUTO)) {
|
||||
pixel = ((gb->io_registers[GB_IO_BGP] >> (pixel << 1)) & 3);
|
||||
}
|
||||
|
||||
if (palette) {
|
||||
*(dest++) = palette[pixel];
|
||||
}
|
||||
else {
|
||||
*(dest++) = gb->background_palletes_rgb[(attributes & 7) * 4 + pixel];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t GB_get_oam_info(GB_gameboy_t *gb, GB_oam_info_t *dest)
|
||||
{
|
||||
uint8_t count = 0;
|
||||
unsigned sprite_height = (gb->io_registers[GB_IO_LCDC] & 4) ? 16:8;
|
||||
uint8_t oam_to_dest_index[40] = {0,};
|
||||
for (unsigned y = 0; y < 144; y++) {
|
||||
GB_sprite_t *sprite = (GB_sprite_t *) &gb->oam;
|
||||
uint8_t sprites_in_line = 0;
|
||||
for (uint8_t i = 0; i < 40; i++, sprite++) {
|
||||
int sprite_y = sprite->y - 16;
|
||||
bool obscured = false;
|
||||
// Is sprite not in this line?
|
||||
if (sprite_y > y || sprite_y + sprite_height <= y) continue;
|
||||
if (++sprites_in_line == 11) obscured = true;
|
||||
|
||||
GB_oam_info_t *info = NULL;
|
||||
if (!oam_to_dest_index[i]) {
|
||||
info = dest + count;
|
||||
oam_to_dest_index[i] = ++count;
|
||||
info->x = sprite->x;
|
||||
info->y = sprite->y;
|
||||
info->tile = sprite_height == 16? sprite->tile & 0xFE : sprite->tile;
|
||||
info->flags = sprite->flags;
|
||||
info->obscured_by_line_limit = false;
|
||||
info->oam_addr = 0xFE00 + i * sizeof(*sprite);
|
||||
}
|
||||
else {
|
||||
info = dest + oam_to_dest_index[i] - 1;
|
||||
}
|
||||
info->obscured_by_line_limit |= obscured;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (unsigned i = 0; i < count; i++) {
|
||||
uint16_t vram_address = dest[i].tile * 0x10;
|
||||
uint8_t flags = dest[i].flags;
|
||||
uint8_t palette = gb->cgb_mode? (flags & 7) : ((flags & 0x10)? 1 : 0);
|
||||
|
||||
for (unsigned y = 0; y < sprite_height; y++) {
|
||||
for (unsigned x = 0; x < 8; x++) {
|
||||
uint8_t color = (((gb->vram[vram_address ] >> ((~x)&7)) & 1 ) |
|
||||
((gb->vram[vram_address + 1] >> ((~x)&7)) & 1) << 1 );
|
||||
|
||||
if (!gb->cgb_mode) {
|
||||
color = (gb->io_registers[palette? GB_IO_OBP1:GB_IO_OBP0] >> (color << 1)) & 3;
|
||||
}
|
||||
dest[i].image[((flags & 0x20)?7-x:x) + ((flags & 0x40)?sprite_height - 1 -y:y) * 8] = gb->sprite_palletes_rgb[palette * 4 + color];
|
||||
}
|
||||
vram_address += 2;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
@ -4,4 +4,35 @@
|
||||
#include "gb.h"
|
||||
void GB_display_run(GB_gameboy_t *gb);
|
||||
void GB_palette_changed(GB_gameboy_t *gb, bool background_palette, uint8_t index);
|
||||
|
||||
typedef enum {
|
||||
GB_PALETTE_NONE,
|
||||
GB_PALETTE_BACKGROUND,
|
||||
GB_PALETTE_OAM,
|
||||
GB_PALETTE_AUTO,
|
||||
} GB_palette_type_t;
|
||||
|
||||
typedef enum {
|
||||
GB_MAP_AUTO,
|
||||
GB_MAP_9800,
|
||||
GB_MAP_9C00,
|
||||
} GB_map_type_t;
|
||||
|
||||
typedef enum {
|
||||
GB_TILESET_AUTO,
|
||||
GB_TILESET_8800,
|
||||
GB_TILESET_8000,
|
||||
} GB_tileset_type_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t image[128];
|
||||
uint8_t x, y, tile, flags;
|
||||
uint16_t oam_addr;
|
||||
bool obscured_by_line_limit;
|
||||
} GB_oam_info_t;
|
||||
|
||||
void GB_draw_tileset(GB_gameboy_t *gb, uint32_t *dest, GB_palette_type_t palette_type, uint8_t palette_index);
|
||||
void GB_draw_tilemap(GB_gameboy_t *gb, uint32_t *dest, GB_palette_type_t palette_type, uint8_t palette_index, GB_map_type_t map_type, GB_tileset_type_t tileset_type);
|
||||
|
||||
uint8_t GB_get_oam_info(GB_gameboy_t *gb, GB_oam_info_t *dest);
|
||||
#endif /* display_h */
|
||||
|
@ -95,7 +95,9 @@ void GB_init(GB_gameboy_t *gb)
|
||||
gb->magic = (uintptr_t)'SAME';
|
||||
gb->version = GB_STRUCT_VERSION;
|
||||
gb->ram = malloc(gb->ram_size = 0x2000);
|
||||
memset(gb->ram, 0, gb->ram_size);
|
||||
gb->vram = malloc(gb->vram_size = 0x2000);
|
||||
memset(gb->vram, 0, gb->vram_size);
|
||||
|
||||
gb->mbc_rom_bank = 1;
|
||||
gb->last_rtc_second = time(NULL);
|
||||
@ -121,7 +123,9 @@ void GB_init_cgb(GB_gameboy_t *gb)
|
||||
gb->magic = (uintptr_t)'SAME';
|
||||
gb->version = GB_STRUCT_VERSION;
|
||||
gb->ram = malloc(gb->ram_size = 0x2000 * 8);
|
||||
memset(gb->ram, 0, gb->ram_size);
|
||||
gb->vram = malloc(gb->vram_size = 0x2000 * 2);
|
||||
memset(gb->vram, 0, gb->vram_size);
|
||||
gb->is_cgb = true;
|
||||
gb->cgb_mode = true;
|
||||
|
||||
|
11
HexFiend/HFController.m
vendored
11
HexFiend/HFController.m
vendored
@ -19,11 +19,7 @@
|
||||
/* Used for the anchor range and location */
|
||||
#define NO_SELECTION ULLONG_MAX
|
||||
|
||||
#if ! NDEBUG
|
||||
#define VALIDATE_SELECTION() [self _ensureSelectionIsValid]
|
||||
#else
|
||||
#define VALIDATE_SELECTION() do { } while (0)
|
||||
#endif
|
||||
|
||||
#define BENCHMARK_BYTEARRAYS 0
|
||||
|
||||
@ -456,7 +452,6 @@ static inline Class preferredByteArrayClass(void) {
|
||||
return [HFRangeWrapper organizeAndMergeRanges:result];
|
||||
}
|
||||
|
||||
#if ! NDEBUG
|
||||
- (void)_ensureSelectionIsValid {
|
||||
HFASSERT(selectedContentsRanges != nil);
|
||||
HFASSERT([selectedContentsRanges count] > 0);
|
||||
@ -464,11 +459,13 @@ static inline Class preferredByteArrayClass(void) {
|
||||
FOREACH(HFRangeWrapper*, wrapper, selectedContentsRanges) {
|
||||
EXPECT_CLASS(wrapper, HFRangeWrapper);
|
||||
HFRange range = [wrapper HFRange];
|
||||
HFASSERT(HFRangeIsSubrangeOfRange(range, HFRangeMake(0, [self contentsLength])));
|
||||
if (!HFRangeIsSubrangeOfRange(range, HFRangeMake(0, [self contentsLength]))){
|
||||
[self setSelectedContentsRanges:@[[HFRangeWrapper withRange:HFRangeMake(0, 0)]]];
|
||||
return;
|
||||
}
|
||||
if (onlyOneWrapper == NO) HFASSERT(range.length > 0); /* If we have more than one wrapper, then none of them should be zero length */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void)_setSingleSelectedContentsRange:(HFRange)newSelection {
|
||||
HFASSERT(HFRangeIsSubrangeOfRange(newSelection, HFRangeMake(0, [self contentsLength])));
|
||||
|
2
Makefile
2
Makefile
@ -48,7 +48,7 @@ endif
|
||||
ifeq ($(PLATFORM),Darwin)
|
||||
CFLAGS += -F/Library/Frameworks
|
||||
OCFLAGS += -x objective-c -fobjc-arc -Wno-deprecated-declarations -isysroot $(shell xcode-select -p)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk -mmacosx-version-min=10.9
|
||||
LDFLAGS += -framework AppKit -framework Carbon
|
||||
LDFLAGS += -framework AppKit -framework Carbon -framework QuartzCore
|
||||
SDL_LDFLAGS := -framework SDL
|
||||
endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user