[Scummvm-cvs-logs] CVS: scummvm/scumm floodfill_he.cpp,NONE,2.1 floodfill_he.h,NONE,2.1 intern.h,2.531,2.532 module.mk,1.56,1.57 saveload.cpp,1.241,1.242 script_v90he.cpp,2.282,2.283

Gregory Montoir cyx at users.sourceforge.net
Tue Oct 18 12:18:21 CEST 2005


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

Modified Files:
	intern.h module.mk saveload.cpp script_v90he.cpp 
Added Files:
	floodfill_he.cpp floodfill_he.h 
Log Message:
Added flood fill support. Pajama2 puzzle seems to be ok now

--- NEW FILE: floodfill_he.cpp ---
/* ScummVM - Scumm Interpreter
 * Copyright (C) 2001  Ludvig Strigeus
 * Copyright (C) 2001-2005 The ScummVM project
 *
 * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * $Header: /cvsroot/scummvm/scummvm/scumm/floodfill_he.cpp,v 2.1 2005/10/18 19:17:20 cyx Exp $
 *
 */

#include "common/stdafx.h"

#include "scumm/intern.h"
#include "scumm/scumm.h"
#include "scumm/floodfill_he.h"

namespace Scumm {
	
static bool floodFillPixelCheck(int x, int y, const FloodFillState *ffs) {
	int diffColor = ffs->color1 - ffs->color2;
	if (x >= 0 && x < ffs->dst_w && y >= 0 && y < ffs->dst_h) {
		uint8 color = *(ffs->dst + y * ffs->dst_w + x);
		diffColor = color - ffs->color1;
	}
	return diffColor == 0;
}

static void floodFillProcessRect(FloodFillState *ffs, const Common::Rect *r) {
	Common::Rect *dr = &ffs->dstBox;
	if (dr->right >= dr->left && dr->top <= dr->bottom) {
		int rw = r->right - r->left + 1;
		int rh = r->bottom - r->top + 1;
		assert(r->top + rh <= ffs->dst_h);
		assert(r->left + rw <= ffs->dst_w);
		uint8 *dst = ffs->dst + r->top * ffs->dst_w + r->left;
		if (rw <= 1) {
			--rh;
			while (rh >= 0) {
				*dst = ffs->color2;
				dst += ffs->dst_w;
				--rh;
			}
		} else {
			--rh;
			while (rh >= 0) {
				memset(dst, ffs->color2, rw);
				dst += ffs->dst_w;
				--rh;
			}
		}
		dr->extend(*r);
	} else {
		*dr = *r;
	}
}

static void floodFillAddLine(FloodFillLine **ffl, int y, int x1, int x2, int dy) {
	(*ffl)->y = y;
	(*ffl)->x1 = x1;
	(*ffl)->x2 = x2;
	(*ffl)->inc = dy;
	(*ffl)++;
}

static void floodFillProcess(int x, int y, FloodFillState *ffs, FloodFillPixelCheckCallback pixelCheckCallback) {
	ffs->dstBox.left = ffs->dstBox.top = 12345;
	ffs->dstBox.right = ffs->dstBox.bottom = -12345;
	
	FloodFillLine **fillLineCur = &ffs->fillLineTableCur;
	FloodFillLine **fillLineEnd = &ffs->fillLineTableEnd;
	
	assert(*fillLineCur < *fillLineEnd);
	if (ffs->srcBox.top <= y + 1 && ffs->srcBox.bottom >= y + 1) {
		(*fillLineCur)->y = y;
		(*fillLineCur)->x1 = x;
		(*fillLineCur)->x2 = x;
		(*fillLineCur)->inc = 1;
		(*fillLineCur)++;
	}
	
	assert(*fillLineCur < *fillLineEnd);
	if (ffs->srcBox.top <= y && ffs->srcBox.bottom >= y) {
		(*fillLineCur)->y = y + 1;
		(*fillLineCur)->x1 = x;
		(*fillLineCur)->x2 = x;
		(*fillLineCur)->inc = -1;
		(*fillLineCur)++;
	}

	assert(ffs->fillLineTable <= *fillLineCur);
	FloodFillLine **fillLineStart = fillLineCur;
	
	while (ffs->fillLineTable < *fillLineStart) {
		Common::Rect r;
		int x_start;
		FloodFillLine *fflCur = --(*fillLineCur);
  		int dy = fflCur->inc;
  		int x_end = fflCur->x2;
  		int x1 = fflCur->x1;
  		int x2 = fflCur->x1 + 1;
		r.bottom = r.top = y = fflCur->y + fflCur->inc;
  		r.left = x2;
  		r.right = x1;
  		x = x1;
  		while (ffs->srcBox.left <= x) {
			if (!(*pixelCheckCallback)(x, y, ffs)) {
				break;
			}
			r.left = x;
			--x;
		}
		if (r.right >= r.left && r.top <= r.bottom) {
			floodFillProcessRect(ffs, &r);
		}
		if (x >= x1) goto skip;
		x_start = x + 1;
		if (x1 > x_start) {
			assert(*fillLineEnd > *fillLineCur);
			if (ffs->srcBox.top <= y - dy && ffs->srcBox.bottom >= y - dy) {
				--x1;
				floodFillAddLine(fillLineCur, y, x_start, x1, -dy);
			}
		}
		x = x2;
		while (x_start <= x_end) {
			r.left = x;
			r.top = y;
			r.right = x - 1;
			r.bottom = y;
			while (ffs->srcBox.right >= x) {
				if (!(*pixelCheckCallback)(x, y, ffs)) {
					break;
				}
				r.right = x;
				++x;
			}
			if (r.right >= r.left && r.top <= r.bottom) {
				floodFillProcessRect(ffs, &r);
			}
			assert(ffs->fillLineTableCur < ffs->fillLineTableEnd);
			if (ffs->srcBox.top <= y + dy && ffs->srcBox.bottom >= y + dy) {
				floodFillAddLine(&ffs->fillLineTableCur, y, x_start, x - 1, dy);
			}
			x_start = x_end + 1;
			if (x > x_start) {
				assert(ffs->fillLineTableCur < ffs->fillLineTableEnd);
				if (ffs->srcBox.top <= y - dy && ffs->srcBox.bottom >= y - dy) {
					floodFillAddLine(&ffs->fillLineTableCur, y, x_start, x - 1, -dy);
				}
			}
skip:
			++x;
			while (x <= x_end) {
				if ((*pixelCheckCallback)(x, y, ffs)) {
					break;
				}
				++x;
			}
			x_start = x;
		}
	}
}

void floodFill(FloodFillParameters *ffp, ScummEngine_v90he *vm) {
	uint8 *dst;
	VirtScreen *vs = &vm->virtscr[kMainVirtScreen];
	if (ffp->flags & 0x8000) {
		dst = vs->getBackPixels(0, vs->topline);
	} else {
		dst = vs->getPixels(0, vs->topline);
	}
	uint8 color = ffp->flags & 0xFF;

	Common::Rect r;
	r.left = r.top = 12345;
	r.right = r.bottom = -12345;
	
	FloodFillState *ffs = new FloodFillState;
	ffs->fillLineTableCount = vs->h * 2;
	ffs->fillLineTable = new FloodFillLine[ffs->fillLineTableCount];
	ffs->color2 = color;
	ffs->dst = dst;
	ffs->dst_w = vs->w;
	ffs->dst_h = vs->h;
	ffs->srcBox = ffp->box;
	ffs->fillLineTableCur = &ffs->fillLineTable[0];
	ffs->fillLineTableEnd = &ffs->fillLineTable[ffs->fillLineTableCount];
	
	if (ffp->x < 0 || ffp->y < 0 || ffp->x >= vs->w || ffp->y >= vs->h) {
		ffs->color1 = color;
	} else {
		ffs->color1 = *(dst + ffp->y * vs->w + ffp->x);
	}
	
	debug(5, "floodFill() x=%d y=%d color1=%d ffp->flags=0x%X", ffp->x, ffp->y, ffs->color1, ffp->flags);
	if (ffs->color1 != color) {
		floodFillProcess(ffp->x, ffp->y, ffs, floodFillPixelCheck);
		r = ffs->dstBox;
	}
	r.debugPrint(5, "floodFill() dirty_rect");
	
	delete[] ffs->fillLineTable;
	delete ffs;
	
	vm->VAR(119) = 1;
	
	if (r.left <= r.right && r.top <= r.bottom) {
		if (ffp->flags & 0x8000) {
			vm->gdi.copyVirtScreenBuffers(r);
		} else {
			++r.bottom;
			vm->markRectAsDirty(kMainVirtScreen, r);
		}
	}
}

} // End of namespace Scumm

