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
This commit is contained in:
helixhorned 2012-06-01 20:09:19 +00:00
parent d1f9cb230c
commit df105128cb
3 changed files with 91 additions and 8 deletions

View file

@ -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;

View file

@ -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;
}

View file

@ -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<degang/90; i++)
tempbits = prev3each[tempbits];
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);
}
}
}
}
if (PRESSED_KEYSC(ENTER)) // ENTER -- paste clipboard contents
{