/// <summary>
        /// Calculates the code for overlapping multiple brightness gradients.
        /// <para>The final code will use the channel of the first BrightnessHDMA object passed.</para>
        /// </summary>
        /// <param name="hdma">An array of BrightnessHDMA object that will be overlapped for the final code.</param>
        /// <returns>The final code.</returns>
        public static string MultiCode(params BrightnessHDMA[] hdma)
        {
            if (hdma == null || hdma.Length == 0)
            {
                return(null);
            }

            int channel = hdma[0].Channel;

            EffectClasses.HDMATable table = new HDMATable(".BrightTable");

            using (Bitmap b = BitmapEffects.OverlapImages(hdma.Select(h => h.EffectImage).ToArray()))
            {
                byte scanlines = 1;
                int  now       = 0;
                int  compare   = 0x0F - (b.GetPixel(0, 0).A / 17);
                for (int y = 1; y < b.Height; y++, scanlines++)
                {
                    now = 0x0F - (b.GetPixel(0, y).A / 17);
                    if (compare != now || scanlines >= 0x80)
                    {
                        table.Add(new HDMATableEntry(TableValueType.db, scanlines, (byte)compare));
                        compare   = now;
                        scanlines = 0;
                    }
                }

                if (table.TotalScanlines != Scanlines)
                {
                    table.Add(new HDMATableEntry(TableValueType.db, scanlines, (byte)now));
                }

                table.Add(HDMATableEntry.End);

                DMAMode        mode       = (table[0].Values.Length == 1 ? DMAMode.P : DMAMode.PP);
                ASMCodeBuilder code       = new ASMCodeBuilder();
                int            channelAdd = 16 * channel;
                table.Name = ".BrightTable";

                code.AppendLabel(INITLabel, "Code to be inserted INIT");
                code.OpenNewBlock();
                code.AppendCode("\tREP #$20", "16 bit mode");
                code.AppendCode("\tLDA #$" + (((Registers.Brightness & 0xFF) << 8) + (int)mode).ToString("X4"));
                code.AppendCode("\tSTA $" + (Registers.DMAMode + channelAdd).ToString("X4"));
                code.AppendCode("\tLDA #" + table.Name, "load high and low byte of table address");
                code.AppendCode("\tSTA $" + (Registers.DMALowByte + channelAdd).ToString("X4"));
                code.AppendCode("\tSEP #$20", "back to 8 bit mode");
                code.AppendCode("\tLDA.b #" + table.Name + ">>16", "load bank byte of table address");
                code.AppendCode("\tSTA $" + (Registers.DMABankByte + channelAdd).ToString("X4"));
                code.AppendCode("\tLDA #$" + (1 << channel).ToString("X2"));
                code.AppendCode("\tTSB $" + RAM.HDMAEnable[RAM.SA1].ToString("X4"), "enable HDMA channel " + channel);
                code.AppendCode("\tRTS");
                code.CloseBlock();
                code.AppendEmptyLine();

                code.AppendTable(table);

                return(code.ToString());
            }
        }
        /// <summary>
        /// Sets up the color math and calculates the values for the HDMA table based on the entries of Values
        /// </summary>
        private void Setup()
        {
            Table.Clear();
            byte totalScanlines = 0;

            Bitmap bg1 = OriginalImages.BG1;
            Bitmap bg2 = OriginalImages.BG2;
            Bitmap bg3 = OriginalImages.BG3;
            Bitmap bg4 = OriginalImages.BG4;

            foreach (PixelScanline pix in Values)
            {
                if (pix.Scanline > 0x80)
                {
                    Table.Add(new HDMATableEntry(TableValueType.db, 0x80, (byte)((pix.Pixelation << 4) + (byte)pix.BGs)));
                    Table.Add(new HDMATableEntry(TableValueType.db, (byte)(pix.Scanline - 0x80), (byte)((pix.Pixelation << 4) + (byte)pix.BGs)));
                }
                else
                {
                    Table.Add(new HDMATableEntry(TableValueType.db, pix.Scanline, (byte)((pix.Pixelation << 4) + (byte)pix.BGs)));
                }

                if (pix.BGs.HasFlag(PixelationBGs.BG1))
                {
                    bg1 = BitmapEffects.PixelLine(pix.Scanline, pix.Pixelation, totalScanlines, bg1);
                }
                if (pix.BGs.HasFlag(PixelationBGs.BG2))
                {
                    bg2 = BitmapEffects.PixelLine(pix.Scanline, pix.Pixelation, totalScanlines, bg2);
                }
                if (pix.BGs.HasFlag(PixelationBGs.BG3))
                {
                    bg3 = BitmapEffects.PixelLine(pix.Scanline, pix.Pixelation, totalScanlines, bg3);
                }
                if (pix.BGs.HasFlag(PixelationBGs.BG4))
                {
                    bg4 = BitmapEffects.PixelLine(pix.Scanline, pix.Pixelation, totalScanlines, bg4);
                }

                totalScanlines += pix.Scanline;
                if (totalScanlines >= Scanlines)
                {
                    break;
                }
            }

            if (totalScanlines < Scanlines)
            {
                Table.Add(new HDMATableEntry(TableValueType.db, 1, 0));
            }

            ColorMath.BG1 = bg1;
            ColorMath.BG2 = bg2;
            ColorMath.BG3 = bg3;
            ColorMath.BG4 = bg4;
            ColorMath.OBJ = OriginalImages.OBJ;
            Table.Add(HDMATableEntry.End);
        }
