- palookup.

This commit is contained in:
Christoph Oelckers 2021-04-13 20:33:21 +02:00
parent bb119fa928
commit aaad546729
7 changed files with 203 additions and 297 deletions

View file

@ -200,10 +200,6 @@ enum {
EXTERN int32_t g_visibility;
// blendtable[1] to blendtable[numalphatabs] are considered to be
// alpha-blending tables:
EXTERN uint8_t numalphatabs;
EXTERN vec2_t windowxy1, windowxy2;
// The maximum tile offset ever used in any tiled parallaxed multi-sky.

View file

@ -1397,290 +1397,8 @@ static int32_t defsparser(scriptfile *script)
}
break;
case T_PALOOKUP:
{
FScanner::SavedPos blockend;
int32_t id;
static const tokenlist subtokens[] =
{
{ "raw", T_RAW },
{ "copy", T_COPY },
{ "undef", T_UNDEF },
{ "fogpal", T_FOGPAL },
{ "makepalookup", T_MAKEPALOOKUP },
{ "floorpal", T_FLOORPAL },
{ "nofloorpal", T_NOFLOORPAL },
};
if (scriptfile_getsymbol(script,&id))
break;
if (scriptfile_getbraces(script,&blockend))
break;
if ((unsigned)id >= MAXPALOOKUPS)
{
pos.Message(MSG_ERROR, "palookup: Invalid pal number");
scriptfile_setposition(script, blockend);
break;
}
int didLoadShade = 0;
while (!scriptfile_endofblock(script, blockend))
{
int32_t token = getatoken(script,subtokens,countof(subtokens));
switch (token)
{
case T_RAW:
{
FScanner::SavedPos subblockend;
static const tokenlist rawsubtokens[] =
{
{ "file", T_FILE },
{ "offset", T_OFFSET },
{ "noshades", T_NOSHADES },
};
if (scriptfile_getbraces(script,&subblockend))
break;
FString fn;
int32_t offset = 0;
int32_t length = 256*32; // hardcoding 32 instead of numshades
while (!scriptfile_endofblock(script, subblockend))
{
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;
}
case T_NOSHADES:
{
length = 256;
break;
}
default:
break;
}
}
if (fn.IsEmpty())
{
pos.Message(MSG_ERROR, "palookup: No filename provided");
break;
}
if (offset < 0)
{
pos.Message(MSG_ERROR, "palookup: Invalid file offset");
break;
}
FileReader fil = fileSystem.OpenFileReader(fn);
if (!fil.isOpen())
{
pos.Message(MSG_ERROR, "palookup: Failed opening \"%s\"", fn.GetChars());
break;
}
if (fil.Seek(offset, FileReader::SeekSet) < 0)
{
pos.Message(MSG_ERROR, "palookup: Seek failed");
break;
}
auto palookupbuf = fil.Read();
if (palookupbuf.Size() < 256)
{
pos.Message(MSG_ERROR, "palookup: Read failed");
break;
}
if (palookupbuf.Size() >= 256*32)
{
didLoadShade = 1;
numshades = 32;
lookups.setTable(id, palookupbuf.Data());
}
else
{
if (!(paletteloaded & PALETTE_SHADE))
{
pos.Message(MSG_ERROR, "palookup: Shade tables not loaded");
break;
}
lookups.makeTable(id, palookupbuf.Data(), 0,0,0, lookups.tables[id].noFloorPal);
}
break;
}
case T_COPY:
{
int32_t source;
scriptfile_getsymbol(script,&source);
if ((unsigned)source >= MAXPALOOKUPS || source == id)
{
pos.Message(MSG_ERROR, "palookup: Invalid source pal number");
break;
}
if (source == 0 && !(paletteloaded & PALETTE_SHADE))
{
pos.Message(MSG_ERROR, "palookup: Shade tables not loaded");
break;
}
if (lookups.checkTable(source) || id > 0) // do not overwrite the base with an empty table.
lookups.copyTable(id, source);
didLoadShade = 1;
break;
}
case T_FOGPAL:
{
FScanner::SavedPos subblockend;
static const tokenlist fogpaltokens[] =
{
{ "red", T_RED }, { "r", T_RED },
{ "green", T_GREEN }, { "g", T_GREEN },
{ "blue", T_BLUE }, { "b", T_BLUE },
};
int32_t red = 0, green = 0, blue = 0;
if (scriptfile_getbraces(script,&subblockend))
break;
while (!scriptfile_endofblock(script, subblockend))
{
switch (getatoken(script, fogpaltokens, countof(fogpaltokens)))
{
case T_RED:
scriptfile_getnumber(script,&red);
red = clamp(red, 0, 255);
break;
case T_GREEN:
scriptfile_getnumber(script,&green);
green = clamp(green, 0, 255);
break;
case T_BLUE:
scriptfile_getnumber(script,&blue);
blue = clamp(blue, 0, 255);
break;
}
}
if (!(paletteloaded & PALETTE_SHADE))
{
pos.Message(MSG_ERROR, "palookup: Shade tables not loaded");
break;
}
lookups.makeTable(id, NULL, red, green, blue, 1);
break;
}
case T_MAKEPALOOKUP:
{
FScanner::SavedPos subblockend;
static const tokenlist makepalookuptokens[] =
{
{ "red", T_RED }, { "r", T_RED },
{ "green", T_GREEN }, { "g", T_GREEN },
{ "blue", T_BLUE }, { "b", T_BLUE },
{ "remappal", T_REMAPPAL },
{ "remapself", T_REMAPSELF },
};
int32_t red = 0, green = 0, blue = 0;
int32_t remappal = -1;
if (scriptfile_getbraces(script,&subblockend))
break;
while (!scriptfile_endofblock(script, subblockend))
{
switch (getatoken(script, makepalookuptokens, countof(makepalookuptokens)))
{
case T_RED:
scriptfile_getnumber(script,&red);
red = clamp(red, 0, 255);
break;
case T_GREEN:
scriptfile_getnumber(script,&green);
green = clamp(green, 0, 255);
break;
case T_BLUE:
scriptfile_getnumber(script,&blue);
blue = clamp(blue, 0, 255);
break;
case T_REMAPPAL:
scriptfile_getsymbol(script,&remappal);
break;
case T_REMAPSELF:
remappal = id;
break;
}
}
if ((unsigned)remappal >= MAXPALOOKUPS)
{
pos.Message(MSG_ERROR, "palookup: Invalid remappal");
break;
}
if (!(paletteloaded & PALETTE_SHADE))
{
pos.Message(MSG_ERROR, "palookup: Shade tables not loaded");
break;
}
lookups.makeTable(id, NULL, red, green, blue, lookups.tables[id].noFloorPal);
break;
}
case T_NOFLOORPAL:
{
lookups.tables[id].noFloorPal = 1;
break;
}
case T_FLOORPAL:
{
lookups.tables[id].noFloorPal = 0;
break;
}
case T_UNDEF:
{
lookups.clearTable(id);
didLoadShade = 0;
if (id == 0)
paletteloaded &= ~PALETTE_SHADE;
break;
}
default:
break;
}
}
if (didLoadShade && id == 0)
{
paletteloaded |= PALETTE_SHADE;
}
}
break;
parsePalookup(*script, pos);
break;
case T_BLENDTABLE:
parseBlendTable(*script, pos);
break;

