SCI: Make Script member vars private; add const qualifiers

Only three Script members remain public (for now)

svn-id: r50428
This commit is contained in:
Max Horn 2010-06-28 11:22:20 +00:00
parent 85038e7d6c
commit 30218a2c32
10 changed files with 77 additions and 76 deletions

View file

@ -1381,7 +1381,7 @@ bool Console::cmdPrintSegmentTable(int argc, const char **argv) {
switch (mobj->getType()) {
case SEG_TYPE_SCRIPT:
DebugPrintf("S script.%03d l:%d ", (*(Script *)mobj)._nr, (*(Script *)mobj).getLockers());
DebugPrintf("S script.%03d l:%d ", (*(Script *)mobj).getScriptNumber(), (*(Script *)mobj).getLockers());
break;
case SEG_TYPE_CLONES:
@ -1455,9 +1455,9 @@ bool Console::segmentInfo(int nr) {
case SEG_TYPE_SCRIPT: {
Script *scr = (Script *)mobj;
DebugPrintf("script.%03d locked by %d, bufsize=%d (%x)\n", scr->_nr, scr->getLockers(), (uint)scr->getBufSize(), (uint)scr->getBufSize());
DebugPrintf("script.%03d locked by %d, bufsize=%d (%x)\n", scr->getScriptNumber(), scr->getLockers(), (uint)scr->getBufSize(), (uint)scr->getBufSize());
if (scr->getExportTable())
DebugPrintf(" Exports: %4d at %d\n", scr->getExportsNr(), (int)(((const byte *)scr->getExportTable()) - ((const byte *)scr->_buf)));
DebugPrintf(" Exports: %4d at %d\n", scr->getExportsNr(), (int)(((const byte *)scr->getExportTable()) - ((const byte *)scr->getBuf())));
else
DebugPrintf(" Exports: none\n");
@ -2377,7 +2377,7 @@ bool Console::cmdBacktrace(int argc, const char **argv) {
DebugPrintf(" argp:ST:%04x", (unsigned)(call.variables_argp - _engine->_gamestate->stack_base));
if (call.type == EXEC_STACK_TYPE_CALL)
DebugPrintf(" script: %d", (*(Script *)_engine->_gamestate->_segMan->_heap[call.addr.pc.segment])._nr);
DebugPrintf(" script: %d", (*(Script *)_engine->_gamestate->_segMan->_heap[call.addr.pc.segment]).getScriptNumber());
DebugPrintf("\n");
}
@ -3351,7 +3351,7 @@ int Console::printObject(reg_t pos) {
DebugPrintf(" [%03x] %s = %04x:%04x\n", obj->getFuncSelector(i), _engine->getKernel()->getSelectorName(obj->getFuncSelector(i)).c_str(), PRINT_REG(fptr));
}
if (s->_segMan->_heap[pos.segment]->getType() == SEG_TYPE_SCRIPT)
DebugPrintf("\nOwner script: %d\n", s->_segMan->getScript(pos.segment)->_nr);
DebugPrintf("\nOwner script: %d\n", s->_segMan->getScript(pos.segment)->getScriptNumber());
return 0;
}

View file

@ -84,7 +84,7 @@ bool GameFeatures::autoDetectSoundType() {
int16 opparams[4];
byte extOpcode;
byte opcode;
offset += readPMachineInstruction(script->_buf + offset, extOpcode, opparams);
offset += readPMachineInstruction(script->getBuf(offset), extOpcode, opparams);
opcode = extOpcode >> 1;
// Check for end of script
@ -220,7 +220,7 @@ bool GameFeatures::autoDetectLofsType(int methodNum) {
int16 opparams[4];
byte extOpcode;
byte opcode;
offset += readPMachineInstruction(script->_buf + offset, extOpcode, opparams);
offset += readPMachineInstruction(script->getBuf(offset), extOpcode, opparams);
opcode = extOpcode >> 1;
// Check for end of script
@ -306,7 +306,7 @@ bool GameFeatures::autoDetectGfxFunctionsType(int methodNum) {
int16 opparams[4];
byte extOpcode;
byte opcode;
offset += readPMachineInstruction(script->_buf + offset, extOpcode, opparams);
offset += readPMachineInstruction(script->getBuf(offset), extOpcode, opparams);
opcode = extOpcode >> 1;
// Check for end of script
@ -409,7 +409,7 @@ bool GameFeatures::autoDetectSci21KernelType() {
int16 opparams[4];
byte extOpcode;
byte opcode;
offset += readPMachineInstruction(script->_buf + offset, extOpcode, opparams);
offset += readPMachineInstruction(script->getBuf(offset), extOpcode, opparams);
opcode = extOpcode >> 1;
// Check for end of script
@ -462,7 +462,7 @@ bool GameFeatures::autoDetectMoveCountType() {
int16 opparams[4];
byte extOpcode;
byte opcode;
offset += readPMachineInstruction(script->_buf + offset, extOpcode, opparams);
offset += readPMachineInstruction(script->getBuf(offset), extOpcode, opparams);
opcode = extOpcode >> 1;
// Check for end of script

View file

@ -644,7 +644,7 @@ int Kernel::findRegType(reg_t reg) {
case SEG_TYPE_SCRIPT:
if (reg.offset <= (*(Script *)mobj).getBufSize() &&
reg.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET &&
RAW_IS_OBJECT((*(Script *)mobj)._buf + reg.offset)) {
RAW_IS_OBJECT((*(Script *)mobj).getBuf(reg.offset)) ) {
return ((Script *)mobj)->getObject(reg.offset) ? KSIG_OBJECT : KSIG_REF;
} else
return KSIG_REF;

View file

@ -278,7 +278,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 == SEG_TYPE_SCRIPT) {
_scriptSegMap[((Script *)mobj)->_nr] = i;
_scriptSegMap[((Script *)mobj)->getScriptNumber()] = i;
}
}
@ -765,7 +765,7 @@ void SegManager::reconstructScripts(EngineState *s) {
scr->_localsBlock = (scr->_localsSegment == 0) ? NULL : (LocalVariables *)(_heap[scr->_localsSegment]);
for (ObjMap::iterator it = scr->_objects.begin(); it != scr->_objects.end(); ++it)
it->_value._baseObj = scr->_buf + it->_value.getPos().offset;
it->_value._baseObj = scr->getBuf(it->_value.getPos().offset);
}
for (i = 0; i < _heap.size(); i++) {

View file

@ -88,14 +88,13 @@ void Script::init(int script_nr, ResourceManager *resMan) {
if (getSciVersion() == SCI_VERSION_0_EARLY) {
_bufSize += READ_LE_UINT16(script->data) * 2;
} else if (getSciVersion() >= SCI_VERSION_1_1) {
/**
* In SCI11, the heap was in a separate space from the script.
* We append it to the end of the script, and adjust addressing accordingly.
* However, since we address the heap with a 16-bit pointer, the combined
* size of the stack and the heap must be 64KB. So far this has worked
* for SCI11, SCI2 and SCI21 games. SCI3 games use a different script format,
* and theoretically they can exceed the 64KB boundary using relocation.
*/
// In SCI11, the heap was in a separate space from the script. We append
// it to the end of the script, and adjust addressing accordingly.
// However, since we address the heap with a 16-bit pointer, the
// combined size of the stack and the heap must be 64KB. So far this has
// worked for SCI11, SCI2 and SCI21 games. SCI3 games use a different
// script format, and theoretically they can exceed the 64KB boundary
// using relocation.
Resource *heap = resMan->findResource(ResourceId(kResourceTypeHeap, script_nr), 0);
_bufSize += heap->size;
_heapSize = heap->size;
@ -109,8 +108,8 @@ void Script::init(int script_nr, ResourceManager *resMan) {
// As mentioned above, the script and the heap together should not exceed 64KB
if (script->size + heap->size > 65535)
error("Script and heap sizes combined exceed 64K. This means a fundamental "
"design bug was made regarding SCI1.1 and newer games.\nPlease "
"report this error to the ScummVM team");
"design bug was made regarding SCI1.1 and newer games.\n"
"Please report this error to the ScummVM team");
}
}
@ -256,7 +255,7 @@ bool Script::relocateLocal(SegmentId segment, int location) {
}
void Script::relocate(reg_t block) {
byte *heap = _buf;
const byte *heap = _buf;
uint16 heapSize = (uint16)_bufSize;
uint16 heapOffset = 0;
@ -452,10 +451,9 @@ void Script::initialiseClasses(SegManager *segMan) {
}
}
void Script::initialiseObjectsSci0(SegManager *segMan) {
void Script::initialiseObjectsSci0(SegManager *segMan, SegmentId segmentId) {
bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY);
const byte *seeker = _buf + (oldScriptHeader ? 2 : 0);
SegmentId segmentId = segMan->getScriptSegment(_nr);
do {
uint16 objType = READ_SCI11ENDIAN_UINT16(seeker);
@ -487,11 +485,14 @@ void Script::initialiseObjectsSci0(SegManager *segMan) {
seeker += READ_SCI11ENDIAN_UINT16(seeker + 2);
} while ((uint32)(seeker - _buf) < getScriptSize() - 2);
byte *relocationBlock = findBlock(SCI_OBJ_POINTERS);
if (relocationBlock)
relocate(make_reg(segmentId, relocationBlock - getBuf() + 4));
}
void Script::initialiseObjectsSci11(SegManager *segMan) {
void Script::initialiseObjectsSci11(SegManager *segMan, SegmentId segmentId) {
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(segmentId, seeker - _buf);
@ -521,6 +522,8 @@ void Script::initialiseObjectsSci11(SegManager *segMan) {
seeker += READ_SCI11ENDIAN_UINT16(seeker + 2) * 2;
}
relocate(make_reg(segmentId, READ_SCI11ENDIAN_UINT16(_heapStart)));
}
} // End of namespace Sci

View file

@ -51,19 +51,12 @@ enum ScriptObjectTypes {
typedef Common::HashMap<uint16, Object> ObjMap;
class Script : public SegmentObj {
public:
private:
int _nr; /**< Script number */
byte *_buf; /**< Static data buffer, or NULL if not used */
byte *_heapStart; /**< Start of heap if SCI1.1, NULL otherwise */
uint32 getScriptSize() { return _scriptSize; }
uint32 getHeapSize() { return _heapSize; }
uint32 getBufSize() { return _bufSize; }
protected:
int _lockers; /**< Number of classes and objects that require this script */
private:
size_t _scriptSize;
size_t _heapSize;
uint16 _bufSize;
@ -77,19 +70,27 @@ private:
int _localsOffset;
uint16 _localsCount;
bool _markedAsDeleted;
public:
/**
* Table for objects, contains property variables.
* Indexed by the TODO offset.
*/
ObjMap _objects;
int getLocalsOffset() const { return _localsOffset; }
uint16 getLocalsCount() const { return _localsCount; }
SegmentId _localsSegment; /**< The local variable segment */
LocalVariables *_localsBlock;
bool _markedAsDeleted;
public:
int getLocalsOffset() const { return _localsOffset; }
uint16 getLocalsCount() const { return _localsCount; }
uint32 getScriptSize() const { return _scriptSize; }
uint32 getHeapSize() const { return _heapSize; }
uint32 getBufSize() const { return _bufSize; }
const byte *getBuf(uint offset = 0) const { return _buf + offset; }
int getScriptNumber() const { return _nr; }
public:
Script();
@ -129,15 +130,6 @@ public:
*/
void scriptObjRemove(reg_t obj_pos);
/**
* Processes a relocation block witin a script
* This function is idempotent, but it must only be called after all
* objects have been instantiated, or a run-time error will occur.
* @param obj_pos Location (segment, offset) of the block
* @return Location of the relocation block
*/
void relocate(reg_t block);
/**
* Initializes the script's local variables
* @param segMan A reference to the segment manager
@ -153,19 +145,17 @@ public:
/**
* Initializes the script's objects (SCI0)
* @param segMan A reference to the segment manager
* @param segmentId The script's segment id
*/
void initialiseObjectsSci0(SegManager *segMan);
void initialiseObjectsSci0(SegManager *segMan, SegmentId segmentId);
/**
* Initializes the script's objects (SCI1.1+)
* @param segMan A reference to the segment manager
* @param segmentId The script's segment id
*/
void initialiseObjectsSci11(SegManager *segMan);
void initialiseObjectsSci11(SegManager *segMan, SegmentId segmentId);
private:
bool relocateLocal(SegmentId segment, int location);
public:
// script lock operations
/** Increments the number of lockers of this script by one. */
@ -246,6 +236,18 @@ public:
* Finds the pointer where a block of a specific type starts from
*/
byte *findBlock(int type);
private:
/**
* Processes a relocation block witin a script
* This function is idempotent, but it must only be called after all
* objects have been instantiated, or a run-time error will occur.
* @param obj_pos Location (segment, offset) of the block
* @return Location of the relocation block
*/
void relocate(reg_t block);
bool relocateLocal(SegmentId segment, int location);
};
} // End of namespace Sci

View file

@ -69,7 +69,7 @@ DebugState g_debugState; // FIXME: Avoid non-const global vars
reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecode) {
SegmentObj *mobj = s->_segMan->getSegment(pos.segment, SEG_TYPE_SCRIPT);
Script *script_entity = NULL;
byte *scr;
const byte *scr;
int scr_size;
reg_t retval = make_reg(pos.segment, pos.offset + 1);
uint16 param_value;
@ -82,7 +82,7 @@ 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 = script_entity->getBuf();
scr_size = script_entity->getBufSize();
if (pos.offset >= scr_size) {
@ -291,7 +291,7 @@ void script_debug(EngineState *s) {
if (mobj) {
Script *scr = (Script *)mobj;
byte *code_buf = scr->_buf;
const byte *code_buf = scr->getBuf();
int code_buf_size = scr->getBufSize();
int opcode = s->xs->addr.pc.offset >= code_buf_size ? 0 : code_buf[s->xs->addr.pc.offset];
int op = opcode >> 1;

View file

@ -157,7 +157,7 @@ int SegManager::deallocate(SegmentId seg, bool recursive) {
if (mobj->getType() == SEG_TYPE_SCRIPT) {
Script *scr = (Script *)mobj;
_scriptSegMap.erase(scr->_nr);
_scriptSegMap.erase(scr->getScriptNumber());
if (recursive && scr->_localsSegment)
deallocate(scr->_localsSegment, recursive);
}
@ -173,7 +173,7 @@ bool SegManager::isHeapObject(reg_t pos) {
if (obj == NULL || (obj && obj->isFreed()))
return false;
Script *scr = getScriptIfLoaded(pos.segment);
return !(scr && scr->_markedAsDeleted);
return !(scr && scr->isMarkedAsDeleted());
}
void SegManager::deallocateScript(int script_nr) {
@ -237,7 +237,7 @@ Object *SegManager::getObject(reg_t pos) {
} else if (mobj->getType() == SEG_TYPE_SCRIPT) {
Script *scr = (Script *)mobj;
if (pos.offset <= scr->getBufSize() && pos.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET
&& RAW_IS_OBJECT(scr->_buf + pos.offset)) {
&& RAW_IS_OBJECT(scr->getBuf(pos.offset))) {
obj = scr->getObject(pos.offset);
}
}
@ -384,12 +384,12 @@ LocalVariables *SegManager::allocLocalsSegment(Script *scr) {
locals = (LocalVariables *)_heap[scr->_localsSegment];
VERIFY(locals != NULL, "Re-used locals segment was NULL'd out");
VERIFY(locals->getType() == SEG_TYPE_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->getScriptNumber(), "Re-used locals segment belonged to other script");
} else
locals = (LocalVariables *)allocSegment(new LocalVariables(), &scr->_localsSegment);
scr->_localsBlock = locals;
locals->script_id = scr->_nr;
locals->script_id = scr->getScriptNumber();
locals->_locals.resize(scr->getLocalsCount());
return locals;
@ -1012,13 +1012,9 @@ int SegManager::instantiateScript(int scriptNum) {
scr->initialiseClasses(this);
if (getSciVersion() >= SCI_VERSION_1_1) {
scr->initialiseObjectsSci11(this);
scr->relocate(make_reg(segmentId, READ_SCI11ENDIAN_UINT16(scr->_heapStart)));
scr->initialiseObjectsSci11(this, segmentId);
} else {
scr->initialiseObjectsSci0(this);
byte *relocationBlock = scr->findBlock(SCI_OBJ_POINTERS);
if (relocationBlock)
scr->relocate(make_reg(segmentId, relocationBlock - scr->_buf + 4));
scr->initialiseObjectsSci0(this, segmentId);
}
return segmentId;
@ -1067,16 +1063,16 @@ void SegManager::uninstantiateScriptSci0(int script_nr) {
do {
reg.offset += objLength; // Step over the last checked object
objType = READ_SCI11ENDIAN_UINT16(scr->_buf + reg.offset);
objType = READ_SCI11ENDIAN_UINT16(scr->getBuf(reg.offset));
if (!objType)
break;
objLength = READ_SCI11ENDIAN_UINT16(scr->_buf + reg.offset + 2);
objLength = READ_SCI11ENDIAN_UINT16(scr->getBuf(reg.offset + 2));
reg.offset += 4; // Step over header
if ((objType == SCI_OBJ_OBJECT) || (objType == SCI_OBJ_CLASS)) { // object or class?
reg.offset += 8; // magic offset (SCRIPT_OBJECT_MAGIC_OFFSET)
int16 superclass = READ_SCI11ENDIAN_UINT16(scr->_buf + reg.offset + 2);
int16 superclass = READ_SCI11ENDIAN_UINT16(scr->getBuf(reg.offset + 2));
if (superclass >= 0) {
int superclass_script = getClass(superclass).script;

View file

@ -299,7 +299,7 @@ static reg_t validate_read_var(reg_t *r, reg_t *stack_base, int type, int max, i
EngineState *state = g_sci->getEngineState();
ExecStack *lastCall = state->xs;
Script *local_script = state->_segMan->getScriptIfLoaded(lastCall->local_segment);
int curScriptNr = local_script->_nr;
int curScriptNr = local_script->getScriptNumber();
if (lastCall->localCallOffset != -1) {
// if lastcall was actually a local call search back for a real call
@ -943,7 +943,7 @@ void run_vm(EngineState *s, bool restoring) {
s->_executionStackPosChanged = false;
obj = s->_segMan->getObject(s->xs->objp);
code_buf = scr->_buf;
code_buf = scr->getBuf();
code_buf_size = scr->getBufSize();
local_script = s->_segMan->getScriptIfLoaded(s->xs->local_segment);
if (!local_script) {
@ -1287,7 +1287,7 @@ void run_vm(EngineState *s, bool restoring) {
// for (int i = 0; i < opparams[0]; i++)
// s->xs->sp[i] = make_reg(0, 'ss');
//if (local_script->_nr == 140 && isIslandOfDrBrain) {
//if (local_script->getScriptNumber() == 140 && isIslandOfDrBrain) {
// // WORKAROUND for The Island of Dr. Brain, room 140.
// // Script 140 runs in an endless loop if we set its
// // variables to 0 here.

View file

@ -64,7 +64,7 @@ struct Class {
reg_t reg; ///< offset; script-relative offset, segment: 0 if not instantiated
};
#define RAW_IS_OBJECT(datablock) (READ_SCI11ENDIAN_UINT16(((byte *) datablock) + SCRIPT_OBJECT_MAGIC_OFFSET) == SCRIPT_OBJECT_MAGIC_NUMBER)
#define RAW_IS_OBJECT(datablock) (READ_SCI11ENDIAN_UINT16(((const byte *) datablock) + SCRIPT_OBJECT_MAGIC_OFFSET) == SCRIPT_OBJECT_MAGIC_NUMBER)
// A reference to an object's variable.
// The object is stored as a reg_t, the variable as an index into _variables