⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 r_things.c

📁 使用Doom引擎开发的著名游戏《毁灭巫师》的源代码。
💻 C
📖 第 1 页 / 共 2 页
字号:
//**************************************************************************//**//** r_things.c : Heretic 2 : Raven Software, Corp.//**//** $RCSfile: r_things.c,v $//** $Revision: 1.26 $//** $Date: 96/01/06 18:37:42 $//** $Author: bgokey $//**//**************************************************************************#include <stdio.h>#include <stdlib.h>#include "h2def.h"#include "r_local.h"void R_DrawColumn (void);void R_DrawFuzzColumn (void);void R_DrawAltFuzzColumn(void);//void R_DrawTranslatedAltFuzzColumn(void);typedef struct{	int		x1, x2;	int		column;	int		topclip;	int		bottomclip;} maskdraw_t;/*Sprite rotation 0 is facing the viewer, rotation 1 is one angle turn CLOCKWISE around the axis.This is not the same as the angle, which increases counter clockwise(protractor).  There was a lot of stuff grabbed wrong, so I changed it...*/fixed_t		pspritescale, pspriteiscale;lighttable_t	**spritelights;// constant arrays used for psprite clipping and initializing clippingshort	negonearray[SCREENWIDTH];short	screenheightarray[SCREENWIDTH];boolean LevelUseFullBright;/*===============================================================================						INITIALIZATION FUNCTIONS===============================================================================*/// variables used to look up and range check thing_t sprites patchesspritedef_t		*sprites;int				numsprites;spriteframe_t	sprtemp[30];int				maxframe;char			*spritename;/*=================== R_InstallSpriteLump== Local function for R_InitSprites=================*/void R_InstallSpriteLump (int lump, unsigned frame, unsigned rotation, boolean flipped){	int		r;	if (frame >= 30 || rotation > 8)		I_Error ("R_InstallSpriteLump: Bad frame characters in lump %i", lump);	if ((int)frame > maxframe)		maxframe = frame;	if (rotation == 0)	{// the lump should be used for all rotations		if (sprtemp[frame].rotate == false)			I_Error ("R_InitSprites: Sprite %s frame %c has multip rot=0 lump"			, spritename, 'A'+frame);		if (sprtemp[frame].rotate == true)			I_Error ("R_InitSprites: Sprite %s frame %c has rotations and a rot=0 lump"			, spritename, 'A'+frame);		sprtemp[frame].rotate = false;		for (r=0 ; r<8 ; r++)		{			sprtemp[frame].lump[r] = lump - firstspritelump;			sprtemp[frame].flip[r] = (byte)flipped;		}		return;	}// the lump is only used for one rotation	if (sprtemp[frame].rotate == false)		I_Error ("R_InitSprites: Sprite %s frame %c has rotations and a rot=0 lump"		, spritename, 'A'+frame);	sprtemp[frame].rotate = true;	rotation--;		// make 0 based	if (sprtemp[frame].lump[rotation] != -1)		I_Error ("R_InitSprites: Sprite %s : %c : %c has two lumps mapped to it"		,spritename, 'A'+frame, '1'+rotation);	sprtemp[frame].lump[rotation] = lump - firstspritelump;	sprtemp[frame].flip[rotation] = (byte)flipped;}/*
=================
=
= R_InitSpriteDefs== Pass a null terminated list of sprite names (4 chars exactly) to be used= Builds the sprite rotation matrixes to account for horizontally flipped= sprites.  Will report an error if the lumps are inconsistant=
Only called at startup== Sprite lump names are 4 characters for the actor, a letter for the frame,= and a number for the rotation, A sprite that is flippable will have an= additional letter/number appended.  The rotation character can be 0 to= signify no rotations=================
*/

void R_InitSpriteDefs (char **namelist)
{
	char		**check;	int		i, l, intname, frame, rotation;	int		start, end;// count the number of sprite names	check = namelist;	while (*check != NULL)		check++;	numsprites = check-namelist;	if (!numsprites)		return;	sprites = Z_Malloc(numsprites *sizeof(*sprites), PU_STATIC, NULL);	start = firstspritelump-1;	end = lastspritelump+1;// scan all the lump names for each of the names, noting the highest// frame letter// Just compare 4 characters as ints	for (i=0 ; i<numsprites ; i++)	{		spritename = namelist[i];		memset (sprtemp,-1, sizeof(sprtemp));		maxframe = -1;		intname = *(int *)namelist[i];		//		// scan the lumps, filling in the frames for whatever is found		//		for (l=start+1 ; l<end ; l++)			if (*(int *)lumpinfo[l].name == intname)			{				frame = lumpinfo[l].name[4] - 'A';				rotation = lumpinfo[l].name[5] - '0';				R_InstallSpriteLump (l, frame, rotation, false);				if (lumpinfo[l].name[6])				{					frame = lumpinfo[l].name[6] - 'A';					rotation = lumpinfo[l].name[7] - '0';					R_InstallSpriteLump (l, frame, rotation, true);				}			}		//		// check the frames that were found for completeness		//		if (maxframe == -1)		{			//continue;			sprites[i].numframes = 0;			if (shareware)				continue;			I_Error ("R_InitSprites: No lumps found for sprite %s"			,namelist[i]);		}		maxframe++;		for (frame = 0 ; frame < maxframe ; frame++)		{			switch ((int)sprtemp[frame].rotate)			{			case -1:	// no rotations were found for that frame at all				I_Error ("R_InitSprites: No patches found for %s frame %c"				, namelist[i], frame+'A');			case 0:	// only the first rotation is needed				break;			case 1:	// must have all 8 frames				for (rotation=0 ; rotation<8 ; rotation++)					if (sprtemp[frame].lump[rotation] == -1)						I_Error ("R_InitSprites: Sprite %s frame %c is missing rotations"						, namelist[i], frame+'A');			}		}		//		// allocate space for the frames present and copy sprtemp to it		//		sprites[i].numframes = maxframe;		sprites[i].spriteframes =			Z_Malloc (maxframe * sizeof(spriteframe_t), PU_STATIC, NULL);		memcpy (sprites[i].spriteframes, sprtemp, maxframe*sizeof(spriteframe_t));	}}/*===============================================================================							GAME FUNCTIONS===============================================================================*/vissprite_t	vissprites[MAXVISSPRITES], *vissprite_p;int			newvissprite;/*===================== R_InitSprites== Called at program start===================*/void R_InitSprites (char **namelist){	int		i;	for (i=0 ; i<SCREENWIDTH ; i++)	{		negonearray[i] = -1;	}	R_InitSpriteDefs (namelist);}/*===================== R_ClearSprites== Called at frame start===================*/void R_ClearSprites (void){	vissprite_p = vissprites;}/*===================== R_NewVisSprite====================*/vissprite_t		overflowsprite;vissprite_t *R_NewVisSprite (void){	if (vissprite_p == &vissprites[MAXVISSPRITES])		return &overflowsprite;	vissprite_p++;	return vissprite_p-1;}/*================== R_DrawMaskedColumn== Used for sprites and masked mid textures================*/short		*mfloorclip;short		*mceilingclip;fixed_t		spryscale;fixed_t		sprtopscreen;fixed_t		sprbotscreen;void R_DrawMaskedColumn (column_t *column, signed int baseclip){	int		topscreen, bottomscreen;	fixed_t	basetexturemid;	basetexturemid = dc_texturemid;	for ( ; column->topdelta != 0xff ; )
	{// calculate unclipped screen coordinates for post		topscreen = sprtopscreen + spryscale*column->topdelta;		bottomscreen = topscreen + spryscale*column->length;		dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS;		dc_yh = (bottomscreen-1)>>FRACBITS;		if (dc_yh >= mfloorclip[dc_x])			dc_yh = mfloorclip[dc_x]-1;		if (dc_yl <= mceilingclip[dc_x])			dc_yl = mceilingclip[dc_x]+1;		if(dc_yh >= baseclip && baseclip != -1)			dc_yh = baseclip;		if (dc_yl <= dc_yh)		{			dc_source = (byte *)column + 3;			dc_texturemid = basetexturemid - (column->topdelta<<FRACBITS);//			dc_source = (byte *)column + 3 - column->topdelta;			colfunc ();		// either R_DrawColumn or R_DrawFuzzColumn		}		column = (column_t *)(  (byte *)column + column->length + 4);	}	dc_texturemid = basetexturemid;}/*================== R_DrawVisSprite== mfloorclip and mceilingclip should also be set================*/void R_DrawVisSprite (vissprite_t *vis, int x1, int x2){	column_t	*column;	int			texturecolumn;	fixed_t		frac;	patch_t		*patch;	fixed_t		baseclip;	patch = W_CacheLumpNum(vis->patch+firstspritelump, PU_CACHE);	dc_colormap = vis->colormap;//	if(!dc_colormap)//		colfunc = fuzzcolfunc;	// NULL colormap = shadow draw	if(vis->mobjflags&(MF_SHADOW|MF_ALTSHADOW))	{		if(vis->mobjflags&MF_TRANSLATION)		{			colfunc = R_DrawTranslatedFuzzColumn;			dc_translation = translationtables-256				+vis->class*((MAXPLAYERS-1)*256)+				((vis->mobjflags&MF_TRANSLATION)>>(MF_TRANSSHIFT-8));		}		else if(vis->mobjflags&MF_SHADOW)		{ // Draw using shadow column function			colfunc = fuzzcolfunc;		}		else		{			colfunc = R_DrawAltFuzzColumn;		}	}	else if(vis->mobjflags&MF_TRANSLATION)	{		// Draw using translated column function		colfunc = R_DrawTranslatedColumn;		dc_translation = translationtables-256			+vis->class*((MAXPLAYERS-1)*256)+			((vis->mobjflags&MF_TRANSLATION)>>(MF_TRANSSHIFT-8));	}	dc_iscale = abs(vis->xiscale)>>detailshift;	dc_texturemid = vis->texturemid;	frac = vis->startfrac;	spryscale = vis->scale;	sprtopscreen = centeryfrac - FixedMul(dc_texturemid,spryscale);	// check to see if vissprite is a weapon	if(vis->psprite)	{		dc_texturemid += FixedMul(((centery-viewheight/2)<<FRACBITS),			vis->xiscale);		sprtopscreen += (viewheight/2-centery)<<FRACBITS;	}	if(vis->floorclip && !vis->psprite)	{		sprbotscreen = sprtopscreen+FixedMul(patch->height<<FRACBITS,			spryscale);		baseclip = (sprbotscreen-FixedMul(vis->floorclip, 			spryscale))>>FRACBITS;	}	else	{		baseclip = -1;	}	for (dc_x=vis->x1 ; dc_x<=vis->x2 ; dc_x++, frac += vis->xiscale)	{		texturecolumn = frac>>FRACBITS;#ifdef RANGECHECK		if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width))			I_Error ("R_DrawSpriteRange: bad texturecolumn");#endif		column = (column_t *) ((byte *)patch +		 LONG(patch->columnofs[texturecolumn]));		 R_DrawMaskedColumn (column, baseclip);	}	colfunc = basecolfunc;}/*===================== R_ProjectSprite== Generates a vissprite for a thing if it might be visible====================*/void R_ProjectSprite (mobj_t *thing){	fixed_t		trx,try;	fixed_t		gxt,gyt;	fixed_t		tx,tz;	fixed_t		xscale;	int			x1, x2;	spritedef_t	*sprdef;	spriteframe_t	*sprframe;	int			lump;	unsigned	rot;	boolean		flip;	int			index;	vissprite_t	*vis;	angle_t		ang;	fixed_t		iscale;	if(thing->flags2&MF2_DONTDRAW)	{ // Never make a vissprite when MF2_DONTDRAW is flagged.		return;	}//// transform the origin point//	trx = thing->x - viewx;	try = thing->y - viewy;	gxt = FixedMul(trx,viewcos);
	gyt = -FixedMul(try,viewsin);
	tz = gxt-gyt;
	if (tz < MINZ)		return;		// thing is behind view plane	xscale = FixedDiv(projection, tz);	gxt = -FixedMul(trx,viewsin);
	gyt = FixedMul(try,viewcos);
	tx = -(gyt+gxt);
	
	if (abs(tx)>(tz<<2))		return;		// too far off the side//// decide which patch to use for sprite reletive to player//#ifdef RANGECHECK	if ((unsigned)thing->sprite >= numsprites)		I_Error ("R_ProjectSprite: invalid sprite number %i ",thing->sprite);#endif	sprdef = &sprites[thing->sprite];#ifdef RANGECHECK	if ( (thing->frame&FF_FRAMEMASK) >= sprdef->numframes )		I_Error ("R_ProjectSprite: invalid sprite frame %i : %i "		,thing->sprite, thing->frame);#endif	sprframe = &sprdef->spriteframes[ thing->frame & FF_FRAMEMASK];	if (sprframe->rotate)	{	// choose a different rotation based on player view		ang = R_PointToAngle (thing->x, thing->y);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -