#include "cbrll.h" /* this library stores the screen in a variable referred to in functions as map * it takes the form of a 2 dimensional array of uint8_t * takes char storing the on/off positions of 8 points, in braille encoding * order, and prints the corresponding braille char * maps maximum size is 200x200 pixels, which works out to a 50 by 100 array */ void printbraille(uint8_t points) { /* outputs braille characters, the encoding for braile is: * 1 4 * 2 5 * 3 6 * 7 8 * with the block being in U+2800 to U+28FF * in utf8 that's encoded * 1110xxxx 10xxxxxx 10xxxxxx * [1110](0010) [10](1000)87 [10]654321 */ printf("%c%c%c", 0b11100010, 0b10100000 | (points >> 6), 0b10000000 | (points & 0b00111111)); } /* prints the map, clears output before aswell*/ /*prints x1 to x2, y1 to y2 bytes of the map*/ void printmap( uint8_t x1, uint8_t x2, uint8_t y1, uint8_t y2 ) { uint8_t xi = x1; uint8_t yi = y1; /*terminal escape code to move the cursor to beginning of screen or 1,1*/ printf("\033[1;1H"); while (yi < y2) { xi = 0; while (xi < x2) { printbraille(map[xi][yi]); xi++; } printf("\n"); yi++; } } /* sets a pixel in the map, converts x,y coordinates to braille order * if set is 0, then set it to 0 * if 1, set to 1 * if > 1, flip * does not throw errors */ void setpixel(uint8_t x, uint8_t y,uint8_t set) { /* anchor x and y coordinates, eg the index in map*/ uint8_t ax; uint8_t ay; /*bitmask in braille order of the byte in mask*/ uint8_t shift = 0x01; /* check if out of bounds, since the arguments are unsigned, don't have * to check below 0, doesn't throw errors */ if ( (x >= 200 ) || (y >= 200) ) { return; } /* integer division rounds down, therefore dividing will always get the * index */ ax = x/2; ay = y/4; /* * maps to braille order based off of x and y offsets * 1 4 * 2 5 * 3 6 * 7 8 */ switch(x % 2) { case 0: switch (y % 4) { case 0: shift = shift << 0; break; case 1: shift = shift << 1; break; case 2: shift = shift << 2; break; case 3: shift = shift << 6; break; } break; case 1: switch (y % 4) { case 0: shift = shift << 3; break; case 1: shift = shift << 4; break; case 2: shift = shift << 5; break; case 3: shift = shift << 7; break; } break; } /* sets the bit based on set*/ switch (set) { case 0: map[ax][ay] = map[ax][ay] & (~shift); break; case 1: map[ax][ay] = map[ax][ay] | shift; break; default: map[ax][ay] = ((~map[ax][ay]) & shift) | ((~shift) & map[ax][ay]); break; } return; } /*takes two points and draws a line between them, dot specifies that every nth x * point be drawn, if dot != 1, then a dotted line is drawn */ void drawline(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t dot) { /*temporary x and y for switching x1,y1 and x2,y1 if x1>x2*/ uint8_t tv; /*number of x values to translate*/ uint8_t dx; /*number of y values to translate*/ uint8_t dy; /* for whether dy should be positive or negative, 1 pos, 0 neg*/ uint8_t dir; /*drawin index*/ uint8_t xi = 0; /*makes sure that x1 < x2, otherwise switch them arround*/ if (x1 > x2) { tv = x1; x1 = x2; x2 = tv; tv = y1; y1 = y2; y2 = tv; } dx = x2 - x1; /*find absolute * dir is used since i'm planning to port to a platform that may not * have signed ints. */ if (y1 > y2) { dir = 0; dy = y1 - y2; } else { dir = 1; dy = y2 - y1; } /* *For vertical Lines * Uses xi as a y index now */ if (x1 == x2) { while (xi <= dy) { if (dir) { setpixel(x1, y1 + xi, 1); } else { setpixel(x1, y1 - xi, 1); } xi++; } } /* * loop through x and draws y in line, dots done with modulus. */ while (xi <= (dx)) { if ((xi % dot) == 0) { if (dir) { setpixel(x1 + xi, y1 + ((dy/dx * xi)), 1); } else { setpixel(x1 + xi, y1 - ((dy/dx * xi)), 1); } } xi++; } return; }