Files
ScreamIntoTheVoid/draw.c
Jannis 873ae5ae9d
Some checks failed
Build / build (push) Failing after 5s
chore: cleanup repository and add Gitea Actions build workflow
- Update .gitignore to exclude build artifacts and IDE files
- Remove tracked .idea and .vscode directories from index
- Add .gitea/workflows/build.yaml for CI
- Commit existing source changes and README updates
2026-06-07 17:40:03 +02:00

288 lines
7.3 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <time.h>
#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);
}