aboutsummaryrefslogtreecommitdiff
path: root/engines/zvision/sound/zork_raw.cpp
diff options
context:
space:
mode:
authorMarisa-Chan2014-06-13 21:43:04 +0700
committerMarisa-Chan2014-06-13 21:43:04 +0700
commit45589950c0fb1a449351e6a00ef10d42290d8bae (patch)
tree44e4eedcb7e69d5fc386155b000ed038af07251d /engines/zvision/sound/zork_raw.cpp
parent48360645dcd5f8fddb135b6e31ae5cae4be8d77f (diff)
parent5c005ad3a3f1df0bc968c85c1cf0fc48e36ab0b2 (diff)
downloadscummvm-rg350-45589950c0fb1a449351e6a00ef10d42290d8bae.tar.gz
scummvm-rg350-45589950c0fb1a449351e6a00ef10d42290d8bae.tar.bz2
scummvm-rg350-45589950c0fb1a449351e6a00ef10d42290d8bae.zip
Merge remote-tracking branch 'upstream/master' into zvision
Conflicts: engines/zvision/animation/rlf_animation.cpp engines/zvision/animation_control.h engines/zvision/core/console.cpp engines/zvision/core/events.cpp engines/zvision/cursors/cursor.cpp engines/zvision/cursors/cursor_manager.cpp engines/zvision/cursors/cursor_manager.h engines/zvision/fonts/truetype_font.cpp engines/zvision/graphics/render_manager.cpp engines/zvision/graphics/render_manager.h engines/zvision/inventory/inventory_manager.h engines/zvision/inventory_manager.h engines/zvision/meta_animation.h engines/zvision/module.mk engines/zvision/scripting/actions.cpp engines/zvision/scripting/control.h engines/zvision/scripting/controls/animation_control.cpp engines/zvision/scripting/controls/animation_control.h engines/zvision/scripting/controls/input_control.cpp engines/zvision/scripting/controls/lever_control.cpp engines/zvision/scripting/controls/timer_node.cpp engines/zvision/scripting/controls/timer_node.h engines/zvision/scripting/puzzle.h engines/zvision/scripting/scr_file_handling.cpp engines/zvision/scripting/script_manager.cpp engines/zvision/scripting/script_manager.h engines/zvision/sidefx.cpp engines/zvision/sound/zork_raw.cpp engines/zvision/sound/zork_raw.h engines/zvision/video/video.cpp engines/zvision/video/zork_avi_decoder.h engines/zvision/zvision.cpp engines/zvision/zvision.h
Diffstat (limited to 'engines/zvision/sound/zork_raw.cpp')
-rw-r--r--engines/zvision/sound/zork_raw.cpp289
1 files changed, 289 insertions, 0 deletions
diff --git a/engines/zvision/sound/zork_raw.cpp b/engines/zvision/sound/zork_raw.cpp
new file mode 100644
index 0000000000..a4d091f3c0
--- /dev/null
+++ b/engines/zvision/sound/zork_raw.cpp
@@ -0,0 +1,289 @@
+/* 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.
+ *
+ */
+
+#include "common/scummsys.h"
+
+#include "zvision/zork_raw.h"
+
+#include "zvision/zvision.h"
+#include "zvision/detection.h"
+#include "zvision/utility.h"
+
+#include "common/file.h"
+#include "common/str.h"
+#include "common/stream.h"
+#include "common/memstream.h"
+#include "common/bufferedstream.h"
+#include "common/util.h"
+
+#include "audio/audiostream.h"
+#include "audio/decoders/raw.h"
+
+
+namespace ZVision {
+
+const int16 RawChunkStream::_stepAdjustmentTable[8] = { -1, -1, -1, 1, 4, 7, 10, 12};
+
+const int32 RawChunkStream::_amplitudeLookupTable[89] = {0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E,
+ 0x0010, 0x0011, 0x0013, 0x0015, 0x0017, 0x0019, 0x001C, 0x001F,
+ 0x0022, 0x0025, 0x0029, 0x002D, 0x0032, 0x0037, 0x003C, 0x0042,
+ 0x0049, 0x0050, 0x0058, 0x0061, 0x006B, 0x0076, 0x0082, 0x008F,
+ 0x009D, 0x00AD, 0x00BE, 0x00D1, 0x00E6, 0x00FD, 0x0117, 0x0133,
+ 0x0151, 0x0173, 0x0198, 0x01C1, 0x01EE, 0x0220, 0x0256, 0x0292,
+ 0x02D4, 0x031C, 0x036C, 0x03C3, 0x0424, 0x048E, 0x0502, 0x0583,
+ 0x0610, 0x06AB, 0x0756, 0x0812, 0x08E0, 0x09C3, 0x0ABD, 0x0BD0,
+ 0x0CFF, 0x0E4C, 0x0FBA, 0x114C, 0x1307, 0x14EE, 0x1706, 0x1954,
+ 0x1BDC, 0x1EA5, 0x21B6, 0x2515, 0x28CA, 0x2CDF, 0x315B, 0x364B,
+ 0x3BB9, 0x41B2, 0x4844, 0x4F7E, 0x5771, 0x602F, 0x69CE, 0x7462, 0x7FFF
+ };
+
+RawChunkStream::RawChunkStream(bool stereo) {
+ if (stereo)
+ _stereo = 1;
+ else
+ _stereo = 0;
+
+ init();
+}
+
+void RawChunkStream::init() {
+ _lastSample[0].index = 0;
+ _lastSample[0].sample = 0;
+ _lastSample[1].index = 0;
+ _lastSample[1].sample = 0;
+}
+
+RawChunkStream::RawChunk RawChunkStream::readNextChunk(Common::SeekableReadStream *stream) {
+ RawChunk tmp;
+ tmp.size = 0;
+ tmp.data = NULL;
+
+ if (stream && (stream->size() == 0 || stream->eos()))
+ return tmp;
+
+ tmp.size = (stream->size() - stream->pos()) * 2;
+ tmp.data = (int16 *)calloc(tmp.size, 1);
+
+ readBuffer(tmp.data, stream, stream->size() - stream->pos());
+
+ return tmp;
+}
+
+int RawChunkStream::readBuffer(int16 *buffer, Common::SeekableReadStream *stream, const int numSamples) {
+ int32 bytesRead = 0;
+
+ // 0: Left, 1: Right
+ uint channel = 0;
+
+ while (bytesRead < numSamples) {
+ byte encodedSample = stream->readByte();
+ if (stream->eos()) {
+ return bytesRead;
+ }
+ bytesRead++;
+
+ int16 index = _lastSample[channel].index;
+ uint32 lookUpSample = _amplitudeLookupTable[index];
+
+ int32 sample = 0;
+
+ if (encodedSample & 0x40)
+ sample += lookUpSample;
+ if (encodedSample & 0x20)
+ sample += lookUpSample >> 1;
+ if (encodedSample & 0x10)
+ sample += lookUpSample >> 2;
+ if (encodedSample & 8)
+ sample += lookUpSample >> 3;
+ if (encodedSample & 4)
+ sample += lookUpSample >> 4;
+ if (encodedSample & 2)
+ sample += lookUpSample >> 5;
+ if (encodedSample & 1)
+ sample += lookUpSample >> 6;
+ if (encodedSample & 0x80)
+ sample = -sample;
+
+ sample += _lastSample[channel].sample;
+ sample = CLIP<int32>(sample, -32768, 32767);
+
+ buffer[bytesRead - 1] = (int16)sample;
+
+ index += _stepAdjustmentTable[(encodedSample >> 4) & 7];
+ index = CLIP<int16>(index, 0, 88);
+
+ _lastSample[channel].sample = sample;
+ _lastSample[channel].index = index;
+
+ // Increment and wrap the channel
+ channel = (channel + 1) & _stereo;
+ }
+ return bytesRead;
+}
+
+const SoundParams RawZorkStream::_zNemSoundParamLookupTable[32] = {{'0', 0x1F40, false, false, false},
+ {'1', 0x1F40, true, false, false},
+ {'2', 0x1F40, false, false, true},
+ {'3', 0x1F40, true, false, true},
+ {'4', 0x2B11, false, false, false},
+ {'5', 0x2B11, true, false, false},
+ {'6', 0x2B11, false, false, true},
+ {'7', 0x2B11, true, false, true},
+ {'8', 0x5622, false, false, false},
+ {'9', 0x5622, true, false, false},
+ {'a', 0x5622, false, false, true},
+ {'b', 0x5622, true, false, true},
+ {'c', 0xAC44, false, false, false},
+ {'d', 0xAC44, true, false, false},
+ {'e', 0xAC44, false, false, true},
+ {'f', 0xAC44, true, false, true},
+ {'g', 0x1F40, false, true, false},
+ {'h', 0x1F40, true, true, false},
+ {'j', 0x1F40, false, true, true},
+ {'k', 0x1F40, true, true, true},
+ {'l', 0x2B11, false, true, false},
+ {'m', 0x2B11, true, true, false},
+ {'n', 0x2B11, false, true, true},
+ {'p', 0x2B11, true, true, true},
+ {'q', 0x5622, false, true, false},
+ {'r', 0x5622, true, true, false},
+ {'s', 0x5622, false, true, true},
+ {'t', 0x5622, true, true, true},
+ {'u', 0xAC44, false, true, false},
+ {'v', 0xAC44, true, true, false},
+ {'w', 0xAC44, false, true, true},
+ {'x', 0xAC44, true, true, true}
+};
+
+const SoundParams RawZorkStream::_zgiSoundParamLookupTable[24] = {{'4', 0x2B11, false, false, false},
+ {'5', 0x2B11, true, false, false},
+ {'6', 0x2B11, false, false, true},
+ {'7', 0x2B11, true, false, true},
+ {'8', 0x5622, false, false, false},
+ {'9', 0x5622, true, false, false},
+ {'a', 0x5622, false, false, true},
+ {'b', 0x5622, true, false, true},
+ {'c', 0xAC44, false, false, false},
+ {'d', 0xAC44, true, false, false},
+ {'e', 0xAC44, false, false, true},
+ {'f', 0xAC44, true, false, true},
+ {'g', 0x2B11, false, true, false},
+ {'h', 0x2B11, true, true, false},
+ {'j', 0x2B11, false, true, true},
+ {'k', 0x2B11, true, true, true},
+ {'m', 0x5622, false, true, false},
+ {'n', 0x5622, true, true, false},
+ {'p', 0x5622, false, true, true},
+ {'q', 0x5622, true, true, true},
+ {'r', 0xAC44, false, true, false},
+ {'s', 0xAC44, true, true, false},
+ {'t', 0xAC44, false, true, true},
+ {'u', 0xAC44, true, true, true}
+};
+
+RawZorkStream::RawZorkStream(uint32 rate, bool stereo, DisposeAfterUse::Flag disposeStream, Common::SeekableReadStream *stream)
+ : _rate(rate),
+ _stereo(0),
+ _stream(stream, disposeStream),
+ _endOfData(false),
+ _streamReader(stereo) {
+ if (stereo)
+ _stereo = 1;
+
+ // Calculate the total playtime of the stream
+ if (stereo)
+ _playtime = Audio::Timestamp(0, _stream->size() / 2, rate);
+ else
+ _playtime = Audio::Timestamp(0, _stream->size(), rate);
+}
+
+int RawZorkStream::readBuffer(int16 *buffer, const int numSamples) {
+
+ int32 bytesRead = _streamReader.readBuffer(buffer, _stream.get(), numSamples);
+
+ if (_stream->eos())
+ _endOfData = true;
+
+ return bytesRead;
+}
+
+bool RawZorkStream::rewind() {
+ _stream->seek(0, 0);
+ _stream->clearErr();
+ _endOfData = false;
+ _streamReader.init();
+
+ return true;
+}
+
+Audio::RewindableAudioStream *makeRawZorkStream(Common::SeekableReadStream *stream,
+ int rate,
+ bool stereo,
+ DisposeAfterUse::Flag disposeAfterUse) {
+ if (stereo)
+ assert(stream->size() % 2 == 0);
+
+ return new RawZorkStream(rate, stereo, disposeAfterUse, stream);
+}
+
+Audio::RewindableAudioStream *makeRawZorkStream(const byte *buffer, uint32 size,
+ int rate,
+ bool stereo,
+ DisposeAfterUse::Flag disposeAfterUse) {
+ return makeRawZorkStream(new Common::MemoryReadStream(buffer, size, disposeAfterUse), rate, stereo, DisposeAfterUse::YES);
+}
+
+Audio::RewindableAudioStream *makeRawZorkStream(const Common::String &filePath, ZVision *engine) {
+ Common::File *file = new Common::File();
+ assert(engine->getSearchManager()->openFile(*file, filePath));
+
+ Common::String fileName = getFileName(filePath);
+ fileName.toLowercase();
+
+ SoundParams soundParams;
+
+ if (engine->getGameId() == GID_NEMESIS) {
+ for (int i = 0; i < 32; ++i) {
+ if (RawZorkStream::_zNemSoundParamLookupTable[i].identifier == (fileName[6]))
+ soundParams = RawZorkStream::_zNemSoundParamLookupTable[i];
+ }
+ } else if (engine->getGameId() == GID_GRANDINQUISITOR) {
+ for (int i = 0; i < 24; ++i) {
+ if (RawZorkStream::_zgiSoundParamLookupTable[i].identifier == (fileName[7]))
+ soundParams = RawZorkStream::_zgiSoundParamLookupTable[i];
+ }
+ }
+
+ if (soundParams.packed) {
+ return makeRawZorkStream(wrapBufferedSeekableReadStream(file, 2048, DisposeAfterUse::YES), soundParams.rate, soundParams.stereo, DisposeAfterUse::YES);
+ } else {
+ byte flags = 0;
+ if (soundParams.bits16)
+ flags |= Audio::FLAG_16BITS | Audio::FLAG_LITTLE_ENDIAN;
+ if (soundParams.stereo)
+ flags |= Audio::FLAG_STEREO;
+
+ return Audio::makeRawStream(file, soundParams.rate, flags, DisposeAfterUse::YES);
+ }
+}
+
+} // End of namespace ZVision