diff --git a/ArcFormats/ArcFormats.csproj b/ArcFormats/ArcFormats.csproj
index 1350f3ee..695a8e60 100644
--- a/ArcFormats/ArcFormats.csproj
+++ b/ArcFormats/ArcFormats.csproj
@@ -62,6 +62,7 @@
+
diff --git a/ArcFormats/RenPy/ArcRPA.cs b/ArcFormats/RenPy/ArcRPA.cs
index d113777e..a96168fc 100644
--- a/ArcFormats/RenPy/ArcRPA.cs
+++ b/ArcFormats/RenPy/ArcRPA.cs
@@ -29,6 +29,7 @@ using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Diagnostics;
using System.Globalization;
+using System.Numerics;
using System.IO;
using System.Text;
using GameRes.Compression;
@@ -99,8 +100,8 @@ namespace GameRes.Formats.RenPy
return null;
}
var entry = FormatCatalog.Instance.Create (name);
- entry.Offset = (uint)((int)tuple[0] ^ key);
- entry.UnpackedSize = (uint)((int)tuple[1] ^ key);
+ entry.Offset = (long)(Convert.ToInt64 (tuple[0]) ^ key);
+ entry.UnpackedSize = (uint)(Convert.ToInt32 (tuple[1]) ^ key);
entry.Size = entry.UnpackedSize;
if (tuple.Count > 2)
{
@@ -205,6 +206,8 @@ namespace GameRes.Formats.RenPy
const byte PROTO = 0x80; /* identify pickle protocol */
const byte TUPLE2 = 0x86; /* build 2-tuple from two topmost stack items */
const byte TUPLE3 = 0x87; /* build 3-tuple from three topmost stack items */
+ const byte LONG1 = 0x8A; /* push long from < 256 bytes */
+ const byte LONG4 = 0x8B; /* push really big long */
const byte MARK = (byte)'(';
const byte STOP = (byte)'.';
const byte INT = (byte)'I';
@@ -527,6 +530,16 @@ namespace GameRes.Formats.RenPy
break;
continue;
+ case LONG1:
+ if (!LoadLong())
+ break;
+ continue;
+
+ case LONG4:
+ if (!LoadLong4())
+ break;
+ continue;
+
case APPEND:
if (!LoadAppend())
break;
@@ -675,6 +688,47 @@ namespace GameRes.Formats.RenPy
return true;
}
+ bool LoadLong ()
+ {
+ int count = m_stream.ReadByte();
+ if (-1 == count)
+ return false;
+ m_stack.Push (DecodeLong (count));
+ return true;
+ }
+
+ bool LoadLong4 ()
+ {
+ int count = 0;
+ if (!ReadInt (4, out count) || count < 0)
+ return false;
+ m_stack.Push (DecodeLong (count));
+ return true;
+ }
+
+ object DecodeLong (int count)
+ {
+ if (count <= 0)
+ return 0L;
+ else if (count > 8)
+ {
+ var bytes = new byte[count];
+ m_stream.Read (bytes, 0, count);
+ return new BigInteger (bytes);
+ }
+ else
+ {
+ var bytes = new byte[8];
+ m_stream.Read (bytes, 0, count);
+ if (0 != (bytes[count-1] & 0x80)) // sign bit is set
+ {
+ for (int i = count; i < bytes.Length; ++i)
+ bytes[i] = 0xFF;
+ }
+ return bytes.ToInt64 (0);
+ }
+ }
+
bool LoadCountedTuple (int count)
{
if (m_stack.Count < count)