public void FillTextureBlock(Texture2D tex, int blockX, int blockY, int relX, int relY, byte[] imageBuffer, int imageBufferOffset, IList<ARGB1555Color> pal, int paletteInd, bool flipX, bool flipY)
        {
            var offset1 = imageBufferOffset;
            var offset2 = imageBufferOffset + 16;

            for (int y = 0; y < 8; y++)
            {
                for (int x = 0; x < 8; x++)
                {
                    int actualX = blockX + relX * 8 + (flipX ? (8 - x - 1) : x);
                    int actualY = blockY + relY * 8 + (flipY ? (8 - y - 1) : y);

                    int off = y * 8 + (8 - x - 1);

                    var bit0 = BitHelpers.ExtractBits(imageBuffer[offset1 + ((off / 8) * 2)], 1, off % 8);
                    var bit1 = BitHelpers.ExtractBits(imageBuffer[offset1 + ((off / 8) * 2 + 1)], 1, off % 8);
                    var bit2 = BitHelpers.ExtractBits(imageBuffer[offset2 + ((off / 8) * 2)], 1, off % 8);
                    var bit3 = BitHelpers.ExtractBits(imageBuffer[offset2 + ((off / 8) * 2 + 1)], 1, off % 8);

                    int b = 0;

                    b = BitHelpers.SetBits(b, bit0, 1, 0);
                    b = BitHelpers.SetBits(b, bit1, 1, 1);
                    b = BitHelpers.SetBits(b, bit2, 1, 2);
                    b = BitHelpers.SetBits(b, bit3, 1, 3);
                    
                    Color c = pal[paletteInd * 0x10 + b].GetColor();

                    if (b != 0)
                        c = new Color(c.r, c.g, c.b, 1f);

                    tex.SetPixel(actualX, actualY, c);
                }
            }
        }
Exemple #2
0
 public XM_PatternRow(
     byte?note             = null,
     byte?instrument       = null,
     byte?volumeColumnByte = null,
     byte?effectType       = null,
     byte?effectParameter  = null)
 {
     if (!(instrument.HasValue || volumeColumnByte.HasValue || effectType.HasValue || effectParameter.HasValue))
     {
         if (note.HasValue)
         {
             Flags = note.Value;
             Note  = note.Value;
         }
         Size = 1;
     }
     else
     {
         Size = 1;
         if (note.HasValue)
         {
             Flags = (byte)BitHelpers.SetBits(Flags, 1, 1, 0);
             Note  = note.Value;
             Size++;
         }
         if (instrument.HasValue)
         {
             Flags      = (byte)BitHelpers.SetBits(Flags, 1, 1, 1);
             Instrument = instrument.Value;
             Size++;
         }
         if (volumeColumnByte.HasValue)
         {
             Flags            = (byte)BitHelpers.SetBits(Flags, 1, 1, 2);
             VolumeColumnByte = volumeColumnByte.Value;
             Size++;
         }
         if (effectType.HasValue)
         {
             Flags      = (byte)BitHelpers.SetBits(Flags, 1, 1, 3);
             EffectType = effectType.Value;
             Size++;
         }
         if (effectParameter.HasValue)
         {
             Flags           = (byte)BitHelpers.SetBits(Flags, 1, 1, 4);
             EffectParameter = effectParameter.Value;
             Size++;
         }
     }
 }
        public override async UniTask ExportMenuSpritesAsync(GameSettings settings, string outputPath, bool exportAnimFrames)
        {
            using (var menuContext = new Context(settings))
            {
                using (var bigRayContext = new Context(settings))
                {
                    await LoadFilesAsync(menuContext);
                    await LoadFilesAsync(bigRayContext);

                    // Read the allfix & font files for the menu
                    await LoadExtraFile(menuContext, GetAllfixFilePath(menuContext.Settings), false);

                    var fix = FileFactory.Read <R1_PS1_AllfixFile>(GetAllfixFilePath(menuContext.Settings), menuContext);
                    await LoadExtraFile(menuContext, GetFontFilePath(menuContext.Settings), false);

                    // Correct font palette
                    if (settings.EngineVersion == EngineVersion.R1_PS1_JP)
                    {
                        foreach (R1_PS1_FontData font in fix.AllfixData.FontData)
                        {
                            foreach (R1_ImageDescriptor imgDescr in font.ImageDescriptors)
                            {
                                var paletteInfo = imgDescr.PaletteInfo;
                                paletteInfo          = (ushort)BitHelpers.SetBits(paletteInfo, 509, 10, 6);
                                imgDescr.PaletteInfo = paletteInfo;
                            }
                        }
                    }
                    else
                    {
                        foreach (R1_PS1_FontData font in fix.AllfixData.FontData)
                        {
                            foreach (R1_ImageDescriptor imgDescr in font.ImageDescriptors)
                            {
                                var paletteInfo = imgDescr.PaletteInfo;
                                paletteInfo          = (ushort)BitHelpers.SetBits(paletteInfo, 492, 10, 6);
                                imgDescr.PaletteInfo = paletteInfo;
                            }
                        }
                    }

                    // Read the BigRay file
                    await LoadExtraFile(bigRayContext, GetBigRayFilePath(bigRayContext.Settings), false);

                    var br = bigRayContext.FileExists(GetBigRayFilePath(bigRayContext.Settings)) ? FileFactory.Read <R1_PS1_BigRayFile>(GetBigRayFilePath(bigRayContext.Settings), bigRayContext) : null;

                    // Export
                    await ExportMenuSpritesAsync(menuContext, bigRayContext, outputPath, exportAnimFrames, fix.AllfixData.FontData, fix.AllfixData.WldObj, br?.BigRayData);
                }
            }
        }
