mirror of https://github.com/bsnes-emu/bsnes.git
Added optional OSD (Cocoa)
This commit is contained in:
parent
033f025851
commit
3ed18a76da
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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"/>
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface GBOSDView : NSView
|
||||
@property bool usesSGBScale;
|
||||
- (void)displayText:(NSString *)text;
|
||||
@end
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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"/>
|
||||
|
|
68
Core/gb.c
68
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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)) {
|
||||
|
|
2
Makefile
2
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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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";
|
||||
|
|
Loading…
Reference in New Issue