示例#1
0
FDynamicColormap *F3DFloor::GetColormap()
{
	// If there's no fog in either model or target sector this is easy and fast.
	if ((target->ColorMap->Fade == 0 && model->ColorMap->Fade == 0) || (flags & (FF_FADEWALLS|FF_FOG)))
	{
		return model->ColorMap;
	}
	else
	{
		// We must create a new colormap combining the properties we need
		return GetSpecialLights(model->ColorMap->Color, target->ColorMap->Fade, model->ColorMap->Desaturate);
	}
}
示例#2
0
void F3DFloor::UpdateColormap(FDynamicColormap *&map)
{
	// If there's no fog in either model or target sector (or both have the same fog) this is easy and fast.
	if ((target->ColorMap->Fade == 0 && model->ColorMap->Fade == 0) || (flags & FF_FADEWALLS) ||
		target->ColorMap->Fade == model->ColorMap->Fade)
	{
		map = model->ColorMap;
	}
	else
	{
		// since rebuilding the map is not a cheap operation let's only do it if something really changed.
		if (map->Color != model->ColorMap->Color || map->Fade != target->ColorMap->Fade ||
			map->Desaturate != model->ColorMap->Desaturate)
		{
			map = GetSpecialLights(model->ColorMap->Color, target->ColorMap->Fade, model->ColorMap->Desaturate);
		}
	}
}
示例#3
0
	void ParseSector(sector_t *sec, int index)
	{
		int lightcolor = -1;
		int fadecolor = -1;
		int desaturation = -1;
		int fplaneflags = 0, cplaneflags = 0;
		double fp[4] = { 0 }, cp[4] = { 0 };

		memset(sec, 0, sizeof(*sec));
		sec->lightlevel = 160;
		sec->SetXScale(sector_t::floor, FRACUNIT);	// [RH] floor and ceiling scaling
		sec->SetYScale(sector_t::floor, FRACUNIT);
		sec->SetXScale(sector_t::ceiling, FRACUNIT);
		sec->SetYScale(sector_t::ceiling, FRACUNIT);
		sec->SetAlpha(sector_t::floor, FRACUNIT);
		sec->SetAlpha(sector_t::ceiling, FRACUNIT);
		sec->thinglist = NULL;
		sec->touching_thinglist = NULL;		// phares 3/14/98
		sec->seqType = (level.flags & LEVEL_SNDSEQTOTALCTRL) ? 0 : -1;
		sec->nextsec = -1;	//jff 2/26/98 add fields to support locking out
		sec->prevsec = -1;	// stair retriggering until build completes
		sec->heightsec = NULL;	// sector used to get floor and ceiling height
		sec->sectornum = index;
		if (floordrop) sec->Flags = SECF_FLOORDROP;
		// killough 3/7/98: end changes

		sec->gravity = 1.f;	// [RH] Default sector gravity of 1.0
		sec->ZoneNumber = 0xFFFF;

		// killough 8/28/98: initialize all sectors to normal friction
		sec->friction = ORIG_FRICTION;
		sec->movefactor = ORIG_FRICTION_FACTOR;

		sc.MustGetToken('{');
		while (!sc.CheckToken('}'))
		{
			FName key = ParseKey();
			switch(key)
			{
			case NAME_Heightfloor:
				sec->SetPlaneTexZ(sector_t::floor, CheckInt(key) << FRACBITS);
				continue;

			case NAME_Heightceiling:
				sec->SetPlaneTexZ(sector_t::ceiling, CheckInt(key) << FRACBITS);
				continue;

			case NAME_Texturefloor:
				SetTexture(sec, index, sector_t::floor, CheckString(key), missingTex, false);
				continue;

			case NAME_Textureceiling:
				SetTexture(sec, index, sector_t::ceiling, CheckString(key), missingTex, false);
				continue;

			case NAME_Lightlevel:
				sec->lightlevel = sector_t::ClampLight(CheckInt(key));
				continue;

			case NAME_Special:
				sec->special = (short)CheckInt(key);
				if (isTranslated) sec->special = P_TranslateSectorSpecial(sec->special);
				else if (namespc == NAME_Hexen)
				{
					if (sec->special < 0 || sec->special > 255 || !HexenSectorSpecialOk[sec->special])
						sec->special = 0;	// NULL all unknown specials
				}
				continue;

			case NAME_Id:
				sec->tag = (short)CheckInt(key);
				continue;

			default:
				break;
			}

			if (namespace_bits & (Zd|Zdt|Va)) switch(key)
			{
				case NAME_Xpanningfloor:
					sec->SetXOffset(sector_t::floor, CheckFixed(key));
					continue;

				case NAME_Ypanningfloor:
					sec->SetYOffset(sector_t::floor, CheckFixed(key));
					continue;

				case NAME_Xpanningceiling:
					sec->SetXOffset(sector_t::ceiling, CheckFixed(key));
					continue;

				case NAME_Ypanningceiling:
					sec->SetYOffset(sector_t::ceiling, CheckFixed(key));
					continue;

				case NAME_Xscalefloor:
					sec->SetXScale(sector_t::floor, CheckFixed(key));
					continue;

				case NAME_Yscalefloor:
					sec->SetYScale(sector_t::floor, CheckFixed(key));
					continue;

				case NAME_Xscaleceiling:
					sec->SetXScale(sector_t::ceiling, CheckFixed(key));
					continue;

				case NAME_Yscaleceiling:
					sec->SetYScale(sector_t::ceiling, CheckFixed(key));
					continue;

				case NAME_Rotationfloor:
					sec->SetAngle(sector_t::floor, CheckAngle(key));
					continue;

				case NAME_Rotationceiling:
					sec->SetAngle(sector_t::ceiling, CheckAngle(key));
					continue;

				case NAME_Lightfloor:
					sec->SetPlaneLight(sector_t::floor, CheckInt(key));
					continue;

				case NAME_Lightceiling:
					sec->SetPlaneLight(sector_t::ceiling, CheckInt(key));
					continue;

				case NAME_Alphafloor:
					sec->SetAlpha(sector_t::floor, CheckFixed(key));
					continue;

				case NAME_Alphaceiling:
					sec->SetAlpha(sector_t::ceiling, CheckFixed(key));
					continue;

				case NAME_Renderstylefloor:
				{
					const char *str = CheckString(key);
					if (!stricmp(str, "translucent")) sec->ChangeFlags(sector_t::floor, PLANEF_ADDITIVE, 0);
					else if (!stricmp(str, "add")) sec->ChangeFlags(sector_t::floor, 0, PLANEF_ADDITIVE);
					else sc.ScriptMessage("Unknown value \"%s\" for 'renderstylefloor'\n", str);
					continue;
				}

				case NAME_Renderstyleceiling:
				{
					const char *str = CheckString(key);
					if (!stricmp(str, "translucent")) sec->ChangeFlags(sector_t::ceiling, PLANEF_ADDITIVE, 0);
					else if (!stricmp(str, "add")) sec->ChangeFlags(sector_t::ceiling, 0, PLANEF_ADDITIVE);
					else sc.ScriptMessage("Unknown value \"%s\" for 'renderstyleceiling'\n", str);
					continue;
				}

				case NAME_Lightfloorabsolute:
					if (CheckBool(key)) sec->ChangeFlags(sector_t::floor, 0, PLANEF_ABSLIGHTING);
					else sec->ChangeFlags(sector_t::floor, PLANEF_ABSLIGHTING, 0);
					continue;

				case NAME_Lightceilingabsolute:
					if (CheckBool(key)) sec->ChangeFlags(sector_t::ceiling, 0, PLANEF_ABSLIGHTING);
					else sec->ChangeFlags(sector_t::ceiling, PLANEF_ABSLIGHTING, 0);
					continue;

				case NAME_Gravity:
					sec->gravity = float(CheckFloat(key));
					continue;

				case NAME_Lightcolor:
					lightcolor = CheckInt(key);
					continue;

				case NAME_Fadecolor:
					fadecolor = CheckInt(key);
					continue;

				case NAME_Desaturation:
					desaturation = int(255*CheckFloat(key));
					continue;

				case NAME_Silent:
					Flag(sec->Flags, SECF_SILENT, key);
					continue;

				case NAME_NoRespawn:
					Flag(sec->Flags, SECF_NORESPAWN, key);
					continue;

				case NAME_Nofallingdamage:
					Flag(sec->Flags, SECF_NOFALLINGDAMAGE, key);
					continue;

				case NAME_Dropactors:
					Flag(sec->Flags, SECF_FLOORDROP, key);
					continue;

				case NAME_SoundSequence:
					sec->SeqName = CheckString(key);
					sec->seqType = -1;
					continue;

				case NAME_hidden:
					Flag(sec->MoreFlags, SECF_HIDDEN, key);
					break;

				case NAME_Waterzone:
					Flag(sec->MoreFlags, SECF_UNDERWATER, key);
					break;

				case NAME_floorplane_a:
					fplaneflags |= 1;
					fp[0] = CheckFloat(key);
					break;

				case NAME_floorplane_b:
					fplaneflags |= 2;
					fp[1] = CheckFloat(key);
					break;

				case NAME_floorplane_c:
					fplaneflags |= 4;
					fp[2] = CheckFloat(key);
					break;

				case NAME_floorplane_d:
					fplaneflags |= 8;
					fp[3] = CheckFloat(key);
					break;

				case NAME_ceilingplane_a:
					cplaneflags |= 1;
					cp[0] = CheckFloat(key);
					break;

				case NAME_ceilingplane_b:
					cplaneflags |= 2;
					cp[1] = CheckFloat(key);
					break;

				case NAME_ceilingplane_c:
					cplaneflags |= 4;
					cp[2] = CheckFloat(key);
					break;

				case NAME_ceilingplane_d:
					cplaneflags |= 8;
					cp[3] = CheckFloat(key);
					break;

				default:
					break;
			}
				
			if (!strnicmp("user_", key.GetChars(), 5))
			{
				AddUserKey(key, UDMF_Sector, index);
			}
		}

		sec->secretsector = !!(sec->special&SECRET_MASK);
		
		// Reset the planes to their defaults if not all of the plane equation's parameters were found.
		if (fplaneflags != 15)
		{
			sec->floorplane.a = sec->floorplane.b = 0;
			sec->floorplane.d = -sec->GetPlaneTexZ(sector_t::floor);
			sec->floorplane.c = FRACUNIT;
			sec->floorplane.ic = FRACUNIT;
		}
		else
		{
			double ulen = TVector3<double>(fp[0], fp[1], fp[2]).Length();

			// normalize the vector, it must have a length of 1
			sec->floorplane.a = FLOAT2FIXED(fp[0] / ulen);
			sec->floorplane.b = FLOAT2FIXED(fp[1] / ulen);
			sec->floorplane.c = FLOAT2FIXED(fp[2] / ulen);
			sec->floorplane.d = FLOAT2FIXED(fp[3] / ulen);
			sec->floorplane.ic = FLOAT2FIXED(ulen / fp[2]);
		}
		if (cplaneflags != 15)
		{
			sec->ceilingplane.a = sec->ceilingplane.b = 0;
			sec->ceilingplane.d = sec->GetPlaneTexZ(sector_t::ceiling);
			sec->ceilingplane.c = -FRACUNIT;
			sec->ceilingplane.ic = -FRACUNIT;
		}
		else
		{
			double ulen = TVector3<double>(cp[0], cp[1], cp[2]).Length();

			// normalize the vector, it must have a length of 1
			sec->floorplane.a = FLOAT2FIXED(cp[0] / ulen);
			sec->floorplane.b = FLOAT2FIXED(cp[1] / ulen);
			sec->floorplane.c = FLOAT2FIXED(cp[2] / ulen);
			sec->floorplane.d = FLOAT2FIXED(cp[3] / ulen);
			sec->floorplane.ic = FLOAT2FIXED(ulen / cp[2]);
		}

		if (lightcolor == -1 && fadecolor == -1 && desaturation == -1)
		{
			// [RH] Sectors default to white light with the default fade.
			//		If they are outside (have a sky ceiling), they use the outside fog.
			if (level.outsidefog != 0xff000000 && (sec->GetTexture(sector_t::ceiling) == skyflatnum || (sec->special&0xff) == Sector_Outside))
			{
				if (fogMap == NULL)
					fogMap = GetSpecialLights (PalEntry (255,255,255), level.outsidefog, 0);
				sec->ColorMap = fogMap;
			}
			else
			{
				if (normMap == NULL)
					normMap = GetSpecialLights (PalEntry (255,255,255), level.fadeto, NormalLight.Desaturate);
				sec->ColorMap = normMap;
			}
		}
		else
		{
			if (lightcolor == -1) lightcolor = PalEntry(255,255,255);
			if (fadecolor == -1) 
			{
				if (level.outsidefog != 0xff000000 && (sec->GetTexture(sector_t::ceiling) == skyflatnum || (sec->special&0xff) == Sector_Outside))
					fadecolor = level.outsidefog;
				else
					fadecolor = level.fadeto;
			}
			if (desaturation == -1) desaturation = NormalLight.Desaturate;

			sec->ColorMap = GetSpecialLights (lightcolor, fadecolor, desaturation);
		}
	}