Exemple #4
0
        public override void SerializeBitValues <T>(Action <SerializeBits> serializeFunc)
        {
            int    valueInt  = 0;
            int    pos       = 0;
            string logPrefix = LogPrefix;

            // Set bits
            serializeFunc((v, length, name) => {
                valueInt = BitHelpers.SetBits(valueInt, v, length, pos);
                if (Settings.Log)
                {
                    Context.Log.Log(logPrefix + $"  ({typeof(T)}) {name ?? "<no name>"}: {v}");
                }
                pos += length;
                return(v);
            });

            // Serialize value
            Serialize <T>((T)Convert.ChangeType(valueInt, typeof(T)), name: "Value");
        }
        private Stream XORStream(Stream s)
        {
            byte compr_incremental_xor = 0x57;

            var    decompressedStream = new MemoryStream();
            Reader reader             = new Reader(s, isLittleEndian: true); // No using, because we don't want to close the stream

            byte bytes_in_window = reader.ReadByte();

            bytes_in_window ^= 0x53;
            decompressedStream.WriteByte(bytes_in_window);

            uint decompressedSize = reader.ReadUInt32();

            decompressedSize ^= 0x54555657;
            decompressedStream.Write(BitConverter.GetBytes(decompressedSize), 0, 4);
            while (s.Position < s.Length)
            {
                byte b   = reader.ReadByte();
                byte xor = 0;
                // Bit reverse
                for (int i = 0; i < 8; i++)
                {
                    xor = (byte)BitHelpers.SetBits(xor, BitHelpers.ExtractBits(compr_incremental_xor, 1, i), 1, 7 - i);
                }
                b = (byte)(b ^ (xor ^ 0xB9));
                if (compr_incremental_xor == 0xFF)
                {
                    compr_incremental_xor = 0x0;
                }
                else
                {
                    compr_incremental_xor++;
                }
                decompressedStream.WriteByte(b);
            }
            decompressedStream.Position = 0;
            return(decompressedStream);
        }
