示例#1
0
void ThemeEngine::addDirtyRect(Common::Rect r) {
	// Clip the rect to screen coords
	r.clip(_screen.w, _screen.h);

	// If it is empty after clipping, we are done
	if (r.isEmpty())
		return;

	// Check if the new rectangle is contained within another in the list
	Common::List<Common::Rect>::iterator it;
	for (it = _dirtyScreen.begin(); it != _dirtyScreen.end();) {
		// If we find a rectangle which fully contains the new one,
		// we can abort the search.
		if (it->contains(r))
			return;

		// Conversely, if we find rectangles which are contained in
		// the new one, we can remove them
		if (r.contains(*it))
			it = _dirtyScreen.erase(it);
		else
			++it;
	}

	// If we got here, we can safely add r to the list of dirty rects.
	_dirtyScreen.push_back(r);
}
示例#2
0
void Surface::fillRect(Common::Rect r, uint32 color) {
	r.clip(w, h);

	if (!r.isValidRect())
		return;

	int width = r.width();
	int height = r.height();
//	int i;

	if (bytesPerPixel == 1) {
		byte *ptr = (byte *)getBasePtr(r.left, r.top);
		while (height--) {
			memset(ptr, (byte)color, width);
			ptr += pitch;
		}
	} else if (bytesPerPixel == 2) {
		uint16 *ptr = (uint16 *)getBasePtr(r.left, r.top);
		while (height--) {
			Common::set_to(ptr, ptr + width, (uint16)color);
			ptr += pitch/2;
		}
	} else {
		error("Surface::fillRect: bytesPerPixel must be 1 or 2");
	}
}
示例#3
0
void Render::addDirtyRect(Common::Rect r) {
	if (_fullRefresh)
		return;

	// Clip rectangle
	r.clip(_backGroundSurface.w, _backGroundSurface.h);

	// If it is empty after clipping, we are done
	if (r.isEmpty())
		return;

	// Check if the new rectangle is contained within another in the list
	Common::List<Common::Rect>::iterator it;
	for (it = _dirtyRects.begin(); it != _dirtyRects.end(); ) {
		// If we find a rectangle which fully contains the new one,
		// we can abort the search.
		if (it->contains(r))
			return;

		// Conversely, if we find rectangles which are contained in
		// the new one, we can remove them
		if (r.contains(*it))
			it = _dirtyRects.erase(it);
		else
			++it;
	}

	// If we got here, we can safely add r to the list of dirty rects.
	if (_vm->_interface->getFadeMode() != kFadeOut)
		_dirtyRects.push_back(r);
}
示例#4
0
Common::Rect PaintControl::paint(const Common::Point &point) {
    Common::Rect paintRect = Common::Rect(_brush->w, _brush->h);
    paintRect.moveTo(point);
    paintRect.clip(_rectangle);

    if (!paintRect.isEmpty()) {
        Common::Rect brushRect = paintRect;
        brushRect.translate(-point.x, -point.y);

        Common::Rect bkgRect = paintRect;
        bkgRect.translate(-_rectangle.left, -_rectangle.top);

        for (int yy = 0; yy < brushRect.height(); yy++) {
            uint16 *mask = (uint16 *)_brush->getBasePtr(brushRect.left, brushRect.top + yy);
            uint16 *from = (uint16 *)_paint->getBasePtr(bkgRect.left, bkgRect.top + yy);
            uint16 *to   = (uint16 *)_bkg->getBasePtr(bkgRect.left, bkgRect.top + yy);
            for (int xx = 0; xx < brushRect.width(); xx++) {
                if (*mask != 0)
                    *(to + xx) = *(from + xx);

                mask++;
            }
        }

    }
    return paintRect;
}
示例#5
0
void MicroTileArray::addRect(Common::Rect r) {

	int ux0, uy0, ux1, uy1;
	int tx0, ty0, tx1, ty1;
	int ix0, iy0, ix1, iy1;

	r.clip(Common::Rect(0, 0, 799, 599));

	ux0 = r.left / TileSize;
	uy0 = r.top / TileSize;
	ux1 = r.right / TileSize;
	uy1 = r.bottom / TileSize;

	tx0 = r.left % TileSize;
	ty0 = r.top % TileSize;
	tx1 = r.right % TileSize;
	ty1 = r.bottom % TileSize;

	for (int yc = uy0; yc <= uy1; yc++) {
		for (int xc = ux0; xc <= ux1; xc++) {
			ix0 = (xc == ux0) ? tx0 : 0;
			ix1 = (xc == ux1) ? tx1 : TileSize - 1;
			iy0 = (yc == uy0) ? ty0 : 0;
			iy1 = (yc == uy1) ? ty1 : TileSize - 1;
			updateBoundingBox(_tiles[xc + yc * _tilesW], ix0, iy0, ix1, iy1);
		}
	}

}
示例#6
0
void GfxPaint16::fillRect(const Common::Rect &rect, int16 drawFlags, byte color, byte priority, byte control) {
	Common::Rect r = rect;
	r.clip(_ports->_curPort->rect);
	if (r.isEmpty()) // nothing to fill
		return;

	int16 oldPenMode = _ports->_curPort->penMode;
	_ports->offsetRect(r);
	int16 x, y;
	byte curVisual;

	// Doing visual first
	if (drawFlags & GFX_SCREEN_MASK_VISUAL) {
		if (oldPenMode == 2) { // invert mode
			for (y = r.top; y < r.bottom; y++) {
				for (x = r.left; x < r.right; x++) {
					curVisual = _screen->getVisual(x, y);
					if (curVisual == color) {
						_screen->putPixel(x, y, GFX_SCREEN_MASK_VISUAL, priority, 0, 0);
					} else if (curVisual == priority) {
						_screen->putPixel(x, y, GFX_SCREEN_MASK_VISUAL, color, 0, 0);
					}
				}
			}
		} else { // just fill rect with color
			for (y = r.top; y < r.bottom; y++) {
				for (x = r.left; x < r.right; x++) {
//20140521
			//		if(y >= 0)															
						_screen->putPixel(x, y, GFX_SCREEN_MASK_VISUAL, color, 0, 0);
				}
			}
		}
	}

	if (drawFlags < 2)
		return;
	drawFlags &= GFX_SCREEN_MASK_PRIORITY|GFX_SCREEN_MASK_CONTROL;

	// we need to isolate the bits, sierra sci saved priority and control inside one byte, we don't
	priority &= 0x0f;
	control &= 0x0f;

	if (oldPenMode != 2) {
		for (y = r.top; y < r.bottom; y++) {
			for (x = r.left; x < r.right; x++) {
				_screen->putPixel(x, y, drawFlags, 0, priority, control);
			}
		}
	} else {
		for (y = r.top; y < r.bottom; y++) {
			for (x = r.left; x < r.right; x++) {
				_screen->putPixel(x, y, drawFlags, 0, !_screen->getPriority(x, y), !_screen->getControl(x, y));
			}
		}
	}
}
示例#7
0
uint16 RobotDecoder::getFrameSize(Common::Rect &outRect) const {
	outRect.clip(0, 0);
	for (RobotScreenItemList::size_type i = 0; i < _screenItemList.size(); ++i) {
		ScreenItem &screenItem = *_screenItemList[i];
		outRect.extend(screenItem.getNowSeenRect(*_plane));
	}

	return _numFramesTotal;
}
示例#8
0
void TattooMap::restoreArea(const Common::Rect &bounds) {
	Screen &screen = *_vm->_screen;

	Common::Rect r = bounds;
	r.clip(Common::Rect(0, 0, screen._backBuffer1.w(), screen._backBuffer1.h()));

	if (!r.isEmpty())
		screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(r.left, r.top), r);
}
示例#9
0
void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Common::Rect &_srcRect , Graphics::Surface &dst, int _x, int _y) {
	Common::Rect srcRect = _srcRect;
	if (srcRect.isEmpty())
		srcRect = Common::Rect(src.w, src.h);
	srcRect.clip(src.w, src.h);
	Common::Rect dstRect = Common::Rect(-_x + srcRect.left , -_y + srcRect.top, -_x + srcRect.left + dst.w, -_y + srcRect.top + dst.h);
	srcRect.clip(dstRect);

	if (srcRect.isEmpty() || !srcRect.isValidRect())
		return;

	Graphics::Surface *srcAdapted = src.convertTo(dst.format);

	// Copy srcRect from src surface to dst surface
	const byte *srcBuffer = (const byte *)srcAdapted->getBasePtr(srcRect.left, srcRect.top);

	int xx = _x;
	int yy = _y;

	if (xx < 0)
		xx = 0;
	if (yy < 0)
		yy = 0;

	if (_x >= dst.w || _y >= dst.h) {
		srcAdapted->free();
		delete srcAdapted;
		return;
	}

	byte *dstBuffer = (byte *)dst.getBasePtr(xx, yy);

	int32 w = srcRect.width();
	int32 h = srcRect.height();

	for (int32 y = 0; y < h; y++) {
		memcpy(dstBuffer, srcBuffer, w * srcAdapted->format.bytesPerPixel);
		srcBuffer += srcAdapted->pitch;
		dstBuffer += dst.pitch;
	}

	srcAdapted->free();
	delete srcAdapted;
}
示例#10
0
bool RenderManager::clipRectToWorkingWindow(Common::Rect &rect) {
	if (!_workingWindow.contains(rect)) {
		return false;
	}

	// We can't clip against the actual working window rect because it's in screen space
	// But rect is in working window space
	rect.clip(_workingWidth, _workingHeight);
	return true;
}
示例#11
0
void CSTimeGraphics::drawRect(Common::Rect rect, byte color) {
	rect.clip(Common::Rect(640, 480));

	// Useful with debugging. Shows where hotspots are on the screen and whether or not they're active.
	if (!rect.isValidRect() || rect.width() == 0 || rect.height() == 0)
		return;

	Graphics::Surface *screen = _vm->_system->lockScreen();

	screen->frameRect(rect, color);

	_vm->_system->unlockScreen();
}
示例#12
0
// This version of drawCel is not supposed to call BitsShow()!
void GfxPaint16::drawCel(GfxView *view, int16 loopNo, int16 celNo, const Common::Rect &celRect, byte priority, uint16 paletteNo, uint16 scaleX, uint16 scaleY) {
	Common::Rect clipRect = celRect;
	clipRect.clip(_ports->_curPort->rect);
	if (clipRect.isEmpty()) // nothing to draw
		return;

	Common::Rect clipRectTranslated = clipRect;
	_ports->offsetRect(clipRectTranslated);
	if (scaleX == 128 && scaleY == 128)
		view->draw(celRect, clipRect, clipRectTranslated, loopNo, celNo, priority, paletteNo, false);
	else
		view->drawScaled(celRect, clipRect, clipRectTranslated, loopNo, celNo, priority, scaleX, scaleY);
}
示例#13
0
void ThemeEngine::drawChar(const Common::Rect &r, byte ch, const Graphics::Font *font, WidgetStateInfo state, FontColor color) {
	if (!ready())
		return;

	Common::Rect charArea = r;
	charArea.clip(_screen.w, _screen.h);

	uint32 rgbColor = _overlayFormat.RGBToColor(_textColors[color]->r, _textColors[color]->g, _textColors[color]->b);

	restoreBackground(charArea);
	font->drawChar(&_screen, ch, charArea.left, charArea.top, rgbColor);
	addDirtyRect(charArea);
}
示例#14
0
Graphics::Surface *RenderManager::getBkgRect(Common::Rect &rect) {
	Common::Rect dst = rect;
	dst.clip(_backgroundWidth, _backgroundHeight);

	if (dst.isEmpty() || !dst.isValidRect())
		return NULL;

	Graphics::Surface *srf = new Graphics::Surface;
	srf->create(dst.width(), dst.height(), _currentBackgroundImage.format);

	srf->copyRectToSurface(_currentBackgroundImage, 0, 0, Common::Rect(dst));

	return srf;
}
示例#15
0
void ThemeEngine::queueBitmap(const Graphics::Surface *bitmap, const Common::Rect &r, bool alpha) {

	Common::Rect area = r;
	area.clip(_screen.w, _screen.h);

	ThemeItemBitmap *q = new ThemeItemBitmap(this, area, bitmap, alpha);

	if (_buffering) {
		_bufferQueue.push_back(q);
	} else {
		q->drawSelf(true, false);
		delete q;
	}
}
示例#16
0
// used in SCI0early exclusively
void GfxPaint16::invertRectViaXOR(const Common::Rect &rect) {
	Common::Rect r = rect;
	int16 x, y;
	byte curVisual;

	r.clip(_ports->_curPort->rect);
	if (r.isEmpty()) // nothing to invert
		return;

	_ports->offsetRect(r);
	for (y = r.top; y < r.bottom; y++) {
		for (x = r.left; x < r.right; x++) {
			curVisual = _screen->getVisual(x, y);
			_screen->putPixel(x, y, GFX_SCREEN_MASK_VISUAL, curVisual ^ 0x0f, 0, 0);
		}
	}
}
示例#17
0
void ThemeEngine::queueDDText(TextData type, TextColor color, const Common::Rect &r, const Common::String &text, bool restoreBg,
                              bool ellipsis, Graphics::TextAlign alignH, TextAlignVertical alignV, int deltax) {

	if (_texts[type] == 0)
		return;

	Common::Rect area = r;
	area.clip(_screen.w, _screen.h);

	ThemeItemTextData *q = new ThemeItemTextData(this, _texts[type], _textColors[color], area, text, alignH, alignV, ellipsis, restoreBg, deltax);

	if (_buffering) {
		_screenQueue.push_back(q);
	} else {
		q->drawSelf(true, false);
		delete q;
	}
}
示例#18
0
void Surface::fillRect(Common::Rect r, uint32 color) {
	r.clip(w, h);

	if (!r.isValidRect())
		return;

	int width = r.width();
	int lineLen = width;
	int height = r.height();
	bool useMemset = true;

	if (format.bytesPerPixel == 2) {
		lineLen *= 2;
		if ((uint16)color != ((color & 0xff) | (color & 0xff) << 8))
			useMemset = false;
	} else if (format.bytesPerPixel == 4) {
		useMemset = false;
	} else if (format.bytesPerPixel != 1) {
		error("Surface::fillRect: bytesPerPixel must be 1, 2, or 4");
	}

	if (useMemset) {
		byte *ptr = (byte *)getBasePtr(r.left, r.top);
		while (height--) {
			memset(ptr, (byte)color, lineLen);
			ptr += pitch;
		}
	} else {
		if (format.bytesPerPixel == 2) {
			uint16 *ptr = (uint16 *)getBasePtr(r.left, r.top);
			while (height--) {
				Common::set_to(ptr, ptr + width, (uint16)color);
				ptr += pitch / 2;
			}
		} else {
			uint32 *ptr = (uint32 *)getBasePtr(r.left, r.top);
			while (height--) {
				Common::set_to(ptr, ptr + width, color);
				ptr += pitch / 4;
			}
		}
	}
}
示例#19
0
// Pixelates the new picture over the old one - works against the whole screen.
// TODO: it seems this needs to get applied on _picRect only if possible
void GfxTransitions::pixelation(bool blackoutFlag) {
	uint16 mask = 0x40, stepNr = 0;
	Common::Rect pixelRect;
	uint32 msecCount = 0;

	do {
		mask = (mask & 1) ? (mask >> 1) ^ 0xB400 : mask >> 1;
		if (mask >= _screen->getWidth() * _screen->getHeight())
			continue;
		pixelRect.left = mask % _screen->getWidth(); pixelRect.right = pixelRect.left + 1;
		pixelRect.top = mask / _screen->getWidth();	pixelRect.bottom = pixelRect.top + 1;
		pixelRect.clip(_picRect);
		if (!pixelRect.isEmpty())
			copyRectToScreen(pixelRect, blackoutFlag);
		if ((stepNr & 0x3FF) == 0) {
			msecCount += 9;
			updateScreenAndWait(msecCount);
		}
		stepNr++;
	} while (mask != 0x40);
}
示例#20
0
/**
 * @brief Marks a dirty rectangle on the surface
 * @param r The rectangle to be marked dirty
 */
