public MainForm() { testToolStripMenuItem_Click(null, null); if (Properties.Settings.Default.ProjectsDirectory == null) Properties.Settings.Default.ProjectsDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Sunfish 2011\\Projects"); if(!Directory.Exists(Properties.Settings.Default.ProjectsDirectory)) Directory.CreateDirectory(Properties.Settings.Default.ProjectsDirectory); InitializeComponent(); LoadDefaultWorkspace(); #region Status Handler Globals.StatusChangeHandler s = new Globals.StatusChangeHandler(Status); Globals.StatusChanged += s; #endregion #region Dialogs Initialization openMapDialog = new OpenFileDialog(); openMapDialog.Filter = "Halo 2 Cache File (*.map) | *.map"; openProjectDialog = new OpenFileDialog(); openProjectDialog.Filter = "Sunfish Project File (*.h2proj) | *.h2proj"; openProjectDialog.InitialDirectory = Properties.Settings.Default.ProjectsDirectory; saveTagDialog = new SaveFileDialog(); saveTagDialog.Filter = "Sunfish Tag File (*.sf) | *.sf"; saveFilters = new Dictionary<string, int>(Index.Types.Length); for (int i = 0; i < Index.Types.Length; i++) { saveFilters.Add(Index.Types[i].ToString(), i + 2); saveTagDialog.Filter += String.Format("|Sunfish {0} File (*.{1}.sf) | *.{1}.sf", Index.Types[i].ToString(), Index.Types[i].ToPathSafeString()); } saveTagDialog.SupportMultiDottedExtensions = true; saveTagDialog.AddExtension = true; #endregion #region auto load #if DEBUG project = new Project(); project.Load(@"O:\Sunfish 2011\Projects\taco\taco.h2proj"); LoadProject(); #endif #endregion }
public void Compile(Project project, bool rebuildcaches) { List<string> filenames = new List<string>(Directory.GetFiles(project.SourceDirectory, String.Format("*{0}", Sunfish.Tag.Path.Extension), SearchOption.AllDirectories)); project.SourceFiles = new List<string>(filenames); //for(int i=0;i<project.SourceFiles.Count;i++) // project.SourceFiles[i] = project.SourceFiles[i].Substring(project.SourceDirectory.Length); project.SortSourceFiles(); Benchmark mark = new Benchmark(); mark.Begin(); if (!rebuildcaches && CheckCacheStatus(project)) { LoadCaches(project); } else CreateCaches(project); CreateMap(project); mark.End(); System.Windows.Forms.MessageBox.Show(String.Format("finished in: {0}", mark.Result), "Solution Compiled"); }
private void LoadCaches(Project project) { SoundCache.Load(Path.Combine(project.BinDirectory, "SOUND_RAW_CACHE.BIN")); ModelCache.Load(Path.Combine(project.BinDirectory, "MODEL_RAW_CACHE.BIN")); SbspCache.Load(Path.Combine(project.BinDirectory, "STRUCTURE_RAW_CACHE.BIN")); LtmpCache.Load(Path.Combine(project.BinDirectory, "LIGHTMAP_RAW_CACHE.BIN")); DECRCache.Load(Path.Combine(project.BinDirectory, "DECORATER_RAW_CACHE.BIN")); WeatherCache.Load(Path.Combine(project.BinDirectory, "WEATHER_RAW_CACHE.BIN")); AnimationCache.Load(Path.Combine(project.BinDirectory, "ANIMATION_RAW_CACHE.BIN")); BitmapCache.Load(Path.Combine(project.BinDirectory, "TEXTURE_RAW_CACHE.BIN")); StringIDsCache.Load(Path.Combine(project.BinDirectory, "STRINGS_CACHE.BIN")); IndexCache.Load(Path.Combine(project.BinDirectory, "INDEX.BIN")); TagnameCache.Load(Path.Combine(project.BinDirectory, "TAGNAMES.BIN")); EnglishUnicodeCache.Load(Path.Combine(project.BinDirectory, "ENGLISH_UNICODE.BIN")); MetaCache.Load(Path.Combine(project.BinDirectory, "META.BIN")); SbspLtmpMetaCache.Load(Path.Combine(project.BinDirectory, "STRUCTURE_LIGHTMAP_META.BIN")); Header = new Header(File.OpenRead(Path.Combine(project.BinDirectory, "HEADER.BIN"))); }
public void Load(string filename) { Globals.Status = "Loading Project..."; XmlReader xmlReader = XmlReader.Create(filename); while (xmlReader.Read()) if (xmlReader.NodeType == XmlNodeType.Element) { switch (xmlReader.LocalName) { case "Project": Name = xmlReader.GetAttribute("name"); Scenario = xmlReader.GetAttribute("scenario"); CacheCreationDate = DateTime.FromBinary(long.Parse(xmlReader.GetAttribute("cache"))); break; case "RootDirectory": RootDirectory = xmlReader.GetAttribute("path"); break; case "Includes": XmlReader filesReader = xmlReader.ReadSubtree(); filesReader.Read(); while (filesReader.Read()) { if (filesReader.NodeType == XmlNodeType.Element) { switch (filesReader.LocalName) { case "include": string fName = filesReader.GetAttribute("path"); Includes.Add(fName); break; } } } break; } } xmlReader.Close(); SourceFiles = new List<string>(Directory.GetFiles(SourceDirectory, String.Format("*{0}", Sunfish.Tag.Path.Extension), SearchOption.AllDirectories)); SortSourceFiles(); List<CompilerTag> Tags = new List<CompilerTag>(SourceFiles.Count); Directory.SetCurrentDirectory(SourceDirectory); foreach (string filepath in SourceFiles) Tags.Add(new CompilerTag(filepath)); Strings = new List<string>(10000); Strings.AddRange(Sunfish.Developmental.GlobalStringIDs.Values); foreach (CompilerTag tag in Tags) foreach (string str in tag.Strings) if (!Strings.Contains(str)) Strings.Add(str); CurrentProject = this; Globals.ClearStatus(); }
public static Project Create(string path, string name) { if (!Directory.Exists(path)) throw new Exception(); Project p = new Project(); p.RootDirectory = path; p.Name = name; Directory.CreateDirectory(p.SourceDirectory); Directory.CreateDirectory(p.BinDirectory); XmlWriter xmlWriter = XmlWriter.Create(Path.Combine(p.RootDirectory, Path.ChangeExtension(name, ".h2proj"))); xmlWriter.WriteStartDocument(); xmlWriter.WriteStartElement("Project"); xmlWriter.WriteAttributeString("name", name); xmlWriter.WriteAttributeString("cache", DateTime.MinValue.ToBinary().ToString()); xmlWriter.WriteStartElement("RootDirectory"); xmlWriter.WriteAttributeString("path", p.RootDirectory); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("Includes"); xmlWriter.WriteEndElement(); xmlWriter.WriteEndDocument(); xmlWriter.Close(); return p; }
private void openProjectToolStripMenuItem_Click(object sender, EventArgs e) { if (openProjectDialog.ShowDialog() == DialogResult.OK) { if (project != null) { CloseProject(); } project = new Project(); project.Load(openProjectDialog.FileName); LoadProject(); } }
private void CloseProject() { if (project != null) { project.Save(); Explorer.SaveLayout(Path.Combine(project.RootDirectory, "user.settings")); project = null; this.Text = "Sunfish 2011"; Explorer.treeView1.Nodes.Clear(); projectToolStripMenuItem.Enabled = false; projectToolStripMenuItem.Visible = false; buildToolStripMenuItem.Enabled = false; buildToolStripMenuItem.Visible = false; closeProjectToolStripMenuItem.Enabled = false; } }
private void newProjectToolStripMenuItem_Click(object sender, EventArgs e) { CreateFileDialog cfd = new CreateFileDialog("New Project"); if (cfd.ShowDialog() == DialogResult.OK) { project = Project.Create(Path.Combine(Properties.Settings.Default.ProjectsDirectory, cfd.FileName), cfd.FileName); LoadProject(); } }
private bool CheckCacheStatus(Project project) { return (File.Exists(Path.Combine(project.BinDirectory, "SOUND_RAW_CACHE.BIN")) && File.GetLastWriteTime(Path.Combine(project.BinDirectory, "SOUND_RAW_CACHE.BIN")) == project.CacheCreationDate && File.Exists(Path.Combine(project.BinDirectory, "MODEL_RAW_CACHE.BIN")) && File.GetLastWriteTime(Path.Combine(project.BinDirectory, "MODEL_RAW_CACHE.BIN")) == project.CacheCreationDate && File.Exists(Path.Combine(project.BinDirectory, "STRUCTURE_RAW_CACHE.BIN")) && File.GetLastWriteTime(Path.Combine(project.BinDirectory, "STRUCTURE_RAW_CACHE.BIN")) == project.CacheCreationDate && File.Exists(Path.Combine(project.BinDirectory, "LIGHTMAP_RAW_CACHE.BIN")) && File.GetLastWriteTime(Path.Combine(project.BinDirectory, "LIGHTMAP_RAW_CACHE.BIN")) == project.CacheCreationDate && File.Exists(Path.Combine(project.BinDirectory, "DECORATER_RAW_CACHE.BIN")) && File.GetLastWriteTime(Path.Combine(project.BinDirectory, "DECORATER_RAW_CACHE.BIN")) == project.CacheCreationDate && File.Exists(Path.Combine(project.BinDirectory, "WEATHER_RAW_CACHE.BIN")) && File.GetLastWriteTime(Path.Combine(project.BinDirectory, "WEATHER_RAW_CACHE.BIN")) == project.CacheCreationDate && File.Exists(Path.Combine(project.BinDirectory, "ANIMATION_RAW_CACHE.BIN")) && File.GetLastWriteTime(Path.Combine(project.BinDirectory, "ANIMATION_RAW_CACHE.BIN")) == project.CacheCreationDate && File.Exists(Path.Combine(project.BinDirectory, "TEXTURE_RAW_CACHE.BIN")) && File.GetLastWriteTime(Path.Combine(project.BinDirectory, "TEXTURE_RAW_CACHE.BIN")) == project.CacheCreationDate && File.Exists(Path.Combine(project.BinDirectory, "STRINGS_CACHE.BIN")) && File.GetLastWriteTime(Path.Combine(project.BinDirectory, "STRINGS_CACHE.BIN")) == project.CacheCreationDate && File.Exists(Path.Combine(project.BinDirectory, "INDEX.BIN")) && File.GetLastWriteTime(Path.Combine(project.BinDirectory, "INDEX.BIN")) == project.CacheCreationDate && File.Exists(Path.Combine(project.BinDirectory, "TAGNAMES.BIN")) && File.GetLastWriteTime(Path.Combine(project.BinDirectory, "TAGNAMES.BIN")) == project.CacheCreationDate && File.Exists(Path.Combine(project.BinDirectory, "ENGLISH_UNICODE.BIN")) && File.GetLastWriteTime(Path.Combine(project.BinDirectory, "ENGLISH_UNICODE.BIN")) == project.CacheCreationDate && File.Exists(Path.Combine(project.BinDirectory, "META.BIN")) && File.GetLastWriteTime(Path.Combine(project.BinDirectory, "META.BIN")) == project.CacheCreationDate && File.Exists(Path.Combine(project.BinDirectory, "STRUCTURE_LIGHTMAP_META.BIN")) && File.GetLastWriteTime(Path.Combine(project.BinDirectory, "STRUCTURE_LIGHTMAP_META.BIN")) == project.CacheCreationDate && File.Exists(Path.Combine(project.BinDirectory, "HEADER.BIN")) && File.GetLastWriteTime(Path.Combine(project.BinDirectory, "HEADER.BIN")) == project.CacheCreationDate); }
public void Compile(Project project) { Compile(project, false); }
public void CreateMap(Project project) { FileStream output = new FileStream(Path.ChangeExtension(Path.Combine(project.BinDirectory, project.Name), ".map"), FileMode.Create, FileAccess.ReadWrite, FileShare.None); using (output) { BinaryWriter bw = new BinaryWriter(output); output.Position = SoundCache.Offset; SoundCache.Stream.WriteTo(output); output.Position = ModelCache.Offset; ModelCache.Stream.WriteTo(output); output.Position = SbspCache.Offset; SbspCache.Stream.WriteTo(output); output.Position = LtmpCache.Offset; LtmpCache.Stream.WriteTo(output); output.Position = DECRCache.Offset; DECRCache.Stream.WriteTo(output); output.Position = WeatherCache.Offset; WeatherCache.Stream.WriteTo(output); output.Position = AnimationCache.Offset; AnimationCache.Stream.WriteTo(output); output.Position = SbspLtmpMetaCache.Offset; SbspLtmpMetaCache.WriteTo(output); output.Position = StringIDsCache.Offset; StringIDsCache.WriteTo(output, ref Header); output.Position = Padding.Pad(output.Position); output.Position = TagnameCache.Offset; TagnameCache.WriteIndexTo(output, ref Header); TagnameCache.WriteTableTo(output, ref Header); output.Position = Padding.Pad(output.Position); output.Position = EnglishUnicodeCache.Offset; EnglishUnicodeCache.WriteUnicodeIndexTo(output); EnglishUnicodeCache.WriteUnicodeTableTo(output); output.Position = Padding.Pad(output.Position); output.Position = BitmapCache.Offset; BitmapCache.Stream.WriteTo(output); output.Position = IndexCache.Offset; IndexCache.WriteTo(output, ref Header, IndexCache.Entries[0].Index, IndexCache.Entries[3].Index); output.Position = MetaCache.Offset; MetaCache.Stream.WriteTo(output); bw.Write(Padding.GetBytes(output.Position, 2048)); Header.Checksum = CalculateChecksum(output); Header.TagCacheLength = MetaCache.Length; Header.TotalCacheLength = MetaCache.Length + SbspLtmpMetaCache.Length + IndexCache.Length; output.Position = 0; bw.Write(Header.ToByteArray()); } }
public void CreateCaches(Project project) { #region STAGE ONE - Load Data To Caches #region Load Tags Tags = new List<CompilerTag>(project.SourceFiles.Count); Directory.SetCurrentDirectory(project.SourceDirectory); foreach (string filename in project.SourceFiles) Tags.Add(new CompilerTag(filename)); #endregion Header = new Header() { Type = Header.MapType.Multiplayer, Name = project.Name, Scenario = project.Scenario }; foreach (CompilerTag tag in Tags) { #region Cache StringReference Values StringIDsCache.CacheData(tag); #endregion #region Process Unicode Tags if (tag.Type == "utf8") EnglishUnicodeCache.CacheData(tag, StringIDsCache); #endregion #region Initialize Tag in Filetable and Index TagnameCache.CacheData(tag); IndexCache.CacheData(tag); #endregion #region Cache Resource Data switch (tag.Type) { case "ugh!": SoundCache.CacheData(tag); break; case "mode": ModelCache.CacheData(tag); break; case "sbsp": SbspCache.CacheData(tag); break; case "ltmp": LtmpCache.CacheData(tag); break; case "DECR": DECRCache.CacheData(tag); break; case "weat": WeatherCache.CacheData(tag); break; case "jmad": AnimationCache.CacheData(tag); break; case "bitm": BitmapCache.CacheData(tag); break; } #endregion #region Cache Tag Data switch (tag.Type) { case "sbsp": SbspLtmpMetaCache.CacheData(tag); break; case "ltmp": SbspLtmpMetaCache.CacheData(tag); break; default: MetaCache.CacheData(tag); break; } #endregion } #endregion #region STAGE TWO - Setup And Sort Caches SoundCache.Offset = 2048; ModelCache.Offset = SoundCache.NextOffset; SbspCache.Offset = ModelCache.NextOffset; LtmpCache.Offset = SbspCache.NextOffset; DECRCache.Offset = LtmpCache.NextOffset; WeatherCache.Offset = DECRCache.NextOffset; AnimationCache.Offset = WeatherCache.NextOffset; SbspLtmpMetaCache.Offset = AnimationCache.NextOffset; #region Update Scenario Tag SbspLtmpMetaCache.SetVirtualOffset(IndexCache.NextVirtualOffset); SbspLtmpMetaCache.UpdateScenario(Tags[3]); MetaCache[3] = Tags[3].TagStream.ToArray(); #endregion StringIDsCache.Offset = SbspLtmpMetaCache.NextOffset; TagnameCache.Offset = StringIDsCache.NextOffset; EnglishUnicodeCache.Offset = TagnameCache.NextOffset; BitmapCache.Offset = EnglishUnicodeCache.NextOffset; IndexCache.Offset = BitmapCache.NextOffset; MetaCache.Offset = IndexCache.NextOffset; #region Update Globals with Unicode information BinaryWriter bw = new BinaryWriter(Tags[0].TagStream); Tags[0].TagStream.Seek(400, SeekOrigin.Begin); bw.Write(EnglishUnicodeCache.Values.Count); bw.Write(EnglishUnicodeCache.UnicodeTableLength); bw.Write(EnglishUnicodeCache.UnicodeIndexOffset); bw.Write(EnglishUnicodeCache.UnicodeTableOffset); Tags[0].TagStream.Seek(4, SeekOrigin.Current); for (int i = 0; i < 8; i++) { Tags[0].TagStream.Seek(8, SeekOrigin.Current); bw.Write(new byte[8]); bw.Write(BitmapCache.Offset); bw.Write(BitmapCache.Offset); Tags[0].TagStream.Seek(4, SeekOrigin.Current); } MetaCache[0] = Tags[0].TagStream.ToArray(); #endregion #region Set Virtual Addresses MetaCache.VirtualOffset = SbspLtmpMetaCache.NextVirtualOffset; #endregion #region Update IndexCache SbspLtmpMetaCache.UpdateIndexCache(IndexCache); MetaCache.UpdateIndexCache(IndexCache); #endregion #endregion #region STAGE THREE - Update Meta Values foreach (CompilerTag tag in Tags) { BinaryReader br; MetaCache Cache = null; if (SbspLtmpMetaCache.TagIndexers.Contains(tag.ID)) Cache = SbspLtmpMetaCache; else if (MetaCache.TagIndexers.Contains(tag.ID)) Cache = MetaCache; else throw new Exception(); br = new BinaryReader(Cache.Stream); bw = new BinaryWriter(Cache.Stream); int Index = Cache.TagIndexers.IndexOf(tag.ID); RawCache ResourceCache = null; switch (tag.Type) { case "ugh!": ResourceCache = SoundCache; break; case "mode": ResourceCache = ModelCache; break; case "sbsp": ResourceCache = SbspCache; break; case "ltmp": ResourceCache = LtmpCache; break; case "DECR": ResourceCache = DECRCache; break; case "weat": ResourceCache = WeatherCache; break; case "jmad": ResourceCache = AnimationCache; break; case "bitm": ResourceCache = BitmapCache; break; } #region Update Pointers and Other Values valueCache.Clear(); pointerCache.Clear(); Block block = Blocks.Types[tag.Type]; ProcessBlock(block, 1, 0, tag.TagStream); for (int i = 0; i < pointerCache.Count; i++) { Cache.Stream.Position = Cache.Entries[Index].Offset + pointerCache.Values[i].Offset; int address = br.ReadInt32(); if (address != -1) { Cache.Stream.Seek(-4, SeekOrigin.Current); bw.Write(IndexCache.Entries[tag.ID].Address + address); } } for (int i = 0; i < valueCache.Count; i++) { switch (valueCache.Values[i].Type) { case Value.ValueType.StringId: Cache.Stream.Position = Cache.Entries[Index].Offset + valueCache.Values[i].Offset; int index = br.ReadInt32(); Cache.Stream.Seek(-4, SeekOrigin.Current); StringId strRef = new StringId((short)StringIDsCache.Values.IndexOf(tag.Strings[index]), (sbyte)Encoding.UTF8.GetByteCount(tag.Strings[index])); bw.Write(strRef); break; TagIndex tagIndex; case Value.ValueType.TagId: Cache.Stream.Position = Cache.Entries[Index].Offset + valueCache.Values[i].Offset; index = br.ReadInt32(); if (index == -1) continue; Cache.Stream.Seek(-4, SeekOrigin.Current); tagIndex = IndexCache.Entries[TagnameCache.Tagnames.IndexOf(tag.TagReferences[index])].Index; bw.Write(tagIndex); break; case Value.ValueType.TagReference: Cache.Stream.Position = Cache.Entries[Index].Offset + valueCache.Values[i].Offset + 4; index = br.ReadInt32(); if (index == -1) continue; Cache.Stream.Seek(-8, SeekOrigin.Current); byte[] bytes = Encoding.UTF8.GetBytes(Globals.ReverseString(Sunfish.Index.GetDirtyType(Tag.Path.GetTagType(tag.TagReferences[index])))); bw.Write(bytes, 0, 4); tagIndex = IndexCache.Entries[TagnameCache.Tagnames.IndexOf(tag.TagReferences[index])].Index; bw.Write(tagIndex); break; } } #endregion #region Update Resource Values if (tag.ResourceInformation.Length > 0) { rawCache.Clear(); ProcessBlockRaw(block, 1, 0, tag.TagStream); int ResourceCacheIndex = ResourceCache.TagIDs.IndexOf(tag.ID); int ResourceIndex = 0; for (int i = 0; i < rawCache.Count; i++) { Cache.Stream.Position = Cache.Entries[Index].Offset + rawCache.Values[i].Offset1; int address = br.ReadInt32(); if (!(address == -1 || Globals.IsExternalResource(address))) { Cache.Stream.Seek(-4, SeekOrigin.Current); bw.Write(ResourceCache.Offset + ResourceCache.Tags[ResourceCacheIndex].Offset + tag.ResourceInformation[ResourceIndex].Address); Cache.Stream.Position = Cache.Entries[Index].Offset + rawCache.Values[i].Offset0; bw.Write(tag.ResourceInformation[ResourceIndex].Length); ResourceIndex++; } } } #endregion } #endregion #region STAGE FOUR - Save Caches project.CacheCreationDate = DateTime.Now; SoundCache.Save(Path.Combine(project.BinDirectory, "SOUND_RAW_CACHE.BIN"), project.CacheCreationDate); ModelCache.Save(Path.Combine(project.BinDirectory, "MODEL_RAW_CACHE.BIN"), project.CacheCreationDate); SbspCache.Save(Path.Combine(project.BinDirectory, "STRUCTURE_RAW_CACHE.BIN"), project.CacheCreationDate); LtmpCache.Save(Path.Combine(project.BinDirectory, "LIGHTMAP_RAW_CACHE.BIN"), project.CacheCreationDate); DECRCache.Save(Path.Combine(project.BinDirectory, "DECORATER_RAW_CACHE.BIN"), project.CacheCreationDate); WeatherCache.Save(Path.Combine(project.BinDirectory, "WEATHER_RAW_CACHE.BIN"), project.CacheCreationDate); AnimationCache.Save(Path.Combine(project.BinDirectory, "ANIMATION_RAW_CACHE.BIN"), project.CacheCreationDate); BitmapCache.Save(Path.Combine(project.BinDirectory, "TEXTURE_RAW_CACHE.BIN"), project.CacheCreationDate); StringIDsCache.Save(Path.Combine(project.BinDirectory, "STRINGS_CACHE.BIN"), project.CacheCreationDate); IndexCache.Save(Path.Combine(project.BinDirectory, "INDEX.BIN"), project.CacheCreationDate); TagnameCache.Save(Path.Combine(project.BinDirectory, "TAGNAMES.BIN"), project.CacheCreationDate); EnglishUnicodeCache.Save(Path.Combine(project.BinDirectory, "ENGLISH_UNICODE.BIN"), project.CacheCreationDate); MetaCache.Save(Path.Combine(project.BinDirectory, "META.BIN"), project.CacheCreationDate); SbspLtmpMetaCache.Save(Path.Combine(project.BinDirectory, "STRUCTURE_LIGHTMAP_META.BIN"), project.CacheCreationDate); using (FileStream file = new FileStream(Path.Combine(project.BinDirectory, "HEADER.BIN"), FileMode.Create, FileAccess.Write, FileShare.ReadWrite | FileShare.Delete)) { byte[] buffer = Header.ToByteArray(); file.Write(buffer, 0, buffer.Length); } File.SetLastWriteTime(Path.Combine(project.BinDirectory, "HEADER.BIN"), project.CacheCreationDate); project.Save(); #endregion }