public async UniTask ExportAnimSetAsync(Context context, string outputPath, GBAIsometric_RHR_AnimSet animSet) { if (animSet == null) { return; } Dictionary <ushort, byte[]> decompressedDictionary = new Dictionary <ushort, byte[]>(); var pal = animSet.GetAllPalettes; for (int a = 0; a < animSet.Animations.Length; a++) { if (a % 10 == 0) { await Controller.WaitIfNecessary(); } var anim = animSet.Animations[a]; for (int p = 0; p < pal.Length; p++) { string outPath = Path.Combine(outputPath, pal.Length > 1 ? $"{animSet.Name}_{p}" : animSet.Name); var f = 0; foreach (var tex in GetAnimationFrames(context, animSet, anim, decompressedDictionary, pal[p])) { Util.ByteArrayToFile(Path.Combine(outPath, $"{a}-{anim.Speed}", $"{f++}.png"), tex.EncodeToPNG()); } } } }
public IEnumerable <Texture2D> GetAnimationFrames(Context context, GBAIsometric_RHR_AnimSet animSet, GBAIsometric_RHR_Animation anim, Dictionary <ushort, byte[]> decompressedDictionary, RGBA5551Color[] palette) { SerializerObject s = context.Deserializer; var startFrame = anim.StartFrameIndex; var frameCount = anim.FrameCount; Color[] pal = Util.ConvertGBAPalette(palette); for (int f = 0; f < frameCount; f++) { var frame = animSet.Frames[startFrame + f]; Texture2D tex = TextureHelpers.CreateTexture2D(animSet.Width * CellSize, animSet.Height * CellSize, clear: true); if (frame.PatternIndex == 0xFFFF || frame.TileIndicesIndex == 0xFFFF) { // Empty frame } else { var patIndex = frame.PatternIndex; int curTile = frame.TileIndicesIndex; for (int p = 0; p < animSet.Patterns[patIndex].Length; p++) { var pattern = animSet.Patterns[patIndex][p]; for (int y = 0; y < pattern.Height; y++) { for (int x = 0; x < pattern.Width; x++) { int actualX = x + pattern.XPosition; int actualY = y + pattern.YPosition; ushort tileIndex = animSet.TileIndices[curTile]; if (!decompressedDictionary.ContainsKey(tileIndex)) { s.Goto(animSet.GraphicsDataPointer.Value.CompressedDataPointer); s.DoEncoded(new RHR_SpriteEncoder(animSet.Is8Bit, animSet.GraphicsDataPointer.Value.CompressionLookupBuffer, animSet.GraphicsDataPointer.Value.CompressedDataPointer, tileIndex), () => { decompressedDictionary[tileIndex] = s.SerializeArray <byte>(default, s.CurrentLength, name: $"{animSet.Name}:Tiles[{curTile}]:{tileIndex}");
/// <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 pointerTable = PointerTables.GBAIsometric_RHR_PointerTable(s.GameSettings.GameModeSelection, Offset.file); // Serialize localization Localization = s.DoAt(pointerTable[GBAIsometric_RHR_Pointer.Localization], () => s.SerializeObject <GBAIsometric_RHR_Localization>(Localization, name: nameof(Localization))); if (s.GameSettings.World == 0) { // Serialize level infos s.DoAt(pointerTable[GBAIsometric_RHR_Pointer.Levels], () => { if (LevelInfos == null) { LevelInfos = new GBAIsometric_RHR_LevelInfo[20]; } for (int i = 0; i < LevelInfos.Length; i++) { LevelInfos[i] = s.SerializeObject(LevelInfos[i], x => x.SerializeData = i == s.GameSettings.Level, name: $"{nameof(LevelInfos)}[{i}]"); } }); PaletteAnimations = new GBAIsometric_RHR_PaletteAnimationTable[3]; s.DoAt(pointerTable[GBAIsometric_RHR_Pointer.PaletteAnimations0], () => { PaletteAnimations[0] = s.SerializeObject <GBAIsometric_RHR_PaletteAnimationTable>(PaletteAnimations[0], name: $"{nameof(PaletteAnimations)}[0]"); }); s.DoAt(pointerTable[GBAIsometric_RHR_Pointer.PaletteAnimations1], () => { PaletteAnimations[1] = s.SerializeObject <GBAIsometric_RHR_PaletteAnimationTable>(PaletteAnimations[1], name: $"{nameof(PaletteAnimations)}[1]"); }); s.DoAt(pointerTable[GBAIsometric_RHR_Pointer.PaletteAnimations2], () => { PaletteAnimations[2] = s.SerializeObject <GBAIsometric_RHR_PaletteAnimationTable>(PaletteAnimations[2], name: $"{nameof(PaletteAnimations)}[2]"); }); // Serialize object types ObjectTypes = s.DoAt(pointerTable[GBAIsometric_RHR_Pointer.ObjTypes], () => s.SerializeObjectArray <GBAIsometric_ObjectType>(ObjectTypes, 105, name: nameof(ObjectTypes))); // Serialize the crab type and add to the array (the crab entry points to memory) ObjectTypes[13].Data = s.DoAt(pointerTable[GBAIsometric_RHR_Pointer.CrabObjType], () => s.SerializeObject <GBAIsometric_ObjectTypeData>(ObjectTypes[13].Data, name: $"CrabObjectTypeData")); // Serialize additional object types var additionalObjTypePointers = ObjTypePointers[s.GameSettings.GameModeSelection]; if (AdditionalObjectTypes == null) { AdditionalObjectTypes = new GBAIsometric_ObjectTypeData[additionalObjTypePointers.Length]; } for (int i = 0; i < AdditionalObjectTypes.Length; i++) { AdditionalObjectTypes[i] = s.DoAt(new Pointer(additionalObjTypePointers[i], Offset.file), () => s.SerializeObject <GBAIsometric_ObjectTypeData>(AdditionalObjectTypes[i], name: $"{nameof(AdditionalObjectTypes)}[{i}]")); } // Serialize additional animation sets var additionalAnimSetPointers = AnimSetPointers[s.GameSettings.GameModeSelection]; if (AdditionalAnimSets == null) { AdditionalAnimSets = new GBAIsometric_RHR_AnimSet[additionalAnimSetPointers.Length]; } for (int i = 0; i < AdditionalAnimSets.Length; i++) { AdditionalAnimSets[i] = s.DoAt(new Pointer(additionalAnimSetPointers[i], Offset.file), () => s.SerializeObject <GBAIsometric_RHR_AnimSet>(AdditionalAnimSets[i], name: $"{nameof(AdditionalAnimSets)}[{i}]")); } // Serialize sprite sets var spriteSetPointers = SpriteSetPointers[s.GameSettings.GameModeSelection]; if (SpriteSets == null) { SpriteSets = new GBAIsometric_RHR_SpriteSet[spriteSetPointers.Length]; } for (int i = 0; i < SpriteSets.Length; i++) { SpriteSets[i] = s.DoAt(new Pointer(spriteSetPointers[i], Offset.file), () => s.SerializeObject <GBAIsometric_RHR_SpriteSet>(SpriteSets[i], name: $"{nameof(SpriteSets)}[{i}]")); } // Serialize sprites var spritePointers = SpritePointers[s.GameSettings.GameModeSelection]; if (Sprites == null) { Sprites = new GBAIsometric_RHR_Sprite[spritePointers.Length]; } for (int i = 0; i < Sprites.Length; i++) { Sprites[i] = s.DoAt(new Pointer(spritePointers[i], Offset.file), () => s.SerializeObject <GBAIsometric_RHR_Sprite>(Sprites[i], name: $"{nameof(Sprites)}[{i}]")); } // Serialize sprite icons SpriteIconPointers = s.DoAt(pointerTable[GBAIsometric_RHR_Pointer.SpriteIcons], () => s.SerializePointerArray(SpriteIconPointers, 84, name: nameof(SpriteIconPointers))); if (SpriteIcons == null) { SpriteIcons = new GBAIsometric_RHR_Sprite[SpriteIconPointers.Length]; } for (int i = 0; i < SpriteIcons.Length; i++) { SpriteIcons[i] = s.DoAt(SpriteIconPointers[i], () => s.SerializeObject <GBAIsometric_RHR_Sprite>(SpriteIcons[i], name: $"{nameof(SpriteIcons)}[{i}]")); } // Serialize flag sprites FlagSpritesUS = s.DoAt(pointerTable[GBAIsometric_RHR_Pointer.SpriteFlagsUS], () => s.SerializeObjectArray <GBAIsometric_RHR_FlagSprite>(FlagSpritesUS, 3, name: nameof(FlagSpritesUS))); FlagSpritesEU = s.DoAt(pointerTable[GBAIsometric_RHR_Pointer.SpriteFlagsEU], () => s.SerializeObjectArray <GBAIsometric_RHR_FlagSprite>(FlagSpritesEU, 6, name: nameof(FlagSpritesEU))); // Serialize font Font0 = s.DoAt(pointerTable[GBAIsometric_RHR_Pointer.Font0], () => s.SerializeObject <GBAIsometric_RHR_Font>(Font0, name: nameof(Font0))); Font1 = s.DoAt(pointerTable[GBAIsometric_RHR_Pointer.Font1], () => s.SerializeObject <GBAIsometric_RHR_Font>(Font1, name: nameof(Font1))); Font2 = s.DoAt(pointerTable[GBAIsometric_RHR_Pointer.Font2], () => s.SerializeObject <GBAIsometric_RHR_Font>(Font2, name: nameof(Font2))); // Serialize portraits PortraitPointers = s.DoAt(pointerTable[GBAIsometric_RHR_Pointer.Portraits], () => s.SerializePointerArray(PortraitPointers, 10, name: nameof(PortraitPointers))); if (Portraits == null) { Portraits = new GBAIsometric_RHR_AnimSet[PortraitPointers.Length]; } for (int i = 0; i < Portraits.Length; i++) { Portraits[i] = s.DoAt(PortraitPointers[i], () => s.SerializeObject <GBAIsometric_RHR_AnimSet>(Portraits[i], name: $"{nameof(Portraits)}[{i}]")); } // Serialize alternative anim set palettes var alternativeAnimSetPalettes = AlternativeAnimSetPalettes[s.GameSettings.GameModeSelection]; foreach (GBAIsometric_RHR_AnimSet animSet in GetAllAnimSets().Where(x => alternativeAnimSetPalettes.ContainsKey(x.Name))) { animSet.SerializeAlternativePalettes(s, alternativeAnimSetPalettes[animSet.Name]); } } else { var maps = ((GBAIsometric_RHR_Manager)s.GameSettings.GetGameManager).GetMenuMaps(s.GameSettings.Level); MenuMaps = new GBAIsometric_RHR_MapLayer[maps.Length]; for (int i = 0; i < MenuMaps.Length; i++) { MenuMaps[i] = s.DoAt(pointerTable[maps[i]], () => s.SerializeObject <GBAIsometric_RHR_MapLayer>(default, name: $"{maps[i]}"));