From e1cf3464939b71f5923d95722289a7d74a9cc005 Mon Sep 17 00:00:00 2001 From: "fabio.olimpieri" Date: Thu, 29 Mar 2012 07:49:31 +0000 Subject: [PATCH] Added ZIP, DMS and floppy sound support --- Makefile.wii | 4 +- src/audio.c | 3 +- src/driveclick.c | 150 +++++++++++--- src/gui-sdl/gui-sdl.c | 51 +++-- src/gui-sdl/menu.c | 14 +- src/jd-sdl/joystick.c | 4 +- src/sd-sdl/sound.c | 458 +++++++++++++++++++++--------------------- src/sd-sdl/sound.h | 3 + uaerc.wii | 8 + 9 files changed, 418 insertions(+), 277 deletions(-) diff --git a/Makefile.wii b/Makefile.wii index 841433b..1d437d6 100644 --- a/Makefile.wii +++ b/Makefile.wii @@ -56,6 +56,7 @@ src/tools/genlinetoscr.exe: clean: @echo Cleaning $(OBJ_DIR) @rm -rf $(OBJS) $(OBJ_DIR) src/machdep src/target.h src/md-fpp.h src/sysconfig.h $(SYMLINKS) + @rm -rf dist @rm -f src/blit.h src/blitfunc.c src/blitfunc.h src/blittable.c src/linetoscr.c @rm -f uae.dol uae.elf cd src/tools/ && make -f Makefile.wii clean @@ -143,7 +144,7 @@ COMMON_FLAGS := -g -O3 -G8 -mrvl -Wall -D__inline__=__inline__ $(MACHDEP) -Wno-u INCLUDES := -Isrc/md-generic/ -Isrc/include -Isrc -I$(DEVKITPRO)/libogc/include -I$(DEVKITPRO)/libogc/include/SDL -I$(PORTLIBS)/include DEFINES := -DOS_WITHOUT_MEMORY_MANAGEMENT -DSAVESTATE -DUSE_SDL -DSUPPORT_THREADS -DCPUEMU_0 -DCPUEMU_5 -DCPUEMU_6 \ -DFPUEMU -DAGA -DAUTOCONFIG -DFILESYS \ - -DTD_START_HEIGHT=16 + -DTD_START_HEIGHT=16 -DDRIVESOUND CFLAGS := $(COMMON_FLAGS) $(INCLUDES) $(DEFINES) #unused defines; -DFDI2RAW @@ -181,6 +182,7 @@ distsource: cd .. && cp -r uae-wii uae-wii-v cd ../uae-wii-v && find . -name ".svn" | xargs rm -rf cd .. && tar -czf uae-wii-v.tar.gz uae-wii-v + cd .. && rm -fr uae-wii-v #--------------------------------------------------------------------------------- diff --git a/src/audio.c b/src/audio.c index 89f94d8..637a589 100644 --- a/src/audio.c +++ b/src/audio.c @@ -21,17 +21,18 @@ #include "custom_private.h" #include "newcpu.h" #include "gensound.h" +#include "driveclick.h" #include "sounddep/sound.h" #include "events.h" #include "audio.h" #include "savestate.h" -#include "driveclick.h" #ifdef AVIOUTPUT # include "avioutput.h" #endif #include "sinctable.h" #include "gui.h" /* for gui_ledstate */ + #define MAX_EV ~0ul //#define DEBUG_AUDIO #define DEBUG_CHANNEL_MASK 15 diff --git a/src/driveclick.c b/src/driveclick.c index 7d8a571..55f8eeb 100644 --- a/src/driveclick.c +++ b/src/driveclick.c @@ -13,14 +13,21 @@ #include "uae.h" #include "options.h" +#include "driveclick.h" #include "sounddep/sound.h" #include "zfile.h" #include "events.h" -#include "driveclick.h" #include "fsdb.h" +#include "resource/drive_click.c" +#include "resource/drive_snatch.c" +#include "resource/drive_spin.c" +#include "resource/drive_startup.c" + + + static struct drvsample drvs[4][DS_END]; static int freq = 44100; @@ -51,7 +58,18 @@ uae_s16 *decodewav (uae_u8 *s, int *lenp) s += 4; len = s[0] | (s[1] << 8) | (s[2] << 16) | (s[3] << 24); dst = xmalloc (len); +#ifdef WORDS_BIGENDIAN + { + int i; + uae_u8* d = (uae_u8*) dst; + for (i = 0; i < len; i+= 2) { + d[i] = s[i + 5]; + d[i+1] = s[i + 4]; + } + } +#else memcpy (dst, s + 4, len); +#endif *lenp = len / 2; return dst; } @@ -65,24 +83,77 @@ static int loadsample (const char *path, struct drvsample *ds) struct zfile *f; uae_u8 *buf; int size; + int i; f = zfile_fopen (path, "rb"); if (!f) { write_log ("driveclick: can't open '%s'\n", path); return 0; } + // ("driveclick: loading '%s'\n", path); zfile_fseek (f, 0, SEEK_END); size = zfile_ftell (f); buf = malloc (size); zfile_fseek (f, 0, SEEK_SET); zfile_fread (buf, size, 1, f); zfile_fclose (f); + + /* + printf("size=%i \n", size); + for (i = 0; i < size; i++) { + printf("0x%02x,", buf[i]); + if (i % 20 == 19) { + printf("\n"); + } + } + printf("\n"); + flush(NULL); + } + */ + ds->len = size; ds->p = decodewav (buf, &ds->len); + free (buf); return 1; } +//The same function as load sample, but the wav data is already in memory. +//No read, just decode. +static int loadsample_resource(int resId, struct drvsample *ds) { + uae_u8* buf = NULL; + int size; + switch (resId) { + case DS_CLICK: { + buf = res_drive_click; + size = res_drive_click_size; + } break; + case DS_SPIN : + case DS_SPINND: { + buf = res_drive_spin; + size = res_drive_spin_size; + } break; + case DS_START: { + buf = res_drive_startup; + size = res_drive_startup_size; + } break; + case DS_SNATCH: { + buf = res_drive_snatch; + size = res_drive_snatch_size; + } break; + + default: return 0; + } //end of switch + + + //write_log("loading click resource %i \n", resId); + ds->len = size; + ds->p = decodewav (buf, &ds->len); + + return 1; + +} + static void freesample (struct drvsample *s) { free (s->p); @@ -94,47 +165,72 @@ extern char *start_path; void driveclick_init (void) { int v, vv, i, j; - char tmp[1000]; + static char tmp_path[1024]; driveclick_free (); vv = 0; + + write_log("driveclick init...\n"); + for (i = 0; i < 4; i++) { if (currprefs.dfxclick[i]) { /* TODO: Implement location of sample data */ -#if 0 - if (currprefs.dfxclick[i] > 0) { - v = 0; - if (driveclick_loadresource (drvs[i], currprefs.dfxclick[i])) - v = 3; - } else if (currprefs.dfxclick[i] == -1) { - sprintf (tmp, "%suae_data%cdrive_click_%s", start_path, FSDB_DIR_SEPARATOR, currprefs.dfxclickexternal[i]); - v = loadsample (tmp, &drvs[i][DS_CLICK]); - sprintf (tmp, "%suae_data%cdrive_spin_%s", start_path, FSDB_DIR_SEPARATOR, currprefs.dfxclickexternal[i]); - v += loadsample (tmp, &drvs[i][DS_SPIN]); - sprintf (tmp, "%suae_data%cdrive_spinnd_%s", start_path, FSDB_DIR_SEPARATOR, currprefs.dfxclickexternal[i]); - v += loadsample (tmp, &drvs[i][DS_SPINND]); - sprintf (tmp, "%suae_data%cdrive_startup_%s", start_path, FSDB_DIR_SEPARATOR, currprefs.dfxclickexternal[i]); - v += loadsample (tmp, &drvs[i][DS_START]); - sprintf (tmp, "%suae_data%cdrive_snatch_%s", start_path, FSDB_DIR_SEPARATOR, currprefs.dfxclickexternal[i]); - v += loadsample (tmp, &drvs[i][DS_SNATCH]); + //load from resource + if (currprefs.dfxclick[i] > 0) { // > 0 + v = loadsample_resource(DS_CLICK, &drvs[i][DS_CLICK]); + v += loadsample_resource(DS_SPIN, &drvs[i][DS_SPIN]); + v += loadsample_resource(DS_SPINND, &drvs[i][DS_SPINND]); + v += loadsample_resource(DS_SNATCH, &drvs[i][DS_SNATCH]); + v += loadsample_resource(DS_START, &drvs[i][DS_START]); + + } else + //load from file + if (currprefs.dfxclick[i] == -1) { +#ifdef GEKKO //currprefs.dfxclickexternal[i] is the path to the wav directory (path contains trailing separator) + sprintf (tmp_path, "%sdrive_click.wav", currprefs.dfxclickexternal[i]); + v = loadsample (tmp_path, &drvs[i][DS_CLICK]); + sprintf (tmp_path, "%sdrive_spin.wav", currprefs.dfxclickexternal[i]); + v += loadsample (tmp_path, &drvs[i][DS_SPIN]); + sprintf (tmp_path, "%sdrive_spinnd.wav", currprefs.dfxclickexternal[i]); + v += loadsample (tmp_path, &drvs[i][DS_SPINND]); + sprintf (tmp_path, "%sdrive_startup.wav", currprefs.dfxclickexternal[i]); + v += loadsample (tmp_path, &drvs[i][DS_START]); + sprintf (tmp_path, "%sdrive_snatch.wav", currprefs.dfxclickexternal[i]); + v += loadsample (tmp_path, &drvs[i][DS_SNATCH]); +#else + char * start_path = "."; //TODO - ??? set correct path + sprintf (tmp_path, "%suae_data%cdrive_click_%s", start_path, FSDB_DIR_SEPARATOR, currprefs.dfxclickexternal[i]); + v = loadsample (tmp_path, &drvs[i][DS_CLICK]); + sprintf (tmp_path, "%suae_data%cdrive_spin_%s", start_path, FSDB_DIR_SEPARATOR, currprefs.dfxclickexternal[i]); + v += loadsample (tmp_path, &drvs[i][DS_SPIN]); + sprintf (tmp_path, "%suae_data%cdrive_spinnd_%s", start_path, FSDB_DIR_SEPARATOR, currprefs.dfxclickexternal[i]); + v += loadsample (tmp_path, &drvs[i][DS_SPINND]); + sprintf (tmp_path, "%suae_data%cdrive_startup_%s", start_path, FSDB_DIR_SEPARATOR, currprefs.dfxclickexternal[i]); + v += loadsample (tmp_path, &drvs[i][DS_START]); + sprintf (tmp_path, "%suae_data%cdrive_snatch_%s", start_path, FSDB_DIR_SEPARATOR, currprefs.dfxclickexternal[i]); + v += loadsample (tmp_path, &drvs[i][DS_SNATCH]); +#endif /* GEKKO */ } if (v == 0) { - int j; - for (j = 0; j < DS_END; j++) - freesample (&drvs[i][j]); - currprefs.dfxclick[i] = changed_prefs.dfxclick[i] = 0; + int j; + for (j = 0; j < DS_END; j++) { + freesample (&drvs[i][j]); + } + currprefs.dfxclick[i] = changed_prefs.dfxclick[i] = 0; } - for (j = 0; j < DS_END; j++) - drvs[i][j].len <<= DS_SHIFT; + for (j = 0; j < DS_END; j++) { + drvs[i][j].len <<= DS_SHIFT; + } drvs[i][DS_CLICK].pos = drvs[i][DS_CLICK].len; drvs[i][DS_SNATCH].pos = drvs[i][DS_SNATCH].len; vv += currprefs.dfxclick[i]; -#endif + } } if (vv > 0) { - driveclick_reset (); - click_initialized = 1; + write_log("reset driveclick \n"); + driveclick_reset (); + click_initialized = 1; } } diff --git a/src/gui-sdl/gui-sdl.c b/src/gui-sdl/gui-sdl.c index b0b1b57..a314c8e 100644 --- a/src/gui-sdl/gui-sdl.c +++ b/src/gui-sdl/gui-sdl.c @@ -149,18 +149,16 @@ static const char *graphic_messages[] = { /*00*/ "Correct aspect", /*01*/ "^|off|100%|95%|93%|90%|custom", - /*02*/ " ", - /*03*/ "Scanlines", - /*04*/ "^|on|off", - /*05*/ " ", - /*06*/ "Leds", + /*02*/ "Scanlines", + /*03*/ "^|on|off", + /*04*/ "Leds", + /*05*/ "^|on|off", + /*06*/ "Floppy sound", /*07*/ "^|on|off", - /*08*/ " ", - /*09*/ "Port", - /*10*/ "^|SD|USB|SMB", - /*11*/ " ", - /*12*/ "Rumble", - /*13*/ "^|on|off", + /*08*/ "Port", + /*09*/ "^|SD|USB|SMB", + /*10*/ "Rumble", + /*11*/ "^|on|off", NULL }; @@ -538,6 +536,25 @@ cfgfile_save(&changed_prefs, user_options, 0); msgInfo("Configurations saved",3000,NULL); } +int get_dfxclick(void) +{ + int sounddf_on = 0; + int i; + + for (i=0; i < 4; i++) + if (changed_prefs.dfxclick[i]&&(changed_prefs.dfxtype[i]>=0)) sounddf_on =1; + + return sounddf_on; +} + +void set_dfxclick(int sounddf_on) +{ + int i; + for (i=0; i < 4; i++) + if ((changed_prefs.dfxtype[i]>=0)&&(changed_prefs.dfxclick[i]!=sounddf_on)) + changed_prefs.dfxclick[i] = sounddf_on; +} + static void emulation_options(void) { int submenus[7]; @@ -571,7 +588,7 @@ static void emulation_options(void) static void graphic_options(void) { - int submenus[5]; + int submenus[6]; int opt; memset(submenus, 0, sizeof(submenus)); @@ -580,8 +597,9 @@ static void graphic_options(void) submenus[0] = get_gfx_aspect_ratio(); submenus[1] = !(changed_prefs.gfx_linedbl == 2) ; submenus[2] = !changed_prefs.leds_on_screen; - submenus[3] = changed_prefs.Port; - submenus[4] = !changed_prefs.rumble; + submenus[3] = !get_dfxclick(); + submenus[4] = changed_prefs.Port; + submenus[5] = !changed_prefs.rumble; opt = menu_select_title("Other options menu", graphic_messages, submenus); @@ -591,8 +609,9 @@ static void graphic_options(void) set_gfx_aspect_ratio(submenus[0]); changed_prefs.gfx_linedbl = submenus[1] ? 1 : 2; changed_prefs.leds_on_screen = !submenus[2]; - set_Port(submenus[3]); - changed_prefs.rumble = !submenus[4]; + set_dfxclick(!submenus[3]); + set_Port(submenus[4]); + changed_prefs.rumble = !submenus[5]; currprefs.leds_on_screen = changed_prefs.leds_on_screen; currprefs.rumble = changed_prefs.rumble; } diff --git a/src/gui-sdl/menu.c b/src/gui-sdl/menu.c index 8220c68..f046fa2 100644 --- a/src/gui-sdl/menu.c +++ b/src/gui-sdl/menu.c @@ -21,6 +21,14 @@ #include "menu.h" #include "VirtualKeyboard.h" +struct joyinfo { + SDL_Joystick *joy; + unsigned int axles; + unsigned int buttons; +}; + +extern unsigned int nr_joysticks; +extern struct joyinfo joys[]; typedef struct { @@ -269,7 +277,7 @@ static const char **get_file_list(const char *base_dir) { char buf[255]; const char *exts[] = {".adf", ".ADF", ".adz", ".ADZ", ".ipf", ".IPF", ".fdi", ".FDI", - ".sav", ".SAV", ".uss", ".USS", ".rom", ".ROM", NULL}; + ".sav", ".SAV", ".uss", ".USS", ".rom", ".ROM", ".zip",".ZIP",".dms", ".DMS",NULL}; struct stat st; snprintf(buf, 255, "%s/%s", base_dir, de->d_name); @@ -687,8 +695,8 @@ uint32_t menu_wait_key_press(void) static int joy_keys_last; /* Wii-specific, sorry */ - for (nr = 0; nr < SDL_NumJoysticks(); nr++) { - joy = SDL_JoystickOpen(nr); + for (nr = 0; nr < nr_joysticks; nr++) { + joy = joys[nr].joy; if (!joy) continue; diff --git a/src/jd-sdl/joystick.c b/src/jd-sdl/joystick.c index 2bb32a8..98b1955 100644 --- a/src/jd-sdl/joystick.c +++ b/src/jd-sdl/joystick.c @@ -22,7 +22,7 @@ extern int gui_is_active; -static unsigned int nr_joysticks; +unsigned int nr_joysticks; static int initialized; struct joyinfo { @@ -31,7 +31,7 @@ struct joyinfo { unsigned int buttons; }; -static struct joyinfo joys[MAX_INPUT_DEVICES]; +struct joyinfo joys[MAX_INPUT_DEVICES]; //Wiimote Rumble #ifdef GEKKO diff --git a/src/sd-sdl/sound.c b/src/sd-sdl/sound.c index 0298a0f..f5daf60 100644 --- a/src/sd-sdl/sound.c +++ b/src/sd-sdl/sound.c @@ -1,227 +1,231 @@ - /* - * UAE - The Un*x Amiga Emulator - * - * Support for SDL sound - * - * Copyright 1997 Bernd Schmidt - * Copyright 2003-2006 Richard Drummond - */ - -#include "sysconfig.h" -#include "sysdeps.h" - -#include "options.h" -#include "gensound.h" -#include "sounddep/sound.h" -#include "threaddep/thread.h" -#include -#include - -static int have_sound = 0; - -uae_u16 sndbuffer[44100]; -uae_u16 *sndbufpt; -int sndbufsize; -static SDL_AudioSpec spec; - -static smp_comm_pipe to_sound_pipe; -static uae_sem_t data_available_sem, callback_done_sem, sound_init_sem; - -static int in_callback, closing_sound; - -static void clearbuffer (void) -{ - memset (sndbuffer, (spec.format == AUDIO_U8) ? SOUND8_BASE_VAL : SOUND16_BASE_VAL, sizeof (sndbuffer)); -} - -/* This shouldn't be necessary . . . */ -static void dummy_callback (void *userdata, Uint8 *stream, int len) -{ - return; -} - -static void sound_callback (void *userdata, Uint8 *stream, int len) -{ - if (closing_sound) - return; - in_callback = 1; - /* Wait for data to finish. */ - uae_sem_wait (&data_available_sem); - if (! closing_sound) { - memcpy (stream, sndbuffer, sndbufsize); - /* Notify writer that we're done. */ - uae_sem_post (&callback_done_sem); - } - in_callback = 0; -} - -void finish_sound_buffer (void) -{ - uae_sem_post (&data_available_sem); - uae_sem_wait (&callback_done_sem); -} - -/* Try to determine whether sound is available. */ -int setup_sound (void) -{ - int success = 0; - - if (SDL_InitSubSystem (SDL_INIT_AUDIO) == 0) { - spec.freq = currprefs.sound_freq; - spec.format = currprefs.sound_bits == 8 ? AUDIO_U8 : AUDIO_S16SYS; - spec.channels = currprefs.sound_stereo ? 2 : 1; - spec.callback = dummy_callback; - spec.samples = spec.freq * currprefs.sound_latency / 1000; - spec.callback = sound_callback; - spec.userdata = 0; - - if (SDL_OpenAudio (&spec, 0) < 0) { - write_log ("Couldn't open audio: %s\n", SDL_GetError()); - SDL_QuitSubSystem (SDL_INIT_AUDIO); - } else { - success = 1; - SDL_CloseAudio (); - } - } - - sound_available = success; - - return sound_available; -} - -static int open_sound (void) -{ - spec.freq = currprefs.sound_freq; - spec.format = currprefs.sound_bits == 8 ? AUDIO_U8 : AUDIO_S16SYS; - spec.channels = currprefs.sound_stereo ? 2 : 1; - spec.samples = spec.freq * currprefs.sound_latency / 1000; - spec.callback = sound_callback; - spec.userdata = 0; - - clearbuffer(); - if (SDL_OpenAudio (&spec, NULL) < 0) { - write_log ("Couldn't open audio: %s\n", SDL_GetError()); - return 0; - } - - if (spec.format == AUDIO_S16SYS) { - init_sound_table16 (); - sample_handler = currprefs.sound_stereo ? sample16s_handler : sample16_handler; - } else { - init_sound_table8 (); - sample_handler = currprefs.sound_stereo ? sample8s_handler : sample8_handler; - } - have_sound = 1; - - sound_available = 1; - obtainedfreq = currprefs.sound_freq; - sndbufsize = spec.samples * currprefs.sound_bits / 8 * spec.channels; - write_log ("SDL sound driver found and configured for %d bits at %d Hz, buffer is %d ms (%d bytes).\n", - currprefs.sound_bits, spec.freq, spec.samples * 1000 / spec.freq, sndbufsize); - sndbufpt = sndbuffer; - - return 1; -} - -static void *sound_thread (void *dummy) -{ - for (;;) { - int cmd = read_comm_pipe_int_blocking (&to_sound_pipe); - int n; - - switch (cmd) { - case 0: - open_sound (); - uae_sem_post (&sound_init_sem); - break; - case 1: - uae_sem_post (&sound_init_sem); - return 0; - } - } -} - -/* We need a thread for this, since communication between finish_sound_buffer - * and the callback works through semaphores. In theory, this is unnecessary, - * since SDL uses a sound thread internally, and the callback runs in its - * context. But we don't want to depend on SDL's internals too much. */ -static void init_sound_thread (void) -{ - uae_thread_id tid; - - init_comm_pipe (&to_sound_pipe, 20, 1); - uae_sem_init (&data_available_sem, 0, 0); - uae_sem_init (&callback_done_sem, 0, 0); - uae_sem_init (&sound_init_sem, 0, 0); - uae_start_thread (sound_thread, NULL, &tid); -} - -void close_sound (void) -{ - if (! have_sound) - return; - - SDL_PauseAudio (1); - clearbuffer(); - if (in_callback) { - closing_sound = 1; - uae_sem_post (&data_available_sem); - } - write_comm_pipe_int (&to_sound_pipe, 1, 1); - uae_sem_wait (&sound_init_sem); - SDL_CloseAudio (); - uae_sem_destroy (&data_available_sem); - uae_sem_destroy (&sound_init_sem); - uae_sem_destroy (&callback_done_sem); - have_sound = 0; -} - -int init_sound (void) -{ - in_callback = 0; - closing_sound = 0; - - init_sound_thread (); - write_comm_pipe_int (&to_sound_pipe, 0, 1); - uae_sem_wait (&sound_init_sem); - SDL_PauseAudio (0); - - return have_sound; -} - -void pause_sound (void) -{ - SDL_PauseAudio (1); -} - -void resume_sound (void) -{ - clearbuffer(); - SDL_PauseAudio (0); -} - -void reset_sound (void) -{ - clearbuffer(); - return; -} - -void sound_volume (int dir) -{ -} - -/* - * Handle audio specific cfgfile options - */ -void audio_default_options (struct uae_prefs *p) -{ -} - -void audio_save_options (FILE *f, const struct uae_prefs *p) -{ -} - -int audio_parse_option (struct uae_prefs *p, const char *option, const char *value) -{ - return 0; -} + /* + * UAE - The Un*x Amiga Emulator + * + * Support for SDL sound + * + * Copyright 1997 Bernd Schmidt + * Copyright 2003-2006 Richard Drummond + */ + +#include "sysconfig.h" +#include "sysdeps.h" + +#include "options.h" +#include "gensound.h" +#include "sounddep/sound.h" +#include "threaddep/thread.h" +#include +#include + +static int have_sound = 0; + +uae_u16 sndbuffer[44100]; +uae_u16 *sndbufpt; +int sndbufsize; +static SDL_AudioSpec spec; + +static smp_comm_pipe to_sound_pipe; +static uae_sem_t data_available_sem, callback_done_sem, sound_init_sem; + +static int in_callback, closing_sound; + +static void clearbuffer (void) +{ + memset (sndbuffer, (spec.format == AUDIO_U8) ? SOUND8_BASE_VAL : SOUND16_BASE_VAL, sizeof (sndbuffer)); +} + +/* This shouldn't be necessary . . . */ +static void dummy_callback (void *userdata, Uint8 *stream, int len) +{ + return; +} + +static void sound_callback (void *userdata, Uint8 *stream, int len) +{ + if (closing_sound) + return; + in_callback = 1; + /* Wait for data to finish. */ + uae_sem_wait (&data_available_sem); + if (! closing_sound) { + memcpy (stream, sndbuffer, sndbufsize); + /* Notify writer that we're done. */ + uae_sem_post (&callback_done_sem); + } + in_callback = 0; +} + +void finish_sound_buffer (void) +{ + uae_sem_post (&data_available_sem); + uae_sem_wait (&callback_done_sem); +} + +/* Try to determine whether sound is available. */ +int setup_sound (void) +{ + int success = 0; + + if (SDL_InitSubSystem (SDL_INIT_AUDIO) == 0) { + spec.freq = currprefs.sound_freq; + spec.format = currprefs.sound_bits == 8 ? AUDIO_U8 : AUDIO_S16SYS; + spec.channels = currprefs.sound_stereo ? 2 : 1; + spec.callback = dummy_callback; + spec.samples = spec.freq * currprefs.sound_latency / 1000; + spec.callback = sound_callback; + spec.userdata = 0; + + if (SDL_OpenAudio (&spec, 0) < 0) { + write_log ("Couldn't open audio: %s\n", SDL_GetError()); + SDL_QuitSubSystem (SDL_INIT_AUDIO); + } else { + success = 1; + SDL_CloseAudio (); + } + } + + sound_available = success; + + return sound_available; +} + +static int open_sound (void) +{ + spec.freq = currprefs.sound_freq; + spec.format = currprefs.sound_bits == 8 ? AUDIO_U8 : AUDIO_S16SYS; + spec.channels = currprefs.sound_stereo ? 2 : 1; + spec.samples = spec.freq * currprefs.sound_latency / 1000; + spec.callback = sound_callback; + spec.userdata = 0; + + clearbuffer(); + if (SDL_OpenAudio (&spec, NULL) < 0) { + write_log ("Couldn't open audio: %s\n", SDL_GetError()); + return 0; + } + + if (spec.format == AUDIO_S16SYS) { + init_sound_table16 (); + sample_handler = currprefs.sound_stereo ? sample16s_handler : sample16_handler; + } else { + init_sound_table8 (); + sample_handler = currprefs.sound_stereo ? sample8s_handler : sample8_handler; + } + have_sound = 1; + + sound_available = 1; + obtainedfreq = currprefs.sound_freq; + sndbufsize = spec.samples * currprefs.sound_bits / 8 * spec.channels; + write_log ("SDL sound driver found and configured for %d bits at %d Hz, buffer is %d ms (%d bytes).\n", + currprefs.sound_bits, spec.freq, spec.samples * 1000 / spec.freq, sndbufsize); + sndbufpt = sndbuffer; + + return 1; +} + +static void *sound_thread (void *dummy) +{ + for (;;) { + int cmd = read_comm_pipe_int_blocking (&to_sound_pipe); + int n; + + switch (cmd) { + case 0: + open_sound (); + uae_sem_post (&sound_init_sem); + break; + case 1: + uae_sem_post (&sound_init_sem); + return 0; + } + } +} + +/* We need a thread for this, since communication between finish_sound_buffer + * and the callback works through semaphores. In theory, this is unnecessary, + * since SDL uses a sound thread internally, and the callback runs in its + * context. But we don't want to depend on SDL's internals too much. */ +static void init_sound_thread (void) +{ + uae_thread_id tid; + + init_comm_pipe (&to_sound_pipe, 20, 1); + uae_sem_init (&data_available_sem, 0, 0); + uae_sem_init (&callback_done_sem, 0, 0); + uae_sem_init (&sound_init_sem, 0, 0); + uae_start_thread (sound_thread, NULL, &tid); +} + +void close_sound (void) +{ + if (! have_sound) + return; + + SDL_PauseAudio (1); + clearbuffer(); + if (in_callback) { + closing_sound = 1; + uae_sem_post (&data_available_sem); + } + write_comm_pipe_int (&to_sound_pipe, 1, 1); + uae_sem_wait (&sound_init_sem); + SDL_CloseAudio (); + uae_sem_destroy (&data_available_sem); + uae_sem_destroy (&sound_init_sem); + uae_sem_destroy (&callback_done_sem); + have_sound = 0; +} + +int init_sound (void) +{ + in_callback = 0; + closing_sound = 0; + + init_sound_thread (); + write_comm_pipe_int (&to_sound_pipe, 0, 1); + uae_sem_wait (&sound_init_sem); + SDL_PauseAudio (0); + + #ifdef DRIVESOUND + driveclick_init(); + #endif + + return have_sound; +} + +void pause_sound (void) +{ + SDL_PauseAudio (1); +} + +void resume_sound (void) +{ + clearbuffer(); + SDL_PauseAudio (0); +} + +void reset_sound (void) +{ + clearbuffer(); + return; +} + +void sound_volume (int dir) +{ +} + +/* + * Handle audio specific cfgfile options + */ +void audio_default_options (struct uae_prefs *p) +{ +} + +void audio_save_options (FILE *f, const struct uae_prefs *p) +{ +} + +int audio_parse_option (struct uae_prefs *p, const char *option, const char *value) +{ + return 0; +} diff --git a/src/sd-sdl/sound.h b/src/sd-sdl/sound.h index ee54249..642007f 100644 --- a/src/sd-sdl/sound.h +++ b/src/sd-sdl/sound.h @@ -21,6 +21,9 @@ extern void reset_sound (void); STATIC_INLINE void check_sound_buffers (void) { if ((char *)sndbufpt - (char *)sndbuffer >= sndbufsize) { + #ifdef DRIVESOUND + driveclick_mix ((uae_s16*)sndbuffer, sndbufsize >> 1); + #endif finish_sound_buffer (); sndbufpt = sndbuffer; } diff --git a/uaerc.wii b/uaerc.wii index ec1056b..4f74c81 100644 --- a/uaerc.wii +++ b/uaerc.wii @@ -170,5 +170,13 @@ floppy1type=0 floppy2type=-1 floppy3type=-1 +# Enable floppy sound +floppy0sound=1 +floppy1sound=1 +floppy_volume=33 +floppy0soundext=/uae/wave/ +floppy1soundext=/uae/wave/ + + # Set keyboard language. Possible values are de, dk, es, us, se, fr, it kbd_lang=us