View file

@ -113,4 +113,7 @@ inline int shadeToLight(int shade)
return PalEntry(255, light, light, light);
}
inline void copyfloorpal(spritetype* spr, const sectortype* sect)
{
if (!lookups.noFloorPal(sect->floorpal)) spr->pal = sect->floorpal;
}

View file

@ -1061,3 +1061,191 @@ void parseNumAlphaTabs(FScanner& sc, FScriptPosition& pos)
}
}
//===========================================================================
//
// sadly this looks broken by design with its hard coded 32 shades...
//
//===========================================================================
static void parsePalookupRaw(FScanner& sc, FScriptPosition& pos, int id, int& didLoadShade)
{
FScanner::SavedPos blockend;
if (sc.StartBraces(&blockend)) return;
FString fn;
int32_t offset = 0;
int32_t length = 256 * 32; // hardcoding 32 instead of numshades
while (!sc.FoundEndBrace(blockend))
{
sc.MustGetString();
if (sc.Compare("file")) sc.GetString(fn);
else if (sc.Compare("offset")) sc.GetNumber(offset);
else if (sc.Compare("noshades")) length = 256;
}
if (fn.IsEmpty())
{
pos.Message(MSG_ERROR, "palookup: No filename provided");
}
else if (offset < 0)
{
pos.Message(MSG_ERROR, "palookup: Invalid file offset %d", offset);
}
else
{
FileReader fil = fileSystem.OpenFileReader(fn);
if (!fil.isOpen())
{
pos.Message(MSG_ERROR, "palookup: Failed opening \"%s\"", fn.GetChars());
}
else if (fil.Seek(offset, FileReader::SeekSet) < 0)
{
pos.Message(MSG_ERROR, "palookup: Seek failed");
}
else
{
auto palookupbuf = fil.Read();
if (palookupbuf.Size() < 256)
{
pos.Message(MSG_ERROR, "palookup: Read failed");
}
else if (palookupbuf.Size() >= 256 * 32)
{
didLoadShade = 1;
numshades = 32;
lookups.setTable(id, palookupbuf.Data());
}
else
{
if (!(paletteloaded & PALETTE_SHADE))
{
pos.Message(MSG_ERROR, "palookup: Shade tables not loaded");
}
else
lookups.makeTable(id, palookupbuf.Data(), 0, 0, 0, lookups.tables[id].noFloorPal);
}
}
}
}
static void parsePalookupFogpal(FScanner& sc, FScriptPosition& pos, int id)
{
FScanner::SavedPos blockend;
if (sc.StartBraces(&blockend)) return;
int red = 0, green = 0, blue = 0;
while (!sc.FoundEndBrace(blockend))
{
sc.MustGetString();
if (sc.Compare({ "r", "red" })) sc.GetNumber(red);
else if (sc.Compare({ "g", "green" })) sc.GetNumber(green);
else if (sc.Compare({ "b", "blue" })) sc.GetNumber(blue);
}
red = clamp(red, 0, 255);
green = clamp(green, 0, 255);
blue = clamp(blue, 0, 255);
if (!(paletteloaded & PALETTE_SHADE))
{
pos.Message(MSG_ERROR, "palookup: Shade tables not loaded");
}
else
lookups.makeTable(id, nullptr, red, green, blue, 1);
}
static void parsePalookupMakePalookup(FScanner& sc, FScriptPosition& pos, int id, int& didLoadShade)
{
FScanner::SavedPos blockend;
if (sc.StartBraces(&blockend)) return;
int red = 0, green = 0, blue = 0;
int remappal = -1;
while (!sc.FoundEndBrace(blockend))
{
sc.MustGetString();
if (sc.Compare({ "r", "red" })) sc.GetNumber(red);
else if (sc.Compare({ "g", "green" })) sc.GetNumber(green);
else if (sc.Compare({ "b", "blue" })) sc.GetNumber(blue);
else if (sc.Compare("remappal")) sc.GetNumber(remappal, true);
else if (sc.Compare("remapself")) remappal = id;
}
red = clamp(red, 0, 255);
green = clamp(green, 0, 255);
blue = clamp(blue, 0, 255);
if ((unsigned)remappal >= MAXPALOOKUPS)
{
pos.Message(MSG_ERROR, "palookup: Invalid remappal %d", remappal);
}
else if (!(paletteloaded & PALETTE_SHADE))
{
pos.Message(MSG_ERROR, "palookup: Shade tables not loaded");
}
else
lookups.makeTable(id, nullptr, red, green, blue, lookups.tables[id].noFloorPal);
}
void parsePalookup(FScanner& sc, FScriptPosition& pos)
{
FScanner::SavedPos blockend;
int id;
int didLoadShade = 0;
if (!sc.GetNumber(id, true)) return;
if (sc.StartBraces(&blockend)) return;
if ((unsigned)id >= MAXPALOOKUPS)
{
pos.Message(MSG_ERROR, "palookup: Invalid pal number %d", id);
sc.RestorePos(blockend);
return;
}
while (!sc.FoundEndBrace(blockend))
{
sc.MustGetString();
if (sc.Compare("raw")) parsePalookupRaw(sc, pos, id, didLoadShade);
else if (sc.Compare("fogpal")) parsePalookupFogpal(sc, pos, id);
else if (sc.Compare("makepalookup")) parsePalookupMakePalookup(sc, pos, id, didLoadShade);
else if (sc.Compare("floorpal")) lookups.tables[id].noFloorPal = 0;
else if (sc.Compare("nofloorpal")) lookups.tables[id].noFloorPal = 1;
else if (sc.Compare("copy"))
{
int source;
sc.GetNumber(source, true);
if ((unsigned)source >= MAXPALOOKUPS || source == id)
{
pos.Message(MSG_ERROR, "palookup: Invalid source pal number %d", source);
}
else if (source == 0 && !(paletteloaded & PALETTE_SHADE))
{
pos.Message(MSG_ERROR, "palookup: Shade tables not loaded");
}
else
{
// do not overwrite the base with an empty table.
if (lookups.checkTable(source) || id > 0) lookups.copyTable(id, source);
didLoadShade = 1;
}
}
else if (sc.Compare("undef"))
{
lookups.clearTable(id);
didLoadShade = 0;
if (id == 0) paletteloaded &= ~PALETTE_SHADE;
}
}
if (didLoadShade && id == 0)
{
paletteloaded |= PALETTE_SHADE;
}
}

