diff --git a/Cocoa/Document.h b/Cocoa/Document.h index 0a7f7e8..1117c26 100644 --- a/Cocoa/Document.h +++ b/Cocoa/Document.h @@ -33,6 +33,7 @@ @property (strong) IBOutlet NSTextView *debuggerSideView; @property (strong) IBOutlet GBSplitView *debuggerSplitView; @property (strong) IBOutlet NSBox *debuggerVerticalLine; +@property (strong) IBOutlet NSPanel *cheatsWindow; -(uint8_t) readMemory:(uint16_t) addr; -(void) writeMemory:(uint16_t) addr value:(uint8_t)value; diff --git a/Cocoa/Document.m b/Cocoa/Document.m index b7b56cf..71436d3 100644 --- a/Cocoa/Document.m +++ b/Cocoa/Document.m @@ -706,6 +706,9 @@ static void audioCallback(GB_gameboy_t *gb, GB_sample_t *sample) else if ([anItem action] == @selector(connectPrinter:)) { [(NSMenuItem*)anItem setState:accessory == GBAccessoryPrinter]; } + else if ([anItem action] == @selector(toggleCheats:)) { + [(NSMenuItem*)anItem setState:GB_cheats_enabled(&gb)]; + } return [super validateUserInterfaceItem:anItem]; } @@ -1699,4 +1702,14 @@ static void audioCallback(GB_gameboy_t *gb, GB_sample_t *sample) self.debuggerVerticalLine.frame = rect; } +- (IBAction)showCheats:(id)sender +{ + [self.cheatsWindow makeKeyAndOrderFront:nil]; +} + +- (IBAction)toggleCheats:(id)sender +{ + GB_set_cheats_enabled(&gb, !GB_cheats_enabled(&gb)); +} + @end diff --git a/Cocoa/Document.xib b/Cocoa/Document.xib index c680df5..338650b 100644 --- a/Cocoa/Document.xib +++ b/Cocoa/Document.xib @@ -9,6 +9,7 @@ + @@ -44,8 +45,7 @@ - - + @@ -69,11 +69,10 @@ - + - - + @@ -103,7 +102,7 @@ - + @@ -228,11 +227,10 @@ - - + + - - + @@ -312,11 +310,10 @@ - - + + - - + @@ -784,10 +781,9 @@ - - - - + + + @@ -803,7 +799,7 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NSAllRomanInputSourcesLocaleIdentifier + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NSAllRomanInputSourcesLocaleIdentifier + + + + + + + + + + + + + + + + NSAllRomanInputSourcesLocaleIdentifier + + + + + + + + + + + + + + + + NSAllRomanInputSourcesLocaleIdentifier + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Cocoa/GBCheatTextFieldCell.h b/Cocoa/GBCheatTextFieldCell.h new file mode 100644 index 0000000..473e0f3 --- /dev/null +++ b/Cocoa/GBCheatTextFieldCell.h @@ -0,0 +1,5 @@ +#import + +@interface GBCheatTextFieldCell : NSTextFieldCell +@property bool usesAddressFormat; +@end diff --git a/Cocoa/GBCheatTextFieldCell.m b/Cocoa/GBCheatTextFieldCell.m new file mode 100644 index 0000000..611cade --- /dev/null +++ b/Cocoa/GBCheatTextFieldCell.m @@ -0,0 +1,121 @@ +#import "GBCheatTextFieldCell.h" + +@interface GBCheatTextView : NSTextView +@property bool usesAddressFormat; +@end + +@implementation GBCheatTextView + +- (bool)_insertText:(NSString *)string replacementRange:(NSRange)range +{ + if (range.location == NSNotFound) { + range = self.selectedRange; + } + + NSString *new = [self.string stringByReplacingCharactersInRange:range withString:string]; + if (!self.usesAddressFormat) { + NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^(\\$[0-9A-Fa-f]{1,2}|[0-9]{1,3})$" options:0 error:NULL]; + if ([regex numberOfMatchesInString:new options:0 range:NSMakeRange(0, new.length)]) { + [super insertText:string replacementRange:range]; + return true; + } + if ([regex numberOfMatchesInString:[@"$" stringByAppendingString:new] options:0 range:NSMakeRange(0, new.length + 1)]) { + [super insertText:string replacementRange:range]; + [super insertText:@"$" replacementRange:NSMakeRange(0, 0)]; + return true; + } + if ([new isEqualToString:@"$"] || [string length] == 0) { + self.string = @"$00"; + self.selectedRange = NSMakeRange(1, 2); + return true; + } + } + else { + NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^(\\$[0-9A-Fa-f]{1,3}:)?\\$[0-9a-fA-F]{1,4}$" options:0 error:NULL]; + if ([regex numberOfMatchesInString:new options:0 range:NSMakeRange(0, new.length)]) { + [super insertText:string replacementRange:range]; + return true; + } + if ([string length] == 0) { + NSUInteger index = [new rangeOfString:@":"].location; + if (index != NSNotFound) { + if (range.location > index) { + self.string = [[new componentsSeparatedByString:@":"] firstObject]; + self.selectedRange = NSMakeRange(self.string.length, 0); + return true; + } + self.string = [[new componentsSeparatedByString:@":"] lastObject]; + self.selectedRange = NSMakeRange(0, 0); + return true; + } + else if ([[self.string substringWithRange:range] isEqualToString:@":"]) { + self.string = [[self.string componentsSeparatedByString:@":"] lastObject]; + self.selectedRange = NSMakeRange(0, 0); + return true; + } + } + if ([new isEqualToString:@"$"] || [string length] == 0) { + self.string = @"$0000"; + self.selectedRange = NSMakeRange(1, 4); + return true; + } + if (([string isEqualToString:@"$"] || [string isEqualToString:@":"]) && range.length == 0 && range.location == 0) { + if ([self _insertText:@"$00:" replacementRange:range]) { + self.selectedRange = NSMakeRange(1, 2); + return true; + } + } + if ([string isEqualToString:@":"] && range.length + range.location == self.string.length) { + if ([self _insertText:@":$0" replacementRange:range]) { + self.selectedRange = NSMakeRange(self.string.length - 2, 2); + return true; + } + } + if ([string isEqualToString:@"$"]) { + if ([self _insertText:@"$0" replacementRange:range]) { + self.selectedRange = NSMakeRange(range.location + 1, 1); + return true; + } + } + } + return false; +} + +- (NSUndoManager *)undoManager +{ + return nil; +} + +- (void)insertText:(id)string replacementRange:(NSRange)replacementRange +{ + if (![self _insertText:string replacementRange:replacementRange]) { + NSBeep(); + } +} + +/* Private API, don't tell the police! */ +- (void)_userReplaceRange:(NSRange)range withString:(NSString *)string +{ + [self insertText:string replacementRange:range]; +} + +@end + +@implementation GBCheatTextFieldCell +{ + bool _drawing, _editing; + GBCheatTextView *_fieldEditor; +} + +- (NSTextView *)fieldEditorForView:(NSView *)controlView +{ + if (_fieldEditor) { + _fieldEditor.usesAddressFormat = self.usesAddressFormat; + return _fieldEditor; + } + _fieldEditor = [[GBCheatTextView alloc] initWithFrame:controlView.frame]; + _fieldEditor.fieldEditor = YES; + _fieldEditor.usesAddressFormat = self.usesAddressFormat; + return _fieldEditor; +} +@end diff --git a/Cocoa/GBCheatWindowController.h b/Cocoa/GBCheatWindowController.h new file mode 100644 index 0000000..adb0bf8 --- /dev/null +++ b/Cocoa/GBCheatWindowController.h @@ -0,0 +1,17 @@ +#import +#import +#import "Document.h" + +@interface GBCheatWindowController : NSObject +@property (weak) IBOutlet NSTableView *cheatsTable; +@property (weak) IBOutlet NSTextField *addressField; +@property (weak) IBOutlet NSTextField *valueField; +@property (weak) IBOutlet NSTextField *oldValueField; +@property (weak) IBOutlet NSButton *oldValueCheckbox; +@property (weak) IBOutlet NSTextField *descriptionField; +@property (weak) IBOutlet NSTextField *importCodeField; +@property (weak) IBOutlet NSTextField *importDescriptionField; +@property (weak) IBOutlet Document *document; + +@end + diff --git a/Cocoa/GBCheatWindowController.m b/Cocoa/GBCheatWindowController.m new file mode 100644 index 0000000..994d5e1 --- /dev/null +++ b/Cocoa/GBCheatWindowController.m @@ -0,0 +1,234 @@ +#import "GBCheatWindowController.h" +#import "GBWarningPopover.h" +#import "GBCheatTextFieldCell.h" + +@implementation GBCheatWindowController + ++ (NSString *)addressStringFromCheat:(const GB_cheat_t *)cheat +{ + if (cheat->bank != GB_CHEAT_ANY_BANK) { + return [NSString stringWithFormat:@"$%x:$%04x", cheat->bank, cheat->address]; + } + return [NSString stringWithFormat:@"$%04x", cheat->address]; +} + ++ (NSString *)actionDescriptionForCheat:(const GB_cheat_t *)cheat +{ + if (cheat->use_old_value) { + return [NSString stringWithFormat:@"[%@]($%02x) = $%02x", [self addressStringFromCheat:cheat], cheat->old_value, cheat->value]; + } + return [NSString stringWithFormat:@"[%@] = $%02x", [self addressStringFromCheat:cheat], cheat->value]; +} + +- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView +{ + GB_gameboy_t *gb = self.document.gameboy; + if (!gb) return 0; + size_t cheatCount; + GB_get_cheats(gb, &cheatCount); + return cheatCount + 1; +} + +- (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row +{ + GB_gameboy_t *gb = self.document.gameboy; + if (!gb) return nil; + size_t cheatCount; + GB_get_cheats(gb, &cheatCount); + NSUInteger columnIndex = [[tableView tableColumns] indexOfObject:tableColumn]; + if (row >= cheatCount && columnIndex == 0) { + return [[NSCell alloc] init]; + } + return nil; +} + +- (nullable id)tableView:(NSTableView *)tableView objectValueForTableColumn:(nullable NSTableColumn *)tableColumn row:(NSInteger)row +{ + size_t cheatCount; + GB_gameboy_t *gb = self.document.gameboy; + if (!gb) return nil; + const GB_cheat_t *const *cheats = GB_get_cheats(gb, &cheatCount); + NSUInteger columnIndex = [[tableView tableColumns] indexOfObject:tableColumn]; + if (row >= cheatCount) { + switch (columnIndex) { + case 0: + return @(YES); + + case 1: + return @NO; + + case 2: + return @"Add Cheat..."; + + case 3: + return @""; + } + } + + switch (columnIndex) { + case 0: + return @(NO); + + case 1: + return @(cheats[row]->enabled); + + case 2: + return @(cheats[row]->description); + + case 3: + return [GBCheatWindowController actionDescriptionForCheat:cheats[row]]; + } + + return nil; +} + +- (IBAction)importCheat:(id)sender +{ + GB_gameboy_t *gb = self.document.gameboy; + if (!gb) return; + + [self.document performAtomicBlock:^{ + if (GB_import_cheat(gb, + self.importCodeField.stringValue.UTF8String, + self.importDescriptionField.stringValue.UTF8String, + true)) { + self.importCodeField.stringValue = @""; + self.importDescriptionField.stringValue = @""; + [self.cheatsTable reloadData]; + [self tableViewSelectionDidChange:nil]; + } + else { + NSBeep(); + [GBWarningPopover popoverWithContents:@"This code is not a valid GameShark or GameGenie code" onView:self.importCodeField]; + } + }]; +} + +- (void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row +{ + GB_gameboy_t *gb = self.document.gameboy; + if (!gb) return; + size_t cheatCount; + const GB_cheat_t *const *cheats = GB_get_cheats(gb, &cheatCount); + NSUInteger columnIndex = [[tableView tableColumns] indexOfObject:tableColumn]; + [self.document performAtomicBlock:^{ + if (columnIndex == 1) { + if (row >= cheatCount) { + GB_add_cheat(gb, "New Cheat", 0, 0, 0, 0, false, true); + } + else { + GB_update_cheat(gb, cheats[row], cheats[row]->description, cheats[row]->address, cheats[row]->bank, cheats[row]->value, cheats[row]->old_value, cheats[row]->use_old_value, !cheats[row]->enabled); + } + } + else if (row < cheatCount) { + GB_remove_cheat(gb, cheats[row]); + } + }]; + [self.cheatsTable reloadData]; + [self tableViewSelectionDidChange:nil]; +} + +- (void)tableViewSelectionDidChange:(NSNotification *)notification +{ + GB_gameboy_t *gb = self.document.gameboy; + if (!gb) return; + + size_t cheatCount; + const GB_cheat_t *const *cheats = GB_get_cheats(gb, &cheatCount); + unsigned row = self.cheatsTable.selectedRow; + const GB_cheat_t *cheat = NULL; + if (row >= cheatCount) { + static const GB_cheat_t template = { + .address = 0, + .bank = 0, + .value = 0, + .old_value = 0, + .use_old_value = false, + .enabled = false, + .description = "New Cheat", + }; + cheat = &template; + } + else { + cheat = cheats[row]; + } + + self.addressField.stringValue = [GBCheatWindowController addressStringFromCheat:cheat]; + self.valueField.stringValue = [NSString stringWithFormat:@"$%02x", cheat->value]; + self.oldValueField.stringValue = [NSString stringWithFormat:@"$%02x", cheat->old_value]; + self.oldValueCheckbox.state = cheat->use_old_value; + self.descriptionField.stringValue = @(cheat->description); +} + +- (void)awakeFromNib +{ + [self tableViewSelectionDidChange:nil]; + ((GBCheatTextFieldCell *)self.addressField.cell).usesAddressFormat = true; +} + +- (void)controlTextDidChange:(NSNotification *)obj +{ + [self updateCheat:nil]; +} + +- (IBAction)updateCheat:(id)sender +{ + GB_gameboy_t *gb = self.document.gameboy; + if (!gb) return; + + uint16_t address = 0; + uint16_t bank = GB_CHEAT_ANY_BANK; + if ([self.addressField.stringValue rangeOfString:@":"].location != NSNotFound) { + sscanf(self.addressField.stringValue.UTF8String, "$%hx:$%hx", &bank, &address); + } + else { + sscanf(self.addressField.stringValue.UTF8String, "$%hx", &address); + } + + uint8_t value = 0; + if ([self.valueField.stringValue characterAtIndex:0] == '$') { + sscanf(self.valueField.stringValue.UTF8String, "$%02hhx", &value); + } + else { + sscanf(self.valueField.stringValue.UTF8String, "%hhd", &value); + } + + uint8_t oldValue = 0; + if ([self.oldValueField.stringValue characterAtIndex:0] == '$') { + sscanf(self.oldValueField.stringValue.UTF8String, "$%02hhx", &oldValue); + } + else { + sscanf(self.oldValueField.stringValue.UTF8String, "%hhd", &oldValue); + } + + size_t cheatCount; + const GB_cheat_t *const *cheats = GB_get_cheats(gb, &cheatCount); + unsigned row = self.cheatsTable.selectedRow; + + [self.document performAtomicBlock:^{ + if (row >= cheatCount) { + GB_add_cheat(gb, + self.descriptionField.stringValue.UTF8String, + address, + bank, + value, + oldValue, + self.oldValueCheckbox.state, + false); + } + else { + GB_update_cheat(gb, + cheats[row], + self.descriptionField.stringValue.UTF8String, + address, + bank, + value, + oldValue, + self.oldValueCheckbox.state, + cheats[row]->enabled); + } + }]; + [self.cheatsTable reloadData]; +} + +@end diff --git a/Cocoa/GBImageCell.m b/Cocoa/GBImageCell.m index 6f54ec8..de75e0e 100644 --- a/Cocoa/GBImageCell.m +++ b/Cocoa/GBImageCell.m @@ -3,7 +3,7 @@ @implementation GBImageCell - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView { - CGContextRef context = [[NSGraphicsContext currentContext] CGContext]; + CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort]; CGContextSetInterpolationQuality(context, kCGInterpolationNone); [super drawWithFrame:cellFrame inView:controlView]; } diff --git a/Cocoa/GBImageView.m b/Cocoa/GBImageView.m index 973625e..47efa00 100644 --- a/Cocoa/GBImageView.m +++ b/Cocoa/GBImageView.m @@ -16,7 +16,7 @@ } - (void)drawRect:(NSRect)dirtyRect { - CGContextRef context = [[NSGraphicsContext currentContext] CGContext]; + CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort]; CGContextSetInterpolationQuality(context, kCGInterpolationNone); [super drawRect:dirtyRect]; CGFloat y_ratio = self.frame.size.height / self.image.size.height; diff --git a/Cocoa/GBOptionalVisualEffectView.h b/Cocoa/GBOptionalVisualEffectView.h new file mode 100644 index 0000000..1355071 --- /dev/null +++ b/Cocoa/GBOptionalVisualEffectView.h @@ -0,0 +1,6 @@ +#import + +/* Fake interface so the compiler assumes it conforms to NSVisualEffectView */ +@interface GBOptionalVisualEffectView : NSVisualEffectView + +@end diff --git a/Cocoa/GBOptionalVisualEffectView.m b/Cocoa/GBOptionalVisualEffectView.m new file mode 100644 index 0000000..c28eb59 --- /dev/null +++ b/Cocoa/GBOptionalVisualEffectView.m @@ -0,0 +1,18 @@ +#import + +@interface GBOptionalVisualEffectView : NSView + +@end + +@implementation GBOptionalVisualEffectView + ++ (instancetype)allocWithZone:(struct _NSZone *)zone +{ + Class NSVisualEffectView = NSClassFromString(@"NSVisualEffectView"); + if (NSVisualEffectView) { + return (id)[NSVisualEffectView alloc]; + } + return [super allocWithZone:zone]; +} + +@end diff --git a/Cocoa/MainMenu.xib b/Cocoa/MainMenu.xib index ee989ee..e56b4a0 100644 --- a/Cocoa/MainMenu.xib +++ b/Cocoa/MainMenu.xib @@ -345,6 +345,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/Core/cheats.c b/Core/cheats.c index 36b4afb..fa9b6a7 100644 --- a/Core/cheats.c +++ b/Core/cheats.c @@ -1,6 +1,7 @@ #include "gb.h" #include "cheats.h" #include +#include static inline uint8_t hash_addr(uint16_t addr) { @@ -30,6 +31,8 @@ static uint16_t bank_for_addr(GB_gameboy_t *gb, uint16_t addr) void GB_apply_cheat(GB_gameboy_t *gb, uint16_t address, uint8_t *value) { + if (!gb->cheat_enabled) return; + if (!gb->boot_rom_finished) return; const GB_cheat_hash_t *hash = gb->cheat_hash[hash_addr(address)]; if (hash) { for (unsigned i = 0; i < hash->size; i++) { @@ -44,6 +47,16 @@ void GB_apply_cheat(GB_gameboy_t *gb, uint16_t address, uint8_t *value) } } +bool GB_cheats_enabled(GB_gameboy_t *gb) +{ + return gb->cheat_enabled; +} + +void GB_set_cheats_enabled(GB_gameboy_t *gb, bool enabled) +{ + gb->cheat_enabled = enabled; +} + void GB_add_cheat(GB_gameboy_t *gb, const char *description, uint16_t address, uint16_t bank, uint8_t value, uint8_t old_value, bool use_old_value, bool enabled) { GB_cheat_t *cheat = malloc(sizeof(*cheat)); @@ -66,7 +79,7 @@ void GB_add_cheat(GB_gameboy_t *gb, const char *description, uint16_t address, u } else { (*hash)->size++; - *hash = malloc(sizeof(GB_cheat_hash_t) + sizeof(cheat) * (*hash)->size); + *hash = realloc(*hash, sizeof(GB_cheat_hash_t) + sizeof(cheat) * (*hash)->size); (*hash)->cheats[(*hash)->size - 1] = cheat; } } @@ -171,3 +184,57 @@ bool GB_import_cheat(GB_gameboy_t *gb, const char *cheat, const char *descriptio } return false; } + +void GB_update_cheat(GB_gameboy_t *gb, const GB_cheat_t *_cheat, const char *description, uint16_t address, uint16_t bank, uint8_t value, uint8_t old_value, bool use_old_value, bool enabled) +{ + GB_cheat_t *cheat = NULL; + for (unsigned i = 0; i < gb->cheat_count; i++) { + if (gb->cheats[i] == _cheat) { + cheat = gb->cheats[i]; + break; + } + } + + assert(cheat); + + if (cheat->address != address) { + /* Remove from old bucket */ + GB_cheat_hash_t **hash = &gb->cheat_hash[hash_addr(cheat->address)]; + for (unsigned i = 0; i < (*hash)->size; i++) { + if ((*hash)->cheats[i] == cheat) { + (*hash)->cheats[i] = (*hash)->cheats[(*hash)->size--]; + if ((*hash)->size == 0) { + free(*hash); + *hash = NULL; + } + else { + *hash = malloc(sizeof(GB_cheat_hash_t) + sizeof(cheat) * (*hash)->size); + } + break; + } + } + cheat->address = address; + + /* Add to new bucket */ + hash = &gb->cheat_hash[hash_addr(address)]; + if (!*hash) { + *hash = malloc(sizeof(GB_cheat_hash_t) + sizeof(cheat)); + (*hash)->size = 1; + (*hash)->cheats[0] = cheat; + } + else { + (*hash)->size++; + *hash = malloc(sizeof(GB_cheat_hash_t) + sizeof(cheat) * (*hash)->size); + (*hash)->cheats[(*hash)->size - 1] = cheat; + } + } + cheat->bank = bank; + cheat->value = value; + cheat->old_value = old_value; + cheat->use_old_value = use_old_value; + cheat->enabled = enabled; + if (description != cheat->description) { + strncpy(cheat->description, description, sizeof(cheat->description)); + cheat->description[sizeof(cheat->description) - 1] = 0; + } +} diff --git a/Core/cheats.h b/Core/cheats.h index c461f22..be5b39a 100644 --- a/Core/cheats.h +++ b/Core/cheats.h @@ -7,9 +7,12 @@ typedef struct GB_cheat_s GB_cheat_t; void GB_add_cheat(GB_gameboy_t *gb, const char *description, uint16_t address, uint16_t bank, uint8_t value, uint8_t old_value, bool use_old_value, bool enabled); +void GB_update_cheat(GB_gameboy_t *gb, const GB_cheat_t *cheat, const char *description, uint16_t address, uint16_t bank, uint8_t value, uint8_t old_value, bool use_old_value, bool enabled); bool GB_import_cheat(GB_gameboy_t *gb, const char *cheat, const char *description, bool enabled); const GB_cheat_t *const *GB_get_cheats(GB_gameboy_t *gb, size_t *size); void GB_remove_cheat(GB_gameboy_t *gb, const GB_cheat_t *cheat); +bool GB_cheats_enabled(GB_gameboy_t *gb); +void GB_set_cheats_enabled(GB_gameboy_t *gb, bool enabled); #ifdef GB_INTERNAL void GB_apply_cheat(GB_gameboy_t *gb, uint16_t address, uint8_t *value); diff --git a/Core/gb.h b/Core/gb.h index 8a60770..03abfa1 100644 --- a/Core/gb.h +++ b/Core/gb.h @@ -647,6 +647,7 @@ struct GB_gameboy_internal_s { double sgb_intro_sweep_previous_sample; /* Cheats */ + bool cheat_enabled; size_t cheat_count; GB_cheat_t **cheats; GB_cheat_hash_t *cheat_hash[256]; diff --git a/Makefile b/Makefile index 7c22375..5923b2e 100644 --- a/Makefile +++ b/Makefile @@ -88,7 +88,7 @@ OPEN_DIALOG = OpenDialog/cocoa.m endif -CFLAGS += -Werror -Wall -Wno-unused-result -Wno-strict-aliasing -Wno-unknown-warning -Wno-unknown-warning-option -Wno-multichar -Wno-int-in-bool-context -std=gnu11 -D_GNU_SOURCE -DVERSION="$(VERSION)" -I. -D_USE_MATH_DEFINES +CFLAGS += -Werror -Wall -Wno-nonnull -Wno-unused-result -Wno-strict-aliasing -Wno-unknown-warning -Wno-unknown-warning-option -Wno-multichar -Wno-int-in-bool-context -std=gnu11 -D_GNU_SOURCE -DVERSION="$(VERSION)" -I. -D_USE_MATH_DEFINES ifeq (,$(PKG_CONFIG)) SDL_CFLAGS := $(shell sdl2-config --cflags) SDL_LDFLAGS := $(shell sdl2-config --libs)