OffsetY() public method

public OffsetY ( int y ) : void
y int
return void
示例#1
0
        static void DecompressMaskImgOr(PixelNavigator dst, Stream src, int height)
        {
            byte b, c;

            while (height != 0)
            {
                b = (byte)src.ReadByte();

                if ((b & 0x80) != 0)
                {
                    b &= 0x7F;
                    c  = (byte)src.ReadByte();

                    do
                    {
                        dst.Write((byte)(dst.Read() | c));
                        dst.OffsetY(1);
                        --height;
                    } while ((--b != 0) && (height != 0));
                }
                else
                {
                    do
                    {
                        dst.Write((byte)(dst.Read() | src.ReadByte()));
                        dst.OffsetY(1);
                        --height;
                    } while ((--b != 0) && (height != 0));
                }
            }
        }
示例#2
0
        static void DecompressMaskImg(PixelNavigator dst, Stream src, int height)
        {
            while (height != 0)
            {
                var b = (byte)src.ReadByte();

                if ((b & 0x80) != 0)
                {
                    b &= 0x7F;
                    var c = (byte)src.ReadByte();

                    do
                    {
                        dst.Write(c);
                        dst.OffsetY(1);
                        --height;
                    } while (--b != 0 && height != 0);
                }
                else
                {
                    do
                    {
                        dst.Write((byte)src.ReadByte());
                        dst.OffsetY(1);
                        --height;
                    } while (--b != 0 && height != 0);
                }
            }
        }
示例#3
0
        void DrawStripV1Background(PixelNavigator navDst, int stripnr, int height)
        {
            int charIdx;

            height /= 8;
            for (int y = 0; y < height; y++)
            {
                _v1.Colors[3] = (byte)(_v1.ColorMap[y + stripnr * height] & 7);
                // Check for room color change in V1 zak
                if (RoomPalette[0] == 255)
                {
                    _v1.Colors[2] = RoomPalette[2];
                    _v1.Colors[1] = RoomPalette[1];
                }

                charIdx = _v1.PicMap[y + stripnr * height] * 8;
                for (int i = 0; i < 8; i++)
                {
                    byte c     = _v1.CharMap[charIdx + i];
                    var  color = _v1.Colors[(c >> 6) & 3];
                    navDst.Write(0, color);
                    navDst.Write(1, color);
                    color = _v1.Colors[(c >> 4) & 3];
                    navDst.Write(2, color);
                    navDst.Write(3, color);
                    color = _v1.Colors[(c >> 2) & 3];
                    navDst.Write(4, color);
                    navDst.Write(5, color);
                    color = _v1.Colors[(c >> 0) & 3];
                    navDst.Write(6, color);
                    navDst.Write(7, color);
                    navDst.OffsetY(1);
                }
            }
        }
示例#4
0
        void DrawStripRaw(PixelNavigator navDst, BinaryReader src, int height, bool transpCheck)
        {
            int x;

            if (game.Features.HasFlag(GameFeatures.Old256))
            {
                int h = height;
                x = 8;
                while (true)
                {
                    navDst.Write(RoomPalette[src.ReadByte()]);
                    if (!NextRow(ref navDst, ref x, ref h, height))
                    {
                        return;
                    }
                }
            }
            do
            {
                for (x = 0; x < 8; x++)
                {
                    int color = src.ReadByte();
                    if (!transpCheck || color != TransparentColor)
                    {
                        navDst.OffsetX(x);
                        WriteRoomColor(navDst, color);
                        navDst.OffsetX(-x);
                    }
                }
                navDst.OffsetY(1);
            } while ((--height) != 0);
        }
示例#5
0
        void DrawStripV1Object(PixelNavigator navDst, int stripnr, int width, int height)
        {
            int charIdx;

            height /= 8;
            width  /= 8;
            for (var y = 0; y < height; y++)
            {
                _v1.Colors[3] = (byte)(objectMap[(y + height) * width + stripnr] & 7);
                charIdx       = objectMap[y * width + stripnr] * 8;
                for (var i = 0; i < 8; i++)
                {
                    byte c     = _v1.CharMap[charIdx + i];
                    var  color = _v1.Colors[(c >> 6) & 3];
                    navDst.Write(0, color);
                    navDst.Write(1, color);
                    color = _v1.Colors[(c >> 4) & 3];
                    navDst.Write(2, color);
                    navDst.Write(3, color);
                    color = _v1.Colors[(c >> 2) & 3];
                    navDst.Write(4, color);
                    navDst.Write(5, color);
                    color = _v1.Colors[(c >> 0) & 3];
                    navDst.Write(6, color);
                    navDst.Write(7, color);
                    navDst.OffsetY(1);
                }
            }
        }
示例#6
0
        void DrawStripV1Mask(PixelNavigator navDst, int stripnr, int width, int height)
        {
            int maskIdx;

            height /= 8;
            width  /= 8;
            for (var y = 0; y < height; y++)
            {
                if (_objectMode)
                {
                    maskIdx = objectMap[(y + 2 * height) * width + stripnr] * 8;
                }
                else
                {
                    maskIdx = _v1.MaskMap[y + stripnr * height] * 8;
                }
                for (var i = 0; i < 8; i++)
                {
                    byte c = _v1.MaskChar[maskIdx + i];

                    // V1/V0 masks are inverted compared to what ScummVM expects
                    navDst.Write((byte)(c ^ 0xFF));
                    navDst.OffsetY(1);
                }
            }
        }
示例#7
0
        public void DrawChar(PixelNavigator dst, char c, int x, int y, byte color)
        {
            var width    = Math.Min((int)_chars[c].Width, dst.Width - x);
            var height   = Math.Min((int)_chars[c].Height, dst.Height - y);
            var src      = UnpackChar(c);
            var srcPitch = _chars[c].Width;
            var srcPos   = 0;

            var minX = x < 0 ? -x : 0;
            var minY = y < 0 ? -y : 0;

            if (height <= 0 || width <= 0)
            {
                return;
            }

            if (minY != 0)
            {
                srcPos += minY * srcPitch;
                dst.OffsetY(minY);
            }

            for (int ty = minY; ty < height; ty++)
            {
                for (int tx = minX; tx < width; tx++)
                {
                    if (src[srcPos + tx] != _chars[c].Transparency)
                    {
                        if (src[srcPos + tx] == 1)
                        {
                            dst.Write(tx, color);
                        }
                        else
                        {
                            dst.Write(tx, src[srcPos + tx]);
                        }
                    }
                }
                srcPos += srcPitch;
                dst.OffsetY(1);
            }
        }
示例#8
0
 static bool NextRow(ref PixelNavigator navDst, ref int x, ref int y, int height)
 {
     navDst.OffsetY(1);
     if (--y == 0)
     {
         if ((--x) == 0)
         {
             return(false);
         }
         navDst.Offset(1, -height);
         y = height;
     }
     return(true);
 }
示例#9
0
        void DrawStripBasicV(PixelNavigator navDst, BinaryReader src, int height, bool transpCheck)
        {
            byte color = src.ReadByte();
            uint bits  = src.ReadByte();
            byte cl    = 8;
            int  inc   = -1;

            int x = 8;

            do
            {
                int h = height;
                do
                {
                    FillBits(ref cl, ref bits, src);
                    if (!transpCheck || color != transparentColor)
                    {
                        WriteRoomColor(navDst, color);
                    }
                    navDst.OffsetY(1);
                    if (!ReadBit(ref cl, ref bits))
                    {
                    }
                    else if (!ReadBit(ref cl, ref bits))
                    {
                        FillBits(ref cl, ref bits, src);
                        color  = (byte)(bits & decompMask);
                        bits >>= decompShr;
                        cl    -= decompShr;
                        inc    = -1;
                    }
                    else if (!ReadBit(ref cl, ref bits))
                    {
                        color = (byte)(color + inc);
                    }
                    else
                    {
                        inc   = -inc;
                        color = (byte)(color + inc);
                    }
                } while ((--h) != 0);
                navDst.Offset(1, -height);
            } while ((--x) != 0);
        }
示例#10
0
        void UnkDecode11(PixelNavigator navDst, BinaryReader src, int height)
        {
            int i;
            int buffer = 0, mask = 128;
            int inc   = 1;
            int color = src.ReadByte();

            int x = 8;

            do
            {
                int h = height;
                do
                {
                    navDst.Write(RoomPalette[color]);
                    navDst.OffsetY(1);
                    for (i = 0; i < 3; i++)
                    {
                        if (!ReadBit256(src, ref mask, ref buffer))
                        {
                            break;
                        }
                    }
                    switch (i)
                    {
                    case 1:
                        inc    = -inc;
                        color -= inc;
                        break;

                    case 2:
                        color -= inc;
                        break;

                    case 3:
                        inc   = 1;
                        color = ReadNBits(src, 8, ref mask, ref buffer);
                        break;
                    }
                } while ((--h) != 0);
                navDst.Offset(1, -height);
            } while ((--x) != 0);
        }