void Surface::markDirtyRect(Common::Rect r) {
	Common::List<Common::Rect>::iterator it;

	r.clip(w, h);

	if (r.isEmpty())
		return;

	it = _dirtyRects.begin();
	while (it != _dirtyRects.end()) {
		if (it->contains(r))
			return;

		if (r.contains(*it))
			it = _dirtyRects.erase(it);
		else
			++it;
	}

	_dirtyRects.push_back(r);
}
示例#21
0
// Like pixelation but uses 8x8 blocks - works against the whole screen.
// TODO: it seems this needs to get applied on _picRect only if possible
void GfxTransitions::blocks(bool blackoutFlag) {
	uint16 mask = 0x40, stepNr = 0;
	Common::Rect blockRect;
	uint32 msecCount = 0;

	do {
		mask = (mask & 1) ? (mask >> 1) ^ 0x240 : mask >> 1;
		if (mask >= 40 * 25)
			continue;
		blockRect.left = (mask % 40) << 3; blockRect.right = blockRect.left + 8;
		blockRect.top = (mask / 40) << 3; blockRect.bottom = blockRect.top + 8;
		blockRect.clip(_picRect);
		if (!blockRect.isEmpty())
			copyRectToScreen(blockRect, blackoutFlag);
		if ((stepNr & 7) == 0) {
			msecCount += 5;
			updateScreenAndWait(msecCount);
		}
		stepNr++;
	} while (mask != 0x40);
}
示例#22
0
void GfxAnimate::updateScreen(byte oldPicNotValid) {
	AnimateList::iterator it;
	const AnimateList::iterator end = _list.end();
	Common::Rect lsRect;
	Common::Rect workerRect;

	for (it = _list.begin(); it != end; ++it) {
		if (it->showBitsFlag || !(it->signal & (kSignalRemoveView | kSignalNoUpdate) ||
										(!(it->signal & kSignalRemoveView) && (it->signal & kSignalNoUpdate) && oldPicNotValid))) {
			lsRect.left = readSelectorValue(_s->_segMan, it->object, SELECTOR(lsLeft));
			lsRect.top = readSelectorValue(_s->_segMan, it->object, SELECTOR(lsTop));
			lsRect.right = readSelectorValue(_s->_segMan, it->object, SELECTOR(lsRight));
			lsRect.bottom = readSelectorValue(_s->_segMan, it->object, SELECTOR(lsBottom));

			workerRect = lsRect;
			workerRect.clip(it->celRect);

			if (!workerRect.isEmpty()) {
				workerRect = lsRect;
				workerRect.extend(it->celRect);
			} else {
				_paint16->bitsShow(lsRect);
				workerRect = it->celRect;
			}
			writeSelectorValue(_s->_segMan, it->object, SELECTOR(lsLeft), it->celRect.left);
			writeSelectorValue(_s->_segMan, it->object, SELECTOR(lsTop), it->celRect.top);
			writeSelectorValue(_s->_segMan, it->object, SELECTOR(lsRight), it->celRect.right);
			writeSelectorValue(_s->_segMan, it->object, SELECTOR(lsBottom), it->celRect.bottom);
			// may get used for debugging
			//_paint16->frameRect(workerRect);
			_paint16->bitsShow(workerRect);

			if (it->signal & kSignalHidden)
				it->signal |= kSignalRemoveView;
		}
	}
	// use this for debug purposes
	// _screen->copyToScreen();
}
示例#23
0
void GfxFrameout::kernelDeletePlane(reg_t object) {
	deletePlanePictures(object);
	for (PlaneList::iterator it = _planes.begin(); it != _planes.end(); it++) {
		if (it->object == object) {
			_planes.erase(it);
			Common::Rect planeRect;
			planeRect.top = readSelectorValue(_segMan, object, SELECTOR(top));
			planeRect.left = readSelectorValue(_segMan, object, SELECTOR(left));
			planeRect.bottom = readSelectorValue(_segMan, object, SELECTOR(bottom)) + 1;
			planeRect.right = readSelectorValue(_segMan, object, SELECTOR(right)) + 1;

			Common::Rect screenRect(_screen->getWidth(), _screen->getHeight());
			planeRect.top = (planeRect.top * screenRect.height()) / scriptsRunningHeight;
			planeRect.left = (planeRect.left * screenRect.width()) / scriptsRunningWidth;
			planeRect.bottom = (planeRect.bottom * screenRect.height()) / scriptsRunningHeight;
			planeRect.right = (planeRect.right * screenRect.width()) / scriptsRunningWidth;
			planeRect.clip(screenRect); // we need to do this, at least in gk1 on cemetary we get bottom right -> 201, 321
			// Blackout removed plane rect
			_paint32->fillRect(planeRect, 0);
			return;
		}
	}
}
示例#24
0
/**********************************************************
 * Drawing Queue management
 *********************************************************/
