diff --git a/polymer/eduke32/build/include/editor.h b/polymer/eduke32/build/include/editor.h index 0b15e00a6..a67f945ed 100644 --- a/polymer/eduke32/build/include/editor.h +++ b/polymer/eduke32/build/include/editor.h @@ -247,6 +247,10 @@ int32_t inside_editor(const vec3_t *pos, int32_t searchx, int32_t searchy, int32 int32_t x, int32_t y, int16_t sectnum); void correct_sprite_yoffset(int32_t i); +void inflineintersect(int32_t x1, int32_t y1, int32_t x2, int32_t y2, + int32_t x3, int32_t y3, int32_t x4, int32_t y4, + int32_t *intx, int32_t *inty, int32_t *sign12, int32_t *sign34); + extern uint8_t hlsectorbitmap[MAXSECTORS>>3]; #if defined(_WIN32) diff --git a/polymer/eduke32/build/src/build.c b/polymer/eduke32/build/src/build.c index 7b83a9314..e0a1cd724 100644 --- a/polymer/eduke32/build/src/build.c +++ b/polymer/eduke32/build/src/build.c @@ -2781,6 +2781,42 @@ static int32_t M32_InsertPoint(int32_t thewall, int32_t dax, int32_t day, int32_ } +// based on lineintersect in engine.c, but lines are considered as infinitely +// extending +void inflineintersect(int32_t x1, int32_t y1, int32_t x2, int32_t y2, + int32_t x3, int32_t y3, int32_t x4, int32_t y4, + int32_t *intx, int32_t *inty, int32_t *sign12, int32_t *sign34) +{ + //p1 to p2 is a line segment + int64_t x21, y21, x34, y34, x31, y31, bot, topt, topu, t; + + x21 = x2-x1; x34 = x3-x4; + y21 = y2-y1; y34 = y3-y4; + bot = x21*y34 - y21*x34; + if (bot >= 0) + { + if (bot == 0) { *sign12 = *sign34 = 0; return; }; + x31 = x3-x1; y31 = y3-y1; + topt = x31*y34 - y31*x34; + topu = x21*y31 - y21*x31; + } + else + { + x31 = x3-x1; y31 = y3-y1; + topt = x31*y34 - y31*x34; + topu = x21*y31 - y21*x31; + } + + t = (topt*(1<<24))/bot; + *intx = x1 + ((x21*t)>>24); + *inty = y1 + ((y21*t)>>24); + + *sign12 = topt < 0 ? -1 : 1; + *sign34 = topu < 0 ? -1 : 1; + + return; +} + static int32_t lineintersect2v(const vec2_t *p1, const vec2_t *p2, // line segment 1 const vec2_t *q1, const vec2_t *q2, // line segment 2 vec2_t *pint) diff --git a/polymer/eduke32/source/astub.c b/polymer/eduke32/source/astub.c index ec5dfcb41..63323d8dd 100644 --- a/polymer/eduke32/source/astub.c +++ b/polymer/eduke32/source/astub.c @@ -6960,11 +6960,11 @@ static void Keys3d(void) const vec2_t vecw2r90 = { -vecw2.y, vecw2.x }; // v, rotated 90 deg CW const int32_t bits = CEILINGFLOOR(tempsectornum, stat)&(64+32+16+8+4); + const int32_t tile = CEILINGFLOOR(tempsectornum, picnum); if ((CEILINGFLOOR(tempsectornum, stat)&64) == 0) { // world-aligned texture - const int32_t tile = CEILINGFLOOR(tempsectornum, picnum); if (tilesizx[tile]<=0 || tilesizy[tile]<=0) { @@ -6997,7 +6997,7 @@ static void Keys3d(void) const int64_t a = lldotv2(&vecw1, &vecw2); const int64_t b = lldotv2(&vecw1, &vecw2r90); - if (a & b) + if (a!=0 && b!=0) { message("Walls %d and %d are nether parallel nor perpendicular", refwall, ourwall); @@ -7017,8 +7017,45 @@ static void Keys3d(void) tempbits = (tempbits&4) + ((tempbits&3)<<4); CEILINGFLOOR(searchsector, stat) |= 64 + (bits&8) + tempbits; - message("(TODO) Aligned sector %d %s (firstwall-relative) with sector %d's", - searchsector, typestr[searchstat], tempsectornum); + { + const walltype *rw = &wall[refwall], *rw2 = &POINT2(refwall); + const walltype *ow = &wall[ourwall], *ow2 = &POINT2(ourwall); + int32_t intx, inty, sign12, sign34; + + if (b != 0) // perpendicular + inflineintersect(rw->x,rw->y, rw2->x,rw2->y, ow->x,ow->y, ow2->x,ow2->y, + &intx,&inty, &sign12,&sign34); + else // parallel + inflineintersect(rw->x,rw->y, rw2->x,rw2->y, + ow->x,ow->y, ow->x+vecw2r90.x,ow->y+vecw2r90.y, + &intx,&inty, &sign12,&sign34); + if (sign12 == 0) + { + message("INTERNAL ERROR: Couldn't get intersection" + " of reference and alignee walls"); + } + else + { + double dx = (double)(rw->x-intx)*(rw->x-intx) + (double)(rw->y-inty)*(rw->y-inty); + double dy = (double)(ow->x-intx)*(ow->x-intx) + (double)(ow->y-inty)*(ow->y-inty); + + dx = -sign12 * sqrt(dx) * 16; + dy = sign34 * sqrt(dy) * 16; + if (a < 0 || b > 0) + dx = -dx; + dx /= 1<<((picsiz[tile]&15) - !!(bits&8)); + dy /= 1<<((picsiz[tile]>>4) - !!(bits&8)); +//initprintf("int=(%d,%d), dx=%.03f dy=%.03f\n", intx,inty, dx, dy); + CEILINGFLOOR(searchsector, xpanning) = + CEILINGFLOOR(tempsectornum, xpanning) + (int32_t)dx; + CEILINGFLOOR(searchsector, ypanning) = + CEILINGFLOOR(tempsectornum, ypanning) + (int32_t)dy; + + message("%sAligned sector %d %s (firstwall-relative) with sector %d's", + (CEILINGFLOOR(tempsectornum, stat)&(32+16+4)) ? "(TODO) ":"", + searchsector, typestr[searchstat], tempsectornum); + } + } } } }