2001-10-09 14:30:12 +00:00
/* ScummVM - Scumm Interpreter
* Copyright ( C ) 2001 Ludvig Strigeus
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
* of the License , or ( at your option ) any later version .
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*
2001-11-06 20:00:47 +00:00
* $ Header $
2001-10-09 14:30:12 +00:00
*
*/
# include "stdafx.h"
# include "scumm.h"
2001-11-09 18:54:15 +00:00
# include "gui.h"
2002-02-27 22:48:55 +00:00
# include "string.h"
2001-10-09 14:30:12 +00:00
void Scumm : : initRandSeeds ( ) {
_randSeed1 = 0xA943DE35 ;
_randSeed2 = 0x37A9ED27 ;
}
uint Scumm : : getRandomNumber ( uint max ) {
/* TODO: my own random number generator */
_randSeed1 = 0xDEADBEEF * ( _randSeed1 + 1 ) ;
_randSeed1 = ( _randSeed1 > > 13 ) | ( _randSeed1 < < 19 ) ;
2001-10-16 10:01:48 +00:00
return _randSeed1 % max ;
2001-10-09 14:30:12 +00:00
}
2001-11-26 19:57:57 +00:00
uint Scumm : : getRandomNumberRng ( uint min , uint max ) {
return getRandomNumber ( max - min + 1 ) + min ;
}
2001-10-09 14:30:12 +00:00
void Scumm : : scummInit ( ) {
int i ;
Actor * a ;
debug ( 9 , " scummInit " ) ;
2001-11-26 19:57:57 +00:00
2002-02-12 18:20:37 +00:00
if ( _features & GF_SMALL_HEADER )
_resourceHeaderSize = 6 ;
else
_resourceHeaderSize = 8 ;
if ( ! ( _features & GF_SMALL_NAMES ) )
loadCharset ( 1 ) ;
2001-12-27 17:51:58 +00:00
2001-10-09 14:30:12 +00:00
initScreens ( 0 , 16 , 320 , 144 ) ;
setShake ( 0 ) ;
2001-11-06 20:00:47 +00:00
setupCursor ( ) ;
2001-10-09 14:30:12 +00:00
2001-11-10 19:12:32 +00:00
for ( i = 1 , a = getFirstActor ( ) ; + + a , i < NUM_ACTORS ; i + + ) {
2001-10-09 14:30:12 +00:00
a - > number = i ;
initActor ( a , 1 ) ;
}
_defaultTalkDelay = 60 ;
2001-10-16 10:01:48 +00:00
_vars [ VAR_CHARINC ] = 4 ;
2001-10-09 14:30:12 +00:00
_numNestedScripts = 0 ;
vm . cutSceneStackPointer = 0 ;
memset ( vm . cutScenePtr , 0 , sizeof ( vm . cutScenePtr ) ) ;
memset ( vm . cutSceneData , 0 , sizeof ( vm . cutSceneData ) ) ;
for ( i = 0 ; i < _maxVerbs ; i + + ) {
2001-10-16 10:01:48 +00:00
_verbs [ i ] . verbid = 0 ;
_verbs [ i ] . right = 319 ;
_verbs [ i ] . oldleft = - 1 ;
_verbs [ i ] . type = 0 ;
_verbs [ i ] . color = 2 ;
_verbs [ i ] . hicolor = 0 ;
_verbs [ i ] . charset_nr = 1 ;
_verbs [ i ] . curmode = 0 ;
_verbs [ i ] . saveid = 0 ;
_verbs [ i ] . center = 0 ;
_verbs [ i ] . key = 0 ;
2001-10-09 14:30:12 +00:00
}
2001-12-27 17:51:58 +00:00
# if !defined(FULL_THROTTLE)
2001-10-09 14:30:12 +00:00
camera . _leftTrigger = 10 ;
camera . _rightTrigger = 30 ;
camera . _mode = 0 ;
2001-12-27 17:51:58 +00:00
# endif
2001-10-09 14:30:12 +00:00
camera . _follows = 0 ;
virtscr [ 0 ] . xstart = 0 ;
2001-11-26 19:57:57 +00:00
# if !defined(FULL_THROTTLE)
2001-10-26 17:34:50 +00:00
_vars [ VAR_V5_DRAWFLAGS ] = 11 ;
_vars [ VAR_59 ] = 3 ;
2001-11-26 19:57:57 +00:00
# endif
2001-10-09 14:30:12 +00:00
mouse . x = 104 ;
mouse . y = 56 ;
_ENCD_offs = 0 ;
_EXCD_offs = 0 ;
_currentScript = 0xFF ;
2001-11-26 19:57:57 +00:00
_sentenceNum = 0 ;
2001-10-09 14:30:12 +00:00
_currentRoom = 0 ;
_numObjectsInRoom = 0 ;
_actorToPrintStrFor = 0 ;
charset . _bufPos = 0 ;
_haveMsg = 0 ;
_screenStartStrip = 0 ;
2001-10-26 17:34:50 +00:00
_vars [ VAR_TALK_ACTOR ] = 0 ;
2001-10-09 14:30:12 +00:00
_talkDelay = 0 ;
_keepText = false ;
_cursorState = 0 ;
_userPut = 0 ;
_newEffect = 129 ;
2001-11-09 18:54:15 +00:00
_fullRedraw = true ;
2001-10-09 14:30:12 +00:00
clearDrawObjectQueue ( ) ;
for ( i = 0 ; i < 6 ; i + + ) {
2002-02-19 22:36:09 +00:00
if ( _features & GF_OLD256 )
{
string [ i ] . t_xpos = 0 ;
string [ i ] . t_ypos = 0 ;
} else {
string [ i ] . t_xpos = 2 ;
string [ i ] . t_ypos = 5 ;
}
2001-10-16 10:01:48 +00:00
string [ i ] . t_right = 319 ;
string [ i ] . t_color = 0xF ;
string [ i ] . t_center = 0 ;
string [ i ] . t_charset = 0 ;
2001-10-09 14:30:12 +00:00
}
_numInMsgStack = 0 ;
2001-11-05 19:21:49 +00:00
createResource ( rtTemp , 6 , 500 ) ;
2001-10-09 14:30:12 +00:00
initScummVars ( ) ;
2001-11-26 19:57:57 +00:00
if ( ! ( _features & GF_AFTER_V6 ) )
2001-10-26 17:34:50 +00:00
_vars [ VAR_V5_TALK_STRING_Y ] = - 0x50 ;
2001-10-09 14:30:12 +00:00
getGraphicsPerformance ( ) ;
}
void Scumm : : initScummVars ( ) {
2001-11-26 19:57:57 +00:00
# if !defined(FULL_THROTTLE)
2001-10-16 10:01:48 +00:00
_vars [ VAR_CURRENTDRIVE ] = _currentDrive ;
_vars [ VAR_FIXEDDISK ] = checkFixedDisk ( ) ;
_vars [ VAR_SOUNDCARD ] = _soundCardType ;
2001-11-09 18:54:15 +00:00
_vars [ VAR_VIDEOMODE ] = 0x13 ;
2001-11-12 20:50:36 +00:00
_vars [ VAR_HEAPSPACE ] = 630 ;
2001-10-16 10:01:48 +00:00
_vars [ VAR_MOUSEPRESENT ] = _mousePresent ;
_vars [ VAR_SOUNDPARAM ] = _soundParam ;
_vars [ VAR_SOUNDPARAM2 ] = _soundParam2 ;
_vars [ VAR_SOUNDPARAM3 ] = _soundParam3 ;
2001-11-26 19:57:57 +00:00
if ( _features & GF_AFTER_V6 )
2001-10-26 17:34:50 +00:00
_vars [ VAR_V6_EMSSPACE ] = 10000 ;
2001-11-26 19:57:57 +00:00
# endif
2001-10-09 14:30:12 +00:00
}
void Scumm : : checkRange ( int max , int min , int no , const char * str ) {
if ( no < min | | no > max ) {
2002-02-12 18:20:37 +00:00
error ( " Value %d is out of bounds (%d,%d) int script(%d) msg %s " , no , min , max , vm . slot [ _curExecScript ] . number , str ) ;
2001-10-09 14:30:12 +00:00
}
}
2002-02-24 17:25:03 +00:00
void Scumm : : scummMain ( int argc , char * * argv ) {
2001-10-09 14:30:12 +00:00
charset . _vm = this ;
2001-10-26 17:34:50 +00:00
gdi . _vm = this ;
2001-10-09 14:30:12 +00:00
_fileHandle = NULL ;
_debugMode = 1 ;
2001-11-05 19:21:49 +00:00
2001-11-14 18:40:39 +00:00
_maxHeapThreshold = 450000 ;
_minHeapThreshold = 400000 ;
2002-02-27 22:48:55 +00:00
_gameDataPath = NULL ;
2002-03-02 12:54:37 +00:00
_gameTempo = 0 ;
2001-10-23 19:51:50 +00:00
parseCommandLine ( argc , argv ) ;
if ( _exe_name = = NULL )
error ( " Specify the name of the game to start on the command line " ) ;
if ( ! detectGame ( ) ) {
warning ( " Game detection failed. Using default settings " ) ;
2001-11-26 19:57:57 +00:00
_features = GF_DEFAULT ;
2001-10-23 19:51:50 +00:00
}
2002-02-27 22:48:55 +00:00
if ( ! _gameDataPath ) {
warning ( " No path was provided. Assuming that data file are in the current directory " ) ;
2002-03-02 12:54:37 +00:00
_gameDataPath = ( char * ) malloc ( sizeof ( char ) * 2 ) ;
2002-03-02 08:48:31 +00:00
strcpy ( _gameDataPath , " " ) ;
2002-02-27 22:48:55 +00:00
}
2002-02-23 23:23:28 +00:00
if ( _features & GF_AFTER_V7 )
setupScummVarsNew ( ) ;
else
setupScummVarsOld ( ) ;
2001-10-23 19:51:50 +00:00
if ( _gameId = = GID_INDY4 & & _bootParam = = 0 ) {
_bootParam = - 7873 ;
}
2001-10-29 23:07:24 +00:00
2001-12-01 17:06:13 +00:00
// if (_gameId==GID_MONKEY2 && _bootParam==0) {
// _bootParam = 10001;
// }
2001-11-14 18:40:39 +00:00
2001-11-06 20:00:47 +00:00
initGraphics ( this , _fullScreen ) ;
2001-10-09 19:02:28 +00:00
2002-02-12 18:20:37 +00:00
if ( _features & GF_SMALL_HEADER )
readIndexFileSmall ( ) ;
else
readIndexFile ( ) ;
2001-11-26 19:57:57 +00:00
initRandSeeds ( ) ;
if ( _features & GF_NEW_OPCODES )
setupOpcodes2 ( ) ;
2001-10-23 19:51:50 +00:00
else
2001-11-26 19:57:57 +00:00
setupOpcodes ( ) ;
2001-10-23 19:51:50 +00:00
2001-10-09 14:30:12 +00:00
scummInit ( ) ;
2001-11-26 19:57:57 +00:00
# if !defined(FULL_THROTTLE)
2001-10-16 10:01:48 +00:00
_vars [ VAR_VERSION ] = 21 ;
2001-11-26 19:57:57 +00:00
# endif
2001-10-16 10:01:48 +00:00
_vars [ VAR_DEBUGMODE ] = _debugMode ;
2001-10-09 14:30:12 +00:00
2001-10-29 23:07:24 +00:00
if ( _gameId = = GID_MONKEY ) {
_vars [ 74 ] = 1225 ;
}
2001-11-05 19:21:49 +00:00
setupSound ( ) ;
2001-10-29 23:07:24 +00:00
2001-10-09 14:30:12 +00:00
runScript ( 1 , 0 , 0 , & _bootParam ) ;
2001-11-09 18:54:15 +00:00
// _scummTimer = 0;
}
2001-10-09 14:30:12 +00:00
2001-11-09 18:54:15 +00:00
int Scumm : : scummLoop ( int delta ) {
if ( _debugger )
_debugger - > on_frame ( ) ;
_vars [ VAR_TMR_1 ] + = delta ;
_vars [ VAR_TMR_2 ] + = delta ;
_vars [ VAR_TMR_3 ] + = delta ;
_vars [ VAR_TMR_4 ] + = delta ;
2001-10-09 14:30:12 +00:00
2001-11-09 18:54:15 +00:00
if ( delta > 15 )
delta = 15 ;
2001-10-23 19:51:50 +00:00
2001-11-09 18:54:15 +00:00
decreaseScriptDelay ( delta ) ;
2001-11-05 19:21:49 +00:00
2001-11-09 18:54:15 +00:00
_talkDelay - = delta ;
if ( _talkDelay < 0 ) _talkDelay = 0 ;
processKbd ( ) ;
2001-12-27 17:51:58 +00:00
# if defined(FULL_THROTTLE)
_vars [ VAR_CAMERA_POS_X ] = camera . _cur . x ;
_vars [ VAR_CAMERA_POS_Y ] = camera . _cur . y ;
# else
_vars [ VAR_CAMERA_POS_X ] = camera . _cur . x ;
# endif
2001-11-09 18:54:15 +00:00
_vars [ VAR_HAVE_MSG ] = _haveMsg ;
_vars [ VAR_VIRT_MOUSE_X ] = _virtual_mouse_x ;
_vars [ VAR_VIRT_MOUSE_Y ] = _virtual_mouse_y ;
_vars [ VAR_MOUSE_X ] = mouse . x ;
_vars [ VAR_MOUSE_Y ] = mouse . y ;
_vars [ VAR_DEBUGMODE ] = _debugMode ;
2002-02-12 22:25:41 +00:00
if ( _features & GF_AUDIOTRACKS )
2002-02-12 22:46:30 +00:00
_vars [ VAR_MI1_TIMER ] + = 5 ;
2002-02-22 16:59:24 +00:00
else
if ( _features & GF_OLD256 )
_vars [ VAR_MUSIC_FLAG ] + + ;
2001-11-09 18:54:15 +00:00
if ( _saveLoadFlag ) {
if ( _saveLoadFlag = = 1 ) {
saveState ( _saveLoadSlot , _saveLoadCompatible ) ;
if ( _saveLoadCompatible )
_vars [ VAR_GAME_LOADED ] = 201 ;
} else {
loadState ( _saveLoadSlot , _saveLoadCompatible ) ;
if ( _saveLoadCompatible ) {
_vars [ VAR_GAME_LOADED ] = 203 ;
2001-10-10 10:02:33 +00:00
}
2001-10-09 14:30:12 +00:00
}
2001-11-09 18:54:15 +00:00
_saveLoadFlag = 0 ;
}
2001-10-09 14:30:12 +00:00
2001-11-09 18:54:15 +00:00
if ( _completeScreenRedraw ) {
int i ;
Actor * a ;
_completeScreenRedraw = false ;
gdi . clearUpperMask ( ) ;
charset . _hasMask = false ;
redrawVerbs ( ) ;
_fullRedraw = true ;
2001-11-10 19:12:32 +00:00
for ( i = 0 , a = getFirstActor ( ) ; i < NUM_ACTORS ; i + + , a + + )
2001-11-09 18:54:15 +00:00
a - > needRedraw = 1 ;
}
2001-10-09 14:30:12 +00:00
2001-11-09 18:54:15 +00:00
runAllScripts ( ) ;
checkExecVerbs ( ) ;
checkAndRunVar33 ( ) ;
2001-10-09 14:30:12 +00:00
2001-11-09 18:54:15 +00:00
if ( _currentRoom = = 0 ) {
gdi . _cursorActive = 0 ;
CHARSET_1 ( ) ;
drawDirtyScreenParts ( ) ;
processSoundQues ( ) ;
2001-12-27 17:51:58 +00:00
camera . _last = camera . _cur ;
2001-11-09 18:54:15 +00:00
} else {
2001-10-09 14:30:12 +00:00
walkActors ( ) ;
moveCamera ( ) ;
fixObjectFlags ( ) ;
CHARSET_1 ( ) ;
2001-12-27 17:51:58 +00:00
# if !defined(FULL_THROTTLE)
if ( camera . _cur . x ! = camera . _last . x | | _BgNeedsRedraw | | _fullRedraw ) {
# else
if ( camera . _cur . x ! = camera . _last . x | |
camera . _cur . y ! = camera . _last . y | | _BgNeedsRedraw | |
_fullRedraw ) {
# endif
2002-02-14 15:09:40 +00:00
redrawBGAreas ( ) ;
2001-10-09 14:30:12 +00:00
}
processDrawQue ( ) ;
setActorRedrawFlags ( ) ;
resetActorBgs ( ) ;
2001-11-26 19:57:57 +00:00
// if (!(_vars[VAR_V5_DRAWFLAGS]&2) && _vars[VAR_V5_DRAWFLAGS]&4) {
// error("Flashlight not implemented in this version");
// }
2001-10-09 14:30:12 +00:00
2001-11-26 19:57:57 +00:00
processActors ( ) ;
2001-10-09 14:30:12 +00:00
clear_fullRedraw ( ) ;
cyclePalette ( ) ;
palManipulate ( ) ;
2001-11-09 18:54:15 +00:00
2001-10-26 17:34:50 +00:00
if ( _doEffect ) {
_doEffect = false ;
2001-10-09 14:30:12 +00:00
screenEffect ( _newEffect ) ;
clearClickedStatus ( ) ;
}
2001-11-09 18:54:15 +00:00
2001-10-09 14:30:12 +00:00
if ( _cursorState > 0 ) {
verbMouseOver ( checkMouseOver ( mouse . x , mouse . y ) ) ;
}
2001-11-09 18:54:15 +00:00
gdi . _cursorActive = _cursorState > 0 ;
2001-10-09 14:30:12 +00:00
2001-11-11 16:54:45 +00:00
drawEnqueuedObjects ( ) ;
2001-11-09 18:54:15 +00:00
drawDirtyScreenParts ( ) ;
2001-11-11 16:54:45 +00:00
removeEnqueuedObjects ( ) ;
2001-10-09 14:30:12 +00:00
2001-11-26 19:57:57 +00:00
if ( ! ( _features & GF_AFTER_V6 ) )
2001-10-23 19:51:50 +00:00
playActorSounds ( ) ;
2001-11-05 19:21:49 +00:00
processSoundQues ( ) ;
2001-12-27 17:51:58 +00:00
camera . _last = camera . _cur ;
2001-11-09 18:54:15 +00:00
}
if ( ! ( + + _expire_counter ) ) {
increaseResourceCounter ( ) ;
}
_vars [ VAR_TIMER ] = 0 ;
return _vars [ VAR_TIMER_NEXT ] ;
}
2001-10-09 19:02:28 +00:00
void Scumm : : parseCommandLine ( int argc , char * * argv ) {
int i ;
char * s ;
/* Parse the arguments */
for ( i = 1 ; i < argc ; i + + ) {
s = argv [ i ] ;
if ( s & & s [ 0 ] = = ' - ' ) {
s + + ;
while ( * s ) {
switch ( tolower ( * s ) ) {
case ' b ' :
_bootParam = atoi ( s + 1 ) ;
goto NextArg ;
2001-11-06 20:00:47 +00:00
case ' f ' :
_fullScreen = true ;
break ;
2002-02-03 20:41:23 +00:00
case ' v ' :
2002-02-03 21:46:26 +00:00
printf ( " ScummVM " SCUMMVM_VERSION " \n Built on " __DATE__ " " __TIME__ " \n " ) ;
2002-02-03 20:41:23 +00:00
exit ( 1 ) ;
2002-02-27 22:48:55 +00:00
case ' p ' :
_gameDataPath = argv [ + + i ] ;
break ;
2002-03-02 12:54:37 +00:00
case ' t ' :
_gameTempo = atoi ( s + 1 ) ;
goto NextArg ;
2001-10-09 19:02:28 +00:00
default :
2001-10-23 19:51:50 +00:00
ShowHelpAndExit : ;
printf (
" ScummVM - Scumm Interpreter \n "
" Syntax: \n "
2002-02-27 22:48:55 +00:00
" \t scummvm [-b<num>] [-p path] game \n "
2001-10-23 19:51:50 +00:00
" Flags: \n "
2001-11-06 20:00:47 +00:00
" \t b<num> - start in that room \n "
2002-03-02 12:54:37 +00:00
" \t t<num> - Set music tempo. Suggested: 1F0000 \n "
2001-11-06 20:00:47 +00:00
" \t f - fullscreen mode \n " ) ;
2001-10-23 19:51:50 +00:00
exit ( 1 ) ;
2001-10-09 19:02:28 +00:00
}
s + + ;
}
NextArg : ;
} else {
2001-10-23 19:51:50 +00:00
if ( _exe_name ) goto ShowHelpAndExit ;
_exe_name = s ;
2001-10-09 19:02:28 +00:00
}
}
2001-10-23 19:51:50 +00:00
2001-10-09 19:02:28 +00:00
}
2001-10-23 19:51:50 +00:00
struct VersionSettings {
2001-11-08 20:00:33 +00:00
const char * filename ;
const char * gamename ;
2001-11-06 20:18:26 +00:00
byte id , major , middle , minor ;
2001-11-26 19:57:57 +00:00
uint32 features ;
2001-10-11 11:49:51 +00:00
} ;
2002-02-12 18:20:37 +00:00
/*
This is a list of all known SCUMM games . Commented games are not
supported at this time */
2001-10-23 19:51:50 +00:00
static const VersionSettings version_settings [ ] = {
2002-02-12 18:20:37 +00:00
/* Scumm Version 1 */
// {"maniac", "Maniac Mansion (C64)", GID_MANIAC64, 1, 0, 0,},
// {"zak", "Zak McKracken and the Alien Mindbenders (C64)", GID_ZAK64, 1, 0, 0,},
/* Scumm Version 2 */
// {"maniac", "Maniac Mansion", GID_MANIAC, 2, 0, 0,},
// {"zak", "Zak McKracken and the Alien Mindbenders", GID_ZAK, 2, 0, 0,},
// {"indy3", "Indiana Jones and the Last Crusade", GID_INDY3, 2, 0, 0,},
/* Scumm Version 3 */
2002-02-15 13:11:51 +00:00
{ " indy3 " , " Indiana Jones and the Last Crusade (256) " , GID_INDY3_256 , 3 , 0 , 22 , GF_SMALL_HEADER | GF_USE_KEY | GF_SMALL_NAMES | GF_OLD256 | GF_NO_SCALLING } ,
{ " zak256 " , " Zak McKracken and the Alien Mindbenders (256) " , GID_ZAK256 , 3 , 0 , 0 , GF_SMALL_HEADER | GF_USE_KEY | GF_SMALL_NAMES | GF_OLD256 | GF_AUDIOTRACKS | GF_NO_SCALLING } ,
{ " loom " , " Loom " , GID_LOOM , 3 , 5 , 40 , GF_SMALL_HEADER | GF_USE_KEY | GF_SMALL_NAMES | GF_OLD_BUNDLE | GF_16COLOR | GF_NO_SCALLING } ,
2002-02-12 18:20:37 +00:00
/* Scumm Version 4 */
{ " monkeyEGA " , " Monkey Island 1 (EGA) " , GID_MONKEY_EGA , 4 , 0 , 67 , GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR } , // EGA version
/* Scumm version 5 */
2002-02-12 22:25:41 +00:00
{ " loomcd " , " Loom (256 color CD version) " , GID_LOOM256 , 5 , 1 , 42 , GF_SMALL_HEADER | GF_USE_KEY | GF_AUDIOTRACKS } ,
{ " monkey " , " Monkey Island 1 " , GID_MONKEY , 5 , 2 , 2 , GF_USE_KEY | GF_AUDIOTRACKS } ,
2002-02-12 18:20:37 +00:00
{ " monkey2 " , " Monkey Island 2: LeChuck's revenge " , GID_MONKEY2 , 5 , 2 , 2 , GF_USE_KEY } ,
{ " atlantis " , " Indiana Jones 4 and the Fate of Atlantis " , GID_INDY4 , 5 , 5 , 0 , GF_USE_KEY } ,
{ " playfate " , " Indiana Jones 4 and the Fate of Atlantis (Demo) " , GID_INDY4 , 5 , 5 , 0 , GF_USE_KEY } ,
/* Scumm Version 6 */
{ " tentacle " , " Day Of The Tentacle " , GID_TENTACLE , 6 , 4 , 2 , GF_NEW_OPCODES | GF_AFTER_V6 | GF_USE_KEY } ,
{ " dottdemo " , " Day Of The Tentacle (Demo) " , GID_TENTACLE , 6 , 3 , 2 , GF_NEW_OPCODES | GF_AFTER_V6 | GF_USE_KEY } ,
{ " samnmax " , " Sam & Max " , GID_SAMNMAX , 6 , 4 , 2 , GF_NEW_OPCODES | GF_AFTER_V6 | GF_USE_KEY | GF_DRAWOBJ_OTHER_ORDER } ,
{ " snmdemo " , " Sam & Max (Demo) " , GID_SAMNMAX , 6 , 3 , 0 , GF_NEW_OPCODES | GF_AFTER_V6 | GF_USE_KEY } ,
/* Scumm Version 7 */
2002-02-23 23:23:28 +00:00
{ " ft " , " Full Throttle " , GID_FT , 7 , 3 , 0 , GF_NEW_OPCODES | GF_AFTER_V6 | GF_AFTER_V7 } ,
{ " dig " , " The Dig " , GID_DIG , 7 , 5 , 0 , GF_NEW_OPCODES | GF_AFTER_V6 | GF_AFTER_V7 } ,
2002-02-12 18:20:37 +00:00
/* Scumm Version 8 */
// {"curse", "The Curse of Monkey Island", GID_CMI, 8, 1, 0,},
2001-10-11 11:49:51 +00:00
{ NULL , NULL }
} ;
2001-10-23 19:51:50 +00:00
bool Scumm : : detectGame ( ) {
const VersionSettings * gnl = version_settings ;
_gameId = 0 ;
_gameText = NULL ;
2001-10-11 11:49:51 +00:00
do {
2001-10-23 19:51:50 +00:00
if ( ! scumm_stricmp ( _exe_name , gnl - > filename ) ) {
_gameId = gnl - > id ;
2001-11-26 19:57:57 +00:00
// _majorScummVersion = gnl->major;
// _middleScummVersion = gnl->middle;
// _minorScummVersion = gnl->minor;
_features = gnl - > features ;
2001-10-23 19:51:50 +00:00
_gameText = gnl - > gamename ;
2001-11-06 20:18:26 +00:00
debug ( 1 , " Detected game '%s', version %d.%d.%d " ,
gnl - > gamename , gnl - > major , gnl - > middle , gnl - > minor ) ;
2001-10-23 19:51:50 +00:00
return true ;
}
2001-10-11 11:49:51 +00:00
} while ( ( + + gnl ) - > filename ) ;
2001-10-23 19:51:50 +00:00
2001-11-06 20:18:26 +00:00
debug ( 1 , " Failed game detection " ) ;
2001-10-23 19:51:50 +00:00
return true ;
}
char * Scumm : : getGameName ( ) {
if ( _gameText = = NULL ) {
char buf [ 256 ] ;
sprintf ( buf , " Unknown game: \" %s \" " , _exe_name ) ;
return strdup ( buf ) ;
}
return strdup ( _gameText ) ;
2001-10-11 11:49:51 +00:00
}
2001-10-09 19:02:28 +00:00
2001-10-09 14:30:12 +00:00
void Scumm : : startScene ( int room , Actor * a , int objectNr ) {
2001-11-12 20:50:36 +00:00
int i , where ;
2001-10-09 14:30:12 +00:00
Actor * at ;
2001-10-16 10:01:48 +00:00
CHECK_HEAP
2001-10-09 14:30:12 +00:00
2001-11-05 19:21:49 +00:00
debug ( 1 , " Loading room %d " , room ) ;
2001-10-09 14:30:12 +00:00
clearMsgQueue ( ) ;
unkVirtScreen4 ( _switchRoomEffect2 ) ;
_newEffect = _switchRoomEffect ;
if ( _currentScript ! = 0xFF ) {
2001-11-12 20:50:36 +00:00
if ( vm . slot [ _currentScript ] . where = = WIO_ROOM | |
vm . slot [ _currentScript ] . where = = WIO_FLOBJECT ) {
2001-10-09 14:30:12 +00:00
if ( vm . slot [ _currentScript ] . cutsceneOverride ! = 0 )
error ( " Object %d stopped with active cutscene/override in exit " , vm . slot [ _currentScript ] . number ) ;
_currentScript = 0xFF ;
2001-11-12 20:50:36 +00:00
} else if ( vm . slot [ _currentScript ] . where = = WIO_LOCAL ) {
2001-10-09 14:30:12 +00:00
if ( vm . slot [ _currentScript ] . cutsceneOverride ! = 0 )
error ( " Script %d stopped with active cutscene/override in exit " , vm . slot [ _currentScript ] . number ) ;
_currentScript = 0xFF ;
}
}
2001-10-16 10:01:48 +00:00
_vars [ VAR_NEW_ROOM ] = room ;
2001-10-09 14:30:12 +00:00
runExitScript ( ) ;
killScriptsAndResources ( ) ;
2001-12-27 17:51:58 +00:00
clearEnqueue ( ) ;
2001-10-09 14:30:12 +00:00
stopCycle ( 0 ) ;
2001-12-27 17:51:58 +00:00
2001-11-10 19:12:32 +00:00
for ( i = 1 , at = getFirstActor ( ) ; + + at , i < NUM_ACTORS ; i + + ) {
2001-10-09 14:30:12 +00:00
if ( at - > visible )
hideActor ( at ) ;
}
2001-12-27 17:51:58 +00:00
if ( ! ( _features & GF_AFTER_V7 ) ) {
for ( i = 0 ; i < 0x100 ; i + + )
_shadowPalette [ i ] = i ;
}
2001-10-09 14:30:12 +00:00
clearDrawObjectQueue ( ) ;
2001-10-16 10:01:48 +00:00
_vars [ VAR_ROOM ] = room ;
2001-10-09 14:30:12 +00:00
_fullRedraw = 1 ;
_roomResource = _currentRoom = 0xFF ;
2001-11-05 19:21:49 +00:00
increaseResourceCounter ( ) ;
2001-10-09 14:30:12 +00:00
_currentRoom = room ;
2001-10-16 10:01:48 +00:00
_vars [ VAR_ROOM ] = room ;
2001-10-09 14:30:12 +00:00
if ( room > = 0x80 )
_roomResource = _resourceMapper [ room & 0x7F ] ;
else
_roomResource = room ;
2001-10-16 10:01:48 +00:00
_vars [ VAR_ROOM_RESOURCE ] = _roomResource ;
2001-10-09 14:30:12 +00:00
if ( room ! = 0 )
ensureResourceLoaded ( 1 , room ) ;
if ( _currentRoom = = 0 ) {
_ENCD_offs = _EXCD_offs = 0 ;
_numObjectsInRoom = 0 ;
return ;
}
initRoomSubBlocks ( ) ;
2002-02-12 18:20:37 +00:00
if ( _features & GF_SMALL_HEADER )
loadRoomObjectsSmall ( ) ;
else
loadRoomObjects ( ) ;
2001-10-09 14:30:12 +00:00
2001-12-27 17:51:58 +00:00
# if !defined(FULL_THROTTLE)
2001-11-14 20:09:39 +00:00
camera . _mode = CM_NORMAL ;
2001-12-27 17:51:58 +00:00
camera . _cur . x = camera . _dest . x = 160 ;
# endif
2001-10-26 17:34:50 +00:00
2001-11-26 19:57:57 +00:00
if ( _features & GF_AFTER_V6 ) {
2001-12-27 17:51:58 +00:00
_vars [ VAR_V6_SCREEN_WIDTH ] = _scrWidth ;
2001-10-26 17:34:50 +00:00
_vars [ VAR_V6_SCREEN_HEIGHT ] = _scrHeight ;
}
2001-12-27 17:51:58 +00:00
# if defined(FULL_THROTTLE)
_vars [ VAR_CAMERA_MIN_X ] = 160 ;
_vars [ VAR_CAMERA_MAX_X ] = _scrWidth - 160 ;
_vars [ VAR_CAMERA_MIN_Y ] = 100 ;
_vars [ VAR_CAMERA_MAX_Y ] = _scrHeight - 100 ;
setCameraAt ( 160 , 100 ) ;
# else
_vars [ VAR_CAMERA_MAX_X ] = _scrWidth - 160 ;
_vars [ VAR_CAMERA_MIN_X ] = 160 ;
# endif
2001-10-09 14:30:12 +00:00
if ( _roomResource = = 0 )
return ;
2001-11-26 19:57:57 +00:00
memset ( gfxUsageBits , 0 , sizeof ( gfxUsageBits ) ) ;
2001-10-09 14:30:12 +00:00
if ( a ) {
2001-11-12 20:50:36 +00:00
where = whereIsObject ( objectNr ) ;
if ( where ! = WIO_ROOM & & where ! = WIO_FLOBJECT )
error ( " startScene: Object %d is not in room %d " , objectNr , _currentRoom ) ;
2001-10-09 14:30:12 +00:00
getObjectXYPos ( objectNr ) ;
putActor ( a , _xPos , _yPos , _currentRoom ) ;
2001-11-26 19:57:57 +00:00
fixActorDirection ( a , _dir + 180 ) ;
2001-10-09 14:30:12 +00:00
a - > moving = 0 ;
}
showActors ( ) ;
2001-10-26 17:34:50 +00:00
_egoPositioned = false ;
runEntryScript ( ) ;
2001-12-27 17:51:58 +00:00
# if !defined(FULL_THROTTLE)
2001-10-26 17:34:50 +00:00
if ( a & & ! _egoPositioned ) {
2001-10-09 14:30:12 +00:00
getObjectXYPos ( objectNr ) ;
putActor ( a , _xPos , _yPos , _currentRoom ) ;
a - > moving = 0 ;
}
2001-12-27 17:51:58 +00:00
# else
if ( camera . _follows ) {
Actor * a = derefActorSafe ( camera . _follows , " startScene: follows " ) ;
setCameraAt ( a - > x , a - > y ) ;
}
# endif
2001-10-09 14:30:12 +00:00
2001-10-26 17:34:50 +00:00
_doEffect = true ;
2001-10-09 14:30:12 +00:00
2001-10-16 10:01:48 +00:00
CHECK_HEAP
2001-10-09 14:30:12 +00:00
}
void Scumm : : initRoomSubBlocks ( ) {
int i , offs ;
byte * ptr ;
2001-11-26 19:57:57 +00:00
byte * roomptr , * searchptr ;
2001-12-27 17:51:58 +00:00
RoomHeader * rmhd ;
2001-10-09 14:30:12 +00:00
_ENCD_offs = 0 ;
_EXCD_offs = 0 ;
2001-10-16 10:01:48 +00:00
_CLUT_offs = 0 ;
_PALS_offs = 0 ;
2001-10-09 14:30:12 +00:00
2001-11-05 19:21:49 +00:00
nukeResource ( rtMatrix , 1 ) ;
nukeResource ( rtMatrix , 2 ) ;
2001-10-09 14:30:12 +00:00
for ( i = 1 ; i < _maxScaleTable ; i + + )
2001-11-05 19:21:49 +00:00
nukeResource ( rtScaleTable , i ) ;
2001-10-09 14:30:12 +00:00
2001-11-05 19:21:49 +00:00
roomptr = getResourceAddress ( rtRoom , _roomResource ) ;
2001-10-09 14:30:12 +00:00
2001-12-27 17:51:58 +00:00
rmhd = ( RoomHeader * ) findResourceData ( MKID ( ' RMHD ' ) , roomptr ) ;
_scrWidth = READ_LE_UINT16 ( & rmhd - > width ) ;
_scrHeight = READ_LE_UINT16 ( & rmhd - > height ) ;
2001-10-09 14:30:12 +00:00
2002-02-12 18:20:37 +00:00
if ( _features & GF_SMALL_HEADER )
_IM00_offs = findResourceData ( MKID ( ' IM00 ' ) , roomptr ) - roomptr ;
else
_IM00_offs = findResource ( MKID ( ' IM00 ' ) , findResource ( MKID ( ' RMIM ' ) , roomptr ) ) - roomptr ;
2001-10-09 14:30:12 +00:00
2001-12-27 17:51:58 +00:00
ptr = findResourceData ( MKID ( ' EXCD ' ) , roomptr ) ;
2001-10-09 14:30:12 +00:00
if ( ptr ) {
_EXCD_offs = ptr - roomptr ;
# ifdef DUMP_SCRIPTS
2001-12-27 17:51:58 +00:00
dumpResource ( " exit- " , _roomResource , ptr - 8 ) ;
2001-10-09 14:30:12 +00:00
# endif
}
2001-12-27 17:51:58 +00:00
ptr = findResourceData ( MKID ( ' ENCD ' ) , roomptr ) ;
2001-10-09 14:30:12 +00:00
if ( ptr ) {
_ENCD_offs = ptr - roomptr ;
# ifdef DUMP_SCRIPTS
2001-12-27 17:51:58 +00:00
dumpResource ( " entry- " , _roomResource , ptr - 8 ) ;
2001-10-09 14:30:12 +00:00
# endif
}
2002-02-12 21:28:07 +00:00
if ( _features & GF_SMALL_HEADER ) {
ptr = findResourceData ( MKID ( ' BOXD ' ) , roomptr ) ;
if ( ptr ) {
byte numOfBoxes = * ( ptr ) ;
int size = numOfBoxes * SIZEOF_BOX + 1 ;
createResource ( rtMatrix , 2 , size ) ;
memcpy ( getResourceAddress ( rtMatrix , 2 ) , ptr , size ) ;
ptr + = size ;
size = getResourceDataSize ( ptr - size - 6 ) - size ;
2002-02-25 17:29:51 +00:00
if ( _features & GF_OLD256 ) { // FIXME: Total hack.
createBoxMatrix ( ) ; // This function shouldn't
} else if ( size > = 0 ) { // do this :)
2002-02-22 16:59:24 +00:00
createResource ( rtMatrix , 1 , size ) ;
memcpy ( getResourceAddress ( rtMatrix , 1 ) , ptr , size ) ;
}
2002-02-25 17:29:51 +00:00
2002-02-12 21:28:07 +00:00
}
} else {
ptr = findResourceData ( MKID ( ' BOXD ' ) , roomptr ) ;
if ( ptr ) {
int size = getResourceDataSize ( ptr ) ;
createResource ( rtMatrix , 2 , size ) ;
roomptr = getResourceAddress ( rtRoom , _roomResource ) ;
ptr = findResourceData ( MKID ( ' BOXD ' ) , roomptr ) ;
memcpy ( getResourceAddress ( rtMatrix , 2 ) , ptr , size ) ;
}
ptr = findResourceData ( MKID ( ' BOXM ' ) , roomptr ) ;
if ( ptr ) {
int size = getResourceDataSize ( ptr ) ;
createResource ( rtMatrix , 1 , size ) ;
roomptr = getResourceAddress ( rtRoom , _roomResource ) ;
ptr = findResourceData ( MKID ( ' BOXM ' ) , roomptr ) ;
memcpy ( getResourceAddress ( rtMatrix , 1 ) , ptr , size ) ;
}
}
2001-10-09 14:30:12 +00:00
2001-12-27 17:51:58 +00:00
ptr = findResourceData ( MKID ( ' SCAL ' ) , roomptr ) ;
2001-10-09 14:30:12 +00:00
if ( ptr ) {
offs = ptr - roomptr ;
for ( i = 1 ; i < _maxScaleTable ; i + + , offs + = 8 ) {
2001-12-27 17:51:58 +00:00
int a = READ_LE_UINT16 ( roomptr + offs ) ;
int b = READ_LE_UINT16 ( roomptr + offs + 2 ) ;
int c = READ_LE_UINT16 ( roomptr + offs + 4 ) ;
int d = READ_LE_UINT16 ( roomptr + offs + 6 ) ;
2001-10-09 14:30:12 +00:00
if ( a | | b | | c | | d ) {
setScaleItem ( i , b , a , d , c ) ;
2001-11-05 19:21:49 +00:00
roomptr = getResourceAddress ( rtRoom , _roomResource ) ;
2001-10-09 14:30:12 +00:00
}
}
}
2001-11-26 19:57:57 +00:00
memset ( _localScriptList , 0 , sizeof ( _localScriptList ) ) ;
searchptr = roomptr = getResourceAddress ( rtRoom , _roomResource ) ;
2002-02-12 21:28:07 +00:00
if ( _features & GF_SMALL_HEADER ) {
while ( ( ptr = findResourceSmall ( MKID ( ' LSCR ' ) , searchptr ) ) ! = NULL ) {
int id ;
ptr + = _resourceHeaderSize ; /* skip tag & size */
# ifdef DUMP_SCRIPTS
do {
char buf [ 32 ] ;
sprintf ( buf , " room-%d- " , _roomResource ) ;
dumpResource ( buf , id , ptr - 6 ) ;
} while ( 0 ) ;
# endif
id = ptr [ 0 ] ;
_localScriptList [ id - _numGlobalScripts ] = ptr + 1 - roomptr ;
searchptr = NULL ;
}
} else {
while ( ( ptr = findResource ( MKID ( ' LSCR ' ) , searchptr ) ) ! = NULL ) {
int id ;
2001-12-27 17:51:58 +00:00
2002-02-12 21:28:07 +00:00
ptr + = _resourceHeaderSize ; /* skip tag & size */
2001-11-26 19:57:57 +00:00
# ifdef FULL_THROTTLE
2002-02-12 21:28:07 +00:00
id = READ_LE_UINT16 ( ptr ) ;
checkRange ( 2050 , 2000 , id , " Invalid local script %d " ) ;
_localScriptList [ id - _numGlobalScripts ] = ptr + 2 - roomptr ;
2001-11-26 19:57:57 +00:00
# else
2002-02-12 21:28:07 +00:00
id = ptr [ 0 ] ;
_localScriptList [ id - _numGlobalScripts ] = ptr + 1 - roomptr ;
2001-11-26 19:57:57 +00:00
# endif
2001-10-09 14:30:12 +00:00
# ifdef DUMP_SCRIPTS
2002-02-12 21:28:07 +00:00
do {
char buf [ 32 ] ;
sprintf ( buf , " room-%d- " , _roomResource ) ;
dumpResource ( buf , id , ptr - 8 ) ;
} while ( 0 ) ;
2001-10-09 14:30:12 +00:00
# endif
2002-02-12 21:28:07 +00:00
searchptr = NULL ;
}
}
if ( _features & GF_SMALL_HEADER )
ptr = findResourceSmall ( MKID ( ' EPAL ' ) , roomptr ) ;
else
ptr = findResource ( MKID ( ' EPAL ' ) , roomptr ) ;
2001-10-09 14:30:12 +00:00
if ( ptr )
_EPAL_offs = ptr - roomptr ;
2002-02-12 21:28:07 +00:00
if ( _features & GF_SMALL_HEADER )
ptr = findResourceSmall ( MKID ( ' CLUT ' ) , roomptr ) ;
else
ptr = findResourceData ( MKID ( ' CLUT ' ) , roomptr ) ;
2001-10-16 10:01:48 +00:00
if ( ptr ) {
_CLUT_offs = ptr - roomptr ;
setPaletteFromRes ( ) ;
}
2001-10-09 14:30:12 +00:00
2001-11-26 19:57:57 +00:00
if ( _features & GF_AFTER_V6 ) {
ptr = findResource ( MKID ( ' PALS ' ) , roomptr ) ;
2001-10-23 19:51:50 +00:00
if ( ptr ) {
_PALS_offs = ptr - roomptr ;
setPalette ( 0 ) ;
}
2001-10-16 10:01:48 +00:00
}
2002-02-12 18:20:37 +00:00
if ( _features & GF_SMALL_HEADER )
ptr = findResourceData ( MKID ( ' CYCL ' ) , roomptr ) ;
else
ptr = findResourceData ( MKID ( ' CYCL ' ) , roomptr ) ;
if ( ptr )
initCycl ( findResourceData ( MKID ( ' CYCL ' ) , roomptr ) ) ;
2001-10-09 14:30:12 +00:00
2001-12-27 17:51:58 +00:00
ptr = findResourceData ( MKID ( ' TRNS ' ) , roomptr ) ;
2001-10-09 14:30:12 +00:00
if ( ptr )
2001-12-27 17:51:58 +00:00
gdi . _transparency = ptr [ 0 ] ;
2001-10-09 14:30:12 +00:00
else
2001-10-26 17:34:50 +00:00
gdi . _transparency = 255 ;
2001-10-09 14:30:12 +00:00
initBGBuffers ( ) ;
2001-11-26 19:57:57 +00:00
memset ( _extraBoxFlags , 0 , sizeof ( _extraBoxFlags ) ) ;
2001-10-09 14:30:12 +00:00
}
void Scumm : : setScaleItem ( int slot , int a , int b , int c , int d ) {
byte * ptr ;
int cur , amounttoadd , i , tmp ;
2001-11-05 19:21:49 +00:00
ptr = createResource ( rtScaleTable , slot , 200 ) ;
2001-10-09 14:30:12 +00:00
if ( a = = c )
return ;
cur = ( b - d ) * a ;
amounttoadd = d - b ;
for ( i = 200 ; i > 0 ; i - - ) {
tmp = cur / ( c - a ) + b ;
if ( tmp < 1 ) tmp = 1 ;
if ( tmp > 255 ) tmp = 255 ;
* ptr + + = tmp ;
cur + = amounttoadd ;
}
}
void Scumm : : dumpResource ( char * tag , int index , byte * ptr ) {
char buf [ 256 ] ;
FILE * out ;
2001-10-10 16:29:59 +00:00
2002-02-12 18:20:37 +00:00
uint32 size ;
if ( _features & GF_SMALL_HEADER )
size = READ_LE_UINT32 ( ptr ) ;
else
size = READ_BE_UINT32_UNALIGNED ( ptr + 4 ) ;
2001-10-09 14:30:12 +00:00
2002-03-03 22:14:47 +00:00
sprintf ( buf , " dumps/%s%d.dmp " , tag , index ) ;
2001-10-09 14:30:12 +00:00
out = fopen ( buf , " rb " ) ;
if ( ! out ) {
out = fopen ( buf , " wb " ) ;
if ( ! out )
return ;
fwrite ( ptr , size , 1 , out ) ;
}
fclose ( out ) ;
}
void Scumm : : clear_fullRedraw ( ) {
_fullRedraw = 0 ;
}
void Scumm : : clearClickedStatus ( ) {
checkKeyHit ( ) ;
_mouseButStat = 0 ;
_leftBtnPressed = 0 ;
_rightBtnPressed = 0 ;
}
int Scumm : : checkKeyHit ( ) {
int a = _keyPressed ;
_keyPressed = 0 ;
return a ;
}
void Scumm : : unkRoomFunc3 ( int a , int b , int c , int d , int e ) {
warning ( " stub unkRoomFunc3(%d,%d,%d,%d,%d) " , a , b , c , d , e ) ;
}
void Scumm : : unkRoomFunc4 ( int a , int b , int c , int d , int e ) {
/* TODO: implement this */
warning ( " unkRoomFunc4: not implemented " ) ;
}
2001-11-14 18:40:39 +00:00
void Scumm : : pauseGame ( bool user ) {
( ( Gui * ) _gui ) - > pause ( ) ;
2001-10-09 14:30:12 +00:00
}
void Scumm : : shutDown ( int i ) {
/* TODO: implement this */
warning ( " shutDown: not implemented " ) ;
}
void Scumm : : processKbd ( ) {
getKeyInput ( 0 ) ;
_virtual_mouse_x = mouse . x + virtscr [ 0 ] . xstart ;
2002-02-22 16:06:09 +00:00
_virtual_mouse_y = mouse . y ;
if ( ! ( _features & GF_OLD256 ) )
_virtual_mouse_y + = virtscr [ 0 ] . topline ;
else
_virtual_mouse_y - = 16 ;
2001-10-09 14:30:12 +00:00
if ( _virtual_mouse_y < 0 )
_virtual_mouse_y = - 1 ;
2002-02-22 16:06:09 +00:00
if ( _features & GF_OLD256 ) {
if ( _virtual_mouse_y > = virtscr [ 0 ] . height + virtscr [ 0 ] . topline )
_virtual_mouse_y = - 1 ;
} else {
if ( _virtual_mouse_y > = virtscr [ 0 ] . height )
_virtual_mouse_y = - 1 ;
}
2001-10-09 14:30:12 +00:00
if ( ! _lastKeyHit )
return ;
2001-10-16 10:01:48 +00:00
if ( _lastKeyHit = = _vars [ VAR_RESTART_KEY ] ) {
2001-10-09 14:30:12 +00:00
warning ( " Restart not implemented " ) ;
2001-11-14 18:40:39 +00:00
// pauseGame(true);
2001-10-09 14:30:12 +00:00
return ;
}
2001-10-16 10:01:48 +00:00
if ( _lastKeyHit = = _vars [ VAR_PAUSE_KEY ] ) {
2001-11-14 18:40:39 +00:00
pauseGame ( true ) ;
2001-10-09 14:30:12 +00:00
/* pause */
return ;
}
2001-10-16 10:01:48 +00:00
if ( _lastKeyHit = = _vars [ VAR_CUTSCENEEXIT_KEY ] ) {
2001-11-09 18:54:15 +00:00
exitCutscene ( ) ;
} else if ( _lastKeyHit = = _vars [ VAR_SAVELOADDIALOG_KEY ] ) {
( ( Gui * ) _gui ) - > saveLoadDialog ( ) ;
} else if ( _lastKeyHit = = _vars [ VAR_TALKSTOP_KEY ] ) {
2001-10-09 14:30:12 +00:00
_talkDelay = 0 ;
2001-11-14 18:40:39 +00:00
if ( _sfxMode = = 2 )
stopTalk ( ) ;
2001-10-09 14:30:12 +00:00
return ;
}
_mouseButStat = _lastKeyHit ;
}
int Scumm : : getKeyInput ( int a ) {
_mouseButStat = 0 ;
_lastKeyHit = checkKeyHit ( ) ;
if ( a = = 0 )
convertKeysToClicks ( ) ;
if ( mouse . x < 0 ) mouse . x = 0 ;
if ( mouse . x > 319 ) mouse . x = 319 ;
if ( mouse . y < 0 ) mouse . y = 0 ;
if ( mouse . y > 199 ) mouse . y = 199 ;
2001-12-27 17:51:58 +00:00
if ( _leftBtnPressed & msClicked & & _rightBtnPressed & msClicked ) {
2001-10-09 14:30:12 +00:00
_mouseButStat = 0 ;
2001-10-16 10:01:48 +00:00
_lastKeyHit = _vars [ VAR_CUTSCENEEXIT_KEY ] ;
2001-12-27 17:51:58 +00:00
} else if ( _leftBtnPressed & msClicked ) {
2001-11-14 20:09:39 +00:00
_mouseButStat = MBS_LEFT_CLICK ;
2001-12-27 17:51:58 +00:00
} else if ( _rightBtnPressed & msClicked ) {
2001-11-14 20:09:39 +00:00
_mouseButStat = MBS_RIGHT_CLICK ;
2001-10-09 14:30:12 +00:00
}
2001-12-27 17:51:58 +00:00
# if defined(FULL_THROTTLE)
// _vars[VAR_LEFTBTN_DOWN] = (_leftBtnPressed&msClicked) != 0;
_vars [ VAR_LEFTBTN_HOLD ] = ( _leftBtnPressed & msDown ) ! = 0 ;
// _vars[VAR_RIGHTBTN_DOWN] = (_rightBtnPressed&msClicked) != 0;
_vars [ VAR_RIGHTBTN_HOLD ] = ( _rightBtnPressed & msDown ) ! = 0 ;
# endif
_leftBtnPressed & = ~ msClicked ;
_rightBtnPressed & = ~ msClicked ;
2001-10-09 14:30:12 +00:00
return _lastKeyHit ;
}
void Scumm : : convertKeysToClicks ( ) {
if ( _lastKeyHit & & _cursorState > 0 ) {
if ( _lastKeyHit = = 9 ) {
2001-11-14 20:09:39 +00:00
_mouseButStat = MBS_RIGHT_CLICK ;
2001-10-09 14:30:12 +00:00
} else if ( _lastKeyHit = = 13 ) {
2001-11-14 20:09:39 +00:00
_mouseButStat = MBS_LEFT_CLICK ;
2001-10-09 14:30:12 +00:00
} else
return ;
_lastKeyHit = 0 ;
}
}
Actor * Scumm : : derefActorSafe ( int id , const char * errmsg ) {
2002-03-05 09:58:12 +00:00
if ( id < 1 | | id > = NUM_ACTORS ) {
warning ( " Invalid actor %d in %s (script %d) - This is potentially a BIG problem. " , id , errmsg , vm . slot [ _curExecScript ] . number ) ;
return NULL ;
}
2001-10-09 14:30:12 +00:00
return derefActor ( id ) ;
}
2001-11-06 20:00:47 +00:00
void Scumm : : makeCursorColorTransparent ( int a ) {
int i , size ;
size = _cursorWidth * _cursorHeight ;
2001-10-16 10:01:48 +00:00
2001-11-06 20:00:47 +00:00
for ( i = 0 ; i < size ; i + + )
if ( _grabbedCursor [ i ] = = ( byte ) a )
_grabbedCursor [ i ] = 0xFF ;
2001-10-16 10:01:48 +00:00
}
void Scumm : : setStringVars ( int slot ) {
2001-10-26 17:34:50 +00:00
StringTab * st = & string [ slot ] ;
st - > xpos = st - > t_xpos ;
st - > ypos = st - > t_ypos ;
st - > center = st - > t_center ;
st - > overhead = st - > t_overhead ;
2001-11-05 19:21:49 +00:00
st - > no_talk_anim = st - > t_no_talk_anim ;
2001-10-26 17:34:50 +00:00
st - > right = st - > t_right ;
st - > color = st - > t_color ;
st - > charset = st - > t_charset ;
2001-10-16 10:01:48 +00:00
}
void Scumm : : unkMiscOp9 ( ) {
warning ( " stub unkMiscOp9() " ) ;
}
void Scumm : : startManiac ( ) {
warning ( " stub startManiac() " ) ;
}
2001-11-05 19:21:49 +00:00
void Scumm : : destroy ( ) {
freeResources ( ) ;
2001-11-26 19:57:57 +00:00
free ( _objectStateTable ) ;
free ( _objectRoomTable ) ;
free ( _objectOwnerTable ) ;
2001-11-05 19:21:49 +00:00
free ( _inventory ) ;
free ( _arrays ) ;
free ( _verbs ) ;
free ( _objs ) ;
free ( _vars ) ;
free ( _bitVars ) ;
free ( _newNames ) ;
free ( _classData ) ;
}
2001-11-26 19:57:57 +00:00
int Scumm : : newDirToOldDir ( int dir ) {
if ( dir > = 71 & & dir < = 109 )
return 1 ;
if ( dir > = 109 & & dir < = 251 )
return 2 ;
if ( dir > = 251 & & dir < = 289 )
return 0 ;
return 3 ;
}
const int new_dir_table [ 4 ] = {
270 ,
90 ,
180 ,
0 ,
} ;
int Scumm : : oldDirToNewDir ( int dir ) {
return new_dir_table [ dir ] ;
}
2001-12-27 17:51:58 +00:00
const uint16 many_direction_tab [ 18 ] = {
71 , 109 , 251 , 530 ,
0 ,
0 ,
0 ,
0 ,
22 , 72 , 107 ,
157 ,
202 ,
252 ,
287 ,
337
} ;
int Scumm : : numSimpleDirDirections ( int dirType ) {
return dirType ? 8 : 4 ;
}
/* Convert an angle to a simple direction */
int Scumm : : toSimpleDir ( int dirType , int dir ) {
int num = dirType ? 8 : 4 , i ;
const uint16 * dirtab = & many_direction_tab [ dirType * 8 ] ;
for ( i = 1 ; i < num ; i + + , dirtab + + ) {
if ( dir > = dirtab [ 0 ] & & dir < = dirtab [ 1 ] )
return i ;
}
2001-11-26 19:57:57 +00:00
return 0 ;
2001-12-27 17:51:58 +00:00
2001-11-26 19:57:57 +00:00
}
2001-12-27 17:51:58 +00:00
/* Convert a simple direction to an angle */
int Scumm : : fromSimpleDir ( int dirType , int dir ) {
if ( ! dirType ) dir + = dir ;
return dir * 45 ;
2001-11-26 19:57:57 +00:00
}
int Scumm : : normalizeAngle ( int angle ) {
return ( angle + 360 ) % 360 ;
}
2001-10-16 10:01:48 +00:00
2001-10-09 14:30:12 +00:00
extern Scumm scumm ;
void NORETURN CDECL error ( const char * s , . . . ) {
char buf [ 1024 ] ;
va_list va ;
va_start ( va , s ) ;
vsprintf ( buf , s , va ) ;
va_end ( va ) ;
if ( scumm . _currentScript ! = 0xFF ) {
2001-10-29 23:07:24 +00:00
ScriptSlot * ss = & scumm . vm . slot [ scumm . _currentScript ] ;
fprintf ( stderr , " Error(%d:%d:0x%X): %s! \n Press a key to quit. \n " ,
scumm . _roomResource ,
ss - > number ,
scumm . _scriptPointer - scumm . _scriptOrgPointer ,
buf ) ;
2001-10-09 14:30:12 +00:00
} else {
fprintf ( stderr , " Error: %s! \n Press a key to quit. \n " , buf ) ;
}
exit ( 1 ) ;
}
void CDECL warning ( const char * s , . . . ) {
char buf [ 1024 ] ;
va_list va ;
va_start ( va , s ) ;
vsprintf ( buf , s , va ) ;
va_end ( va ) ;
fprintf ( stderr , " WARNING: %s! \n " , buf ) ;
}
void CDECL debug ( int level , const char * s , . . . ) {
char buf [ 1024 ] ;
va_list va ;
if ( level > 5 )
return ;
va_start ( va , s ) ;
vsprintf ( buf , s , va ) ;
va_end ( va ) ;
printf ( " %s \n " , buf ) ;
fflush ( stdout ) ;
}
void checkHeap ( ) {
2001-10-16 12:20:22 +00:00
# if defined(WIN32)
2001-10-16 10:01:48 +00:00
if ( _heapchk ( ) ! = _HEAPOK ) {
error ( " Heap is invalid! " ) ;
}
2001-10-16 12:20:22 +00:00
# endif
2001-10-09 14:30:12 +00:00
}