/// <summary>
        /// Mod_LoadSpriteGroup
        /// </summary>
        private Int32 LoadSpriteGroup(ByteArraySegment pin, out Object ppframe, Int32 framenum, Func <String, ByteArraySegment, Int32, Int32, Int32> onLoadSpriteTexture)
        {
            var pingroup = Utilities.BytesToStructure <dspritegroup_t>(pin.Data, pin.StartIndex);

            var numframes    = EndianHelper.LittleLong(pingroup.numframes);
            var pspritegroup = new mspritegroup_t( );

            pspritegroup.numframes = numframes;
            pspritegroup.frames    = new mspriteframe_t[numframes];
            ppframe = pspritegroup;
            var poutintervals = new Single[numframes];

            pspritegroup.intervals = poutintervals;

            var offset = pin.StartIndex + dspritegroup_t.SizeInBytes;

            for (var i = 0; i < numframes; i++, offset += dspriteinterval_t.SizeInBytes)
            {
                var interval = Utilities.BytesToStructure <dspriteinterval_t>(pin.Data, offset);
                poutintervals[i] = EndianHelper.LittleFloat(interval.interval);
                if (poutintervals[i] <= 0)
                {
                    Utilities.Error("Mod_LoadSpriteGroup: interval<=0");
                }
            }

            for (var i = 0; i < numframes; i++)
            {
                Object tmp;
                offset = LoadSpriteFrame(new ByteArraySegment(pin.Data, offset), out tmp, framenum * 100 + i, onLoadSpriteTexture);
                pspritegroup.frames[i] = ( mspriteframe_t )tmp;
            }

            return(offset);
        }
Пример #2
0
        /// <summary>
        /// CL_WriteDemoMessage
        /// Dumps the current net message, prefixed by the length and view angles
        /// </summary>
        private void WriteDemoMessage( )
        {
            var len    = EndianHelper.LittleLong(Host.Network.Message.Length);
            var writer = ((DisposableWrapper <BinaryWriter>)cls.demofile).Object;

            writer.Write(len);
            writer.Write(EndianHelper.LittleFloat(cl.viewangles.X));
            writer.Write(EndianHelper.LittleFloat(cl.viewangles.Y));
            writer.Write(EndianHelper.LittleFloat(cl.viewangles.Z));
            writer.Write(Host.Network.Message.Data, 0, Host.Network.Message.Length);
            writer.Flush( );
        }
