[Scummvm-git-logs] scummvm master -> 9e2f713248b6c7d2df47f4edd4ef1dac6b75fc00

sev- sev at scummvm.org
Thu Oct 21 16:08:01 UTC 2021


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

Summary:
9e2f713248 JANITORIAL: Fix line endings


Commit: 9e2f713248b6c7d2df47f4edd4ef1dac6b75fc00
    https://github.com/scummvm/scummvm/commit/9e2f713248b6c7d2df47f4edd4ef1dac6b75fc00
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2021-10-21T19:07:53+03:00

Commit Message:
JANITORIAL: Fix line endings

Changed paths:
    engines/groovie/logic/t11hgame.cpp
    engines/groovie/logic/t11hgame.h
    engines/groovie/logic/tlcgame.h


diff --git a/engines/groovie/logic/t11hgame.cpp b/engines/groovie/logic/t11hgame.cpp
index a639c021b3..0eadafd457 100644
--- a/engines/groovie/logic/t11hgame.cpp
+++ b/engines/groovie/logic/t11hgame.cpp
@@ -1,762 +1,762 @@
-/* ScummVM - Graphic Adventure Engine
-*
-* ScummVM is the legal property of its developers, whose names
-* are too numerous to list here. Please refer to the COPYRIGHT
-* file distributed with this source distribution.
-*
-* This program is free software; you can redistribute it and/or
-* modify it under the terms of the GNU General Public License
-* as published by the Free Software Foundation; either version 2
-* of the License, or (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-*
-*/
-
-#include <limits.h>
-#include "groovie/logic/t11hgame.h"
-#include "groovie/groovie.h"
-
-#include "common/archive.h"
-#include "common/config-manager.h"
-#include "common/debug-channels.h"
-#include "common/events.h"
-#include "common/file.h"
-#include "common/macresman.h"
-#include "common/translation.h"
-
-namespace Groovie {
-
-T11hGame::T11hGame(byte *scriptVariables)
-	: _random("GroovieT11hGame"), _scriptVariables(scriptVariables), _cake(NULL), _beehiveHexagons() {
-}
-
-T11hGame::~T11hGame() {
-}
-
-void T11hGame::handleOp(uint8 op) {
-	switch (op) {
-	case 1:
-		debugC(1, kDebugScript, "Groovie::Script Op42 (0x%02X): T11H Connect four in the dining room. (tb.grv) TODO", op);
-		opConnectFour();
-		break;
-
-	case 2:
-		debugC(1, kDebugScript, "Groovie::Script Op42 (0x%02X): T11H Beehive Puzzle in the top room (hs.grv)", op);
-		opBeehive();
-		break;
-
-	case 3:
-		debugC(1, kDebugScript, "Groovie::Script Op42 (0x%02X): T11H Make last move on modern art picture in the gallery (bs.grv)", op);
-		opGallery();
-		break;
-
-	case 4:
-		debugC(1, kDebugScript, "Groovie::Script Op42 (0x%02X): T11H Triangle in the Chapel (tx.grv)", op);
-		opTriangle();
-		break;
-
-	case 5:
-		debugC(1, kDebugScript, "Groovie::Script Op42 (0x%02X): T11H Mouse Trap in the lab (al.grv)", op);
-		opMouseTrap();
-		break;
-
-	case 6:
-		debugC(1, kDebugScript, "Groovie::Script Op42 (0x%02X): T11H Pente (pt.grv)", op);
-		opPente();
-		break;
-
-	case 8:	// used in UHP
-		debugC(1, kDebugScript, "Groovie::Script Op42 (0x%02X): UHP Othello", op);
-		// TODO: Same as the Clandestiny Othello/Reversi puzzle (opOthello)
-		break;
-
-	default:
-		debugC(1, kDebugScript, "Groovie::Script: Op42 (0x%02X): T11H Invalid -> NOP", op);
-	}
-}
-
-/*
- * Mouse Trap puzzle in the Lab.
- *
- * Stauf's Goal is space 1, counting up as you go north east
- * towards the north corner which is space 5 and the moveable
- * space to the left of that is space 4.
- * South east from Stauf's goal is the next line starting with
- * space 6, counting up as you go north east where the moveable
- * space to the right of the north corner is space 10
- * 
- * Next line is 11 (unmovable) to 15 (unmoveable), this line
- * contains the center space which is space 13
- * Next line is 16 (moveable) to 20 (moveable)
- * Next line is 21 (unmovable) to 25 (unmovable), with 25 being
- * the player's goal door
- *
- * Space -2 is the next piece, outside of the box
- */
-void T11hGame::opMouseTrap() {
-	// TODO: Finish the logic
-	byte op = _scriptVariables[2];
-
-	warning("Mousetrap subop %d", op);
-
-	// variable 24 is the mouse?
-	//_scriptVariables[24] = 2;
-
-	// player wins: _scriptVariables[22] = 1;
-	// stauf wins: _scriptVariables[22] = 2;
-	// allows the player to click to place the mouse somewhere? _scriptVariables[5] = 0;
-
-	switch (op) {
-	case 0:
-		break;
-	case 1: // init board
-		// value of 0 is V, 1 is <, 2 is ^, 3 is >
-		// variable 23 is the outside piece
-		_scriptVariables[23] = _random.getRandomNumber(3);
-		// variable slot is the space number + 25, the left corner
-		// (Stauf's goal) is space 1, above that is space 2, the
-		// center is 13, and the right corner (goal) is space 25
-		for (int i = 27; i <= 49; i++) {
-			_scriptVariables[i] = _random.getRandomNumber(3);
-		}
-		break;
-	case 2: // before player chooses the floor to move, set the banned move
-	{
-		int clicked = int(_scriptVariables[0]) * 5 + int(_scriptVariables[1]) + 1;
-		_scriptVariables[clicked + 50] = 0;
-		break;
-	}
-	case 3: // after player moving floor
-		// a bunch of hardcoded conditionals to copy variables and
-		// set the banned move
-		// this probably also sets a variable to allow the player to
-		// move the mouse, and checks for win/lose
-		break;
-	case 5: // maybe player moving mouse
-		break;
-	case 6: // Stauf moving floor?
-		break;
-	case 7: // maybe Stauf moving mouse
-		break;
-	case 8: // Samantha making a move
-		break;
-
-	default:
-		warning("Unknown mousetrap op %d", op);
-		break;
-	}
-}
-
-class T11hCake {
-/*
-* Connect Four puzzle, the cake in the dining room
-*/
-public:
-	Common::RandomSource &_random;
-
-	/*
-	* T11hCake() constructor
-	*	- Each spot on the board is part of multiple potential victory lines
-	*	- The first x and y dimensions of the loops select the origin point of the line
-	*	- The z is for the distance along that line
-	*	- Then we push_back the id number of the line into the array at _map.indecies[x][y]
-	*	- This is used in UpdateScores()
-	*	.
-	* @see UpdateScores()
-	*/
-	T11hCake(Common::RandomSource &rng) : _random(rng) {
-		Restart();
-
-		_map = {};
-		int numLines = 0;
-
-		// map all the lines with slope of (1, 0)
-		for (int y = 0; y < HEIGHT; y++) {
-			for (int x = 0; x <= WIDTH - GOAL_LEN; x++) {
-				for (int z = 0; z < GOAL_LEN; z++) {
-					SetLineNum(x + z, y, numLines);
-				}
-				numLines++;
-			}
-		}
-
-		// map all the lines with slope of (0, 1)
-		for (int x = 0; x < WIDTH; x++) {
-			for (int y = 0; y <= HEIGHT - GOAL_LEN; y++) {
-				for (int z = 0; z < GOAL_LEN; z++) {
-					SetLineNum(x, y + z, numLines);
-				}
-				numLines++;
-			}
-		}
-
-		// map all the lines with slope of (1,1)
-		for (int y = 0; y <= HEIGHT - GOAL_LEN; y++) {
-			for (int x = 0; x <= WIDTH - GOAL_LEN; x++) {
-				for (int z = 0; z < GOAL_LEN; z++) {
-					SetLineNum(x + z, y + z, numLines);
-				}
-				numLines++;
-			}
-		}
-
-		// map all the lines with slope of (1,-1)
-		for (int y = GOAL_LEN - 1; y < HEIGHT; y++) {
-			for (int x = 0; x <= WIDTH - GOAL_LEN; x++) {
-				for (int z = 0; z < GOAL_LEN; z++) {
-					SetLineNum(x + z, y - z, numLines);
-				}
-				numLines++;
-			}
-		}
-	}
-
-	byte OpConnectFour(byte &lastMove) {
-		if (lastMove == 8) {
-			Restart();
-			return 0;
-		}
-
-		if (lastMove == 9) {
-			// samantha makes a move
-			// TODO: fix graphical bug when samantha makes a move
-			lastMove = AiGetBestMove(6);
-			_hasCheated = true;
-			return 0;
-		}
-
-		if (IsColumnFull(lastMove)) {
-			warning("player tried to place a bon bon in a full column, last_move: %d", (int)lastMove);
-			lastMove = 10;
-			return 0;
-		}
-
-		PlaceBonBon(lastMove);
-		byte winner = GetWinner();
-		if (winner) {
-			return winner;
-		}
-
-		lastMove = AiGetBestMove(4 + (_hasCheated == false));
-		PlaceBonBon(lastMove);
-		if (GameEnded())
-			return STAUF;
-
-		return 0;
-	}
-
-private:
-	static const int WIDTH = 8;
-	static const int HEIGHT = 7;
-	static const int GOAL_LEN = 4;
-	static const int WIN_SCORE = 1000000;//!< the number of points added for a connect four
-	static const byte STAUF = 1;
-	static const byte PLAYER = 2;
-	static const int NUM_LINES = 107;//!< how many potential victory lines there are
-
-
-	//! ID numbers for all of the potential victory lines for each spot on the board
-	struct LinesMappings {
-		byte lengths[WIDTH][HEIGHT];
-		byte indecies[WIDTH][HEIGHT][GOAL_LEN * GOAL_LEN];
-	};
-
-	//! how many points a player has, and their progress on potential victory lines
-	struct PlayerProgress {
-		int _score;
-		int _linesCounters[NUM_LINES];//!< how many pieces are claimed in each potential victory, links to LineMappings, an entry of 4 means that's a victory
-	};
-
-	PlayerProgress _playerProgress;
-	PlayerProgress _staufProgress;
-
-	byte _boardState[WIDTH][HEIGHT];//!< (0, 0) is the bottom left of the board
-	byte _columnHeights[WIDTH];
-
-	int _moveCount;
-	bool _hasCheated;
-
-	LinesMappings _map;//!< ID numbers for all of the potential victory lines for each spot on the board
-
-	void Restart() {
-		_playerProgress = {};
-		_staufProgress = {};
-		memset(_boardState, 0, sizeof(_boardState));
-		memset(_columnHeights, 0, sizeof(_columnHeights));
-		_moveCount = 0;
-		_hasCheated = false;
-
-		_playerProgress._score = NUM_LINES;
-		_staufProgress._score = NUM_LINES;
-	}
-
-	void SetLineNum(uint x, uint y, uint index) {
-		assert(x < WIDTH);
-		assert(y < HEIGHT);
-		byte slot = _map.lengths[x][y]++;
-		assert(slot < GOAL_LEN * GOAL_LEN);
-		assert(index < NUM_LINES);
-		_map.indecies[x][y][slot] = index;
-	}
-
-	bool IsColumnFull(byte column) {
-		return _columnHeights[column] >= HEIGHT;
-	}
-
-	PlayerProgress &GetPlayerProgress(bool stauf) {
-		if (stauf)
-			return _staufProgress;
-		else
-			return _playerProgress;
-	}
-
-	/*
-	* UpdateScores()
-	*	- Each PlayerProgress has an array of ints, _linesCounters[], where each entry maps to the ID of a line
-	*	- When a bon bon is added to the board, we look up _map.lengths[x][y] and then loop through all the indecies for that point
-	*		- Increment the PlayerProgress._linesCounters[id]
-	*		- Calculate the scores proportional to the PlayerProgress._linesCounters[id]
-	*		.
-	*	.
-	*/
-	void UpdateScores(byte x, bool revert=false) {
-		bool stauf = _moveCount % 2;
-		PlayerProgress &pp = GetPlayerProgress(stauf);
-
-		byte y = _columnHeights[x] - 1;
-
-		// get the number of potential victory lines that this spot exists in
-		int num_lines = _map.lengths[x][y];
-
-		for (int line = 0; line < num_lines; line++) {
-			// get the ID for this potential victory line
-			int index = _map.indecies[x][y][line];
-			int len = pp._linesCounters[index];
-
-			// add this new bon bon to the progress of this potential victory line, or remove in the case of revert
-			int mult = 1;// mult is used for multiplying the score gains, depends on revert
-			if (!revert)
-				pp._linesCounters[index]++;
-			else {
-				len = --pp._linesCounters[index];
-				mult = -1;
-			}
-
-			if (GOAL_LEN == len + 1) {
-				// that's a bingo
-				pp._score += WIN_SCORE * mult;
-			}
-			else {
-				PlayerProgress &pp2 = GetPlayerProgress(!stauf);
-				int len2 = pp2._linesCounters[index];
-				if (len == 0) {
-					// we started a new line, take away the points the opponent had from this line since we ruined it for them
-					pp2._score -= (1 << (len2 & 31)) * mult;
-				}
-				if (len2 == 0) {
-					// the opponent doesn't have any spots in this line, so we get points for it
-					pp._score += (1 << (len & 31)) * mult;
-				}
-			}
-		}
-	}
-
-	void PlaceBonBon(byte x) {
-		byte y = _columnHeights[x]++;
-		if (_moveCount % 2)
-			_boardState[x][y] = STAUF;
-		else
-			_boardState[x][y] = PLAYER;
-
-		UpdateScores(x);
-
-		_moveCount++;
-	}
-
-	void RevertMove(byte x) {
-		// PlaceBonBon in reverse, this is used for the AI's recursion rollback
-		_moveCount--;
-
-		UpdateScores(x, true);
-
-		byte y = --_columnHeights[x];
-		_boardState[x][y] = 0;
-	}
-
-	byte GetWinner() {
-		if (_playerProgress._score >= WIN_SCORE)
-			return PLAYER;
-
-		if (_staufProgress._score >= WIN_SCORE)
-			return STAUF;
-
-		return 0;
-	}
-
-	bool GameEnded() {
-		if (GetWinner())
-			return true;
-
-		if (_moveCount >= WIDTH * HEIGHT)
-			return true;
-
-		return false;
-	}
-
-	int GetScoreDiff() {
-		if (_moveCount % 2)
-			return _staufProgress._score - _playerProgress._score;
-		else
-			return _playerProgress._score - _staufProgress._score;
-	}
-
-	int AiRecurse(int search_depth, int parent_score) {
-		int best_score = 0x7fffffff;
-
-		for (byte move = 0; move < WIDTH; move++) {
-			if (IsColumnFull(move))
-				continue;
-
-			PlaceBonBon(move);
-			int score = GetScoreDiff();
-			if (search_depth > 1 && !GameEnded())
-				score = AiRecurse(search_depth - 1, best_score);
-			RevertMove(move);
-
-			if (score < best_score)
-				best_score = score;
-
-			if (-parent_score != best_score && parent_score <= -best_score)
-				break;
-		}
-
-		// we negate the score because from the perspective of our parent caller, this is his opponent's score
-		return -best_score;
-	}
-
-	uint Rng() {
-		return _random.getRandomNumber(UINT_MAX);
-	}
-
-	byte AiGetBestMove(int search_depth) {
-		int best_move = 0xffff;
-		uint counter = 1;
-
-		for (int best_score = 0x7fffffff; best_score > 999999 && search_depth > 1; search_depth--) {
-			for (byte move = 0; move < WIDTH; move++) {
-				if (IsColumnFull(move))
-					continue;
-
-				PlaceBonBon(move);
-				if (GetWinner()) {
-					RevertMove(move);
-					return move;
-				}
-
-				int score = AiRecurse(search_depth - 1, best_score);
-				RevertMove(move);
-				if (score < best_score) {
-					counter = 1;
-					best_move = move;
-					best_score = score;
-				} else if (best_score == score) {
-					// rng is only used on moves with equal scores
-					counter++;
-					uint r = Rng() % 1000000;
-					if (r * counter < 1000000) {
-						best_move = move;
-					}
-				}
-			}
-		}
-
-		return best_move;
-	}
-};
-
-void T11hGame::opConnectFour() {
-	byte &last_move = _scriptVariables[1];
-	byte &winner = _scriptVariables[3];
-	winner = 0;
-
-	if (_cake == NULL) {
-		clearAIs();
-		_cake = new T11hCake(_random);
-	}
-
-	winner = _cake->OpConnectFour(last_move);
-
-	if (winner) {
-		clearAIs();
-	}
-}
-
-void T11hGame::clearAIs() {
-	if (_cake != NULL) {
-		delete _cake;
-		_cake = NULL;
-	}
-}
-
-
-/*
- * Beehive puzzle
- *
- * An infection-style game in which the player must cover more
- * territory than the computer. It's similar to the microscope puzzle
- * in the 7th Guest. The playfield is a honeycomb made of 61
- * hexagons. The hexagons are numbered starting from the top-left
- * corner, with a direction from bottom left to top right.
- */
-void T11hGame::opBeehive() {
-	// TODO: Finish the logic
-	int8 *hexagons = (int8 *)_scriptVariables + 25;
-	int8 *hexDifference = (int8 *)_scriptVariables + 13;
-	byte op = _scriptVariables[14] - 1;
-
-	enum kBeehiveColor {
-		kBeehiveColorYellow = -1,
-		kBeehiveColorRed = 1
-	};
-
-	warning("Beehive subop %d", op);
-
-	//*hexDifference = 4;
-	*hexDifference = 5; // DEBUG: set the difference to 5 to skip the game
-
-	switch (op) {
-	case 0:	// init board's hexagons
-		memset(_beehiveHexagons, 0, 60);
-		_beehiveHexagons[0] = kBeehiveColorYellow;
-		_beehiveHexagons[4] = kBeehiveColorRed;
-		_beehiveHexagons[34] = kBeehiveColorYellow;
-		_beehiveHexagons[60] = kBeehiveColorRed;
-		_beehiveHexagons[56] = kBeehiveColorYellow;
-		_beehiveHexagons[26] = kBeehiveColorRed;
-		break;
-	case 1:
-		memset(hexagons, 0, 60);
-		_scriptVariables[85] = 0;
-		//opBeehiveSub2();	// TODO
-		// TODO: Check opBeehiveSub2()'s result
-		//*hexDifference = opBeehiveGetHexDifference();
-		break;
-	case 2:
-		memset(hexagons, 0, 60);
-		_scriptVariables[85] = 0;
-		//opBeehiveSub4();	// TODO
-		break;
-	case 3:
-		break;
-	case 4:
-		break;
-	case 5:
-		break;
-	case 6:
-		break;
-	default:
-		break;
-	}
-}
-
-int8 T11hGame::opBeehiveGetHexDifference() {
-	return (opBeehiveGetTotal(_beehiveHexagons) >= 0) + 5;
-}
-
-int8 T11hGame::opBeehiveGetTotal(int8 *hexagons) {
-	int8 result = 0;
-
-	for (int i = 0; i < 61; i++)
-		result += hexagons[i];
-
-	return result;
-}
-
-void T11hGame::opPente() {
-	// FIXME: properly implement Pente game (the final puzzle)
-	// for now just auto-solve the puzzle so the player can continue
-	_scriptVariables[5] = 4;
-}
-
-/*
- * Puzzle in the Gallery.
- * The aim is to select the last piece of the image.
- * There are 18 pieces in total.
- * When selecting a piece, all surrounding pieces are also selected
- * 
- * +--------------------+--------------------------------+--------+
- * |         1/1A       |       2/1B                     |        |
- * |  +--------------+--+--------------------------+-----+        |
- * |  |              |                             |              |
- * +--+     4/1D     |            5/1E             |       3/1C   |
- * |                 |                             |              |
- * +-----+--------+--+--------+-----------------+--+--------+     |
- * |     |        |           |                 |           |     |
- * |     |        |           |                 |           |     |
- * |     |        |   8/21    |                 |           |     |
- * |     |        |           |     +-----------+           |     |
- * |     |        |           |     |           |           |     |
- * |     |        +-----------+     |   10/23   |   9/22    |     |
- * |     |                          |           |           |     |
- * |     |           7/20           +-----+-----+           +-----+
- * |     |                          |     |     |           |     |
- * |     +--------------------------+     |     |           |     |
- * |              6/1F                    |     |           |     |
- * +-----------+-----------+-----+--+     | 11  |           | 12  |
- * |   13/26   |           |     |  |     | /   |           | /   |
- * |     +-----+-----+     |     |  |     | 24  +-----------+ 25  |
- * |     |           |     |     |  |     |     |           |     |
- * +-----+   17/2A   |     |     |16|     |     |           |     |
- * |     |           |     |     |/ |     |     |           |     |
- * |     +-----+-----+     |     |29|     |     |           +-----+
- * |           |           |     |  |     |     |           |     |
- * |           |           |     |  |     +-----+   18/2B   |     |
- * |   19/2C   |   14/27   |     |  |           |           |     |
- * |           |           |     |  +-----------+           |     |
- * |           |           |     |  |           |           |     |
- * |           |           |     +--+   15/28   |           |     |
- * |           |           |                    |           |     |
- * |           +--------+--+--------------------+-----------+     |
- * |           | 20/2D  |              21/2E                      |
- * +-----------+--------+-----------------------------------------+
- */
-
-// Links between the pieces in the Gallery challenge
-// For example, the first row signifies that piece 1
-// is connected to pieces 2, 4 and 5
-const byte T11hGame::kGalleryLinks[21][10] = {
-	{ 2,  4,  5,  0,  0,  0,  0,  0,  0,  0 },	//  1
-	{ 1,  5,  3,  0,  0,  0,  0,  0,  0,  0 },	//  2
-	{ 2,  5,  9, 12,  0,  0,  0,  0,  0,  0 },	//  3
-	{ 1,  5,  6,  7,  8,  0,  0,  0,  0,  0 },	//  4
-	{ 1,  2,  3,  4,  7,  8,  9,  0,  0,  0 },	//  5
-	{ 4,  7, 10, 11, 13, 14, 15, 16, 18,  0 },	//  6
-	{ 4,  5,  6,  8,  9, 10,  0,  0,  0,  0 },	//  7
-	{ 4,  5,  7,  0,  0,  0,  0,  0,  0,  0 },	//  8
-	{ 3,  5,  7, 10, 11, 12, 18,  0,  0,  0 },	//  9
-	{ 6,  7,  9, 11,  0,  0,  0,  0,  0,  0 },	// 10
-	{ 6,  9, 10, 18,  0,  0,  0,  0,  0,  0 },	// 11
-	{ 3,  9, 18, 21,  0,  0,  0,  0,  0,  0 },	// 12
-	{ 6, 14, 17, 19,  0,  0,  0,  0,  0,  0 },	// 13
-	{ 6, 13, 15, 17, 19, 20, 21,  0,  0,  0 },	// 14
-	{ 6, 14, 16, 18, 21,  0,  0,  0,  0,  0 },	// 15
-	{ 6, 15,  0,  0,  0,  0,  0,  0,  0,  0 },	// 16
-	{13, 14, 19,  0,  0,  0,  0,  0,  0,  0 },	// 17
-	{ 6,  9, 11, 12, 15, 21,  0,  0,  0,  0 },	// 18
-	{13, 14, 17, 20,  0,  0,  0,  0,  0,  0 },	// 19
-	{14, 19, 21,  0,  0,  0,  0,  0,  0,  0 },	// 20
-	{12, 14, 15, 18, 20,  0,  0,  0,  0,  0 }	// 21
-};
-
-void T11hGame::opGallery() {
-	const int kPieceCount = 21;
-	byte pieceStatus[kPieceCount];
-	byte var_18[kPieceCount];
-	int selectedPieces;
-	byte curLink = 0;
-
-	enum kGalleryPieceStatus {
-		kPieceUnselected = 0,
-		kPieceSelected = 1
-	};
-
-	memcpy(pieceStatus, _scriptVariables + 26, kPieceCount);
-
-	selectedPieces = 0;
-	for (int i = 0; i < kPieceCount; i++) {
-		var_18[i] = 0;
-		if (pieceStatus[i] == kPieceSelected) {
-			curLink = kGalleryLinks[i][0];
-			pieceStatus[i] = kPieceUnselected;
-
-			int linkedPiece = 1;
-			while (curLink != 0) {
-				linkedPiece++;
-				pieceStatus[curLink - 1] = kPieceUnselected;
-				curLink = kGalleryLinks[linkedPiece - 1][i];
-			}
-			var_18[i] = opGallerySub(pieceStatus, 1);
-			if (var_18[i] == kPieceSelected) {
-				selectedPieces++;
-			}
-		}
-	}
-
-	if (selectedPieces == 0) {
-		int esi = 0;
-		for (int i = 0; i < kPieceCount; i++) {
-			if (esi < var_18[i]) {
-				esi = var_18[i];
-			}
-		}
-
-		if (esi == 2) {
-			esi = 1;
-		} else {
-			if (esi < kPieceCount) {
-				esi = 2;
-			} else {
-				esi -= 12;
-			}
-		}
-
-		for (int i = 0; i < kPieceCount; i++) {
-			if (esi < var_18[i]) {
-				var_18[i] = kPieceSelected;
-				selectedPieces++;
-			}
-		}
-	}
-
-	int selectedPiece;
-
-	// TODO: copy the AI from the game
-	do {
-		selectedPiece = _random.getRandomNumber(20) + 1;
-	} while (_scriptVariables[selectedPiece + 25] != 1);
-
-	setScriptVar(47, selectedPiece / 10);
-	setScriptVar(48, selectedPiece % 10);
-}
-
-byte T11hGame::opGallerySub(byte *field, int start) {
-	// TODO
-	warning("STUB: T11hGame::opGallerySub()");
-	return 0;
-}
-
-void T11hGame::opTriangle() {
-	// TODO
-}
-
-// This function is mainly for debugging purposes
-void inline T11hGame::setScriptVar(uint16 var, byte value) {
-	_scriptVariables[var] = value;
-	debugC(5, kDebugTlcGame, "script variable[0x%03X] = %d (0x%04X)", var, value, value);
-}
-
-void inline T11hGame::setScriptVar16(uint16 var, uint16 value) {
-	_scriptVariables[var] = value & 0xFF;
-	_scriptVariables[var + 1] = (value >> 8) & 0xFF;
-	debugC(5, kDebugTlcGame, "script variable[0x%03X, 0x%03X] = %d (0x%02X, 0x%02X)",
-		var, var + 1, value, _scriptVariables[var], _scriptVariables[var + 1]);
-}
-
-uint16 inline T11hGame::getScriptVar16(uint16 var) {
-	uint16 value;
-
-	value = _scriptVariables[var];
-	value += _scriptVariables[var + 1] << 8;
-
-	return value;
-}
-
-} // End of Namespace Groovie
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*/
+
+#include <limits.h>
+#include "groovie/logic/t11hgame.h"
+#include "groovie/groovie.h"
+
+#include "common/archive.h"
+#include "common/config-manager.h"
+#include "common/debug-channels.h"
+#include "common/events.h"
+#include "common/file.h"
+#include "common/macresman.h"
+#include "common/translation.h"
+
+namespace Groovie {
+
+T11hGame::T11hGame(byte *scriptVariables)
+	: _random("GroovieT11hGame"), _scriptVariables(scriptVariables), _cake(NULL), _beehiveHexagons() {
+}
+
+T11hGame::~T11hGame() {
+}
+
+void T11hGame::handleOp(uint8 op) {
+	switch (op) {
+	case 1:
+		debugC(1, kDebugScript, "Groovie::Script Op42 (0x%02X): T11H Connect four in the dining room. (tb.grv) TODO", op);
+		opConnectFour();
+		break;
+
+	case 2:
+		debugC(1, kDebugScript, "Groovie::Script Op42 (0x%02X): T11H Beehive Puzzle in the top room (hs.grv)", op);
+		opBeehive();
+		break;
+
+	case 3:
+		debugC(1, kDebugScript, "Groovie::Script Op42 (0x%02X): T11H Make last move on modern art picture in the gallery (bs.grv)", op);
+		opGallery();
+		break;
+
+	case 4:
+		debugC(1, kDebugScript, "Groovie::Script Op42 (0x%02X): T11H Triangle in the Chapel (tx.grv)", op);
+		opTriangle();
+		break;
+
+	case 5:
+		debugC(1, kDebugScript, "Groovie::Script Op42 (0x%02X): T11H Mouse Trap in the lab (al.grv)", op);
+		opMouseTrap();
+		break;
+
+	case 6:
+		debugC(1, kDebugScript, "Groovie::Script Op42 (0x%02X): T11H Pente (pt.grv)", op);
+		opPente();
+		break;
+
+	case 8:	// used in UHP
+		debugC(1, kDebugScript, "Groovie::Script Op42 (0x%02X): UHP Othello", op);
+		// TODO: Same as the Clandestiny Othello/Reversi puzzle (opOthello)
+		break;
+
+	default:
+		debugC(1, kDebugScript, "Groovie::Script: Op42 (0x%02X): T11H Invalid -> NOP", op);
+	}
+}
+
+/*
+ * Mouse Trap puzzle in the Lab.
+ *
+ * Stauf's Goal is space 1, counting up as you go north east
+ * towards the north corner which is space 5 and the moveable
+ * space to the left of that is space 4.
+ * South east from Stauf's goal is the next line starting with
+ * space 6, counting up as you go north east where the moveable
+ * space to the right of the north corner is space 10
+ *
+ * Next line is 11 (unmovable) to 15 (unmoveable), this line
+ * contains the center space which is space 13
+ * Next line is 16 (moveable) to 20 (moveable)
+ * Next line is 21 (unmovable) to 25 (unmovable), with 25 being
+ * the player's goal door
+ *
+ * Space -2 is the next piece, outside of the box
+ */
+void T11hGame::opMouseTrap() {
+	// TODO: Finish the logic
+	byte op = _scriptVariables[2];
+
+	warning("Mousetrap subop %d", op);
+
+	// variable 24 is the mouse?
+	//_scriptVariables[24] = 2;
+
+	// player wins: _scriptVariables[22] = 1;
+	// stauf wins: _scriptVariables[22] = 2;
+	// allows the player to click to place the mouse somewhere? _scriptVariables[5] = 0;
+
+	switch (op) {
+	case 0:
+		break;
+	case 1: // init board
+		// value of 0 is V, 1 is <, 2 is ^, 3 is >
+		// variable 23 is the outside piece
+		_scriptVariables[23] = _random.getRandomNumber(3);
+		// variable slot is the space number + 25, the left corner
+		// (Stauf's goal) is space 1, above that is space 2, the
+		// center is 13, and the right corner (goal) is space 25
+		for (int i = 27; i <= 49; i++) {
+			_scriptVariables[i] = _random.getRandomNumber(3);
+		}
+		break;
+	case 2: // before player chooses the floor to move, set the banned move
+	{
+		int clicked = int(_scriptVariables[0]) * 5 + int(_scriptVariables[1]) + 1;
+		_scriptVariables[clicked + 50] = 0;
+		break;
+	}
+	case 3: // after player moving floor
+		// a bunch of hardcoded conditionals to copy variables and
+		// set the banned move
+		// this probably also sets a variable to allow the player to
+		// move the mouse, and checks for win/lose
+		break;
+	case 5: // maybe player moving mouse
+		break;
+	case 6: // Stauf moving floor?
+		break;
+	case 7: // maybe Stauf moving mouse
+		break;
+	case 8: // Samantha making a move
+		break;
+
+	default:
+		warning("Unknown mousetrap op %d", op);
+		break;
+	}
+}
+
+class T11hCake {
+/*
+* Connect Four puzzle, the cake in the dining room
+*/
+public:
+	Common::RandomSource &_random;
+
+	/*
+	* T11hCake() constructor
+	*	- Each spot on the board is part of multiple potential victory lines
+	*	- The first x and y dimensions of the loops select the origin point of the line
+	*	- The z is for the distance along that line
+	*	- Then we push_back the id number of the line into the array at _map.indecies[x][y]
+	*	- This is used in UpdateScores()
+	*	.
+	* @see UpdateScores()
+	*/
+	T11hCake(Common::RandomSource &rng) : _random(rng) {
+		Restart();
+
+		_map = {};
+		int numLines = 0;
+
+		// map all the lines with slope of (1, 0)
+		for (int y = 0; y < HEIGHT; y++) {
+			for (int x = 0; x <= WIDTH - GOAL_LEN; x++) {
+				for (int z = 0; z < GOAL_LEN; z++) {
+					SetLineNum(x + z, y, numLines);
+				}
+				numLines++;
+			}
+		}
+
+		// map all the lines with slope of (0, 1)
+		for (int x = 0; x < WIDTH; x++) {
+			for (int y = 0; y <= HEIGHT - GOAL_LEN; y++) {
+				for (int z = 0; z < GOAL_LEN; z++) {
+					SetLineNum(x, y + z, numLines);
+				}
+				numLines++;
+			}
+		}
+
+		// map all the lines with slope of (1,1)
+		for (int y = 0; y <= HEIGHT - GOAL_LEN; y++) {
+			for (int x = 0; x <= WIDTH - GOAL_LEN; x++) {
+				for (int z = 0; z < GOAL_LEN; z++) {
+					SetLineNum(x + z, y + z, numLines);
+				}
+				numLines++;
+			}
+		}
+
+		// map all the lines with slope of (1,-1)
+		for (int y = GOAL_LEN - 1; y < HEIGHT; y++) {
+			for (int x = 0; x <= WIDTH - GOAL_LEN; x++) {
+				for (int z = 0; z < GOAL_LEN; z++) {
+					SetLineNum(x + z, y - z, numLines);
+				}
+				numLines++;
+			}
+		}
+	}
+
+	byte OpConnectFour(byte &lastMove) {
+		if (lastMove == 8) {
+			Restart();
+			return 0;
+		}
+
+		if (lastMove == 9) {
+			// samantha makes a move
+			// TODO: fix graphical bug when samantha makes a move
+			lastMove = AiGetBestMove(6);
+			_hasCheated = true;
+			return 0;
+		}
+
+		if (IsColumnFull(lastMove)) {
+			warning("player tried to place a bon bon in a full column, last_move: %d", (int)lastMove);
+			lastMove = 10;
+			return 0;
+		}
+
+		PlaceBonBon(lastMove);
+		byte winner = GetWinner();
+		if (winner) {
+			return winner;
+		}
+
+		lastMove = AiGetBestMove(4 + (_hasCheated == false));
+		PlaceBonBon(lastMove);
+		if (GameEnded())
+			return STAUF;
+
+		return 0;
+	}
+
+private:
+	static const int WIDTH = 8;
+	static const int HEIGHT = 7;
+	static const int GOAL_LEN = 4;
+	static const int WIN_SCORE = 1000000;//!< the number of points added for a connect four
+	static const byte STAUF = 1;
+	static const byte PLAYER = 2;
+	static const int NUM_LINES = 107;//!< how many potential victory lines there are
+
+
+	//! ID numbers for all of the potential victory lines for each spot on the board
+	struct LinesMappings {
+		byte lengths[WIDTH][HEIGHT];
+		byte indecies[WIDTH][HEIGHT][GOAL_LEN * GOAL_LEN];
+	};
+
+	//! how many points a player has, and their progress on potential victory lines
+	struct PlayerProgress {
+		int _score;
+		int _linesCounters[NUM_LINES];//!< how many pieces are claimed in each potential victory, links to LineMappings, an entry of 4 means that's a victory
+	};
+
+	PlayerProgress _playerProgress;
+	PlayerProgress _staufProgress;
+
+	byte _boardState[WIDTH][HEIGHT];//!< (0, 0) is the bottom left of the board
+	byte _columnHeights[WIDTH];
+
+	int _moveCount;
+	bool _hasCheated;
+
+	LinesMappings _map;//!< ID numbers for all of the potential victory lines for each spot on the board
+
+	void Restart() {
+		_playerProgress = {};
+		_staufProgress = {};
+		memset(_boardState, 0, sizeof(_boardState));
+		memset(_columnHeights, 0, sizeof(_columnHeights));
+		_moveCount = 0;
+		_hasCheated = false;
+
+		_playerProgress._score = NUM_LINES;
+		_staufProgress._score = NUM_LINES;
+	}
+
+	void SetLineNum(uint x, uint y, uint index) {
+		assert(x < WIDTH);
+		assert(y < HEIGHT);
+		byte slot = _map.lengths[x][y]++;
+		assert(slot < GOAL_LEN * GOAL_LEN);
+		assert(index < NUM_LINES);
+		_map.indecies[x][y][slot] = index;
+	}
+
+	bool IsColumnFull(byte column) {
+		return _columnHeights[column] >= HEIGHT;
+	}
+
+	PlayerProgress &GetPlayerProgress(bool stauf) {
+		if (stauf)
+			return _staufProgress;
+		else
+			return _playerProgress;
+	}
+
+	/*
+	* UpdateScores()
+	*	- Each PlayerProgress has an array of ints, _linesCounters[], where each entry maps to the ID of a line
+	*	- When a bon bon is added to the board, we look up _map.lengths[x][y] and then loop through all the indecies for that point
+	*		- Increment the PlayerProgress._linesCounters[id]
+	*		- Calculate the scores proportional to the PlayerProgress._linesCounters[id]
+	*		.
+	*	.
+	*/
+	void UpdateScores(byte x, bool revert=false) {
+		bool stauf = _moveCount % 2;
+		PlayerProgress &pp = GetPlayerProgress(stauf);
+
+		byte y = _columnHeights[x] - 1;
+
+		// get the number of potential victory lines that this spot exists in
+		int num_lines = _map.lengths[x][y];
+
+		for (int line = 0; line < num_lines; line++) {
+			// get the ID for this potential victory line
+			int index = _map.indecies[x][y][line];
+			int len = pp._linesCounters[index];
+
+			// add this new bon bon to the progress of this potential victory line, or remove in the case of revert
+			int mult = 1;// mult is used for multiplying the score gains, depends on revert
+			if (!revert)
+				pp._linesCounters[index]++;
+			else {
+				len = --pp._linesCounters[index];
+				mult = -1;
+			}
+
+			if (GOAL_LEN == len + 1) {
+				// that's a bingo
+				pp._score += WIN_SCORE * mult;
+			}
+			else {
+				PlayerProgress &pp2 = GetPlayerProgress(!stauf);
+				int len2 = pp2._linesCounters[index];
+				if (len == 0) {
+					// we started a new line, take away the points the opponent had from this line since we ruined it for them
+					pp2._score -= (1 << (len2 & 31)) * mult;
+				}
+				if (len2 == 0) {
+					// the opponent doesn't have any spots in this line, so we get points for it
+					pp._score += (1 << (len & 31)) * mult;
+				}
+			}
+		}
+	}
+
+	void PlaceBonBon(byte x) {
+		byte y = _columnHeights[x]++;
+		if (_moveCount % 2)
+			_boardState[x][y] = STAUF;
+		else
+			_boardState[x][y] = PLAYER;
+
+		UpdateScores(x);
+
+		_moveCount++;
+	}
+
+	void RevertMove(byte x) {
+		// PlaceBonBon in reverse, this is used for the AI's recursion rollback
+		_moveCount--;
+
+		UpdateScores(x, true);
+
+		byte y = --_columnHeights[x];
+		_boardState[x][y] = 0;
+	}
+
+	byte GetWinner() {
+		if (_playerProgress._score >= WIN_SCORE)
+			return PLAYER;
+
+		if (_staufProgress._score >= WIN_SCORE)
+			return STAUF;
+
+		return 0;
+	}
+
+	bool GameEnded() {
+		if (GetWinner())
+			return true;
+
+		if (_moveCount >= WIDTH * HEIGHT)
+			return true;
+
+		return false;
+	}
+
+	int GetScoreDiff() {
+		if (_moveCount % 2)
+			return _staufProgress._score - _playerProgress._score;
+		else
+			return _playerProgress._score - _staufProgress._score;
+	}
+
+	int AiRecurse(int search_depth, int parent_score) {
+		int best_score = 0x7fffffff;
+
+		for (byte move = 0; move < WIDTH; move++) {
+			if (IsColumnFull(move))
+				continue;
+
+			PlaceBonBon(move);
+			int score = GetScoreDiff();
+			if (search_depth > 1 && !GameEnded())
+				score = AiRecurse(search_depth - 1, best_score);
+			RevertMove(move);
+
+			if (score < best_score)
+				best_score = score;
+
+			if (-parent_score != best_score && parent_score <= -best_score)
+				break;
+		}
+
+		// we negate the score because from the perspective of our parent caller, this is his opponent's score
+		return -best_score;
+	}
+
+	uint Rng() {
+		return _random.getRandomNumber(UINT_MAX);
+	}
+
+	byte AiGetBestMove(int search_depth) {
+		int best_move = 0xffff;
+		uint counter = 1;
+
+		for (int best_score = 0x7fffffff; best_score > 999999 && search_depth > 1; search_depth--) {
+			for (byte move = 0; move < WIDTH; move++) {
+				if (IsColumnFull(move))
+					continue;
+
+				PlaceBonBon(move);
+				if (GetWinner()) {
+					RevertMove(move);
+					return move;
+				}
+
+				int score = AiRecurse(search_depth - 1, best_score);
+				RevertMove(move);
+				if (score < best_score) {
+					counter = 1;
+					best_move = move;
+					best_score = score;
+				} else if (best_score == score) {
+					// rng is only used on moves with equal scores
+					counter++;
+					uint r = Rng() % 1000000;
+					if (r * counter < 1000000) {
+						best_move = move;
+					}
+				}
+			}
+		}
+
+		return best_move;
+	}
+};
+
+void T11hGame::opConnectFour() {
+	byte &last_move = _scriptVariables[1];
+	byte &winner = _scriptVariables[3];
+	winner = 0;
+
+	if (_cake == NULL) {
+		clearAIs();
+		_cake = new T11hCake(_random);
+	}
+
+	winner = _cake->OpConnectFour(last_move);
+
+	if (winner) {
+		clearAIs();
+	}
+}
+
+void T11hGame::clearAIs() {
+	if (_cake != NULL) {
+		delete _cake;
+		_cake = NULL;
+	}
+}
+
+
+/*
+ * Beehive puzzle
+ *
+ * An infection-style game in which the player must cover more
+ * territory than the computer. It's similar to the microscope puzzle
+ * in the 7th Guest. The playfield is a honeycomb made of 61
+ * hexagons. The hexagons are numbered starting from the top-left
+ * corner, with a direction from bottom left to top right.
+ */
+void T11hGame::opBeehive() {
+	// TODO: Finish the logic
+	int8 *hexagons = (int8 *)_scriptVariables + 25;
+	int8 *hexDifference = (int8 *)_scriptVariables + 13;
+	byte op = _scriptVariables[14] - 1;
+
+	enum kBeehiveColor {
+		kBeehiveColorYellow = -1,
+		kBeehiveColorRed = 1
+	};
+
+	warning("Beehive subop %d", op);
+
+	//*hexDifference = 4;
+	*hexDifference = 5; // DEBUG: set the difference to 5 to skip the game
+
+	switch (op) {
+	case 0:	// init board's hexagons
+		memset(_beehiveHexagons, 0, 60);
+		_beehiveHexagons[0] = kBeehiveColorYellow;
+		_beehiveHexagons[4] = kBeehiveColorRed;
+		_beehiveHexagons[34] = kBeehiveColorYellow;
+		_beehiveHexagons[60] = kBeehiveColorRed;
+		_beehiveHexagons[56] = kBeehiveColorYellow;
+		_beehiveHexagons[26] = kBeehiveColorRed;
+		break;
+	case 1:
+		memset(hexagons, 0, 60);
+		_scriptVariables[85] = 0;
+		//opBeehiveSub2();	// TODO
+		// TODO: Check opBeehiveSub2()'s result
+		//*hexDifference = opBeehiveGetHexDifference();
+		break;
+	case 2:
+		memset(hexagons, 0, 60);
+		_scriptVariables[85] = 0;
+		//opBeehiveSub4();	// TODO
+		break;
+	case 3:
+		break;
+	case 4:
+		break;
+	case 5:
+		break;
+	case 6:
+		break;
+	default:
+		break;
+	}
+}
+
+int8 T11hGame::opBeehiveGetHexDifference() {
+	return (opBeehiveGetTotal(_beehiveHexagons) >= 0) + 5;
+}
+
+int8 T11hGame::opBeehiveGetTotal(int8 *hexagons) {
+	int8 result = 0;
+
+	for (int i = 0; i < 61; i++)
+		result += hexagons[i];
+
+	return result;
+}
+
+void T11hGame::opPente() {
+	// FIXME: properly implement Pente game (the final puzzle)
+	// for now just auto-solve the puzzle so the player can continue
+	_scriptVariables[5] = 4;
+}
+
+/*
+ * Puzzle in the Gallery.
+ * The aim is to select the last piece of the image.
+ * There are 18 pieces in total.
+ * When selecting a piece, all surrounding pieces are also selected
+ *
+ * +--------------------+--------------------------------+--------+
+ * |         1/1A       |       2/1B                     |        |
+ * |  +--------------+--+--------------------------+-----+        |
+ * |  |              |                             |              |
+ * +--+     4/1D     |            5/1E             |       3/1C   |
+ * |                 |                             |              |
+ * +-----+--------+--+--------+-----------------+--+--------+     |
+ * |     |        |           |                 |           |     |
+ * |     |        |           |                 |           |     |
+ * |     |        |   8/21    |                 |           |     |
+ * |     |        |           |     +-----------+           |     |
+ * |     |        |           |     |           |           |     |
+ * |     |        +-----------+     |   10/23   |   9/22    |     |
+ * |     |                          |           |           |     |
+ * |     |           7/20           +-----+-----+           +-----+
+ * |     |                          |     |     |           |     |
+ * |     +--------------------------+     |     |           |     |
+ * |              6/1F                    |     |           |     |
+ * +-----------+-----------+-----+--+     | 11  |           | 12  |
+ * |   13/26   |           |     |  |     | /   |           | /   |
+ * |     +-----+-----+     |     |  |     | 24  +-----------+ 25  |
+ * |     |           |     |     |  |     |     |           |     |
+ * +-----+   17/2A   |     |     |16|     |     |           |     |
+ * |     |           |     |     |/ |     |     |           |     |
+ * |     +-----+-----+     |     |29|     |     |           +-----+
+ * |           |           |     |  |     |     |           |     |
+ * |           |           |     |  |     +-----+   18/2B   |     |
+ * |   19/2C   |   14/27   |     |  |           |           |     |
+ * |           |           |     |  +-----------+           |     |
+ * |           |           |     |  |           |           |     |
+ * |           |           |     +--+   15/28   |           |     |
+ * |           |           |                    |           |     |
+ * |           +--------+--+--------------------+-----------+     |
+ * |           | 20/2D  |              21/2E                      |
+ * +-----------+--------+-----------------------------------------+
+ */
+
+// Links between the pieces in the Gallery challenge
+// For example, the first row signifies that piece 1
+// is connected to pieces 2, 4 and 5
+const byte T11hGame::kGalleryLinks[21][10] = {
+	{ 2,  4,  5,  0,  0,  0,  0,  0,  0,  0 },	//  1
+	{ 1,  5,  3,  0,  0,  0,  0,  0,  0,  0 },	//  2
+	{ 2,  5,  9, 12,  0,  0,  0,  0,  0,  0 },	//  3
+	{ 1,  5,  6,  7,  8,  0,  0,  0,  0,  0 },	//  4
+	{ 1,  2,  3,  4,  7,  8,  9,  0,  0,  0 },	//  5
+	{ 4,  7, 10, 11, 13, 14, 15, 16, 18,  0 },	//  6
+	{ 4,  5,  6,  8,  9, 10,  0,  0,  0,  0 },	//  7
+	{ 4,  5,  7,  0,  0,  0,  0,  0,  0,  0 },	//  8
+	{ 3,  5,  7, 10, 11, 12, 18,  0,  0,  0 },	//  9
+	{ 6,  7,  9, 11,  0,  0,  0,  0,  0,  0 },	// 10
+	{ 6,  9, 10, 18,  0,  0,  0,  0,  0,  0 },	// 11
+	{ 3,  9, 18, 21,  0,  0,  0,  0,  0,  0 },	// 12
+	{ 6, 14, 17, 19,  0,  0,  0,  0,  0,  0 },	// 13
+	{ 6, 13, 15, 17, 19, 20, 21,  0,  0,  0 },	// 14
+	{ 6, 14, 16, 18, 21,  0,  0,  0,  0,  0 },	// 15
+	{ 6, 15,  0,  0,  0,  0,  0,  0,  0,  0 },	// 16
+	{13, 14, 19,  0,  0,  0,  0,  0,  0,  0 },	// 17
+	{ 6,  9, 11, 12, 15, 21,  0,  0,  0,  0 },	// 18
+	{13, 14, 17, 20,  0,  0,  0,  0,  0,  0 },	// 19
+	{14, 19, 21,  0,  0,  0,  0,  0,  0,  0 },	// 20
+	{12, 14, 15, 18, 20,  0,  0,  0,  0,  0 }	// 21
+};
+
+void T11hGame::opGallery() {
+	const int kPieceCount = 21;
+	byte pieceStatus[kPieceCount];
+	byte var_18[kPieceCount];
+	int selectedPieces;
+	byte curLink = 0;
+
+	enum kGalleryPieceStatus {
+		kPieceUnselected = 0,
+		kPieceSelected = 1
+	};
+
+	memcpy(pieceStatus, _scriptVariables + 26, kPieceCount);
+
+	selectedPieces = 0;
+	for (int i = 0; i < kPieceCount; i++) {
+		var_18[i] = 0;
+		if (pieceStatus[i] == kPieceSelected) {
+			curLink = kGalleryLinks[i][0];
+			pieceStatus[i] = kPieceUnselected;
+
+			int linkedPiece = 1;
+			while (curLink != 0) {
+				linkedPiece++;
+				pieceStatus[curLink - 1] = kPieceUnselected;
+				curLink = kGalleryLinks[linkedPiece - 1][i];
+			}
+			var_18[i] = opGallerySub(pieceStatus, 1);
+			if (var_18[i] == kPieceSelected) {
+				selectedPieces++;
+			}
+		}
+	}
+
+	if (selectedPieces == 0) {
+		int esi = 0;
+		for (int i = 0; i < kPieceCount; i++) {
+			if (esi < var_18[i]) {
+				esi = var_18[i];
+			}
+		}
+
+		if (esi == 2) {
+			esi = 1;
+		} else {
+			if (esi < kPieceCount) {
+				esi = 2;
+			} else {
+				esi -= 12;
+			}
+		}
+
+		for (int i = 0; i < kPieceCount; i++) {
+			if (esi < var_18[i]) {
+				var_18[i] = kPieceSelected;
+				selectedPieces++;
+			}
+		}
+	}
+
+	int selectedPiece;
+
+	// TODO: copy the AI from the game
+	do {
+		selectedPiece = _random.getRandomNumber(20) + 1;
+	} while (_scriptVariables[selectedPiece + 25] != 1);
+
+	setScriptVar(47, selectedPiece / 10);
+	setScriptVar(48, selectedPiece % 10);
+}
+
+byte T11hGame::opGallerySub(byte *field, int start) {
+	// TODO
+	warning("STUB: T11hGame::opGallerySub()");
+	return 0;
+}
+
+void T11hGame::opTriangle() {
+	// TODO
+}
+
+// This function is mainly for debugging purposes
+void inline T11hGame::setScriptVar(uint16 var, byte value) {
+	_scriptVariables[var] = value;
+	debugC(5, kDebugTlcGame, "script variable[0x%03X] = %d (0x%04X)", var, value, value);
+}
+
+void inline T11hGame::setScriptVar16(uint16 var, uint16 value) {
+	_scriptVariables[var] = value & 0xFF;
+	_scriptVariables[var + 1] = (value >> 8) & 0xFF;
+	debugC(5, kDebugTlcGame, "script variable[0x%03X, 0x%03X] = %d (0x%02X, 0x%02X)",
+		var, var + 1, value, _scriptVariables[var], _scriptVariables[var + 1]);
+}
+
+uint16 inline T11hGame::getScriptVar16(uint16 var) {
+	uint16 value;
+
+	value = _scriptVariables[var];
+	value += _scriptVariables[var + 1] << 8;
+
+	return value;
+}
+
+} // End of Namespace Groovie
diff --git a/engines/groovie/logic/t11hgame.h b/engines/groovie/logic/t11hgame.h
index 7bb97156cc..24e9a919b7 100644
--- a/engines/groovie/logic/t11hgame.h
+++ b/engines/groovie/logic/t11hgame.h
@@ -1,75 +1,75 @@
-/* ScummVM - Graphic Adventure Engine
-*
-* ScummVM is the legal property of its developers, whose names
-* are too numerous to list here. Please refer to the COPYRIGHT
-* file distributed with this source distribution.
-*
-* This program is free software; you can redistribute it and/or
-* modify it under the terms of the GNU General Public License
-* as published by the Free Software Foundation; either version 2
-* of the License, or (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-*
-*/
-
-#ifndef GROOVIE_LOGIC_T11HGAME_H
-#define GROOVIE_LOGIC_T11HGAME_H
-
-#include "common/textconsole.h"
-#include "common/random.h"
-
-namespace Groovie {
-
-class GroovieEngine;
-
-#ifdef ENABLE_GROOVIE2
-class T11hCake;
-#endif
-
-class T11hGame {
-public:
-#ifdef ENABLE_GROOVIE2
-	T11hGame(byte *scriptVariables);
-	~T11hGame();
-
-	void handleOp(uint8 op);
-
-private:
-	Common::RandomSource _random;
-
-	void opMouseTrap();
-	void opConnectFour();
-	void opBeehive();
-	void opPente();
-	void opGallery();
-	void opTriangle();
-
-	byte opGallerySub(byte *field, int start);
-	int8 opBeehiveGetHexDifference();
-	int8 opBeehiveGetTotal(int8 *hexagons);
-	void inline setScriptVar(uint16 var, byte value);
-	void inline setScriptVar16(uint16 var, uint16 value);
-	uint16 inline getScriptVar16(uint16 var);
-
-	void clearAIs();
-
-	T11hCake *_cake;
-	byte *_scriptVariables;
-
-	int8 _beehiveHexagons[61];
-
-	static const byte kGalleryLinks[21][10];
-#endif
-};
-
-} // End of Groovie namespace
-
-#endif // GROOVIE_LOGIC_T11HGAME_H
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*/
+
+#ifndef GROOVIE_LOGIC_T11HGAME_H
+#define GROOVIE_LOGIC_T11HGAME_H
+
+#include "common/textconsole.h"
+#include "common/random.h"
+
+namespace Groovie {
+
+class GroovieEngine;
+
+#ifdef ENABLE_GROOVIE2
+class T11hCake;
+#endif
+
+class T11hGame {
+public:
+#ifdef ENABLE_GROOVIE2
+	T11hGame(byte *scriptVariables);
+	~T11hGame();
+
+	void handleOp(uint8 op);
+
+private:
+	Common::RandomSource _random;
+
+	void opMouseTrap();
+	void opConnectFour();
+	void opBeehive();
+	void opPente();
+	void opGallery();
+	void opTriangle();
+
+	byte opGallerySub(byte *field, int start);
+	int8 opBeehiveGetHexDifference();
+	int8 opBeehiveGetTotal(int8 *hexagons);
+	void inline setScriptVar(uint16 var, byte value);
+	void inline setScriptVar16(uint16 var, uint16 value);
+	uint16 inline getScriptVar16(uint16 var);
+
+	void clearAIs();
+
+	T11hCake *_cake;
+	byte *_scriptVariables;
+
+	int8 _beehiveHexagons[61];
+
+	static const byte kGalleryLinks[21][10];
+#endif
+};
+
+} // End of Groovie namespace
+
+#endif // GROOVIE_LOGIC_T11HGAME_H
diff --git a/engines/groovie/logic/tlcgame.h b/engines/groovie/logic/tlcgame.h
index 8363478c1f..b064ccb375 100644
--- a/engines/groovie/logic/tlcgame.h
+++ b/engines/groovie/logic/tlcgame.h
@@ -1,194 +1,194 @@
-/* ScummVM - Graphic Adventure Engine
-*
-* ScummVM is the legal property of its developers, whose names
-* are too numerous to list here. Please refer to the COPYRIGHT
-* file distributed with this source distribution.
-*
-* This program is free software; you can redistribute it and/or
-* modify it under the terms of the GNU General Public License
-* as published by the Free Software Foundation; either version 2
-* of the License, or (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-*
-*/
-
-#ifndef GROOVIE_LOGIC_TLCGAME_H
-#define GROOVIE_LOGIC_TLCGAME_H
-
-#include "common/textconsole.h"
-#include "common/random.h"
-
-#define GROOVIE_TLC_MAX_EPSIODES    (15)
-#define GROOVIE_TLC_MAX_QUEST_EP	(50)
-
-namespace Groovie {
-
-class GroovieEngine;
-
-// The regions.rle contains 898 entries. Round about 18 kByte in memory.
-struct TlcRegionsHeader {
-	char   name[12];
-	int    numAnswers;
-	uint32 offset;
-};
-
-struct TlcRegion {
-	uint16 left;
-	uint16 top;
-	uint16 right;
-	uint16 bottom;
-};
-
-struct TlcEpQuestionData {
-	bool   questionUsed;
-	uint32 questionScore;
-};
-
-struct TlcTatHeader {
-	uint32 questionsNum;
-	uint32 questionsOffset;
-	uint8  binDividends[16];
-};
-
-struct TlcTatAnswer {
-	uint8  binScore[8];
-};
-
-struct TlcTatQuestions {
-	char name[6];
-	int  answerCount;
-	TlcTatAnswer answerData[8];
-};
-
-class TlcGame
-{
-public:
-#ifdef ENABLE_GROOVIE2
-	TlcGame(byte *scriptVariables);
-	~TlcGame();
-
-	static const char *getTlcMusicFilename(int musicId);
-
-	void handleOp(uint8 op);
-
-	/**
-	 * Handle region commands. A region describes the coordinates of
-	 * a rectangle as clickable area in the question dialogs. These regions
-	 * are provided by a the extra file.
-	 * screen coordinates.
-	 */
-	void opRegions();
-
-	/**
-	 * Get the coordiantes of the region for the next answer. There are 
-	 * up to 8 answers possible for each question. In the script the
-	 * coordinates are (0,0,0,0) which will be replace by the new ones.
-	 * @param left        Left value of the rectangle
-	 * @param top         Top value of the rectangle
-	 * @param right       Right value of the rectangle
-	 * @param bottom      Bottom value of the rectangle
-	 * @return            0 if anwer was found. -1 in case no more answer
-	 *                    available for this question
-	 */
-	int getRegionNext(uint16 &left, uint16 &top, uint16 &right, uint16 &bottom);
-
-	/**
-	 * Rewinds the internal answer counter for the function
-	 * getRegionNext()
-	 */
-	void getRegionRewind();
-
-
-	/**
-	 * Handles some flags which are used during a TAT. The game seems to
-	 * use this flags to skip some questions during a TAT.
-	 * OpCode_0x42(2) 
-	 */
-	void opFlags();
-
-
-	/**
-	 * Handles all Exit Poll commands. The exit poll (EP) questions are
-	 * described in detail in the file EPAIDB.RLE.
-	 * OpCode_0x42(1)
-	 */
-	void opExitPoll();
-
-	/**
-	 * Handles all TAT commands. The TAT questions are described in detail
-	 * in the file TATAIDB.RLE
-	 */
-	void opTat();
-
-private:
-	Common::RandomSource _random;
-
-	void inline setScriptVar(uint16 var, byte value);
-	void inline setScriptVar16(uint16 var, uint16 value);
-	uint16 inline getScriptVar16(uint16 var);
-	byte *_scriptVariables;
-
-	/**
-	 * Loads the description part of the regions.rle file into memory
-	 * This makes it faster to search for the correct quesion.
-	 */
-	void regionsInit();
-	void regionsLoad();
-
-	// Variables for region handling
-	int       _numRegionHeaders;
-	int       _curAnswerIndex;
-	int       _curQuestNumAnswers;
-	TlcRegion _curQuestRegions[8];
-	TlcRegionsHeader *_regionHeader;
-
-	/**
-	 * Functions for Exit Poll Commands
-	 */
-	void epInit();
-	void epSelectNextQuestion();
-	void epResultQuestion();
-	void epResultEpisode();
-
-	// Variables for Exit Poll handling
-	int16  _epScoreBin[6];
-	int    _epEpisodeIdx;                   // 15 Episodes: 0..14
-	int    _epQuestionIdx;					// 1..X (questions in current episode. counted up for every question)
-	int    _epQuestionNumOfPool;            // 1..X (question number in the data base. The questions are played in random order)
-	int    _epQuestionsInEpisode;
-	TlcEpQuestionData *_epQuestionsData;
-
-	// Variables for flag handling
-	byte _tatFlags[0x0E][0x09];
-
-	/**
-	 * Functions for TAT Commands
-	 */
-	void tatInitRegs();
-	void tatLoadDB();
-	void tatLoadDBHeaders();
-	void tatResultQuest();
-	void tatResultEpisode();
-	void tatGetProfile();
-	void debugTatFlags(int y, int y2);
-
-	// Variables for TAT handling
-	int _tatEpisodes;
-	int _tatQuestCount;
-	TlcTatHeader *_tatHeaders;
-	TlcTatQuestions *_tatQuestions;
-	// uint8 _tatCoeffs[15][16];
-#endif
-};
-
-} // End of Groovie namespace
-
-#endif // GROOVIE_LOGIC_TLCGAME_H
+/* ScummVM - Graphic Adventure Engine
+*
+* ScummVM is the legal property of its developers, whose names
+* are too numerous to list here. Please refer to the COPYRIGHT
+* file distributed with this source distribution.
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*/
+
+#ifndef GROOVIE_LOGIC_TLCGAME_H
+#define GROOVIE_LOGIC_TLCGAME_H
+
+#include "common/textconsole.h"
+#include "common/random.h"
+
+#define GROOVIE_TLC_MAX_EPSIODES    (15)
+#define GROOVIE_TLC_MAX_QUEST_EP	(50)
+
+namespace Groovie {
+
+class GroovieEngine;
+
+// The regions.rle contains 898 entries. Round about 18 kByte in memory.
+struct TlcRegionsHeader {
+	char   name[12];
+	int    numAnswers;
+	uint32 offset;
+};
+
+struct TlcRegion {
+	uint16 left;
+	uint16 top;
+	uint16 right;
+	uint16 bottom;
+};
+
+struct TlcEpQuestionData {
+	bool   questionUsed;
+	uint32 questionScore;
+};
+
+struct TlcTatHeader {
+	uint32 questionsNum;
+	uint32 questionsOffset;
+	uint8  binDividends[16];
+};
+
+struct TlcTatAnswer {
+	uint8  binScore[8];
+};
+
+struct TlcTatQuestions {
+	char name[6];
+	int  answerCount;
+	TlcTatAnswer answerData[8];
+};
+
+class TlcGame
+{
+public:
+#ifdef ENABLE_GROOVIE2
+	TlcGame(byte *scriptVariables);
+	~TlcGame();
+
+	static const char *getTlcMusicFilename(int musicId);
+
+	void handleOp(uint8 op);
+
+	/**
+	 * Handle region commands. A region describes the coordinates of
+	 * a rectangle as clickable area in the question dialogs. These regions
+	 * are provided by a the extra file.
+	 * screen coordinates.
+	 */
+	void opRegions();
+
+	/**
+	 * Get the coordiantes of the region for the next answer. There are
+	 * up to 8 answers possible for each question. In the script the
+	 * coordinates are (0,0,0,0) which will be replace by the new ones.
+	 * @param left        Left value of the rectangle
+	 * @param top         Top value of the rectangle
+	 * @param right       Right value of the rectangle
+	 * @param bottom      Bottom value of the rectangle
+	 * @return            0 if anwer was found. -1 in case no more answer
+	 *                    available for this question
+	 */
+	int getRegionNext(uint16 &left, uint16 &top, uint16 &right, uint16 &bottom);
+
+	/**
+	 * Rewinds the internal answer counter for the function
+	 * getRegionNext()
+	 */
+	void getRegionRewind();
+
+
+	/**
+	 * Handles some flags which are used during a TAT. The game seems to
+	 * use this flags to skip some questions during a TAT.
+	 * OpCode_0x42(2)
+	 */
+	void opFlags();
+
+
+	/**
+	 * Handles all Exit Poll commands. The exit poll (EP) questions are
+	 * described in detail in the file EPAIDB.RLE.
+	 * OpCode_0x42(1)
+	 */
+	void opExitPoll();
+
+	/**
+	 * Handles all TAT commands. The TAT questions are described in detail
+	 * in the file TATAIDB.RLE
+	 */
+	void opTat();
+
+private:
+	Common::RandomSource _random;
+
+	void inline setScriptVar(uint16 var, byte value);
+	void inline setScriptVar16(uint16 var, uint16 value);
+	uint16 inline getScriptVar16(uint16 var);
+	byte *_scriptVariables;
+
+	/**
+	 * Loads the description part of the regions.rle file into memory
+	 * This makes it faster to search for the correct quesion.
+	 */
+	void regionsInit();
+	void regionsLoad();
+
+	// Variables for region handling
+	int       _numRegionHeaders;
+	int       _curAnswerIndex;
+	int       _curQuestNumAnswers;
+	TlcRegion _curQuestRegions[8];
+	TlcRegionsHeader *_regionHeader;
+
+	/**
+	 * Functions for Exit Poll Commands
+	 */
+	void epInit();
+	void epSelectNextQuestion();
+	void epResultQuestion();
+	void epResultEpisode();
+
+	// Variables for Exit Poll handling
+	int16  _epScoreBin[6];
+	int    _epEpisodeIdx;                   // 15 Episodes: 0..14
+	int    _epQuestionIdx;					// 1..X (questions in current episode. counted up for every question)
+	int    _epQuestionNumOfPool;            // 1..X (question number in the data base. The questions are played in random order)
+	int    _epQuestionsInEpisode;
+	TlcEpQuestionData *_epQuestionsData;
+
+	// Variables for flag handling
+	byte _tatFlags[0x0E][0x09];
+
+	/**
+	 * Functions for TAT Commands
+	 */
+	void tatInitRegs();
+	void tatLoadDB();
+	void tatLoadDBHeaders();
+	void tatResultQuest();
+	void tatResultEpisode();
+	void tatGetProfile();
+	void debugTatFlags(int y, int y2);
+
+	// Variables for TAT handling
+	int _tatEpisodes;
+	int _tatQuestCount;
+	TlcTatHeader *_tatHeaders;
+	TlcTatQuestions *_tatQuestions;
+	// uint8 _tatCoeffs[15][16];
+#endif
+};
+
+} // End of Groovie namespace
+
+#endif // GROOVIE_LOGIC_TLCGAME_H




More information about the Scummvm-git-logs mailing list