use internal functions to speed up, not too effective in reading tho…
[shellsnippets/shellsnippets.git] / mksh / clock
1 #!/bin/mksh
2 # Copyright © 2009, 2013
3 #       Dominik George <nik@naturalnet.de>
4 #       Felix Falk <felix@b9d.de>
5 #
6 # Provided that these terms and disclaimer and all copyright notices
7 # are retained or reproduced in an accompanying document, permission
8 # is granted to deal in this work without restriction, including un‐
9 # limited rights to use, publicly perform, distribute, sell, modify,
10 # merge, give away, or sublicence.
11 #
12 # This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to
13 # the utmost extent permitted by applicable law, neither express nor
14 # implied; without malicious intent or gross negligence. In no event
15 # may a licensor, author or contributor be held liable for indirect,
16 # direct, other damage, loss, or other issues arising in any way out
17 # of dealing in the work, even if advised of the possibility of such
18 # damage or existence of a defect, except proven that it results out
19 # of said person’s immediate fault when using the work as intended.
20
21 # Config
22
23 CONFIG_DIGITAL=true
24
25 # Check dependencies
26 if [ ! -x $(which bc) ]; then
27         echo "bc not found, install bc!"
28         exit 1
29 fi
30
31 bc -ql |&
32
33 # Definitions
34 PI=$(echo "4*a(1)" | bc -l)
35
36 # Library
37 function cobc {
38         print -p -- "${1}"
39         read -p result
40         echo "${result}"
41 }
42
43 function deg2rad {
44         cobc "${1}/180*${PI}"
45 }
46
47 function sine {
48         cobc "s($(deg2rad ${1}))"
49 }
50
51 function cosine {
52         cobc "c($(deg2rad ${1}))"
53 }
54
55 function round {
56         local x=$1
57         local pre=${x%%.*}
58         local post=${x#*.}
59         local postone=${post:1:1}
60
61         if [ "${pre}" = "-" ]; then
62                 pre=${pre/#-\$/0}
63         fi
64
65         if [ -n ${postone} ]; then
66                 echo ${pre}
67         else
68                 echo $((pre + 1))
69         fi
70 }
71
72 function drawpoint {
73         local deg=$1
74         local percent=$2
75
76         local char=$3
77         local mirror=$4
78
79         radx=$(cobc "${RADIUSX} * ${percent} / 100")
80         rady=$(cobc "${RADIUSY} * ${percent} / 100")
81
82         xoff=$(round $(cobc "$(sine ${deg}) * ${radx}"))
83         yoff=$(round $(cobc "$(cosine ${deg}) * ${rady}"))
84
85         echo -ne "\033[$((MIDDLEY + yoff));$((MIDDLEX + xoff))H${char}"
86
87         if [ ${mirror} = true ]; then
88                 echo -ne "\033[$((MIDDLEY - yoff));$((MIDDLEX + xoff))H${char}"
89                 echo -ne "\033[$((MIDDLEY + yoff));$((MIDDLEX - xoff))H${char}"
90                 echo -ne "\033[$((MIDDLEY - yoff));$((MIDDLEX - xoff))H${char}"
91         fi
92 }
93
94 # Clear terminal
95 clear
96
97 # Determine clock size from terminal size
98 if [ ${COLUMNS} -ge $((LINES * 2)) ]; then
99         HEIGHT=$((LINES - 2))
100         WIDTH=$((HEIGHT * 2))
101 else
102         WIDTH=$((COLUMNS - 2))
103         HEIGHT=$((WIDTH / 2))
104 fi
105
106 # Determine clock position
107 TOP=$(((LINES - HEIGHT)/2))
108
109 LEFT=$(((COLUMNS - WIDTH)/2))
110 MIDDLEX=$((COLUMNS/2))
111
112 MIDDLEY=$((LINES/2))
113 RADIUSX=$((MIDDLEX - LEFT))
114
115 RADIUSY=$((MIDDLEY - TOP))
116
117 # Draw border
118 for deg in $(seq 0 1 90); do
119         if [ ${deg} -ge 0 -a ${deg} -le 5 -o ${deg} -ge 25 -a ${deg} -le 35 -o ${deg} -ge 55 -a ${deg} -le 65 -o ${deg} -ge 83 -a ${deg} -le 90 ]; then
120                 char=x
121         else
122                 char=.
123         fi
124
125         drawpoint ${deg} 100 ${char} true
126 done
127
128 # Get time
129 hour=$(date +"%H")
130 min=$(date +"%M")
131 sec=$(date +"%S")
132
133 # Hours
134 for percent in $(seq 0 1 60); do
135         deg=$((180 - (((hour * 60 + min) % 720) / 2)))
136
137         if [ ${deg} -lt 0 ]; then
138                 deg=$((360 + deg))
139         fi
140
141         drawpoint ${deg} ${percent} x false
142 done
143
144 # Minutes
145 for percent in $(seq 0 1 85); do
146         deg=$((180 - (min * 6)))
147
148         if [ ${deg} -lt 0 ]; then
149                 deg=$((360 + deg))
150         fi
151
152         drawpoint ${deg} ${percent} + false
153 done
154
155 # Seconds
156 for percent in $(seq 0 1 85); do
157         deg=$((180 - (sec * 6)))
158
159         if [ ${deg} -lt 0 ]; then
160                 deg=$((360 + deg))
161         fi
162
163         drawpoint ${deg} ${percent} . false
164 done
165
166 # Draw center
167 echo -ne "\033[${MIDDLEY};${MIDDLEX}HX"
168
169
170 # Print digital clock if requested
171 if [ ${CONFIG_DIGITAL} = true ]; then
172         echo -ne "\033[$((MIDDLEY + (HEIGHT / 4)));$((MIDDLEX - 4))H${hour}:${min}:${sec}"
173 fi
174
175 # Set cursor to bottom left corner
176 echo -ne "\033[${LINES};1HPress any key to exit"
177 read
178
179 exit 0