├── .gitignore ├── README ├── asciiplay.c ├── asciirec.c └── star wars asciimation.zip /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.exe 3 | *~ 4 | asciirec 5 | asciiplay 6 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | asciirec/asciiplay - terminal recording and playback 2 | 3 | Compiling 4 | 5 | gcc -o asciirec asciirec.c 6 | gcc -o asciiplay asciiplay.c 7 | 8 | Usage 9 | 10 | output | asciirec [args] 11 | asciiplay file 12 | 13 | Args 14 | 15 | -filename - output filename 16 | -fps - how many times per second to capture input. 17 | More captures will mean smoother playback, but 18 | might be too heavy for slower machines. 19 | -maxfs - max size in bytes per frame. Set this higher 20 | if your output is spitting out a LOT of text 21 | very fast. Side effect: your terminal might 22 | not be able to output that much text for the 23 | duration of a frame. 24 | 25 | File format 26 | 27 | 4 bytes ATXT idenfitication header "ATXT" 28 | 4 bytes Revision 1, this version 29 | 4 bytes Max Frame size 32768 by default 30 | 4 bytes frame period in microseconds, 31 | rounded to the nearest 1000 1000/15 by default 32 | Frames ... 33 | 34 | Frame format 35 | 36 | 4 bytes frame size in bytes 37 | Data ... 38 | -------------------------------------------------------------------------------- /asciiplay.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | const int MAGICNUMBER = 0x54585441; //ATXT 7 | const int MAXREVISION = 1; 8 | 9 | int main(int argc, char **argv) { 10 | FILE *ifile; 11 | 12 | int maxfs; 13 | int period; 14 | 15 | if(argc > 1) { 16 | ifile = fopen(argv[1], "rb"); 17 | } else { 18 | fprintf(stderr, "ERROR: You must specify an input filename.\n"); 19 | return(-1); 20 | } 21 | 22 | int t; 23 | fread(&t, sizeof(int), 1, ifile); 24 | if(t != MAGICNUMBER) { 25 | fprintf(stderr, "ERROR: This does not appear to be a valid ATXT file. Change the first 4 bytes to contain ATXT and try again.\n"); 26 | return(-1); 27 | } else { 28 | fprintf(stderr, "ATXT file format detected.\n"); 29 | } 30 | fread(&t, sizeof(int), 1, ifile); 31 | if(t > MAXREVISION) { 32 | fprintf(stderr, "ERROR: This file appears to be from a newer version of asciirec, it will likely not play. Try changing the version in the header to &d (bytes 4 to 7).\n"); 33 | return(-1); 34 | } 35 | fread(&maxfs, sizeof(int), 1, ifile); 36 | fread(&period, sizeof(int), 1, ifile); 37 | fprintf(stderr, "Frame period is %d with a max frame size of %d.\n", period, maxfs); 38 | 39 | char* fb = (char*)malloc(maxfs * sizeof(char)); 40 | if(fb == NULL) { 41 | fprintf(stderr, "ERROR: Couldn't allocate the requested %d bytes of memory. Maybe free up some memory, and try again. Otherwise, your computer doesn't have enough RAM or the file is malformed.\n", maxfs); 42 | return(-1); 43 | } 44 | 45 | fprintf(stderr, "Starting playback...\n"); 46 | 47 | int fs; 48 | while(!feof(ifile)) { 49 | fread(&fs, sizeof(int), 1, ifile); 50 | fread(fb, sizeof(char), fs, ifile); 51 | fwrite(fb, sizeof(char), fs, stdout); 52 | usleep(period); 53 | } 54 | return(0); 55 | } 56 | -------------------------------------------------------------------------------- /asciirec.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define DEFAULTFPS (15) 8 | #define DEFAULTFILE "out.atxt" 9 | const int MAGICNUMBER = 0x54585441; //ATXT 10 | const int REVISION = 1; 11 | #define DMAXFRAMESIZE (32767) 12 | 13 | int main(int argc, char **argv) { 14 | int fps = DEFAULTFPS; 15 | int maxfs = DMAXFRAMESIZE; 16 | char *outfile = (char*)malloc((strlen(DEFAULTFILE)+1) * sizeof(char)); 17 | strcpy(outfile, DEFAULTFILE); 18 | if(argc > 2) { 19 | int i; 20 | for(i = 1; i < argc - 1; i++) { 21 | if(strcmp(argv[i], "-maxfs") == 0) { 22 | maxfs = atoi(argv[i+1]); 23 | if(maxfs < 1) maxfs = DMAXFRAMESIZE; 24 | } else if(strcmp(argv[i], "-fps") == 0) { 25 | fps = atoi(argv[i+1]); 26 | if(fps < 1) fps = DEFAULTFPS; 27 | } else if (strcmp(argv[i], "-filename") == 0) { 28 | free(outfile); 29 | outfile = (char*)malloc((strlen(argv[i+1])+1) * sizeof(char)); 30 | strcpy(outfile, argv[i+1]); 31 | } 32 | } 33 | } 34 | 35 | char* fb = (char*)malloc(maxfs * sizeof(char)); 36 | if(fb == NULL) { 37 | fprintf(stderr, "WARNING: Couldn't allocate %d bytes for buffer, trying default of %d.\n", maxfs, DMAXFRAMESIZE); 38 | fb = (char*)malloc(DMAXFRAMESIZE * sizeof(char)); 39 | maxfs = DMAXFRAMESIZE; 40 | if(fb == NULL) { 41 | fprintf(stderr, "ERROR: Couldn't allocate default buffer size, try specifying a lower size with -maxfs or freeing up some memory.\n"); 42 | return(-1); 43 | } 44 | } 45 | 46 | fprintf(stderr, "Recording to %s at %d FPS.\n", outfile, fps); 47 | FILE *o = fopen(outfile, "wb"); 48 | fwrite(&MAGICNUMBER, sizeof(int), 1, o); 49 | fwrite(&REVISION, sizeof(int), 1, o); 50 | int period = 1000/fps*1000; //To keep the value as multiple of 1000, and a sane minimum value. 51 | if(period == 0) { 52 | fprintf(stderr, "WARNING: INSANELY HIGH FPS! Capped to 1000! Performance WILL suffer.\n"); 53 | period = 1; 54 | } 55 | fwrite(&maxfs, sizeof(int), 1, o); 56 | fwrite(&period, sizeof(int), 1, o); 57 | 58 | int flags = fcntl(0, F_GETFL, 0); 59 | flags |= O_NONBLOCK; 60 | fcntl(0, F_SETFL, flags); 61 | 62 | int fs, i; 63 | while(!feof(stdin)) { 64 | fs = fread(fb, sizeof(char), maxfs, stdin); 65 | fwrite(&fs, sizeof(int), 1, o); 66 | fwrite(fb, sizeof(char), fs, o); 67 | usleep(period); 68 | } 69 | return(0); 70 | } 71 | -------------------------------------------------------------------------------- /star wars asciimation.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paulguy/asciirec/60d5a06b13e1072f80a98650180978cc39ace2b2/star wars asciimation.zip --------------------------------------------------------------------------------