示例#11
0
        protected virtual void DrawBits1(Surface surface, int x, int y, BinaryReader src, int drawTop, int width, int height)
        {
            var dst = new PixelNavigator(surface);

            dst.GoTo(x, y);

            byte bits = 0;
            byte col  = Color;
            //int pitch = surface.Pitch - width * surface.BytesPerPixel;
            var dst2 = new PixelNavigator(dst);

            dst2.OffsetY(1);

            for (y = 0; y < height && y + drawTop < surface.Height; y++)
            {
                for (x = 0; x < width; x++)
                {
                    if ((x % 8) == 0)
                    {
                        bits = src.ReadByte();
                    }
                    if ((bits & ScummHelper.RevBitMask(x % 8)) != 0 && y + drawTop >= 0)
                    {
                        if (_shadowMode)
                        {
                            dst.OffsetX(1);
                            dst.Write(_shadowColor);
                            dst2.Write(_shadowColor);
                            dst2.OffsetX(1);
                            dst2.Write(_shadowColor);
                        }
                        dst.Write(col);
                    }
                    dst.OffsetX(1);
                    dst2.OffsetX(1);
                }

                dst.OffsetX(surface.Width - width);
                dst2.OffsetX(surface.Width - width);
            }
        }
示例#12
0
        void Akos16Decompress(PixelNavigator dest, int srcPos, int t_width, int t_height, int dir,
                              int numskip_before, int numskip_after, byte transparency, int maskLeft, int maskTop, int zBuf)
        {
            var tmp_buf = _akos16.Buffer;
            var tmp_pos = 0;
            var maskbit = (byte)ScummHelper.RevBitMask(maskLeft & 7);

            if (dir < 0)
            {
                dest.OffsetX(-(t_width - 1));
                tmp_pos += (t_width - 1);
            }

            Akos16SetupBitReader(srcPos);

            if (numskip_before != 0)
            {
                Akos16SkipData(numskip_before);
            }

            var maskptr = _vm.GetMaskBuffer(maskLeft, maskTop, zBuf);

            Debug.Assert(t_height > 0);
            Debug.Assert(t_width > 0);
            while ((t_height--) != 0)
            {
                Akos16DecodeLine(tmp_buf, tmp_pos, t_width, dir);
                BompDrawData.BompApplyMask(_akos16.Buffer, 0, maskptr, maskbit, t_width, transparency);
                BompDrawData.BompApplyShadow(ShadowMode, ShadowTable, _akos16.Buffer, 0, dest, t_width, transparency);

                if (numskip_after != 0)
                {
                    Akos16SkipData(numskip_after);
                }
                dest.OffsetY(1);
                maskptr.OffsetY(1);
            }
        }
示例#13
0
        protected override void DrawBits1(Surface dest, int x, int y, BinaryReader src, int drawTop, int width, int height)
        {
            if (_sjisCurChar != 0)
            {
//                Debug.Assert(Vm._cjkFont);
//                Vm._cjkFont.drawChar(dest, _sjisCurChar, x, y, _color, _shadowColor);
                return;
            }
            bool scale2x = ((dest == Vm.TextSurface) && (Vm.TextSurfaceMultiplier == 2) /*&& !(_sjisCurChar >= 256 && Vm.UseCJKMode)*/);

            byte bits  = 0;
            var  col   = Color;
            var  bpp   = Surface.GetBytesPerPixel(dest.PixelFormat);
            int  pitch = dest.Pitch - width * bpp;
            var  dst   = new PixelNavigator(dest);

            dst.GoTo(x, y);
            var dst2 = new PixelNavigator(dst);

            dst2.OffsetY(1);

            var dst3 = new PixelNavigator(dst2);
            var dst4 = new PixelNavigator(dst2);

            if (scale2x)
            {
                dst3.OffsetY(1);
                dst4.OffsetY(1);
                pitch <<= 1;
            }

            for (y = 0; y < height && y + drawTop < dest.Height; y++)
            {
                for (x = 0; x < width; x++)
                {
                    if ((x % 8) == 0)
                    {
                        bits = src.ReadByte();
                    }
                    if (((bits & ScummHelper.RevBitMask(x % 8)) != 0) && y + drawTop >= 0)
                    {
                        if (bpp == 2)
                        {
                            if (_enableShadow)
                            {
                                dst.WriteUInt16(2, Vm._16BitPalette[_shadowColor]);
                                dst.WriteUInt16(2 + dest.Pitch, Vm._16BitPalette[_shadowColor]);
                            }
                            dst.WriteUInt16(Vm._16BitPalette[Color]);
                        }
                        else
                        {
                            if (_enableShadow)
                            {
                                if (scale2x)
                                {
                                    dst.Write(2, _shadowColor);
                                    dst.Write(3, _shadowColor);
                                    dst2.Write(2, _shadowColor);
                                    dst2.Write(3, _shadowColor);

                                    dst3.Write(0, _shadowColor);
                                    dst3.Write(1, _shadowColor);
                                    dst4.Write(0, _shadowColor);
                                    dst4.Write(0, _shadowColor);
                                }
                                else
                                {
                                    dst2.Write(_shadowColor);
                                    dst.Write(1, _shadowColor);
                                }
                            }
                            dst.Write(col);

                            if (scale2x)
                            {
                                dst.Write(1, col);
                                dst2.Write(0, col);
                                dst2.Write(1, col);
                            }
                        }
                    }
                    dst.OffsetX(1);
                    dst2.OffsetX(1);
                    if (scale2x)
                    {
                        dst.OffsetX(1);
                        dst2.OffsetX(1);
                        dst3.OffsetX(1);
                        dst4.OffsetX(1);
                    }
                }

                dst.OffsetX(pitch / dst.BytesByPixel);
                dst2.OffsetX(pitch / dst2.BytesByPixel);
                dst3.OffsetX(pitch / dst3.BytesByPixel);
                dst4.OffsetX(pitch / dst4.BytesByPixel);
            }
        }
示例#14
0
        void Proc3(Codec1 v1)
        {
            int y = v1.Y;

            _loaded.CostumeReader.BaseStream.Seek(_srcptr, System.IO.SeekOrigin.Begin);
            var  dst    = new PixelNavigator(v1.DestPtr);
            var  len    = v1.RepLen;
            uint color  = v1.RepColor;
            var  height = (uint)_height;

            var scaleIndexY = _scaleIndexY;
            var maskbit     = (byte)ScummHelper.RevBitMask(v1.X & 7);
            var mask        = new PixelNavigator(v1.MaskPtr);

            mask.OffsetX(v1.X / 8);

            bool ehmerde = (len != 0);

            do
            {
                if (!ehmerde)
                {
                    len   = _loaded.CostumeReader.ReadByte();
                    color = (uint)(len >> v1.Shr);
                    len  &= v1.Mask;
                    if (len == 0)
                    {
                        len = _loaded.CostumeReader.ReadByte();
                    }
                }

                do
                {
                    if (!ehmerde)
                    {
                        if (ScaleY == 255 || v1.Scaletable[scaleIndexY++] < ScaleY)
                        {
                            var masked = (y < 0 || y >= _h) || (v1.X < 0 || v1.X >= _w) || ((mask.Read() & maskbit) != 0);

                            if (color != 0 && !masked)
                            {
                                byte pcolor;
                                if ((ShadowMode & 0x20) != 0)
                                {
                                    pcolor = ShadowTable[dst.Read()];
                                }
                                else
                                {
                                    pcolor = (byte)_palette[color];
                                    if (pcolor == 13 && ShadowTable != null)
                                    {
                                        pcolor = ShadowTable[dst.Read()];
                                    }
                                }
                                dst.Write(pcolor);
                            }
                            dst.OffsetY(1);
                            mask.OffsetY(1);
                            y++;
                        }
                        if ((--height) == 0)
                        {
                            if ((--v1.SkipWidth) == 0)
                            {
                                return;
                            }
                            height = (uint)_height;
                            y      = v1.Y;

                            scaleIndexY = _scaleIndexY;

                            if (ScaleX == 255 || v1.Scaletable[_scaleIndexX] < ScaleX)
                            {
                                v1.X += v1.ScaleXStep;
                                if (v1.X < 0 || v1.X >= _w)
                                {
                                    return;
                                }
                                maskbit = (byte)ScummHelper.RevBitMask(v1.X & 7);
                                v1.DestPtr.OffsetX(v1.ScaleXStep);
                            }
                            _scaleIndexX = (byte)(_scaleIndexX + v1.ScaleXStep);
                            dst          = new PixelNavigator(v1.DestPtr);
                            mask         = new PixelNavigator(v1.MaskPtr);
                            mask.OffsetX(v1.X / 8);
                        }
                    }
                    ehmerde = false;
                } while ((--len) != 0);
            } while (true);
        }