示例#4
0
//
// P_ArchiveWorld
//
void P_SerializeWorld (FArchive &arc)
{
	int i, j;
	sector_t *sec;
	line_t *li;

	if (arc.IsStoring ())
	{ // saving to archive

		// do sectors
		for (i = 0, sec = sectors; i < numsectors; i++, sec++)
		{
			arc << sec->floorheight
				<< sec->ceilingheight
				<< sec->floorplane.a
				<< sec->floorplane.b
				<< sec->floorplane.c
				<< sec->floorplane.d
				<< sec->ceilingplane.a
				<< sec->ceilingplane.b
				<< sec->ceilingplane.c
				<< sec->ceilingplane.d
				<< sec->floorpic
				<< sec->ceilingpic
				<< sec->lightlevel
				<< sec->special
				<< sec->tag
				<< sec->soundtraversed
				/*<< sec->soundtarget*/
				<< sec->friction
				<< sec->movefactor
				<< sec->floordata
				<< sec->ceilingdata
				<< sec->lightingdata
				<< sec->stairlock
				<< sec->prevsec
				<< sec->nextsec
				<< sec->floor_xoffs << sec->floor_yoffs
				<< sec->ceiling_xoffs << sec->ceiling_xoffs
				<< sec->floor_xscale << sec->floor_yscale
				<< sec->ceiling_xscale << sec->ceiling_yscale
				<< sec->floor_angle << sec->ceiling_angle
				<< sec->base_ceiling_angle << sec->base_ceiling_yoffs
				<< sec->base_floor_angle << sec->base_floor_yoffs
				<< sec->heightsec
				<< sec->floorlightsec << sec->ceilinglightsec
				<< sec->bottommap << sec->midmap << sec->topmap
				<< sec->gravity
				<< sec->damage
				<< sec->mod
				<< sec->floorcolormap->color
				<< sec->floorcolormap->fade
				<< sec->ceilingcolormap->color
				<< sec->ceilingcolormap->fade
				<< sec->alwaysfake
				<< sec->waterzone
				<< sec->SecActTarget
				<< sec->MoreFlags;
		}

		// do lines
		for (i = 0, li = lines; i < numlines; i++, li++)
		{
			arc << li->flags
				<< li->special
				<< li->lucency
				<< li->id
				<< li->args[0] << li->args[1] << li->args[2] << li->args[3] << li->args[4] << (WORD)0;

			for (j = 0; j < 2; j++)
			{
				if (li->sidenum[j] == R_NOSIDE)
					continue;

				side_t *si = &sides[li->sidenum[j]];
				arc << si->textureoffset
					<< si->rowoffset
					<< si->toptexture
					<< si->bottomtexture
					<< si->midtexture;
			}
		}
	}
	else
	{ // loading from archive

		// do sectors
		for (i = 0, sec = sectors; i < numsectors; i++, sec++)
		{

			unsigned int color=0, fade=0;
			AActor* SecActTarget;

			arc >> sec->floorheight
				>> sec->ceilingheight
				>> sec->floorplane.a
				>> sec->floorplane.b
				>> sec->floorplane.c
				>> sec->floorplane.d
				>> sec->ceilingplane.a
				>> sec->ceilingplane.b
				>> sec->ceilingplane.c
				>> sec->ceilingplane.d
				>> sec->floorpic
				>> sec->ceilingpic
				>> sec->lightlevel
				>> sec->special
				>> sec->tag
				>> sec->soundtraversed
				/*>> sec->soundtarget->netid*/
				>> sec->friction
				>> sec->movefactor
				>> sec->floordata
				>> sec->ceilingdata
				>> sec->lightingdata
				>> sec->stairlock
				>> sec->prevsec
				>> sec->nextsec
				>> sec->floor_xoffs >> sec->floor_yoffs
				>> sec->ceiling_xoffs >> sec->ceiling_xoffs
				>> sec->floor_xscale >> sec->floor_yscale
				>> sec->ceiling_xscale >> sec->ceiling_yscale
				>> sec->floor_angle >> sec->ceiling_angle
				>> sec->base_ceiling_angle >> sec->base_ceiling_yoffs
				>> sec->base_floor_angle >> sec->base_floor_yoffs
				>> sec->heightsec
				>> sec->floorlightsec >> sec->ceilinglightsec
				>> sec->bottommap >> sec->midmap >> sec->topmap
				>> sec->gravity
				>> sec->damage
				>> sec->mod
                >> color
				>> fade;
			sec->floorcolormap = GetSpecialLights (
				RPART(color), GPART(color), BPART(color),
				RPART(fade), GPART(fade), BPART(fade));
			arc >> color >> fade;
			sec->ceilingcolormap = GetSpecialLights (
				RPART(color), GPART(color), BPART(color),
				RPART(fade), GPART(fade), BPART(fade));
			arc >> sec->alwaysfake
				>> sec->waterzone
				>> SecActTarget
				>> sec->MoreFlags;

			sec->floorplane.invc = FixedDiv(FRACUNIT, sec->floorplane.c);
			sec->floorplane.sector = sec;
			sec->ceilingplane.invc = FixedDiv(FRACUNIT, sec->ceilingplane.c);
			sec->ceilingplane.sector = sec;
			sec->SecActTarget.init(SecActTarget);
		}

		// do lines
		for (i = 0, li = lines; i < numlines; i++, li++)
		{
		    WORD dummy;
			arc >> li->flags
				>> li->special
				>> li->lucency
				>> li->id
				>> li->args[0] >> li->args[1] >> li->args[2] >> li->args[3] >> li->args[4] >> dummy;

			for (j = 0; j < 2; j++)
			{
				if (li->sidenum[j] == R_NOSIDE)
					continue;

				side_t *si = &sides[li->sidenum[j]];
				arc >> si->textureoffset
					>> si->rowoffset
					>> si->toptexture
					>> si->bottomtexture
					>> si->midtexture;
			}
		}
	}
}
static void LoadSectors (sectortype *bsec)
{
    FDynamicColormap *map = GetSpecialLights (PalEntry (255,255,255), level.fadeto, 0);
    sector_t *sec;
    char tnam[9];

    sec = sectors = new sector_t[numsectors];
    memset (sectors, 0, sizeof(sector_t)*numsectors);

    sectors[0].e = new extsector_t[numsectors];

    for (int i = 0; i < numsectors; ++i, ++bsec, ++sec)
    {
        bsec->wallptr = WORD(bsec->wallptr);
        bsec->wallnum = WORD(bsec->wallnum);
        bsec->ceilingstat = WORD(bsec->ceilingstat);
        bsec->floorstat = WORD(bsec->floorstat);

        sec->e = &sectors[0].e[i];
        sec->SetPlaneTexZ(sector_t::floor, -(LittleLong(bsec->floorz) << 8));
        sec->floorplane.d = -sec->GetPlaneTexZ(sector_t::floor);
        sec->floorplane.c = FRACUNIT;
        sec->floorplane.ic = FRACUNIT;
        mysnprintf (tnam, countof(tnam), "BTIL%04d", LittleShort(bsec->floorpicnum));
        sec->SetTexture(sector_t::floor, TexMan.GetTexture (tnam, FTexture::TEX_Build));
        sec->SetXScale(sector_t::floor, (bsec->floorstat & 8) ? FRACUNIT*2 : FRACUNIT);
        sec->SetYScale(sector_t::floor, (bsec->floorstat & 8) ? FRACUNIT*2 : FRACUNIT);
        sec->SetXOffset(sector_t::floor, (bsec->floorxpanning << FRACBITS) + (32 << FRACBITS));
        sec->SetYOffset(sector_t::floor, bsec->floorypanning << FRACBITS);
        sec->SetPlaneLight(sector_t::floor, SHADE2LIGHT (bsec->floorshade));
        sec->ChangeFlags(sector_t::floor, 0, PLANEF_ABSLIGHTING);

        sec->SetPlaneTexZ(sector_t::ceiling, -(LittleLong(bsec->ceilingz) << 8));
        sec->ceilingplane.d = sec->GetPlaneTexZ(sector_t::ceiling);
        sec->ceilingplane.c = -FRACUNIT;
        sec->ceilingplane.ic = -FRACUNIT;
        mysnprintf (tnam, countof(tnam), "BTIL%04d", LittleShort(bsec->ceilingpicnum));
        sec->SetTexture(sector_t::ceiling, TexMan.GetTexture (tnam, FTexture::TEX_Build));
        if (bsec->ceilingstat & 1)
        {
            sky1texture = sky2texture = sec->GetTexture(sector_t::ceiling);
            sec->SetTexture(sector_t::ceiling, skyflatnum);
        }
        sec->SetXScale(sector_t::ceiling, (bsec->ceilingstat & 8) ? FRACUNIT*2 : FRACUNIT);
        sec->SetYScale(sector_t::ceiling, (bsec->ceilingstat & 8) ? FRACUNIT*2 : FRACUNIT);
        sec->SetXOffset(sector_t::ceiling, (bsec->ceilingxpanning << FRACBITS) + (32 << FRACBITS));
        sec->SetYOffset(sector_t::ceiling, bsec->ceilingypanning << FRACBITS);
        sec->SetPlaneLight(sector_t::ceiling, SHADE2LIGHT (bsec->ceilingshade));
        sec->ChangeFlags(sector_t::ceiling, 0, PLANEF_ABSLIGHTING);

        sec->lightlevel = (sec->GetPlaneLight(sector_t::floor) + sec->GetPlaneLight(sector_t::ceiling)) / 2;

        sec->seqType = -1;
        sec->SeqName = NAME_None;
        sec->nextsec = -1;
        sec->prevsec = -1;
        sec->gravity = 1.f;
        sec->friction = ORIG_FRICTION;
        sec->movefactor = ORIG_FRICTION_FACTOR;
        sec->ColorMap = map;
        sec->ZoneNumber = 0xFFFF;

        if (bsec->floorstat & 4)
        {
            sec->SetAngle(sector_t::floor, ANGLE_90);
            sec->SetXScale(sector_t::floor, -sec->GetXScale(sector_t::floor));
        }
        if (bsec->floorstat & 16)
        {
            sec->SetXScale(sector_t::floor, -sec->GetXScale(sector_t::floor));
        }
        if (bsec->floorstat & 32)
        {
            sec->SetYScale(sector_t::floor, -sec->GetYScale(sector_t::floor));
        }

        if (bsec->ceilingstat & 4)
        {
            sec->SetAngle(sector_t::ceiling, ANGLE_90);
            sec->SetYScale(sector_t::ceiling, -sec->GetYScale(sector_t::ceiling));
        }
        if (bsec->ceilingstat & 16)
        {
            sec->SetXScale(sector_t::ceiling, -sec->GetXScale(sector_t::ceiling));
        }
        if (bsec->ceilingstat & 32)
        {
            sec->SetYScale(sector_t::ceiling, -sec->GetYScale(sector_t::ceiling));
        }
    }
}
示例#6
0
//
// P_ArchiveWorld
//
void P_SerializeWorld (FArchive &arc)
{
	int i, j;
	sector_t *sec;
	line_t *li;
	zone_t *zn;

	// do sectors
	for (i = 0, sec = sectors; i < numsectors; i++, sec++)
	{
		arc << sec->floorplane
			<< sec->ceilingplane;
		if (SaveVersion < 3223)
		{
			BYTE bytelight;
			arc << bytelight;
			sec->lightlevel = bytelight;
		}
		else
		{
			arc << sec->lightlevel;
		}
		arc << sec->special
			<< sec->tag
			<< sec->soundtraversed
			<< sec->seqType
			<< sec->friction
			<< sec->movefactor
			<< sec->floordata
			<< sec->ceilingdata
			<< sec->lightingdata
			<< sec->stairlock
			<< sec->prevsec
			<< sec->nextsec
			<< sec->planes[sector_t::floor]
			<< sec->planes[sector_t::ceiling]
			<< sec->heightsec
			<< sec->bottommap << sec->midmap << sec->topmap
			<< sec->gravity
			<< sec->damage
			<< sec->mod
			<< sec->SoundTarget
			<< sec->SecActTarget
			<< sec->sky
			<< sec->MoreFlags
			<< sec->Flags
			<< sec->FloorSkyBox << sec->CeilingSkyBox
			<< sec->ZoneNumber
			<< sec->secretsector
			<< sec->interpolations[0]
			<< sec->interpolations[1]
			<< sec->interpolations[2]
			<< sec->interpolations[3]
			<< sec->SeqName;

		sec->e->Serialize(arc);
		if (arc.IsStoring ())
		{
			arc << sec->ColorMap->Color
				<< sec->ColorMap->Fade;
			BYTE sat = sec->ColorMap->Desaturate;
			arc << sat;
		}
		else
		{
			PalEntry color, fade;
			BYTE desaturate;
			arc << color << fade
				<< desaturate;
			sec->ColorMap = GetSpecialLights (color, fade, desaturate);
		}
		// begin of GZDoom additions
		arc << sec->reflect[sector_t::ceiling] << sec->reflect[sector_t::floor];
		// end of GZDoom additions
	}

	// do lines
	for (i = 0, li = lines; i < numlines; i++, li++)
	{
		arc << li->flags
			<< li->activation
			<< li->special
			<< li->Alpha
			<< li->id;
		if (P_IsACSSpecial(li->special))
		{
			P_SerializeACSScriptNumber(arc, li->args[0], false);
		}
		else
		{
			arc << li->args[0];
		}
		arc << li->args[1] << li->args[2] << li->args[3] << li->args[4];

		for (j = 0; j < 2; j++)
		{
			if (li->sidedef[j] == NULL)
				continue;

			side_t *si = li->sidedef[j];
			arc << si->textures[side_t::top]
				<< si->textures[side_t::mid]
				<< si->textures[side_t::bottom]
				<< si->Light
				<< si->Flags
				<< si->LeftSide
				<< si->RightSide
				<< si->Index;
			DBaseDecal::SerializeChain (arc, &si->AttachedDecals);
		}
	}

	// do zones
	arc << numzones;

	if (arc.IsLoading())
	{
		if (zones != NULL)
		{
			delete[] zones;
		}
		zones = new zone_t[numzones];
	}

	for (i = 0, zn = zones; i < numzones; ++i, ++zn)
	{
		arc << zn->Environment;
	}
}
示例#7
0
	void ParseSector(sector_t *sec, int index)
	{
		int lightcolor = -1;
		int fadecolor = -1;
		int desaturation = -1;
		int fplaneflags = 0, cplaneflags = 0;
		double fp[4] = { 0 }, cp[4] = { 0 };
		FString tagstring;

		memset(sec, 0, sizeof(*sec));
		sec->lightlevel = 160;
		sec->SetXScale(sector_t::floor, 1.);	// [RH] floor and ceiling scaling
		sec->SetYScale(sector_t::floor, 1.);
		sec->SetXScale(sector_t::ceiling, 1.);
		sec->SetYScale(sector_t::ceiling, 1.);
		sec->SetAlpha(sector_t::floor, 1.);
		sec->SetAlpha(sector_t::ceiling, 1.);
		sec->thinglist = NULL;
		sec->touching_thinglist = NULL;		// phares 3/14/98
		sec->render_thinglist = NULL;
		sec->seqType = (level.flags & LEVEL_SNDSEQTOTALCTRL) ? 0 : -1;
		sec->nextsec = -1;	//jff 2/26/98 add fields to support locking out
		sec->prevsec = -1;	// stair retriggering until build completes
		sec->heightsec = NULL;	// sector used to get floor and ceiling height
		sec->sectornum = index;
		sec->damageinterval = 32;
		sec->terrainnum[sector_t::ceiling] = sec->terrainnum[sector_t::floor] = -1;
		if (floordrop) sec->Flags = SECF_FLOORDROP;
		// killough 3/7/98: end changes

		sec->gravity = 1.;	// [RH] Default sector gravity of 1.0
		sec->ZoneNumber = 0xFFFF;

		// killough 8/28/98: initialize all sectors to normal friction
		sec->friction = ORIG_FRICTION;
		sec->movefactor = ORIG_FRICTION_FACTOR;

		sc.MustGetToken('{');
		while (!sc.CheckToken('}'))
		{
			FName key = ParseKey();
			switch(key)
			{
			case NAME_Heightfloor:
				sec->SetPlaneTexZ(sector_t::floor, CheckFloat(key));
				continue;

			case NAME_Heightceiling:
				sec->SetPlaneTexZ(sector_t::ceiling, CheckFloat(key));
				continue;

			case NAME_Texturefloor:
				SetTexture(sec, index, sector_t::floor, CheckString(key), missingTex, false);
				continue;

			case NAME_Textureceiling:
				SetTexture(sec, index, sector_t::ceiling, CheckString(key), missingTex, false);
				continue;

			case NAME_Lightlevel:
				sec->lightlevel = sector_t::ClampLight(CheckInt(key));
				continue;

			case NAME_Special:
				sec->special = (short)CheckInt(key);
				if (isTranslated) sec->special = P_TranslateSectorSpecial(sec->special);
				else if (namespc == NAME_Hexen)
				{
					if (sec->special < 0 || sec->special > 255 || !HexenSectorSpecialOk[sec->special])
						sec->special = 0;	// NULL all unknown specials
				}
				continue;

			case NAME_Id:
				tagManager.AddSectorTag(index, CheckInt(key));
				continue;

			default:
				break;
			}

			if (namespace_bits & (Zd|Zdt|Va)) switch(key)
			{
				case NAME_Xpanningfloor:
					sec->SetXOffset(sector_t::floor, CheckFloat(key));
					continue;

				case NAME_Ypanningfloor:
					sec->SetYOffset(sector_t::floor, CheckFloat(key));
					continue;

				case NAME_Xpanningceiling:
					sec->SetXOffset(sector_t::ceiling, CheckFloat(key));
					continue;

				case NAME_Ypanningceiling:
					sec->SetYOffset(sector_t::ceiling, CheckFloat(key));
					continue;

				case NAME_Xscalefloor:
					sec->SetXScale(sector_t::floor, CheckFloat(key));
					continue;

				case NAME_Yscalefloor:
					sec->SetYScale(sector_t::floor, CheckFloat(key));
					continue;

				case NAME_Xscaleceiling:
					sec->SetXScale(sector_t::ceiling, CheckFloat(key));
					continue;

				case NAME_Yscaleceiling:
					sec->SetYScale(sector_t::ceiling, CheckFloat(key));
					continue;

				case NAME_Rotationfloor:
					sec->SetAngle(sector_t::floor, CheckAngle(key));
					continue;

				case NAME_Rotationceiling:
					sec->SetAngle(sector_t::ceiling, CheckAngle(key));
					continue;

				case NAME_Lightfloor:
					sec->SetPlaneLight(sector_t::floor, CheckInt(key));
					continue;

				case NAME_Lightceiling:
					sec->SetPlaneLight(sector_t::ceiling, CheckInt(key));
					continue;

				case NAME_Alphafloor:
					sec->SetAlpha(sector_t::floor, CheckFloat(key));
					continue;

				case NAME_Alphaceiling:
					sec->SetAlpha(sector_t::ceiling, CheckFloat(key));
					continue;

				case NAME_Renderstylefloor:
				{
					const char *str = CheckString(key);
					if (!stricmp(str, "translucent")) sec->ChangeFlags(sector_t::floor, PLANEF_ADDITIVE, 0);
					else if (!stricmp(str, "add")) sec->ChangeFlags(sector_t::floor, 0, PLANEF_ADDITIVE);
					else sc.ScriptMessage("Unknown value \"%s\" for 'renderstylefloor'\n", str);
					continue;
				}

				case NAME_Renderstyleceiling:
				{
					const char *str = CheckString(key);
					if (!stricmp(str, "translucent")) sec->ChangeFlags(sector_t::ceiling, PLANEF_ADDITIVE, 0);
					else if (!stricmp(str, "add")) sec->ChangeFlags(sector_t::ceiling, 0, PLANEF_ADDITIVE);
					else sc.ScriptMessage("Unknown value \"%s\" for 'renderstyleceiling'\n", str);
					continue;
				}

				case NAME_Lightfloorabsolute:
					if (CheckBool(key)) sec->ChangeFlags(sector_t::floor, 0, PLANEF_ABSLIGHTING);
					else sec->ChangeFlags(sector_t::floor, PLANEF_ABSLIGHTING, 0);
					continue;

				case NAME_Lightceilingabsolute:
					if (CheckBool(key)) sec->ChangeFlags(sector_t::ceiling, 0, PLANEF_ABSLIGHTING);
					else sec->ChangeFlags(sector_t::ceiling, PLANEF_ABSLIGHTING, 0);
					continue;

				case NAME_Gravity:
					sec->gravity = CheckFloat(key);
					continue;

				case NAME_Lightcolor:
					lightcolor = CheckInt(key);
					continue;

				case NAME_Fadecolor:
					fadecolor = CheckInt(key);
					continue;

				case NAME_Desaturation:
					desaturation = int(255*CheckFloat(key));
					continue;

				case NAME_Silent:
					Flag(sec->Flags, SECF_SILENT, key);
					continue;

				case NAME_NoRespawn:
					Flag(sec->Flags, SECF_NORESPAWN, key);
					continue;

				case NAME_Nofallingdamage:
					Flag(sec->Flags, SECF_NOFALLINGDAMAGE, key);
					continue;

				case NAME_Dropactors:
					Flag(sec->Flags, SECF_FLOORDROP, key);
					continue;

				case NAME_SoundSequence:
					sec->SeqName = CheckString(key);
					sec->seqType = -1;
					continue;

				case NAME_hidden:
					Flag(sec->MoreFlags, SECF_HIDDEN, key);
					break;

				case NAME_Waterzone:
					Flag(sec->MoreFlags, SECF_UNDERWATER, key);
					break;

				case NAME_floorplane_a:
					fplaneflags |= 1;
					fp[0] = CheckFloat(key);
					break;

				case NAME_floorplane_b:
					fplaneflags |= 2;
					fp[1] = CheckFloat(key);
					break;

				case NAME_floorplane_c:
					fplaneflags |= 4;
					fp[2] = CheckFloat(key);
					break;

				case NAME_floorplane_d:
					fplaneflags |= 8;
					fp[3] = CheckFloat(key);
					break;

				case NAME_ceilingplane_a:
					cplaneflags |= 1;
					cp[0] = CheckFloat(key);
					break;

				case NAME_ceilingplane_b:
					cplaneflags |= 2;
					cp[1] = CheckFloat(key);
					break;

				case NAME_ceilingplane_c:
					cplaneflags |= 4;
					cp[2] = CheckFloat(key);
					break;

				case NAME_ceilingplane_d:
					cplaneflags |= 8;
					cp[3] = CheckFloat(key);
					break;

				case NAME_damageamount:
					sec->damageamount = CheckInt(key);
					break;

				case NAME_damagetype:
					sec->damagetype = CheckString(key);
					break;

				case NAME_damageinterval:
					sec->damageinterval = CheckInt(key);
					if (sec->damageinterval < 1) sec->damageinterval = 1;
					break;

				case NAME_leakiness:
					sec->leakydamage = CheckInt(key);
					break;

				case NAME_damageterraineffect:
					Flag(sec->Flags, SECF_DMGTERRAINFX, key);
					break;

				case NAME_damagehazard:
					Flag(sec->Flags, SECF_HAZARD, key);
					break;

				case NAME_floorterrain:
					sec->terrainnum[sector_t::floor] = P_FindTerrain(CheckString(key));
					break;

				case NAME_ceilingterrain:
					sec->terrainnum[sector_t::ceiling] = P_FindTerrain(CheckString(key));
					break;

				case NAME_MoreIds:
					// delay parsing of the tag string until parsing of the sector is complete
					// This ensures that the ID is always the first tag in the list.
					tagstring = CheckString(key);
					break;

				default:
					break;
			}
			if ((namespace_bits & (Zd | Zdt)) && !strnicmp("user_", key.GetChars(), 5))
			{
				AddUserKey(key, UDMF_Sector, index);
			}
		}

		if (tagstring.IsNotEmpty())
		{
			FScanner sc;
			sc.OpenString("tagstring", tagstring);
			// scan the string as long as valid numbers can be found
			while (sc.CheckNumber())
			{
				if (sc.Number != 0)	tagManager.AddSectorTag(index, sc.Number);
			}
		}

		if (sec->damageamount == 0)
		{
			// If no damage is set, clear all other related properties so that they do not interfere
			// with other means of setting them.
			sec->damagetype = NAME_None;
			sec->damageinterval = 0;
			sec->leakydamage = 0;
			sec->Flags &= ~SECF_DAMAGEFLAGS;
		}
		
		// Reset the planes to their defaults if not all of the plane equation's parameters were found.
		if (fplaneflags != 15)
		{
			sec->floorplane.SetAtHeight(sec->GetPlaneTexZ(sector_t::floor), sector_t::floor);
		}
		else
		{
			// normalize the vector, it must have a length of 1
			DVector3 n = DVector3(fp[0], fp[1], fp[2]).Unit();
			sec->floorplane.set(n.X, n.Y, n.Z, fp[3]);
		}
		if (cplaneflags != 15)
		{
			sec->ceilingplane.SetAtHeight(sec->GetPlaneTexZ(sector_t::ceiling), sector_t::ceiling);
		}
		else
		{
			DVector3 n = DVector3(cp[0], cp[1], cp[2]).Unit();
			sec->ceilingplane.set(n.X, n.Y, n.Z, cp[3]);
		}

		if (lightcolor == -1 && fadecolor == -1 && desaturation == -1)
		{
			// [RH] Sectors default to white light with the default fade.
			//		If they are outside (have a sky ceiling), they use the outside fog.
			if (level.outsidefog != 0xff000000 && (sec->GetTexture(sector_t::ceiling) == skyflatnum || (sec->special & 0xff) == Sector_Outside))
			{
				if (fogMap == NULL)
					fogMap = GetSpecialLights(PalEntry(255, 255, 255), level.outsidefog, 0);
				sec->ColorMap = fogMap;
			}
			else
			{
				if (normMap == NULL)
					normMap = GetSpecialLights (PalEntry (255,255,255), level.fadeto, NormalLight.Desaturate);
				sec->ColorMap = normMap;
			}
		}
		else
		{
			if (lightcolor == -1) lightcolor = PalEntry(255,255,255);
			if (fadecolor == -1)
			{
				if (level.outsidefog != 0xff000000 && (sec->GetTexture(sector_t::ceiling) == skyflatnum || (sec->special & 0xff) == Sector_Outside))
					fadecolor = level.outsidefog;
				else
					fadecolor = level.fadeto;
			}
			if (desaturation == -1) desaturation = NormalLight.Desaturate;

			sec->ColorMap = GetSpecialLights (lightcolor, fadecolor, desaturation);
		}
	}