Пример #3
0
        /// <summary>
        /// Mod_LoadAliasGroup
        /// </summary>
        /// <returns>Offset of next data block in source byte array</returns>
        private int LoadAliasGroup(ByteArraySegment pin, ref maliasframedesc_t frame)
        {
            var offset    = pin.StartIndex;
            var pingroup  = Utilities.BytesToStructure <daliasgroup_t>(pin.Data, offset);
            var numframes = EndianHelper.LittleLong(pingroup.numframes);

            frame.Init( );
            frame.firstpose = this.PoseNum;
            frame.numposes  = numframes;

            for (var i = 0; i < 3; i++)
            {
                // these are byte values, so we don't have to worry about endianness
                frame.bboxmin.v[i] = pingroup.bboxmin.v[i];
                frame.bboxmin.v[i] = pingroup.bboxmax.v[i];
            }

            offset += daliasgroup_t.SizeInBytes;
            var pin_intervals = Utilities.BytesToStructure <daliasinterval_t>(pin.Data, offset);  // (daliasinterval_t*)(pingroup + 1);

            frame.interval = EndianHelper.LittleFloat(pin_intervals.interval);

            offset += numframes * daliasinterval_t.SizeInBytes;

            for (var i = 0; i < numframes; i++)
            {
                var tris    = new trivertx_t[this.Header.numverts];
                var offset1 = offset + daliasframe_t.SizeInBytes;
                for (var j = 0; j < this.Header.numverts; j++, offset1 += trivertx_t.SizeInBytes)
                {
                    tris[j] = Utilities.BytesToStructure <trivertx_t>(pin.Data, offset1);
                }

                this._PoseVerts[this.PoseNum] = tris;
                this.PoseNum++;

                offset += daliasframe_t.SizeInBytes + this.Header.numverts * trivertx_t.SizeInBytes;
            }

            return(offset);
        }
        public void Load(UInt32[] table8to24, String name, Byte[] buffer, Func <String, ByteArraySegment, aliashdr_t, Int32> onLoadSkinTexture, Action <AliasModelData, aliashdr_t> onMakeAliasModelDisplayList)
        {
            Name   = name;
            Buffer = buffer;

            var pinmodel = Utilities.BytesToStructure <mdl_t>(Buffer, 0);

            var version = EndianHelper.LittleLong(pinmodel.version);

            if (version != ModelDef.ALIAS_VERSION)
            {
                Utilities.Error("{0} has wrong version number ({1} should be {2})",
                                Name, version, ModelDef.ALIAS_VERSION);
            }

            //
            // allocate space for a working header, plus all the data except the frames,
            // skin and group info
            //
            Header = new aliashdr_t( );

            Flags = ( EntityFlags )EndianHelper.LittleLong(pinmodel.flags);

            //
            // endian-adjust and copy the data, starting with the alias model header
            //
            Header.boundingradius = EndianHelper.LittleFloat(pinmodel.boundingradius);
            Header.numskins       = EndianHelper.LittleLong(pinmodel.numskins);
            Header.skinwidth      = EndianHelper.LittleLong(pinmodel.skinwidth);
            Header.skinheight     = EndianHelper.LittleLong(pinmodel.skinheight);

            if (Header.skinheight > ModelDef.MAX_LBM_HEIGHT)
            {
                Utilities.Error("model {0} has a skin taller than {1}", Name, ModelDef.MAX_LBM_HEIGHT);
            }

            Header.numverts = EndianHelper.LittleLong(pinmodel.numverts);

            if (Header.numverts <= 0)
            {
                Utilities.Error("model {0} has no vertices", Name);
            }

            if (Header.numverts > ModelDef.MAXALIASVERTS)
            {
                Utilities.Error("model {0} has too many vertices", Name);
            }

            Header.numtris = EndianHelper.LittleLong(pinmodel.numtris);

            if (Header.numtris <= 0)
            {
                Utilities.Error("model {0} has no triangles", Name);
            }

            Header.numframes = EndianHelper.LittleLong(pinmodel.numframes);
            var numframes = Header.numframes;

            if (numframes < 1)
            {
                Utilities.Error("Mod_LoadAliasModel: Invalid # of frames: {0}\n", numframes);
            }

            Header.size = EndianHelper.LittleFloat(pinmodel.size) * ModelDef.ALIAS_BASE_SIZE_RATIO;
            SyncType    = ( SyncType )EndianHelper.LittleLong(( Int32 )pinmodel.synctype);
            FrameCount  = Header.numframes;

            Header.scale        = EndianHelper.LittleVector(Utilities.ToVector(ref pinmodel.scale));
            Header.scale_origin = EndianHelper.LittleVector(Utilities.ToVector(ref pinmodel.scale_origin));
            Header.eyeposition  = EndianHelper.LittleVector(Utilities.ToVector(ref pinmodel.eyeposition));

            //
            // load the skins
            //
            var offset = LoadAllSkins(table8to24, Header.numskins, new ByteArraySegment(buffer, mdl_t.SizeInBytes), onLoadSkinTexture);

            //
            // load base s and t vertices
            //
            var stvOffset = offset; // in bytes

            for (var i = 0; i < Header.numverts; i++, offset += stvert_t.SizeInBytes)
            {
                _STVerts[i] = Utilities.BytesToStructure <stvert_t>(buffer, offset);

                _STVerts[i].onseam = EndianHelper.LittleLong(_STVerts[i].onseam);
                _STVerts[i].s      = EndianHelper.LittleLong(_STVerts[i].s);
                _STVerts[i].t      = EndianHelper.LittleLong(_STVerts[i].t);
            }

            //
            // load triangle lists
            //
            var triOffset = stvOffset + Header.numverts * stvert_t.SizeInBytes;

            offset = triOffset;
            for (var i = 0; i < Header.numtris; i++, offset += dtriangle_t.SizeInBytes)
            {
                _Triangles[i]            = Utilities.BytesToStructure <dtriangle_t>(buffer, offset);
                _Triangles[i].facesfront = EndianHelper.LittleLong(_Triangles[i].facesfront);

                for (var j = 0; j < 3; j++)
                {
                    _Triangles[i].vertindex[j] = EndianHelper.LittleLong(_Triangles[i].vertindex[j]);
                }
            }

            //
            // load the frames
            //
            PoseNum = 0;
            var framesOffset = triOffset + Header.numtris * dtriangle_t.SizeInBytes;

            Header.frames = new maliasframedesc_t[Header.numframes];

            for (var i = 0; i < numframes; i++)
            {
                var frametype = ( aliasframetype_t )BitConverter.ToInt32(buffer, framesOffset);
                framesOffset += 4;

                if (frametype == aliasframetype_t.ALIAS_SINGLE)
                {
                    framesOffset = LoadAliasFrame(new ByteArraySegment(buffer, framesOffset), ref Header.frames[i]);
                }
                else
                {
                    framesOffset = LoadAliasGroup(new ByteArraySegment(buffer, framesOffset), ref Header.frames[i]);
                }
            }

            Header.numposes = PoseNum;

            Type = ModelType.Alias;

            // FIXME: do this right
            BoundsMin = -Vector3.One * 16.0f;
            BoundsMax = -BoundsMin;

            //
            // build the draw lists
            //
            onMakeAliasModelDisplayList(this, Header);
            //mesh.MakeAliasModelDisplayLists( mod, Header );

            //
            // move the complete, relocatable alias model to the cache
            //
            //cache = Host.Cache.Alloc( aliashdr_t.SizeInBytes * Header.frames.Length * maliasframedesc_t.SizeInBytes, null );

            //if ( cache == null )
            //    return;

            //cache.data = Header;
        }
