SCI: Rename Script class members, change Script from struct to class
svn-id: r44126
This commit is contained in:
parent
1b75a1825e
commit
a277123f54
13 changed files with 291 additions and 289 deletions
|
@ -1320,7 +1320,7 @@ bool Console::cmdPrintSegmentTable(int argc, const char **argv) {
|
|||
|
||||
switch (mobj->getType()) {
|
||||
case MEM_OBJ_SCRIPT:
|
||||
DebugPrintf("S script.%03d l:%d ", (*(Script *)mobj).nr, (*(Script *)mobj).lockers);
|
||||
DebugPrintf("S script.%03d l:%d ", (*(Script *)mobj)._nr, (*(Script *)mobj).getLockers());
|
||||
break;
|
||||
|
||||
case MEM_OBJ_CLONES:
|
||||
|
@ -1384,16 +1384,16 @@ bool Console::segmentInfo(int nr) {
|
|||
|
||||
case MEM_OBJ_SCRIPT: {
|
||||
Script *scr = (Script *)mobj;
|
||||
DebugPrintf("script.%03d locked by %d, bufsize=%d (%x)\n", scr->nr, scr->lockers, (uint)scr->buf_size, (uint)scr->buf_size);
|
||||
if (scr->export_table)
|
||||
DebugPrintf(" Exports: %4d at %d\n", scr->exports_nr, (int)(((byte *)scr->export_table) - ((byte *)scr->buf)));
|
||||
DebugPrintf("script.%03d locked by %d, bufsize=%d (%x)\n", scr->_nr, scr->getLockers(), (uint)scr->_bufSize, (uint)scr->_bufSize);
|
||||
if (scr->_exportTable)
|
||||
DebugPrintf(" Exports: %4d at %d\n", scr->_numExports, (int)(((byte *)scr->_exportTable) - ((byte *)scr->_buf)));
|
||||
else
|
||||
DebugPrintf(" Exports: none\n");
|
||||
|
||||
DebugPrintf(" Synonyms: %4d\n", scr->synonyms_nr);
|
||||
DebugPrintf(" Synonyms: %4d\n", scr->_numSynonyms);
|
||||
|
||||
if (scr->locals_block)
|
||||
DebugPrintf(" Locals : %4d in segment 0x%x\n", scr->locals_block->_locals.size(), scr->locals_segment);
|
||||
if (scr->_localsBlock)
|
||||
DebugPrintf(" Locals : %4d in segment 0x%x\n", scr->_localsBlock->_locals.size(), scr->_localsSegment);
|
||||
else
|
||||
DebugPrintf(" Locals : none\n");
|
||||
|
||||
|
@ -2104,7 +2104,7 @@ bool Console::cmdBacktrace(int argc, const char **argv) {
|
|||
|
||||
printf(" argp:ST:%04x", (unsigned)(call.variables_argp - _vm->_gamestate->stack_base));
|
||||
if (call.type == EXEC_STACK_TYPE_CALL)
|
||||
printf(" script: %d", (*(Script *)_vm->_gamestate->segMan->_heap[call.addr.pc.segment]).nr);
|
||||
printf(" script: %d", (*(Script *)_vm->_gamestate->segMan->_heap[call.addr.pc.segment])._nr);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
@ -3090,7 +3090,7 @@ int Console::printObject(reg_t pos) {
|
|||
DebugPrintf(" [%03x] %s = %04x:%04x\n", VM_OBJECT_GET_FUNCSELECTOR(obj, i), selector_name(s, VM_OBJECT_GET_FUNCSELECTOR(obj, i)), PRINT_REG(fptr));
|
||||
}
|
||||
if (s->segMan->_heap[pos.segment]->getType() == MEM_OBJ_SCRIPT)
|
||||
DebugPrintf("\nOwner script:\t%d\n", s->segMan->getScript(pos.segment)->nr);
|
||||
DebugPrintf("\nOwner script:\t%d\n", s->segMan->getScript(pos.segment)->_nr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -48,15 +48,15 @@ struct WorklistManager {
|
|||
}
|
||||
};
|
||||
|
||||
static reg_t_hash_map *normalise_hashmap_ptrs(SegManager *sm, reg_t_hash_map &nonnormal_map) {
|
||||
static reg_t_hash_map *normalise_hashmap_ptrs(SegManager *segMan, reg_t_hash_map &nonnormal_map) {
|
||||
reg_t_hash_map *normal_map = new reg_t_hash_map();
|
||||
|
||||
for (reg_t_hash_map::iterator i = nonnormal_map.begin(); i != nonnormal_map.end(); ++i) {
|
||||
reg_t reg = i->_key;
|
||||
MemObject *mobj = (reg.segment < sm->_heap.size()) ? sm->_heap[reg.segment] : NULL;
|
||||
MemObject *mobj = (reg.segment < segMan->_heap.size()) ? segMan->_heap[reg.segment] : NULL;
|
||||
|
||||
if (mobj) {
|
||||
reg = mobj->findCanonicAddress(sm, reg);
|
||||
reg = mobj->findCanonicAddress(segMan, reg);
|
||||
normal_map->setVal(reg, true);
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ void add_outgoing_refs(void *refcon, reg_t addr) {
|
|||
}
|
||||
|
||||
reg_t_hash_map *find_all_used_references(EngineState *s) {
|
||||
SegManager *sm = s->segMan;
|
||||
SegManager *segMan = s->segMan;
|
||||
reg_t_hash_map *normal_map = NULL;
|
||||
WorklistManager wm;
|
||||
uint i;
|
||||
|
@ -109,14 +109,14 @@ reg_t_hash_map *find_all_used_references(EngineState *s) {
|
|||
debugC(2, kDebugLevelGC, "[GC] -- Finished adding execution stack");
|
||||
|
||||
// Init: Explicitly loaded scripts
|
||||
for (i = 1; i < sm->_heap.size(); i++)
|
||||
if (sm->_heap[i]
|
||||
&& sm->_heap[i]->getType() == MEM_OBJ_SCRIPT) {
|
||||
Script *script = (Script *)sm->_heap[i];
|
||||
for (i = 1; i < segMan->_heap.size(); i++)
|
||||
if (segMan->_heap[i]
|
||||
&& segMan->_heap[i]->getType() == MEM_OBJ_SCRIPT) {
|
||||
Script *script = (Script *)segMan->_heap[i];
|
||||
|
||||
if (script->lockers) { // Explicitly loaded?
|
||||
if (script->getLockers()) { // Explicitly loaded?
|
||||
// Locals, if present
|
||||
wm.push(make_reg(script->locals_segment, 0));
|
||||
wm.push(make_reg(script->_localsSegment, 0));
|
||||
|
||||
// All objects (may be classes, may be indirectly reachable)
|
||||
for (uint obj_nr = 0; obj_nr < script->_objects.size(); obj_nr++) {
|
||||
|
@ -133,13 +133,13 @@ reg_t_hash_map *find_all_used_references(EngineState *s) {
|
|||
wm._worklist.pop_back();
|
||||
if (reg.segment != s->stack_segment) { // No need to repeat this one
|
||||
debugC(2, kDebugLevelGC, "[GC] Checking %04x:%04x\n", PRINT_REG(reg));
|
||||
if (reg.segment < sm->_heap.size() && sm->_heap[reg.segment])
|
||||
sm->_heap[reg.segment]->listAllOutgoingReferences(reg, &wm, add_outgoing_refs, s->resMan->sciVersion());
|
||||
if (reg.segment < segMan->_heap.size() && segMan->_heap[reg.segment])
|
||||
segMan->_heap[reg.segment]->listAllOutgoingReferences(reg, &wm, add_outgoing_refs, s->resMan->sciVersion());
|
||||
}
|
||||
}
|
||||
|
||||
// Normalise
|
||||
normal_map = normalise_hashmap_ptrs(sm, wm._map);
|
||||
normal_map = normalise_hashmap_ptrs(segMan, wm._map);
|
||||
|
||||
return normal_map;
|
||||
}
|
||||
|
@ -172,19 +172,19 @@ void free_unless_used(void *refcon, reg_t addr) {
|
|||
void run_gc(EngineState *s) {
|
||||
uint seg_nr;
|
||||
deallocator_t deallocator;
|
||||
SegManager *sm = s->segMan;
|
||||
SegManager *segMan = s->segMan;
|
||||
|
||||
#ifdef DEBUG_GC
|
||||
debugC(2, kDebugLevelGC, "[GC] Running...\n");
|
||||
memset(&(deallocator.segcount), 0, sizeof(int) * (MEM_OBJ_MAX + 1));
|
||||
#endif
|
||||
|
||||
deallocator.segMan = sm;
|
||||
deallocator.segMan = segMan;
|
||||
deallocator.use_map = find_all_used_references(s);
|
||||
|
||||
for (seg_nr = 1; seg_nr < sm->_heap.size(); seg_nr++) {
|
||||
if (sm->_heap[seg_nr] != NULL) {
|
||||
deallocator.mobj = sm->_heap[seg_nr];
|
||||
for (seg_nr = 1; seg_nr < segMan->_heap.size(); seg_nr++) {
|
||||
if (segMan->_heap[seg_nr] != NULL) {
|
||||
deallocator.mobj = segMan->_heap[seg_nr];
|
||||
#ifdef DEBUG_GC
|
||||
deallocator.segnames[deallocator.mobj->getType()] = deallocator.mobj->type; // FIXME: add a segment "name"
|
||||
#endif
|
||||
|
|
|
@ -641,8 +641,8 @@ int determine_reg_type(SegManager *segMan, reg_t reg, bool allow_invalid) {
|
|||
|
||||
switch (mobj->getType()) {
|
||||
case MEM_OBJ_SCRIPT:
|
||||
if (reg.offset <= (*(Script *)mobj).buf_size && reg.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET
|
||||
&& RAW_IS_OBJECT((*(Script *)mobj).buf + reg.offset)) {
|
||||
if (reg.offset <= (*(Script *)mobj)._bufSize && reg.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET
|
||||
&& RAW_IS_OBJECT((*(Script *)mobj)._buf + reg.offset)) {
|
||||
Object *obj = ((Script *)mobj)->getObject(reg.offset);
|
||||
if (obj)
|
||||
return KSIG_OBJECT;
|
||||
|
|
|
@ -275,7 +275,7 @@ static void bresenham_autodetect(EngineState *s) {
|
|||
return;
|
||||
}
|
||||
|
||||
buf = s->segMan->getScript(fptr.segment)->buf + fptr.offset;
|
||||
buf = s->segMan->getScript(fptr.segment)->_buf + fptr.offset;
|
||||
handle_movecnt = (s->segMan->sciVersion() <= SCI_VERSION_01 || checksum_bytes(buf, 8) == 0x216) ? INCREMENT_MOVECNT : IGNORE_MOVECNT;
|
||||
printf("b-moveCnt action based on checksum: %s\n", handle_movecnt == IGNORE_MOVECNT ? "ignore" : "increment");
|
||||
} else {
|
||||
|
|
|
@ -272,14 +272,14 @@ reg_t kScriptID(EngineState *s, int, int argc, reg_t *argv) {
|
|||
|
||||
scr = s->segMan->getScript(scriptSeg);
|
||||
|
||||
if (!scr->exports_nr) {
|
||||
if (!scr->_numExports) {
|
||||
// FIXME: Is this fatal? This occurs in SQ4CD
|
||||
warning("Script 0x%x does not have a dispatch table", script);
|
||||
return NULL_REG;
|
||||
}
|
||||
|
||||
if (index > scr->exports_nr) {
|
||||
error("Dispatch index too big: %d > %d", index, scr->exports_nr);
|
||||
if (index > scr->_numExports) {
|
||||
error("Dispatch index too big: %d > %d", index, scr->_numExports);
|
||||
return NULL_REG;
|
||||
}
|
||||
|
||||
|
|
|
@ -143,29 +143,29 @@ reg_t kSetSynonyms(EngineState *s, int, int argc, reg_t *argv) {
|
|||
while (node) {
|
||||
reg_t objpos = node->value;
|
||||
int seg;
|
||||
int synonyms_nr = 0;
|
||||
int _numSynonyms = 0;
|
||||
|
||||
script = GET_SEL32V(objpos, number);
|
||||
seg = s->segMan->getScriptSegment(script);
|
||||
|
||||
if (seg >= 0)
|
||||
synonyms_nr = s->segMan->getScript(seg)->getSynonymsNr();
|
||||
_numSynonyms = s->segMan->getScript(seg)->getSynonymsNr();
|
||||
|
||||
if (synonyms_nr) {
|
||||
if (_numSynonyms) {
|
||||
byte *synonyms;
|
||||
|
||||
synonyms = s->segMan->getScript(seg)->getSynonyms();
|
||||
if (synonyms) {
|
||||
debugC(2, kDebugLevelParser, "Setting %d synonyms for script.%d\n",
|
||||
synonyms_nr, script);
|
||||
_numSynonyms, script);
|
||||
|
||||
if (synonyms_nr > 16384) {
|
||||
if (_numSynonyms > 16384) {
|
||||
error("Segtable corruption: script.%03d has %d synonyms",
|
||||
script, synonyms_nr);
|
||||
script, _numSynonyms);
|
||||
/* We used to reset the corrupted value here. I really don't think it's appropriate.
|
||||
* Lars */
|
||||
} else
|
||||
for (int i = 0; i < synonyms_nr; i++) {
|
||||
for (int i = 0; i < _numSynonyms; i++) {
|
||||
synonym_t tmp;
|
||||
tmp.replaceant = (int16)READ_LE_UINT16(synonyms + i * 4);
|
||||
tmp.replacement = (int16)READ_LE_UINT16(synonyms + i * 4 + 2);
|
||||
|
|
|
@ -77,32 +77,57 @@ MemObject *MemObject::createMemObject(MemObjectType type) {
|
|||
return mem;
|
||||
}
|
||||
|
||||
Script::Script() {
|
||||
_nr = 0;
|
||||
_buf = NULL;
|
||||
_bufSize = 0;
|
||||
_scriptSize = 0;
|
||||
_heapSize = 0;
|
||||
|
||||
_synonyms = NULL;
|
||||
_heapStart = NULL;
|
||||
_exportTable = NULL;
|
||||
|
||||
_objIndices = NULL;
|
||||
|
||||
_localsOffset = 0;
|
||||
_localsSegment = 0;
|
||||
_localsBlock = NULL;
|
||||
|
||||
_relocated = false;
|
||||
_markedAsDeleted = 0;
|
||||
}
|
||||
|
||||
Script::~Script() {
|
||||
freeScript();
|
||||
}
|
||||
|
||||
void Script::freeScript() {
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
buf_size = 0;
|
||||
free(_buf);
|
||||
_buf = NULL;
|
||||
_bufSize = 0;
|
||||
|
||||
_objects.clear();
|
||||
|
||||
delete obj_indices;
|
||||
obj_indices = 0;
|
||||
delete _objIndices;
|
||||
_objIndices = 0;
|
||||
_codeBlocks.clear();
|
||||
}
|
||||
|
||||
void Script::init() {
|
||||
locals_offset = 0;
|
||||
locals_block = NULL;
|
||||
_localsOffset = 0;
|
||||
_localsBlock = NULL;
|
||||
|
||||
_codeBlocks.clear();
|
||||
|
||||
_relocated = false;
|
||||
_markedAsDeleted = false;
|
||||
relocated = 0;
|
||||
|
||||
obj_indices = new IntMapper();
|
||||
_objIndices = new IntMapper();
|
||||
}
|
||||
|
||||
Object *Script::allocateObject(uint16 offset) {
|
||||
int idx = obj_indices->checkKey(offset, true);
|
||||
int idx = _objIndices->checkKey(offset, true);
|
||||
if ((uint)idx == _objects.size())
|
||||
_objects.push_back(Object());
|
||||
|
||||
|
@ -110,7 +135,7 @@ Object *Script::allocateObject(uint16 offset) {
|
|||
}
|
||||
|
||||
Object *Script::getObject(uint16 offset) {
|
||||
int idx = obj_indices->checkKey(offset, false);
|
||||
int idx = _objIndices->checkKey(offset, false);
|
||||
if (idx >= 0 && (uint)idx < _objects.size())
|
||||
return &_objects[idx];
|
||||
else
|
||||
|
@ -118,61 +143,61 @@ Object *Script::getObject(uint16 offset) {
|
|||
}
|
||||
|
||||
void Script::incrementLockers() {
|
||||
lockers++;
|
||||
_lockers++;
|
||||
}
|
||||
|
||||
void Script::decrementLockers() {
|
||||
if (lockers > 0)
|
||||
lockers--;
|
||||
if (_lockers > 0)
|
||||
_lockers--;
|
||||
}
|
||||
|
||||
int Script::getLockers() const {
|
||||
return lockers;
|
||||
return _lockers;
|
||||
}
|
||||
|
||||
void Script::setLockers(int lockers_) {
|
||||
lockers = lockers_;
|
||||
void Script::setLockers(int lockers) {
|
||||
_lockers = lockers;
|
||||
}
|
||||
|
||||
void Script::setExportTableOffset(int offset) {
|
||||
if (offset) {
|
||||
export_table = (uint16 *)(buf + offset + 2);
|
||||
exports_nr = READ_LE_UINT16((byte *)(export_table - 1));
|
||||
_exportTable = (uint16 *)(_buf + offset + 2);
|
||||
_numExports = READ_LE_UINT16((byte *)(_exportTable - 1));
|
||||
} else {
|
||||
export_table = NULL;
|
||||
exports_nr = 0;
|
||||
_exportTable = NULL;
|
||||
_numExports = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Script::setSynonymsOffset(int offset) {
|
||||
synonyms = buf + offset;
|
||||
_synonyms = _buf + offset;
|
||||
}
|
||||
|
||||
byte *Script::getSynonyms() const {
|
||||
return synonyms;
|
||||
return _synonyms;
|
||||
}
|
||||
|
||||
void Script::setSynonymsNr(int n) {
|
||||
synonyms_nr = n;
|
||||
_numSynonyms = n;
|
||||
}
|
||||
|
||||
int Script::getSynonymsNr() const {
|
||||
return synonyms_nr;
|
||||
return _numSynonyms;
|
||||
}
|
||||
|
||||
// memory operations
|
||||
|
||||
void Script::mcpyInOut(int dst, const void *src, size_t n) {
|
||||
if (buf) {
|
||||
assert(dst + n <= buf_size);
|
||||
memcpy(buf + dst, src, n);
|
||||
if (_buf) {
|
||||
assert(dst + n <= _bufSize);
|
||||
memcpy(_buf + dst, src, n);
|
||||
}
|
||||
}
|
||||
|
||||
int16 Script::getHeap(uint16 offset) const {
|
||||
assert(offset + 1 < (int)buf_size);
|
||||
return READ_LE_UINT16(buf + offset);
|
||||
// return (buf[offset] | (buf[offset+1]) << 8);
|
||||
assert(offset + 1 < (int)_bufSize);
|
||||
return READ_LE_UINT16(_buf + offset);
|
||||
// return (_buf[offset] | (_buf[offset+1]) << 8);
|
||||
}
|
||||
|
||||
byte *MemObject::dereference(reg_t pointer, int *size) {
|
||||
|
@ -182,18 +207,18 @@ byte *MemObject::dereference(reg_t pointer, int *size) {
|
|||
}
|
||||
|
||||
bool Script::isValidOffset(uint16 offset) const {
|
||||
return offset < buf_size;
|
||||
return offset < _bufSize;
|
||||
}
|
||||
|
||||
byte *Script::dereference(reg_t pointer, int *size) {
|
||||
if (pointer.offset > buf_size) {
|
||||
if (pointer.offset > _bufSize) {
|
||||
warning("Attempt to dereference invalid pointer %04x:%04x into script segment (script size=%d)\n",
|
||||
PRINT_REG(pointer), (uint)buf_size);
|
||||
PRINT_REG(pointer), (uint)_bufSize);
|
||||
return NULL;
|
||||
}
|
||||
if (size)
|
||||
*size = buf_size - pointer.offset;
|
||||
return buf + pointer.offset;
|
||||
*size = _bufSize - pointer.offset;
|
||||
return _buf + pointer.offset;
|
||||
}
|
||||
|
||||
bool LocalVariables::isValidOffset(uint16 offset) const {
|
||||
|
@ -260,12 +285,12 @@ reg_t Script::findCanonicAddress(SegManager *segMan, reg_t addr) {
|
|||
void Script::freeAtAddress(SegManager *segMan, reg_t addr) {
|
||||
/*
|
||||
debugC(2, kDebugLevelGC, "[GC] Freeing script %04x:%04x\n", PRINT_REG(addr));
|
||||
if (locals_segment)
|
||||
debugC(2, kDebugLevelGC, "[GC] Freeing locals %04x:0000\n", locals_segment);
|
||||
if (_localsSegment)
|
||||
debugC(2, kDebugLevelGC, "[GC] Freeing locals %04x:0000\n", _localsSegment);
|
||||
*/
|
||||
|
||||
if (_markedAsDeleted)
|
||||
segMan->deallocateScript(nr);
|
||||
segMan->deallocateScript(_nr);
|
||||
}
|
||||
|
||||
void Script::listAllDeallocatable(SegmentId segId, void *param, NoteCallback note) {
|
||||
|
@ -275,12 +300,12 @@ void Script::listAllDeallocatable(SegmentId segId, void *param, NoteCallback not
|
|||
void Script::listAllOutgoingReferences(reg_t addr, void *param, NoteCallback note, SciVersion version) {
|
||||
Script *script = this;
|
||||
|
||||
if (addr.offset <= script->buf_size && addr.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET && RAW_IS_OBJECT(script->buf + addr.offset)) {
|
||||
if (addr.offset <= script->_bufSize && addr.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET && RAW_IS_OBJECT(script->_buf + addr.offset)) {
|
||||
Object *obj = getObject(addr.offset);
|
||||
if (obj) {
|
||||
// Note all local variables, if we have a local variable environment
|
||||
if (script->locals_segment)
|
||||
(*note)(param, make_reg(script->locals_segment, 0));
|
||||
if (script->_localsSegment)
|
||||
(*note)(param, make_reg(script->_localsSegment, 0));
|
||||
|
||||
for (uint i = 0; i < obj->_variables.size(); i++)
|
||||
(*note)(param, obj->_variables[i]);
|
||||
|
|
|
@ -237,25 +237,28 @@ struct CodeBlock {
|
|||
|
||||
|
||||
|
||||
struct Script : public MemObject {
|
||||
int nr; /**< Script number */
|
||||
byte *buf; /**< Static data buffer, or NULL if not used */
|
||||
size_t buf_size;
|
||||
size_t script_size;
|
||||
size_t heap_size;
|
||||
class Script : public MemObject {
|
||||
public:
|
||||
int _nr; /**< Script number */
|
||||
byte *_buf; /**< Static data buffer, or NULL if not used */
|
||||
size_t _bufSize;
|
||||
size_t _scriptSize;
|
||||
size_t _heapSize;
|
||||
|
||||
byte *synonyms; /**< Synonyms block or 0 if not present*/
|
||||
byte *heap_start; /**< Start of heap if SCI1.1, NULL otherwise */
|
||||
uint16 *export_table; /**< Abs. offset of the export table or 0 if not present */
|
||||
byte *_heapStart; /**< Start of heap if SCI1.1, NULL otherwise */
|
||||
|
||||
uint16 *_exportTable; /**< Abs. offset of the export table or 0 if not present */
|
||||
int _numExports; /**< Number of entries in the exports table */
|
||||
|
||||
byte *_synonyms; /**< Synonyms block or 0 if not present*/
|
||||
int _numSynonyms; /**< Number of entries in the synonyms block */
|
||||
|
||||
protected:
|
||||
IntMapper *obj_indices;
|
||||
int _lockers; /**< Number of classes and objects that require this script */
|
||||
|
||||
IntMapper *_objIndices;
|
||||
|
||||
public:
|
||||
int exports_nr; /**< Number of entries in the exports table */
|
||||
int synonyms_nr; /**< Number of entries in the synonyms block */
|
||||
int lockers; /**< Number of classes and objects that require this script */
|
||||
|
||||
/**
|
||||
* Table for objects, contains property variables.
|
||||
* Indexed by the value stored at SCRIPT_LOCALVARPTR_OFFSET,
|
||||
|
@ -263,39 +266,17 @@ public:
|
|||
*/
|
||||
Common::Array<Object> _objects;
|
||||
|
||||
int locals_offset;
|
||||
int locals_segment; /**< The local variable segment */
|
||||
LocalVariables *locals_block;
|
||||
int _localsOffset;
|
||||
int _localsSegment; /**< The local variable segment */
|
||||
LocalVariables *_localsBlock;
|
||||
|
||||
Common::Array<CodeBlock> _codeBlocks;
|
||||
int relocated;
|
||||
bool _relocated;
|
||||
bool _markedAsDeleted;
|
||||
|
||||
public:
|
||||
Script() {
|
||||
nr = 0;
|
||||
buf = NULL;
|
||||
buf_size = 0;
|
||||
script_size = 0;
|
||||
heap_size = 0;
|
||||
|
||||
synonyms = NULL;
|
||||
heap_start = NULL;
|
||||
export_table = NULL;
|
||||
|
||||
obj_indices = NULL;
|
||||
|
||||
locals_offset = 0;
|
||||
locals_segment = 0;
|
||||
locals_block = NULL;
|
||||
|
||||
relocated = 0;
|
||||
_markedAsDeleted = 0;
|
||||
}
|
||||
|
||||
~Script() {
|
||||
freeScript();
|
||||
}
|
||||
Script();
|
||||
~Script();
|
||||
|
||||
void freeScript();
|
||||
void init();
|
||||
|
|
|
@ -242,7 +242,7 @@ void SegManager::saveLoadWithSerializer(Common::Serializer &s) {
|
|||
|
||||
// If we are loading a script, hook it up in the script->segment map.
|
||||
if (s.isLoading() && type == MEM_OBJ_SCRIPT) {
|
||||
_scriptSegMap[((Script *)mobj)->nr] = i;
|
||||
_scriptSegMap[((Script *)mobj)->_nr] = i;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -379,27 +379,27 @@ void HunkTable::saveLoadWithSerializer(Common::Serializer &s) {
|
|||
}
|
||||
|
||||
void Script::saveLoadWithSerializer(Common::Serializer &s) {
|
||||
s.syncAsSint32LE(nr);
|
||||
s.syncAsUint32LE(buf_size);
|
||||
s.syncAsUint32LE(script_size);
|
||||
s.syncAsUint32LE(heap_size);
|
||||
s.syncAsSint32LE(_nr);
|
||||
s.syncAsUint32LE(_bufSize);
|
||||
s.syncAsUint32LE(_scriptSize);
|
||||
s.syncAsUint32LE(_heapSize);
|
||||
|
||||
// FIXME: revamp obj_indices handling
|
||||
if (!obj_indices) {
|
||||
// FIXME: revamp _objIndices handling
|
||||
if (!_objIndices) {
|
||||
assert(s.isLoading());
|
||||
obj_indices = new IntMapper();
|
||||
_objIndices = new IntMapper();
|
||||
}
|
||||
|
||||
obj_indices->saveLoadWithSerializer(s);
|
||||
_objIndices->saveLoadWithSerializer(s);
|
||||
|
||||
s.syncAsSint32LE(exports_nr);
|
||||
s.syncAsSint32LE(synonyms_nr);
|
||||
s.syncAsSint32LE(lockers);
|
||||
s.syncAsSint32LE(_numExports);
|
||||
s.syncAsSint32LE(_numSynonyms);
|
||||
s.syncAsSint32LE(_lockers);
|
||||
|
||||
syncArray<Object>(s, _objects);
|
||||
|
||||
s.syncAsSint32LE(locals_offset);
|
||||
s.syncAsSint32LE(locals_segment);
|
||||
s.syncAsSint32LE(_localsOffset);
|
||||
s.syncAsSint32LE(_localsSegment);
|
||||
|
||||
s.syncAsSint32LE(_markedAsDeleted);
|
||||
}
|
||||
|
@ -536,17 +536,17 @@ static void reconstruct_stack(EngineState *retval) {
|
|||
static void load_script(EngineState *s, Script *scr) {
|
||||
Resource *script, *heap = NULL;
|
||||
|
||||
scr->buf = (byte *)malloc(scr->buf_size);
|
||||
assert(scr->buf);
|
||||
scr->_buf = (byte *)malloc(scr->_bufSize);
|
||||
assert(scr->_buf);
|
||||
|
||||
script = s->resMan->findResource(ResourceId(kResourceTypeScript, scr->nr), 0);
|
||||
script = s->resMan->findResource(ResourceId(kResourceTypeScript, scr->_nr), 0);
|
||||
if (s->resMan->sciVersion() >= SCI_VERSION_1_1)
|
||||
heap = s->resMan->findResource(ResourceId(kResourceTypeHeap, scr->nr), 0);
|
||||
heap = s->resMan->findResource(ResourceId(kResourceTypeHeap, scr->_nr), 0);
|
||||
|
||||
memcpy(scr->buf, script->data, script->size);
|
||||
memcpy(scr->_buf, script->data, script->size);
|
||||
if (s->resMan->sciVersion() >= SCI_VERSION_1_1) {
|
||||
scr->heap_start = scr->buf + scr->script_size;
|
||||
memcpy(scr->heap_start, heap->data, heap->size);
|
||||
scr->_heapStart = scr->_buf + scr->_scriptSize;
|
||||
memcpy(scr->_heapStart, heap->data, heap->size);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -565,24 +565,24 @@ static void reconstruct_scripts(EngineState *s, SegManager *self) {
|
|||
|
||||
// FIXME: Unify this code with script_instantiate_*
|
||||
load_script(s, scr);
|
||||
scr->locals_block = (scr->locals_segment == 0) ? NULL : (LocalVariables *)(s->segMan->_heap[scr->locals_segment]);
|
||||
scr->_localsBlock = (scr->_localsSegment == 0) ? NULL : (LocalVariables *)(s->segMan->_heap[scr->_localsSegment]);
|
||||
if (s->resMan->sciVersion() >= SCI_VERSION_1_1) {
|
||||
scr->export_table = 0;
|
||||
scr->synonyms = 0;
|
||||
if (READ_LE_UINT16(scr->buf + 6) > 0) {
|
||||
scr->_exportTable = 0;
|
||||
scr->_synonyms = 0;
|
||||
if (READ_LE_UINT16(scr->_buf + 6) > 0) {
|
||||
scr->setExportTableOffset(6);
|
||||
s->segMan->scriptRelocateExportsSci11(i);
|
||||
}
|
||||
} else {
|
||||
scr->export_table = (uint16 *) find_unique_script_block(s, scr->buf, SCI_OBJ_EXPORTS);
|
||||
scr->synonyms = find_unique_script_block(s, scr->buf, SCI_OBJ_SYNONYMS);
|
||||
scr->export_table += 3;
|
||||
scr->_exportTable = (uint16 *) find_unique_script_block(s, scr->_buf, SCI_OBJ_EXPORTS);
|
||||
scr->_synonyms = find_unique_script_block(s, scr->_buf, SCI_OBJ_SYNONYMS);
|
||||
scr->_exportTable += 3;
|
||||
}
|
||||
scr->_codeBlocks.clear();
|
||||
|
||||
for (j = 0; j < scr->_objects.size(); j++) {
|
||||
byte *data = scr->buf + scr->_objects[j].pos.offset;
|
||||
scr->_objects[j].base = scr->buf;
|
||||
byte *data = scr->_buf + scr->_objects[j].pos.offset;
|
||||
scr->_objects[j].base = scr->_buf;
|
||||
scr->_objects[j].base_obj = data;
|
||||
}
|
||||
break;
|
||||
|
@ -601,11 +601,11 @@ static void reconstruct_scripts(EngineState *s, SegManager *self) {
|
|||
Script *scr = (Script *)mobj;
|
||||
|
||||
for (j = 0; j < scr->_objects.size(); j++) {
|
||||
byte *data = scr->buf + scr->_objects[j].pos.offset;
|
||||
byte *data = scr->_buf + scr->_objects[j].pos.offset;
|
||||
|
||||
if (s->resMan->sciVersion() >= SCI_VERSION_1_1) {
|
||||
uint16 *funct_area = (uint16 *) (scr->buf + READ_LE_UINT16( data + 6 ));
|
||||
uint16 *prop_area = (uint16 *) (scr->buf + READ_LE_UINT16( data + 4 ));
|
||||
uint16 *funct_area = (uint16 *) (scr->_buf + READ_LE_UINT16( data + 6 ));
|
||||
uint16 *prop_area = (uint16 *) (scr->_buf + READ_LE_UINT16( data + 4 ));
|
||||
|
||||
scr->_objects[j].base_method = funct_area;
|
||||
scr->_objects[j].base_vars = prop_area;
|
||||
|
@ -617,7 +617,7 @@ static void reconstruct_scripts(EngineState *s, SegManager *self) {
|
|||
|
||||
if (!base_obj) {
|
||||
warning("Object without a base class: Script %d, index %d (reg address %04x:%04x",
|
||||
scr->nr, j, PRINT_REG(scr->_objects[j]._variables[SCRIPT_SPECIES_SELECTOR]));
|
||||
scr->_nr, j, PRINT_REG(scr->_objects[j]._variables[SCRIPT_SPECIES_SELECTOR]));
|
||||
continue;
|
||||
}
|
||||
scr->_objects[j].variable_names_nr = base_obj->_variables.size();
|
||||
|
|
|
@ -117,8 +117,8 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod
|
|||
} else
|
||||
script_entity = (Script *)mobj;
|
||||
|
||||
scr = script_entity->buf;
|
||||
scr_size = script_entity->buf_size;
|
||||
scr = script_entity->_buf;
|
||||
scr_size = script_entity->_bufSize;
|
||||
|
||||
if (pos.offset >= scr_size) {
|
||||
warning("Trying to disassemble beyond end of script");
|
||||
|
@ -350,7 +350,7 @@ void script_debug(EngineState *s, bool bp) {
|
|||
disassemble(s, scriptState.xs->addr.pc, 0, 1);
|
||||
if (scriptState.seeking == kDebugSeekGlobal)
|
||||
printf("Global %d (0x%x) = %04x:%04x\n", scriptState.seekSpecial,
|
||||
scriptState.seekSpecial, PRINT_REG(s->script_000->locals_block->_locals[scriptState.seekSpecial]));
|
||||
scriptState.seekSpecial, PRINT_REG(s->script_000->_localsBlock->_locals[scriptState.seekSpecial]));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -364,8 +364,8 @@ void script_debug(EngineState *s, bool bp) {
|
|||
|
||||
if (mobj) {
|
||||
Script *scr = (Script *)mobj;
|
||||
byte *code_buf = scr->buf;
|
||||
int code_buf_size = scr->buf_size;
|
||||
byte *code_buf = scr->_buf;
|
||||
int code_buf_size = scr->_bufSize;
|
||||
int opcode = scriptState.xs->addr.pc.offset >= code_buf_size ? 0 : code_buf[scriptState.xs->addr.pc.offset];
|
||||
int op = opcode >> 1;
|
||||
int paramb1 = scriptState.xs->addr.pc.offset + 1 >= code_buf_size ? 0 : code_buf[scriptState.xs->addr.pc.offset + 1];
|
||||
|
|
|
@ -138,28 +138,28 @@ void SegManager::setScriptSize(Script &scr, int script_nr) {
|
|||
Resource *heap = _resMan->findResource(ResourceId(kResourceTypeHeap, script_nr), 0);
|
||||
bool oldScriptHeader = (_resMan->sciVersion() == SCI_VERSION_0_EARLY);
|
||||
|
||||
scr.script_size = script->size;
|
||||
scr.heap_size = 0; // Set later
|
||||
scr._scriptSize = script->size;
|
||||
scr._heapSize = 0; // Set later
|
||||
|
||||
if (!script || (_resMan->sciVersion() >= SCI_VERSION_1_1 && !heap)) {
|
||||
error("SegManager::setScriptSize: failed to load %s", !script ? "script" : "heap");
|
||||
}
|
||||
if (oldScriptHeader) {
|
||||
scr.buf_size = script->size + READ_LE_UINT16(script->data) * 2;
|
||||
scr._bufSize = script->size + READ_LE_UINT16(script->data) * 2;
|
||||
//locals_size = READ_LE_UINT16(script->data) * 2;
|
||||
} else if (_resMan->sciVersion() < SCI_VERSION_1_1) {
|
||||
scr.buf_size = script->size;
|
||||
scr._bufSize = script->size;
|
||||
} else {
|
||||
scr.buf_size = script->size + heap->size;
|
||||
scr.heap_size = heap->size;
|
||||
scr._bufSize = script->size + heap->size;
|
||||
scr._heapSize = heap->size;
|
||||
|
||||
// Ensure that the start of the heap resource can be word-aligned.
|
||||
if (script->size & 2) {
|
||||
scr.buf_size++;
|
||||
scr.script_size++;
|
||||
scr._bufSize++;
|
||||
scr._scriptSize++;
|
||||
}
|
||||
|
||||
if (scr.buf_size > 65535) {
|
||||
if (scr._bufSize > 65535) {
|
||||
error("Script and heap sizes combined exceed 64K."
|
||||
"This means a fundamental design bug was made in SCI\n"
|
||||
"regarding SCI1.1 games.\nPlease report this so it can be"
|
||||
|
@ -170,29 +170,29 @@ void SegManager::setScriptSize(Script &scr, int script_nr) {
|
|||
}
|
||||
|
||||
int SegManager::initialiseScript(Script &scr, int script_nr) {
|
||||
// allocate the script.buf
|
||||
// allocate the script._buf
|
||||
|
||||
setScriptSize(scr, script_nr);
|
||||
scr.buf = (byte *)malloc(scr.buf_size);
|
||||
scr._buf = (byte *)malloc(scr._bufSize);
|
||||
|
||||
#ifdef DEBUG_segMan
|
||||
printf("scr.buf = %p ", scr.buf);
|
||||
printf("scr._buf = %p ", scr._buf);
|
||||
#endif
|
||||
if (!scr.buf) {
|
||||
if (!scr._buf) {
|
||||
scr.freeScript();
|
||||
warning("SegManager: Not enough memory space for script size");
|
||||
scr.buf_size = 0;
|
||||
scr._bufSize = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Initialize objects
|
||||
scr.init();
|
||||
scr.nr = script_nr;
|
||||
scr._nr = script_nr;
|
||||
|
||||
if (_resMan->sciVersion() >= SCI_VERSION_1_1)
|
||||
scr.heap_start = scr.buf + scr.script_size;
|
||||
scr._heapStart = scr._buf + scr._scriptSize;
|
||||
else
|
||||
scr.heap_start = scr.buf;
|
||||
scr._heapStart = scr._buf;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -205,9 +205,9 @@ int SegManager::deallocate(SegmentId seg, bool recursive) {
|
|||
|
||||
if (mobj->getType() == MEM_OBJ_SCRIPT) {
|
||||
Script *scr = (Script *)mobj;
|
||||
_scriptSegMap.erase(scr->nr);
|
||||
if (recursive && scr->locals_segment)
|
||||
deallocate(scr->locals_segment, recursive);
|
||||
_scriptSegMap.erase(scr->_nr);
|
||||
if (recursive && scr->_localsSegment)
|
||||
deallocate(scr->_localsSegment, recursive);
|
||||
}
|
||||
|
||||
delete mobj;
|
||||
|
@ -282,8 +282,8 @@ Object *SegManager::getObject(reg_t pos) {
|
|||
obj = &(ct->_table[pos.offset]);
|
||||
} else if (mobj->getType() == MEM_OBJ_SCRIPT) {
|
||||
Script *scr = (Script *)mobj;
|
||||
if (pos.offset <= scr->buf_size && pos.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET
|
||||
&& RAW_IS_OBJECT(scr->buf + pos.offset)) {
|
||||
if (pos.offset <= scr->_bufSize && pos.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET
|
||||
&& RAW_IS_OBJECT(scr->_buf + pos.offset)) {
|
||||
obj = scr->getObject(pos.offset);
|
||||
}
|
||||
}
|
||||
|
@ -349,14 +349,14 @@ int SegManager::relocateBlock(Common::Array<reg_t> &block, int block_location, S
|
|||
}
|
||||
block[idx].segment = segment; // Perform relocation
|
||||
if (_resMan->sciVersion() >= SCI_VERSION_1_1)
|
||||
block[idx].offset += getScript(segment)->script_size;
|
||||
block[idx].offset += getScript(segment)->_scriptSize;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SegManager::relocateLocal(Script *scr, SegmentId segment, int location) {
|
||||
if (scr->locals_block)
|
||||
return relocateBlock(scr->locals_block->_locals, scr->locals_offset, segment, location);
|
||||
if (scr->_localsBlock)
|
||||
return relocateBlock(scr->_localsBlock->_locals, scr->_localsOffset, segment, location);
|
||||
else
|
||||
return 0; // No hands, no cookies
|
||||
}
|
||||
|
@ -370,20 +370,20 @@ void SegManager::scriptAddCodeBlock(reg_t location) {
|
|||
|
||||
CodeBlock cb;
|
||||
cb.pos = location;
|
||||
cb.size = READ_LE_UINT16(scr->buf + location.offset - 2);
|
||||
cb.size = READ_LE_UINT16(scr->_buf + location.offset - 2);
|
||||
scr->_codeBlocks.push_back(cb);
|
||||
}
|
||||
|
||||
void SegManager::scriptRelocate(reg_t block) {
|
||||
Script *scr = getScript(block.segment);
|
||||
|
||||
VERIFY(block.offset < (uint16)scr->buf_size && READ_LE_UINT16(scr->buf + block.offset) * 2 + block.offset < (uint16)scr->buf_size,
|
||||
VERIFY(block.offset < (uint16)scr->_bufSize && READ_LE_UINT16(scr->_buf + block.offset) * 2 + block.offset < (uint16)scr->_bufSize,
|
||||
"Relocation block outside of script\n");
|
||||
|
||||
int count = READ_LE_UINT16(scr->buf + block.offset);
|
||||
int count = READ_LE_UINT16(scr->_buf + block.offset);
|
||||
|
||||
for (int i = 0; i <= count; i++) {
|
||||
int pos = READ_LE_UINT16(scr->buf + block.offset + 2 + (i * 2));
|
||||
int pos = READ_LE_UINT16(scr->_buf + block.offset + 2 + (i * 2));
|
||||
if (!pos)
|
||||
continue; // FIXME: A hack pending investigation
|
||||
|
||||
|
@ -405,8 +405,8 @@ void SegManager::scriptRelocate(reg_t block) {
|
|||
if (!done) {
|
||||
printf("While processing relocation block %04x:%04x:\n", PRINT_REG(block));
|
||||
printf("Relocation failed for index %04x (%d/%d)\n", pos, i + 1, count);
|
||||
if (scr->locals_block)
|
||||
printf("- locals: %d at %04x\n", scr->locals_block->_locals.size(), scr->locals_offset);
|
||||
if (scr->_localsBlock)
|
||||
printf("- locals: %d at %04x\n", scr->_localsBlock->_locals.size(), scr->_localsOffset);
|
||||
else
|
||||
printf("- No locals\n");
|
||||
for (k = 0; k < scr->_objects.size(); k++)
|
||||
|
@ -421,16 +421,16 @@ void SegManager::scriptRelocate(reg_t block) {
|
|||
void SegManager::heapRelocate(reg_t block) {
|
||||
Script *scr = getScript(block.segment);
|
||||
|
||||
VERIFY(block.offset < (uint16)scr->heap_size && READ_LE_UINT16(scr->heap_start + block.offset) * 2 + block.offset < (uint16)scr->buf_size,
|
||||
VERIFY(block.offset < (uint16)scr->_heapSize && READ_LE_UINT16(scr->_heapStart + block.offset) * 2 + block.offset < (uint16)scr->_bufSize,
|
||||
"Relocation block outside of script\n");
|
||||
|
||||
if (scr->relocated)
|
||||
if (scr->_relocated)
|
||||
return;
|
||||
scr->relocated = 1;
|
||||
int count = READ_LE_UINT16(scr->heap_start + block.offset);
|
||||
scr->_relocated = true;
|
||||
int count = READ_LE_UINT16(scr->_heapStart + block.offset);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
int pos = READ_LE_UINT16(scr->heap_start + block.offset + 2 + (i * 2)) + scr->script_size;
|
||||
int pos = READ_LE_UINT16(scr->_heapStart + block.offset + 2 + (i * 2)) + scr->_scriptSize;
|
||||
|
||||
if (!relocateLocal(scr, block.segment, pos)) {
|
||||
bool done = false;
|
||||
|
@ -444,8 +444,8 @@ void SegManager::heapRelocate(reg_t block) {
|
|||
if (!done) {
|
||||
printf("While processing relocation block %04x:%04x:\n", PRINT_REG(block));
|
||||
printf("Relocation failed for index %04x (%d/%d)\n", pos, i + 1, count);
|
||||
if (scr->locals_block)
|
||||
printf("- locals: %d at %04x\n", scr->locals_block->_locals.size(), scr->locals_offset);
|
||||
if (scr->_localsBlock)
|
||||
printf("- locals: %d at %04x\n", scr->_localsBlock->_locals.size(), scr->_localsOffset);
|
||||
else
|
||||
printf("- No locals\n");
|
||||
for (k = 0; k < scr->_objects.size(); k++)
|
||||
|
@ -511,14 +511,14 @@ Object *SegManager::scriptObjInit0(reg_t obj_pos) {
|
|||
|
||||
Script *scr = getScript(obj_pos.segment);
|
||||
|
||||
VERIFY(base < scr->buf_size, "Attempt to initialize object beyond end of script\n");
|
||||
VERIFY(base < scr->_bufSize, "Attempt to initialize object beyond end of script\n");
|
||||
|
||||
obj = scr->allocateObject(base);
|
||||
|
||||
VERIFY(base + SCRIPT_FUNCTAREAPTR_OFFSET < scr->buf_size, "Function area pointer stored beyond end of script\n");
|
||||
VERIFY(base + SCRIPT_FUNCTAREAPTR_OFFSET < scr->_bufSize, "Function area pointer stored beyond end of script\n");
|
||||
|
||||
{
|
||||
byte *data = (byte *)(scr->buf + base);
|
||||
byte *data = (byte *)(scr->_buf + base);
|
||||
int funct_area = READ_LE_UINT16(data + SCRIPT_FUNCTAREAPTR_OFFSET);
|
||||
int variables_nr;
|
||||
int functions_nr;
|
||||
|
@ -528,7 +528,7 @@ Object *SegManager::scriptObjInit0(reg_t obj_pos) {
|
|||
obj->flags = 0;
|
||||
obj->pos = make_reg(obj_pos.segment, base);
|
||||
|
||||
VERIFY(base + funct_area < scr->buf_size, "Function area pointer references beyond end of script");
|
||||
VERIFY(base + funct_area < scr->_bufSize, "Function area pointer references beyond end of script");
|
||||
|
||||
variables_nr = READ_LE_UINT16(data + SCRIPT_SELECTORCTR_OFFSET);
|
||||
functions_nr = READ_LE_UINT16(data + funct_area - 2);
|
||||
|
@ -536,12 +536,12 @@ Object *SegManager::scriptObjInit0(reg_t obj_pos) {
|
|||
|
||||
VERIFY(base + funct_area + functions_nr * 2
|
||||
// add again for classes, since those also store selectors
|
||||
+ (is_class ? functions_nr * 2 : 0) < scr->buf_size, "Function area extends beyond end of script");
|
||||
+ (is_class ? functions_nr * 2 : 0) < scr->_bufSize, "Function area extends beyond end of script");
|
||||
|
||||
obj->_variables.resize(variables_nr);
|
||||
|
||||
obj->methods_nr = functions_nr;
|
||||
obj->base = scr->buf;
|
||||
obj->base = scr->_buf;
|
||||
obj->base_obj = data;
|
||||
obj->base_method = (uint16 *)(data + funct_area);
|
||||
obj->base_vars = NULL;
|
||||
|
@ -559,16 +559,16 @@ Object *SegManager::scriptObjInit11(reg_t obj_pos) {
|
|||
|
||||
Script *scr = getScript(obj_pos.segment);
|
||||
|
||||
VERIFY(base < scr->buf_size, "Attempt to initialize object beyond end of script\n");
|
||||
VERIFY(base < scr->_bufSize, "Attempt to initialize object beyond end of script\n");
|
||||
|
||||
obj = scr->allocateObject(base);
|
||||
|
||||
VERIFY(base + SCRIPT_FUNCTAREAPTR_OFFSET < scr->buf_size, "Function area pointer stored beyond end of script\n");
|
||||
VERIFY(base + SCRIPT_FUNCTAREAPTR_OFFSET < scr->_bufSize, "Function area pointer stored beyond end of script\n");
|
||||
|
||||
{
|
||||
byte *data = (byte *)(scr->buf + base);
|
||||
uint16 *funct_area = (uint16 *)(scr->buf + READ_LE_UINT16(data + 6));
|
||||
uint16 *prop_area = (uint16 *)(scr->buf + READ_LE_UINT16(data + 4));
|
||||
byte *data = (byte *)(scr->_buf + base);
|
||||
uint16 *funct_area = (uint16 *)(scr->_buf + READ_LE_UINT16(data + 6));
|
||||
uint16 *prop_area = (uint16 *)(scr->_buf + READ_LE_UINT16(data + 4));
|
||||
int variables_nr;
|
||||
int functions_nr;
|
||||
int is_class;
|
||||
|
@ -577,7 +577,7 @@ Object *SegManager::scriptObjInit11(reg_t obj_pos) {
|
|||
obj->flags = 0;
|
||||
obj->pos = obj_pos;
|
||||
|
||||
VERIFY((byte *) funct_area < scr->buf + scr->buf_size, "Function area pointer references beyond end of script");
|
||||
VERIFY((byte *) funct_area < scr->_buf + scr->_bufSize, "Function area pointer references beyond end of script");
|
||||
|
||||
variables_nr = READ_LE_UINT16(data + 2);
|
||||
functions_nr = READ_LE_UINT16(funct_area);
|
||||
|
@ -586,13 +586,13 @@ Object *SegManager::scriptObjInit11(reg_t obj_pos) {
|
|||
obj->base_method = funct_area;
|
||||
obj->base_vars = prop_area;
|
||||
|
||||
VERIFY(((byte *) funct_area + functions_nr) < scr->buf + scr->buf_size, "Function area extends beyond end of script");
|
||||
VERIFY(((byte *) funct_area + functions_nr) < scr->_buf + scr->_bufSize, "Function area extends beyond end of script");
|
||||
|
||||
obj->variable_names_nr = variables_nr;
|
||||
obj->_variables.resize(variables_nr);
|
||||
|
||||
obj->methods_nr = functions_nr;
|
||||
obj->base = scr->buf;
|
||||
obj->base = scr->_buf;
|
||||
obj->base_obj = data;
|
||||
|
||||
for (i = 0; i < variables_nr; i++)
|
||||
|
@ -611,22 +611,22 @@ Object *SegManager::scriptObjInit(reg_t obj_pos) {
|
|||
|
||||
LocalVariables *SegManager::allocLocalsSegment(Script *scr, int count) {
|
||||
if (!count) { // No locals
|
||||
scr->locals_segment = 0;
|
||||
scr->locals_block = NULL;
|
||||
scr->_localsSegment = 0;
|
||||
scr->_localsBlock = NULL;
|
||||
return NULL;
|
||||
} else {
|
||||
LocalVariables *locals;
|
||||
|
||||
if (scr->locals_segment) {
|
||||
locals = (LocalVariables *)_heap[scr->locals_segment];
|
||||
if (scr->_localsSegment) {
|
||||
locals = (LocalVariables *)_heap[scr->_localsSegment];
|
||||
VERIFY(locals != NULL, "Re-used locals segment was NULL'd out");
|
||||
VERIFY(locals->getType() == MEM_OBJ_LOCALS, "Re-used locals segment did not consist of local variables");
|
||||
VERIFY(locals->script_id == scr->nr, "Re-used locals segment belonged to other script");
|
||||
VERIFY(locals->script_id == scr->_nr, "Re-used locals segment belonged to other script");
|
||||
} else
|
||||
locals = (LocalVariables *)allocSegment(MEM_OBJ_LOCALS, &scr->locals_segment);
|
||||
locals = (LocalVariables *)allocSegment(MEM_OBJ_LOCALS, &scr->_localsSegment);
|
||||
|
||||
scr->locals_block = locals;
|
||||
locals->script_id = scr->nr;
|
||||
scr->_localsBlock = locals;
|
||||
locals->script_id = scr->_nr;
|
||||
locals->_locals.resize(count);
|
||||
|
||||
return locals;
|
||||
|
@ -636,7 +636,7 @@ LocalVariables *SegManager::allocLocalsSegment(Script *scr, int count) {
|
|||
void SegManager::scriptInitialiseLocalsZero(SegmentId seg, int count) {
|
||||
Script *scr = getScript(seg);
|
||||
|
||||
scr->locals_offset = -count * 2; // Make sure it's invalid
|
||||
scr->_localsOffset = -count * 2; // Make sure it's invalid
|
||||
|
||||
allocLocalsSegment(scr, count);
|
||||
}
|
||||
|
@ -645,25 +645,25 @@ void SegManager::scriptInitialiseLocals(reg_t location) {
|
|||
Script *scr = getScript(location.segment);
|
||||
unsigned int count;
|
||||
|
||||
VERIFY(location.offset + 1 < (uint16)scr->buf_size, "Locals beyond end of script\n");
|
||||
VERIFY(location.offset + 1 < (uint16)scr->_bufSize, "Locals beyond end of script\n");
|
||||
|
||||
if (_resMan->sciVersion() >= SCI_VERSION_1_1)
|
||||
count = READ_LE_UINT16(scr->buf + location.offset - 2);
|
||||
count = READ_LE_UINT16(scr->_buf + location.offset - 2);
|
||||
else
|
||||
count = (READ_LE_UINT16(scr->buf + location.offset - 2) - 4) >> 1;
|
||||
count = (READ_LE_UINT16(scr->_buf + location.offset - 2) - 4) >> 1;
|
||||
// half block size
|
||||
|
||||
scr->locals_offset = location.offset;
|
||||
scr->_localsOffset = location.offset;
|
||||
|
||||
if (!(location.offset + count * 2 + 1 < scr->buf_size)) {
|
||||
warning("Locals extend beyond end of script: offset %04x, count %x vs size %x", location.offset, count, (uint)scr->buf_size);
|
||||
count = (scr->buf_size - location.offset) >> 1;
|
||||
if (!(location.offset + count * 2 + 1 < scr->_bufSize)) {
|
||||
warning("Locals extend beyond end of script: offset %04x, count %x vs size %x", location.offset, count, (uint)scr->_bufSize);
|
||||
count = (scr->_bufSize - location.offset) >> 1;
|
||||
}
|
||||
|
||||
LocalVariables *locals = allocLocalsSegment(scr, count);
|
||||
if (locals) {
|
||||
uint i;
|
||||
byte *base = (byte *)(scr->buf + location.offset);
|
||||
byte *base = (byte *)(scr->_buf + location.offset);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
locals->_locals[i].offset = READ_LE_UINT16(base + i * 2);
|
||||
|
@ -672,13 +672,13 @@ void SegManager::scriptInitialiseLocals(reg_t location) {
|
|||
|
||||
void SegManager::scriptRelocateExportsSci11(SegmentId seg) {
|
||||
Script *scr = getScript(seg);
|
||||
for (int i = 0; i < scr->exports_nr; i++) {
|
||||
for (int i = 0; i < scr->_numExports; i++) {
|
||||
/* We are forced to use an ugly heuristic here to distinguish function
|
||||
exports from object/class exports. The former kind points into the
|
||||
script resource, the latter into the heap resource. */
|
||||
uint16 location = READ_LE_UINT16((byte *)(scr->export_table + i));
|
||||
if ((location < scr->heap_size - 1) && (READ_LE_UINT16(scr->heap_start + location) == SCRIPT_OBJECT_MAGIC_NUMBER)) {
|
||||
WRITE_LE_UINT16((byte *)(scr->export_table + i), location + scr->heap_start - scr->buf);
|
||||
uint16 location = READ_LE_UINT16((byte *)(scr->_exportTable + i));
|
||||
if ((location < scr->_heapSize - 1) && (READ_LE_UINT16(scr->_heapStart + location) == SCRIPT_OBJECT_MAGIC_NUMBER)) {
|
||||
WRITE_LE_UINT16((byte *)(scr->_exportTable + i), location + scr->_heapStart - scr->_buf);
|
||||
} else {
|
||||
// Otherwise it's probably a function export,
|
||||
// and we don't need to do anything.
|
||||
|
@ -688,17 +688,17 @@ void SegManager::scriptRelocateExportsSci11(SegmentId seg) {
|
|||
|
||||
void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) {
|
||||
Script *scr = getScript(seg);
|
||||
byte *seeker = scr->heap_start + 4 + READ_LE_UINT16(scr->heap_start + 2) * 2;
|
||||
byte *seeker = scr->_heapStart + 4 + READ_LE_UINT16(scr->_heapStart + 2) * 2;
|
||||
SciVersion version = _resMan->sciVersion(); // for the selector defines
|
||||
|
||||
while (READ_LE_UINT16(seeker) == SCRIPT_OBJECT_MAGIC_NUMBER) {
|
||||
if (READ_LE_UINT16(seeker + 14) & SCRIPT_INFO_CLASS) {
|
||||
int classpos = seeker - scr->buf;
|
||||
int classpos = seeker - scr->_buf;
|
||||
int species = READ_LE_UINT16(seeker + 10);
|
||||
|
||||
if (species < 0 || species >= (int)_classtable.size()) {
|
||||
error("Invalid species %d(0x%x) not in interval [0,%d) while instantiating script %d",
|
||||
species, species, _classtable.size(), scr->nr);
|
||||
species, species, _classtable.size(), scr->_nr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -708,13 +708,13 @@ void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) {
|
|||
seeker += READ_LE_UINT16(seeker + 2) * 2;
|
||||
}
|
||||
|
||||
seeker = scr->heap_start + 4 + READ_LE_UINT16(scr->heap_start + 2) * 2;
|
||||
seeker = scr->_heapStart + 4 + READ_LE_UINT16(scr->_heapStart + 2) * 2;
|
||||
while (READ_LE_UINT16(seeker) == SCRIPT_OBJECT_MAGIC_NUMBER) {
|
||||
reg_t reg;
|
||||
Object *obj;
|
||||
|
||||
reg.segment = seg;
|
||||
reg.offset = seeker - scr->buf;
|
||||
reg.offset = seeker - scr->_buf;
|
||||
obj = scriptObjInit(reg);
|
||||
|
||||
#if 0
|
||||
|
@ -736,7 +736,7 @@ void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) {
|
|||
// uses this selector together with -propDict- to compare classes.
|
||||
// For the purpose of Obj::isKindOf, using the script number appears
|
||||
// to be sufficient.
|
||||
obj->_variables[SCRIPT_CLASSSCRIPT_SELECTOR] = make_reg(0, scr->nr);
|
||||
obj->_variables[SCRIPT_CLASSSCRIPT_SELECTOR] = make_reg(0, scr->_nr);
|
||||
|
||||
seeker += READ_LE_UINT16(seeker + 2) * 2;
|
||||
}
|
||||
|
@ -779,15 +779,15 @@ SegmentId SegManager::allocateStringFrags() {
|
|||
|
||||
uint16 SegManager::validateExportFunc(int pubfunct, SegmentId seg) {
|
||||
Script *scr = getScript(seg);
|
||||
if (scr->exports_nr <= pubfunct) {
|
||||
if (scr->_numExports <= pubfunct) {
|
||||
warning("validateExportFunc(): pubfunct is invalid");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (_exportsAreWide)
|
||||
pubfunct *= 2;
|
||||
uint16 offset = READ_LE_UINT16((byte *)(scr->export_table + pubfunct));
|
||||
VERIFY(offset < scr->buf_size, "invalid export function pointer");
|
||||
uint16 offset = READ_LE_UINT16((byte *)(scr->_exportTable + pubfunct));
|
||||
VERIFY(offset < scr->_bufSize, "invalid export function pointer");
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@ EngineState::~EngineState() {
|
|||
}
|
||||
|
||||
uint16 EngineState::currentRoomNumber() const {
|
||||
return script_000->locals_block->_locals[13].toUint16();
|
||||
return script_000->_localsBlock->_locals[13].toUint16();
|
||||
}
|
||||
|
||||
kLanguage EngineState::charToLanguage(const char c) const {
|
||||
|
@ -251,15 +251,15 @@ int EngineState::methodChecksum(reg_t objAddress, Selector sel, int offset, uint
|
|||
|
||||
Script *script = segMan->getScript(fptr.segment);
|
||||
|
||||
if (!script->buf || (fptr.offset + offset < 0))
|
||||
if (!script->_buf || (fptr.offset + offset < 0))
|
||||
return -1;
|
||||
|
||||
fptr.offset += offset;
|
||||
|
||||
if (fptr.offset + size > script->buf_size)
|
||||
if (fptr.offset + size > script->_bufSize)
|
||||
return -1;
|
||||
|
||||
byte *buf = script->buf + fptr.offset;
|
||||
byte *buf = script->_buf + fptr.offset;
|
||||
|
||||
uint sum = 0;
|
||||
for (uint i = 0; i < size; i++)
|
||||
|
@ -359,7 +359,7 @@ SciVersion EngineState::detectLofsType() {
|
|||
|
||||
Script *script = segMan->getScript(fptr.segment);
|
||||
|
||||
if ((script == NULL) || (script->buf == NULL))
|
||||
if ((script == NULL) || (script->_buf == NULL))
|
||||
continue;
|
||||
|
||||
uint offset = fptr.offset;
|
||||
|
@ -367,10 +367,10 @@ SciVersion EngineState::detectLofsType() {
|
|||
|
||||
while (!done) {
|
||||
// Read opcode
|
||||
if (offset >= script->buf_size)
|
||||
if (offset >= script->_bufSize)
|
||||
break;
|
||||
|
||||
byte opcode = script->buf[offset++];
|
||||
byte opcode = script->_buf[offset++];
|
||||
byte opnumber = opcode >> 1;
|
||||
|
||||
if ((opnumber == 0x39) || (opnumber == 0x3a)) {
|
||||
|
@ -378,24 +378,24 @@ SciVersion EngineState::detectLofsType() {
|
|||
|
||||
// Load lofs operand
|
||||
if (opcode & 1) {
|
||||
if (offset >= script->buf_size)
|
||||
if (offset >= script->_bufSize)
|
||||
break;
|
||||
lofs = script->buf[offset++];
|
||||
lofs = script->_buf[offset++];
|
||||
} else {
|
||||
if (offset + 1 >= script->buf_size)
|
||||
if (offset + 1 >= script->_bufSize)
|
||||
break;
|
||||
lofs = READ_LE_UINT16(script->buf + offset);
|
||||
lofs = READ_LE_UINT16(script->_buf + offset);
|
||||
offset += 2;
|
||||
}
|
||||
|
||||
// Check for going out of bounds when interpreting as abs/rel
|
||||
if (lofs >= script->buf_size)
|
||||
if (lofs >= script->_bufSize)
|
||||
couldBeAbs = false;
|
||||
|
||||
if ((signed)offset + (int16)lofs < 0)
|
||||
couldBeRel = false;
|
||||
|
||||
if ((signed)offset + (int16)lofs >= (signed)script->buf_size)
|
||||
if ((signed)offset + (int16)lofs >= (signed)script->_bufSize)
|
||||
couldBeRel = false;
|
||||
|
||||
continue;
|
||||
|
|
|
@ -425,17 +425,17 @@ ExecStack *add_exec_stack_varselector(EngineState *s, reg_t objp, int argc, Stac
|
|||
}
|
||||
|
||||
ExecStack *add_exec_stack_entry(EngineState *s, reg_t pc, StackPtr sp, reg_t objp, int argc,
|
||||
StackPtr argp, Selector selector, reg_t sendp, int origin, SegmentId locals_segment) {
|
||||
StackPtr argp, Selector selector, reg_t sendp, int origin, SegmentId _localsSegment) {
|
||||
// Returns new TOS element for the execution stack
|
||||
// locals_segment may be -1 if derived from the called object
|
||||
// _localsSegment may be -1 if derived from the called object
|
||||
|
||||
//printf("Exec stack: [%d/%d], origin %d, at %p\n", s->execution_stack_pos, s->_executionStack.size(), origin, s->execution_stack);
|
||||
|
||||
ExecStack xstack;
|
||||
|
||||
xstack.objp = objp;
|
||||
if (locals_segment != SCI_XS_CALLEE_LOCALS)
|
||||
xstack.local_segment = locals_segment;
|
||||
if (_localsSegment != SCI_XS_CALLEE_LOCALS)
|
||||
xstack.local_segment = _localsSegment;
|
||||
else
|
||||
xstack.local_segment = pc.segment;
|
||||
|
||||
|
@ -531,19 +531,19 @@ void run_vm(EngineState *s, int restoring) {
|
|||
|
||||
#ifndef DISABLE_VALIDATIONS
|
||||
// Initialize maximum variable count
|
||||
if (s->script_000->locals_block)
|
||||
scriptState.variables_max[VAR_GLOBAL] = s->script_000->locals_block->_locals.size();
|
||||
if (s->script_000->_localsBlock)
|
||||
scriptState.variables_max[VAR_GLOBAL] = s->script_000->_localsBlock->_locals.size();
|
||||
else
|
||||
scriptState.variables_max[VAR_GLOBAL] = 0;
|
||||
#endif
|
||||
|
||||
scriptState.variables_seg[VAR_GLOBAL] = s->script_000->locals_segment;
|
||||
scriptState.variables_seg[VAR_GLOBAL] = s->script_000->_localsSegment;
|
||||
scriptState.variables_seg[VAR_TEMP] = scriptState.variables_seg[VAR_PARAM] = s->stack_segment;
|
||||
scriptState.variables_base[VAR_TEMP] = scriptState.variables_base[VAR_PARAM] = s->stack_base;
|
||||
|
||||
// SCI code reads the zeroeth argument to determine argc
|
||||
if (s->script_000->locals_block)
|
||||
scriptState.variables_base[VAR_GLOBAL] = scriptState.variables[VAR_GLOBAL] = s->script_000->locals_block->_locals.begin();
|
||||
if (s->script_000->_localsBlock)
|
||||
scriptState.variables_base[VAR_GLOBAL] = scriptState.variables[VAR_GLOBAL] = s->script_000->_localsBlock->_locals.begin();
|
||||
else
|
||||
scriptState.variables_base[VAR_GLOBAL] = scriptState.variables[VAR_GLOBAL] = NULL;
|
||||
|
||||
|
@ -577,9 +577,9 @@ void run_vm(EngineState *s, int restoring) {
|
|||
obj = NULL;
|
||||
} else {
|
||||
obj = s->segMan->getObject(scriptState.xs->objp);
|
||||
code_buf = scr->buf;
|
||||
code_buf = scr->_buf;
|
||||
#ifndef DISABLE_VALIDATIONS
|
||||
code_buf_size = scr->buf_size;
|
||||
code_buf_size = scr->_bufSize;
|
||||
#endif
|
||||
local_script = s->segMan->getScriptIfLoaded(scriptState.xs->local_segment);
|
||||
if (!local_script) {
|
||||
|
@ -591,14 +591,14 @@ void run_vm(EngineState *s, int restoring) {
|
|||
#endif
|
||||
} else {
|
||||
|
||||
scriptState.variables_seg[VAR_LOCAL] = local_script->locals_segment;
|
||||
if (local_script->locals_block)
|
||||
scriptState.variables_base[VAR_LOCAL] = scriptState.variables[VAR_LOCAL] = local_script->locals_block->_locals.begin();
|
||||
scriptState.variables_seg[VAR_LOCAL] = local_script->_localsSegment;
|
||||
if (local_script->_localsBlock)
|
||||
scriptState.variables_base[VAR_LOCAL] = scriptState.variables[VAR_LOCAL] = local_script->_localsBlock->_locals.begin();
|
||||
else
|
||||
scriptState.variables_base[VAR_LOCAL] = scriptState.variables[VAR_LOCAL] = NULL;
|
||||
#ifndef DISABLE_VALIDATIONS
|
||||
if (local_script->locals_block)
|
||||
scriptState.variables_max[VAR_LOCAL] = local_script->locals_block->_locals.size();
|
||||
if (local_script->_localsBlock)
|
||||
scriptState.variables_max[VAR_LOCAL] = local_script->_localsBlock->_locals.size();
|
||||
else
|
||||
scriptState.variables_max[VAR_LOCAL] = 0;
|
||||
scriptState.variables_max[VAR_TEMP] = scriptState.xs->sp - scriptState.xs->fp;
|
||||
|
@ -1158,7 +1158,7 @@ void run_vm(EngineState *s, int restoring) {
|
|||
|
||||
switch (s->detectLofsType()) {
|
||||
case SCI_VERSION_1_1:
|
||||
s->r_acc.offset = opparams[0] + local_script->script_size;
|
||||
s->r_acc.offset = opparams[0] + local_script->_scriptSize;
|
||||
break;
|
||||
case SCI_VERSION_1_MIDDLE:
|
||||
s->r_acc.offset = opparams[0];
|
||||
|
@ -1180,7 +1180,7 @@ void run_vm(EngineState *s, int restoring) {
|
|||
|
||||
switch (s->detectLofsType()) {
|
||||
case SCI_VERSION_1_1:
|
||||
r_temp.offset = opparams[0] + local_script->script_size;
|
||||
r_temp.offset = opparams[0] + local_script->_scriptSize;
|
||||
break;
|
||||
case SCI_VERSION_1_MIDDLE:
|
||||
r_temp.offset = opparams[0];
|
||||
|
@ -1565,7 +1565,6 @@ int script_instantiate_common(ResourceManager *resMan, SegManager *segMan, int s
|
|||
int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int script_nr) {
|
||||
int objtype;
|
||||
unsigned int objlength;
|
||||
int seg_id;
|
||||
int relocation = -1;
|
||||
int magic_pos_adder; // Usually 0; 2 for older SCI versions
|
||||
Resource *script;
|
||||
|
@ -1573,7 +1572,7 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr
|
|||
SciVersion version = resMan->sciVersion();
|
||||
bool oldScriptHeader = (version == SCI_VERSION_0_EARLY);
|
||||
|
||||
seg_id = script_instantiate_common(resMan, segMan, script_nr, &script, NULL, &was_new);
|
||||
const int seg_id = script_instantiate_common(resMan, segMan, script_nr, &script, NULL, &was_new);
|
||||
|
||||
if (was_new)
|
||||
return seg_id;
|
||||
|
@ -1683,9 +1682,9 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr
|
|||
break;
|
||||
|
||||
objlength = scr->getHeap(reg.offset + 2);
|
||||
reg.offset += 4; // Step over header
|
||||
|
||||
addr = reg;
|
||||
addr.offset += 4; // Step over header
|
||||
|
||||
switch (objtype) {
|
||||
case SCI_OBJ_CODE:
|
||||
|
@ -1715,42 +1714,39 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr
|
|||
break;
|
||||
}
|
||||
|
||||
reg.offset -= 4; // Step back on header
|
||||
|
||||
} while (objtype != 0 && reg.offset < script->size - 2);
|
||||
|
||||
if (relocation >= 0)
|
||||
segMan->scriptRelocate(make_reg(reg.segment, relocation));
|
||||
segMan->scriptRelocate(make_reg(seg_id, relocation));
|
||||
|
||||
return reg.segment; // instantiation successful
|
||||
}
|
||||
|
||||
int script_instantiate_sci11(ResourceManager *resMan, SegManager *segMan, int script_nr) {
|
||||
Resource *script, *heap;
|
||||
int seg_id;
|
||||
int heap_start;
|
||||
int _heapStart;
|
||||
reg_t reg;
|
||||
int was_new;
|
||||
|
||||
seg_id = script_instantiate_common(resMan, segMan, script_nr, &script, &heap, &was_new);
|
||||
const int seg_id = script_instantiate_common(resMan, segMan, script_nr, &script, &heap, &was_new);
|
||||
|
||||
if (was_new)
|
||||
return seg_id;
|
||||
|
||||
Script *scr = segMan->getScript(seg_id);
|
||||
|
||||
heap_start = script->size;
|
||||
_heapStart = script->size;
|
||||
if (script->size & 2)
|
||||
heap_start ++;
|
||||
_heapStart ++;
|
||||
|
||||
scr->mcpyInOut(0, script->data, script->size);
|
||||
scr->mcpyInOut(heap_start, heap->data, heap->size);
|
||||
scr->mcpyInOut(_heapStart, heap->data, heap->size);
|
||||
|
||||
if (READ_LE_UINT16(script->data + 6) > 0)
|
||||
scr->setExportTableOffset(6);
|
||||
|
||||
reg.segment = seg_id;
|
||||
reg.offset = heap_start + 4;
|
||||
reg.offset = _heapStart + 4;
|
||||
segMan->scriptInitialiseLocals(reg);
|
||||
|
||||
segMan->scriptRelocateExportsSci11(seg_id);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue