UScript implementation of reading CompactIndex

Discussions about Coding and Scripting

UScript implementation of reading CompactIndex

Postby Barbie » Sun Oct 30, 2016 4:52 pm

If you have once read about the Unreal package format, you will have noticed that INDEX data type, the compact representation of integers: small absolute values -64..+64 are stored in one byte only, bigger integers need up to 5 bytes, depending on their distance to zero.

Is there an UScript implementation for reading such from a stream? ("stream" is an array of byte in this case.)
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett
User avatar
Barbie
Godlike
 
Posts: 1648
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: UScript implementation of reading CompactIndex

Postby Higor » Sun Oct 30, 2016 7:21 pm

Are you serializing through XC_Core?
Higor
Godlike
 
Posts: 1718
Joined: Sun Mar 04, 2012 6:47 pm

Re: UScript implementation of reading CompactIndex

Postby Barbie » Sun Oct 30, 2016 7:30 pm

Higor wrote:Are you serializing through XC_Core?
No, it is intended for a mutator that should be able to run on a default installation.
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett
User avatar
Barbie
Godlike
 
Posts: 1648
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: UScript implementation of reading CompactIndex

Postby Chris » Sun Oct 30, 2016 7:39 pm

Have a look at the serializer.
Code: Select all
//
// FCompactIndex serializer.
//
FArchive& operator<<( FArchive& Ar, FCompactIndex& I )
{
          INT Original = I.Value;
   DWORD V = Abs(I.Value);
          BYTE B0 = ((I.Value>=0) ? 0 : 0x80) + ((V < 0x40) ? V : ((V & 0x3f)+0x40));
        I.Value = 0;
        Ar << B0;
        if( B0 & 0x40 )
        {
            V >>= 6;
            BYTE B1 = (V < 0x80) ? V : ((V & 0x7f)+0x80);
            Ar << B1;
            if( B1 & 0x80 )
            {
                V >>= 7;
                BYTE B2 = (V < 0x80) ? V : ((V & 0x7f)+0x80);
                Ar << B2;
                if( B2 & 0x80 )
                {
                    V >>= 7;
                    BYTE B3 = (V < 0x80) ? V : ((V & 0x7f)+0x80);
                    Ar << B3;
                    if( B3 & 0x80 )
                    {
                        V >>= 7;
                        BYTE B4 = V;
                        Ar << B4;
                        I.Value = B4;
                    }
                    I.Value = (I.Value << 7) + (B3 & 0x7f);
                }
                I.Value = (I.Value << 7) + (B2 & 0x7f);
            }
            I.Value = (I.Value << 7) + (B1 & 0x7f);
        }
        I.Value = (I.Value << 6) + (B0 & 0x3f);
        if( B0 & 0x80 )
            I.Value = -I.Value;
        if( Ar.IsSaving() && I.Value!=Original )
            appErrorf("Mismatch: %08X %08X",I.Value,Original);
    }
    return Ar;
}
Chris
Experienced
 
Posts: 116
Joined: Mon Nov 24, 2014 9:27 am

Re: UScript implementation of reading CompactIndex

Postby Barbie » Mon Oct 31, 2016 8:46 am

Thanks for that implementation, but it does not look like UScript ;o). The Wiki page I mentioned in first post has also an C# implementation, and additionally I got one in Delphi Pascal.
To save the time for translating and testing I asked for an existing (hopefully tested) UScript implementation.
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett
User avatar
Barbie
Godlike
 
Posts: 1648
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: UScript implementation of reading CompactIndex

Postby Chris » Mon Oct 31, 2016 10:16 am

Barbie wrote:Thanks for that implementation, but it does not look like UScript ;o). The Wiki page I mentioned in first post has also an C# implementation, and additionally I got one in Delphi Pascal.
To save the time for translating and testing I asked for an existing (hopefully tested) UScript implementation.

May I ask what the use for this is exactly? That C# version would take a few minutes to port to UScript since the syntax is similar and the necessary bitwise operators are all available. Since the bitwise operators only exist for Integers you will need to work with Integers instead of bytes.

Code: Select all
final function int ReadCompactInteger()
{
   local int output;
   local bool signed;
        local int bytes[4]; //For some reason Epic decided not to implement bitwise ops for bytes. Fill with whatever bytes you want to decode here.
        local int i;
   for(i = 0; i < 5; i++)
   {
      // First byte
      if(i == 0)
      {
         // Bit: X0000000
         if((bytes[i] & 0x80) > 0)
            signed = true;
         // Bits: 00XXXXXX
         output = (output | (bytes[i] & 0x3F));
         // Bit: 0X000000
         if((bytes[i] & 0x40) == 0)
            break;
      }
      // Last byte
      else if(i == 4)
      {
         // Bits: 000XXXXX -- the 0 bits are ignored
         // (hits the 32 bit boundary)
         output = (output | (bytes[i] & 0x1F) << (/*6 + (3 * 7) */ 27)); //Chris: If you need the runtime to do this math for you then you should not be coding at all.
      }
      // Middle bytes
      else
      {
         // Bits: 0XXXXXXX
         output = (output | (bytes[i] & 0x7F) << (6 + ((i - 1) * 7)));
         // Bit: X0000000
         if((bytes[i] & 0x80) == 0)
            break;
      }
   }
   // multiply by negative one here, since the first 6+ bits could be 0
   if(signed)
      output *= -1;
   return output;
}


Atleast you can do the testing yourself.
Chris
Experienced
 
Posts: 116
Joined: Mon Nov 24, 2014 9:27 am

Re: UScript implementation of reading CompactIndex

Postby Barbie » Mon Oct 31, 2016 1:49 pm

Thanks for translating into UScript. :tu:
Chris wrote:May I ask what the use for this is exactly?
Of course. I'm still having a Map Patcher Mutator in mind (but on low priority). I'm going to add the description there.
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett
User avatar
Barbie
Godlike
 
Posts: 1648
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: UScript implementation of reading CompactIndex

Postby Chris » Mon Oct 31, 2016 3:31 pm

Barbie wrote:Thanks for translating into UScript. :tu:
Chris wrote:May I ask what the use for this is exactly?
Of course. I'm still having a Map Patcher Mutator in mind (but on low priority). I'm going to add the description there.

I'm kinda curious as to why you need to explicitly decode compact indices in UScript. You probably already know that the compacts are only really relevant when we're dealing with archieves, are you planning to do some file reading within UScript?
Chris
Experienced
 
Posts: 116
Joined: Mon Nov 24, 2014 9:27 am


Return to Coding, Scripting

Who is online

Users browsing this forum: No registered users and 4 guests