diff --git a/source/build/src/defs.cpp b/source/build/src/defs.cpp index 9780286a9..50c34e016 100644 --- a/source/build/src/defs.cpp +++ b/source/build/src/defs.cpp @@ -1679,210 +1679,8 @@ static int32_t defsparser(scriptfile *script) } break; case T_BLENDTABLE: - { - FScanner::SavedPos blockend; - int32_t id; - - static const tokenlist subtokens[] = - { - { "raw", T_RAW }, - { "glblend", T_GLBLEND }, - { "copy", T_COPY }, - { "undef", T_UNDEF }, - }; - - if (scriptfile_getsymbol(script,&id)) - break; - if (scriptfile_getbraces(script,&blockend)) - break; - - if ((unsigned)id >= MAXBLENDTABS) - { - pos.Message(MSG_ERROR, "blendtable: Invalid blendtable number"); - scriptfile_setposition(script, blockend); - break; - } - while (!scriptfile_endofblock(script, blockend)) - { - int32_t token = getatoken(script,subtokens,countof(subtokens)); - switch (token) - { - case T_RAW: - { - FScanner::SavedPos rawblockend; - - static const tokenlist rawsubtokens[] = - { - { "file", T_FILE }, - { "offset", T_OFFSET }, - }; - - if (scriptfile_getbraces(script,&rawblockend)) - break; - - FString fn; - int32_t offset = 0; - - while (!scriptfile_endofblock(script, rawblockend)) - { - int32_t token = getatoken(script,rawsubtokens,countof(rawsubtokens)); - switch (token) - { - case T_FILE: - { - scriptfile_getstring(script,&fn); - break; - } - case T_OFFSET: - { - scriptfile_getnumber(script,&offset); - break; - } - default: - break; - } - } - - if (fn.IsEmpty()) - { - pos.Message(MSG_ERROR, "blendtable: No filename provided"); - break; - } - - if (offset < 0) - { - pos.Message(MSG_ERROR, "blendtable: Invalid file offset"); - break; - } - - FileReader fil = fileSystem.OpenFileReader(fn); - if (!fil.isOpen()) - { - pos.Message(MSG_ERROR, "blendtable: Failed opening \"%s\"", fn.GetChars()); - break; - } - - if (fil.Seek(offset, FileReader::SeekSet) < 0) - { - pos.Message(MSG_ERROR, "blendtable: Seek failed"); - break; - } - - auto blendbuf = fil.Read(); - if (blendbuf.Size() < 256*256) - { - pos.Message(MSG_ERROR, "blendtable: Read failed"); - break; - } - break; - } - case T_COPY: - { - int32_t source; - scriptfile_getsymbol(script,&source); - - if ((unsigned)source >= MAXBLENDTABS || source == id) - { - pos.Message(MSG_ERROR, "blendtable: Invalid source blendtable number"); - break; - } - glblend[id] = glblend[source]; - break; - } - case T_UNDEF: - { - glblend[id] = defaultglblend; - break; - } - case T_GLBLEND: - { - FScanner::SavedPos glblendblockend; - - static const tokenlist glblendtokens[] = - { - { "forward", T_FORWARD }, - { "reverse", T_REVERSE }, - { "both", T_BOTH }, - }; - - if (scriptfile_getbraces(script,&glblendblockend)) - break; - - glblend_t * const glb = glblend + id; - *glb = nullglblend; - - while (!scriptfile_endofblock(script, glblendblockend)) - { - int32_t glblendtoken = getatoken(script,glblendtokens,countof(glblendtokens)); - switch (glblendtoken) - { - case T_FORWARD: - case T_REVERSE: - case T_BOTH: - { - FScanner::SavedPos glblenddefblockend; - - static const tokenlist glblenddeftokens[] = - { - { "src", T_SRC }, - { "sfactor", T_SRC }, - { "top", T_SRC }, - - { "dst", T_DST }, - { "dfactor", T_DST }, - { "bottom", T_DST }, - - { "alpha", T_ALPHA }, - }; - - if (scriptfile_getbraces(script,&glblenddefblockend)) - break; - - glblenddef_t * const glbdef = glb->def + (glblendtoken == T_REVERSE); - while (!scriptfile_endofblock(script, glblenddefblockend)) - { - int32_t glblenddeftoken = getatoken(script,glblenddeftokens,countof(glblenddeftokens)); - switch (glblenddeftoken) - { - case T_SRC: - case T_DST: - { - uint8_t * const factor = glblenddeftoken == T_SRC ? &glbdef->src : &glbdef->dst; - if (script->Compare("ZERO")) *factor = STYLEALPHA_Zero; - else if (script->Compare("ONE")) *factor = STYLEALPHA_One; - else if (script->Compare("SRC_COLOR")) *factor = STYLEALPHA_SrcCol; - else if (script->Compare("ONE_MINUS_SRC_COLOR")) *factor = STYLEALPHA_InvSrcCol; - else if (script->Compare("SRC_ALPHA")) *factor = STYLEALPHA_Src; - else if (script->Compare("ONE_MINUS_SRC_ALPHA")) *factor = STYLEALPHA_InvSrc; - else if (script->Compare("DST_ALPHA")) *factor = STYLEALPHA_Dst; - else if (script->Compare("ONE_MINUS_DST_ALPHA")) *factor = STYLEALPHA_InvDst; - else if (script->Compare("DST_COLOR")) *factor = STYLEALPHA_DstCol; - else if (script->Compare("ONE_MINUS_DST_COLOR")) *factor = STYLEALPHA_InvDstCol; - else script->ScriptMessage("Unknown blend operation %s", script->String); - break; - } - case T_ALPHA: - { - double tempalpha; - scriptfile_getdouble(script,&tempalpha); - glbdef->alpha = (float)tempalpha; - break; - } - } - } - if (glblendtoken == T_BOTH) - glb->def[1] = *glbdef; - break; - } - } - } - } - default: - break; - } - } - } - break; + parseBlendTable(*script, pos); + break; case T_NUMALPHATABS: { int32_t value; diff --git a/source/core/parsefuncs.h b/source/core/parsefuncs.h index eedcf7fa4..96621d55e 100644 --- a/source/core/parsefuncs.h +++ b/source/core/parsefuncs.h @@ -872,10 +872,7 @@ void parseEmptyBlock(FScanner& sc, FScriptPosition& pos) FScanner::SavedPos blockend; if (sc.StartBraces(&blockend)) return; - while (!sc.FoundEndBrace(blockend)) - { - sc.MustGetString(); - } + sc.RestorePos(blockend); } //=========================================================================== @@ -946,3 +943,98 @@ void parseArtFile(FScanner& sc, FScriptPosition& pos) else if (tile >= 0 && ValidateTilenum("artfile", tile, pos)) TileFiles.LoadArtFile(file, nullptr, tile); } + +//=========================================================================== +// +// this is only left in for compatibility purposes. +// There's way better methods to handle translucency. +// +//=========================================================================== + +static void parseBlendTableGlBlend(FScanner& sc, FScriptPosition& pos, int id) +{ + FScanner::SavedPos blockend; + FString file; + + if (sc.StartBraces(&blockend)) return; + + glblend_t* const glb = glblend + id; + *glb = nullglblend; + + while (!sc.FoundEndBrace(blockend)) + { + int which = 0; + sc.MustGetString(); + if (sc.Compare("forward")) which = 1; + else if (sc.Compare("reverse")) which = 2; + else if (sc.Compare("both")) which = 3; + else continue; + + FScanner::SavedPos blockend2; + + if (sc.StartBraces(&blockend2)) return; + glblenddef_t bdef{}; + while (!sc.FoundEndBrace(blockend2)) + { + int whichb = 0; + sc.MustGetString(); + if (sc.Compare({ "src", "sfactor", "top" })) whichb = 0; + else if (sc.Compare({ "dst", "dfactor", "bottom" })) whichb = 1; + else if (sc.Compare("alpha")) + { + sc.GetFloat(true); + bdef.alpha = (float)sc.Float; + continue; + } + uint8_t* const factor = whichb == 0 ? &bdef.src : &bdef.dst; + if (sc.Compare("ZERO")) *factor = STYLEALPHA_Zero; + else if (sc.Compare("ONE")) *factor = STYLEALPHA_One; + else if (sc.Compare("SRC_COLOR")) *factor = STYLEALPHA_SrcCol; + else if (sc.Compare("ONE_MINUS_SRC_COLOR")) *factor = STYLEALPHA_InvSrcCol; + else if (sc.Compare("SRC_ALPHA")) *factor = STYLEALPHA_Src; + else if (sc.Compare("ONE_MINUS_SRC_ALPHA")) *factor = STYLEALPHA_InvSrc; + else if (sc.Compare("DST_ALPHA")) *factor = STYLEALPHA_Dst; + else if (sc.Compare("ONE_MINUS_DST_ALPHA")) *factor = STYLEALPHA_InvDst; + else if (sc.Compare("DST_COLOR")) *factor = STYLEALPHA_DstCol; + else if (sc.Compare("ONE_MINUS_DST_COLOR")) *factor = STYLEALPHA_InvDstCol; + else sc.ScriptMessage("Unknown blend operation %s", sc.String); + } + if (which & 1) glb->def[0] = bdef; + if (which & 2) glb->def[1] = bdef; + } +} + +void parseBlendTable(FScanner& sc, FScriptPosition& pos) +{ + FScanner::SavedPos blockend; + int id; + + if (!sc.GetNumber(id, true)) return; + + if (sc.StartBraces(&blockend)) return; + + if ((unsigned)id >= MAXBLENDTABS) + { + pos.Message(MSG_ERROR, "blendtable: Invalid blendtable number %d", id); + sc.RestorePos(blockend); + return; + } + + while (!sc.FoundEndBrace(blockend)) + { + sc.MustGetString(); + if (sc.Compare("raw")) parseEmptyBlock(sc, pos); // Raw translucency map for the software renderer. We have no use for this. + else if (sc.Compare("glblend")) parseBlendTableGlBlend(sc, pos, id); + else if (sc.Compare("undef")) glblend[id] = defaultglblend; + else if (sc.Compare("copy")) + { + sc.GetNumber(true); + + if ((unsigned)sc.Number >= MAXBLENDTABS || sc.Number == id) + { + pos.Message(MSG_ERROR, "blendtable: Invalid source blendtable number %d in copy", sc.Number); + } + else glblend[id] = glblend[sc.Number]; + } + } +}