Re: Sort of a not really a potential bug report. -ish.

  • From: Andre Majorel <amajorel@xxxxxxxxx>
  • To: yadex@xxxxxxxxxxxxx
  • Date: Wed, 3 Dec 2003 21:40:57 +0100

On 2003-11-20 02:10 +0100, ras2 wrote:

> hm. This info is quite a bit more useful than the default, but like you
> said, you wouldn't know that you had a need for it because you couldn't
> see that there was a problem.

Enclosed is a patch against 1.6.0. With it, when you highlight a
linedef that has superimposed linedefs, you get a fourth object
info box with a list of superimposed linedefs.

Ideally, I'd like to make superimposed linedefs more visible,
for example by drawing them in red as is done for linedefs that
have no first sidedef. But doing it right is a lot more work, so
this will have to do for the time being.

Andrew's suggestion (putting it in the level checks) is less
work but going the full mile, i.e. creating a framework for
caching level-dependent computations, is tempting. In the long
term, it would open the door to a bunch of features, such as
correctly placed sector numbers and higher-level checks.

Combined with the highlight-highest-numbered patch, I think it's
an improvement over the current situation. If you all like them,
they go into the next release.

> Is there a use for such doubled linedefs? bsp 5.1 doesn't seem to remove
> them, but I don't know if that means anything.

For double-sided linedefs, it's the standard way to get more
than 128 pixels' worth of semi-transparent texture. For
single-sided linedefs, I don't see what it could do, other than
very weird special effects. Colin and Andrew surely know, but
they're not telling.

> I may just be unlucky, but I'm seeing many more cases where a linedef
> far from the area I'm working on suddenly disappears (for example,
> there was a linedef that ran parallel with linedef 1058, with about 4
> units between them, and that disappeared when I rearranged the
> linedefs near 1051).  It's a bit risky because it often happens on
> linedefs that are out of sight, so it can take quite a while before
> you notice it.

Hmm. That doesn't smell good. If you can reproduce it, I'd be
interested in having the recipe.

-- 
André Majorel <amajorel@xxxxxxxxx>
http://www.teaser.fr/~amajorel/
The linedef object info box now lists any superimposed linedefs (up to
seven). No such feature for vertices, sectors and things, mainly because
it doesn't seem to be as big an issue and I'm lazy.

-- AYM 2003-12-03

diff -uaNr yadex-1.6.0/src/l_super.h yadex-1.6.90/src/l_super.h
--- yadex-1.6.0/src/l_super.h   1970-01-01 01:00:00.000000000 +0100
+++ yadex-1.6.0-superimposed/src/l_super.h      2003-12-02 18:42:48.000000000 
+0100
@@ -0,0 +1,148 @@
+/*
+ *     l_super.h - Superimposed_ld class
+ *     AYM 2003-12-02
+ */
+
+/*
+This file is copyright André Majorel 2003.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of version 2 of the GNU General Public License as published by the
+Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+Place, Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef YH_L_SUPER  /* DO NOT INSERT ANYTHING BEFORE THIS LINE */
+#define YH_L_SUPER
+
+#include "levels.h"
+#include "objid.h"
+
+
+/* The Superimposed_ld class is used to find all the linedefs that are
+   superimposed with a particular reference linedef. Call the set()
+   method to specify the reference linedef. Each call to the get()
+   method returns the number of the next superimposed linedef, or -1
+   when there are no more superimposed linedefs.
+
+   Two linedefs are superimposed iff their ends have the same map
+   coordinates, regardless of whether the vertex numbers are the same,
+   and irrespective of start/end vertex distinctions. */
+
+class Superimposed_ld
+{
+  public:
+             Superimposed_ld ();
+    int      set             (obj_no_t);
+    obj_no_t get             ();
+    void     rewind          ();
+
+  private:
+    obj_no_t refldno;                  // Reference linedef
+    obj_no_t ldno;                     // get() will start from there
+};
+
+
+inline Superimposed_ld::Superimposed_ld ()
+{
+  refldno = -1;
+  rewind ();
+}
+
+
+/*
+ *     Superimposed_ld::set - set the reference linedef
+ *
+ *     If the argument is not a valid linedef number, does nothing and
+ *     returns a non-zero value. Otherwise, set the linedef number,
+ *     calls rewind() and returns a zero value.
+ */
+inline int Superimposed_ld::set (obj_no_t ldno)
+{
+  if (! is_linedef (ldno))             // Paranoia
+    return 1;
+
+  refldno = ldno;
+  rewind ();
+  return 0;
+}
+
+
+/*
+ *     Superimposed_ld::get - return the next superimposed linedef
+ *
+ *     Returns the number of the next superimposed linedef, or -1 if
+ *     there's none. If the reference linedef was not specified, or is
+ *     invalid (possibly as a result of changes in the level), returns
+ *     -1.
+ *
+ *     Linedefs that have invalid start/end vertices are silently
+ *     skipped.
+ */
+inline obj_no_t Superimposed_ld::get ()
+{
+  if (refldno == -1)
+    return -1;
+
+  /* These variables are there to speed things up a bit by avoiding
+     repetitive table lookups. Everything is re-computed each time as
+     LineDefs could very well be realloc'd while we were out. */
+
+  if (refldno < 0 || refldno >= NumLineDefs)
+    return -1;
+  const struct LineDef *const pmax = LineDefs + NumLineDefs;
+  const struct LineDef *const pref = LineDefs + refldno;
+
+  const wad_vn_t refv0 = pref->start;
+  const wad_vn_t refv1 = pref->end;
+  if (! is_vertex (refv0) || ! is_vertex (refv1))              // Paranoia
+    return -1;
+
+  const wad_coord_t refx0 = Vertices[refv0].x;
+  const wad_coord_t refy0 = Vertices[refv0].y;
+  const wad_coord_t refx1 = Vertices[refv1].x;
+  const wad_coord_t refy1 = Vertices[refv1].y;
+
+  for (const struct LineDef *p = LineDefs + ldno; ldno < NumLineDefs;
+      p++, ldno++)
+  {
+    if (! is_vertex (p->start) || ! is_vertex (p->end))                // 
Paranoia
+      continue;
+    obj_no_t x0 = Vertices[p->start].x;
+    obj_no_t y0 = Vertices[p->start].y;
+    obj_no_t x1 = Vertices[p->end].x;
+    obj_no_t y1 = Vertices[p->end].y;
+    if ( x0 == refx0 && y0 == refy0 && x1 == refx1 && y1 == refy1
+      || x0 == refx1 && y0 == refy1 && x1 == refx0 && y1 == refy0)
+    {
+      if (ldno == refldno)
+       continue;
+      return ldno++;
+    }
+  }
+
+  return -1;
+}
+
+
+/*
+ *     Superimposed_ld::rewind - rewind the counter
+ *
+ *     After calling this method, the next call to get() will start
+ *     from the first linedef.
+ */
+inline void Superimposed_ld::rewind ()
+{
+  ldno = 0;
+}
+
+
+#endif  /* DO NOT ADD ANYTHING AFTER THIS LINE */
--- yadex-1.6.0/src/objinfo.cc  2003-03-28 13:37:32.000000000 +0100
+++ yadex-1.6.0-superimposed/src/objinfo.cc     2003-12-03 15:33:23.000000000 
+0100
@@ -37,8 +37,9 @@
 #include "gamesky.h"   // is_sky()
 #include "gfx.h"
 #include "img.h"
 #include "imgspect.h"
