예제 #1
0
bool BaseSurfaceOSystem::drawSprite(int x, int y, Rect32 *rect, float zoomX, float zoomY, uint32 alpha, bool alphaDisable, TSpriteBlendMode blendMode, bool mirrorX, bool mirrorY, int offsetX, int offsetY) {
	BaseRenderOSystem *renderer = static_cast<BaseRenderOSystem *>(_gameRef->_renderer);

	if (!_loaded) {
		finishLoad();
	}

	if (renderer->_forceAlphaColor != 0) {
		alpha = renderer->_forceAlphaColor;
	}

	byte r = RGBCOLGetR(alpha);
	byte g = RGBCOLGetG(alpha);
	byte b = RGBCOLGetB(alpha);
	byte a = RGBCOLGetA(alpha);

	renderer->setAlphaMod(a);
	renderer->setColorMod(r, g, b);

#if 0 // These are kept for reference if BlendMode is reimplemented at some point.
	if (alphaDisable) {
		SDL_SetTextureBlendMode(_texture, SDL_BLENDMODE_NONE);
	} else {
		SDL_SetTextureBlendMode(_texture, SDL_BLENDMODE_BLEND);
	}
#endif
	// TODO: This _might_ miss the intended behaviour by 1 in each direction
	// But I think it fits the model used in Wintermute.
	Common::Rect srcRect;
	srcRect.left = rect->left;
	srcRect.top = rect->top;
	srcRect.setWidth(rect->right - rect->left);
	srcRect.setHeight(rect->bottom - rect->top);

	Common::Rect position;
	position.left = x + offsetX;
	position.top = y + offsetY;

	// Crop off-by-ones:
	if (position.left == -1) {
		position.left = 0; // TODO: Something is wrong
	}
	if (position.top == -1) {
		position.top = 0; // TODO: Something is wrong
	}

	position.setWidth((int16)((float)srcRect.width() * zoomX / 100.f));
	position.setHeight((int16)((float)srcRect.height() * zoomX / 100.f));

	renderer->modTargetRect(&position);

	/*  position.left += offsetX;
	    position.top += offsetY;*/

	// TODO: This actually requires us to have the SAME source-offsets every time,
	// But no checking is in place for that yet.

	// TODO: Optimize by not doing alpha-blits if we lack or disable alpha
	bool hasAlpha;
	if (_hasAlpha && !alphaDisable) {
		hasAlpha = true;
	} else {
		hasAlpha = false;
	}
	if (alphaDisable) {
		warning("BaseSurfaceOSystem::drawSprite - AlphaDisable ignored");
	}

	renderer->drawSurface(this, _surface, &srcRect, &position, mirrorX, mirrorY, !hasAlpha);

	return STATUS_OK;
}
예제 #2
0
bool Debugger::Cmd_GfxObjects(int argc, const char **argv) {

	const char *objType[] = { "DOOR", "GET", "ANIM" };

	DebugPrintf("+--------------------+-----+-----+-----+-----+-----+-------+-----+--------+\n"
				"| name               |  x  |  y  |  w  |  h  |  z  | layer |  f  |  type  |\n"
				"+--------------------+-----+-----+-----+-----+-----+-------+-----+--------+\n");

	GfxObjArray::iterator b = _vm->_gfx->_sceneObjects.begin();
	GfxObjArray::iterator e = _vm->_gfx->_sceneObjects.end();
	Common::Rect r;

	for ( ; b != e; ++b) {
		GfxObj *obj = *b;
		obj->getRect(obj->frame, r);
		DebugPrintf("|%-20s|%5i|%5i|%5i|%5i|%5i|%7i|%5i|%8s|\n", obj->getName(), r.left, r.top, r.width(), r.height(),
			obj->z, obj->layer, obj->frame, objType[obj->type]);
	}

	DebugPrintf("+--------------------+-----+-----+-----+-----+-----+-------+-----+--------+\n");

	return true;
}
예제 #3
0
void RivenGraphics::updateScreen(Common::Rect updateRect) {
	if (_updatesEnabled) {
		_vm->runUpdateScreenScript();

		if (_dirtyScreen) {
			_activatedPLSTs.clear();

			// Copy to screen if there's no transition. Otherwise transition. ;)
			if (_scheduledTransition < 0)
				_vm->_system->copyRectToScreen(_mainScreen->getBasePtr(updateRect.left, updateRect.top), _mainScreen->pitch, updateRect.left, updateRect.top, updateRect.width(), updateRect.height());
			else
				runScheduledTransition();

			// Finally, update the screen.
			_vm->_system->updateScreen();
			_dirtyScreen = false;
		}
	}
}
예제 #4
0
void GfxScreen::copyRectToScreen(const Common::Rect &rect, int16 x, int16 y) {
	if (!_upscaledHires)  {
		g_system->copyRectToScreen(_activeScreen + rect.top * _displayWidth + rect.left, _displayWidth, x, y, rect.width(), rect.height());
	} else {
		int rectHeight = _upscaledMapping[rect.bottom] - _upscaledMapping[rect.top];
		g_system->copyRectToScreen(_activeScreen + _upscaledMapping[rect.top] * _displayWidth + rect.left * 2, _displayWidth, x * 2, _upscaledMapping[y], rect.width() * 2, rectHeight);
	}
}
예제 #5
0
파일: menu.cpp 프로젝트: Deledrius/scummvm
void Menu::renderSubmenu(MenuItem *menu) {
	Common::Rect *r = &menu->subbbox;

	if (r->width() == 0 || r->height() == 0)
		return;

	Design::drawFilledRect(&_gui->_screen, *r, kColorWhite, _gui->_patterns, kPatternSolid);
	Design::drawRect(&_gui->_screen, *r, 1, kColorBlack, _gui->_patterns, kPatternSolid);
	Design::drawVLine(&_gui->_screen, r->right + 1, r->top + 3, r->bottom + 1, 1, kColorBlack, _gui->_patterns, kPatternSolid);
	Design::drawHLine(&_gui->_screen, r->left + 3, r->right + 1, r->bottom + 1, 1, kColorBlack, _gui->_patterns, kPatternSolid);

	int x = r->left + kMenuDropdownPadding;
	int y = r->top + 1;
	for (uint i = 0; i < menu->subitems.size(); i++) {
		Common::String text(menu->subitems[i]->text);
		Common::String acceleratorText(getAcceleratorString(menu->subitems[i], ""));
		int accelX = r->right - 25;

		int color = kColorBlack;
		if (i == (uint)_activeSubItem && !text.empty() && menu->subitems[i]->enabled) {
			color = kColorWhite;
			Common::Rect trect(r->left, y - (_gui->_builtInFonts ? 1 : 0), r->right, y + _font->getFontHeight());

			Design::drawFilledRect(&_gui->_screen, trect, kColorBlack, _gui->_patterns, kPatternSolid);
		}

		if (!text.empty()) {
			Graphics::ManagedSurface *s = &_gui->_screen;
			int tx = x, ty = y;

			if (!menu->subitems[i]->enabled) {
				s = &_tempSurface;
				tx = 0;
				ty = 0;
				accelX -= x;

				_tempSurface.clear(kColorGreen);
			}

			_font->drawString(s, text, tx, ty, r->width(), color);

			if (!acceleratorText.empty())
				_font->drawString(s, acceleratorText, accelX, ty, r->width(), color);

			if (!menu->subitems[i]->enabled) {
				// I am lazy to extend drawString() with plotProc as a parameter, so
				// fake it here
				for (int ii = 0; ii < _tempSurface.h; ii++) {
					const byte *src = (const byte *)_tempSurface.getBasePtr(0, ii);
					byte *dst = (byte *)_gui->_screen.getBasePtr(x, y+ii);
					byte pat = _gui->_patterns[kPatternCheckers2 - 1][ii % 8];
					for (int j = 0; j < r->width(); j++) {
						if (*src != kColorGreen && (pat & (1 << (7 - (x + j) % 8))))
							*dst = *src;
						src++;
						dst++;
					}
				}
			}
		} else { // Delimiter
			Design::drawHLine(&_gui->_screen, r->left + 1, r->right - 1, y + kMenuDropdownItemHeight / 2, 1, kColorBlack, _gui->_patterns, kPatternStripes);
		}

		y += kMenuDropdownItemHeight;
	}

	g_system->copyRectToScreen(_gui->_screen.getBasePtr(r->left, r->top), _gui->_screen.pitch, r->left, r->top, r->width() + 3, r->height() + 3);
}
예제 #6
0
bool VideoManager::drawNextFrame(VideoEntryPtr videoEntry) {
	Video::VideoDecoder *video = videoEntry->_video;
	const Graphics::Surface *frame = video->decodeNextFrame();

	if (!frame || !videoEntry->isEnabled()) {
		return false;
	}

	Graphics::Surface *convertedFrame = nullptr;
	Graphics::PixelFormat pixelFormat = _vm->_system->getScreenFormat();

	if (frame->format != pixelFormat) {
		// We don't support downconverting to 8bpp without having
		// support in the codec. Set _enableDither if shows up.
		if (pixelFormat.bytesPerPixel == 1) {
			warning("Cannot convert high color video frame to 8bpp");
			return false;
		}

		// Convert to the current screen format
		convertedFrame = frame->convertTo(pixelFormat, video->getPalette());
		frame = convertedFrame;
	} else if (pixelFormat.bytesPerPixel == 1 && video->hasDirtyPalette()) {
		// Set the palette when running in 8bpp mode only
		// Don't do this for Myst, which has its own per-stack handling
		if (_vm->getGameType() != GType_MYST)
			_vm->_system->getPaletteManager()->setPalette(video->getPalette(), 0, 256);
	}

	// Clip the video to make sure it stays on the screen (Myst does this a few times)
	Common::Rect targetRect = Common::Rect(video->getWidth(), video->getHeight());
	targetRect.translate(videoEntry->getX(), videoEntry->getY());

	Common::Rect frameRect = Common::Rect(video->getWidth(), video->getHeight());

	if (targetRect.left < 0) {
		frameRect.left -= targetRect.left;
		targetRect.left = 0;
	}

	if (targetRect.top < 0) {
		frameRect.top -= targetRect.top;
		targetRect.top = 0;
	}

	if (targetRect.right > _vm->_system->getWidth()) {
		frameRect.right -= targetRect.right - _vm->_system->getWidth();
		targetRect.right = _vm->_system->getWidth();
	}

	if (targetRect.bottom > _vm->_system->getHeight()) {
		frameRect.bottom -= targetRect.bottom - _vm->_system->getHeight();
		targetRect.bottom = _vm->_system->getHeight();
	}

	_vm->_system->copyRectToScreen(frame->getBasePtr(frameRect.left, frameRect.top), frame->pitch,
	                               targetRect.left, targetRect.top, targetRect.width(), targetRect.height());

	// Delete 8bpp conversion surface
	if (convertedFrame) {
		convertedFrame->free();
		delete convertedFrame;
	}

	// We've drawn something to the screen, make sure we update it
	return true;
}
예제 #7
0
void Screen::setDisplayBounds(const Common::Rect &r) {
	_sceneSurface.setPixels(_backBuffer1.getBasePtr(r.left, r.top), r.width(), r.height(), _backBuffer1.getPixelFormat());

	_backBuffer = &_sceneSurface;
}
void ShaderRenderer::draw2DText(const Common::String &text, const Common::Point &position) {
	OpenGLTexture *glFont = static_cast<OpenGLTexture *>(_font);

	// The font only has uppercase letters
	Common::String textToDraw = text;
	textToDraw.toUppercase();

	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	glDisable(GL_DEPTH_TEST);
	glDepthMask(GL_FALSE);

	if (_prevText != textToDraw || _prevTextPosition != position) {
		_prevText = textToDraw;
		_prevTextPosition = position;

		float x = position.x / _currentViewport.getWidth();
		float y = position.y / _currentViewport.getHeight();

		float *bufData = new float[16 * textToDraw.size()];
		float *cur = bufData;

		for (uint i = 0; i < textToDraw.size(); i++) {
			Common::Rect textureRect = getFontCharacterRect(textToDraw[i]);
			float w = textureRect.width() / _currentViewport.getWidth();
			float h = textureRect.height() / _currentViewport.getHeight();

			float cw = textureRect.width() / (float)glFont->internalWidth;
			float ch = textureRect.height() / (float)glFont->internalHeight;
			float cx = textureRect.left / (float)glFont->internalWidth;
			float cy = textureRect.top / (float)glFont->internalHeight;

			const float charData[] = {
				cx,      cy + ch, x,     y,    
				cx + cw, cy + ch, x + w, y,    
				cx + cw, cy,      x + w, y + h,
				cx,      cy,      x,     y + h,
			};

			memcpy(cur, charData, 16 * sizeof(float));
			cur += 16;

			x += (textureRect.width() - 3) / _currentViewport.getWidth();
		}

		glBindBuffer(GL_ARRAY_BUFFER, _textVBO);
		glBufferSubData(GL_ARRAY_BUFFER, 0, textToDraw.size() * 16 * sizeof(float), bufData);
		delete[] bufData;
	}

	_textShader->use();
	glBindTexture(GL_TEXTURE_2D, glFont->id);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _quadEBO);
	glDrawElements(GL_TRIANGLES, 6 * textToDraw.size(), GL_UNSIGNED_SHORT, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

	glDisable(GL_BLEND);
	glEnable(GL_DEPTH_TEST);
	glDepthMask(GL_TRUE);
}
예제 #9
0
View::View(M4Engine *vm, const Common::Rect &viewBounds, bool transparent):
	_hotkeys(HotkeyList(this)), M4Surface(viewBounds.width(), viewBounds.height()), _vm(vm) {
	SCREEN_FLAGS_DEFAULT;
	_coords = viewBounds;
	_transparent = transparent;
}
예제 #10
0
void Screen::addDirtyRect(const Common::Rect &r) {
	_dirtyRects.push_back(r);
	assert(r.width() > 0 && r.height() > 0);
}
예제 #11
0
void Gfx::bltMaskScale(const Common::Rect& r, byte *data, Graphics::Surface *surf, uint16 z, uint scale, byte transparentColor) {
	if (scale == 100) {
		// use optimized path
		bltMaskNoScale(r, data, surf, z, transparentColor);
		return;
	}

	// unscaled rectangle size
	uint width = r.width();
	uint height = r.height();

	// scaled rectangle size
	uint scaledWidth = r.width() * scale / 100;
	uint scaledHeight = r.height() * scale / 100;

	// scaled rectangle origin
	uint scaledLeft = r.left + (width - scaledWidth) / 2;
	uint scaledTop = r.top + (height - scaledHeight);

	// clipped scaled destination rectangle
	Common::Rect dstRect(scaledWidth, scaledHeight);
	dstRect.moveTo(scaledLeft, scaledTop);
	
	Common::Rect clipper(surf->w, surf->h);	
	dstRect.clip(clipper);
	if (!dstRect.isValidRect()) return;
	
	
	// clipped source rectangle
	Common::Rect srcRect;
	srcRect.left = (dstRect.left - scaledLeft)  * 100 / scale;
	srcRect.top = (dstRect.top - scaledTop) * 100 / scale;
	srcRect.setWidth(dstRect.width() * 100 / scale);
	srcRect.setHeight(dstRect.height() * 100 / scale);
	if (!srcRect.isValidRect()) return;	

	Common::Point dp;
	dp.x = dstRect.left;
	dp.y = dstRect.top;

	byte *s = data + srcRect.left + srcRect.top * width;
	byte *d = (byte*)surf->getBasePtr(dp.x, dp.y);

	uint line = 0, col = 0;

	uint xAccum = 0, yAccum = 0;
	uint inc = width * (100 - scale);
	uint thr = width * 100;

	for (uint16 i = 0; i < srcRect.height(); i++) {
		yAccum += inc;

		if (yAccum >= thr) {
			yAccum -= thr;
			s += width;
			continue;
		}

		xAccum = 0;
		byte *d2 = d;
		col = 0;

		for (uint16 j = 0; j < srcRect.width(); j++) {
			xAccum += inc;

			if (xAccum >= thr) {
				xAccum -= thr;
				s++;
				continue;
			}

			if (*s != transparentColor) {
				if (_backgroundInfo->hasMask()) {
					byte v = _backgroundInfo->_mask->getValue(dp.x + col, dp.y + line);
					if (z >= v) *d2 = *s;
				} else {
					*d2 = *s;
				}
			}

			s++;
			d2++;
			col++;
		}

		s += width - srcRect.width();
		d += surf->w;
		line++;
	}

}
예제 #12
0
void GfxScreen::copyRectToScreen(const Common::Rect &rect) {
	if (!_upscaledHires)  {
		g_system->copyRectToScreen(_activeScreen + rect.top * _displayWidth + rect.left, _displayWidth, rect.left, rect.top, rect.width(), rect.height());
	} else {
		int rectHeight = _upscaledHeightMapping[rect.bottom] - _upscaledHeightMapping[rect.top];
		int rectWidth  = _upscaledWidthMapping[rect.right] - _upscaledWidthMapping[rect.left];
		g_system->copyRectToScreen(_activeScreen + _upscaledHeightMapping[rect.top] * _displayWidth + _upscaledWidthMapping[rect.left], _displayWidth, _upscaledWidthMapping[rect.left], _upscaledHeightMapping[rect.top], rectWidth, rectHeight);
	}
}
예제 #13
0
void Animation::getFoot(Common::Point &foot) {
	Common::Rect rect;
	gfxobj->getRect(_frame, rect);
	foot.x = getX() + (rect.left + rect.width() / 2);
	foot.y = getY() + (rect.top + rect.height());
}
예제 #14
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;
}
예제 #15
0
파일: screen.cpp 프로젝트: idkiller/scummvm
void Screen::restoreBackground(const Common::Rect &r) {
	if (r.width() > 0 && r.height() > 0)
		_backBuffer.SHblitFrom(_backBuffer2, Common::Point(r.left, r.top), r);
}
void ShaderRenderer::setupCameraPerspective(float pitch, float heading, float fov) {
	Renderer::setupCameraPerspective(pitch, heading, fov);

	Common::Rect frame = frameViewport();
	glViewport(frame.left, frame.top, frame.width(), frame.height());
}
예제 #17
0
파일: screen.cpp 프로젝트: idkiller/scummvm
void Screen::setDisplayBounds(const Common::Rect &r) {
	_backBuffer.create(_backBuffer1, r);
	assert(_backBuffer.width()  == r.width());
	assert(_backBuffer.height() == r.height());
}
예제 #18
0
// Replacement for SDL2's SDL_RenderCopy
void RenderTicket::drawToSurface(Graphics::Surface *_targetSurface) const {
    TransparentSurface src(*getSurface(), false);

    Common::Rect clipRect;
    clipRect.setWidth(getSurface()->w);
    clipRect.setHeight(getSurface()->h);

    if (_owner) {
        if (_transform._alphaDisable) {
            src._alphaMode = TransparentSurface::ALPHA_OPAQUE;
        } else {
            src._alphaMode = _owner->getAlphaType();
        }
    }
    src.blit(*_targetSurface, _dstRect.left, _dstRect.top, _transform._flip, &clipRect, _transform._rgbaMod, clipRect.width(), clipRect.height());
}
예제 #19
0
reg_t GfxText32::createTextBitmap(reg_t textObject, uint16 maxWidth, uint16 maxHeight) {
	reg_t stringObject = readSelector(_segMan, textObject, SELECTOR(text));

	// The object in the text selector of the item can be either a raw string
	// or a Str object. In the latter case, we need to access the object's data
	// selector to get the raw string.
	if (_segMan->isHeapObject(stringObject))
		stringObject = readSelector(_segMan, stringObject, SELECTOR(data));

	Common::String text = _segMan->getString(stringObject);
	// HACK: The character offsets of the up and down arrow buttons are off by one
	// in GK1, for some unknown reason. Fix them here.
	if (text.size() == 1 && (text[0] == 29 || text[0] == 30)) {
		text.setChar(text[0] + 1, 0);
	}
	GuiResourceId fontId = readSelectorValue(_segMan, textObject, SELECTOR(font));
	GfxFont *font = _cache->getFont(fontId);
	bool dimmed = readSelectorValue(_segMan, textObject, SELECTOR(dimmed));
	int16 alignment = readSelectorValue(_segMan, textObject, SELECTOR(mode));
	uint16 foreColor = readSelectorValue(_segMan, textObject, SELECTOR(fore));
	uint16 backColor = readSelectorValue(_segMan, textObject, SELECTOR(back));

	Common::Rect nsRect = g_sci->_gfxCompare->getNSRect(textObject);
	uint16 width = nsRect.width() + 1;
	uint16 height = nsRect.height() + 1;

	// Limit rectangle dimensions, if requested
	if (maxWidth > 0)
		width = maxWidth;
	if (maxHeight > 0)
		height = maxHeight;

	// Upscale the coordinates/width if the fonts are already upscaled
	if (_screen->fontIsUpscaled()) {
		width = width * _screen->getDisplayWidth() / _screen->getWidth();
		height = height * _screen->getDisplayHeight() / _screen->getHeight();
	}

	int entrySize = width * height + BITMAP_HEADER_SIZE;
	reg_t memoryId = _segMan->allocateHunkEntry("TextBitmap()", entrySize);
	writeSelector(_segMan, textObject, SELECTOR(bitmap), memoryId);
	byte *memoryPtr = _segMan->getHunkPointer(memoryId);
	memset(memoryPtr, backColor, entrySize);
	byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE;

	// Save totalWidth, totalHeight
	WRITE_LE_UINT16(memoryPtr, width);
	WRITE_LE_UINT16(memoryPtr + 2, height);

	int16 charCount = 0;
	uint16 curX = 0, curY = 0;
	const char *txt = text.c_str();
	int16 textWidth, textHeight, totalHeight = 0, offsetX = 0, offsetY = 0;
	uint16 start = 0;

	// Calculate total text height
	while (*txt) {
		charCount = GetLongest(txt, width, font);
		if (charCount == 0)
			break;

		Width(txt, 0, (int16)strlen(txt), fontId, textWidth, textHeight, true);

		totalHeight += textHeight;
		txt += charCount;
		while (*txt == ' ')
			txt++; // skip over breaking spaces
	}

	txt = text.c_str();

	// Draw text in buffer
	while (*txt) {
		charCount = GetLongest(txt, width, font);
		if (charCount == 0)
			break;
		Width(txt, start, charCount, fontId, textWidth, textHeight, true);

		switch (alignment) {
		case SCI_TEXT32_ALIGNMENT_RIGHT:
			offsetX = width - textWidth;
			break;
		case SCI_TEXT32_ALIGNMENT_CENTER:
			// Center text both horizontally and vertically
			offsetX = (width - textWidth) / 2;
			offsetY = (height - totalHeight) / 2;
			break;
		case SCI_TEXT32_ALIGNMENT_LEFT:
			offsetX = 0;
			break;

		default:
			warning("Invalid alignment %d used in TextBox()", alignment);
		}

		for (int i = 0; i < charCount; i++) {
			unsigned char curChar = txt[i];
			font->drawToBuffer(curChar, curY + offsetY, curX + offsetX, foreColor, dimmed, bitmap, width, height);
			curX += font->getCharWidth(curChar);
		}

		curX = 0;
		curY += font->getHeight();
		txt += charCount;
		while (*txt == ' ')
			txt++; // skip over breaking spaces
	}

	return memoryId;
}
예제 #20
0
void Cursor::render() {
	updateFadeLevel();
	updateHintDelay();

	if (!_gfx->isPosInScreenBounds(_mousePos)) {
		setCursorType(Cursor::kPassive);
	}

	if (_mouseText && _gfx->gameViewport().contains(_mousePos) && _hintDisplayDelay <= 0) {
		_gfx->setScreenViewport(false);

		// TODO: Should probably query the image for the width of the cursor
		// TODO: Add delay to the mouse hints like in the game
		const int16 cursorDistance = 32;
		Common::Rect mouseRect = _mouseText->getRect();
		Common::Point pos = _gfx->convertCoordinateCurrentToOriginal(_mousePos);
		pos.x = CLIP<int16>(pos.x, 48, Gfx::Driver::kOriginalWidth - 48);
		pos.y = CLIP<int16>(pos.y, Gfx::Driver::kTopBorderHeight, Gfx::Driver::kOriginalHeight - Gfx::Driver::kBottomBorderHeight - cursorDistance - mouseRect.height());
		pos.x -= mouseRect.width() / 2;
		pos.y += cursorDistance;

		_mouseText->render(pos);
	}

	if (_currentCursorType != kImage) {
		_cursorImage = StarkStaticProvider->getCursorImage(_currentCursorType);
	}

	if (_cursorImage) {
		_gfx->setScreenViewport(true); // Unscaled viewport so that cursor is drawn on native pixel space, thus no 'skipping', perform scaling below instead

		_cursorImage->setFadeLevel(_fadeLevel);
		_cursorImage->render(_mousePos, true, false); // Draws image (scaled)
	}
}
예제 #21
0
/**
 * This copies a rect to screen w/o scaling adjustment and is only meant to be
 * used on hires graphics used in upscaled hires mode.
 */
