/// <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}]")); } } }
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); }
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); }