aboutsummaryrefslogtreecommitdiff
path: root/engines/parallaction
diff options
context:
space:
mode:
Diffstat (limited to 'engines/parallaction')
-rw-r--r--engines/parallaction/disk.cpp145
-rw-r--r--engines/parallaction/disk.h40
-rw-r--r--engines/parallaction/disk_br.cpp114
-rw-r--r--engines/parallaction/disk_ns.cpp79
-rw-r--r--engines/parallaction/gfxbase.cpp8
-rw-r--r--engines/parallaction/iff.cpp276
-rw-r--r--engines/parallaction/iff.h105
-rw-r--r--engines/parallaction/module.mk2
-rw-r--r--engines/parallaction/sound.h36
-rw-r--r--engines/parallaction/sound_br.cpp90
-rw-r--r--engines/parallaction/sound_ns.cpp69
11 files changed, 313 insertions, 651 deletions
diff --git a/engines/parallaction/disk.cpp b/engines/parallaction/disk.cpp
new file mode 100644
index 0000000000..6928c1eefc
--- /dev/null
+++ b/engines/parallaction/disk.cpp
@@ -0,0 +1,145 @@
+/* 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 "parallaction/disk.h"
+#include "parallaction/graphics.h"
+
+namespace Parallaction {
+
+void ILBMLoader::setupBuffer(uint32 w, uint32 h) {
+ _intBuffer = 0;
+ switch (_bodyMode) {
+ case BODYMODE_SURFACE:
+ if (!_surf) {
+ _surf = new Graphics::Surface;
+ assert(_surf);
+ }
+ _surf->create(w, h, 1);
+ _mode = Graphics::ILBMDecoder::ILBM_UNPACK_PLANES;
+ _intBuffer = (byte*)_surf->pixels;
+ break;
+
+ case BODYMODE_MASKBUFFER:
+ if (!_maskBuffer) {
+ _maskBuffer = new MaskBuffer;
+ assert(_maskBuffer);
+ }
+ _maskBuffer->create(w, h);
+ _mode = Graphics::ILBMDecoder::ILBM_2_PACK_PLANES;
+ _intBuffer = _maskBuffer->data;
+ break;
+
+ case BODYMODE_PATHBUFFER:
+ if (!_pathBuffer) {
+ _pathBuffer = new PathBuffer;
+ assert(_pathBuffer);
+ }
+ _pathBuffer->create(w, h);
+ _mode = Graphics::ILBMDecoder::ILBM_1_PACK_PLANES;
+ _intBuffer = _pathBuffer->data;
+ break;
+
+ default:
+ error("Invalid bodyMode '%i' for ILBMLoader", _bodyMode);
+ break;
+ }
+}
+
+bool ILBMLoader::callback(Common::IFFChunk &chunk) {
+ switch (chunk._type) {
+ case ID_BMHD:
+ _decoder.loadHeader(chunk._stream);
+ break;
+
+ case ID_CMAP:
+ if (_palette) {
+ chunk._stream->read(_palette, chunk._size);
+ }
+ break;
+
+ case ID_CRNG:
+ if (_crng) {
+ PaletteFxRange *ptr = &_crng[_numCRNG];
+ chunk._stream->read((byte*)ptr, chunk._size);
+ ptr->_timer = FROM_BE_16(ptr->_timer);
+ ptr->_step = FROM_BE_16(ptr->_step);
+ ptr->_flags = FROM_BE_16(ptr->_flags);
+ ++_numCRNG;
+ }
+ break;
+
+ case ID_BODY:
+ setupBuffer(_decoder._header.width, _decoder._header.height);
+ assert(_intBuffer);
+ _decoder.loadBitmap(_mode, _intBuffer, chunk._stream);
+ return true; // stop the parser
+ }
+
+ return false;
+}
+
+void ILBMLoader::load(Common::ReadStream *in, bool disposeStream) {
+ Common::IFFParser parser(in, disposeStream);
+ Common::Functor1Mem< Common::IFFChunk&, bool, ILBMLoader > c(this, &ILBMLoader::callback);
+ parser.parse(c);
+}
+
+ILBMLoader::ILBMLoader(uint32 bodyMode, byte *palette, PaletteFxRange *crng) {
+ _bodyMode = bodyMode;
+ _surf = 0;
+ _maskBuffer = 0;
+ _pathBuffer = 0;
+ _palette = palette;
+ _crng = crng;
+ _numCRNG = 0;
+}
+
+ILBMLoader::ILBMLoader(Graphics::Surface *surf, byte *palette, PaletteFxRange *crng) {
+ _bodyMode = ILBMLoader::BODYMODE_SURFACE;
+ _surf = surf;
+ _palette = palette;
+ _crng = crng;
+ _numCRNG = 0;
+}
+
+ILBMLoader::ILBMLoader(MaskBuffer *buffer) {
+ _bodyMode = ILBMLoader::BODYMODE_MASKBUFFER;
+ _maskBuffer = buffer;
+ _palette = 0;
+ _crng = 0;
+ _numCRNG = 0;
+}
+
+ILBMLoader::ILBMLoader(PathBuffer *buffer) {
+ _bodyMode = ILBMLoader::BODYMODE_PATHBUFFER;
+ _pathBuffer = buffer;
+ _palette = 0;
+ _crng = 0;
+ _numCRNG = 0;
+}
+
+
+
+}
diff --git a/engines/parallaction/disk.h b/engines/parallaction/disk.h
index 4cc2711e96..a9da429473 100644
--- a/engines/parallaction/disk.h
+++ b/engines/parallaction/disk.h
@@ -33,6 +33,7 @@
#include "common/file.h"
#include "graphics/surface.h"
+#include "graphics/iff.h"
@@ -77,8 +78,37 @@ public:
virtual Table* loadTable(const char* name) = 0;
virtual Common::SeekableReadStream* loadMusic(const char* name) = 0;
virtual Common::SeekableReadStream* loadSound(const char* name) = 0;
- virtual void loadMask(const char *name, MaskBuffer &buffer) { }
- virtual void loadPath(const char *name, PathBuffer &buffer) { }
+ virtual MaskBuffer *loadMask(const char *name, uint32 w, uint32 h) { return 0; }
+ virtual PathBuffer *loadPath(const char *name, uint32 w, uint32 h) { return 0; }
+};
+
+struct PaletteFxRange;
+
+struct ILBMLoader {
+ enum {
+ BODYMODE_SURFACE,
+ BODYMODE_MASKBUFFER,
+ BODYMODE_PATHBUFFER
+ };
+ uint32 _bodyMode;
+ Graphics::Surface *_surf;
+ MaskBuffer *_maskBuffer;
+ PathBuffer *_pathBuffer;
+ byte *_palette;
+ PaletteFxRange *_crng;
+ uint32 _mode;
+ byte* _intBuffer;
+ uint32 _numCRNG;
+ Graphics::ILBMDecoder _decoder;
+
+ ILBMLoader(uint32 bodyMode, byte *palette = 0, PaletteFxRange *crng = 0);
+ ILBMLoader(Graphics::Surface *surf, byte *palette = 0, PaletteFxRange *crng = 0);
+ ILBMLoader(MaskBuffer *buffer);
+ ILBMLoader(PathBuffer *buffer);
+
+ bool callback(Common::IFFChunk &chunk);
+ void setupBuffer(uint32 w, uint32 h);
+ void load(Common::ReadStream *in, bool disposeStream = false);
};
@@ -235,8 +265,8 @@ public:
Table* loadTable(const char* name);
Common::SeekableReadStream* loadMusic(const char* name);
Common::SeekableReadStream* loadSound(const char* name);
- void loadMask(const char *name, MaskBuffer &buffer);
- void loadPath(const char *name, PathBuffer &buffer);
+ MaskBuffer *loadMask(const char *name, uint32 w, uint32 h);
+ PathBuffer *loadPath(const char *name, uint32 w, uint32 h);
};
class DosDemoDisk_br : public DosDisk_br {
@@ -272,7 +302,7 @@ public:
GfxObj* loadObjects(const char *name, uint8 part = 0);
Common::SeekableReadStream* loadMusic(const char* name);
Common::SeekableReadStream* loadSound(const char* name);
- void loadMask(const char *name, MaskBuffer &buffer);
+ MaskBuffer *loadMask(const char *name, uint32 w, uint32 h);
};
} // namespace Parallaction
diff --git a/engines/parallaction/disk_br.cpp b/engines/parallaction/disk_br.cpp
index ec4fc32cc1..46c849e6f2 100644
--- a/engines/parallaction/disk_br.cpp
+++ b/engines/parallaction/disk_br.cpp
@@ -28,7 +28,6 @@
#include "common/config-manager.h"
#include "parallaction/parallaction.h"
#include "parallaction/parser.h"
-#include "parallaction/iff.h"
namespace Parallaction {
@@ -331,32 +330,40 @@ void DosDisk_br::loadSlide(BackgroundInfo& info, const char *name) {
}
}
-void DosDisk_br::loadMask(const char *name, MaskBuffer &buffer) {
+MaskBuffer *DosDisk_br::loadMask(const char *name, uint32 w, uint32 h) {
if (!name) {
- return;
+ return 0;
}
Common::SeekableReadStream *stream = openFile("msk/" + Common::String(name), ".msk");
- // NOTE: info.width and info.height are only valid if the background graphics
- // have already been loaded
- buffer.bigEndian = false;
- stream->read(buffer.data, buffer.size);
+ MaskBuffer *buffer = new MaskBuffer;
+ assert(buffer);
+ buffer->create(w, h);
+ buffer->bigEndian = false;
+
+ stream->read(buffer->data, buffer->size);
delete stream;
+
+ return buffer;
}
-void DosDisk_br::loadPath(const char *name, PathBuffer &buffer) {
+PathBuffer *DosDisk_br::loadPath(const char *name, uint32 w, uint32 h) {
if (!name) {
- return;
+ return 0;
}
Common::SeekableReadStream *stream = openFile("pth/" + Common::String(name), ".pth");
- // NOTE: info.width and info.height are only valid if the background graphics
- // have already been loaded
- buffer.bigEndian = false;
- stream->read(buffer.data, buffer.size);
+ PathBuffer *buffer = new PathBuffer;
+ assert(buffer);
+ buffer->create(w, h);
+ buffer->bigEndian = false;
+
+ stream->read(buffer->data, buffer->size);
delete stream;
+
+ return buffer;
}
void DosDisk_br::loadScenery(BackgroundInfo& info, const char *name, const char *mask, const char* path) {
@@ -380,18 +387,12 @@ void DosDisk_br::loadScenery(BackgroundInfo& info, const char *name, const char
}
if (mask) {
- info._mask = new MaskBuffer;
- info._mask->create(info.width, info.height);
- loadMask(mask, *info._mask);
+ info._mask = loadMask(mask, info.width, info.height);
}
if (path) {
- info._path = new PathBuffer;
- info._path->create(info.width, info.height);
- loadPath(path, *info._path);
+ info._path = loadPath(path, info.width, info.height);
}
-
- return;
}
Table* DosDisk_br::loadTable(const char* name) {
@@ -459,7 +460,7 @@ void AmigaDisk_br::adjustForPalette(Graphics::Surface &surf, int transparentColo
void AmigaDisk_br::loadBackground(BackgroundInfo& info, const char *filename) {
byte r,g,b;
- byte *pal, *p;
+ byte *p;
Common::SeekableReadStream *stream;
uint i;
@@ -488,20 +489,14 @@ void AmigaDisk_br::loadBackground(BackgroundInfo& info, const char *filename) {
}
stream = openFile("backs/" + Common::String(filename), ".bkg");
- ILBMDecoder decoder(stream, true);
- // TODO: encapsulate surface creation
- info.bg.w = decoder.getWidth();
- info.bg.h = decoder.getHeight();
- info.bg.pitch = info.bg.w;
- info.bg.bytesPerPixel = 1;
- info.bg.pixels = decoder.getBitmap();
- assert(info.bg.pixels);
+ byte pal[768];
+ ILBMLoader loader(&info.bg, pal);
+ loader.load(stream, true);
info.width = info.bg.w;
info.height = info.bg.h;
- pal = decoder.getPalette();
p = pal;
for (i = 16; i < 32; i++) {
r = *p >> 2;
@@ -516,8 +511,6 @@ void AmigaDisk_br::loadBackground(BackgroundInfo& info, const char *filename) {
// Overwrite the first color (transparent key) in the palette
info.palette.setEntry(0, pal[0] >> 2, pal[1] >> 2, pal[2] >> 0);
- delete []pal;
-
// background data is drawn used the upper portion of the palette
adjustForPalette(info.bg);
}
@@ -543,27 +536,24 @@ void finalpass(byte *buffer, uint32 size) {
}
}
-void AmigaDisk_br::loadMask(const char *name, MaskBuffer &buffer) {
+MaskBuffer *AmigaDisk_br::loadMask(const char *name, uint32 w, uint32 h) {
if (!name) {
- return;
+ return 0;
}
debugC(1, kDebugDisk, "AmigaDisk_br::loadMask '%s'", name);
Common::SeekableReadStream *stream = tryOpenFile("msk/" + Common::String(name), ".msk");
if (!stream) {
- return;
+ return 0;
}
- ILBMDecoder decoder(stream, true);
+ ILBMLoader loader(ILBMLoader::BODYMODE_MASKBUFFER);
+ loader.load(stream, true);
- // TODO: the buffer is allocated by the caller, so a copy here is
- // unavoidable... a better solution would be inform the function
- // of the size of the mask (the size in the mask file is not valid!)
- byte *bitmap = decoder.getBitmap(2, true);
- memcpy(buffer.data, bitmap, buffer.size);
- finalpass(buffer.data, buffer.size);
-
- buffer.bigEndian = true;
+ MaskBuffer *buffer = loader._maskBuffer;
+ buffer->bigEndian = true;
+ finalpass(buffer->data, buffer->size);
+ return buffer;
}
void AmigaDisk_br::loadScenery(BackgroundInfo& info, const char* name, const char* mask, const char* path) {
@@ -573,18 +563,12 @@ void AmigaDisk_br::loadScenery(BackgroundInfo& info, const char* name, const cha
loadBackground(info, name);
}
if (mask) {
- info._mask = new MaskBuffer;
- info._mask->create(info.width, info.height);
- loadMask(mask, *info._mask);
+ info._mask = loadMask(mask, info.width, info.height);
}
if (path) {
- info._path = new PathBuffer;
- info._path->create(info.width, info.height);
- loadPath(path, *info._path);
+ info._path = loadPath(path, info.width, info.height);
}
-
- return;
}
void AmigaDisk_br::loadSlide(BackgroundInfo& info, const char *name) {
@@ -596,20 +580,13 @@ GfxObj* AmigaDisk_br::loadStatic(const char* name) {
debugC(1, kDebugDisk, "AmigaDisk_br::loadStatic '%s'", name);
Common::String sName = name;
-
Common::SeekableReadStream *stream = openFile("ras/" + sName, ".ras");
- ILBMDecoder decoder(stream, true);
- Graphics::Surface* surf = new Graphics::Surface;
- assert(surf);
+ ILBMLoader loader(ILBMLoader::BODYMODE_SURFACE);
+ loader.load(stream, true);
- // TODO: encapsulate surface creation
- surf->w = decoder.getWidth();
- surf->h = decoder.getHeight();
- surf->pitch = surf->w;
- surf->bytesPerPixel = 1;
- surf->pixels = decoder.getBitmap();
- assert(surf->pixels);
+ Graphics::Surface* surf = loader._surf;
+ assert(surf);
// Static pictures are drawn used the upper half of the palette: this must be
// done before shadow mask is applied. This way, only really transparent pixels
@@ -741,15 +718,16 @@ GfxObj* AmigaDisk_br::loadObjects(const char *name, uint8 part) {
debugC(5, kDebugDisk, "AmigaDisk_br::loadObjects");
Common::SeekableReadStream *stream = openFile(name);
- ILBMDecoder decoder(stream, true);
+ ILBMLoader loader(ILBMLoader::BODYMODE_SURFACE);
+ loader.load(stream, true);
uint16 max = objectsMax[part];
if (_vm->getFeatures() & GF_DEMO)
max = 72;
byte *data = new byte[max * 2601];
- byte *srcPtr = decoder.getBitmap();
- int w = decoder.getWidth();
+ byte *srcPtr = (byte*)loader._surf->getBasePtr(0,0);
+ int w = loader._surf->w;
// Convert to the expected display format
for (int i = 0; i < max; i++) {
@@ -764,7 +742,7 @@ GfxObj* AmigaDisk_br::loadObjects(const char *name, uint8 part) {
dst += 51;
}
}
- free(srcPtr);
+ delete loader._surf;
return new GfxObj(0, new Cnv(max, 51, 51, data, true));
}
diff --git a/engines/parallaction/disk_ns.cpp b/engines/parallaction/disk_ns.cpp
index 8aa2a9f543..d35b338069 100644
--- a/engines/parallaction/disk_ns.cpp
+++ b/engines/parallaction/disk_ns.cpp
@@ -23,18 +23,11 @@
*
*/
-#include "parallaction/iff.h"
#include "common/config-manager.h"
#include "parallaction/parser.h"
#include "parallaction/parallaction.h"
-namespace Audio {
- class AudioStream;
-
- AudioStream *make8SVXStream(Common::ReadStream &input);
-}
-
namespace Parallaction {
@@ -900,56 +893,18 @@ void AmigaDisk_ns::buildMask(byte* buf) {
}
}
-// TODO: extend the ILBMDecoder to return CRNG chunks and get rid of this BackgroundDecoder crap
-class BackgroundDecoder : public ILBMDecoder {
-
-public:
- BackgroundDecoder(Common::SeekableReadStream *input, bool disposeStream = false) : ILBMDecoder(input, disposeStream) {
- }
-
- uint32 getCRNG(PaletteFxRange *ranges, uint32 num) {
- assert(ranges);
-
- uint32 size = _parser.getIFFBlockSize(ID_CRNG);
- if (size == (uint32)-1) {
- return 0;
- }
-
- uint32 count = MIN((uint32)(size / sizeof(PaletteFxRange)), num);
- _parser.loadIFFBlock(ID_CRNG, ranges, count * sizeof(PaletteFxRange));
-
- for (uint32 i = 0; i < count; ++i) {
- ranges[i]._timer = FROM_BE_16(ranges[i]._timer);
- ranges[i]._step = FROM_BE_16(ranges[i]._step);
- ranges[i]._flags = FROM_BE_16(ranges[i]._flags);
- }
-
- return count;
- }
-};
-
void AmigaDisk_ns::loadBackground(BackgroundInfo& info, const char *name) {
-
- Common::SeekableReadStream *s = openFile(name);
- BackgroundDecoder decoder(s, true);
-
PaletteFxRange ranges[6];
- memset(ranges, 0, 6*sizeof(PaletteFxRange));
- decoder.getCRNG(ranges, 6);
+ byte pal[768];
- // TODO: encapsulate surface creation
- info.bg.w = decoder.getWidth();
- info.bg.h = decoder.getHeight();
- info.bg.pitch = info.bg.w;
- info.bg.bytesPerPixel = 1;
- info.bg.pixels = decoder.getBitmap();
+ Common::SeekableReadStream *s = openFile(name);
+ ILBMLoader loader(&info.bg, pal, ranges);
+ loader.load(s, true);
info.width = info.bg.w;
info.height = info.bg.h;
- byte *pal = decoder.getPalette();
- assert(pal);
byte *p = pal;
for (uint i = 0; i < 32; i++) {
byte r = *p >> 2;
@@ -960,7 +915,6 @@ void AmigaDisk_ns::loadBackground(BackgroundInfo& info, const char *name) {
p++;
info.palette.setEntry(i, r, g, b);
}
- delete []pal;
for (uint j = 0; j < 6; j++) {
info.setPaletteRange(j, ranges[j]);
@@ -979,9 +933,9 @@ void AmigaDisk_ns::loadMask(BackgroundInfo& info, const char *name) {
return; // no errors if missing mask files: not every location has one
}
- ILBMDecoder decoder(s, true);
- byte *pal = decoder.getPalette();
- assert(pal);
+ byte pal[768];
+ ILBMLoader loader(ILBMLoader::BODYMODE_MASKBUFFER, pal);
+ loader.load(s, true);
byte r, g, b;
for (uint i = 0; i < 4; i++) {
@@ -990,14 +944,8 @@ void AmigaDisk_ns::loadMask(BackgroundInfo& info, const char *name) {
b = pal[i*3+2];
info.layers[i] = (((r << 4) & 0xF00) | (g & 0xF0) | (b >> 4)) & 0xFF;
}
- delete []pal;
- info._mask = new MaskBuffer;
- info._mask->w = info.width;
- info._mask->h = info.height;
- info._mask->internalWidth = info.width >> 2;
- info._mask->size = info._mask->internalWidth * info._mask->h;
- info._mask->data = decoder.getBitmap(2, true);
+ info._mask = loader._maskBuffer;
}
void AmigaDisk_ns::loadPath(BackgroundInfo& info, const char *name) {
@@ -1010,15 +958,10 @@ void AmigaDisk_ns::loadPath(BackgroundInfo& info, const char *name) {
return; // no errors if missing path files: not every location has one
}
- ILBMDecoder decoder(s, true);
- info._path = new PathBuffer;
- info._path->create(info.width, info.height);
+ ILBMLoader loader(ILBMLoader::BODYMODE_PATHBUFFER);
+ loader.load(s, true);
+ info._path = loader._pathBuffer;
info._path->bigEndian = true;
-
- byte *bitmap = decoder.getBitmap(1, true);
- assert(bitmap);
- memcpy(info._path->data, bitmap, info._path->size);
- delete bitmap;
}
void AmigaDisk_ns::loadScenery(BackgroundInfo& info, const char* background, const char* mask, const char* path) {
diff --git a/engines/parallaction/gfxbase.cpp b/engines/parallaction/gfxbase.cpp
index ec72b14c15..fc6cb28d9e 100644
--- a/engines/parallaction/gfxbase.cpp
+++ b/engines/parallaction/gfxbase.cpp
@@ -162,9 +162,7 @@ void BackgroundInfo::loadGfxObjMask(const char *name, GfxObj *obj) {
Common::Rect rect;
obj->getRect(0, rect);
- MaskBuffer *buf = new MaskBuffer;
- buf->create(rect.width(), rect.height());
- _vm->_disk->loadMask(name, *buf);
+ MaskBuffer *buf = _vm->_disk->loadMask(name, rect.width(), rect.height());
obj->_maskId = addMaskPatch(buf);
obj->_hasMask = true;
@@ -174,9 +172,7 @@ void BackgroundInfo::loadGfxObjPath(const char *name, GfxObj *obj) {
Common::Rect rect;
obj->getRect(0, rect);
- PathBuffer *buf = new PathBuffer;
- buf->create(rect.width(), rect.height());
- _vm->_disk->loadPath(name, *buf);
+ PathBuffer *buf = _vm->_disk->loadPath(name, rect.width(), rect.height());
obj->_pathId = addPathPatch(buf);
obj->_hasPath = true;
diff --git a/engines/parallaction/iff.cpp b/engines/parallaction/iff.cpp
deleted file mode 100644
index 43dcac3697..0000000000
--- a/engines/parallaction/iff.cpp
+++ /dev/null
@@ -1,276 +0,0 @@
-/* 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/iff_container.h"
-#include "common/stream.h"
-#include "common/util.h"
-#include "parallaction/iff.h"
-
-namespace Parallaction {
-
-
-void IFFParser::setInputStream(Common::SeekableReadStream *stream) {
- destroy();
-
- assert(stream);
- _stream = stream;
- _startOffset = 0;
- _endOffset = _stream->size();
-
- _formType = 0;
- _formSize = (uint32)-1;
-
- if (_stream->size() < 12) {
- // this file is too small to be a valid IFF container
- return;
- }
-
- if (_stream->readUint32BE() != ID_FORM) {
- // no FORM header was found
- return;
- }
-
- _formSize = _stream->readUint32BE();
- _formType = _stream->readUint32BE();
-}
-
-void IFFParser::destroy() {
- _stream = 0;
- _startOffset = _endOffset = 0;
-}
-
-uint32 IFFParser::getFORMSize() const {
- return _formSize;
-}
-
-Common::IFF_ID IFFParser::getFORMType() const {
- return _formType;
-}
-
-uint32 IFFParser::moveToIFFBlock(Common::IFF_ID chunkName) {
- uint32 size = (uint32)-1;
-
- _stream->seek(_startOffset + 0x0C);
-
- while ((uint)_stream->pos() < _endOffset) {
- uint32 chunk = _stream->readUint32BE();
- uint32 size_temp = _stream->readUint32BE();
-
- if (chunk != chunkName) {
- _stream->seek((size_temp + 1) & (~1), SEEK_CUR);
- assert((uint)_stream->pos() <= _endOffset);
- } else {
- size = size_temp;
- break;
- }
- }
-
- return size;
-}
-
-uint32 IFFParser::getIFFBlockSize(Common::IFF_ID chunkName) {
- uint32 size = moveToIFFBlock(chunkName);
- return size;
-}
-
-bool IFFParser::loadIFFBlock(Common::IFF_ID chunkName, void *loadTo, uint32 ptrSize) {
- uint32 chunkSize = moveToIFFBlock(chunkName);
-
- if (chunkSize == (uint32)-1) {
- return false;
- }
-
- uint32 loadSize = 0;
- loadSize = MIN(ptrSize, chunkSize);
- _stream->read(loadTo, loadSize);
- return true;
-}
-
-Common::SeekableReadStream *IFFParser::getIFFBlockStream(Common::IFF_ID chunkName) {
- uint32 chunkSize = moveToIFFBlock(chunkName);
-
- if (chunkSize == (uint32)-1) {
- return 0;
- }
-
- uint32 pos = _stream->pos();
- return new Common::SeekableSubReadStream(_stream, pos, pos + chunkSize, false);
-}
-
-
-// ILBM decoder implementation
-
-ILBMDecoder::ILBMDecoder(Common::SeekableReadStream *in, bool disposeStream) : _in(in), _disposeStream(disposeStream), _hasHeader(false), _bodySize((uint32)-1), _paletteSize((uint32)-1) {
- assert(in);
- _parser.setInputStream(in);
-
- if (_parser.getFORMType() != ID_ILBM) {
- return;
- }
-
- _hasHeader = _parser.loadIFFBlock(ID_BMHD, &_header, sizeof(_header));
- if (!_hasHeader) {
- return;
- }
-
- _header.width = TO_BE_16(_header.width);
- _header.height = TO_BE_16(_header.height);
-
- _paletteSize = _parser.getIFFBlockSize(ID_CMAP);
- _bodySize = _parser.getIFFBlockSize(ID_BODY);
-}
-
-
-ILBMDecoder::~ILBMDecoder() {
- if (_disposeStream) {
- delete _in;
- }
-}
-
-uint32 ILBMDecoder::getWidth() {
- assert(_hasHeader);
- return _header.width;
-}
-
-uint32 ILBMDecoder::getHeight() {
- assert(_hasHeader);
- return _header.height;
-}
-
-uint32 ILBMDecoder::getNumColors() {
- assert(_hasHeader);
- return (1 << _header.depth);
-}
-
-byte *ILBMDecoder::getPalette() {
- assert(_paletteSize != (uint32)-1);
- byte *palette = new byte[_paletteSize];
- assert(palette);
- _parser.loadIFFBlock(ID_CMAP, palette, _paletteSize);
- return palette;
-}
-
-byte *ILBMDecoder::getBitmap(uint32 numPlanes, bool packPlanes) {
- assert(_bodySize != (uint32)-1);
- assert(numPlanes == 1 || numPlanes == 2 || numPlanes == 3 || numPlanes == 4 || numPlanes == 5 || numPlanes == 8);
-
- numPlanes = MIN(numPlanes, (uint32)_header.depth);
- if (numPlanes > 4) {
- packPlanes = false;
- }
-
- uint32 bitmapSize = _header.width * _header.height;
- uint32 bitmapWidth = _header.width;
- if (packPlanes) {
- bitmapSize /= (8 / numPlanes);
- bitmapWidth /= (8 / numPlanes);
- }
-
- Common::SeekableReadStream *bodyStream = _parser.getIFFBlockStream(ID_BODY);
- assert(bodyStream);
-
- byte *bitmap = (byte*)calloc(bitmapSize, 1);
- assert(bitmap);
-
- switch (_header.pack) {
- case 1: { // PackBits compressed bitmap
- Graphics::PackBitsReadStream stream(*bodyStream);
-
- byte *out = bitmap;
-
- // setup a buffer to hold enough data to build a line in the output
- uint32 scanWidth = ((_header.width + 15)/16) << 1;
- byte *scanBuffer = (byte*)malloc(scanWidth * _header.depth);
-
- for (uint i = 0; i < _header.height; ++i) {
- byte *s = scanBuffer;
- for (uint32 j = 0; j < _header.depth; ++j) {
- stream.read(s, scanWidth);
- s += scanWidth;
- }
-
- planarToChunky(out, bitmapWidth, scanBuffer, scanWidth, numPlanes, packPlanes);
- out += bitmapWidth;
- }
-
- free(scanBuffer);
- break;
- }
- default:
- error("only RLE compressed ILBM files are supported");
- break;
- }
-
- delete bodyStream;
-
- return bitmap;
-}
-
-
-void ILBMDecoder::planarToChunky(byte *out, uint32 width, byte *in, uint32 planeWidth, uint32 nPlanes, bool packPlanes) {
- byte pix, ofs, bit;
- byte *s;
-
- uint32 pixels = width;
- if (packPlanes) {
- pixels *= (8 / nPlanes);
- }
-
- for (uint32 x = 0; x < pixels; ++x) {
-
- pix = 0;
- ofs = x >> 3;
- bit = 0x80 >> (x & 7);
-
- // first build a pixel by scanning all the usable planes in the input
- s = in;
- for (uint32 plane = 0; plane < nPlanes; ++plane) {
- if (s[ofs] & bit) {
- pix |= (1 << plane);
- }
- s += planeWidth;
- }
-
-
- // then output the pixel according to the requested packing
- if (!packPlanes) {
- out[x] = pix;
- } else
- if (nPlanes == 1) {
- out[x/8] |= (pix << (x & 7));
- } else
- if (nPlanes == 2) {
- out[x/4] |= (pix << ((x & 3) << 1));
- } else
- if (nPlanes == 4) {
- out[x/2] |= (pix << ((x & 1) << 2));
- }
- }
-
-}
-
-
-} // End of namespace Parallaction
diff --git a/engines/parallaction/iff.h b/engines/parallaction/iff.h
deleted file mode 100644
index 43f78bf001..0000000000
--- a/engines/parallaction/iff.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* 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 PARALLACTION_IFF_H
-#define PARALLACTION_IFF_H
-
-#include "common/stream.h"
-#include "common/iff_container.h" // for IFF chunk names
-#include "graphics/iff.h" // for BMHD
-
-// this IFF parser code is courtesy of the Kyra engine team ;)
-
-namespace Parallaction {
-
-class IFFParser {
-public:
- IFFParser() : _stream(0), _startOffset(0), _endOffset(0) {}
- IFFParser(Common::SeekableReadStream *stream) : _stream(0), _startOffset(0), _endOffset(0) {
- setInputStream(stream);
- }
- ~IFFParser() { destroy(); }
-
- void setInputStream(Common::SeekableReadStream *stream);
-
- operator bool() const { return (_startOffset != _endOffset) && _stream; }
-
- uint32 getFORMSize() const;
- Common::IFF_ID getFORMType() const;
-
- uint32 getIFFBlockSize(Common::IFF_ID chunk);
- bool loadIFFBlock(Common::IFF_ID chunk, void *loadTo, uint32 ptrSize);
- Common::SeekableReadStream *getIFFBlockStream(Common::IFF_ID chunkName);
-private:
- void destroy();
- uint32 moveToIFFBlock(Common::IFF_ID chunkName);
-
- Common::SeekableReadStream *_stream;
- uint32 _startOffset;
- uint32 _endOffset;
-
- uint32 _formSize;
- Common::IFF_ID _formType;
-};
-
-
-
-
-class ILBMDecoder {
- Common::SeekableReadStream *_in;
- bool _disposeStream;
-
- void planarToChunky(byte *out, uint32 width, byte *in, uint32 planeWidth, uint32 nPlanes, bool packPlanes);
-
-protected:
- IFFParser _parser;
- Graphics::BMHD _header;
- bool _hasHeader;
- uint32 _bodySize;
- uint32 _paletteSize;
-
-
-public:
- ILBMDecoder(Common::SeekableReadStream *input, bool disposeStream = false);
-
- virtual ~ILBMDecoder();
-
- uint32 getWidth();
- uint32 getHeight();
- uint32 getNumColors();
- byte *getPalette();
-
- byte *getBitmap(uint32 numPlanes, bool packPlanes);
- byte *getBitmap() {
- assert(_hasHeader);
- return getBitmap(_header.depth, false);
- }
-};
-
-
-}
-
-#endif
-
diff --git a/engines/parallaction/module.mk b/engines/parallaction/module.mk
index 16b79c3d5a..d65653cd92 100644
--- a/engines/parallaction/module.mk
+++ b/engines/parallaction/module.mk
@@ -7,6 +7,7 @@ MODULE_OBJS := \
debug.o \
detection.o \
dialogue.o \
+ disk.o \
disk_br.o \
disk_ns.o \
exec.o \
@@ -18,7 +19,6 @@ MODULE_OBJS := \
gui.o \
gui_br.o \
gui_ns.o \
- iff.o \
input.o \
inventory.o \
objects.o \
diff --git a/engines/parallaction/sound.h b/engines/parallaction/sound.h
index f0ecea67bb..8fcfb94a9a 100644
--- a/engines/parallaction/sound.h
+++ b/engines/parallaction/sound.h
@@ -84,6 +84,14 @@ enum {
SC_PAUSE
};
+struct Channel {
+ Audio::AudioStream *stream;
+ Audio::SoundHandle handle;
+ uint32 volume;
+};
+
+
+
class SoundMan_ns : public SoundManImpl {
public:
enum {
@@ -148,16 +156,9 @@ class AmigaSoundMan_ns : public SoundMan_ns {
Audio::AudioStream *_musicStream;
Audio::SoundHandle _musicHandle;
- struct Channel {
- Audio::Voice8Header header;
- int8 *data;
- uint32 dataSize;
- bool dispose;
- Audio::SoundHandle handle;
- uint32 flags;
- } _channels[NUM_SFX_CHANNELS];
+ Channel _channels[NUM_SFX_CHANNELS];
- void loadChannelData(const char *filename, Channel *ch);
+ Audio::AudioStream *loadChannelData(const char *filename, Channel *ch, bool looping);
public:
AmigaSoundMan_ns(Parallaction_ns *vm);
@@ -192,21 +193,12 @@ protected:
bool _musicEnabled;
bool _sfxEnabled;
+ Channel _channels[NUM_SFX_CHANNELS];
+
virtual void playMusic() = 0;
virtual void stopMusic() = 0;
virtual void pause(bool p) = 0;
- struct Channel {
- Audio::Voice8Header header;
- int8 *data;
- uint32 dataSize;
- bool dispose;
- Audio::SoundHandle handle;
- uint32 flags;
- } _channels[NUM_SFX_CHANNELS];
-
- virtual void loadChannelData(const char *filename, Channel *ch) = 0;
-
public:
SoundMan_br(Parallaction_br *vm);
~SoundMan_br();
@@ -228,7 +220,7 @@ class DosSoundMan_br : public SoundMan_br {
MidiPlayer_MSC *_midiPlayer;
- void loadChannelData(const char *filename, Channel *ch);
+ Audio::AudioStream *loadChannelData(const char *filename, Channel *ch, bool looping);
public:
DosSoundMan_br(Parallaction_br *vm, MidiDriver *midiDriver);
@@ -246,7 +238,7 @@ class AmigaSoundMan_br : public SoundMan_br {
Audio::AudioStream *_musicStream;
Audio::SoundHandle _musicHandle;
- void loadChannelData(const char *filename, Channel *ch);
+ Audio::AudioStream *loadChannelData(const char *filename, Channel *ch, bool looping);
public:
AmigaSoundMan_br(Parallaction_br *vm);
diff --git a/engines/parallaction/sound_br.cpp b/engines/parallaction/sound_br.cpp
index 4915eb41e2..c0e3f3b24a 100644
--- a/engines/parallaction/sound_br.cpp
+++ b/engines/parallaction/sound_br.cpp
@@ -401,19 +401,29 @@ DosSoundMan_br::~DosSoundMan_br() {
delete _midiPlayer;
}
-void DosSoundMan_br::loadChannelData(const char *filename, Channel *ch) {
+Audio::AudioStream *DosSoundMan_br::loadChannelData(const char *filename, Channel *ch, bool looping) {
Common::SeekableReadStream *stream = _vm->_disk->loadSound(filename);
- ch->dataSize = stream->size();
- ch->data = (int8*)malloc(ch->dataSize);
- if (stream->read(ch->data, ch->dataSize) != ch->dataSize)
+ uint32 dataSize = stream->size();
+ int8 *data = (int8*)malloc(dataSize);
+ if (stream->read(data, dataSize) != dataSize)
error("DosSoundMan_br::loadChannelData: Read failed");
- ch->dispose = true;
delete stream;
// TODO: Confirm sound rate
- ch->header.samplesPerSec = 11025;
+ int rate = 11025;
+
+ uint32 loopStart = 0, loopEnd = 0;
+ uint32 flags = Audio::Mixer::FLAG_UNSIGNED | Audio::Mixer::FLAG_AUTOFREE;
+
+ if (looping) {
+ loopEnd = dataSize;
+ flags |= Audio::Mixer::FLAG_LOOP;
+ }
+
+ ch->stream = Audio::makeLinearInputStream((byte *)data, dataSize, rate, flags, loopStart, loopEnd);
+ return ch->stream;
}
void DosSoundMan_br::playSfx(const char *filename, uint channel, bool looping, int volume) {
@@ -426,16 +436,8 @@ void DosSoundMan_br::playSfx(const char *filename, uint channel, bool looping, i
debugC(1, kDebugAudio, "DosSoundMan_br::playSfx(%s, %u, %i, %i)", filename, channel, looping, volume);
Channel *ch = &_channels[channel];
- loadChannelData(filename, ch);
-
- uint32 loopStart = 0, loopEnd = 0, flags = Audio::Mixer::FLAG_UNSIGNED;
- if (looping) {
- loopEnd = ch->dataSize;
- flags |= Audio::Mixer::FLAG_LOOP;
- }
-
- _mixer->playRaw(Audio::Mixer::kSFXSoundType, &ch->handle, ch->data, ch->dataSize,
- ch->header.samplesPerSec, flags, -1, volume, 0, loopStart, loopEnd);
+ Audio::AudioStream *input = loadChannelData(filename, ch, looping);
+ _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &ch->handle, input, -1, volume);
}
void DosSoundMan_br::playMusic() {
@@ -468,22 +470,27 @@ AmigaSoundMan_br::~AmigaSoundMan_br() {
stopMusic();
}
-void AmigaSoundMan_br::loadChannelData(const char *filename, Channel *ch) {
+Audio::AudioStream *AmigaSoundMan_br::loadChannelData(const char *filename, Channel *ch, bool looping) {
Common::SeekableReadStream *stream = _vm->_disk->loadSound(filename);
+ Audio::AudioStream *input = 0;
+
if (_vm->getFeatures() & GF_DEMO) {
- ch->dataSize = stream->size();
- ch->data = (int8*)malloc(ch->dataSize);
- if (stream->read(ch->data, ch->dataSize) != ch->dataSize)
+ uint32 dataSize = stream->size();
+ int8 *data = (int8*)malloc(dataSize);
+ if (stream->read(data, dataSize) != dataSize)
error("DosSoundMan_br::loadChannelData: Read failed");
// TODO: Confirm sound rate
- ch->header.samplesPerSec = 11025;
+ int rate = 11025;
+ input = Audio::makeLinearInputStream((byte *)data, dataSize, rate, Audio::Mixer::FLAG_AUTOFREE, 0, 0);
} else {
- Audio::A8SVXDecoder decoder(*stream, ch->header, ch->data, ch->dataSize);
- decoder.decode();
+ input = Audio::make8SVXStream(*stream, looping);
}
- ch->dispose = true;
+
delete stream;
+
+ ch->stream = input;
+ return input;
}
void AmigaSoundMan_br::playSfx(const char *filename, uint channel, bool looping, int volume) {
@@ -501,24 +508,13 @@ void AmigaSoundMan_br::playSfx(const char *filename, uint channel, bool looping,
debugC(1, kDebugAudio, "AmigaSoundMan_ns::playSfx(%s, %i)", filename, channel);
Channel *ch = &_channels[channel];
- loadChannelData(filename, ch);
-
- uint32 loopStart = 0, loopEnd = 0, flags = 0;
- if (looping) {
- // the standard way to loop 8SVX audio implies use of the oneShotHiSamples and
- // repeatHiSamples fields, but Nippon Safes handles loops according to flags
- // set in its location scripts and always operates on the whole data.
- loopStart = 0;
- loopEnd = ch->header.oneShotHiSamples + ch->header.repeatHiSamples;
- flags = Audio::Mixer::FLAG_LOOP;
- }
+ Audio::AudioStream *input = loadChannelData(filename, ch, looping);
if (volume == -1) {
- volume = ch->header.volume;
+ volume = ch->volume;
}
- _mixer->playRaw(Audio::Mixer::kSFXSoundType, &ch->handle, ch->data, ch->dataSize,
- ch->header.samplesPerSec, flags, -1, volume, 0, loopStart, loopEnd);
+ _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &ch->handle, input, -1, volume);
}
void AmigaSoundMan_br::playMusic() {
@@ -560,15 +556,6 @@ void AmigaSoundMan_br::pause(bool p) {
SoundMan_br::SoundMan_br(Parallaction_br *vm) : _vm(vm) {
_mixer = _vm->_mixer;
- _channels[0].data = 0;
- _channels[0].dispose = false;
- _channels[1].data = 0;
- _channels[1].dispose = false;
- _channels[2].data = 0;
- _channels[2].dispose = false;
- _channels[3].data = 0;
- _channels[3].dispose = false;
-
_musicEnabled = true;
_sfxEnabled = true;
}
@@ -595,12 +582,9 @@ void SoundMan_br::stopSfx(uint channel) {
return;
}
- if (_channels[channel].dispose) {
- debugC(1, kDebugAudio, "SoundMan_br::stopSfx(%i)", channel);
- _mixer->stopHandle(_channels[channel].handle);
- free(_channels[channel].data);
- _channels[channel].data = 0;
- }
+ debugC(1, kDebugAudio, "SoundMan_br::stopSfx(%i)", channel);
+ _mixer->stopHandle(_channels[channel].handle);
+ _channels[channel].stream = 0;
}
void SoundMan_br::execute(int command, const char *parm) {
diff --git a/engines/parallaction/sound_ns.cpp b/engines/parallaction/sound_ns.cpp
index d0688c7264..65ee75ed98 100644
--- a/engines/parallaction/sound_ns.cpp
+++ b/engines/parallaction/sound_ns.cpp
@@ -335,14 +335,6 @@ void DosSoundMan_ns::playLocationMusic(const char *location) {
AmigaSoundMan_ns::AmigaSoundMan_ns(Parallaction_ns *vm) : SoundMan_ns(vm) {
_musicStream = 0;
- _channels[0].data = 0;
- _channels[0].dispose = false;
- _channels[1].data = 0;
- _channels[1].dispose = false;
- _channels[2].data = 0;
- _channels[2].dispose = false;
- _channels[3].data = 0;
- _channels[3].dispose = false;
}
AmigaSoundMan_ns::~AmigaSoundMan_ns() {
@@ -360,30 +352,30 @@ static int8 res_amigaBeep[AMIGABEEP_SIZE] = {
0, 20, 40, 60, 80, 60, 40, 20, 0, -20, -40, -60, -80, -60, -40, -20
};
+Audio::AudioStream *AmigaSoundMan_ns::loadChannelData(const char *filename, Channel *ch, bool looping) {
+ Audio::AudioStream *input = 0;
-void AmigaSoundMan_ns::loadChannelData(const char *filename, Channel *ch) {
if (!scumm_stricmp("beep", filename)) {
- ch->header.oneShotHiSamples = 0;
- ch->header.repeatHiSamples = 0;
- ch->header.samplesPerHiCycle = 0;
- ch->header.samplesPerSec = 11934;
- ch->header.volume = 160;
- ch->data = (int8*)malloc(AMIGABEEP_SIZE * NUM_REPEATS);
- int8* odata = ch->data;
+ // TODO: make a permanent stream out of this
+ uint32 dataSize = AMIGABEEP_SIZE * NUM_REPEATS;
+ int8 *data = (int8*)malloc(dataSize);
+ int8 *odata = data;
for (uint i = 0; i < NUM_REPEATS; i++) {
memcpy(odata, res_amigaBeep, AMIGABEEP_SIZE);
odata += AMIGABEEP_SIZE;
}
- ch->dataSize = AMIGABEEP_SIZE * NUM_REPEATS;
- ch->dispose = true;
- return;
+ int rate = 11934;
+ ch->volume = 160;
+ input = Audio::makeLinearInputStream((byte *)data, dataSize, rate, Audio::Mixer::FLAG_AUTOFREE, 0, 0);
+ } else {
+ Common::SeekableReadStream *stream = _vm->_disk->loadSound(filename);
+ input = Audio::make8SVXStream(*stream, looping);
+ delete stream;
}
- Common::SeekableReadStream *stream = _vm->_disk->loadSound(filename);
- Audio::A8SVXDecoder decoder(*stream, ch->header, ch->data, ch->dataSize);
- decoder.decode();
- ch->dispose = true;
- delete stream;
+ ch->stream = input;
+
+ return input;
}
void AmigaSoundMan_ns::playSfx(const char *filename, uint channel, bool looping, int volume) {
@@ -397,27 +389,13 @@ void AmigaSoundMan_ns::playSfx(const char *filename, uint channel, bool looping,
debugC(1, kDebugAudio, "AmigaSoundMan_ns::playSfx(%s, %i)", filename, channel);
Channel *ch = &_channels[channel];
- loadChannelData(filename, ch);
-
- uint32 loopStart, loopEnd, flags;
- if (looping) {
- // the standard way to loop 8SVX audio implies use of the oneShotHiSamples and
- // repeatHiSamples fields, but Nippon Safes handles loops according to flags
- // set in its location scripts and always operates on the whole data.
- loopStart = 0;
- loopEnd = ch->header.oneShotHiSamples + ch->header.repeatHiSamples;
- flags = Audio::Mixer::FLAG_LOOP;
- } else {
- loopStart = loopEnd = 0;
- flags = 0;
- }
+ Audio::AudioStream *input = loadChannelData(filename, ch, looping);
if (volume == -1) {
- volume = ch->header.volume;
+ volume = ch->volume;
}
- _mixer->playRaw(Audio::Mixer::kSFXSoundType, &ch->handle, ch->data, ch->dataSize,
- ch->header.samplesPerSec, flags, -1, volume, 0, loopStart, loopEnd);
+ _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &ch->handle, input, -1, volume);
}
void AmigaSoundMan_ns::stopSfx(uint channel) {
@@ -426,12 +404,9 @@ void AmigaSoundMan_ns::stopSfx(uint channel) {
return;
}
- if (_channels[channel].dispose) {
- debugC(1, kDebugAudio, "AmigaSoundMan_ns::stopSfx(%i)", channel);
- _mixer->stopHandle(_channels[channel].handle);
- free(_channels[channel].data);
- _channels[channel].data = 0;
- }
+ debugC(1, kDebugAudio, "AmigaSoundMan_ns::stopSfx(%i)", channel);
+ _mixer->stopHandle(_channels[channel].handle);
+ _channels[channel].stream = 0;
}
void AmigaSoundMan_ns::playMusic() {