Allow setting a non-default audio driver, fixes #466
This commit is contained in:
parent
d9b8e829a5
commit
88f5b22bf6
28
SDL/audio.c
28
SDL/audio.c
@ -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;
|
||||
}
|
||||
|
@ -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
49
SDL/configuration.c
Normal 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
103
SDL/configuration.h
Normal 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
122
SDL/gui.c
@ -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;
|
||||
|
96
SDL/gui.h
96
SDL/gui.h
@ -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);
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user