示例#15
0
文件: Gdi.cs 项目: scemino/nscumm
        void DrawStripRaw(PixelNavigator navDst, BinaryReader src, int height, bool transpCheck)
        {
            int x;

            if (game.Features.HasFlag(GameFeatures.Old256))
            {
                int h = height;
                x = 8;
                while (true)
                {
                    navDst.Write(RoomPalette[src.ReadByte()]);
                    if (!NextRow(ref navDst, ref x, ref h, height))
                        return;
                }
            }
            do
            {
                for (x = 0; x < 8; x++)
                {
                    int color = src.ReadByte();
                    if (!transpCheck || color != TransparentColor)
                    {
                        navDst.OffsetX(x);
                        WriteRoomColor(navDst, color);
                        navDst.OffsetX(-x);
                    }
                }
                navDst.OffsetY(1);
            } while ((--height) != 0);
        }
示例#16
0
文件: Gdi2.cs 项目: scemino/nscumm
        protected override void PrepareDrawBitmap(ImageData img, VirtScreen vs,
                               Point p, int width, int height,
                               int stripnr, int numstrip)
        {
            var ptr = img.Data;
            //
            // Since V3, all graphics data was encoded in strips, which is very efficient
            // for redrawing only parts of the screen. However, V2 is different: here
            // the whole graphics are encoded as one big chunk. That makes it rather
            // difficult to draw only parts of a room/object. We handle the V2 graphics
            // differently from all other (newer) graphic formats for this reason.
            //
            var table = (_objectMode ? null : _roomStrips);
            int left = (stripnr * 8);
            int right = left + (numstrip * 8);
            PixelNavigator navDst;
            var srcOffset = 0;
            byte color, data = 0;
            int run;
            bool dither = false;
            byte[] dither_table = new byte[128];
            var ditherOffset = 0;
            int theX, theY, maxX;

            var surface = vs.HasTwoBuffers ? vs.Surfaces[1] : vs.Surfaces[0];
            navDst = new PixelNavigator(surface);
            navDst.GoTo(p.X * 8, p.Y);

            var mask_ptr = GetMaskBuffer(p.X, p.Y, 1);

            if (table != null)
            {
                run = table.run[stripnr];
                color = (byte)table.color[stripnr];
                srcOffset = table.offsets[stripnr];
                theX = left;
                maxX = right;
            }
            else
            {
                run = 1;
                color = 0;
                srcOffset = 0;
                theX = 0;
                maxX = width;
            }

            // Decode and draw the image data.
            Debug.Assert(height <= 128);
            for (; theX < maxX; theX++)
            {
                ditherOffset = 0;
                for (theY = 0; theY < height; theY++)
                {
                    if (--run == 0)
                    {
                        data = ptr[srcOffset++];
                        if ((data & 0x80) != 0)
                        {
                            run = data & 0x7f;
                            dither = true;
                        }
                        else
                        {
                            run = data >> 4;
                            dither = false;
                        }
                        color = RoomPalette[data & 0x0f];
                        if (run == 0)
                        {
                            run = ptr[srcOffset++];
                        }
                    }
                    if (!dither)
                    {
                        dither_table[ditherOffset] = color;
                    }
                    if (left <= theX && theX < right)
                    {
                        navDst.Write(dither_table[ditherOffset++]);
                        navDst.OffsetY(1);
                    }
                }
                if (left <= theX && theX < right)
                {
                    navDst.Offset(1, -height);
                }
            }

            // Draw mask (zplane) data
            theY = 0;

            if (table != null)
            {
                srcOffset = table.zoffsets[stripnr];
                run = table.zrun[stripnr];
                theX = left;
            }
            else
            {
                run = ptr[srcOffset++];
                theX = 0;
            }
            while (theX < right)
            {
                byte runFlag = (byte)(run & 0x80);
                if (runFlag != 0)
                {
                    run &= 0x7f;
                    data = ptr[srcOffset++];
                }
                do
                {
                    if (runFlag == 0)
                        data = ptr[srcOffset++];

                    if (left <= theX)
                    {
                        mask_ptr.Write(data);
                        mask_ptr.OffsetY(1);
                    }
                    theY++;
                    if (theY >= height)
                    {
                        if (left <= theX)
                        {
                            mask_ptr.Offset(1, -height);
                        }
                        theY = 0;
                        theX += 8;
                        if (theX >= right)
                            break;
                    }
                } while ((--run) != 0);
                run = ptr[srcOffset++];
            }
        }
示例#17
0
        void Proc3(Codec1 v1)
        {
            int y = v1.Y;
            _loaded.CostumeReader.BaseStream.Seek(_srcptr, System.IO.SeekOrigin.Begin);
            var dst = new PixelNavigator(v1.DestPtr);
            var len = v1.RepLen;
            uint color = v1.RepColor;
            var height = (uint)_height;

            var scaleIndexY = _scaleIndexY;
            var maskbit = (byte)ScummHelper.RevBitMask(v1.X & 7);
            var mask = new PixelNavigator(v1.MaskPtr);
            mask.OffsetX(v1.X / 8);

            bool ehmerde = (len != 0);

            do
            {
                if (!ehmerde)
                {
                    len = _loaded.CostumeReader.ReadByte();
                    color = (uint)(len >> v1.Shr);
                    len &= v1.Mask;
                    if (len == 0)
                        len = _loaded.CostumeReader.ReadByte();
                }

                do
                {
                    if (!ehmerde)
                    {
                        if (ScaleY == 255 || v1.Scaletable[scaleIndexY++] < ScaleY)
                        {
                            var masked = (y < 0 || y >= _h) || (v1.X < 0 || v1.X >= _w) || ((mask.Read() & maskbit) != 0);

                            if (color != 0 && !masked)
                            {
                                byte pcolor;
                                if ((ShadowMode & 0x20) != 0)
                                {
                                    pcolor = ShadowTable[dst.Read()];
                                }
                                else
                                {
                                    pcolor = (byte)_palette[color];
                                    if (pcolor == 13 && ShadowTable != null)
                                        pcolor = ShadowTable[dst.Read()];
                                }
                                dst.Write(pcolor);
                            }
                            dst.OffsetY(1);
                            mask.OffsetY(1);
                            y++;
                        }
                        if ((--height) == 0)
                        {
                            if ((--v1.SkipWidth) == 0)
                                return;
                            height = (uint)_height;
                            y = v1.Y;

                            scaleIndexY = _scaleIndexY;

                            if (ScaleX == 255 || v1.Scaletable[_scaleIndexX] < ScaleX)
                            {
                                v1.X += v1.ScaleXStep;
                                if (v1.X < 0 || v1.X >= _w)
                                    return;
                                maskbit = (byte)ScummHelper.RevBitMask(v1.X & 7);
                                v1.DestPtr.OffsetX(v1.ScaleXStep);
                            }
                            _scaleIndexX = (byte)(_scaleIndexX + v1.ScaleXStep);
                            dst = new PixelNavigator(v1.DestPtr);
                            mask = new PixelNavigator(v1.MaskPtr);
                            mask.OffsetX(v1.X / 8);
                        }
                    }
                    ehmerde = false;
                } while ((--len) != 0);
            } while (true);
        }
