[Scummvm-cvs-logs] SF.net SVN: scummvm: [26837] scummvm/trunk/engines/cine

cyx at users.sourceforge.net cyx at users.sourceforge.net
Sun May 13 18:11:20 CEST 2007


Revision: 26837
          http://scummvm.svn.sourceforge.net/scummvm/?rev=26837&view=rev
Author:   cyx
Date:     2007-05-13 09:11:19 -0700 (Sun, 13 May 2007)

Log Message:
-----------
added basic support for sounds playback in Amiga versions (only tested with the demos)

Modified Paths:
--------------
    scummvm/trunk/engines/cine/anim.cpp
    scummvm/trunk/engines/cine/cine.cpp
    scummvm/trunk/engines/cine/main_loop.cpp
    scummvm/trunk/engines/cine/script.cpp
    scummvm/trunk/engines/cine/script.h
    scummvm/trunk/engines/cine/sound_driver.cpp
    scummvm/trunk/engines/cine/sound_driver.h

Modified: scummvm/trunk/engines/cine/anim.cpp
===================================================================
--- scummvm/trunk/engines/cine/anim.cpp	2007-05-13 16:07:33 UTC (rev 26836)
+++ scummvm/trunk/engines/cine/anim.cpp	2007-05-13 16:11:19 UTC (rev 26837)
@@ -395,6 +395,18 @@
 	strcpy(animDataTable[entry].name, currentPartName);
 }
 
+void loadSplAbs(const char *resourceName, uint16 idx) {
+	int16 foundFileIdx;
+	byte *dataPtr;
+	int16 entry;
+
+	foundFileIdx = findFileInBundle(resourceName);
+	dataPtr = readBundleFile(foundFileIdx);
+
+	entry = reserveFrame((uint16) partBuffer[foundFileIdx].unpackedSize, 1, 0, idx);
+	memcpy(animDataTable[entry].ptr1, dataPtr, partBuffer[foundFileIdx].unpackedSize);
+}
+
 void loadMsk(const char *resourceName) {
 	int16 foundFileIdx;
 	byte *dataPtr;
@@ -877,6 +889,7 @@
 		loadSeqAbs(resourceName, idx);
 		return;
 	} else if (strstr(resourceName, ".SPL")) {
+		loadSplAbs(resourceName, idx);
 		return;
 	} else if (strstr(resourceName, ".AMI")) {
 		return;

Modified: scummvm/trunk/engines/cine/cine.cpp
===================================================================
--- scummvm/trunk/engines/cine/cine.cpp	2007-05-13 16:07:33 UTC (rev 26836)
+++ scummvm/trunk/engines/cine/cine.cpp	2007-05-13 16:11:19 UTC (rev 26837)
@@ -95,10 +95,15 @@
 	_system->initSize(320, 200);
 	_system->endGFXTransaction();
 
-	if (g_cine->getGameType() == GType_FW) {
-		g_soundDriver = new AdlibSoundDriverINS(_mixer);
+	if (g_cine->getPlatform() == Common::kPlatformPC) {
+		if (g_cine->getGameType() == GType_FW) {
+			g_soundDriver = new AdlibSoundDriverINS(_mixer);
+		} else {
+			g_soundDriver = new AdlibSoundDriverADL(_mixer);
+		}
 	} else {
-		g_soundDriver = new AdlibSoundDriverADL(_mixer);
+		// Paula chipset for Amiga and Atari versions
+		g_soundDriver = new PaulaSoundDriver(_mixer);
 	}
 	g_sfxPlayer = new SfxPlayer(g_soundDriver);
 	g_saveFileMan = _saveFileMan;

Modified: scummvm/trunk/engines/cine/main_loop.cpp
===================================================================
--- scummvm/trunk/engines/cine/main_loop.cpp	2007-05-13 16:07:33 UTC (rev 26836)
+++ scummvm/trunk/engines/cine/main_loop.cpp	2007-05-13 16:11:19 UTC (rev 26837)
@@ -32,6 +32,7 @@
 #include "cine/sfx_player.h"
 #include "cine/various.h"
 #include "cine/bg_list.h"
+#include "cine/sound_driver.h"
 
 namespace Cine {
 
@@ -156,6 +157,7 @@
 		if (i % 2)
 			g_system->updateScreen();
 		g_system->delayMillis(10);
+		g_soundDriver->update();
 		manageEvents(0);
 	}
 }

Modified: scummvm/trunk/engines/cine/script.cpp
===================================================================
--- scummvm/trunk/engines/cine/script.cpp	2007-05-13 16:07:33 UTC (rev 26836)
+++ scummvm/trunk/engines/cine/script.cpp	2007-05-13 16:11:19 UTC (rev 26837)
@@ -356,9 +356,9 @@
 		NULL,
 		NULL,
 		NULL,
-		o1_playSample,
+		o2_playSample,
 		/* 78 */
-		o2_op78,
+		o2_playSampleAlt,
 		o1_disableSystemMenu,
 		o1_loadMask5,
 		o1_unloadMask5,
@@ -1702,16 +1702,31 @@
 
 void o1_playMusic() {
 	debugC(5, kCineDebugScript, "Line: %d: playMusic()", _currentLine);
+	if (g_cine->getPlatform() == Common::kPlatformAmiga ||
+			g_cine->getPlatform() == Common::kPlatformAtariST) {
+		warning("STUB: o1_playMusic");
+		return;
+	}
 	g_sfxPlayer->play();
 }
 
 void o1_fadeOutMusic() {
 	debugC(5, kCineDebugScript, "Line: %d: fadeOutMusic()", _currentLine);
+	if (g_cine->getPlatform() == Common::kPlatformAmiga ||
+			g_cine->getPlatform() == Common::kPlatformAtariST) {
+		warning("STUB: o1_fadeOutMusic");
+		return;
+	}
 	g_sfxPlayer->fadeOut();
 }
 
 void o1_stopSample() {
 	debugC(5, kCineDebugScript, "Line: %d: stopSample()", _currentLine);
+	if (g_cine->getPlatform() == Common::kPlatformAmiga ||
+			g_cine->getPlatform() == Common::kPlatformAtariST) {
+		warning("STUB: o1_stopSample");
+		return;
+	}
 	g_sfxPlayer->stop();
 }
 
@@ -1737,9 +1752,46 @@
 	getNextWord();
 }
 
