diff options
| author | Norbert Lange | 2009-07-01 14:45:24 +0000 | 
|---|---|---|
| committer | Norbert Lange | 2009-07-01 14:45:24 +0000 | 
| commit | abef70f4e14f495b20097cb46411d1fafbafdd53 (patch) | |
| tree | 27462f82f352b303ac059dd275466930c88b2de6 /engines/parallaction | |
| parent | 3b94e2488df9a699a899727515ac69af6a0a1a6e (diff) | |
| parent | f9298ff40310149779b37ccdecc873afba7adf2f (diff) | |
| download | scummvm-rg350-abef70f4e14f495b20097cb46411d1fafbafdd53.tar.gz scummvm-rg350-abef70f4e14f495b20097cb46411d1fafbafdd53.tar.bz2 scummvm-rg350-abef70f4e14f495b20097cb46411d1fafbafdd53.zip  | |
Merging in changes from trunk
svn-id: r41989
Diffstat (limited to 'engines/parallaction')
| -rw-r--r-- | engines/parallaction/disk.cpp | 145 | ||||
| -rw-r--r-- | engines/parallaction/disk.h | 40 | ||||
| -rw-r--r-- | engines/parallaction/disk_br.cpp | 114 | ||||
| -rw-r--r-- | engines/parallaction/disk_ns.cpp | 79 | ||||
| -rw-r--r-- | engines/parallaction/gfxbase.cpp | 8 | ||||
| -rw-r--r-- | engines/parallaction/iff.cpp | 276 | ||||
| -rw-r--r-- | engines/parallaction/iff.h | 105 | ||||
| -rw-r--r-- | engines/parallaction/module.mk | 2 | ||||
| -rw-r--r-- | engines/parallaction/sound.h | 36 | ||||
| -rw-r--r-- | engines/parallaction/sound_br.cpp | 90 | ||||
| -rw-r--r-- | engines/parallaction/sound_ns.cpp | 69 | 
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() {  | 
