diff options
-rw-r--r-- | engines/saga/saga.cpp | 4 | ||||
-rw-r--r-- | engines/saga/script.cpp | 107 | ||||
-rw-r--r-- | engines/saga/script.h | 27 |
3 files changed, 90 insertions, 48 deletions
diff --git a/engines/saga/saga.cpp b/engines/saga/saga.cpp index 4781ef79ab..b24ae7a8fb 100644 --- a/engines/saga/saga.cpp +++ b/engines/saga/saga.cpp @@ -194,10 +194,12 @@ Common::Error SagaEngine::init() { if (!isSaga2()) { _font = new Font(this); _sprite = new Sprite(this); + _script = new SAGA1Script(this); + } else { + _script = new SAGA2Script(this); } _anim = new Anim(this); - _script = new Script(this); _interface = new Interface(this); // requires script module _scene = new Scene(this); _actor = new Actor(this); diff --git a/engines/saga/script.cpp b/engines/saga/script.cpp index 6bdbed87d6..cf1cf84b24 100644 --- a/engines/saga/script.cpp +++ b/engines/saga/script.cpp @@ -44,9 +44,7 @@ namespace Saga { #define RID_SCENE1_VOICE_START 57 #define RID_SCENE1_VOICE_END 186 -// Initializes the scripting module. -// Loads script resource look-up table, initializes script data system -Script::Script(SagaEngine *vm) : _vm(vm) { +SAGA1Script::SAGA1Script(SagaEngine *vm) : Script(vm) { ResourceContext *resourceContext; byte *resourcePointer; size_t resourceLength; @@ -59,7 +57,6 @@ Script::Script(SagaEngine *vm) : _vm(vm) { _abortEnabled = true; _skipSpeeches = false; _conversingThread = NULL; - _firstObjectSet = false; _secondObjectNeeded = false; _pendingVerb = getVerbType(kVerbNone); @@ -87,34 +84,15 @@ Script::Script(SagaEngine *vm) : _vm(vm) { } uint32 scriptResourceId = 0; - - if (!_vm->isSaga2()) { - scriptResourceId = _vm->getResourceDescription()->moduleLUTResourceId; - debug(3, "Loading module LUT from resource %i", scriptResourceId); - _vm->_resource->loadResource(resourceContext, scriptResourceId, resourcePointer, resourceLength); - } else { - uint32 saga2DataSegId = MKID_BE('__DA'); - int32 scr = _scriptContext->getEntryNum(saga2DataSegId); - if (scr < 0) - error("Unable to locate the script's data segment"); - scriptResourceId = (uint32)scr; - debug(3, "Loading module LUT from resource %i", scriptResourceId); - _vm->_resource->loadResource(_scriptContext, scriptResourceId, resourcePointer, resourceLength); - - //uint32 saga2ExportSegId = MKID_BE('_EXP'); - // TODO: SAGA2 script export segment - } - - // Do nothing for SAGA2 games for now - if (_vm->isSaga2()) { - return; - } + scriptResourceId = _vm->getResourceDescription()->moduleLUTResourceId; + debug(3, "Loading module LUT from resource %i", scriptResourceId); + _vm->_resource->loadResource(resourceContext, scriptResourceId, resourcePointer, resourceLength); // Create logical script LUT from resource - if (resourceLength % S_LUT_ENTRYLEN_ITECD == 0) { - _modulesLUTEntryLen = S_LUT_ENTRYLEN_ITECD; - } else if (resourceLength % S_LUT_ENTRYLEN_ITEDISK == 0) { - _modulesLUTEntryLen = S_LUT_ENTRYLEN_ITEDISK; + if (resourceLength % 22 == 0) { // ITE CD + _modulesLUTEntryLen = 22; + } else if (resourceLength % 16 == 0) { // ITE disk, IHNM + _modulesLUTEntryLen = 16; } else { error("Script::Script() Invalid script lookup table length (%i)", (int)resourceLength); } @@ -130,6 +108,11 @@ Script::Script(SagaEngine *vm) : _vm(vm) { memoryError("Script::Script()"); } + // Do nothing for SAGA2 games for now + if (_vm->isSaga2()) { + return; + } + // Convert LUT resource to logical LUT MemoryReadStreamEndian scriptS(resourcePointer, resourceLength, resourceContext->isBigEndian); for (i = 0; i < _modulesCount; i++) { @@ -174,25 +157,77 @@ Script::Script(SagaEngine *vm) : _vm(vm) { setupIHNMScriptFuncList(); break; #endif - // TODO: FTA2 and DINO } } -// Shut down script module gracefully; free all allocated module resources -Script::~Script() { - +SAGA1Script::~SAGA1Script() { debug(8, "Shutting down scripting subsystem."); _mainStrings.freeMem(); _globalVoiceLUT.freeMem(); freeModules(); - if (!_vm->isSaga2()) // TODO: remove this once the script module is working for SAGA2 - free(_modules); + free(_modules); free(_commonBuffer); } +SAGA2Script::SAGA2Script(SagaEngine *vm) : Script(vm) { + byte *resourcePointer; + size_t resourceLength; + + debug(8, "Initializing scripting subsystem"); + // Load script resource file context + _scriptContext = _vm->_resource->getContext(GAME_SCRIPTFILE); + if (_scriptContext == NULL) { + error("Script::Script() script context not found"); + } + + // Script export segment (lookup table) + uint32 saga2ExportSegId = MKID_BE('_EXP'); + int32 entryNum = _scriptContext->getEntryNum(saga2ExportSegId); + if (entryNum < 0) + error("Unable to locate the script's export segment"); + debug(3, "Loading module LUT from resource %i", entryNum); + _vm->_resource->loadResource(_scriptContext, (uint32)entryNum, resourcePointer, resourceLength); + + _modulesLUTEntryLen = sizeof(uint32); + + // Calculate number of entries + _modulesCount = resourceLength / _modulesLUTEntryLen + 1; + + debug(3, "LUT has %i entries", _modulesCount); + + // Script data segment + /* + uint32 saga2DataSegId = MKID_BE('__DA'); + entryNum = _scriptContext->getEntryNum(saga2DataSegId); + if (entryNum < 0) + error("Unable to locate the script's data segment"); + debug(3, "Loading module data from resource %i", entryNum); + _vm->_resource->loadResource(_scriptContext, (uint32)entryNum, resourcePointer, resourceLength); + */ + + // TODO +} + +SAGA2Script::~SAGA2Script() { + debug(8, "Shutting down scripting subsystem."); + + // TODO +} + +// Initializes the scripting module. +// Loads script resource look-up table, initializes script data system +Script::Script(SagaEngine *vm) : _vm(vm) { + +} + +// Shut down script module gracefully; free all allocated module resources +Script::~Script() { + +} + // Script opcodes #define OPCODE(x) {&Script::x, #x} diff --git a/engines/saga/script.h b/engines/saga/script.h index 608891bb8a..1237435fec 100644 --- a/engines/saga/script.h +++ b/engines/saga/script.h @@ -37,9 +37,6 @@ namespace Saga { #define COMMON_BUFFER_SIZE 1024 // Why 1024? -#define S_LUT_ENTRYLEN_ITECD 22 -#define S_LUT_ENTRYLEN_ITEDISK 16 - #define SCRIPT_TBLENTRY_LEN 4 #define SCRIPT_MAX 5000 @@ -313,7 +310,7 @@ public: int getVerbType(VerbTypes verbType); TextListEntry *getPlacardTextEntry() { return _placardTextEntry; } -private: +protected: // 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 @@ -348,22 +345,19 @@ private: SagaEngine *_vm; ResourceContext *_scriptContext; + ResourceContext *_dataContext; uint16 _modulesLUTEntryLen; ModuleData *_modules; int _modulesCount; TextListEntry *_placardTextEntry; -protected: friend class SagaEngine; byte *_commonBuffer; uint _commonBufferSize; -private: uint _staticSize; - ScriptThreadList _threadList; - ScriptThread *_conversingThread; //verb @@ -400,7 +394,7 @@ public: void loadVoiceLUT(VoiceLUT &voiceLUT, const byte *resourcePointer, size_t resourceLength); -private: +protected: void loadModuleBase(ModuleData &module, const byte *resourcePointer, size_t resourceLength); // runThread returns true if we should break running of other threads @@ -410,8 +404,7 @@ private: public: void finishDialog(int strID, int replyID, int flags, int bitOffset); -private: - +protected: // Script opcodes ------------------------------------------------------------ typedef void (Script::*ScriptOpType)(SCRIPTOP_PARAMS); struct ScriptOpDescription { @@ -618,6 +611,18 @@ private: void sfStub(const char *name, ScriptThread *thread, int nArgs); }; +class SAGA1Script : public Script { +public: + SAGA1Script(SagaEngine *vm); + ~SAGA1Script(); +}; + +class SAGA2Script : public Script { +public: + SAGA2Script(SagaEngine *vm); + ~SAGA2Script(); +}; + } // End of namespace Saga #endif |