void GfxScreen::copyDisplayRectToScreen(const Common::Rect &rect) {
	if (!_upscaledHires)
		error("copyDisplayRectToScreen: not in upscaled hires mode");
	g_system->copyRectToScreen(_activeScreen + rect.top * _displayWidth + rect.left, _displayWidth, rect.left, rect.top, rect.width(), rect.height());
}
예제 #22
0
void CUP_Player::copyRectToScreen(const Common::Rect &r) {
	const uint8 *src = _offscreenBuffer + r.top * _width + r.left;
	_system->copyRectToScreen(src, _width, r.left, r.top, r.width() + 1, r.height() + 1);
}
예제 #23
0
Common::Rect Surface::render(Graphics::Surface *surface, int dx, int dy, bool mirror, Common::Rect src_rect, uint zoom) const {
	if (src_rect.isEmpty()) {
		src_rect = Common::Rect(0, 0, w, h);
	}
	Common::Rect dst_rect(x + dx, y + dy, x + dx + zoom * src_rect.width() / 256, y + dy + zoom * src_rect.height() / 256);
	if (dst_rect.left < 0) {
		src_rect.left = -dst_rect.left;
		dst_rect.left = 0;
	}
	if (dst_rect.right > surface->w) {
		src_rect.right -= dst_rect.right - surface->w;
		dst_rect.right = surface->w;
	}
	if (dst_rect.top < 0) {
		src_rect.top -= dst_rect.top;
		dst_rect.top = 0;
	}
	if (dst_rect.bottom > surface->h) {
		src_rect.bottom -= dst_rect.bottom - surface->h;
		dst_rect.bottom = surface->h;
	}
	if (src_rect.isEmpty() || dst_rect.isEmpty())
		return Common::Rect();

	if (zoom == 256) {
		const byte *src = (const byte *)getBasePtr(0, src_rect.top);
		byte *dst_base = (byte *)surface->getBasePtr(dst_rect.left, dst_rect.top);

		for (int i = src_rect.top; i < src_rect.bottom; ++i) {
			byte *dst = dst_base;
			for (int j = src_rect.left; j < src_rect.right; ++j) {
				byte p = src[(mirror? w - j - 1: j)];
				if (p != 0xff)
					*dst++ = p;
				else
					++dst;
			}
			dst_base += surface->pitch;
			src += pitch;
		}
	} else {
		byte *dst = (byte *)surface->getBasePtr(dst_rect.left, dst_rect.top);
		for(int i = 0; i < dst_rect.height(); ++i) {
			for (int j = 0; j < dst_rect.width(); ++j) {
				int px = j * 256 / zoom;
				const byte *src = (const byte *)getBasePtr(src_rect.left + (mirror? w - px - 1: px), src_rect.top + i * 256 / zoom);
				byte p = *src;
				if (p != 0xff)
					dst[j] = p;
			}
			dst += surface->pitch;
		}
	}
	return dst_rect;
}