Added optional OSD (Cocoa)

This commit is contained in:
Lior Halphon 2021-05-30 20:55:04 +03:00
parent 033f025851
commit 3ed18a76da
21 changed files with 276 additions and 53 deletions

View File

@ -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];
}

View File

@ -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;

View File

@ -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];
}

View File

@ -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"/>

6
Cocoa/GBOSDView.h Normal file
View File

@ -0,0 +1,6 @@
#import <Cocoa/Cocoa.h>
@interface GBOSDView : NSView
@property bool usesSGBScale;
- (void)displayText:(NSString *)text;
@end

104
Cocoa/GBOSDView.m Normal file
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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>

View File

@ -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>

View File

@ -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"/>

View File

@ -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;
}

View File

@ -885,4 +885,9 @@ 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 */

View File

@ -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)) {

View File

@ -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

View File

@ -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);

View File

@ -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))

View File

@ -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")

View File

@ -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";