Exemple #3
0
        public ColorMath(BitmapCollection Collection) : this()
        {
            BG1 = Collection.BG1;
            BG2 = Collection.BG2;
            BG3 = Collection.BG3;
            BG4 = Collection.BG4;
            OBJ = Collection.OBJ;

            FixedColor = BitmapEffects.FromColor(Collection.FixedColor, LayerSizes);
        }
Exemple #4
0
        /// <summary>
        /// Creates a base image with the preset setting of Amplitede and Width
        /// </summary>
        /// <param name="basePic">The base for the disordered image</param>
        /// <returns>The according to the settings disordered image</returns>
        public override Bitmap StaticPic(Bitmap basePic)
        {
            Reset();
            Bitmap NewOne = new Bitmap(basePic);

            //NewOne gets overwritten with the disordered image.
            //_Breite * i sets the start of the to move setction.
            //_Breite sets how thick the to move section is.
            //_IArr[i % 16] says how many pixel to move the image to the right.
            for (int i = 0; i *_width < NewOne.Height; i++)
            {
                NewOne = BitmapEffects.MoveLine((_width * i), _width, _IArr[i % 16] / 2, NewOne, Direction);
            }

            if (!EnableTable)
            {
                return(NewOne);
            }


            using (Graphics g = Graphics.FromImage(NewOne))
            {
                int totalCount = 0;
                foreach (var entry in EnabledWaveCollection)
                {
                    int height = entry.LineCount;
                    if (!entry.Value)
                    {
                        if (NewOne.Height <= totalCount + height)
                        {
                            height = NewOne.Height - totalCount;
                        }

                        var rec = Original.Clone(new Rectangle(0, totalCount, NewOne.Width, height), NewOne.PixelFormat);
                        g.DrawImage(rec, 0, totalCount);
                    }
                    totalCount += height;

                    if (totalCount >= NewOne.Height)
                    {
                        break;
                    }
                }

                /*
                 * if (totalCount < bm.Height)
                 *      g.DrawImage(
                 *              _yEffect.Original.Clone(new Rectangle(0, totalCount, bm.Width, (bm.Height - totalCount)),
                 *              bm.PixelFormat), 0, totalCount);*/
            }
            return(NewOne);
        }
        internal void UpdateImage()
        {
            if (Table == null)
            {
                return;
            }

            Bitmap bm      = BitmapEffects.FromColor(Color.Transparent, 1, Scanlines);
            int    counter = 0;

            foreach (HDMATableEntry entry in Table)
            {
                if (entry.ValueType == TableValueType.End)
                {
                    break;
                }
                if (entry.ValueType == TableValueType.Single)
                {
                    for (int y = counter; y < counter + entry.Scanlines - 0x80 && y < Scanlines; y++)
                    {
                        for (int x = 0; x < bm.Width; x++)
                        {
                            bm.SetPixel(x, y, Color.FromArgb(255 - (entry.Values[y] & 0x0F) * 17, 0, 0, 0));
                        }
                    }
                    counter += entry.Scanlines - 0x80;
                }
                else if (entry.ValueType == TableValueType.db)
                {
                    for (int y = counter; y < counter + entry.Scanlines && y < Scanlines; y++)
                    {
                        for (int x = 0; x < bm.Width; x++)
                        {
                            bm.SetPixel(x, y, Color.FromArgb(255 - (entry.Values[0] & 0x0F) * 17, 0, 0, 0));
                        }
                    }
                    counter += entry.Scanlines;
                }
                else
                {
                    //fixme exception
                    throw new HDMAException();
                }
            }

            Bitmap retImg = new Bitmap(256, Scanlines);

            using (TextureBrush brush = new TextureBrush(bm, WrapMode.Tile))
                using (Graphics gr = Graphics.FromImage(retImg))
                    gr.FillRectangle(brush, 0, 0, retImg.Width, retImg.Height);
            EffectImage = retImg;
        }
