mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-21 09:21:08 +00:00
932 lines
26 KiB
C++
932 lines
26 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
*/
|
|
|
|
|
|
#include "common/endian.h"
|
|
#include "common/util.h"
|
|
#include "common/events.h"
|
|
#include "common/system.h"
|
|
#include "common/textconsole.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"
|
|
|
|
#include "audio/audiostream.h"
|
|
#include "audio/decoders/raw.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() {
|
|
if (_skyScreen->sequenceRunning())
|
|
_skyScreen->stopSequence();
|
|
|
|
free(_textBuf);
|
|
free(_saveBuf);
|
|
_mixer->stopID(SOUND_BG);
|
|
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;
|
|
Audio::RewindableAudioStream *stream = 0;
|
|
|
|
// 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 playStream()
|
|
// directly, but this will have to do for now.
|
|
memset(vData, 127, sizeof(DataFileHeader));
|
|
|
|
stream = Audio::makeRawStream(vData, _skyDisk->_lastLoadedFileSize, 11025, Audio::FLAG_UNSIGNED);
|
|
_mixer->playStream(Audio::Mixer::kSpeechSoundType, &_voice, stream, SOUND_VOICE);
|
|
return true;
|
|
case WAITVOICE:
|
|
while (_mixer->isSoundHandleActive(_voice))
|
|
if (!escDelay(50))
|
|
return false;
|
|
return true;
|
|
case LOADBG:
|
|
_mixer->stopID(SOUND_BG);
|
|
free(_bgBuf);
|
|
_bgBuf = _skyDisk->loadFile(*data++);
|
|
_bgSize = _skyDisk->_lastLoadedFileSize;
|
|
return true;
|
|
case LOOPBG:
|
|
_mixer->stopID(SOUND_BG);
|
|
stream = Audio::makeRawStream(_bgBuf + 256, _bgSize - 768, 11025, Audio::FLAG_UNSIGNED, DisposeAfterUse::NO);
|
|
_mixer->playStream(Audio::Mixer::kSFXSoundType, &_bgSfx, Audio::makeLoopingAudioStream(stream, 0), SOUND_BG);
|
|
return true;
|
|
case PLAYBG:
|
|
_mixer->stopID(SOUND_BG);
|
|
stream = Audio::makeRawStream(_bgBuf + 256, _bgSize - 768, 11025, Audio::FLAG_UNSIGNED, DisposeAfterUse::NO);
|
|
_mixer->playStream(Audio::Mixer::kSFXSoundType, &_bgSfx, stream, SOUND_BG);
|
|
return true;
|
|
case STOPBG:
|
|
_mixer->stopID(SOUND_BG);
|
|
return true;
|
|
default:
|
|
error("Unknown intro command %X", command);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool Intro::floppyScrollFlirt() {
|
|
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", command);
|
|
}
|
|
}
|
|
|
|
if (!escDelay(50)) {
|
|
_skyScreen->stopSequence();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
data++; // move pointer over "COMMANDEND"
|
|
return true;
|
|
}
|
|
|
|
void Intro::showTextBuf() {
|
|
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() {
|
|
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 > 20)
|
|
nDelay = 20;
|
|
|
|
_system->delayMillis(nDelay);
|
|
|
|
_skyScreen->processSequence();
|
|
_system->updateScreen();
|
|
} while (nDelay == 20);
|
|
|
|
return true;
|
|
}
|
|
|
|
} // End of namespace Sky
|