git.y1.nz

SameBoy

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

commit 3ed18a76da22c7125d55b3e5d7edcb067725e9b5
parent 033f025851622bd15c5ebff92df95963fc942ca2
Author: Lior Halphon <LIJI32@gmail.com>
Date:   Sun, 30 May 2021 20:55:04 +0300

Added optional OSD (Cocoa)

Diffstat:
MCocoa/AppDelegate.m6++----
MCocoa/Document.h2++
MCocoa/Document.m13+++++++++++++
MCocoa/Document.xib7++++++-
ACocoa/GBOSDView.h6++++++
ACocoa/GBOSDView.m104+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MCocoa/GBPreferencesWindow.h2+-
MCocoa/GBPreferencesWindow.m20+++++++++++++++++++-
MCocoa/GBView.h2++
MCocoa/GBView.m10++++++++++
MCocoa/GBVisualizerView.h8--------
MCocoa/GBVisualizerView.m8--------
MCocoa/Preferences.xib46+++++++++++++++++++++++++++++-----------------
MCore/gb.c68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MCore/gb.h5+++++
MCore/save_state.c6++----
MMakefile2+-
MSDL/main.c6++----
Mlibretro/Makefile2+-
Mlibretro/jni/Android.mk2+-
Mlibretro/libretro.c4++--
21 files changed, 276 insertions(+), 53 deletions(-)

