home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / D / SVGALIB / SVGALIB1.TAR / svgalib / src / vgadraw.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-08  |  5.9 KB  |  238 lines

  1. /* VGAlib version 1.2 - (c) 1993 Tommy Frandsen            */
  2. /*                                   */
  3. /* This library is free software; you can redistribute it and/or   */
  4. /* modify it without any restrictions. This library is distributed */
  5. /* in the hope that it will be useful, but without any warranty.   */
  6.  
  7. /* Multi-chipset support Copyright 1993 Harm Hanemaayer */
  8. /* partially copyrighted (C) 1993 by Hartmut Schirmer */
  9.  
  10. #include <stdio.h>
  11. #include "vga.h"
  12. #include "libvga.h"
  13.  
  14.  
  15. /* used to decompose color value into bits (for fast scanline drawing) */
  16. union bits {
  17.     struct {
  18.         unsigned char bit3;
  19.         unsigned char bit2;
  20.         unsigned char bit1;
  21.         unsigned char bit0;
  22.     } b;
  23.     unsigned int i;
  24. };
  25.  
  26. /* color decompositions */
  27. static union bits color16[16] = {{0,0,0,0},
  28.                      {0,0,0,1},
  29.                        {0,0,1,0},
  30.                      {0,0,1,1},
  31.                      {0,1,0,0},
  32.                      {0,1,0,1},
  33.                      {0,1,1,0},
  34.                      {0,1,1,1},
  35.                      {1,0,0,0},
  36.                      {1,0,0,1},
  37.                      {1,0,1,0},
  38.                      {1,0,1,1},
  39.                      {1,1,0,0},
  40.                      {1,1,0,1},
  41.                      {1,1,1,0},
  42.                      {1,1,1,1}};
  43.  
  44. /* display plane buffers (for fast scanline drawing) */
  45. /* 256 bytes -> max 2048 pixel per line (2/16 colors)*/
  46. static unsigned char plane0[256];
  47. static unsigned char plane1[256];
  48. static unsigned char plane2[256];
  49. static unsigned char plane3[256];
  50.  
  51.  
  52. int vga_drawscanline(int line, unsigned char* colors)
  53. {
  54.     if ((CI.colors == 2) || (CI.colors > 256))
  55.     return vga_drawscansegment(colors, 0, line, CI.xbytes);
  56.     else
  57.     return vga_drawscansegment(colors, 0, line, CI.xdim);
  58.  
  59.  
  60. int vga_drawscansegment(unsigned char* colors, int x, int y, int length)
  61. {
  62.     /* both length and x must divide with 8 */
  63.  
  64.     if (MODEX) goto modeX;
  65.     switch (CI.colors) {
  66.         case 16:
  67.             {
  68.                int i, j, k, first, last, page, l1, l2;
  69.                 int offset;
  70.         union bits bytes;
  71.                 unsigned char* address;
  72.  
  73.                 k = 0;
  74.                 for(i = 0; i < length; i += 8) {
  75.                     bytes.i = 0;
  76.                     first = i;
  77.                     last  = i+8;
  78.                     for(j = first; j < last; j++)
  79.                        bytes.i = (bytes.i<<1) | color16[colors[j]].i;
  80.             plane0[k]   = bytes.b.bit0;
  81.             plane1[k]   = bytes.b.bit1;
  82.             plane2[k]   = bytes.b.bit2;
  83.             plane3[k++] = bytes.b.bit3;
  84.                 }
  85.  
  86.                 offset = (y*CI.xdim + x)/8;
  87.         vga_setpage((page = offset>>16));
  88.         l1 = 0x10000 - (offset &= 0xffff);
  89.         length /= 8;
  90.         if (l1 > length) l1 = length;
  91.         l2 = length - l1; 
  92.         
  93.                 address = GM + offset;
  94.  
  95.         /* disable Set/Reset Register */
  96.             port_out(0x01, GRA_I ); 
  97.             port_out(0x00, GRA_D ); 
  98.  
  99.         /* write to all bits */
  100.             port_out(0x08, GRA_I ); 
  101.             port_out(0xFF, GRA_D );   
  102.  
  103.         /* select map mask register */
  104.             port_out(0x02, SEQ_I ); 
  105.  
  106.                 /* write plane 0 */
  107.             port_out(0x01, SEQ_D ); 
  108.             memcpy(address, plane0, l1);
  109.  
  110.                 /* write plane 1 */
  111.             port_out(0x02, SEQ_D ); 
  112.             memcpy(address, plane1, l1);
  113.  
  114.                 /* write plane 2 */
  115.             port_out(0x04, SEQ_D ); 
  116.             memcpy(address, plane2, l1);
  117.  
  118.                 /* write plane 3 */
  119.             port_out(0x08, SEQ_D ); 
  120.             memcpy(address, plane3, l1);
  121.  
  122.         if (l2 > 0) {
  123.             vga_setpage(page+1);
  124.  
  125.                     /* write plane 0 */
  126.                 port_out(0x01, SEQ_D ); 
  127.                 memcpy( GM, &plane0[l1], l2);
  128.  
  129.                     /* write plane 1 */
  130.                 port_out(0x02, SEQ_D ); 
  131.                 memcpy( GM, &plane1[l1], l2);
  132.  
  133.                     /* write plane 2 */
  134.                 port_out(0x04, SEQ_D ); 
  135.                 memcpy( GM, &plane2[l1], l2);
  136.  
  137.                     /* write plane 3 */
  138.                 port_out(0x08, SEQ_D ); 
  139.                 memcpy( GM, &plane3[l1], l2);
  140.         }
  141.  
  142.                 /* restore map mask register */
  143.             port_out(0x0F, SEQ_D ); 
  144.   
  145.         /* enable Set/Reset Register */
  146.             port_out(0x01, GRA_I );
  147.                 port_out(0x0F, GRA_D );
  148.         }
  149.             break;
  150.         case 2 :
  151.         {
  152.         /* disable Set/Reset Register */
  153.             port_out(0x01, GRA_I ); 
  154.             port_out(0x00, GRA_D );
  155.  
  156.         /* write to all bits */
  157.             port_out(0x08, GRA_I ); 
  158.             port_out(0xFF, GRA_D );   
  159.  
  160.         /* write to all planes */
  161.             port_out(0x02, SEQ_I ); 
  162.             port_out(0x0F, SEQ_D ); 
  163.  
  164.             memcpy( GM + (y*CI.xdim + x)/8, colors, length);
  165.  
  166.                 /* restore map mask register */
  167.             port_out(0x0F, SEQ_D ); 
  168.   
  169.         /* enable Set/Reset Register */
  170.             port_out(0x01, GRA_I ); 
  171.             port_out(0x0F, GRA_D );   
  172.           }
  173.             break;
  174.     case 256:
  175.             {
  176.           switch (CM) {
  177.           case G320x200x256: /* linear addressing - easy and fast */
  178.                              memcpy(GM+y*CI.xdim+x,colors,length);
  179.                      return 0;
  180.               case G320x240x256:
  181.               case G320x400x256:
  182.               case G360x480x256:
  183. modeX:
  184.                      {
  185.                        int first, last, offset, pixel, plane;
  186.  
  187.                        /* select map mask register */ 
  188.                        port_out(0x02, SEQ_I); 
  189.  
  190.                        for(plane = 0; plane < 4; plane++) {
  191.                      /* select plane */
  192.                      port_out(1 << plane, SEQ_D);   
  193.  
  194.                      pixel = plane;
  195.                      first = (y*CI.xdim + x)/4;
  196.                      last  = (y*CI.xdim + x + length)/4;
  197.                      for(offset = first; offset < last; offset++) {
  198.                        GM[offset] = colors[pixel];  
  199.                        pixel += 4;
  200.                      }
  201.                        }
  202.                      }
  203.                      return 0;
  204.           }
  205.           {
  206.         unsigned long offset;
  207.         int segment, free;
  208.  
  209.   SegmentedCopy:
  210.         offset  = y*CI.xbytes+x;
  211.         segment = offset >> 16;
  212.         free    = ((segment+1)<<16)-offset;
  213.         offset  &= 0xFFFF;
  214.  
  215.         if (free < length) {
  216.             vga_setpage(segment);
  217.             memcpy(GM + offset, colors, free);
  218.                    vga_setpage(segment + 1);
  219.             memcpy(GM, colors+free, length-free);
  220.         } else {
  221.             vga_setpage(segment);
  222.             memcpy(GM + offset, colors, length);
  223.         }
  224.           }
  225.         }  
  226.             break;
  227.         case 32768:
  228.     case 65536: x *= 2;
  229.                 goto SegmentedCopy;
  230.     case 1<<24: x*=3;
  231.                 goto SegmentedCopy;
  232.     }    
  233.  
  234.     return 0;
  235. }
  236.  
  237.