Convert fb, console, klog to "static instance" namespacing structs
This commit is contained in:
1 parent
06242a0c9f
commit
98e992aad0
4 files changed
+102
-110
No files matched your search
+274
@@ -0,0 +1,274 @@
|
||||
/**
|
||||
* HULK Framebuffer support.
|
||||
*/
|
||||
module hulk.fb;
|
||||
|
||||
import hos.memory;
|
||||
import hulk.kfont;
|
||||
|
||||
/**
|
||||
* Represent a graphical frame buffer.
|
||||
*
|
||||
* TODO: Handle other pixel formats. Currently only BGRx is supported.
|
||||
*/
|
||||
struct fb
|
||||
{
|
||||
/** Frame buffer base address. */
|
||||
private __gshared static uint * m_buffer;
|
||||
|
||||
/** Frame buffer width. */
|
||||
private __gshared static uint m_width;
|
||||
|
||||
/** Frame buffer height. */
|
||||
private __gshared static uint m_height;
|
||||
|
||||
/** Frame buffer stride. */
|
||||
private __gshared static uint m_stride;
|
||||
|
||||
/** Number of pixels in the frame buffer (whether visible or not). */
|
||||
private __gshared static uint m_buffer_size;
|
||||
|
||||
/**
|
||||
* Get the framebuffer width.
|
||||
*/
|
||||
public static @property uint width()
|
||||
{
|
||||
return m_width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the framebuffer height.
|
||||
*/
|
||||
public static @property uint height()
|
||||
{
|
||||
return m_height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a frame buffer.
|
||||
*
|
||||
* @param buffer Frame buffer base address.
|
||||
* @param width Frame buffer width.
|
||||
* @param height Frame buffer height.
|
||||
* @param stride Frame buffer stride.
|
||||
*/
|
||||
static void initialize(uint * buffer, uint width, uint height, uint stride)
|
||||
{
|
||||
m_buffer = buffer;
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_stride = stride;
|
||||
m_buffer_size = stride * height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the frame buffer to the given color.
|
||||
*
|
||||
* @param color Color to clear to.
|
||||
*/
|
||||
static void clear(uint color = 0u)
|
||||
{
|
||||
memset32(m_buffer, color, m_buffer_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a solid rectangle on the framebuffer.
|
||||
*
|
||||
* @param x X coordinate of left side of rectangle.
|
||||
* @param y Y coordinate of bottom side of rectangle.
|
||||
* @param width Width of rectangle.
|
||||
* @param height Height of rectangle.
|
||||
* @param color Color of rectangle.
|
||||
*/
|
||||
static void rect(size_t x, size_t y, size_t width, size_t height, uint color)
|
||||
{
|
||||
for (size_t iy = 0u; iy < height; iy++)
|
||||
{
|
||||
size_t buffer_index = buffer_index(x, y);
|
||||
memset32(&m_buffer[buffer_index], color, width);
|
||||
y++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a horizontal line.
|
||||
*
|
||||
* @param x X coordinate of left side of line.
|
||||
* @param y Y coordinate of line.
|
||||
* @param width Width of line.
|
||||
* @param color Color of line.
|
||||
*/
|
||||
static void hline(size_t x, size_t y, size_t width, uint color)
|
||||
{
|
||||
size_t buffer_index = buffer_index(x, y);
|
||||
memset32(&m_buffer[buffer_index], color, width);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a vertical line.
|
||||
*
|
||||
* @param x X coordinate of line.
|
||||
* @param y Y coordinate of bottom of line.
|
||||
* @param height Height of line.
|
||||
* @param color Color of line.
|
||||
*/
|
||||
static void vline(size_t x, size_t y, size_t height, uint color)
|
||||
{
|
||||
size_t buffer_index = buffer_index(x, y);
|
||||
for (size_t iy = 0u; iy < height; iy++)
|
||||
{
|
||||
m_buffer[buffer_index] = color;
|
||||
buffer_index -= m_stride;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a character.
|
||||
*
|
||||
* @param x X coordinate of left side of character.
|
||||
* @param y Y coordinate of bottom side of character.
|
||||
* @param ch Character to draw.
|
||||
* @param color Color of character.
|
||||
*/
|
||||
static void character(int x, int y, char ch, uint color)
|
||||
{
|
||||
const(CharInfo) * ci = &kfont.chars[ch];
|
||||
blend_alpha_bitmap(x + ci.left, y + kfont.baseline_offset + ci.top - ci.height, ci.bitmap, ci.width, ci.height, color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Blend an 8-bit alpha bitmap to the framebuffer.
|
||||
*
|
||||
* @param x X coordinate of left side of target location.
|
||||
* @param y Y coordinate of bottom side of target location.
|
||||
* @param alpha_bitmap 8-bit alpha-channel bitmap.
|
||||
* @param width Bitmap width.
|
||||
* @param height Bitmap height.
|
||||
* @param color Color to blend with alpha value.
|
||||
*/
|
||||
static void blend_alpha_bitmap(size_t x, size_t y, const(ubyte) * alpha_bitmap,
|
||||
size_t width, size_t height, uint color)
|
||||
{
|
||||
y += height - 1u;
|
||||
size_t bitmap_index;
|
||||
for (size_t iy = 0u; iy < height; iy++)
|
||||
{
|
||||
for (size_t ix = 0u; ix < width; ix++)
|
||||
{
|
||||
size_t buffer_index = buffer_index(x + ix, y);
|
||||
ubyte alpha = alpha_bitmap[bitmap_index];
|
||||
uint current_color = m_buffer[buffer_index];
|
||||
uint in_color_scaled = scale_color(color, alpha);
|
||||
uint old_color_scaled = scale_color(current_color, 255u - alpha);
|
||||
uint new_color = old_color_scaled + in_color_scaled;
|
||||
m_buffer[buffer_index] = new_color;
|
||||
bitmap_index++;
|
||||
}
|
||||
y--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Blend an 8-bit alpha bitmap to the framebuffer.
|
||||
*
|
||||
* @param x X coordinate of left side of target location.
|
||||
* @param y Y coordinate of bottom side of target location.
|
||||
* @param alpha_bitmap 8-bit alpha-channel bitmap.
|
||||
* @param width Bitmap width.
|
||||
* @param height Bitmap height.
|
||||
* @param color Color to blend with alpha value.
|
||||
*/
|
||||
static void blend_alpha_bitmap(size_t x, size_t y, const(ubyte)[] alpha_bitmap,
|
||||
size_t width, size_t height, uint color)
|
||||
{
|
||||
blend_alpha_bitmap(x, y, alpha_bitmap.ptr, width, height, color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Blit an 8-bit alpha bitmap to the framebuffer.
|
||||
* The foreground will be white (based on the alpha value), and the
|
||||
* background black.
|
||||
*
|
||||
* @param x X coordinate of left side of target location.
|
||||
* @param y Y coordinate of bottom side of target location.
|
||||
* @param alpha_bitmap 8-bit alpha-channel bitmap.
|
||||
* @param width Bitmap width.
|
||||
* @param height Bitmap height.
|
||||
*/
|
||||
static void blit_alpha_bitmap(size_t x, size_t y, const(ubyte) * alpha_bitmap,
|
||||
size_t width, size_t height)
|
||||
{
|
||||
y += height - 1u;
|
||||
size_t bitmap_index;
|
||||
for (size_t iy = 0u; iy < height; iy++)
|
||||
{
|
||||
for (size_t ix = 0u; ix < width; ix++)
|
||||
{
|
||||
size_t buffer_index = buffer_index(x + ix, y);
|
||||
ubyte alpha = alpha_bitmap[bitmap_index];
|
||||
m_buffer[buffer_index] = (alpha << 16u) | (alpha << 8u) | alpha;
|
||||
bitmap_index++;
|
||||
}
|
||||
y--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Blit an 8-bit alpha bitmap to the framebuffer.
|
||||
* The foreground will be white (based on the alpha value), and the
|
||||
* background black.
|
||||
*
|
||||
* @param x X coordinate of left side of target location.
|
||||
* @param y Y coordinate of bottom side of target location.
|
||||
* @param alpha_bitmap 8-bit alpha-channel bitmap.
|
||||
* @param width Bitmap width.
|
||||
* @param height Bitmap height.
|
||||
*/
|
||||
static void blit_alpha_bitmap(size_t x, size_t y, const(ubyte)[] alpha_bitmap,
|
||||
size_t width, size_t height)
|
||||
{
|
||||
blit_alpha_bitmap(x, y, alpha_bitmap.ptr, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy framebuffer rows up in the framebuffer.
|
||||
*
|
||||
* @param y Y coordinate of bottom side of region to copy up.
|
||||
* @param height Height of region to copy up.
|
||||
* @param offset Number of rows to copy region up by.
|
||||
*/
|
||||
static void copy_rows_up(size_t y, size_t height, size_t offset)
|
||||
{
|
||||
memcpy32(&m_buffer[buffer_index(0u, y + height + offset - 1u)],
|
||||
&m_buffer[buffer_index(0u, y + height - 1u)],
|
||||
(m_stride * height));
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale a color value by an alpha amount.
|
||||
*
|
||||
* @param color Color value.
|
||||
* @param alpha Alpha amount.
|
||||
*
|
||||
* @return Scaled color value.
|
||||
*/
|
||||
private static uint scale_color(uint color, ubyte alpha)
|
||||
{
|
||||
return ((((color & 0xFFu) * alpha) >> 8u) & 0xFFu) |
|
||||
((((color & 0xFF00u) * alpha) >> 8u) & 0xFF00u) |
|
||||
((((color & 0xFF0000u) * alpha) >> 8u) & 0xFF0000u);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the buffer index for the given X and Y coordinates.
|
||||
*
|
||||
* @param x X coordinate from left side of framebuffer.
|
||||
* @param y Y coordinate from bottom side of framebuffer.
|
||||
*
|
||||
* @return Buffer index for the given X and Y coordinates.
|
||||
*/
|
||||
private static size_t buffer_index(size_t x, size_t y)
|
||||
{
|
||||
return (m_height - y - 1u) * m_stride + x;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user