예제 #1
0
void splashScreen() {
	Common::MemoryReadStream stream(logo_data, ARRAYSIZE(logo_data));

	Image::BitmapDecoder bitmap;

	if (!bitmap.loadStream(stream)) {
		warning("Error loading logo file");
		return;
	}

	g_system->showOverlay();

	// Fill with blue - ResidualVM theme
	Graphics::Surface screen;
	screen.create(g_system->getOverlayWidth(), g_system->getOverlayHeight(), g_system->getOverlayFormat());
	screen.fillRect(Common::Rect(screen.w, screen.h), screen.format.ARGBToColor(0xff, 0x1e, 0x6f, 0x95)); // ResidualVM theme

	// Load logo
	Graphics::Surface *logo = bitmap.getSurface()->convertTo(g_system->getOverlayFormat(), bitmap.getPalette());
	int lx = MAX((g_system->getOverlayWidth() - logo->w) / 2, 0);
	int ly = MAX((g_system->getOverlayHeight() - logo->h) / 2, 0);

	// Print version information
	const Graphics::Font *font = FontMan.getFontByUsage(Graphics::FontManager::kConsoleFont);
	int w = font->getStringWidth(gScummVMVersionDate);
	int x = g_system->getOverlayWidth() - w - 5; // lx + logo->w - w + 5;
	int y = g_system->getOverlayHeight() - font->getFontHeight() - 5; //ly + logo->h + 5;
	font->drawString(&screen, gScummVMVersionDate, x, y, w, screen.format.ARGBToColor(0xff, 0, 0, 0));

	g_system->copyRectToOverlay(screen.getPixels(), screen.pitch, 0, 0, screen.w, screen.h);
	screen.free();

	// Draw logo
	int lw = MIN<uint16>(logo->w, g_system->getOverlayWidth() - lx);
	int lh = MIN<uint16>(logo->h, g_system->getOverlayHeight() - ly);

	g_system->copyRectToOverlay(logo->getPixels(), logo->pitch, lx, ly, lw, lh);
	logo->free();
	delete logo;

	g_system->updateScreen();

	// Delay 0.6 secs
	uint time0 = g_system->getMillis();
	Common::Event event;
	while (time0 + 600 > g_system->getMillis()) {
		(void)g_system->getEventManager()->pollEvent(event);
		g_system->delayMillis(10);
	}
	g_system->hideOverlay();

	splash = true;
}
예제 #2
0
void RenderManager::blitSurfaceToBkgScaled(const Graphics::Surface &src, const Common::Rect &_dstRect, int32 colorkey) {
	if (src.w == _dstRect.width() && src.h == _dstRect.height()) {
		blitSurfaceToBkg(src, _dstRect.left, _dstRect.top, colorkey);
	} else {
		Graphics::Surface *tmp = new Graphics::Surface;
		tmp->create(_dstRect.width(), _dstRect.height(), src.format);
		scaleBuffer(src.getPixels(), tmp->getPixels(), src.w, src.h, src.format.bytesPerPixel, _dstRect.width(), _dstRect.height());
		blitSurfaceToBkg(*tmp, _dstRect.left, _dstRect.top, colorkey);
		tmp->free();
		delete tmp;
	}
}
예제 #3
0
파일: gfx_opengl.cpp 프로젝트: klusark/twin
Graphics::Surface *OpenGLRenderer::getScreenshot() {
	Common::Rect screen = viewport();

	Graphics::Surface *s = new Graphics::Surface();
	s->create(screen.width(), screen.height(), Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));

	glReadPixels(screen.left, screen.top, screen.width(), screen.height(), GL_RGBA, GL_UNSIGNED_BYTE, s->getPixels());

	flipVertical(s);

	return s;
}
예제 #4
0
Graphics::Surface *TruetypeFont::drawTextToSurface(const Common::String &text, uint16 textColor, int maxWidth, int maxHeight, Graphics::TextAlign align, bool wrap) {
	if (text.equals("")) {
		return nullptr;
	}

	Graphics::Surface *surface = new Graphics::Surface();

	if (!wrap) {
		int width = MIN(_font->getStringWidth(text), maxWidth);
		surface->create(width, _lineHeight, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
		// TODO: Add better alpha support by getting the pixels from the backbuffer.
		// However doing that requires some kind of caching system so future text doesn't try to use this text as it's alpha background.
		surface->fillRect(Common::Rect(0, 0, surface->w, surface->h), 0);

		_font->drawString(surface, text, 0, 0, maxWidth, textColor, align);
		return surface;
	}

	Common::Array<Common::String> lines;
	_font->wordWrapText(text, maxWidth, lines);

	while (maxHeight > 0 && (int)lines.size() * _lineHeight > maxHeight) {
		lines.pop_back();
	}
	if (lines.size() == 0) {
		delete surface;
		return nullptr;
	}

	surface->create(maxWidth, lines.size() * _lineHeight, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
	surface->fillRect(Common::Rect(0, 0, surface->w, surface->h), 0);

	int heightOffset = 0;
	for (Common::Array<Common::String>::iterator it = lines.begin(); it != lines.end(); it++) {
		_font->drawString(surface, *it, 0, 0 + heightOffset, maxWidth, textColor, align);
		heightOffset += _lineHeight;
	}

	return surface;
}
예제 #5
0
static bool createThumbnail(Graphics::Surface &out, Graphics::Surface &in) {
	int height;
	if ((in.w == 320 && in.h == 200) || (in.w == 640 && in.h == 400)) {
		height = kThumbnailHeight1;
	} else {
		height = kThumbnailHeight2;
	}

	out.create(kThumbnailWidth, height, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
	scaleThumbnail(in, out);
	in.free();
	return true;
}
예제 #6
0
파일: events.cpp 프로젝트: 0xf1sh/scummvm
void EventsManager::setCursor(CursorType cursorId) {
	if (cursorId == _cursorId)
		return;	
	_cursorId = cursorId;
	
	if (cursorId == CURSOR_INVENTORY) {
		// Set the cursor
		CursorMan.replaceCursor(_invCursor.getPixels(), _invCursor.w, _invCursor.h,
			_invCursor.w / 2, _invCursor.h / 2, 0);
	} else {
		// Get a pointer to the mouse data to use, and get the cursor hotspot
		const byte *srcP = Amazon::CURSORS[cursorId];
		int hotspotX = (int16)READ_LE_UINT16(srcP);
		int hotspotY = (int16)READ_LE_UINT16(srcP + 2);
		srcP += 4;

		// Create a surface to build up the cursor on
		Graphics::Surface cursorSurface;
		cursorSurface.create(16, 16, Graphics::PixelFormat::createFormatCLUT8());
		byte *destP = (byte *)cursorSurface.getPixels();
		Common::fill(destP, destP + CURSOR_WIDTH * CURSOR_HEIGHT, 0);

		// Loop to build up the cursor
		for (int y = 0; y < CURSOR_HEIGHT; ++y) {
			destP = (byte *)cursorSurface.getBasePtr(0, y);
			int width = CURSOR_WIDTH;
			int skip = *srcP++;
			int plot = *srcP++;
			if (skip >= width)
				break;

			// Skip over pixels
			destP += skip;
			width -= skip;

			// Write out the pixels to plot
			while (plot > 0 && width > 0) {
				*destP++ = *srcP++;
				--plot;
				--width;
			}
		}

		// Set the cursor
		CursorMan.replaceCursor(cursorSurface.getPixels(), CURSOR_WIDTH, CURSOR_HEIGHT,
			hotspotX, hotspotY, 0);

		// Free the cursor surface
		cursorSurface.free();
	}
}
예제 #7
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;
}
예제 #8
0
Graphics::Surface *BalloonManager_br::expandBalloon(Frames *data, int frameNum) {

	Common::Rect rect;
	data->getRect(frameNum, rect);

	rect.translate(-rect.left, -rect.top);

	Graphics::Surface *surf = new Graphics::Surface;
	surf->create(rect.width(), rect.height(), 1);

	_vm->_gfx->unpackBlt(rect, data->getData(frameNum), data->getRawSize(frameNum), surf, LAYER_FOREGROUND, 100, BALLOON_TRANSPARENT_COLOR_BR);

	return surf;
}
예제 #9
0
void MoviePlayer::drawFramePSX(const Graphics::Surface *frame) {
	// The PSX videos have half resolution

	Graphics::Surface scaledFrame;
	scaledFrame.create(frame->getWidth(), frame->getHeight() * 2, frame->getFormat());

	for (int y = 0; y < scaledFrame.getHeight(); y++)
		memcpy(scaledFrame.getBasePtr(0, y), frame->getBasePtr(0, y / 2), scaledFrame.getWidth() * scaledFrame.getFormat().bytesPerPixel);

	uint16 x = (g_system->getWidth() - scaledFrame.getWidth()) / 2;
	uint16 y = (g_system->getHeight() - scaledFrame.getHeight()) / 2;

	_vm->_system->copyRectToScreen(scaledFrame.getPixels(), scaledFrame.getPitch(), x, y, scaledFrame.getWidth(), scaledFrame.getHeight());
}
예제 #10
0
SaveDataWidget::SaveDataWidget(int slot, Gfx::Driver *gfx, SaveLoadMenuScreen *screen) :
		StaticLocationWidget(nullptr, nullptr, nullptr),
		_slot(slot),
		_screen(screen),
		_thumbWidth(StarkUserInterface->kThumbnailWidth),
		_thumbHeight(StarkUserInterface->kThumbnailHeight),
		_texture(gfx->createTexture()),
		_outline(gfx->createTexture()),
		_surfaceRenderer(gfx->createSurfaceRenderer()),
		_textDesc(gfx),
		_textTime(gfx),
		_isMouseHovered(false),
		_hasSave(false),
		_name() {
	// Load from the save data
	loadSaveDataElements();

	_textDesc.setColor(_textColor);
	_textDesc.setFont(FontProvider::kCustomFont, 3);

	_textTime.setColor(_textColor);
	_textTime.setFont(FontProvider::kCustomFont, 3);

	Graphics::PixelFormat pixelFormat = Gfx::Driver::getRGBAPixelFormat();
	uint32 outlineColor = pixelFormat.ARGBToColor(
			_outlineColor.a, _outlineColor.r, _outlineColor.g, _outlineColor.b
	);

	// Create the outline texture
	Graphics::Surface lineSurface;
	lineSurface.create(_thumbWidth, _thumbHeight, pixelFormat);
	lineSurface.drawThickLine(0, 0, _thumbWidth - 1, 0, 2, 2, outlineColor);
	lineSurface.drawThickLine(0, 0, 0, _thumbHeight - 1, 2, 2, outlineColor);
	lineSurface.drawThickLine(_thumbWidth - 2, 0, _thumbWidth - 2, _thumbHeight - 2, 2, 2, outlineColor);
	lineSurface.drawThickLine(0, _thumbHeight - 2, _thumbWidth - 2, _thumbHeight - 2, 2, 2, outlineColor);

	_outline->update(&lineSurface);
	lineSurface.free();

	// Set the position
	_thumbPos.x = 41 + (_slot % SaveLoadMenuScreen::_slotPerRow) * (_thumbWidth + 39);
	_thumbPos.y = 61 + (_slot % SaveLoadMenuScreen::_slotPerPage / SaveLoadMenuScreen::_slotPerColumn) * (_thumbHeight + 38);

	_textDescPos.x = _thumbPos.x;
	_textDescPos.y = _thumbPos.y + _thumbHeight + 2;

	_textTimePos.x = _thumbPos.x;
	_textTimePos.y = _textDescPos.y + 12;
}
예제 #11
0
Graphics::Surface BladeRunnerEngine::generateThumbnail() const {
	Graphics::Surface thumbnail;
	thumbnail.create(640 / 8, 480 / 8, createRGB555());

	for (int y = 0; y < thumbnail.h; ++y) {
		for (int x = 0; x < thumbnail.w; ++x) {
			uint16       *dstPixel = (uint16 *)thumbnail.getBasePtr(x, y);
			const uint16 *srcPixel = (const uint16 *)_surfaceFront.getBasePtr(x * 8, y * 8);

			*dstPixel = *srcPixel;
		}
	}

	return thumbnail;
}
예제 #12
0
void MoviePlayer::drawFramePSX(const Graphics::Surface *frame) {
	// The PSX videos have half resolution

	Graphics::Surface scaledFrame;
	scaledFrame.create(frame->w, frame->h * 2, frame->format);

	for (int y = 0; y < scaledFrame.h; y++)
		memcpy(scaledFrame.getBasePtr(0, y), frame->getBasePtr(0, y / 2), scaledFrame.w * scaledFrame.format.bytesPerPixel);

	uint16 x = (g_system->getWidth() - scaledFrame.w) / 2;
	uint16 y = (g_system->getHeight() - scaledFrame.h) / 2;

	_vm->_system->copyRectToScreen((byte *)scaledFrame.pixels, scaledFrame.pitch, x, y, scaledFrame.w, scaledFrame.h);

	scaledFrame.free();
}
예제 #13
0
    virtual void setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor = 255, bool dontScale = false, const Graphics::PixelFormat *format = NULL)
    {
        const Graphics::PixelFormat mformat = format ? *format : Graphics::PixelFormat::createFormatCLUT8();

        if(_mouseImage.w != w || _mouseImage.h != h || _mouseImage.format != mformat)
        {
            _mouseImage.create(w, h, mformat);
        }

        memcpy(_mouseImage.pixels, buf, h * _mouseImage.pitch);

        _mouseHotspotX = hotspotX;
        _mouseHotspotY = hotspotY;
        _mouseKeyColor = keycolor;
        _mouseDontScale = dontScale;
    }
예제 #14
0
Graphics::Surface *TinyGLRenderer::getScreenshot() {
	Graphics::Surface *s = new Graphics::Surface();
	s->create(kOriginalWidth, kOriginalHeight, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
	Graphics::PixelBuffer buf(s->format, (byte *)s->getPixels());
	_fb->copyToBuffer(buf);
	//Vertical flip in place:
	Graphics::PixelBuffer startLine(s->format, kOriginalWidth, DisposeAfterUse::YES);
	Graphics::PixelBuffer endLine(s->format, kOriginalWidth, DisposeAfterUse::YES);
	for(int y = 0; y < kOriginalHeight / 2; y++)
	{
		startLine.copyBuffer(0, y * kOriginalWidth, kOriginalWidth, buf);
		endLine.copyBuffer(0, (kOriginalHeight - y - 1) * kOriginalWidth, kOriginalWidth, buf);
		buf.copyBuffer(y * kOriginalWidth, 0, kOriginalWidth, endLine);
		buf.copyBuffer((kOriginalHeight - y - 1) * kOriginalWidth, 0, kOriginalWidth, startLine);
	}
	return s;
}
예제 #15
0
void AnimationResource::load(byte *source, int size) {
	Common::MemoryReadStream *sourceS = new Common::MemoryReadStream(source, size);

	sourceS->readUint32LE();
	sourceS->readUint32LE();
	sourceS->readUint16LE();

	_flags = sourceS->readUint16LE();
	_width = sourceS->readUint16LE();
	_height = sourceS->readUint16LE();
	sourceS->readUint32LE();
	uint16 frameCount = sourceS->readUint16LE();
	sourceS->readUint16LE();
	sourceS->readUint16LE();

	for (uint16 i = 0; i < frameCount; i++) {

		sourceS->seek(26 + i * 4);

		uint32 frameOffs = sourceS->readUint32LE();

		sourceS->seek(frameOffs);
		sourceS->readUint32LE();
		sourceS->readUint32LE();

		uint16 frameWidth = sourceS->readUint16LE();
		uint16 frameHeight = sourceS->readUint16LE();
		uint16 cmdOffs = sourceS->readUint16LE();
		sourceS->readUint16LE();
		uint16 pixelOffs = sourceS->readUint16LE();
		sourceS->readUint16LE();
		uint16 maskOffs = sourceS->readUint16LE();
		sourceS->readUint16LE();
		uint16 lineSize = sourceS->readUint16LE();

		Graphics::Surface *frame = new Graphics::Surface();
		frame->create(frameWidth, frameHeight, Graphics::PixelFormat::createFormatCLUT8());

		decompressImage(source + frameOffs, *frame, cmdOffs, pixelOffs, maskOffs, lineSize, 0, 0, 0, _flags & 1);

		_frames.push_back(frame);

	}

	delete sourceS;
}
예제 #16
0
Graphics::Surface *RenderManager::tranposeSurface(const Graphics::Surface *surface) {
	Graphics::Surface *tranposedSurface = new Graphics::Surface();
	tranposedSurface->create(surface->h, surface->w, surface->format);

	const uint16 *source = (const uint16 *)surface->getPixels();
	uint16 *dest = (uint16 *)tranposedSurface->getPixels();

	for (uint32 y = 0; y < tranposedSurface->h; ++y) {
		uint32 columnIndex = y * tranposedSurface->w;

		for (uint32 x = 0; x < tranposedSurface->w; ++x) {
			dest[columnIndex + x] = source[x * surface->w + y];
		}
	}

	return tranposedSurface;
}
예제 #17
0
파일: menu.cpp 프로젝트: AReim1982/scummvm
int MenuSystem::run(MenuID menuId) {
	_background = new Graphics::Surface();
	_background->create(640, 400, Graphics::PixelFormat::createFormatCLUT8());

	// Save original background
	Graphics::Surface backgroundOrig;
	backgroundOrig.create(640, 400, Graphics::PixelFormat::createFormatCLUT8());
	memcpy(backgroundOrig.getBasePtr(0,0), _vm->_screen->_frontScreen, 640 * 400);

	_currMenuID = kMenuIdNone;
	_newMenuID = menuId;
	_currItemID = kItemIdNone;
	_editingDescription = false;

	_running = true;
	_top = 30 - _vm->_guiHeight / 2;

	_needRedraw = false;

	_vm->_palette->buildColorTransTable(0, 16, 7);

	_vm->_screen->_renderQueue->clear();
	// Draw the menu background and frame
	_vm->_screen->blastSprite(0x140 + _vm->_cameraX, 0x175 + _vm->_cameraY, 0, 1, 0x4000);
	shadeRect(60, 39, 520, 247, 225, 229);

	memcpy(_background->getPixels(), _vm->_screen->_frontScreen, 640 * 400);

	while (_running) {
		update();
		_vm->_system->updateScreen();
	}

	// Restore original background
	memcpy(_vm->_screen->_frontScreen, backgroundOrig.getBasePtr(0,0), 640 * 400);
	_vm->_system->copyRectToScreen(_vm->_screen->_frontScreen, 640, 0, 0, 640, 400);
	_vm->_system->updateScreen();

	// Cleanup
	backgroundOrig.free();
	_background->free();
	delete _background;

	return 0;
}
예제 #18
0
Graphics::Surface *Hero::zoomSprite(Graphics::Surface *heroFrame) {
	Graphics::Surface *zoomedFrame = new Graphics::Surface();
	zoomedFrame->create(_scaledFrameXSize, _scaledFrameYSize, Graphics::PixelFormat::createFormatCLUT8());

	int sprZoomX;
	int sprZoomY = _vm->_scaleValue;
	uint xSource = 0;
	uint ySource = 0;
	uint xDest = 0;
	uint yDest = 0;

	for (int i = 0; i < _scaledFrameYSize; i++) {
		// linear_loop:
		while (1) {
			sprZoomY -= 100;
			if (sprZoomY >= 0 || _vm->_scaleValue == 10000) {
				// all_r_y
				sprZoomX = _vm->_scaleValue;
				break; // to loop_lin
			} else {
				sprZoomY += _vm->_scaleValue;
				xSource = 0;
				ySource++;
			}
		}
		// loop_lin:
		for (int j = 0; j < _scaledFrameXSize; j++) {
			sprZoomX -= 100;
			if (sprZoomX >= 0) {
				// its_all_r
				memcpy(zoomedFrame->getBasePtr(xDest, yDest), heroFrame->getBasePtr(xSource, ySource), 1);
				xDest++;
			} else {
				sprZoomX += _vm->_scaleValue;
				j--;
			}
			xSource++;
		}
		xDest = 0;
		yDest++;
		xSource = 0;
		ySource++;
	}
	return zoomedFrame;
}
예제 #19
0
bool createThumbnail(Graphics::Surface *surf, const uint8 *pixels, int w, int h, const uint8 *palette) {
	assert(surf);

	Graphics::Surface screen;
	screen.create(w, h, 2);

	for (uint y = 0; y < screen.h; ++y) {
		for (uint x = 0; x < screen.w; ++x) {
			byte r, g, b;
			r = palette[pixels[y * w + x] * 3];
			g = palette[pixels[y * w + x] * 3 + 1];
			b = palette[pixels[y * w + x] * 3 + 2];

			((uint16 *)screen.pixels)[y * screen.w + x] = Graphics::RGBToColor<Graphics::ColorMasks<565> >(r, g, b);
		}
	}

	return createThumbnail(*surf, screen);
}
예제 #20
0
bool createThumbnail(Graphics::Surface *surf, const uint8 *pixels, int w, int h, const uint8 *palette) {
	assert(surf);

	Graphics::Surface screen;
	screen.create(w, h, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));

	for (uint y = 0; y < screen.h; ++y) {
		for (uint x = 0; x < screen.w; ++x) {
			byte r, g, b;
			r = palette[pixels[y * w + x] * 3];
			g = palette[pixels[y * w + x] * 3 + 1];
			b = palette[pixels[y * w + x] * 3 + 2];

			*((uint16 *)screen.getBasePtr(x, y)) = Graphics::RGBToColor<Graphics::ColorMasks<565> >(r, g, b);
		}
	}

	return createThumbnail(*surf, screen);
}
예제 #21
0
bool InputControl::process(uint32 deltaTimeInMillis) {
	if (_engine->getScriptManager()->getStateFlag(_key) & Puzzle::DISABLED)
		return false;

	// First see if we need to render the text
	if (_textChanged) {
		// Blit the text using the RenderManager

		Graphics::Surface txt;
		txt.create(_textRectangle.width(), _textRectangle.height(), _engine->_pixelFormat);

		if (!_readOnly || !_focused)
			_txtWidth = _engine->getTextRenderer()->drawTxt(_currentInputText, _stringInit, txt);
		else
			_txtWidth = _engine->getTextRenderer()->drawTxt(_currentInputText, _stringChooserInit, txt);

		_engine->getRenderManager()->blitSurfaceToBkg(txt, _textRectangle.left, _textRectangle.top);

		txt.free();
	}

	if (_animation && !_readOnly && _focused) {
		bool needDraw = true;// = _textChanged;
		_frameDelay -= deltaTimeInMillis;
		if (_frameDelay <= 0) {
			_frame = (_frame + 1) % _animation->frameCount();
			_frameDelay = _animation->frameTime();
			needDraw = true;
		}

		if (needDraw) {
			const Graphics::Surface *srf = _animation->getFrameData(_frame);
			uint32 xx = _textRectangle.left + _txtWidth;
			if (xx >= _textRectangle.left + (_textRectangle.width() - _animation->width()))
				xx = _textRectangle.left + _textRectangle.width() - _animation->width();
			_engine->getRenderManager()->blitSurfaceToBkg(*srf, xx, _textRectangle.top);
		}
	}

	_textChanged = false;
	return false;
}
예제 #22
0
void RenderManager::processSubs(uint16 deltatime) {
	bool redraw = false;
	for (SubtitleMap::iterator it = _subsList.begin(); it != _subsList.end(); it++) {
		if (it->_value.timer != -1) {
			it->_value.timer -= deltatime;
			if (it->_value.timer <= 0)
				it->_value.todelete = true;
		}
		if (it->_value.todelete) {
			_subsList.erase(it);
			redraw = true;
		} else if (it->_value.redraw) {
			redraw = true;
		}
	}

	if (redraw) {
		_subtitleSurface.fillRect(Common::Rect(_subtitleSurface.w, _subtitleSurface.h), 0);

		for (SubtitleMap::iterator it = _subsList.begin(); it != _subsList.end(); it++) {
			OneSubtitle *sub = &it->_value;
			if (sub->txt.size()) {
				Graphics::Surface *rndr = new Graphics::Surface();
				rndr->create(sub->r.width(), sub->r.height(), _engine->_resourcePixelFormat);
				_engine->getTextRenderer()->drawTxtInOneLine(sub->txt, *rndr);
				Common::Rect empty;
				blitSurfaceToSurface(*rndr, empty, _subtitleSurface, sub->r.left - _subtitleArea.left + _workingWindow.left, sub->r.top - _subtitleArea.top + _workingWindow.top);
				rndr->free();
				delete rndr;
			}
			sub->redraw = false;
		}

		Common::Rect rect(
			_subtitleArea.left,
			_subtitleArea.top,
			_subtitleArea.left + _subtitleSurface.w,
			_subtitleArea.top + _subtitleSurface.h
		);
		copyToScreen(_subtitleSurface, rect, 0, 0);
	}
}
예제 #23
0
// TODO: this method will probably go away and be integrated in the main loop
void Animation::play() {
	Common::EventManager *eventMan = g_system->getEventManager();
	while (!hasEnded() && !Engine::shouldQuit()) {
		process();

		if (_changed) {
			// Create a temporary surface to merge the overlay with the background
			Graphics::Surface *s = new Graphics::Surface;
			s->create(640, 480, Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0));

			draw(s);

			// XXX: Update the screen
			g_system->copyRectToScreen(s->getPixels(), s->pitch, 0, 0, s->w, s->h);

			// Free the temporary surface
			s->free();
			delete s;

			_changed = false;
		}

		g_system->updateScreen();

		//FIXME: implement subtitles
		g_system->delayMillis(20);

		// Handle right-click to interrupt animations
		Common::Event ev = Common::Event();
		while (eventMan->pollEvent(ev)) {
			if (ev.type == Common::EVENT_RBUTTONUP) {
				// Stop audio
				if (_audio)
					_audio->finish();

				// TODO start LNK file sound?
				return;
			}
		}
	}
}
예제 #24
0
    const Graphics::Surface& getScreen()
    {
        const Graphics::Surface& srcSurface = (_overlayVisible) ? _overlay : _gameScreen;

        if(srcSurface.w != _screen.w || srcSurface.h != _screen.h)
        {
            _screen.create(srcSurface.w, srcSurface.h, Graphics::PixelFormat(2, 5, 5, 5, 1, 10, 5, 0, 15));
        }

        if(srcSurface.w && srcSurface.h)
        {
            switch(srcSurface.format.bytesPerPixel)
            {
            case 1:
                blit<uint8, uint16>(_screen, srcSurface, 0, 0, _gamePalette, 0xFFFFFFFF);
                break;
            case 2:
                blit<uint16, uint16>(_screen, srcSurface, 0, 0, _gamePalette, 0xFFFFFFFF);
                break;
            case 3:
                blit<uint8, uint16>(_screen, srcSurface, 0, 0, _gamePalette, 0xFFFFFFFF);
                break;
            case 4:
                blit<uint32, uint16>(_screen, srcSurface, 0, 0, _gamePalette, 0xFFFFFFFF);
                break;
            }
        }

        // Draw Mouse
        if(_mouseVisible)
        {
            const int x = _mouseX - _mouseHotspotX;
            const int y = _mouseY - _mouseHotspotY;

            blit<uint8, uint16>(_screen, _mouseImage, x, y, _mousePaletteEnabled ? _mousePalette : _gamePalette, _mouseKeyColor);
        }

        return _screen;
    }
