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.