1 /*
2 * objinfo.cc
3 * AYM 1998-09-20
4 */
5
6
7 /*
8 This file is part of Yadex.
9
10 Yadex incorporates code from DEU 5.21 that was put in the public domain in
11 1994 by Rapha�l Quinet and Brendon Wyber.
12
13 The rest of Yadex is Copyright � 1997-2003 Andr� Majorel and others.
14
15 This program is free software; you can redistribute it and/or modify it under
16 the terms of the GNU General Public License as published by the Free Software
17 Foundation; either version 2 of the License, or (at your option) any later
18 version.
19
20 This program is distributed in the hope that it will be useful, but WITHOUT
21 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
22 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License along with
25 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
26 Place, Suite 330, Boston, MA 02111-1307, USA.
27 */
28
29
30 #include "yadex.h"
31 #include <vector>
32 #include <algorithm>
33 #include <X11/Xlib.h>
34 #include "disppic.h"
35 #include "flats.h" // DisplayFloorTexture()
36 #include "game.h" // THINGDEF_SPECTRAL
37 #include "gamesky.h" // is_sky()
38 #include "gfx.h"
39 #include "img.h"
40 #include "imgspect.h"
41 #include "l_super.h"
42 #include "levels.h"
43 #include "objid.h"
44 #include "objinfo.h"
45 #include "pic2img.h"
46 #include "sticker.h"
47 #include "things.h"
48 #include "wadres.h"
49
50
51 static const int sprite_width = 90;
52 static const int sprite_height = 90;
53
54
55 /*
56 * Extraf - one item in the list of EDGE extrafloors
57 */
58 class Extraf
59 {
60 public :
Extraf(obj_no_t sector,wad_name_t & tex,wad_z_t height)61 Extraf (obj_no_t sector, wad_name_t& tex, wad_z_t height)
62 {
63 this->sector = sector;
64 memcpy (this->tex, &tex, sizeof this->tex);
65 this->height = height;
66 }
67
operator <(const Extraf & other) const68 bool operator< (const Extraf& other) const
69 {
70 if (height < other.height)
71 return true;
72 else if (height == other.height && sector < other.sector)
73 return true;
74 return false;
75 }
76
77 wad_z_t height; // To sort by increasing floor height
78 obj_no_t sector; // Sector# (for heights, flats and light level)
79 wad_tex_name_t tex; // Texture (middle tex of first sidedef)
80 };
81
82
83 static void get_extrafloors (std::vector<Extraf>& list, wad_tag_t tag);
84
85
objinfo_c()86 objinfo_c::objinfo_c ()
87 {
88 for (size_t n = 0; n < MAX_BOXES; n++)
89 box_disp[n] = false;
90 obj_no = OBJ_NO_NONE;
91 obj_no_disp = OBJ_NO_NONE;
92 prev_sector = OBJ_NO_NONE;
93 out_y1 = 0;
94 }
95
96
draw()97 void objinfo_c::draw ()
98 {
99 int n;
100 int sd1 = OBJ_NO_NONE;
101 int sd2 = OBJ_NO_NONE;
102 int s1 = OBJ_NO_NONE;
103 int s2 = OBJ_NO_NONE;
104 int x0, y0; // Outer top left corner
105 int ix0, iy0; // Inner top left corner
106 int width;
107 int height;
108
109 // Am I already drawn ?
110 if (! is_obj (obj_no) || obj_no == obj_no_disp && obj_type == obj_type_disp)
111 return;
112
113 // Does the box need to be redrawn ?
114 if (obj_type != obj_type_disp)
115 box_disp[0] = false;
116
117 // The caller should have called set_y1() before !
118 if (! out_y1)
119 return;
120
121 ObjectsNeeded (obj_type, 0);
122 switch (obj_type)
123 {
124 case OBJ_THINGS:
125 {
126 const int columns = 27;
127 width = 2 * BOX_BORDER + 3 * WIDE_HSPACING + columns * FONTW
128 + 2 * HOLLOW_BORDER + sprite_width;
129 height = 2 * BOX_BORDER + 2 * WIDE_VSPACING
130 + y_max ((int) (6.5 * FONTH), sprite_height);
131 x0 = 0;
132 y0 = out_y1 - height + 1;
133 ix0 = x0 + BOX_BORDER + WIDE_HSPACING;
134 iy0 = y0 + BOX_BORDER + WIDE_VSPACING;
135 int ix1 = x0 + width - 1 - BOX_BORDER - WIDE_HSPACING;
136 int iy1 = y0 + height - 1 - BOX_BORDER - WIDE_VSPACING;
137 if (box_disp[0])
138 {
139 push_colour (WINBG);
140 DrawScreenBox (ix0, iy0, ix0 + columns * FONTW - 1, iy1);
141 pop_colour ();
142 }
143 else
144 DrawScreenBox3D (x0, y0, x0 + width - 1, y0 + height - 1);
145 if (obj_no < 0)
146 {
147 const char *message = "(no thing selected)";
148 set_colour (WINFG_DIM);
149 DrawScreenText (x0 + (width - FONTW * strlen (message)) / 2,
150 y0 + (height - FONTH) / 2, message);
151 break;
152 }
153 set_colour (WINTITLE);
154 DrawScreenText (ix0, iy0, "Thing #%d", obj_no);
155 const bool invalid_type = ! is_thing_type (Things[obj_no].type);
156 set_colour (WINFG);
157 DrawScreenText (-1, iy0 + (int) (1.5 * FONTH), 0);
158 DrawScreenText (-1, -1, "\1Coords:\2 (%d, %d)",
159 Things[obj_no].xpos, Things[obj_no].ypos);
160 DrawScreenString (-1, -1, "\1Type: ");
161 if (invalid_type)
162 push_colour (CLR_ERROR);
163 DrawScreenText (-2, -2, "%d", Things[obj_no].type);
164 if (invalid_type)
165 pop_colour ();
166 DrawScreenString (-1, -1, "\1Desc: ");
167 if (invalid_type)
168 push_colour (CLR_ERROR);
169 DrawScreenText (-2, -2, "%.19s", get_thing_name (Things[obj_no].type));
170 if (invalid_type)
171 pop_colour ();
172 DrawScreenText (-1, -1, "\1Angle:\2 %s",
173 GetAngleName (Things[obj_no].angle));
174 DrawScreenText (-1, -1, "\1Flags:\2 %s",
175 GetWhenName (Things[obj_no].when));
176
177 // Show the corresponding sprite
178 {
179 int sx1 = ix1 + 1 - HOLLOW_BORDER;
180 int sy1 = iy1 + 1 - HOLLOW_BORDER;
181 int sx0 = sx1 + 1 - sprite_width;
182 int sy0 = sy1 + 1 - sprite_height;
183 draw_box_border (sx0 - HOLLOW_BORDER, sy0 - HOLLOW_BORDER,
184 sprite_width + 2 * HOLLOW_BORDER,
185 sprite_height + 2 * HOLLOW_BORDER,
186 HOLLOW_BORDER, 0);
187 const char *sprite_root = get_thing_sprite (Things[obj_no].type);
188 char flags = get_thing_flags (Things[obj_no].type);
189 if (sprite_root == NULL)
190 {
191 push_colour (WINBG);
192 DrawScreenBox (sx0, sy0, sx1, sy1);
193 pop_colour ();
194 set_colour (WINFG_DIM);
195 DrawScreenText (
196 sx0 + (sprite_width - 2 * FONTW) / 2,
197 sy0 + sprite_height / 2 + 1 - FONTH, "no");
198 DrawScreenText (
199 sx0 + (sprite_width - 6 * FONTW) / 2,
200 sy0 + sprite_height / 2 + 1, "sprite");
201 }
202 else
203 {
204 Lump_loc loc;
205 Img img (sprite_width, sprite_height, false);
206 Sticker sticker;
207 wad_res.sprites.loc_by_root (sprite_root, loc);
208 if (loc.wad == 0
209 || LoadPicture (img, sprite_root, loc, INT_MIN, INT_MIN))
210 {
211 push_colour (WINBG);
212 DrawScreenBox (sx0, sy0, sx1, sy1);
213 pop_colour ();
214 set_colour (CLR_ERROR);
215 DrawScreenString (
216 sx0 + (sprite_width - strlen (sprite_root) * FONTW) / 2,
217 sy0 + sprite_height / 2 + 1 - 3 * FONTH / 2, sprite_root);
218 DrawScreenText (
219 sx0 + (sprite_width - 3 * FONTW) / 2,
220 sy0 + sprite_height / 2 + 1 - FONTH / 2, "not");
221 DrawScreenText (
222 sx0 + (sprite_width - 5 * FONTW) / 2,
223 sy0 + sprite_height / 2 + 1 + FONTH / 2, "found");
224 }
225 else
226 {
227 if (flags & THINGDEF_SPECTRAL)
228 spectrify_img (img);
229 sticker.load (img, true);
230 sticker.draw (drw, 't', sx0, sy0);
231 }
232 }
233 }
234 }
235 break;
236
237 case OBJ_LINEDEFS:
238 // Linedef
239 width = 2 * BOX_BORDER + 2 * WIDE_HSPACING + 29 * FONTW;
240 height = 2 * BOX_BORDER + 2 * WIDE_VSPACING + (int) (8.5 * FONTH);
241 x0 = 0;
242 y0 = out_y1 - height + 1;
243 ix0 = x0 + BOX_BORDER + WIDE_HSPACING;
244 iy0 = y0 + BOX_BORDER + WIDE_VSPACING;
245 // Ignore box_disp -- always redraw the whole box
246 DrawScreenBox3D (x0, y0, x0 + width - 1, y0 + height - 1);
247 if (obj_no >= 0)
248 {
249 set_colour (WINTITLE);
250 DrawScreenText (ix0, iy0, "Linedef #%d", obj_no);
251 set_colour (WINFG);
252 DrawScreenText (-1, iy0 + (int) (1.5 * FONTH),
253 "\1Flags:\2 %.19s",
254 GetLineDefFlagsName (LineDefs[obj_no].flags));
255 DrawScreenText (-1, -1, "\1Type:\2 %3d %.19s",
256 LineDefs[obj_no].type,
257 GetLineDefTypeName (LineDefs[obj_no].type));
258 ObjectsNeeded (OBJ_SIDEDEFS, OBJ_SECTORS, 0);
259 {
260 int tag = LineDefs[obj_no].tag;
261 int first_sector = NumSectors;
262 int second_sector = NumSectors;
263 if (tag != 0)
264 {
265 for (int n = 0; n < NumSectors; n++)
266 if (Sectors[n].tag == tag)
267 {
268 if (first_sector >= NumSectors)
269 first_sector = n;
270 else
271 {
272 second_sector = n;
273 break;
274 }
275 }
276 }
277 if (first_sector < NumSectors && second_sector < NumSectors)
278 DrawScreenText (-1, -1, "\1Tag:\2 %d (#%d+)", tag, first_sector);
279 else if (first_sector < NumSectors)
280 DrawScreenText (-1, -1, "\1Tag:\2 %d (#%d)", tag, first_sector);
281 else
282 DrawScreenText (-1, -1, "\1Tag:\2 %d (none)", tag);
283 }
284 s1 = LineDefs[obj_no].start;
285 s2 = LineDefs[obj_no].end;
286 DrawScreenText (-1, -1, "\1Vertices:\2 (#%d, #%d)", s1, s2);
287 ObjectsNeeded (OBJ_VERTICES, 0);
288 n = ComputeDist (Vertices[s2].x - Vertices[s1].x,
289 Vertices[s2].y - Vertices[s1].y);
290 DrawScreenText (-1, -1, "\1Length:\2 %d", n);
291 sd1 = LineDefs[obj_no].sidedef1;
292 sd2 = LineDefs[obj_no].sidedef2;
293 DrawScreenText (-1, -1, "\1" "1st sd:\2 #%d", sd1);
294 DrawScreenText (-1, -1, "\1" "2nd sd:\2 #%d", sd2);
295 if (sd1 >= 0)
296 s1 = SideDefs[sd1].sector;
297 else
298 s1 = -1;
299 if (sd2 >= 0)
300 s2 = SideDefs[sd2].sector;
301 else
302 s2 = -1;
303 }
304 else
305 {
306 const char *message = "(no linedef selected)";
307 set_colour (WINFG_DIM);
308 DrawScreenText (x0 + (width - FONTW * strlen (message)) / 2,
309 y0 + (height - FONTH) / 2, message);
310 }
311
312 // 1st sidedef
313 x0 += width;
314 width = 2 * BOX_BORDER + 2 * WIDE_HSPACING + 16 * FONTW;
315 ix0 = x0 + BOX_BORDER + WIDE_HSPACING;
316 y0 = out_y1 - height + 1;
317 // Ignore box_disp -- always redraw the whole box
318 DrawScreenBox3D (x0, y0, x0 + width - 1, y0 + height - 1);
319 if (obj_no >= 0 && sd1 >= 0)
320 {
321 set_colour (WINTITLE);
322 DrawScreenText (ix0, iy0, "Sidedef1 #%d", sd1);
323
324 if (s1 >= 0 && s2 >= 0 && Sectors[s1].ceilh > Sectors[s2].ceilh
325 && ! (is_sky (Sectors[s1].ceilt) && is_sky (Sectors[s2].ceilt)))
326 {
327 if (SideDefs[sd1].tex1[0] == '-' && SideDefs[sd1].tex1[1] == '\0')
328 set_colour (CLR_ERROR);
329 else
330 set_colour (WINFG);
331 }
332 else
333 set_colour (WINFG_DIM);
334 DrawScreenText (-1, iy0 + (int) (1.5 * FONTH), "\1Upper:\2 %.*s",
335 WAD_TEX_NAME, SideDefs[sd1].tex1);
336
337 if (sd2 < 0
338 && SideDefs[sd1].tex3[0] == '-' && SideDefs[sd1].tex3[1] == '\0')
339 set_colour (CLR_ERROR);
340 else
341 set_colour (WINFG);
342 DrawScreenText (-1, -1,
343 "\1Middle:\2 %.*s", WAD_TEX_NAME, SideDefs[sd1].tex3);
344
345 if (s1 >= 0 && s2 >= 0 && Sectors[s1].floorh < Sectors[s2].floorh
346 && ! (is_sky (Sectors[s1].floort) && is_sky (Sectors[s2].floort)))
347 {
348 if (SideDefs[sd1].tex2[0] == '-' && SideDefs[sd1].tex2[1] == '\0')
349 set_colour (CLR_ERROR);
350 else
351 set_colour (WINFG);
352 }
353 else
354 set_colour (WINFG_DIM);
355 DrawScreenText (-1, -1, "\1Lower:\2 %.*s",
356 WAD_TEX_NAME, SideDefs[sd1].tex2);
357
358 set_colour (WINFG);
359 DrawScreenText (-1, -1, "\1X-ofs:\2 %d", SideDefs[sd1].xoff);
360 DrawScreenText (-1, -1, "\1Y-ofs:\2 %d", SideDefs[sd1].yoff);
361 DrawScreenText (-1, -1, "\1Sector:\2 #%d", s1);
362 }
363 else
364 {
365 const char *message = "(no 1st sidedef)";
366 set_colour (CLR_ERROR);
367 DrawScreenText (x0 + (width - FONTW * strlen (message)) / 2,
368 y0 + (height - FONTH) / 2, message);
369 }
370
371 // 2nd sidedef
372 x0 += width;
373 ix0 = x0 + BOX_BORDER + WIDE_HSPACING;
374 y0 = out_y1 - height + 1;
375 // Ignore box_disp -- always redraw the whole box
376 DrawScreenBox3D (x0, y0, x0 + width - 1, y0 + height - 1);
377 if (obj_no >= 0 && sd2 >= 0)
378 {
379 set_colour (WINTITLE);
380 DrawScreenText (ix0, iy0, "Sidedef2 #%d", sd2);
381 set_colour (WINFG);
382 const char *tex_name;
383
384 tex_name = SideDefs[sd2].tex1; // Upper texture
385 if (s1 >= 0 && s2 >= 0 && Sectors[s2].ceilh > Sectors[s1].ceilh
386 && ! (is_sky (Sectors[s1].ceilt) && is_sky (Sectors[s2].ceilt)))
387 {
388 if (tex_name[0] == '-' && tex_name[1] == '\0')
389 set_colour (CLR_ERROR);
390 else
391 set_colour (WINFG);
392 }
393 else
394 set_colour (WINFG_DIM);
395 DrawScreenText (-1, iy0 + (int) (1.5 * FONTH),
396 "\1Upper:\2 %.*s", WAD_TEX_NAME, tex_name);
397
398 tex_name = SideDefs[sd2].tex3; // Middle texture
399 set_colour (WINFG);
400 DrawScreenText (-1, -1,
401 "\1Middle:\2 %.*s", WAD_TEX_NAME, tex_name);
402
403 tex_name = SideDefs[sd2].tex2; // Lower texture
404 if (s1 >= 0 && s2 >= 0 && Sectors[s2].floorh < Sectors[s1].floorh
405 && ! (is_sky (Sectors[s1].floort) && is_sky (Sectors[s2].floort)))
406 {
407 if (tex_name[0] == '-' && tex_name[1] == '\0')
408 set_colour (CLR_ERROR);
409 else
410 set_colour (WINFG);
411 }
412 else
413 set_colour (WINFG_DIM);
414 DrawScreenText (-1, -1, "\1Lower:\2 %.*s", WAD_TEX_NAME, tex_name);
415
416 set_colour (WINFG);
417 DrawScreenText (-1, -1, "\1X-ofs:\2 %d", SideDefs[sd2].xoff);
418 DrawScreenText (-1, -1, "\1Y-ofs:\2 %d", SideDefs[sd2].yoff);
419 DrawScreenText (-1, -1, "\1Sector:\2 #%d", s2);
420 }
421 else
422 {
423 const char *message = "(no 2nd sidedef)";
424 // If the "2" flag is set, there must be a second sidedef
425 if (LineDefs[obj_no].flags & 0x04) // FIXME hard-coded
426 set_colour (CLR_ERROR);
427 else
428 set_colour (WINFG_DIM);
429 DrawScreenText (x0 + (width - FONTW * strlen (message)) / 2,
430 y0 + (height - FONTH) / 2, message);
431 }
432
433 // Superimposed linedefs
434 {
435 Superimposed_ld super;
436 super.set (obj_no);
437 obj_no_t l = super.get ();
438 int iy1;
439
440 if (l != -1 || box_disp[3])
441 {
442 x0 += width;
443 width = 2 * BOX_BORDER + 2 * WIDE_HSPACING + 12 * FONTW;
444 ix0 = x0 + BOX_BORDER + WIDE_HSPACING;
445 iy0 = y0 + BOX_BORDER + WIDE_VSPACING;
446 iy1 = y0 + height - 1 - BOX_BORDER - WIDE_VSPACING;
447 DrawScreenBox3D (x0, y0, x0 + width - 1, y0 + height - 1);
448 }
449 if (l != -1)
450 {
451 box_disp[3] = true;
452 set_colour (WINTITLE);
453 DrawScreenString (ix0, iy0, "Superimposed");
454 set_colour (WINFG);
455 iy0 += int (1.5 * FONTH);
456 while (l != -1)
457 {
458 if (iy0 + FONTH - 1 <= iy1)
459 DrawScreenText (ix0, iy0, "#%d", l);
460 /* Too many linedefs, replace the last one by "(more)".
461 Not elegant, but it makes the code simpler. */
462 else
463 {
464 iy0 -= FONTH;
465 set_colour (WINBG);
466 DrawScreenBox (ix0, iy0, ix0 + 12 * FONTW - 1, iy0 + FONTH - 1);
467 set_colour (WINFG);
468 DrawScreenString (ix0, iy0, "(more)");
469 break;
470 }
471 iy0 += FONTH;
472 l = super.get ();
473 }
474 }
475 }
476 break;
477
478 case OBJ_VERTICES:
479 width = 2 * BOX_BORDER + 2 * WIDE_HSPACING + 29 * FONTW;
480 height = 2 * BOX_BORDER + 2 * WIDE_VSPACING + (int) (2.5 * FONTH);
481 x0 = 0;
482 y0 = out_y1 - height + 1;
483 ix0 = x0 + BOX_BORDER + WIDE_HSPACING;
484 iy0 = y0 + BOX_BORDER + WIDE_VSPACING;
485 // Ignore box_disp -- always redraw the whole box
486 DrawScreenBox3D (x0, y0, x0 + width - 1, y0 + height - 1);
487 if (obj_no < 0)
488 {
489 const char *message = "(no vertex selected)";
490 set_colour (WINFG_DIM);
491 DrawScreenText (x0 + (width - FONTW * strlen (message)) / 2,
492 y0 + (height - FONTH) / 2, message);
493 break;
494 }
495 set_colour (WINTITLE);
496 DrawScreenText (ix0, iy0, "Vertex #%d", obj_no);
497 set_colour (WINFG);
498 DrawScreenText (-1, iy0 + (int) (1.5 * FONTH),
499 "\1Coordinates:\2 (%d, %d)", Vertices[obj_no].x, Vertices[obj_no].y);
500 break;
501
502 case OBJ_SECTORS:
503 {
504 int x1, y1;
505 int ix1, iy1;
506 const int columns = 24;
507 width = BOX_BORDER
508 + WIDE_HSPACING
509 + columns * FONTW
510 + WIDE_HSPACING
511 + HOLLOW_BORDER
512 + DOOM_FLAT_WIDTH
513 + HOLLOW_BORDER
514 + WIDE_HSPACING
515 + BOX_BORDER;
516 height = 2 * BOX_BORDER
517 + 2 * WIDE_VSPACING
518 + y_max ((unsigned) (9.5 * FONTH),
519 WIDE_HSPACING + 4 * HOLLOW_BORDER + 2 * DOOM_FLAT_HEIGHT);
520 x0 = 0;
521 y0 = out_y1 - height + 1;
522 x1 = x0 + width - 1;
523 y1 = y0 + height - 1;
524 ix0 = x0 + BOX_BORDER + WIDE_HSPACING;
525 iy0 = y0 + BOX_BORDER + WIDE_VSPACING;
526 ix1 = x1 - BOX_BORDER - WIDE_HSPACING;
527 iy1 = y1 - BOX_BORDER - WIDE_VSPACING;
528 if (box_disp[0])
529 {
530 push_colour (WINBG);
531 DrawScreenBox (ix0, iy0, ix0 + columns * FONTW - 1, iy1);
532 pop_colour ();
533 }
534 else
535 DrawScreenBox3D (x0, y0, x1, y1);
536 if (obj_no < 0)
537 {
538 const char *const message = "(no sector selected)";
539 set_colour (WINFG_DIM);
540 DrawScreenText (x0 + (width - FONTW * strlen (message)) / 2,
541 y0 + (height - FONTH) / 2, message);
542 break;
543 }
544 set_colour (WINTITLE);
545 DrawScreenText (ix0, iy0, "Sector #%d", obj_no);
546 set_colour (WINFG);
547 const struct Sector *sec = Sectors + obj_no;
548 if (prev_sector >= 0 && prev_sector != obj_no)
549 {
550 DrawScreenText (-1, iy0 + (int) (1.5 * FONTH),
551 "\1Floor:\2 %d (%+d)",
552 sec->floorh, sec->floorh - prev_floorh);
553 DrawScreenText (-1, -1, "\1Ceiling:\2 %d (%+d)",
554 sec->ceilh, sec->ceilh - prev_ceilh);
555 }
556 else
557 {
558 DrawScreenText (-1, iy0 + (int) (1.5 * FONTH),
559 "\1Floor:\2 %d", sec->floorh);
560 DrawScreenText (-1, -1, "\1Ceiling:\2 %d", sec->ceilh);
561 }
562 DrawScreenText (-1, -1, "\1Headroom:\2 %d", sec->ceilh - sec->floorh);
563 DrawScreenText (-1, -1, "\1Floor:\2 %.*s", WAD_FLAT_NAME, sec->floort);
564 DrawScreenText (-1, -1, "\1Ceiling:\2 %.*s", WAD_FLAT_NAME, sec->ceilt);
565 DrawScreenText (-1, -1, "\1Light:\2 %d", sec->light);
566 DrawScreenText (-1, -1, "\1Type:\2 %3d %.14s",
567 sec->special, GetSectorTypeName (sec->special));
568 {
569 int tag = sec->tag;
570 int first_ld = NumLineDefs;
571 int second_ld = NumLineDefs;
572
573 ObjectsNeeded (OBJ_LINEDEFS, 0);
574 if (tag != 0)
575 {
576 for (n = 0; n < NumLineDefs; n++)
577 if (LineDefs[n].tag == tag)
578 {
579 if (first_ld >= NumLineDefs)
580 first_ld = n;
581 else
582 {
583 second_ld = n;
584 break;
585 }
586 }
587 }
588 if (first_ld < NumLineDefs && second_ld < NumLineDefs)
589 DrawScreenText (-1, -1, "\1Tag:\2 %d (#%d+)", tag, first_ld);
590 else if (first_ld < NumLineDefs)
591 DrawScreenText (-1, -1, "\1Tag:\2 %d (#%d)", tag, first_ld);
592 else if (tag == 99 || tag == 999)
593 DrawScreenText (-1, -1, "\1Tag:\2 %d (stairs?)", tag);
594 else if (tag == 666)
595 DrawScreenText (-1, -1, "\1Tag:\2 %d (lower@end)", tag);
596 else if (tag == 667)
597 DrawScreenText (-1, -1, "\1Tag:\2 %d (raise@end)", tag);
598 else
599 DrawScreenText (-1, -1, "\1Tag:\2 %d (none)", tag);
600 }
601 {
602 hookfunc_comm_t block;
603
604 // Display the floor texture in the bottom right corner
605 block.x1 = ix1;
606 block.x0 = block.x1 - (DOOM_FLAT_WIDTH + 2 * HOLLOW_BORDER - 1);
607 block.y1 = iy1;
608 block.y0 = block.y1 - (DOOM_FLAT_HEIGHT + 2 * HOLLOW_BORDER - 1);
609 block.name = sec->floort;
610 display_flat_depressed (&block);
611
612 // Display the ceiling texture above the floor texture
613 block.y1 = block.y0 - (WIDE_VSPACING + 1);
614 block.y0 = block.y1 - (DOOM_FLAT_HEIGHT + 2 * HOLLOW_BORDER - 1);
615 block.name = sec->ceilt;
616 display_flat_depressed (&block);
617 }
618
619 // Show all EDGE extrafloors for this sector
620 {
621 x0 += width;
622 const int columns2 = 16;
623 const int width2 = BOX_BORDER
624 + WIDE_HSPACING
625 + columns2 * FONTW
626 + WIDE_HSPACING
627 + HOLLOW_BORDER
628 + DOOM_FLAT_WIDTH
629 + HOLLOW_BORDER
630 + WIDE_HSPACING
631 + BOX_BORDER;
632 std::vector<Extraf> v;
633 get_extrafloors (v, sec->tag);
634 size_t e;
635 for (e = 0; e < v.size () && e + 1 < MAX_BOXES; e++, x0 += width2)
636 {
637 const Extraf& i = v[e];
638 obj_no_t dsecno = i.sector;
639 bool thick = (*i.tex != '\0');
640 const struct Sector *dsec = Sectors + dsecno;
641 x1 = x0 + width2 - 1;
642 y1 = y0 + height - 1;
643 ix0 = x0 + BOX_BORDER + WIDE_HSPACING;
644 iy0 = y0 + BOX_BORDER + WIDE_VSPACING;
645 ix1 = x1 - BOX_BORDER - WIDE_HSPACING;
646 iy1 = y1 - BOX_BORDER - WIDE_VSPACING;
647 if (box_disp[e + 1]) // FIXME
648 {
649 push_colour (WINBG);
650 DrawScreenBox (ix0, iy0, ix0 + columns2 * FONTW - 1, iy1);
651 pop_colour ();
652 }
653 else
654 {
655 DrawScreenBox3D (x0, y0, x1, y1);
656 box_disp[e + 1] = true;
657 }
658 if (! is_sector (dsecno)) // Can't happen
659 continue;
660 set_colour (WINTITLE);
661 if (thick)
662 DrawScreenText (ix0, iy0, "Thick #%d", dsecno);
663 else
664 DrawScreenText (ix0, iy0, "Thin #%d", dsecno);
665 set_colour (WINFG);
666 if (thick)
667 {
668 DrawScreenText (-1, iy0 + (int) (1.5 * FONTH),
669 "\1Bottom:\2 %d", dsec->floorh);
670 DrawScreenText (-1, -1, "\1Top:\2 %d", dsec->ceilh);
671 DrawScreenText (-1, -1, "\1Thick:\2 %d", dsec->ceilh - dsec->floorh);
672 DrawScreenText (-1, -1, "\1Bottom:\2 %.*s", WAD_FLAT_NAME,dsec->floort);
673 DrawScreenText (-1, -1, "\1Top:\2 %.*s", WAD_FLAT_NAME, dsec->ceilt);
674 }
675 else
676 {
677 DrawScreenText (-1, iy0 + (int) (1.5 * FONTH),
678 "\1Height:\2 %d", dsec->floorh);
679 DrawScreenText (-1, -1, "\1Flat:\2 %.*s", WAD_FLAT_NAME,dsec->floort);
680 }
681 DrawScreenText (-1, -1, "\1Shadow:\2 %d", dsec->light);
682 DrawScreenText (-1, -1, "\1Type:\2 %d", dsec->special);
683 ObjectsNeeded (OBJ_LINEDEFS, 0);
684 if (thick)
685 DrawScreenText (-1, -1, "\1Side:\2 %.*s", WAD_TEX_NAME, i.tex);
686 {
687 hookfunc_comm_t block;
688
689 // Display the top texture in the bottom right corner
690 block.x1 = ix1;
691 block.x0 = block.x1 - (DOOM_FLAT_WIDTH + 2 * HOLLOW_BORDER - 1);
692 block.y1 = iy1;
693 block.y0 = block.y1 - (DOOM_FLAT_HEIGHT + 2 * HOLLOW_BORDER - 1);
694 block.name = dsec->floort;
695 display_flat_depressed (&block);
696
697 // Display the bottom texture above the floor texture
698 block.y1 = block.y0 - (WIDE_VSPACING + 1);
699 block.y0 = block.y1 - (DOOM_FLAT_HEIGHT + 2 * HOLLOW_BORDER - 1);
700 if (thick)
701 {
702 block.name = dsec->ceilt;
703 display_flat_depressed (&block);
704 }
705 else
706 {
707 push_colour (WINBG);
708 DrawScreenBoxwh (block.x0, block.y0, DOOM_FLAT_WIDTH
709 + 2 * HOLLOW_BORDER, DOOM_FLAT_HEIGHT + 2 * HOLLOW_BORDER);
710 pop_colour ();
711 }
712 }
713 }
714 // Clear out remaining boxes
715 for (; e + 1 < MAX_BOXES && box_disp[e + 1]; e++, x0 += width2)
716 {
717 x1 = x0 + width2 - 1;
718 y1 = y0 + height - 1;
719 ix0 = x0 + BOX_BORDER + WIDE_HSPACING;
720 iy0 = y0 + BOX_BORDER + WIDE_VSPACING;
721 ix1 = x1 - BOX_BORDER - WIDE_HSPACING;
722 iy1 = y1 - BOX_BORDER - WIDE_VSPACING;
723 push_colour (WINBG);
724 DrawScreenBox (ix0, iy0, ix1, iy1);
725 pop_colour ();
726 }
727 }
728 break;
729 }
730 }
731
732 if (obj_type == OBJ_SECTORS)
733 {
734 if (obj_no != prev_sector)
735 prev_sector = obj_no;
736 if (obj_no >= 0)
737 {
738 prev_floorh = Sectors[obj_no].floorh;
739 prev_ceilh = Sectors[obj_no].ceilh;
740 }
741 }
742 box_disp[0] = true;
743 obj_no_disp = obj_no;
744 obj_type_disp = obj_type;
745 }
746
747
748 /*
749 * get_extrafloors - get list of EDGE extrafloors for tag
750 *
751 * Put in <v> a list of the extrafloors for tag <tag>,
752 * sorted by floor height major, sector number minor. The
753 * previous content of <v> is lost. Each Extraf object in
754 * <v> is set up in the following way :
755 *
756 * - <sector> is set to the number of the dummy sector,
757 *
758 * - <tex> is set to the side texture of the extrafloor, or
759 * "" if it's a thin extrafloor,
760 *
761 * - <height> is the to the floor height of the dummy
762 * sector.
763 */
get_extrafloors(std::vector<Extraf> & v,wad_tag_t tag)764 static void get_extrafloors (std::vector<Extraf>& v, wad_tag_t tag)
765 {
766 v.clear ();
767 for (obj_no_t l = 0; l < NumLineDefs; l++)
768 {
769 if (LineDefs[l].tag == tag
770 && LineDefs[l].type >= 400 && LineDefs[l].type <= 407) // FIXME
771 {
772 obj_no_t sd = LineDefs[l].sidedef1;
773 if (! is_sidedef (sd) || ! is_sector (SideDefs[sd].sector)) // Paranoia
774 continue;
775 wad_tex_name_t tex;
776 if (LineDefs[l].type == 400)
777 memcpy (tex, SideDefs[sd].tex3, sizeof tex);
778 else if (LineDefs[l].type == 401) // side_upper
779 memcpy (tex, SideDefs[sd].tex1, sizeof tex);
780 else if (LineDefs[l].type == 402) // side_lower
781 memcpy (tex, SideDefs[sd].tex2, sizeof tex);
782 else
783 memset (tex, '\0', sizeof tex);
784 v.push_back (Extraf (SideDefs[sd].sector,
785 tex,
786 Sectors[SideDefs[sd].sector].floorh));
787 }
788 }
789 sort (v.begin (), v.end ());
790 }
791
792
793