예제 #1
0
Common::Rect Testsuite::writeOnScreen(const Common::String &textToDisplay, const Common::Point &pt, bool flag) {
	const Graphics::Font &font(*FontMan.getFontByUsage(Graphics::FontManager::kConsoleFont));
	uint fillColor = kColorBlack;
	uint textColor = kColorWhite;

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

	int height = font.getFontHeight();
	int width = screen->w;

	Common::Rect rect(pt.x, pt.y, pt.x + width, pt.y + height);

	if (flag) {
		Graphics::PixelFormat pf = g_system->getScreenFormat();
		fillColor = pf.RGBToColor(0, 0, 0);
		textColor = pf.RGBToColor(255, 255, 255);
	}

	screen->fillRect(rect, fillColor);
	font.drawString(screen, textToDisplay, rect.left, rect.top, screen->w, textColor, Graphics::kTextAlignCenter);

	g_system->unlockScreen();
	g_system->updateScreen();

	return rect;
}
예제 #2
0
SaveStateDescriptor TonyMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
    Common::String saveName;
    byte difficulty;
    byte thumbData[160 * 120 * 2];

    if (Tony::RMOptionScreen::loadThumbnailFromSaveState(slot, thumbData, saveName, difficulty)) {
        // Convert the 565 thumbnail data to the needed overlay format
        Common::MemoryReadStream thumbStream(thumbData, 160 * 120 * 2);
        Graphics::PixelFormat destFormat = g_system->getOverlayFormat();
        Graphics::Surface *to = new Graphics::Surface();
        to->create(160, 120, destFormat);

        OverlayColor *pixels = (OverlayColor *)to->pixels;
        for (int y = 0; y < to->h; ++y) {
            for (int x = 0; x < to->w; ++x) {
                uint8 r, g, b;
                Graphics::colorToRGB<Graphics::ColorMasks<555> >(thumbStream.readUint16LE(), r, g, b);

                // converting to current OSystem Color
                *pixels++ = destFormat.RGBToColor(r, g, b);
            }
        }

        // Create the return descriptor
        SaveStateDescriptor desc(slot, saveName);
        desc.setDeletableFlag(true);
        desc.setWriteProtectedFlag(false);
        desc.setThumbnail(to);

        return desc;
    }

    return SaveStateDescriptor();
}
예제 #3
0
Graphics::Surface *loadThumbnail(Common::SeekableReadStream &in) {
	ThumbnailHeader header;

	if (!loadHeader(in, header, true))
		return 0;

	if (header.bpp != 2) {
		warning("trying to load thumbnail with unsupported bit depth %d", header.bpp);
		return 0;
	}

	Graphics::PixelFormat format = g_system->getOverlayFormat();
	Graphics::Surface *const to = new Graphics::Surface();
	to->create(header.width, header.height, format);

	OverlayColor *pixels = (OverlayColor *)to->pixels;
	for (int y = 0; y < to->h; ++y) {
		for (int x = 0; x < to->w; ++x) {
			uint8 r, g, b;
			colorToRGB<ColorMasks<565> >(in.readUint16BE(), r, g, b);

			// converting to current OSystem Color
			*pixels++ = format.RGBToColor(r, g, b);
		}
	}

	return to;
}
예제 #4
0
bool SavePartSprite::readSprite(const Surface &sprite) {
	// The sprite's dimensions have to fit
	if (((uint32)sprite.getWidth()) != _width)
		return false;
	if (((uint32)sprite.getHeight()) != _height)
		return false;

	if (_trueColor) {
		if (sprite.getBPP() <= 1)
			return false;

		Graphics::PixelFormat pixelFormat = g_system->getScreenFormat();

		byte *data = _dataSprite;
		ConstPixel pixel = sprite.get();
		for (uint32 i = 0; i < (_width * _height); i++, ++pixel, data += 3)
			pixelFormat.colorToRGB(pixel.get(), data[0], data[1], data[2]);

	} else {
		if (sprite.getBPP() != 1)
			return false;

		memcpy(_dataSprite, sprite.getData(), _width * _height);
	}

	return true;
}
예제 #5
0
bool SavePartSprite::writeSprite(Surface &sprite) const {
	// The sprite's dimensions have to fit
	if (((uint32)sprite.getWidth()) != _width)
		return false;
	if (((uint32)sprite.getHeight()) != _height)
		return false;

	if (_trueColor) {
		if (sprite.getBPP() <= 1)
			return false;

		Graphics::PixelFormat pixelFormat = g_system->getScreenFormat();

		const byte *data = _dataSprite;
		Pixel pixel = sprite.get();
		for (uint32 i = 0; i < (_width * _height); i++, ++pixel, data += 3)
			pixel.set(pixelFormat.RGBToColor(data[0], data[1], data[2]));

	} else {
		if (sprite.getBPP() != 1)
			return false;

		memcpy(sprite.getData(), _dataSprite, _spriteSize);
	}

	return true;
}
예제 #6
0
파일: mt32.cpp 프로젝트: agharbi/residual
static void drawMessage(int offset, const Common::String &text) {
	const Graphics::Font &font(*FontMan.getFontByUsage(Graphics::FontManager::kGUIFont));
	Graphics::Surface *screen = g_system->lockScreen();

	assert(screen);
	assert(screen->pixels);

	Graphics::PixelFormat screenFormat = g_system->getScreenFormat();

	uint16 h = font.getFontHeight();
	uint16 y = g_system->getHeight() / 2 - h / 2 + offset * (h + 1);

	uint32 col;

	if (screenFormat.bytesPerPixel > 1)
		col = screenFormat.RGBToColor(0, 0, 0);
	else
		col = 0;

	Common::Rect r(0, y, screen->w, y + h);
	screen->fillRect(r, col);

	if (screenFormat.bytesPerPixel > 1)
		col = screenFormat.RGBToColor(0, 171, 0);
	else
		col = 1;

	font.drawString(screen, text, 0, y, screen->w, col, Graphics::kTextAlignCenter);

	g_system->unlockScreen();
	g_system->updateScreen();
}
예제 #7
0
void BaseAnimationState::buildLookup() {
	// Do we already have lookup tables for this bit format?
	Graphics::PixelFormat format = _sys->getOverlayFormat();
	if (format == _overlayFormat && _colorTab && _rgbToPix)
		return;

	free(_colorTab);
	free(_rgbToPix);

	_colorTab = (int16 *)malloc(4 * 256 * sizeof(int16));

	int16 *Cr_r_tab = &_colorTab[0 * 256];
	int16 *Cr_g_tab = &_colorTab[1 * 256];
	int16 *Cb_g_tab = &_colorTab[2 * 256];
	int16 *Cb_b_tab = &_colorTab[3 * 256];

	_rgbToPix = (OverlayColor *)malloc(3 * 768 * sizeof(OverlayColor));

	OverlayColor *r_2_pix_alloc = &_rgbToPix[0 * 768];
	OverlayColor *g_2_pix_alloc = &_rgbToPix[1 * 768];
	OverlayColor *b_2_pix_alloc = &_rgbToPix[2 * 768];

	int16 CR, CB;
	int i;

	// Generate the tables for the display surface

	for (i = 0; i < 256; i++) {
		// Gamma correction (luminescence table) and chroma correction
		// would be done here. See the Berkeley mpeg_play sources.

		CR = CB = (i - 128);
		Cr_r_tab[i] = (int16) ( (0.419 / 0.299) * CR) + 0 * 768 + 256;
		Cr_g_tab[i] = (int16) (-(0.299 / 0.419) * CR) + 1 * 768 + 256;
		Cb_g_tab[i] = (int16) (-(0.114 / 0.331) * CB);
		Cb_b_tab[i] = (int16) ( (0.587 / 0.331) * CB) + 2 * 768 + 256;
	}

	// Set up entries 0-255 in rgb-to-pixel value tables.
	for (i = 0; i < 256; i++) {
		r_2_pix_alloc[i + 256] = format.RGBToColor(i, 0, 0);
		g_2_pix_alloc[i + 256] = format.RGBToColor(0, i, 0);
		b_2_pix_alloc[i + 256] = format.RGBToColor(0, 0, i);
	}

	// Spread out the values we have to the rest of the array so that we do
	// not need to check for overflow.
	for (i = 0; i < 256; i++) {
		r_2_pix_alloc[i] = r_2_pix_alloc[256];
		r_2_pix_alloc[i + 512] = r_2_pix_alloc[511];
		g_2_pix_alloc[i] = g_2_pix_alloc[256];
		g_2_pix_alloc[i + 512] = g_2_pix_alloc[511];
		b_2_pix_alloc[i] = b_2_pix_alloc[256];
		b_2_pix_alloc[i + 512] = b_2_pix_alloc[511];
	}

	_overlayFormat = format;
}
예제 #8
0
파일: mt32.cpp 프로젝트: agharbi/residual
int MidiDriver_MT32::open() {
	MT32Emu::SynthProperties prop;

	if (_isOpen)
		return MERR_ALREADY_OPEN;

	MidiDriver_Emulated::open();

	memset(&prop, 0, sizeof(prop));
	prop.sampleRate = getRate();
	prop.useReverb = true;
	prop.useDefaultReverb = false;
	prop.reverbType = 0;
	prop.reverbTime = 5;
	prop.reverbLevel = 3;
	prop.userData = this;
	prop.printDebug = MT32_PrintDebug;
	prop.report = MT32_Report;
	prop.openFile = MT32_OpenFile;

	_synth = new MT32Emu::Synth();

	Graphics::PixelFormat screenFormat = g_system->getScreenFormat();

	if (screenFormat.bytesPerPixel == 1) {
		const byte dummy_palette[] = {
			0, 0, 0,		// background
			0, 171, 0,	// border, font
			171, 0, 0	// fill
		};

		g_system->getPaletteManager()->setPalette(dummy_palette, 0, 3);
	}

	_initializing = true;
	drawMessage(-1, _s("Initializing MT-32 Emulator"));
	if (!_synth->open(prop))
		return MERR_DEVICE_NOT_AVAILABLE;

	double gain = (double)ConfMan.getInt("midi_gain") / 100.0;
	_synth->setOutputGain(1.0f * gain);
	_synth->setReverbOutputGain(0.68f * gain);

	_initializing = false;

	if (screenFormat.bytesPerPixel > 1)
		g_system->fillScreen(screenFormat.RGBToColor(0, 0, 0));
	else
		g_system->fillScreen(0);

	g_system->updateScreen();

	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_mixerSoundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);

	return 0;
}
예제 #9
0
void Surface::shadeRect(uint16 left, uint16 top, uint16 right, uint16 bottom,
		uint32 color, uint8 strength) {

	if (_bpp == 1) {
		// We can't properly shade in paletted mode, fill the rect instead
		fillRect(left, top, right, bottom, color);
		return;
	}

	// Just in case those are swapped
	if (left > right)
		SWAP(left, right);
	if (top  > bottom)
		SWAP(top, bottom);

	if ((left >= _width) || (top >= _height))
		// Nothing to do
		return;

	// Area to actually shade
	uint16 width  = CLIP<int32>(right  - left + 1, 0, _width  - left);
	uint16 height = CLIP<int32>(bottom - top  + 1, 0, _height - top);

	if ((width == 0) || (height == 0))
		// Nothing to do
		return;

	Graphics::PixelFormat pixelFormat = g_system->getScreenFormat();

	uint8 cR, cG, cB;
	pixelFormat.colorToRGB(color, cR, cG, cB);

	int shadeR = cR * (16 - strength);
	int shadeG = cG * (16 - strength);
	int shadeB = cB * (16 - strength);

	Pixel p = get(left, top);
	while (height-- > 0) {
		for (uint16 i = 0; i < width; i++, ++p) {
			uint8 r, g, b;

			pixelFormat.colorToRGB(p.get(), r, g, b);

			r = CLIP<int>((shadeR + strength * r) >> 4, 0, 255);
			g = CLIP<int>((shadeG + strength * g) >> 4, 0, 255);
			b = CLIP<int>((shadeB + strength * b) >> 4, 0, 255);

			p.set(pixelFormat.RGBToColor(r, g, b));
		}

		p += _width - width;
	}

}
예제 #10
0
void VisualExplodingImage::ExplosionUnit::setColor(uint32 color, const Graphics::PixelFormat &format) {
	_mainColor = color;

	byte a, r, g, b;
	format.colorToARGB(color, a, r, g, b);
	r >>= 1;
	g >>= 1;
	b >>= 1;

	_darkColor = format.ARGBToColor(a, r, g, b);
}
bool VirtualKeyboardParser::parserCallback_layout(ParserNode *node) {
	assert(!_mode->resolution.empty());

	String res = node->values["resolution"];

	if (res != _mode->resolution) {
		node->ignore = true;
		return true;
	}

	_mode->bitmapName = node->values["bitmap"];

	SeekableReadStream *file = _keyboard->_fileArchive->createReadStreamForMember(_mode->bitmapName);
	if (!file)
		return parserError("Bitmap '" + _mode->bitmapName + "' not found");

	const Graphics::PixelFormat format = g_system->getOverlayFormat();

	{
		Graphics::BitmapDecoder bmp;
		if (!bmp.loadStream(*file))
			return parserError("Error loading bitmap '" + _mode->bitmapName + "'");

		_mode->image = bmp.getSurface()->convertTo(format);
	}

	delete file;

	int r, g, b;
	if (node->values.contains("transparent_color")) {
		if (!parseIntegerKey(node->values["transparent_color"], 3, &r, &g, &b))
			return parserError("Could not parse color value");
	} else {
		// default to purple
		r = 255;
		g = 0;
		b = 255;
	}
	_mode->transparentColor = format.RGBToColor(r, g, b);

	if (node->values.contains("display_font_color")) {
		if (!parseIntegerKey(node->values["display_font_color"], 3, &r, &g, &b))
			return parserError("Could not parse color value");
	} else {
		r = g = b = 0; // default to black
	}
	_mode->displayFontColor = format.RGBToColor(r, g, b);

	_layoutParsed = true;

	return true;
}
예제 #12
0
파일: mt32.cpp 프로젝트: SinSiXX/scummvm
int MidiDriver_MT32::open() {
	if (_isOpen)
		return MERR_ALREADY_OPEN;

	MidiDriver_Emulated::open();
	_reportHandler = new MT32Emu::ReportHandlerScummVM();
	_synth = new MT32Emu::Synth(_reportHandler);

	Graphics::PixelFormat screenFormat = g_system->getScreenFormat();

	if (screenFormat.bytesPerPixel == 1) {
		const byte dummy_palette[] = {
			0, 0, 0,		// background
			0, 171, 0,	// border, font
			171, 0, 0	// fill
		};

		g_system->getPaletteManager()->setPalette(dummy_palette, 0, 3);
	}

	_initializing = true;
	debug(4, _s("Initializing MT-32 Emulator"));
	_controlFile = new Common::File();
	if (!_controlFile->open("MT32_CONTROL.ROM") && !_controlFile->open("CM32L_CONTROL.ROM"))
		error("Error opening MT32_CONTROL.ROM / CM32L_CONTROL.ROM");
	_pcmFile = new Common::File();
	if (!_pcmFile->open("MT32_PCM.ROM") && !_pcmFile->open("CM32L_PCM.ROM"))
		error("Error opening MT32_PCM.ROM / CM32L_PCM.ROM");
	_controlROM = MT32Emu::ROMImage::makeROMImage(_controlFile);
	_pcmROM = MT32Emu::ROMImage::makeROMImage(_pcmFile);
	if (!_synth->open(*_controlROM, *_pcmROM))
		return MERR_DEVICE_NOT_AVAILABLE;

	double gain = (double)ConfMan.getInt("midi_gain") / 100.0;
	_synth->setOutputGain(1.0f * gain);
	_synth->setReverbOutputGain(0.68f * gain);

	_initializing = false;

	if (screenFormat.bytesPerPixel > 1)
		g_system->fillScreen(screenFormat.RGBToColor(0, 0, 0));
	else
		g_system->fillScreen(0);

	g_system->updateScreen();

	_mixer->playStream(Audio::Mixer::kPlainSoundType, &_mixerSoundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);

	return 0;
}
예제 #13
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;
}
예제 #14
0
YUVToRGBLookup::YUVToRGBLookup(Graphics::PixelFormat format) {
	_colorTab = new int16[4 * 256]; // 2048 bytes

	int16 *Cr_r_tab = &_colorTab[0 * 256];
	int16 *Cr_g_tab = &_colorTab[1 * 256];
	int16 *Cb_g_tab = &_colorTab[2 * 256];
	int16 *Cb_b_tab = &_colorTab[3 * 256];

	_rgbToPix = new uint32[3 * 768]; // 9216 bytes

	uint32 *r_2_pix_alloc = &_rgbToPix[0 * 768];
	uint32 *g_2_pix_alloc = &_rgbToPix[1 * 768];
	uint32 *b_2_pix_alloc = &_rgbToPix[2 * 768];

	int16 CR, CB;
	int i;

	// Generate the tables for the display surface

	for (i = 0; i < 256; i++) {
		// Gamma correction (luminescence table) and chroma correction
		// would be done here. See the Berkeley mpeg_play sources.

		CR = CB = (i - 128);
		Cr_r_tab[i] = (int16) ( (0.419 / 0.299) * CR) + 0 * 768 + 256;
		Cr_g_tab[i] = (int16) (-(0.299 / 0.419) * CR) + 1 * 768 + 256;
		Cb_g_tab[i] = (int16) (-(0.114 / 0.331) * CB);
		Cb_b_tab[i] = (int16) ( (0.587 / 0.331) * CB) + 2 * 768 + 256;
	}

	// Set up entries 0-255 in rgb-to-pixel value tables.
	for (i = 0; i < 256; i++) {
		r_2_pix_alloc[i + 256] = format.RGBToColor(i, 0, 0);
		g_2_pix_alloc[i + 256] = format.RGBToColor(0, i, 0);
		b_2_pix_alloc[i + 256] = format.RGBToColor(0, 0, i);
	}

	// Spread out the values we have to the rest of the array so that we do
	// not need to check for overflow.
	for (i = 0; i < 256; i++) {
		r_2_pix_alloc[i] = r_2_pix_alloc[256];
		r_2_pix_alloc[i + 512] = r_2_pix_alloc[511];
		g_2_pix_alloc[i] = g_2_pix_alloc[256];
		g_2_pix_alloc[i + 512] = g_2_pix_alloc[511];
		b_2_pix_alloc[i] = b_2_pix_alloc[256];
		b_2_pix_alloc[i + 512] = b_2_pix_alloc[511];
	}
}
예제 #15
0
void MystCursorManager::setCursor(uint16 id) {
	// Zero means empty cursor
	if (id == 0) {
		static const byte emptyCursor[4] = { 0, 0, 0, 0 };
		CursorMan.replaceCursor(&emptyCursor, 2, 2, 0, 0, 0);
		return;
	}

	// Both Myst and Myst ME use the "MystBitmap" format for cursor images.
	MohawkSurface *mhkSurface = _bmpDecoder->decodeImage(_vm->getResource(ID_WDIB, id));
	Graphics::Surface *surface = mhkSurface->getSurface();
	Common::SeekableReadStream *clrcStream = _vm->getResource(ID_CLRC, id);
	uint16 hotspotX = clrcStream->readUint16LE();
	uint16 hotspotY = clrcStream->readUint16LE();
	delete clrcStream;

	// Myst ME stores some cursors as 24bpp images instead of 8bpp
	if (surface->format.bytesPerPixel == 1) {
		CursorMan.replaceCursor(surface->getPixels(), surface->w, surface->h, hotspotX, hotspotY, 0);
		CursorMan.replaceCursorPalette(mhkSurface->getPalette(), 0, 256);
	} else {
		Graphics::PixelFormat pixelFormat = g_system->getScreenFormat();
		CursorMan.replaceCursor(surface->getPixels(), surface->w, surface->h, hotspotX, hotspotY, pixelFormat.RGBToColor(255, 255, 255), false, &pixelFormat);
	}

	_vm->_needsUpdate = true;
	delete mhkSurface;
}
예제 #16
0
void GraphicsWidget::setGfx(int w, int h, int r, int g, int b) {
    if (w == -1)
        w = _w;
    if (h == -1)
        h = _h;

    _gfx.free();
    _gfx.create(w, h, sizeof(OverlayColor));

    OverlayColor *dst = (OverlayColor *)_gfx.pixels;
    Graphics::PixelFormat overlayFormat = g_system->getOverlayFormat();
    OverlayColor fillCol = overlayFormat.RGBToColor(r, g, b);
    while (h--) {
        for (int i = 0; i < w; ++i) {
            *dst++ = fillCol;
        }
    }
}
예제 #17
0
/**
 * Copies the current screen contents to a new surface, using RGB565 format.
 * WARNING: surf->free() must be called by the user to avoid leaking.
 *
 * @param surf      the surface to store the data in it
 */