示例#18
0
        public void DrawBomp()
        {
            Rect clip;
            byte skip_y_bits = 0x80;
            byte skip_y_new = 0;
            byte[] bomp_scaling_x = new byte[64];
            byte[] bomp_scaling_y = new byte[64];

            if (X < 0)
            {
                clip.Left = -X;
            }
            else
            {
                clip.Left = 0;
            }

            if (Y < 0)
            {
                clip.Top = -Y;
            }
            else
            {
                clip.Top = 0;
            }

            clip.Right = Width;
            if (clip.Right > Dst.Width - X)
            {
                clip.Right = Dst.Width - X;
            }

            clip.Bottom = Height;
            if (clip.Bottom > Dst.Height - Y)
            {
                clip.Bottom = Dst.Height - Y;
            }

            var src = Src;
            var pn = new PixelNavigator(Dst);
            pn.GoTo(X + clip.Left, Y);

            var maskbit = ScummHelper.RevBitMask((X + clip.Left) & 7);
            PixelNavigator maskPtr = new PixelNavigator();
            // Mask against any additionally imposed mask
            if (MaskPtr.HasValue)
            {
                maskPtr = MaskPtr.Value;
                maskPtr.GoTo((X + clip.Left) / 8, Y);
            }

            var scalingYPtr = 0;

            // Setup vertical scaling
            if (ScaleY != 255)
            {
                var scaleBottom = SetupBompScale(bomp_scaling_y, Height, ScaleY);

                skip_y_new = bomp_scaling_y[scalingYPtr++];
                skip_y_bits = 0x80;

                if (clip.Bottom > scaleBottom)
                {
                    clip.Bottom = scaleBottom;
                }
            }

            // Setup horizontal scaling
            if (ScaleX != 255)
            {
                var scaleRight = SetupBompScale(bomp_scaling_x, Width, ScaleX);

                if (clip.Right > scaleRight)
                {
                    clip.Right = scaleRight;
                }
            }

            var width = clip.Right - clip.Left;

            if (width <= 0)
                return;

            int pos_y = 0;
            var line_buffer = new byte[1024];

            byte tmp;
            using (var br = new BinaryReader(new MemoryStream(src)))
            {
                // Loop over all lines
                while (pos_y < clip.Bottom)
                {
                    br.ReadUInt16();
                    // Decode a single (bomp encoded) line, reversed if we are in mirror mode
                    if (Mirror)
                        BompDecodeLineReverse(br, line_buffer, 0, Width);
                    else
                        // Decode a single (bomp encoded) line
                        BompDecodeLine(br, line_buffer, 0, Width);

                    // If vertical scaling is enabled, do it
                    if (ScaleY != 255)
                    {
                        // A bit set means we should skip this line...
                        tmp = (byte)(skip_y_new & skip_y_bits);

                        // Advance the scale-skip bit mask, if it's 0, get the next scale-skip byte
                        skip_y_bits /= 2;
                        if (skip_y_bits == 0)
                        {
                            skip_y_bits = 0x80;
                            skip_y_new = bomp_scaling_y[scalingYPtr++];
                        }

                        // Skip the current line if the above check tells us to
                        if (tmp != 0)
                            continue;
                    }

                    // Perform horizontal scaling
                    if (ScaleX != 255)
                    {
                        BompScaleFuncX(line_buffer, bomp_scaling_x, 0, 0x80, Width);
                    }

                    // The first clip.top lines are to be clipped, i.e. not drawn
                    if (clip.Top > 0)
                    {
                        clip.Top--;
                    }
                    else
                    {
                        // Replace the parts of the line which are masked with the transparency color
                        if (MaskPtr.HasValue)
                            BompApplyMask(line_buffer, clip.Left, maskPtr, (byte)maskbit, width, 255);

                        // Apply custom color map, if available
                        if (ActorPalette != null)
                            BompApplyActorPalette(ActorPalette, line_buffer, clip.Left, width);

                        // Finally, draw the decoded, scaled, masked and recolored line onto
                        // the target surface, using the specified shadow mode
                        BompApplyShadow(ShadowMode, ShadowPalette, line_buffer, clip.Left, pn, width, 255);
                    }

                    // Advance to the next line
                    pos_y++;
                    if (MaskPtr.HasValue)
                    {
                        maskPtr.OffsetY(1);
                    }
                    pn.OffsetY(1);
                }
            }
        }
示例#19
0
文件: Gdi.cs 项目: scemino/nscumm
        void DrawStripBasicV(PixelNavigator navDst, BinaryReader src, int height, bool transpCheck)
        {
            byte color = src.ReadByte();
            uint bits = src.ReadByte();
            byte cl = 8;
            int inc = -1;

            int x = 8;
            do
            {
                int h = height;
                do
                {
                    FillBits(ref cl, ref bits, src);
                    if (!transpCheck || color != transparentColor)
                    {
                        WriteRoomColor(navDst, color);
                    }
                    navDst.OffsetY(1);
                    if (!ReadBit(ref cl, ref bits))
                    {
                    }
                    else if (!ReadBit(ref cl, ref bits))
                    {
                        FillBits(ref cl, ref bits, src);
                        color = (byte)(bits & decompMask);
                        bits >>= decompShr;
                        cl -= decompShr;
                        inc = -1;
                    }
                    else if (!ReadBit(ref cl, ref bits))
                    {
                        color = (byte)(color + inc);
                    }
                    else
                    {
                        inc = -inc;
                        color = (byte)(color + inc);
                    }
                } while ((--h) != 0);
                navDst.Offset(1, -height);
            } while ((--x) != 0);
        }
示例#20
0
        protected override void PrepareDrawBitmap(ImageData img, VirtScreen vs,
                                                  Point p, int width, int height,
                                                  int stripnr, int numstrip)
        {
            var ptr = img.Data;
            //
            // Since V3, all graphics data was encoded in strips, which is very efficient
            // for redrawing only parts of the screen. However, V2 is different: here
            // the whole graphics are encoded as one big chunk. That makes it rather
            // difficult to draw only parts of a room/object. We handle the V2 graphics
            // differently from all other (newer) graphic formats for this reason.
            //
            var            table = (_objectMode ? null : _roomStrips);
            int            left  = (stripnr * 8);
            int            right = left + (numstrip * 8);
            PixelNavigator navDst;
            var            srcOffset = 0;
            byte           color, data = 0;
            int            run;
            bool           dither = false;

            byte[] dither_table = new byte[128];
            var    ditherOffset = 0;
            int    theX, theY, maxX;

            var surface = vs.HasTwoBuffers ? vs.Surfaces[1] : vs.Surfaces[0];

            navDst = new PixelNavigator(surface);
            navDst.GoTo(p.X * 8, p.Y);

            var mask_ptr = GetMaskBuffer(p.X, p.Y, 1);

            if (table != null)
            {
                run       = table.run[stripnr];
                color     = (byte)table.color[stripnr];
                srcOffset = table.offsets[stripnr];
                theX      = left;
                maxX      = right;
            }
            else
            {
                run       = 1;
                color     = 0;
                srcOffset = 0;
                theX      = 0;
                maxX      = width;
            }

            // Decode and draw the image data.
            Debug.Assert(height <= 128);
            for (; theX < maxX; theX++)
            {
                ditherOffset = 0;
                for (theY = 0; theY < height; theY++)
                {
                    if (--run == 0)
                    {
                        data = ptr[srcOffset++];
                        if ((data & 0x80) != 0)
                        {
                            run    = data & 0x7f;
                            dither = true;
                        }
                        else
                        {
                            run    = data >> 4;
                            dither = false;
                        }
                        color = RoomPalette[data & 0x0f];
                        if (run == 0)
                        {
                            run = ptr[srcOffset++];
                        }
                    }
                    if (!dither)
                    {
                        dither_table[ditherOffset] = color;
                    }
                    if (left <= theX && theX < right)
                    {
                        navDst.Write(dither_table[ditherOffset++]);
                        navDst.OffsetY(1);
                    }
                }
                if (left <= theX && theX < right)
                {
                    navDst.Offset(1, -height);
                }
            }

            // Draw mask (zplane) data
            theY = 0;

            if (table != null)
            {
                srcOffset = table.zoffsets[stripnr];
                run       = table.zrun[stripnr];
                theX      = left;
            }
            else
            {
                run  = ptr[srcOffset++];
                theX = 0;
            }
            while (theX < right)
            {
                byte runFlag = (byte)(run & 0x80);
                if (runFlag != 0)
                {
                    run &= 0x7f;
                    data = ptr[srcOffset++];
                }
                do
                {
                    if (runFlag == 0)
                    {
                        data = ptr[srcOffset++];
                    }

                    if (left <= theX)
                    {
                        mask_ptr.Write(data);
                        mask_ptr.OffsetY(1);
                    }
                    theY++;
                    if (theY >= height)
                    {
                        if (left <= theX)
                        {
                            mask_ptr.Offset(1, -height);
                        }
                        theY  = 0;
                        theX += 8;
                        if (theX >= right)
                        {
                            break;
                        }
                    }
                } while ((--run) != 0);
                run = ptr[srcOffset++];
            }
        }
示例#21
0
文件: Gdi1.cs 项目: scemino/nscumm
        void DrawStripV1Mask(PixelNavigator navDst, int stripnr, int width, int height)
        {
            int maskIdx;
            height /= 8;
            width /= 8;
            for (var y = 0; y < height; y++)
            {
                if (_objectMode)
                    maskIdx = objectMap[(y + 2 * height) * width + stripnr] * 8;
                else
                    maskIdx = _v1.MaskMap[y + stripnr * height] * 8;
                for (var i = 0; i < 8; i++)
                {
                    byte c = _v1.MaskChar[maskIdx + i];

                    // V1/V0 masks are inverted compared to what ScummVM expects
                    navDst.Write((byte)(c ^ 0xFF));
                    navDst.OffsetY(1);
                }
            }
        }
