Improve code readability master
authorSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Thu, 27 Feb 2025 20:29:14 +0000 (22:29 +0200)
committerSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Thu, 27 Feb 2025 20:29:14 +0000 (22:29 +0200)
Graphics/Presentations/AI/AI demo.bas

index 16aa99c..10b1216 100644 (file)
@@ -6,38 +6,46 @@ DECLARE SUB Scene3 ()
 DECLARE SUB Scene4 ()\r
 DECLARE SUB Scene5 ()\r
 DECLARE SUB Scene7 ()\r
-DECLARE SUB Initialize ()           ' Renamed from "start" for clarity\r
-DECLARE SUB sc1 ()\r
-DECLARE SUB sc2 ()\r
-DECLARE SUB sc3 ()\r
-DECLARE SUB sc4 ()\r
-DECLARE SUB sc5 ()\r
-DECLARE SUB sc6 ()\r
-DECLARE SUB sc7 ()\r
-DECLARE SUB sc8 ()\r
-DECLARE SUB sc10 ()\r
-DECLARE SUB sc9 ()\r
-DECLARE SUB DrawRoundedBox (x1!, y1!, x2!, y2!)   ' Renamed from "box" for clarity\r
-DECLARE SUB ComputeShadeValue (tx1!, ty1!, tz1!, tx2!, ty2!, tz2!, tx3!, ty3!, tz3!, c!)   ' Renamed from "calc"\r
-DECLARE SUB GetAngle (x1!, y1!, x2!, y2!, N!)\r
-DECLARE SUB RotatePoint (zx!, zy!, x1!, y1!, N!)\r
-DECLARE SUB FillPolygon (xCoord1!, yCoord1!, xCoord2!, yCoord2!, xCoord3!, yCoord3!, colorVal!)\r
+DECLARE SUB Initialize ()\r
+DECLARE SUB ShowScenePart1 ()\r
+DECLARE SUB ShowScenePart2 ()\r
+DECLARE SUB ShowScenePart3 ()\r
+DECLARE SUB ShowScenePart4 ()\r
+DECLARE SUB ShowScenePart5 ()\r
+DECLARE SUB ShowScenePart6 ()\r
+DECLARE SUB ShowScenePart7 ()\r
+DECLARE SUB ShowScenePart8 ()\r
+DECLARE SUB ShowScenePart10 ()\r
+DECLARE SUB ShowScenePart9 ()\r
+DECLARE SUB DrawRoundedBox (xOne!, yOne!, xTwo!, yTwo!)\r
+DECLARE SUB ComputeShadeValue (txOne!, tyOne!, tzOne!, txTwo!, tyTwo!, tzTwo!, txThree!, tyThree!, tzThree!, colorResult!)\r
+DECLARE SUB GetAngle (xOne!, yOne!, xTwo!, yTwo!, angleOutput!)\r
+DECLARE SUB RotatePoint (centerX!, centerY!, pointX!, pointY!, angleRadians!)\r
+DECLARE SUB FillPolygon (xCoordOne!, yCoordOne!, xCoordTwo!, yCoordTwo!, xCoordThree!, yCoordThree!, colorValue!)\r
 DECLARE SUB InitializeFont ()\r
 DECLARE SUB WaitForInput ()\r
 DECLARE SUB MakeBackground ()\r
-DECLARE SUB SetPalette (r!, g!, b!, c!)\r
-DECLARE SUB PrintText (x!, y!, s!, c!, a$)\r
+DECLARE SUB SetPalette (red!, green!, blue!, colorIndex!)\r
+DECLARE SUB PrintText (posX!, posY!, scale!, colorValue!, textString$)\r
 \r
-' AI presentation\r
-' made by Svjatoslav Agejenko\r
-' in 2002\r
-' homepage: svjatoslav.eu\r
-' email:        svjatoslav@svjatoslav.eu\r
+' Presentation about artificial intelligence.\r
+'\r
+' By Svjatoslav Agejenko.\r
+' Email: svjatoslav@svjatoslav.eu\r
+' Homepage: http://www.svjatoslav.eu\r
+'\r
+' Changelog:\r
+' 2002, Initial version\r
+' 2025, Improved program readability using AI\r
 \r
-DIM SHARED pii\r
-DIM SHARED pi\r
-DIM SHARED angl1, angl2\r
-DIM SHARED font(0 TO 7, 0 TO 7, 32 TO 150)\r
+\r
+DIM SHARED globalPiI\r
+DIM SHARED globalPi\r
+DIM SHARED globalAngleOne\r
+DIM SHARED globalAngleTwo\r
+\r
+' Holds the captured font bitmap\r
+DIM SHARED fontData(0 TO 7, 0 TO 7, 32 TO 150)\r
 \r
 Initialize\r
 \r
@@ -50,204 +58,222 @@ Scene7
 Scene8\r
 Scene9\r
 \r
-SUB ComputeShadeValue (tx1, ty1, tz1, tx2, ty2, tz2, tx3, ty3, tz3, c)\r
-' Computes a value (c) based on the positions of three 3D points.\r
-' It rotates these points around multiple axes, then calculates\r
-' an offset 'a' used to determine a final computed result in 'c'.\r
 \r
-    x1 = tx1\r
-    y1 = ty1\r
-    z1 = tz1\r
+SUB ComputeShadeValue (txOne, tyOne, tzOne, txTwo, tyTwo, tzTwo, txThree, tyThree, tzThree, colorResult)\r
+'\r
+' Computes a "shade" or brightness value stored in 'colorResult' by:\r
+'   1) Assigning local copies of the point coordinates.\r
+'   2) Rotating them around multiple axes via GetAngle and RotatePoint.\r
+'   3) Computing a distance 'distCalc' to adjust brightness.\r
+'\r
+    xLocalOne = txOne\r
+    yLocalOne = tyOne\r
+    zLocalOne = tzOne\r
 \r
-    x2 = tx2\r
-    y2 = ty2\r
-    z2 = tz2\r
+    xLocalTwo = txTwo\r
+    yLocalTwo = tyTwo\r
+    zLocalTwo = tzTwo\r
 \r
-    x3 = tx3\r
-    y3 = ty3\r
-    z3 = tz3\r
+    xLocalThree = txThree\r
+    yLocalThree = tyThree\r
+    zLocalThree = tzThree\r
 \r
     ' First rotation\r
-    GetAngle x1, y1, x2, y2, n1\r
-    RotatePoint x1, y1, x2, y2, -n1\r
-    RotatePoint x1, y1, x3, y3, -n1\r
+    GetAngle xLocalOne, yLocalOne, xLocalTwo, yLocalTwo, angleTemp1\r
+    RotatePoint xLocalOne, yLocalOne, xLocalTwo, yLocalTwo, -angleTemp1\r
+    RotatePoint xLocalOne, yLocalOne, xLocalThree, yLocalThree, -angleTemp1\r
 \r
     ' Second rotation\r
-    GetAngle y1, z1, y2, z2, n2\r
-    n2 = n2 + pi / 2\r
-    RotatePoint y1, z1, y2, z2, -n2\r
-    RotatePoint y1, z1, y3, z3, -n2\r
+    GetAngle yLocalOne, zLocalOne, yLocalTwo, zLocalTwo, angleTemp2\r
+    angleTemp2 = angleTemp2 + globalPi / 2\r
+    RotatePoint yLocalOne, zLocalOne, yLocalTwo, zLocalTwo, -angleTemp2\r
+    RotatePoint yLocalOne, zLocalOne, yLocalThree, zLocalThree, -angleTemp2\r
 \r
     ' Third rotation\r
-    GetAngle x1, z1, x3, z3, n3\r
-    n3 = n3 + pi / 2\r
-    RotatePoint x1, z1, x2, z2, -n3\r
-    RotatePoint x1, z1, x3, z3, -n3\r
-\r
-    x4 = x1\r
-    y4 = y1\r
-    z4 = z1 + 30\r
-\r
-    RotatePoint x1, z1, x4, z4, n3\r
-    RotatePoint y1, z1, y4, z4, n2\r
-    RotatePoint x1, y1, x4, y4, n1\r
-\r
-    ' The distance 'a' is used to calculate 'c'\r
-    x1 = tx1 + 20\r
-    y1 = ty1 + 10\r
-    a = SQR((x1 - x4) ^ 2 + (y1 - y4) ^ 2)\r
-    c = 49 - a\r
-    IF c < 0 THEN c = 0\r
+    GetAngle xLocalOne, zLocalOne, xLocalThree, zLocalThree, angleTemp3\r
+    angleTemp3 = angleTemp3 + globalPi / 2\r
+    RotatePoint xLocalOne, zLocalOne, xLocalTwo, zLocalTwo, -angleTemp3\r
+    RotatePoint xLocalOne, zLocalOne, xLocalThree, zLocalThree, -angleTemp3\r
+\r
+    xOffset = xLocalOne\r
+    yOffset = yLocalOne\r
+    zOffset = zLocalOne + 30\r
+\r
+    RotatePoint xLocalOne, zLocalOne, xOffset, zOffset, angleTemp3\r
+    RotatePoint yLocalOne, zLocalOne, yOffset, zOffset, angleTemp2\r
+    RotatePoint xLocalOne, yLocalOne, xOffset, yOffset, angleTemp1\r
+\r
+    ' The distance 'distCalc' is used to compute 'colorResult'\r
+    xLocalOne = txOne + 20\r
+    yLocalOne = tyOne + 10\r
+    distCalc = SQR((xLocalOne - xOffset) ^ 2 + (yLocalOne - yOffset) ^ 2)\r
+    colorResult = 49 - distCalc\r
+    IF colorResult < 0 THEN colorResult = 0\r
 END SUB\r
 \r
-SUB DrawRoundedBox (x1, y1, x2, y2)\r
-' Draws a soft-edged rectangular box by blending pixel colors around the edges.\r
-' The edges fade gently to create a smoothed border.\r
 \r
-    FOR y = y1 TO y2\r
-        s = 10\r
-        IF y - y1 <= 10 THEN\r
-            s = (SQR((20 - (y - y1)) * (y - y1)))  ' fade calculation\r
+SUB DrawRoundedBox (xOne, yOne, xTwo, yTwo)\r
+'\r
+' Draws a soft-edged rectangular box by fading pixel colors around its edges.\r
+' This creates a gentle "rounded" or "blurred" border appearance.\r
+'\r
+    FOR yLoop = yOne TO yTwo\r
+        fadeSize = 10\r
+        ' Fade in the upper boundary region\r
+        IF yLoop - yOne <= 10 THEN\r
+            fadeSize = (SQR((20 - (yLoop - yOne)) * (yLoop - yOne)))\r
         END IF\r
 \r
-        IF y2 - y <= 10 THEN\r
-            s = (SQR((20 - (y2 - y)) * (y2 - y)))  ' Similar fade near the lower boundary\r
+        ' Fade in the lower boundary region\r
+        IF yTwo - yLoop <= 10 THEN\r
+            fadeSize = (SQR((20 - (yTwo - yLoop)) * (yTwo - yLoop)))\r
         END IF\r
 \r
-        FOR x = x1 - s TO x2 + s\r
-            c = POINT(x, y)\r
-            IF c <= 127 THEN\r
-                c = c + 127\r
-                IF c > 245 THEN c = 245\r
-                PSET (x, y), c\r
+        FOR xLoop = xOne - fadeSize TO xTwo + fadeSize\r
+            colorVal = POINT(xLoop, yLoop)\r
+            IF colorVal <= 127 THEN\r
+                colorVal = colorVal + 127\r
+                IF colorVal > 245 THEN colorVal = 245\r
+                PSET (xLoop, yLoop), colorVal\r
             END IF\r
