Пример #1
0
        public override Unity_ObjGraphics GetCommonDesign(GBA_BaseBlock puppetBlock, bool is8bit, GBA_Data data, GBA_Animation[] additionalAnimations)
        {
            if (puppetBlock is GBA_Puppet)
            {
                return(base.GetCommonDesign(puppetBlock, is8bit, data, additionalAnimations));
            }

            var puppet = (GBA_BatmanVengeance_Puppet)puppetBlock;

            // Create the design
            var des = new Unity_ObjGraphics {
                Sprites    = new List <Sprite>(),
                Animations = new List <Unity_ObjAnimation>(),
            };

            if (puppet == null)
            {
                return(des);
            }

            var tileSet     = puppet.TileSet;
            var pal         = GetSpritePalette(puppet, data);
            var numPalettes = pal.Length / 16;

            // Add sprites for each palette
            if (tileSet.Is8Bit)
            {
                var pal_8      = Util.ConvertGBAPalette((RGBA5551Color[])pal);
                var tileSetTex = Util.ToTileSetTexture(tileSet.TileSet, pal_8, Util.TileEncoding.Linear_8bpp, CellSize, false, flipTileY: true);

                // Extract every sprite
                for (int i = 0; i < tileSet.TileSetLength; i++)
                {
                    int x = i % 32;
                    int y = i / 32;
                    des.Sprites.Add(tileSetTex.CreateSprite(rect: new Rect(x * CellSize, y * CellSize, CellSize, CellSize)));
                }
            }
            else
            {
                var pal_8 = Util.ConvertAndSplitGBAPalette((RGBA5551Color[])pal);

                for (int palIndex = 0; palIndex < numPalettes; palIndex++)
                {
                    var tileSetTex = Util.ToTileSetTexture(tileSet.TileSet, pal_8[palIndex], Util.TileEncoding.Linear_4bpp, CellSize, false, flipTileY: true);

                    // Extract every sprite
                    for (int i = 0; i < tileSet.TileSetLength; i++)
                    {
                        int x = i % 32;
                        int y = i / 32;
                        des.Sprites.Add(tileSetTex.CreateSprite(rect: new Rect(x * CellSize, y * CellSize, CellSize, CellSize)));
                    }


                    /*for (int i = 0; i < tileSet.TileSetLength; i++)
                     * {
                     *  var tex = TextureHelpers.CreateTexture2D(CellSize, CellSize);
                     *
                     *  for (int y = 0; y < tileWidth; y++)
                     *  {
                     *      for (int x = 0; x < tileWidth; x++)
                     *      {
                     *          int index = (i * tileSize) + ((y * tileWidth + x) / 2);
                     *
                     *          var b = tileSet.TileSet[index];
                     *          var v = BitHelpers.ExtractBits(b, 4, x % 2 == 0 ? 0 : 4);
                     *
                     *          Color c = pal_8[palIndex][v];
                     *
                     *          tex.SetPixel(x, (tileWidth - 1 - y), c);
                     *      }
                     *  }
                     *
                     *  tex.Apply();
                     *  des.Sprites.Add(tex.CreateSprite());
                     * }*/
                }
            }

            Unity_ObjAnimationPart[] GetPartsForTilemap(GBA_BatmanVengeance_Puppet s, GBA_BatmanVengeance_Animation a, int frame, GBA_BatmanVengeance_AnimationCommand c)
            {
                var height = s.TilemapHeight;
                var width  = s.TilemapWidth;

                Unity_ObjAnimationPart[] parts = new Unity_ObjAnimationPart[width * height];
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        var ind = y * width + x;
                        parts[ind] = new Unity_ObjAnimationPart {
                            ImageIndex            = tileSet.TileSetLength * (tileSet.Is8Bit ? 0 : c.TileMap[ind].PaletteIndex) + (c.TileMap[ind].TileIndex),
                            XPosition             = x * CellSize - (width * CellSize / 2),
                            YPosition             = y * CellSize - (height * CellSize / 2),
                            IsFlippedHorizontally = c.TileMap[ind].IsFlippedHorizontally,
                            IsFlippedVertically   = c.TileMap[ind].IsFlippedVertically,
                        };
                    }
                }
                return(parts);
            }

            Unity_ObjAnimationPart[] GetPartsForLayer(GBA_BatmanVengeance_Puppet s, GBA_BatmanVengeance_Animation a, int frame, GBA_BatmanVengeance_AnimationChannel l)
            {
                Unity_ObjAnimationPart[] parts = new Unity_ObjAnimationPart[l.XSize * l.YSize];

                var imageIndex = l.ImageIndex / (tileSet.Is8Bit ? 2 : 1);

                if (imageIndex > puppet.TileSet.TileSetLength)
                {
                    Controller.print("Image index too high: " + puppet.Offset + " - " + l.Offset + $"Index: {imageIndex} - Max: {puppet.TileSet.TileSetLength - 1}");
                }

                if (l.PaletteIndex > pal.Length / 16)
                {
                    Controller.print("Palette index too high: " + puppet.Offset + " - " + l.Offset + " - " + l.PaletteIndex + " - " + (pal.Length / 16));
                }

                for (int y = 0; y < l.YSize; y++)
                {
                    for (int x = 0; x < l.XSize; x++)
                    {
                        parts[y * l.XSize + x] = new Unity_ObjAnimationPart {
                            ImageIndex            = tileSet.TileSetLength * (tileSet.Is8Bit ? 0 : l.PaletteIndex) + (imageIndex + y * l.XSize + x),
                            IsFlippedHorizontally = l.IsFlippedHorizontally,
                            IsFlippedVertically   = l.IsFlippedVertically,
                            XPosition             = (l.XPosition + (l.IsFlippedHorizontally ? (l.XSize - 1 - x) : x) * CellSize),
                            YPosition             = (l.YPosition + (l.IsFlippedVertically ? (l.YSize - 1 - y) : y) * CellSize),
                            TransformOriginX      = (l.XPosition + l.XSize * CellSize / 2f),
                            TransformOriginY      = (l.YPosition + l.YSize * CellSize / 2f)
                        };
                    }
                }
                return(parts);
            }

            // Add first animation for now
            foreach (var a in puppet.Animations)
            {
                var unityAnim = new Unity_ObjAnimation();
                var frames    = new List <Unity_ObjAnimationFrame>();
                for (int i = 0; i < a.FrameCount; i++)
                {
                    var parts          = new List <Unity_ObjAnimationPart[]>();
                    var collisionParts = new List <Unity_ObjAnimationCollisionPart>();
                    foreach (var c in a.Frames[i].Commands)
                    {
                        switch (c.Command)
                        {
                        case GBA_BatmanVengeance_AnimationCommand.InstructionCommand.SpriteNew:
                            parts.Add(c.Layers.SelectMany(l => GetPartsForLayer(puppet, a, i, l)).Reverse().ToArray());
                            break;

                        case GBA_BatmanVengeance_AnimationCommand.InstructionCommand.SpriteTilemap:
                            parts.Add(GetPartsForTilemap(puppet, a, i, c));
                            break;

                        case GBA_BatmanVengeance_AnimationCommand.InstructionCommand.Hitbox:
                            collisionParts.Add(new Unity_ObjAnimationCollisionPart
                            {
                                XPosition = c.HitboxXPos - c.HitboxHalfWidth,
                                YPosition = c.HitboxYPos - c.HitboxHalfHeight,
                                Width     = c.HitboxHalfWidth * 2,
                                Height    = c.HitboxHalfHeight * 2,
                                Type      = Unity_ObjAnimationCollisionPart.CollisionType.AttackBox
                            });
                            break;

                        case GBA_BatmanVengeance_AnimationCommand.InstructionCommand.Hitbox_Batman:
                            collisionParts.Add(new Unity_ObjAnimationCollisionPart {
                                XPosition = c.Hitbox_X1,
                                YPosition = c.Hitbox_Y1,
                                Width     = c.Hitbox_X2 - c.Hitbox_X1,
                                Height    = c.Hitbox_Y2 - c.Hitbox_Y1,
                                Type      = Unity_ObjAnimationCollisionPart.CollisionType.AttackBox
                            });
                            break;
                        }
                    }
                    if (parts.Count == 0 && frames.Count > 0)
                    {
                        var lastFrame = frames.Last();
                        frames.Add(new Unity_ObjAnimationFrame(lastFrame.SpriteLayers, lastFrame.CollisionLayers));
                    }
                    else
                    {
                        frames.Add(new Unity_ObjAnimationFrame(parts.SelectMany(p => p).ToArray(), collisionParts.ToArray()));
                    }
                }
                unityAnim.Frames     = frames.ToArray();
                unityAnim.AnimSpeeds = a.Frames.Select(x => (x.Commands.FirstOrDefault(c => c.IsTerminator)?.Time ?? 0) + 1).ToArray();
                des.Animations.Add(unityAnim);
            }

            return(des);
        }
        public override Unity_ObjGraphics GetCommonDesign(GBA_ActorGraphicData graphicData)
        {
            // Create the design
            var des = new Unity_ObjGraphics {
                Sprites    = new List <Sprite>(),
                Animations = new List <Unity_ObjAnimation>(),
            };

            if (graphicData == null)
            {
                return(des);
            }

            var       tileMap     = graphicData.SpriteGroup_BatmanVengeance.TileMap;
            var       pal         = graphicData.SpriteGroup_BatmanVengeance.Palette.Palette;
            const int tileWidth   = 8;
            const int tileSize    = (tileWidth * tileWidth) / 2;
            var       numPalettes = graphicData.SpriteGroup_BatmanVengeance.Palette.Palette.Length / 16;

            // Add sprites for each palette
            for (int palIndex = 0; palIndex < numPalettes; palIndex++)
            {
                for (int i = 0; i < tileMap.TileMapLength; i++)
                {
                    var tex = TextureHelpers.CreateTexture2D(CellSize, CellSize);

                    for (int y = 0; y < tileWidth; y++)
                    {
                        for (int x = 0; x < tileWidth; x++)
                        {
                            int index = (i * tileSize) + ((y * tileWidth + x) / 2);

                            var b = tileMap.TileMap[index];
                            var v = BitHelpers.ExtractBits(b, 4, x % 2 == 0 ? 0 : 4);

                            Color c = pal[palIndex * 16 + v].GetColor();

                            if (v != 0)
                            {
                                c = new Color(c.r, c.g, c.b, 1f);
                            }

                            tex.SetPixel(x, (tileWidth - 1 - y), c);
                        }
                    }

                    tex.Apply();
                    des.Sprites.Add(tex.CreateSprite());
                }
            }

            Unity_ObjAnimationPart[] GetPartsForLayer(GBA_BatmanVengeance_SpriteGroup s, GBA_BatmanVengeance_Animation a, int frame, GBA_BatmanVengeance_AnimationChannel l)
            {
                /*if (l.TransformMode == GBA_AnimationLayer.AffineObjectMode.Hide
                || l.RenderMode == GBA_AnimationLayer.GfxMode.Window
                || l.RenderMode == GBA_AnimationLayer.GfxMode.Regular
                || l.Mosaic) return new Unity_ObjAnimationPart[0];
                || if (l.Color == GBA_AnimationLayer.ColorMode.Color8bpp) {
                ||  Debug.LogWarning("Animation Layer @ " + l.Offset + " has 8bpp color mode, which is currently not supported.");
                ||  return new Unity_ObjAnimationPart[0];
                || }*/
                Unity_ObjAnimationPart[] parts = new Unity_ObjAnimationPart[l.XSize * l.YSize];
                if (l.ImageIndex > graphicData.SpriteGroup_BatmanVengeance.TileMap.TileMapLength)
                {
                    Controller.print("Image index too high: " + graphicData.Offset + " - " + l.Offset);
                }
                if (l.PaletteIndex > graphicData.SpriteGroup_BatmanVengeance.Palette.Palette.Length / 16)
                {
                    Controller.print("Palette index too high: " + graphicData.Offset + " - " + l.Offset + " - " + l.PaletteIndex + " - " + (graphicData.SpriteGroup_BatmanVengeance.Palette.Palette.Length / 16));
                }
                float   rot = 0;    // l.GetRotation(a, s, frame);
                Vector2?scl = null; // l.GetScale(a, s, frame);

                for (int y = 0; y < l.YSize; y++)
                {
                    for (int x = 0; x < l.XSize; x++)
                    {
                        parts[y * l.XSize + x] = new Unity_ObjAnimationPart {
                            ImageIndex            = tileMap.TileMapLength * l.PaletteIndex + (l.ImageIndex + y * l.XSize + x),
                            IsFlippedHorizontally = l.IsFlippedHorizontally,
                            IsFlippedVertically   = l.IsFlippedVertically,
                            XPosition             = (l.XPosition + (l.IsFlippedHorizontally ? (l.XSize - 1 - x) : x) * CellSize),
                            YPosition             = (l.YPosition + (l.IsFlippedVertically ? (l.YSize - 1 - y) : y) * CellSize),
                            Rotation         = rot,
                            Scale            = scl,
                            TransformOriginX = (l.XPosition + l.XSize * CellSize / 2f),
                            TransformOriginY = (l.YPosition + l.YSize * CellSize / 2f)
                        };
                    }
                }
                return(parts);
            }

            // Add first animation for now
            foreach (var a in graphicData.SpriteGroup_BatmanVengeance.Animations)
            {
                var unityAnim = new Unity_ObjAnimation();
                var frames    = new List <Unity_ObjAnimationFrame>();
                for (int i = 0; i < a.FrameCount; i++)
                {
                    frames.Add(new Unity_ObjAnimationFrame(a.Frames[i].Layers /*.OrderByDescending(l => l.Priority)*/.SelectMany(l => GetPartsForLayer(graphicData.SpriteGroup_BatmanVengeance, a, i, l)).Reverse().ToArray()));
                }
                unityAnim.Frames    = frames.ToArray();
                unityAnim.AnimSpeed = 1;
                des.Animations.Add(unityAnim);
            }

            return(des);
        }