From 540d081a6fd4daa31f746ddf30ccc91fb88ea04b Mon Sep 17 00:00:00 2001 From: athrxx Date: Sun, 11 Dec 2011 01:57:03 +0100 Subject: KYRA: (EOB) - initial code base commit --- engines/kyra/screen_eob.cpp | 965 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 965 insertions(+) create mode 100644 engines/kyra/screen_eob.cpp (limited to 'engines/kyra/screen_eob.cpp') diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp new file mode 100644 index 0000000000..eb5a52477b --- /dev/null +++ b/engines/kyra/screen_eob.cpp @@ -0,0 +1,965 @@ +/* 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. + * + * 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 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + + +#if !defined(ENABLE_EOB) +#include "kyra/screen.h" +#endif + +#ifdef ENABLE_EOB + +#include "kyra/eobcommon.h" +#include "kyra/resource.h" + +#include "common/system.h" + +#include "graphics/cursorman.h" + +namespace Kyra { + +Screen_Eob::Screen_Eob(EobCoreEngine *vm, OSystem *system) : Screen(vm, system) { + _shapeFadeMode[0] = _shapeFadeMode[1] = 0; + _shapeFadeInternal = 0; + _fadeData = 0; + _fadeDataIndex = 0; + _dsX1 = _dsX2 = _dsY1 = _dsY2 = 0; + _customDimTable = 0; + _dsTempPage = 0; +} + +Screen_Eob::~Screen_Eob() { + delete[] _fadeData; + delete[] _customDimTable; + delete[] _dsTempPage; +} + +bool Screen_Eob::init() { + if (Screen::init()) { + _customDimTable = new ScreenDim*[_screenDimTableCount]; + memset(_customDimTable, 0, sizeof(ScreenDim *)* _screenDimTableCount); + + _fadeData = _vm->resource()->fileData("FADING.DAT", 0); + + if (!_fadeData) { + _fadeData = new uint8[0x700]; + memset(_fadeData, 0, 0x700); + uint8 *pal = _vm->resource()->fileData("palette1.pal", 0); // EGA: palette0.pal + for (int i = 0; i < 7; i++) + createFadeTable(pal, &_fadeData[i << 8], 18, (i + 1) * 36); + delete[] pal; + } + + _dsTempPage = new uint8[6000]; + + return true; + } + return false; +} + +void Screen_Eob::setScreenDim(int dim) { + assert(dim < _screenDimTableCount); + _curDim = _customDimTable[dim] ? (const ScreenDim *)_customDimTable[dim] : &_screenDimTable[dim]; + _curDimIndex = dim; +} + +const ScreenDim *Screen_Eob::getScreenDim(int dim) { + assert(dim < _screenDimTableCount); + return _customDimTable[dim] ? (const ScreenDim *)_customDimTable[dim] : &_screenDimTable[dim]; +} + +void Screen_Eob::modifyScreenDim(int dim, int x, int y, int w, int h) { + delete _customDimTable[dim]; + _customDimTable[dim] = new ScreenDim; + memcpy(_customDimTable[dim], &_screenDimTable[dim], sizeof(ScreenDim)); + _customDimTable[dim]->sx = x; + _customDimTable[dim]->sy = y; + _customDimTable[dim]->w = w; + _customDimTable[dim]->h = h; + if (dim == _curDimIndex) + setScreenDim(dim); +} + +void Screen_Eob::setClearScreenDim(int dim) { + setScreenDim(dim); + clearCurDim(); +} + +void Screen_Eob::clearCurDim() { + fillRect(_curDim->sx << 3, _curDim->sy, ((_curDim->sx + _curDim->w) << 3) - 1, (_curDim->sy + _curDim->h) - 1, _curDim->unkA); +} + +void Screen_Eob::setMouseCursor(int x, int y, const byte *shape) { + if (!shape) + return; + int mouseW = shape[2] << 3; + int mouseH = shape[3]; + uint8 *cursor = new uint8[mouseW * mouseH]; + fillRect(0, 0, mouseW, mouseH, _cursorColorKey, 8); + drawShape(8, shape, 0, 0, 0); + CursorMan.showMouse(false); + copyRegionToBuffer(8, 0, 0, mouseW, mouseH, cursor); + CursorMan.replaceCursor(cursor, mouseW, mouseH, x, y, _cursorColorKey); + if (isMouseVisible()) + CursorMan.showMouse(true); + delete[] cursor; + + // makes sure that the cursor is drawn + // we do not use Screen::updateScreen here + // so we can be sure that changes to page 0 + // are NOT updated on the real screen here + _system->updateScreen(); +} + +void Screen_Eob::loadFileDataToPage(Common::SeekableReadStream *s, int pageNum, uint32 size) { + s->read(_pagePtrs[pageNum], size); +} + +void Screen_Eob::printShadedText(const char *string, int x, int y, int col1, int col2) { + printText(string, x - 1, y, 12, col2); + printText(string, x, y + 1, 12, 0); + printText(string, x - 1, y + 1, 12, 0); + printText(string, x, y, col1, 0); +} + +void Screen_Eob::loadEobBitmap(const char *file, int tempPage, int destPage) { + loadEobCpsFileToPage(file, 0, tempPage, destPage, -1); + _curPage = 2; +} + +void Screen_Eob::loadEobCpsFileToPage(const char *file, const uint8 *ditheringData, int tempPage, int destPage, int copyToPage) { + char tmp[13]; + sprintf(tmp, "%s.CPS", file); + + Common::SeekableReadStream *s = _vm->resource()->createReadStream(tmp); + bool loadAlternative = false; + if (s) { + // This additional check is necessary since some localized versions of EOB II seem to contain invalid (size zero) cps files + if (s->size()) + loadBitmap(tmp, tempPage, destPage, 0); + else + loadAlternative = true; + + delete s; + } else { + loadAlternative = true; + } + + if (loadAlternative) { + tmp[0] = 'X'; + s = _vm->resource()->createReadStream(tmp); + if (!s) + error("Screen_Eob::loadEobCpsFileToPage(): CPS file loading failed."); + s->seek(768); + loadFileDataToPage(s, destPage, 64000); + delete s; + } + + if (copyToPage == -1) { + return; + } else if (copyToPage == 0) { + copyPage(destPage, 2); + copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK); + } else { + copyPage(destPage, copyToPage); + } +} + +uint8 *Screen_Eob::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool flag) { + uint8 *shp = 0; + uint16 shapesize = 0; + + uint8 *srcPage = getPagePtr(_curPage) + y * 320 + (x << 3); + uint8 *src = srcPage; + + if (flag) { + uint16 h1 = h; + while (h1--) { + uint8 *lineEnd = src + (w << 3); + do { + if (!*src++) { + shapesize++; + uint8 *startZeroPos = src; + while (src != lineEnd && *src == 0) + src++; + + uint16 numZero = src - startZeroPos + 1; + if (numZero >> 8) + shapesize += 2; + } + shapesize++; + } while (src != lineEnd); + + srcPage += 320; + src = srcPage; + } + + shapesize += 4; + + shp = new uint8[shapesize]; + memset (shp, 0, shapesize); + uint8 *dst = shp; + + *dst++ = 0; + *dst++ = (h & 0xff); + *dst++ = (w & 0xff); + *dst++ = (h & 0xff); + + srcPage = getPagePtr(_curPage) + y * 320 + (x << 3); + src = srcPage; + + h1 = h; + while (h1--) { + uint8 *lineEnd = src + (w << 3); + do { + uint8 val = *src++; + if (!val) { + *dst++ = val; + uint8 *startZeroPos = src; + while (src != lineEnd && *src == 0) + src++; + + uint16 numZero = src - startZeroPos + 1; + if (numZero >> 8) { + numZero -= 0xff; + *dst++ = 0xff; + *dst++ = 0; + } + val = (numZero & 0xff); + } + *dst++ = val; + } while (src != lineEnd); + + srcPage += 320; + src = srcPage; + } + + } else { + uint8 nib = 0, col = 0; + uint8 *colorMap = new uint8[0x100]; + memset (colorMap, 0xff, 0x100); + + shapesize = h * (w << 2) + 0x14; + shp = new uint8[shapesize]; + memset (shp, 0, shapesize); + uint8 *dst = shp; + + *dst++ = 1; + *dst++ = (h & 0xff); + *dst++ = (w & 0xff); + *dst++ = (h & 0xff); + memset (dst, 0xff, 0x10); + + uint8 *pal = dst; + dst += 0x10; + + srcPage = getPagePtr(_curPage) + y * 320 + (x << 3); + src = srcPage; + nib = col = 0; + + uint16 h1 = h; + while (h1--) { + uint16 w1 = w << 3; + while (w1--) { + uint8 s = *src++; + uint8 c = colorMap[s]; + if (c == 0xff) { + if (col < 0x10) { + *pal++ = s; + c = colorMap[s] = col++; + if (!col) + c = 0; + } else { + c = 0; + } + } + + if(++nib & 1) { + *dst = c << 4; + } else { + *dst++ |= c; + } + } + srcPage += 320; + src = srcPage; + } + delete [] colorMap; + } + + return shp; +} + +void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd, int flags, ...) { + uint8 *dst = getPagePtr(pageNum); + const uint8 *src = shapeData; + + if (!src) + return; + + va_list args; + va_start(args, flags); + uint8 *ovl = (flags & 2) ? va_arg(args, uint8*) : 0; + va_end(args); + + if (sd != -1) { + const ScreenDim *dm = getScreenDim(sd); + setShapeFrame(dm->sx, dm->sy, dm->sx + dm->w, dm->sy + dm->h); + x += (_dsX1 << 3); + y += _dsY1; + } + + dst += (_dsX1 << 3); + int16 dX = x - (_dsX1 << 3); + int16 dY = y; + int16 dW = _dsX2 - _dsX1; + uint8 flag = *src++; + + uint16 dH = *src++; + uint16 width = (*src++) << 3; + src++; + + int rX = x; + int rY = y; + int rW = width + 8; + int rH = dH; + + uint16 w2 = width; + int d = dY - _dsY1; + + int pixelStep = (flags & 1) ? -1 : 1; + + if (flag) { + const uint8 *pal = ovl ? ovl : src; + src += 16; + + if (d < 0) { + d = -d; + if (d >= dH) + return; + src += (d * (width >> 1)); + d = dY + dH - _dsY1; + if (d >=0) { + dH = d; + dY = _dsY1; + d = _dsY2 - dY; + } + } else { + d = _dsY2 - dY; + } + + if (d < 1) + return; + + if (d < dH) + dH = d; + + int16 cnt1 = 0; + int16 cnt2 = 0; + int16 dXbit1 = dX & 1; + + if (dX < 0) { + width += dX; + d = -dX; + if ((flags & 1)) + src -= (d >> 1); + else + src += (d >> 1); + + if (d >= w2) + return; + + dX = 0; + cnt1++; + } + + d = (dW << 3) - dX; + + if (d < 1) + return; + + if (d < width) { + width = d; + cnt2++; + } + + dst += (dY * 320 + dX); + + if (pageNum == 0 || pageNum == 1) + addDirtyRect(rX, rY, rW, rH); + + int w3 = w2; + dY = 320 - width; + width >>= 1; + w2 >>= 1; + if ((flags & 1)) + src += (w2 - 1); + + int16 w1shr = width; + + if (cnt1 && (dXbit1 & 1)) { + w1shr++; + w2++; + if (!cnt2) + dY += 2; + } + + if (cnt2 && (dXbit1 & 1)) + w1shr++; + + int lineSrcStep = (w2 - w1shr); + if ((flags & 1)) + lineSrcStep = w3 - lineSrcStep; + + while (dH--) { + int16 hpos = width; + uint8 col = 0; + uint8 b = 0; + uint8 nextloop = 0; + + if (cnt1 && dXbit1) { + if (!hpos) + return; + b = *src; + src += pixelStep; + nextloop = 2; + } else { + nextloop = hpos ? 1 : 3; + } + + while (nextloop) { + switch (nextloop) { + case 1: + b = *src; + src += pixelStep; + col = pal[(flags & 1) ? (b & 0x0f) : (b >> 4)]; + if (col) + drawShapeSetPixel(dst, col); + dst++; + + case 2: + col = pal[(flags & 1) ? (b >> 4) : (b & 0x0f)]; + + if (!col) { + nextloop = 4; + break; + } + + drawShapeSetPixel(dst++, col); + nextloop = --hpos ? 1 : 3; + break; + + case 3: + if (cnt2 && dXbit1) { + col = pal[(flags & 1) ? (*src & 0x0f) : (*src >> 4)]; + src += pixelStep; + if (col) + drawShapeSetPixel(dst, col); + dst++; + } + + src += lineSrcStep; + dst += dY; + nextloop = 0; + break; + + case 4: + dst++; + nextloop = --hpos ? 1 : 3; + break; + } + } + } + } else { + uint16 marginLeft = 0; + uint16 marginRight = 0; + + if (d < 0) { + dH += d; + if (dH <= 0) + return; + d = -d; + + for (int ii = 0; ii < d; ii++) { + marginLeft = width; + int i = 0; + do { + for (i = 0; i < marginLeft; i++) + if (!*src++) + break; + + if (!*(src-1) || i < marginLeft) + marginLeft = ++marginLeft - *src++; + else + marginLeft = 0; + + } while (marginLeft); + } + dY = _dsY1; + } + + d = _dsY2 - dY; + + if (d < 1) + return; + + if (d < dH) + dH = d; + + marginLeft = 0; + + if (dX < 0) { + width += dX; + marginLeft = -dX; + + if (marginLeft >= w2) + return; + + dX = 0; + } + + marginRight = 0; + d = (dW << 3) - dX; + + if (d < 1) + return; + + if (d < width) { + width = d; + marginRight = w2 - marginLeft - width; + } + + dst += (y * 320 + dX); + uint8 * dstL = dst; + + if (pageNum == 0 || pageNum == 1) + addDirtyRect(rX, rY, rW, rH); + + while (dH--) { + int16 xpos = (int16) marginLeft; + + if (xpos) { + do { + while (*src && xpos) { + src++; + xpos--; + } + + if (!*src) { + uint8 bt = *++src; + src++; + xpos = xpos - bt; + } + } while (xpos > 0); + } + + dst -= xpos; + xpos += width; + + while (xpos > 0) { + uint8 c = *src++; + + if (c) { + drawShapeSetPixel(dst++, c); + xpos--; + } else { + dst += *src; + xpos -= *src++; + } + } + xpos += marginRight; + + if (xpos) { + do { + while (*src && xpos) { + src++; + xpos--; + } + + if (!*src) { + uint8 bt = *++src; + src++; + xpos = xpos - bt; + } + } while (xpos > 0); + } + + dstL += 320; + dst = dstL; + } + } +} + +void Screen_Eob::drawShapeSetPixel(uint8 * dst, uint8 c) { + if (_shapeFadeMode[0]) { + if (_shapeFadeMode[1]) { + c = *dst; + } else { + _shapeFadeInternal &= 7; + c = *(dst + _shapeFadeInternal++); + } + } + + if (_shapeFadeMode[1]) { + uint8 cnt = _shapeFadeMode[1]; + while (cnt--) + c = _fadeData[_fadeDataIndex + c]; + } + + *dst = c; +} + +const uint8 *Screen_Eob::scaleShape(const uint8 *shapeData, int steps) { + setShapeFadeMode(1, steps ? true : false); + + while (shapeData && steps--) + shapeData = scaleShapeStep(shapeData); + + return shapeData; +} + +const uint8 *Screen_Eob::scaleShapeStep(const uint8 *shp) { + uint8 *d = _dsTempPage; + *d++ = *shp++; + + uint16 h = (*shp++) + 1; + d[0] = d[2] = (h << 1) / 3; + d++; + + uint16 w = *shp++; + uint16 w2 = w << 2; + uint16 t = ((w << 1) % 3) ? 1 : 0; + *d++ = ((w << 1) / 3) + t; + + shp++; + d++; + + int i = 0; + while (i < 16) { + if (!shp[i]) { + i = -i; + break; + } + i++; + } + + if (i >= 0) + i = 0; + else + i = -i; + + _dsScaleTmp = (i << 4) | (i & 0x0f); + memcpy(d, shp, 16); + d += 16; + shp += 16; + + _dsDiv = w2 / 3; + _dsRem = w2 % 3; + + do { + scaleShapeProcessLine(d, shp); + if (!--h) + break; + scaleShapeProcessLine(d, shp); + if (!--h) + break; + shp += w2; + } while (--h); + + return (const uint8 *) _dsTempPage; +} + +void Screen_Eob::replaceShapePalette(uint8 *shp, const uint8 *pal) { + if (*shp != 1) + return; + shp += 4; + memcpy(shp, pal, 16); +} + +void Screen_Eob::applyShapeOverlay(uint8 *shp, int ovlIndex) { + if (*shp != 1) + return; + shp += 4; + uint8 *ovl = getFadeTable(ovlIndex); + for (int i = 0; i < 16; i++) + shp[i] = ovl[shp[i]]; +} + +void Screen_Eob::scaleShapeProcessLine(uint8 *&dst, const uint8 *&src) { + for (int i = 0; i < _dsDiv; i++) { + *dst++ = *src++; + *dst++ = READ_BE_UINT16(src) >> 4; + src += 2; + } + + if (_dsRem == 1) { + *dst++ = *src++; + *dst++ = _dsScaleTmp; + + } if (_dsRem == 2) { + *dst++ = (src[0] & 0xf0) | (src[1] >> 4); + src += 2; + *dst++ = _dsScaleTmp; + *dst++ = _dsScaleTmp; + *dst++ = _dsScaleTmp; + } +} + +void Screen_Eob::fadeTextColor(Palette *pal, int color1, int rate) { + uint8 *col = pal->getData(); + + for (bool loop = true; loop; ) { + loop = true; + uint32 end = _system->getMillis() + 16; + + loop = false; + for (int ii = 0; ii < 3; ii++) { + uint8 c = col[color1 * 3 + ii]; + if (c > rate) { + col[color1 * 3 + ii] -= rate; + loop = true; + } else if (c) { + col[color1 * 3 + ii] = 0; + loop = true; + } + } + + if (loop) { + setScreenPalette(*pal); + updateScreen(); + uint32 cur = _system->getMillis(); + if (end > cur) + _system->delayMillis(end - cur); + } + } +} + +bool Screen_Eob::delayedFadePalStep(Palette *fadePal, Palette *destPal, int rate) { + bool res = false; + + uint8 *s = fadePal->getData(); + uint8 *d = destPal->getData(); + + for (int i = 0; i < 765; i++) { + int fadeVal = *s++; + int dstCur = *d; + int diff = ABS(fadeVal - dstCur); + + if (diff == 0) { + d++; + continue; + } + + res = true; + diff = MIN(diff, rate); + + if (dstCur < fadeVal) + *d += diff; + else + *d -= diff; + d++; + } + + return res; +} + +void Screen_Eob::createFadeTable(uint8 *palData, uint8 *dst, uint8 rootColor, uint8 weight) { + if (!palData) + return; + + uint8 *src = palData + 3 * rootColor; + uint8 r = *src++; + uint8 g = *src++; + uint8 b = *src; + uint8 tr, tg, tb; + src = palData + 3; + + *dst++ = 0; + weight >>= 1; + + for (uint8 i = 1; i; i++) { + uint16 tmp = (uint16)((*src - r) * weight) << 1; + tr = *src++ - ((tmp >> 8) & 0xff); + tmp = (uint16)((*src - g) * weight) << 1; + tg = *src++ - ((tmp >> 8) & 0xff); + tmp = (uint16)((*src - b) * weight) << 1; + tb = *src++ - ((tmp >> 8) & 0xff); + + uint8 * d = palData + 3; + uint16 v = 0xffff; + uint8 col = rootColor; + + for (uint8 ii = 1; ii; ii++) { + int a = *d++ - tr; + int t = a * a; + a = *d++ - tg; + t += (a * a); + a = *d++ - tb; + t += (a * a); + + if (t <= v && (ii == rootColor || ii != i)) { + v = t; + col = ii ; + } + } + *dst++ = col; + } +} + +OldDOSFont::OldDOSFont() { + _data = 0; + _width = _height = _numGlyphs = 0; + _bitmapOffsets = 0; +} + +bool OldDOSFont::load(Common::SeekableReadStream &file) { + unload(); + + _data = new uint8[file.size()]; + assert(_data); + + file.read(_data, file.size()); + if (file.err()) + return false; + + if (file.size() - 2 != READ_LE_UINT16(_data)) + return false; + + _width = _data[0x103]; + _height = _data[0x102]; + _numGlyphs = 255; + + _bitmapOffsets = (uint16 *)(_data + 2); + + for (int i = 0; i < _numGlyphs; ++i) + _bitmapOffsets[i] = READ_LE_UINT16(&_bitmapOffsets[i]); + + return true; +} + +int OldDOSFont::getCharWidth(uint16 c) const { + if (c >= _numGlyphs) + return 0; + return _width; +} + +void OldDOSFont::drawChar(uint16 c, byte *dst, int pitch) const { + static const uint8 renderMaskTable6[] = { 0xFC, 0x00, 0x7E, 0x00, 0x3F, 0x00, 0x1F, 0x80, 0x0F, 0xC0, 0x07, 0xE0, 0x03, 0xF0, 0x01, 0xF8 }; + static const uint8 renderMaskTable8[] = { 0xFF, 0x00, 0x7F, 0x80, 0x3F, 0xC0, 0x1F, 0xE0, 0x0F, 0xF0, 0x07, 0xF8, 0x03, 0xFC, 0x01, 0xFE }; + + if (_width != 8 && _width != 6) + error("EOB font rendering not implemented for other font widths than 6 and 8."); + + if (_width == 6) { + switch (c) { + case 0x81: + case 0x9a: + c = 0x5d; + break; + case 0x84: + case 0x8e: + c = 0x5b; + break; + case 0x94: + case 0x99: + c = 0x40; + case 0xe1: + // TODO: recheck this: no conversion for 'ß' ? + break; + } + } else if (_width == 8){ + switch (c) { + case 0x81: + case 0x9a: + case 0x5d: + c = 0x1d; + break; + case 0x84: + case 0x5b: + c = 0x1e; + break; + case 0x94: + case 0x40: + c = 0x1f; + break; + case 0x8e: + c = 0x1b; + break; + case 0x99: + c = 0x1c; + break; + case 0xe1: + c = 0x19; + break; + } + } + + const uint8 *src = &_data[_bitmapOffsets[c]]; + + int w = (_width - 1) >> 3; + pitch -= _width; + + uint8 color1 = _colorMap[1]; + uint8 color2 = _colorMap[0]; + + int cH = _height; + while (cH--) { + int cW = w; + const uint8 *mtbl = _width == 8 ? renderMaskTable8 : renderMaskTable6; + + for (bool runWidthLoop = true; runWidthLoop; ) { + uint8 s = *src++; + uint8 m = *mtbl++; + + for (uint8 i = 0x80; i; i >>= 1) { + if (!(m & i)) { + runWidthLoop = false; + break; + } + + if (s & i) { + if (color1) + *dst = color1; + } else if (color2) { + *dst = color2; + } + dst++; + } + + if (cW) + cW--; + else + runWidthLoop = false; + } + + dst += pitch; + } +} + +void OldDOSFont::unload() { + delete[] _data; + _data = 0; + _width = _height = _numGlyphs = 0; + _bitmapOffsets = 0; +} + +} // End of namespace Kyra + +#endif // ENABLE_EOB -- cgit v1.2.3 From 80ece6caaef652e4d0f618ab793c11b00fcf9441 Mon Sep 17 00:00:00 2001 From: athrxx Date: Thu, 9 Jun 2011 23:59:11 +0200 Subject: KYRA: (EOB) - replace snprintf/sprintf --- engines/kyra/screen_eob.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'engines/kyra/screen_eob.cpp') diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp index eb5a52477b..f095b0409e 100644 --- a/engines/kyra/screen_eob.cpp +++ b/engines/kyra/screen_eob.cpp @@ -146,15 +146,13 @@ void Screen_Eob::loadEobBitmap(const char *file, int tempPage, int destPage) { } void Screen_Eob::loadEobCpsFileToPage(const char *file, const uint8 *ditheringData, int tempPage, int destPage, int copyToPage) { - char tmp[13]; - sprintf(tmp, "%s.CPS", file); - + Common::String tmp = Common::String::format("%s.CPS", file); Common::SeekableReadStream *s = _vm->resource()->createReadStream(tmp); bool loadAlternative = false; if (s) { // This additional check is necessary since some localized versions of EOB II seem to contain invalid (size zero) cps files if (s->size()) - loadBitmap(tmp, tempPage, destPage, 0); + loadBitmap(tmp.c_str(), tempPage, destPage, 0); else loadAlternative = true; @@ -164,7 +162,7 @@ void Screen_Eob::loadEobCpsFileToPage(const char *file, const uint8 *ditheringDa } if (loadAlternative) { - tmp[0] = 'X'; + tmp.setChar('X', 0); s = _vm->resource()->createReadStream(tmp); if (!s) error("Screen_Eob::loadEobCpsFileToPage(): CPS file loading failed."); -- cgit v1.2.3 From 9a6be57afd843b0cae09633b3745b104034100fa Mon Sep 17 00:00:00 2001 From: athrxx Date: Sun, 6 Nov 2011 17:02:52 +0100 Subject: KYRA: (EOB) - implement explodeObject() --- engines/kyra/screen_eob.cpp | 217 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 184 insertions(+), 33 deletions(-) (limited to 'engines/kyra/screen_eob.cpp') diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp index f095b0409e..b93ab3eafb 100644 --- a/engines/kyra/screen_eob.cpp +++ b/engines/kyra/screen_eob.cpp @@ -42,6 +42,8 @@ Screen_Eob::Screen_Eob(EobCoreEngine *vm, OSystem *system) : Screen(vm, system) _fadeData = 0; _fadeDataIndex = 0; _dsX1 = _dsX2 = _dsY1 = _dsY2 = 0; + _gfxX = _gfxY = 0; + _gfxCol = 0; _customDimTable = 0; _dsTempPage = 0; } @@ -57,6 +59,8 @@ bool Screen_Eob::init() { _customDimTable = new ScreenDim*[_screenDimTableCount]; memset(_customDimTable, 0, sizeof(ScreenDim *)* _screenDimTableCount); + int temp; + _gfxMaxY = _vm->staticres()->loadRawData(kEobBaseExpObjectY, temp); _fadeData = _vm->resource()->fileData("FADING.DAT", 0); if (!_fadeData) { @@ -605,25 +609,6 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, } } -void Screen_Eob::drawShapeSetPixel(uint8 * dst, uint8 c) { - if (_shapeFadeMode[0]) { - if (_shapeFadeMode[1]) { - c = *dst; - } else { - _shapeFadeInternal &= 7; - c = *(dst + _shapeFadeInternal++); - } - } - - if (_shapeFadeMode[1]) { - uint8 cnt = _shapeFadeMode[1]; - while (cnt--) - c = _fadeData[_fadeDataIndex + c]; - } - - *dst = c; -} - const uint8 *Screen_Eob::scaleShape(const uint8 *shapeData, int steps) { setShapeFadeMode(1, steps ? true : false); @@ -700,24 +685,133 @@ void Screen_Eob::applyShapeOverlay(uint8 *shp, int ovlIndex) { shp[i] = ovl[shp[i]]; } -void Screen_Eob::scaleShapeProcessLine(uint8 *&dst, const uint8 *&src) { - for (int i = 0; i < _dsDiv; i++) { - *dst++ = *src++; - *dst++ = READ_BE_UINT16(src) >> 4; - src += 2; +void Screen_Eob::setShapeFrame(int x1, int y1, int x2, int y2) { + _dsX1 = x1; + _dsY1 = y1; + _dsX2 = x2; + _dsY2 = y2; +} + +void Screen_Eob::setShapeFadeMode (uint8 i, bool b) { + if (!i || i == 1) + _shapeFadeMode[i] = b; +} + +void Screen_Eob::setGfxParameters(int x, int y, int col) { + _gfxX = x; + _gfxY = y; + _gfxCol = col; +} + +void Screen_Eob::drawExplosion(int scale, int radius, int numSteps, int stepSize, int aspectRatio, const uint8 *colorTable, int colorTableSize) { + int ymin = 0; + int ymax = _gfxMaxY[scale]; + int xmin = -100; + int xmax = 276; + + if (scale) + --scale; + + hideMouse(); + + const ScreenDim *dm = getScreenDim(5); + int rX1 = dm->sx << 3; + int rY1 = dm->sy; + int rX2 = rX1 + (dm->w << 3); + int rY2 = rY1 + dm->h - 1; + + int16 gx2 = _gfxX; + int16 gy2 = _gfxY; + + uint8 *ptr1 = _dsTempPage; + int16 *ptr2 = (int16*)_dsTempPage; + int16 *ptr3 = (int16*)&_dsTempPage[300]; + int16 *ptr4 = (int16*)&_dsTempPage[600]; + int16 *ptr5 = (int16*)&_dsTempPage[900]; + int16 *ptr6 = (int16*)&_dsTempPage[1200]; + int16 *ptr7 = (int16*)&_dsTempPage[1500]; + int16 *ptr8 = (int16*)&_dsTempPage[1800]; + + if (numSteps > 150) + numSteps = 150; + + for (int i = 0; i < numSteps; i++) { + ptr2[i] = ptr3[i] = 0; + ptr4[i] = _vm->_rnd.getRandomNumberRng(0, radius) - (radius >> 1); + ptr5[i] = _vm->_rnd.getRandomNumberRng(0, radius) - (radius >> 1) - (radius >> (8 - aspectRatio)); + ptr7[i] = _vm->_rnd.getRandomNumberRng(1024/stepSize, 2048/stepSize); + ptr8[i] = scale << 8; } - if (_dsRem == 1) { - *dst++ = *src++; - *dst++ = _dsScaleTmp; + for (int l = 2; l;) { + if (l != 2) { + for (int i = numSteps - 1; i >= 0; i--) { + uint32 end = _system->getMillis() + 1; + int16 px = ((ptr2[i] >> 6) >> scale) + gx2; + int16 py = ((ptr3[i] >> 6) >> scale) + gy2; + if (py > ymax) + py = ymax; + if (posWithinRect(px, py, rX1, rY1, rX2, rY2)) { + setPagePixel(0, px, py, ptr6[i]); + if (i % 5 == 0) { + updateScreen(); + uint32 cur = _system->getMillis(); + if (end > cur) + _system->delayMillis(end - cur); + } + } + } + } - } if (_dsRem == 2) { - *dst++ = (src[0] & 0xf0) | (src[1] >> 4); - src += 2; - *dst++ = _dsScaleTmp; - *dst++ = _dsScaleTmp; - *dst++ = _dsScaleTmp; + l = 0; + + for (int i = 0; i < numSteps; i++) { + uint32 end = _system->getMillis() + 1; + if (ptr4[i] <= 0) + ptr4[i]++; + else + ptr4[i]--; + ptr2[i] += ptr4[i]; + ptr5[i] += 5; + ptr3[i] += ptr5[i]; + ptr8[i] += ptr7[i]; + + int16 px = ((ptr2[i] >> 6) >> scale) + gx2; + int16 py = ((ptr3[i] >> 6) >> scale) + gy2; + if (py >= ymax || py < ymin) + ptr5[i] = -(ptr5[i] >> 1); + if (px >= xmax || px < xmin) + ptr4[i] = -(ptr4[i] >> 1); + + if (py > ymax) + py = ymax; + + int pxVal1 = 0; + if (posWithinRect(px, py, 0, 0, 319, 199)) { + pxVal1 = getPagePixel(2, px, py); + ptr6[i] = getPagePixel(0, px, py); + } + + assert((ptr8[i] >> 8) < colorTableSize); + int pxVal2 = colorTable[ptr8[i] >> 8]; + if (pxVal2) { + l = 1; + if (pxVal1 == _gfxCol && posWithinRect(px, py, rX1, rY1, rX2, rY2)) { + setPagePixel(0, px, py, pxVal2); + if (i % 5 == 0) { + updateScreen(); + uint32 cur = _system->getMillis(); + if (end > cur) + _system->delayMillis(end - cur); + } + } + } else { + ptr7[i] = 0; + } + } } + + showMouse(); } void Screen_Eob::fadeTextColor(Palette *pal, int color1, int rate) { @@ -778,6 +872,14 @@ bool Screen_Eob::delayedFadePalStep(Palette *fadePal, Palette *destPal, int rate return res; } +int Screen_Eob::getRectSize(int w, int h) { + return w * h; +} + +void Screen_Eob::setFadeTableIndex(int index) { + _fadeDataIndex = (CLIP(index, 0, 7) << 8); +} + void Screen_Eob::createFadeTable(uint8 *palData, uint8 *dst, uint8 rootColor, uint8 weight) { if (!palData) return; @@ -821,6 +923,55 @@ void Screen_Eob::createFadeTable(uint8 *palData, uint8 *dst, uint8 rootColor, ui } } +uint8 *Screen_Eob::getFadeTable(int index) { + return (index >= 0 && index < 5) ? &_fadeData[index << 8] : 0; +} + +void Screen_Eob::drawShapeSetPixel(uint8 * dst, uint8 c) { + if (_shapeFadeMode[0]) { + if (_shapeFadeMode[1]) { + c = *dst; + } else { + _shapeFadeInternal &= 7; + c = *(dst + _shapeFadeInternal++); + } + } + + if (_shapeFadeMode[1]) { + uint8 cnt = _shapeFadeMode[1]; + while (cnt--) + c = _fadeData[_fadeDataIndex + c]; + } + + *dst = c; +} + +void Screen_Eob::scaleShapeProcessLine(uint8 *&dst, const uint8 *&src) { + for (int i = 0; i < _dsDiv; i++) { + *dst++ = *src++; + *dst++ = READ_BE_UINT16(src) >> 4; + src += 2; + } + + if (_dsRem == 1) { + *dst++ = *src++; + *dst++ = _dsScaleTmp; + + } if (_dsRem == 2) { + *dst++ = (src[0] & 0xf0) | (src[1] >> 4); + src += 2; + *dst++ = _dsScaleTmp; + *dst++ = _dsScaleTmp; + *dst++ = _dsScaleTmp; + } +} + +bool Screen_Eob::posWithinRect(int posX, int posY, int x1, int y1, int x2, int y2) { + if (posX < x1 || posX > x2 || posY < y1 || posY > y2) + return false; + return true; +} + OldDOSFont::OldDOSFont() { _data = 0; _width = _height = _numGlyphs = 0; -- cgit v1.2.3 From c8665d06bc59b695cb6c444b1e3c24104b69dec4 Mon Sep 17 00:00:00 2001 From: athrxx Date: Thu, 16 Jun 2011 18:51:47 +0200 Subject: KYRA: (EOB) - fix some warnings and add some menu code --- engines/kyra/screen_eob.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'engines/kyra/screen_eob.cpp') diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp index b93ab3eafb..f6b0eafcf4 100644 --- a/engines/kyra/screen_eob.cpp +++ b/engines/kyra/screen_eob.cpp @@ -508,7 +508,7 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, break; if (!*(src-1) || i < marginLeft) - marginLeft = ++marginLeft - *src++; + marginLeft = marginLeft + 1 - *src++; else marginLeft = 0; @@ -723,7 +723,6 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numSteps, int stepSize int16 gx2 = _gfxX; int16 gy2 = _gfxY; - uint8 *ptr1 = _dsTempPage; int16 *ptr2 = (int16*)_dsTempPage; int16 *ptr3 = (int16*)&_dsTempPage[300]; int16 *ptr4 = (int16*)&_dsTempPage[600]; -- cgit v1.2.3 From 045d08986d3accc3fc7d55d76eb550db01ad7fc7 Mon Sep 17 00:00:00 2001 From: athrxx Date: Wed, 22 Jun 2011 01:08:28 +0200 Subject: KYRA: (EOB) - start implementing camp menu --- engines/kyra/screen_eob.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'engines/kyra/screen_eob.cpp') diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp index f6b0eafcf4..d3c2187177 100644 --- a/engines/kyra/screen_eob.cpp +++ b/engines/kyra/screen_eob.cpp @@ -91,8 +91,9 @@ const ScreenDim *Screen_Eob::getScreenDim(int dim) { } void Screen_Eob::modifyScreenDim(int dim, int x, int y, int w, int h) { - delete _customDimTable[dim]; - _customDimTable[dim] = new ScreenDim; + if (!_customDimTable[dim]) + _customDimTable[dim] = new ScreenDim; + memcpy(_customDimTable[dim], &_screenDimTable[dim], sizeof(ScreenDim)); _customDimTable[dim]->sx = x; _customDimTable[dim]->sy = y; -- cgit v1.2.3 From bac0caeb0ff712fe9002985c44c1ea651b86e018 Mon Sep 17 00:00:00 2001 From: athrxx Date: Sat, 6 Aug 2011 00:40:53 +0200 Subject: KYRA: (EOB) - lots of fixes towards EOB1 playability also implement some new code (EOB1 portals, burning hands spell, etc.) --- engines/kyra/screen_eob.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'engines/kyra/screen_eob.cpp') diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp index d3c2187177..ccbc2a166b 100644 --- a/engines/kyra/screen_eob.cpp +++ b/engines/kyra/screen_eob.cpp @@ -145,12 +145,15 @@ void Screen_Eob::printShadedText(const char *string, int x, int y, int col1, int printText(string, x, y, col1, 0); } -void Screen_Eob::loadEobBitmap(const char *file, int tempPage, int destPage) { - loadEobCpsFileToPage(file, 0, tempPage, destPage, -1); +void Screen_Eob::loadShapeSetBitmap(const char *file, int tempPage, int destPage) { + loadEobBitmap(file, 0, tempPage, destPage, -1); _curPage = 2; } -void Screen_Eob::loadEobCpsFileToPage(const char *file, const uint8 *ditheringData, int tempPage, int destPage, int copyToPage) { +void Screen_Eob::loadEobBitmap(const char *file, const uint8 *ditheringData, int tempPage, int destPage, int copyToPage) { + //Common::String tmp = file; + //if (_vm->game() == GI_EOB1 && tmp.equalsIgnoreCase("spider")) + // tmp += "1"; Common::String tmp = Common::String::format("%s.CPS", file); Common::SeekableReadStream *s = _vm->resource()->createReadStream(tmp); bool loadAlternative = false; @@ -170,7 +173,7 @@ void Screen_Eob::loadEobCpsFileToPage(const char *file, const uint8 *ditheringDa tmp.setChar('X', 0); s = _vm->resource()->createReadStream(tmp); if (!s) - error("Screen_Eob::loadEobCpsFileToPage(): CPS file loading failed."); + error("Screen_Eob::loadEobBitmap(): CPS file loading failed."); s->seek(768); loadFileDataToPage(s, destPage, 64000); delete s; -- cgit v1.2.3 From 0d54aff6324b1f6c739df89ab072328cc5402873 Mon Sep 17 00:00:00 2001 From: athrxx Date: Sun, 14 Aug 2011 18:29:45 +0200 Subject: KYRA: (EOB) - add EOB 1 intro (also add and fix several other things, like cone of cold vortex, drawShape issues, etc.) --- engines/kyra/screen_eob.cpp | 259 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 211 insertions(+), 48 deletions(-) (limited to 'engines/kyra/screen_eob.cpp') diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp index ccbc2a166b..c9ee9119db 100644 --- a/engines/kyra/screen_eob.cpp +++ b/engines/kyra/screen_eob.cpp @@ -189,14 +189,14 @@ void Screen_Eob::loadEobBitmap(const char *file, const uint8 *ditheringData, int } } -uint8 *Screen_Eob::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool flag) { +uint8 *Screen_Eob::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool no4bitEncoding) { uint8 *shp = 0; uint16 shapesize = 0; uint8 *srcPage = getPagePtr(_curPage) + y * 320 + (x << 3); uint8 *src = srcPage; - if (flag) { + if (no4bitEncoding) { uint16 h1 = h; while (h1--) { uint8 *lineEnd = src + (w << 3); @@ -237,19 +237,20 @@ uint8 *Screen_Eob::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool flag uint8 *lineEnd = src + (w << 3); do { uint8 val = *src++; - if (!val) { - *dst++ = val; + if (!val) { + *dst++ = 0; uint8 *startZeroPos = src; + while (src != lineEnd && *src == 0) src++; uint16 numZero = src - startZeroPos + 1; if (numZero >> 8) { - numZero -= 0xff; - *dst++ = 0xff; + *dst++ = 255; *dst++ = 0; + numZero -= 255; } - val = (numZero & 0xff); + val = numZero & 0xff; } *dst++ = val; } while (src != lineEnd); @@ -384,7 +385,7 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, if (dX < 0) { width += dX; d = -dX; - if ((flags & 1)) + if (flags & 1) src -= (d >> 1); else src += (d >> 1); @@ -415,7 +416,7 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, dY = 320 - width; width >>= 1; w2 >>= 1; - if ((flags & 1)) + if (flags & 1) src += (w2 - 1); int16 w1shr = width; @@ -431,7 +432,7 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, w1shr++; int lineSrcStep = (w2 - w1shr); - if ((flags & 1)) + if (flags & 1) lineSrcStep = w3 - lineSrcStep; while (dH--) { @@ -503,20 +504,12 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, return; d = -d; - for (int ii = 0; ii < d; ii++) { + for (int i = 0; i < d; i++) { marginLeft = width; - int i = 0; - do { - for (i = 0; i < marginLeft; i++) - if (!*src++) - break; - - if (!*(src-1) || i < marginLeft) + for (int ii = 0; ii < marginLeft; ii++) { + if (!*src++) marginLeft = marginLeft + 1 - *src++; - else - marginLeft = 0; - - } while (marginLeft); + } } dY = _dsY1; } @@ -552,25 +545,40 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, marginRight = w2 - marginLeft - width; } - dst += (y * 320 + dX); + dst += (dY * 320 + dX); uint8 * dstL = dst; if (pageNum == 0 || pageNum == 1) addDirtyRect(rX, rY, rW, rH); while (dH--) { - int16 xpos = (int16) marginLeft; + int16 xpos = (int16) marginLeft; + + if (flags & 1) { + for (int i = 0; i < w2; i++) { + if (*src++ == 0) { + i += (*src - 1); + src += (*src - 1); + } + } + src--; + } + const uint8 *src2 = src; if (xpos) { do { - while (*src && xpos) { - src++; + uint8 val = (flags & 1) ? *(src - 1) : *src; + while (val && xpos) { + src += pixelStep; xpos--; + val = (flags & 1) ? *(src - 1) : *src; } - if (!*src) { - uint8 bt = *++src; - src++; + val = (flags & 1) ? *(src - 1) : *src; + if (!val) { + src += pixelStep; + uint8 bt = (flags & 1) ? src[1] : src[0]; + src += pixelStep; xpos = xpos - bt; } } while (xpos > 0); @@ -580,28 +588,36 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, xpos += width; while (xpos > 0) { - uint8 c = *src++; + uint8 c = *src; + uint8 m = (flags & 1) ? *(src - 1) : c; + src += pixelStep; - if (c) { + if (m) { drawShapeSetPixel(dst++, c); xpos--; } else { - dst += *src; - xpos -= *src++; + uint8 len = (flags & 1) ? src[1] : src[0]; + dst += len; + xpos -= len; + src += pixelStep; } } xpos += marginRight; if (xpos) { do { - while (*src && xpos) { - src++; + uint8 val = (flags & 1) ? *(src - 1) : *src; + while (val && xpos) { + src += pixelStep; xpos--; + val = (flags & 1) ? *(src - 1) : *src; } - if (!*src) { - uint8 bt = *++src; - src++; + val = (flags & 1) ? *(src - 1) : *src; + if (!val) { + src += pixelStep; + uint8 bt = (flags & 1) ? src[1] : src[0]; + src += pixelStep; xpos = xpos - bt; } } while (xpos > 0); @@ -609,6 +625,8 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, dstL += 320; dst = dstL; + if (flags & 1) + src = src2 + 1; } } } @@ -707,7 +725,7 @@ void Screen_Eob::setGfxParameters(int x, int y, int col) { _gfxCol = col; } -void Screen_Eob::drawExplosion(int scale, int radius, int numSteps, int stepSize, int aspectRatio, const uint8 *colorTable, int colorTableSize) { +void Screen_Eob::drawExplosion(int scale, int radius, int numElements, int stepSize, int aspectRatio, const uint8 *colorTable, int colorTableSize) { int ymin = 0; int ymax = _gfxMaxY[scale]; int xmin = -100; @@ -735,20 +753,20 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numSteps, int stepSize int16 *ptr7 = (int16*)&_dsTempPage[1500]; int16 *ptr8 = (int16*)&_dsTempPage[1800]; - if (numSteps > 150) - numSteps = 150; + if (numElements > 150) + numElements = 150; - for (int i = 0; i < numSteps; i++) { + for (int i = 0; i < numElements; i++) { ptr2[i] = ptr3[i] = 0; ptr4[i] = _vm->_rnd.getRandomNumberRng(0, radius) - (radius >> 1); ptr5[i] = _vm->_rnd.getRandomNumberRng(0, radius) - (radius >> 1) - (radius >> (8 - aspectRatio)); - ptr7[i] = _vm->_rnd.getRandomNumberRng(1024/stepSize, 2048/stepSize); + ptr7[i] = _vm->_rnd.getRandomNumberRng(1024 / stepSize, 2048 / stepSize); ptr8[i] = scale << 8; } for (int l = 2; l;) { if (l != 2) { - for (int i = numSteps - 1; i >= 0; i--) { + for (int i = numElements - 1; i >= 0; i--) { uint32 end = _system->getMillis() + 1; int16 px = ((ptr2[i] >> 6) >> scale) + gx2; int16 py = ((ptr3[i] >> 6) >> scale) + gy2; @@ -760,7 +778,7 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numSteps, int stepSize updateScreen(); uint32 cur = _system->getMillis(); if (end > cur) - _system->delayMillis(end - cur); + _system->delayMillis(end - cur); } } } @@ -768,7 +786,7 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numSteps, int stepSize l = 0; - for (int i = 0; i < numSteps; i++) { + for (int i = 0; i < numElements; i++) { uint32 end = _system->getMillis() + 1; if (ptr4[i] <= 0) ptr4[i]++; @@ -805,7 +823,7 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numSteps, int stepSize updateScreen(); uint32 cur = _system->getMillis(); if (end > cur) - _system->delayMillis(end - cur); + _system->delayMillis(end - cur); } } } else { @@ -817,12 +835,157 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numSteps, int stepSize showMouse(); } +void Screen_Eob::drawVortex(int numElements, int radius, int stepSize, int, int disorder, const uint8 *colorTable, int colorTableSize) { + int16 *xCoords = (int16*)_dsTempPage; + int16 *yCoords = (int16*)&_dsTempPage[300]; + int16 *xMod = (int16*)&_dsTempPage[600]; + int16 *yMod = (int16*)&_dsTempPage[900]; + int16 *pixBackup = (int16*)&_dsTempPage[1200]; + int16 *colTableStep = (int16*)&_dsTempPage[1500]; + int16 *colTableIndex = (int16*)&_dsTempPage[1800]; + int16 *pixDelay = (int16*)&_dsTempPage[2100]; + + hideMouse(); + int cp = _curPage; + + if (numElements > 150) + numElements = 150; + + int cx = 88; + int cy = 48; + radius <<= 6; + + for (int i = 0; i < numElements; i++) { + int16 v38 = _vm->_rnd.getRandomNumberRng(radius >> 2, radius); + int16 stepSum = 0; + int16 sqsum = 0; + while (sqsum < v38) { + stepSum += stepSize; + sqsum += stepSum; + } + + switch (_vm->_rnd.getRandomNumber(255) & 3) { + case 0: + xCoords[i] = 32; + yCoords[i] = sqsum; + xMod[i] = stepSum; + yMod[i] = 0; + break; + + case 1: + xCoords[i] = sqsum; + yCoords[i] = 32; + xMod[i] = 0; + yMod[i] = stepSum; + break; + + case 2: + xCoords[i] = 32; + yCoords[i] = -sqsum; + xMod[i] = stepSum; + yMod[i] = 0; + break; + + default: + xCoords[i] = -sqsum; + yCoords[i] = 32; + xMod[i] = 0; + yMod[i] = stepSum; + break; + } + + if (_vm->_rnd.getRandomBit()) { + xMod[i] *= -1; + yMod[i] *= -1; + } + + colTableStep[i] = _vm->_rnd.getRandomNumberRng(1024 / disorder, 2048 / disorder); + colTableIndex[i] = 0; + pixDelay[i] = _vm->_rnd.getRandomNumberRng(0, disorder >> 2); + } + + int d = 0; + for (int i = 2; i; ) { + if (i != 2) { + uint32 nextDelay = _system->getMillis() + 1; + for (int ii = numElements - 1; ii >= 0; ii--) { + int16 px = CLIP((xCoords[ii] >> 6) + cx, 0, SCREEN_W - 1); + int16 py = CLIP((yCoords[ii] >> 6) + cy, 0, SCREEN_H - 1); + setPagePixel(0, px, py, pixBackup[ii]); + + if (ii % 15 == 0) { + updateScreen(); + uint32 cur = _system->getMillis(); + if (nextDelay > cur) + _system->delayMillis(nextDelay - cur); + nextDelay += 1; + } + } + } + + i = 0; + int r = (stepSize >> 1) + (stepSize >> 2) + (stepSize >> 3); + uint32 nextDelay2 = _system->getMillis() + 1; + + for (int ii = 0; ii < numElements; ii++) { + if (pixDelay[ii] == 0) { + if (xCoords[ii] > 0) { + xMod[ii] -= ((xMod[ii] > 0) ? stepSize : r); + } else { + xMod[ii] += ((xMod[ii] < 0) ? stepSize : r); + } + + if (yCoords[ii] > 0) { + yMod[ii] -= ((yMod[ii] > 0) ? stepSize : r); + } else { + yMod[ii] += ((yMod[ii] < 0) ? stepSize : r); + } + + xCoords[ii] += xMod[ii]; + yCoords[ii] += yMod[ii]; + colTableIndex[ii] += colTableStep[ii]; + + } else { + pixDelay[ii]--; + } + + int16 px = CLIP((xCoords[ii] >> 6) + cx, 0, SCREEN_W - 1); + int16 py = CLIP((yCoords[ii] >> 6) + cy, 0, SCREEN_H - 1); + + uint8 tc1 = ((disorder >> 2) <= d) ? getPagePixel(2, px, py) : 0; + pixBackup[ii] = getPagePixel(0, px, py); + uint8 tblIndex = CLIP(colTableIndex[ii] >> 8, 0, colorTableSize - 1); + uint8 tc2 = colorTable[tblIndex]; + + if (tc2) { + i = 1; + if (tc1 == _gfxCol && !pixDelay[ii]) { + setPagePixel(0, px, py, tc2); + if (ii % 15 == 0) { + updateScreen(); + uint32 cur = _system->getMillis(); + if (nextDelay2 > cur) + _system->delayMillis(nextDelay2 - cur); + nextDelay2 += 1; + } + } + } else { + colTableStep[ii] = 0; + } + } + d++; + } + + _curPage = cp; + showMouse(); +} + void Screen_Eob::fadeTextColor(Palette *pal, int color1, int rate) { uint8 *col = pal->getData(); for (bool loop = true; loop; ) { loop = true; - uint32 end = _system->getMillis() + 16; + uint32 end = _system->getMillis() + 1; loop = false; for (int ii = 0; ii < 3; ii++) { -- cgit v1.2.3 From f7032c126dd097e8083e0fc740c7c856e0f2dd58 Mon Sep 17 00:00:00 2001 From: athrxx Date: Wed, 17 Aug 2011 18:46:29 +0200 Subject: KYRA: (EOB) - fix some bugs - fix monster movement - fix character level gain - add some static res for party transfer --- engines/kyra/screen_eob.cpp | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'engines/kyra/screen_eob.cpp') diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp index c9ee9119db..d29af69f0a 100644 --- a/engines/kyra/screen_eob.cpp +++ b/engines/kyra/screen_eob.cpp @@ -151,9 +151,6 @@ void Screen_Eob::loadShapeSetBitmap(const char *file, int tempPage, int destPage } void Screen_Eob::loadEobBitmap(const char *file, const uint8 *ditheringData, int tempPage, int destPage, int copyToPage) { - //Common::String tmp = file; - //if (_vm->game() == GI_EOB1 && tmp.equalsIgnoreCase("spider")) - // tmp += "1"; Common::String tmp = Common::String::format("%s.CPS", file); Common::SeekableReadStream *s = _vm->resource()->createReadStream(tmp); bool loadAlternative = false; @@ -170,15 +167,20 @@ void Screen_Eob::loadEobBitmap(const char *file, const uint8 *ditheringData, int } if (loadAlternative) { - tmp.setChar('X', 0); - s = _vm->resource()->createReadStream(tmp); - if (!s) - error("Screen_Eob::loadEobBitmap(): CPS file loading failed."); - s->seek(768); - loadFileDataToPage(s, destPage, 64000); - delete s; + if (_vm->game() == GI_EOB1) { + tmp.insertChar('1', tmp.size() - 4); + loadBitmap(tmp.c_str(), tempPage, destPage, 0); + } else { + tmp.setChar('X', 0); + s = _vm->resource()->createReadStream(tmp); + if (!s) + error("Screen_Eob::loadEobBitmap(): CPS file loading failed."); + s->seek(768); + loadFileDataToPage(s, destPage, 64000); + delete s; + } } - + if (copyToPage == -1) { return; } else if (copyToPage == 0) { -- cgit v1.2.3 From c35de374dfe545ffc5044a00a247c5814e3b250e Mon Sep 17 00:00:00 2001 From: athrxx Date: Sat, 20 Aug 2011 13:24:36 +0200 Subject: KYRA: (EOB) - lots of bug fixes, mostly for EOB II --- engines/kyra/screen_eob.cpp | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) (limited to 'engines/kyra/screen_eob.cpp') diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp index d29af69f0a..9c67750ba8 100644 --- a/engines/kyra/screen_eob.cpp +++ b/engines/kyra/screen_eob.cpp @@ -774,15 +774,8 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numElements, int stepS int16 py = ((ptr3[i] >> 6) >> scale) + gy2; if (py > ymax) py = ymax; - if (posWithinRect(px, py, rX1, rY1, rX2, rY2)) { + if (posWithinRect(px, py, rX1, rY1, rX2, rY2)) setPagePixel(0, px, py, ptr6[i]); - if (i % 5 == 0) { - updateScreen(); - uint32 cur = _system->getMillis(); - if (end > cur) - _system->delayMillis(end - cur); - } - } } } @@ -914,14 +907,6 @@ void Screen_Eob::drawVortex(int numElements, int radius, int stepSize, int, int int16 px = CLIP((xCoords[ii] >> 6) + cx, 0, SCREEN_W - 1); int16 py = CLIP((yCoords[ii] >> 6) + cy, 0, SCREEN_H - 1); setPagePixel(0, px, py, pixBackup[ii]); - - if (ii % 15 == 0) { - updateScreen(); - uint32 cur = _system->getMillis(); - if (nextDelay > cur) - _system->delayMillis(nextDelay - cur); - nextDelay += 1; - } } } -- cgit v1.2.3 From 2448d885e4e331a22e1e468277142155a5ddda87 Mon Sep 17 00:00:00 2001 From: athrxx Date: Sun, 21 Aug 2011 20:26:07 +0200 Subject: KYRA: (EOB) - complete EOBII playability - fixed temp data generation, block data loading, some spell issues, etc. - both EOB I and II should now be completable - one big issue remaining (AdLib driver gets swamped with monster sounds which causes heavy lags in some levels) --- engines/kyra/screen_eob.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'engines/kyra/screen_eob.cpp') diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp index 9c67750ba8..4161c757d8 100644 --- a/engines/kyra/screen_eob.cpp +++ b/engines/kyra/screen_eob.cpp @@ -769,7 +769,6 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numElements, int stepS for (int l = 2; l;) { if (l != 2) { for (int i = numElements - 1; i >= 0; i--) { - uint32 end = _system->getMillis() + 1; int16 px = ((ptr2[i] >> 6) >> scale) + gx2; int16 py = ((ptr3[i] >> 6) >> scale) + gy2; if (py > ymax) @@ -902,7 +901,6 @@ void Screen_Eob::drawVortex(int numElements, int radius, int stepSize, int, int int d = 0; for (int i = 2; i; ) { if (i != 2) { - uint32 nextDelay = _system->getMillis() + 1; for (int ii = numElements - 1; ii >= 0; ii--) { int16 px = CLIP((xCoords[ii] >> 6) + cx, 0, SCREEN_W - 1); int16 py = CLIP((yCoords[ii] >> 6) + cy, 0, SCREEN_H - 1); @@ -912,7 +910,7 @@ void Screen_Eob::drawVortex(int numElements, int radius, int stepSize, int, int i = 0; int r = (stepSize >> 1) + (stepSize >> 2) + (stepSize >> 3); - uint32 nextDelay2 = _system->getMillis() + 1; + uint32 nextDelay = _system->getMillis() + 1; for (int ii = 0; ii < numElements; ii++) { if (pixDelay[ii] == 0) { @@ -951,9 +949,9 @@ void Screen_Eob::drawVortex(int numElements, int radius, int stepSize, int, int if (ii % 15 == 0) { updateScreen(); uint32 cur = _system->getMillis(); - if (nextDelay2 > cur) - _system->delayMillis(nextDelay2 - cur); - nextDelay2 += 1; + if (nextDelay > cur) + _system->delayMillis(nextDelay - cur); + nextDelay += 1; } } } else { -- cgit v1.2.3 From 68ed8b95989d784fe42f4e6e400224ffb63ba80b Mon Sep 17 00:00:00 2001 From: athrxx Date: Tue, 13 Sep 2011 21:46:23 +0200 Subject: KYRA: (EOB) - fix some valgrind warnings --- engines/kyra/screen_eob.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'engines/kyra/screen_eob.cpp') diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp index 4161c757d8..8562e25480 100644 --- a/engines/kyra/screen_eob.cpp +++ b/engines/kyra/screen_eob.cpp @@ -46,6 +46,7 @@ Screen_Eob::Screen_Eob(EobCoreEngine *vm, OSystem *system) : Screen(vm, system) _gfxCol = 0; _customDimTable = 0; _dsTempPage = 0; + _curDimIndex = 0; } Screen_Eob::~Screen_Eob() { @@ -266,7 +267,7 @@ uint8 *Screen_Eob::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool no4b uint8 *colorMap = new uint8[0x100]; memset (colorMap, 0xff, 0x100); - shapesize = h * (w << 2) + 0x14; + shapesize = h * (w << 2) + 20; shp = new uint8[shapesize]; memset (shp, 0, shapesize); uint8 *dst = shp; @@ -673,14 +674,13 @@ const uint8 *Screen_Eob::scaleShapeStep(const uint8 *shp) { i = -i; _dsScaleTmp = (i << 4) | (i & 0x0f); - memcpy(d, shp, 16); - d += 16; - shp += 16; + for (int ii = 0; ii < 16; ii++) + *d++ = *shp++; _dsDiv = w2 / 3; _dsRem = w2 % 3; - do { + while (--h) { scaleShapeProcessLine(d, shp); if (!--h) break; @@ -688,7 +688,7 @@ const uint8 *Screen_Eob::scaleShapeStep(const uint8 *shp) { if (!--h) break; shp += w2; - } while (--h); + } return (const uint8 *) _dsTempPage; } @@ -1100,15 +1100,14 @@ void Screen_Eob::drawShapeSetPixel(uint8 * dst, uint8 c) { void Screen_Eob::scaleShapeProcessLine(uint8 *&dst, const uint8 *&src) { for (int i = 0; i < _dsDiv; i++) { *dst++ = *src++; - *dst++ = READ_BE_UINT16(src) >> 4; + *dst++ = (READ_BE_UINT16(src) >> 4) & 0xff; src += 2; } if (_dsRem == 1) { *dst++ = *src++; *dst++ = _dsScaleTmp; - - } if (_dsRem == 2) { + } else if (_dsRem == 2) { *dst++ = (src[0] & 0xf0) | (src[1] >> 4); src += 2; *dst++ = _dsScaleTmp; -- cgit v1.2.3 From 1cbd56693086afa8ce93092c3638e1052e31a5d9 Mon Sep 17 00:00:00 2001 From: athrxx Date: Thu, 29 Sep 2011 22:51:36 +0200 Subject: KYRA: (EOB) - fix invalid string access (also fix several cpp-check warnings) --- engines/kyra/screen_eob.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'engines/kyra/screen_eob.cpp') diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp index 8562e25480..0b877b7247 100644 --- a/engines/kyra/screen_eob.cpp +++ b/engines/kyra/screen_eob.cpp @@ -47,10 +47,18 @@ Screen_Eob::Screen_Eob(EobCoreEngine *vm, OSystem *system) : Screen(vm, system) _customDimTable = 0; _dsTempPage = 0; _curDimIndex = 0; + _dsDiv = 0; + _dsRem = 0; + _dsScaleTmp = 0; + _gfxMaxY = 0; } Screen_Eob::~Screen_Eob() { delete[] _fadeData; + if (_customDimTable) { + for (int i = 0; i < _screenDimTableCount; i++) + delete _customDimTable[i]; + } delete[] _customDimTable; delete[] _dsTempPage; } @@ -58,7 +66,7 @@ Screen_Eob::~Screen_Eob() { bool Screen_Eob::init() { if (Screen::init()) { _customDimTable = new ScreenDim*[_screenDimTableCount]; - memset(_customDimTable, 0, sizeof(ScreenDim *)* _screenDimTableCount); + memset(_customDimTable, 0, sizeof(ScreenDim*) * _screenDimTableCount); int temp; _gfxMaxY = _vm->staticres()->loadRawData(kEobBaseExpObjectY, temp); -- cgit v1.2.3 From 8b618e46df21d90a1a5ad62633a2b9d3c1da0317 Mon Sep 17 00:00:00 2001 From: athrxx Date: Sun, 11 Dec 2011 12:29:09 +0100 Subject: KYRA: (EOB/LOL) - cleanup common code (rename some stuff and move EOB/LOL common code to separate files) --- engines/kyra/screen_eob.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'engines/kyra/screen_eob.cpp') diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp index 0b877b7247..ca44a8a771 100644 --- a/engines/kyra/screen_eob.cpp +++ b/engines/kyra/screen_eob.cpp @@ -189,7 +189,7 @@ void Screen_Eob::loadEobBitmap(const char *file, const uint8 *ditheringData, int delete s; } } - + if (copyToPage == -1) { return; } else if (copyToPage == 0) { @@ -248,7 +248,7 @@ uint8 *Screen_Eob::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool no4b uint8 *lineEnd = src + (w << 3); do { uint8 val = *src++; - if (!val) { + if (!val) { *dst++ = 0; uint8 *startZeroPos = src; @@ -563,9 +563,9 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, addDirtyRect(rX, rY, rW, rH); while (dH--) { - int16 xpos = (int16) marginLeft; + int16 xpos = (int16) marginLeft; - if (flags & 1) { + if (flags & 1) { for (int i = 0; i < w2; i++) { if (*src++ == 0) { i += (*src - 1); @@ -636,7 +636,7 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, dstL += 320; dst = dstL; - if (flags & 1) + if (flags & 1) src = src2 + 1; } } @@ -751,7 +751,7 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numElements, int stepS int rY1 = dm->sy; int rX2 = rX1 + (dm->w << 3); int rY2 = rY1 + dm->h - 1; - + int16 gx2 = _gfxX; int16 gy2 = _gfxY; @@ -783,7 +783,7 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numElements, int stepS py = ymax; if (posWithinRect(px, py, rX1, rY1, rX2, rY2)) setPagePixel(0, px, py, ptr6[i]); - } + } } l = 0; @@ -798,7 +798,7 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numElements, int stepS ptr5[i] += 5; ptr3[i] += ptr5[i]; ptr8[i] += ptr7[i]; - + int16 px = ((ptr2[i] >> 6) >> scale) + gx2; int16 py = ((ptr3[i] >> 6) >> scale) + gy2; if (py >= ymax || py < ymin) @@ -808,7 +808,7 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numElements, int stepS if (py > ymax) py = ymax; - + int pxVal1 = 0; if (posWithinRect(px, py, 0, 0, 319, 199)) { pxVal1 = getPagePixel(2, px, py); @@ -833,7 +833,7 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numElements, int stepS } } } - + showMouse(); } -- cgit v1.2.3 From 4e4f4164be57d66610eac570e048c9ade07f42ea Mon Sep 17 00:00:00 2001 From: athrxx Date: Mon, 12 Dec 2011 21:44:13 +0100 Subject: KYRA: (EOB) - fix eob2 sequence text fading --- engines/kyra/screen_eob.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/kyra/screen_eob.cpp') diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp index ca44a8a771..36af074ee0 100644 --- a/engines/kyra/screen_eob.cpp +++ b/engines/kyra/screen_eob.cpp @@ -978,7 +978,7 @@ void Screen_Eob::fadeTextColor(Palette *pal, int color1, int rate) { for (bool loop = true; loop; ) { loop = true; - uint32 end = _system->getMillis() + 1; + uint32 end = _system->getMillis() + _vm->tickLength(); loop = false; for (int ii = 0; ii < 3; ii++) { -- cgit v1.2.3 From 0aa32385230dbe1ab62bb2d02d04ca5cc46d928c Mon Sep 17 00:00:00 2001 From: athrxx Date: Mon, 12 Dec 2011 16:23:01 +0100 Subject: KYRA: (EOB/LOL) - rename some vars (all cases of Eob to EoB, all cases of Lol to LoL, all cases of LolEobCommon to RpgCommon) --- engines/kyra/screen_eob.cpp | 72 ++++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 36 deletions(-) (limited to 'engines/kyra/screen_eob.cpp') diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp index 36af074ee0..869f4375ae 100644 --- a/engines/kyra/screen_eob.cpp +++ b/engines/kyra/screen_eob.cpp @@ -36,7 +36,7 @@ namespace Kyra { -Screen_Eob::Screen_Eob(EobCoreEngine *vm, OSystem *system) : Screen(vm, system) { +Screen_EoB::Screen_EoB(EoBCoreEngine *vm, OSystem *system) : Screen(vm, system) { _shapeFadeMode[0] = _shapeFadeMode[1] = 0; _shapeFadeInternal = 0; _fadeData = 0; @@ -53,7 +53,7 @@ Screen_Eob::Screen_Eob(EobCoreEngine *vm, OSystem *system) : Screen(vm, system) _gfxMaxY = 0; } -Screen_Eob::~Screen_Eob() { +Screen_EoB::~Screen_EoB() { delete[] _fadeData; if (_customDimTable) { for (int i = 0; i < _screenDimTableCount; i++) @@ -63,13 +63,13 @@ Screen_Eob::~Screen_Eob() { delete[] _dsTempPage; } -bool Screen_Eob::init() { +bool Screen_EoB::init() { if (Screen::init()) { _customDimTable = new ScreenDim*[_screenDimTableCount]; memset(_customDimTable, 0, sizeof(ScreenDim*) * _screenDimTableCount); int temp; - _gfxMaxY = _vm->staticres()->loadRawData(kEobBaseExpObjectY, temp); + _gfxMaxY = _vm->staticres()->loadRawData(kEoBBaseExpObjectY, temp); _fadeData = _vm->resource()->fileData("FADING.DAT", 0); if (!_fadeData) { @@ -88,18 +88,18 @@ bool Screen_Eob::init() { return false; } -void Screen_Eob::setScreenDim(int dim) { +void Screen_EoB::setScreenDim(int dim) { assert(dim < _screenDimTableCount); _curDim = _customDimTable[dim] ? (const ScreenDim *)_customDimTable[dim] : &_screenDimTable[dim]; _curDimIndex = dim; } -const ScreenDim *Screen_Eob::getScreenDim(int dim) { +const ScreenDim *Screen_EoB::getScreenDim(int dim) { assert(dim < _screenDimTableCount); return _customDimTable[dim] ? (const ScreenDim *)_customDimTable[dim] : &_screenDimTable[dim]; } -void Screen_Eob::modifyScreenDim(int dim, int x, int y, int w, int h) { +void Screen_EoB::modifyScreenDim(int dim, int x, int y, int w, int h) { if (!_customDimTable[dim]) _customDimTable[dim] = new ScreenDim; @@ -112,16 +112,16 @@ void Screen_Eob::modifyScreenDim(int dim, int x, int y, int w, int h) { setScreenDim(dim); } -void Screen_Eob::setClearScreenDim(int dim) { +void Screen_EoB::setClearScreenDim(int dim) { setScreenDim(dim); clearCurDim(); } -void Screen_Eob::clearCurDim() { +void Screen_EoB::clearCurDim() { fillRect(_curDim->sx << 3, _curDim->sy, ((_curDim->sx + _curDim->w) << 3) - 1, (_curDim->sy + _curDim->h) - 1, _curDim->unkA); } -void Screen_Eob::setMouseCursor(int x, int y, const byte *shape) { +void Screen_EoB::setMouseCursor(int x, int y, const byte *shape) { if (!shape) return; int mouseW = shape[2] << 3; @@ -143,23 +143,23 @@ void Screen_Eob::setMouseCursor(int x, int y, const byte *shape) { _system->updateScreen(); } -void Screen_Eob::loadFileDataToPage(Common::SeekableReadStream *s, int pageNum, uint32 size) { +void Screen_EoB::loadFileDataToPage(Common::SeekableReadStream *s, int pageNum, uint32 size) { s->read(_pagePtrs[pageNum], size); } -void Screen_Eob::printShadedText(const char *string, int x, int y, int col1, int col2) { +void Screen_EoB::printShadedText(const char *string, int x, int y, int col1, int col2) { printText(string, x - 1, y, 12, col2); printText(string, x, y + 1, 12, 0); printText(string, x - 1, y + 1, 12, 0); printText(string, x, y, col1, 0); } -void Screen_Eob::loadShapeSetBitmap(const char *file, int tempPage, int destPage) { - loadEobBitmap(file, 0, tempPage, destPage, -1); +void Screen_EoB::loadShapeSetBitmap(const char *file, int tempPage, int destPage) { + loadEoBBitmap(file, 0, tempPage, destPage, -1); _curPage = 2; } -void Screen_Eob::loadEobBitmap(const char *file, const uint8 *ditheringData, int tempPage, int destPage, int copyToPage) { +void Screen_EoB::loadEoBBitmap(const char *file, const uint8 *ditheringData, int tempPage, int destPage, int copyToPage) { Common::String tmp = Common::String::format("%s.CPS", file); Common::SeekableReadStream *s = _vm->resource()->createReadStream(tmp); bool loadAlternative = false; @@ -183,7 +183,7 @@ void Screen_Eob::loadEobBitmap(const char *file, const uint8 *ditheringData, int tmp.setChar('X', 0); s = _vm->resource()->createReadStream(tmp); if (!s) - error("Screen_Eob::loadEobBitmap(): CPS file loading failed."); + error("Screen_EoB::loadEoBBitmap(): CPS file loading failed."); s->seek(768); loadFileDataToPage(s, destPage, 64000); delete s; @@ -200,7 +200,7 @@ void Screen_Eob::loadEobBitmap(const char *file, const uint8 *ditheringData, int } } -uint8 *Screen_Eob::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool no4bitEncoding) { +uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool no4bitEncoding) { uint8 *shp = 0; uint16 shapesize = 0; @@ -325,7 +325,7 @@ uint8 *Screen_Eob::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool no4b return shp; } -void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd, int flags, ...) { +void Screen_EoB::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd, int flags, ...) { uint8 *dst = getPagePtr(pageNum); const uint8 *src = shapeData; @@ -642,7 +642,7 @@ void Screen_Eob::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, } } -const uint8 *Screen_Eob::scaleShape(const uint8 *shapeData, int steps) { +const uint8 *Screen_EoB::scaleShape(const uint8 *shapeData, int steps) { setShapeFadeMode(1, steps ? true : false); while (shapeData && steps--) @@ -651,7 +651,7 @@ const uint8 *Screen_Eob::scaleShape(const uint8 *shapeData, int steps) { return shapeData; } -const uint8 *Screen_Eob::scaleShapeStep(const uint8 *shp) { +const uint8 *Screen_EoB::scaleShapeStep(const uint8 *shp) { uint8 *d = _dsTempPage; *d++ = *shp++; @@ -701,14 +701,14 @@ const uint8 *Screen_Eob::scaleShapeStep(const uint8 *shp) { return (const uint8 *) _dsTempPage; } -void Screen_Eob::replaceShapePalette(uint8 *shp, const uint8 *pal) { +void Screen_EoB::replaceShapePalette(uint8 *shp, const uint8 *pal) { if (*shp != 1) return; shp += 4; memcpy(shp, pal, 16); } -void Screen_Eob::applyShapeOverlay(uint8 *shp, int ovlIndex) { +void Screen_EoB::applyShapeOverlay(uint8 *shp, int ovlIndex) { if (*shp != 1) return; shp += 4; @@ -717,25 +717,25 @@ void Screen_Eob::applyShapeOverlay(uint8 *shp, int ovlIndex) { shp[i] = ovl[shp[i]]; } -void Screen_Eob::setShapeFrame(int x1, int y1, int x2, int y2) { +void Screen_EoB::setShapeFrame(int x1, int y1, int x2, int y2) { _dsX1 = x1; _dsY1 = y1; _dsX2 = x2; _dsY2 = y2; } -void Screen_Eob::setShapeFadeMode (uint8 i, bool b) { +void Screen_EoB::setShapeFadeMode (uint8 i, bool b) { if (!i || i == 1) _shapeFadeMode[i] = b; } -void Screen_Eob::setGfxParameters(int x, int y, int col) { +void Screen_EoB::setGfxParameters(int x, int y, int col) { _gfxX = x; _gfxY = y; _gfxCol = col; } -void Screen_Eob::drawExplosion(int scale, int radius, int numElements, int stepSize, int aspectRatio, const uint8 *colorTable, int colorTableSize) { +void Screen_EoB::drawExplosion(int scale, int radius, int numElements, int stepSize, int aspectRatio, const uint8 *colorTable, int colorTableSize) { int ymin = 0; int ymax = _gfxMaxY[scale]; int xmin = -100; @@ -837,7 +837,7 @@ void Screen_Eob::drawExplosion(int scale, int radius, int numElements, int stepS showMouse(); } -void Screen_Eob::drawVortex(int numElements, int radius, int stepSize, int, int disorder, const uint8 *colorTable, int colorTableSize) { +void Screen_EoB::drawVortex(int numElements, int radius, int stepSize, int, int disorder, const uint8 *colorTable, int colorTableSize) { int16 *xCoords = (int16*)_dsTempPage; int16 *yCoords = (int16*)&_dsTempPage[300]; int16 *xMod = (int16*)&_dsTempPage[600]; @@ -973,7 +973,7 @@ void Screen_Eob::drawVortex(int numElements, int radius, int stepSize, int, int showMouse(); } -void Screen_Eob::fadeTextColor(Palette *pal, int color1, int rate) { +void Screen_EoB::fadeTextColor(Palette *pal, int color1, int rate) { uint8 *col = pal->getData(); for (bool loop = true; loop; ) { @@ -1002,7 +1002,7 @@ void Screen_Eob::fadeTextColor(Palette *pal, int color1, int rate) { } } -bool Screen_Eob::delayedFadePalStep(Palette *fadePal, Palette *destPal, int rate) { +bool Screen_EoB::delayedFadePalStep(Palette *fadePal, Palette *destPal, int rate) { bool res = false; uint8 *s = fadePal->getData(); @@ -1031,15 +1031,15 @@ bool Screen_Eob::delayedFadePalStep(Palette *fadePal, Palette *destPal, int rate return res; } -int Screen_Eob::getRectSize(int w, int h) { +int Screen_EoB::getRectSize(int w, int h) { return w * h; } -void Screen_Eob::setFadeTableIndex(int index) { +void Screen_EoB::setFadeTableIndex(int index) { _fadeDataIndex = (CLIP(index, 0, 7) << 8); } -void Screen_Eob::createFadeTable(uint8 *palData, uint8 *dst, uint8 rootColor, uint8 weight) { +void Screen_EoB::createFadeTable(uint8 *palData, uint8 *dst, uint8 rootColor, uint8 weight) { if (!palData) return; @@ -1082,11 +1082,11 @@ void Screen_Eob::createFadeTable(uint8 *palData, uint8 *dst, uint8 rootColor, ui } } -uint8 *Screen_Eob::getFadeTable(int index) { +uint8 *Screen_EoB::getFadeTable(int index) { return (index >= 0 && index < 5) ? &_fadeData[index << 8] : 0; } -void Screen_Eob::drawShapeSetPixel(uint8 * dst, uint8 c) { +void Screen_EoB::drawShapeSetPixel(uint8 * dst, uint8 c) { if (_shapeFadeMode[0]) { if (_shapeFadeMode[1]) { c = *dst; @@ -1105,7 +1105,7 @@ void Screen_Eob::drawShapeSetPixel(uint8 * dst, uint8 c) { *dst = c; } -void Screen_Eob::scaleShapeProcessLine(uint8 *&dst, const uint8 *&src) { +void Screen_EoB::scaleShapeProcessLine(uint8 *&dst, const uint8 *&src) { for (int i = 0; i < _dsDiv; i++) { *dst++ = *src++; *dst++ = (READ_BE_UINT16(src) >> 4) & 0xff; @@ -1124,7 +1124,7 @@ void Screen_Eob::scaleShapeProcessLine(uint8 *&dst, const uint8 *&src) { } } -bool Screen_Eob::posWithinRect(int posX, int posY, int x1, int y1, int x2, int y2) { +bool Screen_EoB::posWithinRect(int posX, int posY, int x1, int y1, int x2, int y2) { if (posX < x1 || posX > x2 || posY < y1 || posY > y2) return false; return true; -- cgit v1.2.3 From 60330556ff5bf319db7815e6f3c635bc98edecc5 Mon Sep 17 00:00:00 2001 From: athrxx Date: Sat, 17 Dec 2011 22:39:11 +0100 Subject: KYRA: (EOB/LOL) - move eob/lol specific screen code to new class --- engines/kyra/screen_eob.cpp | 36 +----------------------------------- 1 file changed, 1 insertion(+), 35 deletions(-) (limited to 'engines/kyra/screen_eob.cpp') diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp index 869f4375ae..15a9fefc37 100644 --- a/engines/kyra/screen_eob.cpp +++ b/engines/kyra/screen_eob.cpp @@ -36,7 +36,7 @@ namespace Kyra { -Screen_EoB::Screen_EoB(EoBCoreEngine *vm, OSystem *system) : Screen(vm, system) { +Screen_EoB::Screen_EoB(EoBCoreEngine *vm, OSystem *system) : Screen(vm, system), Screen_Rpg(vm, system, _screenDimTable, _screenDimTableCount) { _shapeFadeMode[0] = _shapeFadeMode[1] = 0; _shapeFadeInternal = 0; _fadeData = 0; @@ -44,9 +44,7 @@ Screen_EoB::Screen_EoB(EoBCoreEngine *vm, OSystem *system) : Screen(vm, system) _dsX1 = _dsX2 = _dsY1 = _dsY2 = 0; _gfxX = _gfxY = 0; _gfxCol = 0; - _customDimTable = 0; _dsTempPage = 0; - _curDimIndex = 0; _dsDiv = 0; _dsRem = 0; _dsScaleTmp = 0; @@ -55,19 +53,11 @@ Screen_EoB::Screen_EoB(EoBCoreEngine *vm, OSystem *system) : Screen(vm, system) Screen_EoB::~Screen_EoB() { delete[] _fadeData; - if (_customDimTable) { - for (int i = 0; i < _screenDimTableCount; i++) - delete _customDimTable[i]; - } - delete[] _customDimTable; delete[] _dsTempPage; } bool Screen_EoB::init() { if (Screen::init()) { - _customDimTable = new ScreenDim*[_screenDimTableCount]; - memset(_customDimTable, 0, sizeof(ScreenDim*) * _screenDimTableCount); - int temp; _gfxMaxY = _vm->staticres()->loadRawData(kEoBBaseExpObjectY, temp); _fadeData = _vm->resource()->fileData("FADING.DAT", 0); @@ -88,30 +78,6 @@ bool Screen_EoB::init() { return false; } -void Screen_EoB::setScreenDim(int dim) { - assert(dim < _screenDimTableCount); - _curDim = _customDimTable[dim] ? (const ScreenDim *)_customDimTable[dim] : &_screenDimTable[dim]; - _curDimIndex = dim; -} - -const ScreenDim *Screen_EoB::getScreenDim(int dim) { - assert(dim < _screenDimTableCount); - return _customDimTable[dim] ? (const ScreenDim *)_customDimTable[dim] : &_screenDimTable[dim]; -} - -void Screen_EoB::modifyScreenDim(int dim, int x, int y, int w, int h) { - if (!_customDimTable[dim]) - _customDimTable[dim] = new ScreenDim; - - memcpy(_customDimTable[dim], &_screenDimTable[dim], sizeof(ScreenDim)); - _customDimTable[dim]->sx = x; - _customDimTable[dim]->sy = y; - _customDimTable[dim]->w = w; - _customDimTable[dim]->h = h; - if (dim == _curDimIndex) - setScreenDim(dim); -} - void Screen_EoB::setClearScreenDim(int dim) { setScreenDim(dim); clearCurDim(); -- cgit v1.2.3 From 692f9ee6d524752bf1b1d169f81f68309901187a Mon Sep 17 00:00:00 2001 From: athrxx Date: Mon, 12 Dec 2011 19:05:29 +0100 Subject: KYRA: whitespace cleanup --- engines/kyra/screen_eob.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/kyra/screen_eob.cpp') diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp index 15a9fefc37..62d8bca201 100644 --- a/engines/kyra/screen_eob.cpp +++ b/engines/kyra/screen_eob.cpp @@ -285,7 +285,7 @@ uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool no4b srcPage += 320; src = srcPage; } - delete [] colorMap; + delete [] colorMap; } return shp; -- cgit v1.2.3 From 487e73bd218775dec22818477ad75dd230d97052 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Mon, 26 Dec 2011 19:27:20 +0100 Subject: KYRA: Merge Screen_Rpg with Screen (for now). This should(!) fix ARM compilation issues due to virtual inheritance. --- engines/kyra/screen_eob.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/kyra/screen_eob.cpp') diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp index 62d8bca201..7061ada4ac 100644 --- a/engines/kyra/screen_eob.cpp +++ b/engines/kyra/screen_eob.cpp @@ -36,7 +36,7 @@ namespace Kyra { -Screen_EoB::Screen_EoB(EoBCoreEngine *vm, OSystem *system) : Screen(vm, system), Screen_Rpg(vm, system, _screenDimTable, _screenDimTableCount) { +Screen_EoB::Screen_EoB(EoBCoreEngine *vm, OSystem *system) : Screen(vm, system, _screenDimTable, _screenDimTableCount) { _shapeFadeMode[0] = _shapeFadeMode[1] = 0; _shapeFadeInternal = 0; _fadeData = 0; -- cgit v1.2.3 From a95f34bc64ada8f1d35466a0e4cb10c96ba95580 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Tue, 27 Dec 2011 02:02:19 +0100 Subject: KYRA: Some formatting fixes. --- engines/kyra/screen_eob.cpp | 76 ++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 38 deletions(-) (limited to 'engines/kyra/screen_eob.cpp') diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp index 7061ada4ac..6b1128bdfd 100644 --- a/engines/kyra/screen_eob.cpp +++ b/engines/kyra/screen_eob.cpp @@ -198,7 +198,7 @@ uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool no4b shapesize += 4; shp = new uint8[shapesize]; - memset (shp, 0, shapesize); + memset(shp, 0, shapesize); uint8 *dst = shp; *dst++ = 0; @@ -239,18 +239,18 @@ uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool no4b } else { uint8 nib = 0, col = 0; uint8 *colorMap = new uint8[0x100]; - memset (colorMap, 0xff, 0x100); + memset(colorMap, 0xff, 0x100); shapesize = h * (w << 2) + 20; shp = new uint8[shapesize]; - memset (shp, 0, shapesize); + memset(shp, 0, shapesize); uint8 *dst = shp; *dst++ = 1; *dst++ = (h & 0xff); *dst++ = (w & 0xff); *dst++ = (h & 0xff); - memset (dst, 0xff, 0x10); + memset(dst, 0xff, 0x10); uint8 *pal = dst; dst += 0x10; @@ -276,7 +276,7 @@ uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool no4b } } - if(++nib & 1) { + if (++nib & 1) { *dst = c << 4; } else { *dst++ |= c; @@ -300,7 +300,7 @@ void Screen_EoB::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, va_list args; va_start(args, flags); - uint8 *ovl = (flags & 2) ? va_arg(args, uint8*) : 0; + uint8 *ovl = (flags & 2) ? va_arg(args, uint8 *) : 0; va_end(args); if (sd != -1) { @@ -340,7 +340,7 @@ void Screen_EoB::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, return; src += (d * (width >> 1)); d = dY + dH - _dsY1; - if (d >=0) { + if (d >= 0) { dH = d; dY = _dsY1; d = _dsY2 - dY; @@ -355,7 +355,7 @@ void Screen_EoB::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, if (d < dH) dH = d; - int16 cnt1 = 0; + int16 cnt1 = 0; int16 cnt2 = 0; int16 dXbit1 = dX & 1; @@ -488,7 +488,7 @@ void Screen_EoB::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, marginLeft = marginLeft + 1 - *src++; } } - dY = _dsY1; + dY = _dsY1; } d = _dsY2 - dY; @@ -523,7 +523,7 @@ void Screen_EoB::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, } dst += (dY * 320 + dX); - uint8 * dstL = dst; + uint8 *dstL = dst; if (pageNum == 0 || pageNum == 1) addDirtyRect(rX, rY, rW, rH); @@ -664,7 +664,7 @@ const uint8 *Screen_EoB::scaleShapeStep(const uint8 *shp) { shp += w2; } - return (const uint8 *) _dsTempPage; + return (const uint8 *)_dsTempPage; } void Screen_EoB::replaceShapePalette(uint8 *shp, const uint8 *pal) { @@ -690,7 +690,7 @@ void Screen_EoB::setShapeFrame(int x1, int y1, int x2, int y2) { _dsY2 = y2; } -void Screen_EoB::setShapeFadeMode (uint8 i, bool b) { +void Screen_EoB::setShapeFadeMode(uint8 i, bool b) { if (!i || i == 1) _shapeFadeMode[i] = b; } @@ -721,13 +721,13 @@ void Screen_EoB::drawExplosion(int scale, int radius, int numElements, int stepS int16 gx2 = _gfxX; int16 gy2 = _gfxY; - int16 *ptr2 = (int16*)_dsTempPage; - int16 *ptr3 = (int16*)&_dsTempPage[300]; - int16 *ptr4 = (int16*)&_dsTempPage[600]; - int16 *ptr5 = (int16*)&_dsTempPage[900]; - int16 *ptr6 = (int16*)&_dsTempPage[1200]; - int16 *ptr7 = (int16*)&_dsTempPage[1500]; - int16 *ptr8 = (int16*)&_dsTempPage[1800]; + int16 *ptr2 = (int16 *)_dsTempPage; + int16 *ptr3 = (int16 *)&_dsTempPage[300]; + int16 *ptr4 = (int16 *)&_dsTempPage[600]; + int16 *ptr5 = (int16 *)&_dsTempPage[900]; + int16 *ptr6 = (int16 *)&_dsTempPage[1200]; + int16 *ptr7 = (int16 *)&_dsTempPage[1500]; + int16 *ptr8 = (int16 *)&_dsTempPage[1800]; if (numElements > 150) numElements = 150; @@ -804,14 +804,14 @@ void Screen_EoB::drawExplosion(int scale, int radius, int numElements, int stepS } void Screen_EoB::drawVortex(int numElements, int radius, int stepSize, int, int disorder, const uint8 *colorTable, int colorTableSize) { - int16 *xCoords = (int16*)_dsTempPage; - int16 *yCoords = (int16*)&_dsTempPage[300]; - int16 *xMod = (int16*)&_dsTempPage[600]; - int16 *yMod = (int16*)&_dsTempPage[900]; - int16 *pixBackup = (int16*)&_dsTempPage[1200]; - int16 *colTableStep = (int16*)&_dsTempPage[1500]; - int16 *colTableIndex = (int16*)&_dsTempPage[1800]; - int16 *pixDelay = (int16*)&_dsTempPage[2100]; + int16 *xCoords = (int16 *)_dsTempPage; + int16 *yCoords = (int16 *)&_dsTempPage[300]; + int16 *xMod = (int16 *)&_dsTempPage[600]; + int16 *yMod = (int16 *)&_dsTempPage[900]; + int16 *pixBackup = (int16 *)&_dsTempPage[1200]; + int16 *colTableStep = (int16 *)&_dsTempPage[1500]; + int16 *colTableIndex = (int16 *)&_dsTempPage[1800]; + int16 *pixDelay = (int16 *)&_dsTempPage[2100]; hideMouse(); int cp = _curPage; @@ -873,7 +873,7 @@ void Screen_EoB::drawVortex(int numElements, int radius, int stepSize, int, int } int d = 0; - for (int i = 2; i; ) { + for (int i = 2; i;) { if (i != 2) { for (int ii = numElements - 1; ii >= 0; ii--) { int16 px = CLIP((xCoords[ii] >> 6) + cx, 0, SCREEN_W - 1); @@ -911,7 +911,7 @@ void Screen_EoB::drawVortex(int numElements, int radius, int stepSize, int, int int16 px = CLIP((xCoords[ii] >> 6) + cx, 0, SCREEN_W - 1); int16 py = CLIP((yCoords[ii] >> 6) + cy, 0, SCREEN_H - 1); - uint8 tc1 = ((disorder >> 2) <= d) ? getPagePixel(2, px, py) : 0; + uint8 tc1 = ((disorder >> 2) <= d) ? getPagePixel(2, px, py) : 0; pixBackup[ii] = getPagePixel(0, px, py); uint8 tblIndex = CLIP(colTableIndex[ii] >> 8, 0, colorTableSize - 1); uint8 tc2 = colorTable[tblIndex]; @@ -942,7 +942,7 @@ void Screen_EoB::drawVortex(int numElements, int radius, int stepSize, int, int void Screen_EoB::fadeTextColor(Palette *pal, int color1, int rate) { uint8 *col = pal->getData(); - for (bool loop = true; loop; ) { + for (bool loop = true; loop;) { loop = true; uint32 end = _system->getMillis() + _vm->tickLength(); @@ -1027,7 +1027,7 @@ void Screen_EoB::createFadeTable(uint8 *palData, uint8 *dst, uint8 rootColor, ui tmp = (uint16)((*src - b) * weight) << 1; tb = *src++ - ((tmp >> 8) & 0xff); - uint8 * d = palData + 3; + uint8 *d = palData + 3; uint16 v = 0xffff; uint8 col = rootColor; @@ -1044,7 +1044,7 @@ void Screen_EoB::createFadeTable(uint8 *palData, uint8 *dst, uint8 rootColor, ui col = ii ; } } - *dst++ = col; + *dst++ = col; } } @@ -1052,13 +1052,13 @@ uint8 *Screen_EoB::getFadeTable(int index) { return (index >= 0 && index < 5) ? &_fadeData[index << 8] : 0; } -void Screen_EoB::drawShapeSetPixel(uint8 * dst, uint8 c) { +void Screen_EoB::drawShapeSetPixel(uint8 *dst, uint8 c) { if (_shapeFadeMode[0]) { if (_shapeFadeMode[1]) { c = *dst; } else { _shapeFadeInternal &= 7; - c = *(dst + _shapeFadeInternal++); + c = *(dst + _shapeFadeInternal++); } } @@ -1134,7 +1134,7 @@ int OldDOSFont::getCharWidth(uint16 c) const { } void OldDOSFont::drawChar(uint16 c, byte *dst, int pitch) const { - static const uint8 renderMaskTable6[] = { 0xFC, 0x00, 0x7E, 0x00, 0x3F, 0x00, 0x1F, 0x80, 0x0F, 0xC0, 0x07, 0xE0, 0x03, 0xF0, 0x01, 0xF8 }; + static const uint8 renderMaskTable6[] = { 0xFC, 0x00, 0x7E, 0x00, 0x3F, 0x00, 0x1F, 0x80, 0x0F, 0xC0, 0x07, 0xE0, 0x03, 0xF0, 0x01, 0xF8 }; static const uint8 renderMaskTable8[] = { 0xFF, 0x00, 0x7F, 0x80, 0x3F, 0xC0, 0x1F, 0xE0, 0x0F, 0xF0, 0x07, 0xF8, 0x03, 0xFC, 0x01, 0xFE }; if (_width != 8 && _width != 6) @@ -1157,7 +1157,7 @@ void OldDOSFont::drawChar(uint16 c, byte *dst, int pitch) const { // TODO: recheck this: no conversion for 'ß' ? break; } - } else if (_width == 8){ + } else if (_width == 8) { switch (c) { case 0x81: case 0x9a: @@ -1197,7 +1197,7 @@ void OldDOSFont::drawChar(uint16 c, byte *dst, int pitch) const { int cW = w; const uint8 *mtbl = _width == 8 ? renderMaskTable8 : renderMaskTable6; - for (bool runWidthLoop = true; runWidthLoop; ) { + for (bool runWidthLoop = true; runWidthLoop;) { uint8 s = *src++; uint8 m = *mtbl++; @@ -1233,6 +1233,6 @@ void OldDOSFont::unload() { _bitmapOffsets = 0; } -} // End of namespace Kyra +} // End of namespace Kyra #endif // ENABLE_EOB -- cgit v1.2.3 From 86a817beb5eef248c5f5e28f18133db802a59c2e Mon Sep 17 00:00:00 2001 From: athrxx Date: Mon, 13 Feb 2012 18:39:50 +0100 Subject: KYRA: (EOB) - start work on CGA and EGA graphics modes --- engines/kyra/screen_eob.cpp | 320 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 284 insertions(+), 36 deletions(-) (limited to 'engines/kyra/screen_eob.cpp') diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp index 6b1128bdfd..aa94114dfc 100644 --- a/engines/kyra/screen_eob.cpp +++ b/engines/kyra/screen_eob.cpp @@ -33,6 +33,7 @@ #include "common/system.h" #include "graphics/cursorman.h" +#include "graphics/palette.h" namespace Kyra { @@ -49,29 +50,66 @@ Screen_EoB::Screen_EoB(EoBCoreEngine *vm, OSystem *system) : Screen(vm, system, _dsRem = 0; _dsScaleTmp = 0; _gfxMaxY = 0; + _egaColorMap = 0; + _egaPixelValueTable = 0; + _cgaMappingDefault = 0; + _cgaDitheringTables[0] = _cgaDitheringTables[1] = 0; + _useHiResEGADithering = false; } Screen_EoB::~Screen_EoB() { delete[] _fadeData; delete[] _dsTempPage; + delete[] _egaColorMap; + delete[] _egaPixelValueTable; + delete[] _cgaDitheringTables[0]; + delete[] _cgaDitheringTables[1]; + delete[] _cgaDrawCharDitheringTable; } bool Screen_EoB::init() { if (Screen::init()) { int temp; _gfxMaxY = _vm->staticres()->loadRawData(kEoBBaseExpObjectY, temp); - _fadeData = _vm->resource()->fileData("FADING.DAT", 0); + + if (_renderMode != Common::kRenderCGA && _renderMode != Common::kRenderEGA) + _fadeData = _vm->resource()->fileData("FADING.DAT", 0); if (!_fadeData) { _fadeData = new uint8[0x700]; memset(_fadeData, 0, 0x700); - uint8 *pal = _vm->resource()->fileData("palette1.pal", 0); // EGA: palette0.pal - for (int i = 0; i < 7; i++) - createFadeTable(pal, &_fadeData[i << 8], 18, (i + 1) * 36); - delete[] pal; + if (_renderMode != Common::kRenderCGA && _renderMode != Common::kRenderEGA) { + uint8 *pal = _vm->resource()->fileData("PALETTE1.PAL", 0); + for (int i = 0; i < 7; i++) + createFadeTable(pal, &_fadeData[i << 8], 18, (i + 1) * 36); + delete[] pal; + } } _dsTempPage = new uint8[6000]; + if (_renderMode == Common::kRenderEGA) { + _egaColorMap = new uint8[256]; + _egaPixelValueTable = new uint8[256]; + for (int i = 0; i < 256; i++) { + _egaColorMap[i] = i & 0x0f; + _egaPixelValueTable[i] = i & 0x0f; + } + + if (_vm->game() == GI_EOB2) + _useHiResEGADithering = true; + } else if (_renderMode == Common::kRenderCGA) { + _cgaMappingDefault = _vm->staticres()->loadRawData(kEoB1CgaMappingDefault, temp); + _cgaDitheringTables[0] = new uint16[256]; + memset(_cgaDitheringTables[0], 0, 256 * sizeof(uint16)); + _cgaDitheringTables[1] = new uint16[256]; + memset(_cgaDitheringTables[1], 0, 256 * sizeof(uint16)); + _cgaDrawCharDitheringTable = new uint16[256]; + memset(_cgaDrawCharDitheringTable, 0, 256 * sizeof(uint16)); + + static const uint bits[] = { 0, 3, 12, 15 }; + for (int i = 0; i < 256; i++) + WRITE_BE_UINT16(&_cgaDrawCharDitheringTable[i], (bits[i & 3] << 8) | (bits[(i >> 2) & 3] << 12) | (bits[(i >> 4) & 3] << 0) | (bits[(i >> 6) & 3] << 4)); + } return true; } @@ -121,12 +159,13 @@ void Screen_EoB::printShadedText(const char *string, int x, int y, int col1, int } void Screen_EoB::loadShapeSetBitmap(const char *file, int tempPage, int destPage) { - loadEoBBitmap(file, 0, tempPage, destPage, -1); + loadEoBBitmap(file, _cgaMappingDefault, tempPage, destPage, -1); _curPage = 2; } -void Screen_EoB::loadEoBBitmap(const char *file, const uint8 *ditheringData, int tempPage, int destPage, int copyToPage) { - Common::String tmp = Common::String::format("%s.CPS", file); +void Screen_EoB::loadEoBBitmap(const char *file, const uint8 *cgaMapping, int tempPage, int destPage, int convertToPage) { + const char *filePattern = (_vm->game() == GI_EOB1 && (_renderMode == Common::kRenderEGA || _renderMode == Common::kRenderCGA)) ? "%s.EGA" : "%s.CPS"; + Common::String tmp = Common::String::format(filePattern, file); Common::SeekableReadStream *s = _vm->resource()->createReadStream(tmp); bool loadAlternative = false; if (s) { @@ -149,28 +188,124 @@ void Screen_EoB::loadEoBBitmap(const char *file, const uint8 *ditheringData, int tmp.setChar('X', 0); s = _vm->resource()->createReadStream(tmp); if (!s) - error("Screen_EoB::loadEoBBitmap(): CPS file loading failed."); + error("Screen_EoB::loadEoBBitmap(): Failed to load file '%s'", file); s->seek(768); loadFileDataToPage(s, destPage, 64000); delete s; } } - if (copyToPage == -1) { + if (convertToPage == -1) { return; - } else if (copyToPage == 0) { - copyPage(destPage, 2); + } else if (convertToPage == 2 && _renderMode == Common::kRenderCGA) { + convertPage(destPage, 4, cgaMapping); + copyRegion(0, 0, 0, 0, 320, 200, 4, 2, Screen::CR_NO_P_CHECK); + } else if (convertToPage == 0) { + convertPage(destPage, 2, cgaMapping); copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK); } else { - copyPage(destPage, copyToPage); + convertPage(destPage, convertToPage, cgaMapping); + } +} + +void Screen_EoB::convertPage(int srcPage, int dstPage, const uint8 *cgaMapping) { + uint8 *src = getPagePtr(srcPage); + uint8 *dst = getPagePtr(dstPage); + if (src == dst) + return; + + if (_renderMode == Common::kRenderCGA) { + generateCGADitheringTables(cgaMapping); + uint16 *d = (uint16*)dst; + uint8 tblSwitch = 0; + for (int height = SCREEN_H; height; height--) { + const uint16 *table = _cgaDitheringTables[(tblSwitch++) & 1]; + for (int width = SCREEN_W / 2; width; width--) { + *d++ = table[((src[0] & 0x0f) << 4) | (src[1] & 0x0f)]; + src += 2; + } + } + + if (dstPage == 0 || dstPage == 1) + _forceFullUpdate = true; + + } else if (_renderMode == Common::kRenderEGA) { + uint32 len = SCREEN_W * SCREEN_H; + if (_useHiResEGADithering) { + while (len--) { + uint8 col = _egaColorMap[*src++] & 0x0f; + *dst++ = col; + + /*for (int i = 4; i; i--) { + uint8 col = _egaColorMap[*src++]; + + }*/ + } + } else { + while (len--) + *dst++ = *src++ & 0x0f; + } + + if (dstPage == 0 || dstPage == 1) + _forceFullUpdate = true; + } else { + copyPage(srcPage, dstPage); + } +} + +void Screen_EoB::setScreenPalette(const Palette &pal) { + if (_renderMode == Common::kRenderEGA && _egaColorMap && pal.getNumColors() != 16) { + const uint8 *src = pal.getData(); + uint8 *dst = _egaColorMap; + + for (int i = 256; i; i--) { + uint8 r = *src++; + uint8 g = *src++; + uint8 b = *src++; + + uint8 col = 0; + uint16 min = 11907; + + for (int ii = 256; ii; ii--) { + const uint8 *palEntry = _egaMatchTable + (ii - 1) * 3; + if (*palEntry == 0xff) + continue; + + int e_r = palEntry[0]; + e_r -= r; + int e_g = palEntry[1]; + e_g -= g; + int e_b = palEntry[2]; + e_b -= b; + + int s = (e_r * e_r) + (e_g * e_g) + (e_b * e_b); + + if (s < min) { + min = s; + col = ii - 1; + } + } + *dst++ = col; + } + + memset(_egaPixelValueTable, 0, 256); + for (int i = 0; i < 256; i++) + _egaPixelValueTable[_egaColorMap[i]] = i; + + } else if (_renderMode == Common::kRenderEGA) { + _screenPalette->copy(pal); + _system->getPaletteManager()->setPalette(_screenPalette->getData(), 0, _screenPalette->getNumColors()); + + } else if (_renderMode != Common::kRenderCGA) { + Screen::setScreenPalette(pal); } } -uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool no4bitEncoding) { +uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool no4bitEncoding, const uint8 *cgaMapping) { uint8 *shp = 0; uint16 shapesize = 0; - uint8 *srcPage = getPagePtr(_curPage) + y * 320 + (x << 3); + uint8 *srcPage = getPagePtr(_curPage | 1) + y * 320 + (x << 3); uint8 *src = srcPage; if (no4bitEncoding) { @@ -206,7 +341,7 @@ uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool no4b *dst++ = (w & 0xff); *dst++ = (h & 0xff); - srcPage = getPagePtr(_curPage) + y * 320 + (x << 3); + srcPage = getPagePtr(_curPage | 1) + y * 320 + (x << 3); src = srcPage; h1 = h; @@ -255,7 +390,7 @@ uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool no4b uint8 *pal = dst; dst += 0x10; - srcPage = getPagePtr(_curPage) + y * 320 + (x << 3); + srcPage = getPagePtr(_curPage | 1) + y * 320 + (x << 3); src = srcPage; nib = col = 0; @@ -1096,12 +1231,74 @@ bool Screen_EoB::posWithinRect(int posX, int posY, int x1, int y1, int x2, int y return true; } -OldDOSFont::OldDOSFont() { +void Screen_EoB::generateCGADitheringTables(const uint8 *mappingData) { + for (int i = 0; i < 256; i++) { + WRITE_BE_UINT16(&_cgaDitheringTables[0][i], (mappingData[i >> 4] << 8) | mappingData[(i & 0x0f) + 16]); + WRITE_BE_UINT16(&_cgaDitheringTables[1][i], (mappingData[(i >> 4) + 16] << 8) | mappingData[i & 0x0f]); + } +} + +const uint8 Screen_EoB::_egaMatchTable[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x1E, 0x00, 0x00, 0x1E, 0x1E, 0x1E, 0x00, 0x00, 0x1E, + 0x00, 0x1E, 0x1E, 0x0F, 0x00, 0x1E, 0x1E, 0x1E, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x2D, 0x0F, 0x2D, + 0x0F, 0x0F, 0x2D, 0x2D, 0x2D, 0x0F, 0x0F, 0x2D, 0x0F, 0x2D, 0x2D, 0x2D, 0x0F, 0x2D, 0x2D, 0x2D, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x2A, 0x00, 0x1E, 0x1E, 0x00, 0x1E, 0x2A, 0x1E, 0x00, 0x1E, 0x1E, + 0x00, 0x2A, 0x1E, 0x0F, 0x1E, 0x1E, 0x1E, 0x2A, 0x0F, 0x0F, 0x21, 0x0F, 0x0F, 0x36, 0x0F, 0x2D, + 0x21, 0x0F, 0x2D, 0x36, 0x2D, 0x0F, 0x21, 0x2D, 0x0F, 0x36, 0x2D, 0x2D, 0x21, 0x2D, 0x2D, 0x36, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x2A, 0x00, 0x00, 0x2A, 0x1E, 0x1E, 0x1E, 0x00, 0x1E, + 0x1E, 0x1E, 0x1E, 0x21, 0x00, 0x1E, 0x2A, 0x1E, 0x0F, 0x21, 0x0F, 0x0F, 0x21, 0x2D, 0x0F, 0x36, + 0x0F, 0x0F, 0x36, 0x2D, 0x2D, 0x21, 0x0F, 0x2D, 0x21, 0x2D, 0x2D, 0x36, 0x0F, 0x2D, 0x36, 0x2D, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x2A, 0x2A, 0x1E, 0x1E, 0x1E, 0x1E, + 0x1E, 0x2A, 0x1E, 0x21, 0x1E, 0x1E, 0x2A, 0x2A, 0x0F, 0x21, 0x21, 0x0F, 0x21, 0x36, 0x0F, 0x36, + 0x21, 0x0F, 0x36, 0x36, 0x2D, 0x21, 0x21, 0x2D, 0x21, 0x36, 0x2D, 0x36, 0x21, 0x2D, 0x36, 0x36, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2A, 0x00, 0x00, 0x2A, + 0x00, 0x1E, 0x2A, 0x0F, 0x00, 0x2A, 0x1E, 0x1E, 0x21, 0x0F, 0x0F, 0x21, 0x0F, 0x2D, 0x21, 0x2D, + 0x0F, 0x21, 0x2D, 0x2D, 0x36, 0x0F, 0x0F, 0x36, 0x0F, 0x2D, 0x36, 0x2D, 0x0F, 0x36, 0x2D, 0x2D, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2A, + 0x00, 0x2A, 0x2A, 0x0F, 0x1E, 0x2A, 0x1E, 0x2A, 0x21, 0x0F, 0x21, 0x21, 0x0F, 0x36, 0x21, 0x2D, + 0x21, 0x21, 0x2D, 0x36, 0x36, 0x0F, 0x21, 0x36, 0x0F, 0x36, 0x36, 0x2D, 0x21, 0x36, 0x2D, 0x36, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x2A, 0x15, 0x00, 0x2A, 0x21, 0x1E, 0x21, 0x15, 0x0F, 0x21, 0x15, 0x2D, 0x21, 0x2F, + 0x0F, 0x21, 0x2F, 0x2D, 0x36, 0x15, 0x0F, 0x36, 0x15, 0x2D, 0x36, 0x2F, 0x0F, 0x36, 0x2F, 0x2D, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x2A, 0x2A, 0x2A, 0x21, 0x21, 0x21, 0x21, 0x21, 0x36, 0x21, 0x36, + 0x21, 0x21, 0x36, 0x36, 0x36, 0x21, 0x21, 0x36, 0x21, 0x36, 0x36, 0x36, 0x21, 0x36, 0x36, 0x36, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x15, 0x15, 0x15, 0x15, 0x15, 0x2F, 0x15, 0x2F, + 0x15, 0x15, 0x2F, 0x2F, 0x2F, 0x15, 0x15, 0x2F, 0x15, 0x2F, 0x2F, 0x2F, 0x15, 0x2F, 0x2F, 0x2F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x15, 0x15, 0x3F, 0x15, 0x2F, + 0x2F, 0x15, 0x2F, 0x3F, 0x2F, 0x15, 0x2F, 0x2F, 0x15, 0x3F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x15, 0x3F, + 0x15, 0x15, 0x3F, 0x2F, 0x2F, 0x2F, 0x15, 0x2F, 0x2F, 0x2F, 0x2F, 0x3F, 0x15, 0x2F, 0x3F, 0x2F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x15, 0x3F, 0x3F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x3F, 0x2F, 0x3F, 0x2F, 0x2F, 0x3F, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x15, 0x15, 0x3F, 0x15, 0x2F, 0x3F, 0x2F, 0x15, 0x3F, 0x2F, 0x2F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x15, 0x3F, 0x3F, 0x2F, 0x2F, 0x3F, 0x2F, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F, 0x15, 0x3F, 0x3F, 0x2F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F, 0x3F +}; + +OldDOSFont::OldDOSFont(Common::RenderMode mode, const uint16 *cgaDitheringTable) : _renderMode(mode), _cgaDitheringTable(cgaDitheringTable) { _data = 0; _width = _height = _numGlyphs = 0; _bitmapOffsets = 0; } +OldDOSFont::~OldDOSFont() { + unload(); +} + bool OldDOSFont::load(Common::SeekableReadStream &file) { unload(); @@ -1192,36 +1389,87 @@ void OldDOSFont::drawChar(uint16 c, byte *dst, int pitch) const { uint8 color1 = _colorMap[1]; uint8 color2 = _colorMap[0]; + static const uint16 cgaColorMask[] = { 0, 0x5555, 0xAAAA, 0xFFFF }; + uint16 cgaMask1 = cgaColorMask[color1 & 3]; + uint16 cgaMask2 = cgaColorMask[color2 & 3]; + int cH = _height; while (cH--) { int cW = w; + uint8 last = 0; const uint8 *mtbl = _width == 8 ? renderMaskTable8 : renderMaskTable6; - for (bool runWidthLoop = true; runWidthLoop;) { + if (_renderMode == Common::kRenderCGA) { uint8 s = *src++; uint8 m = *mtbl++; - for (uint8 i = 0x80; i; i >>= 1) { - if (!(m & i)) { - runWidthLoop = false; - break; - } + uint8 in = s | last; + uint16 cmp1 = 0; + uint16 cmp2 = 0; + + if (color1) { + in &= m; + cmp1 = _cgaDitheringTable[in]; + } - if (s & i) { - if (color1) - *dst = color1; - } else if (color2) { - *dst = color2; - } - dst++; + if (color2) { + in = ~in & m; + cmp2 = _cgaDitheringTable[in]; } - if (cW) - cW--; - else - runWidthLoop = false; - } + uint16 cDst = 0; + uint8 sh = 14; + for (int i = 0; i < _width; i++) { + cDst |= ((dst[i] & 3) << sh); + sh -= 2; + } + uint16 out = (~(cmp1 | cmp2) & cDst) | (cmp1 & cgaMask1) | (cmp2 & cgaMask2); + + sh = 14; + for (int i = 0; i < _width; i++) { + *dst++ = (out >> sh) & 3; + sh -= 2; + } + + last = s; + } else { + for (bool runWidthLoop = true; runWidthLoop;) { + uint8 s = *src++; + uint8 m = *mtbl++; + + for (uint8 i = 0x80; i; i >>= 1) { + if (!(m & i)) { + runWidthLoop = false; + break; + } + + if (_renderMode == Common::kRenderCGA) { + uint8 in = s | last; + if (s & i) { + if (color1) + *dst = color1; + } else if (color2) { + *dst = color2; + } + last = s; + } else { + if (s & i) { + if (color1) + *dst = color1; + } else if (color2) { + *dst = color2; + } + } + dst++; + } + + if (cW) + cW--; + else + runWidthLoop = false; + } + } dst += pitch; } } -- cgit v1.2.3 From 151d314912b08d7d598a3995524d89c8b4ab0371 Mon Sep 17 00:00:00 2001 From: athrxx Date: Mon, 13 Feb 2012 17:04:05 +0100 Subject: KYRA: (EOB) - complete CGA graphics mode implementation --- engines/kyra/screen_eob.cpp | 540 ++++++++++++++++++++++++++------------------ 1 file changed, 316 insertions(+), 224 deletions(-) (limited to 'engines/kyra/screen_eob.cpp') diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp index aa94114dfc..8721c2cc02 100644 --- a/engines/kyra/screen_eob.cpp +++ b/engines/kyra/screen_eob.cpp @@ -48,7 +48,8 @@ Screen_EoB::Screen_EoB(EoBCoreEngine *vm, OSystem *system) : Screen(vm, system, _dsTempPage = 0; _dsDiv = 0; _dsRem = 0; - _dsScaleTmp = 0; + _dsScaleTrans = 0; + _cgaScaleTable = 0; _gfxMaxY = 0; _egaColorMap = 0; _egaPixelValueTable = 0; @@ -60,6 +61,7 @@ Screen_EoB::Screen_EoB(EoBCoreEngine *vm, OSystem *system) : Screen(vm, system, Screen_EoB::~Screen_EoB() { delete[] _fadeData; delete[] _dsTempPage; + delete[] _cgaScaleTable; delete[] _egaColorMap; delete[] _egaPixelValueTable; delete[] _cgaDitheringTables[0]; @@ -71,7 +73,7 @@ bool Screen_EoB::init() { if (Screen::init()) { int temp; _gfxMaxY = _vm->staticres()->loadRawData(kEoBBaseExpObjectY, temp); - + if (_renderMode != Common::kRenderCGA && _renderMode != Common::kRenderEGA) _fadeData = _vm->resource()->fileData("FADING.DAT", 0); @@ -86,7 +88,8 @@ bool Screen_EoB::init() { } } - _dsTempPage = new uint8[6000]; + _dsTempPage = new uint8[12000]; + if (_renderMode == Common::kRenderEGA) { _egaColorMap = new uint8[256]; _egaPixelValueTable = new uint8[256]; @@ -97,18 +100,24 @@ bool Screen_EoB::init() { if (_vm->game() == GI_EOB2) _useHiResEGADithering = true; + } else if (_renderMode == Common::kRenderCGA) { _cgaMappingDefault = _vm->staticres()->loadRawData(kEoB1CgaMappingDefault, temp); _cgaDitheringTables[0] = new uint16[256]; memset(_cgaDitheringTables[0], 0, 256 * sizeof(uint16)); _cgaDitheringTables[1] = new uint16[256]; memset(_cgaDitheringTables[1], 0, 256 * sizeof(uint16)); + _cgaDrawCharDitheringTable = new uint16[256]; memset(_cgaDrawCharDitheringTable, 0, 256 * sizeof(uint16)); - static const uint bits[] = { 0, 3, 12, 15 }; for (int i = 0; i < 256; i++) - WRITE_BE_UINT16(&_cgaDrawCharDitheringTable[i], (bits[i & 3] << 8) | (bits[(i >> 2) & 3] << 12) | (bits[(i >> 4) & 3] << 0) | (bits[(i >> 6) & 3] << 4)); + _cgaDrawCharDitheringTable[i] = (bits[i & 3] << 8) | (bits[(i >> 2) & 3] << 12) | (bits[(i >> 4) & 3] << 0) | (bits[(i >> 6) & 3] << 4); + + _cgaScaleTable = new uint8[256]; + memset(_cgaScaleTable, 0, 256 * sizeof(uint8)); + for (int i = 0; i < 256; i++) + _cgaScaleTable[i] = ((i & 0xf0) >> 2) | (i & 0x03); } return true; @@ -126,15 +135,43 @@ void Screen_EoB::clearCurDim() { } void Screen_EoB::setMouseCursor(int x, int y, const byte *shape) { + setMouseCursor(x, y, shape, 0); +} + +void Screen_EoB::setMouseCursor(int x, int y, const byte *shape, const uint8 *ovl) { if (!shape) return; int mouseW = shape[2] << 3; int mouseH = shape[3]; uint8 *cursor = new uint8[mouseW * mouseH]; fillRect(0, 0, mouseW, mouseH, _cursorColorKey, 8); - drawShape(8, shape, 0, 0, 0); + drawShape(8, shape, 0, 0, 0, 2, ovl); CursorMan.showMouse(false); copyRegionToBuffer(8, 0, 0, mouseW, mouseH, cursor); + + // Mouse cursor post processing for CGA mode. Unlike the original (which uses drawShape for the mouse cursor) + // the cursor manager cannot know whether a pixel value of 0 is supposed to be black or transparent. Thus, we + // go over the transparency mask again and turn the black pixels to color 4. + if (_renderMode == Common::kRenderCGA) { + const uint8 *maskTbl = shape + 4 + ((mouseW * mouseH) >> 2); + uint8 *dst = cursor; + uint8 trans = 0; + uint8 shift = 6; + + uint16 mH = mouseH; + while (mH--) { + uint16 mW = mouseW; + while (mW--) { + if (shift == 6) + trans = *maskTbl++; + if (!*dst && !((trans >> shift) & 3)) + *dst = 4; + dst++; + shift = (shift - 2) & 7; + } + } + } + CursorMan.replaceCursor(cursor, mouseW, mouseH, x, y, _cursorColorKey); if (isMouseVisible()) CursorMan.showMouse(true); @@ -215,13 +252,14 @@ void Screen_EoB::convertPage(int srcPage, int dstPage, const uint8 *cgaMapping) return; if (_renderMode == Common::kRenderCGA) { - generateCGADitheringTables(cgaMapping); + if (cgaMapping) + generateCGADitheringTables(cgaMapping); uint16 *d = (uint16*)dst; - uint8 tblSwitch = 0; + uint8 tblSwitch = 0; for (int height = SCREEN_H; height; height--) { const uint16 *table = _cgaDitheringTables[(tblSwitch++) & 1]; for (int width = SCREEN_W / 2; width; width--) { - *d++ = table[((src[0] & 0x0f) << 4) | (src[1] & 0x0f)]; + *d++ = table[((src[1] & 0x0f) << 4) | (src[0] & 0x0f)]; src += 2; } } @@ -301,14 +339,53 @@ void Screen_EoB::setScreenPalette(const Palette &pal) { } } -uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool no4bitEncoding, const uint8 *cgaMapping) { +uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool encode8bit, const uint8 *cgaMapping) { uint8 *shp = 0; uint16 shapesize = 0; - uint8 *srcPage = getPagePtr(_curPage | 1) + y * 320 + (x << 3); - uint8 *src = srcPage; + uint8 *srcLineStart = getPagePtr(_curPage | 1) + y * 320 + (x << 3); + uint8 *src = srcLineStart; + + if (_renderMode == Common::kRenderCGA) { + if (cgaMapping) + generateCGADitheringTables(cgaMapping); + shapesize = h * (w << 2) + 4; + shp = new uint8[shapesize]; + memset(shp, 0, shapesize); + uint8 *dst = shp; + + *dst++ = 4; + *dst++ = (h & 0xff); + *dst++ = (w & 0xff); + *dst++ = (h & 0xff); + + uint8 *dst2 = dst + (h * (w << 1)); + + uint8 tblSwitch = 0; + uint16 h1 = h; + while (h1--) { + uint16 w1 = w << 1; + const uint16 *table = _cgaDitheringTables[(tblSwitch++) & 1]; + + while (w1--) { + uint16 p0 = table[((src[1] & 0x0f) << 4) | (src[0] & 0x0f)]; + uint16 p1 = table[((src[3] & 0x0f) << 4) | (src[2] & 0x0f)]; + + *dst++ = ((p0 & 0x0003) << 6) | ((p0 & 0x0300) >> 4) | ((p1 & 0x0003) << 2) | ((p1 & 0x0300) >> 8); + + uint8 msk = 0; + for (int i = 0; i < 4; i++) { + if (!src[3 - i]) + msk |= (3 << (i << 1)); + } + *dst2++ = msk; + src += 4; + } + srcLineStart += SCREEN_W; + src = srcLineStart; + } - if (no4bitEncoding) { + } else if (encode8bit) { uint16 h1 = h; while (h1--) { uint8 *lineEnd = src + (w << 3); @@ -326,8 +403,8 @@ uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool no4b shapesize++; } while (src != lineEnd); - srcPage += 320; - src = srcPage; + srcLineStart += SCREEN_W; + src = srcLineStart; } shapesize += 4; @@ -336,13 +413,13 @@ uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool no4b memset(shp, 0, shapesize); uint8 *dst = shp; - *dst++ = 0; + *dst++ = 8; *dst++ = (h & 0xff); *dst++ = (w & 0xff); *dst++ = (h & 0xff); - srcPage = getPagePtr(_curPage | 1) + y * 320 + (x << 3); - src = srcPage; + srcLineStart = getPagePtr(_curPage | 1) + y * 320 + (x << 3); + src = srcLineStart; h1 = h; while (h1--) { @@ -367,8 +444,8 @@ uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool no4b *dst++ = val; } while (src != lineEnd); - srcPage += 320; - src = srcPage; + srcLineStart += SCREEN_W; + src = srcLineStart; } } else { @@ -381,17 +458,14 @@ uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool no4b memset(shp, 0, shapesize); uint8 *dst = shp; - *dst++ = 1; + *dst++ = 2; *dst++ = (h & 0xff); *dst++ = (w & 0xff); *dst++ = (h & 0xff); memset(dst, 0xff, 0x10); uint8 *pal = dst; - dst += 0x10; - - srcPage = getPagePtr(_curPage | 1) + y * 320 + (x << 3); - src = srcPage; + dst += 16; nib = col = 0; uint16 h1 = h; @@ -411,14 +485,13 @@ uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool no4b } } - if (++nib & 1) { + if (++nib & 1) *dst = c << 4; - } else { + else *dst++ |= c; - } } - srcPage += 320; - src = srcPage; + srcLineStart += SCREEN_W; + src = srcLineStart; } delete [] colorMap; } @@ -449,10 +522,11 @@ void Screen_EoB::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int16 dX = x - (_dsX1 << 3); int16 dY = y; int16 dW = _dsX2 - _dsX1; - uint8 flag = *src++; + uint8 pixelsPerByte = *src++ ; uint16 dH = *src++; uint16 width = (*src++) << 3; + uint16 transOffset = (pixelsPerByte == 4) ? (dH * width) >> 2 : 0; src++; int rX = x; @@ -465,148 +539,7 @@ void Screen_EoB::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int pixelStep = (flags & 1) ? -1 : 1; - if (flag) { - const uint8 *pal = ovl ? ovl : src; - src += 16; - - if (d < 0) { - d = -d; - if (d >= dH) - return; - src += (d * (width >> 1)); - d = dY + dH - _dsY1; - if (d >= 0) { - dH = d; - dY = _dsY1; - d = _dsY2 - dY; - } - } else { - d = _dsY2 - dY; - } - - if (d < 1) - return; - - if (d < dH) - dH = d; - - int16 cnt1 = 0; - int16 cnt2 = 0; - int16 dXbit1 = dX & 1; - - if (dX < 0) { - width += dX; - d = -dX; - if (flags & 1) - src -= (d >> 1); - else - src += (d >> 1); - - if (d >= w2) - return; - - dX = 0; - cnt1++; - } - - d = (dW << 3) - dX; - - if (d < 1) - return; - - if (d < width) { - width = d; - cnt2++; - } - - dst += (dY * 320 + dX); - - if (pageNum == 0 || pageNum == 1) - addDirtyRect(rX, rY, rW, rH); - - int w3 = w2; - dY = 320 - width; - width >>= 1; - w2 >>= 1; - if (flags & 1) - src += (w2 - 1); - - int16 w1shr = width; - - if (cnt1 && (dXbit1 & 1)) { - w1shr++; - w2++; - if (!cnt2) - dY += 2; - } - - if (cnt2 && (dXbit1 & 1)) - w1shr++; - - int lineSrcStep = (w2 - w1shr); - if (flags & 1) - lineSrcStep = w3 - lineSrcStep; - - while (dH--) { - int16 hpos = width; - uint8 col = 0; - uint8 b = 0; - uint8 nextloop = 0; - - if (cnt1 && dXbit1) { - if (!hpos) - return; - b = *src; - src += pixelStep; - nextloop = 2; - } else { - nextloop = hpos ? 1 : 3; - } - - while (nextloop) { - switch (nextloop) { - case 1: - b = *src; - src += pixelStep; - col = pal[(flags & 1) ? (b & 0x0f) : (b >> 4)]; - if (col) - drawShapeSetPixel(dst, col); - dst++; - - case 2: - col = pal[(flags & 1) ? (b >> 4) : (b & 0x0f)]; - - if (!col) { - nextloop = 4; - break; - } - - drawShapeSetPixel(dst++, col); - nextloop = --hpos ? 1 : 3; - break; - - case 3: - if (cnt2 && dXbit1) { - col = pal[(flags & 1) ? (*src & 0x0f) : (*src >> 4)]; - src += pixelStep; - if (col) - drawShapeSetPixel(dst, col); - dst++; - } - - src += lineSrcStep; - dst += dY; - nextloop = 0; - break; - - case 4: - dst++; - nextloop = --hpos ? 1 : 3; - break; - } - } - } - } else { + if (pixelsPerByte == 8) { uint16 marginLeft = 0; uint16 marginRight = 0; @@ -740,6 +673,127 @@ void Screen_EoB::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, if (flags & 1) src = src2 + 1; } + } else { + const uint8 *pal = 0; + uint8 cgaPal[4]; + memset(cgaPal, 0, 4); + + if (pixelsPerByte == 2) { + pal = ovl ? ovl : src; + src += 16; + } else { + static const uint8 cgaDefOvl[] = { 0x00, 0x55, 0xaa, 0xff }; + pal = ovl ? ovl : cgaDefOvl; + for (int i = 0; i < 4; i++) + cgaPal[i] = pal[i] & 3; + pal = cgaPal; + } + + if (d < 0) { + d = -d; + if (d >= dH) + return; + src += (d * (width / pixelsPerByte)); + d = dY + dH - _dsY1; + if (d >= 0) { + dH = d; + dY = _dsY1; + d = _dsY2 - dY; + } + } else { + d = _dsY2 - dY; + } + + if (d < 1) + return; + + if (d < dH) + dH = d; + + bool trimL = false; + uint8 dXbitAlign = dX & (pixelsPerByte - 1); + + if (dX < 0) { + width += dX; + d = -dX; + if (flags & 1) + src -= (d / pixelsPerByte); + else + src += (d / pixelsPerByte); + + if (d >= w2) + return; + + dX = 0; + trimL = true; + } + + d = (dW << 3) - dX; + + if (d < 1) + return; + + if (d < width) + width = d; + + dst += (dY * 320 + dX); + + if (pageNum == 0 || pageNum == 1) + addDirtyRect(rX, rY, rW, rH); + + int pitch = 320 - width; + int16 lineSrcStep = (w2 - width) / pixelsPerByte; + uint8 lineSrcStepRemainder = (w2 - width) % pixelsPerByte; + + w2 /= pixelsPerByte; + if (flags & 1) + src += (w2 - 1); + + uint8 pixelPacking = 8 / pixelsPerByte; + uint8 pixelPackingMask = 0; + + for (int i = 0; i < pixelPacking; i++) + pixelPackingMask |= (1 << i); + + if (trimL && (dXbitAlign > lineSrcStepRemainder)) + lineSrcStep--; + + uint8 bitShDef = 8 - pixelPacking; + if (flags & 1) { + lineSrcStep = (w2 << 1) - lineSrcStep; + bitShDef = 0; + } + + uint8 bitShLineStart = bitShDef; + if (trimL) + bitShLineStart -= (dXbitAlign * pixelStep * pixelPacking); + + while (dH--) { + int16 wd = width; + uint8 in = 0; + uint8 trans = 0; + uint8 shift = bitShLineStart; + uint8 shSwtch = bitShLineStart; + + while (wd--) { + if (shift == shSwtch) { + in = *src; + trans = src[transOffset]; + src += pixelStep; + shSwtch = bitShDef; + } + if (pixelsPerByte == 2) { + if (pal[(in >> shift) & pixelPackingMask]) + drawShapeSetPixel(dst, pal[(in >> shift) & pixelPackingMask]); + } else { + *dst = (*dst & ((trans >> shift) & (pixelPackingMask))) | pal[(in >> shift) & pixelPackingMask]; + } + dst++; + shift = (shift - (pixelStep * pixelPacking) & 7); + } + src += lineSrcStep; + dst += pitch; + } } } @@ -753,69 +807,75 @@ const uint8 *Screen_EoB::scaleShape(const uint8 *shapeData, int steps) { } const uint8 *Screen_EoB::scaleShapeStep(const uint8 *shp) { - uint8 *d = _dsTempPage; - *d++ = *shp++; + uint8 *dst = (shp != _dsTempPage) ? _dsTempPage : _dsTempPage + 6000; + uint8 *d = dst; + uint8 pixelsPerByte = *d++ = *shp++; + assert (pixelsPerByte > 1); - uint16 h = (*shp++) + 1; + uint16 h = shp[0] + 1; d[0] = d[2] = (h << 1) / 3; - d++; - uint16 w = *shp++; - uint16 w2 = w << 2; + uint16 w = shp[1]; + uint16 w2 = (w << 3) / pixelsPerByte; uint16 t = ((w << 1) % 3) ? 1 : 0; - *d++ = ((w << 1) / 3) + t; - - shp++; - d++; - - int i = 0; - while (i < 16) { - if (!shp[i]) { - i = -i; - break; + d[1] = ((w << 1) / 3) + t; + + uint32 transOffsetSrc = (pixelsPerByte == 4) ? (shp[0] * shp[1]) << 1 : 0; + uint32 transOffsetDst = (pixelsPerByte == 4) ? (d[0] * d[1]) << 1 : 0; + shp += 3; + d += 3; + + if (pixelsPerByte == 2) { + int i = 0; + while (i < 16) { + if (!shp[i]) { + i = -i; + break; + } + i++; } - i++; - } - if (i >= 0) - i = 0; - else - i = -i; + if (i >= 0) + i = 0; + else + i = -i; - _dsScaleTmp = (i << 4) | (i & 0x0f); - for (int ii = 0; ii < 16; ii++) - *d++ = *shp++; + _dsScaleTrans = (i << 4) | (i & 0x0f); + for (int ii = 0; ii < 16; ii++) + *d++ = *shp++; + } _dsDiv = w2 / 3; _dsRem = w2 % 3; while (--h) { - scaleShapeProcessLine(d, shp); + if (pixelsPerByte == 2) + scaleShapeProcessLine4Bit(d, shp); + else + scaleShapeProcessLine2Bit(d, shp, transOffsetDst, transOffsetSrc); if (!--h) break; - scaleShapeProcessLine(d, shp); + if (pixelsPerByte == 2) + scaleShapeProcessLine4Bit(d, shp); + else + scaleShapeProcessLine2Bit(d, shp, transOffsetDst, transOffsetSrc); if (!--h) break; shp += w2; } - return (const uint8 *)_dsTempPage; + return (const uint8*)dst; } -void Screen_EoB::replaceShapePalette(uint8 *shp, const uint8 *pal) { - if (*shp != 1) - return; - shp += 4; - memcpy(shp, pal, 16); -} +const uint8 *Screen_EoB::generateShapeOverlay(const uint8 *shp, int paletteOverlayIndex) { + if (*shp != 2) + return 0; -void Screen_EoB::applyShapeOverlay(uint8 *shp, int ovlIndex) { - if (*shp != 1) - return; shp += 4; - uint8 *ovl = getFadeTable(ovlIndex); + uint8 *ovl = getFadeTable(paletteOverlayIndex); for (int i = 0; i < 16; i++) - shp[i] = ovl[shp[i]]; + _shapeOverlay[i] = ovl[shp[i]]; + return _shapeOverlay; } void Screen_EoB::setShapeFrame(int x1, int y1, int x2, int y2) { @@ -1187,6 +1247,10 @@ uint8 *Screen_EoB::getFadeTable(int index) { return (index >= 0 && index < 5) ? &_fadeData[index << 8] : 0; } +const uint16 *Screen_EoB::getCGADitheringTable(int index) { + return !(index & ~1) ? _cgaDitheringTables[index] : 0; +} + void Screen_EoB::drawShapeSetPixel(uint8 *dst, uint8 c) { if (_shapeFadeMode[0]) { if (_shapeFadeMode[1]) { @@ -1206,7 +1270,35 @@ void Screen_EoB::drawShapeSetPixel(uint8 *dst, uint8 c) { *dst = c; } -void Screen_EoB::scaleShapeProcessLine(uint8 *&dst, const uint8 *&src) { +void Screen_EoB::scaleShapeProcessLine2Bit(uint8 *&shpDst, const uint8 *&shpSrc, uint32 transOffsetDst, uint32 transOffsetSrc) { + for (int i = 0; i < _dsDiv; i++) { + shpDst[0] = (_cgaScaleTable[shpSrc[0]] << 2) | (shpSrc[1] >> 6); + shpDst[1] = ((shpSrc[1] & 0x0f) << 4) | ((shpSrc[2] >> 2) & 0x0f); + shpDst[transOffsetDst] = (_cgaScaleTable[shpSrc[transOffsetSrc]] << 2) | (shpSrc[transOffsetSrc + 1] >> 6); + shpDst[transOffsetDst + 1] = ((shpSrc[transOffsetSrc + 1] & 0x0f) << 4) | ((shpSrc[transOffsetSrc + 2] >> 2) & 0x0f); + shpSrc += 3; + shpDst += 2; + } + + if (_dsRem == 1) { + shpDst[0] = _cgaScaleTable[shpSrc[0]] << 2; + shpDst[1] = 0; + shpDst[transOffsetDst] = (_cgaScaleTable[shpSrc[transOffsetSrc]] << 2) | 3; + shpDst[transOffsetDst + 1] = 0xff; + shpSrc++; + shpDst += 2; + + } else if (_dsRem == 2) { + shpDst[0] = (_cgaScaleTable[shpSrc[0]] << 2) | (shpSrc[1] >> 6); + shpDst[1] = (shpSrc[1] & 0x3f) << 2; + shpDst[transOffsetDst] = (_cgaScaleTable[shpSrc[transOffsetSrc]] << 2) | (shpSrc[transOffsetSrc + 1] >> 6); + shpDst[transOffsetDst + 1] = ((shpSrc[transOffsetSrc + 1] & 0x3f) << 2) | 3; + shpSrc += 2; + shpDst += 2; + } +} + +void Screen_EoB::scaleShapeProcessLine4Bit(uint8 *&dst, const uint8 *&src) { for (int i = 0; i < _dsDiv; i++) { *dst++ = *src++; *dst++ = (READ_BE_UINT16(src) >> 4) & 0xff; @@ -1215,13 +1307,13 @@ void Screen_EoB::scaleShapeProcessLine(uint8 *&dst, const uint8 *&src) { if (_dsRem == 1) { *dst++ = *src++; - *dst++ = _dsScaleTmp; + *dst++ = _dsScaleTrans; } else if (_dsRem == 2) { *dst++ = (src[0] & 0xf0) | (src[1] >> 4); src += 2; - *dst++ = _dsScaleTmp; - *dst++ = _dsScaleTmp; - *dst++ = _dsScaleTmp; + *dst++ = _dsScaleTrans; + *dst++ = _dsScaleTrans; + *dst++ = _dsScaleTrans; } } @@ -1233,8 +1325,8 @@ bool Screen_EoB::posWithinRect(int posX, int posY, int x1, int y1, int x2, int y void Screen_EoB::generateCGADitheringTables(const uint8 *mappingData) { for (int i = 0; i < 256; i++) { - WRITE_BE_UINT16(&_cgaDitheringTables[0][i], (mappingData[i >> 4] << 8) | mappingData[(i & 0x0f) + 16]); - WRITE_BE_UINT16(&_cgaDitheringTables[1][i], (mappingData[(i >> 4) + 16] << 8) | mappingData[i & 0x0f]); + _cgaDitheringTables[0][i] = (mappingData[(i >> 4) + 16] << 8) | mappingData[i & 0x0f]; + _cgaDitheringTables[1][i] = (mappingData[i >> 4] << 8) | mappingData[(i & 0x0f) + 16]; } } @@ -1406,7 +1498,7 @@ void OldDOSFont::drawChar(uint16 c, byte *dst, int pitch) const { uint8 in = s | last; uint16 cmp1 = 0; uint16 cmp2 = 0; - + if (color1) { in &= m; cmp1 = _cgaDitheringTable[in]; @@ -1418,18 +1510,18 @@ void OldDOSFont::drawChar(uint16 c, byte *dst, int pitch) const { } uint16 cDst = 0; - uint8 sh = 14; + uint8 sh = 6; for (int i = 0; i < _width; i++) { cDst |= ((dst[i] & 3) << sh); - sh -= 2; + sh = (sh - 2) & 0x0f; } uint16 out = (~(cmp1 | cmp2) & cDst) | (cmp1 & cgaMask1) | (cmp2 & cgaMask2); - sh = 14; + sh = 6; for (int i = 0; i < _width; i++) { *dst++ = (out >> sh) & 3; - sh -= 2; + sh = (sh - 2) & 0x0f; } last = s; -- cgit v1.2.3 From df9b1bd2e4f70b3d9b2ad35ce806d0da4de253fe Mon Sep 17 00:00:00 2001 From: athrxx Date: Tue, 14 Feb 2012 18:31:33 +0100 Subject: KYRA: (EOB) - implement EGA graphics mode for EOB1 --- engines/kyra/screen_eob.cpp | 110 ++++++++++++++++++++++++-------------------- 1 file changed, 61 insertions(+), 49 deletions(-) (limited to 'engines/kyra/screen_eob.cpp') diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp index 8721c2cc02..51665a00b1 100644 --- a/engines/kyra/screen_eob.cpp +++ b/engines/kyra/screen_eob.cpp @@ -70,6 +70,10 @@ Screen_EoB::~Screen_EoB() { } bool Screen_EoB::init() { + return init(false); +} + +bool Screen_EoB::init(bool useHiResEGADithering) { if (Screen::init()) { int temp; _gfxMaxY = _vm->staticres()->loadRawData(kEoBBaseExpObjectY, temp); @@ -91,6 +95,7 @@ bool Screen_EoB::init() { _dsTempPage = new uint8[12000]; if (_renderMode == Common::kRenderEGA) { + _useHiResEGADithering = useHiResEGADithering; _egaColorMap = new uint8[256]; _egaPixelValueTable = new uint8[256]; for (int i = 0; i < 256; i++) { @@ -98,9 +103,6 @@ bool Screen_EoB::init() { _egaPixelValueTable[i] = i & 0x0f; } - if (_vm->game() == GI_EOB2) - _useHiResEGADithering = true; - } else if (_renderMode == Common::kRenderCGA) { _cgaMappingDefault = _vm->staticres()->loadRawData(kEoB1CgaMappingDefault, temp); _cgaDitheringTables[0] = new uint16[256]; @@ -346,6 +348,9 @@ uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool enco uint8 *srcLineStart = getPagePtr(_curPage | 1) + y * 320 + (x << 3); uint8 *src = srcLineStart; + if (_renderMode == Common::kRenderEGA && !_useHiResEGADithering) + encode8bit = false; + if (_renderMode == Common::kRenderCGA) { if (cgaMapping) generateCGADitheringTables(cgaMapping); @@ -450,8 +455,12 @@ uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool enco } else { uint8 nib = 0, col = 0; - uint8 *colorMap = new uint8[0x100]; - memset(colorMap, 0xff, 0x100); + uint8 *colorMap = 0; + + if (_renderMode != Common::kRenderEGA) { + colorMap = new uint8[0x100]; + memset(colorMap, 0xff, 0x100); + } shapesize = h * (w << 2) + 20; shp = new uint8[shapesize]; @@ -462,7 +471,13 @@ uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool enco *dst++ = (h & 0xff); *dst++ = (w & 0xff); *dst++ = (h & 0xff); - memset(dst, 0xff, 0x10); + + if (_renderMode == Common::kRenderEGA) { + for (int i = 0; i < 16; i++) + dst[i] = i; + } else { + memset(dst, 0xff, 0x10); + } uint8 *pal = dst; dst += 16; @@ -473,15 +488,18 @@ uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool enco uint16 w1 = w << 3; while (w1--) { uint8 s = *src++; - uint8 c = colorMap[s]; - if (c == 0xff) { - if (col < 0x10) { - *pal++ = s; - c = colorMap[s] = col++; - if (!col) + uint8 c = s & 0x0f; + if (colorMap) { + c = colorMap[s]; + if (c == 0xff) { + if (col < 0x10) { + *pal++ = s; + c = colorMap[s] = col++; + if (!col) + c = 0; + } else { c = 0; - } else { - c = 0; + } } } @@ -782,12 +800,9 @@ void Screen_EoB::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, src += pixelStep; shSwtch = bitShDef; } - if (pixelsPerByte == 2) { - if (pal[(in >> shift) & pixelPackingMask]) - drawShapeSetPixel(dst, pal[(in >> shift) & pixelPackingMask]); - } else { - *dst = (*dst & ((trans >> shift) & (pixelPackingMask))) | pal[(in >> shift) & pixelPackingMask]; - } + uint8 col = (pixelsPerByte == 2) ? pal[(in >> shift) & pixelPackingMask] : (*dst & ((trans >> shift) & (pixelPackingMask))) | pal[(in >> shift) & pixelPackingMask]; + if (col || pixelsPerByte == 4) + drawShapeSetPixel(dst, col); dst++; shift = (shift - (pixelStep * pixelPacking) & 7); } @@ -819,11 +834,11 @@ const uint8 *Screen_EoB::scaleShapeStep(const uint8 *shp) { uint16 w2 = (w << 3) / pixelsPerByte; uint16 t = ((w << 1) % 3) ? 1 : 0; d[1] = ((w << 1) / 3) + t; - + uint32 transOffsetSrc = (pixelsPerByte == 4) ? (shp[0] * shp[1]) << 1 : 0; uint32 transOffsetDst = (pixelsPerByte == 4) ? (d[0] * d[1]) << 1 : 0; shp += 3; - d += 3; + d += 3; if (pixelsPerByte == 2) { int i = 0; @@ -1252,19 +1267,21 @@ const uint16 *Screen_EoB::getCGADitheringTable(int index) { } void Screen_EoB::drawShapeSetPixel(uint8 *dst, uint8 c) { - if (_shapeFadeMode[0]) { - if (_shapeFadeMode[1]) { - c = *dst; - } else { - _shapeFadeInternal &= 7; - c = *(dst + _shapeFadeInternal++); + if ((_renderMode != Common::kRenderCGA && _renderMode != Common::kRenderEGA) || _useHiResEGADithering) { + if (_shapeFadeMode[0]) { + if (_shapeFadeMode[1]) { + c = *dst; + } else { + _shapeFadeInternal &= 7; + c = *(dst + _shapeFadeInternal++); + } } - } - if (_shapeFadeMode[1]) { - uint8 cnt = _shapeFadeMode[1]; - while (cnt--) - c = _fadeData[_fadeDataIndex + c]; + if (_shapeFadeMode[1]) { + uint8 cnt = _shapeFadeMode[1]; + while (cnt--) + c = _fadeData[_fadeDataIndex + c]; + } } *dst = c; @@ -1485,6 +1502,11 @@ void OldDOSFont::drawChar(uint16 c, byte *dst, int pitch) const { uint16 cgaMask1 = cgaColorMask[color1 & 3]; uint16 cgaMask2 = cgaColorMask[color2 & 3]; + if (_renderMode == Common::kRenderCGA) { + color1 &= 0x0f; + color2 &= 0x0f; + } + int cH = _height; while (cH--) { int cW = w; @@ -1525,6 +1547,7 @@ void OldDOSFont::drawChar(uint16 c, byte *dst, int pitch) const { } last = s; + } else { for (bool runWidthLoop = true; runWidthLoop;) { uint8 s = *src++; @@ -1536,22 +1559,11 @@ void OldDOSFont::drawChar(uint16 c, byte *dst, int pitch) const { break; } - if (_renderMode == Common::kRenderCGA) { - uint8 in = s | last; - if (s & i) { - if (color1) - *dst = color1; - } else if (color2) { - *dst = color2; - } - last = s; - } else { - if (s & i) { - if (color1) - *dst = color1; - } else if (color2) { - *dst = color2; - } + if (s & i) { + if (color1) + *dst = color1; + } else if (color2) { + *dst = color2; } dst++; } -- cgit v1.2.3 From 66da4777d476c6a9fc2a13351e3b30afc748fd94 Mon Sep 17 00:00:00 2001 From: athrxx Date: Tue, 21 Feb 2012 21:14:28 +0100 Subject: KYRA: (EOB) - implement EGA mode (hi res dithering) for EOB II (also fix various thing connected to CGA/EGA modes) --- engines/kyra/screen_eob.cpp | 384 ++++++++++++++++++++++++++++++++------------ 1 file changed, 281 insertions(+), 103 deletions(-) (limited to 'engines/kyra/screen_eob.cpp') diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp index 51665a00b1..38521d757c 100644 --- a/engines/kyra/screen_eob.cpp +++ b/engines/kyra/screen_eob.cpp @@ -51,7 +51,7 @@ Screen_EoB::Screen_EoB(EoBCoreEngine *vm, OSystem *system) : Screen(vm, system, _dsScaleTrans = 0; _cgaScaleTable = 0; _gfxMaxY = 0; - _egaColorMap = 0; + _egaDitheringTable = 0; _egaPixelValueTable = 0; _cgaMappingDefault = 0; _cgaDitheringTables[0] = _cgaDitheringTables[1] = 0; @@ -62,11 +62,10 @@ Screen_EoB::~Screen_EoB() { delete[] _fadeData; delete[] _dsTempPage; delete[] _cgaScaleTable; - delete[] _egaColorMap; + delete[] _egaDitheringTable; delete[] _egaPixelValueTable; delete[] _cgaDitheringTables[0]; delete[] _cgaDitheringTables[1]; - delete[] _cgaDrawCharDitheringTable; } bool Screen_EoB::init() { @@ -74,6 +73,12 @@ bool Screen_EoB::init() { } bool Screen_EoB::init(bool useHiResEGADithering) { + // Define hi-res pages for EGA mode in EOB II + if (useHiResEGADithering) { + for (int i = 0; i < 8; i++) + _pageScaleFactor[i] = 2; + } + if (Screen::init()) { int temp; _gfxMaxY = _vm->staticres()->loadRawData(kEoBBaseExpObjectY, temp); @@ -96,10 +101,10 @@ bool Screen_EoB::init(bool useHiResEGADithering) { if (_renderMode == Common::kRenderEGA) { _useHiResEGADithering = useHiResEGADithering; - _egaColorMap = new uint8[256]; + _egaDitheringTable = new uint8[256]; _egaPixelValueTable = new uint8[256]; for (int i = 0; i < 256; i++) { - _egaColorMap[i] = i & 0x0f; + _egaDitheringTable[i] = i & 0x0f; _egaPixelValueTable[i] = i & 0x0f; } @@ -110,12 +115,6 @@ bool Screen_EoB::init(bool useHiResEGADithering) { _cgaDitheringTables[1] = new uint16[256]; memset(_cgaDitheringTables[1], 0, 256 * sizeof(uint16)); - _cgaDrawCharDitheringTable = new uint16[256]; - memset(_cgaDrawCharDitheringTable, 0, 256 * sizeof(uint16)); - static const uint bits[] = { 0, 3, 12, 15 }; - for (int i = 0; i < 256; i++) - _cgaDrawCharDitheringTable[i] = (bits[i & 3] << 8) | (bits[(i >> 2) & 3] << 12) | (bits[(i >> 4) & 3] << 0) | (bits[(i >> 6) & 3] << 4); - _cgaScaleTable = new uint8[256]; memset(_cgaScaleTable, 0, 256 * sizeof(uint8)); for (int i = 0; i < 256; i++) @@ -143,13 +142,19 @@ void Screen_EoB::setMouseCursor(int x, int y, const byte *shape) { void Screen_EoB::setMouseCursor(int x, int y, const byte *shape, const uint8 *ovl) { if (!shape) return; - int mouseW = shape[2] << 3; - int mouseH = shape[3]; - uint8 *cursor = new uint8[mouseW * mouseH]; - fillRect(0, 0, mouseW, mouseH, _cursorColorKey, 8); - drawShape(8, shape, 0, 0, 0, 2, ovl); + + int mouseW = (shape[2] << 3); + int mouseH = (shape[3]); + int colorKey = (_renderMode == Common::kRenderCGA) ? 0 : _cursorColorKey; + + uint8 *cursor = new uint8[mouseW * _pageScaleFactor[6] * mouseH * _pageScaleFactor[6]]; + // We use memset and copyBlockToPage instead of fillRect to make sure that the + // color key 0xFF doesn't get converted into EGA color + memset (cursor, colorKey, mouseW * _pageScaleFactor[6] * mouseH * _pageScaleFactor[6]); + copyBlockToPage(6, 0, 0, mouseW, mouseH, cursor); + drawShape(6, shape, 0, 0, 0, 2, ovl); CursorMan.showMouse(false); - copyRegionToBuffer(8, 0, 0, mouseW, mouseH, cursor); + copyRegionToBuffer(6, 0, 0, mouseW, mouseH, cursor); // Mouse cursor post processing for CGA mode. Unlike the original (which uses drawShape for the mouse cursor) // the cursor manager cannot know whether a pixel value of 0 is supposed to be black or transparent. Thus, we @@ -174,7 +179,7 @@ void Screen_EoB::setMouseCursor(int x, int y, const byte *shape, const uint8 *ov } } - CursorMan.replaceCursor(cursor, mouseW, mouseH, x, y, _cursorColorKey); + CursorMan.replaceCursor(cursor, mouseW * _pageScaleFactor[6], mouseH * _pageScaleFactor[6], x, y, colorKey); if (isMouseVisible()) CursorMan.showMouse(true); delete[] cursor; @@ -190,6 +195,19 @@ void Screen_EoB::loadFileDataToPage(Common::SeekableReadStream *s, int pageNum, s->read(_pagePtrs[pageNum], size); } +void Screen_EoB::printText(const char *str, int x, int y, uint8 color1, uint8 color2) { + if (_useHiResEGADithering) { + // This is sort of an abuse of the text color map. But since EOB doesn't use it anyway + // and the font drawing code needs access to both the original color values and the + // EGA dithering colors we pass them on like this. + uint8 cmap[2]; + cmap[0] = _egaDitheringTable[color2]; + cmap[1] = _egaDitheringTable[color1]; + setTextColor(cmap, 2, 3); + } + Screen::printText(str, x, y, color1, color2); +} + void Screen_EoB::printShadedText(const char *string, int x, int y, int col1, int col2) { printText(string, x - 1, y, 12, col2); printText(string, x, y + 1, 12, 0); @@ -256,87 +274,153 @@ void Screen_EoB::convertPage(int srcPage, int dstPage, const uint8 *cgaMapping) if (_renderMode == Common::kRenderCGA) { if (cgaMapping) generateCGADitheringTables(cgaMapping); + uint16 *d = (uint16*)dst; uint8 tblSwitch = 0; for (int height = SCREEN_H; height; height--) { const uint16 *table = _cgaDitheringTables[(tblSwitch++) & 1]; for (int width = SCREEN_W / 2; width; width--) { - *d++ = table[((src[1] & 0x0f) << 4) | (src[0] & 0x0f)]; + WRITE_LE_UINT16(d++, table[((src[1] & 0x0f) << 4) | (src[0] & 0x0f)]); src += 2; } } - if (dstPage == 0 || dstPage == 1) - _forceFullUpdate = true; + } else if (_useHiResEGADithering) { + for (int height = SCREEN_H; height; height--) { + uint8 *dst2 = dst + SCREEN_W * 2; + for (int width = SCREEN_W; width; width--) { + uint8 in = _egaDitheringTable[*src++]; + *dst++ = *dst2++ = in >> 4; + *dst++ = *dst2++ = in & 0x0f; + } + dst += (SCREEN_W * 2); + } } else if (_renderMode == Common::kRenderEGA) { uint32 len = SCREEN_W * SCREEN_H; - if (_useHiResEGADithering) { - while (len--) { - uint8 col = _egaColorMap[*src++] & 0x0f; - *dst++ = col; + while (len--) + *dst++ = *src++ & 0x0f; + + } else { + copyPage(srcPage, dstPage); + } - /*for (int i = 4; i; i--) { - uint8 col = _egaColorMap[*src++]; + if (dstPage == 0 || dstPage == 1) + _forceFullUpdate = true; +} - }*/ - } - } else { - while (len--) - *dst++ = *src++ & 0x0f; +void Screen_EoB::fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum, bool xored) { + if (!_useHiResEGADithering) { + Screen::fillRect(x1, y1, x2, y2, color, pageNum, xored); + return; + } + + assert(x2 < SCREEN_W && y2 < SCREEN_H); + if (pageNum == -1) + pageNum = _curPage; + + uint16 pitch = (SCREEN_W - (x2 - x1 + 1)) * _pageScaleFactor[pageNum]; + uint8 col1 = (_egaDitheringTable[color] >> 4); + uint8 col2 = (_egaDitheringTable[color] & 0x0f); + + x1 *= _pageScaleFactor[pageNum]; + y1 *= _pageScaleFactor[pageNum]; + x2 *= _pageScaleFactor[pageNum]; + y2 *= _pageScaleFactor[pageNum]; + uint16 w = x2 - x1 + _pageScaleFactor[pageNum]; + uint16 h = y2 - y1 + _pageScaleFactor[pageNum]; + + uint8 *dst = getPagePtr(pageNum) + y1 * SCREEN_W * _pageScaleFactor[pageNum] + x1; + if (pageNum == 0 || pageNum == 1) + addDirtyRect(x1, y1, w, h); + + while (h--) { + for (uint16 w1 = w; w1; w1 -= 2) { + *dst++ = col1; + *dst++ = col2; } + dst += pitch; + } +} - if (dstPage == 0 || dstPage == 1) - _forceFullUpdate = true; +void Screen_EoB::drawLine(bool vertical, int x, int y, int length, int color) { + if (!_useHiResEGADithering) { + Screen::drawLine(vertical, x, y, length, color); + return; + } + + uint16 pitch = (SCREEN_W - 1) * _pageScaleFactor[_curPage]; + uint8 col1 = (_egaDitheringTable[color] >> 4); + uint8 col2 = (_egaDitheringTable[color] & 0x0f); + + x *= _pageScaleFactor[_curPage]; + y *= _pageScaleFactor[_curPage]; + length *= _pageScaleFactor[_curPage]; + uint8 *ptr = getPagePtr(_curPage) + y * SCREEN_W * _pageScaleFactor[_curPage] + x; + uint8 *ptr2 = ptr + SCREEN_W * _pageScaleFactor[_curPage]; + + if (vertical) { + assert((y + length) <= SCREEN_H * _pageScaleFactor[_curPage]); + int currLine = 0; + while (currLine < length) { + *ptr++ = col1; + *ptr++ = col2; + ptr += pitch; + currLine++; + } } else { - copyPage(srcPage, dstPage); + assert((x + length) <= SCREEN_W * _pageScaleFactor[_curPage]); + int currLine = 0; + while (currLine < length) { + *ptr++ = *ptr2++ = col1; + *ptr++ = *ptr2++ = col2; + currLine += 2; + } } + + if (_curPage == 0 || _curPage == 1) + addDirtyRect(x, y, (vertical) ? _pageScaleFactor[_curPage] : length, (vertical) ? length : _pageScaleFactor[_curPage]); } -void Screen_EoB::setScreenPalette(const Palette &pal) { - if (_renderMode == Common::kRenderEGA && _egaColorMap && pal.getNumColors() != 16) { - const uint8 *src = pal.getData(); - uint8 *dst = _egaColorMap; - - for (int i = 256; i; i--) { - uint8 r = *src++; - uint8 g = *src++; - uint8 b = *src++; - - uint8 col = 0; - uint16 min = 11907; - - for (int ii = 256; ii; ii--) { - const uint8 *palEntry = _egaMatchTable + (ii - 1) * 3; - if (*palEntry == 0xff) - continue; - - int e_r = palEntry[0]; - e_r -= r; - int e_g = palEntry[1]; - e_g -= g; - int e_b = palEntry[2]; - e_b -= b; - - int s = (e_r * e_r) + (e_g * e_g) + (e_b * e_b); - - if (s < min) { - min = s; - col = ii - 1; - } - } - *dst++ = col; - } +uint8 Screen_EoB::getPagePixel(int pageNum, int x, int y) { + if (!_useHiResEGADithering) + return Screen::getPagePixel(pageNum, x, y); - memset(_egaPixelValueTable, 0, 256); - for (int i = 0; i < 256; i++) - _egaPixelValueTable[_egaColorMap[i]] = i; + x *= _pageScaleFactor[_curPage]; + y *= _pageScaleFactor[_curPage]; + uint8 *pos = &_pagePtrs[pageNum][y * SCREEN_W * _pageScaleFactor[_curPage] + x]; - } else if (_renderMode == Common::kRenderEGA) { + return _egaPixelValueTable[(pos[0] << 4) | (pos[1] & 0x0f)]; +} + +void Screen_EoB::setPagePixel(int pageNum, int x, int y, uint8 color) { + if (!_useHiResEGADithering) { + Screen::setPagePixel(pageNum, x, y, color); + return; + } + + assert(pageNum < SCREEN_PAGE_NUM); + assert(x >= 0 && x < SCREEN_W && y >= 0 && y < SCREEN_H); + + x *= _pageScaleFactor[_curPage]; + y *= _pageScaleFactor[_curPage]; + + if (pageNum == 0 || pageNum == 1) + addDirtyRect(x, y, _pageScaleFactor[pageNum], _pageScaleFactor[pageNum]); + + uint8 *pos = &_pagePtrs[pageNum][y * SCREEN_W * _pageScaleFactor[_curPage] + x]; + uint8 *pos2 = pos + SCREEN_W * _pageScaleFactor[_curPage]; + pos[0] = pos2[0] = _egaDitheringTable[color] >> 4; + pos[1] = pos2[1] = _egaDitheringTable[color] & 0x0f; +} + +void Screen_EoB::setScreenPalette(const Palette &pal) { + if (_useHiResEGADithering && pal.getNumColors() != 16) { + generateEGADitheringTable(pal); + } else if (_renderMode == Common::kRenderEGA && pal.getNumColors() == 16) { _screenPalette->copy(pal); _system->getPaletteManager()->setPalette(_screenPalette->getData(), 0, _screenPalette->getNumColors()); - - } else if (_renderMode != Common::kRenderCGA) { + } else if (_renderMode != Common::kRenderCGA && _renderMode != Common::kRenderEGA) { Screen::setScreenPalette(pal); } } @@ -457,7 +541,7 @@ uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool enco uint8 nib = 0, col = 0; uint8 *colorMap = 0; - if (_renderMode != Common::kRenderEGA) { + if (_renderMode != Common::kRenderEGA || _useHiResEGADithering) { colorMap = new uint8[0x100]; memset(colorMap, 0xff, 0x100); } @@ -472,7 +556,7 @@ uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool enco *dst++ = (w & 0xff); *dst++ = (h & 0xff); - if (_renderMode == Common::kRenderEGA) { + if (_renderMode == Common::kRenderEGA && !_useHiResEGADithering) { for (int i = 0; i < 16; i++) dst[i] = i; } else { @@ -536,7 +620,7 @@ void Screen_EoB::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, y += _dsY1; } - dst += (_dsX1 << 3); + dst += (_dsX1 << 3) * _pageScaleFactor[pageNum]; int16 dX = x - (_dsX1 << 3); int16 dY = y; int16 dW = _dsX2 - _dsX1; @@ -608,11 +692,11 @@ void Screen_EoB::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, marginRight = w2 - marginLeft - width; } - dst += (dY * 320 + dX); + dst += (dY * SCREEN_W * _pageScaleFactor[pageNum] * _pageScaleFactor[pageNum] + dX * _pageScaleFactor[pageNum]); uint8 *dstL = dst; if (pageNum == 0 || pageNum == 1) - addDirtyRect(rX, rY, rW, rH); + addDirtyRect(rX * _pageScaleFactor[pageNum], rY * _pageScaleFactor[pageNum], rW * _pageScaleFactor[pageNum], rH * _pageScaleFactor[pageNum]); while (dH--) { int16 xpos = (int16) marginLeft; @@ -647,7 +731,7 @@ void Screen_EoB::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, } while (xpos > 0); } - dst -= xpos; + dst -= (xpos * _pageScaleFactor[pageNum]); xpos += width; while (xpos > 0) { @@ -656,11 +740,12 @@ void Screen_EoB::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, src += pixelStep; if (m) { - drawShapeSetPixel(dst++, c); + drawShapeSetPixel(dst, c, SCREEN_W * _pageScaleFactor[pageNum]); + dst += _pageScaleFactor[pageNum]; xpos--; } else { uint8 len = (flags & 1) ? src[1] : src[0]; - dst += len; + dst += (len * _pageScaleFactor[pageNum]); xpos -= len; src += pixelStep; } @@ -686,7 +771,7 @@ void Screen_EoB::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, } while (xpos > 0); } - dstL += 320; + dstL += SCREEN_W * _pageScaleFactor[pageNum] * _pageScaleFactor[pageNum]; dst = dstL; if (flags & 1) src = src2 + 1; @@ -754,12 +839,12 @@ void Screen_EoB::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, if (d < width) width = d; - dst += (dY * 320 + dX); + dst += (dY * _pageScaleFactor[pageNum] * SCREEN_W * _pageScaleFactor[pageNum] + dX * _pageScaleFactor[pageNum]); if (pageNum == 0 || pageNum == 1) - addDirtyRect(rX, rY, rW, rH); + addDirtyRect(rX * _pageScaleFactor[pageNum], rY * _pageScaleFactor[pageNum], rW * _pageScaleFactor[pageNum], rH * _pageScaleFactor[pageNum]); - int pitch = 320 - width; + int pitch = SCREEN_W * _pageScaleFactor[pageNum] * _pageScaleFactor[pageNum] - width * _pageScaleFactor[pageNum]; int16 lineSrcStep = (w2 - width) / pixelsPerByte; uint8 lineSrcStepRemainder = (w2 - width) % pixelsPerByte; @@ -802,9 +887,9 @@ void Screen_EoB::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, } uint8 col = (pixelsPerByte == 2) ? pal[(in >> shift) & pixelPackingMask] : (*dst & ((trans >> shift) & (pixelPackingMask))) | pal[(in >> shift) & pixelPackingMask]; if (col || pixelsPerByte == 4) - drawShapeSetPixel(dst, col); - dst++; - shift = (shift - (pixelStep * pixelPacking) & 7); + drawShapeSetPixel(dst, col, SCREEN_W * _pageScaleFactor[pageNum]); + dst += _pageScaleFactor[pageNum]; + shift = ((shift - (pixelStep * pixelPacking)) & 7); } src += lineSrcStep; dst += pitch; @@ -1266,25 +1351,36 @@ const uint16 *Screen_EoB::getCGADitheringTable(int index) { return !(index & ~1) ? _cgaDitheringTables[index] : 0; } -void Screen_EoB::drawShapeSetPixel(uint8 *dst, uint8 c) { +const uint8 *Screen_EoB::getEGADitheringTable() { + return _egaDitheringTable; +} + +void Screen_EoB::drawShapeSetPixel(uint8 *dst, uint8 col, uint16 pitch) { if ((_renderMode != Common::kRenderCGA && _renderMode != Common::kRenderEGA) || _useHiResEGADithering) { if (_shapeFadeMode[0]) { if (_shapeFadeMode[1]) { - c = *dst; + col = _useHiResEGADithering ? _egaPixelValueTable[(dst[0] << 4) | (dst[1] & 0x0f)] : *dst; } else { _shapeFadeInternal &= 7; - c = *(dst + _shapeFadeInternal++); + col = _useHiResEGADithering ? _egaPixelValueTable[(dst[_shapeFadeInternal] << 4) | (dst[_shapeFadeInternal + 1] & 0x0f)] : dst[_shapeFadeInternal]; + _shapeFadeInternal++; } } if (_shapeFadeMode[1]) { uint8 cnt = _shapeFadeMode[1]; while (cnt--) - c = _fadeData[_fadeDataIndex + c]; + col = _fadeData[_fadeDataIndex + col]; } } - *dst = c; + if (_useHiResEGADithering) { + col = _egaDitheringTable[col]; + dst[0] = dst[pitch] = col >> 4; + dst[1] = dst[pitch + 1] = col & 0x0f; + } else { + *dst = col; + } } void Screen_EoB::scaleShapeProcessLine2Bit(uint8 *&shpDst, const uint8 *&shpSrc, uint32 transOffsetDst, uint32 transOffsetSrc) { @@ -1340,6 +1436,43 @@ bool Screen_EoB::posWithinRect(int posX, int posY, int x1, int y1, int x2, int y return true; } +void Screen_EoB::generateEGADitheringTable(const Palette &pal) { + assert(_egaDitheringTable); + const uint8 *src = pal.getData(); + uint8 *dst = _egaDitheringTable; + + for (int i = 256; i; i--) { + int r = *src++; + int g = *src++; + int b = *src++; + + uint8 col = 0; + uint16 min = 0x2E83; + + for (int ii = 256; ii; ii--) { + const uint8 *palEntry = _egaMatchTable + (ii - 1) * 3; + if (*palEntry == 0xff) + continue; + + int e_r = palEntry[0] - r; + int e_g = palEntry[1] - g; + int e_b = palEntry[2] - b; + + uint16 s = (e_r * e_r) + (e_g * e_g) + (e_b * e_b); + + if (s <= min) { + min = s; + col = ii - 1; + } + } + *dst++ = col; + } + + memset(_egaPixelValueTable, 0, 256); + for (int i = 0; i < 256; i++) + _egaPixelValueTable[_egaDitheringTable[i]] = i; +} + void Screen_EoB::generateCGADitheringTables(const uint8 *mappingData) { for (int i = 0; i < 256; i++) { _cgaDitheringTables[0][i] = (mappingData[(i >> 4) + 16] << 8) | mappingData[i & 0x0f]; @@ -1398,14 +1531,34 @@ const uint8 Screen_EoB::_egaMatchTable[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x3F, 0x3F }; -OldDOSFont::OldDOSFont(Common::RenderMode mode, const uint16 *cgaDitheringTable) : _renderMode(mode), _cgaDitheringTable(cgaDitheringTable) { +uint16 *OldDOSFont::_cgaDitheringTable = 0; +int OldDOSFont::_numRef = 0; + +OldDOSFont::OldDOSFont(Common::RenderMode mode, bool useHiResEGADithering) : _renderMode(mode), _useHiResEGADithering(useHiResEGADithering) { _data = 0; _width = _height = _numGlyphs = 0; _bitmapOffsets = 0; + + _numRef++; + if (!_cgaDitheringTable && _numRef == 1) { + _cgaDitheringTable = new uint16[256]; + memset(_cgaDitheringTable, 0, 256 * sizeof(uint16)); + static const uint bits[] = { 0, 3, 12, 15 }; + for (int i = 0; i < 256; i++) + _cgaDitheringTable[i] = (bits[i & 3] << 8) | (bits[(i >> 2) & 3] << 12) | (bits[(i >> 4) & 3] << 0) | (bits[(i >> 6) & 3] << 4); + } } OldDOSFont::~OldDOSFont() { unload(); + + if (_numRef) + --_numRef; + + if (_cgaDitheringTable && !_numRef) { + delete[] _cgaDitheringTable; + _cgaDitheringTable = 0; + } } bool OldDOSFont::load(Common::SeekableReadStream &file) { @@ -1491,18 +1644,27 @@ void OldDOSFont::drawChar(uint16 c, byte *dst, int pitch) const { } const uint8 *src = &_data[_bitmapOffsets[c]]; + uint8 *dst2 = dst + pitch; int w = (_width - 1) >> 3; pitch -= _width; + if (_useHiResEGADithering) + pitch *= 2; + uint8 color1 = _colorMap[1]; uint8 color2 = _colorMap[0]; + uint8 colEGA11 = _colorMap[3] >> 4; + uint8 colEGA12 = _colorMap[3] & 0x0f; + uint8 colEGA21 = _colorMap[2] >> 4; + uint8 colEGA22 = _colorMap[2] & 0x0f; + static const uint16 cgaColorMask[] = { 0, 0x5555, 0xAAAA, 0xFFFF }; uint16 cgaMask1 = cgaColorMask[color1 & 3]; uint16 cgaMask2 = cgaColorMask[color2 & 3]; - if (_renderMode == Common::kRenderCGA) { + if (_renderMode == Common::kRenderCGA || (_renderMode == Common::kRenderEGA && !_useHiResEGADithering)) { color1 &= 0x0f; color2 &= 0x0f; } @@ -1559,13 +1721,27 @@ void OldDOSFont::drawChar(uint16 c, byte *dst, int pitch) const { break; } - if (s & i) { - if (color1) - *dst = color1; - } else if (color2) { - *dst = color2; + if (_useHiResEGADithering) { + if (s & i) { + if (color1) { + dst[0] = dst2[0] = colEGA11; + dst[1] = dst2[1] = colEGA12; + } + } else if (color2) { + dst[0] = dst2[0] = colEGA21; + dst[1] = dst2[1] = colEGA22; + } + dst += 2; + dst2 += 2; + } else { + if (s & i) { + if (color1) + *dst = color1; + } else if (color2) { + *dst = color2; + } + dst++; } - dst++; } if (cW) @@ -1574,7 +1750,9 @@ void OldDOSFont::drawChar(uint16 c, byte *dst, int pitch) const { runWidthLoop = false; } } + dst += pitch; + dst2 += pitch; } } -- cgit v1.2.3 From ecd1a9f9435c5fc5d502d75dd256394b5f3283f3 Mon Sep 17 00:00:00 2001 From: athrxx Date: Thu, 23 Feb 2012 21:36:14 +0100 Subject: KYRA: (EOB) - cleanup CGA/EGA code a bit --- engines/kyra/screen_eob.cpp | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'engines/kyra/screen_eob.cpp') diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp index 38521d757c..dc53e8aca5 100644 --- a/engines/kyra/screen_eob.cpp +++ b/engines/kyra/screen_eob.cpp @@ -55,7 +55,7 @@ Screen_EoB::Screen_EoB(EoBCoreEngine *vm, OSystem *system) : Screen(vm, system, _egaPixelValueTable = 0; _cgaMappingDefault = 0; _cgaDitheringTables[0] = _cgaDitheringTables[1] = 0; - _useHiResEGADithering = false; + _useLoResEGA = _useHiResEGADithering = false; } Screen_EoB::~Screen_EoB() { @@ -69,12 +69,8 @@ Screen_EoB::~Screen_EoB() { } bool Screen_EoB::init() { - return init(false); -} - -bool Screen_EoB::init(bool useHiResEGADithering) { // Define hi-res pages for EGA mode in EOB II - if (useHiResEGADithering) { + if (_vm->gameFlags().useHiRes) { for (int i = 0; i < 8; i++) _pageScaleFactor[i] = 2; } @@ -99,15 +95,16 @@ bool Screen_EoB::init(bool useHiResEGADithering) { _dsTempPage = new uint8[12000]; - if (_renderMode == Common::kRenderEGA) { - _useHiResEGADithering = useHiResEGADithering; + if (_vm->gameFlags().useHiRes && _renderMode == Common::kRenderEGA) { + _useHiResEGADithering = true; _egaDitheringTable = new uint8[256]; _egaPixelValueTable = new uint8[256]; for (int i = 0; i < 256; i++) { _egaDitheringTable[i] = i & 0x0f; _egaPixelValueTable[i] = i & 0x0f; } - + } else if (_renderMode == Common::kRenderEGA) { + _useLoResEGA = true; } else if (_renderMode == Common::kRenderCGA) { _cgaMappingDefault = _vm->staticres()->loadRawData(kEoB1CgaMappingDefault, temp); _cgaDitheringTables[0] = new uint16[256]; @@ -432,7 +429,7 @@ uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool enco uint8 *srcLineStart = getPagePtr(_curPage | 1) + y * 320 + (x << 3); uint8 *src = srcLineStart; - if (_renderMode == Common::kRenderEGA && !_useHiResEGADithering) + if (_useLoResEGA) encode8bit = false; if (_renderMode == Common::kRenderCGA) { @@ -556,7 +553,7 @@ uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool enco *dst++ = (w & 0xff); *dst++ = (h & 0xff); - if (_renderMode == Common::kRenderEGA && !_useHiResEGADithering) { + if (_useLoResEGA) { for (int i = 0; i < 16; i++) dst[i] = i; } else { @@ -1538,6 +1535,7 @@ OldDOSFont::OldDOSFont(Common::RenderMode mode, bool useHiResEGADithering) : _re _data = 0; _width = _height = _numGlyphs = 0; _bitmapOffsets = 0; + _useLoResEGA = (_renderMode == Common::kRenderEGA && !_useHiResEGADithering); _numRef++; if (!_cgaDitheringTable && _numRef == 1) { @@ -1664,7 +1662,7 @@ void OldDOSFont::drawChar(uint16 c, byte *dst, int pitch) const { uint16 cgaMask1 = cgaColorMask[color1 & 3]; uint16 cgaMask2 = cgaColorMask[color2 & 3]; - if (_renderMode == Common::kRenderCGA || (_renderMode == Common::kRenderEGA && !_useHiResEGADithering)) { + if (_renderMode == Common::kRenderCGA || _useLoResEGA) { color1 &= 0x0f; color2 &= 0x0f; } -- cgit v1.2.3 From 30fa5e166379b9e0764b437c6925c22d908d7122 Mon Sep 17 00:00:00 2001 From: athrxx Date: Fri, 24 Feb 2012 15:48:06 +0100 Subject: KYRA: (EOB) - fix save file thumbnail generation in CGA/EGA mode --- engines/kyra/screen_eob.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'engines/kyra/screen_eob.cpp') diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp index dc53e8aca5..9fae729bc4 100644 --- a/engines/kyra/screen_eob.cpp +++ b/engines/kyra/screen_eob.cpp @@ -422,6 +422,21 @@ void Screen_EoB::setScreenPalette(const Palette &pal) { } } +void Screen_EoB::getRealPalette(int num, uint8 *dst) { + if (_renderMode == Common::kRenderCGA || _renderMode == Common::kRenderEGA) { + const uint8 *pal = _screenPalette->getData(); + for (int i = 0; i < 16; ++i) { + dst[0] = (pal[0] << 2) | (pal[0] & 3); + dst[1] = (pal[1] << 2) | (pal[1] & 3); + dst[2] = (pal[2] << 2) | (pal[2] & 3); + dst += 3; + pal += 3; + } + } else { + Screen::getRealPalette(num, dst); + } +} + uint8 *Screen_EoB::encodeShape(uint16 x, uint16 y, uint16 w, uint16 h, bool encode8bit, const uint8 *cgaMapping) { uint8 *shp = 0; uint16 shapesize = 0; -- cgit v1.2.3 From 9671b44df8ecd1db46758508b1303d8ab3f515dd Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Mon, 5 Mar 2012 20:02:05 +0100 Subject: KYRA: Some formatting fixes. --- engines/kyra/screen_eob.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/kyra/screen_eob.cpp') diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp index 9fae729bc4..e06ca42c40 100644 --- a/engines/kyra/screen_eob.cpp +++ b/engines/kyra/screen_eob.cpp @@ -147,7 +147,7 @@ void Screen_EoB::setMouseCursor(int x, int y, const byte *shape, const uint8 *ov uint8 *cursor = new uint8[mouseW * _pageScaleFactor[6] * mouseH * _pageScaleFactor[6]]; // We use memset and copyBlockToPage instead of fillRect to make sure that the // color key 0xFF doesn't get converted into EGA color - memset (cursor, colorKey, mouseW * _pageScaleFactor[6] * mouseH * _pageScaleFactor[6]); + memset(cursor, colorKey, mouseW * _pageScaleFactor[6] * mouseH * _pageScaleFactor[6]); copyBlockToPage(6, 0, 0, mouseW, mouseH, cursor); drawShape(6, shape, 0, 0, 0, 2, ovl); CursorMan.showMouse(false); -- cgit v1.2.3