[Scummvm-cvs-logs] CVS: scummvm/queen walk.cpp,NONE,1.1 walk.h,NONE,1.1 cutaway.cpp,1.11,1.12 graphics.cpp,1.11,1.12 graphics.h,1.10,1.11 logic.cpp,1.24,1.25 logic.h,1.14,1.15 resource.h,1.8,1.9 structs.h,1.3,1.4 module.mk,1.8,1.9

Gregory Montoir cyx at users.sourceforge.net
Thu Oct 9 02:11:01 CEST 2003


Update of /cvsroot/scummvm/scummvm/queen
In directory sc8-pr-cvs1:/tmp/cvs-serv3496

Modified Files:
	cutaway.cpp graphics.cpp graphics.h logic.cpp logic.h 
	resource.h structs.h module.mk 
Added Files:
	walk.cpp walk.h 
Log Message:
added walking functions

--- NEW FILE: walk.cpp ---
/* ScummVM - Scumm Interpreter
 * Copyright (C) 2003 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/queen/walk.cpp,v 1.1 2003/10/09 09:09:40 cyx Exp $
 *
 */

#include "queen/walk.h"
#include "queen/logic.h"
#include "queen/graphics.h"
#include "queen/defs.h"

namespace Queen {


Walk::Walk(Logic *logic, Graphics *graphics)
	: _logic(logic), _graphics(graphics) {
}


uint16 Walk::joeFace(uint16 prevFacing, uint16 scale) {
	BobSlot *pbs = _graphics->bob(0);
	uint16 frame;
	if (_logic->currentRoom() == 108) {
		frame = 1;
	}
	else {
		frame = 33;
		if (_logic->joeFacing() == DIR_FRONT) {
			frame = 34;
		}
		if (_logic->joeFacing() == DIR_BACK) {
			frame = 35;
		}
		// FIXME: handle prevFacing
		pbs->frameNum = frame + FRAMES_JOE_XTRA;
		pbs->scale = scale;
		pbs->xflip = (_logic->joeFacing() == DIR_LEFT);
		_graphics->update();
		// joePrevFacing = joeFacing;
		switch (frame) {
		case 33: frame = 1; break;
		case 34: frame = 3; break;
		case 35: frame = 5; break;
		}
	}
	pbs->frameNum = 29 + FRAMES_JOE_XTRA;
	_graphics->bankUnpack(frame, pbs->frameNum, 7);
	return frame;
}


void Walk::joeMoveBlock() {
	warning("Walk::moveJoeBlock() unimplemented");
}


void Walk::animatePersonPrepare() {
	// queen.c l.2748-2788
	int i;
	for (i = 1; i <= _walkDataCount; ++i) {

		MovePersonAnim *mpa = &_moveAnim[i];
		WalkData *pwd = &_walkData[i];
		mpa->wx = pwd->dx;
		mpa->wy = pwd->dy;
		mpa->walkingArea = &_roomAreas[ pwd->area ];

		if (mpa->wx < 0) {
			mpa->setFrames(11, 16 + FRAMES_JOE_XTRA, DIR_LEFT);
		}
		else {
			mpa->setFrames(11, 16 + FRAMES_JOE_XTRA, DIR_RIGHT);
		}

		int16 k = ABS(mpa->wy);
		int16 ds = mpa->walkingArea->scaleDiff();
		if (ds > 0) {
			k *= ((k * ds) / mpa->walkingArea->box.yDiff()) / 2;
		}

		if (ABS(mpa->wx) < k) {
			if ((mpa->wy < 0 && ds < 0) || (mpa->wy > 0 && ds > 0)) {
				mpa->setFrames(17 + FRAMES_JOE_XTRA, 22 + FRAMES_JOE_XTRA, DIR_FRONT);
			}
			else {
				mpa->setFrames(23 + FRAMES_JOE_XTRA, 28 + FRAMES_JOE_XTRA, DIR_BACK);
			}
		}	
	}
}


void Walk::animatePerson() {
	// queen.c l.2789-2835
	uint16 lastDirection = 0;
	uint16 i;
	BobSlot *pbs = _graphics->bob(0);
	_logic->joeFacing(_moveAnim[1].facing);
	joeFace(_logic->joeFacing(), _moveAnim[1].walkingArea->calcScale(pbs->y));
	bool interrupted = false;
	for (i = 1; i <= _walkDataCount && !interrupted; ++i) {
		MovePersonAnim *mpa = &_moveAnim[i];
		if (mpa->walkingArea->mapNeighbours < 0) {
			joeMoveBlock();
			return;
		}
		if (lastDirection != mpa->facing) {
			_graphics->bobAnimNormal(0, mpa->firstFrame, mpa->lastFrame, 1, false, false);
		}
		uint16 scale = _logic->findScale(pbs->x, pbs->y);
		_graphics->bobMove(0, pbs->x + mpa->wx, pbs->y + mpa->wy, scale * 6 / 100);
		pbs->xflip = (pbs->xdir < 0);
		while (pbs->moving) {
			// adjust Joe's movespeed according to scale
			pbs->scale = mpa->walkingArea->calcScale(pbs->y);
			if (pbs->xmajor) {
				pbs->speed = pbs->scale * 6 / 100;
			}
			else {
				pbs->speed = pbs->scale * 3 / 100;
			}
			if (pbs->speed == 0) {
				pbs->speed = 1;
			}
			_graphics->update(); // CHECK_PLAYER();
			if (_logic->joeWalk() == 2) { // || cutQuit 
				// we are about to do something else, so stop walking
				interrupted = true;
				pbs->moving = false;
			}
		}
		lastDirection = mpa->facing;
	}
//	if (!cutQuit) {
	pbs->animating = false;
	_logic->joeFacing(lastDirection);
//	}
}


void Walk::joeSetup() {
	int i;

	_graphics->bankLoad("joe_a.BBK", 13);
	for (i = 11; i <= 28 + FRAMES_JOE_XTRA; ++i) {
		_graphics->bankUnpack(i - 10, i, 13);
	}
	_graphics->bankErase(13);

	_graphics->bankLoad("joe_b.BBK", 7);
	_graphics->bankUnpack(1, 33 + FRAMES_JOE_XTRA, 7);
	_graphics->bankUnpack(3, 34 + FRAMES_JOE_XTRA, 7);
	_graphics->bankUnpack(5, 35 + FRAMES_JOE_XTRA, 7);

	_logic->joeFacing(DIR_FRONT);
}

void Walk::joeMove(int direction, uint16 oldx, uint16 oldy, uint16 newx, uint16 newy, bool inCutaway) {


//   CAN=0
	initWalkData();

	_logic->joeWalk(1);

	uint16 oldPos = _logic->zoneInArea(ZONE_ROOM, oldx, oldy);
	uint16 newPos = _logic->zoneInArea(ZONE_ROOM, newx, newy);

	debug(9, "Walk::joeMove(%d, %d, %d, %d, %d), old = %d, new = %d", direction, oldx, oldy, newx, newy, oldPos, newPos);

	// if in cutaway, allow Joe to walk anywhere
	if(newPos == 0 && inCutaway) {
		incWalkData(oldx, oldy, newx, newy, oldPos);
	}
	else {
		calc(oldPos, newPos, oldx, oldy, newx, newy);
	}

	if (_walkDataCount > 0) {
//MOVE_JOE2:
		animatePersonPrepare();
		animatePerson();
	}
	else {
//		SPEAK(JOE_RESPstr[4],"JOE",find_cd_desc(4))
	}
//MOVE_JOE_EXIT:
}


void Walk::setCurrentRoomAreas(const Area* roomAreas, uint16 roomAreasCount) {

	_roomAreas = roomAreas;
	_roomAreasCount = roomAreasCount;
}


void Walk::calc(uint16 oldPos, uint16 newPos, uint16 oldx, uint16 oldy, uint16 x, uint16 y) {
	
	// if newPos is outside of an AREA then travers Y axis until an AREA is found
	if (newPos == 0) { 
		newPos = findAreaPosition(&x, &y, true);
	}
	
	// do the same for oldPos in case Joe somehow sits on the border of an AREA
	// and does not register
	if (oldPos == 0) {
		oldPos = findAreaPosition(&oldx, &oldy, false);
	}

	if (oldPos == newPos) {
		incWalkData(oldx, oldy, x, y, newPos);
	}
	else if (calcPath(oldPos, newPos)) {
		uint16 i;
		uint16 px = oldx;
		uint16 py = oldy;
		for (i = 2; i <= _areaListCount; ++i) {
			uint16 a1 = _areaList[i - 1];
			uint16 a2 = _areaList[i];
			const Area *pa1 = &_roomAreas[ a1 ];
			const Area *pa2 = &_roomAreas[ a2 ];
			uint16 x1 = calcC(pa1->box.x1, pa1->box.x2, pa2->box.x1, pa2->box.x2, px);
			uint16 y1 = calcC(pa1->box.y1, pa1->box.y2, pa2->box.y1, pa2->box.y2, py);
			incWalkData(px, py, x1, y1, a1);
			px = x1;
			py = y1;
		}
		incWalkData(px, py, x, y, newPos);
	}
}


uint16 Walk::calcC(uint16 c1, uint16 c2, uint16 c3, uint16 c4, uint16 lastc) {
	uint16 s1 = MAX(c1, c3);
	uint16 s2 = MIN(c2, c4);
	uint16 c = (s1 + s2) / 2;
	if ((lastc >= s1 && lastc <= s2) || (lastc >= s2 && lastc <= s1)) {
		c = lastc;
	}
	return c;
}


int16 Walk::findAreaPosition(uint16 *x, uint16 *y, bool recalibrate) {
	uint16 i;
	uint16 pos = 1;
	const Box *b = &_roomAreas[1].box;
	uint16 tx = b->x1;
	uint16 bx = b->x2;
	uint16 ty = b->y1;
	uint16 by = b->y2;
	uint16 prevClosestFace = 640;
	for (i = 1; i <= _roomAreasCount; ++i) {
		b = &_roomAreas[i].box;
		uint16 dx1 = ABS(b->x1 - *x);
		uint16 dx2 = ABS(b->x2 - *x);
		uint16 dy1 = ABS(b->y1 - *y);
		uint16 dy2 = ABS(b->y2 - *y);
		uint16 csx = MIN(dx1, dx2);
		uint16 csy = MIN(dy1, dy2);
		uint16 curClosestFace = 640;
		// check to see if X lies in X range		
		if (*x >= b->x1 && *x <= b->x2) {
			// it is, so record closest Y face distance
			curClosestFace = csy;
		}
		else if (*y >= b->y1 && *y <= b->y2) {
			// record, closest X face distance
			curClosestFace = csx;		
		}
		if (curClosestFace < prevClosestFace) {
			tx = dx1;
			ty = dy1;
			bx = dx2;
			by = dy2;
			pos = i;
			prevClosestFace = curClosestFace;
		}
	}
 	// we now have the closest area near X,Y, so we can recalibrate
 	// the X,Y coord to be in this area
	if (recalibrate) {
		b = &_roomAreas[pos].box;
		if(*x < b->x1) *x = b->x1;
		if(*x > b->x2) *x = b->x2;
		if(*y < b->y1) *y = b->y1;
		if(*y > b->y2) *y = b->y2;
	}
	return pos;
}


uint16 Walk::findFreeArea(uint16 area) const {

	uint16 testArea;
	uint16 freeArea = 0;
	uint16 map = ABS(_roomAreas[area].mapNeighbours);
	for (testArea = 1; testArea <= _roomAreasCount; ++testArea) {
		int b = _roomAreasCount - testArea;
		if (map & (1 << b)) {
			// connecting area, check if it's been struck off
			if(!isAreaStruck(testArea)) {
				// legitimate connecting area, keep it
				freeArea = testArea;
				break;
			}
		}
	}
	return freeArea;
}


bool Walk::isAreaStruck(uint16 area) const {

	uint16 i;
	bool found = false;
	for (i = 1; i <= _areaStrikeCount; ++i) {
		if (_areaStrike[i] == area) {
			found = true;
			break;
		}
	}
	return found;
}


bool Walk::calcPath(uint16 oldArea, uint16 newArea) {

	debug(9, "Walk::calcPath(%d, %d)", oldArea, newArea);
	_areaList[1] = _areaStrike[1] = oldArea;
	_areaListCount = _areaStrikeCount = 1;	
	uint16 area = oldArea;
	while (_areaListCount > 0 && area != newArea) {
		area = findFreeArea(area);
		if (!area) {
			// wrong path, rolling back
			_areaList[_areaListCount] = 0;
			--_areaListCount;
			area = _areaList[_areaListCount];	
		}
		else {
			++_areaListCount;
			_areaList[_areaListCount] = area;
			if(!isAreaStruck(area)) {
				++_areaStrikeCount;
				_areaStrike[_areaStrikeCount] = area;
			}
		}		
	}
	// CAN = -1 if no connection is made, else 0
	return _areaList[1] != 0;
}


void Walk::initWalkData() {
	_walkDataCount = 0;
	memset(_walkData, 0, sizeof(_walkData));
	_areaStrikeCount = 0;
	memset(_areaStrike, 0, sizeof(_areaStrike));
	_areaListCount = 0;
	memset(_areaList, 0, sizeof(_areaList));
}


void Walk::incWalkData(uint16 px, uint16 py, uint16 x, uint16 y, uint16 area) {

	debug(9, "Walk::incWalkData(%d, %d, %d)", (int16)(x - px), (int16)(y - py), area);

	if (px != x || py != y) {
		++_walkDataCount;
		WalkData *pwd = &_walkData[_walkDataCount];
		pwd->dx = x - px;
		pwd->dy = y - py;
		pwd->area = area;
//		pwd->sign = ((pwd->dx < 0) ? -1 : ((pwd->dx > 0) ? 1 : 0)) ;
	}
}


} // End of namespace Queen