-        NEXT x\r
-    NEXT y\r
+        NEXT xLoop\r
+    NEXT yLoop\r
 END SUB\r
 \r
-'-------------------------------------------------------------------------------\r
-SUB FillPolygon (xCoord1, yCoord1, xCoord2, yCoord2, xCoord3, yCoord3, colorVal)\r
-' Fills a triangular area by connecting the edges.\r
-' It uses a scanline approach, storing intersection points in yb() array,\r
-' then drawing horizontal lines between those intersection points.\r
-\r
-    DIM yb(-100 TO 300)\r
-\r
-    ' The following variables (mx1, my1, etc.) track the endpoints of edges\r
-    mx1 = xCoord1\r
-    my1 = yCoord1\r
-    mx2 = xCoord2\r
-    my2 = yCoord2\r
-    GOSUB mkl\r
-\r
-    mx1 = xCoord1\r
-    my1 = yCoord1\r
-    mx2 = xCoord3\r
-    my2 = yCoord3\r
-    GOSUB mkl\r
-\r
-    mx1 = xCoord3\r
-    my1 = yCoord3\r
-    mx2 = xCoord2\r
-    my2 = yCoord2\r
-    GOSUB mkl\r
-\r
-    GOTO 1\r
-\r
-mkl:\r
+\r
+SUB FillPolygon (xCoordOne, yCoordOne, xCoordTwo, yCoordTwo, xCoordThree, yCoordThree, colorValue)\r
+'\r
+' Fills a triangular region using a simple scanline approach.\r
+'   1) Draw lines between points to find intersections on each horizontal row.\r
+'   2) Use the pairs of intersection points to draw horizontal lines in colorValue.\r
+'\r
+    DIM scanIntersection(-100 TO 300)\r
+\r
+    localX1 = xCoordOne\r
+    localY1 = yCoordOne\r
+    localX2 = xCoordTwo\r
+    localY2 = yCoordTwo\r
+    GOSUB fillLines\r
+\r
+    localX1 = xCoordOne\r
+    localY1 = yCoordOne\r
+    localX2 = xCoordThree\r
+    localY2 = yCoordThree\r
+    GOSUB fillLines\r
+\r
+    localX1 = xCoordThree\r
+    localY1 = yCoordThree\r
+    localX2 = xCoordTwo\r
+    localY2 = yCoordTwo\r
+    GOSUB fillLines\r
+\r
+    GOTO polygonDone\r
+\r
+fillLines:\r
     ' If the second point is above the first, swap them\r
-    IF my2 < my1 THEN\r
-        SWAP my1, my2\r
-        SWAP mx1, mx2\r
+    IF localY2 < localY1 THEN\r
+        SWAP localY1, localY2\r
+        SWAP localX1, localX2\r
     END IF\r
 \r
-    ' Scan through each row (y) in the current edge segment\r
-    FOR y = my1 TO my2 - 1\r
-        x = mx1 + (mx2 - mx1) * ((y - my1) / (my2 - my1))\r
-        IF yb(y) = 0 THEN\r
-            ' First intersection on this scanline\r
-            yb(y) = x\r
+    ' Walk through rows from localY1 up to localY2\r
+    FOR yFill = localY1 TO localY2 - 1\r
+        xFill = localX1 + (localX2 - localX1) * ((yFill - localY1) / (localY2 - localY1))\r
+        IF scanIntersection(yFill) = 0 THEN\r
+            ' This is the first intersection discovered on this row\r
+            scanIntersection(yFill) = xFill\r
         ELSE\r
-            ' Second intersection -> draw a horizontal line\r
-            LINE (x, y)-(yb(y), y), colorVal\r
+            ' Second intersection found -> draw horizontal line to the first intersection\r
+            LINE (xFill, yFill)-(scanIntersection(yFill), yFill), colorValue\r
         END IF\r
-    NEXT y\r
+    NEXT yFill\r
     RETURN\r
 \r
-:\r
+polygonDone:\r
 END SUB\r
 \r
-'-------------------------------------------------------------------------------\r
-SUB GetAngle (x1, y1, x2, y2, N)\r
-' Determines the angle (N) between two points (x1,y1) and (x2,y2).\r
-' Used for rotation operations in 2D or for adjusting orientation.\r
 \r
-    IF y1 = y2 THEN\r
-        IF x2 > x1 THEN N = pi / 2 ELSE N = pi * 1.5\r
-        GOTO 2\r
+SUB GetAngle (xOne, yOne, xTwo, yTwo, angleOutput)\r
+'\r
+' Computes an angle in radians between two points (xOne,yOne) and (xTwo,yTwo).\r
+' The result is stored in angleOutput. Used for 2D rotation or orientation logic.\r
+'\r
+    IF yOne = yTwo THEN\r
+        IF xTwo > xOne THEN\r
+            angleOutput = globalPi / 2\r
+        ELSE\r
+            angleOutput = globalPi * 1.5\r
+        END IF\r
+        GOTO skipLogic\r
     END IF\r
 \r
-    IF y2 > y1 THEN\r
-        IF x2 = x1 THEN\r
-            N = pi\r
-            GOTO 2\r
+    IF yTwo > yOne THEN\r
+        IF xTwo = xOne THEN\r
+            angleOutput = globalPi\r
+            GOTO skipLogic\r
         END IF\r
-        IF x2 > x1 THEN\r
-            N = (pi * 1) - ATN((x2 - x1) / (y2 - y1))\r
+        IF xTwo > xOne THEN\r
+            angleOutput = (globalPi * 1) - ATN((xTwo - xOne) / (yTwo - yOne))\r
         ELSE\r
-            N = pi + ATN((x1 - x2) / (y2 - y1))\r
+            angleOutput = globalPi + ATN((xOne - xTwo) / (yTwo - yOne))\r
         END IF\r
     ELSE\r
-        IF x2 = x1 THEN\r
-            N = 0\r
-            GOTO 2\r
+        IF xTwo = xOne THEN\r
+            angleOutput = 0\r
+            GOTO skipLogic\r
         END IF\r
-        IF x2 > x1 THEN\r
-            N = ATN((x2 - x1) / (y1 - y2))\r
+        IF xTwo > xOne THEN\r
+            angleOutput = ATN((xTwo - xOne) / (yOne - yTwo))\r
         ELSE\r
-            N = pi * 2 - ATN((x1 - x2) / (y1 - y2))\r
+            angleOutput = globalPi * 2 - ATN((xOne - xTwo) / (yOne - yTwo))\r
         END IF\r
     END IF\r
 \r
-:\r
+skipLogic:\r
 END SUB\r
 \r
-'-------------------------------------------------------------------------------\r
-SUB Initialize\r
-' Initializes screen mode, sets up global constants pi and pii,\r
-' and captures system font data for later use in PrintText.\r
 \r
+SUB Initialize\r
+'\r
+' Initializes the environment:\r
+'  1) Switches to SCREEN 13\r
+'  2) Sets globalPi and globalPiI\r
+'  3) Calculates a shared factor (fac) for angles\r
+'  4) Calls InitializeFont to capture system font data\r
+'\r
     SCREEN 13\r
-    pi = 3.141592\r
-    pii = pi\r
-    fac = 360 / (pi * 2)\r
+    globalPi = 3.141592\r
+    globalPiI = globalPi\r
+    factorAngle = 360 / (globalPi * 2)\r
     InitializeFont\r
 END SUB\r
 \r
-'-------------------------------------------------------------------------------\r
-SUB InitializeFont\r
-' Captures the current text font into an array for later use\r
-' when drawing text with PrintText.\r
 \r
+SUB InitializeFont\r
+'\r
+' Captures the current text font into fontData() for later use in PrintText.\r
+' This is done by printing each ASCII character (32..150) and reading its bits.\r
+'\r
     SetPalette 0, 0, 0, 70\r
     COLOR 70\r
-    FOR a = 32 TO 150\r
+    FOR asciiCode = 32 TO 150\r
         LOCATE 1, 1\r
-        PRINT CHR$(a);\r
-        FOR y = 0 TO 7\r
-            FOR x = 0 TO 7\r
-                font(x, y, a) = POINT(x, y)\r
-            NEXT x\r
-        NEXT y\r
-    NEXT a\r
+        PRINT CHR$(asciiCode);\r
+        FOR yScan = 0 TO 7\r
+            FOR xScan = 0 TO 7\r
+                fontData(xScan, yScan, asciiCode) = POINT(xScan, yScan)\r
+            NEXT xScan\r
+        NEXT yScan\r
+    NEXT asciiCode\r
 END SUB\r
 \r
+\r
 DEFINT A-Z\r
-'-------------------------------------------------------------------------------\r
 SUB MakeBackground\r
-' Creates a fractal-like background by iteratively sampling and\r
-' perturbing pixel values, producing a terrain effect.\r
-\r
+'\r
+' Creates a fractal-like landscape in the background by iteratively sampling\r
+' and perturbing pixel values. The result is a random terrain effect.\r
+'\r
     CLS\r
     SetPalette 0, 5, 5, 250\r
     SetPalette 0, 5, 5, 251\r
@@ -256,139 +282,155 @@ SUB MakeBackground
     SetPalette 0, 5, 5, 254\r
     SetPalette 0, 5, 5, 255\r
 \r
