mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-06 18:00:44 +00:00
d335b78003
Using Ryan's watch within the game, the watch time always started at
19.30 from point of use, which did not seem correct.
Checking with the original CD and Floppy interpreters under DOSBox
showed they used the current system time, so this was incorrect.
Bisection shows that this regression was introduced by commit
57e940f678
i.e. "DREAMWEB: Move all saved
variables to a GameVars struct" and was probably a side effect of a
minor call ordering change in the equivalent of setupInitialVars()
with respect to the getTime() call.
However, to ensure no further regressions, it was easier to fix this
by replacing the initial value setting by a getTime() call.
3055 lines
67 KiB
C++
3055 lines
67 KiB
C++
/* 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 "dreamweb/sound.h"
|
|
#include "dreamweb/dreamweb.h"
|
|
#include "common/config-manager.h"
|
|
|
|
namespace DreamWeb {
|
|
|
|
// Keyboard buffer. _bufferIn and _bufferOut are indexes
|
|
// into this, making it a ring buffer
|
|
uint8 g_keyBuffer[16];
|
|
|
|
const Room g_roomData[] = {
|
|
// location 0
|
|
{ "DREAMWEB.R00", // Ryan's apartment
|
|
5,255,33,10,
|
|
255,255,255,0,
|
|
1,6,2,255,3,255,255,255,255,255,0 },
|
|
|
|
// location 1
|
|
{ "DREAMWEB.R01",
|
|
1,255,44,10,
|
|
255,255,255,0,
|
|
7,2,255,255,255,255,6,255,255,255,1 },
|
|
|
|
// location 2: Louis' (?)
|
|
{ "DREAMWEB.R02",
|
|
2,255,33,0,
|
|
255,255,255,0,
|
|
1,0,255,255,1,255,3,255,255,255,2 },
|
|
|
|
// location 3
|
|
{ "DREAMWEB.R03",
|
|
5,255,33,10,
|
|
255,255,255,0,
|
|
2,2,0,2,4,255,0,255,255,255,3 },
|
|
|
|
// location 4
|
|
{ "DREAMWEB.R04",
|
|
23,255,11,30,
|
|
255,255,255,0,
|
|
1,4,0,5,255,255,3,255,255,255,4 },
|
|
|
|
// location 5: In hotel, lift noise audible (?)
|
|
{ "DREAMWEB.R05",
|
|
5,255,22,30, // if demo: 22,255,22,30,
|
|
255,255,255,0,
|
|
1,2,0,4,255,255,3,255,255,255,5 },
|
|
|
|
// location 6: sarters (?)
|
|
{ "DREAMWEB.R06",
|
|
5,255,11,30,
|
|
255,255,255,0,
|
|
1,0,0,1,2,255,0,255,255,255,6 },
|
|
|
|
// location 7
|
|
{ "DREAMWEB.R07",
|
|
255,255,0,20,
|
|
255,255,255,0,
|
|
2,2,255,255,255,255,0,255,255,255,7 },
|
|
|
|
// location 8: TV studio (?)
|
|
{ "DREAMWEB.R08",
|
|
8,255,0,10,
|
|
255,255,255,0,
|
|
1,2,255,255,255,255,0,11,40,0,8 },
|
|
|
|
// location 9
|
|
{ "DREAMWEB.R09",
|
|
9,255,22,10,
|
|
255,255,255,0,
|
|
4,6,255,255,255,255,0,255,255,255,9 },
|
|
|
|
// location 10
|
|
{ "DREAMWEB.R10",
|
|
10,255,33,30,
|
|
255,255,255,0,
|
|
2,0,255,255,2,2,4,22,30,255,10 }, // 22,30,0 switches
|
|
// off path 0 in skip
|
|
// location 11
|
|
{ "DREAMWEB.R11",
|
|
11,255,11,20,
|
|
255,255,255,0,
|
|
0,4,255,255,255,255,255,255,255,255,11 },
|
|
|
|
// location 12
|
|
{ "DREAMWEB.R12",
|
|
12,255,22,20,
|
|
255,255,255,0,
|
|
1,4,255,255,255,255,255,255,255,255,12 },
|
|
|
|
// location 13: boathouse (?)
|
|
{ "DREAMWEB.R13",
|
|
12,255,22,20,
|
|
255,255,255,0,
|
|
1,4,255,255,255,255,255,255,255,255,13 },
|
|
|
|
// location 14
|
|
{ "DREAMWEB.R14",
|
|
14,255,44,20,
|
|
255,255,255,0,
|
|
0,6,255,255,255,255,255,255,255,255,14 },
|
|
|
|
{ "", 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
|
|
{ "", 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
|
|
{ "", 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
|
|
{ "", 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
|
|
|
|
// location 19
|
|
{ "DREAMWEB.R19",
|
|
19,255,0,0,
|
|
255,255,255,0,
|
|
0,4,255,255,255,255,255,255,255,255,19 },
|
|
|
|
// location 20: Sart room (?)
|
|
{ "DREAMWEB.R20",
|
|
22,255,0,20,
|
|
255,255,255,0,
|
|
1,4,2,15,255,255,255,255,255,255,20 },
|
|
|
|
// location 21: lift noise audible (?)
|
|
{ "DREAMWEB.R21",
|
|
5,255,11,10, // if demo: 22,255,11,10,
|
|
255,255,255,0,
|
|
1,4,2,15,1,255,255,255,255,255,21 },
|
|
|
|
// location 22: pool room (?)
|
|
{ "DREAMWEB.R22",
|
|
22,255,22,10,
|
|
255,255,255,0,
|
|
0,4,255,255,1,255,255,255,255,255,22 },
|
|
|
|
// location 23
|
|
{ "DREAMWEB.R23",
|
|
23,255,22,30,
|
|
255,255,255,0,
|
|
1,4,2,15,3,255,255,255,255,255,23 },
|
|
|
|
// location 24: only room in which initialInv() is active, i.e. we get initial inventory here
|
|
{ "DREAMWEB.R24",
|
|
5,255,44,0,
|
|
255,255,255,0,
|
|
1,6,2,15,255,255,255,255,255,255,24 },
|
|
|
|
// location 25: helicopter (?)
|
|
{ "DREAMWEB.R25",
|
|
22,255,11,40,
|
|
255,255,255,0,
|
|
1,0,255,255,255,255,255,255,255,255,25 },
|
|
|
|
// location 26: reached via trap door (?)
|
|
{ "DREAMWEB.R26",
|
|
9,255,22,20,
|
|
255,255,255,0,
|
|
4,2,255,255,255,255,255,255,255,255,26 },
|
|
|
|
// location 27: rock room (?)
|
|
{ "DREAMWEB.R27",
|
|
22,255,11,20,
|
|
255,255,255,0,
|
|
0,6,255,255,255,255,255,255,255,255,27 },
|
|
|
|
// location 28: related to TV studiou (?), see resetLocation()
|
|
{ "DREAMWEB.R28",
|
|
5,255,11,30,
|
|
255,255,255,0,
|
|
0,0,255,255,2,255,255,255,255,255,28 },
|
|
|
|
// location 29: aide (?)
|
|
{ "DREAMWEB.R29",
|
|
22,255,11,10,
|
|
255,255,255,0,
|
|
0,2,255,255,255,255,255,255,255,255,29 },
|
|
|
|
|
|
// location 30
|
|
{ "DREAMWEB.R05", // Duplicate of hotel lobby, but emerging from the lift.
|
|
5,255,22,10, // if demo: 22,255,22,10
|
|
255,255,255,0,
|
|
1,4,1,15,255,255,255,255,255,255,5 },
|
|
|
|
// location 31
|
|
{ "DREAMWEB.R04", // Duplicate of pool hall lobby,
|
|
23,255,22,20, // but emerging from the lift.
|
|
255,255,255,0,
|
|
1,4,2,15,255,255,255,255,255,255,4 },
|
|
|
|
// location 32
|
|
{ "DREAMWEB.R10", // entering alley via skip
|
|
10,255,22,30,
|
|
255,255,255,0,
|
|
3,6,255,255,255,255,255,255,255,255,10 },
|
|
|
|
// location 33
|
|
{ "DREAMWEB.R12", // on the beach, getting up.
|
|
12,255,22,20,
|
|
255,255,255,0,
|
|
0,2,255,255,255,255,255,255,255,255,12 },
|
|
|
|
// location 34
|
|
{ "DREAMWEB.R03", // Duplicate of Eden's lobby
|
|
5,255,44,0, // but emerging from the lift
|
|
255,255,255,0,
|
|
1,6,2,255,4,255,255,255,255,255,3 },
|
|
|
|
// location 35: Location when starting the game, after dream (?)
|
|
{ "DREAMWEB.R24", // Duplicate of Eden's flat
|
|
5,255,22,0, // but starting on the bed
|
|
255,255,255,0,
|
|
3,6,0,255,255,255,255,33,0,3,24 }, // 33,0,3 turns off path for lift
|
|
|
|
// location 36
|
|
{ "DREAMWEB.R22", // Duplicate
|
|
22,255,22,20, // of hotel but in pool room
|
|
255,255,255,0,
|
|
1,4,255,255,255,255,255,255,255,255,22 },
|
|
|
|
// location 37
|
|
{ "DREAMWEB.R22", // Duplicate
|
|
22,255,22,20, // of hotel but in pool room
|
|
255,255,255,0, // coming out of bedroom
|
|
0,2,255,255,255,255,255,255,255,255,22 },
|
|
|
|
// location 38
|
|
{ "DREAMWEB.R11", // Duplicate
|
|
11,255,22,30, // of carpark but getting
|
|
255,255,255,0, // up off the floor
|
|
0,0,255,255,255,255,255,255,255,255,11 },
|
|
|
|
// location 39
|
|
{ "DREAMWEB.R28",
|
|
5,255,11,20,
|
|
255,255,255,0,
|
|
0,6,255,255,2,255,255,255,255,255,28 },
|
|
|
|
// location 40
|
|
{ "DREAMWEB.R21",
|
|
5,255,11,10, // if demo: 22,255,11,10
|
|
255,255,255,0,
|
|
1,4,2,15,1,255,255,255,255,255,21 },
|
|
|
|
// location 41
|
|
{ "DREAMWEB.R26",
|
|
9,255,0,40,
|
|
255,255,255,0,
|
|
0,0,255,255,255,255,255,255,255,255,26 },
|
|
|
|
// location 42
|
|
{ "DREAMWEB.R19",
|
|
19,255,0,0,
|
|
255,255,255,0,
|
|
2,2,255,255,255,255,255,255,255,255,19 },
|
|
|
|
// location 43
|
|
{ "DREAMWEB.R08", // leaving tvstudio into street
|
|
8,255,11,40,
|
|
255,255,255,0,
|
|
0,4,255,255,255,255,255,255,255,255,8 },
|
|
|
|
// location 44
|
|
{ "DREAMWEB.R01",
|
|
1,255,44,10,
|
|
255,255,255,0,
|
|
3,6,255,255,255,255,255,255,255,255,1 },
|
|
|
|
|
|
// location 45
|
|
{ "DREAMWEB.R45", // Dream room
|
|
35,255,22,30,
|
|
255,255,255,0,
|
|
0,6,255,255,255,255,255,255,255,255,45 },
|
|
|
|
// location 46
|
|
{ "DREAMWEB.R46", // Dream room
|
|
35,255,22,40,
|
|
255,255,255,0,
|
|
0,4,255,255,255,255,255,255,255,255,46 },
|
|
|
|
// location 47
|
|
{ "DREAMWEB.R47", // Dream room
|
|
35,255,0,0,
|
|
255,255,255,0,
|
|
0,0,255,255,255,255,255,255,255,255,47 },
|
|
|
|
// location 48
|
|
{ "DREAMWEB.R45", // Dream room
|
|
35,255,22,30,
|
|
255,255,255,0,
|
|
4,0,255,255,255,255,255,255,255,255,45 },
|
|
|
|
// location 49
|
|
{ "DREAMWEB.R46", // Dream room
|
|
35,255,22,50,
|
|
255,255,255,0,
|
|
0,4,255,255,255,255,255,255,255,255,46 },
|
|
|
|
|
|
// location 50
|
|
{ "DREAMWEB.R50", // Intro sequence one
|
|
35,255,22,30,
|
|
255,255,255,0,
|
|
0,0,255,255,255,255,255,255,255,255,50 },
|
|
|
|
{ "DREAMWEB.R51", // Intro sequence two
|
|
35,255,11,30,
|
|
255,255,255,0,
|
|
0,0,255,255,255,255,255,255,255,255,51 },
|
|
|
|
{ "DREAMWEB.R52", // Intro sequence three
|
|
35,255,22,30,
|
|
255,255,255,0,
|
|
0,0,255,255,255,255,255,255,255,255,52 },
|
|
|
|
{ "DREAMWEB.R53", // Intro sequence four
|
|
35,255,33,0,
|
|
255,255,255,0,
|
|
0,0,255,255,255,255,255,255,255,255,53 },
|
|
|
|
{ "DREAMWEB.R54", // Intro sequence five - wasteland
|
|
35,255,0,0,
|
|
255,255,255,0,
|
|
0,0,255,255,255,255,255,255,255,255,54 },
|
|
|
|
{ "DREAMWEB.R55", // End sequence
|
|
14,255,44,0,
|
|
255,255,255,0,
|
|
0,0,255,255,255,255,255,255,255,255,55 }
|
|
};
|
|
|
|
static const Atmosphere g_atmosphereList[] = {
|
|
// location,map x,y,sound,repeat
|
|
{ 0,33,10,15,255 },
|
|
{ 0,22,10,15,255 },
|
|
{ 0,22,0,15,255 },
|
|
{ 0,11,0,15,255 },
|
|
{ 0,11,10,15,255 },
|
|
{ 0,0,10,15,255 },
|
|
|
|
{ 1,44,10,6,255 },
|
|
{ 1,44,0,13,255 },
|
|
|
|
{ 2,33,0,6,255 },
|
|
{ 2,22,0,5,255 },
|
|
{ 2,22,10,16,255 },
|
|
{ 2,11,10,16,255 },
|
|
|
|
{ 3,44,0,15,255 },
|
|
{ 3,33,10,6,255 },
|
|
{ 3,33,0,5,255 },
|
|
|
|
{ 4,11,30,6,255 },
|
|
{ 4,22,30,5,255 },
|
|
{ 4,22,20,13,255 },
|
|
|
|
{ 10,33,30,6,255 },
|
|
{ 10,22,30,6,255 },
|
|
|
|
{ 9,22,10,6,255 },
|
|
{ 9,22,20,16,255 },
|
|
{ 9,22,30,16,255 },
|
|
{ 9,22,40,16,255 },
|
|
{ 9,22,50,16,255 },
|
|
|
|
{ 6,11,30,6,255 },
|
|
{ 6,0,10,15,255 },
|
|
{ 6,0,20,15,255 },
|
|
{ 6,11,20,15,255 },
|
|
{ 6,22,20,15,255 },
|
|
|
|
{ 7,11,20,6,255 },
|
|
{ 7,0,20,6,255 },
|
|
{ 7,0,30,6,255 },
|
|
|
|
{ 55,44,0,5,255 },
|
|
{ 55,44,10,5,255 },
|
|
|
|
{ 5,22,30,6,255 },
|
|
{ 5,22,20,15,255 }, // if demo: { 5,22,20,16,255 },
|
|
{ 5,22,10,15,255 }, // if demo: { 5,22,10,16,255 },
|
|
|
|
{ 24,22,0,15,255 },
|
|
{ 24,33,0,15,255 },
|
|
{ 24,44,0,15,255 },
|
|
{ 24,33,10,15,255 },
|
|
|
|
{ 8,0,10,6,255 },
|
|
{ 8,11,10,6,255 },
|
|
{ 8,22,10,6,255 },
|
|
{ 8,33,10,6,255 },
|
|
{ 8,33,20,6,255 },
|
|
{ 8,33,30,6,255 },
|
|
{ 8,33,40,6,255 },
|
|
{ 8,22,40,6,255 },
|
|
{ 8,11,40,6,255 },
|
|
|
|
{ 11,11,20,12,255 },
|
|
{ 11,11,30,12,255 },
|
|
{ 11,22,20,12,255 },
|
|
{ 11,22,30,12,255 },
|
|
|
|
{ 12,22,20,12,255 },
|
|
{ 13,22,20,12,255 },
|
|
{ 13,33,20,12,255 },
|
|
|
|
{ 14,44,20,12,255 },
|
|
{ 14,33,0,12,255 },
|
|
{ 14,33,10,12,255 },
|
|
{ 14,33,20,12,255 },
|
|
{ 14,33,30,12,255 },
|
|
{ 14,33,40,12,255 },
|
|
{ 14,22,0,16,255 },
|
|
|
|
{ 19,0,0,12,255 },
|
|
|
|
{ 20,0,20,16,255 },
|
|
{ 20,0,30,16,255 },
|
|
{ 20,11,30,16,255 },
|
|
{ 20,0,40,16,255 },
|
|
{ 20,11,40,16,255 },
|
|
|
|
{ 21,11,10,15,255 }, // if demo: { 21,11,10,16,255 },
|
|
{ 21,11,20,15,255 }, // if demo: { 21,11,20,16,255 },
|
|
{ 21, 0,20,15,255 }, // if demo: { 21,0,20,16,255 },
|
|
{ 21,22,20,15,255 }, // if demo: { 21,22,20,16,255 },
|
|
{ 21,33,20,15,255 }, // if demo: { 21,33,20,16,255 },
|
|
{ 21,44,20,15,255 }, // if demo: { 21,44,20,16,255 },
|
|
{ 21,44,10,15,255 }, // if demo: { 21,44,10,16,255 },
|
|
|
|
{ 22,22,10,16,255 },
|
|
{ 22,22,20,16,255 },
|
|
|
|
{ 23,22,30,13,255 },
|
|
{ 23,22,40,13,255 },
|
|
{ 23,33,40,13,255 },
|
|
{ 23,11,40,13,255 },
|
|
{ 23,0,40,13,255 },
|
|
{ 23,0,50,13,255 },
|
|
|
|
{ 25,11,40,16,255 },
|
|
{ 25,11,50,16,255 },
|
|
{ 25,0,50,16,255 },
|
|
|
|
{ 27,11,20,16,255 },
|
|
{ 27,11,30,16,255 },
|
|
|
|
{ 29,11,10,16,255 },
|
|
|
|
{ 45,22,30,12,255 },
|
|
{ 45,22,40,12,255 },
|
|
{ 45,22,50,12,255 },
|
|
|
|
{ 46,22,40,12,255 },
|
|
{ 46,11,50,12,255 },
|
|
{ 46,22,50,12,255 },
|
|
{ 46,33,50,12,255 },
|
|
|
|
{ 47,0,0,12,255 },
|
|
|
|
{ 26,22,20,16,255 },
|
|
{ 26,33,10,16,255 },
|
|
{ 26,33,20,16,255 },
|
|
{ 26,33,30,16,255 },
|
|
{ 26,44,30,16,255 },
|
|
{ 26,22,30,16,255 },
|
|
{ 26,11,30,16,255 },
|
|
{ 26,11,20,16,255 },
|
|
{ 26,0,20,16,255 },
|
|
{ 26,11,40,16,255 },
|
|
{ 26,0,40,16,255 },
|
|
{ 26,22,40,16,255 },
|
|
{ 26,11,50,16,255 },
|
|
|
|
{ 28,0,30,15,255 },
|
|
{ 28,0,20,15,255 },
|
|
{ 28,0,40,15,255 },
|
|
{ 28,11,30,15,255 },
|
|
{ 28,11,20,15,255 },
|
|
{ 28,22,30,15,255 },
|
|
{ 28,22,20,15,255 },
|
|
|
|
{ 255,255,255,255,255 }
|
|
|
|
};
|
|
|
|
void DreamWebEngine::dreamwebFinalize() {
|
|
// The engine will need some cleaner finalization (destructor?), let's put
|
|
// it here for now
|
|
|
|
getRidOfAll();
|
|
|
|
_icons1.clear();
|
|
_icons2.clear();
|
|
_charset1.clear();
|
|
_mainSprites.clear();
|
|
|
|
// clear local graphics, just in case
|
|
_keypadGraphics.clear();
|
|
_menuGraphics.clear();
|
|
_menuGraphics2.clear();
|
|
_folderGraphics.clear();
|
|
_folderGraphics2.clear();
|
|
_folderGraphics3.clear();
|
|
_folderCharset.clear();
|
|
_symbolGraphics.clear();
|
|
_diaryGraphics.clear();
|
|
_diaryCharset.clear();
|
|
_monitorGraphics.clear();
|
|
_monitorCharset.clear();
|
|
_newplaceGraphics.clear();
|
|
_newplaceGraphics2.clear();
|
|
_newplaceGraphics3.clear();
|
|
_cityGraphics.clear();
|
|
_saveGraphics.clear();
|
|
|
|
_exFrames.clear();
|
|
_exText.clear();
|
|
|
|
_setFrames.clear();
|
|
_freeFrames.clear();
|
|
_reel1.clear();
|
|
_reel2.clear();
|
|
_reel3.clear();
|
|
_setDesc.clear();
|
|
_blockDesc.clear();
|
|
_roomDesc.clear();
|
|
_freeDesc.clear();
|
|
_personText.clear();
|
|
|
|
_textFile1.clear();
|
|
_textFile2.clear();
|
|
_textFile3.clear();
|
|
_travelText.clear();
|
|
_puzzleText.clear();
|
|
_commandText.clear();
|
|
}
|
|
|
|
void DreamWebEngine::dreamweb() {
|
|
switch(getLanguage()) {
|
|
case Common::EN_ANY:
|
|
case Common::EN_GRB:
|
|
case Common::EN_USA:
|
|
_foreignRelease = false;
|
|
break;
|
|
default:
|
|
_foreignRelease = true;
|
|
break;
|
|
}
|
|
|
|
allocateBuffers();
|
|
|
|
// setMouse
|
|
_oldPointerX = 0xffff;
|
|
|
|
fadeDOS();
|
|
getTime();
|
|
clearBuffers();
|
|
clearPalette();
|
|
set16ColPalette();
|
|
readSetData();
|
|
_wonGame = false;
|
|
|
|
_sound->loadSounds(0, "V99"); // basic sample
|
|
|
|
bool firstLoop = true;
|
|
|
|
int savegameId = Common::ConfigManager::instance().getInt("save_slot");
|
|
|
|
while (true) {
|
|
uint count = scanForNames();
|
|
|
|
bool startNewGame = true;
|
|
|
|
if (firstLoop && savegameId >= 0) {
|
|
// loading a savegame requested from launcher/command line
|
|
|
|
cls();
|
|
setMode();
|
|
loadPalFromIFF();
|
|
clearPalette();
|
|
|
|
doLoad(savegameId);
|
|
workToScreen();
|
|
fadeScreenUp();
|
|
startNewGame = false;
|
|
|
|
} else if (count == 0 && firstLoop) {
|
|
|
|
// no savegames found, and we're not restarting.
|
|
|
|
setMode();
|
|
loadPalFromIFF();
|
|
|
|
} else {
|
|
// "doDecisions"
|
|
|
|
// Savegames found, so ask if we should load one.
|
|
// (If we're restarting after game over, we also always show these
|
|
// options.)
|
|
|
|
cls();
|
|
setMode();
|
|
decide();
|
|
if (_quitRequested)
|
|
return;
|
|
|
|
if (_getBack == 4)
|
|
startNewGame = false; // savegame has been loaded
|
|
}
|
|
|
|
firstLoop = false;
|
|
|
|
if (startNewGame) {
|
|
// "playGame"
|
|
|
|
// "titles"
|
|
// TODO: In the demo version, titles() did nothing
|
|
clearPalette();
|
|
bibleQuote();
|
|
if (!_quitRequested) // "titlesearly"
|
|
intro();
|
|
|
|
if (_quitRequested)
|
|
return;
|
|
|
|
// "credits"
|
|
clearPalette();
|
|
realCredits();
|
|
|
|
if (_quitRequested)
|
|
return;
|
|
|
|
clearChanges();
|
|
setMode();
|
|
loadPalFromIFF();
|
|
_vars._location = 255;
|
|
_vars._roomAfterDream = 1;
|
|
_newLocation = 35;
|
|
_sound->volumeSet(7);
|
|
loadRoom();
|
|
clearSprites();
|
|
initMan();
|
|
entryTexts();
|
|
entryAnims();
|
|
_destPos = 3;
|
|
initialInv();
|
|
_lastFlag = 32;
|
|
startup1();
|
|
_sound->volumeChange(0, -1);
|
|
_commandType = 255;
|
|
}
|
|
|
|
// main loop
|
|
while (true) {
|
|
if (_quitRequested)
|
|
return;
|
|
|
|
screenUpdate();
|
|
|
|
if (_quitRequested)
|
|
return;
|
|
|
|
if (_wonGame) {
|
|
// "endofgame"
|
|
clearBeforeLoad();
|
|
fadeScreenDowns();
|
|
hangOn(200);
|
|
endGame();
|
|
return;
|
|
}
|
|
|
|
if (_vars._manDead == 1 || _vars._manDead == 2)
|
|
break;
|
|
|
|
if (_vars._watchingTime > 0) {
|
|
if (_finalDest == _mansPath)
|
|
_vars._watchingTime--;
|
|
}
|
|
|
|
if (_vars._watchingTime == 0) {
|
|
// "notWatching"
|
|
|
|
if (_vars._manDead == 4)
|
|
break;
|
|
|
|
if (_newLocation != 255) {
|
|
// "loadNew"
|
|
clearBeforeLoad();
|
|
loadRoom();
|
|
clearSprites();
|
|
initMan();
|
|
entryTexts();
|
|
entryAnims();
|
|
_newLocation = 255;
|
|
startup();
|
|
_commandType = 255;
|
|
workToScreenM();
|
|
}
|
|
}
|
|
}
|
|
|
|
// "gameOver"
|
|
clearBeforeLoad();
|
|
showGun();
|
|
fadeScreenDown();
|
|
hangOn(100);
|
|
|
|
}
|
|
}
|
|
|
|
void DreamWebEngine::loadTextFile(TextFile &file, const char *suffix) {
|
|
Common::String fileName = getDatafilePrefix() + suffix;
|
|
FileHeader header;
|
|
|
|
Common::File f;
|
|
f.open(fileName);
|
|
f.read((uint8 *)&header, sizeof(FileHeader));
|
|
uint16 sizeInBytes = header.len(0);
|
|
assert(sizeInBytes >= 2*66);
|
|
|
|
delete[] file._text;
|
|
file._text = new char[sizeInBytes - 2*66];
|
|
|
|
f.read(file._offsetsLE, 2*66);
|
|
f.read(file._text, sizeInBytes - 2*66);
|
|
}
|
|
|
|
void DreamWebEngine::screenUpdate() {
|
|
newPlace();
|
|
mainScreen();
|
|
if (_quitRequested)
|
|
return;
|
|
animPointer();
|
|
|
|
showPointer();
|
|
if ((_vars._watchingTime == 0) && (_newLocation != 0xff))
|
|
return;
|
|
waitForVSync();
|
|
uint16 mouseState = 0;
|
|
mouseState |= readMouseState();
|
|
dumpPointer();
|
|
|
|
dumpTextLine();
|
|
delPointer();
|
|
autoLook();
|
|
spriteUpdate();
|
|
watchCount();
|
|
zoom();
|
|
|
|
showPointer();
|
|
if (_wonGame)
|
|
return;
|
|
waitForVSync();
|
|
mouseState |= readMouseState();
|
|
dumpPointer();
|
|
|
|
dumpZoom();
|
|
delPointer();
|
|
delEverything();
|
|
printSprites();
|
|
reelsOnScreen();
|
|
afterNewRoom();
|
|
|
|
showPointer();
|
|
waitForVSync();
|
|
mouseState |= readMouseState();
|
|
dumpPointer();
|
|
|
|
dumpMap();
|
|
dumpTimedText();
|
|
delPointer();
|
|
|
|
showPointer();
|
|
waitForVSync();
|
|
_oldButton = _mouseButton;
|
|
mouseState |= readMouseState();
|
|
_mouseButton = mouseState;
|
|
dumpPointer();
|
|
|
|
dumpWatch();
|
|
delPointer();
|
|
}
|
|
|
|
void DreamWebEngine::startup() {
|
|
_currentKey = 0;
|
|
_mainMode = 0;
|
|
createPanel();
|
|
_vars._newObs = 1;
|
|
drawFloor();
|
|
showIcon();
|
|
getUnderZoom();
|
|
spriteUpdate();
|
|
printSprites();
|
|
underTextLine();
|
|
reelsOnScreen();
|
|
atmospheres();
|
|
}
|
|
|
|
void DreamWebEngine::startup1() {
|
|
clearPalette();
|
|
_vars._throughDoor = 0;
|
|
|
|
startup();
|
|
|
|
workToScreen();
|
|
fadeScreenUp();
|
|
}
|
|
|
|
void DreamWebEngine::switchRyanOn() {
|
|
_vars._ryanOn = 255;
|
|
}
|
|
|
|
void DreamWebEngine::switchRyanOff() {
|
|
_vars._ryanOn = 1;
|
|
}
|
|
|
|
void DreamWebEngine::loadGraphicsFile(GraphicsFile &file, const char *suffix) {
|
|
Common::String fileName = getDatafilePrefix() + suffix;
|
|
FileHeader header;
|
|
|
|
Common::File f;
|
|
f.open(fileName);
|
|
f.read((uint8 *)&header, sizeof(FileHeader));
|
|
uint16 sizeInBytes = header.len(0);
|
|
|
|
assert(sizeInBytes >= kFrameBlocksize);
|
|
file.clear();
|
|
file._data = new uint8[sizeInBytes - kFrameBlocksize];
|
|
file._frames = new Frame[kGraphicsFileFrameSize];
|
|
f.read((uint8 *)file._frames, kFrameBlocksize);
|
|
f.read(file._data, sizeInBytes - kFrameBlocksize);
|
|
}
|
|
|
|
void DreamWebEngine::loadGraphicsSegment(GraphicsFile &file, Common::File &inFile, unsigned int len) {
|
|
assert(len >= kFrameBlocksize);
|
|
file.clear();
|
|
file._data = new uint8[len - kFrameBlocksize];
|
|
file._frames = new Frame[kGraphicsFileFrameSize];
|
|
inFile.read((uint8 *)file._frames, kFrameBlocksize);
|
|
inFile.read(file._data, len - kFrameBlocksize);
|
|
}
|
|
|
|
void DreamWebEngine::loadTextSegment(TextFile &file, Common::File &inFile, unsigned int len) {
|
|
const uint headerSize = 2 * file._size;
|
|
assert(len >= headerSize);
|
|
delete[] file._text;
|
|
file._text = new char[len - headerSize];
|
|
inFile.read((uint8 *)file._offsetsLE, headerSize);
|
|
inFile.read((uint8 *)file._text, len - headerSize);
|
|
}
|
|
|
|
void DreamWebEngine::hangOnCurs(uint16 frameCount) {
|
|
for (uint16 i = 0; i < frameCount; ++i) {
|
|
printCurs();
|
|
waitForVSync();
|
|
delCurs();
|
|
}
|
|
}
|
|
|
|
void DreamWebEngine::dumpTextLine() {
|
|
if (_newTextLine != 1)
|
|
return;
|
|
_newTextLine = 0;
|
|
uint16 x = _textAddressX;
|
|
uint16 y = _textAddressY;
|
|
if (_foreignRelease)
|
|
y -= 3;
|
|
multiDump(x, y, 228, 13);
|
|
}
|
|
|
|
void DreamWebEngine::getUnderTimed() {
|
|
if (_foreignRelease)
|
|
multiGet(_underTimedText, _timedTemp._x, _timedTemp._y - 3, 240, kUnderTimedTextSizeY_f);
|
|
else
|
|
multiGet(_underTimedText, _timedTemp._x, _timedTemp._y, 240, kUnderTimedTextSizeY);
|
|
}
|
|
|
|
void DreamWebEngine::putUnderTimed() {
|
|
if (_foreignRelease)
|
|
multiPut(_underTimedText, _timedTemp._x, _timedTemp._y - 3, 240, kUnderTimedTextSizeY_f);
|
|
else
|
|
multiPut(_underTimedText, _timedTemp._x, _timedTemp._y, 240, kUnderTimedTextSizeY);
|
|
}
|
|
|
|
void DreamWebEngine::triggerMessage(uint16 index) {
|
|
multiGet(_mapStore, 174, 153, 200, 63);
|
|
const uint8 *string = (const uint8 *)_puzzleText.getString(index);
|
|
uint16 y = 156;
|
|
printDirect(&string, 174, &y, 141, true);
|
|
hangOn(140);
|
|
workToScreen();
|
|
hangOn(340);
|
|
multiPut(_mapStore, 174, 153, 200, 63);
|
|
workToScreen();
|
|
_vars._lastTrigger = 0;
|
|
}
|
|
|
|
void DreamWebEngine::processTrigger() {
|
|
if (_vars._lastTrigger == '1') {
|
|
setLocation(8);
|
|
triggerMessage(45);
|
|
} else if (_vars._lastTrigger == '2') {
|
|
setLocation(9);
|
|
triggerMessage(55);
|
|
} else if (_vars._lastTrigger == '3') {
|
|
setLocation(2);
|
|
triggerMessage(59);
|
|
}
|
|
}
|
|
|
|
void DreamWebEngine::useTimedText() {
|
|
if (_previousTimedTemp._string) {
|
|
// TODO: It might be nice to make subtitles wait for the speech
|
|
// to finish (_sound->isChannel1Playing()) when we're in speech+subtitles mode,
|
|
// instead of waiting the pre-specified amount of time.
|
|
|
|
|
|
// Ugly... (Maybe make this an argument to putUnderTimed()?)
|
|
TimedTemp t = _timedTemp;
|
|
_timedTemp = _previousTimedTemp;
|
|
|
|
// Force-reset the previous string to make room for the next one
|
|
putUnderTimed();
|
|
|
|
_timedTemp = t;
|
|
return;
|
|
}
|
|
|
|
if (_timeCount == 0)
|
|
return;
|
|
--_timeCount;
|
|
if (_timeCount == 0) {
|
|
putUnderTimed();
|
|
_needToDumpTimed = 1;
|
|
return;
|
|
}
|
|
|
|
if (_timeCount == _timedTemp._countToTimed)
|
|
getUnderTimed();
|
|
else if (_timeCount > _timedTemp._countToTimed)
|
|
return;
|
|
|
|
const uint8 *string = (const uint8 *)_timedTemp._string;
|
|
printDirect(string, _timedTemp._x, _timedTemp._y, 237, true);
|
|
_needToDumpTimed = 1;
|
|
}
|
|
|
|
void DreamWebEngine::setupTimedTemp(uint8 textIndex, uint8 voiceIndex, uint8 x, uint8 y, uint16 countToTimed, uint16 timeCount) {
|
|
|
|
if (hasSpeech() && voiceIndex != 0) {
|
|
_speechLoaded = _sound->loadSpeech('T', voiceIndex, 'T', textIndex);
|
|
if (_speechLoaded)
|
|
_sound->playChannel1(62);
|
|
|
|
if (_speechLoaded && !_subtitles)
|
|
return;
|
|
|
|
if (_timeCount != 0) {
|
|
// store previous TimedTemp for deletion
|
|
_previousTimedTemp = _timedTemp;
|
|
_timeCount = 0;
|
|
}
|
|
}
|
|
|
|
if (_timeCount != 0)
|
|
return;
|
|
|
|
_timedTemp._y = y;
|
|
_timedTemp._x = x;
|
|
_timedTemp._countToTimed = countToTimed;
|
|
_timeCount = _timedTemp._timeCount = timeCount + countToTimed;
|
|
_timedTemp._string = _textFile1.getString(textIndex);
|
|
debug(1, "setupTimedTemp: (%d, %d) => '%s'", textIndex, voiceIndex, _timedTemp._string);
|
|
}
|
|
|
|
void DreamWebEngine::dumpTimedText() {
|
|
const TimedTemp *tt;
|
|
if (_previousTimedTemp._string) {
|
|
assert(!_needToDumpTimed);
|
|
|
|
tt = &_previousTimedTemp;
|
|
_previousTimedTemp._string = 0;
|
|
_previousTimedTemp._timeCount = 0;
|
|
} else if (_needToDumpTimed != 1) {
|
|
return;
|
|
} else {
|
|
tt = &_timedTemp;
|
|
_needToDumpTimed = 0;
|
|
}
|
|
|
|
const uint16 kUndertimedysize = 30;
|
|
uint8 y = tt->_y;
|
|
if (_foreignRelease)
|
|
y -= 3;
|
|
|
|
multiDump(tt->_x, y, 240, kUndertimedysize);
|
|
}
|
|
|
|
void DreamWebEngine::getTime() {
|
|
TimeDate t;
|
|
g_system->getTimeAndDate(t);
|
|
debug(1, "\tgettime: %02d:%02d:%02d", t.tm_hour, t.tm_min, t.tm_sec);
|
|
_vars._secondCount = t.tm_sec;
|
|
_vars._minuteCount = t.tm_min;
|
|
_vars._hourCount = t.tm_hour;
|
|
}
|
|
|
|
void DreamWebEngine::DOSReturn() {
|
|
commandOnlyCond(46, 250);
|
|
|
|
if (_mouseButton & 1) {
|
|
_mouseButton = 0;
|
|
quit();
|
|
}
|
|
}
|
|
|
|
void DreamWebEngine::eraseOldObs() {
|
|
if (_vars._newObs == 0)
|
|
return;
|
|
|
|
// Note: the original didn't delete sprites here, but marked the
|
|
// entries as unused, to be filled again by makeSprite. This can
|
|
// change the order of entries, but since they are drawn based on the
|
|
// priority field, this shouldn't matter.
|
|
Common::List<Sprite>::iterator i;
|
|
for (i = _spriteTable.begin(); i != _spriteTable.end(); ) {
|
|
Sprite &sprite = *i;
|
|
if (sprite._objData)
|
|
i = _spriteTable.erase(i);
|
|
else
|
|
++i;
|
|
}
|
|
}
|
|
|
|
void DreamWebEngine::lockMon() {
|
|
// Pressing space pauses text output in the monitor. We use the "hard"
|
|
// key because calling readkey() drains characters from the input
|
|
// buffer, we we want the user to be able to type ahead while the text
|
|
// is being printed.
|
|
if (_lastHardKey == 57) {
|
|
// Clear the keyboard buffer. Otherwise the space that caused
|
|
// the pause will be read immediately unpause the game.
|
|
do {
|
|
readKey();
|
|
} while (_currentKey != 0);
|
|
|
|
lockLightOn();
|
|
while (!shouldQuit()) {
|
|
waitForVSync();
|
|
readKey();
|
|
if (_currentKey == ' ')
|
|
break;
|
|
}
|
|
// Forget the last "hard" key, otherwise the space that caused
|
|
// the unpausing will immediately re-pause the game.
|
|
_lastHardKey = 0;
|
|
lockLightOff();
|
|
}
|
|
}
|
|
|
|
void DreamWebEngine::startLoading(const Room &room) {
|
|
_vars._combatCount = 0;
|
|
_roomsSample = room.roomsSample;
|
|
_mapX = room.mapX;
|
|
_mapY = room.mapY;
|
|
_vars._liftFlag = room.liftFlag;
|
|
_mansPath = room.b21;
|
|
_destination = room.b21;
|
|
_finalDest = room.b21;
|
|
_facing = room.facing;
|
|
_turnToFace = room.facing;
|
|
_vars._countToOpen = room.countToOpen;
|
|
_vars._liftPath = room.liftPath;
|
|
_vars._doorPath = room.doorPath;
|
|
_vars._lastWeapon = (uint8)-1;
|
|
_realLocation = room.realLocation;
|
|
|
|
loadRoomData(room, false);
|
|
|
|
findRoomInLoc();
|
|
deleteTaken();
|
|
setAllChanges();
|
|
autoAppear();
|
|
// const Room &newRoom = g_roomData[_newLocation];
|
|
_vars._lastWeapon = (uint8)-1;
|
|
_vars._manDead = 0;
|
|
_lookCounter = 160;
|
|
_newLocation = 255;
|
|
_linePointer = 254;
|
|
if (room.b27 != 255) {
|
|
_mansPath = room.b27;
|
|
autoSetWalk();
|
|
}
|
|
findXYFromPath();
|
|
}
|
|
|
|
void DreamWebEngine::dealWithSpecial(uint8 firstParam, uint8 secondParam) {
|
|
uint8 type = firstParam - 220;
|
|
if (type == 0) {
|
|
placeSetObject(secondParam);
|
|
_haveDoneObs = 1;
|
|
} else if (type == 1) {
|
|
removeSetObject(secondParam);
|
|
_haveDoneObs = 1;
|
|
} else if (type == 2) {
|
|
placeFreeObject(secondParam);
|
|
_haveDoneObs = 1;
|
|
} else if (type == 3) {
|
|
removeFreeObject(secondParam);
|
|
_haveDoneObs = 1;
|
|
} else if (type == 4) {
|
|
switchRyanOff();
|
|
} else if (type == 5) {
|
|
_turnToFace = secondParam;
|
|
_facing = secondParam;
|
|
switchRyanOn();
|
|
} else if (type == 6) {
|
|
_newLocation = secondParam;
|
|
} else {
|
|
moveMap(secondParam);
|
|
}
|
|
}
|
|
|
|
void DreamWebEngine::plotReel(uint16 &reelPointer) {
|
|
Reel *reel = getReelStart(reelPointer);
|
|
while (reel->x >= 220 && reel->x != 255) {
|
|
dealWithSpecial(reel->x, reel->y);
|
|
++reelPointer;
|
|
reel += 8;
|
|
}
|
|
|
|
for (size_t i = 0; i < 8; ++i) {
|
|
if (reel->frame() != 0xffff)
|
|
showReelFrame(reel);
|
|
++reel;
|
|
}
|
|
soundOnReels(reelPointer);
|
|
}
|
|
|
|
void DreamWebEngine::delTextLine() {
|
|
if (_foreignRelease)
|
|
multiPut(_textUnder, _textAddressX, _textAddressY - 3, kUnderTextSizeX_f, kUnderTextSizeY_f);
|
|
else
|
|
multiPut(_textUnder, _textAddressX, _textAddressY, kUnderTextSizeX, kUnderTextSizeY);
|
|
}
|
|
|
|
void DreamWebEngine::commandOnlyCond(uint8 command, uint8 commandType) {
|
|
if (_commandType != commandType) {
|
|
_commandType = commandType;
|
|
commandOnly(command);
|
|
}
|
|
}
|
|
|
|
void DreamWebEngine::commandOnly(uint8 command) {
|
|
delTextLine();
|
|
const uint8 *string = (const uint8 *)_commandText.getString(command);
|
|
printDirect(string, _textAddressX, _textAddressY, _textLen, (bool)(_textLen & 1));
|
|
_newTextLine = 1;
|
|
}
|
|
|
|
bool DreamWebEngine::checkIfPerson(uint8 x, uint8 y) {
|
|
Common::List<People>::iterator i;
|
|
for (i = _peopleList.begin(); i != _peopleList.end(); ++i) {
|
|
People &people = *i;
|
|
Reel *reel = getReelStart(people._reelPointer);
|
|
if (reel->frame() == 0xffff)
|
|
++reel;
|
|
const Frame *frame = getReelFrameAX(reel->frame());
|
|
uint8 xmin = reel->x + frame->x;
|
|
uint8 ymin = reel->y + frame->y;
|
|
uint8 xmax = xmin + frame->width;
|
|
uint8 ymax = ymin + frame->height;
|
|
if (x < xmin)
|
|
continue;
|
|
if (y < ymin)
|
|
continue;
|
|
if (x >= xmax)
|
|
continue;
|
|
if (y >= ymax)
|
|
continue;
|
|
_personData = people._routinePointer;
|
|
obName(people.b4, 5);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool DreamWebEngine::checkIfFree(uint8 x, uint8 y) {
|
|
Common::List<ObjPos>::const_iterator i;
|
|
for (i = _freeList.reverse_begin(); i != _freeList.end(); --i) {
|
|
const ObjPos &pos = *i;
|
|
assert(pos.index != 0xff);
|
|
if (!pos.contains(x,y))
|
|
continue;
|
|
obName(pos.index, 2);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool DreamWebEngine::checkIfEx(uint8 x, uint8 y) {
|
|
Common::List<ObjPos>::const_iterator i;
|
|
for (i = _exList.reverse_begin(); i != _exList.end(); --i) {
|
|
const ObjPos &pos = *i;
|
|
assert(pos.index != 0xff);
|
|
if (!pos.contains(x,y))
|
|
continue;
|
|
obName(pos.index, 4);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
const uint8 *DreamWebEngine::findObName(uint8 type, uint8 index) {
|
|
switch (type) {
|
|
case 5:
|
|
return (const uint8 *)_personText.getString(64 * (index & 127));
|
|
case kExObjectType:
|
|
return (const uint8 *)_exText.getString(index);
|
|
case kFreeObjectType:
|
|
return (const uint8 *)_freeDesc.getString(index);
|
|
case kSetObjectType1:
|
|
return (const uint8 *)_setDesc.getString(index);
|
|
default:
|
|
return (const uint8 *)_blockDesc.getString(index);
|
|
}
|
|
}
|
|
|
|
void DreamWebEngine::copyName(uint8 type, uint8 index, uint8 *dst) {
|
|
const uint8 *src = findObName(type, index);
|
|
size_t i;
|
|
for (i = 0; i < 28; ++i) {
|
|
char c = src[i];
|
|
if (c == ':')
|
|
break;
|
|
if (c == 0)
|
|
break;
|
|
dst[i] = c;
|
|
}
|
|
dst[i] = 0;
|
|
}
|
|
|
|
void DreamWebEngine::commandWithOb(uint8 command, uint8 type, uint8 index) {
|
|
uint8 commandLine[64] = "OBJECT NAME ONE ";
|
|
delTextLine();
|
|
uint8 textLen = _textLen;
|
|
|
|
const uint8 *string = (const uint8 *)_commandText.getString(command);
|
|
printDirect(string, _textAddressX, _textAddressY, textLen, (bool)(textLen & 1));
|
|
|
|
copyName(type, index, commandLine);
|
|
uint16 x = _lastXPos;
|
|
if (command != 0)
|
|
x += 5;
|
|
printDirect(commandLine, x, _textAddressY, textLen, (bool)(textLen & 1));
|
|
_newTextLine = 1;
|
|
}
|
|
|
|
void DreamWebEngine::examineObText() {
|
|
commandWithOb(1, _commandType, _command);
|
|
}
|
|
|
|
void DreamWebEngine::blockNameText() {
|
|
commandWithOb(0, _commandType, _command);
|
|
}
|
|
|
|
void DreamWebEngine::personNameText() {
|
|
commandWithOb(2, _commandType, _command & 127);
|
|
}
|
|
|
|
void DreamWebEngine::walkToText() {
|
|
commandWithOb(3, _commandType, _command);
|
|
}
|
|
|
|
void DreamWebEngine::findOrMake(uint8 index, uint8 value, uint8 type) {
|
|
Change *change = _listOfChanges;
|
|
for (; change->index != 0xff; ++change) {
|
|
if (index == change->index && _realLocation == change->location && type == change->type) {
|
|
change->value = value;
|
|
return;
|
|
}
|
|
}
|
|
|
|
change->index = index;
|
|
change->location = _realLocation;
|
|
change->value = value;
|
|
change->type = type;
|
|
}
|
|
|
|
void DreamWebEngine::setAllChanges() {
|
|
Change *change = _listOfChanges;
|
|
for (; change->index != 0xff; ++change)
|
|
if (change->location == _realLocation)
|
|
doChange(change->index, change->value, change->type);
|
|
}
|
|
|
|
DynObject *DreamWebEngine::getFreeAd(uint8 index) {
|
|
return &_freeDat[index];
|
|
}
|
|
|
|
DynObject *DreamWebEngine::getExAd(uint8 index) {
|
|
return &_exData[index];
|
|
}
|
|
|
|
DynObject *DreamWebEngine::getEitherAd() {
|
|
if (_objectType == kExObjectType)
|
|
return getExAd(_itemFrame);
|
|
else
|
|
return getFreeAd(_itemFrame);
|
|
}
|
|
|
|
void *DreamWebEngine::getAnyAd(uint8 *slotSize, uint8 *slotCount) {
|
|
if (_objectType == kExObjectType) {
|
|
DynObject *exObject = getExAd(_command);
|
|
*slotSize = exObject->slotSize;
|
|
*slotCount = exObject->slotCount;
|
|
return exObject;
|
|
} else if (_objectType == kFreeObjectType) {
|
|
DynObject *freeObject = getFreeAd(_command);
|
|
*slotSize = freeObject->slotSize;
|
|
*slotCount = freeObject->slotCount;
|
|
return freeObject;
|
|
} else { // 1 or 3. 0 should never happen
|
|
SetObject *setObject = getSetAd(_command);
|
|
// Note: the original returned slotCount/priority (bytes 4 and 5)
|
|
// instead of slotSize/slotCount (bytes 3 and 4).
|
|
// Changed this for consistency with the Ex/Free cases, and also
|
|
// with getOpenedSize()
|
|
*slotSize = setObject->slotSize;
|
|
*slotCount = setObject->slotCount;
|
|
return setObject;
|
|
}
|
|
}
|
|
|
|
void *DreamWebEngine::getAnyAdDir(uint8 index, uint8 flag) {
|
|
if (flag == kExObjectType)
|
|
return getExAd(index);
|
|
else if (flag == kFreeObjectType)
|
|
return getFreeAd(index);
|
|
else
|
|
return getSetAd(index);
|
|
}
|
|
|
|
SetObject *DreamWebEngine::getSetAd(uint8 index) {
|
|
return &_setDat[index];
|
|
}
|
|
|
|
void DreamWebEngine::doChange(uint8 index, uint8 value, uint8 type) {
|
|
if (type == 0) { //object
|
|
getSetAd(index)->mapad[0] = value;
|
|
} else if (type == 1) { //freeObject
|
|
DynObject *freeObject = getFreeAd(index);
|
|
if (freeObject->mapad[0] == 0xff)
|
|
freeObject->mapad[0] = value;
|
|
} else { //path
|
|
_pathData[type - 100].nodes[index].on = value;
|
|
}
|
|
}
|
|
|
|
void DreamWebEngine::deleteTaken() {
|
|
for (size_t i = 0; i < kNumexobjects; ++i) {
|
|
uint8 location = _exData[i].initialLocation;
|
|
if (location == _realLocation) {
|
|
uint8 index = _exData[i].index;
|
|
_freeDat[index].mapad[0] = 0xfe;
|
|
}
|
|
}
|
|
}
|
|
|
|
uint8 DreamWebEngine::getExPos() {
|
|
DynObject *objects = _exData;
|
|
for (size_t i = 0; i < kNumexobjects; ++i) {
|
|
if (objects[i].mapad[0] == 0xff)
|
|
return i;
|
|
}
|
|
error("Out of Ex object positions");
|
|
}
|
|
|
|
void DreamWebEngine::placeSetObject(uint8 index) {
|
|
findOrMake(index, 0, 0);
|
|
getSetAd(index)->mapad[0] = 0;
|
|
}
|
|
|
|
void DreamWebEngine::removeSetObject(uint8 index) {
|
|
findOrMake(index, 0xff, 0);
|
|
getSetAd(index)->mapad[0] = 0xff;
|
|
}
|
|
|
|
bool DreamWebEngine::finishedWalking() {
|
|
return (_linePointer == 254) && (_facing == _turnToFace);
|
|
}
|
|
|
|
void DreamWebEngine::getFlagUnderP(uint8 *flag, uint8 *flagEx) {
|
|
uint8 type, flagX, flagY;
|
|
checkOne(_mouseX - _mapAdX, _mouseY - _mapAdY, flag, flagEx, &type, &flagX, &flagY);
|
|
_lastFlag = *flag;
|
|
}
|
|
|
|
void DreamWebEngine::walkAndExamine() {
|
|
if (!finishedWalking())
|
|
return;
|
|
_commandType = _walkExamType;
|
|
_command = _walkExamNum;
|
|
_walkAndExam = 0;
|
|
if (_commandType != 5)
|
|
examineOb();
|
|
}
|
|
|
|
void DreamWebEngine::obName(uint8 command, uint8 commandType) {
|
|
if (_reAssesChanges == 0) {
|
|
if ((commandType == _commandType) && (command == _command)) {
|
|
if (_walkAndExam == 1) {
|
|
walkAndExamine();
|
|
return;
|
|
} else if (_mouseButton == 0)
|
|
return;
|
|
else if ((_commandType == 3) && (_lastFlag < 2))
|
|
return;
|
|
else if ((_mansPath != _pointersPath) || (_commandType == 3)) {
|
|
setWalk();
|
|
_reAssesChanges = 1;
|
|
return;
|
|
} else if (!finishedWalking())
|
|
return;
|
|
else if (_commandType == 5) {
|
|
if (_vars._watchingTime == 0)
|
|
talk();
|
|
return;
|
|
} else {
|
|
if (_vars._watchingTime == 0)
|
|
examineOb();
|
|
return;
|
|
}
|
|
}
|
|
} else
|
|
_reAssesChanges = 0;
|
|
|
|
_command = command;
|
|
_commandType = commandType;
|
|
if ((_linePointer != 254) || (_vars._watchingTime != 0) || (_facing != _turnToFace)) {
|
|
blockNameText();
|
|
return;
|
|
} else if (_commandType != 3) {
|
|
if (_mansPath != _pointersPath) {
|
|
walkToText();
|
|
return;
|
|
} else if (_commandType == 3) {
|
|
blockNameText();
|
|
return;
|
|
} else if (_commandType == 5) {
|
|
personNameText();
|
|
return;
|
|
} else {
|
|
examineObText();
|
|
return;
|
|
}
|
|
}
|
|
if (_mansPath == _pointersPath) {
|
|
uint8 flag, flagEx, type, flagX, flagY;
|
|
checkOne(_ryanX + 12, _ryanY + 12, &flag, &flagEx, &type, &flagX, &flagY);
|
|
if (flag < 2) {
|
|
blockNameText();
|
|
return;
|
|
}
|
|
}
|
|
|
|
uint8 flag, flagEx;
|
|
getFlagUnderP(&flag, &flagEx);
|
|
if (_lastFlag < 2) {
|
|
blockNameText();
|
|
return;
|
|
} else if (_lastFlag >= 128) {
|
|
blockNameText();
|
|
return;
|
|
} else {
|
|
walkToText();
|
|
return;
|
|
}
|
|
}
|
|
|
|
void DreamWebEngine::showBlink() {
|
|
if (_manIsOffScreen == 1)
|
|
return;
|
|
++_blinkCount;
|
|
if (_vars._shadesOn != 0)
|
|
return;
|
|
if (_realLocation >= 50) // eyesshut
|
|
return;
|
|
if (_blinkCount != 3)
|
|
return;
|
|
_blinkCount = 0;
|
|
uint8 blinkFrame = _blinkFrame;
|
|
++blinkFrame; // Implicit %256
|
|
_blinkFrame = blinkFrame;
|
|
if (blinkFrame > 6)
|
|
blinkFrame = 6;
|
|
static const uint8 blinkTab[] = { 16,18,18,17,16,16,16 };
|
|
uint8 width, height;
|
|
showFrame(_icons1, 44, 32, blinkTab[blinkFrame], 0, &width, &height);
|
|
}
|
|
|
|
void DreamWebEngine::dumpBlink() {
|
|
if (_vars._shadesOn != 0)
|
|
return;
|
|
if (_blinkCount != 0)
|
|
return;
|
|
if (_blinkFrame >= 6)
|
|
return;
|
|
multiDump(44, 32, 16, 12);
|
|
}
|
|
|
|
void DreamWebEngine::printMessage(uint16 x, uint16 y, uint8 index, uint8 maxWidth, bool centered) {
|
|
const uint8 *string = (const uint8 *)_commandText.getString(index);
|
|
printDirect(string, x, y, maxWidth, centered);
|
|
}
|
|
|
|
void DreamWebEngine::printMessage2(uint16 x, uint16 y, uint8 index, uint8 maxWidth, bool centered, uint8 count) {
|
|
const uint8 *string = (const uint8 *)_commandText.getString(index);
|
|
while (count--) {
|
|
findNextColon(&string);
|
|
}
|
|
printDirect(string, x, y, maxWidth, centered);
|
|
}
|
|
|
|
bool DreamWebEngine::objectMatches(void *object, const char *id) {
|
|
const char *objId = (const char *)object + 12; // whether it is a DynObject or a SetObject
|
|
for (size_t i = 0; i < 4; ++i) {
|
|
if (id[i] != objId[i] + 'A')
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool DreamWebEngine::compare(uint8 index, uint8 flag, const char id[4]) {
|
|
return objectMatches(getAnyAdDir(index, flag), id);
|
|
}
|
|
|
|
uint16 DreamWebEngine::findSetObject(const char *id) {
|
|
for (uint16 index = 0; index < 128; index++) {
|
|
if (objectMatches(getSetAd(index), id))
|
|
return index;
|
|
}
|
|
|
|
return 128;
|
|
}
|
|
|
|
uint16 DreamWebEngine::findExObject(const char *id) {
|
|
for (uint16 index = 0; index < kNumexobjects; index++) {
|
|
if (objectMatches(getExAd(index), id))
|
|
return index;
|
|
}
|
|
|
|
return kNumexobjects;
|
|
}
|
|
|
|
bool DreamWebEngine::isRyanHolding(const char *id) {
|
|
for (uint16 index = 0; index < kNumexobjects; index++) {
|
|
DynObject *object = getExAd(index);
|
|
if (object->mapad[0] == 4 && objectMatches(object, id))
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool DreamWebEngine::isItDescribed(const ObjPos *pos) {
|
|
const char *string = _setDesc.getString(pos->index);
|
|
return string[0] != 0;
|
|
}
|
|
|
|
void DreamWebEngine::showIcon() {
|
|
if (_realLocation < 50) {
|
|
showPanel();
|
|
showMan();
|
|
roomName();
|
|
panelIcons1();
|
|
zoomIcon();
|
|
} else {
|
|
error("Unimplemented tempsprites code called");
|
|
// the tempsprites segment is never initialized, but used here.
|
|
/*
|
|
Frame *tempSprites = (Frame *)getSegment(data.word(kTempsprites)).ptr(0, 0);
|
|
showFrame(tempSprites, 72, 2, 45, 0);
|
|
showFrame(tempSprites, 72+47, 2, 46, 0);
|
|
showFrame(tempSprites, 69-10, 21, 49, 0);
|
|
showFrame(tempSprites, 160+88, 2, 45, 4 & 0xfe);
|
|
showFrame(tempSprites, 160+43, 2, 46, 4 & 0xfe);
|
|
showFrame(tempSprites, 160+101, 21, 49, 4 & 0xfe);
|
|
|
|
// middle panel
|
|
showFrame(tempSprites, 72 + 47 + 20, 0, 48, 0);
|
|
showFrame(tempSprites, 72 + 19, 21, 47, 0);
|
|
showFrame(tempSprites, 160 + 23, 0, 48, 4);
|
|
showFrame(tempSprites, 160 + 71, 21, 47, 4);
|
|
*/
|
|
}
|
|
}
|
|
|
|
bool DreamWebEngine::checkIfSet(uint8 x, uint8 y) {
|
|
Common::List<ObjPos>::const_iterator i;
|
|
for (i = _setList.reverse_begin(); i != _setList.end(); --i) {
|
|
const ObjPos &pos = *i;
|
|
assert(pos.index != 0xff);
|
|
if (!pos.contains(x,y))
|
|
continue;
|
|
if (!pixelCheckSet(&pos, x, y))
|
|
continue;
|
|
if (!isItDescribed(&pos))
|
|
continue;
|
|
obName(pos.index, 1);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void DreamWebEngine::hangOn(uint16 frameCount) {
|
|
while (frameCount) {
|
|
waitForVSync();
|
|
--frameCount;
|
|
if (_quitRequested)
|
|
break;
|
|
}
|
|
}
|
|
|
|
void DreamWebEngine::hangOnW(uint16 frameCount) {
|
|
while (frameCount) {
|
|
delPointer();
|
|
readMouse();
|
|
animPointer();
|
|
showPointer();
|
|
waitForVSync();
|
|
dumpPointer();
|
|
--frameCount;
|
|
if (_quitRequested)
|
|
break;
|
|
}
|
|
}
|
|
|
|
void DreamWebEngine::hangOnP(uint16 count) {
|
|
_mainTimer = 0;
|
|
uint8 pointerFrame = _pointerFrame;
|
|
uint8 pickup = _pickUp;
|
|
_pointerMode = 3;
|
|
_pickUp = 0;
|
|
_commandType = 255;
|
|
readMouse();
|
|
animPointer();
|
|
showPointer();
|
|
waitForVSync();
|
|
dumpPointer();
|
|
|
|
count *= 3;
|
|
for (uint16 i = 0; i < count; ++i) {
|
|
delPointer();
|
|
readMouse();
|
|
animPointer();
|
|
showPointer();
|
|
waitForVSync();
|
|
dumpPointer();
|
|
if (_quitRequested)
|
|
break;
|
|
if (_mouseButton != 0 && _mouseButton != _oldButton)
|
|
break;
|
|
}
|
|
|
|
delPointer();
|
|
_pointerFrame = pointerFrame;
|
|
_pickUp = pickup;
|
|
_pointerMode = 0;
|
|
}
|
|
|
|
uint8 DreamWebEngine::findNextColon(const uint8 **string) {
|
|
uint8 c;
|
|
do {
|
|
c = **string;
|
|
++(*string);
|
|
} while ((c != 0) && (c != ':'));
|
|
return c;
|
|
}
|
|
|
|
void DreamWebEngine::zoomOnOff() {
|
|
if (_vars._watchingTime != 0 || _pointerMode == 2) {
|
|
blank();
|
|
return;
|
|
}
|
|
|
|
commandOnlyCond(39, 222);
|
|
|
|
if (!(_mouseButton & 1) || (_mouseButton == _oldButton))
|
|
return;
|
|
|
|
_vars._zoomOn ^= 1;
|
|
createPanel();
|
|
_vars._newObs = 0;
|
|
drawFloor();
|
|
printSprites();
|
|
reelsOnScreen();
|
|
showIcon();
|
|
getUnderZoom();
|
|
underTextLine();
|
|
commandOnly(39);
|
|
readMouse();
|
|
workToScreenM();
|
|
}
|
|
|
|
void DreamWebEngine::sortOutMap() {
|
|
const uint8 *src = workspace();
|
|
uint8 *dst = _mapData;
|
|
for (uint16 y = 0; y < kMapHeight; ++y) {
|
|
memcpy(dst, src, kMapWidth);
|
|
dst += kMapWidth;
|
|
src += 132;
|
|
}
|
|
}
|
|
|
|
void DreamWebEngine::mainScreen() {
|
|
_inMapArea = 0;
|
|
if (_vars._watchOn == 1) {
|
|
RectWithCallback mainList[] = {
|
|
{ 44,70,32,46,&DreamWebEngine::look },
|
|
{ 0,50,0,180,&DreamWebEngine::inventory },
|
|
{ 226,244,10,26,&DreamWebEngine::zoomOnOff },
|
|
{ 226,244,26,40,&DreamWebEngine::saveLoad },
|
|
{ 240,260,100,124,&DreamWebEngine::madmanRun },
|
|
{ 0,320,0,200,&DreamWebEngine::identifyOb },
|
|
{ 0xFFFF,0,0,0,0 }
|
|
};
|
|
checkCoords(mainList);
|
|
} else {
|
|
RectWithCallback mainList2[] = {
|
|
{ 44,70,32,46,&DreamWebEngine::look },
|
|
{ 0,50,0,180,&DreamWebEngine::inventory },
|
|
{ 226+48,244+48,10,26,&DreamWebEngine::zoomOnOff },
|
|
{ 226+48,244+48,26,40,&DreamWebEngine::saveLoad },
|
|
{ 240,260,100,124,&DreamWebEngine::madmanRun },
|
|
{ 0,320,0,200,&DreamWebEngine::identifyOb },
|
|
{ 0xFFFF,0,0,0,0 }
|
|
};
|
|
checkCoords(mainList2);
|
|
}
|
|
|
|
if (_walkAndExam != 0)
|
|
walkAndExamine();
|
|
}
|
|
|
|
void DreamWebEngine::showWatch() {
|
|
if (_vars._watchOn) {
|
|
showFrame(_icons1, 250, 1, 6, 0);
|
|
showTime();
|
|
}
|
|
}
|
|
|
|
void DreamWebEngine::dumpWatch() {
|
|
if (_watchDump != 1)
|
|
return;
|
|
multiDump(256, 21, 40, 12);
|
|
_watchDump = 0;
|
|
}
|
|
|
|
void DreamWebEngine::showTime() {
|
|
if (_vars._watchOn == 0)
|
|
return;
|
|
|
|
int seconds = _vars._secondCount;
|
|
int minutes = _vars._minuteCount;
|
|
int hours = _vars._hourCount;
|
|
|
|
showFrame(_charset1, 282+5, 21, 91*3+10 + seconds / 10, 0);
|
|
showFrame(_charset1, 282+9, 21, 91*3+10 + seconds % 10, 0);
|
|
|
|
showFrame(_charset1, 270+5, 21, 91*3 + minutes / 10, 0);
|
|
showFrame(_charset1, 270+11, 21, 91*3 + minutes % 10, 0);
|
|
|
|
showFrame(_charset1, 256+5, 21, 91*3 + hours / 10, 0);
|
|
showFrame(_charset1, 256+11, 21, 91*3 + hours % 10, 0);
|
|
|
|
showFrame(_charset1, 267+5, 21, 91*3+20, 0);
|
|
}
|
|
|
|
void DreamWebEngine::watchCount() {
|
|
if (_vars._watchOn == 0)
|
|
return;
|
|
++_timerCount;
|
|
if (_timerCount == 9) {
|
|
showFrame(_charset1, 268+4, 21, 91*3+21, 0);
|
|
_watchDump = 1;
|
|
} else if (_timerCount == 18) {
|
|
_timerCount = 0;
|
|
++_vars._secondCount;
|
|
if (_vars._secondCount == 60) {
|
|
_vars._secondCount = 0;
|
|
++_vars._minuteCount;
|
|
if (_vars._minuteCount == 60) {
|
|
_vars._minuteCount = 0;
|
|
++_vars._hourCount;
|
|
if (_vars._hourCount == 24)
|
|
_vars._hourCount = 0;
|
|
}
|
|
}
|
|
showTime();
|
|
_watchDump = 1;
|
|
}
|
|
}
|
|
|
|
void DreamWebEngine::roomName() {
|
|
printMessage(88, 18, 53, 240, false);
|
|
uint16 textIndex = _roomNum;
|
|
if (textIndex >= 32)
|
|
textIndex -= 32;
|
|
_lineSpacing = 7;
|
|
uint8 maxWidth = (_vars._watchOn == 1) ? 120 : 160;
|
|
const uint8 *string = (const uint8 *)_roomDesc.getString(textIndex);
|
|
printDirect(string, 88, 25, maxWidth, false);
|
|
_lineSpacing = 10;
|
|
useCharset1();
|
|
}
|
|
|
|
void DreamWebEngine::loadRoom() {
|
|
_roomLoaded = 1;
|
|
_timeCount = 0;
|
|
_mainTimer = 0;
|
|
_mapOffsetX = 104;
|
|
_mapOffsetY = 38;
|
|
_textAddressX = 13;
|
|
_textAddressY = 182;
|
|
_textLen = 240;
|
|
_vars._location = _newLocation;
|
|
const Room &room = g_roomData[_newLocation];
|
|
startLoading(room);
|
|
_sound->loadRoomsSample(_roomsSample);
|
|
switchRyanOn();
|
|
drawFlags();
|
|
|
|
uint8 mapXstart, mapYstart;
|
|
uint8 mapXsize, mapYsize;
|
|
getDimension(&mapXstart, &mapYstart, &mapXsize, &mapYsize);
|
|
}
|
|
|
|
void DreamWebEngine::readSetData() {
|
|
loadGraphicsFile(_charset1, "C00");
|
|
loadGraphicsFile(_icons1, "G00");
|
|
loadGraphicsFile(_icons2, "G01");
|
|
loadGraphicsFile(_mainSprites, "S00");
|
|
loadTextFile(_puzzleText, "T80");
|
|
loadTextFile(_commandText, "T84");
|
|
useCharset1();
|
|
|
|
// FIXME: Why is this commented out?
|
|
//openFile(getDatafilePrefix() + "VOL");
|
|
//uint8 *volumeTab = getSegment(data.word(kSoundbuffer)).ptr(16384, 0);
|
|
//readFromFile(volumeTab, 2048-256);
|
|
//closeFile();
|
|
}
|
|
|
|
void DreamWebEngine::findRoomInLoc() {
|
|
uint8 x = _mapX / 11;
|
|
uint8 y = _mapY / 10;
|
|
uint8 roomNum = y * 6 + x;
|
|
_roomNum = roomNum;
|
|
}
|
|
|
|
void DreamWebEngine::autoLook() {
|
|
if ((_mouseX != _oldX) || (_mouseY != _oldY)) {
|
|
_lookCounter = 1000;
|
|
return;
|
|
}
|
|
|
|
--_lookCounter;
|
|
if (_lookCounter)
|
|
return;
|
|
if (_vars._watchingTime)
|
|
return;
|
|
doLook();
|
|
}
|
|
|
|
void DreamWebEngine::look() {
|
|
if (_vars._watchingTime || (_pointerMode == 2)) {
|
|
blank();
|
|
return;
|
|
}
|
|
commandOnlyCond(25, 241);
|
|
if ((_mouseButton == 1) && (_mouseButton != _oldButton))
|
|
doLook();
|
|
}
|
|
|
|
void DreamWebEngine::doLook() {
|
|
createPanel();
|
|
showIcon();
|
|
underTextLine();
|
|
workToScreenM();
|
|
_commandType = 255;
|
|
dumpTextLine();
|
|
uint8 index = _roomNum & 31;
|
|
const uint8 *string = (const uint8 *)_roomDesc.getString(index);
|
|
findNextColon(&string);
|
|
uint16 x;
|
|
if (_realLocation < 50)
|
|
x = 66;
|
|
else
|
|
x = 40;
|
|
if (printSlow(string, x, 80, 241, true) != 1)
|
|
hangOnP(400);
|
|
|
|
_pointerMode = 0;
|
|
_commandType = 0;
|
|
redrawMainScrn();
|
|
workToScreenM();
|
|
}
|
|
|
|
void DreamWebEngine::useCharset1() {
|
|
_currentCharset = &_charset1;
|
|
}
|
|
|
|
void DreamWebEngine::useTempCharset(GraphicsFile *charset) {
|
|
_currentCharset = charset;
|
|
}
|
|
|
|
void DreamWebEngine::getRidOfTempText() {
|
|
_textFile1.clear();
|
|
}
|
|
|
|
void DreamWebEngine::getRidOfAll() {
|
|
delete[] _backdropBlocks;
|
|
_backdropBlocks = 0;
|
|
|
|
_setFrames.clear();
|
|
_reel1.clear();
|
|
_reel2.clear();
|
|
_reel3.clear();
|
|
delete[] _reelList;
|
|
_reelList = 0;
|
|
_personText.clear();
|
|
_setDesc.clear();
|
|
_blockDesc.clear();
|
|
_roomDesc.clear();
|
|
_freeFrames.clear();
|
|
_freeDesc.clear();
|
|
}
|
|
|
|
// if skipDat, skip clearing and loading Setdat and Freedat
|
|
void DreamWebEngine::loadRoomData(const Room &room, bool skipDat) {
|
|
processEvents();
|
|
Common::File file;
|
|
if (!file.open(modifyFileName(room.name)))
|
|
error("cannot open file %s", modifyFileName(room.name).c_str());
|
|
|
|
FileHeader header;
|
|
file.read((uint8 *)&header, sizeof(FileHeader));
|
|
|
|
// read segment lengths from room file header
|
|
unsigned int len[15];
|
|
for (int i = 0; i < 15; ++i)
|
|
len[i] = header.len(i);
|
|
|
|
assert(len[0] >= 192);
|
|
_backdropBlocks = new uint8[len[0] - 192];
|
|
file.read((uint8 *)_backdropFlags, 192);
|
|
file.read(_backdropBlocks, len[0] - 192);
|
|
|
|
assert(len[1] <= 132*66); // 132*66 = maplen
|
|
memset(workspace(), 0, 132*66);
|
|
file.read(workspace(), len[1]);
|
|
|
|
sortOutMap();
|
|
|
|
loadGraphicsSegment(_setFrames, file, len[2]);
|
|
if (!skipDat) {
|
|
const uint16 kSetdatlen = 64*128;
|
|
assert(len[3] <= kSetdatlen);
|
|
memset(_setDat, 255, kSetdatlen);
|
|
file.read(_setDat, len[3]);
|
|
} else {
|
|
file.skip(len[3]);
|
|
}
|
|
// NB: The skipDat version of this function as called by restoreall
|
|
// had a 'call bloc' instead of 'call loadseg' for reel1,
|
|
// but 'bloc' was not defined.
|
|
loadGraphicsSegment(_reel1, file, len[4]);
|
|
loadGraphicsSegment(_reel2, file, len[5]);
|
|
loadGraphicsSegment(_reel3, file, len[6]);
|
|
|
|
// segment 7 consists of 36 RoomPaths followed by 'reelList'
|
|
delete[] _reelList;
|
|
if (len[7] <= 36*sizeof(RoomPaths)) {
|
|
file.read((uint8 *)_pathData, len[7]);
|
|
_reelList = 0;
|
|
} else {
|
|
file.read((uint8 *)_pathData, 36*sizeof(RoomPaths));
|
|
unsigned int reelLen = len[7] - 36*sizeof(RoomPaths);
|
|
unsigned int reelCount = (reelLen + sizeof(Reel) - 1) / sizeof(Reel);
|
|
_reelList = new Reel[reelCount];
|
|
file.read((uint8 *)_reelList, reelLen);
|
|
}
|
|
|
|
// segment 8 consists of 12 personFrames followed by a TextFile
|
|
file.read((uint8 *)_personFramesLE, 24);
|
|
loadTextSegment(_personText, file, len[8] - 24);
|
|
|
|
loadTextSegment(_setDesc, file, len[9]);
|
|
loadTextSegment(_blockDesc, file, len[10]);
|
|
loadTextSegment(_roomDesc, file, len[11]);
|
|
loadGraphicsSegment(_freeFrames, file, len[12]);
|
|
if (!skipDat) {
|
|
const uint16 kFreedatlen = 16*80;
|
|
assert(len[13] <= kFreedatlen);
|
|
memset(_freeDat, 255, kFreedatlen);
|
|
file.read(_freeDat, len[13]);
|
|
} else {
|
|
file.skip(len[13]);
|
|
}
|
|
loadTextSegment(_freeDesc, file, len[14]);
|
|
|
|
processEvents();
|
|
}
|
|
|
|
void DreamWebEngine::restoreAll() {
|
|
const Room &room = g_roomData[_vars._location];
|
|
loadRoomData(room, true);
|
|
setAllChanges();
|
|
}
|
|
|
|
void DreamWebEngine::restoreReels() {
|
|
if (_roomLoaded == 0)
|
|
return;
|
|
|
|
const Room &room = g_roomData[_realLocation];
|
|
|
|
processEvents();
|
|
Common::File file;
|
|
if (!file.open(modifyFileName(room.name)))
|
|
error("cannot open file %s", modifyFileName(room.name).c_str());
|
|
|
|
FileHeader header;
|
|
file.read((uint8 *)&header, sizeof(FileHeader));
|
|
|
|
// read segment lengths from room file header
|
|
int len[15];
|
|
for (int i = 0; i < 15; ++i)
|
|
len[i] = header.len(i);
|
|
|
|
file.skip(len[0]);
|
|
file.skip(len[1]);
|
|
file.skip(len[2]);
|
|
file.skip(len[3]);
|
|
loadGraphicsSegment(_reel1, file, len[4]);
|
|
loadGraphicsSegment(_reel2, file, len[5]);
|
|
loadGraphicsSegment(_reel3, file, len[6]);
|
|
|
|
processEvents();
|
|
}
|
|
|
|
void DreamWebEngine::showExit() {
|
|
showFrame(_icons1, 274, 154, 11, 0);
|
|
}
|
|
|
|
void DreamWebEngine::showMan() {
|
|
showFrame(_icons1, 0, 0, 0, 0);
|
|
showFrame(_icons1, 0, 114, 1, 0);
|
|
if (_vars._shadesOn)
|
|
showFrame(_icons1, 28, 25, 2, 0);
|
|
}
|
|
|
|
void DreamWebEngine::panelIcons1() {
|
|
uint16 x;
|
|
if (_vars._watchOn != 1)
|
|
x = 48;
|
|
else
|
|
x = 0;
|
|
showFrame(_icons2, 204 + x, 4, 2, 0);
|
|
if (_vars._zoomOn != 1)
|
|
showFrame(_icons1, 228 + x, 8, 5, 0);
|
|
showWatch();
|
|
}
|
|
|
|
void DreamWebEngine::examIcon() {
|
|
showFrame(_icons2, 254, 5, 3, 0);
|
|
}
|
|
|
|
const uint8 *DreamWebEngine::getTextInFile1(uint16 index) {
|
|
return (const uint8 *)_textFile1.getString(index);
|
|
}
|
|
|
|
void DreamWebEngine::loadTravelText() {
|
|
loadTextFile(_travelText, "T81"); // location descs
|
|
}
|
|
|
|
void DreamWebEngine::loadTempText(const char *suffix) {
|
|
loadTextFile(_textFile1, suffix);
|
|
}
|
|
|
|
void DreamWebEngine::drawFloor() {
|
|
eraseOldObs();
|
|
drawFlags();
|
|
calcMapAd();
|
|
doBlocks();
|
|
showAllObs();
|
|
showAllFree();
|
|
showAllEx();
|
|
panelToMap();
|
|
initRain();
|
|
_vars._newObs = 0;
|
|
}
|
|
|
|
void DreamWebEngine::allocateBuffers() {
|
|
_exFrames.clear();
|
|
_exFrames._data = new uint8[kExframeslen];
|
|
_exFrames._frames = new Frame[kGraphicsFileFrameSize];
|
|
_exText.clear();
|
|
_exText._text = new char[kExtextlen];
|
|
}
|
|
|
|
void DreamWebEngine::workToScreenM() {
|
|
animPointer();
|
|
readMouse();
|
|
showPointer();
|
|
waitForVSync();
|
|
workToScreen();
|
|
delPointer();
|
|
}
|
|
|
|
void DreamWebEngine::atmospheres() {
|
|
|
|
const Atmosphere *a = &g_atmosphereList[0];
|
|
|
|
for (; a->_location != 255; ++a) {
|
|
if (a->_location != _realLocation)
|
|
continue;
|
|
if (a->_mapX != _mapX || a->_mapY != _mapY)
|
|
continue;
|
|
if (a->_sound != _sound->getChannel0Playing()) {
|
|
|
|
if (_vars._location == 45 && _vars._reelToWatch == 45)
|
|
continue; // "web"
|
|
|
|
_sound->playChannel0(a->_sound, a->_repeat);
|
|
|
|
// NB: The asm here reads
|
|
// cmp reallocation,2
|
|
// cmp mapy,0
|
|
// jz fullvol
|
|
// jnz notlouisvol
|
|
// I'm interpreting this as if the cmp reallocation is below the jz
|
|
|
|
if (_mapY == 0) {
|
|
_sound->volumeSet(0); // "fullvol"
|
|
return;
|
|
}
|
|
|
|
if (_realLocation == 2 && _mapX == 22 && _mapY == 10)
|
|
_sound->volumeSet(5); // "louisvol"
|
|
|
|
if (hasSpeech() && _realLocation == 14) {
|
|
if (_mapX == 33) {
|
|
_sound->volumeSet(0); // "ismad2"
|
|
return;
|
|
}
|
|
|
|
if (_mapX == 22) {
|
|
_sound->volumeSet(5);
|
|
return;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
if (_realLocation == 2) {
|
|
if (_mapX == 22) {
|
|
_sound->volumeSet(5); // "louisvol"
|
|
return;
|
|
}
|
|
|
|
if (_mapX == 11) {
|
|
_sound->volumeSet(0); // "fullvol"
|
|
return;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
_sound->cancelCh0();
|
|
}
|
|
|
|
void DreamWebEngine::readKey() {
|
|
uint16 bufOut = _bufferOut;
|
|
|
|
if (bufOut == _bufferIn) {
|
|
// empty buffer
|
|
_currentKey = 0;
|
|
return;
|
|
}
|
|
|
|
bufOut = (bufOut + 1) & 15; // The buffer has size 16
|
|
_currentKey = g_keyBuffer[bufOut];
|
|
_bufferOut = bufOut;
|
|
}
|
|
|
|
void DreamWebEngine::newGame() {
|
|
commandOnlyCond(47, 251);
|
|
|
|
if (_mouseButton == 1)
|
|
_getBack = 3;
|
|
}
|
|
|
|
void DreamWebEngine::pickupOb(uint8 command, uint8 pos) {
|
|
_lastInvPos = pos;
|
|
_objectType = kFreeObjectType;
|
|
_itemFrame = command;
|
|
_command = command;
|
|
//uint8 dummy;
|
|
//getAnyAd(&dummy, &dummy); // was in the original source, seems useless here
|
|
transferToEx(command);
|
|
}
|
|
|
|
void DreamWebEngine::initialInv() {
|
|
if (_realLocation != 24)
|
|
return;
|
|
|
|
pickupOb(11, 5);
|
|
pickupOb(12, 6);
|
|
pickupOb(13, 7);
|
|
pickupOb(14, 8);
|
|
pickupOb(18, 0);
|
|
pickupOb(19, 1);
|
|
pickupOb(20, 9);
|
|
pickupOb(16, 2);
|
|
_vars._watchMode = 1;
|
|
_vars._reelToHold = 0;
|
|
_vars._endOfHoldReel = 6;
|
|
_vars._watchSpeed = 1;
|
|
_vars._speedCount = 1;
|
|
switchRyanOff();
|
|
}
|
|
|
|
void DreamWebEngine::walkIntoRoom() {
|
|
if (_vars._location == 14 && _mapX == 22) {
|
|
_destination = 1;
|
|
_finalDest = 1;
|
|
autoSetWalk();
|
|
}
|
|
}
|
|
|
|
void DreamWebEngine::afterIntroRoom() {
|
|
if (_nowInNewRoom == 0)
|
|
return; // notnewintro
|
|
|
|
clearWork();
|
|
findRoomInLoc();
|
|
_vars._newObs = 1;
|
|
drawFloor();
|
|
reelsOnScreen();
|
|
spriteUpdate();
|
|
printSprites();
|
|
workToScreen();
|
|
_nowInNewRoom = 0;
|
|
}
|
|
|
|
void DreamWebEngine::redrawMainScrn() {
|
|
_timeCount = 0;
|
|
createPanel();
|
|
_vars._newObs = 0;
|
|
drawFloor();
|
|
printSprites();
|
|
reelsOnScreen();
|
|
showIcon();
|
|
getUnderZoom();
|
|
underTextLine();
|
|
readMouse();
|
|
_commandType = 255;
|
|
}
|
|
|
|
void DreamWebEngine::blank() {
|
|
commandOnlyCond(0, 199);
|
|
}
|
|
|
|
void DreamWebEngine::allPointer() {
|
|
readMouse();
|
|
showPointer();
|
|
dumpPointer();
|
|
}
|
|
|
|
void DreamWebEngine::makeMainScreen() {
|
|
createPanel();
|
|
_vars._newObs = 1;
|
|
drawFloor();
|
|
spriteUpdate();
|
|
printSprites();
|
|
reelsOnScreen();
|
|
showIcon();
|
|
getUnderZoom();
|
|
underTextLine();
|
|
_commandType = 255;
|
|
animPointer();
|
|
workToScreenM();
|
|
_commandType = 200;
|
|
_manIsOffScreen = 0;
|
|
}
|
|
|
|
void DreamWebEngine::openInv() {
|
|
_invOpen = 1;
|
|
printMessage(80, 58 - 10, 61, 240, (240 & 1));
|
|
fillRyan();
|
|
_commandType = 255;
|
|
}
|
|
|
|
void DreamWebEngine::obsThatDoThings() {
|
|
if (!compare(_command, _objectType, "MEMB"))
|
|
return; // notlouiscard
|
|
|
|
if (getLocation(4) != 1) {
|
|
setLocation(4);
|
|
lookAtCard();
|
|
}
|
|
}
|
|
|
|
void DreamWebEngine::describeOb() {
|
|
const uint8 *obText = getObTextStart();
|
|
uint16 y = 92;
|
|
if (_foreignRelease && _objectType == kSetObjectType1)
|
|
y = 82;
|
|
_charShift = 91 + 91;
|
|
printDirect(&obText, 33, &y, 241, 241 & 1);
|
|
_charShift = 0;
|
|
y = 104;
|
|
if (_foreignRelease && _objectType == kSetObjectType1)
|
|
y = 94;
|
|
printDirect(&obText, 36, &y, 241, 241 & 1);
|
|
obsThatDoThings();
|
|
|
|
// Additional text
|
|
if (compare(_command, _objectType, "CUPE")) {
|
|
// Empty cup
|
|
const uint8 *string = (const uint8 *)_puzzleText.getString(40);
|
|
printDirect(string, 36, y + 10, 241, 241 & 1);
|
|
} else if (compare(_command, _objectType, "CUPF")) {
|
|
// Full cup
|
|
const uint8 *string = (const uint8 *)_puzzleText.getString(39);
|
|
printDirect(string, 36, y + 10, 241, 241 & 1);
|
|
}
|
|
}
|
|
|
|
void DreamWebEngine::delEverything() {
|
|
if (_mapYSize + _mapOffsetY < 182) {
|
|
mapToPanel();
|
|
} else {
|
|
// Big room
|
|
_mapYSize -= 8;
|
|
mapToPanel();
|
|
_mapYSize += 8;
|
|
}
|
|
}
|
|
|
|
void DreamWebEngine::errorMessage1() {
|
|
delPointer();
|
|
printMessage(76, 21, 58, 240, (240 & 1));
|
|
readMouse();
|
|
showPointer();
|
|
workToScreen();
|
|
delPointer();
|
|
hangOnP(50);
|
|
showPanel();
|
|
showMan();
|
|
examIcon();
|
|
readMouse();
|
|
useOpened();
|
|
showPointer();
|
|
workToScreen();
|
|
delPointer();
|
|
}
|
|
|
|
void DreamWebEngine::errorMessage2() {
|
|
_commandType = 255;
|
|
delPointer();
|
|
printMessage(76, 21, 59, 240, (240 & 1));
|
|
readMouse();
|
|
showPointer();
|
|
workToScreen();
|
|
delPointer();
|
|
hangOnP(50);
|
|
showPanel();
|
|
showMan();
|
|
examIcon();
|
|
readMouse();
|
|
useOpened();
|
|
showPointer();
|
|
workToScreen();
|
|
delPointer();
|
|
}
|
|
|
|
void DreamWebEngine::errorMessage3() {
|
|
delPointer();
|
|
printMessage(76, 21, 60, 240, (240 & 1));
|
|
workToScreenM();
|
|
hangOnP(50);
|
|
showPanel();
|
|
showMan();
|
|
examIcon();
|
|
readMouse();
|
|
useOpened();
|
|
showPointer();
|
|
workToScreen();
|
|
delPointer();
|
|
}
|
|
|
|
void DreamWebEngine::reExFromOpen() {
|
|
|
|
}
|
|
|
|
void DreamWebEngine::putBackObStuff() {
|
|
createPanel();
|
|
showPanel();
|
|
showMan();
|
|
obIcons();
|
|
showExit();
|
|
obPicture();
|
|
describeOb();
|
|
underTextLine();
|
|
_commandType = 255;
|
|
readMouse();
|
|
showPointer();
|
|
workToScreen();
|
|
delPointer();
|
|
}
|
|
|
|
bool DreamWebEngine::isSetObOnMap(uint8 index) {
|
|
return (getSetAd(index)->mapad[0] == 0);
|
|
}
|
|
|
|
void DreamWebEngine::examineInventory() {
|
|
commandOnlyCond(32, 249);
|
|
|
|
if (!(_mouseButton & 1))
|
|
return;
|
|
|
|
createPanel();
|
|
showPanel();
|
|
showMan();
|
|
showExit();
|
|
examIcon();
|
|
_pickUp = 0;
|
|
_invOpen = 2;
|
|
openInv();
|
|
workToScreenM();
|
|
}
|
|
|
|
void DreamWebEngine::middlePanel() {
|
|
}
|
|
|
|
void DreamWebEngine::underTextLine() {
|
|
if (_foreignRelease)
|
|
multiGet(_textUnder, _textAddressX, _textAddressY - 3, kUnderTextSizeX_f, kUnderTextSizeY_f);
|
|
else
|
|
multiGet(_textUnder, _textAddressX, _textAddressY, kUnderTextSizeX, kUnderTextSizeY);
|
|
}
|
|
|
|
void DreamWebEngine::showWatchReel() {
|
|
uint16 reelPointer = _vars._reelToWatch;
|
|
plotReel(reelPointer);
|
|
_vars._reelToWatch = reelPointer;
|
|
|
|
// check for shake
|
|
if (_realLocation == 26 && reelPointer == 104)
|
|
_vars._shakeCounter = 0xFF;
|
|
}
|
|
|
|
void DreamWebEngine::watchReel() {
|
|
if (_vars._reelToWatch != 0xFFFF) {
|
|
if (_mansPath != _finalDest)
|
|
return; // Wait until stopped walking
|
|
if (_turnToFace != _facing)
|
|
return;
|
|
|
|
if (--_vars._speedCount != 0xFF) {
|
|
showWatchReel();
|
|
return;
|
|
}
|
|
_vars._speedCount = _vars._watchSpeed;
|
|
if (_vars._reelToWatch != _vars._endWatchReel) {
|
|
++_vars._reelToWatch;
|
|
showWatchReel();
|
|
return;
|
|
}
|
|
if (_vars._watchingTime) {
|
|
showWatchReel();
|
|
return;
|
|
}
|
|
_vars._reelToWatch = 0xFFFF;
|
|
_vars._watchMode = 0xFF;
|
|
if (_vars._reelToHold == 0xFFFF)
|
|
return; // No more reel
|
|
_vars._watchMode = 1;
|
|
} else if (_vars._watchMode != 1) {
|
|
if (_vars._watchMode != 2)
|
|
return; // "notreleasehold"
|
|
if (--_vars._speedCount == 0xFF) {
|
|
_vars._speedCount = _vars._watchSpeed;
|
|
++_vars._reelToHold;
|
|
}
|
|
if (_vars._reelToHold == _vars._endOfHoldReel) {
|
|
_vars._reelToHold = 0xFFFF;
|
|
_vars._watchMode = 0xFF;
|
|
_destination = _vars._destAfterHold;
|
|
_finalDest = _vars._destAfterHold;
|
|
autoSetWalk();
|
|
return;
|
|
}
|
|
}
|
|
|
|
uint16 reelPointer = _vars._reelToHold;
|
|
plotReel(reelPointer);
|
|
}
|
|
|
|
void DreamWebEngine::afterNewRoom() {
|
|
if (_nowInNewRoom == 0)
|
|
return; // notnew
|
|
|
|
_timeCount = 0;
|
|
createPanel();
|
|
_commandType = 0;
|
|
findRoomInLoc();
|
|
if (_vars._ryanOn != 1) {
|
|
_mansPath = findPathOfPoint(_ryanX + 12, _ryanY + 12);
|
|
findXYFromPath();
|
|
_resetManXY = 1;
|
|
}
|
|
_vars._newObs = 1;
|
|
drawFloor();
|
|
_lookCounter = 160;
|
|
_nowInNewRoom = 0;
|
|
showIcon();
|
|
spriteUpdate();
|
|
printSprites();
|
|
underTextLine();
|
|
reelsOnScreen();
|
|
mainScreen();
|
|
getUnderZoom();
|
|
zoom();
|
|
workToScreenM();
|
|
walkIntoRoom();
|
|
edensFlatReminders();
|
|
atmospheres();
|
|
}
|
|
|
|
void DreamWebEngine::madmanRun() {
|
|
if (_vars._location != 14 ||
|
|
_mapX != 22 ||
|
|
_pointerMode != 2 ||
|
|
_vars._madmanFlag != 0) {
|
|
identifyOb();
|
|
return;
|
|
}
|
|
|
|
commandOnlyCond(52, 211);
|
|
|
|
if (_mouseButton == 1 &&
|
|
_mouseButton != _oldButton)
|
|
_vars._lastWeapon = 8;
|
|
}
|
|
|
|
|
|
void DreamWebEngine::decide() {
|
|
setMode();
|
|
loadPalFromIFF();
|
|
clearPalette();
|
|
_pointerMode = 0;
|
|
_vars._watchingTime = 0;
|
|
_pointerFrame = 0;
|
|
_textAddressX = 70;
|
|
_textAddressY = 182 - 8;
|
|
_textLen = 181;
|
|
_manIsOffScreen = 1;
|
|
loadSaveBox();
|
|
showDecisions();
|
|
workToScreen();
|
|
fadeScreenUp();
|
|
_getBack = 0;
|
|
|
|
RectWithCallback decideList[] = {
|
|
{ kOpsx+69,kOpsx+124,kOpsy+30,kOpsy+76,&DreamWebEngine::newGame },
|
|
{ kOpsx+20,kOpsx+87,kOpsy+10,kOpsy+59,&DreamWebEngine::DOSReturn },
|
|
{ kOpsx+123,kOpsx+190,kOpsy+10,kOpsy+59,&DreamWebEngine::loadOld },
|
|
{ 0,320,0,200,&DreamWebEngine::blank },
|
|
{ 0xFFFF,0,0,0,0 }
|
|
};
|
|
|
|
do {
|
|
if (_quitRequested)
|
|
return;
|
|
|
|
readMouse();
|
|
showPointer();
|
|
waitForVSync();
|
|
dumpPointer();
|
|
dumpTextLine();
|
|
delPointer();
|
|
checkCoords(decideList);
|
|
} while (!_getBack);
|
|
|
|
if (_getBack != 4)
|
|
_saveGraphics.clear(); // room not loaded
|
|
|
|
_textAddressX = 13;
|
|
_textAddressY = 182;
|
|
_textLen = 240;
|
|
}
|
|
|
|
void DreamWebEngine::showGun() {
|
|
_addToRed = 0;
|
|
_addToGreen = 0;
|
|
_addToBlue = 0;
|
|
palToStartPal();
|
|
palToEndPal();
|
|
greyscaleSum();
|
|
_fadeDirection = 1;
|
|
_fadeCount = 63;
|
|
_colourPos = 0;
|
|
_numToFade = 128;
|
|
hangOn(130);
|
|
endPalToStart();
|
|
clearEndPal();
|
|
_fadeDirection = 1;
|
|
_fadeCount = 63;
|
|
_colourPos = 0;
|
|
_numToFade = 128;
|
|
hangOn(200);
|
|
_roomsSample = 34;
|
|
_sound->loadRoomsSample(_roomsSample);
|
|
_sound->volumeSet(0);
|
|
GraphicsFile graphics;
|
|
loadGraphicsFile(graphics, "G13");
|
|
createPanel2();
|
|
showFrame(graphics, 100, 4, 0, 0);
|
|
showFrame(graphics, 158, 106, 1, 0);
|
|
workToScreen();
|
|
graphics.clear();
|
|
fadeScreenUp();
|
|
hangOn(160);
|
|
_sound->playChannel0(12, 0);
|
|
loadTempText("T83");
|
|
rollEndCreditsGameLost();
|
|
getRidOfTempText();
|
|
}
|
|
|
|
void DreamWebEngine::dropError() {
|
|
_commandType = 255;
|
|
delPointer();
|
|
printMessage(76, 21, 56, 240, 240 & 1);
|
|
workToScreenM();
|
|
hangOnP(50);
|
|
showPanel();
|
|
showMan();
|
|
examIcon();
|
|
_commandType = 255;
|
|
workToScreenM();
|
|
}
|
|
|
|
void DreamWebEngine::cantDrop() {
|
|
_commandType = 255;
|
|
delPointer();
|
|
printMessage(76, 21, 24, 240, 240 & 1);
|
|
workToScreenM();
|
|
hangOnP(50);
|
|
showPanel();
|
|
showMan();
|
|
examIcon();
|
|
_commandType = 255;
|
|
workToScreenM();
|
|
}
|
|
|
|
void DreamWebEngine::getBack1() {
|
|
if (_pickUp != 0) {
|
|
blank();
|
|
return;
|
|
}
|
|
|
|
|
|
commandOnlyCond(26, 202);
|
|
|
|
if (_mouseButton == _oldButton)
|
|
return;
|
|
|
|
if (_mouseButton & 1) {
|
|
// Get back
|
|
_getBack = 1;
|
|
_pickUp = 0;
|
|
}
|
|
}
|
|
|
|
void DreamWebEngine::autoAppear() {
|
|
if (_vars._location == 32) {
|
|
// In alley
|
|
resetLocation(5);
|
|
setLocation(10);
|
|
_destPos = 10;
|
|
return;
|
|
}
|
|
|
|
if (_realLocation == 24) {
|
|
// In Eden's apartment
|
|
if (_vars._generalDead == 1) {
|
|
_vars._generalDead++;
|
|
placeSetObject(44);
|
|
placeSetObject(18);
|
|
placeSetObject(93);
|
|
removeSetObject(92);
|
|
removeSetObject(55);
|
|
removeSetObject(75);
|
|
removeSetObject(84);
|
|
removeSetObject(85);
|
|
} else if (_vars._sartainDead == 1) {
|
|
// Eden's part 2
|
|
removeSetObject(44);
|
|
removeSetObject(93);
|
|
placeSetObject(55);
|
|
_vars._sartainDead++;
|
|
}
|
|
} else {
|
|
// Not in Eden's
|
|
if (_realLocation == 25) {
|
|
// Sart roof
|
|
_vars._newsItem = 3;
|
|
resetLocation(6);
|
|
setLocation(11);
|
|
_destPos = 11;
|
|
} else {
|
|
if (_realLocation == 2 && _vars._rockstarDead != 0)
|
|
placeSetObject(23);
|
|
}
|
|
}
|
|
}
|
|
|
|
void DreamWebEngine::setupTimedUse(uint16 textIndex, uint16 countToTimed, uint16 timeCount, byte x, byte y) {
|
|
if (_timeCount != 0)
|
|
return; // can't setup
|
|
|
|
_timedTemp._y = y;
|
|
_timedTemp._x = x;
|
|
_timedTemp._countToTimed = countToTimed;
|
|
_timeCount = _timedTemp._timeCount = timeCount + countToTimed;
|
|
_timedTemp._string = _puzzleText.getString(textIndex);
|
|
debug(1, "setupTimedUse: %d => '%s'", textIndex, _timedTemp._string);
|
|
}
|
|
|
|
void DreamWebEngine::entryTexts() {
|
|
switch (_vars._location) {
|
|
case 21:
|
|
setupTimedUse(28, 60, 11, 68, 64);
|
|
break;
|
|
case 30:
|
|
setupTimedUse(27, 60, 11, 68, 64);
|
|
break;
|
|
case 23:
|
|
setupTimedUse(29, 60, 11, 68, 64);
|
|
break;
|
|
case 31:
|
|
setupTimedUse(30, 60, 11, 68, 64);
|
|
break;
|
|
case 20: // Sarter's 2
|
|
setupTimedUse(31, 60, 11, 68, 64);
|
|
break;
|
|
case 24: // Eden's lobby
|
|
setupTimedUse(32, 60, 3, 68, 64);
|
|
break;
|
|
case 34: // Eden 2
|
|
setupTimedUse(33, 60, 3, 68, 64);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void DreamWebEngine::entryAnims() {
|
|
_vars._reelToWatch = 0xFFFF;
|
|
_vars._watchMode = (byte)-1;
|
|
|
|
switch (_vars._location) {
|
|
case 33: // beach
|
|
switchRyanOff();
|
|
_vars._watchingTime = 76 * 2;
|
|
_vars._reelToWatch = 0;
|
|
_vars._endWatchReel = 76;
|
|
_vars._watchSpeed = 1;
|
|
_vars._speedCount = 1;
|
|
break;
|
|
case 44: // Sparky's
|
|
resetLocation(8);
|
|
_vars._watchingTime = 50*2;
|
|
_vars._reelToWatch = 247;
|
|
_vars._endWatchReel = 297;
|
|
_vars._watchSpeed = 1;
|
|
_vars._speedCount = 1;
|
|
switchRyanOff();
|
|
break;
|
|
case 22: // lift
|
|
_vars._watchingTime = 31 * 2;
|
|
_vars._reelToWatch = 0;
|
|
_vars._endWatchReel = 30;
|
|
_vars._watchSpeed = 1;
|
|
_vars._speedCount = 1;
|
|
switchRyanOff();
|
|
break;
|
|
case 26: // under church
|
|
_symbolTopNum = 2;
|
|
_symbolBotNum = 1;
|
|
break;
|
|
case 45: // entered Dreamweb
|
|
_vars._keeperFlag = 0;
|
|
_vars._watchingTime = 296;
|
|
_vars._reelToWatch = 45;
|
|
_vars._endWatchReel = 198;
|
|
_vars._watchSpeed = 1;
|
|
_vars._speedCount = 1;
|
|
switchRyanOff();
|
|
break;
|
|
default:
|
|
if (_realLocation == 46 && _vars._sartainDead == 1) { // Crystal
|
|
removeFreeObject(0);
|
|
} else if (_vars._location == 9 && !checkIfPathIsOn(2) && _vars._aideDead != 0) {
|
|
// Top of church
|
|
if (checkIfPathIsOn(3))
|
|
turnPathOn(2);
|
|
|
|
// Make doors open
|
|
removeSetObject(4);
|
|
placeSetObject(5);
|
|
} else if (_vars._location == 47) { // Dream centre
|
|
placeSetObject(4);
|
|
placeSetObject(5);
|
|
} else if (_vars._location == 38) { // Car park
|
|
_vars._watchingTime = 57 * 2;
|
|
_vars._reelToWatch = 4;
|
|
_vars._endWatchReel = 57;
|
|
_vars._watchSpeed = 1;
|
|
_vars._speedCount = 1;
|
|
switchRyanOff();
|
|
} else if (_vars._location == 32) { // Alley
|
|
_vars._watchingTime = 66 * 2;
|
|
_vars._reelToWatch = 0;
|
|
_vars._endWatchReel = 66;
|
|
_vars._watchSpeed = 1;
|
|
_vars._speedCount = 1;
|
|
switchRyanOff();
|
|
} else if (_vars._location == 24) { // Eden's again
|
|
turnAnyPathOn(2, _roomNum - 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
void DreamWebEngine::lookAtCard() {
|
|
_manIsOffScreen = 1;
|
|
getRidOfReels();
|
|
loadKeypad();
|
|
createPanel2();
|
|
showFrame(_keypadGraphics, 160, 80, 42, 128);
|
|
const uint8 *obText = getObTextStart();
|
|
findNextColon(&obText);
|
|
findNextColon(&obText);
|
|
findNextColon(&obText);
|
|
uint16 y = 124;
|
|
printDirect(&obText, 36, &y, 241, 241 & 1);
|
|
workToScreenM();
|
|
hangOnW(280);
|
|
createPanel2();
|
|
showFrame(_keypadGraphics, 160, 80, 42, 128);
|
|
printDirect(obText, 36, 130, 241, 241 & 1);
|
|
workToScreenM();
|
|
hangOnW(200);
|
|
_manIsOffScreen = 0;
|
|
_keypadGraphics.clear();
|
|
restoreReels();
|
|
putBackObStuff();
|
|
}
|
|
|
|
void DreamWebEngine::clearBuffers() {
|
|
clearChanges();
|
|
}
|
|
|
|
void DreamWebEngine::clearChanges() {
|
|
memset(_listOfChanges, 0xFF, sizeof(_listOfChanges));
|
|
|
|
setupInitialReelRoutines();
|
|
|
|
setupInitialVars();
|
|
|
|
_vars._exFramePos = 0;
|
|
_vars._exTextPos = 0;
|
|
|
|
memset(_exFrames._frames, 0xFF, kFrameBlocksize);
|
|
memset(_exFrames._data, 0xFF, kExframeslen);
|
|
memset(_exData, 0xFF, sizeof(_exData));
|
|
memset(_exText._offsetsLE, 0xFF, 2*(kNumexobjects+2));
|
|
memset(_exText._text, 0xFF, kExtextlen);
|
|
|
|
const uint8 initialRoomsCanGo[16] = { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
|
|
|
assert(sizeof(_roomsCanGo) == sizeof(initialRoomsCanGo));
|
|
memcpy(_roomsCanGo, initialRoomsCanGo, sizeof(initialRoomsCanGo));
|
|
}
|
|
|
|
void DreamWebEngine::setupInitialVars() {
|
|
_vars._startVars = 0;
|
|
_vars._progressPoints = 0;
|
|
_vars._watchOn = 0;
|
|
_vars._shadesOn = 0;
|
|
getTime();
|
|
_vars._zoomOn = 1;
|
|
_vars._location = 0;
|
|
_vars._exPos = 0;
|
|
_vars._exFramePos = 0;
|
|
_vars._exTextPos = 0;
|
|
_vars._card1Money = 0;
|
|
_vars._listPos = 0;
|
|
_vars._ryanPage = 0;
|
|
_vars._watchingTime = 0;
|
|
_vars._reelToWatch = (uint16)-1;
|
|
_vars._endWatchReel = 0;
|
|
_vars._speedCount = 0;
|
|
_vars._watchSpeed = 0;
|
|
_vars._reelToHold = (uint16)-1;
|
|
_vars._endOfHoldReel = (uint16)-1;
|
|
_vars._watchMode = (uint8)-1;
|
|
_vars._destAfterHold = 0;
|
|
_vars._newsItem = 0;
|
|
_vars._liftFlag = 0;
|
|
_vars._liftPath = 0;
|
|
_vars._lockStatus = 1;
|
|
_vars._doorPath = 0;
|
|
_vars._countToOpen = 0;
|
|
_vars._countToClose = 0;
|
|
_vars._rockstarDead = 0;
|
|
_vars._generalDead = 0;
|
|
_vars._sartainDead = 0;
|
|
_vars._aideDead = 0;
|
|
_vars._beenMugged = 0;
|
|
_vars._gunPassFlag = 0;
|
|
_vars._canMoveAltar = 0;
|
|
_vars._talkedToAttendant = 0;
|
|
_vars._talkedToSparky = 0;
|
|
_vars._talkedToBoss = 0;
|
|
_vars._talkedToRecep = 0;
|
|
_vars._cardPassFlag = 0;
|
|
_vars._madmanFlag = 0;
|
|
_vars._keeperFlag = 0;
|
|
_vars._lastTrigger = 0;
|
|
_vars._manDead = 0;
|
|
_vars._seed1 = 1;
|
|
_vars._seed2 = 2;
|
|
_vars._seed3 = 3;
|
|
_vars._needToTravel = 0;
|
|
_vars._throughDoor = 0;
|
|
_vars._newObs = 0;
|
|
_vars._ryanOn = 255;
|
|
_vars._combatCount = 0;
|
|
_vars._lastWeapon = (uint8)-1;
|
|
_vars._dreamNumber = 0;
|
|
_vars._roomAfterDream = 0;
|
|
_vars._shakeCounter = 48;
|
|
}
|
|
|
|
void DreamWebEngine::edensFlatReminders() {
|
|
if (_realLocation != 24 || _mapX != 44)
|
|
return; // not in Eden's lift
|
|
|
|
if (_vars._progressPoints)
|
|
return; // not the first time in Eden's apartment
|
|
|
|
uint16 exObjextIndex = findExObject("CSHR");
|
|
if (!isRyanHolding("DKEY") || exObjextIndex == kNumexobjects) {
|
|
setupTimedUse(50, 48, 8, 54, 70); // forgot something
|
|
return;
|
|
}
|
|
|
|
DynObject *object = getExAd(exObjextIndex);
|
|
|
|
if (object->mapad[0] != 4) {
|
|
setupTimedUse(50, 48, 8, 54, 70); // forgot something
|
|
return;
|
|
} else if (object->mapad[1] != 255) {
|
|
if (!compare(object->mapad[1], object->mapad[0], "PURS")) {
|
|
setupTimedUse(50, 48, 8, 54, 70); // forgot something
|
|
return;
|
|
}
|
|
}
|
|
|
|
_vars._progressPoints++; // got card
|
|
}
|
|
|
|
void DreamWebEngine::incRyanPage() {
|
|
commandOnlyCond(31, 222);
|
|
|
|
if (_mouseButton == _oldButton || !(_mouseButton & 1))
|
|
return;
|
|
|
|
_vars._ryanPage = (_mouseX - (kInventx + 167)) / 18;
|
|
|
|
delPointer();
|
|
fillRyan();
|
|
readMouse();
|
|
showPointer();
|
|
workToScreen();
|
|
delPointer();
|
|
|
|
}
|
|
|
|
void DreamWebEngine::emergencyPurge() {
|
|
while (true) {
|
|
if (_vars._exFramePos + 4000 < kExframeslen) {
|
|
// Not near frame end
|
|
if (_vars._exTextPos + 400 < kExtextlen)
|
|
return; // notneartextend
|
|
}
|
|
|
|
purgeAnItem();
|
|
}
|
|
}
|
|
|
|
void DreamWebEngine::purgeAnItem() {
|
|
const DynObject *extraObjects = _exData;
|
|
|
|
for (size_t i = 0; i < kNumexobjects; ++i) {
|
|
if (extraObjects[i].mapad[0] && extraObjects[i].objId[0] == 255 &&
|
|
extraObjects[i].initialLocation != _realLocation) {
|
|
deleteExObject(i);
|
|
return;
|
|
}
|
|
}
|
|
|
|
for (size_t i = 0; i < kNumexobjects; ++i) {
|
|
if (extraObjects[i].mapad[0] && extraObjects[i].objId[0] == 255) {
|
|
deleteExObject(i);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
} // End of namespace DreamWeb
|