' Program to render animation inspired by opening scene from The Matrix movie.
'
' This program is free software: released under Creative Commons Zero (CC0) license
' by Svjatoslav Agejenko.
' Email: svjatoslav@svjatoslav.eu
' Homepage: http://www.svjatoslav.eu

' Changelog:
' 2002, Initial version
' 2024, Improved program readability

DEFINT A-Z
DECLARE SUB DisplayMatrix ()
DIM SHARED matrixArray(1 TO 20)
DIM SHARED lineLength
DIM SHARED displayMessage$
RANDOMIZE 2

CLS
COLOR 10, 0
displayMessage$ = ""
frameCounter = 0
iterationCount = 0
DisplayMatrix

1 :   ' Label for looping

' Creates high-pitch pulsing sound by toggling it on and off while iterating
soundFrequency = 0
IF iterationCount >= 3 THEN soundFrequency = 10000: iterationCount = 0
SOUND soundFrequency, .2
iterationCount = iterationCount + 1

frameCounter = frameCounter + 1
IF frameCounter > 100 THEN DisplayMatrix: frameCounter = 0

displayLine$ = ""
lineIndex = 1
FOR column = 1 TO 80
    lineIndex = lineIndex + 1
    randomCharacter$ = CHR$(INT(RND * 9) + 48)
    IF lineIndex > lineLength THEN lineIndex = 1: randomCharacter$ = " "
    displayLine$ = displayLine$ + randomCharacter$
NEXT column
LOCATE 25, 1
PRINT displayLine$
IF INKEY$ <> "" THEN COLOR 7, 0: CLS : SYSTEM
GOTO 1

SUB DisplayMatrix
    ' Set the viewport to print from line 1 to line 25
    VIEW PRINT 1 TO 25

    ' Display a message based on the code decoding progress
    SELECT CASE lineLength
        CASE 13
            displayMessage$ = "Are you sure the line is clear?"
        CASE 6
            displayMessage$ = "       Then I'll go ..."
    END SELECT

    ' Clear and print the message at position (1, 30)
    LOCATE 1, 30
    PRINT "                                 "
    LOCATE 1, 30
    PRINT displayMessage$

    randomValue = INT(RND * 9) + 1
    FOR pass = 1 TO 3
        FOR value = randomValue TO 10
            IF matrixArray(value) = -1 THEN
                ' Assign a random value between 1 and 8 to the array element
                matrixArray(value) = INT(RND * 8) + 1
                lineLength = lineLength - 1
                GOTO 2
            END IF
        NEXT value
        ' Reset randomValue if no valid position is found
        randomValue = 1
    NEXT pass

    ' Reset the length and initialize the array
    lineLength = 13
    FOR index = 1 TO 20
        matrixArray(index) = -1
    NEXT index

    CLS
    IF displayMessage$ <> "" THEN SYSTEM

2 :   ' Label for continuing after GOTO
    FOR index = 1 TO 20
        LOCATE 1, index
        ' Display a space if the array element is -1, otherwise display the value
        IF matrixArray(index) = -1 THEN displayChar$ = " " ELSE displayChar$ = STR$(matrixArray(index))
        displayChar$ = RIGHT$(displayChar$, 1)
        PRINT displayChar$
    NEXT index

    ' Set the viewport to print from line 2 to line 25
    VIEW PRINT 2 TO 25
END SUB

