Skip to content

Commit

Permalink
Automatic model selection in the Cocoa and SDL frontends, closes #648
Browse files Browse the repository at this point in the history
  • Loading branch information
LIJI32 committed Aug 25, 2024
1 parent f0bab07 commit b6c6b9e
Show file tree
Hide file tree
Showing 8 changed files with 189 additions and 106 deletions.
12 changes: 12 additions & 0 deletions Cocoa/Document.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@
#import "GBOSDView.h"
#import "GBDebuggerButton.h"

enum model {
MODEL_NONE,
MODEL_DMG,
MODEL_CGB,
MODEL_AGB,
MODEL_SGB,
MODEL_MGB,
MODEL_AUTO,

MODEL_QUICK_RESET = -1,
};

@class GBCheatWindowController;
@class GBPaletteView;
@class GBObjectView;
Expand Down
79 changes: 43 additions & 36 deletions Cocoa/Document.m
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,6 @@ - (NSString *)pathRelativeToDirectory:(NSString *)directory
/* 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!!! */

enum model {
MODEL_NONE,
MODEL_DMG,
MODEL_CGB,
MODEL_AGB,
MODEL_SGB,
MODEL_MGB,

MODEL_QUICK_RESET = -1,
};

@interface Document ()
@property GBAudioClient *audioClient;
Expand Down Expand Up @@ -100,6 +90,7 @@ @implementation Document
bool _logToSideView;
bool _shouldClearSideView;
enum model _currentModel;
bool _usesAutoModel;

bool _rewind;
bool _modelsChanging;
Expand Down Expand Up @@ -263,6 +254,7 @@ - (GB_model_t)internalModel

case MODEL_NONE:
case MODEL_QUICK_RESET:
case MODEL_AUTO:
case MODEL_CGB:
return (GB_model_t)[[NSUserDefaults standardUserDefaults] integerForKey:@"GBCGBModel"];

Expand Down Expand Up @@ -677,15 +669,46 @@ - (void)loadBootROM: (GB_boot_rom_t)type
GB_load_boot_rom(&_gb, [path UTF8String]);
}

- (enum model)bestModelForROM
{
uint8_t *rom = GB_get_direct_access(&_gb, GB_DIRECT_ACCESS_ROM, NULL, NULL);
if (!rom) return MODEL_CGB;

if (rom[0x143] & 0x80) { // Has CGB features
return MODEL_CGB;
}
if (rom[0x146] == 3) { // Has SGB features
return MODEL_SGB;
}

if (rom[0x14B] == 1) { // Nintendo-licensed (most likely has boot ROM palettes)
return MODEL_CGB;
}

if (rom[0x14B] == 0x33 &&
rom[0x144] == '0' &&
rom[0x145] == '1') { // Ditto
return MODEL_CGB;
}

return MODEL_DMG;
}

