diff --git a/polymer/eduke32/build/src/build.c b/polymer/eduke32/build/src/build.c index af61eea83..a685408d1 100644 --- a/polymer/eduke32/build/src/build.c +++ b/polymer/eduke32/build/src/build.c @@ -1348,6 +1348,15 @@ char changechar(char dachar, int32_t dadir, char smooshyalign, char boundcheck) ////////////////////// 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) { // 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; Bmemset(&wall[newnumwalls], 0, sizeof(walltype)); wall[newnumwalls].extra = -1; - wall[newnumwalls].x = *mousxplc; - wall[newnumwalls].y = *mousyplc; + wall[newnumwalls].x = mousxplc; + wall[newnumwalls].y = mousyplc; wall[newnumwalls].nextsector = -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) YAX_SKIPWALL(wall[i].nextwall); - if (wall[i].x == *mousxplc && wall[i].y == *mousyplc) - *suckwall = i; + if (wall[i].x == mousxplc && wall[i].y == mousyplc) + *suckwall_ret = i; } 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. +// 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 static int32_t backup_drawn_walls(int32_t restore) { @@ -2254,12 +2267,16 @@ static int32_t backup_drawn_walls(int32_t restore) // restore if (wallsdrawn != -1) { - int32_t i; + if (restore==1) + { + int32_t i; - Bmemcpy(&wall[numwalls], tmpwall, wallsdrawn*sizeof(walltype)); - newnumwalls = numwalls + wallsdrawn; - for (i=numwalls; i 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); if (errmsg) { @@ -4251,9 +4293,11 @@ end_autoredwall: if (numdelpoints) { if (numdelpoints > 1) - message("Deleted %d points.", numdelpoints); + message("Deleted %d points%s", numdelpoints, + (havedrawnwalls && restorestat==2) ? " and cleared drawn walls":""); else - printmessage16("Point deleted."); + printmessage16("Point deleted%s", (havedrawnwalls && restorestat==2) ? + ", cleared drawn walls":""); asksave = 1; } else @@ -4276,7 +4320,7 @@ end_autoredwall: yax_updategrays(pos.z); #endif end_after_dragging: - backup_drawn_walls(1); + backup_drawn_walls(restorestat); } if ((bstatus&1) > 0) //drag points @@ -5596,10 +5640,10 @@ end_join_sectors: firstx = mousxplc; firsty = mousyplc; //Make first point newnumwalls = numwalls; - suckwall = -1; - split = 0; + ovh.suckwall = -1; + ovh.split = 0; - init_new_wall1(&suckwall, &mousxplc, &mousyplc); + init_new_wall1(&ovh.suckwall, mousxplc, mousyplc); printmessage16("Sector drawing started."); } @@ -5650,9 +5694,9 @@ end_join_sectors: if (m>=0 && (POINT2(k).x != mousxplc || POINT2(k).y != mousyplc)) if (wall[lastwall(k)].x != mousxplc || wall[lastwall(k)].y != mousyplc) { - split = 1; - splitsect = i; - splitstartwall = m; + ovh.split = 1; + ovh.splitsect = i; + ovh.splitstartwall = m; break; } } @@ -5684,7 +5728,7 @@ end_join_sectors: if (bad == 0) { - init_new_wall1(&suckwall, &mousxplc, &mousyplc); + init_new_wall1(&ovh.suckwall, mousxplc, mousyplc); } else { @@ -5697,12 +5741,12 @@ end_join_sectors: ////////// newnumwalls is at most MAXWALLS here ////////// //if not split and back to first point - if (!split && newnumwalls >= numwalls+3 + if (!ovh.split && newnumwalls >= numwalls+3 && firstx==mousxplc && firsty==mousyplc) { 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; for (i=0; i= suckwall) + if (wall[i].nextwall >= ovh.suckwall) wall[i].nextwall += j; - if (wall[i].point2 >= suckwall) + if (wall[i].point2 >= ovh.suckwall) wall[i].point2 += j; } #ifdef YAX_ENABLE - yax_tweakwalls(suckwall, j); + yax_tweakwalls(ovh.suckwall, j); #endif - Bmemmove(&wall[suckwall+j], &wall[suckwall], (newnumwalls-suckwall)*sizeof(walltype)); - Bmemmove(&wall[suckwall], &wall[newnumwalls], j*sizeof(walltype)); + Bmemmove(&wall[ovh.suckwall+j], &wall[ovh.suckwall], (newnumwalls-ovh.suckwall)*sizeof(walltype)); + Bmemmove(&wall[ovh.suckwall], &wall[newnumwalls], j*sizeof(walltype)); - for (i=suckwall; i 0) { // 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) Bmemcpy(§or[numsectors], §or[sucksect], sizeof(sectortype)); @@ -5900,14 +5944,14 @@ check_next_sector: ; goto end_space_handling; } ////////// split sector ////////// - else if (split == 1) + else if (ovh.split == 1) { int16_t danumwalls, splitendwall, doSectorSplit; int16_t secondstartwall=-1; // used only with splitting int32_t expectedNumwalls = numwalls+2*(newnumwalls-numwalls-1), loopnum; - startwall = sector[splitsect].wallptr; - endwall = startwall + sector[splitsect].wallnum - 1; + startwall = sector[ovh.splitsect].wallptr; + endwall = startwall + sector[ovh.splitsect].wallnum - 1; // OSD_Printf("numwalls: %d, newnumwalls: %d\n", numwalls, newnumwalls); i = -1; @@ -5918,12 +5962,12 @@ check_next_sector: ; break; } // vvvv shouldn't happen, but you never know... - if (i==-1 || k==splitstartwall) + if (i==-1 || k==ovh.splitstartwall) goto end_space_handling; splitendwall = k; - doSectorSplit = (loopnumofsector(splitsect,splitstartwall) - == loopnumofsector(splitsect,splitendwall)); + doSectorSplit = (loopnumofsector(ovh.splitsect,ovh.splitstartwall) + == loopnumofsector(ovh.splitsect,splitendwall)); if (expectedNumwalls > MAXWALLS) { @@ -5947,15 +5991,15 @@ check_next_sector: ; if (doSectorSplit) { // 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; //Add other loops for 1st sector - i = loopnum = loopnumofsector(splitsect,splitstartwall); + i = loopnum = loopnumofsector(ovh.splitsect,ovh.splitstartwall); for (j=startwall; j<=endwall; j++) { - k = loopnumofsector(splitsect,j); + k = loopnumofsector(ovh.splitsect,j); if (k == i) continue; @@ -5996,27 +6040,27 @@ check_next_sector: ; //copy rest of loop next if (doSectorSplit) { - if (do_while_copyloop1(splitstartwall, splitendwall, &danumwalls, secondstartwall)) + if (do_while_copyloop1(ovh.splitstartwall, splitendwall, &danumwalls, secondstartwall)) goto split_not_enough_walls; } else { - if (do_while_copyloop1(splitstartwall, splitstartwall, &danumwalls, numwalls)) + if (do_while_copyloop1(ovh.splitstartwall, ovh.splitstartwall, &danumwalls, numwalls)) goto split_not_enough_walls; } //Add other loops for 2nd sector - i = loopnum = loopnumofsector(splitsect,splitstartwall); + i = loopnum = loopnumofsector(ovh.splitsect,ovh.splitstartwall); for (j=startwall; j<=endwall; j++) { - k = loopnumofsector(splitsect, j); + k = loopnumofsector(ovh.splitsect, j); if (k==i) continue; if (doSectorSplit && k==loopnum) 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; i = k; @@ -6049,7 +6093,7 @@ check_next_sector: ; } //copy sector attributes & fix wall pointers - Bmemcpy(§or[numsectors], §or[splitsect], sizeof(sectortype)); + Bmemcpy(§or[numsectors], §or[ovh.splitsect], sizeof(sectortype)); sector[numsectors].wallptr = numwalls; sector[numsectors].wallnum = (doSectorSplit?secondstartwall:danumwalls) - numwalls; @@ -6065,13 +6109,13 @@ check_next_sector: ; wall[m].nextsector = numsectors; } - Bmemcpy(§or[numsectors+1], §or[splitsect], sizeof(sectortype)); + Bmemcpy(§or[numsectors+1], §or[ovh.splitsect], sizeof(sectortype)); sector[numsectors+1].wallptr = secondstartwall; sector[numsectors+1].wallnum = danumwalls-secondstartwall; } //fix sprites - j = headspritesect[splitsect]; + j = headspritesect[ovh.splitsect]; while (j != -1) { k = nextspritesect[j]; @@ -6098,7 +6142,7 @@ check_next_sector: ; #endif wall[j].nextwall = wall[j].nextsector = -1; } - deletesector(splitsect); + deletesector(ovh.splitsect); //Check pointers for (j=numwalls-k; j=0); + int32_t havedrawnwalls = (newnumwalls!=-1); if (backup_drawn_walls(0)) {