Aktualni
[mirrors/Programs.git] / c / aclox.c
... / ...
CommitLineData
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
38int llines = -1, lcols = -1;
39void 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
157int 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.285587 seconds and 4 git commands to generate.