Ejemplo n.º 1
0
static void parseSector(FScanner &sc, TMap<int, EDSector> &EDSectors)
{
	EDSector sec;

	memset(&sec, 0, sizeof(sec));
	sec.Overlayalpha[sector_t::floor] = sec.Overlayalpha[sector_t::ceiling] = 1.;
	sec.floorterrain = sec.ceilingterrain = -1;

	sc.MustGetStringName("{");
	while (!sc.CheckString("}"))
	{
		sc.MustGetString();
		if (sc.Compare("recordnum"))
		{
			sc.CheckString("=");
			sc.MustGetNumber();
			sec.recordnum = sc.Number;
		}
		else if (sc.Compare("flags"))
		{
			uint32_t *flagvar = nullptr;
			if (sc.CheckString("."))
			{
				sc.MustGetString();
				if (sc.Compare("add"))
				{
					flagvar = &sec.flagsAdd;
				}
				else if (sc.Compare("remove"))
				{
					flagvar = &sec.flagsRemove;
				}
				else
				{
					sc.ScriptError("Invalid property  'flags.%s'", sc.String);
				}
			}
			else
			{
				sec.flagsSet = true;
				flagvar = &sec.flags;
			}
			sc.CheckString("=");
			do
			{
				sc.MustGetString();
				for (const char *tok = strtok(sc.String, ",+ \t"); tok != nullptr; tok = strtok(nullptr, ",+ \t"))
				{
					if (!stricmp(tok, "SECRET")) *flagvar |= SECF_SECRET | SECF_WASSECRET;
					else if (!stricmp(tok, "FRICTION")) *flagvar |= SECF_FRICTION;
					else if (!stricmp(tok, "PUSH")) *flagvar |= SECF_PUSH;
					else if (!stricmp(tok, "KILLSOUND")) *flagvar |= SECF_SILENT;
					else if (!stricmp(tok, "KILLMOVESOUND")) *flagvar |= SECF_SILENTMOVE;
					else sc.ScriptError("Unknown option '%s'", tok);
				}
			} while (sc.CheckString("|"));	// Unquoted strings with '|' separator - parse as a separate string in the loop.
		}
		else if (sc.Compare("damage"))
		{
			sc.CheckString("=");
			sc.MustGetNumber();
			sec.damageamount = sc.Number;
		}
		else if (sc.Compare("damagemod"))
		{
			sc.CheckString("=");
			sc.MustGetString();
			sec.damagetype = sc.String;
		}
		else if (sc.Compare("damagemask"))
		{
			sc.CheckString("=");
			sc.MustGetNumber();
			sec.damageinterval = sc.Number;
		}
		else if (sc.Compare("damageflags"))
		{
			uint32_t *flagvar = nullptr;
			uint8_t *leakvar = nullptr;
			if (sc.CheckString("."))
			{
				sc.MustGetString();
				if (sc.Compare("add"))
				{
					flagvar = &sec.damageflagsAdd;
					leakvar = &sec.leakyadd;
				}
				else if (sc.Compare("remove"))
				{
					flagvar = &sec.damageflagsRemove;
					leakvar = &sec.leakyremove;
				}
				else
				{
					sc.ScriptError("Invalid property  'flags.%s'", sc.String);
				}
			}
			else
			{
				sec.damageflagsSet = true;
				flagvar = &sec.damageflags;
				leakvar = &sec.leaky;
			}
			sc.CheckString("=");
			do
			{
				sc.MustGetString();
				for (const char *tok = strtok(sc.String, ",+ \t"); tok != nullptr; tok = strtok(nullptr, ",+ \t"))
				{
					if (!stricmp(tok, "LEAKYSUIT")) *leakvar |= 1;
					else if (!stricmp(tok, "IGNORESUIT")) *leakvar |= 2;	// these 2 bits will be used to set 'leakychance', but this can only be done when the sector gets initialized
					else if (!stricmp(tok, "ENDGODMODE")) *flagvar |= SECF_ENDGODMODE;
					else if (!stricmp(tok, "ENDLEVEL")) *flagvar |= SECF_ENDLEVEL;
					else if (!stricmp(tok, "TERRAINHIT")) *flagvar |= SECF_DMGTERRAINFX;
					else sc.ScriptError("Unknown option '%s'", tok);
				}
			} while (sc.CheckString("|"));	// Unquoted strings with '|' separator - parse as a separate string in the loop.
		}
		else if (sc.Compare("floorterrain"))
		{
			sc.CheckString("=");
			sc.MustGetString();
			sec.floorterrain = P_FindTerrain(sc.String);
		}
		else if (sc.Compare("floorangle"))
		{
			sc.CheckString("=");
			sc.MustGetFloat();
			sec.angle[sector_t::floor] = sc.Float;
		}
		else if (sc.Compare("flooroffsetx"))
		{
			sc.CheckString("=");
			sc.MustGetFloat();
			sec.xoffs[sector_t::floor] = sc.Float;
		}
		else if (sc.Compare("flooroffsety"))
		{
			sc.CheckString("=");
			sc.MustGetFloat();
			sec.yoffs[sector_t::floor] = sc.Float;
		}
		else if (sc.Compare("ceilingterrain"))
		{
			sc.CheckString("=");
			sc.MustGetString();
			sec.ceilingterrain = P_FindTerrain(sc.String);
		}
		else if (sc.Compare("ceilingangle"))
		{
			sc.CheckString("=");
			sc.MustGetFloat();
			sec.angle[sector_t::ceiling] = sc.Float;
		}
		else if (sc.Compare("ceilingoffsetx"))
		{
			sc.CheckString("=");
			sc.MustGetFloat();
			sec.xoffs[sector_t::ceiling] = sc.Float;
		}
		else if (sc.Compare("ceilingoffsety"))
		{
			sc.CheckString("=");
			sc.MustGetFloat();
			sec.yoffs[sector_t::ceiling] = sc.Float;
		}
		else if (sc.Compare("colormaptop") || sc.Compare("colormapbottom"))
		{
			sc.CheckString("=");
			sc.MustGetString();
			// these properties are not implemented by ZDoom
		}
		else if (sc.Compare("colormapmid"))
		{
			sc.CheckString("=");
			sc.MustGetString();
			// Eternity is based on SMMU and uses colormaps differently than all other ports.
			// The only solution here is to convert the colormap to an RGB value and set it as the sector's color.
			uint32_t cmap = R_ColormapNumForName(sc.String);
			if (cmap != 0)
			{
				sec.color = R_BlendForColormap(cmap) & 0xff000000;
				sec.colorSet = true;
			}
		}
		else if (sc.Compare("overlayalpha"))
		{
			sc.MustGetStringName(".");
			sc.MustGetString();
			if (sc.Compare("floor"))
			{
				sc.MustGetNumber();
				if (sc.CheckString("%")) sc.Float = sc.Number / 100.f;
				else sc.Float = sc.Number / 255.f;
				sec.Overlayalpha[sector_t::floor] = sc.Float;
			}
			else if (sc.Compare("ceiling"))
			{
				sc.MustGetFloat();
				if (sc.CheckString("%")) sc.Float = sc.Number / 100.f;
				else sc.Float = sc.Number / 255.f;
				sec.Overlayalpha[sector_t::floor] = sc.Float;
			}
		}
		else if (sc.Compare("portalflags"))
		{
			int dest = 0;
			sc.MustGetStringName(".");
			sc.MustGetString();
			if (sc.Compare("floor")) dest = sector_t::floor;
			else if (sc.Compare("ceiling")) dest = sector_t::ceiling;
			else sc.ScriptError("Unknown portal type '%s'", sc.String);

			sc.CheckString("=");
			do
			{
				sc.MustGetString();
				for (const char *tok = strtok(sc.String, ",+ \t"); tok != nullptr; tok = strtok(nullptr, ",+ \t"))
				{
					if (!stricmp(tok, "DISABLED")) sec.portalflags[dest] |= PLANEF_DISABLED;
					else if (!stricmp(tok, "NORENDER")) sec.portalflags[dest] |= PLANEF_NORENDER;
					else if (!stricmp(tok, "NOPASS")) sec.portalflags[dest] |= PLANEF_NOPASS;
					else if (!stricmp(tok, "BLOCKSOUND")) sec.portalflags[dest] |= PLANEF_BLOCKSOUND;
					else if (!stricmp(tok, "OVERLAY")) sec.portalflags[dest] |= 0;	// we do not use this. Alpha is the sole determinant for overlay drawing
					else if (!stricmp(tok, "ADDITIVE")) sec.portalflags[dest] |= PLANEF_ADDITIVE;
					else if (!stricmp(tok, "USEGLOBALTEX")) {}	// not implemented
					else sc.ScriptError("Unknown option '%s'", tok);
				}
			} while (sc.CheckString("|"));	// Unquoted strings with '|' separator - parse as a separate string in the loop.
		}
		else
		{
			sc.ScriptError("Unknown property '%s'", sc.String);
		}
	}
	EDSectors[sec.recordnum] = sec;
}
Ejemplo n.º 2
0
//==========================================================================
//
// Draws a blend over the entire view
//
//==========================================================================
void FGLRenderer::DrawBlend(sector_t * viewsector)
{
	float blend[4]={0,0,0,0};
	PalEntry blendv=0;
	float extra_red;
	float extra_green;
	float extra_blue;
	player_t *player = NULL;

	if (players[consoleplayer].camera != NULL)
	{
		player=players[consoleplayer].camera->player;
	}

	// don't draw sector based blends when an invulnerability colormap is active
	if (!gl_fixedcolormap)
	{
		if (!viewsector->e->XFloor.ffloors.Size())
		{
			if (viewsector->heightsec && !(viewsector->MoreFlags&SECF_IGNOREHEIGHTSEC))
			{
				switch (in_area)
				{
				default:
				case area_normal: blendv = viewsector->heightsec->midmap; break;
				case area_above: blendv = viewsector->heightsec->topmap; break;
				case area_below: blendv = viewsector->heightsec->bottommap; break;
				}
			}
		}
		else
		{
			TArray<lightlist_t> & lightlist = viewsector->e->XFloor.lightlist;

			for (unsigned int i = 0; i < lightlist.Size(); i++)
			{
				double lightbottom;
				if (i < lightlist.Size() - 1)
					lightbottom = lightlist[i + 1].plane.ZatPoint(ViewPos);
				else
					lightbottom = viewsector->floorplane.ZatPoint(ViewPos);

				if (lightbottom < ViewPos.Z && (!lightlist[i].caster || !(lightlist[i].caster->flags&FF_FADEWALLS)))
				{
					// 3d floor 'fog' is rendered as a blending value
					blendv = lightlist[i].blend;
					// If this is the same as the sector's it doesn't apply!
					if (blendv == viewsector->ColorMap->Fade) blendv = 0;
					// a little hack to make this work for Legacy maps.
					if (blendv.a == 0 && blendv != 0) blendv.a = 128;
					break;
				}
			}
		}

		if (blendv.a == 0)
		{
			blendv = R_BlendForColormap(blendv);
			if (blendv.a == 255)
			{
				// The calculated average is too dark so brighten it according to the palettes's overall brightness
				int maxcol = MAX<int>(MAX<int>(framebuffer->palette_brightness, blendv.r), MAX<int>(blendv.g, blendv.b));
				blendv.r = blendv.r * 255 / maxcol;
				blendv.g = blendv.g * 255 / maxcol;
				blendv.b = blendv.b * 255 / maxcol;
			}
		}

		if (blendv.a == 255)
		{

			extra_red = blendv.r / 255.0f;
			extra_green = blendv.g / 255.0f;
			extra_blue = blendv.b / 255.0f;

			// If this is a multiplicative blend do it separately and add the additive ones on top of it.
			blendv = 0;

			// black multiplicative blends are ignored
			if (extra_red || extra_green || extra_blue)
			{
				gl_RenderState.BlendFunc(GL_DST_COLOR, GL_ZERO);
				gl_RenderState.SetColor(extra_red, extra_green, extra_blue, 1.0f);
				gl_FillScreen();
			}
		}
		else if (blendv.a)
		{
			// [Nash] allow user to set blend intensity
			int cnt = blendv.a;
			cnt = (int)(cnt * underwater_fade_scalar);

			V_AddBlend(blendv.r / 255.f, blendv.g / 255.f, blendv.b / 255.f, cnt / 255.0f, blend);
		}
	}

	// This mostly duplicates the code in shared_sbar.cpp
	// When I was writing this the original was called too late so that I
	// couldn't get the blend in time. However, since then I made some changes
	// here that would get lost if I switched back so I won't do it.

	if (player)
	{
		V_AddPlayerBlend(player, blend, 0.5, 175);
	}
	
	if (players[consoleplayer].camera != NULL)
	{
		// except for fadeto effects
		player_t *player = (players[consoleplayer].camera->player != NULL) ? players[consoleplayer].camera->player : &players[consoleplayer];
		V_AddBlend (player->BlendR, player->BlendG, player->BlendB, player->BlendA, blend);
	}

	gl_RenderState.SetTextureMode(TM_MODULATE);
	gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	if (blend[3]>0.0f)
	{
		gl_RenderState.SetColor(blend[0], blend[1], blend[2], blend[3]);
		gl_FillScreen();
	}
	gl_RenderState.ResetColor();
	gl_RenderState.EnableTexture(true);
}