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); } }
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); } } }
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); } }
// // 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 = §ors[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)); } } }
// // 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; } }
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); } }
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--); }
// // 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; } }
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++; } } }
//========================================================================== // // 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; }
void sector_t::SetFade(int r, int g, int b) { PalEntry fade = PalEntry (r,g,b); ColorMap = GetSpecialLights (ColorMap->Color, fade, ColorMap->Desaturate); }
void sector_t::SetColor(int r, int g, int b, int desat) { PalEntry color = PalEntry (r,g,b); ColorMap = GetSpecialLights (color, ColorMap->Fade, desat); }
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)); } } }
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); }
// // 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; } } } }
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); }
// // 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; } }