private void CreateLocalLists() { foreach (Robot robot in BaseFile.Robots) { Robots.Add(robot); } foreach (Weapon weapon in BaseFile.Weapons) { Weapons.Add(weapon); } foreach (Polymodel model in BaseFile.Models) { Models.Add(model); } foreach (JointPos joint in BaseFile.Joints) { Joints.Add(joint); } foreach (ushort bm in BaseFile.ObjBitmaps) { ObjBitmaps.Add(bm); } foreach (ushort bm in BaseFile.ObjBitmapPointers) { ObjBitmapPointers.Add(bm); } }
private void GenerateObjectBitmapTables() { ObjBitmaps.Clear(); ObjBitmapPointers.Clear(); int lastObjectBitmap = VHAMFile.NumDescent2ObjBitmaps; int lastObjectBitmapPointer = VHAMFile.NumDescent2ObjBitmapPointers; PIGImage img; EClip clip; Dictionary <string, int> objectBitmapMapping = new Dictionary <string, int>(); //Add the HAM file's object bitmaps so they can be referenced. for (int i = 0; i < BaseHAM.BaseFile.ObjBitmaps.Count; i++) { img = BaseHAM.piggyFile.GetImage(BaseHAM.BaseFile.ObjBitmaps[i]); if (!img.IsAnimated && !objectBitmapMapping.ContainsKey(img.Name)) { objectBitmapMapping.Add(img.Name, i); } } //Add EClip names for (int i = 0; i < BaseHAM.EClips.Count; i++) { clip = BaseHAM.EClips[i]; if (clip.ChangingObjectTexture != -1) { objectBitmapMapping.Add(clip.Name, clip.ChangingObjectTexture); } } Polymodel model; for (int i = 0; i < Models.Count; i++) { model = Models[i]; model.FirstTexture = (ushort)lastObjectBitmapPointer; model.NumTextures = (byte)model.TextureList.Count; foreach (string textureName in model.TextureList) { if (!objectBitmapMapping.ContainsKey(textureName.ToLower())) { objectBitmapMapping.Add(textureName.ToLower(), lastObjectBitmap); ObjBitmaps.Add((ushort)(BaseHAM.piggyFile.GetBitmapIDFromName(textureName))); lastObjectBitmap++; } ObjBitmapPointers.Add((ushort)objectBitmapMapping[textureName.ToLower()]); lastObjectBitmapPointer++; } } }
//--------------------------------------------------------------------- // READING //--------------------------------------------------------------------- /// <summary> /// Converts all the base file's data classes into the editor class for that type. /// </summary> public void CreateLocalLists() { //TODO: This is just passthrough for now, need "editor" classes foreach (ushort texture in BaseFile.Textures) { Textures.Add(texture); } foreach (TMAPInfo tmapInfo in BaseFile.TMapInfo) { TMapInfo.Add(tmapInfo); } Array.Copy(BaseFile.Sounds, Sounds, 254); Array.Copy(BaseFile.AltSounds, AltSounds, 254); foreach (VClip clip in BaseFile.VClips) { VClips.Add(clip); } foreach (EClip clip in BaseFile.EClips) { EClips.Add(clip); } foreach (WClip clip in BaseFile.WClips) { WClips.Add(clip); } foreach (Robot robot in BaseFile.Robots) { Robots.Add(robot); } foreach (JointPos joint in BaseFile.Joints) { Joints.Add(joint); } foreach (Weapon weapon in BaseFile.Weapons) { Weapons.Add(weapon); } foreach (Polymodel model in BaseFile.Models) { Models.Add(model); } foreach (ushort gauge in BaseFile.Gauges) { Gauges.Add(gauge); } foreach (ushort gauge in BaseFile.GaugesHires) { GaugesHires.Add(gauge); } PlayerShip = BaseFile.PlayerShip; foreach (ushort cockpit in BaseFile.Cockpits) { Cockpits.Add(cockpit); } foreach (Reactor reactor in BaseFile.Reactors) { Reactors.Add(reactor); } foreach (Powerup powerup in BaseFile.Powerups) { Powerups.Add(powerup); } FirstMultiBitmapNum = BaseFile.FirstMultiBitmapNum; for (int i = 0; i < 2620; i++) { BitmapXLATData[i] = BaseFile.BitmapXLATData[i]; } foreach (ushort bm in BaseFile.ObjBitmaps) { ObjBitmaps.Add(bm); } foreach (ushort bm in BaseFile.ObjBitmapPointers) { ObjBitmapPointers.Add(bm); } }
private void GenerateObjectBitmapTables(bool compatObjBitmaps) { ObjBitmaps.Clear(); ObjBitmapPointers.Clear(); int lastObjectBitmap = 0; int lastObjectBitmapPointer = 0; Dictionary <string, int> objectBitmapMapping = new Dictionary <string, int>(); Polymodel model; if (compatObjBitmaps) { int lastShipmodel = PlayerShip.ModelNum; if (Models[PlayerShip.ModelNum].DyingModelnum != -1) { lastShipmodel = Models[PlayerShip.ModelNum].DyingModelnum; } else if (Models[PlayerShip.ModelNum].SimplerModels != 0) { lastShipmodel = Models[PlayerShip.ModelNum].SimplerModels - 1; } for (int i = 0; i < Models.Count; i++) { model = Models[i]; model.FirstTexture = (ushort)lastObjectBitmapPointer; model.NumTextures = (byte)model.TextureList.Count; if (i == lastShipmodel && i != PlayerShip.ModelNum) { //Inject multiplayer bitmaps FirstMultiBitmapNum = lastObjectBitmapPointer; for (int j = 0; j < 14; j++) { ObjBitmaps.Add((ushort)(multiplayerBitmaps[j])); ObjBitmapPointers.Add((ushort)(ObjBitmaps.Count - 1)); lastObjectBitmap++; lastObjectBitmapPointer++; } //Don't load textures for the dying ship. Because reasons. model.FirstTexture = Models[PlayerShip.ModelNum].FirstTexture; model.NumTextures = Models[PlayerShip.ModelNum].NumTextures; } else { foreach (string textureName in model.TextureList) { if (EClipNameMapping.ContainsKey(textureName.ToLower()) && !objectBitmapMapping.ContainsKey(textureName.ToLower())) { objectBitmapMapping.Add(textureName.ToLower(), ObjBitmaps.Count); ObjBitmaps.Add(0); //temp, will be remapped later lastObjectBitmap++; } //In the compatible mode, all textures are redundant except vclips. if (objectBitmapMapping.ContainsKey(textureName.ToLower())) { ObjBitmapPointers.Add((ushort)objectBitmapMapping[textureName.ToLower()]); lastObjectBitmapPointer++; } else { ObjBitmapPointers.Add((ushort)lastObjectBitmap); lastObjectBitmapPointer++; ObjBitmaps.Add((ushort)(piggyFile.GetBitmapIDFromName(textureName))); lastObjectBitmap++; } } //I hate hacks, but parallax couldn't keep tabs on their bitmaps.tbl file so... //Descent's smart missile children are defined with model textures despite not being models so for compatibility add them in if (i == Weapons[18].ModelNum || i == Weapons[28].ModelNum) //player and robot mega missiles { ObjBitmaps.Add((ushort)(piggyFile.GetBitmapIDFromName("glow04"))); ObjBitmapPointers.Add((ushort)(ObjBitmaps.Count - 1)); ObjBitmaps.Add((ushort)(piggyFile.GetBitmapIDFromName("rbot046"))); ObjBitmapPointers.Add((ushort)(ObjBitmaps.Count - 1)); lastObjectBitmapPointer += 2; lastObjectBitmap += 2; } //ugh if (i == lastShipmodel && i == PlayerShip.ModelNum) { //Inject multiplayer bitmaps FirstMultiBitmapNum = lastObjectBitmapPointer; for (int j = 0; j < 14; j++) { ObjBitmaps.Add((ushort)(multiplayerBitmaps[j])); ObjBitmapPointers.Add((ushort)(ObjBitmaps.Count - 1)); lastObjectBitmap++; lastObjectBitmapPointer++; } } } } } else { for (int i = 0; i < Models.Count; i++) { model = Models[i]; model.FirstTexture = (ushort)lastObjectBitmapPointer; model.NumTextures = (byte)model.TextureList.Count; foreach (string textureName in model.TextureList) { if (!objectBitmapMapping.ContainsKey(textureName.ToLower())) { objectBitmapMapping.Add(textureName.ToLower(), lastObjectBitmap); ObjBitmaps.Add((ushort)(piggyFile.GetBitmapIDFromName(textureName))); lastObjectBitmap++; } ObjBitmapPointers.Add((ushort)objectBitmapMapping[textureName.ToLower()]); lastObjectBitmapPointer++; } } //Inject multiplayer bitmaps FirstMultiBitmapNum = lastObjectBitmapPointer; for (int i = 0; i < 14; i++) { ObjBitmaps.Add((ushort)(multiplayerBitmaps[i])); ObjBitmapPointers.Add((ushort)(ObjBitmaps.Count - 1)); } } //Update EClips EClip clip; for (int i = 0; i < EClips.Count; i++) { clip = EClips[i]; if (objectBitmapMapping.ContainsKey(EClips[i].Name.ToLower())) { clip.ChangingObjectTexture = (short)objectBitmapMapping[EClips[i].Name.ToLower()]; ObjBitmaps[clip.ChangingObjectTexture] = (ushort)(clip.Clip.Frames[0]); } } }
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 void Read(Stream stream) { BinaryReader br; br = new BinaryReader(stream); HAMDataReader bm = new HAMDataReader(); uint sig = br.ReadUInt32(); if (sig != Util.MakeSig('M', 'A', 'H', 'X')) { br.Dispose(); throw new InvalidDataException("VHAMFile::Read: V-HAM file has bad header."); } int version = br.ReadInt32(); if (version != 1) { br.Dispose(); throw new InvalidDataException(string.Format("VHAMFile::Read: V-HAM file has bad version. Got {0}, but expected 1.", version)); } int numWeapons = br.ReadInt32(); for (int i = 0; i < numWeapons; i++) { Weapons.Add(bm.ReadWeapon(br)); Weapons[i].ID = i + NumDescent2WeaponTypes; } int numRobots = br.ReadInt32(); for (int i = 0; i < numRobots; i++) { Robots.Add(bm.ReadRobot(br)); Robots[i].ID = i + NumDescent2RobotTypes; } int numJoints = br.ReadInt32(); for (int i = 0; i < numJoints; 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.Add(joint); } int numModels = br.ReadInt32(); for (int i = 0; i < numModels; i++) { Models.Add(bm.ReadPolymodelInfo(br)); Models[i].ID = i + NumDescent2Polymodels; } for (int x = 0; x < numModels; x++) { Models[x].InterpreterData = br.ReadBytes(Models[x].ModelIDTASize); } for (int i = 0; i < numModels; i++) { Models[i].DyingModelnum = br.ReadInt32(); } for (int i = 0; i < numModels; i++) { Models[i].DeadModelnum = br.ReadInt32(); } int numObjBitmaps = br.ReadInt32(); for (int i = 0; i < numObjBitmaps; i++) { ObjBitmaps.Add(br.ReadUInt16()); } int numObjBitmapPointers = br.ReadInt32(); for (int i = 0; i < numObjBitmapPointers; i++) { ObjBitmapPointers.Add(br.ReadUInt16()); } br.Dispose(); }