From d057bfc3ff3664f3cb0e949480b2803f8e3396c5 Mon Sep 17 00:00:00 2001
From: Kieron Morris <kjm@kieronmorris.me>
Date: Wed, 23 Jun 2021 22:19:55 +0100
Subject: [PATCH] Expaneded Video.pas and addec color.pas

Backbuffer will need modification to lmemorymanager to remove the limits to allocation size.
---
 src/driver/video/video.pas | 96 +++++++++++++++++++++++++++++++-------
 src/include/color.pas      | 10 ++++
 src/kernel.pas             |  4 +-
 3 files changed, 91 insertions(+), 19 deletions(-)

diff --git a/src/driver/video/video.pas b/src/driver/video/video.pas
index 511f7646..0c6f3db4 100644
--- a/src/driver/video/video.pas
+++ b/src/driver/video/video.pas
@@ -3,29 +3,59 @@ unit video;
 interface
 
 uses
-    multiboot, lmemorymanager, tracer, color, rand;
+    multiboot, lmemorymanager, tracer, color, rand, console;
 
 procedure init();
 procedure DrawPixel(X : uint32; Y : uint32; Pixel : TRGB32);
+procedure Flush();
 
 type
+    VideoBuffer = uint64;
     TVESALinearBuffer = record
-        Location        : uint64;
+        Initialized     : Boolean;
+        Location        : VideoBuffer;
+        BitsPerPixel    : uint8;
+        Width           : uint32;
+        Height          : uint32;
+    end;
+    TBackBuffer = record
+        Initialized     : Boolean;
+        Location        : VideoBuffer;
         BitsPerPixel    : uint8;
         Width           : uint32;
         Height          : uint32;
     end;
     TVESA = record
-        initialized : Boolean;
-        Framebuffer : TVESALinearBuffer;
+        DefaultBuffer   : VideoBuffer;
+        Framebuffer     : TVESALinearBuffer;
+        BackBuffer      : TBackBuffer;
     end;
+    PVESA = ^TVESA;
 
 implementation
 
 var
     VESA : TVESA;
 
-procedure allocateFrameBuffer(Address : uint32; Width : uint32; Height : uint32);
+function allocateBackBuffer(Width : uint32; Height : uint32; BitsPerPixel : uint8) : uint64;
+begin
+    Outputln('VIDEO','Start Kalloc Backbuffer');
+    //This doesn't currently work... Needs a rework of lmemorymanager
+    allocateBackBuffer:= uint64(kalloc((Width * Height) * BitsPerPixel));
+    Outputln('VIDEO','End Kalloc Backbuffer');
+end;
+
+procedure initBackBuffer(VESAInfo : PVESA; Width : uint32; Height : uint32; BitsPerPixel : uint8);
+begin
+    VESAInfo^.BackBuffer.Width:= Width;
+    VESAInfo^.BackBuffer.Height:= Height;
+    VESAInfo^.BackBuffer.BitsPerPixel:= BitsPerPixel;
+    VESAInfo^.BackBuffer.Location:= allocateBackBuffer(VESAInfo^.BackBuffer.Width, VESAInfo^.BackBuffer.Height, VESAInfo^.BackBuffer.BitsPerPixel);
+    VESAInfo^.DefaultBuffer:= VESAInfo^.BackBuffer.Location;
+    VESAInfo^.BackBuffer.Initialized:= True;
+end;
+
+procedure allocateVESAFrameBuffer(Address : uint32; Width : uint32; Height : uint32);
 var
     LowerAddress, UpperAddress : uint32;
     Block : uint32;
@@ -40,6 +70,19 @@ begin
     tracer.push_trace('video.allocateFrameBuffer.enter');
 end;
 
+procedure initVESAFrameBuffer(VESAInfo : PVESA; Location : uint64; Width : uint32; Height : uint32; BitsPerPixel : uint8);
+begin
+    if not(VESAInfo^.Framebuffer.Initialized) then begin
+        VESAInfo^.Framebuffer.Location:= Location;
+        VESAInfo^.Framebuffer.BitsPerPixel:= BitsPerPixel;
+        VESAInfo^.Framebuffer.Width:= Width;
+        VESAInfo^.Framebuffer.Height:= Height;
+        allocateVESAFrameBuffer(VESAInfo^.Framebuffer.Location, VESAInfo^.Framebuffer.Width, VESAInfo^.Framebuffer.Height);
+        VESAInfo^.DefaultBuffer:= VESAInfo^.Framebuffer.Location;
+        VESAInfo^.Framebuffer.Initialized:= True;
+    end;
+end;
+
 procedure init();
 var
     RGB : TRGB32;