- (IBAction)reset:(id)sender
{
[self stop];
size_t old_width = GB_get_screen_width(&_gb);

if ([sender tag] != MODEL_NONE) {
if ([sender tag] > MODEL_NONE) {
/* User explictly selected a model, save the preference */
_currentModel = (enum model)[sender tag];
_usesAutoModel = _currentModel == MODEL_AUTO;
[[NSUserDefaults standardUserDefaults] setInteger:_currentModel forKey:@"GBEmulatedModel"];
}

/* Reload the ROM, SAV and SYM files */
[self loadROM];

if ([sender tag] == MODEL_QUICK_RESET) {
GB_quick_reset(&_gb);
}
Expand All @@ -699,16 +722,6 @@ - (IBAction)reset:(id)sender

[self updateMinSize];

if ([sender tag] > MODEL_NONE) {
/* User explictly selected a model, save the preference */
[[NSUserDefaults standardUserDefaults] setBool:_currentModel == MODEL_DMG forKey:@"EmulateDMG"];
[[NSUserDefaults standardUserDefaults] setBool:_currentModel == MODEL_SGB forKey:@"EmulateSGB"];
[[NSUserDefaults standardUserDefaults] setBool:_currentModel == MODEL_AGB forKey:@"EmulateAGB"];
[[NSUserDefaults standardUserDefaults] setBool:_currentModel == MODEL_MGB forKey:@"EmulateMGB"];
}

/* Reload the ROM, SAV and SYM files */
[self loadROM];

[self start];

Expand Down Expand Up @@ -871,19 +884,10 @@ - (void)windowControllerDidLoadNib:(NSWindowController *)aController
[self observeStandardDefaultsKey:@"GBVolume" withBlock:^(id newValue) {
weakSelf->_volume = [[NSUserDefaults standardUserDefaults] doubleForKey:@"GBVolume"];
}];

if ([[NSUserDefaults standardUserDefaults] boolForKey:@"EmulateDMG"]) {
_currentModel = MODEL_DMG;
}
else if ([[NSUserDefaults standardUserDefaults] boolForKey:@"EmulateSGB"]) {
_currentModel = MODEL_SGB;
}
else if ([[NSUserDefaults standardUserDefaults] boolForKey:@"EmulateMGB"]) {
_currentModel = MODEL_MGB;
}
else {
_currentModel = [[NSUserDefaults standardUserDefaults] boolForKey:@"EmulateAGB"]? MODEL_AGB : MODEL_CGB;
}


_currentModel = [[NSUserDefaults standardUserDefaults] integerForKey:@"GBEmulatedModel"];
_usesAutoModel = _currentModel == MODEL_AUTO;

[self initCommon];
self.view.gb = &_gb;
Expand Down Expand Up @@ -1125,7 +1129,7 @@ static bool is_path_writeable(const char *path)
return true;
}

- (int) loadROM
- (int)loadROM
{
__block int ret = 0;
NSString *fileName = self.romPath;
Expand Down Expand Up @@ -1177,6 +1181,9 @@ - (int) loadROM
[GBWarningPopover popoverWithContents:rom_warnings onWindow:self.mainWindow];
}
_fileModificationTime = [[NSFileManager defaultManager] attributesOfItemAtPath:fileName error:nil][NSFileModificationDate];
if (_usesAutoModel) {
_currentModel = [self bestModelForROM];
}
return ret;
}

