diff --git a/src/driver/video/vesa32.pas b/src/driver/video/vesa32.pas index 18adf7b3..9d316baa 100644 --- a/src/driver/video/vesa32.pas +++ b/src/driver/video/vesa32.pas @@ -35,11 +35,11 @@ var LocationIndex : Uint32; begin - tracer.push_trace('vesa32.DrawPixel.enter'); + //tracer.push_trace('vesa32.DrawPixel.enter'); Location:= Puint32(Buffer^.Location); LocationIndex:= (Y * Buffer^.Width) + X; Location[LocationIndex]:= uint32(Pixel); - tracer.push_trace('vesa32.DrawPixel.exit'); + //tracer.push_trace('vesa32.DrawPixel.exit'); end; procedure init(DrawRoutines : PDrawRoutines); diff --git a/src/driver/video/video.pas b/src/driver/video/video.pas index bf23555f..62fdce87 100644 --- a/src/driver/video/video.pas +++ b/src/driver/video/video.pas @@ -22,13 +22,18 @@ unit video; interface uses - lmemorymanager, tracer, color, videotypes, hashmap; + lmemorymanager, tracer, color, videotypes, hashmap, util; procedure init(); procedure DrawPixel(X : uint32; Y : uint32; Pixel : TRGB32); +procedure DrawLine(x1,y1,x2,y2 : uint32; thickness : uint32; Color : TRGB32); +procedure DrawRect(x1,y1,x2,y2 : uint32; line_thickness : uint32; Color : TRGB32); +procedure FillRect(x1,y1,x2,y2 : uint32; line_thickness : uint32; Line_Color : TRGB32; Fill_Color : TRGB32); procedure Flush(); + function register(DriverIdentifier : pchar; EnableCallback : FEnableDriver) : boolean; function enable(DriverIdentifier : pchar) : boolean; + function frontBufferWidth : uint32; function frontBufferHeight : uint32; function frontBufferBpp : uint8; @@ -41,13 +46,125 @@ implementation Procedure dummyFDrawPixel(Buffer : PVideoBuffer; X : uint32; Y : uint32; Pixel : TRGB32); begin tracer.push_trace('video.dummyFDrawPixel.enter'); - //Do nothing + //Do nothing, this is the most basic function that must be implemented by a driver. end; -Procedure dummyFFlush(FrontBuffer : PVideoBuffer; BackBuffer : PVideoBuffer); +Procedure basicFFlush(FrontBuffer : PVideoBuffer; BackBuffer : PVideoBuffer); +var + x, y : uint32; + Back,Front : puint32; + begin - tracer.push_trace('video.dummyFFlush.enter'); - //Do nothing + tracer.push_trace('video.basicFFlush.enter'); + If not(FrontBuffer^.Initialized and BackBuffer^.Initialized) then exit; + if (BackBuffer^.Width > FrontBuffer^.Width) or (BackBuffer^.Height > FrontBuffer^.Height) then exit; + Back:= puint32(BackBuffer^.Location); + Front:= puint32(FrontBuffer^.Location); + for x:=0 to BackBuffer^.Width-1 do begin + for y:=0 to BackBuffer^.Height-1 do begin + Front[(Y * BackBuffer^.Width) + X]:= Back[(Y * BackBuffer^.Width) + X]; + end; + end; +end; + +procedure basicFDrawLine(Buffer : PVideoBuffer; x1,y1,x2,y2 : uint32; thickness : uint32; Color : TRGB32); +var + X, Y, DX, DY, DX1, DY1, PX, PY, XE, YE, I : sint32; + +begin + tracer.push_trace('video.basicFDrawLine.enter'); + + if(x1 = x2) then begin + for Y:=Y1 to Y2 do begin + DrawPixel(X1,Y,Color); + end; + end else if (y1 = y2) then begin + for X:=X1 to X2 do begin + DrawPixel(X,Y1,Color); + end; + end else begin + DX:= X2 - X1; + DY:= Y2 - Y1; + + DX1:= util.abs(DX); + DY1:= util.abs(DY); + + PX:= 2 * DY1 - DX1; + PY:= 2 * DX1 - DY1; + + if (DY1 <= DX1) then begin + if (dx >= 0) then begin + X:= X1; Y:= Y1; XE:= X2; + end else begin + X:= X2; Y:= Y2; XE:= X1; + end; + + DrawPixel(X, Y, Color); + + I:=0; + while (x < xe) do begin + X:= X + 1; + if (PX < 0) then begin + PX:= PX + 2 + DY1; + end else begin + if(((dx < 0) and (dy < 0)) OR ((dx > 0) and (dy > 0))) then begin + Y:= Y + 1; + end else begin + Y:= Y - 1; + end; + PX:= PX + 2 * (DY1 - DX1); + end; + DrawPixel(X,Y,Color); + I:= I + 1; + end; + end else begin + if (DY >= 0) then begin + X:= X1; Y:= Y1; YE:= Y2; + end else begin + X:= X2; Y:= Y2; YE:= Y1; + end; + + DrawPixel(X, Y, Color); + + I:=0; + while (Y < YE) do begin + Y:= Y + 1; + if (PY <= 0) then begin + PY:= PY + 2 * DX1; + end else begin + if (((dx < 0) and (dy < 0)) OR ((dx > 0) and (dy > 0))) then begin + X:= X + 1; + end else begin + X:= X - 1; + end; + PY:= PY + 2 * (dx1 - dy1); + end; + DrawPixel(X,Y,Color); + I:= I + 1; + end; + end; + end; +end; + +procedure basicFDrawRect(Buffer : PVideoBuffer; x1,y1,x2,y2 : uint32; line_thickness : uint32; Color : TRGB32); +begin + tracer.push_trace('video.basicFDrawRect.enter'); + DrawLine(x1,y1,x2,y1,line_thickness,Color); + DrawLine(x1,y2,x2,y2,line_thickness,Color); + DrawLine(x1,y1,x1,y2,line_thickness,Color); + DrawLine(x2,y1,x2,y2,line_thickness,Color); +end; + +procedure basicFFillRect(Buffer : PVideoBuffer; x1,y1,x2,y2 : uint32; line_thickness : uint32; Line_Color : TRGB32; Fill_Color : TRGB32); +var + Y : uint32; + +begin + tracer.push_trace('video.basicFFillRect.enter'); + for Y:=y1 to y2 do begin + DrawLine(x1,y,x2,y,line_thickness,Fill_Color); + end; + DrawRect(x1,y1,x2,y2,line_thickness,Line_Color); end; var @@ -61,12 +178,34 @@ var begin tracer.push_trace('video.init.enter'); + //Ensure the frontbuffer is empty & nil, ready for initialization by a driver. VideoInterface.FrontBuffer.Initialized:= false; + VideoInterface.FrontBuffer.Width:= 0; + VideoInterface.FrontBuffer.Height:= 0; + VideoInterface.FrontBuffer.BitsPerPixel:= 0; + VideoInterface.FrontBuffer.Location:= 0; + + //Ensure the backbuffer is empty & nil, ready for initialization by a driver. VideoInterface.BackBuffer.Initialized:= false; + VideoInterface.BackBuffer.Width:= 0; + VideoInterface.BackBuffer.Height:= 0; + VideoInterface.BackBuffer.BitsPerPixel:= 0; + VideoInterface.BackBuffer.Location:= 0; + + //Set the default buffer to be the FrontBuffer, assume no double buffering to begin with. VideoInterface.DefaultBuffer:= @VideoInterface.FrontBuffer; + + { Set the draw routines to point to dummy/empty routines. + Calls will still succeed but do nothing until a driver has registered. } VideoInterface.DrawRoutines.DrawPixel:= @dummyFDrawPixel; - VideoInterface.DrawRoutines.Flush:= @dummyFFlush; + VideoInterface.DrawRoutines.Flush:= @basicFFlush; + VideoInterface.DrawRoutines.DrawLine:= @basicFDrawLine; + VideoInterface.DrawRoutines.DrawRect:= @basicFDrawRect; + VideoInterface.DrawRoutines.FillRect:= @basicFFillRect; + + //Initialize our 'DriverMap', a hashmap of loadable display drivers. DriverMap:= hashmap.new; + tracer.push_trace('video.init.exit'); end; @@ -101,16 +240,31 @@ end; procedure DrawPixel(X : uint32; Y : uint32; Pixel : TRGB32); begin - tracer.push_trace('video.DrawPixel.enter'); + //tracer.push_trace('video.DrawPixel.enter'); VideoInterface.DrawRoutines.DrawPixel(VideoInterface.DefaultBuffer, X, Y, Pixel); - tracer.push_trace('video.DrawPixel.exit'); + //tracer.push_trace('video.DrawPixel.exit'); end; procedure Flush(); begin - tracer.push_trace('video.Flush.enter'); + //tracer.push_trace('video.Flush.enter'); VideoInterface.DrawRoutines.Flush(@VideoInterface.FrontBuffer, @VideoInterface.BackBuffer); - tracer.push_trace('video.Flush.exit'); + //tracer.push_trace('video.Flush.exit'); +end; + +procedure DrawLine(x1,y1,x2,y2 : uint32; thickness : uint32; Color : TRGB32); +begin + VideoInterface.DrawRoutines.DrawLine(VideoInterface.DefaultBuffer,x1,y1,x2,y2,thickness,Color); +end; + +procedure DrawRect(x1,y1,x2,y2 : uint32; line_thickness : uint32; Color : TRGB32); +begin + VideoInterface.DrawRoutines.DrawRect(VideoInterface.DefaultBuffer,x1,y1,x2,y2,line_thickness,color); +end; + +procedure FillRect(x1,y1,x2,y2 : uint32; line_thickness : uint32; Line_Color : TRGB32; Fill_Color : TRGB32); +begin + VideoInterface.DrawRoutines.FillRect(VideoInterface.DefaultBuffer,x1,y1,x2,y2,line_thickness,Line_Color,Fill_Color); end; function frontBufferWidth : uint32; diff --git a/src/driver/video/videotypes.pas b/src/driver/video/videotypes.pas index ee6d0d17..22bf512d 100644 --- a/src/driver/video/videotypes.pas +++ b/src/driver/video/videotypes.pas @@ -25,7 +25,7 @@ uses color; type - //Arbitrary pointer to a video buffer in memory + //Arbitrary pointer to a raw video buffer in memory VideoBuffer = uint32; //Struct representing a Memory Mapped Video Buffer @@ -48,11 +48,20 @@ type FDrawPixel = procedure(Buffer : PVideoBuffer; X : uint32; Y : uint32; Pixel : TRGB32); //(Abstract) Flush backbuffer to MMIO Buffer FFlush = procedure(FrontBuffer : PVideoBuffer; BackBuffer : PVideoBuffer); + //(Abstract) Draw a line to the screen + FDrawLine = procedure(Buffer : PVideoBuffer; x1,y1,x2,y2 : uint32; thickness : uint32; Color : TRGB32); + //(Abstract) Draw a rect to the screen + FDrawRect = procedure(Buffer : PVideoBuffer; x1,y1,x2,y2 : uint32; line_thickness : uint32; Color : TRGB32); + //(Abstract) Draw a filled rect to the screen + FFillRect = procedure(Buffer : PVideoBuffer; x1,y1,x2,y2 : uint32; line_thickness : uint32; Line_Color : TRGB32; Fill_Color : TRGB32); //Routines for drawing to the screen TDrawRoutines = record DrawPixel : FDrawPixel; Flush : FFlush; + DrawLine : FDrawLine; + DrawRect : FDrawRect; + FillRect : FFillRect; end; //Pointer to drawing routines PDrawRoutines = ^TDrawRoutines; diff --git a/src/include/util.pas b/src/include/util.pas index 9db9096e..39093f8f 100644 --- a/src/include/util.pas +++ b/src/include/util.pas @@ -80,6 +80,8 @@ function RorDWord(AValue : uint32; Dist : uint8) : uint32; function MsSinceSystemBoot : uint64; +function abs(x : sint32) : uint32; + var endptr : uint32; external name '__end'; stack : uint32; external name 'KERNEL_STACK'; @@ -89,6 +91,15 @@ implementation uses console, RTC, cpu, serial, strings, isr_types; +function abs(x : sint32) : uint32; +var + y : uint32; + +begin + y:= x SHR 31; + abs:= (x XOR y) - y; +end; + function MsSinceSystemBoot : uint64; begin MsSinceSystemBoot:= div6432(getTSC, (CPUID.ClockSpeed.Hz div 1000)); diff --git a/src/kernel.pas b/src/kernel.pas index bfac8bf7..eb0c7ea8 100644 --- a/src/kernel.pas +++ b/src/kernel.pas @@ -211,24 +211,22 @@ begin doublebuffer.init(@video.register); video.enable('VESA'); video.enable('BASIC_DOUBLE_BUFFER'); - colour:= color.red; - while true do begin - for i:=0 to video.frontBufferWidth-1 do begin - for z:=0 to video.frontBufferHeight-1 do begin - video.DrawPixel(i, z, colour); - end; - end; - - if uint32(colour) = uint32(color.red) then - colour:= color.green - else if uint32(colour) = uint32(color.green) then - colour:= color.blue - else if uint32(colour) = uint32(color.blue) then - colour:= color.red; + colour:= color.white; - video.Flush(); + for i:=0 to video.frontBufferWidth-1 do begin + for z:=0 to video.frontBufferHeight-1 do begin + video.DrawPixel(i, z, colour); + end; end; + video.DrawLine(50,50,100,100,1,color.black); + video.DrawRect(50,150,100,200,1,color.black); + video.FillRect(50,250,100,300,1,color.black,color.red); + video.DrawLine(50,350,100,350,1,color.black); + video.Flush(); + + while true do begin end; + { VFS Init } vfs.init();