--- NEW FILE: walk.h ---
/* ScummVM - Scumm Interpreter
 * Copyright (C) 2003 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/queen/walk.h,v 1.1 2003/10/09 09:09:40 cyx Exp $
 *
 */

#ifndef QUEENWALK_H
#define QUEENWALK_H

#include "queen/queen.h"
#include "queen/structs.h"

namespace Queen {


#define MAX_AREAS 11


struct WalkData {
//	int16 sign; // never used
	int16 dx, dy;
	int16 area;
};

struct MovePersonAnim {
	int16 wx;
	int16 wy;
	uint16 firstFrame;
	uint16 lastFrame;
	uint16 facing;
	const Area *walkingArea;

	void setFrames(uint16 ff, uint16 lf, uint16 face) {
		firstFrame = ff;
		lastFrame = lf;
		facing = face;
	}
};


class Logic;
class Graphics;

class Walk {
public:

	Walk(Logic* logic, Graphics* graphics);

	void joeSetup();

	void setCurrentRoomAreas(const Area* roomAreas, uint16 roomAreasCount);
	
	//! MOVE_JOE()
	void joeMove(int dir, uint16 oldx, uint16 oldy, uint16 newx, uint16 newy, bool inCutaway);
	
	//! FACE_JOE()
	uint16 joeFace(uint16 prevFacing, uint16 scale);


private:


