SCI: Add setter/getter methods to reg_t's

No functionality change has been made with this commit. This avoids
setting and getting the reg_t members directly, and is the basis of any
future work on large SCI3 scripts (larger than 64KB)
This commit is contained in:
Filippos Karapetis 2012-06-18 05:21:59 +03:00
parent 3c04d333f2
commit 2b50824133
36 changed files with 457 additions and 425 deletions

View file

@ -1243,7 +1243,7 @@ bool Console::cmdClassTable(int argc, const char **argv) {
for (uint i = 0; i < _engine->_gamestate->_segMan->classTableSize(); i++) { for (uint i = 0; i < _engine->_gamestate->_segMan->classTableSize(); i++) {
Class temp = _engine->_gamestate->_segMan->_classTable[i]; Class temp = _engine->_gamestate->_segMan->_classTable[i];
if (temp.reg.segment) { if (temp.reg.getSegment()) {
const char *className = _engine->_gamestate->_segMan->getObjectName(temp.reg); const char *className = _engine->_gamestate->_segMan->getObjectName(temp.reg);
if (argc == 1 || (argc == 2 && !strcmp(className, argv[1]))) { if (argc == 1 || (argc == 2 && !strcmp(className, argv[1]))) {
DebugPrintf(" Class 0x%x (%s) at %04x:%04x (script %d)\n", i, DebugPrintf(" Class 0x%x (%s) at %04x:%04x (script %d)\n", i,
@ -1688,7 +1688,7 @@ bool Console::cmdSavedBits(int argc, const char **argv) {
Common::Array<reg_t> entries = hunks->listAllDeallocatable(id); Common::Array<reg_t> entries = hunks->listAllDeallocatable(id);
for (uint i = 0; i < entries.size(); ++i) { for (uint i = 0; i < entries.size(); ++i) {
uint16 offset = entries[i].offset; uint16 offset = entries[i].getOffset();
const Hunk& h = hunks->_table[offset]; const Hunk& h = hunks->_table[offset];
if (strcmp(h.type, "SaveBits()") == 0) { if (strcmp(h.type, "SaveBits()") == 0) {
byte* memoryPtr = (byte *)h.mem; byte* memoryPtr = (byte *)h.mem;
@ -1751,12 +1751,12 @@ bool Console::cmdShowSavedBits(int argc, const char **argv) {
return true; return true;
} }
if (memoryHandle.segment != id || !hunks->isValidOffset(memoryHandle.offset)) { if (memoryHandle.getSegment() != id || !hunks->isValidOffset(memoryHandle.getOffset())) {
DebugPrintf("Invalid address.\n"); DebugPrintf("Invalid address.\n");
return true; return true;
} }
const Hunk& h = hunks->_table[memoryHandle.offset]; const Hunk& h = hunks->_table[memoryHandle.getOffset()];
if (strcmp(h.type, "SaveBits()") != 0) { if (strcmp(h.type, "SaveBits()") != 0) {
DebugPrintf("Invalid address.\n"); DebugPrintf("Invalid address.\n");
@ -2266,16 +2266,16 @@ bool Console::cmdGCShowReachable(int argc, const char **argv) {
return true; return true;
} }
SegmentObj *mobj = _engine->_gamestate->_segMan->getSegmentObj(addr.segment); SegmentObj *mobj = _engine->_gamestate->_segMan->getSegmentObj(addr.getSegment());
if (!mobj) { if (!mobj) {
DebugPrintf("Unknown segment : %x\n", addr.segment); DebugPrintf("Unknown segment : %x\n", addr.getSegment());
return 1; return 1;
} }
DebugPrintf("Reachable from %04x:%04x:\n", PRINT_REG(addr)); DebugPrintf("Reachable from %04x:%04x:\n", PRINT_REG(addr));
const Common::Array<reg_t> tmp = mobj->listAllOutgoingReferences(addr); const Common::Array<reg_t> tmp = mobj->listAllOutgoingReferences(addr);
for (Common::Array<reg_t>::const_iterator it = tmp.begin(); it != tmp.end(); ++it) for (Common::Array<reg_t>::const_iterator it = tmp.begin(); it != tmp.end(); ++it)
if (it->segment) if (it->getSegment())
g_sci->getSciDebugger()->DebugPrintf(" %04x:%04x\n", PRINT_REG(*it)); g_sci->getSciDebugger()->DebugPrintf(" %04x:%04x\n", PRINT_REG(*it));
return true; return true;
@ -2298,16 +2298,16 @@ bool Console::cmdGCShowFreeable(int argc, const char **argv) {
return true; return true;
} }
SegmentObj *mobj = _engine->_gamestate->_segMan->getSegmentObj(addr.segment); SegmentObj *mobj = _engine->_gamestate->_segMan->getSegmentObj(addr.getSegment());
if (!mobj) { if (!mobj) {
DebugPrintf("Unknown segment : %x\n", addr.segment); DebugPrintf("Unknown segment : %x\n", addr.getSegment());
return true; return true;
} }
DebugPrintf("Freeable in segment %04x:\n", addr.segment); DebugPrintf("Freeable in segment %04x:\n", addr.getSegment());
const Common::Array<reg_t> tmp = mobj->listAllDeallocatable(addr.segment); const Common::Array<reg_t> tmp = mobj->listAllDeallocatable(addr.getSegment());
for (Common::Array<reg_t>::const_iterator it = tmp.begin(); it != tmp.end(); ++it) for (Common::Array<reg_t>::const_iterator it = tmp.begin(); it != tmp.end(); ++it)
if (it->segment) if (it->getSegment())
g_sci->getSciDebugger()->DebugPrintf(" %04x:%04x\n", PRINT_REG(*it)); g_sci->getSciDebugger()->DebugPrintf(" %04x:%04x\n", PRINT_REG(*it));
return true; return true;
@ -2331,9 +2331,9 @@ bool Console::cmdGCNormalize(int argc, const char **argv) {
return true; return true;
} }
SegmentObj *mobj = _engine->_gamestate->_segMan->getSegmentObj(addr.segment); SegmentObj *mobj = _engine->_gamestate->_segMan->getSegmentObj(addr.getSegment());
if (!mobj) { if (!mobj) {
DebugPrintf("Unknown segment : %x\n", addr.segment); DebugPrintf("Unknown segment : %x\n", addr.getSegment());
return true; return true;
} }
@ -2572,12 +2572,12 @@ bool Console::cmdViewReference(int argc, const char **argv) {
DebugPrintf("%04x:%04x is of type 0x%x: ", PRINT_REG(reg), type_mask); DebugPrintf("%04x:%04x is of type 0x%x: ", PRINT_REG(reg), type_mask);
if (reg.segment == 0 && reg.offset == 0) { if (reg.getSegment() == 0 && reg.getOffset() == 0) {
DebugPrintf("Null.\n"); DebugPrintf("Null.\n");
return true; return true;
} }
if (reg_end.segment != reg.segment && reg_end != NULL_REG) { if (reg_end.getSegment() != reg.getSegment() && reg_end != NULL_REG) {
DebugPrintf("Ending segment different from starting segment. Assuming no bound on dump.\n"); DebugPrintf("Ending segment different from starting segment. Assuming no bound on dump.\n");
reg_end = NULL_REG; reg_end = NULL_REG;
} }
@ -2613,7 +2613,7 @@ bool Console::cmdViewReference(int argc, const char **argv) {
printObject(reg); printObject(reg);
break; break;
case SIG_TYPE_REFERENCE: { case SIG_TYPE_REFERENCE: {
switch (_engine->_gamestate->_segMan->getSegmentType(reg.segment)) { switch (_engine->_gamestate->_segMan->getSegmentType(reg.getSegment())) {
#ifdef ENABLE_SCI32 #ifdef ENABLE_SCI32
case SEG_TYPE_STRING: { case SEG_TYPE_STRING: {
DebugPrintf("SCI32 string\n"); DebugPrintf("SCI32 string\n");
@ -2629,21 +2629,20 @@ bool Console::cmdViewReference(int argc, const char **argv) {
} }
#endif #endif
default: { default: {
int size;
const SegmentRef block = _engine->_gamestate->_segMan->dereference(reg); const SegmentRef block = _engine->_gamestate->_segMan->dereference(reg);
size = block.maxSize; uint16 size = block.maxSize;
DebugPrintf("raw data\n"); DebugPrintf("raw data\n");
if (reg_end.segment != 0 && size < reg_end.offset - reg.offset) { if (reg_end.getSegment() != 0 && size < reg_end.getOffset() - reg.getOffset()) {
DebugPrintf("Block end out of bounds (size %d). Resetting.\n", size); DebugPrintf("Block end out of bounds (size %d). Resetting.\n", size);
reg_end = NULL_REG; reg_end = NULL_REG;
} }
if (reg_end.segment != 0 && (size >= reg_end.offset - reg.offset)) if (reg_end.getSegment() != 0 && (size >= reg_end.getOffset() - reg.getOffset()))
size = reg_end.offset - reg.offset; size = reg_end.getOffset() - reg.getOffset();
if (reg_end.segment != 0) if (reg_end.getSegment() != 0)
DebugPrintf("Block size less than or equal to %d\n", size); DebugPrintf("Block size less than or equal to %d\n", size);
if (block.isRaw) if (block.isRaw)
@ -2655,7 +2654,7 @@ bool Console::cmdViewReference(int argc, const char **argv) {
break; break;
} }
case SIG_TYPE_INTEGER: case SIG_TYPE_INTEGER:
DebugPrintf("arithmetic value\n %d (%04x)\n", (int16) reg.offset, reg.offset); DebugPrintf("arithmetic value\n %d (%04x)\n", (int16) reg.getOffset(), reg.getOffset());
break; break;
default: default:
DebugPrintf("unknown type %d.\n", type); DebugPrintf("unknown type %d.\n", type);
@ -2725,7 +2724,7 @@ bool Console::cmdBacktrace(int argc, const char **argv) {
switch (call.type) { switch (call.type) {
case EXEC_STACK_TYPE_CALL: // Normal function case EXEC_STACK_TYPE_CALL: // Normal function
if (call.type == EXEC_STACK_TYPE_CALL) if (call.type == EXEC_STACK_TYPE_CALL)
DebugPrintf(" %x: script %d - ", i, (*(Script *)_engine->_gamestate->_segMan->_heap[call.addr.pc.segment]).getScriptNumber()); DebugPrintf(" %x: script %d - ", i, (*(Script *)_engine->_gamestate->_segMan->_heap[call.addr.pc.getSegment()]).getScriptNumber());
if (call.debugSelector != -1) { if (call.debugSelector != -1) {
DebugPrintf("%s::%s(", objname, _engine->getKernel()->getSelectorName(call.debugSelector).c_str()); DebugPrintf("%s::%s(", objname, _engine->getKernel()->getSelectorName(call.debugSelector).c_str());
} else if (call.debugExportId != -1) { } else if (call.debugExportId != -1) {
@ -2917,7 +2916,7 @@ bool Console::cmdDisassemble(int argc, const char **argv) {
addr = disassemble(_engine->_gamestate, addr, printBWTag, printBytecode); addr = disassemble(_engine->_gamestate, addr, printBWTag, printBytecode);
if (addr.isNull() && prevAddr < farthestTarget) if (addr.isNull() && prevAddr < farthestTarget)
addr = prevAddr + 1; // skip past the ret addr = prevAddr + 1; // skip past the ret
} while (addr.offset > 0); } while (addr.getOffset() > 0);
return true; return true;
} }
@ -2934,10 +2933,10 @@ bool Console::cmdDisassembleAddress(int argc, const char **argv) {
} }
reg_t vpc = NULL_REG; reg_t vpc = NULL_REG;
int opCount = 1; uint opCount = 1;
bool printBWTag = false; bool printBWTag = false;
bool printBytes = false; bool printBytes = false;
int size; uint16 size;
if (parse_reg_t(_engine->_gamestate, argv[1], &vpc, false)) { if (parse_reg_t(_engine->_gamestate, argv[1], &vpc, false)) {
DebugPrintf("Invalid address passed.\n"); DebugPrintf("Invalid address passed.\n");
@ -2946,7 +2945,7 @@ bool Console::cmdDisassembleAddress(int argc, const char **argv) {
} }
SegmentRef ref = _engine->_gamestate->_segMan->dereference(vpc); SegmentRef ref = _engine->_gamestate->_segMan->dereference(vpc);
size = ref.maxSize + vpc.offset; // total segment size size = ref.maxSize + vpc.getOffset(); // total segment size
for (int i = 2; i < argc; i++) { for (int i = 2; i < argc; i++) {
if (!scumm_stricmp(argv[i], "bwt")) if (!scumm_stricmp(argv[i], "bwt"))
@ -2968,7 +2967,7 @@ bool Console::cmdDisassembleAddress(int argc, const char **argv) {
do { do {
vpc = disassemble(_engine->_gamestate, vpc, printBWTag, printBytes); vpc = disassemble(_engine->_gamestate, vpc, printBWTag, printBytes);
} while ((vpc.offset > 0) && (vpc.offset + 6 < size) && (--opCount)); } while ((vpc.getOffset() > 0) && (vpc.getOffset() + 6 < size) && (--opCount));
return true; return true;
} }
@ -3011,7 +3010,7 @@ void Console::printKernelCallsFound(int kernelFuncNum, bool showFoundScripts) {
// Now dissassemble each method of the script object // Now dissassemble each method of the script object
for (uint16 i = 0; i < obj->getMethodCount(); i++) { for (uint16 i = 0; i < obj->getMethodCount(); i++) {
reg_t fptr = obj->getFunction(i); reg_t fptr = obj->getFunction(i);
uint16 offset = fptr.offset; uint16 offset = fptr.getOffset();
int16 opparams[4]; int16 opparams[4];
byte extOpcode; byte extOpcode;
byte opcode; byte opcode;
@ -3699,8 +3698,8 @@ static int parse_reg_t(EngineState *s, const char *str, reg_t *dest, bool mayBeV
return 1; return 1;
// Now lookup the script's segment // Now lookup the script's segment
dest->segment = s->_segMan->getScriptSegment(script_nr); dest->setSegment(s->_segMan->getScriptSegment(script_nr));
if (!dest->segment) { if (!dest->getSegment()) {
return 1; return 1;
} }
@ -3782,19 +3781,19 @@ static int parse_reg_t(EngineState *s, const char *str, reg_t *dest, bool mayBeV
offsetStr = colon + 1; offsetStr = colon + 1;
Common::String segmentStr(str, colon); Common::String segmentStr(str, colon);
dest->segment = strtol(segmentStr.c_str(), &endptr, 16); dest->setSegment(strtol(segmentStr.c_str(), &endptr, 16));
if (*endptr) if (*endptr)
return 1; return 1;
} else { } else {
int val = 0; int val = 0;
dest->segment = 0; dest->setSegment(0);
if (charsCountNumber == charsCount) { if (charsCountNumber == charsCount) {
// Only numbers in input, assume decimal value // Only numbers in input, assume decimal value
val = strtol(str, &endptr, 10); val = strtol(str, &endptr, 10);
if (*endptr) if (*endptr)
return 1; // strtol failed? return 1; // strtol failed?
dest->offset = val; dest->setOffset(val);
return 0; return 0;
} else { } else {
// We also got letters, check if there were only hexadecimal letters and '0x' at the start or 'h' at the end // We also got letters, check if there were only hexadecimal letters and '0x' at the start or 'h' at the end
@ -3802,7 +3801,7 @@ static int parse_reg_t(EngineState *s, const char *str, reg_t *dest, bool mayBeV
val = strtol(str, &endptr, 16); val = strtol(str, &endptr, 16);
if ((*endptr != 'h') && (*endptr != 0)) if ((*endptr != 'h') && (*endptr != 0))
return 1; return 1;
dest->offset = val; dest->setOffset(val);
return 0; return 0;
} else { } else {
// Something else was in input, assume object name // Something else was in input, assume object name
@ -3851,9 +3850,9 @@ static int parse_reg_t(EngineState *s, const char *str, reg_t *dest, bool mayBeV
int val = strtol(offsetStr, &endptr, 16); int val = strtol(offsetStr, &endptr, 16);
if (relativeOffset) if (relativeOffset)
dest->offset += val; dest->incOffset(val);
else else
dest->offset = val; dest->setOffset(val);
if (*endptr) if (*endptr)
return 1; return 1;
@ -3933,15 +3932,15 @@ void Console::printList(List *list) {
while (!pos.isNull()) { while (!pos.isNull()) {
Node *node; Node *node;
NodeTable *nt = (NodeTable *)_engine->_gamestate->_segMan->getSegment(pos.segment, SEG_TYPE_NODES); NodeTable *nt = (NodeTable *)_engine->_gamestate->_segMan->getSegment(pos.getSegment(), SEG_TYPE_NODES);
if (!nt || !nt->isValidEntry(pos.offset)) { if (!nt || !nt->isValidEntry(pos.getOffset())) {
DebugPrintf(" WARNING: %04x:%04x: Doesn't contain list node!\n", DebugPrintf(" WARNING: %04x:%04x: Doesn't contain list node!\n",
PRINT_REG(pos)); PRINT_REG(pos));
return; return;
} }
node = &(nt->_table[pos.offset]); node = &(nt->_table[pos.getOffset()]);
DebugPrintf("\t%04x:%04x : %04x:%04x -> %04x:%04x\n", PRINT_REG(pos), PRINT_REG(node->key), PRINT_REG(node->value)); DebugPrintf("\t%04x:%04x : %04x:%04x -> %04x:%04x\n", PRINT_REG(pos), PRINT_REG(node->key), PRINT_REG(node->value));
@ -3960,37 +3959,37 @@ void Console::printList(List *list) {
} }
int Console::printNode(reg_t addr) { int Console::printNode(reg_t addr) {
SegmentObj *mobj = _engine->_gamestate->_segMan->getSegment(addr.segment, SEG_TYPE_LISTS); SegmentObj *mobj = _engine->_gamestate->_segMan->getSegment(addr.getSegment(), SEG_TYPE_LISTS);
if (mobj) { if (mobj) {
ListTable *lt = (ListTable *)mobj; ListTable *lt = (ListTable *)mobj;
List *list; List *list;
if (!lt->isValidEntry(addr.offset)) { if (!lt->isValidEntry(addr.getOffset())) {
DebugPrintf("Address does not contain a list\n"); DebugPrintf("Address does not contain a list\n");
return 1; return 1;
} }
list = &(lt->_table[addr.offset]); list = &(lt->_table[addr.getOffset()]);
DebugPrintf("%04x:%04x : first x last = (%04x:%04x, %04x:%04x)\n", PRINT_REG(addr), PRINT_REG(list->first), PRINT_REG(list->last)); DebugPrintf("%04x:%04x : first x last = (%04x:%04x, %04x:%04x)\n", PRINT_REG(addr), PRINT_REG(list->first), PRINT_REG(list->last));
} else { } else {
NodeTable *nt; NodeTable *nt;
Node *node; Node *node;
mobj = _engine->_gamestate->_segMan->getSegment(addr.segment, SEG_TYPE_NODES); mobj = _engine->_gamestate->_segMan->getSegment(addr.getSegment(), SEG_TYPE_NODES);
if (!mobj) { if (!mobj) {
DebugPrintf("Segment #%04x is not a list or node segment\n", addr.segment); DebugPrintf("Segment #%04x is not a list or node segment\n", addr.getSegment());
return 1; return 1;
} }
nt = (NodeTable *)mobj; nt = (NodeTable *)mobj;
if (!nt->isValidEntry(addr.offset)) { if (!nt->isValidEntry(addr.getOffset())) {
DebugPrintf("Address does not contain a node\n"); DebugPrintf("Address does not contain a node\n");
return 1; return 1;
} }
node = &(nt->_table[addr.offset]); node = &(nt->_table[addr.getOffset()]);
DebugPrintf("%04x:%04x : prev x next = (%04x:%04x, %04x:%04x); maps %04x:%04x -> %04x:%04x\n", DebugPrintf("%04x:%04x : prev x next = (%04x:%04x, %04x:%04x); maps %04x:%04x -> %04x:%04x\n",
PRINT_REG(addr), PRINT_REG(node->pred), PRINT_REG(node->succ), PRINT_REG(node->key), PRINT_REG(node->value)); PRINT_REG(addr), PRINT_REG(node->pred), PRINT_REG(node->succ), PRINT_REG(node->key), PRINT_REG(node->value));
@ -4028,8 +4027,8 @@ int Console::printObject(reg_t pos) {
reg_t val = obj->getVariable(i); reg_t val = obj->getVariable(i);
DebugPrintf("%04x:%04x", PRINT_REG(val)); DebugPrintf("%04x:%04x", PRINT_REG(val));
if (!val.segment) if (!val.getSegment())
DebugPrintf(" (%d)", val.offset); DebugPrintf(" (%d)", val.getOffset());
const Object *ref = s->_segMan->getObject(val); const Object *ref = s->_segMan->getObject(val);
if (ref) if (ref)
@ -4042,8 +4041,8 @@ int Console::printObject(reg_t pos) {
reg_t fptr = obj->getFunction(i); reg_t fptr = obj->getFunction(i);
DebugPrintf(" [%03x] %s = %04x:%04x\n", obj->getFuncSelector(i), _engine->getKernel()->getSelectorName(obj->getFuncSelector(i)).c_str(), PRINT_REG(fptr)); 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) if (s->_segMan->_heap[pos.getSegment()]->getType() == SEG_TYPE_SCRIPT)
DebugPrintf("\nOwner script: %d\n", s->_segMan->getScript(pos.segment)->getScriptNumber()); DebugPrintf("\nOwner script: %d\n", s->_segMan->getScript(pos.getSegment())->getScriptNumber());
return 0; return 0;
} }

View file

@ -74,11 +74,11 @@ bool GameFeatures::autoDetectSoundType() {
// Look up the script address // Look up the script address
reg_t addr = getDetectionAddr("Sound", SELECTOR(play)); reg_t addr = getDetectionAddr("Sound", SELECTOR(play));
if (!addr.segment) if (!addr.getSegment())
return false; return false;
uint16 offset = addr.offset; uint16 offset = addr.getOffset();
Script *script = _segMan->getScript(addr.segment); Script *script = _segMan->getScript(addr.getSegment());
uint16 intParam = 0xFFFF; uint16 intParam = 0xFFFF;
bool foundTarget = false; bool foundTarget = false;
@ -221,11 +221,11 @@ bool GameFeatures::autoDetectLofsType(Common::String gameSuperClassName, int met
// Look up the script address // Look up the script address
reg_t addr = getDetectionAddr(gameSuperClassName.c_str(), -1, methodNum); reg_t addr = getDetectionAddr(gameSuperClassName.c_str(), -1, methodNum);
if (!addr.segment) if (!addr.getSegment())
return false; return false;
uint16 offset = addr.offset; uint16 offset = addr.getOffset();
Script *script = _segMan->getScript(addr.segment); Script *script = _segMan->getScript(addr.getSegment());
while (true) { while (true) {
int16 opparams[4]; int16 opparams[4];
@ -320,11 +320,11 @@ bool GameFeatures::autoDetectGfxFunctionsType(int methodNum) {
// Look up the script address // Look up the script address
reg_t addr = getDetectionAddr("Rm", SELECTOR(overlay), methodNum); reg_t addr = getDetectionAddr("Rm", SELECTOR(overlay), methodNum);
if (!addr.segment) if (!addr.getSegment())
return false; return false;
uint16 offset = addr.offset; uint16 offset = addr.getOffset();
Script *script = _segMan->getScript(addr.segment); Script *script = _segMan->getScript(addr.getSegment());
while (true) { while (true) {
int16 opparams[4]; int16 opparams[4];
@ -474,11 +474,11 @@ bool GameFeatures::autoDetectSci21KernelType() {
// Look up the script address // Look up the script address
reg_t addr = getDetectionAddr("Sound", SELECTOR(play)); reg_t addr = getDetectionAddr("Sound", SELECTOR(play));
if (!addr.segment) if (!addr.getSegment())
return false; return false;
uint16 offset = addr.offset; uint16 offset = addr.getOffset();
Script *script = _segMan->getScript(addr.segment); Script *script = _segMan->getScript(addr.getSegment());
while (true) { while (true) {
int16 opparams[4]; int16 opparams[4];
@ -550,11 +550,11 @@ bool GameFeatures::autoDetectSci21StringFunctionType() {
// Look up the script address // Look up the script address
reg_t addr = getDetectionAddr("Str", SELECTOR(size)); reg_t addr = getDetectionAddr("Str", SELECTOR(size));
if (!addr.segment) if (!addr.getSegment())
return false; return false;
uint16 offset = addr.offset; uint16 offset = addr.getOffset();
Script *script = _segMan->getScript(addr.segment); Script *script = _segMan->getScript(addr.getSegment());
while (true) { while (true) {
int16 opparams[4]; int16 opparams[4];
@ -587,11 +587,11 @@ bool GameFeatures::autoDetectMoveCountType() {
// Look up the script address // Look up the script address
reg_t addr = getDetectionAddr("Motion", SELECTOR(doit)); reg_t addr = getDetectionAddr("Motion", SELECTOR(doit));
if (!addr.segment) if (!addr.getSegment())
return false; return false;
uint16 offset = addr.offset; uint16 offset = addr.getOffset();
Script *script = _segMan->getScript(addr.segment); Script *script = _segMan->getScript(addr.getSegment());
bool foundTarget = false; bool foundTarget = false;
while (true) { while (true) {

View file

@ -269,7 +269,7 @@ Common::String DirSeeker::getVirtualFilename(uint fileNumber) {
reg_t DirSeeker::firstFile(const Common::String &mask, reg_t buffer, SegManager *segMan) { reg_t DirSeeker::firstFile(const Common::String &mask, reg_t buffer, SegManager *segMan) {
// Verify that we are given a valid buffer // Verify that we are given a valid buffer
if (!buffer.segment) { if (!buffer.getSegment()) {
error("DirSeeker::firstFile('%s') invoked with invalid buffer", mask.c_str()); error("DirSeeker::firstFile('%s') invoked with invalid buffer", mask.c_str());
return NULL_REG; return NULL_REG;
} }

View file

@ -47,7 +47,7 @@ const char *segmentTypeNames[] = {
#endif #endif
void WorklistManager::push(reg_t reg) { void WorklistManager::push(reg_t reg) {
if (!reg.segment) // No numbers if (!reg.getSegment()) // No numbers
return; return;
debugC(kDebugLevelGC, "[GC] Adding %04x:%04x", PRINT_REG(reg)); debugC(kDebugLevelGC, "[GC] Adding %04x:%04x", PRINT_REG(reg));
@ -69,7 +69,7 @@ static AddrSet *normalizeAddresses(SegManager *segMan, const AddrSet &nonnormal_
for (AddrSet::const_iterator i = nonnormal_map.begin(); i != nonnormal_map.end(); ++i) { for (AddrSet::const_iterator i = nonnormal_map.begin(); i != nonnormal_map.end(); ++i) {
reg_t reg = i->_key; reg_t reg = i->_key;
SegmentObj *mobj = segMan->getSegmentObj(reg.segment); SegmentObj *mobj = segMan->getSegmentObj(reg.getSegment());
if (mobj) { if (mobj) {
reg = mobj->findCanonicAddress(segMan, reg); reg = mobj->findCanonicAddress(segMan, reg);
@ -85,11 +85,11 @@ static void processWorkList(SegManager *segMan, WorklistManager &wm, const Commo
while (!wm._worklist.empty()) { while (!wm._worklist.empty()) {
reg_t reg = wm._worklist.back(); reg_t reg = wm._worklist.back();
wm._worklist.pop_back(); wm._worklist.pop_back();
if (reg.segment != stackSegment) { // No need to repeat this one if (reg.getSegment() != stackSegment) { // No need to repeat this one
debugC(kDebugLevelGC, "[GC] Checking %04x:%04x", PRINT_REG(reg)); debugC(kDebugLevelGC, "[GC] Checking %04x:%04x", PRINT_REG(reg));
if (reg.segment < heap.size() && heap[reg.segment]) { if (reg.getSegment() < heap.size() && heap[reg.getSegment()]) {
// Valid heap object? Find its outgoing references! // Valid heap object? Find its outgoing references!
wm.pushArray(heap[reg.segment]->listAllOutgoingReferences(reg)); wm.pushArray(heap[reg.getSegment()]->listAllOutgoingReferences(reg));
} }
} }
} }

View file

@ -32,7 +32,7 @@ namespace Sci {
struct reg_t_Hash { struct reg_t_Hash {
uint operator()(const reg_t& x) const { uint operator()(const reg_t& x) const {
return (x.segment << 3) ^ x.offset ^ (x.offset << 16); return (x.getSegment() << 3) ^ x.getOffset() ^ (x.getOffset() << 16);
} }
}; };

View file

@ -357,27 +357,27 @@ static uint16 *parseKernelSignature(const char *kernelName, const char *writtenS
uint16 Kernel::findRegType(reg_t reg) { uint16 Kernel::findRegType(reg_t reg) {
// No segment? Must be integer // No segment? Must be integer
if (!reg.segment) if (!reg.getSegment())
return SIG_TYPE_INTEGER | (reg.offset ? 0 : SIG_TYPE_NULL); return SIG_TYPE_INTEGER | (reg.getOffset() ? 0 : SIG_TYPE_NULL);
if (reg.segment == 0xFFFF) if (reg.getSegment() == 0xFFFF)
return SIG_TYPE_UNINITIALIZED; return SIG_TYPE_UNINITIALIZED;
// Otherwise it's an object // Otherwise it's an object
SegmentObj *mobj = _segMan->getSegmentObj(reg.segment); SegmentObj *mobj = _segMan->getSegmentObj(reg.getSegment());
if (!mobj) if (!mobj)
return SIG_TYPE_ERROR; return SIG_TYPE_ERROR;
uint16 result = 0; uint16 result = 0;
if (!mobj->isValidOffset(reg.offset)) if (!mobj->isValidOffset(reg.getOffset()))
result |= SIG_IS_INVALID; result |= SIG_IS_INVALID;
switch (mobj->getType()) { switch (mobj->getType()) {
case SEG_TYPE_SCRIPT: case SEG_TYPE_SCRIPT:
if (reg.offset <= (*(Script *)mobj).getBufSize() && if (reg.getOffset() <= (*(Script *)mobj).getBufSize() &&
reg.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET && reg.getOffset() >= (uint)-SCRIPT_OBJECT_MAGIC_OFFSET &&
(*(Script *)mobj).offsetIsObject(reg.offset)) { (*(Script *)mobj).offsetIsObject(reg.getOffset())) {
result |= ((Script *)mobj)->getObject(reg.offset) ? SIG_TYPE_OBJECT : SIG_TYPE_REFERENCE; result |= ((Script *)mobj)->getObject(reg.getOffset()) ? SIG_TYPE_OBJECT : SIG_TYPE_REFERENCE;
} else } else
result |= SIG_TYPE_REFERENCE; result |= SIG_TYPE_REFERENCE;
break; break;
@ -608,7 +608,7 @@ void Kernel::mapFunctions() {
_kernelFuncs[id].workarounds = kernelMap->workarounds; _kernelFuncs[id].workarounds = kernelMap->workarounds;
if (kernelMap->subFunctions) { if (kernelMap->subFunctions) {
// Get version for subfunction identification // Get version for subfunction identification
SciVersion mySubVersion = (SciVersion)kernelMap->function(NULL, 0, NULL).offset; SciVersion mySubVersion = (SciVersion)kernelMap->function(NULL, 0, NULL).getOffset();
// Now check whats the highest subfunction-id for this version // Now check whats the highest subfunction-id for this version
const SciKernelMapSubEntry *kernelSubMap = kernelMap->subFunctions; const SciKernelMapSubEntry *kernelSubMap = kernelMap->subFunctions;
uint16 subFunctionCount = 0; uint16 subFunctionCount = 0;
@ -885,15 +885,15 @@ Common::String Kernel::lookupText(reg_t address, int index) {
char *seeker; char *seeker;
Resource *textres; Resource *textres;
if (address.segment) if (address.getSegment())
return _segMan->getString(address); return _segMan->getString(address);
int textlen; int textlen;
int _index = index; int _index = index;
textres = _resMan->findResource(ResourceId(kResourceTypeText, address.offset), 0); textres = _resMan->findResource(ResourceId(kResourceTypeText, address.getOffset()), 0);
if (!textres) { if (!textres) {
error("text.%03d not found", address.offset); error("text.%03d not found", address.getOffset());
return NULL; /* Will probably segfault */ return NULL; /* Will probably segfault */
} }
@ -907,7 +907,7 @@ Common::String Kernel::lookupText(reg_t address, int index) {
if (textlen) if (textlen)
return seeker; return seeker;
error("Index %d out of bounds in text.%03d", _index, address.offset); error("Index %d out of bounds in text.%03d", _index, address.getOffset());
return NULL; return NULL;
} }

View file

@ -157,7 +157,7 @@ reg_t kGetEvent(EngineState *s, int argc, reg_t *argv) {
s->r_acc = NULL_REG; s->r_acc = NULL_REG;
} }
if ((s->r_acc.offset) && (g_sci->_debugState.stopOnEvent)) { if ((s->r_acc.getOffset()) && (g_sci->_debugState.stopOnEvent)) {
g_sci->_debugState.stopOnEvent = false; g_sci->_debugState.stopOnEvent = false;
// A SCI event occurred, and we have been asked to stop, so open the debug console // A SCI event occurred, and we have been asked to stop, so open the debug console
@ -248,7 +248,7 @@ reg_t kGlobalToLocal(EngineState *s, int argc, reg_t *argv) {
reg_t planeObject = argc > 1 ? argv[1] : NULL_REG; // SCI32 reg_t planeObject = argc > 1 ? argv[1] : NULL_REG; // SCI32
SegManager *segMan = s->_segMan; SegManager *segMan = s->_segMan;
if (obj.segment) { if (obj.getSegment()) {
int16 x = readSelectorValue(segMan, obj, SELECTOR(x)); int16 x = readSelectorValue(segMan, obj, SELECTOR(x));
int16 y = readSelectorValue(segMan, obj, SELECTOR(y)); int16 y = readSelectorValue(segMan, obj, SELECTOR(y));
@ -267,7 +267,7 @@ reg_t kLocalToGlobal(EngineState *s, int argc, reg_t *argv) {
reg_t planeObject = argc > 1 ? argv[1] : NULL_REG; // SCI32 reg_t planeObject = argc > 1 ? argv[1] : NULL_REG; // SCI32
SegManager *segMan = s->_segMan; SegManager *segMan = s->_segMan;
if (obj.segment) { if (obj.getSegment()) {
int16 x = readSelectorValue(segMan, obj, SELECTOR(x)); int16 x = readSelectorValue(segMan, obj, SELECTOR(x));
int16 y = readSelectorValue(segMan, obj, SELECTOR(y)); int16 y = readSelectorValue(segMan, obj, SELECTOR(y));

View file

@ -185,7 +185,7 @@ reg_t kCheckFreeSpace(EngineState *s, int argc, reg_t *argv) {
reg_t kValidPath(EngineState *s, int argc, reg_t *argv) { reg_t kValidPath(EngineState *s, int argc, reg_t *argv) {
Common::String path = s->_segMan->getString(argv[0]); Common::String path = s->_segMan->getString(argv[0]);
debug(3, "kValidPath(%s) -> %d", path.c_str(), s->r_acc.offset); debug(3, "kValidPath(%s) -> %d", path.c_str(), s->r_acc.getOffset());
// Always return true // Always return true
return make_reg(0, 1); return make_reg(0, 1);
@ -866,7 +866,7 @@ reg_t kRestoreGame(EngineState *s, int argc, reg_t *argv) {
// saving a previously restored game. // saving a previously restored game.
// We set the current savedgame-id directly and remove the script // We set the current savedgame-id directly and remove the script
// code concerning this via script patch. // code concerning this via script patch.
s->variables[VAR_GLOBAL][0xB3].offset = SAVEGAMEID_OFFICIALRANGE_START + savegameId; s->variables[VAR_GLOBAL][0xB3].setOffset(SAVEGAMEID_OFFICIALRANGE_START + savegameId);
} }
} else { } else {
s->r_acc = TRUE_REG; s->r_acc = TRUE_REG;

View file

@ -337,7 +337,7 @@ reg_t kTextSize(EngineState *s, int argc, reg_t *argv) {
Common::String sep_str; Common::String sep_str;
const char *sep = NULL; const char *sep = NULL;
if ((argc > 4) && (argv[4].segment)) { if ((argc > 4) && (argv[4].getSegment())) {
sep_str = s->_segMan->getString(argv[4]); sep_str = s->_segMan->getString(argv[4]);
sep = sep_str.c_str(); sep = sep_str.c_str();
} }
@ -789,7 +789,7 @@ void _k_GenericDrawControl(EngineState *s, reg_t controlObject, bool hilite) {
Common::Rect rect; Common::Rect rect;
TextAlignment alignment; TextAlignment alignment;
int16 mode, maxChars, cursorPos, upperPos, listCount, i; int16 mode, maxChars, cursorPos, upperPos, listCount, i;
int16 upperOffset, cursorOffset; uint16 upperOffset, cursorOffset;
GuiResourceId viewId; GuiResourceId viewId;
int16 loopNo; int16 loopNo;
int16 celNo; int16 celNo;
@ -871,7 +871,7 @@ void _k_GenericDrawControl(EngineState *s, reg_t controlObject, bool hilite) {
listCount = 0; listSeeker = textReference; listCount = 0; listSeeker = textReference;
while (s->_segMan->strlen(listSeeker) > 0) { while (s->_segMan->strlen(listSeeker) > 0) {
listCount++; listCount++;
listSeeker.offset += maxChars; listSeeker.incOffset(maxChars);
} }
// TODO: This is rather convoluted... It would be a lot cleaner // TODO: This is rather convoluted... It would be a lot cleaner
@ -885,11 +885,11 @@ void _k_GenericDrawControl(EngineState *s, reg_t controlObject, bool hilite) {
for (i = 0; i < listCount; i++) { for (i = 0; i < listCount; i++) {
listStrings[i] = s->_segMan->getString(listSeeker); listStrings[i] = s->_segMan->getString(listSeeker);
listEntries[i] = listStrings[i].c_str(); listEntries[i] = listStrings[i].c_str();
if (listSeeker.offset == upperOffset) if (listSeeker.getOffset() == upperOffset)
upperPos = i; upperPos = i;
if (listSeeker.offset == cursorOffset) if (listSeeker.getOffset() == cursorOffset)
cursorPos = i; cursorPos = i;
listSeeker.offset += maxChars; listSeeker.incOffset(maxChars);
} }
} }
@ -1104,7 +1104,7 @@ reg_t kNewWindow(EngineState *s, int argc, reg_t *argv) {
rect2 = Common::Rect (argv[5].toSint16(), argv[4].toSint16(), argv[7].toSint16(), argv[6].toSint16()); rect2 = Common::Rect (argv[5].toSint16(), argv[4].toSint16(), argv[7].toSint16(), argv[6].toSint16());
Common::String title; Common::String title;
if (argv[4 + argextra].segment) { if (argv[4 + argextra].getSegment()) {
title = s->_segMan->getString(argv[4 + argextra]); title = s->_segMan->getString(argv[4 + argextra]);
title = g_sci->strSplit(title.c_str(), NULL); title = g_sci->strSplit(title.c_str(), NULL);
} }
@ -1143,7 +1143,7 @@ reg_t kDisplay(EngineState *s, int argc, reg_t *argv) {
Common::String text; Common::String text;
if (textp.segment) { if (textp.getSegment()) {
argc--; argv++; argc--; argv++;
text = s->_segMan->getString(textp); text = s->_segMan->getString(textp);
} else { } else {

View file

@ -140,7 +140,7 @@ reg_t kIsOnMe(EngineState *s, int argc, reg_t *argv) {
uint16 x = argv[0].toUint16(); uint16 x = argv[0].toUint16();
uint16 y = argv[1].toUint16(); uint16 y = argv[1].toUint16();
reg_t targetObject = argv[2]; reg_t targetObject = argv[2];
uint16 illegalBits = argv[3].offset; uint16 illegalBits = argv[3].getOffset();
Common::Rect nsRect = g_sci->_gfxCompare->getNSRect(targetObject, true); Common::Rect nsRect = g_sci->_gfxCompare->getNSRect(targetObject, true);
// we assume that x, y are local coordinates // we assume that x, y are local coordinates

View file

@ -409,10 +409,14 @@ int sort_temp_cmp(const void *p1, const void *p2) {
const sort_temp_t *st1 = (const sort_temp_t *)p1; const sort_temp_t *st1 = (const sort_temp_t *)p1;
const sort_temp_t *st2 = (const sort_temp_t *)p2; const sort_temp_t *st2 = (const sort_temp_t *)p2;
if (st1->order.segment < st2->order.segment || (st1->order.segment == st2->order.segment && st1->order.offset < st2->order.offset)) if (st1->order.getSegment() < st2->order.getSegment() ||
(st1->order.getSegment() == st2->order.getSegment() &&
st1->order.getOffset() < st2->order.getOffset()))
return -1; return -1;
if (st1->order.segment > st2->order.segment || (st1->order.segment == st2->order.segment && st1->order.offset > st2->order.offset)) if (st1->order.getSegment() > st2->order.getSegment() ||
(st1->order.getSegment() == st2->order.getSegment() &&
st1->order.getOffset() > st2->order.getOffset()))
return 1; return 1;
return 0; return 0;
@ -665,15 +669,15 @@ reg_t kArray(EngineState *s, int argc, reg_t *argv) {
if (argv[2].toUint16() == 3) if (argv[2].toUint16() == 3)
return kString(s, argc, argv); return kString(s, argc, argv);
} else { } else {
if (s->_segMan->getSegmentType(argv[1].segment) == SEG_TYPE_STRING || if (s->_segMan->getSegmentType(argv[1].getSegment()) == SEG_TYPE_STRING ||
s->_segMan->getSegmentType(argv[1].segment) == SEG_TYPE_SCRIPT) { s->_segMan->getSegmentType(argv[1].getSegment()) == SEG_TYPE_SCRIPT) {
return kString(s, argc, argv); return kString(s, argc, argv);
} }
#if 0 #if 0
if (op == 6) { if (op == 6) {
if (s->_segMan->getSegmentType(argv[3].segment) == SEG_TYPE_STRING || if (s->_segMan->getSegmentType(argv[3].getSegment()) == SEG_TYPE_STRING ||
s->_segMan->getSegmentType(argv[3].segment) == SEG_TYPE_SCRIPT) { s->_segMan->getSegmentType(argv[3].getSegment()) == SEG_TYPE_SCRIPT) {
return kString(s, argc, argv); return kString(s, argc, argv);
} }
} }
@ -792,7 +796,7 @@ reg_t kArray(EngineState *s, int argc, reg_t *argv) {
#endif #endif
return NULL_REG; return NULL_REG;
} }
if (s->_segMan->getSegmentObj(argv[1].segment)->getType() != SEG_TYPE_ARRAY) if (s->_segMan->getSegmentObj(argv[1].getSegment())->getType() != SEG_TYPE_ARRAY)
error("kArray(Dup): Request to duplicate a segment which isn't an array"); error("kArray(Dup): Request to duplicate a segment which isn't an array");
reg_t arrayHandle; reg_t arrayHandle;

View file

@ -128,7 +128,7 @@ reg_t kMemoryInfo(EngineState *s, int argc, reg_t *argv) {
// fragmented // fragmented
const uint16 size = 0x7fea; const uint16 size = 0x7fea;
switch (argv[0].offset) { switch (argv[0].getOffset()) {
case K_MEMORYINFO_LARGEST_HEAP_BLOCK: case K_MEMORYINFO_LARGEST_HEAP_BLOCK:
// In order to prevent "Memory fragmented" dialogs from // In order to prevent "Memory fragmented" dialogs from
// popping up in some games, we must return FREE_HEAP - 2 here. // popping up in some games, we must return FREE_HEAP - 2 here.
@ -140,7 +140,7 @@ reg_t kMemoryInfo(EngineState *s, int argc, reg_t *argv) {
return make_reg(0, size); return make_reg(0, size);
default: default:
error("Unknown MemoryInfo operation: %04x", argv[0].offset); error("Unknown MemoryInfo operation: %04x", argv[0].getOffset());
} }
return NULL_REG; return NULL_REG;
@ -304,7 +304,7 @@ reg_t kMemory(EngineState *s, int argc, reg_t *argv) {
break; break;
} }
case K_MEMORY_PEEK : { case K_MEMORY_PEEK : {
if (!argv[1].segment) { if (!argv[1].getSegment()) {
// This occurs in KQ5CD when interacting with certain objects // This occurs in KQ5CD when interacting with certain objects
warning("Attempt to peek invalid memory at %04x:%04x", PRINT_REG(argv[1])); warning("Attempt to peek invalid memory at %04x:%04x", PRINT_REG(argv[1]));
return s->r_acc; return s->r_acc;
@ -334,11 +334,11 @@ reg_t kMemory(EngineState *s, int argc, reg_t *argv) {
} }
if (ref.isRaw) { if (ref.isRaw) {
if (argv[2].segment) { if (argv[2].getSegment()) {
error("Attempt to poke memory reference %04x:%04x to %04x:%04x", PRINT_REG(argv[2]), PRINT_REG(argv[1])); error("Attempt to poke memory reference %04x:%04x to %04x:%04x", PRINT_REG(argv[2]), PRINT_REG(argv[1]));
return s->r_acc; return s->r_acc;
} }
WRITE_SCIENDIAN_UINT16(ref.raw, argv[2].offset); // Amiga versions are BE WRITE_SCIENDIAN_UINT16(ref.raw, argv[2].getOffset()); // Amiga versions are BE
} else { } else {
if (ref.skipByte) if (ref.skipByte)
error("Attempt to poke memory at odd offset %04X:%04X", PRINT_REG(argv[1])); error("Attempt to poke memory at odd offset %04X:%04X", PRINT_REG(argv[1]));

View file

@ -48,7 +48,7 @@ reg_t kSaid(EngineState *s, int argc, reg_t *argv) {
const int debug_parser = 0; const int debug_parser = 0;
#endif #endif
if (!heap_said_block.segment) if (!heap_said_block.getSegment())
return NULL_REG; return NULL_REG;
said_block = (byte *)s->_segMan->derefBulkPtr(heap_said_block, 0); said_block = (byte *)s->_segMan->derefBulkPtr(heap_said_block, 0);

View file

@ -367,7 +367,7 @@ static void draw_input(EngineState *s, reg_t poly_list, Common::Point start, Com
draw_point(s, start, 1, width, height); draw_point(s, start, 1, width, height);
draw_point(s, end, 0, width, height); draw_point(s, end, 0, width, height);
if (!poly_list.segment) if (!poly_list.getSegment())
return; return;
list = s->_segMan->lookupList(poly_list); list = s->_segMan->lookupList(poly_list);
@ -423,7 +423,7 @@ static void print_input(EngineState *s, reg_t poly_list, Common::Point start, Co
debug("End point: (%i, %i)", end.x, end.y); debug("End point: (%i, %i)", end.x, end.y);
debug("Optimization level: %i", opt); debug("Optimization level: %i", opt);
if (!poly_list.segment) if (!poly_list.getSegment())
return; return;
list = s->_segMan->lookupList(poly_list); list = s->_segMan->lookupList(poly_list);
@ -1180,7 +1180,7 @@ static PathfindingState *convert_polygon_set(EngineState *s, reg_t poly_list, Co
PathfindingState *pf_s = new PathfindingState(width, height); PathfindingState *pf_s = new PathfindingState(width, height);
// Convert all polygons // Convert all polygons
if (poly_list.segment) { if (poly_list.getSegment()) {
List *list = s->_segMan->lookupList(poly_list); List *list = s->_segMan->lookupList(poly_list);
Node *node = s->_segMan->lookupNode(list->first); Node *node = s->_segMan->lookupNode(list->first);
@ -1503,7 +1503,7 @@ reg_t kAvoidPath(EngineState *s, int argc, reg_t *argv) {
draw_point(s, start, 1, width, height); draw_point(s, start, 1, width, height);
draw_point(s, end, 0, width, height); draw_point(s, end, 0, width, height);
if (poly_list.segment) { if (poly_list.getSegment()) {
print_input(s, poly_list, start, end, opt); print_input(s, poly_list, start, end, opt);
draw_input(s, poly_list, start, end, opt, width, height); draw_input(s, poly_list, start, end, opt, width, height);
} }

View file

@ -140,7 +140,7 @@ reg_t kClone(EngineState *s, int argc, reg_t *argv) {
debugC(kDebugLevelMemory, "Attempting to clone from %04x:%04x", PRINT_REG(parentAddr)); debugC(kDebugLevelMemory, "Attempting to clone from %04x:%04x", PRINT_REG(parentAddr));
uint16 infoSelector = parentObj->getInfoSelector().offset; uint16 infoSelector = parentObj->getInfoSelector().getOffset();
cloneObj = s->_segMan->allocateClone(&cloneAddr); cloneObj = s->_segMan->allocateClone(&cloneAddr);
if (!cloneObj) { if (!cloneObj) {
@ -169,8 +169,8 @@ reg_t kClone(EngineState *s, int argc, reg_t *argv) {
cloneObj->setSpeciesSelector(cloneObj->getPos()); cloneObj->setSpeciesSelector(cloneObj->getPos());
if (parentObj->isClass()) if (parentObj->isClass())
cloneObj->setSuperClassSelector(parentObj->getPos()); cloneObj->setSuperClassSelector(parentObj->getPos());
s->_segMan->getScript(parentObj->getPos().segment)->incrementLockers(); s->_segMan->getScript(parentObj->getPos().getSegment())->incrementLockers();
s->_segMan->getScript(cloneObj->getPos().segment)->incrementLockers(); s->_segMan->getScript(cloneObj->getPos().getSegment())->incrementLockers();
return cloneAddr; return cloneAddr;
} }
@ -191,7 +191,7 @@ reg_t kDisposeClone(EngineState *s, int argc, reg_t *argv) {
// At least kq4early relies on this behavior. The scripts clone "Sound", then set bit 1 manually // At least kq4early relies on this behavior. The scripts clone "Sound", then set bit 1 manually
// and call kDisposeClone later. In that case we may not free it, otherwise we will run into issues // and call kDisposeClone later. In that case we may not free it, otherwise we will run into issues
// later, because kIsObject would then return false and Sound object wouldn't get checked. // later, because kIsObject would then return false and Sound object wouldn't get checked.
uint16 infoSelector = object->getInfoSelector().offset; uint16 infoSelector = object->getInfoSelector().getOffset();
if ((infoSelector & 3) == kInfoFlagClone) if ((infoSelector & 3) == kInfoFlagClone)
object->markAsFreed(); object->markAsFreed();
@ -203,7 +203,7 @@ reg_t kScriptID(EngineState *s, int argc, reg_t *argv) {
int script = argv[0].toUint16(); int script = argv[0].toUint16();
uint16 index = (argc > 1) ? argv[1].toUint16() : 0; uint16 index = (argc > 1) ? argv[1].toUint16() : 0;
if (argv[0].segment) if (argv[0].getSegment())
return argv[0]; return argv[0];
SegmentId scriptSeg = s->_segMan->getScriptSegment(script, SCRIPT_GET_LOAD); SegmentId scriptSeg = s->_segMan->getScriptSegment(script, SCRIPT_GET_LOAD);
@ -251,12 +251,12 @@ reg_t kScriptID(EngineState *s, int argc, reg_t *argv) {
} }
reg_t kDisposeScript(EngineState *s, int argc, reg_t *argv) { reg_t kDisposeScript(EngineState *s, int argc, reg_t *argv) {
int script = argv[0].offset; int script = argv[0].getOffset();
SegmentId id = s->_segMan->getScriptSegment(script); SegmentId id = s->_segMan->getScriptSegment(script);
Script *scr = s->_segMan->getScriptIfLoaded(id); Script *scr = s->_segMan->getScriptIfLoaded(id);
if (scr && !scr->isMarkedAsDeleted()) { if (scr && !scr->isMarkedAsDeleted()) {
if (s->_executionStack.back().addr.pc.segment != id) if (s->_executionStack.back().addr.pc.getSegment() != id)
scr->setLockers(1); scr->setLockers(1);
} }
@ -273,7 +273,7 @@ reg_t kDisposeScript(EngineState *s, int argc, reg_t *argv) {
} }
reg_t kIsObject(EngineState *s, int argc, reg_t *argv) { reg_t kIsObject(EngineState *s, int argc, reg_t *argv) {
if (argv[0].offset == SIGNAL_OFFSET) // Treated specially if (argv[0].getOffset() == SIGNAL_OFFSET) // Treated specially
return NULL_REG; return NULL_REG;
else else
return make_reg(0, s->_segMan->isHeapObject(argv[0])); return make_reg(0, s->_segMan->isHeapObject(argv[0]));

View file

@ -33,7 +33,7 @@ namespace Sci {
reg_t kStrEnd(EngineState *s, int argc, reg_t *argv) { reg_t kStrEnd(EngineState *s, int argc, reg_t *argv) {
reg_t address = argv[0]; reg_t address = argv[0];
address.offset += s->_segMan->strlen(address); address.incOffset(s->_segMan->strlen(address));
return address; return address;
} }
@ -123,18 +123,22 @@ reg_t kStrAt(EngineState *s, int argc, reg_t *argv) {
oddOffset = !oddOffset; oddOffset = !oddOffset;
if (!oddOffset) { if (!oddOffset) {
value = tmp.offset & 0x00ff; value = tmp.getOffset() & 0x00ff;
if (argc > 2) { /* Request to modify this char */ if (argc > 2) { /* Request to modify this char */
tmp.offset &= 0xff00; uint16 offset = tmp.toUint16();
tmp.offset |= newvalue; offset &= 0xff00;
tmp.segment = 0; offset |= newvalue;
tmp.setOffset(offset);
tmp.setSegment(0);
} }
} else { } else {
value = tmp.offset >> 8; value = tmp.getOffset() >> 8;
if (argc > 2) { /* Request to modify this char */ if (argc > 2) { /* Request to modify this char */
tmp.offset &= 0x00ff; uint16 offset = tmp.toUint16();
tmp.offset |= newvalue << 8; offset &= 0x00ff;
tmp.segment = 0; offset |= newvalue << 8;
tmp.setOffset(offset);
tmp.setSegment(0);
} }
} }
} }
@ -204,7 +208,7 @@ reg_t kFormat(EngineState *s, int argc, reg_t *argv) {
int strLength = 0; /* Used for stuff like "%13s" */ int strLength = 0; /* Used for stuff like "%13s" */
bool unsignedVar = false; bool unsignedVar = false;
if (position.segment) if (position.getSegment())
startarg = 2; startarg = 2;
else { else {
// WORKAROUND: QFG1 VGA Mac calls this without the first parameter (dest). It then // WORKAROUND: QFG1 VGA Mac calls this without the first parameter (dest). It then
@ -291,7 +295,7 @@ reg_t kFormat(EngineState *s, int argc, reg_t *argv) {
if (extralen < 0) if (extralen < 0)
extralen = 0; extralen = 0;
if (reg.segment) /* Heap address? */ if (reg.getSegment()) /* Heap address? */
paramindex++; paramindex++;
else else
paramindex += 2; /* No, text resource address */ paramindex += 2; /* No, text resource address */
@ -654,7 +658,7 @@ reg_t kString(EngineState *s, int argc, reg_t *argv) {
return make_reg(0, s->_segMan->getString(argv[1]).size()); return make_reg(0, s->_segMan->getString(argv[1]).size());
case 2: { // At (return value at an index) case 2: { // At (return value at an index)
// Note that values are put in bytes to avoid sign extension // Note that values are put in bytes to avoid sign extension
if (argv[1].segment == s->_segMan->getStringSegmentId()) { if (argv[1].getSegment() == s->_segMan->getStringSegmentId()) {
SciString *string = s->_segMan->lookupString(argv[1]); SciString *string = s->_segMan->lookupString(argv[1]);
byte val = string->getRawData()[argv[2].toUint16()]; byte val = string->getRawData()[argv[2].toUint16()];
return make_reg(0, val); return make_reg(0, val);
@ -705,7 +709,7 @@ reg_t kString(EngineState *s, int argc, reg_t *argv) {
uint32 string2Size = 0; uint32 string2Size = 0;
Common::String string; Common::String string;
if (argv[3].segment == s->_segMan->getStringSegmentId()) { if (argv[3].getSegment() == s->_segMan->getStringSegmentId()) {
SciString *sstr; SciString *sstr;
sstr = s->_segMan->lookupString(argv[3]); sstr = s->_segMan->lookupString(argv[3]);
string2 = sstr->getRawData(); string2 = sstr->getRawData();
@ -755,7 +759,7 @@ reg_t kString(EngineState *s, int argc, reg_t *argv) {
SciString *dupString = s->_segMan->allocateString(&stringHandle); SciString *dupString = s->_segMan->allocateString(&stringHandle);
if (argv[1].segment == s->_segMan->getStringSegmentId()) { if (argv[1].getSegment() == s->_segMan->getStringSegmentId()) {
*dupString = *s->_segMan->lookupString(argv[1]); *dupString = *s->_segMan->lookupString(argv[1]);
} else { } else {
dupString->fromString(s->_segMan->getString(argv[1])); dupString->fromString(s->_segMan->getString(argv[1]));

View file

@ -135,7 +135,7 @@ reg_t kShowMovie(EngineState *s, int argc, reg_t *argv) {
Video::VideoDecoder *videoDecoder = 0; Video::VideoDecoder *videoDecoder = 0;
if (argv[0].segment != 0) { if (argv[0].getSegment() != 0) {
Common::String filename = s->_segMan->getString(argv[0]); Common::String filename = s->_segMan->getString(argv[0]);
if (g_sci->getPlatform() == Common::kPlatformMacintosh) { if (g_sci->getPlatform() == Common::kPlatformMacintosh) {
@ -303,7 +303,7 @@ reg_t kPlayVMD(EngineState *s, int argc, reg_t *argv) {
// with subfx 21. The subtleness has to do with creation of temporary // with subfx 21. The subtleness has to do with creation of temporary
// planes and positioning relative to such planes. // planes and positioning relative to such planes.
uint16 flags = argv[3].offset; uint16 flags = argv[3].getOffset();
Common::String flagspec; Common::String flagspec;
if (argc > 3) { if (argc > 3) {
@ -331,12 +331,12 @@ reg_t kPlayVMD(EngineState *s, int argc, reg_t *argv) {
s->_videoState.flags = flags; s->_videoState.flags = flags;
} }
warning("x, y: %d, %d", argv[1].offset, argv[2].offset); warning("x, y: %d, %d", argv[1].getOffset(), argv[2].getOffset());
s->_videoState.x = argv[1].offset; s->_videoState.x = argv[1].getOffset();
s->_videoState.y = argv[2].offset; s->_videoState.y = argv[2].getOffset();
if (argc > 4 && flags & 16) if (argc > 4 && flags & 16)
warning("gammaBoost: %d%% between palette entries %d and %d", argv[4].offset, argv[5].offset, argv[6].offset); warning("gammaBoost: %d%% between palette entries %d and %d", argv[4].getOffset(), argv[5].getOffset(), argv[6].getOffset());
break; break;
} }
case 6: // Play case 6: // Play

View file

@ -44,15 +44,15 @@ static bool relocateBlock(Common::Array<reg_t> &block, int block_location, Segme
error("Attempt to relocate odd variable #%d.5e (relative to %04x)\n", idx, block_location); error("Attempt to relocate odd variable #%d.5e (relative to %04x)\n", idx, block_location);
return false; return false;
} }
block[idx].segment = segment; // Perform relocation block[idx].setSegment(segment); // Perform relocation
if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1) if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1)
block[idx].offset += scriptSize; block[idx].incOffset(scriptSize);
return true; return true;
} }
void Object::init(byte *buf, reg_t obj_pos, bool initVariables) { void Object::init(byte *buf, reg_t obj_pos, bool initVariables) {
byte *data = buf + obj_pos.offset; byte *data = buf + obj_pos.getOffset();
_baseObj = data; _baseObj = data;
_pos = obj_pos; _pos = obj_pos;
@ -109,7 +109,7 @@ int Object::locateVarSelector(SegManager *segMan, Selector slc) const {
} }
bool Object::relocateSci0Sci21(SegmentId segment, int location, size_t scriptSize) { bool Object::relocateSci0Sci21(SegmentId segment, int location, size_t scriptSize) {
return relocateBlock(_variables, getPos().offset, segment, location, scriptSize); return relocateBlock(_variables, getPos().getOffset(), segment, location, scriptSize);
} }
bool Object::relocateSci3(SegmentId segment, uint32 location, int offset, size_t scriptSize) { bool Object::relocateSci3(SegmentId segment, uint32 location, int offset, size_t scriptSize) {
@ -117,8 +117,8 @@ bool Object::relocateSci3(SegmentId segment, uint32 location, int offset, size_t
for (uint i = 0; i < _variables.size(); ++i) { for (uint i = 0; i < _variables.size(); ++i) {
if (location == _propertyOffsetsSci3[i]) { if (location == _propertyOffsetsSci3[i]) {
_variables[i].segment = segment; _variables[i].setSegment(segment);
_variables[i].offset += offset; _variables[i].incOffset(offset);
return true; return true;
} }
} }
@ -148,21 +148,21 @@ int Object::propertyOffsetToId(SegManager *segMan, int propertyOffset) const {
} }
void Object::initSpecies(SegManager *segMan, reg_t addr) { void Object::initSpecies(SegManager *segMan, reg_t addr) {
uint16 speciesOffset = getSpeciesSelector().offset; uint16 speciesOffset = getSpeciesSelector().getOffset();
if (speciesOffset == 0xffff) // -1 if (speciesOffset == 0xffff) // -1
setSpeciesSelector(NULL_REG); // no species setSpeciesSelector(NULL_REG); // no species
else else
setSpeciesSelector(segMan->getClassAddress(speciesOffset, SCRIPT_GET_LOCK, addr.segment)); setSpeciesSelector(segMan->getClassAddress(speciesOffset, SCRIPT_GET_LOCK, addr.getSegment()));
} }
void Object::initSuperClass(SegManager *segMan, reg_t addr) { void Object::initSuperClass(SegManager *segMan, reg_t addr) {
uint16 superClassOffset = getSuperClassSelector().offset; uint16 superClassOffset = getSuperClassSelector().getOffset();
if (superClassOffset == 0xffff) // -1 if (superClassOffset == 0xffff) // -1
setSuperClassSelector(NULL_REG); // no superclass setSuperClassSelector(NULL_REG); // no superclass
else else
setSuperClassSelector(segMan->getClassAddress(superClassOffset, SCRIPT_GET_LOCK, addr.segment)); setSuperClassSelector(segMan->getClassAddress(superClassOffset, SCRIPT_GET_LOCK, addr.getSegment()));
} }
bool Object::initBaseObject(SegManager *segMan, reg_t addr, bool doInitSuperClass) { bool Object::initBaseObject(SegManager *segMan, reg_t addr, bool doInitSuperClass) {
@ -187,7 +187,7 @@ bool Object::initBaseObject(SegManager *segMan, reg_t addr, bool doInitSuperClas
// The effect is that a number of its method selectors may be // The effect is that a number of its method selectors may be
// treated as variable selectors, causing unpredictable effects. // treated as variable selectors, causing unpredictable effects.
int objScript = segMan->getScript(_pos.segment)->getScriptNumber(); int objScript = segMan->getScript(_pos.getSegment())->getScriptNumber();
// We have to do a little bit of work to get the name of the object // We have to do a little bit of work to get the name of the object
// before any relocations are done. // before any relocations are done.
@ -196,7 +196,7 @@ bool Object::initBaseObject(SegManager *segMan, reg_t addr, bool doInitSuperClas
if (nameReg.isNull()) { if (nameReg.isNull()) {
name = "<no name>"; name = "<no name>";
} else { } else {
nameReg.segment = _pos.segment; nameReg.setSegment(_pos.getSegment());
name = segMan->derefString(nameReg); name = segMan->derefString(nameReg);
if (!name) if (!name)
name = "<invalid name>"; name = "<invalid name>";

View file

@ -168,7 +168,7 @@ public:
uint16 offset = (getSciVersion() < SCI_VERSION_1_1) ? _methodCount + 1 + i : i * 2 + 2; uint16 offset = (getSciVersion() < SCI_VERSION_1_1) ? _methodCount + 1 + i : i * 2 + 2;
if (getSciVersion() == SCI_VERSION_3) if (getSciVersion() == SCI_VERSION_3)
offset--; offset--;
return make_reg(_pos.segment, _baseMethod[offset]); return make_reg(_pos.getSegment(), _baseMethod[offset]);
} }
Selector getFuncSelector(uint16 i) const { Selector getFuncSelector(uint16 i) const {
@ -198,7 +198,7 @@ public:
*/ */
int locateVarSelector(SegManager *segMan, Selector slc) const; int locateVarSelector(SegManager *segMan, Selector slc) const;
bool isClass() const { return (getInfoSelector().offset & kInfoFlagClass); } bool isClass() const { return (getInfoSelector().getOffset() & kInfoFlagClass); }
const Object *getClass(SegManager *segMan) const; const Object *getClass(SegManager *segMan) const;
void markAsFreed() { _flags |= OBJECT_FLAG_FREED; } void markAsFreed() { _flags |= OBJECT_FLAG_FREED; }

View file

@ -115,8 +115,9 @@ void syncArray(Common::Serializer &s, Common::Array<T> &arr) {
template<> template<>
void syncWithSerializer(Common::Serializer &s, reg_t &obj) { void syncWithSerializer(Common::Serializer &s, reg_t &obj) {
s.syncAsUint16LE(obj.segment); // Segment and offset are accessed directly here
s.syncAsUint16LE(obj.offset); s.syncAsUint16LE(obj._segment);
s.syncAsUint16LE(obj._offset);
} }
template<> template<>
@ -202,7 +203,7 @@ void SegManager::saveLoadWithSerializer(Common::Serializer &s) {
ObjMap objects = scr->getObjectMap(); ObjMap objects = scr->getObjectMap();
for (ObjMap::iterator it = objects.begin(); it != objects.end(); ++it) for (ObjMap::iterator it = objects.begin(); it != objects.end(); ++it)
it->_value.syncBaseObject(scr->getBuf(it->_value.getPos().offset)); it->_value.syncBaseObject(scr->getBuf(it->_value.getPos().getOffset()));
} }
@ -507,7 +508,7 @@ void Script::saveLoadWithSerializer(Common::Serializer &s) {
Object tmp; Object tmp;
for (uint i = 0; i < numObjs; ++i) { for (uint i = 0; i < numObjs; ++i) {
syncWithSerializer(s, tmp); syncWithSerializer(s, tmp);
_objects[tmp.getPos().offset] = tmp; _objects[tmp.getPos().getOffset()] = tmp;
} }
} else { } else {
ObjMap::iterator it; ObjMap::iterator it;
@ -816,7 +817,7 @@ bool gamestate_save(EngineState *s, Common::WriteStream *fh, const Common::Strin
Resource *script0 = g_sci->getResMan()->findResource(ResourceId(kResourceTypeScript, 0), false); Resource *script0 = g_sci->getResMan()->findResource(ResourceId(kResourceTypeScript, 0), false);
meta.script0Size = script0->size; meta.script0Size = script0->size;
meta.gameObjectOffset = g_sci->getGameObject().offset; meta.gameObjectOffset = g_sci->getGameObject().getOffset();
// Checking here again // Checking here again
if (s->executionStackBase) { if (s->executionStackBase) {
@ -867,7 +868,7 @@ void gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) {
if (meta.gameObjectOffset > 0 && meta.script0Size > 0) { if (meta.gameObjectOffset > 0 && meta.script0Size > 0) {
Resource *script0 = g_sci->getResMan()->findResource(ResourceId(kResourceTypeScript, 0), false); Resource *script0 = g_sci->getResMan()->findResource(ResourceId(kResourceTypeScript, 0), false);
if (script0->size != meta.script0Size || g_sci->getGameObject().offset != meta.gameObjectOffset) { if (script0->size != meta.script0Size || g_sci->getGameObject().getOffset() != meta.gameObjectOffset) {
//warning("This saved game was created with a different version of the game, unable to load it"); //warning("This saved game was created with a different version of the game, unable to load it");
showScummVMDialog("This saved game was created with a different version of the game, unable to load it"); showScummVMDialog("This saved game was created with a different version of the game, unable to load it");

View file

@ -239,14 +239,14 @@ const Object *Script::getObject(uint16 offset) const {
Object *Script::scriptObjInit(reg_t obj_pos, bool fullObjectInit) { Object *Script::scriptObjInit(reg_t obj_pos, bool fullObjectInit) {
if (getSciVersion() < SCI_VERSION_1_1 && fullObjectInit) if (getSciVersion() < SCI_VERSION_1_1 && fullObjectInit)
obj_pos.offset += 8; // magic offset (SCRIPT_OBJECT_MAGIC_OFFSET) obj_pos.incOffset(8); // magic offset (SCRIPT_OBJECT_MAGIC_OFFSET)
if (obj_pos.offset >= _bufSize) if (obj_pos.getOffset() >= _bufSize)
error("Attempt to initialize object beyond end of script"); error("Attempt to initialize object beyond end of script");
// Get the object at the specified position and init it. This will // Get the object at the specified position and init it. This will
// automatically "allocate" space for it in the _objects map if necessary. // automatically "allocate" space for it in the _objects map if necessary.
Object *obj = &_objects[obj_pos.offset]; Object *obj = &_objects[obj_pos.getOffset()];
obj->init(_buf, obj_pos, fullObjectInit); obj->init(_buf, obj_pos, fullObjectInit);
return obj; return obj;
@ -269,9 +269,9 @@ static bool relocateBlock(Common::Array<reg_t> &block, int block_location, Segme
error("Attempt to relocate odd variable #%d.5e (relative to %04x)\n", idx, block_location); error("Attempt to relocate odd variable #%d.5e (relative to %04x)\n", idx, block_location);
return false; return false;
} }
block[idx].segment = segment; // Perform relocation block[idx].setSegment(segment); // Perform relocation
if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1) if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1)
block[idx].offset += scriptSize; block[idx].incOffset(scriptSize);
return true; return true;
} }
@ -310,23 +310,23 @@ void Script::relocateSci0Sci21(reg_t block) {
heapOffset = _scriptSize; heapOffset = _scriptSize;
} }
if (block.offset >= (uint16)heapSize || if (block.getOffset() >= (uint16)heapSize ||
READ_SCI11ENDIAN_UINT16(heap + block.offset) * 2 + block.offset >= (uint16)heapSize) READ_SCI11ENDIAN_UINT16(heap + block.getOffset()) * 2 + block.getOffset() >= (uint16)heapSize)
error("Relocation block outside of script"); error("Relocation block outside of script");
int count = READ_SCI11ENDIAN_UINT16(heap + block.offset); int count = READ_SCI11ENDIAN_UINT16(heap + block.getOffset());
int exportIndex = 0; int exportIndex = 0;
int pos = 0; int pos = 0;
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
pos = READ_SCI11ENDIAN_UINT16(heap + block.offset + 2 + (exportIndex * 2)) + heapOffset; pos = READ_SCI11ENDIAN_UINT16(heap + block.getOffset() + 2 + (exportIndex * 2)) + heapOffset;
// This occurs in SCI01/SCI1 games where usually one export value is // This occurs in SCI01/SCI1 games where usually one export value is
// zero. It seems that in this situation, we should skip the export and // zero. It seems that in this situation, we should skip the export and
// move to the next one, though the total count of valid exports remains // move to the next one, though the total count of valid exports remains
// the same // the same
if (!pos) { if (!pos) {
exportIndex++; exportIndex++;
pos = READ_SCI11ENDIAN_UINT16(heap + block.offset + 2 + (exportIndex * 2)) + heapOffset; pos = READ_SCI11ENDIAN_UINT16(heap + block.getOffset() + 2 + (exportIndex * 2)) + heapOffset;
if (!pos) if (!pos)
error("Script::relocate(): Consecutive zero exports found"); error("Script::relocate(): Consecutive zero exports found");
} }
@ -335,12 +335,12 @@ void Script::relocateSci0Sci21(reg_t block) {
// We only relocate locals and objects here, and ignore relocation of // We only relocate locals and objects here, and ignore relocation of
// code blocks. In SCI1.1 and newer versions, only locals and objects // code blocks. In SCI1.1 and newer versions, only locals and objects
// are relocated. // are relocated.
if (!relocateLocal(block.segment, pos)) { if (!relocateLocal(block.getSegment(), pos)) {
// Not a local? It's probably an object or code block. If it's an // Not a local? It's probably an object or code block. If it's an
// object, relocate it. // object, relocate it.
const ObjMap::iterator end = _objects.end(); const ObjMap::iterator end = _objects.end();
for (ObjMap::iterator it = _objects.begin(); it != end; ++it) for (ObjMap::iterator it = _objects.begin(); it != end; ++it)
if (it->_value.relocateSci0Sci21(block.segment, pos, _scriptSize)) if (it->_value.relocateSci0Sci21(block.getSegment(), pos, _scriptSize))
break; break;
} }
@ -357,7 +357,7 @@ void Script::relocateSci3(reg_t block) {
const byte *seeker = relocStart; const byte *seeker = relocStart;
while (seeker < _buf + _bufSize) { while (seeker < _buf + _bufSize) {
// TODO: Find out what UINT16 at (seeker + 8) means // TODO: Find out what UINT16 at (seeker + 8) means
it->_value.relocateSci3(block.segment, it->_value.relocateSci3(block.getSegment(),
READ_SCI11ENDIAN_UINT32(seeker), READ_SCI11ENDIAN_UINT32(seeker),
READ_SCI11ENDIAN_UINT32(seeker + 4), READ_SCI11ENDIAN_UINT32(seeker + 4),
_scriptSize); _scriptSize);
@ -466,7 +466,7 @@ bool Script::isValidOffset(uint16 offset) const {
} }
SegmentRef Script::dereference(reg_t pointer) { SegmentRef Script::dereference(reg_t pointer) {
if (pointer.offset > _bufSize) { if (pointer.getOffset() > _bufSize) {
error("Script::dereference(): Attempt to dereference invalid pointer %04x:%04x into script segment (script size=%d)", error("Script::dereference(): Attempt to dereference invalid pointer %04x:%04x into script segment (script size=%d)",
PRINT_REG(pointer), (uint)_bufSize); PRINT_REG(pointer), (uint)_bufSize);
return SegmentRef(); return SegmentRef();
@ -474,8 +474,8 @@ SegmentRef Script::dereference(reg_t pointer) {
SegmentRef ret; SegmentRef ret;
ret.isRaw = true; ret.isRaw = true;
ret.maxSize = _bufSize - pointer.offset; ret.maxSize = _bufSize - pointer.getOffset();
ret.raw = _buf + pointer.offset; ret.raw = _buf + pointer.getOffset();
return ret; return ret;
} }
@ -653,7 +653,7 @@ void Script::initializeObjectsSci11(SegManager *segMan, SegmentId segmentId) {
// Copy base from species class, as we need its selector IDs // Copy base from species class, as we need its selector IDs
obj->setSuperClassSelector( obj->setSuperClassSelector(
segMan->getClassAddress(obj->getSuperClassSelector().offset, SCRIPT_GET_LOCK, 0)); segMan->getClassAddress(obj->getSuperClassSelector().getOffset(), SCRIPT_GET_LOCK, 0));
// If object is instance, get -propDict- from class and set it for this // If object is instance, get -propDict- from class and set it for this
// object. This is needed for ::isMemberOf() to work. // object. This is needed for ::isMemberOf() to work.
@ -686,7 +686,7 @@ void Script::initializeObjectsSci3(SegManager *segMan, SegmentId segmentId) {
reg_t reg = make_reg(segmentId, seeker - _buf); reg_t reg = make_reg(segmentId, seeker - _buf);
Object *obj = scriptObjInit(reg); Object *obj = scriptObjInit(reg);
obj->setSuperClassSelector(segMan->getClassAddress(obj->getSuperClassSelector().offset, SCRIPT_GET_LOCK, 0)); obj->setSuperClassSelector(segMan->getClassAddress(obj->getSuperClassSelector().getOffset(), SCRIPT_GET_LOCK, 0));
seeker += READ_SCI11ENDIAN_UINT16(seeker + 2); seeker += READ_SCI11ENDIAN_UINT16(seeker + 2);
} }
@ -703,7 +703,7 @@ void Script::initializeObjects(SegManager *segMan, SegmentId segmentId) {
} }
reg_t Script::findCanonicAddress(SegManager *segMan, reg_t addr) const { reg_t Script::findCanonicAddress(SegManager *segMan, reg_t addr) const {
addr.offset = 0; addr.setOffset(0);
return addr; return addr;
} }
@ -725,8 +725,8 @@ Common::Array<reg_t> Script::listAllDeallocatable(SegmentId segId) const {
Common::Array<reg_t> Script::listAllOutgoingReferences(reg_t addr) const { Common::Array<reg_t> Script::listAllOutgoingReferences(reg_t addr) const {
Common::Array<reg_t> tmp; Common::Array<reg_t> tmp;
if (addr.offset <= _bufSize && addr.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET && offsetIsObject(addr.offset)) { if (addr.getOffset() <= _bufSize && addr.getOffset() >= (uint)-SCRIPT_OBJECT_MAGIC_OFFSET && offsetIsObject(addr.getOffset())) {
const Object *obj = getObject(addr.offset); const Object *obj = getObject(addr.getOffset());
if (obj) { if (obj) {
// Note all local variables, if we have a local variable environment // Note all local variables, if we have a local variable environment
if (_localsSegment) if (_localsSegment)

View file

@ -69,17 +69,17 @@ const char *opcodeNames[] = {
// Disassembles one command from the heap, returns address of next command or 0 if a ret was encountered. // Disassembles one command from the heap, returns address of next command or 0 if a ret was encountered.
reg_t disassemble(EngineState *s, reg_t pos, bool printBWTag, bool printBytecode) { reg_t disassemble(EngineState *s, reg_t pos, bool printBWTag, bool printBytecode) {
SegmentObj *mobj = s->_segMan->getSegment(pos.segment, SEG_TYPE_SCRIPT); SegmentObj *mobj = s->_segMan->getSegment(pos.getSegment(), SEG_TYPE_SCRIPT);
Script *script_entity = NULL; Script *script_entity = NULL;
const byte *scr; const byte *scr;
int scr_size; uint scr_size;
reg_t retval = make_reg(pos.segment, pos.offset + 1); reg_t retval = make_reg(pos.getSegment(), pos.getOffset() + 1);
uint16 param_value = 0xffff; // Suppress GCC warning by setting default value, chose value as invalid to getKernelName etc. uint16 param_value = 0xffff; // Suppress GCC warning by setting default value, chose value as invalid to getKernelName etc.
int i = 0; uint i = 0;
Kernel *kernel = g_sci->getKernel(); Kernel *kernel = g_sci->getKernel();
if (!mobj) { if (!mobj) {
warning("Disassembly failed: Segment %04x non-existant or not a script", pos.segment); warning("Disassembly failed: Segment %04x non-existant or not a script", pos.getSegment());
return retval; return retval;
} else } else
script_entity = (Script *)mobj; script_entity = (Script *)mobj;
@ -87,14 +87,14 @@ reg_t disassemble(EngineState *s, reg_t pos, bool printBWTag, bool printBytecode
scr = script_entity->getBuf(); scr = script_entity->getBuf();
scr_size = script_entity->getBufSize(); scr_size = script_entity->getBufSize();
if (pos.offset >= scr_size) { if (pos.getOffset() >= scr_size) {
warning("Trying to disassemble beyond end of script"); warning("Trying to disassemble beyond end of script");
return NULL_REG; return NULL_REG;
} }
int16 opparams[4]; int16 opparams[4];
byte opsize; byte opsize;
int bytecount = readPMachineInstruction(scr + pos.offset, opsize, opparams); uint bytecount = readPMachineInstruction(scr + pos.getOffset(), opsize, opparams);
const byte opcode = opsize >> 1; const byte opcode = opsize >> 1;
opsize &= 1; // byte if true, word if false opsize &= 1; // byte if true, word if false
@ -102,13 +102,13 @@ reg_t disassemble(EngineState *s, reg_t pos, bool printBWTag, bool printBytecode
debugN("%04x:%04x: ", PRINT_REG(pos)); debugN("%04x:%04x: ", PRINT_REG(pos));
if (printBytecode) { if (printBytecode) {
if (pos.offset + bytecount > scr_size) { if (pos.getOffset() + bytecount > scr_size) {
warning("Operation arguments extend beyond end of script"); warning("Operation arguments extend beyond end of script");
return retval; return retval;
} }
for (i = 0; i < bytecount; i++) for (i = 0; i < bytecount; i++)
debugN("%02x ", scr[pos.offset + i]); debugN("%02x ", scr[pos.getOffset() + i]);
for (i = bytecount; i < 5; i++) for (i = bytecount; i < 5; i++)
debugN(" "); debugN(" ");
@ -130,16 +130,16 @@ reg_t disassemble(EngineState *s, reg_t pos, bool printBWTag, bool printBytecode
case Script_SByte: case Script_SByte:
case Script_Byte: case Script_Byte:
param_value = scr[retval.offset]; param_value = scr[retval.getOffset()];
debugN(" %02x", scr[retval.offset]); debugN(" %02x", scr[retval.getOffset()]);
retval.offset++; retval.incOffset(1);
break; break;
case Script_Word: case Script_Word:
case Script_SWord: case Script_SWord:
param_value = READ_SCI11ENDIAN_UINT16(&scr[retval.offset]); param_value = READ_SCI11ENDIAN_UINT16(&scr[retval.getOffset()]);
debugN(" %04x", READ_SCI11ENDIAN_UINT16(&scr[retval.offset])); debugN(" %04x", READ_SCI11ENDIAN_UINT16(&scr[retval.getOffset()]));
retval.offset += 2; retval.incOffset(2);
break; break;
case Script_SVariable: case Script_SVariable:
@ -149,11 +149,12 @@ reg_t disassemble(EngineState *s, reg_t pos, bool printBWTag, bool printBytecode
case Script_Local: case Script_Local:
case Script_Temp: case Script_Temp:
case Script_Param: case Script_Param:
if (opsize) if (opsize) {
param_value = scr[retval.offset++]; param_value = scr[retval.getOffset()];
else { retval.incOffset(1);
param_value = READ_SCI11ENDIAN_UINT16(&scr[retval.offset]); } else {
retval.offset += 2; param_value = READ_SCI11ENDIAN_UINT16(&scr[retval.getOffset()]);
retval.incOffset(2);
} }
if (opcode == op_callk) if (opcode == op_callk)
@ -166,24 +167,26 @@ reg_t disassemble(EngineState *s, reg_t pos, bool printBWTag, bool printBytecode
break; break;
case Script_Offset: case Script_Offset:
if (opsize) if (opsize) {
param_value = scr[retval.offset++]; param_value = scr[retval.getOffset()];
else { retval.incOffset(1);
param_value = READ_SCI11ENDIAN_UINT16(&scr[retval.offset]); } else {
retval.offset += 2; param_value = READ_SCI11ENDIAN_UINT16(&scr[retval.getOffset()]);
retval.incOffset(2);
} }
debugN(opsize ? " %02x" : " %04x", param_value); debugN(opsize ? " %02x" : " %04x", param_value);
break; break;
case Script_SRelative: case Script_SRelative:
if (opsize) { if (opsize) {
int8 offset = (int8)scr[retval.offset++]; int8 offset = (int8)scr[retval.getOffset()];
debugN(" %02x [%04x]", 0xff & offset, 0xffff & (retval.offset + offset)); retval.incOffset(1);
debugN(" %02x [%04x]", 0xff & offset, 0xffff & (retval.getOffset() + offset));
} }
else { else {
int16 offset = (int16)READ_SCI11ENDIAN_UINT16(&scr[retval.offset]); int16 offset = (int16)READ_SCI11ENDIAN_UINT16(&scr[retval.getOffset()]);
retval.offset += 2; retval.incOffset(2);
debugN(" %04x [%04x]", 0xffff & offset, 0xffff & (retval.offset + offset)); debugN(" %04x [%04x]", 0xffff & offset, 0xffff & (retval.getOffset() + offset));
} }
break; break;
@ -216,8 +219,8 @@ reg_t disassemble(EngineState *s, reg_t pos, bool printBWTag, bool printBytecode
if (pos == s->xs->addr.pc) { // Extra information if debugging the current opcode if (pos == s->xs->addr.pc) { // Extra information if debugging the current opcode
if (opcode == op_callk) { if (opcode == op_callk) {
int stackframe = (scr[pos.offset + 2] >> 1) + (s->r_rest); int stackframe = (scr[pos.getOffset() + 2] >> 1) + (s->r_rest);
int argc = ((s->xs->sp)[- stackframe - 1]).offset; int argc = ((s->xs->sp)[- stackframe - 1]).getOffset();
bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY); bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY);
if (!oldScriptHeader) if (!oldScriptHeader)
@ -233,13 +236,13 @@ reg_t disassemble(EngineState *s, reg_t pos, bool printBWTag, bool printBytecode
debugN(")\n"); debugN(")\n");
} else if ((opcode == op_send) || (opcode == op_self)) { } else if ((opcode == op_send) || (opcode == op_self)) {
int restmod = s->r_rest; int restmod = s->r_rest;
int stackframe = (scr[pos.offset + 1] >> 1) + restmod; int stackframe = (scr[pos.getOffset() + 1] >> 1) + restmod;
reg_t *sb = s->xs->sp; reg_t *sb = s->xs->sp;
uint16 selector; uint16 selector;
reg_t fun_ref; reg_t fun_ref;
while (stackframe > 0) { while (stackframe > 0) {
int argc = sb[- stackframe + 1].offset; int argc = sb[- stackframe + 1].getOffset();
const char *name = NULL; const char *name = NULL;
reg_t called_obj_addr = s->xs->objp; reg_t called_obj_addr = s->xs->objp;
@ -248,7 +251,7 @@ reg_t disassemble(EngineState *s, reg_t pos, bool printBWTag, bool printBytecode
else if (opcode == op_self) else if (opcode == op_self)
called_obj_addr = s->xs->objp; called_obj_addr = s->xs->objp;
selector = sb[- stackframe].offset; selector = sb[- stackframe].getOffset();
name = s->_segMan->getObjectName(called_obj_addr); name = s->_segMan->getObjectName(called_obj_addr);
@ -290,20 +293,20 @@ reg_t disassemble(EngineState *s, reg_t pos, bool printBWTag, bool printBytecode
} }
bool isJumpOpcode(EngineState *s, reg_t pos, reg_t& jumpTarget) { bool isJumpOpcode(EngineState *s, reg_t pos, reg_t& jumpTarget) {
SegmentObj *mobj = s->_segMan->getSegment(pos.segment, SEG_TYPE_SCRIPT); SegmentObj *mobj = s->_segMan->getSegment(pos.getSegment(), SEG_TYPE_SCRIPT);
if (!mobj) if (!mobj)
return false; return false;
Script *script_entity = (Script *)mobj; Script *script_entity = (Script *)mobj;
const byte *scr = script_entity->getBuf(); const byte *scr = script_entity->getBuf();
int scr_size = script_entity->getScriptSize(); uint scr_size = script_entity->getScriptSize();
if (pos.offset >= scr_size) if (pos.getOffset() >= scr_size)
return false; return false;
int16 opparams[4]; int16 opparams[4];
byte opsize; byte opsize;
int bytecount = readPMachineInstruction(scr + pos.offset, opsize, opparams); int bytecount = readPMachineInstruction(scr + pos.getOffset(), opsize, opparams);
const byte opcode = opsize >> 1; const byte opcode = opsize >> 1;
switch (opcode) { switch (opcode) {
@ -313,7 +316,7 @@ bool isJumpOpcode(EngineState *s, reg_t pos, reg_t& jumpTarget) {
{ {
reg_t jmpTarget = pos + bytecount + opparams[0]; reg_t jmpTarget = pos + bytecount + opparams[0];
// QFG2 has invalid jumps outside the script buffer in script 260 // QFG2 has invalid jumps outside the script buffer in script 260
if (jmpTarget.offset >= scr_size) if (jmpTarget.getOffset() >= scr_size)
return false; return false;
jumpTarget = jmpTarget; jumpTarget = jmpTarget;
} }
@ -336,16 +339,16 @@ void SciEngine::scriptDebug() {
if (_debugState.seeking != kDebugSeekNothing) { if (_debugState.seeking != kDebugSeekNothing) {
const reg_t pc = s->xs->addr.pc; const reg_t pc = s->xs->addr.pc;
SegmentObj *mobj = s->_segMan->getSegment(pc.segment, SEG_TYPE_SCRIPT); SegmentObj *mobj = s->_segMan->getSegment(pc.getSegment(), SEG_TYPE_SCRIPT);
if (mobj) { if (mobj) {
Script *scr = (Script *)mobj; Script *scr = (Script *)mobj;
const byte *code_buf = scr->getBuf(); const byte *code_buf = scr->getBuf();
int code_buf_size = scr->getBufSize(); uint16 code_buf_size = scr->getBufSize();
int opcode = pc.offset >= code_buf_size ? 0 : code_buf[pc.offset]; int opcode = pc.getOffset() >= code_buf_size ? 0 : code_buf[pc.getOffset()];
int op = opcode >> 1; int op = opcode >> 1;
int paramb1 = pc.offset + 1 >= code_buf_size ? 0 : code_buf[pc.offset + 1]; int paramb1 = pc.getOffset() + 1 >= code_buf_size ? 0 : code_buf[pc.getOffset() + 1];
int paramf1 = (opcode & 1) ? paramb1 : (pc.offset + 2 >= code_buf_size ? 0 : (int16)READ_SCI11ENDIAN_UINT16(code_buf + pc.offset + 1)); int paramf1 = (opcode & 1) ? paramb1 : (pc.getOffset() + 2 >= code_buf_size ? 0 : (int16)READ_SCI11ENDIAN_UINT16(code_buf + pc.getOffset() + 1));
switch (_debugState.seeking) { switch (_debugState.seeking) {
case kDebugSeekSpecialCallk: case kDebugSeekSpecialCallk:
@ -714,7 +717,7 @@ void logKernelCall(const KernelFunction *kernelCall, const KernelSubFunction *ke
else if (regType & SIG_IS_INVALID) else if (regType & SIG_IS_INVALID)
debugN("INVALID"); debugN("INVALID");
else if (regType & SIG_TYPE_INTEGER) else if (regType & SIG_TYPE_INTEGER)
debugN("%d", argv[parmNr].offset); debugN("%d", argv[parmNr].getOffset());
else { else {
debugN("%04x:%04x", PRINT_REG(argv[parmNr])); debugN("%04x:%04x", PRINT_REG(argv[parmNr]));
switch (regType) { switch (regType) {
@ -723,12 +726,12 @@ void logKernelCall(const KernelFunction *kernelCall, const KernelSubFunction *ke
break; break;
case SIG_TYPE_REFERENCE: case SIG_TYPE_REFERENCE:
{ {
SegmentObj *mobj = s->_segMan->getSegmentObj(argv[parmNr].segment); SegmentObj *mobj = s->_segMan->getSegmentObj(argv[parmNr].getSegment());
switch (mobj->getType()) { switch (mobj->getType()) {
case SEG_TYPE_HUNK: case SEG_TYPE_HUNK:
{ {
HunkTable *ht = (HunkTable *)mobj; HunkTable *ht = (HunkTable *)mobj;
int index = argv[parmNr].offset; int index = argv[parmNr].getOffset();
if (ht->isValidEntry(index)) { if (ht->isValidEntry(index)) {
// NOTE: This ", deleted" isn't as useful as it could // NOTE: This ", deleted" isn't as useful as it could
// be because it prints the status _after_ the kernel // be because it prints the status _after_ the kernel
@ -765,7 +768,7 @@ void logKernelCall(const KernelFunction *kernelCall, const KernelSubFunction *ke
if (result.isPointer()) if (result.isPointer())
debugN(" = %04x:%04x\n", PRINT_REG(result)); debugN(" = %04x:%04x\n", PRINT_REG(result));
else else
debugN(" = %d\n", result.offset); debugN(" = %d\n", result.getOffset());
} }
} // End of namespace Sci } // End of namespace Sci

View file

@ -81,7 +81,7 @@ void SegManager::initSysStrings() {
if (getSciVersion() <= SCI_VERSION_1_1) { if (getSciVersion() <= SCI_VERSION_1_1) {
// We need to allocate system strings in one segment, for compatibility reasons // We need to allocate system strings in one segment, for compatibility reasons
allocDynmem(512, "system strings", &_saveDirPtr); allocDynmem(512, "system strings", &_saveDirPtr);
_parserPtr = make_reg(_saveDirPtr.segment, _saveDirPtr.offset + 256); _parserPtr = make_reg(_saveDirPtr.getSegment(), _saveDirPtr.getOffset() + 256);
#ifdef ENABLE_SCI32 #ifdef ENABLE_SCI32
} else { } else {
SciString *saveDirString = allocateString(&_saveDirPtr); SciString *saveDirString = allocateString(&_saveDirPtr);
@ -163,7 +163,7 @@ bool SegManager::isHeapObject(reg_t pos) const {
const Object *obj = getObject(pos); const Object *obj = getObject(pos);
if (obj == NULL || (obj && obj->isFreed())) if (obj == NULL || (obj && obj->isFreed()))
return false; return false;
Script *scr = getScriptIfLoaded(pos.segment); Script *scr = getScriptIfLoaded(pos.getSegment());
return !(scr && scr->isMarkedAsDeleted()); return !(scr && scr->isMarkedAsDeleted());
} }
@ -214,21 +214,21 @@ SegmentObj *SegManager::getSegment(SegmentId seg, SegmentType type) const {
} }
Object *SegManager::getObject(reg_t pos) const { Object *SegManager::getObject(reg_t pos) const {
SegmentObj *mobj = getSegmentObj(pos.segment); SegmentObj *mobj = getSegmentObj(pos.getSegment());
Object *obj = NULL; Object *obj = NULL;
if (mobj != NULL) { if (mobj != NULL) {
if (mobj->getType() == SEG_TYPE_CLONES) { if (mobj->getType() == SEG_TYPE_CLONES) {
CloneTable *ct = (CloneTable *)mobj; CloneTable *ct = (CloneTable *)mobj;
if (ct->isValidEntry(pos.offset)) if (ct->isValidEntry(pos.getOffset()))
obj = &(ct->_table[pos.offset]); obj = &(ct->_table[pos.getOffset()]);
else else
warning("getObject(): Trying to get an invalid object"); warning("getObject(): Trying to get an invalid object");
} else if (mobj->getType() == SEG_TYPE_SCRIPT) { } else if (mobj->getType() == SEG_TYPE_SCRIPT) {
Script *scr = (Script *)mobj; Script *scr = (Script *)mobj;
if (pos.offset <= scr->getBufSize() && pos.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET if (pos.getOffset() <= scr->getBufSize() && pos.getOffset() >= (uint)-SCRIPT_OBJECT_MAGIC_OFFSET
&& scr->offsetIsObject(pos.offset)) { && scr->offsetIsObject(pos.getOffset())) {
obj = scr->getObject(pos.offset); obj = scr->getObject(pos.getOffset());
} }
} }
} }
@ -246,7 +246,7 @@ const char *SegManager::getObjectName(reg_t pos) {
return "<no name>"; return "<no name>";
const char *name = 0; const char *name = 0;
if (nameReg.segment) if (nameReg.getSegment())
name = derefString(nameReg); name = derefString(nameReg);
if (!name) if (!name)
return "<invalid name>"; return "<invalid name>";
@ -272,7 +272,7 @@ reg_t SegManager::findObjectByName(const Common::String &name, int index) {
const Script *scr = (const Script *)mobj; const Script *scr = (const Script *)mobj;
const ObjMap &objects = scr->getObjectMap(); const ObjMap &objects = scr->getObjectMap();
for (ObjMap::const_iterator it = objects.begin(); it != objects.end(); ++it) { for (ObjMap::const_iterator it = objects.begin(); it != objects.end(); ++it) {
objpos.offset = it->_value.getPos().offset; objpos.setOffset(it->_value.getPos().getOffset());
if (name == getObjectName(objpos)) if (name == getObjectName(objpos))
result.push_back(objpos); result.push_back(objpos);
} }
@ -283,7 +283,7 @@ reg_t SegManager::findObjectByName(const Common::String &name, int index) {
if (!ct->isValidEntry(idx)) if (!ct->isValidEntry(idx))
continue; continue;
objpos.offset = idx; objpos.setOffset(idx);
if (name == getObjectName(objpos)) if (name == getObjectName(objpos))
result.push_back(objpos); result.push_back(objpos);
} }
@ -364,14 +364,14 @@ void SegManager::freeHunkEntry(reg_t addr) {
return; return;
} }
HunkTable *ht = (HunkTable *)getSegment(addr.segment, SEG_TYPE_HUNK); HunkTable *ht = (HunkTable *)getSegment(addr.getSegment(), SEG_TYPE_HUNK);
if (!ht) { if (!ht) {
warning("Attempt to free Hunk from address %04x:%04x: Invalid segment type", PRINT_REG(addr)); warning("Attempt to free Hunk from address %04x:%04x: Invalid segment type", PRINT_REG(addr));
return; return;
} }
ht->freeEntryContents(addr.offset); ht->freeEntryContents(addr.getOffset());
} }
reg_t SegManager::allocateHunkEntry(const char *hunk_type, int size) { reg_t SegManager::allocateHunkEntry(const char *hunk_type, int size) {
@ -398,14 +398,14 @@ reg_t SegManager::allocateHunkEntry(const char *hunk_type, int size) {
} }
byte *SegManager::getHunkPointer(reg_t addr) { byte *SegManager::getHunkPointer(reg_t addr) {
HunkTable *ht = (HunkTable *)getSegment(addr.segment, SEG_TYPE_HUNK); HunkTable *ht = (HunkTable *)getSegment(addr.getSegment(), SEG_TYPE_HUNK);
if (!ht || !ht->isValidEntry(addr.offset)) { if (!ht || !ht->isValidEntry(addr.getOffset())) {
// Valid SCI behavior, e.g. when loading/quitting // Valid SCI behavior, e.g. when loading/quitting
return NULL; return NULL;
} }
return (byte *)ht->_table[addr.offset].mem; return (byte *)ht->_table[addr.getOffset()].mem;
} }
Clone *SegManager::allocateClone(reg_t *addr) { Clone *SegManager::allocateClone(reg_t *addr) {
@ -462,35 +462,35 @@ reg_t SegManager::newNode(reg_t value, reg_t key) {
} }
List *SegManager::lookupList(reg_t addr) { List *SegManager::lookupList(reg_t addr) {
if (getSegmentType(addr.segment) != SEG_TYPE_LISTS) { if (getSegmentType(addr.getSegment()) != SEG_TYPE_LISTS) {
error("Attempt to use non-list %04x:%04x as list", PRINT_REG(addr)); error("Attempt to use non-list %04x:%04x as list", PRINT_REG(addr));
return NULL; return NULL;
} }
ListTable *lt = (ListTable *)_heap[addr.segment]; ListTable *lt = (ListTable *)_heap[addr.getSegment()];
if (!lt->isValidEntry(addr.offset)) { if (!lt->isValidEntry(addr.getOffset())) {
error("Attempt to use non-list %04x:%04x as list", PRINT_REG(addr)); error("Attempt to use non-list %04x:%04x as list", PRINT_REG(addr));
return NULL; return NULL;
} }
return &(lt->_table[addr.offset]); return &(lt->_table[addr.getOffset()]);
} }
Node *SegManager::lookupNode(reg_t addr, bool stopOnDiscarded) { Node *SegManager::lookupNode(reg_t addr, bool stopOnDiscarded) {
if (addr.isNull()) if (addr.isNull())
return NULL; // Non-error null return NULL; // Non-error null
SegmentType type = getSegmentType(addr.segment); SegmentType type = getSegmentType(addr.getSegment());
if (type != SEG_TYPE_NODES) { if (type != SEG_TYPE_NODES) {
error("Attempt to use non-node %04x:%04x (type %d) as list node", PRINT_REG(addr), type); error("Attempt to use non-node %04x:%04x (type %d) as list node", PRINT_REG(addr), type);
return NULL; return NULL;
} }
NodeTable *nt = (NodeTable *)_heap[addr.segment]; NodeTable *nt = (NodeTable *)_heap[addr.getSegment()];
if (!nt->isValidEntry(addr.offset)) { if (!nt->isValidEntry(addr.getOffset())) {
if (!stopOnDiscarded) if (!stopOnDiscarded)
return NULL; return NULL;
@ -498,19 +498,19 @@ Node *SegManager::lookupNode(reg_t addr, bool stopOnDiscarded) {
return NULL; return NULL;
} }
return &(nt->_table[addr.offset]); return &(nt->_table[addr.getOffset()]);
} }
SegmentRef SegManager::dereference(reg_t pointer) { SegmentRef SegManager::dereference(reg_t pointer) {
SegmentRef ret; SegmentRef ret;
if (!pointer.segment || (pointer.segment >= _heap.size()) || !_heap[pointer.segment]) { if (!pointer.getSegment() || (pointer.getSegment() >= _heap.size()) || !_heap[pointer.getSegment()]) {
// This occurs in KQ5CD when interacting with certain objects // This occurs in KQ5CD when interacting with certain objects
warning("SegManager::dereference(): Attempt to dereference invalid pointer %04x:%04x", PRINT_REG(pointer)); warning("SegManager::dereference(): Attempt to dereference invalid pointer %04x:%04x", PRINT_REG(pointer));
return ret; /* Invalid */ return ret; /* Invalid */
} }
SegmentObj *mobj = _heap[pointer.segment]; SegmentObj *mobj = _heap[pointer.getSegment()];
return mobj->dereference(pointer); return mobj->dereference(pointer);
} }
@ -522,7 +522,7 @@ static void *derefPtr(SegManager *segMan, reg_t pointer, int entries, bool wantR
if (ret.isRaw != wantRaw) { if (ret.isRaw != wantRaw) {
warning("Dereferencing pointer %04x:%04x (type %d) which is %s, but expected %s", PRINT_REG(pointer), warning("Dereferencing pointer %04x:%04x (type %d) which is %s, but expected %s", PRINT_REG(pointer),
segMan->getSegmentType(pointer.segment), segMan->getSegmentType(pointer.getSegment()),
ret.isRaw ? "raw" : "not raw", ret.isRaw ? "raw" : "not raw",
wantRaw ? "raw" : "not raw"); wantRaw ? "raw" : "not raw");
} }
@ -565,15 +565,15 @@ static inline char getChar(const SegmentRef &ref, uint offset) {
// segment 0xFFFF means that the scripts are using uninitialized temp-variable space // segment 0xFFFF means that the scripts are using uninitialized temp-variable space
// we can safely ignore this, if it isn't one of the first 2 chars. // we can safely ignore this, if it isn't one of the first 2 chars.
// foreign lsl3 uses kFileIO(readraw) and then immediately uses kReadNumber right at the start // foreign lsl3 uses kFileIO(readraw) and then immediately uses kReadNumber right at the start
if (val.segment != 0) if (val.getSegment() != 0)
if (!((val.segment == 0xFFFF) && (offset > 1))) if (!((val.getSegment() == 0xFFFF) && (offset > 1)))
warning("Attempt to read character from non-raw data"); warning("Attempt to read character from non-raw data");
bool oddOffset = offset & 1; bool oddOffset = offset & 1;
if (g_sci->isBE()) if (g_sci->isBE())
oddOffset = !oddOffset; oddOffset = !oddOffset;
return (oddOffset ? val.offset >> 8 : val.offset & 0xff); return (oddOffset ? val.getOffset() >> 8 : val.getOffset() & 0xff);
} }
static inline void setChar(const SegmentRef &ref, uint offset, byte value) { static inline void setChar(const SegmentRef &ref, uint offset, byte value) {
@ -582,16 +582,16 @@ static inline void setChar(const SegmentRef &ref, uint offset, byte value) {
reg_t *val = ref.reg + offset / 2; reg_t *val = ref.reg + offset / 2;
val->segment = 0; val->setSegment(0);
bool oddOffset = offset & 1; bool oddOffset = offset & 1;
if (g_sci->isBE()) if (g_sci->isBE())
oddOffset = !oddOffset; oddOffset = !oddOffset;
if (oddOffset) if (oddOffset)
val->offset = (val->offset & 0x00ff) | (value << 8); val->setOffset((val->getOffset() & 0x00ff) | (value << 8));
else else
val->offset = (val->offset & 0xff00) | value; val->setOffset((val->getOffset() & 0xff00) | value);
} }
// TODO: memcpy, strcpy and strncpy could maybe be folded into a single function // TODO: memcpy, strcpy and strncpy could maybe be folded into a single function
@ -829,10 +829,11 @@ byte *SegManager::allocDynmem(int size, const char *descr, reg_t *addr) {
} }
bool SegManager::freeDynmem(reg_t addr) { bool SegManager::freeDynmem(reg_t addr) {
if (addr.segment < 1 || addr.segment >= _heap.size() || !_heap[addr.segment] || _heap[addr.segment]->getType() != SEG_TYPE_DYNMEM) if (addr.getSegment() < 1 || addr.getSegment() >= _heap.size() ||
!_heap[addr.getSegment()] || _heap[addr.getSegment()]->getType() != SEG_TYPE_DYNMEM)
return false; // error return false; // error
deallocate(addr.segment); deallocate(addr.getSegment());
return true; // OK return true; // OK
} }
@ -854,28 +855,28 @@ SciArray<reg_t> *SegManager::allocateArray(reg_t *addr) {
} }
SciArray<reg_t> *SegManager::lookupArray(reg_t addr) { SciArray<reg_t> *SegManager::lookupArray(reg_t addr) {
if (_heap[addr.segment]->getType() != SEG_TYPE_ARRAY) if (_heap[addr.getSegment()]->getType() != SEG_TYPE_ARRAY)
error("Attempt to use non-array %04x:%04x as array", PRINT_REG(addr)); error("Attempt to use non-array %04x:%04x as array", PRINT_REG(addr));
ArrayTable *arrayTable = (ArrayTable *)_heap[addr.segment]; ArrayTable *arrayTable = (ArrayTable *)_heap[addr.getSegment()];
if (!arrayTable->isValidEntry(addr.offset)) if (!arrayTable->isValidEntry(addr.getOffset()))
error("Attempt to use non-array %04x:%04x as array", PRINT_REG(addr)); error("Attempt to use non-array %04x:%04x as array", PRINT_REG(addr));
return &(arrayTable->_table[addr.offset]); return &(arrayTable->_table[addr.getOffset()]);
} }
void SegManager::freeArray(reg_t addr) { void SegManager::freeArray(reg_t addr) {
if (_heap[addr.segment]->getType() != SEG_TYPE_ARRAY) if (_heap[addr.getSegment()]->getType() != SEG_TYPE_ARRAY)
error("Attempt to use non-array %04x:%04x as array", PRINT_REG(addr)); error("Attempt to use non-array %04x:%04x as array", PRINT_REG(addr));
ArrayTable *arrayTable = (ArrayTable *)_heap[addr.segment]; ArrayTable *arrayTable = (ArrayTable *)_heap[addr.getSegment()];
if (!arrayTable->isValidEntry(addr.offset)) if (!arrayTable->isValidEntry(addr.getOffset()))
error("Attempt to use non-array %04x:%04x as array", PRINT_REG(addr)); error("Attempt to use non-array %04x:%04x as array", PRINT_REG(addr));
arrayTable->_table[addr.offset].destroy(); arrayTable->_table[addr.getOffset()].destroy();
arrayTable->freeEntry(addr.offset); arrayTable->freeEntry(addr.getOffset());
} }
SciString *SegManager::allocateString(reg_t *addr) { SciString *SegManager::allocateString(reg_t *addr) {
@ -894,28 +895,28 @@ SciString *SegManager::allocateString(reg_t *addr) {
} }
SciString *SegManager::lookupString(reg_t addr) { SciString *SegManager::lookupString(reg_t addr) {
if (_heap[addr.segment]->getType() != SEG_TYPE_STRING) if (_heap[addr.getSegment()]->getType() != SEG_TYPE_STRING)
error("lookupString: Attempt to use non-string %04x:%04x as string", PRINT_REG(addr)); error("lookupString: Attempt to use non-string %04x:%04x as string", PRINT_REG(addr));
StringTable *stringTable = (StringTable *)_heap[addr.segment]; StringTable *stringTable = (StringTable *)_heap[addr.getSegment()];
if (!stringTable->isValidEntry(addr.offset)) if (!stringTable->isValidEntry(addr.getOffset()))
error("lookupString: Attempt to use non-string %04x:%04x as string", PRINT_REG(addr)); error("lookupString: Attempt to use non-string %04x:%04x as string", PRINT_REG(addr));
return &(stringTable->_table[addr.offset]); return &(stringTable->_table[addr.getOffset()]);
} }
void SegManager::freeString(reg_t addr) { void SegManager::freeString(reg_t addr) {
if (_heap[addr.segment]->getType() != SEG_TYPE_STRING) if (_heap[addr.getSegment()]->getType() != SEG_TYPE_STRING)
error("freeString: Attempt to use non-string %04x:%04x as string", PRINT_REG(addr)); error("freeString: Attempt to use non-string %04x:%04x as string", PRINT_REG(addr));
StringTable *stringTable = (StringTable *)_heap[addr.segment]; StringTable *stringTable = (StringTable *)_heap[addr.getSegment()];
if (!stringTable->isValidEntry(addr.offset)) if (!stringTable->isValidEntry(addr.getOffset()))
error("freeString: Attempt to use non-string %04x:%04x as string", PRINT_REG(addr)); error("freeString: Attempt to use non-string %04x:%04x as string", PRINT_REG(addr));
stringTable->_table[addr.offset].destroy(); stringTable->_table[addr.getOffset()].destroy();
stringTable->freeEntry(addr.offset); stringTable->freeEntry(addr.getOffset());
} }
#endif #endif
@ -948,16 +949,16 @@ reg_t SegManager::getClassAddress(int classnr, ScriptLoadType lock, uint16 calle
return NULL_REG; return NULL_REG;
} else { } else {
Class *the_class = &_classTable[classnr]; Class *the_class = &_classTable[classnr];
if (!the_class->reg.segment) { if (!the_class->reg.getSegment()) {
getScriptSegment(the_class->script, lock); getScriptSegment(the_class->script, lock);
if (!the_class->reg.segment) { if (!the_class->reg.getSegment()) {
error("[VM] Trying to instantiate class %x by instantiating script 0x%x (%03d) failed;", classnr, the_class->script, the_class->script); error("[VM] Trying to instantiate class %x by instantiating script 0x%x (%03d) failed;", classnr, the_class->script, the_class->script);
return NULL_REG; return NULL_REG;
} }
} else } else
if (callerSegment != the_class->reg.segment) if (callerSegment != the_class->reg.getSegment())
getScript(the_class->reg.segment)->incrementLockers(); getScript(the_class->reg.getSegment())->incrementLockers();
return the_class->reg; return the_class->reg;
} }
@ -1002,7 +1003,7 @@ void SegManager::uninstantiateScript(int script_nr) {
// Free all classtable references to this script // Free all classtable references to this script
for (uint i = 0; i < classTableSize(); i++) for (uint i = 0; i < classTableSize(); i++)
if (getClass(i).reg.segment == segmentId) if (getClass(i).reg.getSegment() == segmentId)
setClassOffset(i, NULL_REG); setClassOffset(i, NULL_REG);
if (getSciVersion() < SCI_VERSION_1_1) if (getSciVersion() < SCI_VERSION_1_1)
@ -1026,18 +1027,18 @@ void SegManager::uninstantiateScriptSci0(int script_nr) {
// Make a pass over the object in order to uninstantiate all superclasses // Make a pass over the object in order to uninstantiate all superclasses
do { do {
reg.offset += objLength; // Step over the last checked object reg.incOffset(objLength); // Step over the last checked object
objType = READ_SCI11ENDIAN_UINT16(scr->getBuf(reg.offset)); objType = READ_SCI11ENDIAN_UINT16(scr->getBuf(reg.getOffset()));
if (!objType) if (!objType)
break; break;
objLength = READ_SCI11ENDIAN_UINT16(scr->getBuf(reg.offset + 2)); objLength = READ_SCI11ENDIAN_UINT16(scr->getBuf(reg.getOffset() + 2));
reg.offset += 4; // Step over header reg.incOffset(4); // Step over header
if ((objType == SCI_OBJ_OBJECT) || (objType == SCI_OBJ_CLASS)) { // object or class? if ((objType == SCI_OBJ_OBJECT) || (objType == SCI_OBJ_CLASS)) { // object or class?
reg.offset += 8; // magic offset (SCRIPT_OBJECT_MAGIC_OFFSET) reg.incOffset(8); // magic offset (SCRIPT_OBJECT_MAGIC_OFFSET)
int16 superclass = READ_SCI11ENDIAN_UINT16(scr->getBuf(reg.offset + 2)); int16 superclass = READ_SCI11ENDIAN_UINT16(scr->getBuf(reg.getOffset() + 2));
if (superclass >= 0) { if (superclass >= 0) {
int superclass_script = getClass(superclass).script; int superclass_script = getClass(superclass).script;
@ -1051,10 +1052,10 @@ void SegManager::uninstantiateScriptSci0(int script_nr) {
// Recurse to assure that the superclass lockers number gets decreased // Recurse to assure that the superclass lockers number gets decreased
} }
reg.offset += SCRIPT_OBJECT_MAGIC_OFFSET; reg.incOffset(SCRIPT_OBJECT_MAGIC_OFFSET);
} // if object or class } // if object or class
reg.offset -= 4; // Step back on header reg.incOffset(-4); // Step back on header
} while (objType != 0); } while (objType != 0);
} }

View file

@ -93,11 +93,11 @@ Common::Array<reg_t> CloneTable::listAllOutgoingReferences(reg_t addr) const {
Common::Array<reg_t> tmp; Common::Array<reg_t> tmp;
// assert(addr.segment == _segId); // assert(addr.segment == _segId);
if (!isValidEntry(addr.offset)) { if (!isValidEntry(addr.getOffset())) {
error("Unexpected request for outgoing references from clone at %04x:%04x", PRINT_REG(addr)); error("Unexpected request for outgoing references from clone at %04x:%04x", PRINT_REG(addr));
} }
const Clone *clone = &(_table[addr.offset]); const Clone *clone = &(_table[addr.getOffset()]);
// Emit all member variables (including references to the 'super' delegate) // Emit all member variables (including references to the 'super' delegate)
for (uint i = 0; i < clone->getVarCount(); i++) for (uint i = 0; i < clone->getVarCount(); i++)
@ -112,7 +112,7 @@ Common::Array<reg_t> CloneTable::listAllOutgoingReferences(reg_t addr) const {
void CloneTable::freeAtAddress(SegManager *segMan, reg_t addr) { void CloneTable::freeAtAddress(SegManager *segMan, reg_t addr) {
#ifdef GC_DEBUG #ifdef GC_DEBUG
Object *victim_obj = &(_table[addr.offset]); Object *victim_obj = &(_table[addr.getOffset()]);
if (!(victim_obj->_flags & OBJECT_FLAG_FREED)) if (!(victim_obj->_flags & OBJECT_FLAG_FREED))
warning("[GC] Clone %04x:%04x not reachable and not freed (freeing now)", PRINT_REG(addr)); warning("[GC] Clone %04x:%04x not reachable and not freed (freeing now)", PRINT_REG(addr));
@ -124,7 +124,7 @@ void CloneTable::freeAtAddress(SegManager *segMan, reg_t addr) {
#endif #endif
#endif #endif
freeEntry(addr.offset); freeEntry(addr.getOffset());
} }
@ -133,15 +133,15 @@ void CloneTable::freeAtAddress(SegManager *segMan, reg_t addr) {
SegmentRef LocalVariables::dereference(reg_t pointer) { SegmentRef LocalVariables::dereference(reg_t pointer) {
SegmentRef ret; SegmentRef ret;
ret.isRaw = false; // reg_t based data! ret.isRaw = false; // reg_t based data!
ret.maxSize = (_locals.size() - pointer.offset / 2) * 2; ret.maxSize = (_locals.size() - pointer.getOffset() / 2) * 2;
if (pointer.offset & 1) { if (pointer.getOffset() & 1) {
ret.maxSize -= 1; ret.maxSize -= 1;
ret.skipByte = true; ret.skipByte = true;
} }
if (ret.maxSize > 0) { if (ret.maxSize > 0) {
ret.reg = &_locals[pointer.offset / 2]; ret.reg = &_locals[pointer.getOffset() / 2];
} else { } else {
if ((g_sci->getEngineState()->currentRoomNumber() == 160 || if ((g_sci->getEngineState()->currentRoomNumber() == 160 ||
g_sci->getEngineState()->currentRoomNumber() == 220) g_sci->getEngineState()->currentRoomNumber() == 220)
@ -181,14 +181,14 @@ Common::Array<reg_t> LocalVariables::listAllOutgoingReferences(reg_t addr) const
SegmentRef DataStack::dereference(reg_t pointer) { SegmentRef DataStack::dereference(reg_t pointer) {
SegmentRef ret; SegmentRef ret;
ret.isRaw = false; // reg_t based data! ret.isRaw = false; // reg_t based data!
ret.maxSize = (_capacity - pointer.offset / 2) * 2; ret.maxSize = (_capacity - pointer.getOffset() / 2) * 2;
if (pointer.offset & 1) { if (pointer.getOffset() & 1) {
ret.maxSize -= 1; ret.maxSize -= 1;
ret.skipByte = true; ret.skipByte = true;
} }
ret.reg = &_entries[pointer.offset / 2]; ret.reg = &_entries[pointer.getOffset() / 2];
return ret; return ret;
} }
@ -204,11 +204,11 @@ Common::Array<reg_t> DataStack::listAllOutgoingReferences(reg_t object) const {
Common::Array<reg_t> ListTable::listAllOutgoingReferences(reg_t addr) const { Common::Array<reg_t> ListTable::listAllOutgoingReferences(reg_t addr) const {
Common::Array<reg_t> tmp; Common::Array<reg_t> tmp;
if (!isValidEntry(addr.offset)) { if (!isValidEntry(addr.getOffset())) {
error("Invalid list referenced for outgoing references: %04x:%04x", PRINT_REG(addr)); error("Invalid list referenced for outgoing references: %04x:%04x", PRINT_REG(addr));
} }
const List *list = &(_table[addr.offset]); const List *list = &(_table[addr.getOffset()]);
tmp.push_back(list->first); tmp.push_back(list->first);
tmp.push_back(list->last); tmp.push_back(list->last);
@ -222,10 +222,10 @@ Common::Array<reg_t> ListTable::listAllOutgoingReferences(reg_t addr) const {
Common::Array<reg_t> NodeTable::listAllOutgoingReferences(reg_t addr) const { Common::Array<reg_t> NodeTable::listAllOutgoingReferences(reg_t addr) const {
Common::Array<reg_t> tmp; Common::Array<reg_t> tmp;
if (!isValidEntry(addr.offset)) { if (!isValidEntry(addr.getOffset())) {
error("Invalid node referenced for outgoing references: %04x:%04x", PRINT_REG(addr)); error("Invalid node referenced for outgoing references: %04x:%04x", PRINT_REG(addr));
} }
const Node *node = &(_table[addr.offset]); const Node *node = &(_table[addr.getOffset()]);
// We need all four here. Can't just stick with 'pred' OR 'succ' because node operations allow us // We need all four here. Can't just stick with 'pred' OR 'succ' because node operations allow us
// to walk around from any given node // to walk around from any given node
@ -242,8 +242,8 @@ Common::Array<reg_t> NodeTable::listAllOutgoingReferences(reg_t addr) const {
SegmentRef DynMem::dereference(reg_t pointer) { SegmentRef DynMem::dereference(reg_t pointer) {
SegmentRef ret; SegmentRef ret;
ret.isRaw = true; ret.isRaw = true;
ret.maxSize = _size - pointer.offset; ret.maxSize = _size - pointer.getOffset();
ret.raw = _buf + pointer.offset; ret.raw = _buf + pointer.getOffset();
return ret; return ret;
} }
@ -252,27 +252,27 @@ SegmentRef DynMem::dereference(reg_t pointer) {
SegmentRef ArrayTable::dereference(reg_t pointer) { SegmentRef ArrayTable::dereference(reg_t pointer) {
SegmentRef ret; SegmentRef ret;
ret.isRaw = false; ret.isRaw = false;
ret.maxSize = _table[pointer.offset].getSize() * 2; ret.maxSize = _table[pointer.getOffset()].getSize() * 2;
ret.reg = _table[pointer.offset].getRawData(); ret.reg = _table[pointer.getOffset()].getRawData();
return ret; return ret;
} }
void ArrayTable::freeAtAddress(SegManager *segMan, reg_t sub_addr) { void ArrayTable::freeAtAddress(SegManager *segMan, reg_t sub_addr) {
_table[sub_addr.offset].destroy(); _table[sub_addr.getOffset()].destroy();
freeEntry(sub_addr.offset); freeEntry(sub_addr.getOffset());
} }
Common::Array<reg_t> ArrayTable::listAllOutgoingReferences(reg_t addr) const { Common::Array<reg_t> ArrayTable::listAllOutgoingReferences(reg_t addr) const {
Common::Array<reg_t> tmp; Common::Array<reg_t> tmp;
if (!isValidEntry(addr.offset)) { if (!isValidEntry(addr.getOffset())) {
error("Invalid array referenced for outgoing references: %04x:%04x", PRINT_REG(addr)); error("Invalid array referenced for outgoing references: %04x:%04x", PRINT_REG(addr));
} }
const SciArray<reg_t> *array = &(_table[addr.offset]); const SciArray<reg_t> *array = &(_table[addr.getOffset()]);
for (uint32 i = 0; i < array->getSize(); i++) { for (uint32 i = 0; i < array->getSize(); i++) {
reg_t value = array->getValue(i); reg_t value = array->getValue(i);
if (value.segment != 0) if (value.getSegment() != 0)
tmp.push_back(value); tmp.push_back(value);
} }
@ -305,8 +305,8 @@ void SciString::fromString(const Common::String &string) {
SegmentRef StringTable::dereference(reg_t pointer) { SegmentRef StringTable::dereference(reg_t pointer) {
SegmentRef ret; SegmentRef ret;
ret.isRaw = true; ret.isRaw = true;
ret.maxSize = _table[pointer.offset].getSize(); ret.maxSize = _table[pointer.getOffset()].getSize();
ret.raw = (byte *)_table[pointer.offset].getRawData(); ret.raw = (byte *)_table[pointer.getOffset()].getRawData();
return ret; return ret;
} }

View file

@ -175,7 +175,7 @@ public:
} }
virtual SegmentRef dereference(reg_t pointer); virtual SegmentRef dereference(reg_t pointer);
virtual reg_t findCanonicAddress(SegManager *segMan, reg_t addr) const { virtual reg_t findCanonicAddress(SegManager *segMan, reg_t addr) const {
return make_reg(addr.segment, 0); return make_reg(addr.getSegment(), 0);
} }
virtual Common::Array<reg_t> listAllOutgoingReferences(reg_t object) const; virtual Common::Array<reg_t> listAllOutgoingReferences(reg_t object) const;
@ -291,7 +291,7 @@ struct NodeTable : public SegmentObjTable<Node> {
NodeTable() : SegmentObjTable<Node>(SEG_TYPE_NODES) {} NodeTable() : SegmentObjTable<Node>(SEG_TYPE_NODES) {}
virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr) { virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr) {
freeEntry(sub_addr.offset); freeEntry(sub_addr.getOffset());
} }
virtual Common::Array<reg_t> listAllOutgoingReferences(reg_t object) const; virtual Common::Array<reg_t> listAllOutgoingReferences(reg_t object) const;
@ -304,7 +304,7 @@ struct ListTable : public SegmentObjTable<List> {
ListTable() : SegmentObjTable<List>(SEG_TYPE_LISTS) {} ListTable() : SegmentObjTable<List>(SEG_TYPE_LISTS) {}
virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr) { virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr) {
freeEntry(sub_addr.offset); freeEntry(sub_addr.getOffset());
} }
virtual Common::Array<reg_t> listAllOutgoingReferences(reg_t object) const; virtual Common::Array<reg_t> listAllOutgoingReferences(reg_t object) const;
@ -333,7 +333,7 @@ struct HunkTable : public SegmentObjTable<Hunk> {
} }
virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr) { virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr) {
freeEntry(sub_addr.offset); freeEntry(sub_addr.getOffset());
} }
virtual void saveLoadWithSerializer(Common::Serializer &ser); virtual void saveLoadWithSerializer(Common::Serializer &ser);
@ -358,7 +358,7 @@ public:
} }
virtual SegmentRef dereference(reg_t pointer); virtual SegmentRef dereference(reg_t pointer);
virtual reg_t findCanonicAddress(SegManager *segMan, reg_t addr) const { virtual reg_t findCanonicAddress(SegManager *segMan, reg_t addr) const {
return make_reg(addr.segment, 0); return make_reg(addr.getSegment(), 0);
} }
virtual Common::Array<reg_t> listAllDeallocatable(SegmentId segId) const { virtual Common::Array<reg_t> listAllDeallocatable(SegmentId segId) const {
const reg_t r = make_reg(segId, 0); const reg_t r = make_reg(segId, 0);
@ -502,8 +502,8 @@ struct StringTable : public SegmentObjTable<SciString> {
StringTable() : SegmentObjTable<SciString>(SEG_TYPE_STRING) {} StringTable() : SegmentObjTable<SciString>(SEG_TYPE_STRING) {}
virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr) { virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr) {
_table[sub_addr.offset].destroy(); _table[sub_addr.getOffset()].destroy();
freeEntry(sub_addr.offset); freeEntry(sub_addr.getOffset());
} }
void saveLoadWithSerializer(Common::Serializer &ser); void saveLoadWithSerializer(Common::Serializer &ser);

View file

@ -171,7 +171,7 @@ struct SelectorCache {
* SelectorCache and mapped in script.cpp. * SelectorCache and mapped in script.cpp.
*/ */
reg_t readSelector(SegManager *segMan, reg_t object, Selector selectorId); reg_t readSelector(SegManager *segMan, reg_t object, Selector selectorId);
#define readSelectorValue(segMan, _obj_, _slc_) (readSelector(segMan, _obj_, _slc_).offset) #define readSelectorValue(segMan, _obj_, _slc_) (readSelector(segMan, _obj_, _slc_).getOffset())
/** /**
* Writes a selector value to an object. * Writes a selector value to an object.

View file

@ -119,7 +119,7 @@ extern const char *opcodeNames[]; // from scriptdebug.cpp
static reg_t read_var(EngineState *s, int type, int index) { static reg_t read_var(EngineState *s, int type, int index) {
if (validate_variable(s->variables[type], s->stack_base, type, s->variablesMax[type], index)) { if (validate_variable(s->variables[type], s->stack_base, type, s->variablesMax[type], index)) {
if (s->variables[type][index].segment == 0xffff) { if (s->variables[type][index].getSegment() == 0xffff) {
switch (type) { switch (type) {
case VAR_TEMP: { case VAR_TEMP: {
// Uninitialized read on a temp // Uninitialized read on a temp
@ -195,8 +195,8 @@ static void write_var(EngineState *s, int type, int index, reg_t value) {
// this happens at least in sq1/room 44 (slot-machine), because a send is missing parameters, then // this happens at least in sq1/room 44 (slot-machine), because a send is missing parameters, then
// those parameters are taken from uninitialized stack and afterwards they are copied back into temps // those parameters are taken from uninitialized stack and afterwards they are copied back into temps
// if we don't remove the segment, we would get false-positive uninitialized reads later // if we don't remove the segment, we would get false-positive uninitialized reads later
if (type == VAR_TEMP && value.segment == 0xffff) if (type == VAR_TEMP && value.getSegment() == 0xffff)
value.segment = 0; value.setSegment(0);
s->variables[type][index] = value; s->variables[type][index] = value;
@ -578,16 +578,16 @@ void run_vm(EngineState *s) {
int var_type; // See description below int var_type; // See description below
int var_number; int var_number;
g_sci->_debugState.old_pc_offset = s->xs->addr.pc.offset; g_sci->_debugState.old_pc_offset = s->xs->addr.pc.getOffset();
g_sci->_debugState.old_sp = s->xs->sp; g_sci->_debugState.old_sp = s->xs->sp;
if (s->abortScriptProcessing != kAbortNone) if (s->abortScriptProcessing != kAbortNone)
return; // Stop processing return; // Stop processing
if (s->_executionStackPosChanged) { if (s->_executionStackPosChanged) {
scr = s->_segMan->getScriptIfLoaded(s->xs->addr.pc.segment); scr = s->_segMan->getScriptIfLoaded(s->xs->addr.pc.getSegment());
if (!scr) if (!scr)
error("No script in segment %d", s->xs->addr.pc.segment); error("No script in segment %d", s->xs->addr.pc.getSegment());
s->xs = &(s->_executionStack.back()); s->xs = &(s->_executionStack.back());
s->_executionStackPosChanged = false; s->_executionStackPosChanged = false;
@ -624,13 +624,13 @@ void run_vm(EngineState *s) {
s->variablesMax[VAR_TEMP] = s->xs->sp - s->xs->fp; s->variablesMax[VAR_TEMP] = s->xs->sp - s->xs->fp;
if (s->xs->addr.pc.offset >= scr->getBufSize()) if (s->xs->addr.pc.getOffset() >= scr->getBufSize())
error("run_vm(): program counter gone astray, addr: %d, code buffer size: %d", error("run_vm(): program counter gone astray, addr: %d, code buffer size: %d",
s->xs->addr.pc.offset, scr->getBufSize()); s->xs->addr.pc.getOffset(), scr->getBufSize());
// Get opcode // Get opcode
byte extOpcode; byte extOpcode;
s->xs->addr.pc.offset += readPMachineInstruction(scr->getBuf() + s->xs->addr.pc.offset, extOpcode, opparams); s->xs->addr.pc.incOffset(readPMachineInstruction(scr->getBuf(s->xs->addr.pc.getOffset()), extOpcode, opparams));
const byte opcode = extOpcode >> 1; const byte opcode = extOpcode >> 1;
//debug("%s: %d, %d, %d, %d, acc = %04x:%04x, script %d, local script %d", opcodeNames[opcode], opparams[0], opparams[1], opparams[2], opparams[3], PRINT_REG(s->r_acc), scr->getScriptNumber(), local_script->getScriptNumber()); //debug("%s: %d, %d, %d, %d, acc = %04x:%04x, script %d, local script %d", opcodeNames[opcode], opparams[0], opparams[1], opparams[2], opparams[3], PRINT_REG(s->r_acc), scr->getScriptNumber(), local_script->getScriptNumber());
@ -705,7 +705,7 @@ void run_vm(EngineState *s) {
break; break;
case op_not: // 0x0c (12) case op_not: // 0x0c (12)
s->r_acc = make_reg(0, !(s->r_acc.offset || s->r_acc.segment)); s->r_acc = make_reg(0, !(s->r_acc.getOffset() || s->r_acc.getSegment()));
// Must allow pointers to be negated, as this is used for checking whether objects exist // Must allow pointers to be negated, as this is used for checking whether objects exist
break; break;
@ -765,30 +765,30 @@ void run_vm(EngineState *s) {
case op_bt: // 0x17 (23) case op_bt: // 0x17 (23)
// Branch relative if true // Branch relative if true
if (s->r_acc.offset || s->r_acc.segment) if (s->r_acc.getOffset() || s->r_acc.getSegment())
s->xs->addr.pc.offset += opparams[0]; s->xs->addr.pc.incOffset(opparams[0]);
if (s->xs->addr.pc.offset >= local_script->getScriptSize()) if (s->xs->addr.pc.getOffset() >= local_script->getScriptSize())
error("[VM] op_bt: request to jump past the end of script %d (offset %d, script is %d bytes)", error("[VM] op_bt: request to jump past the end of script %d (offset %d, script is %d bytes)",
local_script->getScriptNumber(), s->xs->addr.pc.offset, local_script->getScriptSize()); local_script->getScriptNumber(), s->xs->addr.pc.getOffset(), local_script->getScriptSize());
break; break;
case op_bnt: // 0x18 (24) case op_bnt: // 0x18 (24)
// Branch relative if not true // Branch relative if not true
if (!(s->r_acc.offset || s->r_acc.segment)) if (!(s->r_acc.getOffset() || s->r_acc.getSegment()))
s->xs->addr.pc.offset += opparams[0]; s->xs->addr.pc.incOffset(opparams[0]);
if (s->xs->addr.pc.offset >= local_script->getScriptSize()) if (s->xs->addr.pc.getOffset() >= local_script->getScriptSize())
error("[VM] op_bnt: request to jump past the end of script %d (offset %d, script is %d bytes)", error("[VM] op_bnt: request to jump past the end of script %d (offset %d, script is %d bytes)",
local_script->getScriptNumber(), s->xs->addr.pc.offset, local_script->getScriptSize()); local_script->getScriptNumber(), s->xs->addr.pc.getOffset(), local_script->getScriptSize());
break; break;
case op_jmp: // 0x19 (25) case op_jmp: // 0x19 (25)
s->xs->addr.pc.offset += opparams[0]; s->xs->addr.pc.incOffset(opparams[0]);
if (s->xs->addr.pc.offset >= local_script->getScriptSize()) if (s->xs->addr.pc.getOffset() >= local_script->getScriptSize())
error("[VM] op_jmp: request to jump past the end of script %d (offset %d, script is %d bytes)", error("[VM] op_jmp: request to jump past the end of script %d (offset %d, script is %d bytes)",
local_script->getScriptNumber(), s->xs->addr.pc.offset, local_script->getScriptSize()); local_script->getScriptNumber(), s->xs->addr.pc.getOffset(), local_script->getScriptSize());
break; break;
case op_ldi: // 0x1a (26) case op_ldi: // 0x1a (26)
@ -831,13 +831,13 @@ void run_vm(EngineState *s) {
int argc = (opparams[1] >> 1) // Given as offset, but we need count int argc = (opparams[1] >> 1) // Given as offset, but we need count
+ 1 + s->r_rest; + 1 + s->r_rest;
StackPtr call_base = s->xs->sp - argc; StackPtr call_base = s->xs->sp - argc;
s->xs->sp[1].offset += s->r_rest; s->xs->sp[1].incOffset(s->r_rest);
uint16 localCallOffset = s->xs->addr.pc.offset + opparams[0]; uint16 localCallOffset = s->xs->addr.pc.getOffset() + opparams[0];
ExecStack xstack(s->xs->objp, s->xs->objp, s->xs->sp, ExecStack xstack(s->xs->objp, s->xs->objp, s->xs->sp,
(call_base->requireUint16()) + s->r_rest, call_base, (call_base->requireUint16()) + s->r_rest, call_base,
s->xs->local_segment, make_reg(s->xs->addr.pc.segment, localCallOffset), s->xs->local_segment, make_reg(s->xs->addr.pc.getSegment(), localCallOffset),
NULL_SELECTOR, -1, localCallOffset, s->_executionStack.size() - 1, NULL_SELECTOR, -1, localCallOffset, s->_executionStack.size() - 1,
EXEC_STACK_TYPE_CALL); EXEC_STACK_TYPE_CALL);
@ -894,9 +894,9 @@ void run_vm(EngineState *s) {
s_temp = s->xs->sp; s_temp = s->xs->sp;
s->xs->sp -= temp; s->xs->sp -= temp;
s->xs->sp[0].offset += s->r_rest; s->xs->sp[0].incOffset(s->r_rest);
xs_new = execute_method(s, 0, opparams[0], s_temp, s->xs->objp, xs_new = execute_method(s, 0, opparams[0], s_temp, s->xs->objp,
s->xs->sp[0].offset, s->xs->sp); s->xs->sp[0].getOffset(), s->xs->sp);
s->r_rest = 0; // Used up the &rest adjustment s->r_rest = 0; // Used up the &rest adjustment
if (xs_new) // in case of error, keep old stack if (xs_new) // in case of error, keep old stack
s->_executionStackPosChanged = true; s->_executionStackPosChanged = true;
@ -908,11 +908,10 @@ void run_vm(EngineState *s) {
s_temp = s->xs->sp; s_temp = s->xs->sp;
s->xs->sp -= temp; s->xs->sp -= temp;
s->xs->sp[0].offset += s->r_rest; s->xs->sp[0].incOffset(s->r_rest);
xs_new = execute_method(s, opparams[0], opparams[1], s_temp, s->xs->objp, xs_new = execute_method(s, opparams[0], opparams[1], s_temp, s->xs->objp,
s->xs->sp[0].offset, s->xs->sp); s->xs->sp[0].getOffset(), s->xs->sp);
s->r_rest = 0; // Used up the &rest adjustment s->r_rest = 0; // Used up the &rest adjustment
if (xs_new) // in case of error, keep old stack if (xs_new) // in case of error, keep old stack
s->_executionStackPosChanged = true; s->_executionStackPosChanged = true;
break; break;
@ -965,7 +964,7 @@ void run_vm(EngineState *s) {
s_temp = s->xs->sp; s_temp = s->xs->sp;
s->xs->sp -= ((opparams[0] >> 1) + s->r_rest); // Adjust stack s->xs->sp -= ((opparams[0] >> 1) + s->r_rest); // Adjust stack
s->xs->sp[1].offset += s->r_rest; s->xs->sp[1].incOffset(s->r_rest);
xs_new = send_selector(s, s->r_acc, s->r_acc, s_temp, xs_new = send_selector(s, s->r_acc, s->r_acc, s_temp,
(int)(opparams[0] >> 1) + (uint16)s->r_rest, s->xs->sp); (int)(opparams[0] >> 1) + (uint16)s->r_rest, s->xs->sp);
@ -996,7 +995,7 @@ void run_vm(EngineState *s) {
case op_class: // 0x28 (40) case op_class: // 0x28 (40)
// Get class address // Get class address
s->r_acc = s->_segMan->getClassAddress((unsigned)opparams[0], SCRIPT_GET_LOCK, s->r_acc = s->_segMan->getClassAddress((unsigned)opparams[0], SCRIPT_GET_LOCK,
s->xs->addr.pc.segment); s->xs->addr.pc.getSegment());
break; break;
case 0x29: // (41) case 0x29: // (41)
@ -1008,7 +1007,7 @@ void run_vm(EngineState *s) {
s_temp = s->xs->sp; s_temp = s->xs->sp;
s->xs->sp -= ((opparams[0] >> 1) + s->r_rest); // Adjust stack s->xs->sp -= ((opparams[0] >> 1) + s->r_rest); // Adjust stack
s->xs->sp[1].offset += s->r_rest; s->xs->sp[1].incOffset(s->r_rest);
xs_new = send_selector(s, s->xs->objp, s->xs->objp, xs_new = send_selector(s, s->xs->objp, s->xs->objp,
s_temp, (int)(opparams[0] >> 1) + (uint16)s->r_rest, s_temp, (int)(opparams[0] >> 1) + (uint16)s->r_rest,
s->xs->sp); s->xs->sp);
@ -1021,7 +1020,7 @@ void run_vm(EngineState *s) {
case op_super: // 0x2b (43) case op_super: // 0x2b (43)
// Send to any class // Send to any class
r_temp = s->_segMan->getClassAddress(opparams[0], SCRIPT_GET_LOAD, s->xs->addr.pc.segment); r_temp = s->_segMan->getClassAddress(opparams[0], SCRIPT_GET_LOAD, s->xs->addr.pc.getSegment());
if (!r_temp.isPointer()) if (!r_temp.isPointer())
error("[VM]: Invalid superclass in object"); error("[VM]: Invalid superclass in object");
@ -1029,7 +1028,7 @@ void run_vm(EngineState *s) {
s_temp = s->xs->sp; s_temp = s->xs->sp;
s->xs->sp -= ((opparams[1] >> 1) + s->r_rest); // Adjust stack s->xs->sp -= ((opparams[1] >> 1) + s->r_rest); // Adjust stack
s->xs->sp[1].offset += s->r_rest; s->xs->sp[1].incOffset(s->r_rest);
xs_new = send_selector(s, r_temp, s->xs->objp, s_temp, xs_new = send_selector(s, r_temp, s->xs->objp, s_temp,
(int)(opparams[1] >> 1) + (uint16)s->r_rest, (int)(opparams[1] >> 1) + (uint16)s->r_rest,
s->xs->sp); s->xs->sp);
@ -1058,14 +1057,14 @@ void run_vm(EngineState *s) {
var_number = temp & 0x03; // Get variable type var_number = temp & 0x03; // Get variable type
// Get variable block offset // Get variable block offset
r_temp.segment = s->variablesSegment[var_number]; r_temp.setSegment(s->variablesSegment[var_number]);
r_temp.offset = s->variables[var_number] - s->variablesBase[var_number]; r_temp.setOffset(s->variables[var_number] - s->variablesBase[var_number]);
if (temp & 0x08) // Add accumulator offset if requested if (temp & 0x08) // Add accumulator offset if requested
r_temp.offset += s->r_acc.requireSint16(); r_temp.incOffset(s->r_acc.requireSint16());
r_temp.offset += opparams[1]; // Add index r_temp.incOffset(opparams[1]); // Add index
r_temp.offset *= 2; // variables are 16 bit r_temp.setOffset(r_temp.getOffset() * 2); // variables are 16 bit
// That's the immediate address now // That's the immediate address now
s->r_acc = r_temp; s->r_acc = r_temp;
break; break;
@ -1129,28 +1128,28 @@ void run_vm(EngineState *s) {
case op_lofsa: // 0x39 (57) case op_lofsa: // 0x39 (57)
case op_lofss: // 0x3a (58) case op_lofss: // 0x3a (58)
// Load offset to accumulator or push to stack // Load offset to accumulator or push to stack
r_temp.segment = s->xs->addr.pc.segment; r_temp.setSegment(s->xs->addr.pc.getSegment());
switch (g_sci->_features->detectLofsType()) { switch (g_sci->_features->detectLofsType()) {
case SCI_VERSION_0_EARLY: case SCI_VERSION_0_EARLY:
r_temp.offset = s->xs->addr.pc.offset + opparams[0]; r_temp.setOffset(s->xs->addr.pc.getOffset() + opparams[0]);
break; break;
case SCI_VERSION_1_MIDDLE: case SCI_VERSION_1_MIDDLE:
r_temp.offset = opparams[0]; r_temp.setOffset(opparams[0]);
break; break;
case SCI_VERSION_1_1: case SCI_VERSION_1_1:
r_temp.offset = opparams[0] + local_script->getScriptSize(); r_temp.setOffset(opparams[0] + local_script->getScriptSize());
break; break;
case SCI_VERSION_3: case SCI_VERSION_3:
// In theory this can break if the variant with a one-byte argument is // In theory this can break if the variant with a one-byte argument is
// used. For now, assume it doesn't happen. // used. For now, assume it doesn't happen.
r_temp.offset = local_script->relocateOffsetSci3(s->xs->addr.pc.offset-2); r_temp.setOffset(local_script->relocateOffsetSci3(s->xs->addr.pc.getOffset() - 2));
break; break;
default: default:
error("Unknown lofs type"); error("Unknown lofs type");
} }
if (r_temp.offset >= scr->getBufSize()) if (r_temp.getOffset() >= scr->getBufSize())
error("VM: lofsa/lofss operation overflowed: %04x:%04x beyond end" error("VM: lofsa/lofss operation overflowed: %04x:%04x beyond end"
" of script (at %04x)", PRINT_REG(r_temp), scr->getBufSize()); " of script (at %04x)", PRINT_REG(r_temp), scr->getBufSize());

View file

@ -116,7 +116,7 @@ struct ExecStack {
if (localsSegment_ != 0xFFFF) if (localsSegment_ != 0xFFFF)
local_segment = localsSegment_; local_segment = localsSegment_;
else else
local_segment = pc_.segment; local_segment = pc_.getSegment();
debugSelector = debugSelector_; debugSelector = debugSelector_;
debugExportId = debugExportId_; debugExportId = debugExportId_;
debugLocalCallOffset = debugLocalCallOffset_; debugLocalCallOffset = debugLocalCallOffset_;

View file

@ -43,17 +43,17 @@ reg_t reg_t::lookForWorkaround(const reg_t right) const {
reg_t reg_t::operator+(const reg_t right) const { reg_t reg_t::operator+(const reg_t right) const {
if (isPointer() && right.isNumber()) { if (isPointer() && right.isNumber()) {
// Pointer arithmetics. Only some pointer types make sense here // Pointer arithmetics. Only some pointer types make sense here
SegmentObj *mobj = g_sci->getEngineState()->_segMan->getSegmentObj(segment); SegmentObj *mobj = g_sci->getEngineState()->_segMan->getSegmentObj(getSegment());
if (!mobj) if (!mobj)
error("[VM]: Attempt to add %d to invalid pointer %04x:%04x", right.offset, PRINT_REG(*this)); error("[VM]: Attempt to add %d to invalid pointer %04x:%04x", right.getOffset(), PRINT_REG(*this));
switch (mobj->getType()) { switch (mobj->getType()) {
case SEG_TYPE_LOCALS: case SEG_TYPE_LOCALS:
case SEG_TYPE_SCRIPT: case SEG_TYPE_SCRIPT:
case SEG_TYPE_STACK: case SEG_TYPE_STACK:
case SEG_TYPE_DYNMEM: case SEG_TYPE_DYNMEM:
return make_reg(segment, offset + right.toSint16()); return make_reg(getSegment(), getOffset() + right.toSint16());
default: default:
return lookForWorkaround(right); return lookForWorkaround(right);
} }
@ -69,12 +69,12 @@ reg_t reg_t::operator+(const reg_t right) const {
} }
reg_t reg_t::operator-(const reg_t right) const { reg_t reg_t::operator-(const reg_t right) const {
if (segment == right.segment) { if (getSegment() == right.getSegment()) {
// We can subtract numbers, or pointers with the same segment, // We can subtract numbers, or pointers with the same segment,
// an operation which will yield a number like in C // an operation which will yield a number like in C
return make_reg(0, toSint16() - right.toSint16()); return make_reg(0, toSint16() - right.toSint16());
} else { } else {
return *this + make_reg(right.segment, -right.offset); return *this + make_reg(right.getSegment(), -right.toSint16());
} }
} }
@ -174,7 +174,7 @@ reg_t reg_t::operator^(const reg_t right) const {
} }
int reg_t::cmp(const reg_t right, bool treatAsUnsigned) const { int reg_t::cmp(const reg_t right, bool treatAsUnsigned) const {
if (segment == right.segment) { // can compare things in the same segment if (getSegment() == right.getSegment()) { // can compare things in the same segment
if (treatAsUnsigned || !isNumber()) if (treatAsUnsigned || !isNumber())
return toUint16() - right.toUint16(); return toUint16() - right.toUint16();
else else
@ -218,7 +218,7 @@ bool reg_t::pointerComparisonWithInteger(const reg_t right) const {
// SQ1, room 28, when throwing water at the Orat // SQ1, room 28, when throwing water at the Orat
// SQ1, room 58, when giving the ID card to the robot // SQ1, room 58, when giving the ID card to the robot
// SQ4 CD, at the first game screen, when the narrator is about to speak // SQ4 CD, at the first game screen, when the narrator is about to speak
return (isPointer() && right.isNumber() && right.offset <= 2000 && getSciVersion() <= SCI_VERSION_1_1); return (isPointer() && right.isNumber() && right.getOffset() <= 2000 && getSciVersion() <= SCI_VERSION_1_1);
} }
} // End of namespace Sci } // End of namespace Sci

View file

@ -31,43 +31,64 @@ namespace Sci {
typedef uint16 SegmentId; typedef uint16 SegmentId;
struct reg_t { struct reg_t {
SegmentId segment; // Segment and offset. These should never be accessed directly
uint16 offset; SegmentId _segment;
uint16 _offset;
inline SegmentId getSegment() const {
return _segment;
}
inline void setSegment(SegmentId segment) {
_segment = segment;
}
inline uint16 getOffset() const {
return _offset;
}
inline void setOffset(uint16 offset) {
_offset = offset;
}
inline void incOffset(int16 offset) {
setOffset(getOffset() + offset);
}
inline bool isNull() const { inline bool isNull() const {
return (offset | segment) == 0; return (_offset | getSegment()) == 0;
} }
inline uint16 toUint16() const { inline uint16 toUint16() const {
return offset; return _offset;
} }
inline int16 toSint16() const { inline int16 toSint16() const {
return (int16)offset; return (int16)_offset;
} }
bool isNumber() const { bool isNumber() const {
return segment == 0; return getSegment() == 0;
} }
bool isPointer() const { bool isPointer() const {
return segment != 0 && segment != 0xFFFF; return getSegment() != 0 && getSegment() != 0xFFFF;
} }
uint16 requireUint16() const; uint16 requireUint16() const;
int16 requireSint16() const; int16 requireSint16() const;
inline bool isInitialized() const { inline bool isInitialized() const {
return segment != 0xFFFF; return getSegment() != 0xFFFF;
} }
// Comparison operators // Comparison operators
bool operator==(const reg_t &x) const { bool operator==(const reg_t &x) const {
return (offset == x.offset) && (segment == x.segment); return (getOffset() == x.getOffset()) && (getSegment() == x.getSegment());
} }
bool operator!=(const reg_t &x) const { bool operator!=(const reg_t &x) const {
return (offset != x.offset) || (segment != x.segment); return (getOffset() != x.getOffset()) || (getSegment() != x.getSegment());
} }
bool operator>(const reg_t right) const { bool operator>(const reg_t right) const {
@ -141,12 +162,12 @@ private:
static inline reg_t make_reg(SegmentId segment, uint16 offset) { static inline reg_t make_reg(SegmentId segment, uint16 offset) {
reg_t r; reg_t r;
r.offset = offset; r.setSegment(segment);
r.segment = segment; r.setOffset(offset);
return r; return r;
} }
#define PRINT_REG(r) (0xffff) & (unsigned) (r).segment, (unsigned) (r).offset #define PRINT_REG(r) (0xffff) & (unsigned) (r).getSegment(), (unsigned) (r).getOffset()
// Stack pointer type // Stack pointer type
typedef reg_t *StackPtr; typedef reg_t *StackPtr;

View file

@ -723,7 +723,7 @@ void GfxAnimate::printAnimateList(Console *con) {
const AnimateList::iterator end = _list.end(); const AnimateList::iterator end = _list.end();
for (it = _list.begin(); it != end; ++it) { for (it = _list.begin(); it != end; ++it) {
Script *scr = _s->_segMan->getScriptIfLoaded(it->object.segment); Script *scr = _s->_segMan->getScriptIfLoaded(it->object.getSegment());
int16 scriptNo = scr ? scr->getScriptNumber() : -1; int16 scriptNo = scr ? scr->getScriptNumber() : -1;
con->DebugPrintf("%04x:%04x (%s), script %d, view %d (%d, %d), pal %d, " con->DebugPrintf("%04x:%04x (%s), script %d, view %d (%d, %d), pal %d, "

View file

@ -219,7 +219,7 @@ void GfxMenu::kernelAddEntry(Common::String title, Common::String content, reg_t
} }
} }
itemEntry->textVmPtr = contentVmPtr; itemEntry->textVmPtr = contentVmPtr;
itemEntry->textVmPtr.offset += beginPos; itemEntry->textVmPtr.incOffset(beginPos);
if (rightAlignedPos) { if (rightAlignedPos) {
rightAlignedPos++; rightAlignedPos++;
@ -297,13 +297,13 @@ void GfxMenu::kernelSetAttribute(uint16 menuId, uint16 itemId, uint16 attributeI
// We assume here that no script ever creates a separatorLine dynamically // We assume here that no script ever creates a separatorLine dynamically
break; break;
case SCI_MENU_ATTRIBUTE_KEYPRESS: case SCI_MENU_ATTRIBUTE_KEYPRESS:
itemEntry->keyPress = tolower(value.offset); itemEntry->keyPress = tolower(value.getOffset());
itemEntry->keyModifier = 0; itemEntry->keyModifier = 0;
// TODO: Find out how modifier is handled // TODO: Find out how modifier is handled
debug("setAttr keypress %X %X", value.segment, value.offset); debug("setAttr keypress %X %X", value.getSegment(), value.getOffset());
break; break;
case SCI_MENU_ATTRIBUTE_TAG: case SCI_MENU_ATTRIBUTE_TAG:
itemEntry->tag = value.offset; itemEntry->tag = value.getOffset();
break; break;
default: default:
// Happens when loading a game in LSL3 - attribute 1A // Happens when loading a game in LSL3 - attribute 1A

View file

@ -491,10 +491,10 @@ reg_t GfxPaint16::kernelDisplay(const char *text, int argc, reg_t *argv) {
// processing codes in argv // processing codes in argv
while (argc > 0) { while (argc > 0) {
displayArg = argv[0]; displayArg = argv[0];
if (displayArg.segment) if (displayArg.getSegment())
displayArg.offset = 0xFFFF; displayArg.setOffset(0xFFFF);
argc--; argv++; argc--; argv++;
switch (displayArg.offset) { switch (displayArg.getOffset()) {
case SCI_DISPLAY_MOVEPEN: case SCI_DISPLAY_MOVEPEN:
_ports->moveTo(argv[0].toUint16(), argv[1].toUint16()); _ports->moveTo(argv[0].toUint16(), argv[1].toUint16());
argc -= 2; argv += 2; argc -= 2; argv += 2;
@ -547,9 +547,9 @@ reg_t GfxPaint16::kernelDisplay(const char *text, int argc, reg_t *argv) {
if (!(g_sci->getGameId() == GID_LONGBOW && g_sci->isDemo()) && if (!(g_sci->getGameId() == GID_LONGBOW && g_sci->isDemo()) &&
!(g_sci->getGameId() == GID_QFG1 && g_sci->isDemo()) && !(g_sci->getGameId() == GID_QFG1 && g_sci->isDemo()) &&
!(g_sci->getGameId() == GID_PQ2)) !(g_sci->getGameId() == GID_PQ2))
error("Unknown kDisplay argument %d", displayArg.offset); error("Unknown kDisplay argument %d", displayArg.getOffset());
if (displayArg.offset == SCI_DISPLAY_DUMMY2) { if (displayArg.getOffset() == SCI_DISPLAY_DUMMY2) {
if (!argc) if (!argc)
error("No parameter left for kDisplay(115)"); error("No parameter left for kDisplay(115)");
argc--; argv++; argc--; argv++;

View file

@ -2590,7 +2590,7 @@ Common::String ResourceManager::findSierraGameId() {
if (!heap) if (!heap)
return ""; return "";
int16 gameObjectOffset = findGameObject(false).offset; int16 gameObjectOffset = findGameObject(false).getOffset();
if (!gameObjectOffset) if (!gameObjectOffset)
return ""; return "";

View file

@ -453,8 +453,8 @@ static byte patchGameRestoreSaveSci21[] = {
}; };
static void patchGameSaveRestoreCode(SegManager *segMan, reg_t methodAddress, byte id) { static void patchGameSaveRestoreCode(SegManager *segMan, reg_t methodAddress, byte id) {
Script *script = segMan->getScript(methodAddress.segment); Script *script = segMan->getScript(methodAddress.getSegment());
byte *patchPtr = const_cast<byte *>(script->getBuf(methodAddress.offset)); byte *patchPtr = const_cast<byte *>(script->getBuf(methodAddress.getOffset()));
if (getSciVersion() <= SCI_VERSION_1_1) if (getSciVersion() <= SCI_VERSION_1_1)
memcpy(patchPtr, patchGameRestoreSave, sizeof(patchGameRestoreSave)); memcpy(patchPtr, patchGameRestoreSave, sizeof(patchGameRestoreSave));
else // SCI2+ else // SCI2+
@ -463,8 +463,8 @@ static void patchGameSaveRestoreCode(SegManager *segMan, reg_t methodAddress, by
} }
static void patchGameSaveRestoreCodeSci21(SegManager *segMan, reg_t methodAddress, byte id, bool doRestore) { static void patchGameSaveRestoreCodeSci21(SegManager *segMan, reg_t methodAddress, byte id, bool doRestore) {
Script *script = segMan->getScript(methodAddress.segment); Script *script = segMan->getScript(methodAddress.getSegment());
byte *patchPtr = const_cast<byte *>(script->getBuf(methodAddress.offset)); byte *patchPtr = const_cast<byte *>(script->getBuf(methodAddress.getOffset()));
memcpy(patchPtr, patchGameRestoreSaveSci21, sizeof(patchGameRestoreSaveSci21)); memcpy(patchPtr, patchGameRestoreSaveSci21, sizeof(patchGameRestoreSaveSci21));
if (doRestore) if (doRestore)
patchPtr[2] = 0x78; // push1 patchPtr[2] = 0x78; // push1
@ -740,7 +740,7 @@ GUI::Debugger *SciEngine::getDebugger() {
if (_gamestate) { if (_gamestate) {
ExecStack *xs = &(_gamestate->_executionStack.back()); ExecStack *xs = &(_gamestate->_executionStack.back());
if (xs) { if (xs) {
xs->addr.pc.offset = _debugState.old_pc_offset; xs->addr.pc.setOffset(_debugState.old_pc_offset);
xs->sp = _debugState.old_sp; xs->sp = _debugState.old_sp;
} }
} }

View file

@ -61,7 +61,7 @@ reg_t SoundCommandParser::kDoSoundInit(int argc, reg_t *argv, reg_t acc) {
} }
int SoundCommandParser::getSoundResourceId(reg_t obj) { int SoundCommandParser::getSoundResourceId(reg_t obj) {
int resourceId = obj.segment ? readSelectorValue(_segMan, obj, SELECTOR(number)) : -1; int resourceId = obj.getSegment() ? readSelectorValue(_segMan, obj, SELECTOR(number)) : -1;
// Modify the resourceId for the Windows versions that have an alternate MIDI soundtrack, like SSCI did. // Modify the resourceId for the Windows versions that have an alternate MIDI soundtrack, like SSCI did.
if (g_sci && g_sci->_features->useAltWinGMSound()) { if (g_sci && g_sci->_features->useAltWinGMSound()) {
// Check if the alternate MIDI song actually exists... // Check if the alternate MIDI song actually exists...
@ -291,7 +291,7 @@ reg_t SoundCommandParser::kDoSoundPause(int argc, reg_t *argv, reg_t acc) {
reg_t obj = argv[0]; reg_t obj = argv[0];
uint16 value = argc > 1 ? argv[1].toUint16() : 0; uint16 value = argc > 1 ? argv[1].toUint16() : 0;
if (!obj.segment) { // pause the whole playlist if (!obj.getSegment()) { // pause the whole playlist
_music->pauseAll(value); _music->pauseAll(value);
} else { // pause a playlist slot } else { // pause a playlist slot
MusicEntry *musicSlot = _music->getSlot(obj); MusicEntry *musicSlot = _music->getSlot(obj);
@ -369,7 +369,7 @@ reg_t SoundCommandParser::kDoSoundFade(int argc, reg_t *argv, reg_t acc) {
case 5: // SCI1+ (SCI1 late sound scheme), with fade and continue case 5: // SCI1+ (SCI1 late sound scheme), with fade and continue
musicSlot->fadeTo = CLIP<uint16>(argv[1].toUint16(), 0, MUSIC_VOLUME_MAX); musicSlot->fadeTo = CLIP<uint16>(argv[1].toUint16(), 0, MUSIC_VOLUME_MAX);
// sometimes we get objects in that position, fix it up (ffs. workarounds) // sometimes we get objects in that position, fix it up (ffs. workarounds)
if (!argv[1].segment) if (!argv[1].getSegment())
musicSlot->fadeStep = volume > musicSlot->fadeTo ? -argv[3].toUint16() : argv[3].toUint16(); musicSlot->fadeStep = volume > musicSlot->fadeTo ? -argv[3].toUint16() : argv[3].toUint16();
else else
musicSlot->fadeStep = volume > musicSlot->fadeTo ? -5 : 5; musicSlot->fadeStep = volume > musicSlot->fadeTo ? -5 : 5;