[Scummvm-cvs-logs] SF.net SVN: scummvm:[42161] scummvm/trunk/engines/gob

drmccoy at users.sourceforge.net drmccoy at users.sourceforge.net
Mon Jul 6 03:41:29 CEST 2009


Revision: 42161
          http://scummvm.svn.sourceforge.net/scummvm/?rev=42161&view=rev
Author:   drmccoy
Date:     2009-07-06 01:41:29 +0000 (Mon, 06 Jul 2009)

Log Message:
-----------
Adding more comments

Modified Paths:
--------------
    scummvm/trunk/engines/gob/hotspots.cpp
    scummvm/trunk/engines/gob/hotspots.h

Modified: scummvm/trunk/engines/gob/hotspots.cpp
===================================================================
--- scummvm/trunk/engines/gob/hotspots.cpp	2009-07-05 23:38:11 UTC (rev 42160)
+++ scummvm/trunk/engines/gob/hotspots.cpp	2009-07-06 01:41:29 UTC (rev 42161)
@@ -161,12 +161,15 @@
 	MouseButtons myButton = getButton();
 
 	if (myButton == kMouseButtonsAny)
+		// Any button allowed
 		return true;
 
 	if (myButton == kMouseButtonsNone)
+		// No button allowed
 		return false;
 
 	if (myButton == button)
+		// Exact match
 		return true;
 
 	return false;
