-
Notifications
You must be signed in to change notification settings - Fork 569
Creating a GUI The basics
Creating a GUI in Cosmos is hard. The code itself is easy to understand, but most of the tutorials out there are quite outdated and no longer work. Once you have a screen object the rest is quite simple but most COSMOSers get stuck at the first hurdle.
Rings are a safety feature that COSMOS uses that means the kernel (which runs in RING 3 - USER) can only talk to its own ring an the ones adjacent to it (2 - SYSTEM). This means that it is not possible to create or use a screen in the Kernel or your main COSMOS project, you need to make a new project. This will run in RING 2 - SYSTEM and will thus be able to talk to both the kernel in ring 3 and the hardware ring, where the screen lies, in ring 1 - HAL.
To do this right click on your solution on the right hand side and click Add->New Project. Then add a new COSMOS C# OS, call it Hardware. Now you need to both delete the NEW Cosmos boot project (called HardwareBoot) and the Kernel.cs file found within the main Hardware project.
The next job is to allow this project to talk to the screen. To do this right click on the references section of the Hardware project->add references. Now search for cosmos and add all the references (by selecting them with shift-click then pressing ENTER)
Now go into the AssemblyInfo.cs of the Hardware project file and add the lines bellow:
C#
using Cosmos.Common;
[assembly: Ring(Ring.System)]
vb.net
Imports Cosmos.Common
<Assembly: Ring(Ring.System)>
Well done, you now have a project running in Ring 2.
The next step is to actually make a display driver. This is quite self-explanatory. All you need to do is right-click on the hardware project and add a new C# class. Call it DisplayDriver. Now paste this code into the file: 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);
}
}
}
vb.net
Imports Cosmos.HAL
Imports Sys = Cosmos.System
Namespace Display
Public Class DisplayDriver
Protected screen As VGAScreen
Private width As Integer, height As Integer
Public Sub New()
screen = New VGAScreen()
End Sub
Public Sub init()
screen.SetGraphicsMode(VGAScreen.ScreenSize.Size320x200, VGAScreen.ColorDepth.BitDepth8)
screen.Clear(0)
width = screen.PixelWidth
height = screen.PixelHeight
End Sub
Public Overridable Sub setPixel(x As Integer, y As Integer, c As Integer)
If screen.GetPixel320x200x8(CUInt(x), CUInt(y)) <> CUInt(c) Then
setPixelRaw(x, y, c)
End If
End Sub
Public Overridable Function getPixel(x As Integer, y As Integer) As Byte
Return CByte(screen.GetPixel320x200x8(CUInt(x), CUInt(y)))
End Function
Public Overridable Sub clear()
clear(0)
End Sub
Public Overridable Sub clear(c As Integer)
screen.Clear(c)
End Sub
Public Overridable Sub [step]()
End Sub
Public Function getWidth() As Integer
Return width
End Function
Public Function getHeight() As Integer
Return height
End Function
Public Sub setPixelRaw(x As Integer, y As Integer, c As Integer)
screen.SetPixel320x200x8(CUInt(x), CUInt(y), CUInt(c))
End Sub
End Class
End Namespace
This has all the code you need for making basic screen transactions, but is quite slow and is not buffered.
To use the driver all you need to do is:
-
Add the hardware project as a reference in your main project
-
Import the class by adding
using Hardware;
to the top of your kernel -
Create a member,
display
, of your kernel class of classDisplayDriver
-
Add this code to your before run function: C#
display = new DisplayDriver(); display.init();
vb.net
display = New DisplayDriver()
display.init()
And you're done, you can now make your own GUI using the DisplayDriver
--vogon101