aboutsummaryrefslogtreecommitdiff
path: root/engines/lab/graphics.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/lab/graphics.cpp')
-rw-r--r--engines/lab/graphics.cpp273
1 files changed, 217 insertions, 56 deletions
diff --git a/engines/lab/graphics.cpp b/engines/lab/graphics.cpp
index 3ed28d06f3..a10512df55 100644
--- a/engines/lab/graphics.cpp
+++ b/engines/lab/graphics.cpp
@@ -48,7 +48,16 @@ DisplayMan::DisplayMan(LabEngine *vm) : _vm(vm) {
_screenBytesPerPage = 65536;
_curapen = 0;
- _curBitmap = NULL;
+ _curBitmap = nullptr;
+ _displayBuffer = nullptr;
+ _currentDisplayBuffer = nullptr;
+ _tempScrollData = nullptr;
+
+ _screenWidth = 0;
+ _screenHeight = 0;
+
+ for (int i = 0; i < 256 * 3; i++)
+ _curvgapal[i] = 0;
}
DisplayMan::~DisplayMan() {
@@ -129,8 +138,8 @@ bool DisplayMan::readPict(const char *filename, bool playOnce) {
if (!_vm->_music->_doNotFilestopSoundEffect)
_vm->_music->stopSoundEffect();
- DispBitMap->_bytesPerRow = _vm->_screenWidth;
- DispBitMap->_rows = _vm->_screenHeight;
+ DispBitMap->_bytesPerRow = _screenWidth;
+ DispBitMap->_rows = _screenHeight;
DispBitMap->_flags = BITMAPF_VIDEO;
_vm->_anim->readDiff(_curBitmap, playOnce);
@@ -343,15 +352,15 @@ uint32 DisplayMan::flowTextToMem(Image *destIm, void *font, /* the TextAttr
uint16 x1, /* Cords */
uint16 y1, uint16 x2, uint16 y2, const char *str) { /* The text itself */
uint32 res, vgabyte = _screenBytesPerPage;
- byte *tmp = _vm->_currentDisplayBuffer;
+ byte *tmp = _currentDisplayBuffer;
- _vm->_currentDisplayBuffer = destIm->_imageData;
+ _currentDisplayBuffer = destIm->_imageData;
_screenBytesPerPage = (uint32)destIm->_width * (int32)destIm->_height;
- res = _vm->_graphics->flowText(font, spacing, pencolor, backpen, fillback, centerh, centerv, output, x1, y1, x2, y2, str);
+ res = flowText(font, spacing, pencolor, backpen, fillback, centerh, centerv, output, x1, y1, x2, y2, str);
_screenBytesPerPage = vgabyte;
- _vm->_currentDisplayBuffer = tmp;
+ _currentDisplayBuffer = tmp;
return res;
}
@@ -391,10 +400,6 @@ int32 DisplayMan::longDrawMessage(const char *str) {
return flowTextScaled(_vm->_msgFont, 0, 1, 7, false, true, true, true, 6, 155, 313, 195, str);
}
-void LabEngine::drawStaticMessage(byte index) {
- _graphics->drawMessage(_resource->getStaticText((StaticText)index).c_str());
-}
-
/******************************************************************************/
/* Draws a message to the message box. */
/******************************************************************************/
@@ -442,7 +447,7 @@ void DisplayMan::doScrollBlack() {
byte *tempmem;
Image im;
uint32 size, copysize;
- uint32 *baseAddr;
+ byte *baseAddr;
uint16 width = VGAScaleX(320);
uint16 height = VGAScaleY(149) + SVGACord(2);
byte *mem = new byte[width * height];
@@ -456,7 +461,7 @@ void DisplayMan::doScrollBlack() {
im.readScreenImage(0, 0);
_vm->_music->updateMusic();
- baseAddr = (uint32 *)_vm->getCurrentDrawingBuffer();
+ baseAddr = getCurrentDrawingBuffer();
uint16 by = VGAScaleX(4);
uint16 nheight = height;
@@ -467,7 +472,7 @@ void DisplayMan::doScrollBlack() {
if (!_vm->_isHiRes)
_vm->waitTOF();
- baseAddr = (uint32 *)_vm->getCurrentDrawingBuffer();
+ baseAddr = getCurrentDrawingBuffer();
if (by > nheight)
by = nheight;
@@ -510,20 +515,17 @@ void DisplayMan::doScrollBlack() {
}
void DisplayMan::copyPage(uint16 width, uint16 height, uint16 nheight, uint16 startline, byte *mem) {
- uint32 size, offSet, copysize;
- uint16 curPage;
- uint32 *baseAddr;
+ byte *baseAddr = getCurrentDrawingBuffer();
- baseAddr = (uint32 *)_vm->getCurrentDrawingBuffer();
-
- size = (int32)(height - nheight) * (int32)width;
+ uint32 size = (int32)(height - nheight) * (int32)width;
mem += startline * width;
- curPage = ((int32)nheight * (int32)width) / _vm->_graphics->_screenBytesPerPage;
- offSet = ((int32)nheight * (int32)width) - (curPage * _vm->_graphics->_screenBytesPerPage);
+ uint16 curPage = ((int32)nheight * (int32)width) / _screenBytesPerPage;
+ uint32 offSet = ((int32)nheight * (int32)width) - (curPage * _screenBytesPerPage);
while (size) {
- if (size > (_vm->_graphics->_screenBytesPerPage - offSet))
- copysize = _vm->_graphics->_screenBytesPerPage - offSet;
+ uint32 copysize;
+ if (size > (_screenBytesPerPage - offSet))
+ copysize = _screenBytesPerPage - offSet;
else
copysize = size;
@@ -553,7 +555,7 @@ void DisplayMan::doScrollWipe(char *filename) {
_vm->_anim->_isBM = true;
readPict(filename, true);
- _vm->setPalette(_vm->_anim->_diffPalette, 256);
+ setPalette(_vm->_anim->_diffPalette, 256);
_vm->_anim->_isBM = false;
byte *mem = _vm->_anim->_rawDiffBM._planes[0];
@@ -664,7 +666,7 @@ void DisplayMan::doTransWipe(CloseDataPtr *cPtr, char *filename) {
linesdone = 0;
}
- _vm->overlayRect(0, 0, curY, _vm->_screenWidth - 1, curY + 1);
+ overlayRect(0, 0, curY, _screenWidth - 1, curY + 1);
curY += 4;
linesdone++;
}
@@ -682,7 +684,7 @@ void DisplayMan::doTransWipe(CloseDataPtr *cPtr, char *filename) {
linesdone = 0;
}
- rectFill(0, curY, _vm->_screenWidth - 1, curY + 1);
+ rectFill(0, curY, _screenWidth - 1, curY + 1);
curY += 4;
linesdone++;
}
@@ -695,17 +697,17 @@ void DisplayMan::doTransWipe(CloseDataPtr *cPtr, char *filename) {
else
_vm->_curFileName = getPictName(cPtr);
- byte *BitMapMem = readPictToMem(_vm->_curFileName, _vm->_screenWidth, lastY + 5);
- _vm->setPalette(_vm->_anim->_diffPalette, 256);
+ byte *BitMapMem = readPictToMem(_vm->_curFileName, _screenWidth, lastY + 5);
+ setPalette(_vm->_anim->_diffPalette, 256);
if (BitMapMem) {
- imSource._width = _vm->_screenWidth;
+ imSource._width = _screenWidth;
imSource._height = lastY;
imSource._imageData = BitMapMem;
- imDest._width = _vm->_screenWidth;
- imDest._height = _vm->_screenHeight;
- imDest._imageData = _vm->getCurrentDrawingBuffer();
+ imDest._width = _screenWidth;
+ imDest._height = _screenHeight;
+ imDest._imageData = getCurrentDrawingBuffer();
for (uint16 i = 0; i < 2; i++) {
curY = i * 2;
@@ -717,10 +719,10 @@ void DisplayMan::doTransWipe(CloseDataPtr *cPtr, char *filename) {
linesdone = 0;
}
- imDest._imageData = _vm->getCurrentDrawingBuffer();
+ imDest._imageData = getCurrentDrawingBuffer();
- imSource.blitBitmap(0, curY, &imDest, 0, curY, _vm->_screenWidth, 2, false);
- _vm->overlayRect(0, 0, curY, _vm->_screenWidth - 1, curY + 1);
+ imSource.blitBitmap(0, curY, &imDest, 0, curY, _screenWidth, 2, false);
+ overlayRect(0, 0, curY, _screenWidth - 1, curY + 1);
curY += 4;
linesdone++;
}
@@ -736,12 +738,12 @@ void DisplayMan::doTransWipe(CloseDataPtr *cPtr, char *filename) {
linesdone = 0;
}
- imDest._imageData = _vm->getCurrentDrawingBuffer();
+ imDest._imageData = getCurrentDrawingBuffer();
if (curY == lastY)
- imSource.blitBitmap(0, curY, &imDest, 0, curY, _vm->_screenWidth, 1, false);
+ imSource.blitBitmap(0, curY, &imDest, 0, curY, _screenWidth, 1, false);
else
- imSource.blitBitmap(0, curY, &imDest, 0, curY, _vm->_screenWidth, 2, false);
+ imSource.blitBitmap(0, curY, &imDest, 0, curY, _screenWidth, 2, false);
curY += 4;
linesdone++;
@@ -774,7 +776,7 @@ void DisplayMan::doWipe(uint16 wipeType, CloseDataPtr *cPtr, char *filename) {
void DisplayMan::blackScreen() {
byte pal[256 * 3];
memset(pal, 0, 248 * 3);
- _vm->writeColorRegs(pal, 8, 248);
+ writeColorRegs(pal, 8, 248);
g_system->delayMillis(32);
}
@@ -785,7 +787,7 @@ void DisplayMan::blackScreen() {
void DisplayMan::whiteScreen() {
byte pal[256 * 3];
memset(pal, 255, 248 * 3);
- _vm->writeColorRegs(pal, 8, 248);
+ writeColorRegs(pal, 8, 248);
}
/*****************************************************************************/
@@ -794,7 +796,7 @@ void DisplayMan::whiteScreen() {
void DisplayMan::blackAllScreen() {
byte pal[256 * 3];
memset(pal, 0, 256 * 3);
- _vm->writeColorRegs(pal, 0, 256);
+ writeColorRegs(pal, 0, 256);
g_system->delayMillis(32);
}
@@ -938,14 +940,14 @@ void DisplayMan::rectFill(uint16 x1, uint16 y1, uint16 x2, uint16 y2) {
int w = x2 - x1 + 1;
int h = y2 - y1 + 1;
- if (x1 + w > _vm->_screenWidth)
- w = _vm->_screenWidth - x1;
+ if (x1 + w > _screenWidth)
+ w = _screenWidth - x1;
- if (y1 + h > _vm->_screenHeight)
- h = _vm->_screenHeight - y1;
+ if (y1 + h > _screenHeight)
+ h = _screenHeight - y1;
if ((w > 0) && (h > 0)) {
- char *d = (char *)_vm->getCurrentDrawingBuffer() + y1 * _vm->_screenWidth + x1;
+ char *d = (char *)getCurrentDrawingBuffer() + y1 * _screenWidth + x1;
while (h-- > 0) {
char *dd = d;
@@ -955,7 +957,7 @@ void DisplayMan::rectFill(uint16 x1, uint16 y1, uint16 x2, uint16 y2) {
*dd++ = _curapen;
}
- d += _vm->_screenWidth;
+ d += _screenWidth;
}
}
}
@@ -979,7 +981,7 @@ void DisplayMan::drawHLine(uint16 x1, uint16 y, uint16 x2) {
}
void DisplayMan::screenUpdate() {
- g_system->copyRectToScreen(_vm->_displayBuffer, _vm->_screenWidth, 0, 0, _vm->_screenWidth, _vm->_screenHeight);
+ g_system->copyRectToScreen(_displayBuffer, _screenWidth, 0, 0, _screenWidth, _screenHeight);
g_system->updateScreen();
_vm->_event->processInput();
@@ -990,17 +992,176 @@ void DisplayMan::screenUpdate() {
/*****************************************************************************/
bool DisplayMan::createScreen(bool hiRes) {
if (hiRes) {
- _vm->_screenWidth = 640;
- _vm->_screenHeight = 480;
+ _screenWidth = 640;
+ _screenHeight = 480;
} else {
- _vm->_screenWidth = 320;
- _vm->_screenHeight = 200;
+ _screenWidth = 320;
+ _screenHeight = 200;
}
- _screenBytesPerPage = _vm->_screenWidth * _vm->_screenHeight;
-
- _vm->_displayBuffer = new byte[_screenBytesPerPage]; // FIXME: Memory leak!
+ _screenBytesPerPage = _screenWidth * _screenHeight;
+ _displayBuffer = new byte[_screenBytesPerPage]; // FIXME: Memory leak!
return true;
}
+/*****************************************************************************/
+/* Converts an Amiga palette (up to 16 colors) to a VGA palette, then sets */
+/* the VGA palette. */
+/*****************************************************************************/
+void DisplayMan::setAmigaPal(uint16 *pal, uint16 numColors) {
+ byte vgaPal[16 * 3];
+ uint16 vgaIdx = 0;
+
+ if (numColors > 16)
+ numColors = 16;
+
+ for (uint16 i = 0; i < numColors; i++) {
+ vgaPal[vgaIdx++] = (byte)(((pal[i] & 0xf00) >> 8) << 2);
+ vgaPal[vgaIdx++] = (byte)(((pal[i] & 0x0f0) >> 4) << 2);
+ vgaPal[vgaIdx++] = (byte)(((pal[i] & 0x00f)) << 2);
+ }
+
+ writeColorRegs(vgaPal, 0, 16);
+ _vm->waitTOF();
+}
+
+/*****************************************************************************/
+/* Writes any number of the 256 color registers. */
+/* first: the number of the first color register to write. */
+/* numreg: the number of registers to write */
+/* buf: a char pointer which contains the selected color registers. */
+/* Each value representing a color register occupies 3 bytes in */
+/* the array. The order is red, green then blue. The first byte */
+/* in the array is the red component of the first element selected.*/
+/* The length of the buffer is 3 times the number of registers */
+/* selected. */
+/*****************************************************************************/
+void DisplayMan::writeColorRegs(byte *buf, uint16 first, uint16 numreg) {
+ byte tmp[256 * 3];
+
+ for (int i = 0; i < 256 * 3; i++) {
+ tmp[i] = buf[i] * 4;
+ }
+
+ g_system->getPaletteManager()->setPalette(tmp, first, numreg);
+
+ memcpy(&(_curvgapal[first * 3]), buf, numreg * 3);
+}
+
+void DisplayMan::setPalette(void *cmap, uint16 numcolors) {
+ if (memcmp(cmap, _curvgapal, numcolors * 3) != 0)
+ writeColorRegs((byte *)cmap, 0, numcolors);
+}
+
+/*****************************************************************************/
+/* Returns the base address of the current VGA display. */
+/*****************************************************************************/
+byte *DisplayMan::getCurrentDrawingBuffer() {
+ if (_currentDisplayBuffer)
+ return _currentDisplayBuffer;
+
+ return _displayBuffer;
+}
+
+/*****************************************************************************/
+/* Overlays a region on the screen using the desired pen color. */
+/*****************************************************************************/
+void DisplayMan::overlayRect(uint16 pencolor, uint16 x1, uint16 y1, uint16 x2, uint16 y2) {
+ int w = x2 - x1 + 1;
+ int h = y2 - y1 + 1;
+
+ if (x1 + w > _screenWidth)
+ w = _screenWidth - x1;
+
+ if (y1 + h > _screenHeight)
+ h = _screenHeight - y1;
+
+ if ((w > 0) && (h > 0)) {
+ char *d = (char *)getCurrentDrawingBuffer() + y1 * _screenWidth + x1;
+
+ while (h-- > 0) {
+ char *dd = d;
+ int ww = w;
+
+ if (y1 & 1) {
+ dd++;
+ ww--;
+ }
+
+ while (ww > 0) {
+ *dd = pencolor;
+ dd += 2;
+ ww -= 2;
+ }
+
+ d += _screenWidth;
+ y1++;
+ }
+ }
+}
+
+/*****************************************************************************/
+/* Scrolls the display in the x direction by blitting. */
+/* The _tempScrollData variable must be initialized to some memory, or this */
+/* function will fail. */
+/*****************************************************************************/
+void DisplayMan::scrollDisplayX(int16 dx, uint16 x1, uint16 y1, uint16 x2, uint16 y2) {
+ Image im;
+ uint16 temp;
+
+ im._imageData = _tempScrollData;
+
+ if (x1 > x2) {
+ temp = x2;
+ x2 = x1;
+ x1 = temp;
+ }
+
+ if (y1 > y2) {
+ temp = y2;
+ y2 = y1;
+ y1 = temp;
+ }
+
+ im._width = x2 - x1 + 1 - dx;
+ im._height = y2 - y1 + 1;
+
+ im.readScreenImage(x1, y1);
+ im.drawImage(x1 + dx, y1);
+
+ setAPen(0);
+ rectFill(x1, y1, x1 + dx - 1, y2);
+}
+
+/*****************************************************************************/
+/* Scrolls the display in the y direction by blitting. */
+/*****************************************************************************/
+void DisplayMan::scrollDisplayY(int16 dy, uint16 x1, uint16 y1, uint16 x2, uint16 y2) {
+ Image im;
+ uint16 temp;
+
+ im._imageData = _tempScrollData;
+
+ if (x1 > x2) {
+ temp = x2;
+ x2 = x1;
+ x1 = temp;
+ }
+
+ if (y1 > y2) {
+ temp = y2;
+ y2 = y1;
+ y1 = temp;
+ }
+
+ im._width = x2 - x1 + 1;
+ im._height = y2 - y1 + 1 - dy;
+
+ im.readScreenImage(x1, y1);
+ im.drawImage(x1, y1 + dy);
+
+ setAPen(0);
+ rectFill(x1, y1, x2, y1 + dy - 1);
+}
+
} // End of namespace Lab