/// <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())); }
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()); }