/// <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); }
/// <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( ); }
/// <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; }
/// <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; }