Example #1
0
        // This reads the next token and sets an integral value, returns false when failed
        private bool ReadTokenInt(TexturesParser parser, string propertyname, out int value)
        {
            // Next token is the property value to set
            parser.SkipWhitespace(true);
            string strvalue = parser.ReadToken();

            if (!string.IsNullOrEmpty(strvalue))
            {
                // Try parsing as value
                if (!int.TryParse(strvalue, NumberStyles.Integer, CultureInfo.InvariantCulture, out value))
                {
                    parser.ReportError("Expected integral value for property '" + propertyname + "'");
                    return(false);
                }
                else
                {
                    // Success
                    return(true);
                }
            }
            else
            {
                // Can't find the property value!
                parser.ReportError("Expected a value for property '" + propertyname + "'");
                value = 0;
                return(false);
            }
        }
        //mxd. This reads the next token and sets a string value, returns false when failed
        private static bool ReadTokenString(TexturesParser parser, string propertyname, out string value)
        {
            parser.SkipWhitespace(true);
            value = parser.StripTokenQuotes(parser.ReadToken());

            if (string.IsNullOrEmpty(value))
            {
                // Can't find the property value!
                parser.ReportError("Expected a value for property \"" + propertyname + "\"");
                return(false);
            }

            return(true);
        }
        // This reads the next token and sets a floating point value, returns false when failed
        private static bool ReadTokenFloat(TexturesParser parser, string propertyname, out float value)
        {
            // Next token is the property value to set
            parser.SkipWhitespace(true);
            string strvalue = parser.ReadToken();

            if (!string.IsNullOrEmpty(strvalue))
            {
                // Try parsing as value
                if (!float.TryParse(strvalue, NumberStyles.Float, CultureInfo.InvariantCulture, out value))
                {
                    parser.ReportError("Expected numeric value for property \"" + propertyname + "\"");
                    return(false);
                }
                // Success
                return(true);
            }

            // Can't find the property value!
            parser.ReportError("Expected a value for property \"" + propertyname + "\"");
            value = 0.0f;
            return(false);
        }
