diff --git a/polymer/eduke32/build/include/osd.h b/polymer/eduke32/build/include/osd.h index 7f0c9bef3..b70695697 100644 --- a/polymer/eduke32/build/include/osd.h +++ b/polymer/eduke32/build/include/osd.h @@ -102,6 +102,7 @@ char *OSD_GetFmtPtr(void); int32_t OSD_GetCols(void); int32_t OSD_IsMoving(void); +int32_t OSD_GetRowsCur(void); // initializes things void OSD_Init(void); diff --git a/polymer/eduke32/build/src/build.c b/polymer/eduke32/build/src/build.c index 0eb3fa07c..d6f10a8b6 100644 --- a/polymer/eduke32/build/src/build.c +++ b/polymer/eduke32/build/src/build.c @@ -95,7 +95,7 @@ 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]; +static int16_t onextwall[MAXWALLS]; // onextwall[i]>=0 implies wall[j].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; } @@ -128,6 +128,7 @@ static int32_t tempxyar[MAXWALLS][2] ATTRIBUTE((aligned(8))); static int32_t mousx, mousy; int16_t prefixtiles[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; uint8_t hlsectorbitmap[MAXSECTORS>>3]; // show2dsector is already taken... +static int32_t minhlsectorfloorz = 0; static uint8_t visited[MAXWALLS>>3]; // used for AlignWalls and trace_loop @@ -1812,13 +1813,21 @@ void update_highlightsector(void) { int32_t i; + minhlsectorfloorz = INT32_MAX; + highlightsectorcnt = 0; for (i=0; i>3]&(1<<(i&7))) + { highlightsector[highlightsectorcnt++] = i; + minhlsectorfloorz = min(minhlsectorfloorz, sector[i].floorz); + } if (highlightsectorcnt==0) + { + minhlsectorfloorz = 0; highlightsectorcnt = -1; + } } // hook run after handleevents in side view @@ -2244,6 +2253,7 @@ static int32_t compare_wall_coords(const void *w1, const void *w2) circlepoints = 7; \ } while (0) + // breadth-first search helpers void bfirst_search_init(int16_t *list, uint8_t *bitmap, int32_t *eltnumptr, int32_t maxnum, int16_t firstelt) { @@ -2273,7 +2283,7 @@ static int16_t collsectlist[2][MAXSECTORS]; static uint8_t collsectbitmap[2][MAXSECTORS>>3]; static void collect_sectors1(int16_t *sectlist, uint8_t *sectbitmap, int32_t *numsectptr, - int16_t startsec, int32_t alsoyaxnext) + int16_t startsec, int32_t alsoyaxnext, int32_t alsoonw) { int32_t j, startwall, endwall, sectcnt; @@ -2282,7 +2292,12 @@ static void collect_sectors1(int16_t *sectlist, uint8_t *sectbitmap, int32_t *nu for (sectcnt=0; sectcnt<*numsectptr; sectcnt++) { for (WALLS_OF_SECTOR(sectlist[sectcnt], j)) - bfirst_search_try(sectlist, sectbitmap, numsectptr, wall[j].nextsector); + { + if (wall[j].nextsector >= 0) + bfirst_search_try(sectlist, sectbitmap, numsectptr, wall[j].nextsector); + else if (alsoonw && onextwall[j]>=0) + bfirst_search_try(sectlist, sectbitmap, numsectptr, sectorofwall(onextwall[j])); + } if (alsoyaxnext) { @@ -2298,41 +2313,46 @@ static void collect_sectors1(int16_t *sectlist, uint8_t *sectbitmap, int32_t *nu } } + +static int32_t sectors_components(int16_t hlsectcnt, const int16_t *hlsectors, int32_t alsoyaxnext, int32_t alsoonw); +static int32_t highlighted_sectors_components(int32_t alsoyaxnext, int32_t alsoonw) +{ + return sectors_components(highlightsectorcnt, highlightsector, alsoyaxnext, alsoonw); +} + // whether all highlighted sectors are in one (returns 1), two (2) // or more (>2) connected components wrt the nextsector relation // -1 means error // alsoyaxnext: also consider "yax-nextsector" relation -static int32_t highlighted_sectors_components(int32_t alsoyaxnext) +// alsoonw: also consider "old-nextwall" relation (must be valid) +static int32_t sectors_components(int16_t hlsectcnt, const int16_t *hlsector, int32_t alsoyaxnext, int32_t alsoonw) { int32_t j, k, tmp; - if (highlightsectorcnt<1) + if (hlsectcnt<1) return 0; - if (highlightsectorcnt==1) - return 1; - collect_sectors1(collsectlist[0], collsectbitmap[0], &collnumsects[0], - highlightsector[0], alsoyaxnext); + hlsector[0], alsoyaxnext, alsoonw); - for (k=0; k>3]&(1<<(j&7)))==0) { // sector j not collected --> more than 1 conn. comp. collect_sectors1(collsectlist[1], collsectbitmap[1], &collnumsects[1], - j, alsoyaxnext); + j, alsoyaxnext, alsoonw); break; } } - if (k == highlightsectorcnt) + if (k == hlsectcnt) return 1; - for (k=0; k>3]&(1<<(j&7)))!=0) + (((collsectbitmap[1][j>>3]&(1<<(j&7)))!=0)<<1)); if (tmp==3) @@ -2430,6 +2450,42 @@ static void handlesecthighlight1(int32_t i, int32_t sub, int32_t nograycheck) } } +#ifdef YAX_ENABLE +// 1: good, 0: bad +static int32_t hl_all_bunch_sectors_p() +{ + uint8_t *const havebunch = visited; + int16_t cf, cb, fb; + int32_t i, j; + + if (numyaxbunches > 0) + { + Bmemset(havebunch, 0, (numyaxbunches+7)>>3); + for (i=0; i=0) + havebunch[cb>>3] |= (1<<(cb&7)); + if (fb>=0) + havebunch[fb>>3] |= (1<<(fb&7)); + } + + for (i=0; i>3] & (1<<(i&7)))==0) + continue; + + for (cf=0; cf<2; cf++) + for (SECTORS_OF_BUNCH(i,cf, j)) + if ((hlsectorbitmap[j>>3]&(1<<(j&7)))==0) + return 0; + } + } + + return 1; +} +#endif + void overheadeditor(void) { char buffer[80], ch; @@ -2728,12 +2784,9 @@ void overheadeditor(void) if (highlightsectorcnt >= 0) { - int32_t oydim16 = ydim16; - ydim16 = ydim-STATUS2DSIZ2; for (i=0; i>3]&(1<<(i&7))) fillsector(i, -1); - ydim16 = oydim16; } if (keystatus[0x2a]) // FIXME @@ -2841,6 +2894,13 @@ void overheadeditor(void) int32_t about_x=keystatus[0x2d]; int32_t doMirror = eitherALT; // mirror walls and wall/floor sprites +#ifdef YAX_ENABLE + if (highlightsectorcnt > 0 && !hl_all_bunch_sectors_p()) + { + printmessage16("To flip extended sectors, all sectors of a bunch must be selected"); + } + else +#endif if (highlightsectorcnt > 0) { keystatus[0x2d] = keystatus[0x15] = 0; @@ -3017,6 +3077,13 @@ void overheadeditor(void) if (tsign) { +#ifdef YAX_ENABLE + if (highlightsectorcnt > 0 && !hl_all_bunch_sectors_p()) + { + printmessage16("To rotate ext. sectors, all sectors of a bunch must be selected"); + } + else +#endif if (highlightsectorcnt > 0) { int32_t smoothRotation = !eitherSHIFT; @@ -3232,7 +3299,7 @@ void overheadeditor(void) goto end_yax; } - if (highlighted_sectors_components(0) != 1) + if (highlighted_sectors_components(0,0) != 1) { message("Sectors to extend must be in one connected component"); goto end_yax; @@ -4092,29 +4159,20 @@ end_after_dragging: if (cursectorhighlight >= 0 && cursectorhighlight < numsectors) { -// for (i=0; i 0) - locktogrid(&dax, &day); + dax = mousxplc; + day = mousyplc; + if (gridlock && grid > 0) + locktogrid(&dax, &day); - sectorhighlightx = dax; - sectorhighlighty = day; -// break; - } + sectorhighlightx = dax; + sectorhighlighty = day; } } else if (sectorhighlightstat == 1) { -#ifdef YAX_ENABLE - uint8_t *const havebunch = visited; - int16_t cf, cb, fb, good=1; -#endif dax = mousxplc; day = mousyplc; if (gridlock && grid > 0) @@ -4125,35 +4183,7 @@ end_after_dragging: sectorhighlightx += dax; sectorhighlighty += day; #ifdef YAX_ENABLE - if (numyaxbunches > 0) - { - Bmemset(havebunch, 0, (numyaxbunches+7)>>3); - for (i=0; i=0) - havebunch[cb>>3] |= (1<<(cb&7)); - if (fb>=0) - havebunch[fb>>3] |= (1<<(fb&7)); - } - - for (i=0; i>3] & (1<<(i&7)))==0) - continue; - - for (cf=0; cf<2; cf++) - for (SECTORS_OF_BUNCH(i,cf, j)) - if ((hlsectorbitmap[j>>3]&(1<<(j&7)))==0) - { - good = 0; - goto try_dragging_sectors; - } - } - } - -try_dragging_sectors: - if (!good) + if (!hl_all_bunch_sectors_p()) printmessage16("To drag extended sectors, all sectors of a bunch must be selected"); else #endif @@ -4521,11 +4551,12 @@ end_point_dragging: // (doesn't yet say which is stationary) // movestat: which component can be displaced? // &1: first, &2: second - int32_t askres, joinstat, needsdisp, movestat, dx=0,dy=0,dz; + int32_t askres, joinstat, needsdisp, moveonwp; + int32_t movestat, dx=0,dy=0,dz, delayerr=0; // tempxyar: int32_t [MAXWALLS][2] int32_t numouterwalls[2] = {0,0}, numowals; - int16_t *const outerwall[2] = { (int16_t *)tempxyar, ((int16_t *)tempxyar)+MAXWALLS }; + static int16_t outerwall[2][MAXWALLS]; const walltype *wal0, *wal1; // join sector ceilings/floors to a new bunch @@ -4537,7 +4568,7 @@ end_point_dragging: // first, see whether we have exactly two connected components // wrt wall[].nextsector - if (highlighted_sectors_components(0) != 2) + if (highlighted_sectors_components(0,0) != 2) { message("Sectors must be partitioned in two components to join"); goto end_join_sectors; @@ -4603,9 +4634,12 @@ end_point_dragging: if (numouterwalls[0] != numouterwalls[1]) { message("Number of outer walls must be equal for both components"); - goto end_join_sectors; + if (numouterwalls[0]>0 && numouterwalls[1]>0) + delayerr = 1; + else + goto end_join_sectors; } - numowals = numouterwalls[0]; + numowals = min(numouterwalls[0], numouterwalls[1]); // now sort outer walls 'geometrically' for (comp=0; comp<2; comp++) @@ -4626,11 +4660,23 @@ end_point_dragging: wall[wal1->point2].x - wall[wal0->point2].x != dx || wall[wal1->point2].y - wall[wal0->point2].y != dy) { + pos.x = wal0->x; + pos.y = wal0->y; + pos.z = getflorzofslope(sectorofwall(wal0-wall), pos.x, pos.y); + message("Outer wall coordinates must coincide for both components"); + OSD_Printf("wal0:%d (%d,%d)--(%d,%d)\n",wal0-wall, wal0->x,wal0->y, + wall[wal0->point2].x,wall[wal0->point2].y); + OSD_Printf("wal1:%d (%d,%d)--(%d,%d)\n",wal1-wall, wal1->x,wal1->y, + wall[wal1->point2].x,wall[wal1->point2].y); + goto end_join_sectors; } } + if (delayerr) + goto end_join_sectors; + if (joinstat == 3) { char askchars[2] = {'1', 'v'}; @@ -4683,9 +4729,47 @@ end_point_dragging: if (movestat==1) dx*=-1, dy*=-1, dz*=-1; + moveonwp = 0; + if (onwisvalid()) + { + static int16_t ocollsectlist[MAXSECTORS]; + static uint8_t tcollbitmap[MAXSECTORS>>3]; + int16_t ocollnumsects=collnumsects[movestat], tmpsect; + + Bmemcpy(ocollsectlist, collsectlist[movestat], ocollnumsects*sizeof(int16_t)); + Bmemset(tcollbitmap, 0, sizeof(tcollbitmap)); + + for (k=0; k>3; m++) + tcollbitmap[m] |= collsectbitmap[0][m]; + moveonwp = 1; + } + + if (moveonwp) + { + int32_t movecol = movestat==0 ? 159 : editorcolors[11]; + for (i=0; i>3]&(1<<(i&7))) + fillsector(i, editorcolors[12]); + + fade_editor_screen(editorcolors[12] | (movecol<<8)); + moveonwp = ask_if_sure("Also move formerly wall-connected sectors?",0); + if (moveonwp==-1) + goto end_join_sectors; + } + } + // now need to collect them wrt. the nextsector but also // the yax-nextsector relation - if (highlighted_sectors_components(1) != 2) + if (highlighted_sectors_components(1,moveonwp) != 2) { message("Must not have TROR connections between the two components"); goto end_join_sectors; @@ -4713,14 +4797,18 @@ end_point_dragging: } } - // restore old components - highlighted_sectors_components(0); + // restore old components, i.e. only the bunch sectors + highlighted_sectors_components(0,0); } // end if (needsdisp) /*** construct the YAX connection! ***/ for (comp=0; comp<2; comp++) { + // walls + for (j=0; j= 0) return(a%b); + return(((a+1)%b)+b-1); +} + int32_t fillsector(int16_t sectnum, int32_t fillcolor) { - int32_t x1, x2, y1, y2, sy, y; + int32_t x1, x2, y1, y2, sy, y, daminy; int32_t lborder, rborder, uborder, dborder, miny, maxy, dax; int16_t z, zz, startwall, endwall, fillcnt; @@ -8137,7 +8228,8 @@ int32_t fillsector(int16_t sectnum, int32_t fillcolor) col = fillcolor; lborder = 0; rborder = xdim; - uborder = 0; dborder = ydim16; + y = OSD_GetRowsCur(); + uborder = (y>=0)?(y+1)*8:0; dborder = ydim16-STATUS2DSIZ2; if (sectnum == -1) return 0; @@ -8169,8 +8261,12 @@ int32_t fillsector(int16_t sectnum, int32_t fillcolor) if (miny < uborder) miny = uborder; if (maxy >= dborder) maxy = dborder-1; + daminy = miny+2 - imod(miny+2,3); + if (sector[sectnum].floorz > minhlsectorfloorz) + daminy++; + //+((totalclock>>2)&3) - for (sy=miny; sy<=maxy; sy+=3) // JBF 20040116: numframes%3 -> (totalclock>>2)&3 + for (sy=daminy; sy<=maxy; sy+=3) // JBF 20040116: numframes%3 -> (totalclock>>2)&3 { y = pos.y + ((sy-midydim16)<<14)/zoom; @@ -8240,7 +8336,7 @@ int32_t fillsector(int16_t sectnum, int32_t fillcolor) if (fillist[z+1] > rborder) fillist[z+1] = rborder; - drawline16(fillist[z],sy, fillist[z+1],sy, col); //editorcolors[fillcolor] + drawline16(fillist[z]+1,sy, fillist[z+1]-1,sy, col); //editorcolors[fillcolor] } } } diff --git a/polymer/eduke32/build/src/engine.c b/polymer/eduke32/build/src/engine.c index 764157a0e..3f28e8c08 100644 --- a/polymer/eduke32/build/src/engine.c +++ b/polymer/eduke32/build/src/engine.c @@ -878,20 +878,28 @@ void yax_drawrooms(void (*ExtAnalyzeSprites)(void), int32_t horiz, int16_t sectn g_nodraw = 0; scansector_collectsprites = 0; -#ifdef ENGINE_CLEAR_SCREEN - if (getrendermode()==0) +#if 1 +//def ENGINE_CLEAR_SCREEN + if (editstatus==1) { - begindrawing(); - for (i=0; i w1f) + swaplong(&w1c, &w1f); + if (w2c > w2f) + swaplong(&w2c, &w2f); + + // now: c <= f for each "wall-vline" + + maxceil = max(w1c, w2c); + minflor = min(w1f, w2f); + + return minflor-maxceil; +} + const int16_t *chsecptr_onextwall = NULL; int32_t checksectorpointer(int16_t i, int16_t sectnum) { int32_t j, k, startwall, endwall, x1, y1, x2, y2, numnewwalls=0; + int32_t bestnextwall=-1, bestnextsec=-1, bestwallscore=INT32_MIN; + int32_t cz[4], fz[4], tmp[2], tmpscore=0; +#ifdef YAX_ENABLE + int16_t cb[2], fb[2]; +#endif #if 0 if (checksectorpointer_warn && (i<0 || i>=max(numwalls,newnumwalls))) @@ -1589,6 +1619,7 @@ int32_t checksectorpointer(int16_t i, int16_t sectnum) if (chsecptr_onextwall && (k=chsecptr_onextwall[i])>=0 && wall[k].nextwall<0) { + // old next wall found if (WALLS_ARE_CONSISTENT(k)) { j = sectorofwall(k); @@ -1620,19 +1651,57 @@ int32_t checksectorpointer(int16_t i, int16_t sectnum) // The nextwall relation should be definitely one-to-one at all times! if (wall[k].nextwall>=0 && wall[k].nextwall != i) continue; +#ifdef YAX_ENABLE + yax_getbunches(sectnum, &cb[0], &fb[0]); + yax_getbunches(j, &cb[1], &fb[1]); - if (sectnum != -2 && numnewwalls==0) // -2 means dry run + if ((cb[0]>=0 && cb[0]==cb[1]) || (fb[0]>=0 && fb[0]==fb[1])) { - wall[i].nextsector = j; - wall[i].nextwall = k; - wall[k].nextsector = sectnum; - wall[k].nextwall = i; + tmpscore = INT32_MAX; + } + else +#endif + { + getzsofslope(sectnum, x1,y1, &cz[0],&fz[0]); + getzsofslope(sectnum, x2,y2, &cz[1],&fz[1]); + getzsofslope(j, x1,y1, &cz[2],&fz[2]); + getzsofslope(j, x2,y2, &cz[3],&fz[3]); + + tmp[0] = getscore(cz[0],fz[0], cz[2],fz[2]); + tmp[1] = getscore(cz[1],fz[1], cz[3],fz[3]); + + if ((tmp[0]^tmp[1]) >= 0) + tmpscore = tmp[0]+tmp[1]; + else + tmpscore = max(tmp[0], tmp[1]); } - numnewwalls++; + if (bestnextwall == -1 || tmpscore > bestwallscore) + { + bestwallscore = tmpscore; + bestnextwall = k; + bestnextsec = j; + } + + numnewwalls++; } } + // sectnum -2 means dry run + if (bestnextwall >= 0 && sectnum!=-2) +#ifdef YAX_ENABLE + // be conservative in case if score <=0 (meaning that no wall area is mutually + // visible) -- it could be that another sector is a better candidate later on + if ((yax_getnextwall(i, 0)<0 && yax_getnextwall(i, 1)<0) || bestwallscore>0) +#endif + { +// initprintf("w%d new nw=%d (score %d)\n", i, bestnextwall, bestwallscore) + wall[i].nextsector = bestnextsec; + wall[i].nextwall = bestnextwall; + wall[bestnextwall].nextsector = sectnum; + wall[bestnextwall].nextwall = i; + } + return numnewwalls; } @@ -4512,6 +4581,9 @@ static void drawalls(int32_t bunch) } if ((nextsectnum < 0) || (wal->cstat&32)) //White/1-way wall { +#ifdef YAX_ENABLE + int16_t ynw[2]; +#endif globalorientation = (int32_t)wal->cstat; if (nextsectnum < 0) globalpicnum = wal->picnum; else globalpicnum = wal->overpicnum; @@ -4545,7 +4617,12 @@ static void drawalls(int32_t bunch) wallscan(x1,x2,uplc,dplc,swall,lwall); #ifdef YAX_ENABLE // TODO: slopes? - if (globalposz > sec->floorz && (x = yax_getnextwall(wallnum, YAX_FLOOR)) >= 0 && wall[x].nextwall>=0) + ynw[0] = yax_getnextwall(wallnum, 0); + ynw[1] = yax_getnextwall(wallnum, 1); + + if (globalposz > sec->floorz && ((ynw[1]>=0 && wall[ynw[1]].nextwall>=0) +// || (nextsectnum>=0 && yax_getbunch(sectnum,1)>=0) + )) { for (x=x1; x<=x2; x++) if (dplc[x] > umost[x] && umost[x] <= dmost[x]) @@ -4554,7 +4631,9 @@ static void drawalls(int32_t bunch) if (umost[x] > dmost[x]) numhits--; } } - else if (globalposz < sec->ceilingz && (x = yax_getnextwall(wallnum, YAX_CEILING)) >= 0 && wall[x].nextwall>=0) + else if (globalposz < sec->ceilingz && ((ynw[0]>=0 && wall[ynw[0]].nextwall>=0) +// || (nextsectnum>=0 && yax_getbunch(sectnum,0)>=0) + )) { for (x=x1; x<=x2; x++) if (uplc[x] < dmost[x] && umost[x] <= dmost[x]) diff --git a/polymer/eduke32/build/src/osd.c b/polymer/eduke32/build/src/osd.c index 97ffb5f17..14c6d9971 100644 --- a/polymer/eduke32/build/src/osd.c +++ b/polymer/eduke32/build/src/osd.c @@ -300,6 +300,11 @@ int32_t OSD_IsMoving(void) return (osdrowscur!=-1 && osdrowscur!=osdrows); } +int32_t OSD_GetRowsCur(void) +{ + return osdrowscur; +} + int32_t OSD_GetTextMode(void) { return osdtextmode; diff --git a/polymer/eduke32/source/astub.c b/polymer/eduke32/source/astub.c index 8cc0bc4a9..9176ecba7 100644 --- a/polymer/eduke32/source/astub.c +++ b/polymer/eduke32/source/astub.c @@ -57,6 +57,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include static int32_t floor_over_floor; +static int32_t g_fillCurSector = 0; // static char *startwin_labeltext = "Starting Mapster32..."; static char setupfilename[]= "mapster32.cfg"; @@ -7473,7 +7474,12 @@ static void Keys2d(void) if (keystatus[KEYSC_TAB]) //TAB { - if (eitherSHIFT || eitherCTRL) + if (eitherCTRL) + { + g_fillCurSector = !g_fillCurSector; + message("Fill currently pointed-at sector: %s", ONOFF(g_fillCurSector)); + } + else if (eitherSHIFT) { if (pointhighlight >= 16384) { @@ -7538,6 +7544,16 @@ static void Keys2d(void) ///__bigcomment__ + if ((i=tcursectornum)>=0 && g_fillCurSector && (hlsectorbitmap[i>>3]&(1<<(i&7)))==0) + { + int32_t col = editorcolors[4]; +#ifdef YAX_ENABLE + if (yax_getbunch(tcursectornum, YAX_FLOOR)>=0) + col = editorcolors[12]; +#endif + fillsector(tcursectornum, col); + } + #ifdef YAX_ENABLE if (eitherCTRL && PRESSED_KEYSC(U) && tcursectornum>=0) // Ctrl-U: unlink bunch sectors {