Work around bad Clang and GCC optimizations of inline compile-time consts (They can't be static before C23, which isn't supported by Clang)

This commit is contained in:
Lior Halphon 2023-06-21 21:47:30 +03:00
parent 951d0b07f0
commit 57b50cab63
16 changed files with 58 additions and 56 deletions

View File

@ -590,7 +590,7 @@ static uint32_t color_to_int(NSColor *color)
JOYButtonUsage usage = ((JOYButtonUsage)[mapping[n2s(button.uniqueID)] unsignedIntValue]) ?: -1;
if (!mapping && usage >= JOYButtonUsageGeneric0) {
usage = (const JOYButtonUsage[]){JOYButtonUsageY, JOYButtonUsageA, JOYButtonUsageB, JOYButtonUsageX}[(usage - JOYButtonUsageGeneric0) & 3];
usage = GB_inline_const(JOYButtonUsage[], {JOYButtonUsageY, JOYButtonUsageA, JOYButtonUsageB, JOYButtonUsageX})[(usage - JOYButtonUsageGeneric0) & 3];
}
if (usage == GBJoyKitHotkey1 || usage == GBJoyKitHotkey2) {

View File

@ -455,7 +455,7 @@ static inline NSString *keyEquivalentString(NSMenuItem *item)
- (IBAction)displayColorCorrectionHelp:(id)sender
{
[GBWarningPopover popoverWithContents:
(NSString * const[]){
GB_inline_const(NSString *[], {
[GB_COLOR_CORRECTION_DISABLED] = @"Colors are directly interpreted as sRGB, resulting in unbalanced colors and inaccurate hues.",
[GB_COLOR_CORRECTION_CORRECT_CURVES] = @"Colors have their brightness corrected, but hues remain unbalanced.",
[GB_COLOR_CORRECTION_MODERN_BALANCED] = @"Emulates a modern display. Blue contrast is moderately enhanced at the cost of slight hue inaccuracy.",
@ -463,7 +463,7 @@ static inline NSString *keyEquivalentString(NSMenuItem *item)
[GB_COLOR_CORRECTION_REDUCE_CONTRAST] = @"Slightly reduce the contrast to better represent the tint and contrast of the original display.",
[GB_COLOR_CORRECTION_LOW_CONTRAST] = @"Harshly reduce the contrast to accurately represent the tint and low constrast of the original display.",
[GB_COLOR_CORRECTION_MODERN_ACCURATE] = @"Emulates a modern display. Colors have their hues and brightness corrected.",
} [self.colorCorrectionPopupButton.selectedItem.tag]
}) [self.colorCorrectionPopupButton.selectedItem.tag]
title:self.colorCorrectionPopupButton.selectedItem.title
onView:sender
timeout:6
@ -473,11 +473,11 @@ static inline NSString *keyEquivalentString(NSMenuItem *item)
- (IBAction)displayHighPassHelp:(id)sender
{
[GBWarningPopover popoverWithContents:
(NSString * const[]){
GB_inline_const(NSString *[], {
[GB_HIGHPASS_OFF] = @"No high-pass filter will be applied. DC offset will be kept, pausing and resuming will trigger audio pops.",
[GB_HIGHPASS_ACCURATE] = @"An accurate high-pass filter will be applied, removing the DC offset while somewhat attenuating the bass.",
[GB_HIGHPASS_REMOVE_DC_OFFSET] = @"A high-pass filter will be applied to the DC offset itself, removing the DC offset while preserving the waveform.",
} [self.highpassFilterPopupButton.selectedItem.tag]
}) [self.highpassFilterPopupButton.selectedItem.tag]
title:self.highpassFilterPopupButton.selectedItem.title
onView:sender
timeout:6

View File

@ -536,7 +536,7 @@ static const uint8_t workboy_vk_to_key[] = {
JOYButtonUsage usage = ((JOYButtonUsage)[mapping[n2s(button.uniqueID)] unsignedIntValue]) ?: button.usage;
if (!mapping && usage >= JOYButtonUsageGeneric0) {
usage = (const JOYButtonUsage[]){JOYButtonUsageY, JOYButtonUsageA, JOYButtonUsageB, JOYButtonUsageX}[(usage - JOYButtonUsageGeneric0) & 3];
usage = GB_inline_const(JOYButtonUsage[], {JOYButtonUsageY, JOYButtonUsageA, JOYButtonUsageB, JOYButtonUsageX})[(usage - JOYButtonUsageGeneric0) & 3];
}
GB_gameboy_t *effectiveGB = _gb;

View File

@ -1279,7 +1279,7 @@ void GB_apu_write(GB_gameboy_t *gb, uint8_t reg, uint8_t value)
gb->apu.wave_channel.pulse_length = (0x100 - value);
break;
case GB_IO_NR32:
gb->apu.wave_channel.shift = (const uint8_t[]){4, 0, 1, 2}[(value >> 5) & 3];
gb->apu.wave_channel.shift = inline_const(uint8_t[], {4, 0, 1, 2})[(value >> 5) & 3];
if (gb->apu.is_active[GB_WAVE]) {
update_wave_sample(gb, 0);
}
@ -1394,11 +1394,11 @@ void GB_apu_write(GB_gameboy_t *gb, uint8_t reg, uint8_t value)
if (!divisor) divisor = 2;
if (gb->model > GB_MODEL_CGB_C) {
gb->apu.noise_channel.counter_countdown =
divisor + (divisor == 2? 0 : (const uint8_t[]){2, 1, 0, 3}[(gb->apu.noise_channel.alignment) & 3]);
divisor + (divisor == 2? 0 : inline_const(uint8_t[], {2, 1, 0, 3})[(gb->apu.noise_channel.alignment) & 3]);
}
else {
gb->apu.noise_channel.counter_countdown =
divisor + (divisor == 2? 0 : (const uint8_t[]){2, 1, 4, 3}[(gb->apu.noise_channel.alignment) & 3]);
divisor + (divisor == 2? 0 : inline_const(uint8_t[], {2, 1, 4, 3})[(gb->apu.noise_channel.alignment) & 3]);
}
gb->apu.noise_channel.delta = 0;
}
@ -1442,10 +1442,10 @@ void GB_apu_write(GB_gameboy_t *gb, uint8_t reg, uint8_t value)
}
else {
if (gb->model <= GB_MODEL_CGB_C) {
gb->apu.noise_channel.counter_countdown += (const uint8_t[]){2, 1, 4, 3}[gb->apu.noise_channel.alignment & 3];
gb->apu.noise_channel.counter_countdown += inline_const(uint8_t[], {2, 1, 4, 3})[gb->apu.noise_channel.alignment & 3];
}
else {
gb->apu.noise_channel.counter_countdown += (const uint8_t[]){2, 1, 0, 3}[gb->apu.noise_channel.alignment & 3];
gb->apu.noise_channel.counter_countdown += inline_const(uint8_t[], {2, 1, 0, 3})[gb->apu.noise_channel.alignment & 3];
}
if (((gb->apu.noise_channel.alignment + 1) & 3) < 2) {
if ((gb->io_registers[GB_IO_NR43] & 0x07) == 1) {

View File

@ -1834,7 +1834,7 @@ static bool lcd(GB_gameboy_t *gb, char *arguments, char *modifiers, const debugg
GB_log(gb, "Window position: %d, %d\n", (signed) gb->io_registers[GB_IO_WX] - 7, gb->io_registers[GB_IO_WY]);
GB_log(gb, "Interrupt line: %s\n", gb->stat_interrupt_line? "On" : "Off");
GB_log(gb, "Background shifter size: %d\n", gb->bg_fifo.size);
GB_log(gb, "Background fetcher state: %s\n", (const char *[]){
GB_log(gb, "Background fetcher state: %s\n", inline_const(const char *[], {
"Tile (1/2)",
"Tile (2/2)",
"Low data (1/2)",
@ -1843,7 +1843,7 @@ static bool lcd(GB_gameboy_t *gb, char *arguments, char *modifiers, const debugg
"High data (2/2)",
"Push (1/2)",
"Push (2/2)",
}[gb->fetcher_state & 7]);
})[gb->fetcher_state & 7]);
return true;
}
@ -1919,8 +1919,8 @@ static bool apu(GB_gameboy_t *gb, char *arguments, char *modifiers, const debugg
uint8_t duty = gb->io_registers[channel == GB_SQUARE_1? GB_IO_NR11 :GB_IO_NR21] >> 6;
GB_log(gb, " Duty cycle %s%% (%s), current index %u/8%s\n",
duty > 3? "" : (const char *const[]){"12.5", " 25", " 50", " 75"}[duty],
duty > 3? "" : (const char *const[]){"_______-", "-______-", "-____---", "_------_"}[duty],
duty > 3? "" : inline_const(const char *[], {"12.5", " 25", " 50", " 75"})[duty],
duty > 3? "" : inline_const(const char *[], {"_______-", "-______-", "-____---", "_------_"})[duty],
gb->apu.square_channels[channel].current_sample_index,
gb->apu.square_channels[channel].sample_surpressed ? " (suppressed)" : "");
@ -1955,7 +1955,7 @@ static bool apu(GB_gameboy_t *gb, char *arguments, char *modifiers, const debugg
GB_log(gb, " Current position: %u\n", gb->apu.wave_channel.current_sample_index);
GB_log(gb, " Volume %s (right-shifted %u times)\n",
gb->apu.wave_channel.shift > 4? "" : (const char *const[]){"100%", "50%", "25%", "", "muted"}[gb->apu.wave_channel.shift],
gb->apu.wave_channel.shift > 4? "" : inline_const(const char *[], {"100%", "50%", "25%", "", "muted"})[gb->apu.wave_channel.shift],
gb->apu.wave_channel.shift);
GB_log(gb, " Current sample length: %u APU ticks (next in %u ticks)\n",

View File

@ -2,12 +2,14 @@
#define GB_likely(x) __builtin_expect((bool)(x), 1)
#define GB_unlikely(x) __builtin_expect((bool)(x), 0)
#define GB_inline_const(type, ...) (*({static const typeof(type) _= __VA_ARGS__; &_;}))
#ifdef GB_INTERNAL
// "Keyword" definitions
#define likely(x) GB_likely(x)
#define unlikely(x) GB_unlikely(x)
#define inline_const GB_inline_const
#define typeof __typeof__
#if !defined(MIN)

View File

@ -254,17 +254,17 @@ static inline uint8_t scale_channel(uint8_t x)
static inline uint8_t scale_channel_with_curve(uint8_t x)
{
return (const uint8_t[]){0,6,12,20,28,36,45,56,66,76,88,100,113,125,137,149,161,172,182,192,202,210,218,225,232,238,243,247,250,252,254,255}[x];
return inline_const(uint8_t[], {0,6,12,20,28,36,45,56,66,76,88,100,113,125,137,149,161,172,182,192,202,210,218,225,232,238,243,247,250,252,254,255})[x];
}
static inline uint8_t scale_channel_with_curve_agb(uint8_t x)
{
return (const uint8_t[]){0,3,8,14,20,26,33,40,47,54,62,70,78,86,94,103,112,120,129,138,147,157,166,176,185,195,205,215,225,235,245,255}[x];
return inline_const(uint8_t[], {0,3,8,14,20,26,33,40,47,54,62,70,78,86,94,103,112,120,129,138,147,157,166,176,185,195,205,215,225,235,245,255})[x];
}
static inline uint8_t scale_channel_with_curve_sgb(uint8_t x)
{
return (const uint8_t[]){0,2,5,9,15,20,27,34,42,50,58,67,76,85,94,104,114,123,133,143,153,163,173,182,192,202,211,220,229,238,247,255}[x];
return inline_const(uint8_t[], {0,2,5,9,15,20,27,34,42,50,58,67,76,85,94,104,114,123,133,143,153,163,173,182,192,202,211,220,229,238,247,255})[x];
}

View File

@ -172,7 +172,7 @@ hacksByName = @{
JOYConnectedUsage: @2,
JOYConnectedUsagePage: @0xFF00,
JOYActivationReport: [NSData dataWithBytes:(uint8_t[]){0x13} length:1],
JOYActivationReport: [NSData dataWithBytes:&inline_const(uint8_t, 0x13) length:1],
JOYCustomReports: @{

View File

@ -17,13 +17,13 @@
+ (NSString *)usageToString: (JOYAxes2DUsage) usage
{
if (usage < JOYAxes2DUsageNonGenericMax) {
return (NSString *[]) {
return inline_const(NSString *[], {
@"None",
@"Left Stick",
@"Right Stick",
@"Middle Stick",
@"Pointer",
}[usage];
})[usage];
}
if (usage >= JOYAxes2DUsageGeneric0) {
return [NSString stringWithFormat:@"Generic 2D Analog Control %d", usage - JOYAxes2DUsageGeneric0];

View File

@ -17,12 +17,12 @@
+ (NSString *)usageToString: (JOYAxes3DUsage) usage
{
if (usage < JOYAxes3DUsageNonGenericMax) {
return (NSString *[]) {
return inline_const(NSString *[], {
@"None",
@"Acceleretion",
@"Orientation",
@"Gyroscope",
}[usage];
})[usage];
}
if (usage >= JOYAxes3DUsageGeneric0) {
return [NSString stringWithFormat:@"Generic 3D Analog Control %d", usage - JOYAxes3DUsageGeneric0];

View File

@ -11,7 +11,7 @@
+ (NSString *)usageToString: (JOYAxisUsage) usage
{
if (usage < JOYAxisUsageNonGenericMax) {
return (NSString *[]) {
return inline_const(NSString *[], {
@"None",
@"Analog L1",
@"Analog L2",
@ -26,7 +26,7 @@
@"Throttle",
@"Accelerator",
@"Brake",
}[usage];
})[usage];
}
if (usage >= JOYAxisUsageGeneric0) {
return [NSString stringWithFormat:@"Generic Analog Control %d", usage - JOYAxisUsageGeneric0];

View File

@ -15,7 +15,7 @@
+ (NSString *)usageToString: (JOYButtonUsage) usage
{
if (usage < JOYButtonUsageNonGenericMax) {
return (NSString *[]) {
return inline_const(NSString *[], {
@"None",
@"A",
@"B",
@ -39,7 +39,7 @@
@"D-Pad Right",
@"D-Pad Up",
@"D-Pad Down",
}[usage];
})[usage];
}
if (usage >= JOYButtonUsageGeneric0) {
return [NSString stringWithFormat:@"Generic Button %d", usage - JOYButtonUsageGeneric0];

View File

@ -587,8 +587,8 @@ typedef union {
}
if (_isSwitch) {
[self sendReport:[NSData dataWithBytes:(uint8_t[]){0x80, 0x04} length:2]];
[self sendReport:[NSData dataWithBytes:(uint8_t[]){0x80, 0x02} length:2]];
[self sendReport:[NSData dataWithBytes:inline_const(uint8_t[], {0x80, 0x04}) length:2]];
[self sendReport:[NSData dataWithBytes:inline_const(uint8_t[], {0x80, 0x02}) length:2]];
_lastVendorSpecificOutput.switchPacket.reportID = 0x1; // Rumble and LEDs
_lastVendorSpecificOutput.switchPacket.sequence++;

View File

@ -1,6 +1,8 @@
#import <Foundation/Foundation.h>
#import <IOKit/hid/IOHIDLib.h>
#define inline_const(type, ...) (*({static const typeof(type) _= __VA_ARGS__; &_;}))
@interface JOYElement : NSObject<NSCopying>
- (instancetype)initWithElement:(IOHIDElementRef)element;
- (int32_t)value;

View File

@ -952,7 +952,7 @@ static void cycle_model_backwards(unsigned index)
static const char *current_model_string(unsigned index)
{
return (const char *[]){"Game Boy", "Game Boy Color", "Game Boy Advance", "Super Game Boy", "Game Boy Pocket"}
return GB_inline_const(const char *[], {"Game Boy", "Game Boy Color", "Game Boy Advance", "Super Game Boy", "Game Boy Pocket"})
[configuration.model];
}
@ -981,14 +981,14 @@ static void cycle_cgb_revision_backwards(unsigned index)
static const char *current_cgb_revision_string(unsigned index)
{
return (const char *[]){
return GB_inline_const(const char *[], {
"CPU CGB 0 (Exp.)",
"CPU CGB A (Exp.)",
"CPU CGB B (Exp.)",
"CPU CGB C (Exp.)",
"CPU CGB D",
"CPU CGB E",
}
})
[configuration.cgb_revision];
}
@ -1013,8 +1013,8 @@ static void cycle_sgb_revision_backwards(unsigned index)
static const char *current_sgb_revision_string(unsigned index)
{
return (const char *[]){"Super Game Boy NTSC", "Super Game Boy PAL", "Super Game Boy 2"}
[configuration.sgb_revision];
return GB_inline_const(const char *[], {"Super Game Boy NTSC", "Super Game Boy PAL", "Super Game Boy 2"})
[configuration.sgb_revision];
}
static const uint32_t rewind_lengths[] = {0, 10, 30, 60, 60 * 2, 60 * 5, 60 * 10};
@ -1154,19 +1154,19 @@ static void enter_emulation_menu(unsigned index)
static const char *current_scaling_mode(unsigned index)
{
return (const char *[]){"Fill Entire Window", "Retain Aspect Ratio", "Retain Integer Factor"}
return GB_inline_const(const char *[], {"Fill Entire Window", "Retain Aspect Ratio", "Retain Integer Factor"})
[configuration.scaling_mode];
}
static const char *current_default_scale(unsigned index)
{
return (const char *[]){"1x", "2x", "3x", "4x", "5x", "6x", "7x", "8x"}
return GB_inline_const(const char *[], {"1x", "2x", "3x", "4x", "5x", "6x", "7x", "8x"})
[configuration.default_scale - 1];
}
const char *current_color_correction_mode(unsigned index)
{
return (const char *[]){"Disabled", "Correct Color Curves", "Modern - Balanced", "Modern - Boost Contrast", "Reduce Contrast", "Harsh Reality", "Modern - Accurate"}
return GB_inline_const(const char *[], {"Disabled", "Correct Color Curves", "Modern - Balanced", "Modern - Boost Contrast", "Reduce Contrast", "Harsh Reality", "Modern - Accurate"})
[configuration.color_correction_mode];
}
@ -1184,13 +1184,13 @@ const char *current_palette(unsigned index)
if (configuration.dmg_palette == 4) {
return configuration.dmg_palette_name;
}
return (const char *[]){"Greyscale", "Lime (Game Boy)", "Olive (Pocket)", "Teal (Light)"}
return GB_inline_const(const char *[], {"Greyscale", "Lime (Game Boy)", "Olive (Pocket)", "Teal (Light)"})
[configuration.dmg_palette];
}
const char *current_border_mode(unsigned index)
{
return (const char *[]){"SGB Only", "Never", "Always"}
return GB_inline_const(const char *[], {"SGB Only", "Never", "Always"})
[configuration.border_mode];
}
@ -1538,8 +1538,8 @@ static void cycle_blending_mode_backwards(unsigned index)
static const char *blending_mode_string(unsigned index)
{
if (!uses_gl()) return "Requires OpenGL 3.2+";
return (const char *[]){"Disabled", "Simple", "Accurate"}
[configuration.blending_mode];
return GB_inline_const(const char *[], {"Disabled", "Simple", "Accurate"})
[configuration.blending_mode];
}
static void toggle_osd(unsigned index)
@ -1577,7 +1577,7 @@ static void enter_graphics_menu(unsigned index)
static const char *highpass_filter_string(unsigned index)
{
return (const char *[]){"None (Keep DC Offset)", "Accurate", "Preserve Waveform"}
return GB_inline_const(const char *[], {"None (Keep DC Offset)", "Accurate", "Preserve Waveform"})
[configuration.highpass_mode];
}
@ -1891,8 +1891,8 @@ static void cycle_rumble_mode_backwards(unsigned index)
static const char *current_rumble_mode(unsigned index)
{
return (const char *[]){"Disabled", "Rumble Game Paks Only", "All Games"}
[configuration.rumble_mode];
return GB_inline_const(const char *[], {"Disabled", "Rumble Game Paks Only", "All Games"})
[configuration.rumble_mode];
}
static void toggle_allow_background_controllers(unsigned index)
@ -1930,7 +1930,7 @@ static void cycle_hotkey_backwards(unsigned index)
static const char *current_hotkey(unsigned index)
{
return (const char *[]){
return GB_inline_const(const char *[], {
"None",
"Toggle Pause",
"Toggle Mute",
@ -1956,8 +1956,7 @@ static const char *current_hotkey(unsigned index)
"Load State Slot 9",
"Save State Slot 10",
"Load State Slot 10",
}
[configuration.hotkey_actions[index - 2]];
}) [configuration.hotkey_actions[index - 2]];
}
static const struct menu_item joypad_menu[] = {
@ -2721,8 +2720,7 @@ void run_gui(bool is_running)
joypad_configuration_progress != JOYPAD_BUTTONS_MAX ? "Press button for" : "Move the Analog Stick",
gui_palette_native[3], gui_palette_native[0], STYLE_CENTER);
draw_styled_text(pixels, width, height, 80 + y_offset,
(const char *[])
{
GB_inline_const(const char *[], {
"Right",
"Left",
"Up",
@ -2738,8 +2736,8 @@ void run_gui(bool is_running)
"Hotkey 1",
"Hotkey 2",
"",
} [joypad_configuration_progress],
gui_palette_native[3], gui_palette_native[0], STYLE_CENTER);
}) [joypad_configuration_progress],
gui_palette_native[3], gui_palette_native[0], STYLE_CENTER);
draw_styled_text(pixels, width, height, 104 + y_offset, "Press Enter to skip", gui_palette_native[3], gui_palette_native[0], STYLE_CENTER);
break;
case TEXT_INPUT:

View File

@ -247,7 +247,7 @@ static NSString const *typeLightTemp = @"typeLightTemp";
@{@"type": typeRadio, @"pref": @"GBColorCorrection", @"title": @"Harsh Reality (Low Contrast)", @"value": @(GB_COLOR_CORRECTION_LOW_CONTRAST),},
],
@"footer": ^NSString *(){
return (NSString * const[]){
return GB_inline_const(NSString *[], {
[GB_COLOR_CORRECTION_DISABLED] = @"Colors are directly interpreted as sRGB, resulting in unbalanced colors and inaccurate hues.",
[GB_COLOR_CORRECTION_CORRECT_CURVES] = @"Colors have their brightness corrected, but hues remain unbalanced.",
[GB_COLOR_CORRECTION_MODERN_BALANCED] = @"Emulates a modern display. Blue contrast is moderately enhanced at the cost of slight hue inaccuracy.",
@ -255,7 +255,7 @@ static NSString const *typeLightTemp = @"typeLightTemp";
[GB_COLOR_CORRECTION_REDUCE_CONTRAST] = @"Slightly reduce the contrast to better represent the tint and contrast of the original display.",
[GB_COLOR_CORRECTION_LOW_CONTRAST] = @"Harshly reduce the contrast to accurately represent the tint and low constrast of the original display.",
[GB_COLOR_CORRECTION_MODERN_ACCURATE] = @"Emulates a modern display. Colors have their hues and brightness corrected.",
}[MIN(GB_COLOR_CORRECTION_MODERN_ACCURATE, [[NSUserDefaults standardUserDefaults] integerForKey:@"GBColorCorrection"])];
})[MIN(GB_COLOR_CORRECTION_MODERN_ACCURATE, [[NSUserDefaults standardUserDefaults] integerForKey:@"GBColorCorrection"])];
},
},
@{
@ -291,11 +291,11 @@ static NSString const *typeLightTemp = @"typeLightTemp";
@{@"type": typeRadio, @"pref": @"GBHighpassFilter", @"title": @"Preserve Waveform", @"value": @(GB_HIGHPASS_REMOVE_DC_OFFSET),},
],
@"footer": ^NSString *(){
return (NSString * const[]){
return GB_inline_const(NSString *[], {
[GB_HIGHPASS_OFF] = @"No high-pass filter will be applied. DC offset will be kept, pausing and resuming will trigger audio pops.",
[GB_HIGHPASS_ACCURATE] = @"An accurate high-pass filter will be applied, removing the DC offset while somewhat attenuating the bass.",
[GB_HIGHPASS_REMOVE_DC_OFFSET] = @"A high-pass filter will be applied to the DC offset itself, removing the DC offset while preserving the waveform.",
}[MIN(GB_HIGHPASS_REMOVE_DC_OFFSET, [[NSUserDefaults standardUserDefaults] integerForKey:@"GBHighpassFilter"])];
})[MIN(GB_HIGHPASS_REMOVE_DC_OFFSET, [[NSUserDefaults standardUserDefaults] integerForKey:@"GBHighpassFilter"])];
},
},
@{