diff options
author | Max Horn | 2003-05-20 20:42:28 +0000 |
---|---|---|
committer | Max Horn | 2003-05-20 20:42:28 +0000 |
commit | 1a394aa3c764c8a50def5bb9d8aa1342d962fbdd (patch) | |
tree | fc456ba99a56a6b594cc4817807a59531af2ecd2 | |
parent | 410f8b48264ed9fd02f0d18d462d74a67688f9fa (diff) | |
download | scummvm-rg350-1a394aa3c764c8a50def5bb9d8aa1342d962fbdd.tar.gz scummvm-rg350-1a394aa3c764c8a50def5bb9d8aa1342d962fbdd.tar.bz2 scummvm-rg350-1a394aa3c764c8a50def5bb9d8aa1342d962fbdd.zip |
added enum's for the known actor/object claasses; extended putClass/getClass to translate the X/Y flip classes; made code use the new enum's; some other cleanup
svn-id: r7753
-rw-r--r-- | scumm/actor.cpp | 84 | ||||
-rw-r--r-- | scumm/actor.h | 18 | ||||
-rw-r--r-- | scumm/boxes.cpp | 6 | ||||
-rw-r--r-- | scumm/debugger.cpp | 2 | ||||
-rw-r--r-- | scumm/object.cpp | 60 | ||||
-rw-r--r-- | scumm/script.cpp | 230 | ||||
-rw-r--r-- | scumm/script_v5.cpp | 4 | ||||
-rw-r--r-- | scumm/script_v6.cpp | 2 | ||||
-rw-r--r-- | scumm/script_v8.cpp | 2 | ||||
-rw-r--r-- | scumm/scumm.h | 10 | ||||
-rw-r--r-- | scumm/scummvm.cpp | 5 |
11 files changed, 222 insertions, 201 deletions
diff --git a/scumm/actor.cpp b/scumm/actor.cpp index 4be44f161d..3d6972e0c0 100644 --- a/scumm/actor.cpp +++ b/scumm/actor.cpp @@ -32,8 +32,15 @@ #include <math.h> -byte Actor::INVALID_BOX = 0; +byte Actor::kInvalidBox = 0; +Scumm *Actor::_vm = 0; +void Actor::initActorClass(Scumm *scumm) { + _vm = scumm; + if (_vm->_features & GF_SMALL_HEADER) { + kInvalidBox = 255; + } +} void Actor::initActor(int mode) { if (mode == 1) { @@ -71,30 +78,28 @@ void Actor::initActor(int mode) { forceClip = 0; ignoreTurns = false; - initFrame = 1; - walkFrame = 2; - standFrame = 3; - talkFrame1 = 4; - talkFrame2 = 5; + if (_vm->_features & GF_AFTER_V2) { + initFrame = 2; + walkFrame = 0; + standFrame = 1; + talkFrame1 = 5; + talkFrame2 = 4; + } else { + initFrame = 1; + walkFrame = 2; + standFrame = 3; + talkFrame1 = 4; + talkFrame2 = 5; + } walk_script = 0; talk_script = 0; - if (_vm) { - if (_vm->_features & GF_AFTER_V2) { - initFrame = 2; - walkFrame = 0; - standFrame = 1; - talkFrame1 = 5; - talkFrame2 = 4; - } - _vm->_classData[number] = (_vm->_features & GF_AFTER_V7) ? _vm->_classData[0] : 0; - } + _vm->_classData[number] = (_vm->_features & GF_AFTER_V7) ? _vm->_classData[0] : 0; } void Actor::stopActorMoving() { - if (_vm) - _vm->stopScriptNr(walk_script); + _vm->stopScriptNr(walk_script); moving = 0; } @@ -219,12 +224,12 @@ int Actor::remapDirection(int dir, bool is_walking) { // for other games besides Loom! // Check for X-Flip - if ((flags & kBoxXFlip) || isInClass((_vm->_gameId == GID_LOOM256 || _vm->_gameId == GID_LOOM) ? 19 : 30)) { + if ((flags & kBoxXFlip) || isInClass(kObjectClassXFlip)) { dir = 360 - dir; flipX = !flipX; } // Check for Y-Flip - if ((flags & kBoxYFlip) || isInClass((_vm->_gameId == GID_LOOM256 || _vm->_gameId == GID_LOOM) ? 18 : 29)) { + if ((flags & kBoxYFlip) || isInClass(kObjectClassYFlip)) { dir = 180 - dir; flipY = !flipY; } @@ -605,7 +610,7 @@ AdjustBoxResult Actor::adjustXYToBeInBox(int dstX, int dstY) { abr.x = dstX; abr.y = dstY; - abr.dist = INVALID_BOX; + abr.dist = kInvalidBox; if (ignoreBoxes) return abr; @@ -618,14 +623,14 @@ AdjustBoxResult Actor::adjustXYToBeInBox(int dstX, int dstY) { return abr; bestDist = (uint) 0xFFFF; - bestBox = INVALID_BOX; + bestBox = kInvalidBox; // We iterate (backwards) over all boxes, searching the one closes // to the desired coordinates. for (box = numBoxes; box >= firstValidBox; box--) { flags = _vm->getBoxFlags(box); - if (flags & kBoxInvisible && (!(flags & kBoxPlayerOnly) || isInClass(31))) + if (flags & kBoxInvisible && !(flags & kBoxPlayerOnly && !isInClass(kObjectClassPlayer))) continue; // For increased performance, we perform a quick test if @@ -691,7 +696,7 @@ void Actor::adjustActorPos() { stopActorMoving(); } - if (walkbox != INVALID_BOX) { + if (walkbox != kInvalidBox) { byte flags = _vm->getBoxFlags(walkbox); if (flags & 7) { turnToDirection(facing); @@ -908,7 +913,7 @@ void Actor::drawActorCostume() { if (forceClip) cr._zbuf = forceClip; - else if (isInClass(20)) + else if (isInClass(kObjectClassNeverClip)) cr._zbuf = 0; else { cr._zbuf = _vm->getMaskFromBox(walkbox); @@ -1056,7 +1061,8 @@ int Scumm::getActorFromPos(int x, int y) { for (i = 1; i < _numActors; i++) { Actor *a = derefActor(i); assert(a->number == i); - if (testGfxUsageBit(x >> 3, i) && !getClass(i, 32) && y >= a->top && y <= a->bottom) { + if (testGfxUsageBit(x >> 3, i) && !getClass(i, kObjectClassUntouchable) + && y >= a->top && y <= a->bottom) { return i; } } @@ -1182,8 +1188,8 @@ void Actor::startWalkActor(int destX, int destY, int dir) { } if (ignoreBoxes) { - abr.dist = INVALID_BOX; - walkbox = INVALID_BOX; + abr.dist = kInvalidBox; + walkbox = kInvalidBox; } else { if (_vm->checkXYInBoxBounds(walkdata.destbox, abr.x, abr.y)) { abr.dist = walkdata.destbox; @@ -1294,7 +1300,7 @@ void Actor::walkActor() { do { moving &= ~MF_NEW_LEG; - if (walkbox == INVALID_BOX) { + if (walkbox == kInvalidBox) { setBox(walkdata.destbox); walkdata.curbox = walkdata.destbox; break; @@ -1366,7 +1372,7 @@ void Actor::walkActorOld() { do { moving &= ~MF_NEW_LEG; - if (walkbox == INVALID_BOX) { + if (walkbox == kInvalidBox) { walkbox = walkdata.destbox; walkdata.curbox = walkdata.destbox; break; @@ -1385,7 +1391,7 @@ void Actor::walkActorOld() { // FIXME: not sure if this is needed in non-Zak games, but I think it shouldn't // hurt there either. int flags = _vm->getBoxFlags(next_box); - if (flags & kBoxLocked && (!(flags & kBoxPlayerOnly) || isInClass(31))) { + if (flags & kBoxLocked && !(flags & kBoxPlayerOnly && !isInClass(kObjectClassPlayer))) { moving |= MF_LAST_LEG; return; } @@ -1509,22 +1515,10 @@ void Scumm::resetActorBgs() { } void Actor::classChanged(int cls, bool value) { - switch(cls) { - case 20: // Never clip - break; - case 21: // Always clip + if (cls == kObjectClassAlwaysClip) forceClip = value; - break; - case 22: // Ignore boxes + if (cls == kObjectClassIgnoreBoxes) ignoreBoxes = value; - break; - case 29: // Y flip - break; - case 30: // X flip - break; - case 31: // ?? - break; - } } bool Actor::isInClass(int cls) { diff --git a/scumm/actor.h b/scumm/actor.h index eac1557d7e..87a7e48110 100644 --- a/scumm/actor.h +++ b/scumm/actor.h @@ -70,6 +70,11 @@ struct CostumeData { class Actor { public: + static byte kInvalidBox; + + static void initActorClass(Scumm *scumm); + +public: int x, y, top, bottom; int elevation; uint width; @@ -102,18 +107,14 @@ public: uint16 sound[8]; CostumeData cost; byte palette[256]; - - static byte INVALID_BOX; - protected: - Scumm *_vm; + static Scumm *_vm; public: // Constructor, sets all data to 0 Actor() { - _vm = 0; - + assert(_vm != 0); top = bottom = 0; number = 0; needRedraw = needBgReset = costumeNeedsInit = visible = false; @@ -130,9 +131,6 @@ public: initActor(1); } - void initActorClass(Scumm *scumm) { - _vm = scumm; - } //protected: void hideActor(); void showActor(); @@ -192,7 +190,7 @@ public: } void classChanged(int cls, bool value); - + protected: bool isInClass(int cls); }; diff --git a/scumm/boxes.cpp b/scumm/boxes.cpp index 30cf6e9f98..a7acd0c139 100644 --- a/scumm/boxes.cpp +++ b/scumm/boxes.cpp @@ -280,7 +280,7 @@ int Scumm::getSpecialBox(int x, int y) { bool Scumm::checkXYInBoxBounds(int b, int x, int y) { BoxCoords box; - if (b < 0 || b == Actor::INVALID_BOX) + if (b < 0 || b == Actor::kInvalidBox) return false; getBoxCoordinates(b, &box); @@ -571,10 +571,10 @@ int Scumm::getPathToDestBox(byte from, byte to) { if (from == to) return to; - if (to == Actor::INVALID_BOX) + if (to == Actor::kInvalidBox) return -1; - if (from == Actor::INVALID_BOX) + if (from == Actor::kInvalidBox) return to; assert(from < numOfBoxes); diff --git a/scumm/debugger.cpp b/scumm/debugger.cpp index d70e096c41..a55279f1a2 100644 --- a/scumm/debugger.cpp +++ b/scumm/debugger.cpp @@ -638,7 +638,7 @@ bool ScummDebugger::Cmd_Object(int argc, const char **argv) { _s->addObjectToInventory(obj, atoi(argv[3])); _s->putOwner(obj, _s->VAR(_s->VAR_EGO)); - _s->putClass(obj, 32, 1); + _s->putClass(obj, kObjectClassUntouchable, 1); _s->putState(obj, 1); _s->removeObjectFromRoom(obj); _s->clearDrawObjectQueue(); diff --git a/scumm/object.cpp b/scumm/object.cpp index ab1a952504..8b2fa3bb61 100644 --- a/scumm/object.cpp +++ b/scumm/object.cpp @@ -34,12 +34,24 @@ bool Scumm::getClass(int obj, int cls) checkRange(32, 1, cls, "Class %d out of range in getClass"); if (_features & GF_SMALL_HEADER) { - if (cls == 31) // CLASS_PLAYERONLY - cls = 23; - - if (cls == 32) // CLASS_TOUCHABLE - cls = 24; + // Translate the new (V5) object classes to the old classes + // (for those which differ). + switch (cls) { + case kObjectClassUntouchable: + cls = 24; + break; + case kObjectClassPlayer: + cls = 23; + break; + case kObjectClassXFlip: + cls = 19; + break; + case kObjectClassYFlip: + cls = 18; + break; + } } + return (_classData[obj] & (1 << (cls - 1))) != 0; } @@ -50,20 +62,30 @@ void Scumm::putClass(int obj, int cls, bool set) checkRange(32, 1, cls, "Class %d out of range in putClass"); if (_features & GF_SMALL_HEADER) { - if (cls == 31) // CLASS_PLAYERONLY - cls = 23; - - if (cls == 32) // CLASS_TOUCHABLE - cls = 24; - - // FIXME: It isn't enough for the Indy3 intro to make the - // little trains ignore boxes (class 22), they have to always - // clip (class 21) as well. Is this yet another walkbox 0 - // error? - if (_gameId == GID_INDY3_256 && cls == 22 && _currentRoom == 76) - putClass(obj, 21, set); + // Translate the new (V5) object classes to the old classes + // (for those which differ). + switch (cls) { + case kObjectClassUntouchable: + cls = 24; + break; + case kObjectClassPlayer: + cls = 23; + break; + case kObjectClassXFlip: + cls = 19; + break; + case kObjectClassYFlip: + cls = 18; + break; + } } + // FIXME: It isn't enough for the Indy3 intro to make the + // little trains ignore boxes, they have to always clip as + // well. Is this yet another walkbox 0 error? + if (_gameId == GID_INDY3_256 && cls == kObjectClassIgnoreBoxes && _currentRoom == 76) + putClass(obj, kObjectClassAlwaysClip, set); + if (set) _classData[obj] |= (1 << (cls - 1)); else @@ -256,7 +278,7 @@ int Scumm::findObject(int x, int y) { const int mask = (_features & GF_AFTER_V2) ? 0x8 : 0xF; for (i = 1; i < _numLocalObjects; i++) { - if ((_objs[i].obj_nr < 1) || getClass(_objs[i].obj_nr, 32)) + if ((_objs[i].obj_nr < 1) || getClass(_objs[i].obj_nr, kObjectClassUntouchable)) continue; if (_features & GF_AFTER_V2 && _objs[i].state & 0x2) continue; @@ -403,7 +425,7 @@ void Scumm::drawObject(int obj, int arg) { byte flags = Gdi::dbAllowMaskOr; // Sam & Max needs this to fix object-layering problems with // the inventory and conversation icons. - if ((_features & GF_AFTER_V7 || _gameId == GID_SAMNMAX) && getClass(od->obj_nr, 22)) + if ((_features & GF_AFTER_V7 || _gameId == GID_SAMNMAX) && getClass(od->obj_nr, kObjectClassIgnoreBoxes)) flags |= Gdi::dbDrawMaskOnAll; gdi.drawBitmap(ptr, &virtscr[0], x, ypos, width << 3, height, x - xpos, numstrip, flags); } diff --git a/scumm/script.cpp b/scumm/script.cpp index 0c7a2c437b..476a5f1662 100644 --- a/scumm/script.cpp +++ b/scumm/script.cpp @@ -76,6 +76,121 @@ void Scumm::runScript(int script, bool freezeResistant, bool recursive, int *lva runScriptNested(slot); } +void Scumm::runVerbCode(int object, int entry, bool freezeResistant, bool recursive, int *vars) { + ScriptSlot *s; + uint32 obcd; + int slot, where, offs; + + if (!object) + return; + + if (!recursive) + stopObjectScript(object); + + where = whereIsObject(object); + + if (where == WIO_NOT_FOUND) { + warning("Code for object %d not in room %d", object, _roomResource); + return; + } + + obcd = getOBCDOffs(object); + slot = getScriptSlot(); + + offs = getVerbEntrypoint(object, entry); + if (offs == 0) + return; + + s = &vm.slot[slot]; + s->number = object; + s->offs = obcd + offs; + s->status = ssRunning; + s->where = where; + s->freezeResistant = freezeResistant; + s->recursive = recursive; + s->freezeCount = 0; + s->delayFrameCount = 0; + + initializeLocals(slot, vars); + + runScriptNested(slot); +} + +void Scumm::initializeLocals(int slot, int *vars) { + int i; + if (!vars) { + for (i = 0; i < 16; i++) + vm.localvar[slot][i] = 0; + } else { + for (i = 0; i < 16; i++) + vm.localvar[slot][i] = vars[i]; + } +} + +int Scumm::getVerbEntrypoint(int obj, int entry) { + byte *objptr, *verbptr; + int verboffs; + + if (whereIsObject(obj) == WIO_NOT_FOUND) + return 0; + + objptr = getOBCDFromObject(obj); + assert(objptr); + + if (_features & GF_AFTER_V2) + verbptr = objptr + 15; + else if (_features & GF_OLD_BUNDLE) + verbptr = objptr + 17; + else if (_features & GF_SMALL_HEADER) + verbptr = objptr + 19; + else + verbptr = findResource(MKID('VERB'), objptr); + + assert(verbptr); + + verboffs = verbptr - objptr; + + if (!(_features & GF_SMALL_HEADER)) + verbptr += _resourceHeaderSize; + + if (_features & GF_AFTER_V8) { + uint32 *ptr = (uint32 *)verbptr; + uint32 verb; + do { + verb = READ_LE_UINT32(ptr); + if (!verb) + return 0; + if (verb == (uint32)entry || verb == 0xFFFFFFFF) + break; + ptr += 2; + } while (1); + return verboffs + 8 + READ_LE_UINT32(ptr + 1); + } if (_features & GF_AFTER_V2) { + do { + if (!*verbptr) + return 0; + if (*verbptr == entry || *verbptr == 0xFF) + break; + verbptr += 2; + } while (1); + + return *(verbptr + 1); + } else { + do { + if (!*verbptr) + return 0; + if (*verbptr == entry || *verbptr == 0xFF) + break; + verbptr += 3; + } while (1); + + if (_features & GF_SMALL_HEADER) + return READ_LE_UINT16(verbptr + 1); + else + return verboffs + READ_LE_UINT16(verbptr + 1); + } +} + /* Stop script 'script' */ void Scumm::stopScriptNr(int script) { ScriptSlot *ss; @@ -794,121 +909,6 @@ void Scumm::decreaseScriptDelay(int amount) { } } -void Scumm::runVerbCode(int object, int entry, bool freezeResistant, bool recursive, int *vars) { - ScriptSlot *s; - uint32 obcd; - int slot, where, offs; - - if (!object) - return; - - if (!recursive) - stopObjectScript(object); - - where = whereIsObject(object); - - if (where == WIO_NOT_FOUND) { - warning("Code for object %d not in room %d", object, _roomResource); - return; - } - - obcd = getOBCDOffs(object); - slot = getScriptSlot(); - - offs = getVerbEntrypoint(object, entry); - if (offs == 0) - return; - - s = &vm.slot[slot]; - s->number = object; - s->offs = obcd + offs; - s->status = ssRunning; - s->where = where; - s->freezeResistant = freezeResistant; - s->recursive = recursive; - s->freezeCount = 0; - s->delayFrameCount = 0; - - initializeLocals(slot, vars); - - runScriptNested(slot); -} - -void Scumm::initializeLocals(int slot, int *vars) { - int i; - if (!vars) { - for (i = 0; i < 16; i++) - vm.localvar[slot][i] = 0; - } else { - for (i = 0; i < 16; i++) - vm.localvar[slot][i] = vars[i]; - } -} - -int Scumm::getVerbEntrypoint(int obj, int entry) { - byte *objptr, *verbptr; - int verboffs; - - if (whereIsObject(obj) == WIO_NOT_FOUND) - return 0; - - objptr = getOBCDFromObject(obj); - assert(objptr); - - if (_features & GF_AFTER_V2) - verbptr = objptr + 15; - else if (_features & GF_OLD_BUNDLE) - verbptr = objptr + 17; - else if (_features & GF_SMALL_HEADER) - verbptr = objptr + 19; - else - verbptr = findResource(MKID('VERB'), objptr); - - assert(verbptr); - - verboffs = verbptr - objptr; - - if (!(_features & GF_SMALL_HEADER)) - verbptr += _resourceHeaderSize; - - if (_features & GF_AFTER_V8) { - uint32 *ptr = (uint32 *)verbptr; - uint32 verb; - do { - verb = READ_LE_UINT32(ptr); - if (!verb) - return 0; - if (verb == (uint32)entry || verb == 0xFFFFFFFF) - break; - ptr += 2; - } while (1); - return verboffs + 8 + READ_LE_UINT32(ptr + 1); - } if (_features & GF_AFTER_V2) { - do { - if (!*verbptr) - return 0; - if (*verbptr == entry || *verbptr == 0xFF) - break; - verbptr += 2; - } while (1); - - return *(verbptr + 1); - } else { - do { - if (!*verbptr) - return 0; - if (*verbptr == entry || *verbptr == 0xFF) - break; - verbptr += 3; - } while (1); - - if (_features & GF_SMALL_HEADER) - return READ_LE_UINT16(verbptr + 1); - else - return verboffs + READ_LE_UINT16(verbptr + 1); - } -} - bool Scumm::isScriptRunning(int script) { int i; ScriptSlot *ss = vm.slot; diff --git a/scumm/script_v5.cpp b/scumm/script_v5.cpp index 3151a7c4d4..a02c71758f 100644 --- a/scumm/script_v5.cpp +++ b/scumm/script_v5.cpp @@ -1435,7 +1435,7 @@ void Scumm_v5::o5_pickupObject() { room = _roomResource; addObjectToInventory(obj, room); putOwner(obj, VAR(VAR_EGO)); - putClass(obj, 32, 1); + putClass(obj, kObjectClassUntouchable, 1); putState(obj, 1); removeObjectFromRoom(obj); clearDrawObjectQueue(); @@ -2637,7 +2637,7 @@ void Scumm_v5::o5_pickupObjectOld() { addObjectToInventory(obj, _roomResource); removeObjectFromRoom(obj); putOwner(obj, VAR(VAR_EGO)); - putClass(obj, 32, 1); + putClass(obj, kObjectClassUntouchable, 1); putState(obj, 1); clearDrawObjectQueue(); runHook(1); diff --git a/scumm/script_v6.cpp b/scumm/script_v6.cpp index 085aee3abd..f893c836f1 100644 --- a/scumm/script_v6.cpp +++ b/scumm/script_v6.cpp @@ -1120,7 +1120,7 @@ void Scumm_v6::o6_pickupObject() { addObjectToInventory(obj, room); putOwner(obj, VAR(VAR_EGO)); - putClass(obj, 32, 1); + putClass(obj, kObjectClassUntouchable, 1); putState(obj, 1); removeObjectFromRoom(obj); clearDrawObjectQueue(); diff --git a/scumm/script_v8.cpp b/scumm/script_v8.cpp index 469e5e8412..86b4c7a224 100644 --- a/scumm/script_v8.cpp +++ b/scumm/script_v8.cpp @@ -1540,7 +1540,7 @@ void Scumm_v8::o8_kernelGetFunctions() { if (eo->posX <= x && eo->width + eo->posX > x && eo->posY <= y && eo->height + eo->posY > y) { - if (!getClass(eo->number, 32)) { + if (!getClass(eo->number, kObjectClassUntouchable)) { push(eo->number); return; } diff --git a/scumm/scumm.h b/scumm/scumm.h index 0239590482..a797315d1a 100644 --- a/scumm/scumm.h +++ b/scumm/scumm.h @@ -61,6 +61,16 @@ enum { KEY_SET_OPTIONS = 3456 // WinCE }; +enum ObjectClass { + kObjectClassNeverClip = 20, + kObjectClassAlwaysClip = 21, + kObjectClassIgnoreBoxes = 22, + kObjectClassYFlip = 29, + kObjectClassXFlip = 30, + kObjectClassPlayer = 31, // Actor is controlled by the player + kObjectClassUntouchable = 32 +}; + #include "gfx.h" #include "boxes.h" diff --git a/scumm/scummvm.cpp b/scumm/scummvm.cpp index 1fd9e91b07..18be9f9983 100644 --- a/scumm/scummvm.cpp +++ b/scumm/scummvm.cpp @@ -542,9 +542,6 @@ Scumm::Scumm (GameDetector *detector, OSystem *syst) _hexdumpScripts = false; _showStack = false; - if (_features & GF_SMALL_HEADER) - Actor::INVALID_BOX = 255; - if (_gameId == GID_ZAK256) { // FmTowns is 320x240 _screenWidth = 320; _screenHeight = 240; @@ -695,11 +692,11 @@ void Scumm::scummInit() { setupCursor(); // Allocate and Initialize actors + Actor::initActorClass(this); _actors = new Actor[_numActors]; for (i = 1; i < _numActors; i++) { a = derefActor(i); a->number = i; - a->initActorClass(this); a->initActor(1); } |