aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2009-04-01 11:03:06 +0000
committerPaul Gilbert2009-04-01 11:03:06 +0000
commitf0456d67a873f8d6dd8d0c8262dd454bacb235b9 (patch)
treeff1321686349fb82a6ae5d43899306ec09b60e9e
parentef81dc0f983b639e61232a3f6e9cf6643f2c35d8 (diff)
downloadscummvm-rg350-f0456d67a873f8d6dd8d0c8262dd454bacb235b9.tar.gz
scummvm-rg350-f0456d67a873f8d6dd8d0c8262dd454bacb235b9.tar.bz2
scummvm-rg350-f0456d67a873f8d6dd8d0c8262dd454bacb235b9.zip
Laid the basics for music handling
svn-id: r39788
-rw-r--r--engines/cruise/sound.cpp228
-rw-r--r--engines/cruise/sound.h80
2 files changed, 308 insertions, 0 deletions
diff --git a/engines/cruise/sound.cpp b/engines/cruise/sound.cpp
new file mode 100644
index 0000000000..ba66483548
--- /dev/null
+++ b/engines/cruise/sound.cpp
@@ -0,0 +1,228 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program 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 General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/endian.h"
+
+#include "cruise/cruise.h"
+#include "cruise/cruise_main.h"
+#include "cruise/sound.h"
+#include "cruise/volume.h"
+
+namespace Cruise {
+
+MusicPlayer::MusicPlayer(): _looping(false), _isPlaying(false), _songPlayed(false) {
+ _songPointer = NULL;
+ _masterVolume = 0;
+}
+
+MusicPlayer::~MusicPlayer() {
+ stop();
+ if (_songPointer != NULL)
+ free(_songPointer);
+}
+
+void MusicPlayer::setVolume(int volume) {
+ _vm->_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, volume);
+
+ if (_masterVolume == volume)
+ return;
+
+ _masterVolume = volume;
+}
+
+void MusicPlayer::stop() {
+ _isPlaying = false;
+ _songPlayed = songLoaded();
+}
+
+void MusicPlayer::pause() {
+ setVolume(-1);
+ _isPlaying = false;
+}
+
+void MusicPlayer::resume() {
+ setVolume(_masterVolume);
+ _isPlaying = true;
+ _songPlayed = false;
+}
+
+void MusicPlayer::doSync(Common::Serializer &s) {
+ // synchronise current music name, if any, state, and position
+ s.syncString(_musicName, 33);
+ uint16 v = (uint16)songLoaded();
+ s.syncAsSint16LE(v);
+ s.syncAsSint16LE(_songPlayed);
+ s.syncAsSint16LE(_looping);
+}
+
+void MusicPlayer::loadSong(const char *name) {
+ char tempName[20], baseName[20];
+ uint8 *sampleData;
+
+ if (songLoaded())
+ removeSong();
+
+ // Load the correct file
+ int fileIdx = findFileInDisks(name);
+ if (fileIdx < 0) return;
+
+ int unpackedSize = volumePtrToFileDescriptor[fileIdx].extSize + 2;
+ _songPointer = (byte *)malloc(unpackedSize);
+ assert(_songPointer);
+
+ if (volumePtrToFileDescriptor[fileIdx].size + 2 != unpackedSize) {
+ uint8 *packedBuffer = (uint8 *)mallocAndZero(volumePtrToFileDescriptor[fileIdx].size + 2);
+
+ loadPackedFileToMem(fileIdx, packedBuffer);
+
+ uint32 realUnpackedSize = READ_BE_UINT32(packedBuffer + volumePtrToFileDescriptor[fileIdx].size - 4);
+
+ delphineUnpack(_songPointer, packedBuffer, volumePtrToFileDescriptor[fileIdx].size);
+ _songSize = realUnpackedSize;
+
+ free(packedBuffer);
+ } else {
+ loadPackedFileToMem(fileIdx, _songPointer);
+ _songSize = unpackedSize;
+ }
+
+ strcpy(_musicName, name);
+
+ // Get the details of the song
+ // TODO: Figure this out for sure for use in actually playing song
+ int numTracksMaybe = *(_songPointer + 470);
+ int speed = 244 - *(_songPointer + 471);
+ int musicSpeed = (speed * 100) / 1060;
+
+
+ // Get the file without the extension
+ strcpy(baseName, name);
+ char *p = strchr(tempName, '.');
+ if (p) *p = '\0';
+
+ // Get the instruments states file
+ strcpy(tempName, baseName);
+ strcat(tempName, ".IST");
+
+ fileIdx = findFileInDisks(tempName);
+ if (fileIdx >= 0)
+ {
+ // TODO: Figure out instrument state usage
+ uint8 instrumentState[15];
+ loadPackedFileToMem(fileIdx, instrumentState);
+ }
+
+ for (int instrumentCtr = 0; instrumentCtr < 15; ++instrumentCtr) {
+ if (_vm->mt32()) {
+ // Handle loading Roland instrument data
+ strcpy(tempName, baseName);
+ strcat(tempName, ".H32");
+
+ sampleData = loadInstrument(tempName, instrumentCtr);
+ if (sampleData) {
+ int v = *sampleData;
+ if ((v >= 128) && (v < 192))
+ patchMidi(0x80000L + (instrumentCtr * 512), sampleData + 1, 254);
+
+ // TODO: Currently I'm freeing the instrument data immediately. The original
+ // holds onto the sample data, so it may actually still be needed
+ free(sampleData);
+ }
+ } else if (_vm->adlib()) {
+ // Handle loading Adlib instrument data
+ strcpy(tempName, baseName);
+ strcat(tempName, ".ADL");
+
+ fileIdx = findFileInDisks(tempName);
+ if (fileIdx >= 0) {
+ sampleData = (byte *)malloc(volumePtrToFileDescriptor[fileIdx].extSize + 2);
+ assert(sampleData);
+ loadPackedFileToMem(fileIdx, sampleData);
+
+ // TODO: Make use of sample data
+
+ free(sampleData);
+ }
+ }
+ }
+
+ _songPlayed = false;
+ _isPlaying = false;
+}
+
+void MusicPlayer::startSong() {
+ if (songLoaded()) {
+ // Start playing song here
+ }
+}
+
+void MusicPlayer::removeSong() {
+ if (isPlaying())
+ stop();
+
+ if (_songPointer) {
+ free(_songPointer);
+ _songPointer = NULL;
+ }
+
+ _songPlayed = false;
+
+ strcpy(_musicName, "");
+}
+
+void MusicPlayer::fadeSong() {
+ // TODO: Implement fading properly
+ stop();
+}
+
+void MusicPlayer::patchMidi(uint32 adr, const byte *data, int size) {
+ // TODO: Handle patching midi
+}
+
+byte *MusicPlayer::loadInstrument(const char *name, int i) {
+ // Find the resource
+ int fileIdx = findFileInDisks(name);
+ if (fileIdx < 0) {
+ warning("Instrument '%s' not found", name);
+ return NULL;
+ }
+
+ int size = volumePtrToFileDescriptor[fileIdx].extSize;
+
+ // Get the data
+ byte *tmp = (byte *)malloc(size);
+ assert(tmp);
+ loadPackedFileToMem(fileIdx, tmp);
+
+ // Create a copy of the resource that's 22 bytes smaller
+ byte *result = (byte *)malloc(size - 22);
+ assert(result);
+ Common::copy(tmp, tmp + size - 22, result);
+
+ free(tmp);
+ return result;
+}
+
+} // End of namespace Cruise
diff --git a/engines/cruise/sound.h b/engines/cruise/sound.h
new file mode 100644
index 0000000000..c5d4acaa92
--- /dev/null
+++ b/engines/cruise/sound.h
@@ -0,0 +1,80 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program 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 General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef CRUISE_SOUND_H
+#define CRUISE_SOUND_H
+
+#include "sound/mididrv.h"
+#include "sound/midiparser.h"
+#include "sound/mixer.h"
+#include "common/serializer.h"
+
+namespace Cruise {
+
+class MusicPlayer {
+private:
+ byte _channelVolume[16];
+ int _fadeVolume;
+ char _musicName[33];
+
+ bool _isPlaying;
+ bool _songPlayed;
+ bool _looping;
+ byte _masterVolume;
+
+ byte *_songPointer;
+ int _songSize;
+
+ void patchMidi(uint32 adr, const byte *data, int size);
+ byte *loadInstrument(const char *name, int i);
+public:
+ MusicPlayer();
+ ~MusicPlayer();
+
+ void setVolume(int volume);
+ int getVolume() { return _masterVolume; }
+
+ void stop();
+ void pause();
+ void resume();
+
+ // Common public access methods
+ void doSync(Common::Serializer &s);
+ void loadSong(const char *name);
+ void startSong();
+ void stopSong();
+ void removeSong();
+ void fadeSong();
+
+ bool songLoaded() const { return _songPointer != NULL; }
+ bool songPlayed() const { return _songPlayed; }
+ bool isPlaying() const { return _isPlaying; }
+ void setPlaying(bool playing) { _isPlaying = playing; }
+ void setLoop(bool loop) { _looping = loop; }
+};
+
+} // End of namespace Cruise
+
+#endif