Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - The Librarian

Pages: 1 [2] 3
16
Games / WideScreen Asteroids by TerryRitchie
« on: February 29, 2020, 10:48:03 pm »
WideScreen Asteroids

Author: @TerryRitchie
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=2157.0
Version: 2020
Tags: [2d], [game], [asteroids]

Description:
' This is NOT a clone of the original Asteroids coin-op game.
'
' Differences:  - Widescreen format

'               - Hyperspace opens a black hole to create a worm
'                 hole. All asteroids on the screen are pulled
'                 toward the vortex by gravity. Using hyperspace
'                 is very dangerous because it speeds up
'                 asteroids and draws them toward the player
'                 upon re-entry. Once hyperspace is used it can't
'                 be used again for 10 seconds.

'               - Particle effects when objects are hit. The player
'                 ship, UFOs, and small asteroids also disintegrate
'                 into individual pieces upon collision.

'               - The ship emits an exhaust trail behind it when
'                 thrusting.

'               - The game starts out with 5 large asteroids and
'                 maxes out at 16 large asteroids.

'               - Only the small UFO will appear if the game
'                 believes the player is saucer hunting. It will
'                 attempt to clear the remaining asteroids to force
'                 player to the next wave.

'               - Small UFOs get more accurate and shoot more
'                 often as waves progress.

'               - Advancing to the next wave is done through a
'                 warping sequence.

'               - A background star field moves in synch with the
'                 player's ship. As waves progress the star field
'                 begins to advance forward as well. This gives
'                 the illusion of asteroids moving faster than they
'                 really are.


' Features:     - A menu with player selectable options.

'               - All keyboard key inputs can be defined.

'               - Pixel perfect collision detection. You can
'                 literally roll the ship around asteroids.

'               - Mute and pause keys.

'               - Background ambient sci-fi sound.

'               - Player selectable full screen or windowed mode.


Source Code:
See download(s) below.

asteroids.png

17
Utilities / SafeLoadFont (preserve cursor position) by SMcNeill
« on: August 27, 2019, 09:57:41 pm »
SafeLoadFont (preserve cursor position)

Contributor(s): @SMcNeill
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=1597.msg108787#msg108787
Tags: [font]

Description:
Safely loads a font without destroying our current print location and making it revert to the top left corner.