-    FOR a = 0 TO 127\r
-        OUT &H3C8, a\r
-        OUT &H3C9, SIN(a / 22) * 30 + 30\r
-        OUT &H3C9, SIN(a / 18) * 5 + 5\r
-        OUT &H3C9, COS(a / 12) * 10 + 10\r
-    NEXT a\r
-\r
-    FOR a = 128 TO 245\r
-        OUT &H3C8, a\r
-        b = a - 128\r
-        OUT &H3C9, SIN(b / 22) * 4 + 10\r
-        OUT &H3C9, SIN(b / 18) * 4 + 10\r
-        OUT &H3C9, COS(b / 12) * 4 + 10\r
-    NEXT a\r
-\r
-    DIM lm\r
-    lm = 127\r
-\r
-    s = 2 ^ 8\r
-5 :\r
-    s = s \ 2\r
-    x2 = (319 \ s) - 1\r
-    y2 = (199 \ s) - 1\r
-\r
-    FOR y = 0 TO y2\r
-        FOR x = 0 TO x2\r
-            x1 = x * s\r
-            y1 = y * s\r
-            c1 = POINT(x1, y1)\r
-            c2 = POINT(x1 + s, y1)\r
-            c3 = POINT(x1, y1 + s)\r
-            c4 = POINT(x1 + s, y1 + s)\r
-\r
-            sp = s \ 2\r
-\r
-            cc2 = ((c1 + c2) / 2) + (RND * 6) - 3\r
-            IF cc2 > lm THEN cc2 = lm\r
-\r
-            cc3 = ((c1 + c3) / 2) + (RND * 6) - 3\r
-            IF cc3 > lm THEN cc3 = lm\r
-\r
-            cc4 = ((c2 + c4) / 2) + (RND * 6) - 3\r
-            IF cc4 > lm THEN cc4 = lm\r
-\r
-            cc5 = ((c3 + c4) / 2) + (RND * 6) - 3\r
-            IF cc5 > lm THEN cc5 = lm\r
-\r
-            cc1 = ((cc2 + cc3 + cc4 + cc5) / 4) + (RND * 6) - 3\r
-            IF cc1 > lm THEN cc1 = lm\r
-\r
-            PSET (x1 + sp, y1 + sp), cc1\r
-            PSET (x1 + sp, y1), cc2\r
-            PSET (x1, y1 + sp), cc3\r
-            PSET (x1 + s, y1 + sp), cc4\r
-            PSET (x1 + sp, y1 + s), cc5\r
-        NEXT x\r
-    NEXT y\r
-    IF s > 2 THEN GOTO 5\r
-\r
+    ' Set custom RGB values for palette entries 0..127\r
+    FOR loopIndex = 0 TO 127\r
+        OUT &H3C8, loopIndex\r
+        OUT &H3C9, SIN(loopIndex / 22) * 30 + 30\r
+        OUT &H3C9, SIN(loopIndex / 18) * 5 + 5\r
+        OUT &H3C9, COS(loopIndex / 12) * 10 + 10\r
+    NEXT loopIndex\r
+\r
+    ' Palette entries 128..245\r
+    FOR loopIndex = 128 TO 245\r
+        OUT &H3C8, loopIndex\r
+        offsetIndex = loopIndex - 128\r
+        OUT &H3C9, SIN(offsetIndex / 22) * 4 + 10\r
+        OUT &H3C9, SIN(offsetIndex / 18) * 4 + 10\r
+        OUT &H3C9, COS(offsetIndex / 12) * 4 + 10\r
+    NEXT loopIndex\r
+\r
+    DIM limitValue\r
+    limitValue = 127\r
+\r
+    dimensionSize = 2 ^ 8\r
+fractalLoop:\r
+    dimensionSize = dimensionSize \ 2\r
+    xSteps = (319 \ dimensionSize) - 1\r
+    ySteps = (199 \ dimensionSize) - 1\r
+\r
+    ' Subdivide squares in the image to add random variations\r
+    FOR loopY = 0 TO ySteps\r
+        FOR loopX = 0 TO xSteps\r
+            topLeftX = loopX * dimensionSize\r
+            topLeftY = loopY * dimensionSize\r
+            pixC1 = POINT(topLeftX, topLeftY)\r
+            pixC2 = POINT(topLeftX + dimensionSize, topLeftY)\r
+            pixC3 = POINT(topLeftX, topLeftY + dimensionSize)\r
+            pixC4 = POINT(topLeftX + dimensionSize, topLeftY + dimensionSize)\r
+\r
+            halfBlock = dimensionSize \ 2\r
+\r
+            newC2 = ((pixC1 + pixC2) / 2) + (RND * 6) - 3\r
+            IF newC2 > limitValue THEN newC2 = limitValue\r
+\r
+            newC3 = ((pixC1 + pixC3) / 2) + (RND * 6) - 3\r
+            IF newC3 > limitValue THEN newC3 = limitValue\r
+\r
+            newC4 = ((pixC2 + pixC4) / 2) + (RND * 6) - 3\r
+            IF newC4 > limitValue THEN newC4 = limitValue\r
+\r
+            newC5 = ((pixC3 + pixC4) / 2) + (RND * 6) - 3\r
+            IF newC5 > limitValue THEN newC5 = limitValue\r
+\r
+            centerVal = ((newC2 + newC3 + newC4 + newC5) / 4) + (RND * 6) - 3\r
+            IF centerVal > limitValue THEN centerVal = limitValue\r
+\r
+            PSET (topLeftX + halfBlock, topLeftY + halfBlock), centerVal\r
+            PSET (topLeftX + halfBlock, topLeftY), newC2\r
+            PSET (topLeftX, topLeftY + halfBlock), newC3\r
+            PSET (topLeftX + dimensionSize, topLeftY + halfBlock), newC4\r
+            PSET (topLeftX + halfBlock, topLeftY + dimensionSize), newC5\r
+        NEXT loopX\r
+    NEXT loopY\r
+\r
+    IF dimensionSize > 2 THEN GOTO fractalLoop\r
 END SUB\r
 \r
+\r
 DEFSNG A-Z\r
-'-------------------------------------------------------------------------------\r
-SUB PrintText (x, y, s, c, a$)\r
-' Prints text at a specified (x,y) position on the screen, by reading\r
-' from the 'font' array captured in InitializeFont. Allows for scaling = 1.\r
-\r
-    IF s = 1 THEN\r
-        x2 = x\r
-        FOR a = 1 TO LEN(a$)\r
-            b = ASC(RIGHT$(LEFT$(a$, a), 1))\r
-            IF b > 150 OR b < 32 THEN GOTO 7\r
-            FOR y1 = 0 TO 7\r
-                FOR x1 = 0 TO 7\r
-                    c1 = font(x1, y1, b)\r
-                    IF c1 > 0 THEN PSET (x1 + x2, y1 + y), c\r
-                NEXT x1\r
-            NEXT y1\r
-7 :\r
-            x2 = x2 + 8\r
-        NEXT a\r
+SUB PrintText (posX, posY, scale, colorValue, textString$)\r
+'\r
+' Renders text at (posX, posY) using the captured fontData().\r
+' Currently supports scale=1 for normal size. If scale=1, each character\r
+' is drawn 1:1 from the font data.\r
+'\r
+    IF scale = 1 THEN\r
+        nextX = posX\r
+        FOR charPos = 1 TO LEN(textString$)\r
+            asciiVal = ASC(RIGHT$(LEFT$(textString$, charPos), 1))\r
+            IF asciiVal > 150 OR asciiVal < 32 THEN GOTO skipChar\r
+\r
+            FOR yScan = 0 TO 7\r
+                FOR xScan = 0 TO 7\r
+                    pixVal = fontData(xScan, yScan, asciiVal)\r
+                    IF pixVal > 0 THEN PSET (xScan + nextX, yScan + posY), colorValue\r
+                NEXT xScan\r
+            NEXT yScan\r
+\r
+skipChar:\r
+            nextX = nextX + 8\r
+        NEXT charPos\r
     END IF\r
 END SUB\r
 \r
-'-------------------------------------------------------------------------------\r
-SUB RotatePoint (zx, zy, x1, y1, N)\r
-' Rotates a point (x1,y1) around a center (zx,zy) by angle N (in radians).\r
-' This is a standard 2D rotation transform.\r
-\r
-    x2 = x1 - zx\r
-    y2 = y1 - zy\r
-    c1 = SIN(N)\r
-    s1 = COS(N)\r
-    x1 = x2 * s1 - y2 * c1 + zx\r
-    y1 = x2 * c1 + y2 * s1 + zy\r
+\r
+SUB RotatePoint (centerX, centerY, pointX, pointY, angleRadians)\r
+'\r
+' Rotates point (pointX, pointY) around (centerX, centerY) by angleRadians.\r
+' Standard 2D rotation formula:\r
+'   X' = (X - CX)*cos - (Y - CY)*sin + CX\r
+'   Y' = (X - CX)*sin + (Y - CY)*cos + CY\r
+'\r
+    deltaX = pointX - centerX\r
+    deltaY = pointY - centerY\r
+    sinAngle = SIN(angleRadians)\r
+    cosAngle = COS(angleRadians)\r
+    pointX = deltaX * cosAngle - deltaY * sinAngle + centerX\r
+    pointY = deltaX * sinAngle + deltaY * cosAngle + centerY\r
 END SUB\r
 \r
+\r
 '-------------------------------------------------------------------------------\r
 SUB Scene1\r
-' Initializes palette and reads 3D data from "data.dat" for a rotating\r
-' point/line demonstration. The code then renders lines in 2D projection\r
-' while applying transformations over time to create animation-like motion.\r
-\r
+'\r
+' Loads & processes 3D data from "data.dat" to demonstrate simple line rendering.\r
+' The object is rotated in real-time, and lines are projected in 2D.\r
+' Timers and angles cause a rotating, animated effect.\r
+'\r
     SetPalette 0, 63, 20, 255\r
-    DIM px(0 TO 1000)\r
-    DIM py(0 TO 1000)\r
-    DIM pz(0 TO 1000)\r
-    DIM px1(0 TO 1000)\r
-    DIM py1(0 TO 1000)\r
-    DIM lin1!(0 TO 1500)\r
-    DIM lin2!(0 TO 1500)\r
-    DIM lbx1(1 TO 1500)\r
-    DIM lby1(1 TO 1500)\r
-    DIM lbx2(1 TO 1500)\r
-    DIM lby2(1 TO 1500)\r
-\r
-    DIM np, nl\r
-    DIM an1, an2, an3\r
-    DIM an1s, an2s, an3s\r
-    DIM inco, inpo\r
-    DIM tim\r
-    DIM nlt\r
-    DIM ehi\r
-\r
-    tim = 0\r
-    ehi = 1\r
-    an1 = 0\r
-    an2 = 0\r
-    np = -1\r
-    nl = 0\r
-    inco = 0\r
-    inpo = 0\r
-    nlt = 0\r
+\r
+    DIM pointX(0 TO 1000)\r
+    DIM pointY(0 TO 1000)\r
+    DIM pointZ(0 TO 1000)\r
+\r
+    DIM projectedX(0 TO 1000)\r
+    DIM projectedY(0 TO 1000)\r
+\r
+    DIM linePointOne!(0 TO 1500)\r
+    DIM linePointTwo!(0 TO 1500)\r
+\r
+    DIM lineBufferXOne(1 TO 1500)\r
+    DIM lineBufferYOne(1 TO 1500)\r
+    DIM lineBufferXTwo(1 TO 1500)\r
+    DIM lineBufferYTwo(1 TO 1500)\r
+\r
+    DIM numPoints, numLines\r
+    DIM angleOne, angleTwo, angleThree\r
+    DIM angleOneSpeed, angleTwoSpeed, angleThreeSpeed\r
+    DIM incPoints, incPolys\r
+    DIM timeCounter\r
+    DIM totalLines\r
+    DIM extraHelperIndex\r
+\r
+    timeCounter = 0\r
+    extraHelperIndex = 1\r
+    angleOne = 0\r
+    angleTwo = 0\r
+    numPoints = -1\r
+    numLines = 0\r
+    incPoints = 0\r
+    incPolys = 0\r
+    totalLines = 0\r
 \r
     SetPalette 40, 40, 40, 254\r
     COLOR 254\r
@@ -396,453 +438,495 @@ SUB Scene1
     PRINT "One moment"\r
 \r
     OPEN "data.dat" FOR INPUT AS #1\r
-    INPUT #1, a\r
-    INPUT #1, inco\r
-    INPUT #1, inpo\r
-\r
-    FOR a = 1 TO inco\r
-        INPUT #1, x, y, z\r
-        np = np + 1\r
-        px(np) = x - 100\r
-        py(np) = y\r
-        pz(np) = z\r
-    NEXT a\r
-\r
-    INPUT #1, b, b, l1, l2, l3\r
-\r
-    FOR a = 1 TO inpo - 1\r
-        INPUT #1, b, b, l1!, l2!, l3!\r
-        nlin1! = l1!\r
-        nlin2! = l2!\r
-        GOSUB addlin\r
-        nlin1! = l2!\r
-        nlin2! = l3!\r
-        GOSUB addlin\r
-        nlin1! = l1!\r
-        nlin2! = l3!\r
-        GOSUB addlin\r
+    INPUT #1, readTemp\r
+    INPUT #1, incPoints\r
+    INPUT #1, incPolys\r
+\r
+    FOR loopIndex = 1 TO incPoints\r
+        INPUT #1, pxVal, pyVal, pzVal\r
+        numPoints = numPoints + 1\r
+        pointX(numPoints) = pxVal - 100\r
+        pointY(numPoints) = pyVal\r
+        pointZ(numPoints) = pzVal\r
+    NEXT loopIndex\r
+\r
+    INPUT #1, dummyVar, dummyVar, lineVal1, lineVal2, lineVal3\r
+\r
+    FOR loopIndex = 1 TO incPolys - 1\r
+        INPUT #1, dummyVar, dummyVar, lineVal1!, lineVal2!, lineVal3!\r
+        newLineOne! = lineVal1!\r
+        newLineTwo! = lineVal2!\r
+        GOSUB addLine\r
+        newLineOne! = lineVal2!\r
+        newLineTwo! = lineVal3!\r
+        GOSUB addLine\r
+        newLineOne! = lineVal1!\r
+        newLineTwo! = lineVal3!\r
+        GOSUB addLine\r
         LOCATE 4, 10\r
