diff options
| -rw-r--r-- | engines/parallaction/dialogue.cpp | 4 | ||||
| -rw-r--r-- | engines/parallaction/disk.h | 27 | ||||
| -rw-r--r-- | engines/parallaction/disk_br.cpp | 94 | ||||
| -rw-r--r-- | engines/parallaction/disk_ns.cpp | 12 | ||||
| -rw-r--r-- | engines/parallaction/exec_ns.cpp | 6 | ||||
| -rw-r--r-- | engines/parallaction/graphics.cpp | 15 | ||||
| -rw-r--r-- | engines/parallaction/graphics.h | 32 | ||||
| -rw-r--r-- | engines/parallaction/inventory.cpp | 13 | ||||
| -rw-r--r-- | engines/parallaction/inventory.h | 2 | ||||
| -rw-r--r-- | engines/parallaction/objects.cpp | 12 | ||||
| -rw-r--r-- | engines/parallaction/objects.h | 4 | ||||
| -rw-r--r-- | engines/parallaction/parallaction.cpp | 182 | ||||
| -rw-r--r-- | engines/parallaction/parallaction.h | 16 | ||||
| -rw-r--r-- | engines/parallaction/parallaction_br.cpp | 8 | ||||
| -rw-r--r-- | engines/parallaction/parallaction_ns.cpp | 177 | ||||
| -rw-r--r-- | engines/parallaction/parser_ns.cpp | 5 | 
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);  | 
