/*
cl watch.c
*/
#include <time.h>
typedef enum {
black, dblue, dgreen, dcyan, dred, dmagenta, dyellow, gray,
dgray, blue, green, cyan, red, magenta, yellow, white,
} color;
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned long ulong;
typedef struct _CHAR_INFO {
union {
ushort UnicodeChar;
uchar AsciiChar;
} Char;
ushort Attributes;
} CHAR_INFO, *PCHAR_INFO;
typedef struct _COORD {
ushort x, y;
} COORD, *PCOORD;
typedef struct _SMALL_RECT {
ushort l, t, r, b;
} SMALL_RECT, *PSMALL_RECT;
void __stdcall Sleep(ulong);
ulong __stdcall GetStdHandle(ulong);
ulong __stdcall SetConsoleTextAttribute(ulong, ulong);
ulong __stdcall SetConsoleCursorPosition(ulong, ulong);
ulong __stdcall WriteConsoleOutputA(ulong,
PCHAR_INFO, COORD, COORD, PSMALL_RECT);
#define HEIGHT 25
#define WIDTH 80
static ulong handle = 0;
static COORD curs = {0, 0};
static ushort attr = 0;
static CHAR_INFO consb[HEIGHT * WIDTH];
static COORD conssize = {WIDTH, HEIGHT};
static COORD conspos = {0, 0};
static SMALL_RECT consarea = {0, 0, WIDTH - 1, HEIGHT - 1};
void cursor(ushort y, ushort x){
curs.y = y, curs.x = x;
}
void conattr(char bg, char fg){
SetConsoleTextAttribute(handle, attr = (bg << 4) | (fg & 0x0F));
}
void cls(int t, int b, int l, int r, char c){
int i, j;
for(j = t; j <= b; ++j){
for(i = l; i <= r; ++i){
consb[j * WIDTH + i].Char.AsciiChar = c;
consb[j * WIDTH + i].Attributes = attr;
}
}
}
void bputs(ushort y, ushort x, uchar *s){
uchar *p;
cursor(y, x);
for(p = s; *p; ++p, ++curs.x){
consb[curs.y * WIDTH + curs.x].Char.AsciiChar = *p;
consb[curs.y * WIDTH + curs.x].Attributes = attr;
}
}
#define ARTROWS 5
#define ARTCOLS 3
#define COLON_IDX 10
#define SPACE_IDX 11
#define DOT "\x81\xA1"
#define SPC "\x81\x40"
#define DOTWIDTH (sizeof(DOT) - 1)
uchar *col_str(uchar *b, int n, int r){
static ushort art[] = { 0x56d4, 0xe934, 0xe746, 0x71c6, 0x93da,
0x719e, 0xf79c, 0x925e, 0xf55e, 0x73de, 0x0820, 0x0000 };
ushort i, j, c, d;
for(i = 0, c = art[n]; i < r; ++i) c >>= ARTCOLS;
for(i = 0; i < ARTCOLS * DOTWIDTH; i += DOTWIDTH)
for(j = 0, d = (c >>= 1); j < DOTWIDTH; ++j)
b[i + j] = d & 1 ? DOT[j] : SPC[j];
b[i] = 0;
return b;
}
void display(int f, time_t *ptimer){
uchar b[ARTCOLS * DOTWIDTH + 1];
int i, s = (ARTCOLS + 1) * DOTWIDTH;
struct tm *t = localtime(ptimer);
cls(0, HEIGHT - 1, 0, WIDTH - 1, ' ');
for(i = 0; i < ARTROWS; ++i){
int r = 10 + i, c = 10;
bputs(r, c, col_str(b, t->tm_hour / 10, i));
bputs(r, c += s, col_str(b, t->tm_hour % 10, i));
bputs(r, c += s, col_str(b, f ? SPACE_IDX : COLON_IDX, i));
bputs(r, c += s, col_str(b, t->tm_min / 10, i));
bputs(r, c += s, col_str(b, t->tm_min % 10, i));
bputs(r, c += s, col_str(b, f ? SPACE_IDX : COLON_IDX, i));
bputs(r, c += s, col_str(b, t->tm_sec / 10, i));
bputs(r, c += s, col_str(b, t->tm_sec % 10, i));
}
WriteConsoleOutputA(handle, consb, conssize, conspos, &consarea);
}
int main(int ac, char **av){
time_t old = 0;
int f = 0;
handle = GetStdHandle(-11);
conattr(dblue, cyan);
while(1){
time_t timer;
Sleep(200);
time(&timer);
if(++f >= 5) f = 0;
if(f == 3) display(f, &timer);
if(timer < old + 1) continue;
old = timer, f = 0;
display(f, &timer);
}
return 0;
}