Beispiel #1
0
        /// <summary>
        /// Handles the data serialization
        /// </summary>
        /// <param name="s">The serializer object</param>
        public override void SerializeImpl(SerializerObject s)
        {
            NumberOfLanguages = s.Serialize <byte>(NumberOfLanguages, name: nameof(NumberOfLanguages));
            LanguageUtilized  = s.Serialize <byte>(LanguageUtilized, name: nameof(LanguageUtilized));
            KeyboardType      = s.Serialize <KeyboardTypes>(KeyboardType, name: nameof(KeyboardType));

            // Most versions have 3 languages, but sometimes the NumberOfLanguages is set to 1 because only 1 is available. Other versions may have up to 5.
            var numLangNames = Mathf.Clamp(NumberOfLanguages, 3, 5);

            if (s.GameSettings.EngineVersion == EngineVersion.R1_PS1_Edu && (s.GameSettings.EduVolume.StartsWith("IT") || s.GameSettings.EduVolume.StartsWith("CS")))
            {
                numLangNames = 5;
            }

            if (s.GameSettings.EngineVersion == EngineVersion.R1_PC_Edu && (s.GameSettings.EduVolume.StartsWith("HN") || s.GameSettings.EduVolume.StartsWith("IS") || s.GameSettings.EduVolume.StartsWith("NL")))
            {
                numLangNames = 5;
            }

            LanguageNames = s.SerializeStringArray(LanguageNames, numLangNames, 11, name: nameof(LanguageNames));

            var align = 3 + LanguageNames.Length * 11 + 8;

            if (align % 4 != 0)
            {
                s.SerializeArray <byte>(new byte[align % 4], 4 - (align % 4), name: "Align");
            }

            TextDefineCount = s.Serialize <uint>(TextDefineCount, name: nameof(TextDefineCount));
            Unk1            = s.Serialize <ushort>(Unk1, name: nameof(Unk1));
            Unk2            = s.Serialize <ushort>(Unk2, name: nameof(Unk2));

            TextDefine = s.SerializeObjectArray <R1_PC_LocFileString>(TextDefine, TextDefineCount, name: nameof(TextDefine));
        }
        public override void SerializeImpl(SerializerObject s)
        {
            var manager = (R1_PS1BaseManager)s.GameSettings.GetGameManager;

            if (manager.TypeZDCOffset != null)
            {
                TypeZDC = s.DoAt(new Pointer(manager.TypeZDCOffset.Value, Offset.file), () => s.SerializeObjectArray <R1_ZDCEntry>(TypeZDC, manager.TypeZDCCount, name: nameof(TypeZDC)));
            }

            if (manager.ZDCDataOffset != null)
            {
                ZDCData = s.DoAt(new Pointer(manager.ZDCDataOffset.Value, Offset.file), () => s.SerializeObjectArray <R1_ZDCData>(ZDCData, manager.ZDCDataCount, name: nameof(ZDCData)));
            }

            if (manager.EventFlagsOffset != null)
            {
                if (s.GameSettings.EngineVersion == EngineVersion.R1_Saturn)
                {
                    EventFlags = s.DoAt(new Pointer(manager.EventFlagsOffset.Value, Offset.file),
                                        () => s.SerializeArray <int>(EventFlags?.Select(x => BitHelpers.ReverseBits((int)x)).ToArray(), manager.EventFlagsCount, name: nameof(EventFlags))).Select(BitHelpers.ReverseBits).Select(x => (R1_EventFlags)x).ToArray();
                }
                else
                {
                    EventFlags = s.DoAt(new Pointer(manager.EventFlagsOffset.Value, Offset.file),
                                        () => s.SerializeArray <R1_EventFlags>(EventFlags, manager.EventFlagsCount, name: nameof(EventFlags)));
                }
            }

            if (manager.WorldInfoOffset != null)
            {
                WorldInfo = s.DoAt(new Pointer(manager.WorldInfoOffset.Value, Offset.file), () => s.SerializeObjectArray <R1_WorldMapInfo>(WorldInfo, 24, name: nameof(WorldInfo)));
            }

            if (manager.LevelBackgroundIndexTableOffset != null)
            {
                if (LevelBackgroundIndexTable == null)
                {
                    LevelBackgroundIndexTable = new byte[6][];
                }

                s.DoAt(new Pointer(manager.LevelBackgroundIndexTableOffset.Value, Offset.file), () =>
                {
                    for (int i = 0; i < LevelBackgroundIndexTable.Length; i++)
                    {
                        LevelBackgroundIndexTable[i] = s.SerializeArray <byte>(LevelBackgroundIndexTable[i], 30, name: $"{nameof(LevelBackgroundIndexTable)}[{i}]");
                    }
                });
            }

            var fileTableInfos = manager.FileTableInfos;

            if (FileTable == null)
            {
                FileTable = new R1_PS1_FileTableEntry[fileTableInfos.Sum(x => x.Count)];
            }

            var index = 0;

            foreach (var info in fileTableInfos)
            {
                s.DoAt(new Pointer(info.Offset, Offset.file), () =>
                {
                    for (int i = 0; i < info.Count; i++)
                    {
                        FileTable[index] = s.SerializeObject <R1_PS1_FileTableEntry>(FileTable[index], name: $"{nameof(FileTable)}_{info.FileType}[{i}]");
                        index++;
                    }
                });
            }

            if (s.GameSettings.EngineVersion == EngineVersion.R1_Saturn)
            {
                var saturnManager = (R1_Saturn_Manager)manager;

                Saturn_Palettes = s.DoAt(new Pointer(saturnManager.GetPalOffset, Offset.file), () => s.SerializeObjectArray <RGBA5551Color>(Saturn_Palettes, 25 * 256 * 2, name: nameof(Saturn_Palettes)));

                if (Saturn_FNDFileTable == null)
                {
                    Saturn_FNDFileTable = new string[6][];
                }

                s.DoAt(new Pointer(saturnManager.GetFndFileTableOffset, Offset.file), () =>
                {
                    for (int i = 0; i < Saturn_FNDFileTable.Length; i++)
                    {
                        Saturn_FNDFileTable[i] = s.SerializeStringArray(Saturn_FNDFileTable[i], 10, 12, name: $"{nameof(Saturn_FNDFileTable)}[{i}]");
                    }
                });

                if (Saturn_FNDSPFileTable == null)
                {
                    Saturn_FNDSPFileTable = new string[6][];
                }

                s.DoAt(new Pointer(saturnManager.GetFndSPFileTableOffset, Offset.file), () =>
                {
                    for (int i = 0; i < Saturn_FNDSPFileTable.Length; i++)
                    {
                        Saturn_FNDSPFileTable[i] = s.SerializeStringArray(Saturn_FNDSPFileTable[i], 5, 12, name: $"{nameof(Saturn_FNDSPFileTable)}[{i}]");
                    }
                });

                if (Saturn_FNDIndexTable == null)
                {
                    Saturn_FNDIndexTable = new byte[7][];
                }

                s.DoAt(new Pointer(saturnManager.GetFndIndexTableOffset, Offset.file), () =>
                {
                    for (int i = 0; i < Saturn_FNDIndexTable.Length; i++)
                    {
                        Saturn_FNDIndexTable[i] = s.SerializeArray <byte>(Saturn_FNDIndexTable[i], 25, name: $"{nameof(Saturn_FNDIndexTable)}[{i}]");
                    }
                });
            }
        }
Beispiel #3
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++;
                        }
                    }
                }
            });
        }