2007-05-30 21:56:52 +00:00
|
|
|
/* ScummVM - Graphic Adventure Engine
|
2004-04-12 21:40:49 +00:00
|
|
|
*
|
2007-05-30 21:56:52 +00:00
|
|
|
* 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.
|
2004-04-12 21:40:49 +00:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
2008-01-05 12:45:14 +00:00
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2004-04-12 21:40:49 +00:00
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
2005-10-18 01:30:26 +00:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2004-04-12 21:40:49 +00:00
|
|
|
*
|
2006-02-11 12:44:16 +00:00
|
|
|
* $URL$
|
|
|
|
* $Id$
|
2004-04-12 21:40:49 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2004-05-01 14:05:10 +00:00
|
|
|
// Scripting module private header
|
2004-04-12 21:40:49 +00:00
|
|
|
|
|
|
|
#ifndef SAGA_SCRIPT_H
|
|
|
|
#define SAGA_SCRIPT_H
|
|
|
|
|
2006-03-29 15:59:37 +00:00
|
|
|
#include "common/endian.h"
|
|
|
|
|
2005-07-14 17:46:21 +00:00
|
|
|
#include "saga/font.h"
|
2004-04-12 21:40:49 +00:00
|
|
|
|
|
|
|
namespace Saga {
|
|
|
|
|
2005-04-22 01:38:27 +00:00
|
|
|
#define COMMON_BUFFER_SIZE 1024 // Why 1024?
|
2004-08-12 23:57:45 +00:00
|
|
|
|
2004-10-27 21:32:28 +00:00
|
|
|
#define SCRIPT_TBLENTRY_LEN 4
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2004-10-27 21:32:28 +00:00
|
|
|
#define SCRIPT_MAX 5000
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2005-07-21 01:33:28 +00:00
|
|
|
#define ITE_SCRIPT_FUNCTION_MAX 78
|
|
|
|
#define IHNM_SCRIPT_FUNCTION_MAX 105
|
2005-01-21 21:55:54 +00:00
|
|
|
|
|
|
|
enum AddressTypes {
|
|
|
|
kAddressCommon = 0, // offset from global variables
|
|
|
|
kAddressStatic = 1, // offset from global variables
|
|
|
|
kAddressModule = 2, // offset from start of module
|
|
|
|
kAddressStack = 3, // offset from stack
|
2005-01-21 23:16:38 +00:00
|
|
|
kAddressThread = 4 // offset from thread structure
|
2005-01-21 21:55:54 +00:00
|
|
|
/* kAddressId = 5, // offset from const id object
|
|
|
|
kAddressIdIndirect = 6, // offset from stack id object
|
|
|
|
kAddressIndex = 7 // index from id*/
|
|
|
|
};
|
2004-08-12 23:57:45 +00:00
|
|
|
|
2006-01-13 20:20:01 +00:00
|
|
|
enum VerbTypes {
|
|
|
|
kVerbNone,
|
|
|
|
kVerbWalkTo,
|
|
|
|
kVerbGive,
|
|
|
|
kVerbUse,
|
|
|
|
kVerbEnter,
|
|
|
|
kVerbLookAt,
|
|
|
|
kVerbPickUp,
|
|
|
|
kVerbOpen,
|
|
|
|
kVerbClose,
|
|
|
|
kVerbTalkTo,
|
|
|
|
kVerbWalkOnly,
|
|
|
|
kVerbLookOnly,
|
|
|
|
kVerbOptions
|
2004-08-12 23:57:45 +00:00
|
|
|
};
|
|
|
|
|
2004-10-27 02:27:54 +00:00
|
|
|
#define STHREAD_TIMESLICE 8
|
2004-08-12 23:57:45 +00:00
|
|
|
|
2005-01-21 21:55:54 +00:00
|
|
|
enum ThreadVarTypes {
|
|
|
|
kThreadVarObject = 0,
|
|
|
|
kThreadVarWithObject = 1,
|
|
|
|
kThreadVarAction = 2,
|
|
|
|
kThreadVarActor = 3,
|
|
|
|
|
|
|
|
kThreadVarMax = kThreadVarActor + 1
|
2004-10-09 07:39:46 +00:00
|
|
|
};
|
|
|
|
|
2004-12-21 06:49:07 +00:00
|
|
|
enum ThreadFlags {
|
2004-10-27 02:27:54 +00:00
|
|
|
kTFlagNone = 0,
|
|
|
|
kTFlagWaiting = 1, // wait for even denoted in waitType
|
|
|
|
kTFlagFinished = 2,
|
|
|
|
kTFlagAborted = 4,
|
2005-01-03 21:17:32 +00:00
|
|
|
kTFlagAsleep = kTFlagWaiting | kTFlagFinished | kTFlagAborted // Combination of all flags which can halt a thread
|
2004-10-27 02:27:54 +00:00
|
|
|
};
|
|
|
|
|
2004-12-21 06:49:07 +00:00
|
|
|
enum ThreadWaitTypes {
|
|
|
|
kWaitTypeNone = 0, // waiting for nothing
|
|
|
|
kWaitTypeDelay = 1, // waiting for a timer
|
|
|
|
kWaitTypeSpeech = 2, // waiting for speech to finish
|
|
|
|
kWaitTypeDialogEnd = 3, // waiting for my dialog to finish
|
|
|
|
kWaitTypeDialogBegin = 4, // waiting for other dialog to finish
|
|
|
|
kWaitTypeWalk = 5, // waiting to finish walking
|
|
|
|
kWaitTypeRequest = 6, // a request is up
|
2005-01-06 16:07:46 +00:00
|
|
|
kWaitTypePause = 7,
|
2005-06-19 14:06:20 +00:00
|
|
|
kWaitTypePlacard = 8,
|
2005-07-30 14:41:25 +00:00
|
|
|
kWaitTypeStatusTextInput = 9,
|
2007-06-17 01:00:06 +00:00
|
|
|
kWaitTypeWaitFrames = 10, // IHNM. waiting for a frame count
|
|
|
|
kWaitTypeWakeUp = 11 // IHNM. wait until get waken up
|
2004-12-21 06:49:07 +00:00
|
|
|
};
|
|
|
|
|
2004-12-22 21:04:50 +00:00
|
|
|
enum CycleFlags {
|
2005-01-17 20:17:06 +00:00
|
|
|
kCyclePong = 1 << 0,
|
|
|
|
kCycleOnce = 1 << 1,
|
|
|
|
kCycleRandom = 1 << 2,
|
|
|
|
kCycleReverse = 1 << 3
|
2004-12-22 21:04:50 +00:00
|
|
|
};
|
2004-12-24 20:44:39 +00:00
|
|
|
|
2004-12-29 21:49:25 +00:00
|
|
|
enum WalkFlags {
|
2005-01-17 20:17:06 +00:00
|
|
|
kWalkBackPedal = 1 << 0,
|
|
|
|
kWalkAsync = 1 << 1,
|
|
|
|
kWalkUseAngle = 1 << 2,
|
|
|
|
kWalkFace = 1 << 5
|
|
|
|
};
|
|
|
|
|
|
|
|
enum ReplyFlags {
|
|
|
|
kReplyOnce = 1 << 0,
|
|
|
|
kReplySummary = 1 << 1,
|
|
|
|
kReplyCondition = 1 << 2
|
2004-12-29 21:49:25 +00:00
|
|
|
};
|
|
|
|
|
2005-01-21 21:55:54 +00:00
|
|
|
struct EntryPoint {
|
|
|
|
uint16 nameOffset;
|
|
|
|
uint16 offset;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct VoiceLUT {
|
|
|
|
uint16 voicesCount;
|
|
|
|
uint16 *voices;
|
|
|
|
void freeMem() {
|
2005-08-09 16:01:04 +00:00
|
|
|
voicesCount = 0;
|
2005-01-21 21:55:54 +00:00
|
|
|
free(voices);
|
|
|
|
}
|
2005-08-09 16:01:04 +00:00
|
|
|
VoiceLUT() {
|
|
|
|
memset(this, 0, sizeof(*this));
|
|
|
|
}
|
2005-01-21 21:55:54 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct ModuleData {
|
|
|
|
bool loaded; // is it loaded or not?
|
|
|
|
int scriptResourceId;
|
|
|
|
int stringsResourceId;
|
|
|
|
int voicesResourceId;
|
|
|
|
|
|
|
|
byte *moduleBase; // all base module
|
|
|
|
uint16 moduleBaseSize; // base module size
|
|
|
|
uint16 staticSize; // size of static data
|
|
|
|
uint staticOffset; // offset of static data begining in _commonBuffer
|
|
|
|
|
|
|
|
uint16 entryPointsTableOffset; // offset of entrypoint table in moduleBase
|
|
|
|
uint16 entryPointsCount;
|
|
|
|
EntryPoint *entryPoints;
|
|
|
|
|
|
|
|
StringsTable strings;
|
|
|
|
VoiceLUT voiceLUT;
|
|
|
|
void freeMem() {
|
|
|
|
strings.freeMem();
|
|
|
|
voiceLUT.freeMem();
|
|
|
|
free(moduleBase);
|
|
|
|
free(entryPoints);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class ScriptThread {
|
|
|
|
public:
|
2009-04-11 21:38:41 +00:00
|
|
|
int16 *_stackBuf;
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2005-01-21 21:55:54 +00:00
|
|
|
uint16 _stackTopIndex;
|
|
|
|
uint16 _frameIndex;
|
|
|
|
|
|
|
|
uint16 _threadVars[kThreadVarMax];
|
2004-08-12 23:57:45 +00:00
|
|
|
|
2005-01-21 21:55:54 +00:00
|
|
|
byte *_moduleBase; //
|
|
|
|
uint16 _moduleBaseSize;
|
2004-08-12 23:57:45 +00:00
|
|
|
|
2005-07-30 21:11:48 +00:00
|
|
|
byte *_commonBase; //
|
|
|
|
byte *_staticBase; //
|
2005-01-21 21:55:54 +00:00
|
|
|
VoiceLUT *_voiceLUT; //
|
|
|
|
StringsTable *_strings; //
|
2004-09-23 06:46:44 +00:00
|
|
|
|
2005-01-21 21:55:54 +00:00
|
|
|
int _flags; // ThreadFlags
|
|
|
|
int _waitType; // ThreadWaitTypes
|
|
|
|
uint _sleepTime;
|
|
|
|
void *_threadObj; // which object we're handling
|
2004-09-23 06:46:44 +00:00
|
|
|
|
2005-01-22 14:43:49 +00:00
|
|
|
int16 _returnValue;
|
2004-09-23 06:46:44 +00:00
|
|
|
|
2005-01-21 21:55:54 +00:00
|
|
|
uint16 _instructionOffset; // Instruction offset
|
2004-10-09 07:39:46 +00:00
|
|
|
|
2005-07-30 14:41:25 +00:00
|
|
|
int32 _frameWait;
|
2004-10-03 17:11:23 +00:00
|
|
|
|
2009-04-11 21:38:41 +00:00
|
|
|
enum {
|
|
|
|
THREAD_STACK_SIZE = 256
|
|
|
|
};
|
|
|
|
|
2005-01-21 21:55:54 +00:00
|
|
|
public:
|
|
|
|
byte *baseAddress(byte addrMode) {
|
2005-01-22 14:16:00 +00:00
|
|
|
switch (addrMode) {
|
|
|
|
case kAddressCommon:
|
|
|
|
return _commonBase;
|
|
|
|
case kAddressStatic:
|
|
|
|
return _staticBase;
|
|
|
|
case kAddressModule:
|
|
|
|
return _moduleBase;
|
|
|
|
case kAddressStack:
|
|
|
|
return (byte*)&_stackBuf[_frameIndex];
|
|
|
|
case kAddressThread:
|
|
|
|
return (byte*)_threadVars;
|
|
|
|
default:
|
|
|
|
return _commonBase;
|
2005-01-21 21:55:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int16 stackTop() {
|
2009-04-11 21:38:41 +00:00
|
|
|
return _stackBuf[_stackTopIndex];
|
2004-09-23 06:46:44 +00:00
|
|
|
}
|
|
|
|
|
2005-01-21 21:55:54 +00:00
|
|
|
uint pushedSize() {
|
2009-04-11 21:38:41 +00:00
|
|
|
return THREAD_STACK_SIZE - _stackTopIndex - 2;
|
2004-09-23 06:46:44 +00:00
|
|
|
}
|
|
|
|
|
2005-01-21 21:55:54 +00:00
|
|
|
void push(int16 value) {
|
|
|
|
if (_stackTopIndex <= 0) {
|
|
|
|
error("ScriptThread::push() stack overflow");
|
|
|
|
}
|
2009-04-11 21:38:41 +00:00
|
|
|
_stackBuf[--_stackTopIndex] = value;
|
2004-09-23 06:46:44 +00:00
|
|
|
}
|
|
|
|
|
2005-01-21 21:55:54 +00:00
|
|
|
int16 pop() {
|
2009-04-11 21:38:41 +00:00
|
|
|
if (_stackTopIndex >= THREAD_STACK_SIZE) {
|
2005-06-15 14:42:40 +00:00
|
|
|
error("ScriptThread::pop() stack underflow");
|
2005-01-21 21:55:54 +00:00
|
|
|
}
|
2009-04-11 21:38:41 +00:00
|
|
|
return _stackBuf[_stackTopIndex++];
|
2004-09-23 06:46:44 +00:00
|
|
|
}
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2005-01-21 21:55:54 +00:00
|
|
|
|
|
|
|
// wait stuff
|
|
|
|
void wait(int waitType) {
|
|
|
|
_waitType = waitType;
|
|
|
|
_flags |= kTFlagWaiting;
|
2004-12-21 06:49:07 +00:00
|
|
|
}
|
2004-12-15 00:24:12 +00:00
|
|
|
|
2005-01-21 21:55:54 +00:00
|
|
|
void waitWalk(void *threadObj) {
|
2004-12-24 20:44:39 +00:00
|
|
|
wait(kWaitTypeWalk);
|
2005-01-21 21:55:54 +00:00
|
|
|
_threadObj = threadObj;
|
2004-12-24 20:44:39 +00:00
|
|
|
}
|
|
|
|
|
2005-01-21 21:55:54 +00:00
|
|
|
void waitDelay(int sleepTime) {
|
2004-12-24 20:44:39 +00:00
|
|
|
wait(kWaitTypeDelay);
|
2005-01-21 21:55:54 +00:00
|
|
|
_sleepTime = sleepTime;
|
2004-12-24 20:44:39 +00:00
|
|
|
}
|
|
|
|
|
2007-06-02 15:26:05 +00:00
|
|
|
void waitFrames(int frames) {
|
|
|
|
wait(kWaitTypeWaitFrames);
|
|
|
|
_frameWait = frames;
|
|
|
|
}
|
|
|
|
|
2005-01-15 20:12:49 +00:00
|
|
|
ScriptThread() {
|
2005-07-30 21:11:48 +00:00
|
|
|
memset(this, 0xFE, sizeof(*this));
|
2009-04-11 21:38:41 +00:00
|
|
|
_flags = kTFlagNone;
|
|
|
|
_stackBuf = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// copy constructor
|
|
|
|
ScriptThread(const ScriptThread& s) {
|
|
|
|
memcpy(this, &s, sizeof(*this));
|
|
|
|
|
|
|
|
// Verify that s doesn't have a non-zero _stackBuf, for else
|
|
|
|
// we would have to clone that buffer, too, which we currently
|
|
|
|
// don't do. This case should never occur anyway, though (at
|
|
|
|
// least as long as the thread handling code does not change).
|
|
|
|
assert(!_stackBuf);
|
2005-01-21 21:55:54 +00:00
|
|
|
}
|
2009-04-11 21:38:41 +00:00
|
|
|
|
|
|
|
// assignment operator
|
|
|
|
ScriptThread& operator=(const ScriptThread &s) {
|
|
|
|
if (this == &s)
|
|
|
|
return *this;
|
|
|
|
|
|
|
|
free(_stackBuf);
|
|
|
|
memcpy(this, &s, sizeof(*this));
|
|
|
|
|
|
|
|
// Verify that s doesn't have a non-zero _stackBuf, for else
|
|
|
|
// we would have to clone that buffer, too, which we currently
|
|
|
|
// don't do. This case should never occur anyway, though (at
|
|
|
|
// least as long as the thread handling code does not change).
|
|
|
|
assert(!_stackBuf);
|
|
|
|
}
|
|
|
|
|
2005-01-21 21:55:54 +00:00
|
|
|
~ScriptThread() {
|
|
|
|
free(_stackBuf);
|
2005-01-15 20:12:49 +00:00
|
|
|
}
|
2004-08-12 23:57:45 +00:00
|
|
|
};
|
|
|
|
|
2009-04-11 21:38:41 +00:00
|
|
|
typedef Common::List<ScriptThread> ScriptThreadList;
|
2004-12-15 00:24:12 +00:00
|
|
|
|
2009-01-02 13:59:34 +00:00
|
|
|
#define SCRIPTOP_PARAMS ScriptThread *thread, MemoryReadStream *scriptS, bool &stopParsing, bool &breakOut
|
2005-06-19 14:06:20 +00:00
|
|
|
#define SCRIPTFUNC_PARAMS ScriptThread *thread, int nArgs, bool &disContinue
|
2009-01-02 16:52:38 +00:00
|
|
|
#define OPCODE(x) {&Script::x, #x}
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2004-08-01 22:48:40 +00:00
|
|
|
class Script {
|
|
|
|
public:
|
2005-01-18 21:13:44 +00:00
|
|
|
StringsTable _mainStrings;
|
|
|
|
|
2005-01-28 19:25:41 +00:00
|
|
|
Script(SagaEngine *vm);
|
2004-08-01 22:48:40 +00:00
|
|
|
~Script();
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2005-01-21 21:55:54 +00:00
|
|
|
void loadModule(int scriptModuleNumber);
|
|
|
|
void freeModules();
|
2004-08-01 22:48:40 +00:00
|
|
|
|
2005-01-08 20:30:07 +00:00
|
|
|
void doVerb();
|
2005-04-18 20:03:14 +00:00
|
|
|
void showVerb(int statusColor = -1);
|
2005-01-08 20:30:07 +00:00
|
|
|
void setVerb(int verb);
|
2005-01-13 22:42:49 +00:00
|
|
|
int getCurrentVerb() const { return _currentVerb; }
|
2005-01-15 20:12:49 +00:00
|
|
|
void setPointerVerb();
|
2005-01-15 23:46:43 +00:00
|
|
|
void whichObject(const Point& mousePoint);
|
|
|
|
void hitObject(bool leftButton);
|
|
|
|
void playfieldClick(const Point& mousePoint, bool leftButton);
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2005-01-15 20:12:49 +00:00
|
|
|
void setLeftButtonVerb(int verb);
|
2005-01-13 22:42:49 +00:00
|
|
|
int getLeftButtonVerb() const { return _leftButtonVerb; }
|
2005-01-15 20:12:49 +00:00
|
|
|
void setRightButtonVerb(int verb);
|
2005-01-13 22:42:49 +00:00
|
|
|
int getRightButtonVerb() const { return _rightButtonVerb; }
|
2005-01-15 20:12:49 +00:00
|
|
|
void setNonPlayfieldVerb() {
|
2006-01-13 20:20:01 +00:00
|
|
|
setRightButtonVerb(getVerbType(kVerbNone));
|
2005-01-15 20:12:49 +00:00
|
|
|
_pointerObject = ID_NOTHING;
|
|
|
|
_currentObject[_firstObjectSet ? 1 : 0] = ID_NOTHING;
|
|
|
|
}
|
2005-01-15 23:46:43 +00:00
|
|
|
void setNoPendingVerb() {
|
2006-01-13 20:20:01 +00:00
|
|
|
_pendingVerb = getVerbType(kVerbNone);
|
2005-01-15 23:46:43 +00:00
|
|
|
_currentObject[0] = _currentObject[0] = ID_NOTHING;
|
|
|
|
setPointerVerb();
|
|
|
|
}
|
2006-01-13 20:20:01 +00:00
|
|
|
int getVerbType(VerbTypes verbType);
|
2007-07-30 14:22:53 +00:00
|
|
|
TextListEntry *getPlacardTextEntry() { return _placardTextEntry; }
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2009-01-02 23:16:08 +00:00
|
|
|
protected:
|
2005-10-11 17:20:30 +00:00
|
|
|
// When reading or writing data to the common buffer, we have to use a
|
|
|
|
// well-defined byte order since it's stored in savegames. Otherwise,
|
|
|
|
// we use native byte ordering since that data may be accessed in other
|
|
|
|
// ways than through these functions.
|
|
|
|
//
|
|
|
|
// The "module" area is a special case, which possibly never ever
|
|
|
|
// happens. But if it does, we need well-defined byte ordering.
|
|
|
|
|
|
|
|
uint16 readUint16(byte *addr, byte addrMode) {
|
|
|
|
switch (addrMode) {
|
|
|
|
case kAddressCommon:
|
|
|
|
case kAddressStatic:
|
|
|
|
case kAddressModule:
|
|
|
|
return READ_LE_UINT16(addr);
|
|
|
|
default:
|
|
|
|
return READ_UINT16(addr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void writeUint16(byte *addr, uint16 value, byte addrMode) {
|
|
|
|
switch (addrMode) {
|
|
|
|
case kAddressCommon:
|
|
|
|
case kAddressStatic:
|
|
|
|
case kAddressModule:
|
|
|
|
WRITE_LE_UINT16(addr, value);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
WRITE_UINT16(addr, value);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-01-28 19:25:41 +00:00
|
|
|
SagaEngine *_vm;
|
2005-07-19 19:05:52 +00:00
|
|
|
ResourceContext *_scriptContext;
|
2009-01-02 23:16:08 +00:00
|
|
|
ResourceContext *_dataContext;
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2005-01-21 21:55:54 +00:00
|
|
|
uint16 _modulesLUTEntryLen;
|
|
|
|
ModuleData *_modules;
|
|
|
|
int _modulesCount;
|
2005-07-14 17:46:21 +00:00
|
|
|
TextListEntry *_placardTextEntry;
|
2005-04-21 01:30:07 +00:00
|
|
|
|
|
|
|
friend class SagaEngine;
|
|
|
|
byte *_commonBuffer;
|
2005-01-21 21:55:54 +00:00
|
|
|
uint _commonBufferSize;
|
2005-04-21 01:30:07 +00:00
|
|
|
|
2005-01-21 21:55:54 +00:00
|
|
|
uint _staticSize;
|
2004-12-15 00:24:12 +00:00
|
|
|
ScriptThreadList _threadList;
|
2005-01-21 21:55:54 +00:00
|
|
|
ScriptThread *_conversingThread;
|
2005-01-08 20:30:07 +00:00
|
|
|
|
2005-07-30 21:11:48 +00:00
|
|
|
//verb
|
2005-01-08 20:30:07 +00:00
|
|
|
bool _firstObjectSet;
|
|
|
|
bool _secondObjectNeeded;
|
|
|
|
uint16 _currentObject[2];
|
2005-01-15 20:12:49 +00:00
|
|
|
int16 _currentObjectFlags[2];
|
2005-01-08 20:30:07 +00:00
|
|
|
int _currentVerb;
|
|
|
|
int _stickyVerb;
|
|
|
|
int _leftButtonVerb;
|
|
|
|
int _rightButtonVerb;
|
2007-08-02 01:56:45 +00:00
|
|
|
int _ihnmDemoCurrentY;
|
2005-01-15 20:12:49 +00:00
|
|
|
|
2005-07-30 21:11:48 +00:00
|
|
|
public:
|
2005-01-15 23:46:43 +00:00
|
|
|
uint16 _pendingObject[2];
|
|
|
|
int _pendingVerb;
|
2005-07-30 21:11:48 +00:00
|
|
|
uint16 _pointerObject;
|
2004-12-21 06:49:07 +00:00
|
|
|
|
2004-10-27 02:27:54 +00:00
|
|
|
bool _skipSpeeches;
|
|
|
|
bool _abortEnabled;
|
|
|
|
|
2005-08-09 16:01:04 +00:00
|
|
|
VoiceLUT _globalVoiceLUT;
|
|
|
|
|
2004-08-12 23:57:45 +00:00
|
|
|
public:
|
2009-04-11 21:38:41 +00:00
|
|
|
ScriptThread &createThread(uint16 scriptModuleNumber, uint16 scriptEntryPointNumber);
|
2005-01-15 20:12:49 +00:00
|
|
|
int executeThread(ScriptThread *thread, int entrypointNumber);
|
2005-06-19 14:06:20 +00:00
|
|
|
void executeThreads(uint msec);
|
2005-01-15 20:12:49 +00:00
|
|
|
void completeThread(void);
|
2005-03-29 17:54:53 +00:00
|
|
|
void abortAllThreads(void);
|
2004-12-21 06:49:07 +00:00
|
|
|
|
2004-12-24 10:22:01 +00:00
|
|
|
void wakeUpActorThread(int waitType, void *threadObj);
|
2004-12-21 06:49:07 +00:00
|
|
|
void wakeUpThreads(int waitType);
|
|
|
|
void wakeUpThreadsDelayed(int waitType, int sleepTime);
|
2004-08-12 23:57:45 +00:00
|
|
|
|
2005-08-09 16:01:04 +00:00
|
|
|
void loadVoiceLUT(VoiceLUT &voiceLUT, const byte *resourcePointer, size_t resourceLength);
|
|
|
|
|
2009-01-02 23:16:08 +00:00
|
|
|
protected:
|
2005-01-21 21:55:54 +00:00
|
|
|
void loadModuleBase(ModuleData &module, const byte *resourcePointer, size_t resourceLength);
|
2004-08-12 23:57:45 +00:00
|
|
|
|
2005-03-29 17:54:53 +00:00
|
|
|
// runThread returns true if we should break running of other threads
|
2009-04-11 21:38:41 +00:00
|
|
|
bool runThread(ScriptThread &thread);
|
2005-01-21 21:55:54 +00:00
|
|
|
void setThreadEntrypoint(ScriptThread *thread, int entrypointNumber);
|
2005-01-17 20:17:06 +00:00
|
|
|
|
2005-01-17 23:11:31 +00:00
|
|
|
public:
|
2007-06-10 00:36:01 +00:00
|
|
|
void finishDialog(int strID, int replyID, int flags, int bitOffset);
|
2005-01-17 23:11:31 +00:00
|
|
|
|
2009-01-02 23:16:08 +00:00
|
|
|
protected:
|
2009-01-02 13:59:34 +00:00
|
|
|
// Script opcodes ------------------------------------------------------------
|
|
|
|
typedef void (Script::*ScriptOpType)(SCRIPTOP_PARAMS);
|
|
|
|
struct ScriptOpDescription {
|
|
|
|
ScriptOpType scriptOp;
|
|
|
|
const char *scriptOpName;
|
|
|
|
};
|
|
|
|
const ScriptOpDescription *_scriptOpsList;
|
|
|
|
|
|
|
|
void setupScriptOpcodeList();
|
|
|
|
void opDummy(SCRIPTOP_PARAMS) { warning("Dummy opcode called"); }
|
2009-05-24 15:17:42 +00:00
|
|
|
void opNextBlock(SCRIPTOP_PARAMS) {
|
2009-01-02 13:59:34 +00:00
|
|
|
thread->_instructionOffset = (((thread->_instructionOffset) >> 10) + 1) << 10;
|
|
|
|
}
|
|
|
|
void opDup(SCRIPTOP_PARAMS);
|
|
|
|
void opDrop(SCRIPTOP_PARAMS);
|
|
|
|
void opZero(SCRIPTOP_PARAMS);
|
|
|
|
void opOne(SCRIPTOP_PARAMS);
|
|
|
|
void opConstInt(SCRIPTOP_PARAMS);
|
|
|
|
void opStrLit(SCRIPTOP_PARAMS);
|
|
|
|
void opGetFlag(SCRIPTOP_PARAMS);
|
|
|
|
void opGetByte(SCRIPTOP_PARAMS); // SAGA 2
|
|
|
|
void opGetInt(SCRIPTOP_PARAMS);
|
|
|
|
void opPutFlag(SCRIPTOP_PARAMS);
|
|
|
|
void opPutByte(SCRIPTOP_PARAMS); // SAGA 2
|
|
|
|
void opPutInt(SCRIPTOP_PARAMS);
|
|
|
|
void opPutFlagV(SCRIPTOP_PARAMS);
|
|
|
|
void opPutByteV(SCRIPTOP_PARAMS);
|
|
|
|
void opPutIntV(SCRIPTOP_PARAMS);
|
|
|
|
void opCall(SCRIPTOP_PARAMS); // SAGA 1
|
|
|
|
void opCallNear(SCRIPTOP_PARAMS); // SAGA 2
|
|
|
|
void opCallFar(SCRIPTOP_PARAMS); // SAGA 2
|
|
|
|
void opCcall(SCRIPTOP_PARAMS);
|
|
|
|
void opCcallV(SCRIPTOP_PARAMS);
|
|
|
|
void opCallMember(SCRIPTOP_PARAMS); // SAGA 2
|
|
|
|
void opCallMemberV(SCRIPTOP_PARAMS); // SAGA 2
|
|
|
|
void opEnter(SCRIPTOP_PARAMS);
|
|
|
|
void opReturn(SCRIPTOP_PARAMS);
|
|
|
|
void opReturnV(SCRIPTOP_PARAMS);
|
|
|
|
void opJmp(SCRIPTOP_PARAMS);
|
|
|
|
void opJmpTrueV(SCRIPTOP_PARAMS);
|
|
|
|
void opJmpFalseV(SCRIPTOP_PARAMS);
|
|
|
|
void opJmpTrue(SCRIPTOP_PARAMS);
|
|
|
|
void opJmpFalse(SCRIPTOP_PARAMS);
|
|
|
|
void opJmpSwitch(SCRIPTOP_PARAMS);
|
|
|
|
void opJmpRandom(SCRIPTOP_PARAMS);
|
|
|
|
void opNegate(SCRIPTOP_PARAMS);
|
|
|
|
void opNot(SCRIPTOP_PARAMS);
|
|
|
|
void opCompl(SCRIPTOP_PARAMS);
|
|
|
|
void opIncV(SCRIPTOP_PARAMS);
|
|
|
|
void opDecV(SCRIPTOP_PARAMS);
|
|
|
|
void opPostInc(SCRIPTOP_PARAMS);
|
|
|
|
void opPostDec(SCRIPTOP_PARAMS);
|
|
|
|
void opAdd(SCRIPTOP_PARAMS);
|
|
|
|
void opSub(SCRIPTOP_PARAMS);
|
|
|
|
void opMul(SCRIPTOP_PARAMS);
|
|
|
|
void opDiv(SCRIPTOP_PARAMS);
|
|
|
|
void opMod(SCRIPTOP_PARAMS);
|
|
|
|
void opEq(SCRIPTOP_PARAMS);
|
|
|
|
void opNe(SCRIPTOP_PARAMS);
|
|
|
|
void opGt(SCRIPTOP_PARAMS);
|
|
|
|
void opLt(SCRIPTOP_PARAMS);
|
|
|
|
void opGe(SCRIPTOP_PARAMS);
|
|
|
|
void opLe(SCRIPTOP_PARAMS);
|
|
|
|
void opRsh(SCRIPTOP_PARAMS);
|
|
|
|
void opLsh(SCRIPTOP_PARAMS);
|
|
|
|
void opAnd(SCRIPTOP_PARAMS);
|
|
|
|
void opOr(SCRIPTOP_PARAMS);
|
|
|
|
void opXor(SCRIPTOP_PARAMS);
|
|
|
|
void opLAnd(SCRIPTOP_PARAMS);
|
|
|
|
void opLOr(SCRIPTOP_PARAMS);
|
|
|
|
void opLXor(SCRIPTOP_PARAMS);
|
|
|
|
void opSpeak(SCRIPTOP_PARAMS);
|
|
|
|
void opDialogBegin(SCRIPTOP_PARAMS);
|
|
|
|
void opDialogEnd(SCRIPTOP_PARAMS);
|
|
|
|
void opReply(SCRIPTOP_PARAMS);
|
|
|
|
void opAnimate(SCRIPTOP_PARAMS);
|
|
|
|
void opJmpSeedRandom(SCRIPTOP_PARAMS);
|
|
|
|
|
|
|
|
// Script functions ----------------------------------------------------------
|
2005-01-22 19:21:38 +00:00
|
|
|
typedef void (Script::*ScriptFunctionType)(SCRIPTFUNC_PARAMS);
|
2004-08-12 23:57:45 +00:00
|
|
|
|
2004-12-24 11:11:01 +00:00
|
|
|
struct ScriptFunctionDescription {
|
|
|
|
ScriptFunctionType scriptFunction;
|
|
|
|
const char *scriptFunctionName;
|
|
|
|
};
|
|
|
|
const ScriptFunctionDescription *_scriptFunctionsList;
|
2004-08-12 23:57:45 +00:00
|
|
|
|
2009-01-02 16:52:38 +00:00
|
|
|
void setupITEScriptFuncList();
|
|
|
|
void setupIHNMScriptFuncList();
|
2004-10-27 21:32:28 +00:00
|
|
|
|
2005-01-22 19:21:38 +00:00
|
|
|
void sfPutString(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfWait(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfTakeObject(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfIsCarried(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfStatusBar(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfMainMode(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfScriptWalkTo(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfScriptDoAction(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfSetActorFacing(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfStartBgdAnim(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfStopBgdAnim(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfLockUser(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfPreDialog(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfKillActorThreads(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfFaceTowards(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfSetFollower(SCRIPTFUNC_PARAMS);
|
2005-01-22 21:40:54 +00:00
|
|
|
void sfScriptGotoScene(SCRIPTFUNC_PARAMS);
|
2005-04-24 15:17:38 +00:00
|
|
|
void sfSetObjImage(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfSetObjName(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfGetObjImage(SCRIPTFUNC_PARAMS);
|
2005-06-19 14:06:20 +00:00
|
|
|
void sfGetNumber(SCRIPTFUNC_PARAMS);
|
2005-01-22 19:21:38 +00:00
|
|
|
void sfScriptOpenDoor(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfScriptCloseDoor(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfSetBgdAnimSpeed(SCRIPTFUNC_PARAMS);
|
2009-01-02 13:59:34 +00:00
|
|
|
void sfCycleColors(SCRIPTFUNC_PARAMS);
|
2005-01-22 19:21:38 +00:00
|
|
|
void sfDoCenterActor(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfStartBgdAnimSpeed(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfScriptWalkToAsync(SCRIPTFUNC_PARAMS);
|
2005-04-16 20:59:24 +00:00
|
|
|
void sfEnableZone(SCRIPTFUNC_PARAMS);
|
2005-01-22 19:21:38 +00:00
|
|
|
void sfSetActorState(SCRIPTFUNC_PARAMS);
|
2005-01-22 21:40:54 +00:00
|
|
|
void sfScriptMoveTo(SCRIPTFUNC_PARAMS);
|
2005-04-17 11:53:25 +00:00
|
|
|
void sfSceneEq(SCRIPTFUNC_PARAMS);
|
2005-04-23 12:34:35 +00:00
|
|
|
void sfDropObject(SCRIPTFUNC_PARAMS);
|
2005-01-22 19:21:38 +00:00
|
|
|
void sfFinishBgdAnim(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfSwapActors(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfSimulSpeech(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfScriptWalk(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfCycleFrames(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfSetFrame(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfSetPortrait(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfSetProtagPortrait(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfChainBgdAnim(SCRIPTFUNC_PARAMS);
|
2005-04-16 11:03:34 +00:00
|
|
|
void sfScriptSpecialWalk(SCRIPTFUNC_PARAMS);
|
2005-01-22 19:21:38 +00:00
|
|
|
void sfPlaceActor(SCRIPTFUNC_PARAMS);
|
2005-04-17 11:53:25 +00:00
|
|
|
void sfCheckUserInterrupt(SCRIPTFUNC_PARAMS);
|
2005-04-16 11:03:34 +00:00
|
|
|
void sfScriptWalkRelative(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfScriptMoveRelative(SCRIPTFUNC_PARAMS);
|
2005-05-22 01:20:47 +00:00
|
|
|
void sfSimulSpeech2(SCRIPTFUNC_PARAMS);
|
2005-01-22 19:21:38 +00:00
|
|
|
void sfPlacard(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfPlacardOff(SCRIPTFUNC_PARAMS);
|
2005-04-21 01:30:07 +00:00
|
|
|
void sfSetProtagState(SCRIPTFUNC_PARAMS);
|
2005-01-22 19:21:38 +00:00
|
|
|
void sfResumeBgdAnim(SCRIPTFUNC_PARAMS);
|
2005-06-05 16:53:53 +00:00
|
|
|
void sfThrowActor(SCRIPTFUNC_PARAMS);
|
2005-01-22 21:40:54 +00:00
|
|
|
void sfWaitWalk(SCRIPTFUNC_PARAMS);
|
2005-04-16 16:55:35 +00:00
|
|
|
void sfScriptSceneID(SCRIPTFUNC_PARAMS);
|
2005-06-05 16:53:53 +00:00
|
|
|
void sfChangeActorScene(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfScriptClimb(SCRIPTFUNC_PARAMS);
|
2005-01-22 19:21:38 +00:00
|
|
|
void sfSetDoorState(SCRIPTFUNC_PARAMS);
|
2005-06-12 21:21:14 +00:00
|
|
|
void sfSetActorZ(SCRIPTFUNC_PARAMS);
|
2005-06-15 19:26:32 +00:00
|
|
|
void sfScriptText(SCRIPTFUNC_PARAMS);
|
2005-06-12 21:21:14 +00:00
|
|
|
void sfGetActorX(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfGetActorY(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfEraseDelta(SCRIPTFUNC_PARAMS);
|
2005-01-22 19:21:38 +00:00
|
|
|
void sfPlayMusic(SCRIPTFUNC_PARAMS);
|
2005-07-01 17:29:23 +00:00
|
|
|
void sfPickClimbOutPos(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfTossRif(SCRIPTFUNC_PARAMS);
|
2005-06-20 12:17:22 +00:00
|
|
|
void sfShowControls(SCRIPTFUNC_PARAMS);
|
2005-07-03 20:02:56 +00:00
|
|
|
void sfShowMap(SCRIPTFUNC_PARAMS);
|
2005-05-23 02:23:34 +00:00
|
|
|
void sfPuzzleWon(SCRIPTFUNC_PARAMS);
|
2005-01-22 19:21:38 +00:00
|
|
|
void sfEnableEscape(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfPlaySound(SCRIPTFUNC_PARAMS);
|
2005-06-19 21:18:00 +00:00
|
|
|
void sfPlayLoopedSound(SCRIPTFUNC_PARAMS);
|
2005-04-16 20:59:24 +00:00
|
|
|
void sfGetDeltaFrame(SCRIPTFUNC_PARAMS);
|
2005-05-18 18:28:10 +00:00
|
|
|
void sfShowProtect(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfProtectResult(SCRIPTFUNC_PARAMS);
|
2005-01-22 19:21:38 +00:00
|
|
|
void sfRand(SCRIPTFUNC_PARAMS);
|
2005-06-19 21:18:00 +00:00
|
|
|
void sfFadeMusic(SCRIPTFUNC_PARAMS);
|
2005-07-21 01:33:28 +00:00
|
|
|
void sfScriptStartCutAway(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfReturnFromCutAway(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfEndCutAway(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfGetMouseClicks(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfResetMouseClicks(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfWaitFrames(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfScriptFade(SCRIPTFUNC_PARAMS);
|
2005-06-19 21:18:00 +00:00
|
|
|
void sfPlayVoice(SCRIPTFUNC_PARAMS);
|
2005-07-21 01:33:28 +00:00
|
|
|
void sfVstopFX(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfVstopLoopedFX(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfDemoIsInteractive(SCRIPTFUNC_PARAMS);
|
2005-07-24 13:41:49 +00:00
|
|
|
void sfVsetTrack(SCRIPTFUNC_PARAMS);
|
2005-07-21 01:33:28 +00:00
|
|
|
void sfDebugShowData(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfNull(SCRIPTFUNC_PARAMS);
|
2005-08-07 00:00:43 +00:00
|
|
|
void sfWaitFramesEsc(SCRIPTFUNC_PARAMS);
|
2005-07-25 02:38:43 +00:00
|
|
|
void sfPsychicProfile(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfPsychicProfileOff(SCRIPTFUNC_PARAMS);
|
2005-08-10 17:39:29 +00:00
|
|
|
void sfSetSpeechBox(SCRIPTFUNC_PARAMS);
|
2005-10-04 23:38:19 +00:00
|
|
|
void sfSetChapterPoints(SCRIPTFUNC_PARAMS);
|
2005-10-04 17:44:41 +00:00
|
|
|
void sfSetPortraitBgColor(SCRIPTFUNC_PARAMS);
|
2005-09-25 00:08:13 +00:00
|
|
|
void sfScriptStartVideo(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfScriptReturnFromVideo(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfScriptEndVideo(SCRIPTFUNC_PARAMS);
|
2007-08-02 14:43:10 +00:00
|
|
|
void sfShowIHNMDemoHelpBg(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfAddIHNMDemoHelpTextLine(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfShowIHNMDemoHelpPage(SCRIPTFUNC_PARAMS);
|
2005-09-25 00:08:13 +00:00
|
|
|
void sfGetPoints(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfSetGlobalFlag(SCRIPTFUNC_PARAMS);
|
2007-08-17 06:08:18 +00:00
|
|
|
void sfDemoSetInteractive(SCRIPTFUNC_PARAMS);
|
2005-09-25 00:08:13 +00:00
|
|
|
void sfClearGlobalFlag(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfTestGlobalFlag(SCRIPTFUNC_PARAMS);
|
|
|
|
void sfSetPoints(SCRIPTFUNC_PARAMS);
|
2007-07-06 12:39:00 +00:00
|
|
|
void sfQueueMusic(SCRIPTFUNC_PARAMS);
|
2005-10-04 23:38:19 +00:00
|
|
|
void sfDisableAbortSpeeches(SCRIPTFUNC_PARAMS);
|
2005-08-10 17:39:29 +00:00
|
|
|
|
2009-01-02 16:52:38 +00:00
|
|
|
void sfStub(const char *name, ScriptThread *thread, int nArgs);
|
2004-08-01 22:48:40 +00:00
|
|
|
};
|
2004-04-12 21:40:49 +00:00
|
|
|
|
2009-01-02 23:16:08 +00:00
|
|
|
class SAGA1Script : public Script {
|
|
|
|
public:
|
|
|
|
SAGA1Script(SagaEngine *vm);
|
|
|
|
~SAGA1Script();
|
|
|
|
};
|
|
|
|
|
|
|
|
class SAGA2Script : public Script {
|
|
|
|
public:
|
|
|
|
SAGA2Script(SagaEngine *vm);
|
|
|
|
~SAGA2Script();
|
|
|
|
};
|
|
|
|
|
2004-04-12 21:40:49 +00:00
|
|
|
} // End of namespace Saga
|
|
|
|
|
|
|
|
#endif
|