+void o1_playSampleAmiga() {
+	int num = getNextByte();
+	int channel = getNextByte();
+	int freq = getNextWord();
+	int repeat = getNextByte();
+	int volume = getNextWord();
+	int size = getNextWord();
+
+	if (size == 0xFFFF) {
+		size = animDataTable[num].width * animDataTable[num].height;
+	}
+	
+	if (channel < 10) { // || _currentOpcode == 0x78
+		int channel1, channel2;
+		if (channel == 0) {
+			channel1 = 0;
+			channel2 = 1;
+		} else {
+			channel1 = 2;
+			channel2 = 3;			
+		}
+		((PaulaSoundDriver *)g_soundDriver)->queueSound(channel1, freq, animDataTable[num].ptr1, size, -1, volume, 63, repeat);
+		((PaulaSoundDriver *)g_soundDriver)->queueSound(channel2, freq, animDataTable[num].ptr1, size,  1, volume,  0, repeat);
+	} else {
+		channel -= 10;
+		if (volume > 63) {
+			volume = 63;
+		}
+		((PaulaSoundDriver *)g_soundDriver)->queueSound(channel, freq, animDataTable[num].ptr1, size, 0, 0, volume, repeat);
+	}
+}
+
 void o1_playSample() {
 	debugC(5, kCineDebugScript, "Line: %d: playSample()", _currentLine);
 
+	if (g_cine->getPlatform() == Common::kPlatformAmiga || g_cine->getPlatform() == Common::kPlatformAtariST) {
+		o1_playSampleAmiga();
+		return;
+	}
+
 	byte anim = getNextByte();
 	byte channel = getNextByte();
 
@@ -1749,12 +1801,6 @@
 	int16 volume = getNextWord();
 	uint16 flag = getNextWord();
 
-	if (g_cine->getPlatform() == Common::kPlatformAmiga ||
-			g_cine->getPlatform() == Common::kPlatformAtariST) {
-		warning("STUB: o1_playSample");
-		return;
-	}
-
 	if (volume > 63)
 		volume = 63;
 	if (volume < 0)
@@ -1771,7 +1817,7 @@
 		g_sfxPlayer->stop();
 					
 		if (flag == 0xFFFF) {
-			g_soundDriver->playSound(animDataTable[anim].ptr1, channel, volume);
+			g_soundDriver->playSound(animDataTable[anim].ptr1, 0, channel, volume);
 		} else {
 			g_soundDriver->resetChannel(channel);
 		}
@@ -1809,12 +1855,37 @@
 	debugC(5, kCineDebugScript, "Line: %d: loadPart(\"%s\")", _currentLine, param);
 }
 
