private void TestGetBytes(string fileName) { byte[] dataBefore = File.ReadFile(fileName); BackgroundLayout layout = new BackgroundLayout(dataBefore); byte[] dataAfter = layout.GetBytes(); Assert.AreEqual(dataBefore, dataAfter); }
/// <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); }
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); } }