Last active
November 28, 2019 18:32
-
-
Save MitchRatquest/50dec3fc47738401cad6de1ee9eb01ec to your computer and use it in GitHub Desktop.
simple osc framebuffer beginnings
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <linux/fb.h> | |
#include <fcntl.h> | |
#include <sys/ioctl.h> | |
#include <sys/mman.h> | |
#include <inttypes.h> | |
#include <math.h> | |
#include "lo/lo.h" | |
//liblo below | |
int done = 0; | |
void error(int num, const char *m, const char *path); | |
int quit_handler(const char *path, const char *types, lo_arg ** argv, | |
int argc, void *data, void *user_data); | |
int line_handler(const char *path, const char *types, lo_arg ** argv, | |
int argc, void *data, void *user_data); | |
int circle_handler(const char *path, const char *types, lo_arg ** argv, | |
int argc, void *data, void *user_data); | |
int box_handler(const char *path, const char *types, lo_arg ** argv, | |
int argc, void *data, void *user_data); | |
//framebuffer below | |
//we're on a 320x240 16bpp rgb565 ili9341 display | |
int fbfd = 0; | |
struct fb_var_screeninfo vinfo; | |
struct fb_fix_screeninfo finfo; | |
long int screensize = 0; | |
char *fbp = 0; | |
int x = 0, y = 0; | |
long int location = 0; | |
int maxx, maxy; | |
void setPixel(int x, int y, uint16_t pixel) | |
{ | |
//uint16_t pixel = (r << 11) | (g << 5) | b; | |
uint32_t location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + | |
(y/2+vinfo.yoffset) * finfo.line_length; | |
*((uint16_t*)(fbp + location)) = pixel; | |
} | |
int main() | |
{ | |
fbfd = open("/dev/fb0", O_RDWR); | |
ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo); | |
ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo); | |
printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel); | |
screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8; | |
fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0); | |
maxx = vinfo.xres-1; | |
maxy = vinfo.yres-1; | |
lo_server_thread st = lo_server_thread_new("7770", error); | |
lo_server_thread_add_method(st, "/quit", "", quit_handler, NULL); | |
lo_server_thread_add_method(st, "/line", "iiiiiii", line_handler, NULL); | |
lo_server_thread_add_method(st, "/circle", "iiiiii", circle_handler, NULL); | |
lo_server_thread_add_method(st, "/box", "iiiiiii", box_handler, NULL); | |
lo_server_thread_start(st); | |
while (!done) { usleep(1000); } | |
lo_server_thread_free(st); | |
munmap(fbp, screensize); | |
return 0; | |
} | |
void error(int num, const char *msg, const char *path) | |
{ | |
printf("liblo server error %d in path %s: %s\n", num, path, msg); | |
fflush(stdout); | |
} | |
void circle(int x, int y, int radius, uint16_t color) | |
{ | |
uint16_t theta = 1; | |
while (theta < 360) | |
{ | |
int curx = (int) x + radius*(cos(theta)); | |
int cury = (int) y + radius*(sin(theta)); | |
setPixel( curx, cury, color); | |
theta += 1; | |
} | |
} | |
void line(int x0, int y0, int x1, int y1, uint16_t color ) | |
{ | |
int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1; | |
int dy = abs(y1-y0), sy = y0<y1 ? 1 : -1; | |
int err = (dx>dy ? dx : -dy)/2, e2; | |
for(;;){ | |
setPixel(x0,y0,color); | |
if (x0==x1 && y0==y1) break; | |
e2 = err; | |
if (e2 >-dx) { err -= dy; x0 += sx; } | |
if (e2 < dy) { err += dx; y0 += sy; } | |
} | |
} | |
int min(int num1, int num2) { return (num1 > num2 ) ? num2 : num1; } | |
int line_handler(const char *path, const char *types, lo_arg ** argv, | |
int argc, void *data, void *user_data) | |
{ | |
int xstart = min(argv[0]->i, maxx); | |
int ystart = min(argv[1]->i, maxy); | |
int xend = min(argv[2]->i, maxx); | |
int yend = min(argv[3]->i, maxy); | |
uint8_t red = (uint8_t) min(argv[4]->i, 0xFF); //0 through 31 | |
uint8_t green = (uint8_t) min(argv[5]->i, 0xFF); //0 through 63 | |
uint8_t blue = (uint8_t) min(argv[6]->i, 0xFF); //0 through 31 | |
uint16_t color = ((red << 11) & 0xF800 ) | ((green << 6) & 0x07E0) | (blue & 0x1F); | |
line(xstart, ystart, xend, yend, color); | |
return 0; | |
} | |
int circle_handler(const char *path, const char *types, lo_arg ** argv, | |
int argc, void *data, void *user_data) | |
{ | |
int x = min(argv[0]->i, maxx); | |
int y = min(argv[1]->i, maxy); | |
int radius = argv[2]->i; | |
uint8_t red = (uint8_t) min(argv[3]->i, 0xFF); //0 through 31 | |
uint8_t green = (uint8_t) min(argv[4]->i, 0xFF); //0 through 63 | |
uint8_t blue = (uint8_t) min(argv[5]->i, 0xFF); //0 through 31 | |
uint16_t color = ((red << 11) & 0xF800 ) | ((green << 6) & 0x07E0) | (blue & 0x1F); | |
circle(x, y, radius, color); | |
return 0; | |
} | |
int box_handler(const char *path, const char *types, lo_arg ** argv, | |
int argc, void *data, void *user_data) | |
{ | |
int x = min(argv[0]->i, maxx); | |
int y = min(argv[1]->i, maxy); | |
int width = min(argv[2]->i, maxx); | |
int height = min(argv[3]->i, maxy); | |
uint8_t red = (uint8_t) min(argv[4]->i, 0xFF); //0 through 31 | |
uint8_t green = (uint8_t) min(argv[5]->i, 0xFF); //0 through 63 | |
uint8_t blue = (uint8_t) min(argv[6]->i, 0xFF); //0 through 31 | |
uint16_t color = ((red << 11) & 0xF800 ) | ((green << 6) & 0x07E0) | (blue & 0x1F); | |
line(x,y, min(x+width, maxx), y, color); | |
line(x,y,x, min(y+height, maxy), color); | |
line(min(x+width, maxx), y, min(x+width, maxx), min(y+height, maxy), color); | |
line(x,min(y+height, maxy), min(x+width, maxx), min(y+height, maxy), color); | |
} | |
int quit_handler(const char *path, const char *types, lo_arg ** argv, | |
int argc, void *data, void *user_data) | |
{ | |
done = 1; | |
printf("quiting\n\n"); | |
fflush(stdout); | |
return 0; | |
} | |
// gcc osc_fb.c -o f -llo -lm | |
/* | |
oscsend 127.0.0.1 7770 /line iiiiiii 0 0 319 240 31 15 0 | |
oscsend 127.0.0.1 7770 /circle iiiiii 160 120 80 31 15 31 | |
oscsend 127.0.0.1 7770 /box iiiiiii 80 80 40 20 31 15 31 | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment