aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorNicola Mettifogo2007-08-25 20:34:10 +0000
committerNicola Mettifogo2007-08-25 20:34:10 +0000
commit39e4a9b180d37f2fef108391d5f04a3c7e3b2ea0 (patch)
treebd7bd96adb2d8df6677d1e25b9e4b98e2851bbad /engines
parent9f8b0884fa2814b04567a86596cdae7953d8eb1e (diff)
downloadscummvm-rg350-39e4a9b180d37f2fef108391d5f04a3c7e3b2ea0.tar.gz
scummvm-rg350-39e4a9b180d37f2fef108391d5f04a3c7e3b2ea0.tar.bz2
scummvm-rg350-39e4a9b180d37f2fef108391d5f04a3c7e3b2ea0.zip
Added an abstract base class for representing multiple-frames for animations. Changed user code to rely on the new interface. Cnv has been turned into an implementation of the new interface, and it is now known as a concrete class only to Disk and Font code for Nippon Safes.
svn-id: r28734
Diffstat (limited to 'engines')
-rw-r--r--engines/parallaction/dialogue.cpp4
-rw-r--r--engines/parallaction/disk.h27
-rw-r--r--engines/parallaction/disk_br.cpp94
-rw-r--r--engines/parallaction/disk_ns.cpp12
-rw-r--r--engines/parallaction/exec_ns.cpp6
-rw-r--r--engines/parallaction/graphics.cpp15
-rw-r--r--engines/parallaction/graphics.h32
-rw-r--r--engines/parallaction/inventory.cpp13
-rw-r--r--engines/parallaction/inventory.h2
-rw-r--r--engines/parallaction/objects.cpp12
-rw-r--r--engines/parallaction/objects.h4
-rw-r--r--engines/parallaction/parallaction.cpp182
-rw-r--r--engines/parallaction/parallaction.h16
-rw-r--r--engines/parallaction/parallaction_br.cpp8
-rw-r--r--engines/parallaction/parallaction_ns.cpp177
-rw-r--r--engines/parallaction/parser_ns.cpp5
16 files changed, 379 insertions, 230 deletions
diff --git a/engines/parallaction/dialogue.cpp b/engines/parallaction/dialogue.cpp
index 721d43fa19..7539d89368 100644
--- a/engines/parallaction/dialogue.cpp
+++ b/engines/parallaction/dialogue.cpp
@@ -65,8 +65,8 @@ class DialogueManager {
bool _askPassword;
bool isNpc;
- Cnv *_questioner;
- Cnv *_answerer;
+ Frames *_questioner;
+ Frames *_answerer;
Question *_q;
diff --git a/engines/parallaction/disk.h b/engines/parallaction/disk.h
index d58d85e15c..6adab69f51 100644
--- a/engines/parallaction/disk.h
+++ b/engines/parallaction/disk.h
@@ -38,7 +38,9 @@ class Gfx;
class Script;
class Font;
+struct Frames;
struct Cnv;
+struct Sprites;
struct BackgroundInfo;
class Disk {
@@ -52,13 +54,13 @@ public:
virtual Script* loadLocation(const char *name) = 0;
virtual Script* loadScript(const char* name) = 0;
- virtual Cnv* loadTalk(const char *name) = 0;
- virtual Cnv* loadObjects(const char *name) = 0;
+ virtual Frames* loadTalk(const char *name) = 0;
+ virtual Frames* loadObjects(const char *name) = 0;
virtual Graphics::Surface* loadPointer(const char *name) = 0;
virtual Graphics::Surface* loadHead(const char* name) = 0;
virtual Font* loadFont(const char* name) = 0;
virtual Graphics::Surface* loadStatic(const char* name) = 0;
- virtual Cnv* loadFrames(const char* name) = 0;
+ virtual Frames* loadFrames(const char* name) = 0;
virtual void loadSlide(BackgroundInfo& info, const char *filename) = 0;
virtual void loadScenery(BackgroundInfo& info, const char* background, const char* mask, const char* path) = 0;
virtual Table* loadTable(const char* name) = 0;
@@ -144,13 +146,13 @@ public:
Script* loadLocation(const char *name);
Script* loadScript(const char* name);
- Cnv* loadTalk(const char *name);
- Cnv* loadObjects(const char *name);
+ Frames* loadTalk(const char *name);
+ Frames* loadObjects(const char *name);
Graphics::Surface* loadPointer(const char *name);
Graphics::Surface* loadHead(const char* name);
Font* loadFont(const char* name);
Graphics::Surface* loadStatic(const char* name);
- Cnv* loadFrames(const char* name);
+ Frames* loadFrames(const char* name);
void loadSlide(BackgroundInfo& info, const char *filename);
void loadScenery(BackgroundInfo& info, const char* background, const char* mask, const char* path);
Table* loadTable(const char* name);
@@ -178,13 +180,13 @@ public:
Script* loadLocation(const char *name);
Script* loadScript(const char* name);
- Cnv* loadTalk(const char *name);
- Cnv* loadObjects(const char *name);
+ Frames* loadTalk(const char *name);
+ Frames* loadObjects(const char *name);
Graphics::Surface* loadPointer(const char *name);
Graphics::Surface* loadHead(const char* name);
Font* loadFont(const char* name);
Graphics::Surface* loadStatic(const char* name);
- Cnv* loadFrames(const char* name);
+ Frames* loadFrames(const char* name);
void loadSlide(BackgroundInfo& info, const char *filename);
void loadScenery(BackgroundInfo& info, const char* background, const char* mask, const char* path);
Table* loadTable(const char* name);
@@ -206,6 +208,7 @@ protected:
protected:
void errorFileNotFound(const char *s);
Font *createFont(const char *name, Common::ReadStream &stream);
+ Sprites* createSprites(const char *name);
public:
DosDisk_br(Parallaction *vm);
@@ -215,13 +218,13 @@ public:
void setLanguage(uint16 language);
Script* loadLocation(const char *name);
Script* loadScript(const char* name);
- Cnv* loadTalk(const char *name);
- Cnv* loadObjects(const char *name);
+ Frames* loadTalk(const char *name);
+ Frames* loadObjects(const char *name);
Graphics::Surface* loadPointer(const char *name);
Graphics::Surface* loadHead(const char* name);
Font* loadFont(const char* name);
Graphics::Surface* loadStatic(const char* name);
- Cnv* loadFrames(const char* name);
+ Frames* loadFrames(const char* name);
void loadSlide(BackgroundInfo& info, const char *filename);
void loadScenery(BackgroundInfo& info, const char* background, const char* mask, const char* path);
Table* loadTable(const char* name);
diff --git a/engines/parallaction/disk_br.cpp b/engines/parallaction/disk_br.cpp
index 4853a9fb1a..64eb6b533d 100644
--- a/engines/parallaction/disk_br.cpp
+++ b/engines/parallaction/disk_br.cpp
@@ -30,6 +30,57 @@
namespace Parallaction {
+struct Sprite {
+ uint16 size;
+ uint16 x;
+ uint16 y;
+ uint16 w;
+ uint16 h;
+
+ byte *packedData;
+
+ Sprite() : size(0), x(0), y(0), w(0), h(0), packedData(0) {
+ }
+
+ ~Sprite() {
+ if (packedData)
+ free(packedData);
+ }
+};
+
+struct Sprites : public Frames {
+ uint16 _num;
+ Sprite* _sprites;
+
+ Sprites(uint num) {
+ _num = num;
+ _sprites = new Sprite[_num];
+ }
+
+ ~Sprites() {
+ delete _sprites;
+ }
+
+ uint16 getNum() {
+ return _num;
+ }
+
+ byte* getData(uint16 index) {
+ assert(index < _num);
+ return _sprites[index].packedData;
+ }
+
+ void getRect(uint16 index, Common::Rect &r) {
+ assert(index < _num);
+ r.setWidth(_sprites[index].w);
+ r.setHeight(_sprites[index].h);
+ r.moveTo(_sprites[index].x, _sprites[index].y);
+}
+
+};
+
+
+
void DosDisk_br::errorFileNotFound(const char *s) {
error("File '%s' not found", s);
}
@@ -78,10 +129,13 @@ DosDisk_br::DosDisk_br(Parallaction* vm) : _vm(vm) {
DosDisk_br::~DosDisk_br() {
}
-Cnv* DosDisk_br::loadTalk(const char *name) {
+Frames* DosDisk_br::loadTalk(const char *name) {
debugC(5, kDebugDisk, "DosDisk_br::loadTalk");
- return 0;
+ char path[PATH_LEN];
+ sprintf(path, "%s/tal/%s.tal", _partPath, name);
+
+ return createSprites(path);
}
Script* DosDisk_br::loadLocation(const char *name) {
@@ -159,7 +213,7 @@ Font* DosDisk_br::loadFont(const char* name) {
}
-Cnv* DosDisk_br::loadObjects(const char *name) {
+Frames* DosDisk_br::loadObjects(const char *name) {
debugC(5, kDebugDisk, "DosDisk_br::loadObjects");
return 0;
}
@@ -173,9 +227,39 @@ Graphics::Surface* DosDisk_br::loadStatic(const char* name) {
return 0;
}
-Cnv* DosDisk_br::loadFrames(const char* name) {
+Sprites* DosDisk_br::createSprites(const char *path) {
+
+ Common::File stream;
+ if (!stream.open(path)) {
+ errorFileNotFound(path);
+ }
+
+ uint16 num = stream.readUint16LE();
+
+ Sprites *sprites = new Sprites(num);
+
+ for (uint i = 0; i < num; i++) {
+ Sprite *spr = &sprites->_sprites[i];
+ spr->size = stream.readUint16LE();
+ spr->x = stream.readUint16LE();
+ spr->y = stream.readUint16LE();
+ spr->w = stream.readUint16LE();
+ spr->h = stream.readUint16LE();
+
+ spr->packedData = (byte*)malloc(spr->size);
+ stream.read(spr->packedData, spr->size);
+ }
+
+ return sprites;
+}
+
+Frames* DosDisk_br::loadFrames(const char* name) {
debugC(5, kDebugDisk, "DosDisk_br::loadFrames");
- return 0;
+
+ char path[PATH_LEN];
+ sprintf(path, "%s/ani/%s.ani", _partPath, name);
+
+ return createSprites(path);
}
// Slides in Nippon Safes are basically screen-sized pictures with valid
diff --git a/engines/parallaction/disk_ns.cpp b/engines/parallaction/disk_ns.cpp
index 8e71e4a6b7..cb224b713b 100644
--- a/engines/parallaction/disk_ns.cpp
+++ b/engines/parallaction/disk_ns.cpp
@@ -393,7 +393,7 @@ Cnv* DosDisk_ns::loadCnv(const char *filename) {
return new Cnv(numFrames, width, height, data);
}
-Cnv* DosDisk_ns::loadTalk(const char *name) {
+Frames* DosDisk_ns::loadTalk(const char *name) {
const char *ext = strstr(name, ".talk");
if (ext != NULL) {
@@ -487,7 +487,7 @@ Font* DosDisk_ns::loadFont(const char* name) {
}
-Cnv* DosDisk_ns::loadObjects(const char *name) {
+Frames* DosDisk_ns::loadObjects(const char *name) {
if (IS_MINI_CHARACTER(name)) {
name += 4;
@@ -524,7 +524,7 @@ Graphics::Surface* DosDisk_ns::loadStatic(const char* name) {
return cnv;
}
-Cnv* DosDisk_ns::loadFrames(const char* name) {
+Frames* DosDisk_ns::loadFrames(const char* name) {
return loadCnv(name);
}
@@ -1305,7 +1305,7 @@ void AmigaDisk_ns::loadSlide(BackgroundInfo& info, const char *name) {
return;
}
-Cnv* AmigaDisk_ns::loadFrames(const char* name) {
+Frames* AmigaDisk_ns::loadFrames(const char* name) {
debugC(1, kDebugDisk, "AmigaDisk_ns::loadFrames '%s'", name);
Common::SeekableReadStream *s;
@@ -1338,7 +1338,7 @@ Graphics::Surface* AmigaDisk_ns::loadHead(const char* name) {
}
-Cnv* AmigaDisk_ns::loadObjects(const char *name) {
+Frames* AmigaDisk_ns::loadObjects(const char *name) {
debugC(1, kDebugDisk, "AmigaDisk_ns::loadObjects");
char path[PATH_LEN];
@@ -1356,7 +1356,7 @@ Cnv* AmigaDisk_ns::loadObjects(const char *name) {
}
-Cnv* AmigaDisk_ns::loadTalk(const char *name) {
+Frames* AmigaDisk_ns::loadTalk(const char *name) {
debugC(1, kDebugDisk, "AmigaDisk_ns::loadTalk '%s'", name);
Common::SeekableReadStream *s;
diff --git a/engines/parallaction/exec_ns.cpp b/engines/parallaction/exec_ns.cpp
index 1df78da9c4..641a23b772 100644
--- a/engines/parallaction/exec_ns.cpp
+++ b/engines/parallaction/exec_ns.cpp
@@ -622,10 +622,12 @@ void jobToggleDoor(void *parm, Job *j) {
Zone *z = (Zone*)parm;
if (z->u.door->_cnv) {
- Common::Rect r(z->_left, z->_top, z->_left+z->u.door->_cnv->_width, z->_top+z->u.door->_cnv->_height);
+ Common::Rect r;
+ z->u.door->_cnv->getRect(0, r);
+ r.moveTo(z->_left, z->_top);
uint16 _ax = (z->_flags & kFlagsClosed ? 1 : 0);
- _vm->_gfx->restoreDoorBackground(r, z->u.door->_cnv->getFramePtr(_ax), z->u.door->_background);
+ _vm->_gfx->restoreDoorBackground(r, z->u.door->_cnv->getData(_ax), z->u.door->_background);
_ax = (z->_flags & kFlagsClosed ? 0 : 1);
_vm->_gfx->flatBlitCnv(z->u.door->_cnv, _ax, z->_left, z->_top, Gfx::kBitBack);
diff --git a/engines/parallaction/graphics.cpp b/engines/parallaction/graphics.cpp
index c142779167..1cf5216963 100644
--- a/engines/parallaction/graphics.cpp
+++ b/engines/parallaction/graphics.cpp
@@ -463,13 +463,16 @@ void jobEraseLabel(void *parm, Job *j) {
//
// Cnv management
//
-void Gfx::flatBlitCnv(Cnv *cnv, uint16 frame, int16 x, int16 y, Gfx::Buffers buffer) {
+void Gfx::flatBlitCnv(Frames *cnv, uint16 frame, int16 x, int16 y, Gfx::Buffers buffer) {
Graphics::Surface scnv;
+ Common::Rect r;
- scnv.w = cnv->_width;
- scnv.h = cnv->_height;
- scnv.pixels = cnv->getFramePtr(frame);
+ cnv->getRect(frame, r);
+
+ scnv.w = r.width();
+ scnv.h = r.height();
+ scnv.pixels = cnv->getData(frame);
flatBlitCnv(&scnv, x, y, buffer);
}
@@ -493,7 +496,9 @@ void Gfx::blitCnv(Graphics::Surface *cnv, int16 x, int16 y, uint16 z, Gfx::Buffe
void Gfx::backupDoorBackground(DoorData *data, int16 x, int16 y) {
byte *s = (byte*)_buffers[kBit2]->getBasePtr(x, y);
- copyRect(data->_cnv->_width, data->_cnv->_height, data->_background, data->_cnv->_width, s,_backgroundWidth);
+ Common::Rect r;
+ data->_cnv->getRect(0, r);
+ copyRect(r.width(), r.height(), data->_background, r.width(), s,_backgroundWidth);
return;
}
diff --git a/engines/parallaction/graphics.h b/engines/parallaction/graphics.h
index 6082f78343..3913eebbdf 100644
--- a/engines/parallaction/graphics.h
+++ b/engines/parallaction/graphics.h
@@ -72,7 +72,19 @@ public:
};
-struct Cnv {
+
+struct Frames {
+
+ virtual uint16 getNum() = 0;
+ virtual byte* getData(uint16 index) = 0;
+ virtual void getRect(uint16 index, Common::Rect &r) = 0;
+
+ virtual ~Frames() { }
+
+};
+
+
+struct Cnv : public Frames {
uint16 _count; // # of frames
uint16 _width; //
uint16 _height; //
@@ -99,6 +111,21 @@ public:
return NULL;
return &_data[index * _width * _height];
}
+
+ uint16 getNum() {
+ return _count;
+ }
+
+ byte *getData(uint16 index) {
+ return getFramePtr(index);
+ }
+
+ void getRect(uint16 index, Common::Rect &r) {
+ r.left = 0;
+ r.top = 0;
+ r.setWidth(_width);
+ r.setHeight(_height);
+ }
};
@@ -194,7 +221,7 @@ public:
// cut/paste
void flatBlitCnv(Graphics::Surface *cnv, int16 x, int16 y, Gfx::Buffers buffer);
- void flatBlitCnv(Cnv *cnv, uint16 frame, int16 x, int16 y, Gfx::Buffers buffer);
+ void flatBlitCnv(Frames *cnv, uint16 frame, int16 x, int16 y, Gfx::Buffers buffer);
void blitCnv(Graphics::Surface *cnv, int16 x, int16 y, uint16 z, Gfx::Buffers buffer);
void restoreBackground(const Common::Rect& r);
void backupDoorBackground(DoorData *data, int16 x, int16 y);
@@ -268,3 +295,4 @@ protected:
+
diff --git a/engines/parallaction/inventory.cpp b/engines/parallaction/inventory.cpp
index 2804578c84..0a286e4204 100644
--- a/engines/parallaction/inventory.cpp
+++ b/engines/parallaction/inventory.cpp
@@ -117,9 +117,12 @@ void drawInventoryItem(uint16 pos, InventoryItem *item) {
uint16 line = pos / INVENTORY_ITEMS_PER_LINE;
uint16 col = pos % INVENTORY_ITEMS_PER_LINE;
+ Common::Rect r;
+ _vm->_char._objs->getRect(0, r);
+
// FIXME: this will end up in a general blit function
- byte* s = _vm->_char._objs->getFramePtr(item->_index);
- byte* d = _buffer + col * INVENTORYITEM_WIDTH + line * _vm->_char._objs->_height * INVENTORY_WIDTH;
+ byte* s = _vm->_char._objs->getData(item->_index);
+ byte* d = _buffer + col * INVENTORYITEM_WIDTH + line * r.height() * INVENTORY_WIDTH;
for (uint32 i = 0; i < INVENTORYITEM_HEIGHT; i++) {
memcpy(d, s, INVENTORYITEM_WIDTH);
@@ -210,8 +213,10 @@ void highlightInventoryItem(int16 pos, byte color) {
uint16 line = pos / INVENTORY_ITEMS_PER_LINE;
uint16 col = pos % INVENTORY_ITEMS_PER_LINE;
- Common::Rect r(INVENTORYITEM_WIDTH, _vm->_char._objs->_height);
- r.moveTo(col * INVENTORYITEM_WIDTH, line * _vm->_char._objs->_height);
+ Common::Rect r;
+ _vm->_char._objs->getRect(0, r);
+ r.setWidth(INVENTORYITEM_WIDTH);
+ r.moveTo(col * INVENTORYITEM_WIDTH, line * r.height());
drawBorder(r, _buffer, color);
diff --git a/engines/parallaction/inventory.h b/engines/parallaction/inventory.h
index 4a3e07cc97..2ca3559b8f 100644
--- a/engines/parallaction/inventory.h
+++ b/engines/parallaction/inventory.h
@@ -31,8 +31,6 @@
namespace Parallaction {
-struct Cnv;
-
struct InventoryItem {
uint32 _id; // object name (lowest 16 bits are always zero)
uint16 _index; // index to frame in objs file
diff --git a/engines/parallaction/objects.cpp b/engines/parallaction/objects.cpp
index add2f87b5e..195d814265 100644
--- a/engines/parallaction/objects.cpp
+++ b/engines/parallaction/objects.cpp
@@ -62,22 +62,26 @@ Animation::~Animation() {
uint16 Animation::width() const {
if (!_cnv) return 0;
- return _cnv->_width;
+ Common::Rect r;
+ _cnv->getRect(0, r);
+ return r.width();
}
uint16 Animation::height() const {
if (!_cnv) return 0;
- return _cnv->_height;
+ Common::Rect r;
+ _cnv->getRect(0, r);
+ return r.height();
}
uint16 Animation::getFrameNum() const {
if (!_cnv) return 0;
- return _cnv->_count;
+ return _cnv->getNum();
}
byte* Animation::getFrameData(uint32 index) const {
if (!_cnv) return NULL;
- return _cnv->getFramePtr(index);
+ return _cnv->getData(index);
}
diff --git a/engines/parallaction/objects.h b/engines/parallaction/objects.h
index 26c841b285..9ec906f458 100644
--- a/engines/parallaction/objects.h
+++ b/engines/parallaction/objects.h
@@ -202,7 +202,7 @@ struct ExamineData { // size = 28
};
struct DoorData { // size = 28
char* _location;
- Cnv *_cnv;
+ Frames *_cnv;
byte* _background;
Common::Point _startPos;
uint16 _startFrame;
@@ -384,7 +384,7 @@ struct Animation : public Zone {
Common::Point _oldPos;
Program *_program;
- Cnv *_cnv;
+ Frames *_cnv;
char *_scriptName;
int16 _frame;
uint16 field_50; // unused
diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp
index 4a93ee968b..7d150e8813 100644
--- a/engines/parallaction/parallaction.cpp
+++ b/engines/parallaction/parallaction.cpp
@@ -89,9 +89,6 @@ uint16 _introSarcData2 = 1;
// private stuff
static Job *_jDrawInventory = NULL;
-Job *_jDrawLabel = NULL;
-Job *_jEraseLabel = NULL;
-Zone *_hoverZone = NULL;
static Job *_jRunScripts = NULL;
@@ -177,6 +174,10 @@ int Parallaction::init() {
initInventory(); // needs to be pushed into subclass
+ _jDrawLabel = NULL;
+ _jEraseLabel = NULL;
+ _hoverZone = NULL;
+
_animations.push_front(&_char._ani);
_gfx = new Gfx(this);
@@ -664,55 +665,7 @@ void Parallaction::freeCharacter() {
return;
}
-void Parallaction::changeCharacter(const char *name) {
- debugC(1, kDebugLocation, "changeCharacter(%s)", name);
-
- char baseName[20];
- if (IS_MINI_CHARACTER(name)) {
- strcpy(baseName, name+4);
- } else {
- strcpy(baseName, name);
- }
-
- char fullName[20];
- strcpy(fullName, name);
- if (_engineFlags & kEngineTransformedDonna)
- strcat(fullName, "tras");
-
- if (scumm_stricmp(fullName, _characterName1)) {
-
- // freeCharacter takes responsibility for checking
- // character for sanity before memory is freed
- freeCharacter();
-
- Common::String oldArchive = _disk->selectArchive((getFeatures() & GF_LANG_MULT) ? "disk1" : "disk0");
- _char._ani._cnv = _disk->loadFrames(fullName);
-
- if (!IS_DUMMY_CHARACTER(name)) {
- if (getPlatform() == Common::kPlatformAmiga && (getFeatures() & GF_LANG_MULT))
- _disk->selectArchive("disk0");
- _char._head = _disk->loadHead(baseName);
- _char._talk = _disk->loadTalk(baseName);
- _char._objs = _disk->loadObjects(baseName);
- _objectsNames = _disk->loadTable(baseName);
-
- _soundMan->playCharacterMusic(name);
-
- if (!(getFeatures() & GF_DEMO))
- parseLocation("common");
- }
-
- if (!oldArchive.empty())
- _disk->selectArchive(oldArchive);
- }
-
- strcpy(_characterName1, fullName);
-
- debugC(1, kDebugLocation, "changeCharacter() done");
-
- return;
-}
/*
helper function to provide *descending* ordering of the job list
@@ -1036,9 +989,6 @@ void Parallaction::switchBackground(const char* background, const char* mask) {
return;
}
-extern Zone *_hoverZone;
-extern Job *_jDrawLabel;
-extern Job *_jEraseLabel;
void Parallaction::showSlide(const char *name) {
@@ -1061,131 +1011,7 @@ void Parallaction::showSlide(const char *name) {
return;
}
-/*
- changeLocation handles transitions between locations, and is able to display slides
- between one and the other. The input parameter 'location' exists in some flavours:
-
- 1 - [S].slide.[L]{.[C]}
- 2 - [L]{.[C]}
-
- where:
-
- [S] is the slide to be shown
- [L] is the location to switch to (immediately in case 2, or right after slide [S] in case 1)
- [C] is the character to be selected, and is optional
-
- The routine tells one form from the other by searching for the '.slide.'
-
- NOTE: there exists one script in which [L] is not used in the case 1, but its use
- is commented out, and would definitely crash the current implementation.
-*/
-void Parallaction::changeLocation(char *location) {
- debugC(1, kDebugLocation, "changeLocation(%s)", location);
-
- _soundMan->playLocationMusic(location);
-
- // WORKAROUND: this if-statement has been added to avoid crashes caused by
- // execution of label jobs after a location switch. The other workaround in
- // Parallaction::runGame should have been rendered useless by this one.
- if (_jDrawLabel != NULL) {
- removeJob(_jDrawLabel);
- removeJob(_jEraseLabel);
- _jDrawLabel = NULL;
- _jEraseLabel = NULL;
- }
-
-
- _hoverZone = NULL;
- if (_engineFlags & kEngineBlockInput) {
- changeCursor( kCursorArrow );
- }
-
- _animations.remove(&_char._ani);
-
- freeLocation();
- char buf[100];
- strcpy(buf, location);
-
- Common::StringList list;
- char *tok = strtok(location, ".");
- while (tok) {
- list.push_back(tok);
- tok = strtok(NULL, ".");
- }
-
- if (list.size() < 1 || list.size() > 4)
- error("changeLocation: ill-formed location string '%s'", location);
-
- if (list.size() > 1) {
- if (list[1] == "slide") {
- showSlide(list[0].c_str());
- _gfx->setFont(_menuFont);
- _gfx->displayCenteredString(14, _slideText[0]); // displays text on screen
- _gfx->updateScreen();
- waitUntilLeftClick();
-
- list.remove_at(0); // removes slide name
- list.remove_at(0); // removes 'slide'
- }
-
- // list is now only [L].{[C]} (see above comment)
- if (list.size() == 2) {
- changeCharacter(list[1].c_str());
- strcpy(_characterName, list[1].c_str());
- }
- }
-
- _animations.push_front(&_char._ani);
-
- strcpy(_saveData1, list[0].c_str());
- parseLocation(list[0].c_str());
-
- _char._ani._oldPos.x = -1000;
- _char._ani._oldPos.y = -1000;
-
- _char._ani.field_50 = 0;
- if (_location._startPosition.x != -1000) {
- _char._ani._left = _location._startPosition.x;
- _char._ani._top = _location._startPosition.y;
- _char._ani._frame = _location._startFrame;
- _location._startPosition.y = -1000;
- _location._startPosition.x = -1000;
- }
-
-
- _gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
- _gfx->copyScreen(Gfx::kBitBack, Gfx::kBit2);
- _gfx->setBlackPalette();
- _gfx->updateScreen();
-
- if (_location._commands.size() > 0) {
- runCommands(_location._commands);
- runJobs();
- _gfx->swapBuffers();
- runJobs();
- _gfx->swapBuffers();
- }
-
- if (_location._comment) {
- doLocationEnterTransition();
- }
-
- runJobs();
- _gfx->swapBuffers();
- _gfx->setPalette(_gfx->_palette);
- if (_location._aCommands.size() > 0) {
- runCommands(_location._aCommands);
- }
-
- if (_hasLocationSound)
- _soundMan->playSfx(_locationSound, 0, true);
-
- debugC(1, kDebugLocation, "changeLocation() done");
-
- return;
-
-}
// displays transition before a new location
//
diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h
index 1fbdcd6237..4fc9f64537 100644
--- a/engines/parallaction/parallaction.h
+++ b/engines/parallaction/parallaction.h
@@ -238,8 +238,8 @@ struct Location {
struct Character {
Animation _ani;
Graphics::Surface *_head;
- Cnv *_talk;
- Cnv *_objs;
+ Frames *_talk;
+ Frames *_objs;
PathBuilder _builder;
Character() : _builder(&_ani) {
@@ -381,7 +381,6 @@ public:
void changeCursor(int32 index);
void showCursor(bool visible);
- void changeCharacter(const char *name);
Job *addJob(JobFn fn, void *parm, uint16 tag);
@@ -501,6 +500,9 @@ protected: // data
BackgroundInfo *_backgroundInfo;
+ Job *_jDrawLabel;
+ Job *_jEraseLabel;
+ Zone *_hoverZone;
protected: // members
bool detectGame(void);
@@ -519,7 +521,8 @@ protected: // members
void doSaveGame(uint16 slot, const char* name);
void doLocationEnterTransition();
- void changeLocation(char *location);
+ virtual void changeLocation(char *location) = 0;
+ virtual void changeCharacter(const char *name) = 0;
void allocateLocationSlot(const char *name);
void finalizeLocationParsing();
void switchBackground(const char* background, const char* mask);
@@ -580,6 +583,9 @@ private:
void freeFonts();
private:
+ void changeLocation(char *location);
+ void changeCharacter(const char *name);
+
void initResources();
void initCursors();
@@ -833,6 +839,8 @@ private:
void initOpcodes();
void initParsers();
+ void changeLocation(char *location);
+ void changeCharacter(const char *name);
void initPart();
void freePart();
diff --git a/engines/parallaction/parallaction_br.cpp b/engines/parallaction/parallaction_br.cpp
index 3fd56b80aa..31b2793090 100644
--- a/engines/parallaction/parallaction_br.cpp
+++ b/engines/parallaction/parallaction_br.cpp
@@ -349,5 +349,13 @@ void Parallaction_br::startPart() {
}
+void Parallaction_br::changeLocation(char *location) {
+
+}
+
+void Parallaction_br::changeCharacter(const char *name) {
+
+}
+
} // namespace Parallaction
diff --git a/engines/parallaction/parallaction_ns.cpp b/engines/parallaction/parallaction_ns.cpp
index 2a82002f24..db0cdf84e7 100644
--- a/engines/parallaction/parallaction_ns.cpp
+++ b/engines/parallaction/parallaction_ns.cpp
@@ -151,7 +151,7 @@ void Parallaction_ns::setMousePointer(int16 index) {
byte *v8 = (byte*)_mouseComposedArrow->pixels;
// FIXME: destination offseting is not clear
- byte* s = _char._objs->getFramePtr(getInventoryItemIndex(index));
+ byte* s = _char._objs->getData(getInventoryItemIndex(index));
byte* d = v8 + 7 + MOUSECOMBO_WIDTH * 7;
for (uint i = 0; i < INVENTORYITEM_HEIGHT; i++) {
@@ -208,5 +208,180 @@ int Parallaction_ns::go() {
}
+/*
+ changeLocation handles transitions between locations, and is able to display slides
+ between one and the other. The input parameter 'location' exists in some flavours:
+
+ 1 - [S].slide.[L]{.[C]}
+ 2 - [L]{.[C]}
+
+ where:
+
+ [S] is the slide to be shown
+ [L] is the location to switch to (immediately in case 2, or right after slide [S] in case 1)
+ [C] is the character to be selected, and is optional
+
+ The routine tells one form from the other by searching for the '.slide.'
+
+ NOTE: there exists one script in which [L] is not used in the case 1, but its use
+ is commented out, and would definitely crash the current implementation.
+*/
+void Parallaction_ns::changeLocation(char *location) {
+ debugC(1, kDebugLocation, "changeLocation(%s)", location);
+
+ _soundMan->playLocationMusic(location);
+
+ // WORKAROUND: this if-statement has been added to avoid crashes caused by
+ // execution of label jobs after a location switch. The other workaround in
+ // Parallaction::runGame should have been rendered useless by this one.
+ if (_jDrawLabel != NULL) {
+ removeJob(_jDrawLabel);
+ removeJob(_jEraseLabel);
+ _jDrawLabel = NULL;
+ _jEraseLabel = NULL;
+ }
+
+
+ _hoverZone = NULL;
+ if (_engineFlags & kEngineBlockInput) {
+ changeCursor( kCursorArrow );
+ }
+
+ _animations.remove(&_char._ani);
+
+ freeLocation();
+ char buf[100];
+ strcpy(buf, location);
+
+ Common::StringList list;
+ char *tok = strtok(location, ".");
+ while (tok) {
+ list.push_back(tok);
+ tok = strtok(NULL, ".");
+ }
+
+ if (list.size() < 1 || list.size() > 4)
+ error("changeLocation: ill-formed location string '%s'", location);
+
+ if (list.size() > 1) {
+ if (list[1] == "slide") {
+ showSlide(list[0].c_str());
+ _gfx->setFont(_menuFont);
+ _gfx->displayCenteredString(14, _slideText[0]); // displays text on screen
+ _gfx->updateScreen();
+ waitUntilLeftClick();
+
+ list.remove_at(0); // removes slide name
+ list.remove_at(0); // removes 'slide'
+ }
+
+ // list is now only [L].{[C]} (see above comment)
+ if (list.size() == 2) {
+ changeCharacter(list[1].c_str());
+ strcpy(_characterName, list[1].c_str());
+ }
+ }
+
+ _animations.push_front(&_char._ani);
+
+ strcpy(_saveData1, list[0].c_str());
+ parseLocation(list[0].c_str());
+
+ _char._ani._oldPos.x = -1000;
+ _char._ani._oldPos.y = -1000;
+
+ _char._ani.field_50 = 0;
+ if (_location._startPosition.x != -1000) {
+ _char._ani._left = _location._startPosition.x;
+ _char._ani._top = _location._startPosition.y;
+ _char._ani._frame = _location._startFrame;
+ _location._startPosition.y = -1000;
+ _location._startPosition.x = -1000;
+ }
+
+
+ _gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront);
+ _gfx->copyScreen(Gfx::kBitBack, Gfx::kBit2);
+ _gfx->setBlackPalette();
+ _gfx->updateScreen();
+
+ if (_location._commands.size() > 0) {
+ runCommands(_location._commands);
+ runJobs();
+ _gfx->swapBuffers();
+ runJobs();
+ _gfx->swapBuffers();
+ }
+
+ if (_location._comment) {
+ doLocationEnterTransition();
+ }
+
+ runJobs();
+ _gfx->swapBuffers();
+
+ _gfx->setPalette(_gfx->_palette);
+ if (_location._aCommands.size() > 0) {
+ runCommands(_location._aCommands);
+ }
+
+ if (_hasLocationSound)
+ _soundMan->playSfx(_locationSound, 0, true);
+
+ debugC(1, kDebugLocation, "changeLocation() done");
+
+ return;
+
+}
+
+void Parallaction_ns::changeCharacter(const char *name) {
+ debugC(1, kDebugLocation, "changeCharacter(%s)", name);
+
+ char baseName[20];
+ if (IS_MINI_CHARACTER(name)) {
+ strcpy(baseName, name+4);
+ } else {
+ strcpy(baseName, name);
+ }
+
+ char fullName[20];
+ strcpy(fullName, name);
+ if (_engineFlags & kEngineTransformedDonna)
+ strcat(fullName, "tras");
+
+ if (scumm_stricmp(fullName, _characterName1)) {
+
+ // freeCharacter takes responsibility for checking
+ // character for sanity before memory is freed
+ freeCharacter();
+
+ Common::String oldArchive = _disk->selectArchive((getFeatures() & GF_LANG_MULT) ? "disk1" : "disk0");
+ _char._ani._cnv = _disk->loadFrames(fullName);
+
+ if (!IS_DUMMY_CHARACTER(name)) {
+ if (getPlatform() == Common::kPlatformAmiga && (getFeatures() & GF_LANG_MULT))
+ _disk->selectArchive("disk0");
+
+ _char._head = _disk->loadHead(baseName);
+ _char._talk = _disk->loadTalk(baseName);
+ _char._objs = _disk->loadObjects(baseName);
+ _objectsNames = _disk->loadTable(baseName);
+
+ _soundMan->playCharacterMusic(name);
+
+ if (!(getFeatures() & GF_DEMO))
+ parseLocation("common");
+ }
+
+ if (!oldArchive.empty())
+ _disk->selectArchive(oldArchive);
+ }
+
+ strcpy(_characterName1, fullName);
+
+ debugC(1, kDebugLocation, "changeCharacter() done");
+
+ return;
+}
} // namespace Parallaction
diff --git a/engines/parallaction/parser_ns.cpp b/engines/parallaction/parser_ns.cpp
index 1956e7cb03..e3ee3157fb 100644
--- a/engines/parallaction/parser_ns.cpp
+++ b/engines/parallaction/parser_ns.cpp
@@ -1234,7 +1234,10 @@ void Parallaction_ns::parseZoneTypeBlock(Script &script, Zone *z) {
u->door->_cnv = _disk->loadFrames(vC8);
uint16 _ax = (z->_flags & kFlagsClosed ? 0 : 1);
- u->door->_background = (byte*)malloc(u->door->_cnv->_width * u->door->_cnv->_height);
+ Common::Rect r;
+ u->door->_cnv->getRect(0, r);
+
+ u->door->_background = (byte*)malloc(r.width() * r.height());
_gfx->backupDoorBackground(u->door, z->_left, z->_top);
_gfx->flatBlitCnv(u->door->_cnv, _ax, z->_left, z->_top, Gfx::kBitBack);