Exemple #6
0
        /// <summary>
        /// Combines two black/white masks in a new bitmap
        /// </summary>
        /// <param name="mask1">The first mask for the merge</param>
        /// <param name="mask2">The second mask for the merge</param>
        /// <param name="logic">How to merge the masks</param>
        /// <returns>The merged masks</returns>
        private Bitmap MergeMasks(Bitmap mask1, Bitmap mask2, WindowMaskLogic logic)
        {
            Bitmap[]  windowLogicMasks = new Bitmap[4];
            Rectangle maskRec          = new Rectangle(new Point(0, 0), mask2.Size);

            //needs to run if there is any OR, XOR, XNOR => baiscally if there is any that is not And
            if (logic != WindowMaskLogic.And)
            {
                Bitmap          mask = new Bitmap(mask1);
                ImageAttributes attr = new ImageAttributes();
                attr.SetColorKey(Color.White, Color.White);

                using (Graphics g = Graphics.FromImage(mask))
                {
                    g.DrawImage(mask2, maskRec, maskRec.X, maskRec.Y,
                                maskRec.Width, maskRec.Height, GraphicsUnit.Pixel, attr);
                }
                windowLogicMasks[(int)WindowMaskLogic.Or] = mask;
            }
            //needs to run if there is any AND, XOR, XNOR => baiscally if there is any that is not Or
            if (logic != WindowMaskLogic.Or)
            {
                Bitmap          mask = new Bitmap(mask1);
                ImageAttributes attr = new ImageAttributes();
                attr.SetColorKey(Color.Black, Color.Black);

                using (Graphics g = Graphics.FromImage(mask))
                {
                    g.DrawImage(mask2, maskRec, maskRec.X, maskRec.Y,
                                maskRec.Width, maskRec.Height, GraphicsUnit.Pixel, attr);
                }
                windowLogicMasks[(int)WindowMaskLogic.And] = mask;
            }
            if (logic == WindowMaskLogic.Xor || logic == WindowMaskLogic.XNor)
            {
                Bitmap          mask = new Bitmap(windowLogicMasks[(int)WindowMaskLogic.Or]);
                ImageAttributes attr = new ImageAttributes();
                attr.SetColorKey(Color.Black, Color.Black);

                using (Graphics g = Graphics.FromImage(mask))
                {
                    g.DrawImage(BitmapEffects.Invert(windowLogicMasks[(int)WindowMaskLogic.And]),
                                maskRec, maskRec.X, maskRec.Y, maskRec.Width, maskRec.Height, GraphicsUnit.Pixel, attr);
                }

                mask.Save("XOR.png");
                windowLogicMasks[(int)WindowMaskLogic.Xor]  = mask;
                windowLogicMasks[(int)WindowMaskLogic.XNor] = BitmapEffects.Invert(mask);
            }

            return(windowLogicMasks[(int)logic]);
        }
Exemple #7
0
        public override Bitmap NextAnimateFrame(Bitmap basePic)
        {
            Bitmap newBM  = new Bitmap(basePic);
            int    offset = 0;

            foreach (var bar in Bars)
            {
                Bitmap single;
                int    index = (int)(bar.Multiplier * Frame) % _frames.Length;
                if (_frames[index] == null)
                {
                    single         = BitmapEffects.MoveLine(0, basePic.Height, index, basePic, Orientation.Left);
                    _frames[index] = single;
                }
                else
                {
                    single = _frames[index];
                }

                using (Graphics g = Graphics.FromImage(newBM))
                {
                    int scanlines = 0;
                    if (offset + bar.Scanline >= basePic.Height)
                    {
                        scanlines = basePic.Height - offset;
                    }
                    else
                    {
                        scanlines = bar.Scanline;
                    }

                    Rectangle rect = new Rectangle(0, offset, basePic.Width, scanlines);
                    g.SetClip(rect);
                    g.Clear(Color.Transparent);                     //delete the part to be moved before drawing over it.
                    g.ResetClip();
                    g.DrawImageUnscaled(single.Clone(rect, basePic.PixelFormat), rect);
                }
                offset += bar.Scanline;
                if (offset >= basePic.Height)
                {
                    break;
                }
            }

            Frame++;
            return(newBM);
        }
Exemple #8
0
        /*
         * =============================================================================================================
         *                  Constructors
         * =============================================================================================================
         */
        public ColorMath()
        {
            MainScreenDesignation = ScreenDesignation.BG1 | ScreenDesignation.OBJ;
            SubScreenDesignation  = ScreenDesignation.BG2 | ScreenDesignation.BG4 | ScreenDesignation.BG3;
            ColorMathDesignation  = ColorMathMode.Backdrop;

            LayerSizes = new Size(256, HDMA.Scanlines);

            BG1 = new Bitmap(LayerSizes.Width, LayerSizes.Height);
            BG2 = new Bitmap(LayerSizes.Width, LayerSizes.Height);
            BG3 = new Bitmap(LayerSizes.Width, LayerSizes.Height);
            BG4 = new Bitmap(LayerSizes.Width, LayerSizes.Height);
            OBJ = new Bitmap(LayerSizes.Width, LayerSizes.Height);

            FixedColor = new Bitmap(LayerSizes.Width, LayerSizes.Height);

            Backdrop = BitmapEffects.FromColor(Color.Black, LayerSizes);

            //default: White = hide nothing
            WindowingMask1 = BitmapEffects.FromColor(Color.White, LayerSizes);
            WindowingMask2 = BitmapEffects.FromColor(Color.White, LayerSizes);
        }
