Beispiel #1
0
    static void PF_checkclient()
    {
        // find a new check if on a new frame
        if (sv.time - sv.lastchecktime >= 0.1)
        {
            sv.lastcheck     = PF_newcheckclient(sv.lastcheck);
            sv.lastchecktime = sv.time;
        }

        // return check if it might be visible
        edict_t ent = EDICT_NUM(sv.lastcheck);

        if (ent.free || ent.v.health <= 0)
        {
            RETURN_EDICT(sv.edicts[0]);
            return;
        }

        // if current entity can't possibly see the check entity, return 0
        edict_t self = PROG_TO_EDICT(pr_global_struct.self);
        Vector3 view = ToVector(ref self.v.origin) + ToVector(ref self.v.view_ofs);
        mleaf_t leaf = Mod_PointInLeaf(ref view, sv.worldmodel);
        int     l    = Array.IndexOf(sv.worldmodel.leafs, leaf) - 1;

        if ((l < 0) || (checkpvs[l >> 3] & (1 << (l & 7))) == 0)
        {
            c_notvis++;
            RETURN_EDICT(sv.edicts[0]);
            return;
        }

        // might be able to see it
        c_invis++;
        RETURN_EDICT(ent);
    }
Beispiel #2
0
        public virtual void Mod_LoadLeafs(lump_t l)
        {
            qfiles.dleaf_t in_renamed;
            mleaf_t[]      out_renamed;
            Int32          i, j, count;

            if ((l.filelen % qfiles.dleaf_t.SIZE) != 0)
            {
                Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in " + loadmodel.name);
            }
            count              = l.filelen / qfiles.dleaf_t.SIZE;
            out_renamed        = new mleaf_t[count];
            loadmodel.leafs    = out_renamed;
            loadmodel.numleafs = count;
            ByteBuffer bb = ByteBuffer.Wrap(mod_base, l.fileofs, l.filelen);

            bb.Order = ByteOrder.LittleEndian;
            for (i = 0; i < count; i++)
            {
                in_renamed     = new dleaf_t(bb);
                out_renamed[i] = new mleaf_t();
                for (j = 0; j < 3; j++)
                {
                    out_renamed[i].mins[j] = in_renamed.mins[j];
                    out_renamed[i].maxs[j] = in_renamed.maxs[j];
                }

                out_renamed[i].contents = in_renamed.contents;
                out_renamed[i].cluster  = in_renamed.cluster;
                out_renamed[i].area     = in_renamed.area;
                out_renamed[i].SetMarkSurface(in_renamed.firstleafface, loadmodel.marksurfaces);
                out_renamed[i].nummarksurfaces = in_renamed.numleaffaces;
            }
        }
Beispiel #3
0
    public static void R_SetupFrame()
    {
        // don't allow cheats in multiplayer
        if (cl.maxclients > 1)
        {
            Cvar.Cvar_Set("r_fullbright", "0");
        }

        R_AnimateLight();

        r_framecount++;

        // build the transformation matrix for the given view angles
        r_origin = r_refdef.vieworg;

        Mathlib.AngleVectors(ref r_refdef.viewangles, out vpn, out vright, out vup);

        // current viewleaf
        r_oldviewleaf = r_viewleaf;
        r_viewleaf    = Mod_PointInLeaf(ref r_origin, cl.worldmodel);

        game_engine.V_SetContentsColor(r_viewleaf.contents);
        game_engine.V_CalcBlend();

        r_cache_thrash = false;
        c_brush_polys  = 0;
        c_alias_polys  = 0;
    }
