[Scummvm-cvs-logs] SF.net SVN: scummvm:[49758] scummvm/trunk/engines/agi

sev at users.sourceforge.net sev at users.sourceforge.net
Tue Jun 15 12:38:39 CEST 2010


Revision: 49758
          http://scummvm.svn.sourceforge.net/scummvm/?rev=49758&view=rev
Author:   sev
Date:     2010-06-15 10:38:39 +0000 (Tue, 15 Jun 2010)

Log Message:
-----------
AGI: rearranged class methods a bit and cleanup.

Modified Paths:
--------------
    scummvm/trunk/engines/agi/sound.cpp
    scummvm/trunk/engines/agi/sound_2gs.cpp

Modified: scummvm/trunk/engines/agi/sound.cpp
===================================================================
--- scummvm/trunk/engines/agi/sound.cpp	2010-06-15 10:36:54 UTC (rev 49757)
+++ scummvm/trunk/engines/agi/sound.cpp	2010-06-15 10:38:39 UTC (rev 49758)
@@ -31,18 +31,6 @@
 #include "agi/sound_sarien.h"
 #include "agi/sound_pcjr.h"
 
-#if 0
-#include "common/md5.h"
-#include "common/config-manager.h"
-#include "common/fs.h"
-#include "common/random.h"
-#include "common/str-array.h"
-
-#include "sound/mididrv.h"
-
-
-#endif
-
 namespace Agi {
 
 //

Modified: scummvm/trunk/engines/agi/sound_2gs.cpp
===================================================================
--- scummvm/trunk/engines/agi/sound_2gs.cpp	2010-06-15 10:36:54 UTC (rev 49757)
+++ scummvm/trunk/engines/agi/sound_2gs.cpp	2010-06-15 10:38:39 UTC (rev 49758)
@@ -181,19 +181,6 @@
 	return IIGS_BUFFER_SIZE;
 }
 
-/**
- * Convert sample from 8-bit unsigned to 8-bit signed format.
- * @param source  Source stream containing the 8-bit unsigned sample data.
- * @param dest  Destination buffer for the 8-bit signed sample data.
- * @param length  Length of the sample data to be converted.
- */
-static bool convertWave(Common::SeekableReadStream &source, int8 *dest, uint length) {
-	// Convert the wave from 8-bit unsigned to 8-bit signed format
-	for (uint i = 0; i < length; i++)
-		dest[i] = (int8) ((int) source.readByte() - 128);
-	return !(source.eos() || source.err());
-}
-
 void SoundGen2GS::fillAudio(int16 *stream, uint len) {
 	uint32 p = 0;
 
@@ -221,220 +208,6 @@
 	data_available -= len;
 }
 
