예제 #1
0
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 {
예제 #2
0
void ScummEngine_v0::o_setOwnerOf() {
	int obj, owner;

	obj = getVarOrDirectWord(PARAM_1);
	owner = getVarOrDirectByte(PARAM_2);

	if (!obj)
		obj = _cmdObject;

	setOwnerOf(obj, owner);
}
예제 #3
0
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;
	}
}
예제 #4
0
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);
}
예제 #5
0
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);
}
예제 #6
0
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 {
예제 #7
0
void ScummEngine_v4::o4_ifNotState() {
	int a = getVarOrDirectWord(PARAM_1);
	int b = getVarOrDirectByte(PARAM_2);

	jumpRelative(getState(a) != b);
}
예제 #8
0
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 {
예제 #9
0
void ScummEngine_v2::o2_assignVarWordIndirect() {
	getResultPosIndirect();
	setResult(getVarOrDirectWord(PARAM_1));
}
예제 #10
0
int ScummEngine_v2::getActiveObject() {
	return getVarOrDirectWord(PARAM_1);
}
예제 #11
0
void ScummEngine_v0::o_getObjectOwner() {
	getResultPos();
	int obj = getVarOrDirectWord(PARAM_1);
	setResult(getOwner(obj ? obj : _cmdObject));
}