private void TestGetBytes(string fileName)
        {
            byte[]           dataBefore = File.ReadFile(fileName);
            BackgroundLayout layout     = new BackgroundLayout(dataBefore);

            byte[] dataAfter = layout.GetBytes();
            Assert.AreEqual(dataBefore, dataAfter);
        }
Beispiel #2
0
        /// <summary>Initializes a new instance of the <see cref="VisualTile" /> class.</summary>
        public VisualTile()
        {
            Size = new Size(110, 80);

            backgroundLayout = BackgroundLayout.Stretch;
            backColorState   = new ControlColorState();
            type             = TileType.Text;
            image            = Resources.VisualPlus;
            MouseState       = MouseStates.Normal;
            offset           = new Point(0, 0);

            UpdateTheme(ThemeManager.Theme);
        }
        /// <summary>Render the background image.</summary>
        /// <param name="graphics">The specified graphics to draw on.</param>
        /// <param name="backgroundImage">The background image.</param>
        /// <param name="backgroundLayout">The background layout.</param>
        /// <param name="clientRectangle">The client rectangle.</param>
        public static void RenderBackgroundImage(Graphics graphics, Image backgroundImage, BackgroundLayout backgroundLayout, Rectangle clientRectangle)
        {
            if (graphics == null)
            {
                throw new ArgumentNullException(nameof(graphics));
            }

            if (backgroundImage == null)
            {
                return;
            }

            if (clientRectangle == Rectangle.Empty)
            {
                throw new ArgumentNullException(nameof(clientRectangle));
            }

            switch (backgroundLayout)
            {
            case BackgroundLayout.None:
            {
                VisualImageRenderer.RenderImage(graphics, backgroundImage);
                break;
            }

            case BackgroundLayout.Center:
            {
                VisualImageRenderer.RenderImageCenteredFit(graphics, clientRectangle, backgroundImage);
                break;
            }

            case BackgroundLayout.Stretch:
            {
                VisualImageRenderer.RenderImageFilled(graphics, clientRectangle, backgroundImage);
                break;
            }

            default:
            {
                throw new ArgumentOutOfRangeException(nameof(backgroundLayout), backgroundLayout, null);
            }
            }
        }
        /// <summary>Renders the background.</summary>
        /// <param name="graphics">The specified graphics to draw on.</param>
        /// <param name="backColor">The back color.</param>
        /// <param name="backgroundImage">The background image.</param>
        /// <param name="backgroundLayout">The background Layout.</param>
        /// <param name="clientRectangle">The client rectangle.</param>
        public static void RenderBackground(Graphics graphics, Color backColor, Image backgroundImage, BackgroundLayout backgroundLayout, Rectangle clientRectangle)
        {
            if (graphics == null)
            {
                throw new ArgumentNullException(nameof(graphics));
            }

            if (backColor == Color.Empty)
            {
                throw new ArgumentNullException(nameof(backColor));
            }

            if (clientRectangle == Rectangle.Empty)
            {
                throw new ArgumentNullException(nameof(clientRectangle));
            }

            graphics.FillRectangle(new SolidBrush(backColor), clientRectangle);
            RenderBackgroundImage(graphics, backgroundImage, backgroundLayout, clientRectangle);
        }