Example #4
0
        // Constructor
        internal TextureStructure(TexturesParser parser, string typename)
        {
            string tokenstr;

            // Initialize
            this.typename = typename;
            patches       = new List <PatchStructure>(4);
            xscale        = 0.0f;
            yscale        = 0.0f;

            // There should be 3 tokens separated by 2 commas now:
            // Name, Width, Height

            // First token is the class name
            parser.SkipWhitespace(true);
            name = parser.StripTokenQuotes(parser.ReadToken());
            if (string.IsNullOrEmpty(name))
            {
                parser.ReportError("Expected texture or sprite name");
                return;
            }

            // Now we should find a comma
            parser.SkipWhitespace(true);
            tokenstr = parser.ReadToken();
            if (tokenstr != ",")
            {
                parser.ReportError("Expected a comma");
                return;
            }

            // Next is the texture width
            parser.SkipWhitespace(true);
            tokenstr = parser.ReadToken();
            if (string.IsNullOrEmpty(tokenstr) || !int.TryParse(tokenstr, NumberStyles.Integer, CultureInfo.InvariantCulture, out width))
            {
                parser.ReportError("Expected width in pixels");
                return;
            }

            // Now we should find a comma again
            parser.SkipWhitespace(true);
            tokenstr = parser.ReadToken();
            if (tokenstr != ",")
            {
                parser.ReportError("Expected a comma");
                return;
            }

            // Next is the texture height
            parser.SkipWhitespace(true);
            tokenstr = parser.ReadToken();
            if (string.IsNullOrEmpty(tokenstr) || !int.TryParse(tokenstr, NumberStyles.Integer, CultureInfo.InvariantCulture, out height))
            {
                parser.ReportError("Expected height in pixels");
                return;
            }

            // Next token should be the beginning of the texture scope
            parser.SkipWhitespace(true);
            tokenstr = parser.ReadToken();
            if (tokenstr != "{")
            {
                parser.ReportError("Expected begin of structure");
                return;
            }

            // Now parse the contents of texture structure
            while (parser.SkipWhitespace(true))
            {
                string token = parser.ReadToken();
                token = token.ToLowerInvariant();
                if (token == "xscale")
                {
                    if (!ReadTokenFloat(parser, token, out xscale))
                    {
                        return;
                    }
                }
                else if (token == "yscale")
                {
                    if (!ReadTokenFloat(parser, token, out yscale))
                    {
                        return;
                    }
                }
                else if (token == "worldpanning")
                {
                    worldpanning = true;
                }
                else if (token == "offset")
                {
                    // Read x offset
                    if (!ReadTokenInt(parser, token, out xoffset))
                    {
                        return;
                    }

                    // Now we should find a comma
                    parser.SkipWhitespace(true);
                    tokenstr = parser.ReadToken();
                    if (tokenstr != ",")
                    {
                        parser.ReportError("Expected a comma");
                        return;
                    }

                    // Read y offset
                    if (!ReadTokenInt(parser, token, out yoffset))
                    {
                        return;
                    }
                }
                else if (token == "patch")
                {
                    // Read patch structure
                    PatchStructure pt = new PatchStructure(parser);
                    if (parser.HasError)
                    {
                        break;
                    }

                    // Add the patch
                    patches.Add(pt);
                }
                else if (token == "}")
                {
                    // Actor scope ends here,
                    // break out of this parse loop
                    break;
                }
            }
        }
        }                                                 //mxd

        #endregion

        #region ================== Constructor / Disposer

        // Constructor
        internal PatchStructure(TexturesParser parser)
        {
            // Initialize
            alpha       = 1.0f;
            renderstyle = TexturePathRenderStyle.COPY;           //mxd
            blendstyle  = TexturePathBlendStyle.NONE;            //mxd

            // There should be 3 tokens separated by 2 commas now:
            // Name, Width, Height

            // First token is the class name
            parser.SkipWhitespace(true);
            name = parser.StripTokenQuotes(parser.ReadToken(false));             //mxd. Don't skip newline
            if (string.IsNullOrEmpty(name))
            {
                parser.ReportError("Expected patch name");
                return;
            }

            //mxd. Skip what must be skipped
            skip = (name.ToUpperInvariant() == IGNORE_SPRITE);

            //mxd
            name = name.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);

            // Now we should find a comma
            if (!parser.NextTokenIs(","))
            {
                return;                                      //mxd
            }
            // Next is the patch width
            parser.SkipWhitespace(true);
            string tokenstr = parser.ReadToken();

            if (string.IsNullOrEmpty(tokenstr) || !int.TryParse(tokenstr, NumberStyles.Integer, CultureInfo.InvariantCulture, out offsetx))
            {
                parser.ReportError("Expected offset in pixels");
                return;
            }

            // Now we should find a comma again
            if (!parser.NextTokenIs(","))
            {
                return;                                      //mxd
            }
            // Next is the patch height
            parser.SkipWhitespace(true);
            tokenstr = parser.ReadToken();
            if (string.IsNullOrEmpty(tokenstr) || !int.TryParse(tokenstr, NumberStyles.Integer, CultureInfo.InvariantCulture, out offsety))
            {
                parser.ReportError("Expected offset in pixels");
                return;
            }

            // Next token is the beginning of the texture scope. If not, then the patch info ends here.
            if (!parser.NextTokenIs("{", false))
            {
                return;                                             //mxd
            }
            // Now parse the contents of texture structure
            bool done = false;             //mxd

            while (!done && parser.SkipWhitespace(true))
            {
                string token = parser.ReadToken();
                token = token.ToLowerInvariant();

                switch (token)
                {
                case "flipx":
                    flipx = true;
                    break;

                case "flipy":
                    flipy = true;
                    break;

                case "alpha":
                    if (!ReadTokenFloat(parser, token, out alpha))
                    {
                        return;
                    }
                    alpha = General.Clamp(alpha, 0.0f, 1.0f);
                    break;

                case "rotate":
                    if (!ReadTokenInt(parser, token, out rotation))
                    {
                        return;
                    }
                    rotation = rotation % 360;                             //Coalesce multiples
                    if (rotation < 0)
                    {
                        rotation += 360;                                          //Force positive
                    }
                    if (rotation != 0 && rotation != 90 && rotation != 180 && rotation != 270)
                    {
                        parser.LogWarning("Unsupported rotation (" + rotation + ") in patch \"" + name + "\"");
                        rotation = 0;
                    }
                    break;

                case "style":                         //mxd
                    string s;
                    if (!ReadTokenString(parser, token, out s))
                    {
                        return;
                    }
                    int index = Array.IndexOf(renderStyles, s.ToLowerInvariant());
                    renderstyle = index == -1 ? TexturePathRenderStyle.COPY : (TexturePathRenderStyle)index;
                    break;

                case "blend":                         //mxd
                    parser.SkipWhitespace(false);
                    PixelColor color = new PixelColor();

                    // Blend <string color>[,<float alpha>] block?
                    token = parser.ReadToken(false);
                    if (!parser.ReadByte(token, ref color.r))
                    {
                        if (!ZDTextParser.GetColorFromString(token, ref color))
                        {
                            parser.ReportError("Unsupported patch blend definition");
                            return;
                        }
                    }
                    // That's Blend <int r>,<int g>,<int b>[,<float alpha>] block
                    else
                    {
                        if (!parser.SkipWhitespace(false) ||
                            !parser.NextTokenIs(",", false) || !parser.SkipWhitespace(false) || !parser.ReadByte(ref color.g) ||
                            !parser.NextTokenIs(",", false) || !parser.SkipWhitespace(false) || !parser.ReadByte(ref color.b))
                        {
                            parser.ReportError("Unsupported patch blend definition");
                            return;
                        }
                    }

                    // Alpha block?
                    float blendalpha = -1f;
                    parser.SkipWhitespace(false);
                    if (parser.NextTokenIs(",", false))
                    {
                        parser.SkipWhitespace(false);
                        if (!ReadTokenFloat(parser, token, out blendalpha))
                        {
                            parser.ReportError("Unsupported patch blend alpha value");
                            return;
                        }
                    }

                    // Blend may never be 0 when using the Tint effect
                    if (blendalpha > 0.0f)
                    {
                        color.a    = (byte)General.Clamp((int)(blendalpha * 255), 1, 254);
                        blendstyle = TexturePathBlendStyle.TINT;
                    }
                    else if (blendalpha < 0.0f)
                    {
                        color.a    = 255;
                        blendstyle = TexturePathBlendStyle.BLEND;
                    }
                    else
                    {
                        // Ignore Blend when alpha == 0
                        parser.LogWarning("Blend with zero alpha will be ignored by ZDoom");
                        break;
                    }

                    // Store the color
                    blendcolor = color;
                    break;

                case "}":
                    // Patch scope ends here,
                    // break out of this parse loop
                    done = true;
                    break;
                }
            }
        }
