[Scummvm-cvs-logs] CVS: scummvm/saga actor.cpp,1.83,1.84 actor.h,1.44,1.45 actordata.cpp,1.13,1.14 interface.cpp,1.54,1.55 interface.h,1.23,1.24 sprite.cpp,1.38,1.39 sprite.h,1.13,1.14

Andrew Kurushin h00ligan at users.sourceforge.net
Sun Jan 9 07:09:02 CET 2005


Update of /cvsroot/scummvm/scummvm/saga
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24820

Modified Files:
	actor.cpp actor.h actordata.cpp interface.cpp interface.h 
	sprite.cpp sprite.h 
Log Message:
rewritten sprite class
- sprites decoded on first load
- some speed optimization
- actors uses kExtended flag to append spriteList


Index: actor.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/actor.cpp,v
retrieving revision 1.83
retrieving revision 1.84
diff -u -d -r1.83 -r1.84
--- actor.cpp	8 Jan 2005 20:30:06 -0000	1.83
+++ actor.cpp	9 Jan 2005 15:07:48 -0000	1.84
@@ -228,7 +228,7 @@
 	for (i = 0; i < ACTORCOUNT; i++) {
 		actor = &_actors[i];
 		free(actor->frames);
-		_vm->_sprite->freeSprite(actor->spriteList);
+		actor->spriteList.freeMem();
 	}
 }
 
@@ -239,6 +239,7 @@
 	ActorFrameSequence *framesPointer;
 	int lastFrame;
 	int i, orient;
