-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit bf21d71
Showing
4 changed files
with
536 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,236 @@ | ||
|
||
void draw_full_line ( | ||
const struct frame frame, | ||
const int y, | ||
const color write | ||
) { | ||
#ifndef RELEASE | ||
assert(in_frame(frame, y, 0)); | ||
#endif | ||
|
||
color *location = frame_pos(frame, y, 0); | ||
|
||
for (unsigned int i = 0; i < frame.cols; i++) { | ||
location[i] = write; | ||
} | ||
} | ||
|
||
void draw_full_column ( | ||
const struct frame frame, | ||
const int x, | ||
const color write | ||
) { | ||
|
||
#ifndef RELEASE | ||
assert(in_frame(frame, 0, x)); | ||
#endif | ||
|
||
color *location = frame_pos(frame, 0, x); | ||
for (unsigned int y = 0; y < frame.rows; y++) { | ||
location[y*frame.skip] = write; | ||
} | ||
} | ||
|
||
void draw_line( | ||
const struct frame frame, | ||
const int y, const int startx, | ||
const int endx, | ||
const color write | ||
) { | ||
#ifndef RELEASE | ||
assert(in_frame(frame, y, startx)); | ||
assert(in_frame(frame, y, endx)); | ||
#endif | ||
|
||
color *location = frame_pos(frame, y, 0); | ||
for (int x = startx; x < endx; x++) { | ||
location[x] = write; | ||
} | ||
} | ||
|
||
void draw_column( | ||
const struct frame frame, | ||
const int x, const int starty, | ||
const int endy, | ||
color write | ||
) { | ||
#ifndef RELEASE | ||
assert(in_frame(frame, starty, x)); | ||
assert(in_frame(frame, starty, x)); | ||
#endif | ||
|
||
color *location = frame_pos(frame, 0, x); | ||
for (int y = starty; y < endy; y++) { | ||
location[y*frame.skip] = write; | ||
} | ||
} | ||
|
||
void draw_rectangle( | ||
const struct frame frame, | ||
const int topy, const int topx, | ||
const int boty, const int botx, | ||
const color write | ||
) { | ||
#ifndef RELEASE | ||
assert(in_frame(frame, topy, topx)); | ||
assert(in_frame(frame, boty, botx)); | ||
#endif | ||
|
||
draw_line (frame, topy, topx, botx, write); | ||
draw_line (frame, boty, topx, botx, write); | ||
draw_column(frame, topx, topy, boty, write); | ||
draw_column(frame, botx, topy, boty, write); | ||
} | ||
|
||
void fill_rectangle( | ||
const struct frame frame, | ||
const int topy, const int topx, | ||
const int boty, const int botx, | ||
const color write | ||
) { | ||
#ifndef RELEASE | ||
assert(in_frame(frame, topy, topx)); | ||
assert(in_frame(frame, boty, botx)); | ||
#endif | ||
|
||
for (int y = topy; y < boty; y++ ) { | ||
draw_line (frame, y, topx, botx, write); | ||
} | ||
} | ||
|
||
static inline void _cord_draw( | ||
const struct frame frame, | ||
int y, int x, | ||
int draw_offset, const int draw_diameter, | ||
const color write | ||
) { | ||
y-=draw_offset; | ||
x-=draw_offset; | ||
#ifndef RELEASE | ||
assert(in_frame(frame, y, x)); | ||
#endif | ||
color *location = frame_pos(frame, y, x); | ||
for (int _y = 0; _y < draw_diameter; _y++) { | ||
for (int _x = 0; _x < draw_diameter; _x++) { | ||
location[_x+_y*frame.skip] = write; | ||
} | ||
} | ||
} | ||
|
||
void cord_draw( | ||
const struct frame frame, | ||
const int y, const int x, | ||
const unsigned int draw_diameter, color write | ||
) { | ||
#ifndef RELEASE | ||
assert(in_frame(frame, y, x)); | ||
#endif | ||
|
||
if (draw_diameter == 1) { | ||
*frame_pos(frame, y, x) = write; | ||
} else { | ||
_cord_draw(frame, y, x, | ||
(draw_diameter-(draw_diameter%2))/2, | ||
draw_diameter, write); | ||
} | ||
} | ||
|
||
void cord_t_draw( | ||
const struct frame frame, | ||
const cord pnt, const unsigned int draw_diameter, | ||
const color write | ||
) { | ||
cord_draw( frame, pnt.y, pnt.x, draw_diameter, write); | ||
} | ||
|
||
void polar_draw( | ||
const struct frame frame, | ||
int y, int x, | ||
const long double radius, const long double angle, | ||
const int draw_diameter, | ||
const color write | ||
) { | ||
cord diff = polar_cord(radius, angle); | ||
y+=diff.y; | ||
x+=diff.x; | ||
cord_draw(frame, y, x, draw_diameter, write); | ||
} | ||
|
||
void draw_free_line( | ||
const struct frame frame, | ||
const int starty, const int startx, | ||
const int endy, const int endx, | ||
const int p, // pixel count // 'precision' | ||
const int draw_diameter, | ||
const color write | ||
) { | ||
|
||
// iterate p times, range = [0,1] | ||
for (long double t = 0; t <= 1; t+=1/(long double)p) { | ||
cord pnt = cord_lerp(starty, startx, endy, endx, t); | ||
cord_t_draw(frame, pnt, draw_diameter, write); | ||
} | ||
} | ||
|
||
void polar_fill( | ||
const struct frame frame, | ||
const int starty, const int startx, | ||
const long double radius, const long double angle, | ||
const int draw_diameter, | ||
const color write | ||
) { | ||
cord diff = polar_cord(radius, angle); | ||
int endy = starty+diff.y; | ||
int endx = startx+diff.x; | ||
draw_free_line(frame, | ||
starty, startx, | ||
endy, endx, | ||
(int)distancel( | ||
starty, startx, | ||
endy, endx | ||
), | ||
draw_diameter, | ||
write | ||
); | ||
} | ||
|
||
void draw_circle( | ||
const struct frame frame, | ||
const int y, const int x, const int radius, | ||
const color write | ||
) { | ||
#ifndef RELEASE | ||
assert(in_frame(frame, y-radius, x-radius)); | ||
assert(in_frame(frame, y+radius, x+radius)); | ||
#endif | ||
|
||
color *location = frame_pos(frame, y, x); | ||
const int sr = -(radius*radius); | ||
|
||
for (int _y = -radius; _y <= radius; _y++) | ||
for (int _x = -radius; _x <= radius; _x++) | ||
if ( abs(_y*_y + _x*_x + sr) <= radius) | ||
location[(y+_y)*frame.skip+x+_x] = write; | ||
} | ||
|
||
void fill_circle( | ||
const struct frame frame, | ||
const int y, const int x, const int radius, | ||
const color write | ||
) { | ||
#ifndef RELEASE | ||
assert(in_frame(frame, y-radius, x-radius)); | ||
assert(in_frame(frame, y+radius, x+radius)); | ||
#endif | ||
|
||
color *location = frame_pos(frame, y, x); | ||
const int radsqr = radius*radius; | ||
|
||
for (int _y = -radius; _y <= radius; _y++) | ||
for (int _x = -radius; _x <= radius; _x++) | ||
if ( _y*_y + _x*_x -radsqr <= radius) | ||
location[(y+_y)*frame.skip+x+_x] = write; | ||
} | ||
|
||
|
||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
|
||
#include <stdint.h> | ||
#include <stdbool.h> | ||
#include <errno.h> | ||
#include <assert.h> | ||
#include <unistd.h> | ||
#include <stdlib.h> | ||
#include <stdio.h> | ||
#include <sys/ioctl.h> | ||
#include <sys/mman.h> | ||
#include <termios.h> | ||
#include <sys/types.h> | ||
#include <sys/stat.h> | ||
#include <fcntl.h> | ||
#include <linux/fb.h> | ||
|
||
typedef struct { | ||
uint32_t y, x; | ||
} cord; | ||
typedef struct { | ||
long double y, x; | ||
} cordl; | ||
#define decord(point) (point.y, point.x) | ||
|
||
typedef struct { | ||
// radius, angle | ||
long double r, a; | ||
} polar; | ||
#define depolar(plr) (plr.r, plr.a) | ||
|
||
// ARGB | ||
typedef uint32_t color; | ||
#define COL(R, G, B) (color)( (R<<16) + (G<<8) + B ) | ||
|
||
|
||
struct frame { | ||
color* fbmem; | ||
unsigned int bpp; // bytes per pixel // should be 4 | ||
unsigned int xoff, yoff; // x, y offset | ||
unsigned int skip; // @+skip = from y to y+1 (in bytes) | ||
unsigned int rows, cols; // row,col count | ||
unsigned long int screensize; // | ||
int fd; | ||
char* tty; | ||
}; | ||
|
||
struct frame InitFb() { | ||
int fbfd = 0; | ||
color *fbp = 0; | ||
long int screensize = 0; | ||
struct fb_var_screeninfo vinfo; | ||
struct fb_fix_screeninfo finfo; | ||
// Open the file for reading and writing | ||
fbfd = open("/dev/fb0", O_RDWR); | ||
if (fbfd == -1) { | ||
perror("InitFb: cannot open framebuffer device"); | ||
exit(1); | ||
} | ||
//printf("The framebuffer device was opened successfully.\n"); | ||
// read fixed screen information | ||
if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) == -1) { | ||
perror("InitFb: can't read fixed information"); | ||
exit(2); | ||
} | ||
// variable screen information | ||
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) == -1) { | ||
perror("InitFb: can't read variable information"); | ||
exit(3); | ||
} | ||
if (vinfo.bits_per_pixel != 8*4) { | ||
fprintf(stderr, "InitFb: screen not RGBA"); | ||
exit(4); | ||
} | ||
//printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel); | ||
// Figure out the size of the screen in bytes | ||
screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8; | ||
// Map the device to memory | ||
fbp = (color *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0); | ||
if ( *(int*)fbp == -1) { | ||
perror("InitFb: failed to map framebuffer device to memory"); | ||
exit(5); | ||
} | ||
|
||
struct frame jar = { | ||
.fd = fbfd, | ||
.fbmem = fbp, | ||
.bpp = vinfo.bits_per_pixel/8, | ||
.xoff = vinfo.xoffset*vinfo.bits_per_pixel/8, | ||
.yoff = vinfo.yoffset*vinfo.bits_per_pixel/8, | ||
.skip = finfo.line_length/(vinfo.bits_per_pixel/8),// from y to y+1 | ||
.screensize = screensize, | ||
.rows = (screensize / finfo.line_length), | ||
.cols = finfo.line_length/(vinfo.bits_per_pixel/8)-10, | ||
.tty = ttyname(STDIN_FILENO), | ||
}; | ||
return jar; | ||
} | ||
|
||
#include "maths.h" | ||
#include "draw.h" | ||
|
Oops, something went wrong.