void ScummEngine_v2::o2_getObjPreposition() { getResultPos(); int obj = getVarOrDirectWord(PARAM_1); if (whereIsObject(obj) != WIO_NOT_FOUND) { byte *ptr = getOBCDFromObject(obj) + 12; setResult(*ptr >> 5); } else {
void ScummEngine_v0::o_setOwnerOf() { int obj, owner; obj = getVarOrDirectWord(PARAM_1); owner = getVarOrDirectByte(PARAM_2); if (!obj) obj = _cmdObject; setOwnerOf(obj, owner); }
void ScummEngine_v2::o2_setObjPreposition() { int obj = getVarOrDirectWord(PARAM_1); int unk = fetchScriptByte(); if (_game.platform == Common::kPlatformNES) return; if (whereIsObject(obj) != WIO_NOT_FOUND) { // FIXME: this might not work properly the moment we save and restore the game. byte *ptr = getOBCDFromObject(obj) + 12; *ptr &= 0x1F; *ptr |= unk << 5; } }
void ScummEngine_v4::o4_ifState() { int a = getVarOrDirectWord(PARAM_1); int b = getVarOrDirectByte(PARAM_2); // WORKAROUND bug #3306145 (also occurs in original): Some old versions of // Indy3 sometimes fail to allocate IQ points correctly. To quote: // "About the points error leaving Castle Brunwald: It seems to "reversed"! // When you get caught, free yourself and escape, you get 25 IQ points even // though you're not supposed to. However if you escape WITHOUT getting // caught, you get 0 IQ points (supposed to get 25 IQ points)." // This workaround is meant to address that. if (_game.id == GID_INDY3 && a == 367 && vm.slot[_currentScript].number == 363 && _currentRoom == 25) { b = 0; } jumpRelative(getState(a) == b); }
void ScummEngine_v4::o4_pickupObject() { int obj = getVarOrDirectWord(PARAM_1); if (obj < 1) { error("pickupObjectOld received invalid index %d (script %d)", obj, vm.slot[_currentScript].number); } if (getObjectIndex(obj) == -1) return; if (whereIsObject(obj) == WIO_INVENTORY) // Don't take an object twice return; // debug(0, "adding %d from %d to inventoryOld", obj, _currentRoom); addObjectToInventory(obj, _roomResource); markObjectRectAsDirty(obj); putOwner(obj, VAR(VAR_EGO)); putClass(obj, kObjectClassUntouchable, 1); putState(obj, 1); clearDrawObjectQueue(); runInventoryScript(1); }
void ScummEngine_v4::o4_oldRoomEffect() { int a; _opcode = fetchScriptByte(); if ((_opcode & 0x1F) == 3) { a = getVarOrDirectWord(PARAM_1); if (_game.platform == Common::kPlatformFMTowns && _game.version == 3) { if (a == 4) { _textSurface.fillRect(Common::Rect(0, 0, _textSurface.w * _textSurfaceMultiplier, _textSurface.h * _textSurfaceMultiplier), 0); #ifndef DISABLE_TOWNS_DUAL_LAYER_MODE if (_townsScreen) _townsScreen->clearLayer(1); #endif return; } } if (a) { _switchRoomEffect = (byte)(a & 0xFF); _switchRoomEffect2 = (byte)(a >> 8); } else {
void ScummEngine_v4::o4_ifNotState() { int a = getVarOrDirectWord(PARAM_1); int b = getVarOrDirectByte(PARAM_2); jumpRelative(getState(a) != b); }
void ScummEngine_v4::o4_oldRoomEffect() { int a; _opcode = fetchScriptByte(); if ((_opcode & 0x1F) == 3) { a = getVarOrDirectWord(PARAM_1); #if 1 if (_game.platform == Common::kPlatformFMTowns && _game.version == 3) { // FIXME / TODO: OK the first thing to note is: at least in Zak256, // maybe also in other games, this opcode does a bit more. I added // some stubs here, but somebody with a full IDA or more knowledge // about this will have to fill in the gaps. At least now we know // that something is missing here :-) if (a == 4) { //printf("o5_oldRoomEffect ODDBALL: _opcode = 0x%x, a = 0x%x\n", _opcode, a); // No idea what byte_2FCCF is, but it's a globale boolean flag. // I only add it here as a temporary hack to make the pseudo code compile. // Maybe it is just there as a reentry protection guard, given // how it is used? It might also correspond to _screenEffectFlag. int byte_2FCCF = 0; // For now, we force a redraw of the screen background. This // way the Zak end credits seem to work mostly correct. VirtScreen *vs = &_virtscr[kMainVirtScreen]; restoreBackground(Common::Rect(0, vs->topline, vs->w, vs->topline + vs->h)); vs->setDirtyRange(0, vs->h); updateDirtyScreen(kMainVirtScreen); if (byte_2FCCF) { // Here now "sub_1C44" is called, which sets byte_2FCCF to 0 then // calls yet another sub (which also reads byte_2FCCF): byte_2FCCF = 0; //call sub_0BB3 // Now sub_085C is called. This is quite simply: it sets // 0xF000 bytes. starting at 0x40000 to 0. No idea what that // buffer is, maybe a screen buffer, though. Note that // 0xF000 = 320*192. // Maybe this is also the charset mask being cleaned? // call sub_085C // And then sub_1C54 is called, which is almost identical to // the above sub_1C44, only it sets byte_2FCCF to 1: byte_2FCCF = 1; // call sub_0BB3 } else { // Here only sub_085C is called (see comment above) // call sub_085C } return; } #endif } if (a) { _switchRoomEffect = (byte)(a & 0xFF); _switchRoomEffect2 = (byte)(a >> 8); } else {
void ScummEngine_v2::o2_assignVarWordIndirect() { getResultPosIndirect(); setResult(getVarOrDirectWord(PARAM_1)); }
int ScummEngine_v2::getActiveObject() { return getVarOrDirectWord(PARAM_1); }
void ScummEngine_v0::o_getObjectOwner() { getResultPos(); int obj = getVarOrDirectWord(PARAM_1); setResult(getOwner(obj ? obj : _cmdObject)); }