+#include "l_super.h"
 #include "levels.h"
 #include "objid.h"
 #include "objinfo.h"
 #include "pic2img.h"
@@ -233,8 +234,9 @@
     }
     break;
 
     case OBJ_LINEDEFS:
+      // Linedef
       width  = 2 * BOX_BORDER + 2 * WIDE_HSPACING + 29 * FONTW;
       height = 2 * BOX_BORDER + 2 * WIDE_VSPACING + (int) (8.5 * FONTH);
       x0 = 0;
       y0 = out_y1 - height + 1;
@@ -306,8 +308,9 @@
        DrawScreenText (x0 + (width - FONTW * strlen (message)) / 2,
          y0 + (height - FONTH) / 2, message);
       }
 
+      // 1st sidedef
       x0 += width;
       width  = 2 * BOX_BORDER + 2 * WIDE_HSPACING + 16 * FONTW;
       ix0 = x0 + BOX_BORDER + WIDE_HSPACING;
       y0 = out_y1 - height + 1;
@@ -363,8 +366,10 @@
        set_colour (CLR_ERROR);
        DrawScreenText (x0 + (width - FONTW * strlen (message)) / 2,
          y0 + (height - FONTH) / 2, message);
       }
+
+      // 2nd sidedef
       x0 += width;
       ix0 = x0 + BOX_BORDER + WIDE_HSPACING;
       y0 = out_y1 - height + 1;
       // Ignore box_disp -- always redraw the whole box
@@ -423,8 +428,52 @@
          set_colour (WINFG_DIM);
        DrawScreenText (x0 + (width - FONTW * strlen (message)) / 2,
          y0 + (height - FONTH) / 2, message);
       }
+
+      // Superimposed linedefs
+      {
+       Superimposed_ld super;
+       super.set (obj_no);
+       obj_no_t l = super.get ();
+       int iy1;
+
+       if (l != -1 || box_disp[3])
+       {
+         x0 += width;
+         width  = 2 * BOX_BORDER + 2 * WIDE_HSPACING + 12 * FONTW;
+         ix0 = x0 + BOX_BORDER + WIDE_HSPACING;
+         iy0 = y0 + BOX_BORDER + WIDE_VSPACING;
+         iy1 = y0 + height - 1 - BOX_BORDER - WIDE_VSPACING;
+         DrawScreenBox3D (x0, y0, x0 + width - 1, y0 + height - 1);
+       }
+       if (l != -1)
+       {
+         box_disp[3] = true;
+         set_colour (YELLOW);
+         DrawScreenString (ix0, iy0, "Superimposed");
+         set_colour (WINFG);
+         iy0 += int (1.5 * FONTH);
+         while (l != -1)
+         {
+           if (iy0 + FONTH - 1 <= iy1)
+             DrawScreenText (ix0, iy0, "#%d", l);
+           /* Too many linedefs, replace the last one by "(more)".
+              Not elegant, but it makes the code simpler. */
+           else
+           {
+             iy0 -= FONTH;
+             set_colour (WINBG);
+             DrawScreenBox (ix0, iy0, ix0 + 12 * FONTW - 1, iy0 + FONTH - 1);
+             set_colour (WINFG);
+             DrawScreenString (ix0, iy0, "(more)");
+             break;
+           }
+           iy0 += FONTH;
+           l = super.get ();
+         }
+       }
+      }
       break;
 
     case OBJ_VERTICES:
       width  = 2 * BOX_BORDER + 2 * WIDE_HSPACING + 29 * FONTW;

Other related posts: