[Scummvm-cvs-logs] scummvm master -> 6a519f7f40bbbb2e8887e69cef1ecd2b029d7490

bluegr bluegr at gmail.com
Fri Mar 28 01:17:47 CET 2014


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
6a519f7f40 SCI: Initial implementation of the fanmade sciAudio library


Commit: 6a519f7f40bbbb2e8887e69cef1ecd2b029d7490
    https://github.com/scummvm/scummvm/commit/6a519f7f40bbbb2e8887e69cef1ecd2b029d7490
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2014-03-28T02:16:54+02:00

Commit Message:
SCI: Initial implementation of the fanmade sciAudio library

This is used in the fanmade games "LockerGnome Quest Redux" and
"Betrayed Alliance"

Changed paths:
    engines/sci/engine/kfile.cpp
    engines/sci/sound/audio.cpp
    engines/sci/sound/audio.h



diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp
index 29e2972..65acdbc 100644
--- a/engines/sci/engine/kfile.cpp
+++ b/engines/sci/engine/kfile.cpp
@@ -37,6 +37,7 @@
 #include "sci/engine/state.h"
 #include "sci/engine/kernel.h"
 #include "sci/engine/savegame.h"
+#include "sci/sound/audio.h"
 #include "sci/console.h"
 
 namespace Sci {
@@ -494,6 +495,21 @@ reg_t kFileIOWriteString(EngineState *s, int argc, reg_t *argv) {
 	Common::String str = s->_segMan->getString(argv[1]);
 	debugC(kDebugLevelFile, "kFileIO(writeString): %d", handle);
 
+	// Handle sciAudio calls in fanmade games here. sciAudio is an
+	// external .NET library for playing MP3 files in fanmade games.
+	// It runs in the background, and obtains sound commands from the
+	// currently running game via text files (called "conductor files").
+	// We skip creating these files, and instead handle the calls
+	// directly. Since the sciAudio calls are only creating text files,
+	// this is probably the most straightforward place to handle them.
+	if (handle == 0xFFFF && str.hasPrefix("(sciAudio")) {
+		Common::List<ExecStack>::const_iterator iter = s->_executionStack.reverse_begin();
+		iter--;	// sciAudio
+		iter--;	// sciAudio child
+		g_sci->_audio->handleFanmadeSciAudio(iter->sendp, s->_segMan);
+		return NULL_REG;
+	}
+
 #ifdef ENABLE_SCI32
 	if (handle == VIRTUALFILE_HANDLE) {
 		s->_virtualIndexFile->write(str.c_str(), str.size());
diff --git a/engines/sci/sound/audio.cpp b/engines/sci/sound/audio.cpp
index 3147fbd..228abba 100644
--- a/engines/sci/sound/audio.cpp
+++ b/engines/sci/sound/audio.cpp
@@ -61,6 +61,59 @@ void AudioPlayer::stopAllAudio() {
 		audioCdStop();
 }
 
+/**
+ * Handles the sciAudio calls in fanmade games.
+ * sciAudio is an external .NET library for playing MP3 files in fanmade games.
+ * It runs in the background, and obtains sound commands from the
+ * currently running game via text files (called "conductor files").
+ * For further info, check: http://sciprogramming.com/community/index.php?topic=634.0
+ */
+void AudioPlayer::handleFanmadeSciAudio(reg_t sciAudioObject, SegManager *segMan) {
+	// TODO: This is a bare bones implementation. Only the play/playx and stop commands
+	// are handled for now - the other commands haven't been observed in any fanmade game
+	// yet. All the volume related and fading functionality is currently missing.
+
+	Kernel *kernel = g_sci->getKernel();
+
+	reg_t commandReg = readSelector(segMan, sciAudioObject, kernel->findSelector("command"));
+	Common::String command = segMan->getString(commandReg);
+
+	if (command == "play" || command == "playx") {
+		reg_t fileNameReg = readSelector(segMan, sciAudioObject, kernel->findSelector("fileName"));
+		Common::String fileName = segMan->getString(fileNameReg);
+
+		int16 loopCount = (int16)readSelectorValue(segMan, sciAudioObject, kernel->findSelector("loopCount"));
+		// When loopCount is -1, we treat it as infinite looping, else no looping is done.
+		// This is observed by game scripts, which can set loopCount to all sorts of random values.
+		// Adjust loopCount for ScummVM's LoopingAudioStream semantics
+		loopCount = (loopCount == -1) ? 0 : 1;
+
+		// Determine sound type
+		Audio::Mixer::SoundType soundType = Audio::Mixer::kSFXSoundType;
+		if (fileName.hasPrefix("music"))
+			soundType = Audio::Mixer::kMusicSoundType;
+		else if (fileName.hasPrefix("speech"))
+			soundType = Audio::Mixer::kSpeechSoundType;
+
+		Common::File *sciAudio = new Common::File();
+		// Replace backwards slashes
+		for (uint i = 0; i < fileName.size(); i++) {
+			if (fileName[i] == '\\')
+				fileName.setChar('/', i);
+		}
+		sciAudio->open("sciAudio/" + fileName);
+		Audio::SeekableAudioStream *audioStream = Audio::makeMP3Stream(sciAudio, DisposeAfterUse::YES);
+
+		// We only support one audio handle
+		_mixer->playStream(soundType, &_audioHandle,
+							Audio::makeLoopingAudioStream((Audio::RewindableAudioStream *)audioStream, loopCount));
+	} else if (command == "stop") {
+		_mixer->stopHandle(_audioHandle);
+	} else {
+		warning("Unhandled sciAudio command: %s", command.c_str());
+	}
+}
+
 int AudioPlayer::startAudio(uint16 module, uint32 number) {
 	int sampleLen;
 	Audio::AudioStream *audioStream = getAudioStream(number, module, &sampleLen);
diff --git a/engines/sci/sound/audio.h b/engines/sci/sound/audio.h
index 545d35b..9e65d6e 100644
--- a/engines/sci/sound/audio.h
+++ b/engines/sci/sound/audio.h
@@ -75,6 +75,8 @@ public:
 	void pauseAudio();
 	void resumeAudio();
 
+	void handleFanmadeSciAudio(reg_t sciAudioObject, SegManager *segMan);
+
 	void setSoundSync(ResourceId id, reg_t syncObjAddr, SegManager *segMan);
 	void doSoundSync(reg_t syncObjAddr, SegManager *segMan);
 	void stopSoundSync();






More information about the Scummvm-git-logs mailing list