diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 7ed763d56b..e800d8448c 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,16 @@ March 21, 2008 (Changes by Graf Zahl) +- Disabled scrolling of 3DMIDTEX textures. Due to the special needs this + cannot work properly. +- Added new Scroll_Wall special to allow more control over wall scrolling. + Since it uses fixed point parameters it can only be used in scripts though. +- Added flags parameters to all wall scroller specials that didn't use + all 5 args. +- Separated scrolling of the 3 different texture parts of a sidedef. + While doing this I did some more restructuring of the sidedef structure + and changed it so that all state changes to sidedefs that affect rendering + have to be made with access functions. This is not of much use to the + software renderer but it allows far easier caching of rendering data + for OpenGL because the only place I need to check is in the access functions. - Added Karate Chris's ThingCountSector submission. - Made texture indices in FSwitchDef full integers. Since that required some data restructuring I also eliminated the MAX_FRAMES limit of 128 diff --git a/src/actionspecials.h b/src/actionspecials.h index 3821b5e3be..9feaa4026a 100644 --- a/src/actionspecials.h +++ b/src/actionspecials.h @@ -49,6 +49,7 @@ DEFINE_SPECIAL(Sector_Attach3dMidtex, 48, -1, -1) DEFINE_SPECIAL(GlassBreak, 49, 0, 1) DEFINE_SPECIAL(ExtraFloor_LightOnly, 50, -1, -1) DEFINE_SPECIAL(Sector_SetLink, 51, 4, 4) +DEFINE_SPECIAL(Scroll_Wall, 52, 5, 5) DEFINE_SPECIAL(Plat_PerpetualRaise, 60, 3, 3) DEFINE_SPECIAL(Plat_Stop, 61, 1, 1) @@ -128,7 +129,11 @@ DEFINE_SPECIAL(Floor_Waggle, 138, 5, 5) DEFINE_SPECIAL(Thing_SpawnFacing, 139, 2, 4) DEFINE_SPECIAL(Sector_ChangeSound, 140, 2, 2) -// GZDoom/Vavoom specials (put here so that they don't get accidentally redefined) +// GZDoom/Vavoom specials +// Although ZDoom doesn't support them it's better to have them defined so that +// WADs using them somewhere can at least be started without aborting due +// to an error message. +DEFINE_SPECIAL(FS_Execute, 158, 1, 4) DEFINE_SPECIAL(Sector_SetPlaneReflection, 159, 3, 3) DEFINE_SPECIAL(Sector_Set3DFloor, 160, -1, -1) DEFINE_SPECIAL(Sector_SetContents, 161, -1, -1) diff --git a/src/decallib.h b/src/decallib.h index e5e213c586..c829fd11a2 100644 --- a/src/decallib.h +++ b/src/decallib.h @@ -46,7 +46,7 @@ class FDecalTemplate; struct FDecalAnimator; struct PClass; class DBaseDecal; -struct side_s; +struct side_t; class FDecalBase { @@ -71,7 +71,7 @@ class FDecalTemplate : public FDecalBase public: FDecalTemplate () : Translation (0) {} - void ApplyToDecal (DBaseDecal *actor, side_s *wall) const; + void ApplyToDecal (DBaseDecal *actor, side_t *wall) const; const FDecalTemplate *GetDecal () const; void ReplaceDecalRef (FDecalBase *from, FDecalBase *to); diff --git a/src/g_shared/a_decals.cpp b/src/g_shared/a_decals.cpp index 811348bc0f..fe125459da 100644 --- a/src/g_shared/a_decals.cpp +++ b/src/g_shared/a_decals.cpp @@ -245,7 +245,7 @@ int DBaseDecal::StickToWall (side_t *wall, fixed_t x, fixed_t y) Z -= front->floortexz; else Z -= front->ceilingtexz; - tex = wall->midtexture; + tex = wall->GetTexture(side_t::mid); } else if (back->floorplane.ZatPoint (x, y) >= Z) { @@ -254,7 +254,7 @@ int DBaseDecal::StickToWall (side_t *wall, fixed_t x, fixed_t y) Z -= front->ceilingtexz; else Z -= back->floortexz; - tex = wall->bottomtexture; + tex = wall->GetTexture(side_t::bottom); } else { @@ -263,7 +263,7 @@ int DBaseDecal::StickToWall (side_t *wall, fixed_t x, fixed_t y) Z -= front->ceilingtexz; else Z -= back->ceilingtexz; - tex = wall->toptexture; + tex = wall->GetTexture(side_t::top); } CalcFracPos (wall, x, y); diff --git a/src/g_shared/a_sharedglobal.h b/src/g_shared/a_sharedglobal.h index c8b376ce46..b0accd3fb0 100644 --- a/src/g_shared/a_sharedglobal.h +++ b/src/g_shared/a_sharedglobal.h @@ -7,7 +7,7 @@ class FDecalTemplate; struct vertex_s; -struct side_s; +struct side_t; extern void P_SpawnDirt (AActor *actor, fixed_t radius); @@ -18,7 +18,7 @@ bool P_MorphMonster (AActor *actor, const PClass *morphClass); bool P_UpdateMorphedMonster (AActor *actor); -struct side_s; +struct side_t; class DBaseDecal : public DThinker { @@ -33,12 +33,12 @@ public: void Serialize (FArchive &arc); void Destroy (); - int StickToWall (side_s *wall, fixed_t x, fixed_t y); - fixed_t GetRealZ (const side_s *wall) const; + int StickToWall (side_t *wall, fixed_t x, fixed_t y); + fixed_t GetRealZ (const side_t *wall) const; void SetShade (DWORD rgb); void SetShade (int r, int g, int b); - void Spread (const FDecalTemplate *tpl, side_s *wall, fixed_t x, fixed_t y, fixed_t z); - void GetXY (side_s *side, fixed_t &x, fixed_t &y) const; + void Spread (const FDecalTemplate *tpl, side_t *wall, fixed_t x, fixed_t y, fixed_t z); + void GetXY (side_t *side, fixed_t &x, fixed_t &y) const; static void SerializeChain (FArchive &arc, DBaseDecal **firstptr); @@ -55,12 +55,12 @@ public: FRenderStyle RenderStyle; protected: - virtual DBaseDecal *CloneSelf (const FDecalTemplate *tpl, fixed_t x, fixed_t y, fixed_t z, side_s *wall) const; - void CalcFracPos (side_s *wall, fixed_t x, fixed_t y); + virtual DBaseDecal *CloneSelf (const FDecalTemplate *tpl, fixed_t x, fixed_t y, fixed_t z, side_t *wall) const; + void CalcFracPos (side_t *wall, fixed_t x, fixed_t y); void Remove (); - static void SpreadLeft (fixed_t r, vertex_s *v1, side_s *feelwall); - static void SpreadRight (fixed_t r, side_s *feelwall, fixed_t wallsize); + static void SpreadLeft (fixed_t r, vertex_s *v1, side_t *feelwall); + static void SpreadRight (fixed_t r, side_t *feelwall, fixed_t wallsize); }; class DImpactDecal : public DBaseDecal @@ -68,10 +68,10 @@ class DImpactDecal : public DBaseDecal DECLARE_CLASS (DImpactDecal, DBaseDecal) public: DImpactDecal (fixed_t z); - DImpactDecal (side_s *wall, const FDecalTemplate *templ); + DImpactDecal (side_t *wall, const FDecalTemplate *templ); - static DImpactDecal *StaticCreate (const char *name, fixed_t x, fixed_t y, fixed_t z, side_s *wall, PalEntry color=0); - static DImpactDecal *StaticCreate (const FDecalTemplate *tpl, fixed_t x, fixed_t y, fixed_t z, side_s *wall, PalEntry color=0); + static DImpactDecal *StaticCreate (const char *name, fixed_t x, fixed_t y, fixed_t z, side_t *wall, PalEntry color=0); + static DImpactDecal *StaticCreate (const FDecalTemplate *tpl, fixed_t x, fixed_t y, fixed_t z, side_t *wall, PalEntry color=0); void BeginPlay (); void Destroy (); @@ -80,7 +80,7 @@ public: static void SerializeTime (FArchive &arc); protected: - DBaseDecal *CloneSelf (const FDecalTemplate *tpl, fixed_t x, fixed_t y, fixed_t z, side_s *wall) const; + DBaseDecal *CloneSelf (const FDecalTemplate *tpl, fixed_t x, fixed_t y, fixed_t z, side_t *wall) const; static void CheckMax (); private: diff --git a/src/g_shared/r_interpolate.h b/src/g_shared/r_interpolate.h new file mode 100644 index 0000000000..3820cb6866 --- /dev/null +++ b/src/g_shared/r_interpolate.h @@ -0,0 +1,64 @@ +#ifndef R_INTERPOLATE_H +#define R_INTERPOLATE_H + +#include "doomtype.h" + +// BUILD stuff for interpolating between frames, but modified (rather a lot) +#define INTERPOLATION_BUCKETS 107 + + +class FArchive; + +enum EInterpType +{ + INTERP_SectorFloor, // Pass a sector_t * + INTERP_SectorCeiling, // Pass a sector_t * + INTERP_Vertex, // Pass a vertex_t * + INTERP_FloorPanning, // Pass a sector_t * + INTERP_CeilingPanning, // Pass a sector_t * + INTERP_WallPanning_Top, // Pass a side_t * + INTERP_WallPanning_Mid, + INTERP_WallPanning_Bottom, +}; + +struct FActiveInterpolation +{ + FActiveInterpolation *Next; + void *Address; + EInterpType Type; + + friend FArchive &operator << (FArchive &arc, FActiveInterpolation *&interp); + + static int CountInterpolations (); + static int CountInterpolations (int *usedbuckets, int *minbucketfill, int *maxbucketfill); + +private: + fixed_t oldipos[2], bakipos[2]; + + void CopyInterpToOld(); + void CopyBakToInterp(); + void DoAnInterpolation(fixed_t smoothratio); + + static size_t HashKey(EInterpType type, void *interptr); + static FActiveInterpolation *FindInterpolation(EInterpType, void *interptr, FActiveInterpolation **&interp_p); + + friend void updateinterpolations(); + friend void setinterpolation(EInterpType, void *interptr, bool dolinks); + friend void stopinterpolation(EInterpType, void *interptr, bool dolinks); + friend void dointerpolations(fixed_t smoothratio); + friend void restoreinterpolations(); + friend void clearinterpolations(); + friend void SerializeInterpolations(FArchive &arc); + + static FActiveInterpolation *curiposhash[INTERPOLATION_BUCKETS]; +}; + +void updateinterpolations(); +void setinterpolation(EInterpType, void *interptr, bool dolinks = true); +void stopinterpolation(EInterpType, void *interptr, bool dolinks = true); +void dointerpolations(fixed_t smoothratio); +void restoreinterpolations(); +void clearinterpolations(); +void SerializeInterpolations(FArchive &arc); + +#endif \ No newline at end of file diff --git a/src/g_strife/a_strifeitems.cpp b/src/g_strife/a_strifeitems.cpp index a2351d9974..6335b823f3 100644 --- a/src/g_strife/a_strifeitems.cpp +++ b/src/g_strife/a_strifeitems.cpp @@ -72,8 +72,8 @@ void A_RemoveForceField (AActor *self) { line->flags &= ~(ML_BLOCKING|ML_BLOCKEVERYTHING); line->special = 0; - sides[line->sidenum[0]].midtexture = 0; - sides[line->sidenum[1]].midtexture = 0; + sides[line->sidenum[0]].SetTexture(side_t::mid, 0); + sides[line->sidenum[1]].SetTexture(side_t::mid, 0); } } } diff --git a/src/p_3dmidtex.cpp b/src/p_3dmidtex.cpp index d0c8944d87..a1ca695ab8 100644 --- a/src/p_3dmidtex.cpp +++ b/src/p_3dmidtex.cpp @@ -57,8 +57,8 @@ bool P_Scroll3dMidtex(sector_t *sector, int crush, fixed_t move, bool ceiling) { line_t *l = scrollplane.AttachedLines[i]; - sides[l->sidenum[0]].rowoffset += move; - sides[l->sidenum[1]].rowoffset += move; + sides[l->sidenum[0]].AddTextureYOffset(side_t::mid, move); + sides[l->sidenum[1]].AddTextureYOffset(side_t::mid, move); } // Second step: Check all sectors whether the move is ok. @@ -88,8 +88,8 @@ void P_Start3dMidtexInterpolations(sector_t *sector, bool ceiling) { line_t *l = scrollplane.AttachedLines[i]; - setinterpolation(INTERP_WallPanning, &sides[l->sidenum[0]]); - setinterpolation(INTERP_WallPanning, &sides[l->sidenum[1]]); + sides[l->sidenum[0]].SetInterpolation(side_t::mid); + sides[l->sidenum[1]].SetInterpolation(side_t::mid); } } @@ -110,8 +110,8 @@ void P_Stop3dMidtexInterpolations(sector_t *sector, bool ceiling) { line_t *l = scrollplane.AttachedLines[i]; - stopinterpolation(INTERP_WallPanning, &sides[l->sidenum[0]]); - stopinterpolation(INTERP_WallPanning, &sides[l->sidenum[1]]); + sides[l->sidenum[0]].StopInterpolation(side_t::mid); + sides[l->sidenum[1]].StopInterpolation(side_t::mid); } } @@ -237,28 +237,28 @@ bool P_GetMidTexturePosition(const line_t *line, int sideno, fixed_t *ptextop, f { side_t *side = &sides[line->sidenum[sideno]]; - if (line->sidenum[0]==NO_SIDE || line->sidenum[1]==NO_SIDE || !side->midtexture) return false; + if (line->sidenum[0]==NO_SIDE || line->sidenum[1]==NO_SIDE || !side->GetTexture(side_t::mid)) return false; - FTexture * tex= TexMan(side->midtexture); + FTexture * tex= TexMan(side->GetTexture(side_t::mid)); if (!tex) return false; - fixed_t rowoffset = side->rowoffset; + fixed_t y_offset = side->GetTextureYOffset(side_t::mid); fixed_t textureheight = tex->GetScaledHeight() << FRACBITS; if (tex->yScale != FRACUNIT && !tex->bWorldPanning) { - rowoffset = FixedDiv(rowoffset, tex->yScale); + y_offset = FixedDiv(y_offset, tex->yScale); } if(line->flags & ML_DONTPEGBOTTOM) { - *ptexbot = rowoffset + + *ptexbot = y_offset + MAX(line->frontsector->floortexz, line->backsector->floortexz); *ptextop = *ptexbot + textureheight; } else { - *ptextop = rowoffset + + *ptextop = y_offset + MIN(line->frontsector->ceilingtexz, line->backsector->ceilingtexz); *ptexbot = *ptextop - textureheight; diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 73b543f4a3..29fa191bab 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -1945,13 +1945,13 @@ void DLevelScript::SetLineTexture (int lineid, int side, int position, int name) switch (position) { case TEXTURE_TOP: - sidedef->toptexture = texture; + sidedef->SetTexture(side_t::top, texture); break; case TEXTURE_MIDDLE: - sidedef->midtexture = texture; + sidedef->SetTexture(side_t::mid, texture); break; case TEXTURE_BOTTOM: - sidedef->bottomtexture = texture; + sidedef->SetTexture(side_t::bottom, texture); break; default: break; @@ -1978,9 +1978,14 @@ void DLevelScript::ReplaceTextures (int fromnamei, int tonamei, int flags) { side_t *wal = &sides[i]; - if (!(flags & NOT_BOTTOM) && wal->bottomtexture == picnum1) wal->bottomtexture = picnum2; - if (!(flags & NOT_MIDDLE) && wal->midtexture == picnum1) wal->midtexture = picnum2; - if (!(flags & NOT_TOP) && wal->toptexture == picnum1) wal->toptexture = picnum2; + for(int j=0;j<3;j++) + { + static BYTE bits[]={NOT_TOP, NOT_MIDDLE, NOT_BOTTOM}; + if (!(flags & bits[j]) && wal->GetTexture(j) == picnum1) + { + wal->SetTexture(j, picnum2); + } + } } } if ((flags ^ (NOT_FLOOR | NOT_CEILING)) != 0) @@ -4694,7 +4699,7 @@ int DLevelScript::RunScript () case PCD_GETLINEROWOFFSET: if (activationline) { - PushToStack (sides[activationline->sidenum[0]].rowoffset >> FRACBITS); + PushToStack (sides[activationline->sidenum[0]].GetTextureYOffset(side_t::mid) >> FRACBITS); } else { diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index 8671b28338..589f2d5d82 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -459,21 +459,22 @@ static void LoadWalls (walltype *walls, int numwalls, sectortype *bsec) walls[i].nextwall = LittleShort(walls[i].nextwall); walls[i].nextsector = LittleShort(walls[i].nextsector); - sides[i].textureoffset = walls[i].xpanning << FRACBITS; - sides[i].rowoffset = walls[i].ypanning << FRACBITS; + sides[i].SetTextureXOffset(walls[i].xpanning << FRACBITS); + sides[i].SetTextureYOffset(walls[i].ypanning << FRACBITS); - sides[i].toptexture = sides[i].bottomtexture = pic; + sides[i].SetTexture(side_t::top, pic); + sides[i].SetTexture(side_t::bottom, pic); if (walls[i].nextsector < 0 || (walls[i].cstat & 32)) { - sides[i].midtexture = pic; + sides[i].SetTexture(side_t::mid, pic); } else if (walls[i].cstat & 16) { - sides[i].midtexture = overpic; + sides[i].SetTexture(side_t::mid, overpic); } else { - sides[i].midtexture = 0; + sides[i].SetTexture(side_t::mid, 0); } sides[i].TexelLength = walls[i].xrepeat * 8; diff --git a/src/p_doors.cpp b/src/p_doors.cpp index 5eb427686b..1d92ed3da8 100644 --- a/src/p_doors.cpp +++ b/src/p_doors.cpp @@ -265,8 +265,9 @@ void DDoor::DoorSound (bool raise) const if (line->backsector == NULL) continue; - texname = TexMan[sides[line->sidenum[0]].toptexture]->Name; - if (texname[0] == 'D' && texname[1] == 'O' && texname[2] == 'R') + FTexture *tex = TexMan[sides[line->sidenum[0]].GetTexture(side_t::top)]; + texname = tex? tex->Name : NULL; + if (texname != NULL && texname[0] == 'D' && texname[1] == 'O' && texname[2] == 'R') { switch (texname[3]) { @@ -606,11 +607,10 @@ void DAnimatedDoor::Tick () // IF DOOR NEEDS TO ANIMATE TO NEXT FRAME... m_Timer = m_Speed; - sides[m_Line1->sidenum[0]].midtexture = - sides[m_Line1->sidenum[1]].midtexture = - sides[m_Line2->sidenum[0]].midtexture = - sides[m_Line2->sidenum[1]].midtexture = - ani.TextureFrames[m_Frame]; + sides[m_Line1->sidenum[0]].SetTexture(side_t::mid, ani.TextureFrames[m_Frame]); + sides[m_Line1->sidenum[1]].SetTexture(side_t::mid, ani.TextureFrames[m_Frame]); + sides[m_Line2->sidenum[0]].SetTexture(side_t::mid, ani.TextureFrames[m_Frame]); + sides[m_Line2->sidenum[1]].SetTexture(side_t::mid, ani.TextureFrames[m_Frame]); } } break; @@ -642,11 +642,10 @@ void DAnimatedDoor::Tick () // IF DOOR NEEDS TO ANIMATE TO NEXT FRAME... m_Timer = m_Speed; - sides[m_Line1->sidenum[0]].midtexture = - sides[m_Line1->sidenum[1]].midtexture = - sides[m_Line2->sidenum[0]].midtexture = - sides[m_Line2->sidenum[1]].midtexture = - ani.TextureFrames[m_Frame]; + sides[m_Line1->sidenum[0]].SetTexture(side_t::mid, ani.TextureFrames[m_Frame]); + sides[m_Line1->sidenum[1]].SetTexture(side_t::mid, ani.TextureFrames[m_Frame]); + sides[m_Line2->sidenum[0]].SetTexture(side_t::mid, ani.TextureFrames[m_Frame]); + sides[m_Line2->sidenum[1]].SetTexture(side_t::mid, ani.TextureFrames[m_Frame]); } } break; @@ -699,7 +698,7 @@ DAnimatedDoor::DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay) // The DMovingCeiling constructor automatically sets up an interpolation for us. // Stop it, since the ceiling is moving instantly here. stopinterpolation (INTERP_SectorCeiling, sec); - m_WhichDoorIndex = P_FindSlidingDoorType (sides[line->sidenum[0]].toptexture); + m_WhichDoorIndex = P_FindSlidingDoorType (sides[line->sidenum[0]].GetTexture(side_t::top)); if (m_WhichDoorIndex < 0) { Printf ("EV_SlidingDoor: Textures are not defined for sliding door!"); @@ -715,16 +714,16 @@ DAnimatedDoor::DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay) if (sec->lines[i] == line) continue; - if (sides[sec->lines[i]->sidenum[0]].toptexture == sides[line->sidenum[0]].toptexture) + if (sides[sec->lines[i]->sidenum[0]].GetTexture(side_t::top) == sides[line->sidenum[0]].GetTexture(side_t::top)) { m_Line2 = sec->lines[i]; break; } } - picnum = sides[m_Line1->sidenum[0]].toptexture; - sides[m_Line1->sidenum[0]].midtexture = picnum; - sides[m_Line2->sidenum[0]].midtexture = picnum; + picnum = sides[m_Line1->sidenum[0]].GetTexture(side_t::top); + sides[m_Line1->sidenum[0]].SetTexture(side_t::mid, picnum); + sides[m_Line2->sidenum[0]].SetTexture(side_t::mid, picnum); // don't forget texture scaling here! FTexture *tex = TexMan[picnum]; @@ -783,7 +782,7 @@ bool EV_SlidingDoor (line_t *line, AActor *actor, int tag, int speed, int delay) } return false; } - if (P_FindSlidingDoorType (sides[line->sidenum[0]].toptexture) >= 0) + if (P_FindSlidingDoorType (sides[line->sidenum[0]].GetTexture(side_t::top)) >= 0) { new DAnimatedDoor (sec, line, speed, delay); return true; @@ -806,7 +805,7 @@ bool EV_SlidingDoor (line_t *line, AActor *actor, int tag, int speed, int delay) { continue; } - if (P_FindSlidingDoorType (sides[line->sidenum[0]].toptexture) >= 0) + if (P_FindSlidingDoorType (sides[line->sidenum[0]].GetTexture(side_t::top)) >= 0) { rtn = true; new DAnimatedDoor (sec, line, speed, delay); diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index cbef22134f..2be3039335 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -1889,8 +1889,11 @@ FUNC(LS_Sector_SetLink) } -static void SetWallScroller (int id, int sidechoice, fixed_t dx, fixed_t dy) +static void SetWallScroller (int id, int sidechoice, fixed_t dx, fixed_t dy, int Where) { + Where &=7; + if (Where == 0) return; + if ((dx | dy) == 0) { // Special case: Remove the scroller, because the deltas are both 0. @@ -1902,7 +1905,8 @@ static void SetWallScroller (int id, int sidechoice, fixed_t dx, fixed_t dy) int wallnum = scroller->GetWallNum (); if (wallnum >= 0 && lines[sides[wallnum].linenum].id == id && - lines[sides[wallnum].linenum].sidenum[sidechoice] == (DWORD)wallnum) + lines[sides[wallnum].linenum].sidenum[sidechoice] == (DWORD)wallnum && + Where == scroller->GetScrollParts()) { scroller->Destroy (); } @@ -1920,7 +1924,8 @@ static void SetWallScroller (int id, int sidechoice, fixed_t dx, fixed_t dy) { if ((collect.RefNum = ((DScroller *)collect.Obj)->GetWallNum ()) != -1 && lines[sides[collect.RefNum].linenum].id == id && - lines[sides[collect.RefNum].linenum].sidenum[sidechoice] == (DWORD)collect.RefNum) + lines[sides[collect.RefNum].linenum].sidenum[sidechoice] == (DWORD)collect.RefNum && + Where == ((DScroller *)collect.Obj)->GetScrollParts()) { ((DScroller *)collect.Obj)->SetRate (dx, dy); Collection.Push (collect); @@ -1944,7 +1949,7 @@ static void SetWallScroller (int id, int sidechoice, fixed_t dx, fixed_t dy) { if (lines[linenum].sidenum[sidechoice] != NO_SIDE) { - new DScroller (DScroller::sc_side, dx, dy, -1, lines[linenum].sidenum[sidechoice], 0); + new DScroller (DScroller::sc_side, dx, dy, -1, lines[linenum].sidenum[sidechoice], 0, Where); } } } @@ -1972,11 +1977,21 @@ FUNC(LS_Scroll_Texture_Both) sidechoice = 0; } - SetWallScroller (arg0, sidechoice, dx, dy); + SetWallScroller (arg0, sidechoice, dx, dy, 7); return true; } +FUNC(LS_Scroll_Wall) +// Scroll_Wall (id, x, y, side, flags) +{ + if (arg0 == 0) + return false; + + SetWallScroller (arg0, !!arg3, arg1, arg2, arg4); + return true; +} + static void SetScroller (int tag, DScroller::EScrollType type, fixed_t dx, fixed_t dy) { TThinkerIterator iterator (STAT_SCROLLER); @@ -2685,8 +2700,8 @@ FUNC(LS_ClearForceField) { line->flags &= ~(ML_BLOCKING|ML_BLOCKEVERYTHING); line->special = 0; - sides[line->sidenum[0]].midtexture = 0; - sides[line->sidenum[1]].midtexture = 0; + sides[line->sidenum[0]].SetTexture(side_t::mid, 0); + sides[line->sidenum[1]].SetTexture(side_t::mid, 0); } } } @@ -2860,7 +2875,7 @@ lnSpecFunc LineSpecials[256] = LS_GlassBreak, LS_NOP, // 50: ExtraFloor_LightOnly LS_Sector_SetLink, - LS_NOP, // 52 + LS_Scroll_Wall, LS_NOP, // 53 LS_NOP, // 54 LS_NOP, // 55 diff --git a/src/p_lnspec.h b/src/p_lnspec.h index e6d705618b..6d1d8c8929 100644 --- a/src/p_lnspec.h +++ b/src/p_lnspec.h @@ -155,12 +155,12 @@ typedef enum { #define FRICTION_MASK 0x0800 #define PUSH_MASK 0x1000 -struct line_s; +struct line_t; class AActor; FName MODtoDamageType (int mod); -typedef int (*lnSpecFunc)(struct line_s *line, +typedef int (*lnSpecFunc)(struct line_t *line, class AActor *activator, bool backSide, int arg1, diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index ac95be1f34..b6acb28d97 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -367,22 +367,10 @@ void P_SerializeWorld (FArchive &arc) continue; side_t *si = &sides[li->sidenum[j]]; - arc << si->textureoffset - << si->rowoffset; - - if (arc.IsStoring ()) - { - TexMan.WriteTexture (arc, si->toptexture); - TexMan.WriteTexture (arc, si->bottomtexture); - TexMan.WriteTexture (arc, si->midtexture); - } - else - { - si->toptexture = TexMan.ReadTexture (arc); - si->bottomtexture = TexMan.ReadTexture (arc); - si->midtexture = TexMan.ReadTexture (arc); - } - arc << si->Light + arc << si->textures[side_t::top] + << si->textures[side_t::mid] + << si->textures[side_t::bottom] + << si->Light << si->Flags << si->LeftSide << si->RightSide; diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index 3d951957ab..0bbec3929a 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -474,8 +474,8 @@ fixed_t sector_t::FindShortestTextureAround () const { if (lines[i]->flags & ML_TWOSIDED) { - CheckShortestTex (sides[lines[i]->sidenum[0]].bottomtexture, minsize); - CheckShortestTex (sides[lines[i]->sidenum[1]].bottomtexture, minsize); + CheckShortestTex (sides[lines[i]->sidenum[0]].GetTexture(side_t::bottom), minsize); + CheckShortestTex (sides[lines[i]->sidenum[1]].GetTexture(side_t::bottom), minsize); } } return minsize < FIXED_MAX ? minsize : TexMan[0]->GetHeight() * FRACUNIT; @@ -500,8 +500,8 @@ fixed_t sector_t::FindShortestUpperAround () const { if (lines[i]->flags & ML_TWOSIDED) { - CheckShortestTex (sides[lines[i]->sidenum[0]].toptexture, minsize); - CheckShortestTex (sides[lines[i]->sidenum[1]].toptexture, minsize); + CheckShortestTex (sides[lines[i]->sidenum[0]].GetTexture(side_t::top), minsize); + CheckShortestTex (sides[lines[i]->sidenum[1]].GetTexture(side_t::top), minsize); } } return minsize < FIXED_MAX ? minsize : TexMan[0]->GetHeight() * FRACUNIT; diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 8c3d7a44d4..4dccdcb869 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -385,14 +385,15 @@ MapData *P_OpenMapData(const char * mapname) // //=========================================================================== -static void SetTexture (int *texture, DWORD *blend, char *name8) +static void SetTexture (side_t *side, int position, DWORD *blend, char *name8) { char name[9]; strncpy (name, name8, 8); name[8] = 0; + int texture; if ((*blend = R_ColormapNumForName (name)) == 0) { - if ((*texture = TexMan.CheckForTexture (name, FTexture::TEX_Wall, + if ((texture = TexMan.CheckForTexture (name, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_TryAny) ) == -1) { @@ -401,7 +402,7 @@ static void SetTexture (int *texture, DWORD *blend, char *name8) strncpy (name2, name, 8); name2[8] = 0; *blend = strtoul (name2, &stop, 16); - *texture = 0; + texture = 0; } else { @@ -410,16 +411,18 @@ static void SetTexture (int *texture, DWORD *blend, char *name8) } else { - *texture = 0; + texture = 0; } + side->SetTexture(position, texture); } -static void SetTextureNoErr (int *texture, DWORD *color, char *name8, bool *validcolor) +static void SetTextureNoErr (side_t *side, int position, DWORD *color, char *name8, bool *validcolor) { char name[9]; + int texture; strncpy (name, name8, 8); name[8] = 0; - if ((*texture = TexMan.CheckForTexture (name, FTexture::TEX_Wall, + if ((texture = TexMan.CheckForTexture (name, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_TryAny) ) == -1) { @@ -428,13 +431,14 @@ static void SetTextureNoErr (int *texture, DWORD *color, char *name8, bool *vali strncpy (name2, name, 8); name2[8] = 0; *color = strtoul (name2, &stop, 16); - *texture = 0; + texture = 0; *validcolor = (*stop == 0) && (stop >= name2 + 2) && (stop <= name2 + 6); } else { *validcolor = false; } + side->SetTexture(position, texture); } //=========================================================================== @@ -2278,8 +2282,8 @@ void P_LoadSideDefs2 (MapData * map) msd->rowoffset += 102; } - sd->textureoffset = LittleShort(msd->textureoffset)<rowoffset = LittleShort(msd->rowoffset)<SetTextureXOffset(LittleShort(msd->textureoffset)<SetTextureYOffset(LittleShort(msd->rowoffset)<linenum = NO_INDEX; // killough 4/4/98: allow sidedef texture names to be overloaded @@ -2304,9 +2308,9 @@ void P_LoadSideDefs2 (MapData * map) // instead of figuring something out from the colormap. if (sec != NULL) { - SetTexture (&sd->bottomtexture, &sec->bottommap, msd->bottomtexture); - SetTexture (&sd->midtexture, &sec->midmap, msd->midtexture); - SetTexture (&sd->toptexture, &sec->topmap, msd->toptexture); + SetTexture (sd, side_t::bottom, &sec->bottommap, msd->bottomtexture); + SetTexture (sd, side_t::mid, &sec->midmap, msd->midtexture); + SetTexture (sd, side_t::top, &sec->topmap, msd->toptexture); } break; @@ -2318,10 +2322,11 @@ void P_LoadSideDefs2 (MapData * map) DWORD color, fog; bool colorgood, foggood; - SetTextureNoErr (&sd->bottomtexture, &fog, msd->bottomtexture, &foggood); - SetTextureNoErr (&sd->toptexture, &color, msd->toptexture, &colorgood); + SetTextureNoErr (sd, side_t::bottom, &fog, msd->bottomtexture, &foggood); + SetTextureNoErr (sd, side_t::top, &color, msd->toptexture, &colorgood); strncpy (name, msd->midtexture, 8); - sd->midtexture = TexMan.GetTexture (name, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable); + sd->SetTexture(side_t::mid, + TexMan.GetTexture (name, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable)); if (colorgood | foggood) { @@ -2355,47 +2360,42 @@ void P_LoadSideDefs2 (MapData * map) if (strnicmp ("TRANMAP", msd->midtexture, 8) == 0) { // The translator set the alpha argument already; no reason to do it again. - sd->midtexture = 0; + sd->SetTexture(side_t::mid, 0); } else if ((lumpnum = Wads.CheckNumForName (msd->midtexture)) > 0 && Wads.LumpLength (lumpnum) == 65536) { sidetemp[i].a.alpha = P_DetermineTranslucency (lumpnum); - sd->midtexture = 0; + sd->SetTexture(side_t::mid, 0); } else { strncpy (name, msd->midtexture, 8); - sd->midtexture = TexMan.GetTexture (name, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable); + sd->SetTexture(side_t::mid, + TexMan.GetTexture (name, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable)); } strncpy (name, msd->toptexture, 8); - sd->toptexture = TexMan.GetTexture (name, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable); + sd->SetTexture(side_t::top, TexMan.GetTexture (name, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable)); strncpy (name, msd->bottomtexture, 8); - sd->bottomtexture = TexMan.GetTexture (name, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable); + sd->SetTexture(side_t::bottom, TexMan.GetTexture (name, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable)); break; } // Fallthrough for Hexen maps is intentional -#if 0 - sd->midtexture = strncasecmp("TRANMAP", msd->midtexture, 8) ? - (sd->special = W_CheckNumForName(msd->midtexture)) < 0 || - W_LumpLength(sd->special) != 65536 ? - sd->special=0, R_TextureNumForName(msd->midtexture) : - (sd->special++, 0) : (sd->special=0); - sd->toptexture = R_TextureNumForName(msd->toptexture); - sd->bottomtexture = R_TextureNumForName(msd->bottomtexture); -#endif default: // normal cases strncpy (name, msd->midtexture, 8); - sd->midtexture = TexMan.GetTexture (name, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable); + sd->SetTexture(side_t::mid, + TexMan.GetTexture (name, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable)); strncpy (name, msd->toptexture, 8); - sd->toptexture = TexMan.GetTexture (name, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable); + sd->SetTexture(side_t::top, + TexMan.GetTexture (name, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable)); strncpy (name, msd->bottomtexture, 8); - sd->bottomtexture = TexMan.GetTexture (name, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable); + sd->SetTexture(side_t::bottom, + TexMan.GetTexture (name, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable)); break; } } diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 620b605f9f..e56393b760 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -92,7 +92,8 @@ void DScroller::Serialize (FArchive &arc) << m_Control << m_LastHeight << m_vdx << m_vdy - << m_Accel; + << m_Accel + << m_Parts; } DPusher::DPusher () @@ -1109,8 +1110,22 @@ void DScroller::Tick () switch (m_Type) { case sc_side: // killough 3/7/98: Scroll wall texture - sides[m_Affectee].textureoffset += dx; - sides[m_Affectee].rowoffset += dy; + if (m_Parts & scw_top) + { + sides[m_Affectee].AddTextureXOffset(side_t::top, dx); + sides[m_Affectee].AddTextureYOffset(side_t::top, dy); + } + if (m_Parts & scw_mid && (lines[sides[m_Affectee].linenum].backsector == NULL || + !(lines[sides[m_Affectee].linenum].flags&ML_3DMIDTEX))) + { + sides[m_Affectee].AddTextureXOffset(side_t::mid, dx); + sides[m_Affectee].AddTextureYOffset(side_t::mid, dy); + } + if (m_Parts & scw_bottom) + { + sides[m_Affectee].AddTextureXOffset(side_t::bottom, dx); + sides[m_Affectee].AddTextureYOffset(side_t::bottom, dy); + } break; case sc_floor: // killough 3/7/98: Scroll floor texture @@ -1153,13 +1168,14 @@ void DScroller::Tick () // DScroller::DScroller (EScrollType type, fixed_t dx, fixed_t dy, - int control, int affectee, int accel) + int control, int affectee, int accel, int scrollpos) : DThinker (STAT_SCROLLER) { m_Type = type; m_dx = dx; m_dy = dy; m_Accel = accel; + m_Parts = scrollpos; m_vdx = m_vdy = 0; if ((m_Control = control) != -1) m_LastHeight = @@ -1173,7 +1189,19 @@ DScroller::DScroller (EScrollType type, fixed_t dx, fixed_t dy, case sc_side: sides[affectee].Flags |= WALLF_NOAUTODECALS; - setinterpolation (INTERP_WallPanning, &sides[affectee]); + if (m_Parts & scw_top) + { + sides[m_Affectee].SetInterpolation(side_t::top); + } + if (m_Parts & scw_mid && (lines[sides[m_Affectee].linenum].backsector == NULL || + !(lines[sides[m_Affectee].linenum].flags&ML_3DMIDTEX))) + { + sides[m_Affectee].SetInterpolation(side_t::mid); + } + if (m_Parts & scw_bottom) + { + sides[m_Affectee].SetInterpolation(side_t::bottom); + } break; case sc_floor: @@ -1194,7 +1222,19 @@ DScroller::~DScroller () switch (m_Type) { case sc_side: - stopinterpolation (INTERP_WallPanning, &sides[m_Affectee]); + if (m_Parts & scw_top) + { + sides[m_Affectee].StopInterpolation(side_t::top); + } + if (m_Parts & scw_mid && (lines[sides[m_Affectee].linenum].backsector == NULL || + !(lines[sides[m_Affectee].linenum].flags&ML_3DMIDTEX))) + { + sides[m_Affectee].StopInterpolation(side_t::mid); + } + if (m_Parts & scw_bottom) + { + sides[m_Affectee].StopInterpolation(side_t::bottom); + } break; case sc_floor: @@ -1218,7 +1258,7 @@ DScroller::~DScroller () // killough 5/25/98: cleaned up arithmetic to avoid drift due to roundoff DScroller::DScroller (fixed_t dx, fixed_t dy, const line_t *l, - int control, int accel) + int control, int accel, int scrollpos) : DThinker (STAT_SCROLLER) { fixed_t x = abs(l->dx), y = abs(l->dy), d; @@ -1234,16 +1274,30 @@ DScroller::DScroller (fixed_t dx, fixed_t dy, const line_t *l, m_dy = y; m_vdx = m_vdy = 0; m_Accel = accel; + m_Parts = scrollpos; if ((m_Control = control) != -1) m_LastHeight = sectors[control].CenterFloor() + sectors[control].CenterCeiling(); m_Affectee = *l->sidenum; sides[m_Affectee].Flags |= WALLF_NOAUTODECALS; - setinterpolation (INTERP_WallPanning, &sides[m_Affectee]); + if (m_Parts & scw_top) + { + sides[m_Affectee].SetInterpolation(side_t::top); + } + if (m_Parts & scw_mid && (lines[sides[m_Affectee].linenum].backsector == NULL || + !(lines[sides[m_Affectee].linenum].flags&ML_3DMIDTEX))) + { + sides[m_Affectee].SetInterpolation(side_t::mid); + } + if (m_Parts & scw_bottom) + { + sides[m_Affectee].SetInterpolation(side_t::bottom); + } } // Amount (dx,dy) vector linedef is shifted right to get scroll amount #define SCROLL_SHIFT 5 +#define SCROLLTYPE(i) ((i)<=0 ? 7:(i)) // Initialize the scrollers static void P_SpawnScrollers(void) @@ -1333,28 +1387,28 @@ static void P_SpawnScrollers(void) case Scroll_Texture_Offsets: // killough 3/2/98: scroll according to sidedef offsets s = lines[i].sidenum[0]; - new DScroller (DScroller::sc_side, -sides[s].textureoffset, - sides[s].rowoffset, -1, s, accel); + new DScroller (DScroller::sc_side, -sides[s].GetTextureXOffset(side_t::mid), + sides[s].GetTextureYOffset(side_t::mid), -1, s, accel, SCROLLTYPE(l->args[0])); break; case Scroll_Texture_Left: new DScroller (DScroller::sc_side, l->args[0] * (FRACUNIT/64), 0, - -1, lines[i].sidenum[0], accel); + -1, lines[i].sidenum[0], accel, SCROLLTYPE(l->args[1])); break; case Scroll_Texture_Right: new DScroller (DScroller::sc_side, l->args[0] * (-FRACUNIT/64), 0, - -1, lines[i].sidenum[0], accel); + -1, lines[i].sidenum[0], accel, SCROLLTYPE(l->args[1])); break; case Scroll_Texture_Up: new DScroller (DScroller::sc_side, 0, l->args[0] * (FRACUNIT/64), - -1, lines[i].sidenum[0], accel); + -1, lines[i].sidenum[0], accel, SCROLLTYPE(l->args[1])); break; case Scroll_Texture_Down: new DScroller (DScroller::sc_side, 0, l->args[0] * (-FRACUNIT/64), - -1, lines[i].sidenum[0], accel); + -1, lines[i].sidenum[0], accel, SCROLLTYPE(l->args[1])); break; case Scroll_Texture_Both: diff --git a/src/p_spec.h b/src/p_spec.h index 6ee3ef143a..5b73ace2b1 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -52,9 +52,16 @@ public: sc_carry, sc_carry_ceiling, // killough 4/11/98: carry objects hanging on ceilings }; + enum EScrollPos + { + scw_top=1, + scw_mid=2, + scw_bottom=4, + scw_all=7, + }; - DScroller (EScrollType type, fixed_t dx, fixed_t dy, int control, int affectee, int accel); - DScroller (fixed_t dx, fixed_t dy, const line_t *l, int control, int accel); + DScroller (EScrollType type, fixed_t dx, fixed_t dy, int control, int affectee, int accel, int scrollpos = scw_all); + DScroller (fixed_t dx, fixed_t dy, const line_t *l, int control, int accel, int scrollpos = scw_all); ~DScroller (); void Serialize (FArchive &arc); @@ -65,6 +72,7 @@ public: void SetRate (fixed_t dx, fixed_t dy) { m_dx = dx; m_dy = dy; } bool IsType (EScrollType type) const { return type == m_Type; } int GetAffectee () const { return m_Affectee; } + int GetScrollParts() const { return m_Parts; } protected: EScrollType m_Type; // Type of scroll effect @@ -74,6 +82,7 @@ protected: fixed_t m_LastHeight; // Last known height of control sector fixed_t m_vdx, m_vdy; // Accumulated velocity if accelerative int m_Accel; // Whether it's accelerative + int m_Parts; // Which parts of a sidedef are being scrolled? private: DScroller (); diff --git a/src/p_switch.cpp b/src/p_switch.cpp index 4b059439b3..91f1efe28e 100644 --- a/src/p_switch.cpp +++ b/src/p_switch.cpp @@ -58,22 +58,14 @@ class DActiveButton : public DThinker { DECLARE_CLASS (DActiveButton, DThinker) public: - enum EWhere - { - BUTTON_Top, - BUTTON_Middle, - BUTTON_Bottom, - BUTTON_Nowhere - }; - DActiveButton (); - DActiveButton (side_t *, EWhere, WORD switchnum, fixed_t x, fixed_t y, bool flippable); + DActiveButton (side_t *, int, WORD switchnum, fixed_t x, fixed_t y, bool flippable); void Serialize (FArchive &arc); void Tick (); side_t *m_Side; - EWhere m_Where; + SBYTE m_Part; WORD m_SwitchDef; WORD m_Frame; WORD m_Timer; @@ -82,15 +74,6 @@ public: protected: bool AdvanceFrame (); - void StoreTexture (short tex) const; - - friend FArchive &operator<< (FArchive &arc, EWhere &where) - { - BYTE val = (BYTE)where; - arc << val; - where = (EWhere)val; - return arc; - } }; struct FSwitchDef @@ -435,7 +418,7 @@ static WORD AddSwitchDef (FSwitchDef *def) // Start a button counting down till it turns off. // [RH] Rewritten to remove MAXBUTTONS limit. // -static bool P_StartButton (side_t *side, DActiveButton::EWhere w, int switchnum, +static bool P_StartButton (side_t *side, int Where, int switchnum, fixed_t x, fixed_t y, bool useagain) { DActiveButton *button; @@ -451,14 +434,15 @@ static bool P_StartButton (side_t *side, DActiveButton::EWhere w, int switchnum, } } - new DActiveButton (side, w, switchnum, x, y, useagain); + new DActiveButton (side, Where, switchnum, x, y, useagain); return true; } -static int TryFindSwitch (SWORD texture) +static int TryFindSwitch (side_t *side, int Where) { int mid, low, high; + int texture = side->GetTexture(Where); high = (int)(SwitchList.Size () - 1); if (high >= 0) { @@ -519,15 +503,15 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno) P_LineOpening(open, NULL, line, checkx, checky, user->x, user->y); if (open.range <= 0) return true; - if ((TryFindSwitch (side->toptexture)) != -1) + if ((TryFindSwitch (side, side_t::top)) != -1) { return (user->z + user->height >= open.top); } - else if ((TryFindSwitch (side->bottomtexture)) != -1) + else if ((TryFindSwitch (side, side_t::bottom)) != -1) { return (user->z <= open.bottom); } - else if ((line->flags & (ML_3DMIDTEX)) || (TryFindSwitch (side->midtexture)) != -1) + else if ((line->flags & (ML_3DMIDTEX)) || (TryFindSwitch (side, side_t::mid)) != -1) { // 3DMIDTEX lines will force a mid texture check if no switch is found on this line // to keep compatibility with Eternity's implementation. @@ -547,24 +531,20 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno) // bool P_ChangeSwitchTexture (side_t *side, int useAgain, BYTE special, bool *quest) { - DActiveButton::EWhere Where; - int *texture; + int texture; int i, sound; - if ((i = TryFindSwitch (side->toptexture)) != -1) + if ((i = TryFindSwitch (side, side_t::top)) != -1) { - texture = &side->toptexture; - Where = DActiveButton::BUTTON_Top; + texture = side_t::top; } - else if ((i = TryFindSwitch (side->bottomtexture)) != -1) + else if ((i = TryFindSwitch (side, side_t::bottom)) != -1) { - texture = &side->bottomtexture; - Where = DActiveButton::BUTTON_Bottom; + texture = side_t::bottom; } - else if ((i = TryFindSwitch (side->midtexture)) != -1) + else if ((i = TryFindSwitch (side, side_t::mid)) != -1) { - texture = &side->midtexture; - Where = DActiveButton::BUTTON_Middle; + texture = side_t::mid; } else { @@ -600,9 +580,9 @@ bool P_ChangeSwitchTexture (side_t *side, int useAgain, BYTE special, bool *ques pt[0] = line->v1->x + (line->dx >> 1); pt[1] = line->v1->y + (line->dy >> 1); - *texture = SwitchList[i]->u[0].Texture; + side->SetTexture(texture, SwitchList[i]->u[0].Texture); if (useAgain || SwitchList[i]->NumFrames > 1) - playsound = P_StartButton (side, Where, i, pt[0], pt[1], !!useAgain); + playsound = P_StartButton (side, texture, i, pt[0], pt[1], !!useAgain); else playsound = true; if (playsound) S_SoundID (pt, CHAN_VOICE|CHAN_LISTENERZ|CHAN_IMMOBILE, sound, 1, ATTN_STATIC); @@ -618,7 +598,7 @@ IMPLEMENT_CLASS (DActiveButton) DActiveButton::DActiveButton () { m_Side = NULL; - m_Where = BUTTON_Nowhere; + m_Part = -1; m_SwitchDef = 0; m_Timer = 0; m_X = 0; @@ -626,11 +606,11 @@ DActiveButton::DActiveButton () bFlippable = false; } -DActiveButton::DActiveButton (side_t *side, EWhere where, WORD switchnum, +DActiveButton::DActiveButton (side_t *side, int Where, WORD switchnum, fixed_t x, fixed_t y, bool useagain) { m_Side = side; - m_Where = where; + m_Part = SBYTE(Where); m_X = x; m_Y = y; bFlippable = useagain; @@ -649,7 +629,7 @@ void DActiveButton::Serialize (FArchive &arc) { sidenum = m_Side ? m_Side - sides : -1; } - arc << sidenum << m_Where << m_SwitchDef << m_Frame << m_Timer << bFlippable << m_X << m_Y; + arc << sidenum << m_Part << m_SwitchDef << m_Frame << m_Timer << bFlippable << m_X << m_Y; if (arc.IsLoading ()) { m_Side = sidenum >= 0 ? sides + sidenum : NULL; @@ -685,7 +665,7 @@ void DActiveButton::Tick () } bool killme = AdvanceFrame (); - StoreTexture (def->u[m_Frame].Texture); + m_Side->SetTexture(m_Part, def->u[m_Frame].Texture); if (killme) { @@ -728,23 +708,3 @@ bool DActiveButton::AdvanceFrame () return ret; } -void DActiveButton::StoreTexture (short tex) const -{ - switch (m_Where) - { - case BUTTON_Middle: - m_Side->midtexture = tex; - break; - - case BUTTON_Bottom: - m_Side->bottomtexture = tex; - break; - - case BUTTON_Top: - m_Side->toptexture = tex; - break; - - default: - return; - } -} diff --git a/src/p_writemap.cpp b/src/p_writemap.cpp index 1f711a6790..637b689a8a 100644 --- a/src/p_writemap.cpp +++ b/src/p_writemap.cpp @@ -147,12 +147,12 @@ static int WriteSIDEDEFS (FILE *file) for (int i = 0; i < numsides; ++i) { - msd.textureoffset = LittleShort(short(sides[i].textureoffset >> FRACBITS)); - msd.rowoffset = LittleShort(short(sides[i].rowoffset >> FRACBITS)); + msd.textureoffset = LittleShort(short(sides[i].GetTextureXOffset(side_t::mid) >> FRACBITS)); + msd.rowoffset = LittleShort(short(sides[i].GetTextureYOffset(side_t::mid) >> FRACBITS)); msd.sector = LittleShort(short(sides[i].sector - sectors)); - uppercopy (msd.toptexture, GetTextureName (sides[i].toptexture)); - uppercopy (msd.bottomtexture, GetTextureName (sides[i].bottomtexture)); - uppercopy (msd.midtexture, GetTextureName (sides[i].midtexture)); + uppercopy (msd.toptexture, GetTextureName (sides[i].GetTexture(side_t::top))); + uppercopy (msd.bottomtexture, GetTextureName (sides[i].GetTexture(side_t::bottom))); + uppercopy (msd.midtexture, GetTextureName (sides[i].GetTexture(side_t::mid))); fwrite (&msd, sizeof(msd), 1, file); } return numsides * sizeof(msd); diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index e2068767e7..27248e6082 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -756,8 +756,8 @@ void R_AddLine (seg_t *line) && rw_backcz1 <= rw_backfz1 && rw_backcz2 <= rw_backfz2 // preserve a kind of transparent door/lift special effect: - && ((rw_backcz1 >= rw_frontcz1 && rw_backcz2 >= rw_frontcz2) || line->sidedef->toptexture != 0) - && ((rw_backfz1 <= rw_frontfz1 && rw_backfz2 <= rw_frontfz2) || line->sidedef->bottomtexture != 0)) + && ((rw_backcz1 >= rw_frontcz1 && rw_backcz2 >= rw_frontcz2) || line->sidedef->GetTexture(side_t::top) != 0) + && ((rw_backfz1 <= rw_frontfz1 && rw_backfz2 <= rw_frontfz2) || line->sidedef->GetTexture(side_t::bottom) != 0)) { // killough 1/18/98 -- This function is used to fix the automap bug which // showed lines behind closed doors simply because the door had a dropoff. @@ -779,7 +779,7 @@ void R_AddLine (seg_t *line) else if (backsector->lightlevel != frontsector->lightlevel || backsector->floorpic != frontsector->floorpic || backsector->ceilingpic != frontsector->ceilingpic - || curline->sidedef->midtexture != 0 + || curline->sidedef->GetTexture(side_t::mid) != 0 // killough 3/7/98: Take flats offsets into account: || backsector->floor_xoffs != frontsector->floor_xoffs @@ -834,12 +834,12 @@ void R_AddLine (seg_t *line) #if 0 // Maybe later... if (!solid) { - if (rw_ceilstat == 12 && line->sidedef->toptexture != 0) + if (rw_ceilstat == 12 && line->sidedef->GetTexture(side_t::top) != 0) { rw_mustmarkceiling = true; solid = true; } - if (rw_floorstat == 3 && line->sidedef->bottomtexture != 0) + if (rw_floorstat == 3 && line->sidedef->GetTexture(side_t::bottom) != 0) { rw_mustmarkfloor = true; solid = true; diff --git a/src/r_data.cpp b/src/r_data.cpp index e8d119a150..865d22d748 100644 --- a/src/r_data.cpp +++ b/src/r_data.cpp @@ -462,9 +462,9 @@ void R_PrecacheLevel (void) for (i = numsides - 1; i >= 0; i--) { - hitlist[sides[i].toptexture] = - hitlist[sides[i].midtexture] = - hitlist[sides[i].bottomtexture] = 1; + hitlist[sides[i].GetTexture(side_t::top)] = + hitlist[sides[i].GetTexture(side_t::mid)] = + hitlist[sides[i].GetTexture(side_t::bottom)] = 1; } // Sky texture is always present. diff --git a/src/r_defs.h b/src/r_defs.h index 596d058d77..723c1646a7 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -35,6 +35,7 @@ #include "actor.h" #include "dthinker.h" +#include "r_interpolate.h" @@ -82,7 +83,7 @@ struct vertex_s typedef struct vertex_s vertex_t; // Forward of LineDefs, for Sectors. -struct line_s; +struct line_t; class player_s; @@ -262,12 +263,11 @@ struct FExtraLight WORD NumUsedLights; FLightStack *Lights; // Lights arranged from top to bottom - void InsertLight (const secplane_t &plane, line_s *line, int type); + void InsertLight (const secplane_t &plane, line_t *line, int type); }; // this substructure contains a few sector properties that are stored in dynamic arrays // These must not be copied by R_FakeFlat etc. or bad things will happen. -struct line_s; struct sector_t; struct FLinkedSector @@ -285,7 +285,7 @@ struct extsector_t struct plane { TArray AttachedSectors; // all sectors containing 3dMidtex lines attached to this sector - TArray AttachedLines; // all 3dMidtex lines attached to this sector + TArray AttachedLines; // all 3dMidtex lines attached to this sector } Floor, Ceiling; } Midtex; @@ -386,7 +386,7 @@ struct sector_t SWORD nextsec; // -1 or number of next step sector short linecount; - struct line_s **lines; // [linecount] size + struct line_t **lines; // [linecount] size // killough 3/7/98: support flat heights drawn at another sector's heights sector_t *heightsec; // other sector, or NULL if no other sector @@ -443,16 +443,28 @@ enum WALLF_ABSLIGHTING = 1, // Light is absolute instead of relative WALLF_NOAUTODECALS = 2, // Do not attach impact decals to this wall WALLF_ADDTRANS = 4, // Use additive instead of normal translucency - WALLF_AUTOCONTRAST = 8, // Automatically handle fake contrast in side_s::GetLightLevel + WALLF_AUTOCONTRAST = 8, // Automatically handle fake contrast in side_t::GetLightLevel }; -struct side_s +struct side_t { - fixed_t textureoffset; // add this to the calculated texture column - fixed_t rowoffset; // add this to the calculated texture top + enum ETexpart + { + top=0, + mid=1, + bottom=2 + }; + struct part + { + fixed_t xoffset; + fixed_t yoffset; + int texture; + //int Light; + }; + sector_t* sector; // Sector the SideDef is facing. DBaseDecal* AttachedDecals; // [RH] Decals bound to the wall - int toptexture, bottomtexture, midtexture; // texture indices + part textures[3]; WORD linenum; DWORD LeftSide, RightSide; // [RH] Group walls into loops WORD TexelLength; @@ -460,9 +472,66 @@ struct side_s BYTE Flags; int GetLightLevel (bool foggy, int baselight) const; -}; -typedef struct side_s side_t; + int GetTexture(int which) const + { + return textures[which].texture; + } + void SetTexture(int which, int tex) + { + textures[which].texture = tex; + } + + void SetTextureXOffset(int which, fixed_t offset) + { + textures[which].xoffset = offset; + } + void SetTextureXOffset(fixed_t offset) + { + textures[top].xoffset = + textures[mid].xoffset = + textures[bottom].xoffset = offset; + } + fixed_t GetTextureXOffset(int which) const + { + return textures[which].xoffset; + } + void AddTextureXOffset(int which, fixed_t delta) + { + textures[which].xoffset += delta; + } + + void SetTextureYOffset(int which, fixed_t offset) + { + textures[which].yoffset = offset; + } + void SetTextureYOffset(fixed_t offset) + { + textures[top].yoffset = + textures[mid].yoffset = + textures[bottom].yoffset = offset; + } + fixed_t GetTextureYOffset(int which) const + { + return textures[which].yoffset; + } + void AddTextureYOffset(int which, fixed_t delta) + { + textures[which].yoffset += delta; + } + + void SetInterpolation(int position) + { + setinterpolation(EInterpType(INTERP_WallPanning_Top+position), this); + } + void StopInterpolation(int position) + { + setinterpolation(EInterpType(INTERP_WallPanning_Top+position), this); + } + +}; + +FArchive &operator<< (FArchive &arc, side_t::part &p); // // Move clipping aid for LineDefs. @@ -476,7 +545,7 @@ enum slopetype_t }; -struct line_s +struct line_t { vertex_t *v1, *v2; // vertices, from v1 to v2 fixed_t dx, dy; // precalculated v2 - v1 for side checking @@ -486,14 +555,13 @@ struct line_s short id; // <--- same as tag or set with Line_SetIdentification int args[5]; // <--- hexen-style arguments (expanded to ZDoom's full width) int firstid, nextid; - DWORD sidenum[2]; // sidenum[1] will be 0xffffffff if one sided + DWORD sidenum[2]; // sidenum[1] will be NO_SIDE if one sided fixed_t bbox[4]; // bounding box, for the extent of the LineDef. slopetype_t slopetype; // To aid move clipping. sector_t *frontsector, *backsector; int validcount; // if == validcount, already checked }; -typedef struct line_s line_t; // phares 3/14/98 // diff --git a/src/r_main.cpp b/src/r_main.cpp index 150304f5f8..ab61623176 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -1822,9 +1822,11 @@ void FActiveInterpolation::CopyInterpToOld () oldipos[0] = ((sector_t*)Address)->ceiling_xoffs; oldipos[1] = ((sector_t*)Address)->ceiling_yoffs; break; - case INTERP_WallPanning: - oldipos[0] = ((side_t*)Address)->rowoffset; - oldipos[1] = ((side_t*)Address)->textureoffset; + case INTERP_WallPanning_Top: + case INTERP_WallPanning_Mid: + case INTERP_WallPanning_Bottom: + oldipos[0] = ((side_t*)Address)->GetTextureYOffset(Type - INTERP_WallPanning_Top); + oldipos[1] = ((side_t*)Address)->GetTextureXOffset(Type - INTERP_WallPanning_Top); break; } } @@ -1853,9 +1855,11 @@ void FActiveInterpolation::CopyBakToInterp () ((sector_t*)Address)->ceiling_xoffs = bakipos[0]; ((sector_t*)Address)->ceiling_yoffs = bakipos[1]; break; - case INTERP_WallPanning: - ((side_t*)Address)->rowoffset = bakipos[0]; - ((side_t*)Address)->textureoffset = bakipos[1]; + case INTERP_WallPanning_Top: + case INTERP_WallPanning_Mid: + case INTERP_WallPanning_Bottom: + ((side_t*)Address)->SetTextureYOffset(Type - INTERP_WallPanning_Top, bakipos[0]); + ((side_t*)Address)->SetTextureXOffset(Type - INTERP_WallPanning_Top, bakipos[1]); break; } } @@ -1863,6 +1867,7 @@ void FActiveInterpolation::CopyBakToInterp () void FActiveInterpolation::DoAnInterpolation (fixed_t smoothratio) { fixed_t *adr1, *adr2, pos; + int v1, v2; switch (Type) { @@ -1886,9 +1891,13 @@ void FActiveInterpolation::DoAnInterpolation (fixed_t smoothratio) adr1 = &((sector_t*)Address)->ceiling_xoffs; adr2 = &((sector_t*)Address)->ceiling_yoffs; break; - case INTERP_WallPanning: - adr1 = &((side_t*)Address)->rowoffset; - adr2 = &((side_t*)Address)->textureoffset; + case INTERP_WallPanning_Top: + case INTERP_WallPanning_Mid: + case INTERP_WallPanning_Bottom: + v1 = ((side_t*)Address)->GetTextureYOffset(Type - INTERP_WallPanning_Top); + v2 = ((side_t*)Address)->GetTextureXOffset(Type - INTERP_WallPanning_Top); + adr1 = &v1; + adr2 = &v2; break; default: return; @@ -1899,6 +1908,19 @@ void FActiveInterpolation::DoAnInterpolation (fixed_t smoothratio) pos = bakipos[1] = *adr2; *adr2 = oldipos[1] + FixedMul (pos - oldipos[1], smoothratio); + + switch (Type) + { + case INTERP_WallPanning_Top: + case INTERP_WallPanning_Mid: + case INTERP_WallPanning_Bottom: + ((side_t*)Address)->SetTextureYOffset(Type - INTERP_WallPanning_Top, v1); + ((side_t*)Address)->SetTextureXOffset(Type - INTERP_WallPanning_Top, v2); + break; + default: + return; + } + } size_t FActiveInterpolation::HashKey (EInterpType type, void *interptr) @@ -2141,7 +2163,10 @@ FArchive &operator << (FArchive &arc, FActiveInterpolation *&interp) switch (type) { case INTERP_Vertex: arc << ptr.vert; break; - case INTERP_WallPanning: arc << ptr.side; break; + case INTERP_WallPanning_Top: + case INTERP_WallPanning_Mid: + case INTERP_WallPanning_Bottom: + arc << ptr.side; break; default: arc << ptr.sect; break; } } @@ -2153,7 +2178,10 @@ FArchive &operator << (FArchive &arc, FActiveInterpolation *&interp) switch (type) { case INTERP_Vertex: arc << ptr.vert; break; - case INTERP_WallPanning: arc << ptr.side; break; + case INTERP_WallPanning_Top: + case INTERP_WallPanning_Mid: + case INTERP_WallPanning_Bottom: + arc << ptr.side; break; default: arc << ptr.sect; break; } interp->Address = ptr.ptr; diff --git a/src/r_main.h b/src/r_main.h index c4e9b4a41c..ec0459c8dd 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -207,58 +207,6 @@ void R_SetViewSize (int blocks); // [RH] Initialize multires stuff for renderer void R_MultiresInit (void); -// BUILD stuff for interpolating between frames, but modified (rather a lot) -#define INTERPOLATION_BUCKETS 107 - -enum EInterpType -{ - INTERP_SectorFloor, // Pass a sector_t * - INTERP_SectorCeiling, // Pass a sector_t * - INTERP_Vertex, // Pass a vertex_t * - INTERP_FloorPanning, // Pass a sector_t * - INTERP_CeilingPanning, // Pass a sector_t * - INTERP_WallPanning, // Pass a side_t * -}; - -struct FActiveInterpolation -{ - FActiveInterpolation *Next; - void *Address; - EInterpType Type; - - friend FArchive &operator << (FArchive &arc, FActiveInterpolation *&interp); - - static int CountInterpolations (); - static int CountInterpolations (int *usedbuckets, int *minbucketfill, int *maxbucketfill); - -private: - fixed_t oldipos[2], bakipos[2]; - - void CopyInterpToOld(); - void CopyBakToInterp(); - void DoAnInterpolation(fixed_t smoothratio); - - static size_t HashKey(EInterpType type, void *interptr); - static FActiveInterpolation *FindInterpolation(EInterpType, void *interptr, FActiveInterpolation **&interp_p); - - friend void updateinterpolations(); - friend void setinterpolation(EInterpType, void *interptr, bool dolinks); - friend void stopinterpolation(EInterpType, void *interptr, bool dolinks); - friend void dointerpolations(fixed_t smoothratio); - friend void restoreinterpolations(); - friend void clearinterpolations(); - friend void SerializeInterpolations(FArchive &arc); - - static FActiveInterpolation *curiposhash[INTERPOLATION_BUCKETS]; -}; - -void updateinterpolations(); -void setinterpolation(EInterpType, void *interptr, bool dolinks = true); -void stopinterpolation(EInterpType, void *interptr, bool dolinks = true); -void dointerpolations(fixed_t smoothratio); -void restoreinterpolations(); -void clearinterpolations(); -void SerializeInterpolations(FArchive &arc); extern void R_FreePastViewers (); extern void R_ClearPastViewer (AActor *actor); diff --git a/src/r_plane.cpp b/src/r_plane.cpp index 86b445b293..419107e384 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -1276,17 +1276,20 @@ sky1: // Sky transferred from first sidedef const side_t *s = *l->sidenum + sides; + int pos; // Texture comes from upper texture of reference sidedef // [RH] If swapping skies, then use the lower sidedef - if (level.flags & LEVEL_SWAPSKIES && s->bottomtexture != 0) + if (level.flags & LEVEL_SWAPSKIES && s->GetTexture(side_t::bottom) != 0) { - frontskytex = TexMan(s->bottomtexture); + pos = side_t::bottom; } else { - frontskytex = TexMan(s->toptexture); + pos = side_t::top; } + + frontskytex = TexMan(s->GetTexture(pos)); if (frontskytex->UseType == FTexture::TEX_Null) { // [RH] The blank texture: Use normal sky instead. goto sky1; @@ -1297,10 +1300,10 @@ sky1: // to allow sky rotation as well as careful positioning. // However, the offset is scaled very small, so that it // allows a long-period of sky rotation. - frontpos = (-s->textureoffset) >> 6; + frontpos = (-s->GetTextureXOffset(pos)) >> 6; // Vertical offset allows careful sky positioning. - dc_texturemid = s->rowoffset - 28*FRACUNIT; + dc_texturemid = s->GetTextureYOffset(pos) - 28*FRACUNIT; // We sometimes flip the picture horizontally. // diff --git a/src/r_polymost.cpp b/src/r_polymost.cpp index 7adb332196..b184224947 100644 --- a/src/r_polymost.cpp +++ b/src/r_polymost.cpp @@ -1275,7 +1275,7 @@ void RP_AddLine (seg_t *line) // preserve a kind of transparent door/lift special effect: && bcz0 >= fcz0 && bcz1 >= fcz1 - && ((bfz0 <= ffz0 && bfz1 <= ffz1) || line->sidedef->bottomtexture != 0)) + && ((bfz0 <= ffz0 && bfz1 <= ffz1) || line->sidedef->GetTexture(side_t::bottom) != 0)) { // killough 1/18/98 -- This function is used to fix the automap bug which // showed lines behind closed doors simply because the door had a dropoff. @@ -1297,7 +1297,7 @@ void RP_AddLine (seg_t *line) else if (backsector->lightlevel != frontsector->lightlevel || backsector->floorpic != frontsector->floorpic || backsector->ceilingpic != frontsector->ceilingpic - || curline->sidedef->midtexture != 0 + || curline->sidedef->GetTexture(side_t::mid) != 0 // killough 3/7/98: Take flats offsets into account: || backsector->floor_xoffs != frontsector->floor_xoffs @@ -1342,7 +1342,8 @@ void RP_AddLine (seg_t *line) markceiling = markfloor = true; } - rw_offset = line->sidedef->textureoffset; + // must be fixed in case the polymost renderer ever gets developed further! + rw_offset = line->sidedef->GetTextureXOffset(side_t::mid); R_NewWall (false); if (rw_markmirror) diff --git a/src/r_segs.cpp b/src/r_segs.cpp index 9a3dda538c..5abc48dcb5 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -71,6 +71,9 @@ bool markceiling; FTexture *toptexture; FTexture *bottomtexture; FTexture *midtexture; +fixed_t rw_offset_top; +fixed_t rw_offset_mid; +fixed_t rw_offset_bottom; int OWallMost (short *mostbuf, fixed_t z); int WallMost (short *mostbuf, const secplane_t &plane); @@ -219,7 +222,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) frontsector = curline->frontsector; backsector = curline->backsector; - tex = TexMan(curline->sidedef->midtexture); + tex = TexMan(curline->sidedef->GetTexture(side_t::mid)); // killough 4/13/98: get correct lightlevel for 2s normal textures const sector_t *sec = R_FakeFlat (frontsector, &tempsec, NULL, NULL, false); @@ -259,11 +262,13 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) { dc_texturemid = MIN (frontsector->ceilingtexz, backsector->ceilingtexz); } + + fixed_t rowoffset = curline->sidedef->GetTextureYOffset(side_t::mid); if (tex->bWorldPanning) { // rowoffset is added before the MulScale3 so that the masked texture will // still be positioned in world units rather than texels. - dc_texturemid += curline->sidedef->rowoffset - viewz; + dc_texturemid += rowoffset - viewz; textop = dc_texturemid; dc_texturemid = MulScale16 (dc_texturemid, tex->yScale); } @@ -271,8 +276,8 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) { // rowoffset is added outside the multiply so that it positions the texture // by texels instead of world units. - textop = dc_texturemid - viewz + SafeDivScale16 (curline->sidedef->rowoffset, tex->yScale); - dc_texturemid = MulScale16 (dc_texturemid - viewz, tex->yScale) + curline->sidedef->rowoffset; + textop = dc_texturemid - viewz + SafeDivScale16 (rowoffset, tex->yScale); + dc_texturemid = MulScale16 (dc_texturemid - viewz, tex->yScale) + rowoffset; } if (fixedlightlev) @@ -1058,7 +1063,11 @@ void R_RenderSegLoop () } if (midtexture->bWorldPanning) { - rw_offset = MulScale16 (xoffset, midtexture->xScale); + rw_offset = MulScale16 (rw_offset_mid, midtexture->xScale); + } + else + { + rw_offset = rw_offset_mid; } if (fixedlightlev || fixedcolormap || !frontsector->ExtraLights) { @@ -1092,7 +1101,11 @@ void R_RenderSegLoop () } if (toptexture->bWorldPanning) { - rw_offset = MulScale16 (xoffset, toptexture->xScale); + rw_offset = MulScale16 (rw_offset_top, toptexture->xScale); + } + else + { + rw_offset = rw_offset_top; } if (fixedlightlev || fixedcolormap || !frontsector->ExtraLights) { @@ -1129,11 +1142,11 @@ void R_RenderSegLoop () } if (bottomtexture->bWorldPanning) { - rw_offset = MulScale16 (xoffset, bottomtexture->xScale); + rw_offset = MulScale16 (rw_offset_bottom, bottomtexture->xScale); } else { - rw_offset = xoffset; + rw_offset = rw_offset_bottom; } if (fixedlightlev || fixedcolormap || !frontsector->ExtraLights) { @@ -1179,8 +1192,9 @@ void R_NewWall (bool needlights) // [RH] Horizon lines do not need to be textured if (linedef->special != Line_Horizon) { - midtexture = TexMan(sidedef->midtexture); - rowoffset = sidedef->rowoffset; + midtexture = TexMan(sidedef->GetTexture(side_t::mid)); + rw_offset_mid = sidedef->GetTextureXOffset(side_t::mid); + rowoffset = sidedef->GetTextureYOffset(side_t::mid); if (linedef->flags & ML_DONTPEGBOTTOM) { // bottom of texture at bottom rw_midtexturemid = frontsector->floortexz + (midtexture->GetHeight() << FRACBITS); @@ -1271,7 +1285,7 @@ void R_NewWall (bool needlights) || (backsector->floor_angle + backsector->base_floor_angle) != (frontsector->floor_angle + frontsector->base_floor_angle) - || (sidedef->midtexture && linedef->flags & (ML_CLIP_MIDTEX|ML_WRAP_MIDTEX)) + || (sidedef->GetTexture(side_t::mid) && linedef->flags & (ML_CLIP_MIDTEX|ML_WRAP_MIDTEX)) ; markceiling = (frontsector->ceilingpic != skyflatnum || @@ -1300,16 +1314,17 @@ void R_NewWall (bool needlights) || (backsector->ceiling_angle + backsector->base_ceiling_angle) != (frontsector->ceiling_angle + frontsector->base_ceiling_angle) - || (sidedef->midtexture && linedef->flags & (ML_CLIP_MIDTEX|ML_WRAP_MIDTEX)) + || (sidedef->GetTexture(side_t::mid) && linedef->flags & (ML_CLIP_MIDTEX|ML_WRAP_MIDTEX)) ); } if (rw_havehigh) { // top texture - toptexture = TexMan(sidedef->toptexture); + toptexture = TexMan(sidedef->GetTexture(side_t::top)); const fixed_t scale = toptexture->yScale; - rowoffset = sidedef->rowoffset; + rw_offset_top = sidedef->GetTextureXOffset(side_t::top); + rowoffset = sidedef->GetTextureYOffset(side_t::top); if (linedef->flags & ML_DONTPEGTOP) { // top of texture at top rw_toptexturemid = MulScale16 (frontsector->ceilingtexz - viewz, scale); @@ -1333,9 +1348,10 @@ void R_NewWall (bool needlights) } if (rw_havelow) { // bottom texture - bottomtexture = TexMan(sidedef->bottomtexture); + bottomtexture = TexMan(sidedef->GetTexture(side_t::bottom)); - rowoffset = sidedef->rowoffset; + rw_offset_bottom = sidedef->GetTextureXOffset(side_t::bottom); + rowoffset = sidedef->GetTextureYOffset(side_t::bottom); if (linedef->flags & ML_DONTPEGBOTTOM) { // bottom of texture at bottom rw_bottomtexturemid = rw_frontlowertop; @@ -1375,12 +1391,14 @@ void R_NewWall (bool needlights) markceiling = false; } - segtextured = TexMan(sidedef->midtexture) != NULL || toptexture != NULL || bottomtexture != NULL; + FTexture *midtex = TexMan(sidedef->GetTexture(side_t::mid)); + + segtextured = midtex != NULL || toptexture != NULL || bottomtexture != NULL; // calculate light table if (needlights && (segtextured || (backsector && IsFogBoundary (frontsector, backsector)))) { - lwallscale = TexMan(sidedef->midtexture) ? TexMan(sidedef->midtexture)->xScale : + lwallscale = midtex ? midtex->xScale : toptexture ? toptexture->xScale : bottomtexture ? bottomtexture->xScale : FRACUNIT; @@ -1402,7 +1420,7 @@ void R_NewWall (bool needlights) } } -int side_s::GetLightLevel (bool foggy, int baselight) const +int side_t::GetLightLevel (bool foggy, int baselight) const { // [RH] Get wall light level if (this->Flags & WALLF_ABSLIGHTING && (!(this->Flags & WALLF_AUTOCONTRAST) || foggy)) @@ -1431,6 +1449,24 @@ int side_s::GetLightLevel (bool foggy, int baselight) const } } +FArchive &operator<< (FArchive &arc, side_t::part &p) +{ + arc << p.xoffset << p.yoffset;// << p.Light; + if (arc.IsStoring()) + { + if (arc.IsStoring ()) + { + TexMan.WriteTexture (arc, p.texture); + } + else + { + p.texture = TexMan.ReadTexture (arc); + } + } + return arc; +} + + // // R_CheckDrawSegs @@ -1491,7 +1527,7 @@ void R_StoreWallRange (int start, int stop) R_NewWall (true); } - rw_offset = sidedef->textureoffset; + rw_offset = sidedef->GetTextureXOffset(side_t::mid); rw_light = rw_lightleft + rw_lightstep * (start - WallSX1); ds_p->sx1 = WallSX1; @@ -1568,9 +1604,9 @@ void R_StoreWallRange (int start, int stop) // allocate space for masked texture tables, if needed // [RH] Don't just allocate the space; fill it in too. - if ((TexMan(sidedef->midtexture)->UseType != FTexture::TEX_Null || IsFogBoundary (frontsector, backsector)) && - (rw_ceilstat != 12 || sidedef->toptexture == 0) && - (rw_floorstat != 3 || sidedef->bottomtexture == 0) && + if ((TexMan(sidedef->GetTexture(side_t::mid))->UseType != FTexture::TEX_Null || IsFogBoundary (frontsector, backsector)) && + (rw_ceilstat != 12 || sidedef->GetTexture(side_t::top) == 0) && + (rw_floorstat != 3 || sidedef->GetTexture(side_t::bottom) == 0) && (WallSZ1 >= TOO_CLOSE_Z && WallSZ2 >= TOO_CLOSE_Z)) { fixed_t *swal; @@ -1580,15 +1616,15 @@ void R_StoreWallRange (int start, int stop) maskedtexture = true; ds_p->bFogBoundary = IsFogBoundary (frontsector, backsector); - if (sidedef->midtexture != 0) + if (sidedef->GetTexture(side_t::mid) != 0) { ds_p->maskedtexturecol = R_NewOpening ((stop - start) * 2); ds_p->swall = R_NewOpening ((stop - start) * 2); lwal = (fixed_t *)(openings + ds_p->maskedtexturecol); swal = (fixed_t *)(openings + ds_p->swall); - int scaley = TexMan(sidedef->midtexture)->yScale; - int xoffset = rw_offset; + int scaley = TexMan(sidedef->GetTexture(side_t::mid))->yScale; + int xoffset = sidedef->GetTextureXOffset(side_t::mid); for (i = start; i < stop; i++) { *lwal++ = lwall[i] + xoffset; @@ -1667,7 +1703,7 @@ void R_StoreWallRange (int start, int stop) memcpy (openings + ds_p->sprbottomclip, &floorclip[start], sizeof(short)*(stop-start)); } - if (maskedtexture && curline->sidedef->midtexture != 0) + if (maskedtexture && curline->sidedef->GetTexture(side_t::mid) != 0) { ds_p->silhouette |= SIL_TOP | SIL_BOTTOM; } diff --git a/src/version.h b/src/version.h index 191aed244d..8bf3edc215 100644 --- a/src/version.h +++ b/src/version.h @@ -75,7 +75,7 @@ // SAVESIG should match SAVEVER. // MINSAVEVER is the minimum level snapshot version that can be loaded. -#define MINSAVEVER 825 +#define MINSAVEVER 832 #if SVN_REVISION_NUMBER < MINSAVEVER // Never write a savegame with a version lower than what we need