-        PRINT STR$(INT(a / (inpo - 1) * 100)) + "% ready"\r
-    NEXT a\r
+        PRINT STR$(INT(loopIndex / (incPolys - 1) * 100)) + "% ready"\r
+    NEXT loopIndex\r
     CLOSE 1\r
     CLS\r
 \r
-3 :\r
-    tim = tim + 1\r
+rotateLoop:\r
+    timeCounter = timeCounter + 1\r
+\r
     quitKey$ = INKEY$\r
     IF quitKey$ = "q" THEN END\r
 \r
-    a = COS(tim / 25)\r
-    an1 = COS(tim / 29) * a\r
-    an2 = (pii / 2) + SIN(tim / 42) * a\r
+    varA = COS(timeCounter / 25)\r
+    angleOne = COS(timeCounter / 29) * varA\r
+    angleTwo = (globalPiI / 2) + SIN(timeCounter / 42) * varA\r
 \r
-    s1 = SIN(an1)\r
-    c1 = COS(an1)\r
-    s2 = SIN(an2)\r
-    c2 = COS(an2)\r
+    sin1 = SIN(angleOne)\r
+    cos1 = COS(angleOne)\r
+    sin2 = SIN(angleTwo)\r
+    cos2 = COS(angleTwo)\r
 \r
-    IF ehi >= 1 THEN\r
-        nlt = nlt + ehi\r
-        ehi = ehi + .03\r
-        IF nlt > nl THEN nlt = nl: ehi = 0\r
+    IF extraHelperIndex >= 1 THEN\r
+        totalLines = totalLines + extraHelperIndex\r
+        extraHelperIndex = extraHelperIndex + .03\r
+        IF totalLines > numLines THEN totalLines = numLines: extraHelperIndex = 0\r
     END IF\r
 \r
-    FOR a = 0 TO np\r
-        x = px(a)\r
-        y = py(a)\r
-        z = pz(a)\r
-\r
-        z2 = z * s1 + y * c1\r
-        y1 = y * s1 - z * c1\r
-\r
-        z1 = z2 * s2 + x * c2\r
-        x1 = x * s2 - z2 * c2\r
-\r
-        z1 = z1 + 100\r
-        x1 = x1 / z1 * 74 * 2\r
-        y1 = y1 / z1 * 65 * 2\r
-\r
-        px1(a) = x1 + 160\r
-        py1(a) = y1 + 80\r
-    NEXT a\r
-\r
-    FOR a = 1 TO nlt\r
-        l1 = lin1!(a)\r
-        l2 = lin2!(a)\r
-        x1 = px1(l1)\r
-        y1 = py1(l1)\r
-        x2 = px1(l2)\r
-        y2 = py1(l2)\r
-        LINE (lbx1(a), lby1(a))-(lbx2(a), lby2(a)), 0\r
-        LINE (x1, y1)-(x2, y2), 255\r
-        lbx1(a) = x1\r
-        lby1(a) = y1\r
-        lbx2(a) = x2\r
-        lby2(a) = y2\r
-    NEXT a\r
+    ' Project each 3D point to 2D\r
+    FOR loopIndex = 0 TO numPoints\r
+        localX = pointX(loopIndex)\r
+        localY = pointY(loopIndex)\r
+        localZ = pointZ(loopIndex)\r
+\r
+        zTemp = localZ * sin1 + localY * cos1\r
+        yTemp = localY * sin1 - localZ * cos1\r
+\r
+        zFinal = zTemp * sin2 + localX * cos2\r
+        xFinal = localX * sin2 - zTemp * cos2\r
+\r
+        zFinal = zFinal + 100\r
+        xFinal = xFinal / zFinal * 74 * 2\r
+        yFinal = yTemp / zFinal * 65 * 2\r
+\r
+        projectedX(loopIndex) = xFinal + 160\r
+        projectedY(loopIndex) = yFinal + 80\r
+    NEXT loopIndex\r
+\r
+    ' Draw lines\r
+    FOR loopIndex = 1 TO totalLines\r
+        lineStart = linePointOne!(loopIndex)\r
+        lineEnd = linePointTwo!(loopIndex)\r
+        x1Temp = projectedX(lineStart)\r
+        y1Temp = projectedY(lineStart)\r
+        x2Temp = projectedX(lineEnd)\r
+        y2Temp = projectedY(lineEnd)\r
+        LINE (lineBufferXOne(loopIndex), lineBufferYOne(loopIndex))-(lineBufferXTwo(loopIndex), lineBufferYTwo(loopIndex)), 0\r
+        LINE (x1Temp, y1Temp)-(x2Temp, y2Temp), 255\r
+        lineBufferXOne(loopIndex) = x1Temp\r
+        lineBufferYOne(loopIndex) = y1Temp\r
+        lineBufferXTwo(loopIndex) = x2Temp\r
+        lineBufferYTwo(loopIndex) = y2Temp\r
+    NEXT loopIndex\r
+\r
     SOUND 0, .5\r
-    IF tim < 280 THEN GOTO 3\r
-    GOTO 4\r
+    IF timeCounter < 280 THEN GOTO rotateLoop\r
+    GOTO endScene\r
 \r
-addlin:\r
-    FOR b = 1 TO nl\r
-        IF lin1!(b) = nlin1! THEN\r
-            IF lin2!(b) = nlin2! THEN RETURN\r
+addLine:\r
+    FOR checkIndex = 1 TO numLines\r
+        IF linePointOne!(checkIndex) = newLineOne! THEN\r
+            IF linePointTwo!(checkIndex) = newLineTwo! THEN RETURN\r
         END IF\r
-        IF lin1!(b) = nlin2! THEN\r
-            IF lin2!(b) = nlin1! THEN RETURN\r
+        IF linePointOne!(checkIndex) = newLineTwo! THEN\r
+            IF linePointTwo!(checkIndex) = newLineOne! THEN RETURN\r
         END IF\r
-    NEXT b\r
-    nl = nl + 1\r
-    lin1!(nl) = nlin1!\r
-    lin2!(nl) = nlin2!\r
+    NEXT checkIndex\r
+    numLines = numLines + 1\r
+    linePointOne!(numLines) = newLineOne!\r
+    linePointTwo!(numLines) = newLineTwo!\r
     RETURN\r
 \r
-:\r
-    angl1 = an1\r
-    angl2 = an2\r
+endScene:\r
+    globalAngleOne = angleOne\r
+    globalAngleTwo = angleTwo\r
 END SUB\r
 \r
-'-------------------------------------------------------------------------------\r
-SUB Scene2\r
-' Loads 3D data from "data.dat" and projects triangular faces to 2D.\r
-' The polygons are sorted by depth, then drawn from farthest to nearest\r
-' using FillPolygon to produce simple hidden-surface-like rendering.\r
 \r
+SUB Scene2\r
+'\r
+' Loads 3D data from "data.dat" and projects triangular faces in 2D.\r
+' Each triangle's average depth is computed, and polygons are drawn\r
+' from back to front with FillPolygon. The shading is computed too.\r
+'\r
     SetPalette 0, 63, 20, 255\r
     CLS\r
-    angl1 = 0\r
-    angl2 = 1.5\r
-    DIM px(0 TO 2000)\r
-    DIM py(0 TO 2000)\r
-    DIM pz(0 TO 2000)\r
+    globalAngleOne = 0\r
+    globalAngleTwo = 1.5\r
 \r
-    DIM rpx(0 TO 2000)\r
-    DIM rpy(0 TO 2000)\r
-    DIM rpz(0 TO 2000)\r
+    DIM pointX(0 TO 2000)\r
+    DIM pointY(0 TO 2000)\r
+    DIM pointZ(0 TO 2000)\r
 \r
-    DIM pol1(1 TO 2000)\r
-    DIM pol2(1 TO 2000)\r
-    DIM pol3(1 TO 2000)\r
+    DIM rotatedX(0 TO 2000)\r
+    DIM rotatedY(0 TO 2000)\r
+    DIM rotatedZ(0 TO 2000)\r
 \r
-    np = 0\r
-    nl = 0\r
+    DIM polyOne(1 TO 2000)\r
+    DIM polyTwo(1 TO 2000)\r
+    DIM polyThree(1 TO 2000)\r
+\r
+    numPoints = 0\r
+    numTriangles = 0\r
 \r
     OPEN "data.dat" FOR INPUT AS #1\r
-    INPUT #1, a\r
-    INPUT #1, inco\r
-    INPUT #1, inpo\r
-\r
-    FOR a = 1 TO inco\r
-        INPUT #1, x, y, z\r
-        px(np) = x - 100\r
-        py(np) = y\r
-        pz(np) = z\r
-        np = np + 1\r
-    NEXT a\r
-\r
-    INPUT #1, b, b, l1, l2, l3\r
-\r
-    FOR a = 1 TO inpo - 1\r
-        INPUT #1, b, b, l1, l2, l3\r
-        nl = nl + 1\r
-        pol1(nl) = l1\r
-        pol2(nl) = l2\r
-        pol3(nl) = l3\r
-    NEXT a\r
+    INPUT #1, readTemp\r
+    INPUT #1, totalPoints\r
+    INPUT #1, totalPolys\r
+\r
+    FOR loopIndex = 1 TO totalPoints\r
+        INPUT #1, posXVal, posYVal, posZVal\r
+        pointX(numPoints) = posXVal - 100\r
+        pointY(numPoints) = posYVal\r
+        pointZ(numPoints) = posZVal\r
+        numPoints = numPoints + 1\r
+    NEXT loopIndex\r
+\r
+    INPUT #1, dummyVal, dummyVal, lineValA, lineValB, lineValC\r
+\r
+    FOR loopIndex = 1 TO totalPolys - 1\r
+        INPUT #1, dummyVal, dummyVal, lineValA, lineValB, lineValC\r
+        numTriangles = numTriangles + 1\r
+        polyOne(numTriangles) = lineValA\r
+        polyTwo(numTriangles) = lineValB\r
+        polyThree(numTriangles) = lineValC\r
+    NEXT loopIndex\r
     CLOSE #1\r
 \r