Source Code:
Code: QB64: [Select]
  1. DIM fonts(3) AS LONG
  2. SCREEN _NEWIMAGE(640, 480, 32)
  3.  
  4. font(0) = _LOADFONT("cour.ttf", 16, "monospace")
  5. font(1) = _LOADFONT("courbd.ttf", 16, "monospace")
  6. font(2) = _LOADFONT("courbi.ttf", 16, "monospace")
  7. font(3) = _LOADFONT("couri.ttf", 16, "monospace")
  8.  
  9. PRINT "First, I want to showcase the exisinging issue with the _FONT command."
  10. PRINT "Let's start out typing something, and then pause before loading a"
  11. PRINT "new font..."
  12.  
  13. _FONT font(0)
  14. COLOR &HFFF00000, &HFFFFFF00
  15. slowprint "NOW WHERE IS OUR PRINT CURSOR AT??"
  16. CLS , 0
  17. COLOR -1, 0
  18.  
  19. PRINT "Now, let's try this same type of thing, while using SafeLoadFont"
  20. PRINT "We'll start typing something, and then pause before safe loading"
  21. PRINT "a new font..."
  22.  
  23.  
  24. slowprint "Slowly watch what happens to our print cursor "
  25. SafeLoadFont font(1)
  26. slowprint "as we use SafeLoadFont to change "
  27. SafeLoadFont font(2)
  28. slowprint "fonts while happily printing to "
  29. SafeLoadFont 16
  30. slowprint "the screen, without a concern in the world! "
  31. PRINT "Now, isn't that something?!"
  32.  
  33.  
  34. SUB slowprint (text$)
  35.     FOR i = 1 TO LEN(text$)
  36.         PRINT MID$(text$, i, 1);
  37.         _LIMIT 5
  38.     NEXT
  39.  
  40. SUB SafeLoadFont (font#)
  41.     'Safely loads a font without destroying our current print location and making it revert to the top left corner.
  42.  
  43.     down = CSRLIN: right = POS(0)
  44.     down = (down - 1) * _FONTHEIGHT
  45.     IF _FONTWIDTH <> 0 THEN 'we start with a monospace font
  46.         right = (right - 1) * _PRINTWIDTH(" ") 'convert the monospace LOC to a graphic X coordinate
  47.     END IF
  48.     _FONT font#
  49.     IF _FONTWIDTH <> 0 THEN 'we swapped to a monospace font
  50.         right = (right / _PRINTWIDTH(" ")) + 1 'convert the graphic X coordinate back to a monospace LOC column
  51.     END IF
  52.     down = (down / _FONTHEIGHT) + 1
  53.     IF right < 1 THEN right = 1
  54.     LOCATE down, right
  55.  

screenshot.PNG

18
Utilities / SaveImage (take screenshots) by SMcNeill
« on: August 24, 2019, 05:38:01 pm »
SaveImage

Contributor(s): @SMcNeill
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=2701.0
Tags: [bmp] [export] [gif] [graphics] [jpg] [png] [zlib]

Description:
How to save a QB64 screen image in either BMP or PNG format; how one can easily turn a text screen into a 256 color graphic screen with one simple command; and how to compress and inflate strings or programs quickly and easily.
There's a lot of stuff packaged inside the library here, but the main ones which a user might decide to call is the following:
FUNCTION SaveImage (file$, image&, x1%, y1%, x2%, y2%) 
SUB SaveFullImage (filename$)
SUB SaveFullBMP (filename$)
SUB SaveFullJPG (filename$)
SUB SaveBMP (filename$, image&, x1%, y1%, x2%, y2%)
FUNCTION TextScreenToImage256& (image&)
FUNCTION TextScreenToImage32& (image&)
FUNCTION Deflate$ (text$) 
FUNCTION Inflate$ (text$)
FUNCTION PNGExport (file$, imagehandle%, x1%, y1%, x2%, y2%) 
SUB SaveJPG (file$, image&, startx, starty, finishx, finishy)

As you can see, most of these routines can easily be handled by simply using FUNCTION SaveImage, which then decides if it needs to convert from a text screen to a graphic screen, and which save routine to make use of.


Source Code:
Code: QB64: [Select]
  1. '$INCLUDE:'SaveImage.BI'
  2.  
  3. CONST SaveTextAs256Color = 0 'Flag to Save as 256 color file or 32-bit color file, when converting SCREEN 0 to an image
  4. '                             Set to TRUE (any non-zero value) to save text screens in 256 color mode.
  5. '                             Set to FALSE (zero) to save text screens in 32-bit color mode.
  6.  
  7.  
  8. 'CONST ConvertToStandard256Palette = 0
  9. '                             Set the value to 0 (FALSE) to preseve the color information perfectly, using its default palette.
  10. '                             If the CONST is set (TRUE), then we convert our colors to as close of a match as possible, while
  11. '                             preserving the standard QB64 256-color palette.
  12. '                             Commented here, simply to help folks know that it exists for use when converting a 32 bit image
  13. '                             down to 256 colors, such as what the GIF routine has to do for us (GIFs are limited to 256 color images)
  14.  
  15. SCREEN _NEWIMAGE(1280, 720, 32)
  16. DIM exportimage(4) AS STRING
  17. InitialImage$ = "Volcano Logo.jpg"
  18. exportimage(1) = "testimage.png": exportimage(2) = "testimage.bmp"
  19. exportimage(3) = "testimage.jpg": exportimage(4) = "testimage.gif"
  20.  
  21. 'If you want to test the demo with a screen 0 image, then...
  22. l& = _LOADIMAGE(InitialImage$) 'Remark out this line
  23. '_PUTIMAGE , l& 'And remark the _PUTIMAGE line down below as well
  24.  
  25. 'And unremark the following
  26. 'SCREEN 0
  27. 'FOR i = 0 TO 15
  28. '    COLOR i
  29. '    PRINT "COLOR i"
  30. 'NEXT
  31. 'Then you can watch as we prove that we can save images while in Screen 0 TEXT mode.
  32. FOR i = 1 TO 4
  33.     _PUTIMAGE , l& 'Remark out this line, if you want to see the SCREEN 0 demo
  34.     LOCATE 1, 1
  35.     Result = SaveImage(exportimage(i), 0, 0, 0, _WIDTH - 1, _HEIGHT - 1)
  36.     IF Result = 1 THEN 'file already found on drive
  37.         KILL exportimage(i) 'delete the old file
  38.         Result = SaveImage(exportimage(i), 0, 0, 0, _WIDTH - 1, _HEIGHT - 1) 'save the new one again
  39.     END IF
  40.     PRINT Result
  41.     IF Result < 0 THEN PRINT "Successful " + exportimage(i) + " export" ELSE PRINT ext$ + " Export failed with Error Code:"; Result: ' END
  42.     SLEEP
  43.  
  44. FOR i = 1 TO 4
  45.     zz& = _LOADIMAGE(exportimage(i), 32)
  46.     IF zz& <> -1 THEN
  47.         SCREEN zz&
  48.         PRINT "Image Handle: "; zz&, exportimage(i)
  49.         PRINT "Successful Import using _LOADIMAGE"
  50.     ELSE
  51.         PRINT "ERROR - Not Loading the new image (" + exportimage(i) + ") with _LOADIMAGE."
  52.     END IF
  53.     SLEEP
  54.  
  55.  
  56. '$INCLUDE:'SaveImage.BM'
  57.  

Volcano Logo.jpg

Check out the latest update at the author's Project File in the URL above.
 
 

19
Utilities / ImageToData (and back) by SMcNeill
« on: August 18, 2019, 12:38:36 am »
ImageToData (and back)

Contributor(s): @SMcNeill
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=1553.0
Tags: [data] [graphics] [mem]

Description:
The MemImageToData is a specialized version of MemToHex which takes a _MEMIMAGE and converts it to Hex, while placing the DATA statement in front of it for us, for quick use pasting it into another program.  It basically lets us store image files inside a BAS file, without needing to _LOADIMAGE them externally.

Source Code:
Code: QB64: [Select]
  1. ' Set graphics mode.
  2. SCREEN _NEWIMAGE(640, 480, 32)
  3.  
  4. ' Prepare mem block(s) and image(s).
  5. t = _NEWIMAGE(16, 16, 32)
  6. m = _MEMIMAGE(t)
  7.  
  8. ' Send colored pixels to the destination "t".
  9. CIRCLE (8, 8), 7, -1
  10. PAINT (8, 8), -1
  11.  
  12. ' --> So far, nothing has appeared on the screen! <--
  13.  
  14. ' Copy the contents of "t" to the clipboard and display the result.
  15. _CLIPBOARD$ = MemImagetoDATA$(m, "t", 160)
  16.  
  17.  
  18. COLOR _RGB(255, 255, 255)
  19. PRINT "Hex representation of a small filled circle:": PRINT
  20. COLOR _RGB(155, 155, 155)
  21. PRINT "... etc. etc. ..."
  22. COLOR _RGB(255, 255, 255)
  23. PRINT "This information is already contained in the DATA statements in this program."
  24. PRINT "Press any key to convert this data back to an image."
  25.  
  26.  
  27. ' Restore using the proper label associated with the data.
  28. RESTORE TheDataLabel
  29.  
  30. ' Create and display a new image using the data.
  31. t1 = DATAtoImage
  32. _PUTIMAGE (320, 400), t1
  33.  
  34.  
  35. TheDataLabel:
  36. DATA 16,16,4
  37. DATA 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  38. DATA FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000
  39. DATA 0000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  40. DATA FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  41. DATA 00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  42. DATA FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000
  43. DATA 000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000
  44.  
  45. FUNCTION DATAtoImage&
  46.     'Requires a RESTORE label for the proper data BEFORE calling this routine
  47.     READ w, h, ps
  48.     SELECT CASE ps
  49.         CASE 1: ps = 256 '256 color screen
  50.         CASE 2: ps = 0 'text screen
  51.         CASE 4: ps = 32 '32-bit color screen
  52.     END SELECT
  53.     DATAtoImage& = _NEWIMAGE(w, h, ps)
  54.     DIM m AS _MEM
  55.     m = _MEMIMAGE(DATAtoImage&)
  56.     DO
  57.         READ hx$
  58.         FOR i = 1 TO LEN(hx$) STEP 2
  59.             h = VAL("&H" + MID$(hx$, i, 2))
  60.             _MEMPUT m, m.OFFSET + o, h
  61.             o = o + 1
  62.         NEXT
  63.         LOCATE 1, 1: PRINT o, m.SIZE
  64.     LOOP UNTIL o >= m.SIZE
  65.     _MEMFREE m
  66.  
  67. FUNCTION MemImagetoDATA$ (m AS _MEM, label$, break)
  68.     s = ConvertOffset(m.SIZE) - 1
  69.     label$ = _TRIM$(label$)
  70.     IF label$ = "" THEN label$ = "generic_label_placeholder:"
  71.     IF RIGHT$(label$, 1) <> ":" THEN label$ = label$ + ":"
  72.     MemImagetoDATA$ = label$ + CHR$(10) + "DATA "
  73.     MemImagetoDATA$ = MemImagetoDATA$ + STR$(_WIDTH(m.IMAGE)) + ", "
  74.     MemImagetoDATA$ = MemImagetoDATA$ + STR$(_HEIGHT(m.IMAGE)) + ", "
  75.     MemImagetoDATA$ = MemImagetoDATA$ + STR$(_PIXELSIZE(m.IMAGE)) + CHR$(10) + "DATA "
  76.     FOR i = 0 TO s
  77.         _MEMGET m, m.OFFSET + i, b
  78.         h$ = HEX$(b)
  79.         IF LEN(h$) = 1 THEN h$ = "0" + h$
  80.         MemImagetoDATA$ = MemImagetoDATA$ + h$
  81.         IF i MOD break = break - 1 AND i < s THEN
  82.             MemImagetoDATA$ = MemImagetoDATA$ + CHR$(10) + "DATA "
  83.         END IF
  84.     NEXT
  85.  
  86. FUNCTION ConvertOffset&& (value AS _OFFSET)
  87.     DIM m AS _MEM 'Define a memblock
  88.     m = _MEM(value) 'Point it to use value
  89.     $IF 64BIT THEN
  90.         'On 64 bit OSes, an OFFSET is 8 bytes in size.  We can put it directly into an Integer64
  91.         _MEMGET m, m.OFFSET, ConvertOffset&& 'Get the contents of the memblock and put the values there directly into ConvertOffset&&
  92.     $ELSE
  93.         'However, on 32 bit OSes, an OFFSET is only 4 bytes.  We need to put it into a LONG variable first
  94.         _MEMGET m, m.OFFSET, temp& 'Like this
  95.         ConvertOffset&& = temp& 'And then assign that long value to ConvertOffset&&
  96.     $END IF
  97.     _MEMFREE m 'Free the memblock
  98.  

screenshot.png


20
Utilities / MemToHex (and HexToMem) by SMcNeill
« on: August 17, 2019, 11:50:23 pm »
MemToHex (and HexToMem)

Contributor(s): @SMcNeill
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=1553.0
Tags: [hex] [mem]

Description:
With these, we can convert ANY memblock into a sequence of HEX values (which makes them excellent to paste into another program as DATA statements), and then we can take those hex values and convert them back into a memblock.

Source Code:
Code: QB64: [Select]
  1. ' The string to be processed should have known length.
  2. ' or:
  3. ' Change 12 to a higher number and the HEX representation stores the trailing whitespace.
  4. ' Trailing whitespace in an ordinary string can be truncated using RTRIM$().
  5. DIM TheString AS STRING * 12
  6. TheString = "Hello World!"
  7.  
  8. ' Prepare MEM block.
  9. DIM m AS _MEM: m = _MEM(TheString)
  10.  
  11. ' Convert string to HEX and print.
  12. Hx$ = MemToHex(m)
  13. PRINT Hx$
  14.  
  15. ' Overwrite string.
  16. TheString = "Overwritten?"
  17. PRINT TheString
  18.  
  19. ' Restore string from MEM and print the result.
  20. HexToMem Hx$, m
  21. PRINT TheString; "..."
  22. 'PRINT RTRIM$(TheString); "..."
  23.  
  24. ' Free the memblock (redundant at END but good practice).
  25.  
  26. FUNCTION MemToHex$ (m AS _MEM)
  27.     s = ConvertOffset(m.SIZE) - 1
  28.     FOR i = 0 TO s
  29.         _MEMGET m, m.OFFSET + i, b
  30.         h$ = HEX$(b)
  31.         IF LEN(h$) = 1 THEN h$ = "0" + h$
  32.         MemToHex$ = MemToHex$ + h$
  33.     NEXT
  34.  
  35. SUB HexToMem (hx$, m AS _MEM)
  36.     DIM i AS _INTEGER64
  37.     FOR i = 1 TO LEN(hx$) STEP 2
  38.         h = VAL("&H" + MID$(hx$, i, 2))
  39.         _MEMPUT m, m.OFFSET + i \ 2, h
  40.     NEXT
  41.  
  42. FUNCTION ConvertOffset&& (value AS _OFFSET)
  43.     DIM m AS _MEM 'Define a memblock
  44.     m = _MEM(value) 'Point it to use value
  45.     $IF 64BIT THEN
  46.         ' On 64 bit OSes, an OFFSET is 8 bytes in size. We can put it directly into an Integer64.
  47.         _MEMGET m, m.OFFSET, ConvertOffset&& ' Get the contents of the memblock and put the values there directly into ConvertOffset&&.
  48.     $ELSE
  49.         'However, on 32 bit OSes, an OFFSET is only 4 bytes. We need to put it into a LONG variable first.
  50.         _MEMGET m, m.OFFSET, temp& ' Like this:
  51.         ConvertOffset&& = temp& ' And then assign that long value to ConvertOffset&&.
  52.     $END IF
  53.     _MEMFREE m ' Free the memblock.
  54.  

screenshot.png

21
2D/3D Graphics / Sanctum 3D World by STxAxTIC
« on: August 13, 2019, 09:53:46 pm »
Sanctum 3D World

Author: STxAxTIC
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=1600.0
Version: QB64
Tags: [3d] [graphics] [open world]

Description:
Sanctum is an open world 3D engine that makes everything from CIRCLE and LINE. Suggested left hand on "WSAD", and right hand on numeric keypad (hybrid gamer setup)... Discover heaven, discover hell, find the pyramid, find the megalith, blow up the moon, play with blocks.

Source Code:
Code: QB64: [Select]
  1. '$EXEICON:'sanctum.ico'
  2. 'REM $include:'Color32.BI'
  3.  
  4. CONST Aquamarine = _RGB32(127, 255, 212)
  5. CONST Blue = _RGB32(0, 0, 255)
  6. CONST BlueViolet = _RGB32(138, 43, 226)
  7. CONST Chocolate = _RGB32(210, 105, 30)
  8. CONST Cyan = _RGB32(0, 255, 255)
  9. CONST DarkBlue = _RGB32(0, 0, 139)
  10. CONST DarkGoldenRod = _RGB32(184, 134, 11)
  11. CONST DarkGray = _RGB32(169, 169, 169)
  12. CONST DarkKhaki = _RGB32(189, 183, 107)
  13. CONST DeepPink = _RGB32(255, 20, 147)
  14. CONST DodgerBlue = _RGB32(30, 144, 255)
  15. CONST ForestGreen = _RGB32(34, 139, 34)
  16. CONST Gray = _RGB32(128, 128, 128)
  17. CONST Green = _RGB32(0, 128, 0)
  18. CONST Indigo = _RGB32(75, 0, 130)
  19. CONST Ivory = _RGB32(255, 255, 240)
  20. CONST LightSeaGreen = _RGB32(32, 178, 170)
  21. CONST Lime = _RGB32(0, 255, 0)
  22. CONST LimeGreen = _RGB32(50, 205, 50)
  23. CONST Magenta = _RGB32(255, 0, 255)
  24. CONST PaleGoldenRod = _RGB32(238, 232, 170)
  25. CONST Purple = _RGB32(128, 0, 128)
  26. CONST Red = _RGB32(255, 0, 0)
  27. CONST RoyalBlue = _RGB32(65, 105, 225)
  28. CONST SaddleBrown = _RGB32(139, 69, 19)
  29. CONST Sienna = _RGB32(160, 82, 45)
  30. CONST SlateGray = _RGB32(112, 128, 144)
  31. CONST Snow = _RGB32(255, 250, 250)
  32. CONST Sunglow = _RGB32(255, 207, 72)
  33. CONST SunsetOrange = _RGB32(253, 94, 83)
  34. CONST Teal = _RGB32(0, 128, 128)
  35. CONST White = _RGB32(255, 255, 255)
  36. CONST Yellow = _RGB32(255, 255, 0)
  37.  
  38. ' Constants.
  39. pi = 3.1415926536
  40. ee = 2.7182818285
  41.  
  42. ' Scale.
  43. DIM bignumber AS LONG
  44. bignumber = 3000000
  45.  
  46. ' Video.
  47. 'SCREEN _NEWIMAGE(640, 480, 32)
  48. SCREEN _NEWIMAGE(800, 600, 32)
  49. 'SCREEN _NEWIMAGE(1024, 768, 32)
  50. screenwidth = _WIDTH
  51. screenheight = _HEIGHT
  52.  
  53. ' Camera orientation vectors.
  54. DIM uhat(3), vhat(3), nhat(3)
  55.  
  56. ' Basis vectors defined in three-space.
  57. DIM xhat(3), yhat(3), zhat(3)
  58. xhat(1) = 1: xhat(2) = 0: xhat(3) = 0
  59. yhat(1) = 0: yhat(2) = 1: yhat(3) = 0
  60. zhat(1) = 0: zhat(2) = 0: zhat(3) = 1
  61.  
  62. ' Group structure.
  63. TYPE VectorGroupElement
  64.     Identity AS LONG
  65.     Pointer AS LONG
  66.     Lagger AS LONG
  67.     FirstVector AS LONG
  68.     LastVector AS LONG
  69.     GroupName AS STRING * 50
  70.     Visible AS INTEGER
  71.     ForceAnimate AS INTEGER
  72.     COMFixed AS INTEGER
  73.     COMx AS SINGLE ' Center of mass
  74.     COMy AS SINGLE
  75.     COMz AS SINGLE
  76.     ROTx AS SINGLE ' Center of rotation
  77.     ROTy AS SINGLE
  78.     ROTz AS SINGLE
  79.     REVx AS SINGLE ' Revolution speed
  80.     REVy AS SINGLE
  81.     REVz AS SINGLE
  82.     DIMx AS SINGLE ' Maximum volume
  83.     DIMy AS SINGLE
  84.     DIMz AS SINGLE
  85. DIM VectorGroup(bignumber) AS VectorGroupElement
  86.  
  87. ' World vectors.
  88. DIM vec(bignumber, 3) ' Relative Position
  89. DIM vec3Dpos(bignumber, 3) ' Position
  90. DIM vec3Dvel(bignumber, 3) ' Linear velocity
  91. DIM vec3Dacc(bignumber, 3) ' Linear acceleration
  92. DIM vec3Danv(bignumber, 3) ' Angular velocity
  93. DIM vec3Dvis(bignumber) ' Visible toggle
  94. DIM vec2D(bignumber, 2) ' Projection onto 2D plane
  95. DIM vec3Dcolor(bignumber) AS LONG ' Original color
  96. DIM vec2Dcolor(bignumber) AS LONG ' Projected color
  97.  
  98. ' Clipping planes.
  99. DIM nearplane(4), farplane(4), rightplane(4), leftplane(4), topplane(4), bottomplane(4)
  100.  
  101. ' State.
  102. nearplane(4) = 1
  103. farplane(4) = -100
  104. rightplane(4) = 0 '*' fovd * (nhat(1) * rightplane(1) + nhat(2) * rightplane(2) + nhat(3) * rightplane(3))
  105. leftplane(4) = 0
  106. topplane(4) = 0
  107. bottomplane(4) = 0
  108. midscreenx = screenwidth / 2
  109. midscreeny = screenheight / 2
  110. fovd = -256
  111. numgroupvisible = 0
  112. numvectorvisible = 0
  113. groupidticker = 0
  114. vecgroupid = 0
  115. vectorindex = 0
  116. rotspeed = 1 / 33
  117. linspeed = 3 / 2
  118. timestep = .001
  119. camx = -40
  120. camy = 30
  121. camz = 40
  122. uhat(1) = -.2078192: uhat(2) = -.9781672: uhat(3) = 0
  123. vhat(1) = 0: vhat(2) = 0: vhat(3) = 1
  124. toggletimeanimate = 1
  125. toggleinvertmouse = -1
  126. togglehud = 1
  127.  
  128. ' Prime main loop.
  129. GOSUB initialize.objects
  130. GOSUB redraw
  131.  
  132. ' Begin main loop.
  133. fpstimer = INT(TIMER)
  134. fps = 0
  135.     GOSUB redraw
  136.     GOSUB mouseprocess
  137.     GOSUB keyprocess
  138.  
  139.     fps = fps + 1
  140.     tt = INT(TIMER)
  141.     IF tt = fpstimer + 1 THEN
  142.         fpstimer = tt
  143.         fpsreport = fps
  144.         fps = 0
  145.     END IF
  146.  
  147.     _DISPLAY
  148.     _KEYCLEAR
  149.     _LIMIT 30
  150.  
  151.  
  152. ' Gosubs.
  153.  
  154. redraw:
  155. GOSUB normalize.screen.vectors
  156. GOSUB calculate.clippingplanes
  157. GOSUB compute.visible.groups
  158. GOSUB plot.visible.vectors
  159.  
  160. mouseprocess:
  161. 'mx = 0
  162. 'my = 0
  163. 'DO WHILE _MOUSEINPUT
  164. '    mx = mx + _MOUSEMOVEMENTX
  165. '    my = my + _MOUSEMOVEMENTY
  166. '    IF _MOUSEWHEEL > 0 THEN GOSUB rotate.clockwise
  167. '    IF _MOUSEWHEEL < 0 THEN GOSUB rotate.counterclockwise
  168. '    IF mx > 0 THEN
  169. '        GOSUB rotate.uhat.plus: GOSUB normalize.screen.vectors
  170. '    END IF
  171. '    IF mx < 0 THEN
  172. '        GOSUB rotate.uhat.minus: GOSUB normalize.screen.vectors
  173. '    END IF
  174. '    IF my > 0 THEN
  175. '        IF toggleinvertmouse = -1 THEN
  176. '            GOSUB rotate.vhat.plus: GOSUB normalize.screen.vectors
  177. '        ELSE
  178. '            GOSUB rotate.vhat.minus: GOSUB normalize.screen.vectors
  179. '        END IF
  180. '    END IF
  181. '    IF my < 0 THEN
  182. '        IF toggleinvertmouse = -1 THEN
  183. '            GOSUB rotate.vhat.minus: GOSUB normalize.screen.vectors
  184. '        ELSE
  185. '            GOSUB rotate.vhat.plus: GOSUB normalize.screen.vectors
  186. '        END IF
  187. '    END IF
  188. '    mx = 0
  189. '    my = 0
  190. 'LOOP
  191.  
  192. keyprocess:
  193. IF _KEYDOWN(119) = -1 OR _KEYDOWN(18432) = -1 THEN GOSUB strafe.camera.nhat.minus ' w or uparrow
  194. IF _KEYDOWN(115) = -1 OR _KEYDOWN(20480) = -1 THEN GOSUB strafe.camera.nhat.plus ' s or downarrow
  195. IF _KEYDOWN(97) = -1 THEN GOSUB strafe.camera.uhat.minus ' a
  196. IF _KEYDOWN(100) = -1 THEN GOSUB strafe.camera.uhat.plus ' d
  197. IF _KEYDOWN(56) = -1 THEN GOSUB rotate.vhat.plus: GOSUB normalize.screen.vectors ' 8
  198. IF _KEYDOWN(50) = -1 THEN GOSUB rotate.vhat.minus: GOSUB normalize.screen.vectors ' 2
  199. IF _KEYDOWN(19200) = -1 OR _KEYDOWN(52) = -1 THEN GOSUB rotate.uhat.minus: GOSUB normalize.screen.vectors ' 4
  200. IF _KEYDOWN(19712) = -1 OR _KEYDOWN(54) = -1 THEN GOSUB rotate.uhat.plus: GOSUB normalize.screen.vectors ' 6
  201. IF _KEYDOWN(55) = -1 THEN GOSUB rotate.clockwise ' 7
  202. IF _KEYDOWN(57) = -1 THEN GOSUB rotate.counterclockwise ' 9
  203. IF _KEYDOWN(49) = -1 THEN GOSUB rotate.uhat.minus: GOSUB normalize.screen.vectors: GOSUB rotate.clockwise ' 1
  204. IF _KEYDOWN(51) = -1 THEN GOSUB rotate.uhat.plus: GOSUB normalize.screen.vectors: GOSUB rotate.counterclockwise ' 3
  205. IF _KEYDOWN(113) = -1 THEN GOSUB strafe.camera.vhat.minus ' q
  206. IF _KEYDOWN(101) = -1 THEN GOSUB strafe.camera.vhat.plus ' e
  207.  
  208. IF (key$ <> "") THEN
  209.     SELECT CASE key$
  210.         CASE "x"
  211.             uhat(1) = 0: uhat(2) = 1: uhat(3) = 0
  212.             vhat(1) = 0: vhat(2) = 0: vhat(3) = 1
  213.         CASE "X"
  214.             uhat(1) = 0: uhat(2) = -1: uhat(3) = 0
  215.             vhat(1) = 0: vhat(2) = 0: vhat(3) = 1
  216.         CASE "y"
  217.             uhat(1) = -1: uhat(2) = 0: uhat(3) = 0
  218.             vhat(1) = 0: vhat(2) = 0: vhat(3) = 1
  219.         CASE "Y"
  220.             uhat(1) = 1: uhat(2) = 0: uhat(3) = 0
  221.             vhat(1) = 0: vhat(2) = 0: vhat(3) = 1
  222.         CASE "z"
  223.             uhat(1) = 1: uhat(2) = 0: uhat(3) = 0
  224.             vhat(1) = 0: vhat(2) = 1: vhat(3) = 0
  225.             GOSUB normalize.screen.vectors
  226.         CASE "Z"
  227.             uhat(1) = 0: uhat(2) = 1: uhat(3) = 0
  228.             vhat(1) = 1: vhat(2) = 0: vhat(3) = 0
  229.         CASE "]"
  230.             farplane(4) = farplane(4) - 1
  231.         CASE "["
  232.             farplane(4) = farplane(4) + 1
  233.         CASE " "
  234.             togglehud = -togglehud
  235.         CASE "t"
  236.             toggletimeanimate = -toggletimeanimate
  237.         CASE "i"
  238.             toggleinvertmouse = -toggleinvertmouse
  239.         CASE "v"
  240.             OPEN "snapshot-camera.txt" FOR OUTPUT AS #1
  241.             PRINT #1, camx, camy, camz
  242.             PRINT #1, uhat(1), uhat(2), uhat(3)
  243.             PRINT #1, vhat(1), vhat(2), vhat(3)
  244.             CLOSE #1
  245.         CASE CHR$(27)
  246.             SYSTEM
  247.         CASE "n"
  248.             VectorGroup(closestgroup).COMFixed = 1
  249.             FOR vectorindex = VectorGroup(closestgroup).FirstVector TO VectorGroup(closestgroup).LastVector
  250.                 vec3Dvel(vectorindex, 1) = (RND - .5) * 200
  251.                 vec3Dvel(vectorindex, 2) = (RND - .5) * 200
  252.                 vec3Dvel(vectorindex, 3) = (RND - .5) * 200
  253.             NEXT
  254.         CASE "k"
  255.             p = VectorGroup(closestgroup).Pointer
  256.             l = VectorGroup(closestgroup).Lagger
  257.             VectorGroup(l).Pointer = p
  258.             IF (p <> -999) THEN
  259.                 VectorGroup(p).Lagger = l
  260.             END IF
  261.         CASE "b"
  262.             tilesize = 5
  263.             ' Determine last object id.
  264.             p = 1
  265.             DO
  266.                 k = VectorGroup(p).Identity
  267.                 p = VectorGroup(k).Pointer
  268.                 IF (p = -999) THEN EXIT DO
  269.             LOOP
  270.             lastobjectid = k
  271.             vectorindex = VectorGroup(lastobjectid).LastVector
  272.             ' Create new group.
  273.             groupidticker = groupidticker + 1
  274.             vecgroupid = groupidticker
  275.             VectorGroup(vecgroupid).Identity = vecgroupid
  276.             VectorGroup(vecgroupid).Pointer = -999
  277.             VectorGroup(vecgroupid).Lagger = lastobjectid
  278.             VectorGroup(vecgroupid).GroupName = "Block"
  279.             VectorGroup(vecgroupid).Visible = 0
  280.             VectorGroup(vecgroupid).COMFixed = 1
  281.             VectorGroup(vecgroupid).DIMx = tilesize / 2
  282.             VectorGroup(vecgroupid).DIMy = tilesize / 2
  283.             VectorGroup(vecgroupid).DIMz = tilesize / 2
  284.             VectorGroup(vecgroupid).FirstVector = vectorindex + 1
  285.             FOR r = 1 TO 400
  286.                 vectorindex = vectorindex + 1
  287.                 vec3Dpos(vectorindex, 1) = camx + -20 * nhat(1) + (RND - .5) * tilesize
  288.                 vec3Dpos(vectorindex, 2) = camy + -20 * nhat(2) + (RND - .5) * tilesize
  289.                 vec3Dpos(vectorindex, 3) = camz + -20 * nhat(3) + (RND - .5) * tilesize
  290.                 vec3Dvis(vectorindex) = 0
  291.                 IF RND > .5 THEN
  292.                     vec3Dcolor(vectorindex) = Lime
  293.                 ELSE
  294.                     vec3Dcolor(vectorindex) = Purple
  295.                 END IF
  296.                 GOSUB integratecom
  297.             NEXT
  298.             VectorGroup(vecgroupid).LastVector = vectorindex
  299.             GOSUB calculatecom
  300.             VectorGroup(lastobjectid).Pointer = vecgroupid
  301.     END SELECT
  302.  
  303. convert:
  304. ' Convert graphics from uv-cartesian coordinates to monitor coordinates.
  305. x0 = x: y0 = y
  306. x = x0 + midscreenx
  307. y = -y0 + midscreeny
  308.  
  309. rotate.uhat.plus:
  310. uhat(1) = uhat(1) + nhat(1) * rotspeed
  311. uhat(2) = uhat(2) + nhat(2) * rotspeed
  312. uhat(3) = uhat(3) + nhat(3) * rotspeed
  313.  
  314. rotate.uhat.minus:
  315. uhat(1) = uhat(1) - nhat(1) * rotspeed
  316. uhat(2) = uhat(2) - nhat(2) * rotspeed
  317. uhat(3) = uhat(3) - nhat(3) * rotspeed
  318.  
  319. rotate.vhat.plus:
  320. vhat(1) = vhat(1) + nhat(1) * rotspeed
  321. vhat(2) = vhat(2) + nhat(2) * rotspeed
  322. vhat(3) = vhat(3) + nhat(3) * rotspeed
  323.  
  324. rotate.vhat.minus:
  325. vhat(1) = vhat(1) - nhat(1) * rotspeed
  326. vhat(2) = vhat(2) - nhat(2) * rotspeed
  327. vhat(3) = vhat(3) - nhat(3) * rotspeed
  328.  
  329. rotate.counterclockwise:
  330. v1 = vhat(1)
  331. v2 = vhat(2)
  332. v3 = vhat(3)
  333. vhat(1) = vhat(1) + uhat(1) * rotspeed
  334. vhat(2) = vhat(2) + uhat(2) * rotspeed
  335. vhat(3) = vhat(3) + uhat(3) * rotspeed
  336. uhat(1) = uhat(1) - v1 * rotspeed
  337. uhat(2) = uhat(2) - v2 * rotspeed
  338. uhat(3) = uhat(3) - v3 * rotspeed
  339.  
  340. rotate.clockwise:
  341. v1 = vhat(1)
  342. v2 = vhat(2)
  343. v3 = vhat(3)
  344. vhat(1) = vhat(1) - uhat(1) * rotspeed
  345. vhat(2) = vhat(2) - uhat(2) * rotspeed
  346. vhat(3) = vhat(3) - uhat(3) * rotspeed
  347. uhat(1) = uhat(1) + v1 * rotspeed
  348. uhat(2) = uhat(2) + v2 * rotspeed
  349. uhat(3) = uhat(3) + v3 * rotspeed
  350.  
  351. strafe.camera.uhat.plus:
  352. camx = camx + uhat(1) * linspeed
  353. camy = camy + uhat(2) * linspeed
  354. camz = camz + uhat(3) * linspeed
  355.  
  356. strafe.camera.uhat.minus:
  357. camx = camx - uhat(1) * linspeed
  358. camy = camy - uhat(2) * linspeed
  359. camz = camz - uhat(3) * linspeed
  360.  
  361. strafe.camera.vhat.plus:
  362. camx = camx + vhat(1) * linspeed
  363. camy = camy + vhat(2) * linspeed
  364. camz = camz + vhat(3) * linspeed
  365.  
  366. strafe.camera.vhat.minus:
  367. camx = camx - vhat(1) * linspeed
  368. camy = camy - vhat(2) * linspeed
  369. camz = camz - vhat(3) * linspeed
  370.  
  371. strafe.camera.nhat.plus:
  372. camx = camx + nhat(1) * linspeed
  373. camy = camy + nhat(2) * linspeed
  374. camz = camz + nhat(3) * linspeed
  375.  
  376. strafe.camera.nhat.minus:
  377. camx = camx - nhat(1) * linspeed
  378. camy = camy - nhat(2) * linspeed
  379. camz = camz - nhat(3) * linspeed
  380.  
  381. normalize.screen.vectors:
  382. uhatmag = SQR(uhat(1) * uhat(1) + uhat(2) * uhat(2) + uhat(3) * uhat(3))
  383. uhat(1) = uhat(1) / uhatmag: uhat(2) = uhat(2) / uhatmag: uhat(3) = uhat(3) / uhatmag
  384. vhatmag = SQR(vhat(1) * vhat(1) + vhat(2) * vhat(2) + vhat(3) * vhat(3))
  385. vhat(1) = vhat(1) / vhatmag: vhat(2) = vhat(2) / vhatmag: vhat(3) = vhat(3) / vhatmag
  386. uhatdotvhat = uhat(1) * vhat(1) + uhat(2) * vhat(2) + uhat(3) * vhat(3)
  387. ' The normal vector points toward the eye.
  388. nhat(1) = uhat(2) * vhat(3) - uhat(3) * vhat(2)
  389. nhat(2) = uhat(3) * vhat(1) - uhat(1) * vhat(3)
  390. nhat(3) = uhat(1) * vhat(2) - uhat(2) * vhat(1)
  391. nhatmag = SQR(nhat(1) * nhat(1) + nhat(2) * nhat(2) + nhat(3) * nhat(3))
  392. nhat(1) = nhat(1) / nhatmag: nhat(2) = nhat(2) / nhatmag: nhat(3) = nhat(3) / nhatmag
  393.  
  394. calculate.clippingplanes:
  395. ' Calculate normal vectors to all clipping planes.
  396. h2 = screenheight / 2
  397. w2 = screenwidth / 2
  398. nearplane(1) = -nhat(1)
  399. nearplane(2) = -nhat(2)
  400. nearplane(3) = -nhat(3)
  401. farplane(1) = nhat(1)
  402. farplane(2) = nhat(2)
  403. farplane(3) = nhat(3)
  404. rightplane(1) = h2 * fovd * uhat(1) - h2 * w2 * nhat(1)
  405. rightplane(2) = h2 * fovd * uhat(2) - h2 * w2 * nhat(2)
  406. rightplane(3) = h2 * fovd * uhat(3) - h2 * w2 * nhat(3)
  407. mag = SQR(rightplane(1) * rightplane(1) + rightplane(2) * rightplane(2) + rightplane(3) * rightplane(3))
  408. rightplane(1) = rightplane(1) / mag
  409. rightplane(2) = rightplane(2) / mag
  410. rightplane(3) = rightplane(3) / mag
  411. leftplane(1) = -h2 * fovd * uhat(1) - h2 * w2 * nhat(1)
  412. leftplane(2) = -h2 * fovd * uhat(2) - h2 * w2 * nhat(2)
  413. leftplane(3) = -h2 * fovd * uhat(3) - h2 * w2 * nhat(3)
  414. mag = SQR(leftplane(1) * leftplane(1) + leftplane(2) * leftplane(2) + leftplane(3) * leftplane(3))
  415. leftplane(1) = leftplane(1) / mag
  416. leftplane(2) = leftplane(2) / mag
  417. leftplane(3) = leftplane(3) / mag
  418. topplane(1) = w2 * fovd * vhat(1) - h2 * w2 * nhat(1)
  419. topplane(2) = w2 * fovd * vhat(2) - h2 * w2 * nhat(2)
  420. topplane(3) = w2 * fovd * vhat(3) - h2 * w2 * nhat(3)
  421. mag = SQR(topplane(1) * topplane(1) + topplane(2) * topplane(2) + topplane(3) * topplane(3))
  422. topplane(1) = topplane(1) / mag
  423. topplane(2) = topplane(2) / mag
  424. topplane(3) = topplane(3) / mag
  425. bottomplane(1) = -w2 * fovd * vhat(1) - h2 * w2 * nhat(1)
  426. bottomplane(2) = -w2 * fovd * vhat(2) - h2 * w2 * nhat(2)
  427. bottomplane(3) = -w2 * fovd * vhat(3) - h2 * w2 * nhat(3)
  428. mag = SQR(bottomplane(1) * bottomplane(1) + bottomplane(2) * bottomplane(2) + bottomplane(3) * bottomplane(3))
  429. bottomplane(1) = bottomplane(1) / mag
  430. bottomplane(2) = bottomplane(2) / mag
  431. bottomplane(3) = bottomplane(3) / mag
  432.  
  433. compute.visible.groups:
  434. closestdist2 = 10000000
  435. closestgroup = 1
  436. fp42 = farplane(4) * farplane(4)
  437.  
  438. k = 1
  439. k = VectorGroup(k).Identity
  440. DO ' iterates k
  441.  
  442.     VectorGroup(k).Visible = 0
  443.  
  444.     dx = VectorGroup(k).COMx - camx
  445.     dy = VectorGroup(k).COMy - camy
  446.     dz = VectorGroup(k).COMz - camz
  447.  
  448.     dist2 = dx * dx + dy * dy + dz * dz
  449.  
  450.     IF dist2 < fp42 THEN
  451.  
  452.         groupinview = 1
  453.         IF dx * nearplane(1) + dy * nearplane(2) + dz * nearplane(3) - nearplane(4) < 0 THEN groupinview = 0
  454.         'IF dx * farplane(1) + dy * farplane(2) + dz * farplane(3) - farplane(4) < 0 THEN groupinview = 0
  455.         IF dx * rightplane(1) + dy * rightplane(2) + dz * rightplane(3) - rightplane(4) < 0 THEN groupinview = 0
  456.         IF dx * leftplane(1) + dy * leftplane(2) + dz * leftplane(3) - leftplane(4) < 0 THEN groupinview = 0
  457.         IF dx * topplane(1) + dy * topplane(2) + dz * topplane(3) - topplane(4) < 0 THEN groupinview = 0
  458.         IF dx * bottomplane(1) + dy * bottomplane(2) + dz * bottomplane(3) - bottomplane(4) < 0 THEN groupinview = 0
  459.         IF groupinview = 1 THEN
  460.  
  461.             IF (dist2 < closestdist2) THEN
  462.                 closestdist2 = dist2
  463.                 closestgroup = k
  464.             END IF
  465.  
  466.             VectorGroup(k).Visible = 1
  467.  
  468.             IF (toggletimeanimate = 1) THEN
  469.                 vecgroupid = k
  470.                 GOSUB timeanimate
  471.             END IF
  472.  
  473.             FOR i = VectorGroup(k).FirstVector TO VectorGroup(k).LastVector
  474.                 GOSUB clip.project.vectors
  475.             NEXT
  476.  
  477.         ELSE
  478.             ' Force animation regardless of clipping.
  479.             IF (VectorGroup(k).ForceAnimate = 1) THEN
  480.                 vecgroupid = k
  481.                 GOSUB timeanimate
  482.             END IF
  483.         END IF
  484.     ELSE
  485.         ' Force animation regardless of distance from camera.
  486.         IF (VectorGroup(k).ForceAnimate = 1) THEN
  487.             vecgroupid = k
  488.             GOSUB timeanimate
  489.         END IF
  490.     END IF
  491.     k = VectorGroup(k).Pointer
  492.     IF k = -999 THEN EXIT DO
  493.     k = VectorGroup(k).Identity
  494.  
  495. clip.project.vectors: ' requires i
  496. vec(i, 1) = vec3Dpos(i, 1) - camx
  497. vec(i, 2) = vec3Dpos(i, 2) - camy
  498. vec(i, 3) = vec3Dpos(i, 3) - camz
  499. fogswitch = -1
  500. vec3Dvis(i) = 0
  501. vectorinview = 1
  502. ' Perform view plane clipping.
  503. IF vec(i, 1) * nearplane(1) + vec(i, 2) * nearplane(2) + vec(i, 3) * nearplane(3) - nearplane(4) < 0 THEN vectorinview = 0
  504. IF vec(i, 1) * farplane(1) + vec(i, 2) * farplane(2) + vec(i, 3) * farplane(3) - farplane(4) < 0 THEN vectorinview = 0
  505. IF vec(i, 1) * farplane(1) + vec(i, 2) * farplane(2) + vec(i, 3) * farplane(3) - farplane(4) * .85 < 0 THEN fogswitch = 1
  506. IF vec(i, 1) * rightplane(1) + vec(i, 2) * rightplane(2) + vec(i, 3) * rightplane(3) - rightplane(4) < 0 THEN vectorinview = 0
  507. IF vec(i, 1) * leftplane(1) + vec(i, 2) * leftplane(2) + vec(i, 3) * leftplane(3) - leftplane(4) < 0 THEN vectorinview = 0
  508. IF vec(i, 1) * topplane(1) + vec(i, 2) * topplane(2) + vec(i, 3) * topplane(3) - topplane(4) < 0 THEN vectorinview = 0
  509. IF vec(i, 1) * bottomplane(1) + vec(i, 2) * bottomplane(2) + vec(i, 3) * bottomplane(3) - bottomplane(4) < 0 THEN vectorinview = 0
  510. IF vectorinview = 1 THEN
  511.     vec3Dvis(i) = 1
  512.     ' Project vectors onto the screen plane.
  513.     vec3Ddotnhat = vec(i, 1) * nhat(1) + vec(i, 2) * nhat(2) + vec(i, 3) * nhat(3)
  514.     vec2D(i, 1) = (vec(i, 1) * uhat(1) + vec(i, 2) * uhat(2) + vec(i, 3) * uhat(3)) * fovd / vec3Ddotnhat
  515.     vec2D(i, 2) = (vec(i, 1) * vhat(1) + vec(i, 2) * vhat(2) + vec(i, 3) * vhat(3)) * fovd / vec3Ddotnhat
  516.     IF fogswitch = 1 THEN vec2Dcolor(i) = Gray ELSE vec2Dcolor(i) = vec3Dcolor(i)
  517.  
  518. timeanimate: ' requires vecgroupid
  519. dt = timestep
  520.  
  521. xcom = VectorGroup(vecgroupid).COMx
  522. ycom = VectorGroup(vecgroupid).COMy
  523. zcom = VectorGroup(vecgroupid).COMz
  524. xrot = VectorGroup(vecgroupid).ROTx
  525. yrot = VectorGroup(vecgroupid).ROTy
  526. zrot = VectorGroup(vecgroupid).ROTz
  527. xrev = VectorGroup(vecgroupid).ROTx
  528. yrev = VectorGroup(vecgroupid).ROTy
  529. zrev = VectorGroup(vecgroupid).ROTz
  530. xdim = VectorGroup(vecgroupid).DIMx
  531. ydim = VectorGroup(vecgroupid).DIMy
  532. zdim = VectorGroup(vecgroupid).DIMz
  533.  
  534. IF (VectorGroup(vecgroupid).COMFixed = 0) THEN GOSUB resetcom
  535.  
  536. FOR vectorindex = VectorGroup(vecgroupid).FirstVector TO VectorGroup(vecgroupid).LastVector
  537.  
  538.     ' Linear velocity update
  539.     ax = vec3Dacc(vectorindex, 1)
  540.     ay = vec3Dacc(vectorindex, 2)
  541.     az = vec3Dacc(vectorindex, 3)
  542.     IF (ax <> 0) THEN vec3Dvel(vectorindex, 1) = vec3Dvel(vectorindex, 1) + ax * dt
  543.     IF (ay <> 0) THEN vec3Dvel(vectorindex, 2) = vec3Dvel(vectorindex, 2) + ay * dt
  544.     IF (az <> 0) THEN vec3Dvel(vectorindex, 3) = vec3Dvel(vectorindex, 3) + az * dt
  545.  
  546.     ' Linear position update with periodic boundaries inside group dimension
  547.     vx = vec3Dvel(vectorindex, 1)
  548.     vy = vec3Dvel(vectorindex, 2)
  549.     vz = vec3Dvel(vectorindex, 3)
  550.     IF (vx <> 0) THEN
  551.         px = vec3Dpos(vectorindex, 1) + vx * dt
  552.         IF ABS(px - xcom) > xdim THEN
  553.             IF (px > xcom) THEN
  554.                 px = xcom - xdim
  555.             ELSE
  556.                 px = xcom + xdim
  557.             END IF
  558.         END IF
  559.         vec3Dpos(vectorindex, 1) = px
  560.     END IF
  561.     IF (vy <> 0) THEN
  562.         py = vec3Dpos(vectorindex, 2) + vy * dt
  563.         IF ABS(py - ycom) > ydim THEN
  564.             IF (py > ycom) THEN
  565.                 py = ycom - ydim
  566.             ELSE
  567.                 py = ycom + ydim
  568.             END IF
  569.         END IF
  570.         vec3Dpos(vectorindex, 2) = py
  571.     END IF
  572.     IF (vz <> 0) THEN
  573.         pz = vec3Dpos(vectorindex, 3) + vz * dt
  574.         IF ABS(pz - zcom) > zdim THEN
  575.             IF (pz > zcom) THEN
  576.                 pz = zcom - zdim
  577.             ELSE
  578.                 pz = zcom + zdim
  579.             END IF
  580.         END IF
  581.         vec3Dpos(vectorindex, 3) = pz
  582.     END IF
  583.  
  584.     ' Rotation update
  585.     IF (xrot <> 0) THEN
  586.         anv = vec3Danv(vectorindex, 1)
  587.         yy = vec3Dpos(vectorindex, 2) - yrot
  588.         zz = vec3Dpos(vectorindex, 3) - zrot
  589.         y = yy * COS(timestep * anv) - zz * SIN(timestep * anv)
  590.         z = yy * SIN(timestep * anv) + zz * COS(timestep * anv)
  591.         vec3Dpos(vectorindex, 2) = y + yrot
  592.         vec3Dpos(vectorindex, 3) = z + zrot
  593.     END IF
  594.     IF (yrot <> 0) THEN
  595.         anv = vec3Danv(vectorindex, 2)
  596.         xx = vec3Dpos(vectorindex, 1) - xrot
  597.         zz = vec3Dpos(vectorindex, 3) - zrot
  598.         x = xx * COS(timestep * anv) + zz * SIN(timestep * anv)
  599.         z = -xx * SIN(timestep * anv) + zz * COS(timestep * anv)
  600.         vec3Dpos(vectorindex, 1) = x + xrot
  601.         vec3Dpos(vectorindex, 3) = z + zrot
  602.     END IF
  603.     IF (zrot <> 0) THEN
  604.         anv = vec3Danv(vectorindex, 3)
  605.         xx = vec3Dpos(vectorindex, 1) - xrot
  606.         yy = vec3Dpos(vectorindex, 2) - yrot
  607.         x = xx * COS(timestep * anv) - yy * SIN(timestep * anv)
  608.         y = xx * SIN(timestep * anv) + yy * COS(timestep * anv)
  609.         vec3Dpos(vectorindex, 1) = x + xrot
  610.         vec3Dpos(vectorindex, 2) = y + yrot
  611.     END IF
  612.  
  613.     ' Revolution update
  614.     IF (xrev <> 0) THEN
  615.         anv = xrev
  616.         yy = vec3Dpos(vectorindex, 2) - ycom
  617.         zz = vec3Dpos(vectorindex, 3) - zcom
  618.         y = yy * COS(timestep * anv) - zz * SIN(timestep * anv)
  619.         z = yy * SIN(timestep * anv) + zz * COS(timestep * anv)
  620.         vec3Dpos(vectorindex, 2) = y + ycom
  621.         vec3Dpos(vectorindex, 3) = z + zcom
  622.     END IF
  623.     IF (yrev <> 0) THEN
  624.         anv = yrev
  625.         xx = vec3Dpos(vectorindex, 1) - xcom
  626.         zz = vec3Dpos(vectorindex, 3) - zcom
  627.         x = xx * COS(timestep * anv) + zz * SIN(timestep * anv)
  628.         z = -xx * SIN(timestep * anv) + zz * COS(timestep * anv)
  629.         vec3Dpos(vectorindex, 1) = x + xcom
  630.         vec3Dpos(vectorindex, 3) = z + zcom
  631.     END IF
  632.     IF (zrev <> 0) THEN
  633.         anv = zrev
  634.         xx = vec3Dpos(vectorindex, 1) - xcom
  635.         yy = vec3Dpos(vectorindex, 2) - ycom
  636.         x = xx * COS(timestep * anv) - yy * SIN(timestep * anv)
  637.         y = xx * SIN(timestep * anv) + yy * COS(timestep * anv)
  638.         vec3Dpos(vectorindex, 1) = x + xcom
  639.         vec3Dpos(vectorindex, 2) = y + ycom
  640.     END IF
  641.  
  642.     IF (VectorGroup(vecgroupid).COMFixed = 0) THEN GOSUB integratecom
  643. IF (VectorGroup(vecgroupid).COMFixed = 0) THEN GOSUB calculatecom
  644.  
  645. integratecom: ' requires vecgroupid
  646. VectorGroup(vecgroupid).COMx = vec3Dpos(vectorindex, 1) + VectorGroup(vecgroupid).COMx
  647. VectorGroup(vecgroupid).COMy = vec3Dpos(vectorindex, 2) + VectorGroup(vecgroupid).COMy
  648. VectorGroup(vecgroupid).COMz = vec3Dpos(vectorindex, 3) + VectorGroup(vecgroupid).COMz
  649.  
  650. calculatecom: ' requires vecgroupid
  651. f = 1 + VectorGroup(vecgroupid).LastVector - VectorGroup(vecgroupid).FirstVector
  652. VectorGroup(vecgroupid).COMx = VectorGroup(vecgroupid).COMx / f
  653. VectorGroup(vecgroupid).COMy = VectorGroup(vecgroupid).COMy / f
  654. VectorGroup(vecgroupid).COMz = VectorGroup(vecgroupid).COMz / f
  655.  
  656. resetcom: ' requires vecgroupid
  657. VectorGroup(vecgroupid).COMx = 0
  658. VectorGroup(vecgroupid).COMy = 0
  659. VectorGroup(vecgroupid).COMz = 0
  660.  
  661. plot.visible.vectors:
  662. GOSUB plot.vectors
  663. GOSUB plot.hud
  664.  
  665. plot.vectors:
  666. numgroupvisible = 0
  667. numvectorvisible = 0
  668. k = 1
  669. k = VectorGroup(k).Identity
  670.     IF (VectorGroup(k).Visible = 1) THEN
  671.         numgroupvisible = numgroupvisible + 1
  672.         FOR i = VectorGroup(k).FirstVector TO VectorGroup(k).LastVector - 1
  673.             IF (vec3Dvis(i) = 1) THEN
  674.                 numvectorvisible = numvectorvisible + 1
  675.                 IF k = closestgroup THEN col = Yellow ELSE col = vec2Dcolor(i)
  676.                 x = vec2D(i, 1): y = vec2D(i, 2): GOSUB convert: x1 = x: y1 = y
  677.                 x = vec2D(i + 1, 1): y = vec2D(i + 1, 2): GOSUB convert: x2 = x: y2 = y
  678.                 IF ((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) < 225 THEN
  679.                     LINE (x1, y1)-(x2, y2), col
  680.                 ELSE
  681.                     CIRCLE (x1, y1), 1, col
  682.                 END IF
  683.             END IF
  684.         NEXT
  685.     END IF
  686.     k = VectorGroup(k).Pointer
  687.     IF k = -999 THEN EXIT DO
  688.     k = VectorGroup(k).Identity
  689.  
  690. plot.hud:
  691. ' Redraw compass.
  692. x = 30 * (xhat(1) * uhat(1) + xhat(2) * uhat(2) + xhat(3) * uhat(3)): y = 30 * (xhat(1) * vhat(1) + xhat(2) * vhat(2) + xhat(3) * vhat(3)): GOSUB convert
  693. LINE (midscreenx, midscreeny)-(x, y), Red
  694. x = 30 * (yhat(1) * uhat(1) + yhat(2) * uhat(2) + yhat(3) * uhat(3)): y = 30 * (yhat(1) * vhat(1) + yhat(2) * vhat(2) + yhat(3) * vhat(3)): GOSUB convert
  695. LINE (midscreenx, midscreeny)-(x, y), Green
  696. x = 30 * (zhat(1) * uhat(1) + zhat(2) * uhat(2) + zhat(3) * uhat(3)): y = 30 * (zhat(1) * vhat(1) + zhat(2) * vhat(2) + zhat(3) * vhat(3)): GOSUB convert
  697. LINE (midscreenx, midscreeny)-(x, y), Blue
  698. IF togglehud = 1 THEN
  699.     COLOR LimeGreen
  700.     LOCATE 2, 2: PRINT "- View Info -"
  701.     COLOR DarkKhaki
  702.     LOCATE 3, 2: PRINT "FPS:"; fpsreport
  703.     LOCATE 4, 2: PRINT "Vectors:"; numvectorvisible
  704.     LOCATE 5, 2: PRINT "Groups:"; numgroupvisible
  705.     LOCATE 6, 2: PRINT "Depth:"; -farplane(4)
  706.     LOCATE 7, 2: PRINT "Adjust via [ ]"
  707.     COLOR LimeGreen
  708.     LOCATE 9, 2: PRINT "- Camera -"
  709.     COLOR DarkKhaki
  710.     LOCATE 10, 2: PRINT INT(camx); INT(camy); INT(camz)
  711.     COLOR LimeGreen
  712.     LOCATE 12, 2: PRINT "- Closest: -"
  713.     COLOR DarkKhaki
  714.     LOCATE 13, 2: PRINT LTRIM$(RTRIM$(VectorGroup(closestgroup).GroupName))
  715.     COLOR LimeGreen
  716.     a$ = "MOVE - ALIGN": LOCATE 2, screenwidth / 8 - LEN(a$): PRINT a$
  717.     COLOR DarkKhaki
  718.     a$ = "q w e - x y z": LOCATE 3, screenwidth / 8 - LEN(a$): PRINT a$
  719.     a$ = "a s d - X Y Z": LOCATE 4, screenwidth / 8 - LEN(a$): PRINT a$
  720.     a$ = "i = invert ms": LOCATE 5, screenwidth / 8 - LEN(a$): PRINT a$
  721.     COLOR LimeGreen
  722.     a$ = "- ROTATE -": LOCATE 7, screenwidth / 8 - LEN(a$): PRINT a$
  723.     COLOR DarkKhaki
  724.     a$ = "7 8 9 Mouse": LOCATE 8, screenwidth / 8 - LEN(a$): PRINT a$
  725.     a$ = "4 5 6   +  ": LOCATE 9, screenwidth / 8 - LEN(a$): PRINT a$
  726.     a$ = "1 2 3 Wheel": LOCATE 10, screenwidth / 8 - LEN(a$): PRINT a$
  727.     COLOR LimeGreen
  728.     a$ = "- CONTROL -": LOCATE 12, screenwidth / 8 - LEN(a$): PRINT a$
  729.     COLOR DarkKhaki
  730.     a$ = "t = Stop time": LOCATE 13, screenwidth / 8 - LEN(a$): PRINT a$
  731.     a$ = "b = Create": LOCATE 14, screenwidth / 8 - LEN(a$): PRINT a$
  732.     a$ = "n = Destroy": LOCATE 15, screenwidth / 8 - LEN(a$): PRINT a$
  733.     a$ = "k = Delete": LOCATE 16, screenwidth / 8 - LEN(a$): PRINT a$
  734.     COLOR LimeGreen
  735.     a$ = "SPACE = Hide Info": LOCATE (screenheight / 16) - 3, (screenwidth / 8) / 2 - LEN(a$) / 2: PRINT a$
  736.     COLOR LimeGreen
  737.     a$ = "You See: " + LTRIM$(RTRIM$(VectorGroup(closestgroup).GroupName)): LOCATE (screenheight / 16) - 3, (screenwidth / 8) / 2 - LEN(a$) / 2: PRINT a$
  738.  
  739. 'groupidfromname: ' requires n$, returns k
  740. 'k = 1
  741. 'k = VectorGroup(k).Identity
  742. 'DO ' iterates k
  743. '    IF n$ = LTRIM$(RTRIM$(VectorGroup(k).GroupName)) THEN EXIT DO
  744. '    k = VectorGroup(k).Pointer
  745. '    IF k = -999 THEN EXIT DO
  746. '    k = VectorGroup(k).Identity
  747. 'LOOP
  748. 'RETURN
  749.  
  750. ' Data.
  751.  
  752. initialize.objects:
  753. vectorindex = 0
  754. groupidticker = 0
  755. gridsize = 550
  756. tilesize = 15
  757.  
  758. '__AAA
  759. groupidticker = groupidticker + 1
  760. vecgroupid = groupidticker
  761. VectorGroup(vecgroupid).Identity = vecgroupid
  762. VectorGroup(vecgroupid).Pointer = vecgroupid + 1
  763. VectorGroup(vecgroupid).Lagger = vecgroupid - 1 ' Fancy way to say 0.
  764. VectorGroup(vecgroupid).GroupName = "__AAA"
  765. VectorGroup(vecgroupid).Visible = 0
  766. VectorGroup(vecgroupid).COMFixed = 1
  767. VectorGroup(vecgroupid).DIMx = 5
  768. VectorGroup(vecgroupid).DIMy = 5
  769. VectorGroup(vecgroupid).DIMz = 5
  770. VectorGroup(vecgroupid).FirstVector = vectorindex + 1
  771. FOR r = 1 TO 1
  772.     vectorindex = vectorindex + 1
  773.     vec3Dpos(vectorindex, 1) = 0
  774.     vec3Dpos(vectorindex, 2) = 0
  775.     vec3Dpos(vectorindex, 3) = -1000
  776.     vec3Dcolor(vectorindex) = White
  777.     GOSUB integratecom
  778. VectorGroup(vecgroupid).LastVector = vectorindex
  779. GOSUB calculatecom
  780.  
  781. 'Dirt
  782. h = 5
  783. FOR w = 1 TO 5
  784.     FOR u = -gridsize TO gridsize STEP tilesize
  785.         FOR v = -gridsize TO gridsize STEP tilesize
  786.             groupidticker = groupidticker + 1
  787.             vecgroupid = groupidticker
  788.             VectorGroup(vecgroupid).Identity = vecgroupid
  789.             VectorGroup(vecgroupid).Pointer = vecgroupid + 1
  790.             VectorGroup(vecgroupid).Lagger = vecgroupid - 1
  791.             VectorGroup(vecgroupid).GroupName = "Dirt"
  792.             VectorGroup(vecgroupid).Visible = 0
  793.             VectorGroup(vecgroupid).COMFixed = 1
  794.             VectorGroup(vecgroupid).DIMx = 35
  795.             VectorGroup(vecgroupid).DIMy = 35
  796.             VectorGroup(vecgroupid).DIMz = 35
  797.             VectorGroup(vecgroupid).FirstVector = vectorindex + 1
  798.             FOR i = u TO u + tilesize STEP h
  799.                 FOR j = v TO v + tilesize STEP h
  800.                     IF RND > 1 - w / 5 THEN
  801.                         vectorindex = vectorindex + 1
  802.                         vec3Dpos(vectorindex, 1) = i + RND * h - RND * h
  803.                         vec3Dpos(vectorindex, 2) = j + RND * h - RND * h
  804.                         vec3Dpos(vectorindex, 3) = -(w - 1) * 70 - RND * 70
  805.                         vec3Dvis(vectorindex) = 0
  806.                         IF RND > .5 THEN
  807.                             vec3Dcolor(vectorindex) = DarkGoldenRod
  808.                         ELSE
  809.                             IF RND > .5 THEN
  810.                                 vec3Dcolor(vectorindex) = SaddleBrown
  811.                             ELSE
  812.                                 vec3Dcolor(vectorindex) = Sienna
  813.                             END IF
  814.                         END IF
  815.                         GOSUB integratecom
  816.                     END IF
  817.                 NEXT
  818.             NEXT
  819.             VectorGroup(vecgroupid).LastVector = vectorindex
  820.             GOSUB calculatecom
  821.         NEXT
  822.     NEXT
  823.  
  824. 'Grass and Puddles
  825. h = 2
  826. FOR u = -gridsize TO gridsize STEP tilesize
  827.     FOR v = -gridsize TO gridsize STEP tilesize
  828.         groupidticker = groupidticker + 1
  829.         vecgroupid = groupidticker
  830.         VectorGroup(vecgroupid).Identity = vecgroupid
  831.         VectorGroup(vecgroupid).Pointer = vecgroupid + 1
  832.         VectorGroup(vecgroupid).Lagger = vecgroupid - 1
  833.         VectorGroup(vecgroupid).GroupName = "Grass and Puddles"
  834.         VectorGroup(vecgroupid).Visible = 0
  835.         VectorGroup(vecgroupid).COMFixed = 1
  836.         VectorGroup(vecgroupid).DIMx = tilesize / 2
  837.         VectorGroup(vecgroupid).DIMy = tilesize / 2
  838.         VectorGroup(vecgroupid).DIMz = 3
  839.         VectorGroup(vecgroupid).FirstVector = vectorindex + 1
  840.         FOR i = u TO u + tilesize STEP h
  841.             FOR j = v TO v + tilesize STEP h
  842.                 vectorindex = vectorindex + 1
  843.                 vec3Dpos(vectorindex, 1) = i + RND * h - RND * h
  844.                 vec3Dpos(vectorindex, 2) = j + RND * h - RND * h
  845.                 vec3Dpos(vectorindex, 3) = .5 + 1 * COS((i - 15) * .08) - 1 * COS((j - 6) * .12)
  846.                 vec3Dvis(vectorindex) = 0
  847.                 IF vec3Dpos(vectorindex, 3) > 0 THEN
  848.                     IF RND > .5 THEN
  849.                         vec3Dcolor(vectorindex) = Green
  850.                     ELSE
  851.                         vec3Dcolor(vectorindex) = ForestGreen
  852.                     END IF
  853.                 ELSE
  854.                     vec3Dvel(vectorindex, 1) = (RND - .5) * 20
  855.                     vec3Dvel(vectorindex, 2) = (RND - .5) * 20
  856.                     vec3Dvel(vectorindex, 3) = (RND - .5) * 20
  857.                     IF RND > .2 THEN
  858.                         vec3Dcolor(vectorindex) = LightSeaGreen
  859.                     ELSE
  860.                         vec3Dcolor(vectorindex) = Blue
  861.                     END IF
  862.                 END IF
  863.                 GOSUB integratecom
  864.             NEXT
  865.         NEXT
  866.         VectorGroup(vecgroupid).LastVector = vectorindex
  867.         GOSUB calculatecom
  868.     NEXT
  869.  
  870. 'Grave
  871. thickness = 2.5
  872. span = 20
  873. height = 30
  874. crux = 22
  875. FOR xloc = -90 TO -290 STEP -60
  876.     FOR yloc = 0 TO 180 STEP 45
  877.         FOR k = 0 TO height
  878.             groupidticker = groupidticker + 1
  879.             vecgroupid = groupidticker
  880.             VectorGroup(vecgroupid).Identity = vecgroupid
  881.             VectorGroup(vecgroupid).Pointer = vecgroupid + 1
  882.             VectorGroup(vecgroupid).Lagger = vecgroupid - 1
  883.             VectorGroup(vecgroupid).GroupName = "Grave"
  884.             VectorGroup(vecgroupid).Visible = 0
  885.             VectorGroup(vecgroupid).COMFixed = 1
  886.             VectorGroup(vecgroupid).DIMx = thickness
  887.             VectorGroup(vecgroupid).DIMy = thickness
  888.             VectorGroup(vecgroupid).DIMz = thickness
  889.             VectorGroup(vecgroupid).FirstVector = vectorindex + 1
  890.             FOR i = -thickness TO thickness STEP thickness / 2
  891.                 FOR j = -thickness TO thickness STEP thickness / 2
  892.                     vectorindex = vectorindex + 1
  893.                     vec3Dpos(vectorindex, 1) = xloc + i + (RND - .5) * 2
  894.                     vec3Dpos(vectorindex, 2) = yloc + j + (RND - .5) * 2
  895.                     vec3Dpos(vectorindex, 3) = k + (RND - .5) * 2
  896.                     vec3Dvis(vectorindex) = 0
  897.                     IF RND > .5 THEN
  898.                         vec3Dcolor(vectorindex) = SlateGray
  899.                     ELSE
  900.                         vec3Dcolor(vectorindex) = DarkGray
  901.                     END IF
  902.                     GOSUB integratecom
  903.                 NEXT
  904.             NEXT
  905.             VectorGroup(vecgroupid).LastVector = vectorindex
  906.             GOSUB calculatecom
  907.         NEXT
  908.         FOR j = -span / 2 TO -thickness
  909.             groupidticker = groupidticker + 1
  910.             vecgroupid = groupidticker
  911.             VectorGroup(vecgroupid).Identity = vecgroupid
  912.             VectorGroup(vecgroupid).Pointer = vecgroupid + 1
  913.             VectorGroup(vecgroupid).Lagger = vecgroupid - 1
  914.             VectorGroup(vecgroupid).GroupName = "Grave"
  915.             VectorGroup(vecgroupid).Visible = 0
  916.             VectorGroup(vecgroupid).COMFixed = 1
  917.             VectorGroup(vecgroupid).DIMx = thickness
  918.             VectorGroup(vecgroupid).DIMy = thickness
  919.             VectorGroup(vecgroupid).DIMz = thickness
  920.             VectorGroup(vecgroupid).FirstVector = vectorindex + 1
  921.             FOR k = -thickness TO thickness STEP thickness / 2
  922.                 FOR i = -thickness TO thickness STEP thickness / 2
  923.                     vectorindex = vectorindex + 1
  924.                     vec3Dpos(vectorindex, 1) = xloc + i + (RND - .5) * 2
  925.                     vec3Dpos(vectorindex, 2) = yloc + j + (RND - .5) * 2
  926.                     vec3Dpos(vectorindex, 3) = crux + k + (RND - .5) * 2
  927.                     vec3Dvis(vectorindex) = 0
  928.                     IF RND > .5 THEN
  929.                         vec3Dcolor(vectorindex) = SlateGray
  930.                     ELSE
  931.                         vec3Dcolor(vectorindex) = DarkGray
  932.                     END IF
  933.                     GOSUB integratecom
  934.                 NEXT
  935.             NEXT
  936.             VectorGroup(vecgroupid).LastVector = vectorindex
  937.             GOSUB calculatecom
  938.         NEXT
  939.         FOR j = thickness TO span / 2
  940.             groupidticker = groupidticker + 1
  941.             vecgroupid = groupidticker
  942.             VectorGroup(vecgroupid).Identity = vecgroupid
  943.             VectorGroup(vecgroupid).Pointer = vecgroupid + 1
  944.             VectorGroup(vecgroupid).Lagger = vecgroupid - 1
  945.             VectorGroup(vecgroupid).GroupName = "Grave"
  946.             VectorGroup(vecgroupid).Visible = 0
  947.             VectorGroup(vecgroupid).COMFixed = 1
  948.             VectorGroup(vecgroupid).DIMx = thickness
  949.             VectorGroup(vecgroupid).DIMy = thickness
  950.             VectorGroup(vecgroupid).DIMz = thickness
  951.             VectorGroup(vecgroupid).FirstVector = vectorindex + 1
  952.             FOR k = -thickness TO thickness STEP thickness / 2
  953.                 FOR i = -thickness TO thickness STEP thickness / 2
  954.                     vectorindex = vectorindex + 1
  955.                     vec3Dpos(vectorindex, 1) = xloc + i + (RND - .5) * 2
  956.                     vec3Dpos(vectorindex, 2) = yloc + j + (RND - .5) * 2
  957.                     vec3Dpos(vectorindex, 3) = crux + k + (RND - .5) * 2
  958.                     vec3Dvis(vectorindex) = 0
  959.                     IF RND > .5 THEN
  960.                         vec3Dcolor(vectorindex) = SlateGray
  961.                     ELSE
  962.                         vec3Dcolor(vectorindex) = DarkGray
  963.                     END IF
  964.                     GOSUB integratecom
  965.                 NEXT
  966.             NEXT
  967.             VectorGroup(vecgroupid).LastVector = vectorindex
  968.             GOSUB calculatecom
  969.         NEXT
  970.     NEXT
  971.  
  972. 'Heaven's Bottom Layer
  973. h = 2
  974. FOR u = -gridsize TO gridsize STEP tilesize
  975.     FOR v = -gridsize TO gridsize STEP tilesize
  976.         groupidticker = groupidticker + 1
  977.         vecgroupid = groupidticker
  978.         VectorGroup(vecgroupid).Identity = vecgroupid
  979.         VectorGroup(vecgroupid).Pointer = vecgroupid + 1
  980.         VectorGroup(vecgroupid).Lagger = vecgroupid - 1
  981.         VectorGroup(vecgroupid).GroupName = "Heaven's Bottom Layer"
  982.         VectorGroup(vecgroupid).Visible = 0
  983.         VectorGroup(vecgroupid).COMFixed = 1
  984.         VectorGroup(vecgroupid).DIMx = tilesize / 2
  985.         VectorGroup(vecgroupid).DIMy = tilesize / 2
  986.         VectorGroup(vecgroupid).DIMz = 3
  987.         VectorGroup(vecgroupid).FirstVector = vectorindex + 1
  988.         FOR i = u TO u + tilesize STEP h
  989.             FOR j = v TO v + tilesize STEP h
  990.                 vectorindex = vectorindex + 1
  991.                 vec3Dpos(vectorindex, 1) = i + RND * h - RND * h
  992.                 vec3Dpos(vectorindex, 2) = j + RND * h - RND * h
  993.                 vec3Dpos(vectorindex, 3) = 420 - RND
  994.                 vec3Dvis(vectorindex) = 0
  995.                 IF RND > .5 THEN
  996.                     vec3Dcolor(vectorindex) = BlueViolet
  997.                 ELSE
  998.                     vec3Dcolor(vectorindex) = Cyan
  999.                 END IF
  1000.                 GOSUB integratecom
  1001.             NEXT
  1002.         NEXT
  1003.         VectorGroup(vecgroupid).LastVector = vectorindex
  1004.         GOSUB calculatecom
  1005.     NEXT
  1006.  
  1007. 'Hell Spawn
  1008. FOR u = -gridsize TO gridsize STEP tilesize
  1009.     FOR v = -gridsize TO gridsize STEP tilesize
  1010.         groupidticker = groupidticker + 1
  1011.         vecgroupid = groupidticker
  1012.         VectorGroup(vecgroupid).Identity = vecgroupid
  1013.         VectorGroup(vecgroupid).Pointer = vecgroupid + 1
  1014.         VectorGroup(vecgroupid).Lagger = vecgroupid - 1
  1015.         VectorGroup(vecgroupid).GroupName = "Hell Spawn"
  1016.         VectorGroup(vecgroupid).Visible = 0
  1017.         VectorGroup(vecgroupid).COMFixed = 1
  1018.         VectorGroup(vecgroupid).DIMx = tilesize / 2
  1019.         VectorGroup(vecgroupid).DIMy = tilesize / 2
  1020.         VectorGroup(vecgroupid).DIMz = 35
  1021.         VectorGroup(vecgroupid).FirstVector = vectorindex + 1
  1022.         FOR i = u TO u + tilesize STEP tilesize / 5
  1023.             FOR j = v TO v + tilesize STEP tilesize / 5
  1024.                 vectorindex = vectorindex + 1
  1025.                 vec3Dpos(vectorindex, 1) = i + (RND - .5) * tilesize
  1026.                 vec3Dpos(vectorindex, 2) = j + (RND - .5) * tilesize
  1027.                 vec3Dpos(vectorindex, 3) = -350 - RND * 70
  1028.                 vec3Dvel(vectorindex, 1) = 0
  1029.                 vec3Dvel(vectorindex, 2) = 0
  1030.                 vec3Dvel(vectorindex, 3) = 400 * RND
  1031.                 vec3Dvis(vectorindex) = 0
  1032.                 IF RND > .2 THEN
  1033.                     vec3Dcolor(vectorindex) = Red
  1034.                 ELSE
  1035.                     vec3Dcolor(vectorindex) = DarkGoldenRod
  1036.                 END IF
  1037.                 GOSUB integratecom
  1038.             NEXT
  1039.         NEXT
  1040.         VectorGroup(vecgroupid).LastVector = vectorindex
  1041.         GOSUB calculatecom
  1042.         VectorGroup(vecgroupid).COMz = -350 - 35
  1043.     NEXT
  1044.  
  1045. 'Icewall East
  1046. h = 2
  1047. FOR u = -gridsize TO gridsize STEP tilesize
  1048.     FOR v = 0 TO 70 STEP tilesize
  1049.         groupidticker = groupidticker + 1
  1050.         vecgroupid = groupidticker
  1051.         VectorGroup(vecgroupid).Identity = vecgroupid
  1052.         VectorGroup(vecgroupid).Pointer = vecgroupid + 1
  1053.         VectorGroup(vecgroupid).Lagger = vecgroupid - 1
  1054.         VectorGroup(vecgroupid).GroupName = "Icewall East"
  1055.         VectorGroup(vecgroupid).Visible = 0
  1056.         VectorGroup(vecgroupid).COMFixed = 1
  1057.         VectorGroup(vecgroupid).DIMx = tilesize / 2
  1058.         VectorGroup(vecgroupid).DIMy = tilesize / 2
  1059.         VectorGroup(vecgroupid).DIMz = tilesize / 2
  1060.         VectorGroup(vecgroupid).FirstVector = vectorindex + 1
  1061.         FOR i = u TO u + tilesize STEP h
  1062.             FOR j = v TO v + tilesize STEP h
  1063.                 vectorindex = vectorindex + 1
  1064.                 vec3Dpos(vectorindex, 1) = gridsize + tilesize / 2
  1065.                 vec3Dpos(vectorindex, 2) = i + RND * h - RND * h
  1066.                 vec3Dpos(vectorindex, 3) = j + RND * h - RND * h
  1067.                 vec3Dvis(vectorindex) = 0
  1068.                 IF RND > .5 THEN
  1069.                     vec3Dcolor(vectorindex) = White
  1070.                 ELSE
  1071.                     vec3Dcolor(vectorindex) = Ivory
  1072.                 END IF
  1073.                 GOSUB integratecom
  1074.             NEXT
  1075.         NEXT
  1076.         VectorGroup(vecgroupid).LastVector = vectorindex
  1077.         GOSUB calculatecom
  1078.     NEXT
  1079.  
  1080. 'Icewall South
  1081. h = 2
  1082. FOR u = -gridsize TO gridsize STEP tilesize
  1083.     FOR v = 0 TO 70 STEP tilesize
  1084.         groupidticker = groupidticker + 1
  1085.         vecgroupid = groupidticker
  1086.         VectorGroup(vecgroupid).Identity = vecgroupid
  1087.         VectorGroup(vecgroupid).Pointer = vecgroupid + 1
  1088.         VectorGroup(vecgroupid).Lagger = vecgroupid - 1
  1089.         VectorGroup(vecgroupid).GroupName = "Icewall South"
  1090.         VectorGroup(vecgroupid).Visible = 0
  1091.         VectorGroup(vecgroupid).COMFixed = 1
  1092.         VectorGroup(vecgroupid).DIMx = tilesize / 2
  1093.         VectorGroup(vecgroupid).DIMy = tilesize / 2
  1094.         VectorGroup(vecgroupid).DIMz = tilesize / 2
  1095.         VectorGroup(vecgroupid).FirstVector = vectorindex + 1
  1096.         FOR i = u TO u + tilesize STEP h
  1097.             FOR j = v TO v + tilesize STEP h
  1098.                 vectorindex = vectorindex + 1
  1099.                 vec3Dpos(vectorindex, 1) = -gridsize
  1100.                 vec3Dpos(vectorindex, 2) = i + RND * h - RND * h
  1101.                 vec3Dpos(vectorindex, 3) = j + RND * h - RND * h
  1102.                 vec3Dvis(vectorindex) = 0
  1103.                 IF RND > .5 THEN
  1104.                     vec3Dcolor(vectorindex) = White
  1105.                 ELSE
  1106.                     vec3Dcolor(vectorindex) = Ivory
  1107.                 END IF
  1108.                 GOSUB integratecom
  1109.             NEXT
  1110.         NEXT
  1111.         VectorGroup(vecgroupid).LastVector = vectorindex
  1112.         GOSUB calculatecom
  1113.     NEXT
  1114.  
  1115. 'Icewall North
  1116. h = 2
  1117. FOR u = -gridsize TO gridsize STEP tilesize
  1118.     FOR v = 0 TO 70 STEP tilesize
  1119.         groupidticker = groupidticker + 1
  1120.         vecgroupid = groupidticker
  1121.         VectorGroup(vecgroupid).Identity = vecgroupid
  1122.         VectorGroup(vecgroupid).Pointer = vecgroupid + 1
  1123.         VectorGroup(vecgroupid).Lagger = vecgroupid - 1
  1124.         VectorGroup(vecgroupid).GroupName = "Icewall North"
  1125.         VectorGroup(vecgroupid).Visible = 0
  1126.         VectorGroup(vecgroupid).COMFixed = 1
  1127.         VectorGroup(vecgroupid).DIMx = tilesize / 2
  1128.         VectorGroup(vecgroupid).DIMy = tilesize / 2
  1129.         VectorGroup(vecgroupid).DIMz = tilesize / 2
  1130.         VectorGroup(vecgroupid).FirstVector = vectorindex + 1
  1131.         FOR i = u TO u + tilesize STEP h
  1132.             FOR j = v TO v + tilesize STEP h
  1133.                 vectorindex = vectorindex + 1
  1134.                 vec3Dpos(vectorindex, 1) = i + RND * h - RND * h
  1135.                 vec3Dpos(vectorindex, 2) = gridsize + tilesize / 2
  1136.                 vec3Dpos(vectorindex, 3) = j + RND * h - RND * h
  1137.                 vec3Dvis(vectorindex) = 0
  1138.                 IF RND > .5 THEN
  1139.                     vec3Dcolor(vectorindex) = White
  1140.                 ELSE
  1141.                     vec3Dcolor(vectorindex) = Ivory
  1142.                 END IF
  1143.                 GOSUB integratecom
  1144.             NEXT
  1145.         NEXT
  1146.         VectorGroup(vecgroupid).LastVector = vectorindex
  1147.         GOSUB calculatecom
  1148.     NEXT
  1149.  
  1150. 'Icewall West
  1151. h = 2
  1152. FOR u = -gridsize TO gridsize STEP tilesize
  1153.     FOR v = 0 TO 70 STEP tilesize
  1154.         groupidticker = groupidticker + 1
  1155.         vecgroupid = groupidticker
  1156.         VectorGroup(vecgroupid).Identity = vecgroupid
  1157.         VectorGroup(vecgroupid).Pointer = vecgroupid + 1
  1158.         VectorGroup(vecgroupid).Lagger = vecgroupid - 1
  1159.         VectorGroup(vecgroupid).GroupName = "Icewall West"
  1160.         VectorGroup(vecgroupid).Visible = 0
  1161.         VectorGroup(vecgroupid).COMFixed = 1
  1162.         VectorGroup(vecgroupid).DIMx = tilesize / 2
  1163.         VectorGroup(vecgroupid).DIMy = tilesize / 2
  1164.         VectorGroup(vecgroupid).DIMz = tilesize / 2
  1165.         VectorGroup(vecgroupid).FirstVector = vectorindex + 1
  1166.         FOR i = u TO u + tilesize STEP h
  1167.             FOR j = v TO v + tilesize STEP h
  1168.                 vectorindex = vectorindex + 1
  1169.                 vec3Dpos(vectorindex, 1) = i + RND * h - RND * h
  1170.                 vec3Dpos(vectorindex, 2) = -gridsize
  1171.                 vec3Dpos(vectorindex, 3) = j + RND * h - RND * h
  1172.                 vec3Dvis(vectorindex) = 0
  1173.                 IF RND > .5 THEN
  1174.                     vec3Dcolor(vectorindex) = White
  1175.                 ELSE
  1176.                     vec3Dcolor(vectorindex) = Ivory
  1177.                 END IF
  1178.                 GOSUB integratecom
  1179.             NEXT
  1180.         NEXT
  1181.         VectorGroup(vecgroupid).LastVector = vectorindex
  1182.         GOSUB calculatecom
  1183.     NEXT
  1184.  
  1185. 'Lake of Fire
  1186. h = 2
  1187. FOR u = -gridsize TO gridsize STEP tilesize
  1188.     FOR v = -gridsize TO gridsize STEP tilesize
  1189.         groupidticker = groupidticker + 1
  1190.         vecgroupid = groupidticker
  1191.         VectorGroup(vecgroupid).Identity = vecgroupid
  1192.         VectorGroup(vecgroupid).Pointer = vecgroupid + 1
  1193.         VectorGroup(vecgroupid).Lagger = vecgroupid - 1
  1194.         VectorGroup(vecgroupid).GroupName = "Lake of Fire"
  1195.         VectorGroup(vecgroupid).Visible = 0
  1196.         VectorGroup(vecgroupid).COMFixed = 1
  1197.         VectorGroup(vecgroupid).DIMx = tilesize / 2
  1198.         VectorGroup(vecgroupid).DIMy = tilesize / 2
  1199.         VectorGroup(vecgroupid).DIMz = tilesize / 2
  1200.         VectorGroup(vecgroupid).FirstVector = vectorindex + 1
  1201.         FOR i = u TO u + tilesize STEP h
  1202.             FOR j = v TO v + tilesize STEP h
  1203.                 vectorindex = vectorindex + 1
  1204.                 vec3Dpos(vectorindex, 1) = i + RND * h - RND * h
  1205.                 vec3Dpos(vectorindex, 2) = j + RND * h - RND * h
  1206.                 vec3Dpos(vectorindex, 3) = -350 - 70 - RND
  1207.                 vec3Dvis(vectorindex) = 0
  1208.                 IF RND > .2 THEN
  1209.                     vec3Dcolor(vectorindex) = Red
  1210.                 ELSE
  1211.                     vec3Dcolor(vectorindex) = Indigo
  1212.                 END IF
  1213.                 GOSUB integratecom
  1214.             NEXT
  1215.         NEXT
  1216.         VectorGroup(vecgroupid).LastVector = vectorindex
  1217.         GOSUB calculatecom
  1218.     NEXT
  1219.  
  1220. 'Megalith
  1221. ctrx = -90
  1222. ctry = -320
  1223. ctrz = 4
  1224. w = 8
  1225. h = 256
  1226. dens = 100
  1227. FOR k = 1 TO h STEP w
  1228.     FOR i = -h / 20 + k / 20 TO h / 20 - k / 20 STEP w
  1229.         FOR j = -h / 20 + k / 20 TO h / 20 - k / 20 STEP w
  1230.             groupidticker = groupidticker + 1
  1231.             vecgroupid = groupidticker
  1232.             VectorGroup(vecgroupid).Identity = vecgroupid
  1233.             VectorGroup(vecgroupid).Pointer = vecgroupid + 1
  1234.             VectorGroup(vecgroupid).Lagger = vecgroupid - 1
  1235.             VectorGroup(vecgroupid).GroupName = "Megalith"
  1236.             VectorGroup(vecgroupid).Visible = 0
  1237.             VectorGroup(vecgroupid).COMFixed = 1
  1238.             VectorGroup(vecgroupid).DIMx = w / 2
  1239.             VectorGroup(vecgroupid).DIMy = w / 2
  1240.             VectorGroup(vecgroupid).DIMz = w / 2
  1241.             VectorGroup(vecgroupid).FirstVector = vectorindex + 1
  1242.             FOR q = 1 TO dens
  1243.                 vectorindex = vectorindex + 1
  1244.                 vec3Dpos(vectorindex, 1) = ctrx + i + (RND - .5) * w
  1245.                 vec3Dpos(vectorindex, 2) = ctry + j + (RND - .5) * w
  1246.                 vec3Dpos(vectorindex, 3) = ctrz + k + (RND - .5) * w
  1247.                 vec3Dvis(vectorindex) = 0
  1248.                 IF RND > .5 THEN
  1249.                     vec3Dcolor(vectorindex) = Cyan
  1250.                 ELSE
  1251.                     vec3Dcolor(vectorindex) = Teal
  1252.                 END IF
  1253.                 GOSUB integratecom
  1254.             NEXT
  1255.             VectorGroup(vecgroupid).LastVector = vectorindex
  1256.             GOSUB calculatecom
  1257.         NEXT
  1258.     NEXT
  1259.  
  1260. 'Pyramid
  1261. ctrx = -90
  1262. ctry = -120
  1263. ctrz = 4
  1264. w = 8
  1265. h = 56
  1266. dens = 50
  1267. FOR k = 1 TO h STEP w
  1268.     FOR i = -h / 2 + k / 2 TO h / 2 - k / 2 STEP w
  1269.         FOR j = -h / 2 + k / 2 TO h / 2 - k / 2 STEP w
  1270.             groupidticker = groupidticker + 1
  1271.             vecgroupid = groupidticker
  1272.             VectorGroup(vecgroupid).Identity = vecgroupid
  1273.             VectorGroup(vecgroupid).Pointer = vecgroupid + 1
  1274.             VectorGroup(vecgroupid).Lagger = vecgroupid - 1
  1275.             VectorGroup(vecgroupid).GroupName = "Pyramid"
  1276.             VectorGroup(vecgroupid).Visible = 0
  1277.             VectorGroup(vecgroupid).COMFixed = 1
  1278.             VectorGroup(vecgroupid).DIMx = tilesize / 2
  1279.             VectorGroup(vecgroupid).DIMy = tilesize / 2
  1280.             VectorGroup(vecgroupid).DIMz = tilesize / 2
  1281.             VectorGroup(vecgroupid).FirstVector = vectorindex + 1
  1282.             FOR q = 1 TO dens
  1283.                 vectorindex = vectorindex + 1
  1284.                 vec3Dpos(vectorindex, 1) = ctrx + i + (RND - .5) * w
  1285.                 vec3Dpos(vectorindex, 2) = ctry + j + (RND - .5) * w
  1286.                 vec3Dpos(vectorindex, 3) = ctrz + k + (RND - .5) * w
  1287.                 vec3Dvis(vectorindex) = 0
  1288.                 IF RND > .5 THEN
  1289.                     vec3Dcolor(vectorindex) = DarkGoldenRod
  1290.                 ELSE
  1291.                     vec3Dcolor(vectorindex) = GoldenRod
  1292.                 END IF
  1293.                 GOSUB integratecom
  1294.             NEXT
  1295.             VectorGroup(vecgroupid).LastVector = vectorindex
  1296.             GOSUB calculatecom
  1297.         NEXT
  1298.     NEXT
  1299.  
  1300. 'Rain
  1301. FOR u = -gridsize TO gridsize STEP tilesize
  1302.     FOR v = -gridsize TO gridsize STEP tilesize
  1303.         groupidticker = groupidticker + 1
  1304.         vecgroupid = groupidticker
  1305.         VectorGroup(vecgroupid).Identity = vecgroupid
  1306.         VectorGroup(vecgroupid).Pointer = vecgroupid + 1
  1307.         VectorGroup(vecgroupid).Lagger = vecgroupid - 1
  1308.         VectorGroup(vecgroupid).GroupName = "Rain"
  1309.         VectorGroup(vecgroupid).Visible = 0
  1310.         VectorGroup(vecgroupid).COMFixed = 1
  1311.         VectorGroup(vecgroupid).DIMx = tilesize / 2
  1312.         VectorGroup(vecgroupid).DIMy = tilesize / 2
  1313.         VectorGroup(vecgroupid).DIMz = 35
  1314.         VectorGroup(vecgroupid).FirstVector = vectorindex + 1
  1315.         FOR i = u TO u + tilesize STEP tilesize '/ 3
  1316.             FOR j = v TO v + tilesize STEP tilesize '/ 3
  1317.                 vectorindex = vectorindex + 1
  1318.                 vec3Dpos(vectorindex, 1) = i + (RND - .5) * tilesize
  1319.                 vec3Dpos(vectorindex, 2) = j + (RND - .5) * tilesize
  1320.                 vec3Dpos(vectorindex, 3) = RND * 70
  1321.                 vec3Dvel(vectorindex, 1) = 0
  1322.                 vec3Dvel(vectorindex, 2) = 0
  1323.                 vec3Dvel(vectorindex, 3) = -400 * RND
  1324.                 vec3Dvis(vectorindex) = 0
  1325.                 IF RND > 5 THEN
  1326.                     vec3Dcolor(vectorindex) = Aquamarine
  1327.                 ELSE
  1328.                     vec3Dcolor(vectorindex) = DodgerBlue
  1329.                 END IF
  1330.                 GOSUB integratecom
  1331.             NEXT
  1332.         NEXT
  1333.         VectorGroup(vecgroupid).LastVector = vectorindex
  1334.         GOSUB calculatecom
  1335.         VectorGroup(vecgroupid).COMz = 35
  1336.     NEXT
  1337.  
  1338. 'Sky
  1339. h = 2
  1340. FOR u = -gridsize TO gridsize STEP tilesize
  1341.     FOR v = -gridsize TO gridsize STEP tilesize
  1342.         groupidticker = groupidticker + 1
  1343.         vecgroupid = groupidticker
  1344.         VectorGroup(vecgroupid).Identity = vecgroupid
  1345.         VectorGroup(vecgroupid).Pointer = vecgroupid + 1
  1346.         VectorGroup(vecgroupid).Lagger = vecgroupid - 1
  1347.         VectorGroup(vecgroupid).GroupName = "Sky"
  1348.         VectorGroup(vecgroupid).Visible = 0
  1349.         VectorGroup(vecgroupid).COMFixed = 1
  1350.         VectorGroup(vecgroupid).DIMx = tilesize / 2
  1351.         VectorGroup(vecgroupid).DIMy = tilesize / 2
  1352.         VectorGroup(vecgroupid).DIMz = 3
  1353.         VectorGroup(vecgroupid).FirstVector = vectorindex + 1
  1354.         FOR i = u TO u + tilesize STEP h
  1355.             FOR j = v TO v + tilesize STEP h
  1356.                 vectorindex = vectorindex + 1
  1357.                 vec3Dpos(vectorindex, 1) = i + (RND - RND) * h
  1358.                 vec3Dpos(vectorindex, 2) = j + (RND - RND) * h
  1359.                 vec3Dpos(vectorindex, 3) = 70 + (RND - RND) * h
  1360.                 vec3Dvel(vectorindex, 1) = (RND - RND) * 2
  1361.                 vec3Dvel(vectorindex, 2) = (RND - RND) * 2
  1362.                 vec3Dvel(vectorindex, 3) = (RND - RND) * 2
  1363.                 vec3Danv(vectorindex, 1) = 0
  1364.                 vec3Danv(vectorindex, 2) = 0
  1365.                 vec3Danv(vectorindex, 3) = 0
  1366.                 vec3Dvis(vectorindex) = 0
  1367.                 IF RND > .5 THEN
  1368.                     vec3Dcolor(vectorindex) = Snow
  1369.                 ELSE
  1370.                     vec3Dcolor(vectorindex) = RoyalBlue
  1371.                 END IF
  1372.                 GOSUB integratecom
  1373.             NEXT
  1374.         NEXT
  1375.         VectorGroup(vecgroupid).LastVector = vectorindex
  1376.         GOSUB calculatecom
  1377.     NEXT
  1378.  
  1379. 'Stars
  1380. h = 5
  1381. FOR w = 1 TO 5
  1382.     FOR u = -gridsize TO gridsize STEP tilesize
  1383.         FOR v = -gridsize TO gridsize STEP tilesize
  1384.             groupidticker = groupidticker + 1
  1385.             vecgroupid = groupidticker
  1386.             VectorGroup(vecgroupid).Identity = vecgroupid
  1387.             VectorGroup(vecgroupid).Pointer = vecgroupid + 1
  1388.             VectorGroup(vecgroupid).Lagger = vecgroupid - 1
  1389.             VectorGroup(vecgroupid).GroupName = "Stars"
  1390.             VectorGroup(vecgroupid).Visible = 0
  1391.             VectorGroup(vecgroupid).COMFixed = 1
  1392.             VectorGroup(vecgroupid).DIMx = tilesize / 2
  1393.             VectorGroup(vecgroupid).DIMy = tilesize / 2
  1394.             VectorGroup(vecgroupid).DIMz = tilesize / 2
  1395.             VectorGroup(vecgroupid).FirstVector = vectorindex + 1
  1396.             FOR i = u TO u + tilesize STEP h
  1397.                 FOR j = v TO v + tilesize STEP h
  1398.                     IF RND > 1 - w / 5 THEN
  1399.                         vectorindex = vectorindex + 1
  1400.                         vec3Dpos(vectorindex, 1) = i + RND * h - RND * h
  1401.                         vec3Dpos(vectorindex, 2) = j + RND * h - RND * h
  1402.                         vec3Dpos(vectorindex, 3) = w * 70 + RND * 70
  1403.                         vec3Dvis(vectorindex) = 0
  1404.                         IF RND > .5 THEN
  1405.                             vec3Dcolor(vectorindex) = GhostWhite
  1406.                         ELSE
  1407.                             IF RND > .5 THEN
  1408.                                 vec3Dcolor(vectorindex) = White
  1409.                             ELSE
  1410.                                 vec3Dcolor(vectorindex) = DarkGray
  1411.                             END IF
  1412.                         END IF
  1413.                         GOSUB integratecom
  1414.                     END IF
  1415.                 NEXT
  1416.             NEXT
  1417.             VectorGroup(vecgroupid).LastVector = vectorindex
  1418.             GOSUB calculatecom
  1419.         NEXT
  1420.     NEXT
  1421.  
  1422. 'Sun
  1423. radius = 10
  1424. dx = .0628
  1425. dy = .0628
  1426. xl = 0: xr = 2 * pi
  1427. yl = 0: yr = pi
  1428. xrange = 1 + INT((-xl + xr) / dx)
  1429. yrange = 1 + INT((-yl + yr) / dy)
  1430. FOR i = 1 TO xrange STEP 10
  1431.     FOR j = 1 TO yrange STEP 10
  1432.         groupidticker = groupidticker + 1
  1433.         vecgroupid = groupidticker
  1434.         VectorGroup(vecgroupid).Identity = vecgroupid
  1435.         VectorGroup(vecgroupid).Pointer = vecgroupid + 1
  1436.         VectorGroup(vecgroupid).Lagger = vecgroupid - 1
  1437.         VectorGroup(vecgroupid).GroupName = "Sun"
  1438.         VectorGroup(vecgroupid).Visible = 0
  1439.         VectorGroup(vecgroupid).COMFixed = 1
  1440.         VectorGroup(vecgroupid).DIMx = radius
  1441.         VectorGroup(vecgroupid).DIMy = radius
  1442.         VectorGroup(vecgroupid).DIMz = radius
  1443.         VectorGroup(vecgroupid).FirstVector = vectorindex + 1
  1444.         FOR u = i TO i + 10 STEP 1
  1445.             FOR v = j TO j + 10 STEP 1
  1446.                 vectorindex = vectorindex + 1
  1447.                 theta = u * dx - dx
  1448.                 phi = v * dy - dy
  1449.                 vec3Dpos(vectorindex, 1) = radius * SIN(phi) * COS(theta)
  1450.                 vec3Dpos(vectorindex, 2) = radius * SIN(phi) * SIN(theta)
  1451.                 vec3Dpos(vectorindex, 3) = 90 + radius * COS(phi)
  1452.                 vec3Dvis(vectorindex) = 0
  1453.                 IF RND > .5 THEN
  1454.                     vec3Dcolor(vectorindex) = Sunglow
  1455.                 ELSE
  1456.                     vec3Dcolor(vectorindex) = SunsetOrange
  1457.                 END IF
  1458.                 GOSUB integratecom
  1459.             NEXT
  1460.         NEXT
  1461.         GOSUB integratecom
  1462.         VectorGroup(vecgroupid).LastVector = vectorindex
  1463.         GOSUB calculatecom
  1464.     NEXT
  1465.  
  1466. 'Moon
  1467. radius = 4
  1468. au = 60
  1469. dx = (2 * pi / radius) * .05
  1470. dy = (2 * pi / radius) * .05
  1471. xl = 0: xr = 2 * pi
  1472. yl = 0: yr = pi
  1473. xrange = 1 + INT((-xl + xr) / dx)
  1474. yrange = 1 + INT((-yl + yr) / dy)
  1475. groupidticker = groupidticker + 1
  1476. vecgroupid = groupidticker
  1477. VectorGroup(vecgroupid).Identity = vecgroupid
  1478. VectorGroup(vecgroupid).Pointer = vecgroupid + 1
  1479. VectorGroup(vecgroupid).Lagger = vecgroupid - 1
  1480. VectorGroup(vecgroupid).GroupName = "Moon"
  1481. VectorGroup(vecgroupid).Visible = 0
  1482. VectorGroup(vecgroupid).ForceAnimate = 1
  1483. VectorGroup(vecgroupid).COMFixed = 0
  1484. VectorGroup(vecgroupid).ROTx = 0
  1485. VectorGroup(vecgroupid).ROTy = 0
  1486. VectorGroup(vecgroupid).ROTz = 90
  1487. VectorGroup(vecgroupid).REVx = 1.5
  1488. VectorGroup(vecgroupid).REVy = 0
  1489. VectorGroup(vecgroupid).REVz = 0
  1490. VectorGroup(vecgroupid).DIMx = 2 * radius + 1
  1491. VectorGroup(vecgroupid).DIMy = 2 * radius + 1
  1492. VectorGroup(vecgroupid).DIMz = 2 * radius + 1
  1493. VectorGroup(vecgroupid).FirstVector = vectorindex + 1
  1494. FOR i = 1 TO xrange
  1495.     FOR j = 1 TO yrange
  1496.         vectorindex = vectorindex + 1
  1497.         theta = i * dx - dx
  1498.         phi = j * dy - dy
  1499.         vec3Dpos(vectorindex, 1) = au + radius * SIN(phi) * COS(theta)
  1500.         vec3Dpos(vectorindex, 2) = radius * SIN(phi) * SIN(theta)
  1501.         vec3Dpos(vectorindex, 3) = 90 + radius * COS(phi)
  1502.         vec3Danv(vectorindex, 1) = 0
  1503.         vec3Danv(vectorindex, 2) = 0
  1504.         vec3Danv(vectorindex, 3) = 1.5
  1505.         vec3Dvis(vectorindex) = 0
  1506.         IF RND > .5 THEN
  1507.             vec3Dcolor(vectorindex) = Gray
  1508.         ELSE
  1509.             vec3Dcolor(vectorindex) = PaleGoldenRod
  1510.         END IF
  1511.         GOSUB integratecom
  1512.         VectorGroup(vecgroupid).LastVector = vectorindex
  1513.         GOSUB calculatecom
  1514.     NEXT
  1515.  
  1516. 'Waves or Particles? (1)
  1517. FOR i = 1 TO 5 STEP 1
  1518.     FOR k = 1 TO 5 STEP 1
  1519.         groupidticker = groupidticker + 1
  1520.         vecgroupid = groupidticker
  1521.         VectorGroup(vecgroupid).Identity = vecgroupid
  1522.         VectorGroup(vecgroupid).Pointer = vecgroupid + 1
  1523.         VectorGroup(vecgroupid).Lagger = vecgroupid - 1
  1524.         VectorGroup(vecgroupid).GroupName = "Waves or Particles?"
  1525.         VectorGroup(vecgroupid).Visible = 0
  1526.         VectorGroup(vecgroupid).COMFixed = 1
  1527.         VectorGroup(vecgroupid).DIMx = 4
  1528.         VectorGroup(vecgroupid).DIMy = 1
  1529.         VectorGroup(vecgroupid).DIMz = 4
  1530.         VectorGroup(vecgroupid).FirstVector = vectorindex + 1
  1531.         FOR u = i TO i + 1 STEP .05
  1532.             FOR v = k TO k + 1 STEP .05
  1533.                 vectorindex = vectorindex + 1
  1534.                 vec3Dpos(vectorindex, 1) = 70 + 7 * u
  1535.                 vec3Dpos(vectorindex, 2) = 80 + 1 * COS((u ^ 2 - v ^ 2))
  1536.                 vec3Dpos(vectorindex, 3) = 10 + 7 * v
  1537.                 vec3Dvis(vectorindex) = 0
  1538.                 IF vec3Dpos(vectorindex, 2) < 80 THEN
  1539.                     vec3Dcolor(vectorindex) = DarkBlue
  1540.                 ELSE
  1541.                     vec3Dcolor(vectorindex) = DeepPink
  1542.                 END IF
  1543.                 GOSUB integratecom
  1544.             NEXT
  1545.         NEXT
  1546.         VectorGroup(vecgroupid).LastVector = vectorindex
  1547.         GOSUB calculatecom
  1548.     NEXT
  1549.  
  1550. 'Waves or Particles? (2)
  1551. FOR i = 1 TO 5 STEP 1
  1552.     FOR k = 1 TO 5 STEP 1
  1553.         groupidticker = groupidticker + 1
  1554.         vecgroupid = groupidticker
  1555.         VectorGroup(vecgroupid).Identity = vecgroupid
  1556.         VectorGroup(vecgroupid).Pointer = vecgroupid + 1
  1557.         VectorGroup(vecgroupid).Lagger = vecgroupid - 1
  1558.         VectorGroup(vecgroupid).GroupName = "Particles or Waves?"
  1559.         VectorGroup(vecgroupid).Visible = 0
  1560.         VectorGroup(vecgroupid).COMFixed = 1
  1561.         VectorGroup(vecgroupid).DIMx = 4
  1562.         VectorGroup(vecgroupid).DIMy = 1
  1563.         VectorGroup(vecgroupid).DIMz = 4
  1564.         VectorGroup(vecgroupid).FirstVector = vectorindex + 1
  1565.         FOR u = i TO i + 1 STEP .05
  1566.             FOR v = k TO k + 1 STEP .05
  1567.                 vectorindex = vectorindex + 1
  1568.                 vec3Dpos(vectorindex, 1) = -7 * u
  1569.                 vec3Dpos(vectorindex, 2) = 80 + 1 * COS(2 * ((u - 7) ^ 2 - (v - 5) ^ 2))
  1570.                 vec3Dpos(vectorindex, 3) = 10 + 7 * v
  1571.                 vec3Dvis(vectorindex) = 0
  1572.                 IF vec3Dpos(vectorindex, 2) < 80 THEN
  1573.                     vec3Dcolor(vectorindex) = Magenta
  1574.                 ELSE
  1575.                     vec3Dcolor(vectorindex) = Chocolate
  1576.                 END IF
  1577.                 GOSUB integratecom
  1578.             NEXT
  1579.         NEXT
  1580.         VectorGroup(vecgroupid).LastVector = vectorindex
  1581.         GOSUB calculatecom
  1582.     NEXT
  1583.  
  1584. '__ZZZ
  1585. groupidticker = groupidticker + 1
  1586. vecgroupid = groupidticker
  1587. VectorGroup(vecgroupid).Identity = vecgroupid
  1588. VectorGroup(vecgroupid).Pointer = -999
  1589. VectorGroup(vecgroupid).Lagger = vecgroupid - 1
  1590. VectorGroup(vecgroupid).GroupName = "__ZZZ"
  1591. VectorGroup(vecgroupid).COMFixed = 1
  1592. VectorGroup(vecgroupid).FirstVector = vectorindex + 1
  1593. FOR r = 1 TO 1
  1594.     vectorindex = vectorindex + 1
  1595.     vec3Dpos(vectorindex, 1) = 0
  1596.     vec3Dpos(vectorindex, 2) = 0
  1597.     vec3Dpos(vectorindex, 3) = -1000
  1598.     vec3Dcolor(vectorindex) = White
  1599.     GOSUB integratecom
  1600. VectorGroup(vecgroupid).LastVector = vectorindex
  1601. GOSUB calculatecom
  1602.  

screenshot.png

22
Utilities / Split1000 (simple string parser) Collaboration
« on: August 12, 2019, 08:50:44 am »
Split1000 (simple string parser)

Contributor(s): @bplus, @luke, @SMcNeill
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=1073.0
Tags: [string] [parsing]

Description:
This SUB will take a given N delimited string, and delimiter$ and creates an array of N+1 strings using the LBOUND of the given dynamic array to load.

Source Code:
Code: QB64: [Select]
  1. _TITLE "Split demo 2" ' started by B+ on 08-27-2019 to compare to Item$ demo
  2. 'new data setup structure to streamline code in setup
  3.  
  4. SCREEN _NEWIMAGE(400, 300, 32)
  5. 'globals seen inside SUBs and FUNCTIONs because SHARED
  6. DIM SHARED topIndex AS INTEGER '<< this is how many keywords we have
  7. 'VVVV REDIM means dynamic arrays, so can change in setup
  8. REDIM SHARED d(1 TO topIndex) AS STRING
  9.  
  10. 'locals just seen in following main code section
  11. REDIM LIST$(1 TO 1)
  12. setup
  13. FOR i = LBOUND(d) TO UBOUND(d) 'all the keywords are first word$ of d() data array
  14.     Split d(i), ",", LIST$()
  15.     PRINT "Data index:"; i; " "; "String Item:"; LBOUND(LIST$); LIST$(LBOUND(LIST$))
  16.     FOR j = LBOUND(LIST$) + 1 TO UBOUND(LIST$)
  17.         PRINT SPACE$(15); "String Item:"; j; LIST$(j) 'j-1 counts off the items after the first
  18.     NEXT
  19.     PRINT: INPUT "Ok... press enter "; w$
  20.     CLS
  21.  
  22. SUB setup '3rd method of data structure, this is meant to be edited over and over as add to a refine words and substitutes
  23.     topIndex = 5 ' <<< make modifications to d() and then update this number, that's it!
  24.     REDIM d(1 TO topIndex) AS STRING
  25.     d(1) = "Months,January,February,March,April,May,June,July,August,September,October,November,December"
  26.     d(2) = "Days,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday"
  27.     d(3) = "Holidays,NewYears Day,MLK Day,Valentine's Day,Easter,Mother's Day,Memorial Day,Father's Day,Independence Day,Bplus Day,Labor Day,Halloween,Thanksgiving,Christmas"
  28.     d(4) = "Test no further words/phrases in this line. (And the next test will do an empty string.)"
  29.     d(5) = ""
  30.  
  31. 'This SUB will take a given N delimited string, and delimiter$ and creates an array of N+1 strings using the LBOUND of the given dynamic array to load.
  32. 'notes: the loadMeArray() needs to be dynamic string array and will not change the LBOUND of the array it is given.
  33. SUB Split (SplitMeString AS STRING, delim AS STRING, loadMeArray() AS STRING)
  34.     DIM curpos AS LONG, arrpos AS LONG, LD AS LONG, dpos AS LONG 'fix use the Lbound the array already has
  35.     curpos = 1: arrpos = LBOUND(loadMeArray): LD = LEN(delim)
  36.     dpos = INSTR(curpos, SplitMeString, delim)
  37.     DO UNTIL dpos = 0
  38.         loadMeArray(arrpos) = MID$(SplitMeString, curpos, dpos - curpos)
  39.         arrpos = arrpos + 1
  40.         IF arrpos > UBOUND(loadMeArray) THEN REDIM _PRESERVE loadMeArray(LBOUND(loadMeArray) TO UBOUND(loadMeArray) + 1000) AS STRING
  41.         curpos = dpos + LD
  42.         dpos = INSTR(curpos, SplitMeString, delim)
  43.     LOOP
  44.     loadMeArray(arrpos) = MID$(SplitMeString, curpos)
  45.     REDIM _PRESERVE loadMeArray(LBOUND(loadMeArray) TO arrpos) AS STRING 'get the ubound correct
  46.  

screenshot.PNG

Bplus Edit: bplus version was collaboration of @bplus, @luke, @SMcNeill URL where the original discussion was started by Luke contains his complementary Join function. The above is bplus version with a couple of revisions tweaked into it since first posting.

23
Utilities / BIN$ (binary converter) by RhoSigma
« on: August 11, 2019, 01:50:39 pm »
BIN$ (binary converter)

Contributor(s): @RhoSigma
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=4261.msg136393#msg136393
Tags: [binary] [number conversion]

Description:
Although there are already many approaches for a BIN$ function in the Forum, some of my own, some from bplus and Steve McNeill and probably others, I felt there should be one, which best mimics the regular behavior and results of the built-in HEX$ and OCT$ functions, rather than focusing on speed or extended flexibility.

So here it is:
can handle positive and negative numbers
returns the binary string without &B prefix, just as HEX$ and OCT$ do
the result for positive numbers is just as long as needed, ie. no leading zeros are returned
the result length for negative numbers is determined by the integer range, which the given input number does fit in, eg. 8 for numbers in _BYTE range (down until -128), 16 for INTEGER (down until -32768) etc..


Source Code:
Code: QB64: [Select]
  1.     _TITLE "Bin$ Example"
  2.     '=== Full description for the Bin$() function is available
  3.     '=== in the separate HTML document.
  4.     '=====================================================================
  5.      
  6.     '-- some usage examples
  7.     PRINT "some simple numbers..."
  8.     num& = 5: PRINT num&; "= "; Bin$(num&)
  9.     num& = -4: PRINT num&; "= "; Bin$(num&)
  10.     num& = 32000: PRINT num&; "= "; Bin$(num&)
  11.     PRINT
  12.      
  13.     PRINT "works also with &B, &H and &O..."
  14.     PRINT " &B1101 = "; Bin$(&B1101)
  15.     PRINT " &H211 = "; Bin$(&H211)
  16.     PRINT " &O377 = "; Bin$(&O377)
  17.     PRINT
  18.      
  19.     PRINT "and even with floating points (converts integer part only)..."
  20.     num# = 123.456: PRINT num#; "= "; Bin$(num#)
  21.     num# = -60000.25: PRINT num#; "= "; Bin$(num#)
  22.     num# = 0.5: PRINT num#; "= "; Bin$(num#)
  23.     PRINT
  24.      
  25.     '-- done
  26.     END
  27.      
  28.      
  29.      
  30.      
  31.     '--- Full description available in separate HTML document.
  32.     '---------------------------------------------------------------------
  33.     FUNCTION Bin$ (value&&)
  34.     '--- option _explicit requirements ---
  35.     DIM temp~&&, binStr$, charPos%, highPos%
  36.     '--- init ---
  37.     temp~&& = value&&
  38.     binStr$ = STRING$(64, "0"): charPos% = 64: highPos% = 64
  39.     '--- convert ---
  40.     DO
  41.         IF (temp~&& AND 1) THEN MID$(binStr$, charPos%, 1) = "1": highPos% = charPos%
  42.         charPos% = charPos% - 1: temp~&& = temp~&& \ 2
  43.     LOOP UNTIL temp~&& = 0
  44.     '--- adjust negative size ---
  45.     IF value&& < 0 THEN
  46.         IF -value&& < &H0080000000~&& THEN highPos% = 33
  47.         IF -value&& < &H0000008000~&& THEN highPos% = 49
  48.         IF -value&& < &H0000000080~&& THEN highPos% = 57
  49.     END IF
  50.     '--- set result ---
  51.     Bin$ = MID$(binStr$, highPos%)
  52.      
  53.  

 
screenshot.jpg
 

 

Librarian's note: RhoSigma is author of the &B updates to QB64, and this BIN$ should serve as best complement to &B thus the replacement of the old BIN$ code; screenshot contains new range of numbers that this BIN$ can do.

24
Utilities / _MEM Sort by SMcNeill
« on: August 11, 2019, 12:51:49 pm »
_MEM Sort

Contributor(s): @SMcNeill
Source: qb64 @ Freeformus
URL: http://qb64.freeforums.net/thread/28/mem-sort
Tags: [_MEM] [sort]

Description:
The following routine is a quick and efficient way to sort almost any type of array, regardless of data type. (The one thing it doesn't sort is variable-length strings, as _MEM doesn't support those at all.)

Source Code:
Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(1280, 720, 256)
  2.  
  3. DIM x(5) AS _BYTE
  4. DIM z(5) AS STRING * 5
  5.  
  6. 'Let's see if we can sort the integer array
  7. 'Initialize Data
  8. FOR i = 0 TO 5: x(i) = RND * 100: PRINT x(i),: NEXT: PRINT
  9. PRINT "----------------------------------------------------------------------------------------------------------------------------------------------------------------"
  10.  
  11. 'Sort
  12. m = _MEM(x())
  13. Sort m
  14.  
  15. 'Result
  16. FOR i = 0 TO 5: PRINT x(i),: NEXT: PRINT
  17.  
  18. PRINT "----------------------------------------------------------------------------------------------------------------------------------------------------------------"
  19.  
  20.  
  21. 'Try the same routine with a different data type array to sort
  22. 'Initialize Data
  23. FOR i = 0 TO 7: y(i) = RND * 100: PRINT y(i),: NEXT
  24. PRINT "----------------------------------------------------------------------------------------------------------------------------------------------------------------"
  25.  
  26. 'Sort
  27. m = _MEM(y())
  28. Sort m
  29.  
  30. 'Result
  31. FOR i = 0 TO 7: PRINT y(i),: NEXT: PRINT
  32. PRINT "----------------------------------------------------------------------------------------------------------------------------------------------------------------"
  33.  
  34.  
  35. 'To test with fixed length string arrays
  36. z(0) = "Doggy": z(1) = "Pudding": z(2) = "Frog ": z(3) = "test2": z(4) = "Test2": z(5) = "test1"
  37. FOR i = 0 TO 5: PRINT z(i),: NEXT: PRINT
  38. PRINT "----------------------------------------------------------------------------------------------------------------------------------------------------------------"
  39.  
  40. m = _MEM(z())
  41. Sort m
  42.  
  43. 'Result
  44. FOR i = 0 TO 5: PRINT z(i),: NEXT: PRINT
  45.  
  46.  
  47.  
  48.  
  49. SUB Sort (m AS _MEM)
  50.     $IF 64BIT THEN
  51.         DIM ES AS _INTEGER64, EC AS _INTEGER64
  52.     $ELSE
  53.         DIM ES AS LONG, EC AS LONG
  54.     $END IF
  55.  
  56.     IF NOT m.TYPE AND 65536 THEN EXIT SUB 'We won't work without an array
  57.     IF m.TYPE AND 1024 THEN DataType = 10
  58.     IF m.TYPE AND 1 THEN DataType = DataType + 1
  59.     IF m.TYPE AND 2 THEN DataType = DataType + 2
  60.     IF m.TYPE AND 4 THEN IF m.TYPE AND 128 THEN DataType = DataType + 4 ELSE DataType = 3
  61.     IF m.TYPE AND 8 THEN IF m.TYPE AND 128 THEN DataType = DataType + 8 ELSE DataType = 5
  62.     IF m.TYPE AND 32 THEN DataType = 6
  63.     IF m.TYPE AND 512 THEN DataType = 7
  64.  
  65.     'Convert our offset data over to something we can work with
  66.     DIM m1 AS _MEM: m1 = _MEMNEW(LEN(ES))
  67.     _MEMPUT m1, m1.OFFSET, m.ELEMENTSIZE: _MEMGET m1, m1.OFFSET, ES 'Element Size
  68.     _MEMPUT m1, m1.OFFSET, m.SIZE: _MEMGET m1, m1.OFFSET, EC 'Element Count will temporily hold the WHOLE array size
  69.     _MEMFREE m1
  70.  
  71.     EC = EC / ES - 1 'Now we take the whole element size / the size of the elements and get our actual element count.  We subtract 1 so our arrays start at 0 and not 1.
  72.     'And work with it!
  73.     DIM o AS _OFFSET, o1 AS _OFFSET, counter AS _UNSIGNED LONG
  74.  
  75.     SELECT CASE DataType
  76.         CASE 1 'BYTE
  77.             DIM temp1(-128 TO 127) AS _UNSIGNED LONG
  78.             DIM t1 AS _BYTE
  79.             i = 0
  80.             DO
  81.                 _MEMGET m, m.OFFSET + i, t1
  82.                 temp1(t1) = temp1(t1) + 1
  83.                 i = i + 1
  84.             LOOP UNTIL i > EC
  85.             i1 = -128
  86.             DO
  87.                 DO UNTIL temp1(i1) = 0
  88.                     _MEMPUT m, m.OFFSET + counter, i1 AS _BYTE
  89.                     counter = counter + 1
  90.                     temp1(i1) = temp1(i1) - 1
  91.                     IF counter > EC THEN EXIT SUB
  92.                 LOOP
  93.                 i1 = i1 + 1
  94.             LOOP UNTIL i1 > 127
  95.         CASE 2: 'INTEGER
  96.             DIM temp2(-32768 TO 32767) AS _UNSIGNED LONG
  97.             DIM t2 AS INTEGER
  98.             i = 0
  99.             DO
  100.                 _MEMGET m, m.OFFSET + i * 2, t2
  101.                 temp2(t2) = temp2(t2) + 1
  102.                 i = i + 1
  103.             LOOP UNTIL i > EC
  104.             i1 = -32768
  105.             DO
  106.                 DO UNTIL temp2(i1) = 0
  107.                     _MEMPUT m, m.OFFSET + counter * 2, i1 AS INTEGER
  108.                     counter = counter + 1
  109.                     temp2(i1) = temp2(i1) - 1
  110.                     IF counter > EC THEN EXIT SUB
  111.                 LOOP
  112.                 i1 = i1 + 1
  113.             LOOP UNTIL i1 > 32767
  114.         CASE 3 'SINGLE
  115.             DIM T3a AS SINGLE, T3b AS SINGLE
  116.             gap = EC
  117.             DO
  118.                 gap = 10 * gap \ 13
  119.                 IF gap < 1 THEN gap = 1
  120.                 i = 0
  121.                 swapped = 0
  122.                 DO
  123.                     o = m.OFFSET + i * 4
  124.                     o1 = m.OFFSET + (i + gap) * 4
  125.                     IF _MEMGET(m, o, SINGLE) > _MEMGET(m, o1, SINGLE) THEN
  126.                         _MEMGET m, o1, T3a
  127.                         _MEMGET m, o, T3b
  128.                         _MEMPUT m, o1, T3b
  129.                         _MEMPUT m, o, T3a
  130.                         swapped = -1
  131.                     END IF
  132.                     i = i + 1
  133.                 LOOP UNTIL i + gap > EC
  134.             LOOP UNTIL gap = 1 AND swapped = 0
  135.         CASE 4 'LONG
  136.             DIM T4a AS LONG, T4b AS LONG
  137.             gap = EC
  138.             DO
  139.                 gap = 10 * gap \ 13
  140.                 IF gap < 1 THEN gap = 1
  141.                 i = 0
  142.                 swapped = 0
  143.                 DO
  144.                     o = m.OFFSET + i * 4
  145.                     o1 = m.OFFSET + (i + gap) * 4
  146.                     IF _MEMGET(m, o, LONG) > _MEMGET(m, o1, LONG) THEN
  147.                         _MEMGET m, o1, T4a
  148.                         _MEMGET m, o, T4b
  149.                         _MEMPUT m, o1, T4b
  150.                         _MEMPUT m, o, T4a
  151.                         swapped = -1
  152.                     END IF
  153.                     i = i + 1
  154.                 LOOP UNTIL i + gap > EC
  155.             LOOP UNTIL gap = 1 AND swapped = 0
  156.         CASE 5 'DOUBLE
  157.             DIM T5a AS DOUBLE, T5b AS DOUBLE
  158.             gap = EC
  159.             DO
  160.                 gap = 10 * gap \ 13
  161.                 IF gap < 1 THEN gap = 1
  162.                 i = 0
  163.                 swapped = 0
  164.                 DO
  165.                     o = m.OFFSET + i * 8
  166.                     o1 = m.OFFSET + (i + gap) * 8
  167.                     IF _MEMGET(m, o, DOUBLE) > _MEMGET(m, o1, DOUBLE) THEN
  168.                         _MEMGET m, o1, T5a
  169.                         _MEMGET m, o, T5b
  170.                         _MEMPUT m, o1, T5b
  171.                         _MEMPUT m, o, T5a
  172.                         swapped = -1
  173.                     END IF
  174.                     i = i + 1
  175.                 LOOP UNTIL i + gap > EC
  176.             LOOP UNTIL gap = 1 AND swapped = 0
  177.         CASE 6 ' _FLOAT
  178.             DIM T6a AS _FLOAT, T6b AS _FLOAT
  179.             gap = EC
  180.             DO
  181.                 gap = 10 * gap \ 13
  182.                 IF gap < 1 THEN gap = 1
  183.                 i = 0
  184.                 swapped = 0
  185.                 DO
  186.                     o = m.OFFSET + i * 32
  187.                     o1 = m.OFFSET + (i + gap) * 32
  188.                     IF _MEMGET(m, o, _FLOAT) > _MEMGET(m, o1, _FLOAT) THEN
  189.                         _MEMGET m, o1, T6a
  190.                         _MEMGET m, o, T6b
  191.                         _MEMPUT m, o1, T6b
  192.                         _MEMPUT m, o, T6a
  193.                         swapped = -1
  194.                     END IF
  195.                     i = i + 1
  196.                 LOOP UNTIL i + gap > EC
  197.             LOOP UNTIL gap = 1 AND swapped = 0
  198.         CASE 7 'String
  199.             DIM T7a AS STRING, T7b AS STRING, T7c AS STRING
  200.             T7a = SPACE$(ES): T7b = SPACE$(ES): T7c = SPACE$(ES)
  201.             gap = EC
  202.             DO
  203.                 gap = INT(gap / 1.247330950103979)
  204.                 IF gap < 1 THEN gap = 1
  205.                 i = 0
  206.                 swapped = 0
  207.                 DO
  208.                     o = m.OFFSET + i * ES
  209.                     o1 = m.OFFSET + (i + gap) * ES
  210.                     _MEMGET m, o, T7a
  211.                     _MEMGET m, o1, T7b
  212.                     IF T7a > T7b THEN
  213.                         T7c = T7b
  214.                         _MEMPUT m, o1, T7a
  215.                         _MEMPUT m, o, T7c
  216.                         swapped = -1
  217.                     END IF
  218.                     i = i + 1
  219.                 LOOP UNTIL i + gap > EC
  220.             LOOP UNTIL gap = 1 AND swapped = false
  221.         CASE 8 '_INTEGER64
  222.             DIM T8a AS _INTEGER64, T8b AS _INTEGER64
  223.             gap = EC
  224.             DO
  225.                 gap = 10 * gap \ 13
  226.                 IF gap < 1 THEN gap = 1
  227.                 i = 0
  228.                 swapped = 0
  229.                 DO
  230.                     o = m.OFFSET + i * 8
  231.                     o1 = m.OFFSET + (i + gap) * 8
  232.                     IF _MEMGET(m, o, _INTEGER64) > _MEMGET(m, o1, _INTEGER64) THEN
  233.                         _MEMGET m, o1, T8a
  234.                         _MEMGET m, o, T8b
  235.                         _MEMPUT m, o1, T8b
  236.                         _MEMPUT m, o, T8a
  237.                         swapped = -1
  238.                     END IF
  239.                     i = i + 1
  240.                 LOOP UNTIL i + gap > EC
  241.             LOOP UNTIL gap = 1 AND swapped = 0
  242.         CASE 11: '_UNSIGNED _BYTE
  243.             DIM temp11(0 TO 255) AS _UNSIGNED LONG
  244.             DIM t11 AS _UNSIGNED _BYTE
  245.             i = 0
  246.             DO
  247.                 _MEMGET m, m.OFFSET + i, t11
  248.                 temp11(t11) = temp11(t11) + 1
  249.                 i = i + 1
  250.             LOOP UNTIL i > EC
  251.             i1 = 0
  252.             DO
  253.                 DO UNTIL temp11(i1) = 0
  254.                     _MEMPUT m, m.OFFSET + counter, i1 AS _UNSIGNED _BYTE
  255.                     counter = counter + 1
  256.                     temp11(i1) = temp11(i1) - 1
  257.                     IF counter > EC THEN EXIT SUB
  258.                 LOOP
  259.                 i1 = i1 + 1
  260.             LOOP UNTIL i1 > 255
  261.         CASE 12 '_UNSIGNED INTEGER
  262.             DIM temp12(0 TO 65535) AS _UNSIGNED LONG
  263.             DIM t12 AS _UNSIGNED INTEGER
  264.             i = 0
  265.             DO
  266.                 _MEMGET m, m.OFFSET + i * 2, t12
  267.                 temp12(t12) = temp12(t12) + 1
  268.                 i = i + 1
  269.             LOOP UNTIL i > EC
  270.             i1 = 0
  271.             DO
  272.                 DO UNTIL temp12(i1) = 0
  273.                     _MEMPUT m, m.OFFSET + counter * 2, i1 AS _UNSIGNED INTEGER
  274.                     counter = counter + 1
  275.                     temp12(i1) = temp12(i1) - 1
  276.                     IF counter > EC THEN EXIT SUB
  277.                 LOOP
  278.                 i1 = i1 + 1
  279.             LOOP UNTIL i1 > 65535
  280.         CASE 14 '_UNSIGNED LONG
  281.             DIM T14a AS _UNSIGNED LONG, T14b AS _UNSIGNED LONG
  282.             gap = EC
  283.             DO
  284.                 gap = 10 * gap \ 13
  285.                 IF gap < 1 THEN gap = 1
  286.                 i = 0
  287.                 swapped = 0
  288.                 DO
  289.                     o = m.OFFSET + i * 4
  290.                     o1 = m.OFFSET + (i + gap) * 4
  291.                     IF _MEMGET(m, o, _UNSIGNED LONG) > _MEMGET(m, o1, _UNSIGNED LONG) THEN
  292.                         _MEMGET m, o1, T14a
  293.                         _MEMGET m, o, T14b
  294.                         _MEMPUT m, o1, T14b
  295.                         _MEMPUT m, o, T14a
  296.                         swapped = -1
  297.                     END IF
  298.                     i = i + 1
  299.                 LOOP UNTIL i + gap > EC
  300.             LOOP UNTIL gap = 1 AND swapped = 0
  301.         CASE 18: '_UNSIGNED _INTEGER64
  302.             DIM T18a AS _UNSIGNED _INTEGER64, T18b AS _UNSIGNED _INTEGER64
  303.             gap = EC
  304.             DO
  305.                 gap = 10 * gap \ 13
  306.                 IF gap < 1 THEN gap = 1
  307.                 i = 0
  308.                 swapped = 0
  309.                 DO
  310.                     o = m.OFFSET + i * 8
  311.                     o1 = m.OFFSET + (i + gap) * 8
  312.                     IF _MEMGET(m, o, _UNSIGNED _INTEGER64) > _MEMGET(m, o1, _UNSIGNED _INTEGER64) THEN
  313.                         _MEMGET m, o1, T18a
  314.                         _MEMGET m, o, T18b
  315.                         _MEMPUT m, o1, T18b
  316.                         _MEMPUT m, o, T18a
  317.                         swapped = -1
  318.                     END IF
  319.                     i = i + 1
  320.                 LOOP UNTIL i + gap > EC
  321.             LOOP UNTIL gap = 1 AND swapped = 0
  322.     END SELECT
  323.  

screenshot.png

25
Utilities / Extended (Unix Epoch) Timer by SMcNeill
« on: August 11, 2019, 05:29:22 am »
Extended (Unix Epoch) Timer

Contributor(s): @SMcNeill
Source: qb64 @ Freeforums
URL: http://qb64.freeforums.net/thread/20/extended-timer-uet
Tags: [date], [time], [timer]

Description:
The Unix Epoch Time is a popular timekeeping standard based on the number of seconds elapsed since midnight on Jan 1, 1970 in Greenwich, London. The Extended Timer function below will calculate the (relative) Unix epoch time from the local system time and date.

Source Code:
Code: QB64: [Select]
  1. SHELL "https://www.epochconverter.com/"
  2.     CLS
  3.     PRINT TIMER, INT(ExtendedTimer)
  4.     PRINT "Compare to the time at https://www.epochconverter.com/"
  5.     _DISPLAY
  6.     _LIMIT 10
  7.  
  8. FUNCTION ExtendedTimer##
  9.     d$ = DATE$
  10.     l = INSTR(d$, "-")
  11.     l1 = INSTR(l + 1, d$, "-")
  12.     m = VAL(LEFT$(d$, l))
  13.     d = VAL(MID$(d$, l + 1))
  14.     y = VAL(MID$(d$, l1 + 1)) - 1970
  15.     FOR i = 1 TO m
  16.         SELECT CASE i 'Add the number of days for each previous month passed
  17.             CASE 1: d = d 'January doestn't have any carry over days.
  18.             CASE 2, 4, 6, 8, 9, 11: d = d + 31
  19.             CASE 3: d = d + 28
  20.             CASE 5, 7, 10, 12: d = d + 30
  21.         END SELECT
  22.     NEXT
  23.     FOR i = 1 TO y
  24.         d = d + 365
  25.     NEXT
  26.     FOR i = 2 TO y STEP 4
  27.         IF m > 2 THEN d = d + 1 'add an extra day for leap year every 4 years, starting in 1970
  28.     NEXT
  29.     d = d - 1 'for year 2000
  30.     s~&& = d * 24 * 60 * 60 'Seconds are days * 24 hours * 60 minutes * 60 seconds
  31.     ExtendedTimer## = (s~&& + TIMER)
  32.  

screenshot.png

26
Programs / Samples/Toolbox re-awakening. Call for entries.
« on: August 10, 2019, 08:49:24 pm »
As the topic says, it's time we expand our Samples Gallery and Toolbox. Please reply to this post with links to existing threads in Programs with code that qualifies.

First things first though - is everyone happy with the filled circle/ellipse code up there?

27
2D/3D Graphics / Inverse Julia Fractal Explorer by Zom-B
« on: February 06, 2019, 08:46:40 pm »
Inverse Julia Fractal Explorer

Author: Zom-B
Source: [abandoned, outdated and now likely malicious qb64 dot net website - don’t go there] Forum
URL: /forum/index.php?topic=1132.0]http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index.php?topic=1132.0
Version: QB64
Tags: [fractal] [inverse julia set]

Description:
The longer you hold your mouse at one position, the more it starts to glow.

Source Code:
Code: QB64: [Select]
  1. DEFSNG A-Z
  2.  
  3. DIM SHARED px, py, cx, cy
  4.  
  5. SCREEN _NEWIMAGE(1024, 768, 256)
  6.  
  7. COLOR 255
  8. FOR i% = 0 TO 255
  9.     r% = INT((i% / 255) ^ .9323335 * 255)
  10.     g% = INT((i% / 255) ^ 1.576838 * 255)
  11.     b% = INT((i% / 255) ^ 3.484859 * 255)
  12.     _PALETTECOLOR i%, _RGB32(r%, g%, b%)
  13.  
  14. '####################################################################################################################
  15.  
  16. setSeed _MOUSEX, _MOUSEY
  17.  
  18.         n% = 0
  19.         _DISPLAY
  20.         CLS
  21.         setSeed _MOUSEX, _MOUSEY
  22.     END IF
  23.  
  24.     DO 'Marsaglia polar method for random gaussian
  25.         u = RND * 2 - 1
  26.         v = RND2 * 2 - 1
  27.         s = u * u + v * v
  28.     LOOP WHILE s >= 1 OR s = 0
  29.     s = SQR(-2 * LOG(s) / s) * 0.5
  30.     u = u * s * 2
  31.     v = v * s * 2
  32.  
  33.     calcInverseJulia u, v, 1
  34.  
  35.     n% = n% + 1
  36.     IF n% = 300 THEN
  37.         n% = 0
  38.         _DISPLAY
  39.     END IF
  40.  
  41. '####################################################################################################################
  42.  
  43. SUB setSeed (x, y)
  44.     cx = (x / _WIDTH - 0.5) * 4
  45.     cy = (0.5 - y / _HEIGHT) * 3
  46.  
  47. '####################################################################################################################
  48.  
  49. SUB calcInverseJulia (x, y, depth%)
  50.     re = x - cx
  51.     im = y - cy
  52.  
  53.     a = SQR(re * re + im * im)
  54.     x = SQR((a + re) * 0.5)
  55.     IF im < 0 THEN y = -SQR((a - re) * 0.5) ELSE y = SQR((a - re) * 0.5)
  56.  
  57.     PSET2 (x / 4 + 0.5) * _WIDTH, (0.5 - y / 3) * _HEIGHT, 0.02
  58.     PSET2 (x / -4 + 0.5) * _WIDTH, (0.5 + y / 3) * _HEIGHT, 0.02
  59.     IF depth% < 32 THEN
  60.         IF RND < 0.5 THEN calcInverseJulia x, y, depth% + 1 ELSE calcInverseJulia -x, -y, depth% + 1
  61.     END IF
  62.  
  63. '####################################################################################################################
  64.  
  65. SUB PSET2 (x, y, i)
  66.     x% = INT(x)
  67.     y% = INT(y)
  68.     dx = x - x%
  69.     dy = y - y%
  70.  
  71.     q3 = dx * dy
  72.     q2 = (1 - dx) * dy
  73.     q1 = dx * (1 - dy)
  74.     q0 = (1 - dx) * (1 - dy)
  75.  
  76.     PSET (x%, y%), (1 - (1 - q0 * i) * (1 - POINT(x%, y%) / 255)) * 255
  77.     PSET (x% + 1, y%), (1 - (1 - q1 * i) * (1 - POINT(x% + 1, y%) / 255)) * 255
  78.     PSET (x%, y% + 1), (1 - (1 - q2 * i) * (1 - POINT(x%, y% + 1) / 255)) * 255
  79.     PSET (x% + 1, y% + 1), (1 - (1 - q3 * i) * (1 - POINT(x% + 1, y% + 1) / 255)) * 255
  80.  
  81. '####################################################################################################################
  82.  
  83.     seed&& = (25214903917&& * seed&& + 11&&) MOD 281474976710656&&
  84.     RND2 = seed&& / 281474976710656&&
  85.  

inversejulia.png

28
2D/3D Graphics / Julia Rings by Relsoft
« on: February 06, 2019, 08:38:50 pm »
Julia Rings

Author: Relsoft
Source: [abandoned, outdated and now likely malicious qb64 dot net website - don’t go there] Forum
URL: /forum/index.php?topic=128.0]http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/forum/index.php?topic=128.0
Version: QB64
Tags: [fractal] [julia set]

