예제 #1
0
void ScreenFader::setFaderValue(const int32 value) {
	if (value != getFaderValue()) {
		Fader::setFaderValue(value);

		if (_screen->getPixels()) {
			// The original game does a gamma fade here using the Mac API. In order to do
			// that, it would require an immense amount of CPU processing. This does a
			// linear fade instead, which looks fairly well, IMO.
			Graphics::Surface *screen = g_system->lockScreen();

			for (uint y = 0; y < _screen->h; y++) {
				for (uint x = 0; x < _screen->w; x++) {
					if (_screen->format.bytesPerPixel == 2)
						WRITE_UINT16(screen->getBasePtr(x, y), fadePixel(READ_UINT16(_screen->getBasePtr(x, y)), value));
					else
						WRITE_UINT32(screen->getBasePtr(x, y), fadePixel(READ_UINT32(_screen->getBasePtr(x, y)), value));
				}
			}

			g_system->unlockScreen();
			g_system->updateScreen();
		}
	}
}
예제 #2
0
파일: frame.cpp 프로젝트: Tkachov/scummvm
void Frame::drawGhostSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect) {
	uint8 skipColor = _vm->getPaletteColorCount() - 1;
	for (int ii = 0; ii < sprite.h; ii++) {
		const byte *src = (const byte *)sprite.getBasePtr(0, ii);
		byte *dst = (byte *)target.getBasePtr(drawRect.left, drawRect.top + ii);

		for (int j = 0; j < drawRect.width(); j++) {
			if ((getSpriteIDFromPos(Common::Point(drawRect.left + j, drawRect.top + ii)) != 0) && (*src != skipColor))
				*dst = (_vm->getPaletteColorCount() - 1) - *src; //Oposite color

			src++;
			dst++;
		}
	}
}
예제 #3
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;
}
예제 #4
0
/*
 * This command draws the scene regions onto the screen. These are the regions
 * used by hotspots that have non-rectangular areas.
 */
bool Debugger::Cmd_SceneRegions(int argc, const char **argv) {
	int regionNum = 0;

	// Check for an optional specific region to display
	if (argc == 2)
		regionNum = strToInt(argv[1]);

	// Color index to use for the first priority region
	int color = 16;
	int count = 0;

	// Lock the background surface for access
	Graphics::Surface destSurface = g_globals->_sceneManager._scene->_backSurface.lockSurface();

	Common::List<Region>::iterator i = g_globals->_sceneRegions.begin();
	Common::String regionsDesc;

	for (; i != g_globals->_sceneRegions.end(); ++i, ++color, ++count) {
		Region &r = *i;

		if ((regionNum == 0) || (regionNum == (count + 1))) {
			for (int y = 0; y < destSurface.h; ++y) {
				byte *destP = (byte *)destSurface.getBasePtr(0, y);

				for (int x = 0; x < destSurface.w; ++x) {
					if (r.contains(Common::Point(g_globals->_sceneManager._scene->_sceneBounds.left + x,
							g_globals->_sceneManager._scene->_sceneBounds.top + y)))
						*destP = color;
					++destP;
				}
			}
		}

		regionsDesc += Common::String::format("Region id = %d bounds=%d,%d,%d,%d\n",
			r._regionId, r._bounds.left, r._bounds.top, r._bounds.right, r._bounds.bottom);
	}

	// Release the surface
	g_globals->_sceneManager._scene->_backSurface.unlockSurface();

	// Mark the scene as requiring a full redraw
	g_globals->_paneRefreshFlag[0] = 2;

	DebugPrintf("Total regions = %d\n", count);
	DebugPrintf("%s", regionsDesc.c_str());

	return true;
}
예제 #5
0
void Cursor::loadAvailableCursors() {
	assert(_textures.empty());

	// Load available cursors
	for (uint i = 0; i < ARRAYSIZE(availableCursors); i++) {
		// Check if a cursor sharing the same texture has already been loaded
		if (_textures.contains(availableCursors[i].nodeID)) continue;

		// Load the cursor bitmap
		const DirectorySubEntry *cursorDesc = _vm->getFileDescription("GLOB", availableCursors[i].nodeID, 0, DirectorySubEntry::kRawData);
		if (!cursorDesc)
			error("Cursor %d does not exist", availableCursors[i].nodeID);

		Common::MemoryReadStream *bmpStream = cursorDesc->getData();

		Image::BitmapDecoder bitmapDecoder;
		if (!bitmapDecoder.loadStream(*bmpStream))
			error("Could not decode Myst III bitmap");
		const Graphics::Surface *surfaceBGRA = bitmapDecoder.getSurface();
		Graphics::Surface *surfaceRGBA = surfaceBGRA->convertTo(Texture::getRGBAPixelFormat());

		delete bmpStream;

		// Apply the colorkey for transparency
		for (uint y = 0; y < surfaceRGBA->h; y++) {
			byte *pixels = (byte *)(surfaceRGBA->getBasePtr(0, y));
			for (uint x = 0; x < surfaceRGBA->w; x++) {
				byte *r = pixels + 0;
				byte *g = pixels + 1;
				byte *b = pixels + 2;
				byte *a = pixels + 3;

				if (*r == 0 && *g == 0xFF && *b == 0 && *a == 0xFF) {
					*g = 0;
					*a = 0;
				}

				pixels += 4;
			}
		}

		// Create and store the texture
		_textures.setVal(availableCursors[i].nodeID, _vm->_gfx->createTexture(surfaceRGBA));

		surfaceRGBA->free();
		delete surfaceRGBA;
	}
}
예제 #6
0
/**
 * Writes out a character at the currently set position using the active font
 *
 * @ch Character to display
 */
