Beispiel #1
0
// This is "hacked" together, because its only used by debug command
void GfxPaint32::kernelDrawCel(GuiResourceId viewId, int16 loopNo, int16 celNo, uint16 leftPos, uint16 topPos, int16 priority, uint16 paletteNo, bool hiresMode, reg_t upscaledHiresHandle) {
	GfxView *view = _cache->getView(viewId);
	Common::Rect celRect(50, 50, 50, 50);
	Common::Rect translatedRect;
	celRect.bottom += view->getHeight(loopNo, celNo);
	celRect.right += view->getWidth(loopNo, celNo);
	view->draw(celRect, celRect, celRect, loopNo, celNo, 255, 0, false);
	_screen->copyRectToScreen(celRect);
}
Beispiel #2
0
void GfxCompare::kernelSetNowSeen(reg_t objectReference) {
	GfxView *view = NULL;
	Common::Rect celRect(0, 0);
	GuiResourceId viewId = (GuiResourceId)readSelectorValue(_segMan, objectReference, SELECTOR(view));
	int16 loopNo = readSelectorValue(_segMan, objectReference, SELECTOR(loop));
	int16 celNo = readSelectorValue(_segMan, objectReference, SELECTOR(cel));
	int16 x = (int16)readSelectorValue(_segMan, objectReference, SELECTOR(x));
	int16 y = (int16)readSelectorValue(_segMan, objectReference, SELECTOR(y));
	int16 z = 0;
	if (SELECTOR(z) > -1)
		z = (int16)readSelectorValue(_segMan, objectReference, SELECTOR(z));

	view = _cache->getView(viewId);
	view->getCelRect(loopNo, celNo, x, y, z, celRect);

	if (lookupSelector(_segMan, objectReference, SELECTOR(nsTop), NULL, NULL) == kSelectorVariable) {
		setNSRect(objectReference, celRect);
	}
}
Beispiel #3
0
void GfxCompare::kernelSetNowSeen(reg_t objectReference) {
	GfxView *view = NULL;
	Common::Rect celRect(0, 0);
	GuiResourceId viewId = (GuiResourceId)readSelectorValue(_segMan, objectReference, SELECTOR(view));

	// HACK: Ignore invalid views for now (perhaps unimplemented text views?)
	if (viewId == 0xFFFF)	// invalid view
		return;

	int16 loopNo = readSelectorValue(_segMan, objectReference, SELECTOR(loop));
	int16 celNo = readSelectorValue(_segMan, objectReference, SELECTOR(cel));
	int16 x = (int16)readSelectorValue(_segMan, objectReference, SELECTOR(x));
	int16 y = (int16)readSelectorValue(_segMan, objectReference, SELECTOR(y));
	int16 z = 0;
	if (SELECTOR(z) > -1)
		z = (int16)readSelectorValue(_segMan, objectReference, SELECTOR(z));

	view = _cache->getView(viewId);

#ifdef ENABLE_SCI32
	if (view->isSci2Hires())
		view->adjustToUpscaledCoordinates(y, x);
	else if (getSciVersion() == SCI_VERSION_2_1)
		_coordAdjuster->fromScriptToDisplay(y, x);
#endif

	view->getCelRect(loopNo, celNo, x, y, z, celRect);

#ifdef ENABLE_SCI32
	if (view->isSci2Hires()) {
		view->adjustBackUpscaledCoordinates(celRect.top, celRect.left);
		view->adjustBackUpscaledCoordinates(celRect.bottom, celRect.right);
	} else if (getSciVersion() == SCI_VERSION_2_1) {
		_coordAdjuster->fromDisplayToScript(celRect.top, celRect.left);
		_coordAdjuster->fromDisplayToScript(celRect.bottom, celRect.right);
	}
#endif

	if (lookupSelector(_segMan, objectReference, SELECTOR(nsTop), NULL, NULL) == kSelectorVariable) {
		setNSRect(objectReference, celRect);
	}
}
Beispiel #4
0
void ScreenItem::calcRects(const Plane &plane) {
	const int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
	const int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;
	const int16 screenWidth = g_sci->_gfxFrameout->getCurrentBuffer().screenWidth;
	const int16 screenHeight = g_sci->_gfxFrameout->getCurrentBuffer().screenHeight;

	const CelObj &celObj = getCelObj();

	Common::Rect celRect(celObj._width, celObj._height);
	if (_useInsetRect) {
		if (_insetRect.intersects(celRect)) {
			_insetRect.clip(celRect);
		} else {
			_insetRect = Common::Rect();
		}
	} else {
		_insetRect = celRect;
	}

	Ratio scaleX, scaleY;

	if (_scale.signal & kScaleSignalDoScaling32) {
		if (_scale.signal & kScaleSignalUseVanishingPoint) {
			int num = _scale.max * (_position.y - plane._vanishingPoint.y) / (scriptWidth - plane._vanishingPoint.y);
			scaleX = Ratio(num, 128);
			scaleY = Ratio(num, 128);
		} else {
			scaleX = Ratio(_scale.x, 128);
			scaleY = Ratio(_scale.y, 128);
		}
	}

	if (scaleX.getNumerator() && scaleY.getNumerator()) {
		_screenItemRect = _insetRect;

		const Ratio celToScreenX(screenWidth, celObj._scaledWidth);
		const Ratio celToScreenY(screenHeight, celObj._scaledHeight);

		// Cel may use a coordinate system that is not the same size as the
		// script coordinate system (usually this means high-resolution
		// pictures with low-resolution scripts)
		if (celObj._scaledWidth != kLowResX || celObj._scaledHeight != kLowResY) {
			// high resolution coordinates

			if (_useInsetRect) {
				const Ratio scriptToCelX(celObj._scaledWidth, scriptWidth);
				const Ratio scriptToCelY(celObj._scaledHeight, scriptHeight);
				mulru(_screenItemRect, scriptToCelX, scriptToCelY, 0);

				if (_screenItemRect.intersects(celRect)) {
					_screenItemRect.clip(celRect);
				} else {
					_screenItemRect = Common::Rect();
				}
			}

			int displaceX = celObj._displace.x;
			int displaceY = celObj._displace.y;

			if (_mirrorX != celObj._mirrorX && _celInfo.type != kCelTypePic) {
				displaceX = celObj._width - celObj._displace.x - 1;
			}

			if (!scaleX.isOne() || !scaleY.isOne()) {
				// Different games use a different cel scaling mode, but the
				// difference isn't consistent across SCI versions; instead,
				// it seems to be related to an update that happened during
				// SCI2.1mid where games started using hi-resolution game
				// scripts
				if (scriptWidth == kLowResX) {
					mulinc(_screenItemRect, scaleX, scaleY);
				} else {
					_screenItemRect.left = (_screenItemRect.left * scaleX).toInt();
					_screenItemRect.top = (_screenItemRect.top * scaleY).toInt();

					if (scaleX.getNumerator() > scaleX.getDenominator()) {
						_screenItemRect.right = (_screenItemRect.right * scaleX).toInt();
					} else {
						_screenItemRect.right = ((_screenItemRect.right - 1) * scaleX).toInt() + 1;
					}

					if (scaleY.getNumerator() > scaleY.getDenominator()) {
						_screenItemRect.bottom = (_screenItemRect.bottom * scaleY).toInt();
					} else {
						_screenItemRect.bottom = ((_screenItemRect.bottom - 1) * scaleY).toInt() + 1;
					}
				}

				displaceX = (displaceX * scaleX).toInt();
				displaceY = (displaceY * scaleY).toInt();
			}

			mulinc(_screenItemRect, celToScreenX, celToScreenY);
			displaceX = (displaceX * celToScreenX).toInt();
			displaceY = (displaceY * celToScreenY).toInt();

			const Ratio scriptToScreenX = Ratio(screenWidth, scriptWidth);
			const Ratio scriptToScreenY = Ratio(screenHeight, scriptHeight);

			if (/* TODO: dword_C6288 */ false && _celInfo.type == kCelTypePic) {
				_scaledPosition.x = _position.x;
				_scaledPosition.y = _position.y;
			} else {
				_scaledPosition.x = (_position.x * scriptToScreenX).toInt() - displaceX;
				_scaledPosition.y = (_position.y * scriptToScreenY).toInt() - displaceY;
			}

			_screenItemRect.translate(_scaledPosition.x, _scaledPosition.y);

			if (_mirrorX != celObj._mirrorX && _celInfo.type == kCelTypePic) {
				Common::Rect temp(_insetRect);

				if (!scaleX.isOne()) {
					mulinc(temp, scaleX, Ratio());
				}

				mulinc(temp, celToScreenX, Ratio());

				CelObjPic *celObjPic = dynamic_cast<CelObjPic *>(_celObj);
				if (celObjPic == nullptr) {
					error("Expected a CelObjPic");
				}
				temp.translate((celObjPic->_relativePosition.x * scriptToScreenX).toInt() - displaceX, 0);

				// TODO: This is weird.
				int deltaX = plane._planeRect.width() - temp.right - 1 - temp.left;

				_scaledPosition.x += deltaX;
				_screenItemRect.translate(deltaX, 0);
			}

			_scaledPosition.x += plane._planeRect.left;
			_scaledPosition.y += plane._planeRect.top;
			_screenItemRect.translate(plane._planeRect.left, plane._planeRect.top);

			_ratioX = scaleX * celToScreenX;
			_ratioY = scaleY * celToScreenY;
		} else {
			// low resolution coordinates

			int displaceX = celObj._displace.x;
			if (_mirrorX != celObj._mirrorX && _celInfo.type != kCelTypePic) {
				displaceX = celObj._width - celObj._displace.x - 1;
			}

			if (!scaleX.isOne() || !scaleY.isOne()) {
				mulinc(_screenItemRect, scaleX, scaleY);
				// TODO: This was in the original code, baked into the
				// multiplication though it is not immediately clear
				// why this is the only one that reduces the BR corner
				_screenItemRect.right -= 1;
				_screenItemRect.bottom -= 1;
			}

			_scaledPosition.x = _position.x - (displaceX * scaleX).toInt();
			_scaledPosition.y = _position.y - (celObj._displace.y * scaleY).toInt();
			_screenItemRect.translate(_scaledPosition.x, _scaledPosition.y);

			if (_mirrorX != celObj._mirrorX && _celInfo.type == kCelTypePic) {
				Common::Rect temp(_insetRect);

				if (!scaleX.isOne()) {
					mulinc(temp, scaleX, Ratio());
					temp.right -= 1;
				}

				CelObjPic *celObjPic = dynamic_cast<CelObjPic *>(_celObj);
				if (celObjPic == nullptr) {
					error("Expected a CelObjPic");
				}
				temp.translate(celObjPic->_relativePosition.x - (displaceX * scaleX).toInt(), celObjPic->_relativePosition.y - (celObj._displace.y * scaleY).toInt());

				// TODO: This is weird.
				int deltaX = plane._gameRect.width() - temp.right - 1 - temp.left;

				_scaledPosition.x += deltaX;
				_screenItemRect.translate(deltaX, 0);
			}

			_scaledPosition.x += plane._gameRect.left;
			_scaledPosition.y += plane._gameRect.top;
			_screenItemRect.translate(plane._gameRect.left, plane._gameRect.top);

			if (celObj._scaledWidth != screenWidth || celObj._scaledHeight != screenHeight) {
				mulru(_scaledPosition, celToScreenX, celToScreenY);
				mulru(_screenItemRect, celToScreenX, celToScreenY, 1);
			}

			_ratioX = scaleX * celToScreenX;
			_ratioY = scaleY * celToScreenY;
		}

		_screenRect = _screenItemRect;

		if (_screenRect.intersects(plane._screenRect)) {
			_screenRect.clip(plane._screenRect);
		} else {
			_screenRect.right = 0;
			_screenRect.bottom = 0;
			_screenRect.left = 0;
			_screenRect.top = 0;
		}

		if (!_fixedPriority) {
			_priority = _z + _position.y;
		}
	} else {
		_screenRect.left = 0;
		_screenRect.top = 0;
		_screenRect.right = 0;
		_screenRect.bottom = 0;
	}
}