Description:
Automated Julia set explorer.

Source Code:
Code: QB64: [Select]
  1. ' The Lord of the Julia Rings
  2. ' The Fellowship of the Julia Ring
  3. ' Free Basic
  4. ' Relsoft
  5. ' Rel.BetterWebber.com
  6. '
  7. ' Converted to QB64 format by Galleon (FB specific code commented)
  8.  
  9. DEFLNG A-Z
  10.  
  11. ''$include: 'TinyPTC.bi'
  12. ''$include: 'user32.bi'
  13.  
  14. 'option explicit
  15.  
  16. CONST SCR_WIDTH = 320 * 2
  17. CONST SCR_HEIGHT = 240 * 2
  18.  
  19. CONST SCR_SIZE = SCR_WIDTH * SCR_HEIGHT
  20. CONST SCR_MIDX = SCR_WIDTH \ 2
  21. CONST SCR_MIDY = SCR_HEIGHT \ 2
  22.  
  23. CONST FALSE = 0, TRUE = NOT FALSE
  24.  
  25. CONST PI = 3.141593
  26. CONST MAXITER = 20
  27. CONST MAXSIZE = 4
  28.  
  29. DIM Buffer(SCR_SIZE - 1) AS LONG
  30. DIM Lx(SCR_WIDTH - 1) AS SINGLE
  31. DIM Ly(SCR_HEIGHT - 1) AS SINGLE
  32. DIM sqrt(SCR_SIZE - 1) AS SINGLE
  33.  
  34. 'if( ptc_open( "FreeBASIC Julia (Relsoft)", SCR_WIDTH, SCR_HEIGHT ) = 0 ) then
  35. '   end -1
  36. 'end if
  37.  
  38. SCREEN _NEWIMAGE(SCR_WIDTH, SCR_HEIGHT, 32), , 1, 0
  39.  
  40. DIM px AS LONG, py AS LONG
  41. DIM xmin AS SINGLE, xmax AS SINGLE, ymin AS SINGLE, ymax AS SINGLE
  42. DIM theta AS SINGLE
  43. DIM deltax AS SINGLE, deltay AS SINGLE
  44. DIM xsquare AS SINGLE, ysquare AS SINGLE
  45. DIM ytemp AS SINGLE
  46. DIM temp1 AS SINGLE, temp2 AS SINGLE
  47. DIM i AS LONG, pixel AS LONG
  48. DIM r AS LONG, g AS LONG, b AS LONG
  49. DIM red AS LONG, grn AS LONG, blu AS LONG
  50. DIM tmp AS LONG, i_last AS LONG
  51.  
  52. DIM cmagsq AS SINGLE
  53. DIM drad_L AS SINGLE
  54. DIM drad_H AS SINGLE
  55. DIM ztoti AS LONG
  56.  
  57. 'pointers to array "buffer"
  58. 'dim p_buffer as long ptr, p_bufferl as long ptr
  59.  
  60. xmin = -2.0
  61. xmax = 2.0
  62. ymin = -1.5
  63. ymax = 1.5
  64.  
  65. deltax = (xmax - xmin) / (SCR_WIDTH - 1)
  66. deltay = (ymax - ymin) / (SCR_HEIGHT - 1)
  67.  
  68. FOR i = 0 TO SCR_WIDTH - 1
  69.     Lx(i) = xmin + i * deltax
  70.  
  71. FOR i = 0 TO SCR_HEIGHT - 1
  72.     Ly(i) = ymax - i * deltay
  73.  
  74. FOR i = 0 TO SCR_SIZE - 1
  75.     sqrt(i) = SQR(i)
  76.  
  77. 'dim hwnd as long
  78. 'hwnd = GetActiveWindow
  79.  
  80. DIM stime AS LONG, Fps AS SINGLE, Fps2 AS SINGLE
  81.  
  82. stime = TIMER
  83.  
  84.  
  85.     '    p_buffer = @buffer(0)
  86.     '    p_bufferl = @buffer(SCR_SIZE-1)
  87.  
  88.     frame = (frame + 1) AND &H7FFFFFFF
  89.     theta = frame * PI / 180
  90.  
  91.     p = COS(theta) * SIN(theta * .7)
  92.     q = SIN(theta) + SIN(theta)
  93.     p = p * .6
  94.     q = q * .6
  95.  
  96.     cmag = SQR(p * p + q * q)
  97.     cmagsq = (p * p + q * q)
  98.     drad = 0.04
  99.     drad_L = (cmag - drad)
  100.     drad_L = drad_L * drad_L
  101.     drad_H = (cmag + drad)
  102.     drad_H = drad_H * drad_H
  103.  
  104.     FOR py = 0 TO (SCR_HEIGHT \ 2) - 1
  105.         ty = Ly(py)
  106.         FOR px = 0 TO SCR_WIDTH - 1
  107.             x = Lx(px)
  108.             y = ty
  109.             xsquare = 0
  110.             ysquare = 0
  111.             ztot = 0
  112.             i = 0
  113.             WHILE (i < MAXITER) AND ((xsquare + ysquare) < MAXSIZE)
  114.                 xsquare = x * x
  115.                 ysquare = y * y
  116.                 ytemp = x * y * 2
  117.                 x = xsquare - ysquare + p
  118.                 y = ytemp + q
  119.                 zmag = (x * x + y * y)
  120.                 IF (zmag < drad_H) AND (zmag > drad_L) AND (i > 0) THEN
  121.                     ztot = ztot + (1 - (ABS(zmag - cmagsq) / drad))
  122.                     i_last = i
  123.                 END IF
  124.                 i = i + 1
  125.                 IF zmag > 4.0 THEN
  126.                     EXIT WHILE
  127.                 END IF
  128.             WEND
  129.  
  130.             IF ztot > 0 THEN
  131.                 i = CINT(SQR(ztot) * 500)
  132.             ELSE
  133.                 i = 0
  134.             END IF
  135.             IF i < 256 THEN
  136.                 red = i
  137.             ELSE
  138.                 red = 255
  139.             END IF
  140.  
  141.             IF i < 512 AND i > 255 THEN
  142.                 grn = i - 256
  143.             ELSE
  144.                 IF i >= 512 THEN
  145.                     grn = 255
  146.                 ELSE
  147.                     grn = 0
  148.                 END IF
  149.             END IF
  150.  
  151.             IF i <= 768 AND i > 511 THEN
  152.                 blu = i - 512
  153.             ELSE
  154.                 IF i >= 768 THEN
  155.                     blu = 255
  156.                 ELSE
  157.                     blu = 0
  158.                 END IF
  159.             END IF
  160.  
  161.             tmp = INT((red + grn + blu) \ 3)
  162.             red = INT((red + grn + tmp) \ 3)
  163.             grn = INT((grn + blu + tmp) \ 3)
  164.             blu = INT((blu + red + tmp) \ 3)
  165.  
  166.             SELECT CASE (i_last MOD 3)
  167.                 CASE 1
  168.                     tmp = red
  169.                     red = grn
  170.                     grn = blu
  171.                     blu = tmp
  172.                 CASE 2
  173.                     tmp = red
  174.                     blu = grn
  175.                     red = blu
  176.                     grn = tmp
  177.             END SELECT
  178.  
  179.             'pixel = red shl 16 or grn shl 8 or blu
  180.             '*p_buffer = pixel
  181.             '*p_bufferl = pixel
  182.             'p_buffer = p_buffer + Len(long)
  183.             'p_bufferl = p_bufferl - Len(long)
  184.             pixel = _RGB32(red, grn, blu)
  185.             PSET (px, py), pixel
  186.             PSET (SCR_WIDTH - 1 - px, SCR_HEIGHT - 1 - py), pixel
  187.  
  188.         NEXT px
  189.     NEXT py
  190.  
  191.     'calc fps
  192.     Fps = Fps + 1
  193.     IF stime + 1 < TIMER THEN
  194.         Fps2 = Fps
  195.         Fps = 0
  196.         stime = TIMER
  197.     END IF
  198.  
  199.     '    SetWindowText hwnd, "FreeBasic Julia Rings FPS:" + str$(Fps2)
  200.     LOCATE 1, 1: PRINT "QB64 Julia Rings FPS:" + STR$(Fps2)
  201.  
  202.     'ptc_update @buffer(0)
  203.     PCOPY 1, 0
  204.  
  205.  
  206. 'ptc_close
  207.  
  208.  