void ThemeEngine::queueDD(DrawData type, const Common::Rect &r, uint32 dynamic, bool restore) {
	if (_widgets[type] == 0)
		return;

	Common::Rect area = r;
	area.clip(_screen.w, _screen.h);

	ThemeItemDrawData *q = new ThemeItemDrawData(this, _widgets[type], area, dynamic);

	if (_buffering) {
		if (_widgets[type]->_buffer) {
			_bufferQueue.push_back(q);
		} else {
			if (kDrawDataDefaults[type].parent != kDDNone && kDrawDataDefaults[type].parent != type)
				queueDD(kDrawDataDefaults[type].parent, r);

			_screenQueue.push_back(q);
		}
	} else {
		q->drawSelf(!_widgets[type]->_buffer, restore || _widgets[type]->_buffer);
		delete q;
	}
}
示例#25
0
void RenderManager::blitSurfaceToSurface(const Graphics::Surface &src, const Common::Rect &_srcRect , Graphics::Surface &dst, int _x, int _y, uint32 colorkey) {
	Common::Rect srcRect = _srcRect;
	if (srcRect.isEmpty())
		srcRect = Common::Rect(src.w, src.h);
	srcRect.clip(src.w, src.h);
	Common::Rect dstRect = Common::Rect(-_x + srcRect.left , -_y + srcRect.top, -_x + srcRect.left + dst.w, -_y + srcRect.top + dst.h);
	srcRect.clip(dstRect);

	if (srcRect.isEmpty() || !srcRect.isValidRect())
		return;

	Graphics::Surface *srcAdapted = src.convertTo(dst.format);
	uint32 keycolor = colorkey & ((1 << (src.format.bytesPerPixel << 3)) - 1);

	// Copy srcRect from src surface to dst surface
	const byte *srcBuffer = (const byte *)srcAdapted->getBasePtr(srcRect.left, srcRect.top);

	int xx = _x;
	int yy = _y;

	if (xx < 0)
		xx = 0;
	if (yy < 0)
		yy = 0;

	if (_x >= dst.w || _y >= dst.h) {
		srcAdapted->free();
		delete srcAdapted;
		return;
	}

	byte *dstBuffer = (byte *)dst.getBasePtr(xx, yy);

	int32 w = srcRect.width();
	int32 h = srcRect.height();

	for (int32 y = 0; y < h; y++) {
		switch (srcAdapted->format.bytesPerPixel) {
		case 1: {
			const uint *srcTemp = (const uint *)srcBuffer;
			uint *dstTemp = (uint *)dstBuffer;
			for (int32 x = 0; x < w; x++) {
				if (*srcTemp != keycolor)
					*dstTemp = *srcTemp;
				srcTemp++;
				dstTemp++;
			}
		}
		break;

		case 2: {
			const uint16 *srcTemp = (const uint16 *)srcBuffer;
			uint16 *dstTemp = (uint16 *)dstBuffer;
			for (int32 x = 0; x < w; x++) {
				if (*srcTemp != keycolor)
					*dstTemp = *srcTemp;
				srcTemp++;
				dstTemp++;
			}
		}
		break;

		case 4: {
			const uint32 *srcTemp = (const uint32 *)srcBuffer;
			uint32 *dstTemp = (uint32 *)dstBuffer;
			for (int32 x = 0; x < w; x++) {
				if (*srcTemp != keycolor)
					*dstTemp = *srcTemp;
				srcTemp++;
				dstTemp++;
			}
		}
		break;

		default:
			break;
		}
		srcBuffer += srcAdapted->pitch;
		dstBuffer += dst.pitch;
	}

	srcAdapted->free();
	delete srcAdapted;
}
示例#26
0
void ThemeEngine::restoreBackground(Common::Rect r) {
	r.clip(_screen.w, _screen.h);
	_vectorRenderer->blitSurface(&_backBuffer, r);
}
示例#27
0
void RenderManager::prepareBackground() {
	_backgroundDirtyRect.clip(_backgroundWidth, _backgroundHeight);
	RenderTable::RenderState state = _renderTable.getRenderState();

	if (state == RenderTable::PANORAMA) {
		// Calculate the visible portion of the background
		Common::Rect viewPort(_workingWidth, _workingHeight);
		viewPort.translate(-(_screenCenterX - _backgroundOffset), 0);
		Common::Rect drawRect = _backgroundDirtyRect;
		drawRect.clip(viewPort);

		// Render the visible portion
		if (!drawRect.isEmpty()) {
			blitSurfaceToSurface(_currentBackgroundImage, drawRect, _backgroundSurface, _screenCenterX - _backgroundOffset + drawRect.left, drawRect.top);
		}

		// Mark the dirty portion of the surface
		_backgroundSurfaceDirtyRect = _backgroundDirtyRect;
		_backgroundSurfaceDirtyRect.translate(_screenCenterX - _backgroundOffset, 0);

		// Panorama mode allows the user to spin in circles. Therefore, we need to render 
		// the portion of the image that wrapped to the other side of the screen
		if (_backgroundOffset < _screenCenterX) {
			viewPort.moveTo(-(_screenCenterX - (_backgroundOffset + _backgroundWidth)), 0);
			drawRect = _backgroundDirtyRect;
			drawRect.clip(viewPort);

			if (!drawRect.isEmpty())
				blitSurfaceToSurface(_currentBackgroundImage, drawRect, _backgroundSurface, _screenCenterX - (_backgroundOffset + _backgroundWidth) + drawRect.left, drawRect.top);

			Common::Rect tmp = _backgroundDirtyRect;
			tmp.translate(_screenCenterX - (_backgroundOffset + _backgroundWidth), 0);
			if (!tmp.isEmpty())
				_backgroundSurfaceDirtyRect.extend(tmp);

		} else if (_backgroundWidth - _backgroundOffset < _screenCenterX) {
			viewPort.moveTo(-(_screenCenterX + _backgroundWidth - _backgroundOffset), 0);
			drawRect = _backgroundDirtyRect;
			drawRect.clip(viewPort);

			if (!drawRect.isEmpty())
				blitSurfaceToSurface(_currentBackgroundImage, drawRect, _backgroundSurface, _screenCenterX + _backgroundWidth - _backgroundOffset + drawRect.left, drawRect.top);

			Common::Rect tmp = _backgroundDirtyRect;
			tmp.translate(_screenCenterX + _backgroundWidth - _backgroundOffset, 0);
			if (!tmp.isEmpty())
				_backgroundSurfaceDirtyRect.extend(tmp);

		}
	} else if (state == RenderTable::TILT) {
		// Tilt doesn't allow wrapping, so we just do a simple clip
		Common::Rect viewPort(_workingWidth, _workingHeight);
		viewPort.translate(0, -(_screenCenterY - _backgroundOffset));
		Common::Rect drawRect = _backgroundDirtyRect;
		drawRect.clip(viewPort);
		if (!drawRect.isEmpty())
			blitSurfaceToSurface(_currentBackgroundImage, drawRect, _backgroundSurface, drawRect.left, _screenCenterY - _backgroundOffset + drawRect.top);

		// Mark the dirty portion of the surface
		_backgroundSurfaceDirtyRect = _backgroundDirtyRect;
		_backgroundSurfaceDirtyRect.translate(0, _screenCenterY - _backgroundOffset);

	} else {
		if (!_backgroundDirtyRect.isEmpty())
			blitSurfaceToSurface(_currentBackgroundImage, _backgroundDirtyRect, _backgroundSurface, _backgroundDirtyRect.left, _backgroundDirtyRect.top);
		_backgroundSurfaceDirtyRect = _backgroundDirtyRect;
	}

	// Clear the dirty rect since everything is clean now
	_backgroundDirtyRect = Common::Rect();

	_backgroundSurfaceDirtyRect.clip(_workingWidth, _workingHeight);
}
示例#28
0
void RenderTicket::drawToSurface(Graphics::Surface *_targetSurface, Common::Rect *dstRect, Common::Rect *clipRect) const {
	TransparentSurface src(*getSurface(), false);
	bool doDelete = false;
	if (!clipRect) {
		doDelete = true;
		clipRect = new Common::Rect();
		clipRect->setWidth(getSurface()->w * _transform._numTimesX);
		clipRect->setHeight(getSurface()->h * _transform._numTimesY);
	}

	if (_owner) {
		if (_transform._alphaDisable) {
			src.setAlphaMode(TransparentSurface::ALPHA_OPAQUE);
		} else {
			src.setAlphaMode(_owner->getAlphaType());
		}
	}

	if (_transform._numTimesX * _transform._numTimesY == 1) {

		src.blit(*_targetSurface, dstRect->left, dstRect->top, _transform._flip, clipRect, _transform._rgbaMod, clipRect->width(), clipRect->height(), _transform._blendMode);

	} else {

		// clipRect is a subrect of the full numTimesX*numTimesY rect
		Common::Rect subRect;

		int y = 0;
		int w = getSurface()->w;
		int h = getSurface()->h;
		assert(w == _dstRect.width() / _transform._numTimesX);
		assert(h == _dstRect.height() / _transform._numTimesY);

		int basex = dstRect->left - clipRect->left;
		int basey = dstRect->top - clipRect->top;

		for (int ry = 0; ry < _transform._numTimesY; ++ry) {
			int x = 0;
			for (int rx = 0; rx < _transform._numTimesX; ++rx) {

				subRect.left = x;
				subRect.top = y;
				subRect.setWidth(w);
				subRect.setHeight(h);

				if (subRect.intersects(*clipRect)) {
					subRect.clip(*clipRect);
					subRect.translate(-x, -y);
					src.blit(*_targetSurface, basex + x + subRect.left, basey + y + subRect.top, _transform._flip, &subRect, _transform._rgbaMod, subRect.width(), subRect.height(), _transform._blendMode);

				}

				x += w;
			}
			y += h;
		}
	}

	if (doDelete) {
		delete clipRect;
	}
}
示例#29
0
void Sprite::blit(const Sprite &from, const Common::Rect &area, int32 x, int32 y, bool transp) {
	// Sanity checks
	assert((x >= 0) && (y >= 0) && (x <= 0x7FFF) && (y <= 0x7FFF));

	if (!exists() || !from.exists())
		return;

	Common::Rect toArea = getArea(true);

	toArea.left = x;
	toArea.top  = y;
	if (toArea.isEmpty())
		return;

	Common::Rect fromArea = from.getArea();

	fromArea.clip(area);
	fromArea.setWidth (MIN(fromArea.width() , toArea.width()));
	fromArea.setHeight(MIN(fromArea.height(), toArea.height()));
	if (fromArea.isEmpty() || !fromArea.isValidRect())
		return;

	int32 w = fromArea.width();
	int32 h = fromArea.height();

	const int32 fromTop   = fracToInt(fromArea.top  * from._scaleInverse);
	const int32 fromLeft  = fracToInt(fromArea.left * from._scaleInverse);

	const byte *src = (const byte *) from._surfaceTrueColor.getBasePtr(fromLeft, fromTop);
	      byte *dst = (      byte *)      _surfaceTrueColor.getBasePtr(x, y);

	const uint8 *srcT = from._transparencyMap + fromTop * from._surfaceTrueColor.w + fromLeft;
	      uint8 *dstT =      _transparencyMap +       y *      _surfaceTrueColor.w + x;

	frac_t posW = 0, posH = 0;
	while (h-- > 0) {
		posW = 0;

		const byte *srcRow = src;
		      byte *dstRow = dst;

		const uint8 *srcRowT = srcT;
		      uint8 *dstRowT = dstT;

		for (int32 j = 0; j < w; j++, dstRow += _surfaceTrueColor.bytesPerPixel, dstRowT++) {
			if (!transp || (*srcRowT == 0)) {
				// Ignore transparency or source is solid => copy
				memcpy(dstRow, srcRow, _surfaceTrueColor.bytesPerPixel);
				*dstRowT = *srcRowT;
			} else if (*srcRowT == 2) {
				// Half-transparent
				if (*dstRowT == 1)
					// But destination is transparent => propagate
					memcpy(dstRow, srcRow, _surfaceTrueColor.bytesPerPixel);
				else
					// Destination is solid => mix
					ImgConv.mixTrueColor(dstRow, srcRow);

				*dstRowT = *srcRowT;
			}

			// Advance source data
			posW += from._scaleInverse;
			while (posW >= ((frac_t) FRAC_ONE)) {
				srcRow += from._surfaceTrueColor.bytesPerPixel;
				srcRowT++;
				posW -= FRAC_ONE;
			}

		}

		dst  += _surfaceTrueColor.pitch;
		dstT += _surfaceTrueColor.w;

		// Advance source data
		posH += from._scaleInverse;
		while (posH >= ((frac_t) FRAC_ONE)) {
			src  += from._surfaceTrueColor.pitch;
			srcT += from._surfaceTrueColor.w;
			posH -= FRAC_ONE;
		}

	}
}
示例#30
0
文件: paint32.cpp 项目: 86400/scummvm
reg_t GfxPaint32::makeLineBitmap(const Common::Point &startPoint, const Common::Point &endPoint, const int16 priority, const uint8 color, const LineStyle style, uint16 pattern, uint8 thickness, Common::Rect &outRect) {
	const uint8 skipColor = color != kDefaultSkipColor ? kDefaultSkipColor : 0;

	// Line thickness is expected to be 2 * thickness + 1
	thickness = (MAX<uint8>(1, thickness) - 1) | 1;
	const uint8 halfThickness = thickness >> 1;

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

	outRect.left   = MIN<int16>(startPoint.x, endPoint.x);
	outRect.top    = MIN<int16>(startPoint.y, endPoint.y);
	outRect.right  = MAX<int16>(startPoint.x, endPoint.x) + 1 + 1;	// rect lower edge + thickness offset
	outRect.bottom = MAX<int16>(startPoint.y, endPoint.y) + 1 + 1;	// rect lower edge + thickness offset

	outRect.grow(halfThickness);
	outRect.clip(Common::Rect(scriptWidth, scriptHeight));

	reg_t bitmapId;
	SciBitmap &bitmap = *_segMan->allocateBitmap(&bitmapId, outRect.width(), outRect.height(), skipColor, 0, 0, scriptWidth, scriptHeight, 0, false, true);

	byte *pixels = bitmap.getPixels();
	memset(pixels, skipColor, bitmap.getWidth() * bitmap.getHeight());

	LineProperties properties;
	properties.bitmap = &bitmap;

	switch (style) {
	case kLineStyleSolid:
		pattern = 0xFFFF;
		properties.solid = true;
		break;
	case kLineStyleDashed:
		pattern = 0xFF00;
		properties.solid = false;
		break;
	case kLineStylePattern:
		properties.solid = pattern == 0xFFFF;
		break;
	}

	// Change coordinates to be relative to the bitmap
	const int16 x1 = startPoint.x - outRect.left;
	const int16 y1 = startPoint.y - outRect.top;
	const int16 x2 =   endPoint.x - outRect.left;
	const int16 y2 =   endPoint.y - outRect.top;

	if (!properties.solid) {
		for (int i = 0; i < ARRAYSIZE(properties.pattern); ++i) {
			properties.pattern[i] = (pattern & 0x8000);
			pattern <<= 1;
		}

		properties.patternIndex = 0;
		properties.horizontal = ABS(x2 - x1) > ABS(y2 - y1);
		properties.lastAddress = properties.horizontal ? x1 : y1;
	}

	if (thickness <= 1) {
		Graphics::drawLine(x1, y1, x2, y2, color, plotter, &properties);
	} else {
		Graphics::drawThickLine2(x1, y1, x2, y2, thickness, color, plotter, &properties);
	}

	return bitmapId;
}