-
-
Save spencer-p/be85cea0ac865d1e1c7b to your computer and use it in GitHub Desktop.
This file contains hidden or 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
/* | |
* walloftext.c | |
* | |
* This is a hacky program to produce a paragraph of random text with | |
* parts of a quote highlighted and spaced through it. | |
* Don't judge, I didn't spend long on this. | |
* | |
* Usage: | |
* ./walloftext [file] | |
* where [file] contains the quote, with each section on a new line | |
* | |
* Spacing of the text is randomized and may not always look good. | |
* Pressing 'r' (or resizing the window) while it is running re positions everything. | |
* Pressing Escape is the only way to exit. | |
* | |
* Compiling | |
* $ cc walloftext.c -o walloftext -lncurses | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <ncurses.h> | |
#include <time.h> | |
typedef struct { | |
int position; | |
char *str; | |
int strlen; | |
} Line; | |
int linec = 0; | |
Line **lines = NULL; | |
void newline() { | |
lines = realloc(lines, (linec+1)*sizeof(Line*)); | |
lines[linec] = calloc(1, sizeof(Line)); | |
linec++; | |
} | |
void lineappend(char c) { | |
lines[linec-1]->str = realloc(lines[linec-1]->str, (lines[linec-1]->strlen+2)*sizeof(char)); | |
lines[linec-1]->str[lines[linec-1]->strlen] = c; | |
lines[linec-1]->str[lines[linec-1]->strlen+1] = '\0'; | |
lines[linec-1]->strlen++; | |
} | |
void freelines() { | |
for (int i = 0; i < linec; i++) { | |
free(lines[i]->str); | |
free(lines[i]); | |
} | |
free(lines); | |
} | |
void printline(int i) { | |
printf("%d = {position = %d, str = %s, strlen = %d}\n", i, lines[i]->position, lines[i]->str, lines[i]->strlen); | |
} | |
void drawwall() { | |
for (int i = 0; i < linec; i++) { | |
//Decides where each line will go. Maintains order. Tries to stop line wrapping. | |
do { | |
lines[i]->position = (i*LINES*COLS/linec)+rand()%(LINES*COLS/linec); | |
} while (lines[i]->position%COLS + lines[i]->strlen + 2 > COLS && lines[i]->strlen + 2 <= COLS); //Choose a new position until " str " doesn't wrap over | |
} | |
attron(A_BOLD); // Bold colors are better | |
int online = 0; //on which line (not connected to internet) | |
for (int i = 0; i < LINES*COLS; i++) { //loop through every character | |
if (online < linec && i >= lines[online]->position) { //If there is another line and we are at its position | |
attron(COLOR_PAIR(2)); //Make it blue | |
printw(" %s ", lines[online]->str); //Print string remember trailing spaces | |
i += lines[online]->strlen; //Line is more than one character need to inc count | |
online++; //next line | |
attroff(COLOR_PAIR(2)); //reset colors | |
} | |
else { | |
attron(COLOR_PAIR(1)); //make it grey | |
if (rand()%5) { // 1 in 5 chance of being a space, otherwise lowercase char | |
printw("%c", 97+rand()%26); // 97 to 97+26 is ascci for a-z | |
} | |
else { | |
printw(" "); | |
} | |
attroff(COLOR_PAIR(1)); //reset colors | |
} | |
} | |
refresh(); // !important | |
} | |
int main(int argc, char **argv) { | |
//Need a file argument | |
if (argc != 2) { | |
printf("%s [file]\n", argv[0]); | |
return 1; | |
} | |
//Open file, exit if fail | |
FILE *input = fopen(argv[1], "r"); | |
if (!input) { | |
printf("could not open %s\n", argv[1]); | |
return 2; | |
} | |
//Populate the lines variable | |
newline(); | |
//Read the file | |
int c; | |
while ((c = fgetc(input)) != EOF) { | |
switch (c) { | |
case '\n': //Newlines create new lines | |
newline(); | |
break; | |
default: //All other characters written in | |
lineappend(c); | |
break; | |
} | |
} | |
//There is always a newline before the file ends, get rid of extra line | |
linec--; | |
free(lines[linec]->str); | |
free(lines[linec]); | |
lines = realloc(lines, (linec)*sizeof(Line)); | |
fclose(input); | |
//Start ncurses | |
//Don't want weird things happening like keystrokes or visible cursors | |
initscr(); | |
noecho(); | |
curs_set(0); | |
srand((unsigned int)time(NULL)); | |
//Init the colors. 1 for filler, 2 for text | |
start_color(); | |
init_pair(1, COLOR_BLACK, COLOR_BLACK); | |
init_pair(2, COLOR_CYAN, COLOR_BLACK); | |
//Initial drawing | |
drawwall(); | |
while ((c = getch()) != 27) { // Exit when they press escape | |
switch (c) { | |
// r and the window being resized draw a new wall of text | |
case 'r': | |
case KEY_RESIZE: | |
erase(); | |
drawwall(); | |
break; | |
} | |
} | |
//Close and free | |
endwin(); | |
freelines(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
this is great