Пример #1
0
 protected override void PrepareDrawBitmap(ImageData img, VirtScreen vs,
                                           Point p, int width, int height,
                                           int stripnr, int numstrip)
 {
     if (_objectMode)
     {
         var imgData = (ImageData1)img;
         objectMap = imgData.ObjectMap;
     }
 }
Пример #2
0
 public virtual ImageData Clone()
 {
     var data = new ImageData{ IsBomp = IsBomp };
     data.Data = new byte[Data.Length];
     Array.Copy(Data, data.Data, Data.Length);
     foreach (var zplane in ZPlanes)
     {
         data.ZPlanes.Add(zplane.Clone());
     }
     return data;
 }
Пример #3
0
        byte[] GrabPixels(ImageData im, int w, int h)
        {
            // Backup the screen content
            var backup = (byte[])MainVirtScreen.Surfaces[0].Pixels.Clone();

            // Do some drawing
            DrawBox(0, 0, w - 1, h - 1, 0xFF);

            MainVirtScreen.HasTwoBuffers = false;
            Gdi.IsZBufferEnabled = false;
            Gdi.DrawBitmap(im, MainVirtScreen, _screenStartStrip, 0, w, h, 0, w / 8, MainVirtScreen.Width, DrawBitmaps.None);
            MainVirtScreen.HasTwoBuffers = true;
            Gdi.IsZBufferEnabled = true;

            // Grab the data we just drew and setup the cursor with it
            var pixels = Capture(MainVirtScreen, MainVirtScreen.XStart, 0, w, h);

            // Restore the screen content
            Array.Copy(backup, MainVirtScreen.Surfaces[0].Pixels, backup.Length);

            return pixels;
        }
Пример #4
0
 ImageData ReadImage(Stream stream, int numStrips)
 {
     var br = new BinaryReader(stream);
     var img = new ImageData();
     var size = br.ReadInt32();
     br.BaseStream.Seek(-4, SeekOrigin.Current);
     if (size != 0)
     {
         img.Data = br.ReadBytes(size + 2);
         br.BaseStream.Seek(-2, SeekOrigin.Current);
         size = br.ReadUInt16();
         if (br.BaseStream.Position == br.BaseStream.Length)
         {
             size = 0;
         }
     }
     while (size != 0 && img.ZPlanes.Count < 3)
     {
         var zPlane = ReadZPlane(br, size, numStrips);
         img.ZPlanes.Add(zPlane);
         size = 0;
         br.BaseStream.Seek(-2, SeekOrigin.Current);
         if ((br.BaseStream.Position + 2) < br.BaseStream.Length)
         {
             size = br.ReadUInt16();
         }
     }
     return img;
 }
Пример #5
0
 protected ImageData ReadImage(long size, int numStrips)
 {
     var img = new ImageData();
     var it = CreateChunkIterator(size);
     while (it.MoveNext())
     {
         if (it.Current.Tag == "SMAP")
         {
             img.Data = _reader.ReadBytes((int)(it.Current.Size));
         }
         else if (it.Current.Tag.StartsWith("ZP", StringComparison.Ordinal))
         {
             var zpNum = int.Parse(it.Current.Tag.Substring(2), System.Globalization.NumberStyles.HexNumber);
             ZPlane zplane;
             using (var ms = new MemoryStream(_reader.ReadBytes((int)(it.Current.Size))))
             {
                 var br = new BinaryReader(ms);
                 zplane = ReadZPlane(br, (int)(it.Current.Size), numStrips);
             }
             img.ZPlanes.Add(zplane);
         }
         else if (it.Current.Tag == "BOMP")
         {
             img = ReadBomp(it.Current.Size - 8);
         }
         else
         {
             UnknownChunk(it.Current);
         }
     }
     return img;
 }
Пример #6
0
 protected IList<ImageData> ReadImages(long size)
 {
     var images = new List<ImageData>();
     var it = CreateChunkIterator(size);
     while (it.MoveNext())
     {
         if (it.Current.Tag == "WRAP")
         {
             it = CreateChunkIterator(it.Current.Size);
         }
         else if (it.Current.Tag == "OFFS")
         {
             // skip it
         }
         else if (it.Current.Tag == "BOMP")
         {
             var img = ReadBomp(it.Current.Size - 8);
             images.Add(img);
         }
         else if (it.Current.Tag == "OBIM")
         {
             // Object Image
             var obj = ReadObjectImages(it.Current.Size - 8);
             images.AddRange(obj.Images);
         }
         else if (it.Current.Tag == "SMAP")
         {
             var img = new ImageData();
             img.Data = _reader.ReadBytes((int)(it.Current.Size - 8));
             images.Add(img);
         }
         else
         {
             UnknownChunk(it.Current);
         }
     }
     return images;
 }
