git.y1.nz

SameBoy

Accurate GB/GBC emulator
download: https://git.y1.nz/archives/sameboy.tar.gz
README | Files | Log | Refs | LICENSE

Cocoa/GBCheatWindowController.m

      1 #import "GBCheatWindowController.h"
      2 #import "GBWarningPopover.h"
      3 #import "GBCheatTextFieldCell.h"
      4 
      5 @implementation GBCheatWindowController
      6 
      7 + (NSString *)addressStringFromCheat:(const GB_cheat_t *)cheat
      8 {
      9     if (cheat->bank != GB_CHEAT_ANY_BANK) {
     10         return [NSString stringWithFormat:@"$%x:$%04x", cheat->bank, cheat->address];
     11     }
     12     return [NSString stringWithFormat:@"$%04x", cheat->address];
     13 }
     14 
     15 + (NSString *)actionDescriptionForCheat:(const GB_cheat_t *)cheat
     16 {
     17     if (cheat->use_old_value) {
     18         return [NSString stringWithFormat:@"[%@]($%02x) = $%02x", [self addressStringFromCheat:cheat], cheat->old_value, cheat->value];
     19     }
     20     return [NSString stringWithFormat:@"[%@] = $%02x", [self addressStringFromCheat:cheat], cheat->value];
     21 }
     22 
     23 - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
     24 {
     25     GB_gameboy_t *gb = self.document.gameboy;
     26     if (!gb) return 0;
     27     size_t cheatCount;
     28     GB_get_cheats(gb, &cheatCount);
     29     return cheatCount + 1;
     30 }
     31 
     32 - (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
     33 {
     34     GB_gameboy_t *gb = self.document.gameboy;
     35     if (!gb) return nil;
     36     size_t cheatCount;
     37     GB_get_cheats(gb, &cheatCount);
     38     NSUInteger columnIndex = [[tableView tableColumns] indexOfObject:tableColumn];
     39     if (row >= cheatCount && columnIndex == 0) {
     40         return [[NSCell alloc] init];
     41     }
     42     return nil;
     43 }
     44 
     45 - (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
     46 {
     47     size_t cheatCount;
     48     GB_gameboy_t *gb = self.document.gameboy;
     49     if (!gb) return nil;
     50     const GB_cheat_t *const *cheats = GB_get_cheats(gb, &cheatCount);
     51     NSUInteger columnIndex = [[tableView tableColumns] indexOfObject:tableColumn];
     52     if (row >= cheatCount) {
     53         switch (columnIndex) {
     54             case 0:
     55                 return @YES;
     56                 
     57             case 1:
     58                 return @NO;
     59                 
     60             case 2:
     61                 return @"Add Cheat…";
     62             
     63             case 3:
     64                 return @"";
     65         }
     66     }
     67     
     68     switch (columnIndex) {
     69         case 0:
     70             return @NO;
     71             
     72         case 1:
     73             return @(cheats[row]->enabled);
     74             
     75         case 2:
     76             return @(cheats[row]->description);
     77             
     78         case 3:
     79             return [GBCheatWindowController actionDescriptionForCheat:cheats[row]];
     80     }
     81     
     82     return nil;
     83 }
     84 
     85 - (IBAction)importCheat:(id)sender
     86 {
     87     GB_gameboy_t *gb = self.document.gameboy;
     88     if (!gb) return;
     89 
     90     [self.document performAtomicBlock:^{
     91         if (GB_import_cheat(gb,
     92                             self.importCodeField.stringValue.UTF8String,
     93                             self.importDescriptionField.stringValue.UTF8String,
     94                             true)) {
     95             dispatch_async(dispatch_get_main_queue(), ^{
     96                 self.importCodeField.stringValue = @"";
     97                 self.importDescriptionField.stringValue = @"";
     98                 [self.cheatsTable reloadData];
     99                 [self tableViewSelectionDidChange:nil];
    100             });
    101         }
    102         else {
    103             dispatch_async(dispatch_get_main_queue(), ^{
    104                 NSBeep();
    105                 [GBWarningPopover popoverWithContents:@"This code is not a valid GameShark or Game Genie code" onView:self.importCodeField];
    106             });
    107         }
    108     }];
    109 }
    110 
    111 - (void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
    112 {
    113     GB_gameboy_t *gb = self.document.gameboy;
    114     if (!gb) return;
    115     size_t cheatCount;
    116     const GB_cheat_t *const *cheats = GB_get_cheats(gb, &cheatCount);
    117     NSUInteger columnIndex = [[tableView tableColumns] indexOfObject:tableColumn];
    118     [self.document performAtomicBlock:^{
    119         if (columnIndex == 1) {
    120             if (row >= cheatCount) {
    121                 GB_add_cheat(gb, "New Cheat", 0, 0, 0, 0, false, true);
    122             }
    123             else {
    124                 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);
    125             }
    126         }
    127         else if (row < cheatCount) {
    128             GB_remove_cheat(gb, cheats[row]);
    129         }
    130     }];
    131     [self.cheatsTable reloadData];
    132     [self tableViewSelectionDidChange:nil];
    133 }
    134 
    135 - (void)tableViewSelectionDidChange:(NSNotification *)notification
    136 {
    137     GB_gameboy_t *gb = self.document.gameboy;
    138     if (!gb) return;
    139 
    140     size_t cheatCount;
    141     const GB_cheat_t *const *cheats = GB_get_cheats(gb, &cheatCount);
    142     unsigned row = self.cheatsTable.selectedRow;
    143     const GB_cheat_t *cheat = NULL;
    144     if (row >= cheatCount) {
    145         static const GB_cheat_t template = {
    146             .address = 0,
    147             .bank = 0,
    148             .value = 0,
    149             .old_value = 0,
    150             .use_old_value = false,
    151             .enabled = false,
    152             .description = "New Cheat",
    153         };
    154         cheat = &template;
    155     }
    156     else {
    157         cheat = cheats[row];
    158     }
    159     
    160     self.addressField.stringValue = [GBCheatWindowController addressStringFromCheat:cheat];
    161     self.valueField.stringValue = [NSString stringWithFormat:@"$%02x", cheat->value];
    162     self.oldValueField.stringValue = [NSString stringWithFormat:@"$%02x", cheat->old_value];
    163     self.oldValueCheckbox.state = cheat->use_old_value;
    164     self.descriptionField.stringValue = @(cheat->description);
    165 }
    166 
    167 - (void)awakeFromNib
    168 {
    169     [self tableViewSelectionDidChange:nil];
    170     ((GBCheatTextFieldCell *)self.addressField.cell).usesAddressFormat = true;
    171 }
    172 
    173 - (void)controlTextDidChange:(NSNotification *)obj
    174 {
    175     [self updateCheat:nil];
    176 }
    177 
    178 - (IBAction)updateCheat:(id)sender
    179 {
    180     GB_gameboy_t *gb = self.document.gameboy;
    181     if (!gb) return;
    182 
    183     uint16_t address = 0;
    184     uint16_t bank = GB_CHEAT_ANY_BANK;
    185     if ([self.addressField.stringValue rangeOfString:@":"].location != NSNotFound) {
    186         sscanf(self.addressField.stringValue.UTF8String, "$%hx:$%hx", &bank, &address);
    187     }
    188     else {
    189         sscanf(self.addressField.stringValue.UTF8String, "$%hx", &address);
    190     }
    191     
    192     uint8_t value = 0;
    193     if ([self.valueField.stringValue characterAtIndex:0] == '$') {
    194         sscanf(self.valueField.stringValue.UTF8String, "$%02hhx", &value);
    195     }
    196     else {
    197         sscanf(self.valueField.stringValue.UTF8String, "%hhd", &value);
    198     }
    199     
    200     uint8_t oldValue = 0;
    201     if ([self.oldValueField.stringValue characterAtIndex:0] == '$') {
    202         sscanf(self.oldValueField.stringValue.UTF8String, "$%02hhx", &oldValue);
    203     }
    204     else {
    205         sscanf(self.oldValueField.stringValue.UTF8String, "%hhd", &oldValue);
    206     }
    207     
    208     size_t cheatCount;
    209     const GB_cheat_t *const *cheats = GB_get_cheats(gb, &cheatCount);
    210     unsigned row = self.cheatsTable.selectedRow;
    211     
    212     [self.document performAtomicBlock:^{
    213         if (row >= cheatCount) {
    214             GB_add_cheat(gb,
    215                          self.descriptionField.stringValue.UTF8String,
    216                          address,
    217                          bank,
    218                          value,
    219                          oldValue,
    220                          self.oldValueCheckbox.state,
    221                          false);
    222         }
    223         else {
    224             GB_update_cheat(gb,
    225                             cheats[row],
    226                             self.descriptionField.stringValue.UTF8String,
    227                             address,
    228                             bank,
    229                             value,
    230                             oldValue,
    231                             self.oldValueCheckbox.state,
    232                             cheats[row]->enabled);
    233         }
    234     }];
    235     [self.cheatsTable reloadData];
    236 }
    237 
    238 - (void)cheatsUpdated
    239 {
    240     [self.cheatsTable reloadData];
    241     [self tableViewSelectionDidChange:nil];
    242 }
    243 
    244 @end

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.