Beispiel #4
0
    static void S_UpdateAmbientSounds()
    {
        if (!snd_ambient)
        {
            return;
        }

        // calc ambient sound levels
        if (cl.worldmodel == null)
        {
            return;
        }

        mleaf_t l = Mod_PointInLeaf(ref listener_origin, cl.worldmodel);

        if (l == null || ambient_level.value == 0)
        {
            for (int i = 0; i < q_shared.NUM_AMBIENTS; i++)
            {
                channels[i].sfx = null;
            }
            return;
        }

        for (int i = 0; i < q_shared.NUM_AMBIENTS; i++)
        {
            channel_t chan = channels[i];
            chan.sfx = ambient_sfx[i];

            float vol = ambient_level.value * l.ambient_sound_level[i];
            if (vol < 8)
            {
                vol = 0;
            }

            // don't adjust volume too fast
            if (chan.master_vol < vol)
            {
                chan.master_vol += (int)(host_framtime * ambient_fade.value);
                if (chan.master_vol > vol)
                {
                    chan.master_vol = (int)vol;
                }
            }
            else if (chan.master_vol > vol)
            {
                chan.master_vol -= (int)(host_framtime * ambient_fade.value);
                if (chan.master_vol < vol)
                {
                    chan.master_vol = (int)vol;
                }
            }

            chan.leftvol = chan.rightvol = chan.master_vol;
        }
    }
Beispiel #5
0
    public static void R_NewMap()
    {
        for (int i = 0; i < 256; i++)
        {
            d_lightstylevalue[i] = 264;         // normal light value
        }
        r_worldentity.Clear();
        r_worldentity.model = cl.worldmodel;

        // clear out efrags in case the level hasn't been reloaded
        // FIXME: is this one short?
        for (int i = 0; i < cl.worldmodel.numleafs; i++)
        {
            cl.worldmodel.leafs[i].efrags = null;
        }

        r_viewleaf = null;
        R_ClearParticles();

        GL_BuildLightmaps();

        // identify sky texture
        skytexturenum    = -1;
        mirrortexturenum = -1;
        model_t world = cl.worldmodel;

        for (int i = 0; i < world.numtextures; i++)
        {
            if (world.textures[i] == null)
            {
                continue;
            }
            if (world.textures[i].name != null)
            {
                if (world.textures[i].name.StartsWith("sky"))
                {
                    skytexturenum = i;
                }
                if (world.textures[i].name.StartsWith("window02_1"))
                {
                    mirrortexturenum = i;
                }
            }
            world.textures[i].texturechain = null;
        }
    }
Beispiel #6
0
    public static void SV_FindTouchedLeafs(edict_t ent, mnodebase_t node)
    {
        if (node.contents == q_shared.CONTENTS_SOLID)
        {
            return;
        }

        // add an efrag if the node is a leaf

        if (node.contents < 0)
        {
            if (ent.num_leafs == q_shared.MAX_ENT_LEAFS)
            {
                return;
            }

            mleaf_t leaf    = (mleaf_t)node;
            int     leafnum = Array.IndexOf(sv.worldmodel.leafs, leaf) - 1;

            ent.leafnums[ent.num_leafs] = (short)leafnum;
            ent.num_leafs++;
            return;
        }

        // NODE_MIXED
        mnode_t  n          = (mnode_t)node;
        mplane_t splitplane = n.plane;
        int      sides      = Mathlib.BoxOnPlaneSide(ref ent.v.absmin, ref ent.v.absmax, splitplane);

        // recurse down the contacted sides
        if ((sides & 1) != 0)
        {
            SV_FindTouchedLeafs(ent, n.children[0]);
        }

        if ((sides & 2) != 0)
        {
            SV_FindTouchedLeafs(ent, n.children[1]);
        }
    }
Beispiel #7
0
    public static void R_RemoveEfrags(entity_t ent)
    {
        efrag_t ef = ent.efrag;

        while (ef != null)
        {
            mleaf_t leaf = ef.leaf;
            while (true)
            {
                efrag_t walk = leaf.efrags;
                if (walk == null)
                {
                    break;
                }
                if (walk == ef)
                {
                    // remove this fragment
                    leaf.efrags = ef.leafnext;
                    break;
                }
                else
                {
                    leaf = (mleaf_t)(object)walk.leafnext;
                }
            }

            efrag_t old = ef;
            ef = ef.entnext;

            // put it on the free list
            old.entnext    = cl.free_efrags;
            cl.free_efrags = old;
        }

        ent.efrag = null;
    }
