Allow setting a non-default audio driver, fixes #466

This commit is contained in:
Lior Halphon 2022-07-08 17:51:42 +03:00
parent d9b8e829a5
commit 88f5b22bf6
7 changed files with 254 additions and 146 deletions

View File

@ -2,6 +2,7 @@
#include <stddef.h>
#include <Core/gb.h>
#include "audio/audio.h"
#include "configuration.h"
#define unlikely(x) __builtin_expect((bool)(x), 0)
@ -17,6 +18,18 @@ bool GB_audio_init(void)
GB_AUDIO_DRIVER_REF(SDL),
};
// First try the preferred driver
for (unsigned i = 0; i < sizeof(drivers) / sizeof(drivers[0]); i++) {
driver = drivers[i];
if (strcmp(driver->name, configuration.audio_driver) != 0) {
continue;
}
if (driver->audio_init()) {
return true;
}
}
// Else go by priority
for (unsigned i = 0; i < sizeof(drivers) / sizeof(drivers[0]); i++) {
driver = drivers[i];
if (driver->audio_init()) {
@ -69,3 +82,18 @@ const char *GB_audio_driver_name(void)
if (unlikely(!driver)) return "None";
return driver->name;
}
const char *GB_audio_driver_name_at_index(unsigned index)
{
const GB_audio_driver_t *drivers[] = {
#ifdef _WIN32
GB_AUDIO_DRIVER_REF(XAudio2),
GB_AUDIO_DRIVER_REF(XAudio2_7),
#endif
GB_AUDIO_DRIVER_REF(SDL),
};
if (index >= sizeof(drivers) / sizeof(drivers[0])) {
return "";
}
return drivers[index]->name;
}

View File

@ -13,6 +13,7 @@ size_t GB_audio_get_queue_length(void);
void GB_audio_queue_sample(GB_sample_t *sample);
bool GB_audio_init(void);
const char *GB_audio_driver_name(void);
const char *GB_audio_driver_name_at_index(unsigned index);
typedef struct {
typeof(GB_audio_is_playing) *audio_is_playing;

49
SDL/configuration.c Normal file
View File

@ -0,0 +1,49 @@
#include "configuration.h"
configuration_t configuration =
{
.keys = {
SDL_SCANCODE_RIGHT,
SDL_SCANCODE_LEFT,
SDL_SCANCODE_UP,
SDL_SCANCODE_DOWN,
SDL_SCANCODE_X,
SDL_SCANCODE_Z,
SDL_SCANCODE_BACKSPACE,
SDL_SCANCODE_RETURN,
SDL_SCANCODE_SPACE
},
.keys_2 = {
SDL_SCANCODE_TAB,
SDL_SCANCODE_LSHIFT,
},
.joypad_configuration = {
13,
14,
11,
12,
0,
1,
9,
8,
10,
4,
-1,
5,
},
.joypad_axises = {
0,
1,
},
.color_correction_mode = GB_COLOR_CORRECTION_EMULATE_HARDWARE,
.highpass_mode = GB_HIGHPASS_ACCURATE,
.scaling_mode = GB_SDL_SCALING_INTEGER_FACTOR,
.blending_mode = GB_FRAME_BLENDING_MODE_ACCURATE,
.rewind_length = 60 * 2,
.model = MODEL_CGB,
.volume = 100,
.rumble_mode = GB_RUMBLE_ALL_GAMES,
.default_scale = 2,
.color_temperature = 10,
.cgb_revision = GB_MODEL_CGB_E - GB_MODEL_CGB_0,
};

103
SDL/configuration.h Normal file
View File

@ -0,0 +1,103 @@
#ifndef configuration_h
#define configuration_h
#include <SDL.h>
#include <Core/gb.h>
#include "shader.h"
enum scaling_mode {
GB_SDL_SCALING_ENTIRE_WINDOW,
GB_SDL_SCALING_KEEP_RATIO,
GB_SDL_SCALING_INTEGER_FACTOR,
GB_SDL_SCALING_MAX,
};
typedef enum {
JOYPAD_BUTTON_RIGHT,
JOYPAD_BUTTON_LEFT,
JOYPAD_BUTTON_UP,
JOYPAD_BUTTON_DOWN,
JOYPAD_BUTTON_A,
JOYPAD_BUTTON_B,
JOYPAD_BUTTON_SELECT,
JOYPAD_BUTTON_START,
JOYPAD_BUTTON_MENU,
JOYPAD_BUTTON_TURBO,
JOYPAD_BUTTON_REWIND,
JOYPAD_BUTTON_SLOW_MOTION,
JOYPAD_BUTTONS_MAX
} joypad_button_t;
typedef enum {
JOYPAD_AXISES_X,
JOYPAD_AXISES_Y,
JOYPAD_AXISES_MAX
} joypad_axis_t;
typedef struct {
SDL_Scancode keys[9];
GB_color_correction_mode_t color_correction_mode;
enum scaling_mode scaling_mode;
uint8_t blending_mode;
GB_highpass_mode_t highpass_mode;
bool _deprecated_div_joystick;
bool _deprecated_flip_joystick_bit_1;
bool _deprecated_swap_joysticks_bits_1_and_2;
char filter[32];
enum {
MODEL_DMG,
MODEL_CGB,
MODEL_AGB,
MODEL_SGB,
MODEL_MGB,
MODEL_MAX,
} model;
/* v0.11 */
uint32_t rewind_length;
SDL_Scancode keys_2[32]; /* Rewind and underclock, + padding for the future */
uint8_t joypad_configuration[32]; /* 12 Keys + padding for the future*/;
uint8_t joypad_axises[JOYPAD_AXISES_MAX];
/* v0.12 */
enum {
SGB_NTSC,
SGB_PAL,
SGB_2,
SGB_MAX
} sgb_revision;
/* v0.13 */
uint8_t dmg_palette;
GB_border_mode_t border_mode;
uint8_t volume;
GB_rumble_mode_t rumble_mode;
uint8_t default_scale;
/* v0.14 */
unsigned padding;
uint8_t color_temperature;
char bootrom_path[4096];
uint8_t interference_volume;
GB_rtc_mode_t rtc_mode;
/* v0.14.4 */
bool osd;
struct __attribute__((packed, aligned(4))) {
/* v0.15 */
bool allow_mouse_controls;
uint8_t cgb_revision;
/* v0.15.1 */
char audio_driver[16];
};
} configuration_t;
extern configuration_t configuration;
#endif

122
SDL/gui.c
View File

@ -68,55 +68,6 @@ void render_texture(void *pixels, void *previous)
}
}
configuration_t configuration =
{
.keys = {
SDL_SCANCODE_RIGHT,
SDL_SCANCODE_LEFT,
SDL_SCANCODE_UP,
SDL_SCANCODE_DOWN,
SDL_SCANCODE_X,
SDL_SCANCODE_Z,
SDL_SCANCODE_BACKSPACE,
SDL_SCANCODE_RETURN,
SDL_SCANCODE_SPACE
},
.keys_2 = {
SDL_SCANCODE_TAB,
SDL_SCANCODE_LSHIFT,
},
.joypad_configuration = {
13,
14,
11,
12,
0,
1,
9,
8,
10,
4,
-1,
5,
},
.joypad_axises = {
0,
1,
},
.color_correction_mode = GB_COLOR_CORRECTION_EMULATE_HARDWARE,
.highpass_mode = GB_HIGHPASS_ACCURATE,
.scaling_mode = GB_SDL_SCALING_INTEGER_FACTOR,
.blending_mode = GB_FRAME_BLENDING_MODE_ACCURATE,
.rewind_length = 60 * 2,
.model = MODEL_CGB,
.volume = 100,
.rumble_mode = GB_RUMBLE_ALL_GAMES,
.default_scale = 2,
.color_temperature = 10,
.cgb_revision = GB_MODEL_CGB_E - GB_MODEL_CGB_0,
};
static const char *help[] = {
"Drop a ROM to play.\n"
"\n"
@ -961,17 +912,86 @@ static const char *audio_driver_string(unsigned index)
return GB_audio_driver_name();
}
static const char *preferred_audio_driver_string(unsigned index)
{
if (configuration.audio_driver[0] == 0) {
return "Auto";
}
return configuration.audio_driver;
}
static void audio_driver_changed(void);
static void cycle_prefrered_audio_driver(unsigned index)
{
audio_driver_changed();
if (configuration.audio_driver[0] == 0) {
strcpy(configuration.audio_driver, GB_audio_driver_name_at_index(0));
return;
}
unsigned i = 0;
while (true) {
const char *name = GB_audio_driver_name_at_index(i);
if (name[0] == 0) { // Not a supported driver? Switch to auto
configuration.audio_driver[0] = 0;
return;
}
if (strcmp(configuration.audio_driver, name) == 0) {
strcpy(configuration.audio_driver, GB_audio_driver_name_at_index(i + 1));
return;
}
i++;
}
}
static void cycle_preferred_audio_driver_backwards(unsigned index)
{
audio_driver_changed();
if (configuration.audio_driver[0] == 0) {
unsigned i = 0;
while (true) {
const char *name = GB_audio_driver_name_at_index(i);
if (name[0] == 0) {
strcpy(configuration.audio_driver, GB_audio_driver_name_at_index(i - 1));
return;
}
i++;
}
return;
}
unsigned i = 0;
while (true) {
const char *name = GB_audio_driver_name_at_index(i);
if (name[0] == 0) { // Not a supported driver? Switch to auto
configuration.audio_driver[0] = 0;
return;
}
if (strcmp(configuration.audio_driver, name) == 0) {
strcpy(configuration.audio_driver, GB_audio_driver_name_at_index(i - 1));
return;
}
i++;
}
}
static void nop(unsigned index){}
static const struct menu_item audio_menu[] = {
static struct menu_item audio_menu[] = {
{"Highpass Filter:", cycle_highpass_filter, highpass_filter_string, cycle_highpass_filter_backwards},
{"Volume:", increase_volume, volume_string, decrease_volume},
{"Interference Volume:", increase_interference_volume, interference_volume_string, decrease_interference_volume},
{"Audio Driver:", nop, audio_driver_string},
{"Preferred Audio Driver:", cycle_prefrered_audio_driver, preferred_audio_driver_string, cycle_preferred_audio_driver_backwards},
{"Active Driver:", nop, audio_driver_string},
{"Back", return_to_root_menu},
{NULL,}
};
static void audio_driver_changed(void)
{
audio_menu[4].value_getter = NULL;
audio_menu[4].string = "Relaunch to apply";
}
static void enter_audio_menu(unsigned index)
{
current_menu = audio_menu;

View File

@ -5,6 +5,7 @@
#include <Core/gb.h>
#include <stdbool.h>
#include "shader.h"
#include "configuration.h"
#define JOYSTICK_HIGH 0x4000
#define JOYSTICK_LOW 0x3800
@ -24,14 +25,6 @@ extern SDL_PixelFormat *pixel_format;
extern SDL_Haptic *haptic;
extern shader_t shader;
enum scaling_mode {
GB_SDL_SCALING_ENTIRE_WINDOW,
GB_SDL_SCALING_KEEP_RATIO,
GB_SDL_SCALING_INTEGER_FACTOR,
GB_SDL_SCALING_MAX,
};
enum pending_command {
GB_SDL_NO_COMMAND,
GB_SDL_SAVE_STATE_COMMAND,
@ -48,93 +41,6 @@ extern enum pending_command pending_command;
extern unsigned command_parameter;
extern char *dropped_state_file;
typedef enum {
JOYPAD_BUTTON_RIGHT,
JOYPAD_BUTTON_LEFT,
JOYPAD_BUTTON_UP,
JOYPAD_BUTTON_DOWN,
JOYPAD_BUTTON_A,
JOYPAD_BUTTON_B,
JOYPAD_BUTTON_SELECT,
JOYPAD_BUTTON_START,
JOYPAD_BUTTON_MENU,
JOYPAD_BUTTON_TURBO,
JOYPAD_BUTTON_REWIND,
JOYPAD_BUTTON_SLOW_MOTION,
JOYPAD_BUTTONS_MAX
} joypad_button_t;
typedef enum {
JOYPAD_AXISES_X,
JOYPAD_AXISES_Y,
JOYPAD_AXISES_MAX
} joypad_axis_t;
typedef struct {
SDL_Scancode keys[9];
GB_color_correction_mode_t color_correction_mode;
enum scaling_mode scaling_mode;
uint8_t blending_mode;
GB_highpass_mode_t highpass_mode;
bool _deprecated_div_joystick;
bool _deprecated_flip_joystick_bit_1;
bool _deprecated_swap_joysticks_bits_1_and_2;
char filter[32];
enum {
MODEL_DMG,
MODEL_CGB,
MODEL_AGB,
MODEL_SGB,
MODEL_MGB,
MODEL_MAX,
} model;
/* v0.11 */
uint32_t rewind_length;
SDL_Scancode keys_2[32]; /* Rewind and underclock, + padding for the future */
uint8_t joypad_configuration[32]; /* 12 Keys + padding for the future*/;
uint8_t joypad_axises[JOYPAD_AXISES_MAX];
/* v0.12 */
enum {
SGB_NTSC,
SGB_PAL,
SGB_2,
SGB_MAX
} sgb_revision;
/* v0.13 */
uint8_t dmg_palette;
GB_border_mode_t border_mode;
uint8_t volume;
GB_rumble_mode_t rumble_mode;
uint8_t default_scale;
/* v0.14 */
unsigned padding;
uint8_t color_temperature;
char bootrom_path[4096];
uint8_t interference_volume;
GB_rtc_mode_t rtc_mode;
/* v0.14.4 */
bool osd;
struct __attribute__((packed, aligned(4))) {
/* v0.15 */
bool allow_mouse_controls;
uint8_t cgb_revision;
};
} configuration_t;
extern configuration_t configuration;
void update_viewport(void);
void run_gui(bool is_running);
void render_texture(void *pixels, void *previous);

View File

@ -870,6 +870,7 @@ int main(int argc, char **argv)
configuration.color_temperature %= 21;
configuration.bootrom_path[sizeof(configuration.bootrom_path) - 1] = 0;
configuration.cgb_revision %= GB_MODEL_CGB_E - GB_MODEL_CGB_0 + 1;
configuration.audio_driver[15] = 0;
}
if (configuration.model >= MODEL_MAX) {