diff options
| author | Jonathan McCrohan <jmccrohan@gmail.com> | 2012-04-02 01:28:24 +0100 | 
|---|---|---|
| committer | Jonathan McCrohan <jmccrohan@gmail.com> | 2012-04-02 01:28:24 +0100 | 
| commit | 214a092ab59426f7ee79e3d538009f7607be1e73 (patch) | |
| tree | c4c181cf767ce498c393a44910ebfe6892e5c5a1 | |
| parent | d229f9911cb999bf6a7d37aeef4421792c40313e (diff) | |
| parent | 5a88b86b6abe3aae7f8c1e6f7545f2cc2ed260d7 (diff) | |
| download | nyancat-214a092ab59426f7ee79e3d538009f7607be1e73.tar.gz | |
Merge branch 'master' of git://github.com/klange/nyancat
| -rw-r--r-- | src/animation.h | 11 | ||||
| -rw-r--r-- | src/nyancat.c | 222 | 
2 files changed, 179 insertions, 54 deletions
| diff --git a/src/animation.h b/src/animation.h index ebcad3a..ad1aae4 100644 --- a/src/animation.h +++ b/src/animation.h @@ -1,3 +1,9 @@ +/* + * Pop Tart Cat animation frames + */ +#ifndef ANIMATION_H +#define ANIMATION_H +  char * frame0[] = {  ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,.,,,,,,,,,,,,,,,,,,,,,,,,,",  ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,.,.,,,,,,,,,,,,,,,,,,,,,,,,", @@ -805,3 +811,8 @@ char ** frames[] = {  	frame11,  	NULL  }; + +#define FRAME_WIDTH  64 +#define FRAME_HEIGHT 64 + +#endif diff --git a/src/nyancat.c b/src/nyancat.c index d22c6e3..234ff10 100644 --- a/src/nyancat.c +++ b/src/nyancat.c @@ -9,7 +9,7 @@   *                          http://github.com/Peetz0r/nyancat   *                          http://peter.haas-en-berg.nl   * - * Build tools unifed by:   Aaron Peschel + * Build tools unified by:  Aaron Peschel   *                          https://github.com/apeschel   *   * For a complete listing of contributers, please see the git commit history. @@ -90,7 +90,7 @@  char * colors[256] = {NULL};  /* - * For most modes, we ouput spaces, but for some + * For most modes, we output spaces, but for some   * we will use block characters (or even nothing)   */  char * output = "  "; @@ -101,6 +101,28 @@ char * output = "  ";  int telnet = 0;  /* + * Whether or not to show the counter + */ +int show_counter = 1; + +/* + * Number of frames to show before quitting + * or 0 to repeat forever (default) + */ +int frame_count = 0; + +/* + * Clear the screen between frames (as opposed to reseting + * the cursor position) + */ +int clear_screen = 1; + +/* + * Force-set the terminal title. + */ +int set_title = 1; + +/*   * Environment to use for setjmp/longjmp   * when breaking out of options handler   */ @@ -125,18 +147,30 @@ int digits(int val) {   * These values crop the animation, as we have a full 64x64 stored,   * but we only want to display 40x24 (double width).   */ -#define MIN_ROW 20 -#define MAX_ROW 43 -#define MIN_COL 10 -#define MAX_COL 50 +int min_row = 20; +int max_row = 43; +int min_col = 10; +int max_col = 50; + +/* + * Print escape sequences to return cursor to visible mode + * and exit the application. + */ +void finish() { +	if (clear_screen) { +		printf("\033[?25h\033[0m\033[H\033[2J"); +	} else { +		printf("\033[0m\n"); +	} +	exit(0); +}  /*   * In the standalone mode, we want to handle an interrupt signal   * (^C) so that we can restore the cursor and clear the terminal.   */  void SIGINT_handler(int sig){ -	printf("\033[?25h\033[0m\033[H\033[2J"); -	exit(0); +	finish();  }  /* @@ -244,11 +278,21 @@ void usage(char * argv[]) {  	printf(  			"Terminal Nyancat\n"  			"\n" -			"usage: %s [-h] [-t] [-i] \n" +			"usage: %s [-hitn] [-f \033[3mframes\033[0m]\n"  			"\n" -			" -i --intro     \033[3mShow the introduction / about informaiton at startup.\033[0m\n" -			" -t --telnet    \033[3mTelnet mode.\033[0m\n", -			" -h --help      \033[3mShow this help message.\033[0m\n", +			" -i --intro      \033[3mShow the introduction / about information at startup.\033[0m\n" +			" -t --telnet     \033[3mTelnet mode.\033[0m\n" +			" -n --no-counter \033[3mDo not display the timer\033[0m\n" +			" -s --no-title   \033[3mDo not set the titlebar text\033[0m\n" +			" -e --no-clear   \033[3mDo not clear the display between frames\033[0m\n" +			" -f --frames     \033[3mDisplay the requested number of frames, then quit\033[0m\n" +			" -r --min-rows   \033[3mCrop the animation from the top\033[0m\n" +			" -R --max-rows   \033[3mCrop the animation from the bottom\033[0m\n" +			" -c --min-cols   \033[3mCrop the animation from the left\033[0m\n" +			" -C --max-cols   \033[3mCrop the animation from the right\033[0m\n" +			" -W --width      \033[3mCrop the animation to the given width\033[0m\n" +			" -H --height     \033[3mCrop the animation to the given height\033[0m\n" +			" -h --help       \033[3mShow this help message.\033[0m\n",  			argv[0]);  } @@ -268,21 +312,37 @@ int main(int argc, char ** argv) {  	/* Long option names */  	static struct option long_opts[] = { -		{"help",   no_argument,    0, 'h'}, -		{"telnet", no_argument,    0, 't'}, -		{"intro",  no_argument,    0, 'i'}, +		{"help",       no_argument,       0, 'h'}, +		{"telnet",     no_argument,       0, 't'}, +		{"intro",      no_argument,       0, 'i'}, +		{"no-counter", no_argument,       0, 'n'}, +		{"no-title",   no_argument,       0, 's'}, +		{"no-clear",   no_argument,       0, 'e'}, +		{"frames",     required_argument, 0, 'f'}, +		{"min-rows",   required_argument, 0, 'r'}, +		{"max-rows",   required_argument, 0, 'R'}, +		{"min-cols",   required_argument, 0, 'c'}, +		{"max-cols",   required_argument, 0, 'C'}, +		{"width",      required_argument, 0, 'W'}, +		{"height",     required_argument, 0, 'H'},  		{0,0,0,0}  	};  	/* Process arguments */  	int index, c; -	while ((c = getopt_long(argc, argv, "hit", long_opts, &index)) != -1) { +	while ((c = getopt_long(argc, argv, "eshitnf:r:R:c:C:W:H:", long_opts, &index)) != -1) {  		if (!c) {  			if (long_opts[index].flag == 0) {  				c = long_opts[index].val;  			}  		}  		switch (c) { +			case 'e': +				clear_screen = 0; +				break; +			case 's': +				set_title = 0; +				break;  			case 'i': /* Show introduction */  				show_intro = 1;  				break; @@ -293,6 +353,32 @@ int main(int argc, char ** argv) {  				usage(argv);  				exit(0);  				break; +			case 'n': +				show_counter = 0; +				break; +			case 'f': +				frame_count = atoi(optarg); +				break; +			case 'r': +				min_row = atoi(optarg); +				break; +			case 'R': +				max_row = atoi(optarg); +				break; +			case 'c': +				min_col = atoi(optarg); +				break; +			case 'C': +				max_col = atoi(optarg); +				break; +			case 'W': +				min_col = (FRAME_WIDTH - atoi(optarg)) / 2; +				max_col = (FRAME_WIDTH + atoi(optarg)) / 2; +				break; +			case 'H': +				min_row = (FRAME_HEIGHT - atoi(optarg)) / 2; +				max_row = (FRAME_HEIGHT + atoi(optarg)) / 2; +				break;  			default:  				break;  		} @@ -379,7 +465,7 @@ int main(int argc, char ** argv) {  							break;  						case DO:  						case DONT: -							/* Do / Don't Negotation */ +							/* Do / Don't Negotiation */  							opt = getchar();  							if (!telnet_options[opt]) {  								/* We default to DONT */ @@ -414,7 +500,7 @@ int main(int argc, char ** argv) {  						 * our limit; honestly, we shouldn't hit  						 * the limit, as we're only collecting characters  						 * for a terminal type or window size, but better safe than -						 * sorry (and vulernable). +						 * sorry (and vulnerable).  						 */  						sb[sb_len] = i;  						sb_len++; @@ -593,12 +679,18 @@ int main(int argc, char ** argv) {  	}  	/* Attempt to set terminal title */ -	printf("\033kNyanyanyanyanyanyanya...\033\134"); -	printf("\033]1;Nyanyanyanyanyanyanya...\007"); -	printf("\033]2;Nyanyanyanyanyanyanya...\007"); +	if (set_title) { +		printf("\033kNyanyanyanyanyanyanya...\033\134"); +		printf("\033]1;Nyanyanyanyanyanyanya...\007"); +		printf("\033]2;Nyanyanyanyanyanyanya...\007"); +	} -	/* Clear the screen */ -	printf("\033[H\033[2J\033[?25l"); +	if (clear_screen) { +		/* Clear the screen */ +		printf("\033[H\033[2J\033[?25l"); +	} else { +		printf("\033[s"); +	}  	if (show_intro) {  		/* Display the MOTD */ @@ -629,27 +721,40 @@ int main(int argc, char ** argv) {  			fflush(stdout);  			usleep(400000); -			printf("\033[H"); /* Reset cursor */ +			if (clear_screen) { +				printf("\033[H"); /* Reset cursor */ +			} else { +				printf("\033[u"); +			}  		} -		/* Clear the screen again */ -		printf("\033[H\033[2J\033[?25l"); +		if (clear_screen) { +			/* Clear the screen again */ +			printf("\033[H\033[2J\033[?25l"); +		}  	}  	/* Store the start time */  	time_t start, current;  	time(&start); -	int playing = 1; /* Animation should continue [left here for modifications] */ -	size_t i = 0;    /* Current frame # */ -	char last = 0;   /* Last color index rendered */ -	size_t y, x;     /* x/y coordinates of what we're drawing */ +	int playing = 1;    /* Animation should continue [left here for modifications] */ +	size_t i = 0;       /* Current frame # */ +	unsigned int f = 0; /* Total frames passed */ +	char last = 0;      /* Last color index rendered */ +	size_t y, x;        /* x/y coordinates of what we're drawing */  	while (playing) { +		/* Reset cursor */ +		if (clear_screen) { +			printf("\033[H"); +		} else { +			printf("\033[u"); +		}  		/* Render the frame */ -		for (y = MIN_ROW; y < MAX_ROW; ++y) { -			for (x = MIN_COL; x < MAX_COL; ++x) { +		for (y = min_row; y < max_row; ++y) { +			for (x = min_col; x < max_col; ++x) {  				if (always_escape) { -					/* Text mode (or "Always Send Color Escapse") */ +					/* Text mode (or "Always Send Color Escapes") */  					printf("%s", colors[frames[i][y][x]]);  				} else {  					if (frames[i][y][x] != last && colors[frames[i][y][x]]) { @@ -665,35 +770,44 @@ int main(int argc, char ** argv) {  			/* End of row, send newline */  			newline(1);  		} -		/* Get the current time for the "You have nyaned..." string */ -		time(¤t); -		double diff = difftime(current, start); -		/* Now count the length of the time difference so we can center */ -		int nLen = digits((int)diff); -		int width = (terminal_width - 29 - nLen) / 2; -		/* Spit out some spaces so that we're actually centered */ -		while (width > 0) { -			printf(" "); -			width--; +		if (show_counter) { +			/* Get the current time for the "You have nyaned..." string */ +			time(¤t); +			double diff = difftime(current, start); +			/* Now count the length of the time difference so we can center */ +			int nLen = digits((int)diff); +			int anim_width = terminal_width == 80 ? (max_col - min_col) * 2 : (max_col - min_col); +			/* +			 * 29 = the length of the rest of the string; +			 * XXX: Replace this was actually checking the written bytes from a +			 * call to sprintf or something +			 */ +			int width = (anim_width - 29 - nLen) / 2; +			/* Spit out some spaces so that we're actually centered */ +			while (width > 0) { +				printf(" "); +				width--; +			} +			/* You have nyaned for [n] seconds! +			 * The \033[J ensures that the rest of the line has the dark blue +			 * background, and the \033[1;37m ensures that our text is bright white. +			 * The \033[0m prevents the Apple ][ from flipping everything, but +			 * makes the whole nyancat less bright on the vt220 +			 */ +			printf("\033[1;37mYou have nyaned for %0.0f seconds!\033[J\033[0m", diff);  		} -		/* You have nyaned for [n] seconds! -		 * The \033[J ensures that the rest of the line has the dark blue -		 * background, and the \033[1;37m ensures that our text is bright white. -		 * The \033[0m prevents the Apple ][ from flipping everything, but -		 * makes the whole nyancat less bright on the vt220 -		 */ -		printf("\033[1;37mYou have nyaned for %0.0f seconds!\033[J\033[0m", diff); -		  		/* Reset the last color so that the escape sequences rewrite */  		last = 0; -		/* Update frame crount */ +		/* Update frame count */ +		++f; +		if (frame_count != 0 && f == frame_count) { +			finish(); +		}  		++i;  		if (!frames[i]) {  			/* Loop animation */  			i = 0;  		} -		/* Reset cursor */ -		printf("\033[H");  		/* Wait */  		usleep(90000);  	} | 
