2011-12-11 01:57:03 +01:00
|
|
|
|
/* ScummVM - Graphic Adventure Engine
|
|
|
|
|
*
|
|
|
|
|
* ScummVM is the legal property of its developers, whose names
|
|
|
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
|
|
|
* file distributed with this source distribution.
|
|
|
|
|
*
|
|
|
|
|
* 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;
|
2011-11-06 17:02:52 +01:00
|
|
|
|
_gfxX = _gfxY = 0;
|
|
|
|
|
_gfxCol = 0;
|
2011-12-11 01:57:03 +01:00
|
|
|
|
_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);
|
|
|
|
|
|
2011-11-06 17:02:52 +01:00
|
|
|
|
int temp;
|
|
|
|
|
_gfxMaxY = _vm->staticres()->loadRawData(kEobBaseExpObjectY, temp);
|
2011-12-11 01:57:03 +01:00
|
|
|
|
_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) {
|
2011-06-22 01:08:28 +02:00
|
|
|
|
if (!_customDimTable[dim])
|
|
|
|
|
_customDimTable[dim] = new ScreenDim;
|
|
|
|
|
|
2011-12-11 01:57:03 +01:00
|
|
|
|
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) {
|
2011-06-09 23:59:11 +02:00
|
|
|
|
Common::String tmp = Common::String::format("%s.CPS", file);
|
2011-12-11 01:57:03 +01:00
|
|
|
|
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())
|
2011-06-09 23:59:11 +02:00
|
|
|
|
loadBitmap(tmp.c_str(), tempPage, destPage, 0);
|
2011-12-11 01:57:03 +01:00
|
|
|
|
else
|
|
|
|
|
loadAlternative = true;
|
|
|
|
|
|
|
|
|
|
delete s;
|
|
|
|
|
} else {
|
|
|
|
|
loadAlternative = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (loadAlternative) {
|
2011-06-09 23:59:11 +02:00
|
|
|
|
tmp.setChar('X', 0);
|
2011-12-11 01:57:03 +01:00
|
|
|
|
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)
|
2011-06-16 18:51:47 +02:00
|
|
|
|
marginLeft = marginLeft + 1 - *src++;
|
2011-12-11 01:57:03 +01:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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]];
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-06 17:02:52 +01:00
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
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;
|
2011-12-11 01:57:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
2011-11-06 17:02:52 +01:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-12-11 01:57:03 +01:00
|
|
|
|
|
2011-11-06 17:02:52 +01:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-12-11 01:57:03 +01:00
|
|
|
|
}
|
2011-11-06 17:02:52 +01:00
|
|
|
|
|
|
|
|
|
showMouse();
|
2011-12-11 01:57:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-06 17:02:52 +01:00
|
|
|
|
int Screen_Eob::getRectSize(int w, int h) {
|
|
|
|
|
return w * h;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Screen_Eob::setFadeTableIndex(int index) {
|
|
|
|
|
_fadeDataIndex = (CLIP(index, 0, 7) << 8);
|
|
|
|
|
}
|
|
|
|
|
|
2011-12-11 01:57:03 +01:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-06 17:02:52 +01:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2011-12-11 01:57:03 +01:00
|
|
|
|
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 '<27>' ?
|
|
|
|
|
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
|