mirror of
https://github.com/crskycode/GARbro.git
synced 2024-12-18 17:10:12 +08:00
[Musica] Legacy Game Support
This commit is contained in:
parent
cdd4e0161c
commit
a7021686e9
@ -192,6 +192,7 @@
|
||||
<Compile Include="MAGES\ArcLoveOnce.cs" />
|
||||
<Compile Include="MAGES\ImageBIN.cs" />
|
||||
<Compile Include="Mugi\ArcBIN.cs" />
|
||||
<Compile Include="Musica\ArcPAK.cs" />
|
||||
<Compile Include="NipponIchi\ArcCASN.cs" />
|
||||
<Compile Include="NipponIchi\ArcPSFS.cs" />
|
||||
<Compile Include="NipponIchi\ImageNMT.cs" />
|
||||
|
173
ArcFormats/Musica/ArcPAK.cs
Normal file
173
ArcFormats/Musica/ArcPAK.cs
Normal file
@ -0,0 +1,173 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace GameRes.Formats.Musica
|
||||
{
|
||||
[Export(typeof(ArchiveFormat))]
|
||||
public class PakOpener : ArchiveFormat
|
||||
{
|
||||
public override string Tag { get; } = "PAK";
|
||||
public override string Description { get; } = "Musica engine legacy resource archive";
|
||||
public override uint Signature { get; } = 0;
|
||||
public override bool IsHierarchic { get; } = true;
|
||||
public override bool CanWrite { get; } = false;
|
||||
|
||||
public PakOpener()
|
||||
{
|
||||
Extensions = new[] { "pak" };
|
||||
ContainedFormats = new string[] { "PNG", "OGG" };
|
||||
}
|
||||
|
||||
static readonly HashSet<string> PakImageNames = new HashSet<string>()
|
||||
{
|
||||
"bg", "st",
|
||||
};
|
||||
|
||||
static readonly HashSet<string> PakAudioNames = new HashSet<string>()
|
||||
{
|
||||
"bgm", "se", "voice",
|
||||
};
|
||||
|
||||
private string GetType(string pakName, string entryName)
|
||||
{
|
||||
if (PakImageNames.Contains(pakName))
|
||||
{
|
||||
return "image";
|
||||
}
|
||||
|
||||
if (PakAudioNames.Contains(pakName))
|
||||
{
|
||||
return "audio";
|
||||
}
|
||||
|
||||
return FormatCatalog.Instance.GetTypeFromName(entryName, ContainedFormats);
|
||||
}
|
||||
|
||||
public override ArcFile TryOpen(ArcView view)
|
||||
{
|
||||
Stream input = view.CreateStream();
|
||||
using(input = new NegStream(input))
|
||||
{
|
||||
using(ArcView.Reader reader = new ArcView.Reader(input))
|
||||
{
|
||||
int count = reader.ReadInt32();
|
||||
if (count <= 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Entry> entries = new List<Entry>(count);
|
||||
for(int i = 0; i < count; ++i)
|
||||
{
|
||||
uint indexLen = reader.ReadUInt32();
|
||||
long indexStart = input.Position;
|
||||
|
||||
string name = input.ReadCString();
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
uint size = reader.ReadUInt32();
|
||||
uint offset = reader.ReadUInt32();
|
||||
|
||||
Entry entry = new Entry() { Name = name, Offset = offset, Size = size };
|
||||
if (!entry.CheckPlacement(view.MaxOffset))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
entry.Type = this.GetType(Path.GetFileNameWithoutExtension(view.Name), entry.Name);
|
||||
entries.Add(entry);
|
||||
|
||||
input.Position = indexStart + indexLen;
|
||||
}
|
||||
return new PakArchive(view, this, entries, input.Position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override Stream OpenEntry(ArcFile arc, Entry entry)
|
||||
{
|
||||
if (!(arc is PakArchive pakArc))
|
||||
{
|
||||
return base.OpenEntry(arc, entry);
|
||||
}
|
||||
|
||||
return new NegStream(base.OpenEntry(arc, pakArc.GetEntry(entry)));
|
||||
}
|
||||
}
|
||||
|
||||
internal class PakArchive : ArcFile
|
||||
{
|
||||
private long m_IndexSize;
|
||||
public PakArchive(ArcView arc, ArchiveFormat impl, ICollection<Entry> dir, long indexSize) : base(arc, impl, dir)
|
||||
{
|
||||
m_IndexSize = indexSize;
|
||||
}
|
||||
|
||||
public Entry GetEntry(Entry e)
|
||||
{
|
||||
return new Entry
|
||||
{
|
||||
Name = e.Name,
|
||||
Offset = e.Offset + m_IndexSize,
|
||||
Size = e.Size,
|
||||
Type = e.Type,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
//neg reg8
|
||||
public class NegStream : ProxyStream
|
||||
{
|
||||
public NegStream(Stream stream, bool leave_open = false) : base(stream, leave_open)
|
||||
{
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
int read = BaseStream.Read(buffer, offset, count);
|
||||
for (int i = 0; i < read; ++i)
|
||||
{
|
||||
buffer[offset + i] = (byte)-buffer[offset + i];
|
||||
}
|
||||
return read;
|
||||
}
|
||||
|
||||
public override int ReadByte()
|
||||
{
|
||||
int b = BaseStream.ReadByte();
|
||||
if (-1 != b)
|
||||
{
|
||||
b = (byte)-b;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
byte[] write_buf;
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (null == write_buf)
|
||||
write_buf = new byte[81920];
|
||||
while (count > 0)
|
||||
{
|
||||
int chunk = Math.Min(write_buf.Length, count);
|
||||
for (int i = 0; i < chunk; ++i)
|
||||
{
|
||||
write_buf[i] = (byte)-buffer[offset + i];
|
||||
}
|
||||
BaseStream.Write(write_buf, 0, chunk);
|
||||
offset += chunk;
|
||||
count -= chunk;
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteByte(byte value)
|
||||
{
|
||||
BaseStream.WriteByte((byte)-value);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user