Skip to content

Commit fdcb25a

Browse files
committed
implement EncodeRotate
1 parent 30c6b1f commit fdcb25a

File tree

1 file changed

+26
-96
lines changed

1 file changed

+26
-96
lines changed

Dat/FileParsing/SawyerStreamWriter.cs

Lines changed: 26 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
using OpenLoco.Dat.Data;
33
using OpenLoco.Dat.Objects.Sound;
44
using OpenLoco.Dat.Types;
5+
using System;
6+
using System.Numerics;
57
using System.Text;
68

79
namespace OpenLoco.Dat.FileParsing
@@ -123,8 +125,6 @@ public static void Save(string filename, string objName, SourceGame sourceGame,
123125
logger.Info($"{objName} successfully saved to {filename}");
124126
}
125127

126-
public static ReadOnlySpan<byte> WriteLocoObject(string objName, SourceGame sourceGame, SawyerEncoding encoding, ILogger logger, ILocoObject obj, bool allowWritingAsVanilla)
127-
=> WriteLocoObjectStream(objName, sourceGame, encoding, logger, obj, allowWritingAsVanilla).ToArray();
128128
public static byte[] Encode(SawyerEncoding encoding, ReadOnlySpan<byte> data)
129129
=> data.ToArray();
130130

@@ -134,7 +134,7 @@ public static byte[] Encode(SawyerEncoding encoding, ReadOnlySpan<byte> data)
134134
// SawyerEncoding.Uncompressed => data.ToArray(),
135135
// SawyerEncoding.RunLengthSingle => EncodeRunLengthSingle(data),
136136
// SawyerEncoding.RunLengthMulti => throw new NotImplementedException(),
137-
// SawyerEncoding.Rotate => throw new NotImplementedException(),
137+
// SawyerEncoding.Rotate => EncodeRotate(data),
138138
// _ => throw new InvalidDataException("Unknown chunk encoding scheme"),
139139
// };
140140

@@ -190,6 +190,29 @@ public static byte[] EncodeRunLengthSingle(ReadOnlySpan<byte> data)
190190
return buffer.ToArray();
191191
}
192192

193+
static byte[] EncodeRotate(ReadOnlySpan<byte> data)
194+
{
195+
using var buffer = new MemoryStream();
196+
197+
uint8_t code = 1;
198+
for (var i = 0; i < data.Length; ++i)
199+
{
200+
buffer.WriteByte(RotateLeft(data[i], code));
201+
code = (uint8_t)((code + 2) & 7);
202+
}
203+
204+
return buffer.ToArray();
205+
}
206+
207+
static uint8_t RotateLeft(uint8_t value, uint8_t shift)
208+
{
209+
shift &= 7; // Ensure shift is within 0-7 for 8-bit bytes
210+
return (uint8_t)((value << shift) | (value >> (8 - shift)));
211+
}
212+
213+
public static ReadOnlySpan<byte> WriteLocoObject(string objName, SourceGame sourceGame, SawyerEncoding encoding, ILogger logger, ILocoObject obj, bool allowWritingAsVanilla)
214+
=> WriteLocoObjectStream(objName, sourceGame, encoding, logger, obj, allowWritingAsVanilla).ToArray();
215+
193216
public static MemoryStream WriteLocoObjectStream(string objName, SourceGame sourceGame, SawyerEncoding encoding, ILogger logger, ILocoObject obj, bool allowWritingAsVanilla)
194217
{
195218
using var rawObjStream = new MemoryStream();
@@ -312,98 +335,5 @@ public static void SaveG1(string filename, G1Dat g1)
312335
SaveImageTable(g1.G1Elements, fs);
313336
}
314337
}
315-
316-
//public static ReadOnlySpan<byte> Encode(SawyerEncoding encoding, ReadOnlySpan<byte> data, ILogger? logger = null)
317-
//{
318-
// switch (encoding)
319-
// {
320-
// case SawyerEncoding.Uncompressed:
321-
// return data;
322-
// case SawyerEncoding.RunLengthSingle:
323-
// return EncodeRunLengthSingle(data);
324-
// //case SawyerEncoding.runLengthMulti:
325-
// // return encodeRunLengthMulti(decodeRunLengthSingle(data));
326-
// //case SawyerEncoding.rotate:
327-
// // return encodeRotate(data);
328-
// default:
329-
// logger?.Error("Unknown chunk encoding scheme");
330-
// throw new InvalidDataException("Unknown encoding");
331-
// }
332-
//}
333-
334-
//public static void WriteToFile(string filename, ReadOnlySpan<byte> s5Header, ReadOnlySpan<byte> objectHeader, ReadOnlySpan<byte> encodedData)
335-
//{
336-
// var stream = File.Create(filename);
337-
// stream.Write(s5Header);
338-
// stream.Write(objectHeader);
339-
// stream.Write(encodedData);
340-
// stream.Flush();
341-
// stream.Close();
342-
//}
343-
344-
// taken from openloco SawyerStreamReader::encodeRunLengthSingle
345-
// not sure why it doesn't work, but it doesn't work. gets the first 10 or so bytes correct for SIGC3.dat but then fails
346-
//private static Span<byte> EncodeRunLengthSingle(ReadOnlySpan<byte> data)
347-
//{
348-
// List<byte> buffer = [];
349-
// var src = 0; // ptr
350-
// var srcNormStart = 0; // ptr
351-
// var srcEnd = data.Length;
352-
// var count = 0;
353-
354-
// while (src < srcEnd - 1)
355-
// {
356-
// if ((count != 0 && data[src] == data[src + 1]) || count > 125)
357-
// {
358-
// buffer.Add((byte)(count - 1));
359-
// buffer.AddRange(Enumerable.Repeat(data[srcNormStart], count));
360-
// srcNormStart += count;
361-
// count = 0;
362-
// }
363-
364-
// if (data[src] == data[src + 1])
365-
// {
366-
// for (; count < 125 && src + count < srcEnd; count++)
367-
// {
368-
// if (data[src] != data[count])
369-
// {
370-
// break;
371-
// }
372-
// }
373-
374-
// buffer.Add((byte)(257 - count));
375-
// buffer.Add(data[src]);
376-
// src += count;
377-
// srcNormStart = src;
378-
// count = 0;
379-
// }
380-
// else
381-
// {
382-
// count++;
383-
// src++;
384-
// }
385-
// }
386-
387-
// if (data[src] == data[srcEnd - 1])
388-
// {
389-
// count++;
390-
// }
391-
392-
// if (count != 0)
393-
// {
394-
// buffer.Add((byte)(count - 1));
395-
// buffer.AddRange(Enumerable.Repeat(data[srcNormStart], count));
396-
// }
397-
398-
// // convert to span
399-
// Span<byte> encodedSpan = new byte[buffer.Count];
400-
// var counter = 0;
401-
// foreach (var b in buffer)
402-
// {
403-
// encodedSpan[counter++] = b;
404-
// }
405-
406-
// return encodedSpan;
407-
//}
408338
}
409339
}

0 commit comments

Comments
 (0)