Beispiel #5
0
        private void Init(byte[] romBuffer, Offsets offsets, TextCollection names)
        {
            // TODO: Retrieve order dynamically from the ROM
            int[] reorder = { 5, 4, 6, 9, 8, 10, 7, 12 }; // To reorder the themes, as they're not in the same order as the names

            int[] paletteOffsets     = Utilities.ReadBlockOffset(romBuffer, offsets[Offset.ThemePalettes], this.themes.Length);
            int[] roadTileGfxOffsets = Utilities.ReadBlockOffset(romBuffer, offsets[Offset.ThemeRoadGraphics], this.themes.Length);
            int[] bgTileGfxOffsets   = Utilities.ReadBlockOffset(romBuffer, offsets[Offset.ThemeBackgroundGraphics], this.themes.Length);
            int[] bgLayoutOffsets    = Utilities.ReadBlockOffset(romBuffer, offsets[Offset.ThemeBackgroundLayouts], this.themes.Length);

            bool roadTilesetHackApplied = Themes.IsRoadTilesetHackApplied(romBuffer, offsets);

            byte[]   commonRoadTilePaletteIndexes;
            byte[][] commonRoadTileGfx;

            if (roadTilesetHackApplied)
            {
                commonRoadTilePaletteIndexes = null;
                commonRoadTileGfx            = null;
            }
            else
            {
                int commonRoadTileUpperByte  = offsets[Offset.CommonTilesetGraphicsUpperByte];
                int commonRoadTileLowerBytes = offsets[Offset.CommonTilesetGraphicsLowerBytes];
                int commonRoadTileOffset     = Utilities.BytesToOffset(
                    romBuffer[commonRoadTileLowerBytes],
                    romBuffer[commonRoadTileLowerBytes + 1],
                    romBuffer[commonRoadTileUpperByte]
                    );
                byte[] commonRoadTileData = Codec.Decompress(romBuffer, commonRoadTileOffset);
                commonRoadTilePaletteIndexes = Themes.GetPaletteIndexes(commonRoadTileData, RoadTileset.CommonTileCount);
                commonRoadTileGfx            = Utilities.ReadBlockGroupUntil(commonRoadTileData, RoadTileset.TileCount, -1, 32);
            }

            bool tileGenresRelocated = Themes.AreTileGenresRelocated(romBuffer, offsets[Offset.TileGenreLoad]);

            byte[]          roadTileGenreData;
            byte[][]        roadTileGenreIndexes;
            RoadTileGenre[] commonRoadTileGenres;

            if (tileGenresRelocated)
            {
                roadTileGenreData    = null;
                roadTileGenreIndexes = null;
                commonRoadTileGenres = null;
            }
            else
            {
                roadTileGenreData    = Codec.Decompress(romBuffer, offsets[Offset.TileGenres]);
                roadTileGenreIndexes = Utilities.ReadBlockGroup(romBuffer, offsets[Offset.TileGenreIndexes], 2, Theme.Count * 2);
                commonRoadTileGenres = Themes.GetTileGenres(roadTileGenreData, 0, RoadTileset.CommonTileCount);
            }

            for (int i = 0; i < this.themes.Length; i++)
            {
                TextItem nameItem = names[reorder[i]];

                // HACK: Force the length to 512 in case the color palette data in the ROM is corrupt ("EarthBound Kart Beta" has this issue)
                byte[]   paletteData = Codec.Decompress(romBuffer, paletteOffsets[i], 512);
                Palettes palettes    = new Palettes(paletteData);

                byte[]   roadTileData = Codec.Decompress(romBuffer, roadTileGfxOffsets[i]);
                byte[][] roadTileGfx  = Utilities.ReadBlockGroupUntil(roadTileData, RoadTileset.TileCount, -1, 32);
                byte[]   allRoadTilePaletteIndexes;
                byte[][] allRoadTileGfx;

                if (roadTilesetHackApplied)
                {
                    allRoadTilePaletteIndexes = Themes.GetPaletteIndexes(roadTileData, RoadTileset.TileCount);
                    allRoadTileGfx            = roadTileGfx;
                }
                else
                {
                    byte[] roadTilePaletteIndexes = Themes.GetPaletteIndexes(roadTileData, RoadTileset.ThemeTileCount);
                    allRoadTilePaletteIndexes = new byte[RoadTileset.TileCount];
                    Buffer.BlockCopy(roadTilePaletteIndexes, 0, allRoadTilePaletteIndexes, 0, RoadTileset.ThemeTileCount);
                    Buffer.BlockCopy(commonRoadTilePaletteIndexes, 0, allRoadTilePaletteIndexes, RoadTileset.ThemeTileCount, RoadTileset.CommonTileCount);

                    allRoadTileGfx = new byte[RoadTileset.TileCount][];
                    Array.Copy(roadTileGfx, 0, allRoadTileGfx, 0, roadTileGfx.Length);

                    // Clone the commonRoadTileGfx jagged array,
                    // because we don't want theme-specific tile graphics update to affect other themes
                    byte[][] commonRoadTileGfxClone = new byte[commonRoadTileGfx.Length][];
                    for (int j = 0; j < commonRoadTileGfxClone.Length; j++)
                    {
                        commonRoadTileGfxClone[j] = Utilities.ReadBlock(commonRoadTileGfx[j], 0, commonRoadTileGfx[j].Length);
                    }

                    Array.Copy(commonRoadTileGfxClone, 0, allRoadTileGfx, RoadTileset.ThemeTileCount, commonRoadTileGfxClone.Length);

                    // Set empty tile default graphics value
                    for (int j = roadTileGfx.Length; j < RoadTileset.ThemeTileCount; j++)
                    {
                        allRoadTileGfx[j] = new byte[32];
                    }
                }

                RoadTileGenre[] allRoadTileGenres;

                if (tileGenresRelocated)
                {
                    int tileGenreOffset = offsets[Offset.TileGenresRelocated] + i * RoadTileset.TileCount;
                    allRoadTileGenres = Themes.GetTileGenres(romBuffer, tileGenreOffset, RoadTileset.TileCount);
                }
                else
                {
                    int             roadTileGenreIndex = roadTileGenreIndexes[i][0] + (roadTileGenreIndexes[i][1] << 8);
                    RoadTileGenre[] roadTileGenres     = Themes.GetTileGenres(roadTileGenreData, roadTileGenreIndex, roadTileGfx.Length);
                    allRoadTileGenres = new RoadTileGenre[RoadTileset.TileCount];
                    Array.Copy(roadTileGenres, 0, allRoadTileGenres, 0, roadTileGenres.Length);
                    Array.Copy(commonRoadTileGenres, 0, allRoadTileGenres, RoadTileset.ThemeTileCount, commonRoadTileGenres.Length);

                    // Set empty tile default genre value
                    for (int j = roadTileGfx.Length; j < RoadTileset.ThemeTileCount; j++)
                    {
                        allRoadTileGenres[j] = RoadTileGenre.Road;
                    }
                }

                RoadTileset roadTileset = Themes.GetRoadTileset(palettes, allRoadTilePaletteIndexes, allRoadTileGfx, allRoadTileGenres);

                byte[]            bgTileData = Codec.Decompress(romBuffer, bgTileGfxOffsets[i]);
                byte[][]          bgTileGfx  = Utilities.ReadBlockGroupUntil(bgTileData, 0, -1, 16);
                BackgroundTileset bgTileset  = Themes.GetBackgroundTileset(palettes, bgTileGfx);

                byte[]           bgLayoutData = Codec.Decompress(romBuffer, bgLayoutOffsets[i]);
                BackgroundLayout bgLayout     = new BackgroundLayout(bgLayoutData);

                Background background = new Background(bgTileset, bgLayout);

                this.themes[i] = new Theme(nameItem, palettes, roadTileset, background);
            }
        }