scummvm/kyra/kyra.cpp
Torbjörn Andersson 8fc913c21d Moved the sequence player into its own class. I'm sure this could be
cleaned up a bit, but it'll do for now.

svn-id: r18946
2005-10-06 11:57:02 +00:00

801 lines
21 KiB
C++

/* ScummVM - Scumm Interpreter
* Copyright (C) 2004-2005 The ScummVM project
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header$
*
*/
#include "common/stdafx.h"
#include "backends/fs/fs.h"
#include "base/gameDetector.h"
#include "base/plugins.h"
#include "common/config-manager.h"
#include "common/file.h"
#include "common/system.h"
#include "sound/mixer.h"
#include "sound/mididrv.h"
#include "kyra/kyra.h"
#include "kyra/resource.h"
#include "kyra/screen.h"
#include "kyra/script.h"
#include "kyra/seqplayer.h"
#include "kyra/sound.h"
#include "kyra/sprites.h"
#include "kyra/wsamovie.h"
#define TEST_SPRITES 1
using namespace Kyra;
struct KyraGameSettings {
const char *name;
const char *description;
uint32 features;
const char *detectName;
GameSettings toGameSettings() const {
GameSettings dummy = { name, description, features };
return dummy;
}
};
static const KyraGameSettings kyra_settings[] = {
{ "kyra1", "Legend of Kyrandia (Floppy)", GF_FLOPPY | GF_KYRA1, "INTRO.SND" },
{ "kyra1cd", "Legend of Kyrandia (CD)", GF_TALKIE | GF_KYRA1, "CHAPTER1.VRM" },
{ "kyra1demo", "Legend of Kyrandia (Demo)", GF_DEMO | GF_FLOPPY | GF_KYRA1, "DEMO1.WSA" },
// { "kyra2", "Hand of Fate (Floppy)", GF_FLOPPY | GF_KYRA2, 0 },
// { "kyra2cd", "Hand of Fate (CD)", GF_TALKIE | GF_KYRA2, "AUDIO.PAK" },
// { "kyra3", "Malcolm's Revenge", GF_TALKIE | GF_KYRA3, "K3INTRO0.VQA" },
{ 0, 0, 0, 0 }
};
GameList Engine_KYRA_gameList() {
GameList games;
const KyraGameSettings *g = kyra_settings;
while (g->name) {
games.push_back(g->toGameSettings());
g++;
}
return games;
}
DetectedGameList Engine_KYRA_detectGames(const FSList &fslist) {
const KyraGameSettings *game;
DetectedGameList detectedGames;
for (game = kyra_settings; game->name; ++game) {
if (game->detectName == NULL)
continue;
for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
if (!file->isDirectory()) {
const char *name = file->displayName().c_str();
if ((!scumm_stricmp(game->detectName, name))) {
detectedGames.push_back(game->toGameSettings());
break;
}
}
}
}
return detectedGames;
}
Engine *Engine_KYRA_create(GameDetector *detector, OSystem *system) {
return new KyraEngine(detector, system);
}
REGISTER_PLUGIN(KYRA, "Legend of Kyrandia Engine")
namespace Kyra {
KyraEngine::KyraEngine(GameDetector *detector, OSystem *system)
: Engine(system) {
// Setup mixer
if (!_mixer->isReady()) {
warning("Sound initialization failed.");
}
_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
// gets the game
if (detector->_game.features & GF_KYRA1) {
if (detector->_game.features & GF_DEMO) {
_game = KYRA1DEMO;
} else if (detector->_game.features & GF_FLOPPY) {
_game = KYRA1;
} else {
_game = KYRA1CD;
}
} else if (detector->_game.features & GF_KYRA2) {
if (detector->_game.features & GF_FLOPPY) {
_game = KYRA2;
} else {
_game = KYRA2CD;
}
} else if (detector->_game.features & GF_KYRA3) {
_game = KYRA3;
} else {
error("unknown game");
}
}
int KyraEngine::init(GameDetector &detector) {
_system->beginGFXTransaction();
initCommonGFX(detector);
_system->initSize(320, 200);
_system->endGFXTransaction();
// for now we prefer MIDI-to-Adlib conversion over native midi
int midiDrv = MidiDriver::detectMusicDriver(MDT_NATIVE | MDT_ADLIB/* | MDT_PREFER_NATIVE*/);
bool native_mt32 = (ConfMan.getBool("native_mt32") || (midiDrv == MD_MT32));
MidiDriver *driver = MidiDriver::createMidi(midiDrv);
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);
} else if (native_mt32) {
driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
}
_midi = new MusicPlayer(driver, this);
assert(_midi);
_midi->hasNativeMT32(native_mt32);
_midi->setVolume(255);
_res = new Resource(this);
assert(_res);
_screen = new Screen(this, _system);
assert(_screen);
_sprites = new Sprites(this, _system);
assert(_sprites);
_seq = new SeqPlayer(this, _system);
assert(_seq);
_fastMode = false;
_talkCoords.y = 0x88;
_talkCoords.x = 0;
_talkCoords.w = 0;
_talkMessageY = 0xC;
_talkMessageH = 0;
_talkMessagePrinted = false;
return 0;
}
KyraEngine::~KyraEngine() {
delete _sprites;
delete _screen;
delete _res;
delete _midi;
delete _seq;
}
void KyraEngine::errorString(const char *buf1, char *buf2) {
strcpy(buf2, buf1);
}
int KyraEngine::go() {
_quitFlag = false;
uint32 sz;
if (_game == KYRA1) {
_screen->loadFont(Screen::FID_6_FNT, _res->fileData("6.FNT", &sz));
}
_screen->loadFont(Screen::FID_8_FNT, _res->fileData("8FAT.FNT", &sz));
_screen->setScreenDim(0);
_abortIntroFlag = false;
if (_game == KYRA1DEMO) {
seq_demo();
} else {
seq_intro();
startup();
mainLoop();
}
return 0;
}
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);
// _screen->setFont(Screen::FID_6_FNT);
_screen->setAnimBlockPtr(3750);
_gameSpeed = 50;
memset(_flagsTable, 0, sizeof(_flagsTable));
setupRooms();
// XXX
}
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
if (_game == KYRA1CD) {
loadBitmap("MAIN_ENG.CPS", 10, 10, 0);
} else {
loadBitmap("MAIN15.CPS", 10, 10, 0);
}
// 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);
}
void KyraEngine::mainLoop() {
debug(9, "KyraEngine::mainLoop()");
#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) {
debug(9, "Loading a palette of size %i from %s", fileSize, filename);
memcpy(palData, srcData, fileSize);
}
}
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) {
debug(9, "Loading a palette of size %i from %s", palSize, filename);
memcpy(palData, srcData + 10, palSize);
}
uint8 *srcPtr = srcData + 10 + palSize;
uint8 *dstData = _screen->getPagePtr(dstPage);
switch (compType) {
case 0:
memcpy(dstData, srcPtr, imgSize);
break;
case 3:
Screen::decodeFrame3(srcPtr, dstData, imgSize);
break;
case 4:
Screen::decodeFrame4(srcPtr, dstData, imgSize);
break;
default:
error("Unhandled bitmap compression %d", compType);
break;
}
delete[] srcData;
}
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);
_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;
}
int KyraEngine::getCharLength(const char *str, int len) {
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;
}
int KyraEngine::dropCRIntoString(char *str, int offs) {
debug(9, "KyraEngine::dropCRIntoString('%s', %d)", str, offs);
int pos = 0;
str += offs;
while (*str) {
if (*str == ' ') {
*str = '\r';
return pos;
}
++str;
++pos;
}
return 0;
}
char *KyraEngine::preprocessString(const char *str) {
debug(9, "KyraEngine::preprocessString('%s')", str);
assert(strlen(str) < sizeof(_talkBuffer) - 1);
strcpy(_talkBuffer, str);
char *p = _talkBuffer;
while (*p) {
if (*p == '\r') {
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;
}
int KyraEngine::buildMessageSubstrings(const char *str) {
debug(9, "KyraEngine::buildMessageSubstrings('%s')", str);
int currentLine = 0;
int pos = 0;
while (*str) {
if (*str == '\r') {
assert(currentLine < TALK_SUBSTRING_NUM);
_talkSubstrings[currentLine * TALK_SUBSTRING_LEN + pos] = '\0';
++currentLine;
pos = 0;
} else {
_talkSubstrings[currentLine * TALK_SUBSTRING_LEN + pos] = *str;
++pos;
if (pos > TALK_SUBSTRING_LEN - 2) {
pos = TALK_SUBSTRING_LEN - 2;
}
}
++str;
}
_talkSubstrings[currentLine * TALK_SUBSTRING_LEN + pos] = '\0';
return currentLine + 1;
}
int KyraEngine::getWidestLineWidth(int linesCount) {
debug(9, "KyraEngine::getWidestLineWidth(%d)", linesCount);
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;
}
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;
}
void KyraEngine::restoreTalkTextMessageBkgd(int srcPage, int dstPage) {
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);
}
}
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);
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;
_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);
Screen::FontId curFont = _screen->setFont(Screen::FID_8_FNT);
_screen->_charWidth = -2;
_screen->printText(str, x, y, c0, c2);
_screen->_charWidth = 0;
_screen->setFont(curFont);
}
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)) {
switch (event.type) {
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;
}
} else if (event.kbd.keycode == 13 || event.kbd.keycode == 32 || event.kbd.keycode == 27) {
_abortIntroFlag = true;
}
break;
default:
break;
}
}
_system->delayMillis(10);
} while (!_fastMode && _system->getMillis() < end);
}
void KyraEngine::seq_demo() {
debug(9, "KyraEngine::seq_demo()");
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();
_screen->clearPage(0);
loadBitmap("TOP.CPS", 7, 7, NULL);
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);
_system->copyRectToScreen(_screen->getPagePtr(0), 320, 0, 0, 320, 200);
_screen->fadeFromBlack();
_seq->playSequence(_seq_demoData_WestwoodLogo, true);
waitTicks(60);
_seq->playSequence(_seq_demoData_KyrandiaLogo, true);
_screen->fadeToBlack();
_screen->clearPage(2);
_screen->clearPage(0);
_seq->playSequence(_seq_demoData_Demo1, true);
_screen->clearPage(0);
_seq->playSequence(_seq_demoData_Demo2, true);
_screen->clearPage(0);
_seq->playSequence(_seq_demoData_Demo3, true);
_screen->clearPage(0);
_seq->playSequence(_seq_demoData_Demo4, true);
_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();
_midi->stopMusic();
}
void KyraEngine::seq_intro() {
debug(9, "KyraEngine::seq_intro()");
static const IntroProc introProcTable[] = {
&KyraEngine::seq_introLogos,
// &KyraEngine::seq_introStory,
&KyraEngine::seq_introMalcomTree,
&KyraEngine::seq_introKallakWriting,
&KyraEngine::seq_introKallakMalcom
};
_skipIntroFlag = true; // only true if user already played the game once
_seq->setCopyViewOffs(true);
_screen->setFont(Screen::FID_8_FNT);
snd_playTheme(MUSIC_INTRO, 2);
snd_setSoundEffectFile(MUSIC_INTRO);
setTalkCoords(144);
for (int i = 0; i < ARRAYSIZE(introProcTable) && !seq_skipSequence(); ++i) {
(this->*introProcTable[i])();
}
setTalkCoords(136);
waitTicks(30);
_seq->setCopyViewOffs(false);
_midi->stopMusic();
}
void KyraEngine::seq_introLogos() {
debug(9, "KyraEngine::seq_introLogos()");
_screen->clearPage(0);
loadBitmap("TOP.CPS", 7, 7, NULL);
loadBitmap("BOTTOM.CPS", 5, 5, _screen->_currentPalette);
_screen->_curPage = 0;
_screen->copyRegion(0, 91, 0, 8, 320, 103, 6, 0);
_screen->copyRegion(0, 0, 0, 111, 320, 64, 6, 0);
_system->copyRectToScreen(_screen->getPagePtr(0), 320, 0, 0, 320, 200);
_screen->fadeFromBlack();
if (_seq->playSequence(_seq_floppyData_WestwoodLogo, _skipIntroFlag)) {
_screen->fadeToBlack();
_screen->clearPage(0);
return;
}
waitTicks(60);
if (_seq->playSequence(_seq_floppyData_KyrandiaLogo, _skipIntroFlag)) {
_screen->fadeToBlack();
_screen->clearPage(0);
return;
}
_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);
_seq->playSequence(_seq_floppyData_Forest, true);
}
void KyraEngine::seq_introStory() {
debug(9, "KyraEngine::seq_introStory()");
loadBitmap("MAIN_ENG.CPS", 3, 3, 0);
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0);
// XXX wait 360 ticks
}
void KyraEngine::seq_introMalcomTree() {
debug(9, "KyraEngine::seq_introMalcomTree()");
_screen->_curPage = 0;
_screen->clearPage(3);
_seq->playSequence(_seq_floppyData_MalcomTree, true);
}
void KyraEngine::seq_introKallakWriting() {
debug(9, "KyraEngine::seq_introKallakWriting()");
_seq->makeHandShapes();
_screen->setAnimBlockPtr(5060);
_screen->_charWidth = -2;
_screen->clearPage(3);
_seq->playSequence(_seq_floppyData_KallakWriting, true);
_seq->freeHandShapes();
}
void KyraEngine::seq_introKallakMalcom() {
debug(9, "KyraEngine::seq_introKallakMalcom()");
_screen->clearPage(3);
_seq->playSequence(_seq_floppyData_KallakMalcom, true);
}
bool KyraEngine::seq_skipSequence() const {
debug(9, "KyraEngine::seq_skipSequence()");
return _quitFlag || _abortIntroFlag;
}
void KyraEngine::snd_playTheme(int file, int track) {
debug(9, "KyraEngine::snd_playTheme(%d)", file);
assert(file < _xmidiFilesCount);
_midi->playMusic(_xmidiFiles[file]);
_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);
}
void KyraEngine::snd_startTrack() {
debug(9, "KyraEngine::snd_startTrack()");
_midi->startTrack();
}
void KyraEngine::snd_haltTrack() {
debug(9, "KyraEngine::snd_haltTrack()");
_midi->haltTrack();
}
} // End of namespace Kyra