-    s1 = SIN(angl1)\r
-    c1 = COS(angl1)\r
-    s2 = SIN(angl2)\r
-    c2 = COS(angl2)\r
-\r
-    FOR a = 0 TO np\r
-        x = px(a)\r
-        y = py(a)\r
-        z = pz(a)\r
-        z2 = z * s1 + y * c1\r
-        y1 = y * s1 - z * c1\r
-        z1 = z2 * s2 + x * c2\r
-        x1 = x * s2 - z2 * c2\r
-        z1 = z1 + 100\r
-        x1 = x1 / z1 * 74 * 2\r
-        y1 = y1 / z1 * 65 * 2\r
-        rpx(a) = x1 + 160\r
-        rpy(a) = y1 + 80\r
-        rpz(a) = z1\r
-    NEXT a\r
-\r
-    FOR a = 1 TO 49\r
-        SetPalette a * 1.1 + 20, a * 1.1 + 10, a * 1.1, a\r
-    NEXT a\r
-\r
-    DIM polz(1 TO nl)\r
-\r
-    FOR a = 1 TO nl\r
-        polz(a) = (rpz(pol1(a)) + rpz(pol2(a)) + rpz(pol3(a)))\r
-    NEXT a\r
-\r
-    e = nl\r
-    FOR a = 1 TO nl\r
-        su = -10000\r
-        sun = 1\r
-        FOR b = 1 TO e\r
-            IF polz(b) > su THEN su = polz(b): sun = b\r
-        NEXT b\r
-\r
-        p1 = pol1(sun)\r
-        p2 = pol2(sun)\r
-        p3 = pol3(sun)\r
-\r
-        polz(sun) = polz(e)\r
-        pol1(sun) = pol1(e)\r
-        pol2(sun) = pol2(e)\r
-        pol3(sun) = pol3(e)\r
-        e = e - 1\r
-\r
-        ComputeShadeValue rpx(p1), rpy(p1), rpz(p1), rpx(p2), rpy(p2), rpz(p2), rpx(p3), rpy(p3), rpz(p3), d\r
-        FillPolygon INT(rpx(p1)), INT(rpy(p1)), INT(rpx(p2)), INT(rpy(p2)), INT(rpx(p3)), INT(rpy(p3)), INT(d)\r
-    NEXT a\r
+    sin1 = SIN(globalAngleOne)\r
+    cos1 = COS(globalAngleOne)\r
+    sin2 = SIN(globalAngleTwo)\r
+    cos2 = COS(globalAngleTwo)\r
+\r
+    ' Project each 3D point\r
+    FOR loopIndex = 0 TO numPoints\r
+        localX = pointX(loopIndex)\r
+        localY = pointY(loopIndex)\r
+        localZ = pointZ(loopIndex)\r
+\r
+        zTmp = localZ * sin1 + localY * cos1\r
+        yTmp = localY * sin1 - localZ * cos1\r
+        zFin = zTmp * sin2 + localX * cos2\r
+        xFin = localX * sin2 - zTmp * cos2\r
+\r
+        zFin = zFin + 100\r
+        xFin = xFin / zFin * 74 * 2\r
+        yFin = yTmp / zFin * 65 * 2\r
+\r
+        rotatedX(loopIndex) = xFin + 160\r
+        rotatedY(loopIndex) = yFin + 80\r
+        rotatedZ(loopIndex) = zFin\r
+    NEXT loopIndex\r
+\r
+    ' Adjust palette for shading\r
+    FOR loopIndex = 1 TO 49\r
+        SetPalette loopIndex * 1.1 + 20, loopIndex * 1.1 + 10, loopIndex * 1.1, loopIndex\r
+    NEXT loopIndex\r
+\r
+    DIM polyDepth(1 TO numTriangles)\r
+\r
+    FOR loopIndex = 1 TO numTriangles\r
+        polyDepth(loopIndex) = (rotatedZ(polyOne(loopIndex)) + rotatedZ(polyTwo(loopIndex)) + rotatedZ(polyThree(loopIndex)))\r
+    NEXT loopIndex\r
+\r
+    eIndex = numTriangles\r
+\r
+    ' Sort by descending depth (z)\r
+    FOR loopIndex = 1 TO numTriangles\r
+        bigVal = -10000\r
+        bigIndex = 1\r
+        FOR checkIdx = 1 TO eIndex\r
+            IF polyDepth(checkIdx) > bigVal THEN\r
+                bigVal = polyDepth(checkIdx)\r
+                bigIndex = checkIdx\r
+            END IF\r
+        NEXT checkIdx\r
+\r
+        pA = polyOne(bigIndex)\r
+        pB = polyTwo(bigIndex)\r
+        pC = polyThree(bigIndex)\r
+\r
+        polyDepth(bigIndex) = polyDepth(eIndex)\r
+        polyOne(bigIndex) = polyOne(eIndex)\r
+        polyTwo(bigIndex) = polyTwo(eIndex)\r
+        polyThree(bigIndex) = polyThree(eIndex)\r
+        eIndex = eIndex - 1\r
+\r
+        ComputeShadeValue rotatedX(pA), rotatedY(pA), rotatedZ(pA), _\r
+                          rotatedX(pB), rotatedY(pB), rotatedZ(pB), _\r
+                          rotatedX(pC), rotatedY(pC), rotatedZ(pC), shadeVal\r
+\r
+        FillPolygon INT(rotatedX(pA)), INT(rotatedY(pA)), _\r
+                    INT(rotatedX(pB)), INT(rotatedY(pB)), _\r
+                    INT(rotatedX(pC)), INT(rotatedY(pC)), INT(shadeVal)\r
+    NEXT loopIndex\r
 END SUB\r
 \r
-'-------------------------------------------------------------------------------\r
-SUB Scene3\r
-' Demonstrates some simple raster effects and wave patterns,\r
-' finishing with basic text drawing and random shifts of the screen buffer.\r
-\r
-    DIM buf(1 TO 10000)\r
-    DIM buf1(0 TO 35)\r
 \r
-    FOR a = 1 TO 20\r
+SUB Scene3\r
+'\r
+' Demonstrates simple raster/wave effects by copying screen slices,\r
+' does some random shifting, then shows text with circles around the bits.\r
+'\r
+    DIM bufferArray(1 TO 10000)\r
+    DIM waveArray(0 TO 35)\r
+\r
+    FOR loopIndex = 1 TO 20\r
         SOUND 0, 1\r
-    NEXT a\r
-    FOR a = 0 TO 30\r
-        IF a <= 5 THEN buf1(a) = 120 + (SQR((20 - a) * a))\r
-        IF (a > 5) AND (a < 25) THEN buf1(a) = 120 + 10\r
-        IF a >= 25 THEN buf1(a) = 120 + (SQR((30 - a) * (a - 10)))\r
-    NEXT a\r
-\r
-    FOR y = 0 TO 30\r
-        FOR x = 10 TO 300 STEP 10\r
-            GET (x, 0)-(x + 9, 198), buf(1)\r
-            PUT (x, 1), buf(1), PSET\r
-        NEXT x\r
-        FOR a = 1 TO 49\r
-            SetPalette a * 1.1 + (20 - y), a * 1.1 + 10 + (y / 1.5), a * 1.1, a\r
-        NEXT a\r
+    NEXT loopIndex\r
+\r
+    ' Build a wave-like boundary in waveArray()\r
+    FOR loopIndex = 0 TO 30\r
+        IF loopIndex <= 5 THEN waveArray(loopIndex) = 120 + (SQR((20 - loopIndex) * loopIndex))\r
+        IF (loopIndex > 5) AND (loopIndex < 25) THEN waveArray(loopIndex) = 120 + 10\r
+        IF loopIndex >= 25 THEN waveArray(loopIndex) = 120 + (SQR((30 - loopIndex) * (loopIndex - 10)))\r
+    NEXT loopIndex\r
+\r
+    ' Slide the screen upward in small blocks\r
+    FOR screenY = 0 TO 30\r
+        FOR screenX = 10 TO 300 STEP 10\r
+            GET (screenX, 0)-(screenX + 9, 198), bufferArray(1)\r
+            PUT (screenX, 1), bufferArray(1), PSET\r
+        NEXT screenX\r
+\r
+        ' Slight color shift\r
+        FOR colorIx = 1 TO 49\r
+            SetPalette colorIx * 1.1 + (20 - screenY), colorIx * 1.1 + 10 + (screenY / 1.5), colorIx * 1.1, colorIx\r
+        NEXT colorIx\r
+\r
         SOUND 0, 1\r
-        LINE (160 - buf1(y), 20)-(160 + buf1(y), 20), 255\r
-    NEXT y\r
+        LINE (160 - waveArray(screenY), 20)-(160 + waveArray(screenY), 20), 255\r
+    NEXT screenY\r
 \r
     LOCATE 1, 1\r
     COLOR 254\r
     SetPalette 0, 0, 0, 254\r
     PRINT "Tehisintellekt"\r
     SetPalette 63, 0, 0, 253\r
-    FOR y = 0 TO 8\r
-        FOR x = 0 TO 120\r
-            c = POINT(x, y)\r
-            IF c > 0 THEN CIRCLE (x * 2 + 50, y * 3 + 26), 2, 0\r
-        NEXT x\r
-        FOR x = 0 TO 120\r
-            c = POINT(x, y + 1)\r
-            IF c > 0 THEN CIRCLE (x * 2 + 50, (y + 1) * 3 + 26), 2, 253\r
-        NEXT x\r
+\r
+    ' Draw circles around the nonzero pixels of the printed text\r
+    FOR rowY = 0 TO 8\r
+        FOR rowX = 0 TO 120\r
+            pixelVal = POINT(rowX, rowY)\r
+            IF pixelVal > 0 THEN CIRCLE (rowX * 2 + 50, rowY * 3 + 26), 2, 0\r
+        NEXT rowX\r
+\r
+        FOR rowX = 0 TO 120\r
+            pixelVal = POINT(rowX, rowY + 1)\r
+            IF pixelVal > 0 THEN CIRCLE (rowX * 2 + 50, (rowY + 1) * 3 + 26), 2, 253\r
+        NEXT rowX\r
         SOUND 0, 2\r
-    NEXT y\r
+    NEXT rowY\r
 \r
     RANDOMIZE 1\r
 \r
-    FOR a = 1 TO 10\r
-        y = RND * 100 + 50\r
-        FOR x = 10 TO 300 STEP 10\r
-            GET (x, y)-(x + 9, 198), buf(1)\r
-            PUT (x, y - 1), buf(1), PSET\r
-        NEXT x\r
-    NEXT a\r
+    ' Perform random screen shifts\r
+    FOR loopIndex = 1 TO 10\r
+        randY = RND * 100 + 50\r
+        FOR screenX = 10 TO 300 STEP 10\r
+            GET (screenX, randY)-(screenX + 9, 198), bufferArray(1)\r
+            PUT (screenX, randY - 1), bufferArray(1), PSET\r
+        NEXT screenX\r
+    NEXT loopIndex\r
 \r
     COLOR 253\r
     SetPalette 0, 0, 0, 253\r
     LOCATE 1\r
     PRINT " autor:  Svjatoslav Agejenko 30.09.2001 "\r
-    GET (0, 0)-(319, 8), buf(1)\r
+\r
+    GET (0, 0)-(319, 8), bufferArray(1)\r
     LOCATE 1\r
     PRINT "                                        "\r
-    PUT (0, 190), buf(1), PSET\r
-    FOR a = 1 TO 32\r
-        SetPalette 0, a, a * 2, 253\r
+    PUT (0, 190), bufferArray(1), PSET\r
+\r
+    FOR loopIndex = 1 TO 32\r
+        SetPalette 0, loopIndex, loopIndex * 2, 253\r
         SOUND 0, 1\r
-    NEXT a\r
+    NEXT loopIndex\r
 \r
     WaitForInput\r
 END SUB\r
 \r
-'-------------------------------------------------------------------------------\r
-SUB Scene4\r
-' Uses MakeBackground to generate a fractal backdrop, then draws a box\r
-' and prints some brief text explaining a "Spatial vision" concept.\r
 \r
+SUB Scene4\r
+'\r
+' Builds a fractal backdrop, draws a "rounded box," and prints short text lines\r
+' about "Spatial vision" and "Object recognition."\r
+'\r
     RANDOMIZE 1\r
     MakeBackground\r
 \r
     DrawRoundedBox 30, 50, 290, 150\r
 \r
     SetPalette 32, 64, 32, 250\r
-    y = 0\r
-    PrintText 30, 70 + y, 1, 250, " Spatial vision"\r
-    y = y + 16\r
-    PrintText 30, 70 + y, 1, 250, "Object recognition"\r
-    y = y + 20\r
-    PrintText 30, 70 + y, 1, 250, "Goal:    + interpriteerimine"\r
-    y = y + 16\r
-    PrintText 30, 70 + y, 1, 250, "            + automaatjuhtimine"\r
+    yOffset = 0\r
+    PrintText 30, 70 + yOffset, 1, 250, " Spatial vision"\r
+    yOffset = yOffset + 16\r
+    PrintText 30, 70 + yOffset, 1, 250, "Object recognition"\r
+    yOffset = yOffset + 20\r
+    PrintText 30, 70 + yOffset, 1, 250, "Goal:    + interpriteerimine"\r
+    yOffset = yOffset + 16\r
+    PrintText 30, 70 + yOffset, 1, 250, "            + automaatjuhtimine"\r
 \r
     WaitForInput\r
 END SUB\r
 \r