Exemple #9
0
        /// <summary>
        /// Creates a Bitmap depending on the settings and the internal counter, which also get's increased at the end.
        /// </summary>
        /// <param name="basePic">The still (unchanged) image.</param>
        /// <returns>Depending on the settings moved image.</returns>
        public override Bitmap NextAnimateFrame(Bitmap basePic)
        {
            Bitmap NewOne;

            try
            {
                int index = (int)(Frame * _speed) % _animationFrames.Length;
                //only calculate new frame if we don't have one yet.
                if (_animationFrames[index] == null)
                {
                    NewOne = new Bitmap(basePic);
                    for (int i = 0; i *_width < NewOne.Height; i++)
                    {
                        //NewOne gets overwritten with the disordered image.
                        //_Breite * i sets the start of the to move setction.
                        //_Breite sets how thick the to move section is.
                        //_IArr[(i + _rounds) % 16] says how many pixel to move the image to the right.
                        NewOne = BitmapEffects.MoveLine((_width * i), _width, _IArr[(i + index) % 16] / 2, NewOne, Direction);
                    }

                    _animationFrames[index] = NewOne;
                }
                else
                {
                    //load frame from memory
                    NewOne = _animationFrames[index];
                }

                //SPEED_FACTOR multiplication because _speed < 1. So it would get reeeaaally slow.
                //_dRounds = (_dRounds + (_speed * SPEED_FACTOR)) % 16;
                //actual _rounds only increases ever so often due to cast.
                //_rounds = (int)_dRounds;
                Frame++;

                if (!EnableTable)
                {
                    return(NewOne);
                }

                Bitmap img = new Bitmap(NewOne.Width, NewOne.Height);
                using (Graphics g = Graphics.FromImage(img))
                {
                    int totalCount = 0;
                    foreach (var entry in EnabledWaveCollection)
                    {
                        int    height = entry.LineCount;
                        Bitmap toUse  = entry.Value ? NewOne : basePic;

                        if (img.Height <= totalCount + height)
                        {
                            height = img.Height - totalCount;
                        }

                        var rec = toUse.Clone(new Rectangle(0, totalCount, img.Width, height), toUse.PixelFormat);
                        g.DrawImage(rec, 0, totalCount);

                        totalCount += height;

                        if (totalCount >= img.Height)
                        {
                            break;
                        }
                    }


                    if (totalCount < img.Height)
                    {
                        g.DrawImage(
                            basePic.Clone(new Rectangle(0, totalCount, img.Width, (img.Height - totalCount)),
                                          img.PixelFormat), 0, totalCount);
                    }
                }
                return(img);
            }
            catch (Exception ex)
            {
                ThrowExceptionEvent(ex);
                return(StaticPic(basePic));
            }
        }
 public BrightnessHDMA()
 {
     EffectImage = BitmapEffects.FromColor(Color.Transparent, 256, Scanlines);
 }
