mirror of
https://github.com/crskycode/GARbro.git
synced 2024-11-27 07:34:00 +08:00
commit
a52d2f3e25
@ -127,9 +127,13 @@
|
|||||||
<Compile Include="CsWare\AudioWAV.cs" />
|
<Compile Include="CsWare\AudioWAV.cs" />
|
||||||
<Compile Include="CsWare\ImageGDT.cs" />
|
<Compile Include="CsWare\ImageGDT.cs" />
|
||||||
<Compile Include="FC01\ArcBDT.cs" />
|
<Compile Include="FC01\ArcBDT.cs" />
|
||||||
|
<Compile Include="FC01\ArcSCXA.cs" />
|
||||||
<Compile Include="FC01\BdtTables.cs" />
|
<Compile Include="FC01\BdtTables.cs" />
|
||||||
<Compile Include="GScripter\ArcDATA.cs" />
|
<Compile Include="GScripter\ArcDATA.cs" />
|
||||||
<Compile Include="Ism\ImagePNG.cs" />
|
<Compile Include="Ism\ImagePNG.cs" />
|
||||||
|
<Compile Include="Kid\ArcDATRAW.cs" />
|
||||||
|
<Compile Include="Kid\ImageLBG.cs" />
|
||||||
|
<Compile Include="Kid\ImageSPC.cs" />
|
||||||
<Compile Include="Kogado\ArcARC.cs" />
|
<Compile Include="Kogado\ArcARC.cs" />
|
||||||
<Compile Include="Ice\ImageIBM.cs" />
|
<Compile Include="Ice\ImageIBM.cs" />
|
||||||
<Compile Include="Ice\ScriptISD.cs" />
|
<Compile Include="Ice\ScriptISD.cs" />
|
||||||
@ -169,7 +173,15 @@
|
|||||||
<Compile Include="Macromedia\AudioSND.cs" />
|
<Compile Include="Macromedia\AudioSND.cs" />
|
||||||
<Compile Include="Macromedia\DirectorFile.cs" />
|
<Compile Include="Macromedia\DirectorFile.cs" />
|
||||||
<Compile Include="Macromedia\Palettes.cs" />
|
<Compile Include="Macromedia\Palettes.cs" />
|
||||||
|
<Compile Include="MAGES\ArcARC20.cs" />
|
||||||
|
<Compile Include="MAGES\ArcFARC.cs" />
|
||||||
|
<Compile Include="MAGES\ArcGTF.cs" />
|
||||||
|
<Compile Include="MAGES\ArcLoveOnce.cs" />
|
||||||
|
<Compile Include="MAGES\ImageBIN.cs" />
|
||||||
<Compile Include="Mugi\ArcBIN.cs" />
|
<Compile Include="Mugi\ArcBIN.cs" />
|
||||||
|
<Compile Include="NipponIchi\ArcCASN.cs" />
|
||||||
|
<Compile Include="NipponIchi\ArcPSFS.cs" />
|
||||||
|
<Compile Include="NipponIchi\ImageNMT.cs" />
|
||||||
<Compile Include="NScripter\Script.cs" />
|
<Compile Include="NScripter\Script.cs" />
|
||||||
<Compile Include="Psp\ArcQPK.cs" />
|
<Compile Include="Psp\ArcQPK.cs" />
|
||||||
<Compile Include="ScrPlayer\ImageIMG.cs" />
|
<Compile Include="ScrPlayer\ImageIMG.cs" />
|
||||||
@ -310,8 +322,8 @@
|
|||||||
<Compile Include="MyAdv\ArcPAC.cs" />
|
<Compile Include="MyAdv\ArcPAC.cs" />
|
||||||
<Compile Include="Nekopack\ArcNEKO2.cs" />
|
<Compile Include="Nekopack\ArcNEKO2.cs" />
|
||||||
<Compile Include="Nekopack\ArcNEKO3.cs" />
|
<Compile Include="Nekopack\ArcNEKO3.cs" />
|
||||||
<Compile Include="NitroPlus\ArcLAY.cs" />
|
<Compile Include="MAGES\ArcLAY.cs" />
|
||||||
<Compile Include="NitroPlus\ArcMPK.cs" />
|
<Compile Include="MAGES\ArcMPK.cs" />
|
||||||
<Compile Include="NitroPlus\ArcNPP.cs" />
|
<Compile Include="NitroPlus\ArcNPP.cs" />
|
||||||
<Compile Include="Noesis\ArcIGA.cs" />
|
<Compile Include="Noesis\ArcIGA.cs" />
|
||||||
<Compile Include="NonColor\ArcMinato.cs" />
|
<Compile Include="NonColor\ArcMinato.cs" />
|
||||||
|
@ -57,9 +57,9 @@ namespace GameRes.Formats.Cri
|
|||||||
backend.Position = 4;
|
backend.Position = 4;
|
||||||
var lzss = new LzssStream (backend);
|
var lzss = new LzssStream (backend);
|
||||||
var input = new SeekableStream (lzss);
|
var input = new SeekableStream (lzss);
|
||||||
|
var base_name = Path.GetFileNameWithoutExtension(file.Name);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var base_name = Path.GetFileNameWithoutExtension (file.Name);
|
|
||||||
using (var spc = new XtxIndexBuilder (input, base_name))
|
using (var spc = new XtxIndexBuilder (input, base_name))
|
||||||
{
|
{
|
||||||
spc.ReadIndex (0);
|
spc.ReadIndex (0);
|
||||||
@ -71,8 +71,15 @@ namespace GameRes.Formats.Cri
|
|||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
input.Dispose();
|
//input.Dispose();
|
||||||
throw;
|
//throw;
|
||||||
|
var dir = new List<Entry>();
|
||||||
|
var entry = Create<PackedEntry>(base_name);
|
||||||
|
entry.Offset = 0;
|
||||||
|
entry.Size = (uint)input.Length;
|
||||||
|
entry.Type = "image";
|
||||||
|
dir.Add(entry);
|
||||||
|
return new SpcArchive(file, this, dir, input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ namespace GameRes.Formats.Cri
|
|||||||
[Export(typeof(ImageFormat))]
|
[Export(typeof(ImageFormat))]
|
||||||
public class SpcFormat : XtxFormat
|
public class SpcFormat : XtxFormat
|
||||||
{
|
{
|
||||||
public override string Tag { get { return "SPC"; } }
|
public override string Tag { get { return "SPC/Xbox360"; } }
|
||||||
public override string Description { get { return "CRI MiddleWare compressed texture format"; } }
|
public override string Description { get { return "CRI MiddleWare compressed texture format"; } }
|
||||||
public override uint Signature { get { return 0; } }
|
public override uint Signature { get { return 0; } }
|
||||||
|
|
||||||
|
@ -65,6 +65,16 @@ namespace GameRes.Formats.BGI
|
|||||||
return null;
|
return null;
|
||||||
if (0 != stream.ReadInt64())
|
if (0 != stream.ReadInt64())
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
if (flag == 0)
|
||||||
|
{
|
||||||
|
int stride = (int)width * ((bpp + 7) / 8);
|
||||||
|
var pixels = new byte[stride * (int)height];
|
||||||
|
int read = stream.Read(pixels, 0, pixels.Length);
|
||||||
|
if (read != pixels.Length)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return new BgiMetaData
|
return new BgiMetaData
|
||||||
{
|
{
|
||||||
Width = (uint)width,
|
Width = (uint)width,
|
||||||
|
50
ArcFormats/FC01/ArcSCXA.cs
Normal file
50
ArcFormats/FC01/ArcSCXA.cs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.Composition;
|
||||||
|
|
||||||
|
namespace GameRes.Formats.FC01
|
||||||
|
{
|
||||||
|
[Export(typeof(ArchiveFormat))]
|
||||||
|
public class SCXAOpener : ArchiveFormat
|
||||||
|
{
|
||||||
|
public override string Tag { get { return "ARC/SCXA Pia Carrot e Youkoso 4 Xbox360"; } }
|
||||||
|
public override string Description { get { return "Pia Carrot e Youkoso 4 Xbox360 resource archive"; } }
|
||||||
|
public override uint Signature { get { return 0x41584353; } } // 'SCXA'
|
||||||
|
public override bool IsHierarchic { get { return false; } }
|
||||||
|
public override bool CanWrite { get { return false; } }
|
||||||
|
|
||||||
|
public override ArcFile TryOpen(ArcView file)
|
||||||
|
{
|
||||||
|
uint datastart = file.View.ReadUInt32(4);
|
||||||
|
int count = file.View.ReadInt32(8);
|
||||||
|
if (!IsSaneCount(count))
|
||||||
|
return null;
|
||||||
|
uint tnstart = (uint)count * 4 + 12;
|
||||||
|
var dir = new List<Entry>(count);
|
||||||
|
uint index_offset;
|
||||||
|
for (int i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
uint namestart = file.View.ReadUInt32(i * 4 + 12);
|
||||||
|
uint fstart = file.View.ReadUInt32(tnstart + namestart);
|
||||||
|
uint flength = file.View.ReadUInt32(tnstart + namestart + 4);
|
||||||
|
index_offset = tnstart + namestart + 8;
|
||||||
|
byte c;
|
||||||
|
List<byte> namebyte = new List<byte>();
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
c = file.View.ReadByte((long)index_offset);
|
||||||
|
if (c == 0 | index_offset > datastart) break;
|
||||||
|
namebyte.Add(c);
|
||||||
|
index_offset++;
|
||||||
|
}
|
||||||
|
var name = System.Text.Encoding.ASCII.GetString(namebyte.ToArray());
|
||||||
|
var entry = Create<Entry>(name);
|
||||||
|
entry.Offset = datastart + fstart;
|
||||||
|
entry.Size = flength;
|
||||||
|
if (!entry.CheckPlacement(file.MaxOffset))
|
||||||
|
return null;
|
||||||
|
dir.Add(entry);
|
||||||
|
}
|
||||||
|
return new ArcFile(file, this, dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
148
ArcFormats/Kid/ArcDATRAW.cs
Normal file
148
ArcFormats/Kid/ArcDATRAW.cs
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
using GameRes.Utility;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.Composition;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace GameRes.Formats.Kid
|
||||||
|
{
|
||||||
|
[Export(typeof(ArchiveFormat))]
|
||||||
|
public class DATRAWOpener : ArchiveFormat
|
||||||
|
{
|
||||||
|
public override string Tag { get { return "DAT/KID & MAGES PS2 DAT RAW"; } }
|
||||||
|
public override string Description { get { return "DAT/KID & MAGES PS2 DAT RAW"; } }
|
||||||
|
public override uint Signature { get { return 0; } } //actually zero
|
||||||
|
public override bool IsHierarchic { get { return false; } }
|
||||||
|
public override bool CanWrite { get { return false; } }
|
||||||
|
|
||||||
|
private static readonly uint dataEntryCount = 4096;
|
||||||
|
|
||||||
|
public override ArcFile TryOpen(ArcView file)
|
||||||
|
{
|
||||||
|
var archivename = Path.GetFileNameWithoutExtension(file.Name);
|
||||||
|
var dir = new List<Entry>();
|
||||||
|
for (int i = 0; i < dataEntryCount; i++)
|
||||||
|
{
|
||||||
|
uint offset = file.View.ReadUInt32(i * 8);
|
||||||
|
uint size = file.View.ReadUInt32(i * 8 + 4);
|
||||||
|
offset = offset * 2048 + 0x8000;
|
||||||
|
size *= 1024;
|
||||||
|
if (offset > file.MaxOffset || size > file.MaxOffset)
|
||||||
|
{
|
||||||
|
throw new InvalidFormatException();
|
||||||
|
}
|
||||||
|
if (size == 0) continue;
|
||||||
|
|
||||||
|
var entry = Create<Entry>(archivename + i.ToString("D5"));
|
||||||
|
entry.Offset = offset;
|
||||||
|
entry.Size = size;
|
||||||
|
dir.Add(entry);
|
||||||
|
}
|
||||||
|
return new ArcFile(file, this, dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*public override Stream OpenEntry(ArcFile arc, Entry entry)
|
||||||
|
{
|
||||||
|
IBinaryStream input = arc.File.CreateStream(entry.Offset, entry.Size, entry.Name);
|
||||||
|
if (input.Signature == 0x535043) // 'CPS'
|
||||||
|
{
|
||||||
|
using (input)
|
||||||
|
return UnpackCps(input);
|
||||||
|
}
|
||||||
|
return input.AsStream;
|
||||||
|
}*/
|
||||||
|
Stream UnpackCps(IBinaryStream input)
|
||||||
|
{
|
||||||
|
var header = input.ReadHeader(0x10);
|
||||||
|
int packed_size = header.ToInt32(4);
|
||||||
|
int compression = header.ToUInt16(0xA);
|
||||||
|
int unpacked_size = header.ToInt32(0xC);
|
||||||
|
|
||||||
|
//input.Seek(-4, SeekOrigin.End);
|
||||||
|
input.Seek(packed_size - 4, SeekOrigin.Begin);
|
||||||
|
uint key_offset = input.ReadUInt32() - 0x7534682;
|
||||||
|
input.Position = key_offset;
|
||||||
|
uint key = input.ReadUInt32() + key_offset + 0x3786425;
|
||||||
|
|
||||||
|
var decryptor = new CpsTransform(packed_size, (int)key_offset, key);
|
||||||
|
using (var decoded = new InputCryptoStream(input.AsStream, decryptor))
|
||||||
|
using (var cps = new BinaryStream(decoded, input.Name))
|
||||||
|
{
|
||||||
|
var output = new byte[unpacked_size];
|
||||||
|
if ((compression & 1) != 0)
|
||||||
|
{
|
||||||
|
cps.ReadInt32();
|
||||||
|
UnpackLnd(cps, output);
|
||||||
|
}
|
||||||
|
else if ((compression & 2) != 0)
|
||||||
|
{
|
||||||
|
UnpackLnd16(cps, output);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cps.ReadInt32();
|
||||||
|
cps.Read(output, 0, unpacked_size);
|
||||||
|
}
|
||||||
|
return new BinMemoryStream(output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
internal static void UnpackLnd(IBinaryStream input, byte[] output)
|
||||||
|
{
|
||||||
|
int unpacked_size = output.Length;
|
||||||
|
int dst = 0;
|
||||||
|
while (dst < unpacked_size)
|
||||||
|
{
|
||||||
|
int ctl = input.ReadByte();
|
||||||
|
if (-1 == ctl)
|
||||||
|
break;
|
||||||
|
if ((ctl & 0x80) != 0)
|
||||||
|
{
|
||||||
|
if ((ctl & 0x40) != 0)
|
||||||
|
{
|
||||||
|
int count = (ctl & 0x1F) + 2;
|
||||||
|
if ((ctl & 0x20) != 0)
|
||||||
|
count += input.ReadUInt8() << 5;
|
||||||
|
count = Math.Min(count, unpacked_size - dst);
|
||||||
|
byte v = input.ReadUInt8();
|
||||||
|
for (int i = 0; i < count; ++i)
|
||||||
|
output[dst++] = v;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int count = ((ctl >> 2) & 0xF) + 2;
|
||||||
|
int offset = ((ctl & 3) << 8) + input.ReadUInt8() + 1;
|
||||||
|
count = Math.Min(count, unpacked_size - dst);
|
||||||
|
Binary.CopyOverlapped(output, dst - offset, dst, count);
|
||||||
|
dst += count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((ctl & 0x40) != 0)
|
||||||
|
{
|
||||||
|
int length = Math.Min((ctl & 0x3F) + 2, unpacked_size - dst);
|
||||||
|
int count = input.ReadUInt8();
|
||||||
|
input.Read(output, dst, length);
|
||||||
|
dst += length;
|
||||||
|
count = Math.Min(count * length, unpacked_size - dst);
|
||||||
|
if (count > 0)
|
||||||
|
{
|
||||||
|
Binary.CopyOverlapped(output, dst - length, dst, count);
|
||||||
|
dst += count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int count = (ctl & 0x1F) + 1;
|
||||||
|
if ((ctl & 0x20) != 0)
|
||||||
|
count += input.ReadUInt8() << 5;
|
||||||
|
count = Math.Min(count, unpacked_size - dst);
|
||||||
|
input.Read(output, dst, count);
|
||||||
|
dst += count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void UnpackLnd16(IBinaryStream input, byte[] output)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException("KID Lnd16 compression not implemented.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
111
ArcFormats/Kid/ImageLBG.cs
Normal file
111
ArcFormats/Kid/ImageLBG.cs
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.Composition;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace GameRes.Formats.Kid
|
||||||
|
{
|
||||||
|
[Export(typeof(ImageFormat))]
|
||||||
|
public class LbgFormat : ImageFormat
|
||||||
|
{
|
||||||
|
public override string Tag { get { return "LBG/PS2-SPC"; } }
|
||||||
|
public override string Description { get { return "KID PS2 SPC Image Format"; } }
|
||||||
|
public override uint Signature { get { return 0; } } //real signature may exist below
|
||||||
|
|
||||||
|
public LbgFormat()
|
||||||
|
{
|
||||||
|
Extensions = new string[] { "", "lbg" };
|
||||||
|
// Actually LBG format can contain more than one image as lip for chara, well, "not implemented".
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ImageMetaData ReadMetaData(IBinaryStream file)
|
||||||
|
{
|
||||||
|
uint header = file.ReadUInt32();
|
||||||
|
uint overheader = 0;
|
||||||
|
|
||||||
|
if (header != 0x2047424C) //LBG\x20
|
||||||
|
{
|
||||||
|
overheader = header;
|
||||||
|
if (overheader > 0x50) //usually 10 or 30, never seen any larger
|
||||||
|
return null;
|
||||||
|
file.Seek(overheader, SeekOrigin.Begin);
|
||||||
|
header = file.ReadUInt32();
|
||||||
|
if (header != 0x2047424C) //LBG\x20
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int width = file.ReadInt16();
|
||||||
|
int height = file.ReadInt16();
|
||||||
|
if (width <= 0 || height <= 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return new LbgImageMetaData
|
||||||
|
{
|
||||||
|
Width = (uint)width,
|
||||||
|
Height = (uint)height,
|
||||||
|
OverHeader = overheader,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public override ImageData Read(IBinaryStream file, ImageMetaData info)
|
||||||
|
{
|
||||||
|
if (info == null)
|
||||||
|
throw new NotSupportedException(string.Format("Not LBG texture format."));
|
||||||
|
|
||||||
|
/*if (info.Width != 640)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException(string.Format("Not 640 pixels width, may not work."));
|
||||||
|
}*/
|
||||||
|
var lbgheader = (LbgImageMetaData)info;
|
||||||
|
uint oversize = 0;
|
||||||
|
uint blocknum = info.Width / 126;
|
||||||
|
if (lbgheader.OverHeader != 0)
|
||||||
|
{
|
||||||
|
file.Position = 4;
|
||||||
|
uint filesize = file.ReadUInt32();
|
||||||
|
if (filesize == 0)
|
||||||
|
oversize = 8;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
filesize -= 16;
|
||||||
|
oversize = (filesize - info.Width * info.Height * 4) / info.Height / (blocknum + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file.Position = lbgheader.OverHeader + 0x10;
|
||||||
|
//List<byte> pixels = new List<byte>();
|
||||||
|
byte[] pixels = new byte[info.Width * info.Height * 4];
|
||||||
|
for (int blockcount = 0; blockcount <= blocknum; blockcount++)
|
||||||
|
{
|
||||||
|
for (int y = 0; y < info.Height; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; (blockcount != blocknum & x < 126) | (blockcount == blocknum & x < info.Width - blockcount * 126); x++)
|
||||||
|
{
|
||||||
|
var pixel = file.ReadBytes(4); //RGBA with wrong A
|
||||||
|
long target = (x + blockcount * 126) * 4 + y * info.Width * 4;
|
||||||
|
//BGRA
|
||||||
|
pixels[target] = pixel[2];
|
||||||
|
pixels[target + 1] = pixel[1];
|
||||||
|
pixels[target + 2] = pixel[0];
|
||||||
|
if (pixel[3] >= byte.MaxValue / 2)
|
||||||
|
pixels[target + 3] = byte.MaxValue;
|
||||||
|
else
|
||||||
|
pixels[target + 3] = (byte)(pixel[3] << 1); //needs a test
|
||||||
|
}
|
||||||
|
if (oversize != 0)
|
||||||
|
file.ReadBytes((int)oversize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ImageData.Create(info, PixelFormats.Bgra32, null, pixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(Stream file, ImageData bitmap)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException("LbgFormat.Write not implemented");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class LbgImageMetaData : ImageMetaData
|
||||||
|
{
|
||||||
|
public uint OverHeader { get; set; }
|
||||||
|
}
|
||||||
|
}
|
44
ArcFormats/Kid/ImageSPC.cs
Normal file
44
ArcFormats/Kid/ImageSPC.cs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
using GameRes.Compression;
|
||||||
|
using System.ComponentModel.Composition;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace GameRes.Formats.Kid
|
||||||
|
{
|
||||||
|
[Export(typeof(ImageFormat))]
|
||||||
|
public class SpcFormat: LbgFormat
|
||||||
|
{
|
||||||
|
public override string Tag { get { return "SPC/PS2"; } }
|
||||||
|
public override string Description { get { return "PS2 CRI MiddleWare compressed texture format"; } }
|
||||||
|
public override uint Signature { get { return 0; } }
|
||||||
|
public SpcFormat()
|
||||||
|
{
|
||||||
|
Extensions = new string[] { "spc" };
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ImageMetaData ReadMetaData(IBinaryStream stream)
|
||||||
|
{
|
||||||
|
uint unpacked_size = stream.Signature;
|
||||||
|
if (unpacked_size <= 0x20 || unpacked_size > 0x5000000) // ~83MB
|
||||||
|
return null;
|
||||||
|
stream.Position = 4;
|
||||||
|
using (var lzss = new LzssStream(stream.AsStream, LzssMode.Decompress, true))
|
||||||
|
using (var input = new SeekableStream(lzss))
|
||||||
|
using (var lbg = new BinaryStream(input, stream.Name))
|
||||||
|
return base.ReadMetaData(lbg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ImageData Read(IBinaryStream stream, ImageMetaData info)
|
||||||
|
{
|
||||||
|
stream.Position = 4;
|
||||||
|
using (var lzss = new LzssStream(stream.AsStream, LzssMode.Decompress, true))
|
||||||
|
using (var input = new SeekableStream(lzss))
|
||||||
|
using (var lbg = new BinaryStream(input, stream.Name))
|
||||||
|
return base.Read(lbg, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(Stream file, ImageData image)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException("SpcFormat.Write not implemented");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
50
ArcFormats/MAGES/ArcARC20.cs
Normal file
50
ArcFormats/MAGES/ArcARC20.cs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.Composition;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace GameRes.Formats.MAGES
|
||||||
|
{
|
||||||
|
[Export(typeof(ArchiveFormat))]
|
||||||
|
public class ARC20Opener : ArchiveFormat
|
||||||
|
{
|
||||||
|
public override string Tag { get { return "ARC/Princess Soft ARC20"; } }
|
||||||
|
public override string Description { get { return "Princess Soft PS2 resource archive"; } }
|
||||||
|
public override uint Signature { get { return 0x20435241; } } // 'ARC\x20'
|
||||||
|
public override bool IsHierarchic { get { return false; } }
|
||||||
|
public override bool CanWrite { get { return false; } }
|
||||||
|
|
||||||
|
public override ArcFile TryOpen(ArcView file)
|
||||||
|
{
|
||||||
|
int count = file.View.ReadInt32(4);
|
||||||
|
if (!IsSaneCount(count))
|
||||||
|
return null;
|
||||||
|
uint filename_end = file.View.ReadUInt32(8);
|
||||||
|
var dir = new List<Entry>(count);
|
||||||
|
uint index_offset;
|
||||||
|
for (int i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
index_offset = file.View.ReadUInt32(16 * i + 16);
|
||||||
|
byte c;
|
||||||
|
List<byte> namebyte = new List<byte>();
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
c = file.View.ReadByte((long)index_offset);
|
||||||
|
if (c == 0 | index_offset > filename_end) break;
|
||||||
|
namebyte.Add(c);
|
||||||
|
index_offset++;
|
||||||
|
}
|
||||||
|
var sjis = System.Text.Encoding.GetEncoding("Shift-JIS");
|
||||||
|
var name = sjis.GetString(namebyte.ToArray());
|
||||||
|
var entry = Create<Entry>(name);
|
||||||
|
|
||||||
|
entry.Offset = file.View.ReadUInt32(16 * i + 16 + 4) * 2048;
|
||||||
|
entry.Size = file.View.ReadUInt32(16 * i + 16 + 8);
|
||||||
|
if (!entry.CheckPlacement(file.MaxOffset))
|
||||||
|
return null;
|
||||||
|
dir.Add(entry);
|
||||||
|
}
|
||||||
|
return new ArcFile(file, this, dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
48
ArcFormats/MAGES/ArcFARC.cs
Normal file
48
ArcFormats/MAGES/ArcFARC.cs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.Composition;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace GameRes.Formats.MAGES
|
||||||
|
{
|
||||||
|
[Export(typeof(ArchiveFormat))]
|
||||||
|
public class FARCOpener : ArchiveFormat
|
||||||
|
{
|
||||||
|
public override string Tag { get { return "DAT/FARC Rozen Maiden PS3 archive"; } }
|
||||||
|
public override string Description { get { return "MAGES Rozen Maiden Wechseln Sie Welt ab PS3 BLJM61120 archive"; } }
|
||||||
|
public override uint Signature { get { return 0x43524146; } } // 'FARC'
|
||||||
|
public override bool IsHierarchic { get { return false; } }
|
||||||
|
public override bool CanWrite { get { return false; } }
|
||||||
|
|
||||||
|
public override ArcFile TryOpen(ArcView file)
|
||||||
|
{
|
||||||
|
int count = file.View.ReadInt32(20);
|
||||||
|
if (!IsSaneCount(count))
|
||||||
|
return null;
|
||||||
|
uint datanamestart = (uint)count * 20 + 36;
|
||||||
|
var dir = new List<Entry>(count);
|
||||||
|
for (int i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
long namepl = file.View.ReadUInt32(20 * i + 36 + 16);
|
||||||
|
long index_offset = datanamestart + namepl;
|
||||||
|
byte c;
|
||||||
|
List<byte> namebyte = new List<byte>();
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
c = file.View.ReadByte(index_offset);
|
||||||
|
if (c == 0) break;
|
||||||
|
namebyte.Add(c);
|
||||||
|
index_offset++;
|
||||||
|
}
|
||||||
|
var sjis = Encoding.GetEncoding("Shift-JIS");
|
||||||
|
var name = sjis.GetString(namebyte.ToArray());
|
||||||
|
var entry = Create<Entry>(name);
|
||||||
|
entry.Offset = file.View.ReadUInt32(20 * i + 36);
|
||||||
|
entry.Size = file.View.ReadUInt32(20 * i + 36 + 4);
|
||||||
|
if (entry.Size == 0)
|
||||||
|
continue;
|
||||||
|
dir.Add(entry);
|
||||||
|
}
|
||||||
|
return new ArcFile(file, this, dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
116
ArcFormats/MAGES/ArcGTF.cs
Normal file
116
ArcFormats/MAGES/ArcGTF.cs
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
using GameRes.Utility;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.Composition;
|
||||||
|
using System.IO;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace GameRes.Formats.MAGES
|
||||||
|
{
|
||||||
|
[Export(typeof(ArchiveFormat))]
|
||||||
|
public class GTFOpener : ArchiveFormat
|
||||||
|
{
|
||||||
|
public override string Tag { get { return "GTF/Rozen Maiden PS3 Image archive"; } }
|
||||||
|
public override string Description { get { return "MAGES Rozen Maiden Wechseln Sie Welt ab PS3 BLJM61120 Image archive"; } }
|
||||||
|
public override uint Signature { get { return 0xFF000202; } } // 'FF000202'
|
||||||
|
public override bool IsHierarchic { get { return false; } }
|
||||||
|
public override bool CanWrite { get { return false; } }
|
||||||
|
|
||||||
|
public override ArcFile TryOpen(ArcView file)
|
||||||
|
{
|
||||||
|
int count = Binary.BigEndian(file.View.ReadInt32(8));
|
||||||
|
if (!IsSaneCount(count))
|
||||||
|
return null;
|
||||||
|
string filename = Path.GetFileNameWithoutExtension(file.Name);
|
||||||
|
var dir = new List<Entry>(count);
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
var entry = Create<Entry_RawImage>(filename + '_' + i.ToString());
|
||||||
|
entry.Offset = Binary.BigEndian(file.View.ReadUInt32(16 + 36 * i));
|
||||||
|
entry.Size = Binary.BigEndian(file.View.ReadUInt32(16 + 36 * i + 4));
|
||||||
|
entry.width = Binary.BigEndian(file.View.ReadUInt16(32 + 36 * i));
|
||||||
|
entry.height = Binary.BigEndian(file.View.ReadUInt16(32 + 36 * i + 2));
|
||||||
|
entry.Type = "image";
|
||||||
|
dir.Add(entry);
|
||||||
|
}
|
||||||
|
return new ArcFile(file, this, dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Stream OpenEntry(ArcFile arc, Entry entry)
|
||||||
|
{
|
||||||
|
var compentry = (Entry_RawImage)entry;
|
||||||
|
IBinaryStream input = arc.File.CreateStream(entry.Offset, entry.Size, entry.Name);
|
||||||
|
return ReadImageGTF(input, compentry.width, compentry.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class Entry_RawImage : Entry
|
||||||
|
{
|
||||||
|
public ushort width { get; set; }
|
||||||
|
public ushort height { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/*[Export(typeof(ImageFormat))]
|
||||||
|
public class GTFFormat : ImageFormat
|
||||||
|
{
|
||||||
|
public override string Tag { get { return "MAGES PS3/PSV Image Format"; } }
|
||||||
|
public override string Description { get { return "MAGES PS3/PSV Image Format"; } }
|
||||||
|
public override uint Signature { get { return 0; } }
|
||||||
|
|
||||||
|
public override ImageMetaData ReadMetaData(IBinaryStream file)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
public override ImageData Read(IBinaryStream file, ImageMetaData info)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
public override void Write(Stream file, ImageData bitmap)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This method returns MAGES/ImageBIN format Image data stream, please ensure it's decoding method exists.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input">GTF or BIN raw ARGB32 data, start in the upper left corner, each row.</param>
|
||||||
|
/// <param name="width"></param>
|
||||||
|
/// <param name="height"></param>
|
||||||
|
/// <returns>MAGES/ImageBIN format Image data stream</returns>
|
||||||
|
static Stream ReadImageGTF(IBinaryStream input, ushort width, ushort height)
|
||||||
|
{
|
||||||
|
//List<byte> bytes = new List<byte>();
|
||||||
|
byte[] widths = BitConverter.GetBytes(width);
|
||||||
|
byte[] heights = BitConverter.GetBytes(height);
|
||||||
|
byte[] bpp = BitConverter.GetBytes((uint)32);
|
||||||
|
/*Stream output = new MemoryStream();
|
||||||
|
output.Write(widths, 0, widths.Length);
|
||||||
|
output.Write(heights, 0, heights.Length);
|
||||||
|
output.Write(bpp, 0, bpp.Length);
|
||||||
|
output.Write(input.ReadBytes((int)input.Length), 0, (int)input.Length);
|
||||||
|
byte[] bytes = new byte[output.Length];
|
||||||
|
output.Seek(0, SeekOrigin.Begin);
|
||||||
|
output.Read(bytes, 0, bytes.Length);
|
||||||
|
output.Dispose();*/
|
||||||
|
|
||||||
|
byte[] inputData = input.ReadBytes((int)input.Length);
|
||||||
|
byte[] outputData = new byte[widths.Length + heights.Length + bpp.Length + inputData.Length];
|
||||||
|
Buffer.BlockCopy(widths, 0, outputData, 0, widths.Length);
|
||||||
|
Buffer.BlockCopy(heights, 0, outputData, widths.Length, heights.Length);
|
||||||
|
Buffer.BlockCopy(bpp, 0, outputData, widths.Length + heights.Length, bpp.Length);
|
||||||
|
Buffer.BlockCopy(inputData, 0, outputData, widths.Length + heights.Length + bpp.Length, inputData.Length);
|
||||||
|
return new BinMemoryStream(outputData);
|
||||||
|
|
||||||
|
/*List<byte> pixels = new List<byte>();
|
||||||
|
for (int i = 0; i < input.Length; i++)
|
||||||
|
{
|
||||||
|
var pixel = input.ReadBytes(4); //ARGB
|
||||||
|
//BGRA
|
||||||
|
pixels.Add(pixel[3]);
|
||||||
|
pixels.Add(pixel[2]);
|
||||||
|
pixels.Add(pixel[1]);
|
||||||
|
pixels.Add(pixel[0]);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -32,7 +32,7 @@ using System.Windows;
|
|||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
|
|
||||||
namespace GameRes.Formats.NitroPlus
|
namespace GameRes.Formats.MAGES
|
||||||
{
|
{
|
||||||
internal class LayEntry : Entry
|
internal class LayEntry : Entry
|
||||||
{
|
{
|
57
ArcFormats/MAGES/ArcLoveOnce.cs
Normal file
57
ArcFormats/MAGES/ArcLoveOnce.cs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.Composition;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace GameRes.Formats.MAGES
|
||||||
|
{
|
||||||
|
[Export(typeof(ArchiveFormat))]
|
||||||
|
public class LoveOnceOpener : ArchiveFormat
|
||||||
|
{
|
||||||
|
public override string Tag { get { return "BIN/LoveOnce"; } }
|
||||||
|
public override string Description { get { return "L@ve Once PS3 resource archive"; } }
|
||||||
|
public override uint Signature { get { return 0; } } // no header
|
||||||
|
public override bool IsHierarchic { get { return false; } }
|
||||||
|
public override bool CanWrite { get { return false; } }
|
||||||
|
|
||||||
|
public override ArcFile TryOpen(ArcView filedata)
|
||||||
|
{
|
||||||
|
ArcView filelist;
|
||||||
|
if (filedata.Name.EndsWith("data.bin"))
|
||||||
|
{
|
||||||
|
string filepath = Path.GetDirectoryName(filedata.Name);
|
||||||
|
filepath = Path.Combine(filepath, "list.bin");
|
||||||
|
if (! File.Exists(filepath)) return null;
|
||||||
|
filelist = new ArcView(filepath);
|
||||||
|
}
|
||||||
|
else if (filedata.Name.EndsWith("list.bin"))
|
||||||
|
{
|
||||||
|
string filepath = Path.GetDirectoryName(filedata.Name);
|
||||||
|
filepath = Path.Combine(filepath, "data.bin");
|
||||||
|
if (!File.Exists(filepath)) return null;
|
||||||
|
filelist = new ArcView(filepath);
|
||||||
|
return TryOpen(filelist);
|
||||||
|
}
|
||||||
|
else return null;
|
||||||
|
|
||||||
|
uint index_offset = 0, count = 0;
|
||||||
|
var dir = new List<Entry>();
|
||||||
|
while (index_offset < filelist.MaxOffset)
|
||||||
|
{
|
||||||
|
uint filesize = filelist.View.ReadUInt32(index_offset);
|
||||||
|
uint fileoffset = filelist.View.ReadUInt32(index_offset + 8);
|
||||||
|
string name = filelist.View.ReadString(index_offset + 0x10, 0x40);
|
||||||
|
var entry = Create<Entry>(name);
|
||||||
|
entry.Size = filesize;
|
||||||
|
entry.Offset = fileoffset;
|
||||||
|
if (!entry.CheckPlacement(filedata.MaxOffset))
|
||||||
|
return null;
|
||||||
|
dir.Add(entry);
|
||||||
|
count++;
|
||||||
|
index_offset += 0x50;
|
||||||
|
}
|
||||||
|
return new ArcFile(filedata, this, dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -26,7 +26,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.Composition;
|
using System.ComponentModel.Composition;
|
||||||
|
|
||||||
namespace GameRes.Formats.NitroPlus
|
namespace GameRes.Formats.MAGES
|
||||||
{
|
{
|
||||||
[Export(typeof(ArchiveFormat))]
|
[Export(typeof(ArchiveFormat))]
|
||||||
public class MpkOpener : ArchiveFormat
|
public class MpkOpener : ArchiveFormat
|
||||||
@ -39,11 +39,31 @@ namespace GameRes.Formats.NitroPlus
|
|||||||
|
|
||||||
public override ArcFile TryOpen (ArcView file)
|
public override ArcFile TryOpen (ArcView file)
|
||||||
{
|
{
|
||||||
|
uint version_temp = file.View.ReadUInt32 (4);
|
||||||
int count = file.View.ReadInt32 (8);
|
int count = file.View.ReadInt32 (8);
|
||||||
if (!IsSaneCount (count))
|
if (!IsSaneCount (count))
|
||||||
return null;
|
return null;
|
||||||
uint index_offset = 0x48;
|
|
||||||
var dir = new List<Entry> (count);
|
var dir = new List<Entry> (count);
|
||||||
|
uint index_offset = 0;
|
||||||
|
if (version_temp == 65536)
|
||||||
|
{
|
||||||
|
index_offset = 0x44;
|
||||||
|
for (int i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
var name = file.View.ReadString (index_offset+0x1c, 0xE0);
|
||||||
|
var entry = Create<PackedEntry> (name);
|
||||||
|
entry.Offset = file.View.ReadInt32 (index_offset);
|
||||||
|
entry.Size = file.View.ReadUInt32 (index_offset+4);
|
||||||
|
entry.UnpackedSize = file.View.ReadUInt32 (index_offset+8);
|
||||||
|
if (!entry.CheckPlacement (file.MaxOffset))
|
||||||
|
return null;
|
||||||
|
dir.Add (entry);
|
||||||
|
index_offset += 0x100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
index_offset = 0x48;
|
||||||
for (int i = 0; i < count; ++i)
|
for (int i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
var name = file.View.ReadString (index_offset+0x18, 0xE0);
|
var name = file.View.ReadString (index_offset+0x18, 0xE0);
|
||||||
@ -56,6 +76,7 @@ namespace GameRes.Formats.NitroPlus
|
|||||||
dir.Add (entry);
|
dir.Add (entry);
|
||||||
index_offset += 0x100;
|
index_offset += 0x100;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return new ArcFile (file, this, dir);
|
return new ArcFile (file, this, dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
143
ArcFormats/MAGES/ImageBIN.cs
Normal file
143
ArcFormats/MAGES/ImageBIN.cs
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.Composition;
|
||||||
|
using System.Diagnostics.Eventing.Reader;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
|
||||||
|
namespace GameRes.Formats.MAGES
|
||||||
|
{
|
||||||
|
[Export(typeof(ImageFormat))]
|
||||||
|
public class BinFormat : ImageFormat
|
||||||
|
{
|
||||||
|
public override string Tag { get { return "MAGES PS3/PSV Image Format"; } }
|
||||||
|
public override string Description { get { return "MAGES PS3/PSV Image Format"; } }
|
||||||
|
public override uint Signature { get { return 0; } }
|
||||||
|
public override bool CanWrite { get { return true; } }
|
||||||
|
|
||||||
|
public BinFormat()
|
||||||
|
{
|
||||||
|
Extensions = new string[] { "" };
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ImageMetaData ReadMetaData(IBinaryStream file)
|
||||||
|
{
|
||||||
|
//var header = file.ReadHeader(8);
|
||||||
|
int width = file.ReadInt16();
|
||||||
|
int height = file.ReadInt16();
|
||||||
|
if (width <= 0 || height <= 0)
|
||||||
|
return null;
|
||||||
|
int bpp = file.ReadInt16();
|
||||||
|
if (32 == bpp)
|
||||||
|
{
|
||||||
|
uint imagedatasize = (uint)width * (uint)height * 4;
|
||||||
|
if (file.Length != imagedatasize + 8)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else if (8 == bpp)
|
||||||
|
{
|
||||||
|
uint imagedatasize = (uint)width * (uint)height + 256;
|
||||||
|
if (file.Length != imagedatasize + 8)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return new ImageMetaData
|
||||||
|
{
|
||||||
|
Width = (uint)width,
|
||||||
|
Height = (uint)height,
|
||||||
|
BPP = bpp,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public override ImageData Read(IBinaryStream file, ImageMetaData info)
|
||||||
|
{
|
||||||
|
if (info == null)
|
||||||
|
throw new NotSupportedException(string.Format("Not BIN texture format."));
|
||||||
|
if (info.BPP == 32)
|
||||||
|
{
|
||||||
|
uint pixelnum = info.Width * info.Height;
|
||||||
|
if (file.Length != pixelnum * 4 + 8) throw new NotSupportedException(string.Format("Not BIN 32ARGB texture format."));
|
||||||
|
|
||||||
|
file.Position = 8;
|
||||||
|
//var data = file.ReadBytes(info.iWidth * info.iHeight * 4);
|
||||||
|
List<byte> pixels = new List<byte>();
|
||||||
|
for (int i = 0; i < pixelnum; i++)
|
||||||
|
{
|
||||||
|
var pixel = file.ReadBytes(4); //ARGB
|
||||||
|
//BGRA
|
||||||
|
pixels.Add(pixel[3]);
|
||||||
|
pixels.Add(pixel[2]);
|
||||||
|
pixels.Add(pixel[1]);
|
||||||
|
pixels.Add(pixel[0]);
|
||||||
|
}
|
||||||
|
return ImageData.Create(info, PixelFormats.Bgra32, null, pixels.ToArray());
|
||||||
|
}
|
||||||
|
else if (info.BPP == 8)
|
||||||
|
{
|
||||||
|
uint imagedatasize = info.Width * info.Height + 256;
|
||||||
|
if (file.Length != imagedatasize + 8) throw new NotSupportedException(string.Format("Not BIN 256colors texture format."));
|
||||||
|
file.Position = 8;
|
||||||
|
//var pixelColor = file.ReadBytes(256 * 4);
|
||||||
|
List<Color> colors = new List<Color>();
|
||||||
|
for (int i = 0; i < 256; i += 4)
|
||||||
|
{
|
||||||
|
Color c = new Color();
|
||||||
|
var color_b = file.ReadBytes(4); //BGRA
|
||||||
|
c.B = color_b[0];
|
||||||
|
c.G = color_b[1];
|
||||||
|
c.R = color_b[2];
|
||||||
|
c.A = color_b[3];
|
||||||
|
colors.Add(c);
|
||||||
|
}
|
||||||
|
BitmapPalette palette = new BitmapPalette(colors);
|
||||||
|
//file.Position += 256 * 4;
|
||||||
|
var data = file.ReadBytes(info.iWidth * info.iHeight);
|
||||||
|
return ImageData.Create(info, PixelFormats.Indexed8, palette, data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new NotSupportedException(string.Format("Not BIN texture format."));
|
||||||
|
}
|
||||||
|
public override void Write(Stream stream, ImageData image)
|
||||||
|
{
|
||||||
|
//throw new System.NotImplementedException("BINFormat.Write not implemented");
|
||||||
|
using (var file = new BinaryWriter(stream, Encoding.ASCII, true))
|
||||||
|
{
|
||||||
|
if (image.Width > ushort.MaxValue || image.Height > ushort.MaxValue)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException(string.Format("Image width or height oversize."));
|
||||||
|
}
|
||||||
|
if (image.BPP != 32)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException(string.Format("Image bitdepth not supported, should be 32."));
|
||||||
|
}
|
||||||
|
file.Write((ushort)image.Width);
|
||||||
|
file.Write((ushort)image.Height);
|
||||||
|
file.Write(image.BPP);
|
||||||
|
|
||||||
|
var bitmap = image.Bitmap;
|
||||||
|
if (bitmap.Format != PixelFormats.Bgra32)
|
||||||
|
{
|
||||||
|
bitmap = new FormatConvertedBitmap(image.Bitmap, PixelFormats.Bgra32, null, 0);
|
||||||
|
}
|
||||||
|
int stride = (int)image.Width * 4;
|
||||||
|
byte[] row_data = new byte[stride];
|
||||||
|
Int32Rect rect = new Int32Rect(0, 0, (int)image.Width, 1);
|
||||||
|
for (uint row = 0; row < image.Height; ++row)
|
||||||
|
{
|
||||||
|
bitmap.CopyPixels(rect, row_data, stride, 0);
|
||||||
|
for (uint col = 0; col < image.Width; ++col)
|
||||||
|
{
|
||||||
|
(row_data[(col * 4) + 3], row_data[col * 4]) = (row_data[col * 4], row_data[(col * 4) + 3]);
|
||||||
|
(row_data[(col * 4) + 2], row_data[(col * 4) + 1]) = (row_data[(col * 4) + 1], row_data[(col * 4) + 2]);
|
||||||
|
}
|
||||||
|
file.Write(row_data);
|
||||||
|
rect.Y++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
50
ArcFormats/NipponIchi/ArcCASN.cs
Normal file
50
ArcFormats/NipponIchi/ArcCASN.cs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
using GameRes.Utility;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.Composition;
|
||||||
|
|
||||||
|
namespace GameRes.Formats.NipponIchi
|
||||||
|
{
|
||||||
|
[Export(typeof(ArchiveFormat))]
|
||||||
|
public class CASNOpener : ArchiveFormat
|
||||||
|
{
|
||||||
|
public override string Tag { get { return "DAT/CASN ShinHayarigami"; } }
|
||||||
|
public override string Description { get { return "Nippon Ichi Shin Hayarigami PS3 resource archive"; } }
|
||||||
|
public override uint Signature { get { return 0x4E534143; } } // 'CASN'
|
||||||
|
public override bool IsHierarchic { get { return false; } }
|
||||||
|
public override bool CanWrite { get { return false; } }
|
||||||
|
|
||||||
|
public override ArcFile TryOpen(ArcView file)
|
||||||
|
{
|
||||||
|
int count = Binary.BigEndian(file.View.ReadUInt16(6));
|
||||||
|
if (!IsSaneCount(count))
|
||||||
|
return null;
|
||||||
|
long index_offset = count * 10 + 30; //actually count*10 + 28, ignored two bytes of 000C or 000B
|
||||||
|
var dir = new List<Entry>(count);
|
||||||
|
for (int i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
uint fstart = Binary.BigEndian(file.View.ReadUInt32(index_offset));
|
||||||
|
uint flength = Binary.BigEndian(file.View.ReadUInt32(index_offset + 4));
|
||||||
|
index_offset += 8;
|
||||||
|
byte c;
|
||||||
|
List<byte> namebyte = new List<byte>();
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
c = file.View.ReadByte(index_offset);
|
||||||
|
if (c == 0) break;
|
||||||
|
namebyte.Add(c);
|
||||||
|
index_offset++;
|
||||||
|
}
|
||||||
|
index_offset += 3;
|
||||||
|
//var sjis = System.Text.Encoding.GetEncoding("Shift-JIS");
|
||||||
|
var name = System.Text.Encoding.ASCII.GetString(namebyte.ToArray());
|
||||||
|
var entry = Create<Entry>(name);
|
||||||
|
entry.Offset = fstart;
|
||||||
|
entry.Size = flength;
|
||||||
|
if (!entry.CheckPlacement(file.MaxOffset))
|
||||||
|
return null;
|
||||||
|
dir.Add(entry);
|
||||||
|
}
|
||||||
|
return new ArcFile(file, this, dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
42
ArcFormats/NipponIchi/ArcPSFS.cs
Normal file
42
ArcFormats/NipponIchi/ArcPSFS.cs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
using GameRes.Utility;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.Composition;
|
||||||
|
|
||||||
|
namespace GameRes.Formats.NipponIchi
|
||||||
|
{
|
||||||
|
[Export(typeof(ArchiveFormat))]
|
||||||
|
public class PSFSOpener : ArchiveFormat
|
||||||
|
{
|
||||||
|
public override string Tag { get { return "DAT/PS_FS ShinHayarigami2"; } }
|
||||||
|
public override string Description { get { return "Nippon Ichi Shin Hayarigami2 PS3 resource archive"; } }
|
||||||
|
public override uint Signature { get { return 0x465F5350; } } // 'PS_F' of 'PS_FS_V1'
|
||||||
|
public override bool IsHierarchic { get { return false; } }
|
||||||
|
public override bool CanWrite { get { return false; } }
|
||||||
|
|
||||||
|
public override ArcFile TryOpen(ArcView file)
|
||||||
|
{
|
||||||
|
int count = Binary.BigEndian(file.View.ReadInt32(8));
|
||||||
|
if (!IsSaneCount(count))
|
||||||
|
return null;
|
||||||
|
long index_offset = 0x10;
|
||||||
|
var dir = new List<Entry>(count);
|
||||||
|
for (int i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
string name = file.View.ReadString(index_offset, 0x30);
|
||||||
|
var entry = Create<Entry>(name);
|
||||||
|
entry.Offset = Binary.BigEndian(file.View.ReadUInt32(index_offset + 0x3C));
|
||||||
|
entry.Size = Binary.BigEndian(file.View.ReadUInt32(index_offset + 0x34));
|
||||||
|
index_offset += 0x40;
|
||||||
|
if (!entry.CheckPlacement(file.MaxOffset))
|
||||||
|
return null;
|
||||||
|
if (0 == file.View.ReadByte(entry.Offset))
|
||||||
|
{
|
||||||
|
entry.Offset += 0x10;
|
||||||
|
entry.Size -= 0x10;
|
||||||
|
}
|
||||||
|
dir.Add(entry);
|
||||||
|
}
|
||||||
|
return new ArcFile(file, this, dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
39
ArcFormats/NipponIchi/ImageNMT.cs
Normal file
39
ArcFormats/NipponIchi/ImageNMT.cs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel.Composition;
|
||||||
|
using System.IO;
|
||||||
|
using System.Windows.Media;
|
||||||
|
|
||||||
|
namespace GameRes.Formats.NipponIchi
|
||||||
|
{
|
||||||
|
[Export(typeof(ImageFormat))]
|
||||||
|
public class NmtFormat : ImageFormat {
|
||||||
|
public override string Tag { get { return "NMT"; } }
|
||||||
|
public override string Description { get { return "NIS Multy Texform image format"; } }
|
||||||
|
public override uint Signature { get { return 0x6D73696E; } } // 'nism'
|
||||||
|
|
||||||
|
public override ImageMetaData ReadMetaData(IBinaryStream file)
|
||||||
|
{
|
||||||
|
var header = file.ReadHeader(0x30);
|
||||||
|
var signature = file.ReadHeader(15);
|
||||||
|
if (System.Text.Encoding.ASCII.GetString(signature.ToArray()) != "nismultitexform")
|
||||||
|
return null;
|
||||||
|
return new ImageMetaData
|
||||||
|
{
|
||||||
|
Width = header.ToUInt16(0x26),
|
||||||
|
Height = header.ToUInt16(0x28)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public override ImageData Read(IBinaryStream file, ImageMetaData info)
|
||||||
|
{
|
||||||
|
//uint imagedatasize = info.Width * info.Height * 4;
|
||||||
|
if (info == null) throw new NotSupportedException(string.Format("Not NMT texture format."));
|
||||||
|
file.Position = 0x30;
|
||||||
|
var data = file.ReadBytes(info.iWidth * info.iHeight * 4);
|
||||||
|
return ImageData.Create(info, PixelFormats.Bgra32, null, data);
|
||||||
|
}
|
||||||
|
public override void Write(Stream file, ImageData image)
|
||||||
|
{
|
||||||
|
throw new System.NotImplementedException("NmtFormat.Write not implemented");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -100,6 +100,10 @@
|
|||||||
</BootstrapperPackage>
|
</BootstrapperPackage>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<PostBuildEvent>If $(ConfigurationName) == Release del *.pdb
|
||||||
|
If $(ConfigurationName) == Release del *.config</PostBuildEvent>
|
||||||
|
</PropertyGroup>
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
<Target Name="BeforeBuild">
|
<Target Name="BeforeBuild">
|
||||||
|
Loading…
Reference in New Issue
Block a user