	void joeMoveBlock();

	void animatePersonPrepare();

	void animatePerson();

	//! CALC_X, CALC_Y
	static uint16 calcC(uint16 c1, uint16 c2, uint16 c3, uint16 c4, uint16 lastc);
	
	//! FIND_OLDP, FIND_NEWP
	int16 findAreaPosition(uint16 *x, uint16 *y, bool recalibrate);

	//! FIND_FREE_AREA, find an area not already struck
	uint16 findFreeArea(uint16 area) const;

	//! 
	bool isAreaStruck(uint16 area) const;

	//! CALC_PATH, calculates the path list from oldArea to newArea
	bool calcPath(uint16 oldArea, uint16 newArea);
	
	//! resets path computed in calcPath()
	void initWalkData();
	
	//! CALC_WALK
	void incWalkData(uint16 px, uint16 py, uint16 x, uint16 y, uint16 area);
	
	//! equivalent to l.2432,2469 MOVE_OTHER() and l.2696,2744 MOVE_JOE()
    void calc(uint16 oldPos, uint16 newPos, uint16 oldx, uint16 oldy, uint16 x, uint16 y);


	MovePersonAnim _moveAnim[15];

	uint16 _walkDataCount;
	WalkData _walkData[16];	
	
	uint16 _roomAreasCount;
	const Area* _roomAreas;
	uint16 _areaStrikeCount;
	uint16 _areaStrike[MAX_AREAS + 1];
	uint16 _areaListCount;
	uint16 _areaList[MAX_AREAS + 1];

	Logic *_logic;
	Graphics *_graphics;

};


} // End of namespace Queen

#endif

