-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
393 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
using System; | ||
|
||
namespace IntelOrca.Biohazard | ||
{ | ||
public sealed class AfsFile | ||
{ | ||
private AFSLib.AfsArchive _afsArchive; | ||
|
||
public ReadOnlyMemory<byte> Data { get; } | ||
|
||
public AfsFile(ReadOnlyMemory<byte> data) | ||
{ | ||
Data = data; | ||
if (AFSLib.AfsArchive.TryFromFile(data.ToArray(), out var archive)) | ||
{ | ||
_afsArchive = archive; | ||
} | ||
else | ||
{ | ||
throw new ArgumentException("Invalid AFS data", nameof(data)); | ||
} | ||
} | ||
|
||
public ReadOnlyMemory<byte> GetFileData(int index) | ||
{ | ||
return _afsArchive.Files[index].Data; | ||
} | ||
|
||
public ReadOnlyMemory<byte> GetFileData(string path) | ||
{ | ||
foreach (var file in _afsArchive.Files) | ||
{ | ||
if (file.Name == path) | ||
{ | ||
return file.Data; | ||
} | ||
} | ||
throw new ArgumentException("File not found", nameof(path)); | ||
} | ||
|
||
public Builder ToBuilder() | ||
{ | ||
return new Builder(Data); | ||
} | ||
|
||
public class Builder | ||
{ | ||
private AFSLib.AfsArchive _afsArchive; | ||
|
||
public Builder(ReadOnlyMemory<byte> data) | ||
{ | ||
if (AFSLib.AfsArchive.TryFromFile(data.ToArray(), out var archive)) | ||
{ | ||
_afsArchive = archive; | ||
} | ||
else | ||
{ | ||
throw new ArgumentException("Invalid AFS data", nameof(data)); | ||
} | ||
} | ||
|
||
public void Replace(int index, ReadOnlyMemory<byte> data) => Replace(index, data.ToArray()); | ||
|
||
public void Replace(int index, byte[] data) | ||
{ | ||
_afsArchive.Files[index].Data = data; | ||
} | ||
|
||
public AfsFile ToAfsFile() | ||
{ | ||
return new AfsFile(_afsArchive.ToBytes()); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,5 +6,6 @@ public enum BioVersion | |
Biohazard1_5, | ||
Biohazard2, | ||
Biohazard3, | ||
BiohazardCv, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
using System; | ||
|
||
namespace IntelOrca.Biohazard | ||
{ | ||
public sealed class PrsFile | ||
{ | ||
private readonly ReadOnlyMemory<byte> _compressed; | ||
private ReadOnlyMemory<byte>? _uncompressed; | ||
private object _sync = new object(); | ||
|
||
public ReadOnlyMemory<byte> Data => _compressed; | ||
|
||
public static PrsFile Compress(ReadOnlyMemory<byte> uncompressed) | ||
{ | ||
// var bufferSize = 0x1FFF; | ||
var bufferSize = 0xFF; | ||
var compressed = csharp_prs.Prs.Compress(uncompressed.ToArray(), bufferSize); | ||
return new PrsFile(compressed); | ||
} | ||
|
||
public PrsFile(ReadOnlyMemory<byte> compressed) | ||
{ | ||
_compressed = compressed; | ||
} | ||
|
||
public unsafe ReadOnlyMemory<byte> Uncompressed | ||
{ | ||
get | ||
{ | ||
if (_uncompressed == null) | ||
{ | ||
lock (_sync) | ||
{ | ||
if (_uncompressed == null) | ||
{ | ||
var span = _compressed.Span; | ||
fixed (byte* src = span) | ||
{ | ||
_uncompressed = csharp_prs.Prs.Decompress(src, span.Length); | ||
} | ||
} | ||
} | ||
} | ||
return _uncompressed.Value; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
|
||
namespace IntelOrca.Biohazard.Room | ||
{ | ||
public partial class RdtCv | ||
{ | ||
public class Builder : IRdtBuilder | ||
{ | ||
private readonly MemoryStream _ms; | ||
|
||
public List<Item> Items { get; } = new List<Item>(); | ||
public List<Door> Doors { get; } = new List<Door>(); | ||
|
||
public Builder(byte[] data) | ||
{ | ||
_ms = new MemoryStream(data); | ||
} | ||
|
||
public RdtCv ToRdt() | ||
{ | ||
var br = new BinaryReader(_ms); | ||
var bw = new BinaryWriter(_ms); | ||
_ms.Position = 16; | ||
_ms.Position = br.ReadInt32(); | ||
br.ReadInt32(); | ||
br.ReadInt32(); | ||
br.ReadInt32(); | ||
br.ReadInt32(); | ||
var items = br.ReadInt32(); | ||
br.ReadInt32(); | ||
br.ReadInt32(); | ||
var doors = br.ReadInt32(); | ||
|
||
_ms.Position = 256; | ||
br.ReadInt32(); | ||
br.ReadInt32(); | ||
br.ReadInt32(); | ||
br.ReadInt32(); | ||
var itemCount = br.ReadInt32(); | ||
br.ReadInt32(); | ||
br.ReadInt32(); | ||
var doorCount = br.ReadInt32(); | ||
|
||
if (itemCount != Items.Count) | ||
throw new Exception("Changing number of items is not supported"); | ||
|
||
if (doorCount != Doors.Count) | ||
throw new Exception("Changing number of doors is not supported"); | ||
|
||
_ms.Position = items; | ||
foreach (var item in Items) | ||
{ | ||
bw.Write(item); | ||
} | ||
|
||
_ms.Position = doors; | ||
foreach (var door in Doors) | ||
{ | ||
bw.Write(door); | ||
} | ||
|
||
return new RdtCv(_ms.ToArray()); | ||
} | ||
|
||
IRdt IRdtBuilder.ToRdt() => ToRdt(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
using System; | ||
using System.IO; | ||
using System.Runtime.InteropServices; | ||
using IntelOrca.Biohazard.Extensions; | ||
|
||
namespace IntelOrca.Biohazard.Room | ||
{ | ||
public partial class RdtCv : IRdt | ||
{ | ||
public BioVersion Version => BioVersion.BiohazardCv; | ||
|
||
public ReadOnlyMemory<byte> Data { get; } | ||
|
||
public RdtCv(string path) | ||
: this(File.ReadAllBytes(path)) | ||
{ | ||
} | ||
|
||
public RdtCv(ReadOnlyMemory<byte> data) | ||
{ | ||
Data = data; | ||
} | ||
|
||
public Builder ToBuilder() | ||
{ | ||
var builder = new Builder(Data.ToArray()); | ||
builder.Doors.AddRange(Doors.ToArray()); | ||
builder.Items.AddRange(Items.ToArray()); | ||
return builder; | ||
} | ||
|
||
private int ScriptOffsetListOffset => Data.GetSafeSpan<int>(16, 1)[0]; | ||
private ReadOnlySpan<int> ScriptOffsets => Data.GetSafeSpan<int>(ScriptOffsetListOffset, 9); | ||
private ReadOnlySpan<int> ScriptCounts => Data.GetSafeSpan<int>(256, 9); | ||
|
||
public ReadOnlySpan<Item> Items => GetTable<Item>(4); | ||
public ReadOnlySpan<Door> Doors => GetTable<Door>(7); | ||
|
||
private ReadOnlySpan<T> GetTable<T>(int index) where T : struct | ||
{ | ||
var offset = ScriptOffsets[index]; | ||
var count = ScriptCounts[index]; | ||
return Data.GetSafeSpan<T>(offset, count); | ||
} | ||
|
||
IRdtBuilder IRdt.ToBuilder() => ToBuilder(); | ||
|
||
[StructLayout(LayoutKind.Sequential, Pack = 1)] | ||
public struct Item | ||
{ | ||
public byte Unk00; | ||
public byte Unk01; | ||
public byte Unk02; | ||
public byte Unk03; | ||
public int Type; | ||
public int Unk08; | ||
public int X; | ||
public int Y; | ||
public int Z; | ||
public short XRot; | ||
public short YRot; | ||
public short ZRot; | ||
public short Unk1E; | ||
public byte Unk20; | ||
public byte Unk21; | ||
public byte Unk22; | ||
public byte Unk23; | ||
} | ||
|
||
[StructLayout(LayoutKind.Sequential, Pack = 1)] | ||
public struct Door | ||
{ | ||
public byte Unk00; | ||
public byte Unk01; | ||
public byte Unk02; | ||
public byte Unk03; | ||
public int Unk04; | ||
public int Unk08; | ||
public int Unk0C; | ||
public int Unk10; | ||
public int Unk14; | ||
public int Unk18; | ||
public int Unk1C; | ||
public byte Stage; | ||
public byte Room; | ||
public byte ExitId; | ||
public byte Transition; | ||
} | ||
} | ||
} |
Oops, something went wrong.