+	int resourceId;
 
 	if (actor->frameListResourceId == 0) {
 		warning("Frame List ID = 0 for actor index %d", actor->index);
@@ -281,20 +282,22 @@
 	actor->frames = framesPointer;
 	actor->framesCount = framesCount;
 
-
-	debug(9, "Loading sprite resource id %d", actor->spriteListResourceId);
-	if (_vm->_sprite->loadList(actor->spriteListResourceId, &actor->spriteList) != SUCCESS) {
+	resourceId = actor->spriteListResourceId;
+	debug(9, "Loading sprite resource id %d", resourceId);
+	if (_vm->_sprite->loadList(resourceId, actor->spriteList) != SUCCESS) {
 		warning("Unable to load sprite list");
 		return false;
 	}
 
-	i = _vm->_sprite->getListLen(actor->spriteList);
-
-	if (lastFrame >= i) {
-		debug(9, "Appending to sprite list %d (+ %d)", actor->spriteListResourceId, lastFrame);
-		if (_vm->_sprite->appendList(actor->spriteListResourceId + 1, actor->spriteList) != SUCCESS) {
-			warning("Unable append sprite list");
-			return false;
+	i = actor->spriteList.spriteCount;
+	if ((actor->flags & kExtended)) {
+		while ((lastFrame >= actor->spriteList.spriteCount)) {
+			resourceId++;
+			debug(9, "Appending to sprite list %d", resourceId);
+			if (_vm->_sprite->loadList(resourceId, actor->spriteList) != SUCCESS) {
+				warning("Unable append sprite list");
+				return false;
+			}
 		}
 	}
 
@@ -942,13 +945,13 @@
 				continue;
 			}
 			frameNumber = 8;			
-			spriteList = _vm->_sprite->_mainSprites;
+			spriteList = &_vm->_sprite->_mainSprites;
 		} else {
 			frameNumber = actor->frameNumber;			
-			spriteList = actor->spriteList;
+			spriteList = &actor->spriteList;
 		}
 		
-		if ((frameNumber < 0) || (spriteList->sprite_count <= frameNumber)) {
+		if ((frameNumber < 0) || (spriteList->spriteCount <= frameNumber)) {
 			warning("Actor::drawActors frameNumber invalid for actorId 0x%X", actor->actorId);
 			continue;
 		}
@@ -956,7 +959,7 @@
 		if (_vm->_scene->getFlags() & kSceneFlagISO) {
 			//todo: it
 		} else {
-			_vm->_sprite->drawOccluded(back_buf, spriteList, frameNumber, actor->screenPosition, actor->screenScale, actor->screenDepth);
+			_vm->_sprite->drawOccluded(back_buf, *spriteList, frameNumber, actor->screenPosition, actor->screenScale, actor->screenDepth);
 		}
 	}
 

Index: actor.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/actor.h,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -d -r1.44 -r1.45
--- actor.h	8 Jan 2005 21:06:06 -0000	1.44
+++ actor.h	9 Jan 2005 15:07:48 -0000	1.45
@@ -198,7 +198,7 @@
 	uint8 cycleTimeCount;
 	uint8 cycleFlags;
 
-	SpriteList *spriteList;		// Actor's sprite list data
+	SpriteList spriteList;		// Actor's sprite list data
 	int spriteListResourceId;	// Actor's sprite list resource id
 
 	ActorFrameSequence *frames;	// Actor's frames
@@ -232,6 +232,7 @@
 		memset(this, 0xFE, sizeof(*this)); 
 		walkStepsPoints = NULL;
 		walkStepsAlloced = walkStepsCount = walkStepIndex = 0;
+		memset(&spriteList, 0, sizeof(spriteList));
 	}
 	~ActorData() {
 		free(walkStepsPoints);

Index: actordata.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/actordata.cpp,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- actordata.cpp	1 Jan 2005 16:18:36 -0000	1.13
+++ actordata.cpp	9 Jan 2005 15:07:48 -0000	1.14
@@ -34,10 +34,13 @@
 
 //       flags     name scene    x     y    z  spr  frm scp  col 
 //    ------------ ---- ----  ---- ----- ---- ---- ---- --- ---- -- -- --
-	{ kProtagonist,  0,   1,    0,    0,   0,  37, 135,  0,   1,  0, 0, 0},	// map party
-	// spr and frm numbers taken from permanent actors list
-	{ kFollower,     1,   0,    0,    0,   0,  45, 177,  1, 132,  0, 0, 0},	// Okk
-	{ kFollower,     2,   0,    0,    0,   0,  48, 143,  2, 161,  0, 0, 0},	// Eeah
+	{ kProtagonist | kExtended,
+					 0,   1,    0,    0,   0,  37, 135,  0,   1,  0, 0, 0},	// map party
+																			// spr and frm numbers taken from permanent actors list
+	{ kFollower | kExtended,
+					 1,   0,    0,    0,   0,  45, 177,  1, 132,  0, 0, 0},	// Okk
+	{ kFollower | kExtended,
+					 2,   0,    0,    0,   0,  48, 143,  2, 161,  0, 0, 0},	// Eeah
 	{ 0,             3,   0,  240,  480,   0, 115, 206,  0,  25,  0, 0, 0},	// albino ferret
 	{ 0,             4,  17,  368,  400,   0, 115, 206,  4,  49,  0, 0, 0},	// moneychanger
 	{ 0,             5,  11,  552,  412,   0,  54, 152,  1, 171,  0, 0, 0},	// Sist

Index: interface.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/interface.cpp,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -d -r1.54 -r1.55
--- interface.cpp	8 Jan 2005 20:30:06 -0000	1.54
+++ interface.cpp	9 Jan 2005 15:07:48 -0000	1.55
@@ -213,9 +213,15 @@
 		return;
 	}
 
-	_vm->_sprite->loadList(RID_ITE_COMMAND_BUTTONSPRITES, &_cPanel.sprites);
+	if (_vm->_sprite->loadList(RID_ITE_COMMAND_BUTTONSPRITES, _cPanel.sprites) != SUCCESS) {
+		error("Unable to load sprite list");
+	}
+	
+	
+	if (_vm->_sprite->loadList(RID_ITE_DEFAULT_PORTRAITS, _defPortraits) != SUCCESS) {
+		error("Unable to load sprite list");
+	}
 
-	_vm->_sprite->loadList(RID_ITE_DEFAULT_PORTRAITS, &_defPortraits);
 
 	_vm->decodeBGImage(_cPanel.res, _cPanel.res_len, &_cPanel.img,
 					&_cPanel.img_len, &_cPanel.img_w, &_cPanel.img_h);
@@ -231,7 +237,6 @@
 	_dPanel.y = 149;
 
 	_cPanel.set_button = COMMAND_DEFAULT_BUTTON;
-	_scenePortraits = 0;
 	_leftPortrait = 0;
 	_rightPortrait = 0;
 
@@ -256,6 +261,10 @@
 
 Interface::~Interface(void) {
 	free(_inventory);
+	 
+	_cPanel.sprites.freeMem();
+	_defPortraits.freeMem();
+	_scenePortraits.freeMem();
 	_initialized = false;
 }
 
@@ -332,11 +341,10 @@
 	return SUCCESS;
 }
 
