diff options
Diffstat (limited to 'engines/cge/sound.cpp')
-rw-r--r-- | engines/cge/sound.cpp | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/engines/cge/sound.cpp b/engines/cge/sound.cpp new file mode 100644 index 0000000000..a163949ddd --- /dev/null +++ b/engines/cge/sound.cpp @@ -0,0 +1,227 @@ +/* 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. + * + */ + +/* + * This code is based on original Soltys source code + * Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon + */ + +#include "cge/general.h" +#include "cge/startup.h" +#include "cge/sound.h" +#include "cge/text.h" +#include "cge/cfile.h" +#include "cge/vol.h" + + +namespace CGE { + +Fx _fx = 16; // must precede SOUND!! +Sound _sound; + + +Sound::Sound() { + if (Startup::_soundOk) + open(); +} + + +Sound::~Sound() { + close(); +} + + +void Sound::close() { + killMidi(); + sndDone(); +} + + +void Sound::open() { + sndInit(); + play(_fx[30000], 8); +} + + +void Sound::play(DataCk *wav, int pan, int cnt) { + if (wav) { + stop(); + _smpinf._saddr = (uint8 *) &*(wav->eAddr()); + _smpinf._slen = (uint16)wav->size(); + _smpinf._span = pan; + _smpinf._sflag = cnt; + sndDigiStart(&_smpinf); + } +} + + +void Sound::stop() { + sndDigiStop(&_smpinf); +} + + +Fx::Fx(int size) : _emm(0L), _current(NULL) { + _cache = new Han[size]; + for (_size = 0; _size < size; _size++) { + _cache[_size]._ref = 0; + _cache[_size]._wav = NULL; + } +} + + +Fx::~Fx() { + clear(); + delete[] _cache; +} + + +void Fx::clear() { + Han *p, * q; + for (p = _cache, q = p + _size; p < q; p++) { + if (p->_ref) { + p->_ref = 0; + delete p->_wav; + p->_wav = NULL; + } + } + _emm.release(); + _current = NULL; +} + + +int Fx::find(int ref) { + Han *p, * q; + int i = 0; + for (p = _cache, q = p + _size; p < q; p++) { + if (p->_ref == ref) + break; + else + ++i; + } + return i; +} + + +void Fx::preload(int ref0) { + Han *cacheLim = _cache + _size; + int ref; + + for (ref = ref0; ref < ref0 + 10; ref++) { + static char fname[] = "FX00000.WAV"; + wtom(ref, fname + 2, 10, 5); + INI_FILE file = INI_FILE(fname); + DataCk *wav = loadWave(&file, &_emm); + if (wav) { + Han *p = &_cache[find(0)]; + if (p >= cacheLim) + break; + p->_wav = wav; + p->_ref = ref; + } + } +} + + +DataCk *Fx::load(int idx, int ref) { + static char fname[] = "FX00000.WAV"; + wtom(ref, fname + 2, 10, 5); + + INI_FILE file = INI_FILE(fname); + DataCk *wav = loadWave(&file, &_emm); + if (wav) { + Han *p = &_cache[idx]; + p->_wav = wav; + p->_ref = ref; + } + return wav; +} + + +DataCk *Fx::operator [](int ref) { + int i; + if ((i = find(ref)) < _size) + _current = _cache[i]._wav; + else { + if ((i = find(0)) >= _size) { + clear(); + i = 0; + } + _current = load(i, ref); + } + return _current; +} + + +static uint8 *midi = NULL; + + +void killMidi() { + sndMidiStop(); + if (midi) { + delete[] midi; + midi = NULL; + } +} + + +void loadMidi(int ref) { + static char fn[] = "00.MID"; + wtom(ref, fn, 10, 2); + if (INI_FILE::exist(fn)) { + killMidi(); + INI_FILE mid = fn; + if (mid._error == 0) { + uint16 siz = (uint16) mid.size(); + midi = new uint8[siz]; + if (midi) { + mid.read(midi, siz); + if (mid._error) + killMidi(); + else + sndMidiStart(midi); + } + } + } +} + + +void *Patch(int pat) { + void *p = NULL; + static char fn[] = "PATCH000.SND"; + + wtom(pat, fn + 5, 10, 3); + INI_FILE snd = fn; + if (!snd._error) { + uint16 siz = (uint16) snd.size(); + p = (uint8 *) malloc(siz); + if (p) { + snd.read(p, siz); + if (snd._error) { + free(p); + p = NULL; + } + } + } + return p; +} + +} // End of namespace CGE |