aad2d89c83
directly while parsing the bochsrc or command line. If plugin support is enabled, the option could load all optional plugins, not only the ones supported before. NOTE #1: The old option had all plugins enabled by default and gave the user a chance to diable them. Now the plugins are only loaded if they appear in the config line and they are set to "1". NOTE #2: Loading a plugin that is controlled by a bochsrc option is possible, but it currently leads to a panic, since the load command is still present in devices.cc. NOTE #3: The plugin init code creates the device object and registers the optional plugin device. As an option, it can create config parameters and register an option parser. The device init, register state and reset is still handled in devices.cc, but in the order the devices have been loaded with the plugin control. NOTE #4: If plugin support is disabled, the plugin control only accepts the devices listed in plugin.cc. - plugin init of core plugins now fails if they are not loaded with the expected type. For core plugins the load order is important and they cannot be handled with the chained devices list (used for optional and user plugins). - some additions for calling config.cc functions from a plugin device
208 lines
5.1 KiB
C++
208 lines
5.1 KiB
C++
/////////////////////////////////////////////////////////////////////////
|
|
// $Id$
|
|
/////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (C) 2011 The Bochs Project
|
|
//
|
|
// This library is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
// License as published by the Free Software Foundation; either
|
|
// version 2 of the License, or (at your option) any later version.
|
|
//
|
|
// This library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
// Lesser General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
// License along with this library; if not, write to the Free Software
|
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
// Common sound module code and dummy sound lowlevel functions
|
|
|
|
// Define BX_PLUGGABLE in files that can be compiled into plugins. For
|
|
// platforms that require a special tag on exported symbols, BX_PLUGGABLE
|
|
// is used to know when we are exporting symbols and when we are importing.
|
|
#define BX_PLUGGABLE
|
|
|
|
#include "iodev.h"
|
|
|
|
#if BX_SUPPORT_SOUNDLOW
|
|
|
|
#include "soundmod.h"
|
|
#include "soundlnx.h"
|
|
#include "soundosx.h"
|
|
#include "soundwin.h"
|
|
|
|
#define LOG_THIS device->
|
|
|
|
bx_soundmod_ctl_c* theSoundModCtl = NULL;
|
|
|
|
int libsoundmod_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
|
|
{
|
|
if (type == PLUGTYPE_CORE) {
|
|
theSoundModCtl = new bx_soundmod_ctl_c;
|
|
bx_devices.pluginSoundModCtl = theSoundModCtl;
|
|
return 0; // Success
|
|
} else {
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
void libsoundmod_LTX_plugin_fini(void)
|
|
{
|
|
delete theSoundModCtl;
|
|
}
|
|
|
|
void* bx_soundmod_ctl_c::init_module(const char *type, logfunctions *device)
|
|
{
|
|
bx_sound_lowlevel_c *soundmod;
|
|
|
|
if (!strcmp(type, "default")) {
|
|
soundmod = new BX_SOUND_LOWLEVEL_C(device);
|
|
} else if (!strcmp(type, "dummy")) {
|
|
soundmod = new bx_sound_lowlevel_c(device);
|
|
} else {
|
|
BX_PANIC(("unknown sound module type '%s'", type));
|
|
soundmod = NULL;
|
|
}
|
|
return soundmod;
|
|
}
|
|
|
|
// The dummy sound lowlevel functions. They don't do anything.
|
|
bx_sound_lowlevel_c::bx_sound_lowlevel_c(logfunctions *dev)
|
|
{
|
|
device = dev;
|
|
record_timer_index = BX_NULL_TIMER_HANDLE;
|
|
}
|
|
|
|
bx_sound_lowlevel_c::~bx_sound_lowlevel_c()
|
|
{
|
|
}
|
|
|
|
int bx_sound_lowlevel_c::waveready()
|
|
{
|
|
return BX_SOUNDLOW_OK;
|
|
}
|
|
|
|
int bx_sound_lowlevel_c::midiready()
|
|
{
|
|
return BX_SOUNDLOW_OK;
|
|
}
|
|
|
|
int bx_sound_lowlevel_c::openmidioutput(const char *mididev)
|
|
{
|
|
UNUSED(mididev);
|
|
return BX_SOUNDLOW_OK;
|
|
}
|
|
|
|
int bx_sound_lowlevel_c::sendmidicommand(int delta, int command, int length, Bit8u data[])
|
|
{
|
|
UNUSED(delta);
|
|
UNUSED(command);
|
|
UNUSED(length);
|
|
UNUSED(data);
|
|
return BX_SOUNDLOW_OK;
|
|
}
|
|
|
|
int bx_sound_lowlevel_c::closemidioutput()
|
|
{
|
|
return BX_SOUNDLOW_OK;
|
|
}
|
|
|
|
int bx_sound_lowlevel_c::openwaveoutput(const char *wavedev)
|
|
{
|
|
UNUSED(wavedev);
|
|
return BX_SOUNDLOW_OK;
|
|
}
|
|
|
|
int bx_sound_lowlevel_c::startwaveplayback(int frequency, int bits, bx_bool stereo, int format)
|
|
{
|
|
UNUSED(frequency);
|
|
UNUSED(bits);
|
|
UNUSED(stereo);
|
|
UNUSED(format);
|
|
return BX_SOUNDLOW_OK;
|
|
}
|
|
|
|
int bx_sound_lowlevel_c::sendwavepacket(int length, Bit8u data[])
|
|
{
|
|
UNUSED(length);
|
|
UNUSED(data);
|
|
return BX_SOUNDLOW_OK;
|
|
}
|
|
|
|
int bx_sound_lowlevel_c::stopwaveplayback()
|
|
{
|
|
return BX_SOUNDLOW_OK;
|
|
}
|
|
|
|
int bx_sound_lowlevel_c::closewaveoutput()
|
|
{
|
|
return BX_SOUNDLOW_OK;
|
|
}
|
|
|
|
int bx_sound_lowlevel_c::openwaveinput(const char *wavedev, sound_record_handler_t rh)
|
|
{
|
|
UNUSED(wavedev);
|
|
record_handler = rh;
|
|
if (rh != NULL) {
|
|
record_timer_index = bx_pc_system.register_timer(this, record_timer_handler, 1, 1, 0, "soundmod");
|
|
// record timer: inactive, continuous, frequency variable
|
|
}
|
|
return BX_SOUNDLOW_OK;
|
|
}
|
|
|
|
int bx_sound_lowlevel_c::startwaverecord(int frequency, int bits, bx_bool stereo, int format)
|
|
{
|
|
Bit64u timer_val;
|
|
Bit8u shift = 0;
|
|
|
|
UNUSED(format);
|
|
if (record_timer_index != BX_NULL_TIMER_HANDLE) {
|
|
if (bits == 16) shift++;
|
|
if (stereo) shift++;
|
|
record_packet_size = (frequency / 10) << shift; // 0.1 sec
|
|
if (record_packet_size > BX_SOUNDLOW_WAVEPACKETSIZE) {
|
|
record_packet_size = BX_SOUNDLOW_WAVEPACKETSIZE;
|
|
}
|
|
timer_val = (Bit64u)record_packet_size * 1000000 / (frequency << shift);
|
|
bx_pc_system.activate_timer(record_timer_index, (Bit32u)timer_val, 1);
|
|
}
|
|
return BX_SOUNDLOW_OK;
|
|
}
|
|
|
|
int bx_sound_lowlevel_c::getwavepacket(int length, Bit8u data[])
|
|
{
|
|
memset(data, 0, length);
|
|
return BX_SOUNDLOW_OK;
|
|
}
|
|
|
|
int bx_sound_lowlevel_c::stopwaverecord()
|
|
{
|
|
if (record_timer_index != BX_NULL_TIMER_HANDLE) {
|
|
bx_pc_system.deactivate_timer(record_timer_index);
|
|
}
|
|
return BX_SOUNDLOW_OK;
|
|
}
|
|
|
|
int bx_sound_lowlevel_c::closewaveinput()
|
|
{
|
|
stopwaverecord();
|
|
return BX_SOUNDLOW_OK;
|
|
}
|
|
|
|
void bx_sound_lowlevel_c::record_timer_handler(void *this_ptr)
|
|
{
|
|
bx_sound_lowlevel_c *class_ptr = (bx_sound_lowlevel_c *) this_ptr;
|
|
|
|
class_ptr->record_timer();
|
|
}
|
|
|
|
void bx_sound_lowlevel_c::record_timer(void)
|
|
{
|
|
record_handler(this->device, record_packet_size);
|
|
}
|
|
|
|
#endif
|