julia.png

29
Games / Tetris by _vince
« on: September 27, 2018, 10:37:42 pm »
Tetris

Author: @_vince
Source: qb64.org Forum
URL: https://www.qb64.org/forum/index.php?topic=626.0
Version: 2018
Tags: [2d], [game], [tetris]

Description:
clean and simple tetris implementation. you can change variables size, sw, and sh for custom board sizes.

20:55 < _vince> ive said it before but i think tetris is the ultimate test of a
                programmer
20:55 < _vince> as it combines all programming concepts but doesnt demand any
                specialized knowledge


controls:
* arrow keys: movement, up: rotate
* shift + left/right/down: hard left/right/drop
* spacebar: hard drop
* +/-: change speed
* p: pause
* Enter: restart
* Esc: quit


Source Code:
Code: QB64: [Select]
  1. deflng a-z
  2.  
  3. dim shared piece(6, 3, 1)
  4. dim shared piece_color(6)
  5. dim shared size, sw, sh
  6.  
  7. size = 35
  8. sw = 10
  9. sh = 20
  10.  
  11. redim shared board(sw - 1, sh - 1)
  12.  
  13. piece(0,0,0)=0: piece(0,1,0)=1: piece(0,2,0)=1: piece(0,3,0)=0
  14. piece(0,0,1)=0: piece(0,1,1)=1: piece(0,2,1)=1: piece(0,3,1)=0
  15. piece(1,0,0)=1: piece(1,1,0)=1: piece(1,2,0)=1: piece(1,3,0)=1
  16. piece(1,0,1)=0: piece(1,1,1)=0: piece(1,2,1)=0: piece(1,3,1)=0
  17. piece(2,0,0)=0: piece(2,1,0)=0: piece(2,2,0)=1: piece(2,3,0)=1
  18. piece(2,0,1)=0: piece(2,1,1)=1: piece(2,2,1)=1: piece(2,3,1)=0
  19. piece(3,0,0)=0: piece(3,1,0)=1: piece(3,2,0)=1: piece(3,3,0)=0
  20. piece(3,0,1)=0: piece(3,1,1)=0: piece(3,2,1)=1: piece(3,3,1)=1
  21. piece(4,0,0)=0: piece(4,1,0)=1: piece(4,2,0)=1: piece(4,3,0)=1
  22. piece(4,0,1)=0: piece(4,1,1)=0: piece(4,2,1)=1: piece(4,3,1)=0
  23. piece(5,0,0)=0: piece(5,1,0)=1: piece(5,2,0)=1: piece(5,3,0)=1
  24. piece(5,0,1)=0: piece(5,1,1)=1: piece(5,2,1)=0: piece(5,3,1)=0
  25. piece(6,0,0)=0: piece(6,1,0)=1: piece(6,2,0)=1: piece(6,3,0)=1
  26. piece(6,0,1)=0: piece(6,1,1)=0: piece(6,2,1)=0: piece(6,3,1)=1
  27.  
  28. screen _newimage(sw*size, sh*size, 32)
  29.  
  30. piece_color(0) = _rgb(0,200,0)
  31. piece_color(1) = _rgb(200,0,0)
  32. piece_color(2) = _rgb(156,85,211)
  33. piece_color(3) = _rgb(219,112,147)
  34. piece_color(4) = _rgb(0,100,250)
  35. piece_color(5) = _rgb(230,197,92)
  36. piece_color(6) = _rgb(0,128,128)
  37.  
  38.  
  39. redraw = -1
  40.  
  41. speed = 10
  42. lines = 0
  43. pause = 0
  44. putpiece = 0
  45. startx = (sw - 4)/2
  46.  
  47. pn = int(rnd*7)
  48. px = startx
  49. py = 1
  50. rot = 0
  51.  
  52. title$ = "lines="+ltrim$(str$(lines))+",speed="++ltrim$(str$(speed))
  53. _title title$
  54.  
  55. t = timer
  56.  
  57.         if (timer - t) > (1/speed) and not pause then
  58.                 if valid(pn, px, py + 1, rot) then py = py + 1 else putpiece = -1
  59.  
  60.                 t = timer
  61.                 redraw = -1
  62.         end if
  63.  
  64.         if putpiece then
  65.                 if valid(pn, px, py, rot) then
  66.                         n = place(pn, px, py, rot)
  67.                         if n then
  68.                                 lines = lines + n
  69.                                 title$ = "lines="+ltrim$(str$(lines))+",speed="++ltrim$(str$(speed))
  70.                                 _title title$
  71.                         end if
  72.                 end if
  73.  
  74.                 pn = int(rnd*7)
  75.                 px = startx
  76.                 py = 0
  77.                 rot = 0
  78.  
  79.                 putpiece = 0
  80.                 redraw = -1
  81.  
  82.                 if not valid(pn, px, py, rot) then
  83.                         for y=0 to sh-1
  84.                                 for x=0 to sw-1
  85.                                         board(x, y) = 0
  86.                                 next
  87.                         next
  88.                         lines = 0
  89.                         title$ = "lines="+ltrim$(str$(lines))+",speed="++ltrim$(str$(speed))
  90.                         _title title$
  91.                 end if
  92.         end if
  93.  
  94.         if redraw then
  95.                 line (0,0)-(sw*size, sh*size),_rgb(0,0,0),bf
  96.                 for y=0 to sh - 1
  97.                         for x=0 to sw - 1
  98.                                 if board(x, y) <> 0 then
  99.                                         line (x*size, y*size)-step(size-2, size-2), piece_color(board(x, y)-1), bf
  100.                                 else
  101.                                         line (x*size, y*size)-step(size-2, size-2), _rgb(50,50,50), b
  102.                                 end if
  103.                         next
  104.                 next
  105.  
  106.                 for y=0 to 1
  107.                         for x=0 to 3
  108.                                 rotate xx, yy, x, y, pn, rot
  109.                                 if piece(pn, x, y) then line ((px + xx)*size, (py + yy)*size)-step(size-2, size-2), piece_color(pn), bf
  110.                         next
  111.                 next
  112.  
  113.                 _display
  114.                 redraw = 0
  115.         end if
  116.  
  117.         k = _keyhit
  118.         if k then
  119.                 shift = _keydown(100304) or _keydown(100303)
  120.                 select case k
  121.                 case 18432 'up
  122.                         if valid(pn, px, py, (rot + 1) mod 4) then rot = (rot + 1) mod 4
  123.                         pause = 0
  124.                 case 19200 'left
  125.                         if shift then
  126.                                 for xx=0 to sw-1
  127.                                         if not valid(pn, px - xx, py, rot) then exit for
  128.                                 next
  129.                                 px = px - xx + 1
  130.                         else
  131.                                 if valid(pn, px - 1, py, rot) then px = px - 1
  132.                         end if
  133.                         pause = 0
  134.                 case 19712 'right
  135.                         if shift then
  136.                                 for xx=px to sw-1
  137.                                         if not valid(pn, xx, py, rot) then exit for
  138.                                 next
  139.                                 px = xx - 1
  140.                         else
  141.                                 if valid(pn, px + 1, py, rot) then px = px + 1
  142.                         end if
  143.                         pause = 0
  144.                 case 20480, 32 'down
  145.                         if shift or k = 32 then
  146.                                 for yy=py to sh-1
  147.                                         if not valid(pn, px, yy, rot) then exit for
  148.                                 next
  149.                                 py = yy - 1
  150.                                 putpiece = -1
  151.                         else
  152.                                 if valid(pn, px, py + 1, rot) then py = py + 1
  153.                         end if
  154.                         pause = 0
  155.                 case 112 'p
  156.                         pause = not pause
  157.                 case 13 'enter
  158.                         for y=0 to sh-1
  159.                                 for x=0 to sw-1
  160.                                         board(x, y) = 0
  161.                                 next
  162.                         next
  163.                         pn = int(rnd*7)
  164.                         px = startx
  165.                         py = 0
  166.                         rot = 0
  167.                         putpiece = 0
  168.                         lines = 0
  169.                         title$ = "lines="+ltrim$(str$(lines))+",speed="++ltrim$(str$(speed))
  170.                         _title title$
  171.                 case 43, 61 'plus
  172.                         if speed < 100 then
  173.                                 speed = speed + 1
  174.                                 title$ = "lines="+ltrim$(str$(lines))+",speed="++ltrim$(str$(speed))
  175.                                 _title title$
  176.                         end if
  177.                 case 95, 45
  178.                         if speed > 1 then
  179.                                 speed = speed - 1
  180.                                 title$ = "lines="+ltrim$(str$(lines))+",speed="++ltrim$(str$(speed))
  181.                                 _title title$
  182.                         end if
  183.                 case 27
  184.                         exit do
  185.                 end select
  186.  
  187.                 redraw = -1
  188.         end if
  189.  
  190. sub rotate(xx, yy, x, y, pn, rot)
  191.         select case pn
  192.         case 0
  193.                 rot_new = 0
  194.         case 1 to 3
  195.                 rot_new = rot mod 2
  196.         case 4 to 6
  197.                 rot_new = rot
  198.         end select
  199.  
  200.         select case rot_new
  201.         case 0
  202.                 xx = x
  203.                 yy = y
  204.         case 1
  205.                 xx = y + 2
  206.                 yy = 2 - x
  207.         case 2
  208.                 xx = 4 - x
  209.                 yy = 1 - y
  210.         case 3
  211.                 xx = 2 - y
  212.                 yy = x - 1
  213.         end select
  214.  
  215. function valid(pn, px, py, rot)
  216.         for y=0 to 1
  217.                 for x=0 to 3
  218.                         rotate xx, yy, x, y, pn, rot
  219.                         if py + yy >= 0 then
  220.                                 if piece(pn, x, y) then
  221.                                         if (px + xx >= sw) or (px + xx < 0) then
  222.                                                 valid = 0
  223.                                                 exit function
  224.                                         end if
  225.                                         if (py + yy >= sh) then
  226.                                                 valid = 0
  227.                                                 exit function
  228.                                         end if
  229.                                         if (py >= 0) then
  230.                                         if board(px + xx, py + yy) then
  231.                                                 valid = 0
  232.                                                 exit function
  233.                                         end if
  234.                                         end if
  235.                                 end if
  236.                         end if
  237.                 next
  238.         next
  239.  
  240.         valid = -1
  241.  
  242. function place(pn, px, py, rot)
  243.         lines = 0
  244.  
  245.         for y=0 to 1
  246.                 for x=0 to 3
  247.                         rotate xx, yy, x, y, pn, rot
  248.                         if py + yy >= 0 then if piece(pn, x, y) then board(px + xx, py + yy) = pn + 1
  249.                 next
  250.         next
  251.  
  252.         'clear lines
  253.         for y=py-1 to py+2
  254.                 if y>=0 and y<sh then
  255.                         clr = -1
  256.                         for x=0 to sw - 1
  257.                                 if board(x, y) = 0 then
  258.                                         clr = 0
  259.                                         exit for
  260.                                 end if
  261.                         next
  262.  
  263.                         if clr then
  264.                                 lines = lines + 1
  265.                                 for yy=y to 1 step -1
  266.                                         for x=0 to sw-1
  267.                                                 board(x, yy) = board(x, yy-1)
  268.                                         next
  269.                                 next
  270.                         end if
  271.                 end if
  272.         next
  273.  
  274.         place = lines
  275.  

