pipes (3512B)
1 #!/usr/bin/env bash 2 # pipes.sh: Animated pipes terminal screensaver. 3 # 4 # This modified version is maintained at: 5 # 6 # https://github.com/livibetter/pipes.sh 7 8 # options: 9 # s = straight [5-15] 10 # f = rate [20-100] 11 # t = style [0-5] 12 # r = ttl 13 14 VERSION=0.1.0 15 16 M=32768 17 p=1 18 f=75 s=13 r=2000 t=0 19 w=$(tput cols) h=$(tput lines) 20 # ab -> idx = a*4 + b 21 # 0: up, 1: right, 2: down, 3: left 22 # 00 means going up , then going up -> ┃ 23 # 12 means going right, then going down -> ┓ 24 sets=( 25 "┃┏ ┓┛━┓ ┗┃┛┗ ┏━" 26 "│╭ ╮╯─╮ ╰│╯╰ ╭─" 27 "│┌ ┐┘─┐ └│┘└ ┌─" 28 "║╔ ╗╝═╗ ╚║╝╚ ╔═" 29 "|+ ++-+ +|++ +-" 30 "|/ \/-\ \|/\ /-" 31 ) 32 v=() 33 RNDSTART=0 34 NOCOLOR=0 35 36 OPTIND=1 37 while getopts "p:t:f:s:r:RChv" arg; do 38 case $arg in 39 p) ((p=(OPTARG>0)?OPTARG:p));; 40 t) ((OPTARG>=0 && OPTARG<${#sets[@]})) && V+=($OPTARG);; 41 f) ((f=(OPTARG>19 && OPTARG<101)?OPTARG:f));; 42 s) ((s=(OPTARG>4 && OPTARG<16 )?OPTARG:s));; 43 r) ((r=(OPTARG>=0)?OPTARG:r));; 44 R) RNDSTART=1;; 45 C) NOCOLOR=1;; 46 h) echo -e "Usage: $(basename $0) [OPTION]..." 47 echo -e "Animated pipes terminal screensaver.\n" 48 echo -e " -p [1-]\tnumber of pipes (D=1)." 49 echo -e " -t [0-$((${#sets[@]} - 1))]\ttype of pipes, can be used more than once (D=0)." 50 echo -e " -f [20-100]\tframerate (D=75)." 51 echo -e " -s [5-15]\tprobability of a straight fitting (D=13)." 52 echo -e " -r LIMIT\treset after x characters, 0 if no limit (D=2000)." 53 echo -e " -R \t\trandom starting point." 54 echo -e " -C \t\tno color." 55 echo -e " -h\t\thelp (this screen)." 56 echo -e " -v\t\tprint version number.\n" 57 exit 0;; 58 v) echo "$(basename -- "$0") $VERSION" 59 exit 0 60 esac 61 done 62 63 # set default values if not by options 64 ((${#V[@]})) || V=(0) 65 66 # Attempt to workaround for Bash versions < 4, such as 3.2 on Mac: 67 # https://gist.github.com/livibetter/4689307/#comment-892368 68 # Untested--in conduction of using shebang `env bash`--should fall back to 69 # `sleep` 70 printf -v SLEEP "read -t0.0$((1000/f)) -n 1" 71 if $SLEEP &>/dev/null; (($? != 142)); then 72 printf -v SLEEP "sleep 0.0$((1000/f))" 73 fi 74 75 cleanup() { 76 # clear up standard input 77 read -t 0 && cat </dev/stdin>/dev/null 78 79 tput rmcup 80 tput cnorm 81 stty echo 82 exit 0 83 } 84 trap cleanup SIGHUP SIGINT SIGTERM 85 86 for (( i=1; i<=p; i++ )); do 87 c[i]=$((i%8)) n[i]=0 l[i]=0 88 ((x[i]=RNDSTART==1?RANDOM*w/32768:w/2)) 89 ((y[i]=RNDSTART==1?RANDOM*h/32768:h/2)) 90 v[i]=${V[${#V[@]} * RANDOM / M]} 91 done 92 93 stty -echo 94 tput smcup 95 tput reset 96 tput civis 97 # any key press exits the loop and this script 98 while $SLEEP; (($? > 128)) || [[ $SLEEP = sleep* ]] && (($? == 0)); do 99 for (( i=1; i<=p; i++ )); do 100 # New position: 101 ((${l[i]}%2)) && ((x[i]+=-${l[i]}+2,1)) || ((y[i]+=${l[i]}-1)) 102 103 # Loop on edges (change color on loop): 104 ((${x[i]}>w||${x[i]}<0||${y[i]}>h||${y[i]}<0)) && ((c[i]=RANDOM%8, v[i]=V[${#V[@]}*RANDOM/M])) 105 ((x[i]=(x[i]+w)%w)) 106 ((y[i]=(y[i]+h)%h)) 107 108 # New random direction: 109 ((n[i]=RANDOM%s-1)) 110 ((n[i]=(${n[i]}>1||${n[i]}==0)?${l[i]}:${l[i]}+${n[i]})) 111 ((n[i]=(${n[i]}<0)?3:${n[i]}%4)) 112 113 # Print: 114 tput cup ${y[i]} ${x[i]} 115 [[ $NOCOLOR == 0 ]] && echo -ne "\033[1;3${c[i]}m" 116 echo -n "${sets[v[i]]:l[i]*4+n[i]:1}" 117 l[i]=${n[i]} 118 done 119 ((r>0 && t*p>=r)) && tput reset && tput civis && t=0 || ((t++)) 120 done 121 122 cleanup