Make deleting points correct while having some walls drawn. For that,

some wall drawing state is ripped out from overheadeditor() into a
a file-scope struct (even if we don't yet need it there). If the deleting
touches the first drawn point, the walls drawn so far are cleared.

git-svn-id: https://svn.eduke32.com/eduke32@2089 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2011-10-30 19:47:42 +00:00
parent 48ac042ca4
commit cd8fc5328e

View file

@ -1348,6 +1348,15 @@ char changechar(char dachar, int32_t dadir, char smooshyalign, char boundcheck)
////////////////////// OVERHEADEDITOR ////////////////////// ////////////////////// OVERHEADEDITOR //////////////////////
// some 2d mode state
static struct overheadstate
{
// state related to line drawing
int16_t suckwall, split;
int16_t splitsect;
int16_t splitstartwall;
} ovh;
int32_t inside_editor_curpos(int16_t sectnum) int32_t inside_editor_curpos(int16_t sectnum)
{ {
// TODO: take care: mous[xy]plc global vs overheadeditor auto // TODO: take care: mous[xy]plc global vs overheadeditor auto
@ -2042,15 +2051,15 @@ static void copy_some_wall_members(int16_t dst, int16_t src, int32_t reset_some)
} }
} }
static void init_new_wall1(int16_t *suckwall, int32_t *mousxplc, int32_t *mousyplc) static void init_new_wall1(int16_t *suckwall_ret, int32_t mousxplc, int32_t mousyplc)
{ {
int32_t i; int32_t i;
Bmemset(&wall[newnumwalls], 0, sizeof(walltype)); Bmemset(&wall[newnumwalls], 0, sizeof(walltype));
wall[newnumwalls].extra = -1; wall[newnumwalls].extra = -1;
wall[newnumwalls].x = *mousxplc; wall[newnumwalls].x = mousxplc;
wall[newnumwalls].y = *mousyplc; wall[newnumwalls].y = mousyplc;
wall[newnumwalls].nextsector = -1; wall[newnumwalls].nextsector = -1;
wall[newnumwalls].nextwall = -1; wall[newnumwalls].nextwall = -1;
@ -2060,8 +2069,8 @@ static void init_new_wall1(int16_t *suckwall, int32_t *mousxplc, int32_t *mousyp
if (wall[i].nextwall >= 0) if (wall[i].nextwall >= 0)
YAX_SKIPWALL(wall[i].nextwall); YAX_SKIPWALL(wall[i].nextwall);
if (wall[i].x == *mousxplc && wall[i].y == *mousyplc) if (wall[i].x == mousxplc && wall[i].y == mousyplc)
*suckwall = i; *suckwall_ret = i;
} }
wall[newnumwalls].point2 = newnumwalls+1; wall[newnumwalls].point2 = newnumwalls+1;
@ -2220,6 +2229,10 @@ static int32_t trace_loop(int32_t j, uint8_t *visitedwall, int16_t *ignore_ret,
} }
// Backup drawn walls for carrying out other operations in the middle. // Backup drawn walls for carrying out other operations in the middle.
// 0: back up, set newnumwalls to -1
// 1: restore drawn walls and free mem
// 2: only free memory needed for backing up walls but don't restore walls
// (use this if the map has been mangled too much for a safe restoration)
// Context that needs special treatment: suckwall, splitsect, splitstartwall // Context that needs special treatment: suckwall, splitsect, splitstartwall
static int32_t backup_drawn_walls(int32_t restore) static int32_t backup_drawn_walls(int32_t restore)
{ {
@ -2253,13 +2266,17 @@ static int32_t backup_drawn_walls(int32_t restore)
// restore // restore
if (wallsdrawn != -1) if (wallsdrawn != -1)
{
if (restore==1)
{ {
int32_t i; int32_t i;
Bmemcpy(&wall[numwalls], tmpwall, wallsdrawn*sizeof(walltype)); Bmemcpy(&wall[numwalls], tmpwall, wallsdrawn*sizeof(walltype));
newnumwalls = numwalls + wallsdrawn; newnumwalls = numwalls + wallsdrawn;
for (i=numwalls; i<newnumwalls; i++) for (i=numwalls; i<newnumwalls; i++)
wall[i].point2 = i+1; wall[i].point2 = i+1;
}
Bfree(tmpwall); Bfree(tmpwall);
tmpwall = NULL; tmpwall = NULL;
@ -2544,9 +2561,7 @@ void overheadeditor(void)
int32_t numwalls_bak; int32_t numwalls_bak;
int32_t startwall=0, endwall, dax, day, x1, y1, x2, y2, x3, y3; //, x4, y4; int32_t startwall=0, endwall, dax, day, x1, y1, x2, y2, x3, y3; //, x4, y4;
int32_t highlightx1, highlighty1, highlightx2, highlighty2; int32_t highlightx1, highlighty1, highlightx2, highlighty2;
int16_t suckwall=0, split=0, bad; int16_t bad, joinsector[2];
int16_t splitsect=0, joinsector[2];
int16_t splitstartwall=0;
int32_t mousx, mousy, bstatus; int32_t mousx, mousy, bstatus;
int16_t circlepoints; int16_t circlepoints;
int32_t sectorhighlightx=0, sectorhighlighty=0; int32_t sectorhighlightx=0, sectorhighlighty=0;
@ -2555,6 +2570,11 @@ void overheadeditor(void)
int32_t resetsynctics = 0, lasttick=getticks(), waitdelay=totalclock, lastdraw=getticks(); int32_t resetsynctics = 0, lasttick=getticks(), waitdelay=totalclock, lastdraw=getticks();
int32_t olen[2]={0,0}, dragwall[2] = {-1, -1}; int32_t olen[2]={0,0}, dragwall[2] = {-1, -1};
ovh.suckwall = -1;
ovh.split = 0;
ovh.splitsect = -1;
ovh.splitstartwall = -1;
m32_setkeyfilter(1); m32_setkeyfilter(1);
qsetmodeany(xdim2d,ydim2d); qsetmodeany(xdim2d,ydim2d);
@ -4165,6 +4185,10 @@ end_autoredwall:
{ {
int32_t runi, numdelpoints=0; int32_t runi, numdelpoints=0;
const char *errmsg; const char *errmsg;
int32_t havedrawnwalls = (newnumwalls!=-1), restorestat=1;
// restorestat is set to 2 whenever the drawn walls should NOT be
// restored afterwards
if (backup_drawn_walls(0)) if (backup_drawn_walls(0))
goto end_after_dragging; goto end_after_dragging;
@ -4237,6 +4261,24 @@ end_autoredwall:
if (wall[i].x == POINT2(i).x && wall[i].y == POINT2(i).y if (wall[i].x == POINT2(i).x && wall[i].y == POINT2(i).y
&& sector[sectorofwall(i)].wallnum > 3) && sector[sectorofwall(i)].wallnum > 3)
{ {
if (havedrawnwalls)
{
if (i==ovh.suckwall || (ovh.split && i==ovh.splitstartwall))
{
// if we're about to delete a wall that participates
// in splitting, discard the already drawn walls
restorestat = 2;
}
else if (runi == 1)
{
// correct drawn wall anchors
if (ovh.suckwall > i)
ovh.suckwall--;
if (ovh.split && ovh.splitstartwall > i)
ovh.splitstartwall--;
}
}
errmsg = deletepoint(i, runi); errmsg = deletepoint(i, runi);
if (errmsg) if (errmsg)
{ {
@ -4251,9 +4293,11 @@ end_autoredwall:
if (numdelpoints) if (numdelpoints)
{ {
if (numdelpoints > 1) if (numdelpoints > 1)
message("Deleted %d points.", numdelpoints); message("Deleted %d points%s", numdelpoints,
(havedrawnwalls && restorestat==2) ? " and cleared drawn walls":"");
else else
printmessage16("Point deleted."); printmessage16("Point deleted%s", (havedrawnwalls && restorestat==2) ?
", cleared drawn walls":"");
asksave = 1; asksave = 1;
} }
else else
@ -4276,7 +4320,7 @@ end_autoredwall:
yax_updategrays(pos.z); yax_updategrays(pos.z);
#endif #endif
end_after_dragging: end_after_dragging:
backup_drawn_walls(1); backup_drawn_walls(restorestat);
} }
if ((bstatus&1) > 0) //drag points if ((bstatus&1) > 0) //drag points
@ -5596,10 +5640,10 @@ end_join_sectors:
firstx = mousxplc; firstx = mousxplc;
firsty = mousyplc; //Make first point firsty = mousyplc; //Make first point
newnumwalls = numwalls; newnumwalls = numwalls;
suckwall = -1; ovh.suckwall = -1;
split = 0; ovh.split = 0;
init_new_wall1(&suckwall, &mousxplc, &mousyplc); init_new_wall1(&ovh.suckwall, mousxplc, mousyplc);
printmessage16("Sector drawing started."); printmessage16("Sector drawing started.");
} }
@ -5650,9 +5694,9 @@ end_join_sectors:
if (m>=0 && (POINT2(k).x != mousxplc || POINT2(k).y != mousyplc)) if (m>=0 && (POINT2(k).x != mousxplc || POINT2(k).y != mousyplc))
if (wall[lastwall(k)].x != mousxplc || wall[lastwall(k)].y != mousyplc) if (wall[lastwall(k)].x != mousxplc || wall[lastwall(k)].y != mousyplc)
{ {
split = 1; ovh.split = 1;
splitsect = i; ovh.splitsect = i;
splitstartwall = m; ovh.splitstartwall = m;
break; break;
} }
} }
@ -5684,7 +5728,7 @@ end_join_sectors:
if (bad == 0) if (bad == 0)
{ {
init_new_wall1(&suckwall, &mousxplc, &mousyplc); init_new_wall1(&ovh.suckwall, mousxplc, mousyplc);
} }
else else
{ {
@ -5697,12 +5741,12 @@ end_join_sectors:
////////// newnumwalls is at most MAXWALLS here ////////// ////////// newnumwalls is at most MAXWALLS here //////////
//if not split and back to first point //if not split and back to first point
if (!split && newnumwalls >= numwalls+3 if (!ovh.split && newnumwalls >= numwalls+3
&& firstx==mousxplc && firsty==mousyplc) && firstx==mousxplc && firsty==mousyplc)
{ {
wall[newnumwalls-1].point2 = numwalls; wall[newnumwalls-1].point2 = numwalls;
if (suckwall == -1) //if no connections to other sectors if (ovh.suckwall == -1) //if no connections to other sectors
{ {
k = -1; k = -1;
for (i=0; i<numsectors; i++) for (i=0; i<numsectors; i++)
@ -5788,27 +5832,27 @@ check_next_sector: ;
sector[k].wallnum += j; sector[k].wallnum += j;
for (i=k+1; i<numsectors; i++) for (i=k+1; i<numsectors; i++)
sector[i].wallptr += j; sector[i].wallptr += j;
suckwall = sector[k].wallptr; ovh.suckwall = sector[k].wallptr;
for (i=0; i<numwalls; i++) for (i=0; i<numwalls; i++)
{ {
if (wall[i].nextwall >= suckwall) if (wall[i].nextwall >= ovh.suckwall)
wall[i].nextwall += j; wall[i].nextwall += j;
if (wall[i].point2 >= suckwall) if (wall[i].point2 >= ovh.suckwall)
wall[i].point2 += j; wall[i].point2 += j;
} }
#ifdef YAX_ENABLE #ifdef YAX_ENABLE
yax_tweakwalls(suckwall, j); yax_tweakwalls(ovh.suckwall, j);
#endif #endif
Bmemmove(&wall[suckwall+j], &wall[suckwall], (newnumwalls-suckwall)*sizeof(walltype)); Bmemmove(&wall[ovh.suckwall+j], &wall[ovh.suckwall], (newnumwalls-ovh.suckwall)*sizeof(walltype));
Bmemmove(&wall[suckwall], &wall[newnumwalls], j*sizeof(walltype)); Bmemmove(&wall[ovh.suckwall], &wall[newnumwalls], j*sizeof(walltype));
for (i=suckwall; i<suckwall+j; i++) for (i=ovh.suckwall; i<ovh.suckwall+j; i++)
{ {
wall[i].point2 += (suckwall-numwalls); wall[i].point2 += (ovh.suckwall-numwalls);
copy_some_wall_members(i, suckwall+j, 1); copy_some_wall_members(i, ovh.suckwall+j, 1);
wall[i].cstat &= ~(1+16+32+64); wall[i].cstat &= ~(1+16+32+64);
} }
@ -5817,7 +5861,7 @@ check_next_sector: ;
#ifdef YAX_ENABLE #ifdef YAX_ENABLE
if (extendedSector) if (extendedSector)
{ {
newnumwalls = whitelinescan(k, suckwall); newnumwalls = whitelinescan(k, ovh.suckwall);
if (newnumwalls != newnumwalls2) if (newnumwalls != newnumwalls2)
message("YAX: WTF?"); message("YAX: WTF?");
for (i=numwalls; i<newnumwalls2; i++) for (i=numwalls; i<newnumwalls2; i++)
@ -5833,7 +5877,7 @@ check_next_sector: ;
numsectors++; numsectors++;
} }
#endif #endif
setfirstwall(k, suckwall+j); // restore old first wall setfirstwall(k, ovh.suckwall+j); // restore old first wall
#ifdef YAX_ENABLE #ifdef YAX_ENABLE
if (extendedSector) if (extendedSector)
printmessage16("Added inner loop to sector %d and made new inner sector", k); printmessage16("Added inner loop to sector %d and made new inner sector", k);
@ -5855,16 +5899,16 @@ check_next_sector: ;
for (i=numwalls; i<newnumwalls; i++) for (i=numwalls; i<newnumwalls; i++)
{ {
copy_some_wall_members(i, suckwall, 1); copy_some_wall_members(i, ovh.suckwall, 1);
wall[i].cstat &= ~(1+16+32+64); wall[i].cstat &= ~(1+16+32+64);
if (checksectorpointer(i, numsectors) > 0) if (checksectorpointer(i, numsectors) > 0)
{ {
// if new red line, prefer the other-side wall as base // if new red line, prefer the other-side wall as base
suckwall = wall[i].nextwall; ovh.suckwall = wall[i].nextwall;
} }
} }
sucksect = sectorofwall(suckwall); sucksect = sectorofwall(ovh.suckwall);
if (numsectors != sucksect) if (numsectors != sucksect)
Bmemcpy(&sector[numsectors], &sector[sucksect], sizeof(sectortype)); Bmemcpy(&sector[numsectors], &sector[sucksect], sizeof(sectortype));
@ -5900,14 +5944,14 @@ check_next_sector: ;
goto end_space_handling; goto end_space_handling;
} }
////////// split sector ////////// ////////// split sector //////////
else if (split == 1) else if (ovh.split == 1)
{ {
int16_t danumwalls, splitendwall, doSectorSplit; int16_t danumwalls, splitendwall, doSectorSplit;
int16_t secondstartwall=-1; // used only with splitting int16_t secondstartwall=-1; // used only with splitting
int32_t expectedNumwalls = numwalls+2*(newnumwalls-numwalls-1), loopnum; int32_t expectedNumwalls = numwalls+2*(newnumwalls-numwalls-1), loopnum;
startwall = sector[splitsect].wallptr; startwall = sector[ovh.splitsect].wallptr;
endwall = startwall + sector[splitsect].wallnum - 1; endwall = startwall + sector[ovh.splitsect].wallnum - 1;
// OSD_Printf("numwalls: %d, newnumwalls: %d\n", numwalls, newnumwalls); // OSD_Printf("numwalls: %d, newnumwalls: %d\n", numwalls, newnumwalls);
i = -1; i = -1;
@ -5918,12 +5962,12 @@ check_next_sector: ;
break; break;
} }
// vvvv shouldn't happen, but you never know... // vvvv shouldn't happen, but you never know...
if (i==-1 || k==splitstartwall) if (i==-1 || k==ovh.splitstartwall)
goto end_space_handling; goto end_space_handling;
splitendwall = k; splitendwall = k;
doSectorSplit = (loopnumofsector(splitsect,splitstartwall) doSectorSplit = (loopnumofsector(ovh.splitsect,ovh.splitstartwall)
== loopnumofsector(splitsect,splitendwall)); == loopnumofsector(ovh.splitsect,splitendwall));
if (expectedNumwalls > MAXWALLS) if (expectedNumwalls > MAXWALLS)
{ {
@ -5947,15 +5991,15 @@ check_next_sector: ;
if (doSectorSplit) if (doSectorSplit)
{ {
// Copy outer loop of first sector // Copy outer loop of first sector
if (do_while_copyloop1(splitendwall, splitstartwall, &danumwalls, numwalls)) if (do_while_copyloop1(splitendwall, ovh.splitstartwall, &danumwalls, numwalls))
goto split_not_enough_walls; goto split_not_enough_walls;
//Add other loops for 1st sector //Add other loops for 1st sector
i = loopnum = loopnumofsector(splitsect,splitstartwall); i = loopnum = loopnumofsector(ovh.splitsect,ovh.splitstartwall);
for (j=startwall; j<=endwall; j++) for (j=startwall; j<=endwall; j++)
{ {
k = loopnumofsector(splitsect,j); k = loopnumofsector(ovh.splitsect,j);
if (k == i) if (k == i)
continue; continue;
@ -5996,27 +6040,27 @@ check_next_sector: ;
//copy rest of loop next //copy rest of loop next
if (doSectorSplit) if (doSectorSplit)
{ {
if (do_while_copyloop1(splitstartwall, splitendwall, &danumwalls, secondstartwall)) if (do_while_copyloop1(ovh.splitstartwall, splitendwall, &danumwalls, secondstartwall))
goto split_not_enough_walls; goto split_not_enough_walls;
} }
else else
{ {
if (do_while_copyloop1(splitstartwall, splitstartwall, &danumwalls, numwalls)) if (do_while_copyloop1(ovh.splitstartwall, ovh.splitstartwall, &danumwalls, numwalls))
goto split_not_enough_walls; goto split_not_enough_walls;
} }
//Add other loops for 2nd sector //Add other loops for 2nd sector
i = loopnum = loopnumofsector(splitsect,splitstartwall); i = loopnum = loopnumofsector(ovh.splitsect,ovh.splitstartwall);
for (j=startwall; j<=endwall; j++) for (j=startwall; j<=endwall; j++)
{ {
k = loopnumofsector(splitsect, j); k = loopnumofsector(ovh.splitsect, j);
if (k==i) if (k==i)
continue; continue;
if (doSectorSplit && k==loopnum) if (doSectorSplit && k==loopnum)
continue; continue;
if (!doSectorSplit && (k == loopnumofsector(splitsect,splitstartwall) || k == loopnumofsector(splitsect,splitendwall))) if (!doSectorSplit && (k == loopnumofsector(ovh.splitsect,ovh.splitstartwall) || k == loopnumofsector(ovh.splitsect,splitendwall)))
continue; continue;
i = k; i = k;
@ -6049,7 +6093,7 @@ check_next_sector: ;
} }
//copy sector attributes & fix wall pointers //copy sector attributes & fix wall pointers
Bmemcpy(&sector[numsectors], &sector[splitsect], sizeof(sectortype)); Bmemcpy(&sector[numsectors], &sector[ovh.splitsect], sizeof(sectortype));
sector[numsectors].wallptr = numwalls; sector[numsectors].wallptr = numwalls;
sector[numsectors].wallnum = (doSectorSplit?secondstartwall:danumwalls) - numwalls; sector[numsectors].wallnum = (doSectorSplit?secondstartwall:danumwalls) - numwalls;
@ -6065,13 +6109,13 @@ check_next_sector: ;
wall[m].nextsector = numsectors; wall[m].nextsector = numsectors;
} }
Bmemcpy(&sector[numsectors+1], &sector[splitsect], sizeof(sectortype)); Bmemcpy(&sector[numsectors+1], &sector[ovh.splitsect], sizeof(sectortype));
sector[numsectors+1].wallptr = secondstartwall; sector[numsectors+1].wallptr = secondstartwall;
sector[numsectors+1].wallnum = danumwalls-secondstartwall; sector[numsectors+1].wallnum = danumwalls-secondstartwall;
} }
//fix sprites //fix sprites
j = headspritesect[splitsect]; j = headspritesect[ovh.splitsect];
while (j != -1) while (j != -1)
{ {
k = nextspritesect[j]; k = nextspritesect[j];
@ -6098,7 +6142,7 @@ check_next_sector: ;
#endif #endif
wall[j].nextwall = wall[j].nextsector = -1; wall[j].nextwall = wall[j].nextsector = -1;
} }
deletesector(splitsect); deletesector(ovh.splitsect);
//Check pointers //Check pointers
for (j=numwalls-k; j<numwalls; j++) for (j=numwalls-k; j<numwalls; j++)
@ -6360,6 +6404,7 @@ end_space_handling:
{ {
int32_t onewnumwalls = newnumwalls; int32_t onewnumwalls = newnumwalls;
int32_t wallis2sided = (wall[linehighlight].nextwall>=0); int32_t wallis2sided = (wall[linehighlight].nextwall>=0);
int32_t havedrawnwalls = (newnumwalls!=-1);
if (backup_drawn_walls(0)) if (backup_drawn_walls(0))
{ {