2009-09-17 16:53:58 +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 .
2014-02-18 02:34:24 +01:00
*
2009-09-17 16:53:58 +00:00
* 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 .
2014-02-18 02:34:24 +01:00
*
2009-09-17 16:53:58 +00:00
* 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 "sci/sci.h"
2010-06-23 15:23:37 +00:00
# include "sci/engine/kernel.h"
2009-09-17 16:53:58 +00:00
# include "sci/engine/state.h"
2010-01-29 11:03:54 +00:00
# include "sci/engine/selector.h"
2009-09-17 16:53:58 +00:00
namespace Sci {
2010-02-02 22:50:32 +00:00
# if 1
# define FIND_SELECTOR(_slc_) _selectorCache._slc_ = findSelector(#_slc_)
# define FIND_SELECTOR2(_slc_, _slcstr_) _selectorCache._slc_ = findSelector(_slcstr_)
# else
// The defines below can be used to construct static selector tables for games which don't have
// a vocab.997 resource, by dumping the selector table from other similar versions or games
# define FIND_SELECTOR(_slc_) _selectorCache._slc_ = findSelector(#_slc_); \
2010-11-02 09:49:47 +00:00
debugN ( " \t { \" %s \" , %d }, \n " , # _slc_ , _selectorCache . _slc_ )
2010-02-02 22:50:32 +00:00
# define FIND_SELECTOR2(_slc_, _slcstr_) _selectorCache._slc_ = findSelector(_slcstr_); \
2010-11-02 09:49:47 +00:00
debugN ( " \t { \" %s \" , %d }, \n " , _slcstr_ , _selectorCache . _slc_ )
2010-02-02 22:50:32 +00:00
# endif
void Kernel : : mapSelectors ( ) {
// species
// superClass
2010-09-03 18:14:59 +00:00
FIND_SELECTOR2 ( _info_ , " -info- " ) ;
2010-02-02 22:50:32 +00:00
FIND_SELECTOR ( y ) ;
FIND_SELECTOR ( x ) ;
FIND_SELECTOR ( view ) ;
FIND_SELECTOR ( loop ) ;
FIND_SELECTOR ( cel ) ;
FIND_SELECTOR ( underBits ) ;
FIND_SELECTOR ( nsTop ) ;
FIND_SELECTOR ( nsLeft ) ;
FIND_SELECTOR ( nsBottom ) ;
FIND_SELECTOR ( lsTop ) ;
FIND_SELECTOR ( lsLeft ) ;
FIND_SELECTOR ( lsBottom ) ;
FIND_SELECTOR ( lsRight ) ;
FIND_SELECTOR ( nsRight ) ;
FIND_SELECTOR ( signal ) ;
FIND_SELECTOR ( illegalBits ) ;
FIND_SELECTOR ( brTop ) ;
FIND_SELECTOR ( brLeft ) ;
FIND_SELECTOR ( brBottom ) ;
FIND_SELECTOR ( brRight ) ;
// name
// key
// time
FIND_SELECTOR ( text ) ;
FIND_SELECTOR ( elements ) ;
// color
// back
FIND_SELECTOR ( mode ) ;
// style
FIND_SELECTOR ( state ) ;
FIND_SELECTOR ( font ) ;
FIND_SELECTOR ( type ) ;
// window
FIND_SELECTOR ( cursor ) ;
FIND_SELECTOR ( max ) ;
2010-08-29 15:13:25 +00:00
FIND_SELECTOR ( mark ) ;
FIND_SELECTOR ( sort ) ;
2010-02-02 22:50:32 +00:00
// who
FIND_SELECTOR ( message ) ;
// edit
FIND_SELECTOR ( play ) ;
FIND_SELECTOR ( number ) ;
FIND_SELECTOR ( handle ) ; // nodePtr
FIND_SELECTOR ( client ) ;
FIND_SELECTOR ( dx ) ;
FIND_SELECTOR ( dy ) ;
FIND_SELECTOR2 ( b_movCnt , " b-moveCnt " ) ;
FIND_SELECTOR2 ( b_i1 , " b-i1 " ) ;
FIND_SELECTOR2 ( b_i2 , " b-i2 " ) ;
FIND_SELECTOR2 ( b_di , " b-di " ) ;
FIND_SELECTOR2 ( b_xAxis , " b-xAxis " ) ;
FIND_SELECTOR2 ( b_incr , " b-incr " ) ;
FIND_SELECTOR ( xStep ) ;
FIND_SELECTOR ( yStep ) ;
2010-07-16 05:46:07 +00:00
FIND_SELECTOR ( xLast ) ;
FIND_SELECTOR ( yLast ) ;
2010-02-02 22:50:32 +00:00
FIND_SELECTOR ( moveSpeed ) ;
FIND_SELECTOR ( canBeHere ) ; // cantBeHere
FIND_SELECTOR ( heading ) ;
FIND_SELECTOR ( mover ) ;
FIND_SELECTOR ( doit ) ;
FIND_SELECTOR ( isBlocked ) ;
FIND_SELECTOR ( looper ) ;
FIND_SELECTOR ( priority ) ;
FIND_SELECTOR ( modifiers ) ;
FIND_SELECTOR ( replay ) ;
// setPri
// at
// next
// done
// width
FIND_SELECTOR ( wordFail ) ;
FIND_SELECTOR ( syntaxFail ) ;
// semanticFail
// pragmaFail
// said
FIND_SELECTOR ( claimed ) ;
// value
// save
// restore
// title
// button
// icon
// draw
FIND_SELECTOR2 ( delete_ , " delete " ) ;
FIND_SELECTOR ( z ) ;
// -----------------------------
FIND_SELECTOR ( size ) ;
FIND_SELECTOR ( moveDone ) ;
FIND_SELECTOR ( vol ) ;
FIND_SELECTOR ( pri ) ;
FIND_SELECTOR ( min ) ;
FIND_SELECTOR ( sec ) ;
FIND_SELECTOR ( frame ) ;
FIND_SELECTOR ( dataInc ) ;
FIND_SELECTOR ( palette ) ;
FIND_SELECTOR ( cantBeHere ) ;
FIND_SELECTOR ( nodePtr ) ;
FIND_SELECTOR ( flags ) ;
FIND_SELECTOR ( points ) ;
FIND_SELECTOR ( syncCue ) ;
FIND_SELECTOR ( syncTime ) ;
FIND_SELECTOR ( printLang ) ;
FIND_SELECTOR ( subtitleLang ) ;
FIND_SELECTOR ( parseLang ) ;
FIND_SELECTOR ( overlay ) ;
FIND_SELECTOR ( topString ) ;
FIND_SELECTOR ( scaleSignal ) ;
FIND_SELECTOR ( scaleX ) ;
FIND_SELECTOR ( scaleY ) ;
2010-06-23 12:58:14 +00:00
FIND_SELECTOR ( maxScale ) ;
2010-06-23 13:42:09 +00:00
FIND_SELECTOR ( vanishingX ) ;
FIND_SELECTOR ( vanishingY ) ;
2010-05-24 17:21:11 +00:00
FIND_SELECTOR ( iconIndex ) ;
2011-03-09 20:50:11 +01:00
FIND_SELECTOR ( select ) ;
2010-02-02 22:50:32 +00:00
# ifdef ENABLE_SCI32
FIND_SELECTOR ( data ) ;
FIND_SELECTOR ( picture ) ;
2011-10-11 01:24:28 +03:00
FIND_SELECTOR ( bitmap ) ;
2010-02-02 22:50:32 +00:00
FIND_SELECTOR ( plane ) ;
FIND_SELECTOR ( top ) ;
FIND_SELECTOR ( left ) ;
2010-02-04 16:06:56 +00:00
FIND_SELECTOR ( bottom ) ;
FIND_SELECTOR ( right ) ;
2010-02-04 12:01:19 +00:00
FIND_SELECTOR ( resY ) ;
FIND_SELECTOR ( resX ) ;
2010-02-03 01:36:53 +00:00
FIND_SELECTOR ( dimmed ) ;
FIND_SELECTOR ( fore ) ;
2010-02-04 17:55:23 +00:00
FIND_SELECTOR ( back ) ;
2011-10-28 21:52:17 +03:00
FIND_SELECTOR ( skip ) ;
2016-02-14 12:07:30 -06:00
FIND_SELECTOR ( borderColor ) ;
2016-03-05 23:56:38 -06:00
FIND_SELECTOR ( width ) ;
2010-07-22 10:24:08 +00:00
FIND_SELECTOR ( fixPriority ) ;
FIND_SELECTOR ( mirrored ) ;
2012-05-14 02:30:15 +03:00
FIND_SELECTOR ( visible ) ;
2010-07-24 17:43:56 +00:00
FIND_SELECTOR ( useInsetRect ) ;
FIND_SELECTOR ( inTop ) ;
FIND_SELECTOR ( inLeft ) ;
FIND_SELECTOR ( inBottom ) ;
FIND_SELECTOR ( inRight ) ;
2016-02-14 12:07:30 -06:00
FIND_SELECTOR ( textTop ) ;
FIND_SELECTOR ( textLeft ) ;
FIND_SELECTOR ( textBottom ) ;
FIND_SELECTOR ( textRight ) ;
2016-03-05 23:56:38 -06:00
FIND_SELECTOR ( title ) ;
FIND_SELECTOR ( titleFont ) ;
FIND_SELECTOR ( titleFore ) ;
FIND_SELECTOR ( titleBack ) ;
2016-01-18 00:12:47 -06:00
FIND_SELECTOR ( magnifier ) ;
2016-03-05 23:56:38 -06:00
FIND_SELECTOR ( frameOut ) ;
2016-02-21 17:21:48 +01:00
FIND_SELECTOR ( casts ) ;
2010-02-02 22:50:32 +00:00
# endif
}
2010-05-29 23:37:15 +00:00
reg_t readSelector ( SegManager * segMan , reg_t object , Selector selectorId ) {
2009-09-17 16:53:58 +00:00
ObjVarRef address ;
2010-05-29 23:37:15 +00:00
if ( lookupSelector ( segMan , object , selectorId , & address , NULL ) ! = kSelectorVariable )
2009-09-17 16:53:58 +00:00
return NULL_REG ;
else
return * address . getPointer ( segMan ) ;
}
2016-02-24 00:12:29 +01:00
# ifdef ENABLE_SCI32
2016-03-01 20:18:29 +01:00
void updateInfoFlagViewVisible ( Object * obj , int index ) {
2016-02-24 00:12:29 +01:00
// TODO: Make this correct for all SCI versions
// Selectors 26 through 44 are selectors for View script objects in SQ6
2016-03-01 20:18:29 +01:00
if ( index > = 26 & & index < = 44 & & getSciVersion ( ) > = SCI_VERSION_2 ) {
2016-02-24 00:12:29 +01:00
obj - > setInfoSelectorFlag ( kInfoFlagViewVisible ) ;
}
}
# endif
2010-05-29 23:37:15 +00:00
void writeSelector ( SegManager * segMan , reg_t object , Selector selectorId , reg_t value ) {
2009-09-17 16:53:58 +00:00
ObjVarRef address ;
2010-05-29 23:37:15 +00:00
if ( ( selectorId < 0 ) | | ( selectorId > ( int ) g_sci - > getKernel ( ) - > getSelectorNamesSize ( ) ) ) {
2016-09-07 21:09:31 -05:00
const SciCallOrigin origin = g_sci - > getEngineState ( ) - > getCurrentCallOrigin ( ) ;
2016-09-26 20:41:37 -05:00
error ( " Attempt to write to invalid selector %d. Address %04x:%04x, %s " , selectorId , PRINT_REG ( object ) , origin . toString ( ) . c_str ( ) ) ;
2009-09-17 16:53:58 +00:00
}
2016-09-07 21:09:31 -05:00
if ( lookupSelector ( segMan , object , selectorId , & address , NULL ) ! = kSelectorVariable ) {
const SciCallOrigin origin = g_sci - > getEngineState ( ) - > getCurrentCallOrigin ( ) ;
2016-09-26 20:41:37 -05:00
error ( " Selector '%s' of object could not be written to. Address %04x:%04x, %s " , g_sci - > getKernel ( ) - > getSelectorName ( selectorId ) . c_str ( ) , PRINT_REG ( object ) , origin . toString ( ) . c_str ( ) ) ;
2016-09-07 21:09:31 -05:00
} else {
2009-09-17 16:53:58 +00:00
* address . getPointer ( segMan ) = value ;
2016-01-18 00:12:47 -06:00
# ifdef ENABLE_SCI32
2016-02-24 00:12:29 +01:00
updateInfoFlagViewVisible ( segMan - > getObject ( object ) , selectorId ) ;
2016-01-18 00:12:47 -06:00
# endif
}
2009-09-17 16:53:58 +00:00
}
2011-06-20 00:59:48 +02:00
void invokeSelector ( EngineState * s , reg_t object , int selectorId ,
2010-01-29 11:03:54 +00:00
int k_argc , StackPtr k_argp , int argc , const reg_t * argv ) {
2009-09-17 16:53:58 +00:00
int i ;
int framesize = 2 + 1 * argc ;
int slc_type ;
StackPtr stackframe = k_argp + k_argc ;
2010-05-29 23:37:15 +00:00
stackframe [ 0 ] = make_reg ( 0 , selectorId ) ; // The selector we want to call
2009-09-17 16:53:58 +00:00
stackframe [ 1 ] = make_reg ( 0 , argc ) ; // Argument count
2010-06-10 13:43:38 +00:00
slc_type = lookupSelector ( s - > _segMan , object , selectorId , NULL , NULL ) ;
2009-09-17 16:53:58 +00:00
if ( slc_type = = kSelectorNone ) {
2016-09-07 21:09:31 -05:00
const SciCallOrigin origin = g_sci - > getEngineState ( ) - > getCurrentCallOrigin ( ) ;
2016-09-26 20:41:37 -05:00
error ( " invokeSelector: Selector '%s' could not be invoked. Address %04x:%04x, %s " , g_sci - > getKernel ( ) - > getSelectorName ( selectorId ) . c_str ( ) , PRINT_REG ( object ) , origin . toString ( ) . c_str ( ) ) ;
2009-09-17 16:53:58 +00:00
}
2009-12-26 17:10:43 +00:00
if ( slc_type = = kSelectorVariable ) {
2016-09-07 21:09:31 -05:00
const SciCallOrigin origin = g_sci - > getEngineState ( ) - > getCurrentCallOrigin ( ) ;
2016-09-26 20:41:37 -05:00
error ( " invokeSelector: Attempting to invoke variable selector %s. Address %04x:%04x, %s " , g_sci - > getKernel ( ) - > getSelectorName ( selectorId ) . c_str ( ) , PRINT_REG ( object ) , origin . toString ( ) . c_str ( ) ) ;
2009-12-26 17:10:43 +00:00
}
2009-09-17 16:53:58 +00:00
2010-01-28 20:29:45 +00:00
for ( i = 0 ; i < argc ; i + + )
stackframe [ 2 + i ] = argv [ i ] ; // Write each argument
2009-09-17 16:53:58 +00:00
ExecStack * xstack ;
// Now commit the actual function:
xstack = send_selector ( s , object , object , stackframe , framesize , stackframe ) ;
xstack - > sp + = argc + 2 ;
xstack - > fp + = argc + 2 ;
2010-07-20 23:15:07 +00:00
run_vm ( s ) ; // Start a new vm
2010-01-28 20:29:45 +00:00
}
2010-05-29 23:37:15 +00:00
SelectorType lookupSelector ( SegManager * segMan , reg_t obj_location , Selector selectorId , ObjVarRef * varp , reg_t * fptr ) {
2010-05-26 16:30:10 +00:00
const Object * obj = segMan - > getObject ( obj_location ) ;
2009-09-17 16:53:58 +00:00
int index ;
bool oldScriptHeader = ( getSciVersion ( ) = = SCI_VERSION_0_EARLY ) ;
// Early SCI versions used the LSB in the selector ID as a read/write
// toggle, meaning that we must remove it for selector lookup.
if ( oldScriptHeader )
2010-05-29 23:37:15 +00:00
selectorId & = ~ 1 ;
2009-09-17 16:53:58 +00:00
if ( ! obj ) {
2016-09-07 21:09:31 -05:00
const SciCallOrigin origin = g_sci - > getEngineState ( ) - > getCurrentCallOrigin ( ) ;
2016-09-26 20:41:37 -05:00
error ( " lookupSelector: Attempt to send to non-object or invalid script. Address %04x:%04x, %s " , PRINT_REG ( obj_location ) , origin . toString ( ) . c_str ( ) ) ;
2009-09-17 16:53:58 +00:00
}
2010-05-29 23:37:15 +00:00
index = obj - > locateVarSelector ( segMan , selectorId ) ;
2009-09-17 16:53:58 +00:00
if ( index > = 0 ) {
// Found it as a variable
if ( varp ) {
varp - > obj = obj_location ;
varp - > varindex = index ;
}
return kSelectorVariable ;
2009-10-10 15:58:51 +00:00
} else {
// Check if it's a method, with recursive lookup in superclasses
while ( obj ) {
2010-05-29 23:37:15 +00:00
index = obj - > funcSelectorPosition ( selectorId ) ;
2009-10-10 15:58:51 +00:00
if ( index > = 0 ) {
if ( fptr )
* fptr = obj - > getFunction ( index ) ;
return kSelectorMethod ;
} else {
obj = segMan - > getObject ( obj - > getSuperClassSelector ( ) ) ;
}
}
return kSelectorNone ;
2009-09-17 16:53:58 +00:00
}
2009-10-10 15:58:51 +00:00
2010-05-29 23:37:15 +00:00
// return _lookupSelector_function(segMan, obj, selectorId, fptr);
2009-09-17 16:53:58 +00:00
}
} // End of namespace Sci