public void Read(DescentReader reader) { PointCount = reader.ReadInt16(); Point = reader.ReadFixVector(); Normal = reader.ReadFixVector(); Texture = reader.ReadInt16(); Points = new short[PointCount]; //TODO: seems wasteful to do all these allocations? Uvls = new FixVector[PointCount]; for (int i = 0; i < PointCount; i++) { Points[i] = reader.ReadInt16(); } if (PointCount % 2 == 0) { Padding = reader.ReadInt16(); } for (int i = 0; i < PointCount; i++) { Uvls[i] = reader.ReadFixVector(); } }
private void GetVertexes(BSPNode node, byte[] interpreterData) { if (node == null) { return; } if (node.faces != null) { foreach (var face in node.faces) { foreach (var point in face.Points) { Fix x = point.Point.X; Fix y = point.Point.Y; Fix z = point.Point.Z; //TODO this is a bit slow overall var vec = new FixVector(x, y, z); if (!vertexDict.ContainsKey(vec)) { vertexDict.Add(vec, vertexDict.Count + mVertexOffset); } } } } GetVertexes(node.Front, interpreterData); GetVertexes(node.Back, interpreterData); }
public FixVector Cross(FixVector other) { return(new FixVector( this.Y * other.Z - this.Z * other.Y, this.Z * other.X - this.X * other.Z, this.X * other.Y - this.Y * other.X )); }
public static float Dist(FixVector a, FixVector b) { float x = (a.X - b.X); float y = (a.Y - b.Y); float z = (a.Z - b.Z); return((float)Math.Sqrt((x * x) + (y * y) + (z * z))); }
public double Dot(FixVector other) { // optimized to avoid intermediate fix conversions // must divide by 2^16 at the end since we were dealing with fixes return(((((long)this.X.value * other.X.value) >> 16) + (((long)this.Y.value * other.Y.value) >> 16) + (((long)this.Z.value * other.Z.value) >> 16)) * (1.0 / (1 << 16))); }
//[ISB] this seems slightly out of place here, but where else would it go? public static Fix Dot3(Fix x, Fix y, Fix z, FixVector vec) { long q = 0; q += x.MultiplyWithoutShift(vec.X); q += y.MultiplyWithoutShift(vec.Y); q += z.MultiplyWithoutShift(vec.Z); return(Fix.FixFromLong(q)); }
private static FixVector ReadVector(BinaryReader br) { FixVector vec = new FixVector(); vec.X = new Fix(br.ReadInt32()); vec.Y = new Fix(br.ReadInt32()); vec.Z = new Fix(br.ReadInt32()); return(vec); }
public FixVector ReadFixVector() { var x = this.ReadFix(); var y = this.ReadFix(); var z = this.ReadFix(); FixVector result = new FixVector(x, y, z); return(result); }
public Submodel(Submodel other) { Pointer = other.Pointer; Offset = other.Offset; RenderOffset = other.RenderOffset; Normal = other.Normal; Point = other.Point; Radius = other.Radius; Parent = other.Parent; Mins = other.Mins; Maxs = other.Maxs; }
internal static (FixVector vertexLocation, uint vertexId) ReadVertex(BlockStreamReader reader, bool isExtendedFormat) { var regex = isExtendedFormat ? extendedVertexRegex : vertexRegex; var match = regex.Match(reader.ReadLine()); if (!match.Success) { string name = isExtendedFormat ? "Vertex" : "vms_vector"; throw new InvalidDataException($"Expected {name} at line {reader.LastLineNumber}: '{reader.LastLine}'"); } return(vertexLocation : FixVector.FromRawValues( x : int.Parse(match.Groups[2].Value), y : int.Parse(match.Groups[3].Value), z : int.Parse(match.Groups[4].Value)), vertexId : uint.Parse(match.Groups[1].Value)); }
private Submodel GetClosestModel(List <Submodel> modelsToPlace, Submodel rootModel) { float dist = float.MaxValue; Submodel furthest = null; foreach (var childModel in modelsToPlace) { var d = FixVector.Dist(rootModel.Point, childModel.Point); if (d < dist) { dist = d; furthest = childModel; } } return(furthest); }
public FixMatrix Mul(FixMatrix other) { return(new FixMatrix( right: new FixVector( FixVector.Dot3(Right.X, Up.X, Forward.X, other.Right), FixVector.Dot3(Right.Y, Up.Y, Forward.Y, other.Right), FixVector.Dot3(Right.Z, Up.Z, Forward.Z, other.Right)), up: new FixVector( FixVector.Dot3(Right.X, Up.X, Forward.X, other.Up), FixVector.Dot3(Right.Y, Up.Y, Forward.Y, other.Up), FixVector.Dot3(Right.Z, Up.Z, Forward.Z, other.Up)), forward: new FixVector( FixVector.Dot3(Right.X, Up.X, Forward.X, other.Forward), FixVector.Dot3(Right.Y, Up.Y, Forward.Y, other.Forward), FixVector.Dot3(Right.Z, Up.Z, Forward.Z, other.Forward)) )); }
public override void Write(byte[] data, ref int offset) { int index = SubModel.ID; int offsetBase = offset; PolymodelBuilder.SetShort(data, ref offset, ModelOpCode.SubCall); short submodelNum = (short)(index); PolymodelBuilder.SetShort(data, ref offset, submodelNum); FixVector submodelOffset = SubModel.Offset; PolymodelBuilder.SetFixVector(data, ref offset, submodelOffset); //The address where we write the new offset value int offsetAddress = offset; short offsetValue = 0; PolymodelBuilder.SetShort(data, ref offset, offsetValue); offset += 2; //Subcall is immediately followed with the end op code PolymodelBuilder.SetShort(data, ref offset, ModelOpCode.End); // Calculate the new offset offsetValue = (short)(offset - offsetBase); Instruction.Write(data, ref offset); // Store offset var endOffset = offset; offset = offsetAddress; PolymodelBuilder.SetShort(data, ref offset, (short)offsetValue); offset = endOffset; }
public void Read(Stream stream) { BinaryReader br; br = new BinaryReader(stream); HAMDataReader bm = new HAMDataReader(); int sig = br.ReadInt32(); if (sig != 0x214D4148) { br.Dispose(); throw new InvalidDataException("HAMFile::Read: HAM file has bad header."); } Version = br.ReadInt32(); if (Version < 2 || Version > 3) { br.Dispose(); throw new InvalidDataException(string.Format("HAMFile::Read: HAM file has bad version. Got {0}, but expected \"2\" or \"3\"", Version)); } int sndptr = 0; if (Version == 2) { sndptr = br.ReadInt32(); } int NumBitmaps = br.ReadInt32(); for (int x = 0; x < NumBitmaps; x++) { Textures.Add(br.ReadUInt16()); } for (int x = 0; x < NumBitmaps; x++) { TMapInfo.Add(bm.ReadTMAPInfo(br)); TMapInfo[x].ID = x; } int NumSounds = br.ReadInt32(); if (NumSounds > 254) { throw new InvalidDataException("HAM file specifies more than 254 sounds."); } for (int x = 0; x < NumSounds; x++) { Sounds[x] = br.ReadByte(); } for (int x = 0; x < NumSounds; x++) { AltSounds[x] = br.ReadByte(); } int NumVClips = br.ReadInt32(); for (int x = 0; x < NumVClips; x++) { VClips.Add(bm.ReadVClip(br)); VClips[x].ID = x; } int NumEClips = br.ReadInt32(); for (int x = 0; x < NumEClips; x++) { EClips.Add(bm.ReadEClip(br)); EClips[x].ID = x; } int NumWallAnims = br.ReadInt32(); for (int x = 0; x < NumWallAnims; x++) { WClips.Add(bm.ReadWClip(br)); } int NumRobots = br.ReadInt32(); for (int x = 0; x < NumRobots; x++) { Robots.Add(bm.ReadRobot(br)); Robots[x].ID = x; } int NumLoadJoints = br.ReadInt32(); for (int x = 0; x < NumLoadJoints; x++) { JointPos joint = new JointPos(); joint.JointNum = br.ReadInt16(); joint.Angles.P = br.ReadInt16(); joint.Angles.B = br.ReadInt16(); joint.Angles.H = br.ReadInt16(); Joints.Add(joint); } int NumWeaponTypes = br.ReadInt32(); for (int x = 0; x < NumWeaponTypes; x++) { if (Version >= 3) { Weapons.Add(bm.ReadWeapon(br)); } else { Weapons.Add(bm.ReadWeaponInfoVersion2(br)); } Weapons[x].ID = x; } int NumPowerups = br.ReadInt32(); for (int x = 0; x < NumPowerups; x++) { Powerup powerup = new Powerup(); powerup.VClipNum = br.ReadInt32(); powerup.HitSound = br.ReadInt32(); powerup.Size = new Fix(br.ReadInt32()); powerup.Light = new Fix(br.ReadInt32()); powerup.ID = x; Powerups.Add(powerup); } int NumPolygonModels = br.ReadInt32(); for (int x = 0; x < NumPolygonModels; x++) { Models.Add(bm.ReadPolymodelInfo(br)); Models[x].ID = x; } for (int x = 0; x < NumPolygonModels; x++) { Models[x].InterpreterData = br.ReadBytes(Models[x].ModelIDTASize); //PolymodelData.Add(modeldata); } for (int x = 0; x < NumPolygonModels; x++) { Models[x].DyingModelnum = br.ReadInt32(); } for (int x = 0; x < NumPolygonModels; x++) { Models[x].DeadModelnum = br.ReadInt32(); } int gagueCount = br.ReadInt32(); for (int x = 0; x < gagueCount; x++) { Gauges.Add(br.ReadUInt16()); } for (int x = 0; x < gagueCount; x++) { GaugesHires.Add(br.ReadUInt16()); } int bitmapCount = br.ReadInt32(); for (int x = 0; x < bitmapCount; x++) { ObjBitmaps.Add(br.ReadUInt16()); } ushort value; for (int x = 0; x < bitmapCount; x++) { value = br.ReadUInt16(); if ((value + 1) > NumObjBitmaps) { NumObjBitmaps = (value + 1); } ObjBitmapPointers.Add(value); } PlayerShip = new Ship(); PlayerShip.ModelNum = br.ReadInt32(); PlayerShip.DeathVClipNum = br.ReadInt32(); PlayerShip.Mass = new Fix(br.ReadInt32()); PlayerShip.Drag = new Fix(br.ReadInt32()); PlayerShip.MaxThrust = new Fix(br.ReadInt32()); PlayerShip.ReverseThrust = new Fix(br.ReadInt32()); PlayerShip.Brakes = new Fix(br.ReadInt32()); PlayerShip.Wiggle = new Fix(br.ReadInt32()); PlayerShip.MaxRotationThrust = new Fix(br.ReadInt32()); for (int x = 0; x < 8; x++) { PlayerShip.GunPoints[x] = FixVector.FromRawValues(br.ReadInt32(), br.ReadInt32(), br.ReadInt32()); } int NumCockpits = br.ReadInt32(); for (int x = 0; x < NumCockpits; x++) { Cockpits.Add(br.ReadUInt16()); } //Build a table of all multiplayer bitmaps, to inject into the object bitmap table FirstMultiBitmapNum = br.ReadInt32(); int NumReactors = br.ReadInt32(); for (int x = 0; x < NumReactors; x++) { Reactor reactor = new Reactor(); reactor.ModelNum = br.ReadInt32(); reactor.NumGuns = br.ReadInt32(); for (int y = 0; y < 8; y++) { reactor.GunPoints[y] = FixVector.FromRawValues(br.ReadInt32(), br.ReadInt32(), br.ReadInt32()); } for (int y = 0; y < 8; y++) { reactor.GunDirs[y] = FixVector.FromRawValues(br.ReadInt32(), br.ReadInt32(), br.ReadInt32()); } Reactors.Add(reactor); } PlayerShip.MarkerModel = br.ReadInt32(); //2620 if (Version < 3) { ExitModelnum = br.ReadInt32(); DestroyedExitModelnum = br.ReadInt32(); } for (int x = 0; x < 2620; x++) { try { BitmapXLATData[x] = br.ReadUInt16(); } catch (EndOfStreamException) //Descent 2's official HAM files have only 2600 XLAT entries, but later versions of the game attempt to read 2620. { break; } } if (Version < 3) { br.BaseStream.Seek(sndptr, SeekOrigin.Begin); int dataToRead = (int)(br.BaseStream.Length - br.BaseStream.Position); sounddata = br.ReadBytes(dataToRead); } hasRead = true; //br.Dispose(); }
public Robot ReadRobotPSX(BinaryReader br) { Robot robot = new Robot(); robot.ModelNum = br.ReadInt32(); robot.NumGuns = (sbyte)br.ReadInt32(); for (int s = 0; s < Polymodel.MaxGuns; s++) { robot.GunPoints[s] = FixVector.FromRawValues(br.ReadInt32(), br.ReadInt32(), br.ReadInt32()); } for (int s = 0; s < 8; s++) { robot.GunSubmodels[s] = br.ReadByte(); } robot.HitVClipNum = br.ReadInt16(); robot.HitSoundNum = br.ReadInt16(); robot.DeathVClipNum = br.ReadInt16(); robot.DeathSoundNum = br.ReadInt16(); robot.WeaponType = (sbyte)br.ReadInt16(); robot.ContainsID = br.ReadSByte(); robot.ContainsCount = br.ReadSByte(); robot.ContainsProbability = br.ReadSByte(); robot.ContainsType = br.ReadSByte(); short unk1 = br.ReadInt16(); robot.ScoreValue = (short)br.ReadInt32(); robot.Lighting = new Fix(br.ReadInt32()); robot.Strength = new Fix(br.ReadInt32()); robot.Mass = new Fix(br.ReadInt32()); robot.Drag = new Fix(br.ReadInt32()); for (int s = 0; s < Robot.NumDifficultyLevels; s++) { robot.FieldOfView[s] = new Fix(br.ReadInt32()); } for (int s = 0; s < Robot.NumDifficultyLevels; s++) { robot.FiringWait[s] = new Fix(br.ReadInt32()); } for (int s = 0; s < Robot.NumDifficultyLevels; s++) { robot.TurnTime[s] = new Fix(br.ReadInt32()); } for (int s = 0; s < Robot.NumDifficultyLevels; s++) { robot.FirePower[s] = new Fix(br.ReadInt32()); } for (int s = 0; s < Robot.NumDifficultyLevels; s++) { robot.Shield[s] = new Fix(br.ReadInt32()); } for (int s = 0; s < Robot.NumDifficultyLevels; s++) { robot.MaxSpeed[s] = new Fix(br.ReadInt32()); } for (int s = 0; s < Robot.NumDifficultyLevels; s++) { robot.CircleDistance[s] = new Fix(br.ReadInt32()); } for (int s = 0; s < Robot.NumDifficultyLevels; s++) { robot.RapidfireCount[s] = br.ReadSByte(); } for (int s = 0; s < Robot.NumDifficultyLevels; s++) { robot.EvadeSpeed[s] = br.ReadSByte(); } robot.CloakType = (RobotCloakType)br.ReadSByte(); robot.AttackType = (RobotAttackType)br.ReadSByte(); robot.BossFlag = (RobotBossType)br.ReadSByte(); robot.SeeSound = br.ReadByte(); robot.AttackSound = br.ReadByte(); robot.ClawSound = br.ReadByte(); for (int v = 0; v < 9; v++) { for (int u = 0; u < 5; u++) { robot.AnimStates[v, u].NumJoints = br.ReadInt16(); robot.AnimStates[v, u].Offset = br.ReadInt16(); } } robot.Always0xABCD = br.ReadInt32(); return(robot); }
public static void SetFixVector(byte[] data, ref int offset, FixVector value) { SetInt(data, ref offset, value.X.Value); SetInt(data, ref offset, value.Y.Value); SetInt(data, ref offset, value.Z.Value); }
public LevelVertex(Fix x, Fix y, Fix z) { location = new FixVector(x, y, z); }
public void GetFaces(BSPNode node, byte[] data, ref int modelDataOffset) { if (node == null) { return; } if (node.Front == null && node.Back != null) { throw new Exception("ModelData::GetFaces: Front is null but back isn't."); } else if (node.Front != null && node.Back == null) { throw new Exception("ModelData::GetFaces: Back is null but front isn't."); } if (node.Front != null && node.Back != null) { if (node.Point.X == node.Point.Y && node.Point.Y == node.Point.Z && node.Point.Z == 0.0f) { //TODO: figure out if this is actually an error condition. throw new Exception("ModelData::GetFaces: splitter point is 0 but this probably isn't a problem. Probably."); } // Sort start int sortStatPosition = modelDataOffset; PolymodelBuilder.SetShort(data, ref modelDataOffset, 4); // SORTNORM opcode PolymodelBuilder.SetShort(data, ref modelDataOffset, 0); // int n_points FixVector normal = new FixVector(node.Normal.X, node.Normal.Y, node.Normal.Z); FixVector point = new FixVector(node.Point.X, node.Point.Y, node.Point.Z); PolymodelBuilder.SetFixVector(data, ref modelDataOffset, normal); PolymodelBuilder.SetFixVector(data, ref modelDataOffset, point); int backOffset = modelDataOffset; PolymodelBuilder.SetShort(data, ref modelDataOffset, (short)backOffset); // fix the back offset later int frontOffset = modelDataOffset; PolymodelBuilder.SetShort(data, ref modelDataOffset, (short)frontOffset); // fix the front offset later // Terminator opcode PolymodelBuilder.SetShort(data, ref modelDataOffset, ModelOpCode.End); // Process front and store offset int frontOffsetValue = modelDataOffset - sortStatPosition; GetFaces(node.Front, data, ref modelDataOffset); // Process back and store offset int backOffsetValue = modelDataOffset - sortStatPosition; GetFaces(node.Back, data, ref modelDataOffset); // Store the end position int endPosition = modelDataOffset; if (frontOffsetValue > short.MaxValue || backOffsetValue > short.MaxValue || modelDataOffset < 0) { throw new ArgumentException("Model is too complex: 32KB displacement limit exceeded."); } // Correct the back offset modelDataOffset = backOffset; PolymodelBuilder.SetShort(data, ref modelDataOffset, (short)frontOffsetValue); // fix the back offset later // Correct the front offset modelDataOffset = frontOffset; PolymodelBuilder.SetShort(data, ref modelDataOffset, (short)backOffsetValue); // fix the back offset later // Restore the offset to the end position modelDataOffset = endPosition; if (node.faces != null && node.faces.Any()) { throw new Exception("Missing faces!"); } } else if (node.faces != null) { int facesStatPosition = modelDataOffset; BSPVertex vert; short vertexNum; foreach (var face in node.faces) { if (face.TextureID == -1) { // Flat poly opcode PolymodelBuilder.SetShort(data, ref modelDataOffset, ModelOpCode.FlatPoly); short pointc = (short)face.Points.Count(); PolymodelBuilder.SetShort(data, ref modelDataOffset, pointc); Fix x = face.Point.X; Fix y = face.Point.Y; Fix z = face.Point.Z; var facePoint = new FixVector(x, y, z); PolymodelBuilder.SetFixVector(data, ref modelDataOffset, facePoint); x = face.Normal.X; y = face.Normal.Y; z = face.Normal.Z; var normal = new FixVector(x, y, z); PolymodelBuilder.SetFixVector(data, ref modelDataOffset, normal); PolymodelBuilder.SetShort(data, ref modelDataOffset, (short)face.Color); for (short i = 0; i < pointc; i++) { vert = face.Points[i]; FixVector vec = new FixVector(vert.Point.X, vert.Point.Y, vert.Point.Z); vertexNum = (short)vertexDict[vec]; PolymodelBuilder.SetShort(data, ref modelDataOffset, vertexNum); } if (pointc % 2 == 0) { PolymodelBuilder.SetShort(data, ref modelDataOffset, 0); } } else { // tmapped poly opcode PolymodelBuilder.SetShort(data, ref modelDataOffset, ModelOpCode.TexturedPoly); short pointc = (short)face.Points.Count(); PolymodelBuilder.SetShort(data, ref modelDataOffset, pointc); Fix x = face.Point.X; Fix y = face.Point.Y; Fix z = face.Point.Z; var facePoint = new FixVector(x, y, z); PolymodelBuilder.SetFixVector(data, ref modelDataOffset, facePoint); x = face.Normal.X; y = face.Normal.Y; z = face.Normal.Z; var normal = new FixVector(x, y, z); PolymodelBuilder.SetFixVector(data, ref modelDataOffset, normal); PolymodelBuilder.SetShort(data, ref modelDataOffset, (short)face.TextureID); for (short i = 0; i < pointc; i++) { vert = face.Points[i]; FixVector vec = new FixVector(vert.Point.X, vert.Point.Y, vert.Point.Z); vertexNum = (short)vertexDict[vec]; PolymodelBuilder.SetShort(data, ref modelDataOffset, vertexNum); } if (pointc % 2 == 0) { PolymodelBuilder.SetShort(data, ref modelDataOffset, 0); } for (short i = 0; i < pointc; i++) { x = face.Points[i].UVs.X; y = face.Points[i].UVs.Y; z = face.Points[i].UVs.Z; var uv = new FixVector(x, y, z); PolymodelBuilder.SetFixVector(data, ref modelDataOffset, uv); } } } PolymodelBuilder.SetShort(data, ref modelDataOffset, ModelOpCode.End); } }
private FixVector GetFixVector(byte[] data, ref int offset) { return(FixVector.FromRawValues(GetInt(data, ref offset), GetInt(data, ref offset), GetInt(data, ref offset))); }
public void WriteFixVector(FixVector a) { this.WriteFix(a.X); this.WriteFix(a.Y); this.WriteFix(a.Z); }
public int Read(Stream stream) { BinaryReader br = new BinaryReader(stream); HAMDataReader reader = new HAMDataReader(); DataPointer = br.ReadInt32(); numTextures = br.ReadInt32(); for (int i = 0; i < 800; i++) { Textures[i] = br.ReadUInt16(); } for (int i = 0; i < 800; i++) { TMapInfo[i] = reader.ReadTMAPInfoDescentPSX(br); } Sounds = br.ReadBytes(250); AltSounds = br.ReadBytes(250); numVClips = br.ReadInt32(); //this value is bogus. rip for (int i = 0; i < 70; i++) { VClips[i] = reader.ReadVClipPSX(br); } numEClips = br.ReadInt32(); for (int i = 0; i < 60; i++) { EClips[i] = reader.ReadEClipPSX(br); } numWClips = br.ReadInt32(); for (int i = 0; i < 30; i++) { WClips[i] = reader.ReadWClipPSX(br); } numRobots = br.ReadInt32(); for (int i = 0; i < 30; i++) { Robots[i] = reader.ReadRobotPSX(br); } numJoints = br.ReadInt32(); for (int i = 0; i < 600; i++) { JointPos joint = new JointPos(); joint.JointNum = br.ReadInt16(); joint.Angles.P = br.ReadInt16(); joint.Angles.B = br.ReadInt16(); joint.Angles.H = br.ReadInt16(); Joints[i] = joint; } numWeapons = br.ReadInt32(); for (int i = 0; i < 30; i++) { Weapons[i] = reader.ReadWeaponInfoPSX(br); } numPowerups = br.ReadInt32(); for (int i = 0; i < 29; i++) { Powerup powerup = new Powerup(); powerup.VClipNum = br.ReadInt32(); powerup.HitSound = br.ReadInt32(); powerup.Size = new Fix(br.ReadInt32()); powerup.Light = new Fix(br.ReadInt32()); Powerups[i] = powerup; } numModels = br.ReadInt32(); for (int i = 0; i < numModels; i++) { Models[i] = reader.ReadPolymodelInfoPSX(br); } for (int i = 0; i < numModels; i++) { Models[i].InterpreterData = br.ReadBytes(Models[i].ModelIDTASize); } for (int i = 0; i < Gauges.Length; i++) { Gauges[i] = br.ReadUInt16(); } for (int i = 0; i < 85; i++) { int num = br.ReadInt32(); if (i < numModels) { Models[i].DyingModelnum = num; } } for (int i = 0; i < 85; i++) { int num = br.ReadInt32(); if (i < numModels) { Models[i].DeadModelnum = num; } } for (int i = 0; i < 210; i++) { ObjBitmaps[i] = br.ReadUInt16(); } for (int i = 0; i < 210; i++) { ObjBitmapPointers[i] = br.ReadUInt16(); } PlayerShip = new Ship(); PlayerShip.ModelNum = br.ReadInt32(); PlayerShip.DeathVClipNum = br.ReadInt32(); PlayerShip.Mass = new Fix(br.ReadInt32()); PlayerShip.Drag = new Fix(br.ReadInt32()); PlayerShip.MaxThrust = new Fix(br.ReadInt32()); PlayerShip.ReverseThrust = new Fix(br.ReadInt32()); PlayerShip.Brakes = new Fix(br.ReadInt32()); PlayerShip.Wiggle = new Fix(br.ReadInt32()); PlayerShip.MaxRotationThrust = new Fix(br.ReadInt32()); for (int x = 0; x < 8; x++) { PlayerShip.GunPoints[x] = FixVector.FromRawValues(br.ReadInt32(), br.ReadInt32(), br.ReadInt32()); } numCockpits = br.ReadInt32(); for (int i = 0; i < 4; i++) { Cockpits[i] = br.ReadUInt16(); } //heh Sounds = br.ReadBytes(250); AltSounds = br.ReadBytes(250); numObjects = br.ReadInt32(); for (int i = 0; i < 100; i++) { ObjectTypes[i].type = (EditorObjectType)(br.ReadSByte()); } for (int i = 0; i < 100; i++) { ObjectTypes[i].id = br.ReadByte(); } for (int i = 0; i < 100; i++) { ObjectTypes[i].strength = new Fix(br.ReadInt32()); //Console.WriteLine("type: {0}({3})\nid: {1}\nstr: {2}", ObjectTypes[i].type, ObjectTypes[i].id, ObjectTypes[i].strength, (int)ObjectTypes[i].type); } FirstMultiBitmapNum = br.ReadInt32(); reactor.NumGuns = br.ReadInt32(); for (int y = 0; y < 4; y++) { reactor.GunPoints[y] = FixVector.FromRawValues(br.ReadInt32(), br.ReadInt32(), br.ReadInt32()); } for (int y = 0; y < 4; y++) { reactor.GunDirs[y] = FixVector.FromRawValues(br.ReadInt32(), br.ReadInt32(), br.ReadInt32()); } exitModelnum = br.ReadInt32(); destroyedExitModelnum = br.ReadInt32(); for (int i = 0; i < 1800; i++) { BitmapXLATData[i] = br.ReadUInt16(); } br.Dispose(); return(0); }
public void Read(Stream stream) { BinaryReader br = new BinaryReader(stream); HAMDataReader reader = new HAMDataReader(); if (LoadData) { DataPointer = br.ReadInt32(); //So there's no sig, so we're going to take a guess based on the pointer. If it's greater than max bitmaps, we'll assume it's a descent 1 1.4+ piggy file if (DataPointer <= 1800) { throw new ArgumentException("Cannot read this .PIG file"); } numTextures = br.ReadInt32(); for (int i = 0; i < 800; i++) { Textures[i] = br.ReadUInt16(); } for (int i = 0; i < 800; i++) { TMapInfo[i] = reader.ReadTMAPInfoDescent1(br); } SoundIDs = br.ReadBytes(250); AltSounds = br.ReadBytes(250); numVClips = br.ReadInt32(); //this value is bogus. rip for (int i = 0; i < 70; i++) { VClips[i] = reader.ReadVClip(br); } numEClips = br.ReadInt32(); for (int i = 0; i < 60; i++) { EClips[i] = reader.ReadEClip(br); } numWClips = br.ReadInt32(); for (int i = 0; i < 30; i++) { WClips[i] = reader.ReadWClipDescent1(br); } numRobots = br.ReadInt32(); for (int i = 0; i < 30; i++) { Robots[i] = reader.ReadRobotDescent1(br); } numJoints = br.ReadInt32(); for (int i = 0; i < 600; i++) { JointPos joint = new JointPos(); joint.JointNum = br.ReadInt16(); joint.Angles.P = br.ReadInt16(); joint.Angles.B = br.ReadInt16(); joint.Angles.H = br.ReadInt16(); Joints[i] = joint; } numWeapons = br.ReadInt32(); for (int i = 0; i < 30; i++) { Weapons[i] = reader.ReadWeaponInfoDescent1(br); } numPowerups = br.ReadInt32(); for (int i = 0; i < 29; i++) { Powerup powerup = new Powerup(); powerup.VClipNum = br.ReadInt32(); powerup.HitSound = br.ReadInt32(); powerup.Size = new Fix(br.ReadInt32()); powerup.Light = new Fix(br.ReadInt32()); Powerups[i] = powerup; } numModels = br.ReadInt32(); for (int i = 0; i < numModels; i++) { Models[i] = reader.ReadPolymodelInfo(br); } for (int i = 0; i < numModels; i++) { Models[i].InterpreterData = br.ReadBytes(Models[i].ModelIDTASize); } for (int i = 0; i < Gauges.Length; i++) { Gauges[i] = br.ReadUInt16(); } for (int i = 0; i < 85; i++) { int num = br.ReadInt32(); if (i < numModels) { Models[i].DyingModelnum = num; } else { int wtfIsThis = num; } } for (int i = 0; i < 85; i++) { int num = br.ReadInt32(); if (i < numModels) { Models[i].DeadModelnum = num; } else { int wtfIsThis = num; } } for (int i = 0; i < 210; i++) { ObjBitmaps[i] = br.ReadUInt16(); } for (int i = 0; i < 210; i++) { ObjBitmapPointers[i] = br.ReadUInt16(); } PlayerShip = new Ship(); PlayerShip.ModelNum = br.ReadInt32(); PlayerShip.DeathVClipNum = br.ReadInt32(); PlayerShip.Mass = new Fix(br.ReadInt32()); PlayerShip.Drag = new Fix(br.ReadInt32()); PlayerShip.MaxThrust = new Fix(br.ReadInt32()); PlayerShip.ReverseThrust = new Fix(br.ReadInt32()); PlayerShip.Brakes = new Fix(br.ReadInt32()); PlayerShip.Wiggle = new Fix(br.ReadInt32()); PlayerShip.MaxRotationThrust = new Fix(br.ReadInt32()); for (int x = 0; x < 8; x++) { PlayerShip.GunPoints[x] = FixVector.FromRawValues(br.ReadInt32(), br.ReadInt32(), br.ReadInt32()); } numCockpits = br.ReadInt32(); for (int i = 0; i < 4; i++) { Cockpits[i] = br.ReadUInt16(); } //heh SoundIDs = br.ReadBytes(250); AltSounds = br.ReadBytes(250); numObjects = br.ReadInt32(); for (int i = 0; i < 100; i++) { ObjectTypes[i].type = (EditorObjectType)(br.ReadSByte()); } for (int i = 0; i < 100; i++) { ObjectTypes[i].id = br.ReadByte(); } for (int i = 0; i < 100; i++) { ObjectTypes[i].strength = new Fix(br.ReadInt32()); //Console.WriteLine("type: {0}({3})\nid: {1}\nstr: {2}", ObjectTypes[i].type, ObjectTypes[i].id, ObjectTypes[i].strength, (int)ObjectTypes[i].type); } FirstMultiBitmapNum = br.ReadInt32(); reactor.NumGuns = br.ReadInt32(); for (int y = 0; y < 4; y++) { reactor.GunPoints[y] = FixVector.FromRawValues(br.ReadInt32(), br.ReadInt32(), br.ReadInt32()); } for (int y = 0; y < 4; y++) { reactor.GunDirs[y] = FixVector.FromRawValues(br.ReadInt32(), br.ReadInt32(), br.ReadInt32()); } exitModelnum = br.ReadInt32(); destroyedExitModelnum = br.ReadInt32(); for (int i = 0; i < 1800; i++) { BitmapXLATData[i] = br.ReadUInt16(); } } //Init a bogus texture for all piggyfiles PIGImage bogusTexture = new PIGImage(64, 64, 0, 0, 0, 0, "bogus", 0); bogusTexture.Data = new byte[64 * 64]; //Create an X using descent 1 palette indicies. For accuracy. Heh for (int i = 0; i < 4096; i++) { bogusTexture.Data[i] = 85; } for (int i = 0; i < 64; i++) { bogusTexture.Data[i * 64 + i] = 193; bogusTexture.Data[i * 64 + (63 - i)] = 193; } Bitmaps.Add(bogusTexture); if (LoadData) { br.BaseStream.Seek(DataPointer, SeekOrigin.Begin); } int numBitmaps = br.ReadInt32(); int numSounds = br.ReadInt32(); for (int i = 0; i < numBitmaps; i++) { bool hashitnull = false; byte[] localNameBytes = br.ReadBytes(8); char[] localname = new char[8]; for (int j = 0; j < 8; j++) { char c = (char)localNameBytes[j]; if (c == 0) { hashitnull = true; } if (!hashitnull) { localname[j] = c; } } string imagename = new String(localname); imagename = imagename.Trim(' ', '\0'); byte framedata = br.ReadByte(); byte lx = br.ReadByte(); byte ly = br.ReadByte(); byte flags = br.ReadByte(); byte average = br.ReadByte(); int offset = br.ReadInt32(); PIGImage image = new PIGImage(lx, ly, framedata, flags, average, offset, imagename, big); image.LocalName = localNameBytes; Bitmaps.Add(image); } for (int i = 0; i < numSounds; i++) { bool hashitnull = false; byte[] localNameBytes = br.ReadBytes(8); char[] localname = new char[8]; for (int j = 0; j < 8; j++) { char c = (char)localNameBytes[j]; if (c == 0) { hashitnull = true; } if (!hashitnull) { localname[j] = c; } } string soundname = new string(localname); soundname = soundname.Trim(' ', '\0'); int num1 = br.ReadInt32(); int num2 = br.ReadInt32(); int offset = br.ReadInt32(); SoundData sound = new SoundData { Data = null }; sound.Name = soundname; sound.LocalName = localNameBytes; sound.Offset = offset; sound.Length = num1; Sounds.Add(sound); } int basePointer = (int)br.BaseStream.Position; for (int i = 1; i < Bitmaps.Count; i++) { br.BaseStream.Seek(basePointer + Bitmaps[i].Offset, SeekOrigin.Begin); if ((Bitmaps[i].Flags & PIGImage.BM_FLAG_RLE) != 0) { int compressedSize = br.ReadInt32(); Bitmaps[i].Data = br.ReadBytes(compressedSize - 4); } else { Bitmaps[i].Data = br.ReadBytes(Bitmaps[i].Width * Bitmaps[i].Height); } } for (int i = 0; i < Sounds.Count; i++) { br.BaseStream.Seek(basePointer + Sounds[i].Offset, SeekOrigin.Begin); var soundBytes = br.ReadBytes(Sounds[i].Length); var ps = Sounds[i]; ps.Data = soundBytes; } br.Dispose(); }
public LevelVertex(FixVector location) { this.location = location; }
public FixMatrix(FixVector right, FixVector up, FixVector forward) { this.Right = right; this.Up = up; this.Forward = forward; }
private void Execute(byte[] data, int offset, Polymodel mainModel, Submodel model, BSPModel currentModel) { short instruction = GetShort(data, ref offset); while (true) { switch (instruction) { case ModelOpCode.End: return; case ModelOpCode.Points: { short pointc = GetShort(data, ref offset); for (int i = 0; i < pointc; i++) { interpPoints[i] = GetFixVector(data, ref offset); } } break; case ModelOpCode.FlatPoly: //FLATPOLY { short pointc = GetShort(data, ref offset); FixVector point = GetFixVector(data, ref offset); FixVector normal = GetFixVector(data, ref offset); short color = GetShort(data, ref offset); short[] points = new short[pointc]; //TODO: seems wasteful to do all these allocations? for (int i = 0; i < pointc; i++) { points[i] = GetShort(data, ref offset); } if (pointc % 2 == 0) { GetShort(data, ref offset); } if (pointc >= 3) { var triangle = new BSPFace(); triangle.Normal = new Vector3(normal.X, normal.Y, normal.Z); triangle.Point = new Vector3(point.X, point.Y, point.Z); triangle.Color = color; triangle.TextureID = -1; currentModel.Polygons.Add(triangle); for (int i = 0; i < pointc; i++) { var vxA = interpPoints[points[i]].X; var vyA = interpPoints[points[i]].Y; var vzA = interpPoints[points[i]].Z; triangle.Points.Add(new BSPVertex { Point = new Vector3(vxA, vyA, vzA), UVs = new Vector3(0.0f, 0.0f, 0.0f) }); } } } break; case ModelOpCode.TexturedPoly: //TMAPPOLY { short pointc = GetShort(data, ref offset); FixVector point = GetFixVector(data, ref offset); FixVector normal = GetFixVector(data, ref offset); short texture = GetShort(data, ref offset); short[] points = new short[pointc]; //TODO: seems wasteful to do all these allocations? FixVector[] uvls = new FixVector[pointc]; for (int i = 0; i < pointc; i++) { points[i] = GetShort(data, ref offset); } if (pointc % 2 == 0) { GetShort(data, ref offset); } for (int i = 0; i < pointc; i++) { uvls[i] = GetFixVector(data, ref offset); } if (pointc >= 3) { var triangle = new BSPFace(); triangle.Normal = new Vector3(normal.X, normal.Y, normal.Z); triangle.Point = new Vector3(point.X, point.Y, point.Z); triangle.TextureID = texture; currentModel.Polygons.Add(triangle); for (int i = 0; i < pointc; i++) { var vxA = interpPoints[points[i]].X; var vyA = interpPoints[points[i]].Y; var vzA = interpPoints[points[i]].Z; var uvxA = uvls[i].X; var uvyA = uvls[i].Y; triangle.Points.Add(new BSPVertex { Point = new Vector3(vxA, vyA, vzA), UVs = new Vector3(uvxA, uvyA, 0.0f) }); } } } break; case ModelOpCode.SortNormal: //SORTNORM { IsPartitioned = true; int baseOffset = offset - 2; int n_points = GetShort(data, ref offset); FixVector norm = GetFixVector(data, ref offset); FixVector point = GetFixVector(data, ref offset); short backOffset = GetShort(data, ref offset); short frontOffset = GetShort(data, ref offset); Execute(data, baseOffset + frontOffset, mainModel, model, currentModel); Execute(data, baseOffset + backOffset, mainModel, model, currentModel); } break; case ModelOpCode.Rod: //RODBM { offset += 34; } break; case ModelOpCode.SubCall: //SUBCALL { int baseOffset = offset - 2; short submodelNum = GetShort(data, ref offset); FixVector submodelOffset = GetFixVector(data, ref offset); short modelOffset = GetShort(data, ref offset); offset += 2; Submodel newModel = mainModel.Submodels[submodelNum]; currentModel.modelOffset = submodelOffset; Execute(data, baseOffset + modelOffset, mainModel, newModel, modelDatas[submodelNum]); } break; case ModelOpCode.DefinePointStart: //DEFPSTART { short pointc = GetShort(data, ref offset); short firstPoint = GetShort(data, ref offset); offset += 2; for (int i = 0; i < pointc; i++) { interpPoints[i + firstPoint] = GetFixVector(data, ref offset); } } break; case ModelOpCode.Glow: offset += 2; break; default: throw new Exception(string.Format("Unknown interpreter instruction {0} at offset {1}\n", instruction, offset)); } instruction = GetShort(data, ref offset); } }
public Robot ReadRobot(BinaryReader br) { Robot robot = new Robot(); robot.ModelNum = br.ReadInt32(); for (int s = 0; s < Polymodel.MaxGuns; s++) { robot.GunPoints[s] = FixVector.FromRawValues(br.ReadInt32(), br.ReadInt32(), br.ReadInt32()); } for (int s = 0; s < 8; s++) { robot.GunSubmodels[s] = br.ReadByte(); } robot.HitVClipNum = br.ReadInt16(); robot.HitSoundNum = br.ReadInt16(); robot.DeathVClipNum = br.ReadInt16(); robot.DeathSoundNum = br.ReadInt16(); robot.WeaponType = br.ReadSByte(); robot.WeaponTypeSecondary = br.ReadSByte(); robot.NumGuns = br.ReadSByte(); robot.ContainsID = br.ReadSByte(); robot.ContainsCount = br.ReadSByte(); robot.ContainsProbability = br.ReadSByte(); robot.ContainsType = br.ReadSByte(); robot.Kamikaze = br.ReadSByte(); robot.ScoreValue = br.ReadInt16(); robot.DeathExplosionRadius = br.ReadByte(); robot.EnergyDrain = br.ReadByte(); robot.Lighting = new Fix(br.ReadInt32()); robot.Strength = new Fix(br.ReadInt32()); robot.Mass = new Fix(br.ReadInt32()); robot.Drag = new Fix(br.ReadInt32()); for (int s = 0; s < Robot.NumDifficultyLevels; s++) { robot.FieldOfView[s] = new Fix(br.ReadInt32()); } for (int s = 0; s < Robot.NumDifficultyLevels; s++) { robot.FiringWait[s] = new Fix(br.ReadInt32()); } for (int s = 0; s < Robot.NumDifficultyLevels; s++) { robot.FiringWaitSecondary[s] = new Fix(br.ReadInt32()); } for (int s = 0; s < Robot.NumDifficultyLevels; s++) { robot.TurnTime[s] = new Fix(br.ReadInt32()); } for (int s = 0; s < Robot.NumDifficultyLevels; s++) { robot.MaxSpeed[s] = new Fix(br.ReadInt32()); } for (int s = 0; s < Robot.NumDifficultyLevels; s++) { robot.CircleDistance[s] = new Fix(br.ReadInt32()); } for (int s = 0; s < Robot.NumDifficultyLevels; s++) { robot.RapidfireCount[s] = br.ReadSByte(); } for (int s = 0; s < Robot.NumDifficultyLevels; s++) { robot.EvadeSpeed[s] = br.ReadSByte(); } robot.CloakType = (RobotCloakType)br.ReadSByte(); robot.AttackType = (RobotAttackType)br.ReadSByte(); robot.SeeSound = br.ReadByte(); robot.AttackSound = br.ReadByte(); robot.ClawSound = br.ReadByte(); robot.TauntSound = br.ReadByte(); robot.BossFlag = (RobotBossType)br.ReadSByte(); robot.Companion = br.ReadSByte() != 0 ? true : false; robot.SmartBlobsOnDeath = br.ReadSByte(); robot.SmartBlobsOnHit = br.ReadSByte(); robot.Thief = br.ReadSByte() != 0 ? true : false; robot.Pursuit = br.ReadSByte(); robot.LightCast = br.ReadSByte(); robot.DeathRollTime = br.ReadSByte(); robot.Flags = br.ReadByte(); br.ReadBytes(3); robot.DeathRollSound = br.ReadByte(); robot.Glow = br.ReadByte(); robot.Behavior = (RobotAIType)br.ReadByte(); robot.Aim = br.ReadByte(); for (int v = 0; v < 9; v++) { for (int u = 0; u < 5; u++) { robot.AnimStates[v, u].NumJoints = br.ReadInt16(); robot.AnimStates[v, u].Offset = br.ReadInt16(); } } robot.Always0xABCD = br.ReadInt32(); return(robot); }
private Vector3 MakeVector3(FixVector point) { return(new Vector3(point.X, point.Y, point.Z)); }
public FixVector Add(FixVector other) { return(new FixVector(this.X + other.X, this.Y + other.Y, this.Z + other.Z)); }
public FixVector Sub(FixVector other) { return(new FixVector(this.X - other.X, this.Y - other.Y, this.Z - other.Z)); }