[Scummvm-cvs-logs] SF.net SVN: scummvm:[40496] scummvm/trunk

lordhoto at users.sourceforge.net lordhoto at users.sourceforge.net
Tue May 12 20:42:44 CEST 2009


Revision: 40496
          http://scummvm.svn.sourceforge.net/scummvm/?rev=40496&view=rev
Author:   lordhoto
Date:     2009-05-12 18:42:44 +0000 (Tue, 12 May 2009)

Log Message:
-----------
- Add support for selecting the OPL emulator being used (config entry: "opl_driver")
- Make MAME FM OPL the default emulator again
- Add GUI support for selecting the active OPL emulator
- Update themes

Modified Paths:
--------------
    scummvm/trunk/engines/sci/sfx/softseq/adlib.cpp
    scummvm/trunk/gui/options.cpp
    scummvm/trunk/gui/options.h
    scummvm/trunk/gui/themes/default.inc
    scummvm/trunk/gui/themes/scummclassic/classic_layout.stx
    scummvm/trunk/gui/themes/scummclassic/classic_layout_lowres.stx
    scummvm/trunk/gui/themes/scummclassic.zip
    scummvm/trunk/gui/themes/scummmodern/scummmodern_layout.stx
    scummvm/trunk/gui/themes/scummmodern/scummmodern_layout_lowres.stx
    scummvm/trunk/gui/themes/scummmodern.zip
    scummvm/trunk/sound/fmopl.cpp
    scummvm/trunk/sound/fmopl.h
    scummvm/trunk/sound/softsynth/opl/dosbox.cpp
    scummvm/trunk/sound/softsynth/opl/dosbox.h

Modified: scummvm/trunk/engines/sci/sfx/softseq/adlib.cpp
===================================================================
--- scummvm/trunk/engines/sci/sfx/softseq/adlib.cpp	2009-05-12 18:21:32 UTC (rev 40495)
+++ scummvm/trunk/engines/sci/sfx/softseq/adlib.cpp	2009-05-12 18:42:44 UTC (rev 40496)
@@ -82,7 +82,7 @@
 	debug(3, "ADLIB: Starting driver in %s mode", (isSCI0 ? "SCI0" : "SCI1"));
 	_isSCI0 = isSCI0;
 
-	_opl = OPL::OPL::create(isStereo() ? OPL::OPL::kDualOpl2 : OPL::OPL::kOpl2);
+	_opl = OPL::Config::create(isStereo() ? OPL::Config::kDualOpl2 : OPL::Config::kOpl2);
 
 	if (!_opl)
 		return -1;

Modified: scummvm/trunk/gui/options.cpp
===================================================================
--- scummvm/trunk/gui/options.cpp	2009-05-12 18:21:32 UTC (rev 40495)
+++ scummvm/trunk/gui/options.cpp	2009-05-12 18:42:44 UTC (rev 40496)
@@ -40,6 +40,7 @@
 
 #include "sound/mididrv.h"
 #include "sound/mixer.h"
+#include "sound/fmopl.h"
 
 namespace GUI {
 
@@ -102,6 +103,7 @@
 	_aspectCheckbox = 0;
 	_enableAudioSettings = false;
 	_midiPopUp = 0;
+	_oplPopUp = 0;
 	_outputRatePopUp = 0;
 	_enableMIDISettings = false;
 	_multiMidiCheckbox = 0;
@@ -181,6 +183,9 @@
 		_midiPopUp->setSelectedTag(id);
 	}
 
+	if (_oplPopUp)
+		_oplPopUp->setSelectedTag(OPL::Config::parse(ConfMan.get("opl_driver", _domain)));
+
 	if (_outputRatePopUp) {
 		_outputRatePopUp->setSelected(1);
 		int value = ConfMan.getInt("output_rate", _domain);
@@ -315,6 +320,21 @@
 			}
 		}
 
+		if (_oplPopUp) {
+			if (_enableAudioSettings) {
+				const OPL::Config::EmulatorDescription *ed = OPL::Config::getAvailable();
+				while (ed->name && ed->id != (int)_oplPopUp->getSelectedTag())
+					++ed;
+
+				if (ed->name)
+					ConfMan.set("opl_driver", ed->name, _domain);
+				else
+					ConfMan.removeKey("opl_driver", _domain);
+			} else {
+				ConfMan.removeKey("opl_driver", _domain);
+			}
+		}
+
 		if (_outputRatePopUp) {
 			if (_enableAudioSettings) {
 				if (_outputRatePopUp->getSelectedTag() != 0)
@@ -457,6 +477,7 @@
 	_enableAudioSettings = enabled;
 
 	_midiPopUp->setEnabled(enabled);
+	_oplPopUp->setEnabled(enabled);
 	_outputRatePopUp->setEnabled(enabled);
 }
 
@@ -545,6 +566,16 @@
 		md++;
 	}
 