示例#22
0
文件: Gdi1.cs 项目: scemino/nscumm
 void DrawStripV1Object(PixelNavigator navDst, int stripnr, int width, int height)
 {
     int charIdx;
     height /= 8;
     width /= 8;
     for (var y = 0; y < height; y++)
     {
         _v1.Colors[3] = (byte)(objectMap[(y + height) * width + stripnr] & 7);
         charIdx = objectMap[y * width + stripnr] * 8;
         for (var i = 0; i < 8; i++)
         {
             byte c = _v1.CharMap[charIdx + i];
             var color = _v1.Colors[(c >> 6) & 3];
             navDst.Write(0, color);
             navDst.Write(1, color);
             color = _v1.Colors[(c >> 4) & 3];
             navDst.Write(2, color);
             navDst.Write(3, color);
             color = _v1.Colors[(c >> 2) & 3];
             navDst.Write(4, color);
             navDst.Write(5, color);
             color = _v1.Colors[(c >> 0) & 3];
             navDst.Write(6, color);
             navDst.Write(7, color);
             navDst.OffsetY(1);
         }
     }
 }
示例#23
0
        public static void Fill(Surface surface, Rect r, int color)
        {
            r = new Rect(r.Left, r.Top, r.Right, r.Bottom);
            r.Clip(surface.Width, surface.Height);

            if (!r.IsValid)
            {
                return;
            }

            int  width     = r.Width;
            int  lineLen   = width;
            int  height    = r.Height;
            bool useMemset = true;

            var bpp = Surface.GetBytesPerPixel(surface.PixelFormat);

            if (bpp == 2)
            {
                lineLen *= 2;
                if ((ushort)color != ((color & 0xff) | (color & 0xff) << 8))
                {
                    useMemset = false;
                }
            }
            else if (bpp == 4)
            {
                useMemset = false;
            }
            else if (bpp != 1)
            {
                throw new InvalidOperationException("Surface::fillRect: bytesPerPixel must be 1, 2, or 4");
            }

            if (useMemset)
            {
                var pn = new PixelNavigator(surface);
                pn.GoTo(r.Left, r.Top);
                for (int i = 0; i < height; i++)
                {
                    pn.Set((byte)color, lineLen);
                    pn.OffsetY(1);
                }
            }
            else
            {
                if (bpp == 2)
                {
                    var pn = new PixelNavigator(surface);
                    pn.GoTo(r.Left, r.Top);
                    for (int i = 0; i < height; i++)
                    {
                        pn.Set((ushort)color, lineLen);
                        pn.OffsetX(surface.Width);
                    }
                }
                else
                {
                    var pn = new PixelNavigator(surface);
                    pn.GoTo(r.Left, r.Top);
                    for (int i = 0; i < height; i++)
                    {
                        pn.Set((uint)color, lineLen);
                        pn.OffsetX(surface.Width / 2);
                    }
                }
            }
        }
示例#24
0
文件: Gdi.cs 项目: scemino/nscumm
        public static void Fill(Surface surface, Rect r, int color)
        {
            r = new Rect(r.Left, r.Top, r.Right, r.Bottom);
            r.Clip(surface.Width, surface.Height);

            if (!r.IsValid)
                return;

            int width = r.Width;
            int lineLen = width;
            int height = r.Height;
            bool useMemset = true;

            var bpp = Surface.GetBytesPerPixel(surface.PixelFormat);
            if (bpp == 2)
            {
                lineLen *= 2;
                if ((ushort)color != ((color & 0xff) | (color & 0xff) << 8))
                    useMemset = false;
            }
            else if (bpp == 4)
            {
                useMemset = false;
            }
            else if (bpp != 1)
            {
                throw new InvalidOperationException("Surface::fillRect: bytesPerPixel must be 1, 2, or 4");
            }

            if (useMemset)
            {
                var pn = new PixelNavigator(surface);
                pn.GoTo(r.Left, r.Top);
                for (int i = 0; i < height; i++)
                {
                    pn.Set((byte)color, lineLen);
                    pn.OffsetY(1);
                }
            }
            else
            {
                if (bpp == 2)
                {
                    var pn = new PixelNavigator(surface);
                    pn.GoTo(r.Left, r.Top);
                    for (int i = 0; i < height; i++)
                    {
                        pn.Set((ushort)color, lineLen);
                        pn.OffsetX(surface.Width);
                    }
                }
                else
                {
                    var pn = new PixelNavigator(surface);
                    pn.GoTo(r.Left, r.Top);
                    for (int i = 0; i < height; i++)
                    {
                        pn.Set((uint)color, lineLen);
                        pn.OffsetX(surface.Width / 2);
                    }
                }
            }
        }
示例#25
0
文件: Gdi.cs 项目: scemino/nscumm
        static void DecompressMaskImgOr(PixelNavigator dst, Stream src, int height)
        {
            byte b, c;

            while (height != 0)
            {
                b = (byte)src.ReadByte();

                if ((b & 0x80) != 0)
                {
                    b &= 0x7F;
                    c = (byte)src.ReadByte();

                    do
                    {
                        dst.Write((byte)(dst.Read() | c));
                        dst.OffsetY(1);
                        --height;
                    } while ((--b != 0) && (height != 0));
                }
                else
                {
                    do
                    {
                        dst.Write((byte)(dst.Read() | src.ReadByte()));
                        dst.OffsetY(1);
                        --height;
                    } while ((--b != 0) && (height != 0));
                }
            }
        }
示例#26
0
        void Proc3Amiga(Codec1 v1)
        {
            byte len;
            int  color;
            bool masked;

            var mask = new PixelNavigator(v1.MaskPtr);

            mask.OffsetX(v1.X / 8);
            var  dst    = new PixelNavigator(v1.DestPtr);
            byte height = (byte)_height;
            byte width  = (byte)_width;

            _loaded.CostumeReader.BaseStream.Seek(_srcptr, System.IO.SeekOrigin.Begin);
            var maskbit        = (byte)ScummHelper.RevBitMask(v1.X & 7);
            var y              = v1.Y;
            var oldXpos        = v1.X;
            var 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.
            var amigaMap =
                (_vm.Game.Platform == Platform.Amiga && _vm.Game.GameId == GameId.Indy4) ? _vm.Gdi.RoomPalette : null;

            do
            {
                len   = _loaded.CostumeReader.ReadByte();
                color = len >> v1.Shr;
                len  &= v1.Mask;
                if (len == 0)
                {
                    len = _loaded.CostumeReader.ReadByte();
                }
                do
                {
                    if (ScaleY == 255 || v1.Scaletable[_scaleIndexY] < ScaleY)
                    {
                        masked = (y < 0 || y >= _h) || (v1.X < 0 || v1.X >= _w) || ((mask.Read() & maskbit) != 0);

                        if (color != 0 && !masked)
                        {
                            byte pcolor;
                            if (amigaMap != null)
                            {
                                pcolor = amigaMap[_palette[color]];
                            }
                            else
                            {
                                pcolor = (byte)_palette[color];
                            }
                            dst.Write(pcolor);
                        }

                        if (ScaleX == 255 || v1.Scaletable[_scaleIndexX] < ScaleX)
                        {
                            v1.X += v1.ScaleXStep;
                            dst.OffsetX(v1.ScaleXStep);
                            maskbit = (byte)ScummHelper.RevBitMask(v1.X & 7);
                        }
                        _scaleIndexX += (byte)v1.ScaleXStep;
                        mask          = new PixelNavigator(v1.MaskPtr);
                        mask.OffsetX(v1.X / 8);
                    }
                    if (--width == 0)
                    {
                        if (--height == 0)
                        {
                            return;
                        }

                        if (y >= _h)
                        {
                            return;
                        }

                        if (v1.X != oldXpos)
                        {
                            dst.Offset(-(v1.X - oldXpos), 1);
                            mask = new PixelNavigator(v1.MaskPtr);
                            mask.OffsetY(1);
                            v1.MaskPtr = mask;
                            mask.OffsetX(oldXpos / 8);
                            maskbit = (byte)ScummHelper.RevBitMask(oldXpos & 7);
                            y++;
                        }
                        width        = (byte)_width;
                        v1.X         = oldXpos;
                        _scaleIndexX = oldScaleIndexX;
                        _scaleIndexY++;
                    }
                } while (--len != 0);
            } while (true);
        }
        protected override void DrawBitsN(Surface s, PixelNavigator dst, IList<byte> src, int srcPos, byte bpp, int drawTop, int width, int height)
        {
//            if (_sjisCurChar)
//            {
//                assert(Vm._cjkFont);
//                Vm._cjkFont.drawChar(Vm._textSurface, _sjisCurChar, _left * Vm._textSurfaceMultiplier, (_top - Vm._screenTop) * Vm._textSurfaceMultiplier, Vm._townsCharsetColorMap[1], _shadowColor);
//                return;
//            }

            bool scale2x = (Vm.TextSurfaceMultiplier == 2);
            dst = new PixelNavigator(Vm.TextSurface);
            dst.GoTo(Left * Vm.TextSurfaceMultiplier, (Top - Vm.ScreenTop) * Vm.TextSurfaceMultiplier);

            int y, x;
            int color;
            byte numbits, bits;

            int pitch = Vm.TextSurface.Pitch - width;

            Debug.Assert(bpp == 1 || bpp == 2 || bpp == 4 || bpp == 8);
            bits = src[srcPos++];
            numbits = 8;
            var cmap = Vm.CharsetColorMap;
            var dst2 = new PixelNavigator(dst);

            if (Vm.Game.Platform == Platform.FMTowns)
                cmap = Vm.TownsCharsetColorMap;
            if (scale2x)
            {
                dst2.OffsetY(1);
                pitch <<= 1;
            }

            for (y = 0; y < height && y + drawTop < Vm.TextSurface.Height; y++)
            {
                for (x = 0; x < width; x++)
                {
                    color = (bits >> (8 - bpp)) & 0xFF;
                    if (color != 0 && y + drawTop >= 0)
                    {
                        dst.Write(cmap[color]);
                        if (scale2x)
                        {
                            dst.Write(1, dst.Read());
                            dst2.Write(dst.Read());
                            dst2.Write(1, dst.Read());
                        }
                    }
                    dst.OffsetX(1);

                    if (scale2x)
                    {
                        dst.OffsetX(1);
                        dst2.OffsetX(2);
                    }

                    bits <<= bpp;
                    numbits -= bpp;
                    if (numbits == 0)
                    {
                        bits = src[srcPos++];
                        numbits = 8;
                    }
                }
                dst.OffsetX(pitch / dst.BytesByPixel);
                dst2.OffsetX(pitch / dst2.BytesByPixel);
            }
        }