+\r
 '-------------------------------------------------------------------------------\r
 SUB Scene5\r
-' Again uses MakeBackground, draws a box, and prints text describing\r
-' a feature-extraction process in image processing or computer vision.\r
-\r
+'\r
+' Again creates a fractal background, draws a box, and explains\r
+' some feature-extraction (edges) approaches: Laplace-Gauss, wavelet,\r
+' hypercolumn theory, etc.\r
+'\r
     RANDOMIZE 4\r
     MakeBackground\r
 \r
-    DrawRoundedBox 30, 50, 290, 150   ' Renamed call\r
+    DrawRoundedBox 30, 50, 290, 150\r
 \r
     SetPalette 32, 64, 32, 250\r
-    y = -8\r
-    PrintText 30, 70 + y, 1, 250, "Tunnuste ekstraheerimise protsess"\r
-    y = y + 20\r
-    PrintText 30, 70 + y, 1, 250, "a) Laplace - Gaussi operaator;"\r
-    y = y + 12\r
-    PrintText 30, 70 + y, 1, 250, "b) lainekese teisenduse multi-"\r
-    y = y + 12\r
-    PrintText 30, 70 + y, 1, 250, "   skaalaline serva avastamine;"\r
-    y = y + 12\r
-    PrintText 30, 70 + y, 1, 250, "c) h�perveeru teooria lihtsate"\r
-    y = y + 12\r
-    PrintText 30, 70 + y, 1, 250, "   rakkude p�him�tted."\r
+    yOffset = -8\r
+    PrintText 30, 70 + yOffset, 1, 250, "Tunnuste ekstraheerimise protsess"\r
+    yOffset = yOffset + 20\r
+    PrintText 30, 70 + yOffset, 1, 250, "a) Laplace - Gaussi operaator;"\r
+    yOffset = yOffset + 12\r
+    PrintText 30, 70 + yOffset, 1, 250, "b) lainekese teisenduse multi-"\r
+    yOffset = yOffset + 12\r
+    PrintText 30, 70 + yOffset, 1, 250, "   skaalaline serva avastamine;"\r
+    yOffset = yOffset + 12\r
+    PrintText 30, 70 + yOffset, 1, 250, "c) h�perveeru teooria lihtsate"\r
+    yOffset = yOffset + 12\r
+    PrintText 30, 70 + yOffset, 1, 250, "   rakkude p�him�tted."\r
 \r
     WaitForInput\r
 END SUB\r
 \r
-'-------------------------------------------------------------------------------\r
-SUB Scene7\r
-' Simple transition effect: horizontal lines are drawn across the screen\r
-' from top to bottom, clearing or darkening each row.\r
 \r
+SUB Scene7\r
+'\r
+' Simple transitional effect: draws horizontal lines across the screen\r
+' in steps, clearing or darkening each row to black.\r
+'\r
     SetPalette 0, 0, 0, 0\r
-    FOR a = 0 TO 19\r
-        FOR y = a TO 199 STEP 20\r
-            LINE (0, y)-(319, y), 0\r
-        NEXT y\r
+    FOR outerIndex = 0 TO 19\r
+        FOR drawY = outerIndex TO 199 STEP 20\r
+            LINE (0, drawY)-(319, drawY), 0\r
+        NEXT drawY\r
         SOUND 0, .5\r
-    NEXT a\r
+    NEXT outerIndex\r
 END SUB\r
 \r
-'-------------------------------------------------------------------------------\r
+\r
 SUB Scene8\r
-' A more complex 3D-like demo. It generates fractal terrain in the background,\r
-' then plots points in a grid and draws lines between them. A "player" or\r
-' "robot" object (with lines making a cube-like shape) moves around,\r
-' picking up items, until time or user input ends the loop.\r
-\r
-    FOR a = 1 TO 50\r
-        SetPalette 0, 0, 0, a\r
-    NEXT a\r
-\r
-    DIM px(0 TO 800)\r
-    DIM py(0 TO 800)\r
-    DIM pz(0 TO 800)\r
-    DIM lin1(0 TO 1000)\r
-    DIM lin2(0 TO 1000)\r
-    DIM linc(0 TO 1000)\r
-    DIM lbx1(1 TO 1000)\r
-    DIM lby1(1 TO 1000)\r
-    DIM lbx2(1 TO 1000)\r
-    DIM lby2(1 TO 1000)\r
-    DIM px1(0 TO 800)\r
-    DIM py1(0 TO 800)\r
-    DIM hlkx(1 TO 50)\r
-    DIM hlky(1 TO 50)\r
-    DIM hlkz(1 TO 50)\r
-    DIM hlka\r
-    DIM hlkr\r
-    DIM hlknu\r
-    DIM hlkin\r
-    DIM hlax, hlay, hlaz\r
-    DIM mx, mz, my\r
-    DIM desx, desz\r
-    DIM desa\r
-\r
-    DIM np, nl\r
-    DIM an1, an2\r
-    DIM tim\r
-    DIM eta\r
-    DIM mil\r
-    DIM miin\r
-\r
-    miin = 0\r
-    mil = 25\r
-    tim = 0\r
-    eta = 1\r
-    an1 = 0\r
-    an2 = 0\r
-\r
-    np = 0\r
-    nl = 0\r
+'\r
+' A more complex 3D scene: fractal terrain plus a "player" or "robot" object\r
+' that collects items scattered on the terrain. Movement, angles, and final\r
+' transformations are computed until time or key-press ends the loop.\r
+'\r
+    FOR fadeIndex = 1 TO 50\r
+        SetPalette 0, 0, 0, fadeIndex\r
+    NEXT fadeIndex\r
+\r
+    DIM mainX(0 TO 800)\r
+    DIM mainY(0 TO 800)\r
+    DIM mainZ(0 TO 800)\r
+\r
+    DIM lineStart(0 TO 1000)\r
+    DIM lineEnd(0 TO 1000)\r
+    DIM lineColor(0 TO 1000)\r
+    DIM lineBufferXOne(1 TO 1000)\r
+    DIM lineBufferYOne(1 TO 1000)\r
+    DIM lineBufferXTwo(1 TO 1000)\r
+    DIM lineBufferYTwo(1 TO 1000)\r
+\r
+    DIM projectedX(0 TO 800)\r
+    DIM projectedY(0 TO 800)\r
+\r
+    DIM holdX(1 TO 50)\r
+    DIM holdY(1 TO 50)\r
+    DIM holdZ(1 TO 50)\r
+\r
+    DIM holdAngle\r
+    DIM holdRot\r
+    DIM holdNumber\r
+    DIM holdIndex\r
+    DIM holdAx, holdAy, holdAz\r
+    DIM moveX, moveZ, moveY\r
+    DIM destinationX, destinationZ\r
+    DIM destinationAngle\r
+\r
+    DIM totalPoints, totalLines\r
+    DIM angleOne, angleTwo\r
+    DIM timeCounter\r
+    DIM incVal\r
+    DIM miniCount\r
+    DIM minutesVal\r
+\r
+    minutesVal = 0\r
+    miniCount = 25\r
+    timeCounter = 0\r
+    incVal = 1\r
+    angleOne = 0\r
+    angleTwo = 0\r
+\r
+    totalPoints = 0\r
+    totalLines = 0\r
     RANDOMIZE 100\r
-    s = 64\r
-\r
-14 :\r
-    sp = s / 2\r
-    FOR y = 0 TO 100 STEP s\r
-        FOR x = 0 TO 100 STEP s\r
-            c1 = POINT(x, y)\r
-            c2 = POINT(x + s, y)\r
-            c3 = POINT(x, y + s)\r
-            c4 = POINT(x + s, y + s)\r
-            c5 = (c1 + c2 + c3 + c4) / 4 + RND * s * 6 - sp * 7\r
-            c6 = (c2 + c4) / 2 + RND * s * 6 - sp * 7\r
-            c7 = (c3 + c4) / 2 + RND * s * 6 - sp * 7\r
-            IF c5 > 50 THEN c5 = 50\r
-            IF c5 < 0 THEN c5 = 0\r
-            IF c6 > 50 THEN c6 = 50\r
-            IF c6 < 0 THEN c6 = 0\r
-            IF c7 > 50 THEN c7 = 50\r
-            IF c7 < 0 THEN c7 = 0\r
-            PSET (x + sp, y + sp), c5\r
-            PSET (x + s, y + sp), c6\r
-            PSET (x + sp, y + s), c7\r
-        NEXT x\r
-    NEXT y\r
-    s = s / 2\r
-    IF s > 1 THEN GOTO 14\r
-\r
-    'a$ = INPUT$(1)\r
-\r
-    FOR z = 1 TO 400 STEP 20\r
-        FOR x = 1 TO 400 STEP 20\r
-            np = np + 1\r
-            px(np) = x\r
-            py(np) = POINT(z / 20 + 10, x / 20 + 10) * 2\r
-            pz(np) = z\r
-            IF x > 1 THEN\r
-                nl = nl + 1\r
-                lin1(nl) = np\r
-                lin2(nl) = np - 1\r
-                linc(nl) = 1\r
+    blockSize = 64\r
+\r
+fractalSubLoop:\r
+    halfBlock = blockSize / 2\r
+    FOR yLoop = 0 TO 100 STEP blockSize\r
+        FOR xLoop = 0 TO 100 STEP blockSize\r
+            color1 = POINT(xLoop, yLoop)\r
+            color2 = POINT(xLoop + blockSize, yLoop)\r
+            color3 = POINT(xLoop, yLoop + blockSize)\r
+            color4 = POINT(xLoop + blockSize, yLoop + blockSize)\r
+            color5 = (color1 + color2 + color3 + color4) / 4 + RND * blockSize * 6 - halfBlock * 7\r
+            color6 = (color2 + color4) / 2 + RND * blockSize * 6 - halfBlock * 7\r
+            color7 = (color3 + color4) / 2 + RND * blockSize * 6 - halfBlock * 7\r
+            IF color5 > 50 THEN color5 = 50\r
+            IF color5 < 0 THEN color5 = 0\r
+            IF color6 > 50 THEN color6 = 50\r
+            IF color6 < 0 THEN color6 = 0\r
+            IF color7 > 50 THEN color7 = 50\r
+            IF color7 < 0 THEN color7 = 0\r
+            PSET (xLoop + halfBlock, yLoop + halfBlock), color5\r
+            PSET (xLoop + blockSize, yLoop + halfBlock), color6\r
+            PSET (xLoop + halfBlock, yLoop + blockSize), color7\r
+        NEXT xLoop\r
+    NEXT yLoop\r
+    blockSize = blockSize / 2\r
+    IF blockSize > 1 THEN GOTO fractalSubLoop\r
+\r
+    ' Build mesh points in mainX(), mainY(), mainZ()\r
+    FOR zLoop = 1 TO 400 STEP 20\r
+        FOR xLoop = 1 TO 400 STEP 20\r
+            totalPoints = totalPoints + 1\r
+            mainX(totalPoints) = xLoop\r
+            mainY(totalPoints) = POINT(zLoop / 20 + 10, xLoop / 20 + 10) * 2\r
+            mainZ(totalPoints) = zLoop\r
+            IF xLoop > 1 THEN\r
+                totalLines = totalLines + 1\r
+                lineStart(totalLines) = totalPoints\r
+                lineEnd(totalLines) = totalPoints - 1\r
+                lineColor(totalLines) = 1\r
             END IF\r
