2
2
using OpenLoco . Dat . Data ;
3
3
using OpenLoco . Dat . Objects . Sound ;
4
4
using OpenLoco . Dat . Types ;
5
+ using System ;
6
+ using System . Numerics ;
5
7
using System . Text ;
6
8
7
9
namespace OpenLoco . Dat . FileParsing
@@ -123,8 +125,6 @@ public static void Save(string filename, string objName, SourceGame sourceGame,
123
125
logger . Info ( $ "{ objName } successfully saved to { filename } ") ;
124
126
}
125
127
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 ( ) ;
128
128
public static byte [ ] Encode ( SawyerEncoding encoding , ReadOnlySpan < byte > data )
129
129
=> data . ToArray ( ) ;
130
130
@@ -134,7 +134,7 @@ public static byte[] Encode(SawyerEncoding encoding, ReadOnlySpan<byte> data)
134
134
// SawyerEncoding.Uncompressed => data.ToArray(),
135
135
// SawyerEncoding.RunLengthSingle => EncodeRunLengthSingle(data),
136
136
// SawyerEncoding.RunLengthMulti => throw new NotImplementedException(),
137
- // SawyerEncoding.Rotate => throw new NotImplementedException( ),
137
+ // SawyerEncoding.Rotate => EncodeRotate(data ),
138
138
// _ => throw new InvalidDataException("Unknown chunk encoding scheme"),
139
139
// };
140
140
@@ -190,6 +190,29 @@ public static byte[] EncodeRunLengthSingle(ReadOnlySpan<byte> data)
190
190
return buffer . ToArray ( ) ;
191
191
}
192
192
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
+
193
216
public static MemoryStream WriteLocoObjectStream ( string objName , SourceGame sourceGame , SawyerEncoding encoding , ILogger logger , ILocoObject obj , bool allowWritingAsVanilla )
194
217
{
195
218
using var rawObjStream = new MemoryStream ( ) ;
@@ -312,98 +335,5 @@ public static void SaveG1(string filename, G1Dat g1)
312
335
SaveImageTable ( g1 . G1Elements , fs ) ;
313
336
}
314
337
}
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
- //}
408
338
}
409
339
}
0 commit comments