From df105128cb9d6043f5e1ab2a44788ac215dd7297 Mon Sep 17 00:00:00 2001 From: helixhorned Date: Fri, 1 Jun 2012 20:09:19 +0000 Subject: [PATCH] Mapster32: Part 1 of ceiling/floor auto-alignment functionality. Usage is from 3D mode only. When a sector (or wall) is committed to the clipboard, it (or the wall's sector) is saved, and is subsequently used when auto-aligning [;-ENTER] another sector's ceiling or floor against the reference one's. This temp. sector is reset on any structurally modifying operation except setting first walls; also, aligning extended ceilings or floors is impossible as they use .*xrepeat internally. The auto-alignment does not change picnums (this can be accomplished with the ['+ENTER] combination), but copies the orientation bits 2^{2..6} to the alignee. Afterwards, if the reference is relative-aligned, it tweaks them, so that every case where the two firstwalls are either parallel or perpendi- cular is handled correctly. It does not yet calculate the panning values. git-svn-id: https://svn.eduke32.com/eduke32@2715 1a8010ca-5511-0410-912e-c29ae57300e0 --- polymer/eduke32/build/include/editor.h | 1 + polymer/eduke32/build/src/build.c | 22 +++++--- polymer/eduke32/source/astub.c | 76 ++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 8 deletions(-) diff --git a/polymer/eduke32/build/include/editor.h b/polymer/eduke32/build/include/editor.h index 36b5bc411..0b15e00a6 100644 --- a/polymer/eduke32/build/include/editor.h +++ b/polymer/eduke32/build/include/editor.h @@ -58,6 +58,7 @@ extern int16_t pointhighlight, linehighlight, highlightcnt; #define DEFAULT_SPRITE_CSTAT 0 //extern int16_t defaultspritecstat; +extern int32_t tempsectornum; extern int32_t temppicnum, tempcstat, templotag, temphitag, tempextra; extern uint32_t temppal, tempvis, tempxrepeat, tempyrepeat, tempxpanning, tempypanning; extern int32_t tempshade, tempxvel, tempyvel, tempzvel; diff --git a/polymer/eduke32/build/src/build.c b/polymer/eduke32/build/src/build.c index 174be6481..409a64b7b 100644 --- a/polymer/eduke32/build/src/build.c +++ b/polymer/eduke32/build/src/build.c @@ -91,19 +91,20 @@ int16_t highlight[MAXWALLS+MAXSPRITES]; int16_t highlightsector[MAXSECTORS], highlightsectorcnt = -1; extern char textfont[128][8]; -// only valid when highlightsectorcnt>0 and no structural -// modifications (deleting/inserting sectors or points, setting new firstwall) -// have been made -static int16_t onextwall[MAXWALLS]; // onextwall[i]>=0 implies wall[i].nextwall < 0 -static void mkonwvalid(void) { chsecptr_onextwall = onextwall; } -static void mkonwinvalid(void) { chsecptr_onextwall = NULL; } -static int32_t onwisvalid(void) { return chsecptr_onextwall != NULL; } - +int32_t tempsectornum = -1; // for auto ceiling/floor alignment int32_t temppicnum, tempcstat, templotag, temphitag, tempextra; uint32_t temppal, tempvis, tempxrepeat, tempyrepeat, tempxpanning=0, tempypanning=0; int32_t tempshade, tempxvel, tempyvel, tempzvel; char somethingintab = 255; +// Only valid when highlightsectorcnt>0 and no structural +// modifications (deleting/inserting sectors or points, setting new firstwall) +// have been made: +static int16_t onextwall[MAXWALLS]; // onextwall[i]>=0 implies wall[i].nextwall < 0 +static void mkonwvalid(void) { chsecptr_onextwall = onextwall; } +static void mkonwinvalid(void) { chsecptr_onextwall = NULL; tempsectornum=-1; } +static int32_t onwisvalid(void) { return chsecptr_onextwall != NULL; } + int32_t mlook = 0, mskip=0; int32_t revertCTRL=0,scrollamount=3; int32_t unrealedlook=1, quickmapcycling=1; //PK @@ -2559,6 +2560,8 @@ static void sort_walls_geometrically(int16_t *wallist, int32_t nwalls) void SetFirstWall(int32_t sectnum, int32_t wallnum) { + const int32_t otempsectornum = tempsectornum; + #ifdef YAX_ENABLE int32_t i, j, k, startwall, endwall; int16_t cf, bunchnum, tempsect, tempwall; @@ -2600,7 +2603,10 @@ void SetFirstWall(int32_t sectnum, int32_t wallnum) message("This wall now sector %d's first wall (sector[].wallptr)", sectnum); setfirstwall(sectnum, wallnum); + mkonwinvalid(); + tempsectornum = otempsectornum; // protect from mkonwinvalid() + asksave = 1; } diff --git a/polymer/eduke32/source/astub.c b/polymer/eduke32/source/astub.c index bc3d20ba2..a9dea036b 100644 --- a/polymer/eduke32/source/astub.c +++ b/polymer/eduke32/source/astub.c @@ -4851,6 +4851,14 @@ static void toggle_cf_flipping(int32_t sectnum, int32_t floorp) asksave = 1; } +// vec2_t initializer from a 1st point of wall +#define WALLVEC_INITIALIZER(w) { POINT2(w).x-wall[w].x, POINT2(w).y-wall[w].y } + +static int64_t lldotv2(const vec2_t *v1, const vec2_t *v2) +{ + return (int64_t)v1->x * v2->x + (int64_t)v1->y * v2->y; +} + ////////// KEY PRESS HANDLER IN 3D MODE ////////// static void Keys3d(void) { @@ -6905,6 +6913,8 @@ static void Keys3d(void) tempypanning = AIMED_SEL_WALL(ypanning); tempcstat = AIMED_SEL_WALL(cstat) & ~YAX_NEXTWALLBITS; templenrepquot = getlenbyrep(wallength(searchwall), tempxrepeat); + + tempsectornum = sectorofwall(searchwall); } else if (AIMING_AT_CEILING_OR_FLOOR) { @@ -6917,6 +6927,8 @@ static void Keys3d(void) tempxrepeat = 0; #endif tempcstat = AIMED_CEILINGFLOOR(stat) & ~YAX_BIT; + + tempsectornum = searchsector; } else if (AIMING_AT_SPRITE) { @@ -6927,6 +6939,8 @@ static void Keys3d(void) tempxvel = sprite[searchwall].xvel; tempyvel = sprite[searchwall].yvel; tempzvel = sprite[searchwall].zvel; + + tempsectornum = -1; } somethingintab = searchstat; @@ -6946,6 +6960,68 @@ static void Keys3d(void) message("Pasted picnum only"); } + else if (keystatus[KEYSC_SEMI] && PRESSED_KEYSC(ENTER)) // ; ENTER + { + if (AIMING_AT_CEILING_OR_FLOOR && (unsigned)tempsectornum < (unsigned)numsectors +#ifdef YAX_ENABLE + && YAXCHK(yax_getbunch(searchsector, AIMING_AT_FLOOR) < 0) +#endif + && tempsectornum != searchsector) + { + // auto-align ceiling/floor + const int32_t refwall = sector[tempsectornum].wallptr; + const int32_t ourwall = sector[searchsector].wallptr; + + const vec2_t vecw1 = WALLVEC_INITIALIZER(refwall); + const vec2_t vecw2 = WALLVEC_INITIALIZER(ourwall); + 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); + + if ((CEILINGFLOOR(tempsectornum, stat)&64) == 0) + { + // world-aligned texture + + CEILINGFLOOR(searchsector, stat) &= ~(64+32+16+8+4); + CEILINGFLOOR(searchsector, stat) |= bits; + + // TODO: actually align stuff + message("(TODO) Aligned sector %d %s with sector %d's", + searchsector, typestr[searchstat], tempsectornum); + } + else + { + // firstwall-aligned texture + + const int64_t a = lldotv2(&vecw1, &vecw2); + const int64_t b = lldotv2(&vecw1, &vecw2r90); + + if (a & b) + { + message("Walls %d and %d are nether parallel nor perpendicular", + refwall, ourwall); + } + else + { + // 0<-6<-3<-5<-0, 1<-7<-2<-4<-1 (mirrored/not mirrored separately) + static const int8_t prev3each[8] = { 5, 4, 7, 6, 2, 3, 0, 1 }; + + const int32_t degang = 90*(b<0) + 180*(a<0) + 270*(b>0); + int32_t i, tempbits = (bits&4) + ((bits>>4)&3); + +//message("Wall %d is rotated %d degrees CW wrt wall %d", ourwall, degang, refwall); + CEILINGFLOOR(searchsector, stat) &= ~(64+32+16+8+4); + for (i=0; i