示例#28
0
        public void DrawChar(PixelNavigator dst, char c, int x, int y, byte color)
        {
            var width = Math.Min((int)_chars[c].Width, dst.Width - x);
            var height = Math.Min((int)_chars[c].Height, dst.Height - y);
            var src = UnpackChar(c);
            var srcPitch = _chars[c].Width;
            var srcPos = 0;

            var minX = x < 0 ? -x : 0;
            var minY = y < 0 ? -y : 0;

            if (height <= 0 || width <= 0)
            {
                return;
            }

            if (minY != 0)
            {
                srcPos += minY * srcPitch;
                dst.OffsetY(minY);
            }

            for (int ty = minY; ty < height; ty++)
            {
                for (int tx = minX; tx < width; tx++)
                {
                    if (src[srcPos + tx] != _chars[c].Transparency)
                    {
                        if (src[srcPos + tx] == 1)
                        {
                            dst.Write(tx, color);
                        }
                        else
                        {
                            dst.Write(tx, src[srcPos + tx]);
                        }
                    }
                }
                srcPos += srcPitch;
                dst.OffsetY(1);
            }
        }
示例#29
0
文件: Gdi.cs 项目: scemino/nscumm
 static bool NextRow(ref PixelNavigator navDst, ref int x, ref int y, int height)
 {
     navDst.OffsetY(1);
     if (--y == 0)
     { 
         if ((--x) == 0)
             return false; 
         navDst.Offset(1, -height);
         y = height;              
     }               
     return true;
 }
示例#30
0
        protected override void DrawBitsN(Surface s, PixelNavigator dst, IList <byte> src, int srcPos, byte bpp, int drawTop, int width, int height)
        {
//            if (_sjisCurChar)
//            {
//                assert(Vm._cjkFont);
//                Vm._cjkFont.drawChar(Vm._textSurface, _sjisCurChar, _left * Vm._textSurfaceMultiplier, (_top - Vm._screenTop) * Vm._textSurfaceMultiplier, Vm._townsCharsetColorMap[1], _shadowColor);
//                return;
//            }

            bool scale2x = (Vm.TextSurfaceMultiplier == 2);

            dst = new PixelNavigator(Vm.TextSurface);
            dst.GoTo(Left * Vm.TextSurfaceMultiplier, (Top - Vm.ScreenTop) * Vm.TextSurfaceMultiplier);

            int  y, x;
            int  color;
            byte numbits, bits;

            int pitch = Vm.TextSurface.Pitch - width;

            Debug.Assert(bpp == 1 || bpp == 2 || bpp == 4 || bpp == 8);
            bits    = src[srcPos++];
            numbits = 8;
            var cmap = Vm.CharsetColorMap;
            var dst2 = new PixelNavigator(dst);

            if (Vm.Game.Platform == Platform.FMTowns)
            {
                cmap = Vm.TownsCharsetColorMap;
            }
            if (scale2x)
            {
                dst2.OffsetY(1);
                pitch <<= 1;
            }

            for (y = 0; y < height && y + drawTop < Vm.TextSurface.Height; y++)
            {
                for (x = 0; x < width; x++)
                {
                    color = (bits >> (8 - bpp)) & 0xFF;
                    if (color != 0 && y + drawTop >= 0)
                    {
                        dst.Write(cmap[color]);
                        if (scale2x)
                        {
                            dst.Write(1, dst.Read());
                            dst2.Write(dst.Read());
                            dst2.Write(1, dst.Read());
                        }
                    }
                    dst.OffsetX(1);

                    if (scale2x)
                    {
                        dst.OffsetX(1);
                        dst2.OffsetX(2);
                    }

                    bits   <<= bpp;
                    numbits -= bpp;
                    if (numbits == 0)
                    {
                        bits    = src[srcPos++];
                        numbits = 8;
                    }
                }
                dst.OffsetX(pitch / dst.BytesByPixel);
                dst2.OffsetX(pitch / dst2.BytesByPixel);
            }
        }
示例#31
0
文件: Gdi.cs 项目: scemino/nscumm
        void UnkDecode11(PixelNavigator navDst, BinaryReader src, int height)
        {
            int i;
            int buffer = 0, mask = 128;
            int inc = 1;
            int color = src.ReadByte();
		
            int x = 8;
            do
            {
                int h = height;
                do
                {
                    navDst.Write(RoomPalette[color]);
                    navDst.OffsetY(1);
                    for (i = 0; i < 3; i++)
                    {
                        if (!ReadBit256(src, ref mask, ref buffer))
                            break;
                    }
                    switch (i)
                    {
                        case 1:
                            inc = -inc;
                            color -= inc;
                            break;
                        case 2:
                            color -= inc;
                            break;
                        case 3:
                            inc = 1;
                            color = ReadNBits(src, 8, ref mask, ref buffer);
                            break;
                    }
                } while ((--h) != 0);
                navDst.Offset(1, -height);
            } while ((--x) != 0);
        }
示例#32
0
        void Proc3Amiga(Codec1 v1)
        {
            byte len;
            int color;
            bool masked;

            var mask = new PixelNavigator(v1.MaskPtr);
            mask.OffsetX(v1.X / 8);
            var dst = new PixelNavigator(v1.DestPtr);
            byte height = (byte)_height;
            byte width = (byte)_width;
            _loaded.CostumeReader.BaseStream.Seek(_srcptr, System.IO.SeekOrigin.Begin);
            var maskbit = (byte)ScummHelper.RevBitMask(v1.X & 7);
            var y = v1.Y;
            var oldXpos = v1.X;
            var 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.
            var amigaMap = 
                (_vm.Game.Platform == Platform.Amiga && _vm.Game.GameId == GameId.Indy4) ? _vm.Gdi.RoomPalette : null;

            do
            {
                len = _loaded.CostumeReader.ReadByte();
                color = len >> v1.Shr;
                len &= v1.Mask;
                if (len == 0)
                    len = _loaded.CostumeReader.ReadByte();
                do
                {
                    if (ScaleY == 255 || v1.Scaletable[_scaleIndexY] < ScaleY)
                    {
                        masked = (y < 0 || y >= _h) || (v1.X < 0 || v1.X >= _w) || ((mask.Read() & maskbit) != 0);

                        if (color != 0 && !masked)
                        {
                            byte pcolor;
                            if (amigaMap != null)
                                pcolor = amigaMap[_palette[color]];
                            else
                                pcolor = (byte)_palette[color];
                            dst.Write(pcolor);
                        }

                        if (ScaleX == 255 || v1.Scaletable[_scaleIndexX] < ScaleX)
                        {
                            v1.X += v1.ScaleXStep;
                            dst.OffsetX(v1.ScaleXStep);
                            maskbit = (byte)ScummHelper.RevBitMask(v1.X & 7);
                        }
                        _scaleIndexX += (byte)v1.ScaleXStep;
                        mask = new PixelNavigator(v1.MaskPtr);
                        mask.OffsetX(v1.X / 8);
                    }
                    if (--width == 0)
                    {
                        if (--height == 0)
                            return;

                        if (y >= _h)
                            return;

                        if (v1.X != oldXpos)
                        {
                            dst.Offset(-(v1.X - oldXpos), 1);
                            mask = new PixelNavigator(v1.MaskPtr);
                            mask.OffsetY(1);
                            v1.MaskPtr = mask;
                            mask.OffsetX(oldXpos / 8);
                            maskbit = (byte)ScummHelper.RevBitMask(oldXpos & 7);
                            y++;
                        }
                        width = (byte)_width;
                        v1.X = oldXpos;
                        _scaleIndexX = oldScaleIndexX;
                        _scaleIndexY++;
                    }
                } while (--len != 0);
            } while (true);
        }