View file

@ -39,6 +39,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "v_video.h"
#include "v_font.h"
#include "hw_voxels.h"
#include "gamefuncs.h"
#include "glbackend/glbackend.h"
BEGIN_BLD_NS
@ -426,7 +427,7 @@ static void viewApplyDefaultPal(tspritetype *pTSprite, sectortype const *pSector
XSECTOR const *pXSector = nXSector >= 0 ? &xsector[nXSector] : NULL;
if (pXSector && pXSector->color && (VanillaMode() || pSector->floorpal != 0))
{
pTSprite->pal = pSector->floorpal;
copyfloorpal(pTSprite, pSector);
}
}
@ -759,7 +760,7 @@ void viewProcessSprites(spritetype* tsprite, int& spritesortcnt, int32_t cX, int
}
}
if (pXSector && pXSector->color) pTSprite->pal = pSector->floorpal;
if (pXSector && pXSector->color) copyfloorpal(pTSprite, pSector);
if (powerupCheck(gView, kPwUpBeastVision) > 0) pTSprite->shade = -128;
if (IsPlayerSprite(pTSprite)) {

View file

@ -438,7 +438,7 @@ void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int
PALONLY:
if (sector[sect].floorpal)
t->pal = sector[sect].floorpal;
copyfloorpal(t, &sector[sect]);
if (!h->GetOwner()) continue;
@ -484,7 +484,7 @@ void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int
t->shade -= 6;
if (sector[sect].floorpal)
t->pal = sector[sect].floorpal;
copyfloorpal(t, &sector[sect]);
break;
case WATERBUBBLE:
@ -496,7 +496,7 @@ void animatesprites_d(spritetype* tsprite, int& spritesortcnt, int x, int y, int
default:
if (sector[sect].floorpal)
t->pal = sector[sect].floorpal;
copyfloorpal(t, &sector[sect]);
break;
}

View file

@ -487,7 +487,7 @@ void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int
PALONLY:
if (sector[sect].floorpal)
t->pal = sector[sect].floorpal;
copyfloorpal(t, &sector[sect]);
if (!h->GetOwner()) continue;
@ -619,7 +619,7 @@ void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int
else t->picnum += h->temp_data[0];
if (sector[sect].floorpal)
t->pal = sector[sect].floorpal;
copyfloorpal(t, &sector[sect]);
break;
case WATERBUBBLE:
@ -632,7 +632,7 @@ void animatesprites_r(spritetype* tsprite, int& spritesortcnt, int x, int y, int
default_case:
if (sector[sect].floorpal)
t->pal = sector[sect].floorpal;
copyfloorpal(t, &sector[sect]);
break;
}