int GfxFont::writeChar(const char ch) {
	assert((_fontData != NULL) && ((uint8)ch < _numChars));
	uint32 charOffset = READ_LE_UINT32(_fontData + 12 + (uint8)ch * 4);
	int charWidth = _fontData[charOffset] & 0x1f;
	int charHeight = (READ_LE_UINT16(_fontData + charOffset) >> 5) & 0x3f;
	int yOffset = (_fontData[charOffset + 1] >> 3) & 0x1f;
	const uint8 *dataP = &_fontData[charOffset + 2];

	// Lock the surface for access
	Graphics::Surface surfacePtr = _gfxManager->lockSurface();

	Rect charRect;
	charRect.set(0, 0, charWidth, _fontSize.y);
	charRect.translate(_topLeft.x + _position.x, _topLeft.y + _position.y + yOffset);

	if (_fillFlag)
		surfacePtr.fillRect(charRect, _colors.background);

	charRect.bottom = charRect.top + charHeight;

	// Display the character
	int bitCtr = 0;
	uint8 v = 0;
	for (int yp = charRect.top; yp < charRect.bottom; ++yp) {
		byte *destP = (byte *)surfacePtr.getBasePtr(charRect.left, yp);

		for (int xs = 0; xs < charRect.width(); ++xs, ++destP) {
			// Get the next color index to use
			if ((bitCtr % 8) == 0) v = *dataP++;
			int colIndex = 0;
			for (int subCtr = 0; subCtr < _bpp; ++subCtr, ++bitCtr) {
				colIndex = (colIndex << 1) | (v & 0x80 ? 1 : 0);
				v <<= 1;
			}

			switch (colIndex) {
			//case 0: *destP = _colors.background; break;
			case 1: *destP = _colors.foreground; break;
			case 2: *destP = _colors2.background; break;
			case 3: *destP = _colors2.foreground; break;
			}
		}
	}

	_position.x += charWidth;
	_gfxManager->unlockSurface();
	return charWidth;
}
예제 #7
0
void Animation::drawFontFrame(Graphics::Surface &surface, int32 frame, int16 xx, int16 yy, byte *colorMap) {
	debugC(4, kDebugAnim, "drawFontFrame(surface, %d, %d, %d, colorMap)", frame, xx, yy);
	if (frame < 0)
		frame = 0;

	if (frame >= _numFrames)
		frame = _numFrames - 1;

	if (_numFrames == 0)
		return;

	int16 dataFrame = frame;

	if (_frames[frame]._ref != -1)
		dataFrame = _frames[frame]._ref;

	int16 rectX = _frames[frame]._x2 - _frames[frame]._x1;
	int16 rectY = _frames[frame]._y2 - _frames[frame]._y1;

	if ((xx + _x1 + _frames[frame]._x1 < 0) || (yy + _y1 + _frames[frame]._y1 < 0))
		return;

	if (rectX + xx + _x1 + _frames[frame]._x1 >= surface.getWidth())
		rectX = surface.getWidth() - xx - _x1 - _frames[frame]._x1;

	if (rectX < 0)
		return;

	if (rectY + yy + _y1 + _frames[frame]._y1 >= surface.getHeight())
		rectY = surface.getHeight() - yy - _y1 - _frames[frame]._y1;

	if (rectY < 0)
		return;

	int32 destPitch = surface.getPitch();
	uint8 *c = _frames[dataFrame]._data;
	uint8 *curRow = (uint8 *)surface.getBasePtr(xx + _x1 + _frames[frame]._x1, yy + _frames[frame]._y1 + _y1);
	for (int16 y = 0; y < rectY; y++) {
		unsigned char *cur = curRow;
		for (int16 x = 0; x < rectX; x++) {
			if (*c && *c < 4)
				*cur = colorMap[*c];
			c++;
			cur++;
		}
		curRow += destPitch;
	}
}
예제 #8
0
파일: frame.cpp 프로젝트: Tkachov/scummvm
void Frame::drawBackgndTransSprite(Graphics::ManagedSurface &target, const Graphics::Surface &sprite, Common::Rect &drawRect) {
	uint8 skipColor = _vm->getPaletteColorCount() - 1; //FIXME is it always white (last entry in pallette) ?

	for (int ii = 0; ii < sprite.h; ii++) {
		const byte *src = (const byte *)sprite.getBasePtr(0, ii);
		byte *dst = (byte *)target.getBasePtr(drawRect.left, drawRect.top + ii);

		for (int j = 0; j < drawRect.width(); j++) {
			if (*src != skipColor)
				*dst = *src;

			src++;
			dst++;
		}
	}
}
예제 #9
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();
}
예제 #10
0
파일: movie.cpp 프로젝트: jweinberg/scummvm
bool Movie::playVideo(bool isFirstIntroVideo) {
	debugC(1, kDebugMovie, "playVideo(isFirstIntroVideo: %d)", isFirstIntroVideo);

	while (!_vm->shouldQuit() && !_decoder->endOfVideo()) {
		if (_decoder->needsUpdate()) {
			const Graphics::Surface *frame = _decoder->decodeNextFrame();
			if (frame) {
				if (_decoder->isLowRes()) {
					// handle manually 2x scaling here
					Graphics::Surface* surf = _vm->getSystem()->lockScreen();
					for (int y = 0; y < frame->h / 2; y++) {
						memcpy(surf->getBasePtr(0, y * 2 + 0), frame->getBasePtr(0, y), frame->pitch);
						memcpy(surf->getBasePtr(0, y * 2 + 1), frame->getBasePtr(0, y), frame->pitch);
					}
					_vm->getSystem()->unlockScreen();
				} else {
					_vm->getSystem()->copyRectToScreen((byte *)frame->pixels, frame->pitch, 0, 0, frame->w, frame->h);

					// WORKAROUND: There is an encoding glitch in the first intro video. This hides this using the adjacent pixels.
					if (isFirstIntroVideo) {
						int32 currentFrame = _decoder->getCurFrame();
						if (currentFrame >= 956 && currentFrame <= 1038) {
							debugC(1, kDebugMovie, "Triggered workaround for glitch in first intro video...");
							_vm->getSystem()->copyRectToScreen((const byte *)frame->getBasePtr(frame->w-188, 123), frame->pitch, frame->w-188, 124, 188, 1);
							_vm->getSystem()->copyRectToScreen((const byte *)frame->getBasePtr(frame->w-188, 126), frame->pitch, frame->w-188, 125, 188, 1);
							_vm->getSystem()->copyRectToScreen((const byte *)frame->getBasePtr(0, 125), frame->pitch, 0, 126, 64, 1);
							_vm->getSystem()->copyRectToScreen((const byte *)frame->getBasePtr(0, 128), frame->pitch, 0, 127, 64, 1);
						}
					}
				}
			}
			_decoder->setSystemPalette();
			_vm->getSystem()->updateScreen();
		}

		Common::Event event;
		while (_vm->getSystem()->getEventManager()->pollEvent(event))
			if ((event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE)) {
				_vm->dirtyAllScreen();
				return false;
			}

		_vm->getSystem()->delayMillis(10);
	}
	_vm->dirtyAllScreen();
	return !_vm->shouldQuit();
}
예제 #11
0
void Surface::transBlitFrom(const Graphics::Surface &src, const Common::Point &pt,
		bool flipped, int overrideColor, int scaleVal) {
	if (scaleVal == 256) {
		transBlitFromUnscaled(src, pt, flipped, overrideColor);
		return;
	}

	int scaleX = SCALE_THRESHOLD * SCALE_THRESHOLD / scaleVal;
	int scaleY = scaleX;
	int scaleXCtr = 0, scaleYCtr = 0;

	for (int yCtr = 0, destY = pt.y; yCtr < src.h && destY < this->h(); ++yCtr) {
		// Handle skipping lines if Y scaling
		scaleYCtr += scaleY;
		
		while (scaleYCtr >= SCALE_THRESHOLD && destY < this->h()) {
			scaleYCtr -= SCALE_THRESHOLD;

			if (destY >= 0) {
				// Handle drawing the line
				const byte *pSrc = (const byte *)src.getBasePtr(flipped ? src.w - 1 : 0, yCtr);
				byte *pDest = (byte *)getBasePtr(pt.x, destY);
				scaleXCtr = 0;

				for (int xCtr = 0, destX = pt.x; xCtr < src.w && destX < this->w(); ++xCtr) {
					// Handle horizontal scaling
					scaleXCtr += scaleX;

					while (scaleXCtr >= SCALE_THRESHOLD && destX < this->w()) {
						scaleXCtr -= SCALE_THRESHOLD;

						// Only handle on-screen pixels
						if (destX >= 0 && *pSrc != TRANSPARENCY)
							*pDest = *pSrc;

						++pDest;
						++destX;
					}

					pSrc = pSrc + (flipped ? -1 : 1);
				}
			}

			++destY;
		}
	}
}
예제 #12
0
bool LBGraphics::imageIsTransparentAt(uint16 image, bool useOffsets, int x, int y) {
	MohawkSurface *mhkSurface = findImage(image);

	if (useOffsets) {
		x += mhkSurface->getOffsetX();
		y += mhkSurface->getOffsetY();
	}

	if (x < 0 || y < 0)
		return true;

	Graphics::Surface *surface = mhkSurface->getSurface();
	if (x >= surface->w || y >= surface->h)
		return true;

	return *(byte *)surface->getBasePtr(x, y) == 0;
}
예제 #13
0
void Scalpel3DOScreen::transBlitFromUnscaled(const Graphics::Surface &src, const Common::Point &pt,
		bool flipped, int overrideColor) {
	error("TODO: Refactor");
#if 0
	if (!_vm->_isScreenDoubled) {
		ScalpelScreen::transBlitFromUnscaled(src, pt, flipped, overrideColor);
		return;
	}

	Common::Rect drawRect(0, 0, src.w, src.h);
	Common::Rect destRect(pt.x, pt.y, pt.x + src.w, pt.y + src.h);

	// Clip the display area to on-screen
	if (!clip(drawRect, destRect))
		// It's completely off-screen
		return;

	if (flipped)
		drawRect = Common::Rect(src.w - drawRect.right, src.h - drawRect.bottom,
		src.w - drawRect.left, src.h - drawRect.top);

	Common::Point destPt(destRect.left, destRect.top);
	addDirtyRect(Common::Rect(destPt.x * 2, destPt.y * 2, (destPt.x + drawRect.width()) * 2,
		(destPt.y + drawRect.height()) * 2));

	assert(src.format.bytesPerPixel == 2 && _surface.format.bytesPerPixel == 2);

	for (int yp = 0; yp < drawRect.height(); ++yp) {
		const uint16 *srcP = (const uint16 *)src.getBasePtr(
			flipped ? drawRect.right - 1 : drawRect.left, drawRect.top + yp);
		uint16 *destP = (uint16 *)getBasePtr(destPt.x * 2, (destPt.y + yp) * 2);

		for (int xp = 0; xp < drawRect.width(); ++xp, destP += 2) {
			// RGB 0, 0, 0 -> transparent on 3DO
			if (*srcP) {
				*destP = *srcP;
				*(destP + 1) = *srcP;
				*(destP + 640) = *srcP;
				*(destP + 640 + 1) = *srcP;
			}

			srcP = flipped ? srcP - 1 : srcP + 1;
		}
	}
#endif
}
예제 #14
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;
}
예제 #15
0
int Font::drawChar(ASurface *s, char c, Common::Point &pt) {
    Graphics::Surface &ch = _chars[c - ' '];
    Graphics::Surface dest = s->getSubArea(Common::Rect(pt.x, pt.y, pt.x + ch.w, pt.y + ch.h));

    // Loop through the lines of the character
    for (int y = 0; y < ch.h; ++y) {
        byte *pSrc = (byte *)ch.getBasePtr(0, y);
        byte *pDest = (byte *)dest.getBasePtr(0, y);

        // Loop through the horizontal pixels of the line
        for (int x = 0; x < ch.w; ++x, ++pSrc, ++pDest) {
            if (*pSrc != 0)
                *pDest = _fontColors[*pSrc];
        }
    }

    return ch.w;
}
예제 #16
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);
}
예제 #17
0
bool BaseSurfaceOSystem::putSurface(const Graphics::Surface &surface, bool hasAlpha) {
	_loaded = true;
	if (surface.format == _surface->format && surface.pitch == _surface->pitch && surface.h == _surface->h) {
		const byte *src = (const byte *)surface.getBasePtr(0, 0);
		byte *dst = (byte *)_surface->getBasePtr(0, 0);
		memcpy(dst, src, surface.pitch * surface.h);
	} else {
		_surface->free();
		_surface->copyFrom(surface);
	}
	if (hasAlpha) {
		_alphaType = TransparentSurface::ALPHA_FULL;
	} else {
		_alphaType = TransparentSurface::ALPHA_OPAQUE;
	}
	BaseRenderOSystem *renderer = static_cast<BaseRenderOSystem *>(_gameRef->_renderer);
	renderer->invalidateTicketsFromSurface(this);

	return STATUS_OK;
}
예제 #18
0
void DreamWebEngine::printUnderMonitor() {
	uint8 *dst = workspace() + kScreenwidth * 43 + 76;

	Graphics::Surface *s = _system->lockScreen();
	if (!s)
		error("lockScreen failed");

	for (uint y = 0; y < 104; ++y) {
		uint8 *src = (uint8 *)s->getBasePtr(76, 43 + 8 + y);
		for (uint x = 0; x < 170; ++x) {
			if (*src < 231)
				*dst++ = *src++;
			else {
				++dst; ++src;
			}
		}
		dst += kScreenwidth - 170;
	}
	_system->unlockScreen();
}
예제 #19
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->bytesPerPixel == 1 || screen->bytesPerPixel == 2);
	assert(screen->pixels != 0);

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

	surf->create(screen->w, screen->h, 2);

	byte *palette = 0;
	if (screenFormat.bytesPerPixel == 1) {
		palette = new byte[256 * 4];
		assert(palette);
		g_system->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) {
				r = palette[((uint8*)screen->pixels)[y * screen->pitch + x] * 4];
				g = palette[((uint8*)screen->pixels)[y * screen->pitch + x] * 4 + 1];
				b = palette[((uint8*)screen->pixels)[y * screen->pitch + x] * 4 + 2];
			} else if (screenFormat.bytesPerPixel == 2) {
				uint16 col = READ_UINT16(screen->getBasePtr(x, y));
				screenFormat.colorToRGB(col, r, g, b);
			}

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

	delete[] palette;

	g_system->unlockScreen();
	return true;
}
예제 #20
0
/**
 * Highlights the specified graphics element
 */