Beispiel #8
0
    static int PF_newcheckclient(int check)
    {
        // cycle to the next one

        if (check < 1)
        {
            check = 1;
        }
        if (check > svs.maxclients)
        {
            check = svs.maxclients;
        }

        int i = check + 1;

        if (check == svs.maxclients)
        {
            i = 1;
        }

        edict_t ent;

        for (; ; i++)
        {
            if (i == svs.maxclients + 1)
            {
                i = 1;
            }

            ent = EDICT_NUM(i);

            if (i == check)
            {
                break;  // didn't find anything else
            }
            if (ent.free)
            {
                continue;
            }
            if (ent.v.health <= 0)
            {
                continue;
            }
            if (((int)ent.v.flags & q_shared.FL_NOTARGET) != 0)
            {
                continue;
            }

            // anything that is a client, or has a client as an enemy
            break;
        }

        // get the PVS for the entity
        Vector3 org  = ToVector(ref ent.v.origin) + ToVector(ref ent.v.view_ofs);
        mleaf_t leaf = Mod_PointInLeaf(ref org, sv.worldmodel);

        byte[] pvs = Mod_LeafPVS(leaf, sv.worldmodel);
        Buffer.BlockCopy(pvs, 0, checkpvs, 0, pvs.Length);

        return(i);
    }
Beispiel #9
0
    public static void R_RecursiveWorldNode(mnodebase_t node)
    {
        if (node.contents == q_shared.CONTENTS_SOLID)
        {
            return;             // solid
        }
        if (node.visframe != r_visframecount)
        {
            return;
        }
        if (R_CullBox(ref node.mins, ref node.maxs))
        {
            return;
        }

        int c;

        // if a leaf node, draw stuff
        if (node.contents < 0)
        {
            mleaf_t      pleaf = (mleaf_t)node;
            msurface_t[] marks = pleaf.marksurfaces;
            int          mark  = pleaf.firstmarksurface;
            c = pleaf.nummarksurfaces;

            if (c != 0)
            {
                do
                {
                    marks[mark].visframe = r_framecount;
                    mark++;
                } while (--c != 0);
            }

            // deal with model fragments in this leaf
            if (pleaf.efrags != null)
            {
                R_StoreEfrags(pleaf.efrags);
            }

            return;
        }

        // node is just a decision point, so go down the apropriate sides

        mnode_t n = (mnode_t)node;

        // find which side of the node we are on
        mplane_t plane = n.plane;
        double   dot;

        switch (plane.type)
        {
        case q_shared.PLANE_X:
            dot = modelorg.X - plane.dist;
            break;

        case q_shared.PLANE_Y:
            dot = modelorg.Y - plane.dist;
            break;

        case q_shared.PLANE_Z:
            dot = modelorg.Z - plane.dist;
            break;

        default:
            dot = Vector3.Dot(modelorg, plane.normal) - plane.dist;
            break;
        }

        int side = (dot >= 0 ? 0 : 1);

        // recurse down the children, front side first
        R_RecursiveWorldNode(n.children[side]);

        // draw stuff
        c = n.numsurfaces;

        if (c != 0)
        {
            msurface_t[] surf   = cl.worldmodel.surfaces;
            int          offset = n.firstsurface;

            if (dot < 0 - q_shared.BACKFACE_EPSILON)
            {
                side = q_shared.SURF_PLANEBACK;
            }
            else if (dot > q_shared.BACKFACE_EPSILON)
            {
                side = 0;
            }

            for (; c != 0; c--, offset++)
            {
                if (surf[offset].visframe != r_framecount)
                {
                    continue;
                }

                // don't backface underwater surfaces, because they warp
                if ((surf[offset].flags & q_shared.SURF_UNDERWATER) == 0 && ((dot < 0) ^ ((surf[offset].flags & q_shared.SURF_PLANEBACK) != 0)))
                {
                    continue;           // wrong side
                }
                // if sorting by texture, just store it out
                if (gl_texsort.value != 0)
                {
                    if (!mirror || surf[offset].texinfo.texture != cl.worldmodel.textures[mirrortexturenum])
                    {
                        surf[offset].texturechain = surf[offset].texinfo.texture.texturechain;
                        surf[offset].texinfo.texture.texturechain = surf[offset];
                    }
                }
                else if ((surf[offset].flags & q_shared.SURF_DRAWSKY) != 0)
                {
                    surf[offset].texturechain = skychain;
                    skychain = surf[offset];
                }
                else if ((surf[offset].flags & q_shared.SURF_DRAWTURB) != 0)
                {
                    surf[offset].texturechain = waterchain;
                    waterchain = surf[offset];
                }
                else
                {
                    R_DrawSequentialPoly(surf[offset]);
                }
            }
        }

        // recurse down the back side
        R_RecursiveWorldNode(n.children[side == 0 ? 1 : 0]);
    }
