diff --git a/bochs/config.cc b/bochs/config.cc index 3d58b0d32..66f3d2560 100644 --- a/bochs/config.cc +++ b/bochs/config.cc @@ -25,6 +25,9 @@ #if BX_NETWORKING #include "iodev/network/netmod.h" #endif +#if BX_SUPPORT_SOUNDLOW +#include "iodev/sound/soundmod.h" +#endif #include "param_names.h" #include @@ -1526,13 +1529,13 @@ void bx_init_options() soundlow->set_enabled(BX_SUPPORT_SOUNDLOW); #if BX_SUPPORT_SOUNDLOW + bx_soundmod_ctl.init(); bx_param_enum_c *driver = new bx_param_enum_c(soundlow, "waveoutdrv", "Waveout driver", "This is the waveout driver to use for emulated sound devices", - sound_driver_names, - BX_SOUNDDRV_DUMMY, - BX_SOUNDDRV_DUMMY); + bx_soundmod_ctl.get_driver_names(), + 0, 0); driver->set_by_name(BX_SOUND_LOWLEVEL_NAME); new bx_param_filename_c(soundlow, "waveout", @@ -1543,9 +1546,8 @@ void bx_init_options() "waveindrv", "Wavein driver", "This is the wavein driver to use for emulated sound devices", - sound_driver_names, - BX_SOUNDDRV_DUMMY, - BX_SOUNDDRV_DUMMY); + bx_soundmod_ctl.get_driver_names(), + 0, 0); driver->set_by_name(BX_SOUND_LOWLEVEL_NAME); new bx_param_filename_c(soundlow, "wavein", @@ -1556,9 +1558,8 @@ void bx_init_options() "midioutdrv", "Midiout driver", "This is the midiout driver to use for emulated sound devices", - sound_driver_names, - BX_SOUNDDRV_DUMMY, - BX_SOUNDDRV_DUMMY); + bx_soundmod_ctl.get_driver_names(), + 0, 0); driver->set_by_name(BX_SOUND_LOWLEVEL_NAME); new bx_param_filename_c(soundlow, "midiout", diff --git a/bochs/gui/siminterface.cc b/bochs/gui/siminterface.cc index f715efb9b..954c5e311 100644 --- a/bochs/gui/siminterface.cc +++ b/bochs/gui/siminterface.cc @@ -521,27 +521,6 @@ int floppy_type_n_sectors[] = { -1, 80*2*15, 80*2*18, 80*2*36, 80*2*9, 40*2*9, 4 const char *media_status_names[] = { "ejected", "inserted", NULL }; const char *bochs_bootdisk_names[] = { "none", "floppy", "disk","cdrom", "network", NULL }; -const char *sound_driver_names[] = { - "dummy", -#if BX_HAVE_SOUND_ALSA - "alsa", -#endif -#if BX_HAVE_SOUND_OSS - "oss", -#endif -#if BX_HAVE_SOUND_OSX - "osx", -#endif -#if BX_HAVE_SOUND_SDL - "sdl", -#endif -#if BX_HAVE_SOUND_WIN - "win", -#endif - "file", - NULL -}; - void bx_real_sim_c::set_notify_callback(bxevent_handler func, void *arg) { bxevent_callback = func; diff --git a/bochs/gui/siminterface.h b/bochs/gui/siminterface.h index 658e6d6e5..61116dd86 100644 --- a/bochs/gui/siminterface.h +++ b/bochs/gui/siminterface.h @@ -572,32 +572,11 @@ enum { #define BX_CLOCK_TIME0_LOCAL 1 #define BX_CLOCK_TIME0_UTC 2 -enum { - BX_SOUNDDRV_DUMMY, -#if BX_HAVE_SOUND_ALSA - BX_SOUNDDRV_ALSA, -#endif -#if BX_HAVE_SOUND_OSS - BX_SOUNDDRV_OSS, -#endif -#if BX_HAVE_SOUND_OSX - BX_SOUNDDRV_OSX, -#endif -#if BX_HAVE_SOUND_SDL - BX_SOUNDDRV_SDL, -#endif -#if BX_HAVE_SOUND_WIN - BX_SOUNDDRV_WIN, -#endif - BX_SOUNDDRV_FILE -}; - BOCHSAPI extern const char *floppy_devtype_names[]; BOCHSAPI extern const char *floppy_type_names[]; BOCHSAPI extern int floppy_type_n_sectors[]; BOCHSAPI extern const char *media_status_names[]; BOCHSAPI extern const char *bochs_bootdisk_names[]; -BOCHSAPI extern const char *sound_driver_names[]; //////////////////////////////////////////////////////////////////// // base class simulator interface, contains just virtual functions. diff --git a/bochs/iodev/devices.cc b/bochs/iodev/devices.cc index 4e4d4b1bc..764e494a5 100644 --- a/bochs/iodev/devices.cc +++ b/bochs/iodev/devices.cc @@ -61,6 +61,7 @@ bx_devices_c::bx_devices_c() for (unsigned i=0; i < BX_MAX_IRQS; i++) { irq_handler_name[i] = NULL; } + sound_device_count = 0; } bx_devices_c::~bx_devices_c() @@ -70,6 +71,9 @@ bx_devices_c::~bx_devices_c() #if BX_NETWORKING bx_netmod_ctl.exit(); #endif +#if BX_SUPPORT_SOUNDLOW + bx_soundmod_ctl.exit(); +#endif } void bx_devices_c::init_stubs() @@ -175,9 +179,8 @@ void bx_devices_c::init(BX_MEM_C *newmem) bx_slowdown_timer.init(); #if BX_SUPPORT_SOUNDLOW - sound_enabled = is_sound_enabled(); - if (sound_enabled) { - bx_soundmod_ctl.init(); + if (sound_device_count > 0) { + bx_soundmod_ctl.open_output(); } #endif // PCI logic (i440FX) @@ -449,10 +452,6 @@ void bx_devices_c::exit() // unload optional plugins first bx_unload_plugins(); bx_unload_core_plugins(); -#if BX_SUPPORT_SOUNDLOW - if (sound_enabled) - bx_soundmod_ctl.exit(); -#endif #if BX_SUPPORT_PCIUSB if (usb_enabled) bx_usbdev_ctl.exit(); @@ -1115,14 +1114,14 @@ bool bx_devices_c::is_harddrv_enabled(void) return 0; } -bool bx_devices_c::is_sound_enabled(void) +void bx_devices_c::add_sound_device(void) { - if (PLUG_device_present("es1370") || - PLUG_device_present("sb16") || - PLUG_device_present("speaker")) { - return 1; - } - return 0; + sound_device_count++; +} + +void bx_devices_c::remove_sound_device(void) +{ + sound_device_count--; } bool bx_devices_c::is_usb_enabled(void) diff --git a/bochs/iodev/iodev.h b/bochs/iodev/iodev.h index adf8b170a..382c44b67 100644 --- a/bochs/iodev/iodev.h +++ b/bochs/iodev/iodev.h @@ -429,6 +429,8 @@ public: void kbd_set_indicator(Bit8u devid, Bit8u ledid, bool state); void mouse_enabled_changed(bool enabled); void mouse_motion(int delta_x, int delta_y, int delta_z, unsigned button_state, bool absxy); + void add_sound_device(void); + void remove_sound_device(void); #if BX_SUPPORT_PCI Bit32u pci_get_confAddr(void) {return pci.confAddr;} @@ -602,11 +604,10 @@ private: int timer_handle; int statusbar_id[3]; - bool sound_enabled; - bool usb_enabled; + Bit8u sound_device_count; + bool usb_enabled; bool is_harddrv_enabled(); - bool is_sound_enabled(); bool is_usb_enabled(); }; diff --git a/bochs/iodev/network/netmod.cc b/bochs/iodev/network/netmod.cc index 55ba7703c..f8289ad66 100644 --- a/bochs/iodev/network/netmod.cc +++ b/bochs/iodev/network/netmod.cc @@ -154,7 +154,7 @@ eth_locator_c::eth_locator_c(const char *type) this->type = type; this->next = NULL; if (all == NULL) { - all = this; + all = this; } else { ptr = all; while (ptr->next) ptr = ptr->next; diff --git a/bochs/iodev/sound/es1370.cc b/bochs/iodev/sound/es1370.cc index fd788747f..98689df34 100644 --- a/bochs/iodev/sound/es1370.cc +++ b/bochs/iodev/sound/es1370.cc @@ -196,11 +196,13 @@ PLUGIN_ENTRY_FOR_MODULE(es1370) es1370_init_options(); // register add-on option for bochsrc and command line SIM->register_addon_option("es1370", es1370_options_parser, es1370_options_save); + bx_devices.add_sound_device(); } else { delete theES1370Device; SIM->unregister_addon_option("es1370"); bx_list_c *menu = (bx_list_c*)SIM->get_param("sound"); menu->remove("es1370"); + bx_devices.remove_sound_device(); } return 0; // Success } diff --git a/bochs/iodev/sound/sb16.cc b/bochs/iodev/sound/sb16.cc index e5e85a0b1..3e24f2dfa 100644 --- a/bochs/iodev/sound/sb16.cc +++ b/bochs/iodev/sound/sb16.cc @@ -172,10 +172,12 @@ PLUGIN_ENTRY_FOR_MODULE(sb16) sb16_init_options(); // register add-on option for bochsrc and command line SIM->register_addon_option("sb16", sb16_options_parser, sb16_options_save); + bx_devices.add_sound_device(); } else { delete theSB16Device; SIM->unregister_addon_option("sb16"); ((bx_list_c*)SIM->get_param("sound"))->remove("sb16"); + bx_devices.remove_sound_device(); } return(0); // Success } diff --git a/bochs/iodev/sound/soundlow.cc b/bochs/iodev/sound/soundlow.cc index fa7dbcac4..481257997 100644 --- a/bochs/iodev/sound/soundlow.cc +++ b/bochs/iodev/sound/soundlow.cc @@ -595,20 +595,30 @@ int bx_soundlow_midiout_c::closemidioutput() return BX_SOUNDLOW_OK; } +Bit8u bx_sound_lowlevel_c::count = 0; bx_sound_lowlevel_c *bx_sound_lowlevel_c::all; // bx_sound_lowlevel_c class implementation bx_sound_lowlevel_c::bx_sound_lowlevel_c(const char *type) { + bx_sound_lowlevel_c *ptr; + put("soundlow", "SNDLOW"); waveout = NULL; wavein = NULL; midiout = NULL; // self-registering static objects ported from the network code - next = all; - all = this; this->type = type; + this->next = NULL; + if (all == NULL) { + all = this; + } else { + ptr = all; + while (ptr->next) ptr = ptr->next; + ptr->next = this; + } + count++; } bx_sound_lowlevel_c::~bx_sound_lowlevel_c() @@ -642,6 +652,24 @@ bx_sound_lowlevel_c::~bx_sound_lowlevel_c() } } +Bit8u bx_sound_lowlevel_c::get_modules_count() +{ + return count; +} + +const char* bx_sound_lowlevel_c::get_module_name(Bit8u index) +{ + bx_sound_lowlevel_c *ptr; + Bit8u n = 0; + + for (ptr = all; ptr != NULL; ptr = ptr->next) { + if (n == index) + return ptr->type; + n++; + } + return NULL; +} + bool bx_sound_lowlevel_c::module_present(const char *type) { bx_sound_lowlevel_c *ptr = 0; diff --git a/bochs/iodev/sound/soundlow.h b/bochs/iodev/sound/soundlow.h index 7cdba516a..9b85579bb 100644 --- a/bochs/iodev/sound/soundlow.h +++ b/bochs/iodev/sound/soundlow.h @@ -174,6 +174,8 @@ public: class BOCHSAPI_MSVCONLY bx_sound_lowlevel_c : public logfunctions { public: static bool module_present(const char *type); + static Bit8u get_modules_count(void); + static const char* get_module_name(Bit8u index); static bx_sound_lowlevel_c* get_module(const char *type); static void cleanup(); @@ -189,6 +191,7 @@ protected: bx_soundlow_wavein_c *wavein; bx_soundlow_midiout_c *midiout; private: + static Bit8u count; static bx_sound_lowlevel_c *all; bx_sound_lowlevel_c *next; const char *type; diff --git a/bochs/iodev/sound/soundmod.cc b/bochs/iodev/sound/soundmod.cc index b6f854dda..675ff65ed 100644 --- a/bochs/iodev/sound/soundmod.cc +++ b/bochs/iodev/sound/soundmod.cc @@ -35,6 +35,7 @@ bx_soundmod_ctl_c bx_soundmod_ctl; +const char **sound_driver_names; bx_soundmod_ctl_c::bx_soundmod_ctl_c() { @@ -42,6 +43,71 @@ bx_soundmod_ctl_c::bx_soundmod_ctl_c() } void bx_soundmod_ctl_c::init() +{ + Bit8u i, count = 0; + +#if !BX_PLUGINS + count = bx_sound_lowlevel_c::get_modules_count(); +#else + count = PLUG_get_plugins_count(PLUGTYPE_SND); +#endif + sound_driver_names = (const char**) malloc((count + 1) * sizeof(char*)); + for (i = 0; i < count; i++) { +#if !BX_PLUGINS + sound_driver_names[i] = bx_sound_lowlevel_c::get_module_name(i); +#else + sound_driver_names[i] = PLUG_get_plugin_name(PLUGTYPE_SND, i); +#endif + } + sound_driver_names[count] = NULL; + // move 'dummy' module to the top of the list + if (strcmp(sound_driver_names[0], "dummy")) { + for (i = 1; i < count; i++) { + if (!strcmp(sound_driver_names[i], "dummy")) { + sound_driver_names[i] = sound_driver_names[0]; + sound_driver_names[0] = "dummy"; + break; + } + } + } +} + +void bx_soundmod_ctl_c::exit() +{ + bx_sound_lowlevel_c::cleanup(); +} + +const char **bx_soundmod_ctl_c::get_driver_names(void) +{ + return sound_driver_names; +} + +void bx_soundmod_ctl_c::list_modules(void) +{ + char list[60]; + Bit8u i = 0; + size_t len = 0, len1; + + BX_INFO(("Sound drivers")); + list[0] = 0; + while (sound_driver_names[i] != NULL) { + len1 = strlen(sound_driver_names[i]); + if ((len + len1 + 1) > 60) { + BX_INFO((" %s", list)); + list[0] = 0; + len = 0; + } + strcat(list, " "); + strcat(list, sound_driver_names[i]); + len = strlen(list); + i++; + } + if (len > 0) { + BX_INFO((" %s", list)); + } +} + +void bx_soundmod_ctl_c::open_output() { const char *pwaveout = SIM->get_param_string(BXPN_SOUND_WAVEOUT)->getptr(); const char *pwavein = SIM->get_param_string(BXPN_SOUND_WAVEIN)->getptr(); @@ -61,14 +127,8 @@ void bx_soundmod_ctl_c::init() } } -void bx_soundmod_ctl_c::exit() +bx_sound_lowlevel_c* bx_soundmod_ctl_c::get_driver(const char *modname) { - bx_sound_lowlevel_c::cleanup(); -} - -bx_sound_lowlevel_c* bx_soundmod_ctl_c::get_driver(int driver_id) -{ - const char *modname = sound_driver_names[driver_id]; if (!bx_sound_lowlevel_c::module_present(modname)) { #if BX_PLUGINS PLUG_load_plugin_var(modname, PLUGTYPE_SND); @@ -84,10 +144,9 @@ bx_soundlow_waveout_c* bx_soundmod_ctl_c::get_waveout(bool using_file) bx_sound_lowlevel_c *module = NULL; if (!using_file) { - int driver_id = SIM->get_param_enum(BXPN_SOUND_WAVEOUT_DRV)->get(); - module = get_driver(driver_id); + module = get_driver(SIM->get_param_enum(BXPN_SOUND_WAVEOUT_DRV)->get_selected()); } else { - module = get_driver(BX_SOUNDDRV_FILE); + module = get_driver("file"); } if (module != NULL) { return module->get_waveout(); @@ -101,13 +160,12 @@ bx_soundlow_wavein_c* bx_soundmod_ctl_c::get_wavein() bx_sound_lowlevel_c *module = NULL; bx_soundlow_wavein_c *wavein = NULL; - int driver_id = SIM->get_param_enum(BXPN_SOUND_WAVEIN_DRV)->get(); - module = get_driver(driver_id); + module = get_driver(SIM->get_param_enum(BXPN_SOUND_WAVEIN_DRV)->get_selected()); if (module != NULL) { wavein = module->get_wavein(); if (wavein == NULL) { BX_ERROR(("sound service 'wavein' not available - using dummy driver")); - module = get_driver(BX_SOUNDDRV_DUMMY); + module = get_driver("dummy"); if (module != NULL) { wavein = module->get_wavein(); } @@ -122,16 +180,15 @@ bx_soundlow_midiout_c* bx_soundmod_ctl_c::get_midiout(bool using_file) bx_soundlow_midiout_c *midiout = NULL; if (!using_file) { - int driver_id = SIM->get_param_enum(BXPN_SOUND_MIDIOUT_DRV)->get(); - module = get_driver(driver_id); + module = get_driver(SIM->get_param_enum(BXPN_SOUND_MIDIOUT_DRV)->get_selected()); } else { - module = get_driver(BX_SOUNDDRV_FILE); + module = get_driver("file"); } if (module != NULL) { midiout = module->get_midiout(); if (midiout == NULL) { BX_ERROR(("sound service 'midiout' not available - using dummy driver")); - module = get_driver(BX_SOUNDDRV_DUMMY); + module = get_driver("dummy"); if (module != NULL) { midiout = module->get_midiout(); } diff --git a/bochs/iodev/sound/soundmod.h b/bochs/iodev/sound/soundmod.h index 80110b251..989285ea6 100644 --- a/bochs/iodev/sound/soundmod.h +++ b/bochs/iodev/sound/soundmod.h @@ -32,13 +32,15 @@ public: ~bx_soundmod_ctl_c() {} void init(void); void exit(void); - bool register_driver(bx_sound_lowlevel_c *module, int driver_id); + const char **get_driver_names(); + void list_modules(void); + void open_output(void); bx_soundlow_waveout_c* get_waveout(bool using_file); bx_soundlow_wavein_c* get_wavein(); bx_soundlow_midiout_c* get_midiout(bool using_file); private: - bx_sound_lowlevel_c* get_driver(int driver_id); + bx_sound_lowlevel_c* get_driver(const char *modname); }; BOCHSAPI extern bx_soundmod_ctl_c bx_soundmod_ctl; diff --git a/bochs/iodev/speaker.cc b/bochs/iodev/speaker.cc index b7bcd2599..c6d8fcb34 100644 --- a/bochs/iodev/speaker.cc +++ b/bochs/iodev/speaker.cc @@ -139,11 +139,13 @@ PLUGIN_ENTRY_FOR_MODULE(speaker) speaker_init_options(); // register add-on options for bochsrc and command line SIM->register_addon_option("speaker", speaker_options_parser, speaker_options_save); + bx_devices.add_sound_device(); } else { bx_devices.pluginSpeaker = &bx_devices.stubSpeaker; delete theSpeaker; SIM->unregister_addon_option("speaker"); ((bx_list_c*)SIM->get_param("sound"))->remove("speaker"); + bx_devices.remove_sound_device(); } return(0); // Success } diff --git a/bochs/main.cc b/bochs/main.cc index 285616681..f43dcceb6 100644 --- a/bochs/main.cc +++ b/bochs/main.cc @@ -31,6 +31,9 @@ #if BX_NETWORKING #include "iodev/network/netmod.h" #endif +#if BX_SUPPORT_SOUNDLOW +#include "iodev/sound/soundmod.h" +#endif #ifdef HAVE_LOCALE_H #include @@ -1299,6 +1302,9 @@ void bx_init_hardware() bx_hdimage_ctl.list_modules(); #if BX_NETWORKING bx_netmod_ctl.list_modules(); +#endif +#if BX_SUPPORT_SOUNDLOW + bx_soundmod_ctl.list_modules(); #endif // Check if there is a romimage if (SIM->get_param_string(BXPN_ROM_PATH)->isempty()) {