+	// The OPL emulator popup & a label
+	_oplPopUp = new PopUpWidget(boss, prefix + "auOPLPopup", "AdLib emulator:");
+
+	// Populate it
+	const OPL::Config::EmulatorDescription *ed = OPL::Config::getAvailable();
+	while (ed->name) {
+		_oplPopUp->appendEntry(ed->description, ed->id);
+		++ed;
+	}
+
 	// Sample rate settings
 	_outputRatePopUp = new PopUpWidget(boss, prefix + "auSampleRatePopup", "Output rate:");
 

Modified: scummvm/trunk/gui/options.h
===================================================================
--- scummvm/trunk/gui/options.h	2009-05-12 18:21:32 UTC (rev 40495)
+++ scummvm/trunk/gui/options.h	2009-05-12 18:42:44 UTC (rev 40496)
@@ -101,6 +101,7 @@
 	//
 	bool _enableAudioSettings;
 	PopUpWidget *_midiPopUp;
+	PopUpWidget *_oplPopUp;
 	PopUpWidget *_outputRatePopUp;
 
 	//

Modified: scummvm/trunk/gui/themes/default.inc
===================================================================
--- scummvm/trunk/gui/themes/default.inc	2009-05-12 18:21:32 UTC (rev 40495)
+++ scummvm/trunk/gui/themes/default.inc	2009-05-12 18:42:44 UTC (rev 40496)
@@ -475,6 +475,9 @@
 "<widget name='auMidiPopup' "
 "type='PopUp' "
 "/> "
+"<widget name='auOPLPopup' "
+"type='PopUp' "
+"/> "
 "<widget name='auSampleRatePopup' "
 "type='PopUp' "
 "/> "
@@ -1115,6 +1118,9 @@
 "<widget name='auMidiPopup' "
 "type='PopUp' "
 "/> "
+"<widget name='auOPLPopup' "
+"type='PopUp' "
+"/> "
 "<widget name='auSampleRatePopup' "
 "type='PopUp' "
 "/> "

Modified: scummvm/trunk/gui/themes/scummclassic/classic_layout.stx
===================================================================
--- scummvm/trunk/gui/themes/scummclassic/classic_layout.stx	2009-05-12 18:21:32 UTC (rev 40495)
+++ scummvm/trunk/gui/themes/scummclassic/classic_layout.stx	2009-05-12 18:42:44 UTC (rev 40496)
@@ -186,6 +186,9 @@
 			<widget name = 'auMidiPopup'
 					type = 'PopUp'
 			/>
+			<widget name = 'auOPLPopup'
+					type = 'PopUp'
+			/>
 			<widget name = 'auSampleRatePopup'
 					type = 'PopUp'
 			/>

Modified: scummvm/trunk/gui/themes/scummclassic/classic_layout_lowres.stx
===================================================================
--- scummvm/trunk/gui/themes/scummclassic/classic_layout_lowres.stx	2009-05-12 18:21:32 UTC (rev 40495)
+++ scummvm/trunk/gui/themes/scummclassic/classic_layout_lowres.stx	2009-05-12 18:42:44 UTC (rev 40496)
@@ -183,6 +183,9 @@
 			<widget name = 'auMidiPopup'
 					type = 'PopUp'
 			/>
+			<widget name = 'auOPLPopup'
+					type = 'PopUp'
+			/>
 			<widget name = 'auSampleRatePopup'
 					type = 'PopUp'
 			/>

Modified: scummvm/trunk/gui/themes/scummclassic.zip
===================================================================
(Binary files differ)

Modified: scummvm/trunk/gui/themes/scummmodern/scummmodern_layout.stx
===================================================================
--- scummvm/trunk/gui/themes/scummmodern/scummmodern_layout.stx	2009-05-12 18:21:32 UTC (rev 40495)
+++ scummvm/trunk/gui/themes/scummmodern/scummmodern_layout.stx	2009-05-12 18:42:44 UTC (rev 40496)
@@ -201,6 +201,9 @@
 			<widget name = 'auMidiPopup'
 					type = 'PopUp'
 			/>
