Skip to content

Commit b0205d8

Browse files
authored
Merge pull request #3 from Kaioru/bitmaps
Add Bitmap and Audio data for PKG1 format
2 parents 90dd6a4 + 0699a9a commit b0205d8

File tree

14 files changed

+196
-53
lines changed

14 files changed

+196
-53
lines changed

src/Duey.Abstractions/Duey.Abstractions.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,8 @@
22

33
<Import Project="..\Source.targets" />
44

5+
<ItemGroup>
6+
<PackageReference Include="CommunityToolkit.HighPerformance" Version="8.4.0" />
7+
</ItemGroup>
8+
59
</Project>
Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
namespace Duey.Abstractions.Types;
22

3-
public struct DataAudio
4-
{
5-
public DataAudio(byte[] data) => Data = data;
6-
7-
public byte[] Data { get; }
8-
}
3+
public record struct DataAudio(
4+
Memory<byte> Data
5+
);
Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,8 @@
11
namespace Duey.Abstractions.Types;
22

3-
public struct DataBitmap
4-
{
5-
public DataBitmap(ushort width, ushort height, byte[] data)
6-
{
7-
Width = width;
8-
Height = height;
9-
Data = data;
10-
}
11-
12-
public ushort Width { get; }
13-
public ushort Height { get; }
14-
public byte[] Data { get; }
15-
}
3+
public record struct DataBitmap(
4+
ushort Width,
5+
ushort Height,
6+
DataBitmapFormat Format,
7+
Memory<byte> Data
8+
);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace Duey.Abstractions.Types;
2+
3+
public enum DataBitmapFormat
4+
{
5+
Rgba16,
6+
Rgba32,
7+
Bgra32,
8+
Unknown
9+
}
Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
11
namespace Duey.Abstractions.Types;
22

3-
public struct DataVector
4-
{
5-
public DataVector(int x, int y)
6-
{
7-
X = x;
8-
Y = y;
9-
}
10-
11-
public int X { get; }
12-
public int Y { get; }
13-
}
3+
public record struct DataVector(
4+
int X,
5+
int Y
6+
);
Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
{
22
"version": 1,
33
"dependencies": {
4-
".NETStandard,Version=v2.1": {}
4+
".NETStandard,Version=v2.1": {
5+
"CommunityToolkit.HighPerformance": {
6+
"type": "Direct",
7+
"requested": "[8.4.0, )",
8+
"resolved": "8.4.0",
9+
"contentHash": "flxspiBs0G/0GMp7IK2J2ijV9bTG6hEwFc/z6ekHqB6nwRJ4Ry2yLdx+TkbCUYFCl4XhABkAwomeKbT6zM2Zlg==",
10+
"dependencies": {
11+
"System.Runtime.CompilerServices.Unsafe": "6.1.0"
12+
}
13+
},
14+
"System.Runtime.CompilerServices.Unsafe": {
15+
"type": "Transitive",
16+
"resolved": "6.1.0",
17+
"contentHash": "5o/HZxx6RVqYlhKSq8/zronDkALJZUT2Vz0hx43f0gwe8mwlM0y2nYlqdBwLMzr262Bwvpikeb/yEwkAa5PADg=="
18+
}
19+
}
520
}
621
}

src/Duey.Provider.NX/NXPackage.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System.Collections;
22
using System.IO.MemoryMappedFiles;
3-
using System.Runtime.InteropServices;
43
using Duey.Abstractions;
54
using Duey.Provider.NX.Exceptions;
65
using Duey.Provider.NX.Headers;

src/Duey.Provider.NX/Tables/NXBitmapOffsetTable.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,6 @@ public override DataBitmap Get(NXPropertyBitmapHeader data)
2929
Package.Accessor.ReadArray(offset + 4, source, 0, sourceLength);
3030
LZ4Codec.Decode(source, target);
3131

32-
return new DataBitmap(data.Width, data.Height, target);
32+
return new DataBitmap(data.Width, data.Height, DataBitmapFormat.Bgra32, target);
3333
}
3434
}

src/Duey.Provider.NX/packages.lock.json

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,24 @@
1111
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
1212
}
1313
},
14+
"CommunityToolkit.HighPerformance": {
15+
"type": "Transitive",
16+
"resolved": "8.4.0",
17+
"contentHash": "flxspiBs0G/0GMp7IK2J2ijV9bTG6hEwFc/z6ekHqB6nwRJ4Ry2yLdx+TkbCUYFCl4XhABkAwomeKbT6zM2Zlg==",
18+
"dependencies": {
19+
"System.Runtime.CompilerServices.Unsafe": "6.1.0"
20+
}
21+
},
1422
"System.Runtime.CompilerServices.Unsafe": {
1523
"type": "Transitive",
16-
"resolved": "6.0.0",
17-
"contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg=="
24+
"resolved": "6.1.0",
25+
"contentHash": "5o/HZxx6RVqYlhKSq8/zronDkALJZUT2Vz0hx43f0gwe8mwlM0y2nYlqdBwLMzr262Bwvpikeb/yEwkAa5PADg=="
1826
},
1927
"duey.abstractions": {
20-
"type": "Project"
28+
"type": "Project",
29+
"dependencies": {
30+
"CommunityToolkit.HighPerformance": "[8.4.0, )"
31+
}
2132
}
2233
}
2334
}