Exemple #11
0
        public bool CheckAndSplitMask(Bitmap mask, ColorMath math)
        {
            //array of with array for each line.
            //each line has entrys with the color and the start position of that color in that line
            ColPos[][] C_Arr = new ColPos[Scanlines][];

            BitmapData data = mask.LockBits(new Rectangle(new Point(0, 0), mask.Size), ImageLockMode.ReadWrite, mask.PixelFormat);

            byte[] bytes = new byte[data.Height * data.Stride];
            System.Runtime.InteropServices.Marshal.Copy(data.Scan0, bytes, 0, bytes.Length);

            for (int y = 0; y < mask.Height; y++)
            {
                Color         ColorToCheck = BitmapEffects.GetPixel(data, bytes, 0, y);         //mask.GetPixel(0, y);
                List <ColPos> CList        = new List <ColPos>();
                CList.Add(new ColPos(ColorToCheck, 0));

                for (int x = 1; x < mask.Width; x++)
                {
                    Color c = BitmapEffects.GetPixel(data, bytes, x, y);
                    if (ColorToCheck == c)                     //mask.GetPixel(x, y))
                    {
                        continue;
                    }

                    ColorToCheck = c;                     //mask.GetPixel(x, y);
                    CList.Add(new ColPos(ColorToCheck, x));
                }
                C_Arr[y] = CList.ToArray();
            }

            mask.UnlockBits(data);

            //if more then two black/white transitions appear in (any) line
            bool black3 = C_Arr.Any((CA => CA.Count(c => c.Color.Name == "ff000000") > 2));
            bool white3 = C_Arr.Any((CA => CA.Count(c => c.Color.Name == "ffffffff") > 2));

            //3 transitions in both won't work eg. black-white-black-white-black-white
            if (black3 && white3)
            {
                return(false);
            }

            int[] BlackLines;
            int[] WhiteLines;

            //get all the lines with 3 black transitions.
            //can't be more then 3 because that would result in more then 3 white trans. in the same line.
            IEnumerable <ColPos[]> Puff = C_Arr.Where((CA => CA.Count(c => c.Color.Name == "ff000000") > 2));

            //an array of indeces to those lines.
            BlackLines = new int[Puff.Count()];
            int i = 0;

            foreach (ColPos[] cp in Puff)
            {
                BlackLines[i] = Array.IndexOf(C_Arr, cp);
                i++;
            }

            //same for white.
            Puff       = C_Arr.Where((CA => CA.Count(c => c.Color.Name == "ffffffff") > 2));
            WhiteLines = new int[Puff.Count()];
            i          = 0;
            foreach (ColPos[] cp in Puff)
            {
                WhiteLines[i] = Array.IndexOf(C_Arr, cp);
                i++;
            }

            Bitmap w1 = BitmapEffects.FromColor(Color.White, 256, 224);
            Bitmap w2 = BitmapEffects.FromColor(Color.White, 256, 224);

            BitmapData w1Data = w1.LockBits(new Rectangle(0, 0, w1.Width, w1.Height), ImageLockMode.ReadWrite, w1.PixelFormat);
            BitmapData w2Data = w2.LockBits(new Rectangle(0, 0, w2.Width, w2.Height), ImageLockMode.ReadWrite, w2.PixelFormat);

            byte[] w1Bytes = new byte[w1Data.Height * w1Data.Stride];
            byte[] w2Bytes = new byte[w2Data.Height * w2Data.Stride];
            System.Runtime.InteropServices.Marshal.Copy(w1Data.Scan0, w1Bytes, 0, w1Bytes.Length);
            System.Runtime.InteropServices.Marshal.Copy(w2Data.Scan0, w2Bytes, 0, w2Bytes.Length);


            Table = new HDMATable(".windowTable");
            HDMATableEntry entry     = null;
            HDMATableEntry lastEntry = null;

            //if any line in this image requires 3 black and 2 white, one window (bm1) has to be inverted.
            bool WindowInverted = C_Arr.Any(cp => (cp.Count(c => c.Color.Name == "ff000000") == 3 &&
                                                   cp.Count(c => c.Color.Name == "ffffffff") == 2));

            for (int y = 0; y < Scanlines; y++)
            {
                entry = new HDMATableEntry(TableValueType.db, (byte)(1 + y - Table.TotalScanlines),
                                           0xFF, 0x00, 0xFF, 0x00);

                int countBlack = C_Arr[y].Count(cp => cp.Color.Name == "ff000000");
                int countWhite = C_Arr[y].Count(cp => cp.Color.Name == "ffffffff");

                Func <int, int, int, bool> BlackFromTill = (window, from, till) =>
                {
                    if (till == 0x100)
                    {
                        till = 0xFF;
                    }

                    if (window == 1)
                    {
                        for (int x = from; x < till; x++)
                        {
                            BitmapEffects.SetPixel(w1Data, ref w1Bytes, x, y, Color.Black);
                        }
                        entry.Values[0] = (byte)from;
                        entry.Values[1] = (byte)till;
                        return(true);
                    }
                    else if (window == 2)
                    {
                        for (int x = from; x < till; x++)
                        {
                            BitmapEffects.SetPixel(w2Data, ref w2Bytes, x, y, Color.Black);
                        }
                        entry.Values[2] = (byte)from;
                        entry.Values[3] = (byte)till;
                        return(true);
                    }
                    return(false);
                };

                if (countBlack == 1 && countWhite == 0)
                {
                    // whole line black.
                    // if window get's inverted, line can be left unchanged.
                    if (!WindowInverted)
                    {
                        BlackFromTill(1, 0, w1.Width);                          // if not, whole line black
                    }
                }
                else if (countBlack == 2 && countWhite == 1)
                {
                    //outer black, inner white (black-white-black)

                    if (WindowInverted)                                               //if window 1 is inverted it can be done using one window.
                    {
                        BlackFromTill(1, C_Arr[y][1].Position, C_Arr[y][2].Position); //The part white in the mask will be black in w1
                    }
                    else                                                              //window 1 not inveted:
                    {
                        BlackFromTill(1, C_Arr[y][0].Position, C_Arr[y][1].Position); // first black part of mask in window 1,
                        BlackFromTill(2, C_Arr[y][2].Position, w2.Width);             // and the second in window 2.
                    }
                }
                else if (countBlack == 3 && countWhite == 2)
                {
                    //black-white-black-white-black
                    //1 window inverted, the other not (not possible otherwise).
                    //meaning window 1 will be inverted.

                    BlackFromTill(1, C_Arr[y][1].Position, C_Arr[y][4].Position);                       // windows 1 will be black from the beginning of the first white
                    BlackFromTill(2, C_Arr[y][2].Position, C_Arr[y][3].Position);                       // till the end of the second. Windows 2 is the middle black part.
                }

                //else if (countBlack == 3 && countWhite == 3)
                //... IMPOSSIBRU <.<

                else if (countBlack == 2 && countWhite == 3)
                {
                    //white-black-white-black-white
                    //both windows have to be uninverted. (or playing with XOR setting)

                    BlackFromTill(1, C_Arr[y][1].Position, C_Arr[y][2].Position);                       // window 1 black for first black part of mask
                    BlackFromTill(2, C_Arr[y][3].Position, C_Arr[y][4].Position);                       // windows 2 black for second part.
                }
                else if (countBlack == 1 && countWhite == 2)
                {
                    //outer white inner black (white-black-white)

                    if (WindowInverted)                                               //if windows 1 is inverted, we have to use window 2 and set window 1 black on the whole line
                    {
                        BlackFromTill(1, 0, w1.Width);                                // window 1 completly black
                        BlackFromTill(2, C_Arr[y][1].Position, C_Arr[y][2].Position); // window 2 black where mask is black.
                    }
                    else
                    {
                        BlackFromTill(1, C_Arr[y][1].Position, C_Arr[y][2].Position);                           // if not inverted, simply use window 1.
                    }
                }
                else if (countBlack == 0 && countWhite == 1)
                {
                    //whole line visible
                    if (WindowInverted)
                    {
                        BlackFromTill(1, 0, w1.Width);                                          // if window 1 inverted, whole line black
                    }
                }
                else if (countBlack == 2 && countWhite == 2)
                {
                    //problem: unknown if black-white-black-white or white-black-white-black
                    #region 2/2
                    if (C_Arr[y][0].Color.Name == "ff000000")                             //if fisrt part black then B-W-B-W
                    {
                        if (WindowInverted)                                               //inverted:
                        {
                            BlackFromTill(1, C_Arr[y][1].Position, w1.Width);             // the -W-B-W area will be black, so inverted makes the first bar black
                            BlackFromTill(2, C_Arr[y][2].Position, C_Arr[y][3].Position); // window 2 simply makes second bar black
                        }
                        else                                                              //not inverted
                        {
                            BlackFromTill(1, C_Arr[y][0].Position, C_Arr[y][1].Position); // first bar in window 1
                            BlackFromTill(2, C_Arr[y][2].Position, C_Arr[y][3].Position); // guess what
                        }
                    }
                    else                                                                  // first bar not black, thus W-B-W-B
                    {
                        if (WindowInverted)                                               //inverted:
                        {
                            BlackFromTill(1, C_Arr[y][0].Position, C_Arr[y][3].Position); // the W-B-W- area will be black, inverting makes the last bar black.
                            BlackFromTill(2, C_Arr[y][1].Position, C_Arr[y][2].Position); // window 2 will be black where the first bar is.
                        }
                        else                                                              //not inverted
                        {
                            BlackFromTill(1, C_Arr[y][1].Position, C_Arr[y][2].Position); // first bar in window 2
                            BlackFromTill(2, C_Arr[y][3].Position, w2.Width);             // ...
                        }
                    }
                    #endregion
                }
                else if (countBlack == 1 && countWhite == 1)
                {
                    //problem: unknown if black-white or white-black
                    if (C_Arr[y][0].Color.Name == "ff000000")                             //first bar is black thus B-W
                    {
                        if (WindowInverted)                                               //inverted:
                        {
                            BlackFromTill(1, C_Arr[y][1].Position, w1.Width);             //set second bar (white) to black due to inverting
                        }
                        else                                                              //not inverted
                        {
                            BlackFromTill(1, C_Arr[y][0].Position, C_Arr[y][1].Position); //first bar (black) in window one to black
                        }
                    }
                    else                                                                  //first bar not black thus W-B
                    {
                        if (WindowInverted)                                               //inverted:
                        {
                            BlackFromTill(1, C_Arr[y][0].Position, C_Arr[y][1].Position); // set white part black;
                        }
                        else                                                              //not inverted
                        {
                            BlackFromTill(1, C_Arr[y][1].Position, w1.Width);             //set second bar black.
                        }
                    }
                }


                if ((lastEntry != null && !entry.Values.SequenceEqual(lastEntry.Values)) || entry.Scanlines == 0x81)
                {
                    Table.Add(lastEntry);
                    entry.Scanlines = 1;
                }
                lastEntry = (HDMATableEntry)entry.Clone();
            }                              //end of for-loop

            Table.Add(lastEntry);          //the last last entry
            Table.Add(HDMATableEntry.End); //the actual end.

            System.Runtime.InteropServices.Marshal.Copy(w1Bytes, 0, w1Data.Scan0, w1Bytes.Length);
            System.Runtime.InteropServices.Marshal.Copy(w2Bytes, 0, w2Data.Scan0, w2Bytes.Length);
            w1.UnlockBits(w1Data);
            w2.UnlockBits(w2Data);

            math.WindowingMask1 = w1;
            math.WindowingMask2 = w2;

            math.Window1Inverted = WindowInverted ? (WindowingLayers)0x3F : 0;

            return(true);
        }
