much love
[mu.git] / tools / vga_palette.c
blob9f4161ce267c0907f13e3fb8f0fa33cacae5f1c6
1 /* Visualize the standard VGA palette.
2 * Based on https://github.com/canidlogic/vgapal (MIT License) */
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <assert.h>
9 char* bar(int n) {
10 char* result = calloc(1024, 32);
11 int i;
12 strcat(result, "<div style='float:left; width:40em'>");
13 for (i = 0; i < n; ++i)
14 //? result[i] = '.';
15 strcat(result, "&#9632;"); /* black square */
16 //? for (; i < 64; ++i)
17 //? result[i] = ' ';
18 //? result[64] = '\0';
19 strcat(result, "&nbsp;</div>"); /* make sure the div occupies space */
20 return result;
23 /* convert 6-bit color to 8-bit color */
24 int levelUp(int n) {
25 assert(n < 64);
26 /* duplicate two most significant bits in two least significant bits */
27 return (n<<2) | (n>>4);
30 void addColor(int r, int g, int b) {
31 static int i = 0;
32 //? printf("%02x %02x %02x\n", r, g, b);
33 //? printf("%3d: %2d %2d %2d %s %s %s\n", i, r, g, b, bar(r), bar(g), bar(b));
34 printf("<div style='clear:both; white-space:pre; color:#%02x%02x%02x'><div style='float:left; margin-right:1em'>%03d: %02d %02d %02d</div> %s %s %s</div>\n", levelUp(r), levelUp(g), levelUp(b), i, r, g, b, bar(r), bar(g), bar(b));
35 ++i;
38 void addGrayColor(int v) {
39 addColor(v, v, v);
42 void add16Color(int lo, int melo, int mehi, int hi) {
43 int r, g, b, i, h, l;
45 for (i = 0; i < 8; i++) {
46 r = g = b = lo;
47 if (i & 4) r = mehi;
48 if (i & 2) g = (i==6)?melo:mehi; /* exception: color 6 is brown rather than dark yellow */
49 if (i & 1) b = mehi;
50 addColor(r, g, b);
53 for (i = 0; i < 8; i++) {
54 r = g = b = melo;
55 if (i & 4) r = hi;
56 if (i & 2) g = hi;
57 if (i & 1) b = hi;
58 addColor(r, g, b);
62 /* Add four colors to the palette corresponding to a "run" within an RGB cycle.
64 * start - high and low starting states for each channel at the start of the run
65 * ch - the channel to change from high to low or low to high */
66 void addRun(int start, int ch, int lo, int melo, int me, int mehi, int hi) {
67 int r, g, b, i, up;
69 /* Check parameters */
70 if (start < 0 || start > 7)
71 abort();
72 if (ch != 1 && ch != 2 && ch != 4)
73 abort();
75 /* Get the starting RGB color and add it */
76 r = lo;
77 g = lo;
78 b = lo;
79 if ((start & 4) == 4)
80 r = hi;
81 if ((start & 2) == 2)
82 g = hi;
83 if ((start & 1) == 1)
84 b = hi;
85 addColor(r, g, b);
87 /* If selected channel starts high, we're going down; otherwise we're going up */
88 up = (start & ch) != ch;
90 /* Add remaining three colors of the run */
91 switch (ch) {
92 case 4: r = up?melo:mehi; break;
93 case 2: g = up?melo:mehi; break;
94 case 1: b = up?melo:mehi; break;
96 addColor(r, g, b);
98 switch (ch) {
99 case 4: r = me; break;
100 case 2: g = me; break;
101 case 1: b = me; break;
103 addColor(r, g, b);
105 switch (ch) {
106 case 4: r = up?mehi:melo; break;
107 case 2: g = up?mehi:melo; break;
108 case 1: b = up?mehi:melo; break;
110 addColor(r, g, b);
113 /* A cycle consists of six 4-color runs, each of which transitions from
114 * one hue to another until arriving back at starting position. */
115 void addCycle(int lo, int melo, int me, int mehi, int hi) {
116 int hue = 1; /* blue */
117 addRun(hue, 4, lo, melo, me, mehi, hi);
118 hue ^= 4;
119 assert(hue == 5);
120 addRun(hue, 1, lo, melo, me, mehi, hi);
121 hue ^= 1;
122 assert(hue == 4);
123 addRun(hue, 2, lo, melo, me, mehi, hi);
124 hue ^= 2;
125 assert(hue == 6);
126 addRun(hue, 4, lo, melo, me, mehi, hi);
127 hue ^= 4;
128 assert(hue == 2);
129 addRun(hue, 1, lo, melo, me, mehi, hi);
130 hue ^= 1;
131 assert(hue == 3);
132 addRun(hue, 2, lo, melo, me, mehi, hi);
135 int main(void) {
136 int i;
138 /* 16-color palette */
139 add16Color(0, 21, 42, 63);
141 /* 16 shades of gray */
142 addGrayColor( 0);
143 addGrayColor( 5);
144 addGrayColor( 8);
145 addGrayColor(11);
146 addGrayColor(14);
147 addGrayColor(17);
148 addGrayColor(20);
149 addGrayColor(24);
150 addGrayColor(28);
151 addGrayColor(32);
152 addGrayColor(36);
153 addGrayColor(40);
154 addGrayColor(45);
155 addGrayColor(50);
156 addGrayColor(56);
157 addGrayColor(63);
159 /* Nine RGB cycles organized in three groups of three cycles,
160 * The groups represent high/medium/low value,
161 * and the cycles within the groups represent high/medium/low saturation. */
162 addCycle( 0, 16, 31, 47, 63);
163 addCycle(31, 39, 47, 55, 63);
164 addCycle(45, 49, 54, 58, 63);
166 addCycle( 0, 7, 14, 21, 28);
167 addCycle(14, 17, 21, 24, 28);
168 addCycle(20, 22, 24, 26, 28);
170 addCycle( 0, 4, 8, 12, 16);
171 addCycle( 8, 10, 12, 14, 16);
172 addCycle(11, 12, 13, 15, 16);
174 /* final eight palette entries are full black */
175 for (i = 0; i < 8; ++i)
176 addGrayColor(0);
178 return 0;