Author Topic: Psychedelic Star Swirl  (Read 3805 times)

0 Members and 1 Guest are viewing this topic.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Psychedelic Star Swirl
« on: March 04, 2018, 08:30:45 pm »
One Year Anniversary Edition:
Code: QB64: [Select]
  1. _TITLE "Psychedelic Star Swirl bplus 2018-03-04"
  2. ' translated from
  3. ' Psychedelic Star Swirl.bas SmallBASIC 0.12.8 [B+=MGA] 2017-03-03
  4. ' Spiral Pearl Swirl 4 SB.bas  SmallBASIC 0.12.8 [B+=MGA] 2017-03-01
  5. ' from Spiral Pearl Swirl.bas for FreeBASIC [B+=MGA] 2017-02-28
  6. ' from SdlBasic 3d version 2017-02-28
  7. ' inspired by spiral Bang
  8. CONST xmax = 1280
  9. CONST ymax = 760
  10. SCREEN _NEWIMAGE(xmax, ymax, 32)
  11.  
  12. DIM SHARED r, g, b, clr
  13. 'whatever screen size your device here is middle
  14. cx = xmax / 2: cy = ymax / 2: r = RND: g = RND: b = RND: k$ = " "
  15.     size = 1
  16.     radius = .06
  17.     angle = sangle
  18.     CLS
  19.     WHILE radius < 800
  20.         x = COS(angle) * radius
  21.         y = SIN(angle) * radius
  22.         r2 = (x ^ 2 + y ^ 2) ^ .5
  23.         size = 4 * r2 ^ .25
  24.         FOR r = size TO 1 STEP -4
  25.             'cc = 160 + 95 * radius/400 - r/size*120
  26.             chColor
  27.             star cx + x, cy + y, r / 3, r * 1.6, 5, RND * 360
  28.         NEXT
  29.         angle = angle - .4
  30.         radius = radius + 1
  31.     WEND
  32.     _DISPLAY ' update screen with new image
  33.     _LIMIT 5 '<<<<<<<<<<<<<<<<<<<<<<<<<< adjust to higher speeds if you dare
  34.     sangle = sangle + _PI(1 / 18)
  35.  
  36. SUB star (x, y, rInner, rOuter, nPoints, angleOffset)
  37.     ' x, y are same as for circle,
  38.     ' rInner is center circle radius
  39.     ' rOuter is the outer most point of star
  40.     ' nPoints is the number of points,
  41.     ' angleOffset = angle offset IN DEGREES, it will be converted to radians in sub
  42.     ' this is to allow us to spin the polygon of n sides
  43.     pAngle = RAD(360 / nPoints): radAngleOffset = RAD(angleOffset)
  44.     x1 = x + rInner * COS(radAngleOffset)
  45.     y1 = y + rInner * SIN(radAngleOffset)
  46.     FOR i = 0 TO nPoints - 1
  47.         x2 = x + rOuter * COS(i * pAngle + radAngleOffset + .5 * pAngle)
  48.         y2 = y + rOuter * SIN(i * pAngle + radAngleOffset + .5 * pAngle)
  49.         x3 = x + rInner * COS((i + 1) * pAngle + radAngleOffset)
  50.         y3 = y + rInner * SIN((i + 1) * pAngle + radAngleOffset)
  51.         LINE (x1, y1)-(x2, y2)
  52.         LINE (x2, y2)-(x3, y3)
  53.         x1 = x3: y1 = y3
  54.     NEXT
  55.  
  56. SUB chColor ()
  57.     clr = clr + 1
  58.     COLOR _RGB32(127 + 127 * SIN(r * clr), 127 + 127 * SIN(g * clr), 127 + 127 * SIN(b * clr))
  59.     IF clr > 40000 THEN r = RND: g = RND: b = RND: clr = 0
  60. FUNCTION RAD (dA)
  61.     RAD = _PI(dA / 180)
  62.  
  63.  


Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
Re: Psychedelic Star Swirl
« Reply #1 on: March 05, 2018, 04:20:11 am »
This looks pretty good! :D
if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories
OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials

FellippeHeitor

  • Guest
Re: Psychedelic Star Swirl
« Reply #2 on: March 05, 2018, 09:08:22 am »
Crazy stars, bplus!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Psychedelic Star Swirl
« Reply #3 on: March 05, 2018, 09:20:09 am »
So how do your eyes feel after you've seen a dozen or so color patterns?

FellippeHeitor

  • Guest
Re: Psychedelic Star Swirl
« Reply #4 on: March 05, 2018, 10:07:35 am »
I don't like the slow frame rate so I increased it but then the stars were too fast. Maybe if you had more frames in between you could speed frame rate and make it smoother. The overall effect is great anyway.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Psychedelic Star Swirl
« Reply #5 on: March 05, 2018, 10:14:22 am »
More orderly stars, smoother transitions faster color pattern changes:

Code: QB64: [Select]
  1. _TITLE "Psychedelic Star Swirl bplus 2018-03-05 mod 04"
  2. ' translated from
  3. ' Psychedelic Star Swirl.bas SmallBASIC 0.12.8 [B+=MGA] 2017-03-03
  4. ' Spiral Pearl Swirl 4 SB.bas  SmallBASIC 0.12.8 [B+=MGA] 2017-03-01
  5. ' from Spiral Pearl Swirl.bas for FreeBASIC [B+=MGA] 2017-02-28
  6. ' from SdlBasic 3d version 2017-02-28
  7. ' inspired by spiral Bang
  8. CONST xmax = 1280
  9. CONST ymax = 760
  10. SCREEN _NEWIMAGE(xmax, ymax, 32)
  11.  
  12. DIM SHARED r, g, b, clr
  13. 'whatever screen size your device here is middle
  14. cx = xmax / 2: cy = ymax / 2: r = RND: g = RND: b = RND: k$ = " "
  15.     size = 1
  16.     radius = .06
  17.     angle = sangle
  18.     CLS
  19.     WHILE radius < 800
  20.         x = COS(angle) * radius
  21.         y = SIN(angle) * radius
  22.         r2 = (x ^ 2 + y ^ 2) ^ .5
  23.         size = 4 * r2 ^ .25
  24.         FOR r = size TO 1 STEP -7
  25.             'cc = 160 + 95 * radius/400 - r/size*120
  26.             chColor
  27.             star cx + x, cy + y, r / 3, r * 1.6, 5, angle
  28.         NEXT
  29.         angle = angle - .4
  30.         radius = radius + 1
  31.     WEND
  32.     _DISPLAY ' update screen with new image
  33.     _LIMIT 20 '<<<<<<<<<<<<<<<<<<<<<<<<<< adjust to higher speeds if you dare
  34.     sangle = sangle + _PI(1 / 360)
  35.  
  36. SUB star (x, y, rInner, rOuter, nPoints, angleOffset)
  37.     ' x, y are same as for circle,
  38.     ' rInner is center circle radius
  39.     ' rOuter is the outer most point of star
  40.     ' nPoints is the number of points,
  41.     ' angleOffset = angle offset IN DEGREES, it will be converted to radians in sub
  42.     ' this is to allow us to spin the polygon of n sides
  43.     pAngle = RAD(360 / nPoints): radAngleOffset = RAD(angleOffset)
  44.     x1 = x + rInner * COS(radAngleOffset)
  45.     y1 = y + rInner * SIN(radAngleOffset)
  46.     FOR i = 0 TO nPoints - 1
  47.         x2 = x + rOuter * COS(i * pAngle + radAngleOffset + .5 * pAngle)
  48.         y2 = y + rOuter * SIN(i * pAngle + radAngleOffset + .5 * pAngle)
  49.         x3 = x + rInner * COS((i + 1) * pAngle + radAngleOffset)
  50.         y3 = y + rInner * SIN((i + 1) * pAngle + radAngleOffset)
  51.         LINE (x1, y1)-(x2, y2)
  52.         LINE (x2, y2)-(x3, y3)
  53.         x1 = x3: y1 = y3
  54.     NEXT
  55.  
  56. SUB chColor ()
  57.     clr = clr + 1
  58.     COLOR _RGB32(127 + 127 * SIN(r * clr), 127 + 127 * SIN(g * clr), 127 + 127 * SIN(b * clr))
  59.     IF clr > 40000 THEN r = RND: g = RND: b = RND: clr = 0
  60. FUNCTION RAD (dA)
  61.     RAD = _PI(dA / 180)
  62.  
  63.  

