From 8e6aec5c9db27e42152029b14f3bb4bc0ab90804 Mon Sep 17 00:00:00 2001 From: SzymekkYT <69077038+Szymekk44@users.noreply.github.com> Date: Wed, 25 Sep 2024 19:46:43 +0200 Subject: [PATCH 01/12] =?UTF-8?q?=E2=9C=A8Implemented=20DrawPoint=20(color?= =?UTF-8?q?=20as=20uint)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/Cosmos.System2/Graphics/Canvas.cs | 8 ++++++ .../Cosmos.System2/Graphics/SVGAIICanvas.cs | 5 ++++ source/Cosmos.System2/Graphics/VBECanvas.cs | 28 +++++++++++++++++++ source/Cosmos.System2/Graphics/VGACanvas.cs | 2 +- 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/source/Cosmos.System2/Graphics/Canvas.cs b/source/Cosmos.System2/Graphics/Canvas.cs index a6ac312140..8438939382 100644 --- a/source/Cosmos.System2/Graphics/Canvas.cs +++ b/source/Cosmos.System2/Graphics/Canvas.cs @@ -100,6 +100,14 @@ public virtual void Clear(Color color) /// The Y coordinate. public abstract void DrawPoint(Color color, int x, int y); + /// + /// Sets the pixel at the given coordinates to the specified , without unnecessary color operations. + /// + /// The color to draw with (raw argb). + /// The X coordinate. + /// The Y coordinate. + public abstract void DrawPoint(uint color, int x, int y); + /// /// The name of the Canvas implementation. /// diff --git a/source/Cosmos.System2/Graphics/SVGAIICanvas.cs b/source/Cosmos.System2/Graphics/SVGAIICanvas.cs index 32a01de9fe..2639103b92 100644 --- a/source/Cosmos.System2/Graphics/SVGAIICanvas.cs +++ b/source/Cosmos.System2/Graphics/SVGAIICanvas.cs @@ -80,6 +80,11 @@ public override void DrawPoint(Color color, int x, int y) driver.SetPixel((uint)x, (uint)y, (uint)color.ToArgb()); } + public override void DrawPoint(uint color, int x, int y) + { + driver.SetPixel((uint)x, (uint)y, color); + } + public override void DrawFilledRectangle(Color color, int xStart, int yStart, int width, int height, bool preventOffBoundPixels = true) { var argb = color.ToArgb(); diff --git a/source/Cosmos.System2/Graphics/VBECanvas.cs b/source/Cosmos.System2/Graphics/VBECanvas.cs index bb86dbf1be..2b2c80dde0 100644 --- a/source/Cosmos.System2/Graphics/VBECanvas.cs +++ b/source/Cosmos.System2/Graphics/VBECanvas.cs @@ -234,6 +234,34 @@ public override void DrawPoint(Color aColor, int aX, int aY) } } + public override void DrawPoint(uint aColor, int aX, int aY) + { + uint offset; + + switch (Mode.ColorDepth) + { + case ColorDepth.ColorDepth32: + offset = (uint)GetPointOffset(aX, aY); + + driver.SetVRAM(offset, (byte)((aColor >> 16) & 0xFF)); + driver.SetVRAM(offset + 1, (byte)((aColor >> 8) & 0xFF)); + driver.SetVRAM(offset + 2, (byte)(aColor & 0xFF)); + driver.SetVRAM(offset + 3, (byte)((aColor >> 24) & 0xFF)); + + break; + case ColorDepth.ColorDepth24: + offset = (uint)GetPointOffset(aX, aY); + + driver.SetVRAM(offset, (byte)((aColor >> 16) & 0xFF)); + driver.SetVRAM(offset + 1, (byte)((aColor >> 8) & 0xFF)); + driver.SetVRAM(offset + 2, (byte)(aColor & 0xFF)); + + break; + default: + throw new NotImplementedException("Drawing pixels with color depth " + (int)Mode.ColorDepth + " is not yet supported."); + } + } + public override void DrawArray(Color[] aColors, int aX, int aY, int aWidth, int aHeight) { ThrowIfCoordNotValid(aX, aY); diff --git a/source/Cosmos.System2/Graphics/VGACanvas.cs b/source/Cosmos.System2/Graphics/VGACanvas.cs index 2157e06dee..39e99be650 100644 --- a/source/Cosmos.System2/Graphics/VGACanvas.cs +++ b/source/Cosmos.System2/Graphics/VGACanvas.cs @@ -101,7 +101,7 @@ public override void DrawPoint(Color aColor, int aX, int aY) driver.SetPixel((uint)aX, (uint)aY, aColor); } - public void DrawPoint(uint aColor, int aX, int aY) + public override void DrawPoint(uint aColor, int aX, int aY) { driver.SetPixel((uint)aX, (uint)aY, aColor); } From eea22665fd2f585ad35746a0efff62f44a5f2850 Mon Sep 17 00:00:00 2001 From: SzymekkYT <69077038+Szymekk44@users.noreply.github.com> Date: Wed, 25 Sep 2024 19:56:36 +0200 Subject: [PATCH 02/12] =?UTF-8?q?=E2=9C=A8Implemented=20faster=20and=20sho?= =?UTF-8?q?rter=20DrawRectangle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Cosmos.System2/Graphics/SVGAIICanvas.cs | 27 +++++++++++++++++++ source/Cosmos.System2/Graphics/VBECanvas.cs | 27 +++++++++++++++++++ source/Cosmos.System2/Graphics/VGACanvas.cs | 27 +++++++++++++++++++ 3 files changed, 81 insertions(+) diff --git a/source/Cosmos.System2/Graphics/SVGAIICanvas.cs b/source/Cosmos.System2/Graphics/SVGAIICanvas.cs index 2639103b92..0f1b38f66b 100644 --- a/source/Cosmos.System2/Graphics/SVGAIICanvas.cs +++ b/source/Cosmos.System2/Graphics/SVGAIICanvas.cs @@ -102,6 +102,33 @@ public override void DrawFilledRectangle(Color color, int xStart, int yStart, in } } + public override void DrawRectangle(Color color, int x, int y, int width, int height) + { + int rawColor = color.ToArgb(); + /* Draw the top edge*/ + for (int posX = x; posX < x + width; posX++) + { + DrawPoint((uint)rawColor, posX, y); + } + /* Draw the bottom edge */ + int newY = y + height; + for (int posX = x; posX < x + width; posX++) + { + DrawPoint((uint)rawColor, posX, newY); + } + /* Draw the left edge */ + for (int posY = y; posY < y + height; posY++) + { + DrawPoint((uint)rawColor, x, posY); + } + /* Draw the right edge */ + int newX = x + width; + for (int posY = y; posY < y + height; posY++) + { + DrawPoint((uint)rawColor, newX, posY); + } + } + //public override IReadOnlyList AvailableModes { get; } = new List /// /// Available SVGA 2 supported video modes. diff --git a/source/Cosmos.System2/Graphics/VBECanvas.cs b/source/Cosmos.System2/Graphics/VBECanvas.cs index 2b2c80dde0..0867329a06 100644 --- a/source/Cosmos.System2/Graphics/VBECanvas.cs +++ b/source/Cosmos.System2/Graphics/VBECanvas.cs @@ -289,6 +289,33 @@ public override void DrawFilledRectangle(Color aColor, int aX, int aY, int aWidt } } + public override void DrawRectangle(Color color, int x, int y, int width, int height) + { + int rawColor = color.ToArgb(); + /* Draw the top edge */ + for (int posX = x; posX < x + width; posX++) + { + DrawPoint((uint)rawColor, posX, y); + } + /* Draw the bottom edge */ + int newY = y + height; + for (int posX = x; posX < x + width; posX++) + { + DrawPoint((uint)rawColor, posX, newY); + } + /* Draw the left edge */ + for (int posY = y; posY < y + height; posY++) + { + DrawPoint((uint)rawColor, x, posY); + } + /* Draw the right edge */ + int newX = x + width; + for (int posY = y; posY < y + height; posY++) + { + DrawPoint((uint)rawColor, newX, posY); + } + } + public override void DrawImage(Image aImage, int aX, int aY, bool preventOffBoundPixels = true) { var xBitmap = aImage.RawData; diff --git a/source/Cosmos.System2/Graphics/VGACanvas.cs b/source/Cosmos.System2/Graphics/VGACanvas.cs index 39e99be650..544d2a0432 100644 --- a/source/Cosmos.System2/Graphics/VGACanvas.cs +++ b/source/Cosmos.System2/Graphics/VGACanvas.cs @@ -96,6 +96,33 @@ public override void DrawFilledRectangle(Color aColor, int aXStart, int aYStart, driver.DrawFilledRectangle(aXStart, aYStart, aWidth, aHeight, driver.GetClosestColorInPalette(aColor)); } + public override void DrawRectangle(Color color, int x, int y, int width, int height) + { + int rawColor = color.ToArgb(); + /* Draw the top edge */ + for (int posX = x; posX < x + width; posX++) + { + DrawPoint((uint)rawColor, posX, y); + } + /* Draw the bottom edge */ + int newY = y + height; + for (int posX = x; posX < x + width; posX++) + { + DrawPoint((uint)rawColor, posX, newY); + } + /* Draw the left edge */ + for (int posY = y; posY < y + height; posY++) + { + DrawPoint((uint)rawColor, x, posY); + } + /* Draw the right edge */ + int newX = x + width; + for (int posY = y; posY < y + height; posY++) + { + DrawPoint((uint)rawColor, newX, posY); + } + } + public override void DrawPoint(Color aColor, int aX, int aY) { driver.SetPixel((uint)aX, (uint)aY, aColor); From d0c165218229a866f7f6a09ddd91488e40f14d38 Mon Sep 17 00:00:00 2001 From: SzymekkYT <69077038+Szymekk44@users.noreply.github.com> Date: Wed, 25 Sep 2024 20:07:03 +0200 Subject: [PATCH 03/12] =?UTF-8?q?=E2=9C=A8Implemented=20GetImage=20for=20S?= =?UTF-8?q?VGAII?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This function copies a fragment of your video buffer, and returns it as Bitmap. --- source/Cosmos.Core/MemoryBlock.cs | 16 +++++++++++ source/Cosmos.System2/Graphics/Canvas.cs | 27 ++++++++++++++++++- .../Cosmos.System2/Graphics/SVGAIICanvas.cs | 21 +++++++++++++++ source/Cosmos.System2/Graphics/VBECanvas.cs | 6 +++++ source/Cosmos.System2/Graphics/VGACanvas.cs | 5 ++++ 5 files changed, 74 insertions(+), 1 deletion(-) diff --git a/source/Cosmos.Core/MemoryBlock.cs b/source/Cosmos.Core/MemoryBlock.cs index bed3816176..062d63fe27 100644 --- a/source/Cosmos.Core/MemoryBlock.cs +++ b/source/Cosmos.Core/MemoryBlock.cs @@ -270,6 +270,22 @@ public unsafe void Copy(ManagedMemoryBlock block) MemoryOperations.Copy(xDest, aDataPtr, (int)block.Size); } + /// + /// Copies data from the memory block to the specified array. + /// + /// The byte offset in the memory block from which to start copying. + /// The array into which data will be copied. + /// The starting index in the array where data will be copied. + /// The number of elements to copy. + public unsafe void Get(int aByteOffset, int[] aData, int aIndex, int aCount) + { + int* xSource = (int*)(Base + aByteOffset); + fixed (int* aDataPtr = aData) + { + MemoryOperations.Copy(aDataPtr + aIndex, xSource, aCount); + } + } + /// /// Move bytes array down the memory block. /// diff --git a/source/Cosmos.System2/Graphics/Canvas.cs b/source/Cosmos.System2/Graphics/Canvas.cs index 8438939382..68b875c163 100644 --- a/source/Cosmos.System2/Graphics/Canvas.cs +++ b/source/Cosmos.System2/Graphics/Canvas.cs @@ -125,11 +125,14 @@ public virtual void Clear(Color color) /// The X coordinate. /// The Y coordinate. public abstract Color GetPointColor(int x, int y); + /// - /// Gets the index of the pixel at the given coordinates. + /// Gets the color of the pixel at the given coordinates in ARGB. /// /// The X coordinate. /// The Y coordinate. + public abstract int GetRawPointColor(int x, int y); + internal int GetPointOffset(int x, int y) { return (x * Stride) + (y * Pitch); @@ -606,6 +609,28 @@ public virtual void DrawImage(Image image, int x, int y, bool preventOffBoundPix } } + /// + /// Creates a bitmap by copying a portion of your canvas from the specified coordinates and dimensions. + /// + /// The starting X coordinate of the region to copy. + /// The starting Y coordinate of the region to copy. + /// The width of the region to copy. + /// The height of the region to copy. + /// A new containing the copied region. + public virtual Bitmap GetImage(int x, int y, int width, int height) + { + Bitmap bitmap = new Bitmap((uint)x, (uint)y, ColorDepth.ColorDepth32); + + for (int posy = y, desty = 0; posy < y + y; posy++, desty++) + { + for (int posx = x, destx = 0; posx < x + x; posx++, destx++) + { + bitmap.RawData[desty * x + destx] = GetRawPointColor(posx, posy); + } + } + return bitmap; + } + static int[] ScaleImage(Image image, int newWidth, int newHeight) { int[] pixels = image.RawData; diff --git a/source/Cosmos.System2/Graphics/SVGAIICanvas.cs b/source/Cosmos.System2/Graphics/SVGAIICanvas.cs index 0f1b38f66b..ec0c48c22a 100644 --- a/source/Cosmos.System2/Graphics/SVGAIICanvas.cs +++ b/source/Cosmos.System2/Graphics/SVGAIICanvas.cs @@ -347,6 +347,27 @@ public override Color GetPointColor(int x, int y) return Color.FromArgb((int)driver.GetPixel((uint)x, (uint)y)); } + public override int GetRawPointColor(int x, int y) + { + return (int)driver.GetPixel((uint)x, (uint)y); + } + + public override Bitmap GetImage(int x, int y, int width, int height) + { + var frameSize = (int)driver.FrameSize; + int[] buffer = new int[width]; + int[] all = new int[width * height]; + for (int i = 0; i < height; i++) + { + driver.videoMemory.Get(GetPointOffset(x, y + i) + frameSize, buffer, 0, width); + buffer.CopyTo(all, width * i); + } + Bitmap toReturn = new Bitmap((uint)width, (uint)height, ColorDepth.ColorDepth32); + toReturn.RawData = all; + + return toReturn; + } + public override void Display() { driver.DoubleBufferUpdate(); diff --git a/source/Cosmos.System2/Graphics/VBECanvas.cs b/source/Cosmos.System2/Graphics/VBECanvas.cs index 0867329a06..f8ba109930 100644 --- a/source/Cosmos.System2/Graphics/VBECanvas.cs +++ b/source/Cosmos.System2/Graphics/VBECanvas.cs @@ -357,6 +357,12 @@ public override Color GetPointColor(int aX, int aY) return Color.FromArgb((int)driver.GetVRAM(offset)); } + public override int GetRawPointColor(int aX, int aY) + { + uint offset = (uint)GetPointOffset(aX, aY); + return (int)driver.GetVRAM(offset); + } + #endregion } diff --git a/source/Cosmos.System2/Graphics/VGACanvas.cs b/source/Cosmos.System2/Graphics/VGACanvas.cs index 544d2a0432..f75823d564 100644 --- a/source/Cosmos.System2/Graphics/VGACanvas.cs +++ b/source/Cosmos.System2/Graphics/VGACanvas.cs @@ -140,6 +140,11 @@ public override Color GetPointColor(int aX, int aY) return Color.FromArgb((int)driver.GetPixel((uint)aX, (uint)aY)); } + public override int GetRawPointColor(int aX, int aY) + { + return (int)driver.GetPixel((uint)aX, (uint)aY); + } + public override Mode DefaultGraphicsMode => new Mode(640, 480, ColorDepth.ColorDepth4); /// From 854fcc68c4fcb5f68c9929ed4f89e21f5e820993 Mon Sep 17 00:00:00 2001 From: SzymekkYT <69077038+Szymekk44@users.noreply.github.com> Date: Wed, 25 Sep 2024 20:12:26 +0200 Subject: [PATCH 04/12] =?UTF-8?q?=E2=9C=A8Implemented=20CroppedDrawImage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/Cosmos.System2/Graphics/Canvas.cs | 25 ++++++++++++++++ .../Cosmos.System2/Graphics/SVGAIICanvas.cs | 12 ++++++++ source/Cosmos.System2/Graphics/VBECanvas.cs | 29 +++++++++++++------ 3 files changed, 57 insertions(+), 9 deletions(-) diff --git a/source/Cosmos.System2/Graphics/Canvas.cs b/source/Cosmos.System2/Graphics/Canvas.cs index 68b875c163..ff1070f745 100644 --- a/source/Cosmos.System2/Graphics/Canvas.cs +++ b/source/Cosmos.System2/Graphics/Canvas.cs @@ -693,6 +693,31 @@ public virtual void DrawImage(Image image, int x, int y, int w, int h, bool prev } } + /// + /// Draws the given image at the specified coordinates, cropping the image to fit within the maximum width and height. + /// + /// The image to draw. + /// The X coordinate where the image will be drawn. + /// The Y coordinate where the image will be drawn. + /// The maximum width to display the image. If the image exceeds this width, it will be cropped. + /// The maximum height to display the image. If the image exceeds this height, it will be cropped. + public virtual void CroppedDrawImage(Image image, int x, int y, int maxWidth, int maxHeight) + { + Color color; + int width = Math.Min((int)image.Width, maxWidth); + int height = Math.Min((int)image.Height, maxHeight); + int[] pixels = image.RawData; + + for (int xi = 0; xi < width; xi++) + { + for (int yi = 0; yi < height; yi++) + { + color = Color.FromArgb(pixels[xi + (yi * image.Width)]); + DrawPoint(color, x + xi, y + yi); + } + } + } + /// /// Draws an image with alpha blending. /// diff --git a/source/Cosmos.System2/Graphics/SVGAIICanvas.cs b/source/Cosmos.System2/Graphics/SVGAIICanvas.cs index ec0c48c22a..e4a59a2ddc 100644 --- a/source/Cosmos.System2/Graphics/SVGAIICanvas.cs +++ b/source/Cosmos.System2/Graphics/SVGAIICanvas.cs @@ -428,5 +428,17 @@ public override void DrawImage(Image image, int x, int y, bool preventOffBoundPi } } } + + public override void CroppedDrawImage(Image image, int x, int y, int maxWidth, int maxHeight) + { + var width = maxWidth; + var height = maxHeight; + var frameSize = (int)driver.FrameSize; + var data = image.RawData; + for (int i = 0; i < height; i++) + { + driver.videoMemory.Copy(GetPointOffset(x, y + i) + frameSize, data, i * width, width); + } + } } } \ No newline at end of file diff --git a/source/Cosmos.System2/Graphics/VBECanvas.cs b/source/Cosmos.System2/Graphics/VBECanvas.cs index f8ba109930..3e5fa688f9 100644 --- a/source/Cosmos.System2/Graphics/VBECanvas.cs +++ b/source/Cosmos.System2/Graphics/VBECanvas.cs @@ -321,25 +321,36 @@ public override void DrawImage(Image aImage, int aX, int aY, bool preventOffBoun var xBitmap = aImage.RawData; var xWidth = (int)aImage.Width; var xHeight = (int)aImage.Height; - if (preventOffBoundPixels) + int xOffset = aY * (int)Mode.Width + aX; + + if (!preventOffBoundPixels) { - var maxWidth = Math.Min(xWidth, (int)mode.Width - aX); - var maxHeight = Math.Min(xHeight, (int)mode.Height - aY); - int xOffset = aY * (int)Mode.Width + aX; - for (int i = 0; i < maxHeight; i++) + for (int i = 0; i < xHeight; i++) { - driver.CopyVRAM((i * (int)Mode.Width) + xOffset, xBitmap, i * xWidth, maxWidth); + driver.CopyVRAM((i * (int)Mode.Width) + xOffset, xBitmap, i * xWidth, xWidth); } } else { - int xOffset = aY * xHeight + aX; - for (int i = 0; i < Mode.Height; i++) + var maxWidth = Math.Min(xWidth, (int)mode.Width - aX); + var maxHeight = Math.Min(xHeight, (int)mode.Height - aY); + for (int i = 0; i < maxHeight; i++) { - driver.CopyVRAM((i * (int)Mode.Width) + xOffset, xBitmap, i * xWidth, xWidth); + driver.CopyVRAM((i * (int)Mode.Width) + xOffset, xBitmap, i * xWidth, maxWidth); } } + } + public override void CroppedDrawImage(Image aImage, int aX, int aY, int aWidth, int aHeight) + { + var xBitmap = aImage.RawData; + var xWidth = aWidth; + var xHeight = aHeight; + int xOffset = aY * xHeight + aX; + for (int i = 0; i < Mode.Height; i++) + { + driver.CopyVRAM((i * (int)Mode.Width) + xOffset, xBitmap, i * xWidth, xWidth); + } } #endregion From 3e9476aac9130887ee3c8f1191f9cd2cb3c6021c Mon Sep 17 00:00:00 2001 From: SzymekkYT <69077038+Szymekk44@users.noreply.github.com> Date: Wed, 25 Sep 2024 20:20:04 +0200 Subject: [PATCH 05/12] =?UTF-8?q?=F0=9F=8E=A8Improved=20comments=20and=20x?= =?UTF-8?q?ml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/Cosmos.Core/MemoryBlock.cs | 16 +++++ source/Cosmos.System2/Graphics/Canvas.cs | 48 +++++---------- .../Cosmos.System2/Graphics/SVGAIICanvas.cs | 52 ++++++++++------ source/Cosmos.System2/Graphics/VBECanvas.cs | 59 ++++++++++++------- 4 files changed, 101 insertions(+), 74 deletions(-) diff --git a/source/Cosmos.Core/MemoryBlock.cs b/source/Cosmos.Core/MemoryBlock.cs index 062d63fe27..2838bd404f 100644 --- a/source/Cosmos.Core/MemoryBlock.cs +++ b/source/Cosmos.Core/MemoryBlock.cs @@ -286,6 +286,22 @@ public unsafe void Get(int aByteOffset, int[] aData, int aIndex, int aCount) } } + /// + /// Copies a specified number of bytes from the memory block into an array. + /// + /// The byte offset in the memory block from where the copy starts. + /// The array where the data will be copied to. + /// The starting index in the destination array. + /// The number of bytes to copy. + public unsafe void Get(int aByteOffset, byte[] aData, int aIndex, int aCount) + { + byte* xSource = (byte*)(Base + aByteOffset); + fixed (byte* aDataPtr = aData) + { + MemoryOperations.Copy(aDataPtr + aIndex, xSource, aCount); + } + } + /// /// Move bytes array down the memory block. /// diff --git a/source/Cosmos.System2/Graphics/Canvas.cs b/source/Cosmos.System2/Graphics/Canvas.cs index ff1070f745..d0f628168f 100644 --- a/source/Cosmos.System2/Graphics/Canvas.cs +++ b/source/Cosmos.System2/Graphics/Canvas.cs @@ -496,40 +496,17 @@ public virtual void DrawSquare(Color color, int x, int y, int size) /// The height of the rectangle. public virtual void DrawRectangle(Color color, int x, int y, int width, int height) { - /* - * we must draw four lines connecting any vertex of our rectangle to do this we first obtain the position of these - * vertex (we call these vertexes A, B, C, D as for geometric convention) - */ + // Draw top edge from (x, y) to (x + width, y) + DrawLine(color, x, y, x + width, y); - /* The check of the validity of x and y are done in DrawLine() */ + // Draw left edge from (x, y) to (x, y + height) + DrawLine(color, x, y, x, y + height); - /* The vertex A is where x,y are */ - int xa = x; - int ya = y; + // Draw bottom edge from (x, y + height) to (x + width, y + height) + DrawLine(color, x, y + height, x + width, y + height); - /* The vertex B has the same y coordinate of A but x is moved of width pixels */ - int xb = x + width; - int yb = y; - - /* The vertex C has the same x coordiate of A but this time is y that is moved of height pixels */ - int xc = x; - int yc = y + height; - - /* The Vertex D has x moved of width pixels and y moved of height pixels */ - int xd = x + width; - int yd = y + height; - - /* Draw a line betwen A and B */ - DrawLine(color, xa, ya, xb, yb); - - /* Draw a line between A and C */ - DrawLine(color, xa, ya, xc, yc); - - /* Draw a line between B and D */ - DrawLine(color, xb, yb, xd, yd); - - /* Draw a line between C and D */ - DrawLine(color, xc, yc, xd, yd); + // Draw right edge from (x + width, y) to (x + width, y + height) + DrawLine(color, x + width, y, x + width, y + height); } /// @@ -631,6 +608,13 @@ public virtual Bitmap GetImage(int x, int y, int width, int height) return bitmap; } + /// + /// Scales an image to the specified new width and height. + /// + /// The image to be scaled. + /// The width of the scaled image. + /// The height of the scaled image. + /// An array of integers representing the scaled image's pixel data. (Raw bitmap data) static int[] ScaleImage(Image image, int newWidth, int newHeight) { int[] pixels = image.RawData; @@ -640,7 +624,6 @@ static int[] ScaleImage(Image image, int newWidth, int newHeight) int xRatio = (int)((w1 << 16) / newWidth) + 1; int yRatio = (int)((h1 << 16) / newHeight) + 1; int x2, y2; - for (int i = 0; i < newHeight; i++) { for (int j = 0; j < newWidth; j++) @@ -650,7 +633,6 @@ static int[] ScaleImage(Image image, int newWidth, int newHeight) temp[(i * newWidth) + j] = pixels[(y2 * w1) + x2]; } } - return temp; } diff --git a/source/Cosmos.System2/Graphics/SVGAIICanvas.cs b/source/Cosmos.System2/Graphics/SVGAIICanvas.cs index e4a59a2ddc..4eca150edb 100644 --- a/source/Cosmos.System2/Graphics/SVGAIICanvas.cs +++ b/source/Cosmos.System2/Graphics/SVGAIICanvas.cs @@ -104,28 +104,42 @@ public override void DrawFilledRectangle(Color color, int xStart, int yStart, in public override void DrawRectangle(Color color, int x, int y, int width, int height) { - int rawColor = color.ToArgb(); - /* Draw the top edge*/ - for (int posX = x; posX < x + width; posX++) - { - DrawPoint((uint)rawColor, posX, y); - } - /* Draw the bottom edge */ - int newY = y + height; - for (int posX = x; posX < x + width; posX++) - { - DrawPoint((uint)rawColor, posX, newY); - } - /* Draw the left edge */ - for (int posY = y; posY < y + height; posY++) + if (color.A < 255) { - DrawPoint((uint)rawColor, x, posY); + // Draw top edge from (x, y) to (x + width, y) + DrawLine(color, x, y, x + width, y); + // Draw left edge from (x, y) to (x, y + height) + DrawLine(color, x, y, x, y + height); + // Draw bottom edge from (x, y + height) to (x + width, y + height) + DrawLine(color, x, y + height, x + width, y + height); + // Draw right edge from (x + width, y) to (x + width, y + height) + DrawLine(color, x + width, y, x + width, y + height); } - /* Draw the right edge */ - int newX = x + width; - for (int posY = y; posY < y + height; posY++) + else { - DrawPoint((uint)rawColor, newX, posY); + int rawColor = color.ToArgb(); + // Draw top edge from (x, y) to (x + width, y) + for (int posX = x; posX < x + width; posX++) + { + DrawPoint((uint)rawColor, posX, y); + } + // Draw left edge from (x, y) to (x, y + height) + int newY = y + height; + for (int posX = x; posX < x + width; posX++) + { + DrawPoint((uint)rawColor, posX, newY); + } + // Draw bottom edge from (x, y + height) to (x + width, y + height) + for (int posY = y; posY < y + height; posY++) + { + DrawPoint((uint)rawColor, x, posY); + } + // Draw right edge from (x + width, y) to (x + width, y + height) + int newX = x + width; + for (int posY = y; posY < y + height; posY++) + { + DrawPoint((uint)rawColor, newX, posY); + } } } diff --git a/source/Cosmos.System2/Graphics/VBECanvas.cs b/source/Cosmos.System2/Graphics/VBECanvas.cs index 3e5fa688f9..5ebdd26bf3 100644 --- a/source/Cosmos.System2/Graphics/VBECanvas.cs +++ b/source/Cosmos.System2/Graphics/VBECanvas.cs @@ -279,10 +279,11 @@ public override void DrawArray(Color[] aColors, int aX, int aY, int aWidth, int public override void DrawFilledRectangle(Color aColor, int aX, int aY, int aWidth, int aHeight, bool preventOffBoundPixels = true) { // ClearVRAM clears one uint at a time. So we clear pixelwise not byte wise. That's why we divide by 32 and not 8. - if(preventOffBoundPixels) - aWidth = (int)(Math.Min(aWidth, Mode.Width - aX) * (int)Mode.ColorDepth / 32); + if (preventOffBoundPixels) + { + aWidth = (int)(Math.Min(aWidth, Mode.Width - aX) * (int)Mode.ColorDepth / 32); + } var color = aColor.ToArgb(); - for (int i = aY; i < aY + aHeight; i++) { driver.ClearVRAM(GetPointOffset(aX, i), aWidth, color); @@ -291,28 +292,42 @@ public override void DrawFilledRectangle(Color aColor, int aX, int aY, int aWidt public override void DrawRectangle(Color color, int x, int y, int width, int height) { - int rawColor = color.ToArgb(); - /* Draw the top edge */ - for (int posX = x; posX < x + width; posX++) - { - DrawPoint((uint)rawColor, posX, y); - } - /* Draw the bottom edge */ - int newY = y + height; - for (int posX = x; posX < x + width; posX++) - { - DrawPoint((uint)rawColor, posX, newY); - } - /* Draw the left edge */ - for (int posY = y; posY < y + height; posY++) + if (color.A < 255) { - DrawPoint((uint)rawColor, x, posY); + // Draw top edge from (x, y) to (x + width, y) + DrawLine(color, x, y, x + width, y); + // Draw left edge from (x, y) to (x, y + height) + DrawLine(color, x, y, x, y + height); + // Draw bottom edge from (x, y + height) to (x + width, y + height) + DrawLine(color, x, y + height, x + width, y + height); + // Draw right edge from (x + width, y) to (x + width, y + height) + DrawLine(color, x + width, y, x + width, y + height); } - /* Draw the right edge */ - int newX = x + width; - for (int posY = y; posY < y + height; posY++) + else { - DrawPoint((uint)rawColor, newX, posY); + int rawColor = color.ToArgb(); + // Draw top edge from (x, y) to (x + width, y) + for (int posX = x; posX < x + width; posX++) + { + DrawPoint((uint)rawColor, posX, y); + } + // Draw left edge from (x, y) to (x, y + height) + int newY = y + height; + for (int posX = x; posX < x + width; posX++) + { + DrawPoint((uint)rawColor, posX, newY); + } + // Draw bottom edge from (x, y + height) to (x + width, y + height) + for (int posY = y; posY < y + height; posY++) + { + DrawPoint((uint)rawColor, x, posY); + } + // Draw right edge from (x + width, y) to (x + width, y + height) + int newX = x + width; + for (int posY = y; posY < y + height; posY++) + { + DrawPoint((uint)rawColor, newX, posY); + } } } From a5a5e630379b3672639e07693ce1139fc0a1a05c Mon Sep 17 00:00:00 2001 From: SzymekkYT <69077038+Szymekk44@users.noreply.github.com> Date: Wed, 25 Sep 2024 20:32:39 +0200 Subject: [PATCH 06/12] =?UTF-8?q?=E2=9C=A8Implemented=20VBE=20GetImage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/Cosmos.Core/ManagedMemoryBlock.cs | 20 +++++++++++++++ source/Cosmos.HAL2/Drivers/Video/VBEDriver.cs | 12 +++++++++ source/Cosmos.System2/Graphics/Canvas.cs | 4 +++ source/Cosmos.System2/Graphics/VBECanvas.cs | 25 +++++++++++++++++++ 4 files changed, 61 insertions(+) diff --git a/source/Cosmos.Core/ManagedMemoryBlock.cs b/source/Cosmos.Core/ManagedMemoryBlock.cs index 4a6be7d7cf..6daa1aaf42 100644 --- a/source/Cosmos.Core/ManagedMemoryBlock.cs +++ b/source/Cosmos.Core/ManagedMemoryBlock.cs @@ -166,6 +166,26 @@ public unsafe void Copy(MemoryBlock block) MemoryOperations.Copy(xDest, aDataPtr, (int)block.Size); } + /// + /// Copies data from the memory block to the specified array. + /// + /// The start index in the memory block from which to begin copying. + /// The array into which data will be copied. + /// The starting index in the array where data will be copied. + /// The number of elements to copy. + public unsafe void Get(int aStart, int[] aData, int aIndex, int aCount) + { + int* xSrc; + fixed (byte* aArrayPtr = memory) + { + xSrc = (int*)aArrayPtr + aStart; + } + fixed (int* aDataPtr = aData) + { + MemoryOperations.Copy(aDataPtr + aIndex, xSrc, aCount); + } + } + /// /// Write 8-bit to the memory block. /// diff --git a/source/Cosmos.HAL2/Drivers/Video/VBEDriver.cs b/source/Cosmos.HAL2/Drivers/Video/VBEDriver.cs index 5182cd263a..015ab5c06b 100644 --- a/source/Cosmos.HAL2/Drivers/Video/VBEDriver.cs +++ b/source/Cosmos.HAL2/Drivers/Video/VBEDriver.cs @@ -265,6 +265,18 @@ public uint GetVRAM(uint index) return (uint)pixel; } + /// + /// Get VRAM data. + /// + /// Start position in VRAM. + /// Array to copy data into. + /// Starting index in the array to begin copying data. + /// Number of elements to copy. + public void GetVRAM(int aStart, int[] aData, int aIndex, int aCount) + { + lastbuffer.Get(aStart, aData, aIndex, aCount); + } + /// /// Clear VRAM. /// diff --git a/source/Cosmos.System2/Graphics/Canvas.cs b/source/Cosmos.System2/Graphics/Canvas.cs index d0f628168f..67b35c2935 100644 --- a/source/Cosmos.System2/Graphics/Canvas.cs +++ b/source/Cosmos.System2/Graphics/Canvas.cs @@ -328,6 +328,7 @@ public virtual void DrawCircle(Color color, int xCenter, int yCenter, int radius /// The X center coordinate. /// The Y center coordinate. /// The radius of the circle to draw. + /// Prevents drawing outside the bounds of the canvas. public virtual void DrawFilledCircle(Color color, int x0, int y0, int radius) { int x = radius; @@ -557,6 +558,7 @@ public virtual void DrawTriangle(Color color, int v1x, int v1y, int v2x, int v2y /// The image to draw. /// The origin X coordinate. /// The origin Y coordinate. + /// Prevents drawing outside the bounds of the canvas. public virtual void DrawImage(Image image, int x, int y, bool preventOffBoundPixels = true) { Color color; @@ -644,6 +646,7 @@ static int[] ScaleImage(Image image, int newWidth, int newHeight) /// The Y coordinate. /// The desired width to scale the image to before drawing. /// The desired height to scale the image to before drawing + /// Prevents drawing outside the bounds of the canvas. public virtual void DrawImage(Image image, int x, int y, int w, int h, bool preventOffBoundPixels = true) { Color color; @@ -706,6 +709,7 @@ public virtual void CroppedDrawImage(Image image, int x, int y, int maxWidth, in /// The image to draw. /// The X coordinate. /// The Y coordinate. + /// Prevents drawing outside the bounds of the canvas. public void DrawImageAlpha(Image image, int x, int y, bool preventOffBoundPixels = true) { Color color; diff --git a/source/Cosmos.System2/Graphics/VBECanvas.cs b/source/Cosmos.System2/Graphics/VBECanvas.cs index 5ebdd26bf3..6e80eade87 100644 --- a/source/Cosmos.System2/Graphics/VBECanvas.cs +++ b/source/Cosmos.System2/Graphics/VBECanvas.cs @@ -389,6 +389,31 @@ public override int GetRawPointColor(int aX, int aY) return (int)driver.GetVRAM(offset); } + public override Bitmap GetImage(int x, int y, int width, int height) + { + Bitmap bitmap = new((uint)width, (uint)height, ColorDepth.ColorDepth32); + + int startX = Math.Max(0, x); + int startY = Math.Max(0, y); + int endX = Math.Min(x + width, (int)Mode.Width); + int endY = Math.Min(y + height, (int)Mode.Height); + + int offsetX = Math.Max(0, -x); + int offsetY = Math.Max(0, -y); + + int[] rawData = new int[width * height]; + + for (int posy = startY; posy < endY; posy++) + { + int srcOffset = posy * (int)Mode.Width + startX; + int destOffset = (posy - startY) * width; + driver.GetVRAM(srcOffset, rawData, destOffset, endX - startX); + } + + bitmap.RawData = rawData; + return bitmap; + } + #endregion } From 25615857603f42416882da49232556271420d74c Mon Sep 17 00:00:00 2001 From: SzymekkYT <69077038+Szymekk44@users.noreply.github.com> Date: Wed, 25 Sep 2024 20:49:18 +0200 Subject: [PATCH 07/12] =?UTF-8?q?=E2=9C=A8Implemented=20new=20DrawArray=20?= =?UTF-8?q?functions!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/Cosmos.System2/Graphics/Canvas.cs | 52 ++++++++++- .../Cosmos.System2/Graphics/SVGAIICanvas.cs | 90 ++++++++++++++++-- source/Cosmos.System2/Graphics/VBECanvas.cs | 92 +++++++++++++++---- source/Cosmos.System2/Graphics/VGACanvas.cs | 5 + 4 files changed, 213 insertions(+), 26 deletions(-) diff --git a/source/Cosmos.System2/Graphics/Canvas.cs b/source/Cosmos.System2/Graphics/Canvas.cs index 67b35c2935..b464eda8da 100644 --- a/source/Cosmos.System2/Graphics/Canvas.cs +++ b/source/Cosmos.System2/Graphics/Canvas.cs @@ -108,6 +108,14 @@ public virtual void Clear(Color color) /// The Y coordinate. public abstract void DrawPoint(uint color, int x, int y); + /// + /// Sets the pixel at the given coordinates to the specified . without ToArgb() + /// + /// The color to draw with (raw argb). + /// The X coordinate. + /// The Y coordinate. + public abstract void DrawPoint(int color, int x, int y); + /// /// The name of the Canvas implementation. /// @@ -158,6 +166,47 @@ public virtual void DrawArray(Color[] colors, int x, int y, int width, int heigh } } + /// + /// Draws an array of pixels to the canvas, starting at the given coordinates, + /// using the given width. + /// + /// The pixels to draw. + /// The X coordinate. + /// The Y coordinate. + /// The width of the drawn bitmap. + /// The height of the drawn bitmap. + public virtual void DrawArray(int[] colors, int x, int y, int width, int height) + { + for (int X = 0; X < width; X++) + { + for (int Y = 0; Y < height; Y++) + { + DrawPoint(colors[Y * width + X], x + X, y + Y); + } + } + } + + /// + /// Draws an array of pixels to the canvas, starting at the given coordinates, + /// using the given width. + /// + /// The pixels to draw. + /// The X coordinate. + /// The Y coordinate. + /// The width of the drawn bitmap. + /// The height of the drawn bitmap. + /// int[] colors tarting position + public virtual void DrawArray(int[] colors, int x, int y, int width, int height, int startIndex) + { + for (int X = 0; X < width; X++) + { + for (int Y = 0; Y < height; Y++) + { + DrawPoint(colors[Y * width + X + startIndex], x + X, y + Y); + } + } + } + /// /// Draws a horizontal line. /// @@ -686,7 +735,8 @@ public virtual void DrawImage(Image image, int x, int y, int w, int h, bool prev /// The Y coordinate where the image will be drawn. /// The maximum width to display the image. If the image exceeds this width, it will be cropped. /// The maximum height to display the image. If the image exceeds this height, it will be cropped. - public virtual void CroppedDrawImage(Image image, int x, int y, int maxWidth, int maxHeight) + /// Prevents drawing outside the bounds of the canvas. + public virtual void CroppedDrawImage(Image image, int x, int y, int maxWidth, int maxHeight, bool preventOffBoundPixels = true) { Color color; int width = Math.Min((int)image.Width, maxWidth); diff --git a/source/Cosmos.System2/Graphics/SVGAIICanvas.cs b/source/Cosmos.System2/Graphics/SVGAIICanvas.cs index 4eca150edb..39934cf910 100644 --- a/source/Cosmos.System2/Graphics/SVGAIICanvas.cs +++ b/source/Cosmos.System2/Graphics/SVGAIICanvas.cs @@ -85,17 +85,54 @@ public override void DrawPoint(uint color, int x, int y) driver.SetPixel((uint)x, (uint)y, color); } + public override void DrawPoint(int color, int x, int y) + { + driver.SetPixel((uint)x, (uint)y, (uint)color); + } + + public override void DrawArray(Color[] colors, int x, int y, int width, int height) + { + ThrowIfCoordNotValid(x, y); + ThrowIfCoordNotValid(x + width, y + height); + + for (int i = 0; i < x; i++) + { + for (int ii = 0; ii < y; ii++) + { + DrawPoint(colors[i + (ii * width)], i, ii); + } + } + } + + public override void DrawArray(int[] colors, int x, int y, int width, int height) + { + var frameSize = (int)driver.FrameSize; + + for (int i = 0; i < height; i++) + { + driver.videoMemory.Copy(GetPointOffset(x, y + i) + frameSize, colors, i * width, width); + } + } + + public override void DrawArray(int[] colors, int x, int y, int width, int height, int startIndex) + { + var frameSize = (int)driver.FrameSize; + + for (int i = 0; i < height; i++) + { + driver.videoMemory.Copy(GetPointOffset(x, y + i) + frameSize, colors, i * width + startIndex, width); + } + } + public override void DrawFilledRectangle(Color color, int xStart, int yStart, int width, int height, bool preventOffBoundPixels = true) { var argb = color.ToArgb(); var frameSize = (int)driver.FrameSize; - if(preventOffBoundPixels) + if (preventOffBoundPixels) { width = Math.Min(width, (int)mode.Width - xStart); height = Math.Min(height, (int)mode.Height - yStart); } - - for (int i = yStart; i < yStart + height; i++) { driver.videoMemory.Fill(GetPointOffset(xStart, i) + (int)frameSize, width, argb); @@ -424,14 +461,25 @@ public override void DrawImage(Image image, int x, int y, bool preventOffBoundPi var height = (int)image.Height; var frameSize = (int)driver.FrameSize; var data = image.RawData; + if (preventOffBoundPixels) { var maxWidth = Math.Min(width, (int)mode.Width - x); var maxHeight = Math.Min(height, (int)mode.Height - y); + var startX = Math.Max(0, x); + var startY = Math.Max(0, y); + + var sourceX = Math.Max(0, -x); + var sourceY = Math.Max(0, -y); + + // Adjust maxWidth and maxHeight if startX or startY were changed + maxWidth -= startX - x; + maxHeight -= startY - y; for (int i = 0; i < maxHeight; i++) { - driver.videoMemory.Copy(GetPointOffset(x, y + i) + frameSize, data, i * width, maxWidth); + int sourceIndex = (sourceY + i) * width + sourceX; + driver.videoMemory.Copy(GetPointOffset(startX, startY + i) + frameSize, data, sourceIndex, maxWidth); } } else @@ -443,15 +491,39 @@ public override void DrawImage(Image image, int x, int y, bool preventOffBoundPi } } - public override void CroppedDrawImage(Image image, int x, int y, int maxWidth, int maxHeight) + public override void CroppedDrawImage(Image image, int x, int y, int width, int height, bool preventOffBoundPixels = true) { - var width = maxWidth; - var height = maxHeight; var frameSize = (int)driver.FrameSize; var data = image.RawData; - for (int i = 0; i < height; i++) + + if (preventOffBoundPixels) { - driver.videoMemory.Copy(GetPointOffset(x, y + i) + frameSize, data, i * width, width); + var modeWidth = (int)mode.Width; + var modeHeight = (int)mode.Height; + + var maxWidth = Math.Min(width, modeWidth - x); + var maxHeight = Math.Min(height, modeHeight - y); + + var startX = Math.Max(0, -x); + var startY = Math.Max(0, -y); + + var sourceWidth = maxWidth - startX; + var sourceHeight = maxHeight - startY; + + for (int i = 0; i < sourceHeight; i++) + { + int destY = y + startY + i; + int destOffset = GetPointOffset(x + startX, destY) + frameSize; + + driver.videoMemory.Copy(destOffset, data, (startY + i) * width + startX, sourceWidth); + } + } + else + { + for (int i = 0; i < height; i++) + { + driver.videoMemory.Copy(GetPointOffset(x, y + i) + frameSize, data, i * width, width); + } } } } diff --git a/source/Cosmos.System2/Graphics/VBECanvas.cs b/source/Cosmos.System2/Graphics/VBECanvas.cs index 6e80eade87..8db0e7a24b 100644 --- a/source/Cosmos.System2/Graphics/VBECanvas.cs +++ b/source/Cosmos.System2/Graphics/VBECanvas.cs @@ -262,6 +262,11 @@ public override void DrawPoint(uint aColor, int aX, int aY) } } + public override void DrawPoint(int aColor, int aX, int aY) + { + DrawPoint((uint)aColor, aX, aY); + } + public override void DrawArray(Color[] aColors, int aX, int aY, int aWidth, int aHeight) { ThrowIfCoordNotValid(aX, aY); @@ -276,6 +281,24 @@ public override void DrawArray(Color[] aColors, int aX, int aY, int aWidth, int } } + public override void DrawArray(int[] aColors, int aX, int aY, int aWidth, int aHeight) + { + for (int i = 0; i < aHeight; i++) + { + int destinationIndex = (aY + i) * (int)mode.Width + aX; + driver.CopyVRAM(destinationIndex, aColors, i * aWidth, aWidth); + } + } + + public override void DrawArray(int[] aColors, int aX, int aY, int aWidth, int aHeight, int startIndex) + { + for (int i = 0; i < aHeight; i++) + { + int destinationIndex = (aY + i) * (int)mode.Width + aX; + driver.CopyVRAM(destinationIndex, aColors, i * aWidth + startIndex, aWidth); + } + } + public override void DrawFilledRectangle(Color aColor, int aX, int aY, int aWidth, int aHeight, bool preventOffBoundPixels = true) { // ClearVRAM clears one uint at a time. So we clear pixelwise not byte wise. That's why we divide by 32 and not 8. @@ -331,40 +354,77 @@ public override void DrawRectangle(Color color, int x, int y, int width, int hei } } - public override void DrawImage(Image aImage, int aX, int aY, bool preventOffBoundPixels = true) + public override void DrawImage(Image image, int x, int y, bool preventOffBoundPixels = true) { - var xBitmap = aImage.RawData; - var xWidth = (int)aImage.Width; - var xHeight = (int)aImage.Height; - int xOffset = aY * (int)Mode.Width + aX; + var width = (int)image.Width; + var height = (int)image.Height; + var data = image.RawData; - if (!preventOffBoundPixels) + if (preventOffBoundPixels) { - for (int i = 0; i < xHeight; i++) + var maxWidth = Math.Min(width, (int)mode.Width - x); + var maxHeight = Math.Min(height, (int)mode.Height - y); + var startX = Math.Max(0, x); + var startY = Math.Max(0, y); + + var sourceX = Math.Max(0, -x); + var sourceY = Math.Max(0, -y); + + // Adjust maxWidth and maxHeight if startX or startY were changed + maxWidth -= startX - x; + maxHeight -= startY - y; + + for (int i = 0; i < maxHeight; i++) { - driver.CopyVRAM((i * (int)Mode.Width) + xOffset, xBitmap, i * xWidth, xWidth); + int sourceIndex = (sourceY + i) * width + sourceX; + int destinationIndex = (startY + i) * (int)mode.Width + startX; + driver.CopyVRAM(destinationIndex, data, sourceIndex, maxWidth); } } else { - var maxWidth = Math.Min(xWidth, (int)mode.Width - aX); - var maxHeight = Math.Min(xHeight, (int)mode.Height - aY); - for (int i = 0; i < maxHeight; i++) + for (int i = 0; i < height; i++) { - driver.CopyVRAM((i * (int)Mode.Width) + xOffset, xBitmap, i * xWidth, maxWidth); + int destinationIndex = (y + i) * (int)mode.Width + x; + driver.CopyVRAM(destinationIndex, data, i * width, width); } } } - public override void CroppedDrawImage(Image aImage, int aX, int aY, int aWidth, int aHeight) + public override void CroppedDrawImage(Image aImage, int aX, int aY, int aWidth, int aHeight, bool preventOffBoundPixels = true) { var xBitmap = aImage.RawData; var xWidth = aWidth; var xHeight = aHeight; - int xOffset = aY * xHeight + aX; - for (int i = 0; i < Mode.Height; i++) + + if (preventOffBoundPixels) + { + var maxWidth = Math.Min(xWidth, (int)Mode.Width - aX); + var maxHeight = Math.Min(xHeight, (int)Mode.Height - aY); + + var startX = Math.Max(0, aX); + var startY = Math.Max(0, aY); + + var sourceX = Math.Max(0, -aX); + var sourceY = Math.Max(0, -aY); + + maxWidth -= startX - aX; + maxHeight -= startY - aY; + + for (int i = 0; i < maxHeight; i++) + { + int sourceIndex = (sourceY + i) * xWidth + sourceX; + int destinationIndex = (startY + i) * (int)Mode.Width + startX; + driver.CopyVRAM(destinationIndex, xBitmap, sourceIndex, maxWidth); + } + } + else { - driver.CopyVRAM((i * (int)Mode.Width) + xOffset, xBitmap, i * xWidth, xWidth); + for (int i = 0; i < xHeight; i++) + { + int destinationIndex = (aY + i) * (int)Mode.Width + aX; + driver.CopyVRAM(destinationIndex, xBitmap, i * xWidth, xWidth); + } } } diff --git a/source/Cosmos.System2/Graphics/VGACanvas.cs b/source/Cosmos.System2/Graphics/VGACanvas.cs index f75823d564..0d39b52f90 100644 --- a/source/Cosmos.System2/Graphics/VGACanvas.cs +++ b/source/Cosmos.System2/Graphics/VGACanvas.cs @@ -133,6 +133,11 @@ public override void DrawPoint(uint aColor, int aX, int aY) driver.SetPixel((uint)aX, (uint)aY, aColor); } + public override void DrawPoint(int aColor, int aX, int aY) + { + driver.SetPixel((uint)aX, (uint)aY, (uint)aColor); + } + public override List AvailableModes => availableModes; public override Color GetPointColor(int aX, int aY) From 567d6b00e8fe1db3db7383a230c1f9c1f65ed8b5 Mon Sep 17 00:00:00 2001 From: SzymekkYT <69077038+Szymekk44@users.noreply.github.com> Date: Wed, 25 Sep 2024 20:51:53 +0200 Subject: [PATCH 08/12] =?UTF-8?q?=F0=9F=94=93Graphics=20drivers=20are=20no?= =?UTF-8?q?w=20public!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/Cosmos.System2/Graphics/FullScreenCanvas.cs | 2 +- source/Cosmos.System2/Graphics/SVGAIICanvas.cs | 4 ++-- source/Cosmos.System2/Graphics/VBECanvas.cs | 4 ++-- source/Cosmos.System2/Graphics/VGACanvas.cs | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/source/Cosmos.System2/Graphics/FullScreenCanvas.cs b/source/Cosmos.System2/Graphics/FullScreenCanvas.cs index 1733e970d2..89d4c22dec 100644 --- a/source/Cosmos.System2/Graphics/FullScreenCanvas.cs +++ b/source/Cosmos.System2/Graphics/FullScreenCanvas.cs @@ -35,7 +35,7 @@ private enum VideoDriver VGADriver } - static Canvas videoDriver = null; + public static Canvas videoDriver = null; static readonly PCIDevice svgaIIDevice = PCI.GetDevice(VendorID.VMWare, DeviceID.SVGAIIAdapter); /// diff --git a/source/Cosmos.System2/Graphics/SVGAIICanvas.cs b/source/Cosmos.System2/Graphics/SVGAIICanvas.cs index 39934cf910..0dd7bc8ead 100644 --- a/source/Cosmos.System2/Graphics/SVGAIICanvas.cs +++ b/source/Cosmos.System2/Graphics/SVGAIICanvas.cs @@ -17,8 +17,8 @@ public class SVGAIICanvas : Canvas internal Debugger debugger = new("SVGAIIScreen"); static readonly Mode defaultMode = new(1024, 768, ColorDepth.ColorDepth32); - private Mode mode; - private readonly VMWareSVGAII driver; + public Mode mode; + public readonly VMWareSVGAII driver; /// /// Initializes a new instance of the class. diff --git a/source/Cosmos.System2/Graphics/VBECanvas.cs b/source/Cosmos.System2/Graphics/VBECanvas.cs index 8db0e7a24b..a5cd53dc70 100644 --- a/source/Cosmos.System2/Graphics/VBECanvas.cs +++ b/source/Cosmos.System2/Graphics/VBECanvas.cs @@ -14,8 +14,8 @@ namespace Cosmos.System.Graphics public class VBECanvas : Canvas { static readonly Mode defaultMode = new(1024, 768, ColorDepth.ColorDepth32); - readonly VBEDriver driver; - Mode mode; + public readonly VBEDriver driver; + public Mode mode; /// /// Initializes a new instance of the class. diff --git a/source/Cosmos.System2/Graphics/VGACanvas.cs b/source/Cosmos.System2/Graphics/VGACanvas.cs index 0d39b52f90..b5498bb723 100644 --- a/source/Cosmos.System2/Graphics/VGACanvas.cs +++ b/source/Cosmos.System2/Graphics/VGACanvas.cs @@ -12,7 +12,7 @@ namespace Cosmos.System.Graphics public class VGACanvas : Canvas { bool enabled; - readonly VGADriver driver; + public readonly VGADriver driver; /// /// Available VGA supported video modes. From 8177e34312c44f7d8e40034e273b91882b959738 Mon Sep 17 00:00:00 2001 From: SzymekkYT <69077038+Szymekk44@users.noreply.github.com> Date: Wed, 25 Sep 2024 20:58:44 +0200 Subject: [PATCH 09/12] =?UTF-8?q?=F0=9F=9A=A8Added=20GetImage=20test=20in?= =?UTF-8?q?=20GraphicTest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tests/Kernels/GraphicTest/Kernel.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Tests/Kernels/GraphicTest/Kernel.cs b/Tests/Kernels/GraphicTest/Kernel.cs index 8cc1ce5c59..5a37de0f71 100644 --- a/Tests/Kernels/GraphicTest/Kernel.cs +++ b/Tests/Kernels/GraphicTest/Kernel.cs @@ -102,6 +102,9 @@ private void DoTest(Canvas aCanvas) aCanvas.DrawImage(bitmap, 10, 10); aCanvas.DrawImage(letter, 50, 10); + Bitmap GetImageTest = aCanvas.GetImage(50, 10, (int)letter.Width, (int)letter.Height); + Assert.AreEqual(GetImageTest.RawData, letter.RawData, "GetImage returns correct values"); + /* Drawing BitmapHeaderV5 image */ Bitmap v5header = new Bitmap(Convert.FromBase64String(parrot)); aCanvas.DrawImage(v5header,0,0); From 014e99eaacfccbfc7449dd2dc7265ed0ec1d6f12 Mon Sep 17 00:00:00 2001 From: SzymekkYT <69077038+Szymekk44@users.noreply.github.com> Date: Wed, 25 Sep 2024 21:30:46 +0200 Subject: [PATCH 10/12] =?UTF-8?q?=F0=9F=90=9BVBE=20Bugfix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/Cosmos.System2/Graphics/VBECanvas.cs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/source/Cosmos.System2/Graphics/VBECanvas.cs b/source/Cosmos.System2/Graphics/VBECanvas.cs index a5cd53dc70..7088967114 100644 --- a/source/Cosmos.System2/Graphics/VBECanvas.cs +++ b/source/Cosmos.System2/Graphics/VBECanvas.cs @@ -285,6 +285,10 @@ public override void DrawArray(int[] aColors, int aX, int aY, int aWidth, int aH { for (int i = 0; i < aHeight; i++) { + if (i >= mode.Height) + { + return; + } int destinationIndex = (aY + i) * (int)mode.Width + aX; driver.CopyVRAM(destinationIndex, aColors, i * aWidth, aWidth); } @@ -294,6 +298,10 @@ public override void DrawArray(int[] aColors, int aX, int aY, int aWidth, int aH { for (int i = 0; i < aHeight; i++) { + if (i >= mode.Height) + { + return; + } int destinationIndex = (aY + i) * (int)mode.Width + aX; driver.CopyVRAM(destinationIndex, aColors, i * aWidth + startIndex, aWidth); } @@ -458,15 +466,16 @@ public override Bitmap GetImage(int x, int y, int width, int height) int endX = Math.Min(x + width, (int)Mode.Width); int endY = Math.Min(y + height, (int)Mode.Height); - int offsetX = Math.Max(0, -x); - int offsetY = Math.Max(0, -y); + int offsetX = Math.Max(0, -x); + int offsetY = Math.Max(0, -y); - int[] rawData = new int[width * height]; + int[] rawData = new int[width * height]; for (int posy = startY; posy < endY; posy++) { int srcOffset = posy * (int)Mode.Width + startX; - int destOffset = (posy - startY) * width; + int destOffset = (posy - startY + offsetY) * width + offsetX; + driver.GetVRAM(srcOffset, rawData, destOffset, endX - startX); } From 7456545b135f4f7df321ce1ea5d15d4fe6618530 Mon Sep 17 00:00:00 2001 From: SzymekkYT <69077038+Szymekk44@users.noreply.github.com> Date: Wed, 25 Sep 2024 22:58:07 +0200 Subject: [PATCH 11/12] =?UTF-8?q?=E2=8F=AAReverted=20drivers=20to=20not=20?= =?UTF-8?q?public?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/Cosmos.System2/Graphics/SVGAIICanvas.cs | 4 ++-- source/Cosmos.System2/Graphics/VBECanvas.cs | 4 ++-- source/Cosmos.System2/Graphics/VGACanvas.cs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source/Cosmos.System2/Graphics/SVGAIICanvas.cs b/source/Cosmos.System2/Graphics/SVGAIICanvas.cs index 0dd7bc8ead..c694205d8f 100644 --- a/source/Cosmos.System2/Graphics/SVGAIICanvas.cs +++ b/source/Cosmos.System2/Graphics/SVGAIICanvas.cs @@ -17,8 +17,8 @@ public class SVGAIICanvas : Canvas internal Debugger debugger = new("SVGAIIScreen"); static readonly Mode defaultMode = new(1024, 768, ColorDepth.ColorDepth32); - public Mode mode; - public readonly VMWareSVGAII driver; + Mode mode; + readonly VMWareSVGAII driver; /// /// Initializes a new instance of the class. diff --git a/source/Cosmos.System2/Graphics/VBECanvas.cs b/source/Cosmos.System2/Graphics/VBECanvas.cs index 7088967114..62a77c6bd2 100644 --- a/source/Cosmos.System2/Graphics/VBECanvas.cs +++ b/source/Cosmos.System2/Graphics/VBECanvas.cs @@ -14,8 +14,8 @@ namespace Cosmos.System.Graphics public class VBECanvas : Canvas { static readonly Mode defaultMode = new(1024, 768, ColorDepth.ColorDepth32); - public readonly VBEDriver driver; - public Mode mode; + readonly VBEDriver driver; + Mode mode; /// /// Initializes a new instance of the class. diff --git a/source/Cosmos.System2/Graphics/VGACanvas.cs b/source/Cosmos.System2/Graphics/VGACanvas.cs index b5498bb723..0d39b52f90 100644 --- a/source/Cosmos.System2/Graphics/VGACanvas.cs +++ b/source/Cosmos.System2/Graphics/VGACanvas.cs @@ -12,7 +12,7 @@ namespace Cosmos.System.Graphics public class VGACanvas : Canvas { bool enabled; - public readonly VGADriver driver; + readonly VGADriver driver; /// /// Available VGA supported video modes. From 9f36cb50ef05b6c598046ae1abe8080f55b2a887 Mon Sep 17 00:00:00 2001 From: SzymekkYT <69077038+Szymekk44@users.noreply.github.com> Date: Wed, 25 Sep 2024 23:01:12 +0200 Subject: [PATCH 12/12] =?UTF-8?q?=E2=8F=AAFully=20revert=20driver=20to=20*?= =?UTF-8?q?private*?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/Cosmos.System2/Graphics/FullScreenCanvas.cs | 2 +- source/Cosmos.System2/Graphics/SVGAIICanvas.cs | 2 +- source/Cosmos.System2/Graphics/VBECanvas.cs | 2 +- source/Cosmos.System2/Graphics/VGACanvas.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/Cosmos.System2/Graphics/FullScreenCanvas.cs b/source/Cosmos.System2/Graphics/FullScreenCanvas.cs index 89d4c22dec..ca6d5fb417 100644 --- a/source/Cosmos.System2/Graphics/FullScreenCanvas.cs +++ b/source/Cosmos.System2/Graphics/FullScreenCanvas.cs @@ -35,7 +35,7 @@ private enum VideoDriver VGADriver } - public static Canvas videoDriver = null; + private static Canvas videoDriver = null; static readonly PCIDevice svgaIIDevice = PCI.GetDevice(VendorID.VMWare, DeviceID.SVGAIIAdapter); /// diff --git a/source/Cosmos.System2/Graphics/SVGAIICanvas.cs b/source/Cosmos.System2/Graphics/SVGAIICanvas.cs index c694205d8f..d0e1488d90 100644 --- a/source/Cosmos.System2/Graphics/SVGAIICanvas.cs +++ b/source/Cosmos.System2/Graphics/SVGAIICanvas.cs @@ -18,7 +18,7 @@ public class SVGAIICanvas : Canvas static readonly Mode defaultMode = new(1024, 768, ColorDepth.ColorDepth32); Mode mode; - readonly VMWareSVGAII driver; + private readonly VMWareSVGAII driver; /// /// Initializes a new instance of the class. diff --git a/source/Cosmos.System2/Graphics/VBECanvas.cs b/source/Cosmos.System2/Graphics/VBECanvas.cs index 62a77c6bd2..493732cbf4 100644 --- a/source/Cosmos.System2/Graphics/VBECanvas.cs +++ b/source/Cosmos.System2/Graphics/VBECanvas.cs @@ -14,7 +14,7 @@ namespace Cosmos.System.Graphics public class VBECanvas : Canvas { static readonly Mode defaultMode = new(1024, 768, ColorDepth.ColorDepth32); - readonly VBEDriver driver; + private readonly VBEDriver driver; Mode mode; /// diff --git a/source/Cosmos.System2/Graphics/VGACanvas.cs b/source/Cosmos.System2/Graphics/VGACanvas.cs index 0d39b52f90..9cc89fbd40 100644 --- a/source/Cosmos.System2/Graphics/VGACanvas.cs +++ b/source/Cosmos.System2/Graphics/VGACanvas.cs @@ -12,7 +12,7 @@ namespace Cosmos.System.Graphics public class VGACanvas : Canvas { bool enabled; - readonly VGADriver driver; + private readonly VGADriver driver; /// /// Available VGA supported video modes.