home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / D / SVGALIB / SVGALIB1.TAR / svgalib / gl / driver.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-22  |  24.3 KB  |  1,101 lines

  1. /* driver.c    Framebuffer primitives */
  2.  
  3.  
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <vga.h>
  7.  
  8. #include "inlstring.h"        /* include inline string operations */
  9. #include "vgagl.h"
  10. #include "def.h"
  11. #include "driver.h"
  12.  
  13.  
  14. #define MAXBYTEWIDTH 4096    /* used in bitblt emulation */
  15.  
  16. /* All functions that simply call another function with slightly different
  17.  * parameter values are declared inline. */
  18. #define INLINE inline
  19.  
  20. #define NOTIMPL(s) { notimplemented(s); return; }
  21.  
  22. /* in: vp = video offset; out: rvp = video pointer, chunksize, page */
  23. #define SETWRITEPAGED(vp, rvp, chunksize, page) \
  24.     page = vp >> 16; \
  25.     vga_setpage(page); \
  26.     rvp = (vp & 0xffff) + VBUF; \
  27.     chunksize = 0x10000 - (vp & 0xffff);
  28.  
  29.  
  30. static void notimplemented( char *s ) {
  31.     printf("vgagl: %s not implemented.\n", s);
  32. }
  33.  
  34.  
  35.  
  36. /* One byte per pixel frame buffer primitives */
  37.  
  38. #define ASSIGNVP8(x, y, vp) vp = VBUF + (y) * BYTEWIDTH + (x);
  39. #define ASSIGNVPOFFSET8(x, y, vp) vp = (y) * BYTEWIDTH + (x);
  40.  
  41. int driver8_setpixel( int x, int y, int c ) {
  42.     char *vp;
  43.     ASSIGNVP8(x, y, vp);
  44.     *vp = c;
  45. }
  46.  
  47. int driver8p_setpixel( int x, int y, int c ) {
  48.     int vp;
  49.     ASSIGNVPOFFSET8(x, y, vp);
  50.     vga_setpage(vp >> 16);
  51.     *(VBUF + (vp & 0xffff)) = c;
  52. }
  53.  
  54. int driver8_getpixel( int x, int y ) {
  55.     char *vp;
  56.     ASSIGNVP8(x, y, vp);
  57.     return *vp;
  58. }
  59.  
  60. int driver8p_getpixel( int x, int y ) {
  61.     int vp;
  62.     ASSIGNVPOFFSET8(x, y, vp);
  63.     vga_setpage(vp >> 16);
  64.     return *(VBUF + (vp & 0xffff));
  65. }
  66.  
  67. int driver8_hline( int x1, int y, int x2, int c ) {
  68.     char *vp;
  69.     ASSIGNVP8(x1, y, vp);
  70.     __memset(vp, c, x2 - x1 + 1);
  71. }
  72.  
  73. int driver8p_hline( int x1, int y, int x2, int c ) {
  74.     int vp;
  75.     char *rvp;
  76.     int l;
  77.     int chunksize, page;
  78.     ASSIGNVPOFFSET8(x1, y, vp);
  79.     SETWRITEPAGED(vp, rvp, chunksize, page);
  80.     l = x2 - x1 + 1;
  81.     if (l <= chunksize)
  82.         __memset(rvp, c, l);
  83.     else {
  84.         __memset(rvp, c, chunksize);
  85.         vga_setpage(page + 1);
  86.         __memset(VBUF, c, l - chunksize);
  87.     }
  88. }
  89.  
  90. int driver8_fillbox( int x, int y, int w, int h, int c ) {
  91.     char *vp;
  92.     int i;
  93.     ASSIGNVP8(x, y, vp);
  94.     for (i = 0; i < h; i++) {
  95.         __memset(vp, c, w);
  96.         vp += BYTEWIDTH;
  97.     }
  98. }
  99.  
  100. int driver8a_fillbox( int x, int y, int w, int h, int c ) {
  101.     int vp;
  102.     if (w * h < 128)
  103.         if (MODETYPE == CONTEXT_LINEAR)
  104.             driver8_fillbox(x, y, w, h, c);
  105.         else
  106.             driver8p_fillbox(x, y, w, h, c);
  107.     else {
  108.         vga_accel(ACCEL_SETFGCOLOR, c);
  109.         vga_accel(ACCEL_FILLBOX, x, y, w, h);
  110.     }
  111. }
  112.  
  113. int driver8p_fillbox( int x, int y, int w, int h, int c ) {
  114.     int vp;
  115.     int page;
  116.     int i;
  117.     ASSIGNVPOFFSET8(x, y, vp);
  118.     page = vp >> 16;
  119.     vp &= 0xffff;
  120.     vga_setpage(page);
  121.     for (i = 0; i < h; i++) {
  122.         if (vp + w > 0x10000)
  123.             if (vp >= 0x10000) {
  124.                 page++;
  125.                 vga_setpage(page);
  126.                 vp &= 0xffff;
  127.             }
  128.             else {    /* page break within line */
  129.                 __memset(VBUF + vp, c, 0x10000 - vp);
  130.                 page++;
  131.                 vga_setpage(page);
  132.                 __memset(VBUF, c, (vp + w) & 0xffff);
  133.                 vp = (vp + BYTEWIDTH) & 0xffff;
  134.                 continue;
  135.             }
  136.         __memset(VBUF + vp, c, w);
  137.         vp += BYTEWIDTH;
  138.     }
  139. }
  140.  
  141. int driver8_putbox( int x, int y, int w, int h, void *b, int bw ) {
  142.     char *vp;    /* screen pointer */
  143.     char *bp;    /* bitmap pointer */
  144.     int i;
  145.     ASSIGNVP8(x, y, vp);
  146.     bp = b;
  147.     for (i = 0; i < h; i++) {
  148.         __memcpy(vp, bp, w);
  149.         bp += bw;
  150.         vp += BYTEWIDTH;
  151.     }
  152. }
  153.  
  154. int driver8p_putbox( int x, int y, int w, int h, void *b, int bw ) {
  155. /* extra argument width of source bitmap, so that putboxpart can use this */
  156.     int vp;
  157.     int page;
  158.     char *bp = b;
  159.     int i;
  160.     ASSIGNVPOFFSET8(x, y, vp);
  161.     page = vp >> 16;
  162.     vp &= 0xffff;
  163.     vga_setpage(page);
  164.     for (i = 0; i < h; i++) {
  165.         if (vp + w > 0x10000)
  166.             if (vp >= 0x10000) {
  167.                 page++;
  168.                 vga_setpage(page);
  169.                 vp &= 0xffff;
  170.             }
  171.             else {    /* page break within line */
  172.                 __memcpy(VBUF + vp, bp, 0x10000 - vp);
  173.                 page++;
  174.                 vga_setpage(page);
  175.                 __memcpy(VBUF, bp + 0x10000 - vp,
  176.                     (vp + w) & 0xffff);
  177.                 vp = (vp + BYTEWIDTH) & 0xffff;
  178.                 bp += bw;
  179.                 continue;
  180.             }
  181.         __memcpy(VBUF + vp, bp, w);
  182.         bp += bw;
  183.         vp += BYTEWIDTH;
  184.     }
  185. }
  186.  
  187. int driver8_getbox( int x, int y, int w, int h, void *b, int bw ) {
  188.     char *vp;    /* screen pointer */
  189.     char *bp;    /* bitmap pointer */
  190.     int i;
  191.     ASSIGNVP8(x, y, vp);
  192.     bp = b;
  193.     for (i = 0; i < h; i++) {
  194.         __memcpy(bp, vp, w);
  195.         bp += bw;
  196.         vp += BYTEWIDTH;
  197.     }
  198. }
  199.  
  200. int driver8p_getbox( int x, int y, int w, int h, void *b, int bw ) {
  201.     int vp;
  202.     int page;
  203.     char *bp = b;
  204.     int i;
  205.     ASSIGNVPOFFSET8(x, y, vp);
  206.     page = vp >> 16;
  207.     vp &= 0xffff;
  208.     vga_setpage(page);
  209.     for (i = 0; i < h; i++) {
  210.         if (vp + w > 0x10000)
  211.             if (vp >= 0x10000) {
  212.                 page++;
  213.                 vga_setpage(page);
  214.                 vp &= 0xffff;
  215.             }
  216.             else {    /* page break within line */
  217.                 __memcpy(bp, VBUF + vp, 0x10000 - vp);
  218.                 page++;
  219.                 vga_setpage(page);
  220.                 __memcpy(bp + 0x10000 - vp, VBUF,
  221.                     (vp + w) & 0xffff);
  222.                 vp = (vp + BYTEWIDTH) & 0xffff;
  223.                 bp += bw;
  224.                 continue;
  225.             }
  226.         __memcpy(bp, VBUF + vp, w);
  227.         bp += bw;
  228.         vp += BYTEWIDTH;
  229.     }
  230. }
  231.  
  232. int driver8_putboxmask( int x, int y, int w, int h, void *b ) {
  233.     uchar *bp = b;
  234.     uchar *vp;
  235.     int i;
  236.     ASSIGNVP8(x, y, vp);
  237.     for (i = 0; i < h; i++) {
  238.         uchar *endoflinebp = bp + w;
  239.         while (bp < endoflinebp - 3) {
  240.             unsigned int c4 = *(unsigned int *)bp;
  241.             if (c4 & 0xff)
  242.                 *vp = (uchar)c4;
  243.             c4 >>= 8;
  244.             if (c4 & 0xff)
  245.                 *(vp + 1) = (uchar)c4;
  246.             c4 >>= 8;
  247.             if (c4 & 0xff)
  248.                 *(vp + 2) = (uchar)c4;
  249.             c4 >>= 8;
  250.             if (c4 & 0xff)
  251.                 *(vp + 3) = (uchar)c4;
  252.             bp += 4;
  253.             vp += 4;
  254.         }
  255.         while (bp < endoflinebp) {
  256.             uchar c = *bp;
  257.             if (c)
  258.                 *vp = c;
  259.             bp++;
  260.             vp++;
  261.         }
  262.         vp += BYTEWIDTH - w;
  263.     }
  264. }
  265.  
  266. int driver8_putboxpart( int x, int y, int w, int h, int ow, int oh,
  267. void *b, int xo, int yo ) {
  268.     driver8_putbox(x, y, w, h, b + yo * ow + xo, ow);    /* inlined */
  269. }
  270.  
  271. int driver8p_putboxpart( int x, int y, int w, int h, int ow, int oh,
  272. void *b, int xo, int yo ) {
  273.     driver8p_putbox(x, y, w, h, b + yo * ow + xo, ow);    /* inlined */
  274. }
  275.  
  276. int driver8_getboxpart( int x, int y, int w, int h, int ow, int oh,
  277. void *b, int xo, int yo ) {
  278.     driver8_getbox(x, y, w, h, b + yo * ow + xo, ow);
  279. }
  280.  
  281. int driver8p_getboxpart( int x, int y, int w, int h, int ow, int oh,
  282. void *b, int xo, int yo ) {
  283.     driver8p_getbox(x, y, w, h, b + yo * ow + xo, ow);
  284. }
  285.  
  286. int driver8_copybox( int x1, int y1, int w, int h, int x2, int y2 ) {
  287.     char *svp, *dvp;
  288.     /* I hope this works now. */
  289.     if (y1 >= y2) {
  290.         if (y1 == y2 && x2 >= x1) {    /* tricky */
  291.             int i;
  292.             if (x1 == x2)
  293.                 return;
  294.             /* use a temporary buffer to store a line */
  295.             /* using reversed movs would be much faster */
  296.             ASSIGNVP8(x1, y1, svp);
  297.             ASSIGNVP8(x2, y2, dvp);
  298.             for (i = 0; i < h; i++) {
  299.                 uchar linebuf[MAXBYTEWIDTH];
  300.                 __memcpy(linebuf, svp, w);
  301.                 __memcpy(dvp, linebuf, w);            
  302.                 svp += BYTEWIDTH;
  303.                 dvp += BYTEWIDTH;
  304.             }
  305.         }
  306.         else {    /* copy from top to bottom */ 
  307.             int i;
  308.             ASSIGNVP8(x1, y1, svp);
  309.             ASSIGNVP8(x2, y2, dvp);
  310.             for (i = 0; i < h; i++) {
  311.                 __memcpy(dvp, svp, w);
  312.                 svp += BYTEWIDTH;
  313.                 dvp += BYTEWIDTH;
  314.             }
  315.         }
  316.     }
  317.     else {    /* copy from bottom to top */
  318.         int i;
  319.         ASSIGNVP8(x1, y1 + h, svp);
  320.         ASSIGNVP8(x2, y2 + h, dvp);
  321.         for (i = 0; i < h; i++) {
  322.             svp -= BYTEWIDTH;
  323.             dvp -= BYTEWIDTH;
  324.             __memcpy(dvp, svp, w);
  325.         }
  326.     }
  327. }
  328.  
  329. int driver8a_copybox( int x1, int y1, int w, int h, int x2, int y2 ) {
  330.     vga_accel(ACCEL_SCREENCOPY, x1, y1, x2, y2, w, h);
  331. }
  332.  
  333.  
  334.  
  335. /* Two bytes per pixel graphics primitives */
  336.  
  337. #define ASSIGNVP16(x, y, vp) vp = VBUF + (y) * BYTEWIDTH + (x) * 2;
  338. #define ASSIGNVPOFFSET16(x, y, vp) vp = (y) * BYTEWIDTH + (x) * 2;
  339.  
  340. int driver16_setpixel( int x, int y, int c ) {
  341.     char *vp;
  342.     ASSIGNVP16(x, y, vp);
  343.     *(unsigned short *)vp = c;
  344. }
  345.  
  346. int driver16p_setpixel( int x, int y, int c ) {
  347.     int vp;
  348.     ASSIGNVPOFFSET16(x, y, vp);
  349.     vga_setpage(vp >> 16);
  350.     *(unsigned short *)(VBUF + (vp & 0xffff)) = c;
  351. }
  352.  
  353. int driver16_getpixel( int x, int y ) {
  354.     char *vp;
  355.     ASSIGNVP16(x, y, vp);
  356.     return *(unsigned short *)vp;
  357. }
  358.  
  359. int driver16p_getpixel( int x, int y ) {
  360.     int vp;
  361.     ASSIGNVPOFFSET16(x, y, vp);
  362.     vga_setpage(vp >> 16);
  363.     return *(unsigned short *)(VBUF + (vp & 0xffff));
  364. }
  365.  
  366. int driver16_hline( int x1, int y, int x2, int c ) {
  367.     char *vp;
  368.     ASSIGNVP16(x1, y, vp);
  369.     __memset2(vp, c, x2 - x1 + 1);
  370. }
  371.  
  372. int driver16p_hline( int x1, int y, int x2, int c ) {
  373.     int vp;
  374.     char *rvp;
  375.     int l;
  376.     int chunksize, page;
  377.     ASSIGNVPOFFSET16(x1, y, vp);
  378.     SETWRITEPAGED(vp, rvp, chunksize, page);
  379.     l = (x2 - x1 + 1) * 2;
  380.     if (l <= chunksize)
  381.         __memset2(rvp, c, l / 2);
  382.     else {
  383.         __memset2(rvp, c, chunksize / 2);
  384.         vga_setpage(page + 1);
  385.         __memset2(VBUF, c, (l - chunksize) / 2);
  386.     }
  387. }
  388.  
  389. int driver16_fillbox( int x, int y, int w, int h, int c ) {
  390.     char *vp;
  391.     int i;
  392.     ASSIGNVP16(x, y, vp);
  393.     for (i = 0; i < h; i++) {
  394.         __memset2(vp, c, w);
  395.         vp += BYTEWIDTH;
  396.     }
  397. }
  398.  
  399. int driver16p_fillbox( int x, int y, int w, int h, int c ) {
  400.     int vp;
  401.     int page;
  402.     int i;
  403.     ASSIGNVPOFFSET16(x, y, vp);
  404.     page = vp >> 16;
  405.     vp &= 0xffff;
  406.     vga_setpage(page);
  407.     for (i = 0; i < h; i++) {
  408.         if (vp + w * 2 > 0x10000)
  409.             if (vp >= 0x10000) {
  410.                 page++;
  411.                 vga_setpage(page);
  412.                 vp &= 0xffff;
  413.             }
  414.             else {    /* page break within line */
  415.                 __memset2(VBUF + vp, c, (0x10000 - vp) / 2);
  416.                 page++;
  417.                 vga_setpage(page);
  418.                 __memset2(VBUF, c, ((vp + w * 2) & 0xffff) / 2);
  419.                 vp = (vp + BYTEWIDTH) & 0xffff;
  420.                 continue;
  421.             }
  422.         __memset2(VBUF + vp, c, w);
  423.         vp += BYTEWIDTH;
  424.     }
  425. }
  426.  
  427. int driver16_putbox( int x, int y, int w, int h, void *b, int bw ) {
  428.     char *vp;    /* screen pointer */
  429.     char *bp;    /* bitmap pointer */
  430.     int i;
  431.     ASSIGNVP16(x, y, vp);
  432.     bp = b;
  433.     for (i = 0; i < h; i++) {
  434.         __memcpy(vp, bp, w * 2);
  435.         bp += bw * 2;
  436.         vp += BYTEWIDTH;
  437.     }
  438. }
  439.  
  440. int driver16p_putbox( int x, int y, int w, int h, void *b, int bw ) {
  441.     driver8p_putbox(x * 2, y, w * 2, h, b, bw * 2);
  442. }
  443.  
  444. int driver16_getbox( int x, int y, int w, int h, void *b, int bw ) {
  445.     char *vp;    /* screen pointer */
  446.     char *bp;    /* bitmap pointer */
  447.     int i;
  448.     ASSIGNVP16(x, y, vp);
  449.     bp = b;
  450.     for (i = 0; i < h; i++) {
  451.         __memcpy(bp, vp, w * 2);
  452.         bp += bw * 2;
  453.         vp += BYTEWIDTH;
  454.     }
  455. }
  456.  
  457. INLINE int driver16p_getbox( int x, int y, int w, int h, void *b, int bw ) {
  458.     driver8p_getbox(x * 2, y, w * 2, h, b, bw * 2);
  459. }
  460.  
  461. int driver16_putboxmask( int x, int y, int w, int h, void *b ) {
  462.     uchar *bp = b;
  463.     uchar *vp;
  464.     int i;
  465.     ASSIGNVP16(x, y, vp);
  466.     for (i = 0; i < h; i++) {
  467.         uchar *endoflinebp = bp + w * 2;
  468.         while (bp < endoflinebp - 7) {
  469.             unsigned c2 = *(unsigned *)bp;
  470.             if (c2 & 0xffff)
  471.                 *(ushort *)vp = (ushort)c2;
  472.             c2 >>= 16;
  473.             if (c2 & 0xffff)
  474.                 *(ushort *)(vp + 2) = (ushort)c2;
  475.             c2 = *(unsigned *)(bp + 4);
  476.             if (c2 & 0xffff)
  477.                 *(ushort *)(vp + 4) = (ushort)c2;
  478.             c2 >>= 16;
  479.             if (c2 & 0xffff)
  480.                 *(ushort *)(vp + 6) = (ushort)c2;
  481.             bp += 8;
  482.             vp += 8;
  483.         }
  484.         while (bp < endoflinebp) {
  485.             ushort c = *(ushort *)bp;
  486.             if (c)
  487.                 *(ushort *)vp = c;
  488.             bp += 2;
  489.             vp += 2;
  490.         }
  491.         vp += BYTEWIDTH - w * 2;
  492.     }
  493. }
  494.  
  495. INLINE int driver16_putboxpart( int x, int y, int w, int h, int ow, int oh,
  496. void *b, int xo, int yo ) {
  497.     driver8_putbox(x * 2, y, w * 2, h, b + yo * ow * 2 + xo * 2, ow * 2);
  498.         /* inlined */
  499. }
  500.  
  501. INLINE int driver16p_putboxpart( int x, int y, int w, int h, int ow, int oh,
  502. void *b, int xo, int yo ) {
  503.     driver8p_putbox(x * 2, y, w * 2, h, b + yo * ow * 2 + xo * 2, ow * 2);
  504. }
  505.  
  506. INLINE int driver16_getboxpart( int x, int y, int w, int h, int ow, int oh,
  507. void *b, int xo, int yo ) {
  508.     driver16_getbox(x, y, w, h, b + yo * ow + xo, ow);
  509. }
  510.  
  511. INLINE int driver16p_getboxpart( int x, int y, int w, int h, int ow, int oh,
  512. void *b, int xo, int yo ) {
  513.     driver16p_getbox(x, y, w, h, b + yo * ow + xo, ow);
  514. }
  515.  
  516. INLINE int driver16_copybox( int x1, int y1, int w, int h, int x2, int y2 ) {
  517.     driver8_copybox(x1 * 2, y1, w * 2, h, x2 * 2, y2);
  518. }
  519.  
  520. int driver16a_copybox( int x1, int y1, int w, int h, int x2, int y2 ) {
  521.     int svp, dvp;
  522.     ASSIGNVPOFFSET16(x1, y1, svp);
  523.     ASSIGNVPOFFSET16(x2, y2, dvp);
  524.     vga_bitblt(svp, dvp, w * 2, h, BYTEWIDTH);
  525. }
  526.  
  527.  
  528.  
  529. /* Three bytes per pixel graphics primitives */
  530.  
  531. #define ASSIGNVP24(x, y, vp) vp = VBUF + (y) * BYTEWIDTH + (x) * 3;
  532. #define ASSIGNVPOFFSET24(x, y, vp) vp = (y) * BYTEWIDTH + (x) * 3;
  533. #define RGBEQUAL(c) ((c & 0xff) == ((c >> 8) & 0xff) && \
  534.     (c & 0xff) == ((c >> 16) & 0xff))
  535.  
  536. int driver24_setpixel( int x, int y, int c ) {
  537.     char *vp;
  538.     ASSIGNVP24(x, y, vp);
  539.     *(unsigned short *)vp = c;
  540.     *(unsigned char *)(vp + 2) = c >> 16;
  541. }
  542.  
  543. int driver24p_setpixel( int x, int y, int c ) {
  544.     int vp, vpo;
  545.     char *vbuf;
  546.     int page;
  547.     ASSIGNVPOFFSET24(x, y, vp);
  548.     vbuf = VBUF;
  549.     page = vp >> 16;
  550.     vga_setpage(page);
  551.     vpo = vp & 0xffff;
  552.     if (vpo <= 0xfffd) {
  553.         *(unsigned short *)(vbuf + vpo) = c;
  554.         *(unsigned char *)(vbuf + vpo + 2) = c >> 16;
  555.     }
  556.     else
  557.     if (vpo == 0xfffe) {
  558.         *(unsigned short *)(vbuf + 0xfffe) = c;
  559.         vga_setpage(page + 1);
  560.         *(unsigned char *)vbuf = c >> 16;
  561.     }
  562.     else {    /* vpo == 0xffff */
  563.         *(unsigned char *)(vbuf + 0xffff) = c;
  564.         vga_setpage(page + 1);
  565.         *(unsigned short *)vbuf = c >> 8;
  566.     }
  567. }
  568.  
  569. int driver24_getpixel( int x, int y ) {
  570.     char *vp;
  571.     ASSIGNVP24(x, y, vp);
  572.     return *(unsigned short *)vp + (*(unsigned char *)(vp + 2) << 16);
  573. }
  574.  
  575. int driver24p_getpixel( int x, int y ) {
  576.     int vp, vpo;
  577.     char *vbuf;
  578.     int page;
  579.     ASSIGNVPOFFSET24(x, y, vp);
  580.     vbuf = VBUF;
  581.     page = vp >> 16;
  582.     vga_setpage(page);
  583.     vpo = vp & 0xffff;
  584.     if (vpo <= 0xfffd)
  585.         return *(unsigned short *)(vbuf + vpo) +
  586.                (*(unsigned char *)(vbuf + vpo + 2) << 16);
  587.     else
  588.     if (vpo == 0xfffe) {
  589.         int c;
  590.         c = *(unsigned short *)(vbuf + 0xfffe) = c;
  591.         vga_setpage(page + 1);
  592.         return (*(unsigned char *)vbuf << 16) + c;
  593.     }
  594.     else {    /* vpo == 0xffff */
  595.         int c;
  596.         c = *(unsigned char *)(vbuf + 0xffff);
  597.         vga_setpage(page + 1);
  598.         return (*(unsigned short *)vbuf << 8) + c;
  599.     }
  600. }
  601.  
  602. int driver24_hline( int x1, int y, int x2, int c ) {
  603.     char *vp;
  604.     ASSIGNVP24(x1, y, vp);
  605.     if (RGBEQUAL(c))
  606.         __memset(vp, c, (x2 - x1 + 1) * 3);
  607.     else
  608.         __memset3(vp, c, x2 - x1 + 1);
  609. }
  610.  
  611. int driver24p_hline( int x1, int y, int x2, int c ) {
  612.     int vp;
  613.     char *rvp;
  614.     int l;
  615.     int chunksize, page;
  616.     ASSIGNVPOFFSET24(x1, y, vp);
  617.     SETWRITEPAGED(vp, rvp, chunksize, page);
  618.     l = (x2 - x1 + 1) * 3;
  619.     if (l <= chunksize)
  620.         __memset3(rvp, c, l / 3);
  621.     else {
  622.         int n, m, o;
  623.         n = chunksize / 3;
  624.         m = chunksize % 3;
  625.         __memset3(rvp, c, n);
  626.         /* Handle page break within pixel. */
  627.         if (m >= 1)
  628.             *(rvp + n * 3) = c;
  629.         if (m == 2)
  630.             *(rvp + n * 3 + 1) = c >> 8;
  631.         vga_setpage(page + 1);
  632.         o = 0;
  633.         if (m == 2) {
  634.             *(VBUF) = c >> 16;
  635.             o = 1;
  636.         }
  637.         if (m == 1) {
  638.             *(unsigned short *)(VBUF) = c >> 8;
  639.             o = 2;
  640.         }
  641.         __memset3(VBUF + o, c, (l - chunksize) / 3);
  642.     }
  643. }
  644.  
  645. int driver24_fillbox( int x, int y, int w, int h, int c ) {
  646.     char *vp;
  647.     int i, j;
  648.     ASSIGNVP24(x, y, vp);
  649.     if (RGBEQUAL(c))
  650.         for (i = 0; i < h; i++) {
  651.             __memset(vp, c, w * 3);
  652.             vp += BYTEWIDTH;
  653.         }
  654.     else
  655.         for (j = 0; j < h; j++) {
  656.             __memset3(vp, c, w);
  657.             vp += BYTEWIDTH;
  658.         }
  659. }
  660.  
  661. int driver24p_fillbox( int x, int y, int w, int h, int c ) {
  662.     int vp;
  663.     int page;
  664.     int i;
  665.     ASSIGNVPOFFSET24(x, y, vp);
  666.     page = vp >> 16;
  667.     vp &= 0xffff;
  668.     vga_setpage(page);
  669.     if (RGBEQUAL(c)) {
  670.         for (i = 0; i < h; i++) {
  671.             if (vp + w * 3 > 0x10000)
  672.                 if (vp >= 0x10000) {
  673.                     page++;
  674.                     vga_setpage(page);
  675.                     vp &= 0xffff;
  676.                 }
  677.                 else {    /* Page break within line. */
  678.                     __memset(VBUF + vp, c, 0x10000 - vp);
  679.                     page++;
  680.                     vga_setpage(page);
  681.                     __memset(VBUF, c, (vp + w * 3) & 0xffff);
  682.                     vp = (vp + BYTEWIDTH) & 0xffff;
  683.                     continue;
  684.                 }
  685.             __memset(VBUF + vp, c, w * 3);
  686.             vp += BYTEWIDTH;
  687.         }
  688.     }
  689.     else
  690.         for (i = 0; i < h; i++) {
  691.             if (vp + w * 3 > 0x10000)
  692.                 if (vp >= 0x10000) {
  693.                     page++;
  694.                     vga_setpage(page);
  695.                     vp &= 0xffff;
  696.                 }
  697.                 else {    /* Page break within line. */
  698.                     int n, m, o;
  699.                     n = (0x10000 - vp) / 3;
  700.                     m = (0x10000 - vp) % 3;
  701.                     __memset3(VBUF + vp, c, n);
  702.                     /* Handle page break within pixel. */
  703.                     if (m >= 1)
  704.                         *(VBUF + vp + n * 3) = c;
  705.                     if (m == 2)
  706.                         *(VBUF + vp + n * 3 + 1) = c >> 8;
  707.                     page++;
  708.                     vga_setpage(page);
  709.                     o = 0;
  710.                     if (m == 2) {
  711.                         *(VBUF) = c >> 16;
  712.                         o = 1;
  713.                     }
  714.                     if (m == 1) {
  715.                         *(unsigned short *)(VBUF) = c >> 8;
  716.                         o = 2;
  717.                     }
  718.                     __memset3(VBUF + o, c, ((vp + w * 3) & 0xffff) / 3);
  719.                     vp = (vp + BYTEWIDTH) & 0xffff;
  720.                     continue;
  721.                 }
  722.             __memset3(VBUF + vp, c, w);
  723.             vp += BYTEWIDTH;
  724.         }
  725. }
  726.  
  727. int driver24_putbox( int x, int y, int w, int h, void *b, int bw ) {
  728.     char *vp;    /* screen pointer */
  729.     char *bp;    /* bitmap pointer */
  730.     int i;
  731.     ASSIGNVP24(x, y, vp);
  732.     bp = b;
  733.     for (i = 0; i < h; i++) {
  734.         __memcpy(vp, bp, w * 3);
  735.         bp += bw * 3;
  736.         vp += BYTEWIDTH;
  737.     }
  738. }
  739.  
  740. INLINE int driver24p_putbox( int x, int y, int w, int h, void *b, int bw ) {
  741.     driver8p_putbox(x * 3, y, w * 3, h, b, bw * 3);
  742. }
  743.  
  744. int driver24_putbox32( int x, int y, int w, int h, void *b, int bw ) {
  745.     char *vp;    /* screen pointer */
  746.     char *bp;    /* bitmap pointer */
  747.     int i;
  748.     ASSIGNVP24(x, y, vp);
  749.     bp = b;
  750.     for (i = 0; i < h; i++) {
  751.         memcpy4to3(vp, bp, w);
  752.         bp += bw * 4;
  753.         vp += BYTEWIDTH;
  754.     }
  755. }
  756.  
  757. int driver24_getbox( int x, int y, int w, int h, void *b, int bw ) {
  758.     char *vp;    /* screen pointer */
  759.     char *bp;    /* bitmap pointer */
  760.     int i;
  761.     ASSIGNVP24(x, y, vp);
  762.     bp = b;
  763.     for (i = 0; i < h; i++) {
  764.         __memcpy(bp, vp, w * 3);
  765.         bp += bw * 3;
  766.         vp += BYTEWIDTH;
  767.     }
  768. }
  769.  
  770. INLINE int driver24p_getbox( int x, int y, int w, int h, void *b, int bw ) {
  771.     driver8p_getbox(x * 3, y, w * 3, h, b, bw * 3);
  772. }
  773.  
  774. int driver24_putboxmask( int x, int y, int w, int h, void *b ) {
  775.     uchar *bp = b;
  776.     uchar *vp;
  777.     int i;
  778.     ASSIGNVP24(x, y, vp);
  779.     for (i = 0; i < h; i++) {
  780.         uchar *endoflinebp = bp + w * 3;
  781.         while (bp < endoflinebp - 11) {
  782.             unsigned c = *(unsigned *)bp;
  783.             if (c & 0xffffff) {
  784.                 *(ushort *)vp = (ushort)c;
  785.                 *(vp + 2) = c >> 16;
  786.             }
  787.             c = *(unsigned *)(bp + 3);
  788.             if (c & 0xffffff) {
  789.                 *(ushort *)(vp + 3) = (ushort)c;
  790.                 *(vp + 5) = c >> 16;
  791.             }
  792.             c = *(unsigned *)(bp + 6);
  793.             if (c & 0xffffff) {
  794.                 *(ushort *)(vp + 6) = (ushort)c;
  795.                 *(vp + 8) = c >> 16;
  796.             }
  797.             c = *(unsigned *)(bp + 9);
  798.             if (c & 0xffffff) {
  799.                 *(ushort *)(vp + 9) = (ushort)c;
  800.                 *(vp + 11) = c >> 16;
  801.             } 
  802.             bp += 12;
  803.             vp += 12;
  804.         }
  805.         while (bp < endoflinebp) {
  806.             uint c = *(uint *)bp;
  807.             if (c & 0xffffff) {
  808.                 *(ushort *)vp = (ushort)c;
  809.                 *(vp + 2) = c >> 16;
  810.             }
  811.             bp += 3;
  812.             vp += 3;
  813.         }
  814.         vp += BYTEWIDTH - w * 3;
  815.     }
  816. }
  817.  
  818. INLINE int driver24_putboxpart( int x, int y, int w, int h, int ow, int oh,
  819. void *b, int xo, int yo ) {
  820.     driver8_putbox(x * 3, y, w * 3, h, b + yo * ow * 3 + xo * 3, ow * 3);
  821.         /* inlined */
  822. }
  823.  
  824. INLINE int driver24p_putboxpart( int x, int y, int w, int h, int ow, int oh,
  825. void *b, int xo, int yo ) {
  826.     driver8p_putbox(x * 3, y, w * 3, h, b + yo * ow * 3 + xo * 3, ow * 3);
  827. }
  828.  
  829. INLINE int driver24_getboxpart( int x, int y, int w, int h, int ow, int oh,
  830. void *b, int xo, int yo ) {
  831.     driver24_getbox(x, y, w, h, b + yo * ow + xo, ow);
  832. }
  833.  
  834. INLINE int driver24p_getboxpart( int x, int y, int w, int h, int ow, int oh,
  835. void *b, int xo, int yo ) {
  836.     driver24p_getbox(x, y, w, h, b + yo * ow + xo, ow);
  837. }
  838.  
  839. int driver24_copybox( int x1, int y1, int w, int h, int x2, int y2 ) {
  840.     driver8_copybox(x1 * 3, y1, w * 3, h, x2 * 3, y2);
  841. }
  842.  
  843. int driver24a_copybox( int x1, int y1, int w, int h, int x2, int y2 ) {
  844.     int svp, dvp;
  845.     ASSIGNVPOFFSET24(x1, y1, svp);
  846.     ASSIGNVPOFFSET24(x2, y2, dvp);
  847.     vga_bitblt(svp, dvp, w * 3, h, BYTEWIDTH);
  848. }
  849.  
  850.  
  851.  
  852. /* Four bytes per pixel graphics primitives */
  853.  
  854. #define ASSIGNVP32(x, y, vp) vp = VBUF + (y) * BYTEWIDTH + (x) * 4;
  855. #define ASSIGNVPOFFSET32(x, y, vp) vp = (y) * BYTEWIDTH + (x) * 4;
  856.  
  857. int driver32_setpixel( int x, int y, int c ) {
  858.     char *vp;
  859.     ASSIGNVP32(x, y, vp);
  860.     *(unsigned *)vp = c;
  861. }
  862.  
  863. int driver32p_setpixel( int x, int y, int c ) {
  864.     int vp;
  865.     ASSIGNVPOFFSET32(x, y, vp);
  866.     vga_setpage(vp >> 16);
  867.     *(unsigned *)(VBUF + (vp & 0xffff)) = c;
  868. }
  869.  
  870. int driver32_getpixel( int x, int y ) {
  871.     char *vp;
  872.     ASSIGNVP32(x, y, vp);
  873.     return *(unsigned *)vp;
  874. }
  875.  
  876. int driver32p_getpixel( int x, int y ) {
  877.     int vp;
  878.     ASSIGNVPOFFSET32(x, y, vp);
  879.     vga_setpage(vp >> 16);
  880.     return *(unsigned *)(VBUF + (vp & 0xffff));
  881. }
  882.  
  883. int driver32_hline( int x1, int y, int x2, int c ) {
  884.     char *vp;
  885.     ASSIGNVP32(x1, y, vp);
  886.     __memsetlong(vp, c, x2 - x1 + 1);
  887. }
  888.  
  889. int driver32p_hline( int x1, int y, int x2, int c ) {
  890.     int vp;
  891.     char *rvp;
  892.     int l;
  893.     int chunksize, page;
  894.     ASSIGNVPOFFSET32(x1, y, vp);
  895.     SETWRITEPAGED(vp, rvp, chunksize, page);
  896.     l = (x2 - x1 + 1) * 4;
  897.     if (l <= chunksize)
  898.         __memsetlong(rvp, c, l / 4);
  899.     else {
  900.         __memsetlong(rvp, c, chunksize / 4);
  901.         vga_setpage(page + 1);
  902.         __memsetlong(VBUF, c, (l - chunksize) / 4);
  903.     }
  904. }
  905.  
  906. int driver32_fillbox( int x, int y, int w, int h, int c ) {
  907.     char *vp;
  908.     int i;
  909.     ASSIGNVP32(x, y, vp);
  910.     for (i = 0; i < h; i++) {
  911.         __memsetlong(vp, c, w);
  912.         vp += BYTEWIDTH;
  913.     }
  914. }
  915.  
  916. int driver32p_fillbox( int x, int y, int w, int h, int c ) {
  917.     int vp;
  918.     int page;
  919.     int i;
  920.     ASSIGNVPOFFSET32(x, y, vp);
  921.     page = vp >> 16;
  922.     vp &= 0xffff;
  923.     vga_setpage(page);
  924.     for (i = 0; i < h; i++) {
  925.         if (vp + w * 4 > 0x10000)
  926.             if (vp >= 0x10000) {
  927.                 page++;
  928.                 vga_setpage(page);
  929.                 vp &= 0xffff;
  930.             }
  931.             else {    /* page break within line */
  932.                 __memsetlong(VBUF + vp, c, (0x10000 - vp) / 4);
  933.                 page++;
  934.                 vga_setpage(page);
  935.                 __memsetlong(VBUF, c, ((vp + w * 4) & 0xffff) / 4);
  936.                 vp = (vp + BYTEWIDTH) & 0xffff;
  937.                 continue;
  938.             }
  939.         __memsetlong(VBUF + vp, c, w);
  940.         vp += BYTEWIDTH;
  941.     }
  942. }
  943.  
  944. INLINE int driver32_putbox( int x, int y, int w, int h, void *b, int bw ) {
  945.     driver8_putbox(x * 4, y, w * 4, h, b, bw * 4);
  946. }
  947.  
  948. INLINE int driver32p_putbox( int x, int y, int w, int h, void *b, int bw ) {
  949.     driver8p_putbox(x * 4, y, w * 4, h, b, bw * 4);
  950. }
  951.  
  952. INLINE int driver32_getbox( int x, int y, int w, int h, void *b, int bw ) {
  953.     driver8_getbox(x * 4, y, w * 4, h, b, bw * 4);
  954. }
  955.  
  956. INLINE int driver32p_getbox( int x, int y, int w, int h, void *b, int bw ) {
  957.     driver8p_getbox(x * 4, y, w * 4, h, b, bw * 4);
  958. }
  959.  
  960. int driver32_putboxmask( int x, int y, int w, int h, void *b ) {
  961.     uchar *bp = b;
  962.     uchar *vp;
  963.     int i;
  964.     ASSIGNVP32(x, y, vp);
  965.     for (i = 0; i < h; i++) {
  966.         uchar *endoflinebp = bp + w * 4;
  967.         while (bp < endoflinebp - 15) {
  968.             unsigned c = *(unsigned *)bp;
  969.             if (c)
  970.                 *(unsigned *)vp = c;
  971.             c = *(unsigned *)(bp + 4);
  972.             if (c)
  973.                 *(unsigned *)(vp + 4) = c;
  974.             c = *(unsigned *)(bp + 8);
  975.             if (c)
  976.                 *(unsigned *)(vp + 8) = c;
  977.             c = *(unsigned *)(bp + 12);
  978.             if (c)
  979.                 *(unsigned *)(vp + 12) = c;
  980.             bp += 16;
  981.             vp += 16;
  982.         }
  983.         while (bp < endoflinebp) {
  984.             unsigned c = *(unsigned *)bp;
  985.             if (c)
  986.                 *(unsigned *)vp = c;
  987.             bp += 4;
  988.             vp += 4;
  989.         }
  990.         vp += BYTEWIDTH - w * 4;
  991.     }
  992. }
  993.  
  994. INLINE int driver32_putboxpart( int x, int y, int w, int h, int ow, int oh,
  995. void *b, int xo, int yo ) {
  996.     driver32_putbox(x, y, w, h, b + yo * ow + xo, ow);
  997.         /* inlined */
  998. }
  999.  
  1000. INLINE int driver32p_putboxpart( int x, int y, int w, int h, int ow, int oh,
  1001. void *b, int xo, int yo ) {
  1002.     driver32p_putbox(x, y, w, h, b + yo * ow + xo, ow);
  1003.         /* inlined */
  1004. }
  1005.  
  1006. INLINE int driver32_getboxpart( int x, int y, int w, int h, int ow, int oh,
  1007. void *b, int xo, int yo ) {
  1008.     driver32_getbox(x, y, w, h, b + yo * ow + xo, ow);
  1009. }
  1010.  
  1011. INLINE int driver32p_getboxpart( int x, int y, int w, int h, int ow, int oh,
  1012. void *b, int xo, int yo ) {
  1013.     driver32p_getbox(x, y, w, h, b + yo * ow + xo, ow);
  1014. }
  1015.  
  1016. INLINE int driver32_copybox( int x1, int y1, int w, int h, int x2, int y2 ) {
  1017.     driver8_copybox(x1 * 4, y1, w * 4, h, x2 * 4, y2);
  1018. }
  1019.  
  1020.  
  1021.  
  1022. /* Planar 256 color mode graphics primitives (only putbox) */
  1023.  
  1024. driverplanar256_nothing() {
  1025.     NOTIMPL("planar 256 color mode primitive");
  1026. }
  1027.  
  1028. driverplanar256_putbox( int x, int y, int w, int h, void *b, int bw ) {
  1029.     if (w & 3 != 0 || x & 3 != 0)
  1030.         NOTIMPL("planar 256 color mode unaligned putbox");
  1031.     vga_copytoplanar256(b, bw, y * BYTEWIDTH + x / 4, BYTEWIDTH,
  1032.         w, h);
  1033. }
  1034.  
  1035. driverplanar16_nothing() {
  1036.     NOTIMPL("planar 16 color mode primitive");
  1037. }
  1038.  
  1039.  
  1040. /* Memory primitives */
  1041.  
  1042. int driver_setread( GraphicsContext *gc, int i, void **vp ) {
  1043.     if (gc->modetype == CONTEXT_PAGED) {
  1044.         vga_setpage(i >> 16);
  1045.         *vp = (i & 0xffff) + gc->vbuf;
  1046.         return 0x10000 - (i & 0xffff);
  1047.     }
  1048.     else {
  1049.         *vp = gc->vbuf + i;
  1050.         return 0x10000;
  1051.     }
  1052. }
  1053.  
  1054. int driver_setwrite( GraphicsContext *gc, int i, void **vp ) {
  1055.     if (gc->modetype == CONTEXT_PAGED) {
  1056.         vga_setpage(i >> 16);
  1057.         *vp = (i & 0xffff) + gc->vbuf;
  1058.         return 0x10000 - (i & 0xffff);
  1059.     }
  1060.     else {
  1061.         *vp = gc->vbuf + i;
  1062.         return 0x10000;
  1063.     }
  1064. }
  1065.  
  1066.  
  1067.  
  1068. /* Functions that are not yet implemented */
  1069.  
  1070. int driver8p_putboxmask( int x, int y, int w, int h, void *b ) {
  1071.     NOTIMPL("8-bit paged putboxmask");
  1072. }
  1073.  
  1074. int driver8p_copybox( int x1, int y1, int w, int h, int x2, int y2 ) {
  1075.     NOTIMPL("8-bit paged copybox (bitblt)");
  1076. }
  1077.  
  1078. int driver16p_putboxmask( int x, int y, int w, int h, void *b ) {
  1079.     NOTIMPL("16-bit paged putboxmask");
  1080. }
  1081.  
  1082. int driver16p_copybox( int x1, int y1, int w, int h, int x2, int y2 ) {
  1083.     NOTIMPL("16-bit paged copybox");
  1084. }
  1085.  
  1086. int driver24p_putboxmask( int x, int y, int w, int h, void *b ) {
  1087.     NOTIMPL("24-bit paged putboxmask");
  1088. }
  1089.  
  1090. int driver24p_copybox( int x1, int y1, int w, int h, int x2, int y2 ) {
  1091.     NOTIMPL("24-bit paged copybox");
  1092. }
  1093.  
  1094. int driver32p_putboxmask( int x, int y, int w, int h, void *b ) {
  1095.     NOTIMPL("32-bit paged putboxmask");
  1096. }
  1097.  
  1098. int driver32p_copybox( int x1, int y1, int w, int h, int x2, int y2 ) {
  1099.     NOTIMPL("32-bit paged copybox");
  1100. }
  1101.