2. Framebuffer + Videobuffer
This section outlines data + operations needed to interact with the framebuffer.
2.1. Actual Framebuffer
2.1.1. typedef + struct contents
<<norns_typedefs>>=
typedef struct norns_framebuffer norns_framebuffer;
<<norns_structs>>=
struct norns_framebuffer {
int fbfd;
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
long int screensize;
char *fbp;
};
2.1.2. allocating/freeing
<<norns_funcdefs>>=
void norns_framebuffer_new(norns_framebuffer **pfb);
void norns_framebuffer_del(norns_framebuffer **pfb);
<<norns_functions>>=
void norns_framebuffer_new(norns_framebuffer **pfb)
{
norns_framebuffer *fb;
fb = calloc(1, sizeof(norns_framebuffer));
*pfb = fb;
}
void norns_framebuffer_del(norns_framebuffer **fb)
{
free(*fb);
}
2.1.3. opening the framebuffer
<<norns_funcdefs>>=
int norns_framebuffer_open(norns_framebuffer *fb);
<<norns_functions>>=
int norns_framebuffer_open(norns_framebuffer *fb)
{
int rc;
fb->fbfd = open("/dev/fb0", O_RDWR);
if (fb->fbfd == -1) {
perror("Error: cannot open framebuffer device");
return 1;
}
rc = ioctl(fb->fbfd, FBIOGET_FSCREENINFO, &fb->finfo);
if (rc == -1) {
perror("Error reading fixed information");
return 2;
}
rc = ioctl(fb->fbfd, FBIOGET_VSCREENINFO, &fb->vinfo);
if (rc == -1) {
perror("Error reading variable information");
return 3;
}
fb->screensize = fb->vinfo.xres *
fb->vinfo.yres *
fb->vinfo.bits_per_pixel / 8;
fb->fbp = (char *)mmap(0,
fb->screensize,
PROT_READ | PROT_WRITE,
MAP_SHARED,
fb->fbfd,
0);
return 0;
}
2.1.4. closing the framebuffer
<<norns_funcdefs>>=
void norns_framebuffer_close(norns_framebuffer *fb);
<<norns_functions>>=
void norns_framebuffer_close(norns_framebuffer *fb)
{
munmap(fb->fbp, fb->screensize);
close(fb->fbfd);
}
2.1.5. Writing to the framebuffer
<<norns_funcdefs>>=
void norns_framebuffer_write(norns_framebuffer *fb,
int x, int y,
unsigned char val);
<<norns_functions>>=
void norns_framebuffer_write(norns_framebuffer *fb,
int x, int y,
unsigned char val)
{
long int loc;
loc = (x + fb->vinfo.xoffset) *
(fb->vinfo.bits_per_pixel/8) +
(y + fb->vinfo.yoffset) * fb->finfo.line_length;
fb->fbp[loc] = 0x0;
fb->fbp[loc + 1] = val;
}
2.2. Video Buffer
An array of 8-bit values to write to before copying over to the framebuffer.
2.2.1. typedef + struct contents
<<norns_typedefs>>=
typedef struct norns_videobuf norns_videobuf;
All that's really needed in a video buffer is a 128x64 array of unsigned 8-bit ints, which reduces to an array of size 8192.
<<norns_structs>>=
struct norns_videobuf {
unsigned char buf[8192];
};
2.2.2. allocating/freeing
<<norns_funcdefs>>=
void norns_videobuf_new(norns_videobuf **pvb);
void norns_videobuf_del(norns_videobuf **pvb);
<<norns_functions>>=
void norns_videobuf_new(norns_videobuf **pvb)
{
norns_videobuf *vb;
vb = calloc(1, sizeof(norns_videobuf));
*pvb = vb;
}
void norns_videobuf_del(norns_videobuf **vb)
{
free(*vb);
}
2.2.3. initializing the video buffer
<<norns_funcdefs>>=
void norns_videobuf_init(norns_videobuf *vb);
<<norns_functions>>=
void norns_videobuf_init(norns_videobuf *vb)
{
norns_videobuf_clear(vb);
}
2.2.4. getting the video buffer
<<norns_funcdefs>>=
unsigned char *norns_videobuf_get(norns_videobuf *buf);
<<norns_functions>>=
unsigned char *norns_videobuf_get(norns_videobuf *buf)
{
return buf->buf;
}
2.2.5. Writing a pixel to the video buffer
<<norns_funcdefs>>=
void norns_videobuf_write(norns_videobuf *vb,
int x, int y,
unsigned char val);
<<norns_functions>>=
void norns_videobuf_write(norns_videobuf *vb,
int x, int y,
unsigned char val)
{
if (x >= 128 || y >= 64) return;
vb->buf[x + y*128] = val;
}
2.2.6. Clearing the screen
<<norns_funcdefs>>=
void norns_videobuf_clear(norns_videobuf *vb);
<<norns_functions>>=
void norns_videobuf_clear(norns_videobuf *vb)
{
int x;
int y;
for (y = 0; y < 64; y++) {
for (x = 0; x < 128; x++) {
vb->buf[x + y*128] = 0;
}
}
}
2.2.7. copying the video buffer to the framebuffer
<<norns_funcdefs>>=
void norns_videobuf_copy(norns_videobuf *vb,
norns_framebuffer *fb);
<<norns_functions>>=
void norns_videobuf_copy(norns_videobuf *vb,
norns_framebuffer *fb)
{
int x, y;
unsigned char val;
int w, h;
h = fb->vinfo.yres;
w = fb->vinfo.xres;
for(y = 0; y < h; y++) {
for(x = 0; x < w; x++) {
if (x >= 128 || y >= 64) continue;
val = vb->buf[x + y * w];
norns_framebuffer_write(fb, x, y, val);
}
}
}
prev | home | next