diff --git a/OpenRA.Mods.Cnc/FileFormats/VqaVideo.cs b/OpenRA.Mods.Cnc/FileFormats/VqaVideo.cs index 5d60474839..47d1451a5c 100644 --- a/OpenRA.Mods.Cnc/FileFormats/VqaVideo.cs +++ b/OpenRA.Mods.Cnc/FileFormats/VqaVideo.cs @@ -332,7 +332,7 @@ namespace OpenRA.Mods.Cnc.FileFormats if (!cbpIsCompressed) cbf = (byte[])cbp.Clone(); else - LCWDecodeInto(cbp, cbf); + LCWCompression.DecodeInto(cbp, cbf); chunkBufferOffset = currentChunkBuffer = 0; } @@ -352,7 +352,7 @@ namespace OpenRA.Mods.Cnc.FileFormats s.ReadBytes(fileBuffer, 0, subchunkLength); Array.Clear(cbf, 0, cbf.Length); Array.Clear(cbfBuffer, 0, cbfBuffer.Length); - var decodeCount = LCWDecodeInto(fileBuffer, cbfBuffer, decodeMode ? 1 : 0, decodeMode); + var decodeCount = LCWCompression.DecodeInto(fileBuffer, cbfBuffer, decodeMode ? 1 : 0, decodeMode); if ((videoFlags & 0x10) == 16) { var p = 0; @@ -406,7 +406,7 @@ namespace OpenRA.Mods.Cnc.FileFormats // Frame data case "VPTZ": - LCWDecodeInto(s.ReadBytes(subchunkLength), origData); + LCWCompression.DecodeInto(s.ReadBytes(subchunkLength), origData); // This is the last subchunk return; @@ -414,9 +414,9 @@ namespace OpenRA.Mods.Cnc.FileFormats Array.Clear(origData, 0, origData.Length); s.ReadBytes(fileBuffer, 0, subchunkLength); if (fileBuffer[0] != 0) - vtprSize = LCWDecodeInto(fileBuffer, origData); + vtprSize = LCWCompression.DecodeInto(fileBuffer, origData); else - LCWDecodeInto(fileBuffer, origData, 1, true); + LCWCompression.DecodeInto(fileBuffer, origData, 1, true); return; case "VPTR": Array.Clear(origData, 0, origData.Length); @@ -541,75 +541,5 @@ namespace OpenRA.Mods.Cnc.FileFormats } } } - - // TODO: Maybe replace this with LCWCompression.DecodeInto again later - public static int LCWDecodeInto(byte[] src, byte[] dest, int srcOffset = 0, bool reverse = false) - { - var ctx = new FastByteReader(src, srcOffset); - var destIndex = 0; - while (true) - { - var i = ctx.ReadByte(); - if ((i & 0x80) == 0) - { - // case 2 - var secondByte = ctx.ReadByte(); - var count = ((i & 0x70) >> 4) + 3; - var rpos = ((i & 0xf) << 8) + secondByte; - - if (destIndex + count > dest.Length) - return destIndex; - - // Replicate previous - var srcIndex = destIndex - rpos; - if (srcIndex > destIndex) - throw new NotImplementedException($"srcIndex > destIndex {srcIndex} {destIndex}"); - - for (var j = 0; j < count; j++) - { - if (destIndex - srcIndex == 1) - dest[destIndex + j] = dest[destIndex - 1]; - else - dest[destIndex + j] = dest[srcIndex + j]; - } - - destIndex += count; - } - else if ((i & 0x40) == 0) - { - // case 1 - var count = i & 0x3F; - if (count == 0) - return destIndex; - - ctx.CopyTo(dest, destIndex, count); - destIndex += count; - } - else - { - var count3 = i & 0x3F; - if (count3 == 0x3E) - { - // case 4 - var count = ctx.ReadWord(); - var color = ctx.ReadByte(); - - for (var end = destIndex + count; destIndex < end; destIndex++) - dest[destIndex] = color; - } - else - { - // If count3 == 0x3F it's case 5, else case 3 - var count = count3 == 0x3F ? ctx.ReadWord() : count3 + 3; - var srcIndex = reverse ? destIndex - ctx.ReadWord() : ctx.ReadWord(); - if (srcIndex >= destIndex) - throw new NotImplementedException($"srcIndex >= destIndex {srcIndex} {destIndex}"); - - for (var end = destIndex + count; destIndex < end; destIndex++) - dest[destIndex] = dest[srcIndex++]; - } - } - } - } } } diff --git a/OpenRA.Mods.Cnc/Graphics/VoxelLoader.cs b/OpenRA.Mods.Cnc/Graphics/VoxelLoader.cs index 52ad36a8b6..f3baca2dd5 100644 --- a/OpenRA.Mods.Cnc/Graphics/VoxelLoader.cs +++ b/OpenRA.Mods.Cnc/Graphics/VoxelLoader.cs @@ -108,10 +108,10 @@ namespace OpenRA.Mods.Cnc.Graphics return null; var v = l.VoxelMap[(byte)x, (byte)y]; - if (v == null || !v.ContainsKey((byte)z)) + if (v == null || !v.TryGetValue((byte)z, out var element)) return null; - return l.VoxelMap[(byte)x, (byte)y][(byte)z]; + return element; } // Cull slices without any visible faces diff --git a/OpenRA.Mods.Cnc/SpriteLoaders/TmpTSLoader.cs b/OpenRA.Mods.Cnc/SpriteLoaders/TmpTSLoader.cs index 09a6c0d1b6..a5fb452ab5 100644 --- a/OpenRA.Mods.Cnc/SpriteLoaders/TmpTSLoader.cs +++ b/OpenRA.Mods.Cnc/SpriteLoaders/TmpTSLoader.cs @@ -120,8 +120,7 @@ namespace OpenRA.Mods.Cnc.SpriteLoaders for (var j = 0; j < size.Height; j++) { var start = (j - frameBounds.Y) * frameBounds.Width + (size.Width - width) / 2 - frameBounds.X; - for (var i = 0; i < width; i++) - data[start + i] = s.ReadUInt8(); + s.ReadBytes(data, start, width); width += (j < size.Height / 2 - 1 ? 1 : -1) * 4; } diff --git a/OpenRA.Mods.Common/FileFormats/RLEZerosCompression.cs b/OpenRA.Mods.Common/FileFormats/RLEZerosCompression.cs index 5f0049023c..fe41bf809a 100644 --- a/OpenRA.Mods.Common/FileFormats/RLEZerosCompression.cs +++ b/OpenRA.Mods.Common/FileFormats/RLEZerosCompression.cs @@ -9,6 +9,8 @@ */ #endregion +using System; + namespace OpenRA.Mods.Common.FileFormats { // Run length encoded sequences of zeros (aka Format2) @@ -24,8 +26,8 @@ namespace OpenRA.Mods.Common.FileFormats if (cmd == 0) { var count = r.ReadByte(); - while (count-- > 0) - dest[destIndex++] = 0; + Array.Clear(dest, destIndex, count); + destIndex += count; } else dest[destIndex++] = cmd;