aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/sci/engine/script.cpp74
-rw-r--r--engines/sci/engine/script.h24
-rw-r--r--engines/sci/engine/seg_manager.h21
3 files changed, 63 insertions, 56 deletions
diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp
index 748a8f9140..18244c7906 100644
--- a/engines/sci/engine/script.cpp
+++ b/engines/sci/engine/script.cpp
@@ -384,34 +384,31 @@ SegmentRef Script::dereference(reg_t pointer) {
return ret;
}
-void SegManager::scriptInitialiseLocals(SegmentId segmentId) {
- Script *scr = getScript(segmentId);
-
- LocalVariables *locals = allocLocalsSegment(scr);
+void Script::initialiseLocals(SegManager *segMan) {
+ LocalVariables *locals = segMan->allocLocalsSegment(this);
if (locals) {
if (getSciVersion() > SCI_VERSION_0_EARLY) {
- const byte *base = (const byte *)(scr->_buf + scr->getLocalsOffset());
+ const byte *base = (const byte *)(_buf + getLocalsOffset());
- for (uint16 i = 0; i < scr->getLocalsCount(); i++)
+ for (uint16 i = 0; i < getLocalsCount(); i++)
locals->_locals[i] = make_reg(0, READ_SCI11ENDIAN_UINT16(base + i * 2));
} else {
// In SCI0 early, locals are set at run time, thus zero them all here
- for (uint16 i = 0; i < scr->getLocalsCount(); i++)
+ for (uint16 i = 0; i < getLocalsCount(); i++)
locals->_locals[i] = NULL_REG;
}
}
}
-void SegManager::scriptInitialiseClasses(SegmentId seg) {
- Script *scr = getScript(seg);
+void Script::initialiseClasses(SegManager *segMan) {
const byte *seeker = 0;
uint16 mult = 0;
if (getSciVersion() >= SCI_VERSION_1_1) {
- seeker = scr->_heapStart + 4 + READ_SCI11ENDIAN_UINT16(scr->_heapStart + 2) * 2;
+ seeker = _heapStart + 4 + READ_SCI11ENDIAN_UINT16(_heapStart + 2) * 2;
mult = 2;
} else {
- seeker = scr->findBlock(SCI_OBJ_CLASS);
+ seeker = findBlock(SCI_OBJ_CLASS);
mult = 1;
}
@@ -422,7 +419,7 @@ void SegManager::scriptInitialiseClasses(SegmentId seg) {
// In SCI0-SCI1, this is the segment type. In SCI11, it's a marker (0x1234)
uint16 marker = READ_SCI11ENDIAN_UINT16(seeker);
bool isClass;
- uint16 classpos = seeker - scr->_buf;
+ uint16 classpos = seeker - _buf;
int16 species;
if (!marker)
@@ -439,24 +436,25 @@ void SegManager::scriptInitialiseClasses(SegmentId seg) {
if (isClass) {
// WORKAROUND for an invalid species access in the demo of LSL2
- if (g_sci->getGameId() == GID_LSL2 && g_sci->isDemo() && species == (int)classTableSize())
- resizeClassTable(classTableSize() + 1);
+ if (g_sci->getGameId() == GID_LSL2 && g_sci->isDemo() && species == (int)segMan->classTableSize())
+ segMan->resizeClassTable(segMan->classTableSize() + 1);
- if (species < 0 || species >= (int)classTableSize())
+ if (species < 0 || species >= (int)segMan->classTableSize())
error("Invalid species %d(0x%x) not in interval [0,%d) while instantiating script %d\n",
- species, species, classTableSize(), scr->_nr);
+ species, species, segMan->classTableSize(), _nr);
- setClassOffset(species, make_reg(seg, classpos));
+ SegmentId segmentId = segMan->getScriptSegment(_nr);
+ segMan->setClassOffset(species, make_reg(segmentId, classpos));
}
seeker += READ_SCI11ENDIAN_UINT16(seeker + 2) * mult;
}
}
-void SegManager::scriptInitialiseObjectsSci0(SegmentId seg) {
- Script *scr = getScript(seg);
+void Script::initialiseObjectsSci0(SegManager *segMan) {
bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY);
- const byte *seeker = scr->_buf + (oldScriptHeader ? 2 : 0);
+ const byte *seeker = _buf + (oldScriptHeader ? 2 : 0);
+ SegmentId segmentId = segMan->getScriptSegment(_nr);
do {
uint16 objType = READ_SCI11ENDIAN_UINT16(seeker);
@@ -467,14 +465,14 @@ void SegManager::scriptInitialiseObjectsSci0(SegmentId seg) {
case SCI_OBJ_OBJECT:
case SCI_OBJ_CLASS:
{
- reg_t addr = make_reg(seg, seeker - scr->_buf + 4);
- Object *obj = scr->scriptObjInit(addr);
- obj->initSpecies(this, addr);
+ reg_t addr = make_reg(segmentId, seeker - _buf + 4);
+ Object *obj = scriptObjInit(addr);
+ obj->initSpecies(segMan, addr);
- if (!obj->initBaseObject(this, addr)) {
+ if (!obj->initBaseObject(segMan, addr)) {
// Script 202 of KQ5 French has an invalid object. This is non-fatal.
warning("Failed to locate base object for object at %04X:%04X; skipping", PRINT_REG(addr));
- scr->scriptObjRemove(addr);
+ scriptObjRemove(addr);
}
}
break;
@@ -484,20 +482,20 @@ void SegManager::scriptInitialiseObjectsSci0(SegmentId seg) {
}
seeker += READ_SCI11ENDIAN_UINT16(seeker + 2);
- } while ((uint32)(seeker - scr->_buf) < scr->getScriptSize() - 2);
+ } while ((uint32)(seeker - _buf) < getScriptSize() - 2);
}
-void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) {
- Script *scr = getScript(seg);
- const byte *seeker = scr->_heapStart + 4 + READ_SCI11ENDIAN_UINT16(scr->_heapStart + 2) * 2;
+void Script::initialiseObjectsSci11(SegManager *segMan) {
+ const byte *seeker = _heapStart + 4 + READ_SCI11ENDIAN_UINT16(_heapStart + 2) * 2;
+ SegmentId segmentId = segMan->getScriptSegment(_nr);
while (READ_SCI11ENDIAN_UINT16(seeker) == SCRIPT_OBJECT_MAGIC_NUMBER) {
- reg_t reg = make_reg(seg, seeker - scr->_buf);
- Object *obj = scr->scriptObjInit(reg);
+ reg_t reg = make_reg(segmentId, seeker - _buf);
+ Object *obj = scriptObjInit(reg);
// Copy base from species class, as we need its selector IDs
obj->setSuperClassSelector(
- getClassAddress(obj->getSuperClassSelector().offset, SCRIPT_GET_LOCK, NULL_REG));
+ segMan->getClassAddress(obj->getSuperClassSelector().offset, SCRIPT_GET_LOCK, NULL_REG));
// If object is instance, get -propDict- from class and set it for this object
// This is needed for ::isMemberOf() to work.
@@ -505,7 +503,7 @@ void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) {
// clicking on ego
if (!obj->isClass()) {
reg_t classObject = obj->getSuperClassSelector();
- Object *classObj = getObject(classObject);
+ Object *classObj = segMan->getObject(classObject);
obj->setPropDictSelector(classObj->getPropDictSelector());
}
@@ -515,7 +513,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->setClassScriptSelector(make_reg(0, scr->_nr));
+ obj->setClassScriptSelector(make_reg(0, _nr));
seeker += READ_SCI11ENDIAN_UINT16(seeker + 2) * 2;
}
@@ -537,14 +535,14 @@ int script_instantiate(ResourceManager *resMan, SegManager *segMan, int scriptNu
scr->init(scriptNum, resMan);
scr->load(resMan);
- segMan->scriptInitialiseLocals(segmentId);
- segMan->scriptInitialiseClasses(segmentId);
+ scr->initialiseLocals(segMan);
+ scr->initialiseClasses(segMan);
if (getSciVersion() >= SCI_VERSION_1_1) {
- segMan->scriptInitialiseObjectsSci11(segmentId);
+ scr->initialiseObjectsSci11(segMan);
scr->relocate(make_reg(segmentId, READ_SCI11ENDIAN_UINT16(scr->_heapStart)));
} else {
- segMan->scriptInitialiseObjectsSci0(segmentId);
+ scr->initialiseObjectsSci0(segMan);
byte *relocationBlock = scr->findBlock(SCI_OBJ_POINTERS);
if (relocationBlock)
scr->relocate(make_reg(segmentId, relocationBlock - scr->_buf + 4));
diff --git a/engines/sci/engine/script.h b/engines/sci/engine/script.h
index 62d2228c9a..cc3c0263e8 100644
--- a/engines/sci/engine/script.h
+++ b/engines/sci/engine/script.h
@@ -140,6 +140,30 @@ public:
*/
void relocate(reg_t block);
+ /**
+ * Initializes the script's local variables
+ * @param segMan A reference to the segment manager
+ */
+ void initialiseLocals(SegManager *segMan);
+
+ /**
+ * Adds the script's classes to the segment manager's class table
+ * @param segMan A reference to the segment manager
+ */
+ void initialiseClasses(SegManager *segMan);
+
+ /**
+ * Initializes the script's objects (SCI0)
+ * @param segMan A reference to the segment manager
+ */
+ void initialiseObjectsSci0(SegManager *segMan);
+
+ /**
+ * Initializes the script's objects (SCI1.1+)
+ * @param segMan A reference to the segment manager
+ */
+ void initialiseObjectsSci11(SegManager *segMan);
+
private:
bool relocateLocal(SegmentId segment, int location);
diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h
index 19fd06f596..324527400b 100644
--- a/engines/sci/engine/seg_manager.h
+++ b/engines/sci/engine/seg_manager.h
@@ -139,19 +139,6 @@ public:
*/
Script *getScriptIfLoaded(SegmentId seg);
-
- // 1b. Script Initialisation
-
- // The set of functions below are intended
- // to be used during script instantiation,
- // i.e. loading and linking.
-
- /**
- * Initializes a script's local variable block according to a prototype
- * @param segmentId Segment containing the script to initialize
- */
- void scriptInitialiseLocals(SegmentId segmentId);
-
// 2. Clones
/**
@@ -427,10 +414,6 @@ public:
*/
reg_t findObjectByName(const Common::String &name, int index = -1);
- void scriptInitialiseClasses(SegmentId seg);
- void scriptInitialiseObjectsSci0(SegmentId seg);
- void scriptInitialiseObjectsSci11(SegmentId seg);
-
uint32 classTableSize() { return _classTable.size(); }
Class getClass(int index) { return _classTable[index]; }
void setClassOffset(int index, reg_t offset) { _classTable[index].reg = offset; }
@@ -481,7 +464,6 @@ private:
private:
SegmentObj *allocSegment(SegmentObj *mem, SegmentId *segid);
- LocalVariables *allocLocalsSegment(Script *scr);
int deallocate(SegmentId seg, bool recursive);
void createClassTable();
@@ -494,6 +476,9 @@ private:
* 'seg' is a valid segment
*/
bool check(SegmentId seg);
+
+public:
+ LocalVariables *allocLocalsSegment(Script *scr);
};
} // End of namespace Sci