scummvm/engines/sky/intro.cpp
Torbjörn Andersson c2424b04a5 Fixed bug #2394861 ("BASS: artifacts if skipping intro on wrong screen"). As an
added bonus, the Intro class is now freed as soon as the intro is over, rather
than at the end of the game.

svn-id: r35280
2008-12-07 17:32:25 +00:00

926 lines
25 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/endian.h"
#include "common/util.h"
#include "common/events.h"
#include "common/system.h"
#include "sky/disk.h"
#include "sky/intro.h"
#include "sky/music/musicbase.h"
#include "sky/screen.h"
#include "sky/sky.h"
#include "sky/sound.h"
#include "sky/struc.h"
#include "sky/text.h"
namespace Sky {
#define SHOWSCREEN 0
#define COMMANDEND 0 // end of COMMANDFLIRT block
#define FADEUP 1 // fade up palette
#define FADEDOWN 2
#define DELAY 3
#define DOFLIRT 4 // start flirt sequence (and wait for it to finish)
#define SCROLLFLIRT 5 // start special floppy intro flirt sequence (and wait for it)
#define COMMANDFLIRT 6 // start flirt sequence and wait for it, while processing command block
#define BGFLIRT 7 // start flirt sequence without waiting for it
#define WAITFLIRT 8 // wait for sequence started by BGFLIRT
#define STOPFLIRT 9
#define STARTMUSIC 10
#define WAITMUSIC 11
#define PLAYVOICE 12
#define WAITVOICE 13
#define LOADBG 14 // load new background sound
#define PLAYBG 15 // play background sound
#define LOOPBG 16 // loop background sound
#define STOPBG 17 // stop background sound
#define SEQEND 65535 // end of intro sequence
#define IC_PREPARE_TEXT 20 // commands used in COMMANDFLIRT block
#define IC_SHOW_TEXT 21
#define IC_REMOVE_TEXT 22
#define IC_MAKE_SOUND 23
#define IC_FX_VOLUME 24
#define FRAME_SIZE (GAME_SCREEN_WIDTH * GAME_SCREEN_HEIGHT)
#define INTRO_TEXT_WIDTH 128
//CD intro file defines
#define CDV_00 59500
#define CD_PAL 59501
#define CD_1_LOG 59502
#define CD_1 59503
#define CDV_01 59504
#define CDV_02 59505
#define CD_2 59506
#define CDV_03 59507
#define CDV_04 59508
#define CD_3 59509
#define CDV_05 59510
#define CDV_06 59511
#define CD_5 59512
#define CDV_07 59513
#define CDV_08 59514
#define CDV_09 59515
#define CD_7 59516
#define CDV_10 59518
#define CD_11 59519
#define CDV_11 59520
#define CD_11_PAL 59521
#define CD_11_LOG 59522
#define CDV_12 59523
#define CD_13 59524
#define CDV_13 59525
#define CDV_14 59527
#define CDV_15 59528
#define CD_15_PAL 59529
#define CD_15_LOG 59530
#define CDV_16 59531
#define CD_17_LOG 59532
#define CD_17 59533
#define CDV_17 59534
#define CDV_18 59535
#define CDV_19 59536
#define CD_19_PAL 59537
#define CD_19_LOG 59538
#define CDV_20 59539
#define CD_20_LOG 59540
#define CDV_21 59541
#define CD_21_LOG 59542
#define CDV_22 59545
#define CDV_23 59546
#define CD_23_PAL 59547
#define CD_24_LOG 59550
#define CDV_24 59551
#define CDV_25 59554
#define CDV_26 59556
#define CD_27 59557
#define CDV_27 59558
#define CD_27_PAL 59559
#define CD_27_LOG 59560
#define CDV_28 59561
#define CDV_29 59562
#define CDV_30 59563
#define CDV_31 59565
#define CDV_32 59566
#define CDV_33 59567
#define CDV_34 59568
#define CD_35 59569
#define CDV_35 59570
#define CD_35_PAL 59571
#define CD_35_LOG 59572
#define CDV_36 59574
#define CD_37 59575
#define CDV_37 59576
#define CD_37_PAL 59577
#define CD_37_LOG 59578
#define CDV_38 59579
#define CDV_39 59581
#define CDV_40 59583
#define CD_40_PAL 59584
#define CD_40_LOG 59585
#define CDV_41 59587
#define CDV_42 59588
#define CD_43 59589
#define CDV_43 59590
#define CD_43_PAL 59591
#define CD_43_LOG 59592
#define CDV_44 59594
#define CD_45 59595
#define CDV_45 59596
#define CD_45_PAL 59597
#define CD_45_LOG 59598
#define CDV_46 59600
#define CDV_47 59602
#define CD_47_PAL 59603
#define CD_47_LOG 59604
#define CD_48 59605
#define CDV_48 59606
#define CD_48_PAL 59607
#define CD_48_LOG 59608
#define CD_49 59609
#define CDV_49 59610
#define CD_50 59611
#define CDV_50 59612
#define CDV_51 59613
#define CDV_52 59614
#define CDV_53 59615
#define CDV_54 59616
#define CDV_55 59618
#define CD_55_PAL 59619
#define CD_55_LOG 59620
#define CDV_56 59621
#define CDV_57 59622
#define CD_58 59623
#define CDV_58 59624
#define CD_58_PAL 59625
#define CD_58_LOG 59626
#define CDV_59 59627
#define CDV_60 59628
#define CDV_61 59629
#define CDV_62 59630
#define CDV_63 59631
#define CDV_64 59632
#define CDV_65 59633
#define CDV_66 59635
#define CD_66_PAL 59636
#define CD_66_LOG 59637
#define CDV_67 59639
#define CD_67_PAL 59640
#define CD_67_LOG 59641
#define CDV_68 59642
#define CD_69 59643
#define CDV_69 59644
#define CD_69_PAL 59645
#define CD_69_LOG 59646
#define CDV_70 59647
#define CDV_71 59648
#define CDV_72 59649
#define CD_72_PAL 59650
#define CD_72_LOG 59651
#define CD_73_PAL 59652
#define CD_73_LOG 59653
#define CDV_73 59654
#define CDV_74 59655
#define CDV_75 59656
#define CD_76_PAL 59657
#define CD_76_LOG 59658
#define CDV_76 59659
#define CDV_77 59660
#define CD_78_PAL 59661
#define CD_78_LOG 59662
#define CDV_78 59663
#define CDV_79 59664
#define CDV_80 59665
#define CDV_81 59666
#define CDV_82 59667
#define CDV_83 59668
#define CDV_84 59669
#define CDV_85 59670
#define CDV_86 59671
#define CDV_87 59672
#define CD_100 60087
#define CD_101_LOG 60088
#define CD_101 60099
#define CD_102_LOG 60090
#define CD_102 60091
#define CD_103_PAL 60092
#define CD_103_LOG 60093
#define CD_103 60094
#define CD_104_PAL 60095
#define CD_104_LOG 60096
#define CD_104 60097
#define CD_105 60098
uint16 Intro::_mainIntroSeq[] = {
DELAY, 3000, // keep virgin screen up
FADEDOWN,
SHOWSCREEN, 60112, // revo screen + palette
FADEUP, 60113,
DELAY, 8000,
FADEDOWN,
SHOWSCREEN, 60114, // gibbo screen + palette
FADEUP, 60115,
DELAY, 2000,
FADEDOWN,
SEQEND
};
uint16 Intro::_cdIntroSeq[] = {
/* black screen */
PLAYVOICE, CDV_00, // Foster: "The old man was trying to tell the future. Looking for pictures in the campfire..."
LOADBG, 59499, // Fire crackle
LOOPBG,
WAITVOICE,
PLAYVOICE, CDV_01, // Shaman: "ohhh, I see evil..."
/* Fade up shaman image while he says his line... */
SHOWSCREEN, CD_1_LOG,
FADEUP, CD_PAL,
/* And then play the animation showing the shadows of the fire on his face */
BGFLIRT, CD_1,
WAITVOICE,
PLAYVOICE, CDV_02, // Shaman: "Evil born deep beneath the city... far from the light of day."
WAITVOICE,
STOPFLIRT,
BGFLIRT, CD_2,
PLAYVOICE, CDV_03, // Shaman: "I see it growing, safe beneath a sky of steel..."
WAITVOICE,
PLAYVOICE, CDV_04, // Shaman: "Scheming in the dark... gathering strength."
WAITFLIRT,
WAITVOICE,
PLAYVOICE, CDV_05, // Shaman: "And now... ohhh.... now the evil spreads..."
DELAY, 2000,
BGFLIRT, CD_3,
WAITVOICE,
PLAYVOICE, CDV_06, // Shaman: "It sends deadly feelers over the land above..."
WAITFLIRT,
WAITVOICE,
PLAYVOICE, CDV_07, // Shaman: "Across the gap... reaching towards this very place!"
BGFLIRT, CD_5,
WAITVOICE,
PLAYVOICE, CDV_08, // Foster: "I'd seen him do this a hundred times, but I humoured him."
WAITVOICE,
PLAYVOICE, CDV_09, // Foster: "After all, he'd been like a father to me."
WAITFLIRT,
WAITVOICE,
PLAYVOICE, CDV_10, // Foster: "And what does this evil want here?"
BGFLIRT, CD_7,
WAITVOICE,
PLAYVOICE, CDV_11, // Shaman: "Oh, my son. I fear..."
WAITFLIRT,
FADEDOWN,
SHOWSCREEN, CD_11_LOG,
FADEUP, CD_11_PAL,
WAITVOICE,
PLAYVOICE, CDV_12, // Shaman: "I fear the evil wants you!"
DELAY, 1600,
BGFLIRT, CD_11,
WAITVOICE,
PLAYVOICE, CDV_13, // Foster: "That was when Joey piped up..."
WAITVOICE,
WAITFLIRT,
WAITVOICE,
PLAYVOICE, CDV_14, // Joey: "Foster! Sensors detect incoming audio source!"
LOADBG, 59498, // fire crackle to heli start
PLAYBG,
DOFLIRT, CD_13,
WAITVOICE,
PLAYVOICE, CDV_15, // Shaman: "The evil! The evil is nearly here...!"
FADEDOWN,
SHOWSCREEN, CD_15_LOG,
FADEUP, CD_15_PAL,
WAITVOICE,
LOADBG, 59496, // quiet heli
LOOPBG,
PLAYVOICE, CDV_16, // Foster: "It sounded more like a 'copter than a demon."
WAITVOICE,
PLAYVOICE, CDV_17, // Foster: "But next thing, all hell let loose anyway..."
DELAY, 2000,
SHOWSCREEN, CD_17_LOG,
WAITVOICE,
BGFLIRT, CD_17,
PLAYVOICE, CDV_18, // Shaman: "Run, Foster! Run! Hide from the evil!"
LOADBG, 59497, // loud heli
LOOPBG,
WAITFLIRT,
WAITVOICE,
FADEDOWN,
SHOWSCREEN, CD_19_LOG,
FADEUP, CD_19_PAL,
PLAYVOICE, CDV_19, // Joey: "Foster! (zzzt) H-Help!"
WAITVOICE,
PLAYVOICE, CDV_20, // Joey: "Better make my next body move faster, Foster..."
FADEDOWN,
SHOWSCREEN, CD_20_LOG,
FADEUP, CD_19_PAL,
WAITVOICE,
LOADBG, 59496, // quiet heli
LOOPBG,
PLAYVOICE, CDV_21, // Foster: "He was only a robot, but, well, I loved the little guy."
FADEDOWN,
SHOWSCREEN, CD_21_LOG,
FADEUP, CD_19_PAL,
WAITVOICE,
PLAYVOICE, CDV_22, // Foster: "Then, as suddenly as it started, the shooting stopped."
LOADBG, 59494, // heli whine
PLAYBG,
WAITVOICE,
PLAYVOICE, CDV_23, // Foster: "There was a moment's silence as the copter cut its rotors, then..."
/* fade down while Foster's saying his line */
FADEDOWN,
WAITVOICE,
SHOWSCREEN, CD_24_LOG,
FADEUP, CD_23_PAL,
PLAYVOICE, CDV_24, // Reich: "Whoever is in charge here, come forward..."
WAITVOICE,
PLAYVOICE, CDV_25, // Reich: "Now!!"
WAITVOICE,
PLAYVOICE, CDV_26, // Foster: "Only a fool would have argued with that firepower."
WAITVOICE,
FADEDOWN,
SHOWSCREEN, CD_27_LOG,
FADEUP, CD_27_PAL,
PLAYVOICE, CDV_27, // Shaman: "... I am the leader of these people... We are peaceful..."
WAITVOICE,
PLAYVOICE, CDV_29, // Reich: "Bring him here."
WAITVOICE,
PLAYVOICE, CDV_30, // Guard: "At once, Commander Reich."
WAITVOICE,
BGFLIRT, CD_27,
PLAYVOICE, CDV_31, // Reich: "We're looking for someone..."
WAITVOICE,
PLAYVOICE, CDV_32, // Reich: "Someone who doesn't belong here..."
WAITVOICE,
PLAYVOICE, CDV_33, // Reich: "Who wasn't born in this garbage dump..."
WAITVOICE,
PLAYVOICE, CDV_34, // Reich: "Who came from the city as a child..."
WAITFLIRT,
WAITVOICE,
PLAYVOICE, CDV_35, // Reich: "We want to take him home again."
WAITVOICE,
PLAYVOICE, CDV_36, // Foster: "My mind racing, I remembered where I'd seen that symbol before..."
FADEDOWN,
SHOWSCREEN, CD_35_LOG,
FADEUP, CD_35_PAL,
WAITVOICE,
PLAYVOICE, CDV_37, // Foster: "It was the day the tribe found me..."
DOFLIRT, CD_35,
WAITVOICE,
PLAYVOICE, CDV_38, // Foster: "The day of the crash..."
DOFLIRT, CD_37,
WAITVOICE,
PLAYVOICE, CDV_39, // Foster: "The day my mother died."
WAITVOICE,
FADEDOWN,
SHOWSCREEN, CD_40_LOG,
FADEUP, CD_40_PAL,
PLAYVOICE, CDV_40, // Shaman: "You alright, city boy?"
WAITVOICE,
PLAYVOICE, CDV_41, // Shaman: "Got a name, son?"
WAITVOICE,
PLAYVOICE, CDV_42, // Foster: "R-Robert."
WAITVOICE,
FADEDOWN,
SHOWSCREEN, CD_43_LOG,
FADEUP, CD_43_PAL,
PLAYVOICE, CDV_43, // Shaman: "Hah! Welcome to the Gap, Robert!"
WAITVOICE,
DOFLIRT, CD_43,
PLAYVOICE, CDV_45, // Foster: "As he patched me up, the old man had gently explained that there was no way back into the City..."
FADEDOWN,
SHOWSCREEN, CD_45_LOG,
FADEUP, CD_45_PAL,
WAITVOICE,
PLAYVOICE, CDV_46, // Foster: "And I already knew there was nothing he could do for mother."
DOFLIRT, CD_45,
WAITVOICE,
FADEDOWN,
SHOWSCREEN, CD_47_LOG,
FADEUP, CD_47_PAL,
PLAYVOICE, CDV_47, // Foster: "His tribe was poor, but they treated me like one of their own..."
WAITVOICE,
PLAYVOICE, CDV_48, // Foster: "I learned how to survive in the wasteland they called the Gap..."
FADEDOWN,
SHOWSCREEN, CD_48_LOG,
FADEUP, CD_48_PAL,
WAITVOICE,
BGFLIRT, CD_48,
PLAYVOICE, CDV_49, // Foster: "And scavenging from the City dumps."
WAITVOICE,
PLAYVOICE, CDV_50, // Foster: "As the years passed, I forgot my life in the City."
WAITFLIRT,
WAITVOICE,
PLAYVOICE, CDV_51, // Foster: "Discovered new talents..."
BGFLIRT, CD_49,
WAITVOICE,
PLAYVOICE, CDV_52, // Foster: "Hah!"
WAITVOICE,
PLAYVOICE, CDV_53, // Joey: "I'm your (zzzt) friend... call me (zzzt) Joey."
WAITVOICE,
WAITFLIRT,
PLAYVOICE, CDV_54, // Foster: "And got a second name."
DOFLIRT, CD_50,
WAITVOICE,
PLAYVOICE, CDV_55, // Shaman: "This is what we'll call you now you've come of age, son."
WAITVOICE,
PLAYVOICE, CDV_56, // Shaman: "We found you... we fostered you..."
FADEDOWN,
SHOWSCREEN, CD_55_LOG,
FADEUP, CD_55_PAL,
WAITVOICE,
PLAYVOICE, CDV_57, // Shaman: "So that makes you Robert Foster."
WAITVOICE,
FADEDOWN,
SHOWSCREEN, CD_58_LOG,
FADEUP, CD_58_PAL,
PLAYVOICE, CDV_58, // Reich: "...Wasted enough time!"
WAITVOICE,
PLAYVOICE, CDV_59, // Reich: "Give us the runaway or we'll shoot everyone..."
WAITVOICE,
PLAYVOICE, CDV_60, // Reich: "Starting with you, grandad!"
WAITVOICE,
PLAYVOICE, CDV_61, // Foster: "The old man had been right, for once..."
WAITVOICE,
PLAYVOICE, CDV_62, // Foster: "It was me they wanted."
BGFLIRT, CD_58,
WAITVOICE,
PLAYVOICE, CDV_63, // Shaman: "No, my son! Don't let the evil take you! Run!"
WAITVOICE,
PLAYVOICE, CDV_64, // Guard: "DNA scan confirms it's him, sir."
WAITFLIRT,
WAITVOICE,
PLAYVOICE, CDV_65, // Foster: "Evil had come to the Gap, just as he said."
FADEDOWN,
WAITVOICE,
SHOWSCREEN, CD_66_LOG,
FADEUP, CD_66_PAL,
PLAYVOICE, CDV_66, // Reich: "Take him."
WAITVOICE,
PLAYVOICE, CDV_67, // Foster: "But had the old man seen why it wanted me?"
FADEDOWN,
SHOWSCREEN, CD_67_LOG,
FADEUP, CD_67_PAL,
WAITVOICE,
PLAYVOICE, CDV_68, // Foster: "Or what it would do next?"
WAITVOICE,
PLAYVOICE, CDV_69, // Foster: "It was too late to ask him now."
FADEDOWN,
SHOWSCREEN, CD_69_LOG,
FADEUP, CD_69_PAL,
WAITVOICE,
PLAYVOICE, CDV_70, // Guard: "Leaving destruction zone, Commander Reich."
DOFLIRT, CD_69,
WAITVOICE,
FADEDOWN,
PLAYVOICE, CDV_71, // Reich: "Good. Detonate."
WAITVOICE,
SHOWSCREEN, CD_72_LOG,
FADEUP, CD_72_PAL,
PLAYVOICE, CDV_72, // Foster: "Much too late."
WAITVOICE,
FADEDOWN,
SHOWSCREEN, CD_73_LOG,
FADEUP, CD_73_PAL,
PLAYVOICE, CDV_73, // Foster: "Why, you murdering..."
WAITVOICE,
PLAYVOICE, CDV_74, // Reich: "Keep him quiet."
WAITVOICE,
PLAYVOICE, CDV_75, // Foster: "All I could do was wait."
FADEDOWN,
SHOWSCREEN, CD_76_LOG,
FADEUP, CD_76_PAL,
WAITVOICE,
PLAYVOICE, CDV_76, // Foster: "Just like on a hunt. Just like the old man taught me."
WAITVOICE,
PLAYVOICE, CDV_77, // Foster: "Wait... and be ready."
WAITVOICE,
FADEDOWN,
SHOWSCREEN, CD_78_LOG,
FADEUP, CD_78_PAL,
PLAYVOICE, CDV_78, // Foster: "It was dawn when we reached the City."
WAITVOICE,
PLAYVOICE, CDV_79, // Reich: "Land in the central Security compound."
WAITVOICE,
PLAYVOICE, CDV_80, // Foster: "A dawn my tribe would never see."
BGFLIRT, CD_100,
WAITVOICE,
PLAYVOICE, CDV_81, // Foster: "They were no more than a note in Reich's book now."
WAITVOICE,
PLAYVOICE, CDV_82, // Guard: "Yes, sir. Locking on automatic landing beacon."
WAITVOICE,
WAITFLIRT,
SHOWSCREEN, CD_101_LOG,
BGFLIRT, CD_101,
PLAYVOICE, CDV_83, // Foster: "But what was I? Why did..."
WAITVOICE,
PLAYVOICE, CDV_84, // Guard: "Sir! The guidance system! It's gone crazy!"
WAITVOICE,
PLAYVOICE, CDV_85, // Guard: "We're going to HIT!"
WAITVOICE,
WAITFLIRT,
SHOWSCREEN, CD_102_LOG,
PLAYVOICE, CDV_86, // Foster: "Maybe I'd get some answers now."
DOFLIRT, CD_102,
FADEDOWN,
SHOWSCREEN, CD_103_LOG,
FADEUP, CD_103_PAL,
BGFLIRT, CD_103,
WAITVOICE,
PLAYVOICE, CDV_87, // Foster: "If I survived another 'copter crash."
WAITFLIRT,
WAITVOICE,
STARTMUSIC, 2,
FADEDOWN,
SHOWSCREEN, CD_104_LOG,
FADEUP, CD_104_PAL,
DOFLIRT, CD_104,
DOFLIRT, CD_105,
SEQEND
};
uint16 Intro::_floppyIntroSeq[] = {
SHOWSCREEN, 60081,
FADEUP, 60080,
DOFLIRT, 60082,
DOFLIRT, 60083,
DOFLIRT, 60084, // Beneath a Steel Sky
DOFLIRT, 60085,
DOFLIRT, 60086,
SCROLLFLIRT,
COMMANDFLIRT, 60087, // => command list 4a
136, IC_MAKE_SOUND, 1, 70,
90, IC_FX_VOLUME, 80,
50, IC_FX_VOLUME, 90,
5, IC_FX_VOLUME, 100,
COMMANDEND,
SHOWSCREEN, 60088,
COMMANDFLIRT, 60089, // => command list 4b (cockpit)
1000, IC_PREPARE_TEXT, 77,
220, IC_SHOW_TEXT, 20, 160, // radar detects jamming signal
105, IC_REMOVE_TEXT,
105, IC_PREPARE_TEXT, 81,
105, IC_SHOW_TEXT, 170, 86, // well switch to override you fool
35, IC_REMOVE_TEXT,
35, IC_PREPARE_TEXT, 477,
35, IC_SHOW_TEXT, 30, 160,
3, IC_REMOVE_TEXT,
COMMANDEND,
SHOWSCREEN, 60090,
COMMANDFLIRT, 60091, // => command list 4c
1000, IC_FX_VOLUME, 100,
25, IC_FX_VOLUME, 110,
15, IC_FX_VOLUME, 120,
4, IC_FX_VOLUME, 127,
COMMANDEND,
FADEDOWN,
SHOWSCREEN, 60093,
FADEUP, 60092,
COMMANDFLIRT, 60094, // => command list 5
31, IC_MAKE_SOUND, 2, 127,
COMMANDEND,
WAITMUSIC,
FADEDOWN,
SHOWSCREEN, 60096,
STARTMUSIC, 2,
FADEUP, 60095,
COMMANDFLIRT, 60097, // => command list 6a
1000, IC_PREPARE_TEXT, 478,
13, IC_SHOW_TEXT, 175, 155,
COMMANDEND,
COMMANDFLIRT, 60098, // => command list 6b
131, IC_REMOVE_TEXT,
131, IC_PREPARE_TEXT, 479,
74, IC_SHOW_TEXT, 175, 155,
45, IC_REMOVE_TEXT,
45, IC_PREPARE_TEXT, 162,
44, IC_SHOW_TEXT, 175, 155,
4, IC_REMOVE_TEXT,
COMMANDEND,
SEQEND
};
Intro::Intro(Disk *disk, Screen *screen, MusicBase *music, Sound *sound, Text *text, Audio::Mixer *mixer, OSystem *system) {
_skyDisk = disk;
_skyScreen = screen;
_skyMusic = music;
_skySound = sound;
_skyText = text;
_mixer = mixer;
_system = system;
_textBuf = (uint8*)malloc(10000);
_saveBuf = (uint8*)malloc(10000);
_bgBuf = NULL;
_relDelay = 0;
}
Intro::~Intro(void) {
if (_skyScreen->sequenceRunning())
_skyScreen->stopSequence();
free(_textBuf);
free(_saveBuf);
free(_bgBuf);
}
bool Intro::doIntro(bool floppyIntro) {
if (!SkyEngine::isCDVersion())
floppyIntro = true;
_skyMusic->loadSection(0);
_skySound->loadSection(0);
if (!escDelay(3000))
return false;
if (floppyIntro)
_skyMusic->startMusic(1);
uint16 *seqData = _mainIntroSeq;
while (*seqData != SEQEND) {
if (!nextPart(seqData))
return false;
}
if (floppyIntro)
seqData = _floppyIntroSeq;
else
seqData = _cdIntroSeq;
while (*seqData != SEQEND) {
if (!nextPart(seqData))
return false;
}
return true;
}
bool Intro::nextPart(uint16 *&data) {
uint8 *vData = NULL;
// return false means cancel intro
uint16 command = *data++;
switch (command) {
case SHOWSCREEN:
_skyScreen->showScreen(*data++);
return true;
case FADEUP:
_skyScreen->paletteFadeUp(*data++);
_relDelay += 32 * 20; // hack: the screen uses a seperate delay function for the
// blocking fadeups. So add 32*20 msecs to out delay counter.
return true;
case FADEDOWN:
_skyScreen->fnFadeDown(0);
_relDelay += 32 * 20; // hack: see above.
return true;
case DELAY:
if (!escDelay(*data++))
return false;
return true;
case DOFLIRT:
_skyScreen->startSequence(*data++);
while (_skyScreen->sequenceRunning())
if (!escDelay(50))
return false;
return true;
case SCROLLFLIRT:
return floppyScrollFlirt();
case COMMANDFLIRT:
return commandFlirt(data);
case STOPFLIRT:
_skyScreen->stopSequence();
return true;
case STARTMUSIC:
_skyMusic->startMusic(*data++);
return true;
case WAITMUSIC:
while (_skyMusic->musicIsPlaying())
if (!escDelay(50))
return false;
return true;
case BGFLIRT:
_skyScreen->startSequence(*data++);
return true;
case WAITFLIRT:
while (_skyScreen->sequenceRunning())
if (!escDelay(50))
return false;
return true;
case PLAYVOICE:
if (!escDelay(200))
return false;
vData = _skyDisk->loadFile(*data++);
// HACK: Fill the header with silence. We should
// probably use _skySound instead of calling playRaw()
// directly, but this will have to do for now.
memset(vData, 127, sizeof(struct dataFileHeader));
_mixer->playRaw(Audio::Mixer::kSpeechSoundType, &_voice, vData, _skyDisk->_lastLoadedFileSize, 11025,
Audio::Mixer::FLAG_AUTOFREE | Audio::Mixer::FLAG_UNSIGNED, SOUND_VOICE);
return true;
case WAITVOICE:
while (_mixer->isSoundHandleActive(_voice))
if (!escDelay(50))
return false;
return true;
case LOADBG:
_mixer->stopID(SOUND_BG);
if (_bgBuf)
free(_bgBuf);
_bgBuf = _skyDisk->loadFile(*data++);
_bgSize = _skyDisk->_lastLoadedFileSize;
return true;
case LOOPBG:
_mixer->stopID(SOUND_BG);
_mixer->playRaw(Audio::Mixer::kSFXSoundType, &_bgSfx, _bgBuf + 256, _bgSize - 768, 11025,
Audio::Mixer::FLAG_UNSIGNED | Audio::Mixer::FLAG_LOOP, SOUND_BG);
return true;
case PLAYBG:
_mixer->stopID(SOUND_BG);
_mixer->playRaw(Audio::Mixer::kSFXSoundType, &_bgSfx, _bgBuf + 256, _bgSize - 768, 11025,
Audio::Mixer::FLAG_UNSIGNED, SOUND_BG);
return true;
case STOPBG:
_mixer->stopID(SOUND_BG);
return true;
default:
error("Unknown intro command %X", command);
}
return true;
}
bool Intro::floppyScrollFlirt(void) {
uint8 *scrollScreen = (uint8*)malloc(FRAME_SIZE * 2);
memset(scrollScreen, 0, FRAME_SIZE);
memcpy(scrollScreen + FRAME_SIZE, _skyScreen->giveCurrent(), FRAME_SIZE);
uint8 *scrollPos = scrollScreen + FRAME_SIZE;
uint8 *vgaData = _skyDisk->loadFile(60100);
uint8 *diffData = _skyDisk->loadFile(60101);
uint16 frameNum = READ_LE_UINT16(diffData);
uint8 *diffPtr = diffData + 2;
uint8 *vgaPtr = vgaData;
bool doContinue = true;
for (uint16 frameCnt = 1; (frameCnt < frameNum) && doContinue; frameCnt++) {
uint8 scrollVal = *diffPtr++;
if (scrollVal)
scrollPos -= scrollVal * GAME_SCREEN_WIDTH;
uint16 scrPos = 0;
while (scrPos < FRAME_SIZE) {
uint8 nrToDo, nrToSkip;
do {
nrToSkip = *diffPtr++;
scrPos += nrToSkip;
} while (nrToSkip == 255);
do {
nrToDo = *diffPtr++;
memcpy(scrollPos + scrPos, vgaPtr, nrToDo);
scrPos += nrToDo;
vgaPtr += nrToDo;
} while (nrToDo == 255);
}
_system->copyRectToScreen(scrollPos, GAME_SCREEN_WIDTH, 0, 0, GAME_SCREEN_WIDTH, GAME_SCREEN_HEIGHT);
_system->updateScreen();
if (!escDelay(60))
doContinue = false;
}
memcpy(_skyScreen->giveCurrent(), scrollPos, FRAME_SIZE);
free(diffData);
free(vgaData);
free(scrollScreen);
return doContinue;
}
bool Intro::commandFlirt(uint16 *&data) {
_skyScreen->startSequence(*data++);
while ((*data != COMMANDEND) || _skyScreen->sequenceRunning()) {
while ((_skyScreen->seqFramesLeft() < *data)) {
data++;
uint16 command = *data++;
switch (command) {
case IC_PREPARE_TEXT:
_skyText->displayText(*data++, _textBuf, true, INTRO_TEXT_WIDTH, 255);
break;
case IC_SHOW_TEXT:
((dataFileHeader*)_textBuf)->s_x = *data++;
((dataFileHeader*)_textBuf)->s_y = *data++;
showTextBuf();
break;
case IC_REMOVE_TEXT:
restoreScreen();
break;
case IC_MAKE_SOUND:
_skySound->playSound(data[0], data[1], 0);
data += 2;
break;
case IC_FX_VOLUME:
_skySound->playSound(1, *data++, 0);
break;
default:
error("Unknown FLIRT command %X\n", command);
}
}
if (!escDelay(50)) {
_skyScreen->stopSequence();
return false;
}
}
data++; // move pointer over "COMMANDEND"
return true;
}
void Intro::showTextBuf(void) {
uint16 x = ((dataFileHeader*)_textBuf)->s_x;
uint16 y = ((dataFileHeader*)_textBuf)->s_y;
uint16 width = ((dataFileHeader*)_textBuf)->s_width;
uint16 height = ((dataFileHeader*)_textBuf)->s_height;
uint8 *screenBuf = _skyScreen->giveCurrent() + y * GAME_SCREEN_WIDTH + x;
memcpy(_saveBuf, _textBuf, sizeof(dataFileHeader));
uint8 *saveBuf = _saveBuf + sizeof(dataFileHeader);
uint8 *textBuf = _textBuf + sizeof(dataFileHeader);
for (uint16 cnty = 0; cnty < height; cnty++) {
memcpy(saveBuf, screenBuf, width);
for (uint16 cntx = 0; cntx < width; cntx++)
if (textBuf[cntx])
screenBuf[cntx] = textBuf[cntx];
screenBuf += GAME_SCREEN_WIDTH;
textBuf += width;
saveBuf += width;
}
screenBuf = _skyScreen->giveCurrent() + y * GAME_SCREEN_WIDTH + x;
_system->copyRectToScreen(screenBuf, GAME_SCREEN_WIDTH, x, y, width, height);
}
void Intro::restoreScreen(void) {
uint16 x = ((dataFileHeader*)_saveBuf)->s_x;
uint16 y = ((dataFileHeader*)_saveBuf)->s_y;
uint16 width = ((dataFileHeader*)_saveBuf)->s_width;
uint16 height = ((dataFileHeader*)_saveBuf)->s_height;
uint8 *screenBuf = _skyScreen->giveCurrent() + y * GAME_SCREEN_WIDTH + x;
uint8 *saveBuf = _saveBuf + sizeof(dataFileHeader);
for (uint16 cnt = 0; cnt < height; cnt++) {
memcpy(screenBuf, saveBuf, width);
screenBuf += GAME_SCREEN_WIDTH;
saveBuf += width;
}
_system->copyRectToScreen(_saveBuf + sizeof(dataFileHeader), width, x, y, width, height);
}
bool Intro::escDelay(uint32 msecs) {
Common::EventManager *eventMan = _system->getEventManager();
Common::Event event;
if (_relDelay == 0) // first call, init with system time
_relDelay = (int32)_system->getMillis();
_relDelay += msecs; // now wait until _system->getMillis() >= _relDelay
int32 nDelay = 0;
do {
while (eventMan->pollEvent(event)) {
if (event.type == Common::EVENT_KEYDOWN) {
if (event.kbd.keycode == Common::KEYCODE_ESCAPE)
return false;
} else if (event.type == Common::EVENT_QUIT || event.type == Common::EVENT_RTL) {
return false;
}
}
nDelay = _relDelay - _system->getMillis();
if (nDelay < 0)
nDelay = 0;
else if (nDelay > 40)
nDelay = 40;
_system->delayMillis(nDelay);
_system->updateScreen();
} while (nDelay == 40);
return true;
}
} // End of namespace Sky