2010-08-17 09:28:20 +00:00
/* 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/system.h"
2010-10-15 06:16:27 +00:00
# include "common/random.h"
2011-04-24 08:34:27 +00:00
# include "common/error.h"
2010-08-17 09:28:20 +00:00
# include "common/events.h"
# include "common/debug-channels.h"
2011-02-24 18:59:36 +00:00
# include "common/config-manager.h"
2011-04-24 08:34:27 +00:00
# include "common/textconsole.h"
2010-08-17 09:28:20 +00:00
# include "hugo/hugo.h"
# include "hugo/file.h"
# include "hugo/schedule.h"
# include "hugo/display.h"
# include "hugo/mouse.h"
# include "hugo/inventory.h"
# include "hugo/parser.h"
# include "hugo/route.h"
2010-10-15 06:16:27 +00:00
# include "hugo/util.h"
2010-08-17 09:28:20 +00:00
# include "hugo/sound.h"
# include "hugo/intro.h"
2010-10-21 17:09:57 +00:00
# include "hugo/object.h"
2011-01-25 00:32:48 +00:00
# include "hugo/text.h"
2010-08-17 09:28:20 +00:00
# include "engines/util.h"
namespace Hugo {
2010-10-03 08:08:42 +00:00
HugoEngine * HugoEngine : : s_Engine = 0 ;
2010-08-17 09:28:20 +00:00
2011-02-08 20:52:26 +00:00
HugoEngine : : HugoEngine ( OSystem * syst , const HugoGameDescription * gd ) : Engine ( syst ) , _gameDescription ( gd ) ,
2011-02-15 09:15:21 +00:00
_hero ( 0 ) , _heroImage ( 0 ) , _defltTunes ( 0 ) , _numScreens ( 0 ) , _tunesNbr ( 0 ) , _soundSilence ( 0 ) , _soundTest ( 0 ) ,
2011-04-24 20:29:27 +00:00
_screenStates ( 0 ) , _numStates ( 0 ) , _score ( 0 ) , _maxscore ( 0 ) , _lastTime ( 0 ) , _curTime ( 0 ) , _episode ( 0 )
2010-08-17 09:28:20 +00:00
{
2010-11-29 17:42:08 +00:00
_system = syst ;
2010-08-17 09:28:20 +00:00
DebugMan . addDebugChannel ( kDebugSchedule , " Schedule " , " Script Schedule debug level " ) ;
DebugMan . addDebugChannel ( kDebugEngine , " Engine " , " Engine debug level " ) ;
DebugMan . addDebugChannel ( kDebugDisplay , " Display " , " Display debug level " ) ;
DebugMan . addDebugChannel ( kDebugMouse , " Mouse " , " Mouse debug level " ) ;
DebugMan . addDebugChannel ( kDebugParser , " Parser " , " Parser debug level " ) ;
DebugMan . addDebugChannel ( kDebugFile , " File " , " File IO debug level " ) ;
DebugMan . addDebugChannel ( kDebugRoute , " Route " , " Route debug level " ) ;
DebugMan . addDebugChannel ( kDebugInventory , " Inventory " , " Inventory debug level " ) ;
2010-10-25 14:03:01 +00:00
DebugMan . addDebugChannel ( kDebugObject , " Object " , " Object debug level " ) ;
2010-12-22 09:09:38 +00:00
DebugMan . addDebugChannel ( kDebugMusic , " Music " , " Music debug level " ) ;
2010-09-17 22:40:53 +00:00
2010-11-07 15:04:47 +00:00
_console = new HugoConsole ( this ) ;
2010-11-30 00:01:54 +00:00
_rnd = 0 ;
2010-08-17 09:28:20 +00:00
}
HugoEngine : : ~ HugoEngine ( ) {
2011-02-15 18:30:15 +00:00
_file - > closeDatabaseFiles ( ) ;
2010-12-01 23:15:28 +00:00
2011-02-15 09:15:21 +00:00
_intro - > freeIntroData ( ) ;
_inventory - > freeInvent ( ) ;
2011-02-15 18:30:15 +00:00
_mouse - > freeHotspots ( ) ;
_object - > freeObjects ( ) ;
_parser - > freeParser ( ) ;
_scheduler - > freeScheduler ( ) ;
_screen - > freeScreen ( ) ;
_text - > freeAllTexts ( ) ;
2010-08-17 09:28:20 +00:00
free ( _defltTunes ) ;
free ( _screenStates ) ;
2010-09-12 22:59:32 +00:00
2010-10-30 16:04:43 +00:00
2011-01-03 12:38:13 +00:00
delete _topMenu ;
2010-10-30 16:04:43 +00:00
delete _object ;
delete _sound ;
delete _route ;
delete _parser ;
delete _inventory ;
delete _mouse ;
delete _screen ;
2010-11-13 08:08:58 +00:00
delete _intro ;
2010-10-30 16:04:43 +00:00
delete _scheduler ;
delete _file ;
2011-02-05 14:45:36 +00:00
delete _text ;
2010-11-07 15:04:47 +00:00
DebugMan . clearAllDebugChannels ( ) ;
delete _console ;
2010-11-30 00:01:54 +00:00
delete _rnd ;
2010-08-17 09:28:20 +00:00
}
2011-02-18 21:43:38 +00:00
GUI : : Debugger * HugoEngine : : getDebugger ( ) {
return _console ;
2011-02-18 21:24:32 +00:00
}
status_t & HugoEngine : : getGameStatus ( ) {
return _status ;
}
int HugoEngine : : getScore ( ) const {
return _score ;
}
void HugoEngine : : setScore ( const int newScore ) {
_score = newScore ;
}
void HugoEngine : : adjustScore ( const int adjustment ) {
_score + = adjustment ;
}
int HugoEngine : : getMaxScore ( ) const {
return _maxscore ;
}
void HugoEngine : : setMaxScore ( const int newScore ) {
_maxscore = newScore ;
}
2011-06-02 12:11:38 +00:00
Common : : Error HugoEngine : : saveGameState ( int slot , const Common : : String & desc ) {
2011-02-18 21:24:32 +00:00
return ( _file - > saveGame ( slot , desc ) ? Common : : kWritingFailed : Common : : kNoError ) ;
}
Common : : Error HugoEngine : : loadGameState ( int slot ) {
return ( _file - > restoreGame ( slot ) ? Common : : kReadingFailed : Common : : kNoError ) ;
}
bool HugoEngine : : hasFeature ( EngineFeature f ) const {
return ( f = = kSupportsRTL ) | | ( f = = kSupportsLoadingDuringRuntime ) | | ( f = = kSupportsSavingDuringRuntime ) ;
}
2011-02-18 21:43:38 +00:00
const char * HugoEngine : : getCopyrightString ( ) const {
return " Copyright 1989-1997 David P Gray, All Rights Reserved. " ;
2011-02-18 21:24:32 +00:00
}
2010-08-17 09:28:20 +00:00
GameType HugoEngine : : getGameType ( ) const {
return _gameType ;
}
Common : : Platform HugoEngine : : getPlatform ( ) const {
return _platform ;
}
bool HugoEngine : : isPacked ( ) const {
return _packedFl ;
}
2011-02-18 21:24:32 +00:00
/**
* Print options for user when dead
*/
void HugoEngine : : gameOverMsg ( ) {
2011-03-21 12:07:23 +00:00
Utils : : notifyBox ( _text - > getTextUtil ( kGameOver ) ) ;
2011-02-18 21:24:32 +00:00
}
2010-08-17 09:28:20 +00:00
Common : : Error HugoEngine : : run ( ) {
s_Engine = this ;
initGraphics ( 320 , 200 , false ) ;
2010-10-21 17:09:57 +00:00
_mouse = new MouseHandler ( this ) ;
_inventory = new InventoryHandler ( this ) ;
_route = new Route ( this ) ;
_sound = new SoundHandler ( this ) ;
2011-03-19 14:00:10 +00:00
// Setup mixer
syncSoundSettings ( ) ;
2011-01-25 00:32:48 +00:00
_text = new TextHandler ( this ) ;
2010-08-18 13:44:22 +00:00
2011-01-03 12:38:13 +00:00
_topMenu = new TopMenu ( this ) ;
2010-09-04 16:02:16 +00:00
switch ( _gameVariant ) {
2011-01-18 18:26:33 +00:00
case kGameVariantH1Win : // H1 Win
2010-10-21 17:09:57 +00:00
_file = new FileManager_v1w ( this ) ;
2010-10-25 19:59:32 +00:00
_scheduler = new Scheduler_v1w ( this ) ;
2010-10-21 17:09:57 +00:00
_intro = new intro_v1w ( this ) ;
_screen = new Screen_v1w ( this ) ;
_parser = new Parser_v1w ( this ) ;
2010-10-25 09:13:57 +00:00
_object = new ObjectHandler_v1w ( this ) ;
2010-12-12 07:40:00 +00:00
_normalTPS = 9 ;
2010-09-04 16:02:16 +00:00
break ;
2011-01-18 18:26:33 +00:00
case kGameVariantH2Win :
2011-01-04 08:36:03 +00:00
_file = new FileManager_v2w ( this ) ;
2010-10-25 19:59:32 +00:00
_scheduler = new Scheduler_v1w ( this ) ;
2010-10-21 17:09:57 +00:00
_intro = new intro_v2w ( this ) ;
_screen = new Screen_v1w ( this ) ;
_parser = new Parser_v1w ( this ) ;
2010-10-25 09:13:57 +00:00
_object = new ObjectHandler_v1w ( this ) ;
2010-12-12 07:40:00 +00:00
_normalTPS = 9 ;
2010-09-04 16:02:16 +00:00
break ;
2011-01-18 18:26:33 +00:00
case kGameVariantH3Win :
2011-01-04 08:36:03 +00:00
_file = new FileManager_v2w ( this ) ;
2010-10-25 19:59:32 +00:00
_scheduler = new Scheduler_v1w ( this ) ;
2010-10-21 17:09:57 +00:00
_intro = new intro_v3w ( this ) ;
_screen = new Screen_v1w ( this ) ;
_parser = new Parser_v1w ( this ) ;
2010-10-25 09:13:57 +00:00
_object = new ObjectHandler_v1w ( this ) ;
2010-12-12 07:40:00 +00:00
_normalTPS = 9 ;
2010-09-04 16:02:16 +00:00
break ;
2011-01-18 18:26:33 +00:00
case kGameVariantH1Dos : // H1 DOS
2010-10-21 17:09:57 +00:00
_file = new FileManager_v1d ( this ) ;
_scheduler = new Scheduler_v1d ( this ) ;
_intro = new intro_v1d ( this ) ;
_screen = new Screen_v1d ( this ) ;
_parser = new Parser_v1d ( this ) ;
2010-10-25 09:13:57 +00:00
_object = new ObjectHandler_v1d ( this ) ;
2010-12-12 07:40:00 +00:00
_normalTPS = 8 ;
2010-09-04 16:02:16 +00:00
break ;
2011-01-18 18:26:33 +00:00
case kGameVariantH2Dos :
2010-10-21 17:09:57 +00:00
_file = new FileManager_v2d ( this ) ;
2010-10-25 19:59:32 +00:00
_scheduler = new Scheduler_v2d ( this ) ;
2010-10-21 17:09:57 +00:00
_intro = new intro_v2d ( this ) ;
_screen = new Screen_v1d ( this ) ;
_parser = new Parser_v2d ( this ) ;
2010-10-25 12:07:07 +00:00
_object = new ObjectHandler_v2d ( this ) ;
2010-12-12 07:40:00 +00:00
_normalTPS = 8 ;
2010-09-04 16:02:16 +00:00
break ;
2011-01-18 18:26:33 +00:00
case kGameVariantH3Dos :
2010-10-21 17:09:57 +00:00
_file = new FileManager_v3d ( this ) ;
_scheduler = new Scheduler_v3d ( this ) ;
_intro = new intro_v3d ( this ) ;
_screen = new Screen_v1d ( this ) ;
_parser = new Parser_v3d ( this ) ;
2010-12-12 07:40:00 +00:00
_object = new ObjectHandler_v3d ( this ) ;
_normalTPS = 9 ;
2010-09-04 16:02:16 +00:00
break ;
}
2010-08-17 09:28:20 +00:00
if ( ! loadHugoDat ( ) )
return Common : : kUnknownError ;
2011-01-20 19:33:31 +00:00
// Use Windows-looking mouse cursor
2011-01-08 16:56:52 +00:00
_screen - > setCursorPal ( ) ;
_screen - > resetInventoryObjId ( ) ;
2010-08-17 09:28:20 +00:00
2011-02-15 18:30:15 +00:00
_scheduler - > initCypher ( ) ;
2010-08-17 09:28:20 +00:00
initStatus ( ) ; // Initialize game status
2011-01-23 00:05:52 +00:00
initConfig ( ) ; // Initialize user's config
2011-03-29 21:54:47 +00:00
if ( ! _status . doQuitFl ) {
initialize ( ) ;
resetConfig ( ) ; // Reset user's config
initMachine ( ) ;
// Start the state machine
_status . viewState = kViewIntroInit ;
int16 loadSlot = Common : : ConfigManager : : instance ( ) . getInt ( " save_slot " ) ;
if ( loadSlot > = 0 ) {
_status . skipIntroFl = true ;
_file - > restoreGame ( loadSlot ) ;
} else {
_file - > saveGame ( 0 , " New Game " ) ;
}
2011-02-24 18:59:36 +00:00
}
2010-08-17 09:28:20 +00:00
2010-10-10 13:06:48 +00:00
while ( ! _status . doQuitFl ) {
2011-02-14 07:31:01 +00:00
_screen - > drawBoundaries ( ) ;
2010-08-17 09:28:20 +00:00
g_system - > updateScreen ( ) ;
runMachine ( ) ;
2011-02-24 18:59:36 +00:00
2010-08-17 09:28:20 +00:00
// Handle input
Common : : Event event ;
while ( _eventMan - > pollEvent ( event ) ) {
switch ( event . type ) {
case Common : : EVENT_KEYDOWN :
2010-12-20 17:25:58 +00:00
_parser - > keyHandler ( event ) ;
2010-08-17 09:28:20 +00:00
break ;
case Common : : EVENT_MOUSEMOVE :
2011-02-08 20:52:26 +00:00
_mouse - > setMouseX ( event . mouse . x ) ;
_mouse - > setMouseY ( event . mouse . y ) ;
2010-08-17 09:28:20 +00:00
break ;
case Common : : EVENT_LBUTTONUP :
2011-02-08 20:52:26 +00:00
_mouse - > setLeftButton ( ) ;
2010-08-17 09:28:20 +00:00
break ;
case Common : : EVENT_RBUTTONUP :
2011-02-08 20:52:26 +00:00
_mouse - > setRightButton ( ) ;
2010-08-17 09:28:20 +00:00
break ;
case Common : : EVENT_QUIT :
2010-10-10 13:06:48 +00:00
_status . doQuitFl = true ;
2010-08-17 09:28:20 +00:00
break ;
default :
break ;
}
}
2011-04-25 12:28:19 +00:00
if ( _status . helpFl ) {
_status . helpFl = false ;
_file - > instructions ( ) ;
}
2011-06-19 22:59:48 +00:00
2011-01-19 18:02:53 +00:00
_mouse - > mouseHandler ( ) ; // Mouse activity - adds to display list
2011-01-23 00:05:52 +00:00
_screen - > displayList ( kDisplayDisplay ) ; // Blit the display list to screen
2010-11-03 23:56:34 +00:00
_status . doQuitFl | = shouldQuit ( ) ; // update game quit flag
2010-08-17 09:28:20 +00:00
}
return Common : : kNoError ;
}
void HugoEngine : : initMachine ( ) {
2010-09-17 22:40:53 +00:00
if ( _gameVariant = = kGameVariantH1Dos )
2010-09-16 23:03:03 +00:00
readScreenFiles ( 0 ) ;
else
2010-10-21 17:09:57 +00:00
_file - > readBackground ( _numScreens - 1 ) ; // Splash screen
2010-11-11 23:04:04 +00:00
_object - > readObjectImages ( ) ; // Read all object images
2010-08-17 09:28:20 +00:00
if ( _platform = = Common : : kPlatformWindows )
2010-10-21 17:09:57 +00:00
_file - > readUIFImages ( ) ; // Read all uif images (only in Win versions)
2011-06-19 22:59:48 +00:00
2011-02-01 00:08:12 +00:00
_sound - > initPcspkrPlayer ( ) ;
2010-08-17 09:28:20 +00:00
}
2010-11-01 20:20:21 +00:00
/**
2011-02-11 20:27:48 +00:00
* Hugo game state machine - called during onIdle
*/
2010-08-17 09:28:20 +00:00
void HugoEngine : : runMachine ( ) {
status_t & gameStatus = getGameStatus ( ) ;
// Don't process if gameover
if ( gameStatus . gameOverFl )
return ;
2011-02-03 18:25:38 +00:00
_curTime = g_system - > getMillis ( ) ;
2010-08-17 09:28:20 +00:00
// Process machine once every tick
2011-02-03 18:25:38 +00:00
while ( _curTime - _lastTime < ( uint32 ) ( 1000 / getTPS ( ) ) ) {
2011-01-01 10:13:42 +00:00
g_system - > delayMillis ( 5 ) ;
2011-02-03 18:25:38 +00:00
_curTime = g_system - > getMillis ( ) ;
2011-01-01 10:13:42 +00:00
}
2011-02-05 14:45:36 +00:00
2011-02-03 18:25:38 +00:00
_lastTime = _curTime ;
2010-08-17 09:28:20 +00:00
switch ( gameStatus . viewState ) {
2011-01-23 00:05:52 +00:00
case kViewIdle : // Not processing state machine
2011-01-08 16:56:52 +00:00
_screen - > hideCursor ( ) ;
2010-10-21 17:09:57 +00:00
_intro - > preNewGame ( ) ; // Any processing before New Game selected
2010-08-17 09:28:20 +00:00
break ;
2011-01-23 00:05:52 +00:00
case kViewIntroInit : // Initialization before intro begins
2010-10-21 17:09:57 +00:00
_intro - > introInit ( ) ;
2011-01-23 00:05:52 +00:00
gameStatus . viewState = kViewIntro ;
2010-08-17 09:28:20 +00:00
break ;
2011-01-23 00:05:52 +00:00
case kViewIntro : // Do any game-dependant preamble
2010-12-15 20:37:09 +00:00
if ( _intro - > introPlay ( ) ) { // Process intro screen
2010-10-21 17:09:57 +00:00
_scheduler - > newScreen ( 0 ) ; // Initialize first screen
2011-01-23 00:05:52 +00:00
gameStatus . viewState = kViewPlay ;
2010-08-17 09:28:20 +00:00
}
break ;
2011-01-23 00:05:52 +00:00
case kViewPlay : // Playing game
2011-01-08 16:56:52 +00:00
_screen - > showCursor ( ) ;
2010-10-21 17:09:57 +00:00
_parser - > charHandler ( ) ; // Process user cmd input
_object - > moveObjects ( ) ; // Process object movement
_scheduler - > runScheduler ( ) ; // Process any actions
2011-01-23 00:05:52 +00:00
_screen - > displayList ( kDisplayRestore ) ; // Restore previous background
2010-10-21 17:09:57 +00:00
_object - > updateImages ( ) ; // Draw into _frontBuffer, compile display list
_screen - > drawStatusText ( ) ;
2011-01-23 00:05:52 +00:00
_screen - > displayList ( kDisplayDisplay ) ; // Blit the display list to screen
2011-01-01 10:51:57 +00:00
_sound - > checkMusic ( ) ;
2010-08-17 09:28:20 +00:00
break ;
2011-01-23 00:05:52 +00:00
case kViewInvent : // Accessing inventory
2010-10-21 17:09:57 +00:00
_inventory - > runInventory ( ) ; // Process Inventory state machine
2010-08-17 09:28:20 +00:00
break ;
2011-01-23 00:05:52 +00:00
case kViewExit : // Game over or user exited
gameStatus . viewState = kViewIdle ;
2010-10-10 13:06:48 +00:00
_status . doQuitFl = true ;
2010-08-17 09:28:20 +00:00
break ;
}
}
2010-11-01 20:20:21 +00:00
/**
2011-02-11 20:27:48 +00:00
* Loads Hugo . dat file , which contains all the hardcoded data in the original executables
*/
2010-08-17 09:28:20 +00:00
bool HugoEngine : : loadHugoDat ( ) {
Common : : File in ;
in . open ( " hugo.dat " ) ;
if ( ! in . isOpen ( ) ) {
Common : : String errorMessage = " You're missing the 'hugo.dat' file. Get it from the ScummVM website " ;
GUIErrorMessage ( errorMessage ) ;
warning ( " %s " , errorMessage . c_str ( ) ) ;
return false ;
}
// Read header
2011-02-08 20:52:26 +00:00
char buf [ 4 ] ;
2010-08-17 09:28:20 +00:00
in . read ( buf , 4 ) ;
2011-02-08 20:52:26 +00:00
if ( memcmp ( buf , " HUGO " , 4 ) ) {
2010-08-17 09:28:20 +00:00
Common : : String errorMessage = " File 'hugo.dat' is corrupt. Get it from the ScummVM website " ;
GUIErrorMessage ( errorMessage ) ;
return false ;
}
2010-10-03 08:08:42 +00:00
int majVer = in . readByte ( ) ;
int minVer = in . readByte ( ) ;
2010-08-17 09:28:20 +00:00
if ( ( majVer ! = HUGO_DAT_VER_MAJ ) | | ( minVer ! = HUGO_DAT_VER_MIN ) ) {
2011-02-08 20:52:26 +00:00
Common : : String errorMessage = Common : : String : : format ( " File 'hugo.dat' is wrong version. Expected %d.%d but got %d.%d. Get it from the ScummVM website " , HUGO_DAT_VER_MAJ , HUGO_DAT_VER_MIN , majVer , minVer ) ;
GUIErrorMessage ( errorMessage ) ;
2010-08-17 09:28:20 +00:00
return false ;
}
_numVariant = in . readUint16BE ( ) ;
2011-02-15 09:15:21 +00:00
2010-11-06 13:21:18 +00:00
_screen - > loadPalette ( in ) ;
2011-02-20 10:32:00 +00:00
_screen - > loadFontArr ( in ) ;
2011-01-25 00:32:48 +00:00
_text - > loadAllTexts ( in ) ;
2011-02-15 09:15:21 +00:00
_intro - > loadIntroData ( in ) ;
_parser - > loadArrayReqs ( in ) ;
2011-02-20 10:32:00 +00:00
_parser - > loadCatchallList ( in ) ;
_parser - > loadBackgroundObjects ( in ) ;
_parser - > loadCmdList ( in ) ;
2011-02-14 07:31:01 +00:00
_mouse - > loadHotspots ( in ) ;
2011-02-15 09:15:21 +00:00
_inventory - > loadInvent ( in ) ;
_object - > loadObjectUses ( in ) ;
2011-02-20 10:32:00 +00:00
_object - > loadObjectArr ( in ) ;
_object - > loadNumObj ( in ) ;
2011-02-15 09:15:21 +00:00
_scheduler - > loadPoints ( in ) ;
_scheduler - > loadScreenAct ( in ) ;
2011-02-20 10:32:00 +00:00
_scheduler - > loadActListArr ( in ) ;
_scheduler - > loadAlNewscrIndex ( in ) ;
2011-01-23 00:05:52 +00:00
_hero = & _object - > _objects [ kHeroIndex ] ; // This always points to hero
_screen_p = & ( _object - > _objects [ kHeroIndex ] . screenIndex ) ; // Current screen is hero's
_heroImage = kHeroIndex ; // Current in use hero image
2010-11-01 20:20:21 +00:00
2010-08-17 09:28:20 +00:00
for ( int varnt = 0 ; varnt < _numVariant ; varnt + + ) {
if ( varnt = = _gameVariant ) {
2010-10-31 21:20:22 +00:00
_tunesNbr = in . readSByte ( ) ;
_soundSilence = in . readSByte ( ) ;
_soundTest = in . readSByte ( ) ;
2010-08-17 09:28:20 +00:00
} else {
2010-10-31 21:20:22 +00:00
in . readSByte ( ) ;
in . readSByte ( ) ;
in . readSByte ( ) ;
2010-08-17 09:28:20 +00:00
}
}
2011-02-15 09:15:21 +00:00
int numElem ;
2010-08-17 09:28:20 +00:00
//Read _defltTunes
for ( int varnt = 0 ; varnt < _numVariant ; varnt + + ) {
numElem = in . readUint16BE ( ) ;
if ( varnt = = _gameVariant ) {
_defltTunes = ( int16 * ) malloc ( sizeof ( int16 ) * numElem ) ;
for ( int i = 0 ; i < numElem ; i + + )
_defltTunes [ i ] = in . readSint16BE ( ) ;
} else {
for ( int i = 0 ; i < numElem ; i + + )
in . readSint16BE ( ) ;
}
}
//Read _screenStates size
for ( int varnt = 0 ; varnt < _numVariant ; varnt + + ) {
numElem = in . readUint16BE ( ) ;
if ( varnt = = _gameVariant ) {
2011-04-24 20:29:27 +00:00
_numStates = numElem ;
2010-08-17 09:28:20 +00:00
_screenStates = ( byte * ) malloc ( sizeof ( byte ) * numElem ) ;
2011-06-25 19:33:01 +00:00
memset ( _screenStates , 0 , sizeof ( byte ) * numElem ) ;
2010-08-17 09:28:20 +00:00
}
}
//Read look, take and drop special verbs indexes
for ( int varnt = 0 ; varnt < _numVariant ; varnt + + ) {
if ( varnt = = _gameVariant ) {
_look = in . readUint16BE ( ) ;
_take = in . readUint16BE ( ) ;
_drop = in . readUint16BE ( ) ;
} else {
in . readUint16BE ( ) ;
in . readUint16BE ( ) ;
in . readUint16BE ( ) ;
}
}
2011-01-07 15:14:38 +00:00
_sound - > loadIntroSong ( in ) ;
2011-01-03 16:19:00 +00:00
_topMenu - > loadBmpArr ( in ) ;
2010-08-17 09:28:20 +00:00
return true ;
}
2011-02-18 07:11:55 +00:00
uint16 * * HugoEngine : : loadLongArray ( Common : : SeekableReadStream & in ) {
2010-08-17 09:28:20 +00:00
uint16 * * resArray = 0 ;
for ( int varnt = 0 ; varnt < _numVariant ; varnt + + ) {
2010-10-03 08:08:42 +00:00
uint16 numRows = in . readUint16BE ( ) ;
2010-08-17 09:28:20 +00:00
if ( varnt = = _gameVariant ) {
resArray = ( uint16 * * ) malloc ( sizeof ( uint16 * ) * ( numRows + 1 ) ) ;
resArray [ numRows ] = 0 ;
}
for ( int i = 0 ; i < numRows ; i + + ) {
2010-10-03 08:08:42 +00:00
uint16 numElems = in . readUint16BE ( ) ;
2010-08-17 09:28:20 +00:00
if ( varnt = = _gameVariant ) {
2010-10-03 08:08:42 +00:00
uint16 * resRow = ( uint16 * ) malloc ( sizeof ( uint16 ) * numElems ) ;
2010-08-17 09:28:20 +00:00
for ( int j = 0 ; j < numElems ; j + + )
resRow [ j ] = in . readUint16BE ( ) ;
resArray [ i ] = resRow ;
} else {
2011-02-18 07:11:55 +00:00
in . skip ( numElems * sizeof ( uint16 ) ) ;
2010-08-17 09:28:20 +00:00
}
}
}
return resArray ;
}
2010-11-01 20:20:21 +00:00
/**
2011-02-11 20:27:48 +00:00
* Sets the playlist to be the default tune selection
*/
2011-01-23 00:05:52 +00:00
void HugoEngine : : initPlaylist ( bool playlist [ kMaxTunes ] ) {
2010-10-15 06:16:27 +00:00
debugC ( 1 , kDebugEngine , " initPlaylist " ) ;
2011-01-23 00:05:52 +00:00
for ( int16 i = 0 ; i < kMaxTunes ; i + + )
2010-10-15 06:16:27 +00:00
playlist [ i ] = false ;
for ( int16 i = 0 ; _defltTunes [ i ] ! = - 1 ; i + + )
playlist [ _defltTunes [ i ] ] = true ;
}
2010-11-01 20:20:21 +00:00
/**
2011-02-11 20:27:48 +00:00
* Initialize the dynamic game status
*/
2010-10-15 06:16:27 +00:00
void HugoEngine : : initStatus ( ) {
debugC ( 1 , kDebugEngine , " initStatus " ) ;
2011-05-25 18:23:02 +00:00
_status . storyModeFl = false ; // Not in story mode
_status . gameOverFl = false ; // Hero not knobbled yet
_status . lookFl = false ; // Toolbar "look" button
_status . recallFl = false ; // Toolbar "recall" button
_status . newScreenFl = false ; // Screen not just loaded
_status . godModeFl = false ; // No special cheats allowed
2011-05-25 21:58:46 +00:00
_status . showBoundariesFl = false ; // Boundaries hidden by default
_status . doQuitFl = false ;
2011-05-25 18:23:02 +00:00
_status . skipIntroFl = false ;
_status . helpFl = false ;
2010-10-15 06:16:27 +00:00
// Initialize every start of new game
_status . tick = 0 ; // Tick count
2011-01-23 00:05:52 +00:00
_status . viewState = kViewIdle ; // View state
2010-11-26 23:17:16 +00:00
// Strangerke - Suppress as related to playback
// _status.recordFl = false; // Not record mode
// _status.playbackFl = false; // Not playback mode
// Strangerke - Not used ?
// _status.mmtime = false; // Multimedia timer support
2011-02-08 20:52:26 +00:00
// _status.helpFl = false; // Not calling WinHelp()
// _status.demoFl = false; // Not demo mode
// _status.path[0] = 0; // Path to write files
2010-11-26 23:17:16 +00:00
// _status.screenWidth = 0; // Desktop screen width
// _status.saveTick = 0; // Time of last save
2010-11-29 17:42:08 +00:00
// _status.saveSlot = 0; // Slot to save/restore game
2011-04-25 12:28:19 +00:00
// _status.textBoxFl = false; // Not processing a text box
2010-10-15 06:16:27 +00:00
}
2010-11-01 20:20:21 +00:00
/**
2011-02-11 20:27:48 +00:00
* Initialize default config values . Must be done before Initialize ( ) .
*/
2011-01-23 00:05:52 +00:00
void HugoEngine : : initConfig ( ) {
debugC ( 1 , kDebugEngine , " initConfig() " ) ;
_config . musicFl = true ; // Music state initially on
_config . soundFl = true ; // Sound state initially on
_config . turboFl = false ; // Turbo state initially off
initPlaylist ( _config . playlist ) ; // Initialize default tune playlist
_file - > readBootFile ( ) ; // Read startup structure
}
/**
2011-02-11 20:27:48 +00:00
* Reset config parts . Currently only reset music played based on playlist
*/
2011-01-23 00:05:52 +00:00
void HugoEngine : : resetConfig ( ) {
debugC ( 1 , kDebugEngine , " resetConfig() " ) ;
// Find first tune and play it
for ( int16 i = 0 ; i < kMaxTunes ; i + + ) {
if ( _config . playlist [ i ] ) {
_sound - > playMusic ( i ) ;
break ;
2010-10-15 06:16:27 +00:00
}
}
}
void HugoEngine : : initialize ( ) {
debugC ( 1 , kDebugEngine , " initialize " ) ;
_maze . enabledFl = false ;
_line [ 0 ] = ' \0 ' ;
2010-10-21 17:09:57 +00:00
_sound - > initSound ( ) ;
_scheduler - > initEventQueue ( ) ; // Init scheduler stuff
_screen - > initDisplay ( ) ; // Create Dibs and palette
_file - > openDatabaseFiles ( ) ; // Open database files
2011-05-25 15:17:11 +00:00
calcMaxScore ( ) ; // Initialize maxscore
2010-10-15 06:16:27 +00:00
2011-05-16 14:35:10 +00:00
_rnd = new Common : : RandomSource ( " hugo " ) ;
2010-10-15 06:16:27 +00:00
_rnd - > setSeed ( 42 ) ; // Kick random number generator
2010-11-07 22:10:29 +00:00
switch ( _gameVariant ) {
case kGameVariantH1Dos :
_episode = " \" Hugo's House of Horrors \" " ;
2011-01-31 18:22:20 +00:00
_picDir = " " ;
2010-11-07 22:10:29 +00:00
break ;
case kGameVariantH2Dos :
2010-12-08 20:51:44 +00:00
_episode = " \" Hugo II: Whodunit? \" " ;
2011-01-31 18:22:20 +00:00
_picDir = " " ;
2010-11-07 22:10:29 +00:00
break ;
case kGameVariantH3Dos :
_episode = " \" Hugo III: Jungle of Doom \" " ;
2011-01-31 18:22:20 +00:00
_picDir = " pictures/ " ;
2010-11-07 22:10:29 +00:00
break ;
case kGameVariantH1Win :
_episode = " \" Hugo's Horrific Adventure \" " ;
2011-01-31 18:22:20 +00:00
_picDir = " hugo1/ " ;
2010-10-15 06:16:27 +00:00
break ;
2010-11-07 22:10:29 +00:00
case kGameVariantH2Win :
2010-10-15 06:16:27 +00:00
_episode = " \" Hugo's Mystery Adventure \" " ;
2011-01-31 18:22:20 +00:00
_picDir = " hugo2/ " ;
2010-10-15 06:16:27 +00:00
break ;
2010-11-07 22:10:29 +00:00
case kGameVariantH3Win :
2010-10-15 06:16:27 +00:00
_episode = " \" Hugo's Amazon Adventure \" " ;
2011-01-31 18:22:20 +00:00
_picDir = " hugo3/ " ;
2010-10-15 06:16:27 +00:00
break ;
default :
error ( " Unknown game " ) ;
}
}
2010-11-01 20:20:21 +00:00
/**
2011-02-11 20:27:48 +00:00
* Read scenery , overlay files for given screen number
*/
2011-02-02 21:12:51 +00:00
void HugoEngine : : readScreenFiles ( const int screenNum ) {
2010-10-15 06:16:27 +00:00
debugC ( 1 , kDebugEngine , " readScreenFiles(%d) " , screenNum ) ;
2010-10-21 17:09:57 +00:00
_file - > readBackground ( screenNum ) ; // Scenery file
2011-01-23 00:05:52 +00:00
memcpy ( _screen - > getBackBuffer ( ) , _screen - > getFrontBuffer ( ) , sizeof ( _screen - > getFrontBuffer ( ) ) ) ; // Make a copy
2011-02-27 00:04:49 +00:00
// Workaround for graphic glitches in DOS versions. Cleaning the overlays fix the problem
memset ( _object - > _objBound , ' \0 ' , sizeof ( overlay_t ) ) ;
memset ( _object - > _boundary , ' \0 ' , sizeof ( overlay_t ) ) ;
memset ( _object - > _overlay , ' \0 ' , sizeof ( overlay_t ) ) ;
memset ( _object - > _ovlBase , ' \0 ' , sizeof ( overlay_t ) ) ;
2011-02-11 07:12:29 +00:00
_file - > readOverlay ( screenNum , _object - > _boundary , kOvlBoundary ) ; // Boundary file
_file - > readOverlay ( screenNum , _object - > _overlay , kOvlOverlay ) ; // Overlay file
_file - > readOverlay ( screenNum , _object - > _ovlBase , kOvlBase ) ; // Overlay base file
2011-01-18 09:16:52 +00:00
2011-01-18 18:26:33 +00:00
// Suppress a boundary used in H3 DOS in 'Crash' screen, which blocks
// pathfinding and is useless.
if ( ( screenNum = = 0 ) & & ( _gameVariant = = kGameVariantH3Dos ) )
2011-02-11 07:12:29 +00:00
_object - > clearScreenBoundary ( 50 , 311 , 152 ) ;
2011-01-18 09:16:52 +00:00
}
2010-11-01 20:20:21 +00:00
/**
2011-02-11 20:27:48 +00:00
* Set the new screen number into the hero object and any carried objects
*/
2011-02-02 21:12:51 +00:00
void HugoEngine : : setNewScreen ( const int screenNum ) {
2010-10-15 06:16:27 +00:00
debugC ( 1 , kDebugEngine , " setNewScreen(%d) " , screenNum ) ;
2010-11-01 20:20:21 +00:00
* _screen_p = screenNum ; // HERO object
2010-11-11 23:04:04 +00:00
_object - > setCarriedScreen ( screenNum ) ; // Carried objects
2010-10-15 06:16:27 +00:00
}
2010-11-01 20:20:21 +00:00
/**
2011-02-11 20:27:48 +00:00
* Add up all the object values and all the bonus points
*/
2010-10-15 06:16:27 +00:00
void HugoEngine : : calcMaxScore ( ) {
debugC ( 1 , kDebugEngine , " calcMaxScore " ) ;
2011-02-15 09:15:21 +00:00
_maxscore = _object - > calcMaxScore ( ) + _scheduler - > calcMaxPoints ( ) ;
2010-10-15 06:16:27 +00:00
}
2010-11-01 20:20:21 +00:00
/**
2011-02-11 20:27:48 +00:00
* Exit game , advertise trilogy , show copyright
*/
2010-10-15 06:16:27 +00:00
void HugoEngine : : endGame ( ) {
debugC ( 1 , kDebugEngine , " endGame " ) ;
2011-03-07 18:40:20 +00:00
if ( _boot . registered ! = kRegRegistered )
2011-03-21 12:07:23 +00:00
Utils : : notifyBox ( _text - > getTextEngine ( kEsAdvertise ) ) ;
Utils : : notifyBox ( Common : : String : : format ( " %s \n %s " , _episode , getCopyrightString ( ) ) ) ;
2011-01-23 00:05:52 +00:00
_status . viewState = kViewExit ;
2010-10-15 06:16:27 +00:00
}
2011-02-07 22:58:22 +00:00
bool HugoEngine : : canLoadGameStateCurrently ( ) {
2010-11-29 17:42:08 +00:00
return true ;
}
2011-02-07 22:58:22 +00:00
bool HugoEngine : : canSaveGameStateCurrently ( ) {
2011-01-23 00:05:52 +00:00
return ( _status . viewState = = kViewPlay ) ;
2010-11-29 17:42:08 +00:00
}
2011-02-02 21:12:51 +00:00
int8 HugoEngine : : getTPS ( ) const {
2011-01-23 00:05:52 +00:00
return ( ( _config . turboFl ) ? kTurboTps : _normalTPS ) ;
2010-12-12 07:40:00 +00:00
}
2010-12-22 22:25:52 +00:00
void HugoEngine : : syncSoundSettings ( ) {
Engine : : syncSoundSettings ( ) ;
_sound - > syncVolume ( ) ;
}
2011-02-12 08:13:35 +00:00
Common : : String HugoEngine : : getSavegameFilename ( int slot ) {
return _targetName + Common : : String : : format ( " -%02d.SAV " , slot ) ;
}
2010-12-22 22:25:52 +00:00
2010-08-17 09:28:20 +00:00
} // End of namespace Hugo