示例#33
0
        protected void TownsDrawStripToScreen(VirtScreen vs, int dstX, int dstY, int srcX, int srcY, int width, int height)
        {
            if (width <= 0 || height <= 0)
                return;

            int m = _textSurfaceMultiplier;

            var src1 = new PixelNavigator(vs.Surfaces[0]);
            src1.GoTo(vs.XStart + srcX, srcY);
            var src2 = new PixelNavigator(_textSurface);
            src2.GoTo(srcX * m, (srcY + vs.TopLine - ScreenTop) * m);
            var dst1 = new PixelNavigator(_townsScreen.GetLayerPixels(0, dstX, dstY).Value);
            var dst2 = new PixelNavigator(_townsScreen.GetLayerPixels(1, dstX * m, dstY * m).Value);

            int dp1 = _townsScreen.GetLayerPitch(0) - width * _townsScreen.GetLayerBpp(0);
            int dp2 = _townsScreen.GetLayerPitch(1) - width * m * _townsScreen.GetLayerBpp(1);
            int sp1 = vs.Pitch - (width * Surface.GetBytesPerPixel(vs.PixelFormat));
            int sp2 = _textSurface.Pitch - width * m;

            if (vs == MainVirtScreen || Game.GameId == GameId.Indy3 || Game.GameId == GameId.Zak)
            {
                for (int h = 0; h < height; ++h)
                {
                    if (Surface.GetBytesPerPixel(_gfxManager.PixelFormat) == 2)
                    {
                        for (int w = 0; w < width; ++w)
                        {
                            dst1.WriteUInt16(_16BitPalette[src1.Read()]);
                            src1.OffsetX(1);
                            dst1.OffsetX(1);
                        }

                        src1.OffsetX(sp1 / src1.BytesByPixel);
                        dst1.OffsetX(dp1 / dst1.BytesByPixel);
                    }
                    else
                    {
                        for (int i = 0; i < width; i++)
                        {
                            dst1.Write(src1.Read());
                            dst1.OffsetX(1);
                            src1.OffsetX(1);
                        }
                    }

                    for (int sH = 0; sH < m; ++sH)
                    {
                        for (int i = 0; i < width * m; i++)
                        {
                            dst2.Write(src2.Read());
                            src2.OffsetX(1);
                            dst2.OffsetX(1);
                        }
                        src2.OffsetX(_textSurface.Width - (width * m));
                        dst2.OffsetX(dst2.Width - (width * m));
                    }
                }
            }
            else
            {
                dst1 = new PixelNavigator(dst2);
                for (int h = 0; h < height; ++h)
                {
                    for (int w = 0; w < width; ++w)
                    {
                        var t = (src1.Read()) & 0x0f;
                        src1.OffsetX(1);
                        for (int i = 0; i < m; i++)
                        {
                            dst1.Write((byte)((t << 4) | t));
                            dst1.OffsetX(1);
                        }
                    }

                    dst1 = new PixelNavigator(dst2);
                    var src3 = new PixelNavigator(src2);

                    if (m == 2)
                    {
                        dst2.OffsetY(1);
                        src3.OffsetY(1);
                    }

                    for (int w = 0; w < width * m; ++w)
                    {
                        dst2.Write((byte)(src3.Read() | dst1.Read() & _townsLayer2Mask[src3.Read()]));
                        dst2.OffsetX(1);
                        dst1.Write((byte)(src2.Read() | dst1.Read() & _townsLayer2Mask[src2.Read()]));
                        src2.OffsetX(1);
                        src3.OffsetX(1);
                        dst1.OffsetX(1);
                    }

                    src1.OffsetX(sp1 / src1.BytesByPixel);
                    src2 = new PixelNavigator(src3);
                    src2.OffsetX(sp2 / src2.BytesByPixel);
                    dst1 = new PixelNavigator(dst2);
                    dst1.OffsetX(dp2 / dst1.BytesByPixel);
                    dst2.OffsetX(dp2 / dst2.BytesByPixel);
                }
            }

            _townsScreen.AddDirtyRect(dstX * m, dstY * m, width * m, height * m);
        }
示例#34
0
        void Akos16Decompress(PixelNavigator dest, int srcPos, int t_width, int t_height, int dir,
                              int numskip_before, int numskip_after, byte transparency, int maskLeft, int maskTop, int zBuf)
        {
            var tmp_buf = _akos16.Buffer;
            var tmp_pos = 0;
            var maskbit = (byte)ScummHelper.RevBitMask(maskLeft & 7);

            if (dir < 0)
            {
                dest.OffsetX(-(t_width - 1));
                tmp_pos += (t_width - 1);
            }

            Akos16SetupBitReader(srcPos);

            if (numskip_before != 0)
            {
                Akos16SkipData(numskip_before);
            }

            var maskptr = _vm.GetMaskBuffer(maskLeft, maskTop, zBuf);

            Debug.Assert(t_height > 0);
            Debug.Assert(t_width > 0);
            while ((t_height--) != 0)
            {
                Akos16DecodeLine(tmp_buf, tmp_pos, t_width, dir);
                BompDrawData.BompApplyMask(_akos16.Buffer, 0, maskptr, maskbit, t_width, transparency);
                BompDrawData.BompApplyShadow(ShadowMode, ShadowTable, _akos16.Buffer, 0, dest, t_width, transparency);

                if (numskip_after != 0)
                {
                    Akos16SkipData(numskip_after);
                }
                dest.OffsetY(1);
                maskptr.OffsetY(1);
            }
        }
示例#35
0
        protected override void DrawBits1(Surface dest, int x, int y, BinaryReader src, int drawTop, int width, int height)
        {
            if (_sjisCurChar != 0)
            {
//                Debug.Assert(Vm._cjkFont);
//                Vm._cjkFont.drawChar(dest, _sjisCurChar, x, y, _color, _shadowColor);
                return;
            }
            bool scale2x = ((dest == Vm.TextSurface) && (Vm.TextSurfaceMultiplier == 2) /*&& !(_sjisCurChar >= 256 && Vm.UseCJKMode)*/);

            byte bits = 0;
            var col = Color;
            var bpp = Surface.GetBytesPerPixel(dest.PixelFormat);
            int pitch = dest.Pitch - width * bpp;
            var dst = new PixelNavigator(dest);
            dst.GoTo(x, y);
            var dst2 = new PixelNavigator(dst);
            dst2.OffsetY(1);

            var dst3 = new PixelNavigator(dst2);
            var dst4 = new PixelNavigator(dst2);
            if (scale2x)
            {
                dst3.OffsetY(1);
                dst4.OffsetY(1);
                pitch <<= 1;
            }

            for (y = 0; y < height && y + drawTop < dest.Height; y++)
            {
                for (x = 0; x < width; x++)
                {
                    if ((x % 8) == 0)
                        bits = src.ReadByte();
                    if (((bits & ScummHelper.RevBitMask(x % 8)) != 0) && y + drawTop >= 0)
                    {
                        if (bpp == 2)
                        {
                            if (_enableShadow)
                            {
                                dst.WriteUInt16(2, Vm._16BitPalette[_shadowColor]);
                                dst.WriteUInt16(2 + dest.Pitch, Vm._16BitPalette[_shadowColor]);
                            }
                            dst.WriteUInt16(Vm._16BitPalette[Color]);
                        }
                        else
                        {
                            if (_enableShadow)
                            {
                                if (scale2x)
                                {
                                    dst.Write(2, _shadowColor);
                                    dst.Write(3, _shadowColor);
                                    dst2.Write(2, _shadowColor);
                                    dst2.Write(3, _shadowColor);

                                    dst3.Write(0, _shadowColor);
                                    dst3.Write(1, _shadowColor);
                                    dst4.Write(0, _shadowColor);
                                    dst4.Write(0, _shadowColor);
                                }
                                else
                                {
                                    dst2.Write(_shadowColor);
                                    dst.Write(1, _shadowColor);
                                }
                            }
                            dst.Write(col);

                            if (scale2x)
                            {
                                dst.Write(1, col);
                                dst2.Write(0, col);
                                dst2.Write(1, col);
                            }
                        }
                    }
                    dst.OffsetX(1);
                    dst2.OffsetX(1);
                    if (scale2x)
                    {
                        dst.OffsetX(1);
                        dst2.OffsetX(1);
                        dst3.OffsetX(1);
                        dst4.OffsetX(1);
                    }
                }

                dst.OffsetX(pitch / dst.BytesByPixel);
                dst2.OffsetX(pitch / dst2.BytesByPixel);
                dst3.OffsetX(pitch / dst3.BytesByPixel);
                dst4.OffsetX(pitch / dst4.BytesByPixel);
            }
        }
