// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman // Ken Silverman's official web site: "http://www.advsys.net/ken" // See the included license file "BUILDLIC.TXT" for license info. // // This file has been modified from Ken Silverman's original release // by Jonathon Fowler (jf@jonof.id.au) // by the EDuke32 team (development@voidpoint.com) #include "build.h" #include "editor.h" int32_t editorgridextent = 131072; ////////// editor side view ////////// int32_t m32_sideview = 0; int32_t m32_sideelev = 256; // elevation in BUILD degrees, 0..512 int16_t m32_sideang = 200; // azimuth, 0..2047 int32_t m32_sidecos, m32_sidesin; int32_t m32_swcnt; int32_t m32_wallscreenxy[MAXWALLS][2]; int16_t m32_wallsprite[MAXWALLS+MAXSPRITES]; static int32_t m32_sidedist[MAXWALLS+MAXSPRITES]; static vec3_t m32_viewplane; static void drawpixel_safe(void *s, char a) { #if defined __GNUC__ if (__builtin_expect((intptr_t) s >= frameplace && (intptr_t) s < frameplace+bytesperline*ydim, 1)) #else if ((intptr_t) s >= frameplace && (intptr_t) s < frameplace+bytesperline*ydim) #endif drawpixel(s, a); #ifdef DEBUGGINGAIDS else { const char c = editorcolors[15]; drawpixel((intptr_t *) frameplace, c); drawpixel((intptr_t *) frameplace+1, c); drawpixel((intptr_t *) frameplace+2, c); drawpixel((intptr_t *) frameplace+bytesperline, c); drawpixel((intptr_t *) frameplace+bytesperline+1, c); drawpixel((intptr_t *) frameplace+bytesperline+2, c); drawpixel((intptr_t *) frameplace+2*bytesperline, c); drawpixel((intptr_t *) frameplace+2*bytesperline+1, c); drawpixel((intptr_t *) frameplace+2*bytesperline+2, c); } #endif } // // plotpixel // void plotpixel(int32_t x, int32_t y, char col) { // XXX: if we ever want the editor to work under GL ES, find a replacement for the raster functions #if defined USE_OPENGL && !defined EDUKE32_GLES if (videoGetRenderMode() >= REND_POLYMOST && in3dmode()) { palette_t p = paletteGetColor(col); glRasterPos4i(x, y, 0, 1); glDrawPixels(1, 1, GL_RGB, GL_UNSIGNED_BYTE, &p); glRasterPos4i(0, 0, 0, 1); return; } #endif videoBeginDrawing(); //{{{ drawpixel_safe((void *) (ylookup[y]+x+frameplace), col); videoEndDrawing(); //}}} } void plotlines2d(const int32_t *xx, const int32_t *yy, int32_t numpoints, int col) { int32_t i; #ifdef USE_OPENGL if (videoGetRenderMode() >= REND_POLYMOST && in3dmode()) { palette_t p = paletteGetColor(col); polymost_useColorOnly(true); glBegin(GL_LINE_STRIP); glColor4ub(p.r, p.g, p.b, 1); for (i=0; i= 0) { if ((x1 >= wx2) || (x2 < wx1)) return; if (x1 < wx1) y1 += scale(wx1-x1, dy, dx), x1 = wx1; if (x2 > wx2) y2 += scale(wx2-x2, dy, dx), x2 = wx2; } else { if ((x2 >= wx2) || (x1 < wx1)) return; if (x2 < wx1) y2 += scale(wx1-x2, dy, dx), x2 = wx1; if (x1 > wx2) y1 += scale(wx2-x1, dy, dx), x1 = wx2; } if (dy >= 0) { if ((y1 >= wy2) || (y2 < wy1)) return; if (y1 < wy1) x1 += scale(wy1-y1, dx, dy), y1 = wy1; if (y2 > wy2) x2 += scale(wy2-y2, dx, dy), y2 = wy2; } else { if ((y2 >= wy2) || (y1 < wy1)) return; if (y2 < wy1) x2 += scale(wy1-y2, dx, dy), y2 = wy1; if (y1 > wy2) x1 += scale(wy2-y1, dx, dy), y1 = wy2; } glVertex2f((float) x1 * (1.f/4096.f), (float) y1 * (1.f/4096.f)); glVertex2f((float) x2 * (1.f/4096.f), (float) y2 * (1.f/4096.f)); glEnd(); polymost_useColorOnly(false); } #endif static void drawlinepixels(int32_t x1, int32_t y1, int32_t x2, int32_t y2, char col) { int32_t dx, dy, i, j, inc, plc, daend; intptr_t p; dx = x2-x1; dy = y2-y1; if (dx >= 0) { if ((x1 >= wx2) || (x2 < wx1)) return; if (x1 < wx1) y1 += scale(wx1-x1, dy, dx), x1 = wx1; if (x2 > wx2) y2 += scale(wx2-x2, dy, dx), x2 = wx2; } else { if ((x2 >= wx2) || (x1 < wx1)) return; if (x2 < wx1) y2 += scale(wx1-x2, dy, dx), x2 = wx1; if (x1 > wx2) y1 += scale(wx2-x1, dy, dx), x1 = wx2; } if (dy >= 0) { if ((y1 >= wy2) || (y2 < wy1)) return; if (y1 < wy1) x1 += scale(wy1-y1, dx, dy), y1 = wy1; if (y2 > wy2) x2 += scale(wy2-y2, dx, dy), y2 = wy2; } else { if ((y2 >= wy2) || (y1 < wy1)) return; if (y2 < wy1) x2 += scale(wy1-y2, dx, dy), y2 = wy1; if (y1 > wy2) x1 += scale(wy2-y1, dx, dy), y1 = wy2; } if (klabs(dx) >= klabs(dy)) { if (dx == 0) return; if (dx < 0) { i = x1; x1 = x2; x2 = i; i = y1; y1 = y2; y2 = i; } inc = divscale12(dy, dx); plc = y1+mulscale12((2047-x1)&4095, inc); i = ((x1+2048)>>12); daend = ((x2+2048)>>12); videoBeginDrawing(); //{{{ for (; i>12); if ((j >= startumost[i]) && (j < startdmost[i])) drawpixel_safe((void *) (frameplace+ylookup[j]+i), col); plc += inc; } videoEndDrawing(); //}}} } else { if (dy < 0) { i = x1; x1 = x2; x2 = i; i = y1; y1 = y2; y2 = i; } inc = divscale12(dx, dy); plc = x1+mulscale12((2047-y1)&4095, inc); i = ((y1+2048)>>12); daend = ((y2+2048)>>12); videoBeginDrawing(); //{{{ p = ylookup[i]+frameplace; for (; i>12); if ((i >= startumost[j]) && (i < startdmost[j])) drawpixel_safe((void *) (j+p), col); plc += inc; p += ylookup[1]; } videoEndDrawing(); //}}} } } void drawlinergb(int32_t x1, int32_t y1, int32_t x2, int32_t y2, palette_t p) { #ifdef USE_OPENGL if (videoGetRenderMode() >= REND_POLYMOST) { drawlinegl(x1, y1, x2, y2, p); return; } #endif char const col = palookup[0][p.f]; drawlinepixels(x1, y1, x2, y2, col); } void renderDrawLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, char col) { col = palookup[0][col]; #ifdef USE_OPENGL if (videoGetRenderMode() >= REND_POLYMOST) { palette_t p = paletteGetColor(col); p.f = col; drawlinegl(x1, y1, x2, y2, p); return; } #endif drawlinepixels(x1, y1, x2, y2, col); } //static void attach_here() {} // // drawline16 // // JBF: Had to add extra tests to make sure x-coordinates weren't winding up -'ve // after clipping or crashes would ensue uint32_t drawlinepat = 0xffffffff; int32_t editorDraw2dLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int col) { //int32_t odx,ody; //int32_t ox1=x1,oy1=y1, ox2=x2,oy2=y2; vec2_t d = { x2-x1, y2-y1 }; //odx=dx; //ody=dy; if (d.x < 0) { swaplong(&x1, &x2); swaplong(&y1, &y2); } if (x1 >= xdim || x2 < 0) return 0; if (x1 < 0) { if (d.y) y1 += scale(0-x1, d.y, d.x); x1 = 0; } if (x2 >= xdim) { if (d.y) y2 += scale(xdim-1-x2, d.y, d.x); x2 = xdim-1; } if ((d.x < 0 && d.y >= 0) || (d.y < 0 && d.x >= 0)) { swaplong(&x1, &x2); swaplong(&y1, &y2); } if (y1 >= ydim16 || y2 < 0) return 0; if (y1 < 0) { if (d.x) x1 = clamp(x1 + scale(0 - y1, d.x, d.y), 0, xdim - 1); y1 = 0; } if (y2 >= ydim16) { if (d.x) x2 = clamp(x2 + scale(ydim16-1-y2, d.x, d.y), 0, xdim-1); y2 = ydim16-1; } if (d.y < 0) { swaplong(&x1, &x2); swaplong(&y1, &y2); } //if (ox1||ox2||oy1||oy2) // if (x1<0||x1>=xdim || y2<0||y2>=ydim) // attach_here(); d.x = klabs(x2-x1)+1; d.y = klabs(y2-y1)+1; if ((d.x >= d.y && x2 < x1) || (d.x < d.y && y2 < y1)) { swaplong(&x1, &x2); swaplong(&y1, &y2); } int pinc, inc = 1; videoBeginDrawing(); //{{{ intptr_t p = (y1*bytesperline)+x1+frameplace; if (d.x >= d.y) { pinc = (y2 > y1) ? bytesperline : -bytesperline; } else { pinc = (x2 > x1) ? 1 : -1; swaplong(&d.x, &d.y); inc = bytesperline; } int const trans = (col < 0); if (trans) { col = -col; if (drawlinepat == 0xffffffff) { for (bssize_t i=d.x, df=0; i>0; i--) { drawtranspixel((char *) p, col); df += d.y; if (df >= d.x) { df -= d.x; p += pinc; } p += inc; } } else { uint32_t patc = UINT_MAX; for (bssize_t i=d.x, df=0; i>0; i--) { if (drawlinepat & pow2long[(++patc)&31]) drawtranspixel((char *) p, col); df += d.y; if (df >= d.x) { df -= d.x; p += pinc; } p += inc; } } videoEndDrawing(); //}}} return 1; } if (inc == 1 && d.y == 1 && drawlinepat == 0xffffffff) clearbufbyte((void *) p, d.x, ((int32_t) col<<24)|((int32_t) col<<16)|((int32_t) col<<8)|col); else if (drawlinepat == 0xffffffff) { for (bssize_t i=d.x, df=0; i>0; i--) { drawpixel((char *) p, col); df += d.y; if (df >= d.x) { df -= d.x; p += pinc; } p += inc; } } else { uint32_t patc = UINT_MAX; for (bssize_t i=d.x, df=0; i>0; i--) { if (drawlinepat & pow2long[(++patc)&31]) drawpixel((char *) p, col); df += d.y; if (df >= d.x) { df -= d.x; p += pinc; } p += inc; } } videoEndDrawing(); //}}} return 1; } static FORCE_INLINE void editorDraw2dLineMiddle(int32_t x1, int32_t y1, int32_t x2, int32_t y2, char col) { editorDraw2dLine(halfxdim16+x1, midydim16+y1, halfxdim16+x2, midydim16+y2, col); } // eccen: eccentricity of the ellipse, // 16384: circle // <16384: shrink in y // >16384: grow in y void editorDraw2dCircle(int32_t x1, int32_t y1, int32_t r, int32_t eccen, char col) { if (eccen != 16384) { // JonoF's rough approximation of a circle int32_t l, spx, spy, lpx, lpy, px, py; spx = lpx = x1 + mulscale14(r, sintable[0]); spy = lpy = y1 + mulscale14(eccen, mulscale14(r, sintable[512])); for (l=64; l<2048; l+=64) { px = x1 + mulscale14(r, sintable[l]); py = y1 + mulscale14(eccen, mulscale14(r, sintable[(l+512)&2047])); editorDraw2dLine(lpx, lpy, px, py, col); lpx = px; lpy = py; } editorDraw2dLine(lpx, lpy, spx, spy, col); return; } if (r < 0) r = -r; if (x1+r < 0 || y1+r < 0 || x1-r >= xdim || y1-r >= ydim16) return; uint32_t const uxdim = xdim, uydim16 = ydim16; /* * d * 6 | 7 * \ | / * 5 \|/ 8 * c----+----a * 4 /|\ 1 * / | \ * 3 | 2 * b */ videoBeginDrawing(); intptr_t const p = (y1*bytesperline)+x1+frameplace; uint32_t patc = UINT_MAX; if (drawlinepat == 0xffffffff || drawlinepat & pow2long[(++patc)&31]) { if ((uint32_t) y1 < uydim16 && (uint32_t) (x1+r) < uxdim) drawpixel((char *) (p+r), col); // a if ((uint32_t) x1 < uxdim && (uint32_t) (y1+r) < uydim16) drawpixel((char *) (p+(r*bytesperline)), col); // b if ((uint32_t) y1 < uydim16 && (uint32_t) (x1-r) < uxdim) drawpixel((char *) (p-r), col); // c if ((uint32_t) x1 < uxdim && (uint32_t) (y1-r) < uydim16) drawpixel((char *) (p-(r*bytesperline)), col); // d } int32_t xp = 0, yp = r; int32_t d = 1 - r, de = 2, dse = 5 - (r << 1); if (drawlinepat != 0xffffffff) { do { if (d < 0) { d += de; dse += 2; } else { d += dse; dse += 4; yp--; } xp++; de += 2; int32_t const ypbpl = yp*bytesperline; int32_t const xpbpl = xp*bytesperline; if (drawlinepat & pow2long[(++patc) & 31]) { if ((uint32_t) (x1 + yp) < uxdim && (uint32_t) (y1 + xp) < uydim16) drawpixel_safe((char *) (p + yp + xpbpl), col); // 1 if ((uint32_t) (x1 + xp) < uxdim && (uint32_t) (y1 + yp) < uydim16) drawpixel_safe((char *) (p + xp + ypbpl), col); // 2 if ((uint32_t) (x1 - xp) < uxdim && (uint32_t) (y1 + yp) < uydim16) drawpixel_safe((char *) (p - xp + ypbpl), col); // 3 if ((uint32_t) (x1 - yp) < uxdim && (uint32_t) (y1 + xp) < uydim16) drawpixel_safe((char *) (p - yp + xpbpl), col); // 4 if ((uint32_t) (x1 - yp) < uxdim && (uint32_t) (y1 - xp) < uydim16) drawpixel_safe((char *) (p - yp - xpbpl), col); // 5 if ((uint32_t) (x1 - xp) < uxdim && (uint32_t) (y1 - yp) < uydim16) drawpixel_safe((char *) (p - xp - ypbpl), col); // 6 if ((uint32_t) (x1 + xp) < uxdim && (uint32_t) (y1 - yp) < uydim16) drawpixel_safe((char *) (p + xp - ypbpl), col); // 7 if ((uint32_t) (x1 + yp) < uxdim && (uint32_t) (y1 - xp) < uydim16) drawpixel_safe((char *) (p + yp - xpbpl), col); // 8 } } while (yp > xp); videoEndDrawing(); return; } do { if (d < 0) { d += de; dse += 2; } else { d += dse; dse += 4; yp--; } xp++; de += 2; int32_t const ypbpl = yp*bytesperline; int32_t const xpbpl = xp*bytesperline; if ((uint32_t) (x1 + yp) < uxdim && (uint32_t) (y1 + xp) < uydim16) drawpixel_safe((char *) (p + yp + xpbpl), col); // 1 if ((uint32_t) (x1 + xp) < uxdim && (uint32_t) (y1 + yp) < uydim16) drawpixel_safe((char *) (p + xp + ypbpl), col); // 2 if ((uint32_t) (x1 - xp) < uxdim && (uint32_t) (y1 + yp) < uydim16) drawpixel_safe((char *) (p - xp + ypbpl), col); // 3 if ((uint32_t) (x1 - yp) < uxdim && (uint32_t) (y1 + xp) < uydim16) drawpixel_safe((char *) (p - yp + xpbpl), col); // 4 if ((uint32_t) (x1 - yp) < uxdim && (uint32_t) (y1 - xp) < uydim16) drawpixel_safe((char *) (p - yp - xpbpl), col); // 5 if ((uint32_t) (x1 - xp) < uxdim && (uint32_t) (y1 - yp) < uydim16) drawpixel_safe((char *) (p - xp - ypbpl), col); // 6 if ((uint32_t) (x1 + xp) < uxdim && (uint32_t) (y1 - yp) < uydim16) drawpixel_safe((char *) (p + xp - ypbpl), col); // 7 if ((uint32_t) (x1 + yp) < uxdim && (uint32_t) (y1 - xp) < uydim16) drawpixel_safe((char *) (p + yp - xpbpl), col); // 8 } while (yp > xp); videoEndDrawing(); } // // clear2dscreen // void clear2dscreen(void) { int32_t const clearsz = (ydim16 <= ydim - STATUS2DSIZ2) ? ydim - STATUS2DSIZ2 : ydim; videoBeginDrawing(); //{{{ Bmemset((char *) frameplace, 0, bytesperline*clearsz); videoEndDrawing(); //}}} } ////////// editor side view ////////// int32_t scalescreeny(int32_t sy) { return (m32_sideview) ? mulscale14(sy, m32_sidesin) : sy; } // return screen coordinates for BUILD coords x and y (relative to current position) void editorGet2dScreenCoordinates(int32_t *xres, int32_t *yres, int32_t x, int32_t y, int32_t zoome) { vec2_t coord = { x, y }; if (m32_sideview) rotatepoint(zerovec, coord, m32_sideang, &coord); *xres = mulscale14(coord.x, zoome); *yres = scalescreeny(mulscale14(coord.y, zoome)); } #if 0 void invscreencoords(int32_t *dx, int32_t *dy, int32_t sx, int32_t sy, int32_t zoome) { if (m32_sidesin==0 || zoome==0) { *dx=0; *dy=0; return; } sy = divscale14(divscale14(sy, m32_sidesin), zoome); sx = divscale14(sx, zoome); rotatepoint(0, 0, sx, sy, -m32_sideang, dx, dy); } #endif // invscreencoords with sx==0 and sy==getscreenvdisp(dz, zoom) int32_t getinvdisplacement(int32_t *dx, int32_t *dy, int32_t dz) { if (m32_sidesin==0) return 1; dz = (((int64_t) dz * (int64_t) m32_sidecos)/(int64_t) m32_sidesin)>>4; vec2_t v[2] = { { 0, dz },{ *dx, *dy } }; rotatepoint(zerovec, v[0], -m32_sideang, &v[1]); *dx = v[1].x; *dy = v[1].y; return 0; } // return vertical screen coordinate displacement for BUILD z coord int32_t getscreenvdisp(int32_t bz, int32_t zoome) { return mulscale32(bz, zoome*m32_sidecos); } void editorSetup2dSideView(void) { if (m32_sideview) { m32_viewplane.x = 0; m32_viewplane.y = -512; m32_sidesin = sintable[m32_sideelev&2047]; m32_sidecos = sintable[(m32_sideelev+512)&2047]; rotatepoint(zerovec, *(vec2_t *) &m32_viewplane, -m32_sideang, (vec2_t *) &m32_viewplane); m32_viewplane.x = mulscale14(m32_viewplane.x, m32_sidecos); m32_viewplane.y = mulscale14(m32_viewplane.y, m32_sidecos); m32_viewplane.z = m32_sidesin>>5; } } static void editorGet2dSideViewDistance(int16_t sw, int16_t sect) { vec3_t *p; vec3_t v; if (sw>1; v.y = (wall[sw].y + wall[wall[sw].point2].y)>>1; v.z = getflorzofslope(sect, v.x, v.y); p = &v; } else p = (vec3_t *) &sprite[sw-MAXWALLS]; m32_sidedist[sw] = p->x*m32_viewplane.x + p->y*m32_viewplane.y + (p->z>>4)*m32_viewplane.z; } static int editorCompare2dSideViewPoints(const void *sw1, const void *sw2) { int32_t dist1 = m32_sidedist[B_UNBUF16(sw1)]; int32_t dist2 = m32_sidedist[B_UNBUF16(sw2)]; if (dist2>dist1) return 1; else if (dist1>dist2) return -1; // if (*sw1=0) - (wall[*sw1].nextwall>=0); return 0; } // // draw2dgrid // void editorDraw2dGrid(int32_t posxe, int32_t posye, int32_t posze, int16_t cursectnum, int16_t ange, int32_t zoome, int16_t gride) { int64_t i, xp1, yp1, xp2=0, yp2, tempy; UNREFERENCED_PARAMETER(ange); if (gride <= 0) return; videoBeginDrawing(); //{{{ if (m32_sideview) { int32_t sx1, sy1, sx2, sy2, dx=0, dy=0; int32_t xinc=0, yinc=2048>>gride, yofs; // yofs = getscreenvdisp((yinc-posze)&((yinc<<4)-1), zoome); if (cursectnum<0 || cursectnum>=numsectors) yofs = getscreenvdisp(-posze, zoome); else yofs = getscreenvdisp(getflorzofslope(cursectnum, posxe, posye)-posze, zoome); while (scalescreeny(mulscale14(yinc, zoome))==0 && gride>2) { gride--; yinc = 2048>>gride; } xp2 = xp1 = ((posxe + (1024 >> gride)) & -(((int64_t)(1)) << (11 - gride))); yp2 = yp1 = ((posye + (1024 >> gride)) & -(((int64_t)(1)) << (11 - gride))); do { if (xinc==0) { editorGet2dScreenCoordinates(&sx1, &sy1, -editorgridextent-posxe, yp2-posye, zoome); if (yp2 == yp1) { editorGet2dScreenCoordinates(&sx2, &sy2, editorgridextent-posxe, yp2-posye, zoome); dx = sx2-sx1; dy = sy2-sy1; } yp2 += yinc; } else // if (yinc==0) { editorGet2dScreenCoordinates(&sx1, &sy1, xp2-posxe, -editorgridextent-posye, zoome); if (xp2 == xp1) { editorGet2dScreenCoordinates(&sx2, &sy2, xp2-posxe, editorgridextent-posye, zoome); dx = sx2-sx1; dy = sy2-sy1; } xp2 += xinc; } i = editorDraw2dLine(halfxdim16+sx1, midydim16+sy1+yofs, halfxdim16+sx1+dx, midydim16+sy1+dy+yofs, editorcolors[25]); if (i==0 || (xp2<-editorgridextent || xp2>editorgridextent || yp2<-editorgridextent || yp2>editorgridextent)) { xp2 = xp1; yp2 = yp1; i = 1; if (yinc>0) yinc *= -1; else if (yinc<0) { xinc = -yinc; yinc = 0; } else if (xinc>0) xinc *= -1; else // if (xinc<0) i = 0; } } while (i); } else { // vertical lines yp1 = midydim16-mulscale14(posye+editorgridextent, zoome); if (yp1 < 0) yp1 = 0; yp2 = midydim16-mulscale14(posye-editorgridextent, zoome); if (yp2 >= ydim16) yp2 = ydim16-1; if ((yp1 < ydim16) && (yp2 >= 0) && (yp2 >= yp1)) { xp1 = halfxdim16-mulscale14(posxe+editorgridextent, zoome); for (i=-editorgridextent; i<=editorgridextent; i+=(2048>>gride)) { xp2 = xp1; xp1 = halfxdim16-mulscale14(posxe-i, zoome); if (xp1 >= xdim) break; if (xp1 >= 0) { if (xp1 != xp2) editorDraw2dLine(xp1, yp1, xp1, yp2, editorcolors[25]); } } if (i >= editorgridextent && xp1 < xdim) xp2 = xp1; if (xp2 >= 0 && xp2 < xdim) editorDraw2dLine(xp2, yp1, xp2, yp2, editorcolors[25]); } // horizontal lines xp1 = mulscale14(posxe+editorgridextent, zoome); xp2 = mulscale14(posxe-editorgridextent, zoome); tempy = 0x80000000l; for (i=-editorgridextent; i<=editorgridextent; i+=(2048>>gride)) { yp1 = ((posye-i)*zoome)>>14; if (yp1 != tempy) { if ((yp1 > midydim16-ydim16) && (yp1 <= midydim16)) { editorDraw2dLineMiddle(-xp1, -yp1, -xp2, -yp1, editorcolors[25]); tempy = yp1; } } } } videoEndDrawing(); //}}} } static void editorDraw2dWall(int32_t i, int32_t posxe, int32_t posye, int32_t posze, int32_t zoome, int32_t grayp) { const walltype *const wal = &wall[i]; int32_t j = wal->nextwall; #if 0 if (editstatus == 0) { if ((show2dwall[i>>3]&pow2char[i&7]) == 0) return; if ((j >= 0) && (i > j)) if ((show2dwall[j>>3]&pow2char[j&7]) > 0) return; } else #endif { if (!m32_sideview && !(grayp&2) && (j >= 0) && (i > j)) return; } char col; if (grayp&1) col = editorcolors[8]; else if (j < 0) col = (i == linehighlight) ? editorcolors[15] - M32_THROB : editorcolors[15]; else { if ((unsigned) wal->nextwall < MAXWALLS && ((wal->cstat^wall[j].cstat)&1)) col = editorcolors[2]; else if ((wal->cstat&1) != 0) col = editorcolors[5]; else col = editorcolors[4]; if (i == linehighlight || (linehighlight >= 0 && i == wall[linehighlight].nextwall)) col += M32_THROB>>2; } int const p2 = wal->point2; int32_t x1, y1, x2, y2; editorGet2dScreenCoordinates(&x1, &y1, wal->x-posxe, wal->y-posye, zoome); editorGet2dScreenCoordinates(&x2, &y2, wall[p2].x-posxe, wall[p2].y-posye, zoome); int64_t const dx = wal->x-wall[p2].x; int64_t const dy = wal->y-wall[p2].y; int64_t const dist = dx*dx + dy*dy; int const bothSidesHighlighted = ((show2dwall[i>>3]&pow2char[i&7]) && (show2dwall[p2>>3]&pow2char[p2&7])); if (dist > INT32_MAX) { col=editorcolors[9]; if (i == linehighlight || (linehighlight >= 0 && i == wall[linehighlight].nextwall)) col -= M32_THROB>>3; } else if ((showfirstwall && searchsector>=0 && (sector[searchsector].wallptr == i || sector[searchsector].wallptr == wal->nextwall)) || bothSidesHighlighted) { col = editorcolors[14]; if (i == linehighlight || (linehighlight >= 0 && i == wall[linehighlight].nextwall) || bothSidesHighlighted) col -= M32_THROB>>1; } else if (circlewall >= 0 && (i == circlewall || wal->nextwall == circlewall)) col = editorcolors[14]; int32_t fz=0, fzn=0; if (m32_sideview) { // draw vertical line to neighboring wall int32_t const sect = sectorofwall(i); fz = getflorzofslope(sect, wal->x, wal->y); int32_t fz2 = getflorzofslope(sect, wall[p2].x, wall[p2].y); int32_t const dz = getscreenvdisp(fz-posze, zoome); int32_t const dz2 = getscreenvdisp(fz2-posze, zoome); y1 += dz; y2 += dz2; if (wal->nextwall>=0) { fzn = getflorzofslope(wal->nextsector, wal->x, wal->y); // if (i < wall[j].point2) editorDraw2dLineMiddle(x1, y1, x1, y1+getscreenvdisp(fzn-fz, zoome), col); } #ifdef YAX_ENABLE { int16_t const nw = yax_getnextwall(i, YAX_CEILING); if (nw >= 0) { int32_t const odrawlinepat = drawlinepat; fz2 = getflorzofslope(sectorofwall(nw), wall[nw].x, wall[nw].y); drawlinepat = 0x11111111; editorDraw2dLineMiddle(x1, y1, x1, y1+getscreenvdisp(fz2-fz, zoome), col); drawlinepat = odrawlinepat; } } #endif m32_wallscreenxy[i][0] = halfxdim16+x1; m32_wallscreenxy[i][1] = midydim16+y1; } if (wal->cstat&64) // if hitscan bit set { int32_t const one=(klabs(x2-x1) >= klabs(y2-y1)), no=!one; editorDraw2dLineMiddle(x1+no, y1+one, x2+no, y2+one, col); editorDraw2dLineMiddle(x1-no, y1-one, x2-no, y2-one, col); } editorDraw2dLineMiddle(x1, y1, x2, y2, col); // Draw height indicators at center of walls if requested and if not in // side-view mode. // XXX: This does not take sloping into account. if (showheightindicators && !m32_sideview) { int32_t dax, day; int32_t const k = getangle(x1-x2, y1-y2); editorGet2dScreenCoordinates(&dax, &day, ((wal->x+wall[wal->point2].x)>>1)-posxe, ((wal->y+wall[wal->point2].y)>>1)-posye, zoome); if (wal->nextsector >= 0) { int32_t const z1 = sector[sectorofwall(i)].floorz; int32_t const z2 = sector[wal->nextsector].floorz; if (z1 != z2 || showheightindicators == 2) { // Red walls. Show them on equal-height walls ONLY with setting 2. int32_t const bb = (z2 < z1); int32_t const dx = mulscale11(sintable[(k+1024 + 1024*bb)&2047], min(4096, zoome)) / 2560; int32_t const dy = scalescreeny(mulscale11(sintable[(k+512 + 1024*bb)&2047], min(4096, zoome)) / 2560); editorDraw2dLineMiddle(dax, day, dax+dx, day+dy, col); } } else if (showheightindicators == 2) { // Show them on white walls ONLY with setting 2. int32_t const dx = mulscale11(sintable[(k+2048)&2047], min(4096, zoome)) / 2560; int32_t const dy = scalescreeny(mulscale11(sintable[(k+1536)&2047], min(4096, zoome)) / 2560); editorDraw2dLineMiddle(dax, day, dax+dx, day+dy, col); } } if ((zoome >= 256 && editstatus == 1) || show2dwall[i>>3]&pow2char[i&7]) if ((halfxdim16+x1 >= 2) && (halfxdim16+x1 <= xdim-3) && (midydim16+y1 >= 2) && (midydim16+y1 <= ydim16-3)) { int32_t pointsize = 2; col = editorcolors[15]; if (i == pointhighlight || ((unsigned) pointhighlight < MAXWALLS && (wal->x == wall[pointhighlight].x) && (wal->y == wall[pointhighlight].y))) { col = editorcolors[15] - (M32_THROB>>1); if (totalclock & 16) pointsize++; } if (show2dwall[i>>3]&pow2char[i&7]) col = editorcolors[14] - (M32_THROB>>1); if (m32_sideview) { if (wal->nextwall >= 0) { if (fz < fzn) col = editorcolors[7]; else if (fz == fzn) col = editorcolors[4]; } } editorDraw2dCircle(halfxdim16+x1, midydim16+y1, pointsize, 16384, col); } } int32_t editorGet2dSpriteColor(int32_t spr) { int const picnum = sprite[spr].picnum; int pal = sprite[spr].pal; int const tilecol = tilecols[picnum]; if (palookup[pal] == NULL || (tilecol && palookup[pal][tilecol] == 0)) pal = 0; if (tilecol) return palookup[pal][tilecol]; if (!waloff[picnum]) tileLoad(picnum); if (!waloff[picnum]) return editorcolors[3]; // Calculate 2D mode tile color. uint32_t cols[256]; Bmemset(cols, 0, sizeof(cols)); const uint8_t *const texbuf = (const uint8_t *) waloff[picnum]; for (bssize_t i = 0; i < tilesiz[picnum].x * tilesiz[picnum].y; i++) cols[texbuf[i]]++; unsigned col = 0, cnt = 0; for (bssize_t i = 0; i < 240; i++) if (cols[i] > cnt) col = i, cnt = cols[i]; while (col < 240 && curpalette[col+1].r > curpalette[col].r) col++; tilecols[picnum] = col - 4; return palookup[pal][tilecols[picnum]]; } static void editorDraw2dSprite(int32_t j, int32_t posxe, int32_t posye, int32_t posze, int32_t zoome) { int32_t x1, y1, x2, y2; int col; const spritetype *const spr = &sprite[j]; int16_t const blocking = (spr->cstat&1), hitblocking = (spr->cstat&256); int16_t const flooraligned = (spr->cstat&32), wallaligned = (spr->cstat&16); int16_t const angofs = m32_sideview ? m32_sideang : 0; uint8_t const spritecol = spritecol2d[spr->picnum][blocking]; // KEEPINSYNC build.c: drawspritelabel() if (spr->sectnum<0) col = editorcolors[4]; // red else col = spritecol ? editorcolors[spritecol] : blocking ? editorcolors[5] : editorGet2dSpriteColor(j); if (editstatus == 1) { if (pointhighlight >= 16384 && (j+16384 == pointhighlight || (!m32_sideview && (spr->x == sprite[pointhighlight-16384].x && spr->y == sprite[pointhighlight-16384].y)))) { if (spritecol >= 8 && spritecol <= 15) col -= M32_THROB>>1; else col += M32_THROB>>2; } else // if (highlightcnt > 0) { if (show2dsprite[j>>3]&pow2char[j&7]) col = editorcolors[14] - (M32_THROB>>1); } } editorGet2dScreenCoordinates(&x1, &y1, spr->x-posxe, spr->y-posye, zoome); // tempint = ((midydim16+y1)*bytesperline)+(halfxdim16+x1)+frameplace; if (m32_sideview) y1 += getscreenvdisp(spr->z-posze, zoome); int f = mulscale12(128, zoome); if ((halfxdim16+x1 >= -f) && (halfxdim16+x1 < xdim+f) && (midydim16+y1 >= -f) && (midydim16+y1 < ydim16+f)) { if (zoome > 512 && spr->clipdist > 32) editorDraw2dCircle(halfxdim16+x1, midydim16+y1, mulscale14(spr->clipdist<<2, zoome), 16384, col); editorDraw2dCircle(halfxdim16+x1, midydim16+y1, 4, 16384, col); x2 = mulscale11(sintable[(spr->ang+angofs+2560)&2047], zoome) / 768; y2 = mulscale11(sintable[(spr->ang+angofs+2048)&2047], zoome) / 768; y2 = scalescreeny(y2); editorDraw2dLineMiddle(x1, y1, x1+x2, y1+y2, col); if (hitblocking) { editorDraw2dLineMiddle(x1, y1+1, x1+x2, y1+y2+1, col); editorDraw2dLineMiddle(x1, y1-1, x1+x2, y1+y2-1, col); editorDraw2dLineMiddle(x1-1, y1, x1+x2-1, y1+y2, col); editorDraw2dLineMiddle(x1+1, y1, x1+x2+1, y1+y2, col); } if (flooraligned) { int32_t fx = mulscale10(mulscale6(tilesiz[spr->picnum].x, spr->xrepeat), zoome) >> 1; int32_t fy = mulscale10(mulscale6(tilesiz[spr->picnum].y, spr->yrepeat), zoome) >> 1; int32_t co[4][2], ii, in; int32_t sinang = sintable[(spr->ang+angofs+1536)&2047]; int32_t cosang = sintable[(spr->ang+angofs+1024)&2047]; int32_t r, s; co[0][0] = co[3][0] = -fx; co[0][1] = co[1][1] = -fy; co[1][0] = co[2][0] = fx; co[2][1] = co[3][1] = fy; for (ii=3; ii>=0; ii--) { r = mulscale14(cosang, co[ii][0]) - mulscale14(sinang, co[ii][1]); s = mulscale14(sinang, co[ii][0]) + mulscale14(cosang, co[ii][1]); s = scalescreeny(s); co[ii][0] = r; co[ii][1] = s; } drawlinepat = 0xcfcfcfcf; for (ii=3; ii>=0; ii--) { in = (ii+1)&3; editorDraw2dLineMiddle(x1+co[ii][0], y1-co[ii][1], x1+co[in][0], y1-co[in][1], col); if (hitblocking) { editorDraw2dLineMiddle(x1+co[ii][0], y1-co[ii][1]+1, x1+co[in][0], y1-co[in][1]+1, col); editorDraw2dLineMiddle(x1+co[ii][0], y1-co[ii][1]-1, x1+co[in][0], y1-co[in][1]-1, col); editorDraw2dLineMiddle(x1+co[ii][0]+1, y1-co[ii][1], x1+co[in][0]+1, y1-co[in][1], col); editorDraw2dLineMiddle(x1+co[ii][0]-1, y1-co[ii][1], x1+co[in][0]-1, y1-co[in][1], col); } editorDraw2dLineMiddle(x1, y1, x1 + co[in][0], y1 - co[in][1], col); } drawlinepat = 0xffffffff; } else if (wallaligned) { int32_t fx = mulscale6(tilesiz[spr->picnum].x, spr->xrepeat); int32_t one=(((spr->ang+angofs+256)&512) == 0), no=!one; x2 = mulscale11(sintable[(spr->ang+angofs+2560)&2047], zoome) / 6144; y2 = mulscale11(sintable[(spr->ang+angofs+2048)&2047], zoome) / 6144; y2 = scalescreeny(y2); editorDraw2dLineMiddle(x1, y1, x1+x2, y1+y2, col); if (!(spr->cstat&64)) // not 1-sided { editorDraw2dLineMiddle(x1, y1, x1-x2, y1-y2, col); if (hitblocking) { editorDraw2dLineMiddle(x1-no, y1-one, x1-x2-no, y1-y2-one, col); editorDraw2dLineMiddle(x1+no, y1+one, x1-x2+no, y1-y2+one, col); } } if (hitblocking) { editorDraw2dLineMiddle(x1-no, y1-one, x1+x2-no, y1+y2-one, col); editorDraw2dLineMiddle(x1+no, y1+one, x1+x2+no, y1+y2+one, col); } x2 = mulscale13(sintable[(spr->ang+angofs+1024)&2047], zoome) * fx / 4096; y2 = mulscale13(sintable[(spr->ang+angofs+512)&2047], zoome) * fx / 4096; y2 = scalescreeny(y2); editorDraw2dLineMiddle(x1, y1, x1-x2, y1-y2, col); editorDraw2dLineMiddle(x1, y1, x1+x2, y1+y2, col); if (hitblocking) { editorDraw2dLineMiddle(x1+1, y1, x1+x2+1, y1+y2, col); editorDraw2dLineMiddle(x1-1, y1, x1-x2-1, y1-y2, col); editorDraw2dLineMiddle(x1-1, y1, x1+x2-1, y1+y2, col); editorDraw2dLineMiddle(x1+1, y1, x1-x2+1, y1-y2, col); editorDraw2dLineMiddle(x1, y1-1, x1+x2, y1+y2-1, col); editorDraw2dLineMiddle(x1, y1+1, x1-x2, y1-y2+1, col); editorDraw2dLineMiddle(x1, y1+1, x1+x2, y1+y2+1, col); editorDraw2dLineMiddle(x1, y1-1, x1-x2, y1-y2-1, col); } } } } // // draw2dscreen // static int8_t tempbuf[(MAXWALLS+7)>>3]; void editorDraw2dScreen(const vec3_t *pos, int16_t cursectnum, int16_t ange, int32_t zoome, int16_t gride) { int32_t i, x1, y1; int16_t angofs = m32_sideview ? m32_sideang : 0; int32_t posxe=pos->x, posye=pos->y, posze=pos->z; uint8_t *graybitmap = (uint8_t *) tempbuf; int32_t alwaysshowgray = get_alwaysshowgray(); if (in3dmode()) return; editorSetup2dSideView(); videoBeginDrawing(); //{{{ if (editstatus == 0) { // faketimerhandler(); clear2dscreen(); // faketimerhandler(); editorDraw2dGrid(posxe, posye, posze, cursectnum, ange, zoome, gride); } faketimerhandler(); m32_swcnt = 0; if (numgraysects==0) Bmemset(graybitmap, 0, (numwalls+7)>>3); else { for (i=0; i>3]&(1<<(i&7))) && (j < 0 || (graywallbitmap[j>>3]&(1<<(j&7))))) graybitmap[i>>3] |= (1<<(i&7)); else graybitmap[i>>3] &= ~(1<<(i&7)); } } if (!m32_sideview) { #ifndef YAX_ENABLE for (i=numwalls-1; i>=0; i--) editorDraw2dWall(i, posxe, posye, posze, zoome, 0); #else if (alwaysshowgray) for (i=numwalls-1; i>=0; i--) if (graybitmap[i>>3]&(1<<(i&7))) editorDraw2dWall(i, posxe, posye, posze, zoome, 1+2); for (i=numwalls-1; i>=0; i--) if ((graybitmap[i>>3]&(1<<(i&7)))==0) editorDraw2dWall(i, posxe, posye, posze, zoome, 2); #endif } else { int32_t j = 0; for (i=0; i= 256 || highlightcnt>0) for (bssize_t j=0; j>3]&pow2char[j&7])==0) { if (!m32_sideview && sprite[j].sectnum >= 0) YAX_SKIPSECTOR(sprite[j].sectnum); if (zoome<256) continue; } if (!m32_sideview) editorDraw2dSprite(j, posxe, posye, posze, zoome); else { m32_wallsprite[m32_swcnt++] = MAXWALLS+j; editorGet2dSideViewDistance(MAXWALLS+j, -1); } } faketimerhandler(); if (m32_sideview) { qsort(m32_wallsprite, m32_swcnt, sizeof(int16_t), &editorCompare2dSideViewPoints); for (i=0; i>3]&(1<<(j&7)))) editorDraw2dWall(j, posxe, posye, posze, zoome, !!(graybitmap[j>>3]&(1<<(j&7)))); } else { if (!alwaysshowgray && sprite[j-MAXWALLS].sectnum>=0) YAX_SKIPSECTOR(sprite[j-MAXWALLS].sectnum); editorDraw2dSprite(j-MAXWALLS, posxe, posye, posze, zoome); } } faketimerhandler(); } #if 0 { int32_t xx, yy, xx2, yy2; screencoords(&xx, &yy, -posxe, -posye, zoome); screencoords(&xx2, &yy2, (m32_viewplane.x)-posxe, (m32_viewplane.y)-posye, zoome); if (m32_sideview) yy2 += getscreenvdisp((m32_viewplane.z<<4)-posze, zoome); drawcircle16(halfxdim16+xx, midydim16+yy, 2, 16384, editorcolors[4]); //red drawcircle16(halfxdim16+xx2, midydim16+yy2, 2, 16384, editorcolors[14]); //yellow drawline16mid(xx, yy, xx2, yy2, editorcolors[15]); } #endif x1 = mulscale11(sintable[(ange+angofs+2560)&2047], zoome) / 768; //Draw white arrow y1 = mulscale11(sintable[(ange+angofs+2048)&2047], zoome) / 768; i = scalescreeny(x1); int32_t j = scalescreeny(y1); editorDraw2dLineMiddle(x1, j, -x1, -j, editorcolors[15]); editorDraw2dLineMiddle(x1, j, +y1, -i, editorcolors[15]); editorDraw2dLineMiddle(x1, j, -y1, +i, editorcolors[15]); videoEndDrawing(); //}}} } // // setpolymost2dview // Sets OpenGL for 2D drawing // void polymostSet2dView(void) { #ifdef USE_OPENGL if (videoGetRenderMode() < REND_POLYMOST) return; glViewport(0, 0, xdim, ydim); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, xdim, ydim, 0, -1, 1); if (videoGetRenderMode() == REND_POLYMER) { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glDisable(GL_TEXTURE_2D); } gloy1 = -1; glDisable(GL_DEPTH_TEST); glDisable(GL_BLEND); #endif }