[Scummvm-git-logs] scummvm master -> 0e244a6b3b79d248a4cf1ede8a8940d4c8a0635a

dreammaster paulfgilbert at gmail.com
Thu Jun 11 00:51:08 UTC 2020


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

Summary:
e3cf51a868 GLK: COMPREHEND: Move static methods into ComprehendGame class
0e244a6b3b GLK: COMPREHEND: Refactoring static methods into GameData class


Commit: e3cf51a86821edd70218285c8686025e92597c92
    https://github.com/scummvm/scummvm/commit/e3cf51a86821edd70218285c8686025e92597c92
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-10T17:49:33-07:00

Commit Message:
GLK: COMPREHEND: Move static methods into ComprehendGame class

Changed paths:
    engines/glk/comprehend/comprehend.cpp
    engines/glk/comprehend/game.cpp
    engines/glk/comprehend/game.h
    engines/glk/comprehend/game_cc.cpp
    engines/glk/comprehend/game_oo.cpp
    engines/glk/comprehend/game_tr.cpp


diff --git a/engines/glk/comprehend/comprehend.cpp b/engines/glk/comprehend/comprehend.cpp
index 6bb8ab182a..5ce17b3130 100644
--- a/engines/glk/comprehend/comprehend.cpp
+++ b/engines/glk/comprehend/comprehend.cpp
@@ -70,7 +70,7 @@ void Comprehend::runGame() {
 	createGame();
 
 	comprehend_load_game(_game);
-	comprehend_play_game(_game);
+	_game->playGame();
 
 	deinitialize();
 }
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index 5ac00138fc..d1f7cbcec0 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -136,13 +136,7 @@ Common::String ComprehendGame::instrStringLookup(uint8 index, uint8 table) {
 	return stringLookup(table << 8 | index);
 }
 