示例#8
0
文件: r_decal.cpp 项目: Blzut3/gzdoom
	void RenderDecal::Render(RenderThread *thread, side_t *wall, DBaseDecal *decal, DrawSegment *clipper, int wallshade, float lightleft, float lightstep, seg_t *curline, const FWallCoords &savecoord, bool foggy, FDynamicColormap *basecolormap, const short *walltop, const short *wallbottom, bool drawsegPass)
	{
		DVector2 decal_left, decal_right, decal_pos;
		int x1, x2;
		double yscale;
		uint8_t flipx;
		double zpos;
		int needrepeat = 0;
		sector_t *back;
		bool calclighting;
		bool rereadcolormap;
		FDynamicColormap *usecolormap;
		float light = 0;
		const short *mfloorclip;
		const short *mceilingclip;

		if (decal->RenderFlags & RF_INVISIBLE || !viewactive || !decal->PicNum.isValid())
			return;

		// Determine actor z
		zpos = decal->Z;
		back = (curline->backsector != NULL) ? curline->backsector : curline->frontsector;

		// for 3d-floor segments use the model sector as reference
		sector_t *front;
		if ((decal->RenderFlags&RF_CLIPMASK) == RF_CLIPMID) front = decal->Sector;
		else front = curline->frontsector;

		switch (decal->RenderFlags & RF_RELMASK)
		{
		default:
			zpos = decal->Z;
			break;
		case RF_RELUPPER:
			if (curline->linedef->flags & ML_DONTPEGTOP)
			{
				zpos = decal->Z + front->GetPlaneTexZ(sector_t::ceiling);
			}
			else
			{
				zpos = decal->Z + back->GetPlaneTexZ(sector_t::ceiling);
			}
			break;
		case RF_RELLOWER:
			if (curline->linedef->flags & ML_DONTPEGBOTTOM)
			{
				zpos = decal->Z + front->GetPlaneTexZ(sector_t::ceiling);
			}
			else
			{
				zpos = decal->Z + back->GetPlaneTexZ(sector_t::floor);
			}
			break;
		case RF_RELMID:
			if (curline->linedef->flags & ML_DONTPEGBOTTOM)
			{
				zpos = decal->Z + front->GetPlaneTexZ(sector_t::floor);
			}
			else
			{
				zpos = decal->Z + front->GetPlaneTexZ(sector_t::ceiling);
			}
		}

		FTexture *WallSpriteTile = TexMan(decal->PicNum, true);
		flipx = (uint8_t)(decal->RenderFlags & RF_XFLIP);

		if (WallSpriteTile == NULL || WallSpriteTile->UseType == ETextureType::Null)
		{
			return;
		}

		// Determine left and right edges of sprite. Since this sprite is bound
		// to a wall, we use the wall's angle instead of the decal's. This is
		// pretty much the same as what R_AddLine() does.

		double edge_right = WallSpriteTile->GetWidth();
		double edge_left = WallSpriteTile->GetLeftOffset(0);	// decals should not use renderer-specific offsets.
		edge_right = (edge_right - edge_left) * decal->ScaleX;
		edge_left *= decal->ScaleX;

		double dcx, dcy;
		decal->GetXY(wall, dcx, dcy);
		decal_pos = { dcx, dcy };

		DVector2 angvec = (curline->v2->fPos() - curline->v1->fPos()).Unit();
		float maskedScaleY;

		decal_left = decal_pos - edge_left * angvec - thread->Viewport->viewpoint.Pos;
		decal_right = decal_pos + edge_right * angvec - thread->Viewport->viewpoint.Pos;

		CameraLight *cameraLight;
		double texturemid;

		FWallCoords WallC;
		if (WallC.Init(thread, decal_left, decal_right, TOO_CLOSE_Z))
			return;

		x1 = WallC.sx1;
		x2 = WallC.sx2;

		if (x1 >= clipper->x2 || x2 <= clipper->x1)
			return;

		FWallTmapVals WallT;
		WallT.InitFromWallCoords(thread, &WallC);

		if (drawsegPass)
		{
			uint32_t clipMode = decal->RenderFlags & RF_CLIPMASK;
			if (clipMode != RF_CLIPMID && clipMode != RF_CLIPFULL)
				return;

			// Clip decal to stay within the draw segment wall
			mceilingclip = walltop;
			mfloorclip = wallbottom;

			// Rumor has it that if RT_CLIPMASK is specified then the decal should be clipped according
			// to the full drawsegment visibility, as implemented in the remarked section below.
			//
			// This is problematic because not all 3d floors may have been drawn yet at this point. The
			// code below might work ok for cases where there is only one 3d floor.

			/*if (clipMode == RF_CLIPFULL)
			{
				mceilingclip = clipper->sprtopclip - clipper->x1;
				mfloorclip = clipper->sprbottomclip - clipper->x1;
			}*/
		}
		else
		{
			// Get the top and bottom clipping arrays
			switch (decal->RenderFlags & RF_CLIPMASK)
			{
			default:
				// keep GCC quiet.
				return;

			case RF_CLIPFULL:
				if (curline->backsector == NULL)
				{
					mceilingclip = walltop;
					mfloorclip = wallbottom;
				}
				else
				{
					mceilingclip = walltop;
					mfloorclip = thread->OpaquePass->ceilingclip;
					needrepeat = 1;
				}
				break;

			case RF_CLIPUPPER:
				mceilingclip = walltop;
				mfloorclip = thread->OpaquePass->ceilingclip;
				break;

			case RF_CLIPMID:
				return;

			case RF_CLIPLOWER:
				mceilingclip = thread->OpaquePass->floorclip;
				mfloorclip = wallbottom;
				break;
			}
		}

		yscale = decal->ScaleY;
		texturemid = WallSpriteTile->GetTopOffset(0) + (zpos - thread->Viewport->viewpoint.Pos.Z) / yscale;

		// Clip sprite to drawseg
		x1 = MAX<int>(clipper->x1, x1);
		x2 = MIN<int>(clipper->x2, x2);
		if (x1 >= x2)
		{
			return;
		}

		ProjectedWallTexcoords walltexcoords;
		walltexcoords.Project(thread->Viewport.get(), WallSpriteTile->GetWidth(), x1, x2, WallT);

		if (flipx)
		{
			int i;
			int right = (WallSpriteTile->GetWidth() << FRACBITS) - 1;

			for (i = x1; i < x2; i++)
			{
				walltexcoords.UPos[i] = right - walltexcoords.UPos[i];
			}
		}

		// Prepare lighting
		calclighting = false;
		usecolormap = basecolormap;
		rereadcolormap = true;

		// Decals that are added to the scene must fade to black.
		if (decal->RenderStyle == LegacyRenderStyles[STYLE_Add] && usecolormap->Fade != 0)
		{
			usecolormap = GetSpecialLights(usecolormap->Color, 0, usecolormap->Desaturate);
			rereadcolormap = false;
		}

		light = lightleft + (x1 - savecoord.sx1) * lightstep;

		cameraLight = CameraLight::Instance();

		// Draw it
		bool sprflipvert;
		if (decal->RenderFlags & RF_YFLIP)
		{
			sprflipvert = true;
			yscale = -yscale;
			texturemid -= WallSpriteTile->GetHeight();
		}
		else
		{
			sprflipvert = false;
		}

		maskedScaleY = float(1 / yscale);
		do
		{
			int x = x1;

			SpriteDrawerArgs drawerargs;

			if (cameraLight->FixedLightLevel() >= 0)
				drawerargs.SetLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : usecolormap, 0, cameraLight->FixedLightLevelShade());
			else if (cameraLight->FixedColormap() != NULL)
				drawerargs.SetLight(cameraLight->FixedColormap(), 0, 0);
			else if (!foggy && (decal->RenderFlags & RF_FULLBRIGHT))
				drawerargs.SetLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : usecolormap, 0, 0);
			else
				calclighting = true;

			bool visible = drawerargs.SetStyle(thread->Viewport.get(), decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor, basecolormap);

			// R_SetPatchStyle can modify basecolormap.
			if (rereadcolormap)
			{
				usecolormap = basecolormap;
			}

			if (visible)
			{
				thread->PrepareTexture(WallSpriteTile, decal->RenderStyle);
				while (x < x2)
				{
					if (calclighting)
					{ // calculate lighting
						drawerargs.SetLight(usecolormap, light, wallshade);
					}
					DrawColumn(thread, drawerargs, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip, decal->RenderStyle);
					light += lightstep;
					x++;
				}
			}

			// If this sprite is RF_CLIPFULL on a two-sided line, needrepeat will
			// be set 1 if we need to draw on the lower wall. In all other cases,
			// needrepeat will be 0, and the while will fail.
			mceilingclip = thread->OpaquePass->floorclip;
			mfloorclip = wallbottom;
		} while (needrepeat--);
	}
