Ejemplo n.º 1
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()));
        }
Ejemplo n.º 2
0
        public string Code()
        {
            ASMCodeBuilder sb = new ASMCodeBuilder();

            sb.AppendLabel(HDMA.INITLabel);

            if (MainScreenDesignation != MainScreenWindowMaskDesignation || true)
            {
                sb.OpenNewBlock();
                sb.AppendCode("LDA #$" + SumEnumFlag(MainScreenDesignation).ToASMString(), MainScreenDesignation.ToString() + " on main screen (TM)");
                sb.AppendCode("STA $" + Registers.MainScreenDesignation.ToASMString());
                sb.AppendCode("LDA #$" + SumEnumFlag(MainScreenWindowMaskDesignation).ToASMString(), MainScreenWindowMaskDesignation.ToString() + " on main screen should use windowing. (TMW)");
                sb.AppendCode("STA $" + Registers.MainScreenWindow.ToASMString());
                sb.CloseBlock();
            }

            /*else
             * {
             *      sb.OpenNewBlock();
             *      sb.AppendCode("LDA #$" + SumEnumFlag(MainScreenDesignation).ToASMString(), MainScreenDesignation.ToString() + " on main screen (TM) and window (TMW)");
             *      sb.AppendCode("STA $" + RAM.MainScreenAndWindowDesignation[RAM.SA1].ToASMString(), "mirror of $212C and $212E");
             *      sb.CloseBlock();
             * }*/
            if (SubScreenDesignation != SubScreenWindowMaskDesignation || true)
            {
                sb.OpenNewBlock();
                sb.AppendCode("LDA #$" + SumEnumFlag(SubScreenDesignation).ToASMString(), SubScreenDesignation.ToString() + " on sub screen (TS)");
                sb.AppendCode("STA $" + Registers.SubScreenDesignation.ToASMString());
                sb.AppendCode("LDA #$" + SumEnumFlag(SubScreenWindowMaskDesignation).ToASMString(), SubScreenWindowMaskDesignation.ToString() + " on sub screen should use windowing. (TSW)");
                sb.AppendCode("STA $" + Registers.SubScreenWindow.ToASMString());
                sb.CloseBlock();
            }

            /*else
             * {
             *      sb.OpenNewBlock();
             *      sb.AppendCode("LDA #$" + SumEnumFlag(SubScreenDesignation).ToASMString(), SubScreenDesignation.ToString() + " on sub screen (TS) and window (TSW)");
             *      sb.AppendCode("STA $" + RAM.SubScreenAndWindowDesignation[RAM.SA1].ToASMString(), "mirror of $212D and $212F");
             *      sb.CloseBlock();
             * }*/

            sb.AppendCode("LDA #$" + SumEnumFlag(ColorMathDesignation).ToASMString(), ColorMathDesignation.ToString() + " for color math");
            sb.AppendCode("STA $" + RAM.ColorMathSetting[RAM.SA1].ToASMString(), "mirror of $2131");
            sb.CloseBlock();

            if (!AddColor || ClipToBlack != 0 || PreventColorMath != 0)
            {
                sb.OpenNewBlock();
                int CGWSEL = (((int)ClipToBlack) << 6) +
                             (((int)PreventColorMath) << 4) +
                             (AddColor ? 0 : 2);

                sb.AppendCode("LDA #$" + CGWSEL.ToASMString(), "Clip to black: " + ClipToBlack + ", Prevent colot math: " + PreventColorMath);
                sb.AppendCode("STA $" + RAM.ColorAdditionSelect[RAM.SA1].ToASMString(), "Add subscreen instead of fixed color: " + !AddColor);
                sb.CloseBlock();
            }

            //mask logic
            if (MaskLogicBgs != 0)
            {
                sb.OpenNewBlock();
                sb.AppendCode("LDA #$" + MaskLogicBgs.ToString("X2"), "Mask logic for overlapping windowing on BGs");
                sb.AppendCode("STA $" + Registers.WindowingLogicBgs.ToASMString());
                sb.CloseBlock();
            }
            //mask logic
            if (MaskLogicObjCol != 0)
            {
                sb.OpenNewBlock();
                sb.AppendCode("LDA #$" + MaskLogicObjCol.ToString("X2"), "Mask logic for overlapping windowing on BGs");
                sb.AppendCode("STA $" + Registers.WindowingLogicObjColor.ToASMString());
                sb.CloseBlock();
            }

            int regW12SEL =
                (Window1Inverted.HasFlag(WindowingLayers.BG1) ? 0x01 : 0x00) +
                (Window1Enabled.HasFlag(WindowingLayers.BG1) ? 0x02 : 0x00) +
                (Window2Inverted.HasFlag(WindowingLayers.BG1) ? 0x04 : 0x00) +
                (Window2Enabled.HasFlag(WindowingLayers.BG1) ? 0x08 : 0x00) +

                (Window1Inverted.HasFlag(WindowingLayers.BG2) ? 0x10 : 0x00) +
                (Window1Enabled.HasFlag(WindowingLayers.BG2) ? 0x20 : 0x00) +
                (Window2Inverted.HasFlag(WindowingLayers.BG2) ? 0x40 : 0x00) +
                (Window2Enabled.HasFlag(WindowingLayers.BG2) ? 0x80 : 0x00);

            int regW34SEL =
                (Window1Inverted.HasFlag(WindowingLayers.BG3) ? 0x01 : 0x00) +
                (Window1Enabled.HasFlag(WindowingLayers.BG3) ? 0x02 : 0x00) +
                (Window2Inverted.HasFlag(WindowingLayers.BG3) ? 0x04 : 0x00) +
                (Window2Enabled.HasFlag(WindowingLayers.BG3) ? 0x08 : 0x00) +

                (Window1Inverted.HasFlag(WindowingLayers.BG4) ? 0x10 : 0x00) +
                (Window1Enabled.HasFlag(WindowingLayers.BG4) ? 0x20 : 0x00) +
                (Window2Inverted.HasFlag(WindowingLayers.BG4) ? 0x40 : 0x00) +
                (Window2Enabled.HasFlag(WindowingLayers.BG4) ? 0x80 : 0x00);

            int regWOBJSEL =
                (Window1Inverted.HasFlag(WindowingLayers.OBJ) ? 0x01 : 0x00) +
                (Window1Enabled.HasFlag(WindowingLayers.OBJ) ? 0x02 : 0x00) +
                (Window2Inverted.HasFlag(WindowingLayers.OBJ) ? 0x04 : 0x00) +
                (Window2Enabled.HasFlag(WindowingLayers.OBJ) ? 0x08 : 0x00) +

                (Window1Inverted.HasFlag(WindowingLayers.Color) ? 0x10 : 0x00) +
                (Window1Enabled.HasFlag(WindowingLayers.Color) ? 0x20 : 0x00) +
                (Window2Inverted.HasFlag(WindowingLayers.Color) ? 0x40 : 0x00) +
                (Window2Enabled.HasFlag(WindowingLayers.Color) ? 0x80 : 0x00);



            sb.OpenNewBlock();
            if (regW12SEL != 0)
            {
                sb.AppendCode("LDA #$" + regW12SEL.ToASMString(), "values for enabling/inverting BG1/BG2 on window 1/2");
                sb.AppendCode("STA $" + RAM.WindowMaskSettingBG1BG2[RAM.SA1].ToASMString(), "mirror of $2123");
            }
            if (regW34SEL != 0)
            {
                if (regW34SEL != regW12SEL)                 //prevent LDA if A still has valid value from before
                {
                    sb.AppendCode("LDA #$" + regW34SEL.ToASMString(), "values for enabling/inverting BG3/BG4 on window 1/2");
                }
                sb.AppendCode("STA $" + RAM.WindowMaskSettingBG3BG4[RAM.SA1].ToASMString(), "mirror of $2124");
            }
            if (regWOBJSEL != 0)
            {
                if (regWOBJSEL != regW34SEL)                    //prevent LDA if A still has valid value from before
                {
                    sb.AppendCode("LDA #$" + regWOBJSEL.ToASMString(), "values for enabling/inverting OBJ/Color on window 1/2");
                }
                sb.AppendCode("STA $" + RAM.WindowMaskSettingOBJColor[RAM.SA1].ToASMString(), "mirror of $2125");
            }
            if (regW12SEL != 0 || regW34SEL != 0 || regWOBJSEL != 0)
            {
                sb.AppendComment("Window 1 enabled on " + Window1Enabled.ToString());
                sb.AppendComment("Window 2 enabled on " + Window2Enabled.ToString());
                sb.AppendComment("Window 1 inverted on " + Window1Inverted.ToString());
                sb.AppendComment("Window 2 inverted on " + Window2Inverted.ToString());
            }
            sb.CloseBlock();


            return(sb.ToString());
        }