+			<widget name = 'auOPLPopup'
+					type = 'PopUp'
+			/>
 			<widget name = 'auSampleRatePopup'
 					type = 'PopUp'
 			/>

Modified: scummvm/trunk/gui/themes/scummmodern/scummmodern_layout_lowres.stx
===================================================================
--- scummvm/trunk/gui/themes/scummmodern/scummmodern_layout_lowres.stx	2009-05-12 18:21:32 UTC (rev 40495)
+++ scummvm/trunk/gui/themes/scummmodern/scummmodern_layout_lowres.stx	2009-05-12 18:42:44 UTC (rev 40496)
@@ -181,6 +181,9 @@
 			<widget name = 'auMidiPopup'
 					type = 'PopUp'
 			/>
+			<widget name = 'auOPLPopup'
+					type = 'PopUp'
+			/>
 			<widget name = 'auSampleRatePopup'
 					type = 'PopUp'
 			/>

Modified: scummvm/trunk/gui/themes/scummmodern.zip
===================================================================
(Binary files differ)

Modified: scummvm/trunk/sound/fmopl.cpp
===================================================================
--- scummvm/trunk/sound/fmopl.cpp	2009-05-12 18:21:32 UTC (rev 40495)
+++ scummvm/trunk/sound/fmopl.cpp	2009-05-12 18:42:44 UTC (rev 40496)
@@ -27,27 +27,101 @@
 #include "sound/softsynth/opl/dosbox.h"
 #include "sound/softsynth/opl/mame.h"
 
