In backing up highlighted sectors code: also back up TROR information so

that bunches and nextwall links are restores, too.  Now, to coalesce two
TROR maps (e.g. for a CBP), one could
  do for i allsectors, sethighlightsector i 1
on the console, and then load the 'other' map to copy over the contents
of the first, including all TROR stuff. Note that neither selecting
all sectors with RAlt, nor duplicating them with Insert would lead to
the desired effect (yet).

Internally,
 - yax_setbunch() now has different behavior for bunchnums -1, -2 and -3
   (it either clears the nextwalls or not)
 - build.c has a helper function free_n_ptrs(). This could be handy in
   other situations where many blocks of memory must be allocated
   consecutively and freed in case of failure

git-svn-id: https://svn.eduke32.com/eduke32@2136 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2011-11-26 22:39:50 +00:00
parent b461dc5fb9
commit 2675334a60
2 changed files with 150 additions and 25 deletions

View file

@ -136,9 +136,15 @@ static uint8_t visited[MAXWALLS>>3]; // used for AlignWalls and trace_loop
typedef struct typedef struct
{ {
int16_t numsectors, numwalls, numsprites; int16_t numsectors, numwalls, numsprites;
#ifdef YAX_ENABLE
int16_t numyaxbunches;
int16_t *bunchnum; // [numsectors][2]
int16_t *ynextwall; // [numwalls][2]
#endif
sectortype *sector; sectortype *sector;
walltype *wall; walltype *wall;
spritetype *sprite; spritetype *sprite;
} mapinfofull_t; } mapinfofull_t;
static int32_t backup_highlighted_map(mapinfofull_t *mapinfo); static int32_t backup_highlighted_map(mapinfofull_t *mapinfo);
@ -1432,6 +1438,17 @@ void drawsmallabel(const char *text, char col, char backcol, int32_t dax, int32_
} }
} }
static void free_n_ptrs(void **ptrptr, int32_t n)
{
int32_t i;
for (i=0; i<n; i++)
{
Bfree(ptrptr[i]);
ptrptr[i] = NULL;
}
}
// backup highlighted sectors with sprites as mapinfo for later restoration // backup highlighted sectors with sprites as mapinfo for later restoration
// return values: // return values:
// -1: highlightsectorcnt<=0 // -1: highlightsectorcnt<=0
@ -1440,12 +1457,23 @@ void drawsmallabel(const char *text, char col, char backcol, int32_t dax, int32_
static int32_t backup_highlighted_map(mapinfofull_t *mapinfo) static int32_t backup_highlighted_map(mapinfofull_t *mapinfo)
{ {
int32_t i, j, k, m, tmpnumwalls=0, tmpnumsprites=0; int32_t i, j, k, m, tmpnumwalls=0, tmpnumsprites=0;
int16_t *otonsect = (int16_t *)tempxyar; int16_t *const otonsect = (int16_t *)tempxyar;
int16_t *otonwall = (int16_t *)(tempxyar+MAXWALLS); int16_t *const otonwall = ((int16_t *)tempxyar) + MAXWALLS;
#ifdef YAX_ENABLE
int16_t otonbunch[YAX_MAXBUNCHES];
int16_t numsectsofbunch[YAX_MAXBUNCHES]; // ceilings + floors
#endif
int32_t np = 0;
void *ptrs[5];
if (highlightsectorcnt <= 0) if (highlightsectorcnt <= 0)
return -1; return -1;
#ifdef YAX_ENABLE
for (i=0; i<numyaxbunches; i++)
numsectsofbunch[i] = 0;
#endif
// set up old-->new mappings // set up old-->new mappings
j = 0; j = 0;
k = 0; k = 0;
@ -1455,6 +1483,14 @@ static int32_t backup_highlighted_map(mapinfofull_t *mapinfo)
if (hlsectorbitmap[i>>3]&(1<<(i&7))) if (hlsectorbitmap[i>>3]&(1<<(i&7)))
{ {
#ifdef YAX_ENABLE
int16_t bn[2], cf;
yax_getbunches(i, &bn[0], &bn[1]);
for (cf=0; cf<2; cf++)
if (bn[cf] >= 0)
numsectsofbunch[bn[cf]]++;
#endif
otonsect[i] = j++; otonsect[i] = j++;
for (WALLS_OF_SECTOR(i, m)) for (WALLS_OF_SECTOR(i, m))
@ -1469,6 +1505,19 @@ static int32_t backup_highlighted_map(mapinfofull_t *mapinfo)
} }
} }
#ifdef YAX_ENABLE
j = 0;
for (i=0; i<numyaxbunches; i++)
{
// only back up complete bunches
if (numsectsofbunch[i] == yax_numsectsinbunch(i, 0)+yax_numsectsinbunch(i, 1))
otonbunch[i] = j++;
else
otonbunch[i] = -1;
}
mapinfo->numyaxbunches = j;
#endif
// count walls & sprites // count walls & sprites
for (i=0; i<highlightsectorcnt; i++) for (i=0; i<highlightsectorcnt; i++)
{ {
@ -1483,21 +1532,31 @@ static int32_t backup_highlighted_map(mapinfofull_t *mapinfo)
} }
// allocate temp storage // allocate temp storage
mapinfo->sector = Bmalloc(highlightsectorcnt * sizeof(sectortype)); ptrs[np++] = mapinfo->sector = Bmalloc(highlightsectorcnt * sizeof(sectortype));
if (!mapinfo->sector) return -2; if (!mapinfo->sector) return -2;
mapinfo->wall = Bmalloc(tmpnumwalls * sizeof(walltype)); ptrs[np++] = mapinfo->wall = Bmalloc(tmpnumwalls * sizeof(walltype));
if (!mapinfo->wall) { Bfree(mapinfo->sector); return -2; } if (!mapinfo->wall) { free_n_ptrs(ptrs, np-1); return -2; }
#ifdef YAX_ENABLE
if (mapinfo->numyaxbunches > 0)
{
ptrs[np++] = mapinfo->bunchnum = Bmalloc(highlightsectorcnt*2*sizeof(int16_t));
if (!mapinfo->bunchnum) { free_n_ptrs(ptrs, np-1); return -2; }
ptrs[np++] = mapinfo->ynextwall = Bmalloc(tmpnumwalls*2*sizeof(int16_t));
if (!mapinfo->ynextwall) { free_n_ptrs(ptrs, np-1); return -2; }
}
else
{
mapinfo->bunchnum = mapinfo->ynextwall = NULL;
}
#endif
if (tmpnumsprites>0) if (tmpnumsprites>0)
{ {
mapinfo->sprite = Bmalloc(tmpnumsprites * sizeof(spritetype)); ptrs[np++] = mapinfo->sprite = Bmalloc(tmpnumsprites * sizeof(spritetype));
if (!mapinfo->sprite) if (!mapinfo->sprite) { free_n_ptrs(ptrs, np-1); return -2; }
{
Bfree(mapinfo->sector);
Bfree(mapinfo->wall);
return -2;
}
} }
else else
{ {
@ -1515,11 +1574,35 @@ static int32_t backup_highlighted_map(mapinfofull_t *mapinfo)
Bmemcpy(&mapinfo->sector[i], &sector[k], sizeof(sectortype)); Bmemcpy(&mapinfo->sector[i], &sector[k], sizeof(sectortype));
mapinfo->sector[i].wallptr = tmpnumwalls; mapinfo->sector[i].wallptr = tmpnumwalls;
#ifdef YAX_ENABLE
if (mapinfo->numyaxbunches > 0)
{
int16_t bn[2];
yax_getbunches(k, &bn[0], &bn[1]);
for (j=0; j<2; j++)
mapinfo->bunchnum[2*i + j] = (bn[j]>=0) ? otonbunch[bn[j]] : -1;
}
#endif
for (j=0; j<sector[k].wallnum; j++) for (j=0; j<sector[k].wallnum; j++)
{ {
Bmemcpy(&mapinfo->wall[tmpnumwalls+j], &wall[sector[k].wallptr+j], sizeof(walltype)); m = sector[k].wallptr;
mapinfo->wall[tmpnumwalls+j].point2 += (tmpnumwalls-sector[k].wallptr); Bmemcpy(&mapinfo->wall[tmpnumwalls+j], &wall[m+j], sizeof(walltype));
mapinfo->wall[tmpnumwalls+j].point2 += (tmpnumwalls-m);
#ifdef YAX_ENABLE
if (mapinfo->numyaxbunches > 0)
{
int32_t ynw, cf;
for (cf=0; cf<2; cf++)
{
ynw = yax_getnextwall(m+j, cf);
mapinfo->ynextwall[2*(tmpnumwalls+j) + cf] = (ynw >= 0) ? otonwall[ynw] : -1;
}
}
#endif
m = mapinfo->wall[tmpnumwalls+j].nextsector; m = mapinfo->wall[tmpnumwalls+j].nextsector;
if (m < 0 || otonsect[m] < 0) if (m < 0 || otonsect[m] < 0)
{ {
@ -1556,6 +1639,13 @@ static int32_t backup_highlighted_map(mapinfofull_t *mapinfo)
static void mapinfofull_free(mapinfofull_t *mapinfo) static void mapinfofull_free(mapinfofull_t *mapinfo)
{ {
Bfree(mapinfo->sector); Bfree(mapinfo->sector);
#ifdef YAX_ENABLE
if (mapinfo->numyaxbunches > 0)
{
Bfree(mapinfo->bunchnum);
Bfree(mapinfo->ynextwall);
}
#endif
Bfree(mapinfo->wall); Bfree(mapinfo->wall);
if (mapinfo->numsprites>0) if (mapinfo->numsprites>0)
Bfree(mapinfo->sprite); Bfree(mapinfo->sprite);
@ -1572,6 +1662,9 @@ static int32_t restore_highlighted_map(mapinfofull_t *mapinfo)
updatenumsprites(); updatenumsprites();
if (numsectors+mapinfo->numsectors>MAXSECTORS || numwalls+mapinfo->numwalls>MAXWALLS if (numsectors+mapinfo->numsectors>MAXSECTORS || numwalls+mapinfo->numwalls>MAXWALLS
#ifdef YAX_ENABLE
|| numyaxbunches+mapinfo->numyaxbunches > YAX_MAXBUNCHES
#endif
|| numsprites+mapinfo->numsprites>MAXSPRITES) || numsprites+mapinfo->numsprites>MAXSPRITES)
{ {
mapinfofull_free(mapinfo); mapinfofull_free(mapinfo);
@ -1586,8 +1679,6 @@ static int32_t restore_highlighted_map(mapinfofull_t *mapinfo)
Bmemcpy(&wall[numwalls], mapinfo->wall, mapinfo->numwalls*sizeof(walltype)); Bmemcpy(&wall[numwalls], mapinfo->wall, mapinfo->numwalls*sizeof(walltype));
// tweak index members // tweak index members
for (i=numsectors; i<newnumsectors; i++)
sector[i].wallptr += numwalls;
for (i=numwalls; i<newnumwalls; i++) for (i=numwalls; i<newnumwalls; i++)
{ {
wall[i].point2 += numwalls; wall[i].point2 += numwalls;
@ -1597,17 +1688,37 @@ static int32_t restore_highlighted_map(mapinfofull_t *mapinfo)
wall[i].nextsector += numsectors; wall[i].nextsector += numsectors;
wall[i].nextwall += numwalls; wall[i].nextwall += numwalls;
} }
#ifdef YAX_ENABLE
for (j=0; j<2; j++)
{
if (mapinfo->numyaxbunches > 0)
yax_setnextwall(i, j, mapinfo->ynextwall[2*(i-numwalls) + j]>=0 ?
numwalls+mapinfo->ynextwall[2*(i-numwalls) + j] : -1);
else
yax_setnextwall(i, j, -1);
}
#endif
} }
for (i=numsectors; i<newnumsectors; i++)
sector[i].wallptr += numwalls;
// highlight copied sectors // highlight copied sectors
numsectors = newnumsectors; numsectors = newnumsectors;
Bmemset(hlsectorbitmap, 0, sizeof(hlsectorbitmap)); Bmemset(hlsectorbitmap, 0, sizeof(hlsectorbitmap));
for (i=onumsectors; i<newnumsectors; i++) for (i=onumsectors; i<newnumsectors; i++)
{ {
hlsectorbitmap[i>>3] |= (1<<(i&7)); hlsectorbitmap[i>>3] |= (1<<(i&7));
#ifdef YAX_ENABLE #ifdef YAX_ENABLE
yax_setbunches(i, -1, -1); for (j=0; j<2; j++)
if (mapinfo->numyaxbunches > 0)
yax_setbunch(i, j, mapinfo->bunchnum[2*(i-onumsectors)+j] >= 0 ?
numyaxbunches + mapinfo->bunchnum[2*(i-onumsectors)+j] : -2);
else
yax_setbunch(i, j, -2);
// -2 clears forward yax-nextwall links
#endif #endif
} }
@ -1620,12 +1731,19 @@ static int32_t restore_highlighted_map(mapinfofull_t *mapinfo)
sprite[j].sectnum = sect; sprite[j].sectnum = sect;
} }
mapinfofull_free(mapinfo);
numwalls = newnumwalls; numwalls = newnumwalls;
updatenumsprites(); updatenumsprites();
update_highlightsector(); update_highlightsector();
mapinfofull_free(mapinfo); #ifdef YAX_ENABLE
if (mapinfo->numyaxbunches > 0)
yax_update(0);
#endif
yax_updategrays(pos.z);
return 0; return 0;
} }

View file

@ -308,6 +308,9 @@ void yax_getbunches(int16_t i, int16_t *cb, int16_t *fb)
*fb = yax_getbunch(i, YAX_FLOOR); *fb = yax_getbunch(i, YAX_FLOOR);
} }
// bunchnum: -1: also clear yax-nextwalls (forward and reverse)
// -2: don't clear reverse yax-nextwalls
// -3: don't clear either forward or reverse yax-nextwalls
void yax_setbunch(int16_t i, int16_t cf, int16_t bunchnum) void yax_setbunch(int16_t i, int16_t cf, int16_t bunchnum)
{ {
if (editstatus==0) if (editstatus==0)
@ -316,19 +319,23 @@ void yax_setbunch(int16_t i, int16_t cf, int16_t bunchnum)
return; return;
} }
if (bunchnum<0) if (bunchnum < 0)
{ {
int32_t j; int32_t j;
int16_t ynw; int16_t ynw;
// TODO: for in-game too? if (bunchnum > -3)
for (j=sector[i].wallptr; j<sector[i].wallptr+sector[i].wallnum; j++)
{ {
ynw = yax_getnextwall(j, cf); // TODO: for in-game too?
if (ynw >= 0) for (j=sector[i].wallptr; j<sector[i].wallptr+sector[i].wallnum; j++)
{ {
yax_setnextwall(ynw, !cf, -1); ynw = yax_getnextwall(j, cf);
yax_setnextwall(j, cf, -1); if (ynw >= 0)
{
if (bunchnum > -2)
yax_setnextwall(ynw, !cf, -1);
yax_setnextwall(j, cf, -1);
}
} }
} }