aboutsummaryrefslogtreecommitdiff
path: root/engines/saga/script.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/saga/script.cpp')
-rw-r--r--engines/saga/script.cpp154
1 files changed, 60 insertions, 94 deletions
diff --git a/engines/saga/script.cpp b/engines/saga/script.cpp
index b0e20da48c..3ae2f19e1b 100644
--- a/engines/saga/script.cpp
+++ b/engines/saga/script.cpp
@@ -46,12 +46,11 @@ namespace Saga {
SAGA1Script::SAGA1Script(SagaEngine *vm) : Script(vm) {
ResourceContext *resourceContext;
- byte *resourcePointer;
- size_t resourceLength;
+ ByteArray resourceData;
int prevTell;
- int i, j;
- byte *stringsPointer;
- size_t stringsLength;
+ uint ui;
+ int j;
+ ByteArray stringsData;
//initialize member variables
_abortEnabled = true;
@@ -67,9 +66,7 @@ SAGA1Script::SAGA1Script(SagaEngine *vm) : Script(vm) {
_pointerObject = ID_NOTHING;
_staticSize = 0;
- _commonBufferSize = COMMON_BUFFER_SIZE;
- _commonBuffer = (byte*)malloc(_commonBufferSize);
- memset(_commonBuffer, 0, _commonBufferSize);
+ _commonBuffer.resize(COMMON_BUFFER_SIZE);
debug(8, "Initializing scripting subsystem");
// Load script resource file context
@@ -86,47 +83,41 @@ SAGA1Script::SAGA1Script(SagaEngine *vm) : Script(vm) {
uint32 scriptResourceId = 0;
scriptResourceId = _vm->getResourceDescription()->moduleLUTResourceId;
debug(3, "Loading module LUT from resource %i", scriptResourceId);
- _vm->_resource->loadResource(resourceContext, scriptResourceId, resourcePointer, resourceLength);
+ _vm->_resource->loadResource(resourceContext, scriptResourceId, resourceData);
// Create logical script LUT from resource
- if (resourceLength % 22 == 0) { // ITE CD
+ if (resourceData.size() % 22 == 0) { // ITE CD
_modulesLUTEntryLen = 22;
- } else if (resourceLength % 16 == 0) { // ITE disk, IHNM
+ } else if (resourceData.size() % 16 == 0) { // ITE disk, IHNM
_modulesLUTEntryLen = 16;
} else {
- error("Script::Script() Invalid script lookup table length (%i)", (int)resourceLength);
+ error("Script::Script() Invalid script lookup table length (%i)", (int)resourceData.size());
}
// Calculate number of entries
- _modulesCount = resourceLength / _modulesLUTEntryLen;
+ int modulesCount = resourceData.size() / _modulesLUTEntryLen;
- debug(3, "LUT has %i entries", _modulesCount);
+ debug(3, "LUT has %i entries", modulesCount);
// Allocate space for logical LUT
- _modules = (ModuleData *)malloc(_modulesCount * sizeof(*_modules));
- if (_modules == NULL) {
- memoryError("Script::Script()");
- }
+ _modules.resize(modulesCount);
// Convert LUT resource to logical LUT
- MemoryReadStreamEndian scriptS(resourcePointer, resourceLength, resourceContext->isBigEndian());
- for (i = 0; i < _modulesCount; i++) {
- memset(&_modules[i], 0, sizeof(ModuleData));
+ ByteArrayReadStreamEndian scriptS(resourceData, resourceContext->isBigEndian());
+ for (ui = 0; ui < _modules.size(); ui++) {
prevTell = scriptS.pos();
- _modules[i].scriptResourceId = scriptS.readUint16();
- _modules[i].stringsResourceId = scriptS.readUint16();
- _modules[i].voicesResourceId = scriptS.readUint16();
+ _modules[ui].scriptResourceId = scriptS.readUint16();
+ _modules[ui].stringsResourceId = scriptS.readUint16();
+ _modules[ui].voicesResourceId = scriptS.readUint16();
// Skip the unused portion of the structure
for (j = scriptS.pos(); j < prevTell + _modulesLUTEntryLen; j++) {
if (scriptS.readByte() != 0)
- warning("Unused scriptLUT part isn't really unused for LUT %d (pos: %d)", i, j);
+ warning("Unused scriptLUT part isn't really unused for LUT %d (pos: %d)", ui, j);
}
}
- free(resourcePointer);
-
// TODO
//
// In ITE, the "main strings" resource contains both the verb strings
@@ -135,10 +126,9 @@ SAGA1Script::SAGA1Script(SagaEngine *vm) : Script(vm) {
// In IHNM, the "main strings" contains the verb strings, but not the
// object names. At least, I think that's the case.
- _vm->_resource->loadResource(resourceContext, _vm->getResourceDescription()->mainStringsResourceId, stringsPointer, stringsLength);
+ _vm->_resource->loadResource(resourceContext, _vm->getResourceDescription()->mainStringsResourceId, stringsData);
- _vm->loadStrings(_mainStrings, stringsPointer, stringsLength);
- free(stringsPointer);
+ _vm->loadStrings(_mainStrings, stringsData);
setupScriptOpcodeList();
@@ -157,19 +147,10 @@ SAGA1Script::SAGA1Script(SagaEngine *vm) : Script(vm) {
SAGA1Script::~SAGA1Script() {
debug(8, "Shutting down scripting subsystem.");
-
- _mainStrings.freeMem();
- _globalVoiceLUT.freeMem();
-
- freeModules();
- free(_modules);
-
- free(_commonBuffer);
}
SAGA2Script::SAGA2Script(SagaEngine *vm) : Script(vm) {
- byte *resourcePointer;
- size_t resourceLength;
+ ByteArray resourceData;
debug(8, "Initializing scripting subsystem");
// Load script resource file context
@@ -184,14 +165,14 @@ SAGA2Script::SAGA2Script(SagaEngine *vm) : Script(vm) {
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);
+ _vm->_resource->loadResource(_scriptContext, (uint32)entryNum, resourceData);
_modulesLUTEntryLen = sizeof(uint32);
// Calculate number of entries
- _modulesCount = resourceLength / _modulesLUTEntryLen + 1;
+ int modulesCount = resourceData.size() / _modulesLUTEntryLen + 1;
- debug(3, "LUT has %i entries", _modulesCount);
+ debug(3, "LUT has %i entries", modulesCount);
// Script data segment
/*
@@ -994,8 +975,8 @@ void Script::opSpeak(SCRIPTOP_PARAMS) {
}
} else {
#endif
- if (thread->_voiceLUT->voicesCount > first)
- sampleResourceId = thread->_voiceLUT->voices[first];
+ if (thread->_voiceLUT->size() > uint16(first))
+ sampleResourceId = (*thread->_voiceLUT)[uint16(first)];
#if 0
}
#endif
@@ -1067,12 +1048,11 @@ void Script::opJmpSeedRandom(SCRIPTOP_PARAMS) {
warning("opJmpSeedRandom");
}
-void Script::loadModule(int scriptModuleNumber) {
- byte *resourcePointer;
- size_t resourceLength;
+void Script::loadModule(uint scriptModuleNumber) {
+ ByteArray resourceData;
// Validate script number
- if ((scriptModuleNumber < 0) || (scriptModuleNumber >= _modulesCount)) {
+ if (scriptModuleNumber >= _modules.size()) {
error("Script::loadScript() Invalid script module number");
}
@@ -1083,79 +1063,70 @@ void Script::loadModule(int scriptModuleNumber) {
// Initialize script data structure
debug(3, "Loading script module #%d", scriptModuleNumber);
- _vm->_resource->loadResource(_scriptContext, _modules[scriptModuleNumber].scriptResourceId, resourcePointer, resourceLength);
+ _vm->_resource->loadResource(_scriptContext, _modules[scriptModuleNumber].scriptResourceId, resourceData);
- loadModuleBase(_modules[scriptModuleNumber], resourcePointer, resourceLength);
- free(resourcePointer);
+ loadModuleBase(_modules[scriptModuleNumber], resourceData);
- _vm->_resource->loadResource(_scriptContext, _modules[scriptModuleNumber].stringsResourceId, resourcePointer, resourceLength);
+ _vm->_resource->loadResource(_scriptContext, _modules[scriptModuleNumber].stringsResourceId, resourceData);
- _vm->loadStrings(_modules[scriptModuleNumber].strings, resourcePointer, resourceLength);
- free(resourcePointer);
+ _vm->loadStrings(_modules[scriptModuleNumber].strings, resourceData);
if (_modules[scriptModuleNumber].voicesResourceId > 0) {
- _vm->_resource->loadResource(_scriptContext, _modules[scriptModuleNumber].voicesResourceId, resourcePointer, resourceLength);
+ _vm->_resource->loadResource(_scriptContext, _modules[scriptModuleNumber].voicesResourceId, resourceData);
- loadVoiceLUT(_modules[scriptModuleNumber].voiceLUT, resourcePointer, resourceLength);
- free(resourcePointer);
+ loadVoiceLUT(_modules[scriptModuleNumber].voiceLUT, resourceData);
}
_modules[scriptModuleNumber].staticOffset = _staticSize;
_staticSize += _modules[scriptModuleNumber].staticSize;
- if (_staticSize > _commonBufferSize) {
- error("Script::loadModule() _staticSize > _commonBufferSize");
+ if (_staticSize > _commonBuffer.size()) {
+ error("Script::loadModule() _staticSize > _commonBuffer.size()");
}
_modules[scriptModuleNumber].loaded = true;
}
-void Script::freeModules() {
- int i;
- for (i = 0; i < _modulesCount; i++) {
+void Script::clearModules() {
+ uint i;
+ for (i = 0; i < _modules.size(); i++) {
if (_modules[i].loaded) {
- _modules[i].freeMem();
- _modules[i].loaded = false;
+ _modules[i].clear();
}
}
_staticSize = 0;
}
-void Script::loadModuleBase(ModuleData &module, const byte *resourcePointer, size_t resourceLength) {
- int i;
+void Script::loadModuleBase(ModuleData &module, const ByteArray &resourceData) {
+ uint i;
debug(3, "Loading module base...");
- module.moduleBase = (byte*)malloc(resourceLength);
- module.moduleBaseSize = resourceLength;
-
- memcpy(module.moduleBase, resourcePointer, resourceLength);
+ module.moduleBase.assign(resourceData);
- MemoryReadStreamEndian scriptS(module.moduleBase, module.moduleBaseSize, _scriptContext->isBigEndian());
+ ByteArrayReadStreamEndian scriptS(module.moduleBase, _scriptContext->isBigEndian());
- module.entryPointsCount = scriptS.readUint16();
+ uint entryPointsCount = scriptS.readUint16();
scriptS.readUint16(); //skip
- module.entryPointsTableOffset = scriptS.readUint16();
+ uint16 entryPointsTableOffset; // offset of entrypoint table in moduleBase
+ entryPointsTableOffset = scriptS.readUint16();
scriptS.readUint16(); //skip
- if ((module.moduleBaseSize - module.entryPointsTableOffset) < (module.entryPointsCount * SCRIPT_TBLENTRY_LEN)) {
+ if ((module.moduleBase.size() - entryPointsTableOffset) < (entryPointsCount * SCRIPT_TBLENTRY_LEN)) {
error("Script::loadModuleBase() Invalid table offset");
}
- if (module.entryPointsCount > SCRIPT_MAX) {
+ if (entryPointsCount > SCRIPT_MAX) {
error("Script::loadModuleBase()Script limit exceeded");
}
- module.entryPoints = (EntryPoint *)malloc(module.entryPointsCount * sizeof(*module.entryPoints));
- if (module.entryPoints == NULL) {
- memoryError("Script::loadModuleBase");
- }
+ module.entryPoints.resize(entryPointsCount);
// Read in the entrypoint table
module.staticSize = scriptS.readUint16();
- while (scriptS.pos() < module.entryPointsTableOffset)
+ while (scriptS.pos() < entryPointsTableOffset)
scriptS.readByte();
- for (i = 0; i < module.entryPointsCount; i++) {
+ for (i = 0; i < module.entryPoints.size(); i++) {
// First uint16 is the offset of the entrypoint name from the start
// of the bytecode resource, second uint16 is the offset of the
// bytecode itself for said entrypoint
@@ -1163,26 +1134,21 @@ void Script::loadModuleBase(ModuleData &module, const byte *resourcePointer, siz
module.entryPoints[i].offset = scriptS.readUint16();
// Perform a simple range check on offset values
- if ((module.entryPoints[i].nameOffset >= module.moduleBaseSize) || (module.entryPoints[i].offset >= module.moduleBaseSize)) {
+ if ((module.entryPoints[i].nameOffset >= module.moduleBase.size()) || (module.entryPoints[i].offset >= module.moduleBase.size())) {
error("Script::loadModuleBase() Invalid offset encountered in script entrypoint table");
}
}
}
-void Script::loadVoiceLUT(VoiceLUT &voiceLUT, const byte *resourcePointer, size_t resourceLength) {
+void Script::loadVoiceLUT(VoiceLUT &voiceLUT, const ByteArray &resourceData) {
uint16 i;
- voiceLUT.voicesCount = resourceLength / 2;
-
- voiceLUT.voices = (uint16 *)malloc(voiceLUT.voicesCount * sizeof(*voiceLUT.voices));
- if (voiceLUT.voices == NULL) {
- error("Script::loadVoiceLUT() not enough memory");
- }
+ voiceLUT.resize(resourceData.size() / 2);
- MemoryReadStreamEndian scriptS(resourcePointer, resourceLength, _scriptContext->isBigEndian());
+ ByteArrayReadStreamEndian scriptS(resourceData, _scriptContext->isBigEndian());
- for (i = 0; i < voiceLUT.voicesCount; i++) {
- voiceLUT.voices[i] = scriptS.readUint16();
+ for (i = 0; i < voiceLUT.size(); i++) {
+ voiceLUT[i] = scriptS.readUint16();
}
}
@@ -1442,7 +1408,7 @@ void Script::doVerb() {
event.param4 = _pendingObject[0]; // Object
event.param5 = _pendingObject[1]; // With Object
event.param6 = (objectType == kGameObjectActor) ? _pendingObject[0] : ID_PROTAG; // Actor
- _vm->_events->queue(&event);
+ _vm->_events->queue(event);
} else {
// Show excuse text in ITE CD Versions