SCI: Turned several script related SegManager methods into Script methods
svn-id: r40597
This commit is contained in:
parent
565cfa074d
commit
75c0d719c9
8 changed files with 180 additions and 225 deletions
|
@ -184,8 +184,8 @@ reg_t kClone(EngineState *s, int funct_nr, int argc, reg_t *argv) {
|
|||
clone_obj->_variables[SCRIPT_SPECIES_SELECTOR] = clone_obj->pos;
|
||||
if (IS_CLASS(parent_obj))
|
||||
clone_obj->_variables[SCRIPT_SUPERCLASS_SELECTOR] = parent_obj->pos;
|
||||
s->seg_manager->incrementLockers(parent_obj->pos.segment, SEG_ID);
|
||||
s->seg_manager->incrementLockers(clone_obj->pos.segment, SEG_ID);
|
||||
s->seg_manager->getScript(parent_obj->pos.segment, SEG_ID)->incrementLockers();
|
||||
s->seg_manager->getScript(clone_obj->pos.segment, SEG_ID)->incrementLockers();
|
||||
|
||||
return clone_addr;
|
||||
}
|
||||
|
@ -269,7 +269,7 @@ reg_t kDisposeScript(EngineState *s, int funct_nr, int argc, reg_t *argv) {
|
|||
int id = s->seg_manager->segGet(script);
|
||||
|
||||
if (s->_executionStack[s->execution_stack_pos].addr.pc.segment != id)
|
||||
s->seg_manager->setLockers(1, script, SCRIPT_ID);
|
||||
s->seg_manager->getScript(id, SEG_ID)->setLockers(1);
|
||||
}
|
||||
|
||||
script_uninstantiate(s, script);
|
||||
|
|
|
@ -200,12 +200,12 @@ reg_t kSetSynonyms(EngineState *s, int funct_nr, int argc, reg_t *argv) {
|
|||
seg = s->seg_manager->segGet(script);
|
||||
|
||||
if (seg >= 0)
|
||||
synonyms_nr = s->seg_manager->getSynonymsNr(seg, SEG_ID);
|
||||
synonyms_nr = s->seg_manager->getScript(seg, SEG_ID)->getSynonymsNr();
|
||||
|
||||
if (synonyms_nr) {
|
||||
byte *synonyms;
|
||||
|
||||
synonyms = s->seg_manager->getSynonyms(seg, SEG_ID);
|
||||
synonyms = s->seg_manager->getScript(seg, SEG_ID)->getSynonyms();
|
||||
if (synonyms) {
|
||||
SCIkdebug(SCIkPARSER, "Setting %d synonyms for script.%d\n",
|
||||
synonyms_nr, script);
|
||||
|
|
|
@ -343,7 +343,7 @@ static void sync_Script(Common::Serializer &s, Script &obj) {
|
|||
s.syncAsSint32LE(obj.locals_offset);
|
||||
s.syncAsSint32LE(obj.locals_segment);
|
||||
|
||||
s.syncAsSint32LE(obj.marked_as_deleted);
|
||||
s.syncAsSint32LE(obj._markedAsDeleted);
|
||||
}
|
||||
|
||||
static void sync_SystemString(Common::Serializer &s, SystemString &obj) {
|
||||
|
|
|
@ -639,7 +639,7 @@ int c_segkill(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) {
|
|||
while (i < cmdParams.size()) {
|
||||
int nr = cmdParams[i++].val;
|
||||
|
||||
s->seg_manager->setLockers(nr, 0, SEG_ID);
|
||||
s->seg_manager->getScript(nr, SEG_ID)->setLockers(0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -193,7 +193,7 @@ int SegManager::initialiseScript(Script &scr, EngineState *s, int script_nr) {
|
|||
scr._codeBlocks.clear();
|
||||
|
||||
scr.nr = script_nr;
|
||||
scr.marked_as_deleted = 0;
|
||||
scr._markedAsDeleted = false;
|
||||
scr.relocated = 0;
|
||||
|
||||
scr.obj_indices = new IntMapper();
|
||||
|
@ -251,33 +251,18 @@ int SegManager::deallocate(int seg, bool recursive) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int SegManager::scriptMarkedDeleted(int script_nr) {
|
||||
Script *scr = getScript(script_nr, SCRIPT_ID);
|
||||
return scr->marked_as_deleted;
|
||||
}
|
||||
|
||||
void SegManager::markScriptDeleted(int script_nr) {
|
||||
Script *scr = getScript(script_nr, SCRIPT_ID);
|
||||
scr->marked_as_deleted = 1;
|
||||
}
|
||||
|
||||
void SegManager::unmarkScriptDeleted(int script_nr) {
|
||||
Script *scr = getScript(script_nr, SCRIPT_ID);
|
||||
scr->marked_as_deleted = 0;
|
||||
}
|
||||
|
||||
int SegManager::scriptIsMarkedAsDeleted(SegmentId seg) {
|
||||
bool SegManager::scriptIsMarkedAsDeleted(SegmentId seg) {
|
||||
Script *scr;
|
||||
|
||||
if (!check(seg))
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
if (_heap[seg]->getType() != MEM_OBJ_SCRIPT)
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
scr = (Script *)_heap[seg];
|
||||
|
||||
return scr->marked_as_deleted;
|
||||
return scr->_markedAsDeleted;
|
||||
}
|
||||
|
||||
|
||||
|
@ -371,10 +356,10 @@ void Script::freeScript() {
|
|||
|
||||
// memory operations
|
||||
|
||||
void SegManager::mcpyInOut(int dst, const void *src, size_t n, int id, idFlag flag) {
|
||||
Script *scr = getScript(id, flag);
|
||||
if (scr->buf) {
|
||||
memcpy(scr->buf + dst, src, n);
|
||||
void Script::mcpyInOut(int dst, const void *src, size_t n) {
|
||||
if (buf) {
|
||||
assert(dst + n <= buf_size);
|
||||
memcpy(buf + dst, src, n);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -439,36 +424,30 @@ int SegManager::scriptIsLoaded(int id, idFlag flag) {
|
|||
return check(id);
|
||||
}
|
||||
|
||||
void SegManager::incrementLockers(int id, idFlag flag) {
|
||||
Script *scr = getScript(id, flag);
|
||||
scr->lockers++;
|
||||
void Script::incrementLockers() {
|
||||
lockers++;
|
||||
}
|
||||
|
||||
void SegManager::decrementLockers(int id, idFlag flag) {
|
||||
Script *scr = getScript(id, flag);
|
||||
if (scr->lockers > 0)
|
||||
scr->lockers--;
|
||||
void Script::decrementLockers() {
|
||||
if (lockers > 0)
|
||||
lockers--;
|
||||
}
|
||||
|
||||
int SegManager::getLockers(int id, idFlag flag) {
|
||||
Script *scr = getScript(id, flag);
|
||||
return scr->lockers;
|
||||
int Script::getLockers() const {
|
||||
return lockers;
|
||||
}
|
||||
|
||||
void SegManager::setLockers(int lockers, int id, idFlag flag) {
|
||||
Script *scr = getScript(id, flag);
|
||||
scr->lockers = lockers;
|
||||
void Script::setLockers(int lockers_) {
|
||||
lockers = lockers_;
|
||||
}
|
||||
|
||||
void SegManager::setExportTableOffset(int offset, int id, idFlag flag) {
|
||||
Script *scr = getScript(id, flag);
|
||||
|
||||
void Script::setExportTableOffset(int offset) {
|
||||
if (offset) {
|
||||
scr->export_table = (uint16 *)(scr->buf + offset + 2);
|
||||
scr->exports_nr = READ_LE_UINT16((byte *)(scr->export_table - 1));
|
||||
export_table = (uint16 *)(buf + offset + 2);
|
||||
exports_nr = READ_LE_UINT16((byte *)(export_table - 1));
|
||||
} else {
|
||||
scr->export_table = NULL;
|
||||
scr->exports_nr = 0;
|
||||
export_table = NULL;
|
||||
exports_nr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -476,24 +455,20 @@ void SegManager::setExportWidth(int flag) {
|
|||
exports_wide = flag;
|
||||
}
|
||||
|
||||
void SegManager::setSynonymsOffset(int offset, int id, idFlag flag) {
|
||||
Script *scr = getScript(id, flag);
|
||||
scr->synonyms = scr->buf + offset;
|
||||
void Script::setSynonymsOffset(int offset) {
|
||||
synonyms = buf + offset;
|
||||
}
|
||||
|
||||
byte *SegManager::getSynonyms(int id, idFlag flag) {
|
||||
Script *scr = getScript(id, flag);
|
||||
return scr->synonyms;
|
||||
byte *Script::getSynonyms() const {
|
||||
return synonyms;
|
||||
}
|
||||
|
||||
void SegManager::setSynonymsNr(int nr, int id, idFlag flag) {
|
||||
Script *scr = getScript(id, flag);
|
||||
scr->synonyms_nr = nr;
|
||||
void Script::setSynonymsNr(int n) {
|
||||
synonyms_nr = n;
|
||||
}
|
||||
|
||||
int SegManager::getSynonymsNr(int id, idFlag flag) {
|
||||
Script *scr = getScript(id, flag);
|
||||
return scr->synonyms_nr;
|
||||
int Script::getSynonymsNr() const {
|
||||
return synonyms_nr;
|
||||
}
|
||||
|
||||
int SegManager::relocateBlock(Common::Array<reg_t> &block, int block_location, SegmentId segment, int location) {
|
||||
|
@ -1149,7 +1124,7 @@ void Script::freeAtAddress(SegManager *segmgr, reg_t addr) {
|
|||
sciprintf("[GC] Freeing locals %04x:0000\n", locals_segment);
|
||||
*/
|
||||
|
||||
if (marked_as_deleted)
|
||||
if (_markedAsDeleted)
|
||||
segmgr->deallocateScript(nr);
|
||||
}
|
||||
|
||||
|
|
|
@ -97,55 +97,6 @@ public:
|
|||
Script *getScript(int id, idFlag flag);
|
||||
|
||||
|
||||
// script lock operations
|
||||
|
||||
// Increments the number of lockers of the script in question by one
|
||||
// Parameters: (int) id: ID of the script or script segment to modify
|
||||
// (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or
|
||||
// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
|
||||
// but less convenient.
|
||||
void incrementLockers(int id, idFlag flag);
|
||||
|
||||
// Decrements the number of lockers of the script in question by one
|
||||
// Parameters: (int) id: ID of the script or script segment to modify
|
||||
// (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or
|
||||
// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
|
||||
// but less convenient.
|
||||
void decrementLockers(int id, idFlag flag);
|
||||
|
||||
// Retrieves the number of locks held on this script
|
||||
// Parameters: (int) id: ID of the script or script segment to read from
|
||||
// (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or
|
||||
// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
|
||||
// but less convenient.
|
||||
// Returns : (int) The number of locks held on the previously identified script
|
||||
int getLockers(int id, idFlag flag);
|
||||
|
||||
// Sets the number of locks held on the specified script
|
||||
// Parameters: (int) id: ID of the script or script segment to modify
|
||||
// (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or
|
||||
// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
|
||||
// but less convenient.
|
||||
void setLockers(int lockers, int id, idFlag flag);
|
||||
|
||||
// Retrieves a pointer to the synonyms associated with the specified script
|
||||
// Parameters: (int) id: ID of the script or script segment to read from
|
||||
// (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or
|
||||
// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
|
||||
// but less convenient.
|
||||
// Returns : (byte *) Pointer to the synonyms, in non-parsed format.
|
||||
// A dynamic failure is issued if the specified ID does not reference a proper script.
|
||||
byte *getSynonyms(int id, idFlag flag);
|
||||
|
||||
// Retrieves the number of synonyms associated with the specified script
|
||||
// Parameters: (int) id: ID of the script or script segment to read from
|
||||
// (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or
|
||||
// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
|
||||
// but less convenient.
|
||||
// Returns : (int) The number of synonyms associated with the specified script
|
||||
// A dynamic failure is issued if the specified ID does not reference a proper script.
|
||||
int getSynonymsNr(int id, idFlag flag);
|
||||
|
||||
|
||||
// 1b. Script Initialisation
|
||||
|
||||
|
@ -186,50 +137,11 @@ public:
|
|||
// objects have been instantiated, or a run-time error will occur.
|
||||
void scriptRelocate(reg_t block);
|
||||
|
||||
// Sets the script-relative offset of the exports table
|
||||
// Parameters: (int) offset: The script-relative exports table offset
|
||||
// (int) id: ID of the script or script segment to write to
|
||||
// (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or
|
||||
// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
|
||||
// but less convenient.
|
||||
// A dynamic failure is issued if the specified ID does not reference a proper script.
|
||||
void setExportTableOffset(int offset, int id, idFlag flag);
|
||||
|
||||
// Sets the script-relative offset of the synonyms associated with the specified script
|
||||
// Parameters: (int) offset: The script-relative offset of the synonyms block
|
||||
// (int) id: ID of the script or script segment to write to
|
||||
// (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or
|
||||
// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
|
||||
// but less convenient.
|
||||
// A dynamic failure is issued if the specified ID does not reference a proper script.
|
||||
void setSynonymsOffset(int offset, int id, idFlag flag);
|
||||
|
||||
// Sets the number of synonyms associated with the specified script
|
||||
// Parameters: (int) nr: The number of synonyms, as to be stored within the script
|
||||
// (int) id: ID of the script or script segment to write to
|
||||
// (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or
|
||||
// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
|
||||
// but less convenient.
|
||||
// A dynamic failure is issued if the specified ID does not reference a proper script.
|
||||
void setSynonymsNr(int nr, int id, idFlag flag);
|
||||
|
||||
// Marks the script identified by its script number as deleted
|
||||
// Parameters: (int) script_nr: Script number to mark as deleted
|
||||
// This will not actually delete the script. If references remain present on the
|
||||
// heap or the stack, the script will stay in memory in a quasi-deleted state until
|
||||
// either unreachable (resulting in its eventual deletion) or reloaded (resulting
|
||||
// in its data being updated).
|
||||
void markScriptDeleted(int script_nr);
|
||||
|
||||
// Marks the script identified by its script number as not deleted
|
||||
// Parameters: (int) script_nr: Script number to mark as not deleted
|
||||
void unmarkScriptDeleted(int script_nr);
|
||||
|
||||
// Determines whether the script referenced by the indicated segment is marked as being deleted.
|
||||
// Parameters: (SegmentId) Segment ID of the script to investigate
|
||||
// Returns : (int) 1 iff seg points to a script and the segment is deleted, 0 otherwise
|
||||
// Will return 0 when applied to an invalid or non-script seg.
|
||||
int scriptIsMarkedAsDeleted(SegmentId seg);
|
||||
bool scriptIsMarkedAsDeleted(SegmentId seg);
|
||||
|
||||
|
||||
// 2. Clones
|
||||
|
@ -249,17 +161,6 @@ public:
|
|||
// Returns : (int16) The value read from the specified location
|
||||
int16 getHeap(reg_t reg);
|
||||
|
||||
// Copies a byte string into a script's heap representation
|
||||
// Parameters: (int) dst: The script-relative offset of the destination area
|
||||
// (const void *) src: Pointer to the data source location
|
||||
// (size_t) n: Number of bytes to copy
|
||||
// (int) id: ID of the script or script segment to write to
|
||||
// (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or
|
||||
// by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
|
||||
// but less convenient.
|
||||
// A dynamic failure is issued if the specified ID does not reference a proper script.
|
||||
void mcpyInOut(int dst, const void *src, size_t n, int id, idFlag flag);
|
||||
|
||||
|
||||
// 4. Stack
|
||||
|
||||
|
@ -360,7 +261,6 @@ public:
|
|||
void heapRelocate(EngineState *s, reg_t block);
|
||||
void scriptRelocateExportsSci11(int seg);
|
||||
void scriptInitialiseObjectsSci11(EngineState *s, int seg);
|
||||
int scriptMarkedDeleted(int script_nr);
|
||||
int initialiseScript(Script &scr, EngineState *s, int script_nr);
|
||||
|
||||
private:
|
||||
|
|
|
@ -222,7 +222,7 @@ reg_t get_class_address(EngineState *s, int classnr, int lock, reg_t caller) {
|
|||
}
|
||||
} else
|
||||
if (caller.segment != the_class->reg.segment)
|
||||
s->seg_manager->incrementLockers(the_class->reg.segment, SEG_ID);
|
||||
s->seg_manager->getScript(the_class->reg.segment, SEG_ID)->incrementLockers();
|
||||
|
||||
return the_class->reg;
|
||||
}
|
||||
|
@ -255,12 +255,12 @@ ExecStack *execute_method(EngineState *s, uint16 script, uint16 pubfunct, StackP
|
|||
int seg;
|
||||
uint16 temp;
|
||||
|
||||
if (!s->seg_manager->scriptIsLoaded(script, SCRIPT_ID)) // Script not present yet?
|
||||
seg = s->seg_manager->segGet(script);
|
||||
|
||||
if (!s->seg_manager->scriptIsLoaded(seg, SEG_ID)) // Script not present yet?
|
||||
script_instantiate(s, script);
|
||||
else
|
||||
s->seg_manager->unmarkScriptDeleted(script);
|
||||
|
||||
seg = s->seg_manager->segGet(script);
|
||||
s->seg_manager->getScript(seg, SEG_ID)->unmarkDeleted();
|
||||
|
||||
temp = s->seg_manager->validateExportFunc(pubfunct, seg);
|
||||
if (!temp) {
|
||||
|
@ -528,11 +528,7 @@ void vm_handle_fatal_error(EngineState *s, int line, const char *file) {
|
|||
}
|
||||
|
||||
static Script *script_locate_by_segment(EngineState *s, SegmentId seg) {
|
||||
MemObject *memobj = GET_SEGMENT(*s->seg_manager, seg, MEM_OBJ_SCRIPT);
|
||||
if (memobj)
|
||||
return (Script *)memobj;
|
||||
|
||||
return NULL;
|
||||
return (Script *)GET_SEGMENT(*s->seg_manager, seg, MEM_OBJ_SCRIPT);
|
||||
}
|
||||
|
||||
static reg_t pointer_add(EngineState *s, reg_t base, int offset) {
|
||||
|
@ -1595,7 +1591,7 @@ SegmentId script_get_segment(EngineState *s, int script_nr, int load) {
|
|||
|
||||
if (segment > 0) {
|
||||
if ((load & SCRIPT_GET_LOCK) == SCRIPT_GET_LOCK)
|
||||
s->seg_manager->incrementLockers(segment, SEG_ID);
|
||||
s->seg_manager->getScript(segment, SEG_ID)->incrementLockers();
|
||||
|
||||
return segment;
|
||||
} else
|
||||
|
@ -1604,7 +1600,6 @@ SegmentId script_get_segment(EngineState *s, int script_nr, int load) {
|
|||
|
||||
reg_t script_lookup_export(EngineState *s, int script_nr, int export_index) {
|
||||
SegmentId seg = script_get_segment(s, script_nr, SCRIPT_GET_DONT_LOAD);
|
||||
MemObject *memobj;
|
||||
Script *script = NULL;
|
||||
|
||||
#ifndef DISABLE_VALIDATIONS
|
||||
|
@ -1616,10 +1611,7 @@ reg_t script_lookup_export(EngineState *s, int script_nr, int export_index) {
|
|||
}
|
||||
#endif
|
||||
|
||||
memobj = GET_SEGMENT(*s->seg_manager, seg, MEM_OBJ_SCRIPT);
|
||||
|
||||
if (memobj)
|
||||
script = (Script *)memobj;
|
||||
script = script_locate_by_segment(s, seg);
|
||||
|
||||
#ifndef DISABLE_VALIDATIONS
|
||||
if (script
|
||||
|
@ -1643,9 +1635,7 @@ reg_t script_lookup_export(EngineState *s, int script_nr, int export_index) {
|
|||
#define INST_LOOKUP_CLASS(id) ((id == 0xffff)? NULL_REG : get_class_address(s, id, SCRIPT_GET_LOCK, reg))
|
||||
|
||||
int script_instantiate_common(EngineState *s, int script_nr, Resource **script, Resource **heap, int *was_new) {
|
||||
int seg;
|
||||
int seg_id;
|
||||
int marked_for_deletion;
|
||||
reg_t reg;
|
||||
|
||||
*was_new = 1;
|
||||
|
@ -1671,23 +1661,22 @@ int script_instantiate_common(EngineState *s, int script_nr, Resource **script,
|
|||
return 0;
|
||||
}
|
||||
|
||||
Script *scr = 0;
|
||||
seg = s->seg_manager->segGet(script_nr);
|
||||
if (s->seg_manager->scriptIsLoaded(script_nr, SCRIPT_ID)) {
|
||||
marked_for_deletion = s->seg_manager->scriptMarkedDeleted(script_nr);
|
||||
if (!marked_for_deletion) {
|
||||
s->seg_manager->incrementLockers(seg, SEG_ID);
|
||||
return seg;
|
||||
seg_id = s->seg_manager->segGet(script_nr);
|
||||
Script *scr = script_locate_by_segment(s, seg_id);
|
||||
if (scr) {
|
||||
if (!scr->isMarkedAsDeleted()) {
|
||||
scr->incrementLockers();
|
||||
return seg_id;
|
||||
} else {
|
||||
seg_id = seg;
|
||||
scr = (Script *)s->seg_manager->_heap[seg];
|
||||
assert(scr);
|
||||
scr->freeScript();
|
||||
}
|
||||
} else if (!(scr = s->seg_manager->allocateScript(s, script_nr, &seg_id))) { // ALL YOUR SCRIPT BASE ARE BELONG TO US
|
||||
sciprintf("Not enough heap space for script size 0x%x of script 0x%x, should this happen?`\n", (*script)->size, script_nr);
|
||||
script_debug_flag = script_error_flag = 1;
|
||||
return 0;
|
||||
} else {
|
||||
scr = s->seg_manager->allocateScript(s, script_nr, &seg_id);
|
||||
if (!scr) { // ALL YOUR SCRIPT BASE ARE BELONG TO US
|
||||
sciprintf("Not enough heap space for script size 0x%x of script 0x%x, should this happen?`\n", (*script)->size, script_nr);
|
||||
script_debug_flag = script_error_flag = 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
s->seg_manager->initialiseScript(*scr, s, script_nr);
|
||||
|
@ -1696,10 +1685,10 @@ int script_instantiate_common(EngineState *s, int script_nr, Resource **script,
|
|||
reg.offset = 0;
|
||||
|
||||
// Set heap position (beyond the size word)
|
||||
s->seg_manager->setLockers(1, reg.segment, SEG_ID);
|
||||
s->seg_manager->setExportTableOffset(0, reg.segment, SEG_ID);
|
||||
s->seg_manager->setSynonymsOffset(0, reg.segment, SEG_ID);
|
||||
s->seg_manager->setSynonymsNr(0, reg.segment, SEG_ID);
|
||||
scr->setLockers(1);
|
||||
scr->setExportTableOffset(0);
|
||||
scr->setSynonymsOffset(0);
|
||||
scr->setSynonymsNr(0);
|
||||
|
||||
*was_new = 0;
|
||||
|
||||
|
@ -1724,6 +1713,8 @@ int script_instantiate_sci0(EngineState *s, int script_nr) {
|
|||
reg.segment = seg_id;
|
||||
reg.offset = 0;
|
||||
|
||||
Script *scr = s->seg_manager->getScript(seg_id, SEG_ID);
|
||||
|
||||
if (s->flags & GF_SCI0_OLD) {
|
||||
//
|
||||
int locals_nr = READ_LE_UINT16(script->data);
|
||||
|
@ -1733,14 +1724,14 @@ int script_instantiate_sci0(EngineState *s, int script_nr) {
|
|||
// Instead, the script starts with a 16 bit int specifying the
|
||||
// number of locals we need; these are then allocated and zeroed.
|
||||
|
||||
s->seg_manager->mcpyInOut(0, script->data, script->size, reg.segment, SEG_ID);
|
||||
scr->mcpyInOut(0, script->data, script->size);
|
||||
magic_pos_adder = 2; // Step over the funny prefix
|
||||
|
||||
if (locals_nr)
|
||||
s->seg_manager->scriptInitialiseLocalsZero(reg.segment, locals_nr);
|
||||
|
||||
} else {
|
||||
s->seg_manager->mcpyInOut(0, script->data, script->size, reg.segment, SEG_ID);
|
||||
scr->mcpyInOut(0, script->data, script->size);
|
||||
magic_pos_adder = 0;
|
||||
}
|
||||
|
||||
|
@ -1767,13 +1758,13 @@ int script_instantiate_sci0(EngineState *s, int script_nr) {
|
|||
|
||||
switch (objtype) {
|
||||
case SCI_OBJ_EXPORTS: {
|
||||
s->seg_manager->setExportTableOffset(data_base.offset, reg.segment, SEG_ID);
|
||||
scr->setExportTableOffset(data_base.offset);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCI_OBJ_SYNONYMS:
|
||||
s->seg_manager->setSynonymsOffset(addr.offset, reg.segment, SEG_ID); // +4 is to step over the header
|
||||
s->seg_manager->setSynonymsNr((objlength) / 4, reg.segment, SEG_ID);
|
||||
scr->setSynonymsOffset(addr.offset); // +4 is to step over the header
|
||||
scr->setSynonymsNr((objlength) / 4);
|
||||
break;
|
||||
|
||||
case SCI_OBJ_LOCALVARS:
|
||||
|
@ -1870,15 +1861,17 @@ int script_instantiate_sci11(EngineState *s, int script_nr) {
|
|||
if (was_new)
|
||||
return seg_id;
|
||||
|
||||
Script *scr = s->seg_manager->getScript(seg_id, SEG_ID);
|
||||
|
||||
heap_start = script->size;
|
||||
if (script->size & 2)
|
||||
heap_start ++;
|
||||
|
||||
s->seg_manager->mcpyInOut(0, script->data, script->size, seg_id, SEG_ID);
|
||||
s->seg_manager->mcpyInOut(heap_start, heap->data, heap->size, seg_id, SEG_ID);
|
||||
scr->mcpyInOut(0, script->data, script->size);
|
||||
scr->mcpyInOut(heap_start, heap->data, heap->size);
|
||||
|
||||
if (READ_LE_UINT16(script->data + 6) > 0)
|
||||
s->seg_manager->setExportTableOffset(6, seg_id, SEG_ID);
|
||||
scr->setExportTableOffset(6);
|
||||
|
||||
reg.segment = seg_id;
|
||||
reg.offset = heap_start + 4;
|
||||
|
@ -1903,6 +1896,7 @@ int script_instantiate(EngineState *s, int script_nr) {
|
|||
void script_uninstantiate_sci0(EngineState *s, int script_nr, SegmentId seg) {
|
||||
reg_t reg = make_reg(seg, (s->flags & GF_SCI0_OLD) ? 2 : 0);
|
||||
int objtype, objlength;
|
||||
Script *scr = s->seg_manager->getScript(seg, SEG_ID);
|
||||
|
||||
// Make a pass over the object in order uninstantiate all superclasses
|
||||
objlength = 0;
|
||||
|
@ -1911,7 +1905,8 @@ void script_uninstantiate_sci0(EngineState *s, int script_nr, SegmentId seg) {
|
|||
reg.offset += objlength; // Step over the last checked object
|
||||
|
||||
objtype = SEG_GET_HEAP(s, reg);
|
||||
if (!objtype) break;
|
||||
if (!objtype)
|
||||
break;
|
||||
objlength = SEG_GET_HEAP(s, make_reg(reg.segment, reg.offset + 2)); // use SEG_UGET_HEAP ??
|
||||
|
||||
reg.offset += 4; // Step over header
|
||||
|
@ -1927,8 +1922,8 @@ void script_uninstantiate_sci0(EngineState *s, int script_nr, SegmentId seg) {
|
|||
int superclass_script = s->_classtable[superclass].script;
|
||||
|
||||
if (superclass_script == script_nr) {
|
||||
if (s->seg_manager->getLockers(reg.segment, SEG_ID))
|
||||
s->seg_manager->decrementLockers(reg.segment, SEG_ID); // Decrease lockers if this is us ourselves
|
||||
if (scr->getLockers())
|
||||
scr->decrementLockers(); // Decrease lockers if this is us ourselves
|
||||
} else
|
||||
script_uninstantiate(s, superclass_script);
|
||||
// Recurse to assure that the superclass lockers number gets decreased
|
||||
|
@ -1946,16 +1941,17 @@ void script_uninstantiate(EngineState *s, int script_nr) {
|
|||
reg_t reg = make_reg(0, (s->flags & GF_SCI0_OLD) ? 2 : 0);
|
||||
|
||||
reg.segment = s->seg_manager->segGet(script_nr);
|
||||
Script *scr = script_locate_by_segment(s, reg.segment);
|
||||
|
||||
if (!s->seg_manager->scriptIsLoaded(script_nr, SCRIPT_ID) || reg.segment <= 0) { // Is it already loaded?
|
||||
if (!scr) { // Is it already loaded?
|
||||
//warning("unloading script 0x%x requested although not loaded", script_nr);
|
||||
// This is perfectly valid SCI behaviour
|
||||
return;
|
||||
}
|
||||
|
||||
s->seg_manager->decrementLockers(reg.segment, SEG_ID); // One less locker
|
||||
scr->decrementLockers(); // One less locker
|
||||
|
||||
if (s->seg_manager->getLockers(reg.segment, SEG_ID) > 0)
|
||||
if (scr->getLockers() > 0)
|
||||
return;
|
||||
|
||||
// Free all classtable references to this script
|
||||
|
@ -1968,12 +1964,12 @@ void script_uninstantiate(EngineState *s, int script_nr) {
|
|||
else
|
||||
sciprintf("FIXME: Add proper script uninstantiation for SCI 1.1\n");
|
||||
|
||||
if (s->seg_manager->getLockers(reg.segment, SEG_ID))
|
||||
if (scr->getLockers())
|
||||
return; // if xxx.lockers > 0
|
||||
|
||||
// Otherwise unload it completely
|
||||
// Explanation: I'm starting to believe that this work is done by SCI itself.
|
||||
s->seg_manager->markScriptDeleted(script_nr);
|
||||
scr->markDeleted();
|
||||
|
||||
if (script_checkloads_flag)
|
||||
sciprintf("Unloaded script 0x%x.\n", script_nr);
|
||||
|
@ -2064,17 +2060,17 @@ int game_run(EngineState **_s) {
|
|||
}
|
||||
|
||||
Object *obj_get(EngineState *s, reg_t offset) {
|
||||
MemObject *memobj = GET_OBJECT_SEGMENT(*s->seg_manager, offset.segment);
|
||||
MemObject *mobj = GET_OBJECT_SEGMENT(*s->seg_manager, offset.segment);
|
||||
Object *obj = NULL;
|
||||
int idx;
|
||||
|
||||
if (memobj != NULL) {
|
||||
if (memobj->getType() == MEM_OBJ_CLONES) {
|
||||
CloneTable *ct = (CloneTable *)memobj;
|
||||
if (mobj != NULL) {
|
||||
if (mobj->getType() == MEM_OBJ_CLONES) {
|
||||
CloneTable *ct = (CloneTable *)mobj;
|
||||
if (ct->isValidEntry(offset.offset))
|
||||
obj = &(ct->_table[offset.offset]);
|
||||
} else if (memobj->getType() == MEM_OBJ_SCRIPT) {
|
||||
Script *scr = (Script *)memobj;
|
||||
} else if (mobj->getType() == MEM_OBJ_SCRIPT) {
|
||||
Script *scr = (Script *)mobj;
|
||||
if (offset.offset <= scr->buf_size && offset.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET
|
||||
&& RAW_IS_OBJECT(scr->buf + offset.offset)) {
|
||||
idx = RAW_GET_CLASS_INDEX(scr, offset);
|
||||
|
|
|
@ -330,7 +330,7 @@ struct Script : public MemObject {
|
|||
|
||||
Common::Array<CodeBlock> _codeBlocks;
|
||||
int relocated;
|
||||
int marked_as_deleted;
|
||||
bool _markedAsDeleted;
|
||||
|
||||
public:
|
||||
Script() {
|
||||
|
@ -351,7 +351,7 @@ public:
|
|||
locals_block = NULL;
|
||||
|
||||
relocated = 0;
|
||||
marked_as_deleted = 0;
|
||||
_markedAsDeleted = 0;
|
||||
}
|
||||
|
||||
~Script() {
|
||||
|
@ -367,6 +367,90 @@ public:
|
|||
virtual void listAllOutgoingReferences(EngineState *s, reg_t object, void *param, NoteCallback note);
|
||||
|
||||
// virtual void saveLoadWithSerializer(Common::Serializer &ser);
|
||||
|
||||
// script lock operations
|
||||
|
||||
/** Increments the number of lockers of this script by one. */
|
||||
void incrementLockers();
|
||||
|
||||
/** Decrements the number of lockers of this script by one. */
|
||||
void decrementLockers();
|
||||
|
||||
/**
|
||||
* Retrieves the number of locks held on this script.
|
||||
* @return the number of locks held on the previously identified script
|
||||
*/
|
||||
int getLockers() const;
|
||||
|
||||
/** Sets the number of locks held on this script. */
|
||||
void setLockers(int lockers);
|
||||
|
||||
/**
|
||||
* Retrieves a pointer to the synonyms associated with this script
|
||||
* @return pointer to the synonyms, in non-parsed format.
|
||||
*/
|
||||
byte *getSynonyms() const;
|
||||
|
||||
/**
|
||||
* Retrieves the number of synonyms associated with this script.
|
||||
* @return the number of synonyms associated with this script
|
||||
*/
|
||||
int getSynonymsNr() const;
|
||||
|
||||
|
||||
/**
|
||||
* Sets the script-relative offset of the exports table.
|
||||
* @param offset script-relative exports table offset
|
||||
*/
|
||||
void setExportTableOffset(int offset);
|
||||
|
||||
/**
|
||||
* Sets the script-relative offset of the synonyms associated with this script.
|
||||
* @param offset script-relative offset of the synonyms block
|
||||
*/
|
||||
void setSynonymsOffset(int offset);
|
||||
|
||||
/**
|
||||
* Sets the number of synonyms associated with this script,
|
||||
* @param nr number of synonyms, as to be stored within the script
|
||||
*/
|
||||
void setSynonymsNr(int nr);
|
||||
|
||||
|
||||
/**
|
||||
* Copies a byte string into a script's heap representation.
|
||||
* @param dst script-relative offset of the destination area
|
||||
* @param src pointer to the data source location
|
||||
* @param n number of bytes to copy
|
||||
*/
|
||||
void mcpyInOut(int dst, const void *src, size_t n);
|
||||
|
||||
|
||||
/**
|
||||
* Marks the script as deleted.
|
||||
* This will not actually delete the script. If references remain present on the
|
||||
* heap or the stack, the script will stay in memory in a quasi-deleted state until
|
||||
* either unreachable (resulting in its eventual deletion) or reloaded (resulting
|
||||
* in its data being updated).
|
||||
*/
|
||||
void markDeleted() {
|
||||
_markedAsDeleted = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the script as not deleted.
|
||||
*/
|
||||
void unmarkDeleted() {
|
||||
_markedAsDeleted = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the script is marked as being deleted.
|
||||
*/
|
||||
bool isMarkedAsDeleted() const {
|
||||
return _markedAsDeleted;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/** Data stack */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue