Esempio n. 1
0
        private bool HandleMouseMove(int pxX, int pxY, Toolbox.ToolType tool)
        {
            if (m_sprite == null || pxX < 0 || pxY < 0)
            {
                return(false);
            }

            // Convert screen pixel (x,y) to sprite pixel index (x,y).
            int pxSpriteX = pxX / BigBitmapPixelSize;
            int pxSpriteY = pxY / BigBitmapPixelSize;

            // Ignore if pixel is outside bounds of current sprite.
            if (pxSpriteX >= m_sprite.PixelWidth || pxSpriteY >= m_sprite.PixelHeight)
            {
                return(false);
            }

            if (tool == Toolbox.ToolType.FloodFill)
            {
                return(m_sprite.FloodFillClick(pxSpriteX, pxSpriteY));
            }

            // Convert sprite pixel coords (x,y) into tile index (x,y) and tile pixel coords (x,y).
            int tileX   = pxSpriteX / Tile.TileSize;
            int pxTileX = pxSpriteX % Tile.TileSize;
            int tileY   = pxSpriteY / Tile.TileSize;
            int pxTileY = pxSpriteY % Tile.TileSize;

            int     nTileIndex = (tileY * m_sprite.TileWidth) + tileX;
            Palette p          = m_parent.ActivePalette();

            if (tool == Toolbox.ToolType.Eyedropper)
            {
                int nCurrColor = m_sprite.GetPixel(pxSpriteX, pxSpriteY);
                if (nCurrColor == p.CurrentColor())
                {
                    return(false);
                }
                p.SetCurrentColor(nCurrColor);
                return(true);
            }

            Tile t      = m_sprite.GetTile(nTileIndex);
            int  nColor = (tool == Toolbox.ToolType.Eraser ? 0 : p.CurrentColor());

            // Same color - no need to update.
            if (t.GetPixel(pxTileX, pxTileY) == nColor)
            {
                return(false);
            }

            // Set the new color.
            t.SetPixel(pxTileX, pxTileY, nColor);

            return(true);
        }
Esempio n. 2
0
        public void Test_AddSprite_draw_redo()
        {
            Sprite s = m_ss.AddSprite(1, 1, "sample", 0, "", 0, m_mgr);

            Assert.IsNotNull(s);
            Assert.AreEqual(1, m_mgr.Count);
            Assert.AreEqual(0, m_mgr.Current);
            Assert.IsTrue(m_mgr.CanUndo());
            Assert.IsFalse(m_mgr.CanRedo());

            // Draw a pixel.
            int x1 = 3, y1 = 4;
            int color1 = 1;

            s.SetPixel(x1, y1, color1);
            Assert.AreEqual(color1, s.GetPixel(x1, y1));
            s.RecordUndoAction("pencil1", m_mgr);
            Assert.AreEqual(2, m_mgr.Count);
            Assert.AreEqual(1, m_mgr.Current);
            UndoAction_SpriteEdit u1 = m_mgr.GetCurrent() as UndoAction_SpriteEdit;

            Assert.AreEqual(0, u1.Before.tiles[0].pixels[x1, y1]);
            Assert.AreEqual(color1, u1.After.tiles[0].pixels[x1, y1]);
            Assert.IsTrue(m_mgr.CanUndo());
            Assert.IsFalse(m_mgr.CanRedo());

            // Undo the pixel draw.
            m_mgr.ApplyUndo();
            Assert.AreEqual(2, m_mgr.Count);
            Assert.AreEqual(0, m_mgr.Current);
            // Pencil mark reverted.
            Assert.AreEqual(0, s.GetPixel(x1, y1));
            Assert.IsTrue(m_mgr.CanUndo());
            Assert.IsTrue(m_mgr.CanRedo());

            // Redo the pixel draw.
            m_mgr.ApplyRedo();
            Assert.AreEqual(2, m_mgr.Count);
            Assert.AreEqual(1, m_mgr.Current);
            Assert.AreEqual(color1, s.GetPixel(x1, y1));
            Assert.IsTrue(m_mgr.CanUndo());
            Assert.IsFalse(m_mgr.CanRedo());
        }
Esempio n. 3
0
        private int[] CalcMask(Sprite s, out int width, out int height)
        {
            width  = 0;
            height = 0;
            if (s == null)
            {
                return(null);
            }
            // Calc # of int32s required.
            int xsize = ((s.PixelWidth + MaskWordWidth - 1) / MaskWordWidth);
            int ysize = s.PixelHeight;
            int size  = xsize * ysize;

            int[] mask = new int[size];

            for (int y = 0; y < ysize; y++)
            {
                for (int x = 0; x < xsize; x++)
                {
                    int index = y * xsize + x;
                    mask[index] = 0;
                    for (int i = 0; i < MaskWordWidth; i++)
                    {
                        mask[index] <<= 1;
                        if (x * MaskWordWidth + i < s.PixelWidth)
                        {
                            if (s.GetPixel(x * MaskWordWidth + i, y) != 0)
                            {
                                mask[index] |= 1;
                            }
                        }
                    }
                }
            }
            width  = xsize;
            height = ysize;
            return(mask);
        }
Esempio n. 4
0
        //    +----------+         -
        //    |A         |         | y offset
        //    |     +---------+    -
        //    |     |B        |
        //    |     |         |
        //    +-----|         |
        //          |         |
        //          +---------+
        //
        //    |-----|
        //       x offset

        private bool CollisionCheck()
        {
            if (s2 == null)
            {
                return(false);
            }

            StringBuilder sb = new StringBuilder();

            if (xOffset >= s1.PixelWidth || yOffset >= s1.PixelHeight ||
                -xOffset >= s2.PixelWidth || -yOffset >= s2.PixelHeight)
            {
                tbInfo.Text = "BBoxes don't overlap";
                return(false);
            }

            // Calculate the intersection rect in the local coord system
            // of each sprite.
            int s1x = xOffset >= 0 ? xOffset : 0;
            int s1y = yOffset >= 0 ? yOffset : 0;
            int s2x = xOffset < 0 ? -xOffset : 0;
            int s2y = yOffset < 0 ? -yOffset : 0;

            sb.Append(String.Format("offset: {0},{1}\r\n", xOffset, yOffset));

            int w, h;

            if (xOffset >= 0)
            {
                w = min(s2.PixelWidth, s1.PixelWidth - s1x);
            }
            else
            {
                w = min(s1.PixelWidth, s2.PixelWidth - s2x);
            }
            if (yOffset >= 0)
            {
                h = min(s2.PixelHeight, s1.PixelHeight - s1y);
            }
            else
            {
                h = min(s1.PixelHeight, s2.PixelHeight - s2y);
            }
            sb.Append(String.Format("s1 size: {0},{1}\r\n", s1.PixelWidth, s1.PixelHeight));
            sb.Append(String.Format("s2 size: {0},{1}\r\n", s2.PixelWidth, s2.PixelHeight));
            sb.Append(String.Format("overlap: {0},{1}\r\n", w, h));

            // Slow but sure method to use for verification.
            int  verify_count = 0;
            bool fFirst       = true;

            for (int x = 0; x < w; x++)
            {
                for (int y = 0; y < h; y++)
                {
                    if (s1.GetPixel(s1x + x, s1y + y) != 0 &&
                        s2.GetPixel(s2x + x, s2y + y) != 0)
                    {
                        if (fFirst)
                        {
                            sb.Append(String.Format("Hit at {0},{1}\r\n", x, y));
                        }
                        fFirst = false;
                        verify_count++;
                        tbInfo.Text = sb.ToString();
                    }
                }
            }
            sb.Append(String.Format("count: {0}\r\n", verify_count));

            // Run bitmask based collision check.
            // Assumes bitmasks are padded out with 0's to a MaskWidth boundary
            // General approach is to:
            //   calculate the bitmask overlap area
            //   for each line:
            //     for each bitmask:
            //       shift bits in A so that they align with B
            //       if shited-A & B != 0:
            //         we have a collision
            //
            // Shifting the masks to align is the only tricky part.
            int[] a_mask, b_mask;
            int   a_maskw, a_maskh;
            int   b_maskw, b_maskh;
            int   x_offset, y_offset;

            if (xOffset >= 0)
            {
                a_mask   = mask1;
                a_maskw  = mask1w;
                a_maskh  = mask1h;
                b_mask   = mask2;
                b_maskw  = mask2w;
                b_maskh  = mask2h;
                x_offset = xOffset;
                y_offset = yOffset;
            }
            else
            {
                a_mask   = mask2;
                a_maskw  = mask2w;
                a_maskh  = mask2h;
                b_mask   = mask1;
                b_maskw  = mask1w;
                b_maskh  = mask1h;
                x_offset = -xOffset;
                y_offset = -yOffset;
            }

            int a_lshift = x_offset % MaskWordWidth;
            int a_maskword_offset = x_offset / MaskWordWidth;
            int maskword_count = (w + MaskWordWidth - 1) / MaskWordWidth;
            int a_x0, b_x0;
            int a_xN;

            if (y_offset >= 0)
            {
                a_x0 = (y_offset * a_maskw) + a_maskword_offset;
                a_xN = a_maskw - (y_offset * a_maskw);
                b_x0 = 0;
            }
            else
            {
                a_x0 = a_maskword_offset;
                a_xN = a_maskw;
                b_x0 = (-y_offset * b_maskw);
            }

            bool fFirstMessage = true;
            int  count         = 0;

            if (a_lshift == 0)
            {
                sb.Append("PP checking mask aligned\r\n");
                // offset is aligned to maskwidth boundary - no bit shifting needed
                for (int x = 0; x < maskword_count; x++)
                {
                    for (int y = 0; y < h; y++)
                    {
                        if ((a_mask[a_x0 + x] & b_mask[b_x0 + x]) != 0)
                        {
                            if (fFirstMessage)
                            {
                                sb.Append("PP found collision\r\n");
                            }
                            fFirstMessage = false;
                            count         = 1;
                        }
                        a_x0 += a_maskw;
                        b_x0 += b_maskw;
                    }
                }
            }
            else
            {
                sb.Append("PP checking mask shifted\r\n");
                int a_rshift = MaskWordWidth - a_lshift;
                for (int x = 0; x < maskword_count; x++)
                {
                    for (int y = 0; y < h; y++)
                    {
                        int a = a_mask[a_x0 + x] << a_lshift;
                        if (x + 1 < a_xN)
                        {
                            a |= a_mask[a_x0 + x + 1] >> a_rshift;
                        }
                        if ((a & b_mask[b_x0 + x]) != 0)
                        {
                            if (fFirstMessage)
                            {
                                sb.Append("PP found collision\r\n");
                            }
                            fFirstMessage = false;
                            count         = 1;
                        }
                        a_x0 += a_maskw;
                        b_x0 += b_maskw;
                    }
                }
            }

            bool fCollision = verify_count != 0;

            lResult.Text = fCollision ? "Collision" : "No collision";
            tbInfo.Text  = sb.ToString();

            if (!((count == 0 && verify_count == 0) || (count != 0 && verify_count != 0)))
            {
                lResult.Text = "ERROR! no match";
            }

            return(fCollision);
        }