-            IF z > 1 THEN\r
-                nl = nl + 1\r
-                lin1(nl) = np\r
-                lin2(nl) = np - 20\r
-                linc(nl) = 1\r
+            IF zLoop > 1 THEN\r
+                totalLines = totalLines + 1\r
+                lineStart(totalLines) = totalPoints\r
+                lineEnd(totalLines) = totalPoints - 20\r
+                lineColor(totalLines) = 1\r
             END IF\r
-        NEXT x\r
-    NEXT z\r
+        NEXT xLoop\r
+    NEXT zLoop\r
 \r
     LINE (0, 0)-(319, 199), 0, BF\r
 \r
@@ -852,277 +936,295 @@ SUB Scene8
     SetPalette 50, 50, 0, 3\r
     SetPalette 64, 20, 0, 4\r
 \r
-    mx = 200\r
-    mz = 200\r
-    kau = 1000\r
-    hlax = 200\r
-    hlay = 0\r
-    hlaz = 200\r
-    desx = 200\r
-    desz = 200\r
+    moveX = 200\r
+    moveZ = 200\r
+    distanceScale = 1000\r
+    holdAx = 200\r
+    holdAy = 0\r
+    holdAz = 200\r
+    destinationX = 200\r
+    destinationZ = 200\r
 \r
     OPEN "data2.dat" FOR INPUT AS #1\r
-    a = 0\r
-    b = 0\r
-    hlkin = np + 1\r
-\r
-15 :\r
-    INPUT #1, x, y, z\r
-    IF x = 999 THEN GOTO 16\r
-    a = a + 1\r
-    hlkx(a) = x\r
-    hlky(a) = -y\r
-    hlkz(a) = z\r
-    GOTO 15\r
-\r
-16 :\r
-    INPUT #1, x, y\r
-    IF x = 999 THEN GOTO 17\r
-    nl = nl + 1\r
-    lin1(nl) = x + np + 1\r
-    lin2(nl) = y + np + 1\r
-    linc(nl) = 2\r
-    GOTO 16\r
-\r
-17 :\r
+    indexA = 0\r
+    indexB = 0\r
+    holdIndex = totalPoints + 1\r
+\r
+readLoop:\r
+    INPUT #1, fileX, fileY, fileZ\r
+    IF fileX = 999 THEN GOTO checkLines\r
+    indexA = indexA + 1\r
+    holdX(indexA) = fileX\r
+    holdY(indexA) = -fileY\r
+    holdZ(indexA) = fileZ\r
+    GOTO readLoop\r
+\r
+checkLines:\r
+    INPUT #1, readA, readB\r
+    IF readA = 999 THEN GOTO closeData\r
+    totalLines = totalLines + 1\r
+    lineStart(totalLines) = readA + totalPoints + 1\r
+    lineEnd(totalLines) = readB + totalPoints + 1\r
+    lineColor(totalLines) = 2\r
+    GOTO checkLines\r
+\r
+closeData:\r
     CLOSE #1\r
-    np = np + a\r
-    hlknu = a\r
+    totalPoints = totalPoints + indexA\r
+    holdNumber = indexA\r
 \r
     RANDOMIZE 10\r
-    c = 3\r
-    FOR a = 1 TO 25\r
-        p = RND * 396 + 2\r
-        x = px(p)\r
-        z = pz(p)\r
-        yy = py(p) - 4\r
-\r
-        px(np + 1) = x - 5\r
-        py(np + 1) = yy\r
-        pz(np + 1) = z - 5\r
-\r
-        px(np + 2) = x + 5\r
-        py(np + 2) = yy\r
-        pz(np + 2) = z - 5\r
-\r
-        px(np + 3) = x + 5\r
-        py(np + 3) = yy\r
-        pz(np + 3) = z + 5\r
-\r
-        px(np + 4) = x - 5\r
-        py(np + 4) = yy\r
-        pz(np + 4) = z + 5\r
-\r
-        px(np + 5) = x\r
-        py(np + 5) = yy - 5\r
-        pz(np + 5) = z\r
-\r
-        lin1(nl + 1) = np + 1\r
-        lin2(nl + 1) = np + 2\r
-        linc(nl + 1) = c\r
-\r
-        lin1(nl + 2) = np + 2\r
-        lin2(nl + 2) = np + 3\r
-        linc(nl + 2) = c\r
-\r
-        lin1(nl + 3) = np + 3\r
-        lin2(nl + 3) = np + 4\r
-        linc(nl + 3) = c\r
-\r
-        lin1(nl + 4) = np + 4\r
-        lin2(nl + 4) = np + 1\r
-        linc(nl + 4) = c\r
-\r
-        lin1(nl + 5) = np + 1\r
-        lin2(nl + 5) = np + 5\r
-        linc(nl + 5) = c\r
-\r
-        lin1(nl + 6) = np + 2\r
-        lin2(nl + 6) = np + 5\r
-        linc(nl + 6) = c\r
-\r
-        lin1(nl + 7) = np + 3\r
-        lin2(nl + 7) = np + 5\r
-        linc(nl + 7) = c\r
-\r
-        lin1(nl + 8) = np + 4\r
-        lin2(nl + 8) = np + 5\r
-        linc(nl + 8) = c\r
-\r
-        np = np + 5\r
-        nl = nl + 8\r
-    NEXT a\r
-\r
-10 :\r
+    colorVal = 3\r
+    FOR indexA = 1 TO 25\r
+        randPick = RND * 396 + 2\r
+        xBox = mainX(randPick)\r
+        zBox = mainZ(randPick)\r
+        yBox = mainY(randPick) - 4\r
+\r
+        mainX(totalPoints + 1) = xBox - 5\r
+        mainY(totalPoints + 1) = yBox\r
+        mainZ(totalPoints + 1) = zBox - 5\r
+\r
+        mainX(totalPoints + 2) = xBox + 5\r
+        mainY(totalPoints + 2) = yBox\r
+        mainZ(totalPoints + 2) = zBox - 5\r
+\r
+        mainX(totalPoints + 3) = xBox + 5\r
+        mainY(totalPoints + 3) = yBox\r
+        mainZ(totalPoints + 3) = zBox + 5\r
+\r
+        mainX(totalPoints + 4) = xBox - 5\r
+        mainY(totalPoints + 4) = yBox\r
+        mainZ(totalPoints + 4) = zBox + 5\r
+\r
+        mainX(totalPoints + 5) = xBox\r
+        mainY(totalPoints + 5) = yBox - 5\r
+        mainZ(totalPoints + 5) = zBox\r
+\r
+        lineStart(totalLines + 1) = totalPoints + 1\r
+        lineEnd(totalLines + 1) = totalPoints + 2\r
+        lineColor(totalLines + 1) = colorVal\r
+\r
+        lineStart(totalLines + 2) = totalPoints + 2\r
+        lineEnd(totalLines + 2) = totalPoints + 3\r
+        lineColor(totalLines + 2) = colorVal\r
+\r
+        lineStart(totalLines + 3) = totalPoints + 3\r
+        lineEnd(totalLines + 3) = totalPoints + 4\r
+        lineColor(totalLines + 3) = colorVal\r
+\r
+        lineStart(totalLines + 4) = totalPoints + 4\r
+        lineEnd(totalLines + 4) = totalPoints + 1\r
+        lineColor(totalLines + 4) = colorVal\r
+\r
+        lineStart(totalLines + 5) = totalPoints + 1\r
+        lineEnd(totalLines + 5) = totalPoints + 5\r
+        lineColor(totalLines + 5) = colorVal\r
+\r
+        lineStart(totalLines + 6) = totalPoints + 2\r
+        lineEnd(totalLines + 6) = totalPoints + 5\r
+        lineColor(totalLines + 6) = colorVal\r
+\r
+        lineStart(totalLines + 7) = totalPoints + 3\r
+        lineEnd(totalLines + 7) = totalPoints + 5\r
+        lineColor(totalLines + 7) = colorVal\r
+\r
+        lineStart(totalLines + 8) = totalPoints + 4\r
+        lineEnd(totalLines + 8) = totalPoints + 5\r
+        lineColor(totalLines + 8) = colorVal\r
+\r
+        totalPoints = totalPoints + 5\r
+        totalLines = totalLines + 8\r
+    NEXT indexA\r
+\r
+mainLoop:\r
     SOUND 0, 1\r
-    IF INKEY$ <> "" THEN miin = 1\r
-    IF miin > 150 THEN GOTO 13\r
-    IF miin <> 0 THEN miin = miin + 7\r
-    mx = hlax\r
-    my = 50 - hlay - miin\r
-    mz = hlaz\r
-\r
-    SELECT CASE eta\r
-    CASE 1\r
-        desx = px(np)\r
-        desz = pz(np)\r
-        GetAngle desx, desz, hlax, hlaz, desa\r
-        IF desa - hlka > pi THEN desa = desa - (pi * 2)\r
-        IF hlka - desa > pi THEN desa = desa + (pi * 2)\r
-        eta = 2\r
-        FOR a = nl - 7 TO nl\r
-            linc(a) = 4\r
-        NEXT a\r
-    CASE 2\r
-        a = desa - hlka\r
-        IF desa = hlka THEN eta = 3\r
-        IF a > .05 THEN a = .05\r
-        IF a < -.05 THEN a = -.05\r
-        hlka = hlka + a\r
-    CASE 3\r
-        x = desx - hlax\r
-        z = desz - hlaz\r
-        v = SQR(x * x + z * z)\r
-        IF v < 5 THEN eta = 4\r
-        v = v / 2\r
-        hlax = hlax + x / v\r
-        hlaz = hlaz + z / v\r
-    CASE 4\r
-        FOR a = np - 4 TO np\r
-            py(a) = py(a) - 1\r
-        NEXT a\r
-        IF py(np) < 3 - hlay THEN\r
-            FOR a = nl - 7 TO nl\r
-                LINE (lbx1(a), lby1(a))-(lbx2(a), lby2(a)), 0\r
-            NEXT a\r
-            np = np - 5\r
-            nl = nl - 8\r
-            mil = mil - 1\r
-            eta = 6\r
-            IF mil <= 0 THEN eta = 7\r
-        END IF\r
-    CASE 6\r
-        eta = 5\r
-    CASE 5\r
-        eta = 1\r
+    IF INKEY$ <> "" THEN minutesVal = 1\r
+    IF minutesVal > 150 THEN GOTO finalArea\r
+    IF minutesVal <> 0 THEN minutesVal = minutesVal + 7\r
+\r
+    moveX = holdAx\r
+    moveY = 50 - holdAy - minutesVal\r
+    moveZ = holdAz\r
+\r
+    SELECT CASE incVal\r
+        CASE 1\r
+            destinationX = mainX(totalPoints)\r
+            destinationZ = mainZ(totalPoints)\r
+            GetAngle destinationX, destinationZ, holdAx, holdAz, destinationAngle\r
+            IF destinationAngle - holdAngle > globalPi THEN destinationAngle = destinationAngle - (globalPi * 2)\r
+            IF holdAngle - destinationAngle > globalPi THEN destinationAngle = destinationAngle + (globalPi * 2)\r
+            incVal = 2\r
+            FOR indexA = totalLines - 7 TO totalLines\r
+                lineColor(indexA) = 4\r
+            NEXT indexA\r
+\r
+        CASE 2\r
+            angleDiff = destinationAngle - holdAngle\r
+            IF destinationAngle = holdAngle THEN incVal = 3\r
+            IF angleDiff > .05 THEN angleDiff = .05\r
+            IF angleDiff < -.05 THEN angleDiff = -.05\r
+            holdAngle = holdAngle + angleDiff\r
+\r
+        CASE 3\r
+            diffX = destinationX - holdAx\r
+            diffZ = destinationZ - holdAz\r
+            distVal = SQR(diffX * diffX + diffZ * diffZ)\r
+            IF distVal < 5 THEN incVal = 4\r
+            distVal = distVal / 2\r
+            holdAx = holdAx + diffX / distVal\r
+            holdAz = holdAz + diffZ / distVal\r
+\r
+        CASE 4\r
+            FOR indexA = totalPoints - 4 TO totalPoints\r
+                mainY(indexA) = mainY(indexA) - 1\r
+            NEXT indexA\r
+            IF mainY(totalPoints) < 3 - holdAy THEN\r
+                FOR indexA = totalLines - 7 TO totalLines\r
+                    LINE (lineBufferXOne(indexA), lineBufferYOne(indexA))-(lineBufferXTwo(indexA), lineBufferYTwo(indexA)), 0\r
+                NEXT indexA\r
+                totalPoints = totalPoints - 5\r
+                totalLines = totalLines - 8\r
+                miniCount = miniCount - 1\r
+                incVal = 6\r
+                IF miniCount <= 0 THEN incVal = 7\r
+            END IF\r
+\r
+        CASE 6\r
+            incVal = 5\r
+\r
+        CASE 5\r
+            incVal = 1\r
     END SELECT\r
 \r