@@ -47,14 +90,12 @@ var
 
 begin
     tracer.push_trace('video.init.enter');
-    If not(VESA.initialized) then begin
-        VESA.Framebuffer.Location:= multiboot.multibootinfo^.framebuffer_addr;
-        VESA.Framebuffer.BitsPerPixel:= multiboot.multibootinfo^.framebuffer_bpp;
-        VESA.Framebuffer.Width:= multiboot.multibootinfo^.framebuffer_width;
-        VESA.Framebuffer.Height:= multiboot.multibootinfo^.framebuffer_height;
-        allocateFrameBuffer(VESA.Framebuffer.Location, VESA.Framebuffer.Width, VESA.Framebuffer.Height);
-        VESA.initialized:= true;
-    end;
+    console.Outputln('VIDEO', 'Init VESA Framebuffer');
+    initVESAFrameBuffer(@VESA, multiboot.multibootinfo^.framebuffer_addr, multiboot.multibootinfo^.framebuffer_width, multiboot.multibootinfo^.framebuffer_height, multiboot.multibootinfo^.framebuffer_bpp);        
+    console.Outputln('VIDEO', 'Init VESA Backbuffer');
+    //initBackBuffer(@VESA, multiboot.multibootinfo^.framebuffer_width, multiboot.multibootinfo^.framebuffer_height, multiboot.multibootinfo^.framebuffer_bpp);
+
+    console.Outputln('VIDEO', 'Start Test Draw Loop');
     srand(98354754397);
     while true do begin
         Inc(RGB.R);
@@ -65,19 +106,40 @@ begin
                 Inc(RGB.B);
             end;
         end;
+        console.Outputln('VIDEO', 'Call flush');
+        Flush();
     end;
+    
     tracer.push_trace('video.init.exit');
 end;
 
 procedure DrawPixel(X : uint32; Y : uint32; Pixel : TRGB32);
 var
     Location : PuInt32;
-    Increment : Uint32;
+    LocationIndex : Uint32;
 
 begin
-    Location:= Puint32(VESA.Framebuffer.Location);
-    Increment:= (Y * VESA.Framebuffer.Width) + X;
-    Location[Increment]:= uint32(Pixel);
+    Location:= Puint32(VESA.DefaultBuffer);
+    LocationIndex:= (Y * VESA.Framebuffer.Width) + X;
+    Location[LocationIndex]:= uint32(Pixel);
+end;
+
+procedure Flush();
+var
+    x,y : uint32;
+    Back,Front : PuInt32;
+
+begin
+    writestringln('Flush Start');
+    if not(VESA.BackBuffer.Initialized) then exit;
+    Back:= PUint32(VESA.BackBuffer.Location);
+    Front:= PuInt32(VESA.Framebuffer.Location);
+    for x:=0 to VESA.Framebuffer.Width-1 do begin
+        for y:=0 to VESA.Framebuffer.Height-1 do begin
+            Front[(Y * VESA.Framebuffer.Width)+X]:= Back[(Y * VESA.Framebuffer.Width)+X];
+        end;
+    end;
+    writestringln('Flush End');
 end;
 
 end.
\ No newline at end of file
diff --git a/src/include/color.pas b/src/include/color.pas
index 4b81efe3..ce5b50f6 100644
--- a/src/include/color.pas
+++ b/src/include/color.pas
@@ -10,6 +10,12 @@ type
         A : uint8;
     end;
 
+    TRGB24 = bitpacked record
+        B : uint8;
+        G : uint8;
+        R : uint8;
+    end;
+
     TRGB16 = bitpacked record
         B : UBit5;
         G : UBit6;
@@ -22,6 +28,10 @@ type
         R : UBit2;
     end;
 
+const
+    black : TRGB32 = (B: 000; G: 000; R: 000; A: 000);
+    white : TRGB32 = (B: 255; G: 255; R: 255; A: 000);
+
 implementation
 
 end.
\ No newline at end of file
diff --git a/src/kernel.pas b/src/kernel.pas
index 45e5f67f..beada98b 100644
--- a/src/kernel.pas
+++ b/src/kernel.pas
@@ -200,6 +200,8 @@ begin
      { Call Tracer }
      tracer.init();
 
+     video.init();
+
      { VFS Init }
      vfs.init();
 
@@ -261,8 +263,6 @@ begin
      rand.srand((getDateTime.Seconds SHL 24) OR (getDateTime.Minutes SHL 16) OR (getDateTime.Hours SHL 8) OR (getDateTime.Day));
 
      tracer.push_trace('kmain.TICK');
-     
-     video.init();
 
      while true do begin
         tracer.push_trace('kmain.RedrawWindows');