Пример #5
0
        /// <summary>
        /// CL_GetMessage
        /// Handles recording and playback of demos, on top of NET_ code
        /// </summary>
        /// <returns></returns>
        private Int32 GetMessage( )
        {
            if (cls.demoplayback)
            {
                // decide if it is time to grab the next message
                if (cls.signon == ClientDef.SIGNONS)    // allways grab until fully connected
                {
                    if (cls.timedemo)
                    {
                        if (Host.FrameCount == cls.td_lastframe)
                        {
                            return(0);           // allready read this frame's message
                        }
                        cls.td_lastframe = Host.FrameCount;
                        // if this is the second frame, grab the real td_starttime
                        // so the bogus time on the first frame doesn't count
                        if (Host.FrameCount == cls.td_startframe + 1)
                        {
                            cls.td_starttime = ( Single )Host.RealTime;
                        }
                    }
                    else if (cl.time <= cl.mtime[0])
                    {
                        return(0);       // don't need another message yet
                    }
                }

                // get the next message
                var reader = ((DisposableWrapper <BinaryReader>)cls.demofile).Object;
                var size   = EndianHelper.LittleLong(reader.ReadInt32( ));
                if (size > QDef.MAX_MSGLEN)
                {
                    Utilities.Error("Demo message > MAX_MSGLEN");
                }

                cl.mviewangles[1]   = cl.mviewangles[0];
                cl.mviewangles[0].X = EndianHelper.LittleFloat(reader.ReadSingle( ));
                cl.mviewangles[0].Y = EndianHelper.LittleFloat(reader.ReadSingle( ));
                cl.mviewangles[0].Z = EndianHelper.LittleFloat(reader.ReadSingle( ));

                Host.Network.Message.FillFrom(reader.BaseStream, size);
                if (Host.Network.Message.Length < size)
                {
                    StopPlayback( );
                    return(0);
                }
                return(1);
            }

            Int32 r;

            while (true)
            {
                r = Host.Network.GetMessage(cls.netcon);

                if (r != 1 && r != 2)
                {
                    return(r);
                }

                // discard nop keepalive message
                if (Host.Network.Message.Length == 1 && Host.Network.Message.Data[0] == ProtocolDef.svc_nop)
                {
                    Host.Console.Print("<-- server to client keepalive\n");
                }
                else
                {
                    break;
                }
            }

            if (cls.demorecording)
            {
                WriteDemoMessage( );
            }

            return(r);
        }
        public void Load(String name, Byte[] buffer, Func <String, ByteArraySegment, Int32, Int32, Int32> onLoadSpriteTexture)
        {
            Name   = name;
            Buffer = buffer;

            var pin = Utilities.BytesToStructure <dsprite_t>(buffer, 0);

            var version = EndianHelper.LittleLong(pin.version);

            if (version != ModelDef.SPRITE_VERSION)
            {
                Utilities.Error("{0} has wrong version number ({1} should be {2})",
                                Name, version, ModelDef.SPRITE_VERSION);
            }

            var numframes = EndianHelper.LittleLong(pin.numframes);

            var psprite = new msprite_t( );

            // Uze: sprite models are not cached so
            cache      = new CacheUser( );
            cache.data = psprite;

            psprite.type       = ( SpriteType )EndianHelper.LittleLong(pin.type);
            psprite.maxwidth   = EndianHelper.LittleLong(pin.width);
            psprite.maxheight  = EndianHelper.LittleLong(pin.height);
            psprite.beamlength = EndianHelper.LittleFloat(pin.beamlength);
            SyncType           = ( SyncType )EndianHelper.LittleLong(( Int32 )pin.synctype);
            psprite.numframes  = numframes;

            var mins = BoundsMin;
            var maxs = BoundsMax;

            mins.X    = mins.Y = -psprite.maxwidth / 2;
            maxs.X    = maxs.Y = psprite.maxwidth / 2;
            mins.Z    = -psprite.maxheight / 2;
            maxs.Z    = psprite.maxheight / 2;
            BoundsMin = BoundsMin;

            //
            // load the frames
            //
            if (numframes < 1)
            {
                Utilities.Error("Mod_LoadSpriteModel: Invalid # of frames: {0}\n", numframes);
            }

            FrameCount = numframes;

            var frameOffset = dsprite_t.SizeInBytes;

            psprite.frames = new mspriteframedesc_t[numframes];

            for (var i = 0; i < numframes; i++)
            {
                var frametype = ( spriteframetype_t )BitConverter.ToInt32(buffer, frameOffset);
                frameOffset += 4;

                psprite.frames[i].type = frametype;

                if (frametype == spriteframetype_t.SPR_SINGLE)
                {
                    frameOffset = LoadSpriteFrame(new ByteArraySegment(buffer, frameOffset), out psprite.frames[i].frameptr, i, onLoadSpriteTexture);
                }
                else
                {
                    frameOffset = LoadSpriteGroup(new ByteArraySegment(buffer, frameOffset), out psprite.frames[i].frameptr, i, onLoadSpriteTexture);
                }
            }

            Type = ModelType.Sprite;
        }