src/Duey.Provider.WZ/FSDirectory.cs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
using System.Collections;
2-
using System.IO.MemoryMappedFiles;
31
using Duey.Abstractions;
42
using Duey.Provider.WZ.Crypto;
53
using Duey.Provider.WZ.Files;
@@ -8,21 +6,16 @@ namespace Duey.Provider.WZ;
86

97
public class FSDirectory : AbstractWZNode, IDataNodeCached, IDataDirectory
108
{
11-
private readonly string _path;
12-
private readonly XORCipher? _cipher;
13-
149
public FSDirectory(string path, XORCipher? cipher = null, IDataNode? parent = null)
1510
{
16-
_path = path;
17-
_cipher = cipher;
1811
Name = Path.GetFileName(path);
1912
Parent = parent ?? this;
2013
Cached = Directory
21-
.GetDirectories(_path)
22-
.Select(d => new FSDirectory(d, _cipher, this))
14+
.GetDirectories(path)
15+
.Select(d => new FSDirectory(d, cipher, this))
2316
.Concat<IDataNode>(Directory
24-
.GetFiles(_path, "*.img")
25-
.Select(f => new WZImage(f, _cipher, this)))
17+
.GetFiles(path, "*.img")
18+
.Select(f => new WZImage(f, cipher, this)))
2619
.ToDictionary(n => n.Name, n => n);
2720
}
2821

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using System.IO.Compression;
2+
using System.IO.MemoryMappedFiles;
3+
using Duey.Abstractions;
4+
using Duey.Abstractions.Types;
5+
using Duey.Provider.WZ.Codecs;
6+
using Duey.Provider.WZ.Crypto;
7+
8+
namespace Duey.Provider.WZ.Files.Extended;
9+
10+
public class WZPropertyCanvas : WZPropertyDeferred<DataBitmap>
11+
{
12+
public WZPropertyCanvas(
13+
MemoryMappedFile view,
14+
XORCipher cipher,
15+
int start,
16+
int offset,
17+
string name,
18+
IDataNode? parent = null
19+
) : base(view, cipher, start, offset, name, parent)
20+
{
21+
}
22+
23+
protected override DataBitmap Resolve(WZReader reader)
24+
{
25+
var width = reader.ReadCompressedInt();
26+
var height = reader.ReadCompressedInt();
27+
var format = reader.ReadCompressedInt() switch
28+
{
29+
0x002 => DataBitmapFormat.Rgba32,
30+
0x201 => DataBitmapFormat.Rgba16,
31+
_ => DataBitmapFormat.Unknown
32+
};
33+
var scale = reader.ReadByte();
34+
35+
reader.BaseStream.Position += 4;
36+
37+
var length = reader.ReadInt32();
38+
var header = reader.ReadBytes(3);
39+
var data = reader.ReadBytes(length - 3);
40+
41+
using var stream0 = new MemoryStream(data, false);
42+
using var stream1 = new DeflateStream(stream0, CompressionMode.Decompress);
43+
using var stream2 = new MemoryStream();
44+
45+
width >>= scale;
46+
height >>= scale;
47+
stream1.CopyTo(stream2);
48+
49+
return new DataBitmap((ushort)width, (ushort)height, format, stream2.ToArray());
50+
}
51+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using System.IO.MemoryMappedFiles;
2+
using Duey.Abstractions;
3+
using Duey.Provider.WZ.Codecs;
4+
using Duey.Provider.WZ.Crypto;
5+
6+
namespace Duey.Provider.WZ.Files;
7+
8+
public abstract class WZPropertyDeferred<T> : WZPropertyFile, IDataProperty<T>
9+
{
10+
public WZPropertyDeferred(
11+
MemoryMappedFile view,
12+
XORCipher cipher,
13+
int start,
14+
int offset,
15+
string name,
16+
IDataNode? parent = null
17+
) : base(view, cipher, start, offset, name, parent)
18+
{
19+
}
20+
21+
public T Resolve()
22+
{
23+
do _ = Children.ToList();
24+
while (!_startDeferred.HasValue);
25+
26+
using var stream = _view.CreateViewStream(_offset, 0, MemoryMappedFileAccess.Read);
27+
using var reader = new WZReader(stream, _cipher, _startDeferred.Value);
28+
29+
return Resolve(reader);
30+
}
31+
32+
protected abstract T Resolve(WZReader reader);
33+
}

src/Duey.Provider.WZ/Files/WZPropertyFile.cs

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,22 @@
33
using Duey.Abstractions.Types;
44
using Duey.Provider.WZ.Codecs;
55
using Duey.Provider.WZ.Crypto;
6+
using Duey.Provider.WZ.Files.Extended;
67
using Duey.Provider.WZ.Types;
78

89
namespace Duey.Provider.WZ.Files;
910

1011
public class WZPropertyFile : AbstractWZNode, IDataNode
1112
{
12-
private readonly MemoryMappedFile _view;
13-
private readonly XORCipher _cipher;
14-
private readonly int _start;
15-
private readonly int _offset;
13+
private static readonly Guid GUIDAudioFormatWav = new("05589f81-c356-11ce-bf01-00aa0055595a");
14+
private static readonly Guid GUIDAudioFormatNone = new("00000000-0000-0000-0000-000000000000");
15+
16+
protected readonly MemoryMappedFile _view;
17+
protected readonly XORCipher _cipher;
18+
protected readonly int _start;
19+
protected readonly int _offset;
20+
21+
protected int? _startDeferred;
1622

1723
public WZPropertyFile(MemoryMappedFile view, XORCipher cipher, int start, int offset, string name, IDataNode? parent = null)
1824
{
@@ -35,7 +41,8 @@ public override IEnumerable<IDataNode> Children
3541
using var reader = new WZReader(stream, _cipher, _start);
3642

3743
reader.ReadBoolean();
38-
reader.ReadByte();
44+
if (reader.ReadBoolean())
45+
reader.BaseStream.Position += 2;
3946

4047
var count = reader.ReadCompressedInt();
4148

@@ -92,12 +99,32 @@ public override IEnumerable<IDataNode> Children
9299
case "Property":
93100
yield return new WZPropertyFile(_view, _cipher, (int)reader.BaseStream.Position, _offset, name, this);
94101
break;
102+
case "Canvas":
103+
yield return new WZPropertyCanvas(_view, _cipher, (int)reader.BaseStream.Position, _offset, name, this);
104+
break;
95105
case "Shape2D#Vector2D":
96106
yield return new WZPropertyData<DataVector>(name, this, new DataVector(
97107
reader.ReadCompressedInt(),
98108
reader.ReadCompressedInt()
99109
));
100110
break;
111+
case "Sound_DX8":
112+
reader.ReadByte();
113+
114+
var length = reader.ReadCompressedInt();
115+
var duration = reader.ReadCompressedInt();
116+
117+
reader.BaseStream.Position += 1 + 16 + 16 + 2;
118+
119+
var format = new Guid(reader.ReadBytes(16));
120+
121+
if (format == GUIDAudioFormatWav)
122+
reader.BaseStream.Position += reader.ReadCompressedInt();
123+
124+
yield return new WZPropertyData<DataAudio>(name, this, new DataAudio(
125+
reader.ReadBytes(length)
126+
));
127+
break;
101128
}
102129

103130
reader.BaseStream.Position = position + size;
@@ -107,6 +134,8 @@ public override IEnumerable<IDataNode> Children
107134
throw new ArgumentOutOfRangeException();
108135
}
109136
}
137+
138+
_startDeferred = (int)reader.BaseStream.Position;
110139
}
111140
}
112141
}

