home *** CD-ROM | disk | FTP | other *** search
/ TOS Silver 2000 / TOS Silver 2000.iso / programm / GNU_C++ / LIB / CFLIB-11.LZH / src / cicon.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-04  |  6.6 KB  |  267 lines

  1. /* Farbicon-Routinen. Basieren auf denen der MyDials von Olaf Meisiek */
  2.  
  3. #include "intern.h"
  4.  
  5. static int        pal_init = FALSE;
  6. static short    farbtbl[256][32];
  7. static int        rgb_palette[256][4];
  8.  
  9. static void fill_farbtbl(int screen_planes, int handle)
  10. {
  11.     if ((screen_planes > 8) && !pal_init)
  12.     {
  13.         int    np, color, pxy[8], backup[32], rgb[3];
  14.         MFDB    screen;
  15.         MFDB    pixel = {NULL, 16, 1, 1, 0, 1, 0, 0, 0};
  16.         MFDB    stdfm = {NULL, 16, 1, 1, 1, 1, 0, 0, 0};
  17.         int    pixtbl[16] = {0, 2, 3, 6, 4, 7, 5, 8, 9, 10, 11, 14, 12, 15, 13, 16};
  18.         
  19.         for (color = 0; color < 255; color++)
  20.         {    
  21.             if (color < 16)
  22.             {
  23.                 vq_color(handle, pixtbl[color], 1, rgb_palette[color]);
  24.                 rgb_palette[color][3] = pixtbl[color];
  25.             }
  26.             else
  27.             {    vq_color(handle, color - 1, 1, rgb_palette[color]);
  28.                 rgb_palette[color][3] = color - 1;
  29.             }
  30.         }
  31.         vq_color(handle, 1, 1, rgb_palette[255]);
  32.         rgb_palette[255][3] = 1;
  33.         
  34.         vs_clip (handle, FALSE, pxy);
  35.         
  36.         memset (farbtbl, 0, sizeof (farbtbl));
  37.         memset (backup, 0, sizeof (backup));
  38.         screen.fd_addr = NULL;
  39.         stdfm.fd_nplanes = pixel.fd_nplanes = screen_planes;
  40.     
  41.         vsl_ends (handle, 0, 0);
  42.         vsl_type (handle, 1);
  43.         vsl_width (handle, 1);
  44.         memset (pxy, 0, sizeof (pxy));
  45.         
  46.         graf_mouse (M_OFF, NULL);
  47.     
  48.         pixel.fd_addr = backup;    /* Punkt retten */
  49.         vro_cpyfm (handle, S_ONLY, pxy, &screen, &pixel);
  50.     
  51.         /* Alte Farbe retten */
  52.         vq_color (handle, 15, 1, rgb);
  53.  
  54.         for (color = 0; color < 256; color++)
  55.         {
  56.             vs_color (handle, 15, rgb_palette[color]);
  57.             
  58.             vsl_color (handle, 15);
  59.             v_pline (handle, 2, pxy);
  60.             
  61.             stdfm.fd_addr = pixel.fd_addr = farbtbl[color];
  62.     
  63.             /* vro_cpyfm, weil v_get_pixel nicht mit TrueColor (24 Planes) funktioniert */
  64.             vro_cpyfm (handle, S_ONLY, pxy, &screen, &pixel);
  65.             vr_trnfm (handle, &pixel, &stdfm);
  66.             for (np = 0; np < screen_planes; np++)
  67.                 if (farbtbl[color][np])
  68.                     farbtbl[color][np] = 0xffff;
  69.         }
  70.     
  71.         /* Alte Farbe restaurieren */
  72.         vs_color (handle, 15, rgb);
  73.  
  74.         pixel.fd_addr = backup;    /* Punkt restaurieren */
  75.         vro_cpyfm (handle, S_ONLY, pxy, &pixel, &screen);
  76.     
  77.         graf_mouse (M_ON, NULL);
  78.         pal_init = TRUE;
  79.     }
  80. }
  81.  
  82. static void fix_cdata(short *col_data, long len, int old_planes, int new_planes)
  83. {
  84.     long    x, i, old_len, rest_len, mul[32], pos;
  85.     short    np, *new_data, mask, pixel, bit, color, back[32], old_col[32], maxcol = 0;
  86.     
  87.     if (old_planes == new_planes)
  88.         return;
  89.     
  90.     len >>= 1;
  91.     if (new_planes <= 8)
  92.     {
  93.         old_len  = old_planes * len;
  94.         rest_len = new_planes * len - old_len;
  95.         new_data = &col_data[old_len];
  96.         
  97.         for (x = 0; x < len; x++)
  98.         {
  99.             mask = 0xffff;
  100.     
  101.             for (i = 0; i < old_len; i += len)
  102.                 mask &= col_data[x+i];
  103.             
  104.             if (mask)
  105.                 for (i = 0; i < rest_len; i += len)
  106.                     new_data[x+i] |= mask;
  107.         }
  108.     }
  109.     else    /* TrueColor, bzw RGB-orientierte Pixelwerte */
  110.     {
  111.         if (old_planes < 8)
  112.         {
  113.             maxcol = (1 << old_planes) - 1;
  114.             memcpy(old_col, farbtbl[maxcol], new_planes * sizeof (short));
  115.             memset(farbtbl[maxcol], 0, new_planes * sizeof (short));
  116.         }
  117.  
  118.         for (i = 0; i < new_planes; i++)
  119.             mul[i] = i * len;
  120.         
  121.         for (x = 0; x < len; x++)
  122.         {
  123.             bit = 1;
  124.             for (np = 0; np < old_planes; np++)
  125.                 back[np] = col_data[mul[np] + x];
  126.             
  127.             for (pixel = 0; pixel < 16; pixel++)
  128.             {
  129.                 color = 0;
  130.                 for (np = 0; np < old_planes; np++)
  131.                 {
  132.                     color += ((back[np] & 1) << np);
  133.                     back[np] >>= 1;
  134.                 }
  135.                 
  136.                 for (np = 0; np < new_planes; np++)
  137.                 {    pos = mul[np] + x;
  138.                     col_data[pos] = (col_data[pos] & ~bit) | (farbtbl[color][np] & bit);
  139.                 }
  140.                 
  141.                 bit <<= 1;
  142.             }
  143.         }
  144.         if (old_planes < 8)
  145.             memcpy(farbtbl[maxcol], old_col, new_planes * sizeof (short));
  146.     }
  147. }
  148.  
  149. CICON *fix_cicon(CICONBLK *cicnblk, int screen_planes, int handle)
  150. {
  151.     int        best_planes, find_planes;
  152.     short        *buf1, *buf2 = NULL;
  153.     CICON     *cicn, *new_icn = NULL, *best_icn = NULL;
  154.     long        len, *next;
  155.     MFDB        s, d;
  156.  
  157.     len = cicnblk->monoblk.ib_wicon / 8 * cicnblk->monoblk.ib_hicon;
  158.  
  159.     best_planes = 1;
  160.     if (screen_planes > 8)
  161.     {
  162.         fill_farbtbl(screen_planes, handle);
  163.         find_planes = 4;
  164.     }
  165.     else
  166.         find_planes = screen_planes;
  167.  
  168.     cicn = cicnblk->mainlist;
  169.     next = (long *)&cicnblk->mainlist;
  170.     while (cicn != NULL)
  171.     {
  172.         *next = (long)cicn;
  173.         next = (long *)&cicn->next_res;
  174.  
  175.         if (cicn->num_planes >= best_planes && cicn->num_planes <= find_planes)
  176.         {
  177.             best_planes = cicn->num_planes;
  178.             best_icn = cicn;
  179.         }
  180.         cicn = cicn->next_res;
  181.     }
  182.     
  183.     if (best_icn != NULL)            /* passendes Farbicon gefunden */
  184.     {
  185.         new_icn = (CICON*)cf_malloc(sizeof(CICON), "fix_cicon", FALSE);
  186.         *new_icn = *best_icn;
  187.     
  188.         if (best_planes > 1)
  189.             new_icn->num_planes = screen_planes;
  190.         else
  191.             new_icn->num_planes = 1;
  192.     
  193.         new_icn->col_data = cf_malloc(len * screen_planes, "fix_cicon", FALSE);
  194.         new_icn->sel_data = cf_malloc(len * screen_planes, "fix_cicon", FALSE);
  195.         
  196.         if (best_planes > 1)
  197.         {    
  198.             buf1 = cf_malloc(len * screen_planes, "fix_cicon", FALSE);
  199.             memset(buf1, 0, len * screen_planes);
  200.             memcpy(buf1, best_icn->col_data, len * best_planes);
  201.         
  202.             buf2 = cf_malloc(len * screen_planes, "fix_cicon", FALSE);
  203.             memset (buf2, 0, len * screen_planes);
  204.             memcpy (buf2, best_icn->sel_data, len * best_planes);
  205.  
  206.             if (best_planes < screen_planes)
  207.             {    
  208.                 fix_cdata(buf1, len, best_planes, screen_planes);
  209.                 if (best_icn->sel_data)
  210.                     fix_cdata(buf2, len, best_planes, screen_planes);
  211.             }
  212.         
  213.             d.fd_addr = new_icn->col_data;
  214.             d.fd_w = cicnblk->monoblk.ib_wicon;
  215.             d.fd_h = cicnblk->monoblk.ib_hicon;
  216.             d.fd_wdwidth = d.fd_w >> 4;
  217.             d.fd_stand = 0;
  218.             d.fd_nplanes = screen_planes;
  219.         
  220.             s.fd_addr = buf1;
  221.             s.fd_w = d.fd_w;
  222.             s.fd_h = d.fd_h;
  223.             s.fd_wdwidth = d.fd_wdwidth;
  224.             s.fd_stand = 1;
  225.             s.fd_nplanes = d.fd_nplanes;
  226.         
  227.             vr_trnfm (handle, &s, &d);
  228.         
  229.             s.fd_addr = buf2;
  230.             d.fd_addr = new_icn->sel_data;
  231.             vr_trnfm(handle, &s, &d);
  232.  
  233.             Mfree(buf2);
  234.             Mfree(buf1);
  235.         }
  236.         else
  237.         {
  238.             memcpy(new_icn->col_data, best_icn->col_data, len);
  239.             memcpy(new_icn->sel_data, best_icn->sel_data, len);
  240.         }
  241.     }
  242.     else
  243.     {    
  244.         /* normales Icon anpassen */
  245.         d.fd_addr = cicnblk->monoblk.ib_pmask;
  246.         d.fd_w = cicnblk->monoblk.ib_wicon;
  247.         d.fd_h = cicnblk->monoblk.ib_hicon;
  248.         d.fd_wdwidth = d.fd_w >> 4;
  249.         d.fd_stand = 0;
  250.         d.fd_nplanes = screen_planes;
  251.     
  252.         s.fd_addr = cicnblk->monoblk.ib_pmask;
  253.         s.fd_w = d.fd_w;
  254.         s.fd_h = d.fd_h;
  255.         s.fd_wdwidth = d.fd_wdwidth;
  256.         s.fd_stand = 1;
  257.         s.fd_nplanes = d.fd_nplanes;
  258.     
  259.         vr_trnfm (handle, &s, &d);
  260.     
  261.         s.fd_addr = cicnblk->monoblk.ib_pdata;
  262.         d.fd_addr = cicnblk->monoblk.ib_pdata;
  263.         vr_trnfm(handle, &s, &d);
  264.     }    
  265.     return new_icn;
  266. }
  267.