From cc232721ad21e4f714467c56dfe064207e77db61 Mon Sep 17 00:00:00 2001 From: david Date: Mon, 5 Oct 2026 23:08:45 -0300 Subject: rewrote basic functionality to C. there are no colors just yet --- src/main.c | 357 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 357 insertions(+) create mode 100644 src/main.c (limited to 'src/main.c') diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..adbd1d3 --- /dev/null +++ b/src/main.c @@ -0,0 +1,357 @@ +#include "../defs/all.h" +#include "../defs/mikuart.h" +#include +#include + +#define VERSION "0.1.0" +//proud.release.patch + +char **getmikuart(int style){ + if(style < 0) + style = rand() % migucount; + return mikuart[style]; +} + +struct win { + int winwidth; + int winheight; +}; + +static struct win term = {80, 24}; //if the function fails this is the defualt + +#ifdef _WIN32 + #include + //i have no way to test this because i don't have any windows pc in my house qwq + //(i asked claude to write this for windows because i never looked at the windows api in my life) + static void getterminalsize(void) { + SetConsoleOutputCP(CP_UTF8); + CONSOLE_SCREEN_BUFFER_INFO csbi; + if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) { + term.winwidth = csbi.srWindow.Right - csbi.srWindow.Left + 1; + term.winheight = csbi.srWindow.Bottom - csbi.srWindow.Top + 1; + } + } +#else //or this if they're not on windows which should be posixish like linux or macos + #include + #include + + static void getterminalsize(void) { + struct winsize ws; + if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == 0) { + if(ws.ws_col > 0) + term.winwidth = ws.ws_col; + if(ws.ws_row > 0) + term.winheight = ws.ws_row; + } + } +#endif + +#define TERMINALWIDTH term.winwidth +#define TERMINALHEIGHT term.winheight + +static int count; + +static void freelines(char **lines){ + if(!lines) return; + for(int i = 0; lines[i] != NULL; i++) + free(lines[i]); + free(lines); +} + +char **wraptext(const char *text, int max, int *count){ + char *copy = strdup(text); + char *current_line = calloc(strlen(text)+1, sizeof(char)); + char **lines = NULL; + *count = 0; + + char *tok = strtok(copy, " \t\n"); + while(tok != NULL){ + if(strlen(current_line)+strlen(tok) < (size_t)max){ + if(current_line[0] != '\0'){ + strcat(current_line, " "); + } + strcat(current_line, tok); + } else{ + if(current_line[0] != '\0'){ + lines = realloc(lines, (*count + 2) * sizeof(char *)); + lines[*count] = strdup(current_line); + (*count)++; + lines[*count] = NULL; + } + strcpy(current_line, tok); + } + tok = strtok(NULL, " \t\n"); + } + + if(current_line[0] != '\0'){ + lines = realloc(lines, (*count + 2) * sizeof(char *)); + lines[*count] = strdup(current_line); + (*count)++; + lines[*count] = NULL; + } + + free(copy); + free(current_line); + return lines; +} + +#define MAX_BUBBLE_WIDTH 50 +#define MIN_BUBBLE_WIDTH 20 +char **getbubblelines(char *text){ + char **templines = wraptext(text, MAX_BUBBLE_WIDTH - 4, &count); + if(templines == NULL) + return NULL; + + size_t content_width = 0; + for (int i = 0; templines[i] != NULL; i++) { + size_t current_len = strlen(templines[i]); + if (current_len > content_width) + content_width = current_len; + } + freelines(templines); + + int bubble_width = content_width + 4; + if(bubble_width < MIN_BUBBLE_WIDTH) bubble_width = MIN_BUBBLE_WIDTH; + if(bubble_width > MAX_BUBBLE_WIDTH) bubble_width = MAX_BUBBLE_WIDTH; + + char **lines = wraptext(text, bubble_width - 4, &count); + + const char *top_left = "╭"; + const char *top_right = "╮"; + const char *bottom_left = "╰"; + const char *bottom_right = "╯"; + const char *horizontal = "─"; + const char *vertical = "│"; + + char **bubblelines = calloc(count + 5, sizeof(char *)); + bubblelines[0] = malloc(strlen(top_left) + strlen(horizontal) * bubble_width + strlen(top_right) + 1); + strcpy(bubblelines[0], top_left); + for (int i = 0; i < bubble_width; i++) + strcat(bubblelines[0], horizontal); + strcat(bubblelines[0], top_right); + + for (int i = 0; lines[i] != NULL; i++) { + int line_width = strlen(lines[i]); + int padding_needed = (bubble_width - 2) - line_width; + if (padding_needed < 0) padding_needed = 0; + int left_padding = padding_needed / 2; + int right_padding = padding_needed - left_padding; + + bubblelines[i + 1] = malloc(strlen(vertical) * 2 + 2 + line_width + padding_needed + 1); + sprintf(bubblelines[i + 1], "%s %*s%s%*s %s",vertical, left_padding, "", lines[i], right_padding, "", vertical); + } + + bubblelines[count+1] = malloc(strlen(bottom_left) + strlen(horizontal) * bubble_width + strlen(bottom_right) + 1); + strcpy(bubblelines[count+1], bottom_left); + for (int i = 0; i < bubble_width; i++) + strcat(bubblelines[count+1], horizontal); + strcat(bubblelines[count+1], bottom_right); + + bubblelines[count + 2] = strdup("\\"); + bubblelines[count + 3] = strdup(" \\"); + + freelines(lines); + return bubblelines; +} + +static void print_help(void){ + printf("A \"cowsay\" clone with Hatsune Miku ASCII art and speech bubbles.\n\n" + "Usage: mikusays [OPTIONS] [TEXT]\n\n" + "Arguments:\n" + " [TEXT] Text to display in the speech bubble\n\n" + "Options:\n" + " -s, --style