2003-12-16 02:10:15 +00:00
/* ScummVM - Scumm Interpreter
2005-01-01 16:09:25 +00:00
* Copyright ( C ) 2003 - 2005 The ScummVM project
2003-12-16 02:10:15 +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
* 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
2005-10-18 01:30:26 +00:00
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
2003-12-16 02:10:15 +00:00
*
* $ Header $
*
*/
2005-06-24 15:23:51 +00:00
# include "common/stdafx.h"
2005-06-24 16:01:42 +00:00
# include "sword1/sword1.h"
2003-12-16 02:10:15 +00:00
# include "backends/fs/fs.h"
# include "base/plugins.h"
# include "common/config-manager.h"
# include "common/file.h"
# include "common/timer.h"
2005-01-10 22:06:49 +00:00
# include "common/system.h"
2003-12-16 02:10:15 +00:00
2004-10-21 12:43:49 +00:00
# include "sword1/resman.h"
# include "sword1/objectman.h"
# include "sword1/mouse.h"
# include "sword1/logic.h"
# include "sword1/sound.h"
# include "sword1/screen.h"
# include "sword1/swordres.h"
# include "sword1/menu.h"
# include "sword1/music.h"
# include "sword1/control.h"
2003-12-16 02:10:15 +00:00
2004-07-11 04:41:48 +00:00
# include "gui/message.h"
# include "gui/newgui.h"
2004-01-11 15:47:41 +00:00
using namespace Sword1 ;
2003-12-17 01:17:12 +00:00
/* Broken Sword 1 */
2004-12-09 15:06:49 +00:00
static const GameSettings sword1FullSettings =
{ " sword1 " , " Broken Sword I " , GF_DEFAULT_TO_1X_SCALER } ;
2005-07-30 21:11:48 +00:00
static const GameSettings sword1DemoSettings =
2004-12-09 15:06:49 +00:00
{ " sword1demo " , " Broken Sword I (Demo) " , GF_DEFAULT_TO_1X_SCALER | Sword1 : : GF_DEMO } ;
// check these subdirectories (if present)
static const char * g_dirNames [ ] = { " clusters " , " speech " } ;
# define NUM_FILES_TO_CHECK 5
static const char * g_filesToCheck [ NUM_FILES_TO_CHECK ] = { // these files have to be found
" swordres.rif " ,
" general.clu " ,
" compacts.clu " ,
" scripts.clu " ,
" cows.mad " , // this one should only exist in the demo version
// the engine needs several more files to work, but checking these should be sufficient
2004-08-31 07:52:47 +00:00
} ;
2003-12-16 02:10:15 +00:00
GameList Engine_SWORD1_gameList ( ) {
GameList games ;
2004-12-09 15:06:49 +00:00
games . push_back ( sword1FullSettings ) ;
games . push_back ( sword1DemoSettings ) ;
2003-12-16 02:10:15 +00:00
return games ;
}
2004-12-09 15:06:49 +00:00
void Sword1CheckDirectory ( const FSList & fslist , bool * filesFound ) {
for ( FSList : : const_iterator file = fslist . begin ( ) ; file ! = fslist . end ( ) ; + + file ) {
if ( ! file - > isDirectory ( ) ) {
const char * fileName = file - > displayName ( ) . c_str ( ) ;
for ( int cnt = 0 ; cnt < NUM_FILES_TO_CHECK ; cnt + + )
if ( scumm_stricmp ( fileName , g_filesToCheck [ cnt ] ) = = 0 )
filesFound [ cnt ] = true ;
} else {
for ( int cnt = 0 ; cnt < ARRAYSIZE ( g_dirNames ) ; cnt + + )
if ( scumm_stricmp ( file - > displayName ( ) . c_str ( ) , g_dirNames [ cnt ] ) = = 0 )
Sword1CheckDirectory ( file - > listDir ( AbstractFilesystemNode : : kListFilesOnly ) , filesFound ) ;
2003-12-16 02:10:15 +00:00
}
}
2004-12-09 15:06:49 +00:00
}
DetectedGameList Engine_SWORD1_detectGames ( const FSList & fslist ) {
2004-12-11 00:37:05 +00:00
int i ;
2004-12-09 15:06:49 +00:00
DetectedGameList detectedGames ;
bool filesFound [ NUM_FILES_TO_CHECK ] ;
2004-12-11 00:37:05 +00:00
for ( i = 0 ; i < NUM_FILES_TO_CHECK ; i + + )
2004-12-09 15:06:49 +00:00
filesFound [ i ] = false ;
Sword1CheckDirectory ( fslist , filesFound ) ;
bool mainFilesFound = true ;
2004-12-11 00:37:05 +00:00
for ( i = 0 ; i < NUM_FILES_TO_CHECK - 1 ; i + + )
2004-12-09 15:06:49 +00:00
if ( ! filesFound [ i ] )
mainFilesFound = false ;
if ( mainFilesFound & & filesFound [ NUM_FILES_TO_CHECK - 1 ] )
detectedGames . push_back ( sword1DemoSettings ) ;
else if ( mainFilesFound )
detectedGames . push_back ( sword1FullSettings ) ;
2003-12-17 01:17:12 +00:00
2003-12-16 02:10:15 +00:00
return detectedGames ;
}
Engine * Engine_SWORD1_create ( GameDetector * detector , OSystem * syst ) {
return new SwordEngine ( detector , syst ) ;
}
2005-03-25 17:55:57 +00:00
REGISTER_PLUGIN ( SWORD1 , " Broken Sword " )
2003-12-16 02:10:15 +00:00
2004-01-11 15:47:41 +00:00
namespace Sword1 {
2003-12-16 02:10:15 +00:00
SystemVars SwordEngine : : _systemVars ;
void SwordEngine : : errorString ( const char * buf1 , char * buf2 ) {
strcpy ( buf2 , buf1 ) ;
}
SwordEngine : : SwordEngine ( GameDetector * detector , OSystem * syst )
: Engine ( syst ) {
2004-08-31 07:52:47 +00:00
_features = detector - > _game . features ;
2003-12-24 17:42:22 +00:00
if ( ! _mixer - > isReady ( ) )
2003-12-16 02:10:15 +00:00
warning ( " Sound initialization failed " ) ;
2004-11-24 00:14:21 +00:00
// Add default file directories
2005-05-10 22:56:25 +00:00
Common : : File : : addDefaultDirectory ( _gameDataPath + " CLUSTERS/ " ) ;
Common : : File : : addDefaultDirectory ( _gameDataPath + " MUSIC/ " ) ;
Common : : File : : addDefaultDirectory ( _gameDataPath + " SPEECH/ " ) ;
Common : : File : : addDefaultDirectory ( _gameDataPath + " VIDEO/ " ) ;
Common : : File : : addDefaultDirectory ( _gameDataPath + " clusters/ " ) ;
Common : : File : : addDefaultDirectory ( _gameDataPath + " music/ " ) ;
Common : : File : : addDefaultDirectory ( _gameDataPath + " speech/ " ) ;
Common : : File : : addDefaultDirectory ( _gameDataPath + " video/ " ) ;
2003-12-16 02:10:15 +00:00
}
SwordEngine : : ~ SwordEngine ( ) {
2004-11-09 04:06:10 +00:00
delete _control ;
delete _logic ;
delete _menu ;
delete _sound ;
delete _music ;
delete _screen ;
delete _mouse ;
delete _objectMan ;
delete _resMan ;
2003-12-16 02:10:15 +00:00
}
2004-11-24 00:14:21 +00:00
int SwordEngine : : init ( GameDetector & detector ) {
2004-06-28 00:06:31 +00:00
2004-11-24 00:14:21 +00:00
_system - > beginGFXTransaction ( ) ;
initCommonGFX ( detector ) ;
_system - > initSize ( 640 , 480 ) ;
_system - > endGFXTransaction ( ) ;
2004-06-28 00:06:31 +00:00
2004-12-10 17:55:03 +00:00
checkCdFiles ( ) ;
2003-12-16 02:10:15 +00:00
debug ( 5 , " Starting resource manager " ) ;
2004-11-19 07:55:33 +00:00
_resMan = new ResMan ( " swordres.rif " ) ;
2003-12-16 02:10:15 +00:00
debug ( 5 , " Starting object manager " ) ;
_objectMan = new ObjectMan ( _resMan ) ;
2005-05-10 23:48:48 +00:00
_mixer - > setVolumeForSoundType ( Audio : : Mixer : : kSFXSoundType , Audio : : Mixer : : kMaxMixerVolume ) ;
_mixer - > setVolumeForSoundType ( Audio : : Mixer : : kMusicSoundType , Audio : : Mixer : : kMaxMixerVolume ) ;
2004-01-11 15:47:41 +00:00
_mouse = new Mouse ( _system , _resMan , _objectMan ) ;
_screen = new Screen ( _system , _resMan , _objectMan ) ;
2005-01-28 22:05:51 +00:00
_music = new Music ( _mixer ) ;
2004-10-12 15:50:00 +00:00
_sound = new Sound ( " " , _mixer , _resMan ) ;
2004-01-11 15:47:41 +00:00
_menu = new Menu ( _screen , _mouse ) ;
2004-01-18 05:52:04 +00:00
_logic = new Logic ( _objectMan , _resMan , _screen , _mouse , _sound , _music , _menu , _system , _mixer ) ;
2003-12-17 05:16:37 +00:00
_mouse - > useLogicAndMenu ( _logic , _menu ) ;
2003-12-16 02:10:15 +00:00
2005-02-06 20:31:20 +00:00
uint musicVol = ConfMan . getInt ( " music_volume " ) ;
uint speechVol = ConfMan . getInt ( " speech_volume " ) ;
uint sfxVol = ConfMan . getInt ( " sfx_volume " ) ;
if ( musicVol > 255 )
musicVol = 255 ;
if ( speechVol > 255 )
speechVol = 255 ;
if ( sfxVol > 255 )
sfxVol = 255 ;
2004-01-07 17:47:46 +00:00
_music - > setVolume ( musicVol , musicVol ) ; // these routines expect left and right volume,
_sound - > setSpeechVol ( speechVol , speechVol ) ; // but our config manager doesn't support it.
_sound - > setSfxVol ( sfxVol , sfxVol ) ;
2004-01-06 11:48:30 +00:00
2004-03-31 18:00:46 +00:00
_systemVars . justRestoredGame = 0 ;
_systemVars . currentCD = 0 ;
2004-11-09 04:06:10 +00:00
_systemVars . controlPanelMode = CP_NEWGAME ;
2003-12-20 09:12:54 +00:00
_systemVars . forceRestart = false ;
2004-03-03 07:37:46 +00:00
_systemVars . wantFade = true ;
2004-11-09 04:06:10 +00:00
_systemVars . engineQuit = false ;
2003-12-16 10:08:27 +00:00
switch ( Common : : parseLanguage ( ConfMan . get ( " language " ) ) ) {
case Common : : DE_DEU :
_systemVars . language = BS1_GERMAN ;
break ;
case Common : : FR_FRA :
_systemVars . language = BS1_FRENCH ;
break ;
case Common : : IT_ITA :
_systemVars . language = BS1_ITALIAN ;
break ;
case Common : : ES_ESP :
_systemVars . language = BS1_SPANISH ;
break ;
case Common : : PT_BRA :
_systemVars . language = BS1_PORT ;
break ;
2004-01-06 12:28:24 +00:00
case Common : : CZ_CZE :
_systemVars . language = BS1_CZECH ;
break ;
2003-12-16 10:08:27 +00:00
default :
_systemVars . language = BS1_ENGLISH ;
}
2003-12-17 14:36:52 +00:00
_systemVars . showText = ConfMan . getBool ( " subtitles " ) ;
2005-07-30 21:11:48 +00:00
2003-12-16 02:10:15 +00:00
_systemVars . playSpeech = 1 ;
2003-12-17 11:54:48 +00:00
_mouseState = 0 ;
2003-12-20 09:12:54 +00:00
_logic - > initialize ( ) ;
_objectMan - > initialize ( ) ;
_mouse - > initialize ( ) ;
2004-11-27 00:26:11 +00:00
_control = new Control ( _saveFileMan , _resMan , _objectMan , _system , _mouse , _sound , _music ) ;
2005-07-30 21:11:48 +00:00
2004-11-23 00:03:25 +00:00
return 0 ;
2003-12-20 09:12:54 +00:00
}
void SwordEngine : : reinitialize ( void ) {
2004-11-19 07:55:33 +00:00
_resMan - > flush ( ) ; // free everything that's currently alloced and opened. (*evil*)
2003-12-20 09:12:54 +00:00
_logic - > initialize ( ) ; // now reinitialize these objects as they (may) have locked
_objectMan - > initialize ( ) ; // resources which have just been wiped.
_mouse - > initialize ( ) ;
2004-03-28 16:30:50 +00:00
_system - > warpMouse ( 320 , 240 ) ;
2003-12-22 11:23:40 +00:00
_systemVars . wantFade = true ;
2003-12-17 11:54:48 +00:00
}
2004-12-10 17:55:03 +00:00
void SwordEngine : : flagsToBool ( bool * dest , uint8 flags ) {
uint8 bitPos = 0 ;
while ( flags ) {
if ( flags & 1 )
dest [ bitPos ] = true ;
flags > > = 1 ;
bitPos + + ;
}
}
static const char * errorMsgs [ ] = {
" The file \" %s \" is missing and the game doesn't work without it. \n "
" Please copy it from CD %d and try starting the game again. \n "
" The Readme file also contains further information. " ,
2005-07-30 21:11:48 +00:00
2004-12-10 17:55:03 +00:00
" %d important files are missing, the game can't start without them. \n "
" Please copy these files from their corresponding CDs: \n " ,
" The file \" %s \" is missing. \n "
" Even though the game may initially seem to \n "
" work fine, it will crash when it needs the \n "
" data from this file and you will be thrown back to your last savegame. \n "
" Please copy the file from CD %d and start the game again. " ,
" %d files are missing. \n "
" Even though the game may initially seem to \n "
" work fine, it will crash when it needs the \n "
" data from these files and you will be thrown back to your last savegame. \n "
" Please copy these files from their corresponding CDs: \n "
} ;
const CdFile SwordEngine : : _cdFileList [ ] = {
{ " paris2.clu " , FLAG_CD1 } ,
{ " ireland.clu " , FLAG_CD2 } ,
{ " paris3.clu " , FLAG_CD1 } ,
{ " paris4.clu " , FLAG_CD1 } ,
{ " scotland.clu " , FLAG_CD2 } ,
{ " spain.clu " , FLAG_CD2 } ,
{ " syria.clu " , FLAG_CD2 } ,
{ " train.clu " , FLAG_CD2 } ,
{ " compacts.clu " , FLAG_CD1 | FLAG_DEMO | FLAG_IMMED } ,
{ " general.clu " , FLAG_CD1 | FLAG_DEMO | FLAG_IMMED } ,
{ " maps.clu " , FLAG_CD1 | FLAG_DEMO } ,
{ " paris1.clu " , FLAG_CD1 | FLAG_DEMO } ,
{ " scripts.clu " , FLAG_CD1 | FLAG_DEMO | FLAG_IMMED } ,
{ " swordres.rif " , FLAG_CD1 | FLAG_DEMO | FLAG_IMMED } ,
{ " text.clu " , FLAG_CD1 | FLAG_DEMO } ,
{ " cows.mad " , FLAG_DEMO } ,
{ " speech1.clu " , FLAG_SPEECH1 } ,
{ " speech2.clu " , FLAG_SPEECH2 }
2004-10-14 06:36:05 +00:00
# ifdef USE_MAD
2004-12-10 17:55:03 +00:00
, { " speech1.cl3 " , FLAG_SPEECH1 } ,
{ " speech2.cl3 " , FLAG_SPEECH2 }
2004-10-14 06:36:05 +00:00
# endif
2005-08-10 12:42:56 +00:00
# ifdef USE_VORBIS
2004-12-10 17:55:03 +00:00
, { " speech1.clv " , FLAG_SPEECH1 } ,
{ " speech2.clv " , FLAG_SPEECH2 }
2004-10-14 06:36:05 +00:00
# endif
2004-12-10 17:55:03 +00:00
} ;
2003-12-30 22:57:52 +00:00
2004-12-10 17:55:03 +00:00
void SwordEngine : : showFileErrorMsg ( uint8 type , bool * fileExists ) {
char msg [ 1024 ] ;
int missCnt = 0 , missNum = 0 ;
for ( int i = 0 ; i < ARRAYSIZE ( _cdFileList ) ; i + + )
if ( ! fileExists [ i ] ) {
missCnt + + ;
missNum = i ;
2004-07-11 04:41:48 +00:00
}
2004-12-10 17:55:03 +00:00
assert ( missCnt > 0 ) ; // this function shouldn't get called if there's nothing missing.
warning ( " %d files missing " , missCnt ) ;
int msgId = ( type = = TYPE_IMMED ) ? 0 : 2 ;
if ( missCnt = = 1 ) {
sprintf ( msg , errorMsgs [ msgId ] ,
_cdFileList [ missNum ] . name , ( _cdFileList [ missNum ] . flags & FLAG_CD2 ) ? 2 : 1 ) ;
warning ( msg ) ;
} else {
char * pos = msg + sprintf ( msg , errorMsgs [ msgId + 1 ] , missCnt ) ;
warning ( msg ) ;
for ( int i = 0 ; i < ARRAYSIZE ( _cdFileList ) ; i + + )
if ( ! fileExists [ i ] ) {
warning ( " \" %s \" (CD %d) " , _cdFileList [ i ] . name , ( _cdFileList [ i ] . flags & FLAG_CD2 ) ? 2 : 1 ) ;
pos + = sprintf ( pos , " \" %s \" (CD %d) \n " , _cdFileList [ i ] . name , ( _cdFileList [ i ] . flags & FLAG_CD2 ) ? 2 : 1 ) ;
}
2004-10-14 06:36:05 +00:00
}
2004-12-10 17:55:03 +00:00
GUI : : MessageDialog dialog ( msg ) ;
dialog . runModal ( ) ;
if ( type = = TYPE_IMMED ) // we can't start without this file, so error() out.
error ( msg ) ;
}
2004-10-14 06:36:05 +00:00
2004-12-10 17:55:03 +00:00
void SwordEngine : : checkCdFiles ( void ) { // check if we're running from cd, hdd or what...
2005-05-10 22:56:25 +00:00
Common : : File test ;
2004-12-10 17:55:03 +00:00
bool fileExists [ 30 ] ;
bool isFullVersion = false ; // default to demo version
bool missingTypes [ 8 ] = { false , false , false , false , false , false , false , false } ;
bool foundTypes [ 8 ] = { false , false , false , false , false , false , false , false } ;
bool cd2FilesFound = false ;
_systemVars . runningFromCd = false ;
_systemVars . playSpeech = true ;
// check all files and look out if we can find a file that wouldn't exist if this was the demo version
for ( int fcnt = 0 ; fcnt < ARRAYSIZE ( _cdFileList ) ; fcnt + + ) {
if ( test . open ( _cdFileList [ fcnt ] . name ) ) {
2003-12-30 22:57:52 +00:00
test . close ( ) ;
2004-12-10 17:55:03 +00:00
fileExists [ fcnt ] = true ;
flagsToBool ( foundTypes , _cdFileList [ fcnt ] . flags ) ;
if ( ! ( _cdFileList [ fcnt ] . flags & FLAG_DEMO ) )
isFullVersion = true ;
if ( _cdFileList [ fcnt ] . flags & FLAG_CD2 )
cd2FilesFound = true ;
2004-07-11 04:41:48 +00:00
} else {
2004-12-10 17:55:03 +00:00
flagsToBool ( missingTypes , _cdFileList [ fcnt ] . flags ) ;
fileExists [ fcnt ] = false ;
2004-07-11 04:41:48 +00:00
}
2003-12-30 22:57:52 +00:00
}
2004-12-05 02:55:06 +00:00
2004-12-10 17:55:03 +00:00
if ( ( ( _features & GF_DEMO ) = = 0 ) ! = isFullVersion ) // shouldn't happen...
warning ( " Your Broken Sword 1 version looks like a %s version but you are starting it as a %s version " , isFullVersion ? " full " : " demo " , ( _features & GF_DEMO ) ? " demo " : " full " ) ;
2005-07-30 21:11:48 +00:00
2004-12-10 17:55:03 +00:00
if ( foundTypes [ TYPE_SPEECH1 ] ) // we found some kind of speech1 file (.clu, .cl3, .clv)
missingTypes [ TYPE_SPEECH1 ] = false ; // so we don't care if there's a different kind missing
if ( foundTypes [ TYPE_SPEECH2 ] ) // same for speech2
missingTypes [ TYPE_SPEECH2 ] = false ;
if ( isFullVersion ) // if this is the full version...
missingTypes [ TYPE_DEMO ] = false ; // then we don't need demo files...
else // and vice versa
missingTypes [ TYPE_SPEECH1 ] = missingTypes [ TYPE_SPEECH2 ] = missingTypes [ TYPE_CD1 ] = missingTypes [ TYPE_CD2 ] = false ;
bool somethingMissing = false ;
for ( int i = 0 ; i < 8 ; i + + )
somethingMissing | = missingTypes [ i ] ;
if ( somethingMissing ) { // okay, there *are* files missing
// first, update the fileExists[] array depending on our changed missingTypes
for ( int fileCnt = 0 ; fileCnt < ARRAYSIZE ( _cdFileList ) ; fileCnt + + )
if ( ! fileExists [ fileCnt ] ) {
fileExists [ fileCnt ] = true ;
for ( int flagCnt = 0 ; flagCnt < 8 ; flagCnt + + )
if ( missingTypes [ flagCnt ] & & ( ( _cdFileList [ fileCnt ] . flags & ( 1 < < flagCnt ) ) ! = 0 ) )
fileExists [ fileCnt ] = false ; // this is one of the files we were looking for
}
2005-07-30 21:11:48 +00:00
if ( missingTypes [ TYPE_IMMED ] ) {
2004-12-10 17:55:03 +00:00
// important files missing, can't start the game without them
showFileErrorMsg ( TYPE_IMMED , fileExists ) ;
} else if ( ( ! missingTypes [ TYPE_CD1 ] ) & & ! cd2FilesFound ) {
/* we have all the data from cd one, but not a single one from CD2.
I ' m not sure how we should handle this , for now I ' ll just assume that the
user has set up the extrapath correctly and copied the necessary files to HDD .
A quite optimistic assumption , I ' d say . Maybe we should change this for the release
to warn the user ? */
warning ( " CD2 data files not found. I hope you know what you're doing and that \n "
" you have set up the extrapath and additional data correctly. \n "
" If you didn't, you should better read the ScummVM readme file " ) ;
_systemVars . runningFromCd = true ;
_systemVars . playSpeech = true ;
} else if ( missingTypes [ TYPE_CD1 ] | | missingTypes [ TYPE_CD2 ] ) {
// several files from CD1 both CDs are missing. we can probably start, but it'll crash sooner or later
showFileErrorMsg ( TYPE_CD1 , fileExists ) ;
} else if ( missingTypes [ TYPE_SPEECH1 ] | | missingTypes [ TYPE_SPEECH2 ] ) {
// not so important, but there won't be any voices
if ( missingTypes [ TYPE_SPEECH1 ] & & missingTypes [ TYPE_SPEECH2 ] )
warning ( " Unable to find the speech files. The game will work, but you won't hear any voice output. \n "
" Please copy the SPEECH.CLU files from both CDs and rename them to SPEECH1.CLU and SPEECH2.CLU, \n "
2004-12-12 07:11:11 +00:00
" corresponding to the CD number. \n "
2004-12-10 17:55:03 +00:00
" Please read the ScummVM Readme file for more information " ) ;
else
warning ( " Unable to find the speech file from CD %d. \n "
" You won't hear any voice output in that part of the game. \n "
" Please read the ScummVM Readme file for more information " , missingTypes [ TYPE_SPEECH1 ] ? 1 : 2 ) ;
} else if ( missingTypes [ TYPE_DEMO ] ) {
// for the demo version, we simply expect to have all files immediately
showFileErrorMsg ( TYPE_IMMED , fileExists ) ;
}
} // everything's fine, let's play.
/*if (!isFullVersion)
_systemVars . isDemo = true ;
*/
// make the demo flag depend on the Gamesettings for now, and not on what the datafiles look like
_systemVars . isDemo = ( _features & GF_DEMO ) ! = 0 ;
2004-12-05 02:55:06 +00:00
_systemVars . cutscenePackVersion = 0 ;
# ifdef USE_MPEG2
if ( test . open ( " intro.snd " ) ) {
_systemVars . cutscenePackVersion = 1 ;
test . close ( ) ;
}
# endif
2003-12-30 22:57:52 +00:00
}
2004-11-23 00:03:25 +00:00
int SwordEngine : : go ( ) {
2003-12-20 09:12:54 +00:00
2004-12-08 04:38:39 +00:00
uint16 startPos = ConfMan . getInt ( " boot_param " ) ;
2003-12-30 22:57:52 +00:00
if ( startPos )
2004-12-08 04:38:39 +00:00
_logic - > startPositions ( startPos ) ;
2003-12-30 22:57:52 +00:00
else {
if ( _control - > savegamesExist ( ) ) {
2004-11-09 04:06:10 +00:00
_systemVars . controlPanelMode = CP_NEWGAME ;
2003-12-30 22:57:52 +00:00
if ( _control - > runPanel ( ) = = CONTROL_GAME_RESTORED )
_control - > doRestore ( ) ;
2004-11-09 04:06:10 +00:00
else if ( ! _systemVars . engineQuit )
2004-12-08 04:38:39 +00:00
_logic - > startPositions ( 0 ) ;
2003-12-30 22:57:52 +00:00
} else // no savegames, start new game.
2004-12-08 04:38:39 +00:00
_logic - > startPositions ( 0 ) ;
2003-12-20 09:12:54 +00:00
}
2004-11-09 04:06:10 +00:00
_systemVars . controlPanelMode = CP_NORMAL ;
2003-12-20 09:12:54 +00:00
2004-11-09 04:06:10 +00:00
while ( ! _systemVars . engineQuit ) {
2003-12-28 19:03:35 +00:00
uint8 action = mainLoop ( ) ;
2003-12-22 01:20:47 +00:00
2004-11-09 04:06:10 +00:00
if ( ! _systemVars . engineQuit ) {
// the mainloop was left, we have to reinitialize.
reinitialize ( ) ;
if ( action = = CONTROL_GAME_RESTORED )
_control - > doRestore ( ) ;
else if ( action = = CONTROL_RESTART_GAME )
2004-12-08 04:38:39 +00:00
_logic - > startPositions ( 1 ) ;
2004-11-09 04:06:10 +00:00
_systemVars . forceRestart = false ;
_systemVars . controlPanelMode = CP_NORMAL ;
}
}
2005-07-30 21:11:48 +00:00
2004-11-23 00:03:25 +00:00
return 0 ;
2003-12-16 02:10:15 +00:00
}
2003-12-20 20:20:53 +00:00
void SwordEngine : : checkCd ( void ) {
2004-01-11 15:47:41 +00:00
uint8 needCd = _cdList [ Logic : : _scriptVars [ NEW_SCREEN ] ] ;
2004-01-06 12:19:02 +00:00
if ( _systemVars . runningFromCd ) { // are we running from cd?
if ( needCd = = 0 ) { // needCd == 0 means we can use either CD1 or CD2.
if ( _systemVars . currentCD = = 0 ) {
_systemVars . currentCD = 1 ; // if there is no CD currently inserted, ask for CD1.
_control - > askForCd ( ) ;
} // else: there is already a cd inserted and we don't care if it's cd1 or cd2.
} else if ( needCd ! = _systemVars . currentCD ) { // we need a different CD than the one in drive.
2005-07-30 21:11:48 +00:00
_music - > startMusic ( 0 , 0 ) ; //
2004-01-06 12:19:02 +00:00
_sound - > closeCowSystem ( ) ; // close music and sound files before changing CDs
_systemVars . currentCD = needCd ; // askForCd will ask the player to insert _systemVars.currentCd,
_control - > askForCd ( ) ; // so it has to be updated before calling it.
2003-12-30 22:57:52 +00:00
}
2004-01-11 15:47:41 +00:00
} else { // we're running from HDD, we don't have to care about music files and Sound will take care of
if ( needCd ) // switching sound.clu files on Sound::newScreen by itself, so there's nothing to be done.
2004-01-06 12:19:02 +00:00
_systemVars . currentCD = needCd ;
else if ( _systemVars . currentCD = = 0 )
_systemVars . currentCD = 1 ;
}
2003-12-20 20:20:53 +00:00
}
2003-12-22 01:20:47 +00:00
uint8 SwordEngine : : mainLoop ( void ) {
uint8 retCode = 0 ;
2004-01-07 19:08:59 +00:00
_keyPressed = 0 ;
2003-12-22 01:20:47 +00:00
2004-11-09 04:06:10 +00:00
while ( ( retCode = = 0 ) & & ( ! _systemVars . engineQuit ) ) {
2003-12-16 02:10:15 +00:00
// do we need the section45-hack from sword.c here?
2003-12-20 20:20:53 +00:00
checkCd ( ) ;
2004-01-11 15:47:41 +00:00
_screen - > newScreen ( Logic : : _scriptVars [ NEW_SCREEN ] ) ;
_logic - > newScreen ( Logic : : _scriptVars [ NEW_SCREEN ] ) ;
_sound - > newScreen ( Logic : : _scriptVars [ NEW_SCREEN ] ) ;
Logic : : _scriptVars [ SCREEN ] = Logic : : _scriptVars [ NEW_SCREEN ] ;
2005-07-30 21:11:48 +00:00
2003-12-16 02:10:15 +00:00
do {
2004-01-07 19:08:59 +00:00
uint32 newTime ;
bool scrollFrameShown = false ;
2004-09-28 20:19:37 +00:00
uint32 frameTime = _system - > getMillis ( ) ;
2003-12-16 02:10:15 +00:00
_logic - > engine ( ) ;
_logic - > updateScreenParams ( ) ; // sets scrolling
2003-12-21 17:34:44 +00:00
_screen - > draw ( ) ;
2003-12-16 02:10:15 +00:00
_mouse - > animate ( ) ;
_sound - > engine ( ) ;
_menu - > refresh ( MENU_TOP ) ;
_menu - > refresh ( MENU_BOT ) ;
2004-09-28 20:19:37 +00:00
newTime = _system - > getMillis ( ) ;
2004-01-07 19:08:59 +00:00
if ( newTime - frameTime < 1000 / FRAME_RATE ) {
scrollFrameShown = _screen - > showScrollFrame ( ) ;
2004-12-08 04:38:39 +00:00
delay ( ( 1000 / ( FRAME_RATE * 2 ) ) - ( _system - > getMillis ( ) - frameTime ) ) ;
2004-01-07 19:08:59 +00:00
}
2003-12-22 23:21:28 +00:00
2004-09-28 20:19:37 +00:00
newTime = _system - > getMillis ( ) ;
2004-01-07 19:08:59 +00:00
if ( ( newTime - frameTime < 1000 / FRAME_RATE ) | | ( ! scrollFrameShown ) )
_screen - > updateScreen ( ) ;
2005-07-30 21:11:48 +00:00
delay ( ( 1000 / FRAME_RATE ) - ( _system - > getMillis ( ) - frameTime ) ) ;
2003-12-16 02:10:15 +00:00
_mouse - > engine ( _mouseX , _mouseY , _mouseState ) ;
2003-12-22 01:20:47 +00:00
if ( _systemVars . forceRestart )
retCode = CONTROL_RESTART_GAME ;
2004-07-16 06:57:47 +00:00
// The control panel is triggered by F5 or ESC.
// FIXME: This is a very strange way of detecting F5...
2004-11-09 04:06:10 +00:00
else if ( ( ( _keyPressed = = 63 | | _keyPressed = = 27 ) & & ( Logic : : _scriptVars [ MOUSE_STATUS ] & 1 ) ) | | ( _systemVars . controlPanelMode ) ) {
2003-12-22 01:20:47 +00:00
retCode = _control - > runPanel ( ) ;
if ( ! retCode )
2004-01-04 05:21:22 +00:00
_screen - > fullRefresh ( ) ;
2003-12-22 01:20:47 +00:00
}
2004-11-09 04:06:10 +00:00
_mouseState = _keyPressed = 0 ;
} while ( ( Logic : : _scriptVars [ SCREEN ] = = Logic : : _scriptVars [ NEW_SCREEN ] ) & & ( retCode = = 0 ) & & ( ! _systemVars . engineQuit ) ) ;
2003-12-28 19:03:35 +00:00
2004-11-09 04:06:10 +00:00
if ( ( retCode = = 0 ) & & ( Logic : : _scriptVars [ SCREEN ] ! = 53 ) & & _systemVars . wantFade & & ( ! _systemVars . engineQuit ) ) {
2003-12-22 11:23:40 +00:00
_screen - > fadeDownPalette ( ) ;
2004-12-08 04:38:39 +00:00
int32 relDelay = ( int32 ) _system - > getMillis ( ) ;
2003-12-22 01:20:47 +00:00
while ( _screen - > stillFading ( ) ) {
2004-12-08 04:38:39 +00:00
relDelay + = ( 1000 / FRAME_RATE ) ;
2003-12-22 01:20:47 +00:00
_screen - > updateScreen ( ) ;
2004-12-08 04:38:39 +00:00
delay ( relDelay - ( int32 ) _system - > getMillis ( ) ) ;
2003-12-22 01:20:47 +00:00
}
2003-12-16 02:10:15 +00:00
}
2003-12-20 09:12:54 +00:00
_sound - > quitScreen ( ) ;
2003-12-16 02:10:15 +00:00
_screen - > quitScreen ( ) ; // close graphic resources
2004-01-11 15:47:41 +00:00
_objectMan - > closeSection ( Logic : : _scriptVars [ SCREEN ] ) ; // close the section that PLAYER has just left, if it's empty now
2003-12-22 01:20:47 +00:00
}
return retCode ;
2003-12-16 02:10:15 +00:00
}
2004-12-08 04:38:39 +00:00
void SwordEngine : : delay ( int32 amount ) { //copied and mutilated from sky.cpp
2003-12-16 02:10:15 +00:00
OSystem : : Event event ;
2004-09-28 20:19:37 +00:00
uint32 start = _system - > getMillis ( ) ;
2003-12-16 02:10:15 +00:00
do {
2004-09-28 20:19:37 +00:00
while ( _system - > pollEvent ( event ) ) {
2004-12-05 17:42:20 +00:00
switch ( event . type ) {
2003-12-16 02:10:15 +00:00
case OSystem : : EVENT_KEYDOWN :
// Make sure backspace works right (this fixes a small issue on OS X)
if ( event . kbd . keycode = = 8 )
2003-12-20 09:12:54 +00:00
_keyPressed = 8 ;
2003-12-16 02:10:15 +00:00
else
2003-12-20 09:12:54 +00:00
_keyPressed = ( uint8 ) event . kbd . ascii ;
2003-12-16 02:10:15 +00:00
break ;
case OSystem : : EVENT_MOUSEMOVE :
_mouseX = event . mouse . x ;
_mouseY = event . mouse . y ;
break ;
case OSystem : : EVENT_LBUTTONDOWN :
_mouseState | = BS1L_BUTTON_DOWN ;
2004-12-10 15:10:10 +00:00
# if defined(_WIN32_WCE) || defined(__PALM_OS__)
2003-12-16 02:10:15 +00:00
_mouseX = event . mouse . x ;
_mouseY = event . mouse . y ;
# endif
break ;
case OSystem : : EVENT_RBUTTONDOWN :
_mouseState | = BS1R_BUTTON_DOWN ;
2004-12-10 15:10:10 +00:00
# if defined(_WIN32_WCE) || defined(__PALM_OS__)
2003-12-17 01:47:47 +00:00
_mouseX = event . mouse . x ;
_mouseY = event . mouse . y ;
# endif
break ;
case OSystem : : EVENT_LBUTTONUP :
_mouseState | = BS1L_BUTTON_UP ;
break ;
case OSystem : : EVENT_RBUTTONUP :
_mouseState | = BS1R_BUTTON_UP ;
2003-12-16 02:10:15 +00:00
break ;
case OSystem : : EVENT_QUIT :
2004-11-09 04:06:10 +00:00
_systemVars . engineQuit = true ;
2003-12-16 02:10:15 +00:00
break ;
default :
break ;
}
}
2005-10-12 19:41:57 +00:00
2004-11-09 04:06:10 +00:00
if ( amount > 0 )
_system - > delayMillis ( 10 ) ;
2005-10-12 19:41:57 +00:00
2004-11-09 04:06:10 +00:00
} while ( _system - > getMillis ( ) < start + amount ) ;
2003-12-16 02:10:15 +00:00
}
2004-01-11 15:47:41 +00:00
} // End of namespace Sword1