Beispiel #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;
}
Beispiel #2
0
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();
}
Beispiel #3
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;
}
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;
}
Beispiel #5
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];
	}
}
Beispiel #6
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;
}
Beispiel #7
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();
}
Beispiel #8
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;
}
Beispiel #9
0
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;
}
Beispiel #10
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;
	}

}
Beispiel #11
0
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();
}
Beispiel #12
0
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;
}
Beispiel #13
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;
        }
    }
}
Beispiel #14
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;
}
Beispiel #15
0
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 {
Beispiel #16
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;
}
Beispiel #17
0
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;
}
Beispiel #18
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);
	}
}
Beispiel #19
0
bool BitmapDecoder::loadStream(Common::SeekableReadStream &stream) {
	destroy();

	if (stream.readByte() != 'B')
		return false;

	if (stream.readByte() != 'M')
		return false;

	/* uint32 fileSize = */ stream.readUint32LE();
	/* uint16 res1 = */ stream.readUint16LE();
	/* uint16 res2 = */ stream.readUint16LE();
	uint32 imageOffset = stream.readUint32LE();

	uint32 infoSize = stream.readUint32LE();
	if (infoSize != 40) {
		warning("Only Windows v3 bitmaps are supported");
		return false;
	}

	uint32 width = stream.readUint32LE();
	int32 height = stream.readSint32LE();

	if (width == 0 || height == 0)
		return false;

	if (height < 0) {
		warning("Right-side up bitmaps not supported");
		return false;
	}

	/* uint16 planes = */ stream.readUint16LE();
	uint16 bitsPerPixel = stream.readUint16LE();

	if (bitsPerPixel != 8 && bitsPerPixel != 24 && bitsPerPixel != 32) {
		warning("%dbpp bitmaps not supported", bitsPerPixel);
		return false;
	}

	uint32 compression = stream.readUint32LE();

	if (compression != 0) {
		warning("Compressed bitmaps not supported");
		return false;
	}

	/* uint32 imageSize = */ stream.readUint32LE();
	/* uint32 pixelsPerMeterX = */ stream.readUint32LE();
	/* uint32 pixelsPerMeterY = */ stream.readUint32LE();
	_paletteColorCount = stream.readUint32LE();
	/* uint32 colorsImportant = */ stream.readUint32LE();

	if (bitsPerPixel == 8) {
		if (_paletteColorCount == 0)
			_paletteColorCount = 256;

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

	// Start us at the beginning of the image
	stream.seek(imageOffset);

	Graphics::PixelFormat format = Graphics::PixelFormat::createFormatCLUT8();

	// BGRA for 24bpp and 32 bpp
	if (bitsPerPixel == 24 || bitsPerPixel == 32)
		format = Graphics::PixelFormat(4, 8, 8, 8, 8, 8, 16, 24, 0);

	_surface = new Graphics::Surface();
	_surface->create(width, height, format);

	int srcPitch = width * (bitsPerPixel >> 3);
	const int extraDataLength = (srcPitch % 4) ? 4 - (srcPitch % 4) : 0;

	if (bitsPerPixel == 8) {
		byte *dst = (byte *)_surface->pixels;

		for (int32 i = 0; i < height; i++) {
			stream.read(dst + (height - i - 1) * width, width);
			stream.skip(extraDataLength);
		}
	} else if (bitsPerPixel == 24) {
		byte *dst = (byte *)_surface->pixels + (height - 1) * _surface->pitch;

		for (int32 i = 0; i < height; i++) {
			for (uint32 j = 0; j < width; j++) {
				byte b = stream.readByte();
				byte g = stream.readByte();
				byte r = stream.readByte();
				uint32 color = format.RGBToColor(r, g, b);

				*((uint32 *)dst) = color;
				dst += format.bytesPerPixel;
			}

			stream.skip(extraDataLength);
			dst -= _surface->pitch * 2;
		}
	} else { // 32 bpp
		byte *dst = (byte *)_surface->pixels + (height - 1) * _surface->pitch;

		for (int32 i = 0; i < height; i++) {
			for (uint32 j = 0; j < width; j++) {
				byte b = stream.readByte();
				byte g = stream.readByte();
				byte r = stream.readByte();
				// Ignore the last byte, as in v3 it is unused
				// and should thus NOT be used as alpha.
				// ref: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183376%28v=vs.85%29.aspx
				stream.readByte();
				uint32 color = format.RGBToColor(r, g, b);

				*((uint32 *)dst) = color;
				dst += format.bytesPerPixel;
			}

			stream.skip(extraDataLength);
			dst -= _surface->pitch * 2;
		}
	}

	return true;
}
Beispiel #20
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;
}
Beispiel #21
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 {
				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;
}