diff --git a/Cocoa/AppDelegate.m b/Cocoa/AppDelegate.m @@ -7,8 +7,6 @@ #import <WebKit/WebKit.h> #define UPDATE_SERVER "https://sameboy.github.io" -#define str(x) #x -#define xstr(x) str(x) static uint32_t color_to_int(NSColor *color) { @@ -186,7 +184,7 @@ static uint32_t color_to_int(NSColor *color) } NSString *changes = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - NSRange cutoffRange = [changes rangeOfString:@"<!--(" xstr(VERSION) ")-->"]; + NSRange cutoffRange = [changes rangeOfString:@"<!--(" GB_VERSION ")-->"]; if (cutoffRange.location != NSNotFound) { changes = [changes substringToIndex:cutoffRange.location]; } @@ -252,7 +250,7 @@ static uint32_t color_to_int(NSColor *color) if (components.count != 2) return; _lastVersion = components[0]; _updateURL = components[1]; - if (![@xstr(VERSION) isEqualToString:_lastVersion] && + if (![@GB_VERSION isEqualToString:_lastVersion] && ![[[NSUserDefaults standardUserDefaults] stringForKey:@"GBSkippedVersion"] isEqualToString:_lastVersion]) { [self updateFound]; } diff --git a/Cocoa/Document.h b/Cocoa/Document.h @@ -3,6 +3,7 @@ #include "GBImageView.h" #include "GBSplitView.h" #include "GBVisualizerView.h" +#include "GBOSDView.h" @class GBCheatWindowController; @@ -49,6 +50,7 @@ @property (strong) IBOutlet NSButton *gbsRewindButton; @property (strong) IBOutlet NSSegmentedControl *gbsNextPrevButton; @property (strong) IBOutlet GBVisualizerView *gbsVisualizer; +@property (strong) IBOutlet GBOSDView *osdView; -(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 @@ -314,6 +314,7 @@ static void infraredStateChanged(GB_gameboy_t *gb, bool on) self.mainWindow.contentView.bounds.size.width < GB_get_screen_height(&gb)) { [self.mainWindow zoom:nil]; } + self.osdView.usesSGBScale = GB_get_screen_width(&gb) == 256; } - (void) vblank @@ -344,6 +345,7 @@ static void infraredStateChanged(GB_gameboy_t *gb, bool on) } if (self.view.isRewinding) { rewind = true; + [self.osdView displayText:@"Rewinding..."]; } } @@ -621,6 +623,10 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency) [(GBMemoryByteArray *)(hex_controller.byteArray) setSelectedBank:0]; [self hexUpdateBank:self.memoryBankInput ignoreErrors:true]; } + + char title[17]; + GB_get_rom_title(&gb, title); + [self.osdView displayText:[NSString stringWithFormat:@"SameBoy v" GB_VERSION "\n%s\n%08X", title, GB_get_rom_crc32(&gb)]]; } - (IBAction)togglePause:(id)sender @@ -780,6 +786,7 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency) [self initCommon]; self.view.gb = &gb; + self.view.osdView = _osdView; [self.view screenSizeChanged]; if ([self loadROM]) { _mainWindow.alphaValue = 0; // Hack hack ugly hack @@ -1284,6 +1291,9 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency) [GBWarningPopover popoverWithContents:@"Failed to write save state." onWindow:self.mainWindow]; NSBeep(); } + else { + [self.osdView displayText:@"State saved"]; + } } - (int)loadStateFile:(const char *)path noErrorOnNotFound:(bool)noErrorOnFileNotFound; @@ -1301,6 +1311,9 @@ static unsigned *multiplication_table_for_frequency(unsigned frequency) if (result) { NSBeep(); } + else { + [self.osdView displayText:@"State loaded"]; + } if (error) { [GBWarningPopover popoverWithContents:error onWindow:self.mainWindow]; } diff --git a/Cocoa/Document.xib b/Cocoa/Document.xib @@ -25,6 +25,7 @@ <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="osdView" destination="MX4-l2-7NE" id="Am7-fq-uvu"/> <outlet property="paletteTableView" destination="gfC-d3-dmq" id="fTC-eL-Qg3"/> <outlet property="printerFeedWindow" destination="NdE-0B-WCf" id="yVK-cS-NOJ"/> <outlet property="spritesTableView" destination="TOc-XJ-w9w" id="O4R-4Z-9hU"/> @@ -65,6 +66,10 @@ </view> </subviews> </customView> + <customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="MX4-l2-7NE" customClass="GBOSDView"> + <rect key="frame" x="0.0" y="0.0" width="160" height="144"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + </customView> </subviews> </view> <connections> @@ -978,7 +983,7 @@ <autoresizingMask key="autoresizingMask" flexibleMinX="YES" heightSizable="YES"/> <clipView key="contentView" id="mzf-yu-RID"> <rect key="frame" x="1" y="0.0" width="398" height="274"/> - <autoresizingMask key="autoresizingMask"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="none" alternatingRowBackgroundColors="YES" columnReordering="NO" columnResizing="NO" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" typeSelect="NO" headerView="pvX-uJ-qK5" id="tA3-8T-bxb"> <rect key="frame" x="0.0" y="0.0" width="398" height="249"/> diff --git a/Cocoa/GBOSDView.h b/Cocoa/GBOSDView.h @@ -0,0 +1,6 @@ +#import <Cocoa/Cocoa.h> + +@interface GBOSDView : NSView +@property bool usesSGBScale; +- (void)displayText:(NSString *)text; +@end diff --git a/Cocoa/GBOSDView.m b/Cocoa/GBOSDView.m @@ -0,0 +1,104 @@ +#import "GBOSDView.h" + +@implementation GBOSDView +{ + bool _usesSGBScale; + NSString *_text; + double _animation; + NSTimer *_timer; +} + +- (void)setUsesSGBScale:(bool)usesSGBScale +{ + _usesSGBScale = usesSGBScale; + [self setNeedsDisplay:true]; +} + +- (bool)usesSGBScale +{ + return _usesSGBScale; +} + +- (void)displayText:(NSString *)text +{ + if (![[NSUserDefaults standardUserDefaults] boolForKey:@"GBOSDEnabled"]) return; + dispatch_async(dispatch_get_main_queue(), ^{ + if (![_text isEqualToString:text]) { + [self setNeedsDisplay:true]; + } + _text = text; + self.alphaValue = 1.0; + _animation = 2.5; + // Longer strings should appear longer + if ([_text rangeOfString:@"\n"].location != NSNotFound) { + _animation += 4; + } + [_timer invalidate]; + self.hidden = false; + _timer = [NSTimer scheduledTimerWithTimeInterval:0.025 target:self selector:@selector(animate) userInfo:nil repeats:true]; + }); +} + +- (void)animate +{ + _animation -= 0.1; + if (_animation < 1.0) { + self.alphaValue = _animation; + }; + if (_animation == 0) { + self.hidden = true; + [_timer invalidate]; + _text = nil; + } +} + +- (void)drawRect:(NSRect)dirtyRect +{ + [super drawRect:dirtyRect]; + if (!_text.length) return; + + double fontSize = 8; + NSSize size = self.frame.size; + if (_usesSGBScale) { + fontSize *= MIN(size.width / 256, size.height / 224); + } + else { + fontSize *= MIN(size.width / 160, size.height / 144); + } + + NSFont *font = [NSFont boldSystemFontOfSize:fontSize]; + + /* The built in stroke attribute uses an inside stroke, which is typographically terrible. + We'll use a naïve manual stroke instead which looks better. */ + + NSDictionary *attributes = @{ + NSFontAttributeName: font, + NSForegroundColorAttributeName: [NSColor blackColor], + }; + + NSAttributedString *text = [[NSAttributedString alloc] initWithString:_text attributes:attributes]; + + [text drawAtPoint:NSMakePoint(fontSize + 1, fontSize + 0)]; + [text drawAtPoint:NSMakePoint(fontSize - 1, fontSize + 0)]; + [text drawAtPoint:NSMakePoint(fontSize + 0, fontSize + 1)]; + [text drawAtPoint:NSMakePoint(fontSize + 0, fontSize - 1)]; + + // The uses of sqrt(2)/2, which is more correct, results in severe ugly-looking rounding errors + if (self.window.screen.backingScaleFactor > 1) { + [text drawAtPoint:NSMakePoint(fontSize + 0.5, fontSize + 0.5)]; + [text drawAtPoint:NSMakePoint(fontSize - 0.5, fontSize + 0.5)]; + [text drawAtPoint:NSMakePoint(fontSize - 0.5, fontSize - 0.5)]; + [text drawAtPoint:NSMakePoint(fontSize + 0.5, fontSize - 0.5)]; + } + + attributes = @{ + NSFontAttributeName: font, + NSForegroundColorAttributeName: [NSColor whiteColor], + }; + + text = [[NSAttributedString alloc] initWithString:_text attributes:attributes]; + + [text drawAtPoint:NSMakePoint(fontSize, fontSize)]; +} + +@end diff --git a/Cocoa/GBPreferencesWindow.h b/Cocoa/GBPreferencesWindow.h @@ -27,5 +27,5 @@ @property (nonatomic, weak) IBOutlet NSPopUpButton *playerListButton; @property (nonatomic, weak) IBOutlet NSButton *autoUpdatesCheckbox; @property (weak) IBOutlet NSSlider *volumeSlider; - +@property (weak) IBOutlet NSButton *OSDCheckbox; @end diff --git a/Cocoa/GBPreferencesWindow.m b/Cocoa/GBPreferencesWindow.m @@ -31,7 +31,7 @@ NSSlider *_interferenceSlider; NSSlider *_volumeSlider; NSButton *_autoUpdatesCheckbox; - + NSButton *_OSDCheckbox; } + (NSArray *)filterList @@ -741,4 +741,22 @@ _autoUpdatesCheckbox = autoUpdatesCheckbox; [_autoUpdatesCheckbox setState: [[NSUserDefaults standardUserDefaults] boolForKey:@"GBAutoUpdatesEnabled"]]; } + +- (NSButton *)OSDCheckbox +{ + return _OSDCheckbox; +} + +- (void)setOSDCheckbox:(NSButton *)OSDCheckbox +{ + _OSDCheckbox = OSDCheckbox; + [_OSDCheckbox setState: [[NSUserDefaults standardUserDefaults] boolForKey:@"GBOSDEnabled"]]; +} + +- (IBAction)changeOSDEnabled:(id)sender +{ + [[NSUserDefaults standardUserDefaults] setBool:[(NSButton *)sender state] == NSOnState + forKey:@"GBOSDEnabled"]; + +} @end diff --git a/Cocoa/GBView.h b/Cocoa/GBView.h @@ -1,6 +1,7 @@ #import <Cocoa/Cocoa.h> #include <Core/gb.h> #import <JoyKit/JoyKit.h> +#import "GBOSDView.h" @class Document; typedef enum { @@ -20,6 +21,7 @@ typedef enum { @property (nonatomic, getter=isMouseHidingEnabled) BOOL mouseHidingEnabled; @property (nonatomic) bool isRewinding; @property (nonatomic, strong) NSView *internalView; +@property (weak) GBOSDView *osdView; - (void) createInternalView; - (uint32_t *)currentBuffer; - (uint32_t *)previousBuffer; diff --git a/Cocoa/GBView.m b/Cocoa/GBView.m @@ -117,6 +117,7 @@ static const uint8_t workboy_vk_to_key[] = { NSEventModifierFlags previousModifiers; JOYController *lastController; GB_frame_blending_mode_t _frameBlendingMode; + bool _turbo; } + (instancetype)alloc @@ -283,6 +284,12 @@ static const uint8_t workboy_vk_to_key[] = { } } } + if (clockMultiplier > 1 || _turbo) { + [self.osdView displayText:@"Fast forwarding..."]; + } + else if (clockMultiplier < 1) { + [self.osdView displayText:@"Slow motion..."]; + } current_buffer = (current_buffer + 1) % self.numberOfBuffers; } @@ -329,6 +336,7 @@ static const uint8_t workboy_vk_to_key[] = { else { GB_set_turbo_mode(_gb, true, self.isRewinding); } + _turbo = true; analogClockMultiplierValid = false; break; @@ -336,6 +344,7 @@ static const uint8_t workboy_vk_to_key[] = { if (!self.document.partner) { self.isRewinding = true; GB_set_turbo_mode(_gb, false, false); + _turbo = false; } break; @@ -401,6 +410,7 @@ static const uint8_t workboy_vk_to_key[] = { else { GB_set_turbo_mode(_gb, false, false); } + _turbo = false; analogClockMultiplierValid = false; break; diff --git a/Cocoa/GBVisualizerView.h b/Cocoa/GBVisualizerView.h @@ -1,11 +1,3 @@ -// -// GBVisualizerView.h -// SameBoySDL -// -// Created by Lior Halphon on 7/4/21. -// Copyright © 2021 Lior Halphon. All rights reserved. -// - #import <Cocoa/Cocoa.h> #include <Core/gb.h> diff --git a/Cocoa/GBVisualizerView.m b/Cocoa/GBVisualizerView.m @@ -1,11 +1,3 @@ -// -// GBVisualizerView.m -// SameBoySDL -// -// Created by Lior Halphon on 7/4/21. -// Copyright © 2021 Lior Halphon. All rights reserved. -// - #import "GBVisualizerView.h" #include <Core/gb.h> diff --git a/Cocoa/Preferences.xib b/Cocoa/Preferences.xib @@ -67,6 +67,7 @@ </defaultToolbarItems> </toolbar> <connections> + <outlet property="OSDCheckbox" destination="quK-gY-Z6h" id="gxE-fd-1g7"/> <outlet property="analogControlsCheckbox" destination="RuW-Db-dzW" id="FRE-hI-mnU"/> <outlet property="aspectRatioCheckbox" destination="Vfj-tg-7OP" id="Yw0-xS-DBr"/> <outlet property="autoUpdatesCheckbox" destination="ZVh-ob-6wl" id="qPS-53-3aW"/> @@ -97,11 +98,11 @@ <point key="canvasLocation" x="183" y="354"/> </window> <customView id="sRK-wO-K6R"> - <rect key="frame" x="0.0" y="0.0" width="292" height="375"/> + <rect key="frame" x="0.0" y="0.0" width="292" height="395"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <subviews> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="T91-rh-rRp"> - <rect key="frame" x="18" y="338" width="256" height="17"/> + <rect key="frame" x="18" y="358" width="256" height="17"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Graphics filter:" id="pXg-WY-8Q5"> <font key="font" metaFont="system"/> @@ -110,7 +111,7 @@ </textFieldCell> </textField> <popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6pP-kK-EEC"> - <rect key="frame" x="30" y="305" width="234" height="26"/> + <rect key="frame" x="30" y="325" width="234" height="26"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <popUpButtonCell key="cell" type="push" title="Nearest neighbor (Pixelated)" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="neN-eo-LA7" id="I1w-05-lGl"> <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/> @@ -147,7 +148,7 @@ </connections> </popUpButton> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Wc3-2K-6CD"> - <rect key="frame" x="18" y="283" width="256" height="17"/> + <rect key="frame" x="18" y="303" width="256" height="17"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Color correction:" id="5Si-hz-EK3"> <font key="font" metaFont="system"/> @@ -156,7 +157,7 @@ </textFieldCell> </textField> <popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="VEz-N4-uP6"> - <rect key="frame" x="30" y="250" width="234" height="26"/> + <rect key="frame" x="30" y="270" width="234" height="26"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <popUpButtonCell key="cell" type="push" title="Disabled" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="D2J-wV-1vu" id="fNJ-Fi-yOm"> <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/> @@ -178,7 +179,7 @@ </connections> </popUpButton> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="MLC-Rx-FgO"> - <rect key="frame" x="18" y="174" width="252" height="17"/> + <rect key="frame" x="18" y="194" width="252" height="17"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Frame blending" id="UCa-EO-tzh"> <font key="font" metaFont="system"/> @@ -187,7 +188,7 @@ </textFieldCell> </textField> <popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="lxk-db-Sxv"> - <rect key="frame" x="30" y="145" width="234" height="22"/> + <rect key="frame" x="30" y="165" width="234" height="22"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <popUpButtonCell key="cell" type="push" title="Disabled" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="iHP-Yz-fiH" id="aQ6-HN-7Aj"> <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/> @@ -207,7 +208,7 @@ </connections> </popUpButton> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8fG-zm-hpr"> - <rect key="frame" x="18" y="123" width="252" height="17"/> + <rect key="frame" x="18" y="143" width="252" height="17"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Color palette for monochrome models:" id="LAN-8Y-T7H"> <font key="font" metaFont="system"/> @@ -216,7 +217,7 @@ </textFieldCell> </textField> <popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Iwr-eI-SD1"> - <rect key="frame" x="30" y="94" width="234" height="22"/> + <rect key="frame" x="30" y="114" width="234" height="22"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <popUpButtonCell key="cell" type="push" title="Greyscale" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="Ajr-5r-iIk" id="rEU-jh-m3j"> <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/> @@ -237,7 +238,7 @@ </connections> </popUpButton> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3Kz-cf-5X6"> - <rect key="frame" x="18" y="72" width="248" height="17"/> + <rect key="frame" x="18" y="92" width="248" height="17"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Display border:" id="HZd-qi-yyk"> <font key="font" metaFont="system"/> @@ -246,7 +247,7 @@ </textFieldCell> </textField> <popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="R9D-FV-bpd"> - <rect key="frame" x="30" y="40" width="234" height="25"/> + <rect key="frame" x="30" y="60" width="234" height="25"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <popUpButtonCell key="cell" type="push" title="Never" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" tag="1" imageScaling="proportionallyDown" inset="2" selectedItem="heL-AV-0az" id="DY9-2D-h1L"> <behavior key="behavior" lightByBackground="YES" lightByGray="YES"/> @@ -266,7 +267,7 @@ </connections> </popUpButton> <slider verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="NuA-mL-AJZ"> - <rect key="frame" x="30" y="198" width="234" height="24"/> + <rect key="frame" x="30" y="218" width="234" height="24"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <sliderCell key="cell" continuous="YES" state="on" alignment="left" minValue="-256" maxValue="256" tickMarkPosition="below" numberOfTickMarks="3" sliderType="linear" id="KX7-G9-k0O"/> <connections> @@ -274,7 +275,7 @@ </connections> </slider> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cCm-Oa-FbN"> - <rect key="frame" x="20" y="228" width="252" height="17"/> + <rect key="frame" x="20" y="248" width="252" height="17"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Ambient light temperature:" id="Lso-GQ-pBl"> <font key="font" metaFont="system"/> @@ -283,7 +284,7 @@ </textFieldCell> </textField> <button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Vfj-tg-7OP"> - <rect key="frame" x="18" y="18" width="256" height="18"/> + <rect key="frame" x="18" y="38" width="256" height="18"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <buttonCell key="cell" type="check" title="Keep aspect ratio" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="lsj-rC-Eo6"> <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/> @@ -293,8 +294,19 @@ <action selector="changeAspectRatio:" target="QvC-M9-y7g" id="mQG-Ib-1jN"/> </connections> </button> + <button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="quK-gY-Z6h"> + <rect key="frame" x="18" y="18" width="252" height="18"/> + <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> + <buttonCell key="cell" type="check" title="On-screen display" bezelStyle="regularSquare" imagePosition="left" inset="2" id="oeT-cD-YRw"> + <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/> + <font key="font" metaFont="system"/> + </buttonCell> + <connections> + <action selector="changeOSDEnabled:" target="QvC-M9-y7g" id="xUx-iN-jl6"/> + </connections> + </button> </subviews> - <point key="canvasLocation" x="-176" y="667.5"/> + <point key="canvasLocation" x="-176" y="677.5"/> </customView> <customView id="ymk-46-SX7"> <rect key="frame" x="0.0" y="0.0" width="292" height="375"/> @@ -583,7 +595,7 @@ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <clipView key="contentView" focusRingType="none" ambiguous="YES" drawsBackground="NO" id="AMs-PO-nid"> <rect key="frame" x="1" y="1" width="227" height="209"/> - <autoresizingMask key="autoresizingMask"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnResizing="NO" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" typeSelect="NO" id="UDd-IJ-fxX"> <rect key="frame" x="0.0" y="0.0" width="227" height="209"/> @@ -734,7 +746,7 @@ </connections> </button> <button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Qa7-Z7-yfO"> - <rect key="frame" x="27" y="13" width="172" height="32"/> + <rect key="frame" x="26" y="13" width="173" height="32"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> <buttonCell key="cell" type="push" title="Configure a controller" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="GdK-tQ-Wim"> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> diff --git a/Core/gb.c b/Core/gb.c @@ -1874,3 +1874,71 @@ void GB_set_rtc_mode(GB_gameboy_t *gb, GB_rtc_mode_t mode) gb->last_rtc_second = time(NULL); } } + +void GB_get_rom_title(GB_gameboy_t *gb, char *title) +{ + memset(title, 0, 17); + if (gb->rom_size >= 0x4000) { + for (unsigned i = 0; i < 0x10; i++) { + if (gb->rom[0x134 + i] < 0x20 || gb->rom[0x134 + i] >= 0x80) break; + title[i] = gb->rom[0x134 + i]; + } + } +} + +uint32_t GB_get_rom_crc32(GB_gameboy_t *gb) +{ + static const uint32_t table[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, + 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, + 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, + 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, + 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, + 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, + 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, + 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d + }; + + const uint8_t *byte = gb->rom; + uint32_t size = gb->rom_size; + uint32_t ret = 0xFFFFFFFF; + while (size--) { + ret = table[(ret ^ *byte++) & 0xFF] ^ (ret >> 8); + } + return ~ret; +} diff --git a/Core/gb.h b/Core/gb.h @@ -884,5 +884,10 @@ unsigned GB_get_screen_width(GB_gameboy_t *gb); unsigned GB_get_screen_height(GB_gameboy_t *gb); double GB_get_usual_frame_rate(GB_gameboy_t *gb); unsigned GB_get_player_count(GB_gameboy_t *gb); + +/* Handy ROM info APIs */ +// `title` must be at least 17 bytes in size +void GB_get_rom_title(GB_gameboy_t *gb, char *title); +uint32_t GB_get_rom_crc32(GB_gameboy_t *gb); #endif /* GB_h */ diff --git a/Core/save_state.c b/Core/save_state.c @@ -3,12 +3,10 @@ #include <errno.h> #include <assert.h> -#define str(x) #x -#define xstr(x) str(x) #ifdef GB_BIG_ENDIAN -#define BESS_NAME "SameBoy v" xstr(VERSION) " (Big Endian)" +#define BESS_NAME "SameBoy v" GB_VERSION " (Big Endian)" #else -#define BESS_NAME "SameBoy v" xstr(VERSION) +#define BESS_NAME "SameBoy v" GB_VERSION #endif typedef struct __attribute__((packed)) { diff --git a/Makefile b/Makefile @@ -121,7 +121,7 @@ endif CFLAGS += $(WARNINGS) -CFLAGS += -std=gnu11 -D_GNU_SOURCE -DVERSION="$(VERSION)" -I. -D_USE_MATH_DEFINES +CFLAGS += -std=gnu11 -D_GNU_SOURCE -DGB_VERSION='"$(VERSION)"' -I. -D_USE_MATH_DEFINES ifneq (,$(UPDATE_SUPPORT)) CFLAGS += -DUPDATE_SUPPORT endif diff --git a/SDL/main.c b/SDL/main.c @@ -652,9 +652,7 @@ int main(int argc, char **argv) #ifdef _WIN32 SetProcessDPIAware(); #endif -#define str(x) #x -#define xstr(x) str(x) - fprintf(stderr, "SameBoy v" xstr(VERSION) "\n"); + fprintf(stderr, "SameBoy v" GB_VERSION "\n"); bool fullscreen = get_arg_flag("--fullscreen", &argc, argv); bool nogl = get_arg_flag("--nogl", &argc, argv); @@ -713,7 +711,7 @@ int main(int argc, char **argv) SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - window = SDL_CreateWindow("SameBoy v" xstr(VERSION), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, + window = SDL_CreateWindow("SameBoy v" GB_VERSION, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 160 * configuration.default_scale, 144 * configuration.default_scale, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); if (window == NULL) { fputs(SDL_GetError(), stderr); diff --git a/libretro/Makefile b/libretro/Makefile @@ -311,7 +311,7 @@ endif include Makefile.common -CFLAGS += -DSAMEBOY_CORE_VERSION=\"$(VERSION)\" +CFLAGS += -DGB_VERSION=\"$(VERSION)\" OBJECTS := $(patsubst $(CORE_DIR)/%.c,$(CORE_DIR)/build/obj/%_libretro.c.o,$(SOURCES_C)) diff --git a/libretro/jni/Android.mk b/libretro/jni/Android.mk @@ -8,7 +8,7 @@ include $(CORE_DIR)/libretro/Makefile.common GENERATED_SOURCES := $(filter %_boot.c,$(SOURCES_C)) -COREFLAGS := -DINLINE=inline -D__LIBRETRO__ -DGB_INTERNAL $(INCFLAGS) -DSAMEBOY_CORE_VERSION=\"$(VERSION)\" -Wno-multichar -DANDROID +COREFLAGS := -DINLINE=inline -D__LIBRETRO__ -DGB_INTERNAL $(INCFLAGS) -DGB_VERSION=\"$(VERSION)\" -Wno-multichar -DANDROID GIT_VERSION := " $(shell git rev-parse --short HEAD || echo unknown)" ifneq ($(GIT_VERSION)," unknown") diff --git a/libretro/libretro.c b/libretro/libretro.c @@ -916,9 +916,9 @@ void retro_get_system_info(struct retro_system_info *info) memset(info, 0, sizeof(*info)); info->library_name = "SameBoy"; #ifdef GIT_VERSION - info->library_version = SAMEBOY_CORE_VERSION GIT_VERSION; + info->library_version = GB_VERSION GIT_VERSION; #else - info->library_version = SAMEBOY_CORE_VERSION; + info->library_version = GB_VERSION; #endif info->need_fullpath = true; info->valid_extensions = "gb|gbc";

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