示例#36
0
        public void DrawBomp()
        {
            Rect clip;
            byte skip_y_bits = 0x80;
            byte skip_y_new  = 0;

            byte[] bomp_scaling_x = new byte[64];
            byte[] bomp_scaling_y = new byte[64];

            if (X < 0)
            {
                clip.Left = -X;
            }
            else
            {
                clip.Left = 0;
            }

            if (Y < 0)
            {
                clip.Top = -Y;
            }
            else
            {
                clip.Top = 0;
            }

            clip.Right = Width;
            if (clip.Right > Dst.Width - X)
            {
                clip.Right = Dst.Width - X;
            }

            clip.Bottom = Height;
            if (clip.Bottom > Dst.Height - Y)
            {
                clip.Bottom = Dst.Height - Y;
            }

            var src = Src;
            var pn  = new PixelNavigator(Dst);

            pn.GoTo(X + clip.Left, Y);

            var            maskbit = ScummHelper.RevBitMask((X + clip.Left) & 7);
            PixelNavigator maskPtr = new PixelNavigator();

            // Mask against any additionally imposed mask
            if (MaskPtr.HasValue)
            {
                maskPtr = MaskPtr.Value;
                maskPtr.GoTo((X + clip.Left) / 8, Y);
            }

            var scalingYPtr = 0;

            // Setup vertical scaling
            if (ScaleY != 255)
            {
                var scaleBottom = SetupBompScale(bomp_scaling_y, Height, ScaleY);

                skip_y_new  = bomp_scaling_y[scalingYPtr++];
                skip_y_bits = 0x80;

                if (clip.Bottom > scaleBottom)
                {
                    clip.Bottom = scaleBottom;
                }
            }

            // Setup horizontal scaling
            if (ScaleX != 255)
            {
                var scaleRight = SetupBompScale(bomp_scaling_x, Width, ScaleX);

                if (clip.Right > scaleRight)
                {
                    clip.Right = scaleRight;
                }
            }

            var width = clip.Right - clip.Left;

            if (width <= 0)
            {
                return;
            }

            int pos_y       = 0;
            var line_buffer = new byte[1024];

            byte tmp;

            using (var br = new BinaryReader(new MemoryStream(src)))
            {
                // Loop over all lines
                while (pos_y < clip.Bottom)
                {
                    br.ReadUInt16();
                    // Decode a single (bomp encoded) line, reversed if we are in mirror mode
                    if (Mirror)
                    {
                        BompDecodeLineReverse(br, line_buffer, 0, Width);
                    }
                    else
                    {
                        // Decode a single (bomp encoded) line
                        BompDecodeLine(br, line_buffer, 0, Width);
                    }

                    // If vertical scaling is enabled, do it
                    if (ScaleY != 255)
                    {
                        // A bit set means we should skip this line...
                        tmp = (byte)(skip_y_new & skip_y_bits);

                        // Advance the scale-skip bit mask, if it's 0, get the next scale-skip byte
                        skip_y_bits /= 2;
                        if (skip_y_bits == 0)
                        {
                            skip_y_bits = 0x80;
                            skip_y_new  = bomp_scaling_y[scalingYPtr++];
                        }

                        // Skip the current line if the above check tells us to
                        if (tmp != 0)
                        {
                            continue;
                        }
                    }

                    // Perform horizontal scaling
                    if (ScaleX != 255)
                    {
                        BompScaleFuncX(line_buffer, bomp_scaling_x, 0, 0x80, Width);
                    }

                    // The first clip.top lines are to be clipped, i.e. not drawn
                    if (clip.Top > 0)
                    {
                        clip.Top--;
                    }
                    else
                    {
                        // Replace the parts of the line which are masked with the transparency color
                        if (MaskPtr.HasValue)
                        {
                            BompApplyMask(line_buffer, clip.Left, maskPtr, (byte)maskbit, width, 255);
                        }

                        // Apply custom color map, if available
                        if (ActorPalette != null)
                        {
                            BompApplyActorPalette(ActorPalette, line_buffer, clip.Left, width);
                        }

                        // Finally, draw the decoded, scaled, masked and recolored line onto
                        // the target surface, using the specified shadow mode
                        BompApplyShadow(ShadowMode, ShadowPalette, line_buffer, clip.Left, pn, width, 255);
                    }

                    // Advance to the next line
                    pos_y++;
                    if (MaskPtr.HasValue)
                    {
                        maskPtr.OffsetY(1);
                    }
                    pn.OffsetY(1);
                }
            }
        }
示例#37
0
        static void DecompressMaskImg(PixelNavigator dst, Stream src, int height)
        {
            while (height != 0)
            {
                var b = (byte)src.ReadByte();

                if ((b & 0x80) != 0)
                {
                    b &= 0x7F;
                    var c = (byte)src.ReadByte();

                    do
                    {
                        dst.Write(c);
                        dst.OffsetY(1);
                        --height;
                    } while (--b != 0 && height != 0);
                }
                else
                {
                    do
                    {
                        dst.Write((byte)src.ReadByte());
                        dst.OffsetY(1);
                        --height;
                    } while (--b != 0 && height != 0);
                }
            }
        }
示例#38
0
 protected virtual void DrawBits1(Surface surface, int x, int y, BinaryReader src, int drawTop, int width, int height)
 {
     var dst = new PixelNavigator(surface);
     dst.GoTo(x, y);
     
     byte bits = 0;
     byte col = Color;
     //int pitch = surface.Pitch - width * surface.BytesPerPixel;
     var dst2 = new PixelNavigator(dst);
     dst2.OffsetY(1);
     
     for (y = 0; y < height && y + drawTop < surface.Height; y++)
     {
         for (x = 0; x < width; x++)
         {
             if ((x % 8) == 0)
                 bits = src.ReadByte();
             if ((bits & ScummHelper.RevBitMask(x % 8)) != 0 && y + drawTop >= 0)
             {
                 if (_shadowMode)
                 {
                     dst.OffsetX(1);
                     dst.Write(_shadowColor);
                     dst2.Write(_shadowColor);
                     dst2.OffsetX(1);
                     dst2.Write(_shadowColor);
                 }
                 dst.Write(col);
             }
             dst.OffsetX(1);
             dst2.OffsetX(1);
         }
     
         dst.OffsetX(surface.Width - width);
         dst2.OffsetX(surface.Width - width);
     }
 }
示例#39
0
文件: Gdi1.cs 项目: scemino/nscumm
        void DrawStripV1Background(PixelNavigator navDst, int stripnr, int height)
        {
            int charIdx;
            height /= 8;
            for (int y = 0; y < height; y++)
            {
                _v1.Colors[3] = (byte)(_v1.ColorMap[y + stripnr * height] & 7);
                // Check for room color change in V1 zak
                if (RoomPalette[0] == 255)
                {
                    _v1.Colors[2] = RoomPalette[2];
                    _v1.Colors[1] = RoomPalette[1];
                }

                charIdx = _v1.PicMap[y + stripnr * height] * 8;
                for (int i = 0; i < 8; i++)
                {
                    byte c = _v1.CharMap[charIdx + i];
                    var color = _v1.Colors[(c >> 6) & 3];
                    navDst.Write(0, color);
                    navDst.Write(1, color);
                    color = _v1.Colors[(c >> 4) & 3];
                    navDst.Write(2, color);
                    navDst.Write(3, color);
                    color = _v1.Colors[(c >> 2) & 3];
                    navDst.Write(4, color);
                    navDst.Write(5, color);
                    color = _v1.Colors[(c >> 0) & 3];
                    navDst.Write(6, color);
                    navDst.Write(7, color);
                    navDst.OffsetY(1);
                }
            }
        }