[Scummvm-cvs-logs] SF.net SVN: scummvm:[55361] scummvm/trunk/engines/mohawk

fuzzie at users.sourceforge.net fuzzie at users.sourceforge.net
Thu Jan 20 22:34:19 CET 2011


Revision: 55361
          http://scummvm.svn.sourceforge.net/scummvm/?rev=55361&view=rev
Author:   fuzzie
Date:     2011-01-20 21:34:19 +0000 (Thu, 20 Jan 2011)

Log Message:
-----------
MOHAWK: Add shared view code.

The design/code here is still very much in flux, because it's still
unclear exactly how the code is used by some games.

Modified Paths:
--------------
    scummvm/trunk/engines/mohawk/module.mk

Added Paths:
-----------
    scummvm/trunk/engines/mohawk/view.cpp
    scummvm/trunk/engines/mohawk/view.h

Modified: scummvm/trunk/engines/mohawk/module.mk
===================================================================
--- scummvm/trunk/engines/mohawk/module.mk	2011-01-20 19:33:31 UTC (rev 55360)
+++ scummvm/trunk/engines/mohawk/module.mk	2011-01-20 21:34:19 UTC (rev 55361)
@@ -24,6 +24,7 @@
 	riven_vars.o \
 	sound.o \
 	video.o \
+	view.o \
 	myst_stacks/channelwood.o \
 	myst_stacks/credits.o \
 	myst_stacks/demo.o \

