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;
}
Esempio n. 2
0
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];
			}
		}
Esempio n. 3
0
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++;
			}
		}
	}
}
Esempio n. 4
0
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);
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
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);
}