Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 #include <event.h>
5 #include <geometry.h>
7 typedef struct Vert{
8 Point3 world;
9 Point3 screen;
10 int color;
11 }Vert;
13 int nocubes;
14 int ncolor;
15 Quaternion q;
16 Image *image;
17 Image *bg;
18 Image *color[256];
19 Rectangle viewrect;
20 int prevsel;
22 int
23 cmp(Vert *a, Vert *b)
24 {
25 if(a->screen.z>b->screen.z)
26 return -1;
27 if(a->screen.z<b->screen.z)
28 return 1;
29 return 0;
30 }
32 /* crummy hack */
33 void
34 readcolmap(Display *d, RGB *cmap)
35 {
36 int i, rgb, r, g, b;
38 for(i=0; i<256; i++){
39 rgb = cmap2rgb(i);
40 r = rgb>>16;
41 g = (rgb>>8)&0xFF;
42 b = rgb & 0xFF;
43 cmap[i].red = r|(r<<8)|(r<<16)|(r<<24);
44 cmap[i].green = g|(g<<8)|(g<<16)|(g<<24);
45 cmap[i].blue = b|(b<<8)|(b<<16)|(b<<24);
46 }
47 }
49 void
50 colorspace(RGB *cmap, Vert *v)
51 {
52 Space *view;
53 int i;
55 for(i=0;i!=ncolor;i++){
56 v[i].world.x=(cmap[i].red>>24)/255.-.5;
57 v[i].world.y=(cmap[i].green>>24)/255.-.5;
58 v[i].world.z=(cmap[i].blue>>24)/255.-.5;
59 v[i].world.w=1.;
60 v[i].color=i;
61 }
62 view = pushmat(0);
63 viewport(view, viewrect, 1.);
64 persp(view, 30., 3., 7.);
65 look(view, (Point3){0., 0., -5., 1.}, (Point3){0., 0., 0., 1.},
66 (Point3){0., 1., 0., 1.});
67 qrot(view, q);
68 for(i=0;i!=ncolor;i++)
69 v[i].screen = xformpointd(v[i].world, 0, view);
70 popmat(view);
71 }
73 void
74 line3(Vert a, Vert b)
75 {
76 line(image, Pt(a.screen.x, a.screen.y), Pt(b.screen.x, b.screen.y), 0, 0, 0, display->white, ZP);
77 }
80 void
81 redraw(void)
82 {
83 int i, m;
84 RGB cmap[256];
85 Vert v[256];
87 readcolmap(display, cmap);
88 colorspace(cmap, v);
89 draw(image, image->r, bg, nil, Pt(0, 0));
90 m = Dx(viewrect)/2;
91 if(m > Dy(viewrect)/2)
92 m = Dy(viewrect)/2;
93 ellipse(image, addpt(viewrect.min, divpt(Pt(Dx(viewrect), Dy(viewrect)), 2)),
94 m, m, 1, display->white, ZP);
96 line3(v[0], v[0x36]);
97 line3(v[0x36], v[0x32]);
98 line3(v[0x32], v[0x3F]);
99 line3(v[0x3F], v[0]);
101 line3(v[0xF0], v[0xF3]);
102 line3(v[0xF3], v[0xFF]);
103 line3(v[0xFF], v[0xFC]);
104 line3(v[0xFC], v[0xF0]);
106 line3(v[0], v[0xF0]);
107 line3(v[0x36], v[0xF3]);
108 line3(v[0x32], v[0xFF]);
109 line3(v[0x3F], v[0xFC]);
111 qsort(v, ncolor, sizeof(Vert), (int(*)(const void*, const void*))cmp);
112 if(!nocubes)
113 for(i=0; i!=ncolor; i++)
114 draw(image, rectaddpt(Rect(-3, -3, 4, 4), Pt(v[i].screen.x, v[i].screen.y)),
115 color[v[i].color], nil, Pt(0, 0));
116 draw(screen, image->r, image, nil, image->r.min);
117 flushimage(display, 1);
120 void
121 eresized(int new)
123 int dx, dy;
125 if(new && getwindow(display, Refnone) < 0){
126 fprint(2, "colors: can't reattach to window: %r\n");
127 exits("reshaped");
129 draw(screen, screen->r, display->black, nil, ZP);
130 replclipr(screen, 0, insetrect(screen->r, 3));
131 viewrect = screen->clipr;
132 viewrect.min.y += stringsize(font, "0i").y + 5;
133 if(image)
134 freeimage(image);
135 image = allocimage(display, viewrect, screen->chan, 0, DNofill);
136 dx = viewrect.max.x-viewrect.min.x;
137 dy = viewrect.max.y-viewrect.min.y;
138 if(dx>dy){
139 viewrect.min.x=(viewrect.min.x+viewrect.max.x-dy)/2;
140 viewrect.max.x=viewrect.min.x+dy;
142 else{
143 viewrect.min.y=(viewrect.min.y+viewrect.max.y-dx)/2;
144 viewrect.max.y=viewrect.min.y+dx;
146 if(image==nil){
147 fprint(2, "can't allocate image\n");
148 exits("bad allocimage");
150 prevsel = -1;
151 redraw();
154 void main(int argc, char **argv){
155 Vert v[256];
156 RGB cmap[256];
157 char buf[100];
158 Point p;
159 Mouse m;
160 int i;
161 ulong bgcol;
163 bgcol = DNofill;
164 ARGBEGIN{
165 case 'n':
166 nocubes = 1;
167 break;
168 case 'b':
169 bgcol = DBlack;
170 break;
171 case 'w':
172 bgcol = DWhite;
173 break;
174 }ARGEND
176 initdraw(0,0,0);
177 ncolor=256;
178 for(i=0;i!=ncolor;i++)
179 color[i] = allocimage(display, Rect(0, 0, 1, 1), CMAP8, 1, cmap2rgba(i));
180 if(bgcol==DNofill){
181 bg = allocimage(display, Rect(0, 0, 2, 2), screen->chan, 1, DWhite);
182 draw(bg, Rect(0, 0, 1, 1), color[0], nil, Pt(0, 0));
183 draw(bg, Rect(1, 1, 2, 2), color[0], nil, Pt(0, 0));
184 }else
185 bg = allocimage(display, Rect(0,0,1,1), screen->chan, 1, bgcol);
187 q=(Quaternion){1.,0.,0.,0.};
188 einit(Emouse);
189 eresized(0);
191 for(;;){
192 m = emouse();
193 if(m.buttons&1)
194 qball(viewrect, &m, &q, redraw, 0);
195 else if(m.buttons & 2){
196 readcolmap(display, cmap);
197 colorspace(cmap, v);
198 qsort(v, ncolor, sizeof(Vert), (int(*)(const void*, const void*))cmp);
199 while(m.buttons){
200 for(i=ncolor-1; i!=0; i--){
201 if(ptinrect(m.xy, rectaddpt(Rect(-3, -3, 4, 4), Pt(v[i].screen.x, v[i].screen.y)))){
202 i = v[i].color;
203 if(i == prevsel)
204 break;
205 sprint(buf, "index %3d r %3ld g %3ld b %3ld",
206 i,
207 cmap[i].red>>24,
208 cmap[i].green>>24,
209 cmap[i].blue>>24);
210 p = addpt(screen->r.min, Pt(2,2));
211 draw(screen, Rpt(p, addpt(p, stringsize(font, buf))), display->black, nil, p);
212 string(screen, p, display->white, ZP, font, buf);
213 prevsel = i;
214 break;
217 m = emouse();
219 }else if(m.buttons&4){
220 do
221 m = emouse();
222 while(m.buttons);
223 exits(0);