Search code examples
c#cosmos

Weird GUI issue in cosmos


When i do display.init() I get these white lines and a few other different pixels. The next thing that happens is they disappear one line at a time and it's preventing my VGA from booting.

I'll post my kernel code and display driver.

DISPLAY DRIVER 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);

        }
    }
  }

KERNEL:

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


            }



        }
    }
}

SCREENSHOT:

enter image description here

Anyway, this has been happening for a while now and I cant seem to figure out why its doing this. Help!


Solution

  • I don't know if it's not too late, however this issue is popular in Cosmos, so future readers might find this answer.

    Your code is correct. After talking with one of the devs he told me that they are aware of the issue and it happens because

    current code [of Cosmos] uses delegates for pixelputting

    If you wait 1-2 minutes, the screen will finally load.

    edit:

    I found a way to speed up this process a lot: never call

    Screen.clear()
    

    function

    Instead create the following function:

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

    and replace

    public virtual void clear(int c)
        {
            screen.Clear(c);
        }
    

    function by:

            public virtual void clear(int c)
        {
            //screen.Clear(c);
            DrawFilledRectangle(0, 0, width, height, c);
        }
    

    Also replace init function by:

    public void init()
        {
            screen.SetGraphicsMode(VGAScreen.ScreenSize.Size320x200, VGAScreen.ColorDepth.BitDepth8);
            width = screen.PixelWidth;
            height = screen.PixelHeight;
            clear(0);
        }
    

    Which is much faster. Good luck in creating your OS :)