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