-IIgsMidi::IIgsMidi(uint8 *data, uint32 len, int resnum, SoundMgr &manager) : AgiSound(manager) {
-	_data = data; // Save the resource pointer
-	_ptr = _data + 2; // Set current position to just after the header
-	_len  = len;  // Save the resource's length
-	_type = READ_LE_UINT16(data); // Read sound resource's type
-	_midiTicks = _soundBufTicks = 0;
-	_isValid = (_type == AGI_SOUND_MIDI) && (_data != NULL) && (_len >= 2);
-
-	if (!_isValid) // Check for errors
-		warning("Error creating Apple IIGS midi sound from resource %d (Type %d, length %d)", resnum, _type, len);
-}
-
-IIgsSample::IIgsSample(uint8 *data, uint32 len, int resnum, SoundMgr &manager) : AgiSound(manager) {
-	Common::MemoryReadStream stream(data, len, DisposeAfterUse::YES);
-
-	// Check that the header was read ok and that it's of the correct type
-	if (_header.read(stream) && _header.type == AGI_SOUND_SAMPLE) { // An Apple IIGS AGI sample resource
-		uint32 sampleStartPos = stream.pos();
-		uint32 tailLen = stream.size() - sampleStartPos;
-
-		if (tailLen < _header.sampleSize) { // Check if there's no room for the sample data in the stream
-			// Apple IIGS Manhunter I: Sound resource 16 has only 16074 bytes
-			// of sample data although header says it should have 16384 bytes.
-			warning("Apple IIGS sample (%d) too short (%d bytes. Should be %d bytes). Using the part that's left",
-				resnum, tailLen, _header.sampleSize);
-
-			_header.sampleSize = (uint16) tailLen; // Use the part that's left
-		}
-
-		if (_header.pitch > 0x7F) { // Check if the pitch is invalid
-			warning("Apple IIGS sample (%d) has too high pitch (0x%02x)", resnum, _header.pitch);
-
-			_header.pitch &= 0x7F; // Apple IIGS AGI probably did it this way too
-		}
-
-		// Finalize the header info using the 8-bit unsigned sample data
-		_header.finalize(stream);
-
-		// Convert sample data from 8-bit unsigned to 8-bit signed format
-		stream.seek(sampleStartPos);
-		_sample = new int8[_header.sampleSize];
-
-		if (_sample != NULL)
-			_isValid = convertWave(stream, _sample, _header.sampleSize);
-	}
-
-	if (!_isValid) // Check for errors
-		warning("Error creating Apple IIGS sample from resource %d (Type %d, length %d)", resnum, _header.type, len);
-}
-
-/** Reads an Apple IIGS envelope from then given stream. */
-bool IIgsEnvelope::read(Common::SeekableReadStream &stream) {
-	for (int segNum = 0; segNum < ENVELOPE_SEGMENT_COUNT; segNum++) {
-		seg[segNum].bp  = stream.readByte();
-		seg[segNum].inc = stream.readUint16LE();
-	}
-
-	return !(stream.eos() || stream.err());
-}
-
-/** Reads an Apple IIGS wave information structure from the given stream. */
-bool IIgsWaveInfo::read(Common::SeekableReadStream &stream, bool ignoreAddr) {
-	top  = stream.readByte();
-	addr = stream.readByte() * 256;
-	size = (1 << (stream.readByte() & 7)) * 256;
-
-	// Read packed mode byte and parse it into parts
-	byte packedModeByte = stream.readByte();
-	channel = (packedModeByte >> 4) & 1; // Bit 4
-	mode    = (packedModeByte >> 1) & 3; // Bits 1-2
-	halt    = (packedModeByte & 1) != 0; // Bit 0 (Converted to boolean)
-
-	relPitch = stream.readSint16LE();
-
-	// Zero the wave address if we want to ignore the wave address info
-	if (ignoreAddr)
-		addr = 0;
-
-	return !(stream.eos() || stream.err());
-}
-
-bool IIgsWaveInfo::finalize(Common::SeekableReadStream &uint8Wave) {
-	uint32 startPos = uint8Wave.pos(); // Save stream's starting position
-	uint8Wave.seek(addr, SEEK_CUR); // Seek to wave's address
-
-	// Calculate the true sample size (A zero ends the sample prematurely)
-	uint trueSize = size; // Set a default value for the result
-	for (uint i = 0; i < size; i++) {
-		if (uint8Wave.readByte() == 0) {
-			trueSize = i;
-			// A zero in the sample stream turns off looping
-			// (At least that's what MESS 0.117 and KEGS32 0.91 seem to do)
-			if (mode == OSC_MODE_LOOP)
-				mode = OSC_MODE_ONESHOT;
-			break;
-		}
-	}
-	size = trueSize; // Set the true sample size
-
-	uint8Wave.seek(startPos); // Seek back to the stream's starting position
-
-	return true;
-}
-
-bool IIgsOscillator::finalize(Common::SeekableReadStream &uint8Wave) {
-	for (uint i = 0; i < WAVES_PER_OSCILLATOR; i++)
-		if (!waves[i].finalize(uint8Wave))
-			return false;
-
-	return true;
-}
-
-bool IIgsOscillatorList::read(Common::SeekableReadStream &stream, uint oscillatorCount, bool ignoreAddr) {
-	// First read the A waves and then the B waves for the oscillators
-	for (uint waveNum = 0; waveNum < WAVES_PER_OSCILLATOR; waveNum++)
-		for (uint oscNum = 0; oscNum < oscillatorCount; oscNum++)
-			if (!osc[oscNum].waves[waveNum].read(stream, ignoreAddr))
-				return false;
-
-	count = oscillatorCount; // Set the oscillator count
-
-	return true;
-}
-
-bool IIgsOscillatorList::finalize(Common::SeekableReadStream &uint8Wave) {
-	for (uint i = 0; i < count; i++)
-		if (!osc[i].finalize(uint8Wave))
-			return false;
-
-	return true;
-}
-
-bool IIgsInstrumentHeader::read(Common::SeekableReadStream &stream, bool ignoreAddr) {
-	env.read(stream);
-	relseg        = stream.readByte();
-	/*byte priority =*/ stream.readByte(); // Not needed? 32 in all tested data.
-	bendrange     = stream.readByte();
-	vibdepth      = stream.readByte();
-	vibspeed      = stream.readByte();
-	/*byte spare    =*/ stream.readByte(); // Not needed? 0 in all tested data.
-	byte wac      = stream.readByte(); // Read A wave count
-	byte wbc      = stream.readByte(); // Read B wave count
-	oscList.read(stream, wac, ignoreAddr); // Read the oscillators
-	return (wac == wbc) && !(stream.eos() || stream.err()); // A and B wave counts must match
-}
-
-bool IIgsInstrumentHeader::finalize(Common::SeekableReadStream &uint8Wave) {
-	return oscList.finalize(uint8Wave);
-}
-
-bool IIgsSampleHeader::read(Common::SeekableReadStream &stream) {
-	type             = stream.readUint16LE();
-	pitch            = stream.readByte();
-	unknownByte_Ofs3 = stream.readByte();
-	volume           = stream.readByte();
-	unknownByte_Ofs5 = stream.readByte();
-	instrumentSize   = stream.readUint16LE();
-	sampleSize       = stream.readUint16LE();
-	// Read the instrument header *ignoring* its wave address info
-
-	return instrument.read(stream, true);
-}
-
-bool IIgsSampleHeader::finalize(Common::SeekableReadStream &uint8Wave) {
-	return instrument.finalize(uint8Wave);
-}
-
-/** Older Apple IIGS AGI MIDI program change to instrument number mapping. */
-static const MidiProgramChangeMapping progToInstMappingV1 = {
-	{19, 20, 22, 23, 21, 24, 5, 5, 5, 5,
-	6, 7, 10, 9, 11, 9, 15, 8, 5, 5,
-	17, 16, 18, 12, 14, 5, 5, 5, 5, 5,
-	0, 1, 2, 9, 3, 4, 15, 2, 2, 2,
-	25, 13, 13, 25},
-	5
-};
-
-/** Newer Apple IIGS AGI MIDI program change to instrument number mapping. */
-static const MidiProgramChangeMapping progToInstMappingV2 = {
-	{21, 22, 24, 25, 23, 26, 6, 6, 6, 6,
-	7, 9, 12, 8, 13, 11, 17, 10, 6, 6,
-	19, 18, 20, 14, 16, 6, 6, 6, 6, 6,
-	0, 1, 2, 4, 3, 5, 17, 2, 2, 2,
-	27, 15, 15, 27},
-	6
-};
-
-/** Older Apple IIGS AGI instrument set. Used only by Space Quest I (AGI v1.002). */
-static const InstrumentSetInfo instSetV1 = {
-	1192, 26, "7ee16bbc135171ffd6b9120cc7ff1af2", "edd3bf8905d9c238e02832b732fb2e18", progToInstMappingV1
-};
-
-/** Newer Apple IIGS AGI instrument set (AGI v1.003+). Used by all others than Space Quest I. */
-static const InstrumentSetInfo instSetV2 = {
-	1292, 28, "b7d428955bb90721996de1cbca25e768", "c05fb0b0e11deefab58bc68fbd2a3d07", progToInstMappingV2
-};
-
-/** Information about different Apple IIGS AGI executables. */
-static const IIgsExeInfo IIgsExeInfos[] = {
-	{GID_SQ1,      "SQ",   0x1002, 138496, 0x80AD, instSetV1},
-	{GID_LSL1,     "LL",   0x1003, 141003, 0x844E, instSetV2},
-	{GID_AGIDEMO,  "DEMO", 0x1005, 141884, 0x8469, instSetV2},
-	{GID_KQ1,      "KQ",   0x1006, 141894, 0x8469, instSetV2},
-	{GID_PQ1,      "PQ",   0x1007, 141882, 0x8469, instSetV2},
-	{GID_MIXEDUP,  "MG",   0x1013, 142552, 0x84B7, instSetV2},
-	{GID_KQ2,      "KQ2",  0x1013, 143775, 0x84B7, instSetV2},
-	{GID_KQ3,      "KQ3",  0x1014, 144312, 0x84B7, instSetV2},
-	{GID_SQ2,      "SQ2",  0x1014, 107882, 0x6563, instSetV2},
-	{GID_MH1,      "MH",   0x2004, 147678, 0x8979, instSetV2},
-	{GID_KQ4,      "KQ4",  0x2006, 147652, 0x8979, instSetV2},
-	{GID_BC,       "BC",   0x3001, 148192, 0x8979, instSetV2},
-	{GID_GOLDRUSH, "GR",   0x3003, 148268, 0x8979, instSetV2}
-};
-
 void SoundGen2GS::playSampleSound() {
 	if (_vm->_soundemu != SOUND_EMU_APPLE2GS) {
 		warning("Trying to play a sample but not using Apple IIGS sound emulation mode");
@@ -462,14 +235,6 @@
 	return true;
 }
 
-void IIgsMidiChannel::stopSounds() {
-	// Stops all sounds on this single MIDI channel
-	for (iterator iter = _gsChannels.begin(); iter != _gsChannels.end(); ++iter)
-		iter->stop();
-
-	_gsChannels.clear();
-}
-
 void SoundGen2GS::playMidiSound() {
 	if (_disabledMidi)
 		return;
@@ -625,12 +390,6 @@
 		iter->removeStoppedSounds();
 }
 
-void IIgsMidiChannel::removeStoppedSounds() {
-	for (int i = _gsChannels.size() - 1; i >= 0; i--)
-		if (!_gsChannels[i].playing())
-			_gsChannels.remove_at(i);
-}
-
 uint SoundGen2GS::activeSounds() const {
 	uint result = 0;
 
@@ -640,6 +399,200 @@
 	return result;
 }
 
+IIgsMidi::IIgsMidi(uint8 *data, uint32 len, int resnum, SoundMgr &manager) : AgiSound(manager) {
+	_data = data; // Save the resource pointer
+	_ptr = _data + 2; // Set current position to just after the header
+	_len  = len;  // Save the resource's length
+	_type = READ_LE_UINT16(data); // Read sound resource's type
+	_midiTicks = _soundBufTicks = 0;
+	_isValid = (_type == AGI_SOUND_MIDI) && (_data != NULL) && (_len >= 2);
+
+	if (!_isValid) // Check for errors
+		warning("Error creating Apple IIGS midi sound from resource %d (Type %d, length %d)", resnum, _type, len);
+}
+
+/**
+ * Convert sample from 8-bit unsigned to 8-bit signed format.
+ * @param source  Source stream containing the 8-bit unsigned sample data.
+ * @param dest  Destination buffer for the 8-bit signed sample data.
+ * @param length  Length of the sample data to be converted.
+ */
+static bool convertWave(Common::SeekableReadStream &source, int8 *dest, uint length) {
+	// Convert the wave from 8-bit unsigned to 8-bit signed format
+	for (uint i = 0; i < length; i++)
+		dest[i] = (int8) ((int) source.readByte() - 128);
+	return !(source.eos() || source.err());
+}
+
+IIgsSample::IIgsSample(uint8 *data, uint32 len, int resnum, SoundMgr &manager) : AgiSound(manager) {
+	Common::MemoryReadStream stream(data, len, DisposeAfterUse::YES);
+
+	// Check that the header was read ok and that it's of the correct type
+	if (_header.read(stream) && _header.type == AGI_SOUND_SAMPLE) { // An Apple IIGS AGI sample resource
+		uint32 sampleStartPos = stream.pos();
+		uint32 tailLen = stream.size() - sampleStartPos;
+
+		if (tailLen < _header.sampleSize) { // Check if there's no room for the sample data in the stream
+			// Apple IIGS Manhunter I: Sound resource 16 has only 16074 bytes
+			// of sample data although header says it should have 16384 bytes.
+			warning("Apple IIGS sample (%d) too short (%d bytes. Should be %d bytes). Using the part that's left",
+				resnum, tailLen, _header.sampleSize);
+
+			_header.sampleSize = (uint16) tailLen; // Use the part that's left
+		}
+
+		if (_header.pitch > 0x7F) { // Check if the pitch is invalid
+			warning("Apple IIGS sample (%d) has too high pitch (0x%02x)", resnum, _header.pitch);
+
+			_header.pitch &= 0x7F; // Apple IIGS AGI probably did it this way too
+		}
+
+		// Finalize the header info using the 8-bit unsigned sample data
+		_header.finalize(stream);
+
+		// Convert sample data from 8-bit unsigned to 8-bit signed format
+		stream.seek(sampleStartPos);
+		_sample = new int8[_header.sampleSize];
+
+		if (_sample != NULL)
+			_isValid = convertWave(stream, _sample, _header.sampleSize);
+	}
+
+	if (!_isValid) // Check for errors
+		warning("Error creating Apple IIGS sample from resource %d (Type %d, length %d)", resnum, _header.type, len);
+}
+
+/** Reads an Apple IIGS envelope from then given stream. */
+bool IIgsEnvelope::read(Common::SeekableReadStream &stream) {
+	for (int segNum = 0; segNum < ENVELOPE_SEGMENT_COUNT; segNum++) {
+		seg[segNum].bp  = stream.readByte();
+		seg[segNum].inc = stream.readUint16LE();
+	}
+
+	return !(stream.eos() || stream.err());
+}
+
+/** Reads an Apple IIGS wave information structure from the given stream. */
+bool IIgsWaveInfo::read(Common::SeekableReadStream &stream, bool ignoreAddr) {
+	top  = stream.readByte();
+	addr = stream.readByte() * 256;
+	size = (1 << (stream.readByte() & 7)) * 256;
+
+	// Read packed mode byte and parse it into parts
+	byte packedModeByte = stream.readByte();
+	channel = (packedModeByte >> 4) & 1; // Bit 4
+	mode    = (packedModeByte >> 1) & 3; // Bits 1-2
+	halt    = (packedModeByte & 1) != 0; // Bit 0 (Converted to boolean)
+
+	relPitch = stream.readSint16LE();
+
+	// Zero the wave address if we want to ignore the wave address info
+	if (ignoreAddr)
+		addr = 0;
+
+	return !(stream.eos() || stream.err());
+}
+
+bool IIgsWaveInfo::finalize(Common::SeekableReadStream &uint8Wave) {
+	uint32 startPos = uint8Wave.pos(); // Save stream's starting position
+	uint8Wave.seek(addr, SEEK_CUR); // Seek to wave's address
+
+	// Calculate the true sample size (A zero ends the sample prematurely)
+	uint trueSize = size; // Set a default value for the result
+	for (uint i = 0; i < size; i++) {
+		if (uint8Wave.readByte() == 0) {
+			trueSize = i;
+			// A zero in the sample stream turns off looping
+			// (At least that's what MESS 0.117 and KEGS32 0.91 seem to do)
+			if (mode == OSC_MODE_LOOP)
+				mode = OSC_MODE_ONESHOT;
+			break;
+		}
+	}
+	size = trueSize; // Set the true sample size
+
+	uint8Wave.seek(startPos); // Seek back to the stream's starting position
+
+	return true;
+}
+
+bool IIgsOscillator::finalize(Common::SeekableReadStream &uint8Wave) {
+	for (uint i = 0; i < WAVES_PER_OSCILLATOR; i++)
+		if (!waves[i].finalize(uint8Wave))
+			return false;
+
+	return true;
+}
+
+bool IIgsOscillatorList::read(Common::SeekableReadStream &stream, uint oscillatorCount, bool ignoreAddr) {
+	// First read the A waves and then the B waves for the oscillators
+	for (uint waveNum = 0; waveNum < WAVES_PER_OSCILLATOR; waveNum++)
+		for (uint oscNum = 0; oscNum < oscillatorCount; oscNum++)
+			if (!osc[oscNum].waves[waveNum].read(stream, ignoreAddr))
+				return false;
+
+	count = oscillatorCount; // Set the oscillator count
+
+	return true;
+}
+
+bool IIgsOscillatorList::finalize(Common::SeekableReadStream &uint8Wave) {
+	for (uint i = 0; i < count; i++)
+		if (!osc[i].finalize(uint8Wave))
+			return false;
+
+	return true;
+}
+
+bool IIgsInstrumentHeader::read(Common::SeekableReadStream &stream, bool ignoreAddr) {
+	env.read(stream);
+	relseg        = stream.readByte();
+	/*byte priority =*/ stream.readByte(); // Not needed? 32 in all tested data.
+	bendrange     = stream.readByte();
+	vibdepth      = stream.readByte();
+	vibspeed      = stream.readByte();
+	/*byte spare    =*/ stream.readByte(); // Not needed? 0 in all tested data.
+	byte wac      = stream.readByte(); // Read A wave count
+	byte wbc      = stream.readByte(); // Read B wave count
+	oscList.read(stream, wac, ignoreAddr); // Read the oscillators
+	return (wac == wbc) && !(stream.eos() || stream.err()); // A and B wave counts must match
+}
+
+bool IIgsInstrumentHeader::finalize(Common::SeekableReadStream &uint8Wave) {
+	return oscList.finalize(uint8Wave);
+}
+
+bool IIgsSampleHeader::read(Common::SeekableReadStream &stream) {
+	type             = stream.readUint16LE();
+	pitch            = stream.readByte();
+	unknownByte_Ofs3 = stream.readByte();
+	volume           = stream.readByte();
+	unknownByte_Ofs5 = stream.readByte();
+	instrumentSize   = stream.readUint16LE();
+	sampleSize       = stream.readUint16LE();
+	// Read the instrument header *ignoring* its wave address info
+
+	return instrument.read(stream, true);
+}
+
+bool IIgsSampleHeader::finalize(Common::SeekableReadStream &uint8Wave) {
+	return instrument.finalize(uint8Wave);
+}
+
+void IIgsMidiChannel::stopSounds() {
+	// Stops all sounds on this single MIDI channel
+	for (iterator iter = _gsChannels.begin(); iter != _gsChannels.end(); ++iter)
+		iter->stop();
+
+	_gsChannels.clear();
+}
+
+void IIgsMidiChannel::removeStoppedSounds() {
+	for (int i = _gsChannels.size() - 1; i >= 0; i--)
+		if (!_gsChannels[i].playing())
+			_gsChannels.remove_at(i);
+}
+
 uint IIgsMidiChannel::activeSounds() const {
 	uint result = 0;
 
@@ -741,6 +694,129 @@
 }
 
 /**
+ * A function object (i.e. a functor) for testing if a Common::FSNode
+ * object's name is equal (Ignoring case) to a string or to at least
+ * one of the strings in a list of strings. Can be used e.g. with find_if().
+ */
+struct fsnodeNameEqualsIgnoreCase : public Common::UnaryFunction<const Common::FSNode&, bool> {
+// FIXME: This should be replaced; use SearchMan instead
+	fsnodeNameEqualsIgnoreCase(const Common::StringArray &str) : _str(str) {}
+	fsnodeNameEqualsIgnoreCase(const Common::String str) { _str.push_back(str); }
+	bool operator()(const Common::FSNode &param) const {
+		for (Common::StringArray::const_iterator iter = _str.begin(); iter != _str.end(); ++iter)
+			if (param.getName().equalsIgnoreCase(*iter))
+				return true;
+		return false;
+	}
+private:
+	Common::StringArray _str;
+};
+
+bool SoundGen2GS::loadInstruments() {
+	// Check that the platform is Apple IIGS, as only it uses custom instruments
+	if (_vm->getPlatform() != Common::kPlatformApple2GS) {
+		debugC(3, kDebugLevelSound, "Platform isn't Apple IIGS so not loading any instruments");
+		return true;
+	}
+
+	// Get info on the particular Apple IIGS AGI game's executable
+	const IIgsExeInfo *exeInfo = getIIgsExeInfo((enum AgiGameID) _vm->getGameID());
+	if (exeInfo == NULL) {
+		warning("Unsupported Apple IIGS game, not loading instruments");
+		return false;
+	}
+
+	// List files in the game path
+	Common::FSList fslist;
+	Common::FSNode dir(ConfMan.get("path"));
+	if (!dir.getChildren(fslist, Common::FSNode::kListFilesOnly)) {
+		warning("Invalid game path (\"%s\"), not loading Apple IIGS instruments", dir.getPath().c_str());
+		return false;
+	}
+
+	// Populate executable filenames list (Long filename and short filename) for searching
+	Common::StringArray exeNames;
+	exeNames.push_back(Common::String(exeInfo->exePrefix) + ".SYS16");
+	exeNames.push_back(Common::String(exeInfo->exePrefix) + ".SYS");
+
+	// Populate wave filenames list (Long filename and short filename) for searching
+	Common::StringArray waveNames;
+	waveNames.push_back("SIERRASTANDARD");
+	waveNames.push_back("SIERRAST");
+
+	// Search for the executable file and the wave file (i.e. check if any of the filenames match)
+	Common::FSList::const_iterator exeFsnode, waveFsnode;
+	exeFsnode  = Common::find_if(fslist.begin(), fslist.end(), fsnodeNameEqualsIgnoreCase(exeNames));
+	waveFsnode = Common::find_if(fslist.begin(), fslist.end(), fsnodeNameEqualsIgnoreCase(waveNames));
+
+	// Make sure that we found the executable file
+	if (exeFsnode == fslist.end()) {
+		warning("Couldn't find Apple IIGS game executable (%s), not loading instruments", exeNames.begin()->c_str());
+		return false;
+	}
+
+	// Make sure that we found the wave file
+	if (waveFsnode == fslist.end()) {
+		warning("Couldn't find Apple IIGS wave file (%s), not loading instruments", waveNames.begin()->c_str());
+		return false;
+	}
+
+	// Set the MIDI program change to instrument number mapping and
+	// load the instrument headers and their sample data.
+	// None of the tested SIERRASTANDARD-files have zeroes in them so
+	// there's no need to check for prematurely ending samples here.
+	setProgramChangeMapping(&exeInfo->instSet.progToInst);
+	return loadWaveFile(*waveFsnode, *exeInfo) && loadInstrumentHeaders(*exeFsnode, *exeInfo);
+}
+
+/** Older Apple IIGS AGI MIDI program change to instrument number mapping. */
+static const MidiProgramChangeMapping progToInstMappingV1 = {
+	{19, 20, 22, 23, 21, 24, 5, 5, 5, 5,
+	6, 7, 10, 9, 11, 9, 15, 8, 5, 5,
+	17, 16, 18, 12, 14, 5, 5, 5, 5, 5,
+	0, 1, 2, 9, 3, 4, 15, 2, 2, 2,
+	25, 13, 13, 25},
+	5
+};
+
+/** Newer Apple IIGS AGI MIDI program change to instrument number mapping. */
+static const MidiProgramChangeMapping progToInstMappingV2 = {
+	{21, 22, 24, 25, 23, 26, 6, 6, 6, 6,
+	7, 9, 12, 8, 13, 11, 17, 10, 6, 6,
+	19, 18, 20, 14, 16, 6, 6, 6, 6, 6,
+	0, 1, 2, 4, 3, 5, 17, 2, 2, 2,
+	27, 15, 15, 27},
+	6
+};
+
+/** Older Apple IIGS AGI instrument set. Used only by Space Quest I (AGI v1.002). */
+static const InstrumentSetInfo instSetV1 = {
+	1192, 26, "7ee16bbc135171ffd6b9120cc7ff1af2", "edd3bf8905d9c238e02832b732fb2e18", progToInstMappingV1
+};
+
+/** Newer Apple IIGS AGI instrument set (AGI v1.003+). Used by all others than Space Quest I. */
+static const InstrumentSetInfo instSetV2 = {
+	1292, 28, "b7d428955bb90721996de1cbca25e768", "c05fb0b0e11deefab58bc68fbd2a3d07", progToInstMappingV2
+};
+
+/** Information about different Apple IIGS AGI executables. */
+static const IIgsExeInfo IIgsExeInfos[] = {
+	{GID_SQ1,      "SQ",   0x1002, 138496, 0x80AD, instSetV1},
+	{GID_LSL1,     "LL",   0x1003, 141003, 0x844E, instSetV2},
+	{GID_AGIDEMO,  "DEMO", 0x1005, 141884, 0x8469, instSetV2},
+	{GID_KQ1,      "KQ",   0x1006, 141894, 0x8469, instSetV2},
+	{GID_PQ1,      "PQ",   0x1007, 141882, 0x8469, instSetV2},
+	{GID_MIXEDUP,  "MG",   0x1013, 142552, 0x84B7, instSetV2},
+	{GID_KQ2,      "KQ2",  0x1013, 143775, 0x84B7, instSetV2},
+	{GID_KQ3,      "KQ3",  0x1014, 144312, 0x84B7, instSetV2},
+	{GID_SQ2,      "SQ2",  0x1014, 107882, 0x6563, instSetV2},
+	{GID_MH1,      "MH",   0x2004, 147678, 0x8979, instSetV2},
+	{GID_KQ4,      "KQ4",  0x2006, 147652, 0x8979, instSetV2},
+	{GID_BC,       "BC",   0x3001, 148192, 0x8979, instSetV2},
+	{GID_GOLDRUSH, "GR",   0x3003, 148268, 0x8979, instSetV2}
+};
+
+/**
  * Finds information about an Apple IIGS AGI executable based on the game ID.
  * @return A non-null IIgsExeInfo pointer if successful, otherwise NULL.
  */
@@ -840,80 +916,4 @@
 	}
 }
 