Esempio n. 5
0
        private int[] CalcMask(Sprite s, out int width, out int height)
        {
            width = 0;
            height = 0;
            if (s == null)
                return null;
            // Calc # of int32s required.
            int xsize = ((s.PixelWidth + MaskWordWidth-1) / MaskWordWidth);
            int ysize = s.PixelHeight;
            int size = xsize * ysize;
            int[] mask = new int[size];

            for (int y = 0; y < ysize; y++)
            {
                for (int x = 0; x < xsize; x++)
                {
                    int index = y * xsize + x;
                    mask[index] = 0;
                    for (int i = 0; i < MaskWordWidth; i++)
                    {
                        mask[index] <<= 1;
                        if (x * MaskWordWidth + i < s.PixelWidth)
                        {
                            if (s.GetPixel(x * MaskWordWidth + i, y) != 0)
                                mask[index] |= 1;
                        }
                    }
                }
            }
            width = xsize;
            height = ysize;
            return mask;
        }
Esempio n. 6
0
        public void Test_AddSprite_draw_undo()
        {
            Sprite s = m_ss.AddSprite(1, 1, "sample", 0, "", 0, m_mgr);

            Assert.IsNotNull(s);
            Assert.AreEqual(1, m_mgr.Count);
            Assert.AreEqual(0, m_mgr.Current);
            Assert.IsTrue(m_mgr.CanUndo());
            Assert.IsFalse(m_mgr.CanRedo());

            // Draw a pixel.
            int x1 = 3, y1 = 4;
            int color1 = 1;

            s.SetPixel(x1, y1, color1);
            Assert.AreEqual(color1, s.GetPixel(x1, y1));
            s.RecordUndoAction("pencil1", m_mgr);
            Assert.AreEqual(2, m_mgr.Count);
            Assert.AreEqual(1, m_mgr.Current);
            UndoAction_SpriteEdit u1 = m_mgr.GetCurrent() as UndoAction_SpriteEdit;

            Assert.AreEqual(0, u1.Before.tiles[0].pixels[x1, y1]);
            Assert.AreEqual(color1, u1.After.tiles[0].pixels[x1, y1]);
            Assert.IsTrue(m_mgr.CanUndo());
            Assert.IsFalse(m_mgr.CanRedo());

            // Draw another pixel.
            int x2 = 4, y2 = 5;
            int color2 = 2;

            s.SetPixel(x2, y2, color2);
            Assert.AreEqual(color2, s.GetPixel(x2, y2));
            s.RecordUndoAction("pencil2", m_mgr);
            Assert.AreEqual(3, m_mgr.Count);
            Assert.AreEqual(2, m_mgr.Current);
            UndoAction_SpriteEdit u2 = m_mgr.GetCurrent() as UndoAction_SpriteEdit;

            Assert.AreEqual(0, u2.Before.tiles[0].pixels[x2, y2]);
            Assert.AreEqual(color2, u2.After.tiles[0].pixels[x2, y2]);
            Assert.IsTrue(m_mgr.CanUndo());
            Assert.IsFalse(m_mgr.CanRedo());

            // Undo the last pixel draw.
            m_mgr.ApplyUndo();
            Assert.AreEqual(3, m_mgr.Count);
            Assert.AreEqual(1, m_mgr.Current);
            // Last pencil reverted.
            Assert.AreEqual(0, s.GetPixel(x2, y2));
            // First pencil still present.
            Assert.AreEqual(color1, s.GetPixel(x1, y1));
            Assert.IsTrue(m_mgr.CanUndo());
            Assert.IsTrue(m_mgr.CanRedo());

            // Undo the first pixel draw.
            m_mgr.ApplyUndo();
            Assert.AreEqual(3, m_mgr.Count);
            Assert.AreEqual(0, m_mgr.Current);
            // Both pencil marks reverted.
            Assert.AreEqual(0, s.GetPixel(x1, y1));
            Assert.AreEqual(0, s.GetPixel(x2, y2));
            Assert.IsTrue(m_mgr.CanUndo());
            Assert.IsTrue(m_mgr.CanRedo());

            // Undo the sprite add.
            m_mgr.ApplyUndo();
            Assert.AreEqual(3, m_mgr.Count);
            Assert.AreEqual(-1, m_mgr.Current);
            Assert.IsFalse(m_mgr.CanUndo());
            Assert.IsTrue(m_mgr.CanRedo());
        }