Esempio n. 1
0
reg_t GfxText32::createFontBitmap(const CelInfo32 &celInfo, const Common::Rect &rect, const Common::String &text, const int16 foreColor, const int16 backColor, const GuiResourceId fontId, const int16 skipColor, const int16 borderColor, const bool dimmed, const bool gc) {
	_borderColor = borderColor;
	_text = text;
	_textRect = rect;
	_foreColor = foreColor;
	_dimmed = dimmed;

	setFont(fontId);

	int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
	int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;

	mulinc(_textRect, Ratio(_xResolution, scriptWidth), Ratio(_yResolution, scriptHeight));

	CelObjView view(celInfo.resourceId, celInfo.loopNo, celInfo.celNo);
	_skipColor = view._skipColor;
	_width = view._width * _xResolution / view._xResolution;
	_height = view._height * _yResolution / view._yResolution;

	Common::Rect bitmapRect(_width, _height);
	if (_textRect.intersects(bitmapRect)) {
		_textRect.clip(bitmapRect);
	} else {
		_textRect = Common::Rect();
	}

	SciBitmap &bitmap = *_segMan->allocateBitmap(&_bitmap, _width, _height, _skipColor, 0, 0, _xResolution, _yResolution, 0, false, gc);

	// NOTE: The engine filled the bitmap pixels with 11 here, which is silly
	// because then it just erased the bitmap using the skip color. So we don't
	// fill the bitmap redundantly here.

	_backColor = _skipColor;
	erase(bitmapRect, false);
	_backColor = backColor;

	view.draw(bitmap.getBuffer(), bitmapRect, Common::Point(0, 0), false, Ratio(_xResolution, view._xResolution), Ratio(_yResolution, view._yResolution));

	if (_backColor != skipColor && _foreColor != skipColor) {
		erase(_textRect, false);
	}

	if (text.size() > 0) {
		if (_foreColor == skipColor) {
			error("TODO: Implement transparent text");
		} else {
			if (borderColor != -1) {
				drawFrame(bitmapRect, 1, _borderColor, false);
			}

			drawTextBox();
		}
	}

	return _bitmap;
}
Esempio n. 2
0
reg_t GfxText32::createFontBitmap(int16 width, int16 height, const Common::Rect &rect, const Common::String &text, const uint8 foreColor, const uint8 backColor, const uint8 skipColor, const GuiResourceId fontId, const TextAlign alignment, const int16 borderColor, const bool dimmed, const bool doScaling, reg_t *outBitmapObject) {

	_field_22 = 0;
	_borderColor = borderColor;
	_text = text;
	_textRect = rect;
	_width = width;
	_height = height;
	_foreColor = foreColor;
	_backColor = backColor;
	_skipColor = skipColor;
	_alignment = alignment;
	_dimmed = dimmed;

	setFont(fontId);

	if (doScaling) {
		int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
		int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;

		Ratio scaleX(_scaledWidth, scriptWidth);
		Ratio scaleY(_scaledHeight, scriptHeight);

		_width = (_width * scaleX).toInt();
		_height = (_height * scaleY).toInt();
		mulinc(_textRect, scaleX, scaleY);
	}

	// _textRect represents where text is drawn inside the
	// bitmap; clipRect is the entire bitmap
	Common::Rect bitmapRect(_width, _height);

	if (_textRect.intersects(bitmapRect)) {
		_textRect.clip(bitmapRect);
	} else {
		_textRect = Common::Rect();
	}

	_bitmap = _segMan->allocateHunkEntry("FontBitmap()", _width * _height + BITMAP_HEADER_SIZE);

	byte *bitmap = _segMan->getHunkPointer(_bitmap);
	buildBitmapHeader(bitmap, _width, _height, _skipColor, 0, 0, _scaledWidth, _scaledHeight, 0, false);

	erase(bitmapRect, false);

	if (_borderColor > -1) {
		drawFrame(bitmapRect, 1, _borderColor, false);
	}

	drawTextBox();

	*outBitmapObject = _bitmap;
	return _bitmap;
}
Esempio n. 3
0
reg_t GfxText32::createFontBitmap(int16 width, int16 height, const Common::Rect &rect, const Common::String &text, const uint8 foreColor, const uint8 backColor, const uint8 skipColor, const GuiResourceId fontId, const TextAlign alignment, const int16 borderColor, const bool dimmed, const bool doScaling, const bool gc) {

	_borderColor = borderColor;
	_text = text;
	_textRect = rect;
	_width = width;
	_height = height;
	_foreColor = foreColor;
	_backColor = backColor;
	_skipColor = skipColor;
	_alignment = alignment;
	_dimmed = dimmed;

	setFont(fontId);

	if (doScaling) {
		int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
		int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;

		Ratio scaleX(_xResolution, scriptWidth);
		Ratio scaleY(_yResolution, scriptHeight);

		_width = (_width * scaleX).toInt();
		_height = (_height * scaleY).toInt();
		mulinc(_textRect, scaleX, scaleY);
	}

	// _textRect represents where text is drawn inside the
	// bitmap; clipRect is the entire bitmap
	Common::Rect bitmapRect(_width, _height);

	if (_textRect.intersects(bitmapRect)) {
		_textRect.clip(bitmapRect);
	} else {
		_textRect = Common::Rect();
	}

	_segMan->allocateBitmap(&_bitmap, _width, _height, _skipColor, 0, 0, _xResolution, _yResolution, 0, false, gc);

	erase(bitmapRect, false);

	if (_borderColor > -1) {
		drawFrame(bitmapRect, 1, _borderColor, false);
	}

	drawTextBox();
	return _bitmap;
}
Esempio n. 4
0
ScrollWindow::ScrollWindow(SegManager *segMan, const Common::Rect &gameRect, const Common::Point &position, const reg_t plane, const uint8 defaultForeColor, const uint8 defaultBackColor, const GuiResourceId defaultFontId, const TextAlign defaultAlignment, const int16 defaultBorderColor, const uint16 maxNumEntries) :
	_segMan(segMan),
	_gfxText32(segMan, g_sci->_gfxCache),
	_maxNumEntries(maxNumEntries),
	_firstVisibleChar(0),
	_topVisibleLine(0),
	_lastVisibleChar(0),
	_bottomVisibleLine(0),
	_numLines(0),
	_numVisibleLines(0),
	_plane(plane),
	_foreColor(defaultForeColor),
	_backColor(defaultBackColor),
	_borderColor(defaultBorderColor),
	_fontId(defaultFontId),
	_alignment(defaultAlignment),
	_visible(false),
	_position(position),
	_screenItem(nullptr),
	_nextEntryId(1) {

	_entries.reserve(maxNumEntries);

	_gfxText32.setFont(_fontId);
	_pointSize = _gfxText32._font->getHeight();

	const uint16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
	const uint16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;

	Common::Rect bitmapRect(gameRect);
	mulinc(bitmapRect, Ratio(_gfxText32._scaledWidth, scriptWidth), Ratio(_gfxText32._scaledHeight, scriptHeight));

	_textRect.left = 2;
	_textRect.top = 2;
	_textRect.right = bitmapRect.width() - 2;
	_textRect.bottom = bitmapRect.height() - 2;

	uint8 skipColor = 0;
	while (skipColor == _foreColor || skipColor == _backColor) {
		skipColor++;
	}

	assert(bitmapRect.width() > 0 && bitmapRect.height() > 0);
	_bitmap = _gfxText32.createFontBitmap(bitmapRect.width(), bitmapRect.height(), _textRect, "", _foreColor, _backColor, skipColor, _fontId, _alignment, _borderColor, false, false, false);

	debugC(1, kDebugLevelGraphics, "New ScrollWindow: textRect size: %d x %d, bitmap: %04x:%04x", _textRect.width(), _textRect.height(), PRINT_REG(_bitmap));
}
Esempio n. 5
0
int16 GfxText32::getTextCount(const Common::String &text, const uint index, const Common::Rect &textRect, const bool doScaling) {
	const int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
	const int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;

	Common::Rect scaledRect(textRect);
	if (doScaling) {
		mulinc(scaledRect, Ratio(_xResolution, scriptWidth), Ratio(_yResolution, scriptHeight));
	}

	Common::String oldText = _text;
	_text = text;

	uint charIndex = index;
	int16 maxWidth = scaledRect.width();
	int16 lineCount = (scaledRect.height() - 2) / _font->getHeight();
	while (lineCount--) {
		getLongest(&charIndex, maxWidth);
	}

	_text = oldText;
	return charIndex - index;
}
Esempio n. 6
0
Common::Rect ScreenItem::getNowSeenRect(const Plane &plane) const {
	CelObj &celObj = getCelObj();

	Common::Rect celObjRect(celObj._width, celObj._height);
	Common::Rect nsRect;

	if (_useInsetRect) {
		if (_insetRect.intersects(celObjRect)) {
			nsRect = _insetRect;
			nsRect.clip(celObjRect);
		} else {
			nsRect = Common::Rect();
		}
	} else {
		nsRect = celObjRect;
	}

	const uint16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
	const uint16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;

	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() == 0 || scaleY.getNumerator() == 0) {
		return Common::Rect();
	}

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

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

	if (celObj._scaledWidth != kLowResX || celObj._scaledHeight != kLowResY) {
		// high resolution coordinates

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

			if (nsRect.intersects(celObjRect)) {
				nsRect.clip(celObjRect);
			} else {
				nsRect = Common::Rect();
			}
		}

		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(nsRect, 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
				nsRect.right -= 1;
				nsRect.bottom -= 1;
			} else {
				nsRect.left = (nsRect.left * scaleX).toInt();
				nsRect.top = (nsRect.top * scaleY).toInt();

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

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

		Ratio celToScriptX(scriptWidth, celObj._scaledWidth);
		Ratio celToScriptY(scriptHeight, celObj._scaledHeight);

		displaceX = (displaceX * scaleX * celToScriptX).toInt();
		displaceY = (displaceY * scaleY * celToScriptY).toInt();

		mulinc(nsRect, celToScriptX, celToScriptY);
		nsRect.translate(_position.x - displaceX, _position.y - displaceY);
	} else {
		// low resolution coordinates

		if (!scaleX.isOne() || !scaleY.isOne()) {
			mulinc(nsRect, 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
			nsRect.right -= 1;
			nsRect.bottom -= 1;
		}

		displaceX = (displaceX * scaleX).toInt();
		displaceY = (displaceY * scaleY).toInt();
		nsRect.translate(_position.x - displaceX, _position.y - displaceY);

		if (_mirrorX != celObj._mirrorX && _celInfo.type != kCelTypePic) {
			nsRect.translate(plane._gameRect.width() - nsRect.width(), 0);
		}
	}

	return nsRect;
}
Esempio n. 7
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;
	}
}
Esempio n. 8
0
reg_t GfxText32::createFontBitmap(const CelInfo32 &celInfo, const Common::Rect &rect, const Common::String &text, const int16 foreColor, const int16 backColor, const GuiResourceId fontId, const int16 skipColor, const int16 borderColor, const bool dimmed, reg_t *outBitmapObject) {
	_field_22 = 0;
	_borderColor = borderColor;
	_text = text;
	_textRect = rect;
	_foreColor = foreColor;
	_dimmed = dimmed;

	setFont(fontId);

	int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
	int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;

	int borderSize = 1;
	mulinc(_textRect, Ratio(_scaledWidth, scriptWidth), Ratio(_scaledHeight, scriptHeight));

	CelObjView view(celInfo.resourceId, celInfo.loopNo, celInfo.celNo);
	_skipColor = view._transparentColor;
	_width = view._width * _scaledWidth / view._scaledWidth;
	_height = view._height * _scaledHeight / view._scaledHeight;

	Common::Rect bitmapRect(_width, _height);
	if (_textRect.intersects(bitmapRect)) {
		_textRect.clip(bitmapRect);
	} else {
		_textRect = Common::Rect();
	}

	_bitmap = _segMan->allocateHunkEntry("FontBitmap()", _width * _height + CelObjMem::getBitmapHeaderSize());
	byte *bitmap = _segMan->getHunkPointer(_bitmap);
	CelObjMem::buildBitmapHeader(bitmap, _width, _height, _skipColor, 0, 0, _scaledWidth, _scaledHeight, 0, false);

	Buffer buffer(_width, _height, bitmap + READ_SCI11ENDIAN_UINT32(bitmap + 28));

	// NOTE: The engine filled the bitmap pixels with 11 here, which is silly
	// because then it just erased the bitmap using the skip color. So we don't
	// fill the bitmap redundantly here.

	_backColor = _skipColor;
	erase(bitmapRect, false);
	_backColor = backColor;

	view.draw(buffer, bitmapRect, Common::Point(0, 0), false, Ratio(_scaledWidth, view._scaledWidth), Ratio(_scaledHeight, view._scaledHeight));

	if (_backColor != skipColor && _foreColor != skipColor) {
		erase(_textRect, false);
	}

	if (text.size() > 0) {
		if (_foreColor == skipColor) {
			error("TODO: Implement transparent text");
		} else {
			if (borderColor != -1) {
				drawFrame(bitmapRect, borderSize, _borderColor, false);
			}

			drawTextBox();
		}
	}

	*outBitmapObject = _bitmap;
	return _bitmap;
}