Added: scummvm/trunk/engines/mohawk/view.cpp
===================================================================
--- scummvm/trunk/engines/mohawk/view.cpp	                        (rev 0)
+++ scummvm/trunk/engines/mohawk/view.cpp	2011-01-20 21:34:19 UTC (rev 55361)
@@ -0,0 +1,810 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "mohawk/view.h"
+#include "mohawk/resource.h"
+#include "mohawk/graphics.h"
+#include "common/stream.h"
+#include "common/system.h"
+
+namespace Mohawk {
+
+Module::Module() {
+}
+
+Module::~Module() {
+}
+
+Feature::Feature(View *view) : _view(view) {
+}
+
+Feature::~Feature() {
+}
+
+void Feature::setNodeDefaults(Feature *prev, Feature *next) {
+	_prev = prev;
+	_next = next;
+
+	_moveProc = NULL;
+	_drawProc = NULL;
+	_doneProc = NULL;
+	_frameProc = NULL;
+
+	_data.bounds = Common::Rect();
+	_data.clipRect = Common::Rect();
+	_data.useClipRect = 0;
+
+	_region = 0;
+	_id = 0; // This is dealt with elsewhere.
+	_scrbId = 0;
+	_storedScrbId = 0;
+
+	_data.scrbIndex = 0;
+	_data.compoundSHAPIndex = 0;
+	_data.bitmapIds[0] = 0;
+
+	_data.unknown192 = 0;
+	_data.currFrame = 0;
+
+	_data.syncChannel = 0;
+	_data.enabled = 1;
+
+	_data.paused = 0; // new
+	_data.hidden = 0; // new
+
+	_flags = 0;
+
+	_dirty = 1;
+	_needsReset = 1;
+	_justReset = 0; // old
+	_notifyDone = 0;
+	_done = 0; // new
+
+	_nextTime = 0;
+	_delayTime = 0;
+}
+
+void Feature::resetFeatureScript(uint16 enabled, uint16 scrbId) {
+	if (!scrbId)
+		scrbId = _scrbId;
+	if (scrbId != _scrbId || _needsReset) {
+		if (_needsReset)
+			_data.bounds = Common::Rect();
+		_scrbId = scrbId;
+		_view->getnthScriptSetGroup(_data.scrbIndex, _data.compoundSHAPIndex, scrbId);
+	}
+	if (_data.scrbIndex == 0xFFFF) {
+		_data.enabled = 0;
+		_data.bitmapIds[0] = 0;
+		_data.scrbIndex = 0;
+		_data.compoundSHAPIndex = 0;
+		resetFrame();
+		return;
+	}
+
+	resetScript();
+	resetFrame();
+	_nextTime = 0; // New feature code uses _view->_lastIdleTime, but should be equivalent.
+	_data.enabled = enabled;
+	_dirty = 1;
+
+	finishResetFeatureScript();
+
+	_needsReset = 0;
+
+	if (_region) {
+		// TODO: mark _region as dirty
+	} else {
+		// TODO: mark _data.bounds as dirty
+	}
+}
+
+void Feature::resetFeature(bool notifyDone, Module::FeatureProc doneProc, uint16 scrbId) {
+	resetFeatureScript(1, scrbId);
+	_doneProc = doneProc;
+	_notifyDone = notifyDone;
+}
+
+void Feature::hide(bool clip) {
+	// FIXME: stuff
+
+	if (!_data.hidden && clip) {
+		if (_region) {
+			// TODO: mark _region as dirty
+		} else {
+			// TODO: mark _data.bounds as dirty
+		}
+	}
+
+	_data.hidden++;
+	_data.paused++;
+}
+
+void Feature::show() {
+	if (_data.hidden == 1) {
+		if (_region) {
+			// TODO: mark _region as dirty
+		} else {
+			// TODO: mark _data.bounds as dirty
+		}
+	}
+
+	_data.hidden--;
+	_data.paused--;
+}
+
+void Feature::moveAndUpdate(Common::Point newPos) {
+	if (newPos == _data.currentPos)
+		return;
+
+	_nextTime = 0;
+	_dirty = 1;
+	// TODO: mark _data.bounds as dirty
+
+	if (_data.bitmapIds[0])
+		_data.bounds.moveTo(newPos);
+
+	int xDiff = _data.currentPos.x - newPos.x;
+	int yDiff = _data.currentPos.y - newPos.y;
+
+	for (uint i = 0; i < FEATURE_BITMAP_ITEMS; i++) {
+		uint16 bitmapId = _data.bitmapIds[i];
+		if (!bitmapId) // || bitmapId > compoundSHAP.size()
+			break;
+		_data.bitmapPos[i].x -= xDiff;
+		_data.bitmapPos[i].y -= yDiff;
+	}
+
+	_data.currentPos = newPos;
+}
+
+void Feature::defaultDraw() {
+	if (_data.useClipRect) {
+		// TODO: set clip rect
+	}
+	uint16 compoundSHAPId = _view->getCompoundSHAPId(_data.compoundSHAPIndex);
+	for (uint i = 0; i < FEATURE_BITMAP_ITEMS; i++) {
+		uint16 bitmapId = _data.bitmapIds[i];
+		if (!bitmapId) // || bitmapId > compoundSHAP.size()
+			break;
+		_view->getGfx()->copyAnimSubImageToScreen(compoundSHAPId, bitmapId - 1, _data.bitmapPos[i].x, _data.bitmapPos[i].y);
+	}
+	if (_data.useClipRect) {
+		// TODO: restore clip rgn
+	}
+}
+
+OldFeature::OldFeature(View *view) : Feature(view) {
+}
+
+OldFeature::~OldFeature() {
+}
+
+void OldFeature::resetFrame() {
+	_data.currFrame = 0;
+	_data.currOffset = 1;
+}
+
+void OldFeature::resetFeatureScript(uint16 enabled, uint16 scrbId) {
+	if ((_flags & kFeatureOldAlternateScripts) && (_justReset || !_needsReset)) {
+		if (_storedScrbId)
+			return;
+		if (_flags & kFeatureOldRandom) {
+			_storedScrbId = -(int16)_scrbId;
+			_flags &= ~kFeatureOldRandom;
+		} else {
+			_storedScrbId = _scrbId;
+		}
+	}
+
+	Feature::resetFeatureScript(enabled, scrbId);
+}
+
+void OldFeature::resetScript() {
+	Common::SeekableReadStream *ourSCRB = _view->getSCRB(_data.scrbIndex, _scrbId);
+	_data.endFrame = ourSCRB->readUint16BE() - 1;
+	delete ourSCRB;
+}
+
+void OldFeature::finishResetFeatureScript() {
+	_justReset = 1;
+
+	if (_flags & kFeatureOldAdjustByPos) {
+		Common::SeekableReadStream *ourSCRB = _view->getSCRB(_data.scrbIndex, _scrbId);
+		ourSCRB->seek(4);
+		_data.nextPos.x = ourSCRB->readUint16BE();
+		_data.nextPos.y = ourSCRB->readUint16BE();
+		delete ourSCRB;
+	}
+}
+
+NewFeature::NewFeature(View *view) : Feature(view) {
+}
+
+NewFeature::~NewFeature() {
+}
+
+void NewFeature::resetFrame() {
+	_data.currOffset = 26;
+}
+
+void NewFeature::resetFeatureScript(uint16 enabled, uint16 scrbId) {
+	// TODO: _frameProc(this, -3);
+	// TODO: set unknown184 to 0x01010101
+
+	Feature::resetFeatureScript(enabled, scrbId);
+}
+
+void NewFeature::resetScript() {
+	// FIXME: registrations, etc
+	Common::SeekableReadStream *ourSCRB = _view->getSCRB(_data.scrbIndex, _scrbId);
+	ourSCRB->seek(16);
+	Common::Point scriptBase, scriptSize;
+	scriptBase.x = ourSCRB->readUint16BE();
+	scriptBase.y = ourSCRB->readUint16BE();
+	scriptSize.x = ourSCRB->readUint16BE();
+	scriptSize.y = ourSCRB->readUint16BE();
+	ourSCRB->seek(26);
+	Common::Point one, two;
+	while (true) {
+		if (ourSCRB->pos() == ourSCRB->size())
+			error("resetScript (getNewXYAndReg) ran out of script");
+		byte opcode = ourSCRB->readByte();
+		byte size = ourSCRB->readByte();
+		if (opcode != 0x10) {
+			ourSCRB->skip(size - 2);
+		} else if (size) {
+			assert(size >= 1);
+			ourSCRB->skip(2);
+			int16 x = ourSCRB->readUint16BE();
+			int16 y = ourSCRB->readUint16BE();
+			one.x = -x;
+			one.y = -y;
+			two.x = scriptBase.x + x;
+			two.y = scriptBase.y + y;
+			break;
+		}
+	}
+	delete ourSCRB;
+
+	if ((_needsReset || false /* TODO: param */) && (_unknown168 == 0x7FFFFFFF || false /* TODO: param */)) {
+		_data.currentPos = two;
+		_data.nextPos = one;
+		_unknown168 = 0;
+		if (_needsReset || false /* TODO: param */) {
+			_data.bounds = Common::Rect(scriptBase.x, scriptBase.y, scriptSize.x, scriptSize.y);
+		}
+	} else {
+		if (false /* FIXME: 0 shapes? */) {
+			_data.nextPos.x = one.x + two.x - _data.currentPos.x;
+			_data.nextPos.y = one.y + two.y - _data.currentPos.y;
+		} else if (_unknown168 != 0x7FFFFFFF) {
+			_data.nextPos = one;
+		}
+	}
+	// _needsReset = 0; (handled by caller)
+}
+
+void NewFeature::finishResetFeatureScript() {
+	_done = 0;
+}
+
+View::View(MohawkEngine *vm) : _vm(vm) {
+	_currentModule = NULL;
+
+	_backgroundId = 0xffff;
+
+	for (uint i = 0; i < 14; i++) { // used to be 8
+		_compoundSHAPGroups[i] = 0;
+	}
+	_numSCRBGroups = 0;
+}
+
+View::~View() {
+}
+
+void View::idleView() {
+	assert(_currentModule);
+
+	_lastIdleTime = getTime();
+
+	for (Feature *node = _rootNode; node; node = node->_next) {
+		if (node->_moveProc)
+			(_currentModule->*(node->_moveProc))(node);
+	}
+
+	// TODO: find a way this works for all clients
+	//if (/* TODO: _sortView */ true && !_inDialog) {
+	//	sortView();
+	//}
+	sortView();
+
+	for (Feature *node = _rootNode; node; node = node->_next) {
+		if (node->_dirty) {
+			// TODO: clipping
+			_needsUpdate = true;
+		}
+		if (node->_drawProc)
+			(_currentModule->*(node->_drawProc))(node);
+		node->_dirty = 0;
+	}
+
+	if (_needsUpdate) {
+		finishDraw();
+		_vm->_system->updateScreen();
+		_needsUpdate = false;
+		if (_backgroundId != 0xffff)
+			_gfx->copyAnimImageToScreen(_backgroundId);
+	}
+}
+
+void View::setModule(Module *module) {
+	if (_currentModule) {
+		module->shutdown();
+		delete module;
+	}
+
+	_currentModule = NULL;
+
+	if (module) {
+		_currentModule = module;
+		module->init();
+	}
+}
+
+Common::Array<uint16> View::getSHPL(uint16 id) {
+	Common::SeekableReadStream *stream;
+
+	if (_vm->hasResource(ID_TCNT, id)) {
+		stream = _vm->getResource(ID_TCNT, id);
+	} else {
+		stream = _vm->getResource(ID_SHPL, id);
+		stream->seek(4);
+		setColors(stream);
+		stream->seek(0);
+	}
+
+	uint16 base = stream->readUint16BE();
+	uint16 count = stream->readUint16BE();
+	delete stream;
+
+	Common::Array<uint16> items;
+	for (uint i = 0; i < count; i++)
+		items.push_back(base + i);
+
+	return items;
+}
+
+void View::installBG(uint16 id) {
+	// getShapes
+	Common::Array<uint16> shapes = getSHPL(id);
+	if (_vm->hasResource(ID_TPAL, id)) {
+		Common::SeekableReadStream *stream = _vm->getResource(ID_TPAL, id);
+		setColors(stream);
+		delete stream;
+	}
+
+	if (shapes.size() != 1) {
+		// TODO
+		warning("background with id 0x%04x has the wrong number of shapes (%d)", id, shapes.size());
+		_backgroundId = id;
+		_gfx->copyAnimImageToScreen(_backgroundId);
+	} else {
+		// DrawViewBackground
+		_backgroundId = shapes[0];
+		_gfx->copyAnimImageToScreen(_backgroundId);
+	}
+}
+
+void View::setColors(Common::SeekableReadStream *tpalStream) {
+	uint16 colorStart = tpalStream->readUint16BE();
+	uint16 colorCount = tpalStream->readUint16BE();
+	byte *palette = new byte[colorCount * 4];
+
+	for (uint16 i = 0; i < colorCount; i++) {
+		palette[i * 4] = tpalStream->readByte();
+		palette[i * 4 + 1] = tpalStream->readByte();
+		palette[i * 4 + 2] = tpalStream->readByte();
+		palette[i * 4 + 3] = tpalStream->readByte();
+	}
+
+	// TODO: copy into temporary buffer
+	_vm->_system->setPalette(palette, colorStart, colorCount);
+	delete[] palette;
+
+	// original does pdLightenUp here..
+}
+
+void View::copyFadeColors(uint start, uint count) {
+	// TODO
+}
+
+uint16 View::getCompoundSHAPId(uint16 shapIndex) {
+	return _compoundSHAPGroups[shapIndex];
+}
+
+void View::installGroupOfSCRBs(bool main, uint base, uint size, uint count) {
+	if (main) {
+		// TODO: _dropSpots.clear();
+		_numSCRBGroups = 0;
+		_SCRBEntries.clear();
+	}
+
+	if (_numSCRBGroups >= 14) // used to be 8
+		error("installGroupOfSCRBs called when we already had 14 groups");
+
+	for (uint i = 0; i < size; i++)
+		_SCRBEntries.push_back(base + i);
+
+	// TODO: think about this
+	if (count == 0)
+		count = size;
+	else if (count > size) {
+		for (uint i = 0; i < count - size; i++)
+			_SCRBEntries.push_back(0);
+	} else
+		error("installGroupOfSCRBs got count %d, size %d", count, size);
+
+	_SCRBGroupBases[_numSCRBGroups] = base;
+	_SCRBGroupSizes[_numSCRBGroups] = count;
+	_numSCRBGroups++;
+}
+
+void View::freeScripts() {
+	freeFeatureShapes();
+
+	for (uint i = 0; i < 14; i++) { // used to be 8
+		_SCRBGroupBases[i] = 0;
+		_SCRBGroupSizes[i] = 0;
+	}
+	_SCRBEntries.clear();
+	_numSCRBGroups = 0;
+}
+
+void View::installFeatureShapes(bool regs, uint groupId, uint16 resourceBase) {
+	if (groupId >= 14) // used to be 8
+		error("installFeatureShapes called for invalid group %d", groupId);
+
+	if (_compoundSHAPGroups[groupId])
+		error("installFeatureShapes called for existing group %d", groupId);
+
+	_compoundSHAPGroups[groupId] = resourceBase;
+
+	if (regs) {
+		// TODO
+	}
+}
+
+void View::freeFeatureShapes() {
+	for (uint i = 0; i < 14; i++) { // used to be 8
+		_compoundSHAPGroups[i] = 0;
+		// TODO: wipe regs data
+	}
+}
+
+uint16 View::getGroupFromBaseId(uint16 baseId) {
+	for (uint i = 0; i < 14; i++) {
+		if (_compoundSHAPGroups[i] == baseId)
+			return i;
+	}
+
+	// TODO: error?
+	return 0xffff;
+}
+
+void View::getnthScriptSetGroup(uint16 &scrbIndex, uint16 &shapIndex, uint16 scrbId) {
+	scrbIndex = 0;
+	for (uint i = 0; i < _numSCRBGroups; i++) {
+		if (_SCRBGroupBases[i] <= scrbId && _SCRBGroupBases[i] + _SCRBGroupSizes[i] > scrbId) {
+			shapIndex = i;
+			scrbIndex += scrbId - _SCRBGroupBases[i];
+			return;
+		}
+		scrbIndex += _SCRBGroupSizes[i];
+	}
+	scrbIndex = 0xffff;
+}
+
+Common::SeekableReadStream *View::getSCRB(uint16 index, uint16 id) {
+	// If we don't have an entry, load the load provided id.
+	// (The 0xffff check is a default parameter hack.)
+	if (!_SCRBEntries[index] && id != 0xffff)
+		_SCRBEntries[index] = id;
+
+	// FIXME
+	if (_vm->hasResource(ID_SCRB, _SCRBEntries[index]))
+		return _vm->getResource(ID_SCRB, _SCRBEntries[index]);
+	return _vm->getResource(ID_TSCR, _SCRBEntries[index]);
+}
+
+Feature *View::getFeaturePtr(uint16 id) {
+	for (Feature *node = _cursorNode; node; node = node->_prev) {
+		if (node->_id == id)
+			return node;
+	}
+
+	return NULL;
+}
+
+uint16 View::getNewFeatureId() {
+	uint16 nextId = 0;
+	Feature *node;
+	for (node = _rootNode; node; node = node->_next) {
+		// The original doesn't check for 0xffff but I don't want to fudge with signed integers.
+		if (node->_id != 0xffff && node->_id > nextId)
+			nextId = node->_id;
+	}
+	return nextId + 1;
+}
+
+void View::removeFeature(Feature *feature, bool free) {
+	// TODO: or bounds into dirty feature bounds
+
+	feature->_prev->_next = feature->_next;
+	feature->_next->_prev = feature->_prev;
+	feature->_next = NULL;
+	feature->_prev = NULL;
+
+	if (free)
+		delete feature;
+}
+
+void View::insertUnderCursor(Feature *feature) {
+	feature->_next = _cursorNode;
+	feature->_prev = _cursorNode->_prev;
+	feature->_prev->_next = feature;
+	feature->_next->_prev = feature;
+}
+
+Feature *View::pointOnFeature(bool topdown, uint32 flags, Common::Point pos) {
+	flags &= 0x7fffff;
+	Feature *curr = _rootNode->_next;
+	if (topdown)
+		curr = _cursorNode->_prev;
+	while (curr) {
+		if ((curr->_flags & 0x7fffff) == flags)
+			if (curr->_data.bounds.contains(pos))
+				return curr;
+		if (topdown)
+			curr = curr->_prev;
+		else
+			curr = curr->_next;
+	}
+	return NULL;
+}
+
+void View::sortView() {
+	Feature *base = _rootNode;
+	Feature *next = base->_next;
+	Feature *otherRoot = NULL;
+	Feature *otherBase = NULL;
+	Feature *objectRoot = NULL;
+	Feature *objectBase = NULL;
+	Feature *staticRoot = NULL;
+	Feature *staticBase = NULL;
+
+	// Remove all features.
+	base->_next = NULL;
+
+	// Iterate through all the previous features, placing them in the appropriate list.
+	while (next) {
+		Feature *curr = next;
+		next = next->_next;
+
+		if (curr->_flags & kFeatureSortBackground) {
+			// These are behind everything else (e.g. stars, drop spot highlights),
+			// so we insert this node directly after the current base.
+			base->_next = curr;
+			curr->_prev = base;
+			curr->_next = NULL;
+			base = base->_next;
+		} else if (curr->_flags & kFeatureSortStatic) {
+			// Insert this node into the list of static objects.
+			if (staticBase) {
+				staticBase->_next = curr;
+				curr->_prev = staticBase;
+				curr->_next = NULL;
+				staticBase = curr;
+			} else {
+				staticBase = curr;
+				staticRoot = curr;
+				curr->_prev = NULL;
+				curr->_next = NULL;
+			}
+		} else if (curr->_flags & kFeatureObjectMask) { // This is == 1 or == 2 in old code.
+			// Insert this node into the list of objects.
+			if (objectRoot) {
+				objectBase->_next = curr;
+				curr->_prev = objectBase;
+				curr->_next = NULL;
+				objectBase = curr;
+			} else {
+				objectBase = curr;
+				objectRoot = curr;
+				curr->_prev = NULL;
+				curr->_next = NULL;
+			}
+		} else {
+			if (!(curr->_flags & kFeatureOldSortForeground))
+				curr->_flags |= kFeatureSortStatic;
+
+			// Insert this node into the list of other features.
+			if (otherRoot) {
+				otherBase->_next = curr;
+				curr->_prev = otherBase;
+				curr->_next = NULL;
+				otherBase = curr;
+			} else {
+				otherBase = curr;
+				otherRoot = curr;
+				curr->_prev = NULL;
+				curr->_next = NULL;
+			}
+		}
+	}
+
+	// Add the static features after the background ones.
+	Feature *curr = staticRoot;
+	while (curr) {
+		Feature *prev = curr;
+		curr = curr->_next;
+		base->_next = prev;
+		prev->_prev = base;
+		base = base->_next;
+		base->_next = NULL;
+	}
+
+	// Add the other features on top..
+	_rootNode = mergeLists(_rootNode, sortOneList(otherRoot));
+	// Then finally, add the objects.
+	_rootNode = mergeLists(_rootNode, sortOneList(objectRoot));
+}
+
+Feature *View::sortOneList(Feature *root) {
+	if (!root)
+		return NULL;
+
+	// Save the next feature and then clear the list.
+	Feature *curr = root->_next;
+	root->_next = NULL;
+	root->_prev = NULL;
+
+	// Iterate over all the features.
+	while (curr) {
+		Feature *prev = curr;
+		curr = curr->_next;
+		Common::Rect &prevRect = prev->_data.bounds;
+
+		// Check against all features currently in the list.
+		Feature *check = root;
+		while (check) {
+			Common::Rect &checkRect = check->_data.bounds;
+
+			if ((prev->_flags & kFeatureOldSortForeground) || (prevRect.bottom >= checkRect.bottom && (prevRect.bottom != checkRect.bottom || prevRect.left >= checkRect.left))) {
+				// If we're meant to be in front of everything else, or we're in front of the check object..
+				if (!check->_next) {
+					// This is the end of the list: add ourselves there.
+					check->_next = prev;
+					prev->_prev = check;
+					prev->_next = NULL;
+					break;
+				}
+			} else {
+				// We're meant to be behind this object. Insert ourselves here.
+				prev->_prev = check->_prev;
+				prev->_next = check;
+				check->_prev = prev;
+				if (prev->_prev)
+					prev->_prev->_next = prev;
+				else
+					root = prev;
+				break;
+			}
+
+			check = check->_next;
+		}
+	}
+
+	return root;
+}
+
+Feature *View::mergeLists(Feature *root, Feature *mergeRoot) {
+	Feature *base = root;
+	// Skip anything marked as being behind everything else.
+	while (base->_next && (base->_next->_flags & kFeatureSortBackground))
+		base = base->_next;
+
+	// Iterate over all the objects in the root to be merged.
+	Feature *curr = mergeRoot;
+	while (curr) {
+		Feature *prev = curr;
+		curr = curr->_next;
+		Common::Rect &prevRect = prev->_data.bounds;
+
+		// Check against all objects currently in the list.
+		Feature *check = base;
+		if (prev->_flags & kFeatureOldSortForeground) {
+			// This object is meant to be in front of everything else,
+			// put it at the end of the list.
+			while (check && check->_next)
+				check = check->_next;
+			check->_next = prev;
+			prev->_prev = check;
+			prev->_next = NULL;
+			continue;
+		}
+
+		while (check) {
+			if (check->_flags & kFeatureOldSortForeground) {
+				// The other object is meant to be in front of everything else,
+				// put ourselves before it.
+				prev->_prev = check->_prev;
+				prev->_next = check;
+				check->_prev = prev;
+				// The original doesn't bother with this 'if'.
+				if (prev->_prev)
+					prev->_prev->_next = prev;
+				else
+					root = prev;
+				break;
+			}
+
+			if (!check->_next) {
+				// We're at the end of the list, so we have to go here.
+				check->_next = prev;
+				prev->_prev = check;
+				prev->_next = NULL;
+				base = prev;
+				break;
+			}
+
+			Common::Rect &checkRect = check->_data.bounds;
+
+			if (prevRect.bottom < checkRect.bottom || (prevRect.bottom == checkRect.bottom && prevRect.left < checkRect.left)) {
+				if (prevRect.bottom < checkRect.top || (
+					(!(check->_flags & kFeatureSortCheckLeft) || prevRect.left >= checkRect.left) &&
+					(!(check->_flags & kFeatureSortCheckTop) || prevRect.top >= checkRect.top) &&
+					(!(check->_flags & kFeatureSortCheckRight) || prevRect.right <= checkRect.right))) {
+					// Insert ourselves before this one.
+					prev->_prev = check->_prev;
+					prev->_next = check;
+					check->_prev = prev;
+					if (prev->_prev)
+						prev->_prev->_next = prev;
+					else
+						root = prev;
+					base = prev->_next;
+					break;
+				}
+			}
+
+			check = check->_next;
+		}
+	}
+
+	return root;
+}
+
+} // End of namespace Mohawk


