diff --git a/.fblib.c.swp b/.fblib.c.swp new file mode 100644 index 0000000..a4e5717 Binary files /dev/null and b/.fblib.c.swp differ diff --git a/.fblib.h.swp b/.fblib.h.swp new file mode 100644 index 0000000..7ad4068 Binary files /dev/null and b/.fblib.h.swp differ diff --git a/.gitignore b/.gitignore index e40a096..c61352b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ fb_dash +*.o diff --git a/Makefile b/Makefile index 11cf553..4dcc90f 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,10 @@ CFLAGS = -g -Wall -fb_dash: fb_dash.c - gcc -o $@ $(CFLAGS) $< +fbdash: fbdash.c fblib + gcc fblib.o -o $@ $(CFLAGS) $< + +fblib: fblib.o + gcc -c fblib.c clean: - rm fb_dash + rm fbdash fblib.o diff --git a/fbdash b/fbdash new file mode 100755 index 0000000..4c4ec93 Binary files /dev/null and b/fbdash differ diff --git a/fbdash.c b/fbdash.c new file mode 100644 index 0000000..1469ec2 --- /dev/null +++ b/fbdash.c @@ -0,0 +1,113 @@ +/* + * fbdash.c + * + * Adapted by Florian Klemenz for use in the fb_dash project + * + * Source and all credit goes to + * http://raspberrycompote.blogspot.ie/2014/03/low-level-graphics-on-raspberry-pi-part_14.html + * + * Original work by J-P Rosti (a.k.a -rst- and 'Raspberry Compote') + * + * Licensed under the Creative Commons Attribution 3.0 Unported License + * (http://creativecommons.org/licenses/by/3.0/deed.en_US) + * + * Distributed in the hope that this will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#include "fblib.h" + +// 'global' variables to store screen info +char *fbp = 0; +struct fb_var_screeninfo vinfo; +struct fb_fix_screeninfo finfo; + + +// helper function for drawing - no more need to go mess with +// the main function when just want to change what to draw... +void draw() { + + clear_screen(fbp); + + // horizontal spacersint x_space = 10; + int y_step_width = vinfo.yres / 4; + for (int i = 1; i < 4; i++) { + int x0 = 15; + int x1 = vinfo.xres - x0; + int y = y_step_width * i; + + int r = 200; + int g = 32; + int b = 32; + + draw_line(fbp, x0, y-1, x1, y-1, r, g, b); + draw_line(fbp, x0, y , x1, y , r, g, b); + draw_line(fbp, x0, y+1, x1, y+1, r, g, b); + } + + + + + + +} + +// application entry point +int main(int argc, char* argv[]) +{ + + int fbfd = 0; + //struct fb_var_screeninfo orig_vinfo; + long int screensize = 0; + + // Open the framebuffer file for reading and writing + fbfd = open("/dev/fb1", O_RDWR); + if (fbfd == -1) { + printf("Error: cannot open framebuffer device.\n"); + return(1); + } + printf("The framebuffer device was opened successfully.\n"); + + // Get variable screen information + if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) { + printf("Error reading variable information.\n"); + } + printf("Variable info: %dx%d, %dbpp\n", + vinfo.xres, vinfo.yres, + vinfo.bits_per_pixel ); + + // Get fixed screen information + if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) { + printf("Error reading fixed information.\n"); + } + printf("Fixed info: smem_len %d, line_length %d\n", finfo.smem_len, finfo.line_length); + + // map fb to user mem + screensize = finfo.smem_len; + fbp = (char*)mmap(0, + screensize, + PROT_READ | PROT_WRITE, + MAP_SHARED, + fbfd, + 0); + + if ((int)fbp == -1) { + printf("Failed to mmap.\n"); + } + else { + // draw... + draw(); + } + + // cleanup + //clear_screen(fbp); + // unmap fb file from memory + munmap(fbp, screensize); + // close fb file + close(fbfd); + + return 0; + +} diff --git a/fblib.c b/fblib.c new file mode 100644 index 0000000..43bd98a --- /dev/null +++ b/fblib.c @@ -0,0 +1,168 @@ +/* + * fblib.c + * + * Adapted by Florian Klemenz for use in the fb_dash project + * + * Source and all credit goes to + * http://raspberrycompote.blogspot.ie/2014/03/low-level-graphics-on-raspberry-pi-part_14.html + * + * Original work by J-P Rosti (a.k.a -rst- and 'Raspberry Compote') + * + * Licensed under the Creative Commons Attribution 3.0 Unported License + * (http://creativecommons.org/licenses/by/3.0/deed.en_US) + * + * Distributed in the hope that this will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#include "fblib.h" + + +// helper function to 'plot' a pixel in given color +void put_pixel(char *fbp, int x, int y, int r, int g, int b) +{ + // calculate the pixel's byte offset inside the buffer + // note: x * 2 as every pixel is 2 consecutive bytes + //unsigned int pix_offset = x * 2 + y * finfo.line_length; + unsigned int pix_offset = x * 2 + y * (WIDTH * 2); + + // now this is about the same as 'fbp[pix_offset] = value' + // but a bit more complicated for RGB565 + //unsigned short c = ((r / 8) << 11) + ((g / 4) << 5) + (b / 8); + unsigned short c = ((r / 8) * 2048) + ((g / 4) * 32) + (b / 8); + // write 'two bytes at once' + *((unsigned short*)(fbp + pix_offset)) = c; + +} + +// helper function to draw a rectangle in given color +void fill_rect(char *fbp, int x, int y, int w, int h, int r, int g, int b) { + int cx, cy; + for (cy = 0; cy < h; cy++) { + for (cx = 0; cx < w; cx++) { + put_pixel(fbp, x + cx, y + cy, r, g, b); + } + } +} + +// helper function to draw a rectangle outline in given color +void draw_rect(char *fbp, int x0, int y0, int w, int h, int r, int g, int b) { + draw_line(fbp, x0, y0, x0 + w, y0, r, g, b); // top + draw_line(fbp, x0, y0, x0, y0 + h, r, g, b); // left + draw_line(fbp, x0, y0 + h, x0 + w, y0 + h, r, g, b); // bottom + draw_line(fbp, x0 + w, y0, x0 + w, y0 + h, r, g, b); // right +} + +// helper function to draw a circle outline in given color +// (uses Bresenham's circle algorithm) +void draw_circle(char *fbp, int x0, int y0, int radius, int r, int g, int b) +{ + int x = radius; + int y = 0; + int radiusError = 1 - x; + + while(x >= y) + { + // top left + put_pixel(fbp, -y + x0, -x + y0, r, g, b); + // top right + put_pixel(fbp, y + x0, -x + y0, r, g, b); + // upper middle left + put_pixel(fbp, -x + x0, -y + y0, r, g, b); + // upper middle right + put_pixel(fbp, x + x0, -y + y0, r, g, b); + // lower middle left + put_pixel(fbp, -x + x0, y + y0, r, g, b); + // lower middle right + put_pixel(fbp, x + x0, y + y0, r, g, b); + // bottom left + put_pixel(fbp, -y + x0, x + y0, r, g, b); + // bottom right + put_pixel(fbp, y + x0, x + y0, r, g, b); + + y++; + if (radiusError < 0) + { + radiusError += 2 * y + 1; + } else { + x--; + radiusError+= 2 * (y - x + 1); + } + } +} + +// helper function to draw a filled circle in given color +// (uses Bresenham's circle algorithm) +void fill_circle(char *fbp, int x0, int y0, int radius, int r, int g, int b) { + int x = radius; + int y = 0; + int radiusError = 1 - x; + + while(x >= y) + { + // top + draw_line(fbp, -y + x0, -x + y0, y + x0, -x + y0, r, g, b); + // upper middle + draw_line(fbp, -x + x0, -y + y0, x + x0, -y + y0, r, g, b); + // lower middle + draw_line(fbp, -x + x0, y + y0, x + x0, y + y0, r, g, b); + // bottom + draw_line(fbp, -y + x0, x + y0, y + x0, x + y0, r, g, b); + + y++; + if (radiusError < 0) + { + radiusError += 2 * y + 1; + } else { + x--; + radiusError+= 2 * (y - x + 1); + } + } +} + +// helper function to clear the screen - fill whole +// screen with given color +void clear_screen(char *fbp) { + //memset(fbp, 0, vinfo.xres * vinfo.yres * 2); // 16Bit = 8Bit * 2 + memset(fbp, 0, WIDTH * HEIGHT * 2); // 16Bit = 8Bit * 2 +} + +// helper function to draw a line in given color +// (uses Bresenham's line algorithm) +void draw_line(char *fbp, int x0, int y0, int x1, int y1, int r, int g, int b) { + int dx = x1 - x0; + dx = (dx >= 0) ? dx : -dx; // abs() + int dy = y1 - y0; + dy = (dy >= 0) ? dy : -dy; // abs() + int sx; + int sy; + if (x0 < x1) + sx = 1; + else + sx = -1; + if (y0 < y1) + sy = 1; + else + sy = -1; + int err = dx - dy; + int e2; + int done = 0; + while (!done) { + put_pixel(fbp, x0, y0, r, g, b); + if ((x0 == x1) && (y0 == y1)) + done = 1; + else { + e2 = 2 * err; + if (e2 > -dy) { + err = err - dy; + x0 = x0 + sx; + } + if (e2 < dx) { + err = err + dx; + y0 = y0 + sy; + } + } + } +} diff --git a/fblib.h b/fblib.h new file mode 100644 index 0000000..07ffbf1 --- /dev/null +++ b/fblib.h @@ -0,0 +1,48 @@ +/* + * fblib.h + * + * Adapted by Florian Klemenz for use in the fb_dash project + * + * Source and all credit goes to + * http://raspberrycompote.blogspot.ie/2014/03/low-level-graphics-on-raspberry-pi-part_14.html + * + * Original work by J-P Rosti (a.k.a -rst- and 'Raspberry Compote') + * + * Licensed under the Creative Commons Attribution 3.0 Unported License + * (http://creativecommons.org/licenses/by/3.0/deed.en_US) + * + * Distributed in the hope that this will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + + +#ifndef FBLIB_H +#define FBLIB_H + +#include +#include +#include +#include +#include +#include +#include +#include + + +#define WIDTH 240 +#define HEIGHT 320 + +void put_pixel(char *fbp, int x, int y, int r, int g, int b); +void clear_screen(char *fbp); + +void draw_line(char *fbp, int x0, int y0, int x1, int y1, int r, int g, int b); + +void draw_rect(char *fbp, int x0, int y0, int w, int h, int r, int g, int b); +void fill_rect(char *fbp, int x, int y, int w, int h, int r, int g, int b); + +void draw_circle(char *fbp, int x0, int y0, int radius, int r, int g, int b); +void fill_circle(char *fbp, int x0, int y0, int radius, int r, int g, int b); + +#endif