wolf3d

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

OLDSCALE.C (15341B)


      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