-void o2_op78() {
-	warning("STUB: o2_op78()");
-	// This is probably wrong, but preserve the old behaviour for now.
+void o2_playSample() {
+	if (g_cine->getPlatform() == Common::kPlatformAmiga || g_cine->getPlatform() == Common::kPlatformAtariST) {
+		// no-op in these versions
+		_currentPosition += 9;
+		return;
+	}
 	o1_playSample();
 }
 
+void o2_playSampleAlt() {
+	int num = getNextByte();
+	int channel = getNextByte();
+	int freq = getNextWord();
+	getNextByte();
+	getNextWord();
+	int size = getNextWord();
+
+	if (size == 0xFFFF) {
+		size = animDataTable[num].width * animDataTable[num].height;
+	}
+	if (animDataTable[num].ptr1) {
+		if (g_cine->getPlatform() == Common::kPlatformPC) {
+			// if speaker output is enabled, play sound on it
+			// if it's another device, don't play anything
+		} else {
+			g_soundDriver->setChannelFrequency(channel, freq);
+			g_soundDriver->playSound(animDataTable[num].ptr1, size, channel, 63);
+		}
+	}
+}
+
 void o2_addSeqListElement() {
 	byte param1 = getNextByte();
 	byte param2 = getNextByte();

Modified: scummvm/trunk/engines/cine/script.h
===================================================================
--- scummvm/trunk/engines/cine/script.h	2007-05-13 16:07:33 UTC (rev 26836)
+++ scummvm/trunk/engines/cine/script.h	2007-05-13 16:11:19 UTC (rev 26837)
@@ -146,7 +146,8 @@
 void o2_loadPart();
 void o2_addSeqListElement();
 void o2_removeSeq();
-void o2_op78(); 
+void o2_playSample();
+void o2_playSampleAlt();
 void o2_op81();
 void o2_op82();
 void o2_isSeqRunning();

Modified: scummvm/trunk/engines/cine/sound_driver.cpp
===================================================================
--- scummvm/trunk/engines/cine/sound_driver.cpp	2007-05-13 16:07:33 UTC (rev 26836)
+++ scummvm/trunk/engines/cine/sound_driver.cpp	2007-05-13 16:11:19 UTC (rev 26837)
@@ -283,7 +283,7 @@
 	}
 }
 
-void AdlibSoundDriverINS::playSound(const byte *data, int channel, int volume) {
+void AdlibSoundDriverINS::playSound(const byte *data, int size, int channel, int volume) {
 	assert(channel < 4);
 	_channelsVolumeTable[channel] = 127;
 	resetChannel(channel);
@@ -356,7 +356,7 @@
 	}
 }
 
