Modified the routine for the cif-output "bloat-all <dist>" operator

to make it slightly more efficient.  Noting, however, that it is
still highly inefficient relative to the stepped "grow" + "and"
(or "and-not") operators that it was supposed to replace, I also
implemented a convenience function "repeat <steps>" ... "endrepeat"
to the tech file syntax.  This allows the "grow" + "and" series to
be defined with a few lines, whereas if the steps have to be
spelled out, the series can be scores or hundreds of lines long.
This commit is contained in:
R. Timothy Edwards 2026-03-01 21:35:00 -05:00
parent f3478cba7b
commit ecd6ec56ae
2 changed files with 51 additions and 24 deletions

View File

@ -1500,6 +1500,7 @@ cifBloatAllFunc(
while (!StackEmpty(BloatStack))
{
Rect cifarea;
TileType tt;
POPTILE(t, dinfo, BloatStack);
@ -1516,8 +1517,6 @@ cifBloatAllFunc(
if (op->co_distance > 0)
{
Rect cifarea;
cifarea.r_xbot = area.r_xbot;
cifarea.r_ybot = area.r_ybot;
cifarea.r_xtop = area.r_xtop;
@ -1555,40 +1554,42 @@ cifBloatAllFunc(
{
tt = TiGetTypeExact(t);
if (op->co_distance > 0)
GeoClip(&area, &clipArea);
DBNMPaintPlane(cifPlane, TiGetTypeExact(t), &area,
DBNMPaintPlane(cifPlane, TiGetTypeExact(t), &cifarea,
CIFPaintTable, (PaintUndoInfo *) NULL);
else
DBNMPaintPlane(cifPlane, TiGetTypeExact(t), &area,
CIFPaintTable, (PaintUndoInfo *) NULL);
}
/* Top */
for (tp = RT(t); RIGHT(tp) > LEFT(t); tp = BL(tp))
if (TTMaskHasType(connect, TiGetBottomType(tp)))
PUSHTILE(tp,
(SplitDirection(tp) == ((tt & TT_DIRECTION) ? 1 : 0)) ?
(TileType)0 : (TileType)TT_SIDE,
BloatStack);
if ((op->co_distance == 0) || (area.r_ytop < clipArea.r_ytop))
for (tp = RT(t); RIGHT(tp) > LEFT(t); tp = BL(tp))
if (TTMaskHasType(connect, TiGetBottomType(tp)))
PUSHTILE(tp, (SplitDirection(tp) == ((tt & TT_DIRECTION) ? 1 : 0)) ?
(TileType)0 : (TileType)TT_SIDE, BloatStack);
/* Left */
for (tp = BL(t); BOTTOM(tp) < TOP(t); tp = RT(tp))
if (TTMaskHasType(connect, TiGetRightType(tp)))
PUSHTILE(tp, (TileType)TT_SIDE, BloatStack);
if ((op->co_distance == 0) || (area.r_xbot > clipArea.r_xbot))
for (tp = BL(t); BOTTOM(tp) < TOP(t); tp = RT(tp))
if (TTMaskHasType(connect, TiGetRightType(tp)))
PUSHTILE(tp, (TileType)TT_SIDE, BloatStack);
/* Bottom */
for (tp = LB(t); LEFT(tp) < RIGHT(t); tp = TR(tp))
if (TTMaskHasType(connect, TiGetTopType(tp)))
PUSHTILE(tp,
(SplitDirection(tp) == ((tt & TT_DIRECTION) ? 1 : 0)) ?
(TileType)TT_SIDE : (TileType)0,
BloatStack);
if ((op->co_distance == 0) || (area.r_ybot > clipArea.r_ybot))
for (tp = LB(t); LEFT(tp) < RIGHT(t); tp = TR(tp))
if (TTMaskHasType(connect, TiGetTopType(tp)))
PUSHTILE(tp, (SplitDirection(tp) == ((tt & TT_DIRECTION) ? 1 : 0)) ?
(TileType)TT_SIDE : (TileType)0, BloatStack);
/* Right */
for (tp = TR(t); TOP(tp) > BOTTOM(t); tp = LB(tp))
if (TTMaskHasType(connect, TiGetLeftType(tp)))
PUSHTILE(tp, (TileType)0, BloatStack);
if ((op->co_distance == 0) || (area.r_xtop < clipArea.r_xtop))
for (tp = TR(t); TOP(tp) > BOTTOM(t); tp = LB(tp))
if (TTMaskHasType(connect, TiGetLeftType(tp)))
PUSHTILE(tp, (TileType)0, BloatStack);
}
/* Clear self */
TiSetClient(tile, CIF_UNPROCESSED);
// TiSetClient(tile, CIF_UNPROCESSED);
/* NOTE: Tiles must be cleared after the bloat-all function has
* completed. However, for bloat-all with a limiting distance,

View File

@ -432,7 +432,8 @@ TechLoad(filename, initmask)
char suffix[20], line[MAXLINESIZE], *realname;
char *argv[MAXARGS];
SectionID mask, badMask;
int argc, s;
int argc, s, repeatcount = 0;
off_t repeatpos;
bool retval, skip;
filestack *fstack, *newstack;
filestack topfile;
@ -603,6 +604,31 @@ TechLoad(filename, initmask)
skip = FALSE;
while ((argc = techGetTokens(line, sizeof line, &fstack, argv)) >= 0)
{
/* Check for end-of-loop */
if ((argc == 1) && (!strcmp(argv[0], "endrepeat")))
{
if (repeatcount > 0)
{
repeatcount--;
fseek(fstack->file, repeatpos, SEEK_SET);
}
continue;
}
/* "repeat <number>" reads the lines until "endrepeat" <number> times */
else if ((argc == 2) && (!strcmp(argv[0], "repeat")))
{
char *endptr;
repeatcount = (off_t)strtol(argv[1], &endptr, 0);
if (*endptr != '\0')
{
TechError("Error: \"repeat\" with invalid count %s\n", argv[1]);
repeatcount = 0;
}
else
repeatpos = ftell(fstack->file);
continue;
}
/* Check for file inclusions (can be nested) */
if ((argc > 1) && (!strcmp(argv[0], "include")))
{