Beispiel #1
0
        /// <summary>
        /// Serializes the data
        /// </summary>
        /// <param name="s">The serializer object</param>
        public override void SerializeImpl(SerializerObject s)
        {
            if (FileType == Type.World)
            {
                // Serialize header
                BG1 = s.Serialize <ushort>(BG1, name: nameof(BG1));
                BG2 = s.Serialize <ushort>(BG2, name: nameof(BG2));
                Plan0NumPcxCount = s.Serialize <byte>(Plan0NumPcxCount, name: nameof(Plan0NumPcxCount));
                s.DoXOR(0x19, () => Plan0NumPcxFiles = s.SerializeStringArray(Plan0NumPcxFiles, Plan0NumPcxCount, 8, name: nameof(Plan0NumPcxFiles)));

                // Serialize counts
                DESCount       = s.Serialize <ushort>(DESCount, name: nameof(DESCount));
                ETACount       = s.Serialize <byte>(ETACount, name: nameof(ETACount));
                DESBlockLength = s.Serialize <uint>(DESBlockLength, name: nameof(DESBlockLength));
            }
            else
            {
                // Serialize header
                ETACount = s.Serialize <byte>(ETACount, name: nameof(ETACount));
                DESCount = s.Serialize <ushort>(DESCount, name: nameof(DESCount));
            }

            // Serialize DES data
            DESData = s.SerializeObjectArray <R1_PS1Edu_DESData>(DESData, DESCount, name: nameof(DESData));

            if (FileType == Type.World)
            {
                WorldDefine = WorldDefine = s.SerializeObject <R1_PC_WorldDefine>(WorldDefine, name: nameof(WorldDefine));
            }

            // Serialize main data block length
            MainDataBlockLength = s.Serialize <uint>(MainDataBlockLength, name: nameof(MainDataBlockLength));

            // We parse the main data block later...
            MainDataBlockPointer = s.CurrentPointer;
            s.Goto(MainDataBlockPointer + MainDataBlockLength);

            if (FileType == Type.Allfix)
            {
                DESDataIndices = s.SerializeArray <uint>(DESDataIndices, 8, name: nameof(DESDataIndices));
            }

            // Serialize ETA tables
            if (FileType == Type.World)
            {
                ETAStateCountTableCount = s.Serialize <byte>(ETAStateCountTableCount, name: nameof(ETAStateCountTableCount));
                ETAStateCountTable      = s.SerializeArray <byte>(ETAStateCountTable, ETAStateCountTableCount, name: nameof(ETAStateCountTable));
            }
            else
            {
                ETAStateCountTable = s.SerializeArray <byte>(ETAStateCountTable, ETACount, name: nameof(ETAStateCountTable));
            }
            ETASubStateCountTableCount = s.Serialize <byte>(ETASubStateCountTableCount, name: nameof(ETASubStateCountTableCount));
            ETASubStateCountTable      = s.SerializeArray <byte>(ETASubStateCountTable, ETASubStateCountTableCount, name: nameof(ETASubStateCountTable));

            // Serialize animation descriptor layer table
            AnimationDescriptorLayersBlockSizeTableCount = s.Serialize <uint>(AnimationDescriptorLayersBlockSizeTableCount, name: nameof(AnimationDescriptorLayersBlockSizeTableCount));
            AnimationDescriptorLayersBlockSizeTable      = s.SerializeArray <ushort>(AnimationDescriptorLayersBlockSizeTable, AnimationDescriptorLayersBlockSizeTableCount, name: nameof(AnimationDescriptorLayersBlockSizeTable));

            // Serialize animation layers
            AnimationLayers = s.SerializeObjectArray <R1_AnimationLayer>(AnimationLayers, 0xFE, name: nameof(AnimationLayers));

            // Serialize the main data block
            s.DoAt(MainDataBlockPointer, () =>
            {
                if (FileType == Type.World)
                {
                    SerializeDES();
                    SerializeETA();
                }
                else
                {
                    SerializeETA();
                    SerializeDES();
                }

                // Helper method for serializing the DES
                void SerializeDES()
                {
                    if (ImageDescriptors == null)
                    {
                        ImageDescriptors = new R1_ImageDescriptor[DESCount][];
                    }

                    if (AnimationDescriptors == null)
                    {
                        AnimationDescriptors = new R1_PS1Edu_AnimationDescriptor[DESCount][];
                    }

                    int curAnimDesc = 0;

                    // Serialize data for every DES
                    for (int i = 0; i < DESCount; i++)
                    {
                        // Serialize image descriptors
                        ImageDescriptors[i] = s.SerializeObjectArray <R1_ImageDescriptor>(ImageDescriptors[i], DESData[i].ImageDescriptorsCount, name: $"{nameof(ImageDescriptors)}[{i}]");

                        // Serialize animation descriptors
                        AnimationDescriptors[i] = s.SerializeObjectArray <R1_PS1Edu_AnimationDescriptor>(AnimationDescriptors[i], DESData[i].AnimationDescriptorsCount, name: $"{nameof(AnimationDescriptors)}[{i}]");

                        // Serialize animation descriptor data
                        for (int j = 0; j < AnimationDescriptors[i].Length; j++)
                        {
                            var descriptor = AnimationDescriptors[i][j];

                            if (descriptor.FrameCount <= 0)
                            {
                                curAnimDesc++;
                                continue;
                            }

                            // Serialize layer data
                            descriptor.LayersData = s.SerializeArray <byte>(descriptor.LayersData, AnimationDescriptorLayersBlockSizeTable[curAnimDesc], name: nameof(descriptor.LayersData));

                            // Padding...
                            if (AnimationDescriptorLayersBlockSizeTable[curAnimDesc] % 4 != 0)
                            {
                                // Padding seems to contain garbage data in this case instead of 0xCD?
                                int paddingLength = 4 - AnimationDescriptorLayersBlockSizeTable[curAnimDesc] % 4;
                                s.SerializeArray <byte>(Enumerable.Repeat((byte)0xCD, paddingLength).ToArray(), paddingLength, name: "Padding");
                            }

                            // Serialize frames
                            if (descriptor.AnimFramesPointer != 0xFFFFFFFF)
                            {
                                descriptor.Frames = s.SerializeObjectArray <R1_AnimationFrame>(descriptor.Frames, descriptor.FrameCount, name: nameof(descriptor.Frames));
                            }

                            // Parse layers
                            if (descriptor.Layers == null)
                            {
                                var layers = new List <R1_AnimationLayer>();
                                var offset = 0;

                                while (offset < descriptor.LayersData.Length)
                                {
                                    if (descriptor.LayersData[offset] < 2)
                                    {
                                        layers.Add(new R1_AnimationLayer()
                                        {
                                            IsFlippedHorizontally = descriptor.LayersData[offset + 0] == 1,
                                            XPosition             = descriptor.LayersData[offset + 1],
                                            YPosition             = descriptor.LayersData[offset + 2],
                                            ImageIndex            = descriptor.LayersData[offset + 3],
                                        });

                                        offset += 4;
                                    }
                                    else
                                    {
                                        layers.Add(AnimationLayers[descriptor.LayersData[offset] - 2]);
                                        offset++;
                                    }
                                }

                                descriptor.Layers = layers.ToArray();
                            }

                            curAnimDesc++;
                        }
                    }
                }

                // Helper method for serializing the ETA
                void SerializeETA()
                {
                    if (ETA == null)
                    {
                        ETA = new R1_EventState[ETACount][][];
                    }

                    var stateIndex = 0;

                    // Serialize every ETA
                    for (int i = 0; i < ETA.Length; i++)
                    {
                        if (ETA[i] == null)
                        {
                            ETA[i] = new R1_EventState[ETAStateCountTable[i]][];
                        }

                        // EDU serializes the pointer structs, but the pointers are invalid. They can be anything as they're overwritten with valid memory pointers upon load
                        uint[] pointerStructs = Enumerable.Repeat((uint)1, ETA[i].Length).ToArray();
                        _ = s.SerializeArray <uint>(pointerStructs, pointerStructs.Length, name: $"ETAPointers[{i}]");

                        // Serialize every state
                        for (int j = 0; j < ETA[i].Length; j++)
                        {
                            // Serialize sub-states
                            ETA[i][j] = s.SerializeObjectArray <R1_EventState>(ETA[i][j], ETASubStateCountTable[stateIndex], name: $"{nameof(ETA)}[{i}][{j}]");

                            stateIndex++;
                        }
                    }
                }
            });
        }
