aboutsummaryrefslogtreecommitdiff
path: root/saga/script.h
diff options
context:
space:
mode:
authorAndrew Kurushin2005-01-21 21:55:54 +0000
committerAndrew Kurushin2005-01-21 21:55:54 +0000
commit58ec0f0aadd5228732a3c5915b9a94ec00e9cc53 (patch)
tree28c6ded9c7fd57a8284fa1212f17917900e7e57e /saga/script.h
parent0228f1645f582213ef3e12f19df8e88e61891fbe (diff)
downloadscummvm-rg350-58ec0f0aadd5228732a3c5915b9a94ec00e9cc53.tar.gz
scummvm-rg350-58ec0f0aadd5228732a3c5915b9a94ec00e9cc53.tar.bz2
scummvm-rg350-58ec0f0aadd5228732a3c5915b9a94ec00e9cc53.zip
problems solved:
- Allow more than one script work at once - Proper implementation of address methods some opcodes may be broken - cause work in progress todo: rewrite opcodes with new address functionality svn-id: r16604
Diffstat (limited to 'saga/script.h')
-rw-r--r--saga/script.h254
1 files changed, 150 insertions, 104 deletions
diff --git a/saga/script.h b/saga/script.h
index 8bf227e6c8..04796d108b 100644
--- a/saga/script.h
+++ b/saga/script.h
@@ -31,8 +31,7 @@
namespace Saga {
-#define SCRIPT_DATABUF_NUM 5
-#define SCRIPT_DATABUF_LEN 1024
+#define COMMON_BUFFER_SIZE 1024
#define S_LUT_ENTRYLEN_ITECD 22
#define S_LUT_ENTRYLEN_ITEDISK 16
@@ -48,8 +47,18 @@ namespace Saga {
#define S_WARN_PREFIX "SWarning: "
#define SCRIPT_FUNCTION_MAX 78
-
-typedef unsigned int ScriptDataWord;
+#define DEFAULT_THREAD_STACK_SIZE 256
+
+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
+ kAddressThread = 4, // offset from thread structure
+/* kAddressId = 5, // offset from const id object
+ kAddressIdIndirect = 6, // offset from stack id object
+ kAddressIndex = 7 // index from id*/
+};
enum VerbTypes {
//todo: LUT for drawing
@@ -74,11 +83,13 @@ enum VerbTypes {
#define STHREAD_TIMESLICE 8
-enum {
- kVarObject = 0,
- kVarWithObject,
- kVarAction,
- kVarActor
+enum ThreadVarTypes {
+ kThreadVarObject = 0,
+ kThreadVarWithObject = 1,
+ kThreadVarAction = 2,
+ kThreadVarActor = 3,
+
+ kThreadVarMax = kThreadVarActor + 1
};
enum ThreadFlags {
@@ -136,104 +147,141 @@ enum ReplyFlags {
kReplyCondition = 1 << 2
};
-struct ScriptThread {
- int flags; // ThreadFlags
- int waitType; // ThreadWaitTypes
- void *threadObj; // which object we're handling
+struct EntryPoint {
+ uint16 nameOffset;
+ uint16 offset;
+};
+
+struct VoiceLUT {
+ uint16 voicesCount;
+ uint16 *voices;
+ void freeMem() {
+ free(voices);
+ }
+};
+
+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);
+ memset(this, 0x0, sizeof(*this));
+ }
+};
+
+class ScriptThread {
+public:
+ uint16 *_stackBuf;
+ uint16 _stackSize; // stack size in uint16
+
+ uint16 _stackTopIndex;
+ uint16 _frameIndex;
+
+ uint16 _threadVars[kThreadVarMax];
- uint sleepTime;
- int entrypointNumber; // Entrypoint number
- unsigned long entrypointOffset; // Entrypoint offset
- unsigned long instructionOffset; // Instruction offset
+ byte *_moduleBase; //
+ uint16 _moduleBaseSize;
- // The scripts are allowed to access the stack like any other memory
- // area. It's therefore probably quite important that our stacks work
- // the same as in the original interpreter.
+ byte *_commonBase; //
+ byte *_staticBase; //
+ VoiceLUT *_voiceLUT; //
+ StringsTable *_strings; //
- ScriptDataWord stackBuf[64];
+ int _flags; // ThreadFlags
+ int _waitType; // ThreadWaitTypes
+ uint _sleepTime;
+ void *_threadObj; // which object we're handling
- int stackPtr;
- int framePtr;
+ uint16 _returnValue;
- ScriptDataWord threadVars[4];
+ uint16 _instructionOffset; // Instruction offset
- ScriptDataWord retVal;
- ScriptDataWord stackTop() {
- return stackBuf[stackPtr];
+public:
+ byte *baseAddress(byte addrMode) {
+ switch(addrMode) {
+ case kAddressCommon:
+ return _commonBase;
+ case kAddressStatic:
+ return _staticBase;
+ case kAddressModule:
+ return _moduleBase;
+/* case kAddressStack:
+ return _stackBuf + framePtr;*/
+ case kAddressThread:
+ return (byte*)_threadVars;
+ default:
+ return _commonBase;
+ }
+ }
+
+ int16 stackTop() {
+ return (int16)_stackBuf[_stackTopIndex];
}
- int stackSize() {
- return ARRAYSIZE(stackBuf) - stackPtr - 1;
+ uint pushedSize() {
+ return _stackSize - _stackTopIndex - 1;
}
- void push(ScriptDataWord n) {
- assert(stackPtr > 0);
- stackBuf[--stackPtr] = n;
+ void push(int16 value) {
+ if (_stackTopIndex <= 0) {
+ error("ScriptThread::push() stack overflow");
+ }
+ _stackBuf[--_stackTopIndex] = (uint16)value;
}
- ScriptDataWord pop() {
- assert(stackPtr < ARRAYSIZE(stackBuf));
- return stackBuf[stackPtr++];
+ int16 pop() {
+ if (_stackTopIndex >= _stackSize) {
+ error("ScriptThread::push() stack underflow");
+ }
+ return (int16)_stackBuf[_stackTopIndex++];
}
- void wait(int aWaitType) {
- waitType = aWaitType;
- flags |= kTFlagWaiting;
+
+// wait stuff
+ void wait(int waitType) {
+ _waitType = waitType;
+ _flags |= kTFlagWaiting;
}
- void waitWalk(void *aThreadObj) {
+ void waitWalk(void *threadObj) {
wait(kWaitTypeWalk);
- threadObj = aThreadObj;
+ _threadObj = threadObj;
}
- void waitDelay(int aSleepTime) {
+ void waitDelay(int sleepTime) {
wait(kWaitTypeDelay);
- sleepTime = aSleepTime;
+ _sleepTime = sleepTime;
}
ScriptThread() {
- memset(this, 0, sizeof(*this));
+ memset(this, 0xFE, sizeof(*this));
+ _stackBuf = NULL;
+ }
+ ~ScriptThread() {
+ free(_stackBuf);
}
};
typedef SortedList<ScriptThread> ScriptThreadList;
-struct PROC_TBLENTRY {
- size_t name_offset;
- size_t offset;
-};
-
-struct SCRIPT_BYTECODE {
- unsigned char *bytecode_p;
- size_t bytecode_len;
- size_t ep_tbl_offset;
- unsigned long n_entrypoints;
- PROC_TBLENTRY *entrypoints;
-};
-
-struct VOICE_LUT {
- int n_voices;
- int *voices;
-};
-
-struct ScriptData {
- int loaded;
- SCRIPT_BYTECODE *bytecode;
- StringsTable strings;
- VOICE_LUT *voice;
-};
-
-struct SCRIPT_LUT_ENTRY {
- int script_rn;
- int diag_list_rn;
- int voice_lut_rn;
-};
-
-struct ScriptDataBuf {
- ScriptDataWord *data;
- int length;
-};
#define SCRIPTFUNC_PARAMS ScriptThread *thread, int nArgs
@@ -246,20 +294,17 @@ public:
void CF_script_togglestep();
- int loadScript(int scriptNum);
- int freeScript();
- SCRIPT_BYTECODE *loadBytecode(byte *bytecode_p, size_t bytecode_len);
- VOICE_LUT *loadVoiceLUT(const byte *voicelut_p, size_t voicelut_len, ScriptData *script);
+ void loadModule(int scriptModuleNumber);
+ void freeModules();
bool isInitialized() const { return _initialized; }
bool isVoiceLUTPresent() const { return _voiceLUTPresent; }
- ScriptData *currentScript() { return _currentScript; }
- ScriptDataBuf *dataBuffer(int idx) { return &_dataBuf[idx]; }
+/* ScriptData *currentScript() { return _currentScript; }
int getWord(int bufNumber, int wordNumber, ScriptDataWord *data);
int putWord(int bufNumber, int wordNumber, ScriptDataWord data);
int setBit(int bufNumber, ScriptDataWord bitNumber, int bitState);
- int getBit(int bufNumber, ScriptDataWord bitNumber, int *bitState);
- const char * getScriptString(int index) const { return _currentScript->strings.getString(index); }
+ int getBit(int bufNumber, ScriptDataWord bitNumber, int *bitState); */
+// const char * getScriptString(int index) const { return _currentScript->strings.getString(index); }
void doVerb();
void showVerb(int statuscolor = -1);
@@ -288,17 +333,22 @@ public:
void scriptInfo();
void scriptExec(int argc, const char **argv);
-protected:
+private:
bool _initialized;
bool _voiceLUTPresent;
RSCFILE_CONTEXT *_scriptContext;
- SCRIPT_LUT_ENTRY *_scriptLUT;
- int _scriptLUTMax;
- uint16 _scriptLUTEntryLen;
- ScriptData *_currentScript;
- ScriptDataBuf _dataBuf[SCRIPT_DATABUF_NUM];
+
+ uint16 _modulesLUTEntryLen;
+ ModuleData *_modules;
+ int _modulesCount;
+
+ byte* _commonBuffer;
+ uint _commonBufferSize;
+ uint _staticSize;
+
ScriptThreadList _threadList;
+ ScriptThread *_conversingThread;
//verb
bool _firstObjectSet;
@@ -315,7 +365,6 @@ public:
int _pendingVerb;
uint16 _pointerObject;
-public:
bool _skipSpeeches;
bool _abortEnabled;
@@ -325,7 +374,7 @@ public:
TEXTLIST_ENTRY *_dbg_txtentry;
public:
- ScriptThread *createThread();
+ ScriptThread *createThread(uint16 scriptModuleNumber, uint16 scriptEntryPointNumber);
int executeThread(ScriptThread *thread, int entrypointNumber);
int executeThreads(uint msec);
int SThreadDebugStep();
@@ -336,20 +385,17 @@ public:
void wakeUpThreadsDelayed(int waitType, int sleepTime);
private:
- void setFramePtr(ScriptThread *thread, int newPtr);
- unsigned char *SThreadGetReadPtr(ScriptThread *thread);
- unsigned long SThreadGetReadOffset(const byte *read_p);
- size_t SThreadGetReadLen(ScriptThread *thread);
- void runThread(ScriptThread *thread, int instr_limit);
- void setThreadEntrypoint(ScriptThread *thread, int entrypointNumber);
+ void loadModuleBase(ModuleData &module, const byte *resourcePointer, size_t resourceLength);
+ void loadModuleVoiceLUT(ModuleData &module, const byte *resourcePointer, size_t resourceLength);
-private:
- ScriptThread *_conversingThread;
+ void runThread(ScriptThread *thread, uint instructionLimit);
+ void setThreadEntrypoint(ScriptThread *thread, int entrypointNumber);
public:
void finishDialog(int replyID, int flags, int bitOffset);
private:
+
typedef int (Script::*ScriptFunctionType)(SCRIPTFUNC_PARAMS);
struct ScriptFunctionDescription {
@@ -442,7 +488,7 @@ private:
int SF_playVoice(SCRIPTFUNC_PARAMS);
};
-inline int getSWord(ScriptDataWord word) {
+/*inline int getSWord(ScriptDataWord word) {
uint16 uInt = word;
int sInt;
@@ -458,7 +504,7 @@ inline int getSWord(ScriptDataWord word) {
inline uint getUWord(ScriptDataWord word) {
return (uint16) word;
}
-
+*/
} // End of namespace Saga