示例#9
0
文件: p_saveg.cpp 项目: Tox86/gzdoom
//
// P_ArchiveWorld
//
void P_SerializeWorld (FArchive &arc)
{
    int i, j;
    sector_t *sec;
    line_t *li;
    zone_t *zn;

    // do sectors
    for (i = 0, sec = sectors; i < numsectors; i++, sec++)
    {
        arc << sec->floorplane
            << sec->ceilingplane;
        if (SaveVersion < 3223)
        {
            BYTE bytelight;
            arc << bytelight;
            sec->lightlevel = bytelight;
        }
        else
        {
            arc << sec->lightlevel;
        }
        arc << sec->special;
        if (SaveVersion < 4523)
        {
            short tag;
            arc << tag;
        }
        arc << sec->soundtraversed
            << sec->seqType
            << sec->friction
            << sec->movefactor
            << sec->floordata
            << sec->ceilingdata
            << sec->lightingdata
            << sec->stairlock
            << sec->prevsec
            << sec->nextsec
            << sec->planes[sector_t::floor]
            << sec->planes[sector_t::ceiling]
            << sec->heightsec
            << sec->bottommap << sec->midmap << sec->topmap
            << sec->gravity;
        if (SaveVersion >= 4530)
        {
            P_SerializeTerrain(arc, sec->terrainnum[0]);
            P_SerializeTerrain(arc, sec->terrainnum[1]);
        }
        if (SaveVersion >= 4529)
        {
            arc << sec->damageamount;
        }
        else
        {
            short dmg;
            arc << dmg;
            sec->damageamount = dmg;
        }
        if (SaveVersion >= 4528)
        {
            arc << sec->damageinterval
                << sec->leakydamage
                << sec->damagetype;
        }
        else
        {
            short damagemod;
            arc << damagemod;
            sec->damagetype = MODtoDamageType(damagemod);
            if (sec->damageamount < 20)
            {
                sec->leakydamage = 0;
                sec->damageinterval = 32;
            }
            else if (sec->damageamount < 50)
            {
                sec->leakydamage = 5;
                sec->damageinterval = 32;
            }
            else
            {
                sec->leakydamage = 256;
                sec->damageinterval = 1;
            }
        }

        arc << sec->SoundTarget
            << sec->SecActTarget
            << sec->sky
            << sec->MoreFlags
            << sec->Flags
            << sec->SkyBoxes[sector_t::floor] << sec->SkyBoxes[sector_t::ceiling]
            << sec->ZoneNumber;
        if (SaveVersion < 4529)
        {
            short secretsector;
            arc << secretsector;
            if (secretsector) sec->Flags |= SECF_WASSECRET;
            sec->special &= ~(SECRET_MASK|FRICTION_MASK|PUSH_MASK);
            P_InitSectorSpecial(sec, sec->special, true);
        }
        arc	<< sec->interpolations[0]
            << sec->interpolations[1]
            << sec->interpolations[2]
            << sec->interpolations[3]
            << sec->SeqName;

        sec->e->Serialize(arc);
        if (arc.IsStoring ())
        {
            arc << sec->ColorMap->Color
                << sec->ColorMap->Fade;
            BYTE sat = sec->ColorMap->Desaturate;
            arc << sat;
        }
        else
        {
            PalEntry color, fade;
            BYTE desaturate;
            arc << color << fade
                << desaturate;
            sec->ColorMap = GetSpecialLights (color, fade, desaturate);
        }
        // begin of GZDoom additions
        arc << sec->reflect[sector_t::ceiling] << sec->reflect[sector_t::floor];
        // end of GZDoom additions
    }

    // do lines
    for (i = 0, li = lines; i < numlines; i++, li++)
    {
        arc << li->flags
            << li->activation
            << li->special
            << li->Alpha;

        if (SaveVersion < 4523)
        {
            int id;
            arc << id;
        }
        if (P_IsACSSpecial(li->special))
        {
            P_SerializeACSScriptNumber(arc, li->args[0], false);
        }
        else
        {
            arc << li->args[0];
        }
        arc << li->args[1] << li->args[2] << li->args[3] << li->args[4];

        if (SaveVersion >= 4531)
        {
            arc << li->skybox;
        }

        for (j = 0; j < 2; j++)
        {
            if (li->sidedef[j] == NULL)
                continue;

            side_t *si = li->sidedef[j];
            arc << si->textures[side_t::top]
                << si->textures[side_t::mid]
                << si->textures[side_t::bottom]
                << si->Light
                << si->Flags
                << si->LeftSide
                << si->RightSide
                << si->Index;
            DBaseDecal::SerializeChain (arc, &si->AttachedDecals);
        }
    }

    // do zones
    arc << numzones;

    if (arc.IsLoading())
    {
        if (zones != NULL)
        {
            delete[] zones;
        }
        zones = new zone_t[numzones];
    }

    for (i = 0, zn = zones; i < numzones; ++i, ++zn)
    {
        arc << zn->Environment;
    }
}
示例#10
0
	void RenderWallSprite::Render(RenderThread *thread, short *mfloorclip, short *mceilingclip, int, int, Fake3DTranslucent)
	{
		auto spr = this;

		int x1, x2;
		double iyscale;
		bool sprflipvert;

		x1 = MAX<int>(spr->x1, spr->wallc.sx1);
		x2 = MIN<int>(spr->x2, spr->wallc.sx2);
		if (x1 >= x2)
			return;

		FWallTmapVals WallT;
		WallT.InitFromWallCoords(thread, &spr->wallc);

		ProjectedWallTexcoords walltexcoords;
		walltexcoords.Project(thread->Viewport.get(), spr->pic->GetWidth() << FRACBITS, x1, x2, WallT);

		iyscale = 1 / spr->yscale;
		double texturemid = (spr->gzt - thread->Viewport->viewpoint.Pos.Z) * iyscale;
		if (spr->renderflags & RF_XFLIP)
		{
			int right = (spr->pic->GetWidth() << FRACBITS) - 1;

			for (int i = x1; i < x2; i++)
			{
				walltexcoords.UPos[i] = right - walltexcoords.UPos[i];
			}
		}
		// Prepare lighting
		bool calclighting = false;
		FSWColormap *usecolormap = spr->Light.BaseColormap;
		bool rereadcolormap = true;

		// Decals that are added to the scene must fade to black.
		if (spr->RenderStyle == LegacyRenderStyles[STYLE_Add] && usecolormap->Fade != 0)
		{
			usecolormap = GetSpecialLights(usecolormap->Color, 0, usecolormap->Desaturate);
			rereadcolormap = false;
		}

		SpriteDrawerArgs drawerargs;

		int shade = LightVisibility::LightLevelToShade(spr->sector->lightlevel + LightVisibility::ActualExtraLight(spr->foggy, thread->Viewport.get()), spr->foggy);
		double GlobVis = thread->Light->WallGlobVis(foggy);
		float lightleft = float(GlobVis / spr->wallc.sz1);
		float lightstep = float((GlobVis / spr->wallc.sz2 - lightleft) / (spr->wallc.sx2 - spr->wallc.sx1));
		float light = lightleft + (x1 - spr->wallc.sx1) * lightstep;
		CameraLight *cameraLight = CameraLight::Instance();
		if (cameraLight->FixedLightLevel() >= 0)
			drawerargs.SetLight(usecolormap, 0, cameraLight->FixedLightLevelShade());
		else if (cameraLight->FixedColormap() != NULL)
			drawerargs.SetLight(cameraLight->FixedColormap(), 0, 0);
		else if (!spr->foggy && (spr->renderflags & RF_FULLBRIGHT))
			drawerargs.SetLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : usecolormap, 0, 0);
		else
			calclighting = true;

		// Draw it
		FTexture *WallSpriteTile = spr->pic;
		if (spr->renderflags & RF_YFLIP)
		{
			sprflipvert = true;
			iyscale = -iyscale;
			texturemid -= spr->pic->GetHeight();
		}
		else
		{
			sprflipvert = false;
		}

		float maskedScaleY = (float)iyscale;

		int x = x1;

		FDynamicColormap *basecolormap = static_cast<FDynamicColormap*>(spr->Light.BaseColormap);

		bool visible = drawerargs.SetStyle(thread->Viewport.get(), spr->RenderStyle, spr->Alpha, spr->Translation, spr->FillColor, basecolormap);

		// R_SetPatchStyle can modify basecolormap.
		if (rereadcolormap)
		{
			usecolormap = spr->Light.BaseColormap;
		}

		if (!visible)
		{
			return;
		}
		else
		{
			RenderTranslucentPass *translucentPass = thread->TranslucentPass.get();

			thread->PrepareTexture(WallSpriteTile, spr->RenderStyle);
			while (x < x2)
			{
				if (calclighting)
				{ // calculate lighting
					drawerargs.SetLight(usecolormap, light, shade);
				}
				if (!translucentPass->ClipSpriteColumnWithPortals(x, spr))
					DrawColumn(thread, drawerargs, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip, spr->RenderStyle);
				light += lightstep;
				x++;
			}
		}
	}