-/**
- * A function object (i.e. a functor) for testing if a Common::FSNode
- * object's name is equal (Ignoring case) to a string or to at least
- * one of the strings in a list of strings. Can be used e.g. with find_if().
- */
-struct fsnodeNameEqualsIgnoreCase : public Common::UnaryFunction<const Common::FSNode&, bool> {
-// FIXME: This should be replaced; use SearchMan instead
-	fsnodeNameEqualsIgnoreCase(const Common::StringArray &str) : _str(str) {}
-	fsnodeNameEqualsIgnoreCase(const Common::String str) { _str.push_back(str); }
-	bool operator()(const Common::FSNode &param) const {
-		for (Common::StringArray::const_iterator iter = _str.begin(); iter != _str.end(); ++iter)
-			if (param.getName().equalsIgnoreCase(*iter))
-				return true;
-		return false;
-	}
-private:
-	Common::StringArray _str;
-};
-
-bool SoundGen2GS::loadInstruments() {
-	// Check that the platform is Apple IIGS, as only it uses custom instruments
-	if (_vm->getPlatform() != Common::kPlatformApple2GS) {
-		debugC(3, kDebugLevelSound, "Platform isn't Apple IIGS so not loading any instruments");
-		return true;
-	}
-
-	// Get info on the particular Apple IIGS AGI game's executable
-	const IIgsExeInfo *exeInfo = getIIgsExeInfo((enum AgiGameID) _vm->getGameID());
-	if (exeInfo == NULL) {
-		warning("Unsupported Apple IIGS game, not loading instruments");
-		return false;
-	}
-
-	// List files in the game path
-	Common::FSList fslist;
-	Common::FSNode dir(ConfMan.get("path"));
-	if (!dir.getChildren(fslist, Common::FSNode::kListFilesOnly)) {
-		warning("Invalid game path (\"%s\"), not loading Apple IIGS instruments", dir.getPath().c_str());
-		return false;
-	}
-
-	// Populate executable filenames list (Long filename and short filename) for searching
-	Common::StringArray exeNames;
-	exeNames.push_back(Common::String(exeInfo->exePrefix) + ".SYS16");
-	exeNames.push_back(Common::String(exeInfo->exePrefix) + ".SYS");
-
-	// Populate wave filenames list (Long filename and short filename) for searching
-	Common::StringArray waveNames;
-	waveNames.push_back("SIERRASTANDARD");
-	waveNames.push_back("SIERRAST");
-
-	// Search for the executable file and the wave file (i.e. check if any of the filenames match)
-	Common::FSList::const_iterator exeFsnode, waveFsnode;
-	exeFsnode  = Common::find_if(fslist.begin(), fslist.end(), fsnodeNameEqualsIgnoreCase(exeNames));
-	waveFsnode = Common::find_if(fslist.begin(), fslist.end(), fsnodeNameEqualsIgnoreCase(waveNames));
-
-	// Make sure that we found the executable file
-	if (exeFsnode == fslist.end()) {
-		warning("Couldn't find Apple IIGS game executable (%s), not loading instruments", exeNames.begin()->c_str());
-		return false;
-	}
-
-	// Make sure that we found the wave file
-	if (waveFsnode == fslist.end()) {
-		warning("Couldn't find Apple IIGS wave file (%s), not loading instruments", waveNames.begin()->c_str());
-		return false;
-	}
-
-	// Set the MIDI program change to instrument number mapping and
-	// load the instrument headers and their sample data.
-	// None of the tested SIERRASTANDARD-files have zeroes in them so
-	// there's no need to check for prematurely ending samples here.
-	setProgramChangeMapping(&exeInfo->instSet.progToInst);
-	return loadWaveFile(*waveFsnode, *exeInfo) && loadInstrumentHeaders(*exeFsnode, *exeInfo);
-}
-
 } // End of namespace Agi


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