wolf3d

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

ID_VH.C (9970B)


      1 // ID_VH.C
      2 
      3 #include "ID_HEADS.H"
      4 
      5 #define	SCREENWIDTH		80
      6 #define CHARWIDTH		2
      7 #define TILEWIDTH		4
      8 #define GRPLANES		4
      9 #define BYTEPIXELS		4
     10 
     11 #define SCREENXMASK		(~3)
     12 #define SCREENXPLUS		(3)
     13 #define SCREENXDIV		(4)
     14 
     15 #define VIEWWIDTH		80
     16 
     17 #define PIXTOBLOCK		4		// 16 pixels to an update block
     18 
     19 #define UNCACHEGRCHUNK(chunk)	{MM_FreePtr(&grsegs[chunk]);grneeded[chunk]&=~ca_levelbit;}
     20 
     21 byte	update[UPDATEHIGH][UPDATEWIDE];
     22 
     23 //==========================================================================
     24 
     25 pictabletype	_seg *pictable;
     26 
     27 
     28 int	px,py;
     29 byte	fontcolor,backcolor;
     30 int	fontnumber;
     31 int bufferwidth,bufferheight;
     32 
     33 
     34 //==========================================================================
     35 
     36 void	VWL_UpdateScreenBlocks (void);
     37 
     38 //==========================================================================
     39 
     40 void VW_DrawPropString (char far *string)
     41 {
     42 	fontstruct	far	*font;
     43 	int		width,step,height,i;
     44 	byte	far *source, far *dest, far *origdest;
     45 	byte	ch,mask;
     46 
     47 	font = (fontstruct far *)grsegs[STARTFONT+fontnumber];
     48 	height = bufferheight = font->height;
     49 	dest = origdest = MK_FP(SCREENSEG,bufferofs+ylookup[py]+(px>>2));
     50 	mask = 1<<(px&3);
     51 
     52 
     53 	while ((ch = *string++)!=0)
     54 	{
     55 		width = step = font->width[ch];
     56 		source = ((byte far *)font)+font->location[ch];
     57 		while (width--)
     58 		{
     59 			VGAMAPMASK(mask);
     60 
     61 asm	mov	ah,[BYTE PTR fontcolor]
     62 asm	mov	bx,[step]
     63 asm	mov	cx,[height]
     64 asm	mov	dx,[linewidth]
     65 asm	lds	si,[source]
     66 asm	les	di,[dest]
     67 
     68 vertloop:
     69 asm	mov	al,[si]
     70 asm	or	al,al
     71 asm	je	next
     72 asm	mov	[es:di],ah			// draw color
     73 
     74 next:
     75 asm	add	si,bx
     76 asm	add	di,dx
     77 asm	loop	vertloop
     78 asm	mov	ax,ss
     79 asm	mov	ds,ax
     80 
     81 			source++;
     82 			px++;
     83 			mask <<= 1;
     84 			if (mask == 16)
     85 			{
     86 				mask = 1;
     87 				dest++;
     88 			}
     89 		}
     90 	}
     91 bufferheight = height;
     92 bufferwidth = ((dest+1)-origdest)*4;
     93 }
     94 
     95 
     96 void VW_DrawColorPropString (char far *string)
     97 {
     98 	fontstruct	far	*font;
     99 	int		width,step,height,i;
    100 	byte	far *source, far *dest, far *origdest;
    101 	byte	ch,mask;
    102 
    103 	font = (fontstruct far *)grsegs[STARTFONT+fontnumber];
    104 	height = bufferheight = font->height;
    105 	dest = origdest = MK_FP(SCREENSEG,bufferofs+ylookup[py]+(px>>2));
    106 	mask = 1<<(px&3);
    107 
    108 
    109 	while ((ch = *string++)!=0)
    110 	{
    111 		width = step = font->width[ch];
    112 		source = ((byte far *)font)+font->location[ch];
    113 		while (width--)
    114 		{
    115 			VGAMAPMASK(mask);
    116 
    117 asm	mov	ah,[BYTE PTR fontcolor]
    118 asm	mov	bx,[step]
    119 asm	mov	cx,[height]
    120 asm	mov	dx,[linewidth]
    121 asm	lds	si,[source]
    122 asm	les	di,[dest]
    123 
    124 vertloop:
    125 asm	mov	al,[si]
    126 asm	or	al,al
    127 asm	je	next
    128 asm	mov	[es:di],ah			// draw color
    129 
    130 next:
    131 asm	add	si,bx
    132 asm	add	di,dx
    133 
    134 asm rcr cx,1				// inc font color
    135 asm jc  cont
    136 asm	inc ah
    137 
    138 cont:
    139 asm rcl cx,1
    140 asm	loop	vertloop
    141 asm	mov	ax,ss
    142 asm	mov	ds,ax
    143 
    144 			source++;
    145 			px++;
    146 			mask <<= 1;
    147 			if (mask == 16)
    148 			{
    149 				mask = 1;
    150 				dest++;
    151 			}
    152 		}
    153 	}
    154 bufferheight = height;
    155 bufferwidth = ((dest+1)-origdest)*4;
    156 }
    157 
    158 
    159 //==========================================================================
    160 
    161 
    162 /*
    163 =================
    164 =
    165 = VL_MungePic
    166 =
    167 =================
    168 */
    169 
    170 void VL_MungePic (byte far *source, unsigned width, unsigned height)
    171 {
    172 	unsigned	x,y,plane,size,pwidth;
    173 	byte		_seg *temp, far *dest, far *srcline;
    174 
    175 	size = width*height;
    176 
    177 	if (width&3)
    178 		MS_Quit ("VL_MungePic: Not divisable by 4!");
    179 
    180 //
    181 // copy the pic to a temp buffer
    182 //
    183 	MM_GetPtr (&(memptr)temp,size);
    184 	_fmemcpy (temp,source,size);
    185 
    186 //
    187 // munge it back into the original buffer
    188 //
    189 	dest = source;
    190 	pwidth = width/4;
    191 
    192 	for (plane=0;plane<4;plane++)
    193 	{
    194 		srcline = temp;
    195 		for (y=0;y<height;y++)
    196 		{
    197 			for (x=0;x<pwidth;x++)
    198 				*dest++ = *(srcline+x*4+plane);
    199 			srcline+=width;
    200 		}
    201 	}
    202 
    203 	MM_FreePtr (&(memptr)temp);
    204 }
    205 
    206 void VWL_MeasureString (char far *string, word *width, word *height
    207 	, fontstruct _seg *font)
    208 {
    209 	*height = font->height;
    210 	for (*width = 0;*string;string++)
    211 		*width += font->width[*((byte far *)string)];	// proportional width
    212 }
    213 
    214 void	VW_MeasurePropString (char far *string, word *width, word *height)
    215 {
    216 	VWL_MeasureString(string,width,height,(fontstruct _seg *)grsegs[STARTFONT+fontnumber]);
    217 }
    218 
    219 void	VW_MeasureMPropString  (char far *string, word *width, word *height)
    220 {
    221 	VWL_MeasureString(string,width,height,(fontstruct _seg *)grsegs[STARTFONTM+fontnumber]);
    222 }
    223 
    224 
    225 
    226 /*
    227 =============================================================================
    228 
    229 				Double buffer management routines
    230 
    231 =============================================================================
    232 */
    233 
    234 
    235 /*
    236 =======================
    237 =
    238 = VW_MarkUpdateBlock
    239 =
    240 = Takes a pixel bounded block and marks the tiles in bufferblocks
    241 = Returns 0 if the entire block is off the buffer screen
    242 =
    243 =======================
    244 */
    245 
    246 int VW_MarkUpdateBlock (int x1, int y1, int x2, int y2)
    247 {
    248 	int	x,y,xt1,yt1,xt2,yt2,nextline;
    249 	byte *mark;
    250 
    251 	xt1 = x1>>PIXTOBLOCK;
    252 	yt1 = y1>>PIXTOBLOCK;
    253 
    254 	xt2 = x2>>PIXTOBLOCK;
    255 	yt2 = y2>>PIXTOBLOCK;
    256 
    257 	if (xt1<0)
    258 		xt1=0;
    259 	else if (xt1>=UPDATEWIDE)
    260 		return 0;
    261 
    262 	if (yt1<0)
    263 		yt1=0;
    264 	else if (yt1>UPDATEHIGH)
    265 		return 0;
    266 
    267 	if (xt2<0)
    268 		return 0;
    269 	else if (xt2>=UPDATEWIDE)
    270 		xt2 = UPDATEWIDE-1;
    271 
    272 	if (yt2<0)
    273 		return 0;
    274 	else if (yt2>=UPDATEHIGH)
    275 		yt2 = UPDATEHIGH-1;
    276 
    277 	mark = updateptr + uwidthtable[yt1] + xt1;
    278 	nextline = UPDATEWIDE - (xt2-xt1) - 1;
    279 
    280 	for (y=yt1;y<=yt2;y++)
    281 	{
    282 		for (x=xt1;x<=xt2;x++)
    283 			*mark++ = 1;			// this tile will need to be updated
    284 
    285 		mark += nextline;
    286 	}
    287 
    288 	return 1;
    289 }
    290 
    291 void VWB_DrawTile8 (int x, int y, int tile)
    292 {
    293 	if (VW_MarkUpdateBlock (x,y,x+7,y+7))
    294 		LatchDrawChar(x,y,tile);
    295 }
    296 
    297 void VWB_DrawTile8M (int x, int y, int tile)
    298 {
    299 	if (VW_MarkUpdateBlock (x,y,x+7,y+7))
    300 		VL_MemToScreen (((byte far *)grsegs[STARTTILE8M])+tile*64,8,8,x,y);
    301 }
    302 
    303 
    304 void VWB_DrawPic (int x, int y, int chunknum)
    305 {
    306 	int	picnum = chunknum - STARTPICS;
    307 	unsigned width,height;
    308 
    309 	x &= ~7;
    310 
    311 	width = pictable[picnum].width;
    312 	height = pictable[picnum].height;
    313 
    314 	if (VW_MarkUpdateBlock (x,y,x+width-1,y+height-1))
    315 		VL_MemToScreen (grsegs[chunknum],width,height,x,y);
    316 }
    317 
    318 
    319 
    320 void VWB_DrawPropString	 (char far *string)
    321 {
    322 	int x;
    323 	x=px;
    324 	VW_DrawPropString (string);
    325 	VW_MarkUpdateBlock(x,py,px-1,py+bufferheight-1);
    326 }
    327 
    328 
    329 void VWB_Bar (int x, int y, int width, int height, int color)
    330 {
    331 	if (VW_MarkUpdateBlock (x,y,x+width,y+height-1) )
    332 		VW_Bar (x,y,width,height,color);
    333 }
    334 
    335 void VWB_Plot (int x, int y, int color)
    336 {
    337 	if (VW_MarkUpdateBlock (x,y,x,y))
    338 		VW_Plot(x,y,color);
    339 }
    340 
    341 void VWB_Hlin (int x1, int x2, int y, int color)
    342 {
    343 	if (VW_MarkUpdateBlock (x1,y,x2,y))
    344 		VW_Hlin(x1,x2,y,color);
    345 }
    346 
    347 void VWB_Vlin (int y1, int y2, int x, int color)
    348 {
    349 	if (VW_MarkUpdateBlock (x,y1,x,y2))
    350 		VW_Vlin(y1,y2,x,color);
    351 }
    352 
    353 void VW_UpdateScreen (void)
    354 {
    355 	VH_UpdateScreen ();
    356 }
    357 
    358 
    359 /*
    360 =============================================================================
    361 
    362 						WOLFENSTEIN STUFF
    363 
    364 =============================================================================
    365 */
    366 
    367 /*
    368 =====================
    369 =
    370 = LatchDrawPic
    371 =
    372 =====================
    373 */
    374 
    375 void LatchDrawPic (unsigned x, unsigned y, unsigned picnum)
    376 {
    377 	unsigned wide, height, source;
    378 
    379 	wide = pictable[picnum-STARTPICS].width;
    380 	height = pictable[picnum-STARTPICS].height;
    381 	source = latchpics[2+picnum-LATCHPICS_LUMP_START];
    382 
    383 	VL_LatchToScreen (source,wide/4,height,x*8,y);
    384 }
    385 
    386 
    387 //==========================================================================
    388 
    389 /*
    390 ===================
    391 =
    392 = LoadLatchMem
    393 =
    394 ===================
    395 */
    396 
    397 void LoadLatchMem (void)
    398 {
    399 	int	i,j,p,m,width,height,start,end;
    400 	byte	far *src;
    401 	unsigned	destoff;
    402 
    403 //
    404 // tile 8s
    405 //
    406 	latchpics[0] = freelatch;
    407 	CA_CacheGrChunk (STARTTILE8);
    408 	src = (byte _seg *)grsegs[STARTTILE8];
    409 	destoff = freelatch;
    410 
    411 	for (i=0;i<NUMTILE8;i++)
    412 	{
    413 		VL_MemToLatch (src,8,8,destoff);
    414 		src += 64;
    415 		destoff +=16;
    416 	}
    417 	UNCACHEGRCHUNK (STARTTILE8);
    418 
    419 #if 0	// ran out of latch space!
    420 //
    421 // tile 16s
    422 //
    423 	src = (byte _seg *)grsegs[STARTTILE16];
    424 	latchpics[1] = destoff;
    425 
    426 	for (i=0;i<NUMTILE16;i++)
    427 	{
    428 		CA_CacheGrChunk (STARTTILE16+i);
    429 		src = (byte _seg *)grsegs[STARTTILE16+i];
    430 		VL_MemToLatch (src,16,16,destoff);
    431 		destoff+=64;
    432 		if (src)
    433 			UNCACHEGRCHUNK (STARTTILE16+i);
    434 	}
    435 #endif
    436 
    437 //
    438 // pics
    439 //
    440 	start = LATCHPICS_LUMP_START;
    441 	end = LATCHPICS_LUMP_END;
    442 
    443 	for (i=start;i<=end;i++)
    444 	{
    445 		latchpics[2+i-start] = destoff;
    446 		CA_CacheGrChunk (i);
    447 		width = pictable[i-STARTPICS].width;
    448 		height = pictable[i-STARTPICS].height;
    449 		VL_MemToLatch (grsegs[i],width,height,destoff);
    450 		destoff += width/4 *height;
    451 		UNCACHEGRCHUNK(i);
    452 	}
    453 
    454 	EGAMAPMASK(15);
    455 }
    456 
    457 //==========================================================================
    458 
    459 /*
    460 ===================
    461 =
    462 = FizzleFade
    463 =
    464 = returns true if aborted
    465 =
    466 ===================
    467 */
    468 
    469 extern	ControlInfo	c;
    470 
    471 boolean FizzleFade (unsigned source, unsigned dest,
    472 	unsigned width,unsigned height, unsigned frames, boolean abortable)
    473 {
    474 	int			pixperframe;
    475 	unsigned	drawofs,pagedelta;
    476 	byte 		mask,maskb[8] = {1,2,4,8};
    477 	unsigned	x,y,p,frame;
    478 	long		rndval;
    479 
    480 	pagedelta = dest-source;
    481 	rndval = 1;
    482 	y = 0;
    483 	pixperframe = 64000/frames;
    484 
    485 	IN_StartAck ();
    486 
    487 	TimeCount=frame=0;
    488 	do	// while (1)
    489 	{
    490 		if (abortable && IN_CheckAck () )
    491 			return true;
    492 
    493 		asm	mov	es,[screenseg]
    494 
    495 		for (p=0;p<pixperframe;p++)
    496 		{
    497 			//
    498 			// seperate random value into x/y pair
    499 			//
    500 			asm	mov	ax,[WORD PTR rndval]
    501 			asm	mov	dx,[WORD PTR rndval+2]
    502 			asm	mov	bx,ax
    503 			asm	dec	bl
    504 			asm	mov	[BYTE PTR y],bl			// low 8 bits - 1 = y xoordinate
    505 			asm	mov	bx,ax
    506 			asm	mov	cx,dx
    507 			asm	mov	[BYTE PTR x],ah			// next 9 bits = x xoordinate
    508 			asm	mov	[BYTE PTR x+1],dl
    509 			//
    510 			// advance to next random element
    511 			//
    512 			asm	shr	dx,1
    513 			asm	rcr	ax,1
    514 			asm	jnc	noxor
    515 			asm	xor	dx,0x0001
    516 			asm	xor	ax,0x2000
    517 noxor:
    518 			asm	mov	[WORD PTR rndval],ax
    519 			asm	mov	[WORD PTR rndval+2],dx
    520 
    521 			if (x>width || y>height)
    522 				continue;
    523 			drawofs = source+ylookup[y] + (x>>2);
    524 
    525 			//
    526 			// copy one pixel
    527 			//
    528 			mask = x&3;
    529 			VGAREADMAP(mask);
    530 			mask = maskb[mask];
    531 			VGAMAPMASK(mask);
    532 
    533 			asm	mov	di,[drawofs]
    534 			asm	mov	al,[es:di]
    535 			asm add	di,[pagedelta]
    536 			asm	mov	[es:di],al
    537 
    538 			if (rndval == 1)		// entire sequence has been completed
    539 				return false;
    540 		}
    541 		frame++;
    542 		while (TimeCount<frame)		// don't go too fast
    543 		;
    544 	} while (1);
    545 
    546 
    547 }