Expand Down Expand Up @@ -1250,7 +1257,7 @@ - (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)anItem
return !GB_debugger_is_stopped(&_gb);
}
else if ([anItem action] == @selector(reset:) && anItem.tag != MODEL_NONE && anItem.tag != MODEL_QUICK_RESET) {
[(NSMenuItem *)anItem setState:anItem.tag == _currentModel];
[(NSMenuItem *)anItem setState:(anItem.tag == _currentModel) || (anItem.tag == MODEL_AUTO && _usesAutoModel)];
}
else if ([anItem action] == @selector(interrupt:)) {
if (![[NSUserDefaults standardUserDefaults] boolForKey:@"DeveloperMode"]) {
Expand Down
2 changes: 2 additions & 0 deletions Cocoa/GBApp.m
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ - (void) applicationDidFinishLaunching:(NSNotification *)notification
@"GBJoyConAutoPair": @YES,
@"GBJoyConsDefaultsToHorizontal": @YES,

@"GBEmulatedModel": @(MODEL_AUTO),

// Default themes
@"GBThemes": @{
@"Desert": @{
Expand Down
75 changes: 44 additions & 31 deletions Cocoa/MainMenu.xib
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,50 @@
<action selector="togglePause:" target="-1" id="osW-wt-QAa"/>
</connections>
</menuItem>
<menuItem title="Emulated Model" id="Cip-1S-4Zp">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Emulated Model" id="MtH-V4-vUi">
<items>
<menuItem title="Pick Automatically" tag="6" id="GXg-yH-3dl">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="reset:" target="-1" id="ao2-FI-kk1"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="Nyl-zW-Uez"/>
<menuItem title="Game Boy" tag="1" id="g7C-LA-VAr">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="reset:" target="-1" id="rxG-cz-s1S"/>
</connections>
</menuItem>
<menuItem title="Game Boy Pocket/Light" tag="5" id="1bM-CT-hoW">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="reset:" target="-1" id="U7l-BM-kB1"/>
</connections>
</menuItem>
<menuItem title="Super Game Boy" tag="4" id="vc7-yy-ARW">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="reset:" target="-1" id="E4M-QG-ua9"/>
</connections>
</menuItem>
<menuItem title="Game Boy Color" tag="2" id="hdG-Bl-8nJ">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="reset:" target="-1" id="xAz-cr-0u2"/>
</connections>
</menuItem>
<menuItem title="Game Boy Advance" tag="3" id="7jw-B1-tf5">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="reset:" target="-1" id="xQk-4e-kd7"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="QIS-av-Byy"/>
<menuItem title="Save State" id="Hdz-ut-okE">
<modifierMask key="keyEquivalentModifierMask"/>
Expand Down Expand Up @@ -360,37 +404,6 @@
<action selector="copyScreenshot:" target="-1" id="XJC-EB-HNl"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="zk7-gf-LXN"/>
<menuItem title="Game Boy" tag="1" id="g7C-LA-VAr">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="reset:" target="-1" id="rxG-cz-s1S"/>
</connections>
</menuItem>
<menuItem title="Game Boy Pocket/Light" tag="5" id="1bM-CT-hoW">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="reset:" target="-1" id="U7l-BM-kB1"/>
</connections>
</menuItem>
<menuItem title="Super Game Boy" tag="4" id="vc7-yy-ARW">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="reset:" target="-1" id="E4M-QG-ua9"/>
</connections>
</menuItem>
<menuItem title="Game Boy Color" tag="2" id="hdG-Bl-8nJ">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="reset:" target="-1" id="xAz-cr-0u2"/>
</connections>
</menuItem>
<menuItem title="Game Boy Advance" tag="3" id="7jw-B1-tf5">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="reset:" target="-1" id="xQk-4e-kd7"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="DPb-Sh-5tg"/>
<menuItem title="Start Audio Recording…" keyEquivalent="A" id="1UK-8n-QPP">
<connections>
Expand Down
2 changes: 1 addition & 1 deletion SDL/configuration.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ configuration_t configuration =
.scaling_mode = GB_SDL_SCALING_INTEGER_FACTOR,
.blending_mode = GB_FRAME_BLENDING_MODE_ACCURATE,
.rewind_length = 60 * 2,
.model = MODEL_CGB,
.model = MODEL_AUTO,
.volume = 100,
.rumble_mode = GB_RUMBLE_CARTRIDGE_ONLY,
.default_scale = 2,
Expand Down
1 change: 1 addition & 0 deletions SDL/configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ typedef struct {
MODEL_AGB,
MODEL_SGB,
MODEL_MGB,
MODEL_AUTO,
MODEL_MAX,
} model;

Expand Down
25 changes: 17 additions & 8 deletions SDL/gui.c
Original file line number Diff line number Diff line change
Expand Up @@ -933,26 +933,35 @@ static void enter_help_menu(unsigned index)

static void cycle_model(unsigned index)
{

configuration.model++;
if (configuration.model == MODEL_MAX) {
configuration.model = 0;
switch (configuration.model) {
case MODEL_DMG: configuration.model = MODEL_MGB; break;
case MODEL_MGB: configuration.model = MODEL_SGB; break;
case MODEL_SGB: configuration.model = MODEL_CGB; break;
case MODEL_CGB: configuration.model = MODEL_AGB; break;
case MODEL_AGB: configuration.model = MODEL_AUTO; break;
case MODEL_AUTO: configuration.model = MODEL_DMG; break;
default: configuration.model = MODEL_AUTO;
}
pending_command = GB_SDL_RESET_COMMAND;
}

static void cycle_model_backwards(unsigned index)
{
if (configuration.model == 0) {
configuration.model = MODEL_MAX;
switch (configuration.model) {
case MODEL_MGB: configuration.model = MODEL_DMG; break;
case MODEL_SGB: configuration.model = MODEL_MGB; break;
case MODEL_CGB: configuration.model = MODEL_SGB; break;
case MODEL_AGB: configuration.model = MODEL_CGB; break;
case MODEL_AUTO: configuration.model = MODEL_AGB; break;
case MODEL_DMG: configuration.model = MODEL_AUTO; break;
default: configuration.model = MODEL_AUTO;
}
configuration.model--;
pending_command = GB_SDL_RESET_COMMAND;
}

static const char *current_model_string(unsigned index)
{
return GB_inline_const(const char *[], {"Game Boy", "Game Boy Color", "Game Boy Advance", "Super Game Boy", "Game Boy Pocket"})
return GB_inline_const(const char *[], {"Game Boy", "Game Boy Color", "Game Boy Advance", "Super Game Boy", "Game Boy Pocket", "Pick Automatically"})
[configuration.model];
}

Expand Down
Loading

0 comments on commit b6c6b9e

Please sign in to comment.