-void AdlibSoundDriverADL::playSound(const byte *data, int channel, int volume) {
+void AdlibSoundDriverADL::playSound(const byte *data, int size, int channel, int volume) {
 	assert(channel < 4);
 	_channelsVolumeTable[channel] = 127;
 	setupInstrument(data, channel);
@@ -429,4 +429,71 @@
 
 const int AdlibSoundDriver::_voiceOperatorsTableCount = ARRAYSIZE(_voiceOperatorsTable);
 
+
+PaulaSoundDriver::PaulaSoundDriver(Audio::Mixer *mixer)
+	: _mixer(mixer) {
+	memset(_channelsFreqTable, 0, sizeof(_channelsFreqTable));
+	memset(_soundsQueue, 0, sizeof(_soundsQueue));
+}
+
+void PaulaSoundDriver::setupChannel(int channel, const byte *data, int instrument, int volume) {
+}
+
+void PaulaSoundDriver::setChannelFrequency(int channel, int frequency) {
+	assert(frequency > 0);
+	_channelsFreqTable[channel] = PAULA_FREQ / frequency;
+}
+
+void PaulaSoundDriver::stopChannel(int channel) {
+	_mixer->stopHandle(_channelsTable[channel]);
+}
+
+void PaulaSoundDriver::playSound(const byte *data, int size, int channel, int volume) {
+	stopChannel(channel);
+	size = MIN<int>(size - SPL_HDR_SIZE, READ_BE_UINT16(data + 4));
+	data += SPL_HDR_SIZE;
+	if (size > 0) {
+		_mixer->playRaw(Audio::Mixer::kSFXSoundType, &_channelsTable[channel], const_cast<byte *>(data), size, _channelsFreqTable[channel], 0);	
+		_mixer->setChannelVolume(_channelsTable[channel], volume * Audio::Mixer::kMaxChannelVolume / 63);
+	}
+}
+
+void PaulaSoundDriver::stopSound() {
+	for (int i = 0; i < NUM_CHANNELS; ++i) {
+		_mixer->stopHandle(_channelsTable[i]);
+	}
+}
+
+void PaulaSoundDriver::queueSound(int channel, int frequency, const uint8 *data, int size, int volumeStep, int stepCount, int volume, int repeat) {
+	SoundQueue *sq = &_soundsQueue[channel];
+	sq->freq = frequency;
+	sq->data = data;
+	sq->size = size;
+	sq->volumeStep = volumeStep;
+	sq->stepCount = stepCount;
+	sq->step = stepCount;
+	sq->repeat = repeat != 0;
+	sq->volume = volume;
+}
+
+void PaulaSoundDriver::update() {
+	// process volume slides and start sound playback
+	for (int i = 0; i < NUM_CHANNELS; ++i) {
+		SoundQueue *sq = &_soundsQueue[i];
+		if (sq->data) {
+			if (sq->step) {
+				--sq->step;
+				continue;
+			}
+			sq->step = sq->stepCount;
+			sq->volume = CLIP(sq->volume + sq->volumeStep, 0, 63);
+			setChannelFrequency(i, sq->freq);
+			playSound(sq->data, sq->size, i, sq->volume);
+			if (!sq->repeat) {
+				sq->data = 0;
+			}
+		}
+	}
+}
+
 } // End of namespace Cine

Modified: scummvm/trunk/engines/cine/sound_driver.h
===================================================================
--- scummvm/trunk/engines/cine/sound_driver.h	2007-05-13 16:07:33 UTC (rev 26836)
+++ scummvm/trunk/engines/cine/sound_driver.h	2007-05-13 16:11:19 UTC (rev 26837)
@@ -30,7 +30,7 @@
 #include "sound/mixer.h"
 
 namespace Cine {
-	
+
 class SoundDriver {
 public:
 	typedef void (*UpdateCallback)(void *);
@@ -40,9 +40,10 @@
 	virtual void setupChannel(int channel, const byte *data, int instrument, int volume) = 0;
 	virtual void setChannelFrequency(int channel, int frequency) = 0;
 	virtual void stopChannel(int channel) = 0;
-	virtual void playSound(const byte *data, int channel, int volume) = 0;
+	virtual void playSound(const byte *data, int size, int channel, int volume) = 0;
 	virtual void stopSound() = 0;
-	virtual const char *getInstrumentExtension() const = 0;
+	virtual const char *getInstrumentExtension() const { return ""; }
+	virtual void update() {}
 	
 	void setUpdateCallback(UpdateCallback upCb, void *ref);
 	void resetChannel(int channel);
@@ -123,7 +124,7 @@
 	virtual const char *getInstrumentExtension() const { return ".INS"; }
 	virtual void loadInstrument(const byte *data, AdlibSoundInstrument *asi);
 	virtual void setChannelFrequency(int channel, int frequency);
-	virtual void playSound(const byte *data, int channel, int volume);
+	virtual void playSound(const byte *data, int size, int channel, int volume);
 };
 
 // Operation Stealth adlib driver
@@ -133,9 +134,47 @@
 	virtual const char *getInstrumentExtension() const { return ".ADL"; }
 	virtual void loadInstrument(const byte *data, AdlibSoundInstrument *asi);
 	virtual void setChannelFrequency(int channel, int frequency);
-	virtual void playSound(const byte *data, int channel, int volume);
+	virtual void playSound(const byte *data, int size, int channel, int volume);
 };
 
+class PaulaSoundDriver : public SoundDriver {
+public:
+	PaulaSoundDriver(Audio::Mixer *mixer);
+	
+	virtual void setupChannel(int channel, const byte *data, int instrument, int volume);
+	virtual void setChannelFrequency(int channel, int frequency);
+	virtual void stopChannel(int channel);
+	virtual void playSound(const byte *data, int size, int channel, int volume);
+	virtual void stopSound();
+	
+	// Future Wars specific
+	void queueSound(int channel, int frequency, const uint8 *data, int size, int volumeStep, int stepCount, int volume, int repeat);
+	virtual void update();
+
+	enum {
+		PAULA_FREQ = 7093789,
+		NUM_CHANNELS = 4,
+		SPL_HDR_SIZE = 22
+	};
+	
+	struct SoundQueue {
+		int freq;
+		const uint8 *data;
+		int size;
+		int volumeStep;
+		int stepCount;
+		int step;
+		bool repeat;
+		int volume;
+	};
+
+private:
+	Audio::Mixer *_mixer;
+	Audio::SoundHandle _channelsTable[NUM_CHANNELS];
+	uint _channelsFreqTable[NUM_CHANNELS];
+	SoundQueue _soundsQueue[NUM_CHANNELS];
+};
+
 extern SoundDriver *g_soundDriver; // TEMP
 
 } // End of namespace Cine


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