예제 #25
0
bool createScreenShot(Graphics::Surface &surf) {
	Graphics::PixelFormat screenFormat = g_system->getScreenFormat();
	//convert surface to 2 bytes pixel format to avoid problems with palette saving and loading
	if ((screenFormat.bytesPerPixel == 1) || (screenFormat.bytesPerPixel == 2)) {
		return grabScreen565(&surf);
	} else {
		Graphics::Surface *screen = g_system->lockScreen();
		if (!screen) {
			return false;
		}
		surf.create(screen->w, screen->h, Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
		for (uint y = 0; y < screen->h; ++y) {
			for (uint x = 0; x < screen->w; ++x) {
				byte r = 0, g = 0, b = 0, a = 0;
				uint32 col = READ_UINT32(screen->getBasePtr(x, y));
				screenFormat.colorToARGB(col, a, r, g, b);
				*((uint32 *)surf.getBasePtr(x, y)) = Graphics::ARGBToColor<Graphics::ColorMasks<8888> >(a, r, g, b);
			}
		}
		g_system->unlockScreen();
		return true;
	}
}
예제 #26
0
Graphics::Surface *ShaderRenderer::getScreenshot() {
	Common::Rect screen = viewport();

	Graphics::Surface *s = new Graphics::Surface();
	s->create(screen.width(), screen.height(), Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));

#if defined(USE_GLES2)
	GLenum format = GL_UNSIGNED_BYTE;
#else
	GLenum format = GL_UNSIGNED_INT_8_8_8_8_REV;
#endif

	glReadPixels(screen.left, screen.top, screen.width(), screen.height(), GL_RGBA, format, s->getPixels());

#if defined(USE_GLES2) && defined(SCUMM_BIG_ENDIAN)
	// OpenGL ES does not support the GL_UNSIGNED_INT_8_8_8_8_REV texture format, we need to byteswap the surface
	OpenGLTexture::byteswapSurface(s);
#endif

	flipVertical(s);

	return s;
}
예제 #27
0
PaintControl::PaintControl(ZVision *engine, uint32 key, Common::SeekableReadStream &stream)
    : Control(engine, key, CONTROL_PAINT) {

    _cursor = CursorIndex_Active;
    _paint = NULL;
    _bkg = NULL;
    _brush = NULL;
    _colorKey = 0;
    _mouseDown = false;

    // Loop until we find the closing brace
    Common::String line = stream.readLine();
    trimCommentsAndWhiteSpace(&line);
    Common::String param;
    Common::String values;
    getParams(line, param, values);

    while (!stream.eos() && !line.contains('}')) {
        if (param.matchString("rectangle", true)) {
            int x;
            int y;
            int width;
            int height;

            sscanf(values.c_str(), "%d %d %d %d", &x, &y, &width, &height);

            _rectangle = Common::Rect(x, y, width + x, height + y);
        } else if (param.matchString("cursor", true)) {
            _cursor = _engine->getCursorManager()->getCursorId(values);
        } else if (param.matchString("brush_file", true)) {
            _brush = _engine->getRenderManager()->loadImage(values, false);
        } else if (param.matchString("venus_id", true)) {
            _venusId = atoi(values.c_str());
        } else if (param.matchString("paint_file", true)) {
            _paint = _engine->getRenderManager()->loadImage(values, false);
        } else if (param.matchString("eligible_objects", true)) {
            char buf[256];
            memset(buf, 0, 256);
            strcpy(buf, values.c_str());

            char *curpos = buf;
            char *strend = buf + strlen(buf);
            while (true) {
                char *st = curpos;

                if (st >= strend)
                    break;

                while (*curpos != ' ' && curpos < strend)
                    curpos++;

                *curpos = 0;
                curpos++;

                int obj = atoi(st);

                _eligibleObjects.push_back(obj);
            }
        }

        line = stream.readLine();
        trimCommentsAndWhiteSpace(&line);
        getParams(line, param, values);
    }

    if (_paint) {
        _colorKey = _paint->format.RGBToColor(255, 0, 255);
        _bkg = new Graphics::Surface;
        _bkg->create(_rectangle.width(), _rectangle.height(), _paint->format);
        _bkg->fillRect(Common::Rect(_rectangle.width(), _rectangle.height()), _colorKey);

        Graphics::Surface *tmp = new Graphics::Surface;
        tmp->create(_rectangle.width(), _rectangle.height(), _paint->format);
        _engine->getRenderManager()->blitSurfaceToSurface(*_paint, _rectangle, *tmp, 0, 0);
        _paint->free();
        delete _paint;
        _paint = tmp;
    }
}
예제 #28
0
bool VideoManager::updateMovies() {
	bool updateScreen = false;

	for (uint32 i = 0; i < _videoStreams.size() && !_vm->shouldQuit(); i++) {
		// Skip deleted videos
		if (!_videoStreams[i].video)
			continue;

		// Remove any videos that are over
		if (_videoStreams[i].endOfVideo()) {
			if (_videoStreams[i].loop) {
				_videoStreams[i]->seekToTime(_videoStreams[i].start);
			} else {
				// Check the video time one last time before deleting it
				_vm->doVideoTimer(i, true);
				delete _videoStreams[i].video;
				_videoStreams[i].clear();
				continue;
			}
		}

		// Nothing more to do if we're paused
		if (_videoStreams[i]->isPaused())
			continue;

		// Check if we need to draw a frame
		if (_videoStreams[i]->needsUpdate()) {
			const Graphics::Surface *frame = _videoStreams[i]->decodeNextFrame();
			Graphics::Surface *convertedFrame = 0;

			if (frame && _videoStreams[i].enabled) {
				Graphics::PixelFormat pixelFormat = _vm->_system->getScreenFormat();

				// Create (or resize) the off-screen surface
				if (frame->w > _videoStreams[i].surface.w || frame->h > _videoStreams[i].surface.h) {
					_videoStreams[i].surface.create(frame->w, frame->h, pixelFormat);
				}

				// Convert from 8bpp to the current screen format if necessary
				if (frame->format.bytesPerPixel == 1) {
					if (pixelFormat.bytesPerPixel == 1) {
						if (_videoStreams[i]->hasDirtyPalette())
							_videoStreams[i]->setSystemPalette();
					} else {
						convertedFrame = new Graphics::Surface();
						const byte *palette = _videoStreams[i]->getPalette();
						assert(palette);

						convertedFrame->create(frame->w, frame->h, pixelFormat);

						for (uint16 j = 0; j < frame->h; j++) {
							for (uint16 k = 0; k < frame->w; k++) {
								byte palIndex = *((const byte *)frame->getBasePtr(k, j));
								byte r = palette[palIndex * 3];
								byte g = palette[palIndex * 3 + 1];
								byte b = palette[palIndex * 3 + 2];
								if (pixelFormat.bytesPerPixel == 2)
									*((uint16 *)convertedFrame->getBasePtr(k, j)) = pixelFormat.RGBToColor(r, g, b);
								else
									*((uint32 *)convertedFrame->getBasePtr(k, j)) = pixelFormat.RGBToColor(r, g, b);
							}
						}

						frame = convertedFrame;
					}
				}

				// Copy frame to the off-screen surface
				for (int y = 0; y < frame->h; ++y) {
					memcpy(_videoStreams[i].surface.getBasePtr(0, y), frame->getBasePtr(0, y), frame->w * pixelFormat.bytesPerPixel);
				}

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

		// Don't draw anything until we have a valid surface
		if (_videoStreams[i].surface.w == 0 || _videoStreams[i].surface.h == 0) continue;

		// Clip the width/height to make sure we stay on the screen (Myst does this a few times)
		uint16 width = MIN<int32>(_videoStreams[i]->getWidth(), _vm->_system->getWidth() - _videoStreams[i].x);
		uint16 height = MIN<int32>(_videoStreams[i]->getHeight(), _vm->_system->getHeight() - _videoStreams[i].y);

		// Render the off-screen surface
		_vm->_system->copyRectToScreen((byte *)_videoStreams[i].surface.pixels, _videoStreams[i].surface.pitch, _videoStreams[i].x, _videoStreams[i].y, width, height);
		updateScreen = true;

		// Check the video time
		_vm->doVideoTimer(i, false);
	}

	// Return true if we need to update the screen
	return updateScreen;
}
예제 #29
0
BaseSurface *BaseFontTT::renderTextToTexture(const WideString &text, int width, TTextAlign align, int maxHeight, int &textOffset) {
	//TextLineList lines;
	// TODO: Use WideString-conversion here.
	//WrapText(text, width, maxHeight, lines);
	Common::Array<WideString> lines;
	_font->wordWrapText(text, width, lines);

	while (maxHeight > 0 && lines.size() * _lineHeight > maxHeight) {
		lines.pop_back();
	}
	if (lines.size() == 0) {
		return nullptr;
	}

	Graphics::TextAlign alignment = Graphics::kTextAlignInvalid;
	if (align == TAL_LEFT) {
		alignment = Graphics::kTextAlignLeft;
	} else if (align == TAL_CENTER) {
		alignment = Graphics::kTextAlignCenter;
	} else if (align == TAL_RIGHT) {
		alignment = Graphics::kTextAlignRight;
	}

	// TODO: This debug call does not work with WideString because text.c_str() returns an uint32 array.
	//debugC(kWintermuteDebugFont, "%s %d %d %d %d", text.c_str(), RGBCOLGetR(_layers[0]->_color), RGBCOLGetG(_layers[0]->_color), RGBCOLGetB(_layers[0]->_color), RGBCOLGetA(_layers[0]->_color));
//	void drawString(Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true) const;
	Graphics::Surface *surface = new Graphics::Surface();
	surface->create((uint16)width, (uint16)(_lineHeight * lines.size()), _gameRef->_renderer->getPixelFormat());
	uint32 useColor = 0xffffffff;
	Common::Array<WideString>::iterator it;
	int heightOffset = 0;
	for (it = lines.begin(); it != lines.end(); ++it) {
		_font->drawString(surface, *it, 0, heightOffset, width, useColor, alignment);
		heightOffset += (int)_lineHeight;
	}

	BaseSurface *retSurface = _gameRef->_renderer->createSurface();

	if (_deletableFont) {
		// Reconstruct the alpha channel of the font.

		// Since we painted it with color 0xFFFFFFFF onto a black background,
		// the alpha channel is gone, but the color value of each pixel corresponds
		// to its original alpha value.

		Graphics::PixelFormat format = _gameRef->_renderer->getPixelFormat();
		uint32 *pixels = (uint32 *)surface->getPixels();

		// This is a Surface we created ourselves, so no empty space between rows.
		for (int i = 0; i < surface->w * surface->h; ++i) {
			uint8 a, r, g, b;
			format.colorToRGB(*pixels, r, g, b);
			a = r;
			*pixels++ = format.ARGBToColor(a, r, g, b);
		}
	}

	retSurface->putSurface(*surface, true);
	surface->free();
	delete surface;
	return retSurface;
	// TODO: _isUnderline, _isBold, _isItalic, _isStriked
}
예제 #30
0
void ZVision::playVideo(Video::VideoDecoder &vid, const Common::Rect &destRect, bool skippable, Subtitle *sub) {
	Common::Rect dst = destRect;
	// If destRect is empty, no specific scaling was requested. However, we may choose to do scaling anyway
	if (dst.isEmpty())
		dst = Common::Rect(vid.getWidth(), vid.getHeight());

	Graphics::Surface scaled;

	if (vid.getWidth() != dst.width() || vid.getHeight() != dst.height())
		scaled.create(dst.width(), dst.height(), vid.getPixelFormat());

	uint16 x = _workingWindow.left + dst.left;
	uint16 y = _workingWindow.top + dst.top;
	uint16 finalWidth = dst.width() < _workingWindow.width() ? dst.width() : _workingWindow.width();
	uint16 finalHeight = dst.height() < _workingWindow.height() ? dst.height() : _workingWindow.height();
	bool showSubs = (_scriptManager->getStateValue(StateKey_Subtitles) == 1);

	_clock.stop();
	vid.start();
	_videoIsPlaying = true;

	// Only continue while the video is still playing
	while (!shouldQuit() && !vid.endOfVideo() && vid.isPlaying()) {
		// Check for engine quit and video stop key presses
		while (_eventMan->pollEvent(_event)) {
			switch (_event.type) {
			case Common::EVENT_KEYDOWN:
				switch (_event.kbd.keycode) {
				case Common::KEYCODE_q:
					if (_event.kbd.hasFlags(Common::KBD_CTRL))
						quitGame();
					break;
				case Common::KEYCODE_SPACE:
					if (skippable) {
						vid.stop();
					}
					break;
				default:
					break;
				}
			default:
				break;
			}
		}

		if (vid.needsUpdate()) {
			const Graphics::Surface *frame = vid.decodeNextFrame();
			if (sub && showSubs)
				sub->process(vid.getCurFrame());

			if (frame) {
				if (scaled.getPixels()) {
					_renderManager->scaleBuffer(frame->getPixels(), scaled.getPixels(), frame->getWidth(), frame->getHeight(), frame->getFormat().bytesPerPixel, scaled.getWidth(), scaled.getHeight());
					frame = &scaled;
				}
				Common::Rect rect = Common::Rect(x, y, x + finalWidth, y + finalHeight);
				_renderManager->copyToScreen(*frame, rect, 0, 0);
				_renderManager->processSubs(0);
			}
		}

		// Always update the screen so the mouse continues to render
		_system->updateScreen();

		_system->delayMillis(vid.getTimeToNextFrame() / 2);
	}

	_videoIsPlaying = false;
	_clock.start();
}