Пример #7
0
 protected virtual ImageData ReadBomp(long size)
 {
     var id = _reader.ReadUInt16();
     var width = _reader.ReadUInt16();
     var height = _reader.ReadUInt16();
     var padding = _reader.ReadUInt32();
     var img = new ImageData();
     img.Data = _reader.ReadBytes((int)(size - 10));
     img.IsBomp = true;
     return img;
 }
Пример #8
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++];
            }
        }
Пример #9
0
 public Room()
 {
     Boxes = new List<Box>();
     Objects = new List<ObjectData>();
     BoxMatrix = new List<byte>();
     EntryScript = new ScriptData();
     ExitScript = new ScriptData();
     LocalScripts = new ScriptData[1024];
     TransparentColor = 255;
     Scales = new ScaleSlot[0];
     ColorCycle = new ColorCycle[16];
     for (int i = 0; i < ColorCycle.Length; i++)
     {
         ColorCycle[i] = new ColorCycle();
     }
     Image = new ImageData();
     Palettes = new List<Palette>();
     Palettes.Add(new Palette());
 }
Пример #10
0
 protected override ImageData ReadBomp(long size)
 {
     var width = _reader.ReadUInt32();
     var height = _reader.ReadUInt32();
     var img = new ImageData();
     img.Data = _reader.ReadBytes((int)(size - 8));
     img.IsBomp = true;
     return img;
 }
Пример #11
0
 protected virtual void PrepareDrawBitmap(ImageData img, VirtScreen vs,
                                          Point p, int width, int height,
                                          int stripnr, int numstrip)
 {
 }
Пример #12
0
        public void DrawBitmap(ImageData img, VirtScreen vs, Point p, int width, int height, int stripnr, int numstrip, int roomWidth, DrawBitmaps flags, bool isLightOn)
        {
            var x = p.X;
            var y = p.Y;
            if ((_vm.TownsPaletteFlags & 2) != 0)
            {
                int cx = (x - _vm.ScreenStartStrip) << 3;
                Gdi.Fill(_vm.TextSurface, 
                    new Rect(cx * _vm.TextSurfaceMultiplier, y * _vm.TextSurfaceMultiplier, 
                        (cx + width - 1) * _vm.TextSurfaceMultiplier, (y + height - 1) * _vm.TextSurfaceMultiplier), 0);
            }

            _objectMode = flags.HasFlag(DrawBitmaps.ObjectMode);
            PrepareDrawBitmap(img, vs, p, width, height, stripnr, numstrip);

            int sx = x - vs.XStart / 8;
            if (sx < 0)
            {
                numstrip -= -sx;
                x += -sx;
                stripnr += -sx;
                sx = 0;
            }

            // Compute the number of strips we have to iterate over.
            // TODO/FIXME: The computation of its initial value looks very fishy.
            // It was added as a kind of hack to fix some corner cases, but it compares
            // the room width to the virtual screen width; but the former should always
            // be bigger than the latter (except for MM NES, maybe)... strange
            int limit = Math.Max(roomWidth, vs.Width) / 8 - x;
            if (limit > numstrip)
                limit = numstrip;
            if (limit > NumStrips - sx)
                limit = NumStrips - sx;

            for (int k = 0; k < limit; ++k, ++stripnr, ++sx, ++x)
            {
                if (y < vs.TDirty[sx])
                    vs.TDirty[sx] = y;

                if (y + height > vs.BDirty[sx])
                    vs.BDirty[sx] = y + height;

                // In the case of a double buffered virtual screen, we draw to
                // the backbuffer, otherwise to the primary surface memory.
                var surface = vs.HasTwoBuffers ? vs.Surfaces[1] : vs.Surfaces[0];
                var navDst = new PixelNavigator(surface);
                navDst.GoTo(x * 8, y);

                bool transpStrip;
                using (var smapReader = new BinaryReader(new MemoryStream(img.Data)))
                {
                    transpStrip = DrawStrip(navDst, width, height, stripnr, smapReader);
                }

                // COMI and HE games only uses flag value
                if (game.Version == 8)
                    transpStrip = true;

                if (vs.HasTwoBuffers)
                {
                    var navFrontBuf = new PixelNavigator(vs.Surfaces[0]);
                    navFrontBuf.GoTo(x * 8, y);
                    if (isLightOn)
                        Copy8Col(navFrontBuf, navDst, height);
                    else
                        Clear8Col(navFrontBuf, height);
                }

                DecodeMask(x, y, width, height, stripnr, img.ZPlanes, transpStrip, flags);
            }
        }
Пример #13
0
 public void DrawBitmap(ImageData img, VirtScreen vs, int x, int y, int width, int height, int stripnr, int numstrip, int roomWidth, DrawBitmaps flags)
 {
     // Check whether lights are turned on or not
     var lightsOn = _vm.IsLightOn();
     DrawBitmap(img, vs, new Point(x, y), width, height, stripnr, numstrip, roomWidth, flags, lightsOn);
 }