]> git.bzium.org/ - embe/choinka.git/blob - choinka.c
c02dc72d5069fd15b88f3c13820c736796ea0c08
[embe/choinka.git] / choinka.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <term.h>
4 #include <time.h>
5
6 #define A_POGRUBIONY (1 << 0)
7
8 #define KOLOR_CZARNY 0
9 #define KOLOR_CZERWONY 1
10 #define KOLOR_ZIELONY 2
11 #define KOLOR_BRAZOWY 3
12 #define KOLOR_NIEBIESKI 4
13 #define KOLOR_MAGENTA 5
14 #define KOLOR_CYJAN 6
15 #define KOLOR_BIALY 7
16
17 typedef struct {
18   int attr;
19   int kolor;
20 } atrybut;
21
22 static atrybut const bombki[] = {
23   {A_POGRUBIONY, KOLOR_CZERWONY},
24   {A_POGRUBIONY, KOLOR_NIEBIESKI},
25   {A_POGRUBIONY, KOLOR_BRAZOWY},
26   {A_POGRUBIONY, KOLOR_MAGENTA},
27   {A_POGRUBIONY, KOLOR_CYJAN},
28   {A_POGRUBIONY, KOLOR_BIALY},
29 };
30 static int const ile_b = sizeof bombki / sizeof *bombki;
31
32 static atrybut const choinka = {0, KOLOR_ZIELONY};
33 static atrybut const podstawa = {0, KOLOR_BRAZOWY};
34 static atrybut const podpis = {A_POGRUBIONY, KOLOR_CZERWONY};
35 static atrybut const gwiazdka = {A_POGRUBIONY, KOLOR_BRAZOWY};
36
37 static void inicjuj_rng()
38 {
39   unsigned ziarno = 0;
40   FILE* f = fopen("/dev/urandom", "rb");
41   if (f != NULL) {
42     unsigned nowe_ziarno;
43     if (fread(&nowe_ziarno, sizeof nowe_ziarno, 1, f) == 1) {
44       ziarno = nowe_ziarno;
45     }
46     fclose(f);
47   }
48   if (ziarno == 0) {
49     ziarno = time(NULL);
50   }
51   srand(ziarno);
52 }
53
54 static char const rysunek[] =
55 "           *\n"
56 "          /.\\\n"
57 "         /..'\\\n"
58 "         /'.'\\\n"
59 "        /.''.'\\\n"
60 "        /.'.'.\\\n"
61 "       /'.''.'.\\\n"
62 "  jgs  ^^^[_]^^^\n"
63 ;
64
65 static void ustaw(atrybut const* attr)
66 {
67   static atrybut ostatni = {-1, -1};
68   if (ostatni.attr == attr->attr && ostatni.kolor == attr->kolor) return;
69   ostatni = *attr;
70   putp(exit_attribute_mode);
71   if ((attr->attr & A_POGRUBIONY) != 0) {
72     putp(enter_bold_mode);
73   }
74   putp(tparm(set_a_foreground, attr->kolor));
75 }
76
77 int main()
78 {
79   inicjuj_rng();
80   setupterm(NULL, 1, NULL);
81   atrybut const* kolor = &choinka;
82   for (int i = 0; rysunek[i] != '\0'; i++) {
83     char c = rysunek[i];
84     if (c == '[') kolor = &podstawa;
85     atrybut const* akt = kolor;
86     if (c >= 'a' && c <= 'z') akt = &podpis;
87     if (c == '.') akt = &bombki[rand() % ile_b];
88     if (c == '*') akt = &gwiazdka;
89     if (c == ']') kolor = &choinka;
90     ustaw(akt);
91     putchar(c);
92   }
93   putp(exit_attribute_mode);
94   return 0;
95 }