rootasuna

pipes

Mar 27th, 2018
1,821
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.74 KB | None | 0 0
  1. #!/usr/bin/env bash
  2. # pipes.sh: Animated pipes terminal screensaver.
  3. # https://github.com/pipeseroni/pipes.sh
  4. #
  5. # Copyright (c) 2015-2018 Pipeseroni/pipes.sh contributors
  6. # Copyright (c) 2013-2015 Yu-Jie Lin
  7. # Copyright (c) 2010 Matthew Simpson
  8. #
  9. # Permission is hereby granted, free of charge, to any person obtaining a copy
  10. # of this software and associated documentation files (the "Software"), to deal
  11. # in the Software without restriction, including without limitation the rights
  12. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. # copies of the Software, and to permit persons to whom the Software is
  14. # furnished to do so, subject to the following conditions:
  15. #
  16. # The above copyright notice and this permission notice shall be included in
  17. # all copies or substantial portions of the Software.
  18. #
  19. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  25. # SOFTWARE.
  26.  
  27.  
  28. VERSION=1.3.0
  29.  
  30. M=32768 # Bash RANDOM maximum + 1
  31. p=1 # number of pipes
  32. f=75 # frame rate
  33. s=13 # probability of straight fitting
  34. r=2000 # characters limit
  35. t=0 # iteration counter for -r character limit
  36. w=80 # terminal size
  37. h=24
  38.  
  39. # ab -> sets[][idx] = a*4 + b
  40. # 0: up, 1: right, 2: down, 3: left
  41. # 00 means going up , then going up -> ┃
  42. # 12 means going right, then going down -> ┓
  43. sets=(
  44. "┃┏ ┓┛━┓ ┗┃┛┗ ┏━"
  45. "│╭ ╮╯─╮ ╰│╯╰ ╭─"
  46. "│┌ ┐┘─┐ └│┘└ ┌─"
  47. "║╔ ╗╝═╗ ╚║╝╚ ╔═"
  48. "|+ ++-+ +|++ +-"
  49. "|/ \/-\ \|/\ /-"
  50. ".. .... .... .."
  51. ".o oo.o o.oo o."
  52. "-\ /\|/ /-\/ \|" # railway
  53. "╿┍ ┑┚╼┒ ┕╽┙┖ ┎╾" # knobby pipe
  54. )
  55.  
  56. # pipes'
  57. x=() # current position
  58. y=()
  59. l=() # current directions
  60. # 0: up, 1: right, 2: down, 3: left
  61. n=() # new directions
  62. v=() # current types
  63. c=() # current color
  64.  
  65. # selected pipes'
  66. V=() # types (indexes to sets[])
  67. C=() # colors
  68. VN=0 # number of selected types
  69. CN=0 # number of selected colors
  70.  
  71. # switches
  72. RNDSTART=0 # randomize starting position and direction
  73. BOLD=1
  74. NOCOLOR=0
  75. KEEPCT=0 # keep pipe color and type
  76.  
  77.  
  78. parse() {
  79. OPTIND=1
  80. while getopts "p:t:c:f:s:r:RBCKhv" arg; do
  81. case $arg in
  82. p) ((p = (OPTARG > 0) ? OPTARG : p));;
  83. t)
  84. if [[ "$OPTARG" = c???????????????? ]]; then
  85. V+=(${#sets[@]})
  86. sets+=("${OPTARG:1}")
  87. else
  88. ((OPTARG >= 0 && OPTARG < ${#sets[@]})) && V+=($OPTARG)
  89. fi
  90. ;;
  91. c) [[ $OPTARG =~ ^[0-7]$ ]] && C+=($OPTARG);;
  92. f) ((f = (OPTARG > 19 && OPTARG < 101) ? OPTARG : f));;
  93. s) ((s = (OPTARG > 4 && OPTARG < 16) ? OPTARG : s));;
  94. r) ((r = (OPTARG >= 0) ? OPTARG : r, 1));;
  95. R) RNDSTART=1;;
  96. B) BOLD=0;;
  97. C) NOCOLOR=1;;
  98. K) KEEPCT=1;;
  99. h) echo -e "Usage: $(basename $0) [OPTION]..."
  100. echo -e "Animated pipes terminal screensaver.\n"
  101. echo -e " -p [1-]\tnumber of pipes (D=1)."
  102. echo -e " -t [0-$((${#sets[@]} - 1))]\ttype of pipes, can be used more than once (D=0)."
  103. echo -e " -c [0-7]\tcolor of pipes, can be used more than once (D=1 2 3 4 5 6 7 0)."
  104. echo -e " -t c[16 chars]\tcustom type of pipes."
  105. echo -e " -f [20-100]\tframerate (D=75)."
  106. echo -e " -s [5-15]\tprobability of a straight fitting (D=13)."
  107. echo -e " -r LIMIT\treset after x characters, 0 if no limit (D=2000)."
  108. echo -e " -R \t\trandomize starting position and direction."
  109. echo -e " -B \t\tno bold effect."
  110. echo -e " -C \t\tno color."
  111. echo -e " -K \t\tpipes keep their color and type when hitting the screen edge."
  112. echo -e " -h\t\thelp (this screen)."
  113. echo -e " -v\t\tprint version number.\n"
  114. exit 0;;
  115. v) echo "$(basename -- "$0") $VERSION"
  116. exit 0
  117. esac
  118. done
  119.  
  120. # set default values if not by options
  121. ((${#V[@]})) || V=(0)
  122. VN=${#V[@]}
  123. ((${#C[@]})) || C=(1 2 3 4 5 6 7 0)
  124. CN=${#C[@]}
  125. }
  126.  
  127.  
  128. cleanup() {
  129. # clear out standard input
  130. read -t 0.001 && cat </dev/stdin>/dev/null
  131.  
  132. tput reset # fix for konsole, see pipeseroni/pipes.sh#43
  133. tput rmcup
  134. tput cnorm
  135. stty echo
  136. ((NOCOLOR)) && echo -ne '\e[0m'
  137. exit 0
  138. }
  139.  
  140.  
  141. resize() {
  142. w=$(tput cols) h=$(tput lines)
  143. }
  144.  
  145.  
  146. init_pipes() {
  147. # +_CP_init_pipes
  148. local i
  149.  
  150. ci=$((KEEPCT ? 0 : CN * RANDOM / M))
  151. vi=$((KEEPCT ? 0 : VN * RANDOM / M))
  152. for ((i = 0; i < p; i++)); {((
  153. n[i] = 0,
  154. l[i] = RNDSTART ? RANDOM % 4 : 0,
  155. x[i] = RNDSTART ? w * RANDOM / M : w / 2,
  156. y[i] = RNDSTART ? h * RANDOM / M : h / 2,
  157. c[i] = C[ci],
  158. v[i] = V[vi],
  159. ci = (ci + 1) % CN,
  160. vi = (vi + 1) % VN,
  161. 1
  162. ));}
  163. # -_CP_init_pipes
  164. }
  165.  
  166.  
  167. init_screen() {
  168. stty -echo
  169. tput smcup
  170. tput civis
  171. tput clear
  172. trap cleanup HUP TERM
  173.  
  174. resize
  175. trap resize SIGWINCH
  176. }
  177.  
  178.  
  179. main() {
  180. local i
  181.  
  182. parse "$@"
  183. init_screen
  184.  
  185. init_pipes
  186. # any key press exits the loop and this script
  187. trap 'break 2' INT
  188. while REPLY=; do
  189. read -t 0.0$((1000 / f)) -n 1 2>/dev/null
  190. case "$REPLY" in
  191. P) ((s = s < 15 ? s + 1 : s));;
  192. O) ((s = s > 3 ? s - 1 : s));;
  193. F) ((f = f < 100 ? f + 1 : f));;
  194. D) ((f = f > 20 ? f - 1 : f));;
  195. B) ((BOLD = (BOLD + 1) % 2));;
  196. C) ((NOCOLOR = (NOCOLOR + 1) % 2));;
  197. K) ((KEEPCT = (KEEPCT + 1) % 2));;
  198. ?) break;;
  199. esac
  200. for ((i = 0; i < p; i++)); do
  201. # New position:
  202. # l[] direction = 0: up, 1: right, 2: down, 3: left
  203. # +_CP_newpos
  204. ((l[i] % 2)) && ((x[i] += -l[i] + 2, 1)) || ((y[i] += l[i] - 1, 1))
  205. # -_CP_newpos
  206.  
  207. # Loop on edges (change color on loop):
  208. # +_CP_warp
  209. ((!KEEPCT && (x[i] >= w || x[i] < 0 || y[i] >= h || y[i] < 0))) \
  210. && ((c[i] = C[CN * RANDOM / M], v[i] = V[VN * RANDOM / M]))
  211. ((x[i] = (x[i] + w) % w,
  212. y[i] = (y[i] + h) % h, 1))
  213. # -_CP_warp
  214.  
  215. # new turning direction:
  216. # $((s - 1)) in $s, going straight, therefore n[i] == l[i];
  217. # and 1 in $s that pipe makes a right or left turn
  218. #
  219. # s * RANDOM / M - 1 == 0
  220. # n[i] == -1
  221. # => n[i] == l[i] + 1 or l[i] - 1
  222. # +_CP_newdir
  223. ((
  224. n[i] = s * RANDOM / M - 1,
  225. n[i] = n[i] >= 0 ? l[i] : l[i] + (2 * (RANDOM % 2) - 1),
  226. n[i] = (n[i] + 4) % 4,
  227. 1
  228. ))
  229. # -_CP_newdir
  230.  
  231. # Print:
  232. # +_CP_print
  233. echo -ne "\e[$((y[i] + 1));$((x[i] + 1))H\e[${BOLD}m"
  234. ((NOCOLOR)) && echo -ne "\e[0m" || echo -ne "\e[3${c[i]}m"
  235. echo -n "${sets[v[i]]:l[i]*4+n[i]:1}"
  236. # -_CP_print
  237. l[i]=${n[i]}
  238. done
  239. ((r > 0 && t * p >= r)) && tput reset && tput civis && t=0 || ((t++))
  240. done
  241.  
  242. cleanup
  243. }
  244.  
  245.  
  246. # when being sourced, $0 == bash, only invoke main when they are the same
  247. [[ "$0" != "$BASH_SOURCE" ]] || main "$@"
Advertisement
Add Comment
Please, Sign In to add comment