예제 #1
0
        /// <summary>
        /// Saves a GUIOMETRY.BIN data class to the disk.
        /// </summary>
        /// <param name="data">The GUIOMETRY data class.</param>
        /// <param name="filename">The filename to save as.</param>
        /// <returns>Whether the save was successful or not.</returns>
        public static bool Save(GUIOMETRY data, string filename)
        {
            // Collect data class metadata
            var textureMetadata = new Dictionary<byte, string>();

            // For each of these, only add the metadata if the source of the texture is not blank or null

            // Add font metadata
            foreach (var font in data.Fonts)
            {
                if (!string.IsNullOrEmpty(font.Value.Texture.Source))
                    textureMetadata.Add(GetTextureNameToID(font.Key), font.Value.Texture.Source);
            }

            // Add element metadata
            foreach (var element in data.Elements)
            {
                // In here element.Key is the internal name of the element, and element.Value is the ElementInfo object
                if (!string.IsNullOrEmpty(element.Value.Texture.Source))
                    textureMetadata.Add(GetTextureNameToID(element.Key), element.Value.Texture.Source);
            }

            // Construct the save data file
            var saveData = new List<byte>();

            saveData.Add(GUIOMETRY.VERSION); // Add format version byte

            // Add metadata
            foreach (var metadata in textureMetadata)
            {
                saveData.Add(metadata.Key); // Texture ID
                saveData.AddRange(UnicodeEncoding.Unicode.GetBytes(metadata.Value + "\0")); // Texture path with NULL char
            }

            saveData.Add(0); // End metadata byte

            // Add font data
            saveData.AddRange(data.Fonts["ChatFont"].GetBytes());
            saveData.AddRange(data.Fonts["SmallFont"].GetBytes());
            saveData.AddRange(data.Fonts["MediumFont"].GetBytes());
            saveData.AddRange(data.Fonts["HugeFont"].GetBytes());

            // Add element data and save
            saveData.AddRange(data.GetElementInfo("Button"));
            saveData.AddRange(data.GetElementInfo("Text"));
            saveData.AddRange(data.GetElementInfo("Check"));

            return Files.PutBinaryFile(filename, saveData.ToArray());
        }
예제 #2
0
        /// <summary>
        /// Reads a GUIOMETRY.BIN file into its data class.
        /// </summary>
        /// <param name="filename">The filename of the GUIOMETRY.BIN to read.</param>
        /// <returns>A GUIOMETRY data class with the contents of the file if it exists, null otherwise.</returns>
        public static GUIOMETRY Read(string filename)
        {
            // This function is still a WIP, implementing reading of GUIOMETRY.BIN files
            // The spec for this can be found inside of formats.md in the project root!

            if (!File.Exists(filename))
            {
                return null;
            }

            var guiometry = new GUIOMETRY(); // The result we're working on

            IList<byte> guiometryFile = Files.GetBinaryFile(filename);
            int currentIndex = 0; // Index of the byte in the array we're reading
            bool nextSection = false; // Set this to true to move onto the next section

            // Get the version before doing anything
            byte version = ByteParse.NextByte(guiometryFile, ref currentIndex);

            // Read file metadata (for the textures)
            while (!nextSection && currentIndex <= guiometryFile.Count - 1)
            {
                byte textureID = ByteParse.NextByte(guiometryFile, ref currentIndex);

                if (textureID == 0) // End of metadata
                {
                    nextSection = true;
                }
                else
                {
                    string textureName = GetTextureIDToName(textureID);
                    string textureSource = ByteParse.NextString(guiometryFile, ref currentIndex);

                    // Attempt to assign textures to relevant objects in their dictionaries.

                    if (File.Exists(textureSource))
                    {
                        if (textureName.EndsWith("Font")) // Assign inside of the Fonts Dictionary
                        {
                            guiometry.Fonts[textureName].Texture.Source = textureSource;
                            guiometry.Fonts[textureName].Texture.Data = Image.FromFile(textureSource);
                        }
                        else if (textureName.StartsWith("Button") ||
                            textureName.StartsWith("Text") ||
                            textureName.StartsWith("Check")) // Assign inside of the Elements Dictionary
                        {
                            guiometry.Elements[textureName].Texture.Source = textureSource;
                            guiometry.Elements[textureName].Texture.Data = Image.FromFile(textureSource);
                        }
                    }
                }
            }

            if (version == 1)
            {
                #region Version 1

                // This should be the fonts to look for (eg. ChatFont, SmallFont etc.) in the order they are
                // supposed to be according to the format
                string[] fonts = new string[] { "ChatFont", "SmallFont", "MediumFont", "HugeFont" };

                // Keep track of the current character being read (out of the number in the font)
                short currentChar = 0; // Make sure to reset this to 0 after reading a font or you will be shot

                // However many characters are in the font being read
                short charsInFont;

                // This should be the elements to look for (eg. Button, Text etc.) in the order they are
                // supposed to be according to the format
                string[] elements = new string[] { "Button", "Text", "Check" };

                // This should be the 'parts' of the elements to look for (eg. Body, Top, Side etc.) in the
                // order they are supposed to be according to the format
                string[] elementParts;

                #region Font Data

                foreach (string font in fonts)
                {
                    charsInFont = ByteParse.NextShort(guiometryFile, ref currentIndex);

                    while (currentChar++ < charsInFont)
                    {
                        char character = ByteParse.NextChar(guiometryFile, ref currentIndex);

                        guiometry.Fonts[font].AddNewCharacter(character,
                            NextCharacter(guiometryFile, ref currentIndex));
                    }

                    guiometry.Fonts[font].SpacingWidth = ByteParse.NextByte(guiometryFile, ref currentIndex);
                    guiometry.Fonts[font].LineHeight = ByteParse.NextByte(guiometryFile, ref currentIndex);

                    currentChar = 0;
                }

                #endregion

                #region Element Data

                foreach (string element in elements)
                {
                    // Set up the parts to look for...
                    if (element == "Button" || element == "Text")
                        elementParts = new string[] { "Top", "Side", "EdgeSE", "EdgeSW" };
                    else // element == "CheckBox"
                        elementParts = new string[] { "Top", "Side", "EdgeSE", "EdgeSW", "Tick" };

                    foreach (string part in elementParts)
                    {
                        if (part == "Side" || part == "EdgeSE" || part == "EdgeSW" || part == "Tick")
                            guiometry.Elements[element + part].XOffset = ByteParse.NextSByte(guiometryFile, ref currentIndex);

                        if (part == "Top" || part == "EdgeSE" || part == "EdgeSW" || part == "Tick")
                            guiometry.Elements[element + part].YOffset = ByteParse.NextSByte(guiometryFile, ref currentIndex);
                    }

                    // Read the element details too
                    if (element == "Button")
                    {
                        guiometry.ButtonCentredText = ByteParse.NextBool(guiometryFile, ref currentIndex);
                        guiometry.ButtonOffsetTop = ByteParse.NextSByte(guiometryFile, ref currentIndex);
                        guiometry.ButtonOffsetLeft = ByteParse.NextSByte(guiometryFile, ref currentIndex);
                    }
                    else if (element == "Text")
                    {
                        guiometry.TextCentredText = ByteParse.NextBool(guiometryFile, ref currentIndex);
                        guiometry.TextOffsetTop = ByteParse.NextSByte(guiometryFile, ref currentIndex);
                        guiometry.TextOffsetLeft = ByteParse.NextSByte(guiometryFile, ref currentIndex);
                    }
                }

                #endregion

                #endregion
            }

            return guiometry;
        }