+#include "common/config-manager.h"
+
 namespace OPL {
 
-bool OPL::_hasInstance = false;
+// Config implementation
 
-OPL *OPL::create(kOplType type) {
-	// Simple hack to assure we only create one instance,
-	// since the DOSBox OPL emulator does not allow more than
-	// one instance.
-	assert(!_hasInstance);
-	_hasInstance = true;
+enum OplEmulator {
+	kMame = 0,
+	kDOSBox = 1
+};
 
-#ifdef DISABLE_DOSBOX_OPL
-	if (type != kOpl2)
-		return 0;
-	else
-		return new MAME::OPL();
-#else
-	return new DOSBox::OPL(type);
+const Config::EmulatorDescription Config::_drivers[] = {
+	{ "auto", "<default>", 0, kFlagOpl2 | kFlagDualOpl2 | kFlagOpl3 },
+	{ "mame", "MAME OPL emulator", kMame, kFlagOpl2 },
+#ifndef DISABLE_DOSBOX_OPL
+	{ "db", "DOSBox OPL emulator (experimental)", kDOSBox, kFlagOpl2 | kFlagDualOpl2 | kFlagOpl3 },
 #endif
+	{ 0, 0, 0, 0 }
+};
+
+Config::DriverId Config::parse(const Common::String &name) {
+	for (int i = 0; _drivers[i].name; ++i) {
+		if (name.equalsIgnoreCase(_drivers[i].name))
+			return _drivers[i].id;
+	}
+
+	return 0;
 }
 
+Config::DriverId Config::detect(OplType type) {
+	uint32 flags = 0;
+	switch (type) {
+	case kOpl2:
+		flags = kFlagOpl2;
+		break;
+
+	case kDualOpl2:
+		flags = kFlagDualOpl2;
+		break;
+
+	case kOpl3:
+		flags = kFlagOpl3;
+		break;
+	}
+
+	DriverId drv = parse(ConfMan.get("opl_driver"));
+
+	// When a valid driver is selected, check whether it supports
+	// the requested OPL chip.
+	if (validDriver(drv)) {
+		// If the chip is supported, just use the driver.
+		if ((flags & _drivers[drv].flags))
+			return drv;
+
+		// When it doesn't support the flags fall back to auto detection
+	}
+
+	// Detect the first matching emulator
+	for (int i = 1; _drivers[i].name; ++i) {
+		if (_drivers[i].flags & flags) {
+			drv = _drivers[i].id;
+			break;
+		}
+	}
+
+	return drv;
+}
+
+OPL *Config::create(DriverId driver, OplType type) {
+	if (!validDriver(driver))
+		driver = detect(type);
+
+	switch (driver)  {
+	case kMame:
+		if (type == kOpl2)
+			return new MAME::OPL();
+		else
+			warning("MAME OPL emulator only supports OPL2 emulation.");
+			return 0;
+
+#ifndef DISABLE_DOSBOX_OPL
+	case kDOSBox:
+		return new DOSBox::OPL(type);
+#endif
+
+	default:
+		warning("Unsupported OPL emulator %d", driver);
+		// TODO: Maybe we should add some dummy emulator too, which just outputs
+		// silence as sound?
+		return 0;
+	}
+}
+
+bool OPL::_hasInstance = false;
+
 } // end of namespace OPL
 
 void OPLDestroy(FM_OPL *OPL) {
@@ -75,7 +149,7 @@
 }
 
 FM_OPL *makeAdlibOPL(int rate) {
-	FM_OPL *opl = OPL::OPL::create(OPL::OPL::kOpl2);
+	FM_OPL *opl = OPL::Config::create(OPL::Config::kOpl2);
 
 	if (opl) {
 		if (!opl->init(rate)) {

Modified: scummvm/trunk/sound/fmopl.h
===================================================================
--- scummvm/trunk/sound/fmopl.h	2009-05-12 18:21:32 UTC (rev 40495)
+++ scummvm/trunk/sound/fmopl.h	2009-05-12 18:42:44 UTC (rev 40496)
@@ -26,26 +26,82 @@
 #define SOUND_FMOPL_H
 
 #include "common/scummsys.h"
+#include "common/str.h"
 
 namespace OPL {
 
-class OPL {
-private:
-	// TODO: This is part of a temporary HACK to allow only 1 instance
-	static bool _hasInstance;
+class OPL;
+
+class Config {
 public:
-	virtual ~OPL() { _hasInstance = false; }
+	enum OplFlags {
+		kFlagOpl2		= (1 << 0),
+		kFlagDualOpl2	= (1 << 1),
+		kFlagOpl3		= (1 << 2)
+	};
 
 	/**
 	 * OPL type to emulate.
 	 */
-	enum kOplType {
+	enum OplType {
 		kOpl2,
 		kDualOpl2,
 		kOpl3
 	};
 
+	typedef int8 DriverId;
+	struct EmulatorDescription {
+		const char *name;
+		const char *description;
+
+		DriverId id;	// A unique ID for each driver
+		uint32 flags;	// Capabilities of this driver
+	};
+
 	/**
+	 * Get a list of all available OPL emulators.
+	 * @return list of all available OPL emulators, terminated by a zero entry
+	 */
+	static const EmulatorDescription *getAvailable() { return _drivers; }
+
+	/**
+	 * Returns the driver id of a given name.
+	 */
+	static DriverId parse(const Common::String &name);
+
+	/**
+	 * Detects a driver for the specific type.
+	 */
+	static DriverId detect(OplType type = kOpl2);
+
+	/**
+	 * Checks whether the driver id is valid.
+	 */
+	static bool validDriver(DriverId id) { return (id > 0); }
+
+	/**
+	 * Creates the specific driver with a specific type setup.
+	 */ 
+	static OPL *create(DriverId driver, OplType type);
+
+	/**
+	 * Wrapper to easily init an OPL chip, without specifing an emulator.
+	 */
+	static OPL *create(OplType type) { return create(detect(type), type); }
+
+private:
+	static const EmulatorDescription _drivers[];	
+};
+
+class OPL {
+private:
+	// TODO: This is part of a temporary HACK to allow only 1 instance
+	static bool _hasInstance;
+public:
+	OPL() { _hasInstance = true; }
+	virtual ~OPL() { _hasInstance = false; }
+
+	/**
 	 * Initializes the OPL emulator.
 	 *
 	 * @param rate	output sample rate
@@ -99,8 +155,6 @@
 	 * Returns whether the setup OPL mode is stereo or not
 	 */
 	virtual bool isStereo() const = 0;
-
-	static OPL *create(kOplType type);
 };
 
 } // end of namespace OPL

Modified: scummvm/trunk/sound/softsynth/opl/dosbox.cpp
===================================================================
--- scummvm/trunk/sound/softsynth/opl/dosbox.cpp	2009-05-12 18:21:32 UTC (rev 40495)
+++ scummvm/trunk/sound/softsynth/opl/dosbox.cpp	2009-05-12 18:42:44 UTC (rev 40496)
@@ -190,7 +190,7 @@
 };
 } // end of namespace OPL3
 
-OPL::OPL(kOplType type) : _type(type), _rate(0), _handler(0) {
+OPL::OPL(Config::OplType type) : _type(type), _rate(0), _handler(0) {
 }
 
 OPL::~OPL() {
@@ -209,12 +209,12 @@
 	memset(_chip, 0, sizeof(_chip));
 
 	switch (_type) {
-	case kOpl2:
+	case Config::kOpl2:
 		_handler = new OPL2::Handler();
 		break;
 
-	case kDualOpl2:
-	case kOpl3:
+	case Config::kDualOpl2:
+	case Config::kOpl3:
 		_handler = new OPL3::Handler();
 		break;
 	
@@ -224,7 +224,7 @@
 
 	_handler->init(rate);
 	
-	if (_type == kDualOpl2) {
+	if (_type == Config::kDualOpl2) {
 		// Setup opl3 mode in the hander
 		_handler->writeReg(0x105, 1);
 	}
@@ -240,12 +240,12 @@
 void OPL::write(int port, int val) {
 	if (port&1) {
 		switch (_type) {
-		case kOpl2:
-		case kOpl3:
+		case Config::kOpl2:
+		case Config::kOpl3:
 			if (!_chip[0].write(_reg.normal, val))
 				_handler->writeReg(_reg.normal, val);
 			break;
-		case kDualOpl2:
+		case Config::kDualOpl2:
 			// Not a 0x??8 port, then write to a specific port
 			if (!(port & 0x8)) {
 				byte index = (port & 2) >> 1;
@@ -261,13 +261,13 @@
 		// Ask the handler to write the address
 		// Make sure to clip them in the right range
 		switch (_type) {
-		case kOpl2:
+		case Config::kOpl2:
 			_reg.normal = _handler->writeAddr(port, val) & 0xff;
 			break;
-		case kOpl3:
+		case Config::kOpl3:
 			_reg.normal = _handler->writeAddr(port, val) & 0x1ff;
 			break;
-		case kDualOpl2:
+		case Config::kDualOpl2:
 			// Not a 0x?88 port, when write to a specific side
 			if (!(port & 0x8)) {
 				byte index = (port & 2) >> 1;
@@ -283,16 +283,16 @@
 
 byte OPL::read(int port) {
 	switch (_type) {
-	case kOpl2:
+	case Config::kOpl2:
 		if (!(port & 1))
 			//Make sure the low bits are 6 on opl2
 			return _chip[0].read() | 0x6;
 		break;
-	case kOpl3:
+	case Config::kOpl3:
 		if (!(port & 1))
 			return _chip[0].read();
 		break;
-	case kDualOpl2:
+	case Config::kDualOpl2:
 		// Only return for the lower ports
 		if (port & 1)
 			return 0xff;
@@ -305,9 +305,9 @@
 void OPL::writeReg(int r, int v) {
 	byte tempReg = 0;
 	switch (_type) {
-	case kOpl2:
-	case kDualOpl2:
-	case kOpl3:
+	case Config::kOpl2:
+	case Config::kDualOpl2:
+	case Config::kOpl3:
 		// We can't use _handler->writeReg here directly, since it would miss timer changes.
 
 		// Backup old setup register
@@ -350,7 +350,7 @@
 void OPL::readBuffer(int16 *buffer, int length) {
 	// For stereo OPL cards, we divide the sample count by 2,
 	// to match stereo AudioStream behavior.
-	if (_type != kOpl2)
+	if (_type != Config::kOpl2)
 		length >>= 1;
 
 	_handler->generate(buffer, length);

Modified: scummvm/trunk/sound/softsynth/opl/dosbox.h
===================================================================
--- scummvm/trunk/sound/softsynth/opl/dosbox.h	2009-05-12 18:21:32 UTC (rev 40495)
+++ scummvm/trunk/sound/softsynth/opl/dosbox.h	2009-05-12 18:42:44 UTC (rev 40496)
@@ -85,7 +85,7 @@
 
 class OPL : public ::OPL::OPL {
 private:
-	kOplType _type;
+	Config::OplType _type;
 	uint _rate;
 
 	Handler *_handler;
@@ -98,7 +98,7 @@
 	void free();
 	void dualWrite(uint8 index, uint8 reg, uint8 val);
 public:
-	OPL(kOplType type);
+	OPL(Config::OplType type);
 	~OPL();
 
 	bool init(int rate);
@@ -110,7 +110,7 @@
 	void writeReg(int r, int v);
 
 	void readBuffer(int16 *buffer, int length);
-	bool isStereo() const { return _type != kOpl2; }
+	bool isStereo() const { return _type != Config::kOpl2; }
 };
 
 } // end of namespace DOSBox


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list