static bool grabScreen565(Graphics::Surface *surf) {
	Graphics::Surface *screen = g_system->lockScreen();
	if (!screen)
		return false;

	assert(screen->format.bytesPerPixel == 1 || screen->format.bytesPerPixel == 2);
	assert(screen->getPixels() != 0);

	Graphics::PixelFormat screenFormat = g_system->getScreenFormat();

	surf->create(screen->w, screen->h, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));

	byte *palette = 0;
	if (screenFormat.bytesPerPixel == 1) {
		palette = new byte[256 * 3];
		assert(palette);
		g_system->getPaletteManager()->grabPalette(palette, 0, 256);
	}

	for (uint y = 0; y < screen->h; ++y) {
		for (uint x = 0; x < screen->w; ++x) {
			byte r = 0, g = 0, b = 0;

			if (screenFormat.bytesPerPixel == 1) {
				uint8 pixel = *(uint8 *)screen->getBasePtr(x, y);
				r = palette[pixel * 3 + 0];
				g = palette[pixel * 3 + 1];
				b = palette[pixel * 3 + 2];
			} else if (screenFormat.bytesPerPixel == 2) {
				uint16 col = READ_UINT16(screen->getBasePtr(x, y));
				screenFormat.colorToRGB(col, r, g, b);
			}

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

	delete[] palette;

	g_system->unlockScreen();
	return true;
}
예제 #18
0
bool ImgLoader::decodeThumbnailImage(const byte *pFileData, uint fileSize, byte *&pUncompressedData, int &width, int &height, int &pitch) {
	const byte *src = pFileData + 4;	// skip header
	width = READ_LE_UINT16(src); src += 2;
	height = READ_LE_UINT16(src); src += 2;
	src++;	// version, ignored for now
	pitch = width * 4;

	uint32 totalSize = pitch * height;
	pUncompressedData = new byte[totalSize];
	uint32 *dst = (uint32 *)pUncompressedData;	// treat as uint32, for pixelformat output
	const Graphics::PixelFormat format = Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24);
	byte r, g, b;

	for (uint32 i = 0; i < totalSize / 4; i++) {
		r = *src++;
		g = *src++;
		b = *src++;
		*dst++ = format.RGBToColor(r, g, b);
	}

	return true;
}
예제 #19
0
파일: mt32.cpp 프로젝트: agharbi/residual
static void drawProgress(float progress) {
	const Graphics::Font &font(*FontMan.getFontByUsage(Graphics::FontManager::kGUIFont));
	Graphics::Surface *screen = g_system->lockScreen();

	assert(screen);
	assert(screen->pixels);

	Graphics::PixelFormat screenFormat = g_system->getScreenFormat();

	int16 w = g_system->getWidth() / 7 * 5;
	int16 h = font.getFontHeight();
	int16 x = g_system->getWidth() / 7;
	int16 y = g_system->getHeight() / 2 - h / 2;

	Common::Rect r(x, y, x + w, y + h);

	uint32 col;

	if (screenFormat.bytesPerPixel > 1)
		col = screenFormat.RGBToColor(0, 171, 0);
	else
		col = 1;

	screen->frameRect(r, col);

	r.grow(-1);
	r.setWidth(uint16(progress * w));

	if (screenFormat.bytesPerPixel > 1)
		col = screenFormat.RGBToColor(171, 0, 0);
	else
		col = 2;

	screen->fillRect(r, col);

	g_system->unlockScreen();
	g_system->updateScreen();
}
예제 #20
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;
	}
}
예제 #21
0
void MystCursorManager::setCursor(uint16 id) {
	// Zero means empty cursor
	if (id == 0) {
		static const byte emptyCursor[4] = { 0, 0, 0, 0 };
		CursorMan.replaceCursor(&emptyCursor, 2, 2, 0, 0, 0);
		return;
	}

	Common::SeekableReadStream *clrcStream = _vm->getResource(ID_CLRC, id);
	uint16 hotspotX = clrcStream->readUint16LE();
	uint16 hotspotY = clrcStream->readUint16LE();
	delete clrcStream;

	// Both Myst and Myst ME use the "MystBitmap" format for cursor images.
	MohawkSurface *mhkSurface = _vm->_gfx->findImage(id);
	Graphics::Surface *surface = mhkSurface->getSurface();

	// Myst ME stores some cursors as 24bpp images instead of 8bpp
	if (surface->format.bytesPerPixel == 1) {
		// The transparent color is almost always 255, except for the main cursor (100)
		// in the D'ni archive, where it is 0.
		// Using the color of the first pixel as the transparent color for the main cursor always works.
		byte transparentColor;
		if (id == kDefaultMystCursor) {
			transparentColor = ((byte *)surface->getPixels())[0];
		} else {
			transparentColor = 255;
		}
		CursorMan.replaceCursor(surface->getPixels(), surface->w, surface->h, hotspotX, hotspotY, transparentColor);

		// We're using the screen palette for the original game, but we need
		// to use this for any 8bpp cursor in ME.
		if (_vm->getFeatures() & GF_ME)
			CursorMan.replaceCursorPalette(mhkSurface->getPalette(), 0, 256);
	} else {
		Graphics::PixelFormat pixelFormat = g_system->getScreenFormat();
		CursorMan.replaceCursor(surface->getPixels(), surface->w, surface->h, hotspotX, hotspotY, pixelFormat.RGBToColor(255, 255, 255), false, &pixelFormat);
	}
}
예제 #22
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;
}
예제 #23
0
파일: pcx.cpp 프로젝트: AReim1982/scummvm
bool PCXDecoder::loadStream(Common::SeekableReadStream &stream) {
	destroy();

	if (stream.readByte() != 0x0a)	// ZSoft PCX
		return false;

	byte version = stream.readByte();	// 0 - 5
	if (version > 5)
		return false;

	bool compressed = stream.readByte(); // encoding, 1 = run length encoding
	byte bitsPerPixel = stream.readByte();	// 1, 2, 4 or 8

	// Window
	uint16 xMin = stream.readUint16LE();
	uint16 yMin = stream.readUint16LE();
	uint16 xMax = stream.readUint16LE();
	uint16 yMax = stream.readUint16LE();

	uint16 width  = xMax - xMin + 1;
	uint16 height = yMax - yMin + 1;

	if (xMax < xMin || yMax < yMin) {
		warning("Invalid PCX image dimensions");
		return false;
	}

	stream.skip(4);	// HDpi, VDpi

	// Read the EGA palette (colormap)
	_palette = new byte[16 * 3];
	for (uint16 i = 0; i < 16; i++) {
		_palette[i * 3 + 0] = stream.readByte();
		_palette[i * 3 + 1] = stream.readByte();
		_palette[i * 3 + 2] = stream.readByte();
	}

	if (stream.readByte() != 0)	// reserved, should be set to 0
		return false;

	byte nPlanes = stream.readByte();
	uint16 bytesPerLine = stream.readUint16LE();
	uint16 bytesPerscanLine = nPlanes * bytesPerLine;

	if (bytesPerscanLine < width * bitsPerPixel * nPlanes / 8) {
		warning("PCX data is corrupted");
		return false;
	}

	stream.skip(60);	// PaletteInfo, HscreenSize, VscreenSize, Filler

	_surface = new Graphics::Surface();

	byte *scanLine = new byte[bytesPerscanLine];
	byte *dst;
	int x, y;

	if (nPlanes == 3 && bitsPerPixel == 8) {	// 24bpp
		Graphics::PixelFormat format = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
		_surface->create(width, height, format);
		dst = (byte *)_surface->getPixels();
		_paletteColorCount = 0;

		for (y = 0; y < height; y++) {
			decodeRLE(stream, scanLine, bytesPerscanLine, compressed);

			for (x = 0; x < width; x++) {
				byte b = scanLine[x];
				byte g = scanLine[x +  bytesPerLine];
				byte r = scanLine[x + (bytesPerLine << 1)];
				uint32 color = format.RGBToColor(r, g, b);

				*((uint32 *)dst) = color;
				dst += format.bytesPerPixel;
			}
		}
	} else if (nPlanes == 1 && bitsPerPixel == 8) {	// 8bpp indexed
		_surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8());
		dst = (byte *)_surface->getPixels();
		_paletteColorCount = 16;

		for (y = 0; y < height; y++, dst += _surface->pitch) {
			decodeRLE(stream, scanLine, bytesPerscanLine, compressed);
			memcpy(dst, scanLine, width);
		}

		if (version == 5) {
			if (stream.readByte() != 12) {
				warning("Expected a palette after the PCX image data");
				delete[] scanLine;
				return false;
			}

			// Read the VGA palette
			delete[] _palette;
			_palette = new byte[256 * 3];
			for (uint16 i = 0; i < 256; i++) {
				_palette[i * 3 + 0] = stream.readByte();
				_palette[i * 3 + 1] = stream.readByte();
				_palette[i * 3 + 2] = stream.readByte();
			}

			_paletteColorCount = 256;
		}
	} else if ((nPlanes == 2 || nPlanes == 3 || nPlanes == 4) && bitsPerPixel == 1) {	// planar, 4, 8 or 16 colors
		_surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8());
		dst = (byte *)_surface->getPixels();
		_paletteColorCount = 16;

		for (y = 0; y < height; y++, dst += _surface->pitch) {
			decodeRLE(stream, scanLine, bytesPerscanLine, compressed);

			for (x = 0; x < width; x++) {
				int m = 0x80 >> (x & 7), v = 0;
				for (int i = nPlanes - 1; i >= 0; i--) {
					v <<= 1;
					v  += (scanLine[i * bytesPerLine + (x >> 3)] & m) == 0 ? 0 : 1;
				}
				dst[x] = v;
			}
		}
	} else {
예제 #24
0
// Function to blit a rect from one color format to another
bool crossBlit(byte *dst, const byte *src, int dstpitch, int srcpitch,
						int w, int h, const Graphics::PixelFormat &dstFmt, const Graphics::PixelFormat &srcFmt) {
	// Error out if conversion is impossible
	if ((srcFmt.bytesPerPixel == 1) || (dstFmt.bytesPerPixel == 1)
			 || (!srcFmt.bytesPerPixel) || (!dstFmt.bytesPerPixel)
			 || (srcFmt.bytesPerPixel > dstFmt.bytesPerPixel))
		return false;

	// Don't perform unnecessary conversion
	if (srcFmt == dstFmt) {
		if (dst == src)
			return true;
		if (dstpitch == srcpitch && ((w * dstFmt.bytesPerPixel) == dstpitch)) {
			memcpy(dst,src,dstpitch * h);
			return true;
		} else {
			for (int i = 0; i < h; i++) {
				memcpy(dst,src,w * dstFmt.bytesPerPixel);
				dst += dstpitch;
				src += srcpitch;
			}
			return true;
		}
	}

	// Faster, but larger, to provide optimized handling for each case.
	int srcDelta, dstDelta;
	srcDelta = (srcpitch - w * srcFmt.bytesPerPixel);
	dstDelta = (dstpitch - w * dstFmt.bytesPerPixel);

	// TODO: optimized cases for dstDelta of 0
	uint8 r, g, b, a;
	if (dstFmt.bytesPerPixel == 2) {
		uint16 color;
		for (int y = 0; y < h; y++) {
			for (int x = 0; x < w; x++, src += 2, dst += 2) {
				color = *(const uint16 *)src;
				srcFmt.colorToARGB(color, a, r, g, b);
				color = dstFmt.ARGBToColor(a, r, g, b);
				*(uint16 *)dst = color;
			}
			src += srcDelta;
			dst += dstDelta;
		}
	} else if (dstFmt.bytesPerPixel == 3) {
		uint32 color;
		uint8 *col = (uint8 *) &color;
#ifdef SCUMM_BIG_ENDIAN
		col++;
#endif
		if (srcFmt.bytesPerPixel == 2) {
			for (int y = 0; y < h; y++) {
				for (int x = 0; x < w; x++, src += 2, dst += 3) {
					color = *(const uint16 *)src;
					srcFmt.colorToARGB(color, a, r, g, b);
					color = dstFmt.ARGBToColor(a, r, g, b);
					memcpy(dst, col, 3);
				}
				src += srcDelta;
				dst += dstDelta;
			}
		} else {
			for (int y = 0; y < h; y++) {
				for (int x = 0; x < w; x++, src += 3, dst += 3) {
					memcpy(col, src, 3);
					srcFmt.colorToARGB(color, a, r, g, b);
					color = dstFmt.ARGBToColor(a, r, g, b);
					memcpy(dst, col, 3);
				}
				src += srcDelta;
				dst += dstDelta;
			}
		}
	} else if (dstFmt.bytesPerPixel == 4) {
		uint32 color;
		if (srcFmt.bytesPerPixel == 2) {
			for (int y = 0; y < h; y++) {
				for (int x = 0; x < w; x++, src += 2, dst += 4) {
					color = *(const uint16 *)src;
					srcFmt.colorToARGB(color, a, r, g, b);
					color = dstFmt.ARGBToColor(a, r, g, b);
					*(uint32 *)dst = color;
				}
				src += srcDelta;
				dst += dstDelta;
			}
		} else if (srcFmt.bytesPerPixel == 3) {
			uint8 *col = (uint8 *)&color;
#ifdef SCUMM_BIG_ENDIAN
			col++;
#endif
			for (int y = 0; y < h; y++) {
				for (int x = 0; x < w; x++, src += 2, dst += 4) {
					memcpy(col, src, 3);
					srcFmt.colorToARGB(color, a, r, g, b);
					color = dstFmt.ARGBToColor(a, r, g, b);
					*(uint32 *)dst = color;
				}
				src += srcDelta;
				dst += dstDelta;
			}
		} else {
			for (int y = 0; y < h; y++) {
				for (int x = 0; x < w; x++, src += 4, dst += 4) {
					color = *(const uint32 *)src;
					srcFmt.colorToARGB(color, a, r, g, b);
					color = dstFmt.ARGBToColor(a, r, g, b);
					*(uint32 *)dst = color;
				}
				src += srcDelta;
				dst += dstDelta;
			}
		}
	} else {
		return false;
	}
	return true;
}
예제 #25
0
void OpenGLGraphicsManager::setMouseCursor(const void *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, bool dontScale, const Graphics::PixelFormat *format) {
	Graphics::PixelFormat inputFormat;
#ifdef USE_RGB_COLOR
	if (format) {
		inputFormat = *format;
	} else {
		inputFormat = Graphics::PixelFormat::createFormatCLUT8();
	}
#else
	inputFormat = Graphics::PixelFormat::createFormatCLUT8();
#endif

	// In case the color format has changed we will need to create the texture.
	if (!_cursor || _cursor->getFormat() != inputFormat) {
		delete _cursor;
		_cursor = nullptr;

		GLenum glIntFormat, glFormat, glType;

		Graphics::PixelFormat textureFormat;
		if (inputFormat.bytesPerPixel == 1 || (inputFormat.aBits() && getGLPixelFormat(inputFormat, glIntFormat, glFormat, glType))) {
			// There is two cases when we can use the cursor format directly.
			// The first is when it's CLUT8, here color key handling can
			// always be applied because we use the alpha channel of
			// _defaultFormatAlpha for that.
			// The other is when the input format has alpha bits and
			// furthermore is directly supported.
			textureFormat = inputFormat;
		} else {
			textureFormat = _defaultFormatAlpha;
		}
		_cursor = createTexture(textureFormat, true);
		assert(_cursor);
		_cursor->enableLinearFiltering(_currentState.graphicsMode == GFX_LINEAR);
	}

	_cursorKeyColor = keycolor;
	_cursorHotspotX = hotspotX;
	_cursorHotspotY = hotspotY;
	_cursorDontScale = dontScale;

	_cursor->allocate(w, h);
	if (inputFormat.bytesPerPixel == 1) {
		// For CLUT8 cursors we can simply copy the input data into the
		// texture.
		_cursor->copyRectToTexture(0, 0, w, h, buf, w * inputFormat.bytesPerPixel);
	} else {
		// Otherwise it is a bit more ugly because we have to handle a key
		// color properly.

		Graphics::Surface *dst = _cursor->getSurface();
		const uint srcPitch = w * inputFormat.bytesPerPixel;

		// Copy the cursor data to the actual texture surface. This will make
		// sure that the data is also converted to the expected format.
		Graphics::crossBlit((byte *)dst->getPixels(), (const byte *)buf, dst->pitch, srcPitch,
		                    w, h, dst->format, inputFormat);

		// We apply the color key by setting the alpha bits of the pixels to
		// fully transparent.
		const uint32 aMask = (0xFF >> dst->format.aLoss) << dst->format.aShift;
		if (dst->format.bytesPerPixel == 2) {
			if (inputFormat.bytesPerPixel == 2) {
				applyColorKey<uint16, uint16>((uint16 *)dst->getPixels(), (const uint16 *)buf, w, h,
				                              dst->pitch, srcPitch, keycolor, aMask);
			} else if (inputFormat.bytesPerPixel == 4) {
				applyColorKey<uint16, uint32>((uint16 *)dst->getPixels(), (const uint32 *)buf, w, h,
				                              dst->pitch, srcPitch, keycolor, aMask);
			}
		} else {
			if (inputFormat.bytesPerPixel == 2) {
				applyColorKey<uint32, uint16>((uint32 *)dst->getPixels(), (const uint16 *)buf, w, h,
				                              dst->pitch, srcPitch, keycolor, aMask);
			} else if (inputFormat.bytesPerPixel == 4) {
				applyColorKey<uint32, uint32>((uint32 *)dst->getPixels(), (const uint32 *)buf, w, h,
				                              dst->pitch, srcPitch, keycolor, aMask);
			}
		}

		// Flag the texture as dirty.
		_cursor->flagDirty();
	}

	// In case we actually use a palette set that up properly.
	if (inputFormat.bytesPerPixel == 1) {
		updateCursorPalette();
	}

	// Update the scaling.
	recalculateCursorScaling();
}
예제 #26
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
}
예제 #27
0
bool UIWindow::display(int offsetX, int offsetY) {
	// go exclusive
	if (_mode == WINDOW_EXCLUSIVE || _mode == WINDOW_SYSTEM_EXCLUSIVE) {
		if (!_shieldWindow) {
			_shieldWindow = new UIWindow(_gameRef);
		}
		if (_shieldWindow) {
			_shieldWindow->_posX = _shieldWindow->_posY = 0;
			_shieldWindow->_width = _gameRef->_renderer->getWidth();
			_shieldWindow->_height = _gameRef->_renderer->getHeight();

			_shieldWindow->display();
		}
	} else if (_isMenu) {
		if (!_shieldButton) {
			_shieldButton = new UIButton(_gameRef);
			_shieldButton->setName("close");
			_shieldButton->setListener(this, _shieldButton, 0);
			_shieldButton->_parent = this;
		}
		if (_shieldButton) {
			_shieldButton->_posX = _shieldButton->_posY = 0;
			_shieldButton->setWidth(_gameRef->_renderer->getWidth());
			_shieldButton->setHeight(_gameRef->_renderer->getHeight());

			_shieldButton->display();
		}
	}

	if (!_visible) {
		return STATUS_OK;
	}

	if (_fadeBackground) {
		Graphics::PixelFormat format = _gameRef->_renderer->getPixelFormat();
		byte fadeR, fadeG, fadeB, fadeA;
		// First convert from the internal format to the screen-format
		uint32 fadeColor = format.ARGBToColor(RGBCOLGetA(_fadeColor), RGBCOLGetR(_fadeColor), RGBCOLGetG(_fadeColor), RGBCOLGetB(_fadeColor));
		// Then get components
		format.colorToARGB(fadeColor, fadeA, fadeR, fadeG, fadeB);
		_gameRef->_renderer->fadeToColor(fadeR, fadeG, fadeB, fadeA);
	}

	if (_dragging) {
		_posX += (_gameRef->_mousePos.x - _dragFrom.x);
		_posY += (_gameRef->_mousePos.y - _dragFrom.y);

		_dragFrom.x = _gameRef->_mousePos.x;
		_dragFrom.y = _gameRef->_mousePos.y;
	}

	if (!_focusedWidget || (!_focusedWidget->canFocus() || _focusedWidget->isDisabled() || !_focusedWidget->isVisible())) {
		moveFocus();
	}

	bool popViewport = false;
	if (_clipContents) {
		if (!_viewport) {
			_viewport = new BaseViewport(_gameRef);
		}
		if (_viewport) {
			_viewport->setRect(_posX + offsetX, _posY + offsetY, _posX + _width + offsetX, _posY + _height + offsetY);
			_gameRef->pushViewport(_viewport);
			popViewport = true;
		}
	}


	UITiledImage *back = _back;
	BaseSprite *image = _image;
	BaseFont *font = _font;

	if (!isFocused()) {
		if (_backInactive) {
			back = _backInactive;
		}
		if (_imageInactive) {
			image = _imageInactive;
		}
		if (_fontInactive) {
			font = _fontInactive;
		}
	}

	if (_alphaColor != 0) {
		_gameRef->_renderer->_forceAlphaColor = _alphaColor;
	}
	if (back) {
		back->display(_posX + offsetX, _posY + offsetY, _width, _height);
	}
	if (image) {
		image->draw(_posX + offsetX, _posY + offsetY, _transparent ? nullptr : this);
	}

	if (!BasePlatform::isRectEmpty(&_titleRect) && font && _text) {
		font->drawText((byte *)_text, _posX + offsetX + _titleRect.left, _posY + offsetY + _titleRect.top, _titleRect.right - _titleRect.left, _titleAlign, _titleRect.bottom - _titleRect.top);
	}

	if (!_transparent && !image) {
		_gameRef->_renderer->addRectToList(new BaseActiveRect(_gameRef,  this, nullptr, _posX + offsetX, _posY + offsetY, _width, _height, 100, 100, false));
	}

	for (uint32 i = 0; i < _widgets.size(); i++) {
		_widgets[i]->display(_posX + offsetX, _posY + offsetY);
	}

	if (_alphaColor != 0) {
		_gameRef->_renderer->_forceAlphaColor = 0;
	}

	if (popViewport) {
		_gameRef->popViewport();
	}

	return STATUS_OK;
}
예제 #28
0
파일: mt32.cpp 프로젝트: CrazyMax/scummvm
int MidiDriver_MT32::open() {
	if (_isOpen)
		return MERR_ALREADY_OPEN;

	_reportHandler = new MT32Emu::ReportHandlerScummVM();
	_synth = new MT32Emu::Synth(_reportHandler);

	Graphics::PixelFormat screenFormat = g_system->getScreenFormat();

	if (screenFormat.bytesPerPixel == 1) {
		const byte dummy_palette[] = {
			0, 0, 0,		// background
			0, 171, 0,	// border, font
			171, 0, 0	// fill
		};

		g_system->getPaletteManager()->setPalette(dummy_palette, 0, 3);
	}

	_initializing = true;
	debug(4, _s("Initializing MT-32 Emulator"));
	_controlFile = new Common::File();
	if (!_controlFile->open("CM32L_CONTROL.ROM") && !_controlFile->open("MT32_CONTROL.ROM"))
		error("Error opening MT32_CONTROL.ROM / CM32L_CONTROL.ROM");
	_pcmFile = new Common::File();
	if (!_pcmFile->open("CM32L_PCM.ROM") && !_pcmFile->open("MT32_PCM.ROM"))
		error("Error opening MT32_PCM.ROM / CM32L_PCM.ROM");
	_controlROM = MT32Emu::ROMImage::makeROMImage(_controlFile);
	_pcmROM = MT32Emu::ROMImage::makeROMImage(_pcmFile);
	if (!_synth->open(*_controlROM, *_pcmROM))
		return MERR_DEVICE_NOT_AVAILABLE;

	double gain = (double)ConfMan.getInt("midi_gain") / 100.0;
	_synth->setOutputGain(1.0f * gain);
	_synth->setReverbOutputGain(0.68f * gain);
	// We let the synthesizer play MIDI messages immediately. Our MIDI
	// handling is synchronous to sample generation. This makes delaying MIDI
	// events result in odd sound output in some cases. For example, the
	// shattering window in the Indiana Jones and the Fate of Atlantis intro
	// will sound like a bell if we use any delay here.
	// Bug #6242 "AUDIO: Built-In MT-32 MUNT Produces Wrong Sounds".
	_synth->setMIDIDelayMode(MT32Emu::MIDIDelayMode_IMMEDIATE);

	// We need to report the sample rate MUNT renders at as sample rate of our
	// AudioStream.
	_outputRate = _synth->getStereoOutputSampleRate();
	MidiDriver_Emulated::open();

	_initializing = false;

	if (screenFormat.bytesPerPixel > 1)
		g_system->fillScreen(screenFormat.RGBToColor(0, 0, 0));
	else
		g_system->fillScreen(0);

	g_system->updateScreen();

	_mixer->playStream(Audio::Mixer::kPlainSoundType, &_mixerSoundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);

	return 0;
}
예제 #29
0
파일: png.cpp 프로젝트: AReim1982/scummvm
bool writePNG(Common::WriteStream &out, const Graphics::Surface &input, const bool bottomUp) {
#ifdef USE_PNG
	const Graphics::PixelFormat requiredFormat_3byte(3, 8, 8, 8, 0, 16, 8, 0, 0);
	const Graphics::PixelFormat requiredFormat_4byte(4, 8, 8, 8, 8, 0, 8, 16, 24);

	if (input.format.bytesPerPixel == 3) {
		if (input.format != requiredFormat_3byte) {
			warning("Cannot currently write PNG with 3-byte pixel format other than %s", requiredFormat_3byte.toString().c_str());
			return false;
		}
	} else if (input.format.bytesPerPixel != 4) {
		warning("Cannot currently write PNG with pixel format of bpp other than 3, 4");
		return false;
	}

	int colorType;
	Graphics::Surface *tmp = NULL;
	const Graphics::Surface *surface;

	if (input.format == requiredFormat_3byte) {
		surface = &input;
		colorType = PNG_COLOR_TYPE_RGB;
	} else {
		if (input.format == requiredFormat_4byte) {
			surface = &input;
		} else {
			surface = tmp = input.convertTo(requiredFormat_4byte);
		}
		colorType = PNG_COLOR_TYPE_RGB_ALPHA;
	}

	png_structp pngPtr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	if (!pngPtr) {
		return false;
	}
	png_infop infoPtr = png_create_info_struct(pngPtr);
	if (!infoPtr) {
		png_destroy_write_struct(&pngPtr, NULL);
		return false;
	}

	png_set_error_fn(pngPtr, NULL, pngError, pngWarning);
	// TODO: The manual says errors should be handled via setjmp

	png_set_write_fn(pngPtr, &out, pngWriteToStream, pngFlushStream);

	png_set_IHDR(pngPtr, infoPtr, surface->w, surface->h, 8, colorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);

	Common::Array<const uint8 *> rows;
	rows.reserve(surface->h);
	if (bottomUp) {
		for (uint y = surface->h; y-- > 0;) {
			rows.push_back((const uint8 *)surface->getBasePtr(0, y));
		}
	} else {
		for (uint y = 0; y < surface->h; ++y) {
			rows.push_back((const uint8 *)surface->getBasePtr(0, y));
		}
	}

	png_set_rows(pngPtr, infoPtr, const_cast<uint8 **>(&rows.front()));
	png_write_png(pngPtr, infoPtr, 0, NULL);
	png_destroy_write_struct(&pngPtr, &infoPtr);

	// free tmp surface
	if (tmp) {
		tmp->free();
		delete tmp;
	}

	return true;
#else
	return false;
#endif
}
예제 #30
0
파일: video.cpp 프로젝트: peres/scummvm
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 {
				delete _videoStreams[i].video;
				_videoStreams[i].clear();
				continue;
			}
		}

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

			if (frame && _videoStreams[i].enabled) {
				// Convert from 8bpp to the current screen format if necessary
				Graphics::PixelFormat pixelFormat = _vm->_system->getScreenFormat();

				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;
					}
				}

				// 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);
				_vm->_system->copyRectToScreen((byte*)frame->pixels, frame->pitch, _videoStreams[i].x, _videoStreams[i].y, width, height);

				// We've drawn something to the screen, make sure we update it
				updateScreen = true;

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

	// Return true if we need to update the screen
	return updateScreen;
}