Skip to content

Commit

Permalink
flip textures horizontally in viewport, improve navigation performanc…
Browse files Browse the repository at this point in the history
…e on large, non-previewable assets
  • Loading branch information
parzivail committed Aug 22, 2021
1 parent 4af51ca commit 8ae9a2b
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 66 deletions.
5 changes: 3 additions & 2 deletions Prism/AssetStream.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.IO;
using System;
using System.IO;

namespace Prism
{
internal record AssetStream(ulong Uid, ulong Magic, string Filename, BinaryReader Stream);
internal record AssetStream(ulong Uid, ulong Magic, string Filename, Func<BinaryReader> StreamProvider);
}
29 changes: 19 additions & 10 deletions Prism/PrismForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -249,14 +249,14 @@ private static EventHandler CreateDumpEventHandler(string filter, Action<string>
private void DumpSelectionAsBin(string fileName)
{
var streamData = GetAssetStream(_assetList.SelectedObject);
using var stream = streamData.Stream;
using var stream = streamData.StreamProvider.Invoke();
DumpHelper.DumpBin(fileName, stream.BaseStream);
}

private void DumpSelectionAsObj(string fileName)
{
var streamData = GetAssetStream(_assetList.SelectedObject);
using var stream = streamData.Stream;
using var stream = streamData.StreamProvider.Invoke();

var header = MeshHeader.Read(stream);

Expand Down Expand Up @@ -305,7 +305,7 @@ private void DumpSelectionAsObj(string fileName)
private void DumpSelectionAsDds(string fileName)
{
var streamData = GetAssetStream(_assetList.SelectedObject);
using var stream = streamData.Stream;
using var stream = streamData.StreamProvider.Invoke();

var texture = Texture.Read(stream);
var surface = texture.ReadSurfaceBytes(stream);
Expand All @@ -324,8 +324,8 @@ private AssetStream GetAssetStream(object o)

return container switch
{
ForgeAsset forgeAsset => new AssetStream(entry.Uid, entry.MetaData.FileType, entry.MetaData.FileName, forgeAsset.GetDataStream(_openedForge)),
_ => new AssetStream(entry.Uid, entry.MetaData.FileType, entry.MetaData.FileName, _openedForge.GetEntryStream(entry))
ForgeAsset forgeAsset => new AssetStream(entry.Uid, entry.MetaData.FileType, entry.MetaData.FileName, () => forgeAsset.GetDataStream(_openedForge)),
_ => new AssetStream(entry.Uid, entry.MetaData.FileType, entry.MetaData.FileName, () => _openedForge.GetEntryStream(entry))
};
}
case FlatArchiveEntry flatArchiveEntry:
Expand All @@ -334,10 +334,13 @@ private AssetStream GetAssetStream(object o)
if (container is not ForgeAsset forgeAsset)
return null;

using var assetStream = forgeAsset.GetDataStream(_openedForge);
var arc = FlatArchive.Read(assetStream);
return new AssetStream(flatArchiveEntry.MetaData.Uid, flatArchiveEntry.MetaData.FileType, flatArchiveEntry.MetaData.FileName,
arc.GetEntryStream(assetStream.BaseStream, flatArchiveEntry.MetaData.Uid));
() =>
{
using var assetStream = forgeAsset.GetDataStream(_openedForge);
var arc = FlatArchive.Read(assetStream);
return arc.GetEntryStream(assetStream.BaseStream, flatArchiveEntry.MetaData.Uid);
});
}
}

Expand Down Expand Up @@ -400,7 +403,7 @@ private void SetupAssetList()
};
}
});