Index: cutaway.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/queen/cutaway.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- cutaway.cpp	7 Oct 2003 12:20:31 -0000	1.11
+++ cutaway.cpp	9 Oct 2003 09:09:40 -0000	1.12
@@ -984,12 +984,12 @@
 				// Turn area on or off
 
 				if (areaSubIndex > 0) {
-					int16 *area = _logic->area(areaIndex, areaSubIndex);
-					area[0] = abs(area[0]);
+					Area *area = _logic->area(areaIndex, areaSubIndex);
+					area->mapNeighbours = abs(area->mapNeighbours);
 				}
 				else {
-					int16 *area = _logic->area(areaIndex, abs(areaSubIndex));
-					area[0] = -abs(area[0]);
+					Area *area = _logic->area(areaIndex, abs(areaSubIndex));
+					area->mapNeighbours = -abs(area->mapNeighbours);
 				}
 			}
 

Index: graphics.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/queen/graphics.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- graphics.cpp	7 Oct 2003 15:27:53 -0000	1.11
+++ graphics.cpp	9 Oct 2003 09:09:40 -0000	1.12
@@ -276,7 +276,10 @@
 	_shrinkBuffer.data = new uint8[ BOB_SHRINK_BUF_SIZE ];
 	_backdrop = new uint8[ BACKDROP_W * BACKDROP_H ];
 	_panel = new uint8[ PANEL_W * PANEL_H ];
-
+	_screen = new uint8[ SCREEN_W * SCREEN_H ];
+	_fullscreen = true;
+	_horizontalScroll = 0;
+	_palette = new uint8[ 256 * 4 ];
 }
 
 
@@ -285,10 +288,12 @@
 	for(i = 0; i < ARRAYSIZE(_banks); ++i) {
 		delete _banks[i].data;
 	}
-//	frameClearAll();
+	frameEraseAll(true);
 	delete[] _shrinkBuffer.data;
 	delete[] _backdrop;
 	delete[] _panel;
+	delete[] _screen;
+	delete[] _palette;
 }
 
 
@@ -369,6 +374,16 @@
 }
 
 
+void Graphics::bobSetupControl() {
+
+	bankLoad("control.BBK",17);
+	bankUnpack(1, 1, 17); // Mouse pointer
+    bankUnpack(3, 3, 17); // Up arrow dialogue
+    bankUnpack(4, 4, 17); // Down arrow dialogue
+    bankErase(17);
+}
+
+
 void Graphics::bobAnimString(uint32 bobnum, uint8* animBuf) {
 
 	BobSlot *pbs = &_bobs[bobnum];
@@ -400,6 +415,8 @@
 
 void Graphics::bobMove(uint32 bobnum, uint16 endx, uint16 endy, int16 speed) {
 
+	debug(5, "Graphics::bobMove(%d, %d, %d, %d)", bobnum, endx, endy, speed);
+
 	BobSlot *pbs = &_bobs[bobnum];
 
 	pbs->active = true;
@@ -408,7 +425,6 @@
 	pbs->endx = endx;
 	pbs->endy = endy;
 
-	// FIXME: can speed be negative or =0 ? the original sources does the check
 	pbs->speed = (speed < 1) ? 1 : speed;
 
 	int16 dx = endx - pbs->x;
@@ -513,23 +529,23 @@
 					frameDir *= -1;
 				}
 				else {
-					frameNum = anim.normal.lastFrame - 1;
+					frameNum = anim.normal.firstFrame - 1;
 				}
-				frameNum += frameDir;
 			}
+			frameNum += frameDir;
 		}
 	}
 }
-            
+          
 
 void Graphics::bobDraw(uint32 bobnum, uint16 x, uint16 y, uint16 scale, bool xflip, const Box& box) {
 
 	uint16 w, h;
 
-	debug(5, "Preparing to draw frame %d, scale = %d", bobnum, scale);
+	debug(5, "Preparing to draw frame %d, scale = %d, coords = (%d,%d)", bobnum, scale, x, y);
 
 	BobFrame *pbf = &_frames[bobnum];
-	if (scale < 100) {  // Note: scale is unsigned, hence always >= 0
+	if (scale < 100) {
 		bobShrink(pbf, scale);
 		pbf = &_shrinkBuffer;
 	}
@@ -565,18 +581,15 @@
 			h_new = box.y2 - y + 1;
 		}
 
-//		_display->ulines(w_new / 16, h_new, 2);
-
-		// FIXME: original code blits to 'hidden' buffer
 		src += w * y_skip;
 		if (!xflip) {
 			src += x_skip;
-			displayBlit(_backdrop, x, y, BACKDROP_W, src, w_new, h_new, w, xflip, true);
+			displayBlit(_screen, x, y, SCREEN_W, src, w_new, h_new, w, xflip, true);
 		}
 		else {
 			src += w - w_new - x_skip;
 			x += w_new - 1;
-			displayBlit(_backdrop, x, y, BACKDROP_W, src, w_new, h_new, w, xflip, true);
+			displayBlit(_screen, x, y, SCREEN_W, src, w_new, h_new, w, xflip, true);
 		}
     }
 
@@ -836,8 +849,6 @@
 
 void Graphics::backdropLoad(const char* name, uint16 room) {
 
-//	_display->ulines(2);
-
 	// init Dynalum
 	char roomPrefix[20];
 	strcpy(roomPrefix, name);
@@ -849,14 +860,14 @@
 		error("Unable to load backdrop : '%s'", name);
 	}
 
-//	uint32 size = _resource->fileSize(name);
-//	_display->setPal(pcxbuf + size - 768, 0, (room <= 144) ? 144 : 256);
+	uint32 size = _resource->fileSize(name);
+	displaySetPal(pcxbuf + size - 768, 0, (room <= 144) ? 144 : 256);
 
 	_backdropWidth  = READ_LE_UINT16(pcxbuf +  12);
 	_backdropHeight = READ_LE_UINT16(pcxbuf +  14);
 
 	if (_backdropHeight == 150) {
-//		_display->_fullscreen = 0;
+		_fullscreen = false;
 	}
 
 	if (room >= 90) {
@@ -868,19 +879,43 @@
 }
 
 
