bunch of stuff.

This commit is contained in:
morkt
2023-08-24 01:33:50 +04:00
parent ea096c52ef
commit 77fde27d26
119 changed files with 11078 additions and 619 deletions

View File

@@ -34,6 +34,24 @@ namespace GameRes.Formats.Nonono
public int Seed;
}
internal class NpfArchive : ArcFile
{
public readonly IRandomGenerator KeyGenerator;
public NpfArchive (ArcView arc, ArchiveFormat impl, ICollection<Entry> dir, IRandomGenerator rnd)
: base (arc, impl, dir)
{
KeyGenerator = rnd;
}
}
internal interface IRandomGenerator
{
void SRand (int seed);
int Rand ();
}
[Export(typeof(ArchiveFormat))]
public class NpfOpener : ArchiveFormat
{
@@ -49,8 +67,28 @@ namespace GameRes.Formats.Nonono
{
if (file.View.ReadInt32 (4) != 4 || file.View.ReadInt32 (8) != 1)
return null;
foreach (var rnd in GetGenerators())
{
var dir = ReadIndex (file, rnd);
if (dir != null)
{
return new NpfArchive (file, this, dir, rnd);
}
}
return null;
}
internal IEnumerable<IRandomGenerator> GetGenerators ()
{
yield return new RandomGenerator1 (DefaultSeed);
yield return new RandomGenerator2 (DefaultSeed);
}
List<Entry> ReadIndex (ArcView file, IRandomGenerator rnd)
{
var header = file.View.ReadBytes (12, 20);
var rnd = new RandomGenerator (DefaultSeed);
// rnd.SRand (DefaultSeed); // generator already seeded by GetGenerators()
Decrypt (header, 0, header.Length, rnd);
if (!header.AsciiEqual ("FAT "))
return null;
@@ -84,16 +122,16 @@ namespace GameRes.Formats.Nonono
pos += 20;
name_pos += name_length;
}
return new ArcFile (file, this, dir);
return dir;
}
public override Stream OpenEntry (ArcFile arc, Entry entry)
{
var nent = entry as NpfEntry;
if (null == nent)
return base.OpenEntry (arc, entry);
var narc = (NpfArchive)arc;
var nent = (NpfEntry)entry;
var data = arc.File.View.ReadBytes (entry.Offset, entry.Size);
var rnd = new RandomGenerator (nent.Seed);
var rnd = narc.KeyGenerator;
rnd.SRand (nent.Seed);
Decrypt (data, 0, data.Length, rnd);
return new BinMemoryStream (data, entry.Name);
}
@@ -106,20 +144,20 @@ namespace GameRes.Formats.Nonono
return new ImgXDecoder (input);
}
internal void Decrypt (byte[] data, int pos, int count, RandomGenerator rnd)
internal void Decrypt (byte[] data, int pos, int count, IRandomGenerator rnd)
{
for (int i = 0; i < count; ++i)
data[pos + i] ^= (byte)rnd.Rand();
}
}
internal class RandomGenerator
internal class RandomGenerator1 : IRandomGenerator
{
int m_seed;
const int DefaultSeed = 0x67895;
public RandomGenerator (int seed = DefaultSeed)
public RandomGenerator1 (int seed = DefaultSeed)
{
SRand (seed);
}
@@ -141,4 +179,30 @@ namespace GameRes.Formats.Nonono
return m_seed;
}
}
internal class RandomGenerator2 : IRandomGenerator
{
int m_seed1;
int m_seed2;
const int DefaultSeed = 0x67895;
public RandomGenerator2 (int seed = DefaultSeed)
{
SRand (seed);
}
public void SRand (int seed)
{
m_seed1 = seed;
m_seed2 = ((seed >> 12) ^ (seed << 18)) - 0x579E2B8D;
}
public int Rand ()
{
int n = m_seed2 + ((m_seed1 >> 10) ^ (m_seed1 << 14));
m_seed2 = n - 0x15633649 + ((m_seed2 >> 12) ^ (m_seed2 << 18));
return m_seed2;
}
}
}

View File

@@ -64,7 +64,12 @@ namespace GameRes.Formats.Nonono
using (var input = new MemoryStream (bitmap, header_size, bitmap.Length - header_size))
{
if (8 == m_info.BPP)
palette = ImageFormat.ReadPalette (input);
{
int num_colors = bitmap.ToInt32 (0x20);
if (0 == num_colors)
num_colors = 0x100;
palette = ImageFormat.ReadPalette (input, num_colors);
}
input.Read (pixels, 0, pixels.Length);
}
PixelFormat format = 8 == m_info.BPP ? PixelFormats.Indexed8