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"
2016-11-27 10:53:06 -06:00
# include "sci/engine/features.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 ) ;
2016-11-27 10:53:06 -06:00
FIND_SELECTOR ( nsRight ) ;
2010-02-02 22:50:32 +00:00
FIND_SELECTOR ( lsTop ) ;
FIND_SELECTOR ( lsLeft ) ;
FIND_SELECTOR ( lsBottom ) ;
FIND_SELECTOR ( lsRight ) ;
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 ) ;
2017-02-04 12:10:36 -06:00
FIND_SELECTOR ( restore ) ;
2010-02-02 22:50:32 +00:00
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 ) ;
2017-10-09 01:58:16 +02:00
FIND_SELECTOR ( handsOff ) ;
FIND_SELECTOR ( setStep ) ;
FIND_SELECTOR ( setMotion ) ;
FIND_SELECTOR ( cycleSpeed ) ;
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 ) ;
2016-11-27 10:53:06 -06:00
FIND_SELECTOR ( seenRect ) ;
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 ) ;
SCI: Improve audio volume & settings sync code
This patch includes enhancements to the ScummVM integration with
SCI engine, with particular focus on SCI32 support.
1. Fixes audio volumes syncing erroneously to ScummVM in games
that modify the audio volume without user action (e.g. SCI1.1
talkies that reduce music volume during speech playback). Now,
volumes will only be synchronised when the user interacts with
the game's audio settings. This mechanism works by looking for
a known volume control object in the stack, and only syncing
when the control object is present. (Ports and planes were
researched and found unreliable.)
2. Fixes audio syncing in SCI32 games that do not set game
volumes through kDoSoundMasterVolume/kDoAudioVolume, like GK1,
GK2, Phant1, and Torin.
3. Fixes speech/subtitles syncing in SCI32 games that do not use
global 90, like LSL6hires.
4. Fixes in-game volume controls in SCI32 games reflecting
outdated audio volumes when a change is made during the game
from the ScummVM launcher.
5. Fixes SCI32 games that would restore volumes from save games
or reset volumes on startup, which caused game volumes to be
out-of-sync with ScummVM when started.
6. ScummVM integration code for audio sync has been abstracted
into a new GuestAdditions class. This keeps the ScummVM-
specific code all in one place, with only small hooks into the
engine code. ScummVM integrated save/load code should probably
also go here in the future.
Fixes Trac#9700.
2017-01-26 13:18:41 -06:00
FIND_SELECTOR ( setVol ) ;
FIND_SELECTOR ( reSyncVol ) ;
FIND_SELECTOR ( set ) ;
FIND_SELECTOR ( clear ) ;
FIND_SELECTOR ( curPos ) ;
FIND_SELECTOR ( update ) ;
FIND_SELECTOR ( show ) ;
FIND_SELECTOR ( position ) ;
FIND_SELECTOR ( musicVolume ) ;
FIND_SELECTOR ( soundVolume ) ;
FIND_SELECTOR ( initialOff ) ;
FIND_SELECTOR ( setPos ) ;
FIND_SELECTOR ( setSize ) ;
FIND_SELECTOR ( displayValue ) ;
2017-07-17 22:29:07 -05:00
FIND_SELECTOR2 ( new_ , " new " ) ;
2017-07-24 12:24:48 -05:00
FIND_SELECTOR ( mainCel ) ;
2017-07-27 20:30:01 -05:00
FIND_SELECTOR ( move ) ;
FIND_SELECTOR ( eachElementDo ) ;
FIND_SELECTOR ( physicalBar ) ;
2017-07-27 22:31:12 -05:00
FIND_SELECTOR ( init ) ;
FIND_SELECTOR ( scratch ) ;
2017-07-30 00:22:11 -05:00
FIND_SELECTOR ( num ) ;
FIND_SELECTOR ( reallyRestore ) ;
2017-09-14 20:42:42 -05:00
FIND_SELECTOR ( bookMark ) ;
2017-09-23 01:08:09 -05:00
FIND_SELECTOR ( fileNumber ) ;
FIND_SELECTOR ( description ) ;
2017-09-22 19:51:24 -05:00
FIND_SELECTOR ( dispose ) ;
2017-09-28 13:47:45 -05:00
FIND_SELECTOR ( masterVolume ) ;
FIND_SELECTOR ( setCel ) ;
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
SCI32: Fix mustSetViewVisible for SCI3
In SCI2/2.1, variable indexes are used along with a range encoded
in the interpreter executable to determine whether an object
variable is a view-related variable. Operands to aTop, sTop, ipToa,
dpToa, ipTos, and dpTos are byte offsets into an object, which
are divided by two to get the varindex to check against the
interpreter range.
In SCI3, objects in game scripts contain groups of 32 selectors,
and each group has a flag that says whether or not the selectors
in that group are view-related. Operands to aTop, sTop, ipToa,
dpToa, ipTos, and dpTos are selectors.
2017-04-01 22:01:22 -05:00
void updateInfoFlagViewVisible ( Object * obj , int index , bool fromPropertyOp ) {
if ( getSciVersion ( ) > = SCI_VERSION_2 & & obj - > mustSetViewVisible ( index , fromPropertyOp ) ) {
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-10-20 11:23:43 -05:00
}
* address . getPointer ( segMan ) = value ;
2016-01-18 00:12:47 -06:00
# ifdef ENABLE_SCI32
2016-10-20 11:23:43 -05:00
updateInfoFlagViewVisible ( segMan - > getObject ( object ) , address . varindex ) ;
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