Added ZIP, DMS and floppy sound support

This commit is contained in:
fabio.olimpieri 2012-03-29 07:49:31 +00:00
parent b5feec8512
commit e1cf346493
9 changed files with 418 additions and 277 deletions

View File

@ -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
#---------------------------------------------------------------------------------

View File

@ -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

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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 <SDL_audio.h>
#include <SDL.h>
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 <SDL_audio.h>
#include <SDL.h>
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;
}

View File

@ -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;
}

View File

@ -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