#+begin_export html
<div class="flex-center">
<video width="300" controls loop autoplay>
- <source src="Bump mapping.webm" type="video/webm">
+ <source src="Bump mapping - Screencast 0.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
artistic representation of how simple rules can generate intricate and
beautiful structures, reminiscent of natural tree growth patterns.
-#+begin_export html
-<div class="flex-center">
- <video width="1000" controls loop autoplay>
- <source src="Tree.webm" type="video/webm">
- Your browser does not support the video tag.
- </video>
-</div>
-#+end_export
+#+attr_html: :class responsive-img
+[[file:Tree - Screenshot 0.png]]
[[file:Tree.bas][Source code]]
#+begin_export html
<div class="flex-center">
<video width="1000" controls loop autoplay>
- <source src="2D rotation.webm" type="video/webm">
+ <source src="2D rotation - Screencast 0.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
#+begin_export html
<div class="flex-center">
<video width="1000" controls loop autoplay>
- <source src="text mode animation.webm" type="video/webm">
+ <source src="text mode animation - Screencast 0.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
#+begin_export html
<div class="flex-center">
<video width="1000" controls loop autoplay>
- <source src="Snowfall.webm" type="video/webm">
+ <source src="Snowfall - Screencast 0.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
#+begin_export html
<div class="flex-center">
<video width="1000" controls loop autoplay>
- <source src="Screensaver.webm" type="video/webm">
+ <source src="Screensaver - Screencast 0.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
#+begin_export html
<div class="flex-center">
<video width="1000" controls loop autoplay>
- <source src="Screensaver, flying hand fans.webm" type="video/webm">
+ <source src="Screensaver, flying hand fans - Screencast 0.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
#+begin_export html
<div class="flex-center">
<video width="1000" controls loop autoplay>
- <source src="Polygon.webm" type="video/webm">
+ <source src="Polygon - Screencast 0.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
#+begin_export html
<div class="flex-center">
<video width="1000" controls loop autoplay>
- <source src="Polygon textured.webm" type="video/webm">
+ <source src="Polygon textured - Screencast 0.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
#+begin_export html
<div class="flex-center">
<video width="1000" controls loop autoplay>
- <source src="Yin and yang.webm" type="video/webm">
+ <source src="Yin and yang - Screencast 0.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
#+begin_export html
<div class="flex-center">
<video width="1000" controls loop autoplay>
- <source src="Orbiting particles.webm" type="video/webm">
+ <source src="Orbiting particles - Screencast 0.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
#+begin_export html
<div class="flex-center">
<video width="1000" controls loop autoplay>
- <source src="DNA.webm" type="video/webm">
+ <source src="DNA - Screencast 0.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
#+begin_export html
<div class="flex-center">
<video width="1000" controls loop autoplay>
- <source src="matrix.webm" type="video/webm">
+ <source src="matrix - Screencast 0.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
[[file:matrix.bas][Source code]]
+* Matrix - the opening scene
+
+Animation inspired by the opening scene from "The Matrix" movie: the
+phone-call trace sequence. A line of digits is gradually decoded at
+the top of the screen while random numbers cascade along the bottom,
+accompanied by a high-pitch pulsing sound. Messages such as "Are you
+sure the line is clear?" appear as the decoding progresses.
+
+#+begin_export html
+<div class="flex-center">
+ <video width="1000" controls loop autoplay>
+ <source src="matrix2 - Screencast 0.mp4" type="video/mp4">
+ Your browser does not support the video tag.
+ </video>
+</div>
+#+end_export
+
+[[file:matrix2.bas][Source code]]
+
* Hacker
Ultra-realistic hacker screen simulator! Behold da glory of a true
#+begin_export html
<div class="flex-center">
<video width="1000" controls loop autoplay>
- <source src="hacker.webm" type="video/webm">
+ <source src="hacker - Screencast 0.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
#+end_export
[[file:hacker.bas][Source code]]
+
+* Circular patterns
+
+This QBasic program generates a fractal animation that looks like
+atoms. While it uses a simple formula to calculate the color of every
+pixel, sin((x² + y²) / 10) * 6 + 23, the visual effect is quite
+impressive. The formula was accidentally discovered. Frame by frame
+the zoom factor decreases, creating a continuous zooming effect into
+the circular pattern.
+
+#+begin_export html
+<div class="flex-center">
+ <video width="1000" controls loop autoplay>
+ <source src="circular patterns - Screencast 0.mp4" type="video/mp4">
+ Your browser does not support the video tag.
+ </video>
+</div>
+#+end_export
+
+[[file:circular patterns.bas][Source code]]
+
+* Sun, earth and moon
+
+This QBasic program projects an animation of the sun, earth and
+moon. The moon orbits the earth, and the earth orbits the sun. The
+program uses clever trickery to determine the drawing order of the
+objects based on their y-coordinates, instead of doing proper
+Z-sorting.
+
+#+begin_export html
+<div class="flex-center">
+ <video width="1000" controls loop autoplay>
+ <source src="sun&eart - Screencast 0.mp4" type="video/mp4">
+ Your browser does not support the video tag.
+ </video>
+</div>
+#+end_export
+
+[[file:sun&eart.bas][Source code]]
+
+* Maze
+
+This QBasic program renders an animated 3D maze. The maze grows one
+segment at a time along a randomly picked axis, each segment colored
+randomly, while the viewer position and rotation angles are driven by
+sine functions. Points are rotated around two axes and projected with
+perspective division, and only line segments in front of the viewer
+are drawn.
+
+#+begin_export html
+<div class="flex-center">
+ <video width="1000" controls loop autoplay>
+ <source src="maze - Screencast 0.mp4" type="video/mp4">
+ Your browser does not support the video tag.
+ </video>
+</div>
+#+end_export
+
+[[file:maze.BAS][Source code]]
+
+* Fancy text mode animations
+
+This QBasic program renders fancy looking text mode animations in an
+80x50 text screen. Various effects are overlaid on top of each other
+while the program scrolls its own source code in the background: a
+wrapping pattern of asterisks driven by sine functions, a wobbling
+circle filled with random characters and colors, and vertical and
+horizontal lines bouncing between the screen edges.
+
+#+begin_export html
+<div class="flex-center">
+ <video width="1000" controls loop autoplay>
+ <source src="mkcircle - Screencast 0.mp4" type="video/mp4">
+ Your browser does not support the video tag.
+ </video>
+</div>
+#+end_export
+
+[[file:mkcircle.bas][Source code]]
--- /dev/null
+' Program to render fancy looking text mode animations.\r
+' Various effects are overlaid on top of each other\r
+' while program scrolls it's own source code in the background.\r
+'\r
+' This program is free software: released under Creative Commons Zero (CC0) license\r
+' by Svjatoslav Agejenko.\r
+' Email: svjatoslav@svjatoslav.eu\r
+' Homepage: http://www.svjatoslav.eu\r
+'\r
+' Changelog:\r
+' 2003.10, Initial version\r
+' 2024, Improved program readability\r
+\r
+DECLARE SUB displayScreen ()\r
+DECLARE SUB drawCircle ()\r
+DECLARE SUB drawLines ()\r
+DECLARE SUB fillBuffer ()\r
+DECLARE SUB updateDisplay ()\r
+DIM SHARED pi\r
+DIM SHARED angle\r
+DIM SHARED frameCounter\r
+DIM SHARED buffer2(1 TO 50, 1 TO 80) AS STRING * 1\r
+DIM SHARED buffer(1 TO 50, 1 TO 80) AS STRING * 1\r
+DIM SHARED colors(1 TO 50, 1 TO 80) AS INTEGER\r
+\r
+DIM SHARED verticalLinePosition, horizontalLinePosition\r
+DIM SHARED verticalLineSpeed, horizontalLineSpeed\r
+\r
+WIDTH 80, 50\r
+VIEW PRINT 1 TO 50\r
+pi = 3.14159\r
+OPEN "mkcircle.bas" FOR INPUT AS #1\r
+\r
+CLS\r
+\r
+horizontalLinePosition = 20\r
+horizontalLineSpeed = 1\r
+verticalLinePosition = 20\r
+verticalLineSpeed = 1\r
+\r
+1\r
+frameCounter = frameCounter + 1\r
+SOUND 0, 1\r
+displayScreen\r
+fillBuffer\r
+drawLines\r
+drawCircle\r
+updateDisplay\r
+IF INKEY$ <> "" THEN GOTO 2\r
+GOTO 1\r
+2\r
+CLOSE #1\r
+SYSTEM\r
+\r
+SUB updateDisplay\r
+' This subroutine updates the display with the contents of the buffer\r
+COLOR 7, 0\r
+LOCATE 1, 1\r
+FOR y = 1 TO 50\r
+ FOR x = 1 TO 80\r
+ COLOR colors(y, x)\r
+ PRINT buffer(y, x);\r
+ ' Swap the contents of buffer and buffer2\r
+ buffer(y, x) = buffer2(y, x)\r
+ colors(y, x) = 4\r
+ NEXT x\r
+NEXT y\r
+\r
+END SUB\r
+\r
+SUB fillBuffer\r
+' This subroutine fills the buffer with a pattern\r
+COLOR 4, 0\r
+sizeMultiplier = SIN(frameCounter / 7) + 1.1\r
+\r
+angle = angle + SIN(frameCounter / 30) / 10\r
+radiusXPosition = 50 - SIN(angle + pi / 4) * 12 * 20 * sizeMultiplier\r
+radiusYPosition = 50 - COS(angle + pi / 4) * 12 * 20 * sizeMultiplier\r
+\r
+stepXPosition = SIN(angle) * 6 * sizeMultiplier\r
+stepYPosition = COS(angle) * 6 * sizeMultiplier\r
+radiusStepXPosition = SIN(angle + pi / 2) * 6 * sizeMultiplier\r
+radiusStepYPosition = COS(angle + pi / 2) * 6 * sizeMultiplier\r
+\r
+FOR y = 1 TO 50\r
+ radiusXPosition = radiusXPosition + radiusStepXPosition\r
+ radiusYPosition = radiusYPosition + radiusStepYPosition\r
+\r
+4\r
+IF radiusXPosition > 100 THEN radiusXPosition = radiusXPosition - 100: GOTO 4\r
+IF radiusXPosition < 0 THEN radiusXPosition = radiusXPosition + 100: GOTO 4\r
+IF radiusYPosition > 100 THEN radiusYPosition = radiusYPosition - 100: GOTO 4\r
+IF radiusYPosition < 0 THEN radiusYPosition = radiusYPosition + 100: GOTO 4\r
+\r
+currentXPosition = radiusXPosition\r
+currentYPosition = radiusYPosition\r
+\r
+FOR x = 1 TO 80\r
+ characterCode = 0\r
+ currentXPosition = currentXPosition + stepXPosition\r
+ currentYPosition = currentYPosition + stepYPosition\r
+\r
+3\r
+IF currentXPosition > 100 THEN currentXPosition = currentXPosition - 100: GOTO 3\r
+IF currentXPosition < 0 THEN currentXPosition = currentXPosition + 100: GOTO 3\r
+IF currentYPosition > 100 THEN currentYPosition = currentYPosition - 100: GOTO 3\r
+IF currentYPosition < 0 THEN currentYPosition = currentYPosition + 100: GOTO 3\r
+\r
+IF currentXPosition < 12 OR currentYPosition < 12 THEN buffer(y, x) = "*": colors(y, x) = 9\r
+NEXT x\r
+NEXT y\r
+END SUB\r
+\r
+SUB drawCircle\r
+' This subroutine draws a circle on the screen\r
+circleSize = (SIN(frameCounter / 10) + 1.01) * 30\r
+circleYPosition = SIN(frameCounter / 12) * 30 + 40\r
+circleXPosition = COS(frameCounter / 17) * 15 + 25\r
+\r
+FOR y = 1 TO 50\r
+ xPositionOffset = SIN(y / 5 + frameCounter / 30) * circleSize / 10\r
+\r
+IF (y >= circleYPosition - circleSize) AND (y <= circleYPosition + circleSize) THEN\r
+\r
+halfHeight1 = SQR((y - (circleYPosition - circleSize)) * ((circleYPosition + circleSize) - y))\r
+IF (y >= circleYPosition - circleSize / 2) AND (y <= circleYPosition + circleSize / 2) THEN halfHeight2 = SQR((y - (circleYPosition - circleSize / 2)) * ((circleYPosition + circleSize / 2) - y)) ELSE halfHeight2 = 0\r
+\r
+startXPosition = circleXPosition - halfHeight1 + xPositionOffset\r
+IF startXPosition < 1 THEN startXPosition = 1\r
+endXPosition = circleXPosition - halfHeight2 + xPositionOffset\r
+IF endXPosition > 80 THEN endXPosition = 80\r
+\r
+FOR x = startXPosition TO endXPosition\r
+ buffer(y, x) = CHR$(RND * 40 + 48)\r
+ colors(y, x) = RND * 15\r
+NEXT x\r
+\r
+startXPosition = circleXPosition + halfHeight2 + xPositionOffset\r
+IF startXPosition < 1 THEN startXPosition = 1\r
+endXPosition = circleXPosition + halfHeight1 + xPositionOffset\r
+IF endXPosition > 80 THEN endXPosition = 80\r
+\r
+FOR x = startXPosition TO endXPosition\r
+ buffer(y, x) = CHR$(RND * 200 + 32)\r
+ colors(y, x) = RND * 15\r
+NEXT x\r
+\r
+END IF\r
+\r
+NEXT y\r
+\r
+END SUB\r
+\r
+SUB drawLines\r
+' This subroutine draws vertical and horizontal lines on the screen\r
+verticalLinePosition = verticalLinePosition + verticalLineSpeed\r
+IF verticalLinePosition > 49 THEN verticalLineSpeed = -1\r
+IF verticalLinePosition < 2 THEN verticalLineSpeed = 1\r
+\r
+horizontalLinePosition = horizontalLinePosition + horizontalLineSpeed\r
+IF horizontalLinePosition > 79 THEN horizontalLineSpeed = -1\r
+IF horizontalLinePosition < 2 THEN horizontalLineSpeed = 1\r
+\r
+FOR x = 1 TO 80\r
+ IF buffer(verticalLinePosition, x) = "*" THEN characterCode = 31 ELSE characterCode = 10\r
+ buffer(verticalLinePosition, x) = "#"\r
+ colors(verticalLinePosition, x) = characterCode\r
+NEXT x\r
+\r
+FOR y = 1 TO 50\r
+ IF buffer(y, horizontalLinePosition) = "*" THEN characterCode = 31 ELSE characterCode = 10\r
+ buffer(y, horizontalLinePosition) = "#"\r
+ colors(y, horizontalLinePosition) = characterCode\r
+NEXT y\r
+END SUB\r
+\r
+SUB displayScreen\r
+' This subroutine displays the text from a file on the screen\r
+IF EOF(1) <> 0 THEN\r
+ CLOSE 1\r
+ OPEN "mkcircle.bas" FOR INPUT AS #1\r
+END IF\r
+\r
+LINE INPUT #1, lineText$\r
+\r
+FOR y = 1 TO 49\r
+FOR x = 1 TO 80\r
+ buffer2(y, x) = buffer2(y + 1, x)\r
+NEXT x\r
+NEXT y\r
+\r
+FOR x = 1 TO 80\r
+ buffer2(50, x) = " "\r
+NEXT x\r
+\r
+IF LEN(lineText$) > 80 THEN lineText$ = LEFT$(lineText$, 80)\r
+FOR b = 1 TO LEN(lineText$)\r
+ character$ = RIGHT$(LEFT$(lineText$, b), 1)\r
+ buffer2(50, b) = character$\r
+NEXT b\r
+\r
+END SUB\r