mirror of
https://github.com/crskycode/GARbro.git
synced 2026-06-06 13:48:57 +08:00
Merge pull request #77 from Manicsteiner/private_build
Multiple changes of TIM2/KLZ
This commit is contained in:
@@ -131,7 +131,9 @@
|
||||
<Compile Include="Artemis\ImageNekoPNG.cs" />
|
||||
<Compile Include="CsWare\AudioWAV.cs" />
|
||||
<Compile Include="CsWare\ImageGDT.cs" />
|
||||
<Compile Include="DigitalWorks\ArcPACsingle.cs" />
|
||||
<Compile Include="DigitalWorks\ArcPACPS2.cs" />
|
||||
<Compile Include="DigitalWorks\ImageTM2arc.cs" />
|
||||
<Compile Include="DxLib\HuffmanDecoder.cs" />
|
||||
<Compile Include="DxLib\WidgetDXA.xaml.cs">
|
||||
<DependentUpon>WidgetDXA.xaml</DependentUpon>
|
||||
@@ -142,8 +144,10 @@
|
||||
<Compile Include="GScripter\ArcDATA.cs" />
|
||||
<Compile Include="Ism\ImagePNG.cs" />
|
||||
<Compile Include="Kid\ArcDATRAW.cs" />
|
||||
<Compile Include="Kid\ArcKLZ.cs" />
|
||||
<Compile Include="Kid\ImageBIP.cs" />
|
||||
<Compile Include="Kid\ImageBIParc.cs" />
|
||||
<Compile Include="Kid\ImageKLZ.cs" />
|
||||
<Compile Include="Kid\ImageLBG.cs" />
|
||||
<Compile Include="Kid\ImageSPC.cs" />
|
||||
<Compile Include="Kogado\ArcARC.cs" />
|
||||
|
||||
88
ArcFormats/DigitalWorks/ArcPACsingle.cs
Normal file
88
ArcFormats/DigitalWorks/ArcPACsingle.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
//! \file ArcPACPS2.cs
|
||||
//! \date 2018 Sep 18
|
||||
//! \brief Digital Works PS2 resource archive.
|
||||
//
|
||||
// Copyright (C) 2018 by morkt
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using GameRes.Compression;
|
||||
|
||||
namespace GameRes.Formats.DigitalWorks
|
||||
{
|
||||
[Export(typeof(ArchiveFormat))]
|
||||
public class PacSingleOpener : ArchiveFormat
|
||||
{
|
||||
public override string Tag { get { return "PAC/LZS-TIM2"; } }
|
||||
public override string Description { get { return "LZS-TIM2 Image archive"; } }
|
||||
public override uint Signature { get { return 0x535A4C; } } // 'LZS'
|
||||
public override bool IsHierarchic { get { return false; } }
|
||||
public override bool CanWrite { get { return false; } }
|
||||
|
||||
/**
|
||||
Target games:
|
||||
Cafe Little Wish SLPM-65294
|
||||
F Fanatic SLPM-65296
|
||||
*/
|
||||
|
||||
public override ArcFile TryOpen (ArcView file)
|
||||
{
|
||||
if (!file.View.AsciiEqual(9, "TIM2"))
|
||||
return null;
|
||||
var dir = new List<Entry> (1);
|
||||
var entry = FormatCatalog.Instance.Create<PackedEntry> (file.Name);
|
||||
entry.Offset = 0L;
|
||||
entry.Size = (uint)file.MaxOffset;
|
||||
if (!entry.CheckPlacement (file.MaxOffset))
|
||||
return null;
|
||||
dir.Add (entry);
|
||||
|
||||
return new ArcFile (file, this, dir);
|
||||
}
|
||||
|
||||
public override Stream OpenEntry (ArcFile arc, Entry entry)
|
||||
{
|
||||
var pent = entry as PackedEntry;
|
||||
if (null == pent)
|
||||
return base.OpenEntry (arc, entry);
|
||||
if (!pent.IsPacked)
|
||||
{
|
||||
if (!arc.File.View.AsciiEqual (entry.Offset, "LZS\0"))
|
||||
return base.OpenEntry (arc, entry);
|
||||
pent.IsPacked = true;
|
||||
pent.UnpackedSize = arc.File.View.ReadUInt32 (entry.Offset+4);
|
||||
}
|
||||
var input = arc.File.CreateStream (entry.Offset+8, entry.Size-8);
|
||||
bool embedded_lzs = (input.Signature & ~0xF0u) == 0x535A4C0F; // 'LZS'
|
||||
var lzs = new LzssStream (input);
|
||||
if (embedded_lzs)
|
||||
{
|
||||
var header = new byte[8];
|
||||
lzs.Read (header, 0, 8);
|
||||
pent.UnpackedSize = header.ToUInt32 (4);
|
||||
lzs = new LzssStream (lzs);
|
||||
}
|
||||
return lzs;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@
|
||||
// IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using GameRes.Formats.Strings;
|
||||
using System;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
@@ -36,6 +37,7 @@ namespace GameRes.Formats.DigitalWorks
|
||||
public int PaletteSize;
|
||||
public int HeaderSize;
|
||||
public int Colors;
|
||||
public byte Alpha;
|
||||
}
|
||||
|
||||
[Export(typeof(ImageFormat))]
|
||||
@@ -48,8 +50,16 @@ namespace GameRes.Formats.DigitalWorks
|
||||
public Tim2Format ()
|
||||
{
|
||||
Extensions = new string[] { "tm2", "ext" };
|
||||
Settings = new[] { AlphaFormat };
|
||||
}
|
||||
|
||||
FixedSetSetting AlphaFormat = new FixedSetSetting(Properties.Settings.Default)
|
||||
{
|
||||
Name = "TIM2AlphaFormat",
|
||||
Text = arcStrings.Tim2AlphaFormat,
|
||||
ValuesSet = new[] { "No Alpha", "RGBX", "RGBA" },
|
||||
};
|
||||
|
||||
public override ImageMetaData ReadMetaData (IBinaryStream file)
|
||||
{
|
||||
var header = file.ReadHeader (0x40);
|
||||
@@ -59,9 +69,18 @@ namespace GameRes.Formats.DigitalWorks
|
||||
case 1: bpp = 16; break;
|
||||
case 2: bpp = 24; break;
|
||||
case 3: bpp = 32; break;
|
||||
case 4: bpp = 4; break; //16color
|
||||
case 5: bpp = 8; break;
|
||||
default: return null;
|
||||
}
|
||||
byte alpha;
|
||||
switch (AlphaFormat.Get<String>())
|
||||
{
|
||||
case "No Alpha": alpha = 0; break;
|
||||
case "RGBX": alpha = 7; break;
|
||||
case "RGBA":
|
||||
default: alpha = 8; break;
|
||||
}
|
||||
return new Tim2MetaData {
|
||||
Width = header.ToUInt16 (0x24),
|
||||
Height = header.ToUInt16 (0x26),
|
||||
@@ -69,6 +88,7 @@ namespace GameRes.Formats.DigitalWorks
|
||||
PaletteSize = header.ToInt32 (0x14),
|
||||
HeaderSize = header.ToUInt16 (0x1C),
|
||||
Colors = header.ToUInt16 (0x1E),
|
||||
Alpha = alpha, //header.ToUInt16(0x30) == 0?// not so sure, there will be omissions
|
||||
};
|
||||
}
|
||||
|
||||
@@ -99,39 +119,69 @@ namespace GameRes.Formats.DigitalWorks
|
||||
m_info = info;
|
||||
switch (info.BPP)
|
||||
{
|
||||
case 8: Format = PixelFormats.Indexed8; break;
|
||||
case 16: Format = PixelFormats.Bgr555; break;
|
||||
case 24: Format = PixelFormats.Bgr24; break;
|
||||
case 32: Format = PixelFormats.Bgra32; break;
|
||||
case 4: Format = PixelFormats.Indexed4; break;
|
||||
case 8: Format = PixelFormats.Indexed8; break;
|
||||
case 16: Format = PixelFormats.Bgr555; break;
|
||||
case 24: Format = PixelFormats.Bgr24; break;
|
||||
case 32: Format = PixelFormats.Bgra32; break;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] Unpack ()
|
||||
{
|
||||
m_input.Position = 0x10 + m_info.HeaderSize;
|
||||
int pixel_size = m_info.BPP / 8;
|
||||
int image_size = (int)m_info.Width * (int)m_info.Height * pixel_size;
|
||||
double pixel_size = (double)m_info.BPP / 8;
|
||||
int image_size = (int)((int)m_info.Width * (int)m_info.Height * pixel_size);
|
||||
var output = m_input.ReadBytes (image_size);
|
||||
if (pixel_size <= 8 && m_info.Colors > 0)
|
||||
Palette = ReadPalette (m_info.Colors);
|
||||
Palette = ReadPalette (m_info.Colors, m_info.Alpha);
|
||||
|
||||
if (pixel_size >= 3)
|
||||
if (pixel_size == 3 || pixel_size == 4 && m_info.Alpha == 8)
|
||||
{
|
||||
for (int i = 0; i < image_size; i += pixel_size)
|
||||
for (int i = 0; i < image_size; i += (int)pixel_size)
|
||||
{
|
||||
byte r = output[i];
|
||||
output[i] = output[i+2];
|
||||
output[i+2] = r;
|
||||
}
|
||||
}
|
||||
if (pixel_size == 4 && m_info.Alpha == 7)
|
||||
{
|
||||
for (int i = 0; i < image_size; i += 4)
|
||||
{
|
||||
byte r = output[i];
|
||||
output[i] = output[i + 2];
|
||||
output[i + 2] = r;
|
||||
if (output[i + 3] >= byte.MaxValue / 2)
|
||||
output[i + 3] = byte.MaxValue;
|
||||
else
|
||||
output[i + 3] = (byte)(output[i + 3] << 1);
|
||||
}
|
||||
}
|
||||
if (pixel_size == 4 && m_info.Alpha == 0)
|
||||
{
|
||||
for (int i = 0; i < image_size; i += 4)
|
||||
{
|
||||
byte r = output[i];
|
||||
output[i] = output[i + 2];
|
||||
output[i + 2] = r;
|
||||
output[i + 3] = byte.MaxValue;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
BitmapPalette ReadPalette (int color_num)
|
||||
BitmapPalette ReadPalette (int color_num, byte X_A = 8)
|
||||
{
|
||||
var source = ImageFormat.ReadColorMap (m_input.AsStream, color_num, PaletteFormat.RgbA);
|
||||
var source = ImageFormat.ReadColorMap (m_input.AsStream,
|
||||
color_num, X_A == 7 ? PaletteFormat.RgbA7 : X_A == 0 ? PaletteFormat.RgbX : PaletteFormat.RgbA);
|
||||
var color_map = new Color[color_num];
|
||||
|
||||
if (color_num == 16){
|
||||
Array.Copy(source, 0, color_map, 0, 16);
|
||||
return new BitmapPalette(color_map);
|
||||
}
|
||||
|
||||
int parts = color_num / 32;
|
||||
const int blocks = 2;
|
||||
const int rows = 2;
|
||||
|
||||
53
ArcFormats/DigitalWorks/ImageTM2arc.cs
Normal file
53
ArcFormats/DigitalWorks/ImageTM2arc.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using GameRes.Compression;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
|
||||
namespace GameRes.Formats.DigitalWorks
|
||||
{
|
||||
[Export(typeof(ImageFormat))]
|
||||
public class TM2ArkFormat : Tim2Format
|
||||
{
|
||||
public override string Tag { get { return "TIM2/PS2 compressed"; } }
|
||||
public override string Description { get { return "PlayStation/2 image format with LZSS compress"; } }
|
||||
public override uint Signature { get { return 0x535A4C; } } // 'LZS'
|
||||
public TM2ArkFormat()
|
||||
{
|
||||
Extensions = new string[] { "tm2" };
|
||||
Settings = null;
|
||||
}
|
||||
|
||||
public override ImageMetaData ReadMetaData(IBinaryStream stream)
|
||||
{
|
||||
stream.Position = 9;
|
||||
uint real_sign = stream.ReadUInt32();
|
||||
//Tim2Format tm2raw = new Tim2Format();
|
||||
if (real_sign != base.Signature)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
stream.Position = 4;
|
||||
uint unpacked_size = stream.ReadUInt32();
|
||||
if (unpacked_size <= 0x20 || unpacked_size > 0x5000000) // ~83MB
|
||||
return null;
|
||||
stream.Position = 8;
|
||||
using (var lzss = new LzssStream(stream.AsStream, LzssMode.Decompress, true))
|
||||
using (var input = new SeekableStream(lzss))
|
||||
using (var tm2 = new BinaryStream(input, stream.Name))
|
||||
return base.ReadMetaData(tm2);
|
||||
}
|
||||
public override ImageData Read(IBinaryStream stream, ImageMetaData info)
|
||||
{
|
||||
stream.Position = 8;
|
||||
using (var lzss = new LzssStream(stream.AsStream, LzssMode.Decompress, true))
|
||||
using (var input = new SeekableStream(lzss))
|
||||
using (var tm2 = new BinaryStream(input, stream.Name))
|
||||
return base.Read(tm2, info);
|
||||
}
|
||||
public override void Write(Stream file, ImageData image)
|
||||
{
|
||||
throw new System.NotImplementedException("TM2ArkFormat.Write not implemented");
|
||||
}
|
||||
}
|
||||
}
|
||||
122
ArcFormats/Kid/ArcKLZ.cs
Normal file
122
ArcFormats/Kid/ArcKLZ.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
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 KlzOpener: ArchiveFormat
|
||||
{
|
||||
public override string Tag { get { return "KLZ/KID PS2"; } }
|
||||
public override string Description { get { return "KID PS2 compressed image format with multi TIM2"; } }
|
||||
public override uint Signature { get { return 0; } }
|
||||
public override bool IsHierarchic { get { return false; } }
|
||||
public override bool CanWrite { get { return false; } }
|
||||
|
||||
public KlzOpener()
|
||||
{
|
||||
Extensions = new string[] { "klz" };
|
||||
}
|
||||
|
||||
public override ArcFile TryOpen(ArcView file)
|
||||
{
|
||||
if (!file.Name.HasExtension(".klz"))
|
||||
return null;
|
||||
uint unpacked_size = Binary.BigEndian(file.View.ReadUInt32(0));
|
||||
if (unpacked_size <= 0x20 || unpacked_size > 0x5000000)
|
||||
return null;
|
||||
|
||||
var backend = file.CreateStream();
|
||||
var input = KlzFormat.LzhStreamDecode(backend);
|
||||
var base_name = Path.GetFileNameWithoutExtension(file.Name);
|
||||
var dir = GetEntries(input, base_name);
|
||||
if (dir == null || dir.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new KlzArchive(file, this, dir, input);
|
||||
}
|
||||
//throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override Stream OpenEntry(ArcFile arc, Entry entry)
|
||||
{
|
||||
return new StreamRegion(((KlzArchive)arc).Source, entry.Offset, entry.Size, true);
|
||||
}
|
||||
|
||||
internal static List<Entry> GetEntries (Stream input, string base_name)
|
||||
{
|
||||
var entries = new List<Entry>();
|
||||
BinaryReader m_input = new ArcView.Reader(input);
|
||||
int count = 0;
|
||||
m_input.BaseStream.Position = 0;
|
||||
while (m_input.BaseStream.Position < m_input.BaseStream.Length)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
uint sign = m_input.ReadUInt32();
|
||||
m_input.ReadBytes(12);
|
||||
if (sign == 0x324D4954) //TIM2
|
||||
{
|
||||
//m_input.BaseStream.Seek(-4, SeekOrigin.Current);
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (EndOfStreamException)
|
||||
{
|
||||
return entries;
|
||||
}
|
||||
}
|
||||
long tell = m_input.BaseStream.Position - 16;
|
||||
uint size = m_input.ReadUInt32() + 16;
|
||||
string name = base_name + "_" + count.ToString("D2");
|
||||
if (tell + size > m_input.BaseStream.Length)
|
||||
{
|
||||
size = (uint)(m_input.BaseStream.Length - tell);
|
||||
name += "_incomplete";
|
||||
}
|
||||
var entry = new Entry {
|
||||
Name = name + ".tm2",
|
||||
Size = size,
|
||||
Offset = tell,
|
||||
Type = "image"
|
||||
};
|
||||
count++;
|
||||
entries.Add(entry);
|
||||
m_input.BaseStream.Position = tell + size;
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
}
|
||||
|
||||
internal class KlzArchive : ArcFile
|
||||
{
|
||||
public readonly Stream Source;
|
||||
public KlzArchive(ArcView arc, ArchiveFormat impl, ICollection<Entry> dir, Stream input)
|
||||
: base (arc, impl, dir)
|
||||
{
|
||||
Source = input;
|
||||
}
|
||||
|
||||
#region IDisposable Members
|
||||
bool _spc_disposed = false;
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (_spc_disposed)
|
||||
return;
|
||||
if (disposing)
|
||||
{
|
||||
Source.Dispose();
|
||||
}
|
||||
_spc_disposed = true;
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
313
ArcFormats/Kid/ImageKLZ.cs
Normal file
313
ArcFormats/Kid/ImageKLZ.cs
Normal file
@@ -0,0 +1,313 @@
|
||||
using GameRes.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace GameRes.Formats.Kid
|
||||
{
|
||||
[Export(typeof(ImageFormat))]
|
||||
public class KlzFormat: DigitalWorks.Tim2Format
|
||||
{
|
||||
public override string Tag { get { return "KLZ/KID PS2 compressed TIM2"; } }
|
||||
public override string Description { get { return "KID PS2 compressed TIM2 image format"; } }
|
||||
public override uint Signature { get { return 0; } } //KLZ have no header
|
||||
public KlzFormat()
|
||||
{
|
||||
Extensions = new string[] { "klz" };
|
||||
Settings = null;
|
||||
}
|
||||
|
||||
public override ImageMetaData ReadMetaData(IBinaryStream stream)
|
||||
{
|
||||
uint unpacked_size = Binary.BigEndian(stream.Signature);
|
||||
if (unpacked_size <= 0x20 || unpacked_size > 0x5000000) // ~83MB
|
||||
return null;
|
||||
stream.Position = 0;
|
||||
//Stream streamdec = LzsStreamDecode(stream);
|
||||
//using (var lzss = new LzssStream(stream.AsStream, LzssMode.Decompress, true))
|
||||
using (var input = new SeekableStream(LzhStreamDecode(stream)))
|
||||
using (var tm2 = new BinaryStream(input, stream.Name))
|
||||
return base.ReadMetaData(tm2);
|
||||
}
|
||||
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(LzhStreamDecode(stream)))
|
||||
using (var tm2 = new BinaryStream(input, stream.Name))
|
||||
return base.Read(tm2, info);
|
||||
}
|
||||
public override void Write(Stream file, ImageData image)
|
||||
{
|
||||
throw new System.NotImplementedException("KlzFormat.Write not implemented");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Original lzh_decode_mips
|
||||
/// </summary>
|
||||
/// The following code is from punk7890/PS2-Visual-Novel-Tool under MIT license.
|
||||
/// Source code: https://github.com/punk7890/PS2-Visual-Novel-Tool/blob/ac5602fbf13d15ce1bfaa27dc2263373cfebc0e5/src/scenes/kid.gd#L104
|
||||
/// <param name="input">input stream, include header</param>
|
||||
/// <returns></returns>
|
||||
public static Stream LzhStreamDecode(IBinaryStream input) {
|
||||
byte[] out_bytes = new byte[0x4000];
|
||||
List<byte> f_out_bytes = new List<byte>();
|
||||
uint output_size = Binary.BigEndian(input.ReadUInt32());
|
||||
ushort fill_count = Binary.BigEndian(input.ReadUInt16());
|
||||
bool at;
|
||||
int v0, s0 = 0, s1, s3;
|
||||
byte v1; //byte a0
|
||||
ushort s2;
|
||||
int OO40_sp = 0, OO42_sp = 0, OO44_sp, OO48_sp, OO50_sp = 0, OO60_sp = 0, OO70_sp = fill_count;
|
||||
int next_read_pos = 0;
|
||||
int count = 0;
|
||||
int num_passes = 0;
|
||||
byte[] decode_table = new byte[] {
|
||||
0x01, 0x02, 0x04, 0x08,
|
||||
0x10, 0x20, 0x40, 0x80,
|
||||
// Only first 8 are used
|
||||
0x81, 0x75, 0x81, 0x69,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x02, 0x00, 0x00
|
||||
};
|
||||
// out.resize(0x4000)
|
||||
/*int temp = 0x4000;
|
||||
while (temp > 0)
|
||||
{
|
||||
out_bytes.Add(0);
|
||||
temp--;
|
||||
}*/
|
||||
//out_bytes = Enumerable.Repeat((byte)0, 0x4000);
|
||||
// out.resize(0x4000) end
|
||||
if (fill_count > 0x4000)
|
||||
{
|
||||
next_read_pos = 4;
|
||||
while (OO70_sp > 0x4000)
|
||||
{
|
||||
int cnt = 0;
|
||||
int copy_off = next_read_pos + 2;
|
||||
while (cnt < 0x4000)
|
||||
{
|
||||
input.Position = copy_off;
|
||||
f_out_bytes.Add(input.ReadUInt8());
|
||||
cnt++;
|
||||
copy_off++;
|
||||
}
|
||||
count += 0x4000;
|
||||
next_read_pos += cnt + 2;
|
||||
num_passes++;
|
||||
input.Position = next_read_pos;
|
||||
OO70_sp = Binary.BigEndian(input.ReadUInt16());
|
||||
if (count >= output_size || next_read_pos >= input.Length)
|
||||
{
|
||||
Stream stream = new MemoryStream(f_out_bytes.ToArray());
|
||||
return stream;
|
||||
}
|
||||
OO60_sp = next_read_pos + 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
OO60_sp = 6;
|
||||
}
|
||||
|
||||
OO44_sp = OO60_sp;
|
||||
/*v0 = OO60_sp + 1;
|
||||
OO48_sp = v0;*/
|
||||
OO48_sp = OO60_sp + 1;
|
||||
while (true){
|
||||
input.Position = OO44_sp;
|
||||
//input.Seek(OO44_sp, SeekOrigin.Begin);
|
||||
/*v0 = input.ReadUInt8();
|
||||
a0 = v0 & 0xFF;*/
|
||||
//a0 = input.ReadUInt8();
|
||||
/*v0 = OO40_sp;
|
||||
v1 = v0 & 0xFF;*/
|
||||
v0 = decode_table[OO40_sp & 0xFF] & input.ReadUInt8();
|
||||
//v0 &= a0;
|
||||
// #001BA8AC
|
||||
if (v0 == 0)
|
||||
{
|
||||
input.Position = OO48_sp;
|
||||
//input.Seek(OO48_sp, SeekOrigin.Begin);
|
||||
v1 = input.ReadUInt8();
|
||||
v0 = OO50_sp + s0;
|
||||
/*out_bytes.RemoveAt(v0);
|
||||
out_bytes.Insert(v0, v1);*/
|
||||
out_bytes[v0] = v1;
|
||||
OO48_sp++;
|
||||
OO42_sp++;
|
||||
s0++;
|
||||
}
|
||||
else if (v0 != 0) {
|
||||
// # 001BA8F0
|
||||
OO42_sp += 2;
|
||||
input.Position = OO48_sp;
|
||||
// input.Seek(OO48_sp, SeekOrigin.Begin);
|
||||
/*v0 = input.ReadUInt8() & 0xFF;
|
||||
v1 = v0 << 8;
|
||||
v0 = input.ReadUInt8() & 0xFF;
|
||||
v0 = v1 | v0;
|
||||
v0 &= 0xFFFF;*/
|
||||
s2 = Binary.BigEndian(input.ReadUInt16());
|
||||
/*s2 = v0 & 0xFFFF;
|
||||
v0 = s2 & 0xFFFF;*/
|
||||
//v0 = s2;
|
||||
//v0 = (s2 & 0x1F);
|
||||
//v0 += 2;
|
||||
//v0 &= 0xFFFF;
|
||||
/*s3 = v0 & 0xFFFF;
|
||||
v0 = s2 & 0xFFFF;*/
|
||||
s3 = (s2 & 0x1F) + 2;
|
||||
//v0 = s2;
|
||||
//v0 >>= 5;
|
||||
/*v0 &= 0xFFFF;
|
||||
s1 = v0 & 0xFFFF;
|
||||
v0 = s1 & 0xFFFF;*/
|
||||
v0 = s0 - (s2 >> 5) - 1;
|
||||
//v0 -= 1;
|
||||
//v0 &= 0xFFFF;
|
||||
s1 = v0 & 0xFFFF;
|
||||
OO48_sp += 1;
|
||||
v0 = 1;
|
||||
while (v0 != 0)
|
||||
{
|
||||
at = s0 < 0x0800;
|
||||
// # 001BA96C
|
||||
if (at)
|
||||
{
|
||||
v0 = s1 & 0xFFFF;
|
||||
at = s0 < v0;
|
||||
if (at)
|
||||
{
|
||||
v1 = out_bytes[OO50_sp];
|
||||
v0 = OO50_sp + s0;
|
||||
/*out_bytes.RemoveAt(v0);
|
||||
out_bytes.Insert(v0, v1);*/
|
||||
out_bytes[v0] = v1;
|
||||
s0 += 1;
|
||||
/*v0 = s1 + 1;
|
||||
s1 = v0 & 0xFFFF;*/
|
||||
s1 = (s1 + 1) & 0xFFFF;
|
||||
// # 001BA9D8
|
||||
/*v1 = s3;
|
||||
v0 = v1 - 1;
|
||||
s3 = v0 & 0xFFFF;
|
||||
v0 = v1 & 0xFFFF;*/
|
||||
v0 = s3 & 0xFFFF;
|
||||
s3 = (s3 - 1) & 0xFFFF;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// # 001BA9B0
|
||||
/*v1 = s1 & 0xFFFF;
|
||||
v0 = OO50_sp;
|
||||
v0 += v1;*/
|
||||
//v0 = OO50_sp + s1 & 0xFFFF;
|
||||
//v1 = out_bytes[v0];
|
||||
v1 = out_bytes[OO50_sp + s1 & 0xFFFF];
|
||||
v0 = OO50_sp;
|
||||
v0 += s0;
|
||||
/*out_bytes.RemoveAt(v0);
|
||||
out_bytes.Insert(v0, v1);*/
|
||||
out_bytes[v0] = v1;
|
||||
s0 += 1;
|
||||
//v0 = s1 + 1;
|
||||
s1 = (s1 + 1) & 0xFFFF;
|
||||
// # 001BA9D8
|
||||
/*v1 = s3;
|
||||
v0 = v1 - 1;
|
||||
s3 = v0 & 0xFFFF;
|
||||
v0 = v1 & 0xFFFF;*/
|
||||
v0 = s3 & 0xFFFF;
|
||||
s3 = s3 - 1 & 0xFFFF;
|
||||
}
|
||||
OO48_sp += 1;
|
||||
}
|
||||
// # 001BAA00
|
||||
OO40_sp += 1;
|
||||
//v1 = Convert.ToByte(OO40_sp & 0xFF);
|
||||
//v0 = 8;
|
||||
if ((OO40_sp & 0xFF) == 8)
|
||||
{
|
||||
OO40_sp = 0;
|
||||
OO44_sp = OO48_sp;
|
||||
OO48_sp += 1;
|
||||
OO42_sp += 1;
|
||||
}
|
||||
/*v0 = OO42_sp;
|
||||
v1 = v0 & 0xFFFF;
|
||||
v0 = OO70_sp;
|
||||
v0 -= 1;*/
|
||||
//v0 = v1 < v0 ? 1 : 0;
|
||||
v0 = OO42_sp < OO70_sp - 1 ? 1 : 0;
|
||||
if (v0 == 0)
|
||||
{
|
||||
count += s0;
|
||||
if (count >= output_size || next_read_pos >= input.Length)
|
||||
{
|
||||
f_out_bytes.AddRange(out_bytes);
|
||||
Stream stream = new MemoryStream(f_out_bytes.ToArray());
|
||||
return stream;
|
||||
}
|
||||
num_passes += 1;
|
||||
if (num_passes == 1)
|
||||
{
|
||||
next_read_pos += OO70_sp + 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
next_read_pos += OO70_sp + 2;
|
||||
}
|
||||
|
||||
f_out_bytes.AddRange(out_bytes);
|
||||
// # out.fill(0);
|
||||
input.Position = next_read_pos;
|
||||
OO70_sp = Binary.BigEndian(input.ReadUInt16());
|
||||
if (OO70_sp > 0x4000)
|
||||
{
|
||||
while (OO70_sp > 0x4000)
|
||||
{
|
||||
int cnt = 0;
|
||||
int copy_off = next_read_pos + 2;
|
||||
while (cnt < 0x4000)
|
||||
{
|
||||
input.Position = copy_off;
|
||||
f_out_bytes.Add(input.ReadUInt8());
|
||||
cnt += 1;
|
||||
copy_off += 1;
|
||||
}
|
||||
count += 0x4000;
|
||||
next_read_pos += cnt + 2;
|
||||
input.Position = next_read_pos;
|
||||
OO70_sp = Binary.BigEndian(input.ReadUInt16());
|
||||
if (count >= output_size || next_read_pos >= input.Length)
|
||||
{
|
||||
Stream stream = new MemoryStream(f_out_bytes.ToArray());
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
}
|
||||
s0 = 0;
|
||||
//s1 = 0;
|
||||
OO50_sp = 0;
|
||||
OO42_sp = 0;
|
||||
OO48_sp = next_read_pos + 2;
|
||||
if (OO48_sp > input.Length) {
|
||||
Stream stream = new MemoryStream(f_out_bytes.ToArray());
|
||||
return stream;
|
||||
}
|
||||
OO40_sp = 0;
|
||||
OO60_sp = OO48_sp;
|
||||
OO44_sp = OO60_sp;
|
||||
v0 = OO60_sp + 1;
|
||||
OO48_sp = v0;
|
||||
}
|
||||
}
|
||||
//Stream stream_out = new MemoryStream(f_out_bytes.ToArray());
|
||||
//return stream_out;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ namespace GameRes.Formats.MAGES
|
||||
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 IsHierarchic { get { return true; } }
|
||||
public override bool CanWrite { get { return false; } }
|
||||
|
||||
public override ArcFile TryOpen(ArcView file)
|
||||
|
||||
12
ArcFormats/Properties/Settings.Designer.cs
generated
12
ArcFormats/Properties/Settings.Designer.cs
generated
@@ -837,5 +837,17 @@ namespace GameRes.Formats.Properties {
|
||||
this["NexasEncodingCP"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("RGBA")]
|
||||
public string TIM2AlphaFormat {
|
||||
get {
|
||||
return ((string)(this["TIM2AlphaFormat"]));
|
||||
}
|
||||
set {
|
||||
this["TIM2AlphaFormat"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,5 +206,8 @@
|
||||
<Setting Name="NexasEncodingCP" Type="System.Int32" Scope="User">
|
||||
<Value Profile="(Default)">932</Value>
|
||||
</Setting>
|
||||
<Setting Name="TIM2AlphaFormat" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)">RGBA</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
||||
10
ArcFormats/Strings/arcStrings.Designer.cs
generated
10
ArcFormats/Strings/arcStrings.Designer.cs
generated
@@ -752,6 +752,16 @@ namespace GameRes.Formats.Strings {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Choose Tim2 image alpha format.
|
||||
/// It can't be read correctly from the file.
|
||||
/// </summary>
|
||||
public static string Tim2AlphaFormat {
|
||||
get {
|
||||
return ResourceManager.GetString("Tim2AlphaFormat", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Hex number.
|
||||
/// </summary>
|
||||
|
||||
@@ -501,4 +501,8 @@ Choose encryption scheme or enter a passphrase.</comment>
|
||||
<data name="ODNAudioSampleRate" xml:space="preserve">
|
||||
<value>Default audio sampling rate</value>
|
||||
</data>
|
||||
<data name="Tim2AlphaFormat" xml:space="preserve">
|
||||
<value>Tim2画像のAlpha形式を選択してください。
|
||||
ファイルから正しく読み取ることができません。</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -401,4 +401,8 @@ Choose encryption scheme or enter a passphrase.</value>
|
||||
<data name="ODNAudioSampleRate" xml:space="preserve">
|
||||
<value>Default audio sampling rate</value>
|
||||
</data>
|
||||
<data name="Tim2AlphaFormat" xml:space="preserve">
|
||||
<value>Choose Tim2 image alpha format.
|
||||
It can't be read correctly from the file.</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -399,4 +399,8 @@
|
||||
<data name="ODNAudioSampleRate" xml:space="preserve">
|
||||
<value>默认音频采样率</value>
|
||||
</data>
|
||||
<data name="Tim2AlphaFormat" xml:space="preserve">
|
||||
<value>选择Tim2图片透明度格式。
|
||||
这无法从文件中正确获取。</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -208,6 +208,9 @@
|
||||
<setting name="NexasEncodingCP" serializeAs="String">
|
||||
<value>932</value>
|
||||
</setting>
|
||||
<setting name="TIM2AlphaFormat" serializeAs="String">
|
||||
<value>RGBA</value>
|
||||
</setting>
|
||||
</GameRes.Formats.Properties.Settings>
|
||||
</userSettings>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" /></startup>
|
||||
|
||||
@@ -71,6 +71,8 @@ namespace GameRes
|
||||
BgrX = 6,
|
||||
RgbA = 9,
|
||||
BgrA = 10,
|
||||
RgbA7 = 55,
|
||||
BgrA7 = 66,
|
||||
}
|
||||
|
||||
public class ImageData
|
||||
@@ -124,7 +126,8 @@ namespace GameRes
|
||||
public static ImageData Create (ImageMetaData info, PixelFormat format, BitmapPalette palette,
|
||||
Array pixel_data)
|
||||
{
|
||||
return Create (info, format, palette, pixel_data, (int)info.Width*((format.BitsPerPixel+7)/8));
|
||||
return Create (info, format, palette, pixel_data,
|
||||
format.BitsPerPixel == 4 ? (int)info.Width*format.BitsPerPixel/8 : (int)info.Width*((format.BitsPerPixel+7)/8));
|
||||
}
|
||||
|
||||
public static ImageData CreateFlipped (ImageMetaData info, PixelFormat format, BitmapPalette palette,
|
||||
@@ -215,12 +218,16 @@ namespace GameRes
|
||||
Func<int, Color> get_color;
|
||||
if (PaletteFormat.Bgr == format || PaletteFormat.BgrX == format)
|
||||
get_color = x => Color.FromRgb (palette_data[x+2], palette_data[x+1], palette_data[x]);
|
||||
else if (PaletteFormat.BgrA7 == format)
|
||||
get_color = x => Color.FromArgb(palette_data[x+3] >= byte.MaxValue / 2 ? byte.MaxValue : (byte)(palette_data[x+3] << 1), palette_data[x+2], palette_data[x+1], palette_data[x]);
|
||||
else if (PaletteFormat.BgrA == format)
|
||||
get_color = x => Color.FromArgb (palette_data[x+3], palette_data[x+2], palette_data[x+1], palette_data[x]);
|
||||
else if (PaletteFormat.RgbA == format)
|
||||
get_color = x => Color.FromArgb (palette_data[x+3], palette_data[x], palette_data[x+1], palette_data[x+2]);
|
||||
else if (PaletteFormat.RgbA7 == format)
|
||||
get_color = x => Color.FromArgb (palette_data[x+3] >= byte.MaxValue / 2 ? byte.MaxValue : (byte)(palette_data[x+3] << 1), palette_data[x], palette_data[x+1], palette_data[x+2]);
|
||||
else
|
||||
get_color = x => Color.FromRgb (palette_data[x], palette_data[x+1], palette_data[x+2]);
|
||||
get_color = x => Color.FromRgb (palette_data[x], palette_data[x+1], palette_data[x+2]);
|
||||
|
||||
for (int i = 0; i < colors; ++i)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user