diff options
| -rw-r--r-- | engines/sci/engine/kscripts.cpp | 6 | ||||
| -rw-r--r-- | engines/sci/engine/kstring.cpp | 4 | ||||
| -rw-r--r-- | engines/sci/engine/savegame.cpp | 2 | ||||
| -rw-r--r-- | engines/sci/engine/scriptdebug.cpp | 2 | ||||
| -rw-r--r-- | engines/sci/engine/seg_manager.cpp | 89 | ||||
| -rw-r--r-- | engines/sci/engine/seg_manager.h | 102 | ||||
| -rw-r--r-- | engines/sci/engine/vm.cpp | 112 | ||||
| -rw-r--r-- | engines/sci/engine/vm.h | 88 | 
8 files changed, 180 insertions, 225 deletions
| diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp index 3ce2ebb5a7..b66647e390 100644 --- a/engines/sci/engine/kscripts.cpp +++ b/engines/sci/engine/kscripts.cpp @@ -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); diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp index e7149e51df..9c9eb6ede8 100644 --- a/engines/sci/engine/kstring.cpp +++ b/engines/sci/engine/kstring.cpp @@ -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); diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index 51c3059329..69275e8ada 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -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) { diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp index e54efdc5d8..ae538554d7 100644 --- a/engines/sci/engine/scriptdebug.cpp +++ b/engines/sci/engine/scriptdebug.cpp @@ -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;  } diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index 848c3a044d..b4cbc75d55 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -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);  } diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h index f68fa6a23a..9521d84b7b 100644 --- a/engines/sci/engine/seg_manager.h +++ b/engines/sci/engine/seg_manager.h @@ -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: diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 43022dc3f5..e1d3b254e8 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -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); diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h index fc3744f551..b7969c3447 100644 --- a/engines/sci/engine/vm.h +++ b/engines/sci/engine/vm.h @@ -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 */ | 
