mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-16 22:58:09 +00:00
DIRECTOR: LINGO: Add split contexts for main and shared archives
This commit is contained in:
parent
3c0be1d7a6
commit
189acb438d
@ -336,7 +336,7 @@ void LC::cb_list() {
|
||||
|
||||
void LC::cb_call() {
|
||||
int nameId = g_lingo->readInt();
|
||||
Common::String name = g_lingo->_namelist[nameId];
|
||||
Common::String name = g_lingo->getName(nameId);
|
||||
|
||||
Datum nargs = g_lingo->pop();
|
||||
if ((nargs.type == ARGC) || (nargs.type == ARGCNORET)) {
|
||||
@ -351,7 +351,7 @@ void LC::cb_call() {
|
||||
|
||||
void LC::cb_globalpush() {
|
||||
int nameId = g_lingo->readInt();
|
||||
Common::String name = g_lingo->_namelist[nameId];
|
||||
Common::String name = g_lingo->getName(nameId);
|
||||
Datum result;
|
||||
result.type = VOID;
|
||||
|
||||
@ -374,7 +374,7 @@ void LC::cb_globalpush() {
|
||||
|
||||
void LC::cb_globalassign() {
|
||||
int nameId = g_lingo->readInt();
|
||||
Common::String name = g_lingo->_namelist[nameId];
|
||||
Common::String name = g_lingo->getName(nameId);
|
||||
|
||||
Symbol *s = g_lingo->lookupVar(name.c_str(), false);
|
||||
if (!s) {
|
||||
@ -397,7 +397,7 @@ void LC::cb_globalassign() {
|
||||
|
||||
void LC::cb_objectpush() {
|
||||
int nameId = g_lingo->readInt();
|
||||
Common::String name = g_lingo->_namelist[nameId];
|
||||
Common::String name = g_lingo->getName(nameId);
|
||||
warning("STUB: cb_objectpush(%s)", name.c_str());
|
||||
Datum result;
|
||||
result.type = VOID;
|
||||
@ -407,7 +407,7 @@ void LC::cb_objectpush() {
|
||||
|
||||
void LC::cb_varpush() {
|
||||
int nameId = g_lingo->readInt();
|
||||
Common::String name = g_lingo->_namelist[nameId];
|
||||
Common::String name = g_lingo->getName(nameId);
|
||||
Datum result;
|
||||
result.type = VOID;
|
||||
|
||||
@ -430,7 +430,7 @@ void LC::cb_varpush() {
|
||||
|
||||
void LC::cb_varassign() {
|
||||
int nameId = g_lingo->readInt();
|
||||
Common::String name = g_lingo->_namelist[nameId];
|
||||
Common::String name = g_lingo->getName(nameId);
|
||||
|
||||
Symbol *s = g_lingo->lookupVar(name.c_str(), false);
|
||||
if (!s) {
|
||||
@ -519,7 +519,7 @@ void LC::cb_v4theentitynamepush() {
|
||||
}
|
||||
|
||||
int nameId = g_lingo->readInt();
|
||||
Common::String name = g_lingo->_namelist[nameId];
|
||||
Common::String name = g_lingo->getName(nameId);
|
||||
|
||||
Datum id;
|
||||
id.u.s = NULL;
|
||||
@ -618,7 +618,7 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
|
||||
_currentScriptContext = new ScriptContext;
|
||||
_currentScriptType = type;
|
||||
_currentEntityId = id;
|
||||
_scriptContexts[type][id] = _currentScriptContext;
|
||||
_archives[_archiveIndex].scriptContexts[type][id] = _currentScriptContext;
|
||||
|
||||
if (stream.size() < 0x5c) {
|
||||
warning("Lscr header too small");
|
||||
@ -667,8 +667,8 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
|
||||
stream.seek(globalsOffset);
|
||||
for (uint16 i = 0; i < globalsCount; i++) {
|
||||
uint16 index = stream.readUint16();
|
||||
if (index < _namelist.size()) {
|
||||
const char *name = _namelist[index].c_str();
|
||||
if (index < _archives[_archiveIndex].names.size()) {
|
||||
const char *name = _archives[_archiveIndex].names[index].c_str();
|
||||
debugC(5, kDebugLoading, "%d: %s", i, name);
|
||||
g_lingo->lookupVar(name, true, true);
|
||||
} else {
|
||||
@ -866,8 +866,8 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
|
||||
uint16 index = (uint16)READ_BE_UINT16(&codeStore[namePointer]);
|
||||
namePointer += 2;
|
||||
Common::String name;
|
||||
if (index < _namelist.size()) {
|
||||
name = _namelist[index];
|
||||
if (index < _archives[_archiveIndex].names.size()) {
|
||||
name = _archives[_archiveIndex].names[index];
|
||||
argMap[j] = index;
|
||||
} else {
|
||||
name = Common::String::format("arg_%d", j);
|
||||
@ -892,8 +892,8 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
|
||||
uint16 index = (uint16)READ_BE_UINT16(&codeStore[namePointer]);
|
||||
namePointer += 2;
|
||||
Common::String name;
|
||||
if (index < _namelist.size()) {
|
||||
name = _namelist[index];
|
||||
if (index < _archives[_archiveIndex].names.size()) {
|
||||
name = _archives[_archiveIndex].names[index];
|
||||
varMap[j] = index;
|
||||
} else {
|
||||
name = Common::String::format("var_%d", j);
|
||||
@ -1081,9 +1081,9 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
|
||||
|
||||
// Attach to handlers
|
||||
Symbol *sym = NULL;
|
||||
if (nameIndex < _namelist.size()) {
|
||||
debugC(5, kDebugLoading, "Function %d binding: %s()", i, _namelist[nameIndex].c_str());
|
||||
sym = g_lingo->define(_namelist[nameIndex], argCount, _currentScript);
|
||||
if (nameIndex < _archives[_archiveIndex].names.size()) {
|
||||
debugC(5, kDebugLoading, "Function %d binding: %s()", i, _archives[_archiveIndex].names[nameIndex].c_str());
|
||||
sym = g_lingo->define(_archives[_archiveIndex].names[nameIndex], argCount, _currentScript);
|
||||
} else {
|
||||
warning("Function has unknown name id %d, skipping define", nameIndex);
|
||||
sym = new Symbol;
|
||||
@ -1095,6 +1095,7 @@ void Lingo::addCodeV4(Common::SeekableSubReadStreamEndian &stream, ScriptType ty
|
||||
sym->argNames = argNames;
|
||||
sym->varNames = varNames;
|
||||
sym->ctx = _currentScriptContext;
|
||||
sym->archiveIndex = _archiveIndex;
|
||||
_currentScriptContext->functions.push_back(sym);
|
||||
|
||||
}
|
||||
@ -1135,7 +1136,7 @@ void Lingo::addNamesV4(Common::SeekableSubReadStreamEndian &stream) {
|
||||
|
||||
stream.seek(offset);
|
||||
|
||||
_namelist.clear();
|
||||
_archives[_archiveIndex].names.clear();
|
||||
|
||||
Common::Array<Common::String> names;
|
||||
for (uint32 i = 0; i < count; i++) {
|
||||
@ -1144,7 +1145,7 @@ void Lingo::addNamesV4(Common::SeekableSubReadStreamEndian &stream) {
|
||||
for (uint8 j = 0; j < size; j++) {
|
||||
name += stream.readByte();
|
||||
}
|
||||
_namelist.push_back(name);
|
||||
_archives[_archiveIndex].names.push_back(name);
|
||||
debugC(5, kDebugLoading, "%d: \"%s\"", i, name.c_str());
|
||||
}
|
||||
|
||||
|
@ -270,7 +270,7 @@ void LC::c_symbolpush() {
|
||||
void LC::c_namepush() {
|
||||
Datum d;
|
||||
int i = g_lingo->readInt();
|
||||
g_lingo->push(Datum(new Common::String(g_lingo->_namelist[i])));
|
||||
g_lingo->push(Datum(new Common::String(g_lingo->getName(i))));
|
||||
}
|
||||
|
||||
void LC::c_argcpush() {
|
||||
@ -1310,6 +1310,7 @@ void LC::call(Symbol *sym, int nargs) {
|
||||
fp->retpc = g_lingo->_pc;
|
||||
fp->retscript = g_lingo->_currentScript;
|
||||
fp->retctx = g_lingo->_currentScriptContext;
|
||||
fp->retarchive = g_lingo->_archiveIndex;
|
||||
fp->localvars = g_lingo->_localvars;
|
||||
|
||||
// Create new set of local variables
|
||||
@ -1356,6 +1357,9 @@ void LC::call(Symbol *sym, int nargs) {
|
||||
if (sym->ctx) {
|
||||
g_lingo->_currentScriptContext = sym->ctx;
|
||||
}
|
||||
if (sym->archiveIndex) {
|
||||
g_lingo->_archiveIndex = sym->archiveIndex;
|
||||
}
|
||||
|
||||
g_lingo->execute(0);
|
||||
|
||||
@ -1376,6 +1380,7 @@ void LC::c_procret() {
|
||||
|
||||
g_lingo->_currentScript = fp->retscript;
|
||||
g_lingo->_currentScriptContext = fp->retctx;
|
||||
g_lingo->_archiveIndex = fp->retarchive;
|
||||
g_lingo->_pc = fp->retpc;
|
||||
|
||||
g_lingo->cleanLocalVars();
|
||||
|
@ -275,6 +275,7 @@ Symbol *Lingo::define(Common::String &name, int nargs, ScriptData *code) {
|
||||
sym->argNames = NULL;
|
||||
sym->varNames = NULL;
|
||||
sym->ctx = NULL;
|
||||
sym->archiveIndex = -1;
|
||||
|
||||
if (debugChannelSet(1, kDebugLingoCompile)) {
|
||||
uint pc = 0;
|
||||
|
@ -200,8 +200,8 @@ void Lingo::runMovieScript(LEvent event) {
|
||||
if (_dontPassEvent)
|
||||
return;
|
||||
|
||||
for (ScriptContextHash::iterator it = _scriptContexts[kMovieScript].begin();
|
||||
it != _scriptContexts[kMovieScript].end(); ++it) {
|
||||
for (ScriptContextHash::iterator it = _archives[_archiveIndex].scriptContexts[kMovieScript].begin();
|
||||
it != _archives[_archiveIndex].scriptContexts[kMovieScript].end(); ++it) {
|
||||
processEvent(event, kMovieScript, it->_key);
|
||||
// TODO: How do know which script handles the message?
|
||||
}
|
||||
@ -319,7 +319,7 @@ void Lingo::processEvent(LEvent event, ScriptType st, int entityId) {
|
||||
if (_handlers.contains(ENTITY_INDEX(event, entityId))) {
|
||||
debugC(1, kDebugEvents, "Lingo::processEvent(%s, %s, %d), _eventHandler", _eventHandlerTypes[event], scriptType2str(st), entityId);
|
||||
executeHandler(_eventHandlerTypes[event]); // D4+ Events
|
||||
} else if (_vm->getVersion() < 4 && event == kEventNone && _scriptContexts[st].contains(entityId)) {
|
||||
} else if (_vm->getVersion() < 4 && event == kEventNone && getScriptContext(st, entityId)) {
|
||||
debugC(1, kDebugEvents, "Lingo::processEvent(%s, %s, %d), script", _eventHandlerTypes[event], scriptType2str(st), entityId);
|
||||
|
||||
executeScript(st, entityId, 0); // D3 list of scripts.
|
||||
|
@ -75,6 +75,8 @@ Lingo::Lingo(DirectorEngine *vm) : _vm(vm) {
|
||||
|
||||
_dontPassEvent = false;
|
||||
|
||||
_archiveIndex = 0;
|
||||
|
||||
initEventHandlerTypes();
|
||||
|
||||
initBuiltIns();
|
||||
@ -89,13 +91,23 @@ Lingo::~Lingo() {
|
||||
}
|
||||
|
||||
ScriptContext *Lingo::getScriptContext(ScriptType type, uint16 id) {
|
||||
if (type >= (int)_scriptContexts->size()) {
|
||||
if (type >= (int)_archives[_archiveIndex].scriptContexts->size()) {
|
||||
return NULL;
|
||||
}
|
||||
if (!_scriptContexts[type].contains(id)) {
|
||||
if (!_archives[_archiveIndex].scriptContexts[type].contains(id)) {
|
||||
return NULL;
|
||||
}
|
||||
return _scriptContexts[type][id];
|
||||
return _archives[_archiveIndex].scriptContexts[type][id];
|
||||
}
|
||||
|
||||
Common::String Lingo::getName(uint16 id) {
|
||||
Common::String result;
|
||||
if (id >= _archives[_archiveIndex].names.size()) {
|
||||
warning("Name id %d not in list", id);
|
||||
return result;
|
||||
}
|
||||
result = _archives[_archiveIndex].names[id];
|
||||
return result;
|
||||
}
|
||||
|
||||
const char *Lingo::findNextDefinition(const char *s) {
|
||||
@ -149,7 +161,7 @@ void Lingo::addCode(const char *code, ScriptType type, uint16 id) {
|
||||
_currentScriptContext = new ScriptContext;
|
||||
_currentScriptType = type;
|
||||
_currentEntityId = id;
|
||||
_scriptContexts[type][id] = _currentScriptContext;
|
||||
_archives[_archiveIndex].scriptContexts[type][id] = _currentScriptContext;
|
||||
|
||||
// FIXME: unpack into seperate functions
|
||||
_currentScriptFunction = 0;
|
||||
@ -272,14 +284,14 @@ void Lingo::restartLingo() {
|
||||
warning("STUB: restartLingo()");
|
||||
|
||||
for (int i = 0; i <= kMaxScriptType; i++) {
|
||||
for (ScriptContextHash::iterator it = _scriptContexts[i].begin(); it != _scriptContexts[i].end(); ++it) {
|
||||
for (ScriptContextHash::iterator it = _archives[_archiveIndex].scriptContexts[i].begin(); it != _archives[_archiveIndex].scriptContexts[i].end(); ++it) {
|
||||
for (size_t j = 0; j < it->_value->functions.size(); j++) {
|
||||
delete it->_value->functions[j];
|
||||
}
|
||||
delete it->_value;
|
||||
}
|
||||
|
||||
_scriptContexts[i].clear();
|
||||
_archives[_archiveIndex].scriptContexts[i].clear();
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
@ -88,6 +88,7 @@ struct Symbol { /* symbol table entry */
|
||||
Common::Array<Common::String> *argNames;
|
||||
Common::Array<Common::String> *varNames;
|
||||
ScriptContext *ctx; /* optional script context to execute with */
|
||||
int archiveIndex; /* optional archive to execute with */
|
||||
|
||||
Symbol();
|
||||
};
|
||||
@ -140,9 +141,17 @@ struct CFrame { /* proc/func call stack frame */
|
||||
int retpc; /* where to resume after return */
|
||||
ScriptData *retscript; /* which script to resume after return */
|
||||
ScriptContext *retctx; /* which script context to use after return */
|
||||
int retarchive; /* which archive to use after return */
|
||||
SymbolHash *localvars;
|
||||
};
|
||||
|
||||
|
||||
struct LingoArchive {
|
||||
ScriptContextHash scriptContexts[kMaxScriptType + 1];
|
||||
Common::Array<Common::String> names;
|
||||
};
|
||||
|
||||
|
||||
class Lingo {
|
||||
|
||||
public:
|
||||
@ -182,9 +191,10 @@ private:
|
||||
void runMovieScript(LEvent event);
|
||||
void processSpriteEvent(LEvent event);
|
||||
void processEvent(LEvent event, ScriptType st, int entityId);
|
||||
ScriptContext *getScriptContext(ScriptType type, uint16 id);
|
||||
|
||||
public:
|
||||
ScriptContext *getScriptContext(ScriptType type, uint16 id);
|
||||
Common::String getName(uint16 id);
|
||||
ScriptType event2script(LEvent ev);
|
||||
Symbol *getHandler(Common::String &name);
|
||||
|
||||
@ -304,7 +314,6 @@ public:
|
||||
int _objectEntityId;
|
||||
|
||||
Common::Array<int> _labelstack;
|
||||
Common::Array<Common::String> _namelist;
|
||||
|
||||
SymbolHash _builtins;
|
||||
Common::HashMap<Common::String, bool> _twoWordBuiltins;
|
||||
@ -341,8 +350,6 @@ public:
|
||||
Common::HashMap<Common::String, uint32, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _eventHandlerTypeIds;
|
||||
Common::HashMap<Common::String, Audio::AudioStream *> _audioAliases;
|
||||
|
||||
ScriptContextHash _scriptContexts[kMaxScriptType + 1];
|
||||
|
||||
SymbolHash _globalvars;
|
||||
SymbolHash *_localvars;
|
||||
|
||||
@ -351,6 +358,9 @@ public:
|
||||
Common::HashMap<int, LingoV4Bytecode *> _lingoV4;
|
||||
Common::HashMap<int, LingoV4TheEntity *> _lingoV4TheEntity;
|
||||
|
||||
LingoArchive _archives[2];
|
||||
int _archiveIndex;
|
||||
|
||||
uint _pc;
|
||||
|
||||
StackData _stack;
|
||||
|
@ -305,6 +305,7 @@ void DirectorEngine::loadSharedCastsFrom(Common::String filename) {
|
||||
debug(0, "@@@@ Loading Shared cast '%s'", filename.c_str());
|
||||
debug(0, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
|
||||
|
||||
_lingo->_archiveIndex = 1;
|
||||
_sharedScore = new Score(this);
|
||||
_sharedScore->setArchive(sharedCast);
|
||||
|
||||
@ -409,6 +410,7 @@ void DirectorEngine::loadSharedCastsFrom(Common::String filename) {
|
||||
}
|
||||
|
||||
_sharedScore->loadSpriteImages(true);
|
||||
_lingo->_archiveIndex = 0;
|
||||
}
|
||||
|
||||
} // End of namespace Director
|
||||
|
Loading…
Reference in New Issue
Block a user