diff options
| author | Alyssa Milburn | 2010-12-05 16:19:52 +0000 | 
|---|---|---|
| committer | Alyssa Milburn | 2010-12-05 16:19:52 +0000 | 
| commit | f84b027e50e303edeb4bc341f76764b830ad35a7 (patch) | |
| tree | 0ac1e25eb4b73e0f17d5df4c90870a5532f72b06 | |
| parent | 9e6fe3bd888625de33c029998b0403ca7f0b48da (diff) | |
| download | scummvm-rg350-f84b027e50e303edeb4bc341f76764b830ad35a7.tar.gz scummvm-rg350-f84b027e50e303edeb4bc341f76764b830ad35a7.tar.bz2 scummvm-rg350-f84b027e50e303edeb4bc341f76764b830ad35a7.zip  | |
MOHAWK: read and use LB 2/3 conditions/commands
svn-id: r54778
| -rw-r--r-- | engines/mohawk/livingbooks.cpp | 99 | ||||
| -rw-r--r-- | engines/mohawk/livingbooks.h | 3 | 
2 files changed, 89 insertions, 13 deletions
diff --git a/engines/mohawk/livingbooks.cpp b/engines/mohawk/livingbooks.cpp index d874da7676..a8cdc661a3 100644 --- a/engines/mohawk/livingbooks.cpp +++ b/engines/mohawk/livingbooks.cpp @@ -1609,9 +1609,10 @@ void LBItem::readData(uint16 type, uint16 size, Common::SeekableSubReadStreamEnd  			entry->param = stream->readUint16();  			debug(4, "Script entry: type 0x%04x, action 0x%04x, opcode 0x%04x, param 0x%04x",  				entry->type, entry->action, entry->opcode, entry->param); +			size -= 6;  			if (type == kLBMsgListScript) { -				if (size < 8) +				if (size < 2)  					error("Script entry of type 0x%04x was too small (%d)", type, size);  				entry->argc = stream->readUint16(); @@ -1619,7 +1620,7 @@ void LBItem::readData(uint16 type, uint16 size, Common::SeekableSubReadStreamEnd  				entry->argvTarget = new uint16[entry->argc];  				debug(4, "With %d targets:", entry->argc); -				if (size < (8 + entry->argc * 4)) +				if (size < (2 + entry->argc * 4))  					error("Script entry of type 0x%04x was too small (%d)", type, size);  				for (uint i = 0; i < entry->argc; i++) { @@ -1628,19 +1629,74 @@ void LBItem::readData(uint16 type, uint16 size, Common::SeekableSubReadStreamEnd  					debug(4, "Target %d, param 0x%04x", entry->argvTarget[i], entry->argvParam[i]);  				} -				if (size > (8 + entry->argc * 4)) { -					// TODO -					warning("Skipping %d probably-important bytes", size - (8 + entry->argc * 4)); -					stream->skip(size - (8 + entry->argc * 4)); +				size -= (2 + entry->argc * 4); +			} + +			if (type == kLBNotifyScript && entry->opcode == kLBNotifyQuit) { +				if (size < 8) { +					error("%d unknown bytes in notify entry 0x%04x", size, entry->opcode);  				} -			} else { -				if (size > 6) { -					// TODO -					warning("Skipping %d probably-important bytes", size - 6); -					stream->skip(size - 6); +				uint16 opcodeId = stream->readUint16(); +				uint16 modeId = stream->readUint16(); +				uint16 pageId = stream->readUint16(); +				uint16 subPageId = stream->readUint16(); +				// FIXME +				warning("unknown notify: opcode %04x, mode %d, page %d.%d", opcodeId, modeId, pageId, subPageId); +				size -= 8; +			} +			if (entry->action == 7) { +				if (size < 4) +					error("not enough bytes (%d) in action 7, opcode 0x%04x", size, entry->opcode); +				// FIXME: meh +				size -= 4; +				uint16 itemId = stream->readUint16(); +				uint16 unknown = stream->readUint16(); +				warning("ignoring id %d, unknown 0x%04x in script entry (type 0x%04x, action 0x%04x, opcode 0x%04x)", itemId, unknown, entry->type, entry->action, entry->opcode); +			} +			if (entry->opcode == 0xffff) { +				if (size < 4) +					error("didn't get enough bytes (%d) to read command in script entry", size); +				size -= 4; + +				uint16 msgId = stream->readUint16(); +				if (msgId != kLBCommand) +					error("expected a command in script entry, got 0x%04x", msgId); +				uint16 msgLen = stream->readUint16(); +				if (msgLen != size) +					error("script entry msgLen %d is not equal to size %d", msgLen, size); + +				Common::String command = readString(stream); +				if (command.size() + 1 > size) { +					error("failed to read command in script entry: msgLen %d, command '%s' (%d chars)", +						msgLen, command.c_str(), command.size());  				} +				size -= command.size() + 1; + +				entry->command = command; +				debug(4, "script entry command '%s'", command.c_str()); +			} else if (size) { +				byte commandLen = stream->readByte(); +				if (commandLen) +					error("got confused while reading bytes at end of script entry"); +				size--;  			} +			while (size) { +				Common::String condition = readString(stream); +				if (condition.size() + 1 > size) +					error("failed to read condition (ran out of stream)"); +				size -= (condition.size() + 1); + +				entry->conditions.push_back(condition); +				debug(4, "script entry condition '%s'", condition.c_str()); +			} + +			// TODO: read as bytes, if this is correct (but beware endianism) +			byte expectedConditions = (entry->action & 0xff00) >> 8; +			entry->action = entry->action & 0xff; +			if (entry->conditions.size() != expectedConditions) +				error("got %d conditions, but expected %d", entry->conditions.size(), expectedConditions); +  			_scriptEntries.push_back(entry);  		}  		break; @@ -1700,8 +1756,8 @@ void LBItem::readData(uint16 type, uint16 size, Common::SeekableSubReadStreamEnd  			Common::String command = readString(stream);  			if (size != command.size() + 1)  				error("failed to read command string"); -			// FIXME -			warning("ignoring command '%s'", command.c_str()); + +			runCommand(command);  		}  		break; @@ -1957,7 +2013,20 @@ void LBItem::runScript(uint id) {  		if (entry->action != id)  			continue; +		bool conditionsMatch = true; +		for (uint n = 0; n < entry->conditions.size(); n++) { +			if (!checkCondition(entry->conditions[n])) { +				conditionsMatch = false; +				break; +			} +		} +		if (!conditionsMatch) +			continue; +  		if (entry->type == kLBNotifyScript) { +			debug(2, "Notify: action 0x%04x, opcode 0x%04x, param 0x%04x", +				entry->action, entry->opcode, entry->param); +  			if (entry->opcode == kLBNotifyGUIAction)  				_vm->addNotifyEvent(NotifyEvent(entry->opcode, _itemId));  			else @@ -1983,6 +2052,10 @@ void LBItem::runScript(uint id) {  					continue;  				switch (entry->opcode) { +				case 0xffff: +					runCommand(entry->command); +					break; +  				case 1:  					// TODO: should be setVisible(true) - not a delayed event -  					// when we're doing the param 1/2/3 stuff above? diff --git a/engines/mohawk/livingbooks.h b/engines/mohawk/livingbooks.h index 862c682048..8a06e8bc2b 100644 --- a/engines/mohawk/livingbooks.h +++ b/engines/mohawk/livingbooks.h @@ -151,6 +151,9 @@ struct LBScriptEntry {  	uint16 argc;  	uint16 *argvParam;  	uint16 *argvTarget; + +	Common::String command; +	Common::Array<Common::String> conditions;  };  struct LBAnimScriptEntry {  | 
