From: Svjatoslav Agejenko Date: Tue, 24 Jun 2025 15:28:24 +0000 (+0300) Subject: Better code readability X-Git-Url: http://www2.svjatoslav.eu/gitweb/?a=commitdiff_plain;h=7d761de14549b732063724acd58e029f8ccb036e;p=qbasicapps.git Better code readability --- diff --git a/2D GFX/Presentations/strobo.bas b/2D GFX/Presentations/strobo.bas index ffcdb33..c79ab5c 100644 --- a/2D GFX/Presentations/strobo.bas +++ b/2D GFX/Presentations/strobo.bas @@ -1,462 +1,512 @@ -' Presentation about how to build stroboscope. -' By Svjatoslav Agejenko. -' Email: svjatoslav@svjatoslav.eu -' Homepage: http://www.svjatoslav.eu -' -' Changelog: -' 2002, Initial version -' 2024, Improved program readability using AI - -DECLARE SUB pag4 () -DECLARE SUB getkey (a$) -DECLARE SUB mo () -DEFINT A-Z -DECLARE SUB dra () -DECLARE SUB get3d () -DECLARE SUB pag3 () -DECLARE SUB pag2 () -DECLARE SUB getfnt () -DECLARE SUB prn (x2%, y%, s%, c%, t$) -DECLARE SUB pag1 () - -DECLARE SUB start () - -DIM SHARED font(0 TO 7, 0 TO 15, 0 TO 207) -DIM SHARED det(1 TO 100) -DIM SHARED px1(1 TO 1000) -DIM SHARED py1(1 TO 1000) -DIM SHARED px2(1 TO 1000) -DIM SHARED py2(1 TO 1000) -DIM SHARED opx1(1 TO 1000) -DIM SHARED opy1(1 TO 1000) -DIM SHARED opx2(1 TO 1000) -DIM SHARED opy2(1 TO 1000) -DIM SHARED linc(1 TO 1000) - -DIM SHARED myx, myy, myz -DIM SHARED myx1, myy1, myz1 -DIM SHARED myx2, myy2, myz2 -DIM SHARED tfra - -DIM SHARED nl - -start - -pag1 -pag2 -pag3 -pag4 -END - -DATA 0,0,5,-2 -DATA 0,0,5,2 -DATA 0, 0, 15, 0 - -DATA 15,-2,15,2 -DATA 25,-2,25,2 -DATA 15,-2,25,-2 -DATA 15,2,25,2 - -DATA 25,0,35,0 -DATA 35,-2,35,2 -DATA 35,-2,40,0 -DATA 35,2,40,0 -DATA 40,-2,40,2 - -DATA 40,0,80,0 -DATA 50,0,50,19 -DATA 48,19,52,19 -DATA 48,21,52,21 -DATA 50,21,50,35 - -DATA 0,35,125,35 -DATA 0,35,5,33 -DATA 0,35,5,37 - -DATA 70,0,70,15 -DATA 70,35,70,20 -DATA 69,16,71,19 -DATA 69,19,71,16 -DATA 67,10,73,10 -DATA 67,25,73,25 -DATA 67,10,67,25 -DATA 73,10,73,25 - -DATA 75,15,75,25 -DATA 75,20,90,20 -DATA 90,20,91,21 -DATA 91,21,90,22 -DATA 90,22,91,23 -DATA 91,23,90,24 -DATA 90,24,91,25 -DATA 91,25,90,26 -DATA 90,26,90,35 - -DATA 93,18,93,28 -DATA 92,18,92,28 - -DATA 95,20,94,21 -DATA 94,21,95,22 -DATA 95,22,94,23 -DATA 94,23,95,24 -DATA 95,24,94,25 -DATA 94,25,95,26 -DATA 95,26,95,35 - -DATA 95, 20, 115, 20 -DATA 115,20,115,15 -DATA 115,7,115,0 -DATA 125,35,125,26 -DATA 123,26,127,26 -DATA 123,24,127,24 -DATA 125,24,125,0 -DATA 125,0,110,0 -DATA 110,-2,110,2 -DATA 100,-2,100,2 -DATA 100,-2,110,-2 -DATA 100,2,110,2 - -DATA 100,0,90,0 -DATA 90,-2,90,2 -DATA 80,-2,80,2 -DATA 80,-2,90,-2 -DATA 80,2,90,2 - -DATA 113,5,117,5 -DATA 113,17,117,17 -DATA 113,5,113,17 -DATA 117,5,117,17 -DATA 115,11,125,11 - -DATA 105,-2,105,-5 -DATA 105,-5,113,-5 -DATA 113,-5,113,0 -DATA 105,-2,104,-4 -DATA 105,-2,106,-4 - -DATA 999,999,999,999 - -SUB dra - -FOR a = 1 TO nl - x1 = px1(a) - myx - y1 = py1(a) - myy - x2 = px2(a) - myx - y2 = py2(a) - myy - - ' Calculate the new coordinates based on the current zoom level - x1 = x1 * 30 / myz + 160 - y1 = y1 * 30 / myz + 100 - x2 = x2 * 30 / myz + 160 - y2 = y2 * 30 / myz + 100 - - ' Draw the line from old coordinates to new coordinates - LINE (opx1(a), opy1(a)) - (opx2(a), opy2(a)), 0 - LINE (x1, y1) - (x2, y2), linc(a) - - ' Update the old coordinates to the new coordinates - opx1(a) = x1 - opy1(a) = y1 - opx2(a) = x2 - opy2(a) = y2 -NEXT a - -END SUB - -SUB get3d - -nl = 0 -5 -READ x1, y1, x2, y2 -IF x1 = 999 THEN GOTO 6 -nl = nl + 1 -px1(nl) = x1 -py1(nl) = y1 -px2(nl) = x2 -py2(nl) = y2 -linc(nl) = 11 -GOTO 5 -6 -'PRINT nl, "of lines loaded" -'a$ = INPUT$(1) -END SUB - -SUB getfnt - -FOR c = 0 TO 15 - OUT &H3C8, c - OUT &H3C9, 0 - OUT &H3C9, 0 - OUT &H3C9, 0 -NEXT c - -FOR a = 0 TO 207 - LOCATE 1, 1 - IF (a > 5) AND (a < 14) THEN GOTO 1 - PRINT CHR$(a) -1 - FOR y = 0 TO 15 - FOR x = 0 TO 7 - font(x, y, a) = POINT(x, y) - NEXT x - NEXT y -NEXT a -END SUB - -SUB getkey (a$) - -FOR a = 1 TO 50 - b$ = INKEY$ -NEXT a - -7 -a$ = INKEY$ -IF a$ = "" THEN GOTO 7 - -FOR a = 1 TO 50 - b$ = INKEY$ -NEXT a - -END SUB - -SUB mo - -myxv = myx2 - myx1 -myyv = myy2 - myy1 -myzv = myz2 - myz1 - -FOR a = 1 TO tfra - myx = myx1 + (myxv * a / tfra) - myy = myy1 + (myyv * a / tfra) - myz = myz1 + (myzv * a / tfra) - dra - SOUND 0, 1 -NEXT a -dra - -END SUB - -SUB pag1 - -SCREEN 13 - -a = 0 -FOR c = 16 TO 31 - OUT &H3C8, c - OUT &H3C9, a * 3 - OUT &H3C9, a * 4.5 - OUT &H3C9, a * 0 - a = a + 1 -NEXT c - -OUT &H3C8, 101 -OUT &H3C9, 63 -OUT &H3C9, 63 -OUT &H3C9, 0 - -OUT &H3C8, 102 -OUT &H3C9, 63 -OUT &H3C9, 10 -OUT &H3C9, 10 - -OUT &H3C8, 103 -OUT &H3C9, 60 -OUT &H3C9, 60 -OUT &H3C9, 0 - -a = 0 -FOR c = 50 TO 65 - OUT &H3C8, c - OUT &H3C9, a * 4.5 - OUT &H3C9, a * 0 - OUT &H3C9, (15 - a) * 4.5 - a = a + 1 -NEXT c - -st$ = " Esitlus teemal:" - -FOR t = 0 TO 400 - IF t < 320 THEN - FOR y = 0 TO 199 - c = POINT(319 - t, y) - IF c < 100 THEN c = c + 34 - PSET (319 - t, y), c - NEXT y - x = 319 - t - IF x / 16 = x \ 16 THEN - s = x / 16 - IF s <= LEN(st$) THEN - a$ = RIGHT$(LEFT$(st$, s), 1) - prn x, 20, 2, 101, a$ - END IF - END IF - END IF - - IF (t < 360) AND (t > 39) THEN - FOR y = 0 TO 13 - c = POINT(359 - t, y) - IF c < 100 THEN c = c - 34 - PSET (359 - t, y), c - NEXT y - FOR y = 55 TO 199 - c = POINT(359 - t, y) - IF c < 100 THEN c = c - 34 - PSET (359 - t, y), c - NEXT y - END IF - - SOUND 0, .2 -NEXT t - -prn 31, 101, 3, 102, "STROBOSKOOP" -prn 29, 99, 3, 102, "STROBOSKOOP" -prn 30, 100, 3, 103, "STROBOSKOOP" - -FOR x = 0 TO 160 - FOR y = 100 TO 150 - c = POINT(x, y) - IF c = 102 THEN c = 103: GOTO 2 - IF c = 103 THEN c = 102: GOTO 2 -2 - PSET (x, y), c - NEXT y - SOUND 0, .1 -NEXT x - -FOR y = 199 TO 120 STEP -1 - FOR x = 0 TO 319 - c = POINT(x, y) - IF c = 102 THEN c = 103: GOTO 3 - IF c = 103 THEN c = 102: GOTO 3 -3 - PSET (x, y), c - NEXT x - SOUND 0, .1 -NEXT y - -prn 49, 179, 1, 0, "autor: Svjatoslav Agejenko" -prn 51, 181, 1, 0, "autor: Svjatoslav Agejenko" -prn 50, 180, 1, 15, "autor: Svjatoslav Agejenko" - -getkey a$ - -DIM buf(1 TO 30000) -FOR a = 1 TO 320 / 5 - GET (0, 0)-(314, 100), buf(1) - PUT (5, 0), buf(1), PSET - LINE (0, 0)-(4, 100), 0, BF - - GET (5, 101)-(319, 199), buf(1) - PUT (0, 101), buf(1), PSET - LINE (315, 101)-(319, 199), 0, BF -NEXT a - -END SUB - -SUB pag2 -SCREEN 13 -SCREEN 12 - -END SUB - -SUB pag3 - -myx1 = 20 -myy1 = 15 -myz1 = 100 -myx2 = 20 -myy2 = 15 -myz2 = 10 -tfra = 20 - -mo - -prn 147, 66, 1, 3, "100 D336B 180k 680k" -prn 180, 120, 1, 3, "50m 450V 1m" -prn 180, 400, 2, 14, "Principal scheematic" - -getkey a$ - -LINE (0, 0)-(639, 390), 0, BF - -myx1 = 20 -myy1 = 15 -myz1 = 10 -myx2 = 80 -myy2 = 5 -myz2 = 4 -tfra = 20 -mo -getkey a$ - -myx1 = 80 -myy1 = 5 -myz1 = 4 -myx2 = 40 -myy2 = 5 -myz2 = 4 -tfra = 20 -mo -getkey a$ - -myx1 = 40 -myy1 = 5 -myz1 = 4 -myx2 = 20 -myy2 = 15 -myz2 = 10 -tfra = 10 -mo -prn 147, 66, 1, 3, "100 D336B 180k 680k" -prn 180, 120, 1, 3, "50m 450V 1m" -getkey a$ - -END SUB - -SUB pag4 -CLS -SCREEN 13 -prn 35, 100, 2, 14, " Thank you" -prn 35, 140, 2, 14, " for attention!" - -DIM buf(1 TO 30000) - -GET (0, 100)-(319, 199), buf(1) -FOR y = 100 TO 50 STEP -1 - PUT (0, y), buf(1), PSET - SOUND 0, .5 -NEXT y - -getkey a$ -SYSTEM -END SUB - -SUB prn (x2%, y%, s%, c%, t$) -x = x2 - -FOR a = 1 TO LEN(t$) - b = ASC(RIGHT$(LEFT$(t$, a), 1)) - - ' Draw each character in the string - FOR y1 = 0 TO 15 - FOR x1 = 0 TO 7 - IF font(x1, y1, b) > 0 THEN - LINE (x1 * s + x, y1 * s + y) - (x1 * s + s - 1 + x, y1 * s + s - 1 + y), c, BF - END IF - NEXT x1 - NEXT y1 - - ' Move to the next character position - x = x + (8 * s) -NEXT a -END SUB - -SUB start -SCREEN 12 -get3d -getfnt - -myx = 30 -myy = 15 -myz = 10 -END SUB +' Presentation about how to build stroboscope. +' By Svjatoslav Agejenko. +' Email: svjatoslav@svjatoslav.eu +' Homepage: http://www.svjatoslav.eu +' +' Changelog: +' 2002, Initial version +' 2024-2025, Improved program readability + +DECLARE SUB InitializePresentation () +DECLARE SUB WaitForKeyPress (keyInput$) +DECLARE SUB MoveModel () +DEFINT A-Z +DECLARE SUB DrawLines () +DECLARE SUB Load3DModel () +DECLARE SUB Animate3DModel () +DECLARE SUB ClearScreen () +DECLARE SUB LoadFontPalette () +DECLARE SUB PrintText (x2%, y%, s%, c%, t$) +DECLARE SUB DisplayClosingPage () + +DECLARE SUB ProgramStart () + +DIM SHARED font(0 TO 7, 0 TO 15, 0 TO 207) +DIM SHARED paletteData(1 TO 100) +DIM SHARED originalX1(1 TO 1000) +DIM SHARED originalY1(1 TO 1000) +DIM SHARED originalX2(1 TO 1000) +DIM SHARED originalY2(1 TO 1000) +DIM SHARED previousX1(1 TO 1000) +DIM SHARED previousY1(1 TO 1000) +DIM SHARED previousX2(1 TO 1000) +DIM SHARED previousY2(1 TO 1000) +DIM SHARED lineColor(1 TO 1000) + +DIM SHARED movementX, movementY, zoomLevel +DIM SHARED startX, startY, startZoom +DIM SHARED endX, endY, endZoom +DIM SHARED totalFrames + +DIM SHARED lineCount + +ProgramStart + +InitializePresentation +ClearScreen +Animate3DModel +DisplayClosingPage +END + +DATA 0,0,5,-2 +DATA 0,0,5,2 +DATA 0, 0, 15, 0 + +DATA 15,-2,15,2 +DATA 25,-2,25,2 +DATA 15,-2,25,-2 +DATA 15,2,25,2 + +DATA 25,0,35,0 +DATA 35,-2,35,2 +DATA 35,-2,40,0 +DATA 35,2,40,0 +DATA 40,-2,40,2 + +DATA 40,0,80,0 +DATA 50,0,50,19 +DATA 48,19,52,19 +DATA 48,21,52,21 +DATA 50,21,50,35 + +DATA 0,35,125,35 +DATA 0,35,5,33 +DATA 0,35,5,37 + +DATA 70,0,70,15 +DATA 70,35,70,20 +DATA 69,16,71,19 +DATA 69,19,71,16 +DATA 67,10,73,10 +DATA 67,25,73,25 +DATA 67,10,67,25 +DATA 73,10,73,25 + +DATA 75,15,75,25 +DATA 75,20,90,20 +DATA 90,20,91,21 +DATA 91,21,90,22 +DATA 90,22,91,23 +DATA 91,23,90,24 +DATA 90,24,91,25 +DATA 91,25,90,26 +DATA 90,26,90,35 + +DATA 93,18,93,28 +DATA 92,18,92,28 + +DATA 95,20,94,21 +DATA 94,21,95,22 +DATA 95,22,94,23 +DATA 94,23,95,24 +DATA 95,24,94,25 +DATA 94,25,95,26 +DATA 95,26,95,35 + +DATA 95, 20, 115, 20 +DATA 115,20,115,15 +DATA 115,7,115,0 +DATA 125,35,125,26 +DATA 123,26,127,26 +DATA 123,24,127,24 +DATA 125,24,125,0 +DATA 125,0,110,0 +DATA 110,-2,110,2 +DATA 100,-2,100,2 +DATA 100,-2,110,-2 +DATA 100,2,110,2 + +DATA 100,0,90,0 +DATA 90,-2,90,2 +DATA 80,-2,80,2 +DATA 80,-2,90,-2 +DATA 80,2,90,2 + +DATA 113,5,117,5 +DATA 113,17,117,17 +DATA 113,5,113,17 +DATA 117,5,117,17 +DATA 115,11,125,11 + +DATA 105,-2,105,-5 +DATA 105,-5,113,-5 +DATA 113,-5,113,0 +DATA 105,-2,104,-4 +DATA 105,-2,106,-4 + +DATA 999,999,999,999 + +SUB Animate3DModel + ' Set up first animation parameters + startX = 20 + startY = 15 + startZoom = 100 + endX = 20 + endY = 15 + endZoom = 10 + totalFrames = 20 + + MoveModel + + ' Print technical information + PrintText 147, 66, 1, 3, "100 D336B 180k 680k" + PrintText 180, 120, 1, 3, "50m 450V 1m" + PrintText 180, 400, 2, 14, "Principal schematic" + + WaitForKeyPress keyInput$ + + ' Clear screen for next animation + LINE (0, 0)-(639, 390), 0, BF + + ' Set up second animation parameters + startX = 20 + startY = 15 + startZoom = 10 + endX = 80 + endY = 5 + endZoom = 4 + totalFrames = 20 + MoveModel + WaitForKeyPress keyInput$ + + ' Set up third animation parameters + startX = 80 + startY = 5 + startZoom = 4 + endX = 40 + endY = 5 + endZoom = 4 + totalFrames = 20 + MoveModel + WaitForKeyPress keyInput$ + + ' Set up fourth animation parameters + startX = 40 + startY = 5 + startZoom = 4 + endX = 20 + endY = 15 + endZoom = 10 + totalFrames = 10 + MoveModel + + ' Redraw technical information + PrintText 147, 66, 1, 3, "100 D336B 180k 680k" + PrintText 180, 120, 1, 3, "50m 450V 1m" + WaitForKeyPress keyInput$ +END SUB + +SUB ClearScreen + ' change screen resolution. This also resets color palette. + SCREEN 13 + SCREEN 12 +END SUB + +SUB DisplayClosingPage + CLS + SCREEN 13 + PrintText 35, 100, 2, 14, " Thank you" + PrintText 35, 140, 2, 14, " for attention!" + + ' Create closing animation effect + DIM buffer(1 TO 30000) + GET (0, 100)-(319, 199), buffer(1) + + ' Move text down with delay + FOR y = 100 TO 50 STEP -1 + PUT (0, y), buffer(1), PSET + SOUND 0, .5 + NEXT y + + WaitForKeyPress keyInput$ + SYSTEM +END SUB + +SUB DrawLines + ' Draw all lines in the schematic with current transformation parameters. + ' First calculate new screen coordinates based on movement and zoom. + ' Then draw lines by erasing previous positions and drawing new ones. + + FOR a = 1 TO lineCount + ' Calculate relative coordinates from original positions + x1 = originalX1(a) - movementX + y1 = originalY1(a) - movementY + x2 = originalX2(a) - movementX + y2 = originalY2(a) - movementY + + ' Apply zoom scaling and centering (320x200 screen) + x1 = x1 * 30 / zoomLevel + 160 + y1 = y1 * 30 / zoomLevel + 100 + x2 = x2 * 30 / zoomLevel + 160 + y2 = y2 * 30 / zoomLevel + 100 + + ' Erase previous line by drawing in black (color 0) + LINE (previousX1(a), previousY1(a))-(previousX2(a), previousY2(a)), 0 + + ' Draw new line with appropriate color + LINE (x1, y1)-(x2, y2), lineColor(a) + + ' Update previous positions for next frame + previousX1(a) = x1 + previousY1(a) = y1 + previousX2(a) = x2 + previousY2(a) = y2 + NEXT a +END SUB + +SUB InitializePresentation + ' Set up screen and create title animation + SCREEN 13 + + ' Configure palette for title animation + a = 0 + FOR c = 16 TO 31 + OUT &H3C8, c + OUT &H3C9, a * 3 + OUT &H3C9, a * 4.5 + OUT &H3C9, a * 0 + a = a + 1 + NEXT c + + ' Set special colors for title effects + OUT &H3C8, 101 + OUT &H3C9, 63 + OUT &H3C9, 63 + OUT &H3C9, 0 + + OUT &H3C8, 102 + OUT &H3C9, 63 + OUT &H3C9, 10 + OUT &H3C9, 10 + + OUT &H3C8, 103 + OUT &H3C9, 60 + OUT &H3C9, 60 + OUT &H3C9, 0 + + ' Configure palette for background text + a = 0 + FOR c = 50 TO 65 + OUT &H3C8, c + OUT &H3C9, a * 4.5 + OUT &H3C9, a * 0 + OUT &H3C9, (15 - a) * 4.5 + a = a + 1 + NEXT c + + ' Create scrolling title animation + titleText$ = " Esitlus teemal:" + + FOR t = 0 TO 400 + ' Scroll title text across screen + IF t < 320 THEN + FOR y = 0 TO 199 + c = POINT(319 - t, y) + IF c < 100 THEN c = c + 34 + PSET (319 - t, y), c + NEXT y + + x = 319 - t + ' Add text to scrolling animation + IF x / 16 = x \ 16 THEN + segment = x / 16 + IF segment <= LEN(titleText$) THEN + char$ = RIGHT$(LEFT$(titleText$, segment), 1) + PrintText x, 20, 2, 101, char$ + END IF + END IF + END IF + + ' Create second animation phase + IF (t < 360) AND (t > 39) THEN + FOR y = 0 TO 13 + c = POINT(359 - t, y) + IF c < 100 THEN c = c - 34 + PSET (359 - t, y), c + NEXT y + + FOR y = 55 TO 199 + c = POINT(359 - t, y) + IF c < 100 THEN c = c - 34 + PSET (359 - t, y), c + NEXT y + END IF + + ' Frame delay using sound command + SOUND 0, .2 + NEXT t + + ' Draw final title text + PrintText 31, 101, 3, 102, "STROBOSKOOP" + PrintText 29, 99, 3, 102, "STROBOSKOOP" + PrintText 30, 100, 3, 103, "STROBOSKOOP" + + ' Create color flipping effect for title + FOR x = 0 TO 160 + FOR y = 100 TO 150 + c = POINT(x, y) + IF c = 102 THEN c = 103: GOTO 2 + IF c = 103 THEN c = 102: GOTO 2 +2 + PSET (x, y), c + NEXT y + SOUND 0, .1 + NEXT x + + ' Continue color flipping effect + FOR y = 199 TO 120 STEP -1 + FOR x = 0 TO 319 + c = POINT(x, y) + IF c = 102 THEN c = 103: GOTO 3 + IF c = 103 THEN c = 102: GOTO 3 +3 + PSET (x, y), c + NEXT x + SOUND 0, .1 + NEXT y + + ' Print author information + PrintText 49, 179, 1, 0, "autor: Svjatoslav Agejenko" + PrintText 51, 181, 1, 0, "autor: Svjatoslav Agejenko" + PrintText 50, 180, 1, 15, "autor: Svjatoslav Agejenko" + + ' Wait for user input before continuing + WaitForKeyPress keyInput$ + + ' Create screen border effect + DIM buffer(1 TO 30000) + FOR a = 1 TO 320 / 5 + ' Capture and move screen sections + GET (0, 0)-(314, 100), buffer(1) + PUT (5, 0), buffer(1), PSET + LINE (0, 0)-(4, 100), 0, BF + + GET (5, 101)-(319, 199), buffer(1) + PUT (0, 101), buffer(1), PSET + LINE (315, 101)-(319, 199), 0, BF + NEXT a +END SUB + +SUB LoadFontPalette + ' Capture pixel data for each character in font array. + ' Make colors invisible for the human while doing so. + + FOR c = 0 TO 15 + OUT &H3C8, c + OUT &H3C9, 0 + OUT &H3C9, 0 + OUT &H3C9, 0 + NEXT c + + ' Load character pixel patterns into font array + FOR a = 0 TO 207 + LOCATE 1, 1 + IF (a > 5) AND (a < 14) THEN GOTO 1 + PRINT CHR$(a) +1 + FOR y = 0 TO 15 + FOR x = 0 TO 7 + font(x, y, a) = POINT(x, y) + NEXT x + NEXT y + NEXT a +END SUB + +SUB LoadSchematic + ' Load 3D model line data from DATA statements + ' Each line has two endpoints (x1,y1)-(x2,y2) and color + + lineCount = 0 +5 + READ x1, y1, x2, y2 + IF x1 = 999 THEN GOTO 6 + lineCount = lineCount + 1 + originalX1(lineCount) = x1 + originalY1(lineCount) = y1 + originalX2(lineCount) = x2 + originalY2(lineCount) = y2 + lineColor(lineCount) = 11 + GOTO 5 +6 +END SUB + +SUB MoveModel + ' Calculate model movement over time frames + ' Interpolate between start and end positions + + movementXVelocity = endX - startX + movementYVelocity = endY - startY + zoomVelocity = endZoom - startZoom + + ' Animate model by gradually changing position and zoom + FOR a = 1 TO totalFrames + movementX = startX + (movementXVelocity * a / totalFrames) + movementY = startY + (movementYVelocity * a / totalFrames) + zoomLevel = startZoom + (zoomVelocity * a / totalFrames) + DrawLines + ' Use sound command for sub-second delay (QBasic workaround) + SOUND 0, 1 + NEXT a + + ' Draw final position + DrawLines +END SUB + +SUB PrintText (x2%, y%, s%, c%, t$) + ' Print text using custom font + ' Parameters: + ' x2% - starting x position + ' y% - starting y position + ' s% - character size multiplier + ' c% - color to use + ' t$ - text string to print + + currentX = x2 + + ' Process each character in the string + FOR a = 1 TO LEN(t$) + charCode = ASC(RIGHT$(LEFT$(t$, a), 1)) + + ' Draw character using font data + FOR y1 = 0 TO 15 + FOR x1 = 0 TO 7 + IF font(x1, y1, charCode) > 0 THEN + ' Draw filled rectangle for each pixel in character + LINE (x1 * s + currentX, y1 * s + y)-(x1 * s + s - 1 + currentX, y1 * s + s - 1 + y), c, BF + END IF + NEXT x1 + NEXT y1 + + ' Move to next character position + currentX = currentX + (8 * s) + NEXT a +END SUB + +SUB ProgramStart + ' Initialize program with appropriate screen mode + SCREEN 12 + LoadSchematic + LoadFontPalette + + ' Set initial model parameters + movementX = 30 + movementY = 15 + zoomLevel = 10 +END SUB + +SUB WaitForKeyPress (keyInput$) + ' Clear keyboard buffer to avoid ghost keys + FOR a = 1 TO 50 + keyInput$ = INKEY$ + NEXT a + +7 + keyInput$ = INKEY$ + IF keyInput$ = "" THEN GOTO 7 + + ' Wait for another key press after initial one + FOR a = 1 TO 50 + keyInput$ = INKEY$ + NEXT a +END SUB + diff --git a/3D GFX/Ray casting engine/raycast.bas b/3D GFX/Ray casting engine/raycast.bas index 67b8a84..7a36760 100755 --- a/3D GFX/Ray casting engine/raycast.bas +++ b/3D GFX/Ray casting engine/raycast.bas @@ -1,8 +1,3 @@ -DECLARE SUB makeland () -DECLARE SUB dispframe () -DECLARE SUB displand () -DECLARE SUB start () -DECLARE SUB setupal () ' Realtime 3D rendering with ray casting engine. ' By Svjatoslav Agejenko. @@ -44,10 +39,10 @@ DIM SHARED tim$, frm, frml frmrate = 10 ' Desired framerate. ' Lower framerate, better quality -start -makeland +InitializeProgram +GenerateLandscape -displand +DisplayTopDownLandscape a$ = INPUT$(1) 1 LOCATE 1, 35 @@ -154,10 +149,10 @@ END IF myz = zmyz myy = zmyy myx = zmyx -dispframe +DisplayFrame GOTO 1 -SUB dispframe +SUB DisplayFrame l = 0 zst = -.0031 * ste @@ -169,7 +164,7 @@ NEXT z END SUB -SUB displand +SUB DisplayTopDownLandscape ' Draw the landscape from a top-down perspective FOR z = 0 TO 180 @@ -226,7 +221,7 @@ getcol = INT(r / 43) * 36 + INT(g / 43) * 6 + INT(b / 43) END FUNCTION DEFINT A-Y -SUB makeland +SUB GenerateLandscape ' Create a square landscape square 0, 0, 180, 180, 15, 0 @@ -292,7 +287,7 @@ NEXT za END SUB -SUB setupal +SUB SetupPalette ' Initialize the color palette c = 0 FOR r = 0 TO 5 @@ -320,13 +315,13 @@ NEXT y END SUB -SUB start +SUB InitializeProgram ' Set the graphics mode SCREEN 13 PRINT "please wait..." ' Initialize the color palette -setupal +SetupPalette ' Initialize player position and orientation zmyan = 4.14 @@ -418,4 +413,3 @@ NEXT a% LINE (xl%, yo% - 1)-(xl% + istem%, 0), 0, BF END SUB - diff --git a/3D GFX/Realtime anaglyph/anaglyph.BAS b/3D GFX/Realtime anaglyph/anaglyph.BAS index c150f79..5e4a987 100755 --- a/3D GFX/Realtime anaglyph/anaglyph.BAS +++ b/3D GFX/Realtime anaglyph/anaglyph.BAS @@ -5,7 +5,7 @@ ' Changelog: ' 2004.07, Initial version -' 2024.10, Improved program readability using AI +' 2024 - 2025, Improved program readability ' Controls: ' arrow keys - move around @@ -14,404 +14,409 @@ ' + - fly down ' q, w - change horizontal distance between left and right view - - -DECLARE SUB ling (x1%, y1%, x2%, y2%) - - -DECLARE SUB mkkoll () -DECLARE SUB putkol () -DECLARE SUB rend () -DECLARE SUB env () -DECLARE SUB start () -DIM SHARED npo, nlo, np, nl -DIM SHARED px(1 TO 1000) -DIM SHARED py(1 TO 1000) -DIM SHARED pz(1 TO 1000) - -DIM SHARED rpx(1 TO 1000) -DIM SHARED rpx2(1 TO 1000) -DIM SHARED rpy(1 TO 1000) - -DIM SHARED orpx(1 TO 1000) -DIM SHARED orpx2(1 TO 1000) -DIM SHARED orpy(1 TO 1000) -DIM SHARED onp -DIM SHARED lin1(1 TO 1000) -DIM SHARED lin2(1 TO 1000) -DIM SHARED linc(1 TO 1000) -DIM SHARED olin1(1 TO 1000) -DIM SHARED olin2(1 TO 1000) -DIM SHARED onl -DIM SHARED myx, myy, myz -DIM SHARED myxs, myys, myzs -DIM SHARED an1, an2 -DIM SHARED an1s, an2s -DIM SHARED kolx(1 TO 10) -DIM SHARED koly(1 TO 10) -DIM SHARED kolz(1 TO 10) -DIM SHARED kolxs(1 TO 10) -DIM SHARED kolys(1 TO 10) -DIM SHARED kolzs(1 TO 10) -DIM SHARED kolm -DIM SHARED difp - -DIM SHARED spee - -spee = 4 +DECLARE SUB DrawLine (x1%, y1%, x2%, y2%) +DECLARE SUB CreateCube () +DECLARE SUB PlaceCubes () +DECLARE SUB RenderScene () +DECLARE SUB InitializeEnvironment () +DECLARE SUB InitializeProgram () + +DIM SHARED originalPointCount, originalLineCount, currentPointCount, currentLineCount +DIM SHARED pointX(1 TO 1000) +DIM SHARED pointY(1 TO 1000) +DIM SHARED pointZ(1 TO 1000) + +DIM SHARED projectedX(1 TO 1000) +DIM SHARED projectedXRight(1 TO 1000) +DIM SHARED projectedY(1 TO 1000) + +DIM SHARED originalProjectedX(1 TO 1000) +DIM SHARED originalProjectedXRight(1 TO 1000) +DIM SHARED originalProjectedY(1 TO 1000) +DIM SHARED originalProjectedPointCount +DIM SHARED lineStart(1 TO 1000) +DIM SHARED lineEnd(1 TO 1000) +DIM SHARED lineColor(1 TO 1000) +DIM SHARED originalLineStart(1 TO 1000) +DIM SHARED originalLineEnd(1 TO 1000) +DIM SHARED originalProjectedLineCount + +DIM SHARED cameraX, cameraY, cameraZ +DIM SHARED cameraXSpeed, cameraYSpeed, cameraZSpeed +DIM SHARED rotationAngle1, rotationAngle2 +DIM SHARED rotationAngle1Speed, rotationAngle2Speed +DIM SHARED cubeX(1 TO 10) +DIM SHARED cubeY(1 TO 10) +DIM SHARED cubeZ(1 TO 10) +DIM SHARED cubeXSpeed(1 TO 10) +DIM SHARED cubeYSpeed(1 TO 10) +DIM SHARED cubeZSpeed(1 TO 10) +DIM SHARED cubeCount +DIM SHARED horizontalViewDistance + +DIM SHARED movementSpeed + +movementSpeed = 4 'ON ERROR GOTO 2 -start -env -putkol -difp = -.1 +InitializeProgram +InitializeEnvironment +PlaceCubes +horizontalViewDistance = -.1 1 PCOPY 0, 1 CLS -np = npo -nl = nlo +currentPointCount = originalPointCount +currentLineCount = originalLineCount -mkkoll -rend +CreateCube +RenderScene -myx = myx + myxs -myy = myy + myys -myz = myz + myzs -an1 = an1 + an1s -an2 = an2 + an2s +cameraX = cameraX + cameraXSpeed +cameraY = cameraY + cameraYSpeed +cameraZ = cameraZ + cameraZSpeed +rotationAngle1 = rotationAngle1 + rotationAngle1Speed +rotationAngle2 = rotationAngle2 + rotationAngle2Speed -a$ = INKEY$ -IF a$ <> "" THEN - IF a$ = CHR$(0) + "H" THEN +inputKey$ = INKEY$ +IF inputKey$ <> "" THEN + IF inputKey$ = CHR$(0) + "H" THEN ' Move forward - myzs = myzs - SIN(an1) / 100 - myxs = myxs - COS(an1) / 100 + cameraZSpeed = cameraZSpeed - SIN(rotationAngle1) / 100 + cameraXSpeed = cameraXSpeed - COS(rotationAngle1) / 100 END IF - IF a$ = CHR$(0) + "P" THEN + IF inputKey$ = CHR$(0) + "P" THEN ' Move backward - myzs = myzs + SIN(an1) / 100 - myxs = myxs + COS(an1) / 100 + cameraZSpeed = cameraZSpeed + SIN(rotationAngle1) / 100 + cameraXSpeed = cameraXSpeed + COS(rotationAngle1) / 100 END IF - IF a$ = CHR$(0) + "M" THEN + IF inputKey$ = CHR$(0) + "M" THEN ' Strafe left - myzs = myzs + COS(an1) / 100 - myxs = myxs - SIN(an1) / 100 + cameraZSpeed = cameraZSpeed + COS(rotationAngle1) / 100 + cameraXSpeed = cameraXSpeed - SIN(rotationAngle1) / 100 END IF - IF a$ = CHR$(0) + "K" THEN + IF inputKey$ = CHR$(0) + "K" THEN ' Strafe right - myzs = myzs - COS(an1) / 100 - myxs = myxs + SIN(an1) / 100 + cameraZSpeed = cameraZSpeed - COS(rotationAngle1) / 100 + cameraXSpeed = cameraXSpeed + SIN(rotationAngle1) / 100 END IF - IF a$ = "6" THEN an1s = an1s - .01 - IF a$ = "4" THEN an1s = an1s + .01 - IF a$ = "8" THEN an2s = an2s - .01 - IF a$ = "2" THEN an2s = an2s + .01 - IF a$ = "+" THEN myys = myys - .01 - IF a$ = "-" THEN myys = myys + .01 - IF a$ = "q" THEN difp = difp - .01 - IF a$ = "w" THEN difp = difp + .01 - IF a$ = " " THEN + IF inputKey$ = "6" THEN rotationAngle1Speed = rotationAngle1Speed - .01 + IF inputKey$ = "4" THEN rotationAngle1Speed = rotationAngle1Speed + .01 + IF inputKey$ = "8" THEN rotationAngle2Speed = rotationAngle2Speed - .01 + IF inputKey$ = "2" THEN rotationAngle2Speed = rotationAngle2Speed + .01 + IF inputKey$ = "+" THEN cameraYSpeed = cameraYSpeed - .01 + IF inputKey$ = "-" THEN cameraYSpeed = cameraYSpeed + .01 + IF inputKey$ = "q" THEN horizontalViewDistance = horizontalViewDistance - .01 + IF inputKey$ = "w" THEN horizontalViewDistance = horizontalViewDistance + .01 + IF inputKey$ = " " THEN ' Slow down movements - myxs = myxs / 2 - myys = myys / 2 - myzs = myzs / 2 + cameraXSpeed = cameraXSpeed / 2 + cameraYSpeed = cameraYSpeed / 2 + cameraZSpeed = cameraZSpeed / 2 - an1s = an1s / 2 - an2s = an2s / 2 + rotationAngle1Speed = rotationAngle1Speed / 2 + rotationAngle2Speed = rotationAngle2Speed / 2 END IF - IF a$ = CHR$(27) THEN SYSTEM + IF inputKey$ = CHR$(27) THEN SYSTEM END IF GOTO 1 2 END RESUME -SUB env +SUB InitializeEnvironment ' This subroutine initializes the environment by creating points and lines. -FOR z = -5 TO 5 - FOR x = -5 TO 5 - np = np + 1 - px(np) = x - py(np) = SIN(SQR(x * x + z * z) / 2) - pz(np) = z - IF x > -5 THEN - nl = nl + 1 - lin1(nl) = np - lin2(nl) = np - 1 - linc(nl) = 3 +FOR worldZ = -5 TO 5 + FOR worldX = -5 TO 5 + currentPointCount = currentPointCount + 1 + pointX(currentPointCount) = worldX + pointY(currentPointCount) = SIN(SQR(worldX * worldX + worldZ * worldZ) / 2) + pointZ(currentPointCount) = worldZ + IF worldX > -5 THEN + currentLineCount = currentLineCount + 1 + lineStart(currentLineCount) = currentPointCount + lineEnd(currentLineCount) = currentPointCount - 1 + lineColor(currentLineCount) = 3 END IF - IF z > -5 THEN - nl = nl + 1 - lin1(nl) = np - lin2(nl) = np - 11 - linc(nl) = 3 + IF worldZ > -5 THEN + currentLineCount = currentLineCount + 1 + lineStart(currentLineCount) = currentPointCount + lineEnd(currentLineCount) = currentPointCount - 11 + lineColor(currentLineCount) = 3 END IF - NEXT x -NEXT z + NEXT worldX +NEXT worldZ -npo = np -nlo = nl +originalPointCount = currentPointCount +originalLineCount = currentLineCount END SUB -SUB env1 +SUB InitializeEnvironment1 ' This subroutine initializes the environment with a simple setup. -np = 1 -px(np) = -2 -py(np) = 0 -pz(np) = 0 +currentPointCount = 1 +pointX(currentPointCount) = -2 +pointY(currentPointCount) = 0 +pointZ(currentPointCount) = 0 -np = np + 1 -px(np) = 2 -py(np) = 0 -pz(np) = 0 +currentPointCount = currentPointCount + 1 +pointX(currentPointCount) = 2 +pointY(currentPointCount) = 0 +pointZ(currentPointCount) = 0 -nl = 1 -lin1(nl) = 1 -lin2(nl) = 2 -linc(nl) = 14 +currentLineCount = 1 +lineStart(currentLineCount) = 1 +lineEnd(currentLineCount) = 2 +lineColor(currentLineCount) = 14 END SUB -SUB ling (x1%, y1%, x2%, y2%) - -' This subroutine draws a line between two points. -s = ABS(x1% - x2%) -s2 = ABS(y1% - y2%) -IF s2 > s THEN s = s2 -IF s < 2 THEN GOTO 101 -xp = x2% - x1% -yp = y2% - y1% - -FOR a% = 1 TO s - rx% = xp * a% / s + x1% - ry% = yp * a% / s + y1% - c% = POINT(rx%, ry%) - IF c% = 0 THEN PSET (rx%, ry%), 2 - IF c% = 1 THEN PSET (rx%, ry%), 3 -NEXT a% +SUB DrawLine (x1%, y1%, x2%, y2%) + +' This subroutine draws a line between two points using a custom algorithm. +' It calculates intermediate points and sets pixels with appropriate colors. +' The color is inverted if the point is already set to avoid overwriting. + +lineLength = ABS(x1% - x2%) +lineLength2 = ABS(y1% - y2%) +IF lineLength2 > lineLength THEN lineLength = lineLength2 +IF lineLength < 2 THEN GOTO 101 + +xDelta = x2% - x1% +yDelta = y2% - y1% + +FOR stp% = 1 TO lineLength + x = xDelta * stp% / lineLength + x1% + y = yDelta * stp% / lineLength + y1% + currentColor = POINT(x, y) + IF currentColor = 0 THEN PSET (x, y), 2 + IF currentColor = 1 THEN PSET (x, y), 3 +NEXT stp% 101 END SUB -SUB linr (x1, y1, x2, y2) -' This subroutine draws a line using the LINE statement. +SUB DrawLineRight (x1, y1, x2, y2) +' This subroutine draws a line using the LINE statement for the right eye view. LINE (x1, y1)-(x2, y2), 1 END SUB -SUB mkkoll +SUB CreateCube -' This subroutine updates the positions of the objects in the environment. -FOR a = 1 TO kolm - x = kolx(a) - y = koly(a) - z = kolz(a) +' This subroutine updates the positions of the cubes and adds their edges to the environment. +FOR cubeIndex = 1 TO cubeCount + worldX = cubeX(cubeIndex) + worldY = cubeY(cubeIndex) + worldZ = cubeZ(cubeIndex) - xs = kolxs(a) - ys = kolys(a) - zs = kolzs(a) + velocityX = cubeXSpeed(cubeIndex) + velocityY = cubeYSpeed(cubeIndex) + velocityZ = cubeZSpeed(cubeIndex) - ' Apply gravity - ys = ys - .01 + ' Apply gravity to the cube's vertical movement + velocityY = velocityY - .01 - ' Calculate new positions - x = x + xs / spee - y = y + ys / spee - z = z + zs / spee + ' Calculate new positions based on velocity and speed + worldX = worldX + velocityX / movementSpeed + worldY = worldY + velocityY / movementSpeed + worldZ = worldZ + velocityZ / movementSpeed ' Bounce from boundaries - IF x > 5 THEN xs = -.1 - IF z > 5 THEN zs = -.1 - IF x < -5 THEN xs = .1 - IF z < -5 THEN zs = .1 - IF y < .5 THEN ys = RND * .2 + .1 - - ' Add new lines to the environment - nl = nl + 1 - lin1(nl) = np + 1 - lin2(nl) = np + 2 - linc(nl) = 14 - - nl = nl + 1 - lin1(nl) = np + 3 - lin2(nl) = np + 2 - linc(nl) = 14 - - nl = nl + 1 - lin1(nl) = np + 3 - lin2(nl) = np + 4 - linc(nl) = 14 - - nl = nl + 1 - lin1(nl) = np + 1 - lin2(nl) = np + 4 - linc(nl) = 14 - - nl = nl + 1 - lin1(nl) = np + 1 - lin2(nl) = np + 5 - linc(nl) = 14 - - nl = nl + 1 - lin1(nl) = np + 2 - lin2(nl) = np + 6 - linc(nl) = 14 - - nl = nl + 1 - lin1(nl) = np + 3 - lin2(nl) = np + 7 - linc(nl) = 14 - - nl = nl + 1 - lin1(nl) = np + 4 - lin2(nl) = np + 8 - linc(nl) = 14 - - nl = nl + 1 - lin1(nl) = np + 5 - lin2(nl) = np + 6 - linc(nl) = 14 - - nl = nl + 1 - lin1(nl) = np + 7 - lin2(nl) = np + 6 - linc(nl) = 14 - - nl = nl + 1 - lin1(nl) = np + 7 - lin2(nl) = np + 8 - linc(nl) = 14 - - nl = nl + 1 - lin1(nl) = np + 5 - lin2(nl) = np + 8 - linc(nl) = 14 - - ' Update the positions of the points in the environment - np = np + 1 - px(np) = x - .5 - py(np) = y - .5 - pz(np) = z - .5 - - np = np + 1 - px(np) = x + .5 - py(np) = y - .5 - pz(np) = z - .5 - - np = np + 1 - px(np) = x + .5 - py(np) = y + .5 - pz(np) = z - .5 - - np = np + 1 - px(np) = x - .5 - py(np) = y + .5 - pz(np) = z - .5 - - np = np + 1 - px(np) = x - .5 - py(np) = y - .5 - pz(np) = z + .5 - - np = np + 1 - px(np) = x + .5 - py(np) = y - .5 - pz(np) = z + .5 - - np = np + 1 - px(np) = x + .5 - py(np) = y + .5 - pz(np) = z + .5 - - np = np + 1 - px(np) = x - .5 - py(np) = y + .5 - pz(np) = z + .5 - - ' Update the positions and velocities of the objects - kolx(a) = x - koly(a) = y - kolz(a) = z - kolxs(a) = xs - kolys(a) = ys - kolzs(a) = zs -NEXT a + IF worldX > 5 THEN velocityX = -.1 + IF worldZ > 5 THEN velocityZ = -.1 + IF worldX < -5 THEN velocityX = .1 + IF worldZ < -5 THEN velocityZ = .1 + IF worldY < .5 THEN velocityY = RND * .2 + .1 + + ' Add cube edges to the environment + currentLineCount = currentLineCount + 1 + lineStart(currentLineCount) = currentPointCount + 1 + lineEnd(currentLineCount) = currentPointCount + 2 + lineColor(currentLineCount) = 14 + + currentLineCount = currentLineCount + 1 + lineStart(currentLineCount) = currentPointCount + 3 + lineEnd(currentLineCount) = currentPointCount + 2 + lineColor(currentLineCount) = 14 + + currentLineCount = currentLineCount + 1 + lineStart(currentLineCount) = currentPointCount + 3 + lineEnd(currentLineCount) = currentPointCount + 4 + lineColor(currentLineCount) = 14 + + currentLineCount = currentLineCount + 1 + lineStart(currentLineCount) = currentPointCount + 1 + lineEnd(currentLineCount) = currentPointCount + 4 + lineColor(currentLineCount) = 14 + + currentLineCount = currentLineCount + 1 + lineStart(currentLineCount) = currentPointCount + 1 + lineEnd(currentLineCount) = currentPointCount + 5 + lineColor(currentLineCount) = 14 + + currentLineCount = currentLineCount + 1 + lineStart(currentLineCount) = currentPointCount + 2 + lineEnd(currentLineCount) = currentPointCount + 6 + lineColor(currentLineCount) = 14 + + currentLineCount = currentLineCount + 1 + lineStart(currentLineCount) = currentPointCount + 3 + lineEnd(currentLineCount) = currentPointCount + 7 + lineColor(currentLineCount) = 14 + + currentLineCount = currentLineCount + 1 + lineStart(currentLineCount) = currentPointCount + 4 + lineEnd(currentLineCount) = currentPointCount + 8 + lineColor(currentLineCount) = 14 + + currentLineCount = currentLineCount + 1 + lineStart(currentLineCount) = currentPointCount + 5 + lineEnd(currentLineCount) = currentPointCount + 6 + lineColor(currentLineCount) = 14 + + currentLineCount = currentLineCount + 1 + lineStart(currentLineCount) = currentPointCount + 7 + lineEnd(currentLineCount) = currentPointCount + 6 + lineColor(currentLineCount) = 14 + + currentLineCount = currentLineCount + 1 + lineStart(currentLineCount) = currentPointCount + 7 + lineEnd(currentLineCount) = currentPointCount + 8 + lineColor(currentLineCount) = 14 + + currentLineCount = currentLineCount + 1 + lineStart(currentLineCount) = currentPointCount + 5 + lineEnd(currentLineCount) = currentPointCount + 8 + lineColor(currentLineCount) = 14 + + ' Add cube vertices to the environment + currentPointCount = currentPointCount + 1 + pointX(currentPointCount) = worldX - .5 + pointY(currentPointCount) = worldY - .5 + pointZ(currentPointCount) = worldZ - .5 + + currentPointCount = currentPointCount + 1 + pointX(currentPointCount) = worldX + .5 + pointY(currentPointCount) = worldY - .5 + pointZ(currentPointCount) = worldZ - .5 + + currentPointCount = currentPointCount + 1 + pointX(currentPointCount) = worldX + .5 + pointY(currentPointCount) = worldY + .5 + pointZ(currentPointCount) = worldZ - .5 + + currentPointCount = currentPointCount + 1 + pointX(currentPointCount) = worldX - .5 + pointY(currentPointCount) = worldY + .5 + pointZ(currentPointCount) = worldZ - .5 + + currentPointCount = currentPointCount + 1 + pointX(currentPointCount) = worldX - .5 + pointY(currentPointCount) = worldY - .5 + pointZ(currentPointCount) = worldZ + .5 + + currentPointCount = currentPointCount + 1 + pointX(currentPointCount) = worldX + .5 + pointY(currentPointCount) = worldY - .5 + pointZ(currentPointCount) = worldZ + .5 + + currentPointCount = currentPointCount + 1 + pointX(currentPointCount) = worldX + .5 + pointY(currentPointCount) = worldY + .5 + pointZ(currentPointCount) = worldZ + .5 + + currentPointCount = currentPointCount + 1 + pointX(currentPointCount) = worldX - .5 + pointY(currentPointCount) = worldY + .5 + pointZ(currentPointCount) = worldZ + .5 + + ' Update cube positions and velocities + cubeX(cubeIndex) = worldX + cubeY(cubeIndex) = worldY + cubeZ(cubeIndex) = worldZ + cubeXSpeed(cubeIndex) = velocityX + cubeYSpeed(cubeIndex) = velocityY + cubeZSpeed(cubeIndex) = velocityZ +NEXT cubeIndex END SUB -SUB putkol +SUB PlaceCubes -' This subroutine initializes the objects in the environment. -s = 1 -FOR a = 1 TO kolm - kolx(a) = RND * 10 - 5 - koly(a) = 2 - kolz(a) = RND * 10 - 5 - kolxs(a) = (RND * .5 - .25) / s - kolys(a) = (RND * .5 + .1) / s - kolzs(a) = (RND * .5 - .25) / s -NEXT a +' This subroutine initializes the positions and velocities of the cubes. +scaleFactor = 1 +FOR cubeIndex = 1 TO cubeCount + cubeX(cubeIndex) = RND * 10 - 5 + cubeY(cubeIndex) = 2 + cubeZ(cubeIndex) = RND * 10 - 5 + cubeXSpeed(cubeIndex) = (RND * .5 - .25) / scaleFactor + cubeYSpeed(cubeIndex) = (RND * .5 + .1) / scaleFactor + cubeZSpeed(cubeIndex) = (RND * .5 - .25) / scaleFactor +NEXT cubeIndex END SUB -SUB rend -'C3& = Cosine&(Deg3): S3& = Sine&(Deg3) - -s1 = SIN(an1) -c1 = COS(an1) -s2 = SIN(an2) -c2 = COS(an2) - -' This subroutine renders the environment by projecting points onto a 2D plane. -FOR a = 1 TO np - x = px(a) + myx - y = py(a) - myy - z = pz(a) + myz - - ' Apply rotation to the point - x1 = x * s1 - z * c1 - z1 = x * c1 + z * s1 - y1 = y * s2 - z1 * c2 - z2 = y * c2 + z1 * s2 - - ' Project the point onto a 2D plane - IF z2 < .1 THEN - rpx(a) = -1 +SUB RenderScene +' This subroutine renders the environment by projecting 3D points onto a 2D plane. +' It applies rotation and perspective projection to create the anaglyph effect. + +sinAngle1 = SIN(rotationAngle1) +cosAngle1 = COS(rotationAngle1) +sinAngle2 = SIN(rotationAngle2) +cosAngle2 = COS(rotationAngle2) + +' Project each 3D point to 2D screen coordinates +FOR pointIndex = 1 TO currentPointCount + worldX = pointX(pointIndex) + cameraX + worldY = pointY(pointIndex) - cameraY + worldZ = pointZ(pointIndex) + cameraZ + + ' First rotation around Y-axis (horizontal rotation) + rotatedX = worldX * sinAngle1 - worldZ * cosAngle1 + rotatedZ = worldX * cosAngle1 + worldZ * sinAngle1 + + ' Second rotation around X-axis (vertical rotation) + rotatedY = worldY * sinAngle2 - rotatedZ * cosAngle2 + depth = worldY * cosAngle2 + rotatedZ * sinAngle2 + + ' Apply perspective projection if point is in view + IF depth < .1 THEN + projectedX(pointIndex) = -1 ELSE - rpx(a) = 160 + ((x1 + difp) / z2 * 200) - rpx2(a) = 160 + ((x1 - difp) / z2 * 200) - rpy(a) = 100 - (y1 / z2 * 200) + projectedX(pointIndex) = 160 + ((rotatedX + horizontalViewDistance) / depth * 200) + projectedXRight(pointIndex) = 160 + ((rotatedX - horizontalViewDistance) / depth * 200) + projectedY(pointIndex) = 100 - (rotatedY / depth * 200) END IF -NEXT a - -' Draw lines between projected points -FOR a = 1 TO nl - l1 = lin1(a) - l2 = lin2(a) - IF rpx(l1) = -1 OR rpx(l2) = -1 THEN - ' Do nothing if the point is out of view +NEXT pointIndex + +' Draw lines between projected points for left eye view +FOR lineIndex = 1 TO currentLineCount + startPoint = lineStart(lineIndex) + endPoint = lineEnd(lineIndex) + IF projectedX(startPoint) = -1 OR projectedX(endPoint) = -1 THEN + ' Skip drawing if either point is out of view ELSE - LINE (rpx(l1), rpy(l1))-(rpx(l2), rpy(l2)), 1 + LINE (projectedX(startPoint), projectedY(startPoint))-(projectedX(endPoint), projectedY(endPoint)), 1 END IF -NEXT - -' Draw lines between projected points for the right eye -FOR a = 1 TO nl - l1 = lin1(a) - l2 = lin2(a) - IF rpx(l1) = -1 OR rpx(l2) = -1 THEN - ' Do nothing if the point is out of view +NEXT lineIndex + +' Draw lines between projected points for right eye view +FOR lineIndex = 1 TO currentLineCount + startPoint = lineStart(lineIndex) + endPoint = lineEnd(lineIndex) + IF projectedX(startPoint) = -1 OR projectedX(endPoint) = -1 THEN + ' Skip drawing if either point is out of view ELSE - ling INT(rpx2(l1)), INT(rpy(l1)), INT(rpx2(l2)), INT(rpy(l2)) + DrawLine INT(projectedXRight(startPoint)), INT(projectedY(startPoint)), INT(projectedXRight(endPoint)), INT(projectedY(endPoint)) END IF -NEXT +NEXT lineIndex END SUB -SUB start +SUB InitializeProgram SCREEN 7, , , 1 OUT &H3C8, 0 @@ -434,25 +439,25 @@ OUT &H3C9, 0 OUT &H3C9, 0 OUT &H3C9, 0 -npo = 0 -nlo = 0 -np = npo -nl = nlo -kolm = 9 +originalPointCount = 0 +originalLineCount = 0 +currentPointCount = originalPointCount +currentLineCount = originalLineCount +cubeCount = 9 -myx = 0 -myy = 4 -myz = 7 -an1 = 3.14 / 2 -an2 = an1 + .6 +cameraX = 0 +cameraY = 4 +cameraZ = 7 +rotationAngle1 = 3.14 / 2 +rotationAngle2 = rotationAngle1 + .6 -FOR a = 1 TO 1000 - linc(a) = 4 -NEXT a +FOR pointIndex = 1 TO 1000 + lineColor(pointIndex) = 4 +NEXT pointIndex -FOR a = 1 TO 1000 - olin1(a) = 1 - olin2(a) = 1 -NEXT a +FOR lineIndex = 1 TO 1000 + originalLineStart(lineIndex) = 1 + originalLineEnd(lineIndex) = 1 +NEXT lineIndex -END SUB \ No newline at end of file +END SUB