/// <summary> /// Draw the frame buffer to the screen. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void Gpu_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; g.Clear(BackColor); if (VRAM == null) { g.DrawString("VRAM Not initialized", this.Font, TextBrush, 0, 0); return; } if (CodeRAM == null) { g.DrawString("CodeRAM Not initialized", this.Font, TextBrush, 0, 0); return; } if (ColumnsVisible < 1 || ColumnsVisible > 128) { g.DrawString("ColumnsVisible invalid:" + ColumnsVisible.ToString(), this.Font, TextBrush, 0, 0); return; } if (LinesVisible < 1) { g.DrawString("LinesVisible invalid:" + LinesVisible.ToString(), this.Font, TextBrush, 0, 0); return; } //DrawVectorText(e.Graphics); DrawBitmapText(e.Graphics); }
void Gpu_Paint(object sender, PaintEventArgs e) { paintCycle++; //if (VICKY == null) //{ // e.Graphics.DrawString("IO Memory Not Initialized", this.Font, TextBrush, 0, 0); // return; //} //if (VRAM == null) //{ // e.Graphics.DrawString("VRAM Not Initialized", this.Font, TextBrush, 0, 0); // return; //} //if (RAM == null || DesignMode) if (DesignMode) { e.Graphics.DrawString("RAM Not Initialized", this.Font, TextBrush, 0, 0); return; } // Read the Master Control Register //byte MCRegister = VICKY.ReadByte(0); // Reading address $AF:0000 byte MCRegister = FoenixSystem.Current.MemoryManager.ReadByte(MemoryMap.VICKY_BASE_ADDR); // Reading address $AF:0000 if (MCRegister == 0 || (MCRegister & 0x80) == 0x80) { e.Graphics.DrawString("Graphics Mode disabled", this.Font, TextBrush, 0, 0); return; } if (drawing) { return; } drawing = true; e.Graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy; e.Graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed; e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed; if (MCRegister != 0 && MCRegister != 0x80) { StartOfFrame?.Invoke(); } Graphics g = Graphics.FromImage(frameBuffer); // Determine if we display a border int border_register = FoenixSystem.Current.MemoryManager.ReadByte(MemoryMap.VICKY_BASE_ADDR + 4); //VICKY.ReadByte(4); bool displayBorder = (border_register & 1) == 1; int colOffset = FoenixSystem.Current.MemoryManager.ReadByte(MemoryMap.VICKY_BASE_ADDR + 8); //VICKY.ReadByte(8); int rowOffset = FoenixSystem.Current.MemoryManager.ReadByte(MemoryMap.VICKY_BASE_ADDR + 9); //VICKY.ReadByte(9); // Load Graphical LUTs graphicsLUT = LoadLUT(); // Apply gamma correct if ((MCRegister & 0x40) == 0x40) { gammaCorrection = LoadGammaCorrection(); } else { gammaCorrection = null; } // Default background color to border color // In Text mode, the border color is stored at $AF:0005. byte borderRed = FoenixSystem.Current.MemoryManager.ReadByte(MemoryMap.VICKY_BASE_ADDR + 5); //VICKY.ReadByte(5); byte borderGreen = FoenixSystem.Current.MemoryManager.ReadByte(MemoryMap.VICKY_BASE_ADDR + 6); //VICKY.ReadByte(6); byte borderBlue = FoenixSystem.Current.MemoryManager.ReadByte(MemoryMap.VICKY_BASE_ADDR + 7); //VICKY.ReadByte(7); if (gammaCorrection != null) { borderRed = gammaCorrection[0x200 + borderRed]; borderGreen = gammaCorrection[0x100 + borderGreen]; borderBlue = gammaCorrection[borderBlue]; } int borderColor = (int)(0xFF000000 + (borderBlue << 16) + (borderGreen << 8) + borderRed); if (tileEditorMode) { g.Clear(Color.LightGray); DrawTextWithBackground("Tile Editing Mode", g, Color.Black, 240, 10); DrawTextWithBackground("Tile Editing Mode", g, Color.Black, 240, 455); } else { g.Clear(Color.FromArgb(borderColor)); } // Graphics Mode if ((MCRegister & 0x4) == 0x4) { byte backRed = FoenixSystem.Current.MemoryManager.ReadByte(MemoryMap.VICKY_BASE_ADDR + 0xD); //VICKY.ReadByte(0xD); byte backGreen = FoenixSystem.Current.MemoryManager.ReadByte(MemoryMap.VICKY_BASE_ADDR + 0xE); //VICKY.ReadByte(0XE); byte backBlue = FoenixSystem.Current.MemoryManager.ReadByte(MemoryMap.VICKY_BASE_ADDR + 0xF); //VICKY.ReadByte(0xF); if (gammaCorrection != null) { backRed = gammaCorrection[0x200 + backRed]; backGreen = gammaCorrection[0x100 + backGreen]; backBlue = gammaCorrection[backBlue]; } int backgroundColor = (int)(0xFF000000 + (backBlue << 16) + (backGreen << 8) + backRed); Brush graphBackgroundBrush = new SolidBrush(Color.FromArgb(backgroundColor)); g.FillRectangle(graphBackgroundBrush, colOffset, rowOffset, 640 - 2 * colOffset, 480 - 2 * rowOffset); } // Bitmap Mode if ((MCRegister & 0x8) == 0x8) { DrawBitmap(frameBuffer, displayBorder); } for (int layer = 4; layer > 0; --layer) { if ((MCRegister & 0x10) == 0x10) { DrawTiles(frameBuffer, layer - 1, displayBorder); } if ((MCRegister & 0x20) == 0x20) { DrawSprites(frameBuffer, layer - 1, displayBorder); } } if ((MCRegister & 0x1) == 0x1) { int top = 0; if (ColumnsVisible < 1 || ColumnsVisible > MAX_TEXT_COLS) { Graphics graphics = Graphics.FromImage(frameBuffer); DrawTextWithBackground("ColumnsVisible invalid:" + ColumnsVisible.ToString(), graphics, Color.Black, 0, top); top += 12; } if (LinesVisible < 1 || LinesVisible > MAX_TEXT_LINES) { Graphics graphics = Graphics.FromImage(frameBuffer); DrawTextWithBackground("LinesVisible invalid:" + LinesVisible.ToString(), graphics, Color.Black, 0, top); top += 12; } if (top == 0) { DrawBitmapText(frameBuffer, colOffset, rowOffset); } } byte mouseReg = FoenixSystem.Current.MemoryManager.ReadByte(MemoryMap.VICKY_BASE_ADDR + 0x700); //VICKY.ReadByte(0x700); MousePointerMode = (mouseReg & 1) == 1; if (MousePointerMode && !TileEditorMode) { DrawMouse(frameBuffer); } e.Graphics.DrawImage(frameBuffer, ClientRectangle); drawing = false; }
void Gpu_Paint(object sender, PaintEventArgs e) { paintCycle++; if (DesignMode) { e.Graphics.DrawString("Design Mode", this.Font, TextBrush, 0, 0); return; } if (VICKY == null) { e.Graphics.DrawString("IO Memory Not Initialized", this.Font, TextBrush, 0, 0); return; } if (VRAM == null) { e.Graphics.DrawString("VRAM Not Initialized", this.Font, TextBrush, 0, 0); return; } if (RAM == null) { e.Graphics.DrawString("RAM Not Initialized", this.Font, TextBrush, 0, 0); return; } // Read the Master Control Register byte MCRegister = VICKY.ReadByte(0); // Reading address $AF:0000 int top = 0; // top gets modified if error messages are displayed Graphics g = Graphics.FromImage(frameBuffer); if (MCRegister == 0 || (MCRegister & 0x80) == 0x80) { e.Graphics.DrawString("Graphics Mode disabled", this.Font, TextBrush, 0, 0); return; } else if ((MCRegister & 0x1) == 0x1) { if (ColumnsVisible < 1 || ColumnsVisible > MAX_TEXT_COLS) { DrawTextWithBackground("ColumnsVisible invalid:" + ColumnsVisible.ToString(), g, Color.Black, 0, top); top += 12; } if (LinesVisible < 1 || LinesVisible > MAX_TEXT_LINES) { DrawTextWithBackground("LinesVisible invalid:" + LinesVisible.ToString(), g, Color.Black, 0, top); top += 12; } } if (drawing) { // drop the frame return; } drawing = true; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); e.Graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy; e.Graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed; e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed; // Determine if we display a border int border_register = VICKY.ReadByte(4); bool displayBorder = (border_register & 1) == 1; int colOffset = VICKY.ReadByte(8); int rowOffset = VICKY.ReadByte(9); // Load Graphical LUTs graphicsLUT = LoadLUT(VICKY); // Apply gamma correct if ((MCRegister & 0x40) == 0x40) { gammaCorrection = LoadGammaCorrection(VICKY); } else { gammaCorrection = null; } // Default background color to border color // In Text mode, the border color is stored at $AF:0005. byte borderRed = VICKY.ReadByte(5); byte borderGreen = VICKY.ReadByte(6); byte borderBlue = VICKY.ReadByte(7); if (gammaCorrection != null) { borderRed = gammaCorrection[0x200 + borderRed]; borderGreen = gammaCorrection[0x100 + borderGreen]; borderBlue = gammaCorrection[borderBlue]; } int borderColor = (int)(0xFF000000 + (borderBlue << 16) + (borderGreen << 8) + borderRed); if (tileEditorMode) { g.Clear(Color.LightGray); DrawTextWithBackground("Tile Editing Mode", g, Color.Black, 240, 10); DrawTextWithBackground("Tile Editing Mode", g, Color.Black, 240, 455); } else { g.Clear(Color.FromArgb(borderColor)); } // Graphics Mode if ((MCRegister & 0x4) == 0x4) { byte backRed = VICKY.ReadByte(0xD); byte backGreen = VICKY.ReadByte(0XE); byte backBlue = VICKY.ReadByte(0xF); if (gammaCorrection != null) { backRed = gammaCorrection[0x200 + backRed]; backGreen = gammaCorrection[0x100 + backGreen]; backBlue = gammaCorrection[backBlue]; } int backgroundColor = (int)(0xFF000000 + (backBlue << 16) + (backGreen << 8) + backRed); Brush graphBackgroundBrush = new SolidBrush(Color.FromArgb(backgroundColor)); g.FillRectangle(graphBackgroundBrush, colOffset, rowOffset, 640 - 2 * colOffset, 480 - 2 * rowOffset); } Rectangle rect = new Rectangle(0, 0, 640, 480); BitmapData bitmapData = frameBuffer.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); // Bitmap Mode if ((MCRegister & 0x4) == 0x4 || tileEditorMode) { if ((MCRegister & 0x8) == 0x8) { DrawBitmap(ref bitmapData, displayBorder); } for (int layer = 4; layer > 0; --layer) { if ((MCRegister & 0x10) == 0x10) { DrawTiles(ref bitmapData, layer - 1, 640, displayBorder); } if ((MCRegister & 0x20) == 0x20) { DrawSprites(ref bitmapData, layer - 1, 640, displayBorder); } } } if ((MCRegister & 7) == 0x1 || (MCRegister & 7) == 3 || (MCRegister & 7) == 7) { if (top == 0) { DrawBitmapText(ref bitmapData, colOffset, rowOffset); } } byte mouseReg = VICKY.ReadByte(0x700); MousePointerMode = (mouseReg & 1) == 1; if (MousePointerMode && !TileEditorMode) { DrawMouse(ref bitmapData, 640); } frameBuffer.UnlockBits(bitmapData); e.Graphics.DrawImage(frameBuffer, ClientRectangle); drawing = false; stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; if (ts.Milliseconds > 10) { Console.WriteLine("Drawing Time: " + ts.Milliseconds + "ms"); } // This seems to make the rendering much better. Do we care if this is 1 frame off? if (MCRegister != 0 && MCRegister != 0x80) { StartOfFrame?.Invoke(); } }