void GfxElement::highlight() {
	// Get a lock on the surface
	GfxManager &gfxManager = _globals->gfxManager();
	Graphics::Surface surface = gfxManager.lockSurface();

	// Scan through the contents of the element, switching any occurances of the foreground
	// color with the background color and vice versa
	Rect tempRect(_bounds);
	tempRect.collapse(_globals->_gfxEdgeAdjust - 1, _globals->_gfxEdgeAdjust - 1);

	for (int yp = tempRect.top; yp < tempRect.bottom; ++yp) {
		byte *lineP = (byte *)surface.getBasePtr(tempRect.left, yp);
		for (int xp = tempRect.left; xp < tempRect.right; ++xp, ++lineP) {
			if (*lineP == _colors.background) *lineP = _colors.foreground;
			else if (*lineP == _colors.foreground) *lineP = _colors.background;
		}
	}

	// Release the surface
	gfxManager.unlockSurface();
}
예제 #21
0
void Cursor::loadAvailableCursors() {
	assert(_textures.empty());

	// Load available cursors
	for (uint i = 0; i < ARRAYSIZE(availableCursors); i++) {
		// Check if a cursor sharing the same texture has already been loaded
		if (_textures.contains(availableCursors[i].nodeID)) continue;

		// Load the cursor bitmap
		const DirectorySubEntry *cursorDesc = _vm->getFileDescription("GLOB", availableCursors[i].nodeID, 0, DirectorySubEntry::kRawData);
		if (!cursorDesc)
			error("Cursor %d does not exist", availableCursors[i].nodeID);

		Common::MemoryReadStream *bmpStream = cursorDesc->getData();

		Image::BitmapDecoder bitmapDecoder;
		if (!bitmapDecoder.loadStream(*bmpStream))
			error("Could not decode Myst III bitmap");
		const Graphics::Surface *surfaceBGRA = bitmapDecoder.getSurface();
		Graphics::Surface *surfaceRGBA = surfaceBGRA->convertTo(Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));

		delete bmpStream;

		// Apply the colorkey for transparency
		for (uint u = 0; u < surfaceRGBA->w; u++) {
			for (uint v = 0; v < surfaceRGBA->h; v++) {
				uint32 *pixel = (uint32*)(surfaceRGBA->getBasePtr(u, v));
				if (*pixel == 0xFF00FF00)
					*pixel = 0x0000FF00;

			}
		}

		// Create and store the texture
		_textures.setVal(availableCursors[i].nodeID, _vm->_gfx->createTexture(surfaceRGBA));

		surfaceRGBA->free();
		delete surfaceRGBA;
	}
}
예제 #22
0
int BitmapFont::getSourceCharacterWidth(uint charIndex, const Graphics::Surface &src,
		const Common::Rect &charBounds) {
	if (charIndex == 0)
		// The space character is treated as half the width of bounding area
		return charBounds.width() / 2;

	// Scan through the rows to find the right most pixel, getting the width from that
	int maxWidth = 0, rowX;
	for (int y = charBounds.top; y < charBounds.bottom; ++y) {
		rowX = 0;
		const byte *srcP = (const byte *)src.getBasePtr(charBounds.left, y);

		for (int x = 0; x < charBounds.width(); ++x, ++srcP) {
			if (!*srcP)
				rowX = x;
		}

		maxWidth = MAX(maxWidth, MIN(rowX + 2, (int)charBounds.width()));
	}

	return maxWidth;
}
예제 #23
0
void SceneExt::refreshBackground(int xAmount, int yAmount) {
	switch (_activeScreenNumber) {
	case 700:
	case 1020:
	case 1100:
	case 1700:
	case 2600:
	case 2950:
	case 3100:
	case 3101:
	case 3275:
	case 3600:
		// Use traditional style sectioned screen loading
		Scene::refreshBackground(xAmount, yAmount);
		return;
	default:
		// Break out to new style screen loading
		break;
	}

	/* New style background loading */

	// Get the screen data
	byte *dataP = g_resourceManager->getResource(RT18, _activeScreenNumber, 0);
	int screenSize = g_vm->_memoryManager.getSize(dataP);

	// Lock the background for update
	Graphics::Surface s = _backSurface.lockSurface();
	assert(screenSize == (s.w * s.h));

	// Copy the data
	byte *destP = (byte *)s.getBasePtr(0, 0);
	Common::copy(dataP, dataP + (s.w * s.h), destP);
	_backSurface.unlockSurface();

	// Free the resource data
	DEALLOCATE(dataP);
}
예제 #24
0
/**
 * Loads a quarter of a screen from a resource
 */
