aboutsummaryrefslogtreecommitdiff
path: root/engines/parallaction
diff options
context:
space:
mode:
Diffstat (limited to 'engines/parallaction')
-rw-r--r--engines/parallaction/dialogue.cpp2
-rw-r--r--engines/parallaction/disk.cpp145
-rw-r--r--engines/parallaction/disk.h33
-rw-r--r--engines/parallaction/disk_br.cpp50
-rw-r--r--engines/parallaction/disk_ns.cpp59
-rw-r--r--engines/parallaction/input.cpp6
-rw-r--r--engines/parallaction/module.mk1
-rw-r--r--engines/parallaction/parallaction.cpp5
-rw-r--r--engines/parallaction/parser_br.cpp1
-rw-r--r--engines/parallaction/parser_ns.cpp4
-rw-r--r--engines/parallaction/sound_br.cpp4
11 files changed, 82 insertions, 228 deletions
diff --git a/engines/parallaction/dialogue.cpp b/engines/parallaction/dialogue.cpp
index 78cc23311f..06ffd0b89b 100644
--- a/engines/parallaction/dialogue.cpp
+++ b/engines/parallaction/dialogue.cpp
@@ -238,7 +238,7 @@ int16 DialogueManager::selectAnswerN() {
_selection = _balloonMan->hitTestDialogueBalloon(_mousePos.x, _mousePos.y);
- VisibleAnswer *oldAnswer = &_visAnswers[_oldSelection];
+ VisibleAnswer *oldAnswer = (_oldSelection == NO_ANSWER_SELECTED) ? NULL : &_visAnswers[_oldSelection];
VisibleAnswer *answer = &_visAnswers[_selection];
if (_selection != _oldSelection) {
diff --git a/engines/parallaction/disk.cpp b/engines/parallaction/disk.cpp
deleted file mode 100644
index f20e05771a..0000000000
--- a/engines/parallaction/disk.cpp
+++ /dev/null
@@ -1,145 +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.
- *
- */
-
-#include "common/iff_container.h"
-#include "common/textconsole.h"
-
-#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, Graphics::PixelFormat::createFormatCLUT8());
- _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 d1171c3179..63e33dcfbd 100644
--- a/engines/parallaction/disk.h
+++ b/engines/parallaction/disk.h
@@ -28,13 +28,10 @@
#include "common/archive.h"
#include "common/str.h"
-#include "graphics/iff.h"
-
namespace Common {
class FSDirectory;
class ReadStream;
class SeekableReadStream;
-struct IFFChunk;
}
namespace Graphics {
@@ -86,36 +83,6 @@ public:
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);
-};
-
-
class Disk_ns : public Disk {
protected:
diff --git a/engines/parallaction/disk_br.cpp b/engines/parallaction/disk_br.cpp
index 8988897456..3135c3e8c5 100644
--- a/engines/parallaction/disk_br.cpp
+++ b/engines/parallaction/disk_br.cpp
@@ -20,11 +20,10 @@
*
*/
-#include "graphics/iff.h"
-
#include "common/config-manager.h"
#include "common/fs.h"
#include "common/textconsole.h"
+#include "graphics/decoders/iff.h"
#include "parallaction/parallaction.h"
#include "parallaction/parser.h"
@@ -459,8 +458,9 @@ void AmigaDisk_br::adjustForPalette(Graphics::Surface &surf, int transparentColo
void AmigaDisk_br::loadBackground(BackgroundInfo& info, const char *filename) {
byte r,g,b;
- byte *p;
+ const byte *p;
Common::SeekableReadStream *stream;
+ Graphics::IFFDecoder decoder;
uint i;
stream = tryOpenFile("backs/" + Common::String(filename), ".ap");
@@ -488,15 +488,16 @@ void AmigaDisk_br::loadBackground(BackgroundInfo& info, const char *filename) {
}
stream = openFile("backs/" + Common::String(filename), ".bkg");
+ decoder.loadStream(*stream);
- byte pal[768];
- ILBMLoader loader(&info.bg, pal);
- loader.load(stream, true);
-
+ info.bg.copyFrom(*decoder.getSurface());
info.width = info.bg.w;
info.height = info.bg.h;
- p = pal;
+ // Overwrite the first color (transparent key) in the palette
+ p = decoder.getPalette();
+ info.palette.setEntry(0, p[0] >> 2, p[1] >> 2, p[2] >> 0);
+
for (i = 16; i < 32; i++) {
r = *p >> 2;
p++;
@@ -507,9 +508,6 @@ void AmigaDisk_br::loadBackground(BackgroundInfo& info, const char *filename) {
info.palette.setEntry(i, r, g, b);
}
- // Overwrite the first color (transparent key) in the palette
- info.palette.setEntry(0, pal[0] >> 2, pal[1] >> 2, pal[2] >> 0);
-
// background data is drawn used the upper portion of the palette
adjustForPalette(info.bg);
}
@@ -546,10 +544,15 @@ MaskBuffer *AmigaDisk_br::loadMask(const char *name, uint32 w, uint32 h) {
return 0;
}
- ILBMLoader loader(ILBMLoader::BODYMODE_MASKBUFFER);
- loader.load(stream, true);
+ Graphics::IFFDecoder decoder;
+ decoder.setNumRelevantPlanes(2); // use only 2 first bits from each pixels
+ decoder.setPixelPacking(true); // pack 4 2bit pixels into 1 byte
+ decoder.loadStream(*stream);
- MaskBuffer *buffer = loader._maskBuffer;
+ MaskBuffer *buffer = new MaskBuffer;
+ // surface width was shrunk to 1/4th of the bitmap width due to the pixel packing
+ buffer->create(decoder.getSurface()->w * 4, decoder.getSurface()->h);
+ memcpy(buffer->data, decoder.getSurface()->pixels, buffer->size);
buffer->bigEndian = true;
finalpass(buffer->data, buffer->size);
return buffer;
@@ -580,12 +583,12 @@ GfxObj* AmigaDisk_br::loadStatic(const char* name) {
Common::String sName = name;
Common::SeekableReadStream *stream = openFile("ras/" + sName, ".ras");
+ Graphics::IFFDecoder decoder;
+ decoder.loadStream(*stream);
- ILBMLoader loader(ILBMLoader::BODYMODE_SURFACE);
- loader.load(stream, true);
-
- Graphics::Surface* surf = loader._surf;
+ Graphics::Surface *surf = new Graphics::Surface;
assert(surf);
+ surf->copyFrom(*decoder.getSurface());
// 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
@@ -717,23 +720,23 @@ GfxObj* AmigaDisk_br::loadObjects(const char *name, uint8 part) {
debugC(5, kDebugDisk, "AmigaDisk_br::loadObjects");
Common::SeekableReadStream *stream = openFile(name);
- ILBMLoader loader(ILBMLoader::BODYMODE_SURFACE);
- loader.load(stream, true);
+ Graphics::IFFDecoder decoder;
+ decoder.loadStream(*stream);
uint16 max = objectsMax[part];
if (_vm->getFeatures() & GF_DEMO)
max = 72;
byte *data = new byte[max * 2601];
- byte *srcPtr = (byte *)loader._surf->getBasePtr(0,0);
- int w = loader._surf->w;
+ const byte *srcPtr = (const byte *)decoder.getSurface()->getBasePtr(0,0);
+ int w = decoder.getSurface()->w;
// Convert to the expected display format
for (int i = 0; i < max; i++) {
uint16 x = (i % 8) * 51;
uint16 y = (i / 8) * 51;
- byte *src = srcPtr + y * w + x;
+ const byte *src = srcPtr + y * w + x;
byte *dst = data + i * 2601;
for (int h = 0; h < 51; h++) {
memcpy(dst, src, 51);
@@ -741,7 +744,6 @@ GfxObj* AmigaDisk_br::loadObjects(const char *name, uint8 part) {
dst += 51;
}
}
- 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 bad854525d..4c4893ec61 100644
--- a/engines/parallaction/disk_ns.cpp
+++ b/engines/parallaction/disk_ns.cpp
@@ -22,9 +22,11 @@
#include "common/config-manager.h"
#include "common/fs.h"
+#include "common/iff_container.h"
#include "common/memstream.h"
#include "common/substream.h"
#include "common/textconsole.h"
+#include "graphics/decoders/iff.h"
#include "parallaction/parser.h"
#include "parallaction/parallaction.h"
@@ -312,7 +314,7 @@ void DosDisk_ns::decodeCnv(byte *data, uint16 numFrames, uint16 width, uint16 he
int32 decsize = numFrames * width * height;
bool packed = (stream->size() - stream->pos()) != decsize;
if (packed) {
- Graphics::PackBitsReadStream decoder(*stream);
+ Common::PackBitsReadStream decoder(*stream);
decoder.read(data, decsize);
} else {
stream->read(data, decsize);
@@ -392,7 +394,7 @@ Frames* DosDisk_ns::loadFrames(const char* name) {
- path data [bit 8] (walkable areas)
*/
void DosDisk_ns::unpackBackground(Common::ReadStream *stream, byte *screen, byte *mask, byte *path) {
- byte storage[127];
+ byte storage[128];
uint32 storageLen = 0, len = 0;
uint32 j = 0;
@@ -914,17 +916,15 @@ void AmigaDisk_ns::buildMask(byte* buf) {
void AmigaDisk_ns::loadBackground(BackgroundInfo& info, const char *name) {
- PaletteFxRange ranges[6];
- byte pal[768];
-
Common::SeekableReadStream *s = openFile(name);
- ILBMLoader loader(&info.bg, pal, ranges);
- loader.load(s, true);
+ Graphics::IFFDecoder decoder;
+ decoder.loadStream(*s);
+ info.bg.copyFrom(*decoder.getSurface());
info.width = info.bg.w;
info.height = info.bg.h;
- byte *p = pal;
+ const byte *p = decoder.getPalette();
for (uint i = 0; i < 32; i++) {
byte r = *p >> 2;
p++;
@@ -935,8 +935,15 @@ void AmigaDisk_ns::loadBackground(BackgroundInfo& info, const char *name) {
info.palette.setEntry(i, r, g, b);
}
- for (uint j = 0; j < 6; j++) {
- info.setPaletteRange(j, ranges[j]);
+ const Common::Array<Graphics::IFFDecoder::PaletteRange> &paletteRanges = decoder.getPaletteRanges();
+ for (uint j = 0; j < 6 && j < paletteRanges.size(); j++) {
+ PaletteFxRange range;
+ range._timer = paletteRanges[j].timer;
+ range._step = paletteRanges[j].step;
+ range._flags = paletteRanges[j].flags;
+ range._first = paletteRanges[j].first;
+ range._last = paletteRanges[j].last;
+ info.setPaletteRange(j, range);
}
}
@@ -952,19 +959,25 @@ void AmigaDisk_ns::loadMask_internal(BackgroundInfo& info, const char *name) {
return; // no errors if missing mask files: not every location has one
}
- byte pal[768];
- ILBMLoader loader(ILBMLoader::BODYMODE_MASKBUFFER, pal);
- loader.load(s, true);
+ Graphics::IFFDecoder decoder;
+ decoder.setNumRelevantPlanes(2); // use only 2 first bits from each pixel
+ decoder.setPixelPacking(true); // pack 4 2bit pixels into 1 byte
+ decoder.loadStream(*s);
+ const byte *p = decoder.getPalette();
byte r, g, b;
for (uint i = 0; i < 4; i++) {
- r = pal[i*3];
- g = pal[i*3+1];
- b = pal[i*3+2];
+ r = p[i*3];
+ g = p[i*3+1];
+ b = p[i*3+2];
info.layers[i] = (((r << 4) & 0xF00) | (g & 0xF0) | (b >> 4)) & 0xFF;
}
- info._mask = loader._maskBuffer;
+ info._mask = new MaskBuffer;
+ // surface width was shrunk to 1/4th of the bitmap width due to the pixel packing
+ info._mask->create(decoder.getSurface()->w * 4, decoder.getSurface()->h);
+ memcpy(info._mask->data, decoder.getSurface()->pixels, info._mask->size);
+ info._mask->bigEndian = true;
}
void AmigaDisk_ns::loadPath_internal(BackgroundInfo& info, const char *name) {
@@ -977,9 +990,15 @@ void AmigaDisk_ns::loadPath_internal(BackgroundInfo& info, const char *name) {
return; // no errors if missing path files: not every location has one
}
- ILBMLoader loader(ILBMLoader::BODYMODE_PATHBUFFER);
- loader.load(s, true);
- info._path = loader._pathBuffer;
+ Graphics::IFFDecoder decoder;
+ decoder.setNumRelevantPlanes(1); // use only first bit from each pixel
+ decoder.setPixelPacking(true); // pack 8 1bit pixels into 1 byte
+ decoder.loadStream(*s);
+
+ info._path = new PathBuffer;
+ // surface width was shrunk to 1/8th of the bitmap width due to the pixel packing
+ info._path->create(decoder.getSurface()->w * 8, decoder.getSurface()->h);
+ memcpy(info._path->data, decoder.getSurface()->pixels, info._path->size);
info._path->bigEndian = true;
}
diff --git a/engines/parallaction/input.cpp b/engines/parallaction/input.cpp
index 4fbd9b99cc..484e210893 100644
--- a/engines/parallaction/input.cpp
+++ b/engines/parallaction/input.cpp
@@ -551,8 +551,12 @@ void Input::setInventoryCursor(ItemName name) {
case GType_BRA: {
byte *src = _mouseArrow->getData(0);
byte *dst = _comboArrow->getData(0);
- memcpy(dst, src, _comboArrow->getSize(0));
// FIXME: destination offseting is not clear
+ Common::Rect srcRect, dstRect;
+ _mouseArrow->getRect(0, srcRect);
+ _comboArrow->getRect(0, dstRect);
+ for (uint y = 0; y < (uint)srcRect.height(); y++)
+ memcpy(dst + y * dstRect.width(), src + y * srcRect.width(), srcRect.width());
_vm->_inventoryRenderer->drawItem(name, dst + _mouseComboProps_BR._yOffset * _mouseComboProps_BR._width + _mouseComboProps_BR._xOffset, _mouseComboProps_BR._width);
CursorMan.replaceCursor(dst, _mouseComboProps_BR._width, _mouseComboProps_BR._height, 0, 0, 0);
break;
diff --git a/engines/parallaction/module.mk b/engines/parallaction/module.mk
index 36572a51df..f8a4e0b9a3 100644
--- a/engines/parallaction/module.mk
+++ b/engines/parallaction/module.mk
@@ -8,7 +8,6 @@ MODULE_OBJS := \
debug.o \
detection.o \
dialogue.o \
- disk.o \
disk_br.o \
disk_ns.o \
exec.o \
diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp
index e6ef53aa78..f868abfbf4 100644
--- a/engines/parallaction/parallaction.cpp
+++ b/engines/parallaction/parallaction.cpp
@@ -583,7 +583,10 @@ void Parallaction::runZone(ZonePtr z) {
// ZONE TYPE: DOOR
void Parallaction::updateDoor(ZonePtr z, bool close) {
- z->_flags = close ? (z->_flags |= kFlagsClosed) : (z->_flags &= ~kFlagsClosed);
+ if (close)
+ z->_flags |= kFlagsClosed;
+ else
+ z->_flags &= ~kFlagsClosed;
if (z->u._gfxobj) {
uint frame = (close ? 0 : 1);
diff --git a/engines/parallaction/parser_br.cpp b/engines/parallaction/parser_br.cpp
index e7f1b1b1ed..e60349ffa8 100644
--- a/engines/parallaction/parser_br.cpp
+++ b/engines/parallaction/parser_br.cpp
@@ -325,6 +325,7 @@ DECLARE_LOCATION_PARSER(location) {
nextToken = 2;
}
+ debugC(7, kDebugParser, "flip: %d", flip);
// TODO: handle background horizontal flip (via a context parameter)
if (_tokens[nextToken][0] != '\0') {
diff --git a/engines/parallaction/parser_ns.cpp b/engines/parallaction/parser_ns.cpp
index 41ff74f0b4..ac5e7c7135 100644
--- a/engines/parallaction/parser_ns.cpp
+++ b/engines/parallaction/parser_ns.cpp
@@ -292,7 +292,7 @@ void LocationParser_ns::parseAnimation(AnimationList &list, char *name) {
AnimationPtr a(new Animation);
_zoneProg++;
- strncpy(a->_name, name, ZONENAME_LENGTH);
+ Common::strlcpy(a->_name, name, ZONENAME_LENGTH);
a->_flags |= kFlagsIsAnimation;
list.push_front(AnimationPtr(a));
@@ -1312,7 +1312,7 @@ void LocationParser_ns::parseZone(ZoneList &list, char *name) {
ZonePtr z(new Zone);
_zoneProg++;
- strncpy(z->_name, name, ZONENAME_LENGTH);
+ Common::strlcpy(z->_name, name, ZONENAME_LENGTH);
ctxt.z = z;
diff --git a/engines/parallaction/sound_br.cpp b/engines/parallaction/sound_br.cpp
index ad510eb1f1..4a643aaf1d 100644
--- a/engines/parallaction/sound_br.cpp
+++ b/engines/parallaction/sound_br.cpp
@@ -507,10 +507,14 @@ void SoundMan_br::execute(int command, const char *parm) {
stopMusic();
break;
case SC_SETMUSICFILE:
+ if (!parm)
+ error("no parameter passed to SC_SETMUSICFILE");
setMusicFile(parm);
break;
case SC_PLAYSFX:
+ if (!parm)
+ error("no parameter passed to SC_PLAYSFX");
playSfx(parm, _sfxChannel, _sfxLooping, _sfxVolume);
break;
case SC_STOPSFX: