📄 r_things.c
字号:
//**************************************************************************//**//** 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 + -