diff --git a/Deps/TRGE.Coord.dll b/Deps/TRGE.Coord.dll index a726a327a..8a22256aa 100644 Binary files a/Deps/TRGE.Coord.dll and b/Deps/TRGE.Coord.dll differ diff --git a/TREnvironmentEditor/Model/Types/Models/EMConvertSpriteSequenceFunction.cs b/TREnvironmentEditor/Model/Types/Models/EMConvertSpriteSequenceFunction.cs index 38b92ee74..2255625d1 100644 --- a/TREnvironmentEditor/Model/Types/Models/EMConvertSpriteSequenceFunction.cs +++ b/TREnvironmentEditor/Model/Types/Models/EMConvertSpriteSequenceFunction.cs @@ -9,63 +9,35 @@ public class EMConvertSpriteSequenceFunction : BaseEMFunction public override void ApplyToLevel(TR1Level level) { - ConvertSpriteSequence(level.SpriteSequences); - UpdateSpriteEntities(level.Entities); + ConvertSpriteSequence(level.Sprites, level.Entities); } public override void ApplyToLevel(TR2Level level) { - ConvertSpriteSequence(level.SpriteSequences); - UpdateSpriteEntities(level.Entities); + ConvertSpriteSequence(level.Sprites, level.Entities); } public override void ApplyToLevel(TR3Level level) { - ConvertSpriteSequence(level.SpriteSequences); - UpdateSpriteEntities(level.Entities); + ConvertSpriteSequence(level.Sprites, level.Entities); } - private void ConvertSpriteSequence(List sequences) + private void ConvertSpriteSequence(TRDictionary sequences, List entities) + where T : Enum + where E : TREntity { - if (sequences.Find(s => s.SpriteID == NewSpriteID) == null) + T oldID = (T)(object)OldSpriteID; + T newID = (T)(object)NewSpriteID; + if (!sequences.ChangeKey(oldID, newID)) { - TRSpriteSequence oldSequence = sequences.Find(s => s.SpriteID == OldSpriteID); - if (oldSequence != null) - { - oldSequence.SpriteID = NewSpriteID; - } - } - } - - private void UpdateSpriteEntities(List entities) - { - foreach (TR1Entity entity in entities) - { - if (entity.TypeID == (TR1Type)OldSpriteID) - { - entity.TypeID = (TR1Type)NewSpriteID; - } + return; } - } - private void UpdateSpriteEntities(IEnumerable entities) - { - foreach (TR2Entity entity in entities) - { - if (entity.TypeID == (TR2Type)OldSpriteID) - { - entity.TypeID = (TR2Type)NewSpriteID; - } - } - } - - private void UpdateSpriteEntities(IEnumerable entities) - { - foreach (TR3Entity entity in entities) + foreach (E entity in entities) { - if (entity.TypeID == (TR3Type)OldSpriteID) + if (EqualityComparer.Default.Equals(entity.TypeID, oldID)) { - entity.TypeID = (TR3Type)NewSpriteID; + entity.TypeID = newID; } } } diff --git a/TREnvironmentEditor/Model/Types/Models/EMCopySpriteSequenceFunction.cs b/TREnvironmentEditor/Model/Types/Models/EMCopySpriteSequenceFunction.cs index 4b20f0ceb..19f1d6f4f 100644 --- a/TREnvironmentEditor/Model/Types/Models/EMCopySpriteSequenceFunction.cs +++ b/TREnvironmentEditor/Model/Types/Models/EMCopySpriteSequenceFunction.cs @@ -9,32 +9,29 @@ public class EMCopySpriteSequenceFunction : BaseEMFunction public override void ApplyToLevel(TR1Level level) { - CopySpriteSequence(level.SpriteSequences); + CopySpriteSequence(level.Sprites); } public override void ApplyToLevel(TR2Level level) { - CopySpriteSequence(level.SpriteSequences); + CopySpriteSequence(level.Sprites); } public override void ApplyToLevel(TR3Level level) { - CopySpriteSequence(level.SpriteSequences); + CopySpriteSequence(level.Sprites); } - private void CopySpriteSequence(List sequences) + private void CopySpriteSequence(TRDictionary sequences) + where T : Enum { - TRSpriteSequence baseSequence = sequences.Find(s => s.SpriteID == BaseSpriteID); - TRSpriteSequence targetSequence = sequences.Find(s => s.SpriteID == TargetSpriteID); - - if (baseSequence != null && targetSequence == null) + T baseID = (T)(object)BaseSpriteID; + T targetID = (T)(object)TargetSpriteID; + if (!sequences.ContainsKey(baseID) || sequences.ContainsKey(targetID)) { - sequences.Add(new() - { - NegativeLength = baseSequence.NegativeLength, - Offset = baseSequence.Offset, - SpriteID = TargetSpriteID - }); + return; } + + sequences[targetID] = sequences[baseID]; } } diff --git a/TRLevelControl/Build/ISpriteProvider.cs b/TRLevelControl/Build/ISpriteProvider.cs new file mode 100644 index 000000000..7df0f3734 --- /dev/null +++ b/TRLevelControl/Build/ISpriteProvider.cs @@ -0,0 +1,8 @@ +namespace TRLevelControl.Build; + +public interface ISpriteProvider + where T : Enum +{ + public short GetSpriteOffset(T type); + public T FindSpriteType(short textureOffset); +} diff --git a/TRLevelControl/Build/TRSpriteBuilder.cs b/TRLevelControl/Build/TRSpriteBuilder.cs new file mode 100644 index 000000000..bcd4d5f37 --- /dev/null +++ b/TRLevelControl/Build/TRSpriteBuilder.cs @@ -0,0 +1,111 @@ +using System.Diagnostics; +using TRLevelControl.Model; + +namespace TRLevelControl.Build; + +public class TRSpriteBuilder : ISpriteProvider + where T : Enum +{ + private static readonly string _sprMarker = "SPR"; + + private readonly TRGameVersion _version; + private Dictionary _spriteOffsets; + + public TRSpriteBuilder(TRGameVersion version) + { + _version = version; + } + + public TRDictionary ReadSprites(TRLevelReader reader) + { + if (_version >= TRGameVersion.TR4) + { + string sprMarker = new(reader.ReadChars(_sprMarker.Length)); + Debug.Assert(sprMarker == _sprMarker); + Debug.Assert(_version != TRGameVersion.TR5 || reader.ReadByte() == 0); + } + + uint numTextures = reader.ReadUInt32(); + List textures = reader.ReadSpriteTextures(numTextures, _version); + + uint numSpriteSequences = reader.ReadUInt32(); + TRDictionary sprites = new(); + + for (int i = 0; i < numSpriteSequences; i++) + { + TRSpriteSequence sequence = new() + { + Textures = new() + }; + sprites[(T)(object)(uint)reader.ReadInt32()] = sequence; + + short negativeLength = reader.ReadInt16(); + short offset = reader.ReadInt16(); + for (int j = 0; j < -negativeLength; j++) + { + sequence.Textures.Add(textures[offset + j]); + } + } + + CacheSpriteOffsets(sprites); + return sprites; + } + + public void WriteSprites(TRLevelWriter writer, TRDictionary sprites) + { + if (_version >= TRGameVersion.TR4) + { + writer.Write(_sprMarker.ToCharArray()); + if (_version == TRGameVersion.TR5) + { + writer.Write((byte)0); + } + } + + List textures = sprites.Values + .SelectMany(s => s.Textures) + .ToList(); + + writer.Write((uint)textures.Count); + writer.Write(textures, _version); + + writer.Write((uint)sprites.Count); + foreach (T spriteID in sprites.Keys) + { + TRSpriteSequence sequence = sprites[spriteID]; + uint id = (uint)(object)spriteID; + writer.Write((int)id); + writer.Write((short)-sequence.Textures.Count); + writer.Write(GetSpriteOffset(spriteID)); + } + } + + public void CacheSpriteOffsets(TRDictionary spriteSequences) + { + _spriteOffsets = new(); + short offset = 0; + foreach (var (type, sequence) in spriteSequences) + { + _spriteOffsets[type] = offset; + offset += (short)sequence.Textures.Count; + } + } + + public T FindSpriteType(short textureOffset) + { + foreach (var (type, offset) in _spriteOffsets) + { + if (offset == textureOffset) + { + return type; + } + } + + throw new IndexOutOfRangeException(); + } + + public short GetSpriteOffset(T type) + { + return _spriteOffsets[type]; + } +} diff --git a/TRLevelControl/Control/TR1LevelControl.cs b/TRLevelControl/Control/TR1LevelControl.cs index 58f68f2ab..0350d7cc7 100644 --- a/TRLevelControl/Control/TR1LevelControl.cs +++ b/TRLevelControl/Control/TR1LevelControl.cs @@ -8,11 +8,13 @@ namespace TRLevelControl; public class TR1LevelControl : TRLevelControlBase { private readonly TRObjectMeshBuilder _meshBuilder; + private readonly TRSpriteBuilder _spriteBuilder; public TR1LevelControl(ITRLevelObserver observer = null) : base(observer) { _meshBuilder = new(TRGameVersion.TR1, _observer); + _spriteBuilder = new(TRGameVersion.TR1); } protected override TR1Level CreateLevel(TRFileVersion version) @@ -120,19 +122,7 @@ protected override void Read(TRLevelReader reader) _level.ObjectTextures.Add(TR2FileReadUtilities.ReadObjectTexture(reader)); } - uint numSpriteTextures = reader.ReadUInt32(); - _level.SpriteTextures = new(); - for (int i = 0; i < numSpriteTextures; i++) - { - _level.SpriteTextures.Add(TR2FileReadUtilities.ReadSpriteTexture(reader)); - } - - uint numSpriteSequences = reader.ReadUInt32(); - _level.SpriteSequences = new(); - for (int i = 0; i < numSpriteSequences; i++) - { - _level.SpriteSequences.Add(TR2FileReadUtilities.ReadSpriteSequence(reader)); - } + ReadSprites(reader); //Cameras uint numCameras = reader.ReadUInt32(); @@ -200,6 +190,7 @@ protected override void Write(TRLevelWriter writer) writer.Write(_level.Version.LevelNumber); + _spriteBuilder.CacheSpriteOffsets(_level.Sprites); writer.Write((ushort)_level.Rooms.Count); foreach (TR1Room room in _level.Rooms) { writer.Write(room.Serialize()); } @@ -213,10 +204,7 @@ protected override void Write(TRLevelWriter writer) writer.Write((uint)_level.ObjectTextures.Count); foreach (TRObjectTexture tex in _level.ObjectTextures) { writer.Write(tex.Serialize()); } - writer.Write((uint)_level.SpriteTextures.Count); - foreach (TRSpriteTexture tex in _level.SpriteTextures) { writer.Write(tex.Serialize()); } - writer.Write((uint)_level.SpriteSequences.Count); - foreach (TRSpriteSequence sequence in _level.SpriteSequences) { writer.Write(sequence.Serialize()); } + WriteSprites(writer); writer.Write((uint)_level.Cameras.Count); foreach (TRCamera cam in _level.Cameras) { writer.Write(cam.Serialize()); } @@ -284,6 +272,16 @@ private void WriteStaticMeshes(TRLevelWriter writer) _meshBuilder.WriteStaticMeshes(writer, _level.StaticMeshes); } + private void ReadSprites(TRLevelReader reader) + { + _level.Sprites = _spriteBuilder.ReadSprites(reader); + } + + private void WriteSprites(TRLevelWriter writer) + { + _spriteBuilder.WriteSprites(writer, _level.Sprites); + } + private static TR1RoomData ConvertToRoomData(TR1Room room) { int RoomDataOffset = 0; diff --git a/TRLevelControl/Control/TR2LevelControl.cs b/TRLevelControl/Control/TR2LevelControl.cs index 081deebf2..d06733b2f 100644 --- a/TRLevelControl/Control/TR2LevelControl.cs +++ b/TRLevelControl/Control/TR2LevelControl.cs @@ -8,11 +8,13 @@ namespace TRLevelControl; public class TR2LevelControl : TRLevelControlBase { private readonly TRObjectMeshBuilder _meshBuilder; + private readonly TRSpriteBuilder _spriteBuilder; public TR2LevelControl(ITRLevelObserver observer = null) : base(observer) { _meshBuilder = new(TRGameVersion.TR2, _observer); + _spriteBuilder = new(TRGameVersion.TR2); } protected override TR2Level CreateLevel(TRFileVersion version) @@ -128,19 +130,7 @@ protected override void Read(TRLevelReader reader) _level.ObjectTextures.Add(TR2FileReadUtilities.ReadObjectTexture(reader)); } - uint numSpriteTextures = reader.ReadUInt32(); - _level.SpriteTextures = new(); - for (int i = 0; i < numSpriteTextures; i++) - { - _level.SpriteTextures.Add(TR2FileReadUtilities.ReadSpriteTexture(reader)); - } - - uint numSpriteSequences = reader.ReadUInt32(); - _level.SpriteSequences = new(); - for (int i = 0; i < numSpriteSequences; i++) - { - _level.SpriteSequences.Add(TR2FileReadUtilities.ReadSpriteSequence(reader)); - } + ReadSprites(reader); uint numCameras = reader.ReadUInt32(); _level.Cameras = new(); @@ -213,6 +203,7 @@ protected override void Write(TRLevelWriter writer) writer.Write(_level.Version.LevelNumber); + _spriteBuilder.CacheSpriteOffsets(_level.Sprites); writer.Write((ushort)_level.Rooms.Count); foreach (TR2Room room in _level.Rooms) { writer.Write(room.Serialize()); } @@ -226,10 +217,7 @@ protected override void Write(TRLevelWriter writer) writer.Write((uint)_level.ObjectTextures.Count); foreach (TRObjectTexture tex in _level.ObjectTextures) { writer.Write(tex.Serialize()); } - writer.Write((uint)_level.SpriteTextures.Count); - foreach (TRSpriteTexture tex in _level.SpriteTextures) { writer.Write(tex.Serialize()); } - writer.Write((uint)_level.SpriteSequences.Count); - foreach (TRSpriteSequence sequence in _level.SpriteSequences) { writer.Write(sequence.Serialize()); } + WriteSprites(writer); writer.Write((uint)_level.Cameras.Count); foreach (TRCamera cam in _level.Cameras) { writer.Write(cam.Serialize()); } @@ -295,6 +283,16 @@ private void WriteStaticMeshes(TRLevelWriter writer) _meshBuilder.WriteStaticMeshes(writer, _level.StaticMeshes); } + private void ReadSprites(TRLevelReader reader) + { + _level.Sprites = _spriteBuilder.ReadSprites(reader); + } + + private void WriteSprites(TRLevelWriter writer) + { + _spriteBuilder.WriteSprites(writer, _level.Sprites); + } + private static TR2RoomData ConvertToRoomData(TR2Room room) { int RoomDataOffset = 0; diff --git a/TRLevelControl/Control/TR3LevelControl.cs b/TRLevelControl/Control/TR3LevelControl.cs index 708f44c5f..39e8edb70 100644 --- a/TRLevelControl/Control/TR3LevelControl.cs +++ b/TRLevelControl/Control/TR3LevelControl.cs @@ -8,11 +8,13 @@ namespace TRLevelControl; public class TR3LevelControl : TRLevelControlBase { private readonly TRObjectMeshBuilder _meshBuilder; + private readonly TRSpriteBuilder _spriteBuilder; public TR3LevelControl(ITRLevelObserver observer = null) : base(observer) { _meshBuilder = new(TRGameVersion.TR3, _observer); + _spriteBuilder = new(TRGameVersion.TR3); } protected override TR3Level CreateLevel(TRFileVersion version) @@ -125,19 +127,7 @@ protected override void Read(TRLevelReader reader) ReadStaticMeshes(reader); - uint numSpriteTextures = reader.ReadUInt32(); - _level.SpriteTextures = new(); - for (int i = 0; i < numSpriteTextures; i++) - { - _level.SpriteTextures.Add(TR2FileReadUtilities.ReadSpriteTexture(reader)); - } - - uint numSpriteSequences = reader.ReadUInt32(); - _level.SpriteSequences = new(); - for (int i = 0; i < numSpriteSequences; i++) - { - _level.SpriteSequences.Add(TR2FileReadUtilities.ReadSpriteSequence(reader)); - } + ReadSprites(reader); uint numCameras = reader.ReadUInt32(); _level.Cameras = new(); @@ -218,6 +208,7 @@ protected override void Write(TRLevelWriter writer) writer.Write(_level.Version.LevelNumber); + _spriteBuilder.CacheSpriteOffsets(_level.Sprites); writer.Write((ushort)_level.Rooms.Count); foreach (TR3Room room in _level.Rooms) { writer.Write(room.Serialize()); } @@ -229,11 +220,8 @@ protected override void Write(TRLevelWriter writer) WriteStaticMeshes(writer); - writer.Write((uint)_level.SpriteTextures.Count); - foreach (TRSpriteTexture tex in _level.SpriteTextures) { writer.Write(tex.Serialize()); } - writer.Write((uint)_level.SpriteSequences.Count); - foreach (TRSpriteSequence sequence in _level.SpriteSequences) { writer.Write(sequence.Serialize()); } - + WriteSprites(writer); + writer.Write((uint)_level.Cameras.Count); foreach (TRCamera cam in _level.Cameras) { writer.Write(cam.Serialize()); } @@ -301,6 +289,16 @@ private void WriteStaticMeshes(TRLevelWriter writer) _meshBuilder.WriteStaticMeshes(writer, _level.StaticMeshes); } + private void ReadSprites(TRLevelReader reader) + { + _level.Sprites = _spriteBuilder.ReadSprites(reader); + } + + private void WriteSprites(TRLevelWriter writer) + { + _spriteBuilder.WriteSprites(writer, _level.Sprites); + } + private static TR3RoomData ConvertToRoomData(TR3Room room) { int RoomDataOffset = 0; diff --git a/TRLevelControl/Control/TR4LevelControl.cs b/TRLevelControl/Control/TR4LevelControl.cs index 7e1ffd3ce..097d3d028 100644 --- a/TRLevelControl/Control/TR4LevelControl.cs +++ b/TRLevelControl/Control/TR4LevelControl.cs @@ -7,11 +7,13 @@ namespace TRLevelControl; public class TR4LevelControl : TRLevelControlBase { private readonly TRObjectMeshBuilder _meshBuilder; + private readonly TRSpriteBuilder _spriteBuilder; public TR4LevelControl(ITRLevelObserver observer = null) : base(observer) { _meshBuilder = new(TRGameVersion.TR4, _observer); + _spriteBuilder = new(TRGameVersion.TR4); } protected override TR4Level CreateLevel(TRFileVersion version) @@ -168,6 +170,8 @@ private void ReadRooms(TRLevelReader reader) private void WriteRooms(TRLevelWriter writer) { + _spriteBuilder.CacheSpriteOffsets(_level.Sprites); + writer.Write((ushort)_level.Rooms.Count); foreach (TR4Room room in _level.Rooms) { @@ -212,24 +216,12 @@ private void WriteStaticMeshes(TRLevelWriter writer) private void ReadSprites(TRLevelReader reader) { - TR4FileReadUtilities.PopulateSprites(reader, _level); + _level.Sprites = _spriteBuilder.ReadSprites(reader); } private void WriteSprites(TRLevelWriter writer) { - writer.Write(TR4FileReadUtilities.SPRMarker.ToCharArray()); - - writer.Write((uint)_level.SpriteTextures.Count); - foreach (TRSpriteTexture st in _level.SpriteTextures) - { - writer.Write(st.Serialize()); - } - - writer.Write((uint)_level.SpriteSequences.Count); - foreach (TRSpriteSequence seq in _level.SpriteSequences) - { - writer.Write(seq.Serialize()); - } + _spriteBuilder.WriteSprites(writer, _level.Sprites); } private void ReadCameras(TRLevelReader reader) diff --git a/TRLevelControl/Control/TR5LevelControl.cs b/TRLevelControl/Control/TR5LevelControl.cs index 54e885177..359280f07 100644 --- a/TRLevelControl/Control/TR5LevelControl.cs +++ b/TRLevelControl/Control/TR5LevelControl.cs @@ -7,11 +7,13 @@ namespace TRLevelControl; public class TR5LevelControl : TRLevelControlBase { private readonly TRObjectMeshBuilder _meshBuilder; + private readonly TRSpriteBuilder _spriteBuilder; public TR5LevelControl(ITRLevelObserver observer = null) : base(observer) { _meshBuilder = new(TRGameVersion.TR5, _observer); + _spriteBuilder = new(TRGameVersion.TR5); } protected override TR5Level CreateLevel(TRFileVersion version) @@ -185,6 +187,8 @@ private void ReadRooms(TRLevelReader reader) private void WriteRooms(TRLevelWriter writer) { + _spriteBuilder.CacheSpriteOffsets(_level.Sprites); + writer.Write((uint)_level.Rooms.Count); foreach (TR5Room room in _level.Rooms) { @@ -229,25 +233,12 @@ private void WriteStaticMeshes(TRLevelWriter writer) private void ReadSprites(TRLevelReader reader) { - TR5FileReadUtilities.VerifySPRMarker(reader); - TR5FileReadUtilities.PopulateSprites(reader, _level); + _level.Sprites = _spriteBuilder.ReadSprites(reader); } private void WriteSprites(TRLevelWriter writer) { - writer.Write(TR5FileReadUtilities.SPRMarker.ToCharArray()); - - writer.Write((uint)_level.SpriteTextures.Count); - foreach (TRSpriteTexture st in _level.SpriteTextures) - { - writer.Write(st.Serialize()); - } - - writer.Write((uint)_level.SpriteSequences.Count); - foreach (TRSpriteSequence seq in _level.SpriteSequences) - { - writer.Write(seq.Serialize()); - } + _spriteBuilder.WriteSprites(writer, _level.Sprites); } private void ReadCameras(TRLevelReader reader) diff --git a/TRLevelControl/IO/TRLevelReader.cs b/TRLevelControl/IO/TRLevelReader.cs index d63a06373..d411c3b5e 100644 --- a/TRLevelControl/IO/TRLevelReader.cs +++ b/TRLevelControl/IO/TRLevelReader.cs @@ -411,4 +411,62 @@ public TRBoundingBox ReadBoundingBox() MaxZ = ReadInt16() }; } + + public List ReadSpriteTextures(long numTextures, TRGameVersion version) + { + List textures = new(); + for (int i = 0; i < numTextures; i++) + { + textures.Add(ReadSpriteTexture(version)); + } + return textures; + } + + public TRSpriteTexture ReadSpriteTexture(TRGameVersion version) + { + TRSpriteTexture sprite = new() + { + Atlas = ReadUInt16(), + }; + + byte x = ReadByte(); + byte y = ReadByte(); + ushort width = ReadUInt16(); + ushort height = ReadUInt16(); + short left = ReadInt16(); + short top = ReadInt16(); + short right = ReadInt16(); + short bottom = ReadInt16(); + + if (version < TRGameVersion.TR4) + { + sprite.X = x; + sprite.Y = y; + sprite.Width = (ushort)((width + 1) / TRConsts.TPageWidth); + sprite.Height = (ushort)((height + 1) / TRConsts.TPageHeight); + sprite.Alignment = new() + { + Left = left, + Top = top, + Right = right, + Bottom = bottom + }; + } + else + { + sprite.X = (byte)left; + sprite.Y = (byte)top; + sprite.Width = (ushort)(width / TRConsts.TPageWidth + 1); + sprite.Height = (ushort)(height / TRConsts.TPageHeight + 1); + sprite.Alignment = new() + { + Left = x, + Top = y, + Right = right, + Bottom = bottom + }; + } + + return sprite; + } } diff --git a/TRLevelControl/IO/TRLevelWriter.cs b/TRLevelControl/IO/TRLevelWriter.cs index b9896431b..58929eccf 100644 --- a/TRLevelControl/IO/TRLevelWriter.cs +++ b/TRLevelControl/IO/TRLevelWriter.cs @@ -327,4 +327,39 @@ public void Write(TRBoundingBox box) Write(box.MinZ); Write(box.MaxZ); } + + public void Write(IEnumerable textures, TRGameVersion version) + { + foreach (TRSpriteTexture texture in textures) + { + Write(texture, version); + } + } + + public void Write(TRSpriteTexture texture, TRGameVersion version) + { + Write(texture.Atlas); + if (version < TRGameVersion.TR4) + { + Write(texture.X); + Write(texture.Y); + Write((ushort)(texture.Width * TRConsts.TPageWidth - 1)); + Write((ushort)(texture.Height * TRConsts.TPageHeight - 1)); + Write(texture.Alignment.Left); + Write(texture.Alignment.Top); + Write(texture.Alignment.Right); + Write(texture.Alignment.Bottom); + } + else + { + Write((byte)texture.Alignment.Left); + Write((byte)texture.Alignment.Top); + Write((ushort)((texture.Width - 1) * TRConsts.TPageWidth)); + Write((ushort)((texture.Height - 1) * TRConsts.TPageHeight)); + Write((short)texture.X); + Write((short)texture.Y); + Write(texture.Alignment.Right); + Write(texture.Alignment.Bottom); + } + } } diff --git a/TRLevelControl/Model/Common/TRSpriteAlignment.cs b/TRLevelControl/Model/Common/TRSpriteAlignment.cs new file mode 100644 index 000000000..2201895f4 --- /dev/null +++ b/TRLevelControl/Model/Common/TRSpriteAlignment.cs @@ -0,0 +1,15 @@ +namespace TRLevelControl.Model; + +public class TRSpriteAlignment : ICloneable +{ + public short Left { get; set; } + public short Top { get; set; } + public short Right { get; set; } + public short Bottom { get; set; } + + public TRSpriteAlignment Clone() + => (TRSpriteAlignment)MemberwiseClone(); + + object ICloneable.Clone() + => Clone(); +} diff --git a/TRLevelControl/Model/Common/TRSpriteSequence.cs b/TRLevelControl/Model/Common/TRSpriteSequence.cs index 7a251982c..7a4cd41b9 100644 --- a/TRLevelControl/Model/Common/TRSpriteSequence.cs +++ b/TRLevelControl/Model/Common/TRSpriteSequence.cs @@ -1,37 +1,17 @@ -using System.Text; -using TRLevelControl.Serialization; +namespace TRLevelControl.Model; -namespace TRLevelControl.Model; - -public class TRSpriteSequence : ISerializableCompact +public class TRSpriteSequence : ICloneable { - public int SpriteID { get; set; } - - public short NegativeLength { get; set; } - - public short Offset { get; set; } - - public override string ToString() - { - StringBuilder sb = new(base.ToString()); + public List Textures { get; set; } = new(); - sb.Append(" SpriteID: " + SpriteID); - sb.Append(" NegativeLength: " + NegativeLength); - sb.Append(" Offset: " + Offset); - - return sb.ToString(); - } - - public byte[] Serialize() + public TRSpriteSequence Clone() { - using MemoryStream stream = new(); - using (BinaryWriter writer = new(stream)) + return new() { - writer.Write(SpriteID); - writer.Write(NegativeLength); - writer.Write(Offset); - } - - return stream.ToArray(); + Textures = new(Textures.Select(t => t.Clone())) + }; } + + object ICloneable.Clone() + => Clone(); } diff --git a/TRLevelControl/Model/Common/TRSpriteTexture.cs b/TRLevelControl/Model/Common/TRSpriteTexture.cs index ef6615794..3ebd75058 100644 --- a/TRLevelControl/Model/Common/TRSpriteTexture.cs +++ b/TRLevelControl/Model/Common/TRSpriteTexture.cs @@ -1,61 +1,42 @@ -using System.Text; -using TRLevelControl.Serialization; +using System.Drawing; namespace TRLevelControl.Model; -public class TRSpriteTexture : ISerializableCompact +public class TRSpriteTexture : TRTexture { - public ushort Atlas { get; set; } - public byte X { get; set; } - public byte Y { get; set; } - public ushort Width { get; set; } - public ushort Height { get; set; } + public TRSpriteAlignment Alignment { get; set; } - public short LeftSide { get; set; } - - public short TopSide { get; set; } - - public short RightSide { get; set; } - - public short BottomSide { get; set; } - - public override string ToString() + protected override Rectangle GetBounds() { - StringBuilder sb = new(base.ToString()); + return new(X, Y, Width, Height); + } - sb.Append(" Atlas: " + Atlas); - sb.Append(" X: " + X); - sb.Append(" Y: " + Y); - sb.Append(" Width: " + Width); - sb.Append(" Height: " + Height); - sb.Append(" LeftSide: " + LeftSide); - sb.Append(" TopSide: " + TopSide); - sb.Append(" RightSide: " + RightSide); - sb.Append(" BottomSide: " + BottomSide); + protected override void SetPosition(Point position) + { + X = (byte)position.X; + Y = (byte)position.Y; + } - return sb.ToString(); + protected override void SetSize(Size size) + { + Width = (ushort)size.Width; + Height = (ushort)size.Height; } - public byte[] Serialize() + public override TRSpriteTexture Clone() { - using MemoryStream stream = new(); - using (BinaryWriter writer = new(stream)) + return new() { - writer.Write(Atlas); - writer.Write(X); - writer.Write(Y); - writer.Write(Width); - writer.Write(Height); - writer.Write(LeftSide); - writer.Write(TopSide); - writer.Write(RightSide); - writer.Write(BottomSide); - } - - return stream.ToArray(); + Atlas = Atlas, + X = X, + Y = Y, + Width = Width, + Height = Height, + Alignment = Alignment?.Clone(), + }; } } diff --git a/TRLevelControl/Model/Common/TRTexture.cs b/TRLevelControl/Model/Common/TRTexture.cs new file mode 100644 index 000000000..22de00bac --- /dev/null +++ b/TRLevelControl/Model/Common/TRTexture.cs @@ -0,0 +1,52 @@ +using System.Drawing; + +namespace TRLevelControl.Model; + +public abstract class TRTexture : ICloneable +{ + public ushort Atlas { get; set; } + public Rectangle Bounds + { + get => GetBounds(); + set + { + Position = value.Location; + Size = value.Size; + } + } + + public Point Position + { + get => Bounds.Location; + set => SetPosition(value); + } + + public Size Size + { + get => Bounds.Size; + set => SetSize(value); + } + + public List Points => GetPoints(); + + protected List GetPoints() + { + Rectangle bounds = GetBounds(); + return new() + { + new() { X = bounds.Left, Y = bounds.Top }, + new() { X = bounds.Right - 1, Y = bounds.Top }, + new() { X = bounds.Right - 1, Y = bounds.Bottom - 1 }, + new() { X = bounds.Left, Y = bounds.Bottom - 1 }, + }; + } + + protected abstract Rectangle GetBounds(); + protected abstract void SetPosition(Point position); + protected abstract void SetSize(Size size); + + public abstract TRTexture Clone(); + + object ICloneable.Clone() + => Clone(); +} diff --git a/TRLevelControl/Model/TR1/TR1Level.cs b/TRLevelControl/Model/TR1/TR1Level.cs index 6735302f8..3a52d931e 100644 --- a/TRLevelControl/Model/TR1/TR1Level.cs +++ b/TRLevelControl/Model/TR1/TR1Level.cs @@ -8,8 +8,7 @@ public class TR1Level : TRLevelBase public TRDictionary Models { get; set; } public List StaticMeshes { get; set; } public List ObjectTextures { get; set; } - public List SpriteTextures { get; set; } - public List SpriteSequences { get; set; } + public TRDictionary Sprites { get; set; } public List Cameras { get; set; } public List SoundSources { get; set; } public List Boxes { get; set; } diff --git a/TRLevelControl/Model/TR2/TR2Level.cs b/TRLevelControl/Model/TR2/TR2Level.cs index e52459b5c..df12a497b 100644 --- a/TRLevelControl/Model/TR2/TR2Level.cs +++ b/TRLevelControl/Model/TR2/TR2Level.cs @@ -11,8 +11,7 @@ public class TR2Level : TRLevelBase public TRDictionary Models { get; set; } public List StaticMeshes { get; set; } public List ObjectTextures { get; set; } - public List SpriteTextures { get; set; } - public List SpriteSequences { get; set; } + public TRDictionary Sprites { get; set; } public List Cameras { get; set; } public List SoundSources { get; set; } public List Boxes { get; set; } diff --git a/TRLevelControl/Model/TR3/TR3Level.cs b/TRLevelControl/Model/TR3/TR3Level.cs index df69912c5..28aaa8b21 100644 --- a/TRLevelControl/Model/TR3/TR3Level.cs +++ b/TRLevelControl/Model/TR3/TR3Level.cs @@ -10,8 +10,7 @@ public class TR3Level : TRLevelBase public List FloorData { get; set; } public TRDictionary Models { get; set; } public List StaticMeshes { get; set; } - public List SpriteTextures { get; set; } - public List SpriteSequences { get; set; } + public TRDictionary Sprites { get; set; } public List Cameras { get; set; } public List SoundSources { get; set; } public List Boxes { get; set; } diff --git a/TRLevelControl/Model/TR4/TR4Level.cs b/TRLevelControl/Model/TR4/TR4Level.cs index a8d24da7f..4c0208659 100644 --- a/TRLevelControl/Model/TR4/TR4Level.cs +++ b/TRLevelControl/Model/TR4/TR4Level.cs @@ -7,8 +7,7 @@ public class TR4Level : TRLevelBase public List FloorData { get; set; } public TRDictionary Models { get; set; } public List StaticMeshes { get; set; } - public List SpriteTextures { get; set; } - public List SpriteSequences { get; set; } + public TRDictionary Sprites { get; set; } public List Cameras { get; set; } public List FlybyCameras { get; set; } public List SoundSources { get; set; } diff --git a/TRLevelControl/Model/TR5/TR5Level.cs b/TRLevelControl/Model/TR5/TR5Level.cs index 5a4ce8946..b2067afa0 100644 --- a/TRLevelControl/Model/TR5/TR5Level.cs +++ b/TRLevelControl/Model/TR5/TR5Level.cs @@ -9,8 +9,7 @@ public class TR5Level : TRLevelBase public List FloorData { get; set; } public TRDictionary Models { get; set; } public List StaticMeshes { get; set; } - public List SpriteTextures { get; set; } - public List SpriteSequences { get; set; } + public TRDictionary Sprites { get; set; } public List Cameras { get; set; } public List FlybyCameras { get; set; } public List SoundSources { get; set; } diff --git a/TRLevelControl/TR2FileReadUtilities.cs b/TRLevelControl/TR2FileReadUtilities.cs index 956fda18b..332d8757b 100644 --- a/TRLevelControl/TR2FileReadUtilities.cs +++ b/TRLevelControl/TR2FileReadUtilities.cs @@ -109,32 +109,6 @@ public static TRObjectTexture ReadObjectTexture(BinaryReader reader) }; } - public static TRSpriteTexture ReadSpriteTexture(BinaryReader reader) - { - return new TRSpriteTexture() - { - Atlas = reader.ReadUInt16(), - X = reader.ReadByte(), - Y = reader.ReadByte(), - Width = reader.ReadUInt16(), - Height = reader.ReadUInt16(), - LeftSide = reader.ReadInt16(), - TopSide = reader.ReadInt16(), - RightSide = reader.ReadInt16(), - BottomSide = reader.ReadInt16() - }; - } - - public static TRSpriteSequence ReadSpriteSequence(BinaryReader reader) - { - return new TRSpriteSequence() - { - SpriteID = reader.ReadInt32(), - NegativeLength = reader.ReadInt16(), - Offset = reader.ReadInt16() - }; - } - public static TRCamera ReadCamera(BinaryReader reader) { return new TRCamera() diff --git a/TRLevelControl/TR4FileReadUtilities.cs b/TRLevelControl/TR4FileReadUtilities.cs index 81c83d0c2..0b7824208 100644 --- a/TRLevelControl/TR4FileReadUtilities.cs +++ b/TRLevelControl/TR4FileReadUtilities.cs @@ -95,28 +95,6 @@ public static void PopulateFloordata(BinaryReader reader, TR4Level lvl) } } - public static void PopulateSprites(BinaryReader reader, TR4Level lvl) - { - string sprMarker = new(reader.ReadChars(SPRMarker.Length)); - Debug.Assert(sprMarker == SPRMarker); - - uint numSpriteTextures = reader.ReadUInt32(); - lvl.SpriteTextures = new(); - - for (int i = 0; i < numSpriteTextures; i++) - { - lvl.SpriteTextures.Add(TR2FileReadUtilities.ReadSpriteTexture(reader)); - } - - uint numSpriteSequences = reader.ReadUInt32(); - lvl.SpriteSequences = new(); - - for (int i = 0; i < numSpriteSequences; i++) - { - lvl.SpriteSequences.Add(TR2FileReadUtilities.ReadSpriteSequence(reader)); - } - } - public static void PopulateCameras(BinaryReader reader, TR4Level lvl) { //Cameras diff --git a/TRLevelControl/TR5FileReadUtilities.cs b/TRLevelControl/TR5FileReadUtilities.cs index 25b6d3a6e..4b59a0465 100644 --- a/TRLevelControl/TR5FileReadUtilities.cs +++ b/TRLevelControl/TR5FileReadUtilities.cs @@ -6,7 +6,6 @@ namespace TRLevelControl; internal static class TR5FileReadUtilities { - public static readonly string SPRMarker = "SPR\0"; public static readonly string TEXMarker = "TEX\0"; public static void PopulateRooms(BinaryReader reader, TR5Level lvl) @@ -212,31 +211,6 @@ public static void PopulateFloordata(BinaryReader reader, TR5Level lvl) } } - public static void VerifySPRMarker(BinaryReader reader) - { - string sprMarker = new(reader.ReadChars(SPRMarker.Length)); - Debug.Assert(sprMarker == SPRMarker); - } - - public static void PopulateSprites(BinaryReader reader, TR5Level lvl) - { - uint numSpriteTextures = reader.ReadUInt32(); - lvl.SpriteTextures = new(); - - for (int i = 0; i < numSpriteTextures; i++) - { - lvl.SpriteTextures.Add(TR2FileReadUtilities.ReadSpriteTexture(reader)); - } - - uint numSpriteSequences = reader.ReadUInt32(); - lvl.SpriteSequences = new(); - - for (int i = 0; i < numSpriteSequences; i++) - { - lvl.SpriteSequences.Add(TR2FileReadUtilities.ReadSpriteSequence(reader)); - } - } - public static void PopulateCameras(BinaryReader reader, TR5Level lvl) { //Cameras diff --git a/TRLevelToolset/Controls/DataControls/TR/TRSpriteAndObjTextureControl.cs b/TRLevelToolset/Controls/DataControls/TR/TRSpriteAndObjTextureControl.cs index 6843ecd41..badbe7bf0 100644 --- a/TRLevelToolset/Controls/DataControls/TR/TRSpriteAndObjTextureControl.cs +++ b/TRLevelToolset/Controls/DataControls/TR/TRSpriteAndObjTextureControl.cs @@ -11,8 +11,8 @@ public void Draw() if (ImGui.TreeNodeEx("Sprite and Object Texture Data", ImGuiTreeNodeFlags.OpenOnArrow)) { 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.Text("Sprite texture count: " + IOManager.CurrentLevelAsTR1?.Sprites.Sum(s => s.Value.Textures.Count)); + ImGui.Text("Sprite sequence count: " + IOManager.CurrentLevelAsTR1?.Sprites.Count); ImGui.TreePop(); } diff --git a/TRModelTransporter/Handlers/Textures/AbstractTextureImportHandler.cs b/TRModelTransporter/Handlers/Textures/AbstractTextureImportHandler.cs index 12f488c5f..e30bd218a 100644 --- a/TRModelTransporter/Handlers/Textures/AbstractTextureImportHandler.cs +++ b/TRModelTransporter/Handlers/Textures/AbstractTextureImportHandler.cs @@ -71,7 +71,7 @@ protected virtual void CollateSegments() _importSegments = new Dictionary>(); // Track existing sprite sequences to avoid duplication - List spriteSequences = new(GetExistingSpriteSequences()); + List existingSequences = GetExistingSpriteSequences().Keys.ToList(); foreach (D definition in _definitions) { if (!definition.HasGraphics || definition.IsDependencyOnly) @@ -101,8 +101,7 @@ protected virtual void CollateSegments() List spriteEntities = new(definition.SpriteSequences.Keys); foreach (E spriteEntity in spriteEntities) { - TRSpriteSequence existingSequence = spriteSequences.Find(s => s.SpriteID == Convert.ToInt32(spriteEntity)); - if (existingSequence != null) + if (existingSequences.Contains(spriteEntity)) { definition.SpriteSequences.Remove(spriteEntity); continue; @@ -111,7 +110,7 @@ protected virtual void CollateSegments() { // Add it to the tracking list in case we are importing 2 or more models // that share a sequence e.g. Dragon/Flamethrower and Flame_S_H - spriteSequences.Add(new TRSpriteSequence { SpriteID = Convert.ToInt32(spriteEntity) }); + existingSequences.Add(spriteEntity); } // The sequence will be merged later when we know the sprite texture offsets. @@ -232,8 +231,7 @@ protected virtual void MergeObjectTextures() protected virtual void MergeSpriteTextures() { - List levelSpriteTextures = GetExistingSpriteTextures(); - List levelSpriteSequences = GetExistingSpriteSequences(); + TRDictionary levelSpriteSequences = GetExistingSpriteSequences(); foreach (D definition in _definitions) { @@ -245,30 +243,18 @@ protected virtual void MergeSpriteTextures() foreach (E spriteEntity in definition.SpriteSequences.Keys) { TRSpriteSequence sequence = definition.SpriteSequences[spriteEntity]; - sequence.Offset = -1; - levelSpriteSequences.Add(sequence); + levelSpriteSequences[spriteEntity] = new(); foreach (int bitmapIndex in definition.SpriteTextures[spriteEntity].Keys) { List textures = definition.SpriteTextures[spriteEntity][bitmapIndex]; - - for (int i = 0; i < textures.Count; i++) - { - if (sequence.Offset == -1) - { - // mark the position of the first sprite only - sequence.Offset = (short)levelSpriteTextures.Count; - } - levelSpriteTextures.Add(textures[i].Texture); - } + levelSpriteSequences[spriteEntity].Textures.AddRange(textures.Select(t => t.Texture)); } } } } - protected abstract List GetExistingSpriteSequences(); - - protected abstract List GetExistingSpriteTextures(); + protected abstract TRDictionary GetExistingSpriteSequences(); protected abstract AbstractTexturePacker CreatePacker(); diff --git a/TRModelTransporter/Handlers/Textures/TR1/TR1TextureExportHandler.cs b/TRModelTransporter/Handlers/Textures/TR1/TR1TextureExportHandler.cs index 19b0210d2..18d1a957c 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.Find(s => s.SpriteID == (int)entity); + return _level.Sprites[entity]; } } diff --git a/TRModelTransporter/Handlers/Textures/TR1/TR1TextureImportHandler.cs b/TRModelTransporter/Handlers/Textures/TR1/TR1TextureImportHandler.cs index 1f7a8d296..7c9002f79 100644 --- a/TRModelTransporter/Handlers/Textures/TR1/TR1TextureImportHandler.cs +++ b/TRModelTransporter/Handlers/Textures/TR1/TR1TextureImportHandler.cs @@ -10,21 +10,14 @@ public class TR1TextureImportHandler : AbstractTextureImportHandler GetExistingSpriteSequences() + protected override TRDictionary GetExistingSpriteSequences() { - // Allow replacing the Explosion sequence in Vilcabamba (it's there but empty) - List sequences = _level.SpriteSequences; - TRSpriteSequence explosion = sequences.Find(s => s.SpriteID == (int)TR1Type.Explosion1_S_H); - if (explosion != null && explosion.NegativeLength == -1) + if (_level.Sprites[TR1Type.Explosion1_S_H]?.Textures.Count == 1) { - sequences.Remove(explosion); + // Allow replacing the Explosion sequence in Vilcabamba (it's there but empty, originally dynamite?) + _level.Sprites.Remove(TR1Type.Explosion1_S_H); } - return sequences; - } - - protected override List GetExistingSpriteTextures() - { - return _level.SpriteTextures; + return _level.Sprites; } protected override AbstractTexturePacker CreatePacker() diff --git a/TRModelTransporter/Handlers/Textures/TR2/TR2TextureExportHandler.cs b/TRModelTransporter/Handlers/Textures/TR2/TR2TextureExportHandler.cs index 5a3d0493a..d87786b20 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.Find(s => s.SpriteID == (int)entity); + return _level.Sprites[entity]; } } diff --git a/TRModelTransporter/Handlers/Textures/TR2/TR2TextureImportHandler.cs b/TRModelTransporter/Handlers/Textures/TR2/TR2TextureImportHandler.cs index 725507a3a..c44d37fd9 100644 --- a/TRModelTransporter/Handlers/Textures/TR2/TR2TextureImportHandler.cs +++ b/TRModelTransporter/Handlers/Textures/TR2/TR2TextureImportHandler.cs @@ -7,14 +7,9 @@ namespace TRModelTransporter.Handlers; public class TR2TextureImportHandler : AbstractTextureImportHandler { - protected override List GetExistingSpriteSequences() + protected override TRDictionary GetExistingSpriteSequences() { - return _level.SpriteSequences; - } - - protected override List GetExistingSpriteTextures() - { - return _level.SpriteTextures; + return _level.Sprites; } protected override AbstractTexturePacker CreatePacker() @@ -69,30 +64,12 @@ private void ApplyFlamePatch() _level.Models.Keys.Any(flameEnemies.Contains) ) { - 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); + TRSpriteSequence blastSequence = _level.Sprites[TR2Type.FireBlast_S_H]; + TRSpriteSequence explosionSequence = _level.Sprites[TR2Type.Explosion_S_H]; - if (grenadeSequence != -1) + if (blastSequence != null) { - if (blastSequence == -1) - { - TRSpriteSequence grenadeBlast = _level.SpriteSequences[grenadeSequence]; - _level.SpriteSequences.Add(new TRSpriteSequence - { - SpriteID = (int)TR2Type.FireBlast_S_H, - NegativeLength = grenadeBlast.NegativeLength, - Offset = grenadeBlast.Offset - }); - } - 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 < _level.SpriteSequences[grenadeSequence].NegativeLength * -1; i++) - { - _level.SpriteTextures[_level.SpriteSequences[blastSequence].Offset + i] = _level.SpriteTextures[_level.SpriteSequences[grenadeSequence].Offset + i]; - } - } + _level.Sprites[TR2Type.Explosion_S_H] = blastSequence; } } } diff --git a/TRModelTransporter/Handlers/Textures/TR3/TR3TextureExportHandler.cs b/TRModelTransporter/Handlers/Textures/TR3/TR3TextureExportHandler.cs index 910d0e651..b643d22f8 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.Find(s => s.SpriteID == (int)entity); + return _level.Sprites[entity]; } } diff --git a/TRModelTransporter/Handlers/Textures/TR3/TR3TextureImportHandler.cs b/TRModelTransporter/Handlers/Textures/TR3/TR3TextureImportHandler.cs index 14ff3b2ae..b687a694b 100644 --- a/TRModelTransporter/Handlers/Textures/TR3/TR3TextureImportHandler.cs +++ b/TRModelTransporter/Handlers/Textures/TR3/TR3TextureImportHandler.cs @@ -7,14 +7,9 @@ namespace TRModelTransporter.Handlers; public class TR3TextureImportHandler : AbstractTextureImportHandler { - protected override List GetExistingSpriteSequences() + protected override TRDictionary GetExistingSpriteSequences() { - return _level.SpriteSequences; - } - - protected override List GetExistingSpriteTextures() - { - return _level.SpriteTextures; + return _level.Sprites; } protected override AbstractTexturePacker CreatePacker() diff --git a/TRModelTransporter/Helpers/TRModelExtensions.cs b/TRModelTransporter/Helpers/TRModelExtensions.cs index b37dce410..f9bc85af4 100644 --- a/TRModelTransporter/Helpers/TRModelExtensions.cs +++ b/TRModelTransporter/Helpers/TRModelExtensions.cs @@ -12,19 +12,19 @@ public static class TRModelExtensions public static void ResetUnusedTextures(this TR1Level level) { ResetUnusedObjectTextures(level.ObjectTextures); - ResetUnusedSpriteTextures(level.SpriteTextures); + ResetUnusedSpriteTextures(level.Sprites.SelectMany(s => s.Value.Textures)); } public static void ResetUnusedTextures(this TR2Level level) { ResetUnusedObjectTextures(level.ObjectTextures); - ResetUnusedSpriteTextures(level.SpriteTextures); + ResetUnusedSpriteTextures(level.Sprites.SelectMany(s => s.Value.Textures)); } public static void ResetUnusedTextures(this TR3Level level) { ResetUnusedObjectTextures(level.ObjectTextures); - ResetUnusedSpriteTextures(level.SpriteTextures); + ResetUnusedSpriteTextures(level.Sprites.SelectMany(s => s.Value.Textures)); } private static void ResetUnusedObjectTextures(IEnumerable objectTextures) diff --git a/TRModelTransporter/Model/Textures/IndexedTRSpriteTexture.cs b/TRModelTransporter/Model/Textures/IndexedTRSpriteTexture.cs index 8d2fd80ed..303a7464d 100644 --- a/TRModelTransporter/Model/Textures/IndexedTRSpriteTexture.cs +++ b/TRModelTransporter/Model/Textures/IndexedTRSpriteTexture.cs @@ -40,18 +40,7 @@ public override AbstractIndexedTRTexture Clone() { Index = Index, Classification = Classification, - Texture = new TRSpriteTexture - { - Atlas = Texture.Atlas, - BottomSide = Texture.BottomSide, - Height = Texture.Height, - Width = Texture.Width, - LeftSide = Texture.LeftSide, - RightSide = Texture.RightSide, - TopSide = Texture.TopSide, - X = Texture.X, - Y = Texture.Y - } + Texture = _texture.Clone(), }; } } diff --git a/TRModelTransporter/Packing/AbstractTexturePacker.cs b/TRModelTransporter/Packing/AbstractTexturePacker.cs index 2b69e66fc..8bd7272ca 100644 --- a/TRModelTransporter/Packing/AbstractTexturePacker.cs +++ b/TRModelTransporter/Packing/AbstractTexturePacker.cs @@ -130,27 +130,20 @@ public Dictionary> GetObjectTextureSegme public Dictionary> GetSpriteSegments(E entity) { - Dictionary> segmentMap = new(); TRSpriteSequence sequence = GetSpriteSequence(entity); - if (sequence != null) + Dictionary> regionMap = new(); + foreach (TexturedTile tile in _tiles) { - List indices = new(); - for (int j = 0; j < sequence.NegativeLength * -1; j++) + List regions = tile.Rectangles + .Where(r => r.Textures.Any(s => s is IndexedTRSpriteTexture spr && sequence.Textures.Contains(spr.Texture))) + .ToList(); + if (regions.Count > 0) { - indices.Add(sequence.Offset + j); - } - - foreach (TexturedTile tile in _tiles) - { - List segments = tile.GetSpriteTextureIndexSegments(indices); - if (segments.Count > 0) - { - segmentMap[tile] = segments; - } + regionMap[tile] = regions; } } - return segmentMap; + return regionMap; } public Dictionary> GetSpriteTextureSegments(IEnumerable indices) diff --git a/TRModelTransporter/Packing/Types/TR1TexturePacker.cs b/TRModelTransporter/Packing/Types/TR1TexturePacker.cs index b419bcbb6..c3a9988d9 100644 --- a/TRModelTransporter/Packing/Types/TR1TexturePacker.cs +++ b/TRModelTransporter/Packing/Types/TR1TexturePacker.cs @@ -40,10 +40,11 @@ protected override List LoadObjectTextures() protected override List LoadSpriteTextures() { - List textures = new(Level.SpriteTextures.Count); - for (int i = 0; i < Level.SpriteTextures.Count; i++) + List sprites = Level.Sprites.SelectMany(s => s.Value.Textures).ToList(); + List textures = new(); + for (int i = 0; i < sprites.Count; i++) { - TRSpriteTexture texture = Level.SpriteTextures[i]; + TRSpriteTexture texture = sprites[i]; if (texture.IsValid()) { textures.Add(new IndexedTRSpriteTexture @@ -64,7 +65,7 @@ protected override List GetModelMeshes(TR1Type modelEntity) protected override TRSpriteSequence GetSpriteSequence(TR1Type entity) { - return Level.SpriteSequences.Find(s => s.SpriteID == (int)entity); + return Level.Sprites[entity]; } protected override IEnumerable GetAllModelTypes() diff --git a/TRModelTransporter/Packing/Types/TR2TexturePacker.cs b/TRModelTransporter/Packing/Types/TR2TexturePacker.cs index fd6cf214b..3adbb2571 100644 --- a/TRModelTransporter/Packing/Types/TR2TexturePacker.cs +++ b/TRModelTransporter/Packing/Types/TR2TexturePacker.cs @@ -37,10 +37,11 @@ protected override List LoadObjectTextures() protected override List LoadSpriteTextures() { - List textures = new(Level.SpriteTextures.Count); - for (int i = 0; i < Level.SpriteTextures.Count; i++) + List sprites = Level.Sprites.SelectMany(s => s.Value.Textures).ToList(); + List textures = new(); + for (int i = 0; i < sprites.Count; i++) { - TRSpriteTexture texture = Level.SpriteTextures[i]; + TRSpriteTexture texture = sprites[i]; if (texture.IsValid()) { textures.Add(new IndexedTRSpriteTexture @@ -61,7 +62,7 @@ protected override List GetModelMeshes(TR2Type modelEntity) protected override TRSpriteSequence GetSpriteSequence(TR2Type entity) { - return Level.SpriteSequences.Find(s => s.SpriteID == (int)entity); + return Level.Sprites[entity]; } protected override IEnumerable GetAllModelTypes() diff --git a/TRModelTransporter/Packing/Types/TR3TexturePacker.cs b/TRModelTransporter/Packing/Types/TR3TexturePacker.cs index db56bef22..89952db1b 100644 --- a/TRModelTransporter/Packing/Types/TR3TexturePacker.cs +++ b/TRModelTransporter/Packing/Types/TR3TexturePacker.cs @@ -37,10 +37,11 @@ protected override List LoadObjectTextures() protected override List LoadSpriteTextures() { - List textures = new(Level.SpriteTextures.Count); - for (int i = 0; i < Level.SpriteTextures.Count; i++) + List sprites = Level.Sprites.SelectMany(s => s.Value.Textures).ToList(); + List textures = new(); + for (int i = 0; i < sprites.Count; i++) { - TRSpriteTexture texture = Level.SpriteTextures[i]; + TRSpriteTexture texture = sprites[i]; if (texture.IsValid()) { textures.Add(new IndexedTRSpriteTexture @@ -61,7 +62,7 @@ protected override List GetModelMeshes(TR3Type modelEntity) protected override TRSpriteSequence GetSpriteSequence(TR3Type entity) { - return Level.SpriteSequences.Find(s => s.SpriteID == (int)entity); + return Level.Sprites[entity]; } protected override IEnumerable GetAllModelTypes() diff --git a/TRModelTransporter/Transport/TR2/TR2ModelExporter.cs b/TRModelTransporter/Transport/TR2/TR2ModelExporter.cs index 19fa60138..1ca9ed873 100644 --- a/TRModelTransporter/Transport/TR2/TR2ModelExporter.cs +++ b/TRModelTransporter/Transport/TR2/TR2ModelExporter.cs @@ -64,9 +64,6 @@ private static void AmendDXtre3DFlameTextures(TR2ModelDefinition definition) } // Ensures the flame sprite is aligned to OG - required for texture monitoring - TRSpriteSequence seq = definition.SpriteSequences[TR2Type.Flame_S_H]; - seq.Offset += 22; - Dictionary> defaultSprites = definition.SpriteTextures[TR2Type.Flame_S_H]; foreach (int id in defaultSprites.Keys) { diff --git a/TRRandomizerCore/Processors/TR2/TR2ModelAdjuster.cs b/TRRandomizerCore/Processors/TR2/TR2ModelAdjuster.cs index 6afffefd5..740a9fc5e 100644 --- a/TRRandomizerCore/Processors/TR2/TR2ModelAdjuster.cs +++ b/TRRandomizerCore/Processors/TR2/TR2ModelAdjuster.cs @@ -48,28 +48,26 @@ private void AdjustInstanceModels() { if (_levelInstance.Data.Models.ChangeKey(oldEntity, _modelRemap[oldEntity])) { - List modelEntities = _levelInstance.Data.Entities.FindAll(e => e.TypeID == oldEntity); - foreach (TR2Entity entity in modelEntities) - { - entity.TypeID = _modelRemap[oldEntity]; - } + ConvertEntities(oldEntity, _modelRemap[oldEntity]); } } // Repeat for sprites foreach (TR2Type oldEntity in _spriteRemap.Keys) { - TRSpriteSequence sprite = _levelInstance.Data.SpriteSequences.Find(s => s.SpriteID == (short)oldEntity); - if (sprite != null) + if (_levelInstance.Data.Sprites.ChangeKey(oldEntity, _spriteRemap[oldEntity])) { - sprite.SpriteID = (short)_spriteRemap[oldEntity]; - - List spriteEntities = _levelInstance.Data.Entities.FindAll(e => e.TypeID == oldEntity); - foreach (TR2Entity entity in spriteEntities) - { - entity.TypeID = _spriteRemap[oldEntity]; - } + ConvertEntities(oldEntity, _spriteRemap[oldEntity]); } } } + + private void ConvertEntities(TR2Type oldType, TR2Type newType) + { + IEnumerable spriteEntities = _levelInstance.Data.Entities.Where(e => e.TypeID == oldType); + foreach (TR2Entity entity in spriteEntities) + { + entity.TypeID = newType; + } + } } diff --git a/TRRandomizerCore/Randomizers/Shared/ItemSpriteRandomizer.cs b/TRRandomizerCore/Randomizers/Shared/ItemSpriteRandomizer.cs index ec616dc0e..e1e6fb583 100644 --- a/TRRandomizerCore/Randomizers/Shared/ItemSpriteRandomizer.cs +++ b/TRRandomizerCore/Randomizers/Shared/ItemSpriteRandomizer.cs @@ -1,76 +1,28 @@ using TRLevelControl.Model; using TRRandomizerCore.Helpers; -/// -/// Class used to Randomize the sprites of pickups and maybe keys items and/or secret items according to global settings chosen by the user -/// Today this class is usable by TR1 and TR2 randomizer with E=proper Entity type -/// namespace TRRandomizerCore.Randomizers; -public class ItemSpriteRandomizer where E : Enum +public class ItemSpriteRandomizer + where T : Enum { - /// - /// Used only if the sprite randomisation is active and is in OneItemPerGame Mode - /// - private E _randomSpriteID = default; + private T _randomSpriteID = default; - /// - /// List of pichups and weapons of the game - /// - public List StandardItemTypes { get; set; } - - /// - /// List of key items from the game - /// - public List KeyItemTypes { get; set; } - - /// - /// List of secret items - /// - public List SecretItemTypes { get; set; } - - /// - /// Sprite Sequence of the current level (should be left untouched it's just to ensure what types are in the level) - /// - public List Sequences { get; set; } - - /// - /// Sprite Textures of the current level (will be changed) - /// - public List Textures { get; set; } - - /// - /// Debug event - /// - public event EventHandler> TextureChanged; - - - /// - /// Setting entered by the user in Item Rando Window - /// It allows the sprite randomization to include key items in the mix - /// + public List StandardItemTypes { get; set; } + public List KeyItemTypes { get; set; } + public List SecretItemTypes { get; set; } + public TRDictionary Sequences { get; set; } public bool RandomizeKeyItemSprites { get; set; } - /// - /// Setting entered by the user in Item Rando Window - /// It allows the sprite randomization to include secrets items in the mix - /// public bool RandomizeSecretSprites { get; set; } - - /// - /// Setting entered by the user in Item Rando Window - /// Is set the randomization logic - /// public SpriteRandoMode Mode { get; set; } - /// - /// Apply the randomization of sprites according to settings - /// - /// Random generator + public event EventHandler> TextureChanged; + public void Randomize(Random generator) { - List replacementCandidates = new(); // Unique list of item types we wish to target in this level - List commonTypesInAllLevels = new();// for 1 item per game - Dictionary spriteTextures = new(); + List replacementCandidates = new(); + List commonTypesInAllLevels = new(); + Dictionary spriteTextures = new(); commonTypesInAllLevels.AddRange(StandardItemTypes); replacementCandidates.AddRange(StandardItemTypes); @@ -91,50 +43,45 @@ public void Randomize(Random generator) // E.g. on one iteration the grenade launcher may be changed to the small med; on the next, // the autos may be changed to the grenade launcher, but that has already changed to the small // med - by caching we can repurpose those that have already changed. - foreach (E entityType in replacementCandidates) + foreach (T entityType in replacementCandidates) { - TRSpriteSequence spriteSequence = Sequences.Find(s => s.SpriteID == Convert.ToInt32(entityType)); + TRSpriteSequence spriteSequence = Sequences[entityType]; if (spriteSequence != null) { - spriteTextures[entityType] = Textures[spriteSequence.Offset]; + spriteTextures[entityType] = spriteSequence.Textures.First(); } } // The cache indicates exacty what's in the level, so the keys become the candidate list replacementCandidates = spriteTextures.Keys.ToList(); - E replacementSpriteID = default; + T replacementSpriteID = default; if (Mode == SpriteRandoMode.OneSpritePerGame) { - if (EqualityComparer.Default.Equals(_randomSpriteID, default)) + if (EqualityComparer.Default.Equals(_randomSpriteID, default)) { - // I choose just once among pickups that should be in everylevel _randomSpriteID = commonTypesInAllLevels[generator.Next(0, commonTypesInAllLevels.Count)]; } replacementSpriteID = _randomSpriteID; } else if (Mode == SpriteRandoMode.OneSpritePerLevel) { - //I chose 1 random type among the items to switch replacementSpriteID = replacementCandidates[generator.Next(0, replacementCandidates.Count)]; } - // Carry out the actual replacements - foreach (E entityType in replacementCandidates) + foreach (T entityType in replacementCandidates) { if (Mode == SpriteRandoMode.Default) { - //I Chose the random item to replace with (there is a small chance it gets replaced with itslef... but i think thats ok :D ) replacementSpriteID = replacementCandidates[generator.Next(0, replacementCandidates.Count)]; } - // Get this type's current sequence - TRSpriteSequence currentSpriteSequence = Sequences.Find(s => s.SpriteID == Convert.ToInt32(entityType)); - // Get the replacement texture and replace this type's texture with it if it exists + TRSpriteSequence currentSpriteSequence = Sequences[entityType]; if (spriteTextures.ContainsKey(replacementSpriteID)) { - Textures[currentSpriteSequence.Offset] = spriteTextures[replacementSpriteID]; - TextureChanged?.Invoke(this, new SpriteEventArgs + currentSpriteSequence.Textures.Clear(); + currentSpriteSequence.Textures.Add(spriteTextures[replacementSpriteID]); + TextureChanged?.Invoke(this, new() { OldSprite = entityType, NewSprite = replacementSpriteID diff --git a/TRRandomizerCore/Randomizers/TR1/TR1ItemRandomizer.cs b/TRRandomizerCore/Randomizers/TR1/TR1ItemRandomizer.cs index c425d3068..35fcff745 100644 --- a/TRRandomizerCore/Randomizers/TR1/TR1ItemRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR1/TR1ItemRandomizer.cs @@ -523,9 +523,7 @@ private void RandomizeSprites() } } - _spriteRandomizer.Sequences = _levelInstance.Data.SpriteSequences; - _spriteRandomizer.Textures = _levelInstance.Data.SpriteTextures; - + _spriteRandomizer.Sequences = _levelInstance.Data.Sprites; _spriteRandomizer.Randomize(_generator); } diff --git a/TRRandomizerCore/Randomizers/TR1/TR1SecretRandomizer.cs b/TRRandomizerCore/Randomizers/TR1/TR1SecretRandomizer.cs index 253bdb8c6..99a0ea131 100644 --- a/TRRandomizerCore/Randomizers/TR1/TR1SecretRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR1/TR1SecretRandomizer.cs @@ -876,7 +876,7 @@ protected override void ProcessImpl() TR1Type puzzlePickupType = _modelReplacements[puzzleModelType]; level.Data.Models.ChangeKey(secretModelType, puzzleModelType); - level.Data.SpriteSequences.Find(s => s.SpriteID == (int)secretPickupType).SpriteID = (int)puzzlePickupType; + level.Data.Sprites.ChangeKey(secretPickupType, puzzlePickupType); if (secretModelType == TR1Type.SecretScion_M_H && _outer.Are3DPickupsEnabled()) { diff --git a/TRRandomizerCore/Randomizers/TR2/TR2ItemRandomizer.cs b/TRRandomizerCore/Randomizers/TR2/TR2ItemRandomizer.cs index d5abc385d..6731558d7 100644 --- a/TRRandomizerCore/Randomizers/TR2/TR2ItemRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR2/TR2ItemRandomizer.cs @@ -183,12 +183,7 @@ private void RandomizeSprites() #endif } - // 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; - _spriteRandomizer.Textures = _levelInstance.Data.SpriteTextures; - - //Calling the actual randomization + _spriteRandomizer.Sequences = _levelInstance.Data.Sprites; _spriteRandomizer.Randomize(_generator); } diff --git a/TRRandomizerCore/Randomizers/TR2/TR2SecretRandomizer.cs b/TRRandomizerCore/Randomizers/TR2/TR2SecretRandomizer.cs index 5caf958ed..3d7a689bb 100644 --- a/TRRandomizerCore/Randomizers/TR2/TR2SecretRandomizer.cs +++ b/TRRandomizerCore/Randomizers/TR2/TR2SecretRandomizer.cs @@ -184,13 +184,8 @@ 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 = 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); - - List textures = level.Data.SpriteTextures; - (textures[jadeSequence.Offset], textures[stoneSequence.Offset]) - = (textures[stoneSequence.Offset], textures[jadeSequence.Offset]); + (level.Data.Sprites[TR2Type.JadeSecret_S_P].Textures, level.Data.Sprites[TR2Type.StoneSecret_S_P].Textures) + = (level.Data.Sprites[TR2Type.StoneSecret_S_P].Textures, level.Data.Sprites[TR2Type.JadeSecret_S_P].Textures); } private static void AddDamageControl(TR2CombinedLevel level, List locations) diff --git a/TRRandomizerCore/Textures/DynamicTextureBuilder.cs b/TRRandomizerCore/Textures/DynamicTextureBuilder.cs index 8b944ffdc..e043c2f00 100644 --- a/TRRandomizerCore/Textures/DynamicTextureBuilder.cs +++ b/TRRandomizerCore/Textures/DynamicTextureBuilder.cs @@ -79,9 +79,21 @@ public DynamicTextureTarget Build(TR1CombinedLevel level) defaultObjectTextures.Add(f.Texture); foreach (TRRoomSprite sprite in room.RoomData.Sprites) { + // Temporary until room sprites store type IDs and not offsets + TR1Type spriteID = default; + int offset = 0; + foreach (var (type, sequence) in level.Data.Sprites) + { + if (sprite.Texture >= offset && sprite.Texture < offset + sequence.Textures.Count) + { + spriteID = type; + break; + } + offset += sequence.Textures.Count; + } + // Only add ones that aren't also pickups - if (level.Data.SpriteSequences.Find(s => s.Offset == sprite.Texture - && level.Data.Entities.Find(e => e.TypeID == (TR1Type)s.SpriteID) != null) == null) + if (spriteID != default && !level.Data.Entities.Any(e => e.TypeID == spriteID)) { defaultSpriteTextures.Add(sprite.Texture); } @@ -376,13 +388,19 @@ private static void AddMeshTextures(TRMesh mesh, ISet textures) private static void AddSpriteTextures(TR1Level level, TR1Type spriteID, ISet textures) { - TRSpriteSequence sequence = level.SpriteSequences.Find(s => s.SpriteID == (int)spriteID); - if (sequence != null) + // Temporary until texture packing doesn't need index references + int offset = 0; + foreach (var (type, sequence) in level.Sprites) { - for (int i = 0; i < sequence.NegativeLength * -1; i++) + if (type == spriteID) { - textures.Add(sequence.Offset + i); + for (int i = 0; i < sequence.Textures.Count; i++) + { + textures.Add(offset + i); + } + return; } + offset += sequence.Textures.Count; } } diff --git a/TRTexture16Importer/Textures/Mapping/AbstractTextureMapping.cs b/TRTexture16Importer/Textures/Mapping/AbstractTextureMapping.cs index 6e8aff8fb..612d62233 100644 --- a/TRTexture16Importer/Textures/Mapping/AbstractTextureMapping.cs +++ b/TRTexture16Importer/Textures/Mapping/AbstractTextureMapping.cs @@ -34,8 +34,7 @@ protected AbstractTextureMapping(L level) protected abstract List GetPalette8(); protected abstract List GetPalette16(); protected abstract int ImportColour(Color colour); - protected abstract List GetSpriteSequences(); - protected abstract List GetSpriteTextures(); + protected abstract TRDictionary GetSpriteSequences(); protected abstract Bitmap GetTile(int tileIndex); protected abstract void SetTile(int tileIndex, Bitmap bitmap); @@ -412,26 +411,22 @@ 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(); - List spriteTextures = GetSpriteTextures(); - - int spriteID = Convert.ToInt32(source.SpriteSequence); - TRSpriteSequence sequence = spriteSequences.Find(s => s.SpriteID == spriteID); + TRDictionary spriteSequences = GetSpriteSequences(); + TRSpriteSequence sequence = spriteSequences[source.SpriteSequence]; if (sequence == null) { return; } - StaticMapping[source] = new List(); + StaticMapping[source] = new(); - // An assumption is made here that each variant in the source will have the same number - // of rectangles. We only want to define targets for the number of source rectangles, rather + // We only want to define targets for the number of source rectangles, rather // than the total number of sprites. int numTargets = source.VariantMap[source.Variants[0]].Count; - for (int j = 0; j < numTargets; j++) + for (int j = 0; j < numTargets && j < sequence.Textures.Count; j++) { - TRSpriteTexture sprite = spriteTextures[sequence.Offset + j]; - StaticMapping[source].Add(new StaticTextureTarget + TRSpriteTexture sprite = sequence.Textures[j]; + StaticMapping[source].Add(new() { Segment = j, Tile = sprite.Atlas, diff --git a/TRTexture16Importer/Textures/Mapping/TR1TextureMapping.cs b/TRTexture16Importer/Textures/Mapping/TR1TextureMapping.cs index edc91d418..e999a7a8f 100644 --- a/TRTexture16Importer/Textures/Mapping/TR1TextureMapping.cs +++ b/TRTexture16Importer/Textures/Mapping/TR1TextureMapping.cs @@ -49,14 +49,9 @@ protected override List GetModelMeshes(TR1Type entity) return _level.Models.ContainsKey(entity) ? _level.Models[entity].Meshes : null; } - protected override List GetSpriteSequences() + protected override TRDictionary GetSpriteSequences() { - return _level.SpriteSequences; - } - - protected override List GetSpriteTextures() - { - return _level.SpriteTextures; + return _level.Sprites; } protected override Bitmap GetTile(int tileIndex) diff --git a/TRTexture16Importer/Textures/Mapping/TR2TextureMapping.cs b/TRTexture16Importer/Textures/Mapping/TR2TextureMapping.cs index e08b9ea4c..859b5ac74 100644 --- a/TRTexture16Importer/Textures/Mapping/TR2TextureMapping.cs +++ b/TRTexture16Importer/Textures/Mapping/TR2TextureMapping.cs @@ -45,14 +45,9 @@ protected override List GetModelMeshes(TR2Type entity) return _level.Models.ContainsKey(entity) ? _level.Models[entity].Meshes : null; } - protected override List GetSpriteSequences() + protected override TRDictionary GetSpriteSequences() { - return _level.SpriteSequences; - } - - protected override List GetSpriteTextures() - { - return _level.SpriteTextures; + return _level.Sprites; } protected override Bitmap GetTile(int tileIndex) diff --git a/TRTexture16Importer/Textures/Mapping/TR3TextureMapping.cs b/TRTexture16Importer/Textures/Mapping/TR3TextureMapping.cs index bb2383378..460d85306 100644 --- a/TRTexture16Importer/Textures/Mapping/TR3TextureMapping.cs +++ b/TRTexture16Importer/Textures/Mapping/TR3TextureMapping.cs @@ -46,14 +46,9 @@ protected override List GetModelMeshes(TR3Type entity) return _level.Models.ContainsKey(entity) ? _level.Models[entity].Meshes : null; } - protected override List GetSpriteSequences() + protected override TRDictionary GetSpriteSequences() { - return _level.SpriteSequences; - } - - protected override List GetSpriteTextures() - { - return _level.SpriteTextures; + return _level.Sprites; } protected override Bitmap GetTile(int tileIndex)