Split the script module into two parts, for SAGA1 and SAGA2 games

svn-id: r35689
This commit is contained in:
Filippos Karapetis 2009-01-02 23:16:08 +00:00
parent 6a7e4e3c15
commit 40d6a3c1e5
3 changed files with 90 additions and 48 deletions

View File

@ -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);

View File

@ -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}

View File

@ -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