--- NEW FILE: floodfill_he.h ---
/* ScummVM - Scumm Interpreter
 * Copyright (C) 2001  Ludvig Strigeus
 * Copyright (C) 2001-2005 The ScummVM project
 *
 * 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.
 *
 * $Header: /cvsroot/scummvm/scummvm/scumm/floodfill_he.h,v 2.1 2005/10/18 19:17:20 cyx Exp $
 *
 */

#if !defined(FLOODFILL_HE_H) && !defined(DISABLE_HE)
#define FLOODFILL_HE_H

#include "common/rect.h"

namespace Scumm {

struct FloodFillParameters {
	Common::Rect box;
	int32 x;
	int32 y;
	int32 flags;
	int32 unk1C; /* unused */
};

struct FloodFillLine {
	int y;
	int x1;
	int x2;
	int inc;
};

struct FloodFillState {
	FloodFillLine *fillLineTable;
	FloodFillLine *fillLineTableEnd;
	FloodFillLine *fillLineTableCur;
	Common::Rect dstBox;
	Common::Rect srcBox;
	uint8 *dst;
	int dst_w;
	int dst_h;
	int color1;
	int color2;
	int fillLineTableCount;
};

class ScummEngine_v90he;

typedef bool (*FloodFillPixelCheckCallback)(int x, int y, const FloodFillState *ffs);

void floodFill(FloodFillParameters *ffp, ScummEngine_v90he *vm);

} // End of namespace Scumm