+void Graphics::backdropDraw() {
+
+	int n = 3;
+	if (_fullscreen) {
+		n = 4;
+	}
+	uint8 *dst = _screen;
+	uint8 *src = _backdrop + _horizontalScroll;
+	while (n--) {
+		int i;
+		for (i = 0; i < 50; ++i) {
+			memcpy(dst, src, SCREEN_W);
+			dst += SCREEN_W;
+			src += BACKDROP_W;
+		}
+	}
+}
+
+
 void Graphics::panelLoad() {
 
 	uint8 *pcxbuf = _resource->loadFile("panel.pcx");
 	if (pcxbuf == NULL) {
 		error("Unable to open panel file");
 	}
-//	uint32 size = _resource->fileSize("panel.pcx");
-//	_display->setPal(pcxbuf + size - 768, 144, 256);
+	uint32 size = _resource->fileSize("panel.pcx");
+	displaySetPal(pcxbuf + size - 768, 144, 256);
 	readPCX(pcxbuf + 128, _panel + PANEL_W * 10, PANEL_W, PANEL_W, PANEL_H - 10);
 	delete[] pcxbuf;
 }
 
 
+void Graphics::panelDraw() {
+	memcpy(_screen + SCREEN_W * ROOM_ZONE_HEIGHT, _panel, PANEL_W * PANEL_H);
+}
+
+
 void Graphics::readPCX(const uint8 *src, uint8 *dst, uint16 dstPitch, uint16 w, uint16 h) {
 
 	while (h--) {
@@ -901,6 +936,21 @@
 }
 
 
+void Graphics::boxDraw(const Box &b, uint8 color) {
+
+	int x, y;
+
+	for (y = b.y1; y <= b.y2; ++y) {
+		*(_backdrop + y * 640 + b.x1) = color;
+		*(_backdrop + y * 640 + b.x2) = color;
+	}
+	for (x = b.x1; x <= b.x2; ++x) {
+		*(_backdrop + b.y1 * 640 + x) = color;
+		*(_backdrop + b.y2 * 640 + x) = color;
+	}
+}
+
+
 void Graphics::useJournal() { // GameSettings* pgs
 
 	int i;
@@ -959,20 +1009,19 @@
 }
 
 
-
 void Graphics::update() {
 	// FIXME: incomplete !
 	bobSortAll();
-//	panelDraw();
-//	backdropDraw();
+	panelDraw();
+	backdropDraw();
 	bobDrawAll();
 	textDrawAll();
+	displayScreen();
 }
 
 
 void Graphics::displayText(const TextSlot *pts, uint16 y) {
 
-	// FIXME: original source uses hidden buffer (instead of _backdrop)
 	uint16 x = pts->x;
 	uint8 *str = (uint8*)pts->text;
 	while (*str && x < GAME_SCREEN_WIDTH) {
@@ -980,18 +1029,17 @@
 //		if (_resource->_gameVersion->versionString[1] == 'F' && *str == 150) {
 //			chr = 251;
 //		}
-//		_display->ulines(2);
 		if (pts->outlined) {
-			displayChar(_backdrop, BACKDROP_W, x - 1, y - 1, INK_OUTLINED_TEXT, pchr);
-			displayChar(_backdrop, BACKDROP_W, x    , y - 1, INK_OUTLINED_TEXT, pchr);
-			displayChar(_backdrop, BACKDROP_W, x + 1, y - 1, INK_OUTLINED_TEXT, pchr);
-			displayChar(_backdrop, BACKDROP_W, x + 1, y    , INK_OUTLINED_TEXT, pchr);
-			displayChar(_backdrop, BACKDROP_W, x + 1, y + 1, INK_OUTLINED_TEXT, pchr);
-			displayChar(_backdrop, BACKDROP_W, x    , y + 1, INK_OUTLINED_TEXT, pchr);
-			displayChar(_backdrop, BACKDROP_W, x - 1, y + 1, INK_OUTLINED_TEXT, pchr);
-			displayChar(_backdrop, BACKDROP_W, x - 1, y    , INK_OUTLINED_TEXT, pchr);
+			displayChar(x - 1, y - 1, INK_OUTLINED_TEXT, pchr);
+			displayChar(x    , y - 1, INK_OUTLINED_TEXT, pchr);
+			displayChar(x + 1, y - 1, INK_OUTLINED_TEXT, pchr);
+			displayChar(x + 1, y    , INK_OUTLINED_TEXT, pchr);
+			displayChar(x + 1, y + 1, INK_OUTLINED_TEXT, pchr);
+			displayChar(x    , y + 1, INK_OUTLINED_TEXT, pchr);
+			displayChar(x - 1, y + 1, INK_OUTLINED_TEXT, pchr);
+			displayChar(x - 1, y    , INK_OUTLINED_TEXT, pchr);
 		}
-		displayChar(_backdrop, BACKDROP_W, x, y, pts->color, pchr);
+		displayChar(x, y, pts->color, pchr);
 
 		x += FONT_SIZES[ *str ];
 		++str;
@@ -999,10 +1047,10 @@
 }
 
 
-void Graphics::displayChar(uint8 *dst, uint16 dstPitch, uint16 x, uint16 y, uint8 color, const uint8 *chr) {
+void Graphics::displayChar(uint16 x, uint16 y, uint8 color, const uint8 *chr) {
 
 	int i, j;
-	dst += y * dstPitch + x;
+	uint8 *dst = _screen + y * SCREEN_W + x;
 	for (j = 0; j < 8; ++j) {
 		uint8* p = dst;
 		uint8 c = *chr++;
@@ -1015,7 +1063,7 @@
 				c <<= 1;
 			}
 		}
-		dst += dstPitch;
+		dst += SCREEN_W;
 	}
 }
 
@@ -1056,6 +1104,27 @@
 			dst_buf += dst_pitch;   
 		}
 	}