@@ -194,7 +197,9 @@
 Hotspots::~Hotspots() {
 	delete[] _hotspots;
 
+	// Pop the whole stack and free each element's memory
 	while (!_stack.empty()) {
+
 		StackEntry backup = _stack.pop();
 
 		delete[] backup.hotspots;
@@ -278,9 +283,11 @@
 		Hotspot &spot = _hotspots[i];
 
 		if (!force && ((spot.flags & 0x80) != 0))
+			// Not forcing a special hotspot
 			continue;
 
 		if (spot.funcPos == 0)
+			// Simple coordinates don't need update
 			continue;
 
 		// Setting the needed script
@@ -420,6 +427,7 @@
 		error("Hotspots::pop(): Not enough free space in the current Hotspot "
 		      "array to pop %d elements (got %d)", backup.size, kHotspotCount - i);
 
+	// Copy
 	memcpy(destPtr, backup.hotspots, backup.size * sizeof(Hotspot));
 
 	_shouldPush   = backup.shouldPush;
@@ -474,6 +482,7 @@
 
 	Hotspot &spot = _hotspots[index];
 
+	// If requested, write the ID into a variable
 	if ((spot.getState() == (kStateFilled | kStateType1)) ||
 	    (spot.getState() == (kStateFilled | kStateType2)))
 		WRITE_VAR(17, -(spot.id & 0x0FFF));
@@ -492,6 +501,7 @@
 
 	Hotspot &spot = _hotspots[index];
 
+	// If requested, write the ID into a variable
 	if ((spot.getState() == (kStateFilled | kStateType1)) ||
 	    (spot.getState() == (kStateFilled | kStateType2)))
 		WRITE_VAR(17, spot.id & 0x0FFF);
@@ -504,21 +514,26 @@
 	id    = 0;
 	index = 0;
 
-	if        (type == kTypeMove) {
+	if (type == kTypeMove) {
+		// Check where the mouse was moved to
 
 		for (int i = 0; (i < kHotspotCount) && !_hotspots[i].isEnd(); i++) {
 			Hotspot &spot = _hotspots[i];
 
 			if (spot.isDisabled())
+				// Only consider enabled hotspots
 				continue;
 
 			if (spot.getType() > kTypeMove)
+				// Only consider click and move hotspots
 				continue;
 
 			if (spot.getWindow() != 0)
+				// Only check the main window
 				continue;
 
 			if (!spot.isIn(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY))
+				// If we're not in it, ignore it
 				continue;
 
 			id    = spot.id;
@@ -530,35 +545,44 @@
 		return 0;
 
 	} else if (type == kTypeClick) {
+		// Check if something was clicked
 
 		for (int i = 0; (i < kHotspotCount) && !_hotspots[i].isEnd(); i++) {
 			Hotspot &spot = _hotspots[i];
 
 			if (spot.isDisabled())
+				// Only consider enabled hotspots
 				continue;
 
 			if (spot.getWindow() != 0)
+				// Only check the main window
 				continue;
 
 			if (spot.getType() < kTypeMove)
+				// Only consider hotspots that can be clicked
 				continue;
 
 			if (!spot.isIn(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY))
+				// If we're not in it, ignore it
 				continue;
 
 			if (!spot.buttonMatch(_vm->_game->_mouseButtons))
+				// Don't follow hotspots with button requirements we don't meet
 				continue;
 
 			id    = spot.id;
 			index = i;
 
 			if ((spot.getType() == kTypeMove) || (spot.getType() == kTypeClick))
+				// It's a move or click => return the key
 				return spot.key;
 
+			// Otherwise, the key has a different meaning, so ignore it
 			return 0;
 		}
 
 		if (_vm->_game->_mouseButtons != kMouseButtonsLeft)
+			// Let the right mouse button act as an escape key
 			return kKeyEscape;
 
 		return 0;
@@ -568,23 +592,29 @@
 	return 0;
 }
 
-void Hotspots::checkHotspotChanged() {
+bool Hotspots::checkHotspotChanged() {
 	uint16 key, id, index;
 
+	// Get the current hotspot
 	key = checkMouse(kTypeMove, id, index);
 
 	if (key == _currentKey)
-		return;
+		// Nothing changed => nothing to do
+		return false;
 
-	if (isValid(_currentKey, _currentId, _currentIndex))
+	// Leave the old area
+	if (isValid(_currentKey, _currentId,_currentIndex))
 		leave(_currentIndex);
 
 	_currentKey   = key;
 	_currentId    = id;
 	_currentIndex = index;
 
+	// Enter the new one
 	if (isValid(key, id, index))
 		enter(index);
+
+	return true;
 }
 
 uint16 Hotspots::check(uint8 handleMouse, int16 delay, uint16 &id, uint16 &index) {
@@ -601,6 +631,8 @@
 
 	if (handleMouse) {
 		if ((_vm->_draw->_cursorIndex == -1) && (_currentKey == 0)) {
+			// Last know state: No hotspot hit. Look if that changed
+
 			_currentKey = checkMouse(kTypeMove, _currentId, _currentIndex);
 
 			if (isValid(_currentKey, _currentId, _currentIndex))
@@ -612,6 +644,7 @@
 
 	uint32 startTime = _vm->_util->getTimeKey();
 
+	// Update display
 	_vm->_draw->blitInvalidated();
 	_vm->_video->retrace();
 
@@ -624,8 +657,10 @@
 			return 0;
 		}
 
+		// Anything changed?
 		checkHotspotChanged();
 
+		// Update display
 		if (!_vm->_draw->_noInvalidated) {
 			if (handleMouse)
 				_vm->_draw->animateCursor(-1);
@@ -634,21 +669,27 @@
 			_vm->_video->waitRetrace();
 		}
 
+		// Update keyboard and mouse state
 		key = _vm->_game->checkKeys(&_vm->_global->_inter_mouseX,
 				&_vm->_global->_inter_mouseY, &_vm->_game->_mouseButtons, handleMouse);
 
 		if (!handleMouse && (_vm->_game->_mouseButtons != kMouseButtonsNone)) {
+			// We don't want any mouse input but got one => Wait till it went away
+
 			_vm->_util->waitMouseRelease(0);
 			key = 3;
 		}
 
 		if (key != 0) {
+			// Got a key press
+
 			if (handleMouse & 1)
 				_vm->_draw->blitCursor();
 
 			id    = 0;
 			index = 0;
 
+			// Leave the current hotspot
 			if (isValid(_currentKey, _currentId, _currentIndex))
 				leave(_currentIndex);
 
@@ -659,8 +700,11 @@
 		if (handleMouse) {
 
 			if (_vm->_game->_mouseButtons != kMouseButtonsNone) {
+				// Mouse button pressed
 
 				if (delay > 0) {
+					// If a delay was requested, wait the specified time
+
 					_vm->_draw->animateCursor(2);
 					_vm->_util->delay(delay);
 				} else if (handleMouse & 1)
@@ -668,13 +712,17 @@
 
 				_vm->_draw->animateCursor(-1);
 
+				// Which region was clicked?
 				key = checkMouse(kTypeClick, id, index);
 
 				if ((key != 0) || (id != 0)) {
+					// Got a valid region
+
 					if ( (handleMouse & 1) &&
 						  ((delay <= 0) || (_vm->_game->_mouseButtons == kMouseButtonsNone)))
 						_vm->_draw->blitCursor();
 
+					// If the hotspot changed, leave the old one
 					if (key != _currentKey)
 						leave(_currentIndex);
 
@@ -683,22 +731,26 @@
 				}
 
 				if (handleMouse & 4)
+					// Nothing further than one simple check was requested => return
 					return 0;
 
+				// Leave the current area
 				if (_currentKey != 0)
 					leave(_currentIndex);
 
+				// No click, but do we have a move event? If so, enter that hotspot
 				_currentKey = checkMouse(kTypeMove, _currentId, _currentIndex);
 				if (isValid(_currentKey, _currentId, _currentIndex))
 					enter(_currentIndex);
 
 			} else
+				// No mouse button pressed, check whether the position changed at least
 				checkHotspotChanged();
-
 		}
 
 		if ((delay == -2) && (key == 0) &&
 		    (_vm->_game->_mouseButtons == kMouseButtonsNone)) {
+			// Nothing found and no further handling requested. Return.
 
 			id    = 0;
 			index = 0;
@@ -711,9 +763,12 @@
 		if ((delay < 0) && (key == 0) &&
 		    (_vm->_game->_mouseButtons == kMouseButtonsNone)) {
 
+			// Look if we've maybe reached the timeout
+
 			uint32 curTime = _vm->_util->getTimeKey();
-			// Timeout reached?
 			if ((curTime + delay) > startTime) {
+				// If so, return
+
 				id    = 0;
 				index = 0;
 				break;
@@ -721,6 +776,7 @@
 
 		}
 
+	// Sleep for a short amount of time
 	_vm->_util->delay(10);
 
 	}
@@ -731,16 +787,20 @@
 uint16 Hotspots::check(uint8 handleMouse, int16 delay) {
 	uint16 id, index;
 
+	// Check and ignore the id and index
 	return Hotspots::check(handleMouse, delay, id, index);
 }
 
-uint16 Hotspots::readString(uint16 xPos, uint16 yPos, uint16 width, uint16 height,
+uint16 Hotspots::updateInput(uint16 xPos, uint16 yPos, uint16 width, uint16 height,
 		uint16 backColor, uint16 frontColor, char *str, uint16 fontIndex,
-		Type type, int16 &duration, uint16 &id, uint16 index) {
+		Type type, int16 &duration, uint16 &id, uint16 &index) {
 
-	if ((fontIndex >= 8) || !_vm->_draw->_fonts[fontIndex])
+	if ((fontIndex >= 8) || !_vm->_draw->_fonts[fontIndex]) {
+		warning("Hotspots::updateInput(): Invalid font specified: %d", fontIndex);
 		return 0;
+	}
 
+	// Check if we need to consider mouse events
 	bool handleMouse = false;
 	if ( (_vm->_game->_handleMouse != 0) &&
 	    ((_vm->_global->_useMouse != 0) || (_vm->_game->_forceHandleMouse != 0)))
@@ -748,15 +808,20 @@
 
 	const Video::FontDesc &font = *_vm->_draw->_fonts[fontIndex];
 
+	// The font doesn't specify individual character widths => monospaced
 	bool monoSpaced = (font.charWidths == 0);
 
-	uint32 pos            = strlen(str);
-	uint32 editSize       = monoSpaced ? (width / font.itemWidth) : 0;
+	// Current position in the string, preset to the end
+	uint32 pos      = strlen(str);
+	/* Size of input field in characters.
+	 * If the font is not monospaced, we can't know that */
+	uint32 editSize = monoSpaced ? (width / font.itemWidth) : 0;
 
 	uint16 key = 0;
 	char tempStr[256];
 
 	while (1) {
+		// If we the edit field has enough space, add a space for the new character
 		strncpy0(tempStr, str, 254);
 		strcat(tempStr, " ");
 		if ((editSize != 0) && strlen(tempStr) > editSize)
@@ -767,12 +832,15 @@
 		         monoSpaced ? (editSize * font.itemWidth) : width, height,
 		         backColor);
 
+		// Print the current string, vertically centered
 		printText(xPos, yPos + (height - font.itemHeight) / 2,
 				tempStr, fontIndex, frontColor);
 
+		// If we've reached the end of the input field, set the cursor to the last character
 		if ((editSize != 0) && (pos == editSize))
 			pos--;
 
+		// The character under the cursor
 		char curSym = tempStr[pos];
 
 		if (_vm->_inter->_variables)
@@ -790,13 +858,16 @@
 			fillRect(cursorX, cursorY, cursorWidth, cursorHeight, frontColor);
 
 			if (first) {
+				// The first time, purge old information too
 				key = check(handleMouse, -1, id, index);
 
 				if (key == 0)
+					// We didn't catch any input, let's try again with a real timeout
 					key = check(handleMouse, -300, id, index);
 
 				first = false;
 			} else
+				// Try to catch a character
 				key = check(handleMouse, -300, id, index);
 
 			tempStr[0] = curSym;
@@ -807,21 +878,27 @@
 					cursorX, cursorY, cursorWidth, cursorHeight);
 			fillRect(cursorX, cursorY, cursorWidth, cursorHeight, backColor);
 
+			// Print the current string, vertically centered
 			printText(cursorX, yPos + (height - font.itemHeight) / 2,
 					tempStr, fontIndex, frontColor);
 
 			if ((key != 0) || (id != 0))
+				// We did get a key, stop looking
 				break;
 
+			// Try again
 			key = check(handleMouse, -300, id, index);
 
 			if ((key != 0) || (id != 0) ||
 					_vm->_inter->_terminate || _vm->shouldQuit())
+				// We did get a key, stop looking
 				break;
 
 			if (duration > 0) {
+				// Look if we reached the time limit
 				duration -= 600;
 				if (duration <= 1) {
+					// If so, abort
 					key = 0;
 					id  = 0;
 					break;
@@ -831,30 +908,37 @@
 
 		if ((key == 0) || (id != 0) ||
 				_vm->_inter->_terminate || _vm->shouldQuit())
+			// Got no key, or a region ID instead, return
 			return 0;
 
 		switch (key) {
 		case kKeyRight:
+			// If possible, move the cursor right
 			if ((pos > strlen(str)) || (pos > (editSize - 1)) || (editSize == 0)) {
 				pos++;
 				continue;
 			}
+			// Continue downwards instead
 			return kKeyDown;
 
 		case kKeyLeft:
+			// If possible, move the cursor left
 			if (pos > 0) {
 				pos--;
 				continue;
 			}
+			// Continue upwards instead
 			return kKeyUp;
 
 		case kKeyBackspace:
 			if (pos > 0) {
+				// Delete the character to the left
 				_vm->_util->cutFromStr(str, pos - 1, 1);
 				pos--;
 				continue;
 			} else {
 				if (pos < strlen(str))
+					// Delete the character to the right
 					_vm->_util->cutFromStr(str, pos, 1);
 			}
 
@@ -862,6 +946,7 @@
 			if (pos >= strlen(str))
 				continue;
 
+			// Delete the character to the right
 			_vm->_util->cutFromStr(str, pos, 1);
 			continue;
 
@@ -881,6 +966,7 @@
 			return key;
 
 		case kKeyEscape:
+			// If we got an escape event, wait until the mouse buttons have been released
 			if (_vm->_global->_useMouse != 0)
 				continue;
 
@@ -891,17 +977,21 @@
 			    ((_vm->_global->_useMouse != 0) || (_vm->_game->_forceHandleMouse != 0)))
 				handleMouse = true;
 
-			while (_vm->_global->_pressedKeys[1] != 0)
-				;
+			while (_vm->_global->_pressedKeys[1] != 0);
 			continue;
 
 		default:
+			// Got a "normal" key
+
 			uint16 savedKey = key;
 
 			key &= 0xFF;
 
 			if (((type == kTypeInputFloatNoLeave) || (type == kTypeInputFloatLeave)) &&
 					 (key >= ' ') && (key <= 0xFF)) {
+
+				// Only allow character found in numerical floating values
+
 				const char *str1 = "0123456789-.,+ ";
 				const char *str2 = "0123456789-,,+ ";
 
@@ -924,27 +1014,34 @@
 
 			if ((key >= ' ') && (key <= 0xFF)) {
 				if (editSize == 0) {
+					// Length of the string + current character + next one
 					int length = _vm->_draw->stringLength(str, fontIndex) +
 						font.charWidths[' ' - font.startItem] +
 						font.charWidths[key - font.startItem];
 
 					if (length > width)
+						// We're above the limit, ignore the key
 						continue;
 
 					if (((int32) strlen(str)) >= (_vm->_global->_inter_animDataSize * 4 - 1))
+						// Above the limit of character allowed in a string, ignore the key
 						continue;
 
 				} else {
 					if (strlen(str) > editSize)
+						// We're over the upper character limit for this field
 						continue;
 					else if (editSize == strlen(str))
+						// We've reached the upper limit, overwrite the last character
 						_vm->_util->cutFromStr(str, strlen(str) - 1, 1);
 				}
 
+				// Advance cursor
 				pos++;
 				tempStr[0] = key;
 				tempStr[1] = 0;
 
+				// Add character
 				_vm->_util->insertStr(tempStr, str, pos - 1);
 			}
 
@@ -952,22 +1049,25 @@
 	}
 }
 
-uint16 Hotspots::handleInput(int16 time, uint16 inputCount, uint16 &curInput,
+uint16 Hotspots::handleInputs(int16 time, uint16 inputCount, uint16 &curInput,
 		InputDesc *inputs, uint16 &id, uint16 &index) {
 
+	// Redraw all texts in all inputs we currently manage
 	updateAllTexts(inputs);
 
 	for (int i = 0; i < 40; i++)
-		WRITE_VAR_OFFSET(i * 4 + 0x44, 0);
+		WRITE_VAR(17 + i, 0);
 
 	while (1) {
-		uint16 hotspotIndex = findInput(curInput);
+		// Find the hotspot index to our current input
+		uint16 hotspotIndex = inputToHotspot(curInput);
 
 		assert(hotspotIndex != 0xFFFF);
 
 		Hotspot inputSpot = _hotspots[hotspotIndex];
 
-		uint16 key = readString(inputSpot.left, inputSpot.top,
+		// Handle input events from that input field
+		uint16 key = updateInput(inputSpot.left, inputSpot.top,
 				inputSpot.right - inputSpot.left + 1,
 				inputSpot.bottom - inputSpot.top + 1,
 				inputs[curInput].backColor, inputs[curInput].frontColor,
@@ -980,15 +1080,19 @@
 		switch (key) {
 		case kKeyNone:
 			if (id == 0)
+				// No key and no hotspot => return
 				return 0;
 
 			if (_vm->_game->_mouseButtons != kMouseButtonsNone)
+				// Clicked something, get the hotspot index
 				index = findClickedInput(index);
 
 			if (!_hotspots[index].isInput())
+				// It's no input, return
 				return 0;
 
-			curInput = findNthInput(index);
+			// Get the associated input index
+			curInput = hotspotToInput(index);
 			break;
 
 		case kKeyF1:
@@ -1004,12 +1108,11 @@
 			return key;
 
 		case kKeyReturn:
-
 			// Just one input => return
 			if (inputCount == 1)
 				return kKeyReturn;
 
-			// End of input chain reached => wap
+			// End of input chain reached => wrap
 			if (curInput == (inputCount - 1)) {
 				curInput = 0;
 				break;
@@ -1044,6 +1147,8 @@
 	byte window = 0;
 
 	if ((type & 0x40) != 0) {
+		// Got a window ID
+
 		type  -= 0x40;
 		window = _vm->_game->_script->readByte();
 	}
@@ -1052,12 +1157,14 @@
 	uint16 left, top, width, height, right, bottom;
 	uint32 funcPos = 0;
 	if ((type & 0x80) != 0) {
+		// Complex coordinate expressions
 		funcPos = _vm->_game->_script->pos();
 		left    = _vm->_game->_script->readValExpr();
 		top     = _vm->_game->_script->readValExpr();
 		width   = _vm->_game->_script->readValExpr();
 		height  = _vm->_game->_script->readValExpr();
 	} else {
+		// Immediate values
 		funcPos = 0;
 		left    = _vm->_game->_script->readUint16();
 		top     = _vm->_game->_script->readUint16();
@@ -1154,28 +1261,35 @@
 		inputs[inputCount].fontIndex  = _vm->_game->_script->readInt16();
 		inputs[inputCount].backColor  = _vm->_game->_script->readByte();
 		inputs[inputCount].frontColor = _vm->_game->_script->readByte();
+		inputs[inputCount].length     = 0;
 		inputs[inputCount].str        = 0;
 
 		if ((type >= kTypeInput2NoLeave) && (type <= kTypeInput3Leave)) {
+			uint16 length = _vm->_game->_script->readUint16();
+
 			inputs[inputCount].str =
-				(const char *) (_vm->_game->_script->getData() + _vm->_game->_script->pos() + 2);
-			_vm->_game->_script->skip(_vm->_game->_script->peekUint16() + 2);
+				(const char *) (_vm->_game->_script->getData() + _vm->_game->_script->pos());
+
+			_vm->_game->_script->skip(length);
 		}
 
 		if (left == 0xFFFF) {
-			if ((type & 1) == 0)
+			if (!(type & 1))
+				// No coordinates but a leave block => skip it
 				_vm->_game->_script->skipBlock();
 			break;
 		}
 
 		font = _vm->_draw->_fonts[inputs[inputCount].fontIndex];
 		if (!font->charWidths)
+			// Monospaced font
 			right = left + width * font->itemWidth - 1;
 
 		funcEnter = 0;
 		funcPos   = 0;
 		funcLeave = 0;
 		if (!(type & 1)) {
+			// Got a leave
 			funcLeave = _vm->_game->_script->pos();
 			_vm->_game->_script->skipBlock();
 		}
@@ -1215,6 +1329,7 @@
 		break;
 	}
 
+	// Add the new hotspot
 	add(i | (kStateFilled << 12), left, top, right, bottom,
 			flags, key, funcEnter, funcLeave, funcPos);
 }
@@ -1227,8 +1342,10 @@
 	int16 var_26;
 	int16 collStackPos;
 
+	// Push all local hotspots
 	push(0);
 
+	// Find the current end of the hotspot block
 	uint16 endIndex = 0;
 	while (!_hotspots[endIndex].isEnd())
 		endIndex++;
@@ -1237,15 +1354,19 @@
 
 	_vm->_game->_script->skip(1);
 
+	// Number of new hotspots
 	byte count = _vm->_game->_script->readByte();
 
-	_vm->_game->_handleMouse           = _vm->_game->_script->peekByte(0);
-	int16 duration         = _vm->_game->_script->peekByte(1);
-	byte stackPos2         = _vm->_game->_script->peekByte(3);
-	byte descIndex         = _vm->_game->_script->peekByte(4);
-	bool needRecalculation = _vm->_game->_script->peekByte(5) != 0;
+	// Parameters of this block
+	_vm->_game->_handleMouse = _vm->_game->_script->peekByte(0);
+	int16 duration           = _vm->_game->_script->peekByte(1);
+	byte stackPos2           = _vm->_game->_script->peekByte(3);
+	byte descIndex           = _vm->_game->_script->peekByte(4);
+	bool needRecalculation   = _vm->_game->_script->peekByte(5) != 0;
 
+	// Seconds -> Milliseconds
 	duration *= 1000;
+
 	if ((stackPos2 != 0) || (descIndex != 0)) {
 		duration /= 100;
 		if (_vm->_game->_script->peekByte(1) == 100)
@@ -1256,6 +1377,7 @@
 
 	_vm->_game->_script->skip(6);
 
+	// Clear current ID
 	WRITE_VAR(16, 0);
 
 	byte var_41 = 0;
@@ -1267,9 +1389,12 @@
 
 	bool   hasInput   = false;
 	uint16 inputCount = 0;
+
+	// Adding new hotspots
 	for (uint16 i = 0; i < count; i++)
 		evaluateNew(i, ids, inputs, validId, hasInput, inputCount);
 
+	// Recalculate all hotspots if requested
 	if (needRecalculation)
 		recalculate(true);
 
@@ -1279,22 +1404,29 @@
 	do {
 		uint16 key = 0;
 		if (hasInput) {
+			// Input
+
 			uint16 curInput = 0;
 
-			key = handleInput(duration, inputCount, curInput, inputs, id, index);
+			key = handleInputs(duration, inputCount, curInput, inputs, id, index);
 
+			// Notify the script of the current input index
 			WRITE_VAR(55, curInput);
 			if (key == kKeyReturn) {
+				// Return pressed, invoke input leave
 				for (int i = 0; (i < kHotspotCount) && !_hotspots[i].isEnd(); i++) {
 					Hotspot &spot = _hotspots[i];
 
 					if (!spot.isFilledEnabled())
+						// Not filled or disabled
 						continue;
 
 					if ((spot.getType() & 1) != 0)
+						// Not an input with a leave function
 						continue;
 
 					if (spot.getType() <= kTypeClick)
+						// Not an input
 						continue;
 
 					id      = spot.id;
@@ -1305,20 +1437,29 @@
 				break;
 			}
 		} else
+			// Normal move or click check
 			key = check(_vm->_game->_handleMouse, -duration, id, index);
 
+		// Handle special number keys
 		if (((key & 0xFF) >= ' ') && ((key & 0xFF) <= 0xFF) &&
 		    ((key >> 8) > 1) && ((key >> 8) < 12))
 			key = '0' + (((key >> 8) - 1) % 10) + (key & 0xFF00);
 
 		if (id == 0) {
+			// No hotspot area
+
 			if (key != 0) {
+				// But a key
+
+				// Find the hotspot with that key associated
 				for (int i = 0; (i < kHotspotCount) && !_hotspots[i].isEnd(); i++) {
 					Hotspot &spot = _hotspots[i];
 
 					if (!spot.isFilledEnabled())
+						// Not filled or disabled
 						continue;
 
+					//      Key match              Catch all
 					if ((spot.key == key) || (spot.key == 0x7FFF)) {
 						id    = spot.id;
 						index = i;
@@ -1327,6 +1468,9 @@
 				}
 
 				if (id == 0) {
+					// Didn't find such a hotspot
+
+					// Try it again, this time case insensitively
 					for (int i = 0; (i < kHotspotCount) && !_hotspots[i].isEnd(); i++) {
 						Hotspot &spot = _hotspots[i];
 
@@ -1358,26 +1502,33 @@
 
 						collStackPos++;
 						if (collStackPos != stackPos2)
+							// Isn't yet the one wanted
 							continue;
 
 						id    = spot.id;
 						index = i;
 						_vm->_inter->storeMouse();
 						if (VAR(16) != 0)
+							// We already handle a hotspot
 							break;
 
+						// Notify the scripts that we now handle this hotspot
 						if (Hotspot::getState(id) == kStateFilled)
 							WRITE_VAR(16, ids[id & 0xFFF]);
 						else
 							WRITE_VAR(16, id & 0xFFF);
 
 						if (spot.funcLeave != 0) {
+							// It has a leave function
+
 							uint32 timeKey = _vm->_util->getTimeKey();
 							call(spot.funcLeave);
 
 							if (timeVal != 2) {
+								// Rest time we have left = time we had - time the leave took
 								duration = timeVal - (_vm->_util->getTimeKey() - timeKey);
 
+								// Remove the buffer time
 								if ((duration - var_46) < 3) {
 									var_46 -= (duration - 3);
 									duration = 3;
@@ -1386,6 +1537,7 @@
 									var_46 = 0;
 								}
 
+								// Clamp
 								if (duration > timeVal)
 									duration = timeVal;
 
@@ -1395,6 +1547,7 @@
 						}
 
 						if (VAR(16) == 0)
+							// Didn't find anything
 							id = 0;
 						else
 							var_41 = 1;
@@ -1406,6 +1559,7 @@
 					if (descIndex != 0) {
 
 						counter = 0;
+						// Enter the nth hotspot
 						for (int i = endIndex; (i < kHotspotCount) && !_hotspots[i].isEnd(); i++) {
 							Hotspot &spot = _hotspots[i];
 
@@ -1421,6 +1575,7 @@
 
 					} else {
 
+						// Enter the first hotspot
 						for (int i = 0; (i < kHotspotCount) && !_hotspots[i].isEnd(); i++) {
 							Hotspot &spot = _hotspots[i];
 
@@ -1431,6 +1586,7 @@
 							}
 						}
 
+						// Leave the current hotspot
 						if ((_currentKey != 0) && (_hotspots[_currentIndex].funcLeave != 0))
 							call(_hotspots[_currentIndex].funcLeave);
 
@@ -1445,15 +1601,18 @@
 			break;
 
 		if ((id == 0) || (_hotspots[index].funcLeave != 0))
+			// We don't have a new ID, but haven't yet handled the leave function
 			continue;
 
 		_vm->_inter->storeMouse();
 
+		// Notify the scripts of the currently handled hotspot
 		if (Hotspot::getState(id) == kStateFilled)
 			WRITE_VAR(16, ids[id & 0xFFF]);
 		else
 			WRITE_VAR(16, id & 0xFFF);
 
+		// Enter it
 		if (_hotspots[index].funcEnter != 0)
 			call(_hotspots[index].funcEnter);
 
@@ -1470,23 +1629,30 @@
 		for (int i = 0; i < kHotspotCount; i++) {
 			Hotspot &spot = _hotspots[i];
 
+			// Looking for all enabled inputs
 			if (spot.isEnd())
 				continue;
-
 			if (!spot.isFilledEnabled())
 				continue;
-
 			if (!spot.isInput())
 				continue;
 
-			if (spot.getType() > kTypeInput3Leave) {
+			// Clean up numerical floating values
+			if (spot.getType() >= kTypeInputFloatNoLeave) {
+				// Get the string
 				char *ptr;
 				strncpy0(tempStr, GET_VARO_STR(spot.key), 255);
+
+				// Remove spaces
 				while ((ptr = strchr(tempStr, ' ')))
 					_vm->_util->cutFromStr(tempStr, (ptr - tempStr), 1);
+
+				// Exchange decimal separator if needed
 				if (_vm->_global->_language == kLanguageBritish)
 					while ((ptr = strchr(tempStr, '.')))
 						*ptr = ',';
+
+				// Write it back
 				WRITE_VARO_STR(spot.key, tempStr);
 			}
 
@@ -1498,6 +1664,7 @@
 				if (spot.getType() < kTypeInput3NoLeave)
 					_vm->_util->cleanupStr(tempStr);
 
+				// Look if we find a match between the wanted and the typed string
 				int16 pos = 0;
 				do {
 					char spotStr[256];
@@ -1510,20 +1677,23 @@
 					if (spot.getType() < kTypeInput3NoLeave)
 						_vm->_util->cleanupStr(spotStr);
 
+					// Compare the entered string with the string we wanted
 					if (strcmp(tempStr, spotStr) == 0) {
 						WRITE_VAR(17, VAR(17) + 1);
 						WRITE_VAR(17 + var_26, 1);
 						break;
 					}
-				} while (READ_LE_UINT16(inputs[var_24].str - 2) > pos);
+				} while (inputs[var_24].length > pos);
+
 				collStackPos++;
-			} else {
+			} else
 				WRITE_VAR(17 + var_26, 2);
-			}
+
 			var_24++;
 			var_26++;
 		}
 
+		// Notify the scripts if we reached the requested hotspot
 		if (collStackPos != (int16) VAR(17))
 			WRITE_VAR(17, 0);
 		else
@@ -1538,6 +1708,8 @@
 
 		_vm->_inter->storeMouse();
 		if (VAR(16) == 0) {
+			// No hotspot currently handled, now we'll handle the newly found one
+
 			if (Hotspot::getState(id) == kStateFilled)
 				WRITE_VAR(16, ids[id & 0xFFF]);
 			else
@@ -1547,14 +1719,16 @@
 		_vm->_game->_script->setFinished(true);
 
 	for (int i = 0; i < count; i++)
+		// Remove all local hotspots
 		remove(i + (kStateFilled << 12));
 
 	for (int i = 0; i < kHotspotCount; i++) {
 		Hotspot &spot = _hotspots[i];
 
-	if ((spot.getState() == (kStateFilled | kStateType1)) ||
-	    (spot.getState() == (kStateFilled | kStateType2)))
-			spot.disable();
+		// Disable the ones still there
+		if ((spot.getState() == (kStateFilled | kStateType1)) ||
+				(spot.getState() == (kStateFilled | kStateType2)))
+				spot.disable();
 	}
 
 }
@@ -1566,58 +1740,94 @@
 		Hotspot &spot = _hotspots[i];
 
 		if ((spot.getWindow() != 0) || spot.isDisabled())
+			// Ignore disabled and non-main-windowed hotspots
 			continue;
 
 		if (!spot.isIn(x, y))
+			// We're not in that hotspot, ignore it
 			continue;
 
 		if (spot.getCursor() == 0) {
+			// Hotspot doesn't itself specify a cursor...
 			if (spot.getType() >= kTypeInput1NoLeave) {
+				// ...but the type has a generic one
 				cursor = 3;
 				break;
 			} else if ((spot.getButton() != kMouseButtonsRight) && (cursor == 0))
+				// ...but there's a generic "click" cursor
 				cursor = 1;
 		} else if (cursor == 0)
+			// Hotspot had an attached cursor index
 			cursor = spot.getCursor();
 	}
 
 	return cursor;
 }
 
-uint16 Hotspots::findInput(uint16 input) const {
+uint16 Hotspots::inputToHotspot(uint16 input) const {
 	uint16 inputIndex = 0;
 	for (int i = 0; i < kHotspotCount; i++) {
 		Hotspot &spot = _hotspots[i];
 
 		if (!spot.isActiveInput())
+			// Not an active input
 			continue;
 
 		if (inputIndex == input)
+			// We've found our input
 			return i;
 
+		// Next one
 		inputIndex++;
 	}
 
+	// None found
 	return 0xFFFF;
 }
 
+uint16 Hotspots::hotspotToInput(uint16 hotspot) const {
+	uint16 input = 0;
+
+	for (int i = 0; i < kHotspotCount; i++) {
+		Hotspot &spot = _hotspots[i];
+
+		if (!spot.isActiveInput())
+			// Not an active input
+			continue;
+
+		if (i == hotspot)
+			// We've found our hotspot
+			break;
+
+		// Next one
+		input++;
+	}
+
+	return input;
+}
+
 uint16 Hotspots::findClickedInput(uint16 index) const {
 	for (int i = 0; (i < kHotspotCount) && !_hotspots[i].isEnd(); i++) {
 		Hotspot &spot = _hotspots[i];
 
 		if (spot.getWindow() != 0)
+			// Ignore other windows
 			continue;
 
 		if (spot.isDisabled())
+			// Ignore disabled hotspots
 			continue;
 
 		if (!spot.isIn(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY))
+			// This one wasn't it
 			continue;
 
 		if (spot.getCursor() != 0)
+			// This one specifies a cursor, so we don't want it
 			continue;
 
 		if (!spot.isInput())
+			// It's no input
 			continue;
 
 		index = i;
@@ -1627,24 +1837,6 @@
 	return index;
 }
 
-uint16 Hotspots::findNthInput(uint16 n) const {
-	uint16 input = 0;
-
-	for (int i = 0; i < kHotspotCount; i++) {
-		Hotspot &spot = _hotspots[i];
-
-		if (!spot.isActiveInput())
-			continue;
-
-		if (i == n)
-			break;
-
-		input++;
-	}
-
-	return input;
-}
-
 void Hotspots::getTextCursorPos(const Video::FontDesc &font, const char *str,
 		uint32 pos, uint16 x, uint16 y, uint16 width, uint16 height,
 		uint16 &cursorX, uint16 &cursorY, uint16 &cursorWidth, uint16 &cursorHeight) const {
@@ -1657,6 +1849,7 @@
 		cursorWidth  = 1;
 		cursorHeight = height;
 
+		// Iterate through the string and add each character's width
 		for (uint32 i = 0; i < pos; i++)
 			cursorX += font.charWidths[str[i] - font.startItem];
 
@@ -1699,25 +1892,33 @@
 		const Hotspot &spot = _hotspots[i];
 
 		if (spot.isEnd())
+			// It's an end, we don't want it
 			continue;
 
 		if (!spot.isFilledEnabled())
+			// This one's either not used or disabled
 			continue;
 
 		if (!spot.isInput())
+			// Not an input
 			continue;
 
+		// Get its text
 		char tempStr[256];
 		strncpy0(tempStr, GET_VARO_STR(spot.key), 255);
 
+		// Coordinates
 		uint16 x      = spot.left;
 		uint16 y      = spot.top;
 		uint16 width  = spot.right  - spot.left + 1;
 		uint16 height = spot.bottom - spot.top  + 1;
+		// Clear the background
 		fillRect(x, y, width, height, inputs[input].backColor);
 
-		y += (width - _vm->_draw->_fonts[_vm->_draw->_fontIndex]->itemHeight) / 2;
+		// Center the text vertically
+		y += (height - _vm->_draw->_fonts[_vm->_draw->_fontIndex]->itemHeight) / 2;
 
+		// Draw it
 		printText(x, y, tempStr, inputs[input].fontIndex, inputs[input].frontColor);
 
 		input++;

Modified: scummvm/trunk/engines/gob/hotspots.h
===================================================================
--- scummvm/trunk/engines/gob/hotspots.h	2009-07-05 23:38:11 UTC (rev 42160)
+++ scummvm/trunk/engines/gob/hotspots.h	2009-07-06 01:41:29 UTC (rev 42161)
@@ -66,6 +66,7 @@
 	Hotspots(GobEngine *vm);
 	~Hotspots();
 
+	/** Remove all hotspots. */
 	void clear();
 
 	/** Add a hotspot, returning the new index. */
@@ -74,7 +75,9 @@
 			uint16 flags, uint16 key,
 			uint16 funcEnter, uint16 funcLeave, uint16 funcPos);
 
+	/** Remove a specific hotspot. */
 	void remove(uint16 id);
+	/** Remove all hotspots in this state. */
 	void removeState(uint8 state);
 
 	/** Push the current hotspots onto the stack.
@@ -86,11 +89,15 @@
 	/** Pop hotspots from the stack. */
 	void pop();
 
+	/** Check the current hotspot. */
 	uint16 check(uint8 handleMouse, int16 delay, uint16 &id, uint16 &index);
+	/** Check the current hotspot. */
 	uint16 check(uint8 handleMouse, int16 delay);
 
+	/** Evaluate hotspot changes. */
 	void evaluate();
 
+	/** Return the cursor found in the hotspot to the coordinates. */
 	int16 findCursor(uint16 x, uint16 y) const;
 
 private:
@@ -123,13 +130,13 @@
 		/** Is this hotspot the block end marker? */
 		bool isEnd() const;
 
-		bool isInput() const;
+		bool isInput()       const;
 		bool isActiveInput() const;
 
-		bool isFilled() const;
+		bool isFilled()        const;
 		bool isFilledEnabled() const;
-		bool isFilledNew() const;
-		bool isDisabled() const;
+		bool isFilledNew()     const;
+		bool isDisabled()      const;
 
 		/** Are the specified coordinates in the hotspot? */
 		bool isIn(uint16 x, uint16 y) const;
@@ -155,6 +162,7 @@
 		uint16 fontIndex;
 		uint16 backColor;
 		uint16 frontColor;
+		uint16 length;
 		const char *str;
 	};
 
@@ -178,6 +186,7 @@
 	 */
 	void recalculate(bool force);
 
+	/** Is this a valid hotspot? */
 	bool isValid(uint16 key, uint16 id, uint16 index) const;
 
 	/** Call a hotspot subroutine. */
@@ -190,32 +199,40 @@
 	/** Which hotspot is the mouse cursor currently at? */
 	uint16 checkMouse(Type type, uint16 &id, uint16 &index) const;
 
-	void checkHotspotChanged();
+	/** Did the current hotspot change in the meantime? */
+	bool checkHotspotChanged();
 
-	uint16 readString(uint16 xPos, uint16 yPos, uint16 width, uint16 height,
+	/** Update events from a specific input. */
+	uint16 updateInput(uint16 xPos, uint16 yPos, uint16 width, uint16 height,
 			uint16 backColor, uint16 frontColor, char *str, uint16 fontIndex,
-			Type type, int16 &duration, uint16 &id, uint16 index);
+			Type type, int16 &duration, uint16 &id, uint16 &index);
 
-	uint16 handleInput(int16 time, uint16 inputCount, uint16 &curInput,
+	/** Handle all inputs we currently manage. */
+	uint16 handleInputs(int16 time, uint16 inputCount, uint16 &curInput,
 			InputDesc *inputs, uint16 &id, uint16 &index);
 
+	/** Evaluate adding new hotspots script commands. */
 	void evaluateNew(uint16 i, uint16 *ids, InputDesc *inputs,
 			uint16 &validId, bool &hasInput, uint16 &inputCount);
 
-	// Finding certain inputs
-	uint16 findInput(uint16 input) const;
+	/** Find the hotspot index that corresponds to the input index. */
+	uint16 inputToHotspot(uint16 input) const;
+	/** Find the input index that corresponds to the hotspot index. */
+	uint16 hotspotToInput(uint16 hotspot) const;
+	/** Find the input that was clicked on. */
 	uint16 findClickedInput(uint16 index) const;
-	uint16 findNthInput(uint16 n) const;
 
 	/** Calculate the graphical cursor position. */
 	void getTextCursorPos(const Video::FontDesc &font, const char *str,
 			uint32 pos, uint16 x, uint16 y, uint16 width, uint16 height,
 			uint16 &cursorX, uint16 &cursorY, uint16 &cursorWidth, uint16 &cursorHeight) const;
 
-	// Drawing functions
+	/** Fill that rectangle with the color. */
 	void fillRect(uint16 x, uint16 y, uint16 width, uint16 height, uint16 color) const;
+	/** Print the given text. */
 	void printText(uint16 x, uint16 y, const char *str, uint16 fontIndex, uint16 color) const;
 
+	/** Go through all inputs we manage and redraw their texts. */
 	void updateAllTexts(const InputDesc *inputs) const;
 };
 


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