aboutsummaryrefslogtreecommitdiff
path: root/scumm/imuse_digi/dimuse_script.cpp
diff options
context:
space:
mode:
authorPaweł Kołodziejski2004-04-06 19:46:43 +0000
committerPaweł Kołodziejski2004-04-06 19:46:43 +0000
commit2b9311aa26e3536eb7e22239f8ed5b42f2834065 (patch)
treeeb7395a75783193c8c19a2ab772427f7979bfff0 /scumm/imuse_digi/dimuse_script.cpp
parent86dd5c56f68055a7d8386e831554864c3b014e26 (diff)
downloadscummvm-rg350-2b9311aa26e3536eb7e22239f8ed5b42f2834065.tar.gz
scummvm-rg350-2b9311aa26e3536eb7e22239f8ed5b42f2834065.tar.bz2
scummvm-rg350-2b9311aa26e3536eb7e22239f8ed5b42f2834065.zip
- split imuse digital code,
- cleanup a little, - added pool method for FT voc sample from resource, - make struct sync, jump, regions dynamic memory allocation svn-id: r13486
Diffstat (limited to 'scumm/imuse_digi/dimuse_script.cpp')
-rw-r--r--scumm/imuse_digi/dimuse_script.cpp363
1 files changed, 363 insertions, 0 deletions
diff --git a/scumm/imuse_digi/dimuse_script.cpp b/scumm/imuse_digi/dimuse_script.cpp
new file mode 100644
index 0000000000..6d44b55796
--- /dev/null
+++ b/scumm/imuse_digi/dimuse_script.cpp
@@ -0,0 +1,363 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2004 The ScummVM project
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ */
+
+#include "stdafx.h"
+#include "common/timer.h"
+
+#include "scumm/actor.h"
+#include "scumm/scumm.h"
+#include "scumm/sound.h"
+#include "scumm/imuse_digi/dimuse.h"
+#include "scumm/imuse_digi/dimuse_bndmgr.h"
+
+#include "sound/audiostream.h"
+#include "sound/mixer.h"
+
+namespace Scumm {
+
+void IMuseDigital::parseScriptCmds(int a, int b, int c, int d, int e, int f, int g, int h) {
+ int cmd = a;
+ int soundId = b;
+ int sub_cmd = c;
+
+ if (!cmd)
+ return;
+
+ switch (cmd) {
+ case 10: // ImuseStopAllSounds
+ stopAllSounds();
+ break;
+ case 12: // ImuseSetParam
+ switch (sub_cmd) {
+ case 0x400: // select group volume
+ selectVolumeGroup(soundId, d);
+ break;
+ case 0x500: // set priority
+ setPriority(soundId, d);
+ break;
+ case 0x600: // set volume
+ setVolume(soundId, d);
+ break;
+ case 0x700: // set pan
+ setPan(soundId, d);
+ break;
+ default:
+ warning("IMuseDigital::doCommand SetParam DEFAULT command %d", sub_cmd);
+ break;
+ }
+ break;
+ case 14: // ImuseFadeParam
+ switch (sub_cmd) {
+ case 0x600: // set volume fading
+ if ((d != 0) && (e == 0))
+ setVolume(soundId, d);
+ else if ((d == 0) && (e == 0))
+ stopSound(soundId);
+ else
+ setFade(soundId, d, e);
+ break;
+ default:
+ warning("IMuseDigital::doCommand FadeParam DEFAULT sub command %d", sub_cmd);
+ break;
+ }
+ break;
+ case 25: // ImuseStartStream
+ debug(5, "ImuseStartStream (%d, %d, %d)", soundId, c, d);
+ break;
+ case 26: // ImuseSwitchStream
+ debug(5, "ImuseSwitchStream (%d, %d, %d, %d, %d)", soundId, c, d, e, f);
+ break;
+ case 0x1000: // ImuseSetState
+ debug(5, "ImuseSetState (%d)", b);
+ if ((_vm->_gameId == GID_DIG) && (_vm->_features & GF_DEMO)) {
+ if (b == 1) {
+ fadeOutMusic(200);
+ startMusic(1, 127);
+ } else {
+ if (getSoundStatus(2) == 0) {
+ fadeOutMusic(200);
+ startMusic(2, 127);
+ }
+ }
+ } else if ((_vm->_gameId == GID_CMI) && (_vm->_features & GF_DEMO)) {
+ fadeOutMusic(120);
+ if (b == 2) {
+ startMusic("in1.imx", 1100, 0, 127);
+ } else if (b == 4) {
+ startMusic("in2.imx", 1120, 0, 127);
+ } else if (b == 8) {
+ startMusic("out1.imx", 1140, 0, 127);
+ } else if (b == 9) {
+ startMusic("out2.imx", 1150, 0, 127);
+ } else if (b == 16) {
+ startMusic("gun.imx", 1210, 0, 127);
+ } else {
+ warning("imuse digital: set state unknown for cmi demo: %d, room: %d", b, _vm->_currentRoom);
+ }
+ } else if (_vm->_gameId == GID_DIG) {
+ setDigMusicState(b);
+ } else if (_vm->_gameId == GID_CMI) {
+ setComiMusicState(b);
+ } else if (_vm->_gameId == GID_FT) {
+ setFtMusicState(b);
+ }
+ break;
+ case 0x1001: // ImuseSetSequence
+ debug(5, "ImuseSetSequence (%d)", b);
+ if (_vm->_gameId == GID_DIG) {
+ setDigMusicSequence(b);
+ } else if (_vm->_gameId == GID_CMI) {
+ setComiMusicSequence(b);
+ } else if (_vm->_gameId == GID_FT) {
+ setFtMusicSequence(b);
+ }
+ break;
+ case 0x1002: // ImuseSetCuePoint
+ debug(5, "ImuseSetCuePoint (%d)", b);
+ if (_vm->_gameId == GID_FT) {
+ setFtMusicCuePoint(b);
+ }
+ break;
+ case 0x1003: // ImuseSetAttribute
+ debug(5, "ImuseSetAttribute (%d, %d)", b, c);
+ assert((_vm->_gameId == GID_DIG) || (_vm->_gameId == GID_FT));
+ if (_vm->_gameId == GID_DIG) {
+ _attributes[b] = c;
+ }
+ break;
+ case 0x2000: // ImuseSetGroupSfxVolume
+ debug(5, "ImuseSetGroupSFXVolume (%d)", b);
+// setGroupSfxVolume(b);
+ break;
+ case 0x2001: // ImuseSetGroupVoiceVolume
+ debug(5, "ImuseSetGroupVoiceVolume (%d)", b);
+// setGroupVoiceVolume(b);
+ break;
+ case 0x2002: // ImuseSetGroupMusicVolume
+ debug(5, "ImuseSetGroupMusicVolume (%d)", b);
+// setGroupMusicVolume(b);
+ break;
+ default:
+ warning("IMuseDigital::doCommand DEFAULT command %d", cmd);
+ }
+}
+
+void IMuseDigital::startVoice(int soundId, AudioStream *input) {
+ debug(5, "startVoiceStream(%d)", soundId);
+ startSound(soundId, NULL, 0, IMUSE_VOLGRP_VOICE, input, 0, 127, 127);
+}
+
+void IMuseDigital::startVoice(int soundId, const char *soundName) {
+ debug(5, "startVoiceBundle(%s)", soundName);
+ startSound(soundId, soundName, IMUSE_BUNDLE, IMUSE_VOLGRP_VOICE, NULL, 0, 127, 127);
+}
+
+void IMuseDigital::startMusic(int soundId, int volume) {
+ debug(5, "startMusicResource(%d)", soundId);
+ startSound(soundId, NULL, IMUSE_RESOURCE, IMUSE_VOLGRP_MUSIC, NULL, 0, volume, 126);
+}
+
+void IMuseDigital::startMusic(const char *soundName, int soundId, int hookId, int volume) {
+ debug(5, "startMusicBundle(%s)", soundName);
+ startSound(soundId, soundName, IMUSE_BUNDLE, IMUSE_VOLGRP_MUSIC, NULL, hookId, volume, 126);
+}
+
+void IMuseDigital::startSfx(int soundId, int priority) {
+ debug(5, "startSfx(%d)", soundId);
+ startSound(soundId, NULL, IMUSE_RESOURCE, IMUSE_VOLGRP_SFX, NULL, 0, 127, priority);
+}
+
+void IMuseDigital::getLipSync(int soundId, int syncId, int32 msPos, int32 &width, int32 &height) {
+ int32 sync_size;
+ byte *sync_ptr;
+
+ msPos /= 16;
+ if (msPos < 65536) {
+ for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
+ if ((_track[l].soundId == soundId) && _track[l].used) {
+ _sound->getSyncSizeAndPtrById(_track[l].soundHandle, syncId, sync_size, &sync_ptr);
+ if ((sync_size != 0) && (sync_ptr != NULL)) {
+ sync_size /= 4;
+ while (sync_size--) {
+ if (READ_BE_UINT16(sync_ptr) >= msPos)
+ break;
+ sync_ptr += 4;
+ }
+ if (sync_size < 0)
+ sync_ptr -= 4;
+ else
+ if (READ_BE_UINT16(sync_ptr) > msPos)
+ sync_ptr -= 4;
+
+ width = sync_ptr[2];
+ height = sync_ptr[3];
+ return;
+ }
+ }
+ }
+ }
+}
+
+int32 IMuseDigital::getPosInMs(int soundId) {
+ for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
+ if ((_track[l].soundId == soundId) && (_track[l].used)) {
+ int32 pos = (5 * (_track[l].dataOffset + _track[l].regionOffset)) / (_track[l].iteration / 200);
+ return pos;
+ }
+ }
+
+ return 0;
+}
+
+int IMuseDigital::getSoundStatus(int sound) const {
+ Common::StackLock lock(_mutex, "IMuseDigital::getSoundStatus()");
+ debug(5, "IMuseDigital::getSoundStatus(%d)", sound);
+ for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
+ if ((_track[l].soundId == sound) && _track[l].used) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+void IMuseDigital::stopSound(int soundId) {
+ Common::StackLock lock(_mutex, "IMuseDigital::stopSound()");
+ debug(5, "IMuseDigital::stopSound(%d)", soundId);
+ for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
+ if ((_track[l].soundId == soundId) && _track[l].used) {
+ if (_track[l].stream) {
+ _track[l].toBeRemoved = true;
+ }
+ else if (_track[l].stream2)
+ _vm->_mixer->stopHandle(_track[l].handle);
+ }
+ }
+}
+
+int32 IMuseDigital::getCurMusicPosInMs() {
+ Common::StackLock lock(_mutex, "IMuseDigital::getCurMusicPosInMs()");
+ int soundId = -1;
+
+ for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
+ if ((_track[l].used) && (_track[l].volGroupId == IMUSE_VOLGRP_MUSIC) && (!_track[l].volFadeUsed)) {
+ soundId = _track[l].soundId;
+ }
+ }
+
+ int32 msPos = getPosInMs(soundId);
+ debug(5, "IMuseDigital::getCurMusicPosInMs(%d) = %d", soundId, msPos);
+ return msPos;
+}
+
+int32 IMuseDigital::getCurVoiceLipSyncWidth() {
+ Common::StackLock lock(_mutex, "IMuseDigital::getCutVoiceLipSyncWidth()");
+ int32 msPos = getPosInMs(kTalkSoundID) + 50;
+ int32 width = 0, height = 0;
+
+ debug(5, "IMuseDigital::getCurVoiceLipSyncWidth(%d)", kTalkSoundID);
+ getLipSync(kTalkSoundID, 0, msPos, width, height);
+ return width;
+}
+
+int32 IMuseDigital::getCurVoiceLipSyncHeight() {
+ Common::StackLock lock(_mutex, "IMuseDigital::getCurVoiceLipSyncHeight()");
+ int32 msPos = getPosInMs(kTalkSoundID) + 50;
+ int32 width = 0, height = 0;
+
+ debug(5, "IMuseDigital::getCurVoiceLipSyncHeight(%d)", kTalkSoundID);
+ getLipSync(kTalkSoundID, 0, msPos, width, height);
+ return height;
+}
+
+int32 IMuseDigital::getCurMusicLipSyncWidth(int syncId) {
+ Common::StackLock lock(_mutex, "IMuseDigital::getCurMusicLipSyncWidth()");
+ int soundId = -1;
+
+ for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
+ if ((_track[l].used) && (_track[l].volGroupId == IMUSE_VOLGRP_MUSIC) && (!_track[l].volFadeUsed)) {
+ soundId = _track[l].soundId;
+ }
+ }
+
+ int32 msPos = getPosInMs(soundId) + 50;
+ int32 width = 0, height = 0;
+
+ debug(5, "IMuseDigital::getCurVoiceLipSyncWidth(%d, %d)", soundId, msPos);
+ getLipSync(soundId, syncId, msPos, width, height);
+ return width;
+}
+
+int32 IMuseDigital::getCurMusicLipSyncHeight(int syncId) {
+ Common::StackLock lock(_mutex, "IMuseDigital::getCurMusicLipSyncHeight()");
+ int soundId = -1;
+
+ for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
+ if ((_track[l].used) && (_track[l].volGroupId == IMUSE_VOLGRP_MUSIC) && (!_track[l].volFadeUsed)) {
+ soundId = _track[l].soundId;
+ }
+ }
+
+ int32 msPos = getPosInMs(soundId) + 50;
+ int32 width = 0, height = 0;
+
+ debug(5, "IMuseDigital::getCurVoiceLipSyncHeight(%d, %d)", soundId, msPos);
+ getLipSync(soundId, syncId, msPos, width, height);
+ return height;
+}
+
+void IMuseDigital::stopAllSounds(bool waitForStop) {
+ debug(5, "IMuseDigital::stopAllSounds");
+ {
+ Common::StackLock lock(_mutex, "IMuseDigital::stopAllSounds()");
+ for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
+ if (_track[l].used) {
+ if (_track[l].stream) {
+ _track[l].toBeRemoved = true;
+ } else if (_track[l].stream2)
+ _vm->_mixer->stopHandle(_track[l].handle);
+ }
+ }
+ }
+
+ if (waitForStop) {
+ bool used;
+ do {
+ used = false;
+ for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
+ if (_track[l].used)
+ used = true;
+ }
+ g_system->delay_msecs(10);
+ } while (used);
+ }
+}
+
+void IMuseDigital::pause(bool p) {
+ Common::StackLock lock(_mutex, "IMuseDigital::pause()");
+ for (int l = 0; l < MAX_DIGITAL_TRACKS; l++) {
+ if (_track[l].used) {
+ _vm->_mixer->pauseHandle(_track[l].handle, p);
+ }
+ }
+ _pause = p;
+}
+
+} // End of namespace Scumm