aboutsummaryrefslogtreecommitdiff
path: root/engines/scumm/sound_he.cpp
diff options
context:
space:
mode:
authorEugene Sandulenko2006-02-15 00:57:50 +0000
committerEugene Sandulenko2006-02-15 00:57:50 +0000
commit10c7835cfcdd8f0eb1eadf52ac9cfd39d2d6be61 (patch)
treedc3e12a02eb6befdf76c5fc0110f4cd9be82f569 /engines/scumm/sound_he.cpp
parent0bea9cf47b027ad8936751f48779046ca0a48bf9 (diff)
downloadscummvm-rg350-10c7835cfcdd8f0eb1eadf52ac9cfd39d2d6be61.tar.gz
scummvm-rg350-10c7835cfcdd8f0eb1eadf52ac9cfd39d2d6be61.tar.bz2
scummvm-rg350-10c7835cfcdd8f0eb1eadf52ac9cfd39d2d6be61.zip
Moved all he-specific source files to engines/scumm/he/ subdirectory
svn-id: r20696
Diffstat (limited to 'engines/scumm/sound_he.cpp')
-rw-r--r--engines/scumm/sound_he.cpp516
1 files changed, 0 insertions, 516 deletions
diff --git a/engines/scumm/sound_he.cpp b/engines/scumm/sound_he.cpp
deleted file mode 100644
index 879e34a99e..0000000000
--- a/engines/scumm/sound_he.cpp
+++ /dev/null
@@ -1,516 +0,0 @@
-/* ScummVM - Scumm Interpreter
- * Copyright (C) 2001 Ludvig Strigeus
- * Copyright (C) 2001-2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stdafx.h"
-#include "scumm/actor.h"
-#include "scumm/imuse.h"
-#include "scumm/scumm.h"
-#include "scumm/sound.h"
-#include "scumm/util.h"
-
-#include "common/config-manager.h"
-#include "common/timer.h"
-#include "common/util.h"
-
-#include "sound/adpcm.h"
-#include "sound/audiocd.h"
-#include "sound/flac.h"
-#include "sound/mididrv.h"
-#include "sound/mixer.h"
-#include "sound/mp3.h"
-#include "sound/voc.h"
-#include "sound/vorbis.h"
-#include "sound/wave.h"
-
-namespace Scumm {
-
-int Sound::findFreeSoundChannel() {
- int chan, min;
-
- min = _vm->VAR(_vm->VAR_RESERVED_SOUND_CHANNELS);
- if (min == 0) {
- _vm->VAR(_vm->VAR_RESERVED_SOUND_CHANNELS) = 8;
- return 1;
- }
-
- if (min < 8) {
- for (chan = min; chan < ARRAYSIZE(_heChannel); chan++) {
- if (_vm->_mixer->isSoundHandleActive(_heSoundChannels[chan]) == 0)
- return chan;
- }
- } else {
- return 1;
- }
-
- return min;
-}
-
-int Sound::isSoundCodeUsed(int sound) {
- int chan = -1;
- for (int i = 0; i < ARRAYSIZE(_heChannel); i ++) {
- if (_heChannel[i].sound == sound)
- chan = i;
- }
-
- if (chan != -1) {
- return _heChannel[chan].sbngBlock;
- } else {
- return 0;
- }
-}
-
-int Sound::getSoundPos(int sound) {
- int chan = -1;
- for (int i = 0; i < ARRAYSIZE(_heChannel); i ++) {
- if (_heChannel[i].sound == sound)
- chan = i;
- }
-
- if (chan != -1) {
- int time = _vm->getHETimer(chan + 4) * 11025 / 1000;
- return time;
- } else {
- return 0;
- }
-}
-
-int Sound::getSoundVar(int sound, int var) {
- if (_vm->_heversion >= 90 && var == 26) {
- return isSoundCodeUsed(sound);
- }
-
- checkRange(25, 0, var, "Illegal sound variable %d");
-
- int chan = -1;
- for (int i = 0; i < ARRAYSIZE(_heChannel); i ++) {
- if (_heChannel[i].sound == sound)
- chan = i;
- }
-
- if (chan != -1) {
- debug(5, "getSoundVar: sound %d var %d result %d", sound, var, _heChannel[chan].soundVars[var]);
- return _heChannel[chan].soundVars[var];
- } else {
- return 0;
- }
-}
-
-void Sound::setSoundVar(int sound, int var, int val) {
- checkRange(25, 0, var, "Illegal sound variable %d");
-
- int chan = -1;
- for (int i = 0; i < ARRAYSIZE(_heChannel); i ++) {
- if (_heChannel[i].sound == sound)
- chan = i;
- }
-
- if (chan != -1) {
- debug(5, "setSoundVar: sound %d var %d val %d", sound, var, val);
- _heChannel[chan].soundVars[var] = val;
- }
-}
-
-void Sound::setOverrideFreq(int freq) {
- _overrideFreq = freq;
-}
-
-void Sound::setupHEMusicFile() {
- int i, total_size;
- char buf[32], buf1[128];
- Common::File musicFile;
-
- sprintf(buf, "%s.he4", _vm->getBaseName());
-
- if (_vm->_substResFileNameIndex > 0) {
- _vm->generateSubstResFileName(buf, buf1, sizeof(buf1));
- strcpy(buf, buf1);
- }
- if (musicFile.open(buf) == true) {
- musicFile.seek(4, SEEK_SET);
- total_size = musicFile.readUint32BE();
- musicFile.seek(16, SEEK_SET);
- _heMusicTracks = musicFile.readUint32LE();
- debug(5, "Total music tracks %d", _heMusicTracks);
-
- int musicStart = (_vm->_heversion >= 80) ? 56 : 20;
- musicFile.seek(musicStart, SEEK_SET);
-
- _heMusic = (HEMusic *)malloc((_heMusicTracks + 1) * sizeof(HEMusic));
- for (i = 0; i < _heMusicTracks; i++) {
- _heMusic[i].id = musicFile.readUint32LE();
- _heMusic[i].offset = musicFile.readUint32LE();
- _heMusic[i].size = musicFile.readUint32LE();
-
- if (_vm->_heversion >= 80) {
- musicFile.seek(+9, SEEK_CUR);
- } else {
- musicFile.seek(+13, SEEK_CUR);
- }
- }
-
- musicFile.close();
- }
-}
-
-bool Sound::getHEMusicDetails(int id, int &musicOffs, int &musicSize) {
- int i;
-
- for (i = 0; i < _heMusicTracks; i++) {
- if (_heMusic[i].id == id) {
- musicOffs = _heMusic[i].offset;
- musicSize = _heMusic[i].size;
- return 1;
- }
- }
-
- return 0;
-}
-
-void Sound::processSoundCode() {
- byte *codePtr;
- int chan, tmr, size, time;
-
- for (chan = 0; chan < ARRAYSIZE(_heChannel); chan++) {
- if (_heChannel[chan].sound == 0) {
- continue;
- }
-
- if (_heChannel[chan].codeOffs == -1) {
- continue;
- }
-
- tmr = _vm->getHETimer(chan + 4) * 11025 / 1000;
- tmr += _vm->VAR(_vm->VAR_SOUNDCODE_TMR);
- if (tmr < 0)
- tmr = 0;
-
- if (_heChannel[chan].sound > _vm->_numSounds) {
- codePtr = _vm->getResourceAddress(rtSpoolBuffer, chan);
- } else {
- codePtr = _vm->getResourceAddress(rtSound, _heChannel[chan].sound);
- }
- assert(codePtr);
- codePtr += _heChannel[chan].codeOffs;
-
- while(1) {
- size = READ_LE_UINT16(codePtr);
- time = READ_LE_UINT32(codePtr + 2);
-
- if (size == 0) {
- _heChannel[chan].codeOffs = -1;
- break;
- }
-
- debug(5, "Channel %d Timer %d Time %d", chan, tmr, time);
- if (time >= tmr)
- break;
-
- processSoundOpcodes(_heChannel[chan].sound, codePtr + 6, _heChannel[chan].soundVars);
-
- codePtr += size;
- _heChannel[chan].codeOffs += size;
- }
- }
-}
-
-void Sound::processSoundOpcodes(int sound, byte *codePtr, int *soundVars) {
- int arg, opcode, var, val;
-
- while(READ_LE_UINT16(codePtr) != 0) {
- codePtr += 2;
- opcode = READ_LE_UINT16(codePtr); codePtr += 2;
- opcode = (opcode & 0xFFF) >> 4;
- arg = opcode & 3;
- opcode &= ~3;
- debug(5, "processSoundOpcodes: sound %d opcode %d", sound, opcode);
- switch (opcode) {
- case 0: // Continue
- break;
- case 16: // Set talk state
- val = READ_LE_UINT16(codePtr); codePtr += 2;
- setSoundVar(sound, 19, val);
- break;
- case 32: // Set var
- var = READ_LE_UINT16(codePtr); codePtr += 2;
- val = READ_LE_UINT16(codePtr); codePtr += 2;
- if (arg == 2) {
- val = getSoundVar(sound, val);
- }
- setSoundVar(sound, var, val);
- break;
- case 48: // Add
- var = READ_LE_UINT16(codePtr); codePtr += 2;
- val = READ_LE_UINT16(codePtr); codePtr += 2;
- if (arg == 2) {
- val = getSoundVar(sound, val);
- }
- val = getSoundVar(sound, var) + val;
- setSoundVar(sound, var, val);
- break;
- case 56: // Subtract
- var = READ_LE_UINT16(codePtr); codePtr += 2;
- val = READ_LE_UINT16(codePtr); codePtr += 2;
- if (arg == 2) {
- val = getSoundVar(sound, val);
- }
- val = getSoundVar(sound, var) - val;
- setSoundVar(sound, var, val);
- break;
- case 64: // Multiple
- var = READ_LE_UINT16(codePtr); codePtr += 2;
- val = READ_LE_UINT16(codePtr); codePtr += 2;
- if (arg == 2) {
- val = getSoundVar(sound, val);
- }
- val = getSoundVar(sound, var) * val;
- setSoundVar(sound, var, val);
- break;
- case 80: // Divide
- var = READ_LE_UINT16(codePtr); codePtr += 2;
- val = READ_LE_UINT16(codePtr); codePtr += 2;
- if (arg == 2) {
- val = getSoundVar(sound, val);
- }
- val = getSoundVar(sound, var) / val;
- setSoundVar(sound, var, val);
- break;
- case 96: // Increment
- var = READ_LE_UINT16(codePtr); codePtr += 2;
- val = getSoundVar(sound, var) + 1;
- setSoundVar(sound, var, val);
- break;
- case 104: // Decrement
- var = READ_LE_UINT16(codePtr); codePtr += 2;
- val = getSoundVar(sound, var) - 1;
- setSoundVar(sound, var, val);
- break;
- default:
- error("Illegal sound %d opcode %d", sound, opcode);
- }
- }
-}
-
-void Sound::playHESound(int soundID, int heOffset, int heChannel, int heFlags) {
- byte *ptr, *spoolPtr;
- char *sound;
- int size = -1;
- int priority, rate;
- byte flags = Audio::Mixer::FLAG_UNSIGNED | Audio::Mixer::FLAG_AUTOFREE;
-
- if (heChannel == -1)
- heChannel = (_vm->VAR_RESERVED_SOUND_CHANNELS != 0xFF) ? findFreeSoundChannel() : 1;
-
- debug(5,"playHESound: soundID %d heOffset %d heChannel %d heFlags %d", soundID, heOffset, heChannel, heFlags);
-
- if (soundID >= 10000) {
- // Special codes, used in pjgames
- return;
- }
-
- if (soundID > _vm->_numSounds) {
- int music_offs;
- char buf[32], buf1[128];
- Common::File musicFile;
-
- sprintf(buf, "%s.he4", _vm->getBaseName());
-
- if (_vm->_substResFileNameIndex > 0) {
- _vm->generateSubstResFileName(buf, buf1, sizeof(buf1));
- strcpy(buf, buf1);
- }
- if (musicFile.open(buf) == false) {
- warning("playSound: Can't open music file %s", buf);
- return;
- }
- if (!getHEMusicDetails(soundID, music_offs, size)) {
- debug(0, "playSound: musicID %d not found", soundID);
- return;
- }
-
- musicFile.seek(music_offs, SEEK_SET);
-
- if (_vm->_heversion == 70) {
- spoolPtr = (byte *)malloc(size);
- musicFile.read(spoolPtr, size);
- } else {
- spoolPtr = _vm->res.createResource(rtSpoolBuffer, heChannel, size);
- assert(spoolPtr);
- musicFile.read(spoolPtr, size);
- }
- musicFile.close();
-
- if (_vm->_heversion == 70) {
- _vm->_mixer->stopHandle(_heSoundChannels[heChannel]);
- _vm->_mixer->playRaw(&_heSoundChannels[heChannel], spoolPtr, size, 11025, flags, soundID);
- return;
- }
- }
-
- if (soundID > _vm->_numSounds) {
- ptr = _vm->getResourceAddress(rtSpoolBuffer, heChannel);
- } else {
- ptr = _vm->getResourceAddress(rtSound, soundID);
- }
-
- if (!ptr) {
- return;
- }
-
- // TODO: Extra sound flags
- if (heFlags & 1) {
- flags |= Audio::Mixer::FLAG_LOOP;
- }
-
- // Support for sound in later Backyard sports games
- if (READ_UINT32(ptr) == MKID('RIFF') || READ_UINT32(ptr) == MKID('WSOU')) {
- uint16 type;
- int blockAlign;
-
- if (READ_UINT32(ptr) == MKID('WSOU'))
- ptr += 8;
-
- size = READ_LE_UINT32(ptr + 4);
- Common::MemoryReadStream stream(ptr, size);
-
- if (!loadWAVFromStream(stream, size, rate, flags, &type, &blockAlign)) {
- error("playSound: Not a valid WAV file");
- }
-
- if (type == 17) {
- AudioStream *voxStream = new ADPCMInputStream(&stream, size, kADPCMIma, (flags & Audio::Mixer::FLAG_STEREO) ? 2 : 1, blockAlign);
-
- sound = (char *)malloc(size * 4);
- size = voxStream->readBuffer((int16*)sound, size * 2);
- size *= 2; // 16bits.
- delete voxStream;
- } else {
- // Allocate a sound buffer, copy the data into it, and play
- sound = (char *)malloc(size);
- memcpy(sound, ptr + stream.pos(), size);
- }
- _vm->_mixer->stopHandle(_heSoundChannels[heChannel]);
- _vm->_mixer->playRaw(&_heSoundChannels[heChannel], sound, size, rate, flags, soundID);
- }
- // Support for sound in Humongous Entertainment games
- else if (READ_UINT32(ptr) == MKID('DIGI') || READ_UINT32(ptr) == MKID('TALK')) {
- byte *sndPtr = ptr;
-
- priority = (soundID > _vm->_numSounds) ? 255 : *(ptr + 18);
- rate = READ_LE_UINT16(ptr + 22);
- ptr += 8 + READ_BE_UINT32(ptr + 12);
-
- if (_vm->_mixer->isSoundHandleActive(_heSoundChannels[heChannel])) {
- int curSnd = _heChannel[heChannel].sound;
- if (curSnd == 1 && soundID != 1)
- return;
- if (curSnd != 0 && curSnd != 1 && soundID != 1 && _heChannel[heChannel].priority > priority)
- return;
- }
-
- int codeOffs = -1;
- if (READ_UINT32(ptr) == MKID('SBNG')) {
- codeOffs = ptr - sndPtr + 8;
- ptr += READ_BE_UINT32(ptr + 4);
- }
-
- assert(READ_UINT32(ptr) == MKID('SDAT'));
- size = READ_BE_UINT32(ptr+4) - 8;
- if (heOffset < 0 || heOffset > size) {
- // Occurs when making fireworks in puttmoon
- debug(0, "playSound: Invalid sound offset (offset %d, size %d) in sound %d", heOffset, size, soundID);
- heOffset = 0;
- }
- size -= heOffset;
-
- if (_overrideFreq) {
- // Used by the piano in Fatty Bear's Birthday Surprise
- rate = _overrideFreq;
- _overrideFreq = 0;
- }
-
- // Allocate a sound buffer, copy the data into it, and play
- sound = (char *)malloc(size);
- memcpy(sound, ptr + heOffset + 8, size);
- _vm->_mixer->stopHandle(_heSoundChannels[heChannel]);
- _vm->_mixer->playRaw(&_heSoundChannels[heChannel], sound, size, rate, flags, soundID);
-
- _vm->setHETimer(heChannel + 4);
- _heChannel[heChannel].sound = soundID;
- _heChannel[heChannel].priority = priority;
- _heChannel[heChannel].sbngBlock = (codeOffs != -1) ? 1 : 0;
- _heChannel[heChannel].codeOffs = codeOffs;
- memset(_heChannel[heChannel].soundVars, 0, sizeof(_heChannel[heChannel].soundVars));
- }
- // Support for PCM music in 3DO versions of Humongous Entertainment games
- else if (READ_UINT32(ptr) == MKID('MRAW')) {
- priority = *(ptr + 18);
- rate = READ_LE_UINT16(ptr + 22);
- ptr += 8 + READ_BE_UINT32(ptr+12);
-
- assert(READ_UINT32(ptr) == MKID('SDAT'));
- size = READ_BE_UINT32(ptr+4) - 8;
-
- flags = Audio::Mixer::FLAG_AUTOFREE;
-
- // Allocate a sound buffer, copy the data into it, and play
- sound = (char *)malloc(size);
- memcpy(sound, ptr + 8, size);
- _vm->_mixer->stopID(_currentMusic);
- _currentMusic = soundID;
- _vm->_mixer->playRaw(NULL, sound, size, rate, flags, soundID);
- }
- else if (READ_UINT32(ptr) == MKID('MIDI')) {
- if (_vm->_musicEngine) {
- _vm->_musicEngine->startSound(soundID);
- }
- }
-}
-
-void Sound::startHETalkSound(uint32 offset) {
- byte *ptr;
- int32 size;
-
- if (ConfMan.getBool("speech_mute"))
- return;
-
- if (!_sfxFile->isOpen()) {
- error("startHETalkSound: Speech file is not open");
- return;
- }
-
- _sfxMode |= 2;
- _vm->res.nukeResource(rtSound, 1);
-
- _sfxFile->seek(offset + 4, SEEK_SET);
- size = _sfxFile->readUint32BE();
- _sfxFile->seek(offset, SEEK_SET);
-
- _vm->res.createResource(rtSound, 1, size);
- ptr = _vm->getResourceAddress(rtSound, 1);
- _sfxFile->read(ptr, size);
-
- int channel = (_vm->VAR_TALK_CHANNEL != 0xFF) ? _vm->VAR(_vm->VAR_TALK_CHANNEL) : 0;
- addSoundToQueue2(1, 0, channel, 0);
-}
-
-} // End of namespace Scumm