From afde568856948b9e07f2f52d569abca1aaeb1983 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Tue, 4 Jan 2022 19:33:17 +0100 Subject: [PATCH] Add blendmode support to FOFs --- extras/conf/udb/Includes/SRB222_linedefs.cfg | 62 ++++- extras/conf/udb/Includes/SRB222_misc.cfg | 9 + src/p_setup.c | 201 +++++++-------- src/p_spec.c | 250 ++++++++++--------- src/p_spec.h | 10 +- 5 files changed, 302 insertions(+), 230 deletions(-) diff --git a/extras/conf/udb/Includes/SRB222_linedefs.cfg b/extras/conf/udb/Includes/SRB222_linedefs.cfg index 15e7685c3..d40f2a373 100644 --- a/extras/conf/udb/Includes/SRB222_linedefs.cfg +++ b/extras/conf/udb/Includes/SRB222_linedefs.cfg @@ -2453,6 +2453,12 @@ udmf default = 255; } arg2 + { + title = "Blending mode"; + type = 11; + enum = "blendmodes"; + } + arg3 { title = "Appearance"; type = 12; @@ -2466,7 +2472,7 @@ udmf 32 = "Cut cyan flat pixels"; } } - arg3 + arg4 { title = "Tangibility"; type = 12; @@ -2489,6 +2495,12 @@ udmf default = 128; } arg2 + { + title = "Blending mode"; + type = 11; + enum = "blendmodes"; + } + arg3 { title = "Flags"; type = 12; @@ -2556,12 +2568,18 @@ udmf default = 255; } arg2 + { + title = "Blending mode"; + type = 11; + enum = "blendmodes"; + } + arg3 { title = "Tangibility"; type = 12; enum = "tangibility"; } - arg3 + arg4 { title = "Flags"; type = 12; @@ -2591,6 +2609,12 @@ udmf default = 255; } arg2 + { + title = "Blending mode"; + type = 11; + enum = "blendmodes"; + } + arg3 { title = "Appearance"; type = 12; @@ -2604,17 +2628,17 @@ udmf 32 = "Cut cyan flat pixels"; } } - arg3 + arg4 { title = "Tangibility"; type = 12; enum = "tangibility"; } - arg4 + arg5 { title = "Speed"; } - arg5 + arg6 { title = "Flags"; type = 12; @@ -2669,6 +2693,12 @@ udmf default = 255; } arg2 + { + title = "Blending mode"; + type = 11; + enum = "blendmodes"; + } + arg3 { title = "Appearance"; type = 12; @@ -2755,6 +2785,12 @@ udmf default = 255; } arg2 + { + title = "Blending mode"; + type = 11; + enum = "blendmodes"; + } + arg3 { title = "Bustable type"; type = 11; @@ -2766,7 +2802,7 @@ udmf 3 = "Strong"; } } - arg3 + arg4 { title = "Flags"; type = 12; @@ -2778,7 +2814,7 @@ udmf 8 = "Cut cyan flat pixels"; } } - arg4 + arg5 { title = "Linedef executor tag"; type = 15; @@ -2825,6 +2861,12 @@ udmf default = 128; } arg2 + { + title = "Blending mode"; + type = 11; + enum = "blendmodes"; + } + arg3 { title = "Flags"; type = 12; @@ -2851,6 +2893,12 @@ udmf default = 255; } arg2 + { + title = "Blending mode"; + type = 11; + enum = "blendmodes"; + } + arg3 { title = "Flags"; type = 12; diff --git a/extras/conf/udb/Includes/SRB222_misc.cfg b/extras/conf/udb/Includes/SRB222_misc.cfg index c46fff822..e392014c8 100644 --- a/extras/conf/udb/Includes/SRB222_misc.cfg +++ b/extras/conf/udb/Includes/SRB222_misc.cfg @@ -649,6 +649,15 @@ enums 1 = "Random (Weak)"; 2 = "Random (Strong)"; } + + blendmodes + { + 0 = "Translucent"; + 1 = "Add"; + 2 = "Subtract"; + 3 = "Reverse subtract"; + 4 = "Modulate"; + } } //Default things filters diff --git a/src/p_setup.c b/src/p_setup.c index dbbd99859..15e7c6d09 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3282,6 +3282,24 @@ static line_t *P_FindPointPushLine(taglist_t *list) return NULL; } +static void P_SetBinaryFOFAlpha(line_t *line) +{ + if (sides[line->sidenum[0]].toptexture > 0) + { + line->args[1] = sides[line->sidenum[0]].toptexture; + if (sides[line->sidenum[0]].toptexture >= 1001) + { + line->args[2] = (sides[line->sidenum[0]].toptexture/1000); + line->args[1] %= 1000; + } + } + else + { + line->args[1] = 128; + line->args[2] = TMB_TRANSLUCENT; + } +} + //For maps in binary format, converts setup of specials to UDMF format. static void P_ConvertBinaryMap(void) { @@ -3562,36 +3580,33 @@ static void P_ConvertBinaryMap(void) if (lines[i].special == 102) { if (lines[i].flags & ML_NOCLIMB) - lines[i].args[2] |= TMFA_INSIDES; - if (sides[lines[i].sidenum[0]].toptexture > 0) - lines[i].args[1] = sides[lines[i].sidenum[0]].toptexture; - else - lines[i].args[1] = 128; + lines[i].args[3] |= TMFA_INSIDES; + P_SetBinaryFOFAlpha(&lines[i]); //Replicate old hack: Translucent FOFs set to full opacity cut cyan pixels if (lines[i].args[1] == 256) - lines[i].args[2] |= TMFA_SPLAT; + lines[i].args[3] |= TMFA_SPLAT; } else lines[i].args[1] = 255; //Appearance if (lines[i].special == 105) - lines[i].args[2] |= TMFA_NOPLANES|TMFA_NOSIDES; + lines[i].args[3] |= TMFA_NOPLANES|TMFA_NOSIDES; else if (lines[i].special == 104) - lines[i].args[2] |= TMFA_NOSIDES; + lines[i].args[3] |= TMFA_NOSIDES; else if (lines[i].special == 103) - lines[i].args[2] |= TMFA_NOPLANES; + lines[i].args[3] |= TMFA_NOPLANES; if (lines[i].special != 100 && (lines[i].special != 104 || !(lines[i].flags & ML_NOCLIMB))) - lines[i].args[2] |= TMFA_NOSHADE; + lines[i].args[3] |= TMFA_NOSHADE; if (lines[i].flags & ML_EFFECT6) - lines[i].args[2] |= TMFA_SPLAT; + lines[i].args[3] |= TMFA_SPLAT; //Tangibility if (lines[i].flags & ML_EFFECT1) - lines[i].args[3] |= TMFT_DONTBLOCKOTHERS; + lines[i].args[4] |= TMFT_DONTBLOCKOTHERS; if (lines[i].flags & ML_EFFECT2) - lines[i].args[3] |= TMFT_DONTBLOCKPLAYER; + lines[i].args[4] |= TMFT_DONTBLOCKPLAYER; lines[i].special = 100; break; @@ -3608,35 +3623,32 @@ static void P_ConvertBinaryMap(void) lines[i].args[1] = 255; else { - if (sides[lines[i].sidenum[0]].toptexture > 0) - lines[i].args[1] = sides[lines[i].sidenum[0]].toptexture; - else - lines[i].args[1] = 128; + P_SetBinaryFOFAlpha(&lines[i]); //Replicate old hack: Translucent FOFs set to full opacity cut cyan pixels if (lines[i].args[1] == 256) - lines[i].args[2] |= TMFW_SPLAT; + lines[i].args[3] |= TMFW_SPLAT; } //No sides? if (lines[i].special == 122 || lines[i].special == 123 || lines[i].special == 125) - lines[i].args[2] |= TMFW_NOSIDES; + lines[i].args[3] |= TMFW_NOSIDES; //Flags if (lines[i].flags & ML_NOCLIMB) - lines[i].args[2] |= TMFW_DOUBLESHADOW; + lines[i].args[3] |= TMFW_DOUBLESHADOW; if (lines[i].flags & ML_EFFECT4) - lines[i].args[2] |= TMFW_COLORMAPONLY; + lines[i].args[3] |= TMFW_COLORMAPONLY; if (!(lines[i].flags & ML_EFFECT5)) - lines[i].args[2] |= TMFW_NORIPPLE; + lines[i].args[3] |= TMFW_NORIPPLE; //Goo? if (lines[i].special >= 124) - lines[i].args[2] |= TMFW_GOOWATER; + lines[i].args[3] |= TMFW_GOOWATER; //Splat rendering? if (lines[i].flags & ML_EFFECT6) - lines[i].args[2] |= TMFW_SPLAT; + lines[i].args[3] |= TMFW_SPLAT; lines[i].special = 120; break; @@ -3653,41 +3665,38 @@ static void P_ConvertBinaryMap(void) if (lines[i].special == 141 || lines[i].special == 142 || lines[i].special == 144 || lines[i].special == 145) { if (lines[i].flags & ML_NOCLIMB) - lines[i].args[2] |= TMFA_INSIDES; - if (sides[lines[i].sidenum[0]].toptexture > 0) - lines[i].args[1] = sides[lines[i].sidenum[0]].toptexture; - else - lines[i].args[1] = 128; + lines[i].args[3] |= TMFA_INSIDES; + P_SetBinaryFOFAlpha(&lines[i]); //Replicate old hack: Translucent FOFs set to full opacity cut cyan pixels if (lines[i].args[1] == 256) - lines[i].args[2] |= TMFA_SPLAT; + lines[i].args[3] |= TMFA_SPLAT; } else lines[i].args[1] = 255; //Appearance if (lines[i].special == 142 || lines[i].special == 145) - lines[i].args[2] |= TMFA_NOSIDES; + lines[i].args[3] |= TMFA_NOSIDES; else if (lines[i].special == 146) - lines[i].args[2] |= TMFA_NOPLANES; + lines[i].args[3] |= TMFA_NOPLANES; if (lines[i].special != 146 && (lines[i].flags & ML_NOCLIMB)) - lines[i].args[2] |= TMFA_NOSHADE; + lines[i].args[3] |= TMFA_NOSHADE; if (lines[i].flags & ML_EFFECT6) - lines[i].args[2] |= TMFA_SPLAT; + lines[i].args[3] |= TMFA_SPLAT; //Tangibility if (lines[i].special <= 142) - lines[i].args[3] |= TMFT_INTANGIBLEBOTTOM; + lines[i].args[4] |= TMFT_INTANGIBLEBOTTOM; else if (lines[i].special <= 145) - lines[i].args[3] |= TMFT_INTANGIBLETOP; + lines[i].args[4] |= TMFT_INTANGIBLETOP; else - lines[i].args[3] |= TMFT_INTANGIBLEBOTTOM|TMFT_INTANGIBLETOP; + lines[i].args[4] |= TMFT_INTANGIBLEBOTTOM|TMFT_INTANGIBLETOP; if (lines[i].flags & ML_EFFECT1) - lines[i].args[3] |= TMFT_DONTBLOCKOTHERS; + lines[i].args[4] |= TMFT_DONTBLOCKOTHERS; if (lines[i].flags & ML_EFFECT2) - lines[i].args[3] |= TMFT_DONTBLOCKPLAYER; + lines[i].args[4] |= TMFT_DONTBLOCKPLAYER; lines[i].special = 100; break; @@ -3727,38 +3736,35 @@ static void P_ConvertBinaryMap(void) //Alpha if (lines[i].special >= 174 && lines[i].special <= 175) { - if (sides[lines[i].sidenum[0]].toptexture > 0) - lines[i].args[1] = sides[lines[i].sidenum[0]].toptexture; - else - lines[i].args[1] = 128; + P_SetBinaryFOFAlpha(&lines[i]); //Replicate old hack: Translucent FOFs set to full opacity cut cyan pixels if (lines[i].args[1] == 256) - lines[i].args[3] |= TMFC_SPLAT; + lines[i].args[4] |= TMFC_SPLAT; } else lines[i].args[1] = 255; if (lines[i].special >= 172 && lines[i].special <= 175) { - lines[i].args[2] |= TMFT_INTANGIBLEBOTTOM; + lines[i].args[3] |= TMFT_INTANGIBLEBOTTOM; if (lines[i].flags & ML_NOCLIMB) - lines[i].args[3] |= TMFC_NOSHADE; + lines[i].args[4] |= TMFC_NOSHADE; } if (lines[i].special % 2 == 1) - lines[i].args[3] |= TMFC_NORETURN; + lines[i].args[4] |= TMFC_NORETURN; if (lines[i].special == 176 || lines[i].special == 177 || lines[i].special == 180) - lines[i].args[3] |= TMFC_AIRBOB; + lines[i].args[4] |= TMFC_AIRBOB; if (lines[i].special >= 176 && lines[i].special <= 179) - lines[i].args[3] |= TMFC_FLOATBOB; + lines[i].args[4] |= TMFC_FLOATBOB; if (lines[i].flags & ML_EFFECT6) - lines[i].args[3] |= TMFC_SPLAT; + lines[i].args[4] |= TMFC_SPLAT; if (lines[i].flags & ML_EFFECT1) - lines[i].args[2] |= TMFT_DONTBLOCKOTHERS; + lines[i].args[3] |= TMFT_DONTBLOCKOTHERS; if (lines[i].flags & ML_EFFECT2) - lines[i].args[2] |= TMFT_DONTBLOCKPLAYER; + lines[i].args[3] |= TMFT_DONTBLOCKPLAYER; lines[i].special = 170; break; @@ -3773,44 +3779,41 @@ static void P_ConvertBinaryMap(void) //Translucency if (lines[i].special == 192 || lines[i].special == 195) { - if (sides[lines[i].sidenum[0]].toptexture > 0) - lines[i].args[1] = sides[lines[i].sidenum[0]].toptexture; - else - lines[i].args[1] = 128; + P_SetBinaryFOFAlpha(&lines[i]); //Replicate old hack: Translucent FOFs set to full opacity cut cyan pixels if (lines[i].args[1] == 256) - lines[i].args[2] |= TMFA_SPLAT; + lines[i].args[3] |= TMFA_SPLAT; } else lines[i].args[1] = 255; //Appearance if (lines[i].special == 193) - lines[i].args[2] |= TMFA_NOPLANES|TMFA_NOSIDES; + lines[i].args[3] |= TMFA_NOPLANES|TMFA_NOSIDES; if (lines[i].special >= 194) - lines[i].args[2] |= TMFA_INSIDES; + lines[i].args[3] |= TMFA_INSIDES; if (lines[i].special != 190 && (lines[i].special <= 193 || lines[i].flags & ML_NOCLIMB)) - lines[i].args[2] |= TMFA_NOSHADE; + lines[i].args[3] |= TMFA_NOSHADE; if (lines[i].flags & ML_EFFECT6) - lines[i].args[2] |= TMFA_SPLAT; + lines[i].args[3] |= TMFA_SPLAT; //Tangibility if (lines[i].flags & ML_EFFECT1) - lines[i].args[3] |= TMFT_DONTBLOCKOTHERS; + lines[i].args[4] |= TMFT_DONTBLOCKOTHERS; if (lines[i].flags & ML_EFFECT2) - lines[i].args[3] |= TMFT_DONTBLOCKPLAYER; + lines[i].args[4] |= TMFT_DONTBLOCKPLAYER; if (lines[i].special >= 194) - lines[i].args[3] |= TMFT_INTANGIBLEBOTTOM; + lines[i].args[4] |= TMFT_INTANGIBLEBOTTOM; //Speed - lines[i].args[4] = P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS; + lines[i].args[5] = P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS; //Flags if (lines[i].flags & ML_BLOCKMONSTERS) - lines[i].args[5] |= TMFR_REVERSE; + lines[i].args[6] |= TMFR_REVERSE; if (lines[i].flags & ML_BLOCKMONSTERS) - lines[i].args[5] |= TMFR_SPINDASH; + lines[i].args[6] |= TMFR_SPINDASH; lines[i].special = 190; break; @@ -3833,27 +3836,24 @@ static void P_ConvertBinaryMap(void) //Alpha if (lines[i].special == 221) { - if (sides[lines[i].sidenum[0]].toptexture > 0) - lines[i].args[1] = sides[lines[i].sidenum[0]].toptexture; - else - lines[i].args[1] = 128; + P_SetBinaryFOFAlpha(&lines[i]); //Replicate old hack: Translucent FOFs set to full opacity cut cyan pixels if (lines[i].args[1] == 256) - lines[i].args[2] |= TMFA_SPLAT; + lines[i].args[3] |= TMFA_SPLAT; } else lines[i].args[1] = 255; //Appearance if (lines[i].special == 222) - lines[i].args[2] |= TMFA_NOPLANES; + lines[i].args[3] |= TMFA_NOPLANES; if (lines[i].special == 221) - lines[i].args[2] |= TMFA_INSIDES; + lines[i].args[3] |= TMFA_INSIDES; if (lines[i].special != 220 && !(lines[i].flags & ML_NOCLIMB)) - lines[i].args[2] |= TMFA_NOSHADE; + lines[i].args[3] |= TMFA_NOSHADE; if (lines[i].flags & ML_EFFECT6) - lines[i].args[2] |= TMFA_SPLAT; + lines[i].args[3] |= TMFA_SPLAT; lines[i].special = 220; break; @@ -3889,40 +3889,37 @@ static void P_ConvertBinaryMap(void) //Alpha if (lines[i].special == 253 || lines[i].special == 256) { - if (sides[lines[i].sidenum[0]].toptexture > 0) - lines[i].args[1] = sides[lines[i].sidenum[0]].toptexture; - else - lines[i].args[1] = 128; + P_SetBinaryFOFAlpha(&lines[i]); //Replicate old hack: Translucent FOFs set to full opacity cut cyan pixels if (lines[i].args[1] == 256) - lines[i].args[3] |= TMFB_SPLAT; + lines[i].args[4] |= TMFB_SPLAT; } else lines[i].args[1] = 255; //Bustable type if (lines[i].special <= 253) - lines[i].args[2] = TMFB_TOUCH; + lines[i].args[3] = TMFB_TOUCH; else if (lines[i].special >= 255) - lines[i].args[2] = TMFB_SPIN; + lines[i].args[3] = TMFB_SPIN; else if (lines[i].flags & ML_NOCLIMB) - lines[i].args[2] = TMFB_STRONG; + lines[i].args[3] = TMFB_STRONG; else - lines[i].args[2] = TMFB_REGULAR; + lines[i].args[3] = TMFB_REGULAR; //Flags if (lines[i].flags & ML_EFFECT4) - lines[i].args[3] |= TMFB_PUSHABLES; + lines[i].args[4] |= TMFB_PUSHABLES; if (lines[i].flags & ML_EFFECT5) { - lines[i].args[3] |= TMFB_EXECUTOR; - lines[i].args[4] = P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS; + lines[i].args[4] |= TMFB_EXECUTOR; + lines[i].args[5] = P_AproxDistance(lines[i].dx, lines[i].dy) >> FRACBITS; } if (lines[i].special == 252 && lines[i].flags & ML_NOCLIMB) - lines[i].args[3] |= TMFB_ONLYBOTTOM; + lines[i].args[4] |= TMFB_ONLYBOTTOM; if (lines[i].flags & ML_EFFECT6) - lines[i].args[3] |= TMFB_SPLAT; + lines[i].args[4] |= TMFB_SPLAT; lines[i].special = 254; break; @@ -3937,17 +3934,14 @@ static void P_ConvertBinaryMap(void) lines[i].args[0] = tag; //Alpha - if (sides[lines[i].sidenum[0]].toptexture > 0) - lines[i].args[1] = sides[lines[i].sidenum[0]].toptexture; - else - lines[i].args[1] = 128; + P_SetBinaryFOFAlpha(&lines[i]); //Flags if (lines[i].flags & ML_EFFECT1) - lines[i].args[2] = TMFL_NOBOSSES; + lines[i].args[3] |= TMFL_NOBOSSES; //Replicate old hack: Translucent FOFs set to full opacity cut cyan pixels if (lines[i].flags & ML_EFFECT6 || lines[i].args[1] == 256) - lines[i].args[2] = TMFL_SPLAT; + lines[i].args[3] |= TMFL_SPLAT; break; case 259: //Custom FOF @@ -3955,20 +3949,17 @@ static void P_ConvertBinaryMap(void) I_Error("Custom FOF (tag %d) found without a linedef back side!", tag); lines[i].args[0] = tag; - lines[i].args[2] = sides[lines[i].sidenum[1]].toptexture; + lines[i].args[3] = sides[lines[i].sidenum[1]].toptexture; if (lines[i].flags & ML_EFFECT6) - lines[i].args[2] |= FF_SPLAT; - lines[i].args[3] = sides[lines[i].sidenum[1]].midtexture; - if (lines[i].args[2] & FF_TRANSLUCENT) + lines[i].args[3] |= FF_SPLAT; + lines[i].args[4] = sides[lines[i].sidenum[1]].midtexture; + if (lines[i].args[3] & FF_TRANSLUCENT) { - if (sides[lines[i].sidenum[0]].toptexture > 0) - lines[i].args[1] = sides[lines[i].sidenum[0]].toptexture; - else - lines[i].args[1] = 128; + P_SetBinaryFOFAlpha(&lines[i]); //Replicate old hack: Translucent FOFs set to full opacity cut cyan pixels if (lines[i].args[1] == 256) - lines[i].args[2] |= FF_SPLAT; + lines[i].args[3] |= FF_SPLAT; } else lines[i].args[1] = 255; diff --git a/src/p_spec.c b/src/p_spec.c index 1220edf8f..9358d6766 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -115,7 +115,7 @@ static void Add_ColormapFader(sector_t *sector, extracolormap_t *source_exc, ext static void P_AddBlockThinker(sector_t *sec, line_t *sourceline); static void P_AddFloatThinker(sector_t *sec, UINT16 tag, line_t *sourceline); //static void P_AddBridgeThinker(line_t *sourceline, sector_t *sec); -static void P_AddFakeFloorsByLine(size_t line, INT32 alpha, ffloortype_e ffloorflags, thinkerlist_t *secthinkers); +static void P_AddFakeFloorsByLine(size_t line, INT32 alpha, UINT8 blendmode, ffloortype_e ffloorflags, thinkerlist_t *secthinkers); static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec); static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32 referrer); static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control, INT32 affectee, UINT8 reverse); @@ -5490,12 +5490,13 @@ static inline void P_AddFFloorToList(sector_t *sec, ffloor_t *fflr) * \param sec2 Control sector. * \param master Control linedef. * \param alpha Alpha value (0-255). + * \param blendmode Blending mode. * \param flags Options affecting this 3Dfloor. * \param secthinkers List of relevant thinkers sorted by sector. May be NULL. * \return Pointer to the new 3Dfloor. * \sa P_AddFFloor, P_AddFakeFloorsByLine, P_SpawnSpecials */ -static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, INT32 alpha, ffloortype_e flags, thinkerlist_t *secthinkers) +static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, INT32 alpha, UINT8 blendmode, ffloortype_e flags, thinkerlist_t *secthinkers) { ffloor_t *fflr; thinker_t *th; @@ -5621,15 +5622,29 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, I { fflr->flags |= FF_TRANSLUCENT; fflr->spawnflags = fflr->flags; - - if (sides[master->sidenum[0]].toptexture >= 1001) - { - fflr->blend = (sides[master->sidenum[0]].toptexture/1000)+1; // becomes an AST - fflr->alpha %= 1000; - } } fflr->spawnalpha = fflr->alpha; // save for netgames + switch (blendmode) + { + case TMB_TRANSLUCENT: + default: + fflr->blend = AST_TRANSLUCENT; + break; + case TMB_ADD: + fflr->blend = AST_ADD; + break; + case TMB_SUBTRACT: + fflr->blend = AST_SUBTRACT; + break; + case TMB_REVERSESUBTRACT: + fflr->blend = AST_REVERSESUBTRACT; + break; + case TMB_MODULATE: + fflr->blend = AST_MODULATE; + break; + } + if (flags & FF_QUICKSAND) CheckForQuicksand = true; @@ -6455,29 +6470,81 @@ void P_SpawnSpecials(boolean fromnetsave) ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL; //Appearance settings - if (lines[i].args[2] & TMFA_NOPLANES) + if (lines[i].args[3] & TMFA_NOPLANES) ffloorflags &= ~FF_RENDERPLANES; - if (lines[i].args[2] & TMFA_NOSIDES) + if (lines[i].args[3] & TMFA_NOSIDES) ffloorflags &= ~FF_RENDERSIDES; - if (lines[i].args[2] & TMFA_INSIDES) + if (lines[i].args[3] & TMFA_INSIDES) { if (ffloorflags & FF_RENDERPLANES) ffloorflags |= FF_BOTHPLANES; if (ffloorflags & FF_RENDERSIDES) ffloorflags |= FF_ALLSIDES; } - if (lines[i].args[2] & TMFA_ONLYINSIDES) + if (lines[i].args[3] & TMFA_ONLYINSIDES) { if (ffloorflags & FF_RENDERPLANES) ffloorflags |= FF_INVERTPLANES; if (ffloorflags & FF_RENDERSIDES) ffloorflags |= FF_INVERTSIDES; } - if (lines[i].args[2] & TMFA_NOSHADE) + if (lines[i].args[3] & TMFA_NOSHADE) ffloorflags |= FF_NOSHADE; - if (lines[i].args[2] & TMFA_SPLAT) + if (lines[i].args[3] & TMFA_SPLAT) ffloorflags |= FF_SPLAT; + //Tangibility settings + if (lines[i].args[4] & TMFT_INTANGIBLETOP) + ffloorflags |= FF_REVERSEPLATFORM; + if (lines[i].args[4] & TMFT_INTANGIBLEBOTTOM) + ffloorflags |= FF_PLATFORM; + if (lines[i].args[4] & TMFT_DONTBLOCKPLAYER) + ffloorflags &= ~FF_BLOCKPLAYER; + if (lines[i].args[4] & TMFT_DONTBLOCKOTHERS) + ffloorflags &= ~FF_BLOCKOTHERS; + + //Cutting options + if (ffloorflags & FF_RENDERALL) + { + //If translucent or player can enter it, cut inner walls + if ((lines[i].args[1] < 255) || (lines[i].args[4] & TMFT_VISIBLEFROMINSIDE)) + ffloorflags |= FF_CUTEXTRA|FF_EXTRA; + else + ffloorflags |= FF_CUTLEVEL; + } + + P_AddFakeFloorsByLine(i, lines[i].args[1], lines[i].args[2], ffloorflags, secthinkers); + break; + + case 120: // FOF (water) + ffloorflags = FF_EXISTS|FF_RENDERPLANES|FF_SWIMMABLE|FF_BOTHPLANES|FF_CUTEXTRA|FF_EXTRA|FF_CUTSPRITES; + if (!(lines[i].args[3] & TMFW_NOSIDES)) + ffloorflags |= FF_RENDERSIDES|FF_ALLSIDES; + if (lines[i].args[3] & TMFW_DOUBLESHADOW) + ffloorflags |= FF_DOUBLESHADOW; + if (lines[i].args[3] & TMFW_COLORMAPONLY) + ffloorflags |= FF_COLORMAPONLY; + if (!(lines[i].args[3] & TMFW_NORIPPLE)) + ffloorflags |= FF_RIPPLE; + if (lines[i].args[3] & TMFW_GOOWATER) + ffloorflags |= FF_GOOWATER; + if (lines[i].args[3] & TMFW_SPLAT) + ffloorflags |= FF_SPLAT; + P_AddFakeFloorsByLine(i, lines[i].args[1], lines[i].args[2], ffloorflags, secthinkers); + break; + + case 150: // FOF (Air bobbing) + P_AddFakeFloorsByLine(i, 0xff, AST_COPY, FF_EXISTS|FF_SOLID|FF_RENDERALL, secthinkers); + P_AddAirbob(lines[i].frontsector, lines[i].args[0], lines[i].args[1] << FRACBITS, !!(lines[i].args[2] & TMFB_REVERSE), !!(lines[i].args[2] & TMFB_SPINDASH), !!(lines[i].args[2] & TMFB_DYNAMIC)); + break; + + case 160: // FOF (Water bobbing) + P_AddFakeFloorsByLine(i, 0xff, AST_COPY, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_FLOATBOB, secthinkers); + break; + + case 170: // FOF (Crumbling) + ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CRUMBLE; + //Tangibility settings if (lines[i].args[3] & TMFT_INTANGIBLETOP) ffloorflags |= FF_REVERSEPLATFORM; @@ -6488,76 +6555,24 @@ void P_SpawnSpecials(boolean fromnetsave) if (lines[i].args[3] & TMFT_DONTBLOCKOTHERS) ffloorflags &= ~FF_BLOCKOTHERS; - //Cutting options - if (ffloorflags & FF_RENDERALL) - { - //If translucent or player can enter it, cut inner walls - if ((lines[i].args[1] < 255) || (lines[i].args[3] & TMFT_VISIBLEFROMINSIDE)) - ffloorflags |= FF_CUTEXTRA|FF_EXTRA; - else - ffloorflags |= FF_CUTLEVEL; - } - - P_AddFakeFloorsByLine(i, lines[i].args[1], ffloorflags, secthinkers); - break; - - case 120: // FOF (water) - ffloorflags = FF_EXISTS|FF_RENDERPLANES|FF_SWIMMABLE|FF_BOTHPLANES|FF_CUTEXTRA|FF_EXTRA|FF_CUTSPRITES; - if (!(lines[i].args[2] & TMFW_NOSIDES)) - ffloorflags |= FF_RENDERSIDES|FF_ALLSIDES; - if (lines[i].args[2] & TMFW_DOUBLESHADOW) - ffloorflags |= FF_DOUBLESHADOW; - if (lines[i].args[2] & TMFW_COLORMAPONLY) - ffloorflags |= FF_COLORMAPONLY; - if (!(lines[i].args[2] & TMFW_NORIPPLE)) - ffloorflags |= FF_RIPPLE; - if (lines[i].args[2] & TMFW_GOOWATER) - ffloorflags |= FF_GOOWATER; - if (lines[i].args[2] & TMFW_SPLAT) - ffloorflags |= FF_SPLAT; - P_AddFakeFloorsByLine(i, lines[i].args[1], ffloorflags, secthinkers); - break; - - case 150: // FOF (Air bobbing) - P_AddFakeFloorsByLine(i, 0xff, FF_EXISTS|FF_SOLID|FF_RENDERALL, secthinkers); - P_AddAirbob(lines[i].frontsector, lines[i].args[0], lines[i].args[1] << FRACBITS, !!(lines[i].args[2] & TMFB_REVERSE), !!(lines[i].args[2] & TMFB_SPINDASH), !!(lines[i].args[2] & TMFB_DYNAMIC)); - break; - - case 160: // FOF (Water bobbing) - P_AddFakeFloorsByLine(i, 0xff, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_FLOATBOB, secthinkers); - break; - - case 170: // FOF (Crumbling) - ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CRUMBLE; - - //Tangibility settings - if (lines[i].args[2] & TMFT_INTANGIBLETOP) - ffloorflags |= FF_REVERSEPLATFORM; - if (lines[i].args[2] & TMFT_INTANGIBLEBOTTOM) - ffloorflags |= FF_PLATFORM; - if (lines[i].args[2] & TMFT_DONTBLOCKPLAYER) - ffloorflags &= ~FF_BLOCKPLAYER; - if (lines[i].args[2] & TMFT_DONTBLOCKOTHERS) - ffloorflags &= ~FF_BLOCKOTHERS; - //Flags - if (lines[i].args[3] & TMFC_NOSHADE) + if (lines[i].args[4] & TMFC_NOSHADE) ffloorflags |= FF_NOSHADE; - if (lines[i].args[3] & TMFC_NORETURN) + if (lines[i].args[4] & TMFC_NORETURN) ffloorflags |= FF_NORETURN; - if (lines[i].args[3] & TMFC_FLOATBOB) + if (lines[i].args[4] & TMFC_FLOATBOB) ffloorflags |= FF_FLOATBOB; - if (lines[i].args[3] & TMFC_SPLAT) + if (lines[i].args[4] & TMFC_SPLAT) ffloorflags |= FF_SPLAT; //If translucent or player can enter it, cut inner walls - if (lines[i].args[1] < 0xff || (lines[i].args[2] & TMFT_VISIBLEFROMINSIDE)) + if (lines[i].args[1] < 0xff || (lines[i].args[3] & TMFT_VISIBLEFROMINSIDE)) ffloorflags |= FF_CUTEXTRA|FF_EXTRA; else ffloorflags |= FF_CUTLEVEL; //If player can enter it, render insides - if (lines[i].args[2] & TMFT_VISIBLEFROMINSIDE) + if (lines[i].args[3] & TMFT_VISIBLEFROMINSIDE) { if (ffloorflags & FF_RENDERPLANES) ffloorflags |= FF_BOTHPLANES; @@ -6565,8 +6580,8 @@ void P_SpawnSpecials(boolean fromnetsave) ffloorflags |= FF_ALLSIDES; } - P_AddFakeFloorsByLine(i, lines[i].args[1], ffloorflags, secthinkers); - if (lines[i].args[3] & TMFC_AIRBOB) + P_AddFakeFloorsByLine(i, lines[i].args[1], lines[i].args[2], ffloorflags, secthinkers); + if (lines[i].args[4] & TMFC_AIRBOB) P_AddAirbob(lines[i].frontsector, lines[i].args[0], 16*FRACUNIT, false, false, false); break; @@ -6578,50 +6593,50 @@ void P_SpawnSpecials(boolean fromnetsave) ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL; //Appearance settings - if (lines[i].args[2] & TMFA_NOPLANES) + if (lines[i].args[3] & TMFA_NOPLANES) ffloorflags &= ~FF_RENDERPLANES; - if (lines[i].args[2] & TMFA_NOSIDES) + if (lines[i].args[3] & TMFA_NOSIDES) ffloorflags &= ~FF_RENDERSIDES; - if (lines[i].args[2] & TMFA_INSIDES) + if (lines[i].args[3] & TMFA_INSIDES) { if (ffloorflags & FF_RENDERPLANES) ffloorflags |= FF_BOTHPLANES; if (ffloorflags & FF_RENDERSIDES) ffloorflags |= FF_ALLSIDES; } - if (lines[i].args[2] & TMFA_ONLYINSIDES) + if (lines[i].args[3] & TMFA_ONLYINSIDES) { if (ffloorflags & FF_RENDERPLANES) ffloorflags |= FF_INVERTPLANES; if (ffloorflags & FF_RENDERSIDES) ffloorflags |= FF_INVERTSIDES; } - if (lines[i].args[2] & TMFA_NOSHADE) + if (lines[i].args[3] & TMFA_NOSHADE) ffloorflags |= FF_NOSHADE; - if (lines[i].args[2] & TMFA_SPLAT) + if (lines[i].args[3] & TMFA_SPLAT) ffloorflags |= FF_SPLAT; //Tangibility settings - if (lines[i].args[3] & TMFT_INTANGIBLETOP) + if (lines[i].args[4] & TMFT_INTANGIBLETOP) ffloorflags |= FF_REVERSEPLATFORM; - if (lines[i].args[3] & TMFT_INTANGIBLEBOTTOM) + if (lines[i].args[4] & TMFT_INTANGIBLEBOTTOM) ffloorflags |= FF_PLATFORM; - if (lines[i].args[3] & TMFT_DONTBLOCKPLAYER) + if (lines[i].args[4] & TMFT_DONTBLOCKPLAYER) ffloorflags &= ~FF_BLOCKPLAYER; - if (lines[i].args[3] & TMFT_DONTBLOCKOTHERS) + if (lines[i].args[4] & TMFT_DONTBLOCKOTHERS) ffloorflags &= ~FF_BLOCKOTHERS; //Cutting options if (ffloorflags & FF_RENDERALL) { //If translucent or player can enter it, cut inner walls - if ((lines[i].args[1] < 255) || (lines[i].args[3] & TMFT_VISIBLEFROMINSIDE)) + if ((lines[i].args[1] < 255) || (lines[i].args[4] & TMFT_VISIBLEFROMINSIDE)) ffloorflags |= FF_CUTEXTRA|FF_EXTRA; else ffloorflags |= FF_CUTLEVEL; } - P_AddFakeFloorsByLine(i, lines[i].args[1], ffloorflags, secthinkers); + P_AddFakeFloorsByLine(i, lines[i].args[1], lines[i].args[2], ffloorflags, secthinkers); P_AddRaiseThinker(lines[i].frontsector, lines[i].args[0], lines[i].args[4] << FRACBITS, ceilingtop, ceilingbottom, !!(lines[i].args[5] & TMFR_REVERSE), !!(lines[i].args[5] & TMFR_SPINDASH)); break; } @@ -6629,7 +6644,7 @@ void P_SpawnSpecials(boolean fromnetsave) ffloorflags = FF_EXISTS|FF_CUTSPRITES; if (!lines[i].args[1]) ffloorflags |= FF_DOUBLESHADOW; - P_AddFakeFloorsByLine(i, 0xff, ffloorflags, secthinkers); + P_AddFakeFloorsByLine(i, 0xff, AST_COPY, ffloorflags, secthinkers); break; case 202: // Fog @@ -6638,41 +6653,41 @@ void P_SpawnSpecials(boolean fromnetsave) // SoM: Because it's fog, check for an extra colormap and set the fog flag... if (sectors[sec].extra_colormap) sectors[sec].extra_colormap->flags = CMF_FOG; - P_AddFakeFloorsByLine(i, 0xff, ffloorflags, secthinkers); + P_AddFakeFloorsByLine(i, 0xff, AST_COPY, ffloorflags, secthinkers); break; case 220: //Intangible ffloorflags = FF_EXISTS|FF_RENDERALL|FF_CUTEXTRA|FF_EXTRA|FF_CUTSPRITES; //Appearance settings - if (lines[i].args[2] & TMFA_NOPLANES) + if (lines[i].args[3] & TMFA_NOPLANES) ffloorflags &= ~FF_RENDERPLANES; - if (lines[i].args[2] & TMFA_NOSIDES) + if (lines[i].args[3] & TMFA_NOSIDES) ffloorflags &= ~FF_RENDERSIDES; - if (!(lines[i].args[2] & TMFA_INSIDES)) + if (!(lines[i].args[3] & TMFA_INSIDES)) { if (ffloorflags & FF_RENDERPLANES) ffloorflags |= FF_BOTHPLANES; if (ffloorflags & FF_RENDERSIDES) ffloorflags |= FF_ALLSIDES; } - if (lines[i].args[2] & TMFA_ONLYINSIDES) + if (lines[i].args[3] & TMFA_ONLYINSIDES) { if (ffloorflags & FF_RENDERPLANES) ffloorflags |= FF_INVERTPLANES; if (ffloorflags & FF_RENDERSIDES) ffloorflags |= FF_INVERTSIDES; } - if (lines[i].args[2] & TMFA_NOSHADE) + if (lines[i].args[3] & TMFA_NOSHADE) ffloorflags |= FF_NOSHADE; - if (lines[i].args[2] & TMFA_SPLAT) + if (lines[i].args[3] & TMFA_SPLAT) ffloorflags |= FF_SPLAT; - P_AddFakeFloorsByLine(i, lines[i].args[1], ffloorflags, secthinkers); + P_AddFakeFloorsByLine(i, lines[i].args[1], lines[i].args[2], ffloorflags, secthinkers); break; case 223: // FOF (intangible, invisible) - for combining specials in a sector - P_AddFakeFloorsByLine(i, 0xff, FF_EXISTS|FF_NOSHADE, secthinkers); + P_AddFakeFloorsByLine(i, 0xff, AST_COPY, FF_EXISTS|FF_NOSHADE, secthinkers); break; case 250: // Mario Block @@ -6682,14 +6697,14 @@ void P_SpawnSpecials(boolean fromnetsave) if (lines[i].args[1] & TMFM_INVISIBLE) ffloorflags &= ~(FF_SOLID|FF_RENDERALL|FF_CUTLEVEL); - P_AddFakeFloorsByLine(i, 0xff, ffloorflags, secthinkers); + P_AddFakeFloorsByLine(i, 0xff, AST_COPY, ffloorflags, secthinkers); break; case 251: // A THWOMP! { UINT16 sound = (lines[i].stringargs[0]) ? get_number(lines[i].stringargs[0]) : sfx_thwomp; P_AddThwompThinker(lines[i].frontsector, &lines[i], lines[i].args[1] << (FRACBITS - 3), lines[i].args[2] << (FRACBITS - 3), sound); - P_AddFakeFloorsByLine(i, 0xff, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); + P_AddFakeFloorsByLine(i, 0xff, AST_COPY, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); break; } @@ -6701,7 +6716,7 @@ void P_SpawnSpecials(boolean fromnetsave) ffloorflags = FF_EXISTS|FF_BLOCKOTHERS|FF_RENDERALL|FF_BUSTUP; //Bustable type - switch (lines[i].args[2]) + switch (lines[i].args[3]) { case TMFB_TOUCH: busttype = BT_TOUCH; @@ -6718,13 +6733,13 @@ void P_SpawnSpecials(boolean fromnetsave) } //Flags - if (lines[i].args[3] & TMFB_PUSHABLES) + if (lines[i].args[4] & TMFB_PUSHABLES) bustflags |= FB_PUSHABLES; - if (lines[i].args[3] & TMFB_EXECUTOR) + if (lines[i].args[4] & TMFB_EXECUTOR) bustflags |= FB_EXECUTOR; - if (lines[i].args[3] & TMFB_ONLYBOTTOM) + if (lines[i].args[4] & TMFB_ONLYBOTTOM) bustflags |= FB_ONLYBOTTOM; - if (lines[i].args[3] & TMFB_SPLAT) + if (lines[i].args[4] & TMFB_SPLAT) ffloorflags |= FF_SPLAT; if (busttype != BT_TOUCH || bustflags & FB_ONLYBOTTOM) @@ -6732,12 +6747,12 @@ void P_SpawnSpecials(boolean fromnetsave) TAG_ITER_SECTORS(lines[i].args[0], s) { - ffloor_t *fflr = P_AddFakeFloor(§ors[s], lines[i].frontsector, lines + i, lines[i].args[1], ffloorflags, secthinkers); + ffloor_t *fflr = P_AddFakeFloor(§ors[s], lines[i].frontsector, lines + i, lines[i].args[1], lines[i].args[2], ffloorflags, secthinkers); if (!fflr) continue; fflr->bustflags = bustflags; fflr->busttype = busttype; - fflr->busttag = lines[i].args[4]; + fflr->busttag = lines[i].args[5]; } break; } @@ -6748,7 +6763,7 @@ void P_SpawnSpecials(boolean fromnetsave) TAG_ITER_SECTORS(lines[i].args[0], s) { - ffloor_t *fflr = P_AddFakeFloor(§ors[s], lines[i].frontsector, lines + i, 0xff, ffloorflags, secthinkers); + ffloor_t *fflr = P_AddFakeFloor(§ors[s], lines[i].frontsector, lines + i, 0xff, AST_COPY, ffloorflags, secthinkers); if (!fflr) continue; fflr->sinkspeed = abs(lines[i].args[2]) << (FRACBITS - 1); @@ -6758,28 +6773,28 @@ void P_SpawnSpecials(boolean fromnetsave) case 258: // Laser block ffloorflags = FF_EXISTS|FF_RENDERALL|FF_NOSHADE|FF_EXTRA|FF_CUTEXTRA|FF_TRANSLUCENT; - P_AddLaserThinker(lines[i].args[0], lines + i, !!(lines[i].args[2] & TMFL_NOBOSSES)); - if (lines[i].args[2] & TMFL_SPLAT) + P_AddLaserThinker(lines[i].args[0], lines + i, !!(lines[i].args[3] & TMFL_NOBOSSES)); + if (lines[i].args[3] & TMFL_SPLAT) ffloorflags |= FF_SPLAT; - P_AddFakeFloorsByLine(i, lines[i].args[1], ffloorflags, secthinkers); + P_AddFakeFloorsByLine(i, lines[i].args[1], lines[i].args[2], ffloorflags, secthinkers); break; case 259: // Custom FOF TAG_ITER_SECTORS(lines[i].args[0], s) { - ffloor_t *fflr = P_AddFakeFloor(§ors[s], lines[i].frontsector, lines + i, lines[i].args[1], lines[i].args[2], secthinkers); + ffloor_t *fflr = P_AddFakeFloor(§ors[s], lines[i].frontsector, lines + i, lines[i].args[1], lines[i].args[2], lines[i].args[3], secthinkers); if (!fflr) continue; if (!udmf) // Ugly backwards compatibility stuff { - if (lines[i].args[2] & FF_QUICKSAND) + if (lines[i].args[3] & FF_QUICKSAND) { fflr->sinkspeed = abs(lines[i].dx) >> 1; fflr->friction = abs(lines[i].dy) >> 6; } - if (lines[i].args[2] & FF_BUSTUP) + if (lines[i].args[3] & FF_BUSTUP) { - switch (lines[i].args[3] % TMFB_ONLYBOTTOM) + switch (lines[i].args[4] % TMFB_ONLYBOTTOM) { case TMFB_TOUCH: fflr->busttype = BT_TOUCH; @@ -6795,7 +6810,7 @@ void P_SpawnSpecials(boolean fromnetsave) break; } - if (lines[i].args[3] & TMFB_ONLYBOTTOM) + if (lines[i].args[4] & TMFB_ONLYBOTTOM) fflr->bustflags |= FB_ONLYBOTTOM; if (lines[i].flags & ML_EFFECT4) fflr->bustflags |= FB_PUSHABLES; @@ -6870,7 +6885,7 @@ void P_SpawnSpecials(boolean fromnetsave) } } - P_AddFakeFloorsByLine(i, dopacity, ffloorflags, secthinkers); + P_AddFakeFloorsByLine(i, dopacity, AST_TRANSLUCENT, ffloorflags, secthinkers); } break; @@ -7159,12 +7174,13 @@ void P_SpawnSpecials(boolean fromnetsave) * * \param line Control linedef to use. * \param alpha Alpha value (0-255). + * \param blendmode Blending mode. * \param ffloorflags 3Dfloor flags to use. * \param secthkiners Lists of thinkers sorted by sector. May be NULL. * \sa P_SpawnSpecials, P_AddFakeFloor * \author Graue */ -static void P_AddFakeFloorsByLine(size_t line, INT32 alpha, ffloortype_e ffloorflags, thinkerlist_t *secthinkers) +static void P_AddFakeFloorsByLine(size_t line, INT32 alpha, UINT8 blendmode, ffloortype_e ffloorflags, thinkerlist_t *secthinkers) { INT32 s; mtag_t tag = lines[line].args[0]; @@ -7172,7 +7188,7 @@ static void P_AddFakeFloorsByLine(size_t line, INT32 alpha, ffloortype_e ffloorf line_t* li = lines + line; TAG_ITER_SECTORS(tag, s) - P_AddFakeFloor(§ors[s], §ors[sec], li, alpha, ffloorflags, secthinkers); + P_AddFakeFloor(§ors[s], §ors[sec], li, alpha, blendmode, ffloorflags, secthinkers); } /* diff --git a/src/p_spec.h b/src/p_spec.h index d02b5989f..40d7197fb 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -448,7 +448,6 @@ typedef enum TMPF_NONEXCLUSIVE = 1<<1, } textmappusherflags_t; - typedef enum { TMPP_NOZFADE = 1, @@ -456,6 +455,15 @@ typedef enum TMPP_NONEXCLUSIVE = 1<<2, } textmappointpushflags_t; +typedef enum +{ + TMB_TRANSLUCENT = 0, + TMB_ADD = 1, + TMB_SUBTRACT = 2, + TMB_REVERSESUBTRACT = 3, + TMB_MODULATE = 4, +} textmapblendmodes_t; + // GETSECSPECIAL (specialval, section) // // Pulls out the special # from a particular section.