-/*-------------------------------------------------------*/
-
-static void console_init(void) {
-	//  ioctl(STDOUT_FILENO, TIOCGWINSZ, &console_winsize);
-}
-
-int console_get_key(void) {
+int ComprehendGame::console_get_key() {
 	int c, dummy;
 
 	dummy = c = g_comprehend->readChar();
@@ -154,7 +148,7 @@ int console_get_key(void) {
 	return c;
 }
 
-void console_println(ComprehendGame *game, const char *text) {
+void ComprehendGame::console_println(const char *text) {
 	const char *replace, *word = nullptr, *p = text;
 	char bad_word[64];
 	int word_len = 0;
@@ -175,13 +169,13 @@ void console_println(ComprehendGame *game, const char *text) {
 
 		case '@':
 			/* Replace word */
-			if (game->_currentReplaceWord >= game->_replaceWords.size()) {
+			if (_currentReplaceWord >= _replaceWords.size()) {
 				snprintf(bad_word, sizeof(bad_word),
 				         "[BAD_REPLACE_WORD(%.2x)]",
-				         game->_currentReplaceWord);
+				         _currentReplaceWord);
 				word = bad_word;
 			} else {
-				word = game->_replaceWords[game->_currentReplaceWord].c_str();
+				word = _replaceWords[_currentReplaceWord].c_str();
 			}
 			word_len = strlen(word);
 			p++;
@@ -232,28 +226,28 @@ void console_println(ComprehendGame *game, const char *text) {
 	g_comprehend->print("\n");
 }
 
-static Room *get_room(ComprehendGame *game, uint16 index) {
+Room *ComprehendGame::get_room(uint16 index) {
 	/* Room zero is reserved for the players inventory */
 	if (index == 0)
 		error("Room index 0 (player inventory) is invalid");
 
-	if (index >= (int)game->_rooms.size())
+	if (index >= (int)_rooms.size())
 		error("Room index %d is invalid", index);
 
-	return &game->_rooms[index];
+	return &_rooms[index];
 }
 
-Item *get_item(ComprehendGame *game, uint16 index) {
-	if (index >= game->_items.size())
+Item *ComprehendGame::get_item(uint16 index) {
+	if (index >= _items.size())
 		error("Bad item %d\n", index);
 
-	return &game->_items[index];
+	return &_items[index];
 }
 
-void game_save(ComprehendGame *game) {
+void ComprehendGame::game_save() {
 	int c;
 
-	console_println(game, game->_strings[STRING_SAVE_GAME].c_str());
+	console_println(_strings[STRING_SAVE_GAME].c_str());
 
 	c = console_get_key();
 	if (c < '1' || c > '3') {
@@ -261,17 +255,17 @@ void game_save(ComprehendGame *game) {
 		 * The original Comprehend games just silently ignore any
 		 * invalid selection.
 		 */
-		console_println(game, "Invalid save game number");
+		console_println("Invalid save game number");
 		return;
 	}
 
 	g_comprehend->saveGameState(c - '0', _("Savegame"));
 }
 
-void game_restore(ComprehendGame *game) {
+void ComprehendGame::game_restore() {
 	int c;
 
-	console_println(game, game->_strings[STRING_RESTORE_GAME].c_str());
+	console_println(_strings[STRING_RESTORE_GAME].c_str());
 
 	c = console_get_key();
 	if (c < '1' || c > '3') {
@@ -279,29 +273,28 @@ void game_restore(ComprehendGame *game) {
 		 * The original Comprehend games just silently ignore any
 		 * invalid selection.
 		 */
-		console_println(game, "Invalid save game number");
+		console_println("Invalid save game number");
 		return;
 	}
 
 	(void)g_comprehend->loadGameState(c - '0');
 }
 
-void game_restart(ComprehendGame *game) {
-	console_println(game, game->stringLookup(game->_gameStrings->game_restart).c_str());
+void ComprehendGame::game_restart() {
+	console_println(stringLookup(_gameStrings->game_restart).c_str());
 	console_get_key();
 
-	comprehend_load_game(game);
-	game->_updateFlags = UPDATE_ALL;
+	comprehend_load_game(this);
+	_updateFlags = UPDATE_ALL;
 }
 
-static WordIndex *is_word_pair(ComprehendGame *game,
-                               Word *word1, Word *word2) {
+WordIndex *ComprehendGame::is_word_pair(Word *word1, Word *word2) {
 	WordMap *map;
 	uint i;
 
 	/* Check if this is a word pair */
-	for (i = 0; i < game->_wordMaps.size(); i++) {
-		map = &game->_wordMaps[i];
+	for (i = 0; i < _wordMaps.size(); i++) {
+		map = &_wordMaps[i];
 
 		if (map->word[0].index == word1->_index &&
 		        map->word[0].type == word1->_type &&
@@ -313,8 +306,7 @@ static WordIndex *is_word_pair(ComprehendGame *game,
 	return nullptr;
 }
 
-static Item *get_item_by_noun(ComprehendGame *game,
-                              Word *noun) {
+Item *ComprehendGame::get_item_by_noun(Word *noun) {
 	uint i;
 
 	if (!noun || !(noun->_type & WORD_TYPE_NOUN_MASK))
@@ -325,14 +317,14 @@ static Item *get_item_by_noun(ComprehendGame *game,
 	 *         (the box and the snarl-in-a-box). The player is unable
 	 *         to drop the latter because this will match the former.
 	 */
-	for (i = 0; i < game->_items.size(); i++)
-		if (game->_items[i].word == noun->_index)
-			return &game->_items[i];
+	for (i = 0; i < _items.size(); i++)
+		if (_items[i].word == noun->_index)
+			return &_items[i];
 
 	return NULL;
 }
 
-static void update_graphics(ComprehendGame *game) {
+void ComprehendGame::update_graphics() {
 	Item *item;
 	Room *room;
 	int type;
@@ -341,31 +333,31 @@ static void update_graphics(ComprehendGame *game) {
 	if (!g_comprehend->_graphicsEnabled)
 		return;
 
-	type = game->roomIsSpecial(game->_currentRoom, NULL);
+	type = roomIsSpecial(_currentRoom, NULL);
 
 	switch (type) {
 	case ROOM_IS_DARK:
-		if (game->_updateFlags & UPDATE_GRAPHICS)
+		if (_updateFlags & UPDATE_GRAPHICS)
 			g_comprehend->clearScreen(false);
 		break;
 
 	case ROOM_IS_TOO_BRIGHT:
-		if (game->_updateFlags & UPDATE_GRAPHICS)
+		if (_updateFlags & UPDATE_GRAPHICS)
 			g_comprehend->clearScreen(false);
 		break;
 
 	default:
-		if (game->_updateFlags & UPDATE_GRAPHICS) {
-			room = get_room(game, game->_currentRoom);
+		if (_updateFlags & UPDATE_GRAPHICS) {
+			room = get_room(_currentRoom);
 			g_comprehend->drawLocationPicture(room->graphic - 1);
 		}
 
-		if ((game->_updateFlags & UPDATE_GRAPHICS) ||
-		        (game->_updateFlags & UPDATE_GRAPHICS_ITEMS)) {
-			for (i = 0; i < game->_items.size(); i++) {
-				item = &game->_items[i];
+		if ((_updateFlags & UPDATE_GRAPHICS) ||
+		        (_updateFlags & UPDATE_GRAPHICS_ITEMS)) {
+			for (i = 0; i < _items.size(); i++) {
+				item = &_items[i];
 
-				if (item->room == game->_currentRoom &&
+				if (item->room == _currentRoom &&
 				        item->graphic != 0)
 					g_comprehend->drawItemPicture(item->graphic - 1);
 			}
@@ -374,63 +366,63 @@ static void update_graphics(ComprehendGame *game) {
 	}
 }
 
-static void describe_objects_in_current_room(ComprehendGame *game) {
+void ComprehendGame::describe_objects_in_current_room() {
 	Item *item;
 	size_t count = 0;
 	uint i;
 
-	for (i = 0; i < game->_items.size(); i++) {
-		item = &game->_items[i];
+	for (i = 0; i < _items.size(); i++) {
+		item = &_items[i];
 
-		if (item->room == game->_currentRoom &&
+		if (item->room == _currentRoom &&
 		        item->string_desc != 0)
 			count++;
 	}
 
 	if (count > 0) {
-		console_println(game, game->stringLookup(STRING_YOU_SEE).c_str());
+		console_println(stringLookup(STRING_YOU_SEE).c_str());
 
-		for (i = 0; i < game->_items.size(); i++) {
-			item = &game->_items[i];
+		for (i = 0; i < _items.size(); i++) {
+			item = &_items[i];
 
-			if (item->room == game->_currentRoom &&
+			if (item->room == _currentRoom &&
 			        item->string_desc != 0)
-				console_println(game, game->stringLookup(item->string_desc).c_str());
+				console_println(stringLookup(item->string_desc).c_str());
 		}
 	}
 }
 
-static void update(ComprehendGame *game) {
-	Room *room = get_room(game, game->_currentRoom);
+void ComprehendGame::update() {
+	Room *room = get_room(_currentRoom);
 	unsigned room_type, room_desc_string;
 
-	update_graphics(game);
+	update_graphics();
 
 	/* Check if the room is special (dark, too bright, etc) */
 	room_desc_string = room->string_desc;
-	room_type = game->roomIsSpecial(game->_currentRoom,
+	room_type = roomIsSpecial(_currentRoom,
 	                                &room_desc_string);
 
-	if (game->_updateFlags & UPDATE_ROOM_DESC)
-		console_println(game, game->stringLookup(room_desc_string).c_str());
+	if (_updateFlags & UPDATE_ROOM_DESC)
+		console_println(stringLookup(room_desc_string).c_str());
 
-	if ((game->_updateFlags & UPDATE_ITEM_LIST) &&
+	if ((_updateFlags & UPDATE_ITEM_LIST) &&
 	        room_type == ROOM_IS_NORMAL)
-		describe_objects_in_current_room(game);
+		describe_objects_in_current_room();
 
-	game->_updateFlags = 0;
+	_updateFlags = 0;
 }
 
-static void move_to(ComprehendGame *game, uint8 room) {
-	if (room >= (int)game->_rooms.size())
+void ComprehendGame::move_to(uint8 room) {
+	if (room >= (int)_rooms.size())
 		error("Attempted to move to invalid room %.2x\n", room);
 
-	game->_currentRoom = room;
-	game->_updateFlags = (UPDATE_GRAPHICS | UPDATE_ROOM_DESC |
+	_currentRoom = room;
+	_updateFlags = (UPDATE_GRAPHICS | UPDATE_ROOM_DESC |
 	                      UPDATE_ITEM_LIST);
 }
 
-static void func_set_test_result(FunctionState *func_state, bool value) {
+void ComprehendGame::func_set_test_result(FunctionState *func_state, bool value) {
 	if (func_state->or_count == 0) {
 		/* And */
 		if (func_state->_and) {
@@ -448,17 +440,17 @@ static void func_set_test_result(FunctionState *func_state, bool value) {
 	}
 }
 
-static size_t num_objects_in_room(ComprehendGame *game, int room) {
+size_t ComprehendGame::num_objects_in_room(int room) {
 	size_t count = 0, i;
 
-	for (i = 0; i < game->_items.size(); i++)
-		if (game->_items[i].room == room)
+	for (i = 0; i < _items.size(); i++)
+		if (_items[i].room == room)
 			count++;
 
 	return count;
 }
 
-void move_object(ComprehendGame *game, Item *item, int new_room) {
+void ComprehendGame::move_object(Item *item, int new_room) {
 	unsigned obj_weight = item->flags & ITEMF_WEIGHT_MASK;
 
 	if (item->room == new_room)
@@ -466,41 +458,40 @@ void move_object(ComprehendGame *game, Item *item, int new_room) {
 
 	if (item->room == ROOM_INVENTORY) {
 		/* Removed from player's inventory */
-		game->_variables[VAR_INVENTORY_WEIGHT] -= obj_weight;
+		_variables[VAR_INVENTORY_WEIGHT] -= obj_weight;
 	}
 	if (new_room == ROOM_INVENTORY) {
 		/* Moving to the player's inventory */
-		game->_variables[VAR_INVENTORY_WEIGHT] += obj_weight;
+		_variables[VAR_INVENTORY_WEIGHT] += obj_weight;
 	}
 
-	if (item->room == game->_currentRoom) {
+	if (item->room == _currentRoom) {
 		/* Item moved away from the current room */
-		game->_updateFlags |= UPDATE_GRAPHICS;
+		_updateFlags |= UPDATE_GRAPHICS;
 
-	} else if (new_room == game->_currentRoom) {
+	} else if (new_room == _currentRoom) {
 		/*
 		 * Item moved into the current room. Only the item needs a
 		 * redraw, not the whole room.
 		 */
-		game->_updateFlags |= (UPDATE_GRAPHICS_ITEMS |
+		_updateFlags |= (UPDATE_GRAPHICS_ITEMS |
 		                       UPDATE_ITEM_LIST);
 	}
 
 	item->room = new_room;
 }
 
-static void eval_instruction(ComprehendGame *game,
-                             FunctionState *func_state,
+void ComprehendGame::eval_instruction(FunctionState *func_state,
                              Instruction *instr,
                              Word *verb, Word *noun) {
-	const byte *opcode_map = game->_opcodeMap;
+	const byte *opcode_map = _opcodeMap;
 	Room *room;
 	Item *item;
 	uint16 index;
 	bool test;
 	uint i, count;
 
-	room = get_room(game, game->_currentRoom);
+	room = get_room(_currentRoom);
 
 	if (DebugMan.isDebugChannelEnabled(kDebugScripts)) {
 		Common::String line;
@@ -513,7 +504,7 @@ static void eval_instruction(ComprehendGame *game,
 				line += "- ";
 		}
 
-		line += g_debugger->dumpInstruction(game, func_state, instr);
+		line += g_debugger->dumpInstruction(this, func_state, instr);
 		debugC(kDebugScripts, "%s", line.c_str());
 	}
 
@@ -548,35 +539,35 @@ static void eval_instruction(ComprehendGame *game,
 
 	switch (opcode_map[instr->opcode]) {
 	case OPCODE_VAR_ADD:
-		game->_variables[instr->operand[0]] +=
-		    game->_variables[instr->operand[1]];
+		_variables[instr->operand[0]] +=
+		    _variables[instr->operand[1]];
 		break;
 
 	case OPCODE_VAR_SUB:
-		game->_variables[instr->operand[0]] -=
-		    game->_variables[instr->operand[1]];
+		_variables[instr->operand[0]] -=
+		    _variables[instr->operand[1]];
 		break;
 
 	case OPCODE_VAR_INC:
-		game->_variables[instr->operand[0]]++;
+		_variables[instr->operand[0]]++;
 		break;
 
 	case OPCODE_VAR_DEC:
-		game->_variables[instr->operand[0]]--;
+		_variables[instr->operand[0]]--;
 		break;
 
 	case OPCODE_VAR_EQ:
 		func_set_test_result(func_state,
-		                     game->_variables[instr->operand[0]] ==
-		                     game->_variables[instr->operand[1]]);
+		                     _variables[instr->operand[0]] ==
+		                     _variables[instr->operand[1]]);
 		break;
 
 	case OPCODE_TURN_TICK:
-		game->_variables[VAR_TURN_COUNT]++;
+		_variables[VAR_TURN_COUNT]++;
 		break;
 
 	case OPCODE_PRINT:
-		console_println(game, game->instrStringLookup(
+		console_println(instrStringLookup(
 		                    instr->operand[0], instr->operand[1])
 		                .c_str());
 		break;
@@ -593,12 +584,12 @@ static void eval_instruction(ComprehendGame *game,
 
 	case OPCODE_NOT_IN_ROOM:
 		func_set_test_result(func_state,
-		                     game->_currentRoom != instr->operand[0]);
+		                     _currentRoom != instr->operand[0]);
 		break;
 
 	case OPCODE_IN_ROOM:
 		func_set_test_result(func_state,
-		                     game->_currentRoom == instr->operand[0]);
+		                     _currentRoom == instr->operand[0]);
 		break;
 
 	case OPCODE_MOVE_TO_ROOM:
@@ -612,7 +603,7 @@ static void eval_instruction(ComprehendGame *game,
 			break;
 		}
 
-		move_to(game, instr->operand[0]);
+		move_to(instr->operand[0]);
 		break;
 
 	case OPCODE_MOVE:
@@ -622,16 +613,16 @@ static void eval_instruction(ComprehendGame *game,
 			      verb->_index, verb->_type);
 
 		if (room->direction[verb->_index - 1])
-			move_to(game, room->direction[verb->_index - 1]);
+			move_to(room->direction[verb->_index - 1]);
 		else
-			console_println(game, game->stringLookup(STRING_CANT_GO).c_str());
+			console_println(stringLookup(STRING_CANT_GO).c_str());
 		break;
 
 	case OPCODE_MOVE_DIRECTION:
 		if (room->direction[instr->operand[0] - 1])
-			move_to(game, room->direction[instr->operand[0] - 1]);
+			move_to(room->direction[instr->operand[0] - 1]);
 		else
-			console_println(game, game->stringLookup(STRING_CANT_GO).c_str());
+			console_println(stringLookup(STRING_CANT_GO).c_str());
 		break;
 
 	case OPCODE_ELSE:
@@ -639,33 +630,33 @@ static void eval_instruction(ComprehendGame *game,
 		break;
 
 	case OPCODE_MOVE_OBJECT_TO_CURRENT_ROOM:
-		item = get_item(game, instr->operand[0] - 1);
-		move_object(game, item, game->_currentRoom);
+		item = get_item(instr->operand[0] - 1);
+		move_object(item, _currentRoom);
 		break;
 
 	case OPCODE_OBJECT_IN_ROOM:
-		item = get_item(game, instr->operand[0] - 1);
+		item = get_item(instr->operand[0] - 1);
 		func_set_test_result(func_state,
 		                     item->room == instr->operand[1]);
 		break;
 
 	case OPCODE_OBJECT_NOT_IN_ROOM:
-		item = get_item(game, instr->operand[0] - 1);
+		item = get_item(instr->operand[0] - 1);
 		func_set_test_result(func_state,
 		                     item->room != instr->operand[1]);
 		break;
 
 	case OPCODE_MOVE_OBJECT_TO_ROOM:
-		item = get_item(game, instr->operand[0] - 1);
-		move_object(game, item, instr->operand[1]);
+		item = get_item(instr->operand[0] - 1);
+		move_object(item, instr->operand[1]);
 		break;
 
 	case OPCODE_INVENTORY_FULL:
-		item = get_item_by_noun(game, noun);
+		item = get_item_by_noun(noun);
 		func_set_test_result(func_state,
-		                     game->_variables[VAR_INVENTORY_WEIGHT] +
+		                     _variables[VAR_INVENTORY_WEIGHT] +
 		                     (item->flags & ITEMF_WEIGHT_MASK) >
-		                     game->_variables[VAR_INVENTORY_LIMIT]);
+		                     _variables[VAR_INVENTORY_LIMIT]);
 		break;
 
 	case OPCODE_DESCRIBE_CURRENT_OBJECT:
@@ -673,8 +664,8 @@ static void eval_instruction(ComprehendGame *game,
 		 * This opcode is only used in version 2
 		 * FIXME - unsure what the single operand is for.
 		 */
-		item = get_item_by_noun(game, noun);
-		g_comprehend->print("%s\n", game->stringLookup(item->long_string).c_str());
+		item = get_item_by_noun(noun);
+		g_comprehend->print("%s\n", stringLookup(item->long_string).c_str());
 		break;
 
 	case OPCODE_CURRENT_OBJECT_IN_ROOM:
@@ -682,8 +673,8 @@ static void eval_instruction(ComprehendGame *game,
 		test = false;
 
 		if (noun) {
-			for (i = 0; i < game->_items.size(); i++) {
-				Item *itemP = &game->_items[i];
+			for (i = 0; i < _items.size(); i++) {
+				Item *itemP = &_items[i];
 
 				if (itemP->word == noun->_index &&
 				        itemP->room == instr->operand[0]) {
@@ -698,49 +689,49 @@ static void eval_instruction(ComprehendGame *game,
 
 	case OPCODE_CURRENT_OBJECT_NOT_PRESENT:
 		/* FIXME - use common code for these two ops */
-		item = get_item_by_noun(game, noun);
+		item = get_item_by_noun(noun);
 		if (item)
 			func_set_test_result(func_state,
-			                     item->room != game->_currentRoom);
+			                     item->room != _currentRoom);
 		else
 			func_set_test_result(func_state, true);
 		break;
 
 	case OPCODE_CURRENT_OBJECT_PRESENT:
-		item = get_item_by_noun(game, noun);
+		item = get_item_by_noun(noun);
 		if (item)
 			func_set_test_result(func_state,
-			                     item->room == game->_currentRoom);
+			                     item->room == _currentRoom);
 		else
 			func_set_test_result(func_state, false);
 		break;
 
 	case OPCODE_HAVE_OBJECT:
-		item = get_item(game, instr->operand[0] - 1);
+		item = get_item(instr->operand[0] - 1);
 		func_set_test_result(func_state,
 		                     item->room == ROOM_INVENTORY);
 		break;
 
 	case OPCODE_NOT_HAVE_CURRENT_OBJECT:
-		item = get_item_by_noun(game, noun);
+		item = get_item_by_noun(noun);
 		func_set_test_result(func_state,
 		                     !item || item->room != ROOM_INVENTORY);
 		break;
 
 	case OPCODE_HAVE_CURRENT_OBJECT:
-		item = get_item_by_noun(game, noun);
+		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(game, instr->operand[0] - 1);
+		item = get_item(instr->operand[0] - 1);
 		func_set_test_result(func_state,
 		                     item->room != ROOM_INVENTORY);
 		break;
 
 	case OPCODE_CURRENT_OBJECT_TAKEABLE:
-		item = get_item_by_noun(game, noun);
+		item = get_item_by_noun(noun);
 		if (!item)
 			func_set_test_result(func_state, false);
 		else
@@ -749,7 +740,7 @@ static void eval_instruction(ComprehendGame *game,
 		break;
 
 	case OPCODE_CURRENT_OBJECT_NOT_TAKEABLE:
-		item = get_item_by_noun(game, noun);
+		item = get_item_by_noun(noun);
 		if (!item)
 			func_set_test_result(func_state, true);
 		else
@@ -758,7 +749,7 @@ static void eval_instruction(ComprehendGame *game,
 		break;
 
 	case OPCODE_CURRENT_OBJECT_IS_NOWHERE:
-		item = get_item_by_noun(game, noun);
+		item = get_item_by_noun(noun);
 		if (!item)
 			func_set_test_result(func_state, false);
 		else
@@ -767,27 +758,27 @@ static void eval_instruction(ComprehendGame *game,
 		break;
 
 	case OPCODE_OBJECT_IS_NOWHERE:
-		item = get_item(game, instr->operand[0] - 1);
+		item = get_item(instr->operand[0] - 1);
 		func_set_test_result(func_state,
 		                     item->room == ROOM_NOWHERE);
 		break;
 
 	case OPCODE_OBJECT_IS_NOT_NOWHERE:
-		item = get_item(game, instr->operand[0] - 1);
+		item = get_item(instr->operand[0] - 1);
 		func_set_test_result(func_state,
 		                     item->room != ROOM_NOWHERE);
 		break;
 
 	case OPCODE_OBJECT_NOT_PRESENT:
-		item = get_item(game, instr->operand[0] - 1);
+		item = get_item(instr->operand[0] - 1);
 		func_set_test_result(func_state,
-		                     item->room != game->_currentRoom);
+		                     item->room != _currentRoom);
 		break;
 
 	case OPCODE_OBJECT_PRESENT:
-		item = get_item(game, instr->operand[0] - 1);
+		item = get_item(instr->operand[0] - 1);
 		func_set_test_result(func_state,
-		                     item->room == game->_currentRoom);
+		                     item->room == _currentRoom);
 		break;
 
 	case OPCODE_OBJECT_NOT_VALID:
@@ -798,106 +789,106 @@ static void eval_instruction(ComprehendGame *game,
 
 	case OPCODE_CURRENT_IS_OBJECT:
 		func_set_test_result(func_state,
-		                     get_item_by_noun(game, noun) != NULL);
+		                     get_item_by_noun(noun) != NULL);
 		break;
 
 	case OPCODE_CURRENT_NOT_OBJECT:
 		func_set_test_result(func_state,
-		                     get_item_by_noun(game, noun) == NULL);
+		                     get_item_by_noun(noun) == NULL);
 		break;
 
 	case OPCODE_REMOVE_OBJECT:
-		item = get_item(game, instr->operand[0] - 1);
-		move_object(game, item, ROOM_NOWHERE);
+		item = get_item(instr->operand[0] - 1);
+		move_object(item, ROOM_NOWHERE);
 		break;
 
 	case OPCODE_REMOVE_CURRENT_OBJECT:
-		item = get_item_by_noun(game, noun);
-		move_object(game, item, ROOM_NOWHERE);
+		item = get_item_by_noun(noun);
+		move_object(item, ROOM_NOWHERE);
 		break;
 
 	case OPCODE_INVENTORY:
-		count = num_objects_in_room(game, ROOM_INVENTORY);
+		count = num_objects_in_room(ROOM_INVENTORY);
 		if (count == 0) {
-			console_println(game, game->stringLookup(STRING_INVENTORY_EMPTY).c_str());
+			console_println(stringLookup(STRING_INVENTORY_EMPTY).c_str());
 			break;
 		}
 
-		console_println(game, game->stringLookup(STRING_INVENTORY).c_str());
-		for (i = 0; i < game->_items.size(); i++) {
-			item = &game->_items[i];
+		console_println(stringLookup(STRING_INVENTORY).c_str());
+		for (i = 0; i < _items.size(); i++) {
+			item = &_items[i];
 			if (item->room == ROOM_INVENTORY)
 				g_comprehend->print("%s\n",
-				                    game->stringLookup(item->string_desc).c_str());
+				                    stringLookup(item->string_desc).c_str());
 		}
 		break;
 
 	case OPCODE_INVENTORY_ROOM:
-		count = num_objects_in_room(game, instr->operand[0]);
+		count = num_objects_in_room(instr->operand[0]);
 		if (count == 0) {
-			console_println(game, game->stringLookup(instr->operand[1] + 1).c_str());
+			console_println(stringLookup(instr->operand[1] + 1).c_str());
 			break;
 		}
 
-		console_println(game, game->stringLookup(instr->operand[1]).c_str());
-		for (i = 0; i < game->_items.size(); i++) {
-			item = &game->_items[i];
+		console_println(stringLookup(instr->operand[1]).c_str());
+		for (i = 0; i < _items.size(); i++) {
+			item = &_items[i];
 			if (item->room == instr->operand[0])
 				g_comprehend->print("%s\n",
-				                    game->stringLookup(item->string_desc).c_str());
+				                    stringLookup(item->string_desc).c_str());
 		}
 		break;
 
 	case OPCODE_MOVE_CURRENT_OBJECT_TO_ROOM:
-		item = get_item_by_noun(game, noun);
+		item = get_item_by_noun(noun);
 		if (!item)
 			error("Bad current object\n");
 
-		move_object(game, item, instr->operand[0]);
+		move_object(item, instr->operand[0]);
 		break;
 
 	case OPCODE_DROP_OBJECT:
-		item = get_item(game, instr->operand[0] - 1);
-		move_object(game, item, game->_currentRoom);
+		item = get_item(instr->operand[0] - 1);
+		move_object(item, _currentRoom);
 		break;
 
 	case OPCODE_DROP_CURRENT_OBJECT:
-		item = get_item_by_noun(game, noun);
+		item = get_item_by_noun(noun);
 		if (!item)
 			error("Attempt to take object failed\n");
 
-		move_object(game, item, game->_currentRoom);
+		move_object(item, _currentRoom);
 		break;
 
 	case OPCODE_TAKE_CURRENT_OBJECT:
-		item = get_item_by_noun(game, noun);
+		item = get_item_by_noun(noun);
 		if (!item)
 			error("Attempt to take object failed\n");
 
-		move_object(game, item, ROOM_INVENTORY);
+		move_object(item, ROOM_INVENTORY);
 		break;
 
 	case OPCODE_TAKE_OBJECT:
-		item = get_item(game, instr->operand[0] - 1);
-		move_object(game, item, ROOM_INVENTORY);
+		item = get_item(instr->operand[0] - 1);
+		move_object(item, ROOM_INVENTORY);
 		break;
 
 	case OPCODE_TEST_FLAG:
 		func_set_test_result(func_state,
-		                     game->_flags[instr->operand[0]]);
+		                     _flags[instr->operand[0]]);
 		break;
 
 	case OPCODE_TEST_NOT_FLAG:
 		func_set_test_result(func_state,
-		                     !game->_flags[instr->operand[0]]);
+		                     !_flags[instr->operand[0]]);
 		break;
 
 	case OPCODE_CLEAR_FLAG:
-		game->_flags[instr->operand[0]] = false;
+		_flags[instr->operand[0]] = false;
 		break;
 
 	case OPCODE_SET_FLAG:
-		game->_flags[instr->operand[0]] = true;
+		_flags[instr->operand[0]] = true;
 		break;
 
 	case OPCODE_OR:
@@ -910,17 +901,17 @@ static void eval_instruction(ComprehendGame *game,
 		break;
 
 	case OPCODE_SET_OBJECT_DESCRIPTION:
-		item = get_item(game, instr->operand[0] - 1);
+		item = get_item(instr->operand[0] - 1);
 		item->string_desc = (instr->operand[2] << 8) | instr->operand[1];
 		break;
 
 	case OPCODE_SET_OBJECT_LONG_DESCRIPTION:
-		item = get_item(game, instr->operand[0] - 1);
+		item = get_item(instr->operand[0] - 1);
 		item->long_string = (instr->operand[2] << 8) | instr->operand[1];
 		break;
 
 	case OPCODE_SET_ROOM_DESCRIPTION:
-		room = get_room(game, instr->operand[0]);
+		room = get_room(instr->operand[0]);
 		switch (instr->operand[2]) {
 		case 0x80:
 			room->string_desc = instr->operand[1];
@@ -939,29 +930,29 @@ static void eval_instruction(ComprehendGame *game,
 		break;
 
 	case OPCODE_SET_OBJECT_GRAPHIC:
-		item = get_item(game, instr->operand[0] - 1);
+		item = get_item(instr->operand[0] - 1);
 		item->graphic = instr->operand[1];
-		if (item->room == game->_currentRoom)
-			game->_updateFlags |= UPDATE_GRAPHICS;
+		if (item->room == _currentRoom)
+			_updateFlags |= UPDATE_GRAPHICS;
 		break;
 
 	case OPCODE_SET_ROOM_GRAPHIC:
-		room = get_room(game, instr->operand[0]);
+		room = get_room(instr->operand[0]);
 		room->graphic = instr->operand[1];
-		if (instr->operand[0] == game->_currentRoom)
-			game->_updateFlags |= UPDATE_GRAPHICS;
+		if (instr->operand[0] == _currentRoom)
+			_updateFlags |= UPDATE_GRAPHICS;
 		break;
 
 	case OPCODE_CALL_FUNC:
 		index = instr->operand[0];
 		if (instr->operand[1] == 0x81)
 			index += 256;
-		if (index >= game->_functions.size())
+		if (index >= _functions.size())
 			error("Bad function %.4x >= %.4x\n",
-			      index, game->_functions.size());
+			      index, _functions.size());
 
 		debugC(kDebugScripts, "Calling subfunction %.4x", index);
-		eval_function(game, &game->_functions[index], verb, noun);
+		eval_function(&_functions[index], verb, noun);
 		break;
 
 	case OPCODE_TEST_FALSE:
@@ -988,7 +979,7 @@ static void eval_instruction(ComprehendGame *game,
 		break;
 
 	case OPCODE_SET_STRING_REPLACEMENT:
-		game->_currentReplaceWord = instr->operand[0] - 1;
+		_currentReplaceWord = instr->operand[0] - 1;
 		break;
 
 	case OPCODE_SET_CURRENT_NOUN_STRING_REPLACEMENT:
@@ -997,13 +988,13 @@ static void eval_instruction(ComprehendGame *game,
 		 * maybe capitalisation?
 		 */
 		if (noun && (noun->_type & WORD_TYPE_NOUN_PLURAL))
-			game->_currentReplaceWord = 3;
+			_currentReplaceWord = 3;
 		else if (noun && (noun->_type & WORD_TYPE_FEMALE))
-			game->_currentReplaceWord = 0;
+			_currentReplaceWord = 0;
 		else if (noun && (noun->_type & WORD_TYPE_MALE))
-			game->_currentReplaceWord = 1;
+			_currentReplaceWord = 1;
 		else
-			game->_currentReplaceWord = 2;
+			_currentReplaceWord = 2;
 		break;
 
 	case OPCODE_DRAW_ROOM:
@@ -1020,7 +1011,7 @@ static void eval_instruction(ComprehendGame *game,
 
 	case OPCODE_SPECIAL:
 		/* Game specific opcode */
-		game->handleSpecialOpcode(instr->operand[0]);
+		handleSpecialOpcode(instr->operand[0]);
 		break;
 
 	default:
@@ -1038,16 +1029,7 @@ static void eval_instruction(ComprehendGame *game,
 	}
 }
 
-/*
- * Comprehend functions consist of test and command instructions (if the MSB
- * of the opcode is set then it is a command). Functions are parsed by
- * evaluating each test until a command instruction is encountered. If the
- * overall result of the tests was true then the command instructions are
- * executed until either a test instruction is found or the end of the function
- * is reached. Otherwise the commands instructions are skipped over and the
- * next test sequence (if there is one) is tried.
- */
-void eval_function(ComprehendGame *game, Function *func,
+void ComprehendGame::eval_function(Function *func,
                    Word *verb, Word *noun) {
 	FunctionState func_state;
 	uint i;
@@ -1064,23 +1046,22 @@ void eval_function(ComprehendGame *game, Function *func,
 			break;
 		}
 
-		eval_instruction(game, &func_state, &func->instructions[i],
+		eval_instruction(&func_state, &func->instructions[i],
 		                 verb, noun);
 	}
 }
 
-static void skip_whitespace(char **p) {
+void ComprehendGame::skip_whitespace(char **p) {
 	while (**p && Common::isSpace(**p))
 		(*p)++;
 }
 
-static void skip_non_whitespace(char **p) {
+void ComprehendGame::skip_non_whitespace(char **p) {
 	while (**p && !Common::isSpace(**p) && **p != ',' && **p != '\n')
 		(*p)++;
 }
 
-static bool handle_sentence(ComprehendGame *game,
-                            Sentence *sentence) {
+bool ComprehendGame::handle_sentence(Sentence *sentence) {
 	Function *func;
 	Action *action;
 	uint i, j;
@@ -1089,8 +1070,8 @@ static bool handle_sentence(ComprehendGame *game,
 		return false;
 
 	/* Find a matching action */
-	for (i = 0; i < game->_actions.size(); i++) {
-		action = &game->_actions[i];
+	for (i = 0; i < _actions.size(); i++) {
+		action = &_actions[i];
 
 		if (action->type == ACTION_VERB_OPT_NOUN &&
 		        sentence->nr_words > action->nr_words + 1)
@@ -1113,19 +1094,19 @@ static bool handle_sentence(ComprehendGame *game,
 		}
 		if (j == action->nr_words) {
 			/* Match */
-			func = &game->_functions[action->function];
-			eval_function(game, func,
+			func = &_functions[action->function];
+			eval_function(func,
 			              &sentence->words[0], &sentence->words[1]);
 			return true;
 		}
 	}
 
 	/* No matching action */
-	console_println(game, game->stringLookup(STRING_DONT_UNDERSTAND).c_str());
+	console_println(stringLookup(STRING_DONT_UNDERSTAND).c_str());
 	return false;
 }
 
-static void read_sentence(ComprehendGame *game, char **line,
+void ComprehendGame::read_sentence(char **line,
                           Sentence *sentence) {
 	bool sentence_end = false;
 	char *word_string, *p = *line;
@@ -1151,7 +1132,7 @@ static void read_sentence(ComprehendGame *game, char **line,
 		}
 
 		/* Find the dictionary word for this */
-		word = dict_find_word_by_string(game, word_string);
+		word = dict_find_word_by_string(this, word_string);
 		if (!word)
 			sentence->words[sentence->nr_words].clear();
 		else
@@ -1163,8 +1144,7 @@ static void read_sentence(ComprehendGame *game, char **line,
 			index = sentence->nr_words;
 
 			/* See if this word and the previous are a word pair */
-			pair = is_word_pair(game,
-			                    &sentence->words[index - 2],
+			pair = is_word_pair(&sentence->words[index - 2],
 			                    &sentence->words[index - 1]);
 			if (pair) {
 				sentence->words[index - 2]._index = pair->index;
@@ -1183,28 +1163,28 @@ static void read_sentence(ComprehendGame *game, char **line,
 	*line = p;
 }
 
-static void beforeTurn(ComprehendGame *game) {
+void ComprehendGame::doBeforeTurn() {
 	// Run the game specific before turn bits
-	game->beforeTurn();
+	beforeTurn();
 
 	// Run the each turn functions
-	eval_function(game, &game->_functions[0], NULL, NULL);
+	eval_function(&_functions[0], NULL, NULL);
 
-	update(game);
+	update();
 }
 
-static void after_turn(ComprehendGame *game) {
+void ComprehendGame::doAfterTurn() {
 	// Do post turn game specific bits
-	game->afterTurn();
+	afterTurn();
 }
 
-static void read_input(ComprehendGame *game) {
+void ComprehendGame::read_input() {
 	Sentence sentence;
 	char *line = NULL, buffer[1024];
 	bool handled;
 
-	game->beforePrompt();
-	beforeTurn(game);
+	beforePrompt();
+	doBeforeTurn();
 
 	do {
 		g_comprehend->print("> ");
@@ -1217,10 +1197,10 @@ static void read_input(ComprehendGame *game) {
 	line = &buffer[0];
 
 	while (1) {
-		read_sentence(game, &line, &sentence);
-		handled = handle_sentence(game, &sentence);
+		read_sentence(&line, &sentence);
+		handled = handle_sentence(&sentence);
 		if (handled)
-			after_turn(game);
+			doAfterTurn();
 
 		/* FIXME - handle the 'before you can continue' case */
 		if (*line == '\0')
@@ -1228,18 +1208,16 @@ static void read_input(ComprehendGame *game) {
 		line++;
 
 		if (handled)
-			beforeTurn(game);
+			doBeforeTurn();
 	}
 }
 
-void comprehend_play_game(ComprehendGame *game) {
-	console_init();
-
-	game->beforeGame();
+void ComprehendGame::playGame() {
+	beforeGame();
 
-	game->_updateFlags = (uint)UPDATE_ALL;
+	_updateFlags = (uint)UPDATE_ALL;
 	while (!g_comprehend->shouldQuit())
-		read_input(game);
+		read_input();
 }
 
 } // namespace Comprehend
diff --git a/engines/glk/comprehend/game.h b/engines/glk/comprehend/game.h
index 6fa667a314..3d0f5e2143 100644
--- a/engines/glk/comprehend/game.h
+++ b/engines/glk/comprehend/game.h
@@ -36,6 +36,7 @@ namespace Comprehend {
 #define ROOM_IS_TOO_BRIGHT 2
 
 struct GameStrings;
+struct Sentence;
 
 class ComprehendGame : public GameInfo, public OpcodeMap {
 public:
@@ -48,6 +49,46 @@ public:
 
 	const GameStrings *_gameStrings;
 
+private:
+	WordIndex *is_word_pair(Word *word1, Word *word2);
+	Item *get_item_by_noun(Word *noun);
+	void update_graphics();
+	void describe_objects_in_current_room();
+	void update();
+	void move_to(uint8 room);
+	void func_set_test_result(FunctionState *func_state, bool value);
+	size_t num_objects_in_room(int room);
+	void eval_instruction(FunctionState *func_state, Instruction *instr,
+		Word *verb, Word *noun);
+	void skip_whitespace(char **p);
+	void skip_non_whitespace(char **p);
+	bool handle_sentence(Sentence *sentence);
+	void read_sentence(char **line, Sentence *sentence);
+	void doBeforeTurn();
+	void doAfterTurn();
+	void read_input();
+
+protected:
+	void game_save();
+	void game_restore();
+	void game_restart();
+	int console_get_key();
+	void console_println(const char *text);
+	Room *get_room(uint16 index);
+	Item *get_item(uint16 index);
+	void move_object(Item *item, int new_room);
+
+	/*
+	 * Comprehend functions consist of test and command instructions (if the MSB
+	 * of the opcode is set then it is a command). Functions are parsed by
+	 * evaluating each test until a command instruction is encountered. If the
+	 * overall result of the tests was true then the command instructions are
+	 * executed until either a test instruction is found or the end of the function
+	 * is reached. Otherwise the commands instructions are skipped over and the
+	 * next test sequence (if there is one) is tried.
+	 */
+	void eval_function(Function *func, Word *verb, Word *noun);
+
 public:
 	ComprehendGame();
 	virtual ~ComprehendGame();
@@ -69,6 +110,8 @@ public:
 
 	Common::String stringLookup(uint16 index);
 	Common::String instrStringLookup(uint8 index, uint8 table);
+
+	void playGame();
 };
 
 void console_println(ComprehendGame *game, const char *text);
diff --git a/engines/glk/comprehend/game_cc.cpp b/engines/glk/comprehend/game_cc.cpp
index fe1c2c1f85..dd8840497b 100644
--- a/engines/glk/comprehend/game_cc.cpp
+++ b/engines/glk/comprehend/game_cc.cpp
@@ -55,13 +55,13 @@ void CrimsonCrownGame::handleSpecialOpcode(uint8 operand) {
 	case 0x01:
 		// Enter the Vampire's throne room
 		assert(_diskNum == 1);
-		eval_function(this, &_functions[0xe], nullptr, nullptr);
+		eval_function(&_functions[0xe], nullptr, nullptr);
 		break;
 
 	case 0x03:
 		// Game over - failure
 		setupDisk(1);
-		game_restart(this);
+		game_restart();
 		break;
 
 	case 0x05:
@@ -71,16 +71,16 @@ void CrimsonCrownGame::handleSpecialOpcode(uint8 operand) {
 		} else {
 			// Won the game.
 			// FIXME: The merchant ship should arrives, etc.
-			game_restart(this);
+			game_restart();
 		}
 		break;
 
 	case 0x06:
-		game_save(this);
+		game_save();
 		break;
 
 	case 0x07:
-		game_restore(this);
+		game_restore();
 		break;
 
 	default:
diff --git a/engines/glk/comprehend/game_oo.cpp b/engines/glk/comprehend/game_oo.cpp
index 4e52d0daa6..d5a9db601b 100644
--- a/engines/glk/comprehend/game_oo.cpp
+++ b/engines/glk/comprehend/game_oo.cpp
@@ -117,17 +117,17 @@ void OOToposGame::handleSpecialOpcode(uint8 operand) {
 	// fall through
 	case 0x04:
 		// Restart game
-		game_restart(this);
+		game_restart();
 		break;
 
 	case 0x06:
 		// Save game
-		game_save(this);
+		game_save();
 		break;
 
 	case 0x07:
 		// Restore game
-		game_restore(this);
+		game_restore();
 		break;
 	}
 }
diff --git a/engines/glk/comprehend/game_tr.cpp b/engines/glk/comprehend/game_tr.cpp
index 80ffe499b1..abda8a34dd 100644
--- a/engines/glk/comprehend/game_tr.cpp
+++ b/engines/glk/comprehend/game_tr.cpp
@@ -70,7 +70,7 @@ void TransylvaniaGame::updateMonster(const TransylvaniaMonster *monsterInfo) {
 	room = &_rooms[_currentRoom];
 	turn_count = _variables[VAR_TURN_COUNT];
 
-	monster = get_item(this, monsterInfo->object);
+	monster = get_item(monsterInfo->object);
 	if (monster->room == _currentRoom) {
 		// The monster is in the current room - leave it there
 		return;
@@ -85,10 +85,10 @@ void TransylvaniaGame::updateMonster(const TransylvaniaMonster *monsterInfo) {
 		 * it back to limbo.
 		 */
 		if ((g_comprehend->getRandomNumber(0x7fffffff) % monsterInfo->randomness) == 0) {
-			move_object(this, monster, _currentRoom);
+			move_object(monster, _currentRoom);
 			_variables[0xf] = turn_count + 1;
 		} else {
-			move_object(this, monster, ROOM_NOWHERE);
+			move_object(monster, ROOM_NOWHERE);
 		}
 	}
 }
@@ -123,11 +123,11 @@ void TransylvaniaGame::handleSpecialOpcode(uint8 operand) {
 		break;
 
 	case 0x06:
-		game_save(this);
+		game_save();
 		break;
 
 	case 0x07:
-		game_restore(this);
+		game_restore();
 		break;
 
 	case 0x03:
@@ -138,7 +138,7 @@ void TransylvaniaGame::handleSpecialOpcode(uint8 operand) {
 	// fall through
 	case 0x08:
 		// Restart game
-		game_restart(this);
+		game_restart();
 		break;
 
 	case 0x09:
@@ -160,14 +160,14 @@ void TransylvaniaGame::beforeGame() {
 	g_comprehend->drawPicture(TITLE_IMAGE);
 
 	// Welcome to Transylvania - sign your name
-	console_println(this, _strings[0x20].c_str());
+	console_println(_strings[0x20].c_str());
 	g_comprehend->readLine(buffer, sizeof(buffer));
 
 	// The player's name is stored in word 0
 	_replaceWords[0] = Common::String(buffer);
 
 	// And your next of kin - This isn't stored by the game
-	console_println(this, _strings[0x21].c_str());
+	console_println(_strings[0x21].c_str());
 	g_comprehend->readLine(buffer, sizeof(buffer));
 }
 


Commit: 0e244a6b3b79d248a4cf1ede8a8940d4c8a0635a
    https://github.com/scummvm/scummvm/commit/0e244a6b3b79d248a4cf1ede8a8940d4c8a0635a
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2020-06-10T17:49:33-07:00

Commit Message:
GLK: COMPREHEND: Refactoring static methods into GameData class

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


diff --git a/engines/glk/comprehend/comprehend.cpp b/engines/glk/comprehend/comprehend.cpp
index 5ce17b3130..48f5c39a45 100644
--- a/engines/glk/comprehend/comprehend.cpp
+++ b/engines/glk/comprehend/comprehend.cpp
@@ -69,7 +69,7 @@ void Comprehend::runGame() {
 	// Lookup game
 	createGame();
 
-	comprehend_load_game(_game);
+	_game->loadGame();
 	_game->playGame();
 
 	deinitialize();
diff --git a/engines/glk/comprehend/comprehend.h b/engines/glk/comprehend/comprehend.h
index b2ad87cdc8..609d18e899 100644
--- a/engines/glk/comprehend/comprehend.h
+++ b/engines/glk/comprehend/comprehend.h
@@ -34,8 +34,6 @@ namespace Comprehend {
 
 #define PATH_MAX 256
 
-struct GameInfo;
-struct gameState;
 class DrawSurface;
 class Pics;
 
diff --git a/engines/glk/comprehend/game.cpp b/engines/glk/comprehend/game.cpp
index d1f7cbcec0..c67ef5883d 100644
--- a/engines/glk/comprehend/game.cpp
+++ b/engines/glk/comprehend/game.cpp
@@ -48,7 +48,7 @@ struct Sentence {
 	}
 };
 
-ComprehendGame::ComprehendGame() : _colorTable(0), _gameStrings(nullptr) {
+ComprehendGame::ComprehendGame() : _gameStrings(nullptr) {
 }
 
 ComprehendGame::~ComprehendGame() {
@@ -284,7 +284,7 @@ void ComprehendGame::game_restart() {
 	console_println(stringLookup(_gameStrings->game_restart).c_str());
 	console_get_key();
 
-	comprehend_load_game(this);
+	loadGame();
 	_updateFlags = UPDATE_ALL;
 }
 
diff --git a/engines/glk/comprehend/game.h b/engines/glk/comprehend/game.h
index 3d0f5e2143..8ced85b30b 100644
--- a/engines/glk/comprehend/game.h
+++ b/engines/glk/comprehend/game.h
@@ -38,15 +38,8 @@ namespace Comprehend {
 struct GameStrings;
 struct Sentence;
 
-class ComprehendGame : public GameInfo, public OpcodeMap {
+class ComprehendGame : public GameData, public OpcodeMap {
 public:
-	Common::String _gameDataFile;
-	Common::Array<StringFile> _stringFiles;
-	Common::StringArray _locationGraphicFiles;
-	Common::StringArray _itemGraphicFiles;
-	Common::String _titleGraphicFile;
-	unsigned _colorTable;
-
 	const GameStrings *_gameStrings;
 
 private:
@@ -89,6 +82,11 @@ protected:
 	 */
 	void eval_function(Function *func, Word *verb, Word *noun);
 
+	void parse_header(FileBuffer *fb) override {
+		GameData::parse_header(fb);
+		loadOpcodes(_comprehendVersion);
+	}
+
 public:
 	ComprehendGame();
 	virtual ~ComprehendGame();
diff --git a/engines/glk/comprehend/game_data.cpp b/engines/glk/comprehend/game_data.cpp
index d9694d09b5..8ca5ccc007 100644
--- a/engines/glk/comprehend/game_data.cpp
+++ b/engines/glk/comprehend/game_data.cpp
@@ -160,7 +160,7 @@ void GameHeader::clear() {
 
 /*-------------------------------------------------------*/
 
-void GameInfo::clearInfo() {
+void GameData::clearGame() {
 	_header.clear();
 	_comprehendVersion = 0;
 	_startRoom = 0;
@@ -169,9 +169,10 @@ void GameInfo::clearInfo() {
 	_nr_words = 0;
 	_currentReplaceWord = 0;
 	_updateFlags = 0;
+	_colorTable = 0;
+
 	_strings.clear();
 	_strings2.clear();
-
 	_rooms.clear();
 	_items.clear();
 	_wordMaps.clear();
@@ -183,22 +184,12 @@ void GameInfo::clearInfo() {
 	Common::fill(&_variables[0], &_variables[MAX_VARIABLES], 0);
 }
 
-static void parse_header_le16(FileBuffer *fb, uint16 *val) {
+void GameData::parse_header_le16(FileBuffer *fb, uint16 *val) {
 	*val = fb->readUint16LE();
 	*val += (uint16)magic_offset;
 }
 
-static size_t opcode_nr_operands(uint8 opcode) {
-	/* Number of operands is encoded in the low 2 bits */
-	return opcode & 0x3;
-}
-
-static bool opcode_is_command(uint8 opcode) {
-	/* If the MSB is set the instruction is a command */
-	return opcode & 0x80;
-}
-
-static uint8 parse_vm_instruction(FileBuffer *fb,
+uint8 GameData::parse_vm_instruction(FileBuffer *fb,
                                   Instruction *instr) {
 	uint i;
 
@@ -215,7 +206,7 @@ static uint8 parse_vm_instruction(FileBuffer *fb,
 	return instr->opcode;
 }
 
-static void parse_function(FileBuffer *fb, Function *func) {
+void GameData::parse_function(FileBuffer *fb, Function *func) {
 	Instruction *instruction;
 	const uint8 *p;
 	uint8 opcode;
@@ -237,8 +228,8 @@ static void parse_function(FileBuffer *fb, Function *func) {
 	}
 }
 
-static void parse_vm(ComprehendGame *game, FileBuffer *fb) {
-	fb->seek(game->_header.addr_vm);
+void GameData::parse_vm(FileBuffer *fb) {
+	fb->seek(_header.addr_vm);
 
 	while (1) {
 		Function func;
@@ -247,11 +238,11 @@ static void parse_vm(ComprehendGame *game, FileBuffer *fb) {
 		if (func.nr_instructions == 0)
 			break;
 
-		game->_functions.push_back(func);
+		_functions.push_back(func);
 	}
 }
 
-static void parse_action_table_vvnn(ComprehendGame *game, FileBuffer *fb) {
+void GameData::parse_action_table_vvnn(FileBuffer *fb) {
 	uint8 verb, count;
 	int i, j;
 
@@ -265,7 +256,7 @@ static void parse_action_table_vvnn(ComprehendGame *game, FileBuffer *fb) {
 	*     u8:   noun2
 	*     le16: action
 	*/
-	fb->seek(game->_header.addr_actions_vvnn);
+	fb->seek(_header.addr_actions_vvnn);
 	while (1) {
 		verb = fb->readByte();
 		if (verb == 0)
@@ -288,12 +279,12 @@ static void parse_action_table_vvnn(ComprehendGame *game, FileBuffer *fb) {
 				action.word[j + 1] = fb->readByte();
 			action.function = fb->readUint16LE();
 
-			game->_actions.push_back(action);
+			_actions.push_back(action);
 		}
 	}
 }
 
-static void parse_action_table_vnjn(ComprehendGame *game, FileBuffer *fb) {
+void GameData::parse_action_table_vnjn(FileBuffer *fb) {
 	uint8 join, count;
 	int i;
 
@@ -307,7 +298,7 @@ static void parse_action_table_vnjn(ComprehendGame *game, FileBuffer *fb) {
 	*     u8:   noun2
 	*     le16: action
 	*/
-	fb->seek(game->_header.addr_actions_vnjn);
+	fb->seek(_header.addr_actions_vnjn);
 	while (1) {
 		join = fb->readByte();
 		if (join == 0)
@@ -331,12 +322,12 @@ static void parse_action_table_vnjn(ComprehendGame *game, FileBuffer *fb) {
 			action.word[3] = fb->readByte();
 			action.function = fb->readUint16LE();
 
-			game->_actions.push_back(action);
+			_actions.push_back(action);
 		}
 	}
 }
 
-static void parse_action_table_vjn(ComprehendGame *game, FileBuffer *fb) {
+void GameData::parse_action_table_vjn(FileBuffer *fb) {
 	uint8 join, count;
 	int i;
 
@@ -349,7 +340,7 @@ static void parse_action_table_vjn(ComprehendGame *game, FileBuffer *fb) {
 	*     u8:   noun
 	*     le16: action
 	*/
-	fb->seek(game->_header.addr_actions_vjn);
+	fb->seek(_header.addr_actions_vjn);
 	while (1) {
 		join = fb->readByte();
 		if (join == 0)
@@ -370,12 +361,12 @@ static void parse_action_table_vjn(ComprehendGame *game, FileBuffer *fb) {
 			action.word[2] = fb->readByte();
 			action.function = fb->readUint16LE();
 
-			game->_actions.push_back(action);
+			_actions.push_back(action);
 		}
 	}
 }
 
-static void parse_action_table_vdn(ComprehendGame *game, FileBuffer *fb) {
+void GameData::parse_action_table_vdn(FileBuffer *fb) {
 	uint8 verb, count;
 	int i;
 
@@ -388,7 +379,7 @@ static void parse_action_table_vdn(ComprehendGame *game, FileBuffer *fb) {
 	*     u8:   noun
 	*     le16: action
 	*/
-	fb->seek(game->_header.addr_actions_vdn);
+	fb->seek(_header.addr_actions_vdn);
 	while (1) {
 		verb = fb->readByte();
 		if (verb == 0)
@@ -409,12 +400,12 @@ static void parse_action_table_vdn(ComprehendGame *game, FileBuffer *fb) {
 			action.word[2] = fb->readByte();
 			action.function = fb->readUint16LE();
 
-			game->_actions.push_back(action);
+			_actions.push_back(action);
 		}
 	}
 }
 
-static void parse_action_table_vnn(ComprehendGame *game, FileBuffer *fb) {
+void GameData::parse_action_table_vnn(FileBuffer *fb) {
 	uint8 verb, count;
 	int i;
 
@@ -427,7 +418,7 @@ static void parse_action_table_vnn(ComprehendGame *game, FileBuffer *fb) {
 	*     u8:   noun2
 	*     le16: action
 	*/
-	fb->seek(game->_header.addr_actions_vnn);
+	fb->seek(_header.addr_actions_vnn);
 	while (1) {
 		/* 2-byte header */
 		verb = fb->readByte();
@@ -449,12 +440,12 @@ static void parse_action_table_vnn(ComprehendGame *game, FileBuffer *fb) {
 			action.word[2] = fb->readByte();
 			action.function = fb->readUint16LE();
 
-			game->_actions.push_back(action);
+			_actions.push_back(action);
 		}
 	}
 }
 
-static void parse_action_table_vn(ComprehendGame *game, FileBuffer *fb) {
+void GameData::parse_action_table_vn(FileBuffer *fb) {
 	uint8 verb, count;
 	int i;
 
@@ -466,7 +457,7 @@ static void parse_action_table_vn(ComprehendGame *game, FileBuffer *fb) {
 	*     u8:   noun
 	*     le16: action
 	*/
-	fb->seek(game->_header.addr_actions_vn);
+	fb->seek(_header.addr_actions_vn);
 	while (1) {
 		/* 2-byte header */
 		verb = fb->readByte();
@@ -486,12 +477,12 @@ static void parse_action_table_vn(ComprehendGame *game, FileBuffer *fb) {
 			action.word[1] = fb->readByte();
 			action.function = fb->readUint16LE();
 
-			game->_actions.push_back(action);
+			_actions.push_back(action);
 		}
 	}
 }
 
-static void parse_action_table_v(ComprehendGame *game, FileBuffer *fb) {
+void GameData::parse_action_table_v(FileBuffer *fb) {
 	uint8 verb, nr_funcs;
 	uint16 func;
 	int i;
@@ -503,7 +494,7 @@ static void parse_action_table_v(ComprehendGame *game, FileBuffer *fb) {
 	* u8: count (num actions)
 	*     le16: action
 	*/
-	fb->seek(game->_header.addr_actions_v);
+	fb->seek(_header.addr_actions_v);
 	while (1) {
 		verb = fb->readByte();
 		if (verb == 0)
@@ -528,45 +519,44 @@ static void parse_action_table_v(ComprehendGame *game, FileBuffer *fb) {
 				action.function = func;
 		}
 
-		game->_actions.push_back(action);
+		_actions.push_back(action);
 	}
 }
 
-static void parse_action_table(ComprehendGame *game,
-                               FileBuffer *fb) {
-	game->_actions.clear();
+void GameData::parse_action_table(FileBuffer *fb) {
+	_actions.clear();
 
-	if (game->_comprehendVersion == 1) {
-		parse_action_table_vvnn(game, fb);
-		parse_action_table_vdn(game, fb);
+	if (_comprehendVersion == 1) {
+		parse_action_table_vvnn(fb);
+		parse_action_table_vdn(fb);
 	}
-	if (game->_comprehendVersion >= 2) {
-		parse_action_table_vnn(game, fb);
+	if (_comprehendVersion >= 2) {
+		parse_action_table_vnn(fb);
 	}
 
-	parse_action_table_vnjn(game, fb);
-	parse_action_table_vjn(game, fb);
-	parse_action_table_vn(game, fb);
-	parse_action_table_v(game, fb);
+	parse_action_table_vnjn(fb);
+	parse_action_table_vjn(fb);
+	parse_action_table_vn(fb);
+	parse_action_table_v(fb);
 }
 
-static void parse_dictionary(ComprehendGame *game, FileBuffer *fb) {
+void GameData::parse_dictionary(FileBuffer *fb) {
 	uint i;
 
 	// FIXME - fixed size 0xff array?
-	game->_words = (Word *)malloc(game->_nr_words * sizeof(Word));
+	_words = (Word *)malloc(_nr_words * sizeof(Word));
 
-	fb->seek(game->_header.addr_dictionary);
-	for (i = 0; i < game->_nr_words; i++)
-		game->_words[i].load(fb);
+	fb->seek(_header.addr_dictionary);
+	for (i = 0; i < _nr_words; i++)
+		_words[i].load(fb);
 }
 
-static void parse_word_map(ComprehendGame *game, FileBuffer *fb) {
+void GameData::parse_word_map(FileBuffer *fb) {
 	uint8 index, type;
 	uint i;
 
-	game->_wordMaps.clear();
-	fb->seek(game->_header.addr_word_map);
+	_wordMaps.clear();
+	fb->seek(_header.addr_word_map);
 
 	/*
 	* Parse the word pair table. Each entry has a pair of dictionary
@@ -588,7 +578,7 @@ static void parse_word_map(ComprehendGame *game, FileBuffer *fb) {
 		map.word[1].index = fb->readByte();
 		map.word[1].type = fb->readByte();
 
-		game->_wordMaps.push_back(map);
+		_wordMaps.push_back(map);
 	}
 
 	/* Consume two more null bytes (type and index were also null) */
@@ -599,71 +589,71 @@ static void parse_word_map(ComprehendGame *game, FileBuffer *fb) {
 	* index/type. The first and second words from above map to the
 	* target word here. E.g. 'go north' -> 'north'.
 	*/
-	for (i = 0; i < game->_wordMaps.size(); i++) {
-		WordMap &map = game->_wordMaps[i];
+	for (i = 0; i < _wordMaps.size(); i++) {
+		WordMap &map = _wordMaps[i];
 
 		map.word[2].index = fb->readByte();
 		map.word[2].type = fb->readByte();
 	}
 }
 
-static void parse_items(ComprehendGame *game, FileBuffer *fb) {
-	size_t nr_items = game->_header.nr_items;
-	game->_items.resize(nr_items);
+void GameData::parse_items(FileBuffer *fb) {
+	size_t nr_items = _header.nr_items;
+	_items.resize(nr_items);
 
 	/* Item descriptions */
-	fb->seek(game->_header.addr_item_strings);
-	file_buf_get_array_le16(fb, 0, game->_items, string_desc, nr_items);
+	fb->seek(_header.addr_item_strings);
+	file_buf_get_array_le16(fb, 0, _items, string_desc, nr_items);
 
-	if (game->_comprehendVersion == 2) {
+	if (_comprehendVersion == 2) {
 		/* Comprehend version 2 adds long string descriptions */
-		fb->seek(game->_header.addr_item_strings +
-		         (game->_items.size() * sizeof(uint16)));
-		file_buf_get_array_le16(fb, 0, game->_items, long_string, nr_items);
+		fb->seek(_header.addr_item_strings +
+		         (_items.size() * sizeof(uint16)));
+		file_buf_get_array_le16(fb, 0, _items, long_string, nr_items);
 	}
 
 	/* Item flags */
-	fb->seek(game->_header.addr_item_flags);
-	file_buf_get_array_u8(fb, 0, game->_items, flags, nr_items);
+	fb->seek(_header.addr_item_flags);
+	file_buf_get_array_u8(fb, 0, _items, flags, nr_items);
 
 	/* Item word */
-	fb->seek(game->_header.addr_item_word);
-	file_buf_get_array_u8(fb, 0, game->_items, word, nr_items);
+	fb->seek(_header.addr_item_word);
+	file_buf_get_array_u8(fb, 0, _items, word, nr_items);
 
 	/* Item locations */
-	fb->seek(game->_header.addr_item_locations);
-	file_buf_get_array_u8(fb, 0, game->_items, room, nr_items);
+	fb->seek(_header.addr_item_locations);
+	file_buf_get_array_u8(fb, 0, _items, room, nr_items);
 
 	/* Item graphic */
-	fb->seek(game->_header.addr_item_graphics);
-	file_buf_get_array_u8(fb, 0, game->_items, graphic, nr_items);
+	fb->seek(_header.addr_item_graphics);
+	file_buf_get_array_u8(fb, 0, _items, graphic, nr_items);
 }
 
-static void parse_rooms(ComprehendGame *game, FileBuffer *fb) {
-	size_t nr_rooms = game->_rooms.size() - 1;
+void GameData::parse_rooms(FileBuffer *fb) {
+	size_t nr_rooms = _rooms.size() - 1;
 	int i;
 
 	/* Room exit directions */
 	for (i = 0; i < NR_DIRECTIONS; i++) {
-		fb->seek(game->_header.room_direction_table[i]);
-		file_buf_get_array_u8(fb, 1, game->_rooms,
+		fb->seek(_header.room_direction_table[i]);
+		file_buf_get_array_u8(fb, 1, _rooms,
 		                      direction[i], nr_rooms);
 	}
 
 	/* Room string descriptions */
-	fb->seek(game->_header.room_desc_table);
-	file_buf_get_array_le16(fb, 1, game->_rooms, string_desc, nr_rooms);
+	fb->seek(_header.room_desc_table);
+	file_buf_get_array_le16(fb, 1, _rooms, string_desc, nr_rooms);
 
 	/* Room flags */
-	fb->seek(game->_header.room_flags_table);
-	file_buf_get_array_u8(fb, 1, game->_rooms, flags, nr_rooms);
+	fb->seek(_header.room_flags_table);
+	file_buf_get_array_u8(fb, 1, _rooms, flags, nr_rooms);
 
 	/* Room graphic */
-	fb->seek(game->_header.room_graphics_table);
-	file_buf_get_array_u8(fb, 1, game->_rooms, graphic, nr_rooms);
+	fb->seek(_header.room_graphics_table);
+	file_buf_get_array_u8(fb, 1, _rooms, graphic, nr_rooms);
 }
 
-static uint64 string_get_chunk(uint8 *string) {
+uint64 GameData::string_get_chunk(uint8 *string) {
 	uint64 c, val = 0;
 	int i;
 
@@ -675,7 +665,7 @@ static uint64 string_get_chunk(uint8 *string) {
 	return val;
 }
 
-static char decode_string_elem(uint8 c, bool capital, bool special) {
+char GameData::decode_string_elem(uint8 c, bool capital, bool special) {
 	if (special) {
 		if (c < sizeof(SPECIAL_CHARSET) - 1)
 			return SPECIAL_CHARSET[c];
@@ -703,15 +693,7 @@ static char decode_string_elem(uint8 c, bool capital, bool special) {
 	return '*';
 }
 
-/*
-* Game strings are stored using 5-bit characters. By default a character
-* value maps to the lower-case letter table. If a character has the value 0x1e
-* then the next character is upper-case. An upper-case space is used to
-* specify that the character should be replaced at runtime (like a '%s'
-* specifier). If a character has the value 0x1f then the next character is
-* taken from the symbols table.
-*/
-static Common::String parseString(FileBuffer *fb) {
+Common::String GameData::parseString(FileBuffer *fb) {
 	bool capital_next = false, special_next = false;
 	unsigned i, j;
 	uint64 chunk;
@@ -759,7 +741,7 @@ done:
 	return string;
 }
 
-static void parse_string_table(FileBuffer *fb, unsigned start_addr,
+void GameData::parse_string_table(FileBuffer *fb, unsigned start_addr,
                                uint32 end_addr, StringTable *table) {
 	fb->seek(start_addr);
 	while (1) {
@@ -769,35 +751,34 @@ static void parse_string_table(FileBuffer *fb, unsigned start_addr,
 	}
 }
 
-static void parse_variables(ComprehendGame *game, FileBuffer *fb) {
+void GameData::parse_variables(FileBuffer *fb) {
 	uint i;
 
-	for (i = 0; i < ARRAY_SIZE(game->_variables); i++)
-		game->_variables[i] = fb->readUint16LE();
+	for (i = 0; i < ARRAY_SIZE(_variables); i++)
+		_variables[i] = fb->readUint16LE();
 }
 
-static void parse_flags(ComprehendGame *game, FileBuffer *fb) {
+void GameData::parse_flags(FileBuffer *fb) {
 	uint i, flag_index = 0;
 	int bit;
 	uint8 bitmask;
 
-	for (i = 0; i < ARRAY_SIZE(game->_flags) / 8; i++) {
+	for (i = 0; i < ARRAY_SIZE(_flags) / 8; i++) {
 		bitmask = fb->readByte();
 		for (bit = 7; bit >= 0; bit--) {
-			game->_flags[flag_index] = !!(bitmask & (1 << bit));
+			_flags[flag_index] = !!(bitmask & (1 << bit));
 			flag_index++;
 		}
 	}
 }
 
-static void parse_replace_words(ComprehendGame *game,
-                                FileBuffer *fb) {
+void GameData::parse_replace_words(FileBuffer *fb) {
 	size_t len;
 	bool eof;
 	int i;
 
 	/* FIXME - Rename addr_strings_end */
-	fb->seek(game->_header.addr_strings_end);
+	fb->seek(_header.addr_strings_end);
 
 	/* FIXME - what is this for */
 	fb->skip(2);
@@ -807,19 +788,15 @@ static void parse_replace_words(ComprehendGame *game,
 		if (len == 0)
 			break;
 
-		game->_replaceWords.push_back(Common::String((const char *)fb->dataPtr(), len));
+		_replaceWords.push_back(Common::String((const char *)fb->dataPtr(), len));
 		fb->skip(len + (eof ? 0 : 1));
 		if (eof)
 			break;
 	}
 }
 
-/*
-* The main game data file header has the offsets for where each bit of
-* game data is. The offsets have a magic constant value added to them.
-*/
-static void parse_header(ComprehendGame *game, FileBuffer *fb) {
-	GameHeader *header = &game->_header;
+void GameData::parse_header(FileBuffer *fb) {
+	GameHeader *header = &_header;
 	uint16 dummy, addr_dictionary_end;
 
 	fb->seek(0);
@@ -827,17 +804,17 @@ static void parse_header(ComprehendGame *game, FileBuffer *fb) {
 	switch (header->magic) {
 	case 0x2000: /* Transylvania, Crimson Crown disk one */
 	case 0x4800: /* Crimson Crown disk two */
-		game->_comprehendVersion = 1;
+		_comprehendVersion = 1;
 		magic_offset = (uint16)(-0x5a00 + 0x4);
 		break;
 
 	case 0x93f0: /* OO-Topos */
-		game->_comprehendVersion = 2;
+		_comprehendVersion = 2;
 		magic_offset = (uint16) - 0x5a00;
 		break;
 
 	case 0xa429: /* Talisman */
-		game->_comprehendVersion = 2;
+		_comprehendVersion = 2;
 		magic_offset = (uint16) - 0x5a00;
 		break;
 
@@ -846,8 +823,6 @@ static void parse_header(ComprehendGame *game, FileBuffer *fb) {
 		break;
 	}
 
-	game->loadOpcodes(game->_comprehendVersion);
-
 	/* FIXME - Second word in header has unknown usage */
 	parse_header_le16(fb, &dummy);
 
@@ -856,14 +831,14 @@ static void parse_header(ComprehendGame *game, FileBuffer *fb) {
 	*
 	* Layout depends on the comprehend version.
 	*/
-	if (game->_comprehendVersion == 1) {
+	if (_comprehendVersion == 1) {
 		parse_header_le16(fb, &header->addr_actions_vvnn);
 		parse_header_le16(fb, &header->addr_actions_unknown);
 		parse_header_le16(fb, &header->addr_actions_vnjn);
 		parse_header_le16(fb, &header->addr_actions_vjn);
 		parse_header_le16(fb, &header->addr_actions_vdn);
 	}
-	if (game->_comprehendVersion >= 2) {
+	if (_comprehendVersion >= 2) {
 		parse_header_le16(fb, &header->addr_actions_vnjn);
 		parse_header_le16(fb, &header->addr_actions_vjn);
 		parse_header_le16(fb, &header->addr_actions_vnn);
@@ -897,7 +872,7 @@ static void parse_header(ComprehendGame *game, FileBuffer *fb) {
 	*
 	* Layout is dependent on comprehend version.
 	*/
-	if (game->_comprehendVersion == 1) {
+	if (_comprehendVersion == 1) {
 		parse_header_le16(fb, &header->addr_item_locations);
 		parse_header_le16(fb, &header->addr_item_flags);
 		parse_header_le16(fb, &header->addr_item_word);
@@ -923,22 +898,21 @@ static void parse_header(ComprehendGame *game, FileBuffer *fb) {
 	parse_header_le16(fb, &header->addr_strings_end);
 
 	fb->skip(1);
-	game->_startRoom = fb->readByte();
+	_startRoom = fb->readByte();
 	fb->skip(1);
 
-	parse_variables(game, fb);
-	parse_flags(game, fb);
+	parse_variables(fb);
+	parse_flags(fb);
 
-	game->_rooms.resize(header->room_direction_table[DIRECTION_SOUTH] -
+	_rooms.resize(header->room_direction_table[DIRECTION_SOUTH] -
 	                    header->room_direction_table[DIRECTION_NORTH] + 1);
 
-	game->_nr_words = (addr_dictionary_end -
+	_nr_words = (addr_dictionary_end -
 	                   header->addr_dictionary) /
 	                  8;
 }
 
-static void load_extra_string_file(ComprehendGame *game,
-                                   StringFile *string_file) {
+void GameData::load_extra_string_file(StringFile *string_file) {
 	FileBuffer fb(string_file->filename);
 	unsigned end;
 
@@ -948,56 +922,56 @@ static void load_extra_string_file(ComprehendGame *game,
 		end = fb.size();
 
 	parse_string_table(&fb, string_file->base_offset,
-	                   end, &game->_strings2);
+	                   end, &_strings2);
 }
 
-static void load_extra_string_files(ComprehendGame *game) {
+void GameData::load_extra_string_files() {
 	uint i;
 
-	for (i = 0; i < game->_stringFiles.size(); i++) {
+	for (i = 0; i < _stringFiles.size(); i++) {
 		// HACK - get string offsets correct
-		game->_strings2.resize(0x40 * i);
-		if (game->_strings2.empty())
-			game->_strings2.push_back("");
+		_strings2.resize(0x40 * i);
+		if (_strings2.empty())
+			_strings2.push_back("");
 
-		load_extra_string_file(game, &game->_stringFiles[i]);
+		load_extra_string_file(&_stringFiles[i]);
 	}
 }
 
-static void load_game_data(ComprehendGame *game) {
-	FileBuffer fb(game->_gameDataFile);
+void GameData::loadGameData() {
+	FileBuffer fb(_gameDataFile);
 
-	game->clearInfo();
+	clearGame();
 
-	parse_header(game, &fb);
-	parse_rooms(game, &fb);
-	parse_items(game, &fb);
-	parse_dictionary(game, &fb);
-	parse_word_map(game, &fb);
-	parse_string_table(&fb, game->_header.addr_strings,
-	                   game->_header.addr_strings_end,
-	                   &game->_strings);
-	load_extra_string_files(game);
-	parse_vm(game, &fb);
-	parse_action_table(game, &fb);
-	parse_replace_words(game, &fb);
+	parse_header(&fb);
+	parse_rooms(&fb);
+	parse_items(&fb);
+	parse_dictionary(&fb);
+	parse_word_map(&fb);
+	parse_string_table(&fb, _header.addr_strings,
+	                   _header.addr_strings_end,
+	                   &_strings);
+	load_extra_string_files();
+	parse_vm(&fb);
+	parse_action_table(&fb);
+	parse_replace_words(&fb);
 }
 
-void comprehend_load_game(ComprehendGame *game) {
+void GameData::loadGame() {
 	/* Load the main game data file */
-	load_game_data(game);
+	loadGameData();
 
 	if (g_comprehend->_graphicsEnabled) {
 		// Set up the picture archive
-		g_comprehend->_pics->load(game->_locationGraphicFiles,
-		                          game->_itemGraphicFiles, game->_titleGraphicFile);
+		g_comprehend->_pics->load(_locationGraphicFiles,
+		                          _itemGraphicFiles, _titleGraphicFile);
 
-		if (game->_colorTable)
-			g_comprehend->_drawSurface->setColorTable(game->_colorTable);
+		if (_colorTable)
+			g_comprehend->_drawSurface->setColorTable(_colorTable);
 	}
 
 	// FIXME: This can be merged, don't need to keep start room around
-	game->_currentRoom = game->_startRoom;
+	_currentRoom = _startRoom;
 }
 
 } // namespace Comprehend
diff --git a/engines/glk/comprehend/game_data.h b/engines/glk/comprehend/game_data.h
index dad58d527d..206fcaed14 100644
--- a/engines/glk/comprehend/game_data.h
+++ b/engines/glk/comprehend/game_data.h
@@ -48,6 +48,129 @@ enum {
 	NR_DIRECTIONS
 };
 
+
+enum {
+	OPCODE_UNKNOWN,
+	OPCODE_TEST_FALSE,
+	OPCODE_HAVE_OBJECT,
+	OPCODE_OR,
+	OPCODE_IN_ROOM,
+	OPCODE_VAR_EQ,
+	OPCODE_CURRENT_OBJECT_TAKEABLE,
+	OPCODE_OBJECT_PRESENT,
+	OPCODE_ELSE,
+	OPCODE_OBJECT_IN_ROOM,
+	OPCODE_OBJECT_NOT_VALID,
+	OPCODE_INVENTORY_FULL,
+	OPCODE_TEST_FLAG,
+	OPCODE_CURRENT_OBJECT_IN_ROOM,
+	OPCODE_HAVE_CURRENT_OBJECT,
+	OPCODE_OBJECT_IS_NOT_NOWHERE,
+	OPCODE_CURRENT_OBJECT_PRESENT,
+	OPCODE_TEST_ROOM_FLAG,
+	OPCODE_NOT_HAVE_OBJECT,
+	OPCODE_NOT_IN_ROOM,
+	OPCODE_CURRENT_OBJECT_IS_NOWHERE,
+	OPCODE_OBJECT_NOT_PRESENT,
+	OPCODE_OBJECT_NOT_IN_ROOM,
+	OPCODE_TEST_NOT_FLAG,
+	OPCODE_NOT_HAVE_CURRENT_OBJECT,
+	OPCODE_OBJECT_IS_NOWHERE,
+	OPCODE_CURRENT_OBJECT_NOT_PRESENT,
+	OPCODE_CURRENT_OBJECT_NOT_TAKEABLE,
+	OPCODE_TEST_NOT_ROOM_FLAG,
+	OPCODE_INVENTORY,
+	OPCODE_TAKE_OBJECT,
+	OPCODE_MOVE_OBJECT_TO_ROOM,
+	OPCODE_SAVE_ACTION,
+	OPCODE_MOVE_TO_ROOM,
+	OPCODE_VAR_ADD,
+	OPCODE_SET_ROOM_DESCRIPTION,
+	OPCODE_MOVE_OBJECT_TO_CURRENT_ROOM,
+	OPCODE_VAR_SUB,
+	OPCODE_SET_OBJECT_DESCRIPTION,
+	OPCODE_SET_OBJECT_LONG_DESCRIPTION,
+	OPCODE_MOVE,
+	OPCODE_MOVE_DIRECTION,
+	OPCODE_PRINT,
+	OPCODE_REMOVE_OBJECT,
+	OPCODE_SET_FLAG,
+	OPCODE_CALL_FUNC,
+	OPCODE_TURN_TICK,
+	OPCODE_CLEAR_FLAG,
+	OPCODE_INVENTORY_ROOM,
+	OPCODE_TAKE_CURRENT_OBJECT,
+	OPCODE_SPECIAL,
+	OPCODE_DROP_OBJECT,
+	OPCODE_DROP_CURRENT_OBJECT,
+	OPCODE_SET_ROOM_GRAPHIC,
+	OPCODE_SET_OBJECT_GRAPHIC,
+	OPCODE_REMOVE_CURRENT_OBJECT,
+	OPCODE_DO_VERB,
+	OPCODE_VAR_INC,
+	OPCODE_VAR_DEC,
+	OPCODE_MOVE_CURRENT_OBJECT_TO_ROOM,
+	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,
+	OPCODE_WAIT_KEY
+};
+
+/* Game state update flags */
+#define UPDATE_GRAPHICS (1 << 0) /* Implies UPDATE_GRAPHICS_ITEMS */
+#define UPDATE_GRAPHICS_ITEMS (1 << 1)
+#define UPDATE_ROOM_DESC (1 << 2)
+#define UPDATE_ITEM_LIST (1 << 3)
+#define UPDATE_ALL (~0U)
+
+/* Action types */
+enum {
+	ACTION_VERB_VERB_NOUN_NOUN,
+	ACTION_VERB_NOUN_JOIN_NOUN,
+	ACTION_VERB_JOIN_NOUN,
+	ACTION_VERB_DIR_NOUN,
+	ACTION_VERB_NOUN_NOUN,
+	ACTION_VERB_NOUN,
+	ACTION_VERB_OPT_NOUN
+};
+
+/* Standard strings (main string table) */
+#define STRING_CANT_GO 0
+#define STRING_DONT_UNDERSTAND 1
+#define STRING_YOU_SEE 2
+#define STRING_INVENTORY 3
+#define STRING_INVENTORY_EMPTY 4
+#define STRING_BEFORE_CONTINUE 5
+#define STRING_SAVE_GAME 6
+#define STRING_RESTORE_GAME 7
+
+/* Special variables */
+#define VAR_INVENTORY_WEIGHT 0
+#define VAR_INVENTORY_LIMIT 1
+#define VAR_TURN_COUNT 2
+
+/* Special rooms */
+#define ROOM_INVENTORY 0x00
+#define ROOM_NOWHERE 0xff
+
+/* Item flags */
+#define ITEMF_WEIGHT_MASK (0x3)
+#define ITEMF_CAN_TAKE (1 << 3)
+
+/* Word types */
+#define WORD_TYPE_VERB 0x01
+#define WORD_TYPE_JOIN 0x02
+#define WORD_TYPE_FEMALE 0x10
+#define WORD_TYPE_MALE 0x20
+#define WORD_TYPE_NOUN 0x40
+#define WORD_TYPE_NOUN_PLURAL 0x80
+#define WORD_TYPE_NOUN_MASK (WORD_TYPE_FEMALE | WORD_TYPE_MALE | \
+                             WORD_TYPE_NOUN | WORD_TYPE_NOUN_PLURAL)
+
 struct FunctionState {
 	bool test_result;
 	bool else_result;
@@ -173,6 +296,17 @@ struct Function {
 
 typedef Common::StringArray StringTable;
 
+struct StringFile {
+	Common::String filename;
+	uint32 base_offset;
+	uint32 end_offset;
+
+	StringFile() : base_offset(0), end_offset(0) {
+	}
+	StringFile(const Common::String &fname, uint32 baseOfs, uint32 endO = 0) : filename(fname), base_offset(baseOfs), end_offset(endO) {
+	}
+};
+
 struct GameHeader {
 	uint16 magic;
 
@@ -212,7 +346,16 @@ struct GameHeader {
 	void clear();
 };
 
-struct GameInfo {
+class GameData {
+protected:
+	Common::String _gameDataFile;
+	Common::Array<StringFile> _stringFiles;
+	Common::StringArray _locationGraphicFiles;
+	Common::StringArray _itemGraphicFiles;
+	Common::String _titleGraphicFile;
+	uint _colorTable;
+
+public:
 	GameHeader _header;
 
 	unsigned _comprehendVersion;
@@ -226,11 +369,6 @@ struct GameInfo {
 	Word *_words;
 	size_t _nr_words;
 
-	Common::Array<WordMap> _wordMaps;
-	Common::Array<Action> _actions;
-	Common::Array<Function> _functions;
-	Common::StringArray _replaceWords;
-
 	StringTable _strings;
 	StringTable _strings2;
 
@@ -240,153 +378,82 @@ struct GameInfo {
 	uint8 _currentReplaceWord;
 	uint _updateFlags;
 
-	GameInfo() {
-		clearInfo();
-	}
-	~GameInfo() {
-		clearInfo();
-	}
-
-	void clearInfo();
-};
-
-struct StringFile {
-	Common::String filename;
-	uint32 base_offset;
-	uint32 end_offset;
+	Common::Array<WordMap> _wordMaps;
+	Common::Array<Action> _actions;
+	Common::Array<Function> _functions;
+	Common::StringArray _replaceWords;
 
-	StringFile() : base_offset(0), end_offset(0) {}
-	StringFile(const Common::String &fname, uint32 baseOfs, uint32 endO = 0) : filename(fname), base_offset(baseOfs), end_offset(endO) {
+private:
+	size_t opcode_nr_operands(uint8 opcode) const {
+		// Number of operands is encoded in the low 2 bits
+		return opcode & 0x3;
 	}
-};
 
-enum {
-	OPCODE_UNKNOWN,
-	OPCODE_TEST_FALSE,
-	OPCODE_HAVE_OBJECT,
-	OPCODE_OR,
-	OPCODE_IN_ROOM,
-	OPCODE_VAR_EQ,
-	OPCODE_CURRENT_OBJECT_TAKEABLE,
-	OPCODE_OBJECT_PRESENT,
-	OPCODE_ELSE,
-	OPCODE_OBJECT_IN_ROOM,
-	OPCODE_OBJECT_NOT_VALID,
-	OPCODE_INVENTORY_FULL,
-	OPCODE_TEST_FLAG,
-	OPCODE_CURRENT_OBJECT_IN_ROOM,
-	OPCODE_HAVE_CURRENT_OBJECT,
-	OPCODE_OBJECT_IS_NOT_NOWHERE,
-	OPCODE_CURRENT_OBJECT_PRESENT,
-	OPCODE_TEST_ROOM_FLAG,
-	OPCODE_NOT_HAVE_OBJECT,
-	OPCODE_NOT_IN_ROOM,
-	OPCODE_CURRENT_OBJECT_IS_NOWHERE,
-	OPCODE_OBJECT_NOT_PRESENT,
-	OPCODE_OBJECT_NOT_IN_ROOM,
-	OPCODE_TEST_NOT_FLAG,
-	OPCODE_NOT_HAVE_CURRENT_OBJECT,
-	OPCODE_OBJECT_IS_NOWHERE,
-	OPCODE_CURRENT_OBJECT_NOT_PRESENT,
-	OPCODE_CURRENT_OBJECT_NOT_TAKEABLE,
-	OPCODE_TEST_NOT_ROOM_FLAG,
-	OPCODE_INVENTORY,
-	OPCODE_TAKE_OBJECT,
-	OPCODE_MOVE_OBJECT_TO_ROOM,
-	OPCODE_SAVE_ACTION,
-	OPCODE_MOVE_TO_ROOM,
-	OPCODE_VAR_ADD,
-	OPCODE_SET_ROOM_DESCRIPTION,
-	OPCODE_MOVE_OBJECT_TO_CURRENT_ROOM,
-	OPCODE_VAR_SUB,
-	OPCODE_SET_OBJECT_DESCRIPTION,
-	OPCODE_SET_OBJECT_LONG_DESCRIPTION,
-	OPCODE_MOVE,
-	OPCODE_MOVE_DIRECTION,
-	OPCODE_PRINT,
-	OPCODE_REMOVE_OBJECT,
-	OPCODE_SET_FLAG,
-	OPCODE_CALL_FUNC,
-	OPCODE_TURN_TICK,
-	OPCODE_CLEAR_FLAG,
-	OPCODE_INVENTORY_ROOM,
-	OPCODE_TAKE_CURRENT_OBJECT,
-	OPCODE_SPECIAL,
-	OPCODE_DROP_OBJECT,
-	OPCODE_DROP_CURRENT_OBJECT,
-	OPCODE_SET_ROOM_GRAPHIC,
-	OPCODE_SET_OBJECT_GRAPHIC,
-	OPCODE_REMOVE_CURRENT_OBJECT,
-	OPCODE_DO_VERB,
-	OPCODE_VAR_INC,
-	OPCODE_VAR_DEC,
-	OPCODE_MOVE_CURRENT_OBJECT_TO_ROOM,
-	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,
-	OPCODE_WAIT_KEY
-};
+	bool opcode_is_command(uint8 opcode) const {
+		/* If the MSB is set the instruction is a command */
+		return opcode & 0x80;
+	}
 
-/* Game state update flags */
-#define UPDATE_GRAPHICS (1 << 0) /* Implies UPDATE_GRAPHICS_ITEMS */
-#define UPDATE_GRAPHICS_ITEMS (1 << 1)
-#define UPDATE_ROOM_DESC (1 << 2)
-#define UPDATE_ITEM_LIST (1 << 3)
-#define UPDATE_ALL (~0U)
+	void load_extra_string_files();
+	void load_extra_string_file(StringFile *string_file);
+	void parse_header_le16(FileBuffer *fb, uint16 *val);
+	uint8 parse_vm_instruction(FileBuffer *fb, Instruction *instr);
+	void parse_function(FileBuffer *fb, Function *func);
+	void parse_vm(FileBuffer *fb);
+	void parse_action_table_vvnn(FileBuffer *fb);
+	void parse_action_table_vnjn(FileBuffer *fb);
+	void parse_action_table_vjn(FileBuffer *fb);
+	void parse_action_table_vdn(FileBuffer *fb);
+	void parse_action_table_vnn(FileBuffer *fb);
+	void parse_action_table_vn(FileBuffer *fb);
+	void parse_action_table_v(FileBuffer *fb);
+	void parse_action_table(FileBuffer *fb);
+	void parse_dictionary(FileBuffer *fb);
+	void parse_word_map(FileBuffer *fb);
+	void parse_items(FileBuffer *fb);
+	void parse_rooms(FileBuffer *fb);
+	uint64 string_get_chunk(uint8 *string);
+	char decode_string_elem(uint8 c, bool capital, bool special);
+
+	/**
+	 * Game strings are stored using 5-bit characters. By default a character
+	 * value maps to the lower-case letter table. If a character has the value 0x1e
+	 * then the next character is upper-case. An upper-case space is used to
+	 * specify that the character should be replaced at runtime (like a '%s'
+	 * specifier). If a character has the value 0x1f then the next character is
+	 * taken from the symbols table.
+	 */
+	Common::String parseString(FileBuffer *fb);
+
+	void parse_string_table(FileBuffer *fb, unsigned start_addr,
+		uint32 end_addr, StringTable *table);
+	void parse_variables(FileBuffer *fb);
+	void parse_flags(FileBuffer *fb);
+	void parse_replace_words(FileBuffer *fb);
+
+	void loadGameData();
+
+protected:
+	/**
+	 * The main game data file header has the offsets for where each bit of
+	 * game data is. The offsets have a magic constant value added to them.
+	 */
+	virtual void parse_header(FileBuffer *fb);
+
+public:
+	GameData() {
+		clearGame();
+	}
+	virtual ~GameData() {
+		clearGame();
+	}
 
-/* Action types */
-enum {
-	ACTION_VERB_VERB_NOUN_NOUN,
-	ACTION_VERB_NOUN_JOIN_NOUN,
-	ACTION_VERB_JOIN_NOUN,
-	ACTION_VERB_DIR_NOUN,
-	ACTION_VERB_NOUN_NOUN,
-	ACTION_VERB_NOUN,
-	ACTION_VERB_OPT_NOUN
+	void clearGame();
+	void loadGame();
+	//void restoreGame(ComprehendGame *game, const char *filename);
+	//void saveGame(const char *filename);
 };
 
-/* Standard strings (main string table) */
-#define STRING_CANT_GO 0
-#define STRING_DONT_UNDERSTAND 1
-#define STRING_YOU_SEE 2
-#define STRING_INVENTORY 3
-#define STRING_INVENTORY_EMPTY 4
-#define STRING_BEFORE_CONTINUE 5
-#define STRING_SAVE_GAME 6
-#define STRING_RESTORE_GAME 7
-
-/* Special variables */
-#define VAR_INVENTORY_WEIGHT 0
-#define VAR_INVENTORY_LIMIT 1
-#define VAR_TURN_COUNT 2
-
-/* Special rooms */
-#define ROOM_INVENTORY 0x00
-#define ROOM_NOWHERE 0xff
-
-/* Item flags */
-#define ITEMF_WEIGHT_MASK (0x3)
-#define ITEMF_CAN_TAKE (1 << 3)
-
-/* Word types */
-#define WORD_TYPE_VERB 0x01
-#define WORD_TYPE_JOIN 0x02
-#define WORD_TYPE_FEMALE 0x10
-#define WORD_TYPE_MALE 0x20
-#define WORD_TYPE_NOUN 0x40
-#define WORD_TYPE_NOUN_PLURAL 0x80
-#define WORD_TYPE_NOUN_MASK (WORD_TYPE_FEMALE | WORD_TYPE_MALE | \
-                             WORD_TYPE_NOUN | WORD_TYPE_NOUN_PLURAL)
-
-void comprehend_load_game(ComprehendGame *game);
-void comprehend_restore_game(ComprehendGame *game,
-                             const char *filename);
-void comprehend_save_game(ComprehendGame *game, const char *filename);
-
 } // namespace Comprehend
 } // namespace Glk
 




More information about the Scummvm-git-logs mailing list