From 98afeed28dad6173f0b574898ff797fb53e270b5 Mon Sep 17 00:00:00 2001 From: fatalerrors Date: Sat, 27 Aug 2022 21:15:17 +0200 Subject: [PATCH] first implementation of rain screensaver --- profile.sh | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 124 insertions(+), 2 deletions(-) diff --git a/profile.sh b/profile.sh index 313ca87..33535be 100644 --- a/profile.sh +++ b/profile.sh @@ -974,6 +974,126 @@ showinfo() export -f showinfo +# ------------------------------------------------------------------------------ +# Let the rain fall +# ------------------------------------------------------------------------------ +rain() +{ + local EXIT_ST=0 + local RAINS=("|" "│" "┃" "┆" "┇" "┊" "┋" "╽" "╿") + local COLORS=("\e[37m" "\e[37;1m") + # More from 256 color mode + for i in {244..255}; do + COLORS=( "${COLORS[@]}" "\e[38;5;${i}m" ) + done + local NRAINS=${#RAINS[@]} + local NCOLORS=${#COLORS[@]} + local NUM_RAIN_METADATA=5 + local TERM_HEIGHT=$(tput lines) + local TERM_WIDTH=$(tput cols) + local STEP_DURATION=0.025 + local X=0 Y=0 LENTH=0 RAIN=0 MAX_RAINS=0 NEW_RAIN_ODD=0 FALLING_ODD=0 + + + sigwinch() { + TERM_WIDTH=$(tput cols) + TERM_HEIGHT=$(tput lines) + STEP_DURATION=0.025 + (( MAX_RAINS = TERM_WIDTH * TERM_HEIGHT / 4 )) + (( MAX_RAIN_LENGTH = TERM_HEIGHT < 10 ? 1 : TERM_HEIGHT / 10 )) + # In percentage + (( NEW_RAIN_ODD = TERM_HEIGHT > 50 ? 100 : TERM_HEIGHT * 2 )) + (( NEW_RAIN_ODD = NEW_RAIN_ODD * 75 / 100 )) + (( FALLING_ODD = TERM_HEIGHT > 25 ? 100 : TERM_HEIGHT * 4 )) + (( FALLING_ODD = FALLING_ODD * 90 / 100 )) + } + + do_exit() { + EXIT_ST=1 + } + + do_render() { + # Clean screen first + local idx=0 + for ((idx = 0; idx < num_rains * NUM_RAIN_METADATA; idx += NUM_RAIN_METADATA)); do + X=${rains[idx]} + Y=${rains[idx + 1]} + LENGTH=${rains[idx + 4]} + for ((y = Y; y < Y + LENGTH; y++)); do + (( y < 1 || y > TERM_HEIGHT )) && continue + echo -ne "\e[${y};${X}H " + done + done + + for ((idx = 0; idx < num_rains * NUM_RAIN_METADATA; idx += NUM_RAIN_METADATA)); do + if (( 100 * RANDOM / 32768 < FALLING_ODD )); then + # Falling + if (( ++rains[idx + 1] > TERM_HEIGHT )); then + # Out of screen, bye sweet <3 + rains=("${rains[@]:0:idx}" + "${rains[@]:idx+NUM_RAIN_METADATA:num_rains*NUM_RAIN_METADATA}") + (( num_rains-- )) + continue + fi + fi + X=${rains[idx]} + Y=${rains[idx + 1]} + RAIN=${rains[idx + 2]} + COLOR=${rains[idx + 3]} + LENGTH=${rains[idx + 4]} + for ((y = Y; y < Y + LENGTH; y++)); do + (( y < 1 || y > TERM_HEIGHT )) && continue + echo -ne "\e[${y};${X}H${COLOR}${RAIN}" + done + done + } + + trap do_exit TERM INT + trap sigwinch WINCH + # No echo stdin and hide the cursor + stty -echo + echo -ne "\e[?25l" + + echo -ne "\e[2J" + local rains=() + local num_rains=0 + sigwinch + while (( EXIT_ST <= 0 )); do + if (( $EXIT_ST <=0 )); then + read -n 1 -t $STEP_DURATION ch + case "$ch" in + q|Q) + do_exit + ;; + esac + + if (( num_rains < MAX_RAINS )) && (( 100 * RANDOM / 32768 < NEW_RAIN_ODD )); then + # Need new |, 1-based + RAIN="${RAINS[NRAINS * RANDOM / 32768]}" + COLOR="${COLORS[NCOLORS * RANDOM / 32768]}" + LENGTH=$(( MAX_RAIN_LENGTH * RANDOM / 32768 + 1 )) + X=$(( TERM_WIDTH * RANDOM / 32768 + 1 )) + Y=$(( 1 - LENGTH )) + rains=( "${rains[@]}" "$X" "$Y" "$RAIN" "$COLOR" "$LENGTH" ) + (( num_rains++ )) + fi + + # Let rain fall! + do_render + fi + done + echo -ne "\e[${TERM_HEIGHT};1H\e[0K" + + # Show cursor and echo stdin + echo -ne "\e[?25h" + stty echo + unset EXIT_ST + trap - TERM INT + trap - WINCH +} +export -f rain + + # ------------------------------------------------------------------------------ # Display list of commands and general informations # ------------------------------------------------------------------------------ @@ -987,7 +1107,8 @@ isipv4 Tell if the given IPv4 is valid isipv6 Tell if the given IPv6 is valid mcd Create a directory and go inside meteo Display curent weather forecast for the configured city -ppg Display process matching the given parameter +ppg Display process matching the given parameter +rain Let the rain fall rmhost Remove host (IP and/or DNS name) for current known_host rmspc Remove spaces from all the files in working directory setc Set console language to C @@ -1002,6 +1123,7 @@ ver Display version of your copy of profile EOF } +export -f help # ------------------------------------------------------------------------------ @@ -1075,7 +1197,7 @@ settrace () done unset status } - +export -f settrace # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------