- parseBlendTable

This commit is contained in:
Christoph Oelckers 2021-04-13 19:22:28 +02:00
parent 01f93f4cca
commit 82a0b0502b
2 changed files with 98 additions and 208 deletions

View file

@ -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;

View file

@ -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];
}
}
}