aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra/screen.cpp
diff options
context:
space:
mode:
authorJohannes Schickel2008-04-12 23:17:21 +0000
committerJohannes Schickel2008-04-12 23:17:21 +0000
commit1f91dc03846caecc0651101f54ad25f1864ae132 (patch)
treebcb81be8cb19781ef4098810f8aacafe755cbf48 /engines/kyra/screen.cpp
parent91e1a6b7be34e2cbb52826c28ce210b15bb19f1e (diff)
downloadscummvm-rg350-1f91dc03846caecc0651101f54ad25f1864ae132.tar.gz
scummvm-rg350-1f91dc03846caecc0651101f54ad25f1864ae132.tar.bz2
scummvm-rg350-1f91dc03846caecc0651101f54ad25f1864ae132.zip
- some refactoring for Kyra3
- removed unneeded map code in KyraEngine_v3 svn-id: r31488
Diffstat (limited to 'engines/kyra/screen.cpp')
-rw-r--r--engines/kyra/screen.cpp567
1 files changed, 345 insertions, 222 deletions
diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp
index 9abc0cbd80..8135dbb2af 100644
--- a/engines/kyra/screen.cpp
+++ b/engines/kyra/screen.cpp
@@ -33,8 +33,6 @@
namespace Kyra {
-#define BITBLIT_RECTS 10
-
Screen::Screen(KyraEngine *vm, OSystem *system)
: _system(system), _vm(vm) {
}
@@ -62,21 +60,6 @@ Screen::~Screen() {
delete [] _palettes[i];
}
- delete [] _bitBlitRects;
-
- for (int i = 0; i < ARRAYSIZE(_saveLoadPage); ++i) {
- delete [] _saveLoadPage[i];
- _saveLoadPage[i] = 0;
- }
-
- for (int i = 0; i < ARRAYSIZE(_saveLoadPageOvl); ++i) {
- delete [] _saveLoadPageOvl[i];
- _saveLoadPageOvl[i] = 0;
- }
-
- delete [] _unkPtr1;
- delete [] _unkPtr2;
-
delete [] _dirtyRects;
}
@@ -125,7 +108,7 @@ bool Screen::init() {
}
setScreenPalette(_currentPalette);
- _curDim = &_screenDimTable[0];
+ _curDim = 0;
_charWidth = 0;
_charOffset = 0;
memset(_fonts, 0, sizeof(_fonts));
@@ -138,20 +121,6 @@ bool Screen::init() {
_mouseLockCount = 1;
CursorMan.showMouse(false);
- _bitBlitRects = new Rect[BITBLIT_RECTS];
- assert(_bitBlitRects);
- memset(_bitBlitRects, 0, sizeof(Rect)*BITBLIT_RECTS);
- _bitBlitNum = 0;
- memset(_saveLoadPage, 0, sizeof(_saveLoadPage));
- memset(_saveLoadPageOvl, 0, sizeof(_saveLoadPageOvl));
-
- _unkPtr1 = new uint8[getRectSize(1, 144)];
- assert(_unkPtr1);
- memset(_unkPtr1, 0, getRectSize(1, 144));
- _unkPtr2 = new uint8[getRectSize(1, 144)];
- assert(_unkPtr2);
- memset(_unkPtr2, 0, getRectSize(1, 144));
-
_forceFullUpdate = false;
_numDirtyRects = 0;
_dirtyRects = new Rect[kMaxDirtyRects];
@@ -877,11 +846,6 @@ void Screen::setAnimBlockPtr(int size) {
_animBlockSize = size;
}
-void Screen::setTextColorMap(const uint8 *cmap) {
- debugC(9, kDebugLevelScreen, "Screen::setTextColorMap(%p)", (const void *)cmap);
- setTextColor(cmap, 0, 11);
-}
-
void Screen::setTextColor(const uint8 *cmap, int a, int b) {
debugC(9, kDebugLevelScreen, "Screen::setTextColor(%p, %d, %d)", (const void *)cmap, a, b);
memcpy(&_textColorsMap[a], cmap, b-a+1);
@@ -1108,18 +1072,6 @@ void Screen::drawCharANSI(uint8 c, int x, int y) {
addDirtyRect(x, y, charWidth, *(fnt->fontData + fnt->charSizeOffset + 4));
}
-void Screen::setScreenDim(int dim) {
- debugC(9, kDebugLevelScreen, "Screen::setScreenDim(%d)", dim);
- assert(dim < _screenDimTableCount);
- _curDim = &_screenDimTable[dim];
-}
-
-const ScreenDim *Screen::getScreenDim(int dim) {
- debugC(9, kDebugLevelScreen, "Screen::getScreenDim(%d)", dim);
- assert(dim < _screenDimTableCount);
- return &_screenDimTable[dim];
-}
-
void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd, int flags, ...) {
debugC(9, kDebugLevelScreen, "Screen::drawShape(%d, %p, %d, %d, %d, 0x%.04X, ...)", pageNum, (const void *)shapeData, x, y, sd, flags);
if (!shapeData)
@@ -2386,20 +2338,6 @@ int16 Screen::encodeShapeAndCalculateSize(uint8 *from, uint8 *to, int size_to) {
return (to - toPtr);
}
-int Screen::getRectSize(int x, int y) {
- if (x < 1)
- x = 1;
- else if (x > 40)
- x = 40;
-
- if (y < 1)
- y = 1;
- else if (y > 200)
- y = 200;
-
- return ((x*y) << 3);
-}
-
void Screen::hideMouse() {
debugC(9, kDebugLevelScreen, "Screen::hideMouse()");
++_mouseLockCount;
@@ -2416,6 +2354,11 @@ void Screen::showMouse() {
_mouseLockCount--;
}
+
+bool Screen::isMouseVisible() const {
+ return _mouseLockCount == 0;
+}
+
void Screen::setShapePages(int page1, int page2) {
debugC(9, kDebugLevelScreen, "Screen::setShapePages(%d, %d)", page1, page2);
_shapePages[0] = _pagePtrs[page1];
@@ -2526,6 +2469,45 @@ byte Screen::getShapeFlag2(int x, int y) {
return color;
}
+int Screen::getDrawLayer(int x, int y) {
+ debugC(9, kDebugLevelScreen, "Screen::getDrawLayer(%d, %d)", x, y);
+ int xpos = x - 8;
+ int ypos = y - 1;
+ int layer = 1;
+
+ for (int curX = xpos; curX < xpos + 16; ++curX) {
+ int tempLayer = getShapeFlag2(curX, ypos);
+
+ if (layer < tempLayer)
+ layer = tempLayer;
+
+ if (layer >= 7)
+ return 7;
+ }
+ return layer;
+}
+
+int Screen::getDrawLayer2(int x, int y, int height) {
+ debugC(9, kDebugLevelScreen, "Screen::getDrawLayer2(%d, %d, %d)", x, y, height);
+ int xpos = x - 8;
+ int ypos = y - 1;
+ int layer = 1;
+
+ for (int useX = xpos; useX < xpos + 16; ++useX) {
+ for (int useY = ypos - height; useY < ypos; ++useY) {
+ int tempLayer = getShapeFlag2(useX, useY);
+
+ if (tempLayer > layer)
+ layer = tempLayer;
+
+ if (tempLayer >= 7)
+ return 7;
+ }
+ }
+ return layer;
+}
+
+
int Screen::setNewShapeHeight(uint8 *shape, int height) {
debugC(9, kDebugLevelScreen, "Screen::setNewShapeHeight(%p, %d)", (const void *)shape, height);
if (_vm->gameFlags().useAltShapeHeader)
@@ -2546,81 +2528,6 @@ int Screen::resetShapeHeight(uint8 *shape) {
return oldHeight;
}
-void Screen::addBitBlitRect(int x, int y, int w, int h) {
- debugC(9, kDebugLevelScreen, "Screen::addBitBlitRects(%d, %d, %d, %d)", x, y, w, h);
- if (_bitBlitNum >= BITBLIT_RECTS)
- error("too many bit blit rects");
-
- _bitBlitRects[_bitBlitNum].x = x;
- _bitBlitRects[_bitBlitNum].y = y;
- _bitBlitRects[_bitBlitNum].x2 = w;
- _bitBlitRects[_bitBlitNum].y2 = h;
- ++_bitBlitNum;
-}
-
-void Screen::bitBlitRects() {
- debugC(9, kDebugLevelScreen, "Screen::bitBlitRects()");
- Rect *cur = _bitBlitRects;
- while (_bitBlitNum) {
- _bitBlitNum--;
- copyRegion(cur->x, cur->y, cur->x, cur->y, cur->x2, cur->y2, 2, 0);
- ++cur;
- }
-}
-
-void Screen::savePageToDisk(const char *file, int page) {
- debugC(9, kDebugLevelScreen, "Screen::savePageToDisk('%s', %d)", file, page);
- if (!_saveLoadPage[page/2]) {
- _saveLoadPage[page/2] = new uint8[SCREEN_W * SCREEN_H];
- assert(_saveLoadPage[page/2]);
- }
- memcpy(_saveLoadPage[page/2], getPagePtr(page), SCREEN_W * SCREEN_H);
-
- if (_useOverlays) {
- if (!_saveLoadPageOvl[page/2]) {
- _saveLoadPageOvl[page/2] = new uint8[SCREEN_OVL_SJIS_SIZE];
- assert(_saveLoadPageOvl[page/2]);
- }
-
- uint8 *srcPage = getOverlayPtr(page);
- if (!srcPage) {
- warning("trying to save unsupported overlay page %d", page);
- return;
- }
-
- memcpy(_saveLoadPageOvl[page/2], srcPage, SCREEN_OVL_SJIS_SIZE);
- }
-}
-
-void Screen::loadPageFromDisk(const char *file, int page) {
- debugC(9, kDebugLevelScreen, "Screen::loadPageFromDisk('%s', %d)", file, page);
- copyBlockToPage(page, 0, 0, SCREEN_W, SCREEN_H, _saveLoadPage[page/2]);
- delete [] _saveLoadPage[page/2];
-
- if (_saveLoadPageOvl[page/2]) {
- uint8 *dstPage = getOverlayPtr(page);
- if (!dstPage) {
- warning("trying to restore unsupported overlay page %d", page);
- return;
- }
-
- memcpy(dstPage, _saveLoadPageOvl[page/2], SCREEN_OVL_SJIS_SIZE);
- delete [] _saveLoadPageOvl[page/2];
- _saveLoadPageOvl[page/2] = 0;
- } _saveLoadPage[page/2] = 0;
-}
-
-void Screen::deletePageFromDisk(int page) {
- debugC(9, kDebugLevelScreen, "Screen::deletePageFromDisk(%d)", page);
- delete [] _saveLoadPage[page/2];
- _saveLoadPage[page/2] = 0;
-
- if (_saveLoadPageOvl[page/2]) {
- delete [] _saveLoadPageOvl[page/2];
- _saveLoadPageOvl[page/2] = 0;
- }
-}
-
void Screen::blockInRegion(int x, int y, int width, int height) {
debugC(9, kDebugLevelScreen, "Screen::blockInRegion(%d, %d, %d, %d)", x, y, width, height);
assert(_shapePages[0]);
@@ -2657,90 +2564,6 @@ void Screen::rectClip(int &x, int &y, int w, int h) {
y = 200 - h;
}
-int Screen::getDrawLayer(int x, int y) {
- debugC(9, kDebugLevelScreen, "Screen::getDrawLayer(%d, %d)", x, y);
- int xpos = x - 8;
- int ypos = y - 1;
- int layer = 1;
-
- for (int curX = xpos; curX < xpos + 16; ++curX) {
- int tempLayer = getShapeFlag2(curX, ypos);
-
- if (layer < tempLayer)
- layer = tempLayer;
-
- if (layer >= 7)
- return 7;
- }
- return layer;
-}
-
-int Screen::getDrawLayer2(int x, int y, int height) {
- debugC(9, kDebugLevelScreen, "Screen::getDrawLayer2(%d, %d, %d)", x, y, height);
- int xpos = x - 8;
- int ypos = y - 1;
- int layer = 1;
-
- for (int useX = xpos; useX < xpos + 16; ++useX) {
- for (int useY = ypos - height; useY < ypos; ++useY) {
- int tempLayer = getShapeFlag2(useX, useY);
-
- if (tempLayer > layer)
- layer = tempLayer;
-
- if (tempLayer >= 7)
- return 7;
- }
- }
- return layer;
-}
-
-void Screen::copyBackgroundBlock(int x, int page, int flag) {
- debugC(9, kDebugLevelScreen, "Screen::copyBackgroundBlock(%d, %d, %d)", x, page, flag);
-
- if (x < 1)
- return;
-
- int height = 128;
- if (flag)
- height += 8;
- if (!(x & 1))
- ++x;
- if (x == 19)
- x = 17;
-
- uint8 *ptr1 = _unkPtr1;
- uint8 *ptr2 = _unkPtr2;
- int oldVideoPage = _curPage;
- _curPage = page;
-
- int curX = x;
- hideMouse();
- copyRegionToBuffer(_curPage, 8, 8, 8, height, ptr2);
- for (int i = 0; i < 19; ++i) {
- int tempX = curX + 1;
- copyRegionToBuffer(_curPage, tempX<<3, 8, 8, height, ptr1);
- copyBlockToPage(_curPage, tempX<<3, 8, 8, height, ptr2);
- int newXPos = curX + x;
- if (newXPos > 37)
- newXPos = newXPos % 38;
-
- tempX = newXPos + 1;
- copyRegionToBuffer(_curPage, tempX<<3, 8, 8, height, ptr2);
- copyBlockToPage(_curPage, tempX<<3, 8, 8, height, ptr1);
- curX += x*2;
- if (curX > 37) {
- curX = curX % 38;
- }
- }
- showMouse();
- _curPage = oldVideoPage;
-}
-
-void Screen::copyBackgroundBlock2(int x) {
- copyBackgroundBlock(x, 4, 1);
-}
-
void Screen::shakeScreen(int times) {
debugC(9, kDebugLevelScreen, "Screen::shakeScreen(%d)", times);
@@ -3217,5 +3040,305 @@ void Screen::drawCharSJIS(uint16 c, int x, int y) {
}
}
+#pragma mark -
+
+uint8 *ScreenEx::generateOverlay(const uint8 *palette, uint8 *buffer, int startColor, uint16 factor) {
+ if (!palette || !buffer)
+ return buffer;
+
+ factor = MIN<uint16>(255, factor);
+ factor >>= 1;
+ factor &= 0xFF;
+
+ const byte col1 = palette[startColor * 3 + 0];
+ const byte col2 = palette[startColor * 3 + 1];
+ const byte col3 = palette[startColor * 3 + 2];
+
+ uint8 *dst = buffer;
+ *dst++ = 0;
+
+ for (int i = 1; i != 255; ++i) {
+ uint8 processedPalette[3];
+ const uint8 *src = palette + i*3;
+ byte col;
+
+ col = *src++;
+ col -= ((((col - col1) * factor) << 1) >> 8) & 0xFF;
+ processedPalette[0] = col;
+
+ col = *src++;
+ col -= ((((col - col2) * factor) << 1) >> 8) & 0xFF;
+ processedPalette[1] = col;
+
+ col = *src++;
+ col -= ((((col - col3) * factor) << 1) >> 8) & 0xFF;
+ processedPalette[2] = col;
+
+ *dst++ = findLeastDifferentColor(processedPalette, palette+3, 255)+1;
+ }
+
+ return buffer;
+}
+
+void ScreenEx::applyOverlay(int x, int y, int w, int h, int pageNum, const uint8 *overlay) {
+ if (pageNum == 0 || pageNum == 1)
+ addDirtyRect(x, y, w, h);
+
+ uint8 *dst = getPagePtr(pageNum) + y * 320 + x;
+ while (h--) {
+ for (int wi = 0; wi < w; ++wi) {
+ uint8 index = *dst;
+ *dst++ = overlay[index];
+ }
+ dst += 320 - w;
+ }
+}
+
+int ScreenEx::findLeastDifferentColor(const uint8 *paletteEntry, const uint8 *palette, uint16 numColors) {
+ int m = 0x7fff;
+ int r = 0x101;
+
+ for (int i = 0; i < numColors; i++) {
+ int v = paletteEntry[0] - *palette++;
+ int c = v * v;
+ v = paletteEntry[1] - *palette++;
+ c += (v * v);
+ v = paletteEntry[2] - *palette++;
+ c += (v * v);
+
+ if (c <= m) {
+ m = c;
+ r = i;
+ }
+ }
+
+ return r;
+}
+
+void ScreenEx::copyWsaRect(int x, int y, int w, int h, int dimState, int plotFunc, const uint8 *src,
+ int unk1, const uint8 *unkPtr1, const uint8 *unkPtr2) {
+ uint8 *dstPtr = getPagePtr(_curPage);
+ uint8 *origDst = dstPtr;
+
+ const ScreenDim *dim = getScreenDim(dimState);
+ int dimX1 = dim->sx << 3;
+ int dimX2 = dim->w << 3;
+ dimX2 += dimX1;
+
+ int dimY1 = dim->sy;
+ int dimY2 = dim->h;
+ dimY2 += dimY1;
+
+ int temp = y - dimY1;
+ if (temp < 0) {
+ if ((temp += h) <= 0)
+ return;
+ else {
+ SWAP(temp, h);
+ y += temp - h;
+ src += (temp - h) * w;
+ }
+ }
+
+ temp = dimY2 - y;
+ if (temp <= 0)
+ return;
+
+ if (temp < h)
+ h = temp;
+
+ int srcOffset = 0;
+ temp = x - dimX1;
+ if (temp < 0) {
+ temp = -temp;
+ srcOffset = temp;
+ x += temp;
+ w -= temp;
+ }
+
+ int srcAdd = 0;
+
+ temp = dimX2 - x;
+ if (temp <= 0)
+ return;
+
+ if (temp < w) {
+ SWAP(w, temp);
+ temp -= w;
+ srcAdd = temp;
+ }
+
+ dstPtr += y * SCREEN_W + x;
+ uint8 *dst = dstPtr;
+
+ if (_curPage == 0 || _curPage == 1)
+ addDirtyRect(x, y, w, h);
+
+ clearOverlayRect(_curPage, x, y, w, h);
+
+ temp = h;
+ while (h--) {
+ src += srcOffset;
+ int cW = w;
+
+ switch (plotFunc) {
+ case 0:
+ memcpy(dst, src, cW);
+ dst += cW; src += cW;
+ break;
+
+ case 1:
+ while (cW--) {
+ uint8 d = *src++;
+ uint8 t = unkPtr1[d];
+ if (t != 0xFF)
+ d = unkPtr2[*dst + (t << 8)];
+ *dst++ = d;
+ }
+ break;
+
+ case 4:
+ while (cW--) {
+ uint8 d = *src++;
+ if (d)
+ *dst = d;
+ ++dst;
+ }
+ break;
+
+ case 5:
+ while (cW--) {
+ uint8 d = *src++;
+ if (d) {
+ uint8 t = unkPtr1[d];
+ if (t != 0xFF)
+ d = unkPtr2[*dst + (t << 8)];
+ *dst = d;
+ }
+ ++dst;
+ }
+ break;
+
+ case 8:
+ case 9:
+ while (cW--) {
+ uint8 d = *src++;
+ uint8 t = _shapePages[0][dst - origDst] & 7;
+ if (unk1 < t)
+ d = _shapePages[1][dst - origDst];
+ *dst++ = d;
+ }
+ break;
+
+ case 12:
+ case 13:
+ while (cW--) {
+ uint8 d = *src++;
+ if (d) {
+ uint8 t = _shapePages[0][dst - origDst] & 7;
+ if (unk1 < t)
+ d = _shapePages[1][dst - origDst];
+ *dst++ = d;
+ } else {
+ d = _shapePages[1][dst - origDst];
+ *dst++ = d;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ dst = (dstPtr += SCREEN_W);
+ src += srcAdd;
+ }
+}
+
+const uint8 *ScreenEx::getPtrToShape(const uint8 *shpFile, int shape) {
+ debugC(9, kDebugLevelScreen, "ScreenEx::getPtrToShape(%p, %d)", (const void *)shpFile, shape);
+ uint16 shapes = READ_LE_UINT16(shpFile);
+
+ if (shapes <= shape)
+ return 0;
+
+ uint32 offset = READ_LE_UINT32(shpFile + (shape << 2) + 2);
+
+ return shpFile + offset + 2;
+}
+
+uint8 *ScreenEx::getPtrToShape(uint8 *shpFile, int shape) {
+ debugC(9, kDebugLevelScreen, "ScreenEx::getPtrToShape(%p, %d)", (void *)shpFile, shape);
+ uint16 shapes = READ_LE_UINT16(shpFile);
+
+ if (shapes <= shape)
+ return 0;
+
+ uint32 offset = READ_LE_UINT32(shpFile + (shape << 2) + 2);
+
+ return shpFile + offset + 2;
+}
+
+int ScreenEx::getShapeScaledWidth(const uint8 *shpFile, int scale) {
+ int width = READ_LE_UINT16(shpFile+3);
+ return (width * scale) >> 8;
+}
+
+int ScreenEx::getShapeScaledHeight(const uint8 *shpFile, int scale) {
+ int height = shpFile[2];
+ return (height * scale) >> 8;
+}
+
+uint16 ScreenEx::getShapeSize(const uint8 *shp) {
+ debugC(9, kDebugLevelScreen, "ScreenEx::getShapeSize(%p)", (const void *)shp);
+
+ return READ_LE_UINT16(shp+6);
+}
+
+uint8 *ScreenEx::makeShapeCopy(const uint8 *src, int index) {
+ debugC(9, kDebugLevelScreen, "ScreenEx::makeShapeCopy(%p, %d)", (const void *)src, index);
+
+ const uint8 *shape = getPtrToShape(src, index);
+ int size = getShapeSize(shape);
+
+ uint8 *copy = new uint8[size];
+ assert(copy);
+ memcpy(copy, shape, size);
+
+ return copy;
+}
+
+int ScreenEx::getLayer(int x, int y) {
+ if (x < 0)
+ x = 0;
+ else if (x >= 320)
+ x = 319;
+ if (y < 0)
+ y = 0;
+ else if (y >= 144)
+ y = 143;
+
+ uint8 pixel = *(getCPagePtr(5) + y * 320 + x);
+ pixel &= 0x7F;
+ pixel >>= 3;
+
+ if (pixel < 1)
+ pixel = 1;
+ else if (pixel > 15)
+ pixel = 15;
+ return pixel;
+}
+
+int ScreenEx::getRectSize(int w, int h) {
+ if (w > 320 || h > 200)
+ return 0;
+ return w*h;
+}
+
+void ScreenEx::setTextColorMap(const uint8 *cmap) {
+ debugC(9, kDebugLevelScreen, "ScreenEx::setTextColorMap(%p)", (const void *)cmap);
+ setTextColor(cmap, 0, 15);
+}
+
} // End of namespace Kyra