Beispiel #10
0
 public static byte[] Mod_LeafPVS(mleaf_t leaf, model_t model)
 {
     if (leaf == model.leafs[0])
         return mod_novis;
     return Mod_DecompressVis (leaf.compressed_vis, model);
 }
Beispiel #11
0
        /*
        =================
        Mod_LoadLeafs
        =================
        */
        static void Mod_LoadLeafs(bspfile.lump_t l)
        {
            bspfile.dleaf_t[] 	@in;
            mleaf_t[] 	        @out;
            int			        i, j, count, p;

            if ((l.filelen % bspfile.sizeof_dleaf_t) != 0)
                sys_linux.Sys_Error ("MOD_LoadBmodel: funny lump size in " + loadmodel.name);
            count = l.filelen / bspfile.sizeof_dleaf_t;
            bspfile.ByteBuffer buf = new bspfile.ByteBuffer(mod_base, l.fileofs);
            @in = new bspfile.dleaf_t[count];
            @out = new mleaf_t[count];
            for (int kk = 0; kk < count; kk++)
            {
                @in[kk] = (bspfile.dleaf_t)buf;
                buf.ofs += bspfile.sizeof_dleaf_t;
                @out[kk] = new mleaf_t();
            }

            loadmodel.leafs = @out;
            loadmodel.numleafs = count;

            for ( i=0 ; i<count ; i++)
            {
                for (j=0 ; j<3 ; j++)
                {
                    @out[i].minmaxs[j] = @in[i].mins[j];
                    @out[i].minmaxs[3+j] = @in[i].maxs[j];
                }

                p = @in[i].contents;
                @out[i].contents = p;

                @out[i].firstmarksurface = new helper.ObjectBuffer(loadmodel.marksurfaces, @in[i].firstmarksurface);
                @out[i].nummarksurfaces = @in[i].nummarksurfaces;

                p = @in[i].visofs;
                if (p == -1)
                    @out[i].compressed_vis = null;
                else
                    @out[i].compressed_vis = new bspfile.ByteBuffer(loadmodel.visdata, p);
                @out[i].efrags = null;

                for (j=0 ; j<4 ; j++)
                    @out[i].ambient_sound_level[j] = @in[i].ambient_level[j];
            }
        }
