Merge branch 'master' into sdl_gui
This commit is contained in:
commit
7a024d2a69
@ -30,7 +30,8 @@
|
|||||||
@"GBTurbo": @(kVK_Space),
|
@"GBTurbo": @(kVK_Space),
|
||||||
|
|
||||||
@"GBFilter": @"NearestNeighbor",
|
@"GBFilter": @"NearestNeighbor",
|
||||||
@"GBHighpassFilter": @(GB_HIGHPASS_REMOVE_DC_OFFSET),
|
@"GBColorCorrection": @(GB_COLOR_CORRECTION_EMULATE_HARDWARE),
|
||||||
|
@"GBHighpassFilter": @(GB_HIGHPASS_REMOVE_DC_OFFSET)
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,6 +145,7 @@ static void printImage(GB_gameboy_t *gb, uint32_t *image, uint8_t height,
|
|||||||
GB_set_log_callback(&gb, (GB_log_callback_t) consoleLog);
|
GB_set_log_callback(&gb, (GB_log_callback_t) consoleLog);
|
||||||
GB_set_input_callback(&gb, (GB_input_callback_t) consoleInput);
|
GB_set_input_callback(&gb, (GB_input_callback_t) consoleInput);
|
||||||
GB_set_async_input_callback(&gb, (GB_input_callback_t) asyncConsoleInput);
|
GB_set_async_input_callback(&gb, (GB_input_callback_t) asyncConsoleInput);
|
||||||
|
GB_set_color_correction_mode(&gb, (GB_color_correction_mode_t) [[NSUserDefaults standardUserDefaults] integerForKey:@"GBColorCorrection"]);
|
||||||
GB_set_rgb_encode_callback(&gb, rgbEncode);
|
GB_set_rgb_encode_callback(&gb, rgbEncode);
|
||||||
GB_set_camera_get_pixel_callback(&gb, cameraGetPixel);
|
GB_set_camera_get_pixel_callback(&gb, cameraGetPixel);
|
||||||
GB_set_camera_update_request_callback(&gb, cameraRequestUpdate);
|
GB_set_camera_update_request_callback(&gb, cameraRequestUpdate);
|
||||||
@ -302,6 +303,11 @@ static void printImage(GB_gameboy_t *gb, uint32_t *image, uint8_t height,
|
|||||||
name:@"GBHighpassFilterChanged"
|
name:@"GBHighpassFilterChanged"
|
||||||
object:nil];
|
object:nil];
|
||||||
|
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||||
|
selector:@selector(updateColorCorrectionMode)
|
||||||
|
name:@"GBColorCorrectionChanged"
|
||||||
|
object:nil];
|
||||||
|
|
||||||
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"EmulateDMG"]) {
|
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"EmulateDMG"]) {
|
||||||
[self initDMG];
|
[self initDMG];
|
||||||
}
|
}
|
||||||
@ -1287,4 +1293,11 @@ static void printImage(GB_gameboy_t *gb, uint32_t *image, uint8_t height,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) updateColorCorrectionMode
|
||||||
|
{
|
||||||
|
if (GB_is_inited(&gb)) {
|
||||||
|
GB_set_color_correction_mode(&gb, (GB_color_correction_mode_t) [[NSUserDefaults standardUserDefaults] integerForKey:@"GBColorCorrection"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -5,4 +5,5 @@
|
|||||||
@property IBOutlet NSPopUpButton *graphicsFilterPopupButton;
|
@property IBOutlet NSPopUpButton *graphicsFilterPopupButton;
|
||||||
@property (strong) IBOutlet NSButton *aspectRatioCheckbox;
|
@property (strong) IBOutlet NSButton *aspectRatioCheckbox;
|
||||||
@property (strong) IBOutlet NSPopUpButton *highpassFilterPopupButton;
|
@property (strong) IBOutlet NSPopUpButton *highpassFilterPopupButton;
|
||||||
|
@property (strong) IBOutlet NSPopUpButton *colorCorrectionPopupButton;
|
||||||
@end
|
@end
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
NSPopUpButton *_graphicsFilterPopupButton;
|
NSPopUpButton *_graphicsFilterPopupButton;
|
||||||
NSPopUpButton *_highpassFilterPopupButton;
|
NSPopUpButton *_highpassFilterPopupButton;
|
||||||
|
NSPopUpButton *_colorCorrectionPopupButton;
|
||||||
NSButton *_aspectRatioCheckbox;
|
NSButton *_aspectRatioCheckbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,6 +53,18 @@
|
|||||||
return _highpassFilterPopupButton;
|
return _highpassFilterPopupButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setColorCorrectionPopupButton:(NSPopUpButton *)colorCorrectionPopupButton
|
||||||
|
{
|
||||||
|
_colorCorrectionPopupButton = colorCorrectionPopupButton;
|
||||||
|
NSInteger mode = [[NSUserDefaults standardUserDefaults] integerForKey:@"GBColorCorrection"];
|
||||||
|
[_colorCorrectionPopupButton selectItemAtIndex:mode];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSPopUpButton *)colorCorrectionPopupButton
|
||||||
|
{
|
||||||
|
return _colorCorrectionPopupButton;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)setHighpassFilterPopupButton:(NSPopUpButton *)highpassFilterPopupButton
|
- (void)setHighpassFilterPopupButton:(NSPopUpButton *)highpassFilterPopupButton
|
||||||
{
|
{
|
||||||
_highpassFilterPopupButton = highpassFilterPopupButton;
|
_highpassFilterPopupButton = highpassFilterPopupButton;
|
||||||
@ -128,6 +141,14 @@
|
|||||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"GBAspectChanged" object:nil];
|
[[NSNotificationCenter defaultCenter] postNotificationName:@"GBAspectChanged" object:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (IBAction)colorCorrectionChanged:(id)sender
|
||||||
|
{
|
||||||
|
[[NSUserDefaults standardUserDefaults] setObject:@([sender indexOfSelectedItem])
|
||||||
|
forKey:@"GBColorCorrection"];
|
||||||
|
[[NSNotificationCenter defaultCenter] postNotificationName:@"GBColorCorrectionChanged" object:nil];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
- (NSButton *)aspectRatioCheckbox
|
- (NSButton *)aspectRatioCheckbox
|
||||||
{
|
{
|
||||||
return _aspectRatioCheckbox;
|
return _aspectRatioCheckbox;
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="12121" systemVersion="16F73" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13196" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="12121"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13196"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
@ -17,14 +17,14 @@
|
|||||||
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
|
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
|
||||||
<windowCollectionBehavior key="collectionBehavior" fullScreenAuxiliary="YES"/>
|
<windowCollectionBehavior key="collectionBehavior" fullScreenAuxiliary="YES"/>
|
||||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||||
<rect key="contentRect" x="196" y="240" width="292" height="378"/>
|
<rect key="contentRect" x="196" y="240" width="292" height="426"/>
|
||||||
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||||
<view key="contentView" id="EiT-Mj-1SZ">
|
<view key="contentView" id="EiT-Mj-1SZ">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="292" height="378"/>
|
<rect key="frame" x="0.0" y="0.0" width="292" height="426"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="NO" translatesAutoresizingMaskIntoConstraints="NO" id="T91-rh-rRp">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="T91-rh-rRp">
|
||||||
<rect key="frame" x="18" y="341" width="256" height="17"/>
|
<rect key="frame" x="18" y="389" width="256" height="17"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Graphics Filter:" id="pXg-WY-8Q5">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Graphics Filter:" id="pXg-WY-8Q5">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
@ -33,7 +33,7 @@
|
|||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6pP-kK-EEC">
|
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6pP-kK-EEC">
|
||||||
<rect key="frame" x="30" y="309" width="245" height="26"/>
|
<rect key="frame" x="30" y="357" width="245" height="26"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="I1w-05-lGl">
|
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="I1w-05-lGl">
|
||||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||||
@ -66,6 +66,36 @@
|
|||||||
<action selector="graphicFilterChanged:" target="QvC-M9-y7g" id="n87-t4-fbV"/>
|
<action selector="graphicFilterChanged:" target="QvC-M9-y7g" id="n87-t4-fbV"/>
|
||||||
</connections>
|
</connections>
|
||||||
</popUpButton>
|
</popUpButton>
|
||||||
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Wc3-2K-6CD">
|
||||||
|
<rect key="frame" x="18" y="335" 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"/>
|
||||||
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
</textField>
|
||||||
|
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="VEz-N4-uP6">
|
||||||
|
<rect key="frame" x="30" y="303" width="245" 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"/>
|
||||||
|
<font key="font" metaFont="menu"/>
|
||||||
|
<menu key="menu" id="6go-Lb-a4m">
|
||||||
|
<items>
|
||||||
|
<menuItem title="Disabled" state="on" id="D2J-wV-1vu">
|
||||||
|
<modifierMask key="keyEquivalentModifierMask"/>
|
||||||
|
</menuItem>
|
||||||
|
<menuItem title="Correct Color Curves" id="B3Q-x1-VRl"/>
|
||||||
|
<menuItem title="Emulate Hardware" id="XBL-hS-7ke"/>
|
||||||
|
<menuItem title="Preserve Brightness" id="tlx-WB-Bkw"/>
|
||||||
|
</items>
|
||||||
|
</menu>
|
||||||
|
</popUpButtonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="colorCorrectionChanged:" target="QvC-M9-y7g" id="Oq4-B5-nO6"/>
|
||||||
|
</connections>
|
||||||
|
</popUpButton>
|
||||||
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="T69-6N-dhT">
|
<popUpButton verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="T69-6N-dhT">
|
||||||
<rect key="frame" x="30" y="223" width="245" height="26"/>
|
<rect key="frame" x="30" y="223" width="245" height="26"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
@ -87,7 +117,7 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</popUpButton>
|
</popUpButton>
|
||||||
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Vfj-tg-7OP">
|
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Vfj-tg-7OP">
|
||||||
<rect key="frame" x="18" y="285" width="256" height="18"/>
|
<rect key="frame" x="18" y="278" width="256" height="18"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<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">
|
<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"/>
|
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||||
@ -97,7 +127,7 @@
|
|||||||
<action selector="changeAspectRatio:" target="QvC-M9-y7g" id="mQG-Ib-1jN"/>
|
<action selector="changeAspectRatio:" target="QvC-M9-y7g" id="mQG-Ib-1jN"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Utu-t4-cLx">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Utu-t4-cLx">
|
||||||
<rect key="frame" x="18" y="201" width="256" height="17"/>
|
<rect key="frame" x="18" y="201" width="256" height="17"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Button configuration:" id="YqW-Ds-VIC">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Button configuration:" id="YqW-Ds-VIC">
|
||||||
@ -106,7 +136,7 @@
|
|||||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
</textField>
|
</textField>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" allowsCharacterPickerTouchBarItem="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WU3-oV-KHO">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="WU3-oV-KHO">
|
||||||
<rect key="frame" x="18" y="255" width="256" height="17"/>
|
<rect key="frame" x="18" y="255" width="256" height="17"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="High-pass Filter:" id="YLF-RL-b2D">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="High-pass Filter:" id="YLF-RL-b2D">
|
||||||
@ -177,12 +207,13 @@
|
|||||||
</view>
|
</view>
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="aspectRatioCheckbox" destination="Vfj-tg-7OP" id="Yw0-xS-DBr"/>
|
<outlet property="aspectRatioCheckbox" destination="Vfj-tg-7OP" id="Yw0-xS-DBr"/>
|
||||||
|
<outlet property="colorCorrectionPopupButton" destination="VEz-N4-uP6" id="EO2-Vt-JFJ"/>
|
||||||
<outlet property="controlsTableView" destination="UDd-IJ-fxX" id="a1D-Md-yXv"/>
|
<outlet property="controlsTableView" destination="UDd-IJ-fxX" id="a1D-Md-yXv"/>
|
||||||
<outlet property="delegate" destination="-2" id="ASc-vN-Zbq"/>
|
<outlet property="delegate" destination="-2" id="ASc-vN-Zbq"/>
|
||||||
<outlet property="graphicsFilterPopupButton" destination="6pP-kK-EEC" id="LS7-HY-kHC"/>
|
<outlet property="graphicsFilterPopupButton" destination="6pP-kK-EEC" id="LS7-HY-kHC"/>
|
||||||
<outlet property="highpassFilterPopupButton" destination="T69-6N-dhT" id="0p6-4m-hb1"/>
|
<outlet property="highpassFilterPopupButton" destination="T69-6N-dhT" id="0p6-4m-hb1"/>
|
||||||
</connections>
|
</connections>
|
||||||
<point key="canvasLocation" x="179" y="474"/>
|
<point key="canvasLocation" x="179" y="498"/>
|
||||||
</window>
|
</window>
|
||||||
</objects>
|
</objects>
|
||||||
</document>
|
</document>
|
||||||
|
@ -222,21 +222,77 @@ static void display_vblank(GB_gameboy_t *gb)
|
|||||||
|
|
||||||
static inline uint8_t scale_channel(uint8_t x)
|
static inline uint8_t scale_channel(uint8_t x)
|
||||||
{
|
{
|
||||||
x &= 0x1f;
|
|
||||||
return (x << 3) | (x >> 2);
|
return (x << 3) | (x >> 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint8_t scale_channel_with_curve(uint8_t x)
|
||||||
|
{
|
||||||
|
return (uint8_t[]){0,2,4,7,12,18,25,34,42,52,62,73,85,97,109,121,134,146,158,170,182,193,203,213,221,230,237,243,248,251,253,255,}[x];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t GB_convert_rgb15(GB_gameboy_t *gb, uint16_t color)
|
||||||
|
{
|
||||||
|
uint8_t r = (color) & 0x1F;
|
||||||
|
uint8_t g = (color >> 5) & 0x1F;
|
||||||
|
uint8_t b = (color >> 10) & 0x1F;
|
||||||
|
|
||||||
|
if (gb->color_correction_mode == GB_COLOR_CORRECTION_DISABLED) {
|
||||||
|
r = scale_channel(r);
|
||||||
|
g = scale_channel(g);
|
||||||
|
b = scale_channel(b);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r = scale_channel_with_curve(r);
|
||||||
|
g = scale_channel_with_curve(g);
|
||||||
|
b = scale_channel_with_curve(b);
|
||||||
|
|
||||||
|
if (gb->color_correction_mode != GB_COLOR_CORRECTION_CORRECT_CURVES) {
|
||||||
|
uint8_t new_g = (g * 3 + b) / 4;
|
||||||
|
uint8_t new_r = r, new_b = b;
|
||||||
|
if (gb->color_correction_mode == GB_COLOR_CORRECTION_PRESERVE_BRIGHTNESS) {
|
||||||
|
uint8_t old_max = MAX(r, MAX(g, b));
|
||||||
|
uint8_t new_max = MAX(new_r, MAX(new_g, new_b));
|
||||||
|
|
||||||
|
if (new_max != 0) {
|
||||||
|
new_r = new_r * old_max / new_max;
|
||||||
|
new_g = new_g * old_max / new_max;
|
||||||
|
new_b = new_b * old_max / new_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t old_min = MIN(r, MIN(g, b));
|
||||||
|
uint8_t new_min = MIN(new_r, MIN(new_g, new_b));
|
||||||
|
|
||||||
|
if (new_min != 0xff) {
|
||||||
|
new_r = 0xff - (0xff - new_r) * (0xff - old_min) / (0xff - new_min);
|
||||||
|
new_g = 0xff - (0xff - new_g) * (0xff - old_min) / (0xff - new_min);
|
||||||
|
new_b = 0xff - (0xff - new_b) * (0xff - old_min) / (0xff - new_min);;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r = new_r;
|
||||||
|
g = new_g;
|
||||||
|
b = new_b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return gb->rgb_encode_callback(gb, r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
void GB_palette_changed(GB_gameboy_t *gb, bool background_palette, uint8_t index)
|
void GB_palette_changed(GB_gameboy_t *gb, bool background_palette, uint8_t index)
|
||||||
{
|
{
|
||||||
|
if (!gb->rgb_encode_callback) return;
|
||||||
uint8_t *palette_data = background_palette? gb->background_palettes_data : gb->sprite_palettes_data;
|
uint8_t *palette_data = background_palette? gb->background_palettes_data : gb->sprite_palettes_data;
|
||||||
uint16_t color = palette_data[index & ~1] | (palette_data[index | 1] << 8);
|
uint16_t color = palette_data[index & ~1] | (palette_data[index | 1] << 8);
|
||||||
|
|
||||||
// No need to &, scale channel does that.
|
(background_palette? gb->background_palettes_rgb : gb->sprite_palettes_rgb)[index / 2] = GB_convert_rgb15(gb, color);
|
||||||
uint8_t r = scale_channel(color);
|
}
|
||||||
uint8_t g = scale_channel(color >> 5);
|
|
||||||
uint8_t b = scale_channel(color >> 10);
|
void GB_set_color_correction_mode(GB_gameboy_t *gb, GB_color_correction_mode_t mode)
|
||||||
assert (gb->rgb_encode_callback);
|
{
|
||||||
(background_palette? gb->background_palettes_rgb : gb->sprite_palettes_rgb)[index / 2] = gb->rgb_encode_callback(gb, r, g, b);
|
gb->color_correction_mode = mode;
|
||||||
|
for (unsigned i = 0; i < 32; i++) {
|
||||||
|
GB_palette_changed(gb, false, i * 2);
|
||||||
|
GB_palette_changed(gb, true, i * 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -34,8 +34,16 @@ typedef struct {
|
|||||||
bool obscured_by_line_limit;
|
bool obscured_by_line_limit;
|
||||||
} GB_oam_info_t;
|
} GB_oam_info_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GB_COLOR_CORRECTION_DISABLED,
|
||||||
|
GB_COLOR_CORRECTION_CORRECT_CURVES,
|
||||||
|
GB_COLOR_CORRECTION_EMULATE_HARDWARE,
|
||||||
|
GB_COLOR_CORRECTION_PRESERVE_BRIGHTNESS,
|
||||||
|
} GB_color_correction_mode_t;
|
||||||
|
|
||||||
void GB_draw_tileset(GB_gameboy_t *gb, uint32_t *dest, GB_palette_type_t palette_type, uint8_t palette_index);
|
void GB_draw_tileset(GB_gameboy_t *gb, uint32_t *dest, GB_palette_type_t palette_type, uint8_t palette_index);
|
||||||
void GB_draw_tilemap(GB_gameboy_t *gb, uint32_t *dest, GB_palette_type_t palette_type, uint8_t palette_index, GB_map_type_t map_type, GB_tileset_type_t tileset_type);
|
void GB_draw_tilemap(GB_gameboy_t *gb, uint32_t *dest, GB_palette_type_t palette_type, uint8_t palette_index, GB_map_type_t map_type, GB_tileset_type_t tileset_type);
|
||||||
uint8_t GB_get_oam_info(GB_gameboy_t *gb, GB_oam_info_t *dest, uint8_t *sprite_height);
|
uint8_t GB_get_oam_info(GB_gameboy_t *gb, GB_oam_info_t *dest, uint8_t *sprite_height);
|
||||||
|
uint32_t GB_convert_rgb15(GB_gameboy_t *gb, uint16_t color);
|
||||||
|
void GB_set_color_correction_mode(GB_gameboy_t *gb, GB_color_correction_mode_t mode);
|
||||||
#endif /* display_h */
|
#endif /* display_h */
|
||||||
|
@ -541,6 +541,10 @@ void *GB_get_direct_access(GB_gameboy_t *gb, GB_direct_access_t access, size_t *
|
|||||||
*size = sizeof(gb->sprite_palettes_data);
|
*size = sizeof(gb->sprite_palettes_data);
|
||||||
*bank = 0;
|
*bank = 0;
|
||||||
return &gb->sprite_palettes_data;
|
return &gb->sprite_palettes_data;
|
||||||
|
case GB_DIRECT_ACCESS_IE:
|
||||||
|
*size = sizeof(gb->interrupt_enable);
|
||||||
|
*bank = 0;
|
||||||
|
return &gb->interrupt_enable;
|
||||||
default:
|
default:
|
||||||
*size = 0;
|
*size = 0;
|
||||||
*bank = 0;
|
*bank = 0;
|
||||||
|
14
Core/gb.h
14
Core/gb.h
@ -162,6 +162,14 @@ typedef enum {
|
|||||||
#define DIV_CYCLES (0x100)
|
#define DIV_CYCLES (0x100)
|
||||||
#define INTERNAL_DIV_CYCLES (0x40000)
|
#define INTERNAL_DIV_CYCLES (0x40000)
|
||||||
#define FRAME_LENGTH 16742706 // in nanoseconds
|
#define FRAME_LENGTH 16742706 // in nanoseconds
|
||||||
|
|
||||||
|
#if !defined(MIN)
|
||||||
|
#define MIN(A,B) ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __a : __b; })
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(MAX)
|
||||||
|
#define MAX(A,B) ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __b : __a; })
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef void (*GB_vblank_callback_t)(GB_gameboy_t *gb);
|
typedef void (*GB_vblank_callback_t)(GB_gameboy_t *gb);
|
||||||
@ -361,8 +369,6 @@ struct GB_gameboy_internal_s {
|
|||||||
uint8_t oam[0xA0];
|
uint8_t oam[0xA0];
|
||||||
uint8_t background_palettes_data[0x40];
|
uint8_t background_palettes_data[0x40];
|
||||||
uint8_t sprite_palettes_data[0x40];
|
uint8_t sprite_palettes_data[0x40];
|
||||||
uint32_t background_palettes_rgb[0x20];
|
|
||||||
uint32_t sprite_palettes_rgb[0x20];
|
|
||||||
int16_t previous_lcdc_x;
|
int16_t previous_lcdc_x;
|
||||||
bool stat_interrupt_line;
|
bool stat_interrupt_line;
|
||||||
uint8_t effective_scx;
|
uint8_t effective_scx;
|
||||||
@ -405,6 +411,9 @@ struct GB_gameboy_internal_s {
|
|||||||
|
|
||||||
/* I/O */
|
/* I/O */
|
||||||
uint32_t *screen;
|
uint32_t *screen;
|
||||||
|
uint32_t background_palettes_rgb[0x20];
|
||||||
|
uint32_t sprite_palettes_rgb[0x20];
|
||||||
|
GB_color_correction_mode_t color_correction_mode;
|
||||||
bool keys[GB_KEY_MAX];
|
bool keys[GB_KEY_MAX];
|
||||||
|
|
||||||
/* Timing */
|
/* Timing */
|
||||||
@ -512,6 +521,7 @@ typedef enum {
|
|||||||
GB_DIRECT_ACCESS_OAM,
|
GB_DIRECT_ACCESS_OAM,
|
||||||
GB_DIRECT_ACCESS_BGP,
|
GB_DIRECT_ACCESS_BGP,
|
||||||
GB_DIRECT_ACCESS_OBP,
|
GB_DIRECT_ACCESS_OBP,
|
||||||
|
GB_DIRECT_ACCESS_IE,
|
||||||
} GB_direct_access_t;
|
} GB_direct_access_t;
|
||||||
|
|
||||||
/* Returns a mutable pointer to various hardware memories. If that memory is banked, the current bank
|
/* Returns a mutable pointer to various hardware memories. If that memory is banked, the current bank
|
||||||
|
@ -213,6 +213,11 @@ int GB_load_state(GB_gameboy_t *gb, const char *path)
|
|||||||
gb->rumble_callback(gb, gb->rumble_state);
|
gb->rumble_callback(gb, gb->rumble_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < 32; i++) {
|
||||||
|
GB_palette_changed(gb, false, i * 2);
|
||||||
|
GB_palette_changed(gb, true, i * 2);
|
||||||
|
}
|
||||||
|
|
||||||
error:
|
error:
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return errno;
|
return errno;
|
||||||
|
Loading…
Reference in New Issue
Block a user