screenshot.png

30
Utilities / Descriptive Statistics by Bruno Schaefer
« on: June 28, 2018, 06:41:36 am »
Descriptive Statistics

Author: @BSpinoza Bruno Schaefer, Losheim am See, Germany
Author contact: bup.schaefer (.at.) web.de
Source: Submission
Version: 2018-06-16
Tags: [maths] [statistics]

Description:
This program calculates basic descriptive statistics of univariate data:
         n, Std.error, sum, standard error, mean, geometrical mean, variance,
         standard deviation, coefficient of variation, minimum, 1st quartile, median,
         2rd quartile, maximum,skewness, kurtosis, and excess kurtosis.
A dataset must have at least 4 values.
 
Remarks to kurtosis and skewness:
    For kurtosis and skewness the same equation as SPSS, PAST and Excel is used.
    Slightly different results may occur using other programs, especially for
    small sample sizes.
    kurtosis: peak shape  > 3 (excess > 0) leptokurtic: distribution with tapered peak and fat tails
                                    = 3 (excess = 0) mesokurtic: similar to normal bell-curved distribution
                                    < 3 (excess < 0) platykurtic: flat distribution with thin tails
     skewness: symmetry    > 0 skewed right: its right tail is longer and most of the distribution is at the left.
                                         = 0 symmetrical (not skewed)
                                         < 0 skewed left: the left tail is longer and most of the distribution is at the right


