int SmushFont::draw2byte(byte *buffer, int dst_width, int x, int y, int idx) { int w = _vm->_2byteWidth; int h = _vm->_2byteHeight; byte *src = _vm->get2byteCharPtr(idx); byte *dst = buffer + dst_width * (y + (_vm->_game.id == GID_CMI ? 7 : (_vm->_game.id == GID_DIG ? 2 : 0))) + x; byte bits = 0; char color = (_color != -1) ? _color : 1; if (_new_colors) color = (char)0xff; if (_vm->_game.id == GID_FT) color = 1; for (int j = 0; j < h; j++) { for (int i = 0; i < w; i++) { if ((i % 8) == 0) bits = *src++; if (bits & revBitMask(i % 8)) { dst[i + 1] = 0; dst[dst_width + i] = 0; dst[dst_width + i + 1] = 0; dst[i] = color; } } dst += dst_width; } return w + 1; }
byte NESCostumeRenderer::drawLimb(const Actor *a, int limb) { const byte darkpalette[16] = {0x00,0x00,0x2D,0x3D,0x00,0x00,0x2D,0x3D,0x00,0x00,0x2D,0x3D,0x00,0x00,0x2D,0x3D}; const CostumeData &cost = a->_cost; const byte *palette, *src, *sprdata; int anim, frameNum, frame, offset, numSprites; // If the specified limb is stopped or not existing, do nothing. if (cost.curpos[limb] == 0xFFFF) return 0; if (_vm->getCurrentLights() & LIGHTMODE_actor_use_base_palette) palette = _vm->_NESPalette[1]; else palette = darkpalette; src = _loaded._dataOffsets; anim = 4 * cost.frame[limb] + newDirToOldDir(a->getFacing()); frameNum = cost.curpos[limb]; frame = src[src[2 * anim] + frameNum]; offset = READ_LE_UINT16(_vm->_NEScostdesc + v1MMNESLookup[_loaded._id] * 2); numSprites = _vm->_NEScostlens[offset + frame] + 1; sprdata = _vm->_NEScostdata + READ_LE_UINT16(_vm->_NEScostoffs + 2 * (offset + frame)) + numSprites * 3; bool flipped = (newDirToOldDir(a->getFacing()) == 1); int left = 239, right = 0, top = 239, bottom = 0; byte *maskBuf = _vm->getMaskBuffer(0, 0, 1); for (int spr = 0; spr < numSprites; spr++) { byte mask, tile, sprpal; int8 y, x; sprdata -= 3; mask = (sprdata[0] & 0x80) ? 0x01 : 0x80; y = sprdata[0] << 1; y >>= 1; tile = sprdata[1]; sprpal = (sprdata[2] & 0x03) << 2; x = sprdata[2]; x >>= 2; if (flipped) { mask = (mask == 0x80) ? 0x01 : 0x80; x = -x; } left = MIN(left, _actorX + x); right = MAX(right, _actorX + x + 8); top = MIN(top, _actorY + y); bottom = MAX(bottom, _actorY + y + 8); if ((_actorX + x < 0) || (_actorX + x + 8 >= _out.w)) continue; if ((_actorY + y < 0) || (_actorY + y + 8 >= _out.h)) continue; for (int ty = 0; ty < 8; ty++) { byte c1 = _vm->_NESPatTable[0][tile * 16 + ty]; byte c2 = _vm->_NESPatTable[0][tile * 16 + ty + 8]; for (int tx = 0; tx < 8; tx++) { unsigned char c = ((c1 & mask) ? 1 : 0) | ((c2 & mask) ? 2 : 0) | sprpal; if (mask == 0x01) { c1 >>= 1; c2 >>= 1; } else { c1 <<= 1; c2 <<= 1; } if (!(c & 3)) continue; int my = _actorY + y + ty; int mx = _actorX + x + tx; if (!(_zbuf && (maskBuf[my * _numStrips + mx / 8] & revBitMask(mx & 7)))) *((byte *)_out.getBasePtr(mx, my)) = palette[c]; } }
void ClassicCostumeRenderer::procPCEngine(Codec1 &v1) { const byte *mask, *src; byte *dst; byte maskbit; int xPos, yPos; uint pcolor, width, height; bool masked; int vertShift; int xStep; byte block[16][16]; src = _srcptr; width = _width / 16; height = _height / 16; if (_numBlocks == 0) return; xStep = _mirror ? +1 : -1; for (uint x = 0; x < width; ++x) { yPos = 0; for (uint y = 0; y < height; ++y) { vertShift = *src++; if (vertShift == 0xFF) { yPos += 16; continue; } else { yPos += vertShift; } memset(block, 0, sizeof(block)); int index = 0; while (index < 128) { byte cmd = *src++; int cnt = (cmd & 0x3F) + 1; if (!(cmd & 0xC0)) { for (int i = 0; i < cnt; ++i) PCESetCostumeData(block, index++, 0); } else if (cmd & 0x80) { int value = *src++; for (int i = 0; i < cnt; ++i) PCESetCostumeData(block, index++, value); } else { for (int i = 0; i < cnt; ++i) PCESetCostumeData(block, index++, *src++); } } if (index != 128) { warning("ClassicCostumeRenderer::procPCEngine: index %d != 128\n", index); } for (int row = 0; row < 16; ++row) { xPos = xStep * x * 16; for (int col = 0; col < 16; ++col) { dst = v1.destptr + yPos * _out.pitch + xPos * _vm->_bytesPerPixel; mask = v1.mask_ptr + yPos * _numStrips + (v1.x + xPos) / 8; maskbit = revBitMask((v1.x + xPos) % 8); pcolor = 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 (pcolor && !masked) { WRITE_UINT16(dst, ((uint16 *)_palette)[pcolor]); } xPos += xStep; } yPos++; } } } }
void ClassicCostumeRenderer::proc3_ami(Codec1 &v1) { const byte *mask, *src; byte *dst; byte maskbit, len, height, width; int color; int y; bool masked; int oldXpos, oldScaleIndexX; mask = v1.mask_ptr + v1.x / 8; dst = v1.destptr; height = _height; width = _width; src = _srcptr; maskbit = revBitMask(v1.x & 7); y = v1.y; oldXpos = v1.x; oldScaleIndexX = _scaleIndexX; // Indy4 Amiga always uses the room map to match colors to the currently // setup palette in the actor code in the original, thus we need to do this // mapping over here too. byte *amigaMap = 0; if (_vm->_game.platform == Common::kPlatformAmiga && _vm->_game.id == GID_INDY4) amigaMap = _vm->_roomPalette; do { len = *src++; color = len >> v1.shr; len &= v1.mask; if (!len) len = *src++; do { if (_scaleY == 255 || v1.scaletable[_scaleIndexY] < _scaleY) { masked = (y < 0 || y >= _out.h) || (v1.x < 0 || v1.x >= _out.w) || (v1.mask_ptr && (mask[0] & maskbit)); if (color && !masked) { if (amigaMap) *dst = amigaMap[_palette[color]]; else *dst = _palette[color]; } if (_scaleX == 255 || v1.scaletable[_scaleIndexX] < _scaleX) { v1.x += v1.scaleXstep; dst += v1.scaleXstep; maskbit = revBitMask(v1.x & 7); } _scaleIndexX += v1.scaleXstep; mask = v1.mask_ptr + v1.x / 8; } if (!--width) { if (!--height) return; if (y >= _out.h) return; if (v1.x != oldXpos) { dst += _out.pitch - (v1.x - oldXpos); v1.mask_ptr += _numStrips; mask = v1.mask_ptr + oldXpos / 8; maskbit = revBitMask(oldXpos & 7); y++; } width = _width; v1.x = oldXpos; _scaleIndexX = oldScaleIndexX; _scaleIndexY++; } } while (--len); } while (1); }
void ClassicCostumeRenderer::proc3(Codec1 &v1) { const byte *mask, *src; byte *dst; byte len, maskbit; int y; uint color, height, pcolor; byte scaleIndexY; bool masked; #ifdef USE_ARM_COSTUME_ASM if (((_shadow_mode & 0x20) == 0) && (v1.mask_ptr != NULL) && (_shadow_table != NULL)) { _scaleIndexX = ClassicProc3RendererShadowARM(_scaleY, &v1, &_out, _srcptr, _height, _scaleX, _scaleIndexX, _shadow_table, _palette, _numStrips, _scaleIndexY); return; } #endif /* USE_ARM_COSTUME_ASM */ y = v1.y; src = _srcptr; dst = v1.destptr; len = v1.replen; color = v1.repcolor; height = _height; scaleIndexY = _scaleIndexY; maskbit = revBitMask(v1.x & 7); mask = v1.mask_ptr + v1.x / 8; if (len) goto StartPos; do { len = *src++; color = len >> v1.shr; len &= v1.mask; if (!len) len = *src++; do { if (_scaleY == 255 || v1.scaletable[scaleIndexY++] < _scaleY) { masked = (y < 0 || y >= _out.h) || (v1.x < 0 || v1.x >= _out.w) || (v1.mask_ptr && (mask[0] & maskbit)); if (color && !masked) { if (_shadow_mode & 0x20) { pcolor = _shadow_table[*dst]; } else { pcolor = _palette[color]; if (pcolor == 13 && _shadow_table) pcolor = _shadow_table[*dst]; } *dst = pcolor; } dst += _out.pitch; mask += _numStrips; y++; } if (!--height) { if (!--v1.skip_width) return; height = _height; y = v1.y; scaleIndexY = _scaleIndexY; if (_scaleX == 255 || v1.scaletable[_scaleIndexX] < _scaleX) { v1.x += v1.scaleXstep; if (v1.x < 0 || v1.x >= _out.w) return; maskbit = revBitMask(v1.x & 7); v1.destptr += v1.scaleXstep; } _scaleIndexX += v1.scaleXstep; dst = v1.destptr; mask = v1.mask_ptr + v1.x / 8; } StartPos:; } while (--len); } while (1); }
void ClassicCostumeRenderer::proc3_ami(Codec1 &v1) { const byte *mask, *src; byte *dst; byte maskbit, len, height, width; int color; int y; bool masked; int oldXpos, oldScaleIndexX; mask = v1.mask_ptr + v1.x / 8; dst = v1.destptr; height = _height; width = _width; src = _srcptr; maskbit = revBitMask(v1.x & 7); y = v1.y; oldXpos = v1.x; oldScaleIndexX = _scaleIndexX; do { len = *src++; color = len >> v1.shr; len &= v1.mask; if (!len) len = *src++; do { if (_scaleY == 255 || v1.scaletable[_scaleIndexY] < _scaleY) { masked = (y < 0 || y >= _out.h) || (v1.x < 0 || v1.x >= _out.w) || (v1.mask_ptr && (mask[0] & maskbit)); if (color && !masked) { *dst = _palette[color]; } if (_scaleX == 255 || v1.scaletable[_scaleIndexX] < _scaleX) { v1.x += v1.scaleXstep; dst += v1.scaleXstep; maskbit = revBitMask(v1.x & 7); } _scaleIndexX += v1.scaleXstep; mask = v1.mask_ptr + v1.x / 8; } if (!--width) { if (!--height) return; if (y >= _out.h) return; if (v1.x != oldXpos) { dst += _out.pitch - (v1.x - oldXpos); v1.mask_ptr += _numStrips; mask = v1.mask_ptr + oldXpos / 8; maskbit = revBitMask(oldXpos & 7); y++; } width = _width; v1.x = oldXpos; _scaleIndexX = oldScaleIndexX; _scaleIndexY++; } } while (--len); } while (1); }