2005-01-09 16:06:29 +00:00
|
|
|
/* ScummVM - Scumm Interpreter
|
|
|
|
* Copyright (C) 2004-2005 The ScummVM project
|
2004-04-09 12:36:06 +00:00
|
|
|
*
|
|
|
|
* 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
|
2004-10-15 06:06:47 +00:00
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2004-04-09 12:36:06 +00:00
|
|
|
* 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
|
2005-10-18 01:30:26 +00:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2004-04-09 12:36:06 +00:00
|
|
|
*
|
|
|
|
* $Header$
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2005-06-24 15:23:51 +00:00
|
|
|
#include "common/stdafx.h"
|
2004-04-09 12:36:06 +00:00
|
|
|
|
2005-08-19 22:12:09 +00:00
|
|
|
#include "backends/fs/fs.h"
|
|
|
|
|
2004-04-09 12:36:06 +00:00
|
|
|
#include "base/gameDetector.h"
|
|
|
|
#include "base/plugins.h"
|
|
|
|
|
|
|
|
#include "common/config-manager.h"
|
2005-08-19 22:12:09 +00:00
|
|
|
#include "common/file.h"
|
|
|
|
#include "common/system.h"
|
2005-10-13 21:12:47 +00:00
|
|
|
#include "common/md5.h"
|
2005-08-19 22:12:09 +00:00
|
|
|
|
|
|
|
#include "sound/mixer.h"
|
2004-11-11 13:37:35 +00:00
|
|
|
#include "sound/mididrv.h"
|
2005-10-12 19:15:32 +00:00
|
|
|
#include "sound/voc.h"
|
|
|
|
#include "sound/audiostream.h"
|
2004-04-09 12:36:06 +00:00
|
|
|
|
2005-06-24 16:01:42 +00:00
|
|
|
#include "kyra/kyra.h"
|
|
|
|
#include "kyra/resource.h"
|
2005-08-19 22:12:09 +00:00
|
|
|
#include "kyra/screen.h"
|
2005-06-24 16:01:42 +00:00
|
|
|
#include "kyra/script.h"
|
2005-10-06 11:57:02 +00:00
|
|
|
#include "kyra/seqplayer.h"
|
2005-06-24 16:01:42 +00:00
|
|
|
#include "kyra/sound.h"
|
2005-10-03 20:21:18 +00:00
|
|
|
#include "kyra/sprites.h"
|
2005-08-19 22:12:09 +00:00
|
|
|
#include "kyra/wsamovie.h"
|
|
|
|
|
2005-10-03 20:21:18 +00:00
|
|
|
#define TEST_SPRITES 1
|
|
|
|
|
2005-08-19 22:12:09 +00:00
|
|
|
using namespace Kyra;
|
2004-10-15 06:06:47 +00:00
|
|
|
|
2005-10-13 21:12:47 +00:00
|
|
|
enum {
|
|
|
|
// We only compute MD5 of the first megabyte of our data files.
|
|
|
|
kMD5FileSizeLimit = 1024 * 1024
|
|
|
|
};
|
|
|
|
|
|
|
|
// Kyra MD5 detection brutally ripped from the Gobliins engine.
|
2004-10-15 06:06:47 +00:00
|
|
|
struct KyraGameSettings {
|
2004-10-16 22:28:29 +00:00
|
|
|
const char *name;
|
|
|
|
const char *description;
|
2005-10-13 21:12:47 +00:00
|
|
|
byte id;
|
2004-10-16 22:28:29 +00:00
|
|
|
uint32 features;
|
2005-10-13 21:12:47 +00:00
|
|
|
const char *md5sum;
|
|
|
|
const char *checkFile;
|
2004-10-16 22:28:29 +00:00
|
|
|
GameSettings toGameSettings() const {
|
|
|
|
GameSettings dummy = { name, description, features };
|
|
|
|
return dummy;
|
|
|
|
}
|
2004-10-15 06:06:47 +00:00
|
|
|
};
|
|
|
|
|
2005-10-13 21:12:47 +00:00
|
|
|
static const KyraGameSettings kyra_games[] = {
|
2005-10-14 11:25:48 +00:00
|
|
|
{ "kyra1", "Legend of Kyrandia (Floppy, English)", GI_KYRA1, GF_ENGLISH | GF_FLOPPY,
|
2005-10-13 21:12:47 +00:00
|
|
|
"796e44863dd22fa635b042df1bf16673", "GEMCUT.EMC" },
|
2005-10-14 11:25:48 +00:00
|
|
|
{ "kyra1", "Legend of Kyrandia (Floppy, French)", GI_KYRA1, GF_FRENCH | GF_FLOPPY,
|
2005-10-13 21:12:47 +00:00
|
|
|
"abf8eb360e79a6c2a837751fbd4d3d24", "GEMCUT.EMC" },
|
2005-10-14 11:25:48 +00:00
|
|
|
{ "kyra1", "Legend of Kyrandia (Floppy, German)", GI_KYRA1, GF_GERMAN | GF_FLOPPY,
|
2005-10-13 21:12:47 +00:00
|
|
|
"6018e1dfeaca7fe83f8d0b00eb0dd049", "GEMCUT.EMC"},
|
2005-10-18 19:59:51 +00:00
|
|
|
{ "kyra1", "Legend of Kyrandia (Floppy, Spanish)", GI_KYRA1, GF_SPANISH | GF_FLOPPY, // from VooD
|
|
|
|
"8909b41596913b3f5deaf3c9f1017b01", "GEMCUT.EMC"},
|
2005-10-14 11:25:48 +00:00
|
|
|
{ "kyra1", "Legend of Kyrandia (CD, English)", GI_KYRA1, GF_ENGLISH | GF_TALKIE,
|
2005-10-13 21:12:47 +00:00
|
|
|
"fac399fe62f98671e56a005c5e94e39f", "GEMCUT.PAK" },
|
2005-10-14 11:25:48 +00:00
|
|
|
{ "kyra1", "Legend of Kyrandia (CD, German)", GI_KYRA1, GF_GERMAN | GF_TALKIE,
|
2005-10-13 21:12:47 +00:00
|
|
|
"230f54e6afc007ab4117159181a1c722", "GEMCUT.PAK" },
|
2005-10-14 11:25:48 +00:00
|
|
|
{ "kyra1", "Legend of Kyrandia (CD, French)", GI_KYRA1, GF_FRENCH | GF_TALKIE,
|
2005-10-13 21:12:47 +00:00
|
|
|
"b037c41768b652a040360ffa3556fd2a", "GEMCUT.PAK" },
|
2005-10-18 19:59:51 +00:00
|
|
|
{ "kyra1", "Legend of Kyrandia (Demo)", GI_KYRA1, GF_DEMO | GF_ENGLISH,
|
2005-10-13 21:12:47 +00:00
|
|
|
"fb722947d94897512b13b50cc84fd648", "DEMO1.WSA" },
|
|
|
|
{ 0, 0, 0, 0, 0, 0 }
|
|
|
|
};
|
|
|
|
|
|
|
|
// Keep list of different supported games
|
|
|
|
struct KyraGameList {
|
|
|
|
const char *name;
|
|
|
|
const char *description;
|
|
|
|
uint32 features;
|
|
|
|
GameSettings toGameSettings() const {
|
|
|
|
GameSettings dummy = { name, description, features };
|
|
|
|
return dummy;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
static const KyraGameList kyra_list[] = {
|
2005-10-18 19:59:51 +00:00
|
|
|
{ "kyra1", "Legend of Kyrandia", 0 },
|
2005-10-13 21:12:47 +00:00
|
|
|
{ 0, 0, 0 }
|
2004-10-15 06:06:47 +00:00
|
|
|
};
|
2004-04-09 12:36:06 +00:00
|
|
|
|
|
|
|
GameList Engine_KYRA_gameList() {
|
2004-10-16 22:28:29 +00:00
|
|
|
GameList games;
|
2005-10-13 21:12:47 +00:00
|
|
|
const KyraGameList *g = kyra_list;
|
|
|
|
|
2004-10-16 22:28:29 +00:00
|
|
|
while (g->name) {
|
|
|
|
games.push_back(g->toGameSettings());
|
|
|
|
g++;
|
|
|
|
}
|
|
|
|
return games;
|
2004-04-09 12:36:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DetectedGameList Engine_KYRA_detectGames(const FSList &fslist) {
|
|
|
|
DetectedGameList detectedGames;
|
2005-10-13 21:12:47 +00:00
|
|
|
const KyraGameSettings *g;
|
|
|
|
FSList::const_iterator file;
|
2004-10-15 06:06:47 +00:00
|
|
|
|
2005-10-13 21:12:47 +00:00
|
|
|
// Iterate over all files in the given directory
|
|
|
|
bool isFound = false;
|
|
|
|
for (file = fslist.begin(); file != fslist.end(); file++) {
|
|
|
|
if (file->isDirectory())
|
2004-10-15 06:06:47 +00:00
|
|
|
continue;
|
|
|
|
|
2005-10-13 21:12:47 +00:00
|
|
|
for (g = kyra_games; g->name; g++) {
|
|
|
|
if (scumm_stricmp(file->displayName().c_str(), g->checkFile) == 0)
|
|
|
|
isFound = true;
|
2004-04-09 12:36:06 +00:00
|
|
|
}
|
2005-10-13 21:12:47 +00:00
|
|
|
if (isFound)
|
|
|
|
break;
|
2004-04-09 12:36:06 +00:00
|
|
|
}
|
|
|
|
|
2005-10-13 21:12:47 +00:00
|
|
|
if (file == fslist.end())
|
|
|
|
return detectedGames;
|
|
|
|
|
|
|
|
uint8 md5sum[16];
|
|
|
|
char md5str[32 + 1];
|
|
|
|
|
|
|
|
if (Common::md5_file(file->path().c_str(), md5sum, NULL, kMD5FileSizeLimit)) {
|
|
|
|
for (int i = 0; i < 16; i++) {
|
|
|
|
sprintf(md5str + i * 2, "%02x", (int)md5sum[i]);
|
|
|
|
}
|
|
|
|
for (g = kyra_games; g->name; g++) {
|
|
|
|
if (strcmp(g->md5sum, (char *)md5str) == 0) {
|
|
|
|
detectedGames.push_back(g->toGameSettings());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (detectedGames.isEmpty()) {
|
2005-10-14 11:25:48 +00:00
|
|
|
debug("Unknown MD5 (%s)! Please report the details (language, platform, etc.) of this game to the ScummVM team\n", md5str);
|
2005-10-13 21:12:47 +00:00
|
|
|
|
|
|
|
const KyraGameList *g1 = kyra_list;
|
|
|
|
while (g1->name) {
|
|
|
|
detectedGames.push_back(g1->toGameSettings());
|
|
|
|
g1++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-10-16 22:28:29 +00:00
|
|
|
return detectedGames;
|
2004-04-09 12:36:06 +00:00
|
|
|
}
|
|
|
|
|
2005-08-19 22:12:09 +00:00
|
|
|
Engine *Engine_KYRA_create(GameDetector *detector, OSystem *system) {
|
|
|
|
return new KyraEngine(detector, system);
|
2004-04-09 12:36:06 +00:00
|
|
|
}
|
|
|
|
|
2005-03-25 17:55:57 +00:00
|
|
|
REGISTER_PLUGIN(KYRA, "Legend of Kyrandia Engine")
|
2004-04-09 12:36:06 +00:00
|
|
|
|
|
|
|
namespace Kyra {
|
2005-08-19 22:12:09 +00:00
|
|
|
|
|
|
|
KyraEngine::KyraEngine(GameDetector *detector, OSystem *system)
|
|
|
|
: Engine(system) {
|
2005-10-18 19:59:51 +00:00
|
|
|
_seq_Forest = _seq_KallakWriting = _seq_KyrandiaLogo = _seq_KallakMalcolm =
|
|
|
|
_seq_MalcolmTree = _seq_WestwoodLogo = _seq_Demo1 = _seq_Demo2 = _seq_Demo3 =
|
|
|
|
_seq_Demo4 = 0;
|
|
|
|
|
|
|
|
_seq_WSATable = _seq_CPSTable = _seq_COLTable = _seq_textsTable = 0;
|
|
|
|
_seq_WSATable_Size = _seq_CPSTable_Size = _seq_COLTable_Size = _seq_textsTable_Size = 0;
|
2004-04-09 12:36:06 +00:00
|
|
|
|
|
|
|
// Setup mixer
|
|
|
|
if (!_mixer->isReady()) {
|
|
|
|
warning("Sound initialization failed.");
|
|
|
|
}
|
|
|
|
|
2005-05-11 01:02:33 +00:00
|
|
|
_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
|
|
|
|
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
|
2005-10-12 19:15:32 +00:00
|
|
|
_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume"));
|
2004-04-09 12:36:06 +00:00
|
|
|
|
2005-10-13 21:12:47 +00:00
|
|
|
// Detect game features based on MD5. Again brutally ripped from Gobliins.
|
|
|
|
uint8 md5sum[16];
|
|
|
|
char md5str[32 + 1];
|
|
|
|
|
|
|
|
const KyraGameSettings *g;
|
|
|
|
bool found = false;
|
|
|
|
|
|
|
|
// TODO
|
|
|
|
// Fallback. Maybe we will be able to determine game type from game
|
|
|
|
// data contents
|
2005-10-14 11:25:48 +00:00
|
|
|
_features = 0;
|
2005-10-13 21:12:47 +00:00
|
|
|
|
|
|
|
for (g = kyra_games; g->name; g++) {
|
|
|
|
if (!Common::File::exists(g->checkFile))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (Common::md5_file(g->checkFile, md5sum, ConfMan.get("path").c_str(), kMD5FileSizeLimit)) {
|
|
|
|
for (int j = 0; j < 16; j++) {
|
|
|
|
sprintf(md5str + j*2, "%02x", (int)md5sum[j]);
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (strcmp(g->md5sum, (char *)md5str) == 0) {
|
|
|
|
_features = g->features;
|
|
|
|
_game = g->id;
|
|
|
|
|
|
|
|
if (g->description)
|
|
|
|
g_system->setWindowCaption(g->description);
|
|
|
|
|
|
|
|
found = true;
|
|
|
|
break;
|
2005-08-19 22:12:09 +00:00
|
|
|
}
|
2005-10-13 21:12:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!found) {
|
|
|
|
debug("Unknown MD5 (%s)! Please report the details (language, platform, etc.) of this game to the ScummVM team", md5str);
|
2005-10-18 19:59:51 +00:00
|
|
|
_features = GF_LNGUNK;
|
2005-10-14 11:25:48 +00:00
|
|
|
_game = GI_KYRA1;
|
2005-10-18 19:59:51 +00:00
|
|
|
Common::File test;
|
|
|
|
if (test.open("INTRO.VRM")) {
|
|
|
|
_features |= GF_TALKIE;
|
|
|
|
} else {
|
|
|
|
_features |= GF_FLOPPY;
|
|
|
|
}
|
2004-11-11 13:37:35 +00:00
|
|
|
}
|
2004-11-23 00:03:25 +00:00
|
|
|
}
|
|
|
|
|
2004-11-24 00:14:21 +00:00
|
|
|
int KyraEngine::init(GameDetector &detector) {
|
2005-10-12 19:15:32 +00:00
|
|
|
_currentVocFile = 0;
|
2004-11-24 00:14:21 +00:00
|
|
|
_system->beginGFXTransaction();
|
|
|
|
initCommonGFX(detector);
|
|
|
|
_system->initSize(320, 200);
|
|
|
|
_system->endGFXTransaction();
|
|
|
|
|
2005-09-11 14:35:34 +00:00
|
|
|
// for now we prefer MIDI-to-Adlib conversion over native midi
|
|
|
|
int midiDrv = MidiDriver::detectMusicDriver(MDT_NATIVE | MDT_ADLIB/* | MDT_PREFER_NATIVE*/);
|
2004-11-14 14:11:54 +00:00
|
|
|
bool native_mt32 = (ConfMan.getBool("native_mt32") || (midiDrv == MD_MT32));
|
|
|
|
|
2004-12-02 08:21:49 +00:00
|
|
|
MidiDriver *driver = MidiDriver::createMidi(midiDrv);
|
2004-11-14 14:11:54 +00:00
|
|
|
if (!driver) {
|
|
|
|
// In this case we should play the Adlib tracks, but for now
|
|
|
|
// the automagic MIDI-to-Adlib conversion will do.
|
|
|
|
driver = MidiDriver_ADLIB_create(_mixer);
|
2005-08-19 22:12:09 +00:00
|
|
|
} else if (native_mt32) {
|
2004-11-14 14:11:54 +00:00
|
|
|
driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
|
2005-08-19 22:12:09 +00:00
|
|
|
}
|
2004-11-14 14:11:54 +00:00
|
|
|
|
2005-08-19 22:12:09 +00:00
|
|
|
_midi = new MusicPlayer(driver, this);
|
|
|
|
assert(_midi);
|
|
|
|
_midi->hasNativeMT32(native_mt32);
|
|
|
|
_midi->setVolume(255);
|
2005-09-11 14:35:34 +00:00
|
|
|
|
2005-08-19 22:12:09 +00:00
|
|
|
_res = new Resource(this);
|
|
|
|
assert(_res);
|
|
|
|
_screen = new Screen(this, _system);
|
|
|
|
assert(_screen);
|
2005-10-03 20:21:18 +00:00
|
|
|
_sprites = new Sprites(this, _system);
|
|
|
|
assert(_sprites);
|
2005-10-06 11:57:02 +00:00
|
|
|
_seq = new SeqPlayer(this, _system);
|
|
|
|
assert(_seq);
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2005-08-19 22:12:09 +00:00
|
|
|
_fastMode = false;
|
|
|
|
_talkCoords.y = 0x88;
|
|
|
|
_talkCoords.x = 0;
|
|
|
|
_talkCoords.w = 0;
|
2005-08-31 20:14:20 +00:00
|
|
|
_talkMessageY = 0xC;
|
|
|
|
_talkMessageH = 0;
|
|
|
|
_talkMessagePrinted = false;
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2004-11-23 00:03:25 +00:00
|
|
|
return 0;
|
2004-04-09 12:36:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
KyraEngine::~KyraEngine() {
|
2005-10-03 20:21:18 +00:00
|
|
|
delete _sprites;
|
2005-08-19 22:12:09 +00:00
|
|
|
delete _screen;
|
|
|
|
delete _res;
|
|
|
|
delete _midi;
|
2005-10-06 11:57:02 +00:00
|
|
|
delete _seq;
|
2004-04-09 12:36:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void KyraEngine::errorString(const char *buf1, char *buf2) {
|
|
|
|
strcpy(buf2, buf1);
|
|
|
|
}
|
|
|
|
|
2004-11-23 00:03:25 +00:00
|
|
|
int KyraEngine::go() {
|
2005-08-19 22:12:09 +00:00
|
|
|
_quitFlag = false;
|
2005-09-08 19:09:52 +00:00
|
|
|
uint32 sz;
|
2005-09-10 06:48:34 +00:00
|
|
|
|
2005-10-18 19:59:51 +00:00
|
|
|
res_loadResources();
|
2005-10-13 21:12:47 +00:00
|
|
|
if (_features & GF_FLOPPY) {
|
2005-09-10 06:48:34 +00:00
|
|
|
_screen->loadFont(Screen::FID_6_FNT, _res->fileData("6.FNT", &sz));
|
|
|
|
}
|
2005-09-08 19:09:52 +00:00
|
|
|
_screen->loadFont(Screen::FID_8_FNT, _res->fileData("8FAT.FNT", &sz));
|
2005-09-02 11:12:09 +00:00
|
|
|
_screen->setScreenDim(0);
|
2005-09-10 06:40:20 +00:00
|
|
|
|
2005-10-03 20:21:18 +00:00
|
|
|
_abortIntroFlag = false;
|
|
|
|
|
2005-10-13 21:12:47 +00:00
|
|
|
if (_features & GF_DEMO) {
|
2005-09-10 06:40:20 +00:00
|
|
|
seq_demo();
|
|
|
|
} else {
|
|
|
|
seq_intro();
|
|
|
|
startup();
|
|
|
|
mainLoop();
|
|
|
|
}
|
2005-10-18 19:59:51 +00:00
|
|
|
res_unloadResources();
|
2005-08-19 22:12:09 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2004-11-11 13:37:35 +00:00
|
|
|
|
2005-09-10 00:15:40 +00:00
|
|
|
void KyraEngine::startup() {
|
|
|
|
debug(9, "KyraEngine::startup()");
|
|
|
|
static const uint8 colorMap[] = { 0, 0, 0, 0, 12, 12, 12, 0, 0, 0, 0, 0 };
|
|
|
|
_screen->setTextColorMap(colorMap);
|
2005-09-10 20:03:53 +00:00
|
|
|
// _screen->setFont(Screen::FID_6_FNT);
|
2005-09-10 00:15:40 +00:00
|
|
|
_screen->setAnimBlockPtr(3750);
|
2005-10-03 20:21:18 +00:00
|
|
|
_gameSpeed = 50;
|
2005-09-10 00:15:40 +00:00
|
|
|
memset(_flagsTable, 0, sizeof(_flagsTable));
|
2005-10-03 20:21:18 +00:00
|
|
|
setupRooms();
|
2005-09-10 00:15:40 +00:00
|
|
|
// XXX
|
|
|
|
}
|
|
|
|
|
2005-10-03 20:21:18 +00:00
|
|
|
void KyraEngine::delay(uint32 amount) {
|
|
|
|
OSystem::Event event;
|
|
|
|
uint32 start = _system->getMillis();
|
|
|
|
do {
|
|
|
|
while (_system->pollEvent(event)) {
|
|
|
|
switch (event.type) {
|
|
|
|
case OSystem::EVENT_KEYDOWN:
|
|
|
|
if (event.kbd.keycode == 'q' || event.kbd.keycode == 27) {
|
|
|
|
_quitFlag = true;
|
|
|
|
} else if (event.kbd.keycode == ' ') {
|
|
|
|
loadRoom((++_currentRoom) % MAX_NUM_ROOMS);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
// XXX
|
|
|
|
case OSystem::EVENT_LBUTTONDOWN:
|
|
|
|
loadRoom((++_currentRoom) % MAX_NUM_ROOMS);
|
|
|
|
break;
|
|
|
|
case OSystem::EVENT_RBUTTONDOWN:
|
|
|
|
loadRoom((--_currentRoom) % MAX_NUM_ROOMS);
|
|
|
|
break;
|
|
|
|
case OSystem::EVENT_QUIT:
|
|
|
|
_quitFlag = true;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (amount > 0) {
|
|
|
|
_system->delayMillis((amount > 10) ? 10 : amount);
|
|
|
|
}
|
|
|
|
} while (_system->getMillis() < start + amount);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KyraEngine::drawRoom() {
|
|
|
|
//_screen->clearPage(0);
|
|
|
|
_screen->copyRegion(0, 0, 0, 0, 320, 200, 10, 0);
|
|
|
|
_screen->copyRegion(4, 4, 4, 4, 308, 132, 14, 0);
|
|
|
|
_sprites->doAnims();
|
|
|
|
_sprites->drawSprites(14, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KyraEngine::setCursor(uint8 cursorID) {
|
|
|
|
debug(9, "KyraEngine::setCursor(%i)", cursorID);
|
|
|
|
assert(cursorID < _cursorsCount);
|
|
|
|
|
|
|
|
loadBitmap("mouse.cps", 2, 2, _screen->_currentPalette);
|
|
|
|
uint8 *cursor = new uint8[_cursors[cursorID].w * _cursors[cursorID].h];
|
|
|
|
|
|
|
|
_screen->copyRegionToBuffer(2, _cursors[cursorID].x, _cursors[cursorID].y, _cursors[cursorID].w, _cursors[cursorID].h, cursor);
|
|
|
|
_system->setMouseCursor(cursor, _cursors[cursorID].w, _cursors[cursorID].h, 0, 0, 0);
|
|
|
|
_system->showMouse(true);
|
|
|
|
|
|
|
|
delete[] cursor;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KyraEngine::setupRooms() {
|
|
|
|
// XXX
|
|
|
|
// Just a few sample rooms, most with sprite anims.
|
|
|
|
memset(_rooms, 0, sizeof(_rooms));
|
|
|
|
_rooms[0].filename = "gemcut";
|
|
|
|
_rooms[1].filename = "arch";
|
|
|
|
_rooms[2].filename = "sorrow";
|
|
|
|
_rooms[3].filename = "emcav";
|
|
|
|
_rooms[4].filename = "extpot";
|
|
|
|
_rooms[5].filename = "spell";
|
|
|
|
_rooms[6].filename = "song";
|
|
|
|
_rooms[7].filename = "belroom";
|
|
|
|
_rooms[8].filename = "kyragem";
|
|
|
|
_rooms[9].filename = "lephole";
|
|
|
|
_rooms[10].filename = "sickwil";
|
|
|
|
_rooms[11].filename = "temple";
|
|
|
|
}
|
|
|
|
|
|
|
|
void KyraEngine::loadRoom(uint16 roomID) {
|
|
|
|
debug(9, "KyraEngine::loadRoom(%i)", roomID);
|
|
|
|
char buf[12];
|
|
|
|
|
|
|
|
loadPalette("palette.col", _screen->_currentPalette);
|
|
|
|
|
|
|
|
//loadPalette(_rooms[roomID].palFilename, _screen->_currentPalette);
|
|
|
|
//_screen->setScreenPalette(_screen->_currentPalette);
|
|
|
|
|
|
|
|
_screen->clearPage(14);
|
|
|
|
_screen->clearPage(0);
|
|
|
|
_screen->clearPage(10);
|
|
|
|
|
|
|
|
// Loading GUI bitmap
|
2005-10-18 19:59:51 +00:00
|
|
|
if ((_features & GF_ENGLISH) && (_features & GF_TALKIE))
|
2005-10-03 20:21:18 +00:00
|
|
|
loadBitmap("MAIN_ENG.CPS", 10, 10, 0);
|
2005-10-13 21:12:47 +00:00
|
|
|
else if(_features & GF_FRENCH)
|
|
|
|
loadBitmap("MAIN_FRE.CPS", 10, 10, 0);
|
|
|
|
else if(_features & GF_GERMAN)
|
|
|
|
loadBitmap("MAIN_GER.CPS", 10, 10, 0);
|
2005-10-18 19:59:51 +00:00
|
|
|
else if ((_features & GF_ENGLISH) && (_features & GF_FLOPPY))
|
2005-10-03 20:21:18 +00:00
|
|
|
loadBitmap("MAIN15.CPS", 10, 10, 0);
|
2005-10-18 19:59:51 +00:00
|
|
|
else if (_features & GF_SPANISH)
|
|
|
|
loadBitmap("MAIN_SPA.CPS", 10, 10, 0);
|
|
|
|
else
|
|
|
|
warning("no main graphics file found");
|
2005-10-03 20:21:18 +00:00
|
|
|
|
|
|
|
// Loading main room background
|
|
|
|
strncpy(buf, _rooms[roomID].filename, 8);
|
|
|
|
strcat(buf, ".cps");
|
|
|
|
loadBitmap( buf, 14, 14, 0);
|
|
|
|
|
|
|
|
// Loading the room mask
|
|
|
|
strncpy(buf, _rooms[roomID].filename, 8);
|
|
|
|
strcat(buf, ".msc");
|
|
|
|
loadBitmap( buf, 12, 12, 0);
|
|
|
|
|
|
|
|
// Loading room data
|
|
|
|
strncpy(buf, _rooms[roomID].filename, 8);
|
|
|
|
strcat(buf, ".dat");
|
|
|
|
_sprites->loadDAT(buf);
|
|
|
|
|
|
|
|
setCursor(0);
|
|
|
|
}
|
|
|
|
|
2005-09-10 00:15:40 +00:00
|
|
|
void KyraEngine::mainLoop() {
|
|
|
|
debug(9, "KyraEngine::mainLoop()");
|
2005-10-03 20:21:18 +00:00
|
|
|
#ifdef TEST_SPRITES
|
|
|
|
_currentRoom = 0;
|
|
|
|
loadRoom(_currentRoom);
|
|
|
|
|
|
|
|
while (!_quitFlag) {
|
|
|
|
int32 frameTime = (int32)_system->getMillis();
|
|
|
|
|
|
|
|
drawRoom();
|
|
|
|
_screen->updateScreen();
|
|
|
|
|
|
|
|
delay((frameTime + _gameSpeed) - _system->getMillis());
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void KyraEngine::loadPalette(const char *filename, uint8 *palData) {
|
|
|
|
debug(9, "KyraEngine::loadPalette('%s' 0x%X)", filename, palData);
|
|
|
|
uint32 fileSize = 0;
|
|
|
|
uint8 *srcData = _res->fileData(filename, &fileSize);
|
|
|
|
|
|
|
|
if (palData && fileSize) {
|
2005-10-13 21:12:47 +00:00
|
|
|
debug(9, "Loading a palette of size %i from '%s'", fileSize, filename);
|
2005-10-03 20:21:18 +00:00
|
|
|
memcpy(palData, srcData, fileSize);
|
|
|
|
}
|
2005-09-10 00:15:40 +00:00
|
|
|
}
|
|
|
|
|
2005-08-19 22:12:09 +00:00
|
|
|
void KyraEngine::loadBitmap(const char *filename, int tempPage, int dstPage, uint8 *palData) {
|
|
|
|
debug(9, "KyraEngine::copyBitmap('%s', %d, %d, 0x%X)", filename, tempPage, dstPage, palData);
|
|
|
|
uint32 fileSize;
|
|
|
|
uint8 *srcData = _res->fileData(filename, &fileSize);
|
|
|
|
uint8 compType = srcData[2];
|
|
|
|
uint32 imgSize = READ_LE_UINT32(srcData + 4);
|
|
|
|
uint16 palSize = READ_LE_UINT16(srcData + 8);
|
|
|
|
if (palData && palSize) {
|
2005-10-03 20:21:18 +00:00
|
|
|
debug(9, "Loading a palette of size %i from %s", palSize, filename);
|
2005-08-19 22:12:09 +00:00
|
|
|
memcpy(palData, srcData + 10, palSize);
|
2004-10-15 06:06:47 +00:00
|
|
|
}
|
2005-08-22 15:39:07 +00:00
|
|
|
uint8 *srcPtr = srcData + 10 + palSize;
|
2005-08-19 22:12:09 +00:00
|
|
|
uint8 *dstData = _screen->getPagePtr(dstPage);
|
|
|
|
switch (compType) {
|
|
|
|
case 0:
|
2005-08-22 15:39:07 +00:00
|
|
|
memcpy(dstData, srcPtr, imgSize);
|
2005-08-19 22:12:09 +00:00
|
|
|
break;
|
|
|
|
case 3:
|
2005-08-22 15:39:07 +00:00
|
|
|
Screen::decodeFrame3(srcPtr, dstData, imgSize);
|
2005-08-19 22:12:09 +00:00
|
|
|
break;
|
|
|
|
case 4:
|
2005-08-22 15:39:07 +00:00
|
|
|
Screen::decodeFrame4(srcPtr, dstData, imgSize);
|
2005-08-19 22:12:09 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
error("Unhandled bitmap compression %d", compType);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
delete[] srcData;
|
|
|
|
}
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2005-08-31 20:14:20 +00:00
|
|
|
void KyraEngine::setTalkCoords(uint16 y) {
|
|
|
|
debug(9, "KyraEngine::setTalkCoords(%d)", y);
|
|
|
|
_talkCoords.y = y;
|
|
|
|
}
|
|
|
|
|
|
|
|
int KyraEngine::getCenterStringX(const char *str, int x1, int x2) {
|
|
|
|
debug(9, "KyraEngine::getCenterStringX('%s', %d, %d)", str, x1, x2);
|
2005-09-08 19:09:52 +00:00
|
|
|
_screen->_charWidth = -2;
|
|
|
|
Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
|
|
|
|
int strWidth = _screen->getTextWidth(str);
|
|
|
|
_screen->setFont(curFont);
|
|
|
|
_screen->_charWidth = 0;
|
|
|
|
int w = x2 - x1 + 1;
|
|
|
|
return x1 + (w - strWidth) / 2;
|
2005-08-31 20:14:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int KyraEngine::getCharLength(const char *str, int len) {
|
2005-09-08 19:09:52 +00:00
|
|
|
debug(9, "KyraEngine::getCharLength('%s', %d)", str, len);
|
|
|
|
int charsCount = 0;
|
|
|
|
if (*str) {
|
|
|
|
_screen->_charWidth = -2;
|
|
|
|
Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
|
|
|
|
int i = 0;
|
|
|
|
while (i <= len && *str) {
|
|
|
|
i += _screen->getCharWidth(*str++);
|
|
|
|
++charsCount;
|
|
|
|
}
|
|
|
|
_screen->setFont(curFont);
|
|
|
|
_screen->_charWidth = 0;
|
|
|
|
}
|
|
|
|
return charsCount;
|
2005-08-31 20:14:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int KyraEngine::dropCRIntoString(char *str, int offs) {
|
|
|
|
debug(9, "KyraEngine::dropCRIntoString('%s', %d)", str, offs);
|
|
|
|
int pos = 0;
|
2005-09-10 00:15:40 +00:00
|
|
|
str += offs;
|
2005-09-02 11:12:09 +00:00
|
|
|
while (*str) {
|
2005-09-08 19:09:52 +00:00
|
|
|
if (*str == ' ') {
|
2005-09-10 00:15:40 +00:00
|
|
|
*str = '\r';
|
2005-08-31 20:14:20 +00:00
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
++str;
|
|
|
|
++pos;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *KyraEngine::preprocessString(const char *str) {
|
|
|
|
debug(9, "KyraEngine::preprocessString('%s')", str);
|
2005-09-08 19:09:52 +00:00
|
|
|
assert(strlen(str) < sizeof(_talkBuffer) - 1);
|
|
|
|
strcpy(_talkBuffer, str);
|
|
|
|
char *p = _talkBuffer;
|
|
|
|
while (*p) {
|
2005-09-10 00:15:40 +00:00
|
|
|
if (*p == '\r') {
|
2005-09-08 19:09:52 +00:00
|
|
|
return _talkBuffer;
|
|
|
|
}
|
|
|
|
++p;
|
|
|
|
}
|
|
|
|
p = _talkBuffer;
|
|
|
|
Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
|
|
|
|
_screen->_charWidth = -2;
|
|
|
|
int textWidth = _screen->getTextWidth(p);
|
|
|
|
_screen->_charWidth = 0;
|
|
|
|
if (textWidth > 176) {
|
|
|
|
if (textWidth > 352) {
|
|
|
|
int count = getCharLength(p, textWidth / 3);
|
|
|
|
int offs = dropCRIntoString(p, count);
|
|
|
|
p += count + offs;
|
|
|
|
_screen->_charWidth = -2;
|
|
|
|
textWidth = _screen->getTextWidth(p);
|
|
|
|
_screen->_charWidth = 0;
|
|
|
|
count = getCharLength(p, textWidth / 2);
|
|
|
|
dropCRIntoString(p, count);
|
|
|
|
} else {
|
|
|
|
int count = getCharLength(p, textWidth / 2);
|
|
|
|
dropCRIntoString(p, count);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_screen->setFont(curFont);
|
|
|
|
return _talkBuffer;
|
2005-08-31 20:14:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int KyraEngine::buildMessageSubstrings(const char *str) {
|
|
|
|
debug(9, "KyraEngine::buildMessageSubstrings('%s')", str);
|
|
|
|
int currentLine = 0;
|
|
|
|
int pos = 0;
|
|
|
|
while (*str) {
|
2005-09-10 00:15:40 +00:00
|
|
|
if (*str == '\r') {
|
2005-09-08 19:09:52 +00:00
|
|
|
assert(currentLine < TALK_SUBSTRING_NUM);
|
2005-09-10 00:15:40 +00:00
|
|
|
_talkSubstrings[currentLine * TALK_SUBSTRING_LEN + pos] = '\0';
|
2005-08-31 20:14:20 +00:00
|
|
|
++currentLine;
|
|
|
|
pos = 0;
|
|
|
|
} else {
|
2005-09-08 19:09:52 +00:00
|
|
|
_talkSubstrings[currentLine * TALK_SUBSTRING_LEN + pos] = *str;
|
2005-08-31 20:14:20 +00:00
|
|
|
++pos;
|
2005-09-08 19:09:52 +00:00
|
|
|
if (pos > TALK_SUBSTRING_LEN - 2) {
|
|
|
|
pos = TALK_SUBSTRING_LEN - 2;
|
2005-08-31 20:14:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
++str;
|
|
|
|
}
|
2005-09-08 19:09:52 +00:00
|
|
|
_talkSubstrings[currentLine * TALK_SUBSTRING_LEN + pos] = '\0';
|
2005-08-31 20:14:20 +00:00
|
|
|
return currentLine + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int KyraEngine::getWidestLineWidth(int linesCount) {
|
|
|
|
debug(9, "KyraEngine::getWidestLineWidth(%d)", linesCount);
|
2005-09-08 19:09:52 +00:00
|
|
|
int maxWidth = 0;
|
|
|
|
Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
|
|
|
|
_screen->_charWidth = -2;
|
|
|
|
for (int l = 0; l < linesCount; ++l) {
|
|
|
|
int w = _screen->getTextWidth(&_talkSubstrings[l * TALK_SUBSTRING_LEN]);
|
|
|
|
if (maxWidth < w) {
|
|
|
|
maxWidth = w;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_screen->setFont(curFont);
|
|
|
|
_screen->_charWidth = 0;
|
|
|
|
return maxWidth;
|
2005-08-31 20:14:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void KyraEngine::calcWidestLineBounds(int &x1, int &x2, int w, int cx) {
|
|
|
|
debug(9, "KyraEngine::calcWidestLineBounds(%d, %d)", w, cx);
|
|
|
|
x1 = cx - w / 2;
|
|
|
|
if (x1 + w >= Screen::SCREEN_W - 12) {
|
|
|
|
x1 = Screen::SCREEN_W - 12 - w - 1;
|
|
|
|
} else if (x1 < 12) {
|
|
|
|
x1 = 12;
|
|
|
|
}
|
|
|
|
x2 = x1 + w + 1;
|
|
|
|
}
|
|
|
|
|
2005-08-19 22:12:09 +00:00
|
|
|
void KyraEngine::restoreTalkTextMessageBkgd(int srcPage, int dstPage) {
|
2005-08-31 20:14:20 +00:00
|
|
|
debug(9, "KyraEngine::restoreTalkTextMessageBkgd(%d, %d)", srcPage, dstPage);
|
|
|
|
if (_talkMessagePrinted) {
|
|
|
|
_talkMessagePrinted = false;
|
|
|
|
_screen->copyRegion(_talkCoords.x, _talkCoords.y, _talkCoords.x, _talkMessageY, _talkCoords.w, _talkMessageH, srcPage, dstPage);
|
|
|
|
}
|
2005-08-19 22:12:09 +00:00
|
|
|
}
|
2004-11-11 13:37:35 +00:00
|
|
|
|
2005-08-19 22:12:09 +00:00
|
|
|
void KyraEngine::printTalkTextMessage(const char *text, int x, int y, uint8 color, int srcPage, int dstPage) {
|
|
|
|
debug(9, "KyraEngine::printTalkTextMessage('%s', %d, %d, %d, %d, %d)", text, x, y, color, srcPage, dstPage);
|
2005-09-08 19:09:52 +00:00
|
|
|
char *str = preprocessString(text);
|
|
|
|
int lineCount = buildMessageSubstrings(str);
|
|
|
|
int top = y - lineCount * 10;
|
|
|
|
if (top < 0) {
|
|
|
|
top = 0;
|
|
|
|
}
|
|
|
|
_talkMessageY = top;
|
|
|
|
_talkMessageH = lineCount * 10;
|
|
|
|
int w = getWidestLineWidth(lineCount);
|
|
|
|
int x1, x2;
|
|
|
|
calcWidestLineBounds(x1, x2, w, x);
|
|
|
|
_talkCoords.x = x1;
|
|
|
|
_talkCoords.w = w + 2;
|
|
|
|
_screen->copyRegion(_talkCoords.x, _talkMessageY, _talkCoords.x, _talkCoords.y, _talkCoords.w, _talkMessageH, srcPage, dstPage);
|
|
|
|
int curPage = _screen->_curPage;
|
|
|
|
_screen->_curPage = srcPage;
|
|
|
|
for (int i = 0; i < lineCount; ++i) {
|
|
|
|
top = i * 10 + _talkMessageY;
|
|
|
|
char *msg = &_talkSubstrings[i * TALK_SUBSTRING_LEN];
|
|
|
|
int left = getCenterStringX(msg, x1, x2);
|
|
|
|
printText(msg, left, top, color, 0xC, 0);
|
|
|
|
}
|
|
|
|
_screen->_curPage = curPage;
|
2005-08-31 20:14:20 +00:00
|
|
|
_talkMessagePrinted = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KyraEngine::printText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2) {
|
|
|
|
uint8 colorMap[] = { 0, 15, 12, 12 };
|
|
|
|
colorMap[3] = c1;
|
|
|
|
_screen->setTextColor(colorMap, 0, 3);
|
2005-09-08 19:09:52 +00:00
|
|
|
Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
|
2005-08-31 20:14:20 +00:00
|
|
|
_screen->_charWidth = -2;
|
|
|
|
_screen->printText(str, x, y, c0, c2);
|
|
|
|
_screen->_charWidth = 0;
|
2005-09-08 19:09:52 +00:00
|
|
|
_screen->setFont(curFont);
|
2005-08-19 22:12:09 +00:00
|
|
|
}
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2005-08-19 22:12:09 +00:00
|
|
|
void KyraEngine::waitTicks(int ticks) {
|
|
|
|
debug(9, "KyraEngine::waitTicks(%d)", ticks);
|
|
|
|
const uint32 end = _system->getMillis() + ticks * 1000 / 60;
|
|
|
|
do {
|
|
|
|
OSystem::Event event;
|
|
|
|
while (_system->pollEvent(event)) {
|
2004-12-05 17:42:20 +00:00
|
|
|
switch (event.type) {
|
2005-08-19 22:12:09 +00:00
|
|
|
case OSystem::EVENT_QUIT:
|
|
|
|
_quitFlag = true;
|
|
|
|
break;
|
|
|
|
case OSystem::EVENT_KEYDOWN:
|
|
|
|
if (event.kbd.flags == OSystem::KBD_CTRL) {
|
|
|
|
if (event.kbd.keycode == 'f') {
|
|
|
|
_fastMode = !_fastMode;
|
|
|
|
}
|
2005-10-03 20:21:18 +00:00
|
|
|
} else if (event.kbd.keycode == 13 || event.kbd.keycode == 32 || event.kbd.keycode == 27) {
|
|
|
|
_abortIntroFlag = true;
|
2005-08-19 22:12:09 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2004-10-15 06:06:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
_system->delayMillis(10);
|
2005-08-19 22:12:09 +00:00
|
|
|
} while (!_fastMode && _system->getMillis() < end);
|
|
|
|
}
|
|
|
|
|
2005-09-10 06:40:20 +00:00
|
|
|
void KyraEngine::seq_demo() {
|
|
|
|
debug(9, "KyraEngine::seq_demo()");
|
|
|
|
|
2005-09-12 10:49:52 +00:00
|
|
|
snd_playTheme(MUSIC_INTRO, 2);
|
|
|
|
|
|
|
|
loadBitmap("START.CPS", 7, 7, _screen->_currentPalette);
|
|
|
|
_screen->copyRegion(0, 0, 0, 0, 320, 200, 6, 0);
|
|
|
|
_system->copyRectToScreen(_screen->getPagePtr(0), 320, 0, 0, 320, 200);
|
|
|
|
_screen->fadeFromBlack();
|
|
|
|
waitTicks(60);
|
|
|
|
_screen->fadeToBlack();
|
2005-09-10 06:40:20 +00:00
|
|
|
|
|
|
|
_screen->clearPage(0);
|
2005-09-10 07:46:18 +00:00
|
|
|
loadBitmap("TOP.CPS", 7, 7, NULL);
|
2005-09-10 06:40:20 +00:00
|
|
|
loadBitmap("BOTTOM.CPS", 5, 5, _screen->_currentPalette);
|
|
|
|
_screen->copyRegion(0, 91, 0, 8, 320, 103, 6, 0);
|
|
|
|
_screen->copyRegion(0, 0, 0, 111, 320, 64, 6, 0);
|
2005-09-10 07:46:18 +00:00
|
|
|
_system->copyRectToScreen(_screen->getPagePtr(0), 320, 0, 0, 320, 200);
|
2005-09-10 06:40:20 +00:00
|
|
|
_screen->fadeFromBlack();
|
|
|
|
|
2005-10-18 19:59:51 +00:00
|
|
|
_seq->playSequence(_seq_WestwoodLogo, true);
|
2005-09-10 06:40:20 +00:00
|
|
|
waitTicks(60);
|
|
|
|
|
2005-10-18 19:59:51 +00:00
|
|
|
_seq->playSequence(_seq_KyrandiaLogo, true);
|
2005-09-10 06:40:20 +00:00
|
|
|
|
|
|
|
_screen->fadeToBlack();
|
|
|
|
_screen->clearPage(2);
|
|
|
|
_screen->clearPage(0);
|
|
|
|
|
2005-10-18 19:59:51 +00:00
|
|
|
_seq->playSequence(_seq_Demo1, true);
|
2005-09-10 06:40:20 +00:00
|
|
|
|
|
|
|
_screen->clearPage(0);
|
2005-10-18 19:59:51 +00:00
|
|
|
_seq->playSequence(_seq_Demo2, true);
|
2005-09-10 06:40:20 +00:00
|
|
|
|
|
|
|
_screen->clearPage(0);
|
2005-10-18 19:59:51 +00:00
|
|
|
_seq->playSequence(_seq_Demo3, true);
|
2005-09-10 06:40:20 +00:00
|
|
|
|
|
|
|
_screen->clearPage(0);
|
2005-10-18 19:59:51 +00:00
|
|
|
_seq->playSequence(_seq_Demo4, true);
|
2005-09-10 06:40:20 +00:00
|
|
|
|
2005-09-12 10:49:52 +00:00
|
|
|
_screen->clearPage(0);
|
|
|
|
loadBitmap("FINAL.CPS", 7, 7, _screen->_currentPalette);
|
|
|
|
_screen->_curPage = 0;
|
|
|
|
_screen->copyRegion(0, 0, 0, 0, 320, 200, 6, 0);
|
|
|
|
_system->copyRectToScreen(_screen->getPagePtr(0), 320, 0, 0, 320, 200);
|
|
|
|
_screen->fadeFromBlack();
|
|
|
|
waitTicks(60);
|
|
|
|
_screen->fadeToBlack();
|
2005-10-03 20:21:18 +00:00
|
|
|
_midi->stopMusic();
|
2005-09-10 06:40:20 +00:00
|
|
|
}
|
|
|
|
|
2005-08-19 22:12:09 +00:00
|
|
|
void KyraEngine::seq_intro() {
|
|
|
|
debug(9, "KyraEngine::seq_intro()");
|
2005-10-13 21:12:47 +00:00
|
|
|
if (_features & GF_TALKIE) {
|
2005-10-18 19:59:51 +00:00
|
|
|
_res->loadPakFile("INTRO.VRM");
|
2005-10-12 19:15:32 +00:00
|
|
|
}
|
2005-10-18 19:59:51 +00:00
|
|
|
|
2005-09-08 19:09:52 +00:00
|
|
|
static const IntroProc introProcTable[] = {
|
|
|
|
&KyraEngine::seq_introLogos,
|
2005-10-13 21:12:47 +00:00
|
|
|
&KyraEngine::seq_introStory,
|
2005-10-18 19:59:51 +00:00
|
|
|
&KyraEngine::seq_introMalcolmTree,
|
2005-09-08 19:09:52 +00:00
|
|
|
&KyraEngine::seq_introKallakWriting,
|
2005-10-18 19:59:51 +00:00
|
|
|
&KyraEngine::seq_introKallakMalcolm
|
2005-09-08 19:09:52 +00:00
|
|
|
};
|
2005-08-19 22:12:09 +00:00
|
|
|
_skipIntroFlag = true; // only true if user already played the game once
|
2005-10-06 11:57:02 +00:00
|
|
|
_seq->setCopyViewOffs(true);
|
2005-09-08 19:09:52 +00:00
|
|
|
_screen->setFont(Screen::FID_8_FNT);
|
2005-09-11 14:35:34 +00:00
|
|
|
snd_playTheme(MUSIC_INTRO, 2);
|
|
|
|
snd_setSoundEffectFile(MUSIC_INTRO);
|
2005-09-09 21:13:43 +00:00
|
|
|
setTalkCoords(144);
|
2005-09-08 19:09:52 +00:00
|
|
|
for (int i = 0; i < ARRAYSIZE(introProcTable) && !seq_skipSequence(); ++i) {
|
|
|
|
(this->*introProcTable[i])();
|
2004-10-15 06:06:47 +00:00
|
|
|
}
|
2005-09-09 21:13:43 +00:00
|
|
|
setTalkCoords(136);
|
2005-09-11 14:35:34 +00:00
|
|
|
waitTicks(30);
|
2005-10-06 11:57:02 +00:00
|
|
|
_seq->setCopyViewOffs(false);
|
2005-10-03 20:21:18 +00:00
|
|
|
_midi->stopMusic();
|
2005-10-13 21:12:47 +00:00
|
|
|
if (_features & GF_TALKIE) {
|
2005-10-12 19:15:32 +00:00
|
|
|
_res->unloadPakFile("INTRO.VRM");
|
|
|
|
}
|
2005-10-18 19:59:51 +00:00
|
|
|
res_unloadResources(RES_INTRO);
|
2005-08-19 22:12:09 +00:00
|
|
|
}
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2005-08-19 22:12:09 +00:00
|
|
|
void KyraEngine::seq_introLogos() {
|
|
|
|
debug(9, "KyraEngine::seq_introLogos()");
|
|
|
|
_screen->clearPage(0);
|
2005-09-10 07:46:18 +00:00
|
|
|
loadBitmap("TOP.CPS", 7, 7, NULL);
|
2005-09-08 19:09:52 +00:00
|
|
|
loadBitmap("BOTTOM.CPS", 5, 5, _screen->_currentPalette);
|
2005-08-19 22:12:09 +00:00
|
|
|
_screen->_curPage = 0;
|
|
|
|
_screen->copyRegion(0, 91, 0, 8, 320, 103, 6, 0);
|
|
|
|
_screen->copyRegion(0, 0, 0, 111, 320, 64, 6, 0);
|
2005-09-10 07:46:18 +00:00
|
|
|
_system->copyRectToScreen(_screen->getPagePtr(0), 320, 0, 0, 320, 200);
|
2005-08-19 22:12:09 +00:00
|
|
|
_screen->fadeFromBlack();
|
|
|
|
|
2005-10-18 19:59:51 +00:00
|
|
|
if (_seq->playSequence(_seq_WestwoodLogo, _skipIntroFlag)) {
|
|
|
|
_screen->fadeToBlack();
|
|
|
|
_screen->clearPage(0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
waitTicks(60);
|
|
|
|
if (_seq->playSequence(_seq_KyrandiaLogo, _skipIntroFlag)) {
|
|
|
|
_screen->fadeToBlack();
|
|
|
|
_screen->clearPage(0);
|
|
|
|
return;
|
2005-08-19 22:12:09 +00:00
|
|
|
}
|
|
|
|
_screen->fillRect(0, 179, 319, 199, 0);
|
|
|
|
|
|
|
|
int y1 = 8;
|
|
|
|
int h1 = 175;
|
|
|
|
int y2 = 176;
|
|
|
|
int h2 = 0;
|
|
|
|
_screen->copyRegion(0, 91, 0, 8, 320, 103, 6, 2);
|
|
|
|
_screen->copyRegion(0, 0, 0, 111, 320, 64, 6, 2);
|
|
|
|
do {
|
|
|
|
if (h1 > 0) {
|
|
|
|
_screen->copyRegion(0, y1, 0, 8, 320, h1, 2, 0);
|
|
|
|
}
|
|
|
|
++y1;
|
|
|
|
--h1;
|
|
|
|
if (h2 > 0) {
|
|
|
|
_screen->copyRegion(0, 64, 0, y2, 320, h2, 4, 0);
|
|
|
|
}
|
|
|
|
--y2;
|
|
|
|
++h2;
|
|
|
|
_screen->updateScreen();
|
|
|
|
waitTicks(1);
|
|
|
|
} while (y2 >= 64);
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2005-10-18 19:59:51 +00:00
|
|
|
_seq->playSequence(_seq_Forest, true);
|
2004-04-09 12:36:06 +00:00
|
|
|
}
|
|
|
|
|
2005-09-08 19:09:52 +00:00
|
|
|
void KyraEngine::seq_introStory() {
|
|
|
|
debug(9, "KyraEngine::seq_introStory()");
|
2005-10-18 19:59:51 +00:00
|
|
|
_screen->clearPage(3);
|
|
|
|
_screen->clearPage(0);
|
|
|
|
if (_features & GF_ENGLISH) {
|
|
|
|
loadBitmap("TEXT.CPS", 3, 3, 0);
|
|
|
|
} else if (_features & GF_GERMAN) {
|
|
|
|
loadBitmap("TEXT_GER.CPS", 3, 3, 0);
|
|
|
|
} else if (_features & GF_FRENCH) {
|
|
|
|
loadBitmap("TEXT_FRE.CPS", 3, 3, 0);
|
|
|
|
} else if (_features & GF_SPANISH) {
|
|
|
|
loadBitmap("TEXT_SPA.CPS", 3, 3, 0);
|
|
|
|
} else {
|
|
|
|
warning("no story graphics file found");
|
2005-10-13 21:12:47 +00:00
|
|
|
}
|
2005-10-18 19:59:51 +00:00
|
|
|
_screen->copyRegion(0, 0, 0, 0, 320, 200, 3, 0);
|
|
|
|
_screen->updateScreen();
|
|
|
|
waitTicks(360);
|
2005-09-08 19:09:52 +00:00
|
|
|
}
|
|
|
|
|
2005-10-18 19:59:51 +00:00
|
|
|
void KyraEngine::seq_introMalcolmTree() {
|
|
|
|
debug(9, "KyraEngine::seq_introMalcolmTree()");
|
2005-09-08 19:09:52 +00:00
|
|
|
_screen->_curPage = 0;
|
|
|
|
_screen->clearPage(3);
|
2005-10-18 19:59:51 +00:00
|
|
|
_seq->playSequence(_seq_MalcolmTree, true);
|
2005-09-08 19:09:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void KyraEngine::seq_introKallakWriting() {
|
|
|
|
debug(9, "KyraEngine::seq_introKallakWriting()");
|
2005-10-06 11:57:02 +00:00
|
|
|
_seq->makeHandShapes();
|
2005-09-10 00:15:40 +00:00
|
|
|
_screen->setAnimBlockPtr(5060);
|
2005-09-08 19:09:52 +00:00
|
|
|
_screen->_charWidth = -2;
|
|
|
|
_screen->clearPage(3);
|
2005-10-18 19:59:51 +00:00
|
|
|
_seq->playSequence(_seq_KallakWriting, true);
|
2005-09-08 19:09:52 +00:00
|
|
|
}
|
|
|
|
|
2005-10-18 19:59:51 +00:00
|
|
|
void KyraEngine::seq_introKallakMalcolm() {
|
|
|
|
debug(9, "KyraEngine::seq_introKallakMalcolm()");
|
2005-09-08 19:09:52 +00:00
|
|
|
_screen->clearPage(3);
|
2005-10-18 19:59:51 +00:00
|
|
|
_seq->playSequence(_seq_KallakMalcolm, true);
|
2004-10-15 06:06:47 +00:00
|
|
|
}
|
|
|
|
|
2005-08-19 22:12:09 +00:00
|
|
|
bool KyraEngine::seq_skipSequence() const {
|
2005-08-31 20:14:20 +00:00
|
|
|
debug(9, "KyraEngine::seq_skipSequence()");
|
2005-10-03 20:21:18 +00:00
|
|
|
return _quitFlag || _abortIntroFlag;
|
2005-08-19 22:12:09 +00:00
|
|
|
}
|
|
|
|
|
2005-09-11 14:35:34 +00:00
|
|
|
void KyraEngine::snd_playTheme(int file, int track) {
|
|
|
|
debug(9, "KyraEngine::snd_playTheme(%d)", file);
|
|
|
|
assert(file < _xmidiFilesCount);
|
2005-09-11 17:23:04 +00:00
|
|
|
_midi->playMusic(_xmidiFiles[file]);
|
2005-09-11 14:35:34 +00:00
|
|
|
_midi->playTrack(track, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KyraEngine::snd_playTrack(int track) {
|
|
|
|
debug(9, "KyraEngine::snd_playTrack(%d)", track);
|
|
|
|
_midi->playTrack(track, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KyraEngine::snd_setSoundEffectFile(int file) {
|
|
|
|
debug(9, "KyraEngine::snd_setSoundEffectFile(%d)", file);
|
|
|
|
assert(file < _xmidiFilesCount);
|
|
|
|
_midi->loadSoundEffectFile(_xmidiFiles[file]);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KyraEngine::snd_playSoundEffect(int track) {
|
|
|
|
debug(9, "KyraEngine::snd_playSoundEffect(%d)", track);
|
|
|
|
_midi->playSoundEffect(track);
|
|
|
|
}
|
|
|
|
|
2005-10-12 19:15:32 +00:00
|
|
|
void KyraEngine::snd_playVoiceFile(int id) {
|
|
|
|
debug(9, "KyraEngine::snd_playVoiceFile(%d)", id);
|
2005-10-15 06:26:53 +00:00
|
|
|
char vocFile[8];
|
|
|
|
assert(id >= 0 && id < 1000);
|
|
|
|
sprintf(vocFile, "%03d.VOC", id);
|
2005-10-12 19:15:32 +00:00
|
|
|
uint32 fileSize = 0;
|
|
|
|
byte *fileData = 0;
|
|
|
|
fileData = _res->fileData(vocFile, &fileSize);
|
|
|
|
assert(fileData);
|
|
|
|
Common::MemoryReadStream vocStream(fileData, fileSize);
|
|
|
|
_mixer->stopHandle(_vocHandle);
|
|
|
|
_currentVocFile = makeVOCStream(vocStream);
|
|
|
|
if (_currentVocFile)
|
|
|
|
_mixer->playInputStream(Audio::Mixer::kSpeechSoundType, &_vocHandle, _currentVocFile);
|
|
|
|
delete fileData;
|
|
|
|
fileSize = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KyraEngine::snd_voicePlaying() {
|
|
|
|
return _mixer->isSoundHandleActive(_vocHandle);
|
|
|
|
}
|
|
|
|
|
2005-09-11 14:35:34 +00:00
|
|
|
void KyraEngine::snd_startTrack() {
|
|
|
|
debug(9, "KyraEngine::snd_startTrack()");
|
|
|
|
_midi->startTrack();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KyraEngine::snd_haltTrack() {
|
|
|
|
debug(9, "KyraEngine::snd_haltTrack()");
|
|
|
|
_midi->haltTrack();
|
|
|
|
}
|
|
|
|
|
2005-08-19 22:12:09 +00:00
|
|
|
} // End of namespace Kyra
|