From 3215d14e8265f6ad901272f3dd1d3f44ec09eaf5 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Sun, 27 Dec 2015 01:42:20 +0200 Subject: LAB: Rename TilePuzzle to SpecialLocks, to better reflect its purpose This class handles two different special locks, the tile puzzle and the combination door --- engines/lab/engine.cpp | 36 ++-- engines/lab/lab.cpp | 8 +- engines/lab/lab.h | 4 +- engines/lab/module.mk | 2 +- engines/lab/savegame.cpp | 6 +- engines/lab/speciallocks.cpp | 394 ++++++++++++++++++++++++++++++++++++++++++ engines/lab/speciallocks.h | 94 ++++++++++ engines/lab/tilepuzzle.cpp | 396 ------------------------------------------- engines/lab/tilepuzzle.h | 104 ------------ 9 files changed, 516 insertions(+), 528 deletions(-) create mode 100644 engines/lab/speciallocks.cpp create mode 100644 engines/lab/speciallocks.h delete mode 100644 engines/lab/tilepuzzle.cpp delete mode 100644 engines/lab/tilepuzzle.h diff --git a/engines/lab/engine.cpp b/engines/lab/engine.cpp index 59d5ff1070..2d45ab6ac0 100644 --- a/engines/lab/engine.cpp +++ b/engines/lab/engine.cpp @@ -39,18 +39,20 @@ #include "lab/music.h" #include "lab/processroom.h" #include "lab/resource.h" -#include "lab/tilepuzzle.h" +#include "lab/speciallocks.h" #include "lab/utils.h" namespace Lab { -// LAB: Labyrinth specific code for the special puzzles -#define SPECIALLOCK 100 -#define SPECIALBRICK 101 -#define SPECIALBRICKNOMOUSE 102 - #define CRUMBSWIDTH 24 #define CRUMBSHEIGHT 24 + +enum SpecialLock { + kLockCombination = 100, + kLockTiles = 101, + kLockTileSolution = 102 +}; + enum Items { kItemHelmet = 1, kItemBelt = 3, @@ -442,16 +444,14 @@ void LabEngine::mainGameLoop() { _roomsFound->inclElement(_roomNum); _curFileName = _nextFileName; - if (_closeDataPtr) { + if (_closeDataPtr && _mainDisplay) { switch (_closeDataPtr->_closeUpType) { - case SPECIALLOCK: - if (_mainDisplay) - _tilePuzzle->showCombination(_curFileName); + case kLockCombination: + _specialLocks->showCombinationLock(_curFileName); break; - case SPECIALBRICK: - case SPECIALBRICKNOMOUSE: - if (_mainDisplay) - _tilePuzzle->showTile(_curFileName, (_closeDataPtr->_closeUpType == SPECIALBRICKNOMOUSE)); + case kLockTiles: + case kLockTileSolution: + _specialLocks->showTileLock(_curFileName, (_closeDataPtr->_closeUpType == kLockTileSolution)); break; default: _graphics->readPict(_curFileName, false); @@ -571,10 +571,10 @@ bool LabEngine::processEvent(MessageClass tmpClass, uint16 code, uint16 qualifie interfaceOff(); _mainDisplay = true; - if (_closeDataPtr && _closeDataPtr->_closeUpType == SPECIALLOCK) - _tilePuzzle->mouseCombination(curPos); - else if (_closeDataPtr && _closeDataPtr->_closeUpType == SPECIALBRICK) - _tilePuzzle->mouseTile(curPos); + if (_closeDataPtr && _closeDataPtr->_closeUpType == kLockCombination) + _specialLocks->combinationClick(curPos); + else if (_closeDataPtr && _closeDataPtr->_closeUpType == kLockTiles) + _specialLocks->tileClick(curPos); else performAction(actionMode, curPos, curInv); diff --git a/engines/lab/lab.cpp b/engines/lab/lab.cpp index 815053e71e..be299a8236 100644 --- a/engines/lab/lab.cpp +++ b/engines/lab/lab.cpp @@ -44,7 +44,7 @@ #include "lab/music.h" #include "lab/processroom.h" #include "lab/resource.h" -#include "lab/tilepuzzle.h" +#include "lab/speciallocks.h" #include "lab/utils.h" namespace Lab { @@ -85,7 +85,7 @@ LabEngine::LabEngine(OSystem *syst, const ADGameDescription *gameDesc) _graphics = nullptr; _rooms = nullptr; _roomsFound = nullptr; - _tilePuzzle = nullptr; + _specialLocks = nullptr; _utils = nullptr; _console = nullptr; _journalBackImage = nullptr; @@ -151,7 +151,7 @@ LabEngine::~LabEngine() { delete _music; delete _anim; delete _graphics; - delete _tilePuzzle; + delete _specialLocks; delete _utils; delete _console; delete _journalBackImage; @@ -168,7 +168,7 @@ Common::Error LabEngine::run() { _music = new Music(this); _graphics = new DisplayMan(this); _anim = new Anim(this); - _tilePuzzle = new TilePuzzle(this); + _specialLocks = new SpecialLocks(this); _utils = new Utils(this); _console = new Console(this); _journalBackImage = new Image(this); diff --git a/engines/lab/lab.h b/engines/lab/lab.h index 8f20538963..fd09db0a37 100644 --- a/engines/lab/lab.h +++ b/engines/lab/lab.h @@ -63,7 +63,7 @@ class EventManager; class Image; class Music; class Resource; -class TilePuzzle; +class SpecialLocks; class Utils; struct SaveGameHeader { @@ -193,7 +193,7 @@ public: Resource *_resource; RoomData *_rooms; TextFont *_msgFont; - TilePuzzle *_tilePuzzle; + SpecialLocks *_specialLocks; Utils *_utils; Console *_console; GUI::Debugger *getDebugger() { return _console; } diff --git a/engines/lab/module.mk b/engines/lab/module.mk index a619cba6ed..7bb86c8c1e 100644 --- a/engines/lab/module.mk +++ b/engines/lab/module.mk @@ -18,7 +18,7 @@ MODULE_OBJS := \ resource.o \ savegame.o \ special.o \ - tilepuzzle.o \ + speciallocks.o \ utils.o # This module can be built as a plugin diff --git a/engines/lab/savegame.cpp b/engines/lab/savegame.cpp index beeae8dae0..1564babfc8 100644 --- a/engines/lab/savegame.cpp +++ b/engines/lab/savegame.cpp @@ -43,7 +43,7 @@ #include "lab/labsets.h" #include "lab/music.h" #include "lab/processroom.h" -#include "lab/tilepuzzle.h" +#include "lab/speciallocks.h" namespace Lab { @@ -144,7 +144,7 @@ bool LabEngine::saveGame(int slot, const Common::String desc) { for (int i = 0; i < _roomsFound->_lastElement / (8 * 2); i++) file->writeUint16LE(_roomsFound->_array[i]); - _tilePuzzle->save(file); + _specialLocks->save(file); // Breadcrumbs for (uint i = 0; i < MAX_CRUMBS; i++) { @@ -181,7 +181,7 @@ bool LabEngine::loadGame(int slot) { for (int i = 0; i < _roomsFound->_lastElement / (8 * 2); i++) _roomsFound->_array[i] = file->readUint16LE(); - _tilePuzzle->load(file); + _specialLocks->load(file); // Breadcrumbs for (int i = 0; i < MAX_CRUMBS; i++) { diff --git a/engines/lab/speciallocks.cpp b/engines/lab/speciallocks.cpp new file mode 100644 index 0000000000..fe70b0f111 --- /dev/null +++ b/engines/lab/speciallocks.cpp @@ -0,0 +1,394 @@ +/* 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. + * + */ + + /* + * This code is based on Labyrinth of Time code with assistance of + * + * Copyright (c) 1993 Terra Nova Development + * Copyright (c) 2004 The Wyrmkeep Entertainment Co. + * + */ + +#include "common/file.h" + +#include "gui/message.h" + +#include "lab/lab.h" +#include "lab/anim.h" +#include "lab/dispman.h" +#include "lab/image.h" +#include "lab/labsets.h" +#include "lab/resource.h" +#include "lab/speciallocks.h" +#include "lab/utils.h" + +namespace Lab { + +#define BRICKOPEN 115 +#define COMBINATIONUNLOCKED 130 + +enum TileScroll { + kScrollLeft = 1, + kScrollRight = 2, + kScrollUp = 3, + kScrollDown = 4 +}; + +const uint16 INIT_TILE[4][4] = { + { 1, 5, 9, 13 }, + { 2, 6, 10, 14 }, + { 3, 7, 11, 15 }, + { 4, 8, 12, 0 } +}; + +const uint16 SOLUTION[4][4] = { + { 7, 1, 8, 3 }, + { 2, 11, 15, 4 }, + { 9, 5, 14, 6 }, + { 10, 13, 12, 0 } +}; + +const int COMBINATION_X[6] = { 45, 83, 129, 166, 211, 248 }; + +SpecialLocks::SpecialLocks(LabEngine *vm) : _vm(vm) { + for (int i = 0; i < 16; i++) + _tiles[i] = nullptr; + + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) + _curTile[i][j] = INIT_TILE[i][j]; + } + + for (int i = 0; i < 6; i++) + _combination[i] = 0; + + for (int i = 0; i < 10; i++) + _numberImages[i] = nullptr; +} + +SpecialLocks::~SpecialLocks() { + for (int i = 0; i < 16; i++) + delete _tiles[i]; + + for (int imgIdx = 0; imgIdx < 10; imgIdx++) { + delete _numberImages[imgIdx]; + _numberImages[imgIdx] = nullptr; + } +} + +void SpecialLocks::tileClick(Common::Point pos) { + Common::Point realPos = _vm->_utils->vgaUnscale(pos); + + if ((realPos.x < 101) || (realPos.y < 26)) + return; + + int tileX = (realPos.x - 101) / 30; + int tileY = (realPos.y - 26) / 25; + + if ((tileX < 4) && (tileY < 4)) + changeTile(tileX, tileY); +} + +void SpecialLocks::changeTile(uint16 col, uint16 row) { + int16 scrolltype = -1; + + if (row > 0) { + if (_curTile[col][row - 1] == 0) { + _curTile[col][row - 1] = _curTile[col][row]; + _curTile[col][row] = 0; + scrolltype = kScrollDown; + } + } + + if (col > 0) { + if (_curTile[col - 1][row] == 0) { + _curTile[col - 1][row] = _curTile[col][row]; + _curTile[col][row] = 0; + scrolltype = kScrollRight; + } + } + + if (row < 3) { + if (_curTile[col][row + 1] == 0) { + _curTile[col][row + 1] = _curTile[col][row]; + _curTile[col][row] = 0; + scrolltype = kScrollUp; + } + } + + if (col < 3) { + if (_curTile[col + 1][row] == 0) { + _curTile[col + 1][row] = _curTile[col][row]; + _curTile[col][row] = 0; + scrolltype = kScrollLeft; + } + } + + if (scrolltype != -1) { + if (_vm->getFeatures() & GF_WINDOWS_TRIAL) { + GUI::MessageDialog trialMessage("This puzzle is not available in the trial version of the game"); + trialMessage.runModal(); + return; + } + + doTileScroll(col, row, scrolltype); + bool check = true; + row = 0; + col = 0; + + while (row < 4) { + while (col < 4) { + check &= (_curTile[row][col] == SOLUTION[row][col]); + col++; + } + + row++; + col = 0; + } + + if (check) { + // unlocked combination + _vm->_conditions->inclElement(BRICKOPEN); + _vm->_anim->_doBlack = true; + _vm->_graphics->readPict("p:Up/BDOpen"); + } + } +} + +void SpecialLocks::combinationClick(Common::Point pos) { + Common::Point realPos = _vm->_utils->vgaUnscale(pos); + + if (!Common::Rect(44, 63, 285, 99).contains(realPos)) + return; + + uint16 number = 0; + if (realPos.x < 83) + number = 0; + else if (realPos.x < 127) + number = 1; + else if (realPos.x < 165) + number = 2; + else if (realPos.x < 210) + number = 3; + else if (realPos.x < 245) + number = 4; + else if (realPos.x < 286) + number = 5; + + changeCombination(number); +} + +void SpecialLocks::doTile(bool showsolution) { + uint16 row = 0, col = 0, rowm, colm, num; + int16 rows, cols; + + if (showsolution) { + rowm = _vm->_utils->vgaScaleY(23); + colm = _vm->_utils->vgaScaleX(27); + + rows = _vm->_utils->vgaScaleY(31); + cols = _vm->_utils->vgaScaleX(105); + } else { + _vm->_graphics->rectFillScaled(97, 22, 220, 126, 0); + + rowm = _vm->_utils->vgaScaleY(25); + colm = _vm->_utils->vgaScaleX(30); + + rows = _vm->_utils->vgaScaleY(25); + cols = _vm->_utils->vgaScaleX(100); + } + + while (row < 4) { + while (col < 4) { + if (showsolution) + num = SOLUTION[col][row]; + else + num = _curTile[col][row]; + + if (showsolution || num) + _tiles[num]->drawImage(cols + (col * colm), rows + (row * rowm)); + + col++; + } + + row++; + col = 0; + } +} + +void SpecialLocks::showTileLock(const Common::String filename, bool showSolution) { + _vm->_anim->_doBlack = true; + _vm->_anim->_noPalChange = true; + _vm->_graphics->readPict(filename); + _vm->_anim->_noPalChange = false; + _vm->_graphics->blackScreen(); + + Common::File *tileFile = _vm->_resource->openDataFile(showSolution ? "P:TileSolution" : "P:Tile"); + + int start = showSolution ? 0 : 1; + + for (int curBit = start; curBit < 16; curBit++) + _tiles[curBit] = new Image(tileFile, _vm); + + delete tileFile; + + doTile(showSolution); + _vm->_graphics->setPalette(_vm->_anim->_diffPalette, 256); +} + +void SpecialLocks::doTileScroll(uint16 col, uint16 row, uint16 scrolltype) { + int16 dX = 0, dY = 0, dx = 0, dy = 0, sx = 0, sy = 0; + int last = 0; + + if (scrolltype == kScrollLeft) { + dX = _vm->_utils->vgaScaleX(5); + sx = _vm->_utils->vgaScaleX(5); + last = 6; + } else if (scrolltype == kScrollRight) { + dX = _vm->_utils->vgaScaleX(-5); + dx = _vm->_utils->vgaScaleX(-5); + sx = _vm->_utils->vgaScaleX(5); + last = 6; + } else if (scrolltype == kScrollUp) { + dY = _vm->_utils->vgaScaleY(5); + sy = _vm->_utils->vgaScaleY(5); + last = 5; + } else if (scrolltype == kScrollDown) { + dY = _vm->_utils->vgaScaleY(-5); + dy = _vm->_utils->vgaScaleY(-5); + sy = _vm->_utils->vgaScaleY(5); + last = 5; + } + + sx += _vm->_utils->svgaCord(2); + + uint16 x1 = _vm->_utils->vgaScaleX(100) + (col * _vm->_utils->vgaScaleX(30)) + dx; + uint16 y1 = _vm->_utils->vgaScaleY(25) + (row * _vm->_utils->vgaScaleY(25)) + dy; + + byte *buffer = new byte[_tiles[1]->_width * _tiles[1]->_height * 2]; + + for (int i = 0; i < last; i++) { + _vm->waitTOF(); + scrollRaster(dX, dY, x1, y1, x1 + _vm->_utils->vgaScaleX(28) + sx, y1 + _vm->_utils->vgaScaleY(23) + sy, buffer); + x1 += dX; + y1 += dY; + } + + delete[] buffer; +} + +void SpecialLocks::scrollRaster(int16 dx, int16 dy, uint16 x1, uint16 y1, uint16 x2, uint16 y2, byte *buffer) { + if (dx) + _vm->_graphics->scrollDisplayX(dx, x1, y1, x2, y2, buffer); + + if (dy) + _vm->_graphics->scrollDisplayY(dy, x1, y1, x2, y2, buffer); +} + +void SpecialLocks::changeCombination(uint16 number) { + const int solution[6] = { 0, 4, 0, 8, 7, 2 }; + + Image display(_vm); + + if (_combination[number] < 9) + (_combination[number])++; + else + _combination[number] = 0; + + uint16 combnum = _combination[number]; + + display.setData(_vm->_graphics->getCurrentDrawingBuffer(), false); + display._width = _vm->_graphics->_screenWidth; + display._height = _vm->_graphics->_screenHeight; + + byte *buffer = new byte[_numberImages[1]->_width * _numberImages[1]->_height * 2]; + + for (int i = 1; i <= (_numberImages[combnum]->_height / 2); i++) { + if (_vm->_isHiRes) { + if (i & 1) + _vm->waitTOF(); + } + else + _vm->waitTOF(); + + display.setData(_vm->_graphics->getCurrentDrawingBuffer(), false); + _vm->_graphics->scrollDisplayY(2, _vm->_utils->vgaScaleX(COMBINATION_X[number]), _vm->_utils->vgaScaleY(65), _vm->_utils->vgaScaleX(COMBINATION_X[number]) + (_numberImages[combnum])->_width - 1, _vm->_utils->vgaScaleY(65) + (_numberImages[combnum])->_height, buffer); + _numberImages[combnum]->blitBitmap(0, (_numberImages[combnum])->_height - (2 * i), &(display), _vm->_utils->vgaScaleX(COMBINATION_X[number]), _vm->_utils->vgaScaleY(65), (_numberImages[combnum])->_width, 2, false); + } + + delete[] buffer; + + bool unlocked = true; + for (int i = 0; i < 6; i++) + unlocked &= (_combination[i] == solution[i]); + + if (unlocked) + _vm->_conditions->inclElement(COMBINATIONUNLOCKED); + else + _vm->_conditions->exclElement(COMBINATIONUNLOCKED); +} + +void SpecialLocks::showCombinationLock(const Common::String filename) { + _vm->_anim->_doBlack = true; + _vm->_anim->_noPalChange = true; + _vm->_graphics->readPict(filename); + _vm->_anim->_noPalChange = false; + + _vm->_graphics->blackScreen(); + + Common::File *numFile = _vm->_resource->openDataFile("P:Numbers"); + + for (int i = 0; i < 10; i++) { + _numberImages[i] = new Image(numFile, _vm); + } + + delete numFile; + + for (int i = 0; i <= 5; i++) + _numberImages[_combination[i]]->drawImage(_vm->_utils->vgaScaleX(COMBINATION_X[i]), _vm->_utils->vgaScaleY(65)); + + _vm->_graphics->setPalette(_vm->_anim->_diffPalette, 256); +} + +void SpecialLocks::save(Common::OutSaveFile *file) { + // Combination lock + for (int i = 0; i < 6; i++) + file->writeByte(_combination[i]); + + // Tiles + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + file->writeUint16LE(_curTile[i][j]); +} + +void SpecialLocks::load(Common::InSaveFile *file) { + // Combination lock + for (int i = 0; i < 6; i++) + _combination[i] = file->readByte(); + + // Tiles + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + _curTile[i][j] = file->readUint16LE(); +} + +} // End of namespace Lab diff --git a/engines/lab/speciallocks.h b/engines/lab/speciallocks.h new file mode 100644 index 0000000000..424eba242a --- /dev/null +++ b/engines/lab/speciallocks.h @@ -0,0 +1,94 @@ +/* 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. + * + */ + +/* + * This code is based on Labyrinth of Time code with assistance of + * + * Copyright (c) 1993 Terra Nova Development + * Copyright (c) 2004 The Wyrmkeep Entertainment Co. + * + */ + +#ifndef LAB_TILEPUZZLE_H +#define LAB_TILEPUZZLE_H + +#include "common/savefile.h" + +namespace Lab { + +class LabEngine; + +class SpecialLocks { +private: + LabEngine *_vm; + Image *_tiles[16]; + Image *_numberImages[10]; + uint16 _curTile[4][4]; + byte _combination[6]; + +public: + SpecialLocks(LabEngine *vm); + ~SpecialLocks(); + + void showTileLock(const Common::String filename, bool showSolution); + + /** + * Processes mouse clicks and changes tile positions. + */ + void tileClick(Common::Point pos); + + void showCombinationLock(const Common::String filename); + + /** + * Processes mouse clicks and changes the door combination. + */ + void combinationClick(Common::Point pos); + + void save(Common::OutSaveFile *file); + void load(Common::InSaveFile *file); + +private: + /** + * Changes the combination number of one of the slots + */ + void changeCombination(uint16 number); + + /** + * Changes the tile positions in the tile puzzle + */ + void changeTile(uint16 col, uint16 row); + + /** + * Draws the images of the combination lock to the display bitmap. + */ + void doTile(bool showsolution); + + /** + * Does the scrolling for the tiles on the tile puzzle. + */ + void doTileScroll(uint16 col, uint16 row, uint16 scrolltype); + void scrollRaster(int16 dx, int16 dy, uint16 x1, uint16 y1, uint16 x2, uint16 y2, byte *buffer); +}; + +} // End of namespace Lab + +#endif // LAB_TILEPUZZLE_H diff --git a/engines/lab/tilepuzzle.cpp b/engines/lab/tilepuzzle.cpp deleted file mode 100644 index fe37ee4d9e..0000000000 --- a/engines/lab/tilepuzzle.cpp +++ /dev/null @@ -1,396 +0,0 @@ -/* 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. - * - */ - - /* - * This code is based on Labyrinth of Time code with assistance of - * - * Copyright (c) 1993 Terra Nova Development - * Copyright (c) 2004 The Wyrmkeep Entertainment Co. - * - */ - -#include "common/file.h" - -#include "gui/message.h" - -#include "lab/lab.h" -#include "lab/anim.h" -#include "lab/dispman.h" -#include "lab/image.h" -#include "lab/labsets.h" -#include "lab/resource.h" -#include "lab/tilepuzzle.h" -#include "lab/utils.h" - -namespace Lab { - -#define BRICKOPEN 115 -#define COMBINATIONUNLOCKED 130 - -enum TileScroll { - kScrollLeft = 1, - kScrollRight = 2, - kScrollUp = 3, - kScrollDown = 4 -}; - -const uint16 INIT_TILE[4][4] = { - { 1, 5, 9, 13 }, - { 2, 6, 10, 14 }, - { 3, 7, 11, 15 }, - { 4, 8, 12, 0 } -}; - -const uint16 SOLUTION[4][4] = { - { 7, 1, 8, 3 }, - { 2, 11, 15, 4 }, - { 9, 5, 14, 6 }, - { 10, 13, 12, 0 } -}; - -const int COMBINATION_X[6] = { 45, 83, 129, 166, 211, 248 }; - -TilePuzzle::TilePuzzle(LabEngine *vm) : _vm(vm) { - for (int i = 0; i < 16; i++) - _tiles[i] = nullptr; - - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) - _curTile[i][j] = INIT_TILE[i][j]; - } - - for (int i = 0; i < 6; i++) - _combination[i] = 0; - - for (int i = 0; i < 10; i++) - _numberImages[i] = nullptr; -} - -TilePuzzle::~TilePuzzle() { - for (int i = 0; i < 16; i++) - delete _tiles[i]; - - for (int imgIdx = 0; imgIdx < 10; imgIdx++) { - delete _numberImages[imgIdx]; - _numberImages[imgIdx] = nullptr; - } -} - -void TilePuzzle::mouseTile(Common::Point pos) { - Common::Point realPos = _vm->_utils->vgaUnscale(pos); - - if ((realPos.x < 101) || (realPos.y < 26)) - return; - - int tileX = (realPos.x - 101) / 30; - int tileY = (realPos.y - 26) / 25; - - if ((tileX < 4) && (tileY < 4)) - changeTile(tileX, tileY); -} - -void TilePuzzle::changeTile(uint16 col, uint16 row) { - int16 scrolltype = -1; - - if (row > 0) { - if (_curTile[col][row - 1] == 0) { - _curTile[col][row - 1] = _curTile[col][row]; - _curTile[col][row] = 0; - scrolltype = kScrollDown; - } - } - - if (col > 0) { - if (_curTile[col - 1][row] == 0) { - _curTile[col - 1][row] = _curTile[col][row]; - _curTile[col][row] = 0; - scrolltype = kScrollRight; - } - } - - if (row < 3) { - if (_curTile[col][row + 1] == 0) { - _curTile[col][row + 1] = _curTile[col][row]; - _curTile[col][row] = 0; - scrolltype = kScrollUp; - } - } - - if (col < 3) { - if (_curTile[col + 1][row] == 0) { - _curTile[col + 1][row] = _curTile[col][row]; - _curTile[col][row] = 0; - scrolltype = kScrollLeft; - } - } - - if (scrolltype != -1) { - if (_vm->getFeatures() & GF_WINDOWS_TRIAL) { - GUI::MessageDialog trialMessage("This puzzle is not available in the trial version of the game"); - trialMessage.runModal(); - return; - } - - doTileScroll(col, row, scrolltype); - bool check = true; - row = 0; - col = 0; - - while (row < 4) { - while (col < 4) { - check &= (_curTile[row][col] == SOLUTION[row][col]); - col++; - } - - row++; - col = 0; - } - - if (check) { - // unlocked combination - _vm->_conditions->inclElement(BRICKOPEN); - _vm->_anim->_doBlack = true; - _vm->_graphics->readPict("p:Up/BDOpen"); - } - } -} - -void TilePuzzle::mouseCombination(Common::Point pos) { - Common::Point realPos = _vm->_utils->vgaUnscale(pos); - - if (!Common::Rect(44, 63, 285, 99).contains(realPos)) - return; - - uint16 number = 0; - if (realPos.x < 83) - number = 0; - else if (realPos.x < 127) - number = 1; - else if (realPos.x < 165) - number = 2; - else if (realPos.x < 210) - number = 3; - else if (realPos.x < 245) - number = 4; - else if (realPos.x < 286) - number = 5; - - changeCombination(number); -} - -void TilePuzzle::doTile(bool showsolution) { - uint16 row = 0, col = 0, rowm, colm, num; - int16 rows, cols; - - if (showsolution) { - rowm = _vm->_utils->vgaScaleY(23); - colm = _vm->_utils->vgaScaleX(27); - - rows = _vm->_utils->vgaScaleY(31); - cols = _vm->_utils->vgaScaleX(105); - } else { - _vm->_graphics->rectFillScaled(97, 22, 220, 126, 0); - - rowm = _vm->_utils->vgaScaleY(25); - colm = _vm->_utils->vgaScaleX(30); - - rows = _vm->_utils->vgaScaleY(25); - cols = _vm->_utils->vgaScaleX(100); - } - - while (row < 4) { - while (col < 4) { - if (showsolution) - num = SOLUTION[col][row]; - else - num = _curTile[col][row]; - - if (showsolution || num) - _tiles[num]->drawImage(cols + (col * colm), rows + (row * rowm)); - - col++; - } - - row++; - col = 0; - } -} - -void TilePuzzle::showTile(const Common::String filename, bool showSolution) { - _vm->_anim->_doBlack = true; - _vm->_anim->_noPalChange = true; - _vm->_graphics->readPict(filename); - _vm->_anim->_noPalChange = false; - _vm->_graphics->blackScreen(); - - Common::File *tileFile = _vm->_resource->openDataFile(showSolution ? "P:TileSolution" : "P:Tile"); - - int start = showSolution ? 0 : 1; - - for (int curBit = start; curBit < 16; curBit++) - _tiles[curBit] = new Image(tileFile, _vm); - - delete tileFile; - - doTile(showSolution); - _vm->_graphics->setPalette(_vm->_anim->_diffPalette, 256); -} - -void TilePuzzle::doTileScroll(uint16 col, uint16 row, uint16 scrolltype) { - int16 dX = 0, dY = 0, dx = 0, dy = 0, sx = 0, sy = 0; - int last = 0; - - if (scrolltype == kScrollLeft) { - dX = _vm->_utils->vgaScaleX(5); - sx = _vm->_utils->vgaScaleX(5); - last = 6; - } else if (scrolltype == kScrollRight) { - dX = _vm->_utils->vgaScaleX(-5); - dx = _vm->_utils->vgaScaleX(-5); - sx = _vm->_utils->vgaScaleX(5); - last = 6; - } else if (scrolltype == kScrollUp) { - dY = _vm->_utils->vgaScaleY(5); - sy = _vm->_utils->vgaScaleY(5); - last = 5; - } else if (scrolltype == kScrollDown) { - dY = _vm->_utils->vgaScaleY(-5); - dy = _vm->_utils->vgaScaleY(-5); - sy = _vm->_utils->vgaScaleY(5); - last = 5; - } - - sx += _vm->_utils->svgaCord(2); - - uint16 x1 = _vm->_utils->vgaScaleX(100) + (col * _vm->_utils->vgaScaleX(30)) + dx; - uint16 y1 = _vm->_utils->vgaScaleY(25) + (row * _vm->_utils->vgaScaleY(25)) + dy; - - byte *buffer = new byte[_tiles[1]->_width * _tiles[1]->_height * 2]; - - for (int i = 0; i < last; i++) { - _vm->waitTOF(); - scrollRaster(dX, dY, x1, y1, x1 + _vm->_utils->vgaScaleX(28) + sx, y1 + _vm->_utils->vgaScaleY(23) + sy, buffer); - x1 += dX; - y1 += dY; - } - - delete[] buffer; -} - -void TilePuzzle::changeCombination(uint16 number) { - const int solution[6] = { 0, 4, 0, 8, 7, 2 }; - - Image display(_vm); - - if (_combination[number] < 9) - (_combination[number])++; - else - _combination[number] = 0; - - uint16 combnum = _combination[number]; - - display.setData(_vm->_graphics->getCurrentDrawingBuffer(), false); - display._width = _vm->_graphics->_screenWidth; - display._height = _vm->_graphics->_screenHeight; - - byte *buffer = new byte[_numberImages[1]->_width * _numberImages[1]->_height * 2]; - - for (int i = 1; i <= (_numberImages[combnum]->_height / 2); i++) { - if (_vm->_isHiRes) { - if (i & 1) - _vm->waitTOF(); - } else - _vm->waitTOF(); - - display.setData(_vm->_graphics->getCurrentDrawingBuffer(), false); - _vm->_graphics->scrollDisplayY(2, _vm->_utils->vgaScaleX(COMBINATION_X[number]), _vm->_utils->vgaScaleY(65), _vm->_utils->vgaScaleX(COMBINATION_X[number]) + (_numberImages[combnum])->_width - 1, _vm->_utils->vgaScaleY(65) + (_numberImages[combnum])->_height, buffer); - _numberImages[combnum]->blitBitmap(0, (_numberImages[combnum])->_height - (2 * i), &(display), _vm->_utils->vgaScaleX(COMBINATION_X[number]), _vm->_utils->vgaScaleY(65), (_numberImages[combnum])->_width, 2, false); - } - - delete[] buffer; - - bool unlocked = true; - for (int i = 0; i < 6; i++) - unlocked &= (_combination[i] == solution[i]); - - if (unlocked) - _vm->_conditions->inclElement(COMBINATIONUNLOCKED); - else - _vm->_conditions->exclElement(COMBINATIONUNLOCKED); -} - -void TilePuzzle::scrollRaster(int16 dx, int16 dy, uint16 x1, uint16 y1, uint16 x2, uint16 y2, byte *buffer) { - if (dx) - _vm->_graphics->scrollDisplayX(dx, x1, y1, x2, y2, buffer); - - if (dy) - _vm->_graphics->scrollDisplayY(dy, x1, y1, x2, y2, buffer); -} - -void TilePuzzle::doCombination() { - for (int i = 0; i <= 5; i++) - _numberImages[_combination[i]]->drawImage(_vm->_utils->vgaScaleX(COMBINATION_X[i]), _vm->_utils->vgaScaleY(65)); -} - -void TilePuzzle::showCombination(const Common::String filename) { - _vm->_anim->_doBlack = true; - _vm->_anim->_noPalChange = true; - _vm->_graphics->readPict(filename); - _vm->_anim->_noPalChange = false; - - _vm->_graphics->blackScreen(); - - Common::File *numFile = _vm->_resource->openDataFile("P:Numbers"); - - for (int CurBit = 0; CurBit < 10; CurBit++) - _numberImages[CurBit] = new Image(numFile, _vm); - - delete numFile; - - doCombination(); - - _vm->_graphics->setPalette(_vm->_anim->_diffPalette, 256); -} - -void TilePuzzle::save(Common::OutSaveFile *file) { - // Combination lock and tile stuff - for (int i = 0; i < 6; i++) - file->writeByte(_combination[i]); - - // Tiles - for (int i = 0; i < 4; i++) - for (int j = 0; j < 4; j++) - file->writeUint16LE(_curTile[i][j]); -} - -void TilePuzzle::load(Common::InSaveFile *file) { - // Combination lock and tile stuff - for (int i = 0; i < 6; i++) - _combination[i] = file->readByte(); - - // Tiles - for (int i = 0; i < 4; i++) - for (int j = 0; j < 4; j++) - _curTile[i][j] = file->readUint16LE(); -} - -} // End of namespace Lab diff --git a/engines/lab/tilepuzzle.h b/engines/lab/tilepuzzle.h deleted file mode 100644 index 948df9ddcd..0000000000 --- a/engines/lab/tilepuzzle.h +++ /dev/null @@ -1,104 +0,0 @@ -/* 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. - * - */ - -/* - * This code is based on Labyrinth of Time code with assistance of - * - * Copyright (c) 1993 Terra Nova Development - * Copyright (c) 2004 The Wyrmkeep Entertainment Co. - * - */ - -#ifndef LAB_TILEPUZZLE_H -#define LAB_TILEPUZZLE_H - -#include "common/savefile.h" - -namespace Lab { - -class LabEngine; - -class TilePuzzle { -private: - LabEngine *_vm; - Image *_tiles[16]; - Image *_numberImages[10]; - uint16 _curTile[4][4]; - byte _combination[6]; - -public: - TilePuzzle(LabEngine *vm); - ~TilePuzzle(); - - /** - * Processes mouse clicks and changes the combination. - */ - void mouseTile(Common::Point pos); - - /** - * Processes mouse clicks and changes the combination. - */ - void mouseCombination(Common::Point pos); - - /** - * Reads in a backdrop picture. - */ - void showCombination(const Common::String filename); - - /** - * Reads in a backdrop picture. - */ - void showTile(const Common::String filename, bool showSolution); - void save(Common::OutSaveFile *file); - void load(Common::InSaveFile *file); - -private: - /** - * Changes the combination number of one of the slots - */ - void changeCombination(uint16 number); - - /** - * Changes the combination number of one of the slots - */ - void changeTile(uint16 col, uint16 row); - - /** - * Draws the images of the combination lock to the display bitmap. - */ - void doCombination(); - - /** - * Draws the images of the combination lock to the display bitmap. - */ - void doTile(bool showsolution); - - /** - * Does the scrolling for the tiles on the tile puzzle. - */ - void doTileScroll(uint16 col, uint16 row, uint16 scrolltype); - void scrollRaster(int16 dx, int16 dy, uint16 x1, uint16 y1, uint16 x2, uint16 y2, byte *buffer); -}; - -} // End of namespace Lab - -#endif // LAB_TILEPUZZLE_H -- cgit v1.2.3