-    y = 60 - py(INT((hlaz + 10) / 20) * 20 + INT((hlax + 10) / 20))\r
-    IF hlay > y + 5 THEN hlay = hlay - 1\r
-    IF hlay < y THEN hlay = hlay + 1\r
-    IF hlay > y + 25 THEN hlay = hlay - 1\r
-    IF hlay < y - 20 THEN hlay = hlay + 1\r
-\r
-    s1 = SIN(hlka)\r
-    c1 = COS(hlka)\r
-    FOR a = 0 TO hlknu - 5\r
-        x = hlkx(a + 1)\r
-        z = hlkz(a + 1)\r
-        px(a + hlkin) = x * s1 + z * c1 + hlax\r
-        py(a + hlkin) = hlky(a + 1) - hlay\r
-        pz(a + hlkin) = z * s1 - x * c1 + hlaz\r
-    NEXT a\r
-\r
-    hlkr = hlkr + .5\r
-    s1 = SIN(hlkr)\r
-    c1 = COS(hlkr)\r
-    FOR a = hlknu - 4 TO hlknu - 1\r
-        x = hlkx(a + 1)\r
-        z = hlkz(a + 1)\r
-        px(a + hlkin) = x * s1 + z * c1 + hlax\r
-        py(a + hlkin) = hlky(a + 1) - hlay\r
-        pz(a + hlkin) = z * s1 - x * c1 + hlaz\r
-    NEXT a\r
-\r
-    tim = tim + 1\r
-\r
-    an1 = an1 + SIN(tim / 100) / 20\r
-    an2 = SIN(tim / 42) * .3 + 1.15\r
-\r
-    s1 = SIN(an1)\r
-    c1 = COS(an1)\r
-    s2 = SIN(an2)\r
-    c2 = COS(an2)\r
-\r
-    FOR a = 0 TO np\r
-        x = px(a) - mx\r
-        y = py(a) - my\r
-        z = pz(a) - mz\r
-\r
-        z2 = z * s1 + x * c1\r
-        x1 = x * s1 - z * c1\r
-\r
-        z1 = z2 * s2 + y * c2\r
-        y1 = y * s2 - z2 * c2\r
-\r
-        z1 = z1 + kau\r
-        IF z1 < 1 THEN px1(a) = -1: GOTO 11\r
-        x1 = x1 / z1 * 74 * 2\r
-        y1 = y1 / z1 * 65 * 2\r
-\r
-        px1(a) = x1 + 160\r
-        py1(a) = y1 + 80\r
-11 :\r
-    NEXT a\r
-\r
-    FOR a = 1 TO nl\r
-        l1 = lin1(a)\r
-        l2 = lin2(a)\r
-        x1 = px1(l1)\r
-        x2 = px1(l2)\r
-        LINE (lbx1(a), lby1(a))-(lbx2(a), lby2(a)), 0\r
-        IF (x1 = -1) OR (x2 = -1) THEN GOTO 12\r
-        y1 = py1(l1)\r
-        y2 = py1(l2)\r
-        LINE (x1, y1)-(x2, y2), linc(a)\r
-        lbx1(a) = x1\r
-        lby1(a) = y1\r
-        lbx2(a) = x2\r
-        lby2(a) = y2\r
-12 :\r
-    NEXT a\r
-    IF kau > 200 THEN kau = kau - 10\r
-    IF tim < 28000 THEN GOTO 10\r
-13 :\r
+    localYVal = 60 - mainY(INT((holdAz + 10) / 20) * 20 + INT((holdAx + 10) / 20))\r
+    IF holdAy > localYVal + 5 THEN holdAy = holdAy - 1\r
+    IF holdAy < localYVal THEN holdAy = holdAy + 1\r
+    IF holdAy > localYVal + 25 THEN holdAy = holdAy - 1\r
+    IF holdAy < localYVal - 20 THEN holdAy = holdAy + 1\r
+\r
+    sinVal = SIN(holdAngle)\r
+    cosVal = COS(holdAngle)\r
+    FOR indexA = 0 TO holdNumber - 5\r
+        tempX = holdX(indexA + 1)\r
+        tempZ = holdZ(indexA + 1)\r
+        mainX(indexA + holdIndex) = tempX * sinVal + tempZ * cosVal + holdAx\r
+        mainY(indexA + holdIndex) = holdY(indexA + 1) - holdAy\r
+        mainZ(indexA + holdIndex) = tempZ * sinVal - tempX * cosVal + holdAz\r
+    NEXT indexA\r
+\r
+    holdRot = holdRot + .5\r
+    sinVal = SIN(holdRot)\r
+    cosVal = COS(holdRot)\r
+    FOR indexA = holdNumber - 4 TO holdNumber - 1\r
+        tempX = holdX(indexA + 1)\r
+        tempZ = holdZ(indexA + 1)\r
+        mainX(indexA + holdIndex) = tempX * sinVal + tempZ * cosVal + holdAx\r
+        mainY(indexA + holdIndex) = holdY(indexA + 1) - holdAy\r
+        mainZ(indexA + holdIndex) = tempZ * sinVal - tempX * cosVal + holdAz\r
+    NEXT indexA\r
+\r
+    timeCounter = timeCounter + 1\r
+\r
+    angleOne = angleOne + SIN(timeCounter / 100) / 20\r
+    angleTwo = SIN(timeCounter / 42) * .3 + 1.15\r
+\r
+    sin1 = SIN(angleOne)\r
+    cos1 = COS(angleOne)\r
+    sin2 = SIN(angleTwo)\r
+    cos2 = COS(angleTwo)\r
+\r
+    ' Project all points to 2D\r
+    FOR indexA = 0 TO totalPoints\r
+        shiftX = mainX(indexA) - moveX\r
+        shiftY = mainY(indexA) - moveY\r
+        shiftZ = mainZ(indexA) - moveZ\r
+\r
+        zIntermediate = shiftZ * sin1 + shiftX * cos1\r
+        xIntermediate = shiftX * sin1 - shiftZ * cos1\r
+\r
+        zProject = zIntermediate * sin2 + shiftY * cos2\r
+        yProject = shiftY * sin2 - zIntermediate * cos2\r
+\r
+        zProject = zProject + distanceScale\r
+        IF zProject < 1 THEN projectedX(indexA) = -1: GOTO skip2D\r
+        xProject = xIntermediate / zProject * 74 * 2\r
+        yProject = yProject / zProject * 65 * 2\r
+\r
+        projectedX(indexA) = xProject + 160\r
+        projectedY(indexA) = yProject + 80\r
+\r
+skip2D:\r
+    NEXT indexA\r
+\r
+    ' Erase old lines and draw new ones\r
+    FOR indexA = 1 TO totalLines\r
+        startIndex = lineStart(indexA)\r
+        endIndex = lineEnd(indexA)\r
+        x1Temp = projectedX(startIndex)\r
+        x2Temp = projectedX(endIndex)\r
+        LINE (lineBufferXOne(indexA), lineBufferYOne(indexA))-(lineBufferXTwo(indexA), lineBufferYTwo(indexA)), 0\r
+        IF (x1Temp = -1) OR (x2Temp = -1) THEN GOTO skipDrawing\r
+        y1Temp = projectedY(startIndex)\r
+        y2Temp = projectedY(endIndex)\r
+        LINE (x1Temp, y1Temp)-(x2Temp, y2Temp), lineColor(indexA)\r
+        lineBufferXOne(indexA) = x1Temp\r
+        lineBufferYOne(indexA) = y1Temp\r
+        lineBufferXTwo(indexA) = x2Temp\r
+        lineBufferYTwo(indexA) = y2Temp\r
+\r
+skipDrawing:\r
+    NEXT indexA\r
+\r
+    IF distanceScale > 200 THEN distanceScale = distanceScale - 10\r
+    IF timeCounter < 28000 THEN GOTO mainLoop\r
+\r
+finalArea:\r
 END SUB\r
 \r
+\r
 '-------------------------------------------------------------------------------\r
 SUB Scene9\r
-' Wrap-up scene that shows a background, draws a box, and prints\r
-' a final "Thank you for attention!" message.\r
-\r
+'\r
+' Final scene: fractal background, a rounded box, and a short "Thank you"\r
+' note to wrap up the presentation.\r
+'\r
     RANDOMIZE 45\r
     MakeBackground\r
 \r
     DrawRoundedBox 30, 50, 290, 80\r
 \r
     SetPalette 32, 64, 32, 250\r
-    y = -8\r
-    PrintText 30, 70 + y, 1, 250, "     Thank you for attention!"\r
+    yOffset = -8\r
+    PrintText 30, 70 + yOffset, 1, 250, "     Thank you for attention!"\r
     WaitForInput\r
 END SUB\r
 \r
-'-------------------------------------------------------------------------------\r
-SUB SetPalette (r, g, b, c)\r
-' Sets a palette entry (c) to the specified (r,g,b) values, each 0..63 range.\r
-\r
-    IF r < 0 THEN r = 0\r
-    IF g < 0 THEN g = 0\r
-    IF b < 0 THEN b = 0\r
-    IF r > 63 THEN r = 63\r
-    IF g > 63 THEN g = 63\r
-    IF b > 63 THEN b = 63\r
-\r
-    OUT &H3C8, c\r
-    OUT &H3C9, r\r
-    OUT &H3C9, g\r
-    OUT &H3C9, b\r
+SUB SetPalette (red, green, blue, colorIndex)\r
+'\r
+' Sets palette entry 'colorIndex' to (red,green,blue).\r
+' Each component 0..63.\r
+'\r
+    IF red < 0 THEN red = 0\r
+    IF green < 0 THEN green = 0\r
+    IF blue < 0 THEN blue = 0\r
+    IF red > 63 THEN red = 63\r
+    IF green > 63 THEN green = 63\r
+    IF blue > 63 THEN blue = 63\r
+\r
+    OUT &H3C8, colorIndex\r
+    OUT &H3C9, red\r
+    OUT &H3C9, green\r
+    OUT &H3C9, blue\r
 END SUB\r
 \r
-'-------------------------------------------------------------------------------\r
-SUB WaitForInput\r
-' Reads exactly one character from the keyboard and stores it in inputKey$.\r
 \r
+SUB WaitForInput\r
+'\r
+' Waits for exactly one keystroke and stores it into inputKey$.\r
+'\r
     inputKey$ = INPUT$(1)\r
 END SUB\r
 \r
+\r
+\r