src/Duey.Provider.WZ/packages.lock.json

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,24 @@
22
"version": 1,
33
"dependencies": {
44
".NETStandard,Version=v2.1": {
5+
"CommunityToolkit.HighPerformance": {
6+
"type": "Transitive",
7+
"resolved": "8.4.0",
8+
"contentHash": "flxspiBs0G/0GMp7IK2J2ijV9bTG6hEwFc/z6ekHqB6nwRJ4Ry2yLdx+TkbCUYFCl4XhABkAwomeKbT6zM2Zlg==",
9+
"dependencies": {
10+
"System.Runtime.CompilerServices.Unsafe": "6.1.0"
11+
}
12+
},
13+
"System.Runtime.CompilerServices.Unsafe": {
14+
"type": "Transitive",
15+
"resolved": "6.1.0",
16+
"contentHash": "5o/HZxx6RVqYlhKSq8/zronDkALJZUT2Vz0hx43f0gwe8mwlM0y2nYlqdBwLMzr262Bwvpikeb/yEwkAa5PADg=="
17+
},
518
"duey.abstractions": {
6-
"type": "Project"
19+
"type": "Project",
20+
"dependencies": {
21+
"CommunityToolkit.HighPerformance": "[8.4.0, )"
22+
}
723
}
824
}
925
}

0 commit comments

Comments
 (0)