示例#11
0
//==========================================================================
//
// Creates all 3D floors defined by one linedef
//
//==========================================================================
static int P_Set3DFloor(line_t * line, int param, int param2, int alpha)
{
	int s;
	int flags;
	int tag = line->args[0];
	sector_t * sec = line->frontsector, *ss;

	FSectorTagIterator itr(tag);
	while ((s = itr.Next()) >= 0)
	{
		ss = &level.sectors[s];

		if (param == 0)
		{
			flags = FF_EXISTS | FF_RENDERALL | FF_SOLID | FF_INVERTSECTOR;
			alpha = 255;
			for (auto l: sec->Lines)
			{
				if (l->special == Sector_SetContents && l->frontsector == sec)
				{
					alpha = clamp<int>(l->args[1], 0, 100);
					if (l->args[2] & 1) flags &= ~FF_SOLID;
					if (l->args[2] & 2) flags |= FF_SEETHROUGH;
					if (l->args[2] & 4) flags |= FF_SHOOTTHROUGH;
					if (l->args[2] & 8) flags |= FF_ADDITIVETRANS;
					if (alpha != 100) flags |= FF_TRANSLUCENT;//|FF_BOTHPLANES|FF_ALLSIDES;
					if (l->args[0])
					{
						// Yes, Vavoom's 3D-floor definitions suck!
						// The content list changed in r1783 of Vavoom to be unified
						// among all its supported games, so it has now ten different
						// values instead of just five.
						static DWORD vavoomcolors[] = { VC_EMPTY,
							VC_WATER, VC_LAVA, VC_NUKAGE, VC_SLIME, VC_HELLSLIME,
							VC_BLOOD, VC_SLUDGE, VC_HAZARD, VC_BOOMWATER };
						flags |= FF_SWIMMABLE | FF_BOTHPLANES | FF_ALLSIDES | FF_FLOOD;

						l->frontsector->ColorMap =
							GetSpecialLights(l->frontsector->ColorMap->Color,
							vavoomcolors[l->args[0]],
							l->frontsector->ColorMap->Desaturate);
					}
					alpha = (alpha * 255) / 100;
					break;
				}
			}
		}
		else if (param == 4)
		{
			flags = FF_EXISTS | FF_RENDERPLANES | FF_INVERTPLANES | FF_NOSHADE | FF_FIX;
			if (param2 & 1) flags |= FF_SEETHROUGH;	// marker for allowing missing texture checks
			alpha = 255;
		}
		else
		{
			static const int defflags[] = { 0,
				FF_SOLID,
				FF_SWIMMABLE | FF_BOTHPLANES | FF_ALLSIDES | FF_SHOOTTHROUGH | FF_SEETHROUGH,
				FF_SHOOTTHROUGH | FF_SEETHROUGH,
			};

			flags = defflags[param & 3] | FF_EXISTS | FF_RENDERALL;

			if (param & 4) flags |= FF_ALLSIDES | FF_BOTHPLANES;
			if (param & 16) flags ^= FF_SEETHROUGH;
			if (param & 32) flags ^= FF_SHOOTTHROUGH;

			if (param2 & 1) flags |= FF_NOSHADE;
			if (param2 & 2) flags |= FF_DOUBLESHADOW;
			if (param2 & 4) flags |= FF_FOG;
			if (param2 & 8) flags |= FF_THINFLOOR;
			if (param2 & 16) flags |= FF_UPPERTEXTURE;
			if (param2 & 32) flags |= FF_LOWERTEXTURE;
			if (param2 & 64) flags |= FF_ADDITIVETRANS | FF_TRANSLUCENT;
			// if flooding is used the floor must be non-solid and is automatically made shootthrough and seethrough
			if ((param2 & 128) && !(flags & FF_SOLID)) flags |= FF_FLOOD | FF_SEETHROUGH | FF_SHOOTTHROUGH;
			if (param2 & 512) flags |= FF_FADEWALLS;
			if (param2&1024) flags |= FF_RESET;
			FTextureID tex = line->sidedef[0]->GetTexture(side_t::top);
			if (!tex.Exists() && alpha < 255)
			{
				alpha = -tex.GetIndex();
			}
			alpha = clamp(alpha, 0, 255);
			if (alpha == 0) flags &= ~(FF_RENDERALL | FF_BOTHPLANES | FF_ALLSIDES);
			else if (alpha != 255) flags |= FF_TRANSLUCENT;

		}
		P_Add3DFloor(ss, sec, line, flags, alpha);
	}
	// To be 100% safe this should be done even if the alpha by texture value isn't used.
	if (!line->sidedef[0]->GetTexture(side_t::top).isValid())
		line->sidedef[0]->SetTexture(side_t::top, FNullTextureID());
	return 1;
}
示例#12
0
void sector_t::SetFade(int r, int g, int b)
{
	PalEntry fade = PalEntry (r,g,b);
	ColorMap = GetSpecialLights (ColorMap->Color, fade, ColorMap->Desaturate);
}
示例#13
0
void sector_t::SetColor(int r, int g, int b, int desat)
{
	PalEntry color = PalEntry (r,g,b);
	ColorMap = GetSpecialLights (color, ColorMap->Fade, desat);
}
示例#14
0
static void LoadSectors (sectortype *bsec, int count)
{
	FDynamicColormap *map = GetSpecialLights (PalEntry (255,255,255), level.fadeto, 0);
	sector_t *sec;
	char tnam[9];

	level.sectors.Alloc(count);
	sec = &level.sectors[0];
	memset (sec, 0, sizeof(sector_t)*count);

	sec->e = new extsector_t[count];

	for (int i = 0; i < count; ++i, ++bsec, ++sec)
	{
		bsec->wallptr = WORD(bsec->wallptr);
		bsec->wallnum = WORD(bsec->wallnum);
		bsec->ceilingstat = WORD(bsec->ceilingstat);
		bsec->floorstat = WORD(bsec->floorstat);

		sec->e = &sec->e[i];
		double floorheight = -LittleLong(bsec->floorZ) / 256.;
		sec->SetPlaneTexZ(sector_t::floor, floorheight);
		sec->floorplane.SetAtHeight(floorheight, sector_t::floor);
		mysnprintf (tnam, countof(tnam), "BTIL%04d", LittleShort(bsec->floorpicnum));
		sec->SetTexture(sector_t::floor, TexMan.GetTexture (tnam, FTexture::TEX_Build));
		sec->SetXScale(sector_t::floor, (bsec->floorstat & 8) ? 2. : 1.);
		sec->SetYScale(sector_t::floor, (bsec->floorstat & 8) ? 2. : 1.);
		sec->SetXOffset(sector_t::floor, bsec->floorxpanning + 32.);
		sec->SetYOffset(sector_t::floor, bsec->floorypanning + 0.);
		sec->SetPlaneLight(sector_t::floor, SHADE2LIGHT (bsec->floorshade));
		sec->ChangeFlags(sector_t::floor, 0, PLANEF_ABSLIGHTING);

		double ceilingheight = -LittleLong(bsec->ceilingZ) / 256.;
		sec->SetPlaneTexZ(sector_t::ceiling, ceilingheight);
		sec->ceilingplane.SetAtHeight(ceilingheight, sector_t::ceiling);
		mysnprintf (tnam, countof(tnam), "BTIL%04d", LittleShort(bsec->ceilingpicnum));
		sec->SetTexture(sector_t::ceiling, TexMan.GetTexture (tnam, FTexture::TEX_Build));
		if (bsec->ceilingstat & 1)
		{
			sky1texture = sky2texture = sec->GetTexture(sector_t::ceiling);
			sec->SetTexture(sector_t::ceiling, skyflatnum);
		}
		sec->SetXScale(sector_t::ceiling, (bsec->ceilingstat & 8) ? 2. : 1.);
		sec->SetYScale(sector_t::ceiling, (bsec->ceilingstat & 8) ? 2. : 1.);
		sec->SetXOffset(sector_t::ceiling, bsec->ceilingxpanning + 32.);
		sec->SetYOffset(sector_t::ceiling, bsec->ceilingypanning + 0.);
		sec->SetPlaneLight(sector_t::ceiling, SHADE2LIGHT (bsec->ceilingshade));
		sec->ChangeFlags(sector_t::ceiling, 0, PLANEF_ABSLIGHTING);

		sec->lightlevel = (sec->GetPlaneLight(sector_t::floor) + sec->GetPlaneLight(sector_t::ceiling)) / 2;

		sec->seqType = -1;
		sec->SeqName = NAME_None;
		sec->nextsec = -1;
		sec->prevsec = -1;
		sec->gravity = 1.f;
		sec->friction = ORIG_FRICTION;
		sec->movefactor = ORIG_FRICTION_FACTOR;
		sec->ColorMap = map;
		sec->ZoneNumber = 0xFFFF;
		sec->terrainnum[sector_t::ceiling] = sec->terrainnum[sector_t::floor] = -1;

		if (bsec->floorstat & 4)
		{
			sec->SetAngle(sector_t::floor, DAngle(90.));
			sec->SetXScale(sector_t::floor, -sec->GetXScale(sector_t::floor));
		}
		if (bsec->floorstat & 16)
		{
			sec->SetXScale(sector_t::floor, -sec->GetXScale(sector_t::floor));
		}
		if (bsec->floorstat & 32)
		{
			sec->SetYScale(sector_t::floor, -sec->GetYScale(sector_t::floor));
		}

		if (bsec->ceilingstat & 4)
		{
			sec->SetAngle(sector_t::ceiling, DAngle(90.));
			sec->SetYScale(sector_t::ceiling, -sec->GetYScale(sector_t::ceiling));
		}
		if (bsec->ceilingstat & 16)
		{
			sec->SetXScale(sector_t::ceiling, -sec->GetXScale(sector_t::ceiling));
		}
		if (bsec->ceilingstat & 32)
		{
			sec->SetYScale(sector_t::ceiling, -sec->GetYScale(sector_t::ceiling));
		}
	}
}
示例#15
0
void sector_t::SetColor(int r, int g, int b, int desat)
{
	PalEntry color = PalEntry (r,g,b);
	ColorMap = GetSpecialLights (color, ColorMap->Fade, desat);
	P_RecalculateAttachedLights(this);
}
示例#16
0
//
// P_ArchiveWorld
//
void P_SerializeWorld (FArchive &arc)
{
	int i, j;
	sector_t *sec;
	line_t *li;

	if (arc.IsStoring ())
	{ // saving to archive

		// do sectors
		for (i = 0, sec = sectors; i < numsectors; i++, sec++)
		{
			arc << sec->floorheight
				<< sec->ceilingheight
				<< sec->floorplane.a
				<< sec->floorplane.b
				<< sec->floorplane.c
				<< sec->floorplane.d
				<< sec->ceilingplane.a
				<< sec->ceilingplane.b
				<< sec->ceilingplane.c
				<< sec->ceilingplane.d
				<< sec->floorpic
				<< sec->ceilingpic
				<< sec->lightlevel
				<< sec->special
				<< sec->tag
				<< sec->soundtraversed
				/*<< sec->soundtarget*/
				<< sec->friction
				<< sec->movefactor
				<< sec->floordata
				<< sec->ceilingdata
				<< sec->lightingdata
				<< sec->stairlock
				<< sec->prevsec
				<< sec->nextsec
				<< sec->floor_xoffs << sec->floor_yoffs
				<< sec->ceiling_xoffs << sec->ceiling_xoffs
				<< sec->floor_xscale << sec->floor_yscale
				<< sec->ceiling_xscale << sec->ceiling_yscale
				<< sec->floor_angle << sec->ceiling_angle
				<< sec->base_ceiling_angle << sec->base_ceiling_yoffs
				<< sec->base_floor_angle << sec->base_floor_yoffs
				<< sec->heightsec
				<< sec->floorlightsec << sec->ceilinglightsec
				<< sec->bottommap << sec->midmap << sec->topmap
				<< sec->gravity
				<< sec->damage
				<< sec->mod

				<< sec->colormap->color.geta() << sec->colormap->color.getr()
				<< sec->colormap->color.getg() << sec->colormap->color.getb()
				<< sec->colormap->fade.geta() << sec->colormap->fade.getr()
				<< sec->colormap->fade.getg() << sec->colormap->fade.getb()

				// [SL] TODO: Remove the extra set of light and fade color serialization.
				// These are left over from when Odamex had separate colormaps for a sector's
				// floor and ceiling. Now a sector only has one colormap but we keep these
				// here for now for netdemo compatibility.
				<< sec->colormap->color.geta() << sec->colormap->color.getr()
				<< sec->colormap->color.getg() << sec->colormap->color.getb()
				<< sec->colormap->fade.geta() << sec->colormap->fade.getr()
				<< sec->colormap->fade.getg() << sec->colormap->fade.getb()

				<< sec->alwaysfake
				<< sec->waterzone
				<< sec->SecActTarget
				<< sec->MoreFlags;
		}

		// do lines
		for (i = 0, li = lines; i < numlines; i++, li++)
		{
			arc << li->flags
				<< li->special
				<< li->lucency
				<< li->id
				<< li->args[0] << li->args[1] << li->args[2] << li->args[3] << li->args[4] << (WORD)0;

			for (j = 0; j < 2; j++)
			{
				if (li->sidenum[j] == R_NOSIDE)
					continue;

				side_t *si = &sides[li->sidenum[j]];
				arc << si->textureoffset
					<< si->rowoffset
					<< si->toptexture
					<< si->bottomtexture
					<< si->midtexture;
			}
		}
	}
	else
	{ // loading from archive

		// do sectors
		for (i = 0, sec = sectors; i < numsectors; i++, sec++)
		{
			AActor* SecActTarget;

			arc >> sec->floorheight
				>> sec->ceilingheight
				>> sec->floorplane.a
				>> sec->floorplane.b
				>> sec->floorplane.c
				>> sec->floorplane.d
				>> sec->ceilingplane.a
				>> sec->ceilingplane.b
				>> sec->ceilingplane.c
				>> sec->ceilingplane.d
				>> sec->floorpic
				>> sec->ceilingpic
				>> sec->lightlevel
				>> sec->special
				>> sec->tag
				>> sec->soundtraversed
				/*>> sec->soundtarget->netid*/
				>> sec->friction
				>> sec->movefactor
				>> sec->floordata
				>> sec->ceilingdata
				>> sec->lightingdata
				>> sec->stairlock
				>> sec->prevsec
				>> sec->nextsec
				>> sec->floor_xoffs >> sec->floor_yoffs
				>> sec->ceiling_xoffs >> sec->ceiling_xoffs
				>> sec->floor_xscale >> sec->floor_yscale
				>> sec->ceiling_xscale >> sec->ceiling_yscale
				>> sec->floor_angle >> sec->ceiling_angle
				>> sec->base_ceiling_angle >> sec->base_ceiling_yoffs
				>> sec->base_floor_angle >> sec->base_floor_yoffs
				>> sec->heightsec
				>> sec->floorlightsec >> sec->ceilinglightsec
				>> sec->bottommap >> sec->midmap >> sec->topmap
				>> sec->gravity
				>> sec->damage
				>> sec->mod;

			byte color_values[4];
			argb_t lightcolor, fadecolor;

			arc >> color_values[0] >> color_values[1] >> color_values[2] >> color_values[3];
			lightcolor = argb_t(color_values[0], color_values[1], color_values[2], color_values[3]);

			arc >> color_values[0] >> color_values[1] >> color_values[2] >> color_values[3];
			fadecolor = argb_t(color_values[0], color_values[1], color_values[2], color_values[3]);

			sec->colormap = GetSpecialLights(lightcolor.getr(), lightcolor.getg(), lightcolor.getb(),
											fadecolor.getr(), fadecolor.getg(), fadecolor.getb());

			// [SL] TODO: Remove the extra set of light and fade color deserialization.
			// These are left over from when Odamex had separate colormaps for a sector's
			// floor and ceiling. Now a sector only has one colormap but we keep these
			// here for now for netdemo compatibility.
			arc >> color_values[0] >> color_values[1] >> color_values[2] >> color_values[3];
			arc >> color_values[0] >> color_values[1] >> color_values[2] >> color_values[3];

			arc >> sec->alwaysfake
				>> sec->waterzone
				>> SecActTarget
				>> sec->MoreFlags;

			sec->floorplane.invc = FixedDiv(FRACUNIT, sec->floorplane.c);
			sec->floorplane.sector = sec;
			sec->ceilingplane.invc = FixedDiv(FRACUNIT, sec->ceilingplane.c);
			sec->ceilingplane.sector = sec;
			sec->SecActTarget.init(SecActTarget);
		}

		// do lines
		for (i = 0, li = lines; i < numlines; i++, li++)
		{
		    WORD dummy;
			arc >> li->flags
				>> li->special
				>> li->lucency
				>> li->id
				>> li->args[0] >> li->args[1] >> li->args[2] >> li->args[3] >> li->args[4] >> dummy;

			for (j = 0; j < 2; j++)
			{
				if (li->sidenum[j] == R_NOSIDE)
					continue;

				side_t *si = &sides[li->sidenum[j]];
				arc >> si->textureoffset
					>> si->rowoffset
					>> si->toptexture
					>> si->bottomtexture
					>> si->midtexture;
			}
		}
	}
}
示例#17
0
void sector_t::SetFade(int r, int g, int b)
{
	PalEntry fade = PalEntry (r,g,b);
	ColorMap = GetSpecialLights (ColorMap->Color, fade, ColorMap->Desaturate);
	P_RecalculateAttachedLights(this);
}
示例#18
0
//
// P_ArchiveWorld
//
void P_SerializeWorld (FArchive &arc)
{
	int i, j;
	sector_t *sec;
	line_t *li;
	zone_t *zn;

	// [BC] In client mode, just archive whether or not the line's been seen.
	if (( NETWORK_GetState( ) == NETSTATE_CLIENT ) ||
		( CLIENTDEMO_IsPlaying( )))
	{
		// do lines
		for (i = 0, li = lines; i < numlines; i++, li++)
		{
			arc << li->flags;
		}

		return;
	}

	// do sectors
	for (i = 0, sec = sectors; i < numsectors; i++, sec++)
	{
		arc << sec->floorplane
			<< sec->ceilingplane
			<< sec->lightlevel
			<< sec->special
			<< sec->tag
			<< sec->soundtraversed
			<< sec->seqType
			<< sec->friction
			<< sec->movefactor
			<< sec->floordata
			<< sec->ceilingdata
			<< sec->lightingdata
			<< sec->stairlock
			<< sec->prevsec
			<< sec->nextsec
			<< sec->planes[sector_t::floor]
			<< sec->planes[sector_t::ceiling]
			<< sec->heightsec
			<< sec->bottommap << sec->midmap << sec->topmap
			<< sec->gravity
			<< sec->damage
			<< sec->mod
			<< sec->SoundTarget
			<< sec->SecActTarget
			<< sec->sky
			<< sec->MoreFlags
			<< sec->Flags
			<< sec->FloorSkyBox << sec->CeilingSkyBox
			<< sec->ZoneNumber
			<< sec->oldspecial
			<< sec->interpolations[0]
			<< sec->interpolations[1]
			<< sec->interpolations[2]
			<< sec->interpolations[3];

		sec->e->Serialize(arc);
		if (arc.IsStoring ())
		{
			arc << sec->ColorMap->Color
				<< sec->ColorMap->Fade;
			BYTE sat = sec->ColorMap->Desaturate;
			arc << sat;
		}
		else
		{
			PalEntry color, fade;
			BYTE desaturate;
			arc << color << fade
				<< desaturate;
			sec->ColorMap = GetSpecialLights (color, fade, desaturate);
		}
		arc << sec->ceiling_reflect << sec->floor_reflect;

		// [BC]
		arc << sec->floorOrCeiling
			<< sec->bCeilingHeightChange
			<< sec->bFloorHeightChange
			<< sec->SavedCeilingPlane
			<< sec->SavedFloorPlane
			<< sec->SavedCeilingTexZ
			<< sec->SavedFloorTexZ
			<< sec->bFlatChange
			<< sec->SavedFloorPic
			<< sec->SavedCeilingPic
			<< sec->bLightChange
			<< sec->SavedLightLevel;
		if (arc.IsStoring ())
		{
			arc << sec->SavedColorMap->Color
				<< sec->SavedColorMap->Fade;
			BYTE sat = sec->SavedColorMap->Desaturate;
			arc << sat;
		}
		else
		{
			PalEntry color, fade;
			BYTE desaturate;
			arc << color << fade
				<< desaturate;
			sec->SavedColorMap = GetSpecialLights (color, fade, desaturate);
		}
		arc << sec->SavedGravity
			<< sec->SavedFloorXOffset
			<< sec->SavedFloorYOffset
			<< sec->SavedCeilingXOffset
			<< sec->SavedCeilingYOffset
			<< sec->SavedFloorXScale
			<< sec->SavedFloorYScale
			<< sec->SavedCeilingXScale
			<< sec->SavedCeilingYScale
			<< sec->SavedFloorAngle
			<< sec->SavedCeilingAngle
			<< sec->SavedBaseFloorAngle
			<< sec->SavedBaseFloorYOffset
			<< sec->SavedBaseCeilingAngle
			<< sec->SavedBaseCeilingYOffset
			<< sec->SavedFriction
			<< sec->SavedMoveFactor
			<< sec->SavedSpecial
			<< sec->SavedDamage
			<< sec->SavedMOD
			<< sec->SavedCeilingReflect
			<< sec->SavedFloorReflect;
	}

	// do lines
	for (i = 0, li = lines; i < numlines; i++, li++)
	{
		arc << li->flags
			<< li->activation
			<< li->special
			<< li->Alpha
			<< li->id
			<< li->args[0] << li->args[1] << li->args[2] << li->args[3] << li->args[4];
		// [BC]
		arc << (DWORD &)li->ulTexChangeFlags
			<< li->SavedSpecial
			<< li->SavedArgs[0] << li->SavedArgs[1] << li->SavedArgs[2] << li->SavedArgs[3] << li->SavedArgs[4]
			<< li->SavedFlags
			<< li->SavedAlpha;

		for (j = 0; j < 2; j++)
		{
			if (li->sidenum[j] == NO_SIDE)
				continue;

			side_t *si = &sides[li->sidenum[j]];
			arc << si->textures[side_t::top]
				<< si->textures[side_t::mid]
				<< si->textures[side_t::bottom]
				<< si->Light
				<< si->Flags
				<< si->LeftSide
				<< si->RightSide;
			if (SaveVersion >= 1575)
				arc << si->Index;
			DBaseDecal::SerializeChain (arc, &si->AttachedDecals);
			// [BC]
			arc << si->SavedFlags
				<< si->SavedTopTexture
				<< si->SavedMidTexture
				<< si->SavedBottomTexture;
		}
	}

	// do zones
	arc << numzones;

	if (arc.IsLoading())
	{
		if (zones != NULL)
		{
			delete[] zones;
		}
		zones = new zone_t[numzones];
	}

	for (i = 0, zn = zones; i < numzones; ++i, ++zn)
	{
		arc << zn->Environment;
	}
}