kGKv-)i}V_KmA6B@NGIAIp9rd;Y0mH
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
Sf57
@@ -227,6 +227,8 @@ KV KvBlendR(KV kv1, KV kv2, real r)
KV KvBlendN(KV kv1, KV kv2, int n1, int n2)
{
Assert(FBetween(n1, 0, n2));
+ if (n2 == 0)
+ n2 = 1;
return Rgb((RgbR(kv2) - RgbR(kv1)) * n1 / n2 + RgbR(kv1),
(RgbG(kv2) - RgbG(kv1)) * n1 / n2 + RgbG(kv1),
(RgbB(kv2) - RgbB(kv1)) * n1 / n2 + RgbB(kv1));
@@ -646,7 +648,7 @@ void CCol::BitmapSet(KV kv)
if (kv == kvBlack || kv == kvWhite || kv == ~0) {
// For the simplest colors, set 32 bits at a time.
- l = kv == kvBlack ? 0 : ~0;
+ l = kv == kvBlack ? 0 : dwSet;
pl = (dword *)_Pb(0);
for (il = m_y * m_clRow; il > 0; il--)
*pl++ = l;
@@ -976,7 +978,7 @@ void CCol::ColmapExchange(KV kv1, KV kv2)
for (y = 0; y < m_y; y++)
for (x = 0; x < m_x; x++) {
- kv = Get(x, y);
+ kv = _Get(x, y);
if (kv == kv1)
Set(x, y, kv2);
else if (kv == kv2)
@@ -994,7 +996,7 @@ void CCol::ColmapOrAndKv(KV kv, int nOp)
for (y = 0; y < m_y; y++)
for (x = 0; x < m_x; x++) {
- kvT = Get(x, y);
+ kvT = _Get(x, y);
switch (nOp) {
// Boolean bit combining
@@ -2120,6 +2122,42 @@ flag CCol::FColmapBlendFromBitmap(CONST CMon *b1, CONST CMon *b2,
}
+// Make a color bitmap an equal blending together of N other color bitmaps.
+// The N other bitmaps are stacked vertically within a second bitmap. Black
+// pixels are skipped, and make that subbitmap not contribute to the result.
+
+void CCol::ColmapBlendBitmaps(CONST CCol &c)
+{
+ int cc, x, y, i, nT, ccol, nR, nG, nB;
+ KV kv;
+
+ BitmapOff();
+ cc = c.m_y + (m_y - 1) / m_y;
+ for (y = 0; y < m_y; y++)
+ for (x = 0; x < m_x; x++) {
+ ccol = nR = nG = nB = 0;
+ for (i = 0; i < cc; i++) {
+ kv = c.Get(x, i * m_y + y);
+ if (kv == kvBlack)
+ continue;
+ ccol++;
+ nR += RgbR(kv);
+ nG += RgbG(kv);
+ nB += RgbB(kv);
+ }
+ if (ccol <= 0)
+ continue;
+ nT = ccol >> 1;
+ nR = (nR + nT) / ccol;
+ nG = (nG + nT) / ccol;
+ nB = (nB + nT) / ccol;
+ kv = Rgb(nR, nG, nB);
+ if (kv != kvBlack)
+ Set(x, y, kv);
+ }
+}
+
+
// Copy a monochrome bitmap to a color bitmap, where off and on pixels in the
// monochrome bitmap are mapped to the passed in colors. All off pixels
// reachable from a start point or points will be filled with a blend of
@@ -2503,6 +2541,8 @@ flag CCol::FReadColmapTarga(FILE *file)
for (i = 0; i < 12; i++)
skipbyte();
+ if (feof(file))
+ return fFalse;
fscanf(file, "%c%c", S1(&ch), S1(&chR));
x = (int)(chR)*256 + (int)ch;
fscanf(file, "%c%c", S1(&ch), S1(&chR));
@@ -2512,6 +2552,8 @@ flag CCol::FReadColmapTarga(FILE *file)
skipword();
for (y = m_y-1; y >= 0; y--) {
for (x = 0; x < m_x; x++) {
+ if (feof(file))
+ return fFalse;
fscanf(file, "%c%c%c%c", S1(&chB), S1(&chG), S1(&chR), S1(&ch));
Set(x, y, Rgb(chR, chG, chB));
}
diff --git a/color.h b/color.h
index d1723d8..c29a109 100644
--- a/color.h
+++ b/color.h
@@ -1,9 +1,9 @@
/*
-** Daedalus (Version 3.3) File: color.h
+** Daedalus (Version 3.4) File: color.h
** By Walter D. Pullen, Astara@msn.com, http://www.astrolog.org/labyrnth.htm
**
** IMPORTANT NOTICE: Daedalus and all Maze generation and general
-** graphics routines used in this program are Copyright (C) 1998-2018 by
+** graphics routines used in this program are Copyright (C) 1998-2023 by
** Walter D. Pullen. Permission is granted to freely use, modify, and
** distribute these routines provided these credits and notices remain
** unmodified with any altered or distributed versions of the program.
@@ -24,7 +24,7 @@
** on a color bitmap, unrelated to Mazes.
**
** Old last code change: 6/29/1990.
-** Last code change: 11/29/2018.
+** Last code change: 8/29/2023.
*/
/*
@@ -104,9 +104,12 @@ enum _colorreplace {
#define UdD(l) ((int)((dword)(l) >> 12))
#define ITextureWall(kv, d) ((int)(((kv) >> ((d) * 6)) & (cTexture-1)))
#define ITextureWall2(kv, d) ((int)(((kv) >> (FOdd(d) * 12)) & 4095))
+#define ITextureWall3(kv, d) ((int)(((kv) >> (((d) > 1) * 12)) & 4095))
#define GetT(c, x, y, d) ITextureWall((c).Get(x, y), d)
#define SetT(c, x, y, d, t) ((c).Get(x, y) & \
~((KV)(cTexture-1) << ((d) * 6)) | ((KV)(t) << ((d) * 6)))
+#define SetU(c, x, y, f, t) ((c).Get(x, y) & \
+ ~((KV)4095 << ((f) * 12)) | ((KV)(t) << ((f) * 12)))
/*
@@ -214,6 +217,7 @@ class CCol : virtual public CMap // Color bitmap
flag FColmapPutToBitmap(CMon &, int) CONST;
void ColmapOrAndFromBitmap(CONST CMon &, KV, KV, int);
flag FColmapBlendFromBitmap(CONST CMon *, CONST CMon *, CONST CMon *);
+ void ColmapBlendBitmaps(CONST CCol &);
flag FColmapBlur(flag);
void ColmapContrast(flag);
diff --git a/command.cpp b/command.cpp
index 8928a34..cea7dfd 100644
--- a/command.cpp
+++ b/command.cpp
@@ -1,9 +1,9 @@
/*
-** Daedalus (Version 3.3) File: command.cpp
+** Daedalus (Version 3.4) File: command.cpp
** By Walter D. Pullen, Astara@msn.com, http://www.astrolog.org/labyrnth.htm
**
** IMPORTANT NOTICE: Daedalus and all Maze generation and general
-** graphics routines used in this program are Copyright (C) 1998-2018 by
+** graphics routines used in this program are Copyright (C) 1998-2023 by
** Walter D. Pullen. Permission is granted to freely use, modify, and
** distribute these routines provided these credits and notices remain
** unmodified with any altered or distributed versions of the program.
@@ -24,7 +24,7 @@
** execute macros and script files.
**
** Created: 11/26/2001.
-** Last code change: 11/29/2018.
+** Last code change: 8/29/2023.
*/
#include
@@ -184,6 +184,7 @@ CONST CMD rgcmd[ccmd] = {
{cmdCreateInfinite3, "InfiniteRestart", "", MZ | M2},
{cmdCreateKruskal, "Kruskal", "al", MZ | ME | M2},
{cmdCreateLabyrinth, "Labyrinth", "C", MZ | ME | M2},
+{cmdCreateOmicron, "Omicron", "", MZ | ME | M2},
{cmdCreatePatchOverview, "MakePatch", "", HG},
{cmdCreatePerfect, "Perfect", "P", MZ | ME | M2},
{cmdCreatePlanair, "Planair", "J", MZ | M2},
@@ -445,6 +446,7 @@ CONST CMD rgcmd[ccmd] = {
{cmdScript27, "Script27", "ac7", 0},
{cmdScript28, "Script28", "ac8", 0},
{cmdScript29, "Script29", "ac9", 0},
+{cmdScript30, "Script30", "ac0", 0},
{cmdScrollDown, "ScrollDown", "aPgDn",R2},
{cmdScrollEnd, "ScrollEnd", "aEnd", R2},
{cmdScrollHome, "ScrollHome", "aHome",R2},
@@ -556,6 +558,7 @@ enum _operationindex {
oprOpenPaint,
oprOpenWire,
oprOpenPatch,
+ oprDlgDB,
oprDlgPaint,
oprEmbedXbm,
oprEmbed3D,
@@ -578,6 +581,7 @@ enum _operationindex {
oprSaveOverview,
oprSavePatch,
oprSavePicture,
+ oprSaveVector,
oprSaveSolids,
oprSize,
oprSizeC,
@@ -659,6 +663,7 @@ enum _operationindex {
oprSetCE,
oprSetCA,
oprSetX,
+ oprSetY,
oprSet3,
oprSet3T,
oprSet3E,
@@ -668,6 +673,7 @@ enum _operationindex {
oprSet3CE,
oprSet3CA,
oprSet3X,
+ oprSet3Y,
oprZapTexture,
oprMark2,
oprUnmark2,
@@ -676,6 +682,7 @@ enum _operationindex {
oprTextFont,
oprPerimeter,
oprThicken2,
+ oprBlendN,
oprConvex,
oprAllMoire,
opr2ndLine2,
@@ -701,12 +708,15 @@ enum _operationindex {
oprSymmetricX,
oprSymmetricY,
oprSymmetricZ,
+ oprZoomPic,
oprOverview2,
oprAltitude,
oprGetWire,
oprSetWire,
oprGetPatch,
oprSetPatch,
+ oprGetStar,
+ oprSetStar,
oprStereogram,
oprSetLife,
oprEvolution,
@@ -735,6 +745,7 @@ CONST OPR rgopr[copr] = {
{oprOpenPaint, "OpenPaint", 1, SZ | R2 | C2},
{oprOpenWire, "OpenWire", 1, SZ},
{oprOpenPatch, "OpenPatch", 1, SZ},
+{oprDlgDB, "DlgOpenDB", 0, R2},
{oprDlgPaint, "DlgOpenPaint", 0, R2 | C2},
{oprEmbedXbm, "EmbedX11", 0, R2 | B2},
{oprEmbed3D, "Embed3D", 0, R2 | B2 | M3},
@@ -757,6 +768,7 @@ CONST OPR rgopr[copr] = {
{oprSaveOverview,"SaveWire", 1, SZ},
{oprSavePatch, "SavePatch", 1, SZ},
{oprSavePicture, "SavePicture", 1, SZ},
+{oprSaveVector, "SaveVector", 1, SZ},
{oprSaveSolids, "SaveSolids", 1, SZ},
{oprSize, "Size", 4, R2 | B1},
{oprSizeC, "SizeC", 4, R2 | C1},
@@ -838,6 +850,7 @@ CONST OPR rgopr[copr] = {
{oprSetCE, "SetCE", 3, 0},
{oprSetCA, "SetCA", 4, R1},
{oprSetX, "SetX", 4, R1},
+{oprSetY, "SetY", 4, R1},
{oprSet3, "Set3", 4, R2},
{oprSet3T, "Set3T", 4, R1},
{oprSet3E, "Set3E", 4, R1},
@@ -847,6 +860,7 @@ CONST OPR rgopr[copr] = {
{oprSet3CE, "Set3CE", 4, 0},
{oprSet3CA, "Set3CA", 5, R1},
{oprSet3X, "Set3X", 5, R1},
+{oprSet3Y, "Set3Y", 5, R1},
{oprZapTexture, "ZapTexture", 1, R1},
{oprMark2, "MarkX2", 0, R1},
{oprUnmark2, "EraseX2", 0, R1},
@@ -855,6 +869,7 @@ CONST OPR rgopr[copr] = {
{oprTextFont, "TextFont", 3, SZ},
{oprPerimeter, "Perimeter", 0, 0},
{oprThicken2, "Thicken2", 1, R2 | HG | B1},
+{oprBlendN, "BlendN", 0, R2 | HG},
{oprConvex, "Convex", 0, R2 | HG | B1},
{oprAllMoire, "AllMoire", 0, R2 | HG | B2},
{opr2ndLine2, "2ndLineUntil", 1, R2 | B2},
@@ -880,12 +895,15 @@ CONST OPR rgopr[copr] = {
{oprSymmetricX, "SymmetricX", 0, R2 | HG | B1 | M2},
{oprSymmetricY, "SymmetricY", 0, R2 | HG | B1 | M2},
{oprSymmetricZ, "SymmetricZ", 0, R2 | HG | B1 | M2},
+{oprZoomPic, "ZoomBiasPic", 0, R2 | HG | B1 | M2},
{oprOverview2, "Overview2", 0, R2 | HG},
{oprAltitude, "Altitude", 2, R2 | HG | NC | M2},
{oprGetWire, "GetWireframe", 2, 0},
{oprSetWire, "SetWireframe", 2, 0},
{oprGetPatch, "GetPatch", 2, 0},
{oprSetPatch, "SetPatch", 2, 0},
+{oprGetStar, "GetStar", 3, 0},
+{oprSetStar, "SetStar", 5, R2},
{oprStereogram, "Stereogram", 2, R2 | HG},
{oprSetLife, "SetLife", 1, 0},
{oprEvolution, "Evolution", 2, R2 | HG | C1},
@@ -1192,6 +1210,7 @@ enum _variableindex {
varSunMoon2,
varSunMoonY,
varStarColor,
+ varStarSize,
varSkyAll,
varSky3D,
varShowDelay,
@@ -1215,6 +1234,7 @@ enum _variableindex {
varTextureVar,
varTextureElev,
varTextureDual,
+ varTextureDual2,
varTextureBlend,
varMarkElevX1,
varMarkElevY1,
@@ -1235,6 +1255,7 @@ enum _variableindex {
varLineSort,
varLineDistance,
varFaceOrigin,
+ varStereo3D,
varWireCount,
varPatchCount,
varMandelbrot,
@@ -1534,6 +1555,7 @@ CONST VAR rgvar[cvar] = {
{varSunMoon2, "nSunMoon", R1},
{varSunMoonY, "nSunMoonY", R1},
{varStarColor, "nStarColor", 0},
+{varStarSize, "nStarSize", R1},
{varSkyAll, "fSkyAll", R1},
{varSky3D, "fSky3D", R1},
{varShowDelay, "fFrameDelay", R1},
@@ -1557,6 +1579,7 @@ CONST VAR rgvar[cvar] = {
{varTextureVar, "nTextureBlock", R1},
{varTextureElev, "nTextureElev", R1},
{varTextureDual, "fTextureDual", R1},
+{varTextureDual2, "fTextureDual2", R1},
{varTextureBlend, "fTextureBlend", R1},
{varMarkElevX1, "nMarkElevX1", 0},
{varMarkElevY1, "nMarkElevY1", 0},
@@ -1577,6 +1600,7 @@ CONST VAR rgvar[cvar] = {
{varLineSort, "fWireSort", R1},
{varLineDistance, "nWireDistance", R1},
{varFaceOrigin, "nDrawFaceOrigin", R1},
+{varStereo3D, "fStereo3D", R1},
{varWireCount, "nWireframeSize", 0},
{varPatchCount, "nPatchSize", 0},
{varMandelbrot, "fMandelbrotShip", 0},
@@ -1619,15 +1643,19 @@ enum _functionindex {
funInv,
funShftL,
funShftR,
+ funAndL,
+ funOrL,
funOdd,
funAbs,
funSgn,
funMin,
funMax,
+ funTween,
funRnd,
funIf,
funSqr,
funDist,
+ funLn,
funSin,
funCos,
funTan,
@@ -1746,15 +1774,19 @@ CONST FUN rgfun[cfun] = {
{funInv, "Inv", 1},
{funShftL, "<<", 2},
{funShftR, ">>", 2},
+{funAndL, "&&", 2},
+{funOrL, "||", 2},
{funOdd, "Odd", 1},
{funAbs, "Abs", 1},
{funSgn, "Sgn", 1},
{funMin, "Min", 2},
{funMax, "Max", 2},
+{funTween, "Tween", 3},
{funRnd, "Rnd", 2},
{funIf, "?:", 3},
{funSqr, "Sqr", 1},
{funDist, "Dist", 4},
+{funLn, "Ln", 2},
{funSin, "Sin", 2},
{funCos, "Cos", 2},
{funTan, "Tan", 2},
@@ -2014,6 +2046,7 @@ void DoSetVariable(int ivar, CONST char *sz, int cch, long l)
case varFogLength: dr.nFog = n; break;
case varClipPlane: dr.nClip = n; break;
case varViewSpan: dr.dInside = (real)n / 100.0; break;
+ case varStereo: ds.nStereo = n; break;
case varTrans: dr.nTrans = n; break;
case varFrameMove: dr.nFrameXY = n; break;
case varFrameTurn: dr.nFrameD = n; break;
@@ -2168,6 +2201,7 @@ void DoSetVariable(int ivar, CONST char *sz, int cch, long l)
case varSunMoon2: dr.nSunMoon = n; break;
case varSunMoonY: dr.ySunMoon = n; break;
case varStarColor: ds.lStarColor = n; break;
+ case varStarSize: ds.nStarSize = n; break;
case varSkyAll: ds.fSkyAll = f; break;
case varSky3D: dr.fSky3D = f; break;
case varShowDelay: dr.fDelay = f; break;
@@ -2191,12 +2225,12 @@ void DoSetVariable(int ivar, CONST char *sz, int cch, long l)
case varTextureVar: dr.nTextureVar = n; break;
case varTextureElev: dr.nTextureElev = n; break;
case varTextureDual: dr.fTextureDual = f; break;
+ case varTextureDual2: dr.fTextureDual2 = f; break;
case varTextureBlend: dr.fTextureBlend = f; break;
case varMarkElevX1: dr.nMarkElevX1 = n; break;
case varMarkElevY1: dr.nMarkElevY1 = n; break;
case varMarkElevX2: dr.nMarkElevX2 = n; break;
case varMarkElevY2: dr.nMarkElevY2 = n; break;
- case varStereo: dr.nStereo = n; break;
case varMazeCellMax: ms.nCellMax = n; break;
case varHuntType: ms.nHuntType = n; break;
case varFractalDepth: ms.nFractalD = n; break;
@@ -2212,6 +2246,7 @@ void DoSetVariable(int ivar, CONST char *sz, int cch, long l)
case varLineSort: ds.fWireSort = f; break;
case varLineDistance: ds.nWireDistance = n; break;
case varFaceOrigin: ds.nFaceOrigin = n; break;
+ case varStereo3D: ds.fStereo3D = f; break;
case varWireCount:
if (FSetWireSize(&bm.coor, bm.ccoor, n)) bm.ccoor = n; break;
case varPatchCount:
@@ -2377,6 +2412,7 @@ void GetVariable(int ivar, char **psz, int *pcch, long *pl)
case varFogLength: n = dr.nFog; break;
case varClipPlane: n = dr.nClip; break;
case varViewSpan: n = (int)(dr.dInside * 100.0); break;
+ case varStereo: n = ds.nStereo; break;
case varTrans: n = dr.nTrans; break;
case varFrameMove: n = dr.nFrameXY; break;
case varFrameTurn: n = dr.nFrameD; break;
@@ -2530,6 +2566,7 @@ void GetVariable(int ivar, char **psz, int *pcch, long *pl)
case varSunMoon2: n = dr.nSunMoon; break;
case varSunMoonY: n = dr.ySunMoon; break;
case varStarColor: n = ds.lStarColor; break;
+ case varStarSize: n = ds.nStarSize; break;
case varSkyAll: n = ds.fSkyAll; break;
case varSky3D: n = dr.fSky3D; break;
case varShowDelay: n = dr.fDelay; break;
@@ -2553,12 +2590,12 @@ void GetVariable(int ivar, char **psz, int *pcch, long *pl)
case varTextureVar: n = dr.nTextureVar; break;
case varTextureElev: n = dr.nTextureElev; break;
case varTextureDual: n = dr.fTextureDual; break;
+ case varTextureDual2: n = dr.fTextureDual2; break;
case varTextureBlend: n = dr.fTextureBlend; break;
case varMarkElevX1: n = dr.nMarkElevX1; break;
case varMarkElevY1: n = dr.nMarkElevY1; break;
case varMarkElevX2: n = dr.nMarkElevX2; break;
case varMarkElevY2: n = dr.nMarkElevY2; break;
- case varStereo: n = dr.nStereo; break;
case varMazeCellMax: n = ms.nCellMax; break;
case varHuntType: n = ms.nHuntType; break;
case varFractalDepth: n = ms.nFractalD; break;
@@ -2574,6 +2611,7 @@ void GetVariable(int ivar, char **psz, int *pcch, long *pl)
case varLineSort: n = ds.fWireSort; break;
case varLineDistance: n = ds.nWireDistance; break;
case varFaceOrigin: n = ds.nFaceOrigin; break;
+ case varStereo3D: n = ds.fStereo3D; break;
case varWireCount: n = bm.ccoor; break;
case varPatchCount: n = bm.cpatch; break;
case varMandelbrot: n = cs.fMandelbrot; break;
@@ -2630,15 +2668,19 @@ long EvalFunction(int ifun, char *rgsz[], CONST int *rgcch, CONST long *rgl)
case funInv: n = ~n1; break;
case funShftL: n = n1 << n2; break;
case funShftR: n = n1 >> n2; break;
+ case funAndL: n = n1 && n2; break;
+ case funOrL: n = n1 || n2; break;
case funOdd: n = FOdd(n1); break;
case funAbs: n = NAbs(n1); break;
case funSgn: n = NSgn(n1); break;
case funMin: n = Min(n1, n2); break;
case funMax: n = Max(n1, n2); break;
+ case funTween: n = FBetween(n1, n2, n3); break;
case funRnd: n = Rnd(n1, n2); break;
case funIf: n = n1 ? n2 : n3; break;
case funSqr: n = NSqr(NAbs(n1)); break;
case funDist: n = (int)LengthN(n1, n2, n3, n4); break;
+ case funLn: n = (int)((real)n1 * log((real)n2)); break;
case funSin: n = (int)(((real)n1 + rRound) * RSinD((real)n2)); break;
case funCos: n = (int)(((real)n1 + rRound) * RCosD((real)n2)); break;
case funTan: n = (int)(((real)n1 + rRound) * RTanD((real)n2)); break;
@@ -2766,7 +2808,7 @@ long EvalFunction(int ifun, char *rgsz[], CONST int *rgcch, CONST long *rgl)
PchGetParameter(sz, NULL, NULL, (long *)&n, 1);
break;
case funEvent: n = NGetVariableW(n1 ? vosEventMouse : vosEventKey); break;
- case funVer: n = 3300; break; // Daedalus 3.3
+ case funVer: n = 3400; break; // Daedalus 3.4
case funFileOpen:
CopyRgchToSz(rgsz[0], rgcch[0], sz, cchSzMax);
@@ -2966,6 +3008,7 @@ int DoOperation(int iopr, char **rgsz, CONST int *rgcch, CONST long *rgl,
{
size_t cursorPrev = NULL;
CMap3 *pbSrc, *pbDst, *bT;
+ STAR *pstar;
char sz[cchSzOpr], szT[cchSzMax], sz3[cchSzDef];
char *pch, *pchT;
int nRet = 0, n1, n2, n3, n4, n5, n6, n7, x, y, cch, i;
@@ -3042,6 +3085,10 @@ int DoOperation(int iopr, char **rgsz, CONST int *rgcch, CONST long *rgl,
case oprOpenPatch:
FFileOpen(cmdOpenPatch, sz, NULL);
break;
+
+ case oprDlgDB:
+ FFileOpen(cmdOpenDB, NULL, NULL);
+ break;
case oprDlgPaint:
FFileOpen(cmdOpenColmapPaint, NULL, NULL);
break;
@@ -3110,6 +3157,9 @@ int DoOperation(int iopr, char **rgsz, CONST int *rgcch, CONST long *rgl,
case oprSavePicture:
FFileSave(cmdSavePicture, sz);
break;
+ case oprSaveVector:
+ FFileSave(cmdSaveVector, sz);
+ break;
case oprSaveSolids:
CreateSolids(sz);
break;
@@ -3475,7 +3525,8 @@ int DoOperation(int iopr, char **rgsz, CONST int *rgcch, CONST long *rgl,
pbDst = BitmapGetMask(n2);
if (iopr == oprMaskSwap &&
(n1 != -1 || !pbDst->FNull()) && (n2 != -1 || !pbSrc->FNull())) {
- pbSrc->SwapWith(*pbDst);
+ if (pbSrc != pbDst)
+ pbSrc->SwapWith(*pbDst);
break;
}
if (!pbSrc->FNull())
@@ -3493,7 +3544,8 @@ int DoOperation(int iopr, char **rgsz, CONST int *rgcch, CONST long *rgl,
pbSrc = ColmapGetTexture(n1);
pbDst = ColmapGetTexture(n2);
if (iopr == oprTextureSwap) {
- pbSrc->SwapWith(*pbDst);
+ if (pbSrc != pbDst)
+ pbSrc->SwapWith(*pbDst);
if (bm.k.FNull())
FShowColmap(fFalse);
break;
@@ -3608,7 +3660,8 @@ int DoOperation(int iopr, char **rgsz, CONST int *rgcch, CONST long *rgl,
bm.b.Turtle("_");
ws.fSpree = dr.fDot2 = dr.fSky3D = dr.fNoCompass = dr.fNoLocation =
dr.fPolishMaze = dr.fFogFloor = dr.fMarkColor = dr.fMarkAll =
- dr.fMarkBlock = dr.fTextureDual = dr.fTextureBlend = fFalse;
+ dr.fMarkBlock = dr.fTextureDual = dr.fTextureDual2 = dr.fTextureBlend =
+ fFalse;
ms.nCellMax = ws.nTitleMessage = dr.zStep =
dr.kvInWall2 = dr.kvInSky2 = dr.kvInDirt2 = dr.kvInCeil2 = dr.kvInMtn2 =
dr.kvInCld2 = dr.nMarkSky = dr.nWallVar = dr.nFogLit = -1;
@@ -3680,6 +3733,18 @@ int DoOperation(int iopr, char **rgsz, CONST int *rgcch, CONST long *rgl,
l = UD(n4, n4);
bT->Set(n1, n2, l);
break;
+ case oprSetY:
+ bT = ColmapGetTexture(dr.nTextureWall);
+ if (bT == NULL)
+ break;
+ if (n3 >= 0)
+ l = SetU(*bT, n1, n2, n3, n4);
+ else if (n3 == -1)
+ l = UD(n4, n4);
+ else
+ l = NWSE(n4, n4, n4, n4);
+ bT->Set(n1, n2, l);
+ break;
case oprSet3:
bm.b.Set3(n1, n2, n3, n4);
break;
@@ -3727,6 +3792,18 @@ int DoOperation(int iopr, char **rgsz, CONST int *rgcch, CONST long *rgl,
l = UD(n5, n5);
bT->Set3(n1, n2, n3, l);
break;
+ case oprSet3Y:
+ bT = ColmapGetTexture(dr.nTextureWall);
+ if (bT == NULL)
+ break;
+ if (n4 >= 0)
+ l = SetU3(*bT, n1, n2, n3, n4, n5);
+ else if (n4 == -1)
+ l = NWSE(n5, n5, n5, n5);
+ else
+ l = UD(n5, n5);
+ bT->Set3(n1, n2, n3, l);
+ break;
case oprZapTexture:
DotZap(cmdZapTexture, n1);
break;
@@ -3763,6 +3840,9 @@ int DoOperation(int iopr, char **rgsz, CONST int *rgcch, CONST long *rgl,
l = bm.b.BitmapThicken2(n1, !dr.fNoCorner);
SetMacroReturn(l);
break;
+ case oprBlendN:
+ bm.k.ColmapBlendBitmaps(bm.k2);
+ break;
case oprConvex:
bm.b.FBitmapConvex(xl, yl, xh, yh);
break;
@@ -3875,6 +3955,9 @@ int DoOperation(int iopr, char **rgsz, CONST int *rgcch, CONST long *rgl,
SetMacroReturn(l);
PrintSzL("Asymmetries in Maze: %ld\n", l);
break;
+ case oprZoomPic:
+ bm.b.MazeZoomWithPicture(&bm.k);
+ break;
case oprOverview2:
if (!dr.f3D)
DrawOverview2(bm.b);
@@ -3939,6 +4022,25 @@ int DoOperation(int iopr, char **rgsz, CONST int *rgcch, CONST long *rgl,
bm.patch[n1].nTrans = (short)ws.rglVar[y+2];
}
break;
+ case oprGetStar:
+ pstar = !n1 ? dr.rgstar : ds.rgstar;
+ if (pstar != NULL && FBetween(n2, 0, istarMax-1) &&
+ FEnsureLVar(n3 + 2)) {
+ ws.rglVar[n3] = pstar[n2].x;
+ ws.rglVar[n3+1] = pstar[n2].y;
+ ws.rglVar[n3+2] = pstar[n2].kv;
+ }
+ break;
+ case oprSetStar:
+ if (dr.rgstar == NULL)
+ FCreateInsideStars(NULL, 0.0, 0, fFalse);
+ pstar = !n1 ? dr.rgstar : ds.rgstar;
+ if (pstar != NULL && FBetween(n2, 0, istarMax-1)) {
+ pstar[n2].x = n3;
+ pstar[n2].y = n4;
+ pstar[n2].kv = ParseColor(rgsz[4], fFalse);
+ }
+ break;
case oprStereogram:
if (!bm.fColor)
bm.b.FStereogram(bm.b2, n1, n2);
@@ -5480,6 +5582,10 @@ flag DoCommand(int wCmd)
bm.b.CreateMazeUpsilon();
break;
+ case cmdCreateOmicron:
+ bm.b.CreateMazeOmicron();
+ break;
+
case cmdCreateZeta:
bm.b.CreateMazeZeta();
break;
@@ -6305,10 +6411,10 @@ char *ReadEmbedLines(FILE *file)
char szLine[cchSzOpr], ch, *sz = NULL, *szNew = NULL;
int cch = 0, i, j, fSpace;
- if (file == NULL)
+ if (file == NULL && ws.rgszStartup == NULL)
return NULL;
loop {
- for (i = 0; i < cchSzOpr && !feof(file) &&
+ for (i = 0; i < cchSzOpr && (file == NULL || !feof(file)) &&
(ch = getbyte()) >= ' '; i++)
szLine[i] = ch;
skiplf();
diff --git a/create.cpp b/create.cpp
index eec4f0d..545962b 100644
--- a/create.cpp
+++ b/create.cpp
@@ -1,9 +1,9 @@
/*
-** Daedalus (Version 3.3) File: create.cpp
+** Daedalus (Version 3.4) File: create.cpp
** By Walter D. Pullen, Astara@msn.com, http://www.astrolog.org/labyrnth.htm
**
** IMPORTANT NOTICE: Daedalus and all Maze generation and general
-** graphics routines used in this program are Copyright (C) 1998-2018 by
+** graphics routines used in this program are Copyright (C) 1998-2023 by
** Walter D. Pullen. Permission is granted to freely use, modify, and
** distribute these routines provided these credits and notices remain
** unmodified with any altered or distributed versions of the program.
@@ -24,7 +24,7 @@
** produce standard orthogonal 2D Mazes.
**
** Created: 9/4/2000.
-** Last code change: 11/29/2018.
+** Last code change: 8/29/2023.
*/
#include
@@ -1695,8 +1695,8 @@ flag CMaz::CreateMazeAldousBroder()
MazeClear(!fWall);
MakeEntranceExit(0);
if (!fWall) {
- x = RndSkip(xl + 1, xh - 1);
- y = RndSkip(yl + 1, yh - 1);
+ x = ms.fTreeRandom ? RndSkip(xl + 1, xh - 1) : xl + 1;
+ y = ms.fTreeRandom ? RndSkip(yl + 1, yh - 1) : yl + 1;
Set0(x, y);
} else
x = y = 0;
@@ -1807,7 +1807,7 @@ flag CMaz::CreateMazeWilson()
UpdateDisplay();
while (count > 0) {
- i = Rnd(0, count-1);
+ i = ms.fTreeRandom ? Rnd(0, count-1) : count-1;
x = x0 = wils[i].zList % xs; y = y0 = wils[i].zList / xs;
// From a random uncreated location, do a random walk until run into part
diff --git a/create2.cpp b/create2.cpp
index f739786..aace01b 100644
--- a/create2.cpp
+++ b/create2.cpp
@@ -1,9 +1,9 @@
/*
-** Daedalus (Version 3.3) File: create2.cpp
+** Daedalus (Version 3.4) File: create2.cpp
** By Walter D. Pullen, Astara@msn.com, http://www.astrolog.org/labyrnth.htm
**
** IMPORTANT NOTICE: Daedalus and all Maze generation and general
-** graphics routines used in this program are Copyright (C) 1998-2018 by
+** graphics routines used in this program are Copyright (C) 1998-2023 by
** Walter D. Pullen. Permission is granted to freely use, modify, and
** distribute these routines provided these credits and notices remain
** unmodified with any altered or distributed versions of the program.
@@ -24,7 +24,7 @@
** produce orthogonal Mazes, however which aren't standard 2D Mazes.
**
** Created: 11/22/1996.
-** Last code change: 11/29/2018.
+** Last code change: 8/29/2023.
*/
#include
@@ -2208,6 +2208,8 @@ flag CMaz::FValidPlanair(CONST char *sz) CONST
}
+CONST KV rgkvCube[6] = {kvGreen, kvBlue, kvMagenta, kvYellow, kvRed, kvOrange};
+
// Create a new planair Maze in a bitmap, or a Maze on the surface of a set of
// rectangles, whose edges can connect in arbitrary ways. Like a 3D Maze this
// is technically a 3D construct stored as a sequence of levels, where the
@@ -2219,6 +2221,7 @@ flag CMaz::CreateMazePlanair()
int jx = Even(m_x3), jy = Even(m_y3), jz, jw = m_w3,
fHunt = fFalse, pass = 0, x, y, z, xnew, ynew, znew,
xInc = 2, yInc = 2, zInc = 1, d, e, i, iMax, j;
+ int a0, b0, c0, ax, bx, cx, ay, by, cy;
long count;
if (!FValidPlanair(ms.szPlanair))
@@ -2312,6 +2315,54 @@ flag CMaz::CreateMazePlanair()
}
}
LDone:
+
+ // Create a wireframe for this Planair Maze if it's making a cube.
+ if (!(ms.nOmegaDraw == 1 && FEqSz(ms.szPlanair,
+ "e2d3f0b1 e7a3f3c1 e4b3f6d1 e1c3f5a1 c4d0a0b4 a2d6c6b2")))
+ return fTrue;
+ if (InitCoordinates((jx + jy) / 2 * jz) < 0)
+ return fFalse;
+ d = 25; e = d << 1;
+ i = (Max(jx, jy)-2)*d;
+ for (z = 0; z < jz; z++) {
+ ax = bx = cx = ay = by = cy = 0;
+ switch (z) {
+ case 0: a0=0; b0=1; c0=1; ax=1; by=-1; break;
+ case 1: a0=1; b0=1; c0=1; cx=-1; by=-1; break;
+ case 2: a0=1; b0=1; c0=0; ax=-1; by=-1; break;
+ case 3: a0=0; b0=1; c0=0; cx=1; by=-1; break;
+ case 4: a0=0; b0=1; c0=0; ax=1; cy=1; break;
+ case 5: a0=0; b0=0; c0=1; ax=1; cy=-1; break;
+ }
+ a0 = ((a0 << 1) - 1) * i;
+ b0 = ((b0 << 1) - 1) * i;
+ c0 = ((c0 << 1) - 1) * i;
+ ax *= e; ay *= e; bx *= e; by *= e; cx *= e; cy *= e;
+ for (y = 0; y < jy; y += 2)
+ for (x = 0; x < jx; x += 2) {
+ if (x+2 < jx && JG(x+1, y, z) && (y > 0 || PZTo(ms.szPlanair, z, 0) <
+ z) && (y < jy-2 || PZTo(ms.szPlanair, z, 2) < z))
+ FSetCoordinates(a0 + x*ax + y*ay, b0 + x*bx + y*by, c0 + x*cx + y*cy,
+ a0 + (x+2)*ax + y*ay, b0 + (x+2)*bx + y*by, c0 + (x+2)*cx + y*cy,
+ KvBlend(rgkvCube[z], rgkvCube[y <= 0 ? PZTo(ms.szPlanair, z, 0) :
+ (y >= jy-2 ? PZTo(ms.szPlanair, z, 2) : z)]));
+ if (y+2 < jy && JG(x, y+1, z) && (x > 0 || PZTo(ms.szPlanair, z, 1) <
+ z) && (x < jx-2 || PZTo(ms.szPlanair, z, 3) < z))
+ FSetCoordinates(a0 + x*ax + y*ay, b0 + x*bx + y*by, c0 + x*cx + y*cy,
+ a0 + x*ax + (y+2)*ay, b0 + x*bx + (y+2)*by, c0 + x*cx + (y+2)*cy,
+ KvBlend(rgkvCube[z], rgkvCube[x <= 0 ? PZTo(ms.szPlanair, z, 1) :
+ (x >= jx-2 ? PZTo(ms.szPlanair, z, 3) : z)]));
+ }
+ }
+ // Draw two arrows for the entrance and exit to the cube Maze.
+ for (j = -1; j <= 1; j += 2) {
+ zInc = j < 0 ? kvWhite : kvDkGray;
+ FSetCoordinates((i+d)*j, 0, 0, (i+d*10)*j, 0, 0, zInc);
+ e = j < 0 ? -i-d*10 : i+d;
+ FSetCoordinates(e, 0, 0, e+d*3, d*3, 0, zInc);
+ FSetCoordinates(e, 0, 0, e+d*3, -d*3, 0, zInc);
+ }
+ InitCoordinates(0);
return fTrue;
}
diff --git a/create3.cpp b/create3.cpp
index 8add7e4..1812917 100644
--- a/create3.cpp
+++ b/create3.cpp
@@ -1,9 +1,9 @@
/*
-** Daedalus (Version 3.3) File: create3.cpp
+** Daedalus (Version 3.4) File: create3.cpp
** By Walter D. Pullen, Astara@msn.com, http://www.astrolog.org/labyrnth.htm
**
** IMPORTANT NOTICE: Daedalus and all Maze generation and general
-** graphics routines used in this program are Copyright (C) 1998-2018 by
+** graphics routines used in this program are Copyright (C) 1998-2023 by
** Walter D. Pullen. Permission is granted to freely use, modify, and
** distribute these routines provided these credits and notices remain
** unmodified with any altered or distributed versions of the program.
@@ -24,7 +24,7 @@
** produce non-orthogonal Mazes.
**
** Created: 9/4/2000.
-** Last code change: 11/29/2018.
+** Last code change: 8/29/2023.
*/
#include
@@ -55,6 +55,8 @@ class Generic
flag FIsOnMaze(long);
void CreateMazeGeneral();
void GenerateWireframe();
+ virtual void WireframeLine(int, int, int, int);
+ virtual void WireframeOpening();
// Creates an entrance or exit, returning the cell index next to it.
virtual long LMakeOpening(int, flag) = 0;
@@ -241,46 +243,54 @@ void Generic::CreateMazeGeneral()
void Generic::GenerateWireframe()
{
long area, test, hunt;
- int count, d, x1, y1, x2, y2, f, cEdge = 0;
+ int count, d, x1, y1, x2, y2;
if (ms.nOmegaDraw <= 0)
return;
- for (f = 0; f <= 1; f++) {
- for (area = 0; !FIsOnMaze(area) || !FIsRoom(area); area = LNext(area))
- ;
- hunt = area;
- loop {
- if (!FIsOnMaze(area) || !FIsRoom(area))
+ InitCoorPatch(ms.nOmegaDraw == 2, ms.omega * ms.omega);
+ for (area = 0; !FIsOnMaze(area) || !FIsRoom(area); area = LNext(area))
+ ;
+ hunt = area;
+ loop {
+ if (!FIsOnMaze(area) || !FIsRoom(area))
+ continue;
+ count = NCount(area);
+ for (d = 0; d < count; d++) {
+ test = LEnum(area, d);
+ if (test < area && FIsOnMaze(test))
continue;
- count = NCount(area);
- for (d = 0; d < count; d++) {
- test = LEnum(area, d);
- if (test < area && FIsOnMaze(test))
- continue;
- if (!FIsPassage(area, d)) {
- if (!f)
- cEdge++;
- else {
- MapDir(area, d, &x1, &y1, &x2, &y2);
- if (ms.nOmegaDraw == 1)
- FSetCoordinates(x1, y1, 0, x2, y2, 0, -1);
- else
- FSetPatch(x1, y1, 0, x2, y2, 10, -1);
- }
- }
+ if (!FIsPassage(area, d)) {
+ MapDir(area, d, &x1, &y1, &x2, &y2);
+ WireframeLine(x1, y1, x2, y2);
}
- area = LNext(area);
- if (area == hunt)
- break;
- }
- if (!f) {
- if (ms.nOmegaDraw == 1)
- FInitCoordinates(cEdge);
- else
- FInitPatch(cEdge);
}
+ area = LNext(area);
+ if (area == hunt)
+ break;
}
- PrintSzN("Total number of edges generated: %d", cEdge);
+ WireframeOpening();
+ PrintSzN("Total number of edges generated: %d",
+ InitCoorPatch(ms.nOmegaDraw == 2, 0));
+}
+
+
+// Output a wireframe line given a pair of coordinates in the generic Maze.
+
+void Generic::WireframeLine(int x1, int y1, int x2, int y2)
+{
+ KV kv;
+
+ kv = -1;
+ /*if (m_c != NULL && m_c->m_x == m_b.m_x && m_c->m_y == m_b.m_y)
+ kv = CG(*m_c, (x1+x2) >> 1, (y1+y2) >> 1);*/
+ FSetCoorPatch(ms.nOmegaDraw == 2, x1, y1, 0, x2, y2, 10, kv);
+}
+
+
+// Output wireframe arrows for the start and end in the generic Maze.
+
+void Generic::WireframeOpening()
+{
}
@@ -811,7 +821,7 @@ flag Sigma::FCreateMaze(CMaz &b)
return fFalse;
}
b.BitmapOff();
- for (y = 0; y < SYMax; y++) {
+ for (y = 0; y < SYMax; y++)
for (x = 0; x < SXMax(y); x++) {
m = SMapX(x, y); n = SMapY(y);
GLine(m, n, m-ox1, n+oy1);
@@ -824,7 +834,6 @@ flag Sigma::FCreateMaze(CMaz &b)
if ((x >= SXMax(y)-1 && y >= ms.omega-1) || y >= SYMax-1)
GLine(m+ox1, n+oy1*3, m, n+oy1*4);
}
- }
CreateMazeGeneral();
return fTrue;
}
@@ -990,7 +999,7 @@ int Theta::NDirBinary(long area)
XYArea(x, y, area);
if (y <= ms.omega2)
- return 1;
+ return x > 0 ? 1 : -1;
return Rnd(0, 1);
}
@@ -1012,7 +1021,7 @@ flag Theta::FCreateMaze(CMaz &b)
return fFalse;
}
b.BitmapOff();
- for (y = ms.omega2; y <= ms.omega; y++) {
+ for (y = ms.omega2; y <= ms.omega; y++)
for (x = 0; x < TPoint(y); x++) {
m = (x + 1) & (TPoint(y) - 1);
GLine(TMapX(x, y), TMapY(x, y), TMapX(m, y), TMapY(m, y));
@@ -1021,7 +1030,6 @@ flag Theta::FCreateMaze(CMaz &b)
GLine(TMapX(x, y), TMapY(x, y), TMapX(m, y+1), TMapY(m, y+1));
}
}
- }
CreateMazeGeneral();
return fTrue;
}
@@ -1203,7 +1211,7 @@ flag Upsilon::FCreateMaze(CMaz &b)
return fFalse;
}
b.BitmapOff();
- for (y = 0; y <= ms.omega; y++) {
+ for (y = 0; y <= ms.omega; y++)
for (x = 0; x <= ms.omega; x++) {
m = UMapX(x); n = UMapY(y);
if (((x | y) & 1) == 0) {
@@ -1222,7 +1230,6 @@ flag Upsilon::FCreateMaze(CMaz &b)
if (y < ms.omega)
GLine(m - ox2*(!USquare(x, y)), n, m - ox2*(!USquare(x, y)), n+oy1);
}
- }
CreateMazeGeneral();
return fTrue;
}
@@ -1234,6 +1241,229 @@ flag CMaz::CreateMazeUpsilon()
}
+// Create an Omicron Maze, or a Maze formed of concentric circles on a sphere.
+
+#define OMapX(x, y) (ox0 + (x) * ox1 * (m_x / OPoint(y)))
+#define OMapY(y) (oy0 + (y) * oy1)
+#define OPoint(y) \
+ TPoint((y) < ((ms.omega+1) >> 1) ? Max(0, y) : Max(0, ms.omega-1-(y)))
+
+class Omicron : Generic
+{
+private:
+ int m_x;
+
+ long LMakeOpening(int, flag);
+ flag FIsRoom(long);
+ int NCount(long);
+ long LEnum(long, int);
+ long LNext(long);
+ int NDirBinary(long);
+ void MapDir(long, int, int *, int *, int *, int *);
+ void WireframeLine(int, int, int, int);
+ void WireframeOpening();
+
+public:
+ flag FCreateMaze(CMaz &);
+};
+
+void Omicron::MapDir(long area, int dir, int *x1, int *y1, int *x2, int *y2)
+{
+ int x, y, d, dd, m, m1, m2, n1, n2;
+
+ XYArea(x, y, area);
+ d = y < ((ms.omega+1) >> 1) ? 1 : -1;
+ dd = d < 0;
+ n1 = y + dd;
+ n2 = y + 1 - dd;
+ m = (x + 1) & (OPoint(y) - 1);
+ m1 = x << (int)(OPoint(y) < OPoint(y + d));
+ m2 = m << (int)(OPoint(y) < OPoint(y + d));
+ switch (dir) {
+ case 0:
+ *x1 = OMapX(x, n1-dd); *y1 = OMapY(n1);
+ *x2 = OMapX(x+1, n1-dd); *y2 = *y1;
+ break;
+ case 1:
+ *x1 = OMapX(x, n1-dd); *y1 = OMapY(n1);
+ *x2 = *x1; *y2 = OMapY(n2);
+ break;
+ case 2:
+ *x1 = OMapX(m, n1-dd); *y1 = OMapY(n1);
+ *x2 = *x1; *y2 = OMapY(n2);
+ break;
+ case 3:
+ *x1 = OMapX(m1, n2-dd); *y1 = OMapY(n2);
+ *x2 = OMapX(m1+1, n2-dd); *y2 = *y1;
+ break;
+ case 4:
+ *x1 = OMapX(m1+1, n2-dd); *y1 = OMapY(n2);
+ *x2 = OMapX(m1+2, n2-dd); *y2 = *y1;
+ break;
+ }
+}
+
+long Omicron::LMakeOpening(int hint, flag fExit)
+{
+ long area;
+ int x, y, dir, x1, y1, x2, y2;
+
+ x = Rnd(0, 3);
+ y = fExit ? ms.omega-1 : 0;
+ dir = fExit && ms.omega <= 1 ? 3 : 0;
+ AreaXY(area, x, y);
+ MakePassage(area, dir);
+ if (!fExit) {
+ MapDir(area, dir, &x1, &y1, &x2, &y2);
+ ms.xEntrance = (x1 + x2) >> 1; ms.yEntrance = (y1 + y2) >> 1;
+ }
+ return area;
+}
+
+flag Omicron::FIsRoom(long area)
+{
+ int x, y, d;
+
+ XYArea(x, y, area);
+ if (y < 0 || y >= ms.omega)
+ return fTrue;
+ for (d = 0; d < NCount(area); d++)
+ if (FIsPassage(area, d))
+ return fTrue;
+ return fFalse;
+}
+
+int Omicron::NCount(long area)
+{
+ int x, y, d;
+
+ // Cells in a ring have four sides, except when the number of cells in a
+ // ring doubles, in which case the cell in smaller ring has five sides.
+ XYArea(x, y, area);
+ d = y < ((ms.omega+1) >> 1) ? 1 : -1;
+ return 4 + (OPoint(y) < OPoint(y+d));
+}
+
+long Omicron::LEnum(long area, int dir)
+{
+ int x, y, d;
+
+ XYArea(x, y, area);
+ d = y < ((ms.omega+1) >> 1) ? 1 : -1;
+ switch (dir) {
+ case 0: x = x >> (int)(OPoint(y) > OPoint(y-d)); y -= d; break;
+ case 1: x = (x - 1) & (OPoint(y) - 1); break;
+ case 2: x = (x + 1) & (OPoint(y) - 1); break;
+ case 3: x = x << (int)(OPoint(y) < OPoint(y+d)); y += d; break;
+ case 4: x = (x << (int)(OPoint(y) < OPoint(y+d))) + 1; y += d; break;
+ }
+ AreaXY(area, x, y);
+ return area;
+}
+
+long Omicron::LNext(long area)
+{
+ int x, y;
+
+ XYArea(x, y, area);
+ x++;
+ if (x >= OPoint(y)) {
+ x = 0;
+ y++;
+ if (y >= ms.omega)
+ y = 0;
+ }
+ AreaXY(area, x, y);
+ return area;
+}
+
+int Omicron::NDirBinary(long area)
+{
+ int x, y;
+
+ XYArea(x, y, area);
+ if (y <= 0 || y >= ms.omega-1)
+ return x > 0 ? 1 : -1;
+ return Rnd(0, 1);
+}
+
+flag Omicron::FCreateMaze(CMaz &b)
+{
+ int x, y, z;
+
+ m_b = &b;
+ z = ms.omega*2 + 1;
+ x = Max(b.m_x, z); y = Max(b.m_y, z);
+ if (!b.FBitmapSizeSet(x, y))
+ return fFalse;
+ m_x = OPoint(ms.omega >> 1);
+ ox1 = (b.m_x - 1) / m_x;
+ ox0 = (b.m_x - ox1 * m_x) >> 1;
+ oy1 = (b.m_y - 1) / ms.omega;
+ oy0 = (b.m_y - oy1 * ms.omega) >> 1;
+ if (ox1 < 2 || oy1 < 2) {
+ PrintSzN_W("Bitmap too small to make omicron Maze of size: %d", ms.omega);
+ return fFalse;
+ }
+ b.BitmapOff();
+ for (y = 0; y <= ms.omega; y++)
+ for (x = OPoint(y)-1; x >= 0; x--) {
+ GLine(OMapX(x, y), OMapY(y), OMapX(x+1, y), OMapY(y));
+ if (y < ms.omega)
+ GLine(OMapX(x, y), OMapY(y), OMapX(x, y), OMapY(y+1));
+ }
+ CreateMazeGeneral();
+ return fTrue;
+}
+
+void Omicron::WireframeLine(int x1, int y1, int x2, int y2)
+{
+ int z1, z2;
+ real m1, n1, m2, n2, r1, r2;
+ KV kv;
+
+ if (ms.nOmegaDraw == 2)
+ FSetPatch(x1, y1, 0, x2, y2, 10, -1);
+ else {
+ r1 = (real)OPoint(ms.omega >> 1);
+ m1 = (real)((x1 - ox0) / ox1) * rDegMax / r1;
+ m2 = (real)((x2 - ox0) / ox1) * rDegMax / r1;
+ n1 = (real)((y1 - oy0) / oy1 + 1) * rDegHalf / (ms.omega+2) - rDegQuad;
+ n2 = (real)((y2 - oy0) / oy1 + 1) * rDegHalf / (ms.omega+2) - rDegQuad;
+ r1 = RCosD(n1); r2 = RCosD(n2);
+ z1 = (int)(1000.0 * RSinD(n1));
+ z2 = (int)(1000.0 * RSinD(n2));
+ y1 = (int)(1000.0 * RSinD(m1) * r1);
+ y2 = (int)(1000.0 * RSinD(m2) * r2);
+ x1 = (int)(1000.0 * RCosD(m1) * r1);
+ x2 = (int)(1000.0 * RCosD(m2) * r2);
+ kv = Hue((int)(((n1 + n2) / 2.0 + rDegQuad) * 2.0 * 10.0));
+ FSetCoordinates(x1, y1, z1, x2, y2, z2, kv);
+ }
+}
+
+void Omicron::WireframeOpening()
+{
+ int i, j;
+ KV kv;
+
+ // Draw two arrows for the entrance and exit to the Omicron Maze.
+ for (i = -1; i <= 1; i += 2) {
+ kv = i < 0 ? kvDkGray : kvWhite;
+ FSetCoordinates(0, 0, (1000+25)*i, 0, 0, (1000+25*9)*i, kv);
+ j = i < 0 ? -1000-25 : 1000+25*9;
+ FSetCoordinates(0, 0, j, 25*3, 0, j-25*3, kv);
+ FSetCoordinates(0, 0, j, -25*3, 0, j-25*3, kv);
+ }
+}
+
+flag CMaz::CreateMazeOmicron()
+{
+ Omicron omicron;
+ return omicron.FCreateMaze(*this);
+}
+
+
/*
******************************************************************************
** Recursive Fractal Maze Routines
@@ -2237,6 +2467,15 @@ long CMaz::CreateMazeCrack(flag fClear)
MakeEntranceExit(1);
UpdateDisplay();
}
+ if (ms.nOmegaDraw) {
+ InitCoorPatch(ms.nOmegaDraw == 2, 100);
+ FSetCoorPatch(ms.nOmegaDraw == 2, xl, yl, 0, xl, yh, 10, -1);
+ FSetCoorPatch(ms.nOmegaDraw == 2, xh, yl, 0, xh, yh, 10, -1);
+ FSetCoorPatch(ms.nOmegaDraw == 2, xl, yl, 0, ms.xEntrance-1, yl, 10, -1);
+ FSetCoorPatch(ms.nOmegaDraw == 2, ms.xEntrance+1, yl, 0, xh, yl, 10, -1);
+ FSetCoorPatch(ms.nOmegaDraw == 2, xl, yh, 0, ms.xExit-1, yh, 10, -1);
+ FSetCoorPatch(ms.nOmegaDraw == 2, ms.xExit+1, yh, 0, xh, yh, 10, -1);
+ }
// Draw lines appending onto what's already present.
while (pass < ms.nCrackPass) {
@@ -2288,6 +2527,7 @@ long CMaz::CreateMazeCrack(flag fClear)
d >>= 1;
// Draw the line a pixel at a time. Stop before hitting any other wall.
+ x2 = x; y2 = y;
for (z = 0; z <= zMax; z++) {
x += xInc; y += yInc; d += dInc;
if (d >= zMax) {
@@ -2300,6 +2540,9 @@ long CMaz::CreateMazeCrack(flag fClear)
k = (k << 1) + Get(x + xoff[i], y + yoff[i]);
if (mpgrff[k]) {
Set1(x, y);
+ if (ms.nOmegaDraw)
+ FSetCoorPatch(ms.nOmegaDraw == 2, x2, y2, 0, x, y, 10, -1);
+ x2 = x; y2 = y;
f = fTrue;
} else
break;
@@ -2315,6 +2558,8 @@ long CMaz::CreateMazeCrack(flag fClear)
} else
pass++;
}
+ if (ms.nOmegaDraw)
+ InitCoorPatch(ms.nOmegaDraw == 2, 0);
return count;
}
@@ -2333,6 +2578,8 @@ flag CMaz::ZetaGenerate(flag fClear, int x, int y)
while ((y - yl & 3) != 3)
y--;
count = ((xh - xl) >> 2)*((yh - yl) >> 2) - 1;
+ if (ms.nOmegaDraw)
+ InitCoorPatch(ms.nOmegaDraw == 2, count+2);
iMax = ms.fRiver ? DIRS2 : 1;
Set0(x, y);
UpdateDisplay();
@@ -2359,6 +2606,8 @@ flag CMaz::ZetaGenerate(flag fClear, int x, int y)
Set0(x + xoff2[d], y + yoff2[d]);
Set0(xnew - xoff[d], ynew - yoff[d]);
Set0(xnew, ynew);
+ if (ms.nOmegaDraw)
+ FSetCoorPatch(ms.nOmegaDraw == 2, x, y, 0, xnew, ynew, 10, -1);
x = xnew; y = ynew;
pass = 0;
fHunt = fFalse;
@@ -2406,7 +2655,15 @@ flag CMaz::CreateMazeZeta()
MazeClear(fOn);
MakeEntranceExit(3);
UpdateDisplay();
- return ZetaGenerate(fTrue, Rnd(xl + 3, xh), Rnd(yl + 3, yh));
+ if (!ZetaGenerate(fTrue, Rnd(xl + 3, xh), Rnd(yl + 3, yh)))
+ return fFalse;
+ if (ms.nOmegaDraw) {
+ FSetCoorPatch(ms.nOmegaDraw == 2, ms.xEntrance, 0, 0, ms.xEntrance, 3, 10,
+ -1);
+ FSetCoorPatch(ms.nOmegaDraw == 2, ms.xExit, m_y-1, 0, ms.xExit, m_y-4, 10,
+ -1);
+ }
+ return fTrue;
}
diff --git a/daedalus.cpp b/daedalus.cpp
index 3782c7b..c5254b2 100644
--- a/daedalus.cpp
+++ b/daedalus.cpp
@@ -1,9 +1,9 @@
/*
-** Daedalus (Version 3.3) File: daedalus.cpp
+** Daedalus (Version 3.4) File: daedalus.cpp
** By Walter D. Pullen, Astara@msn.com, http://www.astrolog.org/labyrnth.htm
**
** IMPORTANT NOTICE: Daedalus and all Maze generation and general
-** graphics routines used in this program are Copyright (C) 1998-2018 by
+** graphics routines used in this program are Copyright (C) 1998-2023 by
** Walter D. Pullen. Permission is granted to freely use, modify, and
** distribute these routines provided these credits and notices remain
** unmodified with any altered or distributed versions of the program.
@@ -24,7 +24,7 @@
** underlying operating system.
**
** Created: 11/18/1993.
-** Last code change: 11/29/2018.
+** Last code change: 8/29/2023.
*/
#include
@@ -94,9 +94,9 @@ DR dr = {
-1, -1, -1, -1, -1, -1, fFalse, 94001225, 0, 0, 50, 333,
fFalse, fFalse, -1, fFalse, fFalse, fFalse, fFalse, fFalse, fFalse,
fFalse, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1,
- fFalse, fFalse, 11, 3412, 4, 427, 0, 0,
+ fFalse, fFalse, fFalse, 11, 3412, 4, 427, 0,
// Internal settings
- fFalse, 0.0, NULL, 0, NULL, NULL, NULL, NULL, 50, 40, 99999};
+ fFalse, 0, 0.0, NULL, 0, NULL, NULL, NULL, NULL, 50, 40, 99999, 0};
// Constant data
@@ -119,7 +119,7 @@ CONST char *rgszScript[cmdScriptLast - cmdScript01 + 1] = {
"survmaz0.ds", "survmaz1.ds", "survmaz2.ds", "survmaz3.ds", "survmaz4.ds",
"survmaz5.ds", "survmaz6.ds", "survmaz7.ds", "survmaz8.ds", "survmaz9.ds",
"carletn1.ds", "carletn2.ds", "stocker.ds", "glacier.ds", "safari.ds",
- "mousemaz.ds", "squared.ds", "mandy.ds", "pentris.ds"};
+ "mousemaz.ds", "squared.ds", "mandy.ds", "pentris.ds", "gripsox.ds"};
CONST char *rgszShortcut[cmdScriptLast - cmdScript01 + 1] = {
"Daedalus demos", "Word Mazes", "World's largest Maze",
"4D Mazes", "5D Mazes", "Dragonslayer",
@@ -130,7 +130,8 @@ CONST char *rgszShortcut[cmdScriptLast - cmdScript01 + 1] = {
"Survivor Maze game #7", "Survivor Maze game #8", "Survivor Maze game #9",
"Carleton Farm Maze #1", "Carleton Farm Maze #2", "Stocker Farms Maze",
"Glacier Maze game", "Safari Maze", "Mouse Maze game",
- "Survivor Squares game", "Mandelbrot set", "Pentris"};
+ "Survivor Squares game", "Mandelbrot set", "Pentris",
+ "Grippy Socks"};
// Command lines to run on startup. When embedding a complex script file, in
// it first delete the leading DS, then replace \ with \\, " with \", and ?
@@ -188,14 +189,27 @@ byte BRead(FILE *file)
// Initialize a new wireframe list in memory of the specified size.
-flag FInitCoordinates(int cCoor)
+int InitCoordinates(int cCoor)
{
+ COOR *coor;
+ flag fExtend = cCoor < 0;
+
+ if (cCoor == 0)
+ cCoor = ds.cCoorPatch;
+ else if (fExtend)
+ cCoor = NAbs(cCoor);
+ if (cCoor == bm.ccoor)
+ return bm.ccoor;
+ coor = (COOR *)ReallocateArray(bm.coor, bm.ccoor, sizeof(COOR), cCoor);
+ if (coor == NULL)
+ return -1;
if (bm.coor != NULL)
DeallocateP(bm.coor);
- bm.coor = RgAllocate(cCoor, COOR);
+ bm.coor = coor;
bm.ccoor = cCoor;
- ds.cCoorPatch = 0;
- return bm.coor != NULL;
+ if (!fExtend)
+ ds.cCoorPatch = 0;
+ return bm.ccoor;
}
@@ -203,6 +217,9 @@ flag FInitCoordinates(int cCoor)
flag FSetCoordinates(int x1, int y1, int z1, int x2, int y2, int z2, KV kv)
{
+ if (ds.cCoorPatch >= bm.ccoor && InitCoordinates(bm.ccoor * -2) < 0)
+ return fFalse;
+ Assert(ds.cCoorPatch < bm.ccoor);
WriteCoordinates(bm.coor, x1, y1, z1, x2, y2, z2, kv < 0 ? ds.kvTrim : kv);
return fTrue;
}
@@ -210,14 +227,27 @@ flag FSetCoordinates(int x1, int y1, int z1, int x2, int y2, int z2, KV kv)
// Initialize a new patch list in memory of the specified size.
-flag FInitPatch(int cPat)
+int InitPatch(int cPat)
{
+ PATCH *patch;
+ flag fExtend = cPat < 0;
+
+ if (cPat == 0)
+ cPat = ds.cCoorPatch;
+ else if (fExtend)
+ cPat = NAbs(cPat);
+ if (cPat == bm.cpatch)
+ return bm.cpatch;
+ patch = (PATCH *)ReallocateArray(bm.patch, bm.cpatch, sizeof(PATCH), cPat);
+ if (patch == NULL)
+ return -1;
if (bm.patch != NULL)
DeallocateP(bm.patch);
- bm.patch = RgAllocate(cPat, PATCH);
+ bm.patch = patch;
bm.cpatch = cPat;
- ds.cCoorPatch = 0;
- return bm.patch != NULL;
+ if (!fExtend)
+ ds.cCoorPatch = 0;
+ return bm.cpatch;
}
@@ -227,15 +257,41 @@ flag FSetPatch(int x1, int y1, int z1, int x2, int y2, int z2, KV kv)
{
PATN pat[cPatch];
+ if (ds.cCoorPatch >= bm.cpatch && InitPatch(bm.cpatch * -2) < 0)
+ return fFalse;
pat[0].x = x1; pat[0].y = y1; pat[0].z = z1; pat[0].fLine = fTrue;
pat[1].x = x1; pat[1].y = y1; pat[1].z = z2; pat[1].fLine = fTrue;
pat[2].x = x2; pat[2].y = y2; pat[2].z = z2; pat[2].fLine = fTrue;
pat[3].x = x2; pat[3].y = y2; pat[3].z = z1; pat[3].fLine = fTrue;
+ Assert(ds.cCoorPatch < bm.cpatch);
WritePatch(bm.patch, pat, fFalse, kv < 0 ? ds.kvObject : kv);
return fTrue;
}
+// Initialize either the wireframe or patch list in memory to a given size.
+
+int InitCoorPatch(flag fPatch, int cCoorPatch)
+{
+ if (!fPatch)
+ return InitCoordinates(cCoorPatch);
+ else
+ return InitPatch(cCoorPatch);
+}
+
+
+// Append either a line or patch to the wireframe or patch list in memory.
+
+flag FSetCoorPatch(flag fPatch, int x1, int y1, int z1, int x2, int y2, int z2,
+ KV kv)
+{
+ if (!fPatch)
+ return FSetCoordinates(x1, y1, z1, x2, y2, z1/*z2*/, kv);
+ else
+ return FSetPatch(x1, y1, z1, x2, y2, z2, kv);
+}
+
+
/*
******************************************************************************
** Daedalus Routines
@@ -295,6 +351,7 @@ flag FReadDaedalusBitmap(FILE *file)
skipcrlf();
} else {
ws.iszStartup++;
+ ws.ichStartup = 0;
}
if (z == 1) {
if (bm.b.FReadDaedalusBitmapCore(file, x, y))
@@ -687,8 +744,7 @@ CMaz *BitmapGetMask(int ib)
if (pbT == NULL)
return NULL;
for (iT = ws.cbMask; iT <= ib; iT++)
- new(&pbT[iT]) CMaz();
- //pbT[iT].CMaz::CMaz();
+ new(&pbT[iT]) CMaz(); // Effectively does: pbT[iT].CMaz::CMaz();
if (ws.rgbMask != NULL)
DeallocateP(ws.rgbMask);
ws.rgbMask = pbT;
@@ -725,8 +781,7 @@ CMazK *ColmapGetTexture(int ic)
if (pcT == NULL)
return NULL;
for (iT = ws.ccTexture; iT <= ic; iT++)
- new(&pcT[iT]) CMazK();
- //pcT[iT].CMazK::CMazK();
+ new(&pcT[iT]) CMazK(); // Effectively does: pcT[iT].CMazK::CMazK();
if (ws.rgcTexture != NULL)
DeallocateP(ws.rgcTexture);
ws.rgcTexture = pcT;
@@ -3008,6 +3063,10 @@ void *PAllocate(long lcb)
char sz[cchSzMax];
void *pv;
+#ifndef PC
+ // For Unix systems in which longs are 8 bytes instead of 4 bytes.
+ lcb += 4;
+#endif
#ifdef DEBUG
pv = malloc(lcb + sizeof(dword)*3);
#else
diff --git a/daedalus.def b/daedalus.def
index 8a78c60..baf29b4 100644
--- a/daedalus.def
+++ b/daedalus.def
@@ -1,8 +1,8 @@
-; Daedalus (Version 3.3) File: daedalus.def
+; Daedalus (Version 3.4) File: daedalus.def
; By Walter D. Pullen, Astara@msn.com, http://www.astrolog.org/labyrnth.htm
;
; IMPORTANT NOTICE: Daedalus and all Maze generation and general
-; graphics routines used in this program are Copyright (C) 1998-2018 by
+; graphics routines used in this program are Copyright (C) 1998-2023 by
; Walter D. Pullen. Permission is granted to freely use, modify, and
; distribute these routines provided these credits and notices remain
; unmodified with any altered or distributed versions of the program.
@@ -19,10 +19,10 @@
; General Public License for more details, a copy of which is in the
; LICENSE.HTM included with Daedalus, and at http://www.gnu.org
;
-; Last code change: 11/28/2018.
+; Last code change: 8/29/2023.
NAME DAEDALUS
-DESCRIPTION "Daedalus 3.3 - By Walter D. Pullen"
+DESCRIPTION "Daedalus 3.4 - By Walter D. Pullen"
EXETYPE WINDOWS
STUB 'WINSTUB.EXE'
CODE PRELOAD MOVEABLE DISCARDABLE
diff --git a/daedalus.doc b/daedalus.doc
index f2ac3f0cb9b2112a1306b8f2949fd22649502664..1e6f691555f97c8df04afd24c107888154147c28 100644
GIT binary patch
delta 85845
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