public EngineResult Execute()
{
try {
_logger.Info("Initializing virtual filesystem");
var mapStream = File.Open(Settings.InputFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
VirtualFile vmapFile;
var mixMap = new MixFile(mapStream, Settings.InputFile, 0, mapStream.Length, false, false);
if (mixMap.IsValid()) { // input max is a mix
var mapArchive = new MixFile(mapStream, Path.GetFileName(Settings.InputFile), true);
// grab the largest file in the archive
var mixEntry = mapArchive.Index.OrderByDescending(me => me.Value.Length).First();
vmapFile = mapArchive.OpenFile(mixEntry.Key);
}
else {
vmapFile = new VirtualFile(mapStream, Path.GetFileName(Settings.InputFile), true);
}
var mapFile = new MapFile(vmapFile, Path.GetFileName(Settings.InputFile));
if (!string.IsNullOrEmpty(Settings.ModConfig)) {
if (File.Exists(Settings.ModConfig)) {
ModConfig cfg;
try {
using (FileStream f = File.OpenRead(Settings.ModConfig))
cfg = ModConfig.Deserialize(f);
ModConfig.ActiveConfig = cfg;
if (Settings.Engine != EngineType.AutoDetect) {
if (Settings.Engine != cfg.Engine)
_logger.Warn("Provided engine override does not match mod config.");
}
else
Settings.Engine = ModConfig.ActiveConfig.Engine;
}
catch (IOException) {
_logger.Fatal("IOException while loading mod config");
}
catch (XmlException) {
_logger.Fatal("XmlException while loading mod config");
}
catch (SerializationException) {
_logger.Fatal("Serialization exception while loading mod config");
}
}
else {
_logger.Fatal("Invalid mod config file specified");
}
}
if (Settings.Engine == EngineType.AutoDetect) {
Settings.Engine = EngineDetector.DetectEngineType(mapFile);
_logger.Info("Engine autodetect result: {0}", Settings.Engine);
}
// ---------------------------------------------------------------
// Code to organize moving of maps in a directory for themselves
/*
string mapName = DetermineMapName(mapFile, Settings.Engine);
string ndir = Path.Combine(Path.GetDirectoryName(Settings.InputFile), mapName);
if (!Directory.Exists(ndir)) Directory.CreateDirectory(ndir);
mapFile.Close();
mapFile.Dispose();
File.Move(Settings.InputFile, Path.Combine(ndir, Path.GetFileName(mapFile.FileName)));
return 0;*/
// ---------------------------------------------------------------
// enginetype is now definitive, load mod config
if (ModConfig.ActiveConfig == null)
ModConfig.LoadDefaultConfig(Settings.Engine);
// first add the dirs, then load the extra mixes, then scan the dirs
foreach (string modDir in ModConfig.ActiveConfig.Directories)
VFS.Add(modDir);
// add mixdir to VFS (if it's not included in the mod config)
if (!ModConfig.ActiveConfig.Directories.Any()) {
string mixDir = VFS.DetermineMixDir(Settings.MixFilesDirectory, Settings.Engine);
VFS.Add(mixDir);
}
foreach (string mixFile in ModConfig.ActiveConfig.ExtraMixes)
VFS.Add(mixFile);
VFS.Instance.LoadMixes(Settings.Engine);
var map = new Map.Map {
IgnoreLighting = Settings.IgnoreLighting,
StartPosMarking = Settings.StartPositionMarking,
MarkOreFields = Settings.MarkOreFields
};
if (!map.Initialize(mapFile, Settings.Engine, ModConfig.ActiveConfig.CustomRulesIniFiles, ModConfig.ActiveConfig.CustomArtIniFiles)) {
_logger.Error("Could not successfully load this map. Try specifying the engine type manually.");
return EngineResult.LoadRulesFailed;
}
if (!map.LoadTheater()) {
_logger.Error("Could not successfully load all required components for this map. Aborting.");
return EngineResult.LoadTheaterFailed;
}
if (Settings.StartPositionMarking == StartPositionMarking.Tiled)
map.MarkTiledStartPositions();
if (Settings.MarkOreFields)
map.MarkOreAndGems();
if (Settings.FixupTiles) map.FixupTileLayer();
map.Draw();
if (Settings.StartPositionMarking == StartPositionMarking.Squared)
map.DrawSquaredStartPositions();
#if DEBUG
// ====================================================================================
using (var form = new DebugDrawingSurfaceWindow(map.GetDrawingSurface(), map.GetTiles(), map.GetTheater(), map)) {
form.RequestTileEvaluate += map.DebugDrawTile; form.ShowDialog();
}
// ====================================================================================
#endif
if (Settings.OutputFile == "")
Settings.OutputFile = DetermineMapName(mapFile, Settings.Engine);
if (Settings.OutputDir == "")
Settings.OutputDir = Path.GetDirectoryName(Settings.InputFile);
// free up as much memory as possible before saving the large images
Rectangle saveRect = map.GetSizePixels(Settings.SizeMode);
DrawingSurface ds = map.GetDrawingSurface();
saveRect.Intersect(new Rectangle(0, 0, ds.Width, ds.Height));
// if we don't need this data anymore, we can try to save some memory
if (!Settings.GeneratePreviewPack) {
ds.FreeNonBitmap();
map.FreeUseless();
GC.Collect();
}
if (Settings.SaveJPEG)
ds.SaveJPEG(Path.Combine(Settings.OutputDir, Settings.OutputFile + ".jpg"), Settings.JPEGCompression, saveRect);
if (Settings.SavePNG)
ds.SavePNG(Path.Combine(Settings.OutputDir, Settings.OutputFile + ".png"), Settings.PNGQuality, saveRect);
Regex reThumb = new Regex(@"(\+|)?\((\d+),(\d+)\)");
var match = reThumb.Match(Settings.ThumbnailConfig);
if (match.Success) {
Size dimensions = new Size(
int.Parse(match.Groups[2].Captures[0].Value),
int.Parse(match.Groups[3].Captures[0].Value));
var cutRect = map.GetSizePixels(Settings.SizeMode);
if (match.Groups[1].Captures[0].Value == "+") {
// + means maintain aspect ratio
double aspectRatio = cutRect.Width / (double)cutRect.Height;
if (dimensions.Width / (double)dimensions.Height > aspectRatio) {
dimensions.Height = (int)(dimensions.Width / aspectRatio);
}
else {
dimensions.Width = (int)(dimensions.Height / aspectRatio);
}
}
_logger.Info("Saving thumbnail with dimensions {0}x{1}", dimensions.Width, dimensions.Height);
ds.SaveThumb(dimensions, cutRect, Path.Combine(Settings.OutputDir, "thumb_" + Settings.OutputFile + ".jpg"));
}
if (Settings.GeneratePreviewPack || Settings.FixupTiles) {
if (mapFile.BaseStream is MixFile)
_logger.Error("Cannot fix tile layer or inject thumbnail into an archive (.mmx/.yro/.mix)!");
else {
if (Settings.GeneratePreviewPack)
map.GeneratePreviewPack(Settings.PreviewMarkers, Settings.SizeMode, mapFile, Settings.FixPreviewDimensions);
_logger.Info("Saving map to " + Settings.InputFile);
mapFile.Save(Settings.InputFile);
}
}
}
catch (Exception exc) {
_logger.Error(string.Format("An unknown fatal exception occured: {0}", exc), exc);
#if DEBUG
throw;
#endif
return EngineResult.Exception;
}
return EngineResult.RenderedOk;
}