2014-10-06 14:50:05 +02:00
|
|
|
/* 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.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2015-02-19 15:41:15 +02:00
|
|
|
#include "common/translation.h"
|
|
|
|
|
|
|
|
#include "gui/message.h"
|
|
|
|
#include "gui/saveload.h"
|
|
|
|
|
2014-12-25 19:13:52 +01:00
|
|
|
#include "lab/lab.h"
|
2014-10-06 14:50:05 +02:00
|
|
|
#include "lab/labfun.h"
|
|
|
|
#include "lab/parsefun.h"
|
|
|
|
#include "lab/interface.h"
|
|
|
|
#include "lab/diff.h"
|
|
|
|
#include "lab/text.h"
|
|
|
|
#include "lab/mouse.h"
|
|
|
|
#include "lab/parsetypes.h"
|
2015-10-08 06:15:36 +03:00
|
|
|
#include "lab/resource.h"
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
namespace Lab {
|
|
|
|
|
2015-07-21 22:09:00 +03:00
|
|
|
static uint16 MonGadHeight = 1;
|
|
|
|
static uint16 hipal[20];
|
2014-10-06 14:50:05 +02:00
|
|
|
|
2015-07-21 22:09:00 +03:00
|
|
|
// Combination lock rules
|
|
|
|
static Image *Images[10];
|
|
|
|
byte combination[6] = { 0, 0, 0, 0, 0, 0 }, solution[] = { 0, 4, 0, 8, 7, 2 };
|
|
|
|
static uint16 combx[] = { 45, 83, 129, 166, 211, 248 };
|
2014-10-06 14:50:05 +02:00
|
|
|
|
2015-12-01 02:05:29 +02:00
|
|
|
static TextFont *journalFont;
|
2015-07-21 22:09:00 +03:00
|
|
|
static char *journaltext, *journaltexttitle;
|
|
|
|
static uint16 JPage = 0;
|
|
|
|
static bool lastpage = false;
|
2015-10-12 17:13:42 +03:00
|
|
|
static Image JBackImage, ScreenImage;
|
2015-07-21 22:09:00 +03:00
|
|
|
static uint16 JGadX[3] = { 80, 144, 194 }, JGadY[3] = { 162, 164, 162 };
|
|
|
|
static Gadget ForwardG, CancelG, BackG;
|
|
|
|
static bool GotBackImage = false;
|
2015-10-16 01:52:53 +03:00
|
|
|
static uint16 monitorPage;
|
2015-07-21 22:09:00 +03:00
|
|
|
static const char *TextFileName;
|
2014-10-06 14:50:05 +02:00
|
|
|
|
2015-07-21 22:09:00 +03:00
|
|
|
Image *MonButton, *AltMonButton, *MonQuit, *AltMonQuit, *MonBack, *AltMonBack,
|
|
|
|
*MonDown, *AltMonDown, *MonUp, *AltMonUp;
|
2014-10-06 14:50:05 +02:00
|
|
|
|
2015-07-21 22:09:00 +03:00
|
|
|
// Tile puzzle rules
|
|
|
|
Image *Tiles[16];
|
|
|
|
uint16 CurTile[4][4] = {
|
|
|
|
{ 1, 5, 9, 13 },
|
|
|
|
{ 2, 6, 10, 14 },
|
|
|
|
{ 3, 7, 11, 15 },
|
|
|
|
{ 4, 8, 12, 0 }
|
|
|
|
}, TileSolution[4][4] = {
|
|
|
|
{ 7, 1, 8, 3 },
|
|
|
|
{ 2, 11, 15, 4 },
|
|
|
|
{ 9, 5, 14, 6 },
|
|
|
|
{ 10, 13, 12, 0 }
|
|
|
|
};
|
2014-10-06 14:50:05 +02:00
|
|
|
|
2015-07-21 22:09:00 +03:00
|
|
|
extern TextFont *MsgFont;
|
2014-10-06 14:50:05 +02:00
|
|
|
extern uint16 *FadePalette;
|
2015-11-30 00:12:01 +01:00
|
|
|
extern bool nopalchange, DoBlack;
|
2015-07-21 22:09:00 +03:00
|
|
|
extern BitMap *DispBitMap, *DrawBitMap;
|
|
|
|
extern char diffcmap[3 * 256];
|
|
|
|
extern CloseDataPtr CPtr;
|
|
|
|
extern InventoryData *Inventory;
|
2015-11-30 01:42:12 +01:00
|
|
|
extern uint16 Direction;
|
2014-10-06 14:50:05 +02:00
|
|
|
|
2015-07-21 22:09:00 +03:00
|
|
|
#define COMBINATIONUNLOCKED 130
|
|
|
|
#define BRICKOPEN 115
|
2014-12-22 10:03:05 +01:00
|
|
|
#define INCL(BITSET,BIT) ((BITSET) |= (BIT))
|
|
|
|
#define SETBIT(BITSET,BITNUM) INCL(BITSET, (1 << (BITNUM)))
|
|
|
|
#define INBIT(BITSET,BITNUM) ( ((1 << (BITNUM)) & (BITSET)) > 0 )
|
2015-07-21 22:09:00 +03:00
|
|
|
#define LEFTSCROLL 1
|
|
|
|
#define RIGHTSCROLL 2
|
|
|
|
#define UPSCROLL 3
|
|
|
|
#define DOWNSCROLL 4
|
|
|
|
#define BRIDGE0 148
|
|
|
|
#define BRIDGE1 104
|
|
|
|
#define DIRTY 175
|
|
|
|
#define NONEWS 135
|
|
|
|
#define NOCLEAN 152
|
|
|
|
#define QUARTERNUM 30
|
2014-12-22 10:03:05 +01:00
|
|
|
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
static byte *loadBackPict(const char *fileName, bool tomem) {
|
|
|
|
byte *res = NULL;
|
|
|
|
|
|
|
|
FadePalette = hipal;
|
|
|
|
nopalchange = true;
|
|
|
|
|
|
|
|
if (tomem)
|
2015-11-23 17:34:02 +01:00
|
|
|
res = readPictToMem(fileName, g_lab->_screenWidth, g_lab->_screenHeight);
|
2014-10-06 14:50:05 +02:00
|
|
|
else
|
|
|
|
readPict(fileName, true);
|
|
|
|
|
2015-11-27 23:18:15 +01:00
|
|
|
for (uint16 i = 0; i < 16; i++) {
|
|
|
|
hipal[i] = ((diffcmap[i * 3] >> 2) << 8) +
|
|
|
|
((diffcmap[i * 3 + 1] >> 2) << 4) +
|
|
|
|
((diffcmap[i * 3 + 2] >> 2));
|
2014-10-06 14:50:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
nopalchange = false;
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* Draws the images of the combination lock to the display bitmap. */
|
|
|
|
/*****************************************************************************/
|
2015-02-24 00:31:26 +02:00
|
|
|
static void doCombination() {
|
2015-11-27 23:18:15 +01:00
|
|
|
for (uint16 i = 0; i <= 5; i++)
|
|
|
|
g_lab->drawImage(Images[combination[i]], VGAScaleX(combx[i]), VGAScaleY(65));
|
2014-10-06 14:50:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* Reads in a backdrop picture. */
|
|
|
|
/*****************************************************************************/
|
|
|
|
void showCombination(const char *filename) {
|
|
|
|
byte **buffer;
|
|
|
|
|
|
|
|
resetBuffer();
|
|
|
|
DoBlack = true;
|
|
|
|
nopalchange = true;
|
|
|
|
readPict(filename, true);
|
|
|
|
nopalchange = false;
|
|
|
|
|
|
|
|
blackScreen();
|
|
|
|
|
2015-11-30 01:17:05 +01:00
|
|
|
buffer = g_lab->_music->newOpen("P:Numbers");
|
2014-10-06 14:50:05 +02:00
|
|
|
|
2015-11-27 23:18:15 +01:00
|
|
|
for (uint16 CurBit = 0; CurBit < 10; CurBit++)
|
2014-10-06 14:50:05 +02:00
|
|
|
readImage(buffer, &(Images[CurBit]));
|
|
|
|
|
2015-11-24 23:59:30 +01:00
|
|
|
allocFile((void **)&g_lab->_tempScrollData, Images[0]->Width * Images[0]->Height * 2L, "tempdata");
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
doCombination();
|
|
|
|
|
2015-11-30 20:07:23 +01:00
|
|
|
g_lab->setPalette(diffcmap, 256);
|
2014-10-06 14:50:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* Changes the combination number of one of the slots */
|
|
|
|
/*****************************************************************************/
|
2014-12-25 19:13:52 +01:00
|
|
|
static void changeCombination(uint16 number) {
|
2014-12-26 00:32:42 +01:00
|
|
|
Image display;
|
2015-11-27 23:18:15 +01:00
|
|
|
uint16 combnum;
|
2014-10-06 14:50:05 +02:00
|
|
|
bool unlocked = true;
|
|
|
|
|
|
|
|
if (combination[number] < 9)
|
|
|
|
(combination[number])++;
|
|
|
|
else
|
|
|
|
combination[number] = 0;
|
|
|
|
|
|
|
|
combnum = combination[number];
|
|
|
|
|
2015-12-01 10:35:31 +01:00
|
|
|
display.ImageData = g_lab->getCurrentDrawingBuffer();
|
2015-11-23 17:34:02 +01:00
|
|
|
display.Width = g_lab->_screenWidth;
|
|
|
|
display.Height = g_lab->_screenHeight;
|
2014-10-06 14:50:05 +02:00
|
|
|
|
2015-11-27 23:18:15 +01:00
|
|
|
for (uint16 i = 1; i <= (Images[combnum]->Height / 2); i++) {
|
2015-11-30 00:12:01 +01:00
|
|
|
if (g_lab->_isHiRes) {
|
2015-11-27 23:18:15 +01:00
|
|
|
if (i & 1)
|
2015-11-24 23:59:30 +01:00
|
|
|
g_lab->waitTOF();
|
2014-10-06 14:50:05 +02:00
|
|
|
} else
|
2015-11-24 23:59:30 +01:00
|
|
|
g_lab->waitTOF();
|
2014-10-06 14:50:05 +02:00
|
|
|
|
2015-12-01 10:35:31 +01:00
|
|
|
display.ImageData = g_lab->getCurrentDrawingBuffer();
|
2014-10-06 14:50:05 +02:00
|
|
|
|
2015-11-24 23:59:30 +01:00
|
|
|
g_lab->scrollDisplayY(2, VGAScaleX(combx[number]), VGAScaleY(65), VGAScaleX(combx[number]) + (Images[combnum])->Width - 1, VGAScaleY(65) + (Images[combnum])->Height);
|
2014-10-06 14:50:05 +02:00
|
|
|
|
2015-11-27 23:18:15 +01:00
|
|
|
g_lab->bltBitMap(Images[combnum], 0, (Images[combnum])->Height - (2 * i), &(display), VGAScaleX(combx[number]), VGAScaleY(65), (Images[combnum])->Width, 2);
|
2014-10-06 14:50:05 +02:00
|
|
|
}
|
|
|
|
|
2015-11-27 23:18:15 +01:00
|
|
|
for (uint16 i = 0; i < 6; i++)
|
|
|
|
unlocked = (combination[i] == solution[i]) && unlocked;
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
if (unlocked)
|
2014-12-25 19:13:52 +01:00
|
|
|
g_lab->_conditions->inclElement(COMBINATIONUNLOCKED);
|
2014-10-06 14:50:05 +02:00
|
|
|
else
|
2014-12-25 19:13:52 +01:00
|
|
|
g_lab->_conditions->exclElement(COMBINATIONUNLOCKED);
|
2014-10-06 14:50:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* Processes mouse clicks and changes the combination. */
|
|
|
|
/*****************************************************************************/
|
2015-11-28 02:17:05 +01:00
|
|
|
void mouseCombination(Common::Point pos) {
|
2014-10-06 14:50:05 +02:00
|
|
|
uint16 number;
|
|
|
|
|
2015-11-28 02:17:05 +01:00
|
|
|
int x = VGAUnScaleX(pos.x);
|
|
|
|
int y = VGAUnScaleY(pos.y);
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
if ((y >= 63) && (y <= 99)) {
|
|
|
|
if ((x >= 44) && (x < 83))
|
|
|
|
number = 0;
|
|
|
|
else if (x < 127)
|
|
|
|
number = 1;
|
|
|
|
else if (x < 165)
|
|
|
|
number = 2;
|
|
|
|
else if (x < 210)
|
|
|
|
number = 3;
|
|
|
|
else if (x < 245)
|
|
|
|
number = 4;
|
|
|
|
else if (x < 286)
|
|
|
|
number = 5;
|
|
|
|
else
|
|
|
|
return;
|
|
|
|
|
2014-12-25 19:13:52 +01:00
|
|
|
changeCombination(number);
|
2014-10-06 14:50:05 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* Draws the images of the combination lock to the display bitmap. */
|
|
|
|
/*****************************************************************************/
|
|
|
|
static void doTile(bool showsolution) {
|
|
|
|
uint16 row = 0, col = 0, rowm, colm, num;
|
|
|
|
int16 rows, cols;
|
|
|
|
|
|
|
|
if (showsolution) {
|
|
|
|
rowm = VGAScaleY(23);
|
|
|
|
colm = VGAScaleX(27);
|
|
|
|
|
|
|
|
rows = VGAScaleY(31);
|
|
|
|
cols = VGAScaleX(105);
|
|
|
|
} else {
|
2015-11-24 23:59:30 +01:00
|
|
|
g_lab->setAPen(0);
|
|
|
|
g_lab->rectFill(VGAScaleX(97), VGAScaleY(22), VGAScaleX(220), VGAScaleY(126));
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
rowm = VGAScaleY(25);
|
|
|
|
colm = VGAScaleX(30);
|
|
|
|
|
|
|
|
rows = VGAScaleY(25);
|
|
|
|
cols = VGAScaleX(100);
|
|
|
|
}
|
|
|
|
|
|
|
|
while (row < 4) {
|
|
|
|
while (col < 4) {
|
|
|
|
if (showsolution)
|
|
|
|
num = TileSolution[col] [row];
|
|
|
|
else
|
|
|
|
num = CurTile[col] [row];
|
|
|
|
|
|
|
|
if (showsolution || num)
|
2015-11-24 23:59:30 +01:00
|
|
|
g_lab->drawImage(Tiles[num], cols + (col * colm), rows + (row * rowm));
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
col++;
|
|
|
|
}
|
|
|
|
|
|
|
|
row++;
|
|
|
|
col = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* Reads in a backdrop picture. */
|
|
|
|
/*****************************************************************************/
|
|
|
|
void showTile(const char *filename, bool showsolution) {
|
2015-11-27 23:18:15 +01:00
|
|
|
uint16 start;
|
2014-10-06 14:50:05 +02:00
|
|
|
byte **buffer;
|
|
|
|
|
|
|
|
resetBuffer();
|
|
|
|
DoBlack = true;
|
|
|
|
nopalchange = true;
|
|
|
|
readPict(filename, true);
|
|
|
|
nopalchange = false;
|
|
|
|
blackScreen();
|
|
|
|
|
|
|
|
if (showsolution) {
|
|
|
|
start = 0;
|
2015-11-30 01:17:05 +01:00
|
|
|
buffer = g_lab->_music->newOpen("P:TileSolution");
|
2014-10-06 14:50:05 +02:00
|
|
|
} else {
|
|
|
|
start = 1;
|
2015-11-30 01:17:05 +01:00
|
|
|
buffer = g_lab->_music->newOpen("P:Tile");
|
2014-10-06 14:50:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!buffer)
|
|
|
|
return;
|
|
|
|
|
2015-11-27 23:18:15 +01:00
|
|
|
for (uint16 curBit = start; curBit < 16; curBit++)
|
|
|
|
readImage(buffer, &(Tiles[curBit]));
|
2014-10-06 14:50:05 +02:00
|
|
|
|
2015-11-24 23:59:30 +01:00
|
|
|
allocFile((void **)&g_lab->_tempScrollData, Tiles[1]->Width * Tiles[1]->Height * 2L, "tempdata");
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
doTile(showsolution);
|
|
|
|
|
2015-11-30 20:07:23 +01:00
|
|
|
g_lab->setPalette(diffcmap, 256);
|
2014-10-06 14:50:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void scrollRaster(int16 dx, int16 dy, uint16 x1, uint16 y1, uint16 x2, uint16 y2) {
|
|
|
|
if (dx)
|
2015-11-24 23:59:30 +01:00
|
|
|
g_lab->scrollDisplayX(dx, x1, y1, x2, y2);
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
if (dy)
|
2015-11-24 23:59:30 +01:00
|
|
|
g_lab->scrollDisplayY(dy, x1, y1, x2, y2);
|
2014-10-06 14:50:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* Does the scrolling for the tiles on the tile puzzle. */
|
|
|
|
/*****************************************************************************/
|
|
|
|
static void doTileScroll(uint16 col, uint16 row, uint16 scrolltype) {
|
|
|
|
int16 dX = 0, dY = 0, dx = 0, dy = 0, sx = 0, sy = 0;
|
|
|
|
uint16 last = 0, x1, y1;
|
|
|
|
|
|
|
|
if (scrolltype == LEFTSCROLL) {
|
2015-07-17 10:50:04 +03:00
|
|
|
dX = VGAScaleX(5);
|
|
|
|
sx = VGAScaleX(5);
|
2014-10-06 14:50:05 +02:00
|
|
|
last = 6;
|
|
|
|
} else if (scrolltype == RIGHTSCROLL) {
|
2015-07-17 10:50:04 +03:00
|
|
|
dX = VGAScaleX(-5);
|
|
|
|
dx = VGAScaleX(-5);
|
2014-10-06 14:50:05 +02:00
|
|
|
sx = VGAScaleX(5);
|
|
|
|
last = 6;
|
|
|
|
} else if (scrolltype == UPSCROLL) {
|
2015-07-17 10:50:04 +03:00
|
|
|
dY = VGAScaleY(5);
|
|
|
|
sy = VGAScaleY(5);
|
2014-10-06 14:50:05 +02:00
|
|
|
last = 5;
|
|
|
|
} else if (scrolltype == DOWNSCROLL) {
|
2015-07-17 10:50:04 +03:00
|
|
|
dY = VGAScaleY(-5);
|
|
|
|
dy = VGAScaleY(-5);
|
|
|
|
sy = VGAScaleY(5);
|
2014-10-06 14:50:05 +02:00
|
|
|
last = 5;
|
|
|
|
}
|
|
|
|
|
|
|
|
sx += SVGACord(2);
|
|
|
|
|
|
|
|
x1 = VGAScaleX(100) + (col * VGAScaleX(30)) + dx;
|
|
|
|
y1 = VGAScaleY(25) + (row * VGAScaleY(25)) + dy;
|
|
|
|
|
2015-11-27 23:18:15 +01:00
|
|
|
for (uint16 i = 0; i < last; i++) {
|
2015-11-24 23:59:30 +01:00
|
|
|
g_lab->waitTOF();
|
2014-10-06 14:50:05 +02:00
|
|
|
scrollRaster(dX, dY, x1, y1, x1 + VGAScaleX(28) + sx, y1 + VGAScaleY(23) + sy);
|
|
|
|
x1 += dX;
|
|
|
|
y1 += dY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* Changes the combination number of one of the slots */
|
|
|
|
/*****************************************************************************/
|
2014-12-25 19:13:52 +01:00
|
|
|
static void changeTile(uint16 col, uint16 row) {
|
2014-10-06 14:50:05 +02:00
|
|
|
int16 scrolltype = -1;
|
|
|
|
|
|
|
|
if (row > 0) {
|
|
|
|
if (CurTile[col] [row - 1] == 0) {
|
|
|
|
CurTile[col] [row - 1] = CurTile[col] [row];
|
|
|
|
CurTile[col] [row] = 0;
|
|
|
|
scrolltype = DOWNSCROLL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (col > 0) {
|
|
|
|
if (CurTile[col - 1] [row] == 0) {
|
|
|
|
CurTile[col - 1] [row] = CurTile[col] [row];
|
|
|
|
CurTile[col] [row] = 0;
|
|
|
|
scrolltype = RIGHTSCROLL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (row < 3) {
|
|
|
|
if (CurTile[col] [row + 1] == 0) {
|
|
|
|
CurTile[col] [row + 1] = CurTile[col] [row];
|
|
|
|
CurTile[col] [row] = 0;
|
|
|
|
scrolltype = UPSCROLL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (col < 3) {
|
|
|
|
if (CurTile[col + 1] [row] == 0) {
|
|
|
|
CurTile[col + 1] [row] = CurTile[col] [row];
|
|
|
|
CurTile[col] [row] = 0;
|
|
|
|
scrolltype = LEFTSCROLL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scrolltype != -1) {
|
|
|
|
doTileScroll(col, row, scrolltype);
|
|
|
|
|
2015-02-25 03:13:26 +02:00
|
|
|
if (g_lab->getFeatures() & GF_WINDOWS_TRIAL) {
|
|
|
|
GUI::MessageDialog trialMessage("This puzzle is not available in the trial version of the game");
|
|
|
|
trialMessage.runModal();
|
2014-10-06 14:50:05 +02:00
|
|
|
return;
|
2015-02-25 03:13:26 +02:00
|
|
|
}
|
2014-10-06 14:50:05 +02:00
|
|
|
|
2015-11-27 21:52:31 +01:00
|
|
|
bool check = true;
|
2014-10-06 14:50:05 +02:00
|
|
|
row = 0;
|
|
|
|
col = 0;
|
|
|
|
|
|
|
|
while (row < 4) {
|
|
|
|
while (col < 4) {
|
|
|
|
check = check && (CurTile[row] [col] == TileSolution[row] [col]);
|
|
|
|
col++;
|
|
|
|
}
|
|
|
|
|
|
|
|
row++;
|
|
|
|
col = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (check) {
|
2014-12-25 19:13:52 +01:00
|
|
|
g_lab->_conditions->inclElement(BRICKOPEN); /* unlocked combination */
|
2014-10-06 14:50:05 +02:00
|
|
|
DoBlack = true;
|
|
|
|
check = readPict("p:Up/BDOpen", true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* Processes mouse clicks and changes the combination. */
|
|
|
|
/*****************************************************************************/
|
2015-11-28 02:17:05 +01:00
|
|
|
void mouseTile(Common::Point pos) {
|
|
|
|
int x = VGAUnScaleX(pos.x);
|
|
|
|
int y = VGAUnScaleY(pos.y);
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
if ((x < 101) || (y < 26))
|
|
|
|
return;
|
|
|
|
|
|
|
|
x = (x - 101) / 30;
|
|
|
|
y = (y - 26) / 25;
|
|
|
|
|
|
|
|
if ((x < 4) && (y < 4))
|
2014-12-25 19:13:52 +01:00
|
|
|
changeTile(x, y);
|
2014-10-06 14:50:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* Does the things to properly set up the detective notes. */
|
|
|
|
/*****************************************************************************/
|
2015-02-24 00:31:26 +02:00
|
|
|
void doNotes() {
|
2015-12-01 02:05:29 +02:00
|
|
|
TextFont *noteFont = g_lab->_resource->getFont("P:Note.fon");
|
|
|
|
char *ntext = g_lab->_resource->getText("Lab:Rooms/Notes");
|
2014-10-06 14:50:05 +02:00
|
|
|
|
2015-12-01 02:05:29 +02:00
|
|
|
flowText(noteFont, -2 + SVGACord(1), 0, 0, false, false, true, true, VGAScaleX(25) + SVGACord(15), VGAScaleY(50), VGAScaleX(295) - SVGACord(15), VGAScaleY(148), ntext);
|
2015-11-30 20:07:23 +01:00
|
|
|
g_lab->setPalette(diffcmap, 256);
|
2015-12-01 02:05:29 +02:00
|
|
|
|
2015-12-01 02:17:26 +02:00
|
|
|
closeFont(noteFont);
|
2015-12-01 02:05:29 +02:00
|
|
|
delete[] ntext;
|
2014-10-06 14:50:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* Does the things to properly set up the old west newspaper. Assumes that */
|
|
|
|
/* OpenHiRes already called. */
|
|
|
|
/*****************************************************************************/
|
2015-02-24 00:31:26 +02:00
|
|
|
void doWestPaper() {
|
2014-10-06 14:50:05 +02:00
|
|
|
char *ntext;
|
2015-12-01 02:05:29 +02:00
|
|
|
TextFont *paperFont;
|
2014-10-06 14:50:05 +02:00
|
|
|
int32 FileLen, CharsPrinted;
|
|
|
|
uint16 y = 268;
|
|
|
|
|
2015-12-01 02:05:29 +02:00
|
|
|
paperFont = g_lab->_resource->getFont("P:News22.fon");
|
|
|
|
ntext = g_lab->_resource->getText("Lab:Rooms/Date");
|
|
|
|
flowText(paperFont, 0, 0, 0, false, true, false, true, VGAScaleX(57), VGAScaleY(77) + SVGACord(2), VGAScaleX(262), VGAScaleY(91), ntext);
|
2015-12-01 02:17:26 +02:00
|
|
|
closeFont(paperFont);
|
2015-12-01 02:05:29 +02:00
|
|
|
delete[] ntext;
|
2014-10-06 14:50:05 +02:00
|
|
|
|
2015-12-01 02:05:29 +02:00
|
|
|
paperFont = g_lab->_resource->getFont("P:News32.fon");
|
|
|
|
ntext = g_lab->_resource->getText("Lab:Rooms/Headline");
|
2014-10-06 14:50:05 +02:00
|
|
|
FileLen = strlen(ntext) - 1;
|
2015-12-01 02:05:29 +02:00
|
|
|
CharsPrinted = flowText(paperFont, -8, 0, 0, false, true, false, true, VGAScaleX(57), VGAScaleY(86) - SVGACord(2), VGAScaleX(262), VGAScaleY(118), ntext);
|
2014-10-06 14:50:05 +02:00
|
|
|
if (CharsPrinted < FileLen) {
|
|
|
|
y = 130 - SVGACord(5);
|
2015-12-01 02:05:29 +02:00
|
|
|
flowText(paperFont, -8 - SVGACord(1), 0, 0, false, true, false, true, VGAScaleX(57), VGAScaleY(86) - SVGACord(2), VGAScaleX(262), VGAScaleY(132), ntext);
|
2014-10-06 14:50:05 +02:00
|
|
|
} else
|
|
|
|
y = 115 - SVGACord(5);
|
2015-12-01 02:17:26 +02:00
|
|
|
closeFont(paperFont);
|
2015-12-01 02:05:29 +02:00
|
|
|
delete[] ntext;
|
|
|
|
|
|
|
|
paperFont = g_lab->_resource->getFont("P:Note.fon");
|
|
|
|
ntext = g_lab->_resource->getText("Lab:Rooms/Col1");
|
|
|
|
CharsPrinted = flowText(paperFont, -4, 0, 0, false, false, false, true, VGAScaleX(45), VGAScaleY(y), VGAScaleX(158), VGAScaleY(148), ntext);
|
|
|
|
delete[] ntext;
|
|
|
|
ntext = g_lab->_resource->getText("Lab:Rooms/Col2");
|
|
|
|
CharsPrinted = flowText(paperFont, -4, 0, 0, false, false, false, true, VGAScaleX(162), VGAScaleY(y), VGAScaleX(275), VGAScaleY(148), ntext);
|
|
|
|
delete[] ntext;
|
2015-12-01 02:17:26 +02:00
|
|
|
closeFont(paperFont);
|
2014-10-06 14:50:05 +02:00
|
|
|
|
2015-11-30 20:07:23 +01:00
|
|
|
g_lab->setPalette(diffcmap, 256);
|
2014-10-06 14:50:05 +02:00
|
|
|
freeAllStolenMem();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* Loads in the data for the journal. */
|
|
|
|
/*****************************************************************************/
|
2014-12-25 19:13:52 +01:00
|
|
|
static bool loadJournalData() {
|
2014-10-06 14:50:05 +02:00
|
|
|
byte **buffer;
|
|
|
|
char filename[20];
|
2014-12-26 00:32:42 +01:00
|
|
|
Gadget *TopGadget = &BackG;
|
2014-10-06 14:50:05 +02:00
|
|
|
bool bridge, dirty, news, clean;
|
|
|
|
|
2015-12-01 02:17:26 +02:00
|
|
|
journalFont = g_lab->_resource->getFont("P:Journal.fon"); // FIXME: memory leak
|
2014-10-06 14:50:05 +02:00
|
|
|
|
2015-11-30 01:17:05 +01:00
|
|
|
g_lab->_music->updateMusic();
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
strcpy(filename, "Lab:Rooms/j0");
|
2014-12-25 19:13:52 +01:00
|
|
|
bridge = g_lab->_conditions->in(BRIDGE0) || g_lab->_conditions->in(BRIDGE1);
|
|
|
|
dirty = g_lab->_conditions->in(DIRTY);
|
|
|
|
news = !g_lab->_conditions->in(NONEWS);
|
|
|
|
clean = !g_lab->_conditions->in(NOCLEAN);
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
if (bridge && clean && news)
|
|
|
|
filename[11] = '8';
|
|
|
|
else if (clean && news)
|
|
|
|
filename[11] = '9';
|
|
|
|
else if (bridge && clean)
|
|
|
|
filename[11] = '6';
|
|
|
|
else if (clean)
|
|
|
|
filename[11] = '7';
|
|
|
|
else if (bridge && dirty && news)
|
|
|
|
filename[11] = '4';
|
|
|
|
else if (dirty && news)
|
|
|
|
filename[11] = '5';
|
|
|
|
else if (bridge && dirty)
|
|
|
|
filename[11] = '2';
|
|
|
|
else if (dirty)
|
|
|
|
filename[11] = '3';
|
|
|
|
else if (bridge)
|
|
|
|
filename[11] = '1';
|
|
|
|
|
2015-12-01 02:05:29 +02:00
|
|
|
journaltext = g_lab->_resource->getText(filename);
|
|
|
|
journaltexttitle = g_lab->_resource->getText("Lab:Rooms/jt");
|
2014-10-06 14:50:05 +02:00
|
|
|
|
2015-11-30 01:17:05 +01:00
|
|
|
buffer = g_lab->_music->newOpen("P:JImage");
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
if (!buffer)
|
|
|
|
return false;
|
|
|
|
|
2015-10-12 17:13:42 +03:00
|
|
|
readImage(buffer, &(BackG.Im));
|
|
|
|
readImage(buffer, &(BackG.ImAlt));
|
|
|
|
readImage(buffer, &(ForwardG.Im));
|
|
|
|
readImage(buffer, &(ForwardG.ImAlt));
|
|
|
|
readImage(buffer, &(CancelG.Im));
|
|
|
|
readImage(buffer, &(CancelG.ImAlt));
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
BackG.KeyEquiv = VKEY_LTARROW;
|
|
|
|
ForwardG.KeyEquiv = VKEY_RTARROW;
|
2014-12-27 14:18:40 +01:00
|
|
|
|
2015-11-27 23:18:15 +01:00
|
|
|
uint16 counter = 0;
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
while (TopGadget) {
|
|
|
|
TopGadget->x = VGAScaleX(JGadX[counter]);
|
|
|
|
|
|
|
|
if (counter == 1)
|
|
|
|
TopGadget->y = VGAScaleY(JGadY[counter]) + SVGACord(1);
|
|
|
|
else
|
|
|
|
TopGadget->y = VGAScaleY(JGadY[counter]) - SVGACord(1);
|
|
|
|
|
|
|
|
TopGadget->GadgetID = counter;
|
|
|
|
TopGadget = TopGadget->NextGadget;
|
|
|
|
counter++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* Draws the text to the back journal screen to the appropriate Page number */
|
|
|
|
/*****************************************************************************/
|
2015-02-24 00:31:26 +02:00
|
|
|
static void drawJournalText() {
|
2014-10-06 14:50:05 +02:00
|
|
|
uint16 DrawingToPage = 1;
|
|
|
|
int32 CharsDrawn = 0L;
|
|
|
|
char *CurText = journaltext;
|
|
|
|
|
|
|
|
while (DrawingToPage < JPage) {
|
2015-11-30 01:17:05 +01:00
|
|
|
g_lab->_music->updateMusic();
|
2014-10-06 14:50:05 +02:00
|
|
|
CurText = (char *)(journaltext + CharsDrawn);
|
2015-12-01 02:05:29 +02:00
|
|
|
CharsDrawn += flowText(journalFont, -2, 2, 0, false, false, false, false, VGAScaleX(52), VGAScaleY(32), VGAScaleX(152), VGAScaleY(148), CurText);
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
lastpage = (*CurText == 0);
|
|
|
|
|
|
|
|
if (lastpage)
|
|
|
|
JPage = (DrawingToPage / 2) * 2;
|
|
|
|
else
|
|
|
|
DrawingToPage++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (JPage <= 1) {
|
|
|
|
CurText = journaltexttitle;
|
2015-12-01 02:05:29 +02:00
|
|
|
flowTextToMem(&JBackImage, journalFont, -2, 2, 0, false, true, true, true, VGAScaleX(52), VGAScaleY(32), VGAScaleX(152), VGAScaleY(148), CurText);
|
2014-10-06 14:50:05 +02:00
|
|
|
} else {
|
|
|
|
CurText = (char *)(journaltext + CharsDrawn);
|
2015-12-01 02:05:29 +02:00
|
|
|
CharsDrawn += flowTextToMem(&JBackImage, journalFont, -2, 2, 0, false, false, false, true, VGAScaleX(52), VGAScaleY(32), VGAScaleX(152), VGAScaleY(148), CurText);
|
2014-10-06 14:50:05 +02:00
|
|
|
}
|
|
|
|
|
2015-11-30 01:17:05 +01:00
|
|
|
g_lab->_music->updateMusic();
|
2014-10-06 14:50:05 +02:00
|
|
|
CurText = (char *)(journaltext + CharsDrawn);
|
|
|
|
lastpage = (*CurText == 0);
|
2015-12-01 02:05:29 +02:00
|
|
|
flowTextToMem(&JBackImage, journalFont, -2, 2, 0, false, false, false, true, VGAScaleX(171), VGAScaleY(32), VGAScaleX(271), VGAScaleY(148), CurText);
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
CurText = (char *)(journaltext + CharsDrawn);
|
|
|
|
lastpage = lastpage || (*CurText == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* Does the turn page wipe. */
|
|
|
|
/*****************************************************************************/
|
|
|
|
static void turnPage(bool FromLeft) {
|
|
|
|
if (FromLeft) {
|
2015-11-27 23:18:15 +01:00
|
|
|
for (int i = 0; i < g_lab->_screenWidth; i += 8) {
|
2015-11-30 01:17:05 +01:00
|
|
|
g_lab->_music->updateMusic();
|
2015-11-24 23:59:30 +01:00
|
|
|
g_lab->waitTOF();
|
2015-12-01 10:35:31 +01:00
|
|
|
ScreenImage.ImageData = g_lab->getCurrentDrawingBuffer();
|
2015-11-27 23:18:15 +01:00
|
|
|
g_lab->bltBitMap(&JBackImage, i, 0, &ScreenImage, i, 0, 8, g_lab->_screenHeight);
|
2014-10-06 14:50:05 +02:00
|
|
|
}
|
|
|
|
} else {
|
2015-11-27 23:18:15 +01:00
|
|
|
for (int i = (g_lab->_screenWidth - 8); i > 0; i -= 8) {
|
2015-11-30 01:17:05 +01:00
|
|
|
g_lab->_music->updateMusic();
|
2015-11-24 23:59:30 +01:00
|
|
|
g_lab->waitTOF();
|
2015-12-01 10:35:31 +01:00
|
|
|
ScreenImage.ImageData = g_lab->getCurrentDrawingBuffer();
|
2015-11-27 23:18:15 +01:00
|
|
|
g_lab->bltBitMap(&JBackImage, i, 0, &ScreenImage, i, 0, 8, g_lab->_screenHeight);
|
2014-10-06 14:50:05 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* Draws the journal from page x. */
|
|
|
|
/*****************************************************************************/
|
2015-11-29 18:10:06 +01:00
|
|
|
void LabEngine::drawJournal(uint16 wipenum, bool needFade) {
|
|
|
|
_event->mouseHide();
|
2014-10-06 14:50:05 +02:00
|
|
|
|
2015-11-30 01:17:05 +01:00
|
|
|
_music->updateMusic();
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
if (!GotBackImage)
|
|
|
|
JBackImage.ImageData = loadBackPict("P:Journal.pic", true);
|
|
|
|
|
|
|
|
drawJournalText();
|
|
|
|
|
2015-12-01 10:35:31 +01:00
|
|
|
ScreenImage.ImageData = getCurrentDrawingBuffer();
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
if (wipenum == 0)
|
2015-11-29 23:34:35 +01:00
|
|
|
bltBitMap(&JBackImage, 0, 0, &ScreenImage, 0, 0, _screenWidth, _screenHeight);
|
2014-10-06 14:50:05 +02:00
|
|
|
else
|
|
|
|
turnPage((bool)(wipenum == 1));
|
|
|
|
|
|
|
|
if (JPage == 0)
|
|
|
|
ghoastGadget(&BackG, 15);
|
|
|
|
else
|
|
|
|
unGhoastGadget(&BackG);
|
|
|
|
|
|
|
|
if (lastpage)
|
|
|
|
ghoastGadget(&ForwardG, 15);
|
|
|
|
else
|
|
|
|
unGhoastGadget(&ForwardG);
|
|
|
|
|
|
|
|
|
|
|
|
if (needFade)
|
|
|
|
fade(true, 0);
|
|
|
|
|
|
|
|
nopalchange = true;
|
2015-11-29 23:34:35 +01:00
|
|
|
JBackImage.ImageData = readPictToMem("P:Journal.pic", _screenWidth, _screenHeight);
|
2014-10-06 14:50:05 +02:00
|
|
|
GotBackImage = true;
|
|
|
|
|
|
|
|
eatMessages();
|
2015-11-29 18:10:06 +01:00
|
|
|
_event->mouseShow();
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
nopalchange = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* Processes user input. */
|
|
|
|
/*****************************************************************************/
|
2015-11-29 18:10:06 +01:00
|
|
|
void LabEngine::processJournal() {
|
2014-12-26 00:32:42 +01:00
|
|
|
IntuiMessage *Msg;
|
2014-10-06 14:50:05 +02:00
|
|
|
uint32 Class;
|
|
|
|
uint16 Qualifier, GadID;
|
|
|
|
|
|
|
|
while (1) {
|
2015-11-30 01:17:05 +01:00
|
|
|
_music->updateMusic(); /* Make sure we check the music at least after every message */
|
2015-11-29 18:10:06 +01:00
|
|
|
Msg = getMsg();
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
if (Msg == NULL) {
|
2015-11-30 01:17:05 +01:00
|
|
|
_music->updateMusic();
|
2014-10-06 14:50:05 +02:00
|
|
|
} else {
|
2015-11-20 20:26:00 +01:00
|
|
|
Class = Msg->msgClass;
|
|
|
|
Qualifier = Msg->qualifier;
|
|
|
|
GadID = Msg->code;
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
if (((Class == MOUSEBUTTONS) && (IEQUALIFIER_RBUTTON & Qualifier)) ||
|
|
|
|
((Class == RAWKEY) && (GadID == 27)))
|
|
|
|
return;
|
|
|
|
|
|
|
|
else if (Class == GADGETUP) {
|
|
|
|
if (GadID == 0) {
|
|
|
|
if (JPage >= 2) {
|
|
|
|
JPage -= 2;
|
|
|
|
drawJournal(1, false);
|
|
|
|
}
|
|
|
|
} else if (GadID == 1) {
|
|
|
|
return;
|
|
|
|
} else if (GadID == 2) {
|
|
|
|
if (!lastpage) {
|
|
|
|
JPage += 2;
|
|
|
|
drawJournal(2, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* Does the journal processing. */
|
|
|
|
/*****************************************************************************/
|
2015-11-29 18:10:06 +01:00
|
|
|
void LabEngine::doJournal() {
|
2014-10-06 14:50:05 +02:00
|
|
|
resetBuffer();
|
|
|
|
blackAllScreen();
|
|
|
|
|
|
|
|
lastpage = false;
|
|
|
|
GotBackImage = false;
|
|
|
|
|
2015-11-29 23:34:35 +01:00
|
|
|
JBackImage.Width = _screenWidth;
|
|
|
|
JBackImage.Height = _screenHeight;
|
2014-10-06 14:50:05 +02:00
|
|
|
JBackImage.ImageData = NULL;
|
|
|
|
|
|
|
|
BackG.NextGadget = &CancelG;
|
|
|
|
CancelG.NextGadget = &ForwardG;
|
|
|
|
|
|
|
|
ScreenImage = JBackImage;
|
2015-12-01 10:35:31 +01:00
|
|
|
ScreenImage.ImageData = getCurrentDrawingBuffer();
|
2014-10-06 14:50:05 +02:00
|
|
|
|
2015-11-30 01:17:05 +01:00
|
|
|
_music->updateMusic();
|
2014-12-25 19:13:52 +01:00
|
|
|
loadJournalData();
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
drawJournal(0, true);
|
|
|
|
|
2015-11-29 18:10:06 +01:00
|
|
|
_event->attachGadgetList(&BackG);
|
|
|
|
_event->mouseShow();
|
2014-10-06 14:50:05 +02:00
|
|
|
processJournal();
|
2015-11-29 18:10:06 +01:00
|
|
|
_event->attachGadgetList(NULL);
|
2014-10-06 14:50:05 +02:00
|
|
|
fade(false, 0);
|
2015-11-29 18:10:06 +01:00
|
|
|
_event->mouseHide();
|
2014-10-06 14:50:05 +02:00
|
|
|
|
2015-12-01 10:35:31 +01:00
|
|
|
ScreenImage.ImageData = getCurrentDrawingBuffer();
|
2014-10-06 14:50:05 +02:00
|
|
|
|
2015-11-29 23:34:35 +01:00
|
|
|
setAPen(0);
|
|
|
|
rectFill(0, 0, _screenWidth - 1, _screenHeight - 1);
|
2014-10-06 14:50:05 +02:00
|
|
|
blackScreen();
|
|
|
|
|
2015-02-19 15:46:34 +02:00
|
|
|
freeAllStolenMem();
|
2014-10-06 14:50:05 +02:00
|
|
|
}
|
|
|
|
|
2015-02-24 00:31:26 +02:00
|
|
|
bool saveRestoreGame() {
|
2015-02-19 15:41:15 +02:00
|
|
|
bool isOK = false;
|
|
|
|
|
2015-07-17 10:50:04 +03:00
|
|
|
//g_lab->showMainMenu();
|
|
|
|
|
2015-02-19 15:41:15 +02:00
|
|
|
// The original had one screen for saving/loading. We have two.
|
|
|
|
// Ask the user which screen to use.
|
|
|
|
GUI::MessageDialog saveOrLoad(_("Would you like to save or restore a game?"), _("Save"), _("Restore"));
|
|
|
|
|
|
|
|
int choice = saveOrLoad.runModal();
|
|
|
|
if (choice == GUI::kMessageOK) {
|
|
|
|
// Save
|
|
|
|
GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true);
|
|
|
|
int slot = dialog->runModalWithCurrentTarget();
|
|
|
|
if (slot >= 0) {
|
|
|
|
Common::String desc = dialog->getResultString();
|
|
|
|
|
|
|
|
if (desc.empty()) {
|
|
|
|
// create our own description for the saved game, the user didn't enter it
|
|
|
|
desc = dialog->createDefaultSaveDescription(slot);
|
2014-10-06 14:50:05 +02:00
|
|
|
}
|
|
|
|
|
2015-11-30 01:42:12 +01:00
|
|
|
isOK = saveGame(Direction, Inventory[QUARTERNUM].Many, slot, desc);
|
2014-10-06 14:50:05 +02:00
|
|
|
}
|
|
|
|
} else {
|
2015-02-19 15:41:15 +02:00
|
|
|
// Restore
|
|
|
|
GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false);
|
|
|
|
int slot = dialog->runModalWithCurrentTarget();
|
2015-02-19 19:03:45 +02:00
|
|
|
if (slot >= 0) {
|
2015-11-30 01:42:12 +01:00
|
|
|
isOK = loadGame(&Direction, &(Inventory[QUARTERNUM].Many), slot);
|
2015-02-19 19:03:45 +02:00
|
|
|
if (isOK)
|
2015-11-30 01:17:05 +01:00
|
|
|
g_lab->_music->resetMusic();
|
2015-02-19 19:03:45 +02:00
|
|
|
}
|
2014-10-06 14:50:05 +02:00
|
|
|
}
|
|
|
|
|
2015-11-30 20:07:23 +01:00
|
|
|
g_lab->screenUpdate();
|
2015-11-20 19:45:07 +01:00
|
|
|
|
2015-02-19 19:03:45 +02:00
|
|
|
return isOK;
|
2014-10-06 14:50:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* Makes sure that the buttons are in memory. */
|
|
|
|
/*****************************************************************************/
|
2015-02-24 00:31:26 +02:00
|
|
|
static void getMonImages() {
|
2014-10-06 14:50:05 +02:00
|
|
|
byte **buffer;
|
2015-07-17 10:50:04 +03:00
|
|
|
uint32 bufferSize;
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
resetBuffer();
|
|
|
|
|
2015-11-30 01:17:05 +01:00
|
|
|
buffer = g_lab->_music->newOpen("P:MonImage", bufferSize);
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
if (!buffer)
|
|
|
|
return;
|
|
|
|
|
|
|
|
readImage(buffer, &MonButton);
|
|
|
|
|
2015-07-17 10:50:04 +03:00
|
|
|
stealBufMem(bufferSize); /* Trick: protects the memory where the buttons are so they won't be over-written */
|
2014-10-06 14:50:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* Draws the text for the monitor. */
|
|
|
|
/*****************************************************************************/
|
2015-12-01 02:05:29 +02:00
|
|
|
void LabEngine::drawMonText(char *text, TextFont *monitorFont, uint16 x1, uint16 y1, uint16 x2, uint16 y2, bool isinteractive) {
|
2015-11-27 23:18:15 +01:00
|
|
|
uint16 DrawingToPage = 0, yspacing = 0, numlines, fheight;
|
2014-10-06 14:50:05 +02:00
|
|
|
int32 CharsDrawn = 0L;
|
|
|
|
char *CurText = text;
|
|
|
|
|
2015-11-29 18:10:06 +01:00
|
|
|
_event->mouseHide();
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
if (*text == '%') {
|
|
|
|
text++;
|
|
|
|
numlines = (*text - '0') * 10;
|
|
|
|
text++;
|
|
|
|
numlines += (*text - '0');
|
|
|
|
text += 2;
|
|
|
|
|
2015-12-01 02:05:29 +02:00
|
|
|
fheight = textHeight(monitorFont);
|
2014-10-06 14:50:05 +02:00
|
|
|
x1 = MonButton->Width + VGAScaleX(3);
|
|
|
|
MonGadHeight = MonButton->Height + VGAScaleY(3);
|
|
|
|
|
|
|
|
if (MonGadHeight > fheight)
|
|
|
|
yspacing = MonGadHeight - fheight;
|
|
|
|
else
|
|
|
|
MonGadHeight = fheight;
|
|
|
|
|
2015-11-29 23:34:35 +01:00
|
|
|
setAPen(0);
|
|
|
|
rectFill(0, 0, _screenWidth - 1, y2);
|
2014-10-06 14:50:05 +02:00
|
|
|
|
2015-11-27 23:18:15 +01:00
|
|
|
for (uint16 i = 0; i < numlines; i++)
|
2015-11-29 23:34:35 +01:00
|
|
|
drawImage(MonButton, 0, i * MonGadHeight);
|
2014-10-06 14:50:05 +02:00
|
|
|
} else if (isinteractive) {
|
2015-11-29 23:34:35 +01:00
|
|
|
setAPen(0);
|
|
|
|
rectFill(0, 0, _screenWidth - 1, y2);
|
2014-10-06 14:50:05 +02:00
|
|
|
} else {
|
2015-11-29 23:34:35 +01:00
|
|
|
setAPen(0);
|
|
|
|
rectFill(x1, y1, x2, y2);
|
2014-10-06 14:50:05 +02:00
|
|
|
}
|
|
|
|
|
2015-10-16 01:52:53 +03:00
|
|
|
while (DrawingToPage < monitorPage) {
|
2015-11-30 01:17:05 +01:00
|
|
|
_music->updateMusic();
|
2014-10-06 14:50:05 +02:00
|
|
|
CurText = (char *)(text + CharsDrawn);
|
2015-12-01 02:05:29 +02:00
|
|
|
CharsDrawn += flowText(monitorFont, yspacing, 0, 0, false, false, false, false, x1, y1, x2, y2, CurText);
|
2014-10-06 14:50:05 +02:00
|
|
|
lastpage = (*CurText == 0);
|
|
|
|
|
|
|
|
if (lastpage)
|
2015-10-16 01:52:53 +03:00
|
|
|
monitorPage = DrawingToPage;
|
2014-10-06 14:50:05 +02:00
|
|
|
else
|
|
|
|
DrawingToPage++;
|
|
|
|
}
|
|
|
|
|
|
|
|
CurText = (char *)(text + CharsDrawn);
|
|
|
|
lastpage = (*CurText == 0);
|
2015-12-01 02:05:29 +02:00
|
|
|
CharsDrawn = flowText(monitorFont, yspacing, 2, 0, false, false, false, true, x1, y1, x2, y2, CurText);
|
2014-10-06 14:50:05 +02:00
|
|
|
CurText += CharsDrawn;
|
|
|
|
lastpage = lastpage || (*CurText == 0);
|
|
|
|
|
2015-11-29 18:10:06 +01:00
|
|
|
_event->mouseShow();
|
2014-10-06 14:50:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* Processes user input. */
|
|
|
|
/*****************************************************************************/
|
2015-12-01 02:05:29 +02:00
|
|
|
void LabEngine::processMonitor(char *ntext, TextFont *monitorFont, bool isinteractive, uint16 x1, uint16 y1, uint16 x2, uint16 y2) {
|
2014-12-26 00:32:42 +01:00
|
|
|
IntuiMessage *Msg;
|
2014-10-06 14:50:05 +02:00
|
|
|
uint32 Class;
|
|
|
|
uint16 Qualifier, Code, MouseX, MouseY;
|
|
|
|
const char *Test = " ", *StartFileName = TextFileName;
|
|
|
|
CloseDataPtr StartCPtr = CPtr, TestCPtr, LastCPtr[10];
|
|
|
|
uint16 depth = 0;
|
|
|
|
|
|
|
|
LastCPtr[0] = CPtr;
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
if (isinteractive) {
|
|
|
|
if (CPtr == NULL)
|
|
|
|
CPtr = StartCPtr;
|
|
|
|
|
|
|
|
if (CPtr == StartCPtr)
|
|
|
|
Test = StartFileName;
|
|
|
|
else
|
|
|
|
Test = CPtr->GraphicName;
|
|
|
|
|
|
|
|
if (strcmp(Test, TextFileName)) {
|
2015-10-16 01:52:53 +03:00
|
|
|
monitorPage = 0;
|
2014-10-06 14:50:05 +02:00
|
|
|
TextFileName = Test;
|
|
|
|
|
2015-12-01 02:05:29 +02:00
|
|
|
ntext = g_lab->_resource->getText(TextFileName);
|
2014-10-06 14:50:05 +02:00
|
|
|
fade(false, 0);
|
2015-12-01 02:05:29 +02:00
|
|
|
drawMonText(ntext, monitorFont, x1, y1, x2, y2, isinteractive);
|
2014-10-06 14:50:05 +02:00
|
|
|
fade(true, 0);
|
2015-12-01 02:05:29 +02:00
|
|
|
delete[] ntext;
|
2014-10-06 14:50:05 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-30 01:17:05 +01:00
|
|
|
_music->updateMusic(); /* Make sure we check the music at least after every message */
|
2014-10-06 14:50:05 +02:00
|
|
|
Msg = getMsg();
|
|
|
|
|
|
|
|
if (Msg == NULL) {
|
2015-11-30 01:17:05 +01:00
|
|
|
_music->updateMusic();
|
2014-10-06 14:50:05 +02:00
|
|
|
} else {
|
2015-11-20 20:26:00 +01:00
|
|
|
Class = Msg->msgClass;
|
|
|
|
Qualifier = Msg->qualifier;
|
|
|
|
MouseX = Msg->mouseX;
|
|
|
|
MouseY = Msg->mouseY;
|
|
|
|
Code = Msg->code;
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
if (((Class == MOUSEBUTTONS) && (IEQUALIFIER_RBUTTON & Qualifier)) ||
|
|
|
|
((Class == RAWKEY) && (Code == 27)))
|
|
|
|
return;
|
|
|
|
|
|
|
|
else if ((Class == MOUSEBUTTONS) && (IEQUALIFIER_LEFTBUTTON & Qualifier)) {
|
|
|
|
if ((MouseY >= VGAScaleY(171)) && (MouseY <= VGAScaleY(200))) {
|
|
|
|
if ((MouseX >= VGAScaleX(259)) && (MouseX <= VGAScaleX(289))) {
|
|
|
|
if (!lastpage) {
|
2015-10-16 01:52:53 +03:00
|
|
|
monitorPage += 1;
|
2015-12-01 02:05:29 +02:00
|
|
|
drawMonText(ntext, monitorFont, x1, y1, x2, y2, isinteractive);
|
2014-10-06 14:50:05 +02:00
|
|
|
}
|
|
|
|
} else if ((MouseX >= VGAScaleX(0)) && (MouseX <= VGAScaleX(31))) {
|
|
|
|
return;
|
|
|
|
} else if ((MouseX >= VGAScaleX(290)) && (MouseX <= VGAScaleX(320))) {
|
2015-10-16 01:52:53 +03:00
|
|
|
if (monitorPage >= 1) {
|
|
|
|
monitorPage -= 1;
|
2015-12-01 02:05:29 +02:00
|
|
|
drawMonText(ntext, monitorFont, x1, y1, x2, y2, isinteractive);
|
2014-10-06 14:50:05 +02:00
|
|
|
}
|
|
|
|
} else if ((MouseX >= VGAScaleX(31)) && (MouseX <= VGAScaleX(59))) {
|
|
|
|
if (isinteractive) {
|
2015-10-16 01:52:53 +03:00
|
|
|
monitorPage = 0;
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
if (depth) {
|
|
|
|
depth--;
|
|
|
|
CPtr = LastCPtr[depth];
|
|
|
|
}
|
2015-10-16 01:52:53 +03:00
|
|
|
} else if (monitorPage > 0) {
|
|
|
|
monitorPage = 0;
|
2015-12-01 02:05:29 +02:00
|
|
|
drawMonText(ntext, monitorFont, x1, y1, x2, y2, isinteractive);
|
2014-10-06 14:50:05 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (isinteractive) {
|
|
|
|
TestCPtr = CPtr;
|
|
|
|
MouseY = 64 + (MouseY / MonGadHeight) * 42;
|
|
|
|
MouseX = 101;
|
2015-11-28 02:17:05 +01:00
|
|
|
setCurClose(Common::Point(MouseX, MouseY), &CPtr, true);
|
2014-10-06 14:50:05 +02:00
|
|
|
|
|
|
|
if (TestCPtr != CPtr) {
|
|
|
|
LastCPtr[depth] = TestCPtr;
|
|
|
|
depth++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* Does what's necessary for the monitor. */
|
|
|
|
/*****************************************************************************/
|
2015-11-29 18:10:06 +01:00
|
|
|
void LabEngine::doMonitor(char *background, char *textfile, bool isinteractive, uint16 x1, uint16 y1, uint16 x2, uint16 y2) {
|
2014-10-06 14:50:05 +02:00
|
|
|
char *ntext;
|
|
|
|
|
|
|
|
x1 = VGAScaleX(x1);
|
|
|
|
x2 = VGAScaleX(x2);
|
|
|
|
y1 = VGAScaleY(y1);
|
|
|
|
y2 = VGAScaleY(y2);
|
|
|
|
|
|
|
|
TextFileName = textfile;
|
|
|
|
|
|
|
|
blackAllScreen();
|
|
|
|
|
|
|
|
readPict("P:Mon/Monitor.1", true);
|
|
|
|
readPict("P:Mon/NWD1", true);
|
|
|
|
readPict("P:Mon/NWD2", true);
|
|
|
|
readPict("P:Mon/NWD3", true);
|
|
|
|
blackAllScreen();
|
|
|
|
|
|
|
|
resetBuffer();
|
2015-10-16 01:52:53 +03:00
|
|
|
monitorPage = 0;
|
2014-10-06 14:50:05 +02:00
|
|
|
lastpage = false;
|
|
|
|
FadePalette = hipal;
|
|
|
|
|
2015-12-01 02:05:29 +02:00
|
|
|
TextFont *monitorFont = _resource->getFont("P:Map.fon");
|
2014-10-06 14:50:05 +02:00
|
|
|
getMonImages();
|
|
|
|
|
2015-12-01 02:05:29 +02:00
|
|
|
ntext = _resource->getText(textfile);
|
2014-10-06 14:50:05 +02:00
|
|
|
loadBackPict(background, false);
|
2015-12-01 02:05:29 +02:00
|
|
|
drawMonText(ntext, monitorFont, x1, y1, x2, y2, isinteractive);
|
2015-11-29 18:10:06 +01:00
|
|
|
_event->mouseShow();
|
2014-10-06 14:50:05 +02:00
|
|
|
fade(true, 0);
|
2015-12-01 02:05:29 +02:00
|
|
|
processMonitor(ntext, monitorFont, isinteractive, x1, y1, x2, y2);
|
2014-10-06 14:50:05 +02:00
|
|
|
fade(false, 0);
|
2015-11-29 18:10:06 +01:00
|
|
|
_event->mouseHide();
|
2015-12-01 02:05:29 +02:00
|
|
|
delete[] ntext;
|
2015-12-01 02:17:26 +02:00
|
|
|
closeFont(monitorFont);
|
2014-10-06 14:50:05 +02:00
|
|
|
freeAllStolenMem();
|
|
|
|
|
2015-11-29 23:34:35 +01:00
|
|
|
setAPen(0);
|
|
|
|
rectFill(0, 0, _screenWidth - 1, _screenHeight - 1);
|
2014-10-06 14:50:05 +02:00
|
|
|
blackAllScreen();
|
|
|
|
}
|
|
|
|
|
|
|
|
} // End of namespace Lab
|