Exemple #6
0
        /// <summary>
        /// Handles the data serialization
        /// </summary>
        /// <param name="s">The serializer object</param>
        public override void SerializeImpl(SerializerObject s)
        {
            if (s.GameSettings.GameModeSelection == GameModeSelection.MapperPC || s.GameSettings.EngineVersion == EngineVersion.R1_GBA || s.GameSettings.EngineVersion == EngineVersion.R1_DSi)
            {
                TileMapY      = s.Serialize <ushort>(TileMapY, name: nameof(TileMapY));
                TileMapX      = 0;
                CollisionType = (byte)s.Serialize <ushort>((ushort)CollisionType, name: nameof(CollisionType));
            }
            else if (s.GameSettings.EngineVersion == EngineVersion.R1_PC || s.GameSettings.EngineVersion == EngineVersion.R1_PC_Kit || s.GameSettings.EngineVersion == EngineVersion.R1_PC_Edu || s.GameSettings.EngineVersion == EngineVersion.R1_PS1_Edu || s.GameSettings.EngineVersion == EngineVersion.R1_PocketPC)
            {
                TileMapY            = s.Serialize <ushort>(TileMapY, name: nameof(TileMapY));
                TileMapX            = 0;
                CollisionType       = s.Serialize <byte>(CollisionType, name: nameof(CollisionType));
                PC_Unk1             = s.Serialize <byte>(PC_Unk1, name: nameof(PC_Unk1));
                PC_TransparencyMode = s.Serialize <R1_PC_MapTileTransparencyMode>(PC_TransparencyMode, name: nameof(PC_TransparencyMode));
                PC_Unk2             = s.Serialize <byte>(PC_Unk2, name: nameof(PC_Unk2));
            }
            else if (s.GameSettings.EngineVersion == EngineVersion.R1_PS1_JPDemoVol3 || s.GameSettings.EngineVersion == EngineVersion.R1_PS1_JPDemoVol6)
            {
                s.SerializeBitValues <int>(bitFunc =>
                {
                    TileMapX      = (ushort)bitFunc(TileMapX, 10, name: nameof(TileMapX));
                    TileMapY      = (ushort)bitFunc(TileMapY, 6, name: nameof(TileMapY));
                    CollisionType = (byte)bitFunc(CollisionType, 8, name: nameof(CollisionType));
                });
            }
            else if (s.GameSettings.EngineVersion == EngineVersion.R1_Saturn)
            {
                s.SerializeBitValues <ushort>(bitFunc =>
                {
                    TileMapX = (ushort)bitFunc(TileMapX, 4, name: nameof(TileMapX));
                    TileMapY = (ushort)bitFunc(TileMapY, 12, name: nameof(TileMapY));
                });

                CollisionType = s.Serialize <byte>(CollisionType, name: nameof(CollisionType));
                s.Serialize <byte>(0, name: "Padding");
            }
            else if (s.GameSettings.MajorEngineVersion == MajorEngineVersion.Rayman1_Jaguar)
            {
                s.SerializeBitValues <ushort>(bitFunc =>
                {
                    TileMapY      = (ushort)bitFunc(TileMapY, 12, name: nameof(TileMapY));
                    CollisionType = (byte)bitFunc(CollisionType, 4, name: nameof(CollisionType));
                });

                TileMapX = 0;
            }
            else if (s.GameSettings.MajorEngineVersion == MajorEngineVersion.SNES)
            {
                s.SerializeBitValues <ushort>(bitFunc =>
                {
                    TileMapY       = (ushort)bitFunc(TileMapY, 10, name: nameof(TileMapY));
                    HorizontalFlip = bitFunc(HorizontalFlip ? 1 : 0, 1, name: nameof(HorizontalFlip)) == 1;
                    VerticalFlip   = bitFunc(VerticalFlip ? 1 : 0, 1, name: nameof(VerticalFlip)) == 1;
                    CollisionType  = (byte)bitFunc(CollisionType, 4, name: nameof(CollisionType));
                });

                TileMapX = 0;
            }
            else if (s.GameSettings.MajorEngineVersion == MajorEngineVersion.GBA)
            {
                // TODO: Use SerializeBitValues

                if ((GBATileType == GBA_TileType.BGTile || GBATileType == GBA_TileType.FGTile) &&
                    s.GameSettings.EngineVersion != EngineVersion.GBA_SplinterCell_NGage &&
                    s.GameSettings.EngineVersion != EngineVersion.GBA_BatmanVengeance)
                {
                    int numBits = Is8Bpp ? 9 : 10;

                    if (s.GameSettings.EngineVersion <= EngineVersion.GBA_BatmanVengeance)
                    {
                        numBits = 8;
                    }/*else if(s.GameSettings.EngineVersion >= EngineVersion.GBA_StarWarsTrilogy) {
                      * numBits = Is8Bpp ? 9 : 10;
                      * } else if (s.GameSettings.EngineVersion >= EngineVersion.GBA_SplinterCell) {
                      * numBits = 9;
                      * if (GBATileType == GBA_TileType.FGTile) numBits = 10;
                      * }*/

                    ushort value = 0;

                    value = (ushort)BitHelpers.SetBits(value, TileMapY, numBits, 0);
                    //value = (ushort)BitHelpers.SetBits(value, VerticalFlip ? 1 : 0, 1, numBits);
                    value = (ushort)BitHelpers.SetBits(value, HorizontalFlip ? 1 : 0, 1, numBits);
                    value = (ushort)BitHelpers.SetBits(value, PaletteIndex, 4, 12);

                    value = s.Serialize <ushort>(value, name: nameof(value));

                    TileMapY = (ushort)BitHelpers.ExtractBits(value, numBits, 0);
                    TileMapX = 0;
                    if (Is8Bpp)
                    {
                        IsFirstBlock = BitHelpers.ExtractBits(value, 1, 9) == 1;
                    }
                    HorizontalFlip = BitHelpers.ExtractBits(value, 1, 10) == 1;
                    VerticalFlip   = BitHelpers.ExtractBits(value, 1, 11) == 1;
                    PaletteIndex   = (byte)BitHelpers.ExtractBits(value, 4, 12);

                    s.Log($"{nameof(TileMapY)}: {TileMapY}");
                    s.Log($"{nameof(HorizontalFlip)}: {HorizontalFlip}");
                    s.Log($"{nameof(IsFirstBlock)}: {IsFirstBlock}");
                    s.Log($"{nameof(PaletteIndex)}: {PaletteIndex}");
                }
                else if (GBATileType == GBA_TileType.Mode7Tile)
                {
                    ushort value = 0;

                    value = (ushort)BitHelpers.SetBits(value, TileMapY, 9, 0);
                    //value = (ushort)BitHelpers.SetBits(value, VerticalFlip ? 1 : 0, 1, numBits);
                    value = (ushort)BitHelpers.SetBits(value, HorizontalFlip ? 1 : 0, 1, 9);

                    value = s.Serialize <ushort>(value, name: nameof(value));

                    TileMapY       = (ushort)BitHelpers.ExtractBits(value, 9, 0);
                    TileMapX       = 0;
                    IsFirstBlock   = BitHelpers.ExtractBits(value, 1, 9) == 1;
                    HorizontalFlip = BitHelpers.ExtractBits(value, 1, 10) == 1;
                    VerticalFlip   = BitHelpers.ExtractBits(value, 1, 11) == 1;

                    s.Log($"{nameof(TileMapY)}: {TileMapY}");
                    s.Log($"{nameof(HorizontalFlip)}: {HorizontalFlip}");
                    s.Log($"{nameof(IsFirstBlock)}: {IsFirstBlock}");
                }
                else
                {
                    int numBits = Is8Bpp ? 14 : 11;

                    if (s.GameSettings.EngineVersion <= EngineVersion.GBA_BatmanVengeance)
                    {
                        numBits = 10;
                    }
                    else if (s.GameSettings.EngineVersion == EngineVersion.GBA_SplinterCell_NGage)
                    {
                        numBits = Is8Bpp ? 14 : 12;
                    }
                    else if (s.GameSettings.EngineVersion >= EngineVersion.GBA_SplinterCell)
                    {
                        numBits = Is8Bpp ? 14 : 12;
                    }

                    ushort value = 0;

                    value = (ushort)BitHelpers.SetBits(value, TileMapY, numBits, 0);
                    value = (ushort)BitHelpers.SetBits(value, HorizontalFlip ? 1 : 0, 1, numBits);
                    value = (ushort)BitHelpers.SetBits(value, PaletteIndex, 4, 12);

                    value = s.Serialize <ushort>(value, name: nameof(value));

                    TileMapY = (ushort)BitHelpers.ExtractBits(value, numBits, 0);
                    if (s.GameSettings.EngineVersion == EngineVersion.GBA_SplinterCell_NGage && Is8Bpp)
                    {
                        TileMapY = (ushort)BitHelpers.ExtractBits(value, numBits - 1, 0);
                    }
                    TileMapX       = 0;
                    HorizontalFlip = BitHelpers.ExtractBits(value, 1, numBits) == 1;
                    if (s.GameSettings.EngineVersion == EngineVersion.GBA_BatmanVengeance)
                    {
                        VerticalFlip = BitHelpers.ExtractBits(value, 1, numBits + 1) == 1;
                    }
                    if (!Is8Bpp)
                    {
                        if (s.GameSettings.EngineVersion >= EngineVersion.GBA_SplinterCell)
                        {
                            PaletteIndex = (byte)BitHelpers.ExtractBits(value, 3, 13);
                        }
                        else
                        {
                            PaletteIndex = (byte)BitHelpers.ExtractBits(value, 4, 12);
                        }

                        if (s.GameSettings.EngineVersion == EngineVersion.GBA_SplinterCell)
                        {
                            PaletteIndex += 8;
                        }
                    }
                    else if (s.GameSettings.EngineVersion != EngineVersion.GBA_BatmanVengeance)
                    {
                        VerticalFlip = BitHelpers.ExtractBits(value, 1, numBits + 1) == 1;
                    }

                    s.Log($"{nameof(TileMapY)}: {TileMapY}");
                    s.Log($"{nameof(HorizontalFlip)}: {HorizontalFlip}");
                    s.Log($"{nameof(PaletteIndex)}: {PaletteIndex}");
                }
            }
            else if (s.GameSettings.EngineVersion == EngineVersion.R1_PS1 || s.GameSettings.EngineVersion == EngineVersion.R2_PS1)
            {
                s.SerializeBitValues <ushort>(bitFunc =>
                {
                    TileMapX      = (ushort)bitFunc(TileMapX, 4, name: nameof(TileMapX));
                    TileMapY      = (ushort)bitFunc(TileMapY, 6, name: nameof(TileMapY));
                    CollisionType = (byte)bitFunc(CollisionType, 6, name: nameof(CollisionType));
                });
            }
            else if (s.GameSettings.EngineVersion == EngineVersion.R1_PS1_JP)
            {
                s.SerializeBitValues <ushort>(bitFunc =>
                {
                    TileMapX      = (ushort)bitFunc(TileMapX, 9, name: nameof(TileMapX));
                    CollisionType = (byte)bitFunc(CollisionType, 7, name: nameof(CollisionType));
                });
            }
            else if (s.GameSettings.MajorEngineVersion == MajorEngineVersion.GBARRR)
            {
                if (GBARRRType == GBARRR_MapBlock.MapType.Collision)
                {
                    CollisionType = s.Serialize <byte>(CollisionType, name: nameof(CollisionType));
                }
                else if (GBARRRType == GBARRR_MapBlock.MapType.Tiles)
                {
                    TileMapY = s.Serialize <ushort>(TileMapY, name: nameof(TileMapY));
                }
                else if (GBARRRType == GBARRR_MapBlock.MapType.Foreground)
                {
                    s.SerializeBitValues <ushort>(bitFunc =>
                    {
                        TileMapY       = (ushort)bitFunc(TileMapY, 10, name: nameof(TileMapY));
                        HorizontalFlip = bitFunc(HorizontalFlip ? 1 : 0, 1, name: nameof(HorizontalFlip)) == 1;
                        VerticalFlip   = bitFunc(VerticalFlip ? 1 : 0, 1, name: nameof(VerticalFlip)) == 1;
                        PaletteIndex   = (byte)bitFunc(PaletteIndex, 4, name: nameof(PaletteIndex));
                        //Unk = (byte)bitFunc(Unk, 4, name: nameof(Unk));
                    });
                }
                else if (GBARRRType == GBARRR_MapBlock.MapType.Menu)
                {
                    s.SerializeBitValues <ushort>(bitFunc =>
                    {
                        TileMapY       = (ushort)bitFunc(TileMapY, 8, name: nameof(TileMapY));
                        GBARRR_MenuUnk = (byte)bitFunc(GBARRR_MenuUnk, 2, name: nameof(GBARRR_MenuUnk));
                        HorizontalFlip = bitFunc(HorizontalFlip ? 1 : 0, 1, name: nameof(HorizontalFlip)) == 1;
                        VerticalFlip   = bitFunc(VerticalFlip ? 1 : 0, 1, name: nameof(VerticalFlip)) == 1;
                        PaletteIndex   = (byte)bitFunc(PaletteIndex, 4, name: nameof(PaletteIndex));
                        //Unk = (byte)bitFunc(Unk, 4, name: nameof(Unk));
                    });
                }
                else if (GBARRRType == GBARRR_MapBlock.MapType.Mode7Tiles)
                {
                    TileMapY = s.Serialize <byte>((byte)TileMapY, name: nameof(TileMapY));
                }
            }
        }
        public Stream EncodeStream(Stream s)
        {
            var memStream = new MemoryStream();

            Reader reader = new Reader(s);

            using (Stream temp = new MemoryStream()) {
                using (Writer writer = new Writer(temp)) {
                    byte[] compr_big_window = new byte[256 * 8];
                    for (int i = 0; i < 256; i++)
                    {
                        for (int j = 0; j < 8; j++)
                        {
                            compr_big_window[i * 8 + j] = (byte)i;
                        }
                    }
                    byte[] compr_window = new byte[8];
                    for (int j = 0; j < 8; j++)
                    {
                        compr_window[j] = 0;
                    }
                    writer.Write((byte)0); // checksum
                    writer.Write((uint)0); // size

                    uint startPos = (uint)reader.BaseStream.Position;
                    writer.BeginCalculateChecksum(new Checksum8Calculator());
                    bool isFinished = false;
                    while (!isFinished)
                    {
                        uint num_bytesToCompress = 0;
                        for (int i = 0; i < 8; i++)
                        {
                            if (reader.BaseStream.Position >= reader.BaseStream.Length)
                            {
                                break;
                            }
                            num_bytesToCompress++;
                            byte b = reader.ReadByte();
                            compr_window[i] = b;
                        }
                        if (num_bytesToCompress > 0)
                        {
                            int maxOccurrencesInBigWindow = -1;
                            int bestBigWindowI            = 0;
                            for (int i = 0; i < 256; i++)
                            {
                                int occurrencesInBigWindow = 0;
                                for (int j = 0; j < num_bytesToCompress; j++)
                                {
                                    if (compr_big_window[i * 8 + j] == compr_window[j])
                                    {
                                        occurrencesInBigWindow++;
                                    }
                                }
                                if (occurrencesInBigWindow > maxOccurrencesInBigWindow)
                                {
                                    maxOccurrencesInBigWindow = occurrencesInBigWindow;
                                    bestBigWindowI            = i;
                                    if (occurrencesInBigWindow == num_bytesToCompress)
                                    {
                                        break;
                                    }
                                }
                            }
                            writer.Write((byte)bestBigWindowI);
                            byte windowUpdateBitArray = 0;
                            for (int i = 0; i < Math.Min(8, num_bytesToCompress); i++)
                            {
                                if (compr_big_window[bestBigWindowI * 8 + i] != compr_window[i])
                                {
                                    windowUpdateBitArray = (byte)BitHelpers.SetBits(windowUpdateBitArray, 1, 1, i);
                                }
                            }
                            writer.Write(windowUpdateBitArray);
                            for (int i = 0; i < 8; i++)
                            {
                                if (windowUpdateBitArray % 2 == 1)
                                {
                                    writer.Write((byte)compr_window[i]);
                                }
                                windowUpdateBitArray /= 2;
                            }
                            if (num_bytesToCompress >= 8)
                            {
                                for (int i = 0; i < 8; i++)
                                {
                                    compr_big_window[bestBigWindowI * 8 + i] = compr_window[i];
                                }
                            }
                            else
                            {
                                writer.Write((byte)num_bytesToCompress);
                                isFinished = true;
                            }
                        }
                        else
                        {
                            isFinished = true;
                        }
                    }
                    byte checksum         = writer.EndCalculateChecksum <byte>();
                    uint decompressedSize = (uint)reader.BaseStream.Position - startPos;
                    writer.BaseStream.Position = 0;
                    writer.Write((byte)checksum);
                    writer.Write((uint)decompressedSize);
                    writer.BaseStream.Position = 0;
                    using (Stream xor = XORStream(writer.BaseStream)) {
                        xor.CopyTo(memStream);
                    }
                }
            }

            memStream.Position = 0;
            return(memStream);
        }