Exemple #12
0
 public WindowingHDMA()
 {
     Orignal = BitmapEffects.FromColor(Color.White, 256, Scanlines);
 }
Exemple #13
0
        /// <summary>
        /// Gets the screen as it would be displayed by the SNES.
        /// </summary>
        /// <returns></returns>
        public Bitmap GetScreen()
        {
            if (BG1 == null || BG2 == null || BG3 == null || BG4 == null)
            {
                throw new ArgumentNullException("BGs need to be initialized");
            }
            if (FixedColor == null)
            {
                throw new ArgumentNullException("FixedColor need to be initialized");
            }
            if (Backdrop == null)
            {
                throw new ArgumentNullException("Backdrop need to be initialized");
            }


            Bitmap main, sub;
            Bitmap statusBar  = new Bitmap(LayerSizes.Width, LayerSizes.Height);
            Bitmap bg3_remain = new Bitmap(LayerSizes.Width, LayerSizes.Height);

            //cut layer 3 into status bar end rest.
            using (Graphics g = Graphics.FromImage(statusBar))
                g.DrawImageUnscaledAndClipped(BG3, new Rectangle(0, 0, statusBar.Width, StatusBarHeight));
            using (Graphics g = Graphics.FromImage(bg3_remain))
            {
                Rectangle rec = new Rectangle(0, StatusBarHeight, bg3_remain.Width, bg3_remain.Height - StatusBarHeight);
                g.DrawImageUnscaledAndClipped(BG3.Clone(rec, BG3.PixelFormat), rec);
            }


            Func <bool, bool, bool, bool, WindowMaskLogic, Bitmap, Bitmap> doWindowing = (enable1, enable2, invert1, invert2, logic, bg) =>
            {
                Bitmap mask1 = invert1 ? BitmapEffects.Invert(WindowingMask1) : WindowingMask1;
                Bitmap mask2 = invert2 ? BitmapEffects.Invert(WindowingMask2) : WindowingMask2;

                if (enable1 && enable2)
                {
                    return(BitmapEffects.ApplyMask(bg, MergeMasks(mask1, mask2, logic), 0.5f));
                }
                else if (enable1)
                {
                    return(BitmapEffects.ApplyMask(bg, mask1, 0.5f));
                }
                else if (enable2)
                {
                    return(BitmapEffects.ApplyMask(bg, mask2, 0.5f));
                }
                else
                {
                    return(bg);
                }
            };

            Bitmap bg1Windowed = doWindowing(Window1Enabled.HasFlag(WindowingLayers.BG1), Window2Enabled.HasFlag(WindowingLayers.BG1),
                                             Window1Inverted.HasFlag(WindowingLayers.BG1), Window2Inverted.HasFlag(WindowingLayers.BG1), Bg1MaskLogic, BG1);

            Bitmap bg2Windowed = doWindowing(Window1Enabled.HasFlag(WindowingLayers.BG2), Window2Enabled.HasFlag(WindowingLayers.BG2),
                                             Window1Inverted.HasFlag(WindowingLayers.BG2), Window2Inverted.HasFlag(WindowingLayers.BG2), Bg2MaskLogic, BG2);

            Bitmap statusBarWindowed = doWindowing(Window1Enabled.HasFlag(WindowingLayers.BG3), Window2Enabled.HasFlag(WindowingLayers.BG3),
                                                   Window1Inverted.HasFlag(WindowingLayers.BG3), Window2Inverted.HasFlag(WindowingLayers.BG3), Bg3MaskLogic, statusBar);

            Bitmap bg3RemainWindowed = doWindowing(Window1Enabled.HasFlag(WindowingLayers.BG3), Window2Enabled.HasFlag(WindowingLayers.BG3),
                                                   Window1Inverted.HasFlag(WindowingLayers.BG3), Window2Inverted.HasFlag(WindowingLayers.BG3), Bg3MaskLogic, bg3_remain);

            Bitmap bg4Windowed = doWindowing(Window1Enabled.HasFlag(WindowingLayers.BG4), Window2Enabled.HasFlag(WindowingLayers.BG4),
                                             Window1Inverted.HasFlag(WindowingLayers.BG4), Window2Inverted.HasFlag(WindowingLayers.BG4), Bg4MaskLogic, BG4);

            Bitmap objWindowed = doWindowing(Window1Enabled.HasFlag(WindowingLayers.OBJ), Window2Enabled.HasFlag(WindowingLayers.OBJ),
                                             Window1Inverted.HasFlag(WindowingLayers.OBJ), Window2Inverted.HasFlag(WindowingLayers.OBJ), ObjMaskLogic, OBJ);

            Bitmap colorWindowed      = BitmapEffects.FromColor(Color.Black, LayerSizes);
            Bitmap colorWindowedHoles = doWindowing(Window1Enabled.HasFlag(WindowingLayers.Color), Window2Enabled.HasFlag(WindowingLayers.Color),
                                                    Window1Inverted.HasFlag(WindowingLayers.Color), Window2Inverted.HasFlag(WindowingLayers.Color), ColorMaskLogic,
                                                    BitmapEffects.FromColor(Color.White, LayerSizes));

            //colorWindowsedHoles is white with holes where the black should be
            using (Graphics g = Graphics.FromImage(colorWindowed))
                g.DrawImage(colorWindowedHoles, 0, 0);

            #region Sub Screen
            List <Bitmap> BGs = new List <Bitmap>();
            if (SubScreenDesignation.HasFlag(ScreenDesignation.OBJ) && !Hide.HasFlag(ScreenDesignation.OBJ))
            {
                BGs.Add(SubScreenWindowMaskDesignation.HasFlag(ScreenDesignation.OBJ) ? objWindowed : OBJ);
            }

            if (SubScreenDesignation.HasFlag(ScreenDesignation.BG1) && !Hide.HasFlag(ScreenDesignation.BG1))
            {
                BGs.Add(SubScreenWindowMaskDesignation.HasFlag(ScreenDesignation.BG1) ? bg1Windowed : BG1);
            }

            if (SubScreenDesignation.HasFlag(ScreenDesignation.BG2) && !Hide.HasFlag(ScreenDesignation.BG2))
            {
                BGs.Add(SubScreenWindowMaskDesignation.HasFlag(ScreenDesignation.BG2) ? bg2Windowed : BG2);
            }

            //layer 3 special (status bar split) onyl lower part
            if (SubScreenDesignation.HasFlag(ScreenDesignation.BG3) && !Hide.HasFlag(ScreenDesignation.BG3))
            {
                BGs.Add(SubScreenWindowMaskDesignation.HasFlag(ScreenDesignation.BG3) ? bg3RemainWindowed : bg3_remain);
            }

            if (SubScreenDesignation.HasFlag(ScreenDesignation.BG4) && !Hide.HasFlag(ScreenDesignation.BG4))
            {
                BGs.Add(SubScreenWindowMaskDesignation.HasFlag(ScreenDesignation.BG4) ? bg4Windowed : BG4);
            }

            BGs.Add(FixedColor);
            sub = BitmapEffects.OverlapImages(BGs.ToArray());
            #endregion

            #region Main Screen

            BGs.Clear();
            if (MainScreenDesignation.HasFlag(ScreenDesignation.OBJ) && !Hide.HasFlag(ScreenDesignation.OBJ))
            {
                Bitmap objUse = MainScreenWindowMaskDesignation.HasFlag(ScreenDesignation.OBJ) ? objWindowed : OBJ;
                if (ColorMathDesignation.HasFlag(ColorMathMode.OBJ))
                {
                    BGs.Add(ApplyColorMath(objUse, AddColor ? FixedColor : sub, ColorMathDesignation, colorWindowed, ClipToBlack, PreventColorMath));
                }
                else
                {
                    BGs.Add(objUse);
                }
            }
            if (MainScreenDesignation.HasFlag(ScreenDesignation.BG1) && !Hide.HasFlag(ScreenDesignation.BG1))
            {
                Bitmap bg1Use = MainScreenWindowMaskDesignation.HasFlag(ScreenDesignation.BG1) ? bg1Windowed : BG1;
                if (ColorMathDesignation.HasFlag(ColorMathMode.BG1))
                {
                    BGs.Add(ApplyColorMath(bg1Use, AddColor ? FixedColor : sub, ColorMathDesignation, colorWindowed, ClipToBlack, PreventColorMath));
                }
                else
                {
                    BGs.Add(bg1Use);
                }
            }
            if (MainScreenDesignation.HasFlag(ScreenDesignation.BG2) && !Hide.HasFlag(ScreenDesignation.BG2))
            {
                Bitmap bg2Use = MainScreenWindowMaskDesignation.HasFlag(ScreenDesignation.BG2) ? bg2Windowed : BG2;
                if (ColorMathDesignation.HasFlag(ColorMathMode.BG2))
                {
                    BGs.Add(ApplyColorMath(bg2Use, AddColor ? FixedColor : sub, ColorMathDesignation, colorWindowed, ClipToBlack, PreventColorMath));
                }
                else
                {
                    BGs.Add(bg2Use);
                }
            }
            if (MainScreenDesignation.HasFlag(ScreenDesignation.BG3) && !Hide.HasFlag(ScreenDesignation.BG3))
            {
                //layer 3 special (status bar split) onyl lower half
                Bitmap bg3Use = MainScreenWindowMaskDesignation.HasFlag(ScreenDesignation.BG3) ? bg3RemainWindowed : bg3_remain;
                if (ColorMathDesignation.HasFlag(ColorMathMode.BG3))
                {
                    BGs.Add(ApplyColorMath(bg3Use, AddColor ? FixedColor : sub, ColorMathDesignation, colorWindowed, ClipToBlack, PreventColorMath));
                }
                else
                {
                    BGs.Add(bg3Use);
                }
            }
            if (MainScreenDesignation.HasFlag(ScreenDesignation.BG4) && !Hide.HasFlag(ScreenDesignation.BG4))
            {
                Bitmap bg4Use = MainScreenWindowMaskDesignation.HasFlag(ScreenDesignation.BG3) ? bg4Windowed : BG4;
                if (ColorMathDesignation.HasFlag(ColorMathMode.BG4))
                {
                    BGs.Add(ApplyColorMath(bg4Use, AddColor ? FixedColor : sub, ColorMathDesignation, colorWindowed, ClipToBlack, PreventColorMath));
                }
                else
                {
                    BGs.Add(bg4Use);
                }
            }

            //handle the backdrop too
            if (ColorMathDesignation.HasFlag(ColorMathMode.Backdrop))
            {
                BGs.Add(ApplyColorMath(Backdrop, AddColor ? FixedColor : sub, ColorMathDesignation, colorWindowed, ClipToBlack, PreventColorMath));
            }
            else
            {
                BGs.Add(Backdrop);
            }

            main = BitmapEffects.OverlapImages(BGs.ToArray());
            #endregion

            BGs.Clear();

            //check windowing for status bar
            if (MainScreenDesignation.HasFlag(ScreenDesignation.BG3) && !Hide.HasFlag(ScreenDesignation.BG3))
            {
                BGs.Add(MainScreenWindowMaskDesignation.HasFlag(ScreenDesignation.BG3) ? statusBarWindowed : statusBar);
            }
            //if not main, check subscreen. (still put it before main for display purpose)
            else if (SubScreenDesignation.HasFlag(ScreenDesignation.BG3) && !Hide.HasFlag(ScreenDesignation.BG3))
            {
                BGs.Add(SubScreenWindowMaskDesignation.HasFlag(ScreenDesignation.BG3) ? statusBarWindowed : statusBar);
            }

            BGs.Add(main);
            BGs.Add(sub);

            return(BitmapEffects.OverlapImages(BGs.ToArray()));
        }
Exemple #14
0
 /// <summary>
 /// Sets the FixedColor property based on a desired color.
 /// </summary>
 /// <param name="color">The color for the Bitmap</param>
 public void SetBackdrop(Color color)
 {
     Backdrop = BitmapEffects.FromColor(color, LayerSizes);
 }
Exemple #15
0
 /// <summary>
 /// Sets the FixedColor property based on a desired color.
 /// </summary>
 /// <param name="color">The color for the Bitmap</param>
 public void SetFixedColor(Color color)
 {
     FixedColor = BitmapEffects.FromColor(color, LayerSizes);
 }