cosmos 中奇怪的 GUI 问题
Weird GUI issue in cosmos
当我这样做时 display.init()
我得到这些白线和其他一些不同的像素。接下来发生的事情是它们一次消失一行,这会阻止我的 VGA 启动。
我会 post 我的内核代码和显示驱动程序。
显示驱动程序 C#
using Cosmos.HAL;
using Sys = Cosmos.System;
namespace Display
{
public class DisplayDriver
{
protected VGAScreen screen;
private int width, height;
public DisplayDriver()
{
screen = new VGAScreen();
}
public void init()
{
screen.SetGraphicsMode(VGAScreen.ScreenSize.Size320x200, VGAScreen.ColorDepth.BitDepth8);
screen.Clear(0);
width = screen.PixelWidth;
height = screen.PixelHeight;
}
public virtual void setPixel(int x, int y, int c)
{
if (screen.GetPixel320x200x8((uint)x, (uint)y) != (uint)c)
setPixelRaw(x, y, c);
}
public virtual byte getPixel(int x, int y)
{
return (byte)screen.GetPixel320x200x8((uint)x, (uint)y);
}
public virtual void clear()
{
clear(0);
}
public virtual void clear(int c)
{
screen.Clear(c);
}
public virtual void step() { }
public int getWidth()
{
return width;
}
public int getHeight()
{
return height;
}
public void setPixelRaw(int x, int y, int c)
{
screen.SetPixel320x200x8((uint)x, (uint)y, (uint)c);
}
}
}
内核:
using System;
using Sys = Cosmos.System;
using Display;
using Cosmos.Core;
using Cosmos.HAL;
using Cosmos.Common;
using Cosmos.Debug;
using Cosmos.IL2CPU;
namespace CosmosKernel3
{
public class Kernel : Sys.Kernel
{
protected override void BeforeRun()
{
Console.WriteLine("Booting VGADriver.");
try
{
var display = new DisplayDriver();
Console.WriteLine("ATTEMPTING");
display.init(); //init display
display.clear();
display.setPixel((int)40, 50, 60);
}
catch (Exception)
{
Console.WriteLine("Booting VGA failed. Booting into DOS mode.");
dosemergency();
}
}
protected override void Run()
{
boot();
while (true) ;
}
public static void boot()
{
}
public static void dosemergency()
{
Console.WriteLine("XENA DOS EMERGENCY MODE.");
Console.WriteLine("COMMANDS:");
Console.WriteLine("graphics -r (Graphics retry)");
String meow = Console.ReadLine();
if (meow == "graphics -r") ;
Console.WriteLine("Booting VGADriver.");
try
{
var display = new DisplayDriver();
display.init(); //init display
boot(); //boot
}
catch (Exception)
{
Console.WriteLine("Booting VGA failed. Booting into DOS mode.");
dosemergency();
}
}
}
}
屏幕截图:
无论如何,这已经发生了一段时间,我似乎无法弄清楚为什么会这样。求助!
不知道是不是太晚了,不过这个问题在 Cosmos 很流行,所以未来的读者可能会找到这个答案。
您的代码是正确的。在与其中一位开发人员交谈后,他告诉我他们已经意识到了这个问题,它的发生是因为
current code [of Cosmos] uses delegates for pixelputting
如果您等待 1-2 分钟,屏幕将最终加载。
编辑:
我找到了一种可以大大加快这个过程的方法:
从不打电话
Screen.clear()
函数
改为创建以下函数:
public void DrawFilledRectangle(uint x0, uint y0, int Width, int Height, int color)
{
for (uint i = 0; i < Width; i++)
{
for (uint h = 0; h < Height; h++)
{
setPixel((int)(x0 + i), (int)(y0 + h), color);
}
}
}
并替换
public virtual void clear(int c)
{
screen.Clear(c);
}
函数
通过:
public virtual void clear(int c)
{
//screen.Clear(c);
DrawFilledRectangle(0, 0, width, height, c);
}
还将 init 函数替换为:
public void init()
{
screen.SetGraphicsMode(VGAScreen.ScreenSize.Size320x200, VGAScreen.ColorDepth.BitDepth8);
width = screen.PixelWidth;
height = screen.PixelHeight;
clear(0);
}
哪个更快。祝你创建 OS :)
好运
当我这样做时 display.init()
我得到这些白线和其他一些不同的像素。接下来发生的事情是它们一次消失一行,这会阻止我的 VGA 启动。
我会 post 我的内核代码和显示驱动程序。
显示驱动程序 C#
using Cosmos.HAL;
using Sys = Cosmos.System;
namespace Display
{
public class DisplayDriver
{
protected VGAScreen screen;
private int width, height;
public DisplayDriver()
{
screen = new VGAScreen();
}
public void init()
{
screen.SetGraphicsMode(VGAScreen.ScreenSize.Size320x200, VGAScreen.ColorDepth.BitDepth8);
screen.Clear(0);
width = screen.PixelWidth;
height = screen.PixelHeight;
}
public virtual void setPixel(int x, int y, int c)
{
if (screen.GetPixel320x200x8((uint)x, (uint)y) != (uint)c)
setPixelRaw(x, y, c);
}
public virtual byte getPixel(int x, int y)
{
return (byte)screen.GetPixel320x200x8((uint)x, (uint)y);
}
public virtual void clear()
{
clear(0);
}
public virtual void clear(int c)
{
screen.Clear(c);
}
public virtual void step() { }
public int getWidth()
{
return width;
}
public int getHeight()
{
return height;
}
public void setPixelRaw(int x, int y, int c)
{
screen.SetPixel320x200x8((uint)x, (uint)y, (uint)c);
}
}
}
内核:
using System;
using Sys = Cosmos.System;
using Display;
using Cosmos.Core;
using Cosmos.HAL;
using Cosmos.Common;
using Cosmos.Debug;
using Cosmos.IL2CPU;
namespace CosmosKernel3
{
public class Kernel : Sys.Kernel
{
protected override void BeforeRun()
{
Console.WriteLine("Booting VGADriver.");
try
{
var display = new DisplayDriver();
Console.WriteLine("ATTEMPTING");
display.init(); //init display
display.clear();
display.setPixel((int)40, 50, 60);
}
catch (Exception)
{
Console.WriteLine("Booting VGA failed. Booting into DOS mode.");
dosemergency();
}
}
protected override void Run()
{
boot();
while (true) ;
}
public static void boot()
{
}
public static void dosemergency()
{
Console.WriteLine("XENA DOS EMERGENCY MODE.");
Console.WriteLine("COMMANDS:");
Console.WriteLine("graphics -r (Graphics retry)");
String meow = Console.ReadLine();
if (meow == "graphics -r") ;
Console.WriteLine("Booting VGADriver.");
try
{
var display = new DisplayDriver();
display.init(); //init display
boot(); //boot
}
catch (Exception)
{
Console.WriteLine("Booting VGA failed. Booting into DOS mode.");
dosemergency();
}
}
}
}
屏幕截图:
无论如何,这已经发生了一段时间,我似乎无法弄清楚为什么会这样。求助!
不知道是不是太晚了,不过这个问题在 Cosmos 很流行,所以未来的读者可能会找到这个答案。
您的代码是正确的。在与其中一位开发人员交谈后,他告诉我他们已经意识到了这个问题,它的发生是因为
current code [of Cosmos] uses delegates for pixelputting
如果您等待 1-2 分钟,屏幕将最终加载。
编辑:
我找到了一种可以大大加快这个过程的方法: 从不打电话
Screen.clear()
函数
改为创建以下函数:
public void DrawFilledRectangle(uint x0, uint y0, int Width, int Height, int color)
{
for (uint i = 0; i < Width; i++)
{
for (uint h = 0; h < Height; h++)
{
setPixel((int)(x0 + i), (int)(y0 + h), color);
}
}
}
并替换
public virtual void clear(int c)
{
screen.Clear(c);
}
函数 通过:
public virtual void clear(int c)
{
//screen.Clear(c);
DrawFilledRectangle(0, 0, width, height, c);
}
还将 init 函数替换为:
public void init()
{
screen.SetGraphicsMode(VGAScreen.ScreenSize.Size320x200, VGAScreen.ColorDepth.BitDepth8);
width = screen.PixelWidth;
height = screen.PixelHeight;
clear(0);
}
哪个更快。祝你创建 OS :)
好运