Beispiel #12
0
        public virtual void R_RecursiveWorldNode(mnode_t node)
        {
            if (node.contents == Defines.CONTENTS_SOLID)
            {
                return;
            }
            if (node.visframe != r_visframecount)
            {
                return;
            }
            if (R_CullBox(node.mins, node.maxs))
            {
                return;
            }
            Int32      c;
            msurface_t mark;

            if (node.contents != -1)
            {
                mleaf_t pleaf = ( mleaf_t )node;
                if (r_newrefdef.areabits != null)
                {
                    if (((r_newrefdef.areabits[pleaf.area >> 3] & 0xFF) & (1 << (pleaf.area & 7))) == 0)
                    {
                        return;
                    }
                }

                var markp = 0;
                mark = pleaf.GetMarkSurface(markp);
                c    = pleaf.nummarksurfaces;
                if (c != 0)
                {
                    do
                    {
                        mark.visframe = r_framecount;
                        mark          = pleaf.GetMarkSurface(++markp);
                    }while (--c != 0);
                }

                return;
            }

            cplane_t plane = node.plane;
            Single   dot;

            switch (plane.type)

            {
            case Defines.PLANE_X:
                dot = modelorg[0] - plane.dist;
                break;

            case Defines.PLANE_Y:
                dot = modelorg[1] - plane.dist;
                break;

            case Defines.PLANE_Z:
                dot = modelorg[2] - plane.dist;
                break;

            default:
                dot = Math3D.DotProduct(modelorg, plane.normal) - plane.dist;
                break;
            }

            Int32 side, sidebit;

            if (dot >= 0F)
            {
                side    = 0;
                sidebit = 0;
            }
            else
            {
                side    = 1;
                sidebit = Defines.SURF_PLANEBACK;
            }

            R_RecursiveWorldNode(node.children[side]);
            msurface_t surf;
            image_t    image;

            for (c = 0; c < node.numsurfaces; c++)
            {
                surf = r_worldmodel.surfaces[node.firstsurface + c];
                if (surf.visframe != r_framecount)
                {
                    continue;
                }
                if ((surf.flags & Defines.SURF_PLANEBACK) != sidebit)
                {
                    continue;
                }
                if ((surf.texinfo.flags & Defines.SURF_SKY) != 0)
                {
                    R_AddSkySurface(surf);
                }
                else if ((surf.texinfo.flags & (Defines.SURF_TRANS33 | Defines.SURF_TRANS66)) != 0)
                {
                    surf.texturechain = r_alpha_surfaces;
                    r_alpha_surfaces  = surf;
                }
                else
                {
                    if ((surf.flags & Defines.SURF_DRAWTURB) == 0)
                    {
                        GL_RenderLightmappedPoly(surf);
                    }
                    else
                    {
                        image              = R_TextureAnimation(surf.texinfo);
                        surf.texturechain  = image.texturechain;
                        image.texturechain = surf;
                    }
                }
            }

            R_RecursiveWorldNode(node.children[1 - side]);
        }
    public static void R_SplitEntityOnNode(mnodebase_t node)
    {
        if (node.contents == q_shared.CONTENTS_SOLID)
        {
            return;
        }

        // add an efrag if the node is a leaf
        if (node.contents < 0)
        {
            if (r_pefragtopnode == null)
            {
                r_pefragtopnode = node as mnode_t;
            }

            mleaf_t leaf = (mleaf_t)(object)node;

            // grab an efrag off the free list
            efrag_t ef = cl.free_efrags;
            if (ef == null)
            {
                Con_Printf("Too many efrags!\n");
                return; // no free fragments...
            }
            cl.free_efrags = cl.free_efrags.entnext;

            ef.entity = r_addent;

            // add the entity link
            // *lastlink = ef;
            if (_LastObj is entity_t)
            {
                ((entity_t)_LastObj).efrag = ef;
            }
            else
            {
                ((efrag_t)_LastObj).entnext = ef;
            }
            _LastObj   = ef; // lastlink = &ef->entnext;
            ef.entnext = null;

            // set the leaf links
            ef.leaf     = leaf;
            ef.leafnext = leaf.efrags;
            leaf.efrags = ef;

            return;
        }

        // NODE_MIXED
        mnode_t n = node as mnode_t;

        if (n == null)
        {
            return;
        }

        mplane_t splitplane = n.plane;
        int      sides      = Mathlib.BoxOnPlaneSide(ref r_emins, ref r_emaxs, splitplane);

        if (sides == 3)
        {
            // split on this plane
            // if this is the first splitter of this bmodel, remember it
            if (r_pefragtopnode == null)
            {
                r_pefragtopnode = n;
            }
        }

        // recurse down the contacted sides
        if ((sides & 1) != 0)
        {
            R_SplitEntityOnNode(n.children[0]);
        }

        if ((sides & 2) != 0)
        {
            R_SplitEntityOnNode(n.children[1]);
        }
    }