void GfxSurface::loadScreenSection(Graphics::Surface &dest, int xHalf, int yHalf, int xSection, int ySection) {
	int screenNum = _globals->_sceneManager._scene->_activeScreenNumber;
	Rect updateRect(0, 0, 160, 100);
	updateRect.translate(xHalf * 160, yHalf * 100);
	int xHalfCount = (_globals->_sceneManager._scene->_backgroundBounds.right + 159) / 160;
	int yHalfCount = (_globals->_sceneManager._scene->_backgroundBounds.bottom + 99) / 100;

	if (xSection < xHalfCount && ySection < yHalfCount) {
		int rlbNum = xSection * yHalfCount + ySection;
		byte *data = _resourceManager->getResource(RES_BITMAP, screenNum, rlbNum);

		for (int y = 0; y < updateRect.height(); ++y) {
			byte *pSrc = data + y * 160;
			byte *pDest = (byte *)dest.getBasePtr(updateRect.left, updateRect.top + y);

			for (int x = 0; x < updateRect.width(); ++x, ++pSrc, ++pDest) {
				*pDest = *pSrc;
			}
		}

		DEALLOCATE(data);
	}
}
예제 #25
0
/**
 * Locks the surface for access, and returns a raw ScummVM surface to manipulate it
 */
Graphics::Surface GfxSurface::lockSurface() {
	++_lockSurfaceCtr;

	Graphics::Surface *src;
	if (_screenSurface) {
		if (_lockSurfaceCtr == 1)
			_screenSurfaceP = g_system->lockScreen();
		src = _screenSurfaceP;
	} else
		src = _customSurface;
	assert(src);

	// Setup the returned surface either as one pointing to the same pixels as the source, or
	// as a subset of the source one based on the currently set bounds
	Graphics::Surface result;
	result.w = _bounds.width();
	result.h = _bounds.height();
	result.pitch = src->pitch;
	result.format = src->format;
	result.pixels = src->getBasePtr(_bounds.left, _bounds.top);

	return result;
}
예제 #26
0
파일: font.cpp 프로젝트: 86400/scummvm
void Font::drawCharacter(const char character, Graphics::Surface &surface, int x, int y) {
    uint8 characterIndex = (uint8)character + 1;
    if (x < 0 || x >= _screenWidth || y < 0 || y >= _screenHeight || !_data || characterIndex >= _characterCount) {
        return;
    }

    uint16 *dstPtr = (uint16*)surface.getBasePtr(x + _characters[characterIndex]._x, y + _characters[characterIndex]._y);
    uint16 *srcPtr = &_data[_characters[characterIndex]._dataOffset];
    int width = _characters[characterIndex]._width;
    int height = _characters[characterIndex]._height;
    if (_intersperse && y & 1) {
        dstPtr += surface.pitch / 2;
    }

    int endY = height + y - 1;
    int currentY = y;
    while (currentY <= endY && currentY < _screenHeight) {
        int currentX = x;
        int endX = width + x - 1;
        while (currentX <= endX && currentX < _screenWidth) {
            if ((*srcPtr & 0x8000) == 0) {
                *dstPtr = *srcPtr;
            }
            dstPtr++;
            srcPtr++;
            currentX++;
        }
        dstPtr += surface.pitch / 2 - width;
        if (_intersperse) {
            srcPtr += width;
            dstPtr += surface.pitch / 2;
            currentY++;
        }
        currentY++;
    }
}
예제 #27
0
파일: window.cpp 프로젝트: murgo/scummvm
void RMWindow::copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) {
	if (GLOBALS._bCfgAnni30) {
		if (!RMGfxTargetBuffer::_precalcTable) {
			RMGfxTargetBuffer::createBWPrecalcTable();
			g_vm->getEngine()->getPointer().updateCursor();
		}
		Graphics::Surface *screen = g_system->lockScreen();
		const uint16 *src = (const uint16 *)buf;
		for (int i = 0; i < h; i++) {
			uint16 *dst = (uint16 *)screen->getBasePtr(x, y + i);
			for (int j = 0; j < w; j++) {
				dst[j] = RMGfxTargetBuffer::_precalcTable[src[j] & 0x7FFF];
			}
			src += (pitch / 2);
		}
		g_system->unlockScreen();
	} else {
		if (RMGfxTargetBuffer::_precalcTable) {
			RMGfxTargetBuffer::freeBWPrecalcTable();
			g_vm->getEngine()->getPointer().updateCursor();
		}
		g_system->copyRectToScreen(buf, pitch, x, y, w, h);
	}
 }
