2007-05-30 21:56:52 +00:00
|
|
|
/* ScummVM - Graphic Adventure Engine
|
|
|
|
*
|
|
|
|
* ScummVM is the legal property of its developers, whose names
|
|
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
|
|
* file distributed with this source distribution.
|
2005-04-05 18:08:02 +00:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
2008-01-05 12:45:14 +00:00
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2005-04-05 18:08:02 +00:00
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2005-04-09 19:19:54 +00:00
|
|
|
* along with this program; if not, write to the Free Software
|
2005-10-18 01:30:26 +00:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2005-04-05 18:08:02 +00:00
|
|
|
*
|
2006-02-11 10:11:37 +00:00
|
|
|
* $URL$
|
|
|
|
* $Id$
|
2005-04-05 18:08:02 +00:00
|
|
|
*
|
|
|
|
*/
|
2007-03-20 14:51:57 +00:00
|
|
|
|
2006-03-29 15:59:37 +00:00
|
|
|
#include "common/endian.h"
|
2007-03-20 14:51:57 +00:00
|
|
|
#include "graphics/cursorman.h"
|
2008-12-12 02:44:34 +00:00
|
|
|
#include "graphics/fontman.h"
|
|
|
|
#include "graphics/surface.h"
|
2008-12-24 15:57:43 +00:00
|
|
|
#include "graphics/dither.h"
|
2006-03-29 15:59:37 +00:00
|
|
|
|
2005-04-05 15:07:40 +00:00
|
|
|
#include "gob/gob.h"
|
|
|
|
#include "gob/video.h"
|
2007-03-20 14:51:57 +00:00
|
|
|
#include "gob/global.h"
|
|
|
|
#include "gob/util.h"
|
2005-04-05 15:07:40 +00:00
|
|
|
#include "gob/dataio.h"
|
2006-05-01 12:43:50 +00:00
|
|
|
#include "gob/draw.h"
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
#include "gob/driver_vga.h"
|
|
|
|
|
|
|
|
namespace Gob {
|
|
|
|
|
2009-07-09 02:54:10 +00:00
|
|
|
Font::Font(const byte *data) : _dataPtr(data) {
|
|
|
|
assert(data);
|
|
|
|
|
|
|
|
bool hasWidths = _dataPtr[0] & 0x80;
|
|
|
|
|
|
|
|
_data = _dataPtr + 4;
|
|
|
|
_itemWidth = _dataPtr[0] & 0x7F;
|
|
|
|
_itemHeight = _dataPtr[1];
|
|
|
|
_startItem = _dataPtr[2];
|
|
|
|
_endItem = _dataPtr[3];
|
|
|
|
_charWidths = 0;
|
|
|
|
|
|
|
|
uint8 rowAlignedBits = (_itemWidth - 1) / 8 + 1;
|
|
|
|
|
|
|
|
_itemSize = rowAlignedBits * _itemHeight;
|
|
|
|
_bitWidth = _itemWidth;
|
|
|
|
|
|
|
|
if (hasWidths)
|
|
|
|
_charWidths = _dataPtr + 4 + _itemSize * getCharCount();
|
|
|
|
}
|
|
|
|
|
|
|
|
Font::~Font() {
|
2009-07-10 21:49:47 +00:00
|
|
|
delete[] _dataPtr;
|
2009-07-09 02:54:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint8 Font::getCharWidth(uint8 c) const {
|
|
|
|
if (!_charWidths || (_endItem == 0))
|
|
|
|
return _itemWidth;
|
|
|
|
|
|
|
|
if ((c < _startItem) || (c > _endItem))
|
|
|
|
return _itemWidth;
|
|
|
|
|
|
|
|
return _charWidths[c - _startItem];
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8 Font::getCharWidth() const {
|
|
|
|
return _itemWidth;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8 Font::getCharHeight() const {
|
|
|
|
return _itemHeight;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16 Font::getCharCount() const {
|
|
|
|
return _endItem - _startItem + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8 Font::getFirstChar() const {
|
|
|
|
return _startItem;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8 Font::getLastChar() const {
|
|
|
|
return _endItem;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8 Font::getCharSize() const {
|
|
|
|
return _itemSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Font::isMonospaced() const {
|
|
|
|
return _charWidths == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
const byte *Font::getCharData(uint8 c) const {
|
|
|
|
if (_endItem == 0) {
|
|
|
|
warning("Font::getCharData(): _endItem == 0");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((c < _startItem) || (c > _endItem))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return _data + (c - _startItem) * _itemSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-03-20 14:51:57 +00:00
|
|
|
SurfaceDesc::SurfaceDesc(int16 vidMode, int16 width, int16 height,
|
|
|
|
byte *vidMem) : _width(width), _height(height) {
|
|
|
|
|
|
|
|
if (vidMem) {
|
|
|
|
_vidMode = vidMode;
|
|
|
|
_ownVidMem = false;
|
|
|
|
_vidMem = vidMem;
|
|
|
|
} else {
|
|
|
|
_vidMode = vidMode;
|
|
|
|
_ownVidMem = true;
|
|
|
|
_vidMem = new byte[width * height];
|
|
|
|
assert(_vidMem);
|
|
|
|
memset(_vidMem, 0, width * height);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SurfaceDesc::setVidMem(byte *vidMem) {
|
|
|
|
assert(vidMem);
|
|
|
|
|
|
|
|
if (hasOwnVidMem())
|
|
|
|
delete[] _vidMem;
|
|
|
|
|
|
|
|
_ownVidMem = false;
|
|
|
|
_vidMem = vidMem;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SurfaceDesc::resize(int16 width, int16 height) {
|
|
|
|
if (hasOwnVidMem())
|
|
|
|
delete[] _vidMem;
|
|
|
|
|
|
|
|
_width = width;
|
|
|
|
_height = height;
|
|
|
|
_ownVidMem = true;
|
|
|
|
_vidMem = new byte[width * height];
|
|
|
|
assert(_vidMem);
|
|
|
|
memset(_vidMem, 0, width * height);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SurfaceDesc::swap(SurfaceDesc &surf) {
|
|
|
|
SWAP(_width, surf._width);
|
|
|
|
SWAP(_height, surf._height);
|
|
|
|
SWAP(_vidMode, surf._vidMode);
|
|
|
|
SWAP(_ownVidMem, surf._ownVidMem);
|
|
|
|
SWAP(_vidMem, surf._vidMem);
|
|
|
|
}
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
Video::Video(GobEngine *vm) : _vm(vm) {
|
2007-03-20 14:51:57 +00:00
|
|
|
_doRangeClamp = false;
|
2006-05-31 08:44:14 +00:00
|
|
|
_videoDriver = 0;
|
2008-05-17 23:55:04 +00:00
|
|
|
|
2007-01-29 17:04:37 +00:00
|
|
|
_surfWidth = 320;
|
2007-02-06 14:42:05 +00:00
|
|
|
_surfHeight = 200;
|
2008-05-17 23:55:04 +00:00
|
|
|
|
2007-02-06 14:42:05 +00:00
|
|
|
_scrollOffsetX = 0;
|
|
|
|
_scrollOffsetY = 0;
|
2008-05-17 23:55:04 +00:00
|
|
|
|
2007-04-19 13:51:57 +00:00
|
|
|
_splitHeight1 = 200;
|
|
|
|
_splitHeight2 = 0;
|
|
|
|
_splitStart = 0;
|
2007-04-06 13:30:09 +00:00
|
|
|
|
2008-05-03 20:08:46 +00:00
|
|
|
_screenDeltaX = 0;
|
|
|
|
_screenDeltaY = 0;
|
|
|
|
|
2007-04-06 13:30:09 +00:00
|
|
|
_curSparse = 0;
|
|
|
|
_lastSparse = 0xFFFFFFFF;
|
2008-12-04 18:38:55 +00:00
|
|
|
|
|
|
|
_dirtyAll = false;
|
2008-12-11 03:06:43 +00:00
|
|
|
|
2009-04-29 10:24:00 +00:00
|
|
|
_palLUT = new Graphics::PaletteLUT(5, Graphics::PaletteLUT::kPaletteYUV);
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
char Video::initDriver(int16 vidMode) {
|
2006-05-31 08:44:14 +00:00
|
|
|
if (_videoDriver)
|
|
|
|
return 1;
|
|
|
|
|
2005-04-05 15:07:40 +00:00
|
|
|
_videoDriver = new VGAVideoDriver();
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2008-12-14 04:33:28 +00:00
|
|
|
Video::~Video() {
|
|
|
|
delete _palLUT;
|
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Video::freeDriver() {
|
2005-04-05 15:07:40 +00:00
|
|
|
delete _videoDriver;
|
|
|
|
}
|
|
|
|
|
2007-03-20 14:51:57 +00:00
|
|
|
void Video::initPrimary(int16 mode) {
|
|
|
|
if ((mode != 3) && (mode != -1))
|
|
|
|
_vm->validateVideoMode(mode);
|
|
|
|
_vm->validateVideoMode(_vm->_global->_videoMode);
|
|
|
|
|
|
|
|
if (mode == -1)
|
|
|
|
mode = 3;
|
|
|
|
_vm->_global->_oldMode = mode;
|
|
|
|
|
|
|
|
if (mode != 3)
|
|
|
|
Video::initDriver(mode);
|
|
|
|
|
|
|
|
if (mode != 3) {
|
|
|
|
initSurfDesc(mode, _surfWidth, _surfHeight, PRIMARY_SURFACE);
|
|
|
|
|
|
|
|
if (!_vm->_global->_dontSetPalette)
|
|
|
|
Video::setFullPalette(_vm->_global->_pPaletteDesc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-06-06 20:03:13 +00:00
|
|
|
SurfaceDescPtr Video::initSurfDesc(int16 vidMode, int16 width, int16 height, int16 flags) {
|
|
|
|
SurfaceDescPtr descPtr;
|
2007-03-20 14:51:57 +00:00
|
|
|
|
|
|
|
if (flags & PRIMARY_SURFACE)
|
|
|
|
assert((width == _surfWidth) && (height == _surfHeight));
|
|
|
|
|
|
|
|
_vm->validateVideoMode(vidMode);
|
|
|
|
|
|
|
|
if (flags & PRIMARY_SURFACE) {
|
|
|
|
_vm->_global->_primaryWidth = width;
|
|
|
|
_vm->_global->_primaryHeight = height;
|
2007-09-19 08:40:12 +00:00
|
|
|
|
2007-03-20 14:51:57 +00:00
|
|
|
descPtr = _vm->_global->_primarySurfDesc;
|
|
|
|
descPtr->resize(width, height);
|
|
|
|
descPtr->_vidMode = vidMode;
|
|
|
|
} else {
|
|
|
|
assert(!(flags & DISABLE_SPR_ALLOC));
|
|
|
|
|
|
|
|
if (!(flags & SCUMMVM_CURSOR))
|
|
|
|
width = (width + 7) & 0xFFF8;
|
|
|
|
|
2009-06-06 20:03:13 +00:00
|
|
|
descPtr = SurfaceDescPtr(new SurfaceDesc(vidMode, width, height));
|
2007-03-20 14:51:57 +00:00
|
|
|
}
|
|
|
|
return descPtr;
|
|
|
|
}
|
|
|
|
|
2008-05-03 20:08:46 +00:00
|
|
|
void Video::clearScreen() {
|
2009-02-15 21:20:21 +00:00
|
|
|
g_system->fillScreen(0);
|
2008-05-03 20:08:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Video::setSize(bool defaultTo1XScaler) {
|
2008-11-14 22:08:10 +00:00
|
|
|
initGraphics(_vm->_width, _vm->_height, defaultTo1XScaler);
|
2008-05-03 20:08:46 +00:00
|
|
|
}
|
|
|
|
|
2007-03-29 17:55:39 +00:00
|
|
|
void Video::retrace(bool mouse) {
|
2007-03-20 14:51:57 +00:00
|
|
|
if (mouse)
|
|
|
|
CursorMan.showMouse((_vm->_draw->_showCursor & 2) != 0);
|
|
|
|
if (_vm->_global->_primarySurfDesc) {
|
2008-05-03 20:08:46 +00:00
|
|
|
int screenOffset = _scrollOffsetY * _surfWidth + _scrollOffsetX;
|
|
|
|
int screenX = _screenDeltaX;
|
|
|
|
int screenY = _screenDeltaY;
|
2008-05-26 22:02:20 +00:00
|
|
|
int screenWidth = MIN<int>(_surfWidth - _scrollOffsetX, _vm->_width);
|
|
|
|
int screenHeight = MIN<int>(_surfHeight - _splitHeight2 - _scrollOffsetY, _vm->_height);
|
2008-05-03 20:08:46 +00:00
|
|
|
|
2008-12-04 18:38:55 +00:00
|
|
|
dirtyRectsApply(_scrollOffsetX, _scrollOffsetY, screenWidth, screenHeight,
|
|
|
|
screenX, screenY);
|
2008-05-03 20:08:46 +00:00
|
|
|
|
2008-05-17 23:55:04 +00:00
|
|
|
if (_splitSurf) {
|
|
|
|
|
|
|
|
screenOffset = 0;
|
|
|
|
screenX = 0;
|
|
|
|
screenY = _vm->_height - _splitSurf->getHeight();
|
|
|
|
screenWidth = MIN<int>(_vm->_width, _splitSurf->getWidth());
|
|
|
|
screenHeight = _splitSurf->getHeight();
|
|
|
|
|
|
|
|
g_system->copyRectToScreen(_splitSurf->getVidMem() + screenOffset,
|
|
|
|
_splitSurf->getWidth(), screenX, screenY, screenWidth, screenHeight);
|
|
|
|
|
|
|
|
} else if (_splitHeight2 > 0) {
|
|
|
|
|
2008-05-03 20:08:46 +00:00
|
|
|
screenOffset = _splitStart * _surfWidth;
|
|
|
|
screenX = 0;
|
|
|
|
screenY = _vm->_height - _splitHeight2;
|
2008-05-13 18:43:26 +00:00
|
|
|
screenWidth = MIN<int>(_surfWidth, _vm->_width);
|
2008-05-03 20:08:46 +00:00
|
|
|
screenHeight = _splitHeight2;
|
|
|
|
|
2008-12-04 18:38:55 +00:00
|
|
|
dirtyRectsApply(0, _splitStart, screenWidth, screenHeight, screenX, screenY);
|
2008-05-03 20:08:46 +00:00
|
|
|
}
|
|
|
|
|
2008-12-04 18:38:55 +00:00
|
|
|
dirtyRectsClear();
|
2007-03-20 14:51:57 +00:00
|
|
|
g_system->updateScreen();
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
2008-12-04 18:38:55 +00:00
|
|
|
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2007-03-29 17:55:39 +00:00
|
|
|
void Video::waitRetrace(bool mouse) {
|
2007-08-19 17:26:06 +00:00
|
|
|
uint32 time = _vm->_util->getTimeKey();
|
2007-03-29 17:55:39 +00:00
|
|
|
retrace(mouse);
|
2007-08-19 17:26:06 +00:00
|
|
|
_vm->_util->delay(MAX(1, 10 - (int)(_vm->_util->getTimeKey() - time)));
|
2007-03-29 17:55:39 +00:00
|
|
|
}
|
|
|
|
|
2007-04-06 13:30:09 +00:00
|
|
|
void Video::sparseRetrace(int max) {
|
|
|
|
uint32 timeKey = _vm->_util->getTimeKey();
|
|
|
|
|
|
|
|
if ((_curSparse++ > max) || ((timeKey - _lastSparse) > 1000)) {
|
|
|
|
_curSparse = 0;
|
|
|
|
retrace(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
_lastSparse = timeKey;
|
|
|
|
}
|
|
|
|
|
2009-06-06 20:03:13 +00:00
|
|
|
void Video::putPixel(int16 x, int16 y, int16 color, SurfaceDesc &dest) {
|
|
|
|
if ((x >= dest.getWidth()) || (x < 0) ||
|
|
|
|
(y >= dest.getHeight()) || (y < 0))
|
2006-05-31 08:44:14 +00:00
|
|
|
return;
|
|
|
|
|
2007-03-20 14:51:57 +00:00
|
|
|
_videoDriver->putPixel(x, y, color, dest);
|
|
|
|
}
|
|
|
|
|
2009-06-06 20:03:13 +00:00
|
|
|
void Video::fillRect(SurfaceDesc &dest, int16 left, int16 top, int16 right,
|
2007-03-20 14:51:57 +00:00
|
|
|
int16 bottom, int16 color) {
|
|
|
|
|
|
|
|
if (_doRangeClamp) {
|
|
|
|
if (left > right)
|
|
|
|
SWAP(left, right);
|
|
|
|
if (top > bottom)
|
|
|
|
SWAP(top, bottom);
|
|
|
|
|
2009-06-06 20:03:13 +00:00
|
|
|
if ((left >= dest.getWidth()) || (right < 0) ||
|
|
|
|
(top >= dest.getHeight()) || (bottom < 0))
|
2007-03-20 14:51:57 +00:00
|
|
|
return;
|
|
|
|
|
2009-06-06 20:03:13 +00:00
|
|
|
left = CLIP(left, (int16)0, (int16)(dest.getWidth() - 1));
|
|
|
|
top = CLIP(top, (int16)0, (int16)(dest.getHeight() - 1));
|
|
|
|
right = CLIP(right, (int16)0, (int16)(dest.getWidth() - 1));
|
|
|
|
bottom = CLIP(bottom, (int16)0, (int16)(dest.getHeight() - 1));
|
2006-01-29 02:27:10 +00:00
|
|
|
}
|
2007-03-20 14:51:57 +00:00
|
|
|
|
|
|
|
_videoDriver->fillRect(dest, left, top, right, bottom, color);
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2009-06-06 20:03:13 +00:00
|
|
|
void Video::drawLine(SurfaceDesc &dest, int16 x0, int16 y0, int16 x1,
|
2007-03-20 14:51:57 +00:00
|
|
|
int16 y1, int16 color) {
|
|
|
|
|
|
|
|
if ((x0 == x1) || (y0 == y1))
|
|
|
|
Video::fillRect(dest, x0, y0, x1, y1, color);
|
|
|
|
else
|
|
|
|
_videoDriver->drawLine(dest, x0, y0, x1, y1, color);
|
|
|
|
}
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2007-03-20 14:51:57 +00:00
|
|
|
/*
|
|
|
|
* The original's version of the Bresenham Algorithm was a bit "unclean"
|
2007-07-01 12:47:07 +00:00
|
|
|
* and produced strange edges at 45, 135, 225 and 315 degrees, so using the
|
2007-03-20 14:51:57 +00:00
|
|
|
* version found in the Wikipedia article about the
|
|
|
|
* "Bresenham's line algorithm" instead
|
|
|
|
*/
|
2009-06-06 20:03:13 +00:00
|
|
|
void Video::drawCircle(SurfaceDesc &dest, int16 x0, int16 y0,
|
2007-03-20 14:51:57 +00:00
|
|
|
int16 radius, int16 color) {
|
|
|
|
int16 f = 1 - radius;
|
|
|
|
int16 ddFx = 0;
|
|
|
|
int16 ddFy = -2 * radius;
|
|
|
|
int16 x = 0;
|
|
|
|
int16 y = radius;
|
2009-09-16 22:19:54 +00:00
|
|
|
int16 tmpPattern = (_vm->_draw->_pattern & 0xFF);
|
2007-03-20 14:51:57 +00:00
|
|
|
|
2009-09-16 22:19:54 +00:00
|
|
|
if (tmpPattern == 0) {
|
|
|
|
putPixel(x0, y0 + radius, color, dest);
|
|
|
|
putPixel(x0, y0 - radius, color, dest);
|
|
|
|
putPixel(x0 + radius, y0, color, dest);
|
|
|
|
putPixel(x0 - radius, y0, color, dest);
|
|
|
|
} else
|
|
|
|
warning ("Video::drawCircle - pattern %d", _vm->_draw->_pattern);
|
2007-03-20 14:51:57 +00:00
|
|
|
|
|
|
|
while (x < y) {
|
|
|
|
if (f >= 0) {
|
|
|
|
y--;
|
|
|
|
ddFy += 2;
|
|
|
|
f += ddFy;
|
|
|
|
}
|
|
|
|
x++;
|
|
|
|
ddFx += 2;
|
2007-09-19 08:40:12 +00:00
|
|
|
f += ddFx + 1;
|
2009-09-16 22:19:54 +00:00
|
|
|
|
|
|
|
switch (tmpPattern) {
|
|
|
|
case -1:
|
|
|
|
fillRect(dest, x0 - y, y0 + x, x0 + y, y0 + x, color);
|
|
|
|
fillRect(dest, x0 - x, y0 + y, x0 + x, y0 + y, color);
|
|
|
|
fillRect(dest, x0 - y, y0 - x, x0 + y, y0 - x, color);
|
|
|
|
fillRect(dest, x0 - x, y0 - y, x0 + x, y0 - y, color);
|
|
|
|
break;
|
|
|
|
case 0:
|
|
|
|
putPixel(x0 + x, y0 + y, color, dest);
|
|
|
|
putPixel(x0 - x, y0 + y, color, dest);
|
|
|
|
putPixel(x0 + x, y0 - y, color, dest);
|
|
|
|
putPixel(x0 - x, y0 - y, color, dest);
|
|
|
|
putPixel(x0 + y, y0 + x, color, dest);
|
|
|
|
putPixel(x0 - y, y0 + x, color, dest);
|
|
|
|
putPixel(x0 + y, y0 - x, color, dest);
|
|
|
|
putPixel(x0 - y, y0 - x, color, dest);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
fillRect(dest, x0 + y - tmpPattern, y0 + x - tmpPattern, x0 + y, y0 + x, color);
|
|
|
|
fillRect(dest, x0 + x - tmpPattern, y0 + y - tmpPattern, x0 + x, y0 + y, color);
|
|
|
|
fillRect(dest, x0 - y, y0 + x - tmpPattern, x0 - y + tmpPattern, y0 + x, color);
|
|
|
|
fillRect(dest, x0 - x, y0 + y - tmpPattern, x0 - x + tmpPattern, y0 + y, color);
|
|
|
|
fillRect(dest, x0 + y - tmpPattern, y0 - x, x0 + y, y0 - x + tmpPattern, color);
|
|
|
|
fillRect(dest, x0 + x - tmpPattern, y0 - y, x0 + x, y0 - y + tmpPattern, color);
|
|
|
|
fillRect(dest, x0 - y, y0 - x, x0 - y + tmpPattern, y0 - x + tmpPattern, color);
|
|
|
|
fillRect(dest, x0 - x, y0 - y, x0 - x + tmpPattern, y0 - y + tmpPattern, color);
|
|
|
|
break;
|
|
|
|
}
|
2007-03-20 14:51:57 +00:00
|
|
|
}
|
|
|
|
}
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2009-06-06 20:03:13 +00:00
|
|
|
void Video::clearSurf(SurfaceDesc &dest) {
|
|
|
|
Video::fillRect(dest, 0, 0, dest.getWidth() - 1, dest.getHeight() - 1, 0);
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2009-06-06 20:03:13 +00:00
|
|
|
void Video::drawSprite(SurfaceDesc &source, SurfaceDesc &dest,
|
2005-04-05 15:07:40 +00:00
|
|
|
int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp) {
|
|
|
|
int16 destRight;
|
|
|
|
int16 destBottom;
|
|
|
|
|
2007-03-20 14:51:57 +00:00
|
|
|
if (_doRangeClamp) {
|
|
|
|
if (left > right)
|
|
|
|
SWAP(left, right);
|
|
|
|
if (top > bottom)
|
|
|
|
SWAP(top, bottom);
|
|
|
|
|
2009-06-06 20:03:13 +00:00
|
|
|
if ((left >= source.getWidth()) || (right < 0) ||
|
|
|
|
(top >= source.getHeight()) || (bottom < 0))
|
2005-04-05 15:07:40 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
if (left < 0) {
|
|
|
|
x -= left;
|
|
|
|
left = 0;
|
|
|
|
}
|
|
|
|
if (top < 0) {
|
|
|
|
y -= top;
|
|
|
|
top = 0;
|
|
|
|
}
|
2009-06-06 20:03:13 +00:00
|
|
|
right = CLIP(right, (int16)0, (int16)(source.getWidth() - 1));
|
|
|
|
bottom = CLIP(bottom, (int16)0, (int16)(source.getHeight() - 1));
|
|
|
|
if (right - left >= source.getWidth())
|
|
|
|
right = left + source.getWidth() - 1;
|
|
|
|
if (bottom - top >= source.getHeight())
|
|
|
|
bottom = top + source.getHeight() - 1;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
if (x < 0) {
|
|
|
|
left -= x;
|
|
|
|
x = 0;
|
|
|
|
}
|
|
|
|
if (y < 0) {
|
|
|
|
top -= y;
|
|
|
|
y = 0;
|
|
|
|
}
|
2009-06-06 20:03:13 +00:00
|
|
|
if ((x >= dest.getWidth()) || (left > right) ||
|
|
|
|
(y >= dest.getHeight()) || (top > bottom))
|
2005-04-05 15:07:40 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
destRight = x + right - left;
|
|
|
|
destBottom = y + bottom - top;
|
2009-06-06 20:03:13 +00:00
|
|
|
if (destRight >= dest.getWidth())
|
|
|
|
right -= destRight - dest.getWidth() + 1;
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2009-06-06 20:03:13 +00:00
|
|
|
if (destBottom >= dest.getHeight())
|
|
|
|
bottom -= destBottom - dest.getHeight() + 1;
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
_videoDriver->drawSprite(source, dest, left, top, right, bottom, x, y, transp);
|
|
|
|
}
|
|
|
|
|
2009-06-06 20:03:13 +00:00
|
|
|
void Video::drawSpriteDouble(SurfaceDesc &source, SurfaceDesc &dest,
|
2009-04-29 19:58:43 +00:00
|
|
|
int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp) {
|
|
|
|
|
|
|
|
_videoDriver->drawSpriteDouble(source, dest, left, top, right, bottom, x, y, transp);
|
|
|
|
}
|
|
|
|
|
2009-07-09 02:54:10 +00:00
|
|
|
void Video::drawLetter(int16 item, int16 x, int16 y, const Font &font,
|
2009-06-06 20:03:13 +00:00
|
|
|
int16 color1, int16 color2, int16 transp, SurfaceDesc &dest) {
|
2009-07-09 02:54:10 +00:00
|
|
|
_videoDriver->drawLetter((unsigned char)item, x, y, font, color1, color2, transp, dest);
|
2006-04-18 09:59:18 +00:00
|
|
|
}
|
|
|
|
|
2007-03-20 14:51:57 +00:00
|
|
|
void Video::drawPackedSprite(byte *sprBuf, int16 width, int16 height,
|
2009-06-06 20:03:13 +00:00
|
|
|
int16 x, int16 y, int16 transp, SurfaceDesc &dest) {
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2006-05-11 19:43:30 +00:00
|
|
|
if (spriteUncompressor(sprBuf, width, height, x, y, transp, dest))
|
2005-04-05 15:07:40 +00:00
|
|
|
return;
|
|
|
|
|
2009-06-06 20:03:13 +00:00
|
|
|
_vm->validateVideoMode(dest._vidMode);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
_videoDriver->drawPackedSprite(sprBuf, width, height, x, y, transp, dest);
|
|
|
|
}
|
|
|
|
|
2009-06-06 20:03:13 +00:00
|
|
|
void Video::drawPackedSprite(const char *path, SurfaceDesc &dest, int width) {
|
2007-04-02 11:05:09 +00:00
|
|
|
byte *data;
|
2007-02-04 15:45:15 +00:00
|
|
|
|
2007-03-20 14:51:57 +00:00
|
|
|
data = _vm->_dataIO->getData(path);
|
2009-06-06 20:03:13 +00:00
|
|
|
drawPackedSprite(data, width, dest.getHeight(), 0, 0, 0, dest);
|
2007-02-04 15:45:15 +00:00
|
|
|
delete[] data;
|
|
|
|
}
|
|
|
|
|
2007-03-20 14:51:57 +00:00
|
|
|
void Video::setPalElem(int16 index, char red, char green, char blue,
|
|
|
|
int16 unused, int16 vidMode) {
|
2005-04-05 15:07:40 +00:00
|
|
|
byte pal[4];
|
|
|
|
|
2007-03-20 14:51:57 +00:00
|
|
|
_vm->validateVideoMode(vidMode);
|
|
|
|
|
2006-01-04 01:48:15 +00:00
|
|
|
_vm->_global->_redPalette[index] = red;
|
|
|
|
_vm->_global->_greenPalette[index] = green;
|
|
|
|
_vm->_global->_bluePalette[index] = blue;
|
2007-03-20 14:51:57 +00:00
|
|
|
setPalColor(pal, red, green, blue);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
|
|
|
g_system->setPalette(pal, index, 1);
|
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Video::setPalette(PalDesc *palDesc) {
|
2005-04-05 15:07:40 +00:00
|
|
|
byte pal[1024];
|
|
|
|
int16 numcolors;
|
|
|
|
|
2007-03-20 14:51:57 +00:00
|
|
|
_vm->validateVideoMode(_vm->_global->_videoMode);
|
2005-04-05 15:07:40 +00:00
|
|
|
|
2007-03-20 14:51:57 +00:00
|
|
|
numcolors = _vm->_global->_setAllPalette ? 256 : 16;
|
|
|
|
for (int i = 0; i < numcolors; i++)
|
|
|
|
setPalColor(pal + i * 4, palDesc->vgaPal[i]);
|
2005-07-30 21:11:48 +00:00
|
|
|
|
2005-04-05 15:07:40 +00:00
|
|
|
g_system->setPalette(pal, 0, numcolors);
|
|
|
|
}
|
|
|
|
|
2006-01-03 23:14:39 +00:00
|
|
|
void Video::setFullPalette(PalDesc *palDesc) {
|
2006-01-04 01:48:15 +00:00
|
|
|
if (_vm->_global->_setAllPalette) {
|
2007-03-20 14:51:57 +00:00
|
|
|
byte pal[1024];
|
|
|
|
Color *colors = palDesc->vgaPal;
|
|
|
|
|
|
|
|
for (int i = 0; i < 256; i++) {
|
2006-01-04 01:48:15 +00:00
|
|
|
_vm->_global->_redPalette[i] = colors[i].red;
|
|
|
|
_vm->_global->_greenPalette[i] = colors[i].green;
|
|
|
|
_vm->_global->_bluePalette[i] = colors[i].blue;
|
2007-03-20 14:51:57 +00:00
|
|
|
setPalColor(pal + i * 4, colors[i]);
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
g_system->setPalette(pal, 0, 256);
|
2007-03-20 14:51:57 +00:00
|
|
|
} else
|
2006-01-03 23:14:39 +00:00
|
|
|
Video::setPalette(palDesc);
|
2005-04-05 15:07:40 +00:00
|
|
|
}
|
|
|
|
|
2007-03-29 17:55:39 +00:00
|
|
|
void Video::setPalette(Color *palette) {
|
|
|
|
Color *palBak;
|
|
|
|
bool setAllPalBak;
|
|
|
|
|
|
|
|
palBak = _vm->_global->_pPaletteDesc->vgaPal;
|
|
|
|
setAllPalBak = _vm->_global->_setAllPalette;
|
|
|
|
|
|
|
|
_vm->_global->_pPaletteDesc->vgaPal = palette;
|
|
|
|
_vm->_global->_setAllPalette = true;
|
|
|
|
setFullPalette(_vm->_global->_pPaletteDesc);
|
|
|
|
|
|
|
|
_vm->_global->_setAllPalette = setAllPalBak;
|
|
|
|
_vm->_global->_pPaletteDesc->vgaPal = palBak;
|
|
|
|
}
|
|
|
|
|
2008-12-04 18:38:55 +00:00
|
|
|
void Video::dirtyRectsClear() {
|
|
|
|
_dirtyRects.clear();
|
|
|
|
_dirtyAll = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Video::dirtyRectsAll() {
|
|
|
|
_dirtyRects.clear();
|
|
|
|
_dirtyAll = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Video::dirtyRectsAdd(int16 left, int16 top, int16 right, int16 bottom) {
|
|
|
|
if (_dirtyAll)
|
|
|
|
return;
|
|
|
|
|
|
|
|
_dirtyRects.push_back(Common::Rect(left, top, right + 1, bottom + 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
void Video::dirtyRectsApply(int left, int top, int width, int height, int x, int y) {
|
|
|
|
byte *vidMem = _vm->_global->_primarySurfDesc->getVidMem();
|
|
|
|
|
|
|
|
if (_dirtyAll) {
|
|
|
|
g_system->copyRectToScreen(vidMem + top * _surfWidth + left,
|
|
|
|
_surfWidth, x, y, width, height);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int right = left + width;
|
|
|
|
int bottom = top + height;
|
|
|
|
|
|
|
|
Common::List<Common::Rect>::const_iterator it;
|
|
|
|
for (it = _dirtyRects.begin(); it != _dirtyRects.end(); ++it) {
|
|
|
|
int l = MAX<int>(left, it->left);
|
|
|
|
int t = MAX<int>(top, it->top);
|
|
|
|
int r = MIN<int>(right, it->right);
|
|
|
|
int b = MIN<int>(bottom, it->bottom);
|
|
|
|
int w = r - l;
|
|
|
|
int h = b - t;
|
|
|
|
|
|
|
|
if ((w <= 0) || (h <= 0))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
byte *v = vidMem + t * _surfWidth + l;
|
|
|
|
|
|
|
|
g_system->copyRectToScreen(v, _surfWidth, x + (l - left), y + (t - top), w, h);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-12-12 02:44:34 +00:00
|
|
|
void Video::initOSD() {
|
|
|
|
const byte palOSD[] = {
|
|
|
|
0, 0, 0, 0,
|
|
|
|
0, 0, 171, 0,
|
|
|
|
0, 171, 0, 0,
|
|
|
|
0, 171, 171, 0,
|
|
|
|
171, 0, 0, 0
|
|
|
|
};
|
|
|
|
|
|
|
|
g_system->setPalette(palOSD, 0, 5);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Video::drawOSDText(const char *text) {
|
|
|
|
const Graphics::Font &font(*FontMan.getFontByUsage(Graphics::FontManager::kOSDFont));
|
|
|
|
uint32 color = 0x2;
|
|
|
|
Graphics::Surface surf;
|
|
|
|
|
2009-01-02 00:52:01 +00:00
|
|
|
surf.create(g_system->getWidth(), font.getFontHeight(), 1);
|
2008-12-12 02:44:34 +00:00
|
|
|
|
|
|
|
font.drawString(&surf, text, 0, 0, surf.w, color, Graphics::kTextAlignCenter);
|
|
|
|
|
|
|
|
int y = g_system->getHeight() / 2 - font.getFontHeight() / 2;
|
|
|
|
g_system->copyRectToScreen((byte *)surf.pixels, surf.pitch, 0, y, surf.w, surf.h);
|
|
|
|
g_system->updateScreen();
|
|
|
|
|
2009-01-02 00:50:53 +00:00
|
|
|
surf.free();
|
2008-12-12 02:44:34 +00:00
|
|
|
}
|
|
|
|
|
2007-03-20 14:51:57 +00:00
|
|
|
} // End of namespace Gob
|