Beispiel #2
0
        /// <summary>
        /// Gets the sprite texture for an event
        /// </summary>
        /// <param name="context">The context</param>
        /// <param name="imgBuffer">The image buffer, if available</param>
        /// <param name="s">The image descriptor to use</param>
        /// <returns>The texture</returns>
        public override Texture2D GetSpriteTexture(Context context, byte[] imgBuffer, R1_ImageDescriptor img)
        {
            if (img.ImageType != 2 && img.ImageType != 3)
            {
                return(null);
            }
            if (img.Unknown2 == 0)
            {
                return(null);
            }
            ImageBuffer buf = context.GetStoredObject <ImageBuffer>("vram");

            // Get the image properties
            var width  = img.Width;
            var height = img.Height;
            var offset = img.ImageBufferOffset;

            Texture2D tex = TextureHelpers.CreateTexture2D(width, height);

            var palette       = FileFactory.Read <R1_PS1_Executable>(ExeFilePath, context).Saturn_Palettes;
            var paletteOffset = img.PaletteInfo;

            var isBigRay = img.Offset.file.filePath == GetBigRayFilePath();
            var isFont   = context.GetStoredObject <R1_PS1_FontData[]>("Font")?.SelectMany(x => x.ImageDescriptors).Contains(img) == true;

            //paletteOffset = (ushort)(256 * (img.Unknown2 >> 4));
            if (img.ImageType == 3)
            {
                //paletteOffset = 20 * 256;
                paletteOffset = isBigRay ? (ushort)(21 * 256) : isFont ? (ushort)(19 * 256) : (ushort)((GetPaletteIndex(context) * 256));
            }
            else
            {
                paletteOffset = isBigRay ? (ushort)(21 * 256) : isFont ? (ushort)(19 * 256) : (ushort)((GetPaletteIndex(context) * 256) + ((img.PaletteInfo >> 8)) * 16);
                //paletteOffset = (ushort)((GetPaletteIndex(context) * 256) + ((img.Unknown2 >> 4) - 1) * 16);
                //paletteOffset = (ushort)(19 * 256 + ((img.Unknown2 >> 4) - 1) * 16);
            }

            // Set every pixel
            if (img.ImageType == 3)
            {
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        var paletteIndex = buf.GetPixel8((uint)(offset + width * y + x));

                        // Set the pixel
                        var color = palette[paletteOffset + paletteIndex].GetColor();
                        if (paletteIndex == 0)
                        {
                            color = new Color(color.r, color.g, color.b, 0f);
                        }
                        else
                        {
                            color = new Color(color.r, color.g, color.b, 1f);
                        }
                        tex.SetPixel(x, height - 1 - y, color);
                    }
                }
            }
            else if (img.ImageType == 2)
            {
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        var paletteIndex = buf.GetPixel8((uint)(offset + (width * y + x) / 2));
                        if (x % 2 == 0)
                        {
                            paletteIndex = (byte)BitHelpers.ExtractBits(paletteIndex, 4, 4);
                        }
                        else
                        {
                            paletteIndex = (byte)BitHelpers.ExtractBits(paletteIndex, 4, 0);
                        }

                        // Set the pixel
                        var color = palette[paletteOffset + paletteIndex].GetColor();
                        if (paletteIndex == 0)
                        {
                            color = new Color(color.r, color.g, color.b, 0f);
                        }
                        else
                        {
                            color = new Color(color.r, color.g, color.b, 1f);
                        }
                        tex.SetPixel(x, height - 1 - y, color);
                    }
                }
            }


            //tex.SetPixels(Enumerable.Repeat(Color.blue, tex.width * tex.height).ToArray());
            tex.Apply();

            return(tex);
        }
        /// <summary>
        /// Gets the sprite texture for an event
        /// </summary>
        /// <param name="context">The context</param>
        /// <param name="imgBuffer">The image buffer, if available</param>
        /// <param name="s">The image descriptor to use</param>
        /// <returns>The texture</returns>
        public override Texture2D GetSpriteTexture(Context context, byte[] imgBuffer, R1_ImageDescriptor s)
        {
            if (s.ImageType != 2 && s.ImageType != 3)
            {
                return(null);
            }

            // Ignore dummy sprites
            if (s.IsDummySprite())
            {
                return(null);
            }

            // Get the image properties
            var width  = s.Width;
            var height = s.Height;
            var offset = s.ImageBufferOffset;

            var pal4 = FileFactory.Read <ObjectArray <RGBA5551Color> >(GetPalettePath(context.Settings, 4), context, (y, x) => x.Length = 256);
            var pal8 = FileFactory.Read <ObjectArray <RGBA5551Color> >(GetPalettePath(context.Settings, 8), context, (y, x) => x.Length = 256);

            // Select correct palette
            var palette       = s.ImageType == 3 ? pal8.Value : pal4.Value;
            var paletteOffset = 16 * s.Unknown1;

            // Create the texture
            Texture2D tex = TextureHelpers.CreateTexture2D(width, height);

            // Set every pixel
            if (s.ImageType == 3)
            {
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        var paletteIndex = imgBuffer[offset + width * y + x];

                        // Set the pixel
                        tex.SetPixel(x, height - 1 - y, palette[paletteIndex].GetColor());
                    }
                }
            }
            else if (s.ImageType == 2)
            {
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        int actualX      = (s.ImageOffsetInPageX + x) / 2;
                        var paletteIndex = imgBuffer[offset + (width * y + x) / 2];
                        if (x % 2 == 0)
                        {
                            paletteIndex = (byte)BitHelpers.ExtractBits(paletteIndex, 4, 0);
                        }
                        else
                        {
                            paletteIndex = (byte)BitHelpers.ExtractBits(paletteIndex, 4, 4);
                        }

                        // Set the pixel
                        tex.SetPixel(x, height - 1 - y, palette[paletteOffset + paletteIndex].GetColor());
                    }
                }
            }

            // Apply the changes
            tex.Apply();

            // Return the texture
            return(tex);
        }