예제 #28
0
void AVISurface::copyMovieFrame(const Graphics::Surface &src, Graphics::ManagedSurface &dest) {
	// WORKAROUND: Handle rare cases where frame sizes don't match the video size
	Common::Rect copyRect(0, 0, MIN(src.w, dest.w), MIN(src.h, dest.h));

	if (src.format.bytesPerPixel == 1) {
		// Paletted 8-bit, so convert to 16-bit and copy over
		const byte *palette = _decoder->getPalette();
		if (palette) {
			Graphics::Surface *s = src.convertTo(dest.format, palette);
			dest.blitFrom(*s, copyRect, Common::Point(0, 0));
			s->free();
			delete s;
		}
	} else if (src.format.bytesPerPixel == 2) {
		// Source is already 16-bit, with no alpha, so do a straight copy
		dest.blitFrom(src, copyRect, Common::Point(0, 0));
	} else {
		// Source is 32-bit which may have transparent pixels. Copy over each
		// pixel, replacing transparent pixels with the special transparency color
		byte a, r, g, b;
		assert(src.format.bytesPerPixel == 4 && dest.format.bytesPerPixel == 2);
		uint16 transPixel = _videoSurface->getTransparencyColor();

		for (uint y = 0; y < MIN(src.h, dest.h); ++y) {
			const uint32 *pSrc = (const uint32 *)src.getBasePtr(0, y);
			uint16 *pDest = (uint16 *)dest.getBasePtr(0, y);

			for (uint x = 0; x < MIN(src.w, dest.w); ++x, ++pSrc, ++pDest) {
				src.format.colorToARGB(*pSrc, a, r, g, b);
				assert(a == 0 || a == 0xff);

				*pDest = (a == 0) ? transPixel : dest.format.RGBToColor(r, g, b);
			}
		}
	}
}
예제 #29
0
void ScreenEffects::copyFxRect(Graphics::Surface *surface, int16 x1, int16 y1, int16 x2, int16 y2) {

	// TODO: Clean up

	byte *src, *dst;

	x1 = CLIP<int16>(x1, 0, 320);
	y1 = CLIP<int16>(y1, 0, 200);
	x2 = CLIP<int16>(x2, 0, 320);
	y2 = CLIP<int16>(y2, 0, 200);

	x2 -= x1;
	y2 -= y1;
	vfxX1 = x1 & 0x0E;
	x1 += 16;
	x1 = x1 & 0xFFF0;
	x2 += vfxX1;
	x2 -= 15;
	if (x2 < 0)
		x2 = 0;
	vfxWidth = x2 & 0x0E;
	x2 = x2 & 0xFFF0;

	vfxY1 = y1 & 7;

	byte *source = (byte*)surface->getBasePtr(x1, y1);

	Graphics::Surface *vgaScreen = _screen->lockScreen();
	byte *dest = (byte*)vgaScreen->getBasePtr(x1, y1);

	int16 addX = x2 / 16;

	while (y2-- > 0) {

		int16 addVal = vfxOffsTablePtr[vfxY1] * 2;
		int16 w = 0;
		vfxY1 = (vfxY1 + 1) & 7;

		src = source + addVal;
		dst = dest + addVal;

		if (addVal < vfxX1) {
			if (addVal < vfxWidth)
				w = 1;
			else
				w = 0;
		} else {
			src -= 16;
			dst -= 16;
			if (addVal < vfxWidth)
				w = 2;
			else
				w = 1;
		}

		w += addX;

		while (w-- > 0) {
			*dst++ = *src++;
			*dst++ = *src++;
			src += 14;
			dst += 14;
		}

		source += 320;
		dest += 320;

	}

	vfxHeight = (vfxHeight + 1) & 7;
	vfxOffsTablePtr = &vfxOffsTable[vfxOffsIndexTable[vfxHeight] * 8];

	_screen->unlockScreen();

}
예제 #30
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;
}