_assetList.Columns.Add(new OLVColumn("Type", null)
{
Width = 100,
Expand Down Expand Up @@ -585,11 +588,11 @@ private void UpdateAbility(AssetStream assetStream)

private void PreviewAsset(AssetStream assetStream)
{
using var stream = assetStream.Stream;
switch (MagicHelper.GetFiletype(assetStream.Magic))
{
case AssetType.Mesh:
{
using var stream = assetStream.StreamProvider.Invoke();
var header = MeshHeader.Read(stream);
var mesh = CompiledMeshObject.Read(stream, header);

Expand All @@ -608,6 +611,7 @@ private void PreviewAsset(AssetStream assetStream)
}
case AssetType.Texture:
{
using var stream = assetStream.StreamProvider.Invoke();
var texture = Texture.Read(stream);
using var image = Pfim.Pfim.FromStream(DdsHelper.GetDdsStream(texture, texture.ReadSurfaceBytes(stream)));

Expand Down Expand Up @@ -675,6 +679,7 @@ private void PreviewAsset(AssetStream assetStream)
{
case Magic.Mesh:
{
using var stream = assetStream.StreamProvider.Invoke();
var mp = Mesh.Read(stream);

entries = new List<TreeListViewEntry>
Expand All @@ -691,6 +696,7 @@ private void PreviewAsset(AssetStream assetStream)
}
case Magic.Material:
{
using var stream = assetStream.StreamProvider.Invoke();
var mc = Material.Read(stream);

entries = new List<TreeListViewEntry>
Expand All @@ -706,6 +712,7 @@ private void PreviewAsset(AssetStream assetStream)
}
case Magic.TextureMapSpec:
{
using var stream = assetStream.StreamProvider.Invoke();
var mc = TextureMapSpec.Read(stream);

entries = new List<TreeListViewEntry>
Expand All @@ -720,6 +727,7 @@ private void PreviewAsset(AssetStream assetStream)
}
case Magic.TextureMap:
{
using var stream = assetStream.StreamProvider.Invoke();
var mc = TextureMap.Read(stream);

entries = new List<TreeListViewEntry>
Expand All @@ -738,6 +746,7 @@ private void PreviewAsset(AssetStream assetStream)
}
case Magic.R6AIWorldComponent:
{
using var stream = assetStream.StreamProvider.Invoke();
var am = R6AIWorldComponent.Read(stream);

entries = new List<TreeListViewEntry>
Expand Down
3 changes: 2 additions & 1 deletion Prism/Render/SurfaceRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ public void SetTexture(SKBitmap bitmap)
}

ContentTransformation = SKMatrix.Identity
.PreConcat(SKMatrix.CreateTranslation((_imageControl.Width - bitmap.Width) / 2f, (_imageControl.Height - bitmap.Height) / 2f));
.PreConcat(SKMatrix.CreateTranslation((_imageControl.Width - bitmap.Width) / 2f, (_imageControl.Height + bitmap.Height) / 2f))
.PreConcat(SKMatrix.CreateScale(1, -1));

_imageControl.Invalidate();
}
Expand Down
6 changes: 3 additions & 3 deletions RainbowForge/Core/DataBlock/ChunkedDataBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public ChunkedDataBlock(ChunkedData[] chunks, bool isPacked, uint packedLength,
UnpackedLength = unpackedLength;
}

public MemoryStream GetDataStream(BinaryReader r)
public Stream GetDataStream(BinaryReader r)
{
var ms = new MemoryStream();

Expand All @@ -33,11 +33,11 @@ public MemoryStream GetDataStream(BinaryReader r)
// TODO: make sure this reads exactly {chunk.SerializedLength} bytes -- it should,
// but reading {chunk.DataLength} bytes from a decompression stream is
// a weird way to do it
dctx.CopyStream(ms, (int) chunk.DataLength);
dctx.CopyStream(ms, (int)chunk.DataLength);
}
else
{
r.BaseStream.CopyStream(ms, (int) chunk.SerializedLength);
r.BaseStream.CopyStream(ms, (int)chunk.SerializedLength);
}
}

Expand Down
4 changes: 2 additions & 2 deletions RainbowForge/Core/DataBlock/FlatDataBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ public static FlatDataBlock Read(BinaryReader r, Entry entry)
var dataStart = r.BaseStream.Position;
r.BaseStream.Seek(entry.End, SeekOrigin.Begin);

return new FlatDataBlock(meta, dataStart, (int) (entry.End - dataStart));
return new FlatDataBlock(meta, dataStart, (int)(entry.End - dataStart));
}

public MemoryStream GetDataStream(BinaryReader r)
public Stream GetDataStream(BinaryReader r)
{
var ms = new MemoryStream();
r.BaseStream.Seek(Offset, SeekOrigin.Begin);
Expand Down
2 changes: 1 addition & 1 deletion RainbowForge/Core/DataBlock/IAssetBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ namespace RainbowForge.Core.DataBlock
/// </summary>
public interface IAssetBlock
{
public MemoryStream GetDataStream(BinaryReader r);
public Stream GetDataStream(BinaryReader r);
}
}
75 changes: 75 additions & 0 deletions RainbowForge/SubStream.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System;
using System.IO;

namespace RainbowForge
{
public class SubStream : Stream, IDisposable
{
private readonly Stream _source;
private readonly int _length;
private readonly long _minPos;
private readonly long _maxPos;

public SubStream(Stream source, long offset, int length)
{
_source = source;
_minPos = offset;
_length = length;
_maxPos = offset + length;
}

/// <inheritdoc />
protected override void Dispose(bool disposing)
{
if (disposing)
{
_source?.Dispose();
}

base.Dispose(disposing);
}

/// <inheritdoc />
public override void Flush()
{
_source.Flush();
}

/// <inheritdoc />
public override int Read(byte[] buffer, int offset, int count)
{
return _source.Read(buffer, offset, Math.Min((int)(_maxPos - _source.Position), count));
}

/// <inheritdoc />
public override long Seek(long offset, SeekOrigin origin)
{
return _source.Seek(offset + _minPos, origin);
}

/// <inheritdoc />
public override void SetLength(long value) => throw new NotSupportedException();

/// <inheritdoc />
public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException();

/// <inheritdoc />
public override bool CanRead => _source.CanRead;

/// <inheritdoc />
public override bool CanSeek => _source.CanSeek;

/// <inheritdoc />
public override bool CanWrite => false;

/// <inheritdoc />
public override long Length => _length;

/// <inheritdoc />
public override long Position
{
get => _source.Position - _minPos;
set => _source.Position = _minPos + value;
}
}
}
47 changes: 0 additions & 47 deletions Sandbox/Program.cs
Original file line number Diff line number Diff line change
@@ -1,59 +1,12 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using RainbowForge;
using RainbowForge.Archive;
using RainbowForge.Core;
using RainbowForge.Core.Container;

namespace Sandbox
{
internal class Program
{
private static void Main(string[] args)
{
using var sw = new StreamWriter("out.txt");
foreach (var forgeFilename in Directory.GetFiles("R:\\Siege Dumps\\Y6S1 v15500403", "*.forge"))
{
Console.WriteLine(forgeFilename);

var newForge = Forge.GetForge(forgeFilename);

foreach (var entry in newForge.Entries)
{
TestMagic(entry.MetaData.FileType);

if (MagicHelper.GetFiletype(entry.MetaData.FileType) != AssetType.FlatArchive)
continue;

var container = newForge.GetContainer(entry.Uid);
if (container is not ForgeAsset fa)
continue;

var arc = FlatArchive.Read(fa.GetDataStream(newForge));

foreach (var arcEntry in arc.Entries) TestMagic(arcEntry.MetaData.FileType);
}
}

foreach (var (magic, count) in MagicTable.OrderByDescending(pair => pair.Value))
if (Enum.IsDefined(typeof(Magic), (ulong)magic))
sw.WriteLine($"0x{magic:X8} ({(Magic)magic}) - {count}");
else
sw.WriteLine($"0x{magic:X8} - {count}");

Console.WriteLine("Done.");
}

private static readonly Dictionary<uint, int> MagicTable = new();

private static void TestMagic(uint fileType)
{
if (!MagicTable.ContainsKey(fileType))
MagicTable[fileType] = 0;

MagicTable[fileType]++;
}
}
}

0 comments on commit 8ae9a2b

Please sign in to comment.