[Scummvm-git-logs] scummvm master -> 54980c1f6bcde27e6c6bf96061fdee65ab174641

dreammaster paulfgilbert at gmail.com
Sat Oct 17 05:12:09 UTC 2020


This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
49f6ee2868 GLK: COMPREHEND: Verify more v2 opcodes
b6183f85d7 GLK: COMPREHEND: Fix script dumper for v2
3933d43dd0 GLK: COMPREHEND: Implementing string replacement and other opcodes
54980c1f6b GLK: COMPREHEND: Added item flag manipulation opcodes


Commit: 49f6ee28683f116cc1f62fc250388544cb386c68
    https://github.com/scummvm/scummvm/commit/49f6ee28683f116cc1f62fc250388544cb386c68
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-10-16T21:22:37-07:00

Commit Message:
GLK: COMPREHEND: Verify more v2 opcodes

Changed paths:
    engines/glk/comprehend/debugger_dumper.cpp
    engines/glk/comprehend/game.cpp
    engines/glk/comprehend/game.h
    engines/glk/comprehend/game_data.h
    engines/glk/comprehend/game_opcodes.cpp
    engines/glk/comprehend/game_opcodes.h


diff --git a/engines/glk/comprehend/debugger_dumper.cpp b/engines/glk/comprehend/debugger_dumper.cpp
index cb60acacb1..70343fe24a 100644
--- a/engines/glk/comprehend/debugger_dumper.cpp
+++ b/engines/glk/comprehend/debugger_dumper.cpp
@@ -102,7 +102,6 @@ DebuggerDumper::DebuggerDumper() : _game(nullptr) {
 	_opcodes[OPCODE_DESCRIBE_CURRENT_OBJECT] = "describe_current_object";
 	_opcodes[OPCODE_SET_STRING_REPLACEMENT] = "set_string_replacement";
 	_opcodes[OPCODE_SET_CURRENT_NOUN_STRING_REPLACEMENT] = "set_current_noun_string_replacement";
-	_opcodes[OPCODE_CURRENT_NOT_OBJECT] = "current_not_object";
 	_opcodes[OPCODE_CURRENT_IS_OBJECT] = "current_is_object";
 	_opcodes[OPCODE_DRAW_ROOM] = "draw_room";
 	_opcodes[OPCODE_DRAW_OBJECT] = "draw_object";
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index a6f31fa92c..895b2c0ee0 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -505,11 +505,8 @@ void ComprehendGame::move_object(Item *item, int new_room) {
 
 void ComprehendGame::eval_instruction(FunctionState *func_state,
 		const Function &func, uint functionOffset, const Sentence *sentence) {
-	Room *room = nullptr;
-	Item *item = nullptr;
 
 	const Instruction *instr = &func[functionOffset];
-	room = get_room(_currentRoom);
 
 	if (DebugMan.isDebugChannelEnabled(kDebugScripts)) {
 		Common::String line;
@@ -556,7 +553,7 @@ void ComprehendGame::eval_instruction(FunctionState *func_state,
 		}
 	}
 
-	execute_opcode(instr, sentence, func_state, room, item);
+	execute_opcode(instr, sentence, func_state);
 }
 
 void ComprehendGame::eval_function(uint functionNum, const Sentence *sentence) {
diff --git a/engines/glk/comprehend/game.h b/engines/glk/comprehend/game.h
index 9a8e8b5d25..c123c922b0 100644
--- a/engines/glk/comprehend/game.h
+++ b/engines/glk/comprehend/game.h
@@ -91,7 +91,7 @@ protected:
 	virtual bool handle_restart();
 
 	virtual void execute_opcode(const Instruction *instr, const Sentence *sentence,
-		FunctionState *func_state, Room *room, Item *&item) = 0;
+		FunctionState *func_state) = 0;
 
 	int console_get_key();
 	void console_println(const char *text);
diff --git a/engines/glk/comprehend/game_data.h b/engines/glk/comprehend/game_data.h
index 6f02ed2554..70bae48ab2 100644
--- a/engines/glk/comprehend/game_data.h
+++ b/engines/glk/comprehend/game_data.h
@@ -49,7 +49,7 @@ enum {
 };
 
 
-enum {
+enum ScriptOpcode {
 	OPCODE_UNKNOWN,
 	OPCODE_HAVE_OBJECT,
 	OPCODE_OR,
@@ -118,7 +118,6 @@ enum {
 	OPCODE_DESCRIBE_CURRENT_OBJECT,
 	OPCODE_SET_STRING_REPLACEMENT,
 	OPCODE_SET_CURRENT_NOUN_STRING_REPLACEMENT,
-	OPCODE_CURRENT_NOT_OBJECT,
 	OPCODE_CURRENT_IS_OBJECT,
 	OPCODE_DRAW_ROOM,
 	OPCODE_DRAW_OBJECT,
diff --git a/engines/glk/comprehend/game_opcodes.cpp b/engines/glk/comprehend/game_opcodes.cpp
index ce8a2cfd57..bb28f1710f 100644
--- a/engines/glk/comprehend/game_opcodes.cpp
+++ b/engines/glk/comprehend/game_opcodes.cpp
@@ -30,47 +30,58 @@ namespace Glk {
 namespace Comprehend {
 
 ComprehendGameOpcodes::ComprehendGameOpcodes() {
-	Common::fill(&_opcodeMap[0], &_opcodeMap[0x100], 0);
+	Common::fill(&_opcodeMap[0], &_opcodeMap[0x100], (ScriptOpcode)0);
 }
 
 void ComprehendGameOpcodes::execute_opcode(const Instruction *instr, const Sentence *sentence,
-		FunctionState *func_state, Room *room, Item *&item) {
-	byte verb = sentence ? sentence->_formattedWords[0] : 0;
+		FunctionState *func_state) {
+//	byte verb = sentence ? sentence->_formattedWords[0] : 0;
 	byte noun = sentence ? sentence->_formattedWords[2] : 0;
+	Room *room = get_room(_currentRoom);
 	uint index;
 
-	switch (_opcodeMap[instr->_opcode]) {
-	case OPCODE_OR:
-		if (func_state->_orCount) {
-			func_state->_orCount += 2;
-		} else {
-			func_state->_testResult = false;
-			func_state->_orCount += 3;
-		}
+	byte opcode = getOpcode(instr);
+	switch (_opcodeMap[opcode]) {
+	case OPCODE_CALL_FUNC:
+		index = instr->_operand[0];
+		if (instr->_operand[1] == 0x81)
+			index += 256;
+		if (index >= _functions.size())
+			error("Bad function %.4x >= %.4x\n",
+				index, _functions.size());
+
+		eval_function(index, sentence);
 		break;
 
-	case OPCODE_IN_ROOM:
+	case OPCODE_CURRENT_IS_OBJECT:
 		func_set_test_result(func_state,
-			_currentRoom == instr->_operand[0]);
+			get_item_by_noun(noun) != NULL);
 		break;
 
-	case OPCODE_VAR_EQ2:
-		func_set_test_result(func_state,
-			_variables[instr->_operand[0]] ==
-			_variables[instr->_operand[1]]);
+	case OPCODE_CURRENT_OBJECT_NOT_VALID:
+		func_set_test_result(func_state, !noun);
 		break;
 
 	case OPCODE_ELSE:
 		func_state->_testResult = func_state->_elseResult;
 		break;
 
-	case OPCODE_CURRENT_OBJECT_NOT_VALID:
-		func_set_test_result(func_state, !noun);
+	case OPCODE_IN_ROOM:
+		func_set_test_result(func_state,
+			_currentRoom == instr->_operand[0]);
 		break;
 
-	case OPCODE_TEST_FLAG:
-		func_set_test_result(func_state,
-			_flags[instr->_operand[0]]);
+	case OPCODE_OR:
+		if (func_state->_orCount) {
+			func_state->_orCount += 2;
+		} else {
+			func_state->_testResult = false;
+			func_state->_orCount += 3;
+		}
+		break;
+
+	case OPCODE_PRINT:
+		console_println(instrStringLookup(instr->_operand[0], instr->_operand[1]).c_str());
 		break;
 
 	case OPCODE_SET_ROOM_DESCRIPTION:
@@ -92,23 +103,22 @@ void ComprehendGameOpcodes::execute_opcode(const Instruction *instr, const Sente
 		}
 		break;
 
-	case OPCODE_CALL_FUNC:
-		index = instr->_operand[0];
-		if (instr->_operand[1] == 0x81)
-			index += 256;
-		if (index >= _functions.size())
-			error("Bad function %.4x >= %.4x\n",
-				index, _functions.size());
+	case OPCODE_TEST_FLAG:
+		func_set_test_result(func_state,
+			_flags[instr->_operand[0]]);
+		break;
 
-		eval_function(index, sentence);
+	case OPCODE_VAR_EQ2:
+		func_set_test_result(func_state,
+			_variables[instr->_operand[0]] ==
+			_variables[instr->_operand[1]]);
 		break;
 
 	default:
 		if (instr->_opcode & 0x80) {
-			warning("Unhandled command opcode %.2x", instr->_opcode);
+			warning("Unhandled command opcode %.2x", opcode);
 		} else {
-			warning("Unhandled test opcode %.2x - returning false",
-				instr->_opcode);
+			warning("Unhandled test opcode %.2x - returning false", opcode);
 			func_set_test_result(func_state, false);
 		}
 		break;
@@ -208,12 +218,14 @@ ComprehendGameV1::ComprehendGameV1() {
 }
 
 void ComprehendGameV1::execute_opcode(const Instruction *instr, const Sentence *sentence,
-		FunctionState *func_state, Room *room, Item *&item) {
+		FunctionState *func_state) {
 	byte verb = sentence ? sentence->_formattedWords[0] : 0;
 	byte noun = sentence ? sentence->_formattedWords[2] : 0;
+	Room *room = get_room(_currentRoom);
+	Item *item;
 	uint count;
 
-	switch (_opcodeMap[instr->_opcode]) {
+	switch (_opcodeMap[getOpcode(instr)]) {
 	case OPCODE_VAR_ADD:
 		_variables[instr->_operand[0]] +=
 			_variables[instr->_operand[1]];
@@ -266,12 +278,6 @@ void ComprehendGameV1::execute_opcode(const Instruction *instr, const Sentence *
 		_variables[VAR_TURN_COUNT]++;
 		break;
 
-	case OPCODE_PRINT:
-		console_println(instrStringLookup(
-			instr->_operand[0], instr->_operand[1])
-			.c_str());
-		break;
-
 	case OPCODE_TEST_NOT_ROOM_FLAG:
 		func_set_test_result(func_state,
 			!(room->_flags & instr->_operand[0]));
@@ -344,10 +350,8 @@ void ComprehendGameV1::execute_opcode(const Instruction *instr, const Sentence *
 	case OPCODE_INVENTORY_FULL:
 		item = get_item_by_noun(noun);
 
-		func_set_test_result(func_state,
-			_variables[VAR_INVENTORY_WEIGHT] +
-			(item->_flags & ITEMF_WEIGHT_MASK) >
-			_variables[VAR_INVENTORY_LIMIT]);
+		func_set_test_result(func_state, _variables[VAR_INVENTORY_WEIGHT] +
+			(item->_flags & ITEMF_WEIGHT_MASK) > _variables[VAR_INVENTORY_LIMIT]);
 		break;
 
 	case OPCODE_DESCRIBE_CURRENT_OBJECT:
@@ -460,16 +464,6 @@ void ComprehendGameV1::execute_opcode(const Instruction *instr, const Sentence *
 			item->_room == _currentRoom);
 		break;
 
-	case OPCODE_CURRENT_IS_OBJECT:
-		func_set_test_result(func_state,
-			get_item_by_noun(noun) != NULL);
-		break;
-
-	case OPCODE_CURRENT_NOT_OBJECT:
-		func_set_test_result(func_state,
-			get_item_by_noun(noun) == NULL);
-		break;
-
 	case OPCODE_REMOVE_OBJECT:
 		item = get_item(instr->_operand[0] - 1);
 		move_object(item, ROOM_NOWHERE);
@@ -647,7 +641,7 @@ void ComprehendGameV1::execute_opcode(const Instruction *instr, const Sentence *
 		break;
 
 	default:
-		ComprehendGameOpcodes::execute_opcode(instr, sentence, func_state, room, item);
+		ComprehendGameOpcodes::execute_opcode(instr, sentence, func_state);
 		break;
 	}
 }
@@ -658,17 +652,19 @@ ComprehendGameV2::ComprehendGameV2() {
 	_opcodeMap[0x04] = OPCODE_OR;
 	_opcodeMap[0x05] = OPCODE_IN_ROOM;
 	_opcodeMap[0x06] = OPCODE_VAR_EQ2;
+	_opcodeMap[0x08] = OPCODE_CURRENT_IS_OBJECT;
 	_opcodeMap[0x0c] = OPCODE_ELSE;
 	_opcodeMap[0x14] = OPCODE_CURRENT_OBJECT_NOT_VALID;
 	_opcodeMap[0x19] = OPCODE_TEST_FLAG;
+	_opcodeMap[0x25] = OPCODE_NOT_MAX_WEIGHT;
 	_opcodeMap[0x87] = OPCODE_SET_ROOM_DESCRIPTION;
+	_opcodeMap[0x8e] = OPCODE_PRINT;
 	_opcodeMap[0x92] = OPCODE_CALL_FUNC;
 	_opcodeMap[0xa9] = OPCODE_CLEAR_INVISIBLE;
 
 #if 0
 	_opcodeMap[0x01] = OPCODE_HAVE_OBJECT;
 	_opcodeMap[0x02] = OPCODE_VAR_GT2;
-	_opcodeMap[0x08] = OPCODE_CURRENT_IS_OBJECT;
 	_opcodeMap[0x09] = OPCODE_VAR_GT1;
 	_opcodeMap[0x0a] = OPCODE_VAR_GTE2;
 	_opcodeMap[0x0d] = OPCODE_VAR_EQ1;
@@ -690,7 +686,6 @@ ComprehendGameV2::ComprehendGameV2() {
 	_opcodeMap[0x60] = OPCODE_NOT_HAVE_CURRENT_OBJECT;
 	_opcodeMap[0x61] = OPCODE_OBJECT_NOT_PRESENT;
 	_opcodeMap[0x70] = OPCODE_CURRENT_OBJECT_NOT_PRESENT;
-	_opcodeMap[0x74] = OPCODE_CURRENT_NOT_OBJECT;
 	_opcodeMap[0x80] = OPCODE_INVENTORY;
 	_opcodeMap[0x81] = OPCODE_TAKE_OBJECT;
 	_opcodeMap[0x82] = OPCODE_MOVE_OBJECT_TO_ROOM;
@@ -701,7 +696,6 @@ ComprehendGameV2::ComprehendGameV2() {
 	_opcodeMap[0x8a] = OPCODE_VAR_SUB;
 	_opcodeMap[0x8b] = OPCODE_SET_OBJECT_DESCRIPTION;
 	_opcodeMap[0x8c] = OPCODE_MOVE_DEFAULT;
-	_opcodeMap[0x8e] = OPCODE_PRINT;
 	_opcodeMap[0x8f] = OPCODE_SET_OBJECT_LONG_DESCRIPTION;
 	_opcodeMap[0x90] = OPCODE_WAIT_KEY;
 	_opcodeMap[0x95] = OPCODE_REMOVE_OBJECT;
@@ -732,36 +726,47 @@ ComprehendGameV2::ComprehendGameV2() {
 }
 
 void ComprehendGameV2::execute_opcode(const Instruction *instr, const Sentence *sentence,
-		FunctionState *func_state, Room *room, Item *&item) {
+		FunctionState *func_state) {
 	byte noun = sentence ? sentence->_formattedWords[2] : 0;
+	Item *item;
 
-	// Special pre-processing for opcodes
-	byte opcode = instr->_opcode;
-	if ((opcode & 0x30) == 0x30) {
-		// TODO: Check if getCurrentObjectRoom call in original is needed in ScummVM
-		opcode = (opcode & ~0x10) + 1;
-	}
+	switch (_opcodeMap[getOpcode(instr)]) {
+	case OPCODE_CLEAR_INVISIBLE:
+		item = get_item_by_noun(noun);
+		item->_flags &= ~ITEMF_INVISIBLE;
+		break;
 
-	switch (_opcodeMap[opcode]) {
 	case OPCODE_INVENTORY_FULL:
 		item = get_item_by_noun(noun);
 
 		weighInventory();
-		func_set_test_result(func_state,
-			_totalInventoryWeight + (item->_flags & ITEMF_WEIGHT_MASK) <
+		func_set_test_result(func_state, _totalInventoryWeight + (item->_flags & ITEMF_WEIGHT_MASK) <
 			_variables[VAR_INVENTORY_LIMIT]);
 		break;
 
-	case OPCODE_CLEAR_INVISIBLE:
+	case OPCODE_NOT_MAX_WEIGHT:
 		item = get_item_by_noun(noun);
-		item->_flags &= ~ITEMF_INVISIBLE;
+		func_set_test_result(func_state, (item->_flags & ITEMF_WEIGHT_MASK) != ITEMF_WEIGHT_MASK);
 		break;
 
 	default:
-		ComprehendGameOpcodes::execute_opcode(instr, sentence, func_state, room, item);
+		ComprehendGameOpcodes::execute_opcode(instr, sentence, func_state);
 		break;
 	}
 }
 
+byte ComprehendGameV2::getOpcode(const Instruction *instr) {
+	// Special pre-processing for opcodes
+	byte opcode = instr->_opcode;
+	if (!(opcode & 0x80))
+		opcode &= 0x3f;
+	if ((opcode & 0x30) == 0x30) {
+		// TODO: Check if getCurrentObjectRoom call in original is needed in ScummVM
+		opcode = (opcode & ~0x10) + 1;
+	}
+
+	return opcode;
+}
+
 } // namespace Comprehend
 } // namespace Glk
diff --git a/engines/glk/comprehend/game_opcodes.h b/engines/glk/comprehend/game_opcodes.h
index a1f25b888b..fe26ce3b20 100644
--- a/engines/glk/comprehend/game_opcodes.h
+++ b/engines/glk/comprehend/game_opcodes.h
@@ -34,10 +34,11 @@ namespace Comprehend {
  */
 class ComprehendGameOpcodes : public ComprehendGame {
 protected:
-	byte _opcodeMap[0x100];
+	ScriptOpcode _opcodeMap[0x100];
 
-	void execute_opcode(const Instruction *instr, const Sentence *sentence,
-		FunctionState *func_state, Room *room, Item *&item) override;
+	void execute_opcode(const Instruction *instr, const Sentence *sentence, FunctionState *func_state) override;
+
+	virtual byte getOpcode(const Instruction *instr) { return instr->_opcode; }
 
 	void func_set_test_result(FunctionState *func_state, bool value);
 	bool isItemPresent(Item *item) const;
@@ -51,8 +52,7 @@ public:
  */
 class ComprehendGameV1 : public ComprehendGameOpcodes {
 protected:
-	void execute_opcode(const Instruction *instr, const Sentence *sentence,
-		FunctionState *func_state, Room *room, Item *&item) override;
+	void execute_opcode(const Instruction *instr, const Sentence *sentence, FunctionState *func_state) override;
 public:
 	ComprehendGameV1();
 };
@@ -62,8 +62,9 @@ public:
  */
 class ComprehendGameV2 : public ComprehendGameOpcodes {
 protected:
-	void execute_opcode(const Instruction *instr, const Sentence *sentence,
-		FunctionState *func_state, Room *room, Item *&item) override;
+	byte getOpcode(const Instruction *instr) override;
+
+	void execute_opcode(const Instruction *instr, const Sentence *sentence, FunctionState *func_state) override;
 public:
 	ComprehendGameV2();
 };


Commit: b6183f85d7e909aebfb3ccdb994aa68ed4a9d238
    https://github.com/scummvm/scummvm/commit/b6183f85d7e909aebfb3ccdb994aa68ed4a9d238
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-10-16T21:22:37-07:00

Commit Message:
GLK: COMPREHEND: Fix script dumper for v2

Changed paths:
    engines/glk/comprehend/debugger_dumper.cpp
    engines/glk/comprehend/game.h
    engines/glk/comprehend/game_data.h
    engines/glk/comprehend/game_opcodes.cpp
    engines/glk/comprehend/game_opcodes.h


diff --git a/engines/glk/comprehend/debugger_dumper.cpp b/engines/glk/comprehend/debugger_dumper.cpp
index 70343fe24a..fa117bba52 100644
--- a/engines/glk/comprehend/debugger_dumper.cpp
+++ b/engines/glk/comprehend/debugger_dumper.cpp
@@ -109,13 +109,14 @@ DebuggerDumper::DebuggerDumper() : _game(nullptr) {
 	_opcodes[OPCODE_TEST_FALSE] = "test_false";
 	_opcodes[OPCODE_OBJECT_CAN_TAKE] = "object_can_take";
 	_opcodes[OPCODE_CLEAR_INVISIBLE] = "clear_invisible";
+	_opcodes[OPCODE_NOT_TAKEABLE] = "not_takeable";
 }
 
 Common::String DebuggerDumper::dumpInstruction(ComprehendGame *game,
         const FunctionState *func_state, const Instruction *instr) {
 	uint i;
 	int str_index, str_table;
-	uint8 *opcode_map, opcode;
+	ScriptOpcode opcode = _game->getScriptOpcode(instr);
 	Common::String line;
 
 	if (func_state)
diff --git a/engines/glk/comprehend/game.h b/engines/glk/comprehend/game.h
index c123c922b0..98aa386e70 100644
--- a/engines/glk/comprehend/game.h
+++ b/engines/glk/comprehend/game.h
@@ -134,6 +134,8 @@ public:
 
 	virtual void synchronizeSave(Common::Serializer &s);
 
+	virtual ScriptOpcode getScriptOpcode(const Instruction *instr) = 0;
+
 	Common::String stringLookup(uint16 index);
 	Common::String instrStringLookup(uint8 index, uint8 table);
 
diff --git a/engines/glk/comprehend/game_data.h b/engines/glk/comprehend/game_data.h
index 70bae48ab2..07f9be4b09 100644
--- a/engines/glk/comprehend/game_data.h
+++ b/engines/glk/comprehend/game_data.h
@@ -125,7 +125,7 @@ enum ScriptOpcode {
 	OPCODE_TEST_FALSE,
 	OPCODE_CAN_TAKE,
 	OPCODE_TOO_HEAVY,
-	OPCODE_NOT_MAX_WEIGHT,
+	OPCODE_NOT_TAKEABLE,
 	OPCODE_OBJECT_CAN_TAKE,
 	OPCODE_CLEAR_INVISIBLE
 };
diff --git a/engines/glk/comprehend/game_opcodes.cpp b/engines/glk/comprehend/game_opcodes.cpp
index bb28f1710f..78fede277a 100644
--- a/engines/glk/comprehend/game_opcodes.cpp
+++ b/engines/glk/comprehend/game_opcodes.cpp
@@ -30,7 +30,7 @@ namespace Glk {
 namespace Comprehend {
 
 ComprehendGameOpcodes::ComprehendGameOpcodes() {
-	Common::fill(&_opcodeMap[0], &_opcodeMap[0x100], (ScriptOpcode)0);
+	Common::fill(&_opcodeMap[0], &_opcodeMap[0x100], OPCODE_UNKNOWN);
 }
 
 void ComprehendGameOpcodes::execute_opcode(const Instruction *instr, const Sentence *sentence,
@@ -47,15 +47,13 @@ void ComprehendGameOpcodes::execute_opcode(const Instruction *instr, const Sente
 		if (instr->_operand[1] == 0x81)
 			index += 256;
 		if (index >= _functions.size())
-			error("Bad function %.4x >= %.4x\n",
-				index, _functions.size());
+			error("Bad function %.4x >= %.4x\n", index, _functions.size());
 
 		eval_function(index, sentence);
 		break;
 
 	case OPCODE_CURRENT_IS_OBJECT:
-		func_set_test_result(func_state,
-			get_item_by_noun(noun) != NULL);
+		func_set_test_result(func_state, get_item_by_noun(noun) != NULL);
 		break;
 
 	case OPCODE_CURRENT_OBJECT_NOT_VALID:
@@ -97,21 +95,18 @@ void ComprehendGameOpcodes::execute_opcode(const Instruction *instr, const Sente
 			room->_stringDesc = instr->_operand[1] + 0x200;
 			break;
 		default:
-			error("Bad string desc %.2x:%.2x\n",
-				instr->_operand[1], instr->_operand[2]);
+			error("Bad string desc %.2x:%.2x\n", instr->_operand[1], instr->_operand[2]);
 			break;
 		}
 		break;
 
 	case OPCODE_TEST_FLAG:
-		func_set_test_result(func_state,
-			_flags[instr->_operand[0]]);
+		func_set_test_result(func_state, _flags[instr->_operand[0]]);
 		break;
 
 	case OPCODE_VAR_EQ2:
 		func_set_test_result(func_state,
-			_variables[instr->_operand[0]] ==
-			_variables[instr->_operand[1]]);
+			_variables[instr->_operand[0]] == _variables[instr->_operand[1]]);
 		break;
 
 	default:
@@ -656,7 +651,7 @@ ComprehendGameV2::ComprehendGameV2() {
 	_opcodeMap[0x0c] = OPCODE_ELSE;
 	_opcodeMap[0x14] = OPCODE_CURRENT_OBJECT_NOT_VALID;
 	_opcodeMap[0x19] = OPCODE_TEST_FLAG;
-	_opcodeMap[0x25] = OPCODE_NOT_MAX_WEIGHT;
+	_opcodeMap[0x25] = OPCODE_NOT_TAKEABLE;
 	_opcodeMap[0x87] = OPCODE_SET_ROOM_DESCRIPTION;
 	_opcodeMap[0x8e] = OPCODE_PRINT;
 	_opcodeMap[0x92] = OPCODE_CALL_FUNC;
@@ -744,9 +739,9 @@ void ComprehendGameV2::execute_opcode(const Instruction *instr, const Sentence *
 			_variables[VAR_INVENTORY_LIMIT]);
 		break;
 
-	case OPCODE_NOT_MAX_WEIGHT:
+	case OPCODE_NOT_TAKEABLE:
 		item = get_item_by_noun(noun);
-		func_set_test_result(func_state, (item->_flags & ITEMF_WEIGHT_MASK) != ITEMF_WEIGHT_MASK);
+		func_set_test_result(func_state, (item->_flags & ITEMF_WEIGHT_MASK) == ITEMF_WEIGHT_MASK);
 		break;
 
 	default:
diff --git a/engines/glk/comprehend/game_opcodes.h b/engines/glk/comprehend/game_opcodes.h
index fe26ce3b20..3222ab3122 100644
--- a/engines/glk/comprehend/game_opcodes.h
+++ b/engines/glk/comprehend/game_opcodes.h
@@ -38,12 +38,17 @@ protected:
 
 	void execute_opcode(const Instruction *instr, const Sentence *sentence, FunctionState *func_state) override;
 
-	virtual byte getOpcode(const Instruction *instr) { return instr->_opcode; }
-
 	void func_set_test_result(FunctionState *func_state, bool value);
 	bool isItemPresent(Item *item) const;
 public:
 	ComprehendGameOpcodes();
+
+	virtual byte getOpcode(const Instruction *instr) {
+		return instr->_opcode;
+	}
+	virtual ScriptOpcode getScriptOpcode(const Instruction *instr) {
+		return _opcodeMap[getOpcode(instr)];
+	}
 };
 
 
@@ -62,11 +67,11 @@ public:
  */
 class ComprehendGameV2 : public ComprehendGameOpcodes {
 protected:
-	byte getOpcode(const Instruction *instr) override;
-
 	void execute_opcode(const Instruction *instr, const Sentence *sentence, FunctionState *func_state) override;
 public:
 	ComprehendGameV2();
+
+	byte getOpcode(const Instruction *instr) override;
 };
 
 } // namespace Comprehend


Commit: 3933d43dd0da0a0cc70e8b3ced4ded23914ddda9
    https://github.com/scummvm/scummvm/commit/3933d43dd0da0a0cc70e8b3ced4ded23914ddda9
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-10-16T21:22:37-07:00

Commit Message:
GLK: COMPREHEND: Implementing string replacement and other opcodes

Changed paths:
    engines/glk/comprehend/debugger_dumper.cpp
    engines/glk/comprehend/game_data.h
    engines/glk/comprehend/game_opcodes.cpp


diff --git a/engines/glk/comprehend/debugger_dumper.cpp b/engines/glk/comprehend/debugger_dumper.cpp
index fa117bba52..0f26b5561d 100644
--- a/engines/glk/comprehend/debugger_dumper.cpp
+++ b/engines/glk/comprehend/debugger_dumper.cpp
@@ -28,8 +28,6 @@ namespace Glk {
 namespace Comprehend {
 
 DebuggerDumper::DebuggerDumper() : _game(nullptr) {
-	_opcodes[OPCODE_UNKNOWN] = "unknown";
-
 	_opcodes[OPCODE_HAVE_OBJECT] = "have_object";
 	_opcodes[OPCODE_NOT_HAVE_OBJECT] = "not_have_object";
 	_opcodes[OPCODE_HAVE_CURRENT_OBJECT] = "have_current_object";
@@ -100,7 +98,9 @@ DebuggerDumper::DebuggerDumper() : _game(nullptr) {
 	_opcodes[OPCODE_VAR_DEC] = "var_dec";
 	_opcodes[OPCODE_MOVE_CURRENT_OBJECT_TO_ROOM] = "move_current_object_to_room";
 	_opcodes[OPCODE_DESCRIBE_CURRENT_OBJECT] = "describe_current_object";
-	_opcodes[OPCODE_SET_STRING_REPLACEMENT] = "set_string_replacement";
+	_opcodes[OPCODE_SET_STRING_REPLACEMENT1] = "set_string_replacement1";
+	_opcodes[OPCODE_SET_STRING_REPLACEMENT2] = "set_string_replacement2";
+	_opcodes[OPCODE_SET_STRING_REPLACEMENT3] = "set_string_replacement3";
 	_opcodes[OPCODE_SET_CURRENT_NOUN_STRING_REPLACEMENT] = "set_current_noun_string_replacement";
 	_opcodes[OPCODE_CURRENT_IS_OBJECT] = "current_is_object";
 	_opcodes[OPCODE_DRAW_ROOM] = "draw_room";
@@ -155,7 +155,9 @@ Common::String DebuggerDumper::dumpInstruction(ComprehendGame *game,
 		line += Common::String::format(" %s", game->instrStringLookup(str_index, str_table).c_str());
 		break;
 
-	case OPCODE_SET_STRING_REPLACEMENT:
+	case OPCODE_SET_STRING_REPLACEMENT1:
+	case OPCODE_SET_STRING_REPLACEMENT2:
+	case OPCODE_SET_STRING_REPLACEMENT3:
 		line += Common::String::format(" %s", game->_replaceWords[instr->_operand[0] - 1].c_str());
 		break;
 	}
diff --git a/engines/glk/comprehend/game_data.h b/engines/glk/comprehend/game_data.h
index 07f9be4b09..88e2aa3ae8 100644
--- a/engines/glk/comprehend/game_data.h
+++ b/engines/glk/comprehend/game_data.h
@@ -116,7 +116,9 @@ enum ScriptOpcode {
 	OPCODE_VAR_DEC,
 	OPCODE_MOVE_CURRENT_OBJECT_TO_ROOM,
 	OPCODE_DESCRIBE_CURRENT_OBJECT,
-	OPCODE_SET_STRING_REPLACEMENT,
+	OPCODE_SET_STRING_REPLACEMENT1,
+	OPCODE_SET_STRING_REPLACEMENT2,
+	OPCODE_SET_STRING_REPLACEMENT3,
 	OPCODE_SET_CURRENT_NOUN_STRING_REPLACEMENT,
 	OPCODE_CURRENT_IS_OBJECT,
 	OPCODE_DRAW_ROOM,
diff --git a/engines/glk/comprehend/game_opcodes.cpp b/engines/glk/comprehend/game_opcodes.cpp
index 78fede277a..4f3545accb 100644
--- a/engines/glk/comprehend/game_opcodes.cpp
+++ b/engines/glk/comprehend/game_opcodes.cpp
@@ -38,6 +38,7 @@ void ComprehendGameOpcodes::execute_opcode(const Instruction *instr, const Sente
 //	byte verb = sentence ? sentence->_formattedWords[0] : 0;
 	byte noun = sentence ? sentence->_formattedWords[2] : 0;
 	Room *room = get_room(_currentRoom);
+	Item *item;
 	uint index;
 
 	byte opcode = getOpcode(instr);
@@ -64,9 +65,23 @@ void ComprehendGameOpcodes::execute_opcode(const Instruction *instr, const Sente
 		func_state->_testResult = func_state->_elseResult;
 		break;
 
+	case OPCODE_HAVE_CURRENT_OBJECT:
+		item = get_item_by_noun(noun);
+		func_set_test_result(func_state, item->_room == ROOM_INVENTORY);
+		break;
+
 	case OPCODE_IN_ROOM:
-		func_set_test_result(func_state,
-			_currentRoom == instr->_operand[0]);
+		func_set_test_result(func_state, _currentRoom == instr->_operand[0]);
+		break;
+
+	case OPCODE_MOVE_TO_ROOM:
+		if (instr->_operand[0] != 0xff)
+			move_to(instr->_operand[0]);
+		break;
+
+	case OPCODE_OBJECT_PRESENT:
+		item = get_item(instr->_operand[0] - 1);
+		func_set_test_result(func_state, item->_room == _currentRoom);
 		break;
 
 	case OPCODE_OR:
@@ -82,6 +97,10 @@ void ComprehendGameOpcodes::execute_opcode(const Instruction *instr, const Sente
 		console_println(instrStringLookup(instr->_operand[0], instr->_operand[1]).c_str());
 		break;
 
+	case OPCODE_SET_FLAG:
+		_flags[instr->_operand[0]] = true;
+		break;
+
 	case OPCODE_SET_ROOM_DESCRIPTION:
 		room = get_room(instr->_operand[0]);
 		switch (instr->_operand[2]) {
@@ -100,6 +119,14 @@ void ComprehendGameOpcodes::execute_opcode(const Instruction *instr, const Sente
 		}
 		break;
 
+	case OPCODE_SET_STRING_REPLACEMENT1:
+		_currentReplaceWord = (instr->_operand[0] & 0x80) - 1;
+		break;
+
+	case OPCODE_SET_STRING_REPLACEMENT2:
+		_currentReplaceWord = instr->_operand[0] - 1;
+		break;
+
 	case OPCODE_TEST_FLAG:
 		func_set_test_result(func_state, _flags[instr->_operand[0]]);
 		break;
@@ -206,7 +233,9 @@ ComprehendGameV1::ComprehendGameV1() {
 	_opcodeMap[0xa2] = OPCODE_SET_ROOM_GRAPHIC;
 	_opcodeMap[0xb0] = OPCODE_REMOVE_CURRENT_OBJECT;
 	_opcodeMap[0xb1] = OPCODE_MOVE_DIR;
-	_opcodeMap[0xb9] = OPCODE_SET_STRING_REPLACEMENT;
+	_opcodeMap[0xb5] = OPCODE_SET_STRING_REPLACEMENT1;
+	_opcodeMap[0xb9] = OPCODE_SET_STRING_REPLACEMENT2;
+	_opcodeMap[0xc5] = OPCODE_SET_STRING_REPLACEMENT3;
 	_opcodeMap[0xbd] = OPCODE_VAR_INC;
 	_opcodeMap[0xc1] = OPCODE_VAR_DEC;
 	_opcodeMap[0xc9] = OPCODE_MOVE_CURRENT_OBJECT_TO_ROOM;
@@ -221,6 +250,19 @@ void ComprehendGameV1::execute_opcode(const Instruction *instr, const Sentence *
 	uint count;
 
 	switch (_opcodeMap[getOpcode(instr)]) {
+	case OPCODE_INVENTORY_FULL:
+		item = get_item_by_noun(noun);
+
+		func_set_test_result(func_state, _variables[VAR_INVENTORY_WEIGHT] +
+			(item->_flags & ITEMF_WEIGHT_MASK) > _variables[VAR_INVENTORY_LIMIT]);
+		break;
+
+	case OPCODE_SET_STRING_REPLACEMENT3:
+		_currentReplaceWord = instr->_operand[0] - 1;
+		break;
+
+	/*--------------------------------------*/
+
 	case OPCODE_VAR_ADD:
 		_variables[instr->_operand[0]] +=
 			_variables[instr->_operand[1]];
@@ -288,11 +330,6 @@ void ComprehendGameV1::execute_opcode(const Instruction *instr, const Sentence *
 			_currentRoom != instr->_operand[0]);
 		break;
 
-	case OPCODE_MOVE_TO_ROOM:
-		if (instr->_operand[0] != 0xff)
-			move_to(instr->_operand[0]);
-		break;
-
 	case OPCODE_MOVE_DEFAULT:
 		// Move in the direction dictated by the current verb
 		if (verb - 1 >= NR_DIRECTIONS)
@@ -342,13 +379,6 @@ void ComprehendGameV1::execute_opcode(const Instruction *instr, const Sentence *
 		move_object(item, instr->_operand[1]);
 		break;
 
-	case OPCODE_INVENTORY_FULL:
-		item = get_item_by_noun(noun);
-
-		func_set_test_result(func_state, _variables[VAR_INVENTORY_WEIGHT] +
-			(item->_flags & ITEMF_WEIGHT_MASK) > _variables[VAR_INVENTORY_LIMIT]);
-		break;
-
 	case OPCODE_DESCRIBE_CURRENT_OBJECT:
 		/*
 		 * This opcode is only used in version 2
@@ -398,12 +428,6 @@ void ComprehendGameV1::execute_opcode(const Instruction *instr, const Sentence *
 			!item || item->_room != ROOM_INVENTORY);
 		break;
 
-	case OPCODE_HAVE_CURRENT_OBJECT:
-		item = get_item_by_noun(noun);
-		func_set_test_result(func_state,
-			item->_room == ROOM_INVENTORY);
-		break;
-
 	case OPCODE_NOT_HAVE_OBJECT:
 		item = get_item(instr->_operand[0] - 1);
 		func_set_test_result(func_state,
@@ -453,12 +477,6 @@ void ComprehendGameV1::execute_opcode(const Instruction *instr, const Sentence *
 		func_set_test_result(func_state, !isItemPresent(item));
 		break;
 
-	case OPCODE_OBJECT_PRESENT:
-		item = get_item(instr->_operand[0] - 1);
-		func_set_test_result(func_state,
-			item->_room == _currentRoom);
-		break;
-
 	case OPCODE_REMOVE_OBJECT:
 		item = get_item(instr->_operand[0] - 1);
 		move_object(item, ROOM_NOWHERE);
@@ -544,10 +562,6 @@ void ComprehendGameV1::execute_opcode(const Instruction *instr, const Sentence *
 		_flags[instr->_operand[0]] = false;
 		break;
 
-	case OPCODE_SET_FLAG:
-		_flags[instr->_operand[0]] = true;
-		break;
-
 	case OPCODE_SET_OBJECT_DESCRIPTION:
 		item = get_item(instr->_operand[0] - 1);
 		item->_stringDesc = (instr->_operand[2] << 8) | instr->_operand[1];
@@ -591,10 +605,6 @@ void ComprehendGameV1::execute_opcode(const Instruction *instr, const Sentence *
 		 */
 		break;
 
-	case OPCODE_SET_STRING_REPLACEMENT:
-		_currentReplaceWord = instr->_operand[0] - 1;
-		break;
-
 	case OPCODE_SET_CURRENT_NOUN_STRING_REPLACEMENT:
 #if 1
 		error("TODO: OPCODE_SET_CURRENT_NOUN_STRING_REPLACEMENT");
@@ -651,11 +661,19 @@ ComprehendGameV2::ComprehendGameV2() {
 	_opcodeMap[0x0c] = OPCODE_ELSE;
 	_opcodeMap[0x14] = OPCODE_CURRENT_OBJECT_NOT_VALID;
 	_opcodeMap[0x19] = OPCODE_TEST_FLAG;
+	_opcodeMap[0x20] = OPCODE_HAVE_CURRENT_OBJECT;
+	_opcodeMap[0x21] = OPCODE_OBJECT_PRESENT;
 	_opcodeMap[0x25] = OPCODE_NOT_TAKEABLE;
+	_opcodeMap[0x29] = OPCODE_INVENTORY_FULL;
+	_opcodeMap[0x85] = OPCODE_MOVE_TO_ROOM;
 	_opcodeMap[0x87] = OPCODE_SET_ROOM_DESCRIPTION;
 	_opcodeMap[0x8e] = OPCODE_PRINT;
 	_opcodeMap[0x92] = OPCODE_CALL_FUNC;
+	_opcodeMap[0x99] = OPCODE_SET_FLAG;
 	_opcodeMap[0xa9] = OPCODE_CLEAR_INVISIBLE;
+	_opcodeMap[0xc5] = OPCODE_SET_STRING_REPLACEMENT3;
+	_opcodeMap[0xc9] = OPCODE_SET_STRING_REPLACEMENT1;
+	_opcodeMap[0xcd] = OPCODE_SET_STRING_REPLACEMENT2;
 
 #if 0
 	_opcodeMap[0x01] = OPCODE_HAVE_OBJECT;
@@ -665,8 +683,6 @@ ComprehendGameV2::ComprehendGameV2() {
 	_opcodeMap[0x0d] = OPCODE_VAR_EQ1;
 	_opcodeMap[0x11] = OPCODE_OBJECT_IS_NOWHERE;
 	_opcodeMap[0x1d] = OPCODE_TEST_ROOM_FLAG;
-	_opcodeMap[0x20] = OPCODE_HAVE_CURRENT_OBJECT;
-	_opcodeMap[0x21] = OPCODE_OBJECT_PRESENT;
 	_opcodeMap[0x22] = OPCODE_OBJECT_IN_ROOM;
 	_opcodeMap[0x2d] = OPCODE_OBJECT_CAN_TAKE;
 	_opcodeMap[0x30] = OPCODE_CURRENT_OBJECT_PRESENT;
@@ -685,7 +701,6 @@ ComprehendGameV2::ComprehendGameV2() {
 	_opcodeMap[0x81] = OPCODE_TAKE_OBJECT;
 	_opcodeMap[0x82] = OPCODE_MOVE_OBJECT_TO_ROOM;
 	_opcodeMap[0x84] = OPCODE_SAVE_ACTION;
-	_opcodeMap[0x85] = OPCODE_MOVE_TO_ROOM;
 	_opcodeMap[0x86] = OPCODE_VAR_ADD;
 	_opcodeMap[0x89] = OPCODE_SPECIAL;
 	_opcodeMap[0x8a] = OPCODE_VAR_SUB;
@@ -695,20 +710,15 @@ ComprehendGameV2::ComprehendGameV2() {
 	_opcodeMap[0x90] = OPCODE_WAIT_KEY;
 	_opcodeMap[0x95] = OPCODE_REMOVE_OBJECT;
 	_opcodeMap[0x98] = OPCODE_TURN_TICK;
-	_opcodeMap[0x99] = OPCODE_SET_FLAG;
 	_opcodeMap[0x9d] = OPCODE_CLEAR_FLAG;
 	_opcodeMap[0x9e] = OPCODE_INVENTORY_ROOM;
 	_opcodeMap[0xa0] = OPCODE_TAKE_CURRENT_OBJECT;
 	_opcodeMap[0xa2] = OPCODE_SET_OBJECT_GRAPHIC;
-	_opcodeMap[0xa9] = OPCODE_INVENTORY_FULL;
 	_opcodeMap[0xb1] = OPCODE_MOVE_DIR;
 	_opcodeMap[0xb5] = OPCODE_DESCRIBE_CURRENT_OBJECT;
 	_opcodeMap[0xc1] = OPCODE_VAR_DEC;
 	_opcodeMap[0xc2] = OPCODE_SET_ROOM_GRAPHIC;
-	_opcodeMap[0xc5] = OPCODE_SET_CURRENT_NOUN_STRING_REPLACEMENT;
 	_opcodeMap[0xc6] = OPCODE_SET_OBJECT_GRAPHIC;
-	_opcodeMap[0xc9] = OPCODE_MOVE_CURRENT_OBJECT_TO_ROOM;
-	_opcodeMap[0xcd] = OPCODE_SET_STRING_REPLACEMENT;
 	_opcodeMap[0xd1] = OPCODE_MOVE_DIRECTION;
 	_opcodeMap[0xd5] = OPCODE_DRAW_ROOM;
 	_opcodeMap[0xd9] = OPCODE_DRAW_OBJECT;
@@ -744,6 +754,11 @@ void ComprehendGameV2::execute_opcode(const Instruction *instr, const Sentence *
 		func_set_test_result(func_state, (item->_flags & ITEMF_WEIGHT_MASK) == ITEMF_WEIGHT_MASK);
 		break;
 
+	case OPCODE_SET_STRING_REPLACEMENT3:
+		warning("TODO: Figure out OPCODE_SET_STRING_REPLACEMENT3 offset");
+		_currentReplaceWord = instr->_operand[0] - 1;
+		break;
+
 	default:
 		ComprehendGameOpcodes::execute_opcode(instr, sentence, func_state);
 		break;


Commit: 54980c1f6bcde27e6c6bf96061fdee65ab174641
    https://github.com/scummvm/scummvm/commit/54980c1f6bcde27e6c6bf96061fdee65ab174641
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-10-16T22:11:34-07:00

Commit Message:
GLK: COMPREHEND: Added item flag manipulation opcodes

Changed paths:
    engines/glk/comprehend/debugger_dumper.cpp
    engines/glk/comprehend/game_data.h
    engines/glk/comprehend/game_opcodes.cpp


diff --git a/engines/glk/comprehend/debugger_dumper.cpp b/engines/glk/comprehend/debugger_dumper.cpp
index 0f26b5561d..c6478e510f 100644
--- a/engines/glk/comprehend/debugger_dumper.cpp
+++ b/engines/glk/comprehend/debugger_dumper.cpp
@@ -108,8 +108,13 @@ DebuggerDumper::DebuggerDumper() : _game(nullptr) {
 	_opcodes[OPCODE_WAIT_KEY] = "wait_key";
 	_opcodes[OPCODE_TEST_FALSE] = "test_false";
 	_opcodes[OPCODE_OBJECT_CAN_TAKE] = "object_can_take";
-	_opcodes[OPCODE_CLEAR_INVISIBLE] = "clear_invisible";
 	_opcodes[OPCODE_NOT_TAKEABLE] = "not_takeable";
+	_opcodes[OPCODE_CLEAR_INVISIBLE] = "clear_invisible";
+	_opcodes[OPCODE_SET_INVISIBLE] = "set_invisible";
+	_opcodes[OPCODE_CLEAR_CAN_TAKE] = "clear_can_take";
+	_opcodes[OPCODE_SET_CAN_TAKE] = "set_can_take";
+	_opcodes[OPCODE_SET_FLAG40] = "set_flag40";
+	_opcodes[OPCODE_CLEAR_FLAG40] = "clear_flag40";
 }
 
 Common::String DebuggerDumper::dumpInstruction(ComprehendGame *game,
diff --git a/engines/glk/comprehend/game_data.h b/engines/glk/comprehend/game_data.h
index 88e2aa3ae8..104e8f201c 100644
--- a/engines/glk/comprehend/game_data.h
+++ b/engines/glk/comprehend/game_data.h
@@ -129,7 +129,12 @@ enum ScriptOpcode {
 	OPCODE_TOO_HEAVY,
 	OPCODE_NOT_TAKEABLE,
 	OPCODE_OBJECT_CAN_TAKE,
-	OPCODE_CLEAR_INVISIBLE
+	OPCODE_CLEAR_INVISIBLE,
+	OPCODE_SET_INVISIBLE,
+	OPCODE_CLEAR_CAN_TAKE,
+	OPCODE_SET_CAN_TAKE,
+	OPCODE_CLEAR_FLAG40,
+	OPCODE_SET_FLAG40
 };
 
 /* Game state update flags */
diff --git a/engines/glk/comprehend/game_opcodes.cpp b/engines/glk/comprehend/game_opcodes.cpp
index 4f3545accb..067e688383 100644
--- a/engines/glk/comprehend/game_opcodes.cpp
+++ b/engines/glk/comprehend/game_opcodes.cpp
@@ -53,6 +53,21 @@ void ComprehendGameOpcodes::execute_opcode(const Instruction *instr, const Sente
 		eval_function(index, sentence);
 		break;
 
+	case OPCODE_CLEAR_CAN_TAKE:
+		item = get_item_by_noun(noun);
+		item->_flags &= ~ITEMF_CAN_TAKE;
+		break;
+
+	case OPCODE_CLEAR_FLAG40:
+		item = get_item_by_noun(noun);
+		item->_flags &= ~ITEMF_UNKNOWN;
+		break;
+
+	case OPCODE_CLEAR_INVISIBLE:
+		item = get_item_by_noun(noun);
+		item->_flags &= ~ITEMF_INVISIBLE;
+		break;
+
 	case OPCODE_CURRENT_IS_OBJECT:
 		func_set_test_result(func_state, get_item_by_noun(noun) != NULL);
 		break;
@@ -97,10 +112,25 @@ void ComprehendGameOpcodes::execute_opcode(const Instruction *instr, const Sente
 		console_println(instrStringLookup(instr->_operand[0], instr->_operand[1]).c_str());
 		break;
 
+	case OPCODE_SET_CAN_TAKE:
+		item = get_item_by_noun(noun);
+		item->_flags |= ITEMF_CAN_TAKE;
+		break;
+
 	case OPCODE_SET_FLAG:
 		_flags[instr->_operand[0]] = true;
 		break;
 
+	case OPCODE_SET_FLAG40:
+		item = get_item_by_noun(noun);
+		item->_flags |= ITEMF_UNKNOWN;
+		break;
+
+	case OPCODE_SET_INVISIBLE:
+		item = get_item_by_noun(noun);
+		item->_flags |= ITEMF_INVISIBLE;
+		break;
+
 	case OPCODE_SET_ROOM_DESCRIPTION:
 		room = get_room(instr->_operand[0]);
 		switch (instr->_operand[2]) {
@@ -220,7 +250,9 @@ ComprehendGameV1::ComprehendGameV1() {
 	_opcodeMap[0x8a] = OPCODE_VAR_SUB;
 	_opcodeMap[0x8b] = OPCODE_SET_OBJECT_DESCRIPTION;
 	_opcodeMap[0x8c] = OPCODE_MOVE_DEFAULT;
+	_opcodeMap[0x8d] = OPCODE_SET_CAN_TAKE;
 	_opcodeMap[0x8e] = OPCODE_PRINT;
+	_opcodeMap[0x91] = OPCODE_CLEAR_CAN_TAKE;
 	_opcodeMap[0x95] = OPCODE_REMOVE_OBJECT;
 	_opcodeMap[0x99] = OPCODE_SET_FLAG;
 	_opcodeMap[0x92] = OPCODE_CALL_FUNC;
@@ -235,10 +267,14 @@ ComprehendGameV1::ComprehendGameV1() {
 	_opcodeMap[0xb1] = OPCODE_MOVE_DIR;
 	_opcodeMap[0xb5] = OPCODE_SET_STRING_REPLACEMENT1;
 	_opcodeMap[0xb9] = OPCODE_SET_STRING_REPLACEMENT2;
-	_opcodeMap[0xc5] = OPCODE_SET_STRING_REPLACEMENT3;
 	_opcodeMap[0xbd] = OPCODE_VAR_INC;
 	_opcodeMap[0xc1] = OPCODE_VAR_DEC;
+	_opcodeMap[0xc5] = OPCODE_SET_STRING_REPLACEMENT3;
 	_opcodeMap[0xc9] = OPCODE_MOVE_CURRENT_OBJECT_TO_ROOM;
+	_opcodeMap[0xcd] = OPCODE_CLEAR_INVISIBLE;
+	_opcodeMap[0xd1] = OPCODE_SET_INVISIBLE;
+	_opcodeMap[0xd5] = OPCODE_CLEAR_FLAG40;
+	_opcodeMap[0xd9] = OPCODE_SET_FLAG40;
 }
 
 void ComprehendGameV1::execute_opcode(const Instruction *instr, const Sentence *sentence,
@@ -670,10 +706,15 @@ ComprehendGameV2::ComprehendGameV2() {
 	_opcodeMap[0x8e] = OPCODE_PRINT;
 	_opcodeMap[0x92] = OPCODE_CALL_FUNC;
 	_opcodeMap[0x99] = OPCODE_SET_FLAG;
+	_opcodeMap[0xa1] = OPCODE_CLEAR_FLAG40;
+	_opcodeMap[0xa5] = OPCODE_SET_FLAG40;
 	_opcodeMap[0xa9] = OPCODE_CLEAR_INVISIBLE;
+	_opcodeMap[0xad] = OPCODE_SET_INVISIBLE;
 	_opcodeMap[0xc5] = OPCODE_SET_STRING_REPLACEMENT3;
 	_opcodeMap[0xc9] = OPCODE_SET_STRING_REPLACEMENT1;
 	_opcodeMap[0xcd] = OPCODE_SET_STRING_REPLACEMENT2;
+	_opcodeMap[0xe5] = OPCODE_SET_CAN_TAKE;
+	_opcodeMap[0xe9] = OPCODE_CLEAR_CAN_TAKE;
 
 #if 0
 	_opcodeMap[0x01] = OPCODE_HAVE_OBJECT;




More information about the Scummvm-git-logs mailing list