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