Example #6
0
        // Constructor
        internal TextureStructure(TexturesParser parser, string typename, string virtualpath)
        {
            // Initialize
            this.typename    = typename;
            this.virtualpath = virtualpath;
            patches          = new List <PatchStructure>(4);
            xscale           = 0.0f;
            yscale           = 0.0f;

            // There should be 3 tokens separated by 2 commas now:
            // Name, Width, Height

            // First token is the texture name
            parser.SkipWhitespace(true);
            name = parser.StripTokenQuotes(parser.ReadToken(false));             //mxd. Don't skip newline

            //mxd. It can also be "optional" keyword.
            if (name.ToLowerInvariant() == "optional")
            {
                optional = true;
                parser.SkipWhitespace(true);
                name = parser.StripTokenQuotes(parser.ReadToken(false));                 //mxd. Don't skip newline
            }

            if (string.IsNullOrEmpty(name))
            {
                parser.ReportError("Expected " + typename + " name");
                return;
            }

            // Now we should find a comma
            if (!parser.NextTokenIs(","))
            {
                return;                                      //mxd
            }
            // Next is the texture width
            parser.SkipWhitespace(true);
            string tokenstr = parser.ReadToken();

            if (string.IsNullOrEmpty(tokenstr) || !int.TryParse(tokenstr, NumberStyles.Integer, CultureInfo.InvariantCulture, out width))
            {
                parser.ReportError("Expected width in pixels");
                return;
            }

            // Now we should find a comma again
            if (!parser.NextTokenIs(","))
            {
                return;                                      //mxd
            }
            // Next is the texture height
            parser.SkipWhitespace(true);
            tokenstr = parser.ReadToken();
            if (string.IsNullOrEmpty(tokenstr) || !int.TryParse(tokenstr, NumberStyles.Integer, CultureInfo.InvariantCulture, out height))
            {
                parser.ReportError("Expected height in pixels");
                return;
            }

            // Next token should be the beginning of the texture scope
            if (!parser.NextTokenIs("{", false))            //mxd
            {
                parser.ReportError("Expected begin of structure");
                return;
            }

            // Now parse the contents of texture structure
            bool done = false;             //mxd

            while (!done && parser.SkipWhitespace(true))
            {
                string token = parser.ReadToken();
                token = token.ToLowerInvariant();

                switch (token)
                {
                case "xscale":
                    if (!ReadTokenFloat(parser, token, out xscale))
                    {
                        return;
                    }
                    break;

                case "yscale":
                    if (!ReadTokenFloat(parser, token, out yscale))
                    {
                        return;
                    }
                    break;

                case "worldpanning":
                    worldpanning = true;
                    break;

                case "nulltexture":                         //mxd
                    nulltexture = true;
                    break;

                case "offset":
                    // Read x offset
                    if (!ReadTokenInt(parser, token, out xoffset))
                    {
                        return;
                    }

                    // Now we should find a comma
                    if (!parser.NextTokenIs(","))
                    {
                        return;                                                      //mxd
                    }
                    // Read y offset
                    if (!ReadTokenInt(parser, token, out yoffset))
                    {
                        return;
                    }
                    break;

                case "patch":
                    // Read patch structure
                    PatchStructure pt = new PatchStructure(parser);
                    if (parser.HasError)
                    {
                        break;
                    }

                    // Add the patch
                    patches.Add(pt);
                    break;

                case "}":
                    // Actor scope ends here,
                    // break out of this parse loop
                    done = true;
                    break;
                }
            }
        }
