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

📄 p_sight.c

📁 The source code of Doom legacy for windows
💻 C
字号:
// Emacs style mode select   -*- C++ -*- //-----------------------------------------------------------------------------//// $Id: p_sight.c,v 1.3 2001/01/25 22:15:44 bpereira Exp $//// Copyright (C) 1993-1996 by id Software, Inc.// Portions Copyright (C) 1998-2000 by DooM Legacy Team.//// This program is free software; you can redistribute it and/or// modify it under the terms of the GNU General Public License// as published by the Free Software Foundation; either version 2// of the License, or (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.////// $Log: p_sight.c,v $// Revision 1.3  2001/01/25 22:15:44  bpereira// added heretic support//// Revision 1.2  2000/02/27 00:42:10  hurdler// fix CR+LF problem//// Revision 1.1.1.1  2000/02/22 20:32:32  hurdler// Initial import into CVS (v1.29 pr3)////// DESCRIPTION://      LineOfSight/Visibility checks, uses REJECT Lookup Table.////-----------------------------------------------------------------------------#include "doomdef.h"#include "doomstat.h"#include "p_local.h"#include "r_main.h"#include "r_state.h"//// P_CheckSight//fixed_t         sightzstart;            // eye z of lookerfixed_t         topslope;fixed_t         bottomslope;            // slopes to top and bottom of targetdivline_t       strace;                 // from t1 to t2fixed_t         t2x;fixed_t         t2y;int             sightcounts[2];//// P_DivlineSide// Returns side 0 (front), 1 (back), or 2 (on).//static int P_DivlineSide( fixed_t x, fixed_t y, divline_t* node ){    fixed_t     dx;    fixed_t     dy;    fixed_t     left;    fixed_t     right;    if (!node->dx)    {        if (x==node->x)            return 2;        if (x <= node->x)            return node->dy > 0;        return node->dy < 0;    }    if (!node->dy)    {        if (x==node->y)            return 2;        if (y <= node->y)            return node->dx < 0;        return node->dx > 0;    }    dx = (x - node->x);    dy = (y - node->y);    left =  (node->dy>>FRACBITS) * (dx>>FRACBITS);    right = (dy>>FRACBITS) * (node->dx>>FRACBITS);    if (right < left)        return 0;       // front side    if (left == right)        return 2;    return 1;           // back side}//// P_InterceptVector2// Returns the fractional intercept point// along the first divline.// This is only called by the addthings and addlines traversers.//static fixed_t P_InterceptVector2( divline_t* v2, divline_t* v1 ){    fixed_t     frac;    fixed_t     num;    fixed_t     den;    den = FixedMul (v1->dy>>8,v2->dx) - FixedMul(v1->dx>>8,v2->dy);    if (den == 0)        return 0;    //  I_Error ("P_InterceptVector: parallel");    num = FixedMul ( (v1->x - v2->x)>>8 ,v1->dy) +        FixedMul ( (v2->y - v1->y)>>8 , v1->dx);    frac = FixedDiv (num , den);    return frac;}//// P_CrossSubsector// Returns true//  if strace crosses the given subsector successfully.//static boolean P_CrossSubsector (int num){    seg_t*              seg;    line_t*             line;    int                 s1;    int                 s2;    int                 count;    subsector_t*        sub;    sector_t*           front;    sector_t*           back;    fixed_t             opentop;    fixed_t             openbottom;    divline_t           divl;    vertex_t*           v1;    vertex_t*           v2;    fixed_t             frac;    fixed_t             slope;#ifdef RANGECHECK    if (num>=numsubsectors)        I_Error ("P_CrossSubsector: ss %i with numss = %i",                 num,                 numsubsectors);#endif    sub = &subsectors[num];    // check lines    count = sub->numlines;    seg = &segs[sub->firstline];    for ( ; count ; seg++, count--)    {        line = seg->linedef;        // allready checked other side?        if (line->validcount == validcount)            continue;        line->validcount = validcount;        v1 = line->v1;        v2 = line->v2;        s1 = P_DivlineSide (v1->x,v1->y, &strace);        s2 = P_DivlineSide (v2->x, v2->y, &strace);        // line isn't crossed?        if (s1 == s2)            continue;        divl.x = v1->x;        divl.y = v1->y;        divl.dx = v2->x - v1->x;        divl.dy = v2->y - v1->y;        s1 = P_DivlineSide (strace.x, strace.y, &divl);        s2 = P_DivlineSide (t2x, t2y, &divl);        // line isn't crossed?        if (s1 == s2)            continue;        // stop because it is not two sided anyway        // might do this after updating validcount?        if ( !(line->flags & ML_TWOSIDED) )            return false;        // crosses a two sided line        front = seg->frontsector;        back = seg->backsector;        // no wall to block sight with?        if (front->floorheight == back->floorheight            && front->ceilingheight == back->ceilingheight)            continue;        // possible occluder        // because of ceiling height differences        if (front->ceilingheight < back->ceilingheight)            opentop = front->ceilingheight;        else            opentop = back->ceilingheight;        // because of ceiling height differences        if (front->floorheight > back->floorheight)            openbottom = front->floorheight;        else            openbottom = back->floorheight;        // quick test for totally closed doors        if (openbottom >= opentop)            return false;               // stop        frac = P_InterceptVector2 (&strace, &divl);        if (front->floorheight != back->floorheight)        {            slope = FixedDiv (openbottom - sightzstart , frac);            if (slope > bottomslope)                bottomslope = slope;        }        if (front->ceilingheight != back->ceilingheight)        {            slope = FixedDiv (opentop - sightzstart , frac);            if (slope < topslope)                topslope = slope;        }        if (topslope <= bottomslope)            return false;               // stop    }    // passed the subsector ok    return true;}//// P_CrossBSPNode// Returns true//  if strace crosses the given node successfully.//static boolean P_CrossBSPNode (int bspnum){    node_t*     bsp;    int         side;    if (bspnum & NF_SUBSECTOR)    {        if (bspnum == -1)            return P_CrossSubsector (0);        else            return P_CrossSubsector (bspnum&(~NF_SUBSECTOR));    }    bsp = &nodes[bspnum];    // decide which side the start point is on    side = P_DivlineSide (strace.x, strace.y, (divline_t *)bsp);    if (side == 2)        side = 0;       // an "on" should cross both sides    // cross the starting side    if (!P_CrossBSPNode (bsp->children[side]) )        return false;    // the partition plane is crossed here    if (side == P_DivlineSide (t2x, t2y,(divline_t *)bsp))    {        // the line doesn't touch the other side        return true;    }    // cross the ending side    return P_CrossBSPNode (bsp->children[side^1]);}//// P_CheckSight// Returns true//  if a straight line between t1 and t2 is unobstructed.// Uses REJECT.//boolean P_CheckSight( mobj_t* t1, mobj_t* t2 ){    int         s1;    int         s2;    int         pnum;    int         bytenum;    int         bitnum;    // First check for trivial rejection.    // Determine subsector entries in REJECT table.    s1 = (t1->subsector->sector - sectors);    s2 = (t2->subsector->sector - sectors);    pnum = s1*numsectors + s2;    bytenum = pnum>>3;    bitnum = 1 << (pnum&7);    // Check in REJECT table.    if (rejectmatrix[bytenum]&bitnum)    {        sightcounts[0]++;        // can't possibly be connected        return false;    }    if (gamemode == heretic )    {        //        // check precisely        //                      sightzstart = t1->z + t1->height - (t1->height>>2);        topslope = (t2->z+t2->height) - sightzstart;        bottomslope = (t2->z) - sightzstart;                return P_SightPathTraverse ( t1->x, t1->y, t2->x, t2->y );    }        // An unobstructed LOS is possible.    // Now look from eyes of t1 to any part of t2.    sightcounts[1]++;    validcount++;    sightzstart = t1->z + t1->height - (t1->height>>2);    topslope = (t2->z+t2->height) - sightzstart;    bottomslope = (t2->z) - sightzstart;    strace.x = t1->x;    strace.y = t1->y;    t2x = t2->x;    t2y = t2->y;    strace.dx = t2->x - t1->x;    strace.dy = t2->y - t1->y;    // the head node is the last node output    return P_CrossBSPNode (numnodes-1);}

⌨️ 快捷键说明

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