mirror of
https://github.com/crskycode/GARbro.git
synced 2024-11-26 23:24:00 +08:00
(ODN): sometimes scripts are not encrypted.
added possible image dimensions.
This commit is contained in:
parent
657368812e
commit
cd527552b8
@ -55,6 +55,11 @@ namespace GameRes.Formats.Valkyria
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class OdnEntry : Entry
|
||||||
|
{
|
||||||
|
public bool IsEncrypted;
|
||||||
|
}
|
||||||
|
|
||||||
[Export(typeof(ArchiveFormat))]
|
[Export(typeof(ArchiveFormat))]
|
||||||
sealed public class OdnOpener : ArchiveFormat
|
sealed public class OdnOpener : ArchiveFormat
|
||||||
{
|
{
|
||||||
@ -67,9 +72,11 @@ namespace GameRes.Formats.Valkyria
|
|||||||
public OdnOpener ()
|
public OdnOpener ()
|
||||||
{
|
{
|
||||||
Settings = new[] { AudioSampleRate };
|
Settings = new[] { AudioSampleRate };
|
||||||
Extensions = new[] { "odn", "dat" };
|
Extensions = RequiredExtensions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static string[] RequiredExtensions = new[] { "odn", "dat", "pni" };
|
||||||
|
|
||||||
FixedSetSetting AudioSampleRate = new FixedSetSetting (Properties.Settings.Default) {
|
FixedSetSetting AudioSampleRate = new FixedSetSetting (Properties.Settings.Default) {
|
||||||
Name = "ODNAudioSampleRate",
|
Name = "ODNAudioSampleRate",
|
||||||
Text = arcStrings.ODNAudioSampleRate,
|
Text = arcStrings.ODNAudioSampleRate,
|
||||||
@ -78,7 +85,7 @@ namespace GameRes.Formats.Valkyria
|
|||||||
|
|
||||||
public override ArcFile TryOpen (ArcView file)
|
public override ArcFile TryOpen (ArcView file)
|
||||||
{
|
{
|
||||||
if (!file.Name.HasAnyOfExtensions ("odn", "dat"))
|
if (!file.Name.HasAnyOfExtensions (RequiredExtensions))
|
||||||
return null;
|
return null;
|
||||||
var reader = new OdnIndexReader (file);
|
var reader = new OdnIndexReader (file);
|
||||||
var dir = reader.ReadIndex();
|
var dir = reader.ReadIndex();
|
||||||
@ -87,14 +94,15 @@ namespace GameRes.Formats.Valkyria
|
|||||||
return new ArcFile (file, this, dir);
|
return new ArcFile (file, this, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static readonly Regex Image24NameRe = new Regex ("^(?:back|phii)");
|
internal static readonly Regex Image24NameRe = new Regex ("^(?:back|phii|psss)");
|
||||||
internal static readonly Regex Image32NameRe = new Regex ("^(?:data|codn|cccc|fund)");
|
internal static readonly Regex Image32NameRe = new Regex ("^(?:data|codn|cccc|fund|puni|wind)");
|
||||||
internal static readonly Regex ScriptNameRe = new Regex ("^(?:scrp|menu|sysm)");
|
internal static readonly Regex ScriptNameRe = new Regex ("^(?:scrp|menu|sysm)");
|
||||||
internal static readonly Regex AudioNameRe = new Regex ("^hime");
|
internal static readonly Regex AudioNameRe = new Regex ("^hime");
|
||||||
|
|
||||||
public override Stream OpenEntry (ArcFile arc, Entry entry)
|
public override Stream OpenEntry (ArcFile arc, Entry entry)
|
||||||
{
|
{
|
||||||
if (ScriptNameRe.IsMatch (entry.Name))
|
var oent = entry as OdnEntry;
|
||||||
|
if (oent != null && oent.IsEncrypted)
|
||||||
{
|
{
|
||||||
byte key = (byte)~entry.Offset;
|
byte key = (byte)~entry.Offset;
|
||||||
var data = arc.File.View.ReadBytes (entry.Offset, entry.Size);
|
var data = arc.File.View.ReadBytes (entry.Offset, entry.Size);
|
||||||
@ -140,6 +148,11 @@ namespace GameRes.Formats.Valkyria
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
UnpackImage (input, output, pixel_size);
|
UnpackImage (input, output, pixel_size);
|
||||||
|
if (entry.Name.StartsWith ("wind") && output.Length == 1024 * 256 * pixel_size)
|
||||||
|
{
|
||||||
|
var info = new ImageMetaData { Width = 1024, Height = 256, BPP = pixel_size * 8 };
|
||||||
|
return new OdnImageDecoder (output, info);
|
||||||
|
}
|
||||||
return CreateImageDecoder (output, pixel_size);
|
return CreateImageDecoder (output, pixel_size);
|
||||||
}
|
}
|
||||||
catch { /* try different pixel size */ }
|
catch { /* try different pixel size */ }
|
||||||
@ -169,8 +182,10 @@ namespace GameRes.Formats.Valkyria
|
|||||||
static readonly Size[] ImageDimensions = new Size[]
|
static readonly Size[] ImageDimensions = new Size[]
|
||||||
{
|
{
|
||||||
new Size (1024, 768),
|
new Size (1024, 768),
|
||||||
|
new Size (1024, 512),
|
||||||
new Size (800, 600),
|
new Size (800, 600),
|
||||||
new Size (640, 480),
|
new Size (640, 480),
|
||||||
|
new Size (512, 512),
|
||||||
new Size (400, 600),
|
new Size (400, 600),
|
||||||
new Size (400, 200),
|
new Size (400, 200),
|
||||||
};
|
};
|
||||||
@ -221,6 +236,7 @@ namespace GameRes.Formats.Valkyria
|
|||||||
byte[] m_entry_buf = new byte[0x20];
|
byte[] m_entry_buf = new byte[0x20];
|
||||||
List<Entry> m_dir = new List<Entry>();
|
List<Entry> m_dir = new List<Entry>();
|
||||||
Encoding m_enc;
|
Encoding m_enc;
|
||||||
|
bool m_scripts_encrypted = true;
|
||||||
|
|
||||||
public OdnIndexReader (ArcView file)
|
public OdnIndexReader (ArcView file)
|
||||||
{
|
{
|
||||||
@ -265,6 +281,11 @@ namespace GameRes.Formats.Valkyria
|
|||||||
index_offset += 0x10;
|
index_offset += 0x10;
|
||||||
if (m_entry_buf.AsciiEqual (0, "END_ffffffffffff"))
|
if (m_entry_buf.AsciiEqual (0, "END_ffffffffffff"))
|
||||||
break;
|
break;
|
||||||
|
else if (m_entry_buf.AsciiEqual (0, "ffffffffffffffff"))
|
||||||
|
{
|
||||||
|
m_scripts_encrypted = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
else if (m_entry_buf.AsciiEqual (0, "HIME_END"))
|
else if (m_entry_buf.AsciiEqual (0, "HIME_END"))
|
||||||
{
|
{
|
||||||
index_offset += 8;
|
index_offset += 8;
|
||||||
@ -272,10 +293,10 @@ namespace GameRes.Formats.Valkyria
|
|||||||
}
|
}
|
||||||
var name = m_enc.GetString (m_entry_buf, 0, 8);
|
var name = m_enc.GetString (m_entry_buf, 0, 8);
|
||||||
var offset = m_enc.GetString (m_entry_buf, 8, 8);
|
var offset = m_enc.GetString (m_entry_buf, 8, 8);
|
||||||
var entry = new Entry { Name = name, Offset = Convert.ToUInt32 (offset, 16) };
|
var entry = new OdnEntry { Name = name, Offset = Convert.ToUInt32 (offset, 16) };
|
||||||
m_dir.Add (entry);
|
m_dir.Add (entry);
|
||||||
}
|
}
|
||||||
foreach (var entry in m_dir)
|
foreach (OdnEntry entry in m_dir)
|
||||||
entry.Offset += index_offset;
|
entry.Offset += index_offset;
|
||||||
if (m_dir.Any() && m_dir[m_dir.Count-1].Offset == m_file.MaxOffset)
|
if (m_dir.Any() && m_dir[m_dir.Count-1].Offset == m_file.MaxOffset)
|
||||||
m_dir.RemoveAt (m_dir.Count-1);
|
m_dir.RemoveAt (m_dir.Count-1);
|
||||||
@ -293,7 +314,7 @@ namespace GameRes.Formats.Valkyria
|
|||||||
if (m_file.MaxOffset == offset)
|
if (m_file.MaxOffset == offset)
|
||||||
break;
|
break;
|
||||||
var name = m_enc.GetString (m_entry_buf, 0, 8);
|
var name = m_enc.GetString (m_entry_buf, 0, 8);
|
||||||
var entry = new Entry { Name = name, Offset = offset };
|
var entry = new OdnEntry { Name = name, Offset = offset };
|
||||||
m_dir.Add (entry);
|
m_dir.Add (entry);
|
||||||
index_offset += record_size;
|
index_offset += record_size;
|
||||||
if (record_size != m_file.View.Read (index_offset, m_entry_buf, 0, record_size))
|
if (record_size != m_file.View.Read (index_offset, m_entry_buf, 0, record_size))
|
||||||
@ -311,7 +332,7 @@ namespace GameRes.Formats.Valkyria
|
|||||||
break;
|
break;
|
||||||
var name = m_enc.GetString (m_entry_buf, 0, 8);
|
var name = m_enc.GetString (m_entry_buf, 0, 8);
|
||||||
var offset = m_enc.GetString (m_entry_buf, 8, 8);
|
var offset = m_enc.GetString (m_entry_buf, 8, 8);
|
||||||
var entry = new Entry { Name = name, Offset = Convert.ToUInt32 (offset, 16) };
|
var entry = new OdnEntry { Name = name, Offset = Convert.ToUInt32 (offset, 16) };
|
||||||
m_dir.Add (entry);
|
m_dir.Add (entry);
|
||||||
if (0x10 != m_file.View.Read (index_offset, m_entry_buf, 0, 0x10))
|
if (0x10 != m_file.View.Read (index_offset, m_entry_buf, 0, 0x10))
|
||||||
throw new InvalidFormatException();
|
throw new InvalidFormatException();
|
||||||
@ -333,7 +354,7 @@ namespace GameRes.Formats.Valkyria
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < m_dir.Count; ++i)
|
for (int i = 0; i < m_dir.Count; ++i)
|
||||||
{
|
{
|
||||||
var entry = m_dir[i];
|
var entry = (OdnEntry)m_dir[i];
|
||||||
|
|
||||||
long next_offset = i+1 < m_dir.Count ? m_dir[i+1].Offset : m_file.MaxOffset;
|
long next_offset = i+1 < m_dir.Count ? m_dir[i+1].Offset : m_file.MaxOffset;
|
||||||
entry.Size = (uint)(next_offset - entry.Offset);
|
entry.Size = (uint)(next_offset - entry.Offset);
|
||||||
@ -345,6 +366,7 @@ namespace GameRes.Formats.Valkyria
|
|||||||
else if (OdnOpener.ScriptNameRe.IsMatch (entry.Name))
|
else if (OdnOpener.ScriptNameRe.IsMatch (entry.Name))
|
||||||
{
|
{
|
||||||
entry.Type = "script";
|
entry.Type = "script";
|
||||||
|
entry.IsEncrypted = m_scripts_encrypted;
|
||||||
}
|
}
|
||||||
else if (OdnOpener.AudioNameRe.IsMatch (entry.Name))
|
else if (OdnOpener.AudioNameRe.IsMatch (entry.Name))
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user