diff --git a/source/build/include/build.h b/source/build/include/build.h index f9ddbf45b..c6c701c34 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -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. diff --git a/source/build/src/defs.cpp b/source/build/src/defs.cpp index 484822ce3..9c480446b 100644 --- a/source/build/src/defs.cpp +++ b/source/build/src/defs.cpp @@ -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; diff --git a/source/core/gamefuncs.h b/source/core/gamefuncs.h index 2d0989aa1..ce0b3e54a 100644 --- a/source/core/gamefuncs.h +++ b/source/core/gamefuncs.h @@ -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; +} diff --git a/source/core/parsefuncs.h b/source/core/parsefuncs.h index 35ac7ab6f..ceb041b29 100644 --- a/source/core/parsefuncs.h +++ b/source/core/parsefuncs.h @@ -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; + } +} diff --git a/source/games/blood/src/animatesprite.cpp b/source/games/blood/src/animatesprite.cpp index 949052ceb..eaf4de715 100644 --- a/source/games/blood/src/animatesprite.cpp +++ b/source/games/blood/src/animatesprite.cpp @@ -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)) { diff --git a/source/games/duke/src/animatesprites_d.cpp b/source/games/duke/src/animatesprites_d.cpp index 29523455d..e014bc8be 100644 --- a/source/games/duke/src/animatesprites_d.cpp +++ b/source/games/duke/src/animatesprites_d.cpp @@ -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, §or[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, §or[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, §or[sect]); break; } diff --git a/source/games/duke/src/animatesprites_r.cpp b/source/games/duke/src/animatesprites_r.cpp index 4bf44f22c..301cb7151 100644 --- a/source/games/duke/src/animatesprites_r.cpp +++ b/source/games/duke/src/animatesprites_r.cpp @@ -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, §or[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, §or[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, §or[sect]); break; }