+}
+
+
+void Graphics::displaySetPal(uint8 *pal, int start, int end) {
+	int i;
+	pal += start * 3;
+	for (i = start; i < end; ++i, pal += 3) {
+		_palette[i << 2 | 0] = *(pal + 0);
+		_palette[i << 2 | 1] = *(pal + 1);
+		_palette[i << 2 | 2] = *(pal + 2);
+		_palette[i << 2 | 3] = 0;
+	}
+}
+
+
+void Graphics::displayScreen() {
+	// FIXME: temporary code ; cleanup/move to Display class.
+	OSystem *psys =	g_engine->_system;
+	psys->set_palette(_palette, 0, 256);
+	psys->copy_rect(_screen, SCREEN_W, 0, 0, SCREEN_W, SCREEN_H);
+	psys->update_screen();
 }
 
 

Index: graphics.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/queen/graphics.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- graphics.h	7 Oct 2003 14:05:56 -0000	1.10
+++ graphics.h	9 Oct 2003 09:09:40 -0000	1.11
@@ -114,6 +114,7 @@
 	void bankOverpack(uint32 srcframe, uint32 dstframe, uint32 bankslot); // overpackbank()
 	void bankErase(uint32 bankslot); // erase()
 
+	void bobSetupControl();
 	void bobAnimString(uint32 bobnum, uint8* animBuf); // stringanim()
 	void bobAnimNormal(uint32 bobnum, uint16 firstFrame, uint16 lastFrame, uint16 speed, bool rebound, bool xflip); // makeanim()
 	void bobMove(uint32 bobnum, uint16 endx, uint16 endy, int16 speed); // movebob()
@@ -136,28 +137,33 @@
 	void frameErase(uint32 fslot);
 	void frameEraseAll(bool joe); // freeframes, freeallframes
 
-	void backdropLoad(const char* name, uint16 room); // loadbackdrop
-//	void backdropDraw();
+	void backdropLoad(const char *name, uint16 room); // loadbackdrop
+	void backdropDraw();
 
 	void panelLoad(); // loadpanel
-//	void panelDraw();
+	void panelDraw();
+
+	void boxDraw(const Box &b, uint8 color);
 
 	void useJournal();
 	void journalBobSetup(uint32 bobnum, uint16 x, uint16 y, uint16 frame);
 	void journalBobPreDraw();
 
 	void update();
-
+ 
 	void displayText(const TextSlot *pts, uint16 y); // FIXME: move to Display class
-	void displayChar(uint8 *dst, uint16 dstPitch, uint16 x, uint16 y, uint8 color, const uint8 *chr); // FIXME: move to Display class
+	void displayChar(uint16 x, uint16 y, uint8 color, const uint8 *chr); // FIXME: move to Display class
 	static void displayBlit(uint8 *dst_buf, uint16 dst_x, uint16 dst_y, uint16 dst_pitch, const uint8 *src_buf, uint16 src_w, uint16 src_h, uint16 src_pitch, bool xflip, bool masked); // FIXME: move to Display class
-
+	void displaySetPal(uint8 *pal, int start, int end);
+	void displayScreen();
 
 private:
 
 	enum {
 		BACKDROP_W = 640,
 		BACKDROP_H = 200,
+		SCREEN_W = 320,
+		SCREEN_H = 200,
 		PANEL_W = 320,
 		PANEL_H = 50,
 		BOB_SHRINK_BUF_SIZE = 60000
@@ -194,6 +200,14 @@
 
 	 //! current room bitmap
 	uint8 *_backdrop;
+
+	uint8 *_screen;
+
+	bool _fullscreen;
+
+	uint16 _horizontalScroll;
+
+	uint8 *_palette;
 
 	//! panel storage area
 	uint8 *_panel;

Index: logic.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/queen/logic.cpp,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- logic.cpp	8 Oct 2003 08:55:07 -0000	1.24
+++ logic.cpp	9 Oct 2003 09:09:40 -0000	1.25
@@ -20,6 +20,7 @@
  */
 
 #include "queen/logic.h"
+#include "queen/defs.h"
 
 namespace Queen {
 
@@ -36,7 +37,7 @@
 }
 
 void Logic::initialise() {
-	int16 i, j, k;
+	int16 i, j;
 	uint8 *ptr = _jas;
 
 	//_display->loadFont();
@@ -144,7 +145,7 @@
 	
 	_objMax   = new int16[_numRooms + 1];
 	_areaMax  = new int16[_numRooms + 1];
-	_area     = new int16[_numRooms + 1][11][8];
+	_area     = new Area[_numRooms + 1][11];
 
 	for (i = 1; i <= _numRooms; i++) {
 		_objMax[i] = (int16)READ_BE_UINT16(ptr);
@@ -152,12 +153,17 @@
 		_areaMax[i] = (int16)READ_BE_UINT16(ptr);
 		ptr += 2;
 		
-		for (j = 1; j <= _areaMax[i]; j++)
-			for (k = 0; k < 8; k++) {
-				assert(j < 11);
-				_area[i][j][k] = READ_BE_UINT16(ptr);
-				ptr += 2;
-			}
+		for (j = 1; j <= _areaMax[i]; j++) {
+			assert(j < 11);
+			_area[i][j].mapNeighbours = READ_BE_UINT16(ptr); ptr += 2;
+			_area[i][j].box.x1 = READ_BE_UINT16(ptr); ptr += 2;
+			_area[i][j].box.y1 = READ_BE_UINT16(ptr); ptr += 2;
+			_area[i][j].box.x2 = READ_BE_UINT16(ptr); ptr += 2;
+			_area[i][j].box.y2 = READ_BE_UINT16(ptr); ptr += 2;
+			_area[i][j].bottomScaleFactor = READ_BE_UINT16(ptr); ptr += 2;
+			_area[i][j].topScaleFactor = READ_BE_UINT16(ptr); ptr += 2;
+			_area[i][j].object = READ_BE_UINT16(ptr); ptr += 2;
+		}
 	}
 
 	_objectBox = new Box[_numObjects + 1];
@@ -206,6 +212,8 @@
 
 	//Command List Data
 
+
+	memset(_zones, 0, sizeof(_zones));
 }
 
 uint16 Logic::currentRoom() {
@@ -232,8 +240,8 @@
 	return _objMax[room];
 }
 
-int16 *Logic::area(int index, int subIndex) {
-	return _area[index][subIndex];
+Area *Logic::area(int index, int subIndex) {
+	return &_area[index][subIndex];
 }
 
 uint16 Logic::walkOffCount() {
@@ -360,7 +368,7 @@
 			}
 		}
 		if(bobnum <= 3) {
-			framenum = 29 + FRAME_XTRA;
+			framenum = 29 + FRAMES_JOE_XTRA;
 		}
 	}
 	else {
@@ -414,7 +422,7 @@
 
 		// calculate only if there are person frames
 		if(idx > 0) {
-			framenum = 36 + _maxStaticFrame + _maxAnimatedFrameLen + idx + FRAME_XTRA;
+			framenum = 36 + _maxStaticFrame + _maxAnimatedFrameLen + idx + FRAMES_JOE_XTRA;
 		}
 	}
 	return framenum;
