From b6672a7e152709a7d8c6bbc52a73f859a9fbc14c Mon Sep 17 00:00:00 2001 From: Svjatoslav Agejenko Date: Sun, 27 Oct 2024 16:34:36 +0200 Subject: [PATCH] Using AI to improve code readability --- .../Universe explorer/Universe explorer.bas | 157 ++++++++++++------ 1 file changed, 108 insertions(+), 49 deletions(-) diff --git a/Graphics/3D/Universe explorer/Universe explorer.bas b/Graphics/3D/Universe explorer/Universe explorer.bas index 1c4759f..cac08b3 100755 --- a/Graphics/3D/Universe explorer/Universe explorer.bas +++ b/Graphics/3D/Universe explorer/Universe explorer.bas @@ -2,17 +2,17 @@ ' Universe is made of galaxy clusters. ' Galaxy cluster is made of galaxies. ' Galaxies are made of stars. -' + ' Total amount of stars in the universe is enormous. ' This program implements clever algorithm to dynamically increase ' and decrease level of detail of the universe regions depending ' on where user is in the universe and maintaining reasonable ' quantity of stars to render at any given time. -' + ' By Svjatoslav Agejenko. ' Email: svjatoslav@svjatoslav.eu ' Homepage: http://www.svjatoslav.eu -' + ' Changelog: ' 2003.12, Initial version ' 2024, Improved program readability using AI @@ -47,20 +47,26 @@ DIM SHARED tim DIM SHARED extSEG, extADDR +' User position in the universe DIM SHARED myx, myy, myz +' User velocity in the universe DIM SHARED myxs, myys, myzs +' User pressed mouse buttons DIM SHARED buttL, buttR +' Maximum user movement speed DIM SHARED maxmove +' Zoom level DIM SHARED zoom DIM SHARED rndval(0 TO 10000) DIM SHARED rndp -DIM SHARED px(1 TO 10000) -DIM SHARED py(1 TO 10000) -DIM SHARED pz(1 TO 10000) +' Star positions and colors +DIM SHARED px(1 TO 10000), py(1 TO 10000), pz(1 TO 10000) DIM SHARED pc(1 TO 10000) +' Total number of stars DIM SHARED nump +' User speed multiplier DIM SHARED myspd DIM SHARED tempr(0 TO 10) @@ -69,9 +75,8 @@ DIM SHARED vd DIM SHARED oftcloud(0 TO 3) -DIM SHARED oftGalaX(0 TO 19) -DIM SHARED oftGalaY(0 TO 19) -DIM SHARED oftGalaZ(0 TO 19) +' Galaxy positions +DIM SHARED oftGalaX(0 TO 19), oftGalaY(0 TO 19), oftGalaZ(0 TO 19) DIM SHARED timerTime(0 TO 50, 0 TO 100) DIM SHARED timerValue(0 TO 50, 0 TO 100) @@ -96,6 +101,7 @@ myz = 23 nump = 9999 1 +' Initialize the universe mkworld va = INT(RND * 3) @@ -109,17 +115,27 @@ CASE 2 cz = RND * 500 - 250 END SELECT +' Handle user input and movement control + +' Display the universe disp +' Process timers for scripted movements timerprocess +' Copy screen buffer to main screen PCOPY 0, 1 + +' Clear the screen CLS + +' Loop back to start GOTO 1 SUB control +' Handle mouse input IF getbyte(8) <> 0 THEN putbyte 8, 0 xp = getword(2) @@ -128,18 +144,24 @@ IF getbyte(8) <> 0 THEN putword 4, 0 butt = getword(6) putword 6, 0 + + ' Determine which mouse buttons are pressed buttL = 0 buttR = 0 IF butt = 1 THEN buttL = 1 IF butt = 2 THEN buttR = 1 IF butt = 3 THEN buttL = 1: buttR = 1 + ' Handle right mouse button for up/down movement IF buttR = 1 THEN + ' Handle both buttons pressed for back/front movement IF buttL = 1 THEN myxs = myxs + SIN(an1) * yp / 4 myzs = myzs - COS(an1) * yp / 4 GOTO 3 END IF + + ' Handle right button for up/down movement myys = myys + yp / 4 3 yp = 0 @@ -147,6 +169,7 @@ IF getbyte(8) <> 0 THEN END IF +' Clamp user input to maximum movement speed IF xp < -maxmove THEN xp = -maxmove IF xp > maxmove THEN xp = maxmove an1 = an1 - xp / 150 @@ -155,6 +178,7 @@ IF yp < -maxmove THEN yp = -maxmove IF yp > maxmove THEN yp = maxmove an2 = an2 - yp / 150 +' Handle keyboard input for movement a$ = INKEY$ IF a$ = "a" THEN myxs = myxs - COS(an1): myzs = myzs - SIN(an1) @@ -162,6 +186,7 @@ IF a$ = "d" THEN myxs = myxs + COS(an1): myzs = myzs + SIN(an1) IF a$ = "w" THEN myxs = myxs - SIN(an1): myzs = myzs + COS(an1) IF a$ = "s" THEN myxs = myxs + SIN(an1): myzs = myzs - COS(an1) +' Handle keyboard input for speed multiplier IF a$ = "1" THEN myspd = .1 IF a$ = "2" THEN myspd = 1 IF a$ = "3" THEN myspd = 10 @@ -171,36 +196,41 @@ IF a$ = "6" THEN myspd = 10000 IF a$ = "7" THEN myspd = 100000 IF a$ = "8" THEN myspd = 1000000 +' Handle keyboard input for quitting the program IF a$ = "q" THEN SYSTEM +' Handle keyboard input for recording script IF a$ = " " THEN IF timerStartScript = 0 THEN OPEN "script.dat" FOR OUTPUT AS #1 timerStartScript = TIMER END IF - PRINT #1, TIMER - timerStartScript; + PRINT #1, TIMER - timerStartScript PRINT #1, myx; myy; myz; an1; an2 SOUND 2000, .1 END IF +' Handle keyboard input for playing script IF a$ = "r" THEN IF ScriptRunning = 0 THEN timerinit loadScript "script.dat" ELSE ScriptRunning = 0 - END IF END IF +' Friction to dampen movement speed over time myxs = myxs / 1.1 myys = myys / 1.1 myzs = myzs / 1.1 +' Update user position based on velocity and speed multiplier myx = myx + myxs * myspd myz = myz + myzs * myspd myy = myy + myys * myspd +' Apply scripted movement if running IF ScriptRunning = 1 THEN myx = timerCvalue(1) myy = timerCvalue(2) @@ -213,51 +243,60 @@ END SUB SUB disp +' Calculate sine and cosine for rotation s1 = SIN(an1) c1 = COS(an1) s2 = SIN(an2) c2 = COS(an2) +' Initialize view distance vdn = 100000000 +' Loop through all stars to calculate their positions FOR a = 1 TO nump + ' Calculate star position relative to user x = px(a) - myx y = py(a) - myy z = pz(a) - myz + ' Update view distance if star is closer IF ABS(x) < vdn THEN IF ABS(y) < vdn THEN IF ABS(z) < vdn THEN vdn = SQR(x * x + y * y + z * z) END IF END IF + ' Rotate star position based on user orientation x1 = x * c1 + z * s1 z1 = z * c1 - x * s1 y1 = y * c2 + z1 * s2 z2 = z1 * c2 - y * s2 + ' Draw star if it is within view distance IF z2 > 3 THEN PSET (x1 / z2 * 130 + 160, y1 / z2 * 130 + 100), pc(a) END IF NEXT a +' Update average view distance vd = (vd * 5 + vdn) / 6 END SUB SUB galacloud (rx, ry, rz) +' Generate random cloud position a = INT(RND * 100) - d = (a + 30) * 500 x = d y = 0 z = 0 +' Calculate sine and cosine for rotation a1 = SIN(a * (123.45 - (rx MOD 1235))) * 100 a2 = SIN(a * 324 + (ry MOD 5431)) * 120 @@ -266,18 +305,20 @@ c1 = COS(a1) s2 = SIN(a2) c2 = COS(a2) +' Rotate cloud position based on user orientation x1 = x * c1 + z * s1 z1 = z * c1 - x * s1 y1 = y * c2 + z1 * s2 z2 = z1 * c2 - y * s2 +' Calculate distance from cloud to user fx = x1 + rx fy = y1 + ry fz = z2 + rz - dist = gdist(fx, fy, fz) +' Add cloud to galaxy list if within view distance IF dist < 20000 THEN pl = INT(RND * 20) oftGalaX(pl) = fx @@ -285,6 +326,7 @@ IF dist < 20000 THEN oftGalaZ(pl) = fz mkgalaxy fx, fy, fz ELSE + ' Add cloud to galaxy list if random or view distance is high IF (RND * 100 < 10) OR (vd > 500000) THEN mkgalaxy fx, fy, fz END IF @@ -293,12 +335,15 @@ END IF END SUB FUNCTION gdist (x, y, z) +' Calculate distance from user to given coordinates gdist = SQR((x - myx) ^ 2 + (y - myy) ^ 2 + (z - myz) ^ 2) END FUNCTION FUNCTION getbyte (addr) +' Retrieve byte value at given RAM address getbyte = PEEK(extADDR + addr) + END FUNCTION SUB getCloudXYZ (a, x1, y1, z2) @@ -309,6 +354,7 @@ x = d y = 0 z = 0 +' Calculate sine and cosine for rotation a1 = SIN(a * 123) * 100 a2 = SIN(a * 975) * 120 @@ -317,6 +363,7 @@ c1 = COS(a1) s2 = SIN(a2) c2 = COS(a2) +' Rotate cloud position based on user orientation x1 = x * c1 + z * s1 z1 = z * c1 - x * s1 @@ -326,6 +373,7 @@ z2 = z1 * c2 - y * s2 END SUB FUNCTION getword (addr) +' Retrieve word value at given RAM address a = PEEK(extADDR + addr) b = PEEK(extADDR + addr + 1) @@ -336,13 +384,16 @@ IF LEN(c$) = 0 THEN c$ = "00" c = VAL("&H" + HEX$(b) + c$) getword = c + END FUNCTION SUB loadScript (scriptName$) +' Load script from file and start playback ScriptRunning = 1 rt = 2 OPEN scriptName$ FOR INPUT AS #2 + 5 IF EOF(2) <> 0 THEN GOTO 6 @@ -355,9 +406,11 @@ FOR a = 1 TO 5 NEXT a GOTO 5 + 6 CLOSE #2 +' Reset all timers to -1 FOR a = 1 TO 5 timerAdd a, -1, b NEXT a @@ -366,13 +419,16 @@ END SUB SUB mkgalaxy (lx, ly, lz) +' Skip galaxy generation if position is zero IF (lx = 0) AND (ly = 0) AND (lz = 0) THEN GOTO 4 +' Generate random seed for galaxy rndp = ABS(lx + ly + lz) MOD 9000 n1 = rn * 100 n2 = rn * 100 n3 = rn * 100 +' Calculate sine and cosine for rotation gs1 = SIN(n1) gc1 = COS(n1) gs2 = SIN(n2) @@ -380,19 +436,25 @@ gc2 = COS(n2) gs3 = SIN(n3) gc3 = COS(n3) +' Calculate galaxy size and temperature siz = rn * 50 + 75 pi = 3.14 sbm = INT(rn * 3) + 1 +' Calculate distance from galaxy to user dist = gdist(lx, ly, lz) + +' Determine number of stars based on distance amo = 1 IF dist < 20000 THEN amo = 1 IF dist < 5000 THEN amo = 2 IF dist < 1000 THEN amo = 10 IF dist < 500 THEN amo = 50 +' Generate stars in galaxy FOR a = 1 TO amo + ' Calculate random values for star position b = RND * 10 s = b * b / 30 @@ -406,6 +468,7 @@ FOR a = 1 TO amo z = (COS(b - sba + ane) * s + RND * v1 - v1p) * siz y = (RND * v1 - v1p) * siz + ' Rotate star position based on galaxy orientation x1 = x * gc1 + z * gs1 z1 = z * gc1 - x * gs1 @@ -415,12 +478,14 @@ FOR a = 1 TO amo y2 = y1 * gc3 + x1 * gs3 x2 = x1 * gc3 - y1 * gs3 + ' Add star to universe pla = INT(RND * nump) + 1 px(pla) = x2 + lx py(pla) = y2 + ly pz(pla) = z2 + lz pc(pla) = INT(RND * 15) + 1 + NEXT a 4 @@ -428,74 +493,56 @@ END SUB SUB mkworld +' Generate initial galaxy clusters FOR b = 1 TO 10 a = INT(RND * 100) getCloudXYZ a, x, y, z + + ' Add cloud to galaxy list if within view distance IF gdist(x, y, z) < vd * 3 THEN oftcloud(INT(RND * 4)) = a + + ' Generate galaxy cluster at cloud position galacloud x, y, z NEXT b +' Add additional galaxy clusters if view distance is high IF vd < 4000000 THEN FOR b = 0 TO 3 a = oftcloud(b) getCloudXYZ a, x, y, z + + ' Generate galaxy cluster at cloud position galacloud x, y, z NEXT b END IF +' Add galaxies to universe if view distance is low IF vd < 10000 THEN FOR b = 0 TO 19 x = oftGalaX(b) y = oftGalaY(b) z = oftGalaZ(b) + + ' Generate galaxy at given position mkgalaxy x, y, z NEXT b + ELSE END IF END SUB -SUB mousedemo - -cx = 150 -cy = 100 -maxmove = 50 -100 -frm = frm + 1 - -LOCATE 1, 1 -PRINT cx, cy -PRINT frm - -CIRCLE (cx, cy), 10, 0 -xp = getword(2) -putword 2, 0 -yp = getword(4) -putword 4, 0 - -IF xp < -maxmove THEN xp = -maxmove -IF xp > maxmove THEN xp = maxmove -cx = cx + xp - -IF yp < -maxmove THEN yp = -maxmove -IF yp > maxmove THEN yp = maxmove -cy = cy + yp - -CIRCLE (cx, cy), 10, 10 - -SOUND 0, .05 -GOTO 100 - -END SUB - SUB putbyte (addr, dat) +' Store byte value at given RAM address POKE (extADDR + addr), dat + END SUB SUB putword (addr, dat) +' Store word value at given RAM address b$ = HEX$(dat) 2 @@ -511,6 +558,7 @@ END SUB FUNCTION rn +' Generate random number based on current index rndp = rndp + 1 IF rndp > 10000 THEN rndp = 0 rn = rndval(rndp) @@ -519,11 +567,13 @@ END FUNCTION SUB rndinit +' Initialize random number array FOR a = 0 TO 10000 rndval(a) = RND NEXT a rndp = 0 + END SUB SUB start @@ -532,11 +582,11 @@ PRINT "Universe Explorer" PRINT "by Svjatoslav Agejenko, n0@hot.ee" PRINT "2003.12" PRINT + PRINT "Use mouse to aim." PRINT "Use keys: a, s, d, w to move around," PRINT "1 2 3 4 5 6 7 to change speed multiplier." PRINT "r - to start/stop demo." -PRINT "q - to quit program." PRINT "right mouse button, to move UP <> DOWN." PRINT "both right & left mouse buttons pressed to move BACK <> FRONT." @@ -547,6 +597,7 @@ PRINT "Requires mouse driver, and QBasic extension TSR" PRINT "to be loaded first." PRINT + PRINT "In this program:" PRINT "Several stars, make up galaxy." @@ -554,6 +605,7 @@ PRINT "Several galaxies makes metagalaxy." PRINT "Several metagalaxies makes up universe." PRINT + PRINT "Press Any key To Continue." a$ = INPUT$(1) @@ -569,7 +621,8 @@ END SUB SUB startext -DEF SEG = 0 ' read first from interrupt table +' Read interrupt table to find QBasic extension TSR +DEF SEG = 0 extSEG = PEEK(&H79 * 4 + 3) * 256 extSEG = extSEG + PEEK(&H79 * 4 + 2) @@ -583,6 +636,7 @@ PRINT "relative address is:"; extADDR DEF SEG = extSEG +' Check if QBasic extension TSR is loaded IF getword(0) <> 1983 THEN PRINT "FATAL ERROR: you must load" PRINT "QBasic extension TSR first!" @@ -593,6 +647,7 @@ END SUB SUB timerAdd (element, time, value) +' Add timer event to list FOR a = 0 TO 100 IF (timerTime(element, a) = 0) AND (timerValue(element, a) = 0) THEN GOTO timer3 NEXT a @@ -606,6 +661,7 @@ END SUB SUB timerdisp LOCATE 1, 1 +' Display all active timers FOR a = 0 TO 10 PRINT timerCplace(a), timerCtime(a), timerCvalue(a) NEXT a @@ -613,6 +669,8 @@ NEXT a END SUB SUB timerinit + +' Initialize all timers to zero timerLast = TIMER FOR a = 1 TO 50 @@ -626,6 +684,7 @@ END SUB SUB timerprocess +' Process all active timers timerCurrent = TIMER timerDiff = timerCurrent - timerLast timerLast = timerCurrent @@ -652,6 +711,7 @@ timer2: v2 = timerValue(a, Cplace + 1) t2 = timerTime(a, Cplace + 1) + ' Interpolate between two timer values IF v1 = v2 THEN timerCvalue(a) = v1 ELSE @@ -666,4 +726,3 @@ timer1: NEXT a END SUB - -- 2.20.1