home *** CD-ROM | disk | FTP | other *** search
/ The Unsorted BBS Collection / thegreatunsorted.tar / thegreatunsorted / misc / wolfsrc.1 / CONTIGSC.C < prev    next >
C/C++ Source or Header  |  1993-02-04  |  16KB  |  734 lines

  1. // WL_SCALE.C
  2.  
  3. #include "WL_DEF.H"
  4. #pragma hdrstop
  5.  
  6. #define OP_RETF    0xcb
  7.  
  8. /*
  9. =============================================================================
  10.  
  11.                           GLOBALS
  12.  
  13. =============================================================================
  14. */
  15.  
  16. t_compscale far *scaledirectory[MAXSCALEHEIGHT+1];
  17. long            fullscalefarcall[MAXSCALEHEIGHT+1];
  18.  
  19. int            maxscale,maxscaleshl2;
  20.  
  21. byte far    *scalermemory;
  22. byte _seg    *endscalermemory;
  23. long        freescalermemory;
  24.  
  25.  
  26. /*
  27. =============================================================================
  28.  
  29.                           LOCALS
  30.  
  31. =============================================================================
  32. */
  33.  
  34. unsigned BuildCompScale (int height, byte far *code);
  35.  
  36. int            stepbytwo;
  37.  
  38. //===========================================================================
  39.  
  40. /*
  41. ==============
  42. =
  43. = BadScale
  44. =
  45. ==============
  46. */
  47.  
  48. void far BadScale (void)
  49. {
  50.     Quit ("BadScale called!");
  51. }
  52.  
  53.  
  54. /*
  55. ==========================
  56. =
  57. = SetupScaling
  58. =
  59. ==========================
  60. */
  61.  
  62. long SetupScaling (int maxscaleheight)
  63. {
  64.     int        i,x,y;
  65.     byte    far *dest;
  66.     unsigned    seg,ofs;
  67.     long    size;
  68.  
  69.  
  70.     maxscaleheight/=2;            // one scaler every two pixels
  71.  
  72.     maxscale = maxscaleheight-1;
  73.     maxscaleshl2 = maxscale<<2;
  74.  
  75.     dest = scalermemory;
  76.  
  77. //
  78. // build the compiled scalers
  79. //
  80.     stepbytwo = viewheight/2;    // save space by double stepping
  81.  
  82.     for (i=1;i<=maxscaleheight;i++)
  83.     {
  84.         seg = FP_SEG(dest);
  85.         ofs = (FP_OFF(dest)+15)&~15;
  86.         dest = MK_FP(seg+ofs/16,0);
  87.  
  88.         scaledirectory[i] = (t_compscale far *)dest;
  89.         size = BuildCompScale (i*2,dest);
  90.         dest += size;
  91.  
  92.         if ((byte huge *)dest-(byte huge *)scalermemory > MAXSCALERMEMORY)
  93.             Quit ("Compiled scalars exceeded allocated space!");
  94.  
  95.         if (i>=stepbytwo)
  96.             i+= 2;
  97.     }
  98.  
  99. //
  100. // get far call addresses
  101. //
  102.     for (i=1;i<=maxscaleheight;i++)
  103.     {
  104.         fullscalefarcall[i] = (long)scaledirectory[i] + scaledirectory[i]->codeofs[0];
  105.         if (i>=stepbytwo)
  106.         {
  107.             scaledirectory[i+1] = scaledirectory[i];
  108.             fullscalefarcall[i+1] = (long)scaledirectory[i] + scaledirectory[i]->codeofs[0];
  109.             scaledirectory[i+2] = scaledirectory[i];
  110.             fullscalefarcall[i+2] = (long)scaledirectory[i] + scaledirectory[i]->codeofs[0];
  111.             i+=2;
  112.         }
  113.     }
  114.     scaledirectory[0] = scaledirectory[1];
  115.     fullscalefarcall[0] = fullscalefarcall[1];
  116.  
  117. //
  118. // check for oversize wall drawing
  119. //
  120.     for (i=maxscaleheight;i<MAXSCALEHEIGHT;i++)
  121.         fullscalefarcall[i] = (long)BadScale;
  122.  
  123.     seg = FP_SEG(dest);
  124.     ofs = (FP_OFF(dest)+15)&~15;
  125.     endscalermemory = (void _seg *)(seg+ofs/16);
  126.     size = (byte huge *)dest-(byte huge *)scalermemory;
  127.     freescalermemory = MAXSCALERMEMORY-16-size;
  128.  
  129.     return size;
  130. }
  131.  
  132. //===========================================================================
  133.  
  134. /*
  135. ========================
  136. =
  137. = BuildCompScale
  138. =
  139. = Builds a compiled scaler object that will scale a 64 tall object to
  140. = the given height (centered vertically on the screen)
  141. =
  142. = height should be even
  143. =
  144. = Call with
  145. = ---------
  146. = DS:SI        Source for scale
  147. = ES:DI        Dest for scale
  148. =
  149. = Calling the compiled scaler only destroys AL
  150. =
  151. ========================
  152. */
  153.  
  154. unsigned BuildCompScale (int height, byte far *code)
  155. {
  156.     t_compscale     far *work;
  157.  
  158.     int            i;
  159.     long        fix,step;
  160.     unsigned    src,totalscaled,totalsize;
  161.     int            startpix,endpix,toppix;
  162.  
  163.     work = (t_compscale far *)code;
  164.  
  165.     step = ((long)height<<16) / 64;
  166.     code = &work->code[0];
  167.     toppix = (viewheight-height)/2;
  168.     fix = 0;
  169.  
  170.     for (src=0;src<=64;src++)
  171.     {
  172.         startpix = fix>>16;
  173.         fix += step;
  174.         endpix = fix>>16;
  175.  
  176.         if (endpix>startpix)
  177.             work->width[src] = endpix-startpix;
  178.         else
  179.             work->width[src] = 0;
  180.  
  181. //
  182. // mark the start of the code
  183. //
  184.         work->codeofs[src] = FP_OFF(code);
  185.  
  186. //
  187. // compile some code if the source pixel generates any screen pixels
  188. //
  189.         startpix+=toppix;
  190.         endpix+=toppix;
  191.  
  192.         if (startpix == endpix || endpix < 0 || startpix >= viewheight || src == 64)
  193.             continue;
  194.  
  195.     //
  196.     // mov al,[si+src]
  197.     //
  198.         *code++ = 0x8a;
  199.         *code++ = 0x44;
  200.         *code++ = src;
  201.  
  202.         for (;startpix<endpix;startpix++)
  203.         {
  204.             if (startpix >= viewheight)
  205.                 break;                        // off the bottom of the view area
  206.             if (startpix < 0)
  207.                 continue;                    // not into the view area
  208.  
  209.         //
  210.         // mov [es:di+heightofs],al
  211.         //
  212.             *code++ = 0x26;
  213.             *code++ = 0x88;
  214.             *code++ = 0x85;
  215.             *((unsigned far *)code)++ = startpix*SCREENBWIDE;
  216.         }
  217.  
  218.     }
  219.  
  220. //
  221. // retf
  222. //
  223.     *code++ = 0xcb;
  224.  
  225.     totalsize = FP_OFF(code);
  226.  
  227.     return totalsize;
  228. }
  229.  
  230.  
  231. /*
  232. =======================
  233. =
  234. = ScaleLine
  235. =
  236. = linescale should have the high word set to the segment of the scaler
  237. =
  238. =======================
  239. */
  240.  
  241. extern    int            slinex,slinewidth;
  242. extern    unsigned    far *linecmds;
  243. extern    long        linescale;
  244. extern    unsigned    maskword;
  245.  
  246. byte    mask1,mask2,mask3;
  247.  
  248.  
  249. void near ScaleLine (void)
  250. {
  251. asm    mov    cx,WORD PTR [linescale+2]
  252. asm    mov    es,cx                        // segment of scaler
  253.  
  254. asm    mov bp,WORD PTR [linecmds]
  255. asm    mov    dx,SC_INDEX+1                // to set SC_MAPMASK
  256.  
  257. asm    mov    bx,[slinex]
  258. asm    mov    di,bx
  259. asm    shr    di,2                        // X in bytes
  260. asm    add    di,[bufferofs]
  261. asm    and    bx,3
  262. asm    shl    bx,3
  263. asm    add    bx,[slinewidth]                // bx = (pixel*8+pixwidth)
  264. asm    mov    al,BYTE [mapmasks3-1+bx]    // -1 because pixwidth of 1 is first
  265. asm    mov    ds,WORD PTR [linecmds+2]
  266. asm    or    al,al
  267. asm    jz    notthreebyte                // scale across three bytes
  268. asm    jmp    threebyte
  269. notthreebyte:
  270. asm    mov    al,BYTE PTR ss:[mapmasks2-1+bx]    // -1 because pixwidth of 1 is first
  271. asm    or    al,al
  272. asm    jnz    twobyte                        // scale across two bytes
  273.  
  274. //
  275. // one byte scaling
  276. //
  277. asm    mov    al,BYTE PTR ss:[mapmasks1-1+bx]    // -1 because pixwidth of 1 is first
  278. asm    out    dx,al                        // set map mask register
  279.  
  280. scalesingle:
  281.  
  282. asm    mov    bx,[ds:bp]                    // table location of rtl to patch
  283. asm    or    bx,bx
  284. asm    jz    linedone                    // 0 signals end of segment list
  285. asm    mov    bx,[es:bx]
  286. asm    mov    dl,[es:bx]                    // save old value
  287. asm    mov    BYTE PTR es:[bx],OP_RETF    // patch a RETF in
  288. asm    mov    si,[ds:bp+4]                // table location of entry spot
  289. asm    mov    ax,[es:si]
  290. asm    mov    WORD PTR ss:[linescale],ax    // call here to start scaling
  291. asm    mov    si,[ds:bp+2]                // corrected top of shape for this segment
  292. asm    add    bp,6                        // next segment list
  293.  
  294. asm    mov    ax,SCREENSEG
  295. asm    mov    es,ax
  296. asm    call ss:[linescale]                // scale the segment of pixels
  297.  
  298. asm    mov    es,cx                        // segment of scaler
  299. asm    mov    BYTE PTR es:[bx],dl            // unpatch the RETF
  300. asm    jmp    scalesingle                    // do the next segment
  301.  
  302.  
  303. //
  304. // done
  305. //
  306. linedone:
  307. asm    mov    ax,ss
  308. asm    mov    ds,ax
  309. return;
  310.  
  311. //
  312. // two byte scaling
  313. //
  314. twobyte:
  315. asm    mov    ss:[mask2],al
  316. asm    mov    al,BYTE PTR ss:[mapmasks1-1+bx]    // -1 because pixwidth of 1 is first
  317. asm    mov    ss:[mask1],al
  318.  
  319. scaledouble:
  320.  
  321. asm    mov    bx,[ds:bp]                    // table location of rtl to patch
  322. asm    or    bx,bx
  323. asm    jz    linedone                    // 0 signals end of segment list
  324. asm    mov    bx,[es:bx]
  325. asm    mov    cl,[es:bx]                    // save old value
  326. asm    mov    BYTE PTR es:[bx],OP_RETF    // patch a RETF in
  327. asm    mov    si,[ds:bp+4]                // table location of entry spot
  328. asm    mov    ax,[es:si]
  329. asm    mov    WORD PTR ss:[linescale],ax    // call here to start scaling
  330. asm    mov    si,[ds:bp+2]                // corrected top of shape for this segment
  331. asm    add    bp,6                        // next segment list
  332.  
  333. asm    mov    ax,SCREENSEG
  334. asm    mov    es,ax
  335. asm    mov    al,ss:[mask1]
  336. asm    out    dx,al                        // set map mask register
  337. asm    call ss:[linescale]                // scale the segment of pixels
  338. asm    inc    di
  339. asm    mov    al,ss:[mask2]
  340. asm    out    dx,al                        // set map mask register
  341. asm    call ss:[linescale]                // scale the segment of pixels
  342. asm    dec    di
  343.  
  344. asm    mov    es,WORD PTR ss:[linescale+2] // segment of scaler
  345. asm    mov    BYTE PTR es:[bx],cl            // unpatch the RETF
  346. asm    jmp    scaledouble                    // do the next segment
  347.  
  348.  
  349. //
  350. // three byte scaling
  351. //
  352. threebyte:
  353. asm    mov    ss:[mask3],al
  354. asm    mov    al,BYTE PTR ss:[mapmasks2-1+bx]    // -1 because pixwidth of 1 is first
  355. asm    mov    ss:[mask2],al
  356. asm    mov    al,BYTE PTR ss:[mapmasks1-1+bx]    // -1 because pixwidth of 1 is first
  357. asm    mov    ss:[mask1],al
  358.  
  359. scaletriple:
  360.  
  361. asm    mov    bx,[ds:bp]                    // table location of rtl to patch
  362. asm    or    bx,bx
  363. asm    jz    linedone                    // 0 signals end of segment list
  364. asm    mov    bx,[es:bx]
  365. asm    mov    cl,[es:bx]                    // save old value
  366. asm    mov    BYTE PTR es:[bx],OP_RETF    // patch a RETF in
  367. asm    mov    si,[ds:bp+4]                // table location of entry spot
  368. asm    mov    ax,[es:si]
  369. asm    mov    WORD PTR ss:[linescale],ax    // call here to start scaling
  370. asm    mov    si,[ds:bp+2]                // corrected top of shape for this segment
  371. asm    add    bp,6                        // next segment list
  372.  
  373. asm    mov    ax,SCREENSEG
  374. asm    mov    es,ax
  375. asm    mov    al,ss:[mask1]
  376. asm    out    dx,al                        // set map mask register
  377. asm    call ss:[linescale]                // scale the segment of pixels
  378. asm    inc    di
  379. asm    mov    al,ss:[mask2]
  380. asm    out    dx,al                        // set map mask register
  381. asm    call ss:[linescale]                // scale the segment of pixels
  382. asm    inc    di
  383. asm    mov    al,ss:[mask3]
  384. asm    out    dx,al                        // set map mask register
  385. asm    call ss:[linescale]                // scale the segment of pixels
  386. asm    dec    di
  387. asm    dec    di
  388.  
  389. asm    mov    es,WORD PTR ss:[linescale+2] // segment of scaler
  390. asm    mov    BYTE PTR es:[bx],cl            // unpatch the RETF
  391. asm    jmp    scaletriple                    // do the next segment
  392.  
  393.  
  394. }
  395.  
  396.  
  397. /*
  398. =======================
  399. =
  400. = ScaleShape
  401. =
  402. = Draws a compiled shape at [scale] pixels high
  403. =
  404. = each vertical line of the shape has a pointer to segment data:
  405. =     end of segment pixel*2 (0 terminates line) used to patch rtl in scaler
  406. =     top of virtual line with segment in proper place
  407. =    start of segment pixel*2, used to jsl into compiled scaler
  408. =    <repeat>
  409. =
  410. = Setup for call
  411. = --------------
  412. = GC_MODE            read mode 1, write mode 2
  413. = GC_COLORDONTCARE  set to 0, so all reads from video memory return 0xff
  414. = GC_INDEX            pointing at GC_BITMASK
  415. =
  416. =======================
  417. */
  418.  
  419. static    long        longtemp;
  420.  
  421. void ScaleShape (int xcenter, int shapenum, unsigned height)
  422. {
  423.     t_compshape    _seg *shape;
  424.     t_compscale far *comptable;
  425.     unsigned    scale,srcx,stopx,tempx;
  426.     int            t;
  427.     unsigned    far *cmdptr;
  428.     boolean        leftvis,rightvis;
  429.  
  430.  
  431.     shape = PM_GetSpritePage (shapenum);
  432.  
  433.     scale = height>>3;                        // low three bits are fractional
  434.     if (!scale || scale>maxscale)
  435.         return;                                // too close or far away
  436.     comptable = scaledirectory[scale];
  437.  
  438.     *(((unsigned *)&linescale)+1)=FP_SEG(comptable);    // seg of far call
  439.     *(((unsigned *)&linecmds)+1)=(unsigned)shape;        // seg of shape
  440.  
  441. //
  442. // scale to the left (from pixel 31 to shape->leftpix)
  443. //
  444.     srcx = 32;
  445.     slinex = xcenter;
  446.     stopx = shape->leftpix;
  447.     cmdptr = &shape->dataofs[31-stopx];
  448.  
  449.     while ( --srcx >=stopx && slinex>0)
  450.     {
  451.         (unsigned)linecmds = *cmdptr--;
  452.         if ( !(slinewidth = comptable->width[srcx]) )
  453.             continue;
  454.  
  455.         if (slinewidth == 1)
  456.         {
  457.             slinex--;
  458.             if (slinex<viewwidth)
  459.             {
  460.                 if (wallheight[slinex] >= height)
  461.                     continue;        // obscured by closer wall
  462.                 ScaleLine ();
  463.             }
  464.             continue;
  465.         }
  466.  
  467.         //
  468.         // handle multi pixel lines
  469.         //
  470.         if (slinex>viewwidth)
  471.         {
  472.             slinex -= slinewidth;
  473.             slinewidth = viewwidth-slinex;
  474.             if (slinewidth<1)
  475.                 continue;        // still off the right side
  476.         }
  477.         else
  478.         {
  479.             if (slinewidth>slinex)
  480.                 slinewidth = slinex;
  481.             slinex -= slinewidth;
  482.         }
  483.  
  484.  
  485.         leftvis = (wallheight[slinex] < height);
  486.         rightvis = (wallheight[slinex+slinewidth-1] < height);
  487.  
  488.         if (leftvis)
  489.         {
  490.             if (rightvis)
  491.                 ScaleLine ();
  492.             else
  493.             {
  494.                 while (wallheight[slinex+slinewidth-1] >= height)
  495.                     slinewidth--;
  496.                 ScaleLine ();
  497.             }
  498.         }
  499.         else
  500.         {
  501.             if (!rightvis)
  502.                 continue;        // totally obscured
  503.  
  504.             while (wallheight[slinex] >= height)
  505.             {
  506.                 slinex++;
  507.                 slinewidth--;
  508.             }
  509.             ScaleLine ();
  510.             break;            // the rest of the shape is gone
  511.         }
  512.     }
  513.  
  514.  
  515. //
  516. // scale to the right
  517. //
  518.     slinex = xcenter;
  519.     stopx = shape->rightpix;
  520.     if (shape->leftpix<31)
  521.     {
  522.         srcx = 31;
  523.         cmdptr = &shape->dataofs[32-shape->leftpix];
  524.     }
  525.     else
  526.     {
  527.         srcx = shape->leftpix-1;
  528.         cmdptr = &shape->dataofs[0];
  529.     }
  530.     slinewidth = 0;
  531.  
  532.     while ( ++srcx <= stopx && (slinex+=slinewidth)<viewwidth)
  533.     {
  534.         (unsigned)linecmds = *cmdptr++;
  535.         if ( !(slinewidth = comptable->width[srcx]) )
  536.             continue;
  537.  
  538.         if (slinewidth == 1)
  539.         {
  540.             if (slinex>=0 && wallheight[slinex] < height)
  541.             {
  542.                 ScaleLine ();
  543.             }
  544.             continue;
  545.         }
  546.  
  547.         //
  548.         // handle multi pixel lines
  549.         //
  550.         if (slinex<0)
  551.         {
  552.             if (slinewidth <= -slinex)
  553.                 continue;        // still off the left edge
  554.  
  555.             slinewidth += slinex;
  556.             slinex = 0;
  557.         }
  558.         else
  559.         {
  560.             if (slinex + slinewidth > viewwidth)
  561.                 slinewidth = viewwidth-slinex;
  562.         }
  563.  
  564.  
  565.         leftvis = (wallheight[slinex] < height);
  566.         rightvis = (wallheight[slinex+slinewidth-1] < height);
  567.  
  568.         if (leftvis)
  569.         {
  570.             if (rightvis)
  571.             {
  572.                 ScaleLine ();
  573.             }
  574.             else
  575.             {
  576.                 while (wallheight[slinex+slinewidth-1] >= height)
  577.                     slinewidth--;
  578.                 ScaleLine ();
  579.                 break;            // the rest of the shape is gone
  580.             }
  581.         }
  582.         else
  583.         {
  584.             if (rightvis)
  585.             {
  586.                 while (wallheight[slinex] >= height)
  587.                 {
  588.                     slinex++;
  589.                     slinewidth--;
  590.                 }
  591.                 ScaleLine ();
  592.             }
  593.             else
  594.                 continue;        // totally obscured
  595.         }
  596.     }
  597. }
  598.  
  599.  
  600.  
  601. /*
  602. =======================
  603. =
  604. = SimpleScaleShape
  605. =
  606. = NO CLIPPING, height in pixels
  607. =
  608. = Draws a compiled shape at [scale] pixels high
  609. =
  610. = each vertical line of the shape has a pointer to segment data:
  611. =     end of segment pixel*2 (0 terminates line) used to patch rtl in scaler
  612. =     top of virtual line with segment in proper place
  613. =    start of segment pixel*2, used to jsl into compiled scaler
  614. =    <repeat>
  615. =
  616. = Setup for call
  617. = --------------
  618. = GC_MODE            read mode 1, write mode 2
  619. = GC_COLORDONTCARE  set to 0, so all reads from video memory return 0xff
  620. = GC_INDEX            pointing at GC_BITMASK
  621. =
  622. =======================
  623. */
  624.  
  625. void SimpleScaleShape (int xcenter, int shapenum, unsigned height)
  626. {
  627.     t_compshape    _seg *shape;
  628.     t_compscale far *comptable;
  629.     unsigned    scale,srcx,stopx,tempx;
  630.     int            t;
  631.     unsigned    far *cmdptr;
  632.     boolean        leftvis,rightvis;
  633.  
  634.  
  635.     shape = PM_GetSpritePage (shapenum);
  636.  
  637.     scale = height>>1;
  638.     comptable = scaledirectory[scale];
  639.  
  640.     *(((unsigned *)&linescale)+1)=FP_SEG(comptable);    // seg of far call
  641.     *(((unsigned *)&linecmds)+1)=(unsigned)shape;        // seg of shape
  642.  
  643. //
  644. // scale to the left (from pixel 31 to shape->leftpix)
  645. //
  646.     srcx = 32;
  647.     slinex = xcenter;
  648.     stopx = shape->leftpix;
  649.     cmdptr = &shape->dataofs[31-stopx];
  650.  
  651.     while ( --srcx >=stopx )
  652.     {
  653.         (unsigned)linecmds = *cmdptr--;
  654.         if ( !(slinewidth = comptable->width[srcx]) )
  655.             continue;
  656.  
  657.         slinex -= slinewidth;
  658.         ScaleLine ();
  659.     }
  660.  
  661.  
  662. //
  663. // scale to the right
  664. //
  665.     slinex = xcenter;
  666.     stopx = shape->rightpix;
  667.     if (shape->leftpix<31)
  668.     {
  669.         srcx = 31;
  670.         cmdptr = &shape->dataofs[32-shape->leftpix];
  671.     }
  672.     else
  673.     {
  674.         srcx = shape->leftpix-1;
  675.         cmdptr = &shape->dataofs[0];
  676.     }
  677.     slinewidth = 0;
  678.  
  679.     while ( ++srcx <= stopx )
  680.     {
  681.         (unsigned)linecmds = *cmdptr++;
  682.         if ( !(slinewidth = comptable->width[srcx]) )
  683.             continue;
  684.  
  685.         ScaleLine ();
  686.         slinex+=slinewidth;
  687.     }
  688. }
  689.  
  690.  
  691.  
  692.  
  693. //
  694. // bit mask tables for drawing scaled strips up to eight pixels wide
  695. //
  696. // down here so the STUPID inline assembler doesn't get confused!
  697. //
  698.  
  699.  
  700. byte    mapmasks1[4][8] = {
  701. {1 ,3 ,7 ,15,15,15,15,15},
  702. {2 ,6 ,14,14,14,14,14,14},
  703. {4 ,12,12,12,12,12,12,12},
  704. {8 ,8 ,8 ,8 ,8 ,8 ,8 ,8} };
  705.  
  706. byte    mapmasks2[4][8] = {
  707. {0 ,0 ,0 ,0 ,1 ,3 ,7 ,15},
  708. {0 ,0 ,0 ,1 ,3 ,7 ,15,15},
  709. {0 ,0 ,1 ,3 ,7 ,15,15,15},
  710. {0 ,1 ,3 ,7 ,15,15,15,15} };
  711.  
  712. byte    mapmasks3[4][8] = {
  713. {0 ,0 ,0 ,0 ,0 ,0 ,0 ,0},
  714. {0 ,0 ,0 ,0 ,0 ,0 ,0 ,1},
  715. {0 ,0 ,0 ,0 ,0 ,0 ,1 ,3},
  716. {0 ,0 ,0 ,0 ,0 ,1 ,3 ,7} };
  717.  
  718.  
  719. unsigned    wordmasks[8][8] = {
  720. {0x0080,0x00c0,0x00e0,0x00f0,0x00f8,0x00fc,0x00fe,0x00ff},
  721. {0x0040,0x0060,0x0070,0x0078,0x007c,0x007e,0x007f,0x807f},
  722. {0x0020,0x0030,0x0038,0x003c,0x003e,0x003f,0x803f,0xc03f},
  723. {0x0010,0x0018,0x001c,0x001e,0x001f,0x801f,0xc01f,0xe01f},
  724. {0x0008,0x000c,0x000e,0x000f,0x800f,0xc00f,0xe00f,0xf00f},
  725. {0x0004,0x0006,0x0007,0x8007,0xc007,0xe007,0xf007,0xf807},
  726. {0x0002,0x0003,0x8003,0xc003,0xe003,0xf003,0xf803,0xfc03},
  727. {0x0001,0x8001,0xc001,0xe001,0xf001,0xf801,0xfc01,0xfe01} };
  728.  
  729. int            slinex,slinewidth;
  730. unsigned    far *linecmds;
  731. long        linescale;
  732. unsigned    maskword;
  733.  
  734.