@@ -432,6 +440,10 @@
 	_joe.y = y;
 }
 
+void Logic::joeWalk(uint16 walk) {
+	_joe.walk = walk;
+}
+
 int16 Logic::gameState(int index) {
 	if (index >= 0 && index < GAME_STATE_COUNT)
 		return _gameState[index];
@@ -444,6 +456,100 @@
 		 _gameState[index] = newValue;
 	else
 		error("[QueenLogic::gameState] invalid index: %i", index);
+}
+
+
+void Logic::zoneSet(uint16 screen, uint16 zone, uint16 x1, uint16 y1, uint16 x2, uint16 y2) {
+
+	ZoneSlot *pzs = &_zones[screen][zone];
+	pzs->valid = true;
+	pzs->box.x1 = x1;
+	pzs->box.y1 = y1;
+	pzs->box.x2 = x2;
+	pzs->box.y2 = y2;
+}
+
+
+void Logic::zoneSet(uint16 screen, uint16 zone, const Box& box) {
+	
+	debug(9, "Logic::zoneSet(%d, %d, (%d,%d), (%d,%d))", screen, zone, box.x1, box.y1, box.x2, box.y2);
+
+	ZoneSlot *pzs = &_zones[screen][zone];
+	pzs->valid = true;
+	pzs->box = box;
+}
+
+
+uint16 Logic::zoneIn(uint16 screen, uint16 x, uint16 y) {
+
+	int i;
+	if (screen == ZONE_PANEL) {
+		y -= ROOM_ZONE_HEIGHT;
+	}
+	for(i = 1; i < MAX_ZONES_NUMBER; ++i) {
+		ZoneSlot *pzs = &_zones[screen][i];
+		if (pzs->valid && pzs->box.contains(x, y)) {
+			return i;
+		}
+	}
+	return 0;
+}
+
+
+uint16 Logic::zoneInArea(uint16 screen, uint16 x, uint16 y) {
+	uint16 zone = zoneIn(screen, x, y);
+	if (zone <= _objMax[_currentRoom]) {
+		zone = 0;
+	}
+	else {
+		zone -= _objMax[_currentRoom];
+	}
+	return zone;
+}
+
+
+void Logic::zoneClearAll(uint16 screen) {
+
+	int i;
+	for(i = 1; i < MAX_ZONES_NUMBER; ++i) {
+		_zones[screen][i].valid = false;
+	}
+}
+
+
+void Logic::zoneSetup() {
+
+	zoneClearAll(ZONE_ROOM);
+
+	int i;
+	int zoneNum;
+
+	// setup objects zones
+	uint16 maxObjRoom = _objMax[_currentRoom];
+	uint16 objRoomNum = _roomData[_currentRoom];
+	zoneNum = 1;
+	for (i = objRoomNum + 1; i <= objRoomNum + maxObjRoom; ++i) {
+		if (_objectData[i].name != 0) {
+			zoneSet(ZONE_ROOM, zoneNum, _objectBox[i]);
+		}
+		++zoneNum;
+	}
+
+	// setup room zones (areas)
+	uint16 maxAreaRoom = _areaMax[_currentRoom];
+	for (zoneNum = 1; zoneNum <= maxAreaRoom; ++zoneNum) {
+		zoneSet(ZONE_ROOM, maxObjRoom + zoneNum, _area[_currentRoom][zoneNum].box);
+	}
+}
+
+
+uint16 Logic::findScale(uint16 x, uint16 y) {
+	uint16 scale = 100;
+	uint16 areaNum = zoneInArea(ZONE_ROOM, x, y);
+	if(areaNum != 0) {
+		scale = _area[_currentRoom][areaNum].calcScale(y);
+	}
+	return scale;
 }
 
 

