#include #include #include #include /* map holding the pixels for a 200x200 pixel imagebuffer, [x][y] * bits are in braille order within each byte */ uint8_t map[100][50]; /* takes char storing the on/off positions of 8 points, in braille encoding * order, and prints the corresponding braille char */ /* global state bit switch */ uint8_t state = 3; #define STATE_LOOP 0x01 #define STATE_DEJURE 0x02 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*/ void printmap() { uint8_t xi = 0; uint8_t yi = 0; /*terminal escape code to move the cursor to beginning of screen or 1,1*/ printf("\033[1;1H"); while (yi < 50) { xi = 0; while (xi < 100) { 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; } /*node, the thing being simulated * 16 bytes each */ struct node { /*culture to compare similatiry*/ uint8_t culture; /*strength to spread culture*/ uint8_t memetic; /*strength martial*/ uint8_t martial; /*state allegiance*/ uint8_t dejure; /*x and y positions*/ uint8_t x; uint8_t y; /*connections to other nodes, 0 represents none*/ uint8_t connections[10]; }; /*all the nodes, 0 is not used*/ struct node nodes[256]; /*makes a new random node*/ struct node makenode() { /*node to work on*/ struct node rnode; rnode.culture = (uint8_t)rand(); rnode.memetic = (uint8_t)rand(); rnode.martial = (uint8_t)rand(); rnode.dejure = (uint8_t)rand(); rnode.x = (uint8_t)rand(); while (rnode.x >= 200) { rnode.x = (uint8_t)rand(); } rnode.y = (uint8_t)rand(); while (rnode.y >= 200) { rnode.y = (uint8_t)rand(); } memset(rnode.connections, 0, 10*sizeof(uint8_t)); return rnode; } /*draws nodes based on dejure or culture*/ void drawnode(struct node drawn) { /*which symbol to draw*/ uint8_t symbol; if (state & STATE_DEJURE) { symbol = drawn.dejure; } else { symbol = drawn.culture; } /* draws symbol*/ /*layout as follows * 012 * 7X3 * 654 */ setpixel(drawn.x, drawn.y, 1); setpixel(drawn.x-1, drawn.y-1, (symbol & (0x01 << 0)) && 1); setpixel(drawn.x, drawn.y-1, (symbol & (0x01 << 1)) && 1); setpixel(drawn.x+1, drawn.y-1, (symbol & (0x01 << 2)) && 1); setpixel(drawn.x+1, drawn.y, (symbol & (0x01 << 3)) && 1); setpixel(drawn.x+1, drawn.y+1, (symbol & (0x01 << 4)) && 1); setpixel(drawn.x, drawn.y+1, (symbol & (0x01 << 5)) && 1); setpixel(drawn.x-1, drawn.y+1, (symbol & (0x01 << 6)) && 1); setpixel(drawn.x-1, drawn.y, (symbol & (0x01 << 7)) && 1); /*draws memetic strenth*/ /*Ma *00123 Me *1XXX4 *2XOX5 *3XXX6 *45677 */ //a swich without breaks keeps executing switch (drawn.memetic / 32) { case 7: setpixel(drawn.x+2,drawn.y+2,1); case 6: setpixel(drawn.x+2,drawn.y+1,1); case 5: setpixel(drawn.x+2,drawn.y,1); case 4: setpixel(drawn.x+2,drawn.y-1,1); case 3: setpixel(drawn.x+2,drawn.y-2,1); case 2: setpixel(drawn.x+1,drawn.y-2,1); case 1: setpixel(drawn.x,drawn.y-2,1); case 0: setpixel(drawn.x-1,drawn.y-2,1); } //martial strenth switch (drawn.martial / 32) { case 7: setpixel(drawn.x+1,drawn.y+2,1); case 6: setpixel(drawn.x,drawn.y+2,1); case 5: setpixel(drawn.x-1,drawn.y+2,1); case 4: setpixel(drawn.x-2,drawn.y+2,1); case 3: setpixel(drawn.x-2,drawn.y+1,1); case 2: setpixel(drawn.x-2,drawn.y,1); case 1: setpixel(drawn.x-2,drawn.y-1,1); case 0: setpixel(drawn.x-2,drawn.y-2,1); } //draws connections for (uint8_t i = 0; i < 10; i++) { if (drawn.connections[i] != 0) { drawline(drawn.x, drawn.y, nodes[drawn.connections[i]].x, nodes[drawn.connections[i]].y, 1); } } } int main (int argc, char * argv[]) { /*holds keypress*/ char input; /*zeroing map*/ memset(map, 0, sizeof(map[0][0]) * 100 * 50); /*seeds random*/ srand(696969); for (int i = 0; i < 64; i++) { nodes[i] = makenode(); } while (state & STATE_LOOP) { for (int i = 1; i < 64; i++) { drawnode(nodes[i]); } drawnode(nodes[0]); printmap(); /* checks input*/ input = getc(stdin); /*haven't set the terminal to raw mode so will still need * space */ if (input == 'q') { state = state & (~STATE_LOOP); } } return 0; }