Example #7
0
        // Constructor
        internal PatchStructure(TexturesParser parser)
        {
            string tokenstr;

            // Initialize
            alpha = 1.0f;

            // There should be 3 tokens separated by 2 commas now:
            // Name, Width, Height

            // First token is the class name
            parser.SkipWhitespace(true);
            name = parser.StripTokenQuotes(parser.ReadToken());
            if (string.IsNullOrEmpty(name))
            {
                parser.ReportError("Expected patch name");
                return;
            }

            // Now we should find a comma
            parser.SkipWhitespace(true);
            tokenstr = parser.ReadToken();
            if (tokenstr != ",")
            {
                parser.ReportError("Expected a comma");
                return;
            }

            // Next is the patch width
            parser.SkipWhitespace(true);
            tokenstr = parser.ReadToken();
            if (string.IsNullOrEmpty(tokenstr) || !int.TryParse(tokenstr, NumberStyles.Integer, CultureInfo.InvariantCulture, out offsetx))
            {
                parser.ReportError("Expected offset in pixels");
                return;
            }

            // Now we should find a comma again
            parser.SkipWhitespace(true);
            tokenstr = parser.ReadToken();
            if (tokenstr != ",")
            {
                parser.ReportError("Expected a comma");
                return;
            }

            // Next is the patch height
            parser.SkipWhitespace(true);
            tokenstr = parser.ReadToken();
            if (string.IsNullOrEmpty(tokenstr) || !int.TryParse(tokenstr, NumberStyles.Integer, CultureInfo.InvariantCulture, out offsety))
            {
                parser.ReportError("Expected offset in pixels");
                return;
            }

            // Next token is the beginning of the texture scope.
            // If not, then the patch info ends here.
            parser.SkipWhitespace(true);
            tokenstr = parser.ReadToken();
            if (tokenstr != "{")
            {
                // Rewind so this structure can be read again
                parser.DataStream.Seek(-tokenstr.Length - 1, SeekOrigin.Current);
                return;
            }

            // Now parse the contents of texture structure
            while (parser.SkipWhitespace(true))
            {
                string token = parser.ReadToken();
                token = token.ToLowerInvariant();
                if (token == "flipx")
                {
                    flipx = true;
                }
                else if (token == "flipy")
                {
                    flipy = true;
                }
                else if (token == "alpha")
                {
                    if (!ReadTokenFloat(parser, token, out alpha))
                    {
                        return;
                    }
                    alpha = General.Clamp(alpha, 0.0f, 1.0f);
                }
                else if (token == "}")
                {
                    // Patch scope ends here,
                    // break out of this parse loop
                    break;
                }
            }
        }