Move screen and font to proper classes
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
#include "font.h"
|
#include "font.h"
|
||||||
#include "screen.h"
|
|
||||||
|
|
||||||
/* PSF2 header format
|
/* PSF2 header format
|
||||||
* Taken from the Linux KBD documentation
|
* Taken from the Linux KBD documentation
|
||||||
@@ -7,19 +6,16 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const static uint8_t magic[] = {0x72, 0xb5, 0x4a, 0x86};
|
const static uint8_t magic[] = {0x72, 0xb5, 0x4a, 0x86};
|
||||||
|
const static uint32_t max_version = 0;
|
||||||
|
|
||||||
|
const static uint8_t unicode_sep = 0xff;
|
||||||
|
const static uint8_t unicode_start = 0xfe;
|
||||||
|
|
||||||
/* bits used in flags */
|
/* bits used in flags */
|
||||||
enum psf2_flags {
|
enum psf2_flags {
|
||||||
psf2_has_unicode = 0x00000001
|
psf2_has_unicode = 0x00000001
|
||||||
};
|
};
|
||||||
|
|
||||||
/* max version recognized so far */
|
|
||||||
#define PSF2_MAXVERSION 0
|
|
||||||
|
|
||||||
/* UTF8 separators */
|
|
||||||
#define PSF2_SEPARATOR 0xFF
|
|
||||||
#define PSF2_STARTSEQ 0xFE
|
|
||||||
|
|
||||||
struct psf2_header {
|
struct psf2_header {
|
||||||
uint8_t magic[4];
|
uint8_t magic[4];
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
@@ -30,52 +26,59 @@ struct psf2_header {
|
|||||||
uint32_t height, width; // max dimensions of glyphs
|
uint32_t height, width; // max dimensions of glyphs
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
font
|
||||||
font_init(void *header, struct font *font)
|
font::load(void const *data)
|
||||||
{
|
{
|
||||||
struct psf2_header *psf2 = (struct psf2_header *)header;
|
psf2_header const *psf2 = static_cast<psf2_header const *>(data);
|
||||||
for (int i = 0; i < sizeof(magic); ++i) {
|
for (int i = 0; i < sizeof(magic); ++i) {
|
||||||
if (psf2->magic[i] != magic[i]) {
|
if (psf2->magic[i] != magic[i]) {
|
||||||
return 1;
|
return font{};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (font == 0)
|
uint8_t const *font_data = static_cast<uint8_t const *>(data) + psf2->header_size;
|
||||||
return 2;
|
return font{
|
||||||
|
psf2->height,
|
||||||
font->height = psf2->height;
|
psf2->width,
|
||||||
font->width = psf2->width;
|
psf2->length,
|
||||||
font->charsize = psf2->charsize;
|
font_data};
|
||||||
font->count = psf2->length;
|
|
||||||
font->data = (uint8_t *)header + psf2->header_size;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
font::font() :
|
||||||
font_draw(
|
m_height(0),
|
||||||
struct font *f,
|
m_width(0),
|
||||||
struct screen *s,
|
m_count(0),
|
||||||
uint32_t glyph,
|
m_data(nullptr)
|
||||||
uint32_t color,
|
{}
|
||||||
uint32_t x,
|
|
||||||
uint32_t y)
|
|
||||||
{
|
|
||||||
const uint32_t height = f->height;
|
|
||||||
const uint32_t width = f->width;
|
|
||||||
const uint32_t bwidth = (width+7)/8;
|
|
||||||
uint8_t *data = f->data + (glyph * f->charsize);
|
|
||||||
|
|
||||||
for (int dy = 0; dy < f->height; ++dy) {
|
font::font(unsigned height, unsigned width, unsigned count, uint8_t const *data) :
|
||||||
|
m_height(height),
|
||||||
|
m_width(width),
|
||||||
|
m_count(count),
|
||||||
|
m_data(data)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void
|
||||||
|
font::draw_glyph(
|
||||||
|
screen &s,
|
||||||
|
uint32_t glyph,
|
||||||
|
screen::pixel_t color,
|
||||||
|
screen::coord_t x,
|
||||||
|
screen::coord_t y) const
|
||||||
|
{
|
||||||
|
unsigned bwidth = (m_width+7)/8;
|
||||||
|
uint8_t const *data = m_data + (glyph * glyph_bytes());
|
||||||
|
|
||||||
|
for (int dy = 0; dy < m_height; ++dy) {
|
||||||
for (int dx = 0; dx < bwidth; ++dx) {
|
for (int dx = 0; dx < bwidth; ++dx) {
|
||||||
uint8_t byte = data[dy * bwidth + dx];
|
uint8_t byte = data[dy * bwidth + dx];
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (int i = 0; i < 8; ++i) {
|
||||||
if (dx*8 + i >= width) continue;
|
if (dx*8 + i >= m_width) continue;
|
||||||
const uint8_t mask = 1 << (7-i);
|
const uint8_t mask = 1 << (7-i);
|
||||||
uint32_t c = (byte & mask) ? color : 0;
|
uint32_t c = (byte & mask) ? color : 0;
|
||||||
screen_pixel(s, x + dx*8 + i, y + dy, c);
|
s.draw_pixel(x + dx*8 + i, y + dy, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +1,33 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
struct screen;
|
#include "screen.h"
|
||||||
|
|
||||||
struct font {
|
class font
|
||||||
uint16_t height;
|
{
|
||||||
uint16_t width;
|
public:
|
||||||
uint16_t charsize;
|
static font load(void const *data);
|
||||||
uint16_t count;
|
|
||||||
uint8_t *data;
|
unsigned glyph_bytes() const { return m_height * ((m_width + 7) / 8); }
|
||||||
|
unsigned count() const { return m_count; }
|
||||||
|
unsigned width() const { return m_width; }
|
||||||
|
unsigned height() const { return m_height; }
|
||||||
|
bool valid() const { return m_count > 0; }
|
||||||
|
|
||||||
|
void draw_glyph(
|
||||||
|
screen &s,
|
||||||
|
uint32_t glyph,
|
||||||
|
screen::pixel_t color,
|
||||||
|
screen::coord_t x,
|
||||||
|
screen::coord_t y) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
font();
|
||||||
|
font(unsigned height, unsigned width, unsigned count, uint8_t const *data);
|
||||||
|
|
||||||
|
unsigned m_height;
|
||||||
|
unsigned m_width;
|
||||||
|
unsigned m_count;
|
||||||
|
uint8_t const *m_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
int font_init(void *header, struct font *font);
|
|
||||||
|
|
||||||
int font_draw(
|
|
||||||
struct font *f,
|
|
||||||
struct screen *s,
|
|
||||||
uint32_t glyph,
|
|
||||||
uint32_t color,
|
|
||||||
uint32_t x,
|
|
||||||
uint32_t y);
|
|
||||||
|
|||||||
@@ -13,32 +13,22 @@ extern "C" {
|
|||||||
void
|
void
|
||||||
kernel_main(popcorn_data *header)
|
kernel_main(popcorn_data *header)
|
||||||
{
|
{
|
||||||
struct screen screen;
|
font f = font::load(header->font);
|
||||||
struct font font;
|
screen s{
|
||||||
int status = 0;
|
header->frame_buffer,
|
||||||
|
header->hres,
|
||||||
status = font_init(header->font, &font);
|
header->vres,
|
||||||
|
header->rmask,
|
||||||
status = screen_init(
|
header->gmask,
|
||||||
header->frame_buffer,
|
header->bmask};
|
||||||
header->hres,
|
|
||||||
header->vres,
|
|
||||||
header->rmask,
|
|
||||||
header->gmask,
|
|
||||||
header->bmask,
|
|
||||||
&screen);
|
|
||||||
|
|
||||||
uint32_t color = header->gmask;
|
uint32_t color = header->gmask;
|
||||||
uint32_t perline = header->hres / font.width;
|
uint32_t perline = header->hres / f.width();
|
||||||
const char message[] = "Hello, I am text rendered by the kernel! :-D ";
|
const char message[] = "Hello, I am text rendered by the kernel! :-D ";
|
||||||
for (int i=0; i<sizeof(message); ++i) {
|
for (int i=0; i<sizeof(message); ++i) {
|
||||||
font_draw(
|
f.draw_glyph(s, message[i], color,
|
||||||
&font,
|
(i % perline) * f.width() + 10,
|
||||||
&screen,
|
(i / perline) * f.height() + 10);
|
||||||
message[i],
|
|
||||||
color,
|
|
||||||
(i % perline) * font.width + 10,
|
|
||||||
(i / perline) * font.height + 10);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
do_the_set_registers(header);
|
do_the_set_registers(header);
|
||||||
|
|||||||
@@ -1,42 +1,28 @@
|
|||||||
#include "font.h"
|
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
|
|
||||||
int
|
screen::color_masks::color_masks(pixel_t r, pixel_t g, pixel_t b) : r(r), g(g), b(b) {}
|
||||||
screen_fill(struct screen *s, uint32_t color)
|
screen::resolution::resolution(coord_t w, coord_t h) : w(w), h(h) {}
|
||||||
|
|
||||||
|
screen::screen(
|
||||||
|
void *framebuffer,
|
||||||
|
coord_t hres, coord_t vres,
|
||||||
|
pixel_t rmask, pixel_t gmask, pixel_t bmask) :
|
||||||
|
m_framebuffer(static_cast<pixel_t *>(framebuffer)),
|
||||||
|
m_masks(rmask, gmask, bmask),
|
||||||
|
m_resolution(hres, vres)
|
||||||
{
|
{
|
||||||
const size_t len = s->hres * s->vres;
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
screen::fill(pixel_t color)
|
||||||
|
{
|
||||||
|
const size_t len = m_resolution.size();
|
||||||
for (size_t i = 0; i < len; ++i)
|
for (size_t i = 0; i < len; ++i)
|
||||||
s->data[i] = 0;
|
m_framebuffer[i] = color;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
screen_init(
|
screen::draw_pixel(coord_t x, coord_t y, pixel_t color)
|
||||||
void *frame_buffer,
|
|
||||||
uint32_t hres,
|
|
||||||
uint32_t vres,
|
|
||||||
uint32_t rmask,
|
|
||||||
uint32_t gmask,
|
|
||||||
uint32_t bmask,
|
|
||||||
struct screen *s)
|
|
||||||
{
|
{
|
||||||
s->data = static_cast<uint32_t *>(frame_buffer);
|
m_framebuffer[x + y * m_resolution.w] = color;
|
||||||
s->hres = hres;
|
|
||||||
s->vres = vres;
|
|
||||||
s->rmask = rmask;
|
|
||||||
s->gmask = gmask;
|
|
||||||
s->bmask = bmask;
|
|
||||||
|
|
||||||
return screen_fill(s, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
screen_pixel(
|
|
||||||
struct screen *s,
|
|
||||||
uint32_t x,
|
|
||||||
uint32_t y,
|
|
||||||
uint32_t color)
|
|
||||||
{
|
|
||||||
s->data[x + y*s->hres] = color;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,29 +2,37 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
struct screen {
|
class screen
|
||||||
uint32_t *data;
|
{
|
||||||
uint32_t hres;
|
public:
|
||||||
uint32_t vres;
|
using coord_t = uint32_t;
|
||||||
uint32_t rmask;
|
using pixel_t = uint32_t;
|
||||||
uint32_t gmask;
|
|
||||||
uint32_t bmask;
|
screen(
|
||||||
|
void *framebuffer,
|
||||||
|
coord_t hres, coord_t vres,
|
||||||
|
pixel_t rmask, pixel_t gmask, pixel_t bmask);
|
||||||
|
|
||||||
|
void fill(pixel_t color);
|
||||||
|
void draw_pixel(coord_t x, coord_t y, pixel_t color);
|
||||||
|
|
||||||
|
screen() = delete;
|
||||||
|
screen(const screen &) = delete;
|
||||||
|
|
||||||
|
struct color_masks {
|
||||||
|
pixel_t r, g, b;
|
||||||
|
color_masks(pixel_t r, pixel_t g, pixel_t b);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct resolution {
|
||||||
|
coord_t w, h;
|
||||||
|
resolution(coord_t w, coord_t h);
|
||||||
|
coord_t size() const { return w * h; }
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
pixel_t *m_framebuffer;
|
||||||
|
color_masks m_masks;
|
||||||
|
resolution m_resolution;
|
||||||
};
|
};
|
||||||
|
|
||||||
int screen_init(
|
|
||||||
void *frame_buffer,
|
|
||||||
uint32_t hres,
|
|
||||||
uint32_t vres,
|
|
||||||
uint32_t rmask,
|
|
||||||
uint32_t gmask,
|
|
||||||
uint32_t bmask,
|
|
||||||
struct screen *s);
|
|
||||||
|
|
||||||
int screen_fill(struct screen *s, uint32_t color);
|
|
||||||
|
|
||||||
int screen_pixel(
|
|
||||||
struct screen *s,
|
|
||||||
uint32_t x,
|
|
||||||
uint32_t y,
|
|
||||||
uint32_t color);
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user