Example #1
0
        /// <summary>
        /// Handles the data serialization
        /// </summary>
        /// <param name="s">The serializer object</param>
        public override void SerializeImpl(SerializerObject s)
        {
            // Serialize ROM header
            base.SerializeImpl(s);

            var manager = ((GBA_Manager)s.Context.Settings.GetGameManager);

            // Get the pointer table
            var pointerTable = PointerTables.GBA_PointerTable(s.Context, Offset.file);
            var lvlType      = manager.GetLevelType(s.Context);

            // Serialize the offset table
            if (lvlType != GBA_Manager.LevelType.R3SinglePak)
            {
                s.DoAt(pointerTable[GBA_Pointer.UiOffsetTable], () => Data = s.SerializeObject <GBA_Data>(Data, name: nameof(Data)));
            }

            // Serialize level info
            if (pointerTable.ContainsKey(GBA_Pointer.LevelInfo))
            {
                LevelInfo = s.DoAt(pointerTable[GBA_Pointer.LevelInfo], () => s.SerializeObjectArray <GBA_R3_SceneInfo>(LevelInfo, manager.LevelCount, name: nameof(LevelInfo)));
            }

            // Serialize localization
            if (pointerTable.ContainsKey(GBA_Pointer.Localization))
            {
                if (s.GameSettings.GBA_IsMilan)
                {
                    s.DoAt(pointerTable[GBA_Pointer.Localization], () => Milan_Localization = s.SerializeObject <GBA_Milan_LocTable>(Milan_Localization, name: nameof(Milan_Localization)));
                }
                else
                {
                    s.DoAt(pointerTable[GBA_Pointer.Localization], () => Localization = s.SerializeObject <GBA_LocLanguageTable>(Localization, name: nameof(Localization)));
                }
            }

            // Serialize actor type data
            if (pointerTable.ContainsKey(GBA_Pointer.ActorTypeTable))
            {
                ActorTypeTable = s.DoAt(pointerTable[GBA_Pointer.ActorTypeTable], () => s.SerializeObjectArray <GBA_ActorTypeTableEntry>(ActorTypeTable, manager.ActorTypeTableLength, name: nameof(ActorTypeTable)));
            }

            if (lvlType == GBA_Manager.LevelType.R3SinglePak)
            {
                R3SinglePak_OffsetTable = s.DoAt(pointerTable[GBA_Pointer.R3SinglePak_OffsetTable], () => s.SerializeObject <GBA_OffsetTable>(R3SinglePak_OffsetTable, name: nameof(R3SinglePak_OffsetTable)));
                R3SinglePak_Palette     = s.DoAt(pointerTable[GBA_Pointer.R3SinglePak_Palette], () => s.SerializeObjectArray <RGBA5551Color>(R3SinglePak_Palette, 256, name: nameof(R3SinglePak_Palette)));
                R3SinglePak_TileMap     = s.DoAt(pointerTable[GBA_Pointer.R3SinglePak_TileMap], () => s.SerializeArray <ushort>(R3SinglePak_TileMap, 0x400, name: nameof(R3SinglePak_TileMap)));
                R3SinglePak_TileSet     = s.DoAt(pointerTable[GBA_Pointer.R3SinglePak_TileSet], () => s.SerializeArray <byte>(R3SinglePak_TileSet, (R3SinglePak_TileMap.Max() + 1) * 0x40, name: nameof(R3SinglePak_TileSet)));

                if (R3SinglePak_Puppets == null)
                {
                    R3SinglePak_Puppets = new GBA_Puppet[R3SinglePak_OffsetTable.OffsetsCount];
                }

                for (int i = 0; i < R3SinglePak_Puppets.Length; i++)
                {
                    R3SinglePak_Puppets[i] = s.DoAt(R3SinglePak_OffsetTable.GetPointer(i), () => s.SerializeObject <GBA_Puppet>(R3SinglePak_Puppets[i], name: $"{nameof(R3SinglePak_Puppets)}[{i}]"));
                }
            }
        }
Example #2
0
        public UnityEngine.Vector2 GetScale(GBA_Animation anim, GBA_Puppet puppet, int frameIndex)
        {
            if (TransformMode == AffineObjectMode.Affine || TransformMode == AffineObjectMode.AffineDouble)
            {
                if (puppet.Matrices.ContainsKey(anim.AffineMatricesIndex))
                {
                    var m = puppet.Matrices[anim.AffineMatricesIndex].GetMatrix(AffineMatrixIndex, frameIndex);
                    if (m != null)
                    {
                        var a     = m.Pa / 256f;
                        var b     = m.Pb / 256f;
                        var c     = m.Pc / 256f;
                        var d     = m.Pd / 256f;
                        var delta = a * d - b * c;

                        //var rotation = 0f;
                        var scale = UnityEngine.Vector2.zero;
                        //var skew = UnityEngine.Vector2.zero;
                        // Apply the QR-like decomposition.
                        if (a != 0 || b != 0)
                        {
                            var r = Mathf.Sqrt(a * a + b * b);
                            //rotation = b > 0 ? Mathf.Acos(a / r) : -Mathf.Acos(a / r);
                            scale = new UnityEngine.Vector2(r, delta / r);
                            //skew = new UnityEngine.Vector2(Mathf.Atan((a * c + b * d) / (r * r)), 0);
                        }
                        else if (c != 0 || d != 0)
                        {
                            var s = Mathf.Sqrt(c * c + d * d);
                            //rotation =
                            //  Mathf.PI / 2 - (d > 0 ? Mathf.Acos(-c / s) : -Mathf.Acos(c / s));
                            scale = new UnityEngine.Vector2(delta / s, s);
                            //skew = new UnityEngine.Vector2(0, Mathf.Atan((a * c + b * d) / (s * s)));
                        }
                        else
                        {
                            // a = b = c = d = 0
                        }
                        if (scale.x != 0)
                        {
                            scale.x = 1f / scale.x;
                        }
                        if (scale.y != 0)
                        {
                            scale.y = 1f / scale.y;
                        }

                        return(scale);
                        // Resources:
                        // https://wiki.nycresistor.com/wiki/GB101:Affine_Sprites
                        // https://www.coranac.com/tonc/text/affine.htm
                        // https://www.coranac.com/tonc/text/affobj.htm
                    }
                }
            }
            return(UnityEngine.Vector2.one);
        }
Example #3
0
        public float GetRotation(GBA_Animation anim, GBA_Puppet puppet, int frameIndex)
        {
            if (TransformMode == AffineObjectMode.Affine || TransformMode == AffineObjectMode.AffineDouble)
            {
                if (puppet.Matrices.ContainsKey(anim.AffineMatricesIndex))
                {
                    var m = puppet.Matrices[anim.AffineMatricesIndex].GetMatrix(AffineMatrixIndex, frameIndex);
                    if (m != null)
                    {
                        var rotation = -Mathf.Atan2(m.Pb / 256f, m.Pa / 256f);
                        return(rotation * Mathf.Rad2Deg);

                        // Resources:
                        // https://stackoverflow.com/questions/45159314/decompose-2d-transformation-matrix
                        // https://wiki.nycresistor.com/wiki/GB101:Affine_Sprites
                        // https://www.coranac.com/tonc/text/affine.htm
                        // https://www.coranac.com/tonc/text/affobj.htm
                    }
                }
            }
            return(0f);
        }