wolf3d

The original open source release of Wolfenstein 3D
Log | Files | Refs

WL_SCALE.C (15301B)


      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 boolean	insetupscaling;
     22 
     23 /*
     24 =============================================================================
     25 
     26 						  LOCALS
     27 
     28 =============================================================================
     29 */
     30 
     31 t_compscale 	_seg *work;
     32 unsigned BuildCompScale (int height, memptr *finalspot);
     33 
     34 int			stepbytwo;
     35 
     36 //===========================================================================
     37 
     38 /*
     39 ==============
     40 =
     41 = BadScale
     42 =
     43 ==============
     44 */
     45 
     46 void far BadScale (void)
     47 {
     48 	Quit ("BadScale called!");
     49 }
     50 
     51 
     52 /*
     53 ==========================
     54 =
     55 = SetupScaling
     56 =
     57 ==========================
     58 */
     59 
     60 void SetupScaling (int maxscaleheight)
     61 {
     62 	int		i,x,y;
     63 	byte	far *dest;
     64 
     65 	insetupscaling = true;
     66 
     67 	maxscaleheight/=2;			// one scaler every two pixels
     68 
     69 	maxscale = maxscaleheight-1;
     70 	maxscaleshl2 = maxscale<<2;
     71 
     72 //
     73 // free up old scalers
     74 //
     75 	for (i=1;i<MAXSCALEHEIGHT;i++)
     76 	{
     77 		if (scaledirectory[i])
     78 			MM_FreePtr (&(memptr)scaledirectory[i]);
     79 		if (i>=stepbytwo)
     80 			i += 2;
     81 	}
     82 	memset (scaledirectory,0,sizeof(scaledirectory));
     83 
     84 	MM_SortMem ();
     85 
     86 //
     87 // build the compiled scalers
     88 //
     89 	stepbytwo = viewheight/2;	// save space by double stepping
     90 	MM_GetPtr (&(memptr)work,20000);
     91 
     92 	for (i=1;i<=maxscaleheight;i++)
     93 	{
     94 		BuildCompScale (i*2,&(memptr)scaledirectory[i]);
     95 		if (i>=stepbytwo)
     96 			i+= 2;
     97 	}
     98 	MM_FreePtr (&(memptr)work);
     99 
    100 //
    101 // compact memory and lock down scalers
    102 //
    103 	MM_SortMem ();
    104 	for (i=1;i<=maxscaleheight;i++)
    105 	{
    106 		MM_SetLock (&(memptr)scaledirectory[i],true);
    107 		fullscalefarcall[i] = (unsigned)scaledirectory[i];
    108 		fullscalefarcall[i] <<=16;
    109 		fullscalefarcall[i] += scaledirectory[i]->codeofs[0];
    110 		if (i>=stepbytwo)
    111 		{
    112 			scaledirectory[i+1] = scaledirectory[i];
    113 			fullscalefarcall[i+1] = fullscalefarcall[i];
    114 			scaledirectory[i+2] = scaledirectory[i];
    115 			fullscalefarcall[i+2] = fullscalefarcall[i];
    116 			i+=2;
    117 		}
    118 	}
    119 	scaledirectory[0] = scaledirectory[1];
    120 	fullscalefarcall[0] = fullscalefarcall[1];
    121 
    122 //
    123 // check for oversize wall drawing
    124 //
    125 	for (i=maxscaleheight;i<MAXSCALEHEIGHT;i++)
    126 		fullscalefarcall[i] = (long)BadScale;
    127 
    128 	insetupscaling = false;
    129 }
    130 
    131 //===========================================================================
    132 
    133 /*
    134 ========================
    135 =
    136 = BuildCompScale
    137 =
    138 = Builds a compiled scaler object that will scale a 64 tall object to
    139 = the given height (centered vertically on the screen)
    140 =
    141 = height should be even
    142 =
    143 = Call with
    144 = ---------
    145 = DS:SI		Source for scale
    146 = ES:DI		Dest for scale
    147 =
    148 = Calling the compiled scaler only destroys AL
    149 =
    150 ========================
    151 */
    152 
    153 unsigned BuildCompScale (int height, memptr *finalspot)
    154 {
    155 	byte		far *code;
    156 
    157 	int			i;
    158 	long		fix,step;
    159 	unsigned	src,totalscaled,totalsize;
    160 	int			startpix,endpix,toppix;
    161 
    162 
    163 	step = ((long)height<<16) / 64;
    164 	code = &work->code[0];
    165 	toppix = (viewheight-height)/2;
    166 	fix = 0;
    167 
    168 	for (src=0;src<=64;src++)
    169 	{
    170 		startpix = fix>>16;
    171 		fix += step;
    172 		endpix = fix>>16;
    173 
    174 		if (endpix>startpix)
    175 			work->width[src] = endpix-startpix;
    176 		else
    177 			work->width[src] = 0;
    178 
    179 //
    180 // mark the start of the code
    181 //
    182 		work->codeofs[src] = FP_OFF(code);
    183 
    184 //
    185 // compile some code if the source pixel generates any screen pixels
    186 //
    187 		startpix+=toppix;
    188 		endpix+=toppix;
    189 
    190 		if (startpix == endpix || endpix < 0 || startpix >= viewheight || src == 64)
    191 			continue;
    192 
    193 	//
    194 	// mov al,[si+src]
    195 	//
    196 		*code++ = 0x8a;
    197 		*code++ = 0x44;
    198 		*code++ = src;
    199 
    200 		for (;startpix<endpix;startpix++)
    201 		{
    202 			if (startpix >= viewheight)
    203 				break;						// off the bottom of the view area
    204 			if (startpix < 0)
    205 				continue;					// not into the view area
    206 
    207 		//
    208 		// mov [es:di+heightofs],al
    209 		//
    210 			*code++ = 0x26;
    211 			*code++ = 0x88;
    212 			*code++ = 0x85;
    213 			*((unsigned far *)code)++ = startpix*SCREENBWIDE;
    214 		}
    215 
    216 	}
    217 
    218 //
    219 // retf
    220 //
    221 	*code++ = 0xcb;
    222 
    223 	totalsize = FP_OFF(code);
    224 	MM_GetPtr (finalspot,totalsize);
    225 	_fmemcpy ((byte _seg *)(*finalspot),(byte _seg *)work,totalsize);
    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 _seg *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)=(unsigned)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 _seg *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)=(unsigned)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