mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-23 10:19:27 +00:00
bdfdf0e7b3
svn-id: r32651
998 lines
23 KiB
C++
998 lines
23 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.
|
|
*
|
|
* $URL$
|
|
* $Id$
|
|
*
|
|
*/
|
|
|
|
#include "common/events.h"
|
|
#include "common/keyboard.h"
|
|
#include "common/file.h"
|
|
#include "common/savefile.h"
|
|
#include "common/config-manager.h"
|
|
|
|
#include "base/plugins.h"
|
|
#include "base/version.h"
|
|
|
|
#include "sound/mixer.h"
|
|
|
|
#include "drascula/drascula.h"
|
|
|
|
namespace Drascula {
|
|
|
|
struct GameSettings {
|
|
const char *gameid;
|
|
const char *description;
|
|
byte id;
|
|
uint32 features;
|
|
const char *detectname;
|
|
};
|
|
|
|
static const GameSettings drasculaSettings[] = {
|
|
{"drascula", "Drascula game", 0, 0, 0},
|
|
|
|
{NULL, NULL, 0, 0, NULL}
|
|
};
|
|
|
|
DrasculaEngine::DrasculaEngine(OSystem *syst, const DrasculaGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
|
|
|
|
// Setup mixer
|
|
_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
|
|
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
|
|
|
|
_rnd = new Common::RandomSource();
|
|
syst->getEventManager()->registerRandomSource(*_rnd, "drascula");
|
|
|
|
int cd_num = ConfMan.getInt("cdrom");
|
|
if (cd_num >= 0)
|
|
_system->openCD(cd_num);
|
|
|
|
_lang = 0;
|
|
}
|
|
|
|
DrasculaEngine::~DrasculaEngine() {
|
|
delete _rnd;
|
|
|
|
free(_charMap);
|
|
free(_itemLocations);
|
|
free(_polX);
|
|
free(_polY);
|
|
free(_verbBarX);
|
|
free(_x1d_menu);
|
|
free(_y1d_menu);
|
|
free(_frameX);
|
|
free(_candleX);
|
|
free(_candleY);
|
|
free(_pianistX);
|
|
free(_drunkX);
|
|
free(_roomPreUpdates);
|
|
free(_roomUpdates);
|
|
free(_roomActions);
|
|
freeTexts(_text);
|
|
freeTexts(_textd);
|
|
freeTexts(_textb);
|
|
freeTexts(_textbj);
|
|
freeTexts(_texte);
|
|
freeTexts(_texti);
|
|
freeTexts(_textl);
|
|
freeTexts(_textp);
|
|
freeTexts(_textt);
|
|
freeTexts(_textvb);
|
|
freeTexts(_textsys);
|
|
freeTexts(_texthis);
|
|
freeTexts(_textverbs);
|
|
freeTexts(_textmisc);
|
|
freeTexts(_textd1);
|
|
}
|
|
|
|
int DrasculaEngine::init() {
|
|
// Initialize backend
|
|
_system->beginGFXTransaction();
|
|
initCommonGFX(false);
|
|
_system->initSize(320, 200);
|
|
_system->endGFXTransaction();
|
|
|
|
switch (getLanguage()) {
|
|
case Common::EN_ANY:
|
|
_lang = 0;
|
|
break;
|
|
case Common::ES_ESP:
|
|
_lang = 1;
|
|
break;
|
|
case Common::DE_DEU:
|
|
_lang = 2;
|
|
break;
|
|
case Common::FR_FRA:
|
|
_lang = 3;
|
|
break;
|
|
case Common::IT_ITA:
|
|
_lang = 4;
|
|
break;
|
|
default:
|
|
warning("Unknown game language. Falling back to English");
|
|
_lang = 0;
|
|
}
|
|
|
|
_charMap = 0;
|
|
_itemLocations = 0;
|
|
_polX = 0;
|
|
_polY = 0;
|
|
_verbBarX = 0;
|
|
_x1d_menu = 0;
|
|
_y1d_menu = 0;
|
|
_frameX = 0;
|
|
_candleX = 0;
|
|
_candleY = 0;
|
|
_pianistX = 0;
|
|
_drunkX = 0;
|
|
_roomPreUpdates = 0;
|
|
_roomUpdates = 0;
|
|
_roomActions = 0;
|
|
_text = 0;
|
|
_textd = 0;
|
|
_textb = 0;
|
|
_textbj = 0;
|
|
_texte = 0;
|
|
_texti = 0;
|
|
_textl = 0;
|
|
_textp = 0;
|
|
_textt = 0;
|
|
_textvb = 0;
|
|
_textsys = 0;
|
|
_texthis = 0;
|
|
_textverbs = 0;
|
|
_textmisc = 0;
|
|
_textd1 = 0;
|
|
|
|
if (!loadDrasculaDat())
|
|
return 1;
|
|
|
|
setupRoomsTable();
|
|
loadArchives();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int DrasculaEngine::go() {
|
|
currentChapter = 1; // values from 1 to 6 will start each part of game
|
|
hay_que_load = 0;
|
|
|
|
for (;;) {
|
|
int i;
|
|
|
|
VGA = (byte *)malloc(320 * 200);
|
|
memset(VGA, 0, 64000);
|
|
|
|
takeObject = 0;
|
|
menuBar = 0; menuScreen = 0; hasName = 0;
|
|
frame_y = 0;
|
|
curX = -1; characterMoved = 0; trackProtagonist = 3; num_frame = 0; hare_se_ve = 1;
|
|
checkFlags = 1;
|
|
doBreak = 0;
|
|
walkToObject = 0;
|
|
stepX = STEP_X; stepY = STEP_Y;
|
|
curHeight = CHARACTER_HEIGHT; curWidth = CHARACTER_WIDTH; feetHeight = FEET_HEIGHT;
|
|
talkHeight = TALK_HEIGHT; talkWidth = TALK_WIDTH;
|
|
hasAnswer = 0;
|
|
savedTime = 0;
|
|
changeColor = 0;
|
|
breakOut = 0;
|
|
vonBraunX = 120; trackVonBraun = 1; vonBraunHasMoved = 0;
|
|
framesWithoutAction = 0;
|
|
term_int = 0;
|
|
musicStopped = 0;
|
|
selectionMade = 0;
|
|
UsingMem = 0;
|
|
globalSpeed = 0;
|
|
curExcuseLook = 0;
|
|
curExcuseAction = 0;
|
|
roomNumber = 0;
|
|
|
|
for (i = 0; i < 8; i++)
|
|
actorFrames[i] = 0;
|
|
actorFrames[kFrameVonBraun] = 1;
|
|
|
|
allocMemory();
|
|
|
|
withVoices = 0;
|
|
selectionMade = 0;
|
|
|
|
if (currentChapter != 6)
|
|
loadPic(95, tableSurface);
|
|
|
|
if (currentChapter == 1) {
|
|
loadPic(96, frontSurface, COMPLETE_PAL);
|
|
loadPic(99, backSurface);
|
|
loadPic(97, extraSurface);
|
|
} else if (currentChapter == 2) {
|
|
loadPic(96, frontSurface, COMPLETE_PAL);
|
|
loadPic("pts.alg", drawSurface2);
|
|
} else if (currentChapter == 3) {
|
|
loadPic("aux13.alg", bgSurface, COMPLETE_PAL);
|
|
loadPic(96, frontSurface);
|
|
loadPic(97, extraSurface);
|
|
loadPic(99, backSurface);
|
|
} else if (currentChapter == 4) {
|
|
loadPic(96, frontSurface, COMPLETE_PAL);
|
|
if (hay_que_load == 0)
|
|
animation_ray();
|
|
loadPic(96, frontSurface);
|
|
clearRoom();
|
|
loadPic(99, backSurface);
|
|
loadPic(97, extraSurface);
|
|
} else if (currentChapter == 5) {
|
|
loadPic(96, frontSurface, COMPLETE_PAL);
|
|
loadPic(97, extraSurface);
|
|
loadPic(99, backSurface);
|
|
} else if (currentChapter == 6) {
|
|
igorX = 105, igorY = 85, trackIgor = 1;
|
|
drasculaX = 62, drasculaY = 99, trackDrascula = 1;
|
|
actorFrames[kFramePendulum] = 0;
|
|
flag_tv = 0;
|
|
|
|
loadPic(96, frontSurface, COMPLETE_PAL);
|
|
loadPic(99, backSurface);
|
|
loadPic(97, extraSurface);
|
|
loadPic(95, tableSurface);
|
|
}
|
|
memset(iconName, 0, sizeof(iconName));
|
|
|
|
for (i = 0; i < 6; i++)
|
|
strcpy(iconName[i + 1], _textverbs[_lang][i]);
|
|
|
|
assignDefaultPalette();
|
|
if (!runCurrentChapter()) {
|
|
endChapter();
|
|
break;
|
|
}
|
|
endChapter();
|
|
if (currentChapter == 6)
|
|
break;
|
|
|
|
currentChapter++;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void DrasculaEngine::endChapter() {
|
|
stopSound();
|
|
clearRoom();
|
|
black();
|
|
MusicFadeout();
|
|
stopMusic();
|
|
freeMemory();
|
|
free(VGA);
|
|
}
|
|
|
|
bool DrasculaEngine::runCurrentChapter() {
|
|
int n;
|
|
|
|
if (_lang == kSpanish)
|
|
textSurface = extraSurface;
|
|
else
|
|
textSurface = tableSurface;
|
|
|
|
previousMusic = -1;
|
|
|
|
if (currentChapter != 2) {
|
|
int soc = 0;
|
|
for (n = 0; n < 6; n++) {
|
|
soc = soc + CHARACTER_WIDTH;
|
|
_frameX[n] = soc;
|
|
}
|
|
}
|
|
|
|
for (n = 1; n < 43; n++)
|
|
inventoryObjects[n] = 0;
|
|
|
|
for (n = 0; n < NUM_FLAGS; n++)
|
|
flags[n] = 0;
|
|
|
|
if (currentChapter == 2) {
|
|
flags[16] = 1;
|
|
flags[17] = 1;
|
|
flags[27] = 1;
|
|
}
|
|
|
|
for (n = 1; n < 7; n++)
|
|
inventoryObjects[n] = n;
|
|
|
|
if (currentChapter == 1) {
|
|
pickObject(28);
|
|
|
|
if (hay_que_load == 0)
|
|
animation_1_1();
|
|
|
|
withoutVerb();
|
|
loadPic("2aux62.alg", drawSurface2);
|
|
trackProtagonist = 1;
|
|
objExit = 104;
|
|
if (hay_que_load != 0) {
|
|
if (!loadGame(saveName)) {
|
|
return true;
|
|
}
|
|
} else {
|
|
enterRoom(62);
|
|
curX = -20;
|
|
curY = 56;
|
|
gotoObject(65, 145);
|
|
}
|
|
} else if (currentChapter == 2) {
|
|
addObject(kItemPhone);
|
|
trackProtagonist = 3;
|
|
objExit = 162;
|
|
if (hay_que_load == 0)
|
|
enterRoom(14);
|
|
else {
|
|
if (!loadGame(saveName)) {
|
|
return true;
|
|
}
|
|
}
|
|
} else if (currentChapter == 3) {
|
|
addObject(kItemPhone);
|
|
addObject(kItemEarplugs);
|
|
addObject(kItemSickle);
|
|
addObject(kItemHandbag);
|
|
addObject(kItemCross);
|
|
addObject(kItemReefer);
|
|
addObject(kItemOneCoin);
|
|
flags[1] = 1;
|
|
trackProtagonist = 1;
|
|
objExit = 99;
|
|
if (hay_que_load == 0)
|
|
enterRoom(20);
|
|
else {
|
|
if (!loadGame(saveName)) {
|
|
return true;
|
|
}
|
|
}
|
|
// From here onwards the items have different IDs
|
|
} else if (currentChapter == 4) {
|
|
addObject(kItemPhone2);
|
|
addObject(kItemCross2);
|
|
addObject(kItemReefer2);
|
|
addObject(kItemOneCoin2);
|
|
objExit = 100;
|
|
if (hay_que_load == 0) {
|
|
enterRoom(21);
|
|
trackProtagonist = 0;
|
|
curX = 235;
|
|
curY = 164;
|
|
} else {
|
|
if (!loadGame(saveName)) {
|
|
return true;
|
|
}
|
|
}
|
|
} else if (currentChapter == 5) {
|
|
addObject(28);
|
|
addObject(7);
|
|
addObject(9);
|
|
addObject(11);
|
|
addObject(13);
|
|
addObject(14);
|
|
addObject(15);
|
|
addObject(17);
|
|
addObject(20);
|
|
trackProtagonist = 1;
|
|
objExit = 100;
|
|
if (hay_que_load == 0) {
|
|
enterRoom(45);
|
|
} else {
|
|
if (!loadGame(saveName)) {
|
|
return true;
|
|
}
|
|
}
|
|
} else if (currentChapter == 6) {
|
|
addObject(28);
|
|
addObject(9);
|
|
|
|
trackProtagonist = 1;
|
|
objExit = 104;
|
|
if (hay_que_load == 0) {
|
|
enterRoom(58);
|
|
animation_1_6();
|
|
} else {
|
|
if (!loadGame(saveName)) {
|
|
return true;
|
|
}
|
|
loadPic("auxdr.alg", drawSurface2);
|
|
}
|
|
}
|
|
|
|
while (1) {
|
|
if (characterMoved == 0) {
|
|
stepX = STEP_X;
|
|
stepY = STEP_Y;
|
|
}
|
|
if (characterMoved == 0 && walkToObject == 1) {
|
|
trackProtagonist = trackFinal;
|
|
walkToObject = 0;
|
|
}
|
|
|
|
if (currentChapter == 2) {
|
|
// NOTE: the checks for room number 14 below are a hack used in the original
|
|
// game, and move the character to a place where his feet are not drawn above
|
|
// the pianist's head. Originally, walkToObject was not updated properly, which
|
|
// lead to an incorrect setting of the protagonist's tracking flag (above). This
|
|
// made the character start walking off screen, as his actual position was
|
|
// different than the displayed one
|
|
if (roomNumber == 3 && (curX == 279) && (curY + curHeight == 101)) {
|
|
animation_1_2();
|
|
} else if (roomNumber == 14 && (curX == 214) && (curY + curHeight == 121)) {
|
|
walkToObject = 1;
|
|
gotoObject(190, 130);
|
|
} else if (roomNumber == 14 && (curX == 246) && (curY + curHeight == 112)) {
|
|
walkToObject = 1;
|
|
gotoObject(190, 130);
|
|
}
|
|
}
|
|
|
|
moveCursor();
|
|
updateScreen();
|
|
|
|
if (currentChapter == 2) {
|
|
if (musicStatus() == 0 && roomMusic != 0)
|
|
playMusic(roomMusic);
|
|
} else {
|
|
if (musicStatus() == 0)
|
|
playMusic(roomMusic);
|
|
}
|
|
|
|
updateEvents();
|
|
|
|
if (menuScreen == 0 && takeObject == 1)
|
|
checkObjects();
|
|
|
|
if (rightMouseButton == 1 && menuScreen == 1) {
|
|
delay(100);
|
|
if (currentChapter == 2)
|
|
loadPic(menuBackground, backSurface);
|
|
else
|
|
loadPic(99, backSurface);
|
|
setPalette((byte *)&gamePalette);
|
|
menuScreen = 0;
|
|
updateEvents();
|
|
}
|
|
if (rightMouseButton == 1 && menuScreen == 0) {
|
|
delay(100);
|
|
characterMoved = 0;
|
|
if (trackProtagonist == 2)
|
|
trackProtagonist = 1;
|
|
if (currentChapter == 4)
|
|
loadPic("icons2.alg", backSurface);
|
|
else if (currentChapter == 5)
|
|
loadPic("icons3.alg", backSurface);
|
|
else if (currentChapter == 6)
|
|
loadPic("iconsp.alg", backSurface);
|
|
else
|
|
loadPic("icons.alg", backSurface);
|
|
menuScreen = 1;
|
|
updateEvents();
|
|
withoutVerb();
|
|
}
|
|
|
|
if (leftMouseButton == 1 && menuBar == 1) {
|
|
delay(100);
|
|
selectVerbFromBar();
|
|
} else if (leftMouseButton == 1 && takeObject == 0) {
|
|
delay(100);
|
|
if (verify1())
|
|
return true;
|
|
} else if (leftMouseButton == 1 && takeObject == 1) {
|
|
if (verify2())
|
|
return true;
|
|
}
|
|
|
|
menuBar = (mouseY < 24 && menuScreen == 0) ? 1 : 0;
|
|
|
|
Common::KeyCode key = getScan();
|
|
if (key == Common::KEYCODE_F1 && menuScreen == 0) {
|
|
selectVerb(1);
|
|
} else if (key == Common::KEYCODE_F2 && menuScreen == 0) {
|
|
selectVerb(2);
|
|
} else if (key == Common::KEYCODE_F3 && menuScreen == 0) {
|
|
selectVerb(3);
|
|
} else if (key == Common::KEYCODE_F4 && menuScreen == 0) {
|
|
selectVerb(4);
|
|
} else if (key == Common::KEYCODE_F5 && menuScreen == 0) {
|
|
selectVerb(5);
|
|
} else if (key == Common::KEYCODE_F6 && menuScreen == 0) {
|
|
selectVerb(6);
|
|
} else if (key == Common::KEYCODE_F9) {
|
|
volumeControls();
|
|
} else if (key == Common::KEYCODE_F10) {
|
|
if (!saveLoadScreen())
|
|
return true;
|
|
} else if (key == Common::KEYCODE_F8) {
|
|
withoutVerb();
|
|
} else if (key == Common::KEYCODE_v) {
|
|
withVoices = 1;
|
|
print_abc(_textsys[_lang][2], 96, 86);
|
|
updateScreen();
|
|
delay(1410);
|
|
} else if (key == Common::KEYCODE_t) {
|
|
withVoices = 0;
|
|
print_abc(_textsys[_lang][3], 94, 86);
|
|
updateScreen();
|
|
delay(1460);
|
|
} else if (key == Common::KEYCODE_ESCAPE) {
|
|
if (!confirmExit())
|
|
return false;
|
|
} else if (currentChapter == 6 && key == Common::KEYCODE_0 && roomNumber == 61) {
|
|
loadPic("alcbar.alg", bgSurface, 255);
|
|
}
|
|
|
|
if (leftMouseButton != 0 || rightMouseButton != 0 || key != 0)
|
|
if (currentChapter != 3)
|
|
framesWithoutAction = 0;
|
|
|
|
if (framesWithoutAction == 15000) {
|
|
screenSaver();
|
|
if (currentChapter != 3)
|
|
framesWithoutAction = 0;
|
|
}
|
|
|
|
if (currentChapter != 3)
|
|
framesWithoutAction++;
|
|
|
|
}
|
|
}
|
|
|
|
char *DrasculaEngine::getLine(char *buf, int len) {
|
|
byte c;
|
|
char *b;
|
|
|
|
for (;;) {
|
|
b = buf;
|
|
while (!_arj.eos()) {
|
|
c = ~_arj.readByte();
|
|
if (c == '\r')
|
|
continue;
|
|
if (c == '\n' || b - buf >= (len - 1))
|
|
break;
|
|
*b++ = c;
|
|
}
|
|
*b = '\0';
|
|
if (_arj.eos() && b == buf)
|
|
return NULL;
|
|
if (b != buf)
|
|
break;
|
|
}
|
|
return buf;
|
|
}
|
|
|
|
void DrasculaEngine::getIntFromLine(char *buf, int len, int* result) {
|
|
getLine(buf, len);
|
|
sscanf(buf, "%d", result);
|
|
}
|
|
|
|
void DrasculaEngine::getStringFromLine(char *buf, int len, char* result) {
|
|
getLine(buf, len);
|
|
sscanf(buf, "%s", result);
|
|
}
|
|
|
|
bool DrasculaEngine::verify1() {
|
|
int l;
|
|
|
|
if (menuScreen == 1)
|
|
removeObject();
|
|
else {
|
|
for (l = 0; l < numRoomObjs; l++) {
|
|
if (mouseX >= x1[l] && mouseY >= y1[l]
|
|
&& mouseX <= x2[l] && mouseY <= y2[l] && doBreak == 0) {
|
|
if (exitRoom(l))
|
|
return true;
|
|
if (doBreak == 1)
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (mouseX > curX && mouseY > curY
|
|
&& mouseX < curX + curWidth && mouseY < curY + curHeight)
|
|
doBreak = 1;
|
|
|
|
for (l = 0; l < numRoomObjs; l++) {
|
|
if (mouseX > x1[l] && mouseY > y1[l]
|
|
&& mouseX < x2[l] && mouseY < y2[l] && doBreak == 0) {
|
|
roomX = roomObjX[l];
|
|
roomY = roomObjY[l];
|
|
trackFinal = trackObj[l];
|
|
doBreak = 1;
|
|
walkToObject = 1;
|
|
startWalking();
|
|
}
|
|
}
|
|
|
|
if (doBreak == 0) {
|
|
roomX = CLIP(mouseX, floorX1, floorX2);
|
|
roomY = CLIP(mouseY, floorY1 + feetHeight, floorY2);
|
|
startWalking();
|
|
}
|
|
doBreak = 0;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool DrasculaEngine::verify2() {
|
|
int l;
|
|
|
|
if (menuScreen == 1) {
|
|
if (pickupObject())
|
|
return true;
|
|
} else {
|
|
if (!strcmp(textName, "hacker") && hasName == 1) {
|
|
if (checkAction(50))
|
|
return true;
|
|
} else {
|
|
for (l = 0; l < numRoomObjs; l++) {
|
|
if (mouseX > x1[l] && mouseY > y1[l]
|
|
&& mouseX < x2[l] && mouseY < y2[l] && visible[l] == 1) {
|
|
trackFinal = trackObj[l];
|
|
walkToObject = 1;
|
|
gotoObject(roomObjX[l], roomObjY[l]);
|
|
if (checkAction(objectNum[l]))
|
|
return true;
|
|
if (currentChapter == 4)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
Common::KeyCode DrasculaEngine::getScan() {
|
|
updateEvents();
|
|
|
|
return _keyPressed.keycode;
|
|
}
|
|
|
|
void DrasculaEngine::updateEvents() {
|
|
Common::Event event;
|
|
Common::EventManager *eventMan = _system->getEventManager();
|
|
|
|
AudioCD.updateCD();
|
|
|
|
while (eventMan->pollEvent(event)) {
|
|
switch (event.type) {
|
|
case Common::EVENT_KEYDOWN:
|
|
_keyPressed = event.kbd;
|
|
break;
|
|
case Common::EVENT_KEYUP:
|
|
_keyPressed.keycode = Common::KEYCODE_INVALID;
|
|
break;
|
|
case Common::EVENT_MOUSEMOVE:
|
|
mouseX = event.mouse.x;
|
|
mouseY = event.mouse.y;
|
|
break;
|
|
case Common::EVENT_LBUTTONDOWN:
|
|
leftMouseButton = 1;
|
|
break;
|
|
case Common::EVENT_LBUTTONUP:
|
|
leftMouseButton = 0;
|
|
break;
|
|
case Common::EVENT_RBUTTONDOWN:
|
|
rightMouseButton = 1;
|
|
break;
|
|
case Common::EVENT_RBUTTONUP:
|
|
rightMouseButton = 0;
|
|
break;
|
|
case Common::EVENT_QUIT:
|
|
// TODO
|
|
endChapter();
|
|
_system->quit();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void DrasculaEngine::delay(int ms) {
|
|
_system->delayMillis(ms * 2); // originaly was 1
|
|
}
|
|
|
|
void DrasculaEngine::pause(int duration) {
|
|
_system->delayMillis(duration * 30); // was originaly 2
|
|
}
|
|
|
|
int DrasculaEngine::getTime() {
|
|
return _system->getMillis() / 20; // originaly was 1
|
|
}
|
|
|
|
void DrasculaEngine::reduce_hare_chico(int xx1, int yy1, int xx2, int yy2, int width, int height, int factor, byte *dir_inicio, byte *dir_fin) {
|
|
float totalX, totalY;
|
|
int n, m;
|
|
float pixelX, pixelY;
|
|
int pixelPos[6];
|
|
|
|
newWidth = (width * factor) / 100;
|
|
newHeight = (height * factor) / 100;
|
|
|
|
totalX = width / newWidth;
|
|
totalY = height / newHeight;
|
|
|
|
pixelX = xx1;
|
|
pixelY = yy1;
|
|
|
|
for (n = 0; n < newHeight; n++) {
|
|
for (m = 0; m < newWidth; m++) {
|
|
pixelPos[0] = (int)pixelX;
|
|
pixelPos[1] = (int)pixelY;
|
|
pixelPos[2] = xx2 + m;
|
|
pixelPos[3] = yy2 + n;
|
|
pixelPos[4] = 1;
|
|
pixelPos[5] = 1;
|
|
|
|
copyRectClip(pixelPos, dir_inicio, dir_fin);
|
|
|
|
pixelX += totalX;
|
|
}
|
|
pixelX = xx1;
|
|
pixelY += totalY;
|
|
}
|
|
}
|
|
|
|
void DrasculaEngine::hipo_sin_nadie(int counter){
|
|
int y = 0, trackCharacter = 0;
|
|
if (currentChapter == 3)
|
|
y = -1;
|
|
|
|
do {
|
|
counter--;
|
|
|
|
copyBackground(0, 0, 0, 0, 320, 200, bgSurface, screenSurface);
|
|
if (currentChapter == 3)
|
|
updateScreen(0, 0, 0, y, 320, 200, screenSurface);
|
|
else
|
|
updateScreen(0, 1, 0, y, 320, 198, screenSurface);
|
|
|
|
if (trackCharacter == 0)
|
|
y++;
|
|
else
|
|
y--;
|
|
|
|
if (currentChapter == 3) {
|
|
if (y == 1)
|
|
trackCharacter = 1;
|
|
if (y == -1)
|
|
trackCharacter = 0;
|
|
} else {
|
|
if (y == 2)
|
|
trackCharacter = 1;
|
|
if (y == 0)
|
|
trackCharacter = 0;
|
|
}
|
|
} while (counter > 0);
|
|
|
|
copyBackground(0, 0, 0, 0, 320, 200, bgSurface, screenSurface);
|
|
updateScreen();
|
|
}
|
|
|
|
bool DrasculaEngine::loadDrasculaDat() {
|
|
Common::File in;
|
|
int i;
|
|
|
|
in.open("drascula.dat");
|
|
|
|
if (!in.isOpen()) {
|
|
Common::String errorMessage = "You're missing the 'drascula.dat' file. Get it from the ScummVM website";
|
|
GUIErrorMessage(errorMessage);
|
|
warning(errorMessage.c_str());
|
|
|
|
return false;
|
|
}
|
|
|
|
char buf[256];
|
|
int ver;
|
|
|
|
in.read(buf, 8);
|
|
buf[8] = '\0';
|
|
|
|
if (strcmp(buf, "DRASCULA")) {
|
|
Common::String errorMessage = "File 'drascula.dat' is corrupt. Get it from the ScummVM website";
|
|
GUIErrorMessage(errorMessage);
|
|
warning(errorMessage.c_str());
|
|
|
|
return false;
|
|
}
|
|
|
|
ver = in.readByte();
|
|
|
|
if (ver != DRASCULA_DAT_VER) {
|
|
snprintf(buf, 256, "File 'drascula.dat' is wrong version. Expected %d but got %d. Get it from the ScummVM website", DRASCULA_DAT_VER, ver);
|
|
GUIErrorMessage(buf);
|
|
warning(buf);
|
|
|
|
return false;
|
|
}
|
|
|
|
_charMapSize = in.readUint16BE();
|
|
_charMap = (CharInfo *)malloc(sizeof(CharInfo) * _charMapSize);
|
|
for (i = 0; i < _charMapSize; i++) {
|
|
_charMap[i].inChar = in.readByte();
|
|
_charMap[i].mappedChar = in.readSint16BE();
|
|
_charMap[i].charType = in.readByte();
|
|
}
|
|
|
|
_itemLocationsSize = in.readUint16BE();
|
|
_itemLocations = (ItemLocation *)malloc(sizeof(ItemLocation) * _itemLocationsSize);
|
|
for (i = 0; i < _itemLocationsSize; i++) {
|
|
_itemLocations[i].x = in.readSint16BE();
|
|
_itemLocations[i].y = in.readSint16BE();
|
|
}
|
|
|
|
_polXSize = in.readUint16BE();
|
|
_polX = (int *)malloc(sizeof(int) * _polXSize);
|
|
_polY = (int *)malloc(sizeof(int) * _polXSize);
|
|
for (i = 0; i < _polXSize; i++) {
|
|
_polX[i] = in.readSint16BE();
|
|
_polY[i] = in.readSint16BE();
|
|
}
|
|
|
|
_verbBarXSize = in.readUint16BE();
|
|
_verbBarX = (int *)malloc(sizeof(int) * _verbBarXSize);
|
|
for (i = 0; i < _verbBarXSize; i++) {
|
|
_verbBarX[i] = in.readSint16BE();
|
|
}
|
|
|
|
_x1dMenuSize = in.readUint16BE();
|
|
_x1d_menu = (int *)malloc(sizeof(int) * _x1dMenuSize);
|
|
_y1d_menu = (int *)malloc(sizeof(int) * _x1dMenuSize);
|
|
for (i = 0; i < _x1dMenuSize; i++) {
|
|
_x1d_menu[i] = in.readSint16BE();
|
|
_y1d_menu[i] = in.readSint16BE();
|
|
}
|
|
|
|
_frameXSize = in.readUint16BE();
|
|
_frameX = (int *)malloc(sizeof(int) * _frameXSize);
|
|
for (i = 0; i < _frameXSize; i++) {
|
|
_frameX[i] = in.readSint16BE();
|
|
}
|
|
|
|
_candleXSize = in.readUint16BE();
|
|
_candleX = (int *)malloc(sizeof(int) * _candleXSize);
|
|
_candleY = (int *)malloc(sizeof(int) * _candleXSize);
|
|
for (i = 0; i < _candleXSize; i++) {
|
|
_candleX[i] = in.readSint16BE();
|
|
_candleY[i] = in.readSint16BE();
|
|
}
|
|
|
|
_pianistXSize = in.readUint16BE();
|
|
_pianistX = (int *)malloc(sizeof(int) * _pianistXSize);
|
|
for (i = 0; i < _pianistXSize; i++) {
|
|
_pianistX[i] = in.readSint16BE();
|
|
}
|
|
|
|
_drunkXSize = in.readUint16BE();
|
|
_drunkX = (int *)malloc(sizeof(int) * _drunkXSize);
|
|
for (i = 0; i < _drunkXSize; i++) {
|
|
_drunkX[i] = in.readSint16BE();
|
|
}
|
|
|
|
_roomPreUpdatesSize = in.readUint16BE();
|
|
_roomPreUpdates = (RoomUpdate *)malloc(sizeof(RoomUpdate) * _roomPreUpdatesSize);
|
|
for (i = 0; i < _roomPreUpdatesSize; i++) {
|
|
_roomPreUpdates[i].roomNum = in.readSint16BE();
|
|
_roomPreUpdates[i].flag = in.readSint16BE();
|
|
_roomPreUpdates[i].flagValue = in.readSint16BE();
|
|
_roomPreUpdates[i].sourceX = in.readSint16BE();
|
|
_roomPreUpdates[i].sourceY = in.readSint16BE();
|
|
_roomPreUpdates[i].destX = in.readSint16BE();
|
|
_roomPreUpdates[i].destY = in.readSint16BE();
|
|
_roomPreUpdates[i].width = in.readSint16BE();
|
|
_roomPreUpdates[i].height = in.readSint16BE();
|
|
_roomPreUpdates[i].type = in.readSint16BE();
|
|
}
|
|
|
|
_roomUpdatesSize = in.readUint16BE();
|
|
_roomUpdates = (RoomUpdate *)malloc(sizeof(RoomUpdate) * _roomUpdatesSize);
|
|
for (i = 0; i < _roomUpdatesSize; i++) {
|
|
_roomUpdates[i].roomNum = in.readSint16BE();
|
|
_roomUpdates[i].flag = in.readSint16BE();
|
|
_roomUpdates[i].flagValue = in.readSint16BE();
|
|
_roomUpdates[i].sourceX = in.readSint16BE();
|
|
_roomUpdates[i].sourceY = in.readSint16BE();
|
|
_roomUpdates[i].destX = in.readSint16BE();
|
|
_roomUpdates[i].destY = in.readSint16BE();
|
|
_roomUpdates[i].width = in.readSint16BE();
|
|
_roomUpdates[i].height = in.readSint16BE();
|
|
_roomUpdates[i].type = in.readSint16BE();
|
|
}
|
|
|
|
_roomActionsSize = in.readUint16BE();
|
|
_roomActions = (RoomTalkAction *)malloc(sizeof(RoomTalkAction) * _roomActionsSize);
|
|
for (i = 0; i < _roomActionsSize; i++) {
|
|
_roomActions[i].room = in.readSint16BE();
|
|
_roomActions[i].chapter = in.readSint16BE();
|
|
_roomActions[i].action = in.readSint16BE();
|
|
_roomActions[i].objectID = in.readSint16BE();
|
|
_roomActions[i].speechID = in.readSint16BE();
|
|
}
|
|
|
|
_numLangs = in.readUint16BE();
|
|
|
|
_text = loadTexts(in);
|
|
_textd = loadTexts(in);
|
|
_textb = loadTexts(in);
|
|
_textbj = loadTexts(in);
|
|
_texte = loadTexts(in);
|
|
_texti = loadTexts(in);
|
|
_textl = loadTexts(in);
|
|
_textp = loadTexts(in);
|
|
_textt = loadTexts(in);
|
|
_textvb = loadTexts(in);
|
|
_textsys = loadTexts(in);
|
|
_texthis = loadTexts(in);
|
|
_textverbs = loadTexts(in);
|
|
_textmisc = loadTexts(in);
|
|
_textd1 = loadTexts(in);
|
|
|
|
return true;
|
|
}
|
|
|
|
char ***DrasculaEngine::loadTexts(Common::File &in) {
|
|
int numTexts = in.readUint16BE();
|
|
char ***res;
|
|
int entryLen;
|
|
char *pos;
|
|
int len;
|
|
|
|
res = (char ***)malloc(sizeof(char *) * _numLangs);
|
|
|
|
for (int lang = 0; lang < _numLangs; lang++) {
|
|
entryLen = in.readUint16BE();
|
|
|
|
res[lang] = (char **)malloc(sizeof(char *) * numTexts);
|
|
|
|
pos = (char *)malloc(entryLen);
|
|
res[lang][0] = pos;
|
|
|
|
in.read(res[lang][0], entryLen);
|
|
|
|
pos += DATAALIGNMENT;
|
|
|
|
for (int i = 1; i < numTexts; i++) {
|
|
pos -= 2;
|
|
|
|
len = READ_BE_UINT16(pos);
|
|
pos += 2 + len;
|
|
|
|
res[lang][i] = pos;
|
|
}
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
void DrasculaEngine::freeTexts(char ***ptr) {
|
|
for (int lang = 0; lang < _numLangs; lang++) {
|
|
free(ptr[lang][0] - DATAALIGNMENT);
|
|
free(ptr[lang]);
|
|
}
|
|
free(ptr);
|
|
}
|
|
|
|
} // End of namespace Drascula
|