mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-21 11:41:25 +00:00
SAGA: replace Script and Thread "::*alloc" & "::free" with Common::Array
svn-id: r53678
This commit is contained in:
parent
c1505d6e51
commit
8b72f49460
@ -48,7 +48,7 @@ void Resource_RES::loadGlobalResources(int chapter, int actorsEntrance) {
|
||||
if (chapter < 0)
|
||||
chapter = !_vm->isIHNMDemo() ? 8 : 7;
|
||||
|
||||
_vm->_script->_globalVoiceLUT.freeMem();
|
||||
_vm->_script->_globalVoiceLUT.clear();
|
||||
|
||||
// TODO: close chapter context, or rather reassign it in our case
|
||||
|
||||
|
@ -240,9 +240,9 @@ void SagaEngine::save(const char *fileName, const char *saveName) {
|
||||
|
||||
_actor->saveState(out);
|
||||
|
||||
out->writeSint16LE(_script->_commonBufferSize);
|
||||
out->writeSint16LE(_script->_commonBuffer.size());
|
||||
|
||||
out->write(_script->_commonBuffer, _script->_commonBufferSize);
|
||||
out->write(&_script->_commonBuffer.front(), _script->_commonBuffer.size());
|
||||
|
||||
// ISO map x, y coordinates for ITE
|
||||
if (getGameId() == GID_ITE) {
|
||||
@ -351,7 +351,8 @@ void SagaEngine::load(const char *fileName) {
|
||||
_actor->loadState(in);
|
||||
|
||||
commonBufferSize = in->readSint16LE();
|
||||
in->read(_script->_commonBuffer, commonBufferSize);
|
||||
_script->_commonBuffer.resize(commonBufferSize);
|
||||
in->read(&_script->_commonBuffer.front(), commonBufferSize);
|
||||
|
||||
if (getGameId() == GID_ITE) {
|
||||
mapx = in->readSint16LE();
|
||||
|
@ -624,7 +624,7 @@ void Scene::loadScene(LoadSceneParams &loadSceneParams) {
|
||||
_vm->_interface->setLeftPortrait(0);
|
||||
|
||||
_vm->_anim->freeCutawayList();
|
||||
_vm->_script->freeModules();
|
||||
_vm->_script->clearModules();
|
||||
|
||||
// deleteAllScenes();
|
||||
|
||||
|
@ -49,7 +49,8 @@ SAGA1Script::SAGA1Script(SagaEngine *vm) : Script(vm) {
|
||||
byte *resourcePointer;
|
||||
size_t resourceLength;
|
||||
int prevTell;
|
||||
int i, j;
|
||||
uint ui;
|
||||
int j;
|
||||
byte *stringsPointer;
|
||||
size_t stringsLength;
|
||||
|
||||
@ -67,9 +68,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
|
||||
@ -98,30 +97,26 @@ SAGA1Script::SAGA1Script(SagaEngine *vm) : Script(vm) {
|
||||
}
|
||||
|
||||
// Calculate number of entries
|
||||
_modulesCount = resourceLength / _modulesLUTEntryLen;
|
||||
int modulesCount = resourceLength / _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));
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -157,13 +152,6 @@ SAGA1Script::SAGA1Script(SagaEngine *vm) : Script(vm) {
|
||||
|
||||
SAGA1Script::~SAGA1Script() {
|
||||
debug(8, "Shutting down scripting subsystem.");
|
||||
|
||||
_globalVoiceLUT.freeMem();
|
||||
|
||||
freeModules();
|
||||
free(_modules);
|
||||
|
||||
free(_commonBuffer);
|
||||
}
|
||||
|
||||
SAGA2Script::SAGA2Script(SagaEngine *vm) : Script(vm) {
|
||||
@ -188,9 +176,9 @@ SAGA2Script::SAGA2Script(SagaEngine *vm) : Script(vm) {
|
||||
_modulesLUTEntryLen = sizeof(uint32);
|
||||
|
||||
// Calculate number of entries
|
||||
_modulesCount = resourceLength / _modulesLUTEntryLen + 1;
|
||||
int modulesCount = resourceLength / _modulesLUTEntryLen + 1;
|
||||
|
||||
debug(3, "LUT has %i entries", _modulesCount);
|
||||
debug(3, "LUT has %i entries", modulesCount);
|
||||
|
||||
// Script data segment
|
||||
/*
|
||||
@ -993,8 +981,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
|
||||
@ -1066,12 +1054,12 @@ void Script::opJmpSeedRandom(SCRIPTOP_PARAMS) {
|
||||
warning("opJmpSeedRandom");
|
||||
}
|
||||
|
||||
void Script::loadModule(int scriptModuleNumber) {
|
||||
void Script::loadModule(uint scriptModuleNumber) {
|
||||
byte *resourcePointer;
|
||||
size_t resourceLength;
|
||||
|
||||
// Validate script number
|
||||
if ((scriptModuleNumber < 0) || (scriptModuleNumber >= _modulesCount)) {
|
||||
if ((scriptModuleNumber < 0) || (scriptModuleNumber >= _modules.size())) {
|
||||
error("Script::loadScript() Invalid script module number");
|
||||
}
|
||||
|
||||
@ -1101,60 +1089,56 @@ void Script::loadModule(int scriptModuleNumber) {
|
||||
|
||||
_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;
|
||||
uint i;
|
||||
|
||||
debug(3, "Loading module base...");
|
||||
|
||||
module.moduleBase = (byte*)malloc(resourceLength);
|
||||
module.moduleBaseSize = resourceLength;
|
||||
module.moduleBase.resize(resourceLength);
|
||||
|
||||
memcpy(&module.moduleBase.front(), resourcePointer, resourceLength);
|
||||
|
||||
memcpy(module.moduleBase, resourcePointer, resourceLength);
|
||||
MemoryReadStreamEndian scriptS(&module.moduleBase.front(), module.moduleBase.size(), _scriptContext->isBigEndian());
|
||||
|
||||
MemoryReadStreamEndian scriptS(module.moduleBase, module.moduleBaseSize, _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
|
||||
@ -1162,7 +1146,7 @@ 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");
|
||||
}
|
||||
}
|
||||
@ -1171,17 +1155,12 @@ void Script::loadModuleBase(ModuleData &module, const byte *resourcePointer, siz
|
||||
void Script::loadVoiceLUT(VoiceLUT &voiceLUT, const byte *resourcePointer, size_t resourceLength) {
|
||||
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(resourceLength / 2);
|
||||
|
||||
MemoryReadStreamEndian scriptS(resourcePointer, resourceLength, _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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,16 +129,7 @@ struct EntryPoint {
|
||||
uint16 offset;
|
||||
};
|
||||
|
||||
struct VoiceLUT {
|
||||
uint16 voicesCount;
|
||||
uint16 *voices;
|
||||
void freeMem() {
|
||||
voicesCount = 0;
|
||||
free(voices);
|
||||
}
|
||||
VoiceLUT() {
|
||||
memset(this, 0, sizeof(*this));
|
||||
}
|
||||
class VoiceLUT : public Common::Array<uint16> {
|
||||
};
|
||||
|
||||
struct ModuleData {
|
||||
@ -147,28 +138,29 @@ struct ModuleData {
|
||||
int stringsResourceId;
|
||||
int voicesResourceId;
|
||||
|
||||
byte *moduleBase; // all base module
|
||||
uint16 moduleBaseSize; // base module size
|
||||
Common::Array<byte> moduleBase; // all base module
|
||||
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;
|
||||
Common::Array<EntryPoint> entryPoints;
|
||||
|
||||
StringsTable strings;
|
||||
VoiceLUT voiceLUT;
|
||||
void freeMem() {
|
||||
|
||||
void clear() {
|
||||
loaded = false;
|
||||
strings.clear();
|
||||
voiceLUT.freeMem();
|
||||
free(moduleBase);
|
||||
free(entryPoints);
|
||||
voiceLUT.clear();
|
||||
moduleBase.clear();
|
||||
entryPoints.clear();
|
||||
}
|
||||
|
||||
ModuleData() : loaded(false), scriptResourceId(0), stringsResourceId(0), voicesResourceId(0), staticSize(0), staticOffset(0) {
|
||||
}
|
||||
};
|
||||
|
||||
class ScriptThread {
|
||||
public:
|
||||
int16 *_stackBuf;
|
||||
Common::Array<int16> _stackBuf;
|
||||
|
||||
uint16 _stackTopIndex;
|
||||
uint16 _frameIndex;
|
||||
@ -264,41 +256,15 @@ public:
|
||||
}
|
||||
|
||||
ScriptThread() {
|
||||
memset(this, 0xFE, sizeof(*this));
|
||||
memset(&_frameIndex, 0xFE, sizeof(_frameIndex));
|
||||
memset(_threadVars, 0xFE, sizeof(_threadVars));
|
||||
memset(&_waitType, 0xFE, sizeof(_waitType));
|
||||
memset(&_sleepTime, 0xFE, sizeof(_sleepTime));
|
||||
memset(&_threadObj, 0xFE, sizeof(_threadObj));
|
||||
memset(&_returnValue, 0xFE, sizeof(_threadObj));
|
||||
memset(&_frameWait, 0xFE, sizeof(_frameWait));
|
||||
|
||||
_flags = kTFlagNone;
|
||||
_stackBuf = 0;
|
||||
}
|
||||
|
||||
// copy constructor
|
||||
ScriptThread(const ScriptThread& s) {
|
||||
// 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(!s._stackBuf);
|
||||
|
||||
memcpy(this, &s, sizeof(*this));
|
||||
}
|
||||
|
||||
// assignment operator
|
||||
ScriptThread& operator=(const ScriptThread &s) {
|
||||
if (this == &s)
|
||||
return *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(!s._stackBuf);
|
||||
|
||||
free(_stackBuf);
|
||||
memcpy(this, &s, sizeof(*this));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
~ScriptThread() {
|
||||
free(_stackBuf);
|
||||
}
|
||||
};
|
||||
|
||||
@ -315,8 +281,8 @@ public:
|
||||
Script(SagaEngine *vm);
|
||||
virtual ~Script();
|
||||
|
||||
void loadModule(int scriptModuleNumber);
|
||||
void freeModules();
|
||||
void loadModule(uint scriptModuleNumber);
|
||||
void clearModules();
|
||||
|
||||
void doVerb();
|
||||
void showVerb(int statusColor = -1);
|
||||
@ -384,13 +350,11 @@ protected:
|
||||
ResourceContext *_dataContext;
|
||||
|
||||
uint16 _modulesLUTEntryLen;
|
||||
ModuleData *_modules;
|
||||
int _modulesCount;
|
||||
Common::Array<ModuleData> _modules;
|
||||
TextListEntry *_placardTextEntry;
|
||||
|
||||
friend class SagaEngine;
|
||||
byte *_commonBuffer;
|
||||
uint _commonBufferSize;
|
||||
Common::Array<byte> _commonBuffer;
|
||||
|
||||
uint _staticSize;
|
||||
ScriptThreadList _threadList;
|
||||
|
@ -782,11 +782,11 @@ void Script::sfSimulSpeech(SCRIPTFUNC_PARAMS) {
|
||||
for (i = 0; i < actorsCount; i++)
|
||||
actorsIds[i] = thread->pop();
|
||||
|
||||
if (thread->_voiceLUT->voices) {
|
||||
if (!thread->_voiceLUT->empty()) {
|
||||
if (_vm->getGameId() == GID_IHNM && stringId >= 338) {
|
||||
sampleResourceId = -1;
|
||||
} else {
|
||||
sampleResourceId = thread->_voiceLUT->voices[stringId];
|
||||
sampleResourceId = (*thread->_voiceLUT)[stringId];
|
||||
if (sampleResourceId <= 0 || sampleResourceId > 4000)
|
||||
sampleResourceId = -1;
|
||||
}
|
||||
@ -1042,8 +1042,8 @@ void Script::sfSimulSpeech2(SCRIPTFUNC_PARAMS) {
|
||||
for (i = 0; i < actorsCount; i++)
|
||||
actorsIds[i] = thread->pop();
|
||||
|
||||
if (thread->_voiceLUT->voices) {
|
||||
sampleResourceId = thread->_voiceLUT->voices[stringId];
|
||||
if (!thread->_voiceLUT->empty()) {
|
||||
sampleResourceId = (*thread->_voiceLUT)[stringId];
|
||||
if (sampleResourceId <= 0 || sampleResourceId > 4000)
|
||||
sampleResourceId = -1;
|
||||
}
|
||||
@ -1527,7 +1527,7 @@ void Script::finishDialog(int strID, int replyID, int flags, int bitOffset) {
|
||||
const char *str = _conversingThread->_strings->getString(strID);
|
||||
if (*str != '[') {
|
||||
int sampleResourceId = -1;
|
||||
sampleResourceId = _conversingThread->_voiceLUT->voices[strID];
|
||||
sampleResourceId = (*_conversingThread->_voiceLUT)[strID];
|
||||
if (sampleResourceId < 0 || sampleResourceId > 4000)
|
||||
sampleResourceId = -1;
|
||||
|
||||
|
@ -39,16 +39,18 @@ namespace Saga {
|
||||
|
||||
ScriptThread &Script::createThread(uint16 scriptModuleNumber, uint16 scriptEntryPointNumber) {
|
||||
loadModule(scriptModuleNumber);
|
||||
if (_modules[scriptModuleNumber].entryPointsCount <= scriptEntryPointNumber) {
|
||||
if (_modules[scriptModuleNumber].entryPoints.size() <= scriptEntryPointNumber) {
|
||||
error("Script::createThread wrong scriptEntryPointNumber");
|
||||
}
|
||||
|
||||
ScriptThread newThread;
|
||||
ScriptThread tmp;
|
||||
_threadList.push_front(tmp);
|
||||
ScriptThread &newThread = _threadList.front();
|
||||
newThread._instructionOffset = _modules[scriptModuleNumber].entryPoints[scriptEntryPointNumber].offset;
|
||||
newThread._commonBase = _commonBuffer;
|
||||
newThread._staticBase = _commonBuffer + _modules[scriptModuleNumber].staticOffset;
|
||||
newThread._moduleBase = _modules[scriptModuleNumber].moduleBase;
|
||||
newThread._moduleBaseSize = _modules[scriptModuleNumber].moduleBaseSize;
|
||||
newThread._commonBase = &_commonBuffer.front();
|
||||
newThread._staticBase = &_commonBuffer.front() + _modules[scriptModuleNumber].staticOffset;
|
||||
newThread._moduleBase = &_modules[scriptModuleNumber].moduleBase.front();
|
||||
newThread._moduleBaseSize = _modules[scriptModuleNumber].moduleBase.size();
|
||||
newThread._strings = &_modules[scriptModuleNumber].strings;
|
||||
|
||||
if (_vm->getGameId() == GID_IHNM)
|
||||
@ -56,14 +58,10 @@ ScriptThread &Script::createThread(uint16 scriptModuleNumber, uint16 scriptEntry
|
||||
else
|
||||
newThread._voiceLUT = &_modules[scriptModuleNumber].voiceLUT;
|
||||
|
||||
_threadList.push_front(newThread);
|
||||
|
||||
newThread._stackBuf.resize(ScriptThread::THREAD_STACK_SIZE);
|
||||
newThread._stackTopIndex = ScriptThread::THREAD_STACK_SIZE - 2;
|
||||
debug(3, "createThread(). Total threads: %d", _threadList.size());
|
||||
|
||||
ScriptThread &tmp = *_threadList.begin();
|
||||
tmp._stackBuf = (int16 *)malloc(ScriptThread::THREAD_STACK_SIZE * sizeof(int16));
|
||||
tmp._stackTopIndex = ScriptThread::THREAD_STACK_SIZE - 2;
|
||||
return tmp;
|
||||
return newThread;
|
||||
}
|
||||
|
||||
void Script::wakeUpActorThread(int waitType, void *threadObj) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user