mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-03 17:33:05 +00:00
Add patch from Tobias, for masking support in PCE version of Loom, with minor changes.
svn-id: r45387
This commit is contained in:
parent
cac32b61ce
commit
6b61700a7b
@ -595,10 +595,11 @@ void ClassicCostumeRenderer::procPCEngine(Codec1 &v1) {
|
||||
const byte *mask, *src;
|
||||
byte *dst;
|
||||
byte maskbit;
|
||||
uint width, height;
|
||||
byte scaleIndexY;
|
||||
int xPos, yPos;
|
||||
uint color, width, height; //, pcolor;
|
||||
bool masked;
|
||||
int vertShift;
|
||||
|
||||
int xStep;
|
||||
byte block[16][16];
|
||||
|
||||
src = _srcptr;
|
||||
@ -608,19 +609,17 @@ void ClassicCostumeRenderer::procPCEngine(Codec1 &v1) {
|
||||
if (_numBlocks == 0)
|
||||
return;
|
||||
|
||||
scaleIndexY = _scaleIndexY;
|
||||
maskbit = revBitMask(v1.x & 7);
|
||||
mask = v1.mask_ptr + v1.x / 8;
|
||||
xStep = _mirror ? +1 : -1;
|
||||
|
||||
for (uint x = 0; x < width; ++x) {
|
||||
dst = v1.destptr + 16 * x * _out.bytesPerPixel;
|
||||
yPos = 0;
|
||||
for (uint y = 0; y < height; ++y) {
|
||||
vertShift = *src++;
|
||||
if (vertShift == 0xFF) {
|
||||
dst += 16 * _out.pitch;
|
||||
yPos += 16;
|
||||
continue;
|
||||
} else {
|
||||
dst += vertShift * _out.pitch;
|
||||
yPos += vertShift;
|
||||
}
|
||||
|
||||
memset(block, 0, sizeof(block));
|
||||
@ -646,18 +645,24 @@ void ClassicCostumeRenderer::procPCEngine(Codec1 &v1) {
|
||||
}
|
||||
|
||||
for (int row = 0; row < 16; ++row) {
|
||||
xPos = xStep * x * 16;
|
||||
for (int col = 0; col < 16; ++col) {
|
||||
int color = block[row][col];
|
||||
if (color != 0) {
|
||||
if (dst < v1.destptr + _out.w * _out.h * _out.bytesPerPixel) {
|
||||
if (_mirror)
|
||||
dst[col] = color;
|
||||
else
|
||||
dst[-col] = color;
|
||||
}
|
||||
dst = v1.destptr + yPos * _out.pitch + xPos;
|
||||
mask = v1.mask_ptr + yPos * _numStrips + (v1.x + xPos) / 8;
|
||||
maskbit = revBitMask((v1.x + xPos) % 8);
|
||||
|
||||
color = block[row][col];
|
||||
masked = (v1.y + yPos < 0 || v1.y + yPos >= _out.h) ||
|
||||
(v1.x + xPos < 0 || v1.x + xPos >= _out.w) ||
|
||||
(v1.mask_ptr && (mask[0] & maskbit));
|
||||
|
||||
if (color && !masked) {
|
||||
*dst = color;
|
||||
}
|
||||
|
||||
xPos += xStep;
|
||||
}
|
||||
dst += _out.pitch;
|
||||
yPos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -825,54 +830,10 @@ byte NESCostumeRenderer::drawLimb(const Actor *a, int limb) {
|
||||
|
||||
#define PCE_SIGNED(a) (((a) & 0x80) ? -((a) & 0x7F) : (a))
|
||||
|
||||
byte PCEngineCostumeRenderer::drawLimb(const Actor *a, int limb) {
|
||||
int i;
|
||||
int code;
|
||||
const byte *frameptr, *offset;
|
||||
const CostumeData &cost = a->_cost;
|
||||
|
||||
// If the specified limb is stopped or not existing, do nothing.
|
||||
if (cost.curpos[limb] == 0xFFFF || cost.stopped & (1 << limb))
|
||||
return 0;
|
||||
|
||||
// Determine the position the limb is at
|
||||
i = cost.curpos[limb] & 0x7FFF;
|
||||
|
||||
// Get the frame pointer for that limb
|
||||
offset = _loaded._frameOffsets + limb * 2;
|
||||
frameptr = READ_LE_UINT16(offset) + offset + 2;
|
||||
|
||||
// Determine the offset to the costume data for the limb at position i
|
||||
code = _loaded._animCmds[i] & 0x7F;
|
||||
|
||||
// Code 0x7B indicates a limb for which there is nothing to draw
|
||||
if (code != 0x7B) {
|
||||
offset = frameptr + code * 2;
|
||||
_srcptr = READ_LE_UINT16(offset) + offset + 2;
|
||||
|
||||
if (code < 0x79) {
|
||||
int xmoveCur, ymoveCur;
|
||||
|
||||
_numBlocks = _srcptr[0];
|
||||
_width = _srcptr[1] * 16;
|
||||
_height = _srcptr[2] * 16;
|
||||
xmoveCur = _xmove + PCE_SIGNED(_srcptr[3]);
|
||||
ymoveCur = _ymove + PCE_SIGNED(_srcptr[4]);
|
||||
_xmove += PCE_SIGNED(_srcptr[5]);
|
||||
_ymove += PCE_SIGNED(_srcptr[6]);
|
||||
_srcptr += 7;
|
||||
|
||||
return mainRoutine(xmoveCur, ymoveCur);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
byte ClassicCostumeRenderer::drawLimb(const Actor *a, int limb) {
|
||||
int i;
|
||||
int code;
|
||||
const byte *frameptr;
|
||||
const byte *baseptr, *frameptr;
|
||||
const CostumeData &cost = a->_cost;
|
||||
|
||||
// If the specified limb is stopped or not existing, do nothing.
|
||||
@ -882,21 +843,36 @@ byte ClassicCostumeRenderer::drawLimb(const Actor *a, int limb) {
|
||||
// Determine the position the limb is at
|
||||
i = cost.curpos[limb] & 0x7FFF;
|
||||
|
||||
baseptr = _loaded._baseptr;
|
||||
|
||||
// Get the frame pointer for that limb
|
||||
frameptr = _loaded._baseptr + READ_LE_UINT16(_loaded._frameOffsets + limb * 2);
|
||||
if (_vm->_game.id == GID_LOOM && _vm->_game.platform == Common::kPlatformPCEngine)
|
||||
baseptr = _loaded._frameOffsets + limb * 2 + 2;
|
||||
frameptr = baseptr + READ_LE_UINT16(_loaded._frameOffsets + limb * 2);
|
||||
|
||||
// Determine the offset to the costume data for the limb at position i
|
||||
code = _loaded._animCmds[i] & 0x7F;
|
||||
|
||||
// Code 0x7B indicates a limb for which there is nothing to draw
|
||||
if (code != 0x7B) {
|
||||
_srcptr = _loaded._baseptr + READ_LE_UINT16(frameptr + code * 2);
|
||||
if (_vm->_game.id == GID_LOOM && _vm->_game.platform == Common::kPlatformPCEngine)
|
||||
baseptr = frameptr + code * 2 + 2;
|
||||
_srcptr = baseptr + READ_LE_UINT16(frameptr + code * 2);
|
||||
|
||||
if (!(_vm->_game.features & GF_OLD256) || code < 0x79) {
|
||||
const CostumeInfo *costumeInfo;
|
||||
int xmoveCur, ymoveCur;
|
||||
|
||||
if (_loaded._format == 0x57) {
|
||||
if (_vm->_game.id == GID_LOOM && _vm->_game.platform == Common::kPlatformPCEngine) {
|
||||
_numBlocks = _srcptr[0];
|
||||
_width = _srcptr[1] * 16;
|
||||
_height = _srcptr[2] * 16;
|
||||
xmoveCur = _xmove + PCE_SIGNED(_srcptr[3]);
|
||||
ymoveCur = _ymove + PCE_SIGNED(_srcptr[4]);
|
||||
_xmove += PCE_SIGNED(_srcptr[5]);
|
||||
_ymove += PCE_SIGNED(_srcptr[6]);
|
||||
_srcptr += 7;
|
||||
} else if (_loaded._format == 0x57) {
|
||||
_width = _srcptr[0] * 8;
|
||||
_height = _srcptr[1];
|
||||
xmoveCur = _xmove + (int8)_srcptr[2] * 8;
|
||||
|
@ -135,9 +135,6 @@ public:
|
||||
PCEngineCostumeRenderer(ScummEngine *vm) : ClassicCostumeRenderer(vm) {}
|
||||
|
||||
void setPalette(uint16 *palette);
|
||||
|
||||
protected:
|
||||
byte drawLimb(const Actor *a, int limb);
|
||||
};
|
||||
|
||||
class C64CostumeRenderer : public BaseCostumeRenderer {
|
||||
|
@ -225,6 +225,7 @@ GdiPCEngine::GdiPCEngine(ScummEngine *vm) : Gdi(vm) {
|
||||
|
||||
GdiPCEngine::~GdiPCEngine() {
|
||||
free(_PCE.tiles);
|
||||
free(_PCE.masks);
|
||||
}
|
||||
|
||||
GdiV1::GdiV1(ScummEngine *vm) : Gdi(vm) {
|
||||
@ -1570,7 +1571,9 @@ int Gdi::getZPlanes(const byte *ptr, const byte *zplane_list[9], bool bmapImage)
|
||||
numzbuf = _numZBuffer;
|
||||
assert(numzbuf <= 9);
|
||||
|
||||
if (_vm->_game.features & GF_SMALL_HEADER) {
|
||||
if (_vm->_game.id == GID_LOOM && _vm->_game.platform == Common::kPlatformPCEngine) {
|
||||
zplane_list[1] = 0;
|
||||
} else if (_vm->_game.features & GF_SMALL_HEADER) {
|
||||
if (_vm->_game.features & GF_16COLOR)
|
||||
zplane_list[1] = ptr + READ_LE_UINT16(ptr);
|
||||
else {
|
||||
@ -1646,11 +1649,7 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, const int y, const
|
||||
assert(smap_ptr);
|
||||
}
|
||||
|
||||
if (_vm->_game.id == GID_LOOM && _vm->_game.platform == Common::kPlatformPCEngine) {
|
||||
numzbuf = 0;
|
||||
} else {
|
||||
numzbuf = getZPlanes(ptr, zplane_list, false);
|
||||
}
|
||||
numzbuf = getZPlanes(ptr, zplane_list, false);
|
||||
|
||||
const byte *tmsk_ptr = NULL;
|
||||
if (_vm->_game.heversion >= 72) {
|
||||
@ -2611,6 +2610,10 @@ void GdiPCEngine::decodeStrip(const byte *ptr, uint16 *tiles, byte *colors, uint
|
||||
int loopCnt;
|
||||
uint16 lastTileData;
|
||||
|
||||
/*
|
||||
* read tiles indices
|
||||
*/
|
||||
|
||||
int rowIndex = 0;
|
||||
if (isObject) {
|
||||
loopCnt = numRows;
|
||||
@ -2687,7 +2690,7 @@ void GdiPCEngine::decodeStrip(const byte *ptr, uint16 *tiles, byte *colors, uint
|
||||
}
|
||||
|
||||
/*
|
||||
* read z-order or mask???
|
||||
* read mask indices
|
||||
*/
|
||||
|
||||
if (dataWidth == 0 || numRows < 18) {
|
||||
@ -2728,6 +2731,7 @@ void GdiPCEngine::decodePCEngineGfx(const byte *room) {
|
||||
uint16* stripOffsets;
|
||||
|
||||
decodePCEngineTileData(_vm->findResourceData(MKID_BE('TILE'), room));
|
||||
decodePCEngineMaskData(_vm->findResourceData(MKID_BE('ZP00'), room));
|
||||
|
||||
const byte* smap_ptr = _vm->findResourceData(MKID_BE('IM00'), room);
|
||||
*smap_ptr++; // roomID
|
||||
@ -2795,9 +2799,11 @@ void GdiPCEngine::decodePCEngineTileData(const byte *ptr) {
|
||||
|
||||
free(_PCE.tiles);
|
||||
_PCE.tiles = (byte*)calloc(_PCE.numTiles * 8 * 8, sizeof(byte));
|
||||
|
||||
for (int i = 0; i < _PCE.numTiles; ++i) {
|
||||
tile = &_PCE.tiles[i * 64];
|
||||
tilePtr = ptr + tileOffsets[i];
|
||||
|
||||
int index = 0;
|
||||
while (index < 16) {
|
||||
byte cmd = *tilePtr++;
|
||||
@ -2821,21 +2827,61 @@ void GdiPCEngine::decodePCEngineTileData(const byte *ptr) {
|
||||
free(tileOffsets);
|
||||
}
|
||||
|
||||
void GdiPCEngine::decodePCEngineMaskData(const byte *ptr) {
|
||||
const byte *maskPtr;
|
||||
byte* mask;
|
||||
uint16* maskOffsets;
|
||||
|
||||
if (!ptr) {
|
||||
_PCE.numMasks = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
readOffsetTable(ptr, &maskOffsets, &_PCE.numMasks);
|
||||
|
||||
free(_PCE.masks);
|
||||
_PCE.masks = (byte*)malloc(_PCE.numMasks * 8 * sizeof(byte));
|
||||
|
||||
for (int i = 0; i < _PCE.numMasks; ++i) {
|
||||
mask = &_PCE.masks[i * 8];
|
||||
maskPtr = ptr + maskOffsets[i];
|
||||
|
||||
int index = 0;
|
||||
while (index < 8) {
|
||||
byte cmd = *maskPtr++;
|
||||
int cnt = cmd & 0x1F;
|
||||
if (cmd & 0x80) {
|
||||
byte value;
|
||||
if (cmd & 0x60)
|
||||
value = (cmd & 0x40) ? 0x00 : 0xFF;
|
||||
else
|
||||
value = *maskPtr++;
|
||||
for (int j = 0; j < cnt; ++j)
|
||||
mask[index++] = ~value;
|
||||
} else {
|
||||
for (int j = 0; j < cnt; ++j)
|
||||
mask[index++] = ~*maskPtr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(maskOffsets);
|
||||
}
|
||||
|
||||
void GdiPCEngine::drawStripPCEngine(byte *dst, byte *mask, int dstPitch, int stripnr, int top, int height) {
|
||||
uint16 tileIdx;
|
||||
byte *tile;
|
||||
int paletteIdx, paletteOffset, paletteEntry;
|
||||
height /= 8;
|
||||
|
||||
for (int i = 0; i < height; i++) {
|
||||
tileIdx = (_objectMode ? _PCE.nametableObj : _PCE.nametable)[stripnr * height + i];
|
||||
for (int y = 0; y < height; y++) {
|
||||
tileIdx = (_objectMode ? _PCE.nametableObj : _PCE.nametable)[stripnr * height + y];
|
||||
tile = &_PCE.tiles[tileIdx * 64];
|
||||
paletteIdx = (_objectMode ? _PCE.colortableObj : _PCE.colortable)[stripnr * height + i];
|
||||
paletteIdx = (_objectMode ? _PCE.colortableObj : _PCE.colortable)[stripnr * height + y];
|
||||
paletteOffset = paletteIdx * 16;
|
||||
for (int row = 0; row < 8; row++) {
|
||||
for (int col = 0; col < 8; col++) {
|
||||
paletteEntry = tile[row * 8 + col];
|
||||
// TODO: handle transparency (paletteEntry == 0)
|
||||
dst[col] = paletteOffset + paletteEntry;
|
||||
}
|
||||
dst += dstPitch;
|
||||
@ -2844,7 +2890,19 @@ void GdiPCEngine::drawStripPCEngine(byte *dst, byte *mask, int dstPitch, int str
|
||||
}
|
||||
|
||||
void GdiPCEngine::drawStripPCEngineMask(byte *dst, int stripnr, int top, int height) const {
|
||||
// TODO
|
||||
uint16 maskIdx;
|
||||
height /= 8;
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
maskIdx = (_objectMode ? _PCE.masktableObj : _PCE.masktable)[stripnr * height + y];
|
||||
for (int row = 0; row < 8; row++) {
|
||||
if (_PCE.numMasks > 0)
|
||||
*dst = _PCE.masks[maskIdx * 8 + row];
|
||||
else
|
||||
*dst = 0;
|
||||
dst += _numStrips;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GdiV1::drawStripC64Background(byte *dst, int dstPitch, int stripnr, int height) {
|
||||
|
@ -308,15 +308,17 @@ protected:
|
||||
byte colortable[4096], colortableObj[512];
|
||||
uint16 masktable[4096], masktableObj[512];
|
||||
int objX;
|
||||
bool hasmask;
|
||||
int numTiles;
|
||||
int numMasks;
|
||||
byte* tiles;
|
||||
byte* masks;
|
||||
} _PCE;
|
||||
|
||||
protected:
|
||||
void decodePCEngineGfx(const byte *room);
|
||||
void decodeStrip(const byte *ptr, uint16 *tiles, byte *colors, uint16 *masks, int dataWidth, int numRows, bool isObject);
|
||||
void decodePCEngineTileData(const byte *ptr);
|
||||
void decodePCEngineMaskData(const byte *ptr);
|
||||
void decodePCEngineObject(const byte *ptr, int xpos, int ypos, int width, int height);
|
||||
|
||||
void drawStripPCEngine(byte *dst, byte *mask, int dstPitch, int stripnr, int top, int height);
|
||||
|
@ -1474,6 +1474,8 @@ uint16 newTag2Old(uint32 newTag) {
|
||||
return (0x5053); // SP
|
||||
case (MKID_BE('TILE')):
|
||||
return (0x4C54); // TL
|
||||
case (MKID_BE('ZP00')):
|
||||
return (0x505A); // ZP
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user