-int Interface::loadScenePortraits(int res) {
-	if (_scenePortraits)
-		_vm->_sprite->freeSprite(_scenePortraits);
+int Interface::loadScenePortraits(int resourceId) {
+	_scenePortraits.freeMem();
 
-	return _vm->_sprite->loadList(res, &_scenePortraits);
+	return _vm->_sprite->loadList(resourceId, _scenePortraits);
 }
 
 int Interface::setLeftPortrait(int portrait) {

Index: interface.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/interface.h,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- interface.h	8 Jan 2005 20:30:06 -0000	1.23
+++ interface.h	9 Jan 2005 15:07:48 -0000	1.24
@@ -150,7 +150,7 @@
 	int set_button;
 	int nbuttons;
 	INTERFACE_BUTTON *buttons;
-	SpriteList *sprites;
+	SpriteList sprites;
 };
 
 struct INTERFACE_DESC {
@@ -217,7 +217,7 @@
 	void unlockMode() { _panelMode = _lockedMode; }
 	bool isInMainMode() { return _inMainMode; }
 	int setStatusText(const char *new_txt);
-	int loadScenePortraits(int res);
+	int loadScenePortraits(int resourceId);
 	int setLeftPortrait(int portrait);
 	int setRightPortrait(int portrait);
 	int draw();
@@ -252,8 +252,8 @@
 	char _statusText[STATUS_TEXT_LEN];
 	int _leftPortrait;
 	int _rightPortrait;
-	SpriteList *_defPortraits;
-	SpriteList *_scenePortraits;
+	SpriteList _defPortraits;
+	SpriteList _scenePortraits;
 	int _activeVerb;
 	SCRIPT_THREAD *_iThread;
 

Index: sprite.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/sprite.cpp,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -d -r1.38 -r1.39
--- sprite.cpp	8 Jan 2005 20:30:06 -0000	1.38
+++ sprite.cpp	9 Jan 2005 15:07:48 -0000	1.39
@@ -47,12 +47,12 @@
 
 	_decodeBufLen = DECODE_BUF_LEN;
 
-	_decodeBuf = (byte *)malloc(DECODE_BUF_LEN);
+	_decodeBuf = (byte *)malloc(_decodeBufLen);
 	if (_decodeBuf == NULL) {
 		return;
 	}
 
-	loadList(RID_ITE_MAIN_SPRITES, &_mainSprites); //fixme: IHNM may have no such list
+	loadList(RID_ITE_MAIN_SPRITES, _mainSprites); //fixme: IHNM may have no such list
 
 	_initialized = true;
 }
@@ -63,231 +63,185 @@
 	}
 
 	debug(0, "Shutting down sprite subsystem...");
-
+	_mainSprites.freeMem();
 	free(_decodeBuf);
 }
 
