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 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 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
 \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
 \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
 \r
 Initialize\r
 \r
@@ -50,204 +58,222 @@ Scene7
 Scene8\r
 Scene9\r
 \r
 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
 \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
 \r
-    x2 = tx2\r
-    y2 = ty2\r
-    z2 = tz2\r
+    xLocalTwo = txTwo\r
+    yLocalTwo = tyTwo\r
+    zLocalTwo = tzTwo\r
 \r
 \r
-    x3 = tx3\r
-    y3 = ty3\r
-    z3 = tz3\r
+    xLocalThree = txThree\r
+    yLocalThree = tyThree\r
+    zLocalThree = tzThree\r
 \r
     ' First rotation\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
 \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
 \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
 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
 \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
         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
         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
             END IF\r
-        NEXT x\r
-    NEXT y\r
+        NEXT xLoop\r
+    NEXT yLoop\r
 END SUB\r
 \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 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
     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
         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
         END IF\r
-    NEXT y\r
+    NEXT yFill\r
     RETURN\r
 \r
     RETURN\r
 \r
-:\r
+polygonDone:\r
 END SUB\r
 \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
 \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
     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
         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
         ELSE\r
-            N = pi + ATN((x1 - x2) / (y2 - y1))\r
+            angleOutput = globalPi + ATN((xOne - xTwo) / (yTwo - yOne))\r
         END IF\r
     ELSE\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
         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
         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
         END IF\r
     END IF\r
 \r
-:\r
+skipLogic:\r
 END SUB\r
 \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
 \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
     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
     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
 \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
     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
         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
 END SUB\r
 \r
+\r
 DEFINT A-Z\r
 DEFINT A-Z\r
-'-------------------------------------------------------------------------------\r
 SUB MakeBackground\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
     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
     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
 END SUB\r
 \r
+\r
 DEFSNG A-Z\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
     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
 END SUB\r
 \r
+\r
 '-------------------------------------------------------------------------------\r
 SUB Scene1\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
     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
 \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
     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
         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
     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
     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
 \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
 \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
     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
     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
 \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
         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
         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
     RETURN\r
 \r
-:\r
-    angl1 = an1\r
-    angl2 = an2\r
+endScene:\r
+    globalAngleOne = angleOne\r
+    globalAngleTwo = angleTwo\r
 END SUB\r
 \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
 \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
     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
 \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
 \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
 \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
 \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
     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
 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
 \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
         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
         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
 \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
         SOUND 0, 2\r
-    NEXT y\r
+    NEXT rowY\r
 \r
     RANDOMIZE 1\r
 \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
 \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
     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
         SOUND 0, 1\r
-    NEXT a\r
+    NEXT loopIndex\r
 \r
     WaitForInput\r
 END SUB\r
 \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
 \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
     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
     WaitForInput\r
 END SUB\r
 \r
+\r
 '-------------------------------------------------------------------------------\r
 SUB Scene5\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
     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
 \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
     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
 \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
     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
         SOUND 0, .5\r
-    NEXT a\r
+    NEXT outerIndex\r
 END SUB\r
 \r
 END SUB\r
 \r
-'-------------------------------------------------------------------------------\r
+\r
 SUB Scene8\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
     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
             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
             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
 \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
     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
 \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
     CLOSE #1\r
-    np = np + a\r
-    hlknu = a\r
+    totalPoints = totalPoints + indexA\r
+    holdNumber = indexA\r
 \r
     RANDOMIZE 10\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
     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
     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
 END SUB\r
 \r
+\r
 '-------------------------------------------------------------------------------\r
 SUB Scene9\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
     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
     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
 END SUB\r
 \r
-'-------------------------------------------------------------------------------\r
-SUB WaitForInput\r
-' Reads exactly one character from the keyboard and stores it in inputKey$.\r
 \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
     inputKey$ = INPUT$(1)\r
 END SUB\r
 \r
+\r
+\r