From 4ddffd233a9c38fd15834ded889c66ddb6ad4ce1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 29 Oct 2023 16:07:27 +0100 Subject: [PATCH] added UDMF wall scrolling properties from DSDA. --- specs/udmf_zdoom.txt | 10 ++++++ src/maploader/maploader.h | 2 +- src/maploader/specials.cpp | 11 +++--- src/maploader/udmf.cpp | 74 ++++++++++++++++++++++++++++++++------ 4 files changed, 80 insertions(+), 17 deletions(-) diff --git a/specs/udmf_zdoom.txt b/specs/udmf_zdoom.txt index 5a141e7205..3a9a078bd0 100644 --- a/specs/udmf_zdoom.txt +++ b/specs/udmf_zdoom.txt @@ -238,6 +238,16 @@ Note: All fields default to false unless mentioned otherwise. skew_middle = ; // Vertical texture alignment defines the position at the leftmost point of the wall. skew_bottom = ; // Possible values: 0 = no skewing, 1 = align to front floor, 2 = align to front ceiling, 3 = align to back floor, 4 = align to back ceiling. // Front/Back are relative to the sidedef, not the owning linedef. Default = 0. + + xscroll = ; // wall scrolling X speed in map units per tic. + yscroll = ; // wall scrolling Y speed in map units per tic. + xscrolltop = ; // upper wall scrolling X speed in map units per tic. + yscrolltop = ; // upper wall scrolling Y speed in map units per tic. + xscrollmid = ; // mid wall scrolling X speed in map units per tic. + yscrollmid = ; // mid wall scrolling Y speed in map units per tic. + xscrollbottom = ; // lower wall scrolling X speed in map units per tic. + yscrollbottom = ; // lower wall scrolling Y speed in map units per tic. + } diff --git a/src/maploader/maploader.h b/src/maploader/maploader.h index 675311d0ed..432d75197d 100644 --- a/src/maploader/maploader.h +++ b/src/maploader/maploader.h @@ -194,7 +194,7 @@ private: void SpawnSpecials(); void InitSectorSpecial(sector_t *sector, int special); void SpawnLights(sector_t *sector); - void CreateScroller(EScroll type, double dx, double dy, sector_t *affectee, int accel, EScrollPos scrollpos = EScrollPos::scw_all, int scrollmode = 15/*SCROLL_All*/); + void CreateScroller(EScroll type, double dx, double dy, sector_t *sect, side_t* side, int accel, EScrollPos scrollpos = EScrollPos::scw_all, int scrollmode = 15/*SCROLL_All*/); void SpawnScrollers(); void SpawnFriction(); void SpawnPushers(); diff --git a/src/maploader/specials.cpp b/src/maploader/specials.cpp index 8a38f3e7ca..0c07539eed 100644 --- a/src/maploader/specials.cpp +++ b/src/maploader/specials.cpp @@ -574,7 +574,7 @@ void MapLoader::InitSectorSpecial(sector_t *sector, int special) case dScroll_EastLavaDamage: SetupSectorDamage(sector, 5, 16, 256, NAME_Fire, SECF_DMGTERRAINFX); - CreateScroller(EScroll::sc_floor, -4., 0, sector, 0); + CreateScroller(EScroll::sc_floor, -4., 0, sector, nullptr, 0); keepspecial = true; break; @@ -631,13 +631,13 @@ void MapLoader::InitSectorSpecial(sector_t *sector, int special) int i = sector->special - Scroll_North_Slow; double dx = hexenScrollies[i][0] / 2.; double dy = hexenScrollies[i][1] / 2.; - CreateScroller(EScroll::sc_floor, dx, dy, sector, 0); + CreateScroller(EScroll::sc_floor, dx, dy, sector, nullptr, 0); } else if (sector->special >= Carry_East5 && sector->special <= Carry_East35) { // Heretic scroll special // Only east scrollers also scroll the texture - CreateScroller(EScroll::sc_floor, -0.5 * (1 << ((sector->special & 0xff) - Carry_East5)), 0, sector, 0); + CreateScroller(EScroll::sc_floor, -0.5 * (1 << ((sector->special & 0xff) - Carry_East5)), 0, sector, nullptr, 0); } keepspecial = true; break; @@ -1466,7 +1466,8 @@ void MapLoader::SpawnScrollers() } -void MapLoader::CreateScroller(EScroll type, double dx, double dy, sector_t *affectee, int accel, EScrollPos scrollpos, int scrollmode) +void MapLoader::CreateScroller(EScroll type, double dx, double dy, sector_t *sect, side_t* side, int accel, EScrollPos scrollpos, int scrollmode) { - Level->CreateThinker(type, dx, dy, nullptr, affectee, nullptr, accel, scrollpos, scrollmode); + Level->CreateThinker(type, dx, dy, nullptr, sect, side, accel, scrollpos, scrollmode); } + diff --git a/src/maploader/udmf.cpp b/src/maploader/udmf.cpp index a25bf88fd4..b6509875e8 100644 --- a/src/maploader/udmf.cpp +++ b/src/maploader/udmf.cpp @@ -429,7 +429,7 @@ FString GetUDMFString(FLevelLocals *Level, int type, int index, FName key) struct UDMFScroll { - bool ceiling; + int where; int index; double x, y; int scrolltype; @@ -448,7 +448,8 @@ class UDMFParser : public UDMFParserBase TArray ParsedSideTextures; TArray ParsedSectors; TArray ParsedVertices; - TArray UDMFScrollers; + TArray UDMFSectorScrollers; + TArray UDMFWallScrollers; FDynamicColormap *fogMap = nullptr, *normMap = nullptr; FMissingTextureTracker &missingTex; @@ -1245,6 +1246,7 @@ public: void ParseSidedef(side_t *sd, intmapsidedef_t *sdt, int index) { double texOfs[2]={0,0}; + DVector2 scrolls[4] = {}; memset(sd, 0, sizeof(*sd)); sdt->bottomtexture = "-"; @@ -1551,6 +1553,30 @@ public: sd->textures[side_t::bottom].skew = CheckInt(key); break; + case NAME_xscroll: + scrolls[0].X = CheckFloat(key); + break; + case NAME_yscroll: + scrolls[0].Y = CheckFloat(key); + break; + case NAME_xscrolltop: + scrolls[1].X = CheckFloat(key); + break; + case NAME_yscrolltop: + scrolls[1].Y = CheckFloat(key); + break; + case NAME_xscrollmid: + scrolls[2].X = CheckFloat(key); + break; + case NAME_yscrollmid: + scrolls[2].Y = CheckFloat(key); + break; + case NAME_xscrollbottom: + scrolls[3].X = CheckFloat(key); + break; + case NAME_yscrollbottom: + scrolls[3].Y = CheckFloat(key); + break; default: if (strnicmp("user_", key.GetChars(), 5)) DPrintf(DMSG_WARNING, "Unknown UDMF sidedef key %s\n", key.GetChars()); @@ -1569,6 +1595,21 @@ public: sd->AddTextureYOffset(side_t::top, texOfs[1]); sd->AddTextureYOffset(side_t::mid, texOfs[1]); sd->AddTextureYOffset(side_t::bottom, texOfs[1]); + int scroll = scw_all; + for (int i = 1; i < 4; i++) + { + auto& scrl = scrolls[i]; + if (!scrl.isZero()) + { + int where = 1 << (i - 1); + scroll &= ~where; + UDMFWallScrollers.Push({ where, index, scrl.X, scrl.Y, 0 }); + } + } + if (!scrolls[0].isZero() && scroll) + { + UDMFWallScrollers.Push({ scroll, index, scrolls[0].X, scrolls[0].Y, 0}); + } } //=========================================================================== @@ -2137,11 +2178,11 @@ public: // Cannot be initialized yet because they need the final sector array. if (scroll_ceil_type != NAME_None) { - UDMFScrollers.Push({ true, index, scroll_ceil_x, scroll_ceil_y, scroll_ceil_type }); + UDMFSectorScrollers.Push({ true, index, scroll_ceil_x, scroll_ceil_y, scroll_ceil_type }); } if (scroll_floor_type != NAME_None) { - UDMFScrollers.Push({ false, index, scroll_floor_x, scroll_floor_y, scroll_floor_type }); + UDMFSectorScrollers.Push({ false, index, scroll_floor_x, scroll_floor_y, scroll_floor_type }); } @@ -2246,7 +2287,7 @@ public: // //=========================================================================== - void ProcessLineDefs() + void ProcessLineDefs(TArray>& siderefs) { int sidecount = 0; for(unsigned i = 0, skipped = 0; i < ParsedLines.Size();) @@ -2281,6 +2322,7 @@ public: } } unsigned numlines = ParsedLines.Size(); + siderefs.Resize(ParsedSides.Size()); Level->sides.Alloc(sidecount); Level->lines.Alloc(numlines); int line, side; @@ -2300,6 +2342,7 @@ public: int mapside = int(intptr_t(lines[line].sidedef[sd]))-1; if (mapside < sidecount) { + siderefs[mapside].Push(side); sides[side] = ParsedSides[mapside]; sides[side].linedef = &lines[line]; sides[side].sector = &Level->sectors[intptr_t(sides[side].sector)]; @@ -2506,21 +2549,30 @@ public: { Level->sectors[i].e = &Level->extsectors[i]; } + + // Create the real linedefs and decompress the sidedefs. Must be done before + TArray> siderefs; + ProcessLineDefs(siderefs); + // Now create the scrollers. - for (auto &scroll : UDMFScrollers) + for (auto &scroll : UDMFSectorScrollers) { if (scroll.scrolltype & SCROLL_Textures) { - loader->CreateScroller(scroll.ceiling ? EScroll::sc_ceiling : EScroll::sc_floor, -scroll.x, scroll.y, &Level->sectors[scroll.index], 0); + loader->CreateScroller(scroll.where == 1 ? EScroll::sc_ceiling : EScroll::sc_floor, -scroll.x, scroll.y, &Level->sectors[scroll.index], nullptr, 0); } if (scroll.scrolltype & (SCROLL_StaticObjects | SCROLL_Players | SCROLL_Monsters)) { - loader->CreateScroller(scroll.ceiling ? EScroll::sc_carry_ceiling : EScroll::sc_carry, scroll.x, scroll.y, &Level->sectors[scroll.index], 0, scw_all, scroll.scrolltype); + loader->CreateScroller(scroll.where == 1 ? EScroll::sc_carry_ceiling : EScroll::sc_carry, scroll.x, scroll.y, &Level->sectors[scroll.index], nullptr, 0, scw_all, scroll.scrolltype); + } + } + for (auto& scroll : UDMFWallScrollers) + { + for(auto sd : siderefs[scroll.index]) + { + loader->CreateScroller(EScroll::sc_side, scroll.x, scroll.y, nullptr, &Level->sides[sd], 0); } } - - // Create the real linedefs and decompress the sidedefs - ProcessLineDefs(); } };