diff --git a/Deps/TRGE.Coord.dll b/Deps/TRGE.Coord.dll index 157050b06..aa1c9b0d7 100644 Binary files a/Deps/TRGE.Coord.dll and b/Deps/TRGE.Coord.dll differ diff --git a/SFXExport/Program.cs b/SFXExport/Program.cs index b890dd5e5..53b7918f0 100644 --- a/SFXExport/Program.cs +++ b/SFXExport/Program.cs @@ -79,19 +79,19 @@ private static void ExtractFromSFX(string file, TRGameVersion version, bool rema private static void ExtractFromPHD(string file, TRGameVersion version) { TR1Level level = new TR1LevelControl().Read(file); - for (int i = 0; i < level.NumSampleIndices; i++) + for (int i = 0; i < level.SampleIndices.Count; i++) { uint sampleStart = level.SampleIndices[i]; - uint sampleEnd = i < level.NumSampleIndices - 1 ? level.SampleIndices[i + 1] : (uint)level.Samples.Length; - if (sampleEnd > level.Samples.Length) + uint sampleEnd = i < level.SampleIndices.Count - 1 ? level.SampleIndices[i + 1] : (uint)level.Samples.Count; + if (sampleEnd > level.Samples.Count) { - sampleEnd = (uint)level.Samples.Length; + sampleEnd = (uint)level.Samples.Count; } using BinaryWriter writer = new(File.Create(Path.Combine(version.ToString(), i + ".wav"))); for (uint j = sampleStart; j < sampleEnd; j++) { - writer.Write(level.Samples[j]); + writer.Write(level.Samples[(int)j]); } } } diff --git a/TREnvironmentEditor/Model/Types/Mirroring/EMMirrorFunction.cs b/TREnvironmentEditor/Model/Types/Mirroring/EMMirrorFunction.cs index a1570bd72..6564bacff 100644 --- a/TREnvironmentEditor/Model/Types/Mirroring/EMMirrorFunction.cs +++ b/TREnvironmentEditor/Model/Types/Mirroring/EMMirrorFunction.cs @@ -1080,7 +1080,7 @@ private static void MirrorTextures(TR1Level level) // Include all animated texture references too foreach (TRAnimatedTexture anim in level.AnimatedTextures) { - for (int i = 0; i < anim.Textures.Length; i++) + for (int i = 0; i < anim.Textures.Count; i++) { textureReferences.Add(anim.Textures[i]); } @@ -1161,7 +1161,7 @@ private static void MirrorTextures(TR2Level level) // Include all animated texture references too foreach (TRAnimatedTexture anim in level.AnimatedTextures) { - for (int i = 0; i < anim.Textures.Length; i++) + for (int i = 0; i < anim.Textures.Count; i++) { textureReferences.Add(anim.Textures[i]); } @@ -1232,7 +1232,7 @@ private static void MirrorTextures(TR3Level level) foreach (TRAnimatedTexture anim in level.AnimatedTextures) { - for (int i = 0; i < anim.Textures.Length; i++) + for (int i = 0; i < anim.Textures.Count; i++) { textureReferences.Add(anim.Textures[i]); } @@ -1241,7 +1241,7 @@ private static void MirrorTextures(TR3Level level) MirrorObjectTextures(textureReferences, level.ObjectTextures); } - private static void MirrorObjectTextures(ISet textureReferences, TRObjectTexture[] objectTextures) + private static void MirrorObjectTextures(ISet textureReferences, List objectTextures) { // Flip the object texture vertices in the same way as done for faces foreach (ushort textureRef in textureReferences) @@ -1263,11 +1263,11 @@ private static void MirrorObjectTextures(ISet textureReferences, TRObjec } } - private static void MirrorDependentFaces(IEnumerable models, ISet textureReferences, Func meshAction) + private static void MirrorDependentFaces(IEnumerable models, ISet textureReferences, Func> meshAction) { foreach (TRModel model in models) { - TRMesh[] meshes = meshAction.Invoke(model.ID); + List meshes = meshAction.Invoke(model.ID); if (meshes == null) { continue; diff --git a/TREnvironmentEditor/Model/Types/Mirroring/EMMirrorModelFunction.cs b/TREnvironmentEditor/Model/Types/Mirroring/EMMirrorModelFunction.cs index ad31ccc36..724cfb44e 100644 --- a/TREnvironmentEditor/Model/Types/Mirroring/EMMirrorModelFunction.cs +++ b/TREnvironmentEditor/Model/Types/Mirroring/EMMirrorModelFunction.cs @@ -13,8 +13,8 @@ public override void ApplyToLevel(TR1Level level) List meshes = new(); foreach (uint modelID in ModelIDs) { - TRMesh[] modelMeshes = TRMeshUtilities.GetModelMeshes(level, (TR1Type)modelID); - if (modelMeshes == null || modelMeshes.Length > 1) + List modelMeshes = TRMeshUtilities.GetModelMeshes(level, (TR1Type)modelID); + if (modelMeshes == null || modelMeshes.Count > 1) { throw new NotSupportedException("Only models with single meshes can be mirrored."); } @@ -30,8 +30,8 @@ public override void ApplyToLevel(TR2Level level) List meshes = new(); foreach (uint modelID in ModelIDs) { - TRMesh[] modelMeshes = TRMeshUtilities.GetModelMeshes(level, (TR2Type)modelID); - if (modelMeshes == null || modelMeshes.Length > 1) + List modelMeshes = TRMeshUtilities.GetModelMeshes(level, (TR2Type)modelID); + if (modelMeshes == null || modelMeshes.Count > 1) { throw new NotSupportedException("Only models with single meshes can be mirrored."); } @@ -47,8 +47,8 @@ public override void ApplyToLevel(TR3Level level) List meshes = new(); foreach (uint modelID in ModelIDs) { - TRMesh[] modelMeshes = TRMeshUtilities.GetModelMeshes(level, (TR3Type)modelID); - if (modelMeshes == null || modelMeshes.Length > 1) + List modelMeshes = TRMeshUtilities.GetModelMeshes(level, (TR3Type)modelID); + if (modelMeshes == null || modelMeshes.Count> 1) { throw new NotSupportedException("Only models with single meshes can be mirrored."); } @@ -106,7 +106,7 @@ private static ISet MirrorMeshes(List meshes) return textureReferences; } - private static void MirrorObjectTextures(ISet textureReferences, TRObjectTexture[] objectTextures) + private static void MirrorObjectTextures(ISet textureReferences, List objectTextures) { foreach (ushort textureRef in textureReferences) { diff --git a/TREnvironmentEditor/Model/Types/Mirroring/EMMirrorObjectTexture.cs b/TREnvironmentEditor/Model/Types/Mirroring/EMMirrorObjectTexture.cs index 4e03d5fb1..f7ad371f6 100644 --- a/TREnvironmentEditor/Model/Types/Mirroring/EMMirrorObjectTexture.cs +++ b/TREnvironmentEditor/Model/Types/Mirroring/EMMirrorObjectTexture.cs @@ -22,7 +22,7 @@ public override void ApplyToLevel(TR3Level level) MirrorObjectTextures(level.ObjectTextures); } - private void MirrorObjectTextures(TRObjectTexture[] levelTextures) + private void MirrorObjectTextures(List levelTextures) { foreach (ushort textureRef in Textures) { diff --git a/TREnvironmentEditor/Model/Types/Models/EMConvertSpriteSequenceFunction.cs b/TREnvironmentEditor/Model/Types/Models/EMConvertSpriteSequenceFunction.cs index 43adbd575..38b92ee74 100644 --- a/TREnvironmentEditor/Model/Types/Models/EMConvertSpriteSequenceFunction.cs +++ b/TREnvironmentEditor/Model/Types/Models/EMConvertSpriteSequenceFunction.cs @@ -25,11 +25,11 @@ public override void ApplyToLevel(TR3Level level) UpdateSpriteEntities(level.Entities); } - private void ConvertSpriteSequence(TRSpriteSequence[] sequences) + private void ConvertSpriteSequence(List sequences) { - if (Array.Find(sequences, s => s.SpriteID == NewSpriteID) == null) + if (sequences.Find(s => s.SpriteID == NewSpriteID) == null) { - TRSpriteSequence oldSequence = Array.Find(sequences, s => s.SpriteID == OldSpriteID); + TRSpriteSequence oldSequence = sequences.Find(s => s.SpriteID == OldSpriteID); if (oldSequence != null) { oldSequence.SpriteID = NewSpriteID; diff --git a/TREnvironmentEditor/Model/Types/Models/EMCopySpriteSequenceFunction.cs b/TREnvironmentEditor/Model/Types/Models/EMCopySpriteSequenceFunction.cs index 8afd1cd81..4b20f0ceb 100644 --- a/TREnvironmentEditor/Model/Types/Models/EMCopySpriteSequenceFunction.cs +++ b/TREnvironmentEditor/Model/Types/Models/EMCopySpriteSequenceFunction.cs @@ -9,26 +9,17 @@ public class EMCopySpriteSequenceFunction : BaseEMFunction public override void ApplyToLevel(TR1Level level) { - List sequences = level.SpriteSequences.ToList(); - CopySpriteSequence(sequences); - level.SpriteSequences = sequences.ToArray(); - level.NumSpriteSequences = (uint)sequences.Count; + CopySpriteSequence(level.SpriteSequences); } public override void ApplyToLevel(TR2Level level) { - List sequences = level.SpriteSequences.ToList(); - CopySpriteSequence(sequences); - level.SpriteSequences = sequences.ToArray(); - level.NumSpriteSequences = (uint)sequences.Count; + CopySpriteSequence(level.SpriteSequences); } public override void ApplyToLevel(TR3Level level) { - List sequences = level.SpriteSequences.ToList(); - CopySpriteSequence(sequences); - level.SpriteSequences = sequences.ToArray(); - level.NumSpriteSequences = (uint)sequences.Count; + CopySpriteSequence(level.SpriteSequences); } private void CopySpriteSequence(List sequences) diff --git a/TREnvironmentEditor/Model/Types/Models/EMImportNonGraphicsModelFunction.cs b/TREnvironmentEditor/Model/Types/Models/EMImportNonGraphicsModelFunction.cs index a802ad41a..1cb996955 100644 --- a/TREnvironmentEditor/Model/Types/Models/EMImportNonGraphicsModelFunction.cs +++ b/TREnvironmentEditor/Model/Types/Models/EMImportNonGraphicsModelFunction.cs @@ -27,7 +27,7 @@ public override void ApplyToLevel(TR1Level level) }; importer.Import(); - RemapFaces(data, level.NumObjectTextures - 1, modelID => TRMeshUtilities.GetModelMeshes(level, (TR1Type)modelID)); + RemapFaces(data, level.ObjectTextures.Count - 1, modelID => TRMeshUtilities.GetModelMeshes(level, (TR1Type)modelID)); } public override void ApplyToLevel(TR2Level level) @@ -48,7 +48,7 @@ public override void ApplyToLevel(TR2Level level) }; importer.Import(); - RemapFaces(data, level.NumObjectTextures - 1, modelID => TRMeshUtilities.GetModelMeshes(level, (TR2Type)modelID)); + RemapFaces(data, level.ObjectTextures.Count - 1, modelID => TRMeshUtilities.GetModelMeshes(level, (TR2Type)modelID)); } public override void ApplyToLevel(TR3Level level) @@ -69,7 +69,7 @@ public override void ApplyToLevel(TR3Level level) }; importer.Import(); - RemapFaces(data, level.NumObjectTextures - 1, modelID => TRMeshUtilities.GetModelMeshes(level, (TR3Type)modelID)); + RemapFaces(data, level.ObjectTextures.Count - 1, modelID => TRMeshUtilities.GetModelMeshes(level, (TR3Type)modelID)); } private List PrepareImportData(List existingModels) @@ -85,11 +85,11 @@ private List PrepareImportData(List existingModels) return importData; } - private static void RemapFaces(List data, uint maximumTexture, Func meshAction) + private static void RemapFaces(List data, int maximumTexture, Func> meshAction) { foreach (EMMeshTextureData textureData in data) { - TRMesh[] meshes = meshAction.Invoke(textureData.ModelID); + List meshes = meshAction.Invoke(textureData.ModelID); foreach (TRMesh mesh in meshes) { foreach (TRFace3 face in mesh.ColouredTriangles) @@ -112,7 +112,7 @@ private static void RemapFaces(List data, uint maximumTexture } } - private static ushort SelectReplacementTexture(EMMeshTextureData data, ushort currentTexture, int defaultTexture, uint maximumTexture) + private static ushort SelectReplacementTexture(EMMeshTextureData data, ushort currentTexture, int defaultTexture, int maximumTexture) { if (data.TextureMap != null && data.TextureMap.ContainsKey(currentTexture)) { diff --git a/TREnvironmentEditor/Model/Types/Textures/EMCreateTextureFunction.cs b/TREnvironmentEditor/Model/Types/Textures/EMCreateTextureFunction.cs index 802e5da5b..ba3d54440 100644 --- a/TREnvironmentEditor/Model/Types/Textures/EMCreateTextureFunction.cs +++ b/TREnvironmentEditor/Model/Types/Textures/EMCreateTextureFunction.cs @@ -16,10 +16,7 @@ public override void ApplyToLevel(TR1Level level) TR1TexturePacker packer = new(level); List textures = new(level.ObjectTextures); - List mapping = BuildAndPackTextures(packer, textures); - level.ObjectTextures = textures.ToArray(); - level.NumObjectTextures = (uint)textures.Count; - + List mapping = BuildAndPackTextures(packer, level.ObjectTextures); mapping.ForEach(m => new EMRefaceFunction { TextureMap = m @@ -31,10 +28,7 @@ public override void ApplyToLevel(TR2Level level) TR2TexturePacker packer = new(level); List textures = new(level.ObjectTextures); - List mapping = BuildAndPackTextures(packer, textures); - level.ObjectTextures = textures.ToArray(); - level.NumObjectTextures = (uint)textures.Count; - + List mapping = BuildAndPackTextures(packer, level.ObjectTextures); mapping.ForEach(m => new EMRefaceFunction { TextureMap = m @@ -46,10 +40,7 @@ public override void ApplyToLevel(TR3Level level) TR3TexturePacker packer = new(level); List textures = new(level.ObjectTextures); - List mapping = BuildAndPackTextures(packer, textures); - level.ObjectTextures = textures.ToArray(); - level.NumObjectTextures = (uint)textures.Count; - + List mapping = BuildAndPackTextures(packer, level.ObjectTextures); mapping.ForEach(m => new EMRefaceFunction { TextureMap = m diff --git a/TRLevelControl/Control/TR1LevelControl.cs b/TRLevelControl/Control/TR1LevelControl.cs index e7e265a0e..23df8684f 100644 --- a/TRLevelControl/Control/TR1LevelControl.cs +++ b/TRLevelControl/Control/TR1LevelControl.cs @@ -99,29 +99,14 @@ protected override void Read(TRLevelReader reader) uint numFloorData = reader.ReadUInt32(); _level.FloorData = reader.ReadUInt16s(numFloorData).ToList(); - //Mesh Data - //This tells us how much mesh data (# of words/uint16s) coming up - //just like the rooms previously. - _level.NumMeshData = reader.ReadUInt32(); - _level.RawMeshData = new ushort[_level.NumMeshData]; - - for (int i = 0; i < _level.NumMeshData; i++) - { - _level.RawMeshData[i] = reader.ReadUInt16(); - } + uint numMeshData = reader.ReadUInt32(); + ushort[] rawMeshData = reader.ReadUInt16s(numMeshData); //Mesh Pointers - _level.NumMeshPointers = reader.ReadUInt32(); - _level.MeshPointers = new uint[_level.NumMeshPointers]; + uint numMeshPointers = reader.ReadUInt32(); + _level.MeshPointers = reader.ReadUInt32s(numMeshPointers).ToList(); - for (int i = 0; i < _level.NumMeshPointers; i++) - { - _level.MeshPointers[i] = reader.ReadUInt32(); - } - - //Mesh Construction - //level.Meshes = ConstructMeshData(level.NumMeshData, level.NumMeshPointers, level.RawMeshData); - _level.Meshes = ConstructMeshData(_level.MeshPointers, _level.RawMeshData); + _level.Meshes = ConstructMeshData(_level.MeshPointers, rawMeshData); //Animations uint numAnimations = reader.ReadUInt32(); @@ -187,31 +172,25 @@ protected override void Read(TRLevelReader reader) _level.StaticMeshes.Add(TR2FileReadUtilities.ReadStaticMesh(reader)); } - //Object Textures - _level.NumObjectTextures = reader.ReadUInt32(); - _level.ObjectTextures = new TRObjectTexture[_level.NumObjectTextures]; - - for (int i = 0; i < _level.NumObjectTextures; i++) + uint numObjectTextures = reader.ReadUInt32(); + _level.ObjectTextures = new(); + for (int i = 0; i < numObjectTextures; i++) { - _level.ObjectTextures[i] = TR2FileReadUtilities.ReadObjectTexture(reader); + _level.ObjectTextures.Add(TR2FileReadUtilities.ReadObjectTexture(reader)); } - //Sprite Textures - _level.NumSpriteTextures = reader.ReadUInt32(); - _level.SpriteTextures = new TRSpriteTexture[_level.NumSpriteTextures]; - - for (int i = 0; i < _level.NumSpriteTextures; i++) + uint numSpriteTextures = reader.ReadUInt32(); + _level.SpriteTextures = new(); + for (int i = 0; i < numSpriteTextures; i++) { - _level.SpriteTextures[i] = TR2FileReadUtilities.ReadSpriteTexture(reader); + _level.SpriteTextures.Add(TR2FileReadUtilities.ReadSpriteTexture(reader)); } - //Sprite Sequences - _level.NumSpriteSequences = reader.ReadUInt32(); - _level.SpriteSequences = new TRSpriteSequence[_level.NumSpriteSequences]; - - for (int i = 0; i < _level.NumSpriteSequences; i++) + uint numSpriteSequences = reader.ReadUInt32(); + _level.SpriteSequences = new(); + for (int i = 0; i < numSpriteSequences; i++) { - _level.SpriteSequences[i] = TR2FileReadUtilities.ReadSpriteSequence(reader); + _level.SpriteSequences.Add(TR2FileReadUtilities.ReadSpriteSequence(reader)); } //Cameras @@ -244,13 +223,12 @@ protected override void Read(TRLevelReader reader) ushort[] zoneData = reader.ReadUInt16s(numBoxes * 6); _level.Zones = TR1BoxUtilities.ReadZones(numBoxes, zoneData); - //Animated Textures - the data stores the total number of ushorts to read (NumAnimatedTextures) - //followed by a ushort to describe the number of actual texture group objects. - _level.NumAnimatedTextures = reader.ReadUInt32(); - _level.AnimatedTextures = new TRAnimatedTexture[reader.ReadUInt16()]; - for (int i = 0; i < _level.AnimatedTextures.Length; i++) + reader.ReadUInt32(); // Total count of ushorts + ushort numGroups = reader.ReadUInt16(); + _level.AnimatedTextures = new(); + for (int i = 0; i < numGroups; i++) { - _level.AnimatedTextures[i] = TR2FileReadUtilities.ReadAnimatedTexture(reader); + _level.AnimatedTextures.Add(TR2FileReadUtilities.ReadAnimatedTexture(reader)); } //Entities @@ -268,14 +246,8 @@ protected override void Read(TRLevelReader reader) _level.CinematicFrames.Add(TR2FileReadUtilities.ReadCinematicFrame(reader)); } - //Demo Data - _level.NumDemoData = reader.ReadUInt16(); - _level.DemoData = new byte[_level.NumDemoData]; - - for (int i = 0; i < _level.NumDemoData; i++) - { - _level.DemoData[i] = reader.ReadByte(); - } + ushort numDemoData = reader.ReadUInt16(); + _level.DemoData = reader.ReadBytes(numDemoData); //Sound Map & Sound Details _level.SoundMap = new short[256]; @@ -285,30 +257,22 @@ protected override void Read(TRLevelReader reader) _level.SoundMap[i] = reader.ReadInt16(); } - _level.NumSoundDetails = reader.ReadUInt32(); - _level.SoundDetails = new TRSoundDetails[_level.NumSoundDetails]; - - for (int i = 0; i < _level.NumSoundDetails; i++) + uint numSoundDetails = reader.ReadUInt32(); + _level.SoundDetails = new(); + for (int i = 0; i < numSoundDetails; i++) { - _level.SoundDetails[i] = TR2FileReadUtilities.ReadSoundDetails(reader); + _level.SoundDetails.Add(TR2FileReadUtilities.ReadSoundDetails(reader)); } - //Samples - _level.NumSamples = reader.ReadUInt32(); - _level.Samples = new byte[_level.NumSamples]; - - for (int i = 0; i < _level.NumSamples; i++) + uint numSamples = reader.ReadUInt32(); + _level.Samples = new(); + for (int i = 0; i < numSamples; i++) { - _level.Samples[i] = reader.ReadByte(); + _level.Samples.Add(reader.ReadByte()); } - _level.NumSampleIndices = reader.ReadUInt32(); - _level.SampleIndices = new uint[_level.NumSampleIndices]; - - for (int i = 0; i < _level.NumSampleIndices; i++) - { - _level.SampleIndices[i] = reader.ReadUInt32(); - } + uint numSampleIndices = reader.ReadUInt32(); + _level.SampleIndices = reader.ReadUInt32s(numSampleIndices).ToList(); } protected override void Write(TRLevelWriter writer) @@ -324,10 +288,11 @@ protected override void Write(TRLevelWriter writer) writer.Write((uint)_level.FloorData.Count); writer.Write(_level.FloorData); - writer.Write(_level.NumMeshData); - foreach (TRMesh mesh in _level.Meshes) { writer.Write(mesh.Serialize()); } - writer.Write(_level.NumMeshPointers); - foreach (uint ptr in _level.MeshPointers) { writer.Write(ptr); } + List meshData = _level.Meshes.SelectMany(m => m.Serialize()).ToList(); + writer.Write((uint)meshData.Count / 2); + writer.Write(meshData.ToArray()); + writer.Write((uint)_level.MeshPointers.Count); + writer.Write(_level.MeshPointers); writer.Write((uint)_level.Animations.Count); foreach (TRAnimation anim in _level.Animations) { writer.Write(anim.Serialize()); } @@ -347,11 +312,11 @@ protected override void Write(TRLevelWriter writer) writer.Write((uint)_level.StaticMeshes.Count); foreach (TRStaticMesh mesh in _level.StaticMeshes) { writer.Write(mesh.Serialize()); } - writer.Write(_level.NumObjectTextures); + writer.Write((uint)_level.ObjectTextures.Count); foreach (TRObjectTexture tex in _level.ObjectTextures) { writer.Write(tex.Serialize()); } - writer.Write(_level.NumSpriteTextures); + writer.Write((uint)_level.SpriteTextures.Count); foreach (TRSpriteTexture tex in _level.SpriteTextures) { writer.Write(tex.Serialize()); } - writer.Write(_level.NumSpriteSequences); + writer.Write((uint)_level.SpriteSequences.Count); foreach (TRSpriteSequence sequence in _level.SpriteSequences) { writer.Write(sequence.Serialize()); } writer.Write((uint)_level.Cameras.Count); @@ -366,9 +331,10 @@ protected override void Write(TRLevelWriter writer) writer.Write(_level.Overlaps); writer.Write(TR1BoxUtilities.FlattenZones(_level.Zones)); - writer.Write(_level.NumAnimatedTextures); - writer.Write((ushort)_level.AnimatedTextures.Length); - foreach (TRAnimatedTexture texture in _level.AnimatedTextures) { writer.Write(texture.Serialize()); } + byte[] animTextureData = _level.AnimatedTextures.SelectMany(a => a.Serialize()).ToArray(); + writer.Write((uint)(animTextureData.Length / sizeof(ushort)) + 1); + writer.Write((ushort)_level.AnimatedTextures.Count); + writer.Write(animTextureData); writer.Write((uint)_level.Entities.Count); writer.Write(_level.Entities); @@ -381,16 +347,16 @@ protected override void Write(TRLevelWriter writer) writer.Write((ushort)_level.CinematicFrames.Count); foreach (TRCinematicFrame cineframe in _level.CinematicFrames) { writer.Write(cineframe.Serialize()); } - writer.Write(_level.NumDemoData); + writer.Write((ushort)_level.DemoData.Length); writer.Write(_level.DemoData); foreach (short sound in _level.SoundMap) { writer.Write(sound); } - writer.Write(_level.NumSoundDetails); + writer.Write((uint)_level.SoundDetails.Count); foreach (TRSoundDetails snddetail in _level.SoundDetails) { writer.Write(snddetail.Serialize()); } - writer.Write(_level.NumSamples); - foreach (byte sample in _level.Samples) { writer.Write(sample); } - writer.Write(_level.NumSampleIndices); - foreach (uint index in _level.SampleIndices) { writer.Write(index); } + writer.Write((uint)_level.Samples.Count); + writer.Write(_level.Samples.ToArray()); + writer.Write((uint)_level.SampleIndices.Count); + writer.Write(_level.SampleIndices); } private static TRRoomData ConvertToRoomData(TRRoom room) @@ -500,21 +466,21 @@ private static TRRoomData ConvertToRoomData(TRRoom room) return RoomData; } - private static TRMesh[] ConstructMeshData(uint[] meshPointers, ushort[] rawMeshData) + private static List ConstructMeshData(List meshPointers, ushort[] rawMeshData) { byte[] target = new byte[rawMeshData.Length * 2]; Buffer.BlockCopy(rawMeshData, 0, target, 0, target.Length); // The mesh pointer list can contain duplicates so we must make // sure to iterate over distinct values only - meshPointers = meshPointers.Distinct().ToArray(); + meshPointers = new(meshPointers.Distinct()); List meshes = new(); using (MemoryStream ms = new(target)) using (BinaryReader br = new(ms)) { - for (int i = 0; i < meshPointers.Length; i++) + for (int i = 0; i < meshPointers.Count; i++) { TRMesh mesh = new(); meshes.Add(mesh); @@ -599,6 +565,6 @@ private static TRMesh[] ConstructMeshData(uint[] meshPointers, ushort[] rawMeshD } } - return meshes.ToArray(); + return meshes; } } diff --git a/TRLevelControl/Control/TR2LevelControl.cs b/TRLevelControl/Control/TR2LevelControl.cs index 8914a241b..05e656657 100644 --- a/TRLevelControl/Control/TR2LevelControl.cs +++ b/TRLevelControl/Control/TR2LevelControl.cs @@ -107,29 +107,13 @@ protected override void Read(TRLevelReader reader) uint numFloorData = reader.ReadUInt32(); _level.FloorData = reader.ReadUInt16s(numFloorData).ToList(); - //Mesh Data - //This tells us how much mesh data (# of words/uint16s) coming up - //just like the rooms previously. - _level.NumMeshData = reader.ReadUInt32(); - _level.RawMeshData = new ushort[_level.NumMeshData]; + uint numMeshData = reader.ReadUInt32(); + ushort[] rawMeshData = reader.ReadUInt16s(numMeshData); - for (int i = 0; i < _level.NumMeshData; i++) - { - _level.RawMeshData[i] = reader.ReadUInt16(); - } - - //Mesh Pointers - _level.NumMeshPointers = reader.ReadUInt32(); - _level.MeshPointers = new uint[_level.NumMeshPointers]; + uint numMeshPointers = reader.ReadUInt32(); + _level.MeshPointers = reader.ReadUInt32s(numMeshPointers).ToList(); - for (int i = 0; i < _level.NumMeshPointers; i++) - { - _level.MeshPointers[i] = reader.ReadUInt32(); - } - - //Mesh Construction - //level.Meshes = ConstructMeshData(level.NumMeshData, level.NumMeshPointers, level.RawMeshData); - _level.Meshes = ConstructMeshData(_level.MeshPointers, _level.RawMeshData); + _level.Meshes = ConstructMeshData(_level.MeshPointers, rawMeshData); //Animations uint numAnimations = reader.ReadUInt32(); @@ -194,31 +178,25 @@ protected override void Read(TRLevelReader reader) _level.StaticMeshes.Add(TR2FileReadUtilities.ReadStaticMesh(reader)); } - //Object Textures - _level.NumObjectTextures = reader.ReadUInt32(); - _level.ObjectTextures = new TRObjectTexture[_level.NumObjectTextures]; - - for (int i = 0; i < _level.NumObjectTextures; i++) + uint numObjectTextures = reader.ReadUInt32(); + _level.ObjectTextures = new(); + for (int i = 0; i < numObjectTextures; i++) { - _level.ObjectTextures[i] = TR2FileReadUtilities.ReadObjectTexture(reader); + _level.ObjectTextures.Add(TR2FileReadUtilities.ReadObjectTexture(reader)); } - //Sprite Textures - _level.NumSpriteTextures = reader.ReadUInt32(); - _level.SpriteTextures = new TRSpriteTexture[_level.NumSpriteTextures]; - - for (int i = 0; i < _level.NumSpriteTextures; i++) + uint numSpriteTextures = reader.ReadUInt32(); + _level.SpriteTextures = new(); + for (int i = 0; i < numSpriteTextures; i++) { - _level.SpriteTextures[i] = TR2FileReadUtilities.ReadSpriteTexture(reader); + _level.SpriteTextures.Add(TR2FileReadUtilities.ReadSpriteTexture(reader)); } - //Sprite Sequences - _level.NumSpriteSequences = reader.ReadUInt32(); - _level.SpriteSequences = new TRSpriteSequence[_level.NumSpriteSequences]; - - for (int i = 0; i < _level.NumSpriteSequences; i++) + uint numSpriteSequences = reader.ReadUInt32(); + _level.SpriteSequences = new(); + for (int i = 0; i < numSpriteSequences; i++) { - _level.SpriteSequences[i] = TR2FileReadUtilities.ReadSpriteSequence(reader); + _level.SpriteSequences.Add(TR2FileReadUtilities.ReadSpriteSequence(reader)); } uint numCameras = reader.ReadUInt32(); @@ -250,13 +228,12 @@ protected override void Read(TRLevelReader reader) ushort[] zoneData = reader.ReadUInt16s(numBoxes * 10); _level.Zones = TR2BoxUtilities.ReadZones(numBoxes, zoneData); - //Animated Textures - the data stores the total number of ushorts to read (NumAnimatedTextures) - //followed by a ushort to describe the number of actual texture group objects. - _level.NumAnimatedTextures = reader.ReadUInt32(); - _level.AnimatedTextures = new TRAnimatedTexture[reader.ReadUInt16()]; - for (int i = 0; i < _level.AnimatedTextures.Length; i++) + reader.ReadUInt32(); // Total count of ushorts + ushort numGroups = reader.ReadUInt16(); + _level.AnimatedTextures = new(); + for (int i = 0; i < numGroups; i++) { - _level.AnimatedTextures[i] = TR2FileReadUtilities.ReadAnimatedTexture(reader); + _level.AnimatedTextures.Add(TR2FileReadUtilities.ReadAnimatedTexture(reader)); } //Entities @@ -273,14 +250,8 @@ protected override void Read(TRLevelReader reader) _level.CinematicFrames.Add(TR2FileReadUtilities.ReadCinematicFrame(reader)); } - //Demo Data - _level.NumDemoData = reader.ReadUInt16(); - _level.DemoData = new byte[_level.NumDemoData]; - - for (int i = 0; i < _level.NumDemoData; i++) - { - _level.DemoData[i] = reader.ReadByte(); - } + ushort numDemoData = reader.ReadUInt16(); + _level.DemoData = reader.ReadBytes(numDemoData); //Sound Map (370 shorts = 740 bytes) & Sound Details _level.SoundMap = new short[370]; @@ -290,22 +261,15 @@ protected override void Read(TRLevelReader reader) _level.SoundMap[i] = reader.ReadInt16(); } - _level.NumSoundDetails = reader.ReadUInt32(); - _level.SoundDetails = new TRSoundDetails[_level.NumSoundDetails]; - - for (int i = 0; i < _level.NumSoundDetails; i++) + uint numSoundDetails = reader.ReadUInt32(); + _level.SoundDetails = new(); + for (int i = 0; i < numSoundDetails; i++) { - _level.SoundDetails[i] = TR2FileReadUtilities.ReadSoundDetails(reader); + _level.SoundDetails.Add(TR2FileReadUtilities.ReadSoundDetails(reader)); } - //Samples - _level.NumSampleIndices = reader.ReadUInt32(); - _level.SampleIndices = new uint[_level.NumSampleIndices]; - - for (int i = 0; i < _level.NumSampleIndices; i++) - { - _level.SampleIndices[i] = reader.ReadUInt32(); - } + uint numSampleIndices = reader.ReadUInt32(); + _level.SampleIndices = reader.ReadUInt32s(numSampleIndices).ToList(); } protected override void Write(TRLevelWriter writer) @@ -328,10 +292,11 @@ protected override void Write(TRLevelWriter writer) writer.Write((uint)_level.FloorData.Count); writer.Write(_level.FloorData); - writer.Write(_level.NumMeshData); - foreach (TRMesh mesh in _level.Meshes) { writer.Write(mesh.Serialize()); } - writer.Write(_level.NumMeshPointers); - foreach (uint ptr in _level.MeshPointers) { writer.Write(ptr); } + List meshData = _level.Meshes.SelectMany(m => m.Serialize()).ToList(); + writer.Write((uint)meshData.Count / 2); + writer.Write(meshData.ToArray()); + writer.Write((uint)_level.MeshPointers.Count); + writer.Write(_level.MeshPointers); writer.Write((uint)_level.Animations.Count); foreach (TRAnimation anim in _level.Animations) { writer.Write(anim.Serialize()); } @@ -351,11 +316,11 @@ protected override void Write(TRLevelWriter writer) writer.Write((uint)_level.StaticMeshes.Count); foreach (TRStaticMesh mesh in _level.StaticMeshes) { writer.Write(mesh.Serialize()); } - writer.Write(_level.NumObjectTextures); + writer.Write((uint)_level.ObjectTextures.Count); foreach (TRObjectTexture tex in _level.ObjectTextures) { writer.Write(tex.Serialize()); } - writer.Write(_level.NumSpriteTextures); + writer.Write((uint)_level.SpriteTextures.Count); foreach (TRSpriteTexture tex in _level.SpriteTextures) { writer.Write(tex.Serialize()); } - writer.Write(_level.NumSpriteSequences); + writer.Write((uint)_level.SpriteSequences.Count); foreach (TRSpriteSequence sequence in _level.SpriteSequences) { writer.Write(sequence.Serialize()); } writer.Write((uint)_level.Cameras.Count); @@ -370,10 +335,11 @@ protected override void Write(TRLevelWriter writer) writer.Write(_level.Overlaps); writer.Write(TR2BoxUtilities.FlattenZones(_level.Zones)); - writer.Write(_level.NumAnimatedTextures); - writer.Write((ushort)_level.AnimatedTextures.Length); - foreach (TRAnimatedTexture texture in _level.AnimatedTextures) { writer.Write(texture.Serialize()); } - + byte[] animTextureData = _level.AnimatedTextures.SelectMany(a => a.Serialize()).ToArray(); + writer.Write((uint)(animTextureData.Length / sizeof(ushort)) + 1); + writer.Write((ushort)_level.AnimatedTextures.Count); + writer.Write(animTextureData); + writer.Write((uint)_level.Entities.Count); writer.Write(_level.Entities); @@ -383,14 +349,14 @@ protected override void Write(TRLevelWriter writer) writer.Write((ushort)_level.CinematicFrames.Count); foreach (TRCinematicFrame cineframe in _level.CinematicFrames) { writer.Write(cineframe.Serialize()); } - writer.Write(_level.NumDemoData); + writer.Write((ushort)_level.DemoData.Length); writer.Write(_level.DemoData); foreach (short sound in _level.SoundMap) { writer.Write(sound); } - writer.Write(_level.NumSoundDetails); + writer.Write((uint)_level.SoundDetails.Count); foreach (TRSoundDetails snddetail in _level.SoundDetails) { writer.Write(snddetail.Serialize()); } - writer.Write(_level.NumSampleIndices); - foreach (uint index in _level.SampleIndices) { writer.Write(index); } + writer.Write((uint)_level.SampleIndices.Count); + writer.Write(_level.SampleIndices); } private static TR2RoomData ConvertToRoomData(TR2Room room) @@ -504,21 +470,21 @@ private static TR2RoomData ConvertToRoomData(TR2Room room) return RoomData; } - private static TRMesh[] ConstructMeshData(uint[] meshPointers, ushort[] rawMeshData) + private static List ConstructMeshData(List meshPointers, ushort[] rawMeshData) { byte[] target = new byte[rawMeshData.Length * 2]; Buffer.BlockCopy(rawMeshData, 0, target, 0, target.Length); // The mesh pointer list can contain duplicates so we must make // sure to iterate over distinct values only - meshPointers = meshPointers.Distinct().ToArray(); + meshPointers = new(meshPointers.Distinct()); List meshes = new(); using (MemoryStream ms = new(target)) using (BinaryReader br = new(ms)) { - for (int i = 0; i < meshPointers.Length; i++) + for (int i = 0; i < meshPointers.Count; i++) { TRMesh mesh = new(); meshes.Add(mesh); @@ -603,6 +569,6 @@ private static TRMesh[] ConstructMeshData(uint[] meshPointers, ushort[] rawMeshD } } - return meshes.ToArray(); + return meshes; } } diff --git a/TRLevelControl/Control/TR3LevelControl.cs b/TRLevelControl/Control/TR3LevelControl.cs index 2c4d363cd..d041c1f6a 100644 --- a/TRLevelControl/Control/TR3LevelControl.cs +++ b/TRLevelControl/Control/TR3LevelControl.cs @@ -111,29 +111,13 @@ protected override void Read(TRLevelReader reader) uint numFloorData = reader.ReadUInt32(); _level.FloorData = reader.ReadUInt16s(numFloorData).ToList(); - //Mesh Data - //This tells us how much mesh data (# of words/uint16s) coming up - //just like the rooms previously. - _level.NumMeshData = reader.ReadUInt32(); - _level.RawMeshData = new ushort[_level.NumMeshData]; + uint numMeshData = reader.ReadUInt32(); + ushort[] rawMeshData = reader.ReadUInt16s(numMeshData); - for (int i = 0; i < _level.NumMeshData; i++) - { - _level.RawMeshData[i] = reader.ReadUInt16(); - } - - //Mesh Pointers - _level.NumMeshPointers = reader.ReadUInt32(); - _level.MeshPointers = new uint[_level.NumMeshPointers]; - - for (int i = 0; i < _level.NumMeshPointers; i++) - { - _level.MeshPointers[i] = reader.ReadUInt32(); - } + uint numMeshPointers = reader.ReadUInt32(); + _level.MeshPointers = reader.ReadUInt32s(numMeshPointers).ToList(); - //Mesh Construction - //level.Meshes = ConstructMeshData(level.NumMeshData, level.NumMeshPointers, level.RawMeshData); - _level.Meshes = ConstructMeshData(_level.MeshPointers, _level.RawMeshData); + _level.Meshes = ConstructMeshData(_level.MeshPointers, rawMeshData); //Animations uint numAnimations = reader.ReadUInt32(); @@ -199,24 +183,18 @@ protected override void Read(TRLevelReader reader) _level.StaticMeshes.Add(TR2FileReadUtilities.ReadStaticMesh(reader)); } - //Object Textures - in TR3 this is now after animated textures - - //Sprite Textures - _level.NumSpriteTextures = reader.ReadUInt32(); - _level.SpriteTextures = new TRSpriteTexture[_level.NumSpriteTextures]; - - for (int i = 0; i < _level.NumSpriteTextures; i++) + uint numSpriteTextures = reader.ReadUInt32(); + _level.SpriteTextures = new(); + for (int i = 0; i < numSpriteTextures; i++) { - _level.SpriteTextures[i] = TR2FileReadUtilities.ReadSpriteTexture(reader); + _level.SpriteTextures.Add(TR2FileReadUtilities.ReadSpriteTexture(reader)); } - //Sprite Sequences - _level.NumSpriteSequences = reader.ReadUInt32(); - _level.SpriteSequences = new TRSpriteSequence[_level.NumSpriteSequences]; - - for (int i = 0; i < _level.NumSpriteSequences; i++) + uint numSpriteSequences = reader.ReadUInt32(); + _level.SpriteSequences = new(); + for (int i = 0; i < numSpriteSequences; i++) { - _level.SpriteSequences[i] = TR2FileReadUtilities.ReadSpriteSequence(reader); + _level.SpriteSequences.Add(TR2FileReadUtilities.ReadSpriteSequence(reader)); } uint numCameras = reader.ReadUInt32(); @@ -248,22 +226,20 @@ protected override void Read(TRLevelReader reader) ushort[] zoneData = reader.ReadUInt16s(numBoxes * 10); _level.Zones = TR2BoxUtilities.ReadZones(numBoxes, zoneData); - //Animated Textures - the data stores the total number of ushorts to read (NumAnimatedTextures) - //followed by a ushort to describe the number of actual texture group objects. - _level.NumAnimatedTextures = reader.ReadUInt32(); - _level.AnimatedTextures = new TRAnimatedTexture[reader.ReadUInt16()]; - for (int i = 0; i < _level.AnimatedTextures.Length; i++) + reader.ReadUInt32(); // Total count of ushorts + ushort numGroups = reader.ReadUInt16(); + _level.AnimatedTextures = new(); + for (int i = 0; i < numGroups; i++) { - _level.AnimatedTextures[i] = TR2FileReadUtilities.ReadAnimatedTexture(reader); + _level.AnimatedTextures.Add(TR2FileReadUtilities.ReadAnimatedTexture(reader)); } //Object Textures - in TR3 this is now after animated textures - _level.NumObjectTextures = reader.ReadUInt32(); - _level.ObjectTextures = new TRObjectTexture[_level.NumObjectTextures]; - - for (int i = 0; i < _level.NumObjectTextures; i++) + uint numObjectTextures = reader.ReadUInt32(); + _level.ObjectTextures = new(); + for (int i = 0; i < numObjectTextures; i++) { - _level.ObjectTextures[i] = TR2FileReadUtilities.ReadObjectTexture(reader); + _level.ObjectTextures.Add(TR2FileReadUtilities.ReadObjectTexture(reader)); } //Entities @@ -280,14 +256,8 @@ protected override void Read(TRLevelReader reader) _level.CinematicFrames.Add(TR2FileReadUtilities.ReadCinematicFrame(reader)); } - //Demo Data - _level.NumDemoData = reader.ReadUInt16(); - _level.DemoData = new byte[_level.NumDemoData]; - - for (int i = 0; i < _level.NumDemoData; i++) - { - _level.DemoData[i] = reader.ReadByte(); - } + ushort numDemoData = reader.ReadUInt16(); + _level.DemoData = reader.ReadBytes(numDemoData); //Sound Map (370 shorts = 740 bytes) & Sound Details _level.SoundMap = new short[370]; @@ -297,22 +267,15 @@ protected override void Read(TRLevelReader reader) _level.SoundMap[i] = reader.ReadInt16(); } - _level.NumSoundDetails = reader.ReadUInt32(); - _level.SoundDetails = new TR3SoundDetails[_level.NumSoundDetails]; - - for (int i = 0; i < _level.NumSoundDetails; i++) + uint numSoundDetails = reader.ReadUInt32(); + _level.SoundDetails = new(); + for (int i = 0; i < numSoundDetails; i++) { - _level.SoundDetails[i] = TR3FileReadUtilities.ReadSoundDetails(reader); + _level.SoundDetails.Add(TR3FileReadUtilities.ReadSoundDetails(reader)); } - //Samples - _level.NumSampleIndices = reader.ReadUInt32(); - _level.SampleIndices = new uint[_level.NumSampleIndices]; - - for (int i = 0; i < _level.NumSampleIndices; i++) - { - _level.SampleIndices[i] = reader.ReadUInt32(); - } + uint numSampleIndices = reader.ReadUInt32(); + _level.SampleIndices = reader.ReadUInt32s(numSampleIndices).ToList(); } protected override void Write(TRLevelWriter writer) @@ -335,10 +298,11 @@ protected override void Write(TRLevelWriter writer) writer.Write((uint)_level.FloorData.Count); writer.Write(_level.FloorData); - writer.Write(_level.NumMeshData); - foreach (TRMesh mesh in _level.Meshes) { writer.Write(mesh.Serialize()); } - writer.Write(_level.NumMeshPointers); - foreach (uint ptr in _level.MeshPointers) { writer.Write(ptr); } + List meshData = _level.Meshes.SelectMany(m => m.Serialize()).ToList(); + writer.Write((uint)meshData.Count / 2); + writer.Write(meshData.ToArray()); + writer.Write((uint)_level.MeshPointers.Count); + writer.Write(_level.MeshPointers); writer.Write((uint)_level.Animations.Count); foreach (TRAnimation anim in _level.Animations) { writer.Write(anim.Serialize()); } @@ -358,9 +322,9 @@ protected override void Write(TRLevelWriter writer) writer.Write((uint)_level.StaticMeshes.Count); foreach (TRStaticMesh mesh in _level.StaticMeshes) { writer.Write(mesh.Serialize()); } - writer.Write(_level.NumSpriteTextures); + writer.Write((uint)_level.SpriteTextures.Count); foreach (TRSpriteTexture tex in _level.SpriteTextures) { writer.Write(tex.Serialize()); } - writer.Write(_level.NumSpriteSequences); + writer.Write((uint)_level.SpriteSequences.Count); foreach (TRSpriteSequence sequence in _level.SpriteSequences) { writer.Write(sequence.Serialize()); } writer.Write((uint)_level.Cameras.Count); @@ -375,10 +339,12 @@ protected override void Write(TRLevelWriter writer) writer.Write(_level.Overlaps); writer.Write(TR2BoxUtilities.FlattenZones(_level.Zones)); - writer.Write(_level.NumAnimatedTextures); - writer.Write((ushort)_level.AnimatedTextures.Length); - foreach (TRAnimatedTexture texture in _level.AnimatedTextures) { writer.Write(texture.Serialize()); } - writer.Write(_level.NumObjectTextures); + byte[] animTextureData = _level.AnimatedTextures.SelectMany(a => a.Serialize()).ToArray(); + writer.Write((uint)(animTextureData.Length / sizeof(ushort)) + 1); + writer.Write((ushort)_level.AnimatedTextures.Count); + writer.Write(animTextureData); + + writer.Write((uint)_level.ObjectTextures.Count); foreach (TRObjectTexture tex in _level.ObjectTextures) { writer.Write(tex.Serialize()); } writer.Write((uint)_level.Entities.Count); @@ -390,14 +356,14 @@ protected override void Write(TRLevelWriter writer) writer.Write((ushort)_level.CinematicFrames.Count); foreach (TRCinematicFrame cineframe in _level.CinematicFrames) { writer.Write(cineframe.Serialize()); } - writer.Write(_level.NumDemoData); + writer.Write((ushort)_level.DemoData.Length); writer.Write(_level.DemoData); foreach (short sound in _level.SoundMap) { writer.Write(sound); } - writer.Write(_level.NumSoundDetails); + writer.Write((uint)_level.SoundDetails.Count); foreach (TR3SoundDetails snddetail in _level.SoundDetails) { writer.Write(snddetail.Serialize()); } - writer.Write(_level.NumSampleIndices); - foreach (uint index in _level.SampleIndices) { writer.Write(index); } + writer.Write((uint)_level.SampleIndices.Count); + writer.Write(_level.SampleIndices); } private static TR3RoomData ConvertToRoomData(TR3Room room) @@ -511,21 +477,21 @@ private static TR3RoomData ConvertToRoomData(TR3Room room) return RoomData; } - private static TRMesh[] ConstructMeshData(uint[] meshPointers, ushort[] rawMeshData) + private static List ConstructMeshData(List meshPointers, ushort[] rawMeshData) { byte[] target = new byte[rawMeshData.Length * 2]; Buffer.BlockCopy(rawMeshData, 0, target, 0, target.Length); // The mesh pointer list can contain duplicates so we must make // sure to iterate over distinct values only - meshPointers = meshPointers.Distinct().ToArray(); + meshPointers = new(meshPointers.Distinct()); List meshes = new(); using (MemoryStream ms = new(target)) using (BinaryReader br = new(ms)) { - for (int i = 0; i < meshPointers.Length; i++) + for (int i = 0; i < meshPointers.Count; i++) { TRMesh mesh = new(); meshes.Add(mesh); @@ -610,6 +576,6 @@ private static TRMesh[] ConstructMeshData(uint[] meshPointers, ushort[] rawMeshD } } - return meshes.ToArray(); + return meshes; } } diff --git a/TRLevelControl/Control/TR4LevelControl.cs b/TRLevelControl/Control/TR4LevelControl.cs index 78eb53309..266cf8928 100644 --- a/TRLevelControl/Control/TR4LevelControl.cs +++ b/TRLevelControl/Control/TR4LevelControl.cs @@ -56,19 +56,16 @@ protected override void Read(TRLevelReader reader) //Decompress DecompressLevelDataChunk(_level); - //Samples - _level.NumSamples = reader.ReadUInt32(); - _level.Samples = new TR4Sample[_level.NumSamples]; + uint numSamples = reader.ReadUInt32(); + _level.Samples = new(); - for(int i = 0; i < _level.NumSamples; i++) + for (int i = 0; i < numSamples; i++) { - TR4Sample sample = new() + _level.Samples.Add(new() { UncompSize = reader.ReadUInt32(), CompSize = reader.ReadUInt32(), - }; - - _level.Samples[i] = sample; + }); //Compressed chunk is actually NOT zlib compressed - it is simply a WAV file. _level.Samples[i].CompressedChunk = reader.ReadBytes((int)_level.Samples[i].CompSize); @@ -109,8 +106,7 @@ protected override void Write(TRLevelWriter writer) writer.Write(_level.LevelDataChunk.CompressedSize); writer.Write(chunk); - writer.Write(_level.NumSamples); - + writer.Write((uint)_level.Samples.Count); foreach (TR4Sample sample in _level.Samples) { writer.Write(sample.UncompSize); @@ -134,13 +130,13 @@ private static void DecompressLevelDataChunk(TR4Level lvl) TR4FileReadUtilities.PopulateAnimations(lvlChunkReader, lvl); TR4FileReadUtilities.PopulateMeshTreesFramesModels(lvlChunkReader, lvl); TR4FileReadUtilities.PopulateStaticMeshes(lvlChunkReader, lvl); - TR4FileReadUtilities.VerifySPRMarker(lvlChunkReader, lvl); + TR4FileReadUtilities.VerifySPRMarker(lvlChunkReader); TR4FileReadUtilities.PopulateSprites(lvlChunkReader, lvl); TR4FileReadUtilities.PopulateCameras(lvlChunkReader, lvl); TR4FileReadUtilities.PopulateSoundSources(lvlChunkReader, lvl); TR4FileReadUtilities.PopulateBoxesOverlapsZones(lvlChunkReader, lvl); TR4FileReadUtilities.PopulateAnimatedTextures(lvlChunkReader, lvl); - TR4FileReadUtilities.VerifyTEXMarker(lvlChunkReader, lvl); + TR4FileReadUtilities.VerifyTEXMarker(lvlChunkReader); TR4FileReadUtilities.PopulateObjectTextures(lvlChunkReader, lvl); TR4FileReadUtilities.PopulateEntitiesAndAI(lvlChunkReader, lvl); TR4FileReadUtilities.PopulateDemoSoundSampleIndices(lvlChunkReader, lvl); diff --git a/TRLevelControl/Control/TR5LevelControl.cs b/TRLevelControl/Control/TR5LevelControl.cs index f7178594d..a1f393daa 100644 --- a/TRLevelControl/Control/TR5LevelControl.cs +++ b/TRLevelControl/Control/TR5LevelControl.cs @@ -58,19 +58,16 @@ protected override void Read(TRLevelReader reader) //Decompress DecompressLevelDataChunk(_level); - //Samples - _level.NumSamples = reader.ReadUInt32(); - _level.Samples = new TR4Sample[_level.NumSamples]; + uint numSamples = reader.ReadUInt32(); + _level.Samples = new(); - for (int i = 0; i < _level.NumSamples; i++) + for (int i = 0; i < numSamples; i++) { - TR4Sample sample = new() + _level.Samples.Add(new() { UncompSize = reader.ReadUInt32(), CompSize = reader.ReadUInt32(), - }; - - _level.Samples[i] = sample; + }); //Compressed chunk is actually NOT zlib compressed - it is simply a WAV file. _level.Samples[i].CompressedChunk = reader.ReadBytes((int)_level.Samples[i].CompSize); @@ -112,8 +109,7 @@ protected override void Write(TRLevelWriter writer) writer.Write(_level.LevelDataChunk.CompressedSize); writer.Write(chunk); - writer.Write(_level.NumSamples); - + writer.Write((uint)_level.Samples.Count); foreach (TR4Sample sample in _level.Samples) { writer.Write(sample.UncompSize); @@ -138,13 +134,13 @@ private static void DecompressLevelDataChunk(TR5Level lvl) TR5FileReadUtilities.PopulateAnimations(lvlChunkReader, lvl); TR5FileReadUtilities.PopulateMeshTreesFramesModels(lvlChunkReader, lvl); TR5FileReadUtilities.PopulateStaticMeshes(lvlChunkReader, lvl); - TR5FileReadUtilities.VerifySPRMarker(lvlChunkReader, lvl); + TR5FileReadUtilities.VerifySPRMarker(lvlChunkReader); TR5FileReadUtilities.PopulateSprites(lvlChunkReader, lvl); TR5FileReadUtilities.PopulateCameras(lvlChunkReader, lvl); TR5FileReadUtilities.PopulateSoundSources(lvlChunkReader, lvl); TR5FileReadUtilities.PopulateBoxesOverlapsZones(lvlChunkReader, lvl); TR5FileReadUtilities.PopulateAnimatedTextures(lvlChunkReader, lvl); - TR5FileReadUtilities.VerifyTEXMarker(lvlChunkReader, lvl); + TR5FileReadUtilities.VerifyTEXMarker(lvlChunkReader); TR5FileReadUtilities.PopulateObjectTextures(lvlChunkReader, lvl); TR5FileReadUtilities.PopulateEntitiesAndAI(lvlChunkReader, lvl); TR5FileReadUtilities.PopulateDemoSoundSampleIndices(lvlChunkReader, lvl); diff --git a/TRLevelControl/Helpers/TRMeshUtilities.cs b/TRLevelControl/Helpers/TRMeshUtilities.cs index 3c24a6a9b..e9a240795 100644 --- a/TRLevelControl/Helpers/TRMeshUtilities.cs +++ b/TRLevelControl/Helpers/TRMeshUtilities.cs @@ -49,9 +49,9 @@ public static TRMesh GetModelFirstMesh(TR3Level level, TRModel model) return GetMesh(level, model.StartingMesh); } - public static TRMesh[] GetModelMeshes(TR1Level level, TR1Type entity) + public static List GetModelMeshes(TR1Level level, TR1Type entity) { - TRModel model = level.Models.ToList().Find(e => e.ID == (uint)entity); + TRModel model = level.Models.Find(e => e.ID == (uint)entity); if (model != null) { return GetModelMeshes(level, model); @@ -59,9 +59,9 @@ public static TRMesh[] GetModelMeshes(TR1Level level, TR1Type entity) return null; } - public static TRMesh[] GetModelMeshes(TR2Level level, TR2Type entity) + public static List GetModelMeshes(TR2Level level, TR2Type entity) { - TRModel model = level.Models.ToList().Find(e => e.ID == (uint)entity); + TRModel model = level.Models.Find(e => e.ID == (uint)entity); if (model != null) { return GetModelMeshes(level, model); @@ -69,9 +69,9 @@ public static TRMesh[] GetModelMeshes(TR2Level level, TR2Type entity) return null; } - public static TRMesh[] GetModelMeshes(TR3Level level, TR3Type entity) + public static List GetModelMeshes(TR3Level level, TR3Type entity) { - TRModel model = level.Models.ToList().Find(e => e.ID == (uint)entity); + TRModel model = level.Models.Find(e => e.ID == (uint)entity); if (model != null) { return GetModelMeshes(level, model); @@ -79,45 +79,45 @@ public static TRMesh[] GetModelMeshes(TR3Level level, TR3Type entity) return null; } - public static TRMesh[] GetModelMeshes(TR1Level level, TRModel model) + public static List GetModelMeshes(TR1Level level, TRModel model) { return GetModelMeshes(level.Meshes, level.MeshPointers, model); } - public static TRMesh[] GetModelMeshes(TR2Level level, TRModel model) + public static List GetModelMeshes(TR2Level level, TRModel model) { return GetModelMeshes(level.Meshes, level.MeshPointers, model); } - public static TRMesh[] GetModelMeshes(TR3Level level, TRModel model) + public static List GetModelMeshes(TR3Level level, TRModel model) { return GetModelMeshes(level.Meshes, level.MeshPointers, model); } - public static TRMesh[] GetModelMeshes(IEnumerable meshes, uint[] meshPointers, TRModel model) + public static List GetModelMeshes(IEnumerable meshes, List meshPointers, TRModel model) { List modelMeshes = new(); - uint meshPointer = model.StartingMesh; - for (uint j = 0; j < model.NumMeshes; j++) + int meshPointer = model.StartingMesh; + for (int j = 0; j < model.NumMeshes; j++) { modelMeshes.Add(GetMesh(meshes, meshPointers[meshPointer + j])); } - return modelMeshes.ToArray(); + return modelMeshes; } public static TRMesh GetMesh(TR1Level level, uint meshPointer) { - return GetMesh(level.Meshes, level.MeshPointers[meshPointer]); + return GetMesh(level.Meshes, level.MeshPointers[(int)meshPointer]); } public static TRMesh GetMesh(TR2Level level, uint meshPointer) { - return GetMesh(level.Meshes, level.MeshPointers[meshPointer]); + return GetMesh(level.Meshes, level.MeshPointers[(int)meshPointer]); } public static TRMesh GetMesh(TR3Level level, uint meshPointer) { - return GetMesh(level.Meshes, level.MeshPointers[meshPointer]); + return GetMesh(level.Meshes, level.MeshPointers[(int)meshPointer]); } public static TRMesh GetMesh(IEnumerable meshes, uint offset) @@ -164,76 +164,20 @@ public static TRMeshTreeNode[] GetModelMeshTrees(List meshTrees, return nodes.ToArray(); } - /// - /// Inserts a new mesh and returns its index in MeshPointers. - /// public static int InsertMesh(TR1Level level, TRMesh newMesh) - { - //get the final mesh we currently have - if(level.Meshes.Length > 0) - { - TRMesh lastMesh = level.Meshes[^1]; - //new mesh pointer will be the current final mesh's pointer plus its length - newMesh.Pointer = lastMesh.Pointer + (uint)lastMesh.Serialize().Length; - } - else - { - newMesh.Pointer = 0; - } - - List meshes = level.Meshes.ToList(); - meshes.Add(newMesh); - level.Meshes = meshes.ToArray(); - - List pointers = level.MeshPointers.ToList(); - pointers.Add(newMesh.Pointer); - level.MeshPointers = pointers.ToArray(); - level.NumMeshPointers++; - - //NumMeshData needs the additional mesh size added - level.NumMeshData += (uint)newMesh.Serialize().Length / 2; - - //the pointer index will be the final index in the array - return level.MeshPointers.Length - 1; - } + => InsertMesh(newMesh, level.Meshes, level.MeshPointers); public static int InsertMesh(TR2Level level, TRMesh newMesh) - { - //get the final mesh we currently have - if (level.Meshes.Length > 0) - { - TRMesh lastMesh = level.Meshes[^1]; - //new mesh pointer will be the current final mesh's pointer plus its length - newMesh.Pointer = lastMesh.Pointer + (uint)lastMesh.Serialize().Length; - } - else - { - newMesh.Pointer = 0; - } - - List meshes = level.Meshes.ToList(); - meshes.Add(newMesh); - level.Meshes = meshes.ToArray(); - - List pointers = level.MeshPointers.ToList(); - pointers.Add(newMesh.Pointer); - level.MeshPointers = pointers.ToArray(); - level.NumMeshPointers++; - - //NumMeshData needs the additional mesh size added - level.NumMeshData += (uint)newMesh.Serialize().Length / 2; - - //the pointer index will be the final index in the array - return level.MeshPointers.Length - 1; - } + => InsertMesh(newMesh, level.Meshes, level.MeshPointers); public static int InsertMesh(TR3Level level, TRMesh newMesh) + => InsertMesh(newMesh, level.Meshes, level.MeshPointers); + + private static int InsertMesh(TRMesh newMesh, List meshes, List meshPointers) { - //get the final mesh we currently have - if (level.Meshes.Length > 0) + if (meshes.Count > 0) { - TRMesh lastMesh = level.Meshes[^1]; - //new mesh pointer will be the current final mesh's pointer plus its length + TRMesh lastMesh = meshes[^1]; newMesh.Pointer = lastMesh.Pointer + (uint)lastMesh.Serialize().Length; } else @@ -241,20 +185,10 @@ public static int InsertMesh(TR3Level level, TRMesh newMesh) newMesh.Pointer = 0; } - List meshes = level.Meshes.ToList(); meshes.Add(newMesh); - level.Meshes = meshes.ToArray(); - - List pointers = level.MeshPointers.ToList(); - pointers.Add(newMesh.Pointer); - level.MeshPointers = pointers.ToArray(); - level.NumMeshPointers++; - - //NumMeshData needs the additional mesh size added - level.NumMeshData += (uint)newMesh.Serialize().Length / 2; + meshPointers.Add(newMesh.Pointer); - //the pointer index will be the final index in the array - return level.MeshPointers.Length - 1; + return meshPointers.Count - 1; } /// @@ -326,10 +260,8 @@ public static void UpdateMeshPointers(TR1Level level, TRMesh modifiedMesh, int p } } - level.MeshPointers = pointers.ToArray(); - - int numMeshData = (int)level.NumMeshData + lengthDiff / 2; - level.NumMeshData = (uint)numMeshData; + level.MeshPointers.Clear(); + level.MeshPointers.AddRange(pointers); // While the Pointer property on meshes is only for convenience and not // written to the level, we need to update them regardless in case of @@ -358,10 +290,8 @@ public static void UpdateMeshPointers(TR2Level level, TRMesh modifiedMesh, int p } } - level.MeshPointers = pointers.ToArray(); - - int numMeshData = (int)level.NumMeshData + lengthDiff / 2; - level.NumMeshData = (uint)numMeshData; + level.MeshPointers.Clear(); + level.MeshPointers.AddRange(pointers); // While the Pointer property on meshes is only for convenience and not // written to the level, we need to update them regardless in case of @@ -390,10 +320,8 @@ public static void UpdateMeshPointers(TR3Level level, TRMesh modifiedMesh, int p } } - level.MeshPointers = pointers.ToArray(); - - int numMeshData = (int)level.NumMeshData + lengthDiff / 2; - level.NumMeshData = (uint)numMeshData; + level.MeshPointers.Clear(); + level.MeshPointers.AddRange(pointers); // While the Pointer property on meshes is only for convenience and not // written to the level, we need to update them regardless in case of diff --git a/TRLevelControl/Model/Base/TR1Level.cs b/TRLevelControl/Model/Base/TR1Level.cs index 32619ab19..b43b24225 100644 --- a/TRLevelControl/Model/Base/TR1Level.cs +++ b/TRLevelControl/Model/Base/TR1Level.cs @@ -5,32 +5,8 @@ public class TR1Level : TRLevelBase public List Images8 { get; set; } public List Rooms { get; set; } public List FloorData { get; set; } - - /// - /// 4 bytes - /// - public uint NumMeshData { get; set; } - - /// - /// 2 * NumMeshData, holds the raw data stored in Meshes - /// - public ushort[] RawMeshData { get; set; } - - /// - /// Variable - /// - public TRMesh[] Meshes { get; set; } - - /// - /// 4 bytes - /// - public uint NumMeshPointers { get; set; } - - /// - /// NumMeshPointers * 4 bytes - /// - public uint[] MeshPointers { get; set; } - + public List Meshes { get; set; } + public List MeshPointers { get; set; } public List Animations { get; set; } public List StateChanges { get; set; } public List AnimDispatches { get; set; } @@ -39,92 +15,22 @@ public class TR1Level : TRLevelBase public List Frames { get; set; } public List Models { get; set; } public List StaticMeshes { get; set; } - - /// - /// 4 bytes - /// - public uint NumObjectTextures { get; set; } - - /// - /// NumObjectTextures * 20 bytes - /// - public TRObjectTexture[] ObjectTextures { get; set; } - - /// - /// 4 bytes - /// - public uint NumSpriteTextures { get; set; } - - /// - /// NumSpriteTextures * 16 bytes - /// - public TRSpriteTexture[] SpriteTextures { get; set; } - - /// - /// 4 bytes - /// - public uint NumSpriteSequences { get; set; } - - /// - /// NumSpriteSequences * 8 bytes - /// - public TRSpriteSequence[] SpriteSequences { get; set; } + public List ObjectTextures { get; set; } + public List SpriteTextures { get; set; } + public List SpriteSequences { get; set; } public List Cameras { get; set; } public List SoundSources { get; set; } public List Boxes { get; set; } public List Overlaps { get; set; } public List Zones { get; set; } - - /// - /// 4 bytes - /// - public uint NumAnimatedTextures { get; set; } - - /// - /// NumAnimatesTextures * 2 bytes - /// - public TRAnimatedTexture[] AnimatedTextures { get; set; } + public List AnimatedTextures { get; set; } public List Entities { get; set; } public List LightMap { get; set; } public List Palette { get; set; } public List CinematicFrames { get; set; } - - /// - /// 2 bytes - /// - public ushort NumDemoData { get; set; } - - /// - /// NumDemoData bytes - /// public byte[] DemoData { get; set; } - - /// - /// 370 entries of 2 bytes each = 740 bytes - /// public short[] SoundMap { get; set; } - - /// - /// 4 bytes - /// - public uint NumSoundDetails { get; set; } - - /// - /// NumSoundDetails * 8 bytes - /// - public TRSoundDetails[] SoundDetails { get; set; } - - public uint NumSamples { get; set; } - - public byte[] Samples { get; set; } - - /// - /// 4 bytes - /// - public uint NumSampleIndices { get; set; } - - /// - /// NumSampleIndices * 4 bytes - /// - public uint[] SampleIndices { get; set; } + public List SoundDetails { get; set; } + public List Samples { get; set; } + public List SampleIndices { get; set; } } diff --git a/TRLevelControl/Model/Base/TRAnimatedTexture.cs b/TRLevelControl/Model/Base/TRAnimatedTexture.cs index 0e6c4c3b2..74374cda7 100644 --- a/TRLevelControl/Model/Base/TRAnimatedTexture.cs +++ b/TRLevelControl/Model/Base/TRAnimatedTexture.cs @@ -4,15 +4,13 @@ namespace TRLevelControl.Model; public class TRAnimatedTexture : ISerializableCompact { - //https://opentomb.github.io/TRosettaStone3/trosettastone.html#_animated_textures_2 - public ushort NumTextures => (ushort)(Textures.Length - 1); - public ushort[] Textures { get; set; } + public List Textures { get; set; } public byte[] Serialize() { using MemoryStream stream = new(); using BinaryWriter writer = new(stream); - writer.Write(NumTextures); + writer.Write((ushort)(Textures.Count - 1)); foreach (ushort texture in Textures) { writer.Write(texture); diff --git a/TRLevelControl/Model/TR2/TR2Level.cs b/TRLevelControl/Model/TR2/TR2Level.cs index 6169c78a4..c3cb8b2c3 100644 --- a/TRLevelControl/Model/TR2/TR2Level.cs +++ b/TRLevelControl/Model/TR2/TR2Level.cs @@ -8,32 +8,8 @@ public class TR2Level : TRLevelBase public List Images16 { get; set; } public List Rooms { get; set; } public List FloorData { get; set; } - - /// - /// 4 bytes - /// - public uint NumMeshData { get; set; } - - /// - /// 2 * NumMeshData, holds the raw data stored in Meshes - /// - public ushort[] RawMeshData { get; set; } - - /// - /// Variable - /// - public TRMesh[] Meshes { get; set; } - - /// - /// 4 bytes - /// - public uint NumMeshPointers { get; set; } - - /// - /// NumMeshPointers * 4 bytes - /// - public uint[] MeshPointers { get; set; } - + public List Meshes { get; set; } + public List MeshPointers { get; set; } public List Animations { get; set; } public List StateChanges { get; set; } public List AnimDispatches { get; set; } @@ -42,87 +18,20 @@ public class TR2Level : TRLevelBase public List Frames { get; set; } public List Models { get; set; } public List StaticMeshes { get; set; } - - /// - /// 4 bytes - /// - public uint NumObjectTextures { get; set; } - - /// - /// NumObjectTextures * 20 bytes - /// - public TRObjectTexture[] ObjectTextures { get; set; } - - /// - /// 4 bytes - /// - public uint NumSpriteTextures { get; set; } - - /// - /// NumSpriteTextures * 16 bytes - /// - public TRSpriteTexture[] SpriteTextures { get; set; } - - /// - /// 4 bytes - /// - public uint NumSpriteSequences { get; set; } - - /// - /// NumSpriteSequences * 8 bytes - /// - public TRSpriteSequence[] SpriteSequences { get; set; } + public List ObjectTextures { get; set; } + public List SpriteTextures { get; set; } + public List SpriteSequences { get; set; } public List Cameras { get; set; } public List SoundSources { get; set; } public List Boxes { get; set; } public List Overlaps { get; set; } public List Zones { get; set; } - - /// - /// 4 bytes - /// - public uint NumAnimatedTextures { get; set; } - - /// - /// NumAnimatesTextures * 2 bytes - /// - public TRAnimatedTexture[] AnimatedTextures { get; set; } + public List AnimatedTextures { get; set; } public List Entities { get; set; } public List LightMap { get; set; } public List CinematicFrames { get; set; } - - /// - /// 2 bytes - /// - public ushort NumDemoData { get; set; } - - /// - /// NumDemoData bytes - /// public byte[] DemoData { get; set; } - - /// - /// 370 entries of 2 bytes each = 740 bytes - /// public short[] SoundMap { get; set; } - - /// - /// 4 bytes - /// - public uint NumSoundDetails { get; set; } - - /// - /// NumSoundDetails * 8 bytes - /// - public TRSoundDetails[] SoundDetails { get; set; } - - /// - /// 4 bytes - /// - public uint NumSampleIndices { get; set; } - - /// - /// NumSampleIndices * 4 bytes - /// - public uint[] SampleIndices { get; set; } + public List SoundDetails { get; set; } + public List SampleIndices { get; set; } } diff --git a/TRLevelControl/Model/TR3/TR3Level.cs b/TRLevelControl/Model/TR3/TR3Level.cs index 36319ad06..3c97a6de9 100644 --- a/TRLevelControl/Model/TR3/TR3Level.cs +++ b/TRLevelControl/Model/TR3/TR3Level.cs @@ -8,32 +8,8 @@ public class TR3Level : TRLevelBase public List Images16 { get; set; } public List Rooms { get; set; } public List FloorData { get; set; } - - /// - /// 4 bytes - /// - public uint NumMeshData { get; set; } - - /// - /// 2 * NumMeshData, holds the raw data stored in Meshes - /// - public ushort[] RawMeshData { get; set; } - - /// - /// Variable - /// - public TRMesh[] Meshes { get; set; } - - /// - /// 4 bytes - /// - public uint NumMeshPointers { get; set; } - - /// - /// NumMeshPointers * 4 bytes - /// - public uint[] MeshPointers { get; set; } - + public List Meshes { get; set; } + public List MeshPointers { get; set; } public List Animations { get; set; } public List StateChanges { get; set; } public List AnimDispatches { get; set; } @@ -42,87 +18,20 @@ public class TR3Level : TRLevelBase public List Frames { get; set; } public List Models { get; set; } public List StaticMeshes { get; set; } - - /// - /// 4 bytes - /// - public uint NumSpriteTextures { get; set; } - - /// - /// NumSpriteTextures * 16 bytes - /// - public TRSpriteTexture[] SpriteTextures { get; set; } - - /// - /// 4 bytes - /// - public uint NumSpriteSequences { get; set; } - - /// - /// NumSpriteSequences * 8 bytes - /// - public TRSpriteSequence[] SpriteSequences { get; set; } + public List SpriteTextures { get; set; } + public List SpriteSequences { get; set; } public List Cameras { get; set; } public List SoundSources { get; set; } public List Boxes { get; set; } public List Overlaps { get; set; } public List Zones { get; set; } - - /// - /// 4 bytes - /// - public uint NumAnimatedTextures { get; set; } - - /// - /// NumAnimatesTextures * 2 bytes - /// - public TRAnimatedTexture[] AnimatedTextures { get; set; } - - /// - /// 4 bytes - /// - public uint NumObjectTextures { get; set; } - - /// - /// NumObjectTextures * 20 bytes - /// - public TRObjectTexture[] ObjectTextures { get; set; } + public List AnimatedTextures { get; set; } + public List ObjectTextures { get; set; } public List Entities { get; set; } public List LightMap { get; set; } public List CinematicFrames { get; set; } - - /// - /// 2 bytes - /// - public ushort NumDemoData { get; set; } - - /// - /// NumDemoData bytes - /// public byte[] DemoData { get; set; } - - /// - /// 370 entries of 2 bytes each = 740 bytes - /// public short[] SoundMap { get; set; } - - /// - /// 4 bytes - /// - public uint NumSoundDetails { get; set; } - - /// - /// NumSoundDetails * 8 bytes - /// - public TR3SoundDetails[] SoundDetails { get; set; } - - /// - /// 4 bytes - /// - public uint NumSampleIndices { get; set; } - - /// - /// NumSampleIndices * 4 bytes - /// - public uint[] SampleIndices { get; set; } + public List SoundDetails { get; set; } + public List SampleIndices { get; set; } } diff --git a/TRLevelControl/Model/TR4/TR4Level.cs b/TRLevelControl/Model/TR4/TR4Level.cs index fad4a53e6..cb414b56e 100644 --- a/TRLevelControl/Model/TR4/TR4Level.cs +++ b/TRLevelControl/Model/TR4/TR4Level.cs @@ -10,7 +10,5 @@ public class TR4Level : TRLevelBase public TR4LevelDataChunk LevelDataChunk { get; set; } - public uint NumSamples { get; set; } - - public TR4Sample[] Samples { get; set; } + public List Samples { get; set; } } diff --git a/TRLevelControl/Model/TR4/TR4LevelDataChunk.cs b/TRLevelControl/Model/TR4/TR4LevelDataChunk.cs index 2a1715327..b938e670b 100644 --- a/TRLevelControl/Model/TR4/TR4LevelDataChunk.cs +++ b/TRLevelControl/Model/TR4/TR4LevelDataChunk.cs @@ -5,6 +5,9 @@ namespace TRLevelControl.Model; public class TR4LevelDataChunk : ISerializableCompact { + public static readonly string SPRMarker = "SPR"; + public static readonly string TEXMarker = "TEX"; + public uint UncompressedSize { get; set; } public uint CompressedSize { get; set; } @@ -12,17 +15,8 @@ public class TR4LevelDataChunk : ISerializableCompact public uint Unused { get; set; } public List Rooms { get; set; } public List FloorData { get; set; } - - public uint NumMeshData { get; set; } - - public ushort[] RawMeshData { get; set; } - - public TR4Mesh[] Meshes { get; set; } - - public uint NumMeshPointers { get; set; } - - public uint[] MeshPointers { get; set; } - + public List Meshes { get; set; } + public List MeshPointers { get; set; } public List Animations { get; set; } public List StateChanges { get; set; } public List AnimDispatches { get; set; } @@ -31,50 +25,23 @@ public class TR4LevelDataChunk : ISerializableCompact public List Frames { get; set; } public List Models { get; set; } public List StaticMeshes { get; set; } - - public byte[] SPRMarker { get; set; } - - public uint NumSpriteTextures { get; set; } - - public TRSpriteTexture[] SpriteTextures { get; set; } - - public uint NumSpriteSequences { get; set; } - - public TRSpriteSequence[] SpriteSequences { get; set; } + public List SpriteTextures { get; set; } + public List SpriteSequences { get; set; } public List Cameras { get; set; } public List FlybyCameras { get; set; } public List SoundSources { get; set; } public List Boxes { get; set; } public List Overlaps { get; set; } public List Zones { get; set; } - - public uint NumAnimatedTextures { get; set; } - - public TRAnimatedTexture[] AnimatedTextures { get; set; } - + public List AnimatedTextures { get; set; } public byte AnimatedTexturesUVCount { get; set; } - - public byte[] TEXMarker { get; set; } - - public uint NumObjectTextures { get; set; } - - public TR4ObjectTexture[] ObjectTextures { get; set; } + public List ObjectTextures { get; set; } public List Entities { get; set; } public List AIEntities { get; set; } - - public ushort NumDemoData { get; set; } - public byte[] DemoData { get; set; } - public short[] SoundMap { get; set; } - - public uint NumSoundDetails { get; set; } - - public TR3SoundDetails[] SoundDetails { get; set; } - - public uint NumSampleIndices { get; set; } - - public uint[] SampleIndices { get; set; } + public List SoundDetails { get; set; } + public List SampleIndices { get; set; } public byte[] Seperator { get; set; } @@ -97,15 +64,11 @@ public byte[] Serialize() writer.Write((uint)FloorData.Count); writer.Write(FloorData); - writer.Write(NumMeshData); - - foreach (TR4Mesh mesh in Meshes) - { - writer.Write(mesh.Serialize()); - } - - writer.Write(NumMeshPointers); + List meshData = Meshes.SelectMany(m => m.Serialize()).ToList(); + writer.Write((uint)meshData.Count / 2); + writer.Write(meshData.ToArray()); + writer.Write((uint)MeshPointers.Count); foreach (uint data in MeshPointers) { writer.Write(data); @@ -159,17 +122,15 @@ public byte[] Serialize() writer.Write(sm.Serialize()); } - writer.Write(SPRMarker); - - writer.Write(NumSpriteTextures); + writer.Write(SPRMarker.ToCharArray()); + writer.Write((uint)SpriteTextures.Count); foreach (TRSpriteTexture st in SpriteTextures) { writer.Write(st.Serialize()); } - writer.Write(NumSpriteSequences); - + writer.Write((uint)SpriteSequences.Count); foreach (TRSpriteSequence seq in SpriteSequences) { writer.Write(seq.Serialize()); @@ -210,15 +171,15 @@ public byte[] Serialize() writer.Write(zone); } - writer.Write(NumAnimatedTextures); - writer.Write((ushort)AnimatedTextures.Length); - foreach (TRAnimatedTexture texture in AnimatedTextures) { writer.Write(texture.Serialize()); } + byte[] animTextureData = AnimatedTextures.SelectMany(a => a.Serialize()).ToArray(); + writer.Write((uint)(animTextureData.Length / sizeof(ushort)) + 1); + writer.Write((ushort)AnimatedTextures.Count); + writer.Write(animTextureData); writer.Write(AnimatedTexturesUVCount); - writer.Write(TEXMarker); - - writer.Write(NumObjectTextures); + writer.Write(TEXMarker.ToCharArray()); + writer.Write((uint)ObjectTextures.Count); foreach (TR4ObjectTexture otex in ObjectTextures) { writer.Write(otex.Serialize()); @@ -230,7 +191,7 @@ public byte[] Serialize() writer.Write((uint)AIEntities.Count); writer.Write(AIEntities); - writer.Write(NumDemoData); + writer.Write((ushort)DemoData.Length); writer.Write(DemoData); foreach (short sound in SoundMap) @@ -238,15 +199,13 @@ public byte[] Serialize() writer.Write(sound); } - writer.Write(NumSoundDetails); - + writer.Write((uint)SoundDetails.Count); foreach (TR3SoundDetails snd in SoundDetails) { writer.Write(snd.Serialize()); } - writer.Write(NumSampleIndices); - + writer.Write((uint)SampleIndices.Count); foreach (uint sampleindex in SampleIndices) { writer.Write(sampleindex); diff --git a/TRLevelControl/Model/TR5/TR5Level.cs b/TRLevelControl/Model/TR5/TR5Level.cs index ffff05716..324c570c5 100644 --- a/TRLevelControl/Model/TR5/TR5Level.cs +++ b/TRLevelControl/Model/TR5/TR5Level.cs @@ -16,7 +16,5 @@ public class TR5Level : TRLevelBase public TR5LevelDataChunk LevelDataChunk { get; set; } - public uint NumSamples { get; set; } - - public TR4Sample[] Samples { get; set; } + public List Samples { get; set; } } diff --git a/TRLevelControl/Model/TR5/TR5LevelDataChunk.cs b/TRLevelControl/Model/TR5/TR5LevelDataChunk.cs index 619694d06..2a0f96bf8 100644 --- a/TRLevelControl/Model/TR5/TR5LevelDataChunk.cs +++ b/TRLevelControl/Model/TR5/TR5LevelDataChunk.cs @@ -2,6 +2,9 @@ public class TR5LevelDataChunk { + public static readonly string SPRMarker = "SPR\0"; + public static readonly string TEXMarker = "TEX\0"; + public uint UncompressedSize { get; set; } public uint CompressedSize { get; set; } @@ -9,17 +12,8 @@ public class TR5LevelDataChunk public uint Unused { get; set; } public List Rooms { get; set; } public List FloorData { get; set; } - - public uint NumMeshData { get; set; } - - public ushort[] RawMeshData { get; set; } - - public TR4Mesh[] Meshes { get; set; } - - public uint NumMeshPointers { get; set; } - - public uint[] MeshPointers { get; set; } - + public List Meshes { get; set; } + public List MeshPointers { get; set; } public List Animations { get; set; } public List StateChanges { get; set; } public List AnimDispatches { get; set; } @@ -28,50 +22,24 @@ public class TR5LevelDataChunk public List Frames { get; set; } public List Models { get; set; } public List StaticMeshes { get; set; } - - public byte[] SPRMarker { get; set; } - - public uint NumSpriteTextures { get; set; } - - public TRSpriteTexture[] SpriteTextures { get; set; } - - public uint NumSpriteSequences { get; set; } - - public TRSpriteSequence[] SpriteSequences { get; set; } + public List SpriteTextures { get; set; } + public List SpriteSequences { get; set; } public List Cameras { get; set; } public List FlybyCameras { get; set; } public List SoundSources { get; set; } public List Boxes { get; set; } public List Overlaps { get; set; } public List Zones { get; set; } - - public uint NumAnimatedTextures { get; set; } - - public TRAnimatedTexture[] AnimatedTextures { get; set; } - + public List AnimatedTextures { get; set; } public byte AnimatedTexturesUVCount { get; set; } - - public byte[] TEXMarker { get; set; } - - public uint NumObjectTextures { get; set; } - - public TR5ObjectTexture[] ObjectTextures { get; set; } + public List ObjectTextures { get; set; } public List Entities { get; set; } public List AIEntities { get; set; } - - public ushort NumDemoData { get; set; } - public byte[] DemoData { get; set; } public short[] SoundMap { get; set; } - - public uint NumSoundDetails { get; set; } - - public TR3SoundDetails[] SoundDetails { get; set; } - - public uint NumSampleIndices { get; set; } - - public uint[] SampleIndices { get; set; } + public List SoundDetails { get; set; } + public List SampleIndices { get; set; } public byte[] Seperator { get; set; } @@ -94,15 +62,11 @@ public byte[] Serialize() writer.Write((uint)FloorData.Count); writer.Write(FloorData); - writer.Write(NumMeshData); - - foreach (TR4Mesh mesh in Meshes) - { - writer.Write(mesh.Serialize()); - } - - writer.Write(NumMeshPointers); + List meshData = Meshes.SelectMany(m => m.Serialize()).ToList(); + writer.Write((uint)meshData.Count / 2); + writer.Write(meshData.ToArray()); + writer.Write((uint)MeshPointers.Count); foreach (uint data in MeshPointers) { writer.Write(data); @@ -156,17 +120,15 @@ public byte[] Serialize() writer.Write(sm.Serialize()); } - writer.Write(SPRMarker); - - writer.Write(NumSpriteTextures); + writer.Write(SPRMarker.ToCharArray()); + writer.Write((uint)SpriteTextures.Count); foreach (TRSpriteTexture st in SpriteTextures) { writer.Write(st.Serialize()); } - writer.Write(NumSpriteSequences); - + writer.Write((uint)SpriteSequences.Count); foreach (TRSpriteSequence seq in SpriteSequences) { writer.Write(seq.Serialize()); @@ -207,15 +169,15 @@ public byte[] Serialize() writer.Write(zone); } - writer.Write(NumAnimatedTextures); - writer.Write((ushort)AnimatedTextures.Length); - foreach (TRAnimatedTexture texture in AnimatedTextures) { writer.Write(texture.Serialize()); } + byte[] animTextureData = AnimatedTextures.SelectMany(a => a.Serialize()).ToArray(); + writer.Write((uint)(animTextureData.Length / sizeof(ushort)) + 1); + writer.Write((ushort)AnimatedTextures.Count); + writer.Write(animTextureData); writer.Write(AnimatedTexturesUVCount); - writer.Write(TEXMarker); - - writer.Write(NumObjectTextures); + writer.Write(TEXMarker.ToCharArray()); + writer.Write((uint)ObjectTextures.Count); foreach (TR5ObjectTexture otex in ObjectTextures) { writer.Write(otex.Serialize()); @@ -227,7 +189,7 @@ public byte[] Serialize() writer.Write((uint)AIEntities.Count); writer.Write(AIEntities); - writer.Write(NumDemoData); + writer.Write((ushort)DemoData.Length); writer.Write(DemoData); foreach (short sound in SoundMap) @@ -235,15 +197,13 @@ public byte[] Serialize() writer.Write(sound); } - writer.Write(NumSoundDetails); - + writer.Write((uint)SoundDetails.Count); foreach (TR3SoundDetails snd in SoundDetails) { writer.Write(snd.Serialize()); } - writer.Write(NumSampleIndices); - + writer.Write((uint)SampleIndices.Count); foreach (uint sampleindex in SampleIndices) { writer.Write(sampleindex); diff --git a/TRLevelControl/TR2FileReadUtilities.cs b/TRLevelControl/TR2FileReadUtilities.cs index b60b8d287..eee10c444 100644 --- a/TRLevelControl/TR2FileReadUtilities.cs +++ b/TRLevelControl/TR2FileReadUtilities.cs @@ -312,11 +312,12 @@ public static TR2Box ReadBox(BinaryReader reader) public static TRAnimatedTexture ReadAnimatedTexture(BinaryReader reader) { - ushort numTextures = reader.ReadUInt16(); // Actually num textures - 1, see https://opentomb.github.io/TRosettaStone3/trosettastone.html#_animated_textures_2 - ushort[] textures = new ushort[numTextures + 1]; - for (int i = 0; i < textures.Length; i++) + // See https://opentomb.github.io/TRosettaStone3/trosettastone.html#_animated_textures_2 + int numTextures = reader.ReadUInt16() + 1; + List textures = new(); + for (int i = 0; i < numTextures; i++) { - textures[i] = reader.ReadUInt16(); + textures.Add(reader.ReadUInt16()); } return new TRAnimatedTexture diff --git a/TRLevelControl/TR4FileReadUtilities.cs b/TRLevelControl/TR4FileReadUtilities.cs index 57ba58092..11edb98ce 100644 --- a/TRLevelControl/TR4FileReadUtilities.cs +++ b/TRLevelControl/TR4FileReadUtilities.cs @@ -95,29 +95,23 @@ public static void PopulateFloordata(BinaryReader reader, TR4Level lvl) public static void PopulateMeshes(BinaryReader reader, TR4Level lvl) { - //Mesh Data - //This tells us how much mesh data (# of words/uint16s) coming up - //just like the rooms previously. - lvl.LevelDataChunk.NumMeshData = reader.ReadUInt32(); - lvl.LevelDataChunk.RawMeshData = new ushort[lvl.LevelDataChunk.NumMeshData]; + uint numMeshData = reader.ReadUInt32(); + ushort[] rawMeshData = new ushort[numMeshData]; - for (int i = 0; i < lvl.LevelDataChunk.NumMeshData; i++) + for (int i = 0; i < numMeshData; i++) { - lvl.LevelDataChunk.RawMeshData[i] = reader.ReadUInt16(); + rawMeshData[i] = reader.ReadUInt16(); } - //Mesh Pointers - lvl.LevelDataChunk.NumMeshPointers = reader.ReadUInt32(); - lvl.LevelDataChunk.MeshPointers = new uint[lvl.LevelDataChunk.NumMeshPointers]; + uint numMeshPointers = reader.ReadUInt32(); + lvl.LevelDataChunk.MeshPointers = new(); - for (int i = 0; i < lvl.LevelDataChunk.NumMeshPointers; i++) + for (int i = 0; i < numMeshPointers; i++) { - lvl.LevelDataChunk.MeshPointers[i] = reader.ReadUInt32(); + lvl.LevelDataChunk.MeshPointers.Add(reader.ReadUInt32()); } - //Mesh Construction - //level.Meshes = ConstructMeshData(level.NumMeshData, level.NumMeshPointers, level.RawMeshData); - lvl.LevelDataChunk.Meshes = ConstructMeshData(lvl.LevelDataChunk.MeshPointers, lvl.LevelDataChunk.RawMeshData); + lvl.LevelDataChunk.Meshes = ConstructMeshData(lvl.LevelDataChunk.MeshPointers, rawMeshData); } public static void PopulateAnimations(BinaryReader reader, TR4Level lvl) @@ -193,33 +187,28 @@ public static void PopulateStaticMeshes(BinaryReader reader, TR4Level lvl) } } - public static void VerifySPRMarker(BinaryReader reader, TR4Level lvl) + public static void VerifySPRMarker(BinaryReader reader) { - lvl.LevelDataChunk.SPRMarker = reader.ReadBytes(3); - - Debug.Assert(lvl.LevelDataChunk.SPRMarker[0] == 0x53); - Debug.Assert(lvl.LevelDataChunk.SPRMarker[1] == 0x50); - Debug.Assert(lvl.LevelDataChunk.SPRMarker[2] == 0x52); + string sprMarker = new(reader.ReadChars(TR4LevelDataChunk.SPRMarker.Length)); + Debug.Assert(sprMarker == TR4LevelDataChunk.SPRMarker); } public static void PopulateSprites(BinaryReader reader, TR4Level lvl) { - //Sprite Textures - lvl.LevelDataChunk.NumSpriteTextures = reader.ReadUInt32(); - lvl.LevelDataChunk.SpriteTextures = new TRSpriteTexture[lvl.LevelDataChunk.NumSpriteTextures]; + uint numSpriteTextures = reader.ReadUInt32(); + lvl.LevelDataChunk.SpriteTextures = new(); - for (int i = 0; i < lvl.LevelDataChunk.NumSpriteTextures; i++) + for (int i = 0; i < numSpriteTextures; i++) { - lvl.LevelDataChunk.SpriteTextures[i] = TR2FileReadUtilities.ReadSpriteTexture(reader); + lvl.LevelDataChunk.SpriteTextures.Add(TR2FileReadUtilities.ReadSpriteTexture(reader)); } - //Sprite Sequences - lvl.LevelDataChunk.NumSpriteSequences = reader.ReadUInt32(); - lvl.LevelDataChunk.SpriteSequences = new TRSpriteSequence[lvl.LevelDataChunk.NumSpriteSequences]; + uint numSpriteSequences = reader.ReadUInt32(); + lvl.LevelDataChunk.SpriteSequences = new(); - for (int i = 0; i < lvl.LevelDataChunk.NumSpriteSequences; i++) + for (int i = 0; i < numSpriteSequences; i++) { - lvl.LevelDataChunk.SpriteSequences[i] = TR2FileReadUtilities.ReadSpriteSequence(reader); + lvl.LevelDataChunk.SpriteSequences.Add(TR2FileReadUtilities.ReadSpriteSequence(reader)); } } @@ -286,35 +275,32 @@ public static void PopulateBoxesOverlapsZones(BinaryReader reader, TR4Level lvl) public static void PopulateAnimatedTextures(BinaryReader reader, TR4Level lvl) { - lvl.LevelDataChunk.NumAnimatedTextures = reader.ReadUInt32(); - lvl.LevelDataChunk.AnimatedTextures = new TRAnimatedTexture[reader.ReadUInt16()]; - for (int i = 0; i < lvl.LevelDataChunk.AnimatedTextures.Length; i++) + reader.ReadUInt32(); // Total count of ushorts + ushort numGroups = reader.ReadUInt16(); + lvl.LevelDataChunk.AnimatedTextures = new(); + for (int i = 0; i < numGroups; i++) { - lvl.LevelDataChunk.AnimatedTextures[i] = TR2FileReadUtilities.ReadAnimatedTexture(reader); + lvl.LevelDataChunk.AnimatedTextures.Add(TR2FileReadUtilities.ReadAnimatedTexture(reader)); } //TR4+ Specific lvl.LevelDataChunk.AnimatedTexturesUVCount = reader.ReadByte(); } - public static void VerifyTEXMarker(BinaryReader reader, TR4Level lvl) + public static void VerifyTEXMarker(BinaryReader reader) { - lvl.LevelDataChunk.TEXMarker = reader.ReadBytes(3); - - Debug.Assert(lvl.LevelDataChunk.TEXMarker[0] == 0x54); - Debug.Assert(lvl.LevelDataChunk.TEXMarker[1] == 0x45); - Debug.Assert(lvl.LevelDataChunk.TEXMarker[2] == 0x58); + string texMarker = new(reader.ReadChars(TR4LevelDataChunk.TEXMarker.Length)); + Debug.Assert(texMarker == TR4LevelDataChunk.TEXMarker); } public static void PopulateObjectTextures(BinaryReader reader, TR4Level lvl) { - //Object Textures - lvl.LevelDataChunk.NumObjectTextures = reader.ReadUInt32(); - lvl.LevelDataChunk.ObjectTextures = new TR4ObjectTexture[lvl.LevelDataChunk.NumObjectTextures]; + uint numObjectTextures = reader.ReadUInt32(); + lvl.LevelDataChunk.ObjectTextures = new(); - for (int i = 0; i < lvl.LevelDataChunk.NumObjectTextures; i++) + for (int i = 0; i < numObjectTextures; i++) { - lvl.LevelDataChunk.ObjectTextures[i] = TR4FileReadUtilities.ReadObjectTexture(reader); + lvl.LevelDataChunk.ObjectTextures.Add(ReadObjectTexture(reader)); } } @@ -331,14 +317,8 @@ public static void PopulateEntitiesAndAI(TRLevelReader reader, TR4Level lvl) public static void PopulateDemoSoundSampleIndices(BinaryReader reader, TR4Level lvl) { - //Demo Data - lvl.LevelDataChunk.NumDemoData = reader.ReadUInt16(); - lvl.LevelDataChunk.DemoData = new byte[lvl.LevelDataChunk.NumDemoData]; - - for (int i = 0; i < lvl.LevelDataChunk.NumDemoData; i++) - { - lvl.LevelDataChunk.DemoData[i] = reader.ReadByte(); - } + ushort numDemoData = reader.ReadUInt16(); + lvl.LevelDataChunk.DemoData = reader.ReadBytes(numDemoData); //Sound Map (370 shorts) & Sound Details lvl.LevelDataChunk.SoundMap = new short[370]; @@ -348,21 +328,20 @@ public static void PopulateDemoSoundSampleIndices(BinaryReader reader, TR4Level lvl.LevelDataChunk.SoundMap[i] = reader.ReadInt16(); } - lvl.LevelDataChunk.NumSoundDetails = reader.ReadUInt32(); - lvl.LevelDataChunk.SoundDetails = new TR3SoundDetails[lvl.LevelDataChunk.NumSoundDetails]; + uint numSoundDetails = reader.ReadUInt32(); + lvl.LevelDataChunk.SoundDetails = new(); - for (int i = 0; i < lvl.LevelDataChunk.NumSoundDetails; i++) + for (int i = 0; i < numSoundDetails; i++) { - lvl.LevelDataChunk.SoundDetails[i] = TR3FileReadUtilities.ReadSoundDetails(reader); + lvl.LevelDataChunk.SoundDetails.Add(TR3FileReadUtilities.ReadSoundDetails(reader)); } - //Samples - lvl.LevelDataChunk.NumSampleIndices = reader.ReadUInt32(); - lvl.LevelDataChunk.SampleIndices = new uint[lvl.LevelDataChunk.NumSampleIndices]; + uint numSampleIndices = reader.ReadUInt32(); + lvl.LevelDataChunk.SampleIndices = new(); - for (int i = 0; i < lvl.LevelDataChunk.NumSampleIndices; i++) + for (int i = 0; i < numSampleIndices; i++) { - lvl.LevelDataChunk.SampleIndices[i] = reader.ReadUInt32(); + lvl.LevelDataChunk.SampleIndices.Add(reader.ReadUInt32()); } } @@ -515,21 +494,21 @@ private static TR4RoomLight ReadRoomLight(BinaryReader reader) }; } - public static TR4Mesh[] ConstructMeshData(uint[] meshPointers, ushort[] rawMeshData) + public static List ConstructMeshData(List meshPointers, ushort[] rawMeshData) { byte[] target = new byte[rawMeshData.Length * 2]; Buffer.BlockCopy(rawMeshData, 0, target, 0, target.Length); // The mesh pointer list can contain duplicates so we must make // sure to iterate over distinct values only - meshPointers = meshPointers.Distinct().ToArray(); + meshPointers = new(meshPointers.Distinct()); List meshes = new(); using (MemoryStream ms = new(target)) using (BinaryReader br = new(ms)) { - for (int i = 0; i < meshPointers.Length; i++) + for (int i = 0; i < meshPointers.Count; i++) { TR4Mesh mesh = new(); meshes.Add(mesh); @@ -598,7 +577,7 @@ public static TR4Mesh[] ConstructMeshData(uint[] meshPointers, ushort[] rawMeshD } } - return meshes.ToArray(); + return meshes; } public static TR4MeshFace4 ReadTR4MeshFace4(BinaryReader reader) diff --git a/TRLevelControl/TR5FileReadUtilities.cs b/TRLevelControl/TR5FileReadUtilities.cs index 3bffba328..b93e8794f 100644 --- a/TRLevelControl/TR5FileReadUtilities.cs +++ b/TRLevelControl/TR5FileReadUtilities.cs @@ -212,29 +212,23 @@ public static void PopulateFloordata(BinaryReader reader, TR5Level lvl) public static void PopulateMeshes(BinaryReader reader, TR5Level lvl) { - //Mesh Data - //This tells us how much mesh data (# of words/uint16s) coming up - //just like the rooms previously. - lvl.LevelDataChunk.NumMeshData = reader.ReadUInt32(); - lvl.LevelDataChunk.RawMeshData = new ushort[lvl.LevelDataChunk.NumMeshData]; + uint numMeshData = reader.ReadUInt32(); + ushort[] rawMeshData = new ushort[numMeshData]; - for (int i = 0; i < lvl.LevelDataChunk.NumMeshData; i++) + for (int i = 0; i < numMeshData; i++) { - lvl.LevelDataChunk.RawMeshData[i] = reader.ReadUInt16(); + rawMeshData[i] = reader.ReadUInt16(); } - //Mesh Pointers - lvl.LevelDataChunk.NumMeshPointers = reader.ReadUInt32(); - lvl.LevelDataChunk.MeshPointers = new uint[lvl.LevelDataChunk.NumMeshPointers]; + uint numMeshPointers = reader.ReadUInt32(); + lvl.LevelDataChunk.MeshPointers = new(); - for (int i = 0; i < lvl.LevelDataChunk.NumMeshPointers; i++) + for (int i = 0; i < numMeshPointers; i++) { - lvl.LevelDataChunk.MeshPointers[i] = reader.ReadUInt32(); + lvl.LevelDataChunk.MeshPointers.Add(reader.ReadUInt32()); } - //Mesh Construction - //level.Meshes = ConstructMeshData(level.NumMeshData, level.NumMeshPointers, level.RawMeshData); - lvl.LevelDataChunk.Meshes = TR4FileReadUtilities.ConstructMeshData(lvl.LevelDataChunk.MeshPointers, lvl.LevelDataChunk.RawMeshData); + lvl.LevelDataChunk.Meshes = TR4FileReadUtilities.ConstructMeshData(lvl.LevelDataChunk.MeshPointers, rawMeshData); } public static void PopulateAnimations(BinaryReader reader, TR5Level lvl) @@ -324,34 +318,28 @@ public static void PopulateStaticMeshes(BinaryReader reader, TR5Level lvl) } } - public static void VerifySPRMarker(BinaryReader reader, TR5Level lvl) + public static void VerifySPRMarker(BinaryReader reader) { - lvl.LevelDataChunk.SPRMarker = reader.ReadBytes(4); - - Debug.Assert(lvl.LevelDataChunk.SPRMarker[0] == 0x53); - Debug.Assert(lvl.LevelDataChunk.SPRMarker[1] == 0x50); - Debug.Assert(lvl.LevelDataChunk.SPRMarker[2] == 0x52); - Debug.Assert(lvl.LevelDataChunk.SPRMarker[3] == 0x00); + string sprMarker = new(reader.ReadChars(TR5LevelDataChunk.SPRMarker.Length)); + Debug.Assert(sprMarker == TR5LevelDataChunk.SPRMarker); } public static void PopulateSprites(BinaryReader reader, TR5Level lvl) { - //Sprite Textures - lvl.LevelDataChunk.NumSpriteTextures = reader.ReadUInt32(); - lvl.LevelDataChunk.SpriteTextures = new TRSpriteTexture[lvl.LevelDataChunk.NumSpriteTextures]; + uint numSpriteTextures = reader.ReadUInt32(); + lvl.LevelDataChunk.SpriteTextures = new(); - for (int i = 0; i < lvl.LevelDataChunk.NumSpriteTextures; i++) + for (int i = 0; i < numSpriteTextures; i++) { - lvl.LevelDataChunk.SpriteTextures[i] = TR2FileReadUtilities.ReadSpriteTexture(reader); + lvl.LevelDataChunk.SpriteTextures.Add(TR2FileReadUtilities.ReadSpriteTexture(reader)); } - //Sprite Sequences - lvl.LevelDataChunk.NumSpriteSequences = reader.ReadUInt32(); - lvl.LevelDataChunk.SpriteSequences = new TRSpriteSequence[lvl.LevelDataChunk.NumSpriteSequences]; + uint numSpriteSequences = reader.ReadUInt32(); + lvl.LevelDataChunk.SpriteSequences = new(); - for (int i = 0; i < lvl.LevelDataChunk.NumSpriteSequences; i++) + for (int i = 0; i < numSpriteSequences; i++) { - lvl.LevelDataChunk.SpriteSequences[i] = TR2FileReadUtilities.ReadSpriteSequence(reader); + lvl.LevelDataChunk.SpriteSequences.Add(TR2FileReadUtilities.ReadSpriteSequence(reader)); } } @@ -418,36 +406,32 @@ public static void PopulateBoxesOverlapsZones(BinaryReader reader, TR5Level lvl) public static void PopulateAnimatedTextures(BinaryReader reader, TR5Level lvl) { - lvl.LevelDataChunk.NumAnimatedTextures = reader.ReadUInt32(); - lvl.LevelDataChunk.AnimatedTextures = new TRAnimatedTexture[reader.ReadUInt16()]; - for (int i = 0; i < lvl.LevelDataChunk.AnimatedTextures.Length; i++) + reader.ReadUInt32(); // Total count of ushorts + ushort numGroups = reader.ReadUInt16(); + lvl.LevelDataChunk.AnimatedTextures = new(); + for (int i = 0; i < numGroups; i++) { - lvl.LevelDataChunk.AnimatedTextures[i] = TR2FileReadUtilities.ReadAnimatedTexture(reader); + lvl.LevelDataChunk.AnimatedTextures.Add(TR2FileReadUtilities.ReadAnimatedTexture(reader)); } //TR4+ Specific lvl.LevelDataChunk.AnimatedTexturesUVCount = reader.ReadByte(); } - public static void VerifyTEXMarker(BinaryReader reader, TR5Level lvl) + public static void VerifyTEXMarker(BinaryReader reader) { - lvl.LevelDataChunk.TEXMarker = reader.ReadBytes(4); - - Debug.Assert(lvl.LevelDataChunk.TEXMarker[0] == 0x54); - Debug.Assert(lvl.LevelDataChunk.TEXMarker[1] == 0x45); - Debug.Assert(lvl.LevelDataChunk.TEXMarker[2] == 0x58); - Debug.Assert(lvl.LevelDataChunk.TEXMarker[3] == 0x00); + string texMarker = new(reader.ReadChars(TR5LevelDataChunk.TEXMarker.Length)); + Debug.Assert(texMarker == TR5LevelDataChunk.TEXMarker); } public static void PopulateObjectTextures(BinaryReader reader, TR5Level lvl) { - //Object Textures - lvl.LevelDataChunk.NumObjectTextures = reader.ReadUInt32(); - lvl.LevelDataChunk.ObjectTextures = new TR5ObjectTexture[lvl.LevelDataChunk.NumObjectTextures]; + uint numObjectTextures = reader.ReadUInt32(); + lvl.LevelDataChunk.ObjectTextures = new(); - for (int i = 0; i < lvl.LevelDataChunk.NumObjectTextures; i++) + for (int i = 0; i < numObjectTextures; i++) { - lvl.LevelDataChunk.ObjectTextures[i] = ReadTR5ObjectTexture(reader); + lvl.LevelDataChunk.ObjectTextures.Add(ReadTR5ObjectTexture(reader)); } } @@ -501,14 +485,8 @@ public static void PopulateEntitiesAndAI(TRLevelReader reader, TR5Level lvl) public static void PopulateDemoSoundSampleIndices(BinaryReader reader, TR5Level lvl) { - //Demo Data - lvl.LevelDataChunk.NumDemoData = reader.ReadUInt16(); - lvl.LevelDataChunk.DemoData = new byte[lvl.LevelDataChunk.NumDemoData]; - - for (int i = 0; i < lvl.LevelDataChunk.NumDemoData; i++) - { - lvl.LevelDataChunk.DemoData[i] = reader.ReadByte(); - } + ushort numDemoData = reader.ReadUInt16(); + lvl.LevelDataChunk.DemoData = reader.ReadBytes(numDemoData); //Sound Map (370 shorts) & Sound Details lvl.LevelDataChunk.SoundMap = new short[450]; @@ -518,21 +496,20 @@ public static void PopulateDemoSoundSampleIndices(BinaryReader reader, TR5Level lvl.LevelDataChunk.SoundMap[i] = reader.ReadInt16(); } - lvl.LevelDataChunk.NumSoundDetails = reader.ReadUInt32(); - lvl.LevelDataChunk.SoundDetails = new TR3SoundDetails[lvl.LevelDataChunk.NumSoundDetails]; + uint numSoundDetails = reader.ReadUInt32(); + lvl.LevelDataChunk.SoundDetails = new(); - for (int i = 0; i < lvl.LevelDataChunk.NumSoundDetails; i++) + for (int i = 0; i < numSoundDetails; i++) { - lvl.LevelDataChunk.SoundDetails[i] = TR3FileReadUtilities.ReadSoundDetails(reader); + lvl.LevelDataChunk.SoundDetails.Add(TR3FileReadUtilities.ReadSoundDetails(reader)); } - //Samples - lvl.LevelDataChunk.NumSampleIndices = reader.ReadUInt32(); - lvl.LevelDataChunk.SampleIndices = new uint[lvl.LevelDataChunk.NumSampleIndices]; + uint numSampleIndices = reader.ReadUInt32(); + lvl.LevelDataChunk.SampleIndices = new(); - for (int i = 0; i < lvl.LevelDataChunk.NumSampleIndices; i++) + for (int i = 0; i < numSampleIndices; i++) { - lvl.LevelDataChunk.SampleIndices[i] = reader.ReadUInt32(); + lvl.LevelDataChunk.SampleIndices.Add(reader.ReadUInt32()); } } diff --git a/TRLevelToolset/Controls/DataControls/TR/TRAnimatedTextureControl.cs b/TRLevelToolset/Controls/DataControls/TR/TRAnimatedTextureControl.cs index 5e885f76f..2d451cc84 100644 --- a/TRLevelToolset/Controls/DataControls/TR/TRAnimatedTextureControl.cs +++ b/TRLevelToolset/Controls/DataControls/TR/TRAnimatedTextureControl.cs @@ -10,7 +10,7 @@ public void Draw() { if (ImGui.TreeNodeEx("Animated Textures", ImGuiTreeNodeFlags.OpenOnArrow)) { - ImGui.Text("Animated Texture Count: " + IOManager.CurrentLevelAsTR1?.NumAnimatedTextures); + ImGui.Text("Animated Texture Count: " + IOManager.CurrentLevelAsTR1?.AnimatedTextures.Count); ImGui.TreePop(); } diff --git a/TRLevelToolset/Controls/DataControls/TR/TRDemoDataControl.cs b/TRLevelToolset/Controls/DataControls/TR/TRDemoDataControl.cs index e8c2fc13f..8be2b5479 100644 --- a/TRLevelToolset/Controls/DataControls/TR/TRDemoDataControl.cs +++ b/TRLevelToolset/Controls/DataControls/TR/TRDemoDataControl.cs @@ -10,7 +10,7 @@ public void Draw() { if (ImGui.TreeNodeEx("Demo Data", ImGuiTreeNodeFlags.OpenOnArrow)) { - ImGui.Text("Demo Data Size: " + IOManager.CurrentLevelAsTR1?.NumDemoData); + ImGui.Text("Demo Data Size: " + IOManager.CurrentLevelAsTR1?.DemoData.Length); ImGui.TreePop(); } } diff --git a/TRLevelToolset/Controls/DataControls/TR/TRMeshControl.cs b/TRLevelToolset/Controls/DataControls/TR/TRMeshControl.cs index 5bcf42329..d0ef8d7c0 100644 --- a/TRLevelToolset/Controls/DataControls/TR/TRMeshControl.cs +++ b/TRLevelToolset/Controls/DataControls/TR/TRMeshControl.cs @@ -10,8 +10,8 @@ public void Draw() { if (ImGui.TreeNodeEx("Mesh Data", ImGuiTreeNodeFlags.OpenOnArrow)) { - ImGui.Text("Mesh data count: " + IOManager.CurrentLevelAsTR1?.NumMeshData); - ImGui.Text("Mesh pointer count: " + IOManager.CurrentLevelAsTR1?.NumMeshPointers); + ImGui.Text("Mesh count: " + IOManager.CurrentLevelAsTR1?.Meshes.Count); + ImGui.Text("Mesh pointer count: " + IOManager.CurrentLevelAsTR1?.MeshPointers.Count); ImGui.TreePop(); } diff --git a/TRLevelToolset/Controls/DataControls/TR/TRSoundControl.cs b/TRLevelToolset/Controls/DataControls/TR/TRSoundControl.cs index 15446cd12..4017806f9 100644 --- a/TRLevelToolset/Controls/DataControls/TR/TRSoundControl.cs +++ b/TRLevelToolset/Controls/DataControls/TR/TRSoundControl.cs @@ -11,9 +11,9 @@ public void Draw() if (ImGui.TreeNodeEx("Sound Data", ImGuiTreeNodeFlags.OpenOnArrow)) { ImGui.Text("Sound sources count: " + IOManager.CurrentLevelAsTR1?.SoundSources.Count); - ImGui.Text("Sound details count: " + IOManager.CurrentLevelAsTR1?.NumSoundDetails); - ImGui.Text("Sound samples count: " + IOManager.CurrentLevelAsTR1?.NumSamples); - ImGui.Text("Sound sample indices count: " + IOManager.CurrentLevelAsTR1?.NumSampleIndices); + ImGui.Text("Sound details count: " + IOManager.CurrentLevelAsTR1?.SoundDetails.Count); + ImGui.Text("Sound samples count: " + IOManager.CurrentLevelAsTR1?.Samples.Count); + ImGui.Text("Sound sample indices count: " + IOManager.CurrentLevelAsTR1?.SampleIndices.Count); ImGui.Text("Sound map size: " + IOManager.CurrentLevelAsTR1?.SoundMap.Length); ImGui.TreePop(); diff --git a/TRLevelToolset/Controls/DataControls/TR/TRSpriteAndObjTextureControl.cs b/TRLevelToolset/Controls/DataControls/TR/TRSpriteAndObjTextureControl.cs index 6d3df3907..6843ecd41 100644 --- a/TRLevelToolset/Controls/DataControls/TR/TRSpriteAndObjTextureControl.cs +++ b/TRLevelToolset/Controls/DataControls/TR/TRSpriteAndObjTextureControl.cs @@ -10,9 +10,9 @@ public void Draw() { if (ImGui.TreeNodeEx("Sprite and Object Texture Data", ImGuiTreeNodeFlags.OpenOnArrow)) { - ImGui.Text("Object texture count: " + IOManager.CurrentLevelAsTR1?.NumObjectTextures); - ImGui.Text("Sprite texture count: " + IOManager.CurrentLevelAsTR1?.NumSpriteTextures); - ImGui.Text("Sprite sequence count: " + IOManager.CurrentLevelAsTR1?.NumSpriteSequences); + ImGui.Text("Object texture count: " + IOManager.CurrentLevelAsTR1?.ObjectTextures.Count); + ImGui.Text("Sprite texture count: " + IOManager.CurrentLevelAsTR1?.SpriteTextures.Count); + ImGui.Text("Sprite sequence count: " + IOManager.CurrentLevelAsTR1?.SpriteSequences.Count); ImGui.TreePop(); } diff --git a/TRModelTransporter/Handlers/Animations/AnimationUtilities.cs b/TRModelTransporter/Handlers/Animations/AnimationUtilities.cs index 50645367f..91695e8b5 100644 --- a/TRModelTransporter/Handlers/Animations/AnimationUtilities.cs +++ b/TRModelTransporter/Handlers/Animations/AnimationUtilities.cs @@ -165,7 +165,7 @@ public static void PackAnimSounds(TR3Level level, TR3PackedAnimation packedAnima } // Covers TR1 - private static void PackAnimSounds(short[] soundMap, TRSoundDetails[] soundDetails, uint[] sampleIndices, byte[] wavSamples, TR1PackedAnimation packedAnimation) + private static void PackAnimSounds(short[] soundMap, List soundDetails, List sampleIndices, List wavSamples, TR1PackedAnimation packedAnimation) { foreach (TR1PackedAnimationCommand cmd in packedAnimation.Commands.Values) { @@ -185,7 +185,7 @@ private static void PackAnimSounds(short[] soundMap, TRSoundDetails[] soundDetai ushort sampleIndex = (ushort)(details.Sample + i); samples[i] = sampleIndices[sampleIndex]; - uint nextIndex = sampleIndex == sampleIndices.Length - 1 ? (uint)sampleIndices.Length : sampleIndices[sampleIndex + 1]; + uint nextIndex = sampleIndex == sampleIndices.Count - 1 ? (uint)sampleIndices.Count : sampleIndices[sampleIndex + 1]; packedAnimation.Sound.Samples[samples[i]] = GetSample(samples[i], nextIndex, wavSamples); } @@ -195,18 +195,18 @@ private static void PackAnimSounds(short[] soundMap, TRSoundDetails[] soundDetai } } - public static byte[] GetSample(uint offset, uint endOffset, byte[] wavSamples) + public static byte[] GetSample(uint offset, uint endOffset, List wavSamples) { List data = new(); for (uint i = offset; i < endOffset; i++) { - data.Add(wavSamples[i]); + data.Add(wavSamples[(int)i]); } return data.ToArray(); } // Covers TR2 - private static void PackAnimSounds(short[] soundMap, TRSoundDetails[] soundDetails, uint[] sampleIndices, TR2PackedAnimation packedAnimation) + private static void PackAnimSounds(short[] soundMap, List soundDetails, List sampleIndices, TR2PackedAnimation packedAnimation) { foreach (TR1PackedAnimationCommand cmd in packedAnimation.Commands.Values) { @@ -233,7 +233,7 @@ private static void PackAnimSounds(short[] soundMap, TRSoundDetails[] soundDetai } // Covers TR3-5 - private static void PackAnimSounds(short[] soundMap, TR3SoundDetails[] soundDetails, uint[] sampleIndices, TR3PackedAnimation packedAnimation) + private static void PackAnimSounds(short[] soundMap, List soundDetails, List sampleIndices, TR3PackedAnimation packedAnimation) { foreach (TR1PackedAnimationCommand cmd in packedAnimation.Commands.Values) { diff --git a/TRModelTransporter/Handlers/ColourTransportHandler.cs b/TRModelTransporter/Handlers/ColourTransportHandler.cs index 002ebac27..785458bc9 100644 --- a/TRModelTransporter/Handlers/ColourTransportHandler.cs +++ b/TRModelTransporter/Handlers/ColourTransportHandler.cs @@ -21,7 +21,7 @@ public static void Export(TR3Level level, TR3ModelDefinition definition) definition.Colours = GetUsedMeshColours(definition.Meshes, level.Palette16); } - private static Dictionary GetUsedMeshColours(TRMesh[] meshes, List colours) + private static Dictionary GetUsedMeshColours(List meshes, List colours) { ISet colourIndices = GetAllColourIndices(meshes, false); @@ -34,7 +34,7 @@ private static Dictionary GetUsedMeshColours(TRMesh[] meshes, Lis return usedColours; } - private static Dictionary GetUsedMeshColours(TRMesh[] meshes, List colours) + private static Dictionary GetUsedMeshColours(List meshes, List colours) { ISet colourIndices = GetAllColourIndices(meshes, true); @@ -47,7 +47,7 @@ private static Dictionary GetUsedMeshColours(TRMesh[] meshes, Li return usedColours; } - private static ISet GetAllColourIndices(TRMesh[] meshes, bool has16Bit) + private static ISet GetAllColourIndices(List meshes, bool has16Bit) { ISet colourIndices = new SortedSet(); foreach (TRMesh mesh in meshes) @@ -107,7 +107,7 @@ public static void Import(TR3Level level, TR3ModelDefinition definition) ReindexMeshTextures(definition.Meshes, indexMap, true); } - private static void ReindexMeshTextures(TRMesh[] meshes, Dictionary indexMap, bool has16Bit) + private static void ReindexMeshTextures(List meshes, Dictionary indexMap, bool has16Bit) { foreach (TRMesh mesh in meshes) { diff --git a/TRModelTransporter/Handlers/MeshTransportHandler.cs b/TRModelTransporter/Handlers/MeshTransportHandler.cs index d1fb18363..312d254e2 100644 --- a/TRModelTransporter/Handlers/MeshTransportHandler.cs +++ b/TRModelTransporter/Handlers/MeshTransportHandler.cs @@ -38,7 +38,7 @@ public static void Import(TR1Level level, TR1ModelDefinition definition) } } - for (int i = 0; i < definition.Meshes.Length; i++) + for (int i = 0; i < definition.Meshes.Count; i++) { int insertedIndex = TRMeshUtilities.InsertMesh(level, definition.Meshes[i]); if (i == 0) @@ -59,7 +59,7 @@ public static void Import(TR2Level level, TR2ModelDefinition definition) } } - for (int i = 0; i < definition.Meshes.Length; i++) + for (int i = 0; i < definition.Meshes.Count; i++) { int insertedIndex = TRMeshUtilities.InsertMesh(level, definition.Meshes[i]); if (i == 0) @@ -80,7 +80,7 @@ public static void Import(TR3Level level, TR3ModelDefinition definition) } } - for (int i = 0; i < definition.Meshes.Length; i++) + for (int i = 0; i < definition.Meshes.Count; i++) { int insertedIndex = TRMeshUtilities.InsertMesh(level, definition.Meshes[i]); if (i == 0) diff --git a/TRModelTransporter/Handlers/Sound/SoundUnpacker.cs b/TRModelTransporter/Handlers/Sound/SoundUnpacker.cs index 1b73355f0..a66ca0ef8 100644 --- a/TRModelTransporter/Handlers/Sound/SoundUnpacker.cs +++ b/TRModelTransporter/Handlers/Sound/SoundUnpacker.cs @@ -23,43 +23,34 @@ public void Unpack(TR1PackedSound sound, TR1Level level, bool retainInternalIndi { Dictionary sampleDataMap = ImportSamples(level, sound.Samples); GenerateSampleMap(level.SampleIndices, sound.SampleIndices, sampleDataMap); - List soundDetails = GenerateSoundDetailsMap(level.SoundDetails, sound.SoundDetails); + GenerateSoundDetailsMap(level.SoundDetails, sound.SoundDetails); GenerateSoundIndexMap(level, retainInternalIndices, sound.SoundMapIndices); - level.Samples = _samples.ToArray(); - level.NumSamples = (uint)_samples.Count; + level.Samples.Clear(); + level.Samples.AddRange(_samples); - level.SampleIndices = _sampleIndices.ToArray(); - level.NumSampleIndices = (uint)_sampleIndices.Count; - - level.SoundDetails = soundDetails.ToArray(); - level.NumSoundDetails = (uint)soundDetails.Count; + level.SampleIndices.Clear(); + level.SampleIndices.AddRange(_sampleIndices); } public void Unpack(TR2PackedSound sound, TR2Level level, bool retainInternalIndices = false) { GenerateSampleMap(level.SampleIndices, sound.SampleIndices); - List soundDetails = GenerateSoundDetailsMap(level.SoundDetails, sound.SoundDetails); + GenerateSoundDetailsMap(level.SoundDetails, sound.SoundDetails); GenerateSoundIndexMap(level, retainInternalIndices, sound.SoundMapIndices); - level.SampleIndices = _sampleIndices.ToArray(); - level.NumSampleIndices = (uint)_sampleIndices.Count; - - level.SoundDetails = soundDetails.ToArray(); - level.NumSoundDetails = (uint)soundDetails.Count; + level.SampleIndices.Clear(); + level.SampleIndices.AddRange(_sampleIndices); } public void Unpack(TR3PackedSound sound, TR3Level level, bool retainInternalIndices = false) { GenerateSampleMap(level.SampleIndices, sound.SampleIndices); - List soundDetails = GenerateSoundDetailsMap(level.SoundDetails, sound.SoundDetails); + GenerateSoundDetailsMap(level.SoundDetails, sound.SoundDetails); GenerateSoundIndexMap(level, retainInternalIndices, sound.SoundMapIndices); - level.SampleIndices = _sampleIndices.ToArray(); - level.NumSampleIndices = (uint)_sampleIndices.Count; - - level.SoundDetails = soundDetails.ToArray(); - level.NumSoundDetails = (uint)soundDetails.Count; + level.SampleIndices.Clear(); + level.SampleIndices.AddRange(_sampleIndices); } private Dictionary ImportSamples(TR1Level level, Dictionary sampleData) @@ -78,7 +69,7 @@ private Dictionary ImportSamples(TR1Level level, Dictionary packedIndices, Dictionary sampleKeyMap = null) + private void GenerateSampleMap(List sampleIndices, Dictionary packedIndices, Dictionary sampleKeyMap = null) { // Insert each required SampleIndex value, which are the values that point into // MAIN.SFX (or Samples[] in TR1). Note the first inserted index for updating @@ -121,11 +112,10 @@ private void GenerateSampleMap(uint[] sampleIndices, Dictionary } // TR1-2 - private List GenerateSoundDetailsMap(TRSoundDetails[] currentSoundDetails, Dictionary packedSoundDetails) + private void GenerateSoundDetailsMap(List soundDetails, Dictionary packedSoundDetails) { // Update each SoundDetails.Sample with the new SampleIndex values. Store // a map of old SoundsDetails indices to new. - List soundDetails = currentSoundDetails.ToList(); _soundDetailsMap = new Dictionary(); foreach (int soundDetailsIndex in packedSoundDetails.Keys) @@ -144,14 +134,11 @@ private List GenerateSoundDetailsMap(TRSoundDetails[] currentSou _soundDetailsMap[soundDetailsIndex] = currentIndex; } } - - return soundDetails; } // TR3+ - private List GenerateSoundDetailsMap(TR3SoundDetails[] currentSoundDetails, Dictionary packedSoundDetails) + private void GenerateSoundDetailsMap(List soundDetails, Dictionary packedSoundDetails) { - List soundDetails = currentSoundDetails.ToList(); _soundDetailsMap = new Dictionary(); foreach (int soundDetailsIndex in packedSoundDetails.Keys) @@ -170,8 +157,6 @@ private List GenerateSoundDetailsMap(TR3SoundDetails[] currentS _soundDetailsMap[soundDetailsIndex] = currentIndex; } } - - return soundDetails; } private static int FindSoundDetailsIndex(TRSoundDetails details, List allDetails) diff --git a/TRModelTransporter/Handlers/Sound/SoundUtilities.cs b/TRModelTransporter/Handlers/Sound/SoundUtilities.cs index b8d6dd9a9..634d65ecb 100644 --- a/TRModelTransporter/Handlers/Sound/SoundUtilities.cs +++ b/TRModelTransporter/Handlers/Sound/SoundUtilities.cs @@ -12,7 +12,7 @@ public static void ImportLevelSound(TR1Level baseLevel, TR1Level sourceLevel, sh SoundUtilities.ResortSoundIndices(baseLevel); } - public static TR1PackedSound BuildPackedSound(short[] soundMap, TRSoundDetails[] soundDetails, uint[] sampleIndices, byte[] wavSamples, short[] hardcodedSounds) + public static TR1PackedSound BuildPackedSound(short[] soundMap, List soundDetails, List sampleIndices, List wavSamples, short[] hardcodedSounds) { if (hardcodedSounds == null || hardcodedSounds.Length == 0) { @@ -39,7 +39,7 @@ public static TR1PackedSound BuildPackedSound(short[] soundMap, TRSoundDetails[] ushort sampleIndex = (ushort)(details.Sample + i); samples[i] = sampleIndices[sampleIndex]; - uint nextIndex = sampleIndex == sampleIndices.Length - 1 ? (uint)wavSamples.Length : sampleIndices[sampleIndex + 1]; + uint nextIndex = sampleIndex == sampleIndices.Count - 1 ? (uint)wavSamples.Count : sampleIndices[sampleIndex + 1]; packedSound.Samples[samples[i]] = AnimationUtilities.GetSample(samples[i], nextIndex, wavSamples); } @@ -58,7 +58,7 @@ public static TR1PackedSound BuildPackedSound(short[] soundMap, TRSoundDetails[] return packedSound; } - public static TR2PackedSound BuildPackedSound(short[] soundMap, TRSoundDetails[] soundDetails, uint[] sampleIndices, short[] hardcodedSounds) + public static TR2PackedSound BuildPackedSound(short[] soundMap, List soundDetails, List sampleIndices, short[] hardcodedSounds) { if (hardcodedSounds == null || hardcodedSounds.Length == 0) { @@ -100,7 +100,7 @@ public static TR2PackedSound BuildPackedSound(short[] soundMap, TRSoundDetails[] return packedSound; } - public static TR3PackedSound BuildPackedSound(short[] soundMap, TR3SoundDetails[] soundDetails, uint[] sampleIndices, short[] hardcodedSounds) + public static TR3PackedSound BuildPackedSound(short[] soundMap, List soundDetails, List sampleIndices, short[] hardcodedSounds) { if (hardcodedSounds == null || hardcodedSounds.Length == 0) { @@ -169,7 +169,7 @@ public static void ResortSoundIndices(TR1Level level) ushort samplePointerIndex = (ushort)(oldSample + i); uint oldSampleIndex = level.SampleIndices[oldSample + i]; - uint nextSampleIndex = samplePointerIndex == level.SampleIndices.Length - 1 ? (uint)level.Samples.Length : level.SampleIndices[samplePointerIndex + 1]; + uint nextSampleIndex = samplePointerIndex == level.SampleIndices.Count - 1 ? (uint)level.Samples.Count : level.SampleIndices[samplePointerIndex + 1]; newSampleIndices.Add((uint)newSamples.Count); newSamples.AddRange(AnimationUtilities.GetSample(oldSampleIndex, nextSampleIndex, level.Samples)); @@ -178,38 +178,37 @@ public static void ResortSoundIndices(TR1Level level) } level.SoundMap = newSoundMap.ToArray(); - level.SoundDetails = newSoundDetails.ToArray(); - level.SampleIndices = newSampleIndices.ToArray(); - level.Samples = newSamples.ToArray(); - level.NumSoundDetails = (uint)newSoundDetails.Count; - level.NumSampleIndices = (uint)newSampleIndices.Count; - level.NumSamples = (uint)newSamples.Count; + level.SoundDetails.Clear(); + level.SampleIndices.Clear(); + level.Samples.Clear(); + + level.SoundDetails.AddRange(newSoundDetails); + level.SampleIndices.AddRange(newSampleIndices); + level.Samples.AddRange(newSamples); } public static void ResortSoundIndices(TR2Level level) { - List sampleIndices = level.SampleIndices.ToList(); List soundDetails = level.SoundDetails.ToList(); List soundMap = level.SoundMap.ToList(); - ResortSoundIndices(sampleIndices, soundDetails, soundMap); + ResortSoundIndices(level.SampleIndices, soundDetails, soundMap); - level.SampleIndices = sampleIndices.ToArray(); - level.SoundDetails = soundDetails.ToArray(); + level.SoundDetails.Clear(); + level.SoundDetails.AddRange(soundDetails); level.SoundMap = soundMap.ToArray(); } public static void ResortSoundIndices(TR3Level level) { - List sampleIndices = level.SampleIndices.ToList(); List soundDetails = level.SoundDetails.ToList(); List soundMap = level.SoundMap.ToList(); - ResortSoundIndices(sampleIndices, soundDetails, soundMap); + ResortSoundIndices(level.SampleIndices, soundDetails, soundMap); - level.SampleIndices = sampleIndices.ToArray(); - level.SoundDetails = soundDetails.ToArray(); + level.SoundDetails.Clear(); + level.SoundDetails.AddRange(soundDetails); level.SoundMap = soundMap.ToArray(); } diff --git a/TRModelTransporter/Handlers/Textures/AbstractTextureImportHandler.cs b/TRModelTransporter/Handlers/Textures/AbstractTextureImportHandler.cs index 4dc764071..72c4a12c0 100644 --- a/TRModelTransporter/Handlers/Textures/AbstractTextureImportHandler.cs +++ b/TRModelTransporter/Handlers/Textures/AbstractTextureImportHandler.cs @@ -183,7 +183,7 @@ protected virtual void MergeObjectTextures() { // Add each ObjectTexture to the level and store a map of old index to new index. // Make use of any invalid texture first because we are limited to 2048 entries - List levelObjectTextures = GetExistingObjectTextures().ToList(); + List levelObjectTextures = GetExistingObjectTextures(); Queue reusableIndices = new(GetInvalidObjectTextureIndices()); Dictionary> indexMap = new(); @@ -225,9 +225,6 @@ protected virtual void MergeObjectTextures() } } - // Save the new textures in the level - WriteObjectTextures(levelObjectTextures); - // Change the definition's meshes so that the textured rectangles and triangles point // to the correct object texture. RemapMeshTextures(indexMap); @@ -235,8 +232,8 @@ protected virtual void MergeObjectTextures() protected virtual void MergeSpriteTextures() { - List levelSpriteTextures = GetExistingSpriteTextures().ToList(); - List levelSpriteSequences = GetExistingSpriteSequences().ToList(); + List levelSpriteTextures = GetExistingSpriteTextures(); + List levelSpriteSequences = GetExistingSpriteSequences(); foreach (D definition in _definitions) { @@ -267,29 +264,20 @@ protected virtual void MergeSpriteTextures() } } } - - WriteSpriteTextures(levelSpriteTextures); - WriteSpriteSequences(levelSpriteSequences); } - protected abstract IEnumerable GetExistingSpriteSequences(); + protected abstract List GetExistingSpriteSequences(); - protected abstract IEnumerable GetExistingSpriteTextures(); + protected abstract List GetExistingSpriteTextures(); protected abstract AbstractTexturePacker CreatePacker(); protected abstract void ProcessRemovals(AbstractTexturePacker packer); - protected abstract IEnumerable GetExistingObjectTextures(); + protected abstract List GetExistingObjectTextures(); protected abstract IEnumerable GetInvalidObjectTextureIndices(); - protected abstract void WriteObjectTextures(IEnumerable objectTextures); - - protected abstract void WriteSpriteTextures(IEnumerable spriteTextures); - - protected abstract void WriteSpriteSequences(IEnumerable spriteSequences); - protected abstract void RemapMeshTextures(Dictionary> indexMap); public abstract void ResetUnusedTextures(); diff --git a/TRModelTransporter/Handlers/Textures/TR1/TR1TextureExportHandler.cs b/TRModelTransporter/Handlers/Textures/TR1/TR1TextureExportHandler.cs index 33a00cbfc..19b0210d2 100644 --- a/TRModelTransporter/Handlers/Textures/TR1/TR1TextureExportHandler.cs +++ b/TRModelTransporter/Handlers/Textures/TR1/TR1TextureExportHandler.cs @@ -13,6 +13,6 @@ protected override AbstractTexturePacker CreatePacker() protected override TRSpriteSequence GetSprite(TR1Type entity) { - return _level.SpriteSequences.ToList().Find(s => s.SpriteID == (int)entity); + return _level.SpriteSequences.Find(s => s.SpriteID == (int)entity); } } diff --git a/TRModelTransporter/Handlers/Textures/TR1/TR1TextureImportHandler.cs b/TRModelTransporter/Handlers/Textures/TR1/TR1TextureImportHandler.cs index 626fc7608..73442d32e 100644 --- a/TRModelTransporter/Handlers/Textures/TR1/TR1TextureImportHandler.cs +++ b/TRModelTransporter/Handlers/Textures/TR1/TR1TextureImportHandler.cs @@ -10,10 +10,10 @@ public class TR1TextureImportHandler : AbstractTextureImportHandler GetExistingSpriteSequences() + protected override List GetExistingSpriteSequences() { // Allow replacing the Explosion sequence in Vilcabamba (it's there but empty) - List sequences = _level.SpriteSequences.ToList(); + List sequences = _level.SpriteSequences; TRSpriteSequence explosion = sequences.Find(s => s.SpriteID == (int)TR1Type.Explosion1_S_H); if (explosion != null && explosion.NegativeLength == -1) { @@ -22,21 +22,9 @@ protected override IEnumerable GetExistingSpriteSequences() return sequences; } - protected override void WriteSpriteSequences(IEnumerable spriteSequences) + protected override List GetExistingSpriteTextures() { - _level.SpriteSequences = spriteSequences.ToArray(); - _level.NumSpriteSequences = (uint)_level.SpriteSequences.Length; - } - - protected override IEnumerable GetExistingSpriteTextures() - { - return _level.SpriteTextures.ToList(); - } - - protected override void WriteSpriteTextures(IEnumerable spriteTextures) - { - _level.SpriteTextures = spriteTextures.ToArray(); - _level.NumSpriteTextures = (uint)_level.SpriteTextures.Length; + return _level.SpriteTextures; } protected override AbstractTexturePacker CreatePacker() @@ -92,9 +80,9 @@ private void RemoveUnusedSprites(AbstractTexturePacker packer packer.RemoveSpriteSegments(unusedItems); } - protected override IEnumerable GetExistingObjectTextures() + protected override List GetExistingObjectTextures() { - return _level.ObjectTextures.ToList(); + return _level.ObjectTextures; } protected override IEnumerable GetInvalidObjectTextureIndices() @@ -102,12 +90,6 @@ protected override IEnumerable GetInvalidObjectTextureIndices() return _level.GetInvalidObjectTextureIndices(); } - protected override void WriteObjectTextures(IEnumerable objectTextures) - { - _level.ObjectTextures = objectTextures.ToArray(); - _level.NumObjectTextures = (uint)_level.ObjectTextures.Length; - } - protected override void RemapMeshTextures(Dictionary> indexMap) { foreach (TR1ModelDefinition definition in indexMap.Keys) diff --git a/TRModelTransporter/Handlers/Textures/TR2/TR2TextureExportHandler.cs b/TRModelTransporter/Handlers/Textures/TR2/TR2TextureExportHandler.cs index e17941a0f..5a3d0493a 100644 --- a/TRModelTransporter/Handlers/Textures/TR2/TR2TextureExportHandler.cs +++ b/TRModelTransporter/Handlers/Textures/TR2/TR2TextureExportHandler.cs @@ -13,6 +13,6 @@ protected override AbstractTexturePacker CreatePacker() protected override TRSpriteSequence GetSprite(TR2Type entity) { - return _level.SpriteSequences.ToList().Find(s => s.SpriteID == (int)entity); + return _level.SpriteSequences.Find(s => s.SpriteID == (int)entity); } } diff --git a/TRModelTransporter/Handlers/Textures/TR2/TR2TextureImportHandler.cs b/TRModelTransporter/Handlers/Textures/TR2/TR2TextureImportHandler.cs index d71dcbd3a..f6b86da58 100644 --- a/TRModelTransporter/Handlers/Textures/TR2/TR2TextureImportHandler.cs +++ b/TRModelTransporter/Handlers/Textures/TR2/TR2TextureImportHandler.cs @@ -7,26 +7,14 @@ namespace TRModelTransporter.Handlers; public class TR2TextureImportHandler : AbstractTextureImportHandler { - protected override IEnumerable GetExistingSpriteSequences() + protected override List GetExistingSpriteSequences() { return _level.SpriteSequences; } - protected override void WriteSpriteSequences(IEnumerable spriteSequences) + protected override List GetExistingSpriteTextures() { - _level.SpriteSequences = spriteSequences.ToArray(); - _level.NumSpriteSequences = (uint)_level.SpriteSequences.Length; - } - - protected override IEnumerable GetExistingSpriteTextures() - { - return _level.SpriteTextures.ToList(); - } - - protected override void WriteSpriteTextures(IEnumerable spriteTextures) - { - _level.SpriteTextures = spriteTextures.ToArray(); - _level.NumSpriteTextures = (uint)_level.SpriteTextures.Length; + return _level.SpriteTextures; } protected override AbstractTexturePacker CreatePacker() @@ -81,30 +69,26 @@ private void ApplyFlamePatch() _level.Models.FindIndex(m => flameEnemies.Contains((TR2Type)m.ID)) != -1 ) { - List sequences = _level.SpriteSequences.ToList(); - int blastSequence = sequences.FindIndex(s => s.SpriteID == (int)TR2Type.FireBlast_S_H); - int grenadeSequence = sequences.FindIndex(s => s.SpriteID == (int)TR2Type.Explosion_S_H); + int blastSequence = _level.SpriteSequences.FindIndex(s => s.SpriteID == (int)TR2Type.FireBlast_S_H); + int grenadeSequence = _level.SpriteSequences.FindIndex(s => s.SpriteID == (int)TR2Type.Explosion_S_H); if (grenadeSequence != -1) { if (blastSequence == -1) { - TRSpriteSequence grenadeBlast = sequences[grenadeSequence]; - sequences.Add(new TRSpriteSequence + TRSpriteSequence grenadeBlast = _level.SpriteSequences[grenadeSequence]; + _level.SpriteSequences.Add(new TRSpriteSequence { SpriteID = (int)TR2Type.FireBlast_S_H, NegativeLength = grenadeBlast.NegativeLength, Offset = grenadeBlast.Offset }); - - _level.SpriteSequences = sequences.ToArray(); - _level.NumSpriteSequences++; } else { // #275 Rather than just pointing the blast sequence offset to the grenade sequence offset, // retain the original sprite texture objects but just remap where they point in the tiles. - for (int i = 0; i < sequences[grenadeSequence].NegativeLength * -1; i++) + for (int i = 0; i < _level.SpriteSequences[grenadeSequence].NegativeLength * -1; i++) { _level.SpriteTextures[_level.SpriteSequences[blastSequence].Offset + i] = _level.SpriteTextures[_level.SpriteSequences[grenadeSequence].Offset + i]; } @@ -139,9 +123,9 @@ private void RemoveUnusedSprites(AbstractTexturePacker packer packer.RemoveSpriteSegments(unusedItems); } - protected override IEnumerable GetExistingObjectTextures() + protected override List GetExistingObjectTextures() { - return _level.ObjectTextures.ToList(); + return _level.ObjectTextures; } protected override IEnumerable GetInvalidObjectTextureIndices() @@ -149,12 +133,6 @@ protected override IEnumerable GetInvalidObjectTextureIndices() return _level.GetInvalidObjectTextureIndices(); } - protected override void WriteObjectTextures(IEnumerable objectTextures) - { - _level.ObjectTextures = objectTextures.ToArray(); - _level.NumObjectTextures = (uint)_level.ObjectTextures.Length; - } - protected override void RemapMeshTextures(Dictionary> indexMap) { foreach (TR2ModelDefinition definition in indexMap.Keys) diff --git a/TRModelTransporter/Handlers/Textures/TR3/TR3TextureExportHandler.cs b/TRModelTransporter/Handlers/Textures/TR3/TR3TextureExportHandler.cs index 96dfe6092..910d0e651 100644 --- a/TRModelTransporter/Handlers/Textures/TR3/TR3TextureExportHandler.cs +++ b/TRModelTransporter/Handlers/Textures/TR3/TR3TextureExportHandler.cs @@ -12,6 +12,6 @@ protected override AbstractTexturePacker CreatePacker() } protected override TRSpriteSequence GetSprite(TR3Type entity) { - return _level.SpriteSequences.ToList().Find(s => s.SpriteID == (int)entity); + return _level.SpriteSequences.Find(s => s.SpriteID == (int)entity); } } diff --git a/TRModelTransporter/Handlers/Textures/TR3/TR3TextureImportHandler.cs b/TRModelTransporter/Handlers/Textures/TR3/TR3TextureImportHandler.cs index 1254296a3..c2dba0386 100644 --- a/TRModelTransporter/Handlers/Textures/TR3/TR3TextureImportHandler.cs +++ b/TRModelTransporter/Handlers/Textures/TR3/TR3TextureImportHandler.cs @@ -7,26 +7,14 @@ namespace TRModelTransporter.Handlers; public class TR3TextureImportHandler : AbstractTextureImportHandler { - protected override IEnumerable GetExistingSpriteSequences() + protected override List GetExistingSpriteSequences() { return _level.SpriteSequences; } - protected override void WriteSpriteSequences(IEnumerable spriteSequences) + protected override List GetExistingSpriteTextures() { - _level.SpriteSequences = spriteSequences.ToArray(); - _level.NumSpriteSequences = (uint)_level.SpriteSequences.Length; - } - - protected override IEnumerable GetExistingSpriteTextures() - { - return _level.SpriteTextures.ToList(); - } - - protected override void WriteSpriteTextures(IEnumerable spriteTextures) - { - _level.SpriteTextures = spriteTextures.ToArray(); - _level.NumSpriteTextures = (uint)_level.SpriteTextures.Length; + return _level.SpriteTextures; } protected override AbstractTexturePacker CreatePacker() @@ -80,9 +68,9 @@ private void RemoveUnusedSprites(AbstractTexturePacker packer packer.RemoveSpriteSegments(unusedItems); } - protected override IEnumerable GetExistingObjectTextures() + protected override List GetExistingObjectTextures() { - return _level.ObjectTextures.ToList(); + return _level.ObjectTextures; } protected override IEnumerable GetInvalidObjectTextureIndices() @@ -90,12 +78,6 @@ protected override IEnumerable GetInvalidObjectTextureIndices() return _level.GetInvalidObjectTextureIndices(); } - protected override void WriteObjectTextures(IEnumerable objectTextures) - { - _level.ObjectTextures = objectTextures.ToArray(); - _level.NumObjectTextures = (uint)_level.ObjectTextures.Length; - } - protected override void RemapMeshTextures(Dictionary> indexMap) { foreach (TR3ModelDefinition definition in indexMap.Keys) diff --git a/TRModelTransporter/Helpers/TRModelExtensions.cs b/TRModelTransporter/Helpers/TRModelExtensions.cs index d4920a990..427f3e13a 100644 --- a/TRModelTransporter/Helpers/TRModelExtensions.cs +++ b/TRModelTransporter/Helpers/TRModelExtensions.cs @@ -109,10 +109,10 @@ public static List GetInvalidObjectTextureIndices(this TR3Level level) return GetInvalidObjectTextureIndices(level.ObjectTextures); } - private static List GetInvalidObjectTextureIndices(TRObjectTexture[] objectTextures) + private static List GetInvalidObjectTextureIndices(List objectTextures) { List reusableIndices = new(); - for (int i = 0; i < objectTextures.Length; i++) + for (int i = 0; i < objectTextures.Count; i++) { if (!objectTextures[i].IsValid()) { @@ -162,13 +162,13 @@ public static void ReindexTextures(this TR2Level level, Dictionary ind List textures = level.ObjectTextures.ToList(); foreach (TRAnimatedTexture anim in level.AnimatedTextures) { - for (int i = 0; i < anim.Textures.Length; i++) + for (int i = 0; i < anim.Textures.Count; i++) { anim.Textures[i] = ConvertTextureReference(anim.Textures[i], indexMap, defaultToOriginal); } ushort previousIndex = anim.Textures[0]; - for (int i = 1; i < anim.Textures.Length; i++) + for (int i = 1; i < anim.Textures.Count; i++) { if (anim.Textures[i] == previousIndex && textures.Count < 2048) { @@ -179,10 +179,10 @@ public static void ReindexTextures(this TR2Level level, Dictionary ind } } - if (textures.Count > level.NumObjectTextures) + if (textures.Count > level.ObjectTextures.Count) { - level.ObjectTextures = textures.ToArray(); - level.NumObjectTextures = (uint)textures.Count; + level.ObjectTextures.Clear(); + level.ObjectTextures.AddRange(textures); } } @@ -220,13 +220,13 @@ public static void ReindexTextures(this TR3Level level, Dictionary ind List textures = level.ObjectTextures.ToList(); foreach (TRAnimatedTexture anim in level.AnimatedTextures) { - for (int i = 0; i < anim.Textures.Length; i++) + for (int i = 0; i < anim.Textures.Count; i++) { anim.Textures[i] = ConvertTextureReference(anim.Textures[i], indexMap, defaultToOriginal); } ushort previousIndex = anim.Textures[0]; - for (int i = 1; i < anim.Textures.Length; i++) + for (int i = 1; i < anim.Textures.Count; i++) { if (anim.Textures[i] == previousIndex && textures.Count < 2048) { @@ -237,10 +237,10 @@ public static void ReindexTextures(this TR3Level level, Dictionary ind } } - if (textures.Count > level.NumObjectTextures) + if (textures.Count > level.ObjectTextures.Count) { - level.ObjectTextures = textures.ToArray(); - level.NumObjectTextures = (uint)textures.Count; + level.ObjectTextures.Clear(); + level.ObjectTextures.AddRange(textures); } } @@ -254,7 +254,7 @@ private static ushort ConvertTextureReference(ushort textureReference, Dictionar return defaultToOriginal ? textureReference : (ushort)0; } - public static string ComputeSkeletonHash(this TRMesh[] meshes) + public static string ComputeSkeletonHash(this IEnumerable meshes) { using MemoryStream ms = new(); using BinaryWriter writer = new(ms); diff --git a/TRModelTransporter/Model/Definitions/TR1ModelDefinition.cs b/TRModelTransporter/Model/Definitions/TR1ModelDefinition.cs index dfad5876e..6fbe389ae 100644 --- a/TRModelTransporter/Model/Definitions/TR1ModelDefinition.cs +++ b/TRModelTransporter/Model/Definitions/TR1ModelDefinition.cs @@ -12,7 +12,7 @@ public class TR1ModelDefinition : AbstractTRModelDefinition public TRCinematicFrame[] CinematicFrames { get; set; } public Dictionary Colours { get; set; } public TR1PackedSound HardcodedSound { get; set; } - public TRMesh[] Meshes { get; set; } + public List Meshes { get; set; } public TRMeshTreeNode[] MeshTrees { get; set; } public TRModel Model { get; set; } diff --git a/TRModelTransporter/Model/Definitions/TR2ModelDefinition.cs b/TRModelTransporter/Model/Definitions/TR2ModelDefinition.cs index e639a1a57..5a3c4a7c9 100644 --- a/TRModelTransporter/Model/Definitions/TR2ModelDefinition.cs +++ b/TRModelTransporter/Model/Definitions/TR2ModelDefinition.cs @@ -12,7 +12,7 @@ public class TR2ModelDefinition : AbstractTRModelDefinition public TRCinematicFrame[] CinematicFrames { get; set; } public Dictionary Colours { get; set; } public TR2PackedSound HardcodedSound { get; set; } - public TRMesh[] Meshes { get; set; } + public List Meshes { get; set; } public TRMeshTreeNode[] MeshTrees { get; set; } public TRModel Model { get; set; } diff --git a/TRModelTransporter/Model/Definitions/TR3ModelDefinition.cs b/TRModelTransporter/Model/Definitions/TR3ModelDefinition.cs index 73ac3ec4c..893d0ecae 100644 --- a/TRModelTransporter/Model/Definitions/TR3ModelDefinition.cs +++ b/TRModelTransporter/Model/Definitions/TR3ModelDefinition.cs @@ -12,7 +12,7 @@ public class TR3ModelDefinition : AbstractTRModelDefinition public TRCinematicFrame[] CinematicFrames { get; set; } public Dictionary Colours { get; set; } public TR3PackedSound HardcodedSound { get; set; } - public TRMesh[] Meshes { get; set; } + public List Meshes { get; set; } public TRMeshTreeNode[] MeshTrees { get; set; } public TRModel Model { get; set; } diff --git a/TRModelTransporter/Packing/AbstractTexturePacker.cs b/TRModelTransporter/Packing/AbstractTexturePacker.cs index cda765904..76ac0fc6f 100644 --- a/TRModelTransporter/Packing/AbstractTexturePacker.cs +++ b/TRModelTransporter/Packing/AbstractTexturePacker.cs @@ -93,7 +93,7 @@ public PackingResult Pack(bool commitToLevel) public Dictionary> GetModelSegments(E modelEntity) { Dictionary> segmentMap = new(); - TRMesh[] meshes = GetModelMeshes(modelEntity); + List meshes = GetModelMeshes(modelEntity); if (meshes != null) { IEnumerable indices = GetMeshTextureIndices(meshes); @@ -125,7 +125,7 @@ public Dictionary> GetObjectTextureSegme return segmentMap; } - protected abstract TRMesh[] GetModelMeshes(E modelEntity); + protected abstract List GetModelMeshes(E modelEntity); public Dictionary> GetSpriteSegments(E entity) { @@ -169,7 +169,7 @@ public Dictionary> GetSpriteTextureSegme protected abstract TRSpriteSequence GetSpriteSequence(E entity); - protected IEnumerable GetMeshTextureIndices(TRMesh[] meshes) + protected IEnumerable GetMeshTextureIndices(List meshes) { ISet textureIndices = new SortedSet(); foreach (TRMesh mesh in meshes) diff --git a/TRModelTransporter/Packing/Types/TR1TexturePacker.cs b/TRModelTransporter/Packing/Types/TR1TexturePacker.cs index 3b5c163c1..adda6c0ec 100644 --- a/TRModelTransporter/Packing/Types/TR1TexturePacker.cs +++ b/TRModelTransporter/Packing/Types/TR1TexturePacker.cs @@ -22,8 +22,8 @@ public TR1TexturePacker(TR1Level level, ITextureClassifier classifier = null) protected override List LoadObjectTextures() { - List textures = new((int)Level.NumObjectTextures); - for (int i = 0; i < Level.NumObjectTextures; i++) + List textures = new(Level.ObjectTextures.Count); + for (int i = 0; i < Level.ObjectTextures.Count; i++) { TRObjectTexture texture = Level.ObjectTextures[i]; if (texture.IsValid()) @@ -41,8 +41,8 @@ protected override List LoadObjectTextures() protected override List LoadSpriteTextures() { - List textures = new((int)Level.NumSpriteTextures); - for (int i = 0; i < Level.NumSpriteTextures; i++) + List textures = new(Level.SpriteTextures.Count); + for (int i = 0; i < Level.SpriteTextures.Count; i++) { TRSpriteTexture texture = Level.SpriteTextures[i]; if (texture.IsValid()) @@ -58,14 +58,14 @@ protected override List LoadSpriteTextures() return textures; } - protected override TRMesh[] GetModelMeshes(TR1Type modelEntity) + protected override List GetModelMeshes(TR1Type modelEntity) { return TRMeshUtilities.GetModelMeshes(Level, modelEntity); } protected override TRSpriteSequence GetSpriteSequence(TR1Type entity) { - return Level.SpriteSequences.ToList().Find(s => s.SpriteID == (int)entity); + return Level.SpriteSequences.Find(s => s.SpriteID == (int)entity); } protected override IEnumerable GetAllModelTypes() diff --git a/TRModelTransporter/Packing/Types/TR2TexturePacker.cs b/TRModelTransporter/Packing/Types/TR2TexturePacker.cs index 36ddebd8f..8d639866e 100644 --- a/TRModelTransporter/Packing/Types/TR2TexturePacker.cs +++ b/TRModelTransporter/Packing/Types/TR2TexturePacker.cs @@ -19,8 +19,8 @@ public TR2TexturePacker(TR2Level level, ITextureClassifier classifier = null) protected override List LoadObjectTextures() { - List textures = new((int)Level.NumObjectTextures); - for (int i = 0; i < Level.NumObjectTextures; i++) + List textures = new(Level.ObjectTextures.Count); + for (int i = 0; i < Level.ObjectTextures.Count; i++) { TRObjectTexture texture = Level.ObjectTextures[i]; if (texture.IsValid()) @@ -38,8 +38,8 @@ protected override List LoadObjectTextures() protected override List LoadSpriteTextures() { - List textures = new((int)Level.NumSpriteTextures); - for (int i = 0; i < Level.NumSpriteTextures; i++) + List textures = new(Level.SpriteTextures.Count); + for (int i = 0; i < Level.SpriteTextures.Count; i++) { TRSpriteTexture texture = Level.SpriteTextures[i]; if (texture.IsValid()) @@ -55,14 +55,14 @@ protected override List LoadSpriteTextures() return textures; } - protected override TRMesh[] GetModelMeshes(TR2Type modelEntity) + protected override List GetModelMeshes(TR2Type modelEntity) { return TRMeshUtilities.GetModelMeshes(Level, modelEntity); } protected override TRSpriteSequence GetSpriteSequence(TR2Type entity) { - return Level.SpriteSequences.ToList().Find(s => s.SpriteID == (int)entity); + return Level.SpriteSequences.Find(s => s.SpriteID == (int)entity); } protected override IEnumerable GetAllModelTypes() diff --git a/TRModelTransporter/Packing/Types/TR3TexturePacker.cs b/TRModelTransporter/Packing/Types/TR3TexturePacker.cs index bd69910b6..e03ef19a4 100644 --- a/TRModelTransporter/Packing/Types/TR3TexturePacker.cs +++ b/TRModelTransporter/Packing/Types/TR3TexturePacker.cs @@ -19,8 +19,8 @@ public TR3TexturePacker(TR3Level level, ITextureClassifier classifier = null) protected override List LoadObjectTextures() { - List textures = new((int)Level.NumObjectTextures); - for (int i = 0; i < Level.NumObjectTextures; i++) + List textures = new(Level.ObjectTextures.Count); + for (int i = 0; i < Level.ObjectTextures.Count; i++) { TRObjectTexture texture = Level.ObjectTextures[i]; if (texture.IsValid()) @@ -38,8 +38,8 @@ protected override List LoadObjectTextures() protected override List LoadSpriteTextures() { - List textures = new((int)Level.NumSpriteTextures); - for (int i = 0; i < Level.NumSpriteTextures; i++) + List textures = new(Level.SpriteTextures.Count); + for (int i = 0; i < Level.SpriteTextures.Count; i++) { TRSpriteTexture texture = Level.SpriteTextures[i]; if (texture.IsValid()) @@ -55,14 +55,14 @@ protected override List LoadSpriteTextures() return textures; } - protected override TRMesh[] GetModelMeshes(TR3Type modelEntity) + protected override List GetModelMeshes(TR3Type modelEntity) { return TRMeshUtilities.GetModelMeshes(Level, modelEntity); } protected override TRSpriteSequence GetSpriteSequence(TR3Type entity) { - return Level.SpriteSequences.ToList().Find(s => s.SpriteID == (int)entity); + return Level.SpriteSequences.Find(s => s.SpriteID == (int)entity); } protected override IEnumerable GetAllModelTypes() diff --git a/TRRandomizerCore/Processors/TR2/TR2ModelAdjuster.cs b/TRRandomizerCore/Processors/TR2/TR2ModelAdjuster.cs index 98965a120..4143a12f0 100644 --- a/TRRandomizerCore/Processors/TR2/TR2ModelAdjuster.cs +++ b/TRRandomizerCore/Processors/TR2/TR2ModelAdjuster.cs @@ -42,14 +42,11 @@ private void AdjustInstanceModels() return; } - List models = _levelInstance.Data.Models.ToList(); - List sprites = _levelInstance.Data.SpriteSequences.ToList(); - // Point the old models to the new ones, and any matching entities that are instances // of the old model, should also point to the new model type. foreach (TR2Type oldEntity in _modelRemap.Keys) { - TRModel model = models.Find(m => m.ID == (short)oldEntity); + TRModel model = _levelInstance.Data.Models.Find(m => m.ID == (short)oldEntity); if (model != null) { model.ID = (uint)_modelRemap[oldEntity]; @@ -65,7 +62,7 @@ private void AdjustInstanceModels() // Repeat for sprites foreach (TR2Type oldEntity in _spriteRemap.Keys) { - TRSpriteSequence sprite = sprites.Find(s => s.SpriteID == (short)oldEntity); + TRSpriteSequence sprite = _levelInstance.Data.SpriteSequences.Find(s => s.SpriteID == (short)oldEntity); if (sprite != null) { sprite.SpriteID = (short)_spriteRemap[oldEntity]; diff --git a/TRRandomizerCore/Processors/TR3/TR3SequenceProcessor.cs b/TRRandomizerCore/Processors/TR3/TR3SequenceProcessor.cs index f4d855f77..35b17f9a3 100644 --- a/TRRandomizerCore/Processors/TR3/TR3SequenceProcessor.cs +++ b/TRRandomizerCore/Processors/TR3/TR3SequenceProcessor.cs @@ -246,11 +246,10 @@ private static void AmendAntarctica(TR3CombinedLevel level) private void ImportArtefactMenuModels(TR3CombinedLevel level) { - List models = level.Data.Models.ToList(); List imports = new(); foreach (TR3Type artefactMenuModel in TR3TypeUtilities.GetArtefactMenuModels()) { - if (models.Find(m => m.ID == (uint)artefactMenuModel) == null) + if (level.Data.Models.Find(m => m.ID == (uint)artefactMenuModel) == null) { imports.Add(artefactMenuModel); } diff --git a/TRRandomizerCore/Randomizers/TR1/TR1AudioRandomizer.cs b/TRRandomizerCore/Randomizers/TR1/TR1AudioRandomizer.cs index b0e680fa9..44fef9726 100644 --- a/TRRandomizerCore/Randomizers/TR1/TR1AudioRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR1/TR1AudioRandomizer.cs @@ -158,7 +158,7 @@ private void RandomizeSoundEffects(TR1CombinedLevel level) ISet usedSamples = new HashSet(); // Replace each sample but be sure to avoid duplicates - for (int i = 0; i < level.Data.NumSampleIndices; i++) + for (int i = 0; i < level.Data.SampleIndices.Count; i++) { byte[] sample; string id; @@ -177,9 +177,10 @@ private void RandomizeSoundEffects(TR1CombinedLevel level) newSamples.AddRange(sample); } - level.Data.SampleIndices = newSampleIndices.ToArray(); - level.Data.Samples = newSamples.ToArray(); - level.Data.NumSamples = (uint)newSamples.Count; + level.Data.SampleIndices.Clear(); + level.Data.SampleIndices.AddRange(newSampleIndices); + level.Data.Samples.Clear(); + level.Data.Samples.AddRange(newSamples); } else { @@ -259,41 +260,28 @@ private static short ImportSoundEffect(TR1Level level, TR1SFXDefinition definiti // This may result in duplicate WAV data if a sound definition is imported more than // once, but ResortSoundIndices will tidy the data such that only the required WAV // file is retained in the end. - List levelSamples = level.Samples.ToList(); - List levelSampleIndices = level.SampleIndices.ToList(); - - foreach (byte[] sample in definition.SoundData.Samples.Values) - { - levelSampleIndices.Add((uint)levelSamples.Count); - levelSamples.AddRange(sample); - } - newDetails = new TRSoundDetails { Chance = defDetails.Chance, Characteristics = defDetails.Characteristics, - Sample = (ushort)level.SampleIndices.Length, + Sample = (ushort)level.SampleIndices.Count, Volume = defDetails.Volume }; + foreach (byte[] sample in definition.SoundData.Samples.Values) + { + level.SampleIndices.Add((uint)level.Samples.Count); + level.Samples.AddRange(sample); + } + if (category == TRSFXGeneralCategory.StandardWeaponFiring || category == TRSFXGeneralCategory.FastWeaponFiring) { newDetails.LoopingMode = 1; // OneShotRewound } - level.Samples = levelSamples.ToArray(); - level.NumSamples = (uint)levelSamples.Count; - - level.SampleIndices = levelSampleIndices.ToArray(); - level.NumSampleIndices = (uint)levelSampleIndices.Count; - - List levelSoundDetails = level.SoundDetails.ToList(); - levelSoundDetails.Add(newDetails); - level.SoundDetails = levelSoundDetails.ToArray(); - level.NumSoundDetails++; - - return (short)(level.NumSoundDetails - 1); + level.SoundDetails.Add(newDetails); + return (short)(level.SoundDetails.Count - 1); } private void ImportSpeechSFX(TR1CombinedLevel level) diff --git a/TRRandomizerCore/Randomizers/TR1/TR1EnemyRandomizer.cs b/TRRandomizerCore/Randomizers/TR1/TR1EnemyRandomizer.cs index 22fb9fa7f..b4d1c340f 100644 --- a/TRRandomizerCore/Randomizers/TR1/TR1EnemyRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR1/TR1EnemyRandomizer.cs @@ -879,7 +879,7 @@ private static void AmendToQLarson(TR1CombinedLevel level) .ForEach(e => e.TypeID = TR1Type.Raptor); // Make the scion invisible. - TRMesh[] larsonMeshes = TRMeshUtilities.GetModelMeshes(level.Data, larsonModel); + List larsonMeshes = TRMeshUtilities.GetModelMeshes(level.Data, larsonModel); MeshEditor editor = new(); foreach (TRMesh mesh in larsonMeshes) { @@ -961,7 +961,7 @@ private void AmendAtlanteanModels(TR1CombinedLevel level, EnemyRandomizationColl // If we're using flying mummies, add a chance that they'll have proper wings if (enemies.Available.Contains(TR1Type.BandagedFlyer) && _generator.NextDouble() < 0.5) { - TRMesh[] meshes = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.FlyingAtlantean); + List meshes = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.FlyingAtlantean); ushort bandageTexture = meshes[1].TexturedRectangles[3].Texture; for (int i = 15; i < 21; i++) { @@ -1141,19 +1141,19 @@ private void RandomizeMeshes(TR1CombinedLevel level, List availableEnem [TR1Type.CassettePlayer_M_H] = 1 }; - TRMesh[] scion = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.ScionPiece4_S_P); + List scion = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.ScionPiece4_S_P); List replacementKeys = scionSwaps.Keys.ToList(); TR1Type replacement = replacementKeys[_generator.Next(0, replacementKeys.Count)]; - TRMesh[] replacementMeshes = TRMeshUtilities.GetModelMeshes(level.Data, replacement); + List replacementMeshes = TRMeshUtilities.GetModelMeshes(level.Data, replacement); int colRadius = scion[0].CollRadius; TRMeshUtilities.DuplicateMesh(level.Data, scion[0], replacementMeshes[scionSwaps[replacement]]); scion[0].CollRadius = colRadius; // Retain original as Lara may need to shoot it // Cutscene head swaps - TRMesh[] lara = TRMeshUtilities.GetModelMeshes(level.CutSceneLevel.Data, TR1Type.CutsceneActor1); - TRMesh[] natla = TRMeshUtilities.GetModelMeshes(level.CutSceneLevel.Data, TR1Type.CutsceneActor3); - TRMesh[] pierre = TRMeshUtilities.GetModelMeshes(level.CutSceneLevel.Data, TR1Type.Pierre); + List lara = TRMeshUtilities.GetModelMeshes(level.CutSceneLevel.Data, TR1Type.CutsceneActor1); + List natla = TRMeshUtilities.GetModelMeshes(level.CutSceneLevel.Data, TR1Type.CutsceneActor3); + List pierre = TRMeshUtilities.GetModelMeshes(level.CutSceneLevel.Data, TR1Type.Pierre); switch (_generator.Next(0, 6)) { @@ -1191,7 +1191,7 @@ private void RandomizeMeshes(TR1CombinedLevel level, List availableEnem if (availableEnemies.Contains(TR1Type.Adam) && _generator.NextDouble() < 0.4) { // Replace Adam's head with a much larger version of Natla's, Larson's or normal/angry Lara's. - TRMesh[] adam = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.Adam); + List adam = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.Adam); TRMesh replacement; if (availableEnemies.Contains(TR1Type.Natla) && _generator.NextDouble() < 0.5) { @@ -1239,9 +1239,9 @@ private void RandomizeMeshes(TR1CombinedLevel level, List availableEnem if (availableEnemies.Contains(TR1Type.Pierre) && _generator.NextDouble() < 0.25) { // Replace Pierre's head with a slightly bigger version of Lara's (either angry Lara or normal Lara) - TRMesh[] pierre = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.Pierre); - TRMesh[] lara = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.Lara); - TRMesh[] laraUziAnim = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.LaraUziAnimation_H); + List pierre = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.Pierre); + List lara = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.Lara); + List laraUziAnim = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.LaraUziAnimation_H); TRMeshUtilities.DuplicateMesh(level.Data, pierre[8], MeshEditor.CloneMesh(_generator.NextDouble() < 0.5 ? laraUziAnim[14] : lara[14])); foreach (TRVertex vertex in pierre[8].Vertices) diff --git a/TRRandomizerCore/Randomizers/TR1/TR1ItemRandomizer.cs b/TRRandomizerCore/Randomizers/TR1/TR1ItemRandomizer.cs index cd02b5125..c425d3068 100644 --- a/TRRandomizerCore/Randomizers/TR1/TR1ItemRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR1/TR1ItemRandomizer.cs @@ -523,12 +523,10 @@ private void RandomizeSprites() } } - _spriteRandomizer.Sequences = _levelInstance.Data.SpriteSequences.ToList(); - _spriteRandomizer.Textures = _levelInstance.Data.SpriteTextures.ToList(); + _spriteRandomizer.Sequences = _levelInstance.Data.SpriteSequences; + _spriteRandomizer.Textures = _levelInstance.Data.SpriteTextures; _spriteRandomizer.Randomize(_generator); - - _levelInstance.Data.SpriteTextures = _spriteRandomizer.Textures.ToArray(); } private static bool IsSecretItem(TR1Entity entity, int entityIndex, TR1Level level, FDControl floorData) diff --git a/TRRandomizerCore/Randomizers/TR1/TR1OutfitRandomizer.cs b/TRRandomizerCore/Randomizers/TR1/TR1OutfitRandomizer.cs index dd4db415f..4db2d5686 100644 --- a/TRRandomizerCore/Randomizers/TR1/TR1OutfitRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR1/TR1OutfitRandomizer.cs @@ -327,7 +327,7 @@ private void ImportBraid(TR1CombinedLevel level) } // Find the texture references for the plain parts of imported hair - TRMesh[] ponytailMeshes = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.LaraPonytail_H_U); + List ponytailMeshes = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.LaraPonytail_H_U); ushort plainHairQuad = ponytailMeshes[0].TexturedRectangles[0].Texture; ushort plainHairTri = ponytailMeshes[5].TexturedTriangles[0].Texture; @@ -343,8 +343,8 @@ private void ImportBraid(TR1CombinedLevel level) foreach (TR1Type laraType in headAmendments.Keys) { - TRMesh[] meshes = TRMeshUtilities.GetModelMeshes(level.Data, laraType); - if (meshes == null || meshes.Length < 15) + List meshes = TRMeshUtilities.GetModelMeshes(level.Data, laraType); + if (meshes == null || meshes.Count < 15) { continue; } @@ -380,7 +380,7 @@ private static void CreateGoldenBraid(TR1CombinedLevel level) ushort goldPalette = goldenHips.ColouredRectangles[0].Texture; TRModel ponytail = level.Data.Models.Find(m => m.ID == (uint)TR1Type.LaraPonytail_H_U); - TRMesh[] ponytailMeshes = TRMeshUtilities.GetModelMeshes(level.Data, ponytail); + List ponytailMeshes = TRMeshUtilities.GetModelMeshes(level.Data, ponytail); MeshEditor editor = new(); foreach (TRMesh mesh in ponytailMeshes) { @@ -397,7 +397,7 @@ private static void HideEntities(TR1CombinedLevel level, IEnumerable en MeshEditor editor = new(); foreach (TR1Type ent in entities) { - TRMesh[] meshes = TRMeshUtilities.GetModelMeshes(level.Data, ent); + List meshes = TRMeshUtilities.GetModelMeshes(level.Data, ent); if (meshes != null) { foreach (TRMesh mesh in meshes) @@ -494,12 +494,12 @@ private void ConvertToGymOutfit(TR1CombinedLevel level) return; } - TRMesh[] lara = TRMeshUtilities.GetModelMeshes(level.Data, level.IsCutScene ? TR1Type.CutsceneActor1 : TR1Type.Lara); - TRMesh[] laraPistol = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.LaraPistolAnim_H); - TRMesh[] laraShotgun = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.LaraShotgunAnim_H); - TRMesh[] laraMagnums = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.LaraMagnumAnim_H); - TRMesh[] laraUzis = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.LaraUziAnimation_H); - TRMesh[] laraMisc = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.LaraMiscAnim_H); + List lara = TRMeshUtilities.GetModelMeshes(level.Data, level.IsCutScene ? TR1Type.CutsceneActor1 : TR1Type.Lara); + List laraPistol = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.LaraPistolAnim_H); + List laraShotgun = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.LaraShotgunAnim_H); + List laraMagnums = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.LaraMagnumAnim_H); + List laraUzis = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.LaraUziAnimation_H); + List laraMisc = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.LaraMiscAnim_H); // Basic meshes to take from LaraMiscAnim. We don't replace Lara's gloves // or thighs (at this stage - handled below with gun swaps). @@ -592,7 +592,7 @@ private void ConvertToGymOutfit(TR1CombinedLevel level) byte[] replacementSfx = _outer._barefootSfx[soundID][i]; for (int j = 0; j < replacementSfx.Length; j++) { - level.Data.Samples[samplePointer + j] = replacementSfx[j]; + level.Data.Samples[(int)samplePointer + j] = replacementSfx[j]; } } } @@ -616,9 +616,9 @@ private void ConvertToPartialGymOutfit(TR1CombinedLevel level) return; } - TRMesh[] lara = TRMeshUtilities.GetModelMeshes(level.Data, level.IsCutScene ? TR1Type.CutsceneActor1 : TR1Type.Lara); - TRMesh[] laraShotgun = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.LaraShotgunAnim_H); - TRMesh[] laraMisc = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.LaraMiscAnim_H); + List lara = TRMeshUtilities.GetModelMeshes(level.Data, level.IsCutScene ? TR1Type.CutsceneActor1 : TR1Type.Lara); + List laraShotgun = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.LaraShotgunAnim_H); + List laraMisc = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.LaraMiscAnim_H); // Just the torso TRMeshUtilities.DuplicateMesh(level.Data, lara[7], laraMisc[7]); @@ -675,7 +675,7 @@ private void ConvertToPartialGymOutfit(TR1CombinedLevel level) } } - private static void CreateGoldGymOutfit(TR1CombinedLevel level, TRMesh[] laraMisc, Func cloneBaseFunc) + private static void CreateGoldGymOutfit(TR1CombinedLevel level, List laraMisc, Func cloneBaseFunc) { if (!level.Data.Entities.Any(e => e.TypeID == TR1Type.MidasHand_N)) { @@ -686,7 +686,7 @@ private static void CreateGoldGymOutfit(TR1CombinedLevel level, TRMesh[] laraMis .FindClosest(_midasGoldColour, 1); MeshEditor editor = new(); - for (int i = 0; i < laraMisc.Length; i++) + for (int i = 0; i < laraMisc.Count; i++) { TRMesh mesh = laraMisc[i]; TRMeshUtilities.DuplicateMesh(level.Data, mesh, MeshEditor.CloneMesh(cloneBaseFunc(i))); @@ -721,7 +721,7 @@ private bool ImportGymOutfit(TR1CombinedLevel level) if (existingModel != null) { // If we already have the gym outfit available, we're done. - TRMesh[] meshes = TRMeshUtilities.GetModelMeshes(level.Data, existingModel); + List meshes = TRMeshUtilities.GetModelMeshes(level.Data, existingModel); if (meshes.ComputeSkeletonHash() == _gymOutfitHash) { return true; @@ -854,9 +854,9 @@ private static void CopyMeshParts(TR1Level level, MeshCopyData data) private void ConvertToMauledOutfit(TR1CombinedLevel level) { - TRMesh[] lara = TRMeshUtilities.GetModelMeshes(level.Data, level.IsCutScene ? TR1Type.CutsceneActor1 : TR1Type.Lara); - TRMesh[] laraShotgun = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.LaraShotgunAnim_H); - TRMesh[] laraMisc = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.LaraMiscAnim_H); + List lara = TRMeshUtilities.GetModelMeshes(level.Data, level.IsCutScene ? TR1Type.CutsceneActor1 : TR1Type.Lara); + List laraShotgun = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.LaraShotgunAnim_H); + List laraMisc = TRMeshUtilities.GetModelMeshes(level.Data, TR1Type.LaraMiscAnim_H); if (level.Is(TR1LevelNames.QUALOPEC_CUT)) { @@ -912,7 +912,7 @@ private void ConvertToMauledOutfit(TR1CombinedLevel level) }; foreach (TR1Type gunAnimType in gunAnims) { - TRMesh[] meshes = TRMeshUtilities.GetModelMeshes(level.Data, gunAnimType); + List meshes = TRMeshUtilities.GetModelMeshes(level.Data, gunAnimType); if (meshes == null) continue; diff --git a/TRRandomizerCore/Randomizers/TR1/TR1SecretRandomizer.cs b/TRRandomizerCore/Randomizers/TR1/TR1SecretRandomizer.cs index b188251d8..e99871786 100644 --- a/TRRandomizerCore/Randomizers/TR1/TR1SecretRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR1/TR1SecretRandomizer.cs @@ -867,8 +867,6 @@ protected override void ProcessImpl() importer.Import(); - List sequences = level.Data.SpriteSequences.ToList(); - // Redefine the artefacts as puzzle models foreach (TR1Type secretModelType in allocation.ImportModels) { @@ -878,7 +876,7 @@ protected override void ProcessImpl() TR1Type puzzlePickupType = _modelReplacements[puzzleModelType]; level.Data.Models.Find(m => m.ID == (uint)secretModelType).ID = (uint)puzzleModelType; - sequences.Find(s => s.SpriteID == (int)secretPickupType).SpriteID = (int)puzzlePickupType; + level.Data.SpriteSequences.Find(s => s.SpriteID == (int)secretPickupType).SpriteID = (int)puzzlePickupType; if (secretModelType == TR1Type.SecretScion_M_H && _outer.Are3DPickupsEnabled()) { diff --git a/TRRandomizerCore/Randomizers/TR2/TR2AudioRandomizer.cs b/TRRandomizerCore/Randomizers/TR2/TR2AudioRandomizer.cs index 6c17b3515..37ce02f4f 100644 --- a/TRRandomizerCore/Randomizers/TR2/TR2AudioRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR2/TR2AudioRandomizer.cs @@ -211,12 +211,13 @@ private void RandomizeSoundEffects(TR2CombinedLevel level) if (IsUncontrolledLevel(level.Script)) { // Choose a random sample for each current entry and replace the entire index list. - ISet indices = new HashSet(); - while (indices.Count < level.Data.NumSampleIndices) + HashSet indices = new(); + while (indices.Count < level.Data.SampleIndices.Count) { indices.Add((uint)_generator.Next(0, _maxSample + 1)); } - level.Data.SampleIndices = indices.ToArray(); + level.Data.SampleIndices.Clear(); + level.Data.SampleIndices.AddRange(indices); } else { @@ -280,29 +281,18 @@ private static short ImportSoundEffect(TR2Level level, TRSFXDefinition levelSamples = level.SampleIndices.ToList(); List levelSoundDetails = level.SoundDetails.ToList(); uint minSample = definition.SampleIndices.Min(); - if (levelSamples.Contains(minSample)) + if (level.SampleIndices.Contains(minSample)) { - // This index is already defined, so locate the TRSoundDetails that references it - // and return its index. - return (short)levelSoundDetails.FindIndex(d => levelSamples[d.Sample] == minSample); + return (short)levelSoundDetails.FindIndex(d => level.SampleIndices[d.Sample] == minSample); } - // Otherwise, we need to import the samples, create a sound details object to - // point to the first sample, and then return the new index. Make sure the - // samples are sorted first. - ushort newSampleIndex = (ushort)levelSamples.Count; - List sortedSamples = new(definition.SampleIndices); - sortedSamples.Sort(); - levelSamples.AddRange(sortedSamples); + ushort newSampleIndex = (ushort)level.SampleIndices.Count; + level.SampleIndices.AddRange(definition.SampleIndices); - level.SampleIndices = levelSamples.ToArray(); - level.NumSampleIndices = (uint)levelSamples.Count; - - levelSoundDetails.Add(new TRSoundDetails + level.SoundDetails.Add(new TRSoundDetails { Chance = definition.Details.Chance, Characteristics = definition.Details.Characteristics, @@ -310,10 +300,7 @@ private static short ImportSoundEffect(TR2Level level, TRSFXDefinition levelModels = level.Data.Models.ToList(); if (laraClones.Count > 0) { - TRModel laraModel = levelModels.Find(m => m.ID == (uint)TR2Type.Lara); + TRModel laraModel = level.Data.Models.Find(m => m.ID == (uint)TR2Type.Lara); foreach (TR2Type enemyType in laraClones) { - TRModel enemyModel = levelModels.Find(m => m.ID == (uint)enemyType); + TRModel enemyModel = level.Data.Models.Find(m => m.ID == (uint)enemyType); enemyModel.MeshTree = laraModel.MeshTree; enemyModel.StartingMesh = laraModel.StartingMesh; enemyModel.NumMeshes = laraModel.NumMeshes; @@ -951,8 +950,8 @@ private void RandomizeEnemyMeshes(TR2CombinedLevel level, EnemyRandomizationColl && _generator.Next(0, chance) == 0) { // Make Marco look and behave like Winston, until Lara gets too close - TRModel marcoModel = levelModels.Find(m => m.ID == (uint)TR2Type.MarcoBartoli); - TRModel winnieModel = levelModels.Find(m => m.ID == (uint)TR2Type.Winston); + TRModel marcoModel = level.Data.Models.Find(m => m.ID == (uint)TR2Type.MarcoBartoli); + TRModel winnieModel = level.Data.Models.Find(m => m.ID == (uint)TR2Type.Winston); marcoModel.Animation = winnieModel.Animation; marcoModel.FrameOffset = winnieModel.FrameOffset; marcoModel.MeshTree = winnieModel.MeshTree; diff --git a/TRRandomizerCore/Randomizers/TR2/TR2ItemRandomizer.cs b/TRRandomizerCore/Randomizers/TR2/TR2ItemRandomizer.cs index 7f9aadb43..d5abc385d 100644 --- a/TRRandomizerCore/Randomizers/TR2/TR2ItemRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR2/TR2ItemRandomizer.cs @@ -185,14 +185,11 @@ private void RandomizeSprites() // The _spriteRandomizer exists so it gets all the SpriteSquence and SpriteTexture from the level // We cannot pass the level itself as ItemSpriteRandomizer is a shared class - _spriteRandomizer.Sequences = _levelInstance.Data.SpriteSequences.ToList(); - _spriteRandomizer.Textures = _levelInstance.Data.SpriteTextures.ToList(); + _spriteRandomizer.Sequences = _levelInstance.Data.SpriteSequences; + _spriteRandomizer.Textures = _levelInstance.Data.SpriteTextures; //Calling the actual randomization _spriteRandomizer.Randomize(_generator); - - // Only the SpriteTexture needs to be rewritten - _levelInstance.Data.SpriteTextures = _spriteRandomizer.Textures.ToArray(); } public void RandomizeItemLocations(TR2CombinedLevel level) diff --git a/TRRandomizerCore/Randomizers/TR2/TR2OutfitRandomizer.cs b/TRRandomizerCore/Randomizers/TR2/TR2OutfitRandomizer.cs index 3edb9545f..af84f0bc5 100644 --- a/TRRandomizerCore/Randomizers/TR2/TR2OutfitRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR2/TR2OutfitRandomizer.cs @@ -229,9 +229,8 @@ protected override void ProcessImpl() private bool Import(TR2CombinedLevel level, TR2Type lara) { - List models = level.Data.Models.ToList(); - TRModel laraModel = models.Find(m => m.ID == (uint)TR2Type.Lara); - List laraClones = models.FindAll(m => m.MeshTree == laraModel.MeshTree && m != laraModel); + TRModel laraModel = level.Data.Models.Find(m => m.ID == (uint)TR2Type.Lara); + List laraClones = level.Data.Models.FindAll(m => m.MeshTree == laraModel.MeshTree && m != laraModel); if (lara == TR2Type.LaraInvisible) { @@ -276,8 +275,7 @@ private bool Import(TR2CombinedLevel level, TR2Type lara) // #314 Any clones of Lara should copy her new style if (laraClones.Count > 0) { - models = level.Data.Models.ToList(); - laraModel = models.Find(m => m.ID == (uint)TR2Type.Lara); + laraModel = level.Data.Models.Find(m => m.ID == (uint)TR2Type.Lara); foreach (TRModel model in laraClones) { model.MeshTree = laraModel.MeshTree; @@ -311,9 +309,9 @@ private static void CloneLaraMeshes(TR2CombinedLevel level, List clones { if (clones.Count > 0) { - TRMesh[] meshes = TRMeshUtilities.GetModelMeshes(level.Data, laraModel); + List meshes = TRMeshUtilities.GetModelMeshes(level.Data, laraModel); int firstMeshIndex = -1; - for (int i = 0; i < meshes.Length; i++) + for (int i = 0; i < meshes.Count; i++) { int insertedIndex = TRMeshUtilities.InsertMesh(level.Data, MeshEditor.CloneMesh(meshes[i])); if (firstMeshIndex == -1) @@ -334,7 +332,7 @@ private static void HideEntities(TR2CombinedLevel level, IEnumerable en MeshEditor editor = new(); foreach (TR2Type ent in entities) { - TRMesh[] meshes = TRMeshUtilities.GetModelMeshes(level.Data, ent); + List meshes = TRMeshUtilities.GetModelMeshes(level.Data, ent); if (meshes != null) { foreach (TRMesh mesh in meshes) @@ -420,9 +418,8 @@ private void AdjustOutfit(TR2CombinedLevel level, TR2Type lara) // into the diving suit, but model ID 99 is the one before. We always want the cutscene actor to // match DA, but this unfortunately means she'll leave the cutscene in the same outfit. She just // didn't like the look of any of the alternatives... - List models = level.Data.Models.ToList(); - TRModel actorLara = models.Find(m => m.ID == (short)TR2Type.CutsceneActor3); - TRModel realLara = models.Find(m => m.ID == (short)TR2Type.Lara); + TRModel actorLara = level.Data.Models.Find(m => m.ID == (short)TR2Type.CutsceneActor3); + TRModel realLara = level.Data.Models.Find(m => m.ID == (short)TR2Type.Lara); actorLara.MeshTree = realLara.MeshTree; actorLara.NumMeshes = realLara.NumMeshes; diff --git a/TRRandomizerCore/Randomizers/TR2/TR2SecretRandomizer.cs b/TRRandomizerCore/Randomizers/TR2/TR2SecretRandomizer.cs index 3a1b20eb7..5caf958ed 100644 --- a/TRRandomizerCore/Randomizers/TR2/TR2SecretRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR2/TR2SecretRandomizer.cs @@ -185,10 +185,10 @@ private static void FixSecretTextures(TR2CombinedLevel level) // Swap Stone and Jade textures - OG has them the wrong way around. // SpriteSequence offsets have to remain in order, so swap the texture targets instead. - TRSpriteSequence stoneSequence = Array.Find(level.Data.SpriteSequences, s => s.SpriteID == (int)TR2Type.StoneSecret_S_P); - TRSpriteSequence jadeSequence = Array.Find(level.Data.SpriteSequences, s => s.SpriteID == (int)TR2Type.JadeSecret_S_P); + TRSpriteSequence stoneSequence = level.Data.SpriteSequences.Find(s => s.SpriteID == (int)TR2Type.StoneSecret_S_P); + TRSpriteSequence jadeSequence = level.Data.SpriteSequences.Find(s => s.SpriteID == (int)TR2Type.JadeSecret_S_P); - TRSpriteTexture[] textures = level.Data.SpriteTextures; + List textures = level.Data.SpriteTextures; (textures[jadeSequence.Offset], textures[stoneSequence.Offset]) = (textures[stoneSequence.Offset], textures[jadeSequence.Offset]); } diff --git a/TRRandomizerCore/Randomizers/TR2R/TR2RAudioRandomizer.cs b/TRRandomizerCore/Randomizers/TR2R/TR2RAudioRandomizer.cs index ae13be06b..6bfbc82f8 100644 --- a/TRRandomizerCore/Randomizers/TR2R/TR2RAudioRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR2R/TR2RAudioRandomizer.cs @@ -189,11 +189,12 @@ private void RandomizeSoundEffects(TR2RCombinedLevel level) if (IsUncontrolledLevel(level.Script)) { HashSet indices = new(); - while (indices.Count < level.Data.NumSampleIndices) + while (indices.Count < level.Data.SampleIndices.Count) { indices.Add((uint)_generator.Next(0, _maxSample + 1)); } - level.Data.SampleIndices = indices.ToArray(); + level.Data.SampleIndices.Clear(); + level.Data.SampleIndices.AddRange(indices); } else { @@ -246,24 +247,18 @@ private static short ImportSoundEffect(TR2Level level, TRSFXDefinition levelSamples = level.SampleIndices.ToList(); List levelSoundDetails = level.SoundDetails.ToList(); uint minSample = definition.SampleIndices.Min(); - if (levelSamples.Contains(minSample)) + if (level.SampleIndices.Contains(minSample)) { - return (short)levelSoundDetails.FindIndex(d => levelSamples[d.Sample] == minSample); + return (short)levelSoundDetails.FindIndex(d => level.SampleIndices[d.Sample] == minSample); } - ushort newSampleIndex = (ushort)levelSamples.Count; - List sortedSamples = new(definition.SampleIndices); - sortedSamples.Sort(); - levelSamples.AddRange(sortedSamples); + ushort newSampleIndex = (ushort)level.SampleIndices.Count; + level.SampleIndices.AddRange(definition.SampleIndices); - level.SampleIndices = levelSamples.ToArray(); - level.NumSampleIndices = (uint)levelSamples.Count; - - levelSoundDetails.Add(new TRSoundDetails + level.SoundDetails.Add(new TRSoundDetails { Chance = definition.Details.Chance, Characteristics = definition.Details.Characteristics, @@ -271,10 +266,7 @@ private static short ImportSoundEffect(TR2Level level, TRSFXDefinition indices = new HashSet(); - while (indices.Count < level.Data.NumSampleIndices) + HashSet indices = new(); + while (indices.Count < level.Data.SampleIndices.Count) { indices.Add((uint)_generator.Next(0, _maxSample + 1)); } - level.Data.SampleIndices = indices.ToArray(); + level.Data.SampleIndices.Clear(); + level.Data.SampleIndices.AddRange(indices); } else { @@ -243,31 +244,18 @@ private static short ImportSoundEffect(TR3Level level, TRSFXDefinition levelSamples = level.SampleIndices.ToList(); List levelSoundDetails = level.SoundDetails.ToList(); uint minSample = newDefinition.SampleIndices.Min(); - if (levelSamples.Contains(minSample)) + if (level.SampleIndices.Contains(minSample)) { - // This index is already defined, so locate the TRSoundDetails that references it - // and return its index. - return (short)levelSoundDetails.FindIndex(d => levelSamples[d.Sample] == minSample); + return (short)levelSoundDetails.FindIndex(d => level.SampleIndices[d.Sample] == minSample); } - // Otherwise, we need to import the samples, create a sound details object to - // point to the first sample, and then return the new index. Make sure the - // samples are sorted first. - ushort newSampleIndex = (ushort)levelSamples.Count; - List sortedSamples = new(newDefinition.SampleIndices); - sortedSamples.Sort(); - levelSamples.AddRange(sortedSamples); + ushort newSampleIndex = (ushort)level.SampleIndices.Count; + level.SampleIndices.AddRange(newDefinition.SampleIndices); - level.SampleIndices = levelSamples.ToArray(); - level.NumSampleIndices = (uint)levelSamples.Count; - - // Make a new details object, but make sure to use the same chance as the current definition otherwise the - // likes of the Coastal Village "Sheila" guy will say "Hey" continuously. - levelSoundDetails.Add(new TR3SoundDetails + level.SoundDetails.Add(new TR3SoundDetails { Chance = currentDefinition.Details.Chance, Characteristics = newDefinition.Details.Characteristics, @@ -277,10 +265,7 @@ private static short ImportSoundEffect(TR3Level level, TRSFXDefinition en MeshEditor editor = new(); foreach (TR3Type ent in entities) { - TRMesh[] meshes = TRMeshUtilities.GetModelMeshes(level.Data, ent); + List meshes = TRMeshUtilities.GetModelMeshes(level.Data, ent); if (meshes != null) { foreach (TRMesh mesh in meshes) diff --git a/TRRandomizerCore/Randomizers/TR3/TR3SecretRandomizer.cs b/TRRandomizerCore/Randomizers/TR3/TR3SecretRandomizer.cs index 1b0f402e7..2f3b99705 100644 --- a/TRRandomizerCore/Randomizers/TR3/TR3SecretRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR3/TR3SecretRandomizer.cs @@ -762,15 +762,13 @@ protected override void StartImpl() // We exclude artefacts from import if this level already has an // actual artefact model, and we exclude current puzzle/key items // from the available switching pool. - List models = level.Data.Models.ToList(); - if (level.Is(TR3LevelNames.CRASH)) { // Special case for Crash Site, which is the only level that uses Quest1 (the swamp map). // We want to reallocate this as a key to allow us to reuse Quest1 on import. Amend the // models to become Key3 and update the script to match. - models.Find(m => m.ID == (uint)TR3Type.Quest1_P).ID = (uint)TR3Type.Key3_P; - models.Find(m => m.ID == (uint)TR3Type.Quest1_M_H).ID = (uint)TR3Type.Key3_M_H; + level.Data.Models.Find(m => m.ID == (uint)TR3Type.Quest1_P).ID = (uint)TR3Type.Key3_P; + level.Data.Models.Find(m => m.ID == (uint)TR3Type.Quest1_M_H).ID = (uint)TR3Type.Key3_M_H; level.Script.Keys[2] = level.Script.Pickups[0]; level.Script.SetStartInventoryItems(new Dictionary { @@ -780,7 +778,7 @@ protected override void StartImpl() foreach (TR3Type puzzleType in _artefactReplacements.Keys) { - if (models.Find(m => m.ID == (uint)puzzleType) == null) + if (level.Data.Models.Find(m => m.ID == (uint)puzzleType) == null) { allocation.AvailablePickupModels.Add(puzzleType); } @@ -790,7 +788,7 @@ protected override void StartImpl() for (int i = artefactTypes.Count - 1; i >= 0; i--) { TR3Type artefactType = artefactTypes[i]; - if (models.Find(m => m.ID == (uint)artefactType) != null) + if (level.Data.Models.Find(m => m.ID == (uint)artefactType) != null) { artefactTypes.RemoveAt(i); } diff --git a/TRRandomizerCore/Randomizers/TR3R/TR3RAudioRandomizer.cs b/TRRandomizerCore/Randomizers/TR3R/TR3RAudioRandomizer.cs index 475fc2951..9351490b7 100644 --- a/TRRandomizerCore/Randomizers/TR3R/TR3RAudioRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR3R/TR3RAudioRandomizer.cs @@ -149,11 +149,12 @@ private void RandomizeSoundEffects(TR3RCombinedLevel level) if (IsUncontrolledLevel(level.Script)) { HashSet indices = new(); - while (indices.Count < level.Data.NumSampleIndices) + while (indices.Count < level.Data.SampleIndices.Count) { indices.Add((uint)_generator.Next(0, _maxSample + 1)); } - level.Data.SampleIndices = indices.ToArray(); + level.Data.SampleIndices.Clear(); + level.Data.SampleIndices.AddRange(indices); } else { @@ -206,24 +207,18 @@ private static short ImportSoundEffect(TR3Level level, TRSFXDefinition levelSamples = level.SampleIndices.ToList(); List levelSoundDetails = level.SoundDetails.ToList(); uint minSample = newDefinition.SampleIndices.Min(); - if (levelSamples.Contains(minSample)) + if (level.SampleIndices.Contains(minSample)) { - return (short)levelSoundDetails.FindIndex(d => levelSamples[d.Sample] == minSample); + return (short)levelSoundDetails.FindIndex(d => level.SampleIndices[d.Sample] == minSample); } - ushort newSampleIndex = (ushort)levelSamples.Count; - List sortedSamples = new(newDefinition.SampleIndices); - sortedSamples.Sort(); - levelSamples.AddRange(sortedSamples); + ushort newSampleIndex = (ushort)level.SampleIndices.Count; + level.SampleIndices.AddRange(newDefinition.SampleIndices); - level.SampleIndices = levelSamples.ToArray(); - level.NumSampleIndices = (uint)levelSamples.Count; - - levelSoundDetails.Add(new TR3SoundDetails + level.SoundDetails.Add(new TR3SoundDetails { Chance = currentDefinition.Details.Chance, Characteristics = newDefinition.Details.Characteristics, @@ -233,10 +228,7 @@ private static short ImportSoundEffect(TR3Level level, TRSFXDefinition s.Offset == sprite.Texture + if (level.Data.SpriteSequences.Find(s => s.Offset == sprite.Texture && level.Data.Entities.Find(e => e.TypeID == (TR1Type)s.SpriteID) != null) == null) { defaultSpriteTextures.Add(sprite.Texture); @@ -156,7 +156,7 @@ public DynamicTextureTarget Build(TR1CombinedLevel level) // textures from the same animation list. foreach (int texture in defaultObjectTextures.ToList()) { - TRAnimatedTexture anim = Array.Find(level.Data.AnimatedTextures, a => a.Textures.Contains((ushort)texture)); + TRAnimatedTexture anim = level.Data.AnimatedTextures.Find(a => a.Textures.Contains((ushort)texture)); if (anim != null) { foreach (ushort animTexture in anim.Textures) @@ -245,7 +245,7 @@ private void AddModelTextures(TR1Level level, TRModel model, TRMesh dummyMesh, I return; } - TRMesh[] meshes = TRMeshUtilities.GetModelMeshes(level, model); + List meshes = TRMeshUtilities.GetModelMeshes(level, model); List excludedMeshes = new() { dummyMesh }; if (modelID == TR1Type.Adam) @@ -272,7 +272,7 @@ private void AddModelTextures(TR1Level level, TRModel model, TRMesh dummyMesh, I } } else if ((modelID == TR1Type.ScionPiece3_S_P || modelID == TR1Type.ScionPiece4_S_P) - && meshes.Length == 1 && meshes[0].NumNormals != 123) + && meshes.Count == 1 && meshes[0].NumNormals != 123) { try { @@ -329,7 +329,6 @@ private void DuplicateMeshTextures(TR1Level level, TRMesh mesh) packer.Pack(true); // Map the packed segments to object textures. - List levelObjectTextures = level.ObjectTextures.ToList(); Queue reusableIndices = new(level.GetInvalidObjectTextureIndices()); Dictionary reindex = new(); foreach (TexturedTileSegment segment in duplicates) @@ -345,12 +344,12 @@ private void DuplicateMeshTextures(TR1Level level, TRMesh mesh) if (reusableIndices.Count > 0) { newIndex = reusableIndices.Dequeue(); - levelObjectTextures[newIndex] = objTexture.Texture; + level.ObjectTextures[newIndex] = objTexture.Texture; } - else if (levelObjectTextures.Count < maximumObjects) + else if (level.ObjectTextures.Count < maximumObjects) { - levelObjectTextures.Add(objTexture.Texture); - newIndex = levelObjectTextures.Count - 1; + level.ObjectTextures.Add(objTexture.Texture); + newIndex = level.ObjectTextures.Count - 1; } else { @@ -371,8 +370,6 @@ private void DuplicateMeshTextures(TR1Level level, TRMesh mesh) f.Texture = (ushort)reindex[f.Texture]; } - level.ObjectTextures = levelObjectTextures.ToArray(); - level.NumObjectTextures = (uint)levelObjectTextures.Count; level.ResetUnusedTextures(); } @@ -386,7 +383,7 @@ private static void AddMeshTextures(TRMesh mesh, ISet textures) private static void AddSpriteTextures(TR1Level level, TR1Type spriteID, ISet textures) { - TRSpriteSequence sequence = Array.Find(level.SpriteSequences, s => s.SpriteID == (int)spriteID); + TRSpriteSequence sequence = level.SpriteSequences.Find(s => s.SpriteID == (int)spriteID); if (sequence != null) { for (int i = 0; i < sequence.NegativeLength * -1; i++) diff --git a/TRRandomizerCore/Textures/Landmarks/AbstractLandmarkImporter.cs b/TRRandomizerCore/Textures/Landmarks/AbstractLandmarkImporter.cs index e393a3ec0..55d3ce26c 100644 --- a/TRRandomizerCore/Textures/Landmarks/AbstractLandmarkImporter.cs +++ b/TRRandomizerCore/Textures/Landmarks/AbstractLandmarkImporter.cs @@ -20,8 +20,7 @@ public abstract class AbstractLandmarkImporter protected abstract int MaxTextures { get; } protected abstract AbstractTexturePacker CreatePacker(L level); - protected abstract TRObjectTexture[] GetObjectTextures(L level); - protected abstract void SetObjectTextures(L level, IEnumerable textures); + protected abstract List GetObjectTextures(L level); protected abstract void SetRoomTexture(L level, int roomIndex, int rectangleIndex, ushort textureIndex); protected abstract short? GetRoomFromPortal(L level, PortalSector portalSector, bool isLevelMirrored); @@ -31,7 +30,7 @@ public bool Import(L level, AbstractTextureMapping mapping, bool isLevelMi mapping.CommitGraphics(); // If we are already at the maximum number of textures, bail out. - List textures = GetObjectTextures(level).ToList(); + List textures = GetObjectTextures(level); if (textures.Count == MaxTextures) { return false; @@ -164,8 +163,6 @@ public bool Import(L level, AbstractTextureMapping mapping, bool isLevelMi } } - SetObjectTextures(level, textures); - return true; } catch (PackingException) diff --git a/TRRandomizerCore/Textures/Landmarks/TR1LandmarkImporter.cs b/TRRandomizerCore/Textures/Landmarks/TR1LandmarkImporter.cs index d85f97343..9bfb42e14 100644 --- a/TRRandomizerCore/Textures/Landmarks/TR1LandmarkImporter.cs +++ b/TRRandomizerCore/Textures/Landmarks/TR1LandmarkImporter.cs @@ -14,17 +14,11 @@ protected override AbstractTexturePacker CreatePacker(TR1Leve return new TR1TexturePacker(level); } - protected override TRObjectTexture[] GetObjectTextures(TR1Level level) + protected override List GetObjectTextures(TR1Level level) { return level.ObjectTextures; } - protected override void SetObjectTextures(TR1Level level, IEnumerable textures) - { - level.ObjectTextures = textures.ToArray(); - level.NumObjectTextures = (uint)level.ObjectTextures.Length; - } - protected override void SetRoomTexture(TR1Level level, int roomIndex, int rectangleIndex, ushort textureIndex) { level.Rooms[roomIndex].RoomData.Rectangles[rectangleIndex].Texture = textureIndex; diff --git a/TRRandomizerCore/Textures/Landmarks/TR2LandmarkImporter.cs b/TRRandomizerCore/Textures/Landmarks/TR2LandmarkImporter.cs index ad60c168b..b801930ea 100644 --- a/TRRandomizerCore/Textures/Landmarks/TR2LandmarkImporter.cs +++ b/TRRandomizerCore/Textures/Landmarks/TR2LandmarkImporter.cs @@ -14,17 +14,11 @@ protected override AbstractTexturePacker CreatePacker(TR2Leve return new TR2TexturePacker(level); } - protected override TRObjectTexture[] GetObjectTextures(TR2Level level) + protected override List GetObjectTextures(TR2Level level) { return level.ObjectTextures; } - protected override void SetObjectTextures(TR2Level level, IEnumerable textures) - { - level.ObjectTextures = textures.ToArray(); - level.NumObjectTextures = (uint)level.ObjectTextures.Length; - } - protected override void SetRoomTexture(TR2Level level, int roomIndex, int rectangleIndex, ushort textureIndex) { level.Rooms[roomIndex].RoomData.Rectangles[rectangleIndex].Texture = textureIndex; diff --git a/TRRandomizerCore/Textures/Landmarks/TR3LandmarkImporter.cs b/TRRandomizerCore/Textures/Landmarks/TR3LandmarkImporter.cs index c9a1bdb34..b62fc588e 100644 --- a/TRRandomizerCore/Textures/Landmarks/TR3LandmarkImporter.cs +++ b/TRRandomizerCore/Textures/Landmarks/TR3LandmarkImporter.cs @@ -14,17 +14,11 @@ protected override AbstractTexturePacker CreatePacker(TR3Leve return new TR3TexturePacker(level); } - protected override TRObjectTexture[] GetObjectTextures(TR3Level level) + protected override List GetObjectTextures(TR3Level level) { return level.ObjectTextures; } - protected override void SetObjectTextures(TR3Level level, IEnumerable textures) - { - level.ObjectTextures = textures.ToArray(); - level.NumObjectTextures = (uint)level.ObjectTextures.Length; - } - protected override void SetRoomTexture(TR3Level level, int roomIndex, int rectangleIndex, ushort textureIndex) { level.Rooms[roomIndex].RoomData.Rectangles[rectangleIndex].Texture = textureIndex; diff --git a/TRRandomizerCore/Textures/Wireframing/AbstractTRWireframer.cs b/TRRandomizerCore/Textures/Wireframing/AbstractTRWireframer.cs index cab1f5cea..39f296489 100644 --- a/TRRandomizerCore/Textures/Wireframing/AbstractTRWireframer.cs +++ b/TRRandomizerCore/Textures/Wireframing/AbstractTRWireframer.cs @@ -102,7 +102,7 @@ public void Apply(L level, WireframeData data) packer.Pack(true); Queue reusableTextures = new(GetInvalidObjectTextureIndices(level)); - List levelObjectTextures = GetObjectTextures(level).ToList(); + List levelObjectTextures = GetObjectTextures(level); ushort roomTextureIndex = (ushort)reusableTextures.Dequeue(); levelObjectTextures[roomTextureIndex] = roomTexture.Texture; @@ -134,8 +134,6 @@ public void Apply(L level, WireframeData data) } } - SetObjectTextures(level, levelObjectTextures); - ResetRoomTextures(roomTextureIndex, ladderTextureIndex, triggerTextureIndex, deathTextureIndex, specialTextureRemap); ResetMeshTextures(modelRemap, specialTextureRemap); TidyModels(level); @@ -145,8 +143,8 @@ public void Apply(L level, WireframeData data) private void RetainCustomTextures(L level) { - TRObjectTexture[] textures = GetObjectTextures(level); - for (ushort i = 0; i < textures.Length; i++) + List textures = GetObjectTextures(level); + for (ushort i = 0; i < textures.Count; i++) { if (textures[i].Attribute == (ushort)TRBlendingMode.Unused01) { @@ -355,7 +353,7 @@ private void ProcessClips(AbstractTexturePacker packer, L level, Pen pen, { // Some animated textures are shared in segments e.g. 4 32x32 segments within a 64x64 container, // so in instances where we only want to wireframe a section of these, we use manual clipping. - TRObjectTexture[] textures = GetObjectTextures(level); + List textures = GetObjectTextures(level); foreach (WireframeClip clip in _data.ManualClips) { BitmapGraphics frame = CreateFrame(clip.Clip.Width, clip.Clip.Height, pen, mode, true); @@ -681,37 +679,24 @@ private void SetFace3Colours(IEnumerable faces, int colourIndex) private void DeleteAnimatedTextures(L level) { - List animatedTextures = GetAnimatedTextures(level).ToList(); + List animatedTextures = GetAnimatedTextures(level); for (int i = animatedTextures.Count - 1; i >= 0; i--) { TRAnimatedTexture animatedTexture = animatedTextures[i]; - List textures = animatedTexture.Textures.ToList(); - for (int j = textures.Count - 1; j >= 0; j--) + for (int j = animatedTexture.Textures.Count - 1; j >= 0; j--) { - if (!IsTextureExcluded(textures[j])) + if (!IsTextureExcluded(animatedTexture.Textures[j])) { - textures.RemoveAt(j); + animatedTexture.Textures.RemoveAt(j); } } - if (textures.Count < 2) + if (animatedTexture.Textures.Count < 2) { animatedTextures.RemoveAt(i); } - else - { - animatedTexture.Textures = textures.ToArray(); - } } - - int length = 1; - foreach (TRAnimatedTexture animatedTexture in animatedTextures) - { - length += animatedTexture.NumTextures + 2; - } - - SetAnimatedTextures(level, animatedTextures.ToArray(), (ushort)length); } protected abstract Dictionary> CollectLadders(L level); @@ -722,14 +707,12 @@ private void DeleteAnimatedTextures(L level) protected abstract IEnumerable> GetRoomFace3s(L level); protected abstract void ResetUnusedTextures(L level); protected abstract IEnumerable GetInvalidObjectTextureIndices(L level); - protected abstract TRObjectTexture[] GetObjectTextures(L level); - protected abstract void SetObjectTextures(L level, IEnumerable textures); - protected abstract Dictionary GetModelMeshes(L level); + protected abstract List GetObjectTextures(L level); protected abstract int GetBlackPaletteIndex(L level); protected abstract int ImportColour(L level, Color c); protected abstract List GetModels(L level); - protected abstract TRMesh[] GetModelMeshes(L level, TRModel model); - protected abstract TRMesh[] GetLevelMeshes(L level); + protected abstract List GetModelMeshes(L level, TRModel model); + protected abstract List GetLevelMeshes(L level); protected abstract List GetStaticMeshes(L level); protected abstract TRMesh GetStaticMesh(L level, TRStaticMesh staticMesh); protected abstract bool IsSkybox(TRModel model); @@ -739,8 +722,7 @@ private void DeleteAnimatedTextures(L level) protected abstract bool IsInteractableModel(TRModel model); protected virtual bool ShouldSolidifyModel(TRModel model) => false; protected abstract void SetSkyboxVisible(L level); - protected abstract TRAnimatedTexture[] GetAnimatedTextures(L level); - protected abstract void SetAnimatedTextures(L level, TRAnimatedTexture[] animatedTextures, ushort length); + protected abstract List GetAnimatedTextures(L level); public virtual bool Is8BitPalette { get; } protected virtual void ResetPaletteTracking(L level) { } diff --git a/TRRandomizerCore/Textures/Wireframing/TR1Wireframer.cs b/TRRandomizerCore/Textures/Wireframing/TR1Wireframer.cs index f638798a7..52567f0b5 100644 --- a/TRRandomizerCore/Textures/Wireframing/TR1Wireframer.cs +++ b/TRRandomizerCore/Textures/Wireframing/TR1Wireframer.cs @@ -86,26 +86,12 @@ protected override IEnumerable GetInvalidObjectTextureIndices(TR1Level leve return level.GetInvalidObjectTextureIndices(); } - protected override TRMesh[] GetLevelMeshes(TR1Level level) + protected override List GetLevelMeshes(TR1Level level) { return level.Meshes; } - protected override Dictionary GetModelMeshes(TR1Level level) - { - Dictionary modelMeshes = new(); - foreach (TRModel model in level.Models) - { - TRMesh[] meshes = GetModelMeshes(level, model); - if (meshes != null) - { - modelMeshes[(TR1Type)model.ID] = meshes; - } - } - return modelMeshes; - } - - protected override TRMesh[] GetModelMeshes(TR1Level level, TRModel model) + protected override List GetModelMeshes(TR1Level level, TRModel model) { return TRMeshUtilities.GetModelMeshes(level, model); } @@ -115,7 +101,7 @@ protected override List GetModels(TR1Level level) return level.Models; } - protected override TRObjectTexture[] GetObjectTextures(TR1Level level) + protected override List GetObjectTextures(TR1Level level) { return level.ObjectTextures; } @@ -183,12 +169,6 @@ protected override void ResetUnusedTextures(TR1Level level) level.ResetUnusedTextures(); } - protected override void SetObjectTextures(TR1Level level, IEnumerable textures) - { - level.ObjectTextures = textures.ToArray(); - level.NumObjectTextures = (uint)level.ObjectTextures.Length; - } - protected override void SetSkyboxVisible(TR1Level level) { } protected override Dictionary> CollectLadders(TR1Level level) @@ -206,17 +186,11 @@ protected override List CollectDeathFaces(TR1Level level) return FaceUtilities.GetTriggerFaces(level, new List(), true); } - protected override TRAnimatedTexture[] GetAnimatedTextures(TR1Level level) + protected override List GetAnimatedTextures(TR1Level level) { return level.AnimatedTextures; } - protected override void SetAnimatedTextures(TR1Level level, TRAnimatedTexture[] animatedTextures, ushort length) - { - level.AnimatedTextures = animatedTextures; - level.NumAnimatedTextures = length; - } - protected override Dictionary CreateSpecialSegments(TR1Level level, Pen pen) { Dictionary segments = new(); diff --git a/TRRandomizerCore/Textures/Wireframing/TR2Wireframer.cs b/TRRandomizerCore/Textures/Wireframing/TR2Wireframer.cs index 3f350729a..b7f50609d 100644 --- a/TRRandomizerCore/Textures/Wireframing/TR2Wireframer.cs +++ b/TRRandomizerCore/Textures/Wireframing/TR2Wireframer.cs @@ -58,36 +58,22 @@ protected override IEnumerable GetInvalidObjectTextureIndices(TR2Level leve return level.GetInvalidObjectTextureIndices(); } - protected override TRMesh[] GetLevelMeshes(TR2Level level) + protected override List GetLevelMeshes(TR2Level level) { return level.Meshes; } - protected override Dictionary GetModelMeshes(TR2Level level) - { - Dictionary modelMeshes = new(); - foreach (TRModel model in level.Models) - { - TRMesh[] meshes = GetModelMeshes(level, model); - if (meshes != null) - { - modelMeshes[(TR2Type)model.ID] = meshes; - } - } - return modelMeshes; - } - - protected override TRMesh[] GetModelMeshes(TR2Level level, TRModel model) + protected override List GetModelMeshes(TR2Level level, TRModel model) { return TRMeshUtilities.GetModelMeshes(level, model); } protected override List GetModels(TR2Level level) { - return level.Models.ToList(); + return level.Models; } - protected override TRObjectTexture[] GetObjectTextures(TR2Level level) + protected override List GetObjectTextures(TR2Level level) { return level.ObjectTextures; } @@ -144,12 +130,6 @@ protected override void ResetUnusedTextures(TR2Level level) level.ResetUnusedTextures(); } - protected override void SetObjectTextures(TR2Level level, IEnumerable textures) - { - level.ObjectTextures = textures.ToArray(); - level.NumObjectTextures = (uint)level.ObjectTextures.Length; - } - protected override void SetSkyboxVisible(TR2Level level) { foreach (TR2Room room in level.Rooms) @@ -173,14 +153,8 @@ protected override List CollectDeathFaces(TR2Level level) return FaceUtilities.GetTriggerFaces(level, new List(), true); } - protected override TRAnimatedTexture[] GetAnimatedTextures(TR2Level level) + protected override List GetAnimatedTextures(TR2Level level) { return level.AnimatedTextures; } - - protected override void SetAnimatedTextures(TR2Level level, TRAnimatedTexture[] animatedTextures, ushort length) - { - level.AnimatedTextures = animatedTextures; - level.NumAnimatedTextures = length; - } } diff --git a/TRRandomizerCore/Textures/Wireframing/TR3Wireframer.cs b/TRRandomizerCore/Textures/Wireframing/TR3Wireframer.cs index 3af3d2e49..4a8300d81 100644 --- a/TRRandomizerCore/Textures/Wireframing/TR3Wireframer.cs +++ b/TRRandomizerCore/Textures/Wireframing/TR3Wireframer.cs @@ -53,36 +53,22 @@ protected override IEnumerable GetInvalidObjectTextureIndices(TR3Level leve return level.GetInvalidObjectTextureIndices(); } - protected override TRMesh[] GetLevelMeshes(TR3Level level) + protected override List GetLevelMeshes(TR3Level level) { return level.Meshes; } - protected override Dictionary GetModelMeshes(TR3Level level) - { - Dictionary modelMeshes = new(); - foreach (TRModel model in level.Models) - { - TRMesh[] meshes = GetModelMeshes(level, model); - if (meshes != null) - { - modelMeshes[(TR3Type)model.ID] = meshes; - } - } - return modelMeshes; - } - - protected override TRMesh[] GetModelMeshes(TR3Level level, TRModel model) + protected override List GetModelMeshes(TR3Level level, TRModel model) { return TRMeshUtilities.GetModelMeshes(level, model); } protected override List GetModels(TR3Level level) { - return level.Models.ToList(); + return level.Models; } - protected override TRObjectTexture[] GetObjectTextures(TR3Level level) + protected override List GetObjectTextures(TR3Level level) { return level.ObjectTextures; } @@ -150,12 +136,6 @@ protected override void ResetUnusedTextures(TR3Level level) level.ResetUnusedTextures(); } - protected override void SetObjectTextures(TR3Level level, IEnumerable textures) - { - level.ObjectTextures = textures.ToArray(); - level.NumObjectTextures = (uint)level.ObjectTextures.Length; - } - protected override void SetSkyboxVisible(TR3Level level) { foreach (TR3Room room in level.Rooms) @@ -179,17 +159,11 @@ protected override List CollectDeathFaces(TR3Level level) return FaceUtilities.GetTriggerFaces(level, new List(), true); } - protected override TRAnimatedTexture[] GetAnimatedTextures(TR3Level level) + protected override List GetAnimatedTextures(TR3Level level) { return level.AnimatedTextures; } - protected override void SetAnimatedTextures(TR3Level level, TRAnimatedTexture[] animatedTextures, ushort length) - { - level.AnimatedTextures = animatedTextures; - level.NumAnimatedTextures = length; - } - protected override Dictionary CreateSpecialSegments(TR3Level level, Pen pen) { Dictionary segments = new(); diff --git a/TRTexture16Importer/Helpers/TRPalette8Control.cs b/TRTexture16Importer/Helpers/TRPalette8Control.cs index 81b182437..bef4c5689 100644 --- a/TRTexture16Importer/Helpers/TRPalette8Control.cs +++ b/TRTexture16Importer/Helpers/TRPalette8Control.cs @@ -64,10 +64,10 @@ public void MergeTiles() // Grab meshes we aren't interested in - but don't remove Lara's hips e.g. Atlantean spawns List ignoredMeshes = new(); - TRMesh[] laraMeshes = TRMeshUtilities.GetModelMeshes(Level, TR1Type.Lara); + List laraMeshes = TRMeshUtilities.GetModelMeshes(Level, TR1Type.Lara); foreach (TR1Type entity in ObsoleteModels) { - TRMesh[] meshes = TRMeshUtilities.GetModelMeshes(Level, entity); + List meshes = TRMeshUtilities.GetModelMeshes(Level, entity); if (meshes != null) { foreach (TRMesh mesh in meshes) diff --git a/TRTexture16Importer/Textures/Mapping/AbstractTextureMapping.cs b/TRTexture16Importer/Textures/Mapping/AbstractTextureMapping.cs index 0557863f1..4e8d90a41 100644 --- a/TRTexture16Importer/Textures/Mapping/AbstractTextureMapping.cs +++ b/TRTexture16Importer/Textures/Mapping/AbstractTextureMapping.cs @@ -30,12 +30,12 @@ protected AbstractTextureMapping(L level) _committed = false; } - protected abstract TRMesh[] GetModelMeshes(E entity); + protected abstract List GetModelMeshes(E entity); protected abstract List GetPalette8(); protected abstract List GetPalette16(); protected abstract int ImportColour(Color colour); - protected abstract TRSpriteSequence[] GetSpriteSequences(); - protected abstract TRSpriteTexture[] GetSpriteTextures(); + protected abstract List GetSpriteSequences(); + protected abstract List GetSpriteTextures(); protected abstract Bitmap GetTile(int tileIndex); protected abstract void SetTile(int tileIndex, Bitmap bitmap); @@ -302,7 +302,7 @@ public void RedrawStaticTargets(StaticTextureSource source, string variant, D { translatedEntity = EntityMap[entity]; } - TRMesh[] meshes = GetModelMeshes(translatedEntity); + List meshes = GetModelMeshes(translatedEntity); ISet colourIndices = new HashSet(); foreach (TRMesh mesh in meshes) { @@ -364,8 +364,8 @@ public void RedrawStaticTargets(StaticTextureSource source, string variant, D { translatedEntity = EntityMap[entity]; } - TRMesh[] meshes = GetModelMeshes(translatedEntity); - if (meshes == null || meshes.Length == 0) + List meshes = GetModelMeshes(translatedEntity); + if (meshes == null || meshes.Count == 0) { continue; } @@ -433,8 +433,8 @@ private void GenerateSpriteSequenceTargets(StaticTextureSource source) throw new ArgumentException(string.Format("SpriteSequence {0} cannot be dynamically mapped without at least one source rectangle.", source.SpriteSequence)); } - List spriteSequences = GetSpriteSequences().ToList(); - TRSpriteTexture[] spriteTextures = GetSpriteTextures(); + List spriteSequences = GetSpriteSequences(); + List spriteTextures = GetSpriteTextures(); int spriteID = Convert.ToInt32(source.SpriteSequence); TRSpriteSequence sequence = spriteSequences.Find(s => s.SpriteID == spriteID); diff --git a/TRTexture16Importer/Textures/Mapping/TR1TextureMapping.cs b/TRTexture16Importer/Textures/Mapping/TR1TextureMapping.cs index 05539483b..919342a54 100644 --- a/TRTexture16Importer/Textures/Mapping/TR1TextureMapping.cs +++ b/TRTexture16Importer/Textures/Mapping/TR1TextureMapping.cs @@ -45,17 +45,17 @@ protected override int ImportColour(Color colour) return PaletteManager.AddPredefinedColour(colour); } - protected override TRMesh[] GetModelMeshes(TR1Type entity) + protected override List GetModelMeshes(TR1Type entity) { return TRMeshUtilities.GetModelMeshes(_level, entity); } - protected override TRSpriteSequence[] GetSpriteSequences() + protected override List GetSpriteSequences() { return _level.SpriteSequences; } - protected override TRSpriteTexture[] GetSpriteTextures() + protected override List GetSpriteTextures() { return _level.SpriteTextures; } diff --git a/TRTexture16Importer/Textures/Mapping/TR2TextureMapping.cs b/TRTexture16Importer/Textures/Mapping/TR2TextureMapping.cs index a56fa3796..716d21095 100644 --- a/TRTexture16Importer/Textures/Mapping/TR2TextureMapping.cs +++ b/TRTexture16Importer/Textures/Mapping/TR2TextureMapping.cs @@ -41,17 +41,17 @@ protected override int ImportColour(Color colour) return _paletteTracker.Import(colour); } - protected override TRMesh[] GetModelMeshes(TR2Type entity) + protected override List GetModelMeshes(TR2Type entity) { return TRMeshUtilities.GetModelMeshes(_level, entity); } - protected override TRSpriteSequence[] GetSpriteSequences() + protected override List GetSpriteSequences() { return _level.SpriteSequences; } - protected override TRSpriteTexture[] GetSpriteTextures() + protected override List GetSpriteTextures() { return _level.SpriteTextures; } diff --git a/TRTexture16Importer/Textures/Mapping/TR3TextureMapping.cs b/TRTexture16Importer/Textures/Mapping/TR3TextureMapping.cs index 62e3e4866..0e5bc5006 100644 --- a/TRTexture16Importer/Textures/Mapping/TR3TextureMapping.cs +++ b/TRTexture16Importer/Textures/Mapping/TR3TextureMapping.cs @@ -42,17 +42,17 @@ protected override int ImportColour(Color colour) return _paletteTracker.Import(colour); } - protected override TRMesh[] GetModelMeshes(TR3Type entity) + protected override List GetModelMeshes(TR3Type entity) { return TRMeshUtilities.GetModelMeshes(_level, entity); } - protected override TRSpriteSequence[] GetSpriteSequences() + protected override List GetSpriteSequences() { return _level.SpriteSequences; } - protected override TRSpriteTexture[] GetSpriteTextures() + protected override List GetSpriteTextures() { return _level.SpriteTextures; } diff --git a/TextureExport/Types/FaceMapper.cs b/TextureExport/Types/FaceMapper.cs index 60cab44ee..406b00b17 100644 --- a/TextureExport/Types/FaceMapper.cs +++ b/TextureExport/Types/FaceMapper.cs @@ -18,8 +18,6 @@ public static void DrawFaces(TR1Level level, string lvl, int[] roomNumbers) using TR1TexturePacker packer = new(level); packer.MaximumTiles = 255; - List objectTextures = level.ObjectTextures.ToList(); - Dictionary> rectFaces = new(); Dictionary> triFaces = new(); @@ -50,8 +48,8 @@ public static void DrawFaces(TR1Level level, string lvl, int[] roomNumbers) TexturedTileSegment newSegment = DrawNewFace(segment, "Q" + rectIndex, true); packer.AddRectangle(newSegment); - newRectFaces[roomNumber][rectIndex] = objectTextures.Count; - objectTextures.Add((newSegment.FirstTexture as IndexedTRObjectTexture).Texture); + newRectFaces[roomNumber][rectIndex] = level.ObjectTextures.Count; + level.ObjectTextures.Add((newSegment.FirstTexture as IndexedTRObjectTexture).Texture); } } @@ -63,8 +61,8 @@ public static void DrawFaces(TR1Level level, string lvl, int[] roomNumbers) TexturedTileSegment newSegment = DrawNewFace(segment, "T" + triIndex, true); packer.AddRectangle(newSegment); - newTriFaces[roomNumber][triIndex] = objectTextures.Count; - objectTextures.Add((newSegment.FirstTexture as IndexedTRObjectTexture).Texture); + newTriFaces[roomNumber][triIndex] = level.ObjectTextures.Count; + level.ObjectTextures.Add((newSegment.FirstTexture as IndexedTRObjectTexture).Texture); } } } @@ -83,9 +81,6 @@ public static void DrawFaces(TR1Level level, string lvl, int[] roomNumbers) } } - level.ObjectTextures = objectTextures.ToArray(); - level.NumObjectTextures = (uint)objectTextures.Count; - Directory.CreateDirectory(@"TR1\Faces"); new TR1LevelControl().Write(level, @"TR1\Faces\" + lvl); } @@ -95,8 +90,6 @@ public static void DrawFaces(TR2Level level, string lvl, int[] roomNumbers) using TR2TexturePacker packer = new(level); packer.MaximumTiles = 255; - List objectTextures = level.ObjectTextures.ToList(); - Dictionary> rectFaces = new(); Dictionary> triFaces = new(); @@ -127,8 +120,8 @@ public static void DrawFaces(TR2Level level, string lvl, int[] roomNumbers) TexturedTileSegment newSegment = DrawNewFace(segment, "Q" + rectIndex); packer.AddRectangle(newSegment); - newRectFaces[roomNumber][rectIndex] = objectTextures.Count; - objectTextures.Add((newSegment.FirstTexture as IndexedTRObjectTexture).Texture); + newRectFaces[roomNumber][rectIndex] = level.ObjectTextures.Count; + level.ObjectTextures.Add((newSegment.FirstTexture as IndexedTRObjectTexture).Texture); } } @@ -140,8 +133,8 @@ public static void DrawFaces(TR2Level level, string lvl, int[] roomNumbers) TexturedTileSegment newSegment = DrawNewFace(segment, "T" + triIndex); packer.AddRectangle(newSegment); - newTriFaces[roomNumber][triIndex] = objectTextures.Count; - objectTextures.Add((newSegment.FirstTexture as IndexedTRObjectTexture).Texture); + newTriFaces[roomNumber][triIndex] = level.ObjectTextures.Count; + level.ObjectTextures.Add((newSegment.FirstTexture as IndexedTRObjectTexture).Texture); } } } @@ -160,9 +153,6 @@ public static void DrawFaces(TR2Level level, string lvl, int[] roomNumbers) } } - level.ObjectTextures = objectTextures.ToArray(); - level.NumObjectTextures = (uint)objectTextures.Count; - Directory.CreateDirectory(@"TR2\Faces"); new TR2LevelControl().Write(level, @"TR2\Faces\" + lvl); } @@ -172,8 +162,6 @@ public static void DrawFaces(TR3Level level, string lvl, int[] roomNumbers) using TR3TexturePacker packer = new(level); packer.MaximumTiles = 255; - List objectTextures = level.ObjectTextures.ToList(); - Dictionary> rectFaces = new(); Dictionary> triFaces = new(); @@ -204,8 +192,8 @@ public static void DrawFaces(TR3Level level, string lvl, int[] roomNumbers) TexturedTileSegment newSegment = DrawNewFace(segment, "Q" + rectIndex); packer.AddRectangle(newSegment); - newRectFaces[roomNumber][rectIndex] = objectTextures.Count; - objectTextures.Add((newSegment.FirstTexture as IndexedTRObjectTexture).Texture); + newRectFaces[roomNumber][rectIndex] = level.ObjectTextures.Count; + level.ObjectTextures.Add((newSegment.FirstTexture as IndexedTRObjectTexture).Texture); } } @@ -217,8 +205,8 @@ public static void DrawFaces(TR3Level level, string lvl, int[] roomNumbers) TexturedTileSegment newSegment = DrawNewFace(segment, "T" + triIndex); packer.AddRectangle(newSegment); - newTriFaces[roomNumber][triIndex] = objectTextures.Count; - objectTextures.Add((newSegment.FirstTexture as IndexedTRObjectTexture).Texture); + newTriFaces[roomNumber][triIndex] = level.ObjectTextures.Count; + level.ObjectTextures.Add((newSegment.FirstTexture as IndexedTRObjectTexture).Texture); } } } @@ -237,9 +225,6 @@ public static void DrawFaces(TR3Level level, string lvl, int[] roomNumbers) } } - level.ObjectTextures = objectTextures.ToArray(); - level.NumObjectTextures = (uint)objectTextures.Count; - Directory.CreateDirectory(@"TR3\Faces"); new TR3LevelControl().Write(level, @"TR3\Faces\" + lvl); } @@ -252,7 +237,6 @@ public static void DrawBoxes(TR2Level level, string lvl, int[] roomNumbers) Dictionary> rectFaces = new(); Dictionary> newRectFaces = new(); - List objectTextures = level.ObjectTextures.ToList(); FDControl control = new(); control.ParseFromLevel(level); @@ -276,8 +260,8 @@ public static void DrawBoxes(TR2Level level, string lvl, int[] roomNumbers) TexturedTileSegment newSegment = DrawNewFace(segment, GetBoxDescription(level, control, roomNumber, rectIndex)); packer.AddRectangle(newSegment); - newRectFaces[roomNumber][rectIndex] = objectTextures.Count; - objectTextures.Add((newSegment.FirstTexture as IndexedTRObjectTexture).Texture); + newRectFaces[roomNumber][rectIndex] = level.ObjectTextures.Count; + level.ObjectTextures.Add((newSegment.FirstTexture as IndexedTRObjectTexture).Texture); } } @@ -291,9 +275,6 @@ public static void DrawBoxes(TR2Level level, string lvl, int[] roomNumbers) } } - level.ObjectTextures = objectTextures.ToArray(); - level.NumObjectTextures = (uint)objectTextures.Count; - Directory.CreateDirectory(@"TR2\Boxes"); new TR2LevelControl().Write(level, @"TR2\Boxes\" + lvl); } diff --git a/TextureExport/Types/HtmlExporter.cs b/TextureExport/Types/HtmlExporter.cs index 528e29e24..562dbcb87 100644 --- a/TextureExport/Types/HtmlExporter.cs +++ b/TextureExport/Types/HtmlExporter.cs @@ -183,7 +183,7 @@ private static void BuildLevelSelect(StringBuilder html, string currentLevel, IE } } - private static Dictionary GetSkyBoxColours(TRMesh[] meshes, List palette16) + private static Dictionary GetSkyBoxColours(List meshes, List palette16) { Dictionary colours = new(); if (meshes != null)