1 /*
2 * l_super.h - Superimposed_ld class
3 * AYM 2003-12-02
4 */
5
6 /*
7 This file is copyright Andr� Majorel 2003.
8
9 This program is free software; you can redistribute it and/or modify it under
10 the terms of version 2 of the GNU General Public License as published by the
11 Free Software Foundation.
12
13 This program is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License along with
18 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 Place, Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22
23 #ifndef YH_L_SUPER /* DO NOT INSERT ANYTHING BEFORE THIS LINE */
24 #define YH_L_SUPER
25
26 #include "levels.h"
27 #include "objid.h"
28
29
30 /* The Superimposed_ld class is used to find all the linedefs that are
31 superimposed with a particular reference linedef. Call the set()
32 method to specify the reference linedef. Each call to the get()
33 method returns the number of the next superimposed linedef, or -1
34 when there are no more superimposed linedefs.
35
36 Two linedefs are superimposed iff their ends have the same map
37 coordinates, regardless of whether the vertex numbers are the same,
38 and irrespective of start/end vertex distinctions. */
39
40 class Superimposed_ld
41 {
42 public:
43 Superimposed_ld ();
44 int set (obj_no_t);
45 obj_no_t get ();
46 void rewind ();
47
48 private:
49 obj_no_t refldno; // Reference linedef
50 obj_no_t ldno; // get() will start from there
51 };
52
53
Superimposed_ld()54 inline Superimposed_ld::Superimposed_ld ()
55 {
56 refldno = -1;
57 rewind ();
58 }
59
60
61 /*
62 * Superimposed_ld::set - set the reference linedef
63 *
64 * If the argument is not a valid linedef number, does nothing and
65 * returns a non-zero value. Otherwise, set the linedef number,
66 * calls rewind() and returns a zero value.
67 */
set(obj_no_t ldno)68 inline int Superimposed_ld::set (obj_no_t ldno)
69 {
70 if (! is_linedef (ldno)) // Paranoia
71 return 1;
72
73 refldno = ldno;
74 rewind ();
75 return 0;
76 }
77
78
79 /*
80 * Superimposed_ld::get - return the next superimposed linedef
81 *
82 * Returns the number of the next superimposed linedef, or -1 if
83 * there's none. If the reference linedef was not specified, or is
84 * invalid (possibly as a result of changes in the level), returns
85 * -1.
86 *
87 * Linedefs that have invalid start/end vertices are silently
88 * skipped.
89 */
get()90 inline obj_no_t Superimposed_ld::get ()
91 {
92 if (refldno == -1)
93 return -1;
94
95 /* These variables are there to speed things up a bit by avoiding
96 repetitive table lookups. Everything is re-computed each time as
97 LineDefs could very well be realloc'd while we were out. */
98
99 if (! is_linedef (refldno))
100 return -1;
101 const struct LineDef *const pmax = LineDefs + NumLineDefs;
102 const struct LineDef *const pref = LineDefs + refldno;
103
104 const wad_vn_t refv0 = pref->start;
105 const wad_vn_t refv1 = pref->end;
106 if (! is_vertex (refv0) || ! is_vertex (refv1)) // Paranoia
107 return -1;
108
109 const wad_coord_t refx0 = Vertices[refv0].x;
110 const wad_coord_t refy0 = Vertices[refv0].y;
111 const wad_coord_t refx1 = Vertices[refv1].x;
112 const wad_coord_t refy1 = Vertices[refv1].y;
113
114 for (const struct LineDef *p = LineDefs + ldno; ldno < NumLineDefs;
115 p++, ldno++)
116 {
117 if (! is_vertex (p->start) || ! is_vertex (p->end)) // Paranoia
118 continue;
119 obj_no_t x0 = Vertices[p->start].x;
120 obj_no_t y0 = Vertices[p->start].y;
121 obj_no_t x1 = Vertices[p->end].x;
122 obj_no_t y1 = Vertices[p->end].y;
123 if ( x0 == refx0 && y0 == refy0 && x1 == refx1 && y1 == refy1
124 || x0 == refx1 && y0 == refy1 && x1 == refx0 && y1 == refy0)
125 {
126 if (ldno == refldno)
127 continue;
128 return ldno++;
129 }
130 }
131
132 return -1;
133 }
134
135
136 /*
137 * Superimposed_ld::rewind - rewind the counter
138 *
139 * After calling this method, the next call to get() will start
140 * from the first linedef.
141 */
rewind()142 inline void Superimposed_ld::rewind ()
143 {
144 ldno = 0;
145 }
146
147
148 #endif /* DO NOT ADD ANYTHING AFTER THIS LINE */
149