#include #include #include #include #include #include #include "draw.h" #include "main.h" void drawEdges() { for (int i = 0; i < WIDTH; i++) { printf("%c", SEPERATION_CHAR); } printf("\n"); } void drawTitle(char* title) { // put seperation_char at start and end printf("%c", SEPERATION_CHAR); // calculate amount of spaces before and after the word int title_len = strlen(title); int spacing = (WIDTH - 2 - title_len) / 2; if (spacing < 0) spacing = 0; for (int i = 0; i < spacing; i++) { printf(" "); } // Print title, but truncate if it's too long if (title_len > WIDTH - 2) { for(int i = 0; i < WIDTH - 5; i++) printf("%c", title[i]); printf("..."); } else { printf("%s", title); } // we check if either the length of the title or the width is odd. int remaining = WIDTH - 2 - spacing - (title_len > WIDTH - 2 ? WIDTH - 2 : title_len); for (int i = 0; i < remaining; i++) { printf(" "); } printf("%c\n", SEPERATION_CHAR); } void drawEmptyLines(const int amount) { for (int i = 0; i < amount; i++) { printf("%c", SEPERATION_CHAR); for (int j = 0; j < WIDTH - 2; j++) { printf(" "); } printf("%c\n", SEPERATION_CHAR); } } void getUserInput(char* output, char* displayText) { // 1. Print the prompt line printf("%c %s", SEPERATION_CHAR, displayText); int prompt_len = strlen(displayText); int padding = WIDTH - prompt_len - 3; for (int i = 0; i < padding; i++) { printf(" "); } printf("%c\n", SEPERATION_CHAR); // 2. Start the input line with fixed borders printf("%c ", SEPERATION_CHAR); for (int i = 0; i < WIDTH - 4; i++) printf(" "); printf(" %c", SEPERATION_CHAR); printf("\033[%dG", 3); // Move cursor to column 3 fflush(stdout); // 3. Set up terminal for raw input (no echo, no canonical mode) struct termios oldt, newt; tcgetattr(STDIN_FILENO, &oldt); newt = oldt; newt.c_lflag &= ~(ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &newt); int i = 0; int col = 3; // Current terminal column char ch; while (1) { if (read(STDIN_FILENO, &ch, 1) <= 0) break; if (ch == '\n' || ch == '\r') { output[i] = '\0'; // Move cursor to the end of the line and print newline printf("\033[%dG", WIDTH + 1); printf("\n"); break; } else if (ch == 127 || ch == 8) { // Backspace if (i > 0) { if (col > 3) { i--; col--; printf("\b \b"); } } } else { output[i++] = ch; printf("%c", ch); col++; if (col == WIDTH - 1) { printf("\n%c ", SEPERATION_CHAR); for (int j = 0; j < WIDTH - 4; j++) printf(" "); printf(" %c", SEPERATION_CHAR); printf("\033[%dG", 3); col = 3; } } fflush(stdout); } tcsetattr(STDIN_FILENO, TCSANOW, &oldt); } char** splitByNewLine(char *str, int *lineCount) { int maxLines = 1000; char **lines = malloc(maxLines * sizeof(char*)); int count = 0; char *token = strtok(str, "\n"); while (token != NULL) { lines[count] = token; count++; if (count >= maxLines) break; token = strtok(NULL, "\n"); } *lineCount = count; return lines; } void screamIntoVoid(char* text) { srand(time(NULL)); char* copy = strdup(text); int len = strlen(copy); for (int step = 0; step <= 20; step++) { printf("\033[H\033[J"); drawEdges(); drawEmptyLines(2); for (int i = 0; i < len; i++) { if (copy[i] != ' ' && copy[i] != '\n' && copy[i] != '.' && (rand() % 100) < (step * 7)) { copy[i] = (rand() % 2 == 0) ? '.' : ' '; } } char* temp_copy = strdup(copy); int lineCount; char** lines = splitByNewLine(temp_copy, &lineCount); if (lineCount == 0) { drawTitle(" "); } else { for(int i = 0; i < lineCount; i++) { drawTitle(lines[i]); } } free(lines); free(temp_copy); drawEmptyLines(2); drawEdges(); fflush(stdout); sleep_ms(150); } printf("\033[H\033[J"); drawEdges(); drawEmptyLines(5); drawTitle("..."); drawTitle("It's gone."); drawTitle("The void has consumed your worries."); drawEmptyLines(5); drawEdges(); fflush(stdout); sleep_ms(3000); free(copy); } void burnText(char* text) { srand(time(NULL)); char* copy = strdup(text); int len = strlen(copy); char* fire_chars = "@#%*+=-:. "; int fire_len = strlen(fire_chars); for (int step = 0; step <= 25; step++) { printf("\033[H\033[J"); drawEdges(); drawEmptyLines(2); for (int i = 0; i < len; i++) { if (copy[i] != ' ' && copy[i] != '\n') { int r = rand() % 100; if (r < (step * 10)) { int char_idx = (step / 3) + (rand() % 3); if (char_idx >= fire_len) copy[i] = ' '; else copy[i] = fire_chars[char_idx]; } } } char* temp_copy = strdup(copy); int lineCount; char** lines = splitByNewLine(temp_copy, &lineCount); if (lineCount == 0) { drawTitle(" "); } else { for(int i = 0; i < lineCount; i++) { drawTitle(lines[i]); } } free(lines); free(temp_copy); drawEmptyLines(2); drawEdges(); fflush(stdout); sleep_ms(100); } printf("\033[H\033[J"); drawEdges(); drawEmptyLines(5); drawTitle("Ashes to ashes."); drawTitle("Dust to dust."); drawEmptyLines(5); drawEdges(); fflush(stdout); sleep_ms(3000); free(copy); } void dissolveText(char* text) { srand(time(NULL)); char* copy = strdup(text); int len = strlen(copy); for (int step = 0; step <= 30; step++) { printf("\033[H\033[J"); drawEdges(); drawEmptyLines(2); for (int i = 0; i < len; i++) { if (copy[i] != ' ' && copy[i] != '\n') { if ((rand() % 100) < (step * 5)) { copy[i] = (rand() % 5 == 0) ? '~' : (rand() % 2 == 0 ? ',' : ' '); } } } char* temp_copy = strdup(copy); int lineCount; char** lines = splitByNewLine(temp_copy, &lineCount); if (lineCount == 0) { drawTitle(" "); } else { for(int i = 0; i < lineCount; i++) { drawTitle(lines[i]); } } free(lines); free(temp_copy); drawEmptyLines(2); drawEdges(); fflush(stdout); sleep_ms(100); } printf("\033[H\033[J"); drawEdges(); drawEmptyLines(5); drawTitle("Dissolved into nothingness."); drawEmptyLines(5); drawEdges(); fflush(stdout); sleep_ms(3000); free(copy); }