-int Sprite::loadList(int resource_num, SpriteList **sprite_list_p) {
-	SpriteList *new_slist;
-	byte *spritelist_data;
-	size_t spritelist_len;
-	uint16 sprite_count;
-	uint16 i;
+int Sprite::loadList(int resourceId, SpriteList &spriteList) {
+	SpriteInfo *spriteInfo;
+	byte *spriteListData;
+	size_t spriteListLength;
+	uint16 oldSpriteCount;
+	uint16 newSpriteCount;
+	uint16 spriteCount;
+	int i;
+	int outputLength;
+	uint32 offset;
+	const byte *spritePointer;
+	const byte *spriteDataPointer;
 
-	if (RSC_LoadResource(_spriteContext, resource_num, &spritelist_data, &spritelist_len) != SUCCESS) {
+	if (RSC_LoadResource(_spriteContext, resourceId, &spriteListData, &spriteListLength) != SUCCESS) {
+		warning("Sprite::loadList RSC_LoadResource FAILURE");
 		return FAILURE;
 	}
 
-	if (spritelist_len == 0)
+	if (spriteListLength == 0) {
+		warning("Sprite::loadList spriteListLength == 0");
 		return FAILURE;
-
-	MemoryReadStreamEndian readS(spritelist_data, spritelist_len, IS_BIG_ENDIAN);
-
-	sprite_count = readS.readUint16();
-
-	new_slist = (SpriteList *)malloc(sizeof(*new_slist));
-	if (new_slist == NULL) {
-		return MEM;
 	}
 
-	new_slist->sprite_count = sprite_count;
-
-	new_slist->offset_list = (SPRITELIST_OFFSET *)malloc(sprite_count * sizeof(*new_slist->offset_list));
-	if (new_slist->offset_list == NULL) {
-		free(new_slist);
-		return MEM;
-	}
-
-	for (i = 0; i < sprite_count; i++) {
-		new_slist->offset_list[i].data_idx = 0;
-		if (_vm->_features & GF_MAC_RESOURCES)
-			new_slist->offset_list[i].offset = readS.readUint32();
-		else
-			new_slist->offset_list[i].offset = readS.readUint16();
-	}
-
-	new_slist->slist_rn = resource_num;
-	new_slist->sprite_data[0] = spritelist_data;
-	new_slist->append_count = 0;
-
-	*sprite_list_p = new_slist;
+	MemoryReadStreamEndian readS(spriteListData, spriteListLength, IS_BIG_ENDIAN);
 
-	return SUCCESS;
-}
+	spriteCount = readS.readUint16();
 
-int Sprite::appendList(int resource_num, SpriteList *spritelist) {
-	byte *spritelist_data;
-	size_t spritelist_len;
-	void *test_p;
-	uint16 old_sprite_count;
-	uint16 new_sprite_count;
-	uint16 sprite_count;
-	int i;
+	oldSpriteCount = spriteList.spriteCount;
+	newSpriteCount = spriteList.spriteCount + spriteCount;
 
-	if (spritelist->append_count >= (APPENDMAX - 1)) {
-		return FAILURE;
+	spriteList.infoList = (SpriteInfo *)realloc(spriteList.infoList, newSpriteCount * sizeof(*spriteList.infoList));
+	if (spriteList.infoList == NULL) {
+		error("Sprite::loadList Not enough memory");
 	}
 
-	if (RSC_LoadResource(_spriteContext, resource_num, &spritelist_data, &spritelist_len) != SUCCESS) {
-		return FAILURE;
-	}
+	spriteList.spriteCount = newSpriteCount;
 
-	MemoryReadStreamEndian readS(spritelist_data, spritelist_len, IS_BIG_ENDIAN);
+	for (i = oldSpriteCount; i < spriteList.spriteCount; i++) {
+		spriteInfo = &spriteList.infoList[i];
+		if (_vm->_features & GF_MAC_RESOURCES)
+			offset = readS.readUint32();
+		else
+			offset = readS.readUint16();
 
-	sprite_count = readS.readUint16();
+		if (offset >= spriteListLength) {
+			error("Sprite::loadList offset exceed");
+		}
 
-	old_sprite_count = spritelist->sprite_count;
-	new_sprite_count = spritelist->sprite_count + sprite_count;
+		spritePointer = spriteListData;
+		spritePointer += offset;
 
-	test_p = realloc(spritelist->offset_list, new_sprite_count * sizeof(*spritelist->offset_list));
-	if (test_p == NULL) {
-		return MEM;
-	}
+		MemoryReadStream readS(spritePointer, (_vm->_features & GF_MAC_RESOURCES) ? 8 : 4);
 
-	spritelist->offset_list = (SPRITELIST_OFFSET *)test_p;
+		if (!(_vm->_features & GF_MAC_RESOURCES)) {
+			spriteInfo->xAlign = readS.readSByte();
+			spriteInfo->yAlign = readS.readSByte();
 
-	spritelist->sprite_count = new_sprite_count;
-	spritelist->append_count++;
+			spriteInfo->width = readS.readByte();
+			spriteInfo->height = readS.readByte();
+		} else {
+			spriteInfo->xAlign = readS.readSint16BE();
+			spriteInfo->yAlign = readS.readSint16BE();
 
-	for (i = old_sprite_count; i < spritelist->sprite_count; i++) {
-		spritelist->offset_list[i].data_idx = spritelist->append_count;
-		spritelist->offset_list[i].offset = readS.readUint16();
+			spriteInfo->width = readS.readUint16BE();
+			spriteInfo->height = readS.readUint16BE();
+		}
+		spriteDataPointer = spritePointer + readS.pos();
+		outputLength = spriteInfo->width * spriteInfo->height;
+		decodeRLEBuffer(spriteDataPointer, 64000, outputLength); //todo: 64000 - should be replace by real input length
+		spriteInfo->decodedBuffer = (byte *) malloc(outputLength);
+		if (spriteInfo->decodedBuffer == NULL) {
+			error("Sprite::loadList Not enough memory");
+		}
+		memcpy(spriteInfo->decodedBuffer, _decodeBuf, outputLength);
 	}
 
-	spritelist->sprite_data[spritelist->append_count] = spritelist_data;
+	RSC_FreeResource(spriteListData);
 
 	return SUCCESS;
 }
 
-int Sprite::getListLen(SpriteList *spritelist) {
-	return spritelist->sprite_count;
-}
-
-int Sprite::freeSprite(SpriteList *spritelist) {
-	int i;
-
-	for (i = 0; i <= spritelist->append_count; i++) {
+void Sprite::getScaledSpriteBuffer(SpriteList &spriteList, int spriteNumber, int scale, int &width, int &height, int &xAlign, int &yAlign, const byte *&buffer) {
+	SpriteInfo *spriteInfo;
+	assert(spriteList.spriteCount>spriteNumber);
+	spriteInfo = &spriteList.infoList[spriteNumber];
 
-		RSC_FreeResource(spritelist->sprite_data[i]);
+	if (scale < 256) {
+		xAlign = (spriteInfo->xAlign * scale) >> 8;
+		yAlign = (spriteInfo->yAlign * scale) >> 8;
+		height = (spriteInfo->height * scale + 0x80) >> 8;
+		width = (spriteInfo->width * scale + 0x80) >> 8;
+		scaleBuffer(spriteInfo->decodedBuffer, spriteInfo->width, spriteInfo->height, scale);
+		buffer = _decodeBuf;
+	} else {
+		xAlign = spriteInfo->xAlign;
+		yAlign = spriteInfo->yAlign;
+		height = spriteInfo->height;
+		width = spriteInfo->width;
+		buffer = spriteInfo->decodedBuffer;
 	}
 
-	free(spritelist->offset_list);
-	free(spritelist);
-
-	return SUCCESS;
 }
 
-int Sprite::draw(SURFACE *ds, SpriteList *sprite_list, int sprite_num, const Point &screenCoord, int scale) {
-	int offset;
-	int offset_idx;
-	byte *sprite_p;
-	const byte *sprite_data_p;
+int Sprite::draw(SURFACE *ds, SpriteList &spriteList, int spriteNumber, const Point &screenCoord, int scale) {
+	const byte *spriteBuffer;
 	int i, j;
 	byte *buf_row_p;
-	byte *src_row_p;
-	int s_width, so_width;
-	int s_height, so_height;
+	const byte *src_row_p;
 	int clip_width;
 	int clip_height;
-	int x_align;
-	int y_align;
-	Point spr_pt;
-
-	if (!_initialized) {
-		return FAILURE;
-	}
-
-	offset = sprite_list->offset_list[sprite_num].offset;
-	offset_idx = sprite_list->offset_list[sprite_num].data_idx;
-
-	sprite_p = sprite_list->sprite_data[offset_idx];
-	sprite_p += offset;
-
-	assert(sprite_p);
-
-	MemoryReadStream readS(sprite_p, 8);
-	if (!(_vm->_features & GF_MAC_RESOURCES)) {
-		x_align = readS.readSByte();
-		y_align = readS.readSByte();
-
-		so_width = s_width = readS.readByte();
-		so_height = s_height = readS.readByte();
-	} else {
-		x_align = readS.readSint16BE();
-		y_align = readS.readSint16BE();
-
-		so_width = s_width = readS.readUint16BE();
-		so_height = s_height = readS.readUint16BE();
-	}
-	spr_pt.x = screenCoord.x + x_align;
-	spr_pt.y = screenCoord.y + y_align;
-
-	if (scale < 256)
-		scaleSpriteCoords(scale, &s_width, &s_height, &x_align, &y_align);
-
-	sprite_data_p = sprite_p + readS.pos();
+	int width;
+	int height;
+	int xAlign;
+	int yAlign;
+	Point spritePointer;
 
-	decodeRLESprite(sprite_data_p, 64000, _decodeBuf, so_width * so_height);
+	assert(_initialized);
 
-	if (scale < 256)
-		scaleSprite(_decodeBuf, so_width, so_height, scale);
+	getScaledSpriteBuffer(spriteList, spriteNumber, scale, width, height, xAlign, yAlign, spriteBuffer);
+	
+	spritePointer.x = screenCoord.x + xAlign;
+	spritePointer.y = screenCoord.y + yAlign;
 
-	if (spr_pt.x < 0) {
+	if (spritePointer.x < 0) {
 		return 0;
 	}
-
-	if (spr_pt.y < 0) {
+	if (spritePointer.y < 0) {
 		return 0;
 	}
 
-	buf_row_p = (byte *)ds->pixels + ds->pitch * spr_pt.y;
-	src_row_p = _decodeBuf;
+	buf_row_p = (byte *)ds->pixels + ds->pitch * spritePointer.y;
+	src_row_p = spriteBuffer;
 
 	// Clip to right side of surface
-	clip_width = s_width;
-	if (s_width > (ds->w - spr_pt.x)) {
-		clip_width = (ds->w - spr_pt.x);
+	clip_width = width;
+	if (width > (ds->w - spritePointer.x)) {
+		clip_width = (ds->w - spritePointer.x);
 	}
 
 	// Clip to bottom side of surface
-	clip_height = s_height;
-	if (s_height > (ds->h - spr_pt.y)) {
-		clip_height = (ds->h - spr_pt.y);
+	clip_height = height;
+	if (height > (ds->h - spritePointer.y)) {
+		clip_height = (ds->h - spritePointer.y);
 	}
 
 	for (i = 0; i < clip_height; i++) {
 		for (j = 0; j < clip_width; j++) {
 			if (*(src_row_p + j) != 0) {
-				*(buf_row_p + j + spr_pt.x) = *(src_row_p + j);
+				*(buf_row_p + j + spritePointer.x) = *(src_row_p + j);
 			}
 		}
 		buf_row_p += ds->pitch;
-		src_row_p += s_width;
+		src_row_p += width;
 	}
 
 	return SUCCESS;
 }
 
-int Sprite::drawOccluded(SURFACE *ds, SpriteList *sprite_list, int sprite_num, const Point &screenCoord, int scale, int depth) {
-	int offset;
-	int offset_idx;
-	byte *sprite_p;
-	const byte *sprite_data_p;
+int Sprite::drawOccluded(SURFACE *ds, SpriteList &spriteList, int spriteNumber, const Point &screenCoord, int scale, int depth) {
+	const byte *spriteBuffer;
 	int x, y;
 	byte *dst_row_p;
-	byte *src_row_p;
-	byte *src_p;
+	const byte *src_row_p;
+	const byte *src_p;
 	byte *dst_p;
 	byte *mask_p;
-	int s_width, so_width;
-	int s_height, so_height;
-	int x_align;
-	int y_align;
+	int width;
+	int height;
+	int xAlign;
+	int yAlign;
+	Point spritePointer;
 
 	// Clipinfo variables
-	Point spr_pt;
-	Rect spr_src_rect;
-	Rect spr_dst_rect;
+	Rect spriteSourceRect;
+	Rect spriteDestRect;
 	CLIPINFO ci;
 
 	// BG mask variables
@@ -299,67 +253,32 @@
 	int mask_z;
 
 
-	if (!_initialized) {
-		return FAILURE;
-	}
+	assert(_initialized);
 
 	if (!_vm->_scene->isBGMaskPresent()) {
-		return draw(ds, sprite_list, sprite_num, screenCoord, scale);
-	}
-
-	if (sprite_num >= sprite_list->sprite_count) {
-		warning("Invalid sprite number (%d) for sprite list %d", sprite_num, sprite_list->slist_rn);
-		return FAILURE;
-	}
-
-	// Get sprite data from list 
-	offset = sprite_list->offset_list[sprite_num].offset;
-	offset_idx = sprite_list->offset_list[sprite_num].data_idx;
-
-	sprite_p = sprite_list->sprite_data[offset_idx];
-	sprite_p += offset;
-
-	MemoryReadStream readS(sprite_p, 8);
-
-	// Read sprite dimensions -- should probably cache this stuff in 
-	// sprite list
-	if (!(_vm->_features & GF_MAC_RESOURCES)) {
-		x_align = readS.readSByte();
-		y_align = readS.readSByte();
-
-		so_width = s_width = readS.readByte();
-		so_height = s_height = readS.readByte();
-	} else {
-		x_align = readS.readSint16BE();
-		y_align = readS.readSint16BE();
-
-		so_width = s_width = readS.readUint16BE();
-		so_height = s_height = readS.readUint16BE();
+		return draw(ds, spriteList, spriteNumber, screenCoord, scale);
 	}
 
-	sprite_data_p = sprite_p + readS.pos();
-
 	_vm->_scene->getBGMaskInfo(maskWidth, maskHeight, maskBuffer, maskBufferLength);
 
-	if (scale < 256)
-		scaleSpriteCoords(scale, &s_width, &s_height, &x_align, &y_align);
-
-	spr_src_rect.left = 0;
-	spr_src_rect.top = 0;
-	spr_src_rect.right = s_width;
-	spr_src_rect.bottom = s_height;
+	getScaledSpriteBuffer(spriteList, spriteNumber, scale, width, height, xAlign, yAlign, spriteBuffer);
 
-	spr_dst_rect.left = 0;
-	spr_dst_rect.top = 0;
-	spr_dst_rect.right = ds->clip_rect.right;
-	spr_dst_rect.bottom = MIN(ds->clip_rect.bottom, (int16)maskHeight);
+	spritePointer.x = screenCoord.x + xAlign;
+	spritePointer.y = screenCoord.y + yAlign;
 
-	spr_pt.x = screenCoord.x + x_align;
-	spr_pt.y = screenCoord.y + y_align;
+	spriteSourceRect.left = 0;
+	spriteSourceRect.top = 0;
+	spriteSourceRect.right = width;
+	spriteSourceRect.bottom = height;
 
-	ci.dst_rect = &spr_dst_rect;
-	ci.src_rect = &spr_src_rect;
-	ci.dst_pt = &spr_pt;
+	spriteDestRect.left = 0;
+	spriteDestRect.top = 0;
+	spriteDestRect.right = ds->clip_rect.right;
+	spriteDestRect.bottom = MIN(ds->clip_rect.bottom, (int16)maskHeight);
+	
+	ci.dst_rect = &spriteDestRect;
+	ci.src_rect = &spriteSourceRect;
+	ci.dst_pt = &spritePointer;
 
 	getClipInfo(&ci);
 
@@ -367,13 +286,9 @@
 		return SUCCESS;
 	}
 
-	decodeRLESprite(sprite_data_p, 64000, _decodeBuf, so_width * so_height);
-
-	if (scale < 256)
-		scaleSprite(_decodeBuf, so_width, so_height, scale);
 
 	// Finally, draw the occluded sprite
-	src_row_p = _decodeBuf + ci.src_draw_x + (ci.src_draw_y * s_width);
+	src_row_p = spriteBuffer + ci.src_draw_x + (ci.src_draw_y * width);
 
 	dst_row_p = (byte *)ds->pixels + ci.dst_draw_x + (ci.dst_draw_y * ds->pitch);
 	mask_row_p = maskBuffer + ci.dst_draw_x + (ci.dst_draw_y * maskWidth);
@@ -395,59 +310,57 @@
 		}
 		dst_row_p += ds->pitch;
 		mask_row_p += maskWidth;
-		src_row_p += s_width;
+		src_row_p += width;
 	}
 
 	return SUCCESS;
 }
 
-int Sprite::decodeRLESprite(const byte *inbuf, size_t inbuf_len, byte *outbuf, size_t outbuf_len) {
+void Sprite::decodeRLEBuffer(const byte *inputBuffer, size_t inLength, size_t outLength) {
 	int bg_runcount;
 	int fg_runcount;
-	byte *outbuf_ptr;
-	byte *outbuf_end;
+	byte *outPointer;
+	byte *outPointerEnd;
 	int c;
 
-	outbuf_ptr = outbuf;
-
-	outbuf_end = outbuf + outbuf_len;
-	outbuf_end--;
+	if (outLength > _decodeBufLen) { // TODO: may we should make dynamic growing?
+		error("Sprite::decodeRLEBuffer outLength > _decodeBufLen");
+	}
+	
+	outPointer = _decodeBuf;
+	outPointerEnd = _decodeBuf + outLength;
+	outPointerEnd--;
 
-	memset(outbuf, 0, outbuf_len);
+	memset(outPointer, 0, outLength);
 
-	MemoryReadStream readS(inbuf, inbuf_len);
+	MemoryReadStream readS(inputBuffer, inLength);
 
-	while (!readS.eof() && (outbuf_ptr < outbuf_end)) {
+	while (!readS.eof() && (outPointer < outPointerEnd)) {
 		bg_runcount = readS.readByte();
 		fg_runcount = readS.readByte();
 
 		for (c = 0; c < bg_runcount; c++) {
-			*outbuf_ptr = (byte) 0;
-			if (outbuf_ptr < outbuf_end)
-				outbuf_ptr++;
+			*outPointer = (byte) 0;
+			if (outPointer < outPointerEnd)
+				outPointer++;
 			else
-				return 0;
+				return;
 		}
 
 		for (c = 0; c < fg_runcount; c++) {
-			*outbuf_ptr = readS.readByte();
-			if (outbuf_ptr < outbuf_end)
-				outbuf_ptr++;
+			*outPointer = readS.readByte();
+			if (outPointer < outPointerEnd)
+				outPointer++;
 			else
-				return 0;
+				return;
 		}
 	}
-
-	return SUCCESS;
 }
 
-void Sprite::scaleSprite(byte *buf, int width, int height, int scale) {
+void Sprite::scaleBuffer(const byte *src, int width, int height, int scale) {
 	byte skip = 256 - scale; // skip factor
-
 	byte vskip = 0x80, hskip;
-	byte *src, *dst;
-
-	src = dst = buf;
+	byte *dst = _decodeBuf;
 
 	for (int i = 0; i < height; i++) {
 		vskip += skip;
@@ -468,12 +381,5 @@
 	}
 }
 
-void Sprite::scaleSpriteCoords(int scale, int *width, int *height, int *x_align, int *y_align) {
-	*x_align = (*x_align * scale) >> 8;
-	*y_align = (*y_align * scale) >> 8;
-	*height = (*height * scale + 0x80) >> 8;
-	*width = (*width * scale + 0x80) >> 8;
-}
-
 
 } // End of namespace Saga

Index: sprite.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/saga/sprite.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- sprite.h	8 Jan 2005 20:30:06 -0000	1.13
+++ sprite.h	9 Jan 2005 15:07:49 -0000	1.14
@@ -28,53 +28,54 @@
 
 namespace Saga {
 
-#define APPENDMAX 4
-
 #define SPRITE_ZMAX  16
 #define SPRITE_ZMASK 0x0F
 
 #define DECODE_BUF_LEN 64000
 
-struct SPRITELIST_ENTRY {
-	int x_align;
-	int y_align;
+struct SpriteInfo {
+	byte *decodedBuffer;
 	int width;
 	int height;
-
-};
-
-struct SPRITELIST_OFFSET {
-	uint16 data_idx;
-	uint32 offset;
+	int xAlign;
+	int yAlign;
 };
 
 struct SpriteList {
-	int append_count;
-	int sprite_count;
-	SPRITELIST_OFFSET *offset_list;
-	int slist_rn;
-	byte *sprite_data[APPENDMAX];
+	int spriteListResourceId;
+	int spriteCount;
+	SpriteInfo *infoList;
+
+	void freeMem() {
+		int i;
+		for (i = 0; i < spriteCount; i++) {
+			free(infoList[i].decodedBuffer);
+		}
+		free(infoList);
+		memset(this, 0, sizeof(*this));
+	}
+
+	SpriteList() {
+		memset(this, 0, sizeof(*this));
+	}
 };
 
 
 class Sprite {
 public:
-	SpriteList *_mainSprites;
+	SpriteList _mainSprites;
 
 	Sprite(SagaEngine *vm);
 	~Sprite(void);
-	int loadList(int resource_num, SpriteList **sprite_list_p);
-	int appendList(int resource_num, SpriteList *spritelist);
-	int getListLen(SpriteList *spritelist);
-	int freeSprite(SpriteList *spritelist);
-	int draw(SURFACE *ds, SpriteList *sprite_list, int sprite_num, const Point &screenCoord, int scale);
-	int drawOccluded(SURFACE *ds, SpriteList *sprite_list, int sprite_num, const Point &screenCoord, int scale, int depth);
+	int loadList(int resourceId, SpriteList &spriteList); // load or append spriteList
+	int draw(SURFACE *ds, SpriteList &spriteList, int spriteNumber, const Point &screenCoord, int scale);
+	int drawOccluded(SURFACE *ds, SpriteList &spriteList, int spriteNumber, const Point &screenCoord, int scale, int depth);
 
 private:
-	int decodeRLESprite(const byte *inbuf, size_t inbuf_len, byte *outbuf, size_t outbuf_len);
-	void scaleSprite(byte *buf, int width, int height, int scale);
-	void scaleSpriteCoords(int scale, int *width, int *height, int *x_align, int *y_align);
-
+	void decodeRLEBuffer(const byte *inputBuffer, size_t inLength, size_t outLength);
+	void scaleBuffer(const byte *src, int width, int height, int scale);
+	void getScaledSpriteBuffer(SpriteList &spriteList, int spriteNumber, int scale, int &width, int &height, int &xAlign, int &yAlign, const byte *&buffer);
+	
 	SagaEngine *_vm;
 	bool _initialized;
 	RSCFILE_CONTEXT *_spriteContext;





More information about the Scummvm-git-logs mailing list