Index: logic.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/queen/logic.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- logic.h	7 Oct 2003 08:24:54 -0000	1.14
+++ logic.h	9 Oct 2003 09:09:40 -0000	1.15
@@ -27,17 +27,8 @@
 
 namespace Queen {
 
+#define MAX_ZONES_NUMBER 32
 
-enum {
-	FRAME_XTRA = 2
-};
-
-enum {
-	LEFT = 1,
-	RIGHT = 2,
-	FRONT = 3,
-	BACK = 4
-};
 
 enum Language {
 	ENGLISH  = 'E',
@@ -46,6 +37,14 @@
 	ITALIAN  = 'I'
 };
 
+struct ZoneSlot {
+	bool valid;
+	Box box;
+};
+
+
+class Graphics;
+
 class Logic {
 
 public:
@@ -63,23 +62,35 @@
 	uint16 findBob(uint16 obj); // FIXME: move that to QueenDisplay ?
 	uint16 findFrame(uint16 obj); // FIXME: move that to QueenDisplay ?
 
-	int16 *area(int index, int subIndex);
+	Area *area(int index, int subIndex);
 	uint16 walkOffCount();
 	WalkOffData *walkOffData(int index);
 
 	uint16 joeFacing()	{ return _joe.facing; }
 	uint16 joeX()		{ return _joe.x; }
 	uint16 joeY()		{ return _joe.y; }
+	uint16 joeWalk()    { return _joe.walk; }
 
 	void joeFacing(uint16 dir);
 	void joeX(uint16 x);
 	void joeY(uint16 y);
+	void joeWalk(uint16 walk);
 	
 	int16 gameState(int index);
 	void gameState(int index, int16 newValue);
 
 	Language language() { return ENGLISH; } // FIXME: get from queen.jas
 
+	void zoneSet(uint16 screen, uint16 zone, uint16 x1, uint16 y1, uint16 x2, uint16 y2);
+	void zoneSet(uint16 screen, uint16 zone, const Box& box);
+	uint16 zoneIn(uint16 screen, uint16 x, uint16 y);
+	uint16 zoneInArea(uint16 screen, uint16 x, uint16 y);
+	void zoneClearAll(uint16 screen);
+	void zoneSetup();
+
+	uint16 findScale(uint16 x, uint16 y);
+
+
 protected:
 	uint8 *_jas;
 	uint16 _numRooms;
@@ -106,8 +117,9 @@
 	ObjectData *_objectData;
 	ObjectDescription *_objectDescription;
 	uint16 (*_actorData)[12]; // FIXME: ActorData *_actorData;
-	int16 (*_area)[11][8]; // FIXME: Area *_area[11];
+	Area (*_area)[11];
 	WalkOffData *_walkOffData;
+	ZoneSlot _zones[2][MAX_ZONES_NUMBER];
 
 	enum {
 		GAME_STATE_COUNT = 211
@@ -116,6 +128,7 @@
 	struct {
 		uint16	x, y;
 		uint16	facing;
+		uint16  walk;
 	} _joe;
 	
 	int16 _gameState[GAME_STATE_COUNT];

Index: resource.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/queen/resource.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- resource.h	6 Oct 2003 23:04:00 -0000	1.8
+++ resource.h	9 Oct 2003 09:09:40 -0000	1.9
@@ -62,6 +62,7 @@
 	uint8 *loadFile(const char *filename, uint32 skipBytes = 0);
 	bool exists(const char *filename);
 	bool isDemo();
+	uint32 fileSize(const char *filename);
 
 protected:
 	File *_resourceFile;
@@ -73,7 +74,6 @@
 	static ResourceEntry _resourceTablePEM10[];
 
 	int32 resourceIndex(const char *filename);
-	uint32 fileSize(const char *filename);
 	uint32 fileOffset(const char *filename);
 	const char *JASVersion();
 	bool readTableFile();

Index: structs.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/queen/structs.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- structs.h	8 Oct 2003 08:55:05 -0000	1.3
+++ structs.h	9 Oct 2003 09:09:40 -0000	1.4
@@ -28,9 +28,21 @@
 struct Box {
 	uint16 x1, y1, x2, y2;
 
+	int16 xDiff() const {
+		return (int16)(x1 - x2);
+	}
+
+	int16 yDiff() const {
+		return (int16)(y1 - y2);
+	}
+
 	bool intersects(uint16 x, uint16 y, uint16 w, uint16 h) const {
 		return (x + w > x1) && (y + h > y1) && (x <= x2) && (y <= y2);
 	}
+
+	bool contains(uint16 x, uint16 y) const {
+		return (x >= x1) && (x <= x2) && (y >= y1) && (y <= y2);
+	}
 };
 
 
@@ -40,6 +52,20 @@
 	uint16 bottomScaleFactor;
 	uint16 topScaleFactor;
 	uint16 object;
+
+	uint16 calcScale(int16 y) const {
+		uint16 dy = box.y2 - box.y1;
+		uint16 ds = topScaleFactor - bottomScaleFactor;
+		uint16 scale = ((((y - box.y1) * 100) / dy) * ds) / 100 + bottomScaleFactor;
+		if (scale == 0) {
+			scale = 100;
+		}
+		return scale;
+	}
+
+	int16 scaleDiff() const {
+		return (int16)(topScaleFactor - bottomScaleFactor);
+	}
 };
 
 

Index: module.mk
===================================================================
RCS file: /cvsroot/scummvm/scummvm/queen/module.mk,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- module.mk	8 Oct 2003 21:27:57 -0000	1.8
+++ module.mk	9 Oct 2003 09:09:40 -0000	1.9
@@ -7,7 +7,8 @@
 	queen/queen.o \
 	queen/resource.o \
 	queen/restables.o \
-	queen/talk.o
+	queen/talk.o \
+	queen/walk.o
 
 MODULE_DIRS += \
 	queen





More information about the Scummvm-git-logs mailing list