Note that this program includes extended ASCII characters and may not copy/paste correctly. If the interface does not draw correctly, use the attached source listing.

Source code:
Code: QB64: [Select]
  1. 'PROGRAM: descriptiveStatistics.bas
  2. '================= Descriptive Statistics  ================
  3. '        written by Bruno Schaefer, Losheim am See, Germany
  4. '                                       created: 15.12.2016
  5. '                                   last review: 16.06.2018
  6. '============================================================================================================
  7. ' This programm calculates basic descriptive statistics of univariate data:
  8. ' n, Std.error, sum, standard error, mean, geometrical mean, variance,
  9. ' standard deviation, coefficient of variation, minimum, 1st quartile, median,
  10. ' 2rd quartile, maximum,skewness, kurtosis, and excess kurtosis.
  11. ' A dataset must have at least 4 values.
  12. ' For kurtosis and skewness the same equation as SPSS, PAST and Excel is used.
  13. ' Slightly different results may occur using other programs, especially for
  14. ' small sample sizes.
  15. ' kurtosis: peak shape  > 3 (excess > 0) leptokurtic: distribution with tapered peak and fat tails
  16. '                       = 3 (excess = 0) mesokurtic: similar to normal bell-curved distribution
  17. '                       < 3 (excess < 0) platykurtic: flat distribution with thin tails
  18. ' skewness: symmetry    > 0 skewed right: its right tail is longer and most of the distribution is at the left.
  19. '                       = 0 symmetrical (not skewed)
  20. '                       < 0 skewed left: the left tail is longer and most of the distribution is at the right
  21. '===============================================================================================================
  22. _TITLE "descriptive statistics"
  23. SCREEN _NEWIMAGE(680, 520, 256)
  24. WEITER$ = "y" 'loop variable
  25. _CLIPBOARD$ = "" 'clears the clipboard
  26.     _LIMIT 30
  27.     DO
  28.         CLS , 14
  29.         COLOR 0, 14
  30.         PRINT " ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»   "
  31.         PRINT " º  DESCRIPTIVE STATISTICS OF UNIVARIATE DATA  º   "
  32.         PRINT " ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍŒ   "
  33.         PRINT "  number of values (n>3): ";
  34.         COLOR 9, 14
  35.         INPUT "", n 'input of the number of values
  36.     LOOP UNTIL n > 3
  37.     REDIM SHARED sample(n)
  38.     FOR I = 1 TO n
  39.         COLOR 0, 14
  40.         PRINT "  value no. " + STR$(I) + ": ";
  41.         COLOR 12, 14
  42.         INPUT "", Wert#
  43.         sample(I) = Wert# '               fills the data array with values
  44.     NEXT I
  45.     ' ----- SORT of the values ----------
  46.     DO
  47.         ic = 0
  48.         FOR I = 1 TO n - 1
  49.             IF sample(I) > sample(I + 1) THEN
  50.                 h = sample(I)
  51.                 sample(I) = sample(I + 1)
  52.                 sample(I + 1) = h
  53.                 ic = 1
  54.             END IF
  55.         NEXT I
  56.     LOOP UNTIL ic = 0
  57.     ' -----------  calculations and output of the results ------------
  58.     CLS
  59.     COLOR 0, 14
  60.     PRINT
  61.     PRINT " =========================== RESULTS =================================="
  62.     COLOR 2, 14
  63.     PRINT "  n (number of values):          "; n
  64.     PRINT "  sum (sum of values):           "; sum#(sample())
  65.     PRINT "  standard error:                "; StdDev.s#(sample()) / SQR(n) ' stderr#(sample())
  66.     PRINT "  range (xmax - xmin):           "; sample(UBOUND(sample)) - sample(LBOUND(sample))
  67.     COLOR 12, 14
  68.     PRINT "  mean:                          "; mean#(sample())
  69.     PRINT "  geometrical mean:              "; geomean#(sample())
  70.     PRINT "  root mean square RMS:          "; rms#(sample())
  71.     PRINT "  variance (sample):             "; variance.s#(sample())
  72.     PRINT "  std.dev. (sample):             "; StdDev.s#(sample()); " = "; _ROUND((StdDev.s#(sample()) * 100 / mean#(sample())) * 100) / 100; " %"
  73.     PRINT "  coeff. of variation:           "; 100 * StdDev.s#(sample()) / mean#(sample())
  74.     COLOR 9, 14
  75.     PRINT "  variance (population):         "; variance.p#(sample())
  76.     PRINT "  std.dev. (population):         "; StdDev.p#(sample()); " = "; _ROUND((StdDev.p#(sample()) * 100 / mean#(sample())) * 100) / 100; " %"
  77.     PRINT "  coefficient of variation:      "; 100 * StdDev.p#(sample()) / mean#(sample())
  78.     COLOR 6, 14
  79.     PRINT "  minimum:                       "; sample(LBOUND(sample))
  80.     PRINT "  1st quartile (percentile 25%): "; quantile#(sample(), 0.25)
  81.     PRINT "  median (percentile 50%):       "; quantile#(sample(), 0.50)
  82.     PRINT "  standard error of the median:  "; variance.p#(sample()) / SQR(n)
  83.     PRINT "  3rd quartile (percentile 75%): "; quantile#(sample(), 0.75)
  84.     PRINT "  maximum:                       "; sample(UBOUND(sample))
  85.     PRINT "  interquartile range:           "; quantile#(sample(), 0.75) - quantile#(sample(), 0.25)
  86.     COLOR 9, 14
  87.     PRINT "  skewness (sample):             "; _ROUND(skew#(sample()) * 100000) / 100000
  88.     PRINT "  kurtosis (sample):             "; _ROUND(kurt#(sample()) * 100000) / 100000
  89.     PRINT "  excess kurtosis(sample):       "; _ROUND(kurt#(sample()) * 100000) / 100000 - 3
  90.     PRINT "  skewness (population):         "; _ROUND(skew#(sample()) * (n - 2) / SQR(n * (n - 1)) * 100000) / 100000
  91.     PRINT "  kurtosis (population):         "; _ROUND((kurt#(sample()) * (n - 2) * (n - 3) / (n - 1) - 6) / (n + 1) * 100000) / 100000
  92.     PRINT "  excess kurtosis (population):  "; _ROUND((kurt#(sample()) * (n - 2) * (n - 3) / (n - 1) - 6) / (n + 1) * 100000) / 100000 - 3
  93.     COLOR 0, 14
  94.     PRINT " ======================================================================"
  95.     DIM CrLf AS STRING * 2
  96.     CrLf = CHR$(13) + CHR$(10)
  97.     _CLIPBOARD$ = _CLIPBOARD$ + " ========================================= " + CrLf
  98.     _CLIPBOARD$ = _CLIPBOARD$ + " DESCRIPTIVE STATISTICS OF UNIVARIATE DATA      " + CrLf
  99.     _CLIPBOARD$ = _CLIPBOARD$ + " ========================================= " + CrLf
  100.     _CLIPBOARD$ = _CLIPBOARD$ + " sorted data:" + CrLf
  101.     FOR I = 1 TO n
  102.         _CLIPBOARD$ = _CLIPBOARD$ + "    " + STR$(sample(I)) + CrLf
  103.     NEXT I
  104.     _CLIPBOARD$ = _CLIPBOARD$ + " ---------------------------------------------------------" + CrLf
  105.     _CLIPBOARD$ = _CLIPBOARD$ + " n (number of values):                  " + STR$(n) + CrLf
  106.     _CLIPBOARD$ = _CLIPBOARD$ + " sum (sum of values):                   " + STR$(sum#(sample())) + CrLf
  107.     _CLIPBOARD$ = _CLIPBOARD$ + " standard error:                        " + STR$(StdDev.s#(sample()) / SQR(n)) + CrLf
  108.     _CLIPBOARD$ = _CLIPBOARD$ + " range (xmax - xmin):                   " + STR$(sample(UBOUND(sample)) - sample(LBOUND(sample))) + CrLf
  109.     _CLIPBOARD$ = _CLIPBOARD$ + " mean:                                  " + STR$(mean#(sample())) + CrLf
  110.     _CLIPBOARD$ = _CLIPBOARD$ + " geometrical mean                       " + STR$(geomean#(sample())) + CrLf
  111.     _CLIPBOARD$ = _CLIPBOARD$ + " root mean square RMS:                  " + STR$(rms#(sample())) + CrLf
  112.     _CLIPBOARD$ = _CLIPBOARD$ + " variance (sample):                     " + STR$(variance.s#(sample())) + CrLf
  113.     _CLIPBOARD$ = _CLIPBOARD$ + " standard deviation (sample):           " + STR$(StdDev.s#(sample())) + CrLf
  114.     _CLIPBOARD$ = _CLIPBOARD$ + " standard deviation (sample) %:         " + STR$(_ROUND((StdDev.s#(sample()) * 100 / mean#(sample())) * 100) / 100) + " %" + CrLf
  115.     _CLIPBOARD$ = _CLIPBOARD$ + " coefficient of variation (sample):     " + STR$(100 * StdDev.s#(sample()) / mean#(sample())) + CrLf
  116.     _CLIPBOARD$ = _CLIPBOARD$ + " variance (population):                 " + STR$(variance.p#(sample())) + CrLf
  117.     _CLIPBOARD$ = _CLIPBOARD$ + " standard deviation(population):        " + STR$(StdDev.p#(sample())) + CrLf
  118.     _CLIPBOARD$ = _CLIPBOARD$ + " standard deviation (population) %:     " + STR$(_ROUND((StdDev.p#(sample()) * 100 / mean#(sample())) * 100) / 100) + " %" + CrLf
  119.     _CLIPBOARD$ = _CLIPBOARD$ + " coefficient of variation (population): " + STR$(100 * StdDev.p#(sample()) / mean#(sample())) + CrLf
  120.     _CLIPBOARD$ = _CLIPBOARD$ + " minimum:                               " + STR$(sample(LBOUND(sample))) + CrLf
  121.     _CLIPBOARD$ = _CLIPBOARD$ + " 1st quartile (25% percentile):         " + STR$(quantile#(sample(), 0.25)) + CrLf
  122.     _CLIPBOARD$ = _CLIPBOARD$ + " median: 2nd quartile (50% percentile): " + STR$(quantile#(sample(), 0.50)) + CrLf
  123.     _CLIPBOARD$ = _CLIPBOARD$ + " standard error of the median:          " + STR$(variance.p#(sample()) / SQR(n)) + CrLf
  124.     _CLIPBOARD$ = _CLIPBOARD$ + " 3rd quartile (75%) :                   " + STR$(quantile#(sample(), 0.75)) + CrLf
  125.     _CLIPBOARD$ = _CLIPBOARD$ + " maximum:                               " + STR$(sample(UBOUND(sample))) + CrLf
  126.     _CLIPBOARD$ = _CLIPBOARD$ + " interquartile range:                   " + STR$(quantile#(sample(), 0.75) - quantile#(sample(), 0.25)) + CrLf
  127.     _CLIPBOARD$ = _CLIPBOARD$ + " skewness (sample):                     " + STR$(_ROUND(skew#(sample()) * 100000) / 100000) + CrLf
  128.     _CLIPBOARD$ = _CLIPBOARD$ + " kurtosis (sample):                     " + STR$(_ROUND(kurt#(sample()) * 100000) / 100000) + CrLf
  129.     _CLIPBOARD$ = _CLIPBOARD$ + " excess kurtosis (sample):              " + STR$(_ROUND(kurt#(sample()) * 100000) / 100000 - 3) + CrLf
  130.     _CLIPBOARD$ = _CLIPBOARD$ + " skewness (population):                 " + STR$(_ROUND(skew#(sample()) * (n - 2) / SQR(n * (n - 1)) * 100000) / 100000) + CrLf
  131.     _CLIPBOARD$ = _CLIPBOARD$ + " kurtosis (population):                 " + STR$(_ROUND((kurt#(sample()) * (n - 2) * (n - 3) / (n - 1) - 6) / (n + 1) * 100000) / 100000) + CrLf
  132.     _CLIPBOARD$ = _CLIPBOARD$ + " excess kurtosis (population):          " + STR$(_ROUND((kurt#(sample()) * (n - 2) * (n - 3) / (n - 1) - 6) / (n + 1) * 100000) / 100000 - 3) + CrLf
  133.     _CLIPBOARD$ = _CLIPBOARD$ + " ---------------------------------------------------------" + CrLf
  134.     PRINT
  135.     PRINT " All results are stored in the clipboard!"
  136.     PRINT " Do you want to start a new statistical evaluation  [y/n]? ";
  137.     SLEEP
  138.     WEITER$ = INKEY$
  139. LOOP WHILE (WEITER$ = "y") OR (WEITER$ = "Y")
  140. COLOR 12, 14
  141. LOCATE 10, 25: PRINT " E N D   O F   P R O G R A M "
  142. LOCATE 12, 25: PRINT "         - - - -"
  143. LOCATE 14, 25: PRINT "      Press any key ": PRINT
  144. 'FUNCTIONS
  145. '============= sum =========="
  146. FUNCTION sum# (x())
  147.     s# = 0
  148.     FOR i = 1 TO n
  149.         s# = s# + x(i)
  150.     NEXT i
  151.     sum# = s#
  152. '============= mean =========="
  153. FUNCTION mean# (x())
  154.     mean# = sum#(x()) / n
  155. '========= variance (sample) =========="
  156. FUNCTION variance.s# (x())
  157.     m# = mean#(x())
  158.     s# = 0
  159.     FOR i = 1 TO n
  160.         s# = s# + (x(i) - mean#(x())) ^ 2
  161.     NEXT i
  162.     variance.s# = s# / (n - 1)
  163. '========= variance population) =========="
  164. FUNCTION variance.p# (x())
  165.     m# = mean#(x())
  166.     s = 0
  167.     FOR i = 1 TO n
  168.         s# = s# + (x(i) - mean#(x())) ^ 2
  169.     NEXT i
  170.     variance.p# = s# / n
  171. '======= standard deviation (sample) ========"
  172. FUNCTION StdDev.s# (x())
  173.     StdDev.s# = SQR(variance.s#(x()))
  174. '======= standard deviation (population) ========"
  175. FUNCTION StdDev.p# (x())
  176.     StdDev.p# = SQR(variance.p#(x()))
  177. '============== median ====================="
  178. FUNCTION median# (x())
  179.     IF (n / 2) = INT(n / 2) THEN
  180.         'even
  181.         median# = (sample(n / 2) + sample((n / 2) + 1)) / 2
  182.     ELSE
  183.         'odd
  184.         median# = sample((n + 1) / 2)
  185.     END IF
  186. '============================ quantile ========================
  187. FUNCTION quantile# (x(), a)
  188.     rang# = a * (n - 1) + 1
  189.     index% = INT(rang#)
  190.     gewicht# = rang# - index%
  191.     quantile# = x(index%) + gewicht# * (x(index% + 1) - x(index%))
  192. '============================ skewness ========================
  193. FUNCTION skew# (x())
  194.     m# = mean#(x())
  195.     s# = StdDev.s#(x())
  196.     sk# = 0
  197.     FOR J = 1 TO n
  198.         sk# = sk# + ((x(J) - m#) / s#) ^ 3
  199.     NEXT J
  200.     IF s# <> 0 THEN
  201.         skew# = sk# * (n / ((n - 1) * (n - 2)))
  202.     ELSE
  203.         skew# = 0
  204.     END IF
  205. '============================ kurtosis ========================
  206. FUNCTION kurt# (x())
  207.     m# = mean#(x())
  208.     s# = StdDev.s#(x())
  209.     krt# = 0
  210.     FOR j = 1 TO n
  211.         krt# = krt# + ((x(j) - m#) / s#) ^ 4
  212.     NEXT j
  213.     IF s# <> 0 THEN
  214.         kurt# = ((krt# * (n + 1) * n) / ((n - 1) * (n - 2) * (n - 3))) - ((3 * (n - 1) ^ 2) / ((n - 2) * (n - 3)))
  215.     ELSE
  216.         kurt# = 0
  217.     END IF
  218. '====================== geometrical mean ========================
  219. FUNCTION geomean# (x())
  220.     gm# = 1
  221.     FOR j = 1 TO n
  222.         gm# = gm# * x(j)
  223.     NEXT j
  224.     geomean# = gm# ^ (1 / n)
  225.  
  226. '============ mean square error ===================
  227. FUNCTION rms# (x())
  228.     ms# = 0
  229.     FOR j = 1 TO n
  230.         ms# = ms# + x(j) ^ 2
  231.     NEXT j
  232.     rms# = SQR(ms# / n)
  233.  

results.jpg

Pages: 1 [2] 3