Property changes on: scummvm/trunk/engines/mohawk/view.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: scummvm/trunk/engines/mohawk/view.h
===================================================================
--- scummvm/trunk/engines/mohawk/view.h	                        (rev 0)
+++ scummvm/trunk/engines/mohawk/view.h	2011-01-20 21:34:19 UTC (rev 55361)
@@ -0,0 +1,271 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef MOHAWK_VIEW_H
+#define MOHAWK_VIEW_H
+
+#include "mohawk/mohawk.h"
+#include "common/rect.h"
+
+namespace Mohawk {
+
+class GraphicsManager;
+
+class Feature;
+class View;
+
+enum {
+	kFeatureObjectMask = 0xff, // both (sort of)
+	kFeatureOldSortForeground = 0x1000, // old
+	kFeatureOldDropSpot = 0x2000, // old
+	kFeatureOldNoClip = 0x4000, // old
+	kFeatureNewSortForeground = 0x4000, // new
+	kFeatureSortBackground = 0x8000, // both
+	kFeatureOldReset = 0x10000, // old
+	kFeatureOldDisable = 0x20000, // old
+	kFeatureOldAlternateScripts = 0x40000, // old
+	kFeatureOldDisableOnReset = 0x80000, // old
+	kFeatureDisableOnEnd = 0x100000, // both
+	kFeatureNewDisable = 0x200000, // new
+	kFeatureNewDisableOnReset = 0x400000, // new
+	kFeatureOldAdjustByPos = 0x800000, // old
+	kFeatureNewNoLoop = 0x800000, // new
+	kFeatureOldDisabled = 0x1000000, // old
+	kFeatureOldRandom = 0x2000000, // old
+	kFeatureNewClip = 0x2000000, // new
+	kFeatureSortStatic = 0x4000000, // both
+	kFeatureInternalRegion = 0x8000000, // both
+	kFeatureSortCheckRight = 0x10000000, // both
+	kFeatureSortCheckTop = 0x20000000, // both
+	kFeatureSortCheckLeft = 0x40000000, // both
+	kFeatureNewInternalTiming = 0x80000000 // new
+};
+
+class Module {
+public:
+	Module();
+	virtual ~Module();
+
+	virtual void init() = 0;
+	virtual void shutdown() = 0;
+	virtual void update() = 0;
+
+	typedef void (Module::*HotspotProc)(uint);
+	typedef void (Module::*FeatureProc)(Feature *);
+	typedef bool (Module::*BooleanProc)(Feature *);
+	typedef void (Module::*PickupProc)(Feature *, Common::Point, uint32, Common::Rect *);
+};
+
+// This is memcpy()ed around, beware.
+#define FEATURE_BITMAP_ITEMS 48 // this is 24 in old
+struct FeatureData {
+	uint16 bitmapIds[FEATURE_BITMAP_ITEMS];
+	Common::Point bitmapPos[FEATURE_BITMAP_ITEMS];
+
+	uint16 unknown192; // old?
+
+	uint16 scrbIndex;
+	uint16 compoundSHAPIndex;
+	uint16 endFrame; // old?
+	uint16 currFrame; // old?
+	uint32 currOffset;
+
+	Common::Rect bounds;
+
+	Common::Point currentPos;
+	Common::Point nextPos;
+
+	uint16 unknown220; // old?
+
+	uint16 syncChannel;
+	uint16 enabled;
+	byte paused; // new
+	byte hidden; // new
+
+	uint16 useClipRect;
+	Common::Rect clipRect;
+};
+
+class Feature {
+public:
+	Feature(View *view);
+	virtual ~Feature();
+
+	virtual void resetFrame() = 0;
+
+	virtual void setNodeDefaults(Feature *prev, Feature *next);
+	virtual void resetFeatureScript(uint16 enabled, uint16 scrbId);
+	virtual void resetFeature(bool notifyDone, Module::FeatureProc doneProc, uint16 scrbId);
+
+	void hide(bool clip);
+	void show();
+
+	void moveAndUpdate(Common::Point newPos);
+
+	void defaultDraw();
+
+	Feature *_next, *_prev;
+
+	Module::FeatureProc _drawProc;
+	Module::FeatureProc _moveProc;
+	Module::FeatureProc _doneProc;
+	Module::FeatureProc _frameProc;
+	Module::BooleanProc _timeProc;
+
+	uint16 _region; // TODO
+	uint16 _id;
+	uint16 _scrbId;
+	uint16 _storedScrbId; // old
+	uint32 _flags;
+	uint32 _nextTime;
+	uint32 _delayTime;
+	uint16 _dirty; // byte in old
+	byte _needsReset;
+	byte _justReset; // old
+	byte _notifyDone; // old
+	byte _done; // new
+
+	FeatureData _data;
+
+protected:
+	View *_view;
+
+	virtual void resetScript() = 0;
+	virtual void finishResetFeatureScript() = 0;
+};
+
+class OldFeature : public Feature {
+public:
+	OldFeature(View *view);
+	~OldFeature();
+
+	void resetFrame();
+	void resetFeatureScript(uint16 enabled, uint16 scrbId);
+
+protected:
+	void resetScript();
+	void finishResetFeatureScript();
+};
+
+class NewFeature : public Feature {
+public:
+	NewFeature(View *view);
+	~NewFeature();
+
+	void resetFrame();
+	void resetFeatureScript(uint16 enabled, uint16 scrbId);
+
+	uint32 _unknown168;
+
+	// Drag/drop variables.
+	Module::PickupProc _pickupProc;
+	Module::FeatureProc _dropProc;
+	Module::FeatureProc _dragMoveProc;
+	Module::FeatureProc _oldMoveProc;
+	uint32 _dragFlags;
+	uint32 _oldFlags;
+	Common::Point _oldPos;
+	Common::Point _posDiff;
+	Common::Point _currDragPos;
+
+protected:
+	void resetScript();
+	void finishResetFeatureScript();
+};
+
+#define NUM_SYNC_CHANNELS 17
+struct SyncChannel {
+	uint16 masterId;
+	byte state;
+	bool alternate;
+};
+
+class View {
+public:
+	View(MohawkEngine *vm);
+	virtual ~View();
+
+	virtual void idleView();
+
+	void setModule(Module *module);
+	Module *getCurrentModule() { return _currentModule; }
+	GraphicsManager *getGfx() { return _gfx; }
+
+	Common::Array<uint16> getSHPL(uint16 id);
+	void installBG(uint16 id);
+	void setColors(Common::SeekableReadStream *tpalStream);
+	void copyFadeColors(uint start, uint count);
+
+	uint16 getCompoundSHAPId(uint16 shapIndex);
+
+	void installGroupOfSCRBs(bool main, uint base, uint size, uint count = 0);
+	virtual void freeScripts();
+	void installFeatureShapes(bool regs, uint groupId, uint16 resourceBase);
+	void freeFeatureShapes();
+
+	uint16 getGroupFromBaseId(uint16 baseId);
+	void getnthScriptSetGroup(uint16 &scrbIndex, uint16 &shapIndex, uint16 scrbId);
+	Common::SeekableReadStream *getSCRB(uint16 index, uint16 id = 0xffff);
+
+	Feature *getFeaturePtr(uint16 id);
+	uint16 getNewFeatureId();
+	void removeFeature(Feature *feature, bool free);
+	void insertUnderCursor(Feature *feature);
+	Feature *pointOnFeature(bool topdown, uint32 flags, Common::Point pos);
+	void sortView();
+
+	uint32 _lastIdleTime;
+	SyncChannel _syncChannels[NUM_SYNC_CHANNELS];
+
+	virtual uint32 getTime() = 0;
+
+	bool _needsUpdate;
+
+protected:
+	MohawkEngine *_vm;
+	GraphicsManager *_gfx;
+	void setGraphicsManager(GraphicsManager *gfx) { _gfx = gfx; } // TODO
+	Module *_currentModule;
+
+	uint16 _backgroundId;
+
+	Feature *_rootNode, *_cursorNode;
+
+	uint16 _numSCRBGroups;
+	uint16 _SCRBGroupBases[14];
+	uint16 _SCRBGroupSizes[14];
+	Common::Array<uint16> _SCRBEntries;
+	//uint16 _numCompoundSHAPGroups;
+	uint16 _compoundSHAPGroups[14];
+
+	Feature *sortOneList(Feature *root);
+	Feature *mergeLists(Feature *root, Feature *mergeRoot);
+
+	virtual void finishDraw() { }
+};
+
+} // End of namespace Mohawk
+
+#endif


Property changes on: scummvm/trunk/engines/mohawk/view.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list