docs
[mirrors/Programs.git] / c / aclox.c
1 /*
2 * Compile with:
3 * gcc -lm aclox.c -o aclox; ./aclox
4 * or
5 * CFLAGS='-lm' make aclox; ./aclox
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <math.h>
12 #include <time.h>
13
14 #include <termios.h>
15 #include <sys/ioctl.h>
16
17 //config
18 #define HOUR_NUMBERS 1
19 #define HOUR_HEXADECIMAL 1
20 #define HI_PRECISION 1
21 #define SHOW_DIGITS 1
22 #define DIGITS_HEXADECIMAL 1
23 #define MINUTE_DOTS 1
24 #define SMOOTH_MOTION 1
25 #define zoom 2
26
27 //useful macros
28 #define max(a,b) ((a)>=(b)?(a):(b))
29 #define min(a,b) ((a)<=(b)?(a):(b))
30 #define PI 3.141592654
31 #define deg2rad(a) (((a)/180)*PI)
32 //phi = angle, r = length
33 #define polar2x(phi, r) ((r) * cos(deg2rad(phi)))
34 #define polar2y(phi, r) ((r) * sin(deg2rad(phi)))
35 #define cls() printf("\033[2J")
36 #define top() printf("\033[0;0H")
37
38 int llines = -1, lcols = -1;
39 void render_clock(double h, double m, double s) {
40 //colors
41 char color_empty = ' ';
42 char color_center = '+';
43 char color_number = '#';
44 char color_dot = '.';
45 char color_h = 'H';
46 char color_m = 'm';
47 char color_s = '*';
48
49 //convert digital time to "analog" time (enables smooth motion)
50 if(SMOOTH_MOTION) {
51 m += s/(double)60;
52 h += m/(double)60;
53 }
54
55 //get size of terminal
56 int lines = 20;
57 int cols = 20;
58 /*FILE *p;
59 p = popen("stty size", "r");
60 fscanf(p, "%d %d", &lines, &cols);
61 close((int)p);*/
62 struct winsize ws;
63 if ((ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1 &&
64 ioctl(STDERR_FILENO, TIOCGWINSZ, &ws) == -1 &&
65 ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1) ||
66 ws.ws_col == 0) {
67 lines = 25;
68 cols = 80;
69 } else {
70 lines = ws.ws_row;
71 cols = ws.ws_col;
72 }
73
74 //calculate size
75 int size = 40;
76 size = min(lines,cols/zoom);
77 size = ((size%2)==0?size-1:size); //make size odd
78 //printf("%d\n", size);
79
80 //empty canvas
81 char cifernik[size*zoom][size];
82 int i, x, y;
83 double phi, r;
84 for(y=0;y<size;y++) for(x=0;x<(size*zoom);x++) cifernik[x][y] = color_empty;
85
86 //draw minute dots
87 if(MINUTE_DOTS && size > 40) for(i=1;i<=60;i++) {
88 phi = -90+(i*(360/60));
89 r = size/2;
90 x = round((r+polar2x(phi,r))*zoom);
91 y = round(r+polar2y(phi,r));
92 cifernik[x][y] = color_dot;
93 }
94
95 //draw numbers
96 for(i=1;i<=12;i++) {
97 phi = -90+(i*(360/12));
98 r = size/2;
99 x = round((r+polar2x(phi,r))*zoom);
100 y = round(r+polar2y(phi,r));
101 if(HOUR_NUMBERS) {
102 cifernik[x][y] = '0'+(i%10);
103 if(HOUR_HEXADECIMAL) {
104 sprintf(&cifernik[x][y],"%X",i);
105 } else {
106 if(i>9) cifernik[x-1][y] = '0'+(i/10);
107 }
108 } else {
109 cifernik[x][y] = color_number;
110 }
111 }
112
113 //draw minute hand
114 phi = -90+(m*(360/60));
115 for(r=0;r<(size/2);r++) {
116 x = round((size/2+polar2x(phi,r))*zoom);
117 y = round(size/2+polar2y(phi,r));
118 cifernik[x][y] = color_m;
119 }
120
121 //draw hour hand
122 phi = -90+(h*(double)(360/12));
123 for(r=0;r<(size/3);r++) {
124 x = round((size/2+polar2x(phi,r))*zoom);
125 y = round(size/2+polar2y(phi,r));
126 cifernik[x][y] = color_h;
127 }
128
129 //draw seconds hand
130 phi = -90+(s*(360/60));
131 for(r=0;r<(size/2);r++) {
132 x = round((size/2+polar2x(phi,r))*zoom);
133 y = round(size/2+polar2y(phi,r));
134 cifernik[x][y] = color_s;
135 }
136
137 //draw center dot
138 cifernik[(size/2)*zoom][size/2] = color_center;
139
140 //cls when terminal size changes
141 if(lines != llines || cols != lcols) {
142 cls();
143 llines=lines;
144 lcols=cols;
145 }
146
147 //print to terminal
148 for(y=0;y<size;y++) {
149 for(r=0;r<=((cols-(size*zoom))/2);r++) putchar(' ');
150 for(x=0;x<((size*zoom)-(zoom-1));x++) {
151 putchar(cifernik[x][y]);
152 }
153 if(y!=(size-1)) putchar('\n');
154 }
155 }
156
157 int main(void) {
158 int s = -1;
159 time_t cast;
160 struct tm *cas;
161
162 while(1) {
163 cast = time(NULL);
164 cas = localtime(&cast);
165
166 if(cas->tm_sec != s){
167 s = cas->tm_sec;
168 top();
169 render_clock(cas->tm_hour,cas->tm_min,cas->tm_sec); //analog
170 if(SHOW_DIGITS || DIGITS_HEXADECIMAL) putchar('\r');
171 if(SHOW_DIGITS) printf("DEC:[%.2d:%.2d:%.2d]",cas->tm_hour,cas->tm_min,cas->tm_sec); //digital
172 if(SHOW_DIGITS || DIGITS_HEXADECIMAL) putchar(' ');
173 if(DIGITS_HEXADECIMAL) printf("HEX:[%.2x:%.2x:%.2x]",cas->tm_hour,cas->tm_min,cas->tm_sec); //digital hexadec
174 }
175 if(HI_PRECISION) { usleep(100000); }
176 else { sleep(1); }
177 }
178 }
This page took 0.361364 seconds and 4 git commands to generate.