public override void ConvertProject(ProjectFile pf) { GMList <GMPath> dataAssets = pf.DataHandle.GetChunk <GMChunkPATH>().List; dataAssets.Clear(); for (int i = 0; i < pf.Paths.Count; i++) { AssetPath assetPath = pf.Paths[i].Asset; if (assetPath == null) { // This asset was never converted dataAssets.Add((GMPath)pf.Paths[i].DataAsset); continue; } dataAssets.Add(new GMPath() { Name = pf.DataHandle.DefineString(assetPath.Name), Smooth = assetPath.Smooth, Closed = assetPath.Closed, Precision = assetPath.Precision, Points = new GMList <GMPath.Point>() }); GMPath gmPath = dataAssets[dataAssets.Count - 1]; foreach (AssetPath.Point point in assetPath.Points) { gmPath.Points.Add(new GMPath.Point() { X = point.X, Y = point.Y, Speed = point.Speed }); } } }
private static void ConvertPaths(ProjectFile pf) { GMList <GMPath> dataAssets = ((GMChunkPATH)pf.DataHandle.Chunks["PATH"]).List; dataAssets.Clear(); for (int i = 0; i < pf.Paths.Count; i++) { AssetPath assetPath = pf.Paths[i]; dataAssets.Add(new GMPath() { Name = pf.DataHandle.DefineString(assetPath.Name), Smooth = assetPath.Smooth, Closed = assetPath.Closed, Precision = assetPath.Precision, Points = new GMList <GMPath.Point>() }); GMPath gmPath = dataAssets[dataAssets.Count - 1]; foreach (AssetPath.Point point in assetPath.Points) { gmPath.Points.Add(new GMPath.Point() { X = point.X, Y = point.Y, Speed = point.Speed }); } } }
/// <summary> /// Reads all data files from GM file reader stream. /// </summary> public static GMList <GMDataFile> ReadDataFiles(GMFileReader reader) { // Create a new list of data files. GMList <GMDataFile> dataFiles = new GMList <GMDataFile>(); // Amount of data file ids. int num = reader.ReadGMInt(); // Iterate through data files. for (int i = 0; i < num; i++) { // If the data file at index does not exists, continue. if (reader.ReadGMBool() == false) { dataFiles.LastId++; continue; } // Create a new data file object. GMDataFile dataFile = new GMDataFile(); // Set data file id. dataFile.Id = i; // Read data file data. dataFile.Name = reader.ReadGMString(); // Get version. int version = reader.ReadGMInt(); // Check version. if (version != 440) { throw new Exception("Unsupported Data File object version."); } // Read data file data. dataFile.FileName = reader.ReadGMString(); // If data file exists, read it in. if (reader.ReadGMBool()) { dataFile.Data = reader.ReadGMBytes(reader.ReadGMInt()); } // Read data file data. dataFile.ExportMode = (ExportType)(reader.ReadGMInt()); dataFile.OverwriteFile = reader.ReadGMBool(); dataFile.FreeDataMemory = reader.ReadGMBool(); dataFile.RemoveAtGameEnd = reader.ReadGMBool(); // Add data file. dataFiles.Add(dataFile); } // Return data files. return(dataFiles); }
public override void Unserialize(GMDataReader reader) { base.Unserialize(reader); FunctionEntries = new GMList <GMFunctionEntry>(); Locals = new GMList <GMLocalsEntry>(); if (reader.VersionInfo.FormatID <= 14) { int startOff = reader.Offset; while (reader.Offset + 12 <= startOff + Length) { GMFunctionEntry entry = new GMFunctionEntry(); entry.Unserialize(reader); FunctionEntries.Add(entry); } } else { FunctionEntries.Unserialize(reader); Locals.Unserialize(reader); } }
/// <summary> /// Reads shaders from Game Maker Studio project file /// </summary> /// <param name="directory">The directory the shaders are placed</param> /// <param name="assets">Collection of project assets</param> public static GMList <GMShader> ReadShadersGMX(string directory, ref List <string> assets) { // A list of shader GMList <GMShader> shaders = new GMList <GMShader>(); shaders.AutoIncrementIds = false; // Iterate through .gmx files in the directory foreach (string file in Directory.GetFiles(directory, "*.shader")) { // Set name of the shader string name = GetResourceName(file); // If the file is not in the asset list, it has been orphaned, continue if (!assets.Contains(name)) { continue; } // Create a stream to the shader file using (StreamReader streamReader = new StreamReader(file)) { // Create a new shader GMShader shader = new GMShader(); shader.Name = name; shader.Id = GetIdFromName(name); shader.Code = streamReader.ReadToEnd(); shader.Type = name; // Add the shader shaders.Add(shader); } } // Return the list of shaders return(shaders); }
/// <summary> /// Reads all the libraries in a GM file reader stream. /// </summary> public static GMList <GMLibrary> ReadLibraries(GMFileReader reader) { // Create a new list of libraries. GMList <GMLibrary> libraries = new GMList <GMLibrary>(); // Get number of libraries. int num = reader.ReadGMInt(); // Read libraries. for (int j = 0; j < num; j++) { // Create a new library. GMLibrary library = new GMLibrary(); // Read the library code. library.Code = reader.ReadGMString(); // Add the library. libraries.Add(library); } // Return libraries. return(libraries); }
/// <summary> /// Reads objects from GM file /// </summary> private GMList<GMObject> ReadObjects() { // Get version. int version = ReadInt(); // Check version. if (version != 400 && version != 800) throw new Exception("Unsupported Pre-Object object version."); // The number of objects. GMList<GMObject> objects = new GMList<GMObject>(); // Amount of object ids. int num = ReadInt(); // Iterate through objects for (int i = 0; i < num; i++) { // If version is 8.0, start inflate. if (version == 800) Decompress(); // If the object at index does not exists, continue. if (ReadBool() == false) { objects.LastId++; EndDecompress(); continue; } // Create a new script object. GMObject obj = new GMObject(); // Set script id. obj.Id = i; // Read script data. obj.Name = ReadString(); // If version is 8.0, get last changed. if (version == 800) obj.LastChanged = ReadDouble(); // Get version. int version2 = ReadInt(); // Check version. if (version2 != 430) throw new Exception("Unsupported Object object version."); // Read object data. obj.SpriteId = ReadInt(); obj.Solid = ReadBool(); obj.Visible = ReadBool(); obj.Depth = ReadInt(); obj.Persistent = ReadBool(); obj.Parent = ReadInt(); obj.Mask = ReadInt(); // Skip data. ReadBytes(4); // The amount of main event types. int amount = 11; // If version 8.0, there are 12 main event types. if (version == 800) amount = 12; // Iterate through events. for (int j = 0; j < amount; j++) { // Not done processing. bool done = false; // While not done processing events. while (!done) { // Check for event int eventNum = ReadInt(); // If the event exists if (eventNum != -1) { // Create new event. GMEvent ev = new GMEvent(); // Set type of event. ev.MainType = (EventType)(j); // If a collision type of event set other object id. if (ev.MainType == EventType.Collision) ev.OtherId = eventNum; else ev.SubType = eventNum; // Read event actions. ev.Actions = ReadActions(); // Add new event. obj.Events[j].Add(ev); } else done = true; } } // End object inflate. EndDecompress(); // Add object to list. objects.Add(obj); } // Return objects. return objects; }
/// <summary> /// Reads all GMX paths from a directory /// </summary> /// <param name="file">The XML (.GMX) file path</param> /// <returns>A list of paths</returns> public static GMList <GMPath> ReadPathsGMX(string directory, ref List <string> assets) { // A list of paths GMList <GMPath> paths = new GMList <GMPath>(); paths.AutoIncrementIds = false; // Iterate through .gmx files in the directory foreach (string file in Directory.GetFiles(directory, "*.gmx")) { // Set name of the path string name = GetResourceName(file); // If the file is not in the asset list, it has been orphaned, continue if (!assets.Contains(name)) { continue; } // Create a dictionary of path properties Dictionary <string, string> properties = new Dictionary <string, string>(); foreach (GMXPathProperty property in Enum.GetValues(typeof(GMXPathProperty))) { properties.Add(GMXEnumString(property), ""); } // Local variables List <GMPoint> points = new List <GMPoint>(); // Create an xml reader using (XmlReader reader = XmlReader.Create(file)) { // Seek to content reader.MoveToContent(); // Read the GMX file while (reader.Read()) { // If the node is not an element, continue if (reader.NodeType != XmlNodeType.Element) { continue; } // Get the element name string nodeName = reader.Name; // Read element reader.Read(); // If the element value is null or empty, continue if (String.IsNullOrEmpty(reader.Value)) { continue; } // If the element is a point element, else normal property if (nodeName.ToLower() == GMXEnumString(GMXPathProperty.Point).ToLower()) { // Get the point data and add it to the points list GMPoint point = new GMPoint(); string[] data = reader.Value.Split(','); point.X = GMXDouble(data[0], point.X); point.Y = GMXDouble(data[1], point.Y); point.Speed = GMXDouble(data[2], point.Speed); points.Add(point); } else { // Set the property value properties[nodeName] = reader.Value; } } } // Create a new path, set properties GMPath path = new GMPath(); path.Id = GetIdFromName(name); path.Name = name; path.Smooth = GMXBool(properties[GMXEnumString(GMXPathProperty.Kind)], path.Smooth); path.Closed = GMXBool(properties[GMXEnumString(GMXPathProperty.Closed)], path.Closed); path.Precision = GMXInt(properties[GMXEnumString(GMXPathProperty.Precision)], path.Precision); path.RoomName = GMXString(properties[GMXEnumString(GMXPathProperty.Backroom)], path.RoomName); path.RoomId = path.RoomName == "" ? -1 : GetIdFromName(path.RoomName); path.SnapX = GMXInt(properties[GMXEnumString(GMXPathProperty.HSnap)], path.SnapX); path.SnapY = GMXInt(properties[GMXEnumString(GMXPathProperty.VSnap)], path.SnapY); path.Points = points.ToArray(); // Add the path paths.Add(path); } // Return the list of paths return(paths); }
/// <summary> /// Reads objects from GM file /// </summary> public static GMList <GMObject> ReadObjects(GMFileReader reader) { // Get version int version = reader.ReadGMInt(); // Check version if (version != 400 && version != 800) { throw new Exception("Unsupported Pre-Object object version."); } // The number of objects GMList <GMObject> objects = new GMList <GMObject>(); // Amount of object ids int num = reader.ReadGMInt(); // Iterate through objects for (int i = 0; i < num; i++) { // If version is 8.0, start inflate if (version == 800) { reader.Decompress(); } // If the object at index does not exists, continue if (reader.ReadGMBool() == false) { objects.LastId++; reader.EndDecompress(); continue; } // Create a new script object GMObject obj = new GMObject(); // Set script id obj.Id = i; // Read script data. obj.Name = reader.ReadGMString(); // If version is 8.0, get last changed if (version == 800) { obj.LastChanged = reader.ReadGMDouble(); } // Get version int version2 = reader.ReadGMInt(); // Check version if (version2 != 430) { throw new Exception("Unsupported Object object version."); } // Read object data obj.SpriteId = reader.ReadGMInt(); obj.Solid = reader.ReadGMBool(); obj.Visible = reader.ReadGMBool(); obj.Depth = reader.ReadGMInt(); obj.Persistent = reader.ReadGMBool(); obj.Parent = reader.ReadGMInt(); obj.Mask = reader.ReadGMInt(); // Skip data reader.ReadGMBytes(4); // The amount of main event types int amount = 11; // If version 8.0, there are 12 main event types if (version == 800) { amount = 12; } // Iterate through events for (int j = 0; j < amount; j++) { // Not done processing bool done = false; // While not done processing events while (!done) { // Check for event int eventNum = reader.ReadGMInt(); // If the event exists if (eventNum != -1) { // Create new event GMEvent ev = new GMEvent(); // Set type of event ev.MainType = j; // If a collision type of event set other object id if (ev.MainType == (int)EventType.Collision) { ev.OtherId = eventNum; } else { ev.SubType = eventNum; } // Read event actions ev.Actions = GMAction.ReadActions(reader); // Add new event obj.Events[j].Add(ev); } else { done = true; } } } // End object inflate reader.EndDecompress(); // Add object to list objects.Add(obj); } // Return objects return(objects); }
/// <summary> /// Reads fonts from GM file. /// </summary> private GMList<GMFont> ReadFonts(int version) { // Create a new list of fonts. GMList<GMFont> fonts = new GMList<GMFont>(); // Amount of font ids. int num = ReadInt(); // Iterate through fonts. for (int i = 0; i < num; i++) { // If version is 8.0, start inflate. if (version == 800) Decompress(); // If the font at index does not exists, continue. if (ReadBool() == false) { fonts.LastId++; EndDecompress(); continue; } // Create a new font object. GMFont font = new GMFont(); // Set font id. font.Id = i; // Read font data. font.Name = ReadString(); // If version is 8.0, get last changed. if (version == 800) font.LastChanged = ReadDouble(); // Get version. version = ReadInt(); // Check version. if (version != 540 && version != 800) throw new Exception("Unsupported Font object version."); // Read font data. font.FontName = ReadString(); font.Size = ReadInt(); font.Bold = ReadBool(); font.Italic = ReadBool(); font.CharacterRangeMin = ReadInt(); font.CharacterRangeMax = ReadInt(); // End object inflate. EndDecompress(); // Add font. fonts.Add(font); } // Return fonts. return fonts; }
/// <summary> /// Gets data files from project file /// </summary> /// <param name="path">File path to project file</param> public static GMList <GMDataFile> ReadDataFilesGMX(string path, out int lastDataFileId) { // Create a new list of data files GMList <GMDataFile> dataFiles = new GMList <GMDataFile>(); dataFiles.AutoIncrementIds = false; // Create a dictionary of data file properties Dictionary <string, string> properties = new Dictionary <string, string>(); foreach (GMXDataFileProperty property in Enum.GetValues(typeof(GMXDataFileProperty))) { properties.Add(GMXEnumString(property), ""); } // Group this data file belongs to, needed because files can have duplicate names string group = ""; lastDataFileId = -1; // List of configs List <GMConfig> configs = new List <GMConfig>(); // Create an xml reader using (XmlReader reader = XmlReader.Create(path)) { reader.MoveToContent(); // Read the GMX file while (reader.Read()) { // If the node is not an element, continue if (reader.NodeType != XmlNodeType.Element) { continue; } // Get the element name string nodeName = reader.Name; // If a datafiles parent or group if (nodeName.ToLower() == GMXEnumString(GMResourceType.DataFiles)) { // If the last data file id has not been set, do so now if (lastDataFileId == -1) { int.TryParse(reader.GetAttribute("number"), out lastDataFileId); } // Set the group the datafile belongs to group = reader.GetAttribute("name"); } // If the node is a data file, read it in if (nodeName.ToLower() == GMXEnumString(GMResourceSubType.DataFile)) { // Seek to content reader.MoveToContent(); // Create an xml reader using (XmlReader reader2 = reader.ReadSubtree()) { // Read in data file properties while (reader2.Read()) { // If the node is not an element, continue if (reader2.NodeType != XmlNodeType.Element) { continue; } // Get the element name string nodeName2 = reader2.Name; // If the node is a data file, read it in if (nodeName2.ToLower() == GMXEnumString(GMResourceType.ConfigOptions).ToLower()) { reader2.MoveToContent(); // Create an xml reader using (XmlReader reader3 = reader2.ReadSubtree()) { // Read in data file properties while (reader3.Read()) { // If the node is not an element, continue if (reader3.NodeType != XmlNodeType.Element) { continue; } // Get the element name string nodeName3 = reader3.Name; // If the node is a data file, read it in if (nodeName3.ToLower() == GMXEnumString(GMResourceSubType.Config).ToLower()) { GMConfig config = new GMConfig(); config.Name = GMXString(reader3.GetAttribute(GMXEnumString(GMXConfigProperty.Name)), config.Name); config.Id = GetIdFromName(config.Name); reader3.MoveToContent(); // Create an xml reader using (XmlReader reader4 = reader3.ReadSubtree()) { // Read in data file properties while (reader4.Read()) { // If the node is not an element, continue if (reader4.NodeType != XmlNodeType.Element) { continue; } // Get the element name string nodeName4 = reader4.Name; // If the node is a data file, read it in if (nodeName4.ToLower() == GMXEnumString(GMXConfigProperty.CopyToMask).ToLower()) { // Read element reader4.Read(); // If the element value is null or empty, continue if (String.IsNullOrEmpty(reader4.Value)) { continue; } // Finally read the config file data config.CopyToMask = GMXString(reader4.Value, config.CopyToMask); configs.Add(config); } } } } } } } // Read element reader2.Read(); // If the element value is null or empty, continue if (String.IsNullOrEmpty(reader2.Value)) { continue; } // Set the property value properties[nodeName2] = reader2.Value; } // Create a new data file GMDataFile dataFile = new GMDataFile(); dataFile.Name = GMXString(properties[GMXEnumString(GMXDataFileProperty.Name)], dataFile.Name); dataFile.Id = GetIdFromName(dataFile.Name); dataFile.Exists = GMXBool(properties[GMXEnumString(GMXDataFileProperty.Exists)], dataFile.Exists); dataFile.Size = GMXInt(properties[GMXEnumString(GMXDataFileProperty.Size)], dataFile.Size); dataFile.ExportAction = GMXInt(properties[GMXEnumString(GMXDataFileProperty.ExportAction)], dataFile.ExportAction); dataFile.ExportDirectory = GMXString(properties[GMXEnumString(GMXDataFileProperty.ExportDir)], dataFile.ExportDirectory); dataFile.OverwriteFile = GMXBool(properties[GMXEnumString(GMXDataFileProperty.Overwrite)], dataFile.OverwriteFile); dataFile.FreeDataMemory = GMXBool(properties[GMXEnumString(GMXDataFileProperty.FreeData)], dataFile.FreeDataMemory); dataFile.RemoveAtGameEnd = GMXBool(properties[GMXEnumString(GMXDataFileProperty.RemoveEnd)], dataFile.RemoveAtGameEnd); dataFile.Store = GMXBool(properties[GMXEnumString(GMXDataFileProperty.Store)], dataFile.Store); dataFile.FileName = GMXString(properties[GMXEnumString(GMXDataFileProperty.Filename)], dataFile.FileName); dataFile.Group = group == "" ? EnumString.GetEnumString(GMResourceType.DataFiles) : group; dataFile.Configs = configs.ToArray(); configs.Clear(); group = ""; // Add data file to the list dataFiles.Add(dataFile); } } } } // Return the list of data files return(dataFiles); }
/// <summary> /// Reads all backgrounds from a background XML file /// </summary> /// <param name="directory">The XML (.GMX) file path</param> /// <param name="assets">A list of assets listed in the project GMX</param> /// <returns>A GM background</returns> public static GMList <GMBackground> ReadBackgroundsGMX(string directory, ref List <string> assets) { // A list of backgrounds GMList <GMBackground> backgrounds = new GMList <GMBackground>(); backgrounds.AutoIncrementIds = false; // Iterate through .gmx files in the directory foreach (string file in Directory.GetFiles(directory, "*.gmx")) { // Set name of the background string name = GetResourceName(file); // If the file is not in the asset list, it has been orphaned, continue if (!assets.Contains(name)) { continue; } // Create a dictionary of room properties Dictionary <string, string> properties = new Dictionary <string, string>(); foreach (GMXBackgroundProperty property in Enum.GetValues(typeof(GMXBackgroundProperty))) { properties.Add(GMXEnumString(property), ""); } // Background image and texture group strings GMImage image = null; string textureGroup = GMXEnumString(GMXBackgroundProperty.TextureGroup); string textureGroup0 = GMXEnumString(GMXBackgroundProperty.TextureGroup0); // Create an XMLReader to read in the resource elements using (XmlReader reader = XmlReader.Create(file)) { // Move to a content node reader.MoveToContent(); // Read XML file while (reader.Read()) { // If the node is not an element, continue if (reader.NodeType != XmlNodeType.Element) { continue; } // Get the element name string nodeName = reader.Name; // Read reader.Read(); // If the element value is null or empty, continue if (string.IsNullOrEmpty(reader.Value)) { continue; } // If the element is a frame element create subimage, else normal property if (nodeName.ToLower() == GMXEnumString(GMXBackgroundProperty.Data)) { // Create an image and set the image path image = new GMImage(); image.Compressed = false; image.FilePath = reader.Value; image.Data = GMUtilities.LoadBytesFromBitmap(directory + "\\" + image.FilePath); } else { // Set the property value properties[nodeName] = reader.Value; } } } // Create a new background and set its properties GMBackground background = new GMBackground(); background.Id = GetIdFromName(name); background.Name = name; background.UseAsTileSet = GMXBool(properties[GMXEnumString(GMXBackgroundProperty.IsTileset)], background.UseAsTileSet); background.TileWidth = GMXInt(properties[GMXEnumString(GMXBackgroundProperty.TileWidth)], background.TileWidth); background.TileHeight = GMXInt(properties[GMXEnumString(GMXBackgroundProperty.TileHeight)], background.TileHeight); background.HorizontalOffset = GMXInt(properties[GMXEnumString(GMXBackgroundProperty.TileXOff)], background.HorizontalOffset); background.VerticalOffset = GMXInt(properties[GMXEnumString(GMXBackgroundProperty.TileYOff)], background.VerticalOffset); background.HorizontalSeperation = GMXInt(properties[GMXEnumString(GMXBackgroundProperty.TileHSep)], background.HorizontalSeperation); background.VerticalSeperation = GMXInt(properties[GMXEnumString(GMXBackgroundProperty.TileVSep)], background.VerticalSeperation); background.TileHorizontally = GMXBool(properties[GMXEnumString(GMXBackgroundProperty.HTile)], background.TileHorizontally); background.TileVertically = GMXBool(properties[GMXEnumString(GMXBackgroundProperty.VTile)], background.TileVertically); background.UsedFor3D = GMXBool(properties[GMXEnumString(GMXBackgroundProperty.For3D)], background.UsedFor3D); background.Width = GMXInt(properties[GMXEnumString(GMXBackgroundProperty.Width)], background.Width); background.Height = GMXInt(properties[GMXEnumString(GMXBackgroundProperty.Height)], background.Height); properties[textureGroup] = properties[textureGroup] == "" ? "0" : properties[textureGroup]; properties[textureGroup0] = properties[textureGroup0] == "" ? "0" : properties[textureGroup0]; image.Width = background.Width; image.Height = background.Height; background.Image = image; // The texture group does not equal zero set texture group 0 to the texture group value if (properties[textureGroup] != "0") { properties[textureGroup0] = properties[textureGroup]; } // The texture group zero does not equal zero set texture group to the texture group 0 value else if (properties[textureGroup0] != "0") { properties[textureGroup] = properties[textureGroup0]; } // Create a list of texture groups List <int> textureGroups = new List <int>(); for (int i = 0; properties.ContainsKey(string.Concat(textureGroup, i)); i++) { textureGroups.Add(Convert.ToInt32(properties[string.Concat(textureGroup, i)])); } background.TextureGroups = textureGroups.ToArray(); // Add the background backgrounds.Add(background); } // Return the list of backgrounds return(backgrounds); }
/// <summary> /// Reads all paths from a GM file reader stream. /// </summary> public static GMList <GMPath> ReadPaths(GMFileReader reader) { // Get version. int version = reader.ReadGMInt(); // Check version. if (version != 420 && version != 800) { throw new Exception("Unsupported Pre-Path object version."); } // Create a new list of paths. GMList <GMPath> paths = new GMList <GMPath>(); // Amount of path indexes. int num = reader.ReadGMInt(); // Iterate through paths. for (int i = 0; i < num; i++) { // If version is 8.0, start inflate. if (version == 800) { reader.Decompress(); } // If the path at index does not exists, continue. if (reader.ReadGMBool() == false) { paths.LastId++; reader.EndDecompress(); continue; } // Create a new path object. GMPath path = new GMPath(); // Set path id. path.Id = i; // Read path data. path.Name = reader.ReadGMString(); // If version is 8.0, get last changed. if (version == 800) { path.LastChanged = reader.ReadGMDouble(); } // Get version. int version2 = reader.ReadGMInt(); // Check version. if (version2 != 420 && version2 != 530) { throw new Exception("Unsupported Path object version."); } // Check version. if (version2 > 420) { // Read path data. path.Smooth = reader.ReadGMBool(); path.Closed = reader.ReadGMBool(); path.Precision = reader.ReadGMInt(); path.RoomId = reader.ReadGMInt(); path.SnapX = reader.ReadGMInt(); path.SnapY = reader.ReadGMInt(); } else { // Read path data. path.Smooth = reader.ReadGMBool(); path.ActionAtTheEnd = (ActionAtTheEnd)reader.ReadGMInt(); reader.ReadGMBytes(4); } // Number of path points. path.Points = new GMPoint[reader.ReadGMInt()]; // Iterate through path points. for (int j = 0; j < path.Points.Length; j++) { // Create a new point. GMPoint point = new GMPoint(); // Read point data. point.X = reader.ReadGMDouble(); point.Y = reader.ReadGMDouble(); point.Speed = reader.ReadGMDouble(); // Set point. path.Points[j] = point; } // End object inflate. reader.EndDecompress(); // Add path. paths.Add(path); } // Return paths. return(paths); }
/// <summary> /// Reads all GMX sounds from a directory /// </summary> /// <param name="file">The XML (.GMX) file path</param> /// <returns>A list of sounds</returns> public static GMList <GMSound> ReadSoundsGMX(string directory, ref List <string> assets) { // A list of sounds GMList <GMSound> sounds = new GMList <GMSound>(); sounds.AutoIncrementIds = false; // Iterate through .gmx files in the directory foreach (string file in Directory.GetFiles(directory, "*.gmx")) { // Set name of the sound string name = GetResourceName(file); // If the file is not in the asset list, it has been orphaned, continue if (!assets.Contains(name)) { continue; } // Create a dictionary of sound properties Dictionary <string, string> properties = new Dictionary <string, string>(); foreach (GMXSoundProperty property in Enum.GetValues(typeof(GMXSoundProperty))) { properties.Add(GMXEnumString(property), ""); } // Create an xml reader using (XmlReader reader = XmlReader.Create(file)) { // Seek to content reader.MoveToContent(); // Read the GMX file while (reader.Read()) { // If the node is not an element, continue if (reader.NodeType != XmlNodeType.Element) { continue; } // Get the element name string nodeName = reader.Name; // Read element reader.Read(); // If the element value is null or empty, continue if (String.IsNullOrEmpty(reader.Value)) { continue; } // Set the property value properties[nodeName] = reader.Value; } } // Create a new sound, set properties GMSound sound = new GMSound(); sound.Id = GetIdFromName(name); sound.Name = name; sound.Kind = GMXInt(properties[GMXEnumString(GMXSoundProperty.Kind)], sound.Kind); sound.Extension = GMXString(properties[GMXEnumString(GMXSoundProperty.Extension)], sound.Extension); sound.FilePath = GMXString(properties[GMXEnumString(GMXSoundProperty.Origname)], sound.FilePath); sound.Effects = GMXInt(properties[GMXEnumString(GMXSoundProperty.Effects)], sound.Effects); sound.Volume = GMXDouble(properties[GMXEnumString(GMXSoundProperty.Volume)], sound.Volume); sound.Pan = GMXDouble(properties[GMXEnumString(GMXSoundProperty.Pan)], sound.Pan); sound.OGGQuality = GMXInt(properties[GMXEnumString(GMXSoundProperty.OggQuality)], sound.OGGQuality); sound.Preload = GMXBool(properties[GMXEnumString(GMXSoundProperty.Preload)], sound.Preload); sound.FileName = GMXString(properties[GMXEnumString(GMXSoundProperty.Data)], sound.FileName); sound.SampleRate = GMXInt(properties[GMXEnumString(GMXSoundProperty.SampleRate)], sound.SampleRate); sound.Type = GMXInt(properties[GMXEnumString(GMXSoundProperty.Type)], sound.Type); sound.BitDepth = GMXInt(properties[GMXEnumString(GMXSoundProperty.BitDepth)], sound.BitDepth); sound.Streamed = GMXBool(properties[GMXEnumString(GMXSoundProperty.Streamed)], sound.Streamed); sound.UncompressOnLoad = GMXBool(properties[GMXEnumString(GMXSoundProperty.UncompressOnLoad)], sound.UncompressOnLoad); sound.Compressed = GMXBool(properties[GMXEnumString(GMXSoundProperty.Compressed)], sound.Compressed); // Set bit rate if (properties.ContainsKey(GMXEnumString(GMXSoundProperty.BitRate))) { sound.BitRate = GMXInt(properties[GMXEnumString(GMXSoundProperty.BitRate)], sound.BitRate); } else if (properties.ContainsKey(GMXEnumString(GMXSoundProperty.Mp3BitRate))) { sound.BitRate = GMXInt(properties[GMXEnumString(GMXSoundProperty.Mp3BitRate)], sound.BitRate); } // Add the sound sounds.Add(sound); } // Return the list of sounds return(sounds); }
/// <summary> /// Reads scripts from GM file /// </summary> private GMList<GMScript> ReadScripts() { // Get version. int version = ReadInt(); // Check version. if (version != 400 && version != 800) throw new Exception("Unsupported Pre-Script object version."); // Create a new list of scripts. GMList<GMScript> scripts = new GMList<GMScript>(); // Amount of script ids. int num = ReadInt(); // Iterate through scripts. for (int i = 0; i < num; i++) { // If version is 8.0, start inflate. if (version == 800) Decompress(); // If the script at index does not exists, continue. if (ReadBool() == false) { scripts.LastId++; EndDecompress(); continue; } // Create a new script object. GMScript script = new GMScript(); // Set script id. script.Id = i; // Read script data. script.Name = ReadString(); // If version is 8.0, get last changed. if (version == 800) script.LastChanged = ReadDouble(); // Get version. version = ReadInt(); // Check version. if (version != 400 && version != 800) throw new Exception("Unsupported Script object version."); // Read script data. script.Code = ReadString(); // End object inflate. EndDecompress(); // Add script. scripts.Add(script); } // Return scripts. return scripts; }
/// <summary> /// Reads all sounds from Game Maker project file. /// </summary> private GMList<GMSound> ReadSounds() { // Get version. int version = ReadInt(); // Check version. if (version != 400 && version != 800) throw new Exception("Unsupported Pre-Sound object version."); // Create a new sound list. GMList<GMSound> sounds = new GMList<GMSound>(); // Amount of sound ids. int num = ReadInt(); // Iterate through sounds. for (int i = 0; i < num; i++) { // If version is 8.0, start inflate. if (version == 800) Decompress(); // If the sound at index does not exists, continue. if (ReadBool() == false) { sounds.LastId++; EndDecompress(); continue; } // Create sound object. GMSound sound = new GMSound(); // Set sound id. sound.Id = i; // Read sound data. sound.Name = ReadString(); // If version is 8.0, get last changed. if (version == 800) sound.LastChanged = ReadDouble(); // Get version. version = ReadInt(); // Check version. if (version != 440 && version != 600 && version != 800) throw new Exception("Unsupported Sound object version."); // Check version. if (version == 440) sound.Kind = (SoundKind)ReadInt(); else // Read sound data. sound.Type = (SoundType)ReadInt(); // Read sound data. sound.FileType = ReadString(); // Check version. if (version == 440) { // If sound data exists, read it. if ((int)sound.Kind != -1) sound.Data = ReadBytes(ReadInt()); // Read sound data. sound.AllowSoundEffects = ReadBool(); sound.Buffers = ReadInt(); sound.LoadOnlyOnUse = ReadBool(); } else { // Read sound data. sound.FileName = ReadString(); // If sound data exists, read it. if (ReadBool() == true) sound.Data = ReadBytes(ReadInt()); // Read sound data. sound.Effects = ReadInt(); sound.Volume = ReadDouble(); sound.Pan = ReadDouble(); sound.Preload = ReadBool(); } // End object inflate. EndDecompress(); // Add sound. sounds.Add(sound); } // Return sounds. return sounds; }
/// <summary> /// Reads rooms from GM file /// </summary> private GMList<GMRoom> ReadRooms(GMList<GMObject> objects) { // Get version. int version = ReadInt(); // Check version. if (version != 420 && version != 800) throw new Exception("Unsupported Pre-Room object version."); // Create a new list of rooms. GMList<GMRoom> rooms = new GMList<GMRoom>(); // Amount of room indexes. int num = ReadInt(); // Iterate through rooms. for (int i = 0; i < num; i++) { // If version is 8.0, start inflate. if (version == 800) Decompress(); // If the room at index does not exists, continue. if (ReadBool() == false) { rooms.LastId++; EndDecompress(); continue; } // Create a room object. GMRoom room = new GMRoom(); // Set room id. room.Id = i; // Read room data. room.Name = ReadString(); // If version is 8.0, get last changed. if (version == 800) room.LastChanged = ReadDouble(); // Get version. int version2 = ReadInt(); // Check version. if (version2 != 500 && version2 != 520 && version2 != 541) throw new Exception("Unsupported Room object version."); // Read room data. room.Caption = ReadString(); room.Width = ReadInt(); room.Height = ReadInt(); room.SnapY = ReadInt(); room.SnapX = ReadInt(); // Versions greater than 5.1 support isometric grid. if (version2 > 500) room.IsometricGrid = ReadBool(); room.Speed = ReadInt(); room.Persistent = ReadBool(); room.BackgroundColor = ReadInt(); room.DrawBackgroundColor = ReadBool(); room.CreationCode = ReadString(); // Create new parallax array. room.Parallaxes = new GMParallax[ReadInt()]; // Iterate through parallaxs. for (int j = 0; j < room.Parallaxes.Length; j++) { // Create a new parallax object. room.Parallaxes[j] = new GMParallax(); // Read room parallax data. room.Parallaxes[j].Visible = ReadBool(); room.Parallaxes[j].Foreground = ReadBool(); room.Parallaxes[j].BackgroundId = ReadInt(); room.Parallaxes[j].X = ReadInt(); room.Parallaxes[j].Y = ReadInt(); room.Parallaxes[j].TileHorizontally = ReadBool(); room.Parallaxes[j].TileVertically = ReadBool(); room.Parallaxes[j].HorizontalSpeed = ReadInt(); room.Parallaxes[j].VerticalSpeed = ReadInt(); // Versions greater than 5.1 support parallax stretching. if (version2 > 500) room.Parallaxes[j].Stretch = ReadBool(); } // Read room data. room.EnableViews = ReadBool(); // Create new view array. room.Views = new GMView[ReadInt()]; // Iterate through views for (int k = 0; k < room.Views.Length; k++) { // Create new view object. room.Views[k] = new GMView(); // Read room view data. room.Views[k].Visible = ReadBool(); room.Views[k].ViewX = ReadInt(); room.Views[k].ViewY = ReadInt(); room.Views[k].ViewWidth = ReadInt(); room.Views[k].ViewHeight = ReadInt(); room.Views[k].PortX = ReadInt(); room.Views[k].PortY = ReadInt(); // Versions greater than 5.3 support port dimensions. if (version2 > 520) { room.Views[k].PortWidth = ReadInt(); room.Views[k].PortHeight = ReadInt(); } // Read room view data. room.Views[k].HorizontalBorder = ReadInt(); room.Views[k].VerticalBorder = ReadInt(); room.Views[k].HorizontalSpeed = ReadInt(); room.Views[k].VerticalSpeed = ReadInt(); room.Views[k].ObjectToFollow = ReadInt(); } // Create a new array of instances. room.Instances = new GMInstance[ReadInt()]; // Iterate through room instances. for (int l = 0; l < room.Instances.Length; l++) { // Create new instance. room.Instances[l] = new GMInstance(); // Read room instance data. room.Instances[l].X = ReadInt(); room.Instances[l].Y = ReadInt(); room.Instances[l].ObjectId = ReadInt(); room.Instances[l].Id = ReadInt(); // Versions greater than 5.1 support creation code and instance locking. if (version2 > 500) { // Read room instance data. room.Instances[l].CreationCode = ReadString(); room.Instances[l].Locked = ReadBool(); } // Get the object the instance references. GMObject obj = objects.Find(delegate(GMObject o) { return o.Id == room.Instances[l].ObjectId; }); // If the object was found, set instance name and depth. if (obj != null) { // Read room instance data. room.Instances[l].Name = obj.Name; room.Instances[l].Depth = obj.Depth; } // Skipped reserved bytes. if (version2 < 520) ReadBytes(8); } // Create a new array of tiles. room.Tiles = new GMTile[ReadInt()]; // Iterate through room tiles. for (int m = 0; m < room.Tiles.Length; m++) { // Create new tile object. room.Tiles[m] = new GMTile(); // Read room tile data. room.Tiles[m].X = ReadInt(); room.Tiles[m].Y = ReadInt(); room.Tiles[m].BackgroundId = ReadInt(); room.Tiles[m].BackgroundX = ReadInt(); room.Tiles[m].BackgroundY = ReadInt(); room.Tiles[m].Width = ReadInt(); room.Tiles[m].Height = ReadInt(); room.Tiles[m].Depth = ReadInt(); room.Tiles[m].Id = ReadInt(); // Versions greater than 5.1 support tile locking. if (version2 > 500) room.Tiles[m].Locked = ReadBool(); } // Read room data. room.RememberWindowSize = ReadBool(); room.EditorWidth = ReadInt(); room.EditorHeight = ReadInt(); room.ShowGrid = ReadBool(); room.ShowObjects = ReadBool(); room.ShowTiles = ReadBool(); room.ShowBackgrounds = ReadBool(); room.ShowForegrounds = ReadBool(); room.ShowViews = ReadBool(); room.DeleteUnderlyingObjects = ReadBool(); room.DeleteUnderlyingTiles = ReadBool(); // Versions greater than 5.3 don't support tile settings. if (version2 > 520) { // Read room tile data. room.CurrentTab = (TabSetting)(ReadInt()); room.ScrollBarX = ReadInt(); room.ScrollBarY = ReadInt(); } else { // Read room tile data. room.TileWidth = ReadInt(); room.TileHeight = ReadInt(); room.TileHorizontalSeperation = ReadInt(); room.TileVerticalSeperation = ReadInt(); room.TileHorizontalOffset = ReadInt(); room.TileVerticalOffset = ReadInt(); room.CurrentTab = (TabSetting)(ReadInt()); room.ScrollBarX = ReadInt(); room.ScrollBarY = ReadInt(); } // End object inflate. EndDecompress(); // Set room. rooms.Add(room); } // Return rooms return rooms; }
/// <summary> /// Reads paths from GM file. /// </summary> private GMList<GMPath> ReadPaths() { // Get version. int version = ReadInt(); // Check version. if (version != 420 && version !=800) throw new Exception("Unsupported Pre-Path object version."); // Create a new list of paths. GMList<GMPath> paths = new GMList<GMPath>(); // Amount of path indexes. int num = ReadInt(); // Iterate through paths. for (int i = 0; i < num; i++) { // If version is 8.0, start inflate. if (version == 800) Decompress(); // If the path at index does not exists, continue. if (ReadBool() == false) { paths.LastId++; EndDecompress(); continue; } // Create a new path object. GMPath path = new GMPath(); // Set path id. path.Id = i; // Read path data. path.Name = ReadString(); // If version is 8.0, get last changed. if (version == 800) path.LastChanged = ReadDouble(); // Get version. int version2 = ReadInt(); // Check version. if (version2 != 420 && version2 != 530) throw new Exception("Unsupported Path object version."); // Check version. if (version2 > 420) { // Read path data. path.Smooth = ReadBool(); path.Closed = ReadBool(); path.Precision = ReadInt(); path.RoomId = ReadInt(); path.SnapX = ReadInt(); path.SnapY = ReadInt(); } else { // Read path data. path.Smooth = ReadBool(); path.ActionAtTheEnd = (ActionAtTheEnd)ReadInt(); ReadBytes(4); } // Number of path points. path.Points = new GMPoint[ReadInt()]; // Iterate through path points. for (int j = 0; j < path.Points.Length; j++) { // Create a new point. GMPoint point = new GMPoint(); // Read point data. point.X = ReadDouble(); point.Y = ReadDouble(); point.Speed = ReadDouble(); // Set point. path.Points[j] = point; } // End object inflate. EndDecompress(); // Add path. paths.Add(path); } // Return paths. return paths; }
/// <summary> /// Reads all backgrounds from a GM file reader /// </summary> public static GMList <GMBackground> ReadBackgrounds(GMFileReader reader) { // Get version int version = reader.ReadGMInt(); // Check version if (version != 400 && version != 800) { throw new Exception("Unsupported Pre-Background object version."); } // Create a new list of backgrounds GMList <GMBackground> backgrounds = new GMList <GMBackground>(); // Amount of background ids int num = reader.ReadGMInt(); // Iterate through backgrounds for (int i = 0; i < num; i++) { // If version is 8.0, start inflate if (version == 800) { reader.Decompress(); } // If the background at index does not exists, continue if (reader.ReadGMBool() == false) { backgrounds.LastId++; reader.EndDecompress(); continue; } // Create a new background object GMBackground background = new GMBackground(); // Set background id background.Id = i; // Get background data background.Name = reader.ReadGMString(); // If version is 8.0, get last changed if (version == 800) { background.LastChanged = reader.ReadGMDouble(); } // Get version version = reader.ReadGMInt(); // Check version if (version != 400 && version != 543 && version != 710) { throw new Exception("Unsupported Background object version."); } // If version is less than 7.1 if (version < 710) { // Background data background.Width = reader.ReadGMInt(); background.Height = reader.ReadGMInt(); background.Transparent = reader.ReadGMBool(); // Check version if (version > 400) { // Read background data background.SmoothEdges = reader.ReadGMBool(); background.Preload = reader.ReadGMBool(); background.UseAsTileSet = reader.ReadGMBool(); background.TileWidth = reader.ReadGMInt(); background.TileHeight = reader.ReadGMInt(); background.HorizontalOffset = reader.ReadGMInt(); background.VerticalOffset = reader.ReadGMInt(); background.HorizontalSeperation = reader.ReadGMInt(); background.VerticalSeperation = reader.ReadGMInt(); } else { // Read background data background.UseVideoMemory = reader.ReadGMBool(); background.LoadOnlyOnUse = reader.ReadGMBool(); } // If image data exists if (reader.ReadGMBool()) { // If pixel data does not exist if (reader.ReadGMInt() == -1) { continue; } // Create a new image GMImage image = new GMImage(); // Set image data image.Width = background.Width; image.Height = background.Height; // Get size of image data int size = reader.ReadGMInt(); // Get compressed image data image.Data = reader.ReadGMBytes(size); // Set background image background.Image = image; } } else { // Get background data background.UseAsTileSet = reader.ReadGMBool(); background.TileWidth = reader.ReadGMInt(); background.TileHeight = reader.ReadGMInt(); background.HorizontalOffset = reader.ReadGMInt(); background.VerticalOffset = reader.ReadGMInt(); background.HorizontalSeperation = reader.ReadGMInt(); background.VerticalSeperation = reader.ReadGMInt(); // Get version version = reader.ReadGMInt(); // Check version if (version != 800) { throw new Exception("Unsupported Background object version."); } // Get image data background.Width = reader.ReadGMInt(); background.Height = reader.ReadGMInt(); // If the sprite size is not zero if (background.Width != 0 && background.Height != 0) { // Create a new image object GMImage image = new GMImage(); image.Compressed = false; // Set image data image.Width = background.Width; image.Height = background.Height; // Get size of image data int size = reader.ReadGMInt(); // Get image data image.Data = reader.ReadGMBytes(size); // Insert compressed image data background.Image = image; } } // End object inflate reader.EndDecompress(); // Add background backgrounds.Add(background); } // Return backgrounds return(backgrounds); }
private static void ConvertObjects(ProjectFile pf) { GMList <GMObject> dataAssets = ((GMChunkOBJT)pf.DataHandle.Chunks["OBJT"]).List; GMList <GMSprite> dataSprites = ((GMChunkSPRT)pf.DataHandle.Chunks["SPRT"]).List; GMList <GMCode> dataCode = ((GMChunkCODE)pf.DataHandle.Chunks["CODE"]).List; int getSprite(string name) { if (name == null) { return(-1); } try { return(dataSprites.Select((elem, index) => new { elem, index }).First(p => p.elem.Name.Content == name).index); } catch (InvalidOperationException) { return(-1); } } int getCode(string name) { try { return(dataCode.Select((elem, index) => new { elem, index }).First(p => p.elem.Name.Content == name).index); } catch (InvalidOperationException) { return(-1); } } int getObject(string name) { if (name == null) { return(-1); } if (name == "<undefined>") { return(-100); } try { return(dataAssets.Select((elem, index) => new { elem, index }).First(p => p.elem.Name.Content == name).index); } catch (InvalidOperationException) { return(-1); } } List <GMObject> newList = new List <GMObject>(); for (int i = 0; i < pf.Objects.Count; i++) { AssetObject projectAsset = pf.Objects[i]; GMObject dataAsset = new GMObject() { Name = pf.DataHandle.DefineString(projectAsset.Name), SpriteID = getSprite(projectAsset.Sprite), Visible = projectAsset.Visible, Solid = projectAsset.Solid, Depth = projectAsset.Depth, Persistent = projectAsset.Persistent, ParentObjectID = getObject(projectAsset.ParentObject), MaskSpriteID = getSprite(projectAsset.MaskSprite), Physics = projectAsset.Physics, PhysicsSensor = projectAsset.PhysicsSensor, PhysicsShape = projectAsset.PhysicsShape, PhysicsDensity = projectAsset.PhysicsDensity, PhysicsRestitution = projectAsset.PhysicsRestitution, PhysicsGroup = projectAsset.PhysicsGroup, PhysicsLinearDamping = projectAsset.PhysicsLinearDamping, PhysicsAngularDamping = projectAsset.PhysicsAngularDamping, PhysicsVertices = new List <GMObject.PhysicsVertex>(), PhysicsFriction = projectAsset.PhysicsFriction, PhysicsAwake = projectAsset.PhysicsAwake, PhysicsKinematic = projectAsset.PhysicsKinematic, Events = new GMPointerList <GMPointerList <GMObject.Event> >() }; foreach (AssetObject.PhysicsVertex v in projectAsset.PhysicsVertices) { dataAsset.PhysicsVertices.Add(new GMObject.PhysicsVertex() { X = v.X, Y = v.Y }); } foreach (var events in projectAsset.Events.Values) { var newEvents = new GMPointerList <GMObject.Event>(); foreach (var ev in events) { GMObject.Event newEv = new GMObject.Event() { Subtype = 0, Actions = new GMPointerList <GMObject.Event.Action>() { new GMObject.Event.Action() { LibID = 1, ID = ev.Actions[0].ID, Kind = 7, UseRelative = false, IsQuestion = false, UseApplyTo = ev.Actions[0].UseApplyTo, ExeType = 2, ActionName = ev.Actions[0].ActionName != null?pf.DataHandle.DefineString(ev.Actions[0].ActionName) : null, CodeID = getCode(ev.Actions[0].Code), ArgumentCount = ev.Actions[0].ArgumentCount, Who = -1, Relative = false, IsNot = false } } }; // Handle subtype switch (ev) { case AssetObject.EventAlarm e: newEv.Subtype = e.AlarmNumber; break; case AssetObject.EventStep e: newEv.Subtype = (int)e.SubtypeStep; break; case AssetObject.EventCollision e: newEv.Subtype = getObject(e.ObjectName); break; case AssetObject.EventKeyboard e: newEv.Subtype = (int)e.SubtypeKey; break; case AssetObject.EventMouse e: newEv.Subtype = (int)e.SubtypeMouse; break; case AssetObject.EventOther e: newEv.Subtype = (int)e.SubtypeOther; break; case AssetObject.EventDraw e: newEv.Subtype = (int)e.SubtypeDraw; break; case AssetObject.EventGesture e: newEv.Subtype = (int)e.SubtypeGesture; break; } newEvents.Add(newEv); } dataAsset.Events.Add(newEvents); } newList.Add(dataAsset); } dataAssets.Clear(); foreach (var obj in newList) { dataAssets.Add(obj); } }
/// <summary> /// Reads sprites from Game Maker project file. /// </summary> public static GMList <GMSprite> ReadSprites(GMFileReader reader) { // Get version int version = reader.ReadGMInt(); // Check version if (version != 400 && version != 800) { throw new Exception("Unsupported Pre-Sprite object version."); } // Create a new list of sprites GMList <GMSprite> sprites = new GMList <GMSprite>(); // Amount of sprite ids int num = reader.ReadGMInt(); // Iterate through sprites for (int i = 0; i < num; i++) { // If version is 8.0, start inflate if (version == 800) { reader.Decompress(); } // If the sprite at index does not exists, continue if (reader.ReadGMBool() == false) { sprites.LastId++; reader.EndDecompress(); continue; } // Create a new sprite object GMSprite sprite = new GMSprite(); // Set sprite id sprite.Id = i; // Read sprite data sprite.Name = reader.ReadGMString(); // If version is 8.0, get last changed if (version == 800) { sprite.LastChanged = reader.ReadGMDouble(); } // Get version version = reader.ReadGMInt(); // Check version if (version != 400 && version != 542 && version != 800) { throw new Exception("Unsupported Sprite object version."); } // If less than version 8.0 if (version < 800) { // Read sprite data sprite.Width = reader.ReadGMInt(); sprite.Height = reader.ReadGMInt(); sprite.BoundingBoxLeft = reader.ReadGMInt(); sprite.BoundingBoxRight = reader.ReadGMInt(); sprite.BoundingBoxBottom = reader.ReadGMInt(); sprite.BoundingBoxTop = reader.ReadGMInt(); sprite.Transparent = reader.ReadGMBool(); // Check version if (version > 400) { // Read sprite data sprite.SmoothEdges = reader.ReadGMBool(); sprite.Preload = reader.ReadGMBool(); } // Read sprite data sprite.BoundingBoxMode = reader.ReadGMInt(); sprite.Precise = reader.ReadGMBool(); // Check version if (version == 400) { // Read sprtie data sprite.UseVideoMemory = reader.ReadGMBool(); sprite.LoadOnlyOnUse = reader.ReadGMBool(); } // Read sprite data sprite.OriginX = reader.ReadGMInt(); sprite.OriginY = reader.ReadGMInt(); // Sprite number of sub images sprite.SubImages = new GMImage[reader.ReadGMInt()]; // Iterate through sub-images for (int j = 0; j < sprite.SubImages.Length; j++) { // If the sub-image at index does not exists, continue if (reader.ReadGMInt() == -1) { continue; } // Create a new image object GMImage image = new GMImage(); // Get size of image data int size = reader.ReadGMInt(); // Get image data image.Data = reader.ReadGMBytes(size); // Insert compressed image data sprite.SubImages[j] = image; } } else { // Read sprite data sprite.OriginX = reader.ReadGMInt(); sprite.OriginY = reader.ReadGMInt(); // Sprite number of sub images sprite.SubImages = new GMImage[reader.ReadGMInt()]; // Iterate through sub-images for (int j = 0; j < sprite.SubImages.Length; j++) { // Get version. version = reader.ReadGMInt(); // Check version if (version != 800) { throw new Exception("Unsupported Sprite object version."); } // Get width and height of image int width = reader.ReadGMInt(); int height = reader.ReadGMInt(); // If the sprite size is not zero if (width != 0 && height != 0) { // Create a new image object GMImage image = new GMImage(); image.Compressed = false; // Set image data image.Width = width; image.Height = height; // Get size of image data int size = reader.ReadGMInt(); // Get image data image.Data = reader.ReadGMBytes(size); // Insert compressed image data sprite.SubImages[j] = image; } } // Read sprite data sprite.ShapeMode = reader.ReadGMInt(); sprite.AlphaTolerance = reader.ReadGMInt(); sprite.UseSeperateCollisionMasks = reader.ReadGMBool(); sprite.BoundingBoxMode = reader.ReadGMInt(); sprite.BoundingBoxLeft = reader.ReadGMInt(); sprite.BoundingBoxRight = reader.ReadGMInt(); sprite.BoundingBoxBottom = reader.ReadGMInt(); sprite.BoundingBoxTop = reader.ReadGMInt(); } // End object inflate reader.EndDecompress(); // Add sprite sprites.Add(sprite); } // Return sprites return(sprites); }
/// <summary> /// Reads all fonts from a GM file reader stream. /// </summary> public static GMList <GMFont> ReadFonts(int version, GMFileReader reader) { // Create a new list of fonts. GMList <GMFont> fonts = new GMList <GMFont>(); // Amount of font ids. int num = reader.ReadGMInt(); // Iterate through fonts. for (int i = 0; i < num; i++) { // If version is 8.0, start inflate. if (version == 800) { reader.Decompress(); } // If the font at index does not exists, continue. if (reader.ReadGMBool() == false) { fonts.LastId++; reader.EndDecompress(); continue; } // Create a new font object. GMFont font = new GMFont(); // Set font id. font.Id = i; // Read font data. font.Name = reader.ReadGMString(); // If version is 8.0, get last changed. if (version == 800) { font.LastChanged = reader.ReadGMDouble(); } // Get version. version = reader.ReadGMInt(); // Check version. if (version != 540 && version != 800) { throw new Exception("Unsupported Font object version."); } // Read font data. font.FontName = reader.ReadGMString(); font.Size = reader.ReadGMInt(); font.Bold = reader.ReadGMBool(); font.Italic = reader.ReadGMBool(); font.CharacterRangeMin = reader.ReadGMShort(); font.CharacterSet = reader.ReadGMByte(); font.AntiAliasing = reader.ReadGMByte(); font.CharacterRangeMax = reader.ReadGMInt(); // End object inflate. reader.EndDecompress(); // Add font. fonts.Add(font); } // Return fonts. return(fonts); }
/// <summary> /// Reads all GMX timelines from a directory /// </summary> /// <param name="file">The XML (.GMX) file path</param> /// <returns>A list of timelines</returns> public static GMList <GMTimeline> ReadTimelinesGMX(string directory, List <string> assets) { // A list of timelines GMList <GMTimeline> timelines = new GMList <GMTimeline>(); timelines.AutoIncrementIds = false; // Iterate through .gmx files in the directory foreach (string file in Directory.GetFiles(directory, "*.gmx")) { // Set name of the timeline string name = GetResourceName(file); // If the file is not in the asset list, it has been orphaned, continue if (!assets.Contains(name)) { continue; } // Create a dictionary of object properties Dictionary <string, string> objectProperties = new Dictionary <string, string>(); foreach (GMXObjectProperty property in Enum.GetValues(typeof(GMXObjectProperty))) { objectProperties.Add(GMXEnumString(property), ""); } // Create a dictionary of action properties Dictionary <string, string> actionProperties = new Dictionary <string, string>(); foreach (GMXActionProperty property in Enum.GetValues(typeof(GMXActionProperty))) { actionProperties.Add(GMXEnumString(property), ""); } // Create a dictionary of argument properties Dictionary <string, string> argumentProperties = new Dictionary <string, string>(); foreach (GMXArgumentProperty property in Enum.GetValues(typeof(GMXArgumentProperty))) { argumentProperties.Add(GMXEnumString(property), ""); } // Local variables List <GMMoment> moments = new List <GMMoment>(); // Create an xml reader using (XmlReader reader = XmlReader.Create(file)) { // Seek to content reader.MoveToContent(); // Read the GMX file while (reader.Read()) { // If the node is not an element, continue if (reader.NodeType != XmlNodeType.Element) { continue; } // Get the element name string nodeName = reader.Name; // Create a new moment and get it's properties GMMoment moment = new GMMoment(); // If the element is an event if (nodeName.ToLower() == GMXEnumString(GMXObjectProperty.Event).ToLower()) { // Action list List <GMAction> actions = new List <GMAction>(); // Seek to content reader.MoveToContent(); // Create a reader for the actions using (XmlReader reader2 = reader.ReadSubtree()) { // Argument list List <GMArgument> arguments = new List <GMArgument>(); // Read in action properties while (reader2.Read()) { // If the node is not an element, continue if (reader.NodeType != XmlNodeType.Element) { continue; } // Get the element name string nodeName2 = reader2.Name; // If the node is an argument if (nodeName2.ToLower() == EnumString.GetEnumString(GMXObjectProperty.Argument).ToLower()) { // Seek to content reader2.MoveToContent(); // Create a reader for the arguments using (XmlReader reader3 = reader2.ReadSubtree()) { // Read in argument properties while (reader3.Read()) { // If the node is not an element, continue if (reader.NodeType != XmlNodeType.Element) { continue; } // Get the element name string nodeName3 = reader3.Name; // Read element reader3.Read(); // If the element value is null or empty, continue if (String.IsNullOrEmpty(reader3.Value)) { continue; } // Set the property value argumentProperties[nodeName3] = reader3.Value; } // Create a new argument GMArgument argument = new GMArgument(); argument.Type = GMXInt(argumentProperties[GMXEnumString(GMXArgumentProperty.Kind)], argument.Type); argument.Value = GMXString(argumentProperties[GMXEnumString(GMXArgumentProperty.String)], argument.Value); // Add argument to the list arguments.Add(argument); } } // Read element reader2.Read(); // If the element value is null or empty, continue if (String.IsNullOrEmpty(reader2.Value)) { continue; } // Set the property value actionProperties[nodeName2] = reader2.Value; } // Create a new action GMAction action = new GMAction(); action.LibraryId = GMXInt(actionProperties[GMXEnumString(GMXActionProperty.LibId)], action.LibraryId); action.ActionId = GMXInt(actionProperties[GMXEnumString(GMXActionProperty.Id)], action.ActionId); action.ActionKind = GMXInt(actionProperties[GMXEnumString(GMXActionProperty.Kind)], action.ActionKind); action.AllowRelative = GMXBool(actionProperties[GMXEnumString(GMXActionProperty.UseRelative)], action.AllowRelative); action.Question = GMXBool(actionProperties[GMXEnumString(GMXActionProperty.IsQuestion)], action.Question); action.CanApplyTo = GMXBool(actionProperties[GMXEnumString(GMXActionProperty.UseApplyTo)], action.CanApplyTo); action.ExecuteMode = GMXInt(actionProperties[GMXEnumString(GMXActionProperty.ExeType)], action.ExecuteMode); action.FunctionName = GMXString(actionProperties[GMXEnumString(GMXActionProperty.FunctionName)], action.FunctionName); action.ExecuteCode = GMXString(actionProperties[GMXEnumString(GMXActionProperty.CodeString)], action.ExecuteCode); action.AppliesToName = GMXString(actionProperties[GMXEnumString(GMXActionProperty.WhoName)], action.AppliesToName); action.AppliesTo = action.AppliesToName == "" ? -1 : GetIdFromName(action.AppliesToName); action.Relative = GMXBool(actionProperties[GMXEnumString(GMXActionProperty.Relative)], action.Relative); action.Not = GMXBool(actionProperties[GMXEnumString(GMXActionProperty.IsNot)], action.Not); action.Arguments = arguments.ToArray(); // Add action to the list actions.Add(action); } // Set the events actions moment.Actions = actions.ToArray(); moments.Add(moment); } if (nodeName.ToLower() == "step") { // Read element reader.Read(); // If the element value is null or empty, continue if (String.IsNullOrEmpty(reader.Value)) { continue; } moment.StepIndex = GMXInt(reader.Value, moment.StepIndex); moments.Add(moment); } // Set the property value objectProperties[nodeName] = reader.Value; } } // Create a new timeline, set properties GMTimeline timeline = new GMTimeline(); timeline.Moments = moments.ToArray(); // Add the timeline timelines.Add(timeline); } // Return the list of timelines return(timelines); }
/// <summary> /// Reads all sounds from Game Maker project file stream. /// </summary> public static GMList <GMSound> ReadSounds(GMFileReader reader) { // Get version. int version = reader.ReadGMInt(); // Check version. if (version != 400 && version != 800) { throw new Exception("Unsupported Pre-Sound object version."); } // Create a new sound list. GMList <GMSound> sounds = new GMList <GMSound>(); // Amount of sound ids. int num = reader.ReadGMInt(); // Iterate through sounds. for (int i = 0; i < num; i++) { // If version is 8.0, start inflate. if (version == 800) { reader.Decompress(); } // If the sound at index does not exists, continue. if (reader.ReadGMBool() == false) { sounds.LastId++; reader.EndDecompress(); continue; } // Create sound object. GMSound sound = new GMSound(); // Set sound id. sound.Id = i; // Read sound data. sound.Name = reader.ReadGMString(); // If version is 8.0, get last changed. if (version == 800) { sound.LastChanged = reader.ReadGMDouble(); } // Get version. version = reader.ReadGMInt(); // Check version. if (version != 440 && version != 600 && version != 800) { throw new Exception("Unsupported Sound object version."); } // Check version. if (version == 440) { sound.Kind = reader.ReadGMInt(); } else { // Read sound data. sound.Type = reader.ReadGMInt(); } // Read sound data. sound.FileType = reader.ReadGMString(); // Check version. if (version == 440) { // If sound data exists, read it. if ((int)sound.Kind != -1) { sound.Data = reader.ReadGMBytes(reader.ReadGMInt()); } // Read sound data. sound.AllowSoundEffects = reader.ReadGMBool(); sound.Buffers = reader.ReadGMInt(); sound.LoadOnlyOnUse = reader.ReadGMBool(); } else { // Read sound data. sound.FileName = reader.ReadGMString(); // If sound data exists, read it. if (reader.ReadGMBool() == true) { sound.Data = reader.ReadGMBytes(reader.ReadGMInt()); } // Read sound data. sound.Effects = reader.ReadGMInt(); sound.Volume = reader.ReadGMDouble(); sound.Pan = reader.ReadGMDouble(); sound.Preload = reader.ReadGMBool(); } // End object inflate. reader.EndDecompress(); // Add sound. sounds.Add(sound); } // Return sounds. return(sounds); }
/// <summary> /// Reads all scripts from a GM file reader stream. /// </summary> public static GMList <GMScript> ReadScripts(GMFileReader reader) { // Get version. int version = reader.ReadGMInt(); // Check version. if (version != 400 && version != 800) { throw new Exception("Unsupported Pre-Script object version."); } // Create a new list of scripts. GMList <GMScript> scripts = new GMList <GMScript>(); // Amount of script ids. int num = reader.ReadGMInt(); // Iterate through scripts. for (int i = 0; i < num; i++) { // If version is 8.0, start inflate. if (version == 800) { reader.Decompress(); } // If the script at index does not exists, continue. if (reader.ReadGMBool() == false) { scripts.LastId++; reader.EndDecompress(); continue; } // Create a new script object. GMScript script = new GMScript(); // Set script id. script.Id = i; // Read script data. script.Name = reader.ReadGMString(); // If version is 8.0, get last changed. if (version == 800) { script.LastChanged = reader.ReadGMDouble(); } // Get version. version = reader.ReadGMInt(); // Check version. if (version != 400 && version != 800) { throw new Exception("Unsupported Script object version."); } // Read script data. script.Code = reader.ReadGMString(); // End object inflate. reader.EndDecompress(); // Add script. scripts.Add(script); } // Return scripts. return(scripts); }
/// <summary> /// Reads sprites from Game Maker project file. /// </summary> private GMList<GMSprite> ReadSprites() { // Get version. int version = ReadInt(); // Check version. if (version != 400 && version != 800) throw new Exception("Unsupported Pre-Sprite object version."); // Create a new list of sprites. GMList<GMSprite> sprites = new GMList<GMSprite>(); // Amount of sprite ids. int num = ReadInt(); // Iterate through sprites. for (int i = 0; i < num; i++) { // If version is 8.0, start inflate. if (version == 800) Decompress(); // If the sprite at index does not exists, continue. if (ReadBool() == false) { sprites.LastId++; EndDecompress(); continue; } // Create a new sprite object. GMSprite sprite = new GMSprite(); // Set sprite id. sprite.Id = i; // Read sprite data. sprite.Name = ReadString(); // If version is 8.0, get last changed. if (version == 800) sprite.LastChanged = ReadDouble(); // Get version. version = ReadInt(); // Check version. if (version != 400 && version != 542 && version != 800) throw new Exception("Unsupported Sprite object version."); // If less than version 8.0. if (version < 800) { // Read sprite data sprite.Width = ReadInt(); sprite.Height = ReadInt(); sprite.BoundingBoxLeft = ReadInt(); sprite.BoundingBoxRight = ReadInt(); sprite.BoundingBoxBottom = ReadInt(); sprite.BoundingBoxTop = ReadInt(); sprite.Transparent = ReadBool(); // Check version. if (version > 400) { // Read sprite data sprite.SmoothEdges = ReadBool(); sprite.Preload = ReadBool(); } // Read sprite data. sprite.BoundingBoxMode = (BoundingBoxType)ReadInt(); sprite.Precise = ReadBool(); // Check version. if (version == 400) { // Read sprtie data. sprite.UseVideoMemory = ReadBool(); sprite.LoadOnlyOnUse = ReadBool(); } // Read sprite data. sprite.OriginX = ReadInt(); sprite.OriginY = ReadInt(); // Sprite number of sub images sprite.SubImages = new GMImage[ReadInt()]; // Iterate through sub-images for (int j = 0; j < sprite.SubImages.Length; j++) { // If the sub-image at index does not exists, continue. if (ReadInt() == -1) continue; // Create a new image object. GMImage image = new GMImage(); // Get size of image data. int size = ReadInt(); // Get image data. image.Data = ReadBytes(size); // Insert compressed image data. sprite.SubImages[j] = image; } } else { // Read sprite data. sprite.OriginX = ReadInt(); sprite.OriginY = ReadInt(); // Sprite number of sub images. sprite.SubImages = new GMImage[ReadInt()]; // Iterate through sub-images. for (int j = 0; j < sprite.SubImages.Length; j++) { // Get version. version = ReadInt(); // Check version. if (version != 800) throw new Exception("Unsupported Sprite object version."); // Get width and height of image. int width = ReadInt(); int height = ReadInt(); // If the sprite size is not zero. if (width != 0 && height != 0) { // Create a new image object. GMImage image = new GMImage(); image.Compressed = false; // Set image data. image.Width = width; image.Height = height; // Get size of image data. int size = ReadInt(); // Get image data. image.Data = ReadBytes(size); // Insert compressed image data. sprite.SubImages[j] = image; } } // Read sprite data. sprite.ShapeMode = (ShapeType)ReadInt(); sprite.AlphaTolerance = ReadInt(); sprite.UseSeperateCollisionMasks = ReadBool(); sprite.BoundingBoxMode = (BoundingBoxType)ReadInt(); sprite.BoundingBoxLeft = ReadInt(); sprite.BoundingBoxRight = ReadInt(); sprite.BoundingBoxBottom = ReadInt(); sprite.BoundingBoxTop = ReadInt(); } // End object inflate. EndDecompress(); // Add sprite. sprites.Add(sprite); } // Return sprites. return sprites; }
public override void ConvertProject(ProjectFile pf) { // TODO: use asset refs whenever code is implemented var dataCode = pf.DataHandle.GetChunk <GMChunkCODE>()?.List; var dataSeqn = pf.DataHandle.GetChunk <GMChunkSEQN>()?.List; int getCode(string name) { if (name == null) { return(-1); } if (dataCode == null) { return(-1); // not sure? } try { return(dataCode.Select((elem, index) => new { elem, index }).First(p => p.elem.Name.Content == name).index); } catch (InvalidOperationException) { return(-1); } } int getSeqn(string name) { try { return(dataSeqn.Select((elem, index) => new { elem, index }).First(p => p.elem.Name.Content == name).index); } catch (InvalidOperationException) { return(-1); } } GMList <GMRoom> dataAssets = pf.DataHandle.GetChunk <GMChunkROOM>().List; dataAssets.Clear(); for (int i = 0; i < pf.Rooms.Count; i++) { AssetRoom asset = pf.Rooms[i].Asset; if (asset == null) { // This asset was never converted dataAssets.Add((GMRoom)pf.Rooms[i].DataAsset); continue; } GMRoom data = new GMRoom() { Name = pf.DataHandle.DefineString(asset.Name), Caption = pf.DataHandle.DefineString(asset.Caption), Width = asset.Width, Height = asset.Height, Speed = asset.Speed, Persistent = asset.Persistent, BackgroundColor = asset.BackgroundColor, DrawBackgroundColor = asset.DrawBackgroundColor, CreationCodeID = getCode(asset.CreationCode), Backgrounds = new(), Views = new(), GameObjects = new(), Tiles = new(), Physics = asset.Physics.Enabled, Top = asset.Physics.Top, Left = asset.Physics.Left, Right = asset.Physics.Right, Bottom = asset.Physics.Bottom, GravityX = asset.Physics.GravityX, GravityY = asset.Physics.GravityY, PixelsToMeters = asset.Physics.PixelsToMeters }; foreach (var bg in asset.Backgrounds) { data.Backgrounds.Add(new() { Enabled = bg.Enabled, Foreground = bg.Foreground, BackgroundID = pf.Backgrounds.FindIndex(bg.Asset), X = bg.X, Y = bg.Y, TileX = bg.TileX, TileY = bg.TileY, SpeedX = bg.SpeedX, SpeedY = bg.SpeedY, Stretch = bg.Stretch }); } foreach (var view in asset.Views) { data.Views.Add(new() { Enabled = view.Enabled, ViewX = view.ViewX, ViewY = view.ViewY, ViewWidth = view.ViewWidth, ViewHeight = view.ViewHeight, PortX = view.PortX, PortY = view.PortY, PortWidth = view.PortWidth, PortHeight = view.PortHeight, BorderX = view.BorderX, BorderY = view.BorderY, SpeedX = view.SpeedX, SpeedY = view.SpeedY, FollowObjectID = pf.Objects.FindIndex(view.FollowObject) }); } foreach (var obj in asset.GameObjects) { var newObj = new GMRoom.GameObject() { X = obj.X, Y = obj.Y, ObjectID = pf.Objects.FindIndex(obj.Asset), InstanceID = obj.InstanceID, CreationCodeID = getCode(obj.CreationCode), ScaleX = obj.ScaleX, ScaleY = obj.ScaleY, Color = obj.Color, Angle = obj.Angle, ImageSpeed = obj.ImageSpeed, ImageIndex = obj.ImageIndex }; if (pf.DataHandle.VersionInfo.RoomObjectPreCreate) { newObj.PreCreateCodeID = getCode(obj.PreCreateCode); } data.GameObjects.Add(newObj); } foreach (var tile in asset.Tiles) { var newTile = new GMRoom.Tile() { X = tile.X, Y = tile.Y, SourceX = tile.SourceX, SourceY = tile.SourceY, Width = tile.Width, Height = tile.Height, Depth = tile.Depth, ID = tile.ID, ScaleX = tile.ScaleX, ScaleY = tile.ScaleY, Color = tile.Color }; if (pf.DataHandle.VersionInfo.IsNumberAtLeast(2)) { newTile.AssetID = pf.Sprites.FindIndex(tile.Asset); } else { newTile.AssetID = pf.Backgrounds.FindIndex(tile.Asset); } data.Tiles.Add(newTile); } if (pf.DataHandle.VersionInfo.IsNumberAtLeast(2)) { data.Layers = new(asset.Layers.Count); foreach (var layer in asset.Layers) { var newLayer = new GMRoom.Layer() { Name = pf.DataHandle.DefineString(layer.Name), ID = layer.ID, Depth = layer.Depth, OffsetX = layer.OffsetX, OffsetY = layer.OffsetY, HSpeed = layer.HSpeed, VSpeed = layer.VSpeed, Visible = layer.Visible }; if (layer.Background != null) { newLayer.Kind = GMRoom.Layer.LayerKind.Background; newLayer.Background = new() { Visible = layer.Background.Visible, Foreground = layer.Background.Foreground, SpriteID = pf.Sprites.FindIndex(layer.Background.Sprite), TileHorz = layer.Background.TileHorz, TileVert = layer.Background.TileVert, Stretch = layer.Background.Stretch, Color = layer.Background.Color, FirstFrame = layer.Background.FirstFrame, AnimationSpeed = layer.Background.AnimationSpeed, AnimationSpeedType = layer.Background.AnimationSpeedType }; } else if (layer.Instances != null) { newLayer.Kind = GMRoom.Layer.LayerKind.Instances; newLayer.Instances = layer.Instances; } else if (layer.Assets != null) { newLayer.Kind = GMRoom.Layer.LayerKind.Assets; newLayer.Assets = new() { LegacyTiles = new(), Sprites = new() }; foreach (var tile in layer.Assets.LegacyTiles) { newLayer.Assets.LegacyTiles.Add(new() { X = tile.X, Y = tile.Y, SourceX = tile.SourceX, SourceY = tile.SourceY, Width = tile.Width, Height = tile.Height, Depth = tile.Depth, ID = tile.ID, ScaleX = tile.ScaleX, ScaleY = tile.ScaleY, Color = tile.Color, AssetID = pf.Sprites.FindIndex(tile.Asset) }); } foreach (var spr in layer.Assets.Sprites) { newLayer.Assets.Sprites.Add(new() { Name = pf.DataHandle.DefineString(spr.Name), AssetID = pf.Sprites.FindIndex(spr.Asset), X = spr.X, Y = spr.Y, ScaleX = spr.ScaleX, ScaleY = spr.ScaleY, Color = spr.Color, AnimationSpeed = spr.AnimationSpeed, AnimationSpeedType = spr.AnimationSpeedType, FrameIndex = spr.FrameIndex, Rotation = spr.Rotation }); } if (pf.DataHandle.VersionInfo.IsNumberAtLeast(2, 3)) { newLayer.Assets.Sequences = new(layer.Assets.Sequences.Count); foreach (var seq in layer.Assets.Sequences) { newLayer.Assets.Sequences.Add(new() { Name = pf.DataHandle.DefineString(seq.Name), AssetID = getSeqn(seq.Asset), X = seq.X, Y = seq.Y, ScaleX = seq.ScaleX, ScaleY = seq.ScaleY, Color = seq.Color, AnimationSpeed = seq.AnimationSpeed, AnimationSpeedType = seq.AnimationSpeedType, FrameIndex = seq.FrameIndex, Rotation = seq.Rotation }); } if (!pf.DataHandle.VersionInfo.IsNumberAtLeast(2, 3, 2)) { newLayer.Assets.NineSlices = new(layer.Assets.NineSlices.Count); foreach (var spr in layer.Assets.NineSlices) { newLayer.Assets.NineSlices.Add(new() { Name = pf.DataHandle.DefineString(spr.Name), AssetID = pf.Sprites.FindIndex(spr.Asset), X = spr.X, Y = spr.Y, ScaleX = spr.ScaleX, ScaleY = spr.ScaleY, Color = spr.Color, AnimationSpeed = spr.AnimationSpeed, AnimationSpeedType = spr.AnimationSpeedType, FrameIndex = spr.FrameIndex, Rotation = spr.Rotation }); } } } } else if (layer.Tiles != null) { newLayer.Kind = GMRoom.Layer.LayerKind.Tiles; newLayer.Tiles = new() { BackgroundID = pf.Backgrounds.FindIndex(layer.Tiles.Background), TilesX = layer.Tiles.TilesX, TilesY = layer.Tiles.TilesY, TileData = layer.Tiles.TileData }; } else if (layer.Effect != null) { newLayer.Kind = GMRoom.Layer.LayerKind.Effect; newLayer.Effect = new() { EffectType = pf.DataHandle.DefineString(layer.Effect.EffectType), Properties = new(layer.Effect.Properties.Count) }; foreach (var prop in layer.Effect.Properties) { newLayer.Effect.Properties.Add(new() { Kind = prop.Kind, Name = pf.DataHandle.DefineString(prop.Name), Value = pf.DataHandle.DefineString(prop.Value) }); } } // maybe throw exception if nothing else matched? } if (pf.DataHandle.VersionInfo.IsNumberAtLeast(2, 3)) { data.SequenceIDs = new(); foreach (string seq in asset.Sequences) { data.SequenceIDs.Add(getSeqn(seq)); } } } if (asset.EnableViews) { data.Flags &= GMRoom.RoomFlags.EnableViews; } if (asset.ShowColor) { data.Flags &= GMRoom.RoomFlags.ShowColor; } if (asset.ClearDisplayBuffer) { data.Flags &= GMRoom.RoomFlags.ClearDisplayBuffer; } dataAssets.Add(data); } } } }
/// <summary> /// Reads sprites from Game Maker project file. /// </summary> public static GMList <GMSprite> ReadSpritesGMX(string directory, ref List <string> assets) { // A list of sprites GMList <GMSprite> sprites = new GMList <GMSprite>(); sprites.AutoIncrementIds = false; // Iterate through .gmx files in the directory foreach (string file in Directory.GetFiles(directory, "*.gmx")) { // Set name of the sprite string name = GetResourceName(file); // If the file is not in the asset list, it has been orphaned, continue if (!assets.Contains(name)) { continue; } // Create a dictionary of sprite properties Dictionary <string, string> properties = new Dictionary <string, string>(); foreach (GMXSpriteProperty property in Enum.GetValues(typeof(GMXSpriteProperty))) { properties.Add(GMXEnumString(property), ""); } // Local variables and texture group strings List <GMImage> subImages = new List <GMImage>(); string textureGroup = GMXEnumString(GMXSpriteProperty.TextureGroup); string textureGroup0 = GMXEnumString(GMXSpriteProperty.TextureGroup0); // Create an xml reader using (XmlReader reader = XmlReader.Create(file)) { // Seek to content reader.MoveToContent(); // Read the GMX file while (reader.Read()) { // If the node is not an element, continue if (reader.NodeType != XmlNodeType.Element) { continue; } // Get the element name string nodeName = reader.Name; // Read element reader.Read(); // If the element value is null or empty, continue if (String.IsNullOrEmpty(reader.Value)) { continue; } // If the element is a frame element create subimage, else normal property if (nodeName.ToLower() == GMXEnumString(GMXSpriteProperty.Frame).ToLower()) { // Create a sub image and set the image path GMImage subImage = new GMImage(); subImage.Compressed = false; subImage.FilePath = reader.Value; subImage.Data = GMUtilities.LoadBytesFromBitmap(directory + "\\" + subImage.FilePath); subImages.Add(subImage); } else { // Set the property value properties[nodeName] = reader.Value; } } } // Create a new sprite, set properties GMSprite sprite = new GMSprite(); sprite.Id = GetIdFromName(name); sprite.Name = name; sprite.OriginX = GMXInt(properties[GMXEnumString(GMXSpriteProperty.XOrigin)], sprite.OriginX); sprite.OriginY = GMXInt(properties[GMXEnumString(GMXSpriteProperty.YOrigin)], sprite.OriginY); sprite.ShapeMode = GMXInt(properties[GMXEnumString(GMXSpriteProperty.ColKind)], sprite.ShapeMode); sprite.AlphaTolerance = GMXInt(properties[GMXEnumString(GMXSpriteProperty.ColTolerance)], sprite.AlphaTolerance); sprite.UseSeperateCollisionMasks = GMXBool(properties[GMXEnumString(GMXSpriteProperty.SepMasks)], sprite.UseSeperateCollisionMasks); sprite.BoundingBoxMode = GMXInt(properties[GMXEnumString(GMXSpriteProperty.BBoxMode)], sprite.BoundingBoxMode); sprite.BoundingBoxLeft = GMXInt(properties[GMXEnumString(GMXSpriteProperty.BBoxLeft)], sprite.BoundingBoxLeft); sprite.BoundingBoxRight = GMXInt(properties[GMXEnumString(GMXSpriteProperty.BBoxRight)], sprite.BoundingBoxRight); sprite.BoundingBoxTop = GMXInt(properties[GMXEnumString(GMXSpriteProperty.BBoxTop)], sprite.BoundingBoxTop); sprite.BoundingBoxBottom = GMXInt(properties[GMXEnumString(GMXSpriteProperty.BBoxBottom)], sprite.BoundingBoxBottom); sprite.TileHorizontally = GMXBool(properties[GMXEnumString(GMXSpriteProperty.HTile)], sprite.TileHorizontally); sprite.TileVertically = GMXBool(properties[GMXEnumString(GMXSpriteProperty.VTile)], sprite.TileVertically); sprite.UsedFor3D = GMXBool(properties[GMXEnumString(GMXSpriteProperty.For3D)], sprite.UsedFor3D); sprite.Width = GMXInt(properties[GMXEnumString(GMXSpriteProperty.Width)], sprite.Width); sprite.Height = GMXInt(properties[GMXEnumString(GMXSpriteProperty.Height)], sprite.Height); properties[textureGroup] = properties[textureGroup] == "" ? "0" : properties[textureGroup]; properties[textureGroup0] = properties[textureGroup0] == "" ? "0" : properties[textureGroup0]; // The texture group does not equal zero set texture group 0 to the texture group value if (properties[textureGroup] != "0") { properties[textureGroup0] = properties[textureGroup]; } // The texture group zero does not equal zero set texture group to the texture group 0 value else if (properties[textureGroup0] != "0") { properties[textureGroup] = properties[textureGroup0]; } // Create a list of texture groups List <int> textureGroups = new List <int>(); for (int i = 0; properties.ContainsKey(textureGroup + i); i++) { textureGroups.Add(Convert.ToInt32(properties[textureGroup + i])); } // Set the subimage size for all subimages foreach (GMImage image in subImages) { image.Width = sprite.Width; image.Height = sprite.Height; } sprite.TextureGroups = textureGroups.ToArray(); sprite.SubImages = subImages.ToArray(); // Add the sprite sprites.Add(sprite); } // Return the list of sprites return(sprites); }
/// <summary> /// Reads timelines from GM file. /// </summary> private GMList<GMTimeline> ReadTimelines() { // Get version. int version = ReadInt(); // Check version. if (version != 500 && version != 800) throw new Exception("Unsupported Pre-Timeline object version."); // Create a new timeline list. GMList<GMTimeline> timelines = new GMList<GMTimeline>(); // Amount of timeline ids. int num = ReadInt(); // Iterate through timelines for (int i = 0; i < num; i++) { // If version is 8.0, start inflate. if (version == 800) Decompress(); // If the timeline at index does not exists, continue. if (ReadBool() == false) { timelines.LastId++; EndDecompress(); continue; } // Create a new timeline object. GMTimeline timeline = new GMTimeline(); // Set timeline id. timeline.Id = i; // Read timeline data. timeline.Name = ReadString(); // If version is 8.0, get last changed. if (version == 800) timeline.LastChanged = ReadDouble(); // Get version. int version2 = ReadInt(); // Check version. if (version2 != 500) throw new Exception("Unsupported Timeline object version."); // Get number of timeline moments. timeline.Moments = new GMMoment[ReadInt()]; // Iterate through moments. for (int j = 0; j < timeline.Moments.Length; j++) { // Create a new timeline moment object. GMMoment moment = new GMMoment(); // Moment step number moment.StepIndex = ReadInt(); // Read moment actions. moment.Actions = ReadActions(); // Add moment to timeline. timeline.Moments[j] = moment; } // End object inflate. EndDecompress(); // Add timeline. timelines.Add(timeline); } // Return timelines. return timelines; }
/// <summary> /// Reads timelines from GM file. /// </summary> public static GMList <GMTimeline> ReadTimelines(GMFileReader reader) { // Get version. int version = reader.ReadGMInt(); // Check version. if (version != 500 && version != 800) { throw new Exception("Unsupported Pre-Timeline object version."); } // Create a new timeline list. GMList <GMTimeline> timelines = new GMList <GMTimeline>(); // Amount of timeline ids. int num = reader.ReadGMInt(); // Iterate through timelines for (int i = 0; i < num; i++) { // If version is 8.0, start inflate. if (version == 800) { reader.Decompress(); } // If the timeline at index does not exists, continue. if (reader.ReadGMBool() == false) { timelines.LastId++; reader.EndDecompress(); continue; } // Create a new timeline object. GMTimeline timeline = new GMTimeline(); // Set timeline id. timeline.Id = i; // Read timeline data. timeline.Name = reader.ReadGMString(); // If version is 8.0, get last changed. if (version == 800) { timeline.LastChanged = reader.ReadGMDouble(); } // Get version. int version2 = reader.ReadGMInt(); // Check version. if (version2 != 500) { throw new Exception("Unsupported Timeline object version."); } // Get number of timeline moments. timeline.Moments = new GMMoment[reader.ReadGMInt()]; // Iterate through moments. for (int j = 0; j < timeline.Moments.Length; j++) { // Create a new timeline moment object. GMMoment moment = new GMMoment(); // Moment step number moment.StepIndex = reader.ReadGMInt(); // Read moment actions. moment.Actions = GMAction.ReadActions(reader); // Add moment to timeline. timeline.Moments[j] = moment; } // End object inflate. reader.EndDecompress(); // Add timeline. timelines.Add(timeline); } // Return timelines. return(timelines); }
/// <summary> /// Reads all triggers from Game Maker project file. /// </summary> private GMList<GMTrigger> ReadTriggers() { // Get version. int version = ReadInt(); // Check version. if (version != 800) throw new Exception("Unsupported Pre-Trigger object version."); // Create a new trigger list. GMList<GMTrigger> triggers = new GMList<GMTrigger>(); // Amount of trigger ids. int num = ReadInt(); // Iterate through triggers. for (int i = 0; i < num; i++) { // Start inflate. Decompress(); // If the trigger at index does not exists, continue. if (ReadBool() == false) { triggers.LastId++; EndDecompress(); continue; } // Get version. version = ReadInt(); // Check version. if (version != 800) throw new Exception("Unsupported trigger object version."); // Create a new trigger. GMTrigger trigger = new GMTrigger(); // Read trigger data. trigger.Name = ReadString(); trigger.Condition = ReadString(); trigger.Moment = (MomentType)ReadInt(); trigger.Constant = ReadString(); // End object inflate. EndDecompress(); // Add trigger. triggers.Add(trigger); } // Get last changed. GMTrigger.TriggerLastChanged = ReadDouble(); // Return triggers. return triggers; }
/// <summary> /// Reads backgrounds from GM file. /// </summary> private GMList<GMBackground> ReadBackgrounds() { // Get version. int version = ReadInt(); // Check version. if (version != 400 && version != 800) throw new Exception("Unsupported Pre-Background object version."); // Create a new list of backgrounds. GMList<GMBackground> backgrounds = new GMList<GMBackground>(); // Amount of background ids. int num = ReadInt(); // Iterate through backgrounds. for (int i = 0; i < num; i++) { // If version is 8.0, start inflate. if (version == 800) Decompress(); // If the background at index does not exists, continue. if (ReadBool() == false) { backgrounds.LastId++; EndDecompress(); continue; } // Create a new background object. GMBackground background = new GMBackground(); // Set background id background.Id = i; // Get background data. background.Name = ReadString(); // If version is 8.0, get last changed. if (version == 800) background.LastChanged = ReadDouble(); // Get version. version = ReadInt(); // Check version. if (version != 400 && version != 543 && version != 710) throw new Exception("Unsupported Background object version."); // If version is less than 7.1. if (version < 710) { // Background data background.Width = ReadInt(); background.Height = ReadInt(); background.Transparent = ReadBool(); // Check version. if (version > 400) { // Read background data. background.SmoothEdges = ReadBool(); background.Preload = ReadBool(); background.UseAsTileSet = ReadBool(); background.TileWidth = ReadInt(); background.TileHeight = ReadInt(); background.HorizontalOffset = ReadInt(); background.VerticalOffset = ReadInt(); background.HorizontalSeperation = ReadInt(); background.VerticalSeperation = ReadInt(); } else { // Read background data. background.UseVideoMemory = ReadBool(); background.LoadOnlyOnUse = ReadBool(); } // If image data exists. if (ReadBool()) { // If pixel data does not exist. if (ReadInt() == -1) continue; // Create a new image. GMImage image = new GMImage(); // Get size of image data. int size = ReadInt(); // Get compressed image data. image.Data = ReadBytes(size); // Set background image. background.Image = image; } } else { // Get background data. background.UseAsTileSet = ReadBool(); background.TileWidth = ReadInt(); background.TileHeight = ReadInt(); background.HorizontalOffset = ReadInt(); background.VerticalOffset = ReadInt(); background.HorizontalSeperation = ReadInt(); background.VerticalSeperation = ReadInt(); // Get version. version = ReadInt(); // Check version. if (version != 800) throw new Exception("Unsupported Background object version."); // Get image data. background.Width = ReadInt(); background.Height = ReadInt(); // If the sprite size is not zero. if (background.Width != 0 && background.Height != 0) { // Create a new image object. GMImage image = new GMImage(); image.Compressed = false; // Set image data. image.Width = background.Width; image.Height = background.Height; // Get size of image data. int size = ReadInt(); // Get image data. image.Data = ReadBytes(size); // Insert compressed image data. background.Image = image; } } // End object inflate. EndDecompress(); // Add background. backgrounds.Add(background); } // Return backgrounds. return backgrounds; }
/// <summary> /// Reads data files from GM file. /// </summary> private GMList<GMDataFile> ReadDataFiles() { // Create a new list of data files. GMList<GMDataFile> dataFiles = new GMList<GMDataFile>(); // Amount of data file ids. int num = ReadInt(); // Iterate through data files. for (int i = 0; i < num; i++) { // If the data file at index does not exists, continue. if (ReadBool() == false) { dataFiles.LastId++; continue; } // Create a new data file object. GMDataFile dataFile = new GMDataFile(); // Set data file id. dataFile.Id = i; // Read data file data. dataFile.Name = ReadString(); // Get version. int version = ReadInt(); // Check version. if (version != 440) throw new Exception("Unsupported Data File object version."); // Read data file data. dataFile.FileName = ReadString(); // If data file exists, read it in. if (ReadBool()) dataFile.Data = ReadBytes(ReadInt()); // Read data file data. dataFile.ExportMode = (ExportType)(ReadInt()); dataFile.OverwriteFile = ReadBool(); dataFile.FreeDataMemory = ReadBool(); dataFile.RemoveAtGameEnd = ReadBool(); // Add data file. dataFiles.Add(dataFile); } // Return data files. return dataFiles; }
/// <summary> /// Reads all triggers from GM file reader stream. /// </summary> public static GMList <GMTrigger> ReadTriggers(GMFileReader reader) { // Get version. int version = reader.ReadGMInt(); // Check version. if (version != 800) { throw new Exception("Unsupported Pre-Trigger object version."); } // Create a new trigger list. GMList <GMTrigger> triggers = new GMList <GMTrigger>(); // Amount of trigger ids. int num = reader.ReadGMInt(); // Iterate through triggers. for (int i = 0; i < num; i++) { // Start inflate. reader.Decompress(); // If the trigger at index does not exists, continue. if (reader.ReadGMBool() == false) { triggers.LastId++; reader.EndDecompress(); continue; } // Get version. version = reader.ReadGMInt(); // Check version. if (version != 800) { throw new Exception("Unsupported trigger object version."); } // Create a new trigger. GMTrigger trigger = new GMTrigger(); // Read trigger data. trigger.Name = reader.ReadGMString(); trigger.Condition = reader.ReadGMString(); trigger.Moment = (MomentType)reader.ReadGMInt(); trigger.Constant = reader.ReadGMString(); // End object inflate. reader.EndDecompress(); // Add trigger. triggers.Add(trigger); } // Get last changed. GMTrigger.TriggerLastChanged = reader.ReadGMDouble(); // Return triggers. return(triggers); }
/// <summary> /// Reads all GMX objects from a directory /// </summary> /// <param name="file">The XML (.GMX) file path</param> /// <returns>A list of objects</returns> public static GMList <GMObject> ReadObjectsGMX(string directory, ref List <string> assets) { // A list of objects GMList <GMObject> objects = new GMList <GMObject>(); objects.AutoIncrementIds = false; // Iterate through .gmx files in the directory foreach (string file in Directory.GetFiles(directory, "*.gmx")) { // Set name of the object string name = GetResourceName(file); // If the file is not in the asset list, it has been orphaned, continue if (!assets.Contains(name)) { continue; } // Create a dictionary of object properties Dictionary <string, string> objectProperties = new Dictionary <string, string>(); foreach (GMXObjectProperty property in Enum.GetValues(typeof(GMXObjectProperty))) { objectProperties.Add(GMXEnumString(property), ""); } // Create a dictionary of action properties Dictionary <string, string> actionProperties = new Dictionary <string, string>(); foreach (GMXActionProperty property in Enum.GetValues(typeof(GMXActionProperty))) { actionProperties.Add(GMXEnumString(property), ""); } // Create a dictionary of argument properties Dictionary <string, string> argumentProperties = new Dictionary <string, string>(); foreach (GMXArgumentProperty property in Enum.GetValues(typeof(GMXArgumentProperty))) { argumentProperties.Add(GMXEnumString(property), ""); } // Local variables List <GMEvent>[] events = new List <GMEvent> [12]; List <GMPoint> physicsPoints = new List <GMPoint>(); // Create an xml reader using (XmlReader reader = XmlReader.Create(file)) { // Seek to content reader.MoveToContent(); // Read the GMX file while (reader.Read()) { // If the node is not an element, continue if (reader.NodeType != XmlNodeType.Element) { continue; } // Get the element name string nodeName = reader.Name; // If the element is an event if (nodeName.ToLower() == GMXEnumString(GMXObjectProperty.Event).ToLower()) { // Create a new event and get it's properties GMEvent gmEvent = new GMEvent(); int type = GMXInt(reader.GetAttribute(GMXEnumString(GMXEventProperty.Eventtype)), gmEvent.MainType); gmEvent.MainType = type; // If the event is a collision event, set the other name, else use subtype value if (gmEvent.MainType == (int)EventType.Collision) { gmEvent.OtherName = GMXString(reader.GetAttribute(GMXEnumString(GMXEventProperty.EName)), gmEvent.OtherName); } else { gmEvent.SubType = GMXInt(reader.GetAttribute(GMXEnumString(GMXEventProperty.ENumb)), gmEvent.SubType); } // Action list List <GMAction> actions = new List <GMAction>(); // Seek to content reader.MoveToContent(); // Create a reader for the actions using (XmlReader reader2 = reader.ReadSubtree()) { // Argument list List <GMArgument> arguments = new List <GMArgument>(); // Read in action properties while (reader2.Read()) { // If the node is not an element, continue if (reader.NodeType != XmlNodeType.Element) { continue; } // Get the element name string nodeName2 = reader2.Name; // If the node is an argument if (nodeName2.ToLower() == EnumString.GetEnumString(GMXObjectProperty.Argument).ToLower()) { // Seek to content reader2.MoveToContent(); // Create a reader for the arguments using (XmlReader reader3 = reader2.ReadSubtree()) { // Read in argument properties while (reader3.Read()) { // If the node is not an element, continue if (reader.NodeType != XmlNodeType.Element) { continue; } // Get the element name string nodeName3 = reader3.Name; // Read element reader3.Read(); // If the element value is null or empty, continue if (String.IsNullOrEmpty(reader3.Value)) { continue; } // Set the property value argumentProperties[nodeName3] = reader3.Value; } // Create a new argument GMArgument argument = new GMArgument(); argument.Type = GMXInt(argumentProperties[GMXEnumString(GMXArgumentProperty.Kind)], argument.Type); argument.Value = GMXString(argumentProperties[GMXEnumString(GMXArgumentProperty.String)], argument.Value); // Add argument to the list arguments.Add(argument); } } // Read element reader2.Read(); // If the element value is null or empty, continue if (String.IsNullOrEmpty(reader2.Value)) { continue; } // Set the property value actionProperties[nodeName2] = reader2.Value; } // Create a new action GMAction action = new GMAction(); action.LibraryId = GMXInt(actionProperties[GMXEnumString(GMXActionProperty.LibId)], action.LibraryId); action.ActionId = GMXInt(actionProperties[GMXEnumString(GMXActionProperty.Id)], action.ActionId); action.ActionKind = GMXInt(actionProperties[GMXEnumString(GMXActionProperty.Kind)], action.ActionKind); action.AllowRelative = GMXBool(actionProperties[GMXEnumString(GMXActionProperty.UseRelative)], action.AllowRelative); action.Question = GMXBool(actionProperties[GMXEnumString(GMXActionProperty.IsQuestion)], action.Question); action.CanApplyTo = GMXBool(actionProperties[GMXEnumString(GMXActionProperty.UseApplyTo)], action.CanApplyTo); action.ExecuteMode = GMXInt(actionProperties[GMXEnumString(GMXActionProperty.ExeType)], action.ExecuteMode); action.FunctionName = GMXString(actionProperties[GMXEnumString(GMXActionProperty.FunctionName)], action.FunctionName); action.ExecuteCode = GMXString(actionProperties[GMXEnumString(GMXActionProperty.CodeString)], action.ExecuteCode); action.AppliesToName = GMXString(actionProperties[GMXEnumString(GMXActionProperty.WhoName)], action.AppliesToName); action.AppliesTo = GetIdFromName(action.AppliesToName); action.Relative = GMXBool(actionProperties[GMXEnumString(GMXActionProperty.Relative)], action.Relative); action.Not = GMXBool(actionProperties[GMXEnumString(GMXActionProperty.IsNot)], action.Not); action.Arguments = arguments.ToArray(); // Add action to the list actions.Add(action); } // Set the events actions gmEvent.Actions = actions.ToArray(); // If the event type list has not been generated, create it if (events[type] == null) { events[type] = new List <GMEvent>(); } // Add the event of the event type events[type].Add(gmEvent); } // Read element reader.Read(); // If the element value is null or empty, continue if (String.IsNullOrEmpty(reader.Value)) { continue; } // Set the property value objectProperties[nodeName] = reader.Value; } } // Create a new object and set its properties GMObject obj = new GMObject(); obj.Id = GetIdFromName(name); obj.Name = name; obj.SpriteName = GMXString(objectProperties[GMXEnumString(GMXObjectProperty.SpriteName)], obj.SpriteName); obj.SpriteId = GetIdFromName(obj.SpriteName); obj.Solid = GMXBool(objectProperties[GMXEnumString(GMXObjectProperty.Solid)], obj.Solid); obj.Visible = GMXBool(objectProperties[GMXEnumString(GMXObjectProperty.Visible)], obj.Visible); obj.Depth = GMXInt(objectProperties[GMXEnumString(GMXObjectProperty.Depth)], obj.Depth); obj.Persistent = GMXBool(objectProperties[GMXEnumString(GMXObjectProperty.Persistent)], obj.Persistent); obj.ParentName = GMXString(objectProperties[GMXEnumString(GMXObjectProperty.ParentName)], obj.ParentName); obj.Parent = GetIdFromName(obj.ParentName); obj.MaskName = GMXString(objectProperties[GMXEnumString(GMXObjectProperty.MaskName)], obj.MaskName); obj.Mask = GetIdFromName(obj.MaskName); obj.Events = events; // Add the object objects.Add(obj); } // Return the list of objects return(objects); }