#endif

Index: intern.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/intern.h,v
retrieving revision 2.531
retrieving revision 2.532
diff -u -d -r2.531 -r2.532
--- intern.h	18 Oct 2005 01:30:20 -0000	2.531
+++ intern.h	18 Oct 2005 19:17:20 -0000	2.532
@@ -24,6 +24,7 @@
 #define INTERN_H
 
 #include "scumm/scumm.h"
+#include "scumm/floodfill_he.h"
 #include "scumm/sprite_he.h"
 #include "scumm/wiz_he.h"
 
@@ -1121,15 +1122,7 @@
 
 	const OpcodeEntryV90he *_opcodesV90he;
 
-	struct FloodStateParameters {
-		Common::Rect box;
-		int32 field_10;
-		int32 field_14;
-		int32 field_18;
-		int32 field_1C;
-	};
-
-	FloodStateParameters _floodStateParams;
+	FloodFillParameters _floodFillParams;
 
 	struct VideoParameters {
 		byte filename[260];
@@ -1218,7 +1211,7 @@
 	void o90_getSpriteGroupInfo();
 	void o90_setSpriteGroupInfo();
 	void o90_getWizData();
-	void o90_floodState();
+	void o90_floodFill();
 	void o90_mod();
 	void o90_shl();
 	void o90_shr();

Index: module.mk
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/module.mk,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -d -r1.56 -r1.57
--- module.mk	18 Jun 2005 15:44:40 -0000	1.56
+++ module.mk	18 Oct 2005 19:17:21 -0000	1.57
@@ -79,6 +79,7 @@
 
 ifndef DISABLE_HE
 MODULE_OBJS += \
+	scumm/floodfill_he.o \
 	scumm/logic_he.o \
 	scumm/palette_he.o \
 	scumm/resource_v7he.o \

Index: saveload.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/saveload.cpp,v
retrieving revision 1.241
retrieving revision 1.242
diff -u -d -r1.241 -r1.242
--- saveload.cpp	18 Oct 2005 01:30:21 -0000	1.241
+++ saveload.cpp	18 Oct 2005 19:17:21 -0000	1.242
@@ -37,7 +37,6 @@
 #include "scumm/scumm.h"
 #include "scumm/sound.h"
 #include "scumm/verbs.h"
-#include "scumm/wiz_he.h"
 
 #include "sound/audiocd.h"
 #include "sound/mixer.h"
@@ -1237,15 +1236,15 @@
 void ScummEngine_v90he::saveOrLoad(Serializer *s, uint32 savegameVersion) {
 	ScummEngine_v70he::saveOrLoad(s, savegameVersion);
 
-	const SaveLoadEntry floodStateEntries[] = {
-		MKLINE(FloodStateParameters, box.left, sleInt32, VER(51)),
-		MKLINE(FloodStateParameters, box.top, sleInt32, VER(51)),
-		MKLINE(FloodStateParameters, box.right, sleInt32, VER(51)),
-		MKLINE(FloodStateParameters, box.bottom, sleInt32, VER(51)),
-		MKLINE(FloodStateParameters, field_10, sleInt32, VER(51)),
-		MKLINE(FloodStateParameters, field_14, sleInt32, VER(51)),
-		MKLINE(FloodStateParameters, field_18, sleInt32, VER(51)),
-		MKLINE(FloodStateParameters, field_1C, sleInt32, VER(51)),
+	const SaveLoadEntry floodFillEntries[] = {
+		MKLINE(FloodFillParameters, box.left, sleInt32, VER(51)),
+		MKLINE(FloodFillParameters, box.top, sleInt32, VER(51)),
+		MKLINE(FloodFillParameters, box.right, sleInt32, VER(51)),
+		MKLINE(FloodFillParameters, box.bottom, sleInt32, VER(51)),
+		MKLINE(FloodFillParameters, x, sleInt32, VER(51)),
+		MKLINE(FloodFillParameters, y, sleInt32, VER(51)),
+		MKLINE(FloodFillParameters, flags, sleInt32, VER(51)),
+		MKLINE(FloodFillParameters, unk1C, sleInt32, VER(51)),
 		MKEND()
 	};
 
@@ -1262,7 +1261,7 @@
 
 	_sprite->saveOrLoadSpriteData(s, savegameVersion);
 
-	s->saveLoadArrayOf(&_floodStateParams, 1, sizeof(_floodStateParams), floodStateEntries);
+	s->saveLoadArrayOf(&_floodFillParams, 1, sizeof(_floodFillParams), floodFillEntries);
 
 	_numSpritesToProcess = _sprite->_numSpritesToProcess;
 	s->saveLoadEntries(this, HE90Entries);

Index: script_v90he.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/script_v90he.cpp,v
retrieving revision 2.282
retrieving revision 2.283
diff -u -d -r2.282 -r2.283
--- script_v90he.cpp	18 Oct 2005 01:30:21 -0000	2.282
+++ script_v90he.cpp	18 Oct 2005 19:17:21 -0000	2.283
@@ -98,7 +98,7 @@
 		OPCODE(o90_jumpToScriptUnk),
 		OPCODE(o90_videoOps),
 		OPCODE(o90_getVideoData),
-		OPCODE(o90_floodState),
+		OPCODE(o90_floodFill),
 		/* 30 */
 		OPCODE(o90_mod),
 		OPCODE(o90_shl),
@@ -1760,41 +1760,40 @@
 	}
 }
 
-void ScummEngine_v90he::o90_floodState() {
+void ScummEngine_v90he::o90_floodFill() {
 	byte subOp = fetchScriptByte();
 	subOp -= 54;
 
 	switch (subOp) {
 	case 0:
-		_floodStateParams.field_1C = pop();
+		_floodFillParams.unk1C = pop();
 		break;
 	case 3:
-		memset(&_floodStateParams, 0, sizeof(_floodStateParams));
-		_floodStateParams.box.left = 0;
-		_floodStateParams.box.top = 0;
-		_floodStateParams.box.right = 640;
-		_floodStateParams.box.bottom = 480;
+		memset(&_floodFillParams, 0, sizeof(_floodFillParams));
+		_floodFillParams.box.left = 0;
+		_floodFillParams.box.top = 0;
+		_floodFillParams.box.right = 639;
+		_floodFillParams.box.bottom = 479;
 		break;
 	case 11:
-		_floodStateParams.field_14 = pop();
-		_floodStateParams.field_10 = pop();
+		_floodFillParams.y = pop();
+		_floodFillParams.x = pop();
 		break;
 	case 12:
-		_floodStateParams.field_18 = pop();
+		_floodFillParams.flags = pop();
 		break;
 	case 13:
-		_floodStateParams.box.bottom = pop();
-		_floodStateParams.box.right = pop();
-		_floodStateParams.box.top = pop();
-		_floodStateParams.box.left = pop();
+		_floodFillParams.box.bottom = pop();
+		_floodFillParams.box.right = pop();
+		_floodFillParams.box.top = pop();
+		_floodFillParams.box.left = pop();
 		break;
 	case 201:
-		//floodState(_floodStateParams);
+		floodFill(&_floodFillParams, this);
 		break;
 	default:
-		error("o90_floodState: Unknown case %d", subOp);
+		error("o90_floodFill: Unknown case %d", subOp);
 	}
-	debug(1, "o90_floodState stub (%d)", subOp);
 }
 
 void ScummEngine_v90he::o90_shl() {





More information about the Scummvm-git-logs mailing list