Example #1
0
void SmushPlayer::init(int32 speed) {
	VirtScreen *vs = &_vm->_virtscr[kMainVirtScreen];

	_frame = 0;
	_speed = speed;
	_endOfFile = false;

	_vm->_smushVideoShouldFinish = false;
	_vm->_smushActive = true;

	_vm->setDirtyColors(0, 255);
	_dst = vs->getPixels(0, 0);

	// HACK HACK HACK: This is an *evil* trick, beware!
	// We do this to fix bug #1037052. A proper solution would change all the
	// drawing code to use the pitch value specified by the virtual screen.
	// However, since a lot of the SMUSH code currently assumes the screen
	// width and pitch to be equal, this will require lots of changes. So
	// we resort to this hackish solution for now.
	_origPitch = vs->pitch;
	_origNumStrips = _vm->_gdi->_numStrips;
	vs->pitch = vs->w;
	_vm->_gdi->_numStrips = vs->w / 8;

	_vm->_mixer->stopHandle(_compressedFileSoundHandle);
	_vm->_mixer->stopHandle(_IACTchannel);
	_IACTpos = 0;
	_vm->_smixer->stop();
}
Example #2
0
void MoviePlayer::handleNextFrame() {
	if (!_video->isVideoLoaded())
		return;

	VirtScreen *pvs = &_vm->_virtscr[kMainVirtScreen];

	if (_flags & 2) {
		uint8 *dstPtr = _vm->getResourceAddress(rtImage, _wizResNum);
		assert(dstPtr);
		uint8 *dst = _vm->findWrappedBlock(MKTAG('W','I','Z','D'), dstPtr, 0, 0);
		assert(dst);
		copyFrameToBuffer(dst, kDstResource, 0, 0, _vm->_screenWidth * _vm->_bytesPerPixel);
	} else if (_flags & 1) {
		copyFrameToBuffer(pvs->getBackPixels(0, 0), kDstScreen, 0, 0, pvs->pitch);

		Common::Rect imageRect(_video->getWidth(), _video->getHeight());
		_vm->restoreBackgroundHE(imageRect);
	} else {
		copyFrameToBuffer(pvs->getPixels(0, 0), kDstScreen, 0, 0, pvs->pitch);

		Common::Rect imageRect(_video->getWidth(), _video->getHeight());
		_vm->markRectAsDirty(kMainVirtScreen, imageRect);
	}

	if (_video->endOfVideo())
		_video->close();
}
Example #3
0
static void hlineColor(ScummEngine *scumm, int x1, int x2, int y, byte color) {
	VirtScreen *vs = &scumm->_virtscr[kMainVirtScreen];
	byte *ptr;

	// Clip y
	y += scumm->_screenTop;
	if (y < 0 || y >= scumm->_screenHeight)
		return;

	if (x2 < x1)
		SWAP(x2, x1);

	// Clip x1 / x2
	const int left = scumm->_screenStartStrip * 8;
	const int right = scumm->_screenEndStrip * 8;
	if (x1 < left)
		x1 = left;
	if (x2 >= right)
		x2 = right - 1;


	ptr = (byte *)vs->getBasePtr(x1, y);

	while (x1++ <= x2) {
		*ptr++ = color;
	}
}
void MoviePlayer::handleNextFrame() {
	if (_fd.isOpen() == false) {
		return;
	}

	VirtScreen *pvs = &_vm->virtscr[kMainVirtScreen];
	uint8 *dst;

	decodeFrame();

	if (_flags & 2) {
		uint8 *dstPtr = _vm->getResourceAddress(rtImage, _wizResNum);
		assert(dstPtr);
		dst = _vm->findWrappedBlock(MKID_BE('WIZD'), dstPtr, 0, 0);
		assert(dst);
		copyFrame(dst, 0, 0);
	} else if (_flags & 1) {
		dst = pvs->getBackPixels(0, 0);
		copyFrame(dst, 0, 0);
		
		Common::Rect imageRect(_width, _height);
		_vm->gdi.copyVirtScreenBuffers(imageRect);
	} else {
		dst = pvs->getPixels(0, 0);
		copyFrame(dst, 0, 0);

		_vm->markRectAsDirty(kMainVirtScreen, 0, 0, _width, _height);
	}

	_frameNum++;
	if (_frameNum == _framesCount) {
		close();
	}
}
Example #5
0
void ScummEngine_v2::checkV2MouseOver(Common::Point pos) {
	VirtScreen *vs = &_virtscr[kVerbVirtScreen];
	Common::Rect rect;
	byte *ptr, *dst;
	int i, x, y, new_box = -1;

	// Don't do anything unless the inventory is active
	if (!(_userState & USERSTATE_IFACE_INVENTORY)) {
		_mouseOverBoxV2 = -1;
		return;
	}

	if (_cursor.state > 0) {
		for (i = 0; i < ARRAYSIZE(_mouseOverBoxesV2); i++) {
			if (_mouseOverBoxesV2[i].rect.contains(pos.x, pos.y - vs->topline)) {
				new_box = i;
				break;
			}
		}
	}

	if ((new_box != _mouseOverBoxV2) || (_game.version == 0)) {
		if (_mouseOverBoxV2 != -1) {
			rect = _mouseOverBoxesV2[_mouseOverBoxV2].rect;

			dst = ptr = vs->getPixels(rect.left, rect.top);

			// Remove highlight.
			for (y = rect.height() - 1; y >= 0; y--) {
				for (x = rect.width() - 1; x >= 0; x--) {
					if (dst[x] == _mouseOverBoxesV2[_mouseOverBoxV2].hicolor)
						dst[x] = _mouseOverBoxesV2[_mouseOverBoxV2].color;
				}
				dst += vs->pitch;
			}

			markRectAsDirty(kVerbVirtScreen, rect);
		}

		if (new_box != -1) {
			rect = _mouseOverBoxesV2[new_box].rect;

			dst = ptr = vs->getPixels(rect.left, rect.top);

			// Apply highlight
			for (y = rect.height() - 1; y >= 0; y--) {
				for (x = rect.width() - 1; x >= 0; x--) {
					if (dst[x] == _mouseOverBoxesV2[new_box].color)
						dst[x] = _mouseOverBoxesV2[new_box].hicolor;
				}
				dst += vs->pitch;
			}

			markRectAsDirty(kVerbVirtScreen, rect);
		}

		_mouseOverBoxV2 = new_box;
	}
}
Example #6
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 {
Example #7
0
void CharsetRendererV3::printChar(int chr, bool ignoreCharsetMask) {
	// WORKAROUND for bug #1509509: Indy3 Mac does not show black
	// characters (such as in the grail diary) if ignoreCharsetMask
	// is true. See also patch #1851568.
	if (_vm->_game.id == GID_INDY3 && _vm->_game.platform == Common::kPlatformMacintosh && _color == 0)
		ignoreCharsetMask = false;

	// Indy3 / Zak256 / Loom
	int width, height, origWidth = 0, origHeight;
	VirtScreen *vs;
	const byte *charPtr;
	byte *dst;
	int is2byte = (chr >= 256 && _vm->_useCJKMode) ? 1 : 0;

	assertRange(0, _curId, _vm->_numCharsets - 1, "charset");

	if ((vs = _vm->findVirtScreen(_top)) == NULL)
		return;

	if (chr == '@')
		return;

	if (_vm->_useCJKMode && chr > 127) {
		if (_vm->_game.platform == Common::kPlatformFMTowns) {
			charPtr = 0;
			width = _vm->_cjkFont->getCharWidth(chr);
			height = _vm->_cjkFont->getFontHeight();
		} else {
			width = _vm->_2byteWidth;
			height = _vm->_2byteHeight;
			charPtr = _vm->get2byteCharPtr(chr);
		}
	} else {
		charPtr = _fontPtr + chr * 8;
		width = getCharWidth(chr);
		height = 8;
	}

	// Clip at the right side (to avoid drawing "outside" the screen bounds).
	if (_left + origWidth > _right + 1)
		return;

	origWidth = width;
	origHeight = height;

	if (_shadowMode != kNoShadowMode) {
		width++;
		height++;
	}

	if (_firstChar) {
		_str.left = _left;
		_str.top = _top;
		_str.right = _left;
		_str.bottom = _top;
		_firstChar = false;
	}

	int drawTop = _top - vs->topline;

	_vm->markRectAsDirty(vs->number, _left, _left + width, drawTop, drawTop + height);

	if (!ignoreCharsetMask) {
		_hasMask = true;
		_textScreenID = vs->number;
	}

	if (
#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
		(_vm->_game.platform != Common::kPlatformFMTowns) &&
#endif
		(ignoreCharsetMask || !vs->hasTwoBuffers)) {
		dst = vs->getPixels(_left, drawTop);
		if (charPtr)
			drawBits1(*vs, dst, charPtr, drawTop, origWidth, origHeight, vs->bytesPerPixel);
		else if (_vm->_cjkFont)
			_vm->_cjkFont->drawChar(vs, chr, _left, drawTop, _color, _shadowColor);
	} else {
		dst = (byte *)_vm->_textSurface.getBasePtr(_left * _vm->_textSurfaceMultiplier, _top * _vm->_textSurfaceMultiplier);
		if (charPtr)
			drawBits1(_vm->_textSurface, dst, charPtr, drawTop, origWidth, origHeight, _vm->_textSurface.bytesPerPixel, (_vm->_textSurfaceMultiplier == 2 && !is2byte));
		else if (_vm->_cjkFont)
			_vm->_cjkFont->drawChar(_vm->_textSurface, chr, _left * _vm->_textSurfaceMultiplier, _top * _vm->_textSurfaceMultiplier, _color, _shadowColor);
		if (is2byte)
			origWidth /= _vm->_textSurfaceMultiplier;
	}

	if (_str.left > _left)
		_str.left = _left;

	_left += origWidth;

	if (_str.right < _left) {
		_str.right = _left;
		if (_shadowMode != kNoShadowMode)
			_str.right++;
	}

	if (_str.bottom < _top + height / _vm->_textSurfaceMultiplier)
		_str.bottom = _top + height / _vm->_textSurfaceMultiplier;
}