diff --git a/OpenRA.FileFormats/Map/MapStub.cs b/OpenRA.FileFormats/Map/MapStub.cs index 923f0390cf..9662b05a8b 100644 --- a/OpenRA.FileFormats/Map/MapStub.cs +++ b/OpenRA.FileFormats/Map/MapStub.cs @@ -45,8 +45,8 @@ namespace OpenRA.FileFormats public int2 BottomRight; public int Width { get { return BottomRight.X - TopLeft.X; } } public int Height { get { return BottomRight.Y - TopLeft.Y; } } - public Lazy Preview; - + public Map Map { get { return new Map(Package); }} + static List Fields = new List() { "Selectable", "Title", "Description", "Author", "PlayerCount", "Tileset", "TopLeft", "BottomRight" }; @@ -64,10 +64,6 @@ namespace OpenRA.FileFormats Waypoints.Add(wp.Key, new int2(int.Parse(loc[0]), int.Parse(loc[1]))); } - Preview = Lazy.New( - () => new Bitmap(Package.GetContent("preview.png")) - ); - Uid = Package.GetContent("map.uid").ReadAllText(); } diff --git a/OpenRA.Game/Graphics/Minimap.cs b/OpenRA.Game/Graphics/Minimap.cs index c67e8370dd..61a34955b6 100644 --- a/OpenRA.Game/Graphics/Minimap.cs +++ b/OpenRA.Game/Graphics/Minimap.cs @@ -162,5 +162,43 @@ namespace OpenRA.Graphics (int)(bounds.Width * fx + bounds.Left), (int)(bounds.Height * fy + bounds.Top)); } + + + static int NextPowerOf2(int v) + { + --v; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + ++v; + return v; + } + + public static Bitmap RenderMapPreview(MapStub stub) + { + Map map = stub.Map; + var tileset = Rules.TileSets[map.Tileset]; + var size = NextPowerOf2(Math.Max(map.Width, map.Height)); + Bitmap terrain = new Bitmap(size, size); + + for (var x = 0; x < map.Width; x++) + for (var y = 0; y < map.Height; y++) + { + var mapX = x + map.TopLeft.X; + var mapY = y + map.TopLeft.Y; + var type = tileset.GetTerrainType(map.MapTiles[mapX, mapY]); + string res = null; + if (map.MapResources[mapX, mapY].type != 0) + res = Rules.Info["world"].Traits.WithInterface() + .Where(t => t.ResourceType == map.MapResources[mapX, mapY].type) + .Select(t => t.TerrainType).FirstOrDefault(); + if (res != null) + type = res; + + terrain.SetPixel(x, y, tileset.Terrain[type].Color); + } + return terrain; + } } } diff --git a/OpenRA.Game/Widgets/MapPreviewWidget.cs b/OpenRA.Game/Widgets/MapPreviewWidget.cs index 7d75aa9d43..d190122951 100755 --- a/OpenRA.Game/Widgets/MapPreviewWidget.cs +++ b/OpenRA.Game/Widgets/MapPreviewWidget.cs @@ -20,6 +20,8 @@ namespace OpenRA.Widgets public MapPreviewWidget() : base() { } + static Cache PreviewCache = new Cache(stub => Minimap.RenderMapPreview(stub)); + protected MapPreviewWidget(MapPreviewWidget other) : base(other) { @@ -74,10 +76,11 @@ namespace OpenRA.Widgets if( mapPreviewDirty ) { - if( mapChooserSheet == null || mapChooserSheet.Size.Width != map.Width || mapChooserSheet.Size.Height != map.Height ) - mapChooserSheet = new Sheet( Game.renderer, new Size( map.Width, map.Height ) ); + var preview = PreviewCache[map]; + if( mapChooserSheet == null || mapChooserSheet.Size.Width != preview.Width || mapChooserSheet.Size.Height != preview.Height ) + mapChooserSheet = new Sheet( Game.renderer, new Size( preview.Width, preview.Height ) ); - mapChooserSheet.Texture.SetData( map.Preview.Value ); + mapChooserSheet.Texture.SetData( preview ); mapChooserSprite = new Sprite( mapChooserSheet, new Rectangle( 0, 0, map.Width, map.Height ), TextureChannel.Alpha ); mapPreviewDirty = false; }