Esempio n. 1
0
    public static byte[] Decompress(ReadStream compressed)
    {
        List <byte> decompressed = new List <byte>();

        while (true)
        {
            // If an ff-byte is encountered the decompression has completed.
            if (compressed.Peek() == LzEnd)
            {
                break;
            }

            // Bits 5-7 are occupied by control command.
            int command = (compressed.Peek() & 0xe0) >> 5;
            int length  = 1;

            // The long command is used when 5 bits aren't enough.
            if (command == LzLong)
            {
                // Bits 2-4 contain the new control code.
                command = (compressed.Peek() & 0x1c) >> 2;
                // Bits 0-1 are appended to a new byte as bits 8-9, allowing a 10-bit operand.
                length += (compressed.u8() & 0x3) << 8;
                length += compressed.u8();
            }
            else
            {
                // If not a long command, bits 0-5 contain the command's operand.
                length += (compressed.u8() & 0x1f);
            }

            switch (command)
            {
            case LzLiteral: Literal(compressed, decompressed, length); break;

            case LzIterate: Iterate(compressed, decompressed, length); break;

            case LzAlternate: Alternate(compressed, decompressed, length); break;

            case LzBlank: Blank(compressed, decompressed, length); break;

            case LzRepeat: Repeat(compressed, decompressed, length, 1, false); break;

            case LzFlip: Repeat(compressed, decompressed, length, 1, true); break;

            case LzReverse: Repeat(compressed, decompressed, length, -1, false); break;
            }
        }

        return(decompressed.ToArray());
    }
Esempio n. 2
0
    private void LoadSpecies()
    {
        const int maxIndexNumber = 190;

        int numBaseStats = IsYellow ? 151 : 150;

        byte[]     pokedex = ROM.Subarray(SYM["PokedexOrder"], maxIndexNumber);
        ReadStream data    = ROM.From("BaseStats");

        for (int i = 0; i < numBaseStats; i++)
        {
            byte indexNumber = (byte)Array.IndexOf(pokedex, data.Peek());
            Species.Add(new RbySpecies(this, ++indexNumber, data));
        }

        if (this is RedBlue)
        {
            Species.Add(new RbySpecies(this, 21, ROM.From(SYM["MewBaseStats"])));
        }

        // Add MISSINGNO data
        for (int i = 1; i <= maxIndexNumber; i++)
        {
            if (pokedex[i - 1] == 0)
            {
                RbySpecies species = new RbySpecies(this, (byte)i);
                Species.Add(new RbySpecies(this, (byte)i));
            }
        }
    }
Esempio n. 3
0
    public static void Repeat(ReadStream compressed, List <byte> decompressed, int length, int direction, bool flipped)
    {
        // Repeater commands repeat any data already present in the decompressed stream.
        // They take an additional singed operand to mark the relative starting point.
        int offset = 0;

        if (compressed.Peek() >= 0x80)
        {
            // If the operand is negative, it wraps around from the current position.
            offset = compressed.u8() & 0x7f;
            offset = decompressed.Count - offset - 1;
        }
        else
        {
            // For positive operands, a 16-bit offset is used.
            offset = compressed.u16be();
        }

        for (int i = 0; i < length; i++)
        {
            byte b = decompressed[offset + i * direction];
            // Reverse the bits if the command desires it.
            if (flipped)
            {
                b = (byte)(((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16);
            }
            decompressed.Add(b);
        }
    }