1 // "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
2 // Ken Silverman's official web site: "http://www.advsys.net/ken"
3 // See the included license file "BUILDLIC.TXT" for license info.
4 //
5 // This file has been modified from Ken Silverman's original release
6 // by Jonathon Fowler (jf@jonof.id.au)
7 // by the EDuke32 team (development@voidpoint.com)
8
9 #include "build.h"
10 #include "editor.h"
11
12 int32_t editorgridextent = 131072;
13
14 ////////// editor side view //////////
15 int32_t m32_sideview = 0;
16 int32_t m32_sideelev = 256; // elevation in BUILD degrees, 0..512
17 int16_t m32_sideang = 200; // azimuth, 0..2047
18
19 int32_t m32_sidecos, m32_sidesin;
20 int32_t m32_swcnt;
21 int32_t m32_wallscreenxy[MAXWALLS][2];
22 int16_t m32_wallsprite[MAXWALLS+MAXSPRITES];
23 static int32_t m32_sidedist[MAXWALLS+MAXSPRITES];
24 static vec3_t m32_viewplane;
25
drawpixel_safe(void * s,char a)26 static void drawpixel_safe(void *s, char a)
27 {
28 #if defined __GNUC__
29 if (__builtin_expect((intptr_t) s >= frameplace && (intptr_t) s < frameplace+bytesperline*ydim, 1))
30 #else
31 if ((intptr_t) s >= frameplace && (intptr_t) s < frameplace+bytesperline*ydim)
32 #endif
33 drawpixel(s, a);
34 #ifdef DEBUGGINGAIDS
35 else
36 {
37 const char c = editorcolors[15];
38
39 drawpixel((intptr_t *) frameplace, c);
40 drawpixel((intptr_t *) frameplace+1, c);
41 drawpixel((intptr_t *) frameplace+2, c);
42 drawpixel((intptr_t *) frameplace+bytesperline, c);
43 drawpixel((intptr_t *) frameplace+bytesperline+1, c);
44 drawpixel((intptr_t *) frameplace+bytesperline+2, c);
45 drawpixel((intptr_t *) frameplace+2*bytesperline, c);
46 drawpixel((intptr_t *) frameplace+2*bytesperline+1, c);
47 drawpixel((intptr_t *) frameplace+2*bytesperline+2, c);
48 }
49 #endif
50 }
51
52
53
54 //
55 // plotpixel
56 //
plotpixel(int32_t x,int32_t y,char col)57 void plotpixel(int32_t x, int32_t y, char col)
58 {
59 #if defined USE_OPENGL && !defined EDUKE32_GLES
60 if (videoGetRenderMode() >= REND_POLYMOST && in3dmode())
61 {
62 palette_t p = paletteGetColor(col);
63 glEnable(GL_SCISSOR_TEST);
64 glScissor(x,ydim-y+1,1,1);
65 glClearColor((float)p.r*(1.0f/255.0f),(float)p.g*(1.0f/255.0f),(float)p.b*(1.0f)/255.0f,1.0f);
66 glClear(GL_COLOR_BUFFER_BIT);
67 glClearColor(0.0f,0.0f,0.0f,1.0f); // XXX: there must be a better way
68 glDisable(GL_SCISSOR_TEST);
69 return;
70 }
71 #endif
72
73 videoBeginDrawing(); //{{{
74 drawpixel_safe((void *) (ylookup[y]+x+frameplace), col);
75 videoEndDrawing(); //}}}
76 }
77
plotlines2d(const int32_t * xx,const int32_t * yy,int32_t numpoints,int col)78 void plotlines2d(const int32_t *xx, const int32_t *yy, int32_t numpoints, int col)
79 {
80 int32_t i;
81
82 #ifdef USE_OPENGL
83 if (videoGetRenderMode() >= REND_POLYMOST && in3dmode())
84 {
85 palette_t p = paletteGetColor(col);
86
87 polymost_useColorOnly(true);
88 glBegin(GL_LINE_STRIP);
89
90 glColor4ub(p.r, p.g, p.b, 1);
91
92 for (i=0; i<numpoints; i++)
93 glVertex2i(xx[i], yy[i]);
94
95 glEnd();
96 polymost_useColorOnly(false);
97 return;
98 }
99 #endif
100 {
101 int32_t odrawlinepat = drawlinepat;
102 drawlinepat = 0xffffffff;
103
104 videoBeginDrawing();
105 for (i=0; i<numpoints-1; i++)
106 editorDraw2dLine(xx[i], yy[i], xx[i+1], yy[i+1], col);
107 videoEndDrawing();
108
109 drawlinepat = odrawlinepat;
110 }
111 }
112
113
114 //
115 // drawline256
116 //
117 #ifdef USE_OPENGL
drawlinegl(int32_t x1,int32_t y1,int32_t x2,int32_t y2,palette_t p)118 static void drawlinegl(int32_t x1, int32_t y1, int32_t x2, int32_t y2, palette_t p)
119 {
120 // setpolymost2dview(); // JBF 20040205: more efficient setup
121
122 int const dx = x2-x1;
123 int const dy = y2-y1;
124
125 if (dx >= 0)
126 {
127 if ((x1 >= wx2) || (x2 < wx1)) return;
128 if (x1 < wx1) y1 += scale(wx1-x1, dy, dx), x1 = wx1;
129 if (x2 > wx2) y2 += scale(wx2-x2, dy, dx), x2 = wx2;
130 }
131 else
132 {
133 if ((x2 >= wx2) || (x1 < wx1)) return;
134 if (x2 < wx1) y2 += scale(wx1-x2, dy, dx), x2 = wx1;
135 if (x1 > wx2) y1 += scale(wx2-x1, dy, dx), x1 = wx2;
136 }
137 if (dy >= 0)
138 {
139 if ((y1 >= wy2) || (y2 < wy1)) return;
140 if (y1 < wy1) x1 += scale(wy1-y1, dx, dy), y1 = wy1;
141 if (y2 > wy2) x2 += scale(wy2-y2, dx, dy), y2 = wy2;
142 }
143 else
144 {
145 if ((y2 >= wy2) || (y1 < wy1)) return;
146 if (y2 < wy1) x2 += scale(wy1-y2, dx, dy), y2 = wy1;
147 if (y1 > wy2) x1 += scale(wy2-y1, dx, dy), y1 = wy2;
148 }
149
150 glViewport(0, 0, xdim, ydim);
151 glMatrixMode(GL_PROJECTION);
152 glLoadIdentity();
153 glOrtho(0, xdim, ydim, 0, -1, 1);
154 if (videoGetRenderMode() == REND_POLYMER)
155 {
156 glMatrixMode(GL_MODELVIEW);
157 glLoadIdentity();
158 }
159
160 polymost2d = 1;
161 glDisable(GL_ALPHA_TEST);
162 glDisable(GL_DEPTH_TEST);
163 glEnable(GL_BLEND); // When using line antialiasing, this is needed
164
165 polymost_useColorOnly(true);
166 glBegin(GL_LINES);
167 glColor4ub(p.r, p.g, p.b, 255);
168
169 glVertex2f((float) x1 * (1.f/4096.f), (float) y1 * (1.f/4096.f));
170 glVertex2f((float) x2 * (1.f/4096.f), (float) y2 * (1.f/4096.f));
171
172 glEnd();
173 polymost_useColorOnly(false);
174 }
175 #endif
176
drawlinepixels(int32_t x1,int32_t y1,int32_t x2,int32_t y2,char col)177 static void drawlinepixels(int32_t x1, int32_t y1, int32_t x2, int32_t y2, char col)
178 {
179 int32_t dx, dy, i, j, inc, plc, daend;
180 intptr_t p;
181
182 dx = x2-x1; dy = y2-y1;
183 if (dx >= 0)
184 {
185 if ((x1 >= wx2) || (x2 < wx1)) return;
186 if (x1 < wx1) y1 += scale(wx1-x1, dy, dx), x1 = wx1;
187 if (x2 > wx2) y2 += scale(wx2-x2, dy, dx), x2 = wx2;
188 }
189 else
190 {
191 if ((x2 >= wx2) || (x1 < wx1)) return;
192 if (x2 < wx1) y2 += scale(wx1-x2, dy, dx), x2 = wx1;
193 if (x1 > wx2) y1 += scale(wx2-x1, dy, dx), x1 = wx2;
194 }
195 if (dy >= 0)
196 {
197 if ((y1 >= wy2) || (y2 < wy1)) return;
198 if (y1 < wy1) x1 += scale(wy1-y1, dx, dy), y1 = wy1;
199 if (y2 > wy2) x2 += scale(wy2-y2, dx, dy), y2 = wy2;
200 }
201 else
202 {
203 if ((y2 >= wy2) || (y1 < wy1)) return;
204 if (y2 < wy1) x2 += scale(wy1-y2, dx, dy), y2 = wy1;
205 if (y1 > wy2) x1 += scale(wy2-y1, dx, dy), y1 = wy2;
206 }
207
208 if (klabs(dx) >= klabs(dy))
209 {
210 if (dx == 0) return;
211 if (dx < 0)
212 {
213 i = x1; x1 = x2; x2 = i;
214 i = y1; y1 = y2; y2 = i;
215 }
216
217 inc = divscale12(dy, dx);
218 plc = y1+mulscale12((2047-x1)&4095, inc);
219 i = ((x1+2048)>>12); daend = ((x2+2048)>>12);
220
221 videoBeginDrawing(); //{{{
222 for (; i<daend; i++)
223 {
224 j = (plc>>12);
225 if ((j >= startumost[i]) && (j < startdmost[i]))
226 drawpixel_safe((void *) (frameplace+ylookup[j]+i), col);
227 plc += inc;
228 }
229 videoEndDrawing(); //}}}
230 }
231 else
232 {
233 if (dy < 0)
234 {
235 i = x1; x1 = x2; x2 = i;
236 i = y1; y1 = y2; y2 = i;
237 }
238
239 inc = divscale12(dx, dy);
240 plc = x1+mulscale12((2047-y1)&4095, inc);
241 i = ((y1+2048)>>12); daend = ((y2+2048)>>12);
242
243 videoBeginDrawing(); //{{{
244 p = ylookup[i]+frameplace;
245 for (; i<daend; i++)
246 {
247 j = (plc>>12);
248 if ((i >= startumost[j]) && (i < startdmost[j]))
249 drawpixel_safe((void *) (j+p), col);
250 plc += inc; p += ylookup[1];
251 }
252 videoEndDrawing(); //}}}
253 }
254 }
255
drawlinergb(int32_t x1,int32_t y1,int32_t x2,int32_t y2,palette_t p)256 void drawlinergb(int32_t x1, int32_t y1, int32_t x2, int32_t y2, palette_t p)
257 {
258 #ifdef USE_OPENGL
259 if (videoGetRenderMode() >= REND_POLYMOST)
260 {
261 drawlinegl(x1, y1, x2, y2, p);
262 return;
263 }
264 #endif
265
266 char const col = palookup[0][p.f];
267 drawlinepixels(x1, y1, x2, y2, col);
268 }
269
renderDrawLine(int32_t x1,int32_t y1,int32_t x2,int32_t y2,char col)270 void renderDrawLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, char col)
271 {
272 col = palookup[0][col];
273
274 #ifdef USE_OPENGL
275 if (videoGetRenderMode() >= REND_POLYMOST)
276 {
277 palette_t p = paletteGetColor(col);
278 p.f = col;
279 drawlinegl(x1, y1, x2, y2, p);
280 return;
281 }
282 #endif
283
284 drawlinepixels(x1, y1, x2, y2, col);
285 }
286
287
288 //static void attach_here() {}
289
290 //
291 // drawline16
292 //
293 // JBF: Had to add extra tests to make sure x-coordinates weren't winding up -'ve
294 // after clipping or crashes would ensue
295 uint32_t drawlinepat = 0xffffffff;
296
editorDraw2dLine(int32_t x1,int32_t y1,int32_t x2,int32_t y2,int col)297 int32_t editorDraw2dLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int col)
298 {
299 //int32_t odx,ody;
300 //int32_t ox1=x1,oy1=y1, ox2=x2,oy2=y2;
301
302 vec2_t d = { x2-x1, y2-y1 };
303
304 //odx=dx;
305 //ody=dy;
306
307 if (d.x < 0)
308 {
309 swaplong(&x1, &x2);
310 swaplong(&y1, &y2);
311 }
312
313 if (x1 >= xdim || x2 < 0)
314 return 0;
315
316 if (x1 < 0)
317 {
318 if (d.y) y1 += scale(0-x1, d.y, d.x);
319 x1 = 0;
320 }
321
322 if (x2 >= xdim)
323 {
324 if (d.y) y2 += scale(xdim-1-x2, d.y, d.x);
325 x2 = xdim-1;
326 }
327
328 if ((d.x < 0 && d.y >= 0) || (d.y < 0 && d.x >= 0))
329 {
330 swaplong(&x1, &x2);
331 swaplong(&y1, &y2);
332 }
333
334 if (y1 >= ydim16 || y2 < 0)
335 return 0;
336
337 if (y1 < 0)
338 {
339 if (d.x)
340 x1 = clamp(x1 + scale(0 - y1, d.x, d.y), 0, xdim - 1);
341 y1 = 0;
342 }
343
344 if (y2 >= ydim16)
345 {
346 if (d.x)
347 x2 = clamp(x2 + scale(ydim16-1-y2, d.x, d.y), 0, xdim-1);
348 y2 = ydim16-1;
349 }
350
351 if (d.y < 0)
352 {
353 swaplong(&x1, &x2);
354 swaplong(&y1, &y2);
355 }
356
357 //if (ox1||ox2||oy1||oy2)
358 // if (x1<0||x1>=xdim || y2<0||y2>=ydim)
359 // attach_here();
360
361 d.x = klabs(x2-x1)+1;
362 d.y = klabs(y2-y1)+1;
363
364 if ((d.x >= d.y && x2 < x1) || (d.x < d.y && y2 < y1))
365 {
366 swaplong(&x1, &x2);
367 swaplong(&y1, &y2);
368 }
369
370 int pinc, inc = 1;
371
372 videoBeginDrawing(); //{{{
373
374 intptr_t p = (y1*bytesperline)+x1+frameplace;
375
376 if (d.x >= d.y)
377 {
378 pinc = (y2 > y1) ? bytesperline : -bytesperline;
379 }
380 else
381 {
382 pinc = (x2 > x1) ? 1 : -1;
383 swaplong(&d.x, &d.y);
384 inc = bytesperline;
385 }
386
387 int const trans = (col < 0);
388
389 if (trans)
390 {
391 col = -col;
392
393 if (drawlinepat == 0xffffffff)
394 {
395 for (bssize_t i=d.x, df=0; i>0; i--)
396 {
397 drawtranspixel((char *) p, col);
398 df += d.y;
399 if (df >= d.x) { df -= d.x; p += pinc; }
400 p += inc;
401 }
402 }
403 else
404 {
405 uint32_t patc = UINT_MAX;
406
407 for (bssize_t i=d.x, df=0; i>0; i--)
408 {
409 if (drawlinepat & pow2long[(++patc)&31])
410 drawtranspixel((char *) p, col);
411 df += d.y;
412 if (df >= d.x) { df -= d.x; p += pinc; }
413 p += inc;
414 }
415 }
416
417 videoEndDrawing(); //}}}
418
419 return 1;
420 }
421
422 if (inc == 1 && d.y == 1 && drawlinepat == 0xffffffff)
423 clearbufbyte((void *) p, d.x, ((int32_t) col<<24)|((int32_t) col<<16)|((int32_t) col<<8)|col);
424 else if (drawlinepat == 0xffffffff)
425 {
426 for (bssize_t i=d.x, df=0; i>0; i--)
427 {
428 drawpixel((char *) p, col);
429 df += d.y;
430 if (df >= d.x) { df -= d.x; p += pinc; }
431 p += inc;
432 }
433 }
434 else
435 {
436 uint32_t patc = UINT_MAX;
437
438 for (bssize_t i=d.x, df=0; i>0; i--)
439 {
440 if (drawlinepat & pow2long[(++patc)&31])
441 drawpixel((char *) p, col);
442 df += d.y;
443 if (df >= d.x) { df -= d.x; p += pinc; }
444 p += inc;
445 }
446 }
447
448 videoEndDrawing(); //}}}
449
450 return 1;
451 }
452
editorDraw2dLineMiddle(int32_t x1,int32_t y1,int32_t x2,int32_t y2,char col)453 static FORCE_INLINE void editorDraw2dLineMiddle(int32_t x1, int32_t y1, int32_t x2, int32_t y2, char col)
454 {
455 editorDraw2dLine(halfxdim16+x1, midydim16+y1, halfxdim16+x2, midydim16+y2, col);
456 }
457
458 // eccen: eccentricity of the ellipse,
459 // 16384: circle
460 // <16384: shrink in y
461 // >16384: grow in y
editorDraw2dCircle(int32_t x1,int32_t y1,int32_t r,int32_t eccen,char col)462 void editorDraw2dCircle(int32_t x1, int32_t y1, int32_t r, int32_t eccen, char col)
463 {
464 if (eccen != 16384)
465 {
466 // JonoF's rough approximation of a circle
467 int32_t l, spx, spy, lpx, lpy, px, py;
468
469 spx = lpx = x1 + mulscale14(r, sintable[0]);
470 spy = lpy = y1 + mulscale14(eccen, mulscale14(r, sintable[512]));
471
472 for (l=64; l<2048; l+=64)
473 {
474 px = x1 + mulscale14(r, sintable[l]);
475 py = y1 + mulscale14(eccen, mulscale14(r, sintable[(l+512)&2047]));
476
477 editorDraw2dLine(lpx, lpy, px, py, col);
478
479 lpx = px;
480 lpy = py;
481 }
482
483 editorDraw2dLine(lpx, lpy, spx, spy, col);
484
485 return;
486 }
487
488 if (r < 0) r = -r;
489 if (x1+r < 0 || y1+r < 0 || x1-r >= xdim || y1-r >= ydim16) return;
490
491 uint32_t const uxdim = xdim, uydim16 = ydim16;
492
493 /*
494 * d
495 * 6 | 7
496 * \ | /
497 * 5 \|/ 8
498 * c----+----a
499 * 4 /|\ 1
500 * / | \
501 * 3 | 2
502 * b
503 */
504
505 videoBeginDrawing();
506 intptr_t const p = (y1*bytesperline)+x1+frameplace;
507
508 uint32_t patc = UINT_MAX;
509
510 if (drawlinepat == 0xffffffff || drawlinepat & pow2long[(++patc)&31])
511 {
512 if ((uint32_t) y1 < uydim16 && (uint32_t) (x1+r) < uxdim)
513 drawpixel((char *) (p+r), col); // a
514 if ((uint32_t) x1 < uxdim && (uint32_t) (y1+r) < uydim16)
515 drawpixel((char *) (p+(r*bytesperline)), col); // b
516 if ((uint32_t) y1 < uydim16 && (uint32_t) (x1-r) < uxdim)
517 drawpixel((char *) (p-r), col); // c
518 if ((uint32_t) x1 < uxdim && (uint32_t) (y1-r) < uydim16)
519 drawpixel((char *) (p-(r*bytesperline)), col); // d
520 }
521
522 int32_t xp = 0, yp = r;
523 int32_t d = 1 - r, de = 2, dse = 5 - (r << 1);
524
525 if (drawlinepat != 0xffffffff)
526 {
527 do
528 {
529 if (d < 0)
530 {
531 d += de;
532 dse += 2;
533 }
534 else
535 {
536 d += dse;
537 dse += 4;
538 yp--;
539 }
540
541 xp++;
542 de += 2;
543
544 int32_t const ypbpl = yp*bytesperline;
545 int32_t const xpbpl = xp*bytesperline;
546
547 if (drawlinepat & pow2long[(++patc) & 31])
548 {
549 if ((uint32_t) (x1 + yp) < uxdim && (uint32_t) (y1 + xp) < uydim16)
550 drawpixel_safe((char *) (p + yp + xpbpl), col); // 1
551 if ((uint32_t) (x1 + xp) < uxdim && (uint32_t) (y1 + yp) < uydim16)
552 drawpixel_safe((char *) (p + xp + ypbpl), col); // 2
553 if ((uint32_t) (x1 - xp) < uxdim && (uint32_t) (y1 + yp) < uydim16)
554 drawpixel_safe((char *) (p - xp + ypbpl), col); // 3
555 if ((uint32_t) (x1 - yp) < uxdim && (uint32_t) (y1 + xp) < uydim16)
556 drawpixel_safe((char *) (p - yp + xpbpl), col); // 4
557 if ((uint32_t) (x1 - yp) < uxdim && (uint32_t) (y1 - xp) < uydim16)
558 drawpixel_safe((char *) (p - yp - xpbpl), col); // 5
559 if ((uint32_t) (x1 - xp) < uxdim && (uint32_t) (y1 - yp) < uydim16)
560 drawpixel_safe((char *) (p - xp - ypbpl), col); // 6
561 if ((uint32_t) (x1 + xp) < uxdim && (uint32_t) (y1 - yp) < uydim16)
562 drawpixel_safe((char *) (p + xp - ypbpl), col); // 7
563 if ((uint32_t) (x1 + yp) < uxdim && (uint32_t) (y1 - xp) < uydim16)
564 drawpixel_safe((char *) (p + yp - xpbpl), col); // 8
565 }
566 } while (yp > xp);
567
568 videoEndDrawing();
569 return;
570 }
571
572 do
573 {
574 if (d < 0)
575 {
576 d += de;
577 dse += 2;
578 }
579 else
580 {
581 d += dse;
582 dse += 4;
583 yp--;
584 }
585
586 xp++;
587 de += 2;
588
589 int32_t const ypbpl = yp*bytesperline;
590 int32_t const xpbpl = xp*bytesperline;
591
592 if ((uint32_t) (x1 + yp) < uxdim && (uint32_t) (y1 + xp) < uydim16)
593 drawpixel_safe((char *) (p + yp + xpbpl), col); // 1
594 if ((uint32_t) (x1 + xp) < uxdim && (uint32_t) (y1 + yp) < uydim16)
595 drawpixel_safe((char *) (p + xp + ypbpl), col); // 2
596 if ((uint32_t) (x1 - xp) < uxdim && (uint32_t) (y1 + yp) < uydim16)
597 drawpixel_safe((char *) (p - xp + ypbpl), col); // 3
598 if ((uint32_t) (x1 - yp) < uxdim && (uint32_t) (y1 + xp) < uydim16)
599 drawpixel_safe((char *) (p - yp + xpbpl), col); // 4
600 if ((uint32_t) (x1 - yp) < uxdim && (uint32_t) (y1 - xp) < uydim16)
601 drawpixel_safe((char *) (p - yp - xpbpl), col); // 5
602 if ((uint32_t) (x1 - xp) < uxdim && (uint32_t) (y1 - yp) < uydim16)
603 drawpixel_safe((char *) (p - xp - ypbpl), col); // 6
604 if ((uint32_t) (x1 + xp) < uxdim && (uint32_t) (y1 - yp) < uydim16)
605 drawpixel_safe((char *) (p + xp - ypbpl), col); // 7
606 if ((uint32_t) (x1 + yp) < uxdim && (uint32_t) (y1 - xp) < uydim16)
607 drawpixel_safe((char *) (p + yp - xpbpl), col); // 8
608 } while (yp > xp);
609
610 videoEndDrawing();
611 }
612
613 //
614 // clear2dscreen
615 //
clear2dscreen(void)616 void clear2dscreen(void)
617 {
618 int32_t const clearsz = (ydim16 <= ydim - STATUS2DSIZ2) ? ydim - STATUS2DSIZ2 : ydim;
619 videoBeginDrawing(); //{{{
620 Bmemset((char *) frameplace, 0, bytesperline*clearsz);
621 videoEndDrawing(); //}}}
622 }
623
624
625 ////////// editor side view //////////
626
scalescreeny(int32_t sy)627 int32_t scalescreeny(int32_t sy) { return (m32_sideview) ? mulscale14(sy, m32_sidesin) : sy; }
628
629 // return screen coordinates for BUILD coords x and y (relative to current position)
editorGet2dScreenCoordinates(int32_t * xres,int32_t * yres,int32_t x,int32_t y,int32_t zoome)630 void editorGet2dScreenCoordinates(int32_t *xres, int32_t *yres, int32_t x, int32_t y, int32_t zoome)
631 {
632 vec2_t coord = { x, y };
633
634 if (m32_sideview)
635 rotatevec(coord, m32_sideang, &coord);
636
637 *xres = mulscale14(coord.x, zoome);
638 *yres = scalescreeny(mulscale14(coord.y, zoome));
639 }
640
641 #if 0
642 void invscreencoords(int32_t *dx, int32_t *dy, int32_t sx, int32_t sy, int32_t zoome)
643 {
644 if (m32_sidesin==0 || zoome==0) { *dx=0; *dy=0; return; }
645
646 sy = divscale14(divscale14(sy, m32_sidesin), zoome);
647 sx = divscale14(sx, zoome);
648
649 rotatepoint(0, 0, sx, sy, -m32_sideang, dx, dy);
650 }
651 #endif
652
653 // invscreencoords with sx==0 and sy==getscreenvdisp(dz, zoom)
getinvdisplacement(int32_t * dx,int32_t * dy,int32_t dz)654 int32_t getinvdisplacement(int32_t *dx, int32_t *dy, int32_t dz)
655 {
656 if (m32_sidesin==0)
657 return 1;
658
659 dz = (((int64_t) dz * (int64_t) m32_sidecos)/(int64_t) m32_sidesin)>>4;
660
661 vec2_t v[2] = { { 0, dz },{ *dx, *dy } };
662
663 rotatevec(v[0], -m32_sideang, &v[1]);
664
665 *dx = v[1].x;
666 *dy = v[1].y;
667
668 return 0;
669 }
670
671 // return vertical screen coordinate displacement for BUILD z coord
getscreenvdisp(int32_t bz,int32_t zoome)672 int32_t getscreenvdisp(int32_t bz, int32_t zoome)
673 {
674 return mulscale32(bz, zoome*m32_sidecos);
675 }
676
editorSetup2dSideView(void)677 void editorSetup2dSideView(void)
678 {
679 if (m32_sideview)
680 {
681 m32_viewplane.x = 0;
682 m32_viewplane.y = -512;
683
684 m32_sidesin = sintable[m32_sideelev&2047];
685 m32_sidecos = sintable[(m32_sideelev+512)&2047];
686
687 rotatevec(m32_viewplane.vec2, -m32_sideang, &m32_viewplane.vec2);
688 m32_viewplane.x = mulscale14(m32_viewplane.x, m32_sidecos);
689 m32_viewplane.y = mulscale14(m32_viewplane.y, m32_sidecos);
690 m32_viewplane.z = m32_sidesin>>5;
691 }
692 }
693
editorGet2dSideViewDistance(int16_t sw,int16_t sect)694 static void editorGet2dSideViewDistance(int16_t sw, int16_t sect)
695 {
696 vec3_t *p;
697 vec3_t v;
698
699 if (sw<MAXWALLS)
700 {
701 v.x = (wall[sw].x + wall[wall[sw].point2].x)>>1;
702 v.y = (wall[sw].y + wall[wall[sw].point2].y)>>1;
703 v.z = getflorzofslope(sect, v.x, v.y);
704 p = &v;
705 }
706 else
707 p = &sprite[sw-MAXWALLS].pos;
708
709 m32_sidedist[sw] = p->x*m32_viewplane.x + p->y*m32_viewplane.y + (p->z>>4)*m32_viewplane.z;
710 }
711
editorCompare2dSideViewPoints(const void * sw1,const void * sw2)712 static int editorCompare2dSideViewPoints(const void *sw1, const void *sw2)
713 {
714 int32_t dist1 = m32_sidedist[B_UNBUF16(sw1)];
715 int32_t dist2 = m32_sidedist[B_UNBUF16(sw2)];
716
717 if (dist2>dist1)
718 return 1;
719 else if (dist1>dist2)
720 return -1;
721
722 // if (*sw1<MAXWALLS && *sw2<MAXWALLS)
723 // return (wall[*sw2].nextwall>=0) - (wall[*sw1].nextwall>=0);
724
725 return 0;
726 }
727
728 //
729 // draw2dgrid
730 //
editorDraw2dGrid(int32_t posxe,int32_t posye,int32_t posze,int16_t cursectnum,int16_t ange,int32_t zoome,int16_t gride)731 void editorDraw2dGrid(int32_t posxe, int32_t posye, int32_t posze, int16_t cursectnum, int16_t ange, int32_t zoome, int16_t gride)
732 {
733 int64_t i, xp1, yp1, xp2=0, yp2, tempy;
734
735 UNREFERENCED_PARAMETER(ange);
736
737 if (gride <= 0)
738 return;
739
740 videoBeginDrawing(); //{{{
741
742 if (m32_sideview)
743 {
744 int32_t sx1, sy1, sx2, sy2, dx=0, dy=0;
745 int32_t xinc=0, yinc=2048>>gride, yofs;
746
747 // yofs = getscreenvdisp((yinc-posze)&((yinc<<4)-1), zoome);
748 if (cursectnum<0 || cursectnum>=numsectors)
749 yofs = getscreenvdisp(-posze, zoome);
750 else
751 yofs = getscreenvdisp(getflorzofslope(cursectnum, posxe, posye)-posze, zoome);
752
753 while (scalescreeny(mulscale14(yinc, zoome))==0 && gride>2)
754 {
755 gride--;
756 yinc = 2048>>gride;
757 }
758
759 xp2 = xp1 = ((posxe + (1024 >> gride)) & -(((int64_t)(1)) << (11 - gride)));
760 yp2 = yp1 = ((posye + (1024 >> gride)) & -(((int64_t)(1)) << (11 - gride)));
761
762 do
763 {
764 if (xinc==0)
765 {
766 editorGet2dScreenCoordinates(&sx1, &sy1, -editorgridextent-posxe, yp2-posye, zoome);
767 if (yp2 == yp1)
768 {
769 editorGet2dScreenCoordinates(&sx2, &sy2, editorgridextent-posxe, yp2-posye, zoome);
770 dx = sx2-sx1;
771 dy = sy2-sy1;
772 }
773 yp2 += yinc;
774 }
775 else // if (yinc==0)
776 {
777 editorGet2dScreenCoordinates(&sx1, &sy1, xp2-posxe, -editorgridextent-posye, zoome);
778 if (xp2 == xp1)
779 {
780 editorGet2dScreenCoordinates(&sx2, &sy2, xp2-posxe, editorgridextent-posye, zoome);
781 dx = sx2-sx1;
782 dy = sy2-sy1;
783 }
784 xp2 += xinc;
785 }
786
787 i = editorDraw2dLine(halfxdim16+sx1, midydim16+sy1+yofs, halfxdim16+sx1+dx, midydim16+sy1+dy+yofs, editorcolors[25]);
788 if (i==0 || (xp2<-editorgridextent || xp2>editorgridextent ||
789 yp2<-editorgridextent || yp2>editorgridextent))
790 {
791 xp2 = xp1;
792 yp2 = yp1;
793
794 i = 1;
795
796 if (yinc>0)
797 yinc *= -1;
798 else if (yinc<0)
799 {
800 xinc = -yinc;
801 yinc = 0;
802 }
803 else if (xinc>0)
804 xinc *= -1;
805 else // if (xinc<0)
806 i = 0;
807 }
808 } while (i);
809 }
810 else
811 {
812 // vertical lines
813 yp1 = midydim16-mulscale14(posye+editorgridextent, zoome);
814 if (yp1 < 0) yp1 = 0;
815
816 yp2 = midydim16-mulscale14(posye-editorgridextent, zoome);
817 if (yp2 >= ydim16) yp2 = ydim16-1;
818
819 if ((yp1 < ydim16) && (yp2 >= 0) && (yp2 >= yp1))
820 {
821 xp1 = halfxdim16-mulscale14(posxe+editorgridextent, zoome);
822
823 for (i=-editorgridextent; i<=editorgridextent; i+=(2048>>gride))
824 {
825 xp2 = xp1;
826 xp1 = halfxdim16-mulscale14(posxe-i, zoome);
827
828 if (xp1 >= xdim)
829 break;
830
831 if (xp1 >= 0)
832 {
833 if (xp1 != xp2)
834 editorDraw2dLine(xp1, yp1, xp1, yp2, editorcolors[25]);
835 }
836 }
837 if (i >= editorgridextent && xp1 < xdim)
838 xp2 = xp1;
839 if (xp2 >= 0 && xp2 < xdim)
840 editorDraw2dLine(xp2, yp1, xp2, yp2, editorcolors[25]);
841 }
842
843 // horizontal lines
844 xp1 = mulscale14(posxe+editorgridextent, zoome);
845 xp2 = mulscale14(posxe-editorgridextent, zoome);
846 tempy = 0x80000000l;
847
848 for (i=-editorgridextent; i<=editorgridextent; i+=(2048>>gride))
849 {
850 yp1 = ((posye-i)*zoome)>>14;
851 if (yp1 != tempy)
852 {
853 if ((yp1 > midydim16-ydim16) && (yp1 <= midydim16))
854 {
855 editorDraw2dLineMiddle(-xp1, -yp1, -xp2, -yp1, editorcolors[25]);
856 tempy = yp1;
857 }
858 }
859 }
860 }
861
862 videoEndDrawing(); //}}}
863 }
864
865
editorDraw2dWall(int32_t i,int32_t posxe,int32_t posye,int32_t posze,int32_t zoome,int32_t grayp)866 static void editorDraw2dWall(int32_t i, int32_t posxe, int32_t posye, int32_t posze, int32_t zoome, int32_t grayp)
867 {
868 const walltype *const wal = &wall[i];
869
870 int32_t j = wal->nextwall;
871 int32_t cstat = 0;
872 #if 0
873 if (editstatus == 0)
874 {
875 if ((show2dwall[i>>3]&pow2char[i&7]) == 0) return;
876 if ((j >= 0) && (i > j))
877 if ((show2dwall[j>>3]&pow2char[j&7]) > 0) return;
878 }
879 else
880 #endif
881 {
882 if (!m32_sideview && !(grayp&2) && (j >= 0) && (i > j)) return;
883 }
884
885 char col;
886
887 if (grayp&1)
888 col = editorcolors[8];
889 else if (j < 0)
890 {
891 col = (i == linehighlight) ? editorcolors[15] - M32_THROB : editorcolors[15];
892 cstat = wal->cstat;
893 }
894 else
895 {
896 if ((unsigned) wal->nextwall < MAXWALLS && ((wal->cstat^wall[j].cstat)&1))
897 col = editorcolors[2];
898 else if (bloodhack ? (wal->cstat&64) != 0 : (wal->cstat&1) != 0)
899 col = editorcolors[5];
900 else col = editorcolors[4];
901
902 cstat = wal->cstat;
903 if (i != linehighlight && (unsigned)wal->nextwall < MAXWALLS)
904 {
905 if (wal->nextwall == linehighlight)
906 cstat = wall[wal->nextwall].cstat;
907 else
908 cstat |= wall[wal->nextwall].cstat;
909 }
910
911 if (i == linehighlight || (linehighlight >= 0 && i == wall[linehighlight].nextwall))
912 col += M32_THROB>>2;
913 }
914
915 if (bloodhack && (cstat&0xc000))
916 {
917 if (cstat&0x8000)
918 col = editorcolors[10];
919 else if (cstat&0x4000)
920 col = editorcolors[9];
921 if (i == linehighlight || (linehighlight >= 0 && i == wall[linehighlight].nextwall))
922 col -= M32_THROB>>3;
923 }
924
925 int const p2 = wal->point2;
926
927 int32_t x1, y1, x2, y2;
928 editorGet2dScreenCoordinates(&x1, &y1, wal->x-posxe, wal->y-posye, zoome);
929 editorGet2dScreenCoordinates(&x2, &y2, wall[p2].x-posxe, wall[p2].y-posye, zoome);
930
931 int64_t const dx = wal->x-wall[p2].x;
932 int64_t const dy = wal->y-wall[p2].y;
933 int64_t const dist = dx*dx + dy*dy;
934
935 int const bothSidesHighlighted = ((show2dwall[i>>3]&pow2char[i&7]) && (show2dwall[p2>>3]&pow2char[p2&7]));
936
937 if (dist > INT32_MAX)
938 {
939 col=editorcolors[9];
940 if (i == linehighlight || (linehighlight >= 0 && i == wall[linehighlight].nextwall))
941 col -= M32_THROB>>3;
942 }
943 else if ((showfirstwall && searchsector>=0 && (sector[searchsector].wallptr == i ||
944 sector[searchsector].wallptr == wal->nextwall)) ||
945 bothSidesHighlighted)
946 {
947 col = editorcolors[14];
948 if (i == linehighlight || (linehighlight >= 0 && i == wall[linehighlight].nextwall) || bothSidesHighlighted)
949 col -= M32_THROB>>1;
950 }
951 else if (circlewall >= 0 && (i == circlewall || wal->nextwall == circlewall))
952 col = editorcolors[14];
953
954 int32_t fz=0, fzn=0;
955
956 if (m32_sideview)
957 {
958 // draw vertical line to neighboring wall
959 int32_t const sect = sectorofwall(i);
960
961 fz = getflorzofslope(sect, wal->x, wal->y);
962 int32_t fz2 = getflorzofslope(sect, wall[p2].x, wall[p2].y);
963
964 int32_t const dz = getscreenvdisp(fz-posze, zoome);
965 int32_t const dz2 = getscreenvdisp(fz2-posze, zoome);
966
967 y1 += dz;
968 y2 += dz2;
969
970 if (wal->nextwall>=0)
971 {
972 fzn = getflorzofslope(wal->nextsector, wal->x, wal->y);
973 // if (i < wall[j].point2)
974 editorDraw2dLineMiddle(x1, y1, x1, y1+getscreenvdisp(fzn-fz, zoome), col);
975 }
976 #ifdef YAX_ENABLE
977 {
978 int16_t const nw = yax_getnextwall(i, YAX_CEILING);
979
980 if (nw >= 0)
981 {
982 int32_t const odrawlinepat = drawlinepat;
983 fz2 = getflorzofslope(sectorofwall(nw), wall[nw].x, wall[nw].y);
984 drawlinepat = 0x11111111;
985 editorDraw2dLineMiddle(x1, y1, x1, y1+getscreenvdisp(fz2-fz, zoome), col);
986 drawlinepat = odrawlinepat;
987 }
988 }
989 #endif
990
991 m32_wallscreenxy[i][0] = halfxdim16+x1;
992 m32_wallscreenxy[i][1] = midydim16+y1;
993 }
994
995 if (bloodhack ? cstat&1 : wal->cstat&64) // if hitscan bit set
996 {
997 int32_t const one=(klabs(x2-x1) >= klabs(y2-y1)), no=!one;
998
999 editorDraw2dLineMiddle(x1+no, y1+one, x2+no, y2+one, col);
1000 editorDraw2dLineMiddle(x1-no, y1-one, x2-no, y2-one, col);
1001 }
1002
1003 editorDraw2dLineMiddle(x1, y1, x2, y2, col);
1004
1005 // Draw height indicators at center of walls if requested and if not in
1006 // side-view mode.
1007 // XXX: This does not take sloping into account.
1008 if (showheightindicators && !m32_sideview)
1009 {
1010 int32_t dax, day;
1011 int32_t const k = getangle(x1-x2, y1-y2);
1012
1013 editorGet2dScreenCoordinates(&dax, &day,
1014 ((wal->x+wall[wal->point2].x)>>1)-posxe,
1015 ((wal->y+wall[wal->point2].y)>>1)-posye, zoome);
1016
1017 if (wal->nextsector >= 0)
1018 {
1019 int32_t const z1 = sector[sectorofwall(i)].floorz;
1020 int32_t const z2 = sector[wal->nextsector].floorz;
1021
1022 if (z1 != z2 || showheightindicators == 2)
1023 {
1024 // Red walls. Show them on equal-height walls ONLY with setting 2.
1025 int32_t const bb = (z2 < z1);
1026 int32_t const dx = mulscale11(sintable[(k+1024 + 1024*bb)&2047], min(4096, zoome)) / 2560;
1027 int32_t const dy = scalescreeny(mulscale11(sintable[(k+512 + 1024*bb)&2047], min(4096, zoome)) / 2560);
1028
1029 editorDraw2dLineMiddle(dax, day, dax+dx, day+dy, col);
1030 }
1031 }
1032 else if (showheightindicators == 2)
1033 {
1034 // Show them on white walls ONLY with setting 2.
1035 int32_t const dx = mulscale11(sintable[(k+2048)&2047], min(4096, zoome)) / 2560;
1036 int32_t const dy = scalescreeny(mulscale11(sintable[(k+1536)&2047], min(4096, zoome)) / 2560);
1037
1038 editorDraw2dLineMiddle(dax, day, dax+dx, day+dy, col);
1039 }
1040 }
1041
1042 if ((zoome >= 256 && editstatus == 1) || show2dwall[i>>3]&pow2char[i&7])
1043 if ((halfxdim16+x1 >= 2) && (halfxdim16+x1 <= xdim-3) &&
1044 (midydim16+y1 >= 2) && (midydim16+y1 <= ydim16-3))
1045 {
1046 int32_t pointsize = 2;
1047
1048 col = editorcolors[15];
1049
1050 if (i == pointhighlight || ((unsigned) pointhighlight < MAXWALLS &&
1051 (wal->x == wall[pointhighlight].x) && (wal->y == wall[pointhighlight].y)))
1052 {
1053 col = editorcolors[15] - (M32_THROB>>1);
1054
1055 if ((int32_t) totalclock & 16)
1056 pointsize++;
1057 }
1058
1059 if (show2dwall[i>>3]&pow2char[i&7])
1060 col = editorcolors[14] - (M32_THROB>>1);
1061
1062 if (m32_sideview)
1063 {
1064 if (wal->nextwall >= 0)
1065 {
1066 if (fz < fzn)
1067 col = editorcolors[7];
1068 else if (fz == fzn)
1069 col = editorcolors[4];
1070 }
1071 }
1072
1073 editorDraw2dCircle(halfxdim16+x1, midydim16+y1, pointsize, 16384, col);
1074 }
1075 }
1076
editorGet2dSpriteColor(int32_t spr)1077 int32_t editorGet2dSpriteColor(int32_t spr)
1078 {
1079 int const picnum = sprite[spr].picnum;
1080 int pal = sprite[spr].pal;
1081 int const tilecol = tilecols[picnum];
1082
1083 if (palookup[pal] == NULL || (tilecol && palookup[pal][tilecol] == 0))
1084 pal = 0;
1085
1086 if (tilecol) return palookup[pal][tilecol];
1087
1088 if (!waloff[picnum]) tileLoad(picnum);
1089 if (!waloff[picnum]) return editorcolors[3];
1090
1091 // Calculate 2D mode tile color.
1092
1093 uint32_t cols[256];
1094
1095 Bmemset(cols, 0, sizeof(cols));
1096
1097 const uint8_t *const texbuf = (const uint8_t *) waloff[picnum];
1098
1099 for (bssize_t i = 0; i < tilesiz[picnum].x * tilesiz[picnum].y; i++)
1100 cols[texbuf[i]]++;
1101
1102 unsigned col = 0, cnt = 0;
1103
1104 for (bssize_t i = 0; i < 240; i++)
1105 if (cols[i] > cnt)
1106 col = i, cnt = cols[i];
1107
1108 while (col < 240 && curpalette[col+1].r > curpalette[col].r)
1109 col++;
1110
1111 tilecols[picnum] = col - 4;
1112
1113 return palookup[pal][tilecols[picnum]];
1114 }
1115
editorDraw2DBloodMarker(int x,int y,int col)1116 static void editorDraw2DBloodMarker(int x, int y, int col)
1117 {
1118 editorDraw2dCircle(x, y, 4, 16384, col);
1119 editorDraw2dLine(x-2, y-2, x+2, y+2, col);
1120 editorDraw2dLine(x+2, y-2, x-2, y+2, col);
1121 #if 0
1122 plotpixel(x-4, y-1, col);
1123 plotpixel(x-4, y-0, col);
1124 plotpixel(x-4, y+1, col);
1125
1126 plotpixel(x-3, y-3, col);
1127 plotpixel(x-3, y-2, col);
1128 plotpixel(x-3, y+2, col);
1129 plotpixel(x-3, y+3, col);
1130
1131 plotpixel(x-2, y-3, col);
1132 plotpixel(x-2, y-2, col);
1133 plotpixel(x-2, y+2, col);
1134 plotpixel(x-2, y+3, col);
1135
1136 plotpixel(x-1, y-4, col);
1137 plotpixel(x-1, y-1, col);
1138 plotpixel(x-1, y+1, col);
1139 plotpixel(x-1, y+4, col);
1140
1141 plotpixel(x-0, y-4, col);
1142 plotpixel(x-0, y-0, col);
1143 plotpixel(x-0, y+4, col);
1144
1145 plotpixel(x+1, y-4, col);
1146 plotpixel(x+1, y-1, col);
1147 plotpixel(x+1, y+1, col);
1148 plotpixel(x+1, y+4, col);
1149
1150 plotpixel(x+2, y-3, col);
1151 plotpixel(x+2, y-2, col);
1152 plotpixel(x+2, y+2, col);
1153 plotpixel(x+2, y+3, col);
1154
1155 plotpixel(x+3, y-3, col);
1156 plotpixel(x+3, y-2, col);
1157 plotpixel(x+3, y+2, col);
1158 plotpixel(x+3, y+3, col);
1159
1160 plotpixel(x+4, y-1, col);
1161 plotpixel(x+4, y-0, col);
1162 plotpixel(x+4, y+1, col);
1163 #endif
1164 }
1165
editorDraw2dSpriteBloodMarker(int32_t j,int32_t posxe,int32_t posye,int32_t posze,int32_t zoome)1166 static void editorDraw2dSpriteBloodMarker(int32_t j, int32_t posxe, int32_t posye, int32_t posze, int32_t zoome)
1167 {
1168 int32_t x1, y1, x2, y2;
1169 int col;
1170
1171 const spritetype *const spr = &sprite[j];
1172
1173 int16_t const angofs = m32_sideview ? m32_sideang : 0;
1174 uint8_t const spritecol = sectorhighlight == spr->owner ? 15 : 14;
1175
1176 // KEEPINSYNC build.c: drawspritelabel()
1177 if (spr->sectnum<0)
1178 col = editorcolors[4]; // red
1179 else
1180 col = editorcolors[spritecol];
1181
1182 if (editstatus == 1)
1183 {
1184 if (pointhighlight >= 16384 &&
1185 (j+16384 == pointhighlight ||
1186 (!m32_sideview && (spr->x == sprite[pointhighlight-16384].x &&
1187 spr->y == sprite[pointhighlight-16384].y))))
1188 {
1189 if (spritecol >= 8 && spritecol <= 15)
1190 col -= bloodhack ? M32_THROB>>2 : M32_THROB>>1;
1191 else
1192 col += M32_THROB>>2;
1193 }
1194 else // if (highlightcnt > 0)
1195 {
1196 if (show2dsprite[j>>3]&pow2char[j&7])
1197 col = editorcolors[14] - (M32_THROB>>1);
1198 }
1199 }
1200
1201 editorGet2dScreenCoordinates(&x1, &y1, spr->x-posxe, spr->y-posye, zoome);
1202 // tempint = ((midydim16+y1)*bytesperline)+(halfxdim16+x1)+frameplace;
1203
1204 if (m32_sideview)
1205 y1 += getscreenvdisp(spr->z-posze, zoome);
1206
1207 int f = mulscale12(128, zoome);
1208
1209 if ((halfxdim16+x1 >= -f) && (halfxdim16+x1 < xdim+f) &&
1210 (midydim16+y1 >= -f) && (midydim16+y1 < ydim16+f))
1211 {
1212 if (spr->statnum == 10)
1213 {
1214 switch (spr->type)
1215 {
1216 case 3:
1217 case 4:
1218 editorDraw2DBloodMarker(halfxdim16+x1, midydim16+y1, col);
1219 break;
1220
1221 case 5:
1222 case 6:
1223 editorDraw2DBloodMarker(halfxdim16+x1, midydim16+y1, col);
1224 x2 = mulscale11(sintable[(spr->ang+angofs+2560)&2047], zoome) / 768;
1225 y2 = mulscale11(sintable[(spr->ang+angofs+2048)&2047], zoome) / 768;
1226 y2 = scalescreeny(y2);
1227
1228 editorDraw2dLineMiddle(x1, y1, x1+x2, y1+y2, col);
1229 break;
1230 }
1231 }
1232 else
1233 editorDraw2DBloodMarker(halfxdim16+x1, midydim16+y1, col);
1234 }
1235 }
1236
editorDraw2dSprite(int32_t j,int32_t posxe,int32_t posye,int32_t posze,int32_t zoome)1237 static void editorDraw2dSprite(int32_t j, int32_t posxe, int32_t posye, int32_t posze, int32_t zoome)
1238 {
1239 int32_t x1, y1, x2, y2;
1240 int col;
1241
1242 auto const spr = &sprite[j];
1243 int16_t const blocking = (spr->cstat&1), hitblocking = (spr->cstat&256);
1244 int16_t const flooraligned = (spr->cstat&48) >= 32, wallaligned = (spr->cstat&48) == 16;
1245
1246 int16_t const angofs = m32_sideview ? m32_sideang : 0;
1247 uint8_t spritecol = spritecol2d[spr->picnum][blocking];
1248
1249 if (bloodhack)
1250 {
1251 if (spr->statnum == 10 || spr->statnum == 12)
1252 {
1253 editorDraw2dSpriteBloodMarker(j, posxe, posye, posze, zoome);
1254 return;
1255 }
1256 if (spr->cstat & 256)
1257 spritecol = 5;
1258 if (spr->cstat & 0x8000)
1259 spritecol = 8;
1260 if (spr->cstat & 0x2000)
1261 spritecol = 9;
1262 if (spr->cstat & 0x4000)
1263 spritecol = 10;
1264 }
1265
1266 // KEEPINSYNC build.c: drawspritelabel()
1267 if (spr->sectnum<0)
1268 col = editorcolors[4]; // red
1269 else
1270 col = spritecol ? editorcolors[spritecol] : blocking ? editorcolors[5] : editorGet2dSpriteColor(j);
1271
1272 if (editstatus == 1)
1273 {
1274 if (pointhighlight >= 16384 &&
1275 (j+16384 == pointhighlight ||
1276 (!m32_sideview && (spr->x == sprite[pointhighlight-16384].x &&
1277 spr->y == sprite[pointhighlight-16384].y))))
1278 {
1279 if (spritecol >= 8 && spritecol <= 15)
1280 col -= bloodhack ? M32_THROB>>2 : M32_THROB>>1;
1281 else
1282 col += M32_THROB>>2;
1283 }
1284 else // if (highlightcnt > 0)
1285 {
1286 if (show2dsprite[j>>3]&pow2char[j&7])
1287 col = editorcolors[14] - (M32_THROB>>1);
1288 }
1289 }
1290
1291 editorGet2dScreenCoordinates(&x1, &y1, spr->x-posxe, spr->y-posye, zoome);
1292 // tempint = ((midydim16+y1)*bytesperline)+(halfxdim16+x1)+frameplace;
1293
1294 if (m32_sideview)
1295 y1 += getscreenvdisp(spr->z-posze, zoome);
1296
1297 int f = mulscale12(128, zoome);
1298
1299 if ((halfxdim16+x1 >= -f) && (halfxdim16+x1 < xdim+f) &&
1300 (midydim16+y1 >= -f) && (midydim16+y1 < ydim16+f))
1301 {
1302 if (zoome > 512 && spr->clipdist > 32)
1303 editorDraw2dCircle(halfxdim16+x1, midydim16+y1, mulscale14(spr->clipdist<<2, zoome), 16384, col);
1304
1305 editorDraw2dCircle(halfxdim16+x1, midydim16+y1, 4, 16384, col);
1306
1307 x2 = mulscale11(sintable[(spr->ang+angofs+2560)&2047], zoome) / 768;
1308 y2 = mulscale11(sintable[(spr->ang+angofs+2048)&2047], zoome) / 768;
1309 y2 = scalescreeny(y2);
1310
1311 editorDraw2dLineMiddle(x1, y1, x1+x2, y1+y2, col);
1312
1313 if (hitblocking)
1314 {
1315 editorDraw2dLineMiddle(x1, y1+1, x1+x2, y1+y2+1, col);
1316 editorDraw2dLineMiddle(x1, y1-1, x1+x2, y1+y2-1, col);
1317 editorDraw2dLineMiddle(x1-1, y1, x1+x2-1, y1+y2, col);
1318 editorDraw2dLineMiddle(x1+1, y1, x1+x2+1, y1+y2, col);
1319 }
1320
1321 if (flooraligned)
1322 {
1323 int32_t heinum = spriteGetSlope(j);
1324 int32_t ratio = ksqrt(heinum * heinum + 16777216);
1325 int32_t ratioz = divscale12(heinum, ratio);
1326 int32_t yspan = mulscale6(tilesiz[spr->picnum].y, spr->yrepeat);
1327 int32_t fx = mulscale10(mulscale6(tilesiz[spr->picnum].x, spr->xrepeat), zoome) >> 1;
1328 int32_t fy = divscale12(mulscale10(yspan, zoome) >> 1, ratio);
1329 int32_t fz = getscreenvdisp(mulscale4(yspan, ratioz) >> 1, zoome);
1330 int32_t co[4][3], ii, in;
1331 int32_t sinang = sintable[(spr->ang+angofs+1536)&2047];
1332 int32_t cosang = sintable[(spr->ang+angofs+1024)&2047];
1333 int32_t r, s;
1334
1335 co[0][0] = co[3][0] = -fx;
1336 co[0][1] = co[1][1] = -fy;
1337 co[0][2] = co[1][2] = -fz;
1338 co[1][0] = co[2][0] = fx;
1339 co[2][1] = co[3][1] = fy;
1340 co[2][2] = co[3][2] = fz;
1341
1342 for (ii=3; ii>=0; ii--)
1343 {
1344 r = mulscale14(cosang, co[ii][0]) - mulscale14(sinang, co[ii][1]);
1345 s = mulscale14(sinang, co[ii][0]) + mulscale14(cosang, co[ii][1]);
1346 s = scalescreeny(s);
1347 if (m32_sideview)
1348 s += co[ii][2];
1349 co[ii][0] = r;
1350 co[ii][1] = s;
1351 }
1352 drawlinepat = 0xcfcfcfcf;
1353 for (ii=3; ii>=0; ii--)
1354 {
1355 in = (ii+1)&3;
1356 editorDraw2dLineMiddle(x1+co[ii][0], y1-co[ii][1], x1+co[in][0], y1-co[in][1], col);
1357 if (hitblocking)
1358 {
1359 editorDraw2dLineMiddle(x1+co[ii][0], y1-co[ii][1]+1, x1+co[in][0], y1-co[in][1]+1, col);
1360 editorDraw2dLineMiddle(x1+co[ii][0], y1-co[ii][1]-1, x1+co[in][0], y1-co[in][1]-1, col);
1361 editorDraw2dLineMiddle(x1+co[ii][0]+1, y1-co[ii][1], x1+co[in][0]+1, y1-co[in][1], col);
1362 editorDraw2dLineMiddle(x1+co[ii][0]-1, y1-co[ii][1], x1+co[in][0]-1, y1-co[in][1], col);
1363 }
1364 editorDraw2dLineMiddle(x1, y1, x1 + co[in][0], y1 - co[in][1], col);
1365 }
1366 drawlinepat = 0xffffffff;
1367 }
1368 else if (wallaligned)
1369 {
1370 int32_t fx = mulscale6(tilesiz[spr->picnum].x, spr->xrepeat);
1371 int32_t one=(((spr->ang+angofs+256)&512) == 0), no=!one;
1372
1373 x2 = mulscale11(sintable[(spr->ang+angofs+2560)&2047], zoome) / 6144;
1374 y2 = mulscale11(sintable[(spr->ang+angofs+2048)&2047], zoome) / 6144;
1375 y2 = scalescreeny(y2);
1376
1377 editorDraw2dLineMiddle(x1, y1, x1+x2, y1+y2, col);
1378 if (!(spr->cstat&64)) // not 1-sided
1379 {
1380 editorDraw2dLineMiddle(x1, y1, x1-x2, y1-y2, col);
1381 if (hitblocking)
1382 {
1383 editorDraw2dLineMiddle(x1-no, y1-one, x1-x2-no, y1-y2-one, col);
1384 editorDraw2dLineMiddle(x1+no, y1+one, x1-x2+no, y1-y2+one, col);
1385 }
1386 }
1387
1388 if (hitblocking)
1389 {
1390 editorDraw2dLineMiddle(x1-no, y1-one, x1+x2-no, y1+y2-one, col);
1391 editorDraw2dLineMiddle(x1+no, y1+one, x1+x2+no, y1+y2+one, col);
1392 }
1393
1394
1395 x2 = mulscale13(sintable[(spr->ang+angofs+1024)&2047], zoome) * fx / 4096;
1396 y2 = mulscale13(sintable[(spr->ang+angofs+512)&2047], zoome) * fx / 4096;
1397 y2 = scalescreeny(y2);
1398
1399 editorDraw2dLineMiddle(x1, y1, x1-x2, y1-y2, col);
1400 editorDraw2dLineMiddle(x1, y1, x1+x2, y1+y2, col);
1401
1402 if (hitblocking)
1403 {
1404 editorDraw2dLineMiddle(x1+1, y1, x1+x2+1, y1+y2, col);
1405 editorDraw2dLineMiddle(x1-1, y1, x1-x2-1, y1-y2, col);
1406 editorDraw2dLineMiddle(x1-1, y1, x1+x2-1, y1+y2, col);
1407 editorDraw2dLineMiddle(x1+1, y1, x1-x2+1, y1-y2, col);
1408
1409 editorDraw2dLineMiddle(x1, y1-1, x1+x2, y1+y2-1, col);
1410 editorDraw2dLineMiddle(x1, y1+1, x1-x2, y1-y2+1, col);
1411 editorDraw2dLineMiddle(x1, y1+1, x1+x2, y1+y2+1, col);
1412 editorDraw2dLineMiddle(x1, y1-1, x1-x2, y1-y2-1, col);
1413 }
1414 }
1415 }
1416 }
1417
1418 //
1419 // draw2dscreen
1420 //
1421
1422 static int8_t tempbuf[(MAXWALLS+7)>>3];
1423
editorDraw2dScreen(const vec3_t * pos,int16_t cursectnum,int16_t ange,int32_t zoome,int16_t gride)1424 void editorDraw2dScreen(const vec3_t *pos, int16_t cursectnum, int16_t ange, int32_t zoome, int16_t gride)
1425 {
1426 int32_t i, x1, y1;
1427 int16_t angofs = m32_sideview ? m32_sideang : 0;
1428
1429 int32_t posxe=pos->x, posye=pos->y, posze=pos->z;
1430 uint8_t *graybitmap = (uint8_t *) tempbuf;
1431 int32_t alwaysshowgray = get_alwaysshowgray();
1432
1433 if (in3dmode()) return;
1434
1435 editorSetup2dSideView();
1436
1437 videoBeginDrawing(); //{{{
1438
1439
1440 if (editstatus == 0)
1441 {
1442 // faketimerhandler();
1443 clear2dscreen();
1444
1445 // faketimerhandler();
1446 editorDraw2dGrid(posxe, posye, posze, cursectnum, ange, zoome, gride);
1447 }
1448
1449 faketimerhandler();
1450
1451 m32_swcnt = 0;
1452
1453 if (numgraysects==0)
1454 Bmemset(graybitmap, 0, (numwalls+7)>>3);
1455 else
1456 {
1457 for (i=0; i<numwalls; i++)
1458 {
1459 int32_t j = wall[i].nextwall;
1460 if ((graywallbitmap[i>>3]&pow2char[i&7]) && (j < 0 || (graywallbitmap[j>>3]&pow2char[j&7])))
1461 graybitmap[i>>3] |= pow2char[i&7];
1462 else
1463 graybitmap[i>>3] &= ~pow2char[i&7];
1464 }
1465 }
1466
1467 if (!m32_sideview)
1468 {
1469 #ifndef YAX_ENABLE
1470 for (i=numwalls-1; i>=0; i--)
1471 editorDraw2dWall(i, posxe, posye, posze, zoome, 0);
1472 #else
1473 if (alwaysshowgray)
1474 for (i=numwalls-1; i>=0; i--)
1475 if (graybitmap[i>>3]&pow2char[i&7])
1476 editorDraw2dWall(i, posxe, posye, posze, zoome, 1+2);
1477
1478 for (i=numwalls-1; i>=0; i--)
1479 if ((graybitmap[i>>3]&pow2char[i&7])==0)
1480 editorDraw2dWall(i, posxe, posye, posze, zoome, 2);
1481 #endif
1482 }
1483 else
1484 {
1485 int32_t j = 0;
1486
1487 for (i=0; i<numsectors; i++)
1488 for (j=sector[i].wallptr; j<sector[i].wallptr+sector[i].wallnum; j++)
1489 {
1490 m32_wallsprite[m32_swcnt++] = j;
1491 editorGet2dSideViewDistance(j, i);
1492 }
1493
1494 // j = sector[numsectors-1].wallptr + sector[numsectors-1].wallnum
1495 for (; j < numwalls; j++) // new walls ...
1496 {
1497 m32_wallsprite[m32_swcnt++] = j;
1498 editorGet2dSideViewDistance(j, 0);
1499 }
1500 }
1501
1502 faketimerhandler();
1503
1504 if (zoome >= 256 || highlightcnt>0)
1505 for (bssize_t j=0; j<MAXSPRITES; j++)
1506 if (sprite[j].statnum<MAXSTATUS)
1507 {
1508 // if sprite is highlighted, always draw it
1509 if ((show2dsprite[j>>3]&pow2char[j&7])==0)
1510 {
1511 if (!m32_sideview && sprite[j].sectnum >= 0)
1512 YAX_SKIPSECTOR(sprite[j].sectnum);
1513
1514 if (zoome<256)
1515 continue;
1516 }
1517
1518 if (!m32_sideview)
1519 editorDraw2dSprite(j, posxe, posye, posze, zoome);
1520 else
1521 {
1522 m32_wallsprite[m32_swcnt++] = MAXWALLS+j;
1523 editorGet2dSideViewDistance(MAXWALLS+j, -1);
1524 }
1525 }
1526
1527 faketimerhandler();
1528
1529 if (m32_sideview)
1530 {
1531 qsort(m32_wallsprite, m32_swcnt, sizeof(int16_t), &editorCompare2dSideViewPoints);
1532
1533 for (i=0; i<m32_swcnt; i++) // shouldn't it go the other way around?
1534 {
1535 int32_t j = m32_wallsprite[i];
1536 if (j<MAXWALLS)
1537 {
1538 if (alwaysshowgray || !(graybitmap[j>>3]&pow2char[j&7]))
1539 editorDraw2dWall(j, posxe, posye, posze, zoome, !!(graybitmap[j>>3]&pow2char[j&7]));
1540 }
1541 else
1542 {
1543 if (!alwaysshowgray && sprite[j-MAXWALLS].sectnum>=0)
1544 YAX_SKIPSECTOR(sprite[j-MAXWALLS].sectnum);
1545
1546 editorDraw2dSprite(j-MAXWALLS, posxe, posye, posze, zoome);
1547 }
1548 }
1549
1550 faketimerhandler();
1551 }
1552
1553 #if 0
1554 {
1555 int32_t xx, yy, xx2, yy2;
1556 screencoords(&xx, &yy, -posxe, -posye, zoome);
1557 screencoords(&xx2, &yy2, (m32_viewplane.x)-posxe, (m32_viewplane.y)-posye, zoome);
1558 if (m32_sideview)
1559 yy2 += getscreenvdisp((m32_viewplane.z<<4)-posze, zoome);
1560
1561 drawcircle16(halfxdim16+xx, midydim16+yy, 2, 16384, editorcolors[4]); //red
1562 drawcircle16(halfxdim16+xx2, midydim16+yy2, 2, 16384, editorcolors[14]); //yellow
1563 drawline16mid(xx, yy, xx2, yy2, editorcolors[15]);
1564 }
1565 #endif
1566
1567 x1 = mulscale11(sintable[(ange+angofs+2560)&2047], zoome) / 768; //Draw white arrow
1568 y1 = mulscale11(sintable[(ange+angofs+2048)&2047], zoome) / 768;
1569
1570 i = scalescreeny(x1);
1571 int32_t j = scalescreeny(y1);
1572
1573 editorDraw2dLineMiddle(x1, j, -x1, -j, editorcolors[15]);
1574 editorDraw2dLineMiddle(x1, j, +y1, -i, editorcolors[15]);
1575 editorDraw2dLineMiddle(x1, j, -y1, +i, editorcolors[15]);
1576
1577
1578 videoEndDrawing(); //}}}
1579 }
1580
1581 //
1582 // setpolymost2dview
1583 // Sets OpenGL for 2D drawing
1584 //
polymostSet2dView(void)1585 void polymostSet2dView(void)
1586 {
1587 #ifdef USE_OPENGL
1588 if (videoGetRenderMode() < REND_POLYMOST) return;
1589
1590 glViewport(0, 0, xdim, ydim);
1591
1592 glMatrixMode(GL_PROJECTION);
1593 glLoadIdentity();
1594 glOrtho(0, xdim, ydim, 0, -1, 1);
1595
1596 if (videoGetRenderMode() == REND_POLYMER)
1597 {
1598 glMatrixMode(GL_MODELVIEW);
1599 glLoadIdentity();
1600 }
1601
1602 polymost2d = 1;
1603
1604 glDisable(GL_DEPTH_TEST);
1605 glDisable(GL_BLEND);
1606 #endif
1607 }
1608