OMG too early in morning for this!!! bplus getting seasick
« Last Edit: March 05, 2018, 10:21:23 am by bplus »

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
Re: Psychedelic Star Swirl
« Reply #6 on: March 05, 2018, 12:20:03 pm »
The effect was totally lost on me. I'll go into it in more depth later, but right now I have to go outside and cluck like a chicken.

Well, maybe not hypnotic, but when I coded the program, the IDE was tilting! No kidding, it took my eyes about 30-seconds to re-adjust. You should market this to law enforcement for DUI marijuana detection. I figure anyone who is stoned would fall flat on his face when the program closed. Eitehr that, or deny that anything was moving while the program was running. Either way, lock 'em up!

Pete :D

PS That's a lot of bang for such little buck (code).
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline codeguy

  • Forum Regular
  • Posts: 174
Re: Psychedelic Star Swirl
« Reply #7 on: March 05, 2018, 07:17:46 pm »
No OpenGL here. Just old-fashioned number crunching. Only things i did were to eliminate CLS and comment call to findcentroid(), and set the fps limit to 128. It will go higher depending on your computing horsepower. Eliminated unused SUBS because code and comments would not fit.

Code: QB64: [Select]
  1. DEFINT A-Z
  2. CONST MaxPolys = 191
  3. CONST asteroid = 0
  4. CONST laserbomb = 1
  5. CONST ismyship = 2
  6. DIM SHARED CenterScreenX, CenterScreenY
  7.  
  8. '*************** Zom-B's famous (at least on [abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]) screen mode selector!
  9. DIM SHARED maxscreenx, maxscreeny, maxscreenz
  10. WIDTH , 36
  11. maxscreenx = _DESKTOPWIDTH
  12. maxscreeny = _DESKTOPHEIGHT
  13. ncolors = 32
  14. SCREEN _NEWIMAGE(maxscreenx, maxscreeny, ncolors)
  15. CenterScreenX = _WIDTH / 2
  16. CenterScreenY = _HEIGHT / 2
  17. _TITLE "Rotating Polys Using Gradient Triangle And Lines From Center of screen to object centroid * rendered in real-time no get or put. press mouse button or space bar for cool effect, esc to exit"
  18.  
  19. DIM SHARED minX%(0 TO _HEIGHT - 1)
  20. DIM SHARED maxX%(0 TO _HEIGHT - 1)
  21. DIM SHARED minR!(0 TO _HEIGHT - 1)
  22. DIM SHARED maxR!(0 TO _HEIGHT - 1)
  23. DIM SHARED minG!(0 TO _HEIGHT - 1)
  24. DIM SHARED maxG!(0 TO _HEIGHT - 1)
  25. DIM SHARED minB!(0 TO _HEIGHT - 1)
  26. DIM SHARED maxB!(0 TO _HEIGHT - 1)
  27.  
  28. '************************ for experimental collision detection algo
  29. DIM SHARED DivSecX, DivSecY, DivSecZ, NumXSegs, NumYSegs, NumZSegs, MinObjectRotateXYZ%, MaxObjectRotateRateXYZ%, MaxR
  30. DIM SHARED currentplayerx, currentplayery, currentplayerz
  31. NumYSegs = 16
  32. NumXSegs = 16
  33. NumZSegs = 16
  34. maxscreenz = 1024
  35. DivSecY = _HEIGHT / NumYSegs
  36. DivSecX = _WIDTH / NumXSegs
  37. DivSecZ = maxscreenz / NumZSegs
  38.  
  39. '* this is just an arbitrary formula i came up with that keeps counts() and polysinregion() from having array bounds errors
  40. '* there is probably a better one available, but this involves a lot of probability theory
  41. ProbableMax = 2 * MaxPolys / ((NumXSegs + 1) ^ (1 / 8))
  42.  
  43. DIM SHARED Counts(NumXSegs, NumYSegs, NumZSegs), PolysInRegion(NumXSegs, NumYSegs, NumZSegs, ProbableMax)
  44.  
  45. '*************************
  46. TYPE PolyRec
  47.     px AS INTEGER
  48.     py AS INTEGER
  49.     pz AS INTEGER
  50.     radius AS INTEGER
  51.     nsides AS INTEGER
  52.     incx AS INTEGER
  53.     incy AS INTEGER
  54.     incz AS INTEGER
  55.     rotateangle AS INTEGER
  56.     incrotate AS INTEGER
  57.     vertical AS INTEGER
  58.     horizontal AS INTEGER
  59.     verticalinc AS INTEGER
  60.     horizontalinc AS INTEGER
  61.     fill AS INTEGER
  62.     fillstep AS INTEGER
  63.     dosectorlines AS INTEGER
  64.     cr AS SINGLE
  65.     cg AS SINGLE
  66.     cb AS SINGLE
  67.     crs AS SINGLE
  68.     cgs AS SINGLE
  69.     cbs AS SINGLE
  70.     mass AS INTEGER
  71.     alreadychecked AS INTEGER
  72.     style AS INTEGER
  73.     kind AS INTEGER
  74.     active AS INTEGER
  75. k! = 2520
  76. '2^3 * 3^2 * 5 * 7 = 2520, a number dividable by all numbers between 1 and 10.
  77. DIM SHARED SinTable!(0 TO k! - 1), CosTable!(0 TO k! - 1), UpBoundTrigTables%, mybulletmin, mybulletmax, myship, points&
  78.  
  79. UpBoundTrigTables% = UBOUND(SinTable!)
  80. MaxObjectRotateRateXYZ% = (UpBoundTrigTables% + 1) / 8
  81. MinObJectRotateRateXYZ% = (UpBoundTrigTables% + 1) / 15
  82. '* use precalculated trig tables for speed, especially doing rotations!
  83. '* this program does a ton of them
  84. FOR i = 0 TO UpBoundTrigTables%
  85.     a! = i * 3.141592653589793 / ((UpBoundTrigTables% + 1) / 2)
  86.     SinTable!(i) = SIN(a!)
  87.     CosTable!(i) = COS(a!)
  88. keystepx = maxscreenx / 10
  89. keystepy = maxscreeny / 10
  90. keystepz = maxscreenz / 10
  91. DIM Polys(MaxPolys) AS PolyRec
  92.  
  93. IF DivSecX < DivSecY THEN
  94.     MaxR = DivSecX
  95.     MaxR = DivSecY
  96. IF DivSecZ < MaxR THEN
  97.     MaxR = DivSecZ
  98.  
  99. '* user-controlled poly -- still a bit jumpy to say the least, even with loop-unrolled (formerly the for/next with index i on polygons)
  100. '* program a faster way to handle this and add some shooting/effects, you got yourself a game!
  101. myship = 0
  102. numbullets = 32
  103. mybulletmin = myship + 1
  104. mybulletmax = mybulletmin + numbullets
  105. '* set default values for stuff flying around on-screen
  106. '* must pass i as this determines the classification of the polygon
  107. '* far easier to do this than creating individual polygon records for the ship, its weapons (laserbombs) and each asteroid (polyoid)
  108. FOR i = 0 TO MaxPolys
  109.     setPolyParams Polys(), i
  110. nframes% = 0
  111. frames& = 0
  112. tstart# = TIMER
  113. Bytes% = (DivSecX * DivSecY * (32 / 8) + 4) / 2
  114. DIM RestoreScreen%(DivSecX, DivSecY, 1 TO Bytes%)
  115. oldpx = -1
  116. oldpy = -1
  117. asteroidhit = 0
  118.  
  119. '* change this to 0 for making into game
  120. testing = -1
  121. IF testing THEN
  122.     up$ = CHR$(0) + CHR$(72) '* up arrow
  123.     down$ = CHR$(0) + CHR$(80) '* down arrow
  124.     lft$ = CHR$(0) + CHR$(75) '* left arrow
  125.     rght$ = CHR$(0) + CHR$(77) '* right arrow
  126.     back$ = CHR$(0) + CHR$(141) '* ctrl-up
  127.     forward$ = CHR$(0) + CHR$(145) '*ctrl-down
  128.     fire$ = " "
  129.     fdx$ = "X"
  130.     fdy$ = "Y"
  131.     fdz$ = "Z"
  132.     fdxn$ = "^X"
  133.     fdyn$ = "^Y"
  134.     fdzn$ = "^Z"
  135.     cutthatcrapout$ = CHR$(27)
  136.     GetKey "Up", up$
  137.     GetKey "Down", down$
  138.     GetKey "Left", lft$
  139.     GetKey "Right", rght$
  140.     GetKey "forward", forward$
  141.     GetKey "Back", back$
  142.     GetKey "Fire", fire$
  143.     GetKey "Stop this infernal madness", cutthatcrapout$
  144.     GetKey "Fire Direction X+", fdx$
  145.     GetKey "Fire Direction Y+", fdy$
  146.     GetKey "Fire Direction Z+", fdz$
  147.     GetKey "Fire Direction X-", fdxn$
  148.     GetKey "Fire Direction Y-", fdyn$
  149.     GetKey "Fire Direction Z-", fdzn$
  150.  
  151. '_FULLSCREEN
  152. points& = 0
  153. asteroidhit = 0
  154. asteroidhitmax = 256
  155. i = MaxPolys + 1
  156. missilesactive% = 0
  157. nframes% = 0
  158.     frames& = frames& + 1
  159.     DO
  160.  
  161.         DO
  162.             lb% = _MOUSEBUTTON(1)
  163.             IF lb% THEN
  164.                 k$ = fire$
  165.             END IF
  166.             rb% = _MOUSEBUTTON(2)
  167.             IF rb% THEN '* function not yet implemented
  168.             END IF
  169.             currentplayerx = _MOUSEX
  170.             currentplayery = _MOUSEY
  171.             M% = _MOUSEINPUT
  172.         LOOP UNTIL NOT M%
  173.         k$ = INKEY$
  174.         SELECT CASE k$
  175.             CASE CHR$(1) TO CHR$(26)
  176.                 k$ = "^" + CHR$(ASC("A") - 1 + ASC(k$))
  177.         END SELECT
  178.         SELECT CASE k$ '* keyboard
  179.             CASE lft$
  180.                 currentplayerx = SetToMinMax(currentplayerx - keystepx, Polys(myship).radius, maxscreenx - Polys(myship).radius)
  181.             CASE rght$
  182.                 currentplayerx = SetToMinMax(currentplayerx + keystepx, Polys(myship).radius, maxscreenx - Polys(myship).radius)
  183.             CASE up$
  184.                 currentplayery = SetToMinMax(currentplayery - keystepy, Polys(myship).radius, maxscreeny - Polys(myship).radius)
  185.             CASE down$
  186.                 currentplayery = SetToMinMax(currentplayery + keystepy, Polys(myship).radius, maxscreeny - Polys(myship).radius)
  187.             CASE forward$ '* into the screen -- increasing z values move away from player
  188.                 currentplayerz = SetToMinMax(currentplayerz + keystepz, Polys(myship).radius, maxscreenz - Polys(myship).radius)
  189.             CASE back$
  190.                 currentplayerz = SetToMinMax(currentplayerz - keystepz, Polys(myship).radius, maxscreenz - Polys(myship).radius)
  191.             CASE fire$
  192.                 '* the laserbombs start in a cluster and spread out fairly evenly along x,y and z planes
  193.                 '* don't fire off too many at once or my collision-checking program might scream
  194.                 '* i have fired off 64 at once without failure. for a cool effect, hold down the spacebar
  195.                 '* or whatever key you select for your fire button and then release it.
  196.                 missilesactive% = -1
  197.                 nframes% = 0
  198.                 count% = 0
  199.                 FOR h = mybulletmin TO mybulletmax
  200.                     Polys(h).active = -1
  201.                     Polys(h).px = currentplayerx + Polys(myship).radius
  202.                     Polys(h).py = currentplayery + Polys(myship).radius
  203.                     Polys(h).pz = currentplayerz + Polys(myship).radius
  204.                     Polys(h).incx = (CINT(RND) * 2 - 1) * (INT(RND * (_HEIGHT \ 32)) + 1)
  205.                     Polys(h).incy = (CINT(RND) * 2 - 1) * (INT(RND * (_HEIGHT \ 32)) + 1)
  206.                     Polys(h).incz = (CINT(RND) * 2 - 1) * (INT(RND * (maxscreenz \ 32)) + 1)
  207.                     'Polys(h).incx = 7 + INT(RND * 9)
  208.                     'Polys(h).incy = 7 + INT(RND * 9)
  209.                     'Polys(h).incz = 7 + INT(RND * 9)
  210.                 NEXT
  211.                 IF fdx < 1 THEN
  212.                     fdx = 1
  213.                 END IF
  214.                 IF fdy < 1 THEN
  215.                     fdy = 1
  216.                 END IF
  217.                 IF fdz < 1 THEN
  218.                     fdz = 1
  219.                 END IF
  220.                 EXIT DO
  221.             CASE fdx$
  222.                 fdx = fdx + 1
  223.             CASE fdy$
  224.                 fdy = fdy + 1
  225.             CASE fdz$
  226.                 fdz = fdz + 1
  227.             CASE fdxn$ '* "^X"
  228.                 fdx = fdx - 1
  229.             CASE fdyn$ '* "^Y"
  230.                 fdy = fdy - 1
  231.             CASE fdzn$ '* "^Z"
  232.                 fdz = fdz - 1
  233.             CASE cutthatcrapout$
  234.                 SYSTEM
  235.             CASE ELSE
  236.                 mk = 0
  237.                 LOCATE 2, 1
  238.                 DO
  239.                     IF mk < LEN(k$) THEN
  240.                         mk = mk + 1
  241.                         PRINT USING "###:"; ASC(k$, mk);
  242.                     ELSE
  243.                         EXIT DO
  244.                     END IF
  245.                 LOOP
  246.         END SELECT
  247.     LOOP UNTIL k$ = ""
  248.     DO
  249.         IF oldpx <> currentplayerx OR oldpy <> currentplayery OR currentplayerz <> oldpz THEN
  250.             'drawpolySimple PlayerRect, _RGB32(PlayerRect.cr, playerrrect.cg, PlayerRect.cb)
  251.             oldpy = currentplayery
  252.             oldpx = currentplayerx
  253.             oldpz = currentplayerz
  254.             'PlayerRect.px = CurrentPlayerx
  255.             'PlayerRect.py = CurrentPlayerY
  256.             'PlayerRect.pz = CurrentPlayerZ
  257.         END IF
  258.         IF i > MaxPolys THEN
  259.             _DISPLAY
  260.             PrintLocate 3, 1, MID$(STR$(points&), 2), 1, 0, 0, dummy$
  261.             oldpx = currentplayerx - 1
  262.             oldpy = currentplayery - 1
  263.             i = 0
  264.             FOR X = 0 TO NumXSegs
  265.                 FOR y = 0 TO NumYSegs
  266.                     FOR z = 0 TO NumZSegs
  267.                         FOR a = 0 TO Counts(X, y, z) - 1
  268.                             Polys(PolysInRegion(X, y, z, a)).alreadychecked = 0
  269.                         NEXT
  270.                         Counts(X, y, z) = 0
  271.                     NEXT
  272.                 NEXT
  273.             NEXT
  274.             EXIT DO
  275.         ELSE
  276.             'drawpoly Polys(i), 0
  277.             SELECT CASE Polys(i).kind
  278.                 CASE ismyship
  279.                     Polys(i).px = currentplayerx
  280.                     Polys(i).py = currentplayery
  281.                     Polys(i).pz = currentplayerz
  282.                 CASE ELSE
  283.                     IF Polys(i).px > maxscreenx - Polys(i).incx - Polys(i).radius THEN
  284.                         Polys(i).incx = -Polys(i).incx
  285.                         Polys(i).incrotate = -SGN(Polys(i).incy) * RandRange%(MinObJectRotateRateXYZ%, MaxObjectRotateRateXYZ%)
  286.                     ELSEIF Polys(i).px < Polys(i).radius - Polys(i).incx THEN
  287.                         Polys(i).incx = -Polys(i).incx
  288.                         Polys(i).incrotate = SGN(Polys(i).incy) * RandRange%(MinObJectRotateRateXYZ%, MaxObjectRotateRateXYZ%)
  289.                     END IF
  290.  
  291.                     IF Polys(i).py > maxscreeny - Polys(i).incy - Polys(i).radius THEN
  292.                         Polys(i).incy = -Polys(i).incy
  293.                         Polys(i).incrotate = SGN(Polys(i).incx) * RandRange%(MinObJectRotateRateXYZ%, MaxObjectRotateRateXYZ%)
  294.                     ELSEIF Polys(i).py < Polys(i).radius - Polys(i).incy THEN
  295.                         Polys(i).incy = -Polys(i).incy
  296.                         Polys(i).incrotate = -SGN(Polys(i).incx) * RandRange%(MinObJectRotateRateXYZ%, MaxObjectRotateRateXYZ%)
  297.                     END IF
  298.  
  299.                     IF Polys(i).pz > maxscreenz - Polys(i).incz - Polys(i).radius THEN
  300.                         Polys(i).incz = -Polys(i).incz
  301.                         Polys(i).incrotate = SGN(Polys(i).incx) * RandRange%(MinObJectRotateRateXYZ%, MaxObjectRotateRateXYZ%)
  302.                     ELSEIF Polys(i).pz < Polys(i).radius - Polys(i).incz THEN
  303.                         Polys(i).incz = -Polys(i).incz
  304.                         Polys(i).incrotate = -SGN(Polys(i).incz) * RandRange%(MinObJectRotateRateXYZ%, MaxObjectRotateRateXYZ%)
  305.                     END IF
  306.             END SELECT
  307.             '* SetIncrementers Polys(i).px, Polys(i).incx, Polys(i).radius, Maxscreenx - Polys(i).radius
  308.             '* SetIncrementers Polys(i).py, Polys(i).incy, Polys(i).radius, Maxscreeny - Polys(i).radius
  309.             '* SetIncrementers Polys(i).pz, Polys(i).incz, Polys(i).radius, MaxScreenZ - Polys(i).radius
  310.  
  311.             SetIncrementers Polys(i).cr, Polys(i).crs, 0, 255
  312.             SetIncrementers Polys(i).cg, Polys(i).cgs, 0, 255
  313.             SetIncrementers Polys(i).cb, Polys(i).cbs, 0, 255
  314.  
  315.             Polys(i).horizontal = MapToTrigTables%(Polys(i).horizontal + Polys(i).horizontalinc)
  316.             Polys(i).vertical = MapToTrigTables%(Polys(i).vertical + Polys(i).verticalinc)
  317.             Polys(i).rotateangle = MapToTrigTables%(Polys(i).rotateangle + Polys(i).incrotate)
  318.  
  319.             Polys(i).px = Polys(i).px + Polys(i).incx
  320.             Polys(i).py = Polys(i).py + Polys(i).incy
  321.             Polys(i).pz = Polys(i).pz + Polys(i).incz
  322.  
  323.             Polys(i).cr = Polys(i).cr + Polys(i).crs
  324.             Polys(i).cg = Polys(i).cg + Polys(i).cgs
  325.             Polys(i).cb = Polys(i).cb + Polys(i).cbs
  326.             IF Polys(i).active THEN
  327.                 drawpoly Polys(i), 1
  328.  
  329.                 getsegminmax Polys(i).px, StartX, EndX, Polys(i).radius, IndexX, DivSecX, NumXSegs
  330.                 getsegminmax Polys(i).py, StartY, EndY, Polys(i).radius, IndexY, DivSecY, NumYSegs
  331.                 getsegminmax Polys(i).pz, StartZ, EndZ, Polys(i).radius, IndexZ, DivSecZ, NumZSegs
  332.  
  333.                 PolysInRegion(IndexX, IndexY, IndexZ, Counts(IndexX, IndexY, IndexZ)) = i
  334.                 Polys(PolysInRegion(IndexX, IndexY, IndexZ, i)).alreadychecked = -1
  335.                 FOR sx = StartX TO EndX
  336.                     FOR sy = StartY TO EndY
  337.                         FOR sz = StartZ TO EndZ
  338.                             FOR z = 0 TO Counts(sx, sy, sz) - 1
  339.                                 GOSUB MainCollider
  340.                             NEXT
  341.                         NEXT
  342.                     NEXT
  343.                 NEXT
  344.                 Counts(IndexX, IndexY, IndexZ) = Counts(IndexX, IndexY, IndexZ) + 1
  345.                 'PutRegion Polys(i), IndexX, IndexY, RestoreScreen%()
  346.             ELSE
  347.                 'drawpoly Polys(i), 0
  348.             END IF
  349.             i = i + 1
  350.             IF missilesasctive% THEN
  351.                 IF count% > MaxPolys% THEN
  352.                     IF nfames% < 64 THEN
  353.                         nframes% = nframes% + 1
  354.                     ELSE
  355.                         IF testing THEN
  356.                         ELSE
  357.                             '* LOCATE 2, 1
  358.                             '* PRINT "Ha! You missed us, James T Kirk -- you suck!";
  359.                         END IF
  360.                         FOR h = mybulletmin TO mybulletmax
  361.                             '* drawpoly Polys(h), 0
  362.                             Polys(h).active = 0
  363.                         NEXT
  364.                         count% = 0
  365.                         nframes% = 0
  366.                         missilesactive% = 0
  367.                     END IF
  368.                 ELSE
  369.                     count% = count% + 1
  370.                 END IF
  371.             END IF
  372.         END IF
  373.     LOOP
  374.     '_LIMIT 60
  375.     _DISPLAY
  376.     IF k$ = CHR$(27) THEN
  377.         EXIT DO
  378.     ELSE
  379.         'CLS
  380.         IF frames& MOD 1000 = 0 THEN
  381.             '_TITLE STR$(frames& / 1000) + STR$(frames& / (TIMER - tstart#))
  382.         END IF
  383.         'saveimage _DEST, "ScreenShot" + STR$(frame& / 1000)
  384.         'SYSTEM
  385.     END IF
  386.     _LIMIT 128
  387. tend# = TIMER
  388. PRINT frames& / (tend# - tstart#)
  389.  
  390. MainCollider:
  391. IF PolysInRegion(sx, sy, sz, i) <> PolysInRegion(sx, sy, sz, z) THEN
  392.     collide Polys(), PolysInRegion(sx, sy, sz, i), PolysInRegion(sx, sy, sz, z)
  393.     IF Distance(Polys(PolysInRegion(sx, sy, sz, i)), Polys(PolysInRegion(sx, sy, sz, z))) <= 0 THEN
  394.         SELECT CASE Polys(PolysInRegion(sx, sy, sz, i)).kind
  395.             CASE asteroid
  396.                 IF Polys(PolysInRegion(sx, sy, sz, z)).kind = laserbomb THEN
  397.                     '* asteroid smacked bomb
  398.                     Polys(PolysInRegion(sx, sy, sz, z)).active = 0
  399.                     Polys(PolysInRegion(sx, sy, sz, i)).active = 0
  400.                     points& = points& + 1
  401.                 END IF
  402.             CASE laserbomb
  403.                 IF Polys(PolysInRegion(sx, sy, sz, z)).kind = asteroid THEN
  404.                     '* bomb smacked asteroid
  405.                     Polys(PolysInRegion(sx, sy, sz, z)).active = 0
  406.                     Polys(PolysInRegion(sx, sy, sz, i)).active = 0
  407.                     IF testing THEN
  408.                     ELSE
  409.                         points& = points& + 1
  410.                         IF testing THEN
  411.                         ELSE
  412.                         END IF
  413.                     END IF
  414.                 END IF
  415.             CASE ismyship
  416.                 IF Polys(PolysInRegion(sx, sy, sz, z)).kind = asteroid THEN
  417.                     '* asteroid smacked my ship
  418.                     IF asteroidhit < asteroidhitmax THEN
  419.                         asteroidhit = asteroidhit + 1
  420.                     ELSE
  421.                         points& = points& - 1
  422.                         asteroidhit = 0
  423.                     END IF
  424.                 END IF
  425.         END SELECT
  426.     END IF
  427.  
  428. SUB setPolyParams (p() AS PolyRec, i)
  429.     p(i).radius = INT(((MaxR - 2) / 1.28) * RND) + 2
  430.     p(i).px = INT(RND * (maxscreenx - 2 * p(i).radius)) + p(i).radius
  431.     p(i).py = INT(RND * (maxscreeny - 2 * p(i).radius)) + p(i).radius
  432.     p(i).pz = INT(RND * (maxscreenz - 2 * p(i).radius)) + p(i).radius
  433.     p(i).nsides = INT(RND * 7) + 2
  434.     IF p(i).nsides = 2 THEN p(i).nsides = 40 'approximate circle
  435.     p(i).incx = (CINT(RND) * 2 - 1) * (INT(RND * (_HEIGHT \ 32)) + 1)
  436.     p(i).incy = (CINT(RND) * 2 - 1) * (INT(RND * (_HEIGHT \ 32)) + 1)
  437.     p(i).incz = (CINT(RND) * 2 - 1) * (INT(RND * (maxscreenz \ 32)) + 1)
  438.     p(i).rotateangle = RangeNum%(MinObjectRotateXYZ%, MaxObjectRotateRateXYZ%)
  439.     p(i).incrotate = (CINT(RND) * 2 - 1) * RandRange%(MinObJectRotateRateXYZ%, MaxObjectRotateRateXYZ%)
  440.  
  441.     '* these are used by drawpolySimple
  442.     p(i).fill = CINT(RND) * 2 - 1
  443.     p(i).fillstep = INT(RND * MaxR) + 1
  444.     p(i).style = INT(RND * 3)
  445.     p(i).dosectorlines = INT(1 - RND * 2)
  446.     p(i).vertical = (CINT(RND) * 2 - 1) * RangeNum%(MinObjectRotateXYZ%, MaxObjectRotateRateXYZ%)
  447.     p(i).horizontal = (CINT(RND) * 2 - 1) * RangeNum%(MinObjectRotateXYZ%, MaxObjectRotateRateXYZ%)
  448.     p(i).verticalinc = (CINT(RND) * 2 - 1) * RangeNum%(MinObjectRotateXYZ%, MaxObjectRotateRateXYZ%)
  449.     p(i).horizontalinc = (CINT(RND) * 2 - 1) * RangeNum%(MinObjectRotateXYZ%, MaxObjectRotateRateXYZ%)
  450.     'Color cycling
  451.     p(i).cr = RND * 256
  452.     p(i).cg = RND * 256
  453.     p(i).cb = RND * 256
  454.     p(i).crs = (CINT(RND) * 2 - 1) * (RND * 4 + 2)
  455.     p(i).cgs = (CINT(RND) * 2 - 1) * (RND * 4 + 2)
  456.     p(i).cbs = (CINT(RND) * 2 - 1) * (RND * 4 + 2)
  457.  
  458.     '* these are used by collision checker
  459.     p(i).mass = 1 '(Polys(i).radius ^ 3) / 4
  460.     p(i).alreadychecked = 0
  461.     p(i).active = -1
  462.     SELECT CASE i
  463.         CASE myship
  464.             p(i).kind = ismyship
  465.             p(i).incx = 0
  466.             p(i).incy = 0
  467.             p(i).incz = 0
  468.             p(i).radius = MaxR
  469.             IF _MOUSEINPUT THEN
  470.                 currentplayerx = _MOUSEX
  471.                 currentplayery = _MOUSEY
  472.             END IF
  473.             p(i).pz = currentplayerx
  474.             p(i).py = currentplayery
  475.             p(i).px = currentplayerz
  476.             p(i).incrotate = (UpBoundTrigTables% + 1) / (p(i).nsides + 1)
  477.         CASE mybulletmin TO mybulletmax
  478.             p(i).kind = laserbomb
  479.             p(i).active = 0
  480.             p(i).nsides = INT(RND * 7) + 3
  481.         CASE ELSE
  482.             p(i).kind = asteroid
  483.     END SELECT
  484. SUB GetKey (p$, r$)
  485.     PRINT "Press the key to go "; p$
  486.     DO
  487.         r$ = INKEY$
  488.     LOOP UNTIL r$ > ""
  489.  
  490. SUB getsegminmax (ptcheck, sxy, exy, radius, Index, divider, NumSegs)
  491.     Index = SetToMinMax(ptcheck \ divider, 0, NumSegs)
  492.     IF Index > 0 THEN
  493.         sxy = (ptcheck - radius) \ divider
  494.     ELSE
  495.         sxy = Index
  496.     END IF
  497.     IF (ptcheck + radius) \ divider > NumSegs THEN
  498.         exy = NumSegs
  499.     ELSE
  500.         exy = (ptcheck + radius) \ divider
  501.     END IF
  502.  
  503. FUNCTION SetToMinMax (calcvalue, minval, maxval)
  504.     '* used to calculate rotating values, namely color variations used for shading/coloring polygons and increments used for moving asteroids/laserbombs
  505.     '* whose values are not mouse/user input dependent
  506.     IF calcvalue < minval THEN
  507.         SetToMinMax = minval
  508.     ELSE
  509.         IF calcvalue > maxval THEN
  510.             SetToMinMax = maxval
  511.         ELSE
  512.             SetToMinMax = calcvalue
  513.         END IF
  514.     END IF
  515.  
  516. SUB SetIncrementers (a, addv, min, max)
  517.     a = SetToMinMax(a + addv, min, max)
  518.     IF a < min - addv THEN
  519.         addv = -addv
  520.     ELSEIF a > max - addv THEN
  521.         addv = -addv
  522.     END IF
  523.  
  524. SUB collide (p() AS PolyRec, x, y)
  525.     calcmethod = 1
  526.     SELECT CASE calcmethod
  527.         CASE 1
  528.             IF Distance(p(x), p(y)) > 0 THEN
  529.                 EXIT SUB
  530.             ELSE
  531.                 CalcVelocities p(), x, y
  532.                 p(x).alreadychecked = -1
  533.                 p(y).alreadychecked = -1
  534.             END IF
  535.         CASE ELSE
  536.             IF (NOT p(x).alreadychecked) OR (NOT p(y).alreadychecked) THEN
  537.                 IF ABS(p(x).pz - p(y).pz) < p(x).radius + p(y).radius THEN
  538.                     d = ((p(x).px - p(y).px) ^ 2 + (p(x).py - p(y).py) ^ 2)
  539.                     IF d <= (p(x).radius + p(y).radius) ^ 2 THEN
  540.                         CalcVelocities p(), x, y
  541.                         p(x).alreadychecked = -1
  542.                         p(y).alreadychecked = -1
  543.                     END IF
  544.                 END IF
  545.             END IF
  546.     END SELECT
  547.  
  548. FUNCTION Distance (p AS PolyRec, q AS PolyRec)
  549.     '* calculates distance using pythagorean formula for (x1,y1), (x2,y2) and relative distance betweenz Z
  550.     dx! = (p.px - q.px) ^ 2
  551.     dy! = (p.py - q.py) ^ 2
  552.     hyp! = SQR(dx! + dy!)
  553.     IF hyp! > p.radius + q.radius THEN
  554.         s! = hyp! - (p.radius + q.radius)
  555.     ELSE
  556.         IF ABS(p.pz - q.pz) > p.radius + q.radius THEN
  557.             s! = ABS(p.pz - q.pz)
  558.         ELSE
  559.             s! = hyp! - (p.radius + q.radius)
  560.         END IF
  561.     END IF
  562.     Distance = s!
  563.  
  564. FUNCTION RangeNum% (min%, max%)
  565.     '* generates random number from min% to max% inclusive
  566.     RangeNum% = min% + INT(RND * (max% - min% + 1))
  567.  
  568. FUNCTION GetPx (p AS PolyRec, m$)
  569.     SELECT CASE m$
  570.         CASE "x"
  571.             GetPx = p.px
  572.         CASE "y"
  573.             GetPx = p.py
  574.         CASE "z"
  575.             GetPx = p.pz
  576.         CASE ELSE
  577.             GetPx = 0
  578.     END SELECT
  579.  
  580. SUB CalcVelocities (b() AS PolyRec, i&, j&)
  581.     temp1 = b(i&).incx
  582.     temp2 = b(j&).incx
  583.     totalMass = (b(i&).mass + b(j&).mass)
  584.     b(i&).incx = (temp1 * (b(i&).mass - b(j&).mass) + (2 * b(j&).mass * temp2)) / totalMass
  585.     b(j&).incx = (temp2 * (b(j&).mass - b(i&).mass) + (2 * b(i&).mass * temp1)) / totalMass
  586.     temp1 = b(i&).incy
  587.     temp2 = b(j&).incy
  588.     b(i&).incy = (temp1 * (b(i&).mass - b(j&).mass) + (2 * b(j&).mass * temp2)) / totalMass
  589.     b(j&).incy = (temp2 * (b(j&).mass - b(i&).mass) + (2 * b(i&).mass * temp1)) / totalMass
  590.     temp1 = b(i&).incz
  591.     temp2 = b(j&).incz
  592.     b(i&).incz = (temp1 * (b(i&).mass - b(j&).mass) + (2 * b(j&).mass * temp2)) / totalMass
  593.     b(j&).incz = (temp2 * (b(j&).mass - b(i&).mass) + (2 * b(i&).mass * temp1)) / totalMass
  594.  
  595. SUB drawpoly (p AS PolyRec, intensity)
  596.     REDIM x(p.nsides), y(p.nsides)
  597.     cr0 = 255 * intensity
  598.     cg0 = 255 * intensity
  599.     cb0 = 255 * intensity
  600.     cr1 = p.cr * intensity
  601.     cg1 = p.cg * intensity
  602.     cb1 = p.cb * intensity
  603.  
  604.     x = p.px
  605.     y = p.py
  606.     z = p.pz
  607.     r = p.radius
  608.  
  609.     a! = p.rotateangle - INT(p.rotateangle / (UpBoundTrigTables% + 1)) * (UpBoundTrigTables% + 1)
  610.     sa! = (UpBoundTrigTables% + 1) / p.nsides
  611.     b = INT(a!)
  612.     x1! = CosTable!(b) * CosTable!(p.horizontal)
  613.     y1! = SinTable!(b) * SinTable!(p.vertical)
  614.     zscale! = (z / maxscreenz)
  615.     rzscale! = r * zscale!
  616.     IF x < _WIDTH / 2 THEN
  617.         fx = x + rzscale! / 3
  618.     ELSE
  619.         fx = x - rzscale! / 3
  620.     END IF
  621.  
  622.     IF y > _HEIGHT / 2 THEN
  623.         fy = y - rzscale! / 3
  624.     ELSE
  625.         fy = y + rzscale! / 3
  626.     END IF
  627.  
  628.     FOR a = p.nsides - 1 TO 0 STEP -1
  629.         a! = a! + sa!
  630.         a! = a! + (UpBoundTrigTables% + 1) * (a! >= (UpBoundTrigTables% + 1))
  631.         b = INT(a!)
  632.         x2! = CosTable!(b) * CosTable!(p.horizontal): x(a) = x2!
  633.         y2! = SinTable!(b) * SinTable!(p.vertical): y(a) = y2!
  634.         IF zscale! = 1 THEN
  635.             SELECT CASE p.style
  636.                 CASE 1
  637.                     gTriangle fx, fy, x + (x1! * rzscale!), y + (y1! * rzscale!), x + (x2! * rzscale!), y + (y2! * rzscale!), _RGB32(cr0, cg0, cb0), _RGB32(cr1, cg1, cb1), RGBToNum(cr1, cg1, cb1)
  638.                 CASE 2
  639.                     gTriangle fx, fy, x + (x1! * r), y + (y1! * r), x + (x2! * r), y + (y2! * r), _RGB32(cr0, cg0, cb0), _RGB32(cr1, cg1, cb1), _RGB32(cr1, cg1, cb1)
  640.                 CASE ELSE
  641.                     drawpolySimple p, _RGB32(cr0, cg0, cb0)
  642.             END SELECT
  643.         ELSEIF zscale! <> 0 THEN
  644.             SELECT CASE p.style
  645.                 CASE 1
  646.                     gTriangle fx, fy, x + (x1! * rzscale!), y + (y1! * rzscale!), x + (x2! * rzscale!), y + (y2! * rzscale!), _RGB32(cr0, cg0, cb0), _RGB32(cr1, cg1, cb1), RGBToNum(cr1, cg1, cb1)
  647.                 CASE 2
  648.                     gTriangle fx, fy, x + (x1! * r), y + (y1! * r), x + (x2! * r), y + (y2! * r), _RGB32(cr0, cg0, cb0), _RGB32(cr1, cg1, cb1), _RGB32(cr1, cg1, cb1)
  649.                 CASE ELSE
  650.                     drawpolySimple p, _RGB32(cr0, cg0, cb0)
  651.             END SELECT
  652.         END IF
  653.         x1! = x2!
  654.         y1! = y2!
  655.     NEXT
  656.  
  657. FUNCTION RGBToNum& (cr, cg, cb)
  658.     RGBToNum& = cr * 65536 + cg * 256 + cb
  659.  
  660. SUB NewPolyDraw (p AS PolyRec)
  661.     ang = 0
  662.     stp = 360 / p.nsides
  663.     deg = ATN(1) / 45
  664.     r = p.radius
  665.     x = p.px
  666.     y = p.py
  667.     DO
  668.         x1 = y + COS(ang * deg) * r
  669.         y1 = y + SIN(ang * deg) * r
  670.         x2 = y + COS((ang + 5) * deg) * r
  671.         y2 = y + SIN((ang + 5) * deg) * r
  672.         gTriangle x, y, x1, y1, x2, y2, c1&, c2&, c2&
  673.         ang = ang + stp
  674.     LOOP UNTIL ang > 360 - stp
  675.  
  676. SUB drawpolySimple (p AS PolyRec, c)
  677.     IF p.nsides > 0 THEN
  678.         IF c = 0 THEN
  679.             fc& = 0
  680.         ELSE
  681.             fc& = _RGB32(p.cr, p.cg, p.cb)
  682.         END IF
  683.         Zfactor! = p.pz / maxscreenz
  684.         yx = (UpBoundTrigTables% + 1) / p.nsides
  685.         angle2 = MapToTrigTables%(p.rotateangle)
  686.         FOR i = 0 TO (UpBoundTrigTables% + 1) STEP yx
  687.             angle = angle2
  688.             angle2 = MapToTrigTables%(angle + yx)
  689.             IF p.fill THEN
  690.                 FOR cr = 1 TO p.radius STEP p.fillstep
  691.                     x1 = p.px + Zfactor! * (cr * CosTable!(angle)) * CosTable!(MapToTrigTables%(p.horizontal))
  692.                     y1 = p.py + Zfactor! * (cr * SinTable!((angle))) * SinTable!(MapToTrigTables%(p.vertical))
  693.                     x2 = p.px + Zfactor! * (cr * CosTable!(((angle2)))) * CosTable!(MapToTrigTables%(p.horizontal))
  694.                     y2 = p.py + Zfactor! * (cr * SinTable!(((angle2)))) * SinTable!(MapToTrigTables%(p.vertical))
  695.                     LINE (x1, y1)-(x2, y2), fc&
  696.                     IF p.dosectorlines THEN
  697.                         LINE (p.px, p.py)-(x1, y1), fc&
  698.                     END IF
  699.                 NEXT
  700.             ELSE
  701.                 x1 = p.px + Zfactor! * (p.radius * CosTable!((angle)))
  702.                 y1 = p.py + Zfactor! * (p.radius * SinTable!((angle)))
  703.                 x2 = p.px + Zfactor! * (p.radius * CosTable!(((angle2))))
  704.                 y2 = p.py + Zfactor! * (p.radius * SinTable!(((angle2))))
  705.                 LINE (x1, y1)-(x2, y2), fc&
  706.                 IF p.dosectorlines THEN
  707.                     LINE (p.px, p.py)-(x1, y1), fc&
  708.                 END IF
  709.             END IF
  710.         NEXT
  711.     ELSE
  712.         PSET (p.px, p.py), c
  713.     END IF
  714.  
  715. FUNCTION MapToTrigTables% (angle)
  716.     a = angle MOD (UpBoundTrigTables% + 1)
  717.     IF a < 0 THEN
  718.         a = a + (UpBoundTrigTables% + 1)
  719.     END IF
  720.     MapToTrigTables% = a
  721.  
  722. FUNCTION CosToSinMap (angle)
  723.     '* not used
  724.     CosToSinMap = MapToTrigTables%(angle - (UpBoundTrigTables% + 1) / 4)
  725.  
  726. FUNCTION RandRange% (min%, max%)
  727.     RandRange% = min% + INT(RND * (max% - min% + 1))
  728.  
  729. '=== Make a linear gradient along the vertical axis of an edge ===
  730. SUB gTriangle (x1%, y1%, x2%, y2%, x3%, y3%, c1&, c2&, c3&)
  731.     cr1 = _RED32(c1&): cg1 = _GREEN32(c1&): cb1 = _BLUE32(c1&)
  732.     cr2 = _RED32(c2&): cg2 = _GREEN32(c2&): cb2 = _BLUE32(c2&)
  733.     cr3 = _RED32(c3&): cg3 = _GREEN32(c3&): cb3 = _BLUE32(c3&)
  734.  
  735.     minY% = y1%
  736.     maxY% = y1%
  737.     IF minY% > y2% THEN minY% = y2%
  738.     IF maxY% < y2% THEN maxY% = y2%
  739.     IF minY% > y3% THEN minY% = y3%
  740.     IF maxY% < y3% THEN maxY% = y3%
  741.  
  742.     IF minY% < 0 THEN minY% = 0
  743.     IF maxY% > _HEIGHT - 1 THEN maxY% = _HEIGHT - 1
  744.  
  745.     ' Create a vertical gradient along each side of the triangle
  746.     FOR y% = minY% TO maxY%
  747.         minX%(y%) = _WIDTH
  748.         maxX%(y%) = -1
  749.     NEXT
  750.  
  751.     gMark x1%, y1%, x2%, y2%, cr1%, cg1%, cb1%, cr2%, cg2%, cb2%
  752.     gMark x2%, y2%, x3%, y3%, cr2%, cg2%, cb2%, cr3%, cg3%, cb3%
  753.     gMark x3%, y3%, x1%, y1%, cr3%, cg3%, cb3%, cr1%, cg1%, cb1%
  754.  
  755.     FOR y% = minY% TO maxY%
  756.         x% = minX%(y%)
  757.         maxX% = maxX%(y%)
  758.         cr! = minR!(y%)
  759.         cg! = minG!(y%)
  760.         cb! = minB!(y%)
  761.  
  762.         D% = maxX% - x%
  763.         crs! = (maxR!(y%) - cr!) / D%
  764.         cgs! = (maxG!(y%) - cg!) / D%
  765.         cbs! = (maxB!(y%) - cb!) / D%
  766.  
  767.         IF maxX% >= _WIDTH THEN maxX% = _WIDTH - 1
  768.  
  769.         IF x% < 0 THEN
  770.             cr! = cr! - crs! * x%
  771.             cg! = cg! - cgs! * x%
  772.             cb! = cb! - cbs! * x%
  773.             x% = 0
  774.         END IF
  775.  
  776.         WHILE x% <= maxX%
  777.             PSET (x%, y%), _RGB(CINT(cr!) AND &HFF, CINT(cg!) AND &HFF, CINT(cb!) AND &HFF)
  778.             x% = x% + 1
  779.             cr! = cr! + crs!
  780.             cg! = cg! + cgs!
  781.             cb! = cb! + cbs!
  782.         WEND
  783.     NEXT
  784.  
  785. '=== Make a linear gradient along the vertical axis of an edge ===
  786. SUB gMark (x1%, y1%, x2%, y2%, cr1%, cg1%, cb1%, cr2%, cg2%, cb2%)
  787.     D% = y2% - y1%
  788.     IF y1% < y2% THEN
  789.         x! = x1%
  790.         y% = y1%
  791.         cr! = cr1%
  792.         cg! = cg1%
  793.         cb! = cb1%
  794.         maxY% = y2%
  795.     ELSE
  796.         x! = x2%
  797.         y% = y2%
  798.         cr! = cr2%
  799.         cg! = cg2%
  800.         cb! = cb2%
  801.         maxY% = y1%
  802.     END IF
  803.  
  804.     sx! = (x2% - x1%) / D%
  805.     crs! = (cr2% - cr1%) / D%
  806.     cgs! = (cg2% - cg1%) / D%
  807.     cbs! = (cb2% - cb1%) / D%
  808.  
  809.     IF maxY% >= _HEIGHT THEN maxY% = _HEIGHT - 1
  810.  
  811.     IF y% < 0 THEN
  812.         x! = x! - sx! * y%
  813.         cr! = cr! - crs! * y%
  814.         cg! = cg! - cgs! * y%
  815.         cb! = cb! - cbs! * y%
  816.         y% = 0
  817.     END IF
  818.  
  819.     WHILE y% <= maxY%
  820.         x% = CINT(x!)
  821.         IF minX%(y%) > x% THEN
  822.             minX%(y%) = x%
  823.             minR!(y%) = cr!
  824.             minG!(y%) = cg!
  825.             minB!(y%) = cb!
  826.         END IF
  827.         IF maxX%(y%) < x% THEN
  828.             maxX%(y%) = x%
  829.             maxR!(y%) = cr!
  830.             maxG!(y%) = cg!
  831.             maxB!(y%) = cb!
  832.         END IF
  833.         y% = y% + 1
  834.         x! = x! + sx!
  835.         cr! = cr! + crs!
  836.         cg! = cg! + cgs!
  837.         cb! = cb! + cbs!
  838.     WEND
  839.  
  840. SUB GetRegion (p AS PolyRec, ix, iy, pic%())
  841.     '* my failed attempt at capturing a screen region so only regions of screen have to be redrawn
  842.     x1 = SetToMinMax(p.px - p.radius, p.radius, _WIDTH - p.radius)
  843.     y1 = SetToMinMax(p.py - p.radius, p.radius, _HEIGHT - p.radius)
  844.     x2 = SetToMinMax(p.px + p.radius, x1 + p.radius, _WIDTH - p.radius)
  845.     y2 = SetToMinMax(p.py + p.radius, y1 + p.radius, _HEIGHT - p.radius)
  846.     GET (x, y)-(x + p.radius, y + p.radius), pic%(ix, iy, 1)
  847.     'GET (x, y)-STEP(2 * p.radius, 2 * p.radius), pic%(ix,iy,1)
  848.  
  849. SUB PutRegion (p AS PolyRec, ix, iy, pic%())
  850.     '* my failed attempt at redrawing a screen region so only regions of screen have to be redrawn
  851.     x1 = SetToMinMax(p.px - p.radius, p.radius, _WIDTH - p.radius)
  852.     y1 = SetToMinMax(p.py - p.radius, p.radius, _HEIGHT - p.radius)
  853.     x2 = SetToMinMax(p.px + p.radius, x1 + p.radius, _WIDTH - p.radius)
  854.     y2 = SetToMinMax(p.py + p.radius, y1 + p.radius, _HEIGHT - p.radius)
  855.     PUT (x1, y1), pic%(ix, iy, 1), PSET
  856.  
  857. SUB PrintLocate (row, col, what$, whatcolor, gotonextline, doinput, ret$)
  858.     LOCATE row, col
  859.     COLOR whatcolor
  860.     PRINT what$;
  861.     IF doinput THEN
  862.         LINE INPUT ret$
  863.     END IF
  864.     IF gotonextline THEN PRINT
  865.  
« Last Edit: March 05, 2018, 07:45:29 pm by codeguy »

Offline codeguy

  • Forum Regular
  • Posts: 174
Re: Psychedelic Star Swirl
« Reply #8 on: March 05, 2018, 07:53:19 pm »
cool spinning spiral stars :). Indeed, psychedelic.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Psychedelic Star Swirl
« Reply #9 on: March 06, 2018, 12:15:16 am »
Hi codeguy,

I looked at your 800 line plus beautiful monster in post above...

maybe you don't need any more psychedelic?   ;-))

Offline codeguy

  • Forum Regular
  • Posts: 174
Re: Psychedelic Star Swirl
« Reply #10 on: March 06, 2018, 12:33:38 am »
Quote
Posted by: bplus
« on: Today at 02:15:16 AM »

Hi codeguy,

I looked at your 800 line plus beautiful monster in post above...

maybe you don't need any more psychedelic?   ;-))

LMBO. No psychedelics for me except on-screen. I like my brain unaltered.
:) :) :) :^)
« Last Edit: March 06, 2018, 12:36:36 am by codeguy »