QB64.org Forum

Active Forums => Programs => Topic started by: FellippeHeitor on December 06, 2020, 01:20:53 pm

Title: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: FellippeHeitor on December 06, 2020, 01:20:53 pm
🎄☃️ Lights and jingly bells are already all around. It's time to start submitting your 2020 holiday samples! Let's group them under this thread, who'll start? ✨🎁
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Petr on December 06, 2020, 01:52:31 pm
Hi Fellippe. I have done 0 rows of the code :). Some conditions, or it is in free style?
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: SpriggsySpriggs on December 06, 2020, 02:13:00 pm
Any requirements?
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: FellippeHeitor on December 06, 2020, 02:28:35 pm
Make it beautiful, preferably with no extra files.
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: OldMoses on December 06, 2020, 04:38:14 pm
Christmas 2020..... I don't think I'm quite up to flaming Xmas trees... :D
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 06, 2020, 08:05:11 pm
To start decorating you'll need some ornaments, how about ones that rotate color?
Code: QB64: [Select]
  1. _TITLE "Ornaments with Rotating Colors, spacebar to change color set" '  B+ 2018-04-17
  2. 'from figosdev post at http://smallbasic.sourceforge.net/?q=node/1684#comment-1955
  3. 'translating fig to SmallBASIC for alittle cross pollination...
  4. '2020-12-05 for Xmas decorating a little update
  5.  
  6. CONST xmax = 600, ymax = 600
  7. SCREEN _NEWIMAGE(xmax, ymax, 32)
  8. _SCREENMOVE 360, 60
  9. DIM SHARED rrr, ggg, bbb, ccc
  10. cx = 300
  11. ww = 3.14159 / 2 'fix to return back to this after each run
  12. setRGB
  13.     IF INKEY$ = " " THEN setRGB: ccc = 0
  14.     ccc = 0
  15.     w = ww 'fix
  16.     llc = llc + 1
  17.     IF llc = 32000 THEN llc = 0: lc& = 0
  18.     FOR r = 490 TO 300 STEP -.25
  19.         e = w - _PI / 4 / (490 - 300)
  20.         tmp = e: e = w: w = tmp
  21.         FOR p = _PI(-1) TO _PI STEP _PI(1 / 101)
  22.             e = INT((COS(w) * 380) / 2)
  23.             x = INT(COS(p * 2) * e + cx)
  24.             y = INT(SIN(p * 2) * e + r - 50)
  25.             lc& = lc& + 1
  26.             IF lc& MOD 90 = 0 THEN
  27.                 ccc = ccc + .2
  28.                 fcirc x, y, 12, changeRGB~&
  29.             END IF
  30.         NEXT
  31.     NEXT
  32.     _DISPLAY
  33.     _LIMIT 10
  34.  
  35. SUB setRGB 'mod
  36.     rrr = RND ^ 2: ggg = RND ^ 2: bbb = RND ^ 2
  37.  
  38. FUNCTION changeRGB~& 'mod
  39.     changeRGB~& = _RGB32(127 + 127 * SIN(rrr * ccc), 127 + 127 * SIN(ggg * ccc), 127 + 127 * SIN(bbb * ccc))
  40.  
  41. 'from Steve Gold standard
  42. SUB fcirc (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  43.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  44.     DIM X AS INTEGER, Y AS INTEGER
  45.     Radius = ABS(R): RadiusError = -Radius: X = Radius: Y = 0
  46.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  47.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  48.     WHILE X > Y
  49.         RadiusError = RadiusError + Y * 2 + 1
  50.         IF RadiusError >= 0 THEN
  51.             IF X <> Y + 1 THEN
  52.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  53.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  54.             END IF
  55.             X = X - 1
  56.             RadiusError = RadiusError - X * 2
  57.         END IF
  58.         Y = Y + 1
  59.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  60.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  61.     WEND
  62.  
  63.  
  64.  

 


Looking for Andy's pine tree maker code to put them on.
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: FellippeHeitor on December 06, 2020, 08:07:46 pm
Thanks for getting it started, bplus!

Minor typo at line 30: I changed it by adding _DEFAULTCOLOR as the last parameter to fcirc. You may wanna review it.
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 06, 2020, 08:09:49 pm
Was that before I changed it in edit because I posted old version?

I changed changeRGB to a function and the old version had a call to a SUB before the call to old circle routine that didn't take color.

The version I edited should work.
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: FellippeHeitor on December 06, 2020, 08:11:00 pm
If there are no bugs in the latest version, then you've fixed it. 😄
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: SierraKen on December 06, 2020, 08:43:18 pm
Here is my Merry Christmas 2020 submission. I worked on this all afternoon. :) It has random falling glowing snow (I didn't need help this time! LOL), random hills, and random tiny Christmas Trees. Everything changes every 7 seconds. Enjoy!

Edit: I just added a photo of it.

Code: QB64: [Select]
  1. 'Merry Christmas! From SierraKen
  2. 'Made on December 6, 2020.
  3.  
  4. DIM snowx(2000), snowy(2000)
  5. DIM hills AS LONG
  6. DIM hillx AS SINGLE
  7. DIM shape AS SINGLE
  8.  
  9. _TITLE "Merry Christmas! From SierraKen - Every 7 seconds new mountains and trees appear. Press Esc to quit."
  10. scene = _NEWIMAGE(800, 600, 32)
  11. SCREEN scene
  12. start:
  13. FOR cc = 1 TO 200
  14.     IF cc + 400 > 600 THEN GOTO nex:
  15.     LINE (0, 400 + cc)-(_WIDTH, 400 + cc), _RGB32(0, c + 100, cc)
  16. NEXT cc
  17. nex:
  18. 'Hills
  19. FOR hills = 1 TO 10
  20.     hillx = (RND * _WIDTH)
  21.     sz = (RND * 300)
  22.     shape = (RND + 1)
  23.     c1 = (RND * 155)
  24.     c2 = (RND * 155)
  25.     c3 = (RND * 155)
  26.     FOR size = .2 TO sz STEP .2
  27.         CIRCLE (hillx, 400), size, _RGB32(c1, c2 + size, c3), 2 * _PI, _PI, shape
  28.     NEXT size
  29. NEXT hills
  30. FOR trees = 1 TO 75
  31.     tx = (RND * _WIDTH)
  32.     ty = (RND * 200) + 430
  33.     r = 1
  34.     col = INT(RND * 5) + 1
  35.     IF col = 1 THEN c = _RGB32(255, 0, 0)
  36.     IF col = 2 THEN c = _RGB32(0, 0, 255)
  37.     IF col = 3 THEN c = _RGB32(255, 127, 255)
  38.     IF col = 4 THEN c = _RGB32(127, 255, 255)
  39.     IF col = 5 THEN c = _RGB32(255, 139, 0)
  40.  
  41.     LINE (tx, ty)-(tx + 2, ty - 10), _RGB32(183, 127, 127), BF
  42.  
  43.     LINE (tx, ty - 10)-(tx - 5, ty - 10), _RGB32(127, 255, 127)
  44.     LINE (tx - 5, ty - 10)-(tx, ty - 15), _RGB32(127, 255, 127)
  45.     cx = tx - 5: cy = ty - 10
  46.     fillCircle cx, cy, r, c
  47.     LINE (tx, ty - 15)-(tx - 5, ty - 15), _RGB32(127, 255, 127)
  48.     LINE (tx - 5, ty - 15)-(tx, ty - 20), _RGB32(127, 255, 127)
  49.     cx = tx - 5: cy = ty - 15
  50.     fillCircle cx, cy, r, c
  51.     LINE (tx, ty - 20)-(tx - 5, ty - 20), _RGB32(127, 255, 127)
  52.     LINE (tx - 5, ty - 20)-(tx + 1, ty - 25), _RGB32(127, 255, 127)
  53.     cx = tx - 5: cy = ty - 20
  54.     fillCircle cx, cy, r, c
  55.     LINE (tx + 2, ty - 10)-(tx + 7, ty - 10), _RGB32(127, 255, 127)
  56.     LINE (tx + 7, ty - 10)-(tx + 2, ty - 15), _RGB32(127, 255, 127)
  57.     cx = tx + 7: cy = ty - 10
  58.     fillCircle cx, cy, r, c
  59.     LINE (tx + 2, ty - 15)-(tx + 7, ty - 15), _RGB32(127, 255, 127)
  60.     LINE (tx + 7, ty - 15)-(tx + 2, ty - 20), _RGB32(127, 255, 127)
  61.     cx = tx + 7: cy = ty - 15
  62.     fillCircle cx, cy, r, c
  63.     LINE (tx + 2, ty - 20)-(tx + 7, ty - 20), _RGB32(127, 255, 127)
  64.     LINE (tx + 7, ty - 20)-(tx + 1, ty - 25), _RGB32(127, 255, 127)
  65.     cx = tx + 7: cy = ty - 20
  66.     fillCircle cx, cy, r, c
  67.  
  68.     'Yellow Star
  69.     cx = tx + 1: cy = ty - 26
  70.     r = 1
  71.     c = _RGB32(255, 255, 127)
  72.     fillCircle cx, cy, r, c
  73. NEXT trees
  74.  
  75. hills = _COPYIMAGE(0)
  76.  
  77.     _LIMIT 50
  78.     _PUTIMAGE , hills
  79.     a$ = INKEY$
  80.     IF a$ = CHR$(27) THEN END
  81.     snowing = INT(RND * 1000) + 1
  82.     IF snowing > 900 THEN
  83.         s = s + 1
  84.         IF s > 1500 THEN s = 1
  85.         snowx(s) = (RND * _WIDTH)
  86.         snowy(s) = 0
  87.     END IF
  88.     IF yy > 640 THEN yy = 0
  89.     FOR t = 1 TO 1500
  90.         snowy(t) = snowy(t) + 1
  91.         cx = snowx(t): cy = snowy(t)
  92.         r = RND * 5
  93.         c = _RGB32(255, 255, 255)
  94.         fillCircle cx, cy, r, c
  95.     NEXT t
  96.     _DISPLAY
  97.     CLS
  98.     tim = tim + 1
  99.     IF tim > 500 THEN tim = 0: CLS: _FREEIMAGE hills: GOTO start:
  100.  
  101. 'from Steve Gold standard
  102. SUB fillCircle (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  103.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  104.     DIM X AS INTEGER, Y AS INTEGER
  105.     Radius = ABS(R): RadiusError = -Radius: X = Radius: Y = 0
  106.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  107.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  108.     WHILE X > Y
  109.         RadiusError = RadiusError + Y * 2 + 1
  110.         IF RadiusError >= 0 THEN
  111.             IF X <> Y + 1 THEN
  112.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  113.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  114.             END IF
  115.             X = X - 1
  116.             RadiusError = RadiusError - X * 2
  117.         END IF
  118.         Y = Y + 1
  119.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  120.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  121.     WEND
  122.  
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 06, 2020, 08:52:01 pm
Oh today's the 6th, I like that blinking effect with snowfall Ken.

Found Andy's tree, someone might be able to do something with this?

Code: QB64: [Select]
  1. 'Original IFS fractal by Andy Amaya   copy 2019-12-09
  2. 'ap3-191209-216
  3. _TITLE "IFS Pine Tree"
  4.  
  5. scaleX! = 524.0 '424.0 to 1024.0 look OK for X scaling factor
  6. scaleY! = 524.0
  7. offsetX% = 370
  8. offsetY% = 150
  9. SCREEN _NEWIMAGE(800, 600, 32)
  10. CLS , _RGB32(0, 0, 0)
  11. COLOR _RGB32(0, 228, 0, 24)
  12.  
  13. FOR iter& = 0 TO 1000000
  14.         CASE 0 TO .60
  15.             nx! = -0.858985 * lastX! + 0.008944 * lastY! + 0.092336
  16.             ny! = 0.012263 * lastX! + 0.84816 * lastY! + -0.04103
  17.         CASE .60 TO .96
  18.             nx! = -0.373759 * lastX! + -0.353068 * lastY! + 0.296535
  19.             ny! = 0.353068 * lastX! + -0.373759 * lastY! + 0.704598
  20.         CASE ELSE
  21.             nx! = 0.010276 * lastX! + 0 * lastY! + 0.053328
  22.             ny! = -0.05138 * lastX! + 0.313416 * lastY! + 0.576552
  23.     END SELECT
  24.     IF iter& > 20& THEN PSET (nx! * scaleX! + offsetX%, ny! * scaleY! + offsetY%)
  25.     lastX! = nx!
  26.     lastY! = ny!
  27.  

Who me?!
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: SierraKen on December 06, 2020, 09:19:43 pm
Thanks B+ :)
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: FellippeHeitor on December 07, 2020, 06:13:39 am
Cool scene, @SierraKen!
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: _vince on December 07, 2020, 11:50:02 am
Any requirements?

What about rewards?
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: FellippeHeitor on December 07, 2020, 11:53:33 am
What's more rewarding than having your work featured for the whole community to gasp in awe?
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: SierraKen on December 07, 2020, 12:13:21 pm
Thanks Felippe :).
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Pete on December 08, 2020, 12:12:00 am
What's more rewarding than having your work featured for the whole community to gasp in awe?

$1.25 American.
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 08, 2020, 07:40:24 pm
OK some pine trees in winter:
Code: QB64: [Select]
  1. _TITLE "Pine Trees mod, any key for another scene..." ' b+ 2020-12-08   mod from
  2. 'Original IFS fractal by Andy Amaya   copy 2019-12-09
  3. 'ap3-191209-216
  4.  
  5. CONST nTrees = 3, sy = 424
  6. REDIM SHARED ox(1 TO nTrees), oy(1 TO nTrees), sx(1 TO nTrees)
  7. SCREEN _NEWIMAGE(800, 600, 32)
  8. COLOR , &HFFFFFFFF
  9.     CLS
  10.     FOR y = 0 TO _HEIGHT
  11.         LINE (0, y)-(_WIDTH, y), Ink~&(&HFF332266, &H88FFFFFF, y / _HEIGHT)
  12.     NEXT
  13.     FOR i = 1 TO nTrees
  14.         NewTree i
  15.     NEXT
  16.     FOR t = 1 TO nTrees
  17.         FOR i = 0 TO 40000 ' orig 1 million
  18.             SELECT CASE RND
  19.                 CASE 0 TO .60
  20.                     nx = -0.858985 * lastX + 0.008944 * lastY + 0.092336
  21.                     ny = 0.012263 * lastX + 0.84816 * lastY + -0.04103
  22.                 CASE .60 TO .96
  23.                     nx = -0.373759 * lastX + -0.353068 * lastY + 0.296535
  24.                     ny = 0.353068 * lastX + -0.373759 * lastY + 0.704598
  25.                 CASE ELSE
  26.                     nx = 0.010276 * lastX + 0 * lastY + 0.053328
  27.                     ny = -0.05138 * lastX + 0.313416 * lastY + 0.576552
  28.             END SELECT
  29.             IF i > 36000 THEN
  30.                 PSET (nx * sx(t) + ox(t), ny * sy + oy(t)), &HFFFFFFFF
  31.             ELSEIF i > 30 THEN
  32.                 PSET (nx * sx(t) + ox(t), ny * sy + oy(t)), &HFF116611
  33.             END IF
  34.             lastX = nx
  35.             lastY = ny
  36.         NEXT
  37.     NEXT
  38.     SLEEP
  39.  
  40. SUB NewTree (i)
  41.     ox(i) = RND * (_WIDTH - 300)
  42.     oy(i) = RND * 100 + 150
  43.     sx(i) = RND * 300 + 624
  44.  
  45. SUB cAnalysis (c AS _UNSIGNED LONG, outRed, outGrn, outBlu, outAlp)
  46.     outRed = _RED32(c): outGrn = _GREEN32(c): outBlu = _BLUE32(c): outAlp = _ALPHA32(c)
  47.  
  48. FUNCTION Ink~& (c1 AS _UNSIGNED LONG, c2 AS _UNSIGNED LONG, fr##)
  49.     DIM R1, G1, B1, A1, R2, G2, B2, A2
  50.     cAnalysis c1, R1, G1, B1, A1
  51.     cAnalysis c2, R2, G2, B2, A2
  52.     Ink~& = _RGB32(R1 + (R2 - R1) * fr##, G1 + (G2 - G1) * fr##, B1 + (B2 - B1) * fr##, A1 + (A2 - A1) * fr##)
  53.  

  [ This attachment cannot be displayed inline in 'Print Page' view ]  
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 08, 2020, 09:36:51 pm
Word Search for Christmas 2020:

No input files, the list is internal but this code outputs 3 txt files:
1. A word List
2. A Letters Grid to Search Words in
3. A Solution of where the words are.
All these are text files that you can print out from your favorite Text Editor. These files are supplemental paper versions, the game itself you can play entirely on the computer.

"Make it beautiful"  ;-))   Well if sound of kids busy with a puzzle is beautiful this might fill the bill. :)

Code: QB64: [Select]
  1. _TITLE "Word Search for Christmas 2020" 'by b+ mod 2020-12-06 modified from:
  2. ' Puzzle Builder #4 sort lists 2020-12-05.bas but no input files!
  3. ' 3 output files will be created in case you want kids the play same game from:
  4. ' 1. A list of search words
  5. ' 2. The Letter Puzzle grid
  6. ' 3. Solution of words start location and direction.
  7.  
  8. DEFLNG A-Z
  9. CONST AscA = 97, WordLengthLimit = 15
  10. CONST ScreenWidth = 1000, ScreenHeight = 640
  11.  
  12. TYPE WordSearch 'having trouble tracking all Global shared variables for puzzle so here is that container
  13.     FileTheme AS STRING ' the theme name for + " Word List.txt" file we are doing
  14.     GridSide AS LONG ' number of letters per side of square grid
  15.     GridSideM1 AS LONG ' grid size - 1
  16.     GridSideP2M1 AS LONG ' grid size ^ 2 - 1
  17.     GridLabel AS STRING ' top and side labeling of letters grid
  18.     NumWords AS LONG ' number of words
  19.     PlaceWordIndex AS LONG ' current index of word we are working
  20.     NumPlacedWords AS LONG ' current number of placed words
  21.     NumUnplacedWords AS LONG 'count the disasters
  22.     UnfilledCellF AS LONG 'there are still unfilled cells F = Flag
  23.     NumBestPlacedWords AS LONG ' best number of placed words here is goal  = NumWords
  24.     Filler AS STRING
  25.  
  26. TYPE WordType
  27.     S AS STRING ' the word  S for String
  28.     Len AS LONG ' it's length
  29.     Placed AS LONG
  30.     X AS LONG ' placements
  31.     Y AS LONG
  32.     D AS LONG ' direction 0 to 7 ie  North, NorthEast, East, SouthEast... NorthWest
  33.  
  34. REDIM SHARED WS AS WordSearch ' this is all shared variables of puzzle in a container
  35. REDIM SHARED Words(1 TO 250) AS WordType ' essential info about each search word
  36. REDIM SHARED AscWord(1 TO 250, WordLengthLimit) ' break the word done to ASC numbers for each letter, speed up processing
  37. REDIM SHARED BestWords(1 TO 250) AS WordType ' best set of words placed
  38. REDIM SHARED AscLetters(0 TO WS.GridSideM1, 0 TO WS.GridSideM1) ' this is the ASC of the letters on the grid
  39. REDIM SHARED AscBestLetters(0 TO WS.GridSideM1, 0 TO WS.GridSideM1) ' this is the ASC of the letters in the Best grid using the most words
  40. REDIM SHARED DX(0 TO 7), DY(0 TO 7), DString$(0 TO 7) ' these are direction "adders" to x, y position to search in directions
  41. REDIM SHARED DirectionTotals(0 TO 7) ' check direction counts for quality puzzle.
  42.  
  43.  
  44. '======================================= Word Search File Base Name and Grid Size ================================================
  45.  
  46. '   Make your word list file with: Some base name for theme + " Word List.txt"
  47.  
  48. ' test file 2 Richard Frost started this theme to test his puzzles from which I learned much :)
  49. 'WS.FileTheme = "Elements" ' add suffix to your file " Word List.txt"    <<<<<<<<<<<<<<<<<<<<<<<<<    Input
  50. 'WS.GridSide = 30 ' <<<<<<<<<<<<<<<<<<<<<<<<<    Input later    30 the maximum grid size
  51. 'WS.Filler = "bplus" ' <<<<<<<<<<<<<<< Input a personalization to hide in the puzzle
  52.  
  53. ' test file 1  The reason this Word Builder was Built! for the naughty and nice nephews and nieces.
  54. WS.FileTheme = "Christmas 2020" 'add suffix to your file " Word List.txt"   <<<<<<<<<<<<<<<<<<<<<<<<<    Input
  55. WS.GridSide = 19 ' <<<<<<<<<<<<<<<<<<<<<<<<<    Input later    30 the maximum grid size
  56. WS.Filler = "SECRET" ' <<<<<<<<<<<<<<< Input a personalization to hide in the puzzle
  57.  
  58. '' test file 3  check a tiny puzzle
  59. 'WS.FileTheme = "The First Four Elements"
  60. 'WS.GridSide = 5 ' <<<<<<<<<<<<<<<<<<<<<<<<<    Input later    30 the maximum grid size
  61. 'WS.Filler = "BPLUS" ' <<<<<<<<<<<<<<< Input a personalization to hide in the puzzle
  62.  
  63. SCREEN _NEWIMAGE(ScreenWidth, ScreenHeight, 32)
  64. _DELAY .25
  65.  
  66. DIM try, c, r, y$, puzzleFiled
  67.  
  68. InitializeOnce
  69. WHILE try < 100 'for long runs uncomment BEEP
  70.     try = try + 1
  71.     RestartPuzzleFill
  72.     IF WS.PlaceWordIndex > 0 THEN ShowPuzzle
  73.     WHILE WS.PlaceWordIndex < WS.NumWords
  74.         WS.PlaceWordIndex = WS.PlaceWordIndex + 1
  75.         WS.UnfilledCellF = 0 ' set F that all are filled
  76.         PlaceWord
  77.         IF WS.UnfilledCellF = 0 OR (WS.NumPlacedWords = WS.NumWords) THEN EXIT WHILE
  78.     WEND
  79.     LOCATE 2, 1: PRINT "Try:"; try
  80.     IF try MOD 25 = 0 THEN _DISPLAY: ShowBestPuzzle
  81.     IF WS.NumPlacedWords > WS.NumBestPlacedWords THEN 'copy Letters$ into Best$
  82.         REDIM AscBestLetters(0 TO WS.GridSideM1, 0 TO WS.GridSideM1)
  83.         FOR r = 0 TO WS.GridSideM1
  84.             FOR c = 0 TO WS.GridSideM1
  85.                 AscBestLetters(c, r) = AscLetters(c, r)
  86.             NEXT
  87.         NEXT
  88.         WS.NumBestPlacedWords = WS.NumPlacedWords
  89.  
  90.         FOR r = 1 TO WS.NumWords '                 copy everything because we shuffle each time
  91.             BestWords(r).S = Words(r).S: BestWords(r).Len = Words(r).Len: BestWords(r).Placed = Words(r).Placed
  92.             BestWords(r).X = Words(r).X: BestWords(r).Y = Words(r).Y: BestWords(r).D = Words(r).D
  93.         NEXT
  94.         Sort BestWords()
  95.         IF WS.NumBestPlacedWords = WS.NumWords THEN '    automatic file if all words positioned in puzzle
  96.             ShowBestPuzzle
  97.             LOCATE 37, 1: PRINT " After "; TS$(try); " tries, this complete puzzle was made."
  98.             FilePuzzle
  99.             LOCATE 39, 1: PRINT " Puzzle Filed, next up is word search.";
  100.             LOCATE 40, 1: PRINT "      press any to continue.";
  101.             puzzleFiled = -1
  102.             LOCATE 1, 1
  103.             _DISPLAY
  104.             SLEEP
  105.             EXIT WHILE
  106.         END IF
  107.     END IF
  108. IF puzzleFiled = 0 THEN
  109.     ShowBestPuzzle
  110.     LOCATE 37, 1: PRINT " After "; TS$(try); " tries, this was best puzzle."
  111.     _DISPLAY
  112.     LOCATE 38, 1: INPUT " Enter y for yes, to save the best to file."; y$
  113.     IF y$ = "y" THEN
  114.         FilePuzzle
  115.         LOCATE 39, 1: PRINT " Puzzle Filed.";
  116.     END IF
  117.     LOCATE 40, 1: PRINT " Next up is word search, press any to continue.";
  118.     LOCATE 1, 1
  119.     _DISPLAY
  120.     SLEEP
  121.  
  122. ' Now to find words in our best puzzle
  123. DIM bestPuz, mx, my, mb, mIndex, wIndex, cnt, hx, hy, wd, sx, sy, navX$, navY$, navD$, i
  124.  
  125. ShowBestPuzzle 'get a snapshot
  126. bestPuz = _NEWIMAGE(ScreenWidth, ScreenHeight, 32)
  127. _PUTIMAGE , 0, bestPuz
  128. WHILE _KEYDOWN(27) = 0
  129.     _PUTIMAGE , bestPuz, 0
  130.     LOCATE 38, 1: PRINT "Move mouse over a word to find."
  131.     mb = _MOUSEBUTTON(1) 'wait for a word to be clicked
  132.     mx = INT(_MOUSEX / 8) + 1: my = INT(_MOUSEY / 16) + 1
  133.     IF mx >= 65 AND mx <= 84 THEN
  134.         mIndex = my
  135.     ELSEIF mx >= 85 AND mx <= 104 THEN
  136.         mIndex = my + 40
  137.     ELSEIF mx >= 105 AND mx <= 125 THEN
  138.         mIndex = my + 80
  139.     ELSE
  140.         mIndex = 0
  141.     END IF
  142.     wIndex = 0: cnt = 0 '                 convert mIndex to wIndex of BestWords
  143.     FOR i = 1 TO WS.NumWords
  144.         IF BestWords(i).Placed THEN
  145.             cnt = cnt + 1
  146.             IF cnt = mIndex THEN wIndex = i: EXIT FOR
  147.         END IF
  148.     NEXT
  149.     IF wIndex THEN
  150.         IF Found(BestWords(wIndex).S, hx, hy, wd) THEN 'high lite it black, yellow
  151.             ConvertCR2Screen hx, hy, sx, sy '    tranlate array location to screen location and navigate column, row
  152.             ConvertCR2Nav hx, hy, wd, navX$, navY$, navD$
  153.             LOCATE 38, 1: PRINT BestWords(wIndex).S; " found at ("; navX$; ", "; navY$; ") going "; navD$
  154.             COLOR &HFF0000BB, &HFFFFFF00
  155.             LOCATE sy, sx: PRINT CHR$(AscBestLetters(hx, hy));
  156.             FOR i = 2 TO BestWords(wIndex).Len
  157.                 hx = hx + DX(wd): hy = hy + DY(wd)
  158.                 ConvertCR2Screen hx, hy, sx, sy
  159.                 LOCATE sy, sx: PRINT CHR$(AscBestLetters(hx, hy));
  160.             NEXT
  161.             COLOR &HFFFFFFFF, &HFF000000
  162.         ELSE
  163.             LOCATE 38, 1: PRINT "Sorry, something is screwed up!";
  164.         END IF
  165.     END IF
  166.     _DISPLAY
  167.     _LIMIT 60
  168.  
  169. SUB InitializeOnce ' everything that needs to be done once to get going
  170.     REDIM wd$, i, j, fName$, pLine$
  171.  
  172.     'new order to favor diagonals placements first if possible
  173.     DX(0) = 1: DY(0) = 0: DString$(0) = "East"
  174.     DX(1) = 0: DY(1) = 1: DString$(1) = "South"
  175.     DX(2) = -1: DY(2) = 0: DString$(2) = "West"
  176.     DX(3) = 0: DY(3) = -1: DString$(3) = "North"
  177.     DX(4) = -1: DY(4) = 1: DString$(4) = "South West"
  178.     DX(5) = -1: DY(5) = -1: DString$(5) = "North West"
  179.     DX(6) = 1: DY(6) = 1: DString$(6) = "South East"
  180.     DX(7) = 1: DY(7) = -1: DString$(7) = "North East"
  181.  
  182.     WS.GridSideM1 = WS.GridSide - 1
  183.     WS.GridSideP2M1 = WS.GridSide * WS.GridSide - 1
  184.     WS.GridLabel = MID$("   0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z", 1, WS.GridSide * 2 + 2)
  185.  
  186.     WS.NumWords = 0
  187.     WHILE wd$ <> "YULETIDE"
  188.         READ wd$
  189.         wd$ = _TRIM$(UCASE$(wd$))
  190.         IF LEN(wd$) <= WordLengthLimit AND wd$ <> "" THEN
  191.             WS.NumWords = WS.NumWords + 1
  192.             Words(WS.NumWords).S = wd$
  193.         END IF
  194.     WEND
  195.     Sort Words()
  196.     FOR j = 1 TO WS.NumWords
  197.         FOR i = 1 TO LEN(Words(j).S)
  198.             Words(j).Len = LEN(Words(j).S)
  199.             AscWord(j, i) = ASC(Words(j).S, i)
  200.         NEXT
  201.     NEXT
  202.  
  203.     REDIM AscLetters(0 TO WS.GridSideM1, 0 TO WS.GridSideM1) 'now that we have the right size
  204.  
  205.     'Now make a Sorted Word List file of up to 3 Columns of 40 words from the capitalized, trimmed, sorted word list
  206.     fName$ = WS.FileTheme + " Sorted 3 Column Search Words.txt"
  207.     OPEN fName$ FOR OUTPUT AS #1
  208.     FOR i = 1 TO 40
  209.         pLine$ = SPACE$(60)
  210.         IF i <= WS.NumWords THEN MID$(pLine$, 1, 20) = TS$(i) + ") " + Words(i).S
  211.         IF i + 40 <= WS.NumWords THEN MID$(pLine$, 21, 20) = TS$(i + 40) + ") " + Words(i + 40).S
  212.         IF i + 80 <= WS.NumWords THEN MID$(pLine$, 41, 20) = TS$(i + 80) + ") " + Words(i + 80).S
  213.         PRINT #1, pLine$
  214.     NEXT
  215.     CLOSE #1
  216.     EXIT SUB
  217.  
  218.     DATA baby,bethlehem,cards,carols,coal,cookies,december,decorate,eggnog,elf,eve,festivities,garland,gifts,green
  219.     DATA grinch,holiday,holly,joseph,joy,lights,mary,magi,manger,nativity,ornaments,poinsettia,red,reindeer,rudolph
  220.     DATA santa,scrooge,shepherd,sleigh,star,stockings,tidings,tinsel,tree,toys,wreath,mistletoe,candycane,angel
  221.     DATA chimney,fruitcake,gingerbread,greetings,goodwill,jingle,jolly,noel,naughty,nice,party
  222.     DATA partridge,ribbon,bow,helpers,sweater,wrap,vacation,workshop,yuletide
  223.  
  224. SUB RestartPuzzleFill
  225.     DIM i, j, k, r, c
  226.  
  227.     WS.PlaceWordIndex = 0
  228.     WS.NumUnplacedWords = 0 'count the disasters
  229.     WS.NumPlacedWords = 0
  230.     FOR i = 1 TO WS.NumWords 'clear positions of words
  231.         Words(i).Placed = 0: Words(i).X = -1: Words(i).Y = -1: Words(i).D = -1
  232.     NEXT
  233.     FOR r = 0 TO WS.GridSideM1 ' clear the letter numbers
  234.         FOR c = 0 TO WS.GridSideM1
  235.             AscLetters(c, r) = 32
  236.         NEXT
  237.     NEXT
  238.     FOR i = WS.NumWords TO 2 STEP -1 'shuffle the list of Words to load
  239.         r = INT(RND * i) + 1
  240.         SWAP Words(i), Words(r)
  241.         FOR j = 0 TO WordLengthLimit
  242.             SWAP AscWord(i, j), AscWord(r, j)
  243.         NEXT
  244.     NEXT
  245.     i = 0
  246.     WHILE i < WS.NumWords - 1 'order by word length
  247.         i = i + 1
  248.         FOR j = i + 1 TO WS.NumWords
  249.             IF Words(j).Len > Words(i).Len THEN
  250.                 SWAP Words(i), Words(j)
  251.                 FOR k = 0 TO WordLengthLimit
  252.                     SWAP AscWord(i, k), AscWord(j, k)
  253.                 NEXT
  254.             END IF
  255.         NEXT
  256.     WEND
  257.  
  258. SUB ShowPuzzle 'this was needed to make sure finding the best puzzle was working correctly
  259.     DIM i, x, y, cnt, notPlaced$, cntUnplaced
  260.     notPlaced$ = ""
  261.     CLS
  262.     LOCATE 1, 1: PRINT WS.GridLabel$
  263.     FOR i = 3 TO 2 + WS.GridSide
  264.         LOCATE i, 1: PRINT MID$(WS.GridLabel$, i * 2 - 2, 1);
  265.     NEXT
  266.     FOR y = 0 TO WS.GridSide - 1
  267.         FOR x = 0 TO WS.GridSide - 1
  268.             LOCATE y + 3, 2 * x + 4: PRINT CHR$(AscLetters(x, y))
  269.         NEXT
  270.     NEXT
  271.     FOR i = 1 TO WS.PlaceWordIndex
  272.         IF Words(i).Placed THEN
  273.             cnt = cnt + 1
  274.             IF cnt <= 40 THEN
  275.                 LOCATE cnt, 65: PRINT TS$(cnt); " "; Words(i).S;
  276.             ELSEIF cnt <= 80 THEN
  277.                 LOCATE cnt - 40, 85: PRINT TS$(cnt); " "; Words(i).S;
  278.             ELSEIF i <= 120 THEN
  279.                 LOCATE cnt - 80, 105: PRINT TS$(cnt); " "; Words(i).S;
  280.             END IF
  281.         ELSE
  282.             cntUnplaced = cntUnplaced + 1
  283.             notPlaced$ = notPlaced$ + Words(i).S + " "
  284.         END IF
  285.     NEXT
  286.     LOCATE 36, 1: PRINT "Words placed:"; WS.NumPlacedWords
  287.     LOCATE 37, 1: PRINT "Unplaced: "; WS.NumUnplacedWords
  288.     LOCATE 38, 1: PRINT "Not placed words: "; notPlaced$; cntUnplaced
  289.     LOCATE 39, 1: PRINT "Last word: "; TS$(WS.PlaceWordIndex); " "; Words(WS.PlaceWordIndex).S;
  290.     'SLEEP
  291.  
  292. SUB PlaceWord
  293.     DIM bestScore, headScore, tailScore, y, x, d, b1, b2, i, spaceHeadF, spaceTailF
  294.  
  295.     bestScore = -1 ' going through entire array of AscLetters try every direction looking for best score = placement
  296.     FOR y = 0 TO WS.GridSideM1
  297.         FOR x = 0 TO WS.GridSideM1
  298.             spaceHeadF = 0 'every new word do this must be certain we have at least one cell empty
  299.             IF AscWord(WS.PlaceWordIndex, 1) = AscLetters(x, y) OR AscLetters(x, y) = 32 THEN
  300.                 IF AscWord(WS.PlaceWordIndex, 1) = AscLetters(x, y) THEN headScore = 15
  301.                 IF AscLetters(x, y) = 32 THEN headScore = 0: WS.UnfilledCellF = -1: spaceHeadF = -1 'no points for blanks but may proceed
  302.                 FOR d = 0 TO 7
  303.                     spaceTailF = 0: tailScore = 0
  304.                     b1 = x + DX(d) * (Words(WS.PlaceWordIndex).Len - 1) >= 0 AND x + DX(d) * (Words(WS.PlaceWordIndex).Len - 1) <= WS.GridSideM1
  305.                     b2 = y + DY(d) * (Words(WS.PlaceWordIndex).Len - 1) >= 0 AND y + DY(d) * (Words(WS.PlaceWordIndex).Len - 1) <= WS.GridSideM1
  306.                     IF b1 AND b2 THEN 'we're in
  307.                         FOR i = 2 TO Words(WS.PlaceWordIndex).Len
  308.                             IF AscWord(WS.PlaceWordIndex, i) = AscLetters(x + DX(d) * (i - 1), y + DY(d) * (i - 1)) THEN
  309.                                 tailScore = tailScore + 10 + (d <= 3) * -1 + (d > 3) * -(INT(RND * 4) + 1)
  310.                             ELSEIF AscLetters(x + DX(d) * (i - 1), y + DY(d) * (i - 1)) = 32 THEN
  311.                                 WS.UnfilledCellF = -1
  312.                                 spaceTailF = -1
  313.                                 tailScore = tailScore + (d > 1) * -1 + (d > 3) * -1 + (d > 6) * -.5
  314.                             ELSE
  315.                                 GOTO skip
  316.                             END IF
  317.                         NEXT
  318.                         IF headScore + tailScore > bestScore AND (spaceHeadF OR spaceTailF) THEN 'make sure placing word over at least one empty spot
  319.                             Words(WS.PlaceWordIndex).X = x: Words(WS.PlaceWordIndex).Y = y: Words(WS.PlaceWordIndex).D = d
  320.                             bestScore = headScore + tailScore 'local
  321.                         END IF
  322.                     END IF
  323.                     skip:
  324.                 NEXT
  325.             END IF
  326.         NEXT
  327.     NEXT
  328.     'BEEP
  329.     IF bestScore > -1 THEN 'we have a good place for this word put it there and update stuff
  330.         FOR i = 1 TO Words(WS.PlaceWordIndex).Len
  331.             AscLetters(DX(Words(WS.PlaceWordIndex).D) * (i - 1) + Words(WS.PlaceWordIndex).X,_
  332.              DY(Words(WS.PlaceWordIndex).D) * (i - 1) + Words(WS.PlaceWordIndex).Y) = ascWord(WS.PlaceWordIndex, i)
  333.         NEXT
  334.         Words(WS.PlaceWordIndex).Placed = -1
  335.         WS.NumPlacedWords = WS.NumPlacedWords + 1
  336.     ELSE
  337.         Words(WS.PlaceWordIndex).Placed = 0
  338.         WS.NumUnplacedWords = WS.NumUnplacedWords + 1
  339.     END IF
  340.  
  341. SUB ShowBestPuzzle
  342.     REDIM mMod, m, i, j, x, y, DirectionTotals(0 TO 7), s$(1 TO 4)
  343.  
  344.     mMod = LEN(WS.Filler) '     FillBlanksInBest
  345.     FOR y = 0 TO WS.GridSide - 1
  346.         FOR x = 0 TO WS.GridSide - 1
  347.             IF AscBestLetters(x, y) = 32 THEN
  348.                 AscBestLetters(x, y) = ASC(WS.Filler, m + 1)
  349.                 m = (m + 1) MOD mMod
  350.             END IF
  351.         NEXT
  352.     NEXT
  353.  
  354.     CLS '                                redraw screen
  355.     LOCATE 1, 1: PRINT WS.GridLabel$
  356.     FOR i = 3 TO 2 + WS.GridSide
  357.         LOCATE i, 1: PRINT MID$(WS.GridLabel$, i * 2 - 2, 1);
  358.     NEXT
  359.     FOR y = 0 TO WS.GridSide - 1
  360.         FOR x = 0 TO WS.GridSide - 1
  361.             LOCATE y + 3, 2 * x + 4: PRINT CHR$(AscBestLetters(x, y))
  362.         NEXT
  363.     NEXT
  364.  
  365.     FOR i = 1 TO WS.NumWords
  366.         IF BestWords(i).Placed THEN
  367.             j = j + 1
  368.             IF j <= 40 THEN
  369.                 LOCATE j, 65: PRINT TS$(j); " "; BestWords(i).S;
  370.             ELSEIF j <= 80 THEN
  371.                 LOCATE j - 40, 85: PRINT TS$(j); " "; BestWords(i).S;
  372.             ELSEIF j <= 120 THEN
  373.                 LOCATE j - 80, 105: PRINT TS$(j); " "; BestWords(i).S
  374.             END IF
  375.             DirectionTotals(BestWords(i).D) = DirectionTotals(BestWords(i).D) + 1
  376.         END IF
  377.     NEXT
  378.     s$(1) = " Total Norths: " + TS$(DirectionTotals(3)) + ", Total Souths: " + TS$(DirectionTotals(1))
  379.     s$(2) = " Total Easts: " + TS$(DirectionTotals(0)) + ", Total Wests: " + TS$(DirectionTotals(2))
  380.     s$(3) = " Total NWs: " + TS$(DirectionTotals(5)) + ", Total SWs: " + TS$(DirectionTotals(4))
  381.     s$(4) = " Total NEs: " + TS$(DirectionTotals(7)) + ", Total SEs: " + TS$(DirectionTotals(6))
  382.     FOR i = 1 TO 4
  383.         LOCATE 32 + i, 1: PRINT s$(i);
  384.     NEXT
  385.  
  386. SUB FilePuzzle
  387.     REDIM i, j, r, c, b$, x$, y$, d$, s$(1 TO 4)
  388.  
  389.     OPEN WS.FileTheme + " Word Search Puzzle.txt" FOR OUTPUT AS #1
  390.     PRINT #1, WS.GridLabel$
  391.     PRINT #1, ""
  392.     FOR r = 0 TO WS.GridSideM1
  393.         b$ = MID$(WS.GridLabel$, r * 2 + 4, 1) + "  "
  394.         FOR c = 0 TO WS.GridSideM1
  395.             b$ = b$ + CHR$(AscBestLetters(c, r)) + " "
  396.         NEXT
  397.         PRINT #1, b$
  398.     NEXT
  399.     CLOSE #1
  400.  
  401.     OPEN WS.FileTheme + " Word Search Solutions.txt" FOR OUTPUT AS #1
  402.     PRINT #1, ""
  403.     PRINT #1, " Search Word Solutions:"
  404.     PRINT #1, "            Words from: " + WS.FileTheme + " Word List.txt"
  405.     PRINT #1, ""
  406.     PRINT #1, " First Letter Location and Direction:"
  407.     PRINT #1, ""
  408.     FOR i = 1 TO WS.NumWords
  409.         IF BestWords(i).Placed THEN
  410.             j = j + 1
  411.             ConvertCR2Nav BestWords(i).X, BestWords(i).Y, BestWords(i).D, x$, y$, d$
  412.             PRINT #1, RIGHT$("    " + TS$(j), 4) + ") " + RIGHT$(SPC(15) + BestWords(i).S, 15) + " (" + x$ + ", " + y$ + ") >>>---> " + d$
  413.         END IF
  414.     NEXT
  415.     PRINT #1, " "
  416.     s$(1) = " Total Norths: " + TS$(DirectionTotals(3)) + ", Total Souths: " + TS$(DirectionTotals(1))
  417.     s$(2) = " Total Easts: " + TS$(DirectionTotals(0)) + ", Total Wests: " + TS$(DirectionTotals(2))
  418.     s$(3) = " Total NWs: " + TS$(DirectionTotals(5)) + ", Total SWs: " + TS$(DirectionTotals(4))
  419.     s$(4) = " Total NEs: " + TS$(DirectionTotals(7)) + ", Total SEs: " + TS$(DirectionTotals(6))
  420.     FOR i = 1 TO 4
  421.         PRINT #1, s$(i)
  422.     NEXT
  423.     PRINT #1, " "
  424.     PRINT #1, " Message in unused letters: " + WS.Filler
  425.     CLOSE #1
  426.  
  427. FUNCTION Found (word$, headX, headY, direction)
  428.     'First find a letter that matches the first letter in word$,
  429.     'then at that x, y try each of 8 directions to see if find a match.
  430.     'See if enough room to fit the find word before heading out to match letters.
  431.  
  432.     DIM first$, lenFind, x, y, d, b1, b2, xx, yy, b$, i
  433.  
  434.     first$ = MID$(word$, 1, 1): lenFind = LEN(word$) - 1
  435.     FOR y = 0 TO WS.GridSideM1
  436.         FOR x = 0 TO WS.GridSideM1
  437.             IF AscBestLetters(x, y) = ASC(first$) THEN
  438.                 FOR d = 0 TO 7 'will word fit in this direction? 2 booleans True condition
  439.                     b1 = lenFind * DX(d) + x >= 0 AND lenFind * DX(d) + x <= WS.GridSideM1
  440.                     b2 = lenFind * DY(d) + y >= 0 AND lenFind * DY(d) + y <= WS.GridSideM1
  441.                     IF b1 AND b2 THEN 'word fits,
  442.                         ' build word from Letters block to see if matches word to find
  443.                         b$ = first$: xx = x + DX(d): yy = y + DY(d)
  444.                         FOR i = 2 TO LEN(word$)
  445.                             b$ = b$ + CHR$(AscBestLetters(xx, yy))
  446.                             xx = xx + DX(d): yy = yy + DY(d)
  447.                         NEXT
  448.                         xx = x: yy = y 'copy x, y for rebuilding word on screen
  449.                         IF b$ = word$ THEN 'found one show our result
  450.                             headX = x: headY = y: direction = d: Found = -1
  451.                             EXIT SUB
  452.                         END IF
  453.                     END IF
  454.                 NEXT
  455.             END IF
  456.         NEXT
  457.     NEXT
  458.  
  459. SUB ConvertCR2Screen (c, r, screenC, screenR)
  460.     screenC = 2 * c + 4: screenR = r + 3
  461.  
  462. SUB ConvertCR2Nav (c, r, d, navX$, navY$, navD$)
  463.     IF c > 9 THEN navX$ = CHR$(c - 9 + AscA - 1) ELSE navX$ = TS$(c)
  464.     IF r > 9 THEN navY$ = CHR$(r - 9 + AscA - 1) ELSE navY$ = TS$(r)
  465.     navD$ = DString$(d)
  466.  
  467. SUB Sort (arr() AS WordType)
  468.     DIM i, j
  469.     FOR i = 1 TO WS.NumWords - 1
  470.         FOR j = i + 1 TO WS.NumWords
  471.             IF arr(j).S < arr(i).S THEN SWAP arr(j), arr(i)
  472.         NEXT
  473.     NEXT
  474.  
  475. FUNCTION TS$ (n) ' this shorthand for TrimString and I want it shorthand!
  476.     TS$ = _TRIM$(STR$(n))
  477.  
  478.  

Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: SierraKen on December 08, 2020, 11:26:42 pm
Cool pine trees B+! Good job!
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: SierraKen on December 09, 2020, 02:13:47 am
Here is my Christmas Tree ornament. It's not as fancy as B+'s, but I thought I would throw this in tonight. Feel free to use any of the code for your own. Below is a picture. The program itself changes the colors of the parallel circles (ovals).

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(800, 600, 32)
  2. _TITLE "SierraKen's Christmas Tree Ornament - Press Esc to quit."
  3. c3 = 255
  4. FOR cir = .01 TO 130 STEP .1
  5.     c3 = c3 - .1
  6.     CIRCLE (400, 300), cir, _RGB32(0, 0, c3)
  7. NEXT cir
  8.     _LIMIT 30
  9.     yy = 300
  10.     c4 = INT(RND * 155) + 100
  11.     c5 = INT(RND * 155) + 100
  12.     c6 = INT(RND * 155) + 100
  13.     CIRCLE (400, yy), 130, _RGB32(c4, c5, c6), , , .5
  14.     yy = yy - 22.5
  15.     CIRCLE (400, yy), 125, _RGB32(c4, c5, c6), , , .5
  16.     yy = yy - 22.5
  17.     CIRCLE (400, yy), 120, _RGB32(c4, c5, c6), , , .5
  18.     yy = yy - 22.5
  19.     CIRCLE (400, yy), 105, _RGB32(c4, c5, c6), , , .5
  20.     yy = yy - 22.5
  21.     CIRCLE (400, yy), 75, _RGB32(c4, c5, c6), , , .5
  22.     yy = yy - 22.5
  23.     CIRCLE (400, yy), 15, _RGB32(c4, c5, c6), , , .5
  24.     yy = 300
  25.     yy = yy + 22.5
  26.     CIRCLE (400, yy), 125, _RGB32(c4, c5, c6), , , .5
  27.     yy = yy + 22.5
  28.     CIRCLE (400, yy), 120, _RGB32(c4, c5, c6), , , .5
  29.     yy = yy + 22.5
  30.     CIRCLE (400, yy), 105, _RGB32(c4, c5, c6), , , .5
  31.     yy = yy + 22.5
  32.     CIRCLE (400, yy), 75, _RGB32(c4, c5, c6), , , .5
  33.     yy = yy + 22.5
  34.     CIRCLE (400, yy), 15, _RGB32(c4, c5, c6), , , .5
  35.     _DELAY .5
  36.  

Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 09, 2020, 01:02:58 pm
Thanks Ken, only one gasp in awe ;-))

Ken I just noticed your ornament, I can't tell which side is toward me top or bottom? When I look at top then that side, when I look at bottom, that side, I love it and with different lights too.

I wonder if we could make it flip: It goes from light to dark, dark to light then flips...
You'd draw half circles one way (except at top you can see whole cicle and at bottom no circle, then the other half circles the other way.

Well on 2nd thought, it's harder than that because it's more or less than half circles.
Maybe _vince or STx can figure it out, Ashish can probably draw it wobbling like the Earth in it's orbits with GL stuff.

Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: johnno56 on December 09, 2020, 02:44:07 pm
Bplus,

Possible answer for "which side".

As you know, all surface points are equidistant from its centre. So technically, a sphere, has no "sides". Unless it is hollow... Inside and outside...

To answer your query, 'which side is toward me', for want of a better word, the 'outside' is toward you....

But, you have to admit, it's a very nice blue.
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: SierraKen on December 09, 2020, 02:55:58 pm
Thanks guys :). Yeah the only way to explain it would be that it's blue glass and you can see right through it. I also thought about half-circles but I came to the same conclusion, it wouldn't look right for all of them, unless I figured out the right shape on each of them... dang now I want to see if I can do it..... :)
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Petr on December 09, 2020, 03:09:48 pm
I have also something in progress... i think this is done by 7 days or so... :)
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: SierraKen on December 09, 2020, 04:19:15 pm
Here we go. I did all the lines manually by trial and error and I added a glowing blue the pulsates. Now you can't see the other side and you can only see from about a 45 degree angle from the bottom (or 315 degrees if you want to be technical :)). This is a better Christmas Tree ornament than my last one.

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(800, 600, 32)
  2. _TITLE "SierraKen's Christmas Tree Ornament - Press Esc to quit."
  3. t = 1
  4.     _LIMIT 60
  5.     IF col > 100 THEN t = 0
  6.     IF col < 50 THEN t = 1
  7.     IF t = 0 THEN col = col - 25
  8.     IF t = 1 THEN col = col + 25
  9.     c3 = 255
  10.     FOR cir = .01 TO 130 STEP .1
  11.         c3 = c3 - .1
  12.         CIRCLE (400, 300), cir, _RGB32(0, 0, c3 - col)
  13.     NEXT cir
  14.     yy = 300
  15.     c4 = INT(RND * 155) + 100
  16.     c5 = INT(RND * 155) + 100
  17.     c6 = INT(RND * 155) + 100
  18.     CIRCLE (400, yy), 130, _RGB32(c4, c5, c6), 2 * _PI, _PI, .5
  19.     yy = yy - 40.5
  20.     CIRCLE (400, yy), 124, _RGB32(c4, c5, c6), 2 * _PI, _PI, .4
  21.     yy = yy - 30.5
  22.     CIRCLE (400, yy), 105, _RGB32(c4, c5, c6), 2 * _PI, _PI, .39
  23.     yy = 300
  24.     yy = yy + 22.5
  25.     CIRCLE (400, yy), 130, _RGB32(c4, c5, c6), 2 * _PI, _PI, .5
  26.     yy = yy + 22.5
  27.     CIRCLE (400, yy), 125, _RGB32(c4, c5, c6), 2 * _PI, _PI, .5
  28.     yy = yy + 22.5
  29.     CIRCLE (400, yy), 110, _RGB32(c4, c5, c6), 2 * _PI, _PI, .5
  30.     yy = yy + 22.5
  31.     CIRCLE (400, yy), 75, _RGB32(c4, c5, c6), , , .5
  32.     yy = yy + 22.5
  33.     CIRCLE (400, yy), 15, _RGB32(c4, c5, c6), , , .5
  34.     _DELAY .25
  35.     _DISPLAY
  36.  
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 09, 2020, 05:22:27 pm
@SierraKen NICE! you did the hard work, now you can take snapshots at different light levels and play a round upside down and the next right side up AND/OR grab our old favorite RotoZoom and do...

oh heck! then you can do any size and at any place!
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: SierraKen on December 09, 2020, 08:25:53 pm
Thanks B+. But from what I know, I couldn't copy it to other places without having a lot of black erase parts of them because the _COPYIMAGE (0) and ROTOZOOM turns the entire screen and not a part of it that I know of. I tried using the old GET command without luck. But I was able to make this one that just snaps a photo of it and then goes in a ROTOZOOM loop with it turning non-stop. :) It doesn't change colors but it looks really cool! Notice I put the ornament in its own SUB. :) It does have a random color on the lines though for each time you run the program. I like this one even more than the others. :) 

Code: QB64: [Select]
  1. _TITLE "SierraKen's Christmas Tree Ornament - Press Esc to quit."
  2. DIM x AS LONG, y AS LONG, Image AS LONG, Scale AS SINGLE, Rotation AS SINGLE
  3. DIM orn AS LONG
  4. t = 1
  5. i& = _NEWIMAGE(800, 600, 32)
  6. ornament
  7. orn = _COPYIMAGE(0)
  8.     _LIMIT 60
  9.     RotoZoom 400, 300, orn&, 1, turn 'Angle
  10.     _DELAY .01
  11.     _DISPLAY
  12.     CLS
  13.     turn = turn + 1
  14.  
  15. SUB ornament
  16.     c3 = 255
  17.     FOR cir = .01 TO 130 STEP .1
  18.         c3 = c3 - .1
  19.         CIRCLE (400, 300), cir, _RGB32(0, 0, c3)
  20.     NEXT cir
  21.     yy = 300
  22.     c4 = INT(RND * 155) + 100
  23.     c5 = INT(RND * 155) + 100
  24.     c6 = INT(RND * 155) + 100
  25.     CIRCLE (400, yy), 130, _RGB32(c4, c5, c6), 2 * _PI, _PI, .5
  26.     yy = yy - 40.5
  27.     CIRCLE (400, yy), 124, _RGB32(c4, c5, c6), 2 * _PI, _PI, .4
  28.     yy = yy - 30.5
  29.     CIRCLE (400, yy), 105, _RGB32(c4, c5, c6), 2 * _PI, _PI, .39
  30.     yy = 300
  31.     yy = yy + 22.5
  32.     CIRCLE (400, yy), 130, _RGB32(c4, c5, c6), 2 * _PI, _PI, .5
  33.     yy = yy + 22.5
  34.     CIRCLE (400, yy), 125, _RGB32(c4, c5, c6), 2 * _PI, _PI, .5
  35.     yy = yy + 22.5
  36.     CIRCLE (400, yy), 110, _RGB32(c4, c5, c6), 2 * _PI, _PI, .5
  37.     yy = yy + 22.5
  38.     CIRCLE (400, yy), 75, _RGB32(c4, c5, c6), , , .5
  39.     yy = yy + 22.5
  40.     CIRCLE (400, yy), 15, _RGB32(c4, c5, c6), , , .5
  41.  
  42.  
  43.  
  44. SUB RotoZoom (X AS LONG, Y AS LONG, Image AS LONG, Scale AS SINGLE, Rotation AS SINGLE)
  45.     DIM px(3) AS SINGLE: DIM py(3) AS SINGLE
  46.     W& = _WIDTH(Image&): H& = _HEIGHT(Image&)
  47.     px(0) = -W& / 2: py(0) = -H& / 2: px(1) = -W& / 2: py(1) = H& / 2
  48.     px(2) = W& / 2: py(2) = H& / 2: px(3) = W& / 2: py(3) = -H& / 2
  49.     sinr! = SIN(-Rotation / 57.2957795131): cosr! = COS(-Rotation / 57.2957795131)
  50.     FOR i& = 0 TO 3
  51.         x2& = (px(i&) * cosr! + sinr! * py(i&)) * Scale + X: y2& = (py(i&) * cosr! - px(i&) * sinr!) * Scale + Y
  52.         px(i&) = x2&: py(i&) = y2&
  53.     NEXT
  54.     _MAPTRIANGLE (0, 0)-(0, H& - 1)-(W& - 1, H& - 1), Image& TO(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
  55.     _MAPTRIANGLE (0, 0)-(W& - 1, 0)-(W& - 1, H& - 1), Image& TO(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
  56.  
  57.  
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 09, 2020, 08:41:35 pm
@SierraKen  Dang that's NICER! Rotating it, makes it more 3D IMHO.

With _PUTIMAGE, you can put snapshot anywhere you want, any size you want.

Making an ornament sub is really good then you can give ornament a center(x, y) coodinate and it will draw there instead of the center of the screen, same with color, same with radius (but the stuff you did by hand has to be in relation to the center of the screen = center (x, y) of ornament. Let me know if your head is starting to ache ;-))

Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: SierraKen on December 09, 2020, 10:48:51 pm
LOL thanks B+, but I think that's all my brain can take for now. I might look into this more soon. :) I do agree that it looks more 3D :).
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 10, 2020, 01:15:51 am
Here's something:
Code: QB64: [Select]
  1. _TITLE "b+ mod SierraKen's Ornament - Press Esc to quit." ' b+ 2020-12-09
  2. CONST Xmax = 800, Ymax = 600, nOrn = 21, OrnR = 50
  3. SCREEN _NEWIMAGE(Xmax, Ymax, 32)
  4. REDIM OrnX(1 TO nOrn), OrnY(1 TO nOrn), OrnA(1 TO nOrn)
  5.  
  6. ' Get locations for a pyramid of circles st: ========================================================
  7. 'let n = number of circles at base of pile
  8. n = 6
  9.  
  10. 'let r = radius of each circle
  11. r = OrnR
  12.  
  13. 'let base be total length of pile
  14. baseLength = 2 * r * n
  15.  
  16. 'center pyramid in middle of screen
  17. startx = (Xmax - baseLength) / 2
  18.  
  19. 'stacking circles that form equilateral triangles at their origins have a height change of
  20. deltaHeight = r * 3 ^ .5 'r times the sqr(3)
  21. i = 1
  22. FOR row = n TO 1 STEP -1
  23.     IF row = n THEN y = Ymax - r - 1 ELSE y = y - deltaHeight
  24.     FOR col = 1 TO row
  25.         x = startx + col * 2 * r - r
  26.         'CIRCLE (x, y), r
  27.         OrnX(i) = x: OrnY(i) = y: OrnA(i) = RND * 360
  28.         i = i + 1
  29.     NEXT
  30.     startx = startx + r
  31. ' ======================================================================================================
  32.  
  33. ornament 'draw ornament and note the background is transparent at moment
  34.  
  35. _DELAY 1.5
  36. Orn = _NEWIMAGE(262, 262, 32)
  37.  
  38. _PUTIMAGE , 0, Orn, (Xmax / 2 - 131, Ymax / 2 - 131)-STEP(262, 262)
  39.     FOR i = 1 TO nOrn
  40.         OrnA(i) = OrnA(i) + 1
  41.         drawOrn OrnX(i), OrnY(i), 50, OrnA(i)
  42.     NEXT
  43.     _DISPLAY
  44.     _LIMIT 60
  45.  
  46. SUB drawOrn (x, y, r, degreeAngle)
  47.     OffScrn = _NEWIMAGE(262, 262, 32)
  48.     _DEST OffScrn
  49.     RotoZoom 131, 131, Orn, 1, degreeAngle
  50.     _PUTIMAGE (x - r, y - r)-STEP(2 * r, 2 * r), OffScrn, 0
  51.     _DEST 0
  52.     _FREEIMAGE OffScrn
  53.  
  54. SUB ornament
  55.     c3 = 180
  56.     FOR cir = .01 TO 133 STEP .1
  57.         c3 = c3 - .07
  58.         CIRCLE (400, 300), cir, _RGB32(0, c3, 0)
  59.     NEXT cir
  60.     yy = 300
  61.     CIRCLE (400, yy), 130, &HFFFFFFFF, 2 * _PI, _PI, .5
  62.     yy = yy - 40.5
  63.     CIRCLE (400, yy), 124, &HFFFFFFFF, 2 * _PI, _PI, .4
  64.     yy = yy - 30.5
  65.     CIRCLE (400, yy), 105, &HFFFFFFFF, 2 * _PI, _PI, .39
  66.     yy = 300
  67.     yy = yy + 22.5
  68.     CIRCLE (400, yy), 130, &HFFFFFFFF, 2 * _PI, _PI, .5
  69.     yy = yy + 22.5
  70.     CIRCLE (400, yy), 125, &HFFFFFFFF, 2 * _PI, _PI, .5
  71.     yy = yy + 22.5
  72.     CIRCLE (400, yy), 110, &HFFFFFFFF, 2 * _PI, _PI, .5
  73.     yy = yy + 22.5
  74.     CIRCLE (400, yy), 75, &HFFFFFFFF, , , .5
  75.     yy = yy + 22.5
  76.     CIRCLE (400, yy), 15, &HFFFFFFFF, , , .5
  77.  
  78. SUB RotoZoom (X AS LONG, Y AS LONG, Image AS LONG, Scale AS SINGLE, Rotation AS SINGLE)
  79.     DIM px(3) AS SINGLE: DIM py(3) AS SINGLE
  80.     W& = _WIDTH(Image&): H& = _HEIGHT(Image&)
  81.     px(0) = -W& / 2: py(0) = -H& / 2: px(1) = -W& / 2: py(1) = H& / 2
  82.     px(2) = W& / 2: py(2) = H& / 2: px(3) = W& / 2: py(3) = -H& / 2
  83.     sinr! = SIN(-Rotation / 57.2957795131): cosr! = COS(-Rotation / 57.2957795131)
  84.     FOR i& = 0 TO 3
  85.         x2& = (px(i&) * cosr! + sinr! * py(i&)) * Scale + X: y2& = (py(i&) * cosr! - px(i&) * sinr!) * Scale + Y
  86.         px(i&) = x2&: py(i&) = y2&
  87.     NEXT
  88.     _MAPTRIANGLE (0, 0)-(0, H& - 1)-(W& - 1, H& - 1), Image& TO(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
  89.     _MAPTRIANGLE (0, 0)-(W& - 1, 0)-(W& - 1, H& - 1), Image& TO(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
  90.  
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: SierraKen on December 10, 2020, 01:49:24 am
I turned mine into a Musical Christmas Tree Ornament. It plays Jingle Bells while the ornament turns. The PLAY command plays notes in the background but you need to add "MB" at the start of the PLAY string, as you can see in my JingleBells SUB. I found the notes and lyrics online. The lyrics stay in time with the song as it plays and writes them in the _TITLE bar.

Code: QB64: [Select]
  1. 'Musical Christmas Tree Ornament - Sing to Jingle Bells with your computer!
  2. 'by SierraKen
  3. 'Music Notes and Lyrics found here: https://www.piano-keyboard-guide.com/how-to-play-jingle-bells-easy-piano-keyboard-tutorial-for-beginners/
  4.  
  5. DIM orn AS LONG
  6. t = 1
  7. i& = _NEWIMAGE(800, 600, 32)
  8. ornament
  9. orn& = _COPYIMAGE(0)
  10. JingleBells
  11. READ song$: _TITLE song$
  12.     _LIMIT 60
  13.     RotoZoom 400, 300, orn&, 1, turn 'Angle
  14.     _DELAY .01
  15.     _DISPLAY
  16.     CLS
  17.     a$ = INKEY$
  18.     IF a$ = CHR$(27) THEN END
  19.     IF e = 1 AND a$ = " " THEN RESTORE song: e = 0: CLS: turn = 0: READ song$: _TITLE song$: JingleBells
  20.     turn = turn + 1
  21.     IF turn / 145 = INT(turn / 145) AND e <> 1 THEN
  22.         READ song$
  23.         IF song$ = "done" THEN e = 1: GOTO skip:
  24.         _TITLE song$
  25.         skip:
  26.         IF e = 1 THEN _TITLE "Musical Christmas Tree Ornament - Press Space Bar to play song again. - Press Esc to quit."
  27.     END IF
  28. song:
  29. DATA "Jingle bells, jingle bells."
  30. DATA "Jingle all the way"
  31. DATA "Oh, what fun it is to ride"
  32. DATA "In a one horse open sleigh hey"
  33. DATA "Jingle bells, jingle bells"
  34. DATA "Jingle all the way"
  35. DATA "Oh, what fun it is to ride"
  36. DATA "In a one horse open sleigh"
  37. DATA "Dashing through the snow"
  38. DATA "On a one horse open sleigh"
  39. DATA "O'er the fields we go,"
  40. DATA "Laughing all the way"
  41. DATA "Bells on bob tail ring,"
  42. DATA "making spirits bright"
  43. DATA "What fun it is to laugh and sing"
  44. DATA "A sleighing song tonight, Oh"
  45. DATA "Jingle bells, jingle bells"
  46. DATA "Jingle all the way"
  47. DATA "Oh, what fun it is to ride"
  48. DATA "In a one horse open sleigh hey"
  49. DATA "Jingle bells, jingle bells"
  50. DATA "Jingle all the way"
  51. DATA "Oh, what fun it is to ride"
  52. DATA "In a one horse open sleigh"
  53. DATA "done"
  54.  
  55. SUB JingleBells
  56.     PLAY "MB L5 E E E E E E"
  57.     PLAY "MB L5 E G C D E"
  58.     PLAY "MB L5 F F F F F E E"
  59.     PLAY "MB L5 E E E D D E D G"
  60.     PLAY "MB L5 E E E E E E"
  61.     PLAY "MB L5 E G C D E"
  62.     PLAY "MB L5 F F F F F E E"
  63.     PLAY "MB L5 E E G G F D C"
  64.  
  65.     PLAY "MB L5 G E D C G"
  66.     PLAY "MB L5 G G G E D C A"
  67.     PLAY "MB L5 A F E D B"
  68.     PLAY "MB L5 A G F D E"
  69.     PLAY "MB L5 G E D C G"
  70.     PLAY "MB L5 G E D C A"
  71.     PLAY "MB L5 A A F E D G G G"
  72.     PLAY "MB L5 G A G F D C G"
  73.  
  74.     PLAY "MB L5 E E E E E E"
  75.     PLAY "MB L5 E G C D E"
  76.     PLAY "MB L5 F F F F F E E"
  77.     PLAY "MB L5 E E E D D E D G"
  78.     PLAY "MB L5 E E E E E E"
  79.     PLAY "MB L5 E G C D E"
  80.     PLAY "MB L5 F F F F F E E"
  81.     PLAY "MB L5 E E G G F D C"
  82.  
  83.  
  84. SUB ornament
  85.     c3 = 255
  86.     FOR cir = .01 TO 130 STEP .1
  87.         c3 = c3 - .1
  88.         CIRCLE (400, 300), cir, _RGB32(0, 0, c3)
  89.     NEXT cir
  90.     yy = 300
  91.     c4 = INT(RND * 155) + 100
  92.     c5 = INT(RND * 155) + 100
  93.     c6 = INT(RND * 155) + 100
  94.     CIRCLE (400, yy), 130, _RGB32(c4, c5, c6), 2 * _PI, _PI, .5
  95.     yy = yy - 40.5
  96.     CIRCLE (400, yy), 124, _RGB32(c4, c5, c6), 2 * _PI, _PI, .4
  97.     yy = yy - 30.5
  98.     CIRCLE (400, yy), 105, _RGB32(c4, c5, c6), 2 * _PI, _PI, .39
  99.     yy = 300
  100.     yy = yy + 22.5
  101.     CIRCLE (400, yy), 130, _RGB32(c4, c5, c6), 2 * _PI, _PI, .5
  102.     yy = yy + 22.5
  103.     CIRCLE (400, yy), 125, _RGB32(c4, c5, c6), 2 * _PI, _PI, .5
  104.     yy = yy + 22.5
  105.     CIRCLE (400, yy), 110, _RGB32(c4, c5, c6), 2 * _PI, _PI, .5
  106.     yy = yy + 22.5
  107.     CIRCLE (400, yy), 75, _RGB32(c4, c5, c6), , , .5
  108.     yy = yy + 22.5
  109.     CIRCLE (400, yy), 15, _RGB32(c4, c5, c6), , , .5
  110.  
  111.  
  112.  
  113. SUB RotoZoom (X AS LONG, Y AS LONG, Image AS LONG, Scale AS SINGLE, Rotation AS SINGLE)
  114.     DIM px(3) AS SINGLE: DIM py(3) AS SINGLE
  115.     W& = _WIDTH(Image&): H& = _HEIGHT(Image&)
  116.     px(0) = -W& / 2: py(0) = -H& / 2: px(1) = -W& / 2: py(1) = H& / 2
  117.     px(2) = W& / 2: py(2) = H& / 2: px(3) = W& / 2: py(3) = -H& / 2
  118.     sinr! = SIN(-Rotation / 57.2957795131): cosr! = COS(-Rotation / 57.2957795131)
  119.     FOR i& = 0 TO 3
  120.         x2& = (px(i&) * cosr! + sinr! * py(i&)) * Scale + X: y2& = (py(i&) * cosr! - px(i&) * sinr!) * Scale + Y
  121.         px(i&) = x2&: py(i&) = y2&
  122.     NEXT
  123.     _MAPTRIANGLE (0, 0)-(0, H& - 1)-(W& - 1, H& - 1), Image& TO(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
  124.     _MAPTRIANGLE (0, 0)-(W& - 1, 0)-(W& - 1, H& - 1), Image& TO(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
  125.  
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: SierraKen on December 10, 2020, 01:52:41 am
LOL That's awesome B+! I will have to study how you did that sometime. :)
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 10, 2020, 09:51:48 am
That's a great demo of PLAY Ken! I'll have to give that a try.
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: SMcNeill on December 10, 2020, 12:32:46 pm
If it's Christmas time, then it's all about time to go caroling, for which this little program might be of some help:

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(1024, 720, 32)
  2.  
  3.  
  4. REDIM songs(100) AS STRING
  5.  
  6.  
  7.     READ text$
  8.     IF text$ = "EOD" THEN EXIT DO
  9.     IF LEFT$(text$, 3) = "***" THEN count = count + 1: lines = 0
  10.     IF lines > 40 THEN songs(count) = songs(count) + "  (CONTINUE)  ": lines = 0: count = count + 1
  11.     lines = lines + 1
  12.     songs(count) = songs(count) + text$ + CHR$(10)
  13.  
  14. FOR i = 1 TO count
  15.     CLS
  16.     PRINT songs(i)
  17.     SLEEP
  18.  
  19. PRINT "Would you like to print these to a file, so you can print or view them elsewhere?"
  20. DO: i$ = UCASE$(INPUT$(1)): LOOP UNTIL i$ = "Y" OR i$ = "N"
  21. IF i$ = "Y" THEN
  22.     INPUT "Give me a file name to save to: "; filename$
  23.     IF filename$ = "" THEN filename$ = "Christmas Lyrics.txt"
  24.     OPEN filename$ FOR OUTPUT AS #1
  25.     RESTORE
  26.     DO
  27.         READ text$
  28.         IF text$ = "EOD" THEN EXIT DO
  29.         IF LEFT$(text$, 3) = "***" THEN PRINT #1, ""
  30.         PRINT #1, text$
  31.     LOOP
  32.     CLOSE
  33.  
  34.  
  35.  
  36. DATA "**** Angels We Have Heard On High ****"
  37. DATA "Angels we have heard on high"
  38. DATA "Sweetly singing over the plains"
  39. DATA "And the mountains in reply,"
  40. DATA "Echoing their joyous strains."
  41. DATA "Glo-ori-a"
  42. DATA "In excelsis de-o"
  43. DATA "Glo-ori-a"
  44. DATA "In excelsis de-o"
  45. DATA "Shepherds, why this Jubilee?"
  46. DATA "Why your joyous strains prolong?"
  47. DATA "What the gladsome tidings be"
  48. DATA "Which inspire your heavenly song?"
  49. DATA "Glo-ori-a"
  50. DATA "In excelsis de-o"
  51. DATA "Glo-ori-a"
  52. DATA "In excelsis de-o"
  53. DATA "Come to Bethlehem and see"
  54. DATA "Him whose birth the angels sing;"
  55. DATA "Come, adore on bended knee"
  56. DATA "Christ, the Lord,"
  57. DATA "the newborn King"
  58. DATA "Glo-ori-a"
  59. DATA "In excelsis de-o"
  60. DATA "Glo-ori-a"
  61. DATA "In excelsis de-o"
  62. DATA "See Him in a manger laid"
  63. DATA "Jesus, Lord of heaven and earth!"
  64. DATA "Mary, Joseph, lend your aid,"
  65. DATA "With us sing our Savior's birth."
  66. DATA "Glo-ori-a"
  67. DATA "In excelsis de-o"
  68. DATA "Glo-ori-a"
  69. DATA "In excelsis de-o"
  70. DATA "**** Away In a Manger ****"
  71. DATA "Away in a manger,"
  72. DATA "no crib for His bed,"
  73. DATA "The little Lord Jesus"
  74. DATA "laid down His sweet head;"
  75. DATA "The stars in the heavens"
  76. DATA "looked down where He lay,"
  77. DATA "The little Lord Jesus"
  78. DATA "asleep on the hay."
  79. DATA "The cattle are lowing,"
  80. DATA "the poor Baby wakes,"
  81. DATA "But little Lord Jesus,"
  82. DATA "no crying He makes."
  83. DATA "I love Thee, Lord Jesus;"
  84. DATA "look down from the sky"
  85. DATA "And stay by my cradle"
  86. DATA "till morning is nigh."
  87. DATA "Be near me, Lord Jesus;"
  88. DATA "I ask Thee to stay"
  89. DATA "Close by me forever"
  90. DATA "and love me I pray!"
  91. DATA "Bless all the dear children"
  92. DATA "in Thy tender care,"
  93. DATA "And fit us for Heaven"
  94. DATA "to live with Thee there."
  95. DATA "Away in a manger,"
  96. DATA "no crib for His bed,"
  97. DATA "The little Lord Jesus"
  98. DATA "laid down His sweet head;"
  99. DATA "The stars in the heavens"
  100. DATA "looked down where He lay,"
  101. DATA "The little Lord Jesus"
  102. DATA "asleep on the hay."
  103. DATA "**** Deck The Halls ****"
  104. DATA "Deck the halls with boughs of holly"
  105. DATA " Fa-la-la-la-la, la-la-la-la"
  106. DATA "'Tis the season to be jolly"
  107. DATA " Fa-la-la-la-la, la-la-la-la"
  108. DATA "Don we now our gay apparel"
  109. DATA " Fa-la-la, la-la-la, la-la-la."
  110. DATA "Troll the ancient Yule-tide carol"
  111. DATA " Fa-la-la-la-la, la-la-la-la."
  112. DATA "See the blazing Yule before us."
  113. DATA " Fa-la-la-la-la, la-la-la-la"
  114. DATA "Strike the harp and join the chorus."
  115. DATA " Fa-la-la-la-la, la-la-la-la"
  116. DATA "Follow me in merry measure."
  117. DATA " Fa-la-la-la-la, la-la-la-la"
  118. DATA "While I tell of Yule-tide treasure."
  119. DATA " Fa-la-la-la-la, la-la-la-la"
  120. DATA "Fast away the old year passes."
  121. DATA " Fa-la-la-la-la, la-la-la-la"
  122. DATA "Hail the new year, lads and lasses"
  123. DATA " Fa-la-la-la-la, la-la-la-la"
  124. DATA "Sing we joyous, all together."
  125. DATA " Fa-la-la-la-la, la-la-la-la"
  126. DATA "heedless of the wind and weather."
  127. DATA " Fa-la-la-la-la, la-la-la-la"
  128. DATA "**** Do You Hear What I Hear ****"
  129. DATA "Said the night wind to the little lamb,"
  130. DATA "do you see what I see"
  131. DATA "Way up in the sky, little lamb,"
  132. DATA "do you see what I see"
  133. DATA "A star, a star, dancing in the night"
  134. DATA "With a tail as big as a kite"
  135. DATA "With a tail as big as a kite"
  136. DATA "Said the little lamb to the shepherd boy,"
  137. DATA "do you hear what I hear"
  138. DATA "Ringing through the sky, shepherd boy,"
  139. DATA "do you hear what I hear"
  140. DATA "A song, a song, high above the trees"
  141. DATA "With a voice as big as the sea"
  142. DATA "With a voice as big as the sea"
  143. DATA "Said the shepherd boy to the mighty king,"
  144. DATA "do you know what I know"
  145. DATA "In your palace warm, mighty king,"
  146. DATA "do you know what I know"
  147. DATA "A Child, a Child shivers in the cold"
  148. DATA "Let us bring Him silver and gold"
  149. DATA "Let us bring Him silver and gold"
  150. DATA "Said the king to the people everywhere,"
  151. DATA "listen to what I say"
  152. DATA "Pray for peace, people everywhere!"
  153. DATA "listen to what I say"
  154. DATA "The Child, the Child, sleeping in the night"
  155. DATA "He will bring us goodness and light"
  156. DATA "He will bring us goodness and light"
  157. DATA "**** Far, Far Away on Judea's Plains ****"
  158. DATA "Far, far away on Judea's plains,"
  159. DATA "Shepherds of old"
  160. DATA "heard the joyous strains:"
  161. DATA "Glory to God, Glory to God,"
  162. DATA "Glory to God in the highest:"
  163. DATA "Peace on earth,"
  164. DATA "good-will to men;"
  165. DATA "Peace on earth,"
  166. DATA "good-will to men!"
  167. DATA "Sweet are these strains"
  168. DATA "of redeeming love,"
  169. DATA "Message of mercy from heaven above:"
  170. DATA "Glory to God, Glory to God,"
  171. DATA "Glory to God in the highest:"
  172. DATA "Peace on earth,"
  173. DATA "good-will to men;"
  174. DATA "Peace on earth,"
  175. DATA "Lord, with the angels"
  176. DATA "we too would rejoice,"
  177. DATA "Help us to sing with"
  178. DATA "the heart and voice:"
  179. DATA "Glory to God, Glory to God,"
  180. DATA "Glory to God in the highest:"
  181. DATA "Peace on earth,"
  182. DATA "good-will to men;"
  183. DATA "Peace on earth,"
  184. DATA "good-will to men!"
  185. DATA "Hasten the time when,"
  186. DATA "from every clime,"
  187. DATA "Men shall unite"
  188. DATA "in the strains sublime:"
  189. DATA "Glory to God, Glory to God,"
  190. DATA "Glory to God in the highest:"
  191. DATA "Peace on earth,"
  192. DATA "good-will to men;"
  193. DATA "Peace on earth,"
  194. DATA "good-will to men!"
  195. DATA "**** Frosty the Snow Man ****"
  196. DATA "Frosty the snowman was a jolly happy soul,"
  197. DATA "With a corncob pipe and a button nose"
  198. DATA "and two eyes made out of coal."
  199. DATA "Frosty the snowman is a fairy tale, they say,"
  200. DATA "He was made of snow but the children"
  201. DATA "know how he came to life one day."
  202. DATA "There must have been some magic in that"
  203. DATA "old silk hat they found."
  204. DATA "For when they placed it on his head"
  205. DATA "he began to dance around."
  206. DATA "O, Frosty the snowman"
  207. DATA "was alive as he could be,"
  208. DATA "And the children say he could laugh"
  209. DATA "and play just the same as you and me."
  210. DATA "Thumpetty thump thump,"
  211. DATA "thumpety thump thump,"
  212. DATA "Look at Frosty go."
  213. DATA "Thumpetty thump thump,"
  214. DATA "thumpety thump thump,"
  215. DATA "Over the hills of snow."
  216. DATA "Frosty the snowman knew"
  217. DATA "the sun was hot that day,"
  218. DATA "So he said, 'Let's run and"
  219. DATA "we'll have some fun"
  220. DATA "now before I melt away.'"
  221. DATA "Down to the village,"
  222. DATA "with a broomstick in his hand,"
  223. DATA "Running here and there all"
  224. DATA "around the square saying,"
  225. DATA "Catch me if you can."
  226. DATA "He led them down the streets of town"
  227. DATA "right to the traffic cop."
  228. DATA "And he only paused a moment when"
  229. DATA "he heard him holler 'Stop!'"
  230. DATA "For Frosty the snow man"
  231. DATA "had to hurry on his way,"
  232. DATA "But he waved goodbye saying,"
  233. DATA "'Don't you cry,"
  234. DATA "I'll be back again some day.'"
  235. DATA "Thumpetty thump thump,"
  236. DATA "thumpety thump thump,"
  237. DATA "Look at Frosty go."
  238. DATA "Thumpetty thump thump,"
  239. DATA "thumpety thump thump,"
  240. DATA "Over the hills of snow."
  241. DATA "**** Go, Tell It On The Mountain ****"
  242. DATA "While shepherds kept their watching"
  243. DATA "Over silent flocks by night,"
  244. DATA "Behold throughout the heavens,"
  245. DATA "There shone a holy light:"
  246. DATA "Go, Tell It On The Mountain,"
  247. DATA "Over the hills and everywhere;"
  248. DATA "Go, Tell It On The Mountain"
  249. DATA "That Jesus Christ is born."
  250. DATA "The shepherds feared and trembled"
  251. DATA "When lo! above the earth"
  252. DATA "Rang out the angel chorus"
  253. DATA "That hailed our Saviour's birth:"
  254. DATA "Go, Tell It On The Mountain,"
  255. DATA "Over the hills and everywhere;"
  256. DATA "Go, Tell It On The Mountain"
  257. DATA "That Jesus Christ is born."
  258. DATA "Down in a lowly manger"
  259. DATA "Our humble Christ was born"
  260. DATA "And God send us salvation,"
  261. DATA "That blessed Christmas morn:"
  262. DATA "Go, Tell It On The Mountain,"
  263. DATA "Over the hills and everywhere;"
  264. DATA "Go, Tell It On The Mountain"
  265. DATA "That Jesus Christ is born."
  266. DATA "When I am a seeker,"
  267. DATA "I seek both night and day;"
  268. DATA "I seek the Lord to help me,"
  269. DATA "And He shows me the way:"
  270. DATA "Go, Tell It On The Mountain,"
  271. DATA "Over the hills and everywhere;"
  272. DATA "Go, Tell It On The Mountain"
  273. DATA "That Jesus Christ is born."
  274. DATA "He made me a watchman"
  275. DATA "Upon the city wall,"
  276. DATA "And if I am a Christian,"
  277. DATA "I am the least of all."
  278. DATA "Go, Tell It On The Mountain,"
  279. DATA "Over the hills and everywhere;"
  280. DATA "Go, Tell It On The Mountain"
  281. DATA "That Jesus Christ is born."
  282. DATA "**** God Rest Ye Merry, Gentlemen ****"
  283. DATA "God Rest Ye Merry, Gentlemen,"
  284. DATA "Let nothing you dismay;"
  285. DATA "Remember Christ, our Saviour,"
  286. DATA "Was born on Christmas day,"
  287. DATA "To save us all from Satan's power"
  288. DATA "When we were gone astray."
  289. DATA "O tidings of comfort and joy,"
  290. DATA "comfort and joy,"
  291. DATA "O tidings of comfort and joy."
  292. DATA "In Bethlehem, in Jewry,"
  293. DATA "This blessed Babe was born,"
  294. DATA "And laid within a manger,"
  295. DATA "Upon this blessed morn;"
  296. DATA "That which His Mother Mary,"
  297. DATA "Did nothing take in scorn."
  298. DATA "O tidings of comfort and joy,"
  299. DATA "comfort and joy,"
  300. DATA "O tidings of comfort and joy."
  301. DATA "From God our Heavenly Father,"
  302. DATA "A blessed Angel came;"
  303. DATA "And unto certain Shepherds"
  304. DATA "Brought tidings of the same:"
  305. DATA "How that in Bethlehem was born"
  306. DATA "The Son of God by Name."
  307. DATA "O tidings of comfort and joy,"
  308. DATA "comfort and joy,"
  309. DATA "O tidings of comfort and joy."
  310. DATA "'Fear not,' then said the Angel,"
  311. DATA "'let nothing you affright,"
  312. DATA "This day is born a Saviour"
  313. DATA "Of pure Virgin bright,"
  314. DATA "To free all those who trust in Him"
  315. DATA "From Satan's power and might.'"
  316. DATA "O tidings of comfort and joy,"
  317. DATA "comfort and joy,"
  318. DATA "O tidings of comfort and joy."
  319. DATA "The shepherds at those tidings"
  320. DATA "Rejoiced much in mind,"
  321. DATA "And left their flocks a-feeding,"
  322. DATA "In tempest, storm, and wind:"
  323. DATA "And went to Bethlehem straightway,"
  324. DATA "The Son of God to find."
  325. DATA "O tidings of comfort and joy,"
  326. DATA "comfort and joy,"
  327. DATA "O tidings of comfort and joy."
  328. DATA "And when they came to Bethlehem"
  329. DATA "Where our dear Saviour lay,"
  330. DATA "They found Him in a manger,"
  331. DATA "Where oxen feed on hay;"
  332. DATA "His Mother Mary kneeling down,"
  333. DATA "Unto the Lord did pray."
  334. DATA "O tidings of comfort and joy,"
  335. DATA "comfort and joy,"
  336. DATA "O tidings of comfort and joy."
  337. DATA "Now to the Lord sing praises,"
  338. DATA "All you within this place,"
  339. DATA "And with true love and brotherhood"
  340. DATA "Each other now embrace;"
  341. DATA "This holy tide of Christmas"
  342. DATA "All other doth deface."
  343. DATA "O tidings of comfort and joy,"
  344. DATA "comfort and joy,"
  345. DATA "O tidings of comfort and joy."
  346. DATA "**** Hark! The Herald Angels Sing ****"
  347. DATA "Hark! the herald angels sing"
  348. DATA "'Glory to the newborn King"
  349. DATA "Peace on earth and mercy mild,"
  350. DATA "God and sinners reconciled!'"
  351. DATA "Joyful, all ye nations rise;"
  352. DATA "Join the triumph of the skies;"
  353. DATA "With angelic host proclaim"
  354. DATA "'Christ is born in Bethlehem!'"
  355. DATA "Hark! the herald angels sing"
  356. DATA "'Glory to the newborn King!'"
  357. DATA "Christ, by highest heaven adored;"
  358. DATA "Christ the everlasting Lord;"
  359. DATA "Late in time behold Him come,"
  360. DATA "Offspring of the favored one."
  361. DATA "Veiled in flesh, the Godhead see;"
  362. DATA "hail the incarnate Deity"
  363. DATA "Pleased as man with men to dwell,"
  364. DATA "Jesus, our Emmanuel"
  365. DATA "Hark! the herald angels sing,"
  366. DATA "'Glory to the newborn King'"
  367. DATA "Hail! the heaven-born Prince of Peace!"
  368. DATA "Hail! the Son of Righteousness!"
  369. DATA "Light and life to all He brings,"
  370. DATA "risen with healing in His wings."
  371. DATA "Mild He lays His glory by,"
  372. DATA "born that man no more may die;"
  373. DATA "Born to raise the sons of earth,"
  374. DATA "born to give them second birth"
  375. DATA "Hark! the herald angels sing,"
  376. DATA "'Glory to the newborn King'"
  377. DATA "**** I Heard the Bells on Christmas Day ****"
  378. DATA "I Heard the Bells on Christmas Day"
  379. DATA "Their old familiar carols play,"
  380. DATA "And wild and sweet the words repeat"
  381. DATA "Of peace on earth, good will to men."
  382. DATA "I thought how, as the day had come,"
  383. DATA "The belfries of all Christendom"
  384. DATA "Had rolled along the unbroken song"
  385. DATA "Of peace on earth, good will to men."
  386. DATA "And in despair I bowed my head:"
  387. DATA "'There is no peace on earth,' I said,"
  388. DATA "'For hate is strong and mocks the song"
  389. DATA "Of peace on earth, good will to men.'"
  390. DATA "Then pealed the bells more loud and deep:"
  391. DATA "'God is not dead, nor doth he sleep;"
  392. DATA "The wrong shall fail, the right prevail,"
  393. DATA "With peace on earth, good will to men.'"
  394. DATA "Till, ringing singing, on its way,"
  395. DATA "The world revolved from night to day,"
  396. DATA "A voice, a chime, a chant sublime,"
  397. DATA "Of peace on earth, good will to men!"
  398. DATA "**** It Came Upon The Midnight Clear ****"
  399. DATA "It came upon the midnight clear,"
  400. DATA "That glorious song of old,"
  401. DATA "From angels bending near the earth"
  402. DATA "With news of joy foretold,"
  403. DATA "'Peace on the earth, good will to men"
  404. DATA "From heaven's all gracious King.'"
  405. DATA "The world in solemn stillness lay,"
  406. DATA "To hear the angels sing."
  407. DATA "Still through the cloven skies they come,"
  408. DATA "Love's banner all unfurled;"
  409. DATA "And still their heavenly music floats"
  410. DATA "Over all the weary world."
  411. DATA "Above its sad and lowly plains"
  412. DATA "Old echoes plaintive ring,"
  413. DATA "And ever over its Babel sounds"
  414. DATA "The blessed angels sing."
  415. DATA "Yet with the woes of sin and strife"
  416. DATA "The world has suffered long;"
  417. DATA "Beneath the Angel-strain have rolled"
  418. DATA "Two thousand years of wrong;"
  419. DATA "And man at war with man hears not"
  420. DATA "The love-song which they bring;"
  421. DATA "O! hush the noise, ye men of strife,"
  422. DATA "And hear the Angels sing."
  423. DATA "O ye, beneath life's crushing load"
  424. DATA "Whose forms are bending low,"
  425. DATA "Who toil along the climbing way"
  426. DATA "With painful steps and slow;"
  427. DATA "Look now! for glad and golden hours"
  428. DATA "Come swiftly on the wing;"
  429. DATA "O rest beside the weary road"
  430. DATA "And hear the angels sing."
  431. DATA "For lo! the days are hastening on,"
  432. DATA "By prophets seen of old,"
  433. DATA "When with the ever-circling years"
  434. DATA "Shall come the time foretold,"
  435. DATA "When the new heaven and earth shall own"
  436. DATA "The Prince of Peace their King,"
  437. DATA "And the whole world send back the song"
  438. DATA "Which now the angels sing."
  439. DATA "**** Jingle Bells ****"
  440. DATA "Dashing through the snow"
  441. DATA "On a one-horse open sleigh,"
  442. DATA "Over the fields we go,"
  443. DATA "Laughing all the way;"
  444. DATA "Bells on bob-tail ring,"
  445. DATA "making spirits bright,"
  446. DATA "What fun it is to ride and sing"
  447. DATA "A sleighing song tonight"
  448. DATA "Jingle bells, jingle bells,"
  449. DATA "jingle all the way!"
  450. DATA "O what fun it is to ride"
  451. DATA "In a one-horse open sleigh"
  452. DATA "A day or two ago,"
  453. DATA "I thought I'd take a ride,"
  454. DATA "And soon Miss Fanny Bright"
  455. DATA "Was seated by my side;"
  456. DATA "The horse was lean and lank;"
  457. DATA "Misfortune seemed his lot;"
  458. DATA "He got into a drifted bank,"
  459. DATA "And we, we got upsot."
  460. DATA "Jingle Bells, Jingle Bells,"
  461. DATA "Jingle all the way!"
  462. DATA "What fun it is to ride"
  463. DATA "In a one-horse open sleigh."
  464. DATA "A day or two ago,"
  465. DATA "the story I must tell"
  466. DATA "I went out on the snow"
  467. DATA "And on my back I fell;"
  468. DATA "A gent was riding by"
  469. DATA "In a one-horse open sleigh,"
  470. DATA "He laughed as there"
  471. DATA "I sprawling lie,"
  472. DATA "But quickly drove away."
  473. DATA "Jingle Bells, Jingle Bells,"
  474. DATA "Jingle all the way!"
  475. DATA "What fun it is to ride"
  476. DATA "In a one-horse open sleigh."
  477. DATA "Now the ground is white"
  478. DATA "Go it while you're young,"
  479. DATA "Take the girls tonight"
  480. DATA "And sing this sleighing song;"
  481. DATA "Just get a bob-tailed bay"
  482. DATA "two-forty as his speed"
  483. DATA "Hitch him to an open sleigh"
  484. DATA "And crack! you'll take the lead."
  485. DATA "Jingle Bells, Jingle Bells,"
  486. DATA "Jingle all the way!"
  487. DATA "What fun it is to ride"
  488. DATA "In a one-horse open sleigh."
  489. DATA "**** Joy To The World ****"
  490. DATA "Joy to the world! The Lord is come."
  491. DATA "Let earth receive her King"
  492. DATA "Let every heart"
  493. DATA "Prepare Him room"
  494. DATA "And Saints and angels sing"
  495. DATA "And Saints and angels sing"
  496. DATA "And Saints and Saints and angels sing"
  497. DATA "Joy to the world, the Saviour reigns"
  498. DATA "Let Saints their songs employ"
  499. DATA "While fields and floods"
  500. DATA "rocks, hills and plains"
  501. DATA "Repeat the sounding joy"
  502. DATA "Repeat the sounding joy"
  503. DATA "Repeat, Repeat, the sounding joy"
  504. DATA "Joy to the world with truth and grace"
  505. DATA "And makes the nations prove"
  506. DATA "The glories of His righteousness"
  507. DATA "And wonders of His love"
  508. DATA "And wonders of His love"
  509. DATA "And wonders and wonders of His love"
  510. DATA "No more will sin and sorrow grow,"
  511. DATA "Nor thorns infest the ground;"
  512. DATA "He'll come and make the blessings flow"
  513. DATA "Far as the curse was found,"
  514. DATA "Far as the curse was found,"
  515. DATA "Far as, far as the curse was found."
  516. DATA "He rules the world with truth and grace,"
  517. DATA "And gives to nations proof"
  518. DATA "The glories of His righteousness,"
  519. DATA "And wonders of His love;"
  520. DATA "And wonders of His love;"
  521. DATA "And wonders, wonders of His love."
  522. DATA "Rejoice! Rejoice in the Most High,"
  523. DATA "While Israel spreads abroad"
  524. DATA "Like stars that glitter in the sky,"
  525. DATA "And ever worship God,"
  526. DATA "And ever worship God,"
  527. DATA "And ever, and ever worship God."
  528. DATA "**** O Come, All Ye Faithful ****"
  529. DATA "O come, all ye faithful,"
  530. DATA "Joyful and triumphant,"
  531. DATA "O come ye,"
  532. DATA "O come ye to Bethlehem;"
  533. DATA "Come and behold Him"
  534. DATA "Born the King of angels;"
  535. DATA "O come, let us adore Him,"
  536. DATA "O come, let us adore Him,"
  537. DATA "O come, let us adore Him,"
  538. DATA "Christ, the Lord."
  539. DATA "Sing, choirs of angels,"
  540. DATA "Sing in exultation,"
  541. DATA "Sing, all ye citizens"
  542. DATA "of heaven above;"
  543. DATA "Glory to God,"
  544. DATA "Glory in the highest;"
  545. DATA "O come, let us adore Him,"
  546. DATA "O come, let us adore Him,"
  547. DATA "O come, let us adore Him,"
  548. DATA "Christ, the Lord."
  549. DATA "Yea, Lord, we greet Thee,"
  550. DATA "Born this happy morning,"
  551. DATA "Jesus, to Thee be"
  552. DATA "all glory given;"
  553. DATA "Son of the Father,"
  554. DATA "Now in flesh appearing;"
  555. DATA "O come, let us adore Him,"
  556. DATA "O come, let us adore Him,"
  557. DATA "O come, let us adore Him,"
  558. DATA "Christ, the Lord."
  559. DATA "**** O Holy Night ****"
  560. DATA "O holy night,"
  561. DATA "the stars are brightly shining;"
  562. DATA "It is the night of"
  563. DATA "our dear Savior's birth!"
  564. DATA "Long lay the world"
  565. DATA "in sin and error pining,"
  566. DATA "Till He appeared"
  567. DATA "and the soul felt its worth."
  568. DATA "A thrill of hope,"
  569. DATA "the weary world rejoices,"
  570. DATA "For yonder breaks"
  571. DATA "a new and glorious morn."
  572. DATA "Fall on your knees,"
  573. DATA "O hear the angel voices!"
  574. DATA "O night divine,"
  575. DATA "O night when Christ was born!"
  576. DATA "O night divine, O night,"
  577. DATA "O night divine!"
  578. DATA "Led by the light of Faith"
  579. DATA "serenely beaming,"
  580. DATA "With glowing hearts"
  581. DATA "by His cradle we stand."
  582. DATA "So led by light of a star"
  583. DATA "sweetly gleaming,"
  584. DATA "Here came the wise men"
  585. DATA "from Orient land."
  586. DATA "The King of Kings lay thus"
  587. DATA "in lowly manger,"
  588. DATA "In all our trials"
  589. DATA "born to be our Friend!"
  590. DATA "He knows our need,"
  591. DATA "To our weakness no stranger;"
  592. DATA "Behold your King!"
  593. DATA "Before the lowly bend!"
  594. DATA "Behold your King! your King!"
  595. DATA "before Him bend."
  596. DATA "Truly He taught us"
  597. DATA "to love one another;"
  598. DATA "His law is love and"
  599. DATA "His gospel is peace."
  600. DATA "Chains shall He break"
  601. DATA "for the slave is our brother"
  602. DATA "And in His name"
  603. DATA "all oppression shall cease."
  604. DATA "Sweet hymns of joy in"
  605. DATA "grateful chorus raise we,"
  606. DATA "Let all within us"
  607. DATA "praise His holy name!"
  608. DATA "Christ is the Lord,"
  609. DATA "Oh praise His name forever,"
  610. DATA "His pow'r and glory evermore proclaim"
  611. DATA "His pow'r and glory"
  612. DATA "evermore proclaim."
  613. DATA "**** O Little Town of Bethlehem ****"
  614. DATA "O little town of Bethlehem,"
  615. DATA "How still we see thee lie."
  616. DATA "Above thy deep and dreamless sleep"
  617. DATA "The silent stars go by;"
  618. DATA "Yet in thy dark streets shineth"
  619. DATA "The everlasting Light;"
  620. DATA "The hopes and fears of all the years"
  621. DATA "Are met in thee tonight."
  622. DATA "For Christ is born of Mary,"
  623. DATA "And, gathered all above"
  624. DATA "While mortals sleep, the angels keep"
  625. DATA "Their watch of wondering love."
  626. DATA "O morning stars, together"
  627. DATA "Proclaim the holy birth."
  628. DATA "And praises sing to God the King."
  629. DATA "And peace to men on earth."
  630. DATA "How silently, how silently"
  631. DATA "The wondrous gift is given!"
  632. DATA "So God imparts to human hearts"
  633. DATA "The blessings of His heaven."
  634. DATA "No ear may hear His coming;"
  635. DATA "But in this world of sin,"
  636. DATA "Where meek souls will receive Him,"
  637. DATA "still The dear Christ enters in."
  638. DATA "Where children, pure and happy,"
  639. DATA "Pray to the Blessed Child;"
  640. DATA "Where misery cries out to thee,"
  641. DATA "Son of the Mother mild;"
  642. DATA "Where charity stands watching,"
  643. DATA "And faith holds wide the door,"
  644. DATA "The dark night wakes, the glory breaks,"
  645. DATA "and Christmas comes once more."
  646. DATA "O Holy Child of Bethlehem,"
  647. DATA "Descend to us, we pray;"
  648. DATA "Cast out our sin and enter in;"
  649. DATA "Be born in us today!"
  650. DATA "We hear the Christmas angels"
  651. DATA "The great glad tidings tell;"
  652. DATA "O come to us, abide with us,"
  653. DATA "Our Lord Emmanuel!"
  654. DATA "**** Rudolph The Red-Nosed Reindeer ****"
  655. DATA "You know Dasher and Dancer"
  656. DATA "And Prancer and Vixen,"
  657. DATA "Comet and Cupid"
  658. DATA "And Donner and Blitzen."
  659. DATA "But do you recall"
  660. DATA "The most famous reindeer of all?"
  661. DATA "Rudolph the red-nosed reindeer"
  662. DATA "(reindeer)"
  663. DATA "Had a very shiny nose"
  664. DATA "(like a light bulb)"
  665. DATA "And if you ever saw it"
  666. DATA "(saw it)"
  667. DATA "You would even say it glows"
  668. DATA "(like a flash light)"
  669. DATA "All of the other reindeer"
  670. DATA "(reindeer)"
  671. DATA "Used to laugh and call him names"
  672. DATA "(like Pinochio)"
  673. DATA "They never let poor Rudolph"
  674. DATA "(Rudolph)"
  675. DATA "Play in any reindeer games"
  676. DATA "(like Monopoly)"
  677. DATA "Then one foggy Christmas Eve"
  678. DATA "Santa came to say"
  679. DATA "(Ho Ho Ho)"
  680. DATA "Rudolph with your nose so bright"
  681. DATA "Won't you guide my sleigh tonight?"
  682. DATA "Then all the reindeer loved him"
  683. DATA "(loved him)"
  684. DATA "And they shouted out with glee"
  685. DATA "(yippee)"
  686. DATA "'Rudolph the red-nosed reindeer"
  687. DATA "(reindeer)"
  688. DATA "You'll go down in history!'"
  689. DATA "(like Columbus)"
  690. DATA "**** Silent Night ****"
  691. DATA "Silent night, holy night!"
  692. DATA "All is calm, All is bright"
  693. DATA "Round yon Virgin, Mother and Child"
  694. DATA "Holy Infant so Tender and mild,"
  695. DATA "Sleep in heavenly peace,"
  696. DATA "Sleep in heavenly peace."
  697. DATA "Silent night, holy night!"
  698. DATA "Shepherds quake at the sight!"
  699. DATA "Glories stream from heaven afar;"
  700. DATA "Heavenly hosts sing Al-le-lu-ia!"
  701. DATA "Christ the Saviour is born!"
  702. DATA "Christ the Saviour is born!"
  703. DATA "Silent night, holy night!"
  704. DATA "Wondrous star, lend thy light!"
  705. DATA "With the angels let us sing"
  706. DATA "Alleluia to our King!"
  707. DATA "Christ the Saviour is here,"
  708. DATA "Jesus the Saviour is here!"
  709. DATA "Silent night, Holy night!"
  710. DATA "Son of God, love's pure light"
  711. DATA "Radiant beams from Thy holy face,"
  712. DATA "with the dawn of redeeming grace,"
  713. DATA "Jesus Lord at thy birth;"
  714. DATA "Jesus Lord at thy birth."
  715. DATA "**** The First Noel ****"
  716. DATA "The first Noel the angels did say"
  717. DATA "Was to certain poor shepherds"
  718. DATA "in fields as they lay,"
  719. DATA "In fields where they lay"
  720. DATA "keeping their sheep"
  721. DATA "On a cold winter's night"
  722. DATA "that was so deep."
  723. DATA "Noel Noel Noel Noel!"
  724. DATA "Born is the King of Israel!"
  725. DATA "They looked up and saw a star"
  726. DATA "Shining in the East beyond them far,"
  727. DATA "And to the earth it gave great light,"
  728. DATA "And so it continued both day and night."
  729. DATA "Noel Noel Noel Noel!"
  730. DATA "Born is the King of Israel!"
  731. DATA "And by the light of that same star"
  732. DATA "Three wise men came from country far,"
  733. DATA "To seek for a King was their intent"
  734. DATA "And to follow the star"
  735. DATA "wherever it went."
  736. DATA "Noel Noel Noel Noel!"
  737. DATA "Born is the King of Israel!"
  738. DATA "This star drew nigh to the northwest"
  739. DATA "Over Bethlehem it took its rest,"
  740. DATA "And there it did both stop and stay"
  741. DATA "Right over the place where Jesus lay."
  742. DATA "Noel Noel Noel Noel!"
  743. DATA "Born is the King of Israel!"
  744. DATA "Then did they know assuredly"
  745. DATA "Within that house the King did lie:"
  746. DATA "One entered in then for to see,"
  747. DATA "And found the Babe in poverty:"
  748. DATA "Noel Noel Noel Noel!"
  749. DATA "Born is the King of Israel!"
  750. DATA "Then entered in those wise men three"
  751. DATA "Full reverently upon their knee,"
  752. DATA "And offered there in His presence"
  753. DATA "Their gold, and myrrh and frankincense."
  754. DATA "Noel Noel Noel Noel!"
  755. DATA "Born is the King of Israel!"
  756. DATA "Then let us all with one accord"
  757. DATA "Sing praises to our heavenly Lord,"
  758. DATA "That hath made heaven"
  759. DATA "and earth of naught"
  760. DATA "And with His blood"
  761. DATA "mankind hath bought."
  762. DATA "Noel Noel Noel Noel!"
  763. DATA "Born is the King of Israel!"
  764. DATA "**** The Shepherd's Carol (round) ****"
  765. DATA "Mary, Mary hush, see the Child"
  766. DATA "Joseph, Joseph, look see how mild"
  767. DATA "This is Jesus; this is our King"
  768. DATA "This is our Savior, his praises we sing."
  769. DATA "**** The Twelve Days of Christmas ****"
  770. DATA "On the first day of Christmas"
  771. DATA "my true love sent to me:"
  772. DATA "A partridge in a pear tree."
  773. DATA "On the second day of Christmas"
  774. DATA "my true love sent to me:"
  775. DATA "Two turtle doves"
  776. DATA "And a Partridge in a pear tree."
  777. DATA "On the third day of Christmas"
  778. DATA "my true love sent to me:"
  779. DATA "Three French Hens,"
  780. DATA "Two turtle doves"
  781. DATA "And a Partridge in a pear tree."
  782. DATA "On the fourth day of Christmas"
  783. DATA "my true love sent to me:"
  784. DATA "Four calling birds,"
  785. DATA "Three French Hens,"
  786. DATA "Two turtle doves"
  787. DATA "And a Partridge in a pear tree."
  788. DATA "On the fifth day of Christmas"
  789. DATA "my true love sent to me:"
  790. DATA "Five golden rings,"
  791. DATA "Four calling birds,"
  792. DATA "Three French Hens,"
  793. DATA "Two turtle doves"
  794. DATA "And a Partridge in a pear tree."
  795. DATA "On the sixth day of Christmas"
  796. DATA "my true love sent to me:"
  797. DATA "Six geese a laying,"
  798. DATA "Five golden rings,"
  799. DATA "Four calling birds,"
  800. DATA "Three French Hens,"
  801. DATA "Two turtle doves"
  802. DATA "And a Partridge in a pear tree."
  803. DATA "On the seventh day of Christmas"
  804. DATA "my true love sent to me:"
  805. DATA "Seven swans a swimming,"
  806. DATA "Six geese a laying,"
  807. DATA "Five golden rings,"
  808. DATA "Four calling birds,"
  809. DATA "Three French Hens,"
  810. DATA "Two turtle doves"
  811. DATA "And a Partridge in a pear tree."
  812. DATA "On the eighth day of Christmas"
  813. DATA "my true love sent to me:"
  814. DATA "Eight maids a milking,"
  815. DATA "Seven swans a swimming,"
  816. DATA "Six geese a laying,"
  817. DATA "Five golden rings,"
  818. DATA "Four calling birds,"
  819. DATA "Three French Hens,"
  820. DATA "Two turtle doves"
  821. DATA "And a Partridge in a pear tree."
  822. DATA "On the ninth day of Christmas"
  823. DATA "my true love sent to me:"
  824. DATA "Nine ladies dancing,"
  825. DATA "Eight maids a milking,"
  826. DATA "Seven swans a swimming,"
  827. DATA "Six geese a laying,"
  828. DATA "Five golden rings,"
  829. DATA "Four calling birds,"
  830. DATA "Three French Hens,"
  831. DATA "Two turtle doves"
  832. DATA "And a Partridge in a pear tree."
  833. DATA "On the tenth day of Christmas"
  834. DATA "my true love sent to me:"
  835. DATA "Ten lords a leaping,"
  836. DATA "Nine ladies dancing,"
  837. DATA "Eight maids a milking,"
  838. DATA "Seven swans a swimming,"
  839. DATA "Six geese a laying,"
  840. DATA "Five golden rings,"
  841. DATA "Four calling birds,"
  842. DATA "Three French Hens,"
  843. DATA "Two turtle doves"
  844. DATA "And a Partridge in a pear tree."
  845. DATA "On the eleventh day of Christmas"
  846. DATA "my true love sent to me:"
  847. DATA "Eleven pipers piping,"
  848. DATA "Ten lords a leaping,"
  849. DATA "Nine ladies dancing,"
  850. DATA "Eight maids a milking,"
  851. DATA "Seven swans a swimming,"
  852. DATA "Six geese a laying,"
  853. DATA "Five golden rings,"
  854. DATA "Four calling birds,"
  855. DATA "Three French Hens,"
  856. DATA "Two turtle doves"
  857. DATA "And a Partridge in a pear tree."
  858. DATA "On the twelfth day of Christmas"
  859. DATA "my true love sent to me:"
  860. DATA "Twelve drummers drumming,"
  861. DATA "Eleven pipers piping,"
  862. DATA "Ten lords a leaping,"
  863. DATA "Nine ladies dancing,"
  864. DATA "Eight maids a milking,"
  865. DATA "Seven swans a swimming,"
  866. DATA "Six geese a laying,"
  867. DATA "Five golden rings,"
  868. DATA "Four calling birds,"
  869. DATA "Three French Hens,"
  870. DATA "Two turtle doves"
  871. DATA "And a Partridge in a pear tree."
  872. DATA "**** Up On the Housetop ****"
  873. DATA "Up on the housetop"
  874. DATA "reindeer pause,"
  875. DATA "Out jumps good old Santa Claus."
  876. DATA "Down thru' the chimney"
  877. DATA "with lots of toys,"
  878. DATA "All for the little ones,"
  879. DATA "Christmas joys."
  880. DATA "Ho, ho, ho!"
  881. DATA "Who wouldn't go!"
  882. DATA "Ho, ho, ho!"
  883. DATA "Who wouldn't go!"
  884. DATA "Up on the housetop,"
  885. DATA "click, click, click,"
  886. DATA "Down thru' the chimney"
  887. DATA "with good Saint Nick."
  888. DATA "First comes the stocking"
  889. DATA "of little Nell,"
  890. DATA "Oh, dear Santa"
  891. DATA "fill it well;"
  892. DATA "Give her a dolly"
  893. DATA "that laughs and cries"
  894. DATA "One that will open"
  895. DATA "and shut her eyes."
  896. DATA "Ho, ho, ho!"
  897. DATA "Who wouldn't go!"
  898. DATA "Ho, ho, ho!"
  899. DATA "Who wouldn't go!"
  900. DATA "Up on the housetop,"
  901. DATA "click, click, click,"
  902. DATA "Down thru' the chimney"
  903. DATA "with good Saint Nick."
  904. DATA "Next comes the stocking"
  905. DATA "of little Will,"
  906. DATA "Oh just see"
  907. DATA "what a glorious fill"
  908. DATA "Here is a hammer"
  909. DATA "and lots of tacks,"
  910. DATA "Also a ball"
  911. DATA "and a whip that cracks."
  912. DATA "Ho, ho, ho!"
  913. DATA "Who wouldn't go!"
  914. DATA "Ho, ho, ho!"
  915. DATA "Who wouldn't go!"
  916. DATA "Up on the housetop,"
  917. DATA "click, click, click,"
  918. DATA "Down thru' the chimney"
  919. DATA "with good Saint Nick."
  920. DATA "**** We Three Kings ****"
  921. DATA "[all sing]"
  922. DATA "We three kings of orient are,"
  923. DATA "bearing gifts we traverse afar"
  924. DATA "Field and fountain,"
  925. DATA "moor and mountain,"
  926. DATA "following yonder star."
  927. DATA "O star of wonder, star of night,"
  928. DATA "star with royal beauty bright."
  929. DATA "Westward leading, still proceeding,"
  930. DATA "Guide us to thy perfect light."
  931. DATA "[Melchior sings]"
  932. DATA "Born a King on Bethlehem's plain,"
  933. DATA "Gold I bring to crown Him again"
  934. DATA "King for ever, ceasing never"
  935. DATA "over us all to reign."
  936. DATA "[all sing]"
  937. DATA "O star of wonder, star of night,"
  938. DATA "star with royal beauty bright."
  939. DATA "Westward leading, still proceeding,"
  940. DATA "Guide us to thy perfect light."
  941. DATA "[Casper sings]"
  942. DATA "Frankincense to offer have I,"
  943. DATA "incense owns a Deity nigh"
  944. DATA "Prayer and praising, all men raising,"
  945. DATA "Worship Him, God most high."
  946. DATA "[all sing]"
  947. DATA "O star of wonder, star of night,"
  948. DATA "star with royal beauty bright."
  949. DATA "Westward leading, still proceeding,"
  950. DATA "Guide us to thy perfect light."
  951. DATA "[Balthazar sings]"
  952. DATA "Myrrh is mine,"
  953. DATA "its bitter perfume breathes"
  954. DATA "a life of gathering gloom."
  955. DATA "Sorrowing, sighing, bleeding, dying,"
  956. DATA "sealed in the stone cold tomb."
  957. DATA "[all sing]"
  958. DATA "O star of wonder, star of night,"
  959. DATA "star with royal beauty bright."
  960. DATA "Westward leading, still proceeding,"
  961. DATA "Guide us to thy perfect light."
  962. DATA "Glorious now behold Him arise,"
  963. DATA "King and God and Sacrifice!"
  964. DATA "Al-le-lu-ia, al-le-lu-ia,"
  965. DATA "heaven to earth replies."
  966. DATA "O star of wonder, star of night,"
  967. DATA "star with royal beauty bright."
  968. DATA "Westward leading, still proceeding,"
  969. DATA "Guide us to thy perfect light."
  970. DATA "**** We Wish You A Merry Christmas ****"
  971. DATA "We wish you a merry Christmas"
  972. DATA "We wish you a merry Christmas"
  973. DATA "We wish you a merry Christmas"
  974. DATA "And a happy New Year."
  975. DATA "Glad tidings we bring"
  976. DATA "To you and your kin;"
  977. DATA "Glad tidings for Christmas"
  978. DATA "And a happy New Year!"
  979. DATA "We want some figgy pudding"
  980. DATA "We want some figgy pudding"
  981. DATA "We want some figgy pudding"
  982. DATA "Please bring it right here!"
  983. DATA "Glad tidings we bring"
  984. DATA "To you and your kin;"
  985. DATA "Glad tidings for Christmas"
  986. DATA "And a happy New Year!"
  987. DATA "We won't go until we get some"
  988. DATA "We won't go until we get some"
  989. DATA "We won't go until we get some"
  990. DATA "So bring it out here!"
  991. DATA "Glad tidings we bring"
  992. DATA "To you and your kin;"
  993. DATA "Glad tidings for Christmas"
  994. DATA "And a happy New Year!"
  995. DATA "We wish you a Merry Christmas"
  996. DATA "We wish you a Merry Christmas"
  997. DATA "We wish you a Merry Christmas"
  998. DATA "And a happy New Year."
  999. DATA "Glad tidings we bring"
  1000. DATA "To you and your kin;"
  1001. DATA "Glad tidings for Christmas"
  1002. DATA "And a happy New Year!"
  1003. DATA "**** What Child Is This? ****"
  1004. DATA "What Child is this, who laid to rest,"
  1005. DATA "On Mary's lap is sleeping?"
  1006. DATA "Whom angels greet with anthems sweet"
  1007. DATA "While shepherds watch are keeping?"
  1008. DATA "This, this is Christ the King"
  1009. DATA "Whom shepherds guard and angels sing."
  1010. DATA "Haste, haste to bring Him laud,"
  1011. DATA "The Babe, the Son of Mary."
  1012. DATA "Why lies He in such mean estate"
  1013. DATA "Where ox and ass are feeding?"
  1014. DATA "Good Christian, fear: for sinners here,"
  1015. DATA "The silent Word is pleading."
  1016. DATA "This, this is Christ the King"
  1017. DATA "Whom shepherds guard and angels sing."
  1018. DATA "Haste, haste to bring Him laud,"
  1019. DATA "The Babe, the Son of Mary."
  1020. DATA "Nails, spear, shall pierce Him through,"
  1021. DATA "The Cross be borne, for me, for you:"
  1022. DATA "Hail, hail, the Word made flesh,"
  1023. DATA "The Babe, the Son of Mary!"
  1024. DATA "This, this is Christ the King"
  1025. DATA "Whom shepherds guard and angels sing."
  1026. DATA "Haste, haste to bring Him laud,"
  1027. DATA "The Babe, the Son of Mary."
  1028. DATA "So bring Him incense, gold and myrrh;"
  1029. DATA "Come peasant, king to own Him."
  1030. DATA "The King of Kings salvation brings;"
  1031. DATA "Let loving hearts enthrone Him."
  1032. DATA "This, this is Christ the King"
  1033. DATA "Whom shepherds guard and angels sing."
  1034. DATA "Haste, haste to bring Him laud,"
  1035. DATA "The Babe, the Son of Mary."
  1036. DATA "Raise, raise, the song on high,"
  1037. DATA "The Virgin sings her lullaby:"
  1038. DATA "Joy joy for Christ is born,"
  1039. DATA "The Babe, the Son of Mary!"
  1040. DATA "This, this is Christ the King"
  1041. DATA "Whom shepherds guard and angels sing."
  1042. DATA "Haste, haste to bring Him laud,"
  1043. DATA "The Babe, the Son of Mary."
  1044. DATA "**** While Shepherds Watched Their Flocks ****"
  1045. DATA "While shepherds watched their flocks by night,"
  1046. DATA "All seated on the ground,"
  1047. DATA "The angel of the Lord came down,"
  1048. DATA "And glory shone around."
  1049. DATA "'Fear not,' said he, for mighty dread"
  1050. DATA "Had seized their troubled mind,"
  1051. DATA "'Glad tidings of great joy I bring"
  1052. DATA "To you and all mankind.'"
  1053. DATA "'To you, in David's town this day,"
  1054. DATA "Is born of David's line"
  1055. DATA "The Savior who is Christ the Lord,"
  1056. DATA "And this shall be the sign:"
  1057. DATA "The heavenly Babe you there shall find"
  1058. DATA "To human view displayed,"
  1059. DATA "All meanly wrapped in swathing bands,"
  1060. DATA "And in a manger laid.'"
  1061. DATA "Thus spake the seraph, and forthwith"
  1062. DATA "Appeared a shining throng"
  1063. DATA "Of angels praising God and thus"
  1064. DATA "Addressed their joyful song:"
  1065. DATA "'All glory be to God on high"
  1066. DATA "And on the earth be peace,"
  1067. DATA "Goodwill henceforth from heaven to men"
  1068. DATA "Begin and never cease.'"
  1069. DATA "**** With Wondering Awe ****"
  1070. DATA "With wondering awe the wise men saw"
  1071. DATA "The star in heaven springing,"
  1072. DATA "And with delight, in peaceful night,"
  1073. DATA "They heard the angel singing:"
  1074. DATA "Hosanna, hosanna, hosanna to His name!"
  1075. DATA "By light of star they traveled far"
  1076. DATA "To seek the lowly manger,"
  1077. DATA "A humble bed wherein was laid"
  1078. DATA "The wondrous little Stranger."
  1079. DATA "Hosanna, hosanna, hosanna to His name!"
  1080. DATA "And still is found, the world around,"
  1081. DATA "The old and hallowed story,"
  1082. DATA "And still is sung in every tongue"
  1083. DATA "The angels' song of glory:"
  1084. DATA "Hosanna, hosanna, hosanna to His name!"
  1085. DATA "The heavenly star its rays afar"
  1086. DATA "On every land is throwing,"
  1087. DATA "And shall not cease till holy peace"
  1088. DATA "In all the earth is growing."
  1089. DATA "Hosanna, hosanna, hosanna to His name!"
  1090. DATA "EOD"
  1091.  

Less than 30 songs here, but the format should be simple enough that anyone can add the lyrics to whatever they like to this listing without any problems.  View them on your screen, or print them to a file to carry on your phone/ipad as you go and serenade your neighbors for X-Mas.  :D
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Dav on December 10, 2020, 01:19:11 pm
There's some really cool stuff posted here. It made me throw something together.  Here's an old school animated Christmas card.  A little snow, a little tree, a little present, a little Santa, a little music.  Merry Christmas!

- Dav

Code: QB64: [Select]
  1. '=================
  2. 'CHRISTMAS2020.bas
  3. '=================
  4. 'Christmas card to the QB64 community.
  5. 'Coded by Dav, DEC/2020
  6.  
  7. 'Shows a liite snow, santa, tree, present, animation, music.
  8. 'Merry Christmas.
  9.  
  10. SCREEN _NEWIMAGE(868, 540, 32)
  11.  
  12. DIM SHARED wht& 'subs use this...
  13. wht& = _RGB(255, 255, 255) 'white color
  14.  
  15. ON TIMER(.5) GOSUB ANIMATE
  16.  
  17.  
  18.  
  19. '======  draw white color outlines first ...
  20.  
  21. 'Draw tree star
  22. CLINE ("199129209145214126234126219113232095211101201083196102176102192117180134199129")
  23.  
  24. 'Draw the tree
  25. CLINE ("199129175168190168156210168210142237160237129276141276110312132312102348120348")
  26. CLINE ("120348093385108394136399172402242402283399316393327387300348312348284311309311")
  27. CLINE ("309311276275289275258236272236246209259209224168239168214126")
  28. CLINE ("173402181435234435242402")
  29.  
  30. 'Draw fireplace
  31. CLINE ("613328613275618272618268613269613215607209612206613199")
  32. CLINE ("467345489346493206529188582188627204627344649344")
  33. CLINE ("507327506276503274506270505216514207513196")
  34. CLINE ("448340418358417364692364692359669342")
  35. CLINE ("490345508328613328626345")
  36. LINE (422, 105)-(697, 166), wht&, B: LINE (449, 166)-(466, 344), wht&, B
  37. LINE (648, 166)-(669, 345), wht&, B: LINE (481, 0)-(481, 104), wht&
  38. LINE (631, 0)-(631, 104), wht&
  39.  
  40. 'draw santa
  41. CLINE ("514208540214560217583215603211611207613199")
  42. CLINE ("524210524252539257561218580254594251598230595213")
  43. CLINE ("582254591271591275589275590280593284599282598278606278613274")
  44. CLINE ("539258529275529278531280530283523284522280514282506276")
  45. CLINE ("529189556195569194587190")
  46. CLINE ("594251598270613269")
  47. CLINE ("526253523272506270")
  48.  
  49. 'draw window
  50. CLINE ("000104157104157000"): CLINE ("000093146093146000")
  51. CLINE ("035093035028146028"): CLINE ("028093028028000028")
  52. CLINE ("000022028022028000"): CLINE ("035000035022146022")
  53.  
  54. 'draw present
  55. CLINE ("412428388416375425383446402446425434459438452407422425421422412428")
  56. CLINE ("377432353433352451421470488451487435420448403446391446")
  57. CLINE ("419448422469420515359492358452"): CLINE ("420437447444470439459438")
  58. CLINE ("470439469456454460455442"): CLINE ("386433395430404433")
  59. CLINE ("458433487436467440")
  60. LINE (412, 428)-(416, 438), wht&: LINE (421, 424)-(424, 434), wht&
  61. LINE (427, 430)-(443, 423), wht&: LINE (352, 434)-(380, 440), wht&
  62. LINE (373, 440)-(372, 456), wht&: LINE (392, 446)-(392, 461), wht&
  63. LINE (450, 461)-(450, 504), wht&: LINE (463, 458)-(463, 499), wht&
  64. LINE (420, 516)-(482, 491), wht&: LINE (482, 491)-(481, 452), wht&
  65. LINE (378, 458)-(378, 500), wht&: LINE (395, 462)-(394, 505), wht&
  66.  
  67. 'draw walls (left side)
  68. LINE (0, 190)-(173, 190), wht&: LINE (244, 190)-(449, 190), wht&
  69. LINE (0, 206)-(159, 206), wht&: LINE (257, 206)-(449, 206), wht&
  70. LINE (0, 338)-(109, 338), wht&: LINE (305, 338)-(449, 338), wht&
  71.  
  72. 'draw walls (right side)
  73. CLINE ("669192805192867229"): CLINE ("669209805209867244")
  74. CLINE ("669341806341867390"): LINE (805, 0)-(805, 341), wht&
  75.  
  76.  
  77. '======= Paint in the colors....
  78.  
  79. CPAINT ("371435362445366469424443407455408491441454438484371435466436478446473471"), _RGB(31, 255, 31)
  80. CPAINT ("400436420430440430380450446440460450385475455475"), _RGB(255, 0, 0)
  81. CPAINT ("750260380240060240660222543118455183"), _RGB(76, 109, 138)
  82. CPAINT ("525056638214600345153019033026"), _RGB(40, 57, 72)
  83. CPAINT ("707075499209620246297077"), _RGB(67, 87, 123)
  84. CPAINT ("569192537226582236"), _RGB(205, 4, 23)
  85. CPAINT ("515235557278603253"), _RGB(80, 120, 153)
  86. CPAINT ("786202092198322199"), _RGB(83, 120, 153)
  87. CPAINT ("827217842226"), _RGB(74, 107, 136)
  88. PAINT (207, 417), _RGB(176, 65, 13), wht&
  89. PAINT (204, 113), _RGB(255, 255, 69), wht&
  90. PAINT (204, 239), _RGB(0, 94, 0), wht&
  91. PAINT (650, 470), _RGB(28, 40, 50), wht&
  92. PAINT (840, 120), _RGB(56, 80, 102), wht&
  93. PAINT (842, 285), _RGB(62, 89, 114), wht&
  94. PAINT (567, 206), wht&, wht&
  95.  
  96. 'draw santas thought box
  97. LINE (657, 20)-(790, 70), wht&, BF
  98. LINE (637, 100)-(680, 70), wht&
  99. LINE (637, 100)-(734, 70), wht&
  100. PAINT (680, 77), wht&, wht&
  101. COLOR _RGB(0, 0, 0)
  102. _PRINTSTRING (662, 27), "I KNEW I ate"
  103. _PRINTSTRING (662, 45), "too much turkey"
  104.  
  105. '=====================================================
  106.  
  107.  
  108.  
  109. 'Play We wish you a Merry Christmas song...
  110. Music$ = "mbt160o2g4o3c4c8d8c8o2b8a4a4a4o3d4d8e8d8c8o2b4g4g4o3e4e8f8"
  111. Music$ = Music$ + "e8d8c4o2a4g8g8a4o3d4o2b4o3c2o2g4o3c4c4c4o2b2b4o3"
  112. Music$ = Music$ + "c4o2b4a4g2o3d4e4d4c4o3g4o2g4g8g8a4o3d4o2b4o3c2"
  113. Music$ = Music$ + "o2g4o3c4c8d8c8o2b8a4a4a4o3d4d8e8d8c8o2b4g4g4"
  114. Music$ = Music$ + "o3e4e8f8e8d8c4o2a4g8g8a4o3d4o2b4o3c2"
  115. PLAY Music$
  116.  
  117. 'Show until keypress
  118.  
  119.  
  120.  
  121. '======================================================================
  122.  
  123.  
  124.  
  125. '======
  126. ANIMATE:
  127. '======
  128.  
  129. 'show a little snow in window frames
  130. SNOW 0, 0, 27, 20 'top left frame
  131. SNOW 36, 0, 145, 20 'top right frame
  132. SNOW 0, 29, 27, 90 'bottom left
  133. SNOW 36, 29, 145, 91 'bottom right
  134.  
  135. 'Draw/color ornaments
  136. CCIRCLE ("198157051981871123019805191224062302230717126011")
  137. CCIRCLE ("217250082562550515430209195295122282900425427806")
  138. CCIRCLE ("256303051493390718033008209321092433451528032906")
  139. CCIRCLE ("1543751319136804230383062863630927838707")
  140.  
  141. 'blink a message
  142. IF INT(RND * 2) + 1 = 1 THEN COLOR _RGB(0, 0, 0) ELSE COLOR _RGB(255, 255, 255)
  143.  
  144. _PRINTSTRING (450, 128), "M E R R Y  C H R I S T M A S"
  145.  
  146.  
  147.  
  148. '==========================================================================
  149.  
  150. SUB CLINE (a$)
  151.     'draws continuious white line based on string of x/y cordinates
  152.     '(yes, I could have used DRAW instead, but wanted to roll my own...)
  153.     'set first line draw position
  154.     LINE (VAL(MID$(a$, 1, 3)), VAL(MID$(a$, 4, 3)))-(VAL(MID$(a$, 7, 3)), VAL(MID$(a$, 10, 3))), wht&
  155.     'continue based on last line position
  156.     FOR d = 13 TO LEN(a$) STEP 6
  157.         LINE -(VAL(MID$(a$, d, 3)), VAL(MID$(a$, d + 3, 3))), wht&
  158.     NEXT
  159.  
  160. SUB CPAINT (a$, clr&)
  161.     'paints string of cordinates with color, stops at wht& color
  162.     FOR t = 1 TO LEN(a$) STEP 6
  163.         PAINT (VAL(MID$(a$, t, 3)), VAL(MID$(a$, t + 3, 3))), clr&, wht&
  164.     NEXT
  165.  
  166. SUB CCIRCLE (a$)
  167.     'Draw circles based on string of x/y/r data, colors it too
  168.     FOR t = 1 TO LEN(a$) STEP 8
  169.         CIRCLE (VAL(MID$(a$, t, 3)), VAL(MID$(a$, t + 3, 3))), VAL(MID$(a$, t + 6, 2)), wht&
  170.         clr& = INT(RND * 5) + 1 'pick from 5 random colors
  171.         IF clr& = 1 THEN clr& = _RGB(128, 255, 255) 'almost white
  172.         IF clr& = 2 THEN clr& = _RGB(255, 255, 69) 'yellow
  173.         IF clr& = 3 THEN clr& = _RGB(205, 4, 23) 'red
  174.         IF clr& = 4 THEN clr& = _RGB(31, 255, 32) 'green
  175.         IF clr& = 5 THEN clr& = _RGB(0, 31, 221) 'blue
  176.         PAINT (VAL(MID$(a$, t, 3)), VAL(MID$(a$, t + 3, 3))), clr&, wht&
  177.     NEXT
  178.  
  179. SUB SNOW (x1, y1, x2, y2)
  180.     'random snow pattern in given window
  181.     LINE (x1, y1)-(x2, y2), _RGB(0, 0, 0), BF 'snow plow
  182.     FOR x = x1 TO x2
  183.         FOR y = y1 TO y2
  184.             IF INT(RND * 200) = 1 THEN PSET (x, y), wht&
  185.         NEXT
  186.     NEXT
  187.  
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 10, 2020, 01:44:30 pm
Ahh-ha! That's cute Dav!
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: SierraKen on December 10, 2020, 02:28:55 pm
Awesome idea Steve, another way to make QB64 into a useful tool. :)

Dav, that's just incredible. You must have spent hours on that. Good job!
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Dav on December 10, 2020, 02:44:57 pm
Thanks, ya'll.  Yep, I did spend too much time on it. 

I just edited the code to add a Santa's thought box.  Forgot to add it.  Run it again to read what santa says.

- Dav
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: SierraKen on December 10, 2020, 04:34:52 pm
LOL good one. :)
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Petr on December 10, 2020, 04:47:55 pm
Very nice work, Dav!
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: SierraKen on December 10, 2020, 07:09:08 pm
I worked on the Christmas Tree Ornaments one again for most of the day today and made it much better. I learned a little bit from B+'s mod. Making many of them was easier than I thought. :) I got caught in a minor snag when the different shapes of them slowed and sped up the lyrics on the title bar a fraction so I changed it completely to TIMER. On my last one I was using the number of rotation degree on the ornament for the lyrics as well and it just doesn't work with many of them. Plus TIMER is a lot better for different types of computers. I also have it change to new ornaments every couple of seconds with completely different colors. :) The program ends when the song finishes. I also found out some more things about the PLAY command in that you only need one "MB" command in the string as well as any other command, which you put at the start of your list of PLAY commands. I changed the octave of the song to a bit more bass also. I'm pretty happy about this one. Tell me what you think, thanks.

Edit: I just remembered this this won't work right before midnight because of the TIMER, which counts up from midnight. So I made it so the program stops if it's a few seconds before midnight or less. When it ends, it tells you to please run it after midnight because of the TIMER. This certain code probably won't be tested because I very rarely stay up past midnight. But I believe it works. 

Code: QB64: [Select]
  1. 'Musical Christmas Tree Ornaments
  2. 'Made on December 10, 2020.
  3. 'by SierraKen
  4. 'Music Notes and Lyrics found here: https://www.piano-keyboard-guide.com/how-to-play-jingle-bells-easy-piano-keyboard-tutorial-for-beginners/
  5.  
  6. DIM orn AS LONG
  7. DIM ornx(30), orny(30), size(30)
  8. DIM image AS LONG, scale AS SINGLE, rotation AS SINGLE
  9.  
  10. JingleBells
  11. start:
  12. READ lyrics$
  13. IF lyrics$ = "done" THEN END
  14. _TITLE lyrics$
  15. IF orn& <> 0 THEN _FREEIMAGE orn&
  16. t = 1
  17. i& = _NEWIMAGE(800, 600, 32)
  18. ornament
  19. orn& = _COPYIMAGE(0)
  20. FOR o = 1 TO 30
  21.     ornx(o) = RND * _WIDTH
  22.     orny(o) = RND * _HEIGHT
  23.     size(o) = RND
  24.     x = ornx(o)
  25.     y = orny(o)
  26.     scale = size(o)
  27.     rotation = turn
  28.     image = orn&
  29.     RotoZoom x, y, image, scale, rotation
  30. oldt = TIMER
  31. IF oldt > 86327 THEN CLS: PRINT "Please run this program after midnight.": PRINT "It won't work right before midnight because of the TIMER it uses.": END
  32.     _LIMIT 60
  33.     FOR oo = 1 TO 30
  34.         x = ornx(oo)
  35.         y = orny(oo)
  36.         scale = size(oo)
  37.         rotation = turn
  38.         image = orn&
  39.         RotoZoom x, y, image, scale, rotation
  40.     NEXT oo
  41.     _DELAY .01
  42.     _DISPLAY
  43.     CLS
  44.     a$ = INKEY$
  45.     IF a$ = CHR$(27) THEN END
  46.     turn = turn + 1
  47.     t = TIMER - oldt
  48.     IF t > 2.37 THEN GOTO start:
  49.  
  50. song:
  51. DATA "Jingle bells, jingle bells."
  52. DATA "Jingle all the way"
  53. DATA "Oh, what fun it is to ride"
  54. DATA "In a one horse open sleigh hey"
  55. DATA "Jingle bells, jingle bells"
  56. DATA "Jingle all the way"
  57. DATA "Oh, what fun it is to ride"
  58. DATA "In a one horse open sleigh"
  59. DATA "Dashing through the snow"
  60. DATA "On a one horse open sleigh"
  61. DATA "O'er the fields we go,"
  62. DATA "Laughing all the way"
  63. DATA "Bells on bob tail ring,"
  64. DATA "making spirits bright"
  65. DATA "What fun it is to laugh and sing"
  66. DATA "A sleighing song tonight, Oh"
  67. DATA "Jingle bells, jingle bells"
  68. DATA "Jingle all the way"
  69. DATA "Oh, what fun it is to ride"
  70. DATA "In a one horse open sleigh hey"
  71. DATA "Jingle bells, jingle bells"
  72. DATA "Jingle all the way"
  73. DATA "Oh, what fun it is to ride"
  74. DATA "In a one horse open sleigh"
  75. DATA "done"
  76.  
  77. SUB JingleBells
  78.     PLAY "MB O3 L5 E E E E E E"
  79.     PLAY "E G C D E"
  80.     PLAY "F F F F F E E"
  81.     PLAY "E E E D D E D G"
  82.     PLAY "E E E E E E"
  83.     PLAY "E G C D E"
  84.     PLAY "F F F F F E E"
  85.     PLAY "E E G G F D C"
  86.  
  87.     PLAY "G E D C G"
  88.     PLAY "G G G E D C A"
  89.     PLAY "A F E D B"
  90.     PLAY "A G F D E"
  91.     PLAY "G E D C G"
  92.     PLAY "G E D C A"
  93.     PLAY "A A F E D G G G"
  94.     PLAY "G A G F D C G"
  95.  
  96.     PLAY "E E E E E E"
  97.     PLAY "E G C D E"
  98.     PLAY "F F F F F E E"
  99.     PLAY "E E E D D E D G"
  100.     PLAY "E E E E E E"
  101.     PLAY "E G C D E"
  102.     PLAY "F F F F F E E"
  103.     PLAY "E E G G F D C"
  104.  
  105. SUB ornament
  106.     c1 = INT(RND * 155) + 100
  107.     c2 = INT(RND * 155) + 100
  108.     c3 = INT(RND * 155) + 100
  109.     shade = 0
  110.     FOR cir = .01 TO 130 STEP .1
  111.         shade = shade - .1
  112.         CIRCLE (400, 300), cir, _RGB32(c1 + shade, c2 + shade, c3 + shade)
  113.     NEXT cir
  114.     yy = 300
  115.     c4 = INT(RND * 155) + 100
  116.     c5 = INT(RND * 155) + 100
  117.     c6 = INT(RND * 155) + 100
  118.     CIRCLE (400, yy), 130, _RGB32(c4, c5, c6), 2 * _PI, _PI, .5
  119.     yy = yy - 40.5
  120.     CIRCLE (400, yy), 124, _RGB32(c4, c5, c6), 2 * _PI, _PI, .4
  121.     yy = yy - 30.5
  122.     CIRCLE (400, yy), 105, _RGB32(c4, c5, c6), 2 * _PI, _PI, .39
  123.     yy = 300
  124.     yy = yy + 22.5
  125.     CIRCLE (400, yy), 130, _RGB32(c4, c5, c6), 2 * _PI, _PI, .5
  126.     yy = yy + 22.5
  127.     CIRCLE (400, yy), 125, _RGB32(c4, c5, c6), 2 * _PI, _PI, .5
  128.     yy = yy + 22.5
  129.     CIRCLE (400, yy), 110, _RGB32(c4, c5, c6), 2 * _PI, _PI, .5
  130.     yy = yy + 22.5
  131.     CIRCLE (400, yy), 75, _RGB32(c4, c5, c6), , , .5
  132.     yy = yy + 22.5
  133.     CIRCLE (400, yy), 15, _RGB32(c4, c5, c6), , , .5
  134.  
  135. SUB RotoZoom (X AS LONG, Y AS LONG, Image AS LONG, Scale AS SINGLE, Rotation AS SINGLE)
  136.     DIM px(3) AS SINGLE: DIM py(3) AS SINGLE
  137.     W& = _WIDTH(Image&): H& = _HEIGHT(Image&)
  138.     px(0) = -W& / 2: py(0) = -H& / 2: px(1) = -W& / 2: py(1) = H& / 2
  139.     px(2) = W& / 2: py(2) = H& / 2: px(3) = W& / 2: py(3) = -H& / 2
  140.     sinr! = SIN(-Rotation / 57.2957795131): cosr! = COS(-Rotation / 57.2957795131)
  141.     FOR i& = 0 TO 3
  142.         x2& = (px(i&) * cosr! + sinr! * py(i&)) * Scale + X: y2& = (py(i&) * cosr! - px(i&) * sinr!) * Scale + Y
  143.         px(i&) = x2&: py(i&) = y2&
  144.     NEXT
  145.     _MAPTRIANGLE (0, 0)-(0, H& - 1)-(W& - 1, H& - 1), Image& TO(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
  146.     _MAPTRIANGLE (0, 0)-(W& - 1, 0)-(W& - 1, H& - 1), Image& TO(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
  147.  
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: OldMoses on December 10, 2020, 07:28:21 pm
A simple little tree topper. I wasn't expecting the gold effect.

Code: QB64: [Select]
  1.  
  2. SCREEN _NEWIMAGE(600, 600, 32)
  3.  
  4. a = _PI * 2 / 5: b = a / 2: r = _PI * 2 / 360
  5. c1& = &HFFFF0000: c2& = &HFF00FF00
  6.  
  7. FOR x = 0 TO 4
  8.     o(x) = x * a
  9.     i(x) = x * a - b
  10.  
  11. x = 0: d = 1
  12.     CLS
  13.     FOR k = 0 TO 100 STEP 5
  14.         FOR j = 0 TO 4
  15.             LINE (SIN(o(j) + (x * r)) * (200 - k) + 300, COS(o(j) + (x * r)) * (200 - k) + 300)-_
  16.                 (SIN(i(j) + (x * r)) * (80 - k) + 300, COS(i(j) + (x * r)) * (80 - k) + 300), c1&
  17.             LINE (SIN(o(j) + (x * r)) * (200 - k) + 300, COS(o(j) + (x * r)) * (200 - k) + 300)-_
  18.                 (SIN(i(j) + a + (x * r)) * (80 - k) + 300, COS(i(j) + a + (x * r)) * (80 - k) + 300), c1&
  19.         NEXT j
  20.         SWAP c1&, c2&
  21.     NEXT k
  22.     IF x MOD 72 = 0 THEN
  23.         d = -d: SWAP c1&, c2&
  24.     END IF
  25.     x = x + d
  26.     _LIMIT 100
  27.     _DISPLAY
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: SierraKen on December 10, 2020, 08:08:20 pm
I just updated my last code above because of the TIMER before midnight problem. TIMER counts up from midnight and the program wouldn't work if you started it right before midnight. So I added code that ends the program if it's near midnight, and explains why.
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: SierraKen on December 10, 2020, 08:09:56 pm
OldMoses that's really cool looking!
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Dav on December 10, 2020, 09:31:06 pm
Thanks, @Petr.  Nice spinning Star, @OldMoses.  I like the your spinning ornaments, @SierraKen.  Hey, I like everything posted here. Nice tree up there especially, @bplus.

I'm trying to come up with a way to make mine a folded card at the beginning, then when you click on it to open, it unfolds like a card showing the drawing screen and plays - like those store bought cards do.

- Dav
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 10, 2020, 11:48:32 pm
Yeah Ken yours is super, fun to compare to your first :)

Old Moses, I am glad someone thought to bring in a star!
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Petr on December 13, 2020, 01:05:22 pm
Hi guys, and here is my output. It is bigger source code and forum can not load it. It is my Christmas 2020 theme program.

Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: johnno56 on December 13, 2020, 01:44:39 pm
Hi Petr,

The program downloaded fine but did not run. It was expecting 'mp3' and 'font' files...

J
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Petr on December 13, 2020, 01:48:24 pm
OK. Source code upgraded, font is now in the source code.  Try it again, please.  It is running correctly under Windows. (previous version also)
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: SierraKen on December 13, 2020, 02:53:31 pm
Petr, that's totally amazing. I never knew so many sounds can be put into one program like that. And your 3D is always incredible. Great job!
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Dav on December 13, 2020, 05:10:56 pm
Well done, @Petr!   Enjoyable.  I like the screen fading, and the audio fading with the scene makes it more realistic.  I never get tired of listening to Silent Night.  And the cracking firewood sound in background gives the scene a warmer feeling.

For some reason the program crashes for me during Silent night playback, I get this error alert message: gluBuild2DMipmaps failed.  So I haven't made it through the whole program, but what I can see I like very much.

I'm using Windows7-32bit, QB64-GL v1.4 32bit.

- Dav

Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 13, 2020, 06:04:32 pm
+1 Wow nice production Petr!

My system played Silent Night at least 3 times, Windows laptop 64 bit QB64 v1.4 stable.

Feliz Navidad :)
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: NOVARSEG on December 13, 2020, 09:33:57 pm
Petr
Excellent!!!
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Petr on December 14, 2020, 12:48:17 pm
Hi i find memory leak in my program. Please goto row 1192 and find "_FREEIMAGE virt" on row 1197. Add to row 1198 this:  _FREEIMAGE Ve(TVO_S + 13).T    so  as in this short program list:


    TeVe(4).T = 0
    TeVe(4).T = _COPYIMAGE(virt, 33)
    TeVe(4).S = 1

    _DEST pred
    _FREEIMAGE virt
   
_FREEIMAGE Ve(TVO_S + 13).T
    Cube3D -.5, 0, 2.8, .7, .5, .1, 0, TeVe(), coordinates()
    INARR coordinates(), Ve(), TVO_S

END SUB

SUB Krb
    FOR S = 1 TO 6
        Sofa(S).T = KRB_textura&



memory usage now is cca 206 megabytes. I find no more bugs (just chaotic programming).
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: SierraKen on December 14, 2020, 01:04:02 pm
I fixed it Petr, thanks.
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: SierraKen on December 14, 2020, 04:04:53 pm
Here is another one from me. It shows snow falling on a hill that piles up a bit, and also onto a Christmas Tree on top of the hill.

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(800, 600, 32)
  2. DIM sx(600), sy(600), rr(600)
  3. DIM stackx(2000), stacky(2000), stackr(2000)
  4. size = 1
  5. _TITLE "Merry Christmas!!!"
  6.     _LIMIT 100
  7.     cx = 400: cy = 1100: r = 700: c = _RGB32(127, 255, 127)
  8.     fillCircle cx, cy, r, c
  9.     'Christmas Tree
  10.     tx = 390: ty = 400: r = 10: c = _RGB32(255, 0, 0)
  11.     LINE (tx, ty)-(tx + 20, ty - 75), _RGB32(183, 127, 127), BF
  12.     'left side
  13.     LINE (tx, ty - 75)-(tx - 150, ty - 75), _RGB32(127, 255, 127)
  14.     LINE (tx - 150, ty - 75)-(tx, ty - 150), _RGB32(127, 255, 127)
  15.     cx = tx - 150: cy = ty - 75
  16.     fillCircle cx, cy, r, c
  17.     LINE (tx, ty - 150)-(tx - 100, ty - 150), _RGB32(127, 255, 127)
  18.     LINE (tx - 100, ty - 150)-(tx, ty - 200), _RGB32(127, 255, 127)
  19.     cx = tx - 100: cy = ty - 150
  20.     fillCircle cx, cy, r, c
  21.     LINE (tx, ty - 200)-(tx - 50, ty - 200), _RGB32(127, 255, 127)
  22.     LINE (tx - 50, ty - 200)-(tx + 5, ty - 250), _RGB32(127, 255, 127)
  23.     cx = tx - 50: cy = ty - 200
  24.     fillCircle cx, cy, r, c
  25.     'right side
  26.     LINE (tx + 20, ty - 75)-(tx + 170, ty - 75), _RGB32(127, 255, 127)
  27.     LINE (tx + 170, ty - 75)-(tx + 20, ty - 150), _RGB32(127, 255, 127)
  28.     cx = tx + 170: cy = ty - 75
  29.     fillCircle cx, cy, r, c
  30.     LINE (tx + 20, ty - 150)-(tx + 120, ty - 150), _RGB32(127, 255, 127)
  31.     LINE (tx + 120, ty - 150)-(tx + 20, ty - 200), _RGB32(127, 255, 127)
  32.     cx = tx + 120: cy = ty - 150
  33.     fillCircle cx, cy, r, c
  34.     LINE (tx + 20, ty - 200)-(tx + 70, ty - 200), _RGB32(127, 255, 127)
  35.     LINE (tx + 70, ty - 200)-(tx + 5, ty - 250), _RGB32(127, 255, 127)
  36.     cx = tx + 70: cy = ty - 200
  37.     fillCircle cx, cy, r, c
  38.     cx = tx + 5: cy = ty - 260
  39.     r = 10
  40.     c = _RGB32(255, 255, 127)
  41.     fillCircle cx, cy, r, c
  42.     tt = INT(RND * 100) + 1
  43.     IF tt > 95 THEN
  44.         a = a + 1
  45.         IF a > 500 THEN a = 1
  46.         sx(a) = RND * _WIDTH
  47.         sy(a) = 1
  48.         rr(a) = RND * 5
  49.     END IF
  50.     FOR t = 1 TO 500
  51.         sy(t) = sy(t) + 1
  52.         cx = sx(t): cy = sy(t)
  53.         r = rr(t)
  54.         c = _RGB32(255, 255, 255)
  55.         fillCircle cx, cy, r, c
  56.         IF POINT(sx(t), sy(t) + rr(t) + 1) = _RGB32(127, 255, 127) THEN GOTO stacked:
  57.         IF POINT(sx(t), sy(t) + rr(t) + 1) = _RGB32(255, 255, 127) THEN GOTO stacked:
  58.         IF POINT(sx(t), sy(t) + rr(t) + 1) = _RGB32(255, 0, 0) THEN GOTO stacked:
  59.     NEXT t
  60.     nex:
  61.     IF snow <> 0 THEN
  62.         FOR sn = 1 TO snow
  63.             cx = stackx(sn)
  64.             cy = stacky(sn)
  65.             r = stackr(sn)
  66.             c = _RGB32(252, 252, 252)
  67.             fillCircle cx, cy, r, c
  68.         NEXT sn
  69.     END IF
  70.     _DISPLAY
  71.     LINE (0, 0)-(_WIDTH, _HEIGHT), _RGB32(0, 0, 0), BF
  72.  
  73. stacked:
  74. snow = snow + 1
  75. IF snow > 1800 THEN snow = 1: size = 1
  76. IF snow / 200 = INT(snow / 200) THEN size = size * 1.4
  77. stackx(snow) = sx(t)
  78. stacky(snow) = sy(t) - (size / 2)
  79. stackr(snow) = rr(t) + size
  80. sx(t) = -200: sy(t) = 800
  81. GOTO nex:
  82.  
  83. 'from Steve Gold standard
  84. SUB fillCircle (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  85.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  86.     DIM X AS INTEGER, Y AS INTEGER
  87.     Radius = ABS(R): RadiusError = -Radius: X = Radius: Y = 0
  88.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  89.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  90.     WHILE X > Y
  91.         RadiusError = RadiusError + Y * 2 + 1
  92.         IF RadiusError >= 0 THEN
  93.             IF X <> Y + 1 THEN
  94.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  95.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  96.             END IF
  97.             X = X - 1
  98.             RadiusError = RadiusError - X * 2
  99.         END IF
  100.         Y = Y + 1
  101.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  102.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  103.     WEND
  104.  
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Dav on December 14, 2020, 04:34:46 pm
Nice one, @SierraKen.

@Petr: That fixed it for me.  Nice Christmas demo you made.

- Dav
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Petr on December 14, 2020, 05:02:37 pm
@SierraKen Nice work!
@Dav I'm glad it's okay now :)
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Dav on December 14, 2020, 05:20:15 pm
Made a little ornament thing.  Draws random color ornament balls like you see on Christmas trees around here.  Nothing great, I just felt like making something.

- Dav

Code: QB64: [Select]
  1. '=============
  2. 'Ornaments.bas
  3. '=============
  4. 'Draws random Christmas ornaments
  5. 'Coded by Dav, DEC/2020
  6.  
  7. SCREEN _NEWIMAGE(600, 600, 32)
  8.  
  9.     x = RND * _WIDTH: y = RND * _HEIGHT 'random x/y
  10.     size = 50 + RND * 50 'random size ornament
  11.  
  12.     'select random ornament color,red,greem or blue
  13.     SELECT CASE INT(RND * 3) + 1
  14.         CASE 1: r = (RND * 100) + 155: g = 100: b = 100 'red
  15.         CASE 2: g = (RND * 100) + 155: r = 100: b = 100 'green
  16.         CASE 3: b = (RND * 100) + 155: r = 100: g = 100 'blue
  17.     END SELECT
  18.  
  19.     ball x, y, size, r, g, b
  20.  
  21.     _LIMIT 30
  22.  
  23.  
  24. SUB ball (x, y, size, r, g, b)
  25.     'draws a gradient ball
  26.     FOR s = 1 TO size STEP .5
  27.         CIRCLE (x, y), s, _RGB(r, g, b)
  28.         r = r - 1: g = g - 1: b = b - 1
  29.     NEXT
  30.     'Draw top of ornament
  31.     LINE (x - 10, y - size - 10)-(x + 10, y - size), _RGB(r, g, b), BF
  32.  
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: OldMoses on December 14, 2020, 05:47:10 pm
@Petr that was completely amazing! Well done.
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: SierraKen on December 14, 2020, 05:51:40 pm
Thanks guys. Awesome ornaments Dav!
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Pete on December 14, 2020, 07:31:03 pm
Anyone made Rudolf or Olive, yet?

Pete
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: johnno56 on December 15, 2020, 04:54:34 am
You finish off the bauble with a rectangle of the same rgb colour. I was thinking... stop laughing... What if the rectangles were 'center-gradient-based". The left-hand side of the rectangle starts off as pale grey; blends to a darker grey in the center; blends to a lighter grey towards the right-hand side. To give the "top" the illusion of being cylindrical... I don't know the correct way to explain it. I hope I am making sense? Just a thought...
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: STxAxTIC on December 15, 2020, 07:25:21 am
Why invent something new when I can release a greatest hits album?

My (first?) holiday contribution comes as a FluidCraft level. Compile the code below to an EXE, and then drag+drop the attached file.

Code: QB64: [Select]
  1. ' Version 2020-12-15
  2.  
  3.  
  4. _TITLE "FluidCraft"
  5.  
  6. SCREEN _NEWIMAGE(1024, 768, 32)
  7. '_FULLSCREEN , _SMOOTH
  8.  
  9.  
  10. TYPE Vector
  11.     x AS DOUBLE
  12.     y AS DOUBLE
  13.  
  14. TYPE ShadeVector
  15.     shadered AS DOUBLE
  16.     shadegreen AS DOUBLE
  17.     shadeblue AS DOUBLE
  18.     shadealpha AS DOUBLE
  19.  
  20. TYPE ShadeElement
  21.     TheName AS STRING
  22.     TheShade AS ShadeVector
  23.  
  24. TYPE Pixel
  25.     position AS Vector
  26.     velocity AS Vector
  27.     acceleration AS Vector
  28.     size AS DOUBLE
  29.     TheShade AS ShadeVector
  30.  
  31. DIM SHARED ShadeData(8) AS ShadeElement
  32. DIM SHARED ActiveShade AS ShadeVector
  33. DIM SHARED PixelCloud(3000) AS Pixel
  34. DIM SHARED ObjectSize AS DOUBLE
  35. DIM SHARED GridSize AS Vector
  36. ObjectSize = 6
  37. GridSize.x = 1 + INT(_WIDTH / ObjectSize)
  38. GridSize.y = 1 + INT(_HEIGHT / ObjectSize)
  39. DIM SHARED Level(GridSize.x, GridSize.y) AS ShadeVector
  40.  
  41. CALL InitializeAll
  42. CALL LoadFile
  43.     CALL UserInput
  44.     CLS
  45.     CALL DrawBorder
  46.     CALL DrawPixels
  47.     CALL DrawLevel
  48.     CALL Dynamics
  49.     CALL DrawOverlay
  50.     _DISPLAY
  51.     _LIMIT 30
  52.  
  53.  
  54. SUB DrawBorder
  55.     DIM k AS INTEGER
  56.     LINE (0, 0)-(_WIDTH, _HEIGHT), _RGB32(255, 0, 255, 255), BF
  57.     FOR k = 6 TO _HEIGHT - 1 - 6
  58.         LINE (6, k)-(_WIDTH - 6, k), _RGB32(255 * k / _HEIGHT, 0, 255 * (1 - k / _HEIGHT), 255)
  59.     NEXT
  60.     LINE (12, 12)-(_WIDTH - 12, _HEIGHT - 12), _RGB32(0, 0, 0, 255), BF
  61.     LINE (12, 12)-(18 * (UBOUND(ShadeData) + 1) - 1 + 6 + 12, 38 + 12), _RGB32(0, 0, 255, 255), BF
  62.     LINE (12, 12)-(18 * (UBOUND(ShadeData) + 1) - 1 + 6 + 6, 38 + 6), _RGB32(255, 0, 255, 255), BF
  63.     LINE (12, 12)-(18 * (UBOUND(ShadeData) + 1) - 1 + 6, 38), _RGB32(0, 0, 0, 255), BF
  64.  
  65. SUB DrawPixels
  66.     DIM k AS INTEGER
  67.     DIM x AS DOUBLE
  68.     DIM y AS DOUBLE
  69.     DIM s AS DOUBLE
  70.     FOR k = 1 TO UBOUND(PixelCloud)
  71.         x = PixelCloud(k).position.x
  72.         y = PixelCloud(k).position.y
  73.         s = PixelCloud(k).size
  74.         CALL clinebf(x - s, y - s, x + s, y + s, _RGBA(PixelCloud(k).TheShade.shadered, PixelCloud(k).TheShade.shadegreen, PixelCloud(k).TheShade.shadeblue, PixelCloud(k).TheShade.shadealpha))
  75.     NEXT
  76.  
  77. SUB DrawLevel
  78.     DIM i AS INTEGER
  79.     DIM j AS INTEGER
  80.     DIM x AS DOUBLE
  81.     DIM y AS DOUBLE
  82.     DIM s AS DOUBLE
  83.     s = ObjectSize
  84.     FOR i = 1 TO GridSize.x
  85.         FOR j = 1 TO GridSize.y
  86.             x = (i - 1) * s
  87.             y = (j - 1) * s
  88.             IF (Level(i, j).shadered > 5) OR (Level(i, j).shadegreen > 5) OR (Level(i, j).shadeblue > 5) THEN
  89.                 CALL slinebf(x - s / 2, y - s / 2, x + s / 2 - 1, y + s / 2 - 1, _RGBA(Level(i, j).shadered, Level(i, j).shadegreen, Level(i, j).shadeblue, Level(i, j).shadealpha))
  90.             END IF
  91.         NEXT
  92.     NEXT
  93.  
  94. SUB DrawOverlay
  95.     DIM k AS INTEGER
  96.     IF ActiveShade.shadered < 5 AND ActiveShade.shadegreen < 5 AND ActiveShade.shadeblue < 5 THEN
  97.         LINE (ObjectSize * INT(_MOUSEX / ObjectSize) - ObjectSize / 2 - 1, ObjectSize * INT(_MOUSEY / ObjectSize) - ObjectSize / 2 - 1)-(ObjectSize * INT(_MOUSEX / ObjectSize) + ObjectSize / 2 - 1 + 1, ObjectSize * INT(_MOUSEY / ObjectSize) + ObjectSize / 2 - 1 + 1), _RGBA(255, 255, 255, 255), B
  98.     END IF
  99.     LINE (ObjectSize * INT(_MOUSEX / ObjectSize) - ObjectSize / 2, ObjectSize * INT(_MOUSEY / ObjectSize) - ObjectSize / 2)-(ObjectSize * INT(_MOUSEX / ObjectSize) + ObjectSize / 2 - 1, ObjectSize * INT(_MOUSEY / ObjectSize) + ObjectSize / 2 - 1), _RGBA(ActiveShade.shadered, ActiveShade.shadegreen, ActiveShade.shadeblue, ActiveShade.shadealpha), BF
  100.     FOR k = 1 TO UBOUND(ShadeData)
  101.         LINE (18 * k + 1, 18)-(18 * (k + 1) - 1, 32), _RGB32(ShadeData(k).TheShade.shadered, ShadeData(k).TheShade.shadegreen, ShadeData(k).TheShade.shadeblue, ShadeData(k).TheShade.shadealpha), BF
  102.         LINE (18 * k + 1, 18)-(18 * (k + 1) - 1, 32), _RGB32(255, 255, 255, 255), B
  103.     NEXT
  104.  
  105. SUB InitializeAll
  106.     DIM k AS INTEGER
  107.     ShadeData(1).TheName = "Red"
  108.     ShadeData(1).TheShade.shadered = 255
  109.     ShadeData(1).TheShade.shadegreen = 0
  110.     ShadeData(1).TheShade.shadeblue = 0
  111.     ShadeData(1).TheShade.shadealpha = 255
  112.     ShadeData(2).TheName = "Blue"
  113.     ShadeData(2).TheShade.shadered = 0
  114.     ShadeData(2).TheShade.shadegreen = 0
  115.     ShadeData(2).TheShade.shadeblue = 255
  116.     ShadeData(2).TheShade.shadealpha = 255
  117.     ShadeData(3).TheName = "Green"
  118.     ShadeData(3).TheShade.shadered = 0
  119.     ShadeData(3).TheShade.shadegreen = 255
  120.     ShadeData(3).TheShade.shadeblue = 0
  121.     ShadeData(3).TheShade.shadealpha = 255
  122.     ShadeData(4).TheName = "White"
  123.     ShadeData(4).TheShade.shadered = 255
  124.     ShadeData(4).TheShade.shadegreen = 255
  125.     ShadeData(4).TheShade.shadeblue = 255
  126.     ShadeData(4).TheShade.shadealpha = 255
  127.     ShadeData(5).TheName = "Yellow"
  128.     ShadeData(5).TheShade.shadered = 255
  129.     ShadeData(5).TheShade.shadegreen = 255
  130.     ShadeData(5).TheShade.shadeblue = 0
  131.     ShadeData(5).TheShade.shadealpha = 255
  132.     ShadeData(6).TheName = "Aqua"
  133.     ShadeData(6).TheShade.shadered = 0
  134.     ShadeData(6).TheShade.shadegreen = 255
  135.     ShadeData(6).TheShade.shadeblue = 255
  136.     ShadeData(6).TheShade.shadealpha = 255
  137.     ShadeData(7).TheName = "Violet"
  138.     ShadeData(7).TheShade.shadered = 255
  139.     ShadeData(7).TheShade.shadegreen = 0
  140.     ShadeData(7).TheShade.shadeblue = 255
  141.     ShadeData(7).TheShade.shadealpha = 255
  142.     ShadeData(8).TheName = "Black"
  143.     ShadeData(8).TheShade.shadered = 0
  144.     ShadeData(8).TheShade.shadegreen = 0
  145.     ShadeData(8).TheShade.shadeblue = 0
  146.     ShadeData(8).TheShade.shadealpha = 255
  147.  
  148.     FOR k = 1 TO UBOUND(PixelCloud)
  149.         PixelCloud(k).size = 3
  150.         PixelCloud(k).acceleration.x = 0
  151.         PixelCloud(k).acceleration.y = 0
  152.         PixelCloud(k).velocity.x = 0
  153.         PixelCloud(k).velocity.y = 0
  154.         PixelCloud(k).position.x = (RND - .5) * _WIDTH * .8
  155.         PixelCloud(k).position.y = (RND - .5) * _HEIGHT * .8
  156.         CALL SetPixelShade(k, 0, 0, 255, 150)
  157.     NEXT
  158.  
  159.     ActiveShade.shadered = 255
  160.     ActiveShade.shadegreen = 0
  161.     ActiveShade.shadeblue = 0
  162.     ActiveShade.shadealpha = 255
  163.  
  164.  
  165. SUB SetPixelShade (i AS INTEGER, r AS INTEGER, g AS INTEGER, b AS INTEGER, a AS INTEGER)
  166.     PixelCloud(i).TheShade.shadered = r
  167.     PixelCloud(i).TheShade.shadegreen = g
  168.     PixelCloud(i).TheShade.shadeblue = b
  169.     PixelCloud(i).TheShade.shadealpha = a
  170.  
  171. SUB UserInput
  172.     DIM mb1 AS INTEGER
  173.     DIM mb2 AS INTEGER
  174.     DIM mb3 AS INTEGER
  175.     DIM i AS INTEGER
  176.     DIM j AS INTEGER
  177.     DIM k AS INTEGER
  178.     mb1 = 0
  179.     mb2 = 0
  180.     mb3 = 0
  181.         IF (_MOUSEBUTTON(1) = -1) AND (mb1 <> 1) THEN
  182.             mb1 = -1
  183.             i = 1 + INT(_MOUSEX / ObjectSize)
  184.             j = 1 + INT(_MOUSEY / ObjectSize)
  185.             Level(i, j).shadered = ActiveShade.shadered
  186.             Level(i, j).shadegreen = ActiveShade.shadegreen
  187.             Level(i, j).shadeblue = ActiveShade.shadeblue
  188.             Level(i, j).shadealpha = ActiveShade.shadealpha
  189.         END IF
  190.         IF ((_MOUSEBUTTON(2) = -1) AND (mb2 <> -1)) THEN
  191.             mb2 = -1
  192.             i = ObjectSize * INT(_MOUSEX / ObjectSize)
  193.             j = ObjectSize * INT(_MOUSEY / ObjectSize)
  194.             ActiveShade.shadered = _RED32(POINT(i, j))
  195.             ActiveShade.shadegreen = _GREEN32(POINT(i, j))
  196.             ActiveShade.shadeblue = _BLUE32(POINT(i, j))
  197.             ActiveShade.shadealpha = _ALPHA32(POINT(i, j))
  198.         END IF
  199.     LOOP
  200.         CASE ASC("e"), ASC("E")
  201.             CALL Export
  202.         CASE ASC("r"), ASC("R")
  203.             FOR k = 1 TO UBOUND(PixelCloud)
  204.                 PixelCloud(k).TheShade.shadered = 255
  205.                 PixelCloud(k).TheShade.shadegreen = 0
  206.                 PixelCloud(k).TheShade.shadeblue = 0
  207.             NEXT
  208.         CASE ASC("b"), ASC("B")
  209.             FOR k = 1 TO UBOUND(PixelCloud)
  210.                 PixelCloud(k).TheShade.shadered = 0
  211.                 PixelCloud(k).TheShade.shadegreen = 0
  212.                 PixelCloud(k).TheShade.shadeblue = 255
  213.             NEXT
  214.         CASE ASC("0")
  215.             FOR k = 1 TO UBOUND(PixelCloud)
  216.                 PixelCloud(k).position.x = (RND - .5) * _WIDTH * .8
  217.                 PixelCloud(k).position.y = (RND - .5) * _HEIGHT * .8
  218.             NEXT
  219.         CASE 27
  220.             FOR i = 1 TO GridSize.x
  221.                 FOR j = 1 TO GridSize.y
  222.                     Level(i, j).shadered = 0
  223.                     Level(i, j).shadegreen = 0
  224.                     Level(i, j).shadeblue = 0
  225.                     Level(i, j).shadealpha = 0
  226.                 NEXT
  227.             NEXT
  228.     END SELECT
  229.     'DO WHILE _MOUSEINPUT: LOOP
  230.  
  231. SUB Export
  232.     DIM i AS INTEGER
  233.     DIM j AS INTEGER
  234.     OPEN "FluidCraft" + LTRIM$(RTRIM$(STR$(INT(TIMER)))) + ".txt" FOR OUTPUT AS #1
  235.     FOR i = 1 TO UBOUND(Level, 1)
  236.         FOR j = 1 TO UBOUND(Level, 2)
  237.             PRINT #1, i, j, Level(i, j).shadered, Level(i, j).shadegreen, Level(i, j).shadeblue, Level(i, j).shadealpha
  238.         NEXT
  239.     NEXT
  240.     CLOSE #1
  241.  
  242. SUB Dynamics
  243.     DIM k AS INTEGER
  244.     FOR k = 1 TO UBOUND(PixelCloud)
  245.         CALL CalculateInfluence(k)
  246.         CALL UpdatePosition(k)
  247.     NEXT
  248.  
  249. SUB UpdatePosition (i AS INTEGER)
  250.     DIM dt AS DOUBLE
  251.     DIM damp AS DOUBLE
  252.     DIM brownian AS DOUBLE
  253.     dt = 1
  254.     damp = 0.8
  255.     brownian = .65
  256.     PixelCloud(i).velocity.x = damp * PixelCloud(i).velocity.x + dt * PixelCloud(i).acceleration.x
  257.     PixelCloud(i).velocity.y = damp * PixelCloud(i).velocity.y + dt * PixelCloud(i).acceleration.y
  258.     PixelCloud(i).position.x = PixelCloud(i).position.x + dt * PixelCloud(i).velocity.x + (RND - .5) * brownian
  259.     PixelCloud(i).position.y = PixelCloud(i).position.y + dt * PixelCloud(i).velocity.y + (RND - .5) * brownian
  260.     IF (PixelCloud(i).position.y <= -_HEIGHT / 2 + 2 * PixelCloud(i).size + 1) THEN
  261.         PixelCloud(i).position.y = _HEIGHT / 2 - 2 * PixelCloud(i).size
  262.     END IF
  263.  
  264. SUB CalculateInfluence (i AS INTEGER)
  265.     DIM x AS DOUBLE
  266.     DIM y AS DOUBLE
  267.     DIM dx AS DOUBLE
  268.     DIM dy AS DOUBLE
  269.     DIM xr AS DOUBLE
  270.     DIM yr AS DOUBLE
  271.     DIM xg AS DOUBLE
  272.     DIM yg AS DOUBLE
  273.     DIM xb AS DOUBLE
  274.     DIM yb AS DOUBLE
  275.     DIM WPoint(9) AS _UNSIGNED LONG
  276.     x = PixelCloud(i).position.x
  277.     y = PixelCloud(i).position.y
  278.     dx = 2 * PixelCloud(i).size
  279.     dy = 2 * PixelCloud(i).size
  280.     WPoint(7) = cpoint(x - dx, y + dy)
  281.     WPoint(8) = cpoint(x, y + dy)
  282.     WPoint(9) = cpoint(x + dx, y + dy)
  283.     WPoint(4) = cpoint(x - dx, y)
  284.     WPoint(6) = cpoint(x + dx, y)
  285.     WPoint(1) = cpoint(x - dx, y - dy)
  286.     WPoint(2) = cpoint(x, y - dy)
  287.     WPoint(3) = cpoint(x + dx, y - dy)
  288.  
  289.     DIM k AS INTEGER
  290.     DIM WShade(9) AS DOUBLE
  291.     DIM xc AS DOUBLE
  292.     DIM yc AS DOUBLE
  293.     DIM cs AS INTEGER
  294.     cs = 0
  295.     x = 0
  296.     y = 0
  297.  
  298.     ' red
  299.     FOR k = 1 TO 9
  300.         IF (k <> 5) THEN
  301.             IF ((_RED32(WPoint(k)) > 25) AND (_GREEN32(WPoint(k)) < 5) AND (_BLUE32(WPoint(k)) < 25)) THEN
  302.                 WShade(k) = _RED32(WPoint(k)) + _GREEN32(WPoint(k)) + _BLUE32(WPoint(k))
  303.             ELSE
  304.                 WShade(k) = 0
  305.             END IF
  306.         END IF
  307.     NEXT
  308.     xr = (WShade(6) - WShade(4) + (WShade(9) + WShade(3)) / SQR(2) - (WShade(7) + WShade(1)) / SQR(2))
  309.     yr = (WShade(8) - WShade(2) + (WShade(7) + WShade(9)) / SQR(2) - (WShade(1) + WShade(3)) / SQR(2))
  310.     x = x + xr
  311.     y = y + yr
  312.  
  313.     ' blue
  314.     FOR k = 1 TO 9
  315.         IF (k <> 5) THEN
  316.             IF ((_RED32(WPoint(k)) < 25) AND (_GREEN32(WPoint(k)) < 5) AND (_BLUE32(WPoint(k)) > 25)) THEN
  317.                 WShade(k) = _RED32(WPoint(k)) + _GREEN32(WPoint(k)) + _BLUE32(WPoint(k))
  318.             ELSE
  319.                 WShade(k) = 0
  320.             END IF
  321.         END IF
  322.     NEXT
  323.     xb = (WShade(6) - WShade(4) + (WShade(9) + WShade(3)) / SQR(2) - (WShade(7) + WShade(1)) / SQR(2))
  324.     yb = (WShade(8) - WShade(2) + (WShade(7) + WShade(9)) / SQR(2) - (WShade(1) + WShade(3)) / SQR(2))
  325.     x = x + xb
  326.     y = y + yb
  327.  
  328.     ' green
  329.     FOR k = 1 TO 9
  330.         IF (k <> 5) THEN
  331.             IF ((_RED32(WPoint(k)) < 5) AND (_GREEN32(WPoint(k)) > 250) AND (_BLUE32(WPoint(k)) < 5)) THEN
  332.                 WShade(k) = _RED32(WShade(k)) + _GREEN32(WPoint(k)) + _BLUE32(WPoint(k))
  333.                 cs = 1
  334.             ELSE
  335.                 WShade(k) = 0
  336.             END IF
  337.         END IF
  338.     NEXT
  339.     xg = -(WShade(6) - WShade(4) + (WShade(9) + WShade(3)) / SQR(2) - (WShade(7) + WShade(1)) / SQR(2))
  340.     yg = (0 - WShade(2) + (0 + 0) / SQR(2) - (WShade(1) + WShade(3)) / SQR(2))
  341.     x = x + xg
  342.     y = y + yg
  343.  
  344.     ' custom yellow
  345.     FOR k = 1 TO 9
  346.         IF (k <> 5) THEN
  347.             IF ((_RED32(WPoint(k)) > 250) AND (_GREEN32(WPoint(k)) > 250) AND (_BLUE32(WPoint(k)) < 5)) THEN
  348.                 WShade(k) = _RED32(WShade(k)) + _GREEN32(WPoint(k)) + _BLUE32(WPoint(k))
  349.                 cs = 1
  350.             ELSE
  351.                 WShade(k) = 0
  352.             END IF
  353.         END IF
  354.     NEXT
  355.     xc = (WShade(6) - 0 + (WShade(9) + WShade(3)) / SQR(2) - (0 + 0) / SQR(2))
  356.     yc = 0
  357.     x = x + xc
  358.     y = y + yc
  359.  
  360.     ' custom aqua
  361.     FOR k = 1 TO 9
  362.         IF (k <> 5) THEN
  363.             IF ((_RED32(WPoint(k)) < 5) AND (_GREEN32(WPoint(k)) > 250) AND (_BLUE32(WPoint(k)) > 250)) THEN
  364.                 WShade(k) = _RED32(WShade(k)) + _GREEN32(WPoint(k)) + _BLUE32(WPoint(k))
  365.                 cs = 1
  366.             ELSE
  367.                 WShade(k) = 0
  368.             END IF
  369.         END IF
  370.     NEXT
  371.     xc = -(WShade(6) - 0 + (WShade(9) + WShade(3)) / SQR(2) - (0 + 0) / SQR(2))
  372.     yc = 0
  373.     x = x + xc
  374.     y = y + yc
  375.  
  376.     ' custom white
  377.     FOR k = 1 TO 9
  378.         IF (k <> 5) THEN
  379.             IF ((_RED32(WPoint(k)) > 250) AND (_GREEN32(WPoint(k)) > 250) AND (_BLUE32(WPoint(k)) > 250)) THEN
  380.                 WShade(k) = _RED32(WShade(k)) + _GREEN32(WPoint(k)) + _BLUE32(WPoint(k))
  381.                 cs = 1
  382.             ELSE
  383.                 WShade(k) = 0
  384.             END IF
  385.         END IF
  386.     NEXT
  387.     xc = -(WShade(6) - WShade(4) + (WShade(9) + WShade(3)) / SQR(2) - (WShade(7) + WShade(1)) / SQR(2))
  388.     yc = -(0 - WShade(2) + (0 + 0) / SQR(2) - (WShade(1) + WShade(3)) / SQR(2))
  389.     x = x + xc
  390.     y = y + yc
  391.  
  392.     ' custom violet
  393.     FOR k = 1 TO 9
  394.         IF (k <> 5) THEN
  395.             IF ((_RED32(WPoint(k)) > 250) AND (_GREEN32(WPoint(k)) < 5) AND (_BLUE32(WPoint(k)) > 250)) THEN
  396.                 WShade(k) = _RED32(WShade(k)) + _GREEN32(WPoint(k)) + _BLUE32(WPoint(k))
  397.                 cs = 1
  398.             ELSE
  399.                 WShade(k) = 0
  400.             END IF
  401.         END IF
  402.     NEXT
  403.     xc = (WShade(6) - WShade(4) + (WShade(9) + WShade(3)) / SQR(2) - (WShade(7) + WShade(1)) / SQR(2))
  404.     yc = (WShade(8) - WShade(2) + (WShade(7) + WShade(9)) / SQR(2) - (WShade(1) + WShade(3)) / SQR(2))
  405.     x = x + xc
  406.     y = y + yc
  407.  
  408.     ' Conductivity
  409.     IF (cs = 0) THEN
  410.         IF ((xr * xr + yr * yr) > (xb * xb + yb * yb)) THEN
  411.             PixelCloud(i).TheShade.shadered = PixelCloud(i).TheShade.shadered + 64
  412.             IF (PixelCloud(i).TheShade.shadered >= 255) THEN PixelCloud(i).TheShade.shadered = 255
  413.             PixelCloud(i).TheShade.shadeblue = PixelCloud(i).TheShade.shadeblue - 64
  414.             IF (PixelCloud(i).TheShade.shadeblue <= 0) THEN PixelCloud(i).TheShade.shadeblue = 0
  415.         END IF
  416.         IF ((xb * xb + yb * yb) > (xr * xr + yr * yr)) THEN
  417.             PixelCloud(i).TheShade.shadered = PixelCloud(i).TheShade.shadered - 64
  418.             IF (PixelCloud(i).TheShade.shadered <= 0) THEN PixelCloud(i).TheShade.shadered = 0
  419.             PixelCloud(i).TheShade.shadeblue = PixelCloud(i).TheShade.shadeblue + 64
  420.             IF (PixelCloud(i).TheShade.shadeblue >= 255) THEN PixelCloud(i).TheShade.shadeblue = 255
  421.         END IF
  422.     END IF
  423.  
  424.     ' Gravity vs. levity
  425.     IF (cs = 0) THEN
  426.         y = y - (PixelCloud(i).TheShade.shadered - PixelCloud(i).TheShade.shadeblue) / 255
  427.     END IF
  428.  
  429.     ' Normalize acceleration
  430.     IF (ABS(x) < .001) THEN
  431.         PixelCloud(i).acceleration.x = 0
  432.     ELSE
  433.         PixelCloud(i).acceleration.x = -x / SQR(x * x + y * y)
  434.     END IF
  435.     IF (ABS(y) < .001) THEN
  436.         PixelCloud(i).acceleration.y = 0
  437.     ELSE
  438.         PixelCloud(i).acceleration.y = -y / SQR(x * x + y * y)
  439.     END IF
  440.  
  441.     ' Auto-cooling
  442.     IF (cs = 0) THEN
  443.         PixelCloud(i).TheShade.shadered = PixelCloud(i).TheShade.shadered - 2
  444.         IF (PixelCloud(i).TheShade.shadered <= 0) THEN PixelCloud(i).TheShade.shadered = 0
  445.         PixelCloud(i).TheShade.shadeblue = PixelCloud(i).TheShade.shadeblue + 2
  446.         IF (PixelCloud(i).TheShade.shadeblue >= 255) THEN PixelCloud(i).TheShade.shadeblue = 255
  447.     END IF
  448.  
  449. FUNCTION cpoint& (x1 AS DOUBLE, y1 AS DOUBLE)
  450.     DIM TheReturn AS _UNSIGNED LONG
  451.     TheReturn = POINT(_WIDTH / 2 + x1, -y1 + _HEIGHT / 2)
  452.     cpoint = TheReturn
  453.  
  454. SUB clinebf (x1 AS DOUBLE, y1 AS DOUBLE, x2 AS DOUBLE, y2 AS DOUBLE, col AS _UNSIGNED LONG)
  455.     LINE (_WIDTH / 2 + x1, -y1 + _HEIGHT / 2)-(_WIDTH / 2 + x2 - 0, -y2 + _HEIGHT / 2 + 0), col, BF
  456.  
  457. SUB slinebf (x1 AS DOUBLE, y1 AS DOUBLE, x2 AS DOUBLE, y2 AS DOUBLE, col AS _UNSIGNED LONG)
  458.     LINE (x1, y1)-(x2, y2), col, BF
  459.  
  460. SUB cprintstring (y1 AS DOUBLE, a AS STRING)
  461.     _PRINTSTRING (_WIDTH / 2 - (LEN(a) * 8) / 2, -y1 + _HEIGHT / 2), a
  462.  
  463. SUB LoadFile
  464.     DIM i AS INTEGER
  465.     DIM j AS INTEGER
  466.     DIM r AS INTEGER
  467.     DIM g AS INTEGER
  468.     DIM b AS INTEGER
  469.     DIM a AS INTEGER
  470.     IF (COMMAND$ <> "") THEN
  471.         PRINT "Loading..."
  472.         OPEN COMMAND$ FOR INPUT AS #1
  473.         DO WHILE NOT EOF(1)
  474.             INPUT #1, i, j, r, g, b, a
  475.             Level(i, j).shadered = r
  476.             Level(i, j).shadegreen = g
  477.             Level(i, j).shadeblue = b
  478.             Level(i, j).shadealpha = a
  479.         LOOP
  480.         CLOSE #1
  481.     END IF
  482.  
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Dav on December 15, 2020, 08:55:47 am
@johnno56: That sounds good to me.  The top was as afterthought.  I should have made it silver or something before posting.

@STxAxTIC: That looks pretty cool...

Here is something I started working on last night, a multi-note PLAY like system using sound files.  Since it's Christmas I made it play a Christmas song and will post it here.  I wanted to make PLAY songs that used real sounds and play chords, so here it is playing Silent Night. The sound files I ripped from my TankDrum thing.

NOTE: .OGG Alert for those who have problems opening files with .OGG files...

Download       (385k)

Here's the source code, but you will need the SPLAY.ZIP above to run it...

- Dav

Note: Edited code to v1.02. (12/15/2020)
Code: QB64: [Select]
  1. '=========
  2. 'SPLAY.BAS v1.02
  3. '=========
  4. 'A multi-note PLAY-like method using sound files to
  5. 'play notes, and allow more than one note at a time.
  6. 'This demo plays Silent Night.
  7. 'Coded By Dav, DEC/2020
  8.  
  9. 'Added: Added Rests (RN).
  10. 'Fixed: Replace delay routine. Actually works now.
  11. 'Fixed: Allows spaces in note groups ( )
  12. 'Added: Added inkey$ bail-out of SUB playing notes
  13.  
  14. 'Over time I'll adapt this to math PLAY commands as
  15. 'much as possible, but for now heres how you use it:
  16.  
  17. 'For now, there only 15 notes playable, about 2 octaves.
  18. ' e1 f1 g1 a1 b1 | c2 d2 e2 f2 g2 a2 b2 | c3 d3 e3
  19.  
  20. 'You can play a chord of notes by grouping inside ()
  21. ' (c2 e2 g2)
  22.  
  23. 'Assign current note/rest length values like this...
  24. 'WN = Whole note, HN = Half note, DQ = Dotted quarter note
  25. 'QN = Quarter note, EN = Eighth note, SN = Sixteenth note
  26.  
  27. 'Rests - nothing played, but time continues
  28. 'RN = Rest note.  Uses current note length value set.
  29. 'For example, to rest a quarter note, do this:
  30. 'QN RN
  31.  
  32. 'Assign Tempos like this (always must be in 4 characters):
  33. 'T120  ... or T060   ...  or  T100
  34.  
  35. 'Assign current meter (for whole length value to work)
  36. 'M3  (thats for 3/4)....  M4   (Thats for 4/4)
  37.  
  38.  
  39. '=========================================================
  40.  
  41. 'Sound file handles
  42. DIM SHARED e1&, f1&, g1&, a1&, b1&, c2&, d2&
  43. DIM SHARED e2&, f2&, g2&, a2&, b2&, c3&, d3&, e3&
  44. DIM SHARED Tempo, Meter, NoteValue 'playing values
  45.  
  46. 'Load sound samples
  47. e1& = _SNDOPEN("ogg/e1.ogg"): f1& = _SNDOPEN("ogg/f1.ogg")
  48. g1& = _SNDOPEN("ogg/g1.ogg"): a1& = _SNDOPEN("ogg/a1.ogg")
  49. b1& = _SNDOPEN("ogg/b1.ogg"): c2& = _SNDOPEN("ogg/c2.ogg")
  50. d2& = _SNDOPEN("ogg/d2.ogg"): e2& = _SNDOPEN("ogg/e2.ogg")
  51. f2& = _SNDOPEN("ogg/f2.ogg"): g2& = _SNDOPEN("ogg/g2.ogg")
  52. a2& = _SNDOPEN("ogg/a2.ogg"): b2& = _SNDOPEN("ogg/b2.ogg")
  53. c3& = _SNDOPEN("ogg/c3.ogg"): d3& = _SNDOPEN("ogg/d3.ogg")
  54. e3& = _SNDOPEN("ogg/e3.ogg")
  55.  
  56.  
  57. PRINT "Testing all notes...e1 to e3"
  58. 'Set tempo 120, meter 4/4, set sixteen note value, play all notes
  59. SPLAY "t120 m4 sn e1f1g1a1b1c2d2e2f2g2a2b2c3d3e3"
  60.  
  61. 'Note: You don't have to include spaces, but I did here...
  62.  
  63. PRINT "Playing chords..."
  64. 'Note: tempo and meter already set in earlier call, so
  65. '      below will play with that, but you can change it...
  66. SPLAY "qn (c2 e2 g2) rn rn (f2a2c3) (g2b2d3) wn (c3g2e2c2g1)"
  67.  
  68. 'Now, since it's Christmas, play a Christmas song...
  69.  
  70.     CLS: PRINT
  71.     PRINT "Silent night...";
  72.     SPLAY "t100m3dq(c2e2g2)en(c2f2a2)qn(c2e2g2)wn(g1c2e2)"
  73.     PRINT "Holy night..."
  74.     SPLAY "dq(c2e2g2)en(c2f2a2)qn(c2e2g2)wn(g1c2e2)"
  75.     PRINT "All is calm....";
  76.     SPLAY "hn(d3b2g2)qnd3(g2b2)c3(d3g2f2)"
  77.     PRINT "All is bright..."
  78.     SPLAY "hn(c3g2e2)en(c3g2)f2qn(c2e2g3)d2e2"
  79.     PRINT "Round 'yon virgin...";
  80.     SPLAY "en(a2f2)g2f2g2(a2f2)(g2b2)qn(c3a2f2)(b2g2)(a2f2)"
  81.     PRINT "Mother and child...."
  82.     SPLAY "dq(g2e2c2)en(a2f2)qn(g2e2)(e2c2)d2e2"
  83.     PRINT "Holy Infant so ";
  84.     SPLAY "en(a2f2)g2f2g2(a2f2)(g2b2)qn(c3a2f2)(b2g2)(a2f2)"
  85.     PRINT "Tender and mild."
  86.     SPLAY "dq(g2e2c2)en(a2f2)qn(g2e2)(e2c2)a1g1"
  87.     PRINT "Sleep in heavenly peace...."
  88.     SPLAY "hn(d3b2bg2f2)qn(d2b2)dq(d2f2g2)enc3qn(b2g2f2)wn(e2g2c3)(e3c3g3)"
  89.     PRINT "Sleep in heavenly peace."
  90.     SPLAY "qn(c3g2e2c2)g2e2dq(g2f2d2b1)enf2qnd2wn(c2g1e1)qnc3g2d2"
  91.  
  92.  
  93. SUB SPLAY (Music$)
  94.  
  95.     'Set Defaults, just in case empty
  96.     IF Tempo = 0 THEN Tempo = 60
  97.     IF Meter = 0 THEN Meter = 3
  98.     IF NoteValue = 0 THEN NoteValue = 1
  99.  
  100.     Music$ = UCASE$(Music$)
  101.     cur = 1
  102.  
  103.     DO
  104.  
  105.         'skip any spaces
  106.         IF MID$(Music$, cur, 1) = " " THEN cur = cur + 1
  107.  
  108.         'Check for tempo
  109.         IF MID$(Music$, cur, 1) = "T" THEN
  110.             cur = cur + 1
  111.             Tempo = VAL(MID$(Music$, cur, 3)): cur = cur + 3
  112.         END IF
  113.  
  114.         'Check for Meter
  115.         IF MID$(Music$, cur, 1) = "M" THEN
  116.             cur = cur + 1
  117.             Meter = VAL(MID$(Music$, cur, 1)): cur = cur + 1
  118.         END IF
  119.  
  120.         'Get notevalue
  121.         SELECT CASE MID$(Music$, cur, 2)
  122.             CASE IS = "DQ": cur = cur + 2: NoteValue = 1.5
  123.             CASE IS = "EN": cur = cur + 2: NoteValue = .5
  124.             CASE IS = "QN": cur = cur + 2: NoteValue = 1
  125.             CASE IS = "HN": cur = cur + 2: NoteValue = 2
  126.             CASE IS = "WN": cur = cur + 2
  127.                 IF Meter = 3 THEN NoteValue = 3 ELSE NoteValue = 4
  128.             CASE IS = "SN": cur = cur + 2: NoteValue = .25
  129.         END SELECT
  130.  
  131.         'If regular note/rest found (not a group)
  132.         SELECT CASE MID$(Music$, cur, 2)
  133.             CASE IS = "E1": _SNDPLAYCOPY e1&: cur = cur + 2: _DELAY (60 * NoteValue / Tempo)
  134.             CASE IS = "F1": _SNDPLAYCOPY f1&: cur = cur + 2: _DELAY (60 * NoteValue / Tempo)
  135.             CASE IS = "G1": _SNDPLAYCOPY g1&: cur = cur + 2: _DELAY (60 * NoteValue / Tempo)
  136.             CASE IS = "A1": _SNDPLAYCOPY a1&: cur = cur + 2: _DELAY (60 * NoteValue / Tempo)
  137.             CASE IS = "B1": _SNDPLAYCOPY b1&: cur = cur + 2: _DELAY (60 * NoteValue / Tempo)
  138.             CASE IS = "C2": _SNDPLAYCOPY c2&: cur = cur + 2: _DELAY (60 * NoteValue / Tempo)
  139.             CASE IS = "D2": _SNDPLAYCOPY d2&: cur = cur + 2: _DELAY (60 * NoteValue / Tempo)
  140.             CASE IS = "E2": _SNDPLAYCOPY e2&: cur = cur + 2: _DELAY (60 * NoteValue / Tempo)
  141.             CASE IS = "F2": _SNDPLAYCOPY f2&: cur = cur + 2: _DELAY (60 * NoteValue / Tempo)
  142.             CASE IS = "G2": _SNDPLAYCOPY g2&: cur = cur + 2: _DELAY (60 * NoteValue / Tempo)
  143.             CASE IS = "A2": _SNDPLAYCOPY a2&: cur = cur + 2: _DELAY (60 * NoteValue / Tempo)
  144.             CASE IS = "B2": _SNDPLAYCOPY b2&: cur = cur + 2: _DELAY (60 * NoteValue / Tempo)
  145.             CASE IS = "C3": _SNDPLAYCOPY c3&: cur = cur + 2: _DELAY (60 * NoteValue / Tempo)
  146.             CASE IS = "D3": _SNDPLAYCOPY d3&: cur = cur + 2: _DELAY (60 * NoteValue / Tempo)
  147.             CASE IS = "E3": _SNDPLAYCOPY e3&: cur = cur + 2: _DELAY (60 * NoteValue / Tempo)
  148.             CASE IS = "RN": cur = cur + 2: _DELAY (60 * NoteValue / Tempo)
  149.         END SELECT
  150.  
  151.         'if group of notes found
  152.         IF MID$(Music$, cur, 1) = "(" THEN
  153.             cur = cur + 1
  154.             'Grab up until ')' found
  155.             Group$ = ""
  156.             DO
  157.                 a$ = MID$(Music$, cur, 1): cur = cur + 1
  158.                 IF a$ = ")" THEN EXIT DO
  159.                 IF a$ <> " " THEN Group$ = Group$ + a$
  160.             LOOP
  161.             FOR N = 1 TO LEN(Group$) STEP 2
  162.                 note$ = MID$(Group$, N, 2)
  163.                 IF note$ = "E1" THEN _SNDPLAYCOPY e1&
  164.                 IF note$ = "F1" THEN _SNDPLAYCOPY f1&
  165.                 IF note$ = "G1" THEN _SNDPLAYCOPY g1&
  166.                 IF note$ = "A1" THEN _SNDPLAYCOPY a1&
  167.                 IF note$ = "B1" THEN _SNDPLAYCOPY b1&
  168.                 IF note$ = "C2" THEN _SNDPLAYCOPY c2&
  169.                 IF note$ = "D2" THEN _SNDPLAYCOPY d2&
  170.                 IF note$ = "E2" THEN _SNDPLAYCOPY e2&
  171.                 IF note$ = "F2" THEN _SNDPLAYCOPY f2&
  172.                 IF note$ = "G2" THEN _SNDPLAYCOPY g2&
  173.                 IF note$ = "A2" THEN _SNDPLAYCOPY a2&
  174.                 IF note$ = "B2" THEN _SNDPLAYCOPY b2&
  175.                 IF note$ = "C3" THEN _SNDPLAYCOPY c3&
  176.                 IF note$ = "D3" THEN _SNDPLAYCOPY d3&
  177.                 IF note$ = "E3" THEN _SNDPLAYCOPY e3&
  178.             NEXT
  179.             _DELAY (60 * NoteValue / Tempo)
  180.         END IF
  181.  
  182.         IF cur >= LEN(Music$) THEN EXIT DO
  183.  
  184.         IF INKEY$ <> "" THEN EXIT SUB
  185.  
  186.     LOOP
  187.  
  188.     EXIT SUB
  189.  
  190.  




Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 15, 2020, 11:06:55 am
I see Santa's elves have been busy :)

@STxAxTIC  what fun to modify a Christmas Card or animation!
  [ This attachment cannot be displayed inline in 'Print Page' view ]  

I suspect Dav's been smitten by the Christmas spirits ;-))
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Dav on December 15, 2020, 11:30:52 am
I suspect Dav's been smitten by the Christmas spirits ;-))

Trying to get in the mood I guess.  Finding it harder to do that this year for some reason.

I just updated the SPLAY program posted above.  Fixed something, added something.

- Dav
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 15, 2020, 11:53:15 am
@Dav are the oggs all in separate folder? I have no problems with Explorer if I know where not to go with it but of course I use it to access the bas source. I find it easier to navigate (and perform file maintenance, like Delete, Copy, Move Files and Folders) in Explorer than QB64 IDE so I am in habit of using that specially for downloads. PS I don't visit my BlackJack files except through QB64 IDE because of the oggs.
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Dav on December 15, 2020, 11:56:17 am
No folders in the zip, just the .OGG files and the BAS zipped up altogether.  I forget whats the right way to include the .OGG files -- put them in a separate folder?

- Dav
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 15, 2020, 12:05:32 pm
No folders in the zip, just the .OGG files and the BAS zipped up altogether.  I forget whats the right way to include the .OGG files -- put them in a separate folder?

- Dav

Yes Oggs in separate and marked folder, for me and I suspect for Windows users that aren't very tech savvy (two v's ??). It's just Windows 10 (only?) Explorer without the downloaded patch you have to get at the Windows Store which means getting an account and possibly being barraged with more Windows updates, notifications or spam.
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Petr on December 15, 2020, 12:41:49 pm
@Dav Very nice work. For me, this is a very exemplary explanation of notes. I saved the program, I have to study it properly in the future.

@STxAxTIC very nice program. Do I see it supposed to simulate something like thermal flow? So I wouldn't dare do that. Just the idea of doing this is just brilliant.
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 15, 2020, 12:57:22 pm
Quote
@STxAxTIC very nice program. Do I see it supposed to simulate something like thermal flow? So I wouldn't dare do that. Just the idea of doing this is just brilliant.

Yeah when I just ran FluidCraft without any drawing, I was reminded of my Particles Fountain only taken to a way higher level.
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Dav on December 15, 2020, 01:06:53 pm
@Petr: Thanks!

@bplus: I repackaged the ZIP, putting the ogg files in a separate folder named ogg/.

I also added the option of including rests in the songs now. New ZIP and code.

- Dav
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 15, 2020, 01:12:01 pm
Quote
@bplus: I repackaged the ZIP, putting the ogg files in a separate folder named ogg/.

Thanks @Dav what's your favorite charity?

Update: Beautiful! Soothing for the kind of year we've all had.
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: johnno56 on December 15, 2020, 01:27:36 pm
OK. Source code upgraded, font is now in the source code.  Try it again, please.  It is running correctly under Windows. (previous version also)

Petr,

Thank you for the upgrade. Everything functions as it should.

Very nicely done! Great job!

J
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Dav on December 15, 2020, 05:44:15 pm
@bplus: Glad you enjoy the program!

Thanks @Dav what's your favorite charity?

As far as donations go, I don't have a favorite. Me and extra money don't seem to meet that often -- so my contributions are of a local volunteering nature.  Sometime those TV commercials (like for the hospital that helps sick kids 100% free) nearly makes my eyes puddle up and wish I did have money to contribute to charities.

- Dav
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: SierraKen on December 15, 2020, 06:19:41 pm
That's really awesome Dav! When I made my Starfield Clock I thought about something like this for the hourly chimes. Right now it only has the PLAY command. You did an impressive job here. Do you mind if I use 1 or 2 of your .ogg sound files for my clock? But I need to know something first, can the chimes play when there's other things going on in the background? That is why I couldn't use the chime example I found a long time ago.
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Dav on December 15, 2020, 06:39:14 pm
@SierraKen: Thanks! Sure, you may use anything i make and post here in your projects.  The way the SPLAY SUB is set up (with my added delay) the sound playback would suspend your clock from running while chiming. But you could easily adapt the code to eliminate that problem. Cool thing about _SNDPLAYCOPY is that it won't suspend your program while playing a sound. All you need to do is call the sounds from in your main program (forget the SPLAY SUB) and perhaps set a special TIMER for calling each note in your main loop.

- Dav
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: SierraKen on December 15, 2020, 10:17:25 pm
Thanks Dav, I tried for a bit tonight but couldn't figure it out, it kept making the sound a bunch of times on each chime. But that's OK, I'm satisfied with what I have. :) If I decide to check it out later I might.
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: SMcNeill on December 17, 2020, 03:36:59 pm
Here's a little something Xmassy which I tossed together this afternoon.  It works better (as in much faster) with external files, but part of the rules here said we should avoid those, so this is what I've got at the moment:

[edit]

Grab the attachment below and run it; the data length in the BAS file is too large for the forum database to handle properly, and can't be included in a post.

If I'd known I couldn't get this to load as is, I wouldn't have bothered to turn it into a singluar file and would've just kept everything externally available.  :P

Ah well...  Now I need to decide what I want to do next to it (if anything).  I'm thinking of having Santa fly across the screen in his sled, with a ribbon trailing behind him, showing the words of the song as it plays for us...   And then maybe making this a screensaver for the holidays, on a soundplay loop...

Or maybe I'll just leave it as it is, and not worry over it...

I dunno yet what I'm going to end up doing with it, but here's my little Xmas contribution!
 
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Dav on December 17, 2020, 04:53:36 pm
Well that's pretty, Steve.  I really like the floating snow effect.  Has a nice lilt to it that makes it more like snow than just dropping like rain drops.  Good screensaver.

Took a while for the converting on my slower laptop, but worth the wait.  Nice converting functions there you made....
 
- Dav
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: SMcNeill on December 17, 2020, 05:12:26 pm
Well that's pretty, Steve.  I really like the floating snow effect.  Has a nice lilt to it that makes it more like snow than just dropping like rain drops.  Good screensaver.

Took a while for the converting on my slower laptop, but worth the wait.  Nice converting functions there you made....
 
- Dav

If you're just interested in the conversion routines, you can find them alone here: https://www.qb64.org/forum/index.php?topic=3379.msg126862#msg126862

Compress and convert images/sound/resource files to BASE-128 encoding, so we can use them internally in DATA statements without any problems.  They need to be optimized for speed (use of readbit and setbit would help a lot, but they weren't in our language when I first did these routines), but they're functional and usage can often be hidden behind a startup splash screen, or such, in many cases.  ;)
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: SierraKen on December 17, 2020, 05:24:58 pm
Amazing Steve, very nice.
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 18, 2020, 02:31:52 am
Beautiful snow scene Steve!

I finally found an oldie I did in 2015 and translated it to QB64 with some mods:
Code: QB64: [Select]
  1. _TITLE "Sierpinski Decorated" 'b+ 2020-12-18 finally found this oldie
  2. 'sierpinski decorated.bas 2015-12-06 SmallBASIC 0.12.1 [B+=MGA]
  3. 'Thanks to PeterMaria W for code snips
  4. CONST SSQ = 700, horizon = 485 ' Side of Square Screen
  5. DIM SHARED QB(15) 'modified old QB 16 color system
  6. QB(0) = &HFF000000
  7. QB(1) = &HFF000088
  8. QB(2) = &HFF008800
  9. QB(3) = &HFF008888
  10. QB(4) = &HFF880000
  11. QB(5) = &HFF880088
  12. QB(6) = &HFF888800
  13. QB(7) = &HFFCCCCCC
  14. QB(8) = &HFF888888
  15. QB(9) = &HFF0000FF
  16. QB(10) = &HFF00FF00
  17. QB(11) = &HFF00FFFF
  18. QB(12) = &HFFFF0000
  19. QB(13) = &HFFFF00FF
  20. QB(14) = &HFFFFFF00
  21. QB(15) = &HFFFFFFFF
  22.  
  23. SCREEN _NEWIMAGE(SSQ + 100, SSQ, 32)
  24. _DELAY .25
  25.  
  26. xplus = SSQ
  27. yplus = horizon
  28. nstars = 100
  29. DIM xstar(100), ystar(100), rstar(100)
  30. FOR i = 1 TO 100
  31.     xstar(i) = RND * (SSQ + 100): ystar(i) = RND * horizon:
  32.     IF i < 75 THEN
  33.         rstar(i) = 0
  34.     ELSEIF i < 95 THEN
  35.         rstar(i) = 1
  36.     ELSE
  37.         rstar(i) = 2
  38.     END IF
  39.     CLS
  40.     FOR i = 0 TO horizon
  41.         LINE (0, i)-(SSQ + 100, i), _RGB32(i / horizon * 70, i / horizon * 22, 60 * (i) / horizon)
  42.     NEXT
  43.     land = SSQ - horizon
  44.     FOR i = horizon TO SSQ
  45.         cc = 128 + (i - horizon) / land * 127
  46.         LINE (0, i)-(SSQ + 100, i), _RGB32(cc, cc, cc)
  47.     NEXT
  48.     FOR i = 1 TO 100
  49.         fcirc xstar(i), ystar(i), rstar(i), QB(11)
  50.     NEXT
  51.     pinetree 200, 100
  52.     star xplus, yplus
  53.     xdist = 420 - xplus
  54.     xplus = xplus + .1 * xdist
  55.     ydist = 80 - yplus
  56.     yplus = yplus + .1 * ydist
  57.     _DISPLAY
  58.     _LIMIT 7
  59.  
  60. SUB star (x, y)
  61.     fcirc x, y, 3, &HFFAAFF00
  62.     LINE (x - 7, y)-(x - 3, y), &HFFAAFF00
  63.     LINE (x + 3, y)-(x + 7, y), &HFFAAFF00
  64.     LINE (x, y - 7)-(x, y - 3), &HFFAAFF00
  65.     LINE (x, y + 3)-(x, y + 7), &HFFAAFF00
  66.     IF x > 419 AND x < 421 AND y > 79 AND y < 81 THEN
  67.         CIRCLE (x, y), 12, &HFFAAFF00
  68.         COLOR &HFFFFFF88, &H00000000
  69.         Text 35, horizon + 90, 85, &HFFAA0000, "Seasons Greetings"
  70.         sier 210, 125, 420, 340
  71.         SLEEP
  72.     END IF
  73.  
  74. SUB sier (tlx, tly, width, height)
  75.     ' Sierpinski Christmas.bas modified from Petermaria's
  76.     ax = tlx
  77.     ay = tly + height
  78.     bx = tlx + width
  79.     by = tly + height
  80.     cx = tlx + width / 2
  81.     cy = tly
  82.     px = tlx
  83.     py = tly + height
  84.     FOR n = 0 TO 4000
  85.         fcirc px, py, 2, QB(INT(RND * 16))
  86.         SELECT CASE INT(RND * 3)
  87.             CASE 0
  88.                 px = (px + ax) / 2.0
  89.                 py = (py + ay) / 2.0
  90.             CASE 1
  91.                 px = (px + bx) / 2.0
  92.                 py = (py + by) / 2.0
  93.             CASE 2
  94.                 px = (px + cx) / 2.0
  95.                 py = (py + cy) / 2.0
  96.         END SELECT
  97.     NEXT
  98.     _DISPLAY
  99.  
  100. SUB pinetree (x, y)
  101.     'tannen baum by PeterMaria W  orig 440x460
  102.     bpx = 220: bpy = 410
  103.     tpx = bpx
  104.     FOR aa = -4 TO 4
  105.         bpxx = bpx + aa
  106.         bpyy = bpy - 390
  107.         LINE (x + bpxx, y + bpy)-(x + bpx, y + bpyy), _RGB32(30, 30, 0)
  108.     NEXT
  109.     ra = 160
  110.     tpy = bpy - 40
  111.     FOR ht = 1 TO 40
  112.         FOR xs = -100 TO 100 STEP 40
  113.             xsh = xs / 100
  114.             rs = RND * 4 / 10
  115.             tpxx = tpx + (xsh * ra)
  116.             tpyy = tpy - rs * ra
  117.             LINE (x + tpx, y + tpy)-(x + tpxx, y + tpyy), _RGB32(50, 40, 20)
  118.             FOR aa = 1 TO 30
  119.                 fra = RND * 10 / 10 * ra
  120.                 x1 = tpx + (xsh * fra)
  121.                 y1 = tpy - rs * fra
  122.                 x2 = tpx + xsh * (fra + ra / 5)
  123.                 y2 = tpy - rs * fra + (-rs + (RND * 8) / 10 - 0.4) * (ra / 5)
  124.                 LINE (x + x1, y + y1)-(x + x2, y + y2), _RGB32(RND * 120, RND * 70 + 70, RND * 80)
  125.             NEXT
  126.         NEXT
  127.         ra = ra - 4
  128.         tpy = tpy - 9
  129.     NEXT
  130.     _DISPLAY
  131.  
  132. 'from Steve Gold standard
  133. SUB fcirc (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  134.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  135.     DIM X AS INTEGER, Y AS INTEGER
  136.     Radius = ABS(R): RadiusError = -Radius: X = Radius: Y = 0
  137.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  138.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  139.     WHILE X > Y
  140.         RadiusError = RadiusError + Y * 2 + 1
  141.         IF RadiusError >= 0 THEN
  142.             IF X <> Y + 1 THEN
  143.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  144.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  145.             END IF
  146.             X = X - 1
  147.             RadiusError = RadiusError - X * 2
  148.         END IF
  149.         Y = Y + 1
  150.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  151.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  152.     WEND
  153.  
  154. SUB Text (x, y, textHeight, K AS _UNSIGNED LONG, txt$)
  155.     DIM fg AS _UNSIGNED LONG, cur&, I&, multi, xlen
  156.     fg = _DEFAULTCOLOR
  157.     'screen snapshot
  158.     cur& = _DEST
  159.     I& = _NEWIMAGE(8 * LEN(txt$), 16, 32)
  160.     _DEST I&
  161.     COLOR K, _RGBA32(0, 0, 0, 0)
  162.     _PRINTSTRING (0, 0), txt$
  163.     multi = textHeight / 16
  164.     xlen = LEN(txt$) * 8 * multi
  165.     _PUTIMAGE (x, y)-STEP(xlen, textHeight), I&, cur&
  166.     COLOR fg
  167.     _FREEIMAGE I&
  168.  
  169.  
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Petr on December 18, 2020, 02:57:30 am
Very nice work, @Steve. Your program is also IDE destructor :) - goto to row with DATA and press "end" key on the keyboard :) That's why I cut long strings to 450 characters per line to do our IDE well.

@Nice work, BPlus! Better tree than mine :)
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Dav on December 18, 2020, 08:13:09 am
Nice one, @bplus

I was looking for an Christmas oldie to post too, but I think it was on my HD that died.  Anyone happen to save that old school Jingle Bell piano thing I posted a few years ago on the [abandoned, outdated and now likely malicious qb64 dot net website - don’t go there] forum?  It played jingle bells while showing the piano keyboard playing the notes, and displayed the words. 

- Dav
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: _vince on December 18, 2020, 09:31:05 am
Nice work guys, I hope I can contribute something when I get some free time soon.

An honorable mention is TheBOB's christmas train.  It would get posted on TQBF every year as a tradition, would be nice if someone can pull it up and/or translate it to QB64. (@Pete ?)
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 18, 2020, 11:09:21 am
Nice work guys, I hope I can contribute something when I get some free time soon.

An honorable mention is TheBOB's christmas train.  It would get posted on TQBF every year as a tradition, would be nice if someone can pull it up and/or translate it to QB64. (@Pete ?)

Here 'tis: https://www.qb64.org/forum/index.php?topic=820.msg100360#msg100360
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: STxAxTIC on December 18, 2020, 11:20:58 am
Here is the Sanctum Winter Wonderland update. Let it load, and walk forward. Look all around, find the snowmen and the christmas trees. When you're bored with that, you can wander some more: through the desert, up in space, inside a planet -- or you may go down, down, down all the way to hell.

Code: QB64: [Select]
  1. ' Version 2020-12-18
  2.  
  3.  
  4. _TITLE "Sanctum"
  5.  
  6. ' Hardware.
  7. 'SCREEN _NEWIMAGE(640, 480, 32)
  8. SCREEN _NEWIMAGE(800, 600, 32)
  9. 'SCREEN _NEWIMAGE(1024, 768, 32)
  10.  
  11. ' Meta
  12.  
  13. ' Color constants.
  14. CONST Aquamarine = _RGB32(127, 255, 212)
  15. CONST Black = _RGB32(0, 0, 0)
  16. CONST Blue = _RGB32(0, 0, 255)
  17. CONST BlueViolet = _RGB32(138, 43, 226)
  18. CONST Chocolate = _RGB32(210, 105, 30)
  19. CONST Cyan = _RGB32(0, 255, 255)
  20. CONST DarkBlue = _RGB32(0, 0, 139)
  21. CONST DarkGoldenRod = _RGB32(184, 134, 11)
  22. CONST DarkGray = _RGB32(169, 169, 169)
  23. CONST DarkKhaki = _RGB32(189, 183, 107)
  24. CONST DeepPink = _RGB32(255, 20, 147)
  25. CONST DodgerBlue = _RGB32(30, 144, 255)
  26. CONST ForestGreen = _RGB32(34, 139, 34)
  27. CONST Gray = _RGB32(128, 128, 128)
  28. CONST Green = _RGB32(0, 128, 0)
  29. CONST Indigo = _RGB32(75, 0, 130)
  30. CONST Ivory = _RGB32(255, 255, 240)
  31. CONST LightSeaGreen = _RGB32(32, 178, 170)
  32. CONST Lime = _RGB32(0, 255, 0)
  33. CONST LimeGreen = _RGB32(50, 205, 50)
  34. CONST Magenta = _RGB32(255, 0, 255)
  35. CONST PaleGoldenRod = _RGB32(238, 232, 170)
  36. CONST Purple = _RGB32(128, 0, 128)
  37. CONST Red = _RGB32(255, 0, 0)
  38. CONST RoyalBlue = _RGB32(65, 105, 225)
  39. CONST SaddleBrown = _RGB32(139, 69, 19)
  40. CONST Sienna = _RGB32(160, 82, 45)
  41. CONST SlateGray = _RGB32(112, 128, 144)
  42. CONST Snow = _RGB32(255, 250, 250)
  43. CONST Sunglow = _RGB32(255, 207, 72)
  44. CONST SunsetOrange = _RGB32(253, 94, 83)
  45. CONST Teal = _RGB32(0, 128, 128)
  46. CONST White = _RGB32(255, 255, 255)
  47. CONST Yellow = _RGB32(255, 255, 0)
  48.  
  49. ' Mathematical constants.
  50. CONST pi = 4 * ATN(1)
  51. CONST ee = EXP(1)
  52.  
  53. ' Types.
  54.  
  55. TYPE Vector
  56.     x AS DOUBLE
  57.     y AS DOUBLE
  58.     z AS DOUBLE
  59.  
  60. TYPE Camera
  61.     Position AS Vector
  62.     Velocity AS Vector
  63.     Shade AS _UNSIGNED LONG
  64.  
  65. TYPE ClusterElement
  66.     Index AS LONG
  67.     FirstGroup AS LONG
  68.     LastGroup AS LONG
  69.     Centroid AS Vector
  70.     Velocity AS Vector
  71.     Visible AS INTEGER
  72.     MotionType AS INTEGER
  73.  
  74. TYPE GroupElement
  75.     Identity AS LONG
  76.     GroupName AS STRING
  77.     Pointer AS LONG
  78.     Lagger AS LONG
  79.     Volume AS Vector
  80.     FirstVector AS LONG
  81.     LastVector AS LONG
  82.     Centroid AS Vector
  83.     Velocity AS Vector
  84.     Visible AS INTEGER
  85.     Distance2 AS DOUBLE
  86.  
  87. TYPE MissionGroup
  88.     Label AS STRING
  89.     Discovered AS INTEGER
  90.  
  91. ' Scale.
  92. DIM SHARED bignumber AS LONG
  93. bignumber = 6000000
  94.  
  95. ' Cluster setup.
  96. DIM SHARED ClusterIndexTicker AS LONG
  97. DIM SHARED ClusterFillCounter AS INTEGER
  98. DIM SHARED Cluster(bignumber / 100) AS ClusterElement
  99. ClusterIndexTicker = 0
  100. ClusterFillCounter = 0
  101.  
  102. ' Group linked list setup.
  103. DIM SHARED Group(bignumber / 10) AS GroupElement
  104. DIM SHARED GroupIdTicker AS LONG
  105. GroupIdTicker = 0
  106.  
  107. ' Path
  108. DIM SHARED FixedPath(25, 86400) AS Vector
  109. DIM SHARED PathIndexTicker AS LONG
  110. PathIndexTicker = 0
  111.  
  112. ' Basis vectors defined in three-space.
  113. DIM SHARED xhat(3), yhat(3), zhat(3)
  114. xhat(1) = 1: xhat(2) = 0: xhat(3) = 0
  115. yhat(1) = 0: yhat(2) = 1: yhat(3) = 0
  116. zhat(1) = 0: zhat(2) = 0: zhat(3) = 1
  117.  
  118. ' Camera orientation vectors.
  119. DIM SHARED uhat(3), vhat(3), nhat(3)
  120.  
  121. ' Camera position.
  122. DIM SHARED PlayerCamera AS Camera
  123.  
  124. ' Field-of-view distance.
  125. DIM SHARED fovd
  126. fovd = -192
  127.  
  128. ' Clipping planes.
  129. DIM SHARED nearplane(4), farplane(4), rightplane(4), leftplane(4), topplane(4), bottomplane(4)
  130. nearplane(4) = 1
  131. farplane(4) = -180
  132. rightplane(4) = -17 ' (17=35/2=tilesize/2 looks better than 1.)
  133. leftplane(4) = -17
  134. topplane(4) = -17
  135. bottomplane(4) = -17
  136.  
  137. ' World vectors.
  138. DIM SHARED vec(bignumber, 3) ' Relative Position
  139. DIM SHARED vec3Dpos(bignumber, 3) ' Absolute osition
  140. DIM SHARED vec3Dvel(bignumber, 3) ' Linear velocity
  141. DIM SHARED vec3Dvis(bignumber) ' Visible toggle
  142. DIM SHARED vec2D(bignumber, 2) ' Projection onto 2D plane
  143. DIM SHARED vec3Dcolor(bignumber) AS LONG ' Original color
  144. DIM SHARED vec2Dcolor(bignumber) AS LONG ' Projected color
  145.  
  146. ' Mission.
  147. DIM SHARED MissionTicker AS INTEGER
  148. DIM SHARED Mission(20) AS MissionGroup
  149.  
  150. ' Interface.
  151. DIM SHARED ToggleHUD AS INTEGER
  152. DIM SHARED ToggleAnimate AS INTEGER
  153. DIM SHARED FPSReport AS INTEGER
  154. DIM SHARED NumClusterVisible AS LONG
  155. DIM SHARED NumVectorVisible AS LONG
  156. DIM SHARED NumGroupVisible AS LONG
  157. DIM SHARED ClosestGroup AS LONG
  158.  
  159. ' Initialize.
  160. ToggleAnimate = 1
  161. ToggleHUD = 1
  162. PlayerCamera.Position.x = -40
  163. PlayerCamera.Position.y = 500 '30
  164. PlayerCamera.Position.z = 40
  165. uhat(1) = COS(0): uhat(2) = SIN(0): uhat(3) = 0
  166. vhat(1) = 0: vhat(2) = 0: vhat(3) = 1
  167. CALL CalculateScreenVectors
  168.  
  169. ' Prime main loop.
  170. CALL CreateLevel
  171. CALL CreateMission(10)
  172.  
  173. ' Start main loop.
  174. CALL MainLoop
  175.  
  176.  
  177. ' Subs and Functions
  178.  
  179. SUB CreateMission (ListSize AS INTEGER)
  180.     DIM k AS INTEGER
  181.     DIM a AS STRING
  182.     DIM b AS STRING
  183.     a = ""
  184.     b = ""
  185.     REDIM MissionPool(0) AS STRING
  186.  
  187.     '''
  188.     REDIM _PRESERVE MissionPool(UBOUND(MissionPool) + 1): MissionPool(UBOUND(MissionPool)) = "Atmospheric dust"
  189.     REDIM _PRESERVE MissionPool(UBOUND(MissionPool) + 1): MissionPool(UBOUND(MissionPool)) = "Black hole"
  190.     REDIM _PRESERVE MissionPool(UBOUND(MissionPool) + 1): MissionPool(UBOUND(MissionPool)) = "Cloudy sky"
  191.     REDIM _PRESERVE MissionPool(UBOUND(MissionPool) + 1): MissionPool(UBOUND(MissionPool)) = "Comet 1"
  192.     REDIM _PRESERVE MissionPool(UBOUND(MissionPool) + 1): MissionPool(UBOUND(MissionPool)) = "Comet 2"
  193.     REDIM _PRESERVE MissionPool(UBOUND(MissionPool) + 1): MissionPool(UBOUND(MissionPool)) = "Comet 3"
  194.     REDIM _PRESERVE MissionPool(UBOUND(MissionPool) + 1): MissionPool(UBOUND(MissionPool)) = "Demon orb"
  195.     REDIM _PRESERVE MissionPool(UBOUND(MissionPool) + 1): MissionPool(UBOUND(MissionPool)) = "Dirt and sand"
  196.     REDIM _PRESERVE MissionPool(UBOUND(MissionPool) + 1): MissionPool(UBOUND(MissionPool)) = "Grave"
  197.     REDIM _PRESERVE MissionPool(UBOUND(MissionPool) + 1): MissionPool(UBOUND(MissionPool)) = "Hell sparks"
  198.     REDIM _PRESERVE MissionPool(UBOUND(MissionPool) + 1): MissionPool(UBOUND(MissionPool)) = "Laser"
  199.     REDIM _PRESERVE MissionPool(UBOUND(MissionPool) + 1): MissionPool(UBOUND(MissionPool)) = "Lush terrain"
  200.     REDIM _PRESERVE MissionPool(UBOUND(MissionPool) + 1): MissionPool(UBOUND(MissionPool)) = "Tornado 1"
  201.     REDIM _PRESERVE MissionPool(UBOUND(MissionPool) + 1): MissionPool(UBOUND(MissionPool)) = "Tornado 2"
  202.     REDIM _PRESERVE MissionPool(UBOUND(MissionPool) + 1): MissionPool(UBOUND(MissionPool)) = "Tornado 3"
  203.     REDIM _PRESERVE MissionPool(UBOUND(MissionPool) + 1): MissionPool(UBOUND(MissionPool)) = "Planet center"
  204.     REDIM _PRESERVE MissionPool(UBOUND(MissionPool) + 1): MissionPool(UBOUND(MissionPool)) = "Planet column"
  205.     REDIM _PRESERVE MissionPool(UBOUND(MissionPool) + 1): MissionPool(UBOUND(MissionPool)) = "Planet interior"
  206.     REDIM _PRESERVE MissionPool(UBOUND(MissionPool) + 1): MissionPool(UBOUND(MissionPool)) = "Plasma core"
  207.     REDIM _PRESERVE MissionPool(UBOUND(MissionPool) + 1): MissionPool(UBOUND(MissionPool)) = "Pyramid"
  208.     REDIM _PRESERVE MissionPool(UBOUND(MissionPool) + 1): MissionPool(UBOUND(MissionPool)) = "Rain"
  209.     REDIM _PRESERVE MissionPool(UBOUND(MissionPool) + 1): MissionPool(UBOUND(MissionPool)) = "Singularity"
  210.     REDIM _PRESERVE MissionPool(UBOUND(MissionPool) + 1): MissionPool(UBOUND(MissionPool)) = "Snowman 1"
  211.     REDIM _PRESERVE MissionPool(UBOUND(MissionPool) + 1): MissionPool(UBOUND(MissionPool)) = "Snowman 2"
  212.     REDIM _PRESERVE MissionPool(UBOUND(MissionPool) + 1): MissionPool(UBOUND(MissionPool)) = "Snowman 3"
  213.     REDIM _PRESERVE MissionPool(UBOUND(MissionPool) + 1): MissionPool(UBOUND(MissionPool)) = "Tree 1"
  214.     REDIM _PRESERVE MissionPool(UBOUND(MissionPool) + 1): MissionPool(UBOUND(MissionPool)) = "Tree 2"
  215.     REDIM _PRESERVE MissionPool(UBOUND(MissionPool) + 1): MissionPool(UBOUND(MissionPool)) = "Tree 3"
  216.  
  217.     '''
  218.  
  219.     MissionTicker = 0
  220.     DO
  221.         k = 1 + INT(RND * UBOUND(MissionPool))
  222.         a = MissionPool(k)
  223.         IF (INSTR(b, a) = 0) THEN
  224.             b = b + a
  225.             MissionTicker = MissionTicker + 1
  226.             Mission(MissionTicker).Label = a
  227.             Mission(MissionTicker).Discovered = 0
  228.         END IF
  229.     LOOP UNTIL (MissionTicker = ListSize)
  230.  
  231. SUB CreateLevel
  232.     DIM gtmp AS LONG
  233.     DIM p AS LONG
  234.     DIM n AS SINGLE
  235.     DIM i, j, k AS SINGLE
  236.     DIM u, v, w AS SINGLE
  237.     DIM x0, y0, z0 AS SINGLE
  238.  
  239.     ' Initialize linked list.
  240.     gtmp = CreateNewGroup&(0, 0, 0, 0, 0, 1)
  241.  
  242.     LOCATE 1, 1: PRINT "Loading..." + STR$(INT(100 * Group(gtmp).LastVector / bignumber)) + "%": _DISPLAY
  243.  
  244.     ' Atmospheric dust
  245.     FOR u = -1400 TO 1400 - 350 STEP 350
  246.         FOR v = -1400 TO 1400 - 350 STEP 350
  247.             FOR i = u TO u + 350 STEP 35
  248.                 FOR j = v TO v + 350 STEP 35
  249.                     FOR w = (100 + 35 / 2) TO (800 - 35 + 35 / 2) STEP 35
  250.                         gtmp = NewCube&(gtmp, "Atmospheric dust", 5 * (1 - w / 800), i, j, w, 35, 35, 35, DarkGray, White, Snow, -1)
  251.                     NEXT
  252.                 NEXT
  253.             NEXT
  254.             CALL ClusterPinch(gtmp)
  255.         NEXT
  256.     NEXT
  257.     CALL ClusterPinch(gtmp)
  258.     LOCATE 1, 1: PRINT "Loading..." + STR$(INT(100 * Group(gtmp).LastVector / bignumber)) + "%": _DISPLAY
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.     'GOTO moo
  270.  
  271.  
  272.  
  273.  
  274.  
  275.  
  276.     ' Black hole
  277.     k = RND * 2 * pi
  278.     x0 = 1000 * COS(k)
  279.     y0 = 1000 * SIN(k)
  280.     z0 = 300
  281.     i = 100
  282.     j = 25
  283.     FOR u = -i TO i STEP j
  284.         FOR v = -i TO i STEP j
  285.             FOR w = -i TO i STEP j
  286.                 k = SQR(u * u + v * v + w * w)
  287.                 IF k <= i AND k >= i - j THEN
  288.                     gtmp = NewCube&(gtmp, "Black hole", j, x0 + u, y0 + v, z0 + w, j, j, j, DarkGray, White, Snow, -1)
  289.                     CALL SetParticleVelocity(gtmp, -.25 * u / k, -.25 * v / k, -.25 * w / k)
  290.                 END IF
  291.             NEXT
  292.         NEXT
  293.     NEXT
  294.     gtmp = NewShell&("Singularity", 10, x0, y0, z0, Black, Black, Black, 2, 5, -1)
  295.     LOCATE 1, 1: PRINT "Loading..." + STR$(INT(100 * Group(gtmp).LastVector / bignumber)) + "%": _DISPLAY
  296.  
  297.     ' Comet
  298.     FOR n = 1 TO 3
  299.         u = RND * 2 * pi
  300.         PathIndexTicker = PathIndexTicker + 1
  301.         FOR p = 1 TO 86400
  302.             FixedPath(PathIndexTicker, p).x = .25 * COS(u + 2 * pi * (24 * 60) * (p - 1) / 86400)
  303.             FixedPath(PathIndexTicker, p).y = .25 * SIN(u + 2 * pi * (24 * 60) * (p - 1) / 86400)
  304.             FixedPath(PathIndexTicker, p).z = .15 * COS(u + 2 * pi * (24 * 60) * (p - 1) / 86400)
  305.         NEXT
  306.         x0 = 150 + (RND - .5) * 2 * 550
  307.         y0 = 150 + (RND - .5) * 2 * 550
  308.         z0 = 200 + RND * 100
  309.         gtmp = NewCube&(gtmp, "Comet" + STR$(n), 300, x0, y0, z0, 25, 25, 25, Teal, Cyan, DodgerBlue, PathIndexTicker)
  310.         FOR k = Group(gtmp).FirstVector TO Group(gtmp).LastVector
  311.             vec3Dvel(k, 1) = (RND - .5) * .20
  312.             vec3Dvel(k, 2) = (RND - .5) * .20
  313.             vec3Dvel(k, 3) = (RND - .5) * .20
  314.         NEXT
  315.         gtmp = NewShell&("Comet" + STR$(n), 15, x0, y0, z0, Teal, Cyan, DodgerBlue, 1, 80, PathIndexTicker)
  316.         CALL ClusterPinch(gtmp)
  317.     NEXT
  318.     LOCATE 1, 1: PRINT "Loading..." + STR$(INT(100 * Group(gtmp).LastVector / bignumber)) + "%": _DISPLAY
  319.  
  320.     ' Demon orb
  321.     FOR n = 1 TO 6
  322.         u = RND * 2 * pi
  323.         PathIndexTicker = PathIndexTicker + 1
  324.         FOR p = 1 TO 86400
  325.             FixedPath(PathIndexTicker, p).x = .25 * COS(u + 2 * pi * (24 * 60) * (p - 1) / 86400)
  326.             FixedPath(PathIndexTicker, p).y = .25 * SIN(u + 2 * pi * (24 * 60) * (p - 1) / 86400)
  327.             FixedPath(PathIndexTicker, p).z = .15 * COS(u + 2 * pi * (24 * 60) * (p - 1) / 86400)
  328.         NEXT
  329.         x0 = (RND - .5) * 2 * 1000
  330.         y0 = (RND - .5) * 2 * 1000
  331.         z0 = -700 - RND * 100
  332.         gtmp = NewCube&(gtmp, "Demon orb", 300, x0, y0, z0, 25, 25, 25, Red, SunsetOrange, Sunglow, PathIndexTicker)
  333.         FOR k = Group(gtmp).FirstVector TO Group(gtmp).LastVector
  334.             vec3Dvel(k, 1) = (RND - .5) * .20
  335.             vec3Dvel(k, 2) = (RND - .5) * .20
  336.             vec3Dvel(k, 3) = (RND - .5) * .20
  337.         NEXT
  338.         gtmp = NewShell&("Demon orb", 15, x0, y0, z0, Red, SunsetOrange, Sunglow, 1, 80, PathIndexTicker)
  339.         CALL ClusterPinch(gtmp)
  340.     NEXT
  341.     LOCATE 1, 1: PRINT "Loading..." + STR$(INT(100 * Group(gtmp).LastVector / bignumber)) + "%": _DISPLAY
  342.  
  343.     ' Death Star
  344.     PathIndexTicker = PathIndexTicker + 1
  345.     FOR p = 1 TO 86400
  346.         FixedPath(PathIndexTicker, p).x = -.1 * COS(2 * pi * (24 * 60) * (p - 1) / 86400)
  347.         FixedPath(PathIndexTicker, p).y = -.1 * SIN(2 * pi * (24 * 60) * (p - 1) / 86400)
  348.         FixedPath(PathIndexTicker, p).z = 0
  349.     NEXT
  350.     x0 = 100 + (RND - .5) * 2 * 250
  351.     y0 = 100 + (RND - .5) * 2 * 250
  352.     gtmp = NewShell&("Death Star", 75, x0, y0, 400, Gray, DarkGray, White, 0, 0, PathIndexTicker)
  353.     gtmp = NewShell&("Death Star reactor", 15, x0, y0, 400, Cyan, Teal, Blue, 1, 20, PathIndexTicker)
  354.     gtmp = NewCube&(gtmp, "Plasma core", 300, x0, y0, 400, 25, 25, 25, Cyan, Teal, Blue, PathIndexTicker)
  355.     FOR p = Group(gtmp).FirstVector TO Group(gtmp).LastVector
  356.         vec3Dvel(p, 1) = (RND - .5) * .20
  357.         vec3Dvel(p, 2) = (RND - .5) * .20
  358.         vec3Dvel(p, 3) = (RND - .5) * .20
  359.     NEXT
  360.     FOR n = 10 TO 1 STEP -.5
  361.         gtmp = NewCube&(gtmp, "Laser", 300, x0 + 75 / SQR(2) + (n - 1) * 25, y0 + .5 * n * 25, 400 + 75 / SQR(2) + .5 * (n - 1) * 25, 25, 25, 25, Lime, Green, White, PathIndexTicker)
  362.         FOR p = Group(gtmp).FirstVector TO Group(gtmp).LastVector
  363.             vec3Dvel(p, 1) = (RND - .5) * .50
  364.             vec3Dvel(p, 2) = (RND - .5) * .50
  365.             vec3Dvel(p, 3) = (RND - .5) * .50
  366.         NEXT
  367.     NEXT
  368.     CALL ClusterPinch(gtmp)
  369.     LOCATE 1, 1: PRINT "Loading..." + STR$(INT(100 * Group(gtmp).LastVector / bignumber)) + "%": _DISPLAY
  370.  
  371.     ' Dirt and sand
  372.     FOR u = -1400 TO 1400 - 350 STEP 350
  373.         FOR v = -1400 TO 1400 - 350 STEP 350
  374.             FOR i = u TO u + 350 STEP 35
  375.                 FOR j = v TO v + 350 STEP 35
  376.                     FOR w = 0 - 35 / 2 TO -770 - 35 / 2 STEP -35
  377.                         gtmp = NewCube&(gtmp, "Dirt and sand", 5, i, j, w, 35, 35, 35, SaddleBrown, DarkKhaki, Sienna, -1)
  378.                     NEXT
  379.                 NEXT
  380.             NEXT
  381.             CALL ClusterPinch(gtmp)
  382.         NEXT
  383.     NEXT
  384.     CALL ClusterPinch(gtmp)
  385.     LOCATE 1, 1: PRINT "Loading..." + STR$(INT(100 * Group(gtmp).LastVector / bignumber)) + "%": _DISPLAY
  386.  
  387.     ' Grave and Pyramid (1/2)
  388.     k = RND * pi / 2 - pi / 4
  389.     x0 = 1000 * COS(k)
  390.     y0 = 1000 * SIN(k)
  391.     FOR u = x0 - 160 TO x0 + 160 STEP 80
  392.         FOR v = y0 - 160 TO y0 + 160 STEP 80
  393.             gtmp = NewCube&(gtmp, "Grave", 200, u, v, (1) * 10 - 10 / 2, 10, 10, 10, Gray, SlateGray, DarkGray, -1)
  394.             gtmp = NewCube&(gtmp, "Grave", 200, u, v, (2) * 10 - 10 / 2, 10, 10, 10, Gray, SlateGray, DarkGray, -1)
  395.             gtmp = NewCube&(gtmp, "Grave", 200, u, v, (3) * 10 - 10 / 2, 10, 10, 10, Gray, SlateGray, DarkGray, -1)
  396.             gtmp = NewCube&(gtmp, "Grave", 200, u - 10, v, (4) * 10 - 10 / 2, 10, 10, 10, Gray, SlateGray, DarkGray, -1)
  397.             gtmp = NewCube&(gtmp, "Grave", 200, u, v, (4) * 10 - 10 / 2, 10, 10, 10, Gray, SlateGray, DarkGray, -1)
  398.             gtmp = NewCube&(gtmp, "Grave", 200, u + 10, v, (4) * 10 - 10 / 2, 10, 10, 10, Gray, SlateGray, DarkGray, -1)
  399.             gtmp = NewCube&(gtmp, "Grave", 200, u, v, (5) * 10 - 10 / 2, 10, 10, 10, Gray, SlateGray, DarkGray, -1)
  400.         NEXT
  401.     NEXT
  402.     CALL ClusterPinch(gtmp)
  403.     LOCATE 1, 1: PRINT "Loading..." + STR$(INT(100 * Group(gtmp).LastVector / bignumber)) + "%": _DISPLAY
  404.  
  405.     ' Grave and Pyramid (2/2)
  406.     k = k + pi
  407.     x0 = 1000 * COS(k)
  408.     y0 = 1000 * SIN(k)
  409.     FOR w = 0 TO 75 STEP 15
  410.         FOR u = -75 + w TO 75 - w STEP 15
  411.             FOR v = -75 + w TO 75 - w STEP 15
  412.                 gtmp = NewCube&(gtmp, "Pyramid", 35, x0 + u, y0 + v, w, 13, 13, 13, DarkKhaki, SunsetOrange, DarkGoldenRod, -1)
  413.             NEXT
  414.         NEXT
  415.     NEXT
  416.     CALL ClusterPinch(gtmp)
  417.     LOCATE 1, 1: PRINT "Loading..." + STR$(INT(100 * Group(gtmp).LastVector / bignumber)) + "%": _DISPLAY
  418.  
  419.     ' Hell Sparks
  420.     FOR u = -1400 TO 1400 - 350 STEP 350
  421.         FOR v = -1400 TO 1400 - 350 STEP 350
  422.             FOR i = u TO u + 350 STEP 35
  423.                 FOR j = v TO v + 350 STEP 35
  424.                     gtmp = NewCube&(gtmp, "Hell sparks", 15, i, j, -850, 35, 35, 100, Red, SunsetOrange, Sunglow, -1)
  425.                     CALL SetParticleVelocity(gtmp, 0, 0, .75 + RND * .25)
  426.                 NEXT
  427.             NEXT
  428.         NEXT
  429.     NEXT
  430.     CALL ClusterPinch(gtmp)
  431.     LOCATE 1, 1: PRINT "Loading..." + STR$(INT(100 * Group(gtmp).LastVector / bignumber)) + "%": _DISPLAY
  432.  
  433.     ' Lake of Fire
  434.     gtmp = NewTerrain&("Lake of Fire", 2800, 2800, 35, 0, 0, -900, Red, SunsetOrange, Sunglow, 4, 30)
  435.     LOCATE 1, 1: PRINT "Loading..." + STR$(INT(100 * Group(gtmp).LastVector / bignumber)) + "%": _DISPLAY
  436.  
  437.     ' Planet
  438.     PathIndexTicker = PathIndexTicker + 1
  439.     FOR p = 1 TO 86400
  440.         FixedPath(PathIndexTicker, p).x = .1 * COS(2 * pi * (24 * 60) * (p - 1) / 86400)
  441.         FixedPath(PathIndexTicker, p).y = .1 * SIN(2 * pi * (24 * 60) * (p - 1) / 86400)
  442.         FixedPath(PathIndexTicker, p).z = 0
  443.     NEXT
  444.     x0 = 100 + (RND - .5) * 2 * 250
  445.     y0 = 100 + (RND - .5) * 2 * 250
  446.     gtmp = NewPlanet&(350, 35, x0, y0, 900, PathIndexTicker)
  447.     LOCATE 1, 1: PRINT "Loading..." + STR$(INT(100 * Group(gtmp).LastVector / bignumber)) + "%": _DISPLAY
  448.  
  449.     ' Rain
  450.     FOR u = -350 TO 350 STEP 35
  451.         FOR v = -350 TO 350 STEP 35
  452.             IF (u * u + v * v <= 350 ^ 2) THEN
  453.                 gtmp = NewCube&(gtmp, "Rain", 15, u, v, 50, 35, 35, 100, Blue, DodgerBlue, Blue, -1)
  454.                 CALL SetParticleVelocity(gtmp, 0, 0, -.75 - RND * .25)
  455.             END IF
  456.         NEXT
  457.     NEXT
  458.     CALL ClusterPinch(gtmp)
  459.     LOCATE 1, 1: PRINT "Loading..." + STR$(INT(100 * Group(gtmp).LastVector / bignumber)) + "%": _DISPLAY
  460.  
  461.     ' Realm of Heaven
  462.     gtmp = NewTerrain&("Realm of Heaven", 2800, 2800, 35, 0, 0, 1400, BlueViolet, Cyan, White, 4, 30)
  463.     LOCATE 1, 1: PRINT "Loading..." + STR$(INT(100 * Group(gtmp).LastVector / bignumber)) + "%": _DISPLAY
  464.  
  465.     ' Sky and Terrain: Center
  466.     gtmp = NewTerrain&("Cloudy sky", 1400, 1400, 35, 0, 0, 100, RoyalBlue, DarkGray, Snow, 4, 30)
  467.     gtmp = NewTerrain&("Lush terrain", 1400, 1400, 35, 0, 0, 0, Green, LightSeaGreen, Blue, 4, 30)
  468.     LOCATE 1, 1: PRINT "Loading..." + STR$(INT(100 * Group(gtmp).LastVector / bignumber)) + "%": _DISPLAY
  469.  
  470.     ' Sky and Terrain: North
  471.     gtmp = NewTerrain&("Northern winter sky", 2800, 700, 35, 0, 700 + 350, 100, White, DarkBlue, SlateGray, 4, 30)
  472.     gtmp = NewTerrain&("Northern winter terrain", 2800, 700, 35, 0, 700 + 350, 0, White, Snow, SlateGray, 4, 30)
  473.     LOCATE 1, 1: PRINT "Loading..." + STR$(INT(100 * Group(gtmp).LastVector / bignumber)) + "%": _DISPLAY
  474.  
  475.     ' Sky and Terrain: South
  476.     gtmp = NewTerrain&("Southern desert sky", 2800, 700, 35, 0, -700 - 350, 100, RoyalBlue, SunsetOrange, Indigo, 4, 30)
  477.     gtmp = NewTerrain&("Southern desert terrain", 2800, 700, 35, 0, -700 - 350, 0, DarkKhaki, PaleGoldenRod, Sunglow, 4, 30)
  478.     LOCATE 1, 1: PRINT "Loading..." + STR$(INT(100 * Group(gtmp).LastVector / bignumber)) + "%": _DISPLAY
  479.  
  480.     ' Sky and Terrain: West
  481.     gtmp = NewTerrain&("Western desert sky", 700, 1400, 35, -700 - 350, 0, 100, RoyalBlue, DarkGray, Indigo, 4, 30)
  482.     gtmp = NewTerrain&("Western desert terrain", 700, 1400, 35, -700 - 350, 0, 0, DarkKhaki, PaleGoldenRod, Sunglow, 4, 30)
  483.     LOCATE 1, 1: PRINT "Loading..." + STR$(INT(100 * Group(gtmp).LastVector / bignumber)) + "%": _DISPLAY
  484.  
  485.     ' Sky and Terrain: East
  486.     gtmp = NewTerrain&("Eastern desert sky", 700, 1400, 35, 700 + 350, 0, 100, RoyalBlue, DarkGray, Indigo, 4, 30)
  487.     gtmp = NewTerrain&("Eastern desert terrain", 700, 1400, 35, 700 + 350, 0, 0, DarkKhaki, PaleGoldenRod, Sunglow, 4, 30)
  488.     LOCATE 1, 1: PRINT "Loading..." + STR$(INT(100 * Group(gtmp).LastVector / bignumber)) + "%": _DISPLAY
  489.  
  490.     ' Snow
  491.     FOR u = -175 TO 175 STEP 35
  492.         FOR v = -175 TO 175 STEP 35
  493.             IF (u * u + v * v <= 175 ^ 2) THEN
  494.                 gtmp = NewCube&(gtmp, "Snow", 15, u, v + 1050, 50, 35, 35, 100, White, Snow, SlateGray, -1)
  495.                 CALL SetParticleVelocity(gtmp, 0, 0, -.75 - RND * .25)
  496.             END IF
  497.         NEXT
  498.     NEXT
  499.     CALL ClusterPinch(gtmp)
  500.     LOCATE 1, 1: PRINT "Loading..." + STR$(INT(100 * Group(gtmp).LastVector / bignumber)) + "%": _DISPLAY
  501.  
  502.     ' Snowman
  503.     FOR j = 1 TO 10
  504.         u = 5 + RND * 20
  505.         v = 0
  506.         x0 = RND * 2800
  507.         y0 = RND * 700 + 700
  508.         FOR n = 1 TO 3
  509.             z0 = u + v
  510.             gtmp = NewCube&(gtmp, "Snowman" + STR$(n), 300, x0, y0, z0, u * 2 / SQR(3), u * 2 / SQR(3), u * 2 / SQR(3), Teal, Cyan, DodgerBlue, -1)
  511.             FOR k = Group(gtmp).FirstVector TO Group(gtmp).LastVector
  512.                 vec3Dvel(k, 1) = (RND - .5) * .20
  513.                 vec3Dvel(k, 2) = (RND - .5) * .20
  514.                 vec3Dvel(k, 3) = (RND - .5) * .20
  515.             NEXT
  516.             gtmp = NewShell&("Snowman" + STR$(n), u, x0, y0, z0, Teal, Cyan, DodgerBlue, 1, 80, -1)
  517.             CALL ClusterPinch(gtmp)
  518.             v = v + 2 * u
  519.             u = u / 1.618
  520.         NEXT
  521.     NEXT
  522.     LOCATE 1, 1: PRINT "Loading..." + STR$(INT(100 * Group(gtmp).LastVector / bignumber)) + "%": _DISPLAY
  523.  
  524.     ' Tornado
  525.     FOR n = 1 TO 3
  526.         u = RND * 2 * pi
  527.         PathIndexTicker = PathIndexTicker + 1
  528.         FOR p = 1 TO 86400
  529.             FixedPath(PathIndexTicker, p).x = 1 * COS(u + 2 * pi * (24 * 60) * (p - 1) / 86400)
  530.             FixedPath(PathIndexTicker, p).y = 1 * SIN(u + 2 * pi * (24 * 60) * (p - 1) / 86400)
  531.             FixedPath(PathIndexTicker, p).z = 0
  532.         NEXT
  533.         x0 = (RND - .5) * 2 * 750
  534.         y0 = (RND - .5) * 2 * 750
  535.         FOR k = 1 TO 30
  536.             u = RND * 100
  537.             v = RND * u / 3
  538.             w = RND * 2 * pi
  539.             gtmp = NewCube&(gtmp, "Tornado" + STR$(n), 35, x0 + v * COS(w), y0 + v * SIN(w), u, 15, 15, 15, DarkGray, SunsetOrange, DarkGoldenRod, PathIndexTicker)
  540.             CALL SetParticleVelocity(gtmp, -SIN(w), COS(w), 0)
  541.         NEXT
  542.         CALL ClusterPinch(gtmp)
  543.     NEXT
  544.     LOCATE 1, 1: PRINT "Loading..." + STR$(INT(100 * Group(gtmp).LastVector / bignumber)) + "%": _DISPLAY
  545.  
  546.     ' Tree
  547.     FOR n = 1 TO 10
  548.         v = 30 + RND * 60
  549.         u = v / 10
  550.         w = u
  551.         x0 = RND * 2800
  552.         y0 = RND * 700 + 700
  553.         z0 = u / 2
  554.         FOR j = 0 TO v STEP u
  555.             gtmp = NewCube&(gtmp, "Tree" + STR$(n), 5 * (v - j), x0, y0, z0 + j, w, w, u, Chocolate, SaddleBrown, Gray, -1)
  556.             w = w * .9
  557.             CALL ClusterPinch(gtmp)
  558.         NEXT
  559.         w = v / 1.618
  560.         FOR j = u TO (v + 3 * u) STEP u
  561.             gtmp = NewCube&(gtmp, "Tree" + STR$(n), 5 * (v - j), x0, y0, z0 + j, w, w, u, Lime, Green, Teal, -1)
  562.             w = w * .8
  563.             CALL ClusterPinch(gtmp)
  564.         NEXT
  565.         z0 = u / 2 + v
  566.         gtmp = NewCube&(gtmp, "Tree" + STR$(n), 100, x0, y0, z0, u, u, u, White, Yellow, Teal, -1)
  567.         FOR k = Group(gtmp).FirstVector TO Group(gtmp).LastVector
  568.             vec3Dvel(k, 1) = (RND - .5) * .20
  569.             vec3Dvel(k, 2) = (RND - .5) * .20
  570.             vec3Dvel(k, 3) = (RND - .5) * .20
  571.         NEXT
  572.         CALL ClusterPinch(gtmp)
  573.     NEXT
  574.     LOCATE 1, 1: PRINT "Loading..." + STR$(INT(100 * Group(gtmp).LastVector / bignumber)) + "%": _DISPLAY
  575.  
  576.     ' Stellar dust
  577.     FOR u = -1400 TO 1400 - 350 STEP 350
  578.         FOR v = -1400 TO 1400 - 350 STEP 350
  579.             FOR i = u TO u + 350 STEP 35
  580.                 FOR j = v TO v + 350 STEP 35
  581.                     gtmp = NewCube&(gtmp, "Stellar dust", 15, i, j, 1350, 35, 35, 100, BlueViolet, Cyan, White, -1)
  582.                     CALL SetParticleVelocity(gtmp, 0, 0, -.75 - RND * .25)
  583.                 NEXT
  584.             NEXT
  585.         NEXT
  586.     NEXT
  587.     CALL ClusterPinch(gtmp)
  588.     LOCATE 1, 1: PRINT "Loading..." + STR$(INT(100 * Group(gtmp).LastVector / bignumber)) + "%": _DISPLAY
  589.  
  590.     ''' Rocket
  591.     gtmp = NewCube&(gtmp, "Rocket", 200, 0, 0, 0, 15, 15, 35, Green, Green, Green, 0)
  592.     gtmp = NewCube&(gtmp, "Rocket", 200, 0, 0, 0, 15, 15, 15, Red, Red, Red, 0)
  593.     Cluster(ClusterIndexTicker).Velocity.x = 0
  594.     Cluster(ClusterIndexTicker).Velocity.y = 0
  595.     Cluster(ClusterIndexTicker).Velocity.z = 1
  596.     CALL ClusterPinch(gtmp)
  597.     LOCATE 1, 1: PRINT "Loading..." + STR$(INT(100 * Group(gtmp).LastVector / bignumber)) + "%": _DISPLAY
  598.  
  599.     moo:
  600.  
  601.     'PRINT
  602.     'PRINT "Total clusters:  " + STR$(ClusterIndexTicker)
  603.     'PRINT "Total groups:    " + STR$(GroupIdTicker)
  604.     'PRINT "Total particles: " + STR$(Group(gtmp).LastVector)
  605.     '_DISPLAY
  606.     'SLEEP 3
  607.  
  608.  
  609. SUB MainLoop
  610.     DIM fps AS INTEGER
  611.     DIM fpstimer AS INTEGER
  612.     DIM tt AS INTEGER
  613.     fps = 0
  614.     fpstimer = INT(TIMER)
  615.     CALL CalculateScreenVectors
  616.     DO
  617.         CALL PlayerDynamics
  618.         CALL ComputeVisibleScene
  619.         CALL PlotWorld
  620.         CALL DisplayHUD
  621.         CALL KeyProcess
  622.  
  623.         fps = fps + 1
  624.         tt = INT(TIMER)
  625.         IF (tt = fpstimer + 1) THEN
  626.             fpstimer = tt
  627.             FPSReport = fps
  628.             fps = 0
  629.         END IF
  630.  
  631.         _DISPLAY
  632.         _LIMIT 30
  633.     LOOP
  634.  
  635. ' Elevated-order primitive group.
  636.  
  637. FUNCTION NewPlanet& (TheRadius AS DOUBLE, ChunkSize AS DOUBLE, PosX AS DOUBLE, PosY AS DOUBLE, PosZ AS DOUBLE, TheDynamic AS INTEGER)
  638.     DIM ShadeA AS _UNSIGNED LONG
  639.     DIM ShadeB AS _UNSIGNED LONG
  640.     DIM ShadeC AS _UNSIGNED LONG
  641.     DIM gtmp AS LONG
  642.     DIM rtemp AS DOUBLE
  643.     DIM u AS DOUBLE
  644.     DIM v AS DOUBLE
  645.     DIM w AS DOUBLE
  646.     DIM r AS DOUBLE
  647.     FOR rtemp = ChunkSize TO TheRadius STEP ChunkSize
  648.         FOR u = -rtemp TO rtemp STEP ChunkSize
  649.             FOR v = -rtemp TO rtemp STEP ChunkSize
  650.                 FOR w = -rtemp TO rtemp STEP ChunkSize
  651.                     r = SQR(u * u + v * v + w * w)
  652.                     IF r <= rtemp AND r >= rtemp - ChunkSize THEN
  653.                         ShadeA = ShadeMix~&(Red, SaddleBrown, r / TheRadius)
  654.                         ShadeB = ShadeMix~&(SunsetOrange, DarkKhaki, r / TheRadius)
  655.                         ShadeC = DarkKhaki
  656.                         gtmp = NewCube&(1, "Planet Interior", ChunkSize, PosX + u, PosY + v, PosZ + w, ChunkSize, ChunkSize, ChunkSize, ShadeA, ShadeB, ShadeC, TheDynamic)
  657.                         IF (r < TheRadius / 2.5) THEN
  658.                             Group(gtmp).GroupName = "Planet center"
  659.                             CALL SetParticleVelocity(gtmp, .25 * u / r, .25 * v / r, .25 * w / r)
  660.                         END IF
  661.                     END IF
  662.                 NEXT
  663.             NEXT
  664.         NEXT
  665.         CALL ClusterPinch(gtmp)
  666.     NEXT
  667.     CALL ClusterPinch(gtmp)
  668.     gtmp = NewShell&("Planet surface", TheRadius, PosX, PosY, PosZ, Green, DarkKhaki, DodgerBlue, 2, 20, TheDynamic)
  669.     gtmp = NewShell&("Planet core", TheRadius / 10, PosX, PosY, PosZ, Red, Yellow, DarkGoldenRod, 2, 5, TheDynamic)
  670.     FOR w = 0 + ChunkSize / 4 TO PosZ - TheRadius - ChunkSize / 4 STEP ChunkSize / 2
  671.         gtmp = NewCube&(1, "Planet column", 2 * ChunkSize, PosX, PosY, w, ChunkSize / 2, ChunkSize / 2, ChunkSize / 2, Cyan, Teal, Blue, TheDynamic)
  672.         CALL SetParticleVelocity(gtmp, .15 * (RND - .5), .15 * (RND - .5), .25 * RND)
  673.     NEXT
  674.     CALL ClusterPinch(gtmp)
  675.     NewPlanet& = gtmp
  676.  
  677. ' Medium-order primitive group(s).
  678.  
  679. FUNCTION NewTerrain& (TheName AS STRING, SizeX AS DOUBLE, SizeY AS DOUBLE, TheResolution AS DOUBLE, PosX AS DOUBLE, PosY AS DOUBLE, PosZ AS DOUBLE, ShadeA AS _UNSIGNED LONG, ShadeB AS _UNSIGNED LONG, ShadeC AS _UNSIGNED LONG, BumpFactor AS DOUBLE, SmoothFactor AS INTEGER)
  680.     DIM g AS LONG
  681.     DIM q AS LONG
  682.     DIM vindex AS LONG
  683.     DIM k AS INTEGER
  684.     DIM factor1 AS DOUBLE
  685.     DIM factor2 AS DOUBLE
  686.     DIM a AS DOUBLE
  687.     DIM b AS DOUBLE
  688.     DIM i AS DOUBLE
  689.     DIM j AS DOUBLE
  690.     DIM u AS DOUBLE
  691.     DIM v AS DOUBLE
  692.     DIM w AS DOUBLE
  693.     DIM ia AS DOUBLE
  694.     DIM jb AS DOUBLE
  695.     DIM rr AS DOUBLE
  696.     DIM wi AS INTEGER
  697.     DIM wj AS INTEGER
  698.     DIM wa AS INTEGER
  699.     DIM wb AS INTEGER
  700.     DIM ci AS INTEGER
  701.     DIM cj AS INTEGER
  702.     DIM ca AS INTEGER
  703.     DIM cb AS INTEGER
  704.  
  705.     factor1 = TheResolution
  706.     factor2 = factor1 / 10
  707.     wi = 0
  708.     wj = 0
  709.     wa = 0
  710.     wb = 0
  711.     FOR i = -SizeX / 2 + factor1 / 2 TO SizeX / 2 - factor1 / 2 STEP factor1
  712.         wi = wi + 1
  713.     NEXT
  714.     FOR j = -SizeY / 2 + factor1 / 2 TO SizeY / 2 - factor1 / 2 STEP factor1
  715.         wj = wj + 1
  716.     NEXT
  717.     FOR a = 0 TO factor1 - 0 * factor2 STEP factor2
  718.         wa = wa + 1
  719.     NEXT
  720.     FOR b = 0 TO factor1 - 0 * factor2 STEP factor2
  721.         wb = wb + 1
  722.     NEXT
  723.  
  724.     DIM vgrid(wi * wa, wj * wb, 2) AS DOUBLE
  725.     DIM vgrid2(wi * wa, wj * wb) AS DOUBLE
  726.     FOR ia = 1 TO wi * wa
  727.         FOR jb = 1 TO wj * wb
  728.             SELECT CASE (RND)
  729.                 CASE IS < .005
  730.                     vgrid(ia, jb, 1) = factor1 * RND
  731.                     vgrid(ia, jb, 2) = 1
  732.                 CASE IS > 1 - .005
  733.                     vgrid(ia, jb, 1) = -factor1 * RND / 2
  734.                     vgrid(ia, jb, 2) = 1
  735.                 CASE ELSE
  736.                     vgrid(ia, jb, 1) = 0
  737.                     vgrid(ia, jb, 2) = 0
  738.             END SELECT
  739.         NEXT
  740.     NEXT
  741.  
  742.     IF (SmoothFactor > 0) THEN
  743.         FOR k = 1 TO SmoothFactor
  744.             FOR ia = 1 TO wi * wa
  745.                 FOR jb = 1 TO wj * wb
  746.                     vgrid2(ia, jb) = vgrid(ia, jb, 1)
  747.                 NEXT
  748.             NEXT
  749.             FOR ia = 1 + 1 TO wi * wa - 1
  750.                 FOR jb = 1 + 1 TO wj * wb - 1
  751.                     IF (k = SmoothFactor - 5) THEN
  752.                         vgrid(ia, jb, 2) = 0
  753.                     END IF
  754.                     IF vgrid(ia, jb, 2) = 0 THEN
  755.                         vgrid(ia, jb, 1) = (1 / 4) * (vgrid2(ia - 1, jb) + vgrid2(ia + 1, jb) + vgrid2(ia, jb - 1) + vgrid2(ia, jb + 1))
  756.                     END IF
  757.                 NEXT
  758.             NEXT
  759.         NEXT
  760.     END IF
  761.  
  762.     ci = 0
  763.     cj = 0
  764.     ca = 0
  765.     cb = 0
  766.     g = 1
  767.     FOR i = -SizeX / 2 + factor1 / 2 - TheResolution / 2 TO SizeX / 2 - factor1 / 2 - TheResolution / 2 STEP factor1
  768.         ci = ci + 1
  769.         cj = 0
  770.         FOR j = -SizeY / 2 + factor1 / 2 - TheResolution / 2 TO SizeY / 2 - factor1 / 2 - TheResolution / 2 STEP factor1
  771.             cj = cj + 1
  772.             u = i
  773.             v = j
  774.             w = 0
  775.             q = LatestIdentity&(g)
  776.             vindex = Group(q).LastVector
  777.             g = CreateNewGroup&(q, PosX + u, PosY + v, PosZ + w, 0, 24)
  778.             Group(g).GroupName = TheName
  779.             Group(g).Volume.x = SizeX
  780.             Group(g).Volume.y = SizeY
  781.             Group(g).Volume.z = SQR(SizeX * SizeX + SizeY * SizeY)
  782.             Group(g).FirstVector = vindex + 1
  783.             ca = 0
  784.             FOR a = i TO i + factor1 - 0 * factor2 STEP factor2
  785.                 ca = ca + 1
  786.                 cb = 0
  787.                 FOR b = j TO j + factor1 - 0 * factor2 STEP factor2
  788.                     cb = cb + 1
  789.                     rr = vgrid((ci - 1) * wa + ca, (cj - 1) * wb + cb, 1)
  790.                     vindex = vindex + 1
  791.                     vec3Dpos(vindex, 1) = -u + a + BumpFactor * (RND - .5)
  792.                     vec3Dpos(vindex, 2) = -v + b + BumpFactor * (RND - .5)
  793.                     vec3Dpos(vindex, 3) = -w + rr + BumpFactor * (RND - .5)
  794.                     IF (rr > 0) THEN
  795.                         vec3Dcolor(vindex) = ShadeMix~&(ShadeA, ShadeB, rr / 10)
  796.                     ELSE
  797.                         vec3Dcolor(vindex) = ShadeC
  798.                     END IF
  799.                 NEXT
  800.             NEXT
  801.             Group(g).LastVector = vindex
  802.         NEXT
  803.         CALL ClusterPinch(g)
  804.     NEXT
  805.     CALL ClusterPinch(g)
  806.     NewTerrain& = g
  807.  
  808. FUNCTION NewShell& (TheName AS STRING, TheRadius AS DOUBLE, PosX AS DOUBLE, PosY AS DOUBLE, PosZ AS DOUBLE, ShadeA AS _UNSIGNED LONG, ShadeB AS _UNSIGNED LONG, ShadeC AS _UNSIGNED LONG, BumpFactor AS DOUBLE, SmoothFactor AS INTEGER, TheDynamic AS INTEGER)
  809.     DIM g AS LONG
  810.     DIM q AS LONG
  811.     DIM vindex AS LONG
  812.     DIM k AS INTEGER
  813.     DIM factor1 AS DOUBLE
  814.     DIM factor2 AS DOUBLE
  815.     DIM a AS DOUBLE
  816.     DIM b AS DOUBLE
  817.     DIM i AS DOUBLE
  818.     DIM j AS DOUBLE
  819.     DIM u AS DOUBLE
  820.     DIM v AS DOUBLE
  821.     DIM w AS DOUBLE
  822.     DIM ia AS DOUBLE
  823.     DIM jb AS DOUBLE
  824.     DIM rr AS DOUBLE
  825.     DIM wi AS LONG
  826.     DIM wj AS LONG
  827.     DIM wa AS LONG
  828.     DIM wb AS LONG
  829.     DIM ci AS LONG
  830.     DIM cj AS LONG
  831.     DIM ca AS LONG
  832.     DIM cb AS LONG
  833.  
  834.     IF (TheRadius > 200) THEN
  835.         factor1 = (2) * 2 * pi / (10 ^ (INT(LOG(TheRadius) / LOG(10))))
  836.         factor2 = factor1 / (10)
  837.     ELSE
  838.         factor1 = 2 * pi / (10)
  839.         factor2 = factor1 / (5)
  840.     END IF
  841.  
  842.  
  843.     wi = 0
  844.     wj = 0
  845.     wa = 0
  846.     wb = 0
  847.     FOR i = 0 TO 2 * pi - factor1 STEP factor1
  848.         wi = wi + 1
  849.     NEXT
  850.     FOR j = factor2 TO pi - 0 STEP factor1
  851.         wj = wj + 1
  852.     NEXT
  853.     FOR a = 0 TO factor1 STEP factor2
  854.         wa = wa + 1
  855.     NEXT
  856.     FOR b = 0 TO factor1 STEP factor2
  857.         wb = wb + 1
  858.     NEXT
  859.  
  860.     DIM vgrid(wi * wa, wj * wb, 2) AS DOUBLE
  861.     DIM vgrid2(wi * wa, wj * wb) AS DOUBLE
  862.  
  863.     FOR ia = 1 TO wi * wa
  864.         FOR jb = 1 TO wj * wb
  865.             SELECT CASE (RND)
  866.                 CASE IS < .025
  867.                     vgrid(ia, jb, 1) = TheRadius - BumpFactor * (TheRadius / 50)
  868.                     vgrid(ia, jb, 2) = 1
  869.                 CASE IS > 1 - .025
  870.                     vgrid(ia, jb, 1) = TheRadius + BumpFactor * (TheRadius / 50)
  871.                     vgrid(ia, jb, 2) = 1
  872.                 CASE ELSE
  873.                     vgrid(ia, jb, 1) = TheRadius
  874.                     vgrid(ia, jb, 2) = 0
  875.             END SELECT
  876.         NEXT
  877.     NEXT
  878.  
  879.     IF (SmoothFactor > 0) THEN
  880.         FOR k = 1 TO SmoothFactor
  881.             FOR ia = 1 TO wi * wa
  882.                 FOR jb = 1 TO wj * wb
  883.                     vgrid2(ia, jb) = vgrid(ia, jb, 1)
  884.                 NEXT
  885.             NEXT
  886.             FOR ia = 1 + 1 TO wi * wa - 1
  887.                 FOR jb = 1 + 1 TO wj * wb - 1
  888.                     IF (k = SmoothFactor - 5) THEN
  889.                         vgrid(ia, jb, 2) = 0
  890.                     END IF
  891.                     IF vgrid(ia, jb, 2) = 0 THEN
  892.                         vgrid(ia, jb, 1) = (1 / 4) * (vgrid2(ia - 1, jb) + vgrid2(ia + 1, jb) + vgrid2(ia, jb - 1) + vgrid2(ia, jb + 1))
  893.                     END IF
  894.                 NEXT
  895.             NEXT
  896.         NEXT
  897.     END IF
  898.  
  899.     ci = 0
  900.     cj = 0
  901.     ca = 0
  902.     cb = 0
  903.     g = 1
  904.     FOR i = 0 TO 2 * pi - factor1 STEP factor1
  905.         ci = ci + 1
  906.         cj = 0
  907.         FOR j = factor2 TO pi - 0 STEP factor1
  908.             cj = cj + 1
  909.             u = TheRadius * SIN(j) * COS(i)
  910.             v = TheRadius * SIN(j) * SIN(i)
  911.             w = TheRadius * COS(j)
  912.             q = LatestIdentity&(g)
  913.             vindex = Group(q).LastVector
  914.             g = CreateNewGroup&(q, PosX + u, PosY + v, PosZ + w, TheDynamic, 64)
  915.             Group(g).GroupName = TheName
  916.             Group(g).Volume.x = TheRadius
  917.             Group(g).Volume.y = TheRadius
  918.             Group(g).Volume.z = TheRadius
  919.             Group(g).FirstVector = vindex + 1
  920.             ca = 0
  921.             FOR a = i TO i + factor1 STEP factor2
  922.                 ca = ca + 1
  923.                 cb = 0
  924.                 FOR b = j TO j + factor1 STEP factor2
  925.                     cb = cb + 1
  926.                     rr = vgrid((ci - 1) * wa + ca, (cj - 1) * wb + cb, 1)
  927.                     vindex = vindex + 1
  928.                     vec3Dpos(vindex, 1) = -u + rr * SIN(b) * COS(a) + BumpFactor * (RND - .5) * 2
  929.                     vec3Dpos(vindex, 2) = -v + rr * SIN(b) * SIN(a) + BumpFactor * (RND - .5) * 2
  930.                     vec3Dpos(vindex, 3) = -w + rr * COS(b) + BumpFactor * (RND - .5) * 2
  931.                     IF (rr > TheRadius) THEN
  932.                         vec3Dcolor(vindex) = ShadeMix~&(ShadeA, ShadeB, COS(j) ^ 2)
  933.                     ELSE
  934.                         vec3Dcolor(vindex) = ShadeC
  935.                     END IF
  936.                 NEXT
  937.             NEXT
  938.             Group(g).LastVector = vindex
  939.         NEXT
  940.         CALL ClusterPinch(g)
  941.     NEXT
  942.     CALL ClusterPinch(g)
  943.  
  944.     NewShell& = g
  945.  
  946. ' Low-order primitive group(s).
  947.  
  948. FUNCTION NewCube& (StartingIdentity AS LONG, TheName AS STRING, Weight AS INTEGER, PosX AS DOUBLE, PosY AS DOUBLE, PosZ AS DOUBLE, VolX AS DOUBLE, VolY AS DOUBLE, VolZ AS DOUBLE, ShadeA AS _UNSIGNED LONG, ShadeB AS _UNSIGNED LONG, ShadeC AS _UNSIGNED LONG, TheDynamic AS INTEGER)
  949.     DIM k AS INTEGER
  950.     DIM g AS LONG
  951.     DIM q AS LONG
  952.     DIM vindex AS LONG
  953.     q = LatestIdentity&(StartingIdentity)
  954.     vindex = Group(q).LastVector
  955.     g = CreateNewGroup(q, PosX, PosY, PosZ, TheDynamic, 64)
  956.     Group(g).GroupName = TheName
  957.     Group(g).Volume.x = VolX
  958.     Group(g).Volume.y = VolY
  959.     Group(g).Volume.z = VolZ
  960.     Group(g).FirstVector = vindex + 1
  961.     FOR k = 1 TO Weight
  962.         vindex = vindex + 1
  963.         vec3Dpos(vindex, 1) = (RND - .5) * VolX
  964.         vec3Dpos(vindex, 2) = (RND - .5) * VolY
  965.         vec3Dpos(vindex, 3) = (RND - .5) * VolZ
  966.         IF (RND > .5) THEN
  967.             vec3Dcolor(vindex) = ShadeA
  968.         ELSE
  969.             IF (RND > .5) THEN
  970.                 vec3Dcolor(vindex) = ShadeB
  971.             ELSE
  972.                 vec3Dcolor(vindex) = ShadeC
  973.             END IF
  974.         END IF
  975.     NEXT
  976.     Group(g).LastVector = vindex
  977.     NewCube& = g
  978.  
  979. ' Linked list utility.
  980.  
  981. FUNCTION LatestIdentity& (StartingID AS LONG)
  982.     DIM TheReturn AS LONG
  983.     DIM p AS LONG
  984.     DIM q AS LONG
  985.     p = StartingID
  986.     DO
  987.         q = p
  988.         p = Group(q).Pointer
  989.         IF (p = -999) THEN EXIT DO
  990.     LOOP
  991.     TheReturn = q
  992.     LatestIdentity& = TheReturn
  993.  
  994. FUNCTION CreateNewGroup& (TheLaggerIn AS LONG, CenterX AS DOUBLE, CenterY AS DOUBLE, CenterZ AS DOUBLE, TheDynamic AS INTEGER, ClusterSize AS INTEGER)
  995.     GroupIdTicker = GroupIdTicker + 1
  996.     Group(GroupIdTicker).Identity = GroupIdTicker
  997.     Group(GroupIdTicker).Pointer = -999
  998.     Group(GroupIdTicker).Lagger = TheLaggerIn
  999.     Group(GroupIdTicker).Centroid.x = CenterX
  1000.     Group(GroupIdTicker).Centroid.y = CenterY
  1001.     Group(GroupIdTicker).Centroid.z = CenterZ
  1002.     IF (TheLaggerIn <> 0) THEN
  1003.         Group(TheLaggerIn).Pointer = Group(GroupIdTicker).Identity
  1004.     END IF
  1005.     '''
  1006.     ClusterFillCounter = ClusterFillCounter + 1
  1007.  
  1008.     IF (ClusterFillCounter = 1) THEN
  1009.         ClusterIndexTicker = ClusterIndexTicker + 1
  1010.         Cluster(ClusterIndexTicker).FirstGroup = Group(GroupIdTicker).Identity
  1011.         Cluster(ClusterIndexTicker).MotionType = TheDynamic
  1012.     END IF
  1013.  
  1014.     IF (ClusterFillCounter = ClusterSize) THEN
  1015.         CALL ClusterPinch(Group(GroupIdTicker).Identity)
  1016.     END IF
  1017.     '''
  1018.     CreateNewGroup& = Group(GroupIdTicker).Identity
  1019.  
  1020. SUB ClusterPinch (TheLastGroup AS LONG)
  1021.     ClusterFillCounter = 0
  1022.     Cluster(ClusterIndexTicker).LastGroup = TheLastGroup
  1023.     CALL ClusterCentroidCalc(ClusterIndexTicker)
  1024.  
  1025. SUB ClusterCentroidCalc (TheClusterIndex AS LONG)
  1026.     DIM k AS LONG
  1027.     DIM n AS INTEGER
  1028.     Cluster(TheClusterIndex).Centroid.x = 0
  1029.     Cluster(TheClusterIndex).Centroid.y = 0
  1030.     Cluster(TheClusterIndex).Centroid.z = 0
  1031.     k = Cluster(TheClusterIndex).FirstGroup
  1032.     n = 0
  1033.     DO
  1034.         Cluster(TheClusterIndex).Centroid.x = Cluster(TheClusterIndex).Centroid.x + Group(k).Centroid.x
  1035.         Cluster(TheClusterIndex).Centroid.y = Cluster(TheClusterIndex).Centroid.y + Group(k).Centroid.y
  1036.         Cluster(TheClusterIndex).Centroid.z = Cluster(TheClusterIndex).Centroid.z + Group(k).Centroid.z
  1037.         n = n + 1
  1038.         IF (k = Cluster(TheClusterIndex).LastGroup) THEN EXIT DO
  1039.         k = Group(k).Pointer
  1040.     LOOP
  1041.     Cluster(TheClusterIndex).Centroid.x = Cluster(TheClusterIndex).Centroid.x / n
  1042.     Cluster(TheClusterIndex).Centroid.y = Cluster(TheClusterIndex).Centroid.y / n
  1043.     Cluster(TheClusterIndex).Centroid.z = Cluster(TheClusterIndex).Centroid.z / n
  1044.  
  1045. ' Vector manipulation.
  1046.  
  1047. SUB SetParticleVelocity (TheGroup AS LONG, vx AS DOUBLE, vy AS DOUBLE, vz AS DOUBLE)
  1048.     DIM j AS LONG
  1049.     DIM m AS LONG
  1050.     DIM n AS LONG
  1051.     m = Group(TheGroup).FirstVector
  1052.     n = Group(TheGroup).LastVector
  1053.     FOR j = m TO n
  1054.         vec3Dvel(j, 1) = vx
  1055.         vec3Dvel(j, 2) = vy
  1056.         vec3Dvel(j, 3) = vz
  1057.     NEXT
  1058.  
  1059. ' Cluster manipulation.
  1060.  
  1061. SUB EvolveCluster (TheClusterIndex AS LONG)
  1062.     DIM dx, dy, dz, t, u, v AS DOUBLE
  1063.     IF (Cluster(TheClusterIndex).MotionType = 0) THEN
  1064.         dx = Cluster(TheClusterIndex).Velocity.x
  1065.         dy = Cluster(TheClusterIndex).Velocity.y
  1066.         dz = Cluster(TheClusterIndex).Velocity.z
  1067.     ELSE
  1068.         t = TIMER
  1069.         u = INT(t)
  1070.         v = t - u
  1071.         dx = v * FixedPath(Cluster(TheClusterIndex).MotionType, u).x + (1 - v) * FixedPath(Cluster(TheClusterIndex).MotionType, u - 1).x
  1072.         dy = v * FixedPath(Cluster(TheClusterIndex).MotionType, u).y + (1 - v) * FixedPath(Cluster(TheClusterIndex).MotionType, u - 1).y
  1073.         dz = v * FixedPath(Cluster(TheClusterIndex).MotionType, u).z + (1 - v) * FixedPath(Cluster(TheClusterIndex).MotionType, u - 1).z
  1074.     END IF
  1075.     IF ((dx <> 0) OR (dy <> 0) OR (dz <> 0)) THEN
  1076.         CALL TranslateCluster(TheClusterIndex, dx, dy, dz)
  1077.     END IF
  1078.  
  1079. SUB TranslateCluster (TheClusterIndex AS LONG, dx AS DOUBLE, dy AS DOUBLE, dz AS DOUBLE)
  1080.     DIM k AS LONG
  1081.     k = Cluster(TheClusterIndex).FirstGroup
  1082.     DO
  1083.         Group(k).Centroid.x = Group(k).Centroid.x + dx
  1084.         Group(k).Centroid.y = Group(k).Centroid.y + dy
  1085.         Group(k).Centroid.z = Group(k).Centroid.z + dz
  1086.         IF (k = Cluster(TheClusterIndex).LastGroup) THEN EXIT DO
  1087.         k = Group(k).Pointer
  1088.     LOOP
  1089.     Cluster(TheClusterIndex).Centroid.x = Cluster(TheClusterIndex).Centroid.x + dx
  1090.     Cluster(TheClusterIndex).Centroid.y = Cluster(TheClusterIndex).Centroid.y + dy
  1091.     Cluster(TheClusterIndex).Centroid.z = Cluster(TheClusterIndex).Centroid.z + dz
  1092.  
  1093. ' Particle manipulation.
  1094.  
  1095. SUB EvolveParticles (TheGroup AS LONG)
  1096.     DIM xdim AS DOUBLE
  1097.     DIM ydim AS DOUBLE
  1098.     DIM zdim AS DOUBLE
  1099.     DIM dx AS DOUBLE
  1100.     DIM dy AS DOUBLE
  1101.     DIM dz AS DOUBLE
  1102.     DIM px AS DOUBLE
  1103.     DIM py AS DOUBLE
  1104.     DIM pz AS DOUBLE
  1105.     DIM k AS LONG
  1106.  
  1107.     xdim = Group(TheGroup).Volume.x
  1108.     ydim = Group(TheGroup).Volume.y
  1109.     zdim = Group(TheGroup).Volume.z
  1110.  
  1111.     FOR k = Group(TheGroup).FirstVector TO Group(TheGroup).LastVector
  1112.  
  1113.         ' Position update with periodic boundaries inside group volume
  1114.         dx = 1 * vec3Dvel(k, 1)
  1115.         dy = 1 * vec3Dvel(k, 2)
  1116.         dz = 1 * vec3Dvel(k, 3)
  1117.         IF (dx <> 0) THEN
  1118.             px = vec3Dpos(k, 1) + dx
  1119.             IF ABS(px) > xdim / 2 THEN
  1120.                 IF (px > xdim / 2) THEN
  1121.                     px = -xdim / 2
  1122.                 ELSE
  1123.                     px = xdim / 2
  1124.                 END IF
  1125.             END IF
  1126.             vec3Dpos(k, 1) = px
  1127.         END IF
  1128.         IF (dy <> 0) THEN
  1129.             py = vec3Dpos(k, 2) + dy
  1130.             IF ABS(py) > ydim / 2 THEN
  1131.                 IF (py > ydim / 2) THEN
  1132.                     py = -ydim / 2
  1133.                 ELSE
  1134.                     py = ydim / 2
  1135.                 END IF
  1136.             END IF
  1137.             vec3Dpos(k, 2) = py
  1138.         END IF
  1139.         IF (dz <> 0) THEN
  1140.             pz = vec3Dpos(k, 3) + dz
  1141.             IF ABS(pz) > zdim / 2 THEN
  1142.                 IF (pz > zdim / 2) THEN
  1143.                     pz = -zdim / 2
  1144.                 ELSE
  1145.                     pz = zdim / 2
  1146.                 END IF
  1147.             END IF
  1148.             vec3Dpos(k, 3) = pz
  1149.         END IF
  1150.     NEXT
  1151.  
  1152. SUB CalculateScreenVectors
  1153.     DIM uhatmag AS DOUBLE
  1154.     DIM vhatmag AS DOUBLE
  1155.     DIM h2 AS DOUBLE
  1156.     DIM w2 AS DOUBLE
  1157.     DIM mag AS DOUBLE
  1158.     DIM uhatdotvhat AS DOUBLE
  1159.     uhatmag = SQR(uhat(1) * uhat(1) + uhat(2) * uhat(2) + uhat(3) * uhat(3))
  1160.     uhat(1) = uhat(1) / uhatmag: uhat(2) = uhat(2) / uhatmag: uhat(3) = uhat(3) / uhatmag
  1161.     vhatmag = SQR(vhat(1) * vhat(1) + vhat(2) * vhat(2) + vhat(3) * vhat(3))
  1162.     vhat(1) = vhat(1) / vhatmag: vhat(2) = vhat(2) / vhatmag: vhat(3) = vhat(3) / vhatmag
  1163.     uhatdotvhat = uhat(1) * vhat(1) + uhat(2) * vhat(2) + uhat(3) * vhat(3)
  1164.     nhat(1) = uhat(2) * vhat(3) - uhat(3) * vhat(2)
  1165.     nhat(2) = uhat(3) * vhat(1) - uhat(1) * vhat(3)
  1166.     nhat(3) = uhat(1) * vhat(2) - uhat(2) * vhat(1)
  1167.     h2 = _HEIGHT / 2
  1168.     w2 = _WIDTH / 2
  1169.     nearplane(1) = -nhat(1)
  1170.     nearplane(2) = -nhat(2)
  1171.     nearplane(3) = -nhat(3)
  1172.     farplane(1) = nhat(1)
  1173.     farplane(2) = nhat(2)
  1174.     farplane(3) = nhat(3)
  1175.     rightplane(1) = h2 * fovd * uhat(1) - h2 * w2 * nhat(1)
  1176.     rightplane(2) = h2 * fovd * uhat(2) - h2 * w2 * nhat(2)
  1177.     rightplane(3) = h2 * fovd * uhat(3) - h2 * w2 * nhat(3)
  1178.     mag = SQR(rightplane(1) * rightplane(1) + rightplane(2) * rightplane(2) + rightplane(3) * rightplane(3))
  1179.     rightplane(1) = rightplane(1) / mag
  1180.     rightplane(2) = rightplane(2) / mag
  1181.     rightplane(3) = rightplane(3) / mag
  1182.     leftplane(1) = -h2 * fovd * uhat(1) - h2 * w2 * nhat(1)
  1183.     leftplane(2) = -h2 * fovd * uhat(2) - h2 * w2 * nhat(2)
  1184.     leftplane(3) = -h2 * fovd * uhat(3) - h2 * w2 * nhat(3)
  1185.     mag = SQR(leftplane(1) * leftplane(1) + leftplane(2) * leftplane(2) + leftplane(3) * leftplane(3))
  1186.     leftplane(1) = leftplane(1) / mag
  1187.     leftplane(2) = leftplane(2) / mag
  1188.     leftplane(3) = leftplane(3) / mag
  1189.     topplane(1) = w2 * fovd * vhat(1) - h2 * w2 * nhat(1)
  1190.     topplane(2) = w2 * fovd * vhat(2) - h2 * w2 * nhat(2)
  1191.     topplane(3) = w2 * fovd * vhat(3) - h2 * w2 * nhat(3)
  1192.     mag = SQR(topplane(1) * topplane(1) + topplane(2) * topplane(2) + topplane(3) * topplane(3))
  1193.     topplane(1) = topplane(1) / mag
  1194.     topplane(2) = topplane(2) / mag
  1195.     topplane(3) = topplane(3) / mag
  1196.     bottomplane(1) = -w2 * fovd * vhat(1) - h2 * w2 * nhat(1)
  1197.     bottomplane(2) = -w2 * fovd * vhat(2) - h2 * w2 * nhat(2)
  1198.     bottomplane(3) = -w2 * fovd * vhat(3) - h2 * w2 * nhat(3)
  1199.     mag = SQR(bottomplane(1) * bottomplane(1) + bottomplane(2) * bottomplane(2) + bottomplane(3) * bottomplane(3))
  1200.     bottomplane(1) = bottomplane(1) / mag
  1201.     bottomplane(2) = bottomplane(2) / mag
  1202.     bottomplane(3) = bottomplane(3) / mag
  1203.  
  1204. SUB ProjectGroup (TheGroup AS LONG)
  1205.     DIM i AS LONG
  1206.     DIM f AS INTEGER
  1207.     DIM vectorinview AS INTEGER
  1208.     DIM vec3Ddotnhat AS DOUBLE
  1209.     FOR i = Group(TheGroup).FirstVector TO Group(TheGroup).LastVector
  1210.         vec(i, 1) = Group(TheGroup).Centroid.x + vec3Dpos(i, 1) - PlayerCamera.Position.x
  1211.         vec(i, 2) = Group(TheGroup).Centroid.y + vec3Dpos(i, 2) - PlayerCamera.Position.y
  1212.         vec(i, 3) = Group(TheGroup).Centroid.z + vec3Dpos(i, 3) - PlayerCamera.Position.z
  1213.         f = -1
  1214.         vec3Dvis(i) = 0
  1215.         vectorinview = 1
  1216.         IF vec(i, 1) * nearplane(1) + vec(i, 2) * nearplane(2) + vec(i, 3) * nearplane(3) - nearplane(4) < 0 THEN vectorinview = 0
  1217.         'IF vec(i, 1) * farplane(1) + vec(i, 2) * farplane(2) + vec(i, 3) * farplane(3) - farplane(4) < 0 THEN vectorinview = 0
  1218.         IF vec(i, 1) * farplane(1) + vec(i, 2) * farplane(2) + vec(i, 3) * farplane(3) - farplane(4) * .85 < 0 THEN f = 1
  1219.         'IF vec(i, 1) * rightplane(1) + vec(i, 2) * rightplane(2) + vec(i, 3) * rightplane(3) - rightplane(4) < 0 THEN vectorinview = 0
  1220.         'IF vec(i, 1) * leftplane(1) + vec(i, 2) * leftplane(2) + vec(i, 3) * leftplane(3) - leftplane(4) < 0 THEN vectorinview = 0
  1221.         'IF vec(i, 1) * topplane(1) + vec(i, 2) * topplane(2) + vec(i, 3) * topplane(3) - topplane(4) < 0 THEN vectorinview = 0
  1222.         'IF vec(i, 1) * bottomplane(1) + vec(i, 2) * bottomplane(2) + vec(i, 3) * bottomplane(3) - bottomplane(4) < 0 THEN vectorinview = 0
  1223.         IF (vectorinview = 1) THEN
  1224.             vec3Dvis(i) = 1
  1225.             vec3Ddotnhat = vec(i, 1) * nhat(1) + vec(i, 2) * nhat(2) + vec(i, 3) * nhat(3)
  1226.             vec2D(i, 1) = (vec(i, 1) * uhat(1) + vec(i, 2) * uhat(2) + vec(i, 3) * uhat(3)) * fovd / vec3Ddotnhat
  1227.             vec2D(i, 2) = (vec(i, 1) * vhat(1) + vec(i, 2) * vhat(2) + vec(i, 3) * vhat(3)) * fovd / vec3Ddotnhat
  1228.             IF (f = 1) THEN
  1229.                 vec2Dcolor(i) = Gray
  1230.             ELSE
  1231.                 vec2Dcolor(i) = vec3Dcolor(i)
  1232.             END IF
  1233.         END IF
  1234.     NEXT
  1235.  
  1236. ' TheDynamics
  1237.  
  1238. SUB ComputeVisibleScene
  1239.     DIM closestdist2 AS DOUBLE
  1240.     DIM fp42 AS DOUBLE
  1241.     DIM dist2 AS DOUBLE
  1242.     DIM dx AS DOUBLE
  1243.     DIM dy AS DOUBLE
  1244.     DIM dz AS DOUBLE
  1245.     DIM GroupInView AS INTEGER
  1246.     DIM k AS LONG
  1247.     DIM i AS LONG
  1248.     ClosestGroup = 1
  1249.     closestdist2 = 10000000
  1250.     fp42 = farplane(4) * farplane(4)
  1251.     FOR i = 1 TO ClusterIndexTicker
  1252.         dx = Cluster(i).Centroid.x - PlayerCamera.Position.x
  1253.         dy = Cluster(i).Centroid.y - PlayerCamera.Position.y
  1254.         dz = Cluster(i).Centroid.z - PlayerCamera.Position.z
  1255.         dist2 = dx * dx + dy * dy + dz * dz
  1256.         IF (dist2 > 600 * 600) THEN
  1257.             Cluster(i).Visible = 0
  1258.             IF (Cluster(i).MotionType > -1) THEN
  1259.                 CALL EvolveCluster(i)
  1260.             END IF
  1261.         ELSE
  1262.             Cluster(i).Visible = 1
  1263.             k = Cluster(i).FirstGroup
  1264.             IF ((Cluster(i).MotionType > -1) AND (ToggleAnimate = 1)) THEN
  1265.                 CALL EvolveCluster(i)
  1266.             END IF
  1267.             DO
  1268.                 dx = Group(k).Centroid.x - PlayerCamera.Position.x
  1269.                 dy = Group(k).Centroid.y - PlayerCamera.Position.y
  1270.                 dz = Group(k).Centroid.z - PlayerCamera.Position.z
  1271.                 dist2 = dx * dx + dy * dy + dz * dz
  1272.                 Group(k).Visible = 0
  1273.                 IF (dist2 < fp42) THEN
  1274.                     GroupInView = 1
  1275.                     IF dx * nearplane(1) + dy * nearplane(2) + dz * nearplane(3) - nearplane(4) < 0 THEN GroupInView = 0
  1276.                     'IF dx * farplane(1) + dy * farplane(2) + dz * farplane(3) - farplane(4) < 0 THEN groupinview = 0 ''' Redundant
  1277.                     IF dx * rightplane(1) + dy * rightplane(2) + dz * rightplane(3) - rightplane(4) < 0 THEN GroupInView = 0
  1278.                     IF dx * leftplane(1) + dy * leftplane(2) + dz * leftplane(3) - leftplane(4) < 0 THEN GroupInView = 0
  1279.                     IF dx * topplane(1) + dy * topplane(2) + dz * topplane(3) - topplane(4) < 0 THEN GroupInView = 0
  1280.                     IF dx * bottomplane(1) + dy * bottomplane(2) + dz * bottomplane(3) - bottomplane(4) < 0 THEN GroupInView = 0
  1281.                     IF (GroupInView = 1) THEN
  1282.                         Group(k).Visible = 1
  1283.                         IF (dist2 < closestdist2) THEN
  1284.                             closestdist2 = dist2
  1285.                             ClosestGroup = k
  1286.                         END IF
  1287.                         Group(k).Distance2 = dist2
  1288.                         IF (ToggleAnimate = 1) THEN CALL EvolveParticles(k)
  1289.                         CALL ProjectGroup(k)
  1290.                     END IF
  1291.                 END IF
  1292.                 IF (k = Cluster(i).LastGroup) THEN EXIT DO
  1293.                 k = Group(k).Pointer
  1294.             LOOP
  1295.         END IF
  1296.     NEXT
  1297.  
  1298. ' Graphics
  1299.  
  1300. SUB PlotWorld
  1301.     DIM a AS DOUBLE
  1302.     DIM b AS DOUBLE
  1303.     DIM c AS LONG
  1304.     DIM d AS LONG
  1305.     DIM i AS LONG
  1306.     DIM j AS INTEGER
  1307.     DIM k AS LONG
  1308.     DIM x1 AS DOUBLE
  1309.     DIM y1 AS DOUBLE
  1310.     DIM x2 AS DOUBLE
  1311.     DIM y2 AS DOUBLE
  1312.     DIM clrtmp AS _UNSIGNED LONG
  1313.     DIM SortedGroups(5000) AS LONG
  1314.     DIM SortedGroupsCount AS INTEGER
  1315.  
  1316.     NumClusterVisible = 0
  1317.     NumVectorVisible = 0
  1318.  
  1319.     SortedGroupsCount = 0
  1320.     FOR i = 1 TO ClusterIndexTicker
  1321.         IF (Cluster(i).Visible = 1) THEN
  1322.             NumClusterVisible = NumClusterVisible + 1
  1323.             k = Cluster(i).FirstGroup
  1324.             DO
  1325.                 IF (Group(k).Visible = 1) THEN
  1326.                     SortedGroupsCount = SortedGroupsCount + 1
  1327.                     SortedGroups(SortedGroupsCount) = k
  1328.                 END IF
  1329.                 IF (k = Cluster(i).LastGroup) THEN EXIT DO
  1330.                 k = Group(k).Pointer
  1331.             LOOP
  1332.         END IF
  1333.     NEXT
  1334.  
  1335.     NumGroupVisible = SortedGroupsCount
  1336.  
  1337.     ' Bubble sort might be a shitty choice but it works for now. Replace with quicksort prolly.
  1338.     FOR j = SortedGroupsCount TO 1 STEP -1
  1339.         FOR i = 2 TO SortedGroupsCount
  1340.             a = Group(SortedGroups(i - 1)).Distance2
  1341.             b = Group(SortedGroups(i)).Distance2
  1342.             IF (a < b) THEN
  1343.                 c = SortedGroups(i - 1)
  1344.                 d = SortedGroups(i)
  1345.                 SortedGroups(i - 1) = d
  1346.                 SortedGroups(i) = c
  1347.             END IF
  1348.         NEXT
  1349.     NEXT
  1350.  
  1351.     CLS
  1352.     PlayerCamera.Shade = ShadeMix~&(PlayerCamera.Shade, vec3Dcolor(Group(ClosestGroup).FirstVector), .01)
  1353.     PAINT (_WIDTH / 2, _HEIGHT / 2), _RGBA(_RED32(PlayerCamera.Shade), _GREEN32(PlayerCamera.Shade), _BLUE32(PlayerCamera.Shade), 100)
  1354.     FOR j = 1 TO SortedGroupsCount
  1355.         k = SortedGroups(j)
  1356.         FOR i = Group(k).FirstVector TO Group(k).LastVector - 1
  1357.             IF (vec3Dvis(i) = 1) THEN
  1358.                 NumVectorVisible = NumVectorVisible + 1
  1359.                 IF (k = ClosestGroup) THEN
  1360.                     clrtmp = Yellow
  1361.                 ELSE
  1362.                     clrtmp = vec2Dcolor(i)
  1363.                 END IF
  1364.                 x1 = vec2D(i, 1)
  1365.                 y1 = vec2D(i, 2)
  1366.                 x2 = vec2D(i + 1, 1)
  1367.                 y2 = vec2D(i + 1, 2)
  1368.                 IF (((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) < 225) THEN
  1369.                     CALL cline(x1, y1, x2, y2, clrtmp) 'lineSmooth
  1370.                 ELSE
  1371.                     CALL ccircle(x1, y1, 1, clrtmp)
  1372.                 END IF
  1373.             END IF
  1374.         NEXT
  1375.     NEXT
  1376.  
  1377. SUB DisplayHUD
  1378.     DIM a AS STRING
  1379.     DIM k AS INTEGER
  1380.     CALL lineSmooth(0, 0, 25 * (xhat(1) * uhat(1) + xhat(2) * uhat(2) + xhat(3) * uhat(3)), 25 * (xhat(1) * vhat(1) + xhat(2) * vhat(2) + xhat(3) * vhat(3)), _RGBA(255, 0, 0, 200))
  1381.     CALL lineSmooth(0, 0, 25 * (yhat(1) * uhat(1) + yhat(2) * uhat(2) + yhat(3) * uhat(3)), 25 * (yhat(1) * vhat(1) + yhat(2) * vhat(2) + yhat(3) * vhat(3)), _RGBA(0, 255, 0, 200))
  1382.     CALL lineSmooth(0, 0, 25 * (zhat(1) * uhat(1) + zhat(2) * uhat(2) + zhat(3) * uhat(3)), 25 * (zhat(1) * vhat(1) + zhat(2) * vhat(2) + zhat(3) * vhat(3)), _RGBA(30, 144, 255, 200))
  1383.     IF (ToggleHUD = 1) THEN
  1384.         COLOR LimeGreen
  1385.         _PRINTSTRING ((1) * 8, _HEIGHT - (10) * 16), " Position "
  1386.         COLOR Teal
  1387.         _PRINTSTRING ((1) * 8, _HEIGHT - (9) * 16), " x:       "
  1388.         _PRINTSTRING ((1) * 8, _HEIGHT - (8) * 16), " y:       "
  1389.         _PRINTSTRING ((1) * 8, _HEIGHT - (7) * 16), " z:       "
  1390.         _PRINTSTRING ((1) * 8, _HEIGHT - (9) * 16), " x: " + LTRIM$(RTRIM$(STR$(INT(PlayerCamera.Position.x))))
  1391.         _PRINTSTRING ((1) * 8, _HEIGHT - (8) * 16), " y: " + LTRIM$(RTRIM$(STR$(INT(PlayerCamera.Position.y))))
  1392.         _PRINTSTRING ((1) * 8, _HEIGHT - (7) * 16), " z: " + LTRIM$(RTRIM$(STR$(INT(PlayerCamera.Position.z))))
  1393.         COLOR LimeGreen
  1394.         _PRINTSTRING ((1) * 8, _HEIGHT - (6) * 16), " O: Reset "
  1395.         COLOR LimeGreen
  1396.         _PRINTSTRING ((1) * 8, _HEIGHT - (4) * 16), " Move  "
  1397.         COLOR DarkKhaki
  1398.         _PRINTSTRING ((1) * 8, _HEIGHT - (3) * 16), " q W e "
  1399.         _PRINTSTRING ((1) * 8, _HEIGHT - (2) * 16), " A S D "
  1400.         COLOR LimeGreen
  1401.         _PRINTSTRING ((1) * 8, (1) * 16), " Abilities "
  1402.         COLOR DarkKhaki
  1403.         _PRINTSTRING ((1) * 8, (2) * 16), "t = Pause  "
  1404.         _PRINTSTRING ((1) * 8, (3) * 16), "b = Create "
  1405.         _PRINTSTRING ((1) * 8, (4) * 16), "n = Explode"
  1406.         COLOR DarkGray
  1407.         _PRINTSTRING ((1) * 8, (5) * 16), "k = Delete "
  1408.         COLOR DarkKhaki
  1409.         _PRINTSTRING ((1) * 8, (6) * 16), "Esc = Quit "
  1410.         'COLOR LimeGreen
  1411.         '_PRINTSTRING ((1) * 8, (9) * 16), "View"
  1412.         'COLOR DarkKhaki
  1413.         '_PRINTSTRING ((1) * 8, (9) * 16), "FPS: " + LTRIM$(RTRIM$(STR$(FPSReport))) + "/30"
  1414.         '_PRINTSTRING ((1) * 8, (10) * 16), "Clusters: " + LTRIM$(RTRIM$(STR$(NumClusterVisible)))
  1415.         '_PRINTSTRING ((1) * 8, (11) * 16), "Groups: " + LTRIM$(RTRIM$(STR$(NumGroupVisible)))
  1416.         '_PRINTSTRING ((1) * 8, (12) * 16), "Particles: " + LTRIM$(RTRIM$(STR$(NumVectorVisible)))
  1417.         COLOR LimeGreen
  1418.         _PRINTSTRING (_WIDTH - (12) * 8, (1) * 16), " Locations "
  1419.         FOR k = 1 TO MissionTicker
  1420.             a = " " + Mission(k).Label + " "
  1421.             IF (Mission(k).Discovered = 0) THEN
  1422.                 COLOR DarkKhaki
  1423.             ELSE
  1424.                 COLOR DarkGray
  1425.             END IF
  1426.             _PRINTSTRING (_WIDTH - (LEN(a) + 1) * 8, (1 + k) * 16), a
  1427.         NEXT
  1428.         COLOR LimeGreen
  1429.         _PRINTSTRING (_WIDTH - (12) * 8, (k + 1) * 16), " M = Reset "
  1430.         COLOR LimeGreen
  1431.         _PRINTSTRING (_WIDTH - (9) * 8, _HEIGHT - (10) * 16), " Aim    "
  1432.         _PRINTSTRING (_WIDTH - (9) * 8, _HEIGHT - (9) * 16), " x      "
  1433.         _PRINTSTRING (_WIDTH - (9) * 8, _HEIGHT - (8) * 16), " y      "
  1434.         _PRINTSTRING (_WIDTH - (9) * 8, _HEIGHT - (7) * 16), " z      "
  1435.         COLOR Teal
  1436.         _PRINTSTRING (_WIDTH - (9) * 8, _HEIGHT - (9) * 16), " x: " + LTRIM$(RTRIM$(STR$(INT(-nhat(1) * 100))))
  1437.         _PRINTSTRING (_WIDTH - (9) * 8, _HEIGHT - (8) * 16), " y: " + LTRIM$(RTRIM$(STR$(INT(-nhat(2) * 100))))
  1438.         _PRINTSTRING (_WIDTH - (9) * 8, _HEIGHT - (7) * 16), " z: " + LTRIM$(RTRIM$(STR$(INT(-nhat(3) * 100))))
  1439.         COLOR LimeGreen
  1440.         _PRINTSTRING (_WIDTH - (9) * 8, _HEIGHT - (5) * 16), " Swivel "
  1441.         COLOR DarkKhaki
  1442.         _PRINTSTRING (_WIDTH - (9) * 8, _HEIGHT - (4) * 16), " 7 8 9  "
  1443.         _PRINTSTRING (_WIDTH - (9) * 8, _HEIGHT - (3) * 16), " 4 5 6  "
  1444.         _PRINTSTRING (_WIDTH - (9) * 8, _HEIGHT - (2) * 16), " 1 2 3  "
  1445.         a = " - Closest - "
  1446.         COLOR LimeGreen
  1447.         _PRINTSTRING (_WIDTH / 2 - (LEN(a) / 2) * 8, _HEIGHT - (3) * 16), a
  1448.         a = " SPACE = Hide "
  1449.         COLOR LimeGreen
  1450.         _PRINTSTRING (_WIDTH / 2 - (LEN(a) / 2) * 8, _HEIGHT - (1) * 16), a
  1451.     END IF
  1452.     a = " " + Group(ClosestGroup).GroupName + " "
  1453.     COLOR DarkKhaki
  1454.     _PRINTSTRING (_WIDTH / 2 - (LEN(a) / 2) * 8, _HEIGHT - (2) * 16), a
  1455.  
  1456. ' Interface
  1457.  
  1458. SUB KeyProcess
  1459.     DIM modifier AS DOUBLE
  1460.     modifier = 0.05
  1461.  
  1462.     'IF (_KEYDOWN(100303) <> 0) OR (_KEYDOWN(100304) <> 0) THEN
  1463.     '    modifier = modifier * 10
  1464.     'END IF
  1465.     IF (_KEYDOWN(87) <> 0) OR (_KEYDOWN(119) <> 0) OR (_KEYDOWN(18432) <> 0) THEN ' W or w or uparrow
  1466.         CALL StrafeCameraNhatMinus
  1467.         IF (ToggleAnimate = 1) THEN
  1468.             PlayerCamera.Velocity.x = PlayerCamera.Velocity.x - modifier * nhat(1)
  1469.             PlayerCamera.Velocity.y = PlayerCamera.Velocity.y - modifier * nhat(2)
  1470.             PlayerCamera.Velocity.z = PlayerCamera.Velocity.z - modifier * nhat(3)
  1471.         END IF
  1472.     END IF
  1473.     IF (_KEYDOWN(83) <> 0) OR (_KEYDOWN(115) <> 0) OR (_KEYDOWN(20480) <> 0) THEN ' S or s or downarrow
  1474.         CALL StrafeCameraNhatPlus
  1475.         IF (ToggleAnimate = 1) THEN
  1476.             PlayerCamera.Velocity.x = PlayerCamera.Velocity.x + modifier * nhat(1)
  1477.             PlayerCamera.Velocity.y = PlayerCamera.Velocity.y + modifier * nhat(2)
  1478.             PlayerCamera.Velocity.z = PlayerCamera.Velocity.z + modifier * nhat(3)
  1479.         END IF
  1480.     END IF
  1481.     IF (_KEYDOWN(65) <> 0) OR (_KEYDOWN(97) <> 0) THEN ' A or a
  1482.         CALL StrafeCameraUhatMinus
  1483.         IF (ToggleAnimate = 1) THEN
  1484.             PlayerCamera.Velocity.x = PlayerCamera.Velocity.x - modifier * uhat(1)
  1485.             PlayerCamera.Velocity.y = PlayerCamera.Velocity.y - modifier * uhat(2)
  1486.             PlayerCamera.Velocity.z = PlayerCamera.Velocity.z - modifier * uhat(3)
  1487.         END IF
  1488.     END IF
  1489.     IF (_KEYDOWN(68) <> 0) OR (_KEYDOWN(100) <> 0) THEN ' D or d
  1490.         CALL StrafeCameraUhatPlus
  1491.         IF (ToggleAnimate = 1) THEN
  1492.             PlayerCamera.Velocity.x = PlayerCamera.Velocity.x + modifier * uhat(1)
  1493.             PlayerCamera.Velocity.y = PlayerCamera.Velocity.y + modifier * uhat(2)
  1494.             PlayerCamera.Velocity.z = PlayerCamera.Velocity.z + modifier * uhat(3)
  1495.         END IF
  1496.     END IF
  1497.     IF (_KEYDOWN(81) <> 0) OR (_KEYDOWN(113) <> 0) THEN ' Q or q
  1498.         CALL StrafeCameraVhatMinus
  1499.         IF (ToggleAnimate = 1) THEN
  1500.             PlayerCamera.Velocity.x = PlayerCamera.Velocity.x - modifier * vhat(1)
  1501.             PlayerCamera.Velocity.y = PlayerCamera.Velocity.y - modifier * vhat(2)
  1502.             PlayerCamera.Velocity.z = PlayerCamera.Velocity.z - modifier * vhat(3)
  1503.         END IF
  1504.     END IF
  1505.     IF (_KEYDOWN(69) <> 0) OR (_KEYDOWN(101) <> 0) THEN ' E or e
  1506.         CALL StrafeCameraVhatPlus
  1507.         IF (ToggleAnimate = 1) THEN
  1508.             PlayerCamera.Velocity.x = PlayerCamera.Velocity.x + modifier * vhat(1)
  1509.             PlayerCamera.Velocity.y = PlayerCamera.Velocity.y + modifier * vhat(2)
  1510.             PlayerCamera.Velocity.z = PlayerCamera.Velocity.z + modifier * vhat(3)
  1511.         END IF
  1512.     END IF
  1513.     IF (_KEYDOWN(19200) <> 0) OR (_KEYDOWN(52) <> 0) THEN CALL RotateUhatMinus: CALL CalculateScreenVectors ' 4
  1514.     IF (_KEYDOWN(19712) <> 0) OR (_KEYDOWN(54) <> 0) THEN CALL RotateUhatPlus: CALL CalculateScreenVectors ' 6
  1515.     IF (_KEYDOWN(56) <> 0) THEN CALL RotateVhatPlus: CALL CalculateScreenVectors ' 8
  1516.     IF (_KEYDOWN(50) <> 0) THEN CALL RotateVhatMinus: CALL CalculateScreenVectors ' 2
  1517.     IF (_KEYDOWN(55) <> 0) THEN CALL RotateClockwise ' 7
  1518.     IF (_KEYDOWN(57) <> 0) THEN CALL RotateCounterclockwise ' 9
  1519.     IF (_KEYDOWN(49) <> 0) THEN CALL RotateUhatMinus: CALL CalculateScreenVectors: CALL RotateClockwise ' 1
  1520.     IF (_KEYDOWN(51) <> 0) THEN CALL RotateUhatPlus: CALL CalculateScreenVectors: CALL RotateCounterclockwise ' 3
  1521.  
  1522.     DIM k AS LONG
  1523.     DIM p AS LONG
  1524.     DIM l AS LONG
  1525.     DIM kh AS INTEGER
  1526.     kh = _KEYHIT
  1527.     IF (kh <> 0) THEN
  1528.         SELECT CASE kh
  1529.             CASE 27
  1530.                 SYSTEM
  1531.             CASE ASC(" ")
  1532.                 ToggleHUD = -ToggleHUD
  1533.             CASE ASC("b"), ASC("B")
  1534.                 DIM gtmp AS LONG
  1535.                 gtmp = NewCube&(1, "Custom block", 350, PlayerCamera.Position.x - 40 * nhat(1), PlayerCamera.Position.y - 40 * nhat(2), PlayerCamera.Position.z - 40 * nhat(3), 10, 10, 10, Lime, Purple, Teal, 0)
  1536.                 CALL ClusterPinch(gtmp)
  1537.             CASE ASC("k"), ASC("K")
  1538.                 ' set -999? delete actual vectors? deal with cluster headers
  1539.                 p = Group(ClosestGroup).Pointer
  1540.                 l = Group(ClosestGroup).Lagger
  1541.                 Group(l).Pointer = p
  1542.                 IF (p <> -999) THEN
  1543.                     Group(p).Lagger = l
  1544.                 END IF
  1545.             CASE ASC("m"), ASC("M")
  1546.                 CALL CreateMission(10)
  1547.             CASE ASC("n"), ASC("N")
  1548.                 FOR k = Group(ClosestGroup).FirstVector TO Group(ClosestGroup).LastVector
  1549.                     vec3Dvel(k, 1) = (RND - .5) * .20
  1550.                     vec3Dvel(k, 2) = (RND - .5) * .20
  1551.                     vec3Dvel(k, 3) = (RND - .5) * .20
  1552.                 NEXT
  1553.             CASE ASC("o"), ASC("O")
  1554.                 PlayerCamera.Position.x = -40
  1555.                 PlayerCamera.Position.y = 30
  1556.                 PlayerCamera.Position.z = 40
  1557.                 uhat(1) = -.2078192: uhat(2) = -.9781672: uhat(3) = 0
  1558.                 vhat(1) = 0: vhat(2) = 0: vhat(3) = 1
  1559.                 CALL CalculateScreenVectors
  1560.             CASE ASC("t"), ASC("T")
  1561.                 ToggleAnimate = -ToggleAnimate
  1562.         END SELECT
  1563.     END IF
  1564.     _KEYCLEAR
  1565.  
  1566. ' Color utility.
  1567.  
  1568. FUNCTION ShadeMix~& (Shade1 AS _UNSIGNED LONG, Shade2 AS _UNSIGNED LONG, Weight AS DOUBLE)
  1569.     ShadeMix~& = _RGB32((1 - Weight) * _RED32(Shade1) + Weight * _RED32(Shade2), (1 - Weight) * _GREEN32(Shade1) + Weight * _GREEN32(Shade2), (1 - Weight) * _BLUE32(Shade1) + Weight * _BLUE32(Shade2))
  1570.  
  1571. ' Cartesian plotting.
  1572.  
  1573. SUB cline (x1 AS DOUBLE, y1 AS DOUBLE, x2 AS DOUBLE, y2 AS DOUBLE, col AS _UNSIGNED LONG)
  1574.     LINE (_WIDTH / 2 + x1, -y1 + _HEIGHT / 2)-(_WIDTH / 2 + x2, -y2 + _HEIGHT / 2), col
  1575.  
  1576. SUB cpset (x1, y1, col AS _UNSIGNED LONG)
  1577.     PSET (_WIDTH / 2 + x1, -y1 + _HEIGHT / 2), col
  1578.  
  1579. SUB ccircle (x1 AS DOUBLE, y1 AS DOUBLE, rad AS DOUBLE, col AS _UNSIGNED LONG)
  1580.     CIRCLE (_WIDTH / 2 + x1, -y1 + _HEIGHT / 2), rad, col
  1581.  
  1582. SUB lineSmooth (x0, y0, x1, y1, c AS _UNSIGNED LONG)
  1583.     'Inspiration credit: {(FellippeHeitor)(qb64.org)(2020)}
  1584.     '                    {https://en.wikipedia.org/w/index.php?title=Xiaolin_Wu%27s_line_algorithm&oldid=852445548}
  1585.     'Edit: {(STxAxTIC)(2020-11-20)(Correction to alpha channel.)}
  1586.  
  1587.     DIM plX AS INTEGER, plY AS INTEGER, plI
  1588.  
  1589.     DIM steep AS _BYTE
  1590.     steep = ABS(y1 - y0) > ABS(x1 - x0)
  1591.  
  1592.     IF steep THEN
  1593.         SWAP x0, y0
  1594.         SWAP x1, y1
  1595.     END IF
  1596.  
  1597.     IF x0 > x1 THEN
  1598.         SWAP x0, x1
  1599.         SWAP y0, y1
  1600.     END IF
  1601.  
  1602.     DIM dx, dy, gradient
  1603.     dx = x1 - x0
  1604.     dy = y1 - y0
  1605.     gradient = dy / dx
  1606.  
  1607.     IF dx = 0 THEN
  1608.         gradient = 1
  1609.     END IF
  1610.  
  1611.     'handle first endpoint
  1612.     DIM xend, yend, xgap, xpxl1, ypxl1
  1613.     xend = _ROUND(x0)
  1614.     yend = y0 + gradient * (xend - x0)
  1615.     xgap = (1 - ((x0 + .5) - INT(x0 + .5)))
  1616.     xpxl1 = xend 'this will be used in the main loop
  1617.     ypxl1 = INT(yend)
  1618.     IF steep THEN
  1619.         plX = ypxl1
  1620.         plY = xpxl1
  1621.         plI = (1 - (yend - INT(yend))) * xgap
  1622.         GOSUB plot
  1623.  
  1624.         plX = ypxl1 + 1
  1625.         plY = xpxl1
  1626.         plI = (yend - INT(yend)) * xgap
  1627.         GOSUB plot
  1628.     ELSE
  1629.         plX = xpxl1
  1630.         plY = ypxl1
  1631.         plI = (1 - (yend - INT(yend))) * xgap
  1632.         GOSUB plot
  1633.  
  1634.         plX = xpxl1
  1635.         plY = ypxl1 + 1
  1636.         plI = (yend - INT(yend)) * xgap
  1637.         GOSUB plot
  1638.     END IF
  1639.  
  1640.     DIM intery
  1641.     intery = yend + gradient 'first y-intersection for the main loop
  1642.  
  1643.     'handle second endpoint
  1644.     DIM xpxl2, ypxl2
  1645.     xend = _ROUND(x1)
  1646.     yend = y1 + gradient * (xend - x1)
  1647.     xgap = ((x1 + .5) - INT(x1 + .5))
  1648.     xpxl2 = xend 'this will be used in the main loop
  1649.     ypxl2 = INT(yend)
  1650.     IF steep THEN
  1651.         plX = ypxl2
  1652.         plY = xpxl2
  1653.         plI = (1 - (yend - INT(yend))) * xgap
  1654.         GOSUB plot
  1655.  
  1656.         plX = ypxl2 + 1
  1657.         plY = xpxl2
  1658.         plI = (yend - INT(yend)) * xgap
  1659.         GOSUB plot
  1660.     ELSE
  1661.         plX = xpxl2
  1662.         plY = ypxl2
  1663.         plI = (1 - (yend - INT(yend))) * xgap
  1664.         GOSUB plot
  1665.  
  1666.         plX = xpxl2
  1667.         plY = ypxl2 + 1
  1668.         plI = (yend - INT(yend)) * xgap
  1669.         GOSUB plot
  1670.     END IF
  1671.  
  1672.     'main loop
  1673.     DIM x
  1674.     IF steep THEN
  1675.         FOR x = xpxl1 + 1 TO xpxl2 - 1
  1676.             plX = INT(intery)
  1677.             plY = x
  1678.             plI = (1 - (intery - INT(intery)))
  1679.             GOSUB plot
  1680.  
  1681.             plX = INT(intery) + 1
  1682.             plY = x
  1683.             plI = (intery - INT(intery))
  1684.             GOSUB plot
  1685.  
  1686.             intery = intery + gradient
  1687.         NEXT
  1688.     ELSE
  1689.         FOR x = xpxl1 + 1 TO xpxl2 - 1
  1690.             plX = x
  1691.             plY = INT(intery)
  1692.             plI = (1 - (intery - INT(intery)))
  1693.             GOSUB plot
  1694.  
  1695.             plX = x
  1696.             plY = INT(intery) + 1
  1697.             plI = (intery - INT(intery))
  1698.             GOSUB plot
  1699.  
  1700.             intery = intery + gradient
  1701.         NEXT
  1702.     END IF
  1703.  
  1704.     EXIT SUB
  1705.  
  1706.     plot:
  1707.     ' Change to regular PSET for standard coordinate orientation.
  1708.     CALL cpset(plX, plY, _RGB32(_RED32(c), _GREEN32(c), _BLUE32(c), plI * _ALPHA32(c)))
  1709.     RETURN
  1710.  
  1711. ' Camera transformation
  1712.  
  1713. SUB PlayerDynamics
  1714.     DIM k AS INTEGER
  1715.  
  1716.     IF (ToggleAnimate = 1) THEN
  1717.         PlayerCamera.Velocity.x = .95 * PlayerCamera.Velocity.x
  1718.         PlayerCamera.Velocity.y = .95 * PlayerCamera.Velocity.y
  1719.         PlayerCamera.Velocity.z = .95 * PlayerCamera.Velocity.z
  1720.         PlayerCamera.Position.x = PlayerCamera.Position.x + PlayerCamera.Velocity.x
  1721.         PlayerCamera.Position.y = PlayerCamera.Position.y + PlayerCamera.Velocity.y
  1722.         PlayerCamera.Position.z = PlayerCamera.Position.z + PlayerCamera.Velocity.z
  1723.     END IF
  1724.  
  1725.     FOR k = 1 TO MissionTicker
  1726.         IF (Group(ClosestGroup).GroupName = Mission(k).Label) THEN
  1727.             IF (Mission(k).Discovered = 0) THEN
  1728.                 Mission(k).Discovered = 1
  1729.                 SOUND 500, .25
  1730.             END IF
  1731.         END IF
  1732.     NEXT
  1733.  
  1734. SUB RotateUhatPlus
  1735.     uhat(1) = uhat(1) + nhat(1) * .0333
  1736.     uhat(2) = uhat(2) + nhat(2) * .0333
  1737.     uhat(3) = uhat(3) + nhat(3) * .0333
  1738.  
  1739. SUB RotateUhatMinus
  1740.     uhat(1) = uhat(1) - nhat(1) * .0333
  1741.     uhat(2) = uhat(2) - nhat(2) * .0333
  1742.     uhat(3) = uhat(3) - nhat(3) * .0333
  1743.  
  1744. SUB RotateVhatPlus
  1745.     vhat(1) = vhat(1) + nhat(1) * .0333
  1746.     vhat(2) = vhat(2) + nhat(2) * .0333
  1747.     vhat(3) = vhat(3) + nhat(3) * .0333
  1748.  
  1749. SUB RotateVhatMinus
  1750.     vhat(1) = vhat(1) - nhat(1) * .0333
  1751.     vhat(2) = vhat(2) - nhat(2) * .0333
  1752.     vhat(3) = vhat(3) - nhat(3) * .0333
  1753.  
  1754. SUB RotateCounterclockwise
  1755.     DIM v1 AS DOUBLE
  1756.     DIM v2 AS DOUBLE
  1757.     DIM v3 AS DOUBLE
  1758.     v1 = vhat(1)
  1759.     v2 = vhat(2)
  1760.     v3 = vhat(3)
  1761.     vhat(1) = v1 + uhat(1) * .0333
  1762.     vhat(2) = v2 + uhat(2) * .0333
  1763.     vhat(3) = v3 + uhat(3) * .0333
  1764.     uhat(1) = uhat(1) - v1 * .0333
  1765.     uhat(2) = uhat(2) - v2 * .0333
  1766.     uhat(3) = uhat(3) - v3 * .0333
  1767.  
  1768. SUB RotateClockwise
  1769.     DIM v1 AS DOUBLE
  1770.     DIM v2 AS DOUBLE
  1771.     DIM v3 AS DOUBLE
  1772.     v1 = vhat(1)
  1773.     v2 = vhat(2)
  1774.     v3 = vhat(3)
  1775.     vhat(1) = v1 - uhat(1) * .0333
  1776.     vhat(2) = v2 - uhat(2) * .0333
  1777.     vhat(3) = v3 - uhat(3) * .0333
  1778.     uhat(1) = uhat(1) + v1 * .0333
  1779.     uhat(2) = uhat(2) + v2 * .0333
  1780.     uhat(3) = uhat(3) + v3 * .0333
  1781.  
  1782. SUB StrafeCameraUhatPlus
  1783.     PlayerCamera.Position.x = PlayerCamera.Position.x + uhat(1)
  1784.     PlayerCamera.Position.y = PlayerCamera.Position.y + uhat(2)
  1785.     PlayerCamera.Position.z = PlayerCamera.Position.z + uhat(3)
  1786.  
  1787. SUB StrafeCameraUhatMinus
  1788.     PlayerCamera.Position.x = PlayerCamera.Position.x - uhat(1)
  1789.     PlayerCamera.Position.y = PlayerCamera.Position.y - uhat(2)
  1790.     PlayerCamera.Position.z = PlayerCamera.Position.z - uhat(3)
  1791.  
  1792. SUB StrafeCameraVhatPlus
  1793.     PlayerCamera.Position.x = PlayerCamera.Position.x + vhat(1)
  1794.     PlayerCamera.Position.y = PlayerCamera.Position.y + vhat(2)
  1795.     PlayerCamera.Position.z = PlayerCamera.Position.z + vhat(3)
  1796.  
  1797. SUB StrafeCameraVhatMinus
  1798.     PlayerCamera.Position.x = PlayerCamera.Position.x - vhat(1)
  1799.     PlayerCamera.Position.y = PlayerCamera.Position.y - vhat(2)
  1800.     PlayerCamera.Position.z = PlayerCamera.Position.z - vhat(3)
  1801.  
  1802. SUB StrafeCameraNhatPlus
  1803.     PlayerCamera.Position.x = PlayerCamera.Position.x + nhat(1)
  1804.     PlayerCamera.Position.y = PlayerCamera.Position.y + nhat(2)
  1805.     PlayerCamera.Position.z = PlayerCamera.Position.z + nhat(3)
  1806.  
  1807. SUB StrafeCameraNhatMinus
  1808.     PlayerCamera.Position.x = PlayerCamera.Position.x - nhat(1)
  1809.     PlayerCamera.Position.y = PlayerCamera.Position.y - nhat(2)
  1810.     PlayerCamera.Position.z = PlayerCamera.Position.z - nhat(3)
  1811.  
  1812. '''
  1813.  
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 18, 2020, 12:04:06 pm
Hi @STxAxTIC

I tried your latest and not getting it, maybe need more instruction. By walking forward I assume arrow up key, I do encounter snow that I see and Winter Wonder Land (something like that) in descriptor but see no snowmen or trees I keep going and I seem to end up in space? Some turning left and right required? I did a little of that too, maybe more?
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 18, 2020, 12:29:02 pm
Well I am looking forward to Fellippe's, 2018 Christmas entry was a beauty!
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: STxAxTIC on December 18, 2020, 12:39:58 pm
bplus do you spend any time in 3D simulations of any kind? i can make a video i suppose...

EDIT: I just found a snowman off the terrain, so I definitely have a placement variable wrong. Consider the above a prototype, haha.
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 19, 2020, 03:50:37 pm
Well while waiting for STx to fix his, Fellippe, _vince, Ashish? TempodiBasic? I made another one that was going to go into my Christmas Album:

Programmable Tree Lights version 1 (proof of concept):
Code: QB64: [Select]
  1. _TITLE "Programmable Tree Lights, press (&hold) 1, 2, 3 for program" ' b+ 2020-12-19
  2. CONST Xmax = 700, Ymax = 700, NLites = 55, RLite = 30
  3. TYPE LiteSystem
  4.     X AS SINGLE
  5.     Y AS SINGLE
  6.     C AS _UNSIGNED LONG
  7. DIM SHARED L(1 TO NLites) AS LiteSystem
  8. SCREEN _NEWIMAGE(Xmax, Ymax, 32)
  9. _DELAY .25
  10.  
  11. ' Get locations for a pyramid of circles st: ========================================================
  12. 'let n = number of circles at base of pile
  13. n = 10
  14.  
  15. 'let r = radius of each circle
  16. r = RLite
  17.  
  18. 'let base be total length of pile
  19. baseLength = 2 * r * n
  20.  
  21. 'center pyramid in middle of screen
  22. startx = (Xmax - baseLength) / 2
  23.  
  24.  
  25. 'Stringing the lights on tree, adjusted to fit mostly on the tree
  26. 'stacking circles that form equilateral triangles at their origins have a height change of
  27. deltaHeight = r * 3 ^ .5 'r times the sqr(3)
  28. i = 1
  29. FOR row = n TO 1 STEP -1
  30.     IF row = n THEN y = Ymax - r - 1 ELSE y = y - deltaHeight
  31.     FOR col = 1 TO row
  32.         x = startx + col * 2 * r - r
  33.         IF RND < .5 THEN
  34.             r1 = (RND < .45): r2 = (RND < .33): r3 = (RND < .33)
  35.             IF r1 = 0 AND r2 = 0 AND r3 = 0 THEN
  36.                 c~& = _RGB32(100 + RND * 155, 0, RND * 255)
  37.             ELSE
  38.                 c~& = _RGB32(r1 * -(100 + RND * 155), r2 * -(100 + RND * 155), r3 * -(100 + RND * 155))
  39.             END IF
  40.         ELSE
  41.             c~& = _RGB32(100 + RND * 155, 100 + RND * 155, 100 + RND * 155)
  42.         END IF
  43.         L(i).X = x: L(i).Y = y - 3.2 * r - 50: L(i).C = c~&
  44.         i = i + 1
  45.     NEXT
  46.     startx = startx + r
  47.  
  48. ' making the stars
  49. horizon = Ymax - 4 * r
  50. nstars = 100
  51. DIM xstar(100), ystar(100), rstar(100)
  52. FOR i = 1 TO 100
  53.     xstar(i) = RND * (Xmax): ystar(i) = RND * horizon:
  54.     IF i < 75 THEN
  55.         rstar(i) = 0
  56.     ELSEIF i < 95 THEN
  57.         rstar(i) = 1
  58.     ELSE
  59.         rstar(i) = 2
  60.     END IF
  61.  
  62. ' making the background
  63. back = _NEWIMAGE(_WIDTH, _HEIGHT, 32)
  64. FOR i = 0 TO horizon
  65.     LINE (0, i)-(Xmax, i), _RGB32(i / horizon * 70, i / horizon * 22, 60 * (i) / horizon)
  66. land = Ymax - horizon
  67. FOR i = horizon TO Ymax
  68.     cc = 128 + (i - horizon) / land * 127
  69.     LINE (0, i)-(Xmax, i), _RGB32(cc, cc, cc)
  70. FOR i = 1 TO 100
  71.     fcirc xstar(i), ystar(i), rstar(i), &HFFEEEEFF
  72. _PUTIMAGE , 0, back
  73.  
  74. program$ = "1" ' just random
  75. show program$ ' avoid the pause for key checking
  76.     t! = TIMER(.01) '                 needed this for better response to keypresses at such low _LIMIT on loop
  77.     WHILE TIMER(.01) - t! < .25
  78.         k$ = INKEY$
  79.         IF LEN(k$) THEN
  80.             IF INSTR("123", k$) > 0 THEN program$ = k$
  81.             EXIT WHILE
  82.         END IF
  83.         _LIMIT 400
  84.     WEND '                           dang!   still have to hold key down for a while
  85.     _PUTIMAGE , back, 0
  86.     show program$
  87.     _DISPLAY
  88.     _LIMIT 5
  89.  
  90. SUB show (prog$)
  91.     STATIC offset
  92.     Pinetree 25, 30, 650, 600
  93.     SELECT CASE prog$
  94.         CASE "1" 'random blink mostly on
  95.             FOR i = 1 TO NLites
  96.                 IF RND < .8 THEN Lite L(i).X, L(i).Y, L(i).C
  97.             NEXT
  98.         CASE "2" ' random red white and blue
  99.             FOR i = 1 TO NLites
  100.                 r = RND
  101.                 IF r < .33 THEN
  102.                     Lite L(i).X, L(i).Y, &HFFCC0000
  103.                 ELSEIF r < .66 THEN
  104.                     Lite L(i).X, L(i).Y, &HFFFFFFFF
  105.                 ELSE
  106.                     Lite L(i).X, L(i).Y, &HFF0000BB
  107.                 END IF
  108.             NEXT
  109.         CASE "3" ' twinkle
  110.             FOR i = 1 TO NLites
  111.                 fcirc L(i).X, L(i).Y, 2, &HFF00DDFF
  112.                 IF RND < .05 THEN Lite L(i).X, L(i).Y, &HFF00DDFF
  113.             NEXT
  114.     END SELECT
  115.     _TITLE "Program: " + prog$ + "  Programmable Tree Lights, press (&hold) 1, 2, 3 for program"
  116.  
  117. SUB Lite (x, y, c AS _UNSIGNED LONG)
  118.     FOR r = 25 TO 0 STEP -1
  119.         fcirc x, y, r, &H01FFFFFF
  120.     NEXT
  121.     fcirc x, y, 4, c
  122.  
  123. SUB Pinetree (treeX, treeY, wide, high)
  124.     'tannen baum by PeterMaria W  orig 440x460
  125.     'fits here  LINE (0, 0)-(440, 410), , B
  126.     STATIC t&
  127.     IF t& = 0 THEN
  128.         t& = _NEWIMAGE(440, 410, 32)
  129.         _DEST t&
  130.         bpx = 220: bpy = 410
  131.         tpx = bpx
  132.         FOR aa = -4 TO 4
  133.             bpxx = bpx + aa
  134.             bpyy = bpy - 390
  135.             LINE (X + bpxx, y + bpy)-(X + bpx, y + bpyy), _RGB32(30, 30, 0)
  136.         NEXT
  137.         ra = 160
  138.         tpy = bpy - 40
  139.         FOR ht = 1 TO 40
  140.             FOR xs = -100 TO 100 STEP 40
  141.                 xsh = xs / 100
  142.                 rs = RND * 4 / 10
  143.                 tpxx = tpx + (xsh * ra)
  144.                 tpyy = tpy - rs * ra
  145.                 LINE (X + tpx, y + tpy)-(X + tpxx, y + tpyy), _RGB32(50, 40, 20)
  146.                 FOR aa = 1 TO 30
  147.                     fra = RND * 10 / 10 * ra
  148.                     x1 = tpx + (xsh * fra)
  149.                     y1 = tpy - rs * fra
  150.                     x2 = tpx + xsh * (fra + ra / 5)
  151.                     y2 = tpy - rs * fra + (-rs + (RND * 8) / 10 - 0.4) * (ra / 5)
  152.                     LINE (X + x1, y + y1)-(X + x2, y + y2), _RGB32(RND * 80, RND * 70 + 40, RND * 60)
  153.                 NEXT
  154.             NEXT
  155.             ra = ra - 4
  156.             tpy = tpy - 9
  157.         NEXT
  158.         _DEST 0
  159.     END IF
  160.     wf = wide / 440: hf = high / 410
  161.     _PUTIMAGE (treeX, treeY)-STEP(440 * wf, 410 * hf), t&, 0
  162.  
  163. 'from Steve Gold standard
  164. SUB fcirc (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  165.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  166.     DIM X AS INTEGER, Y AS INTEGER
  167.     Radius = ABS(R): RadiusError = -Radius: X = Radius: Y = 0
  168.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  169.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  170.     WHILE X > Y
  171.         RadiusError = RadiusError + Y * 2 + 1
  172.         IF RadiusError >= 0 THEN
  173.             IF X <> Y + 1 THEN
  174.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  175.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  176.             END IF
  177.             X = X - 1
  178.             RadiusError = RadiusError - X * 2
  179.         END IF
  180.         Y = Y + 1
  181.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  182.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  183.     WEND
  184.  
  185.  

Feel free to take this and run with it, a 1000 ways to go from here! :)
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Dav on December 19, 2020, 06:29:18 pm
You all are making such great stuff!!  Very impressive.  Works of art, really.

I tried making a good looking Christmas tree in code, but just couldn't.  So I thought I'd share our Christmas tree here at home which I think is special.  Every ornament was handmade by my mom, who is no longer with us. Guess I'm breaking the no external files suggestion, but @FellippeHeitor you did hint at a musical serenade during the zoom meeting, so the attachment is filling that suggestion.

Here's a peek into Christmas around here.  A screensaver of our Christmas tree with some 'Silent Night' background music I quickly recorded today.  You will need the attachment davstree.dat.

- Dav

Code: QB64: [Select]
  1. 'DavsTree.bas
  2. '============
  3. 'Screensaver of my Christmas tree 2020
  4. 'Coded by Dav, DEC/2020, dedicated to my mother.
  5. 'MERRY CHRISTMAS EVERYONE!
  6.  
  7. 'I just wanted to share what Christmas look around here.
  8. 'Here's our tree.  Every ornament was handmade by my mother.
  9. 'I'm improving on 'Silent Night'for the background music.
  10. 'Just having some fun playing, mistakes and all!   - Dav
  11.  
  12. SCREEN _NEWIMAGE(800, 600, 32)
  13.  
  14. 'Start music
  15. b& = _SNDOPEN("davstree.dat"): _SNDPLAY b&
  16.  
  17. FOR f = 1 TO 13
  18.     ShowFrame "davstree.dat", f
  19.  
  20. 'stop music if playing
  21.  
  22.  
  23. :::::::::::::
  24. ::::: END:::: 'Merry Christmas!
  25. :::::::::::::
  26.  
  27. '=============================================================
  28. 'Adapted from my QBV video format...
  29. SUB ShowFrame (file$, framenum)
  30.     FF = FREEFILE
  31.     OPEN file$ FOR BINARY AS FF
  32.     SEEK FF, LOF(FF) - 19
  33.     Ver$ = INPUT$(7, FF) 'Version of QBV video format
  34.     Audio$ = INPUT$(1, FF) 'Audio setting
  35.     vidwidth = CVI(INPUT$(2, FF)) 'Width of video
  36.     vidheight = CVI(INPUT$(2, FF)) 'Height of video
  37.     VidData = CVL(INPUT$(4, FF)) 'Place in file Video data starts
  38.     frames = CVI(INPUT$(2, FF)) 'How many frames in file
  39.     fps = CVI(INPUT$(2, FF)) 'How many fps
  40.     SEEK FF, VidData + 1
  41.     FOR vid = 1 TO frames
  42.         framelen$ = INPUT$(4, FF)
  43.         frame$ = INPUT$(CVL(framelen$), FF)
  44.         IF vid = framenum THEN EXIT FOR
  45.     NEXT
  46.     'make a temp jpg on disk
  47.     FFF = FREEFILE
  48.     OPEN "_tmp_qbv_frame_.jpg" FOR OUTPUT AS FFF
  49.     PRINT #FFF, frame$;
  50.     CLOSE FFF
  51.     'load it
  52.     frm& = _LOADIMAGE("_tmp_qbv_frame_.jpg")
  53.     'erase it
  54.     KILL "_tmp_qbv_frame_.jpg"
  55.  
  56.  
  57.     'fade in from black...
  58.     FOR a = 255 TO 0 STEP -4
  59.         _PUTIMAGE (0, 0), frm&
  60.         LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA(0, 0, 0, a), BF
  61.         _LIMIT 30
  62.         _DISPLAY
  63.     NEXT
  64.  
  65.     _DELAY 3.9
  66.  
  67.     'fade out to black
  68.     FOR a = 0 TO 255 STEP 4
  69.         _PUTIMAGE (0, 0), frm&
  70.         LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA(0, 0, 0, a), BF
  71.         _LIMIT 30
  72.         _DISPLAY
  73.     NEXT
  74.  
  75.     _FREEIMAGE frm&
  76.     CLOSE FF
  77.  
  78.  
  79.  

Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 19, 2020, 06:48:56 pm
That was really nice, handmade ornaments remind me of Christmas's past. I think my sister took off with the ones I grew up with when she moved to Denver. We had things made from clothespins ( 2 varieties), Popsicle sticks, pine cones, foil, pie tins, tiny photos... Specially valued were 3 old ornaments from Grandma's house one was a small sphere with clock face. She used to host Christmas with 2 sets of families for like 25 years.

Love the music with the story!
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 19, 2020, 09:15:02 pm
Here is version #2 of Programmable Tree Lights, new pyramid scheme, 10 color sets, 4 direction modes:
Press digit for color set, letter keys for wave direction h = horizontal, v = vertical, d = diagonal, e = diagonal the other way :)
Code: QB64: [Select]
  1. _TITLE "Programmable Tree Lights v2" ' b+ 2020-12-19
  2. CONST Xmax = 700, Ymax = 700, N_Rows = 10, N_Cols = 2 * N_Rows - 1
  3. CONST X_Spacer = 30, Y_Spacer = 52, X_Offset = 50
  4. TYPE ColorSeed
  5.     Red AS SINGLE
  6.     Green AS SINGLE
  7.     Blue AS SINGLE
  8. DIM SHARED ColorSet(10) AS ColorSeed, ColorSetIndex AS LONG
  9. DIM SHARED pR, pG, pB, pN, pStart, pMode$
  10. DIM SHARED TG(1 TO N_Cols, 1 TO N_Rows) AS LONG
  11. SCREEN _NEWIMAGE(Xmax, Ymax, 32)
  12. _DELAY .25
  13.  
  14. ' setup some color seeds in ColorSet user can change out with Shift + digit key
  15. FOR i = 0 TO 9 ' 10 random color seeds
  16.     resetPlasma
  17.     ColorSet(i).Red = pR: ColorSet(i).Green = pG: ColorSet(i).Blue = pB
  18.  
  19. 'Stringing the lights on tree, adjusted to fit mostly on the tree   2*N - 1 Pryramid
  20. FOR row = 1 TO 10
  21.     l$ = xStr$(2 * row - 1, "X")
  22.     o$ = xStr$(10 - row, "O")
  23.     b$ = o$ + l$ + o$
  24.     FOR Col = 1 TO N_Cols
  25.         IF MID$(b$, Col, 1) = "O" THEN TG(Col, row) = 0 ELSE TG(Col, row) = -1
  26.     NEXT
  27.     PRINT b$
  28.  
  29. ' making the stars
  30. horizon = Ymax - 4 * r
  31. nstars = 100
  32. DIM xstar(100), ystar(100), rstar(100)
  33. FOR i = 1 TO 100
  34.     xstar(i) = RND * (Xmax): ystar(i) = RND * horizon:
  35.     IF i < 75 THEN
  36.         rstar(i) = 0
  37.     ELSEIF i < 95 THEN
  38.         rstar(i) = 1
  39.     ELSE
  40.         rstar(i) = 2
  41.     END IF
  42. ' make a circle tree and align circles to tree with spacers and offsets with new Pyramid Scheme
  43. 'Pinetree 25, 30, 650, 600
  44. 'FOR row = 1 TO N_Rows
  45. '    FOR col = 1 TO N_Cols
  46. '        IF TG(col, row) THEN CIRCLE (col * X_Spacer + X_Offset, row * Y_Spacer), 10
  47. '    NEXT
  48. 'NEXT
  49.  
  50. ' making the background
  51. back = _NEWIMAGE(_WIDTH, _HEIGHT, 32)
  52. horizon = Ymax - 100
  53. FOR i = 0 TO horizon
  54.     LINE (0, i)-(Xmax, i), _RGB32(i / horizon * 70, i / horizon * 22, 60 * (i) / horizon)
  55. land = Ymax - horizon
  56. FOR i = horizon TO Ymax
  57.     cc = 128 + (i - horizon) / land * 127
  58.     LINE (0, i)-(Xmax, i), _RGB32(cc, cc, cc)
  59. FOR i = 1 TO 100
  60.     fcirc xstar(i), ystar(i), rstar(i), &HFFEEEEFF
  61. _PUTIMAGE , 0, back
  62.  
  63. ColorSetIndex = 1: pMode$ = "h"
  64. show ' avoid the pause for key checking
  65.     k$ = INKEY$
  66.     IF LEN(k$) THEN
  67.         IF INSTR("0123456789", k$) > 0 THEN
  68.             ColorSetIndex = VAL(k$)
  69.         ELSEIF INSTR("vhde", k$) > 0 THEN
  70.             pMode$ = k$
  71.         END IF
  72.     END IF
  73.     _PUTIMAGE , back, 0
  74.     show
  75.     _DISPLAY
  76.     _LIMIT 10
  77.  
  78. SUB show
  79.     Pinetree 25, 30, 650, 600
  80.     _TITLE "Programmable Tree Lights (0-9) Color Set: " + TS$(ColorSetIndex) + "  (v, h, d, e) Mode: " + pMode$
  81.     pR = ColorSet(ColorSetIndex).Red: pG = ColorSet(ColorSetIndex).Green: pB = ColorSet(ColorSetIndex).Blue
  82.     pStart = pStart + 1
  83.     SELECT CASE pMode$
  84.         CASE "h"
  85.             FOR row = 1 TO N_Rows
  86.                 pRow = pStart + row
  87.                 FOR col = 1 TO N_Cols
  88.                     pN = pRow
  89.                     IF TG(col, row) THEN Lite col * X_Spacer + X_Offset, row * Y_Spacer, Plasma~&
  90.                 NEXT
  91.             NEXT
  92.         CASE "v"
  93.             FOR row = 1 TO N_Rows
  94.                 FOR col = 1 TO N_Cols
  95.                     pN = pStart + col
  96.                     IF TG(col, row) THEN Lite col * X_Spacer + X_Offset, row * Y_Spacer, Plasma~&
  97.                 NEXT
  98.             NEXT
  99.         CASE "d"
  100.             FOR row = 1 TO N_Rows
  101.                 FOR col = 1 TO N_Cols
  102.                     pN = pStart + col - row
  103.                     IF TG(col, row) THEN Lite col * X_Spacer + X_Offset, row * Y_Spacer, Plasma~&
  104.                 NEXT
  105.             NEXT
  106.         CASE "e"
  107.             FOR row = 1 TO N_Rows
  108.                 FOR col = 1 TO N_Cols
  109.                     pN = pStart + row + col
  110.                     IF TG(col, row) THEN Lite col * X_Spacer + X_Offset, row * Y_Spacer, Plasma~&
  111.                 NEXT
  112.             NEXT
  113.  
  114.     END SELECT
  115.  
  116. SUB Lite (x, y, c AS _UNSIGNED LONG)
  117.     cAnalysis c, cR, cG, cB, cA
  118.     FOR r = 35 TO 0 STEP -2
  119.         fcirc x, y, r, _RGB32(cR, cG, cB, 1)
  120.     NEXT
  121.     fcirc x, y, 4, c
  122.  
  123. SUB Pinetree (treeX, treeY, wide, high)
  124.     'tannen baum by PeterMaria W  orig 440x460
  125.     'fits here  LINE (0, 0)-(440, 410), , B
  126.     STATIC t&
  127.     IF t& = 0 THEN
  128.         t& = _NEWIMAGE(440, 410, 32)
  129.         _DEST t&
  130.         bpx = 220: bpy = 410
  131.         tpx = bpx
  132.         FOR aa = -4 TO 4
  133.             bpxx = bpx + aa
  134.             bpyy = bpy - 390
  135.             LINE (X + bpxx, y + bpy)-(X + bpx, y + bpyy), _RGB32(30, 30, 0)
  136.         NEXT
  137.         ra = 160
  138.         tpy = bpy - 40
  139.         FOR ht = 1 TO 40
  140.             FOR xs = -100 TO 100 STEP 40
  141.                 xsh = xs / 100
  142.                 rs = RND * 4 / 10
  143.                 tpxx = tpx + (xsh * ra)
  144.                 tpyy = tpy - rs * ra
  145.                 LINE (X + tpx, y + tpy)-(X + tpxx, y + tpyy), _RGB32(50, 40, 20)
  146.                 FOR aa = 1 TO 30
  147.                     fra = RND * 10 / 10 * ra
  148.                     x1 = tpx + (xsh * fra)
  149.                     y1 = tpy - rs * fra
  150.                     x2 = tpx + xsh * (fra + ra / 5)
  151.                     y2 = tpy - rs * fra + (-rs + (RND * 8) / 10 - 0.4) * (ra / 5)
  152.                     LINE (X + x1, y + y1)-(X + x2, y + y2), _RGB32(RND * 80, RND * 70 + 40, RND * 60)
  153.                 NEXT
  154.             NEXT
  155.             ra = ra - 4
  156.             tpy = tpy - 9
  157.         NEXT
  158.         _DEST 0
  159.     END IF
  160.     wf = wide / 440: hf = high / 410
  161.     _PUTIMAGE (treeX, treeY)-STEP(440 * wf, 410 * hf), t&, 0
  162.  
  163. SUB cAnalysis (c AS _UNSIGNED LONG, outRed, outGrn, outBlu, outAlp)
  164.     outRed = _RED32(c): outGrn = _GREEN32(c): outBlu = _BLUE32(c): outAlp = _ALPHA32(c)
  165.  
  166. FUNCTION Plasma~& ()
  167.     pN = pN + 1 'dim shared cN as _Integer64, pR as integer, pG as integer, pB as integer
  168.     Plasma~& = _RGB32(127 + 127 * SIN(pR * pN), 127 + 127 * SIN(pG * pN), 127 + 127 * SIN(pB * pN))
  169.  
  170. SUB resetPlasma ()
  171.     pR = RND ^ 2: pG = RND ^ 2: pB = RND ^ 2: pN = 0
  172.  
  173. FUNCTION xStr$ (x, strng$)
  174.     FOR i = 1 TO x
  175.         xStr$ = xStr$ + strng$
  176.     NEXT
  177.  
  178.     TS$ = _TRIM$(STR$(n))
  179.  
  180. 'from Steve Gold standard
  181. SUB fcirc (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  182.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  183.     DIM X AS INTEGER, Y AS INTEGER
  184.     Radius = ABS(R): RadiusError = -Radius: X = Radius: Y = 0
  185.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  186.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  187.     WHILE X > Y
  188.         RadiusError = RadiusError + Y * 2 + 1
  189.         IF RadiusError >= 0 THEN
  190.             IF X <> Y + 1 THEN
  191.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  192.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  193.             END IF
  194.             X = X - 1
  195.             RadiusError = RadiusError - X * 2
  196.         END IF
  197.         Y = Y + 1
  198.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  199.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  200.     WEND
  201.  
  202.  
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Dav on December 20, 2020, 09:41:54 am
Thanks, @bplus.  My wife begs me to throw those old ornaments out every year, but it ain't gonna happen. Haven't ran your last post yet, but the code looks interesting...

- Dav

Title: Re: %uD83C%uDF84%uD83C%uDF81%u2728 Holiday Season - are you ready to code?
Post by: FellippeHeitor on December 20, 2020, 11:24:45 am
@Dav
That.
Was.
So.
Wholesome.

Man, you rocked that Silent Night! That was amazing! Being able to peek through your X-Mas tree and seeing the hand-made ornaments was so heartwarming.

I thank you so much for sharing that piece. It's wonderful.

@everyone else, I'm still to check your pieces... I'll finally begin having some time off in this holiday season. I'll check your entries soon.

Just to make sure we're all on the same page: is it ok to feature you guys' contributions in a video compilation on our youtube channel?

@Dav is it ok to feature your Silent Night rendition on said video?

PS: I'm running it again and watching the temp files being generated one by one in real time in the background! That's so cool!
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: jack on December 20, 2020, 08:53:40 pm
Dav that was awesome :)
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Dav on December 21, 2020, 08:02:34 am
Thanks guys!

@FellippeHeitor: sure, you can use my silent night version on your videos. I wish i had made another recording though, it was a quick 1st take on a cheap keyboard at the last minute, just to add some sound to make it more interesting. Anyway, glad you like it!

Im thinking to expand this idea into a slideshow kit, i have some screen fx and wipes to use.

- Dav
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Petr on December 21, 2020, 08:13:50 am
@Dav: Now I've run your program and it's a really beautiful job. Merry Christmas! :)

@FellippeHeitor: I will be honored if you add a video from my program to a video on the Youtube site QB64.
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Dav on December 21, 2020, 09:38:15 am
Thankyou @Petr. By the way, have you posted the source code of the easy 3d tunnel video you have on your youtube channel? Looks cool!

- Dav
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Petr on December 21, 2020, 10:32:22 am
@Dav: This is just an appetizer :) The code will be available as soon as I add the turns.
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Adrian on December 22, 2020, 04:46:51 am
very cool programs everyone!
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: SMcNeill on December 22, 2020, 07:13:48 pm
And something which might make a nice little screensaver of sorts, for the season:

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(1280, 720, 32)
  2.  
  3. TYPE Firework
  4.     x AS _FLOAT
  5.     y AS _FLOAT
  6.     Xchange AS _FLOAT
  7.     Ychange AS _FLOAT
  8.     countdown AS _FLOAT
  9.  
  10. TYPE Sparks
  11.     x AS _FLOAT
  12.     y AS _FLOAT
  13.     Xchange AS _FLOAT
  14.     Ychange AS _FLOAT
  15.     countdown AS _FLOAT
  16.  
  17.  
  18.  
  19.  
  20. DIM SHARED Firework(20) AS Firework
  21. DIM SHARED Sparks(180 * 21) AS Sparks
  22. FOR i = 0 TO UBOUND(firework): GenerateFirework (i): NEXT
  23. f = _LOADFONT("OLDENGL.TTF", 72)
  24.  
  25.     LINE (0, 0)-(1280, 720), _RGBA32(0, 0, 0, 10), BF
  26.     DisplayMessage
  27.     FOR i = 0 TO UBOUND(firework)
  28.         Firework(i).x = Firework(i).x + Firework(i).Xchange
  29.         Firework(i).y = Firework(i).y + Firework(i).Ychange
  30.         CircleFill Firework(i).x, Firework(i).y, 5, Firework(i).color
  31.         IF Firework(i).countdown < ExtendedTimer THEN
  32.             GenerateSparks (i)
  33.             GenerateFirework (i)
  34.         END IF
  35.     NEXT
  36.     FOR i = 0 TO UBOUND(sparks)
  37.         Sparks(i).x = Sparks(i).x + Sparks(i).Xchange
  38.         Sparks(i).y = Sparks(i).y + Sparks(i).Ychange
  39.         CircleFill Sparks(i).x, Sparks(i).y, 2, Sparks(i).color
  40.         IF Sparks(i).countdown < ExtendedTimer THEN Sparks(i).color = 0
  41.     NEXT
  42.     _LIMIT 60
  43.     _DISPLAY
  44.  
  45.  
  46.  
  47. SUB GenerateFirework (which)
  48.     Firework(which).x = RND * _WIDTH(0)
  49.     Firework(which).y = 720
  50.     DO: Firework(which).Xchange = RND * 8 - 4: LOOP UNTIL Firework(which).Xchange <> 0
  51.     DO: Firework(which).Ychange = RND * -4: LOOP UNTIL Firework(which).Ychange <> 0
  52.     Firework(which).color = _RGB32(RND * 256, RND * 256, RND * 256)
  53.     Firework(which).countdown = ExtendedTimer + RND * 8
  54.  
  55. SUB GenerateSparks (which)
  56.     count = 180 * which - 1
  57.     DIM cd AS _FLOAT: cd = ExtendedTimer + RND * 4
  58.     FOR j = 0 TO _D2R(360) STEP _D2R(2)
  59.         count = count + 1
  60.         Sparks(count).x = Firework(which).x
  61.         Sparks(count).y = Firework(which).y
  62.         r = RND * 3
  63.         Sparks(count).Xchange = SIN(j) * r
  64.         Sparks(count).Ychange = COS(j) * r
  65.         Sparks(count).color = Firework(which).color
  66.         Sparks(count).countdown = ExtendedTimer + RND * 4
  67.     NEXT
  68.  
  69.  
  70. SUB DisplayMessage
  71.     STATIC T AS _FLOAT, c AS _FLOAT
  72.     IF T = 0 THEN T = ExtendedTimer
  73.     et = ExtendedTimer - T 'elapsed time
  74.     SELECT CASE et
  75.         CASE IS < 8
  76.             c = 255 / 8 * (et - 0) 'fade in
  77.             text$ = "Merry Christmas"
  78.         CASE IS < 16
  79.             c = 255 - 255 / 8 * (et - 8) 'fade out
  80.             text$ = "Merry Christmas"
  81.         CASE IS < 32
  82.             c = 255 / 8 * (et - 16) 'fade in
  83.             text$ = "Happy New Years"
  84.         CASE IS < 48
  85.             c = 255 - 255 / 8 * (et - 32) 'fade out
  86.             text$ = "Happy New Years"
  87.         CASE ELSE
  88.             T = ExtendedTimer
  89.     END SELECT
  90.     COLOR _RGB32(c), 0
  91.     _PRINTSTRING ((_WIDTH - _PRINTWIDTH(text$)) / 2, 320), text$
  92.  
  93.  
  94.  
  95. SUB CircleFill (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  96.     ' CX = center x coordinate
  97.     ' CY = center y coordinate
  98.     '  R = radius
  99.     '  C = fill color
  100.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  101.     DIM X AS INTEGER, Y AS INTEGER
  102.     Radius = ABS(R)
  103.     RadiusError = -Radius
  104.     X = Radius
  105.     Y = 0
  106.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  107.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  108.     WHILE X > Y
  109.         RadiusError = RadiusError + Y * 2 + 1
  110.         IF RadiusError >= 0 THEN
  111.             IF X <> Y + 1 THEN
  112.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  113.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  114.             END IF
  115.             X = X - 1
  116.             RadiusError = RadiusError - X * 2
  117.         END IF
  118.         Y = Y + 1
  119.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  120.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  121.     WEND
  122.  
  123. FUNCTION ExtendedTimer##
  124.     d$ = DATE$
  125.     l = INSTR(d$, "-")
  126.     l1 = INSTR(l + 1, d$, "-")
  127.     m = VAL(LEFT$(d$, l))
  128.     d = VAL(MID$(d$, l + 1))
  129.     y = VAL(MID$(d$, l1 + 1)) - 1970
  130.     FOR i = 1 TO m
  131.         SELECT CASE i 'Add the number of days for each previous month passed
  132.             CASE 1: d = d 'January doestn't have any carry over days.
  133.             CASE 2, 4, 6, 8, 9, 11: d = d + 31
  134.             CASE 3: d = d + 28
  135.             CASE 5, 7, 10, 12: d = d + 30
  136.         END SELECT
  137.     NEXT
  138.     FOR i = 1 TO y
  139.         d = d + 365
  140.     NEXT
  141.     FOR i = 2 TO y STEP 4
  142.         IF m > 2 THEN d = d + 1 'add an extra day for leap year every 4 years, starting in 1970
  143.     NEXT
  144.     d = d - 1 'for year 2000
  145.     s~&& = d * 24 * 60 * 60 'Seconds are days * 24 hours * 60 minutes * 60 seconds
  146.     ExtendedTimer## = (s~&& + TIMER)
  147.  

If needed, font can be downloaded here: https://www.wfonts.com/download/data/2015/11/25/oldenglish/OLDENGL.TTF
Title: Re: %uD83C%uDF84%uD83C%uDF81%u2728 Holiday Season - are you ready to code?
Post by: Dav on December 22, 2020, 09:59:32 pm
@Dav is it ok to feature your Silent Night rendition on said video?

@FellippeHeitor would you need a higher quality sound file for that?  I haven't deleted the original recording yet (was about too then I thought of this request).  The one in the screen save was saved at the lowest quality to make the filesize attachment limit.

@Steve:  Nice fireworks!  I had to comment the olde english font first, my system doesn't have it.

- Dav
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: FellippeHeitor on December 22, 2020, 10:01:14 pm
@Dav I was gonna extract it from your resource file, but a higher quality version sure comes handy.
Title: Re: %uD83C%uDF84%uD83C%uDF81%u2728 Holiday Season - are you ready to code?
Post by: SMcNeill on December 23, 2020, 01:15:20 am
@Steve:  Nice fireworks!  I had to comment the olde english font first, my system doesn't have it.

- Dav

I thought it was a standard Windows font, but after doing some digging, it seems it's from MS Office (Word).  There's a link to it above, now, if you want to see it with the proper font is use.  ;)
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: FellippeHeitor on December 23, 2020, 10:49:10 am
My lazy 2020 submission: Xmas Themed LED Gif Player (loud beeping song warning!):

Code: QB64: [Select]
  1.  
  2. TYPE object
  3.     x AS SINGLE
  4.     y AS SINGLE
  5.     c AS _UNSIGNED LONG
  6.  
  7. SCREEN _NEWIMAGE(800, 540, 32)
  8.  
  9. '78x52
  10. CONST maxW = 78
  11. CONST maxH = 52
  12. DIM px(1 TO maxW, 1 TO maxH) AS object
  13. DIM i AS INTEGER, j AS INTEGER, temp$
  14. DIM frame AS INTEGER
  15.  
  16. CONST offset = 5
  17. FOR i = 1 TO maxW
  18.     FOR j = 1 TO maxH
  19.         px(i, j).x = offset + i * 10
  20.         px(i, j).y = offset + j * 10
  21.     NEXT
  22.  
  23. ' We Wish You a Merry Christmas
  24. ' from http://www.devsuperpage.com/search/Articles.aspx?G=5&ArtID=116269
  25. PLAY "mb t120"
  26. PLAY "o3l4dgg8a8g8f#8"
  27. PLAY "eceaa8b8a8g8f#dd"
  28. PLAY "bb8o4c8o3b8a8ged8d8eaf#g2"
  29. PLAY "dgggf#2f#gf#ed2a"
  30. PLAY "ba8a8g8g8o4do3dd8d8eaf#g2"
  31. PLAY "p1"
  32.  
  33.     frame = frame + 1
  34.     IF frame > 4 THEN frame = 1
  35.  
  36.     SELECT CASE frame
  37.         CASE 1: RESTORE frame1
  38.         CASE 2: RESTORE frame2
  39.         CASE 3: RESTORE frame3
  40.         CASE 4: RESTORE frame4
  41.     END SELECT
  42.  
  43.     CLS
  44.     FOR j = 1 TO maxH
  45.         FOR i = 1 TO maxW
  46.             READ temp$
  47.             IF temp$ <> "0" THEN
  48.                 px(i, j).c = VAL("&H" + temp$)
  49.             ELSE
  50.                 px(i, j).c = _RGB32(21)
  51.             END IF
  52.             CircleFill px(i, j).x, px(i, j).y, 2, px(i, j).c
  53.         NEXT
  54.     NEXT
  55.  
  56.     _DISPLAY
  57.     _LIMIT 5
  58.  
  59. 'image source https://giphy.com/gifs/studiosoriginals-merry-christmas-3o6fJdYXEvMa5ZmlI4
  60.  
  61. frame1:
  62. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  63. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  64. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  65. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  66. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  67. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF130303,FF0C0A03,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  68. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF1B0404,FF0B0202,0,FF0B0202,0,0,FF0B0202,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF130303,FF0B0202,0,FF0B0202,0,0,0,0,0,0,0,0,0,0,0
  69. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF1B0404,0,FF9A3434,FFC54C4C,0,FF130303,0,0,0,0,0,FF0B0202,0,0,FF130303,FF1B0404,FF1B0404,FF130303,FF0B0202,0,0,FF130303,0,0,FF0B0202,0,0,0,0,0,0,0,0,0
  70. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF771B1B,FF3C0000,FF000C0B,0,FFEE6D6D,FFD76565,0,FF1D150D,FF130303,0,0,FF1D0A0A,FF1B0404,FF0B0B0B,0,FF130303,0,0,0,0,0,FF631313,FF4B1212,0,FFA73C3C,FFBB4545,0,FF1D0A0A,0,0,0,0,0,0,0,0
  71. DATA 0,0,0,0,0,0,0,0,0,FF0A1A0C,FF0C130C,0,0,0,FF0A1A0C,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF0B0202,FF000C0B,FF2C0000,FFEB6262,FF9A3434,0,FF8D211F,FFFF7E7E,FFB44343,0,FF2A0F10,0,0,FF0B0202,0,0,0,FF1B0404,0,FF7B2323,FF8D211F,FF9A3434,FFAD4341,0,FFE45C5C,FF8C2D2D,0,FFF46C6C,FFBC4A4A,0,FF220B0B,0,0,0,0,0,0,0,0
  72. DATA 0,0,0,0,0,0,0,0,0,0,0,FF0A040A,FF0A1A0C,FF0B0B0B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF0A1A0C,0,0,0,0,0,0,0,0,0,0,FF1B0404,0,FF5B0101,FFFF7E7E,FFBC4A4A,0,FFD45354,FFFD6B6B,FF9A3434,0,0,FF5B0101,FF220202,FF1B0404,FFB44343,FF9B2A29,FFD45354,FF6F1D1D,0,FFBC4A4A,FFF26665,FFFA7272,FFB54A48,FF4C0000,FFF46C6C,FF5B0101,FF8C2D2D,FFFA7272,FF540000,0,FF130303,0,0,0,0,0,0,0,0
  73. DATA 0,0,0,0,0,0,0,0,FF021F00,FF3E7C3F,FF316B32,0,0,0,FF438645,FF143C15,0,FF0A1A0C,0,0,0,0,0,0,0,0,0,FF030B03,0,0,0,0,0,FF030B03,0,0,0,0,0,FF1B0404,0,FF832525,FFFA7272,FFCC5151,FF871314,FFE45C5C,FFE15555,FF8C2D2D,0,FFBB4545,FFF26665,FFC54C4C,FF630000,FFF46C6C,FFEB6262,FFEE6D6D,FF430101,0,FFDD5A5A,FFAF2D2D,FFDB5555,FF7B2323,FF832525,FFF46C6C,0,FFC54C4C,FFD45354,0,FF1D0A0A,0,0,0,0,0,0,0,0,0
  74. DATA 0,0,0,0,0,0,0,FF0B0B0B,0,FF78CC7A,FF71CC73,FF5CB35D,FF3E7C3F,FF4B994D,FF83DD84,FF2A642C,0,0,0,0,0,0,FF041304,0,0,FF0C130C,FF030B03,FF030B03,FF539452,FF143C15,0,FF131D0F,FF131414,0,0,0,0,0,FF220B0B,FF2A0F10,0,FFAD4341,FFE15555,FFD74C4C,FFD45354,FFC64242,FFDD5A5A,FF6E1414,FF9A3434,FFE45C5C,FFAD2626,FFE45C5C,FFAF2D2D,FFD45354,FFAD2626,FFD45354,0,FF7B2323,FFEB6262,FF6B0000,FFE45C5C,FF540000,FFB54A48,FFFF7E7E,FF870000,FFFA7272,FFA73C3C,0,FF1D0A0A,0,0,0,0,0,0,0,0,0
  75. DATA 0,0,0,0,0,0,0,FF041304,0,FF2A642C,FF5CB35D,FF186C1C,FF63BC65,FF56A358,FF52AC54,FF357837,FF003000,FF61AC62,FF0E2F0F,0,FF030B03,0,0,0,FF0A1A0C,0,0,FF205422,FF88E38A,FF357837,0,0,0,FF003B00,FF0A1A0C,0,FF0B0202,0,0,0,0,FFD45354,FFB43535,FFDD5A5A,FFFA7272,FF870000,FFE56161,FF630000,FFDD5A5A,FFAF2D2D,FFE45C5C,FFB43535,FFDB5555,FFA33636,FFB33C3B,FFCC5151,0,FFDD5A5A,FFBB4545,0,FFE56161,FFBA3C3C,FFE45C5C,FFE45C5C,FFE45C5C,FFF46C6C,FFA73C3C,0,FF1D0A0A,0,0,0,0,0,0,0,0,0
  76. DATA 0,0,0,0,0,0,0,0,FF131414,0,FF66C069,FF3E7C3F,FF003000,FF003000,FF438645,FF6CC66D,FF63BC65,FF7AD57C,FF114713,0,FF030B03,0,FF2A642C,0,FF021F00,FF71C373,FF014803,FF519C53,FF5EBA60,FF5AAC5C,FF316B32,FF4B994D,FF71C373,FF71C373,0,FF14140D,0,FF220202,FFB44343,FF832928,FF340101,FFEB6262,FF630000,FFAD4341,FFBC4A4A,FF5B0101,FFE45C5C,FF5B0101,FFDB5555,FFE15555,FFBA3C3C,FFAF2D2D,FFEB6262,0,FF9A3434,FFEA5E5E,FFCC4C4C,FFDD5A5A,FF220202,0,FF922E2E,FFE45C5C,FFB33C3B,FFA31D1D,FFC64242,FFC64242,FFBC4A4A,0,FF220B0B,0,0,0,0,0,0,0,0,0
  77. DATA 0,0,0,0,0,0,0,FF0C130C,0,FF71C373,FF7AD57C,FF005700,FF316B32,FF62B464,FF003B00,FF5AAC5C,FF278532,FF52AC54,0,0,FF1C1D1D,0,FF71CC73,FF62B464,FF005700,FF71CC73,FF6CC66D,FF66C069,FF003000,FF66C069,FF5CB35D,FF52AC54,FF7AD57C,FF316B32,0,FF1C1B0C,0,FFCC4C4C,FFE45C5C,FF430101,FF9A3434,FFE45C5C,0,0,0,FF4A0D00,FFEB6262,FFAF2D2D,FFE15555,FFDB5555,FFB33C3B,FFF26665,FF832525,0,FF220202,FFB44343,FFC54C4C,FF430101,0,FF1B0404,0,0,FF630000,FFF26665,FF8D211F,FFC54C4C,FFBC4A4A,0,FF220B0B,0,0,0,0,0,0,0,0,0
  78. DATA 0,0,0,0,0,0,0,0,0,FF2A642C,FF429544,FF71CC73,FF3C893E,FF5CB35D,FF3B733A,0,FF5AAC5C,FF5EBA60,FF3C893E,FF3E7C3F,0,0,FF5CB35D,FF52AC54,FF73D375,FF4B994D,FF498A4A,FF3B733A,0,0,FF003000,FF6BBE6D,FF316B32,0,FF131D0F,0,FF4C0000,FFEB6262,FF4C0000,0,FFEA5E5E,FFA33636,0,FF24221A,FF130303,0,FFBB4545,FFE45C5C,FF8D211F,FFBC4A4A,FFCD3448,FF6B0000,0,FF1D0A0A,0,0,0,0,FF130303,0,FF2A0F10,0,FFC54C4C,FFC54C4C,0,FFDD5A5A,FFA73C3C,0,FF220B0B,0,0,0,0,0,0,0,0,0
  79. DATA 0,0,0,0,0,0,0,FF030B03,0,FF003000,FF459D48,FF63BC65,FF316B32,FF357837,FF63BC65,0,FF61AC62,FF5AAC5C,FF73D375,FF52A454,FF5AAC5C,FF52A454,FF5CB35D,FF003000,FF61AC62,FF3E7C3F,0,FF438645,FF63BC65,FF2B762D,FF6CC66D,FF368538,0,FF0E2F0F,0,FF0B0B0B,0,FFD45354,FFD45354,FFDB5555,FFD45354,0,0,0,FF316B32,FF174B1A,0,FF041304,0,0,FF038140,FF3A8C4C,FF021F00,FF0A1A0C,FF131D0F,FF1C0709,FF2A0F10,FF4C0000,FF0B0202,0,FF220B0B,0,FFC54C4C,FFD45354,FFA83232,FFEB6262,FF4C0000,0,FF130303,FF0B0202,0,0,FF130303,FF220B0B,FF0B0202,0,0,0
  80. DATA 0,0,0,0,0,0,0,FF0A1A0C,0,FF56A358,FF83DD84,FF429544,0,0,FF62B464,FF438645,0,FF021F00,FF63BC65,FF003000,FF62B464,FF73D375,FF71CC73,0,0,FF357837,FF66C069,FF5CB35D,FF014803,FF519C53,FF71CC73,FF5EBA60,FF7AD57C,FF003000,0,FF1D0A0A,0,FF430101,FFB44343,FFA73C3C,FF0B0202,0,FF316B32,FF71C373,FF83DD84,FF80D381,0,0,FF3B733A,FF80D381,FF71CC73,FF88E38A,FF498A4A,0,0,FF030B03,FF631313,FFD45354,FF340101,0,FF130303,0,FF580C0C,FFD45354,FFDD5A5A,FF771B1B,0,FF2A0F10,FF130303,0,0,FF130303,0,0,0,FF0B0202,0,0
  81. DATA 0,0,0,0,0,0,0,0,0,FF030B03,FF205422,FF52A454,FF71CC73,FF3B733A,FF114713,FF6CC66D,0,FF438645,FF5AAC5C,0,FF5CB35D,FF2B762D,FF205422,FF003B00,FF62B464,FF63BC65,FF2A642C,0,0,0,FF459D48,FF71CC73,FF498A4A,0,FF1D150D,0,0,FF000C0B,0,0,FF0A1A0C,0,FF519C53,FF429544,FF71C373,FF6AB36B,0,FF62B464,FF88E38A,FF498A4A,FF014803,FF80D381,FF005700,FF438645,FF539452,0,FF832928,FFD45354,0,FF0B0B0B,FF1B0404,FF1B0404,0,0,0,0,FF000C0B,0,0,FF2C0000,FF1B0404,0,FF631313,FFB44343,FF580C0C,0,FF0B0202,0
  82. DATA 0,0,0,0,0,0,0,0,0,0,0,FF3C893E,FF6CC66D,FF357837,0,FF519C53,FF5AAC5C,FF005700,FF4B994D,FF2B762D,FF66C069,0,FF357837,FF6CC66D,FF498A4A,0,0,0,FF498A4A,FF63BC65,FF52A454,FF114713,0,FF1D150D,0,FF130303,FF4C0000,0,FF1D0A0A,FF1B0404,FF220202,FF62211A,0,FF2A642C,FF80D381,FF014803,FF78CC7A,FF78CC7A,FF003B00,0,FF205422,FF80D381,FF78CC7A,FF7AD57C,FF438645,FF540000,FFB33C3B,FFD24545,FFB33C3B,FF340101,0,0,0,0,FF000C0B,0,FF3C0000,FFBC4A4A,FFB33C3B,FFCC4C4C,0,FF631313,FFDB5555,FFFD6B6B,FF9A3434,0,FF220202,0
  83. DATA 0,0,0,0,0,0,0,0,FF0A1A0C,0,FF539452,FF88E38A,FF52AC54,FF5AAC5C,FF174B1A,0,FF5AAC5C,FF52AC54,FF6CC66D,FF63BC65,FF5AAC5C,FF52AC54,FF6CC66D,FF174B1A,0,FF0E2F0F,FF021F00,0,FF52A454,FF73D375,FF56A358,FF205422,FF1B0404,0,FF832525,FFE45C5C,FFEA5E5E,FFBB4545,0,0,FF832525,FFCC5151,0,FF528E51,FF83DD84,FF7AD57C,FF6AB36B,0,0,FF24221A,0,FF2A642C,FF498A4A,0,0,FF8C2D2D,FFD74C4C,FFC64242,FFA33636,FF630000,FF7B2323,FF6E1414,FF8C2D2D,FFBC4A4A,FF580C0C,0,FFCC5151,FFDB5555,FFD24545,FFDD5A5A,0,FFBC4A4A,FFE45C5C,FF760000,FF551913,0,FF0B0202,0
  84. DATA 0,0,0,0,0,0,0,0,0,0,FF0E2F0F,FF003000,FF52AC54,FF7AD57C,FF3C893E,FF498A4A,FF278532,FF66C069,FF6CC66D,0,FF63BC65,FF52A454,0,0,0,FF4B994D,FF78CC7A,FF5CB35D,FF5CB35D,FF63BC65,FF80D381,FF3E7C3F,0,FF60110A,FFEB6262,FFA33636,FF5B0101,FFEA5E5E,FF9A3434,0,FFBB4545,FFC54C4C,0,FF152600,FF6AB36B,FF539452,0,0,FF14140D,0,0,0,0,FF7B2323,FF62211A,0,FFCC4C4C,FFA33636,0,FFDB5555,FFD74C4C,FFEB6262,FFD24545,FFE45C5C,FFC54C4C,FF3C0000,FFEB6262,FF3C0000,FFB44343,FFCC4C4C,0,FF540000,FFDD5A5A,FFD45354,FF1B0404,0,0,0
  85. DATA 0,0,0,0,0,0,0,0,0,FF0A1A0C,0,FF3B733A,FF88E38A,FF5EBA60,FF5AAC5C,FF459D48,FF83AF61,FF6FAC58,FF006A08,FF62B464,FF459D48,FF368538,FF5AAC5C,FF5AAC5C,FF519C53,FF429544,FF6CC66D,FF3C893E,FF205422,FF114713,0,FF0B0202,0,FFCC4C4C,FFC54C4C,0,0,FFDB5555,FFB44343,0,FFDB5555,FF9A3434,0,FF2A0F10,0,0,FF551913,FF9A3434,0,FF62211A,FF8C2D2D,0,FFB54A48,FFFD6B6B,FFD3565D,0,FFE45C5C,FF8C2D2D,FF6E1414,FFEB6262,FF6B0000,FFE56161,FF6B0000,FFA73C3C,FFCC5151,FF6B0000,FFE45C5C,FF1B0404,FFD45354,FF9B2A29,FFA33636,FFB44343,0,FFE45C5C,FFA73C3C,0,FF220202,0
  86. DATA 0,0,0,0,0,0,0,0,0,FF030B03,0,FF2F5724,FF3B733A,FF262B0C,0,FF86002F,FFD3565D,FFC54E54,FF5C934D,FF7AD57C,FF459D48,FF88E38A,FF63BC65,FF2B762D,FF4B994D,FF52A454,FF71CC73,FF6BBE6D,0,FF0B0202,FF1D1D12,FF000C0B,FF430101,FFEB6262,FF771B1B,0,FFB33C3B,FFE45C5C,FF430101,FF2C0000,FFE45C5C,FF9B2A29,FF580C0C,0,FFB54A48,FFC54C4C,FFE56161,FFE56161,0,FFBB4545,FFCC5151,FF4C0000,FFF46C6C,FFAF2D2D,FFBB4545,FF540000,FFEB6262,FF430101,FFA73C3C,FFD45354,FF4C0000,FFEB6262,FF3C0000,FFBC4A4A,FFBB4545,FF4C0000,FFEB6262,FF630000,FFE45C5C,FFAD2626,FFEB6262,FFF46C6C,FFB43535,FFEB6262,FF7B2323,0,FF130303,0
  87. DATA 0,0,0,0,0,0,0,0,0,0,FF1D1D12,0,0,0,0,FF92403A,FFBB4545,FFD76565,FF8E4632,FF2F5724,FF357837,FF519C53,FF3E7C3F,0,0,0,FF174B1A,FF316B32,FF030B03,FF041304,FF1B0404,0,FF832525,FFE45C5C,FF2C0000,0,FF631313,FF3C0000,0,FF771B1B,FFE45C5C,FFD74C4C,FFEB6262,FF871314,FFD3565D,FFE45C5C,FFEB6262,FFBC4A4A,0,FFD45354,FFB44343,0,FFBB4545,FFEA5E5E,FF760000,FF832525,FFE45C5C,0,FFCC5151,FFB44343,FF771B1B,FFE45C5C,0,FFBC4A4A,FFD45354,FFB43535,FFEA5E5E,FFE45C5C,FFDB5555,FFD74C4C,FFC54C4C,FF9B2A29,FFDD5A5A,FF922E2E,0,FF1B0404,0,0
  88. DATA 0,0,0,0,0,0,0,0,0,FF14140D,0,FF63501C,FFAC954A,FFB19A4C,FF63501C,FF801825,FFD3565D,FFCC5151,FFD76565,FFC44F58,FF340101,0,FF2A0827,FF323332,FF2C332C,FF323332,FF2A242C,FF0A040A,0,0,FF220B0B,0,FFA73C3C,FFDB5555,0,FF220B0B,0,FF4B1212,FF771B1B,FFA33636,FFE45C5C,FF340101,FFD45354,FFC64242,FFDB5555,FF760000,FFCC4C4C,FFA73C3C,0,FFE45C5C,FFAF2D2D,FFCC5151,0,FFB33C3B,FFDB5555,FFBA3C3C,FFDB5555,FF760000,FFF26665,FF630000,FF9A3434,FFDB5555,0,FF591313,FFDD5A5A,FFDD5A5A,FF760000,FFA73C3C,FF60110A,0,0,0,0,0,FF130303,0,0,0
  89. DATA 0,0,0,0,0,0,0,0,FF14140D,0,FFB19A4C,FFDBC267,FFAC954A,FFDBC267,FFD19B59,FFD3565D,FFC7635C,FFC54E54,FFBB4545,FFD76565,FF713D38,FF002920,FF1D1D12,0,0,0,FF0C130C,FF323332,FF242424,0,FF220B0B,0,FFBC4A4A,FFC54C4C,0,FF2A0F10,0,FF9A3434,FFDB5555,FFC64242,FFC54C4C,0,FFDD5A5A,FFAF2D2D,FFE45C5C,FF3C0000,FFCC5151,FFBB4545,FF871314,FFE45C5C,FFC64242,FFFF7E7E,FFBA3C3C,FFD45354,FFC64242,FFCC4C4C,FFBA3C3C,FFE45C5C,FFB44343,0,FF591313,FF631313,0,0,FF130303,FF220202,0,0,0,FF0B0202,FF130303,FF1B0404,FF1D0A0A,FF1B0404,0,0,0,0
  90. DATA 0,0,0,0,0,0,0,FF1C1B0C,0,FFAC954A,FFD5BC63,FF340E00,0,FFB19A4C,FFCAA853,FFB10025,FFD3565D,FFA65136,FFAD4341,FF9D494B,FF242424,FF0B0202,0,0,0,0,0,0,FF323332,FF1C1D1D,FF1B0404,0,FFCC5151,FFBB4545,0,FF381515,0,FFCC5151,FFBB4545,FFD74C4C,FFA73C3C,0,FFE45C5C,FFD45354,FFDD5A5A,0,FF6F1D1D,FFE45C5C,FFF26665,FFB43535,FFBA3C3C,FF9B2A29,FFD45354,FFC54C4C,FF340101,FF430101,FF1B0404,FF2C0000,0,FF0B0202,0,0,FF0B0202,FF130303,0,0,FF130303,FF220202,FF130303,0,0,0,0,0,0,0,0,0
  91. DATA 0,0,0,0,0,0,FF130E03,0,FF746027,FFDBC267,FF2C0000,0,0,FF63501C,FFD5BC63,FFDBAE60,FFD19B59,FFCAA853,FF93803C,0,FF2F2723,0,0,0,0,0,0,0,FF131414,FF302F2F,FF1B0404,0,FFD45354,FFA73C3C,0,0,FF5B0101,FFEB6262,FF870000,FFE56161,FF832525,0,FFA33636,FFEB6262,FF8C2D2D,0,0,FF540000,FF832928,FF1B0404,0,0,0,0,0,0,0,0,FF1B0404,0,FF0B0202,FF130303,0,0,FF0B0202,FF0B0202,0,0,0,0,0,0,0,0,0,0,0,0
  92. DATA 0,0,0,0,0,0,FF1C1B0C,0,FFC1AA5B,FFA28D44,0,FF221D0A,FF0C0A03,0,FF4E3804,FFA28D44,FF8A7730,FF9C843E,FFCDB45F,FF12001B,FF24221A,0,0,0,0,0,0,0,0,FF2B2B2B,FF2F2723,0,FFBC4A4A,FFDD5A5A,FF430101,FF6E1414,FFE85F60,FFB44343,0,FFBB4545,FF430101,0,0,FF130303,0,FF0A040A,FF130303,0,0,0,FF0B0202,FF1B0404,FF1D0A0A,FF1D0A0A,FF0B0202,FF0B0202,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  93. DATA 0,0,0,0,0,FF0C0A03,0,FF5C4715,FFD5BC63,FF3F2A00,0,0,0,FF130E03,0,0,0,FF63501C,FFCDB45F,FF3B2A21,FF14191D,0,0,0,0,0,0,0,0,FF1C1D1D,FF2B2B2B,0,FF3C0000,FFCC5151,FFE45C5C,FFE45C5C,FFB33C3B,0,FF0B0B0B,0,0,FF130E03,FF0B0202,0,FF1D150D,0,FF050812,FF14090C,FF1B0404,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  94. DATA 0,0,0,0,0,FF1C1B0C,0,FFA28D44,FFBCA454,0,FF1C1B0C,0,0,0,FF0B0202,FF2B2711,0,FF746027,FFCDB45F,FF2A0F10,FF242424,0,0,0,0,0,0,0,0,0,FF2B2B2B,FF0B0202,0,0,FF580C0C,FF340101,0,FF14090C,0,0,FF1A1D22,0,FF35456D,FF6E7CA1,0,FF232D3F,0,0,FF050812,0,0,0,0,0,0,FF1C1D1D,FF1C1D1D,0,0,0,0,0,0,0,0,0,0,0,FF242424,0,0,0,0,0,0,0,0,0
  95. DATA 0,0,0,0,FF130E03,FF000C0B,FF0B0202,FFD5BC63,FF746027,0,FF1A1506,0,0,0,0,FF1C1B0C,0,FF93803C,FFCAA853,0,FF34352F,0,0,0,0,0,0,0,0,0,FF242424,FF2B2B2B,0,FF14090C,0,0,FF1D0A0A,0,FF0C0A03,FF334161,FF000133,FF8192BC,FF788CC7,FF8A9ACA,FF8294C3,FF5B6A8B,FF000133,FF30394B,0,FF02040A,0,0,FF0B0B0B,FF0B0B0B,FF2B2B2B,FF242424,FF242424,FF2B2B2B,FF0B0B0B,FF0B0B0B,0,0,0,0,FF0B0B0B,0,FF1C1D1D,FF242424,FF2B2B2B,FF242424,FF2B2B2B,0,FF131414,0,0,0,0,0
  96. DATA 0,0,0,FF1E1805,FF131D0F,0,FFC1AA5B,FFBCA454,0,FF1C1B0C,0,0,0,0,0,FF1C1B0C,0,FFBCA454,FFAC954A,0,FF393837,FF0B0B0B,0,0,0,0,0,0,0,0,0,FF2B2B2B,FF2B2B2B,0,0,0,0,FF232D3F,FF000133,FF8A9ACA,FF475677,FF475677,FF99ABDC,FFA1B5EA,FF8192BC,0,FF8A9ACA,FF3C5288,FF000133,FF0D1522,0,0,FF2B2B2B,0,FF1C1D1D,FF323332,FF323332,FF1C1D1D,0,FF2B2B2B,0,0,0,0,FF131414,FF2B2B2B,0,FF2B2B2B,FF323332,FF323332,FF0B0B0B,FF1C1D1D,FF2B2B2B,0,FF0B0B0B,0,0,0
  97. DATA 0,0,0,0,0,FFBCA454,FFCDB45F,0,FF000C0B,0,0,0,0,0,FF0B0202,0,FF3F2A00,FFD5BC63,FF5C4715,0,FF242424,FF2B2B2B,0,0,0,0,0,0,0,0,0,0,FF242424,FF2B2B2B,FF242424,FF1A1D22,0,FF475677,FF8A9ACA,FF889CD6,FF6276AB,0,FF5C6B94,FF90A2D3,0,FF00104A,FF8FA4DC,FF7F93CC,FF7084B8,0,FF242424,FF2B2B2B,FF2B2B2B,FF131414,0,FF242424,FF242424,0,FF131414,FF2B2B2B,FF2B2B2B,FF1C1D1D,0,FF2B2B2B,FF242424,FF2B2B2B,0,0,FF2B2B2B,FF131414,0,FF242424,FF2B2B2B,FF2B2B2B,FF0B0B0B,0,0,0
  98. DATA 0,0,FF3F2A00,FF7D6628,FFCDB45F,FFC1AA5B,FF1B0404,FF030B03,FF130E03,0,0,0,0,0,FF1C1B0C,0,FFAC954A,FFBCA454,0,FF1C1B0C,0,FF2B2B2B,FF131414,0,0,0,0,0,0,0,0,0,0,FF242424,FF393837,FF242424,0,FF162C54,FF788CC7,FFA1B5EA,FF8FA4DC,FF35456D,FF516089,FF8A9ACA,FF000133,FF798BB7,FFA1B5EA,FF98ACE3,FF445992,0,FF0C0E13,FF2B2B2B,FF323332,FF2B2B2B,0,FF242424,FF242424,0,FF2B2B2B,FF323332,FF2B2B2B,FF0B0B0B,0,FF131414,FF323332,FF323332,FF242424,0,FF2B2B2B,FF0B0B0B,FF131414,FF323332,FF323332,FF242424,0,0,0,0
  99. DATA FF1C1B0C,0,FFA28D44,FFFCE689,FFD7B855,FF4A0D00,0,0,FF0C130C,0,0,0,0,FF0C0A03,0,FF340E00,FFD5BC63,FF63501C,0,FF130E03,0,FF1C1D1D,FF2B2B2B,0,0,0,0,0,0,0,FF0B0B0B,FF242424,FF323332,FF242424,0,FF050812,0,FF516089,FF8294C3,FF3C5288,FF5C6B94,FF90A2D3,FF7F93CC,FF889CD6,FF889CD6,FF8192BC,FF1E3D7B,FF7182AD,FF798BB7,FF000026,FF24221A,FF2A242C,FF0B0B0B,FF242424,FF2B2B2B,FF2B2B2B,FF2B2B2B,FF2B2B2B,FF242424,FF0B0B0B,FF242424,FF242424,0,FF2B2B2B,FF1C1D1D,FF0B0B0B,FF2B2B2B,FF2B2B2B,FF2B2B2B,FF2B2B2B,FF2B2B2B,FF131414,FF131414,FF2B2B2B,FF131414,0,0,0
  100. DATA 0,0,FF301F00,FF7D6628,FFBCA454,FFD5BC63,FFBCA454,FF7D6628,0,0,FF0C0A03,FF1D1D12,FF130E03,FF1C1B0C,0,FF93803C,FFC1AA5B,0,FF1C1B0C,0,0,FF0B0B0B,FF2B2B2B,0,0,0,0,0,0,FF242424,FF323332,FF242424,0,0,0,0,0,FF162C54,FF00104A,0,0,FF6276AB,FF8FA4DC,FF6A86CE,FF889CD6,FF000133,0,FF000026,FF1F325B,FF0D1522,0,0,0,0,FF242424,FF2B2B2B,FF2B2B2B,FF242424,0,0,0,0,0,0,0,0,0,FF2B2B2B,FF242424,FF2B2B2B,FF131414,0,0,0,0,0,0,0
  101. DATA 0,0,0,0,0,FF4E3804,FFA28D44,FFD5BC63,FFCDB45F,FF301F00,FF02040A,0,0,FF262B0C,0,FFBCA454,FFA28D44,0,FF1A1506,0,0,0,FF2B2B2B,FF0B0B0B,0,0,FF0B0B0B,FF131414,0,FF2B2B2B,FF242424,0,0,0,0,FF111319,0,FF5C6B94,FF90A2D3,FF788CC7,FF8A9ACA,FF90A2D3,FF7084B8,FF8A9ACA,FF7084B8,FF99ABDC,FF7084B8,FF90A2D3,FF8192BC,FF001032,FF24221A,FF2F2F31,FF242424,FF2B2B2B,FF242424,FF242424,FF242424,FF2B2B2B,FF2B2B2B,FF242424,FF2B2B2B,FF242424,0,FF2B2B2B,FF2B2B2B,FF242424,FF323332,FF242424,FF2B2B2B,FF1C1D1D,FF2B2B2B,FF2B2B2B,FF2B2B2B,FF2B2B2B,FF1C1D1D,0,0,0
  102. DATA 0,0,FF0B0202,FF1A1506,FF1C1B0C,0,0,FF8A7730,FFD5BC63,0,FF3F2A00,FFC1AA5B,FF7D6628,0,0,FFC1AA5B,FF9C843E,0,FF1A1506,0,0,0,FF2B2B2B,0,0,FF242424,FF323332,FF323332,FF131414,FF2B2B2B,FF242424,0,0,0,0,FF02040A,FF0B0202,FF000040,FF788CC7,FFA1B5EA,FF7F93CC,0,FF516089,FF8A9ACA,0,FF445992,FFA1B5EA,FF8FA4DC,FF3C5288,0,FF111319,FF2B2B2B,FF323332,FF1C1D1D,0,FF242424,FF242424,0,FF242424,FF323332,FF2B2B2B,0,0,FF131414,FF323332,FF323332,FF0B0B0B,0,FF2B2B2B,FF0B0B0B,0,FF2B2B2B,FF323332,FF242424,0,0,0,0
  103. DATA 0,0,0,0,0,FF1A1506,0,FF746027,FFD5BC63,FF77570B,FFC1AA5B,FFDBC267,FFCDB45F,FFCDB45F,FF654703,FFB19A4C,FFA28D44,0,FF1A1506,0,0,FF0B0B0B,FF2B2B2B,FF1C1D1D,FF323332,FF242424,0,FF131414,FF2B2B2B,FF242424,0,0,0,0,0,FF0C0E13,0,FF475677,FF7182AD,FF7F93CC,FF6E7CA1,0,FF6276AB,FF90A2D3,0,FF001032,FF90A2D3,FF687CB3,FF6E7CA1,0,FF242424,FF1C1D1D,FF2B2B2B,FF131414,0,FF2B2B2B,FF242424,0,FF131414,FF2B2B2B,FF1C1D1D,FF1C1D1D,0,FF242424,FF1C1D1D,FF2B2B2B,0,0,FF2B2B2B,FF131414,0,FF242424,FF242424,FF242424,FF131414,0,0,0
  104. DATA 0,0,0,0,0,0,FF130E03,0,FF9C843E,FFD5BC63,FFBCA454,FF130303,FF1B0404,FFA28D44,FFCDB45F,FFE8CD6C,FFCDB45F,0,FF1C1B0C,0,0,FF1C1D1D,FF393837,FF242424,FF0B0B0B,0,0,0,0,0,0,0,0,0,0,0,FF02040A,0,0,FF7182AD,FF162C54,FF6E7CA1,FF98ACE3,FF98ACE3,FF8A9ACA,FF000026,FF6E7CA1,FF334161,0,FF1A1D22,0,0,FF242424,0,FF242424,FF323332,FF323332,FF242424,0,FF242424,0,0,0,0,FF131414,FF242424,0,FF2B2B2B,FF323332,FF323332,FF131414,FF0B0B0B,FF242424,0,0,0,0,0
  105. DATA 0,0,0,0,0,0,0,FF0C0A03,0,0,0,FF000C0B,FF000C0B,0,FF1B0404,FFAC954A,FFC1AA5B,0,FF000C0B,0,0,FF131414,FF131414,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF1A1D22,0,FF001032,FF8192BC,FF687CB3,FF7F93CC,FF687CB3,FF5B6A8B,0,FF111319,FF14191D,0,0,0,0,FF131414,FF242424,FF242424,FF242424,FF242424,FF0B0B0B,0,0,0,0,0,0,0,FF242424,FF1C1D1D,FF2B2B2B,FF1C1D1D,FF242424,0,0,0,0,0,0,0
  106. DATA 0,0,0,0,0,0,0,0,FF1D150D,FF0C130C,FF1C1B0C,FF0B0202,FF0B0202,FF1C1B0C,FF02040A,0,0,FF0B0B0B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF0B0B0B,FF14191D,0,FF334161,FF5C6B94,0,FF02040A,FF111319,0,0,0,0,0,0,0,0,FF1C1D1D,FF131414,0,0,0,0,0,0,0,0,0,0,0,FF1C1D1D,0,0,0,0,0,0,0,0,0
  107. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF1C1B0C,FF14140D,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF131414,0,0,FF1C1D1D,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  108. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF02040A,FF131414,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  109. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  110. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  111. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  112. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  113. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  114.  
  115. frame2:
  116. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  117. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  118. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  119. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  120. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  121. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF130303,FF0F0B02,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  122. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF1B0404,FF0B0302,0,FF0B0302,0,0,FF0B0302,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF130303,FF0B0302,0,FF0B0302,0,0,0,0,0,0,0,0,0,0,0
  123. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF1B0404,0,FF9A3434,FFC54C4C,0,FF130303,0,0,0,0,0,FF0B0302,0,0,FF130303,FF1B0404,FF1B0404,FF130303,FF0B0302,0,0,FF130303,0,0,FF0B0302,0,0,0,0,0,0,0,0,0
  124. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF771B1B,FF3C0000,FF010B0B,0,FFEE6D6D,FFD76565,0,FF1C140E,FF130303,0,0,FF1D0A0A,FF1B0404,FF0C0B0B,0,FF130303,0,0,0,0,0,FF631313,FF4B1212,0,FFA43B3B,FFBB4545,0,FF1D0A0A,0,0,0,0,0,0,0,0
  125. DATA 0,0,0,0,0,0,0,0,0,FF0B1A0B,FF0C130C,0,0,0,FF0B1A0B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF0B0302,FF010B0B,FF2C0000,FFEB6262,FF9A3434,0,FF8D211F,FFFF7E7E,FFB44343,0,FF2A0F10,0,0,FF0B0302,0,0,0,FF1B0404,0,FF7B2323,FF8D211F,FF9A3434,FFAD4341,0,FFE45C5C,FF8C2D2D,0,FFF46C6C,FFBC4A4A,0,FF220B0B,0,0,0,0,0,0,0,0
  126. DATA 0,0,0,0,0,0,0,0,0,0,0,FF0B040A,FF0B1A0B,FF0C0B0B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF0B1A0B,0,0,0,0,0,0,0,0,0,0,FF1B0404,0,FF5B0101,FFFF7E7E,FFBC4A4A,0,FFD45354,FFFD6B6B,FF9A3434,0,0,FF5B0101,FF220202,FF1B0404,FFB44343,FF9B2A29,FFD45354,FF6F1D1D,0,FFBC4A4A,FFF26665,FFFA7272,FFB54A48,FF4C0000,FFF46C6C,FF5B0101,FF8C2D2D,FFFA7272,FF540000,0,FF130303,0,0,0,0,0,0,0,0
  127. DATA 0,0,0,0,0,0,0,0,FF021F00,FF3E7C3F,FF316B32,0,0,0,FF438645,FF143C15,0,FF0B1A0B,0,0,0,0,0,0,0,0,0,FF030B03,0,0,0,0,0,FF030B03,0,0,0,0,0,FF1B0404,0,FF832525,FFFA7272,FFCC5151,FF871314,FFE45C5C,FFE15555,FF8C2D2D,0,FFBB4545,FFF26665,FFC54C4C,FF630000,FFF46C6C,FFEB6262,FFEE6D6D,FF430101,0,FFDD5A5A,FFAF2D2D,FFDB5555,FF7B2323,FF832525,FFF46C6C,0,FFC54C4C,FFD45354,0,FF1D0A0A,0,0,0,0,0,0,0,0,0
  128. DATA 0,0,0,0,0,0,0,FF0C0B0B,0,FF78CC7A,FF71CC73,FF5CB35D,FF3E7C3F,FF4B994D,FF83DD84,FF2A642C,0,0,0,0,0,0,FF041304,0,0,FF0C130C,FF030B03,FF030B03,FF539452,FF143C15,0,FF131D0F,FF131413,0,0,0,0,0,FF220B0B,FF2A0F10,0,FFAD4341,FFE15555,FFD74C4C,FFD45354,FFC64242,FFDD5A5A,FF6E1414,FF9A3434,FFE45C5C,FFAD2626,FFE45C5C,FFAF2D2D,FFD45354,FFAD2626,FFD45354,0,FF7B2323,FFEB6262,FF6B0000,FFE45C5C,FF540000,FFB54A48,FFFF7E7E,FF870000,FFFA7272,FFA93D3D,0,FF1D0A0A,0,0,0,0,0,0,0,0,0
  129. DATA 0,0,0,0,0,0,0,FF041304,0,FF2A642C,FF5CB35D,FF186C1C,FF63BC65,FF56A358,FF52AC54,FF357837,FF003000,FF61AC62,FF0B300C,0,FF030B03,0,0,0,FF0B1A0B,0,0,FF205422,FF88E38A,FF357837,0,0,0,FF003B00,FF0B1A0B,0,FF0B0302,0,0,0,0,FFD45354,FFB43535,FFDD5A5A,FFFA7272,FF870000,FFE56161,FF630000,FFDD5A5A,FFAF2D2D,FFE45C5C,FFB43535,FFDB5555,FFA33636,FFB33C3B,FFCC5151,0,FFDD5A5A,FFBB4545,0,FFE56161,FFBA3C3C,FFE45C5C,FFE45C5C,FFE45C5C,FFF46C6C,FFA93D3D,0,FF1D0A0A,0,0,0,0,0,0,0,0,0
  130. DATA 0,0,0,0,0,0,0,0,FF131413,0,FF66C069,FF3E7C3F,FF003000,FF003000,FF438645,FF6CC66D,FF63BC65,FF7CD47D,FF114713,0,FF030B03,0,FF2A642C,0,FF021F00,FF71C373,FF014803,FF519C53,FF5EBA60,FF5AAC5C,FF316B32,FF4B994D,FF71C373,FF71C373,0,FF14140D,0,FF220202,FFB44343,FF832928,FF340101,FFEB6262,FF630000,FFAD4341,FFBC4A4A,FF5B0101,FFE45C5C,FF5B0101,FFDB5555,FFE15555,FFBA3C3C,FFAF2D2D,FFEB6262,0,FF9A3434,FFEA5E5E,FFCC4C4C,FFDD5A5A,FF220202,0,FF922E2E,FFE45C5C,FFB33C3B,FFA31D1D,FFC64242,FFC64242,FFBC4A4A,0,FF220B0B,0,0,0,0,0,0,0,0,0
  131. DATA 0,0,0,0,0,0,0,FF0C130C,0,FF71C373,FF7CD47D,FF005700,FF316B32,FF62B464,FF003B00,FF5AAC5C,FF278532,FF52AC54,0,0,FF1C1C1C,0,FF71CC73,FF62B464,FF005700,FF71CC73,FF6CC66D,FF66C069,FF003000,FF66C069,FF5CB35D,FF52AC54,FF76D77A,FF316B32,0,FF1C1B0C,0,FFCC4C4C,FFE45C5C,FF430101,FF9A3434,FFE45C5C,0,0,0,FF4A0D00,FFEB6262,FFAF2D2D,FFE15555,FFDB5555,FFB33C3B,FFF26665,FF832525,0,FF220202,FFB44343,FFC54C4C,FF430101,0,FF1B0404,0,0,FF630000,FFF26665,FF8D211F,FFC54C4C,FFBC4A4A,0,FF220B0B,0,0,0,0,0,0,0,0,0
  132. DATA 0,0,0,0,0,0,0,0,0,FF2A642C,FF429544,FF71CC73,FF3C893E,FF5CB35D,FF3B733A,0,FF5AAC5C,FF5EBA60,FF3C893E,FF3E7C3F,0,0,FF5CB35D,FF52AC54,FF73D375,FF4B994D,FF498A4A,FF3B733A,0,0,FF003000,FF6BBE6D,FF316B32,0,FF131D0F,0,FF4C0000,FFEB6262,FF4C0000,0,FFEA5E5E,FFA33636,0,FF28201C,FF130303,0,FFBB4545,FFE45C5C,FF8D211F,FFBC4A4A,FFCD3448,FF6B0000,0,FF1D0A0A,0,0,0,0,FF130303,0,FF2A0F10,0,FFC54C4C,FFC54C4C,0,FFDD5A5A,FFA43B3B,0,FF220B0B,0,0,0,0,0,0,0,0,0
  133. DATA 0,0,0,0,0,0,0,FF030B03,0,FF003000,FF459D48,FF63BC65,FF316B32,FF357837,FF63BC65,0,FF61AC62,FF5AAC5C,FF73D375,FF52A454,FF5AAC5C,FF52A454,FF5CB35D,FF003000,FF61AC62,FF3E7C3F,0,FF438645,FF63BC65,FF2B762D,FF6CC66D,FF368538,0,FF1F2917,0,FF0C0B0B,0,FFD45354,FFD45354,FFDB5555,FFD45354,0,0,0,FF316B32,FF174B1A,0,FF041304,0,0,FF038140,FF3A8C4C,FF021F00,FF0B1A0B,FF131D0F,FF1C0709,FF2A0F10,FF4C0000,FF0B0302,0,FF220B0B,0,FFC54C4C,FFD45354,FFA83232,FFEB6262,FF4C0000,0,FF130303,FF0B0302,0,0,FF130303,FF220B0B,FF0B0302,0,0,0
  134. DATA 0,0,0,0,0,0,0,FF0B1A0B,0,FF56A358,FF83DD84,FF429544,0,0,FF62B464,FF438645,0,FF021F00,FF63BC65,FF003000,FF62B464,FF73D375,FF71CC73,0,0,FF357837,FF66C069,FF5CB35D,FF014803,FF519C53,FF71CC73,FF5EBA60,FF7CD47D,FF003000,0,FF1D0A0A,0,FF430101,FFB44343,FFA93D3D,FF0B0302,0,FF316B32,FF71C373,FF83DD84,FF80D381,0,0,FF3B733A,FF80D381,FF71CC73,FF88E38A,FF498A4A,0,0,FF030B03,FF631313,FFD45354,FF340101,0,FF130303,0,FF580C0C,FFD45354,FFDD5A5A,FF771B1B,0,FF2A0F10,FF130303,0,0,FF130303,0,0,0,FF0B0302,0,0
  135. DATA 0,0,0,0,0,0,0,0,0,FF030B03,FF205422,FF52A454,FF71CC73,FF3B733A,FF114713,FF6CC66D,0,FF438645,FF5AAC5C,0,FF5CB35D,FF2B762D,FF205422,FF003B00,FF62B464,FF63BC65,FF2A642C,0,0,0,FF459D48,FF71CC73,FF498A4A,0,FF1C140E,0,0,FF010B0B,0,0,FF021810,0,FF519C53,FF429544,FF71C373,FF6AB36B,0,FF62B464,FF88E38A,FF498A4A,FF014803,FF80D381,FF005700,FF438645,FF539452,0,FF832928,FFD45354,0,FF0C0B0B,FF1B0404,FF1B0404,0,0,0,0,FF010B0B,0,0,FF2C0000,FF1B0404,0,FF631313,FFB44343,FF580C0C,0,FF0B0302,0
  136. DATA 0,0,0,0,0,0,0,0,0,0,0,FF3C893E,FF6CC66D,FF357837,0,FF519C53,FF5AAC5C,FF005700,FF4B994D,FF2B762D,FF66C069,0,FF357837,FF6CC66D,FF498A4A,0,0,0,FF498A4A,FF63BC65,FF52A454,FF114713,0,FF1C140E,0,FF130303,FF4C0000,0,FF1D0A0A,FF1B0404,FF220202,FF62211A,0,FF2A642C,FF80D381,FF014803,FF78CC7A,FF78CC7A,FF003B00,0,FF205422,FF80D381,FF78CC7A,FF7CD47D,FF438645,FF540000,FFB33C3B,FFD24545,FFB33C3B,FF340101,0,0,0,0,FF010B0B,0,FF3C0000,FFBC4A4A,FFB33C3B,FFCC4C4C,0,FF631313,FFDB5555,FFFD6B6B,FF9A3434,0,FF220202,0
  137. DATA 0,0,0,0,0,0,0,0,FF0B1A0B,0,FF539452,FF88E38A,FF52AC54,FF5AAC5C,FF174B1A,0,FF5AAC5C,FF52AC54,FF6CC66D,FF63BC65,FF5AAC5C,FF52AC54,FF6CC66D,FF174B1A,0,FF0B300C,FF021F00,0,FF52A454,FF73D375,FF56A358,FF205422,FF1B0404,0,FF832525,FFE45C5C,FFEA5E5E,FFBB4545,0,0,FF832525,FFCC5151,0,FF528E51,FF83DD84,FF7CD47D,FF6AB36B,0,0,FF1F2917,0,FF2A642C,FF498A4A,0,0,FF8C2D2D,FFD74C4C,FFC64242,FFA33636,FF630000,FF7B2323,FF6E1414,FF8C2D2D,FFBC4A4A,FF580C0C,0,FFCC5151,FFDB5555,FFD24545,FFDD5A5A,0,FFBC4A4A,FFE45C5C,FF760000,FF551913,0,FF0B0302,0
  138. DATA 0,0,0,0,0,0,0,0,0,0,FF0B300C,FF003000,FF52AC54,FF76D77A,FF3C893E,FF498A4A,FF278532,FF66C069,FF6CC66D,0,FF63BC65,FF52A454,0,0,0,FF4B994D,FF78CC7A,FF5CB35D,FF5CB35D,FF63BC65,FF80D381,FF3E7C3F,0,FF60110A,FFEB6262,FFA33636,FF5B0101,FFEA5E5E,FF9A3434,0,FFBB4545,FFC54C4C,0,FF152600,FF6AB36B,FF539452,0,0,FF14140D,0,0,0,0,FF7B2323,FF62211A,0,FFCC4C4C,FFA33636,0,FFDB5555,FFD74C4C,FFEB6262,FFD24545,FFE45C5C,FFC54C4C,FF3C0000,FFEB6262,FF3C0000,FFB44343,FFCC4C4C,0,FF540000,FFDD5A5A,FFD45354,FF1B0404,0,0,0
  139. DATA 0,0,0,0,0,0,0,0,0,FF0B1A0B,0,FF3B733A,FF88E38A,FF5EBA60,FF5AAC5C,FF459D48,FF83AF61,FF6FAC58,FF006A08,FF62B464,FF459D48,FF368538,FF5AAC5C,FF5AAC5C,FF519C53,FF429544,FF6CC66D,FF3C893E,FF205422,FF114713,0,FF0B0302,0,FFCC4C4C,FFC54C4C,0,0,FFDB5555,FFB44343,0,FFDB5555,FF9A3434,0,FF2A0F10,0,0,FF551913,FF9A3434,0,FF62211A,FF8C2D2D,0,FFB54A48,FFFD6B6B,FFD3565D,0,FFE45C5C,FF8C2D2D,FF6E1414,FFEB6262,FF6B0000,FFE56161,FF6B0000,FFA93D3D,FFCC5151,FF6B0000,FFE45C5C,FF1B0404,FFD45354,FF9B2A29,FFA33636,FFB44343,0,FFE45C5C,FFA93D3D,0,FF220202,0
  140. DATA 0,0,0,0,0,0,0,0,0,FF030B03,0,FF2F5724,FF3B733A,FF242E03,0,FF86002F,FFD3565D,FFC54E54,FF5C934D,FF76D77A,FF459D48,FF88E38A,FF63BC65,FF2B762D,FF4B994D,FF52A454,FF71CC73,FF6BBE6D,0,FF0B0302,FF1D1D12,FF00160D,FF430101,FFEB6262,FF771B1B,0,FFB33C3B,FFE45C5C,FF430101,FF2C0000,FFE45C5C,FF9B2A29,FF580C0C,0,FFB54A48,FFC54C4C,FFE56161,FFE56161,0,FFBB4545,FFCC5151,FF4C0000,FFF46C6C,FFAF2D2D,FFBB4545,FF540000,FFEB6262,FF430101,FFA43B3B,FFD45354,FF4C0000,FFEB6262,FF3C0000,FFBC4A4A,FFBB4545,FF4C0000,FFEB6262,FF630000,FFE45C5C,FFAD2626,FFEB6262,FFF46C6C,FFB43535,FFEB6262,FF7B2323,0,FF130303,0
  141. DATA 0,0,0,0,0,0,0,0,0,0,FF1D1D12,0,0,0,0,FF92403A,FFBB4545,FFD76565,FF8E4632,FF2F5724,FF357837,FF519C53,FF3E7C3F,0,0,0,FF174B1A,FF316B32,FF030B03,FF041304,FF1B0404,0,FF832525,FFE45C5C,FF2C0000,0,FF631313,FF3C0000,0,FF771B1B,FFE45C5C,FFD74C4C,FFEB6262,FF871314,FFD3565D,FFE45C5C,FFEB6262,FFBC4A4A,0,FFD45354,FFB44343,0,FFBB4545,FFEA5E5E,FF760000,FF832525,FFE45C5C,0,FFCC5151,FFB44343,FF771B1B,FFE45C5C,0,FFBC4A4A,FFD45354,FFB43535,FFEA5E5E,FFE45C5C,FFDB5555,FFD74C4C,FFC54C4C,FF9B2A29,FFDD5A5A,FF922E2E,0,FF1B0404,0,0
  142. DATA 0,0,0,0,0,0,0,0,0,FF14140D,0,FF63501C,FFAC954A,FFB19A4C,FF63501C,FF801825,FFD3565D,FFCC5151,FFD76565,FFC44F58,FF340101,0,FF2A0827,FF323232,FF2C332C,FF323232,FF2D212D,FF0B040A,0,0,FF220B0B,0,FFA43B3B,FFDB5555,0,FF220B0B,0,FF4B1212,FF771B1B,FFA33636,FFE45C5C,FF340101,FFD45354,FFC64242,FFDB5555,FF760000,FFCC4C4C,FFA43B3B,0,FFE45C5C,FFAF2D2D,FFCC5151,0,FFB33C3B,FFDB5555,FFBA3C3C,FFDB5555,FF760000,FFF26665,FF630000,FF9A3434,FFDB5555,0,FF591313,FFDD5A5A,FFDD5A5A,FF760000,FFA43B3B,FF60110A,0,0,0,0,0,FF130303,0,0,0
  143. DATA 0,0,0,0,0,0,0,0,FF14140D,0,FFB19A4C,FFDBC267,FFAC954A,FFDBC267,FFD19B59,FFD3565D,FFC7635C,FFC54E54,FFBB4545,FFD76565,FF713D38,FF002920,FF1D1D12,0,0,0,FF0C130C,FF323232,FF242424,0,FF220B0B,0,FFBC4A4A,FFC54C4C,0,FF2A0F10,0,FF9A3434,FFDB5555,FFC64242,FFC54C4C,0,FFDD5A5A,FFAF2D2D,FFE45C5C,FF3C0000,FFCC5151,FFBB4545,FF871314,FFE45C5C,FFC64242,FFFF7E7E,FFBA3C3C,FFD45354,FFC64242,FFCC4C4C,FFBA3C3C,FFE45C5C,FFB44343,0,FF591313,FF631313,0,0,FF130303,FF220202,0,0,0,FF0B0302,FF130303,FF1B0404,FF1D0A0A,FF1B0404,0,0,0,0
  144. DATA 0,0,0,0,0,0,0,FF1C1B0C,0,FFAC954A,FFD5BC63,FF340E00,0,FFB19A4C,FFCAA853,FFB10025,FFD3565D,FFA65136,FFAD4341,FF9D494B,FF242424,FF0B0302,0,0,0,0,0,0,FF323232,FF1C1C1C,FF1B0404,0,FFCC5151,FFBB4545,0,FF381515,0,FFCC5151,FFBB4545,FFD74C4C,FFA93D3D,0,FFE45C5C,FFD45354,FFDD5A5A,0,FF6F1D1D,FFE45C5C,FFF26665,FFB43535,FFBA3C3C,FF9B2A29,FFD45354,FFC54C4C,FF340101,FF430101,FF1B0404,FF2C0000,0,FF0B0302,0,0,FF0B0302,FF130303,0,0,FF130303,FF220202,FF130303,0,0,0,0,0,0,0,0,0
  145. DATA 0,0,0,0,0,0,FF141105,0,FF746027,FFDBC267,FF2C0000,0,0,FF63501C,FFD5BC63,FFDBAE60,FFD19B59,FFCAA853,FF93803C,0,FF2F2723,0,0,0,0,0,0,0,FF131413,FF302F2F,FF1B0404,0,FFD45354,FFA93D3D,0,0,FF5B0101,FFEB6262,FF870000,FFE56161,FF832525,0,FFA33636,FFEB6262,FF8C2D2D,0,0,FF540000,FF832928,FF1B0404,0,0,0,0,0,0,0,0,FF1B0404,0,FF0B0302,FF130303,0,0,FF0B0302,FF0B0302,0,0,0,0,0,0,0,0,0,0,0,0
  146. DATA 0,0,0,0,0,0,FF1C1B0C,0,FFC1AA5B,FFA28D44,0,FF221D0A,FF0F0B02,0,FF4E3804,FFA28D44,FF8A7730,FF9C843E,FFCDB45F,FF12001B,FF28201C,0,0,0,0,0,0,0,0,FF2B2B2C,FF2F2723,0,FFBC4A4A,FFDD5A5A,FF430101,FF6E1414,FFE85F60,FFB44343,0,FFBB4545,FF430101,0,0,0,0,FF0B0302,FF130303,0,0,0,FF0B0302,FF1B0404,FF1D0A0A,FF1D0A0A,FF0B0302,FF130B0C,FF0C0B0B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  147. DATA 0,0,0,0,0,FF0F0B02,0,FF5C4715,FFD5BC63,FF3F2A00,0,0,0,FF141105,0,0,0,FF63501C,FFCDB45F,FF3B2A21,FF15191C,0,0,0,0,0,0,0,0,FF1C1C1C,FF2B2B2C,0,FF3C0000,FFCC5151,FFE45C5C,FFE45C5C,FFB33C3B,0,FF0C0B0B,0,0,0,FF130303,0,FF130303,0,0,FF130303,FF1B0404,0,0,0,FF0B0C13,0,FF141105,0,0,FF0F0B02,0,FF0B0C13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  148. DATA 0,0,0,0,0,FF1C1B0C,0,FFA28D44,FFBCA454,0,FF1C1B0C,0,0,0,FF0B0302,FF2B2711,0,FF746027,FFCDB45F,FF2A0F10,FF242424,0,0,0,0,0,0,0,0,0,FF2B2B2C,FF0B0302,0,0,FF580C0C,FF340101,0,FF130B0C,0,FF130303,0,0,FF0C0B0B,FF242424,0,0,0,0,0,0,FF02040B,0,0,FF212937,0,FF53668D,FF53668D,0,FF212937,0,0,FF02040B,0,0,0,0,0,0,FF242424,0,0,0,0,0,0,0,0,0
  149. DATA 0,0,0,0,FF0F0B02,FF010B0B,FF0B0302,FFD5BC63,FF746027,0,FF1A1506,0,0,0,0,FF1C1B0C,0,FF93803C,FFCAA853,0,FF34352F,0,0,0,0,0,0,0,0,0,FF242424,FF2B2B2C,0,FF130B0C,0,0,FF1D0A0A,0,0,FF130B0C,0,FF2B2B2C,FF242424,FF242424,FF2B2B2C,FF1C1C1C,0,FF0C0B0B,0,FF02040B,0,FF212937,FF233253,FF334260,FF8293C0,FF788EC8,FF7188C1,FF889BCC,FF334260,FF233253,FF212937,0,FF02040B,0,FF0C0B0B,0,FF1C1C1C,FF242424,FF2B2B2C,FF242424,FF2B2B2C,0,FF131413,0,0,0,0,0
  150. DATA 0,0,0,FF1E1805,FF131D0F,0,FFC1AA5B,FFBCA454,0,FF1C1B0C,0,0,0,0,0,FF1C1B0C,0,FFBCA454,FFAC954A,0,FF393837,FF0C0B0B,0,0,0,0,0,0,0,0,0,FF2B2B2C,FF2B2B2C,0,0,0,0,FF0C0B0B,0,FF2B2B2C,FF131413,FF131413,FF323232,FF323232,FF2B2B2C,0,FF2B2B2C,FF131413,0,0,FF212937,FF052863,FF8FA2D4,FF000040,FF6C7DA8,FF96ACE5,FF96ACE5,FF66769D,FF00224F,FF8FA2D4,FF000459,FF212937,0,0,FF131413,FF2B2B2C,0,FF2B2B2C,FF323232,FF323232,FF0C0B0B,FF1C1C1C,FF2B2B2C,0,FF0C0B0B,0,0,0
  151. DATA 0,0,0,0,0,FFBCA454,FFCDB45F,0,FF010B0B,0,0,0,0,0,FF0B0302,0,FF3F2A00,FFD5BC63,FF5C4715,0,FF242424,FF2B2B2C,0,0,0,0,0,0,0,0,0,0,FF242424,FF2B2B2C,FF242424,FF131413,0,FF131413,FF2B2B2C,FF2B2B2C,FF1C1C1C,0,FF1C1C1C,FF2B2B2C,0,0,FF2B2B2C,FF242424,FF2B2B2C,0,FF66769D,FF8196CB,FF8FA2D4,FF445476,0,FF7188C1,FF7188C1,0,FF4D5D83,FF8FA2D4,FF8196CB,FF617090,0,FF2D2E31,FF242424,FF2B2B2C,0,0,FF2B2B2C,FF131413,0,FF242424,FF2B2B2C,FF2B2B2C,FF0C0B0B,0,0,0
  152. DATA 0,0,FF3F2A00,FF7D6628,FFCDB45F,FFC1AA5B,FF1B0404,FF030B03,FF0F0B02,0,0,0,0,0,FF1C1B0C,0,FFAC954A,FFBCA454,0,FF1C1B0C,0,FF2B2B2C,FF131413,0,0,0,0,0,0,0,0,0,0,FF242424,FF393837,FF242424,0,0,FF242424,FF323232,FF2B2B2C,FF0C0B0B,FF131413,FF2B2B2C,0,FF242424,FF323232,FF2B2B2C,FF11151D,0,FF29437C,FF879CD6,FFA1B6ED,FF8196CB,FF000040,FF6B81B5,FF6C7DA8,FF000040,FF889BCC,FFA1B6ED,FF879CD6,FF1E386E,0,FF15191C,FF323232,FF323232,FF242424,0,FF2B2B2C,FF0C0B0B,FF131413,FF323232,FF323232,FF242424,0,0,0,0
  153. DATA FF1C1B0C,0,FFA28D44,FFFCE689,FFD7B855,FF4A0D00,0,0,FF0C130C,0,0,0,0,FF0F0B02,0,FF340E00,FFD5BC63,FF63501C,0,FF141105,0,FF1C1C1C,FF2B2B2C,0,0,0,0,0,0,0,FF0C0B0B,FF242424,FF323232,FF242424,0,0,0,FF1C1C1C,FF2B2B2C,FF131413,FF1C1C1C,FF2B2B2C,FF242424,FF2B2B2C,FF2B2B2C,FF242424,FF0C0B0B,FF242424,FF2B2B2C,0,FF6C7DA8,FF7D8EB8,FF29437C,FF7283AD,FF8FA2D4,FF7A93D4,FF7A93D4,FF8FA2D4,FF6C7DA8,FF29437C,FF8293C0,FF66769D,0,FF2B2B2C,FF1B1E22,FF0C0B0B,FF2B2B2C,FF2B2B2C,FF2B2B2C,FF2B2B2C,FF2B2B2C,FF131413,FF131413,FF2B2B2C,FF131413,0,0,0
  154. DATA 0,0,FF301F00,FF7D6628,FFBCA454,FFD5BC63,FFBCA454,FF7D6628,0,0,FF0F0B02,FF1D1D12,FF0F0B02,FF1C1B0C,0,FF93803C,FFC1AA5B,0,FF1C1B0C,0,0,FF0C0B0B,FF2B2B2C,0,0,0,0,0,0,FF242424,FF323232,FF242424,0,0,0,0,0,0,0,0,0,FF1C1C1C,FF2B2B2C,FF242424,FF2B2B2C,0,0,0,0,FF02040B,FF203359,FF000040,0,0,FF788EC8,FF7A93D4,FF7A93D4,FF7188C1,0,0,FF000040,FF233253,0,0,0,0,0,FF2B2B2C,FF242424,FF2B2B2C,FF131413,0,0,0,0,0,0,0
  155. DATA 0,0,0,0,0,FF4E3804,FFA28D44,FFD5BC63,FFCDB45F,FF301F00,FF02040B,0,0,FF1F2917,0,FFBCA454,FFA28D44,0,FF1A1506,0,0,0,FF2B2B2C,FF0C0B0B,0,0,FF0C0B0B,FF131413,0,FF2B2B2C,FF242424,0,0,0,0,0,0,FF1C1C1C,FF2B2B2C,FF242424,FF2B2B2C,FF2B2B2C,FF242424,FF2B2B2C,FF242424,FF323232,FF242424,FF2B2B2C,FF2B2B2C,0,FF7283AD,FF8FA2D4,FF7188C1,FF8FA2D4,FF8293C0,FF788EC8,FF7188C1,FF8293C0,FF8FA2D4,FF7188C1,FF8FA2D4,FF6C7DA8,0,FF2B2B2C,FF2B2B2C,FF242424,FF323232,FF242424,FF2B2B2C,FF1C1C1C,FF2B2B2C,FF2B2B2C,FF2B2B2C,FF2B2B2C,FF1C1C1C,0,0,0
  156. DATA 0,0,FF0B0302,FF1A1506,FF1C1B0C,0,0,FF8A7730,FFD5BC63,0,FF3F2A00,FFC1AA5B,FF7D6628,0,0,FFC1AA5B,FF9C843E,0,FF1A1506,0,0,0,FF2B2B2C,0,0,FF242424,FF323232,FF323232,FF131413,FF2B2B2C,FF242424,0,0,0,0,0,0,0,FF242424,FF323232,FF242424,0,FF131413,FF2B2B2C,0,FF131413,FF323232,FF2B2B2C,FF11151D,0,FF1E386E,FF879CD6,FFA1B6ED,FF6478AF,0,FF7788B2,FF6C7DA8,0,FF6B81B5,FFA1B6ED,FF879CD6,FF052863,0,FF15191C,FF323232,FF323232,FF0C0B0B,0,FF2B2B2C,FF0C0B0B,0,FF2B2B2C,FF323232,FF242424,0,0,0,0
  157. DATA 0,0,0,0,0,FF1A1506,0,FF746027,FFD5BC63,FF77570B,FFC1AA5B,FFDBC267,FFCDB45F,FFCDB45F,FF654703,FFB19A4C,FFA28D44,0,FF1A1506,0,0,FF0C0B0B,FF2B2B2C,FF1C1C1C,FF323232,FF242424,0,FF131413,FF2B2B2C,FF242424,0,0,0,0,0,0,0,FF131413,FF242424,FF242424,FF1C1C1C,0,FF1C1C1C,FF2B2B2C,0,0,FF2B2B2C,FF1C1C1C,FF2B2B2C,0,FF617090,FF6478AF,FF879CD6,FF445476,0,FF8196CB,FF7188C1,0,FF4D5D83,FF879CD6,FF6478AF,FF617090,0,FF2B2B2C,FF1C1C1C,FF2B2B2C,0,0,FF2B2B2C,FF131413,0,FF242424,FF242424,FF242424,FF131413,0,0,0
  158. DATA 0,0,0,0,0,0,FF141105,0,FF9C843E,FFD5BC63,FFBCA454,FF130303,FF1B0404,FFA28D44,FFCDB45F,FFE8CD6C,FFCDB45F,0,FF1C1B0C,0,0,FF1C1C1C,FF393837,FF242424,FF0C0B0B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF242424,0,FF1C1C1C,FF323232,FF323232,FF2B2B2C,0,FF242424,FF0C0B0B,0,FF0E1016,0,FF00002E,FF7788B2,FF00002E,FF8293C0,FF96ACE5,FF96ACE5,FF7788B2,FF00002E,FF7788B2,FF02040B,0,FF11151D,0,FF131413,FF242424,0,FF2B2B2C,FF323232,FF323232,FF131413,FF0C0B0B,FF242424,0,0,0,0,0
  159. DATA 0,0,0,0,0,0,0,FF0F0B02,0,0,0,FF010B0B,FF010B0B,0,FF1B0404,FFAC954A,FFC1AA5B,0,FF010B0B,0,0,FF131413,FF131413,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF2B2B2C,FF1C1C1C,FF242424,FF242424,FF1C1C1C,0,0,0,0,FF0B0C13,FF1B1E22,0,FF445476,FF7788B2,FF7188C1,FF7188C1,FF7788B2,FF334260,0,FF1B1E22,FF0C0B0B,0,0,0,0,FF242424,FF1C1C1C,FF2B2B2C,FF1C1C1C,FF242424,0,0,0,0,0,0,0
  160. DATA 0,0,0,0,0,0,0,0,FF1C140E,FF0C130C,FF1C1B0C,FF0B0302,FF0B0302,FF1C1B0C,FF02040B,0,0,FF0C0B0B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF0C0B0B,FF1C1C1C,0,0,0,0,0,0,0,0,FF131413,FF11151D,0,FF4D5D83,FF445476,0,FF11151D,FF131413,0,0,0,0,0,0,0,0,FF1C1C1C,0,0,0,0,0,0,0,0,0
  161. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF1C1B0C,FF14140D,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF1C1C1C,0,0,FF1C1C1C,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  162. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF0B0C13,FF0B0C13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  163. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  164. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  165. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  166. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  167. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  168.  
  169. frame3:
  170. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  171. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  172. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  173. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  174. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  175. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  176. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  177. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF1C1C1C,FF2B2B2B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  178. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF131413,0,0,0,FF3B3B3B,FF343434,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF131413,FF0B0B0B,0,FF242424,FF2B2B2B,0,0,0,0,0,0,0,0,0,0
  179. DATA 0,0,0,0,0,0,0,0,0,FF0C1A0C,FF0B130B,0,0,0,FF0C1A0C,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF3B3B3B,FF1C1C1C,0,FF131413,FF414241,FF242424,0,0,0,0,0,0,0,0,0,0,FF131413,FF1C1C1C,FF1C1C1C,FF242424,0,FF343434,FF1C1C1C,0,FF3B3B3B,FF2B2B2B,0,0,0,0,0,0,0,0,0,0
  180. DATA 0,0,0,0,0,0,0,0,0,0,0,FF090408,FF0C1A0C,FF0B0B0B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF0C1A0C,0,0,0,0,0,0,0,0,0,0,0,0,0,FF414241,FF2B2B2B,0,FF2B2B2B,FF3B3B3B,FF1C1C1C,0,0,FF0B0B0B,0,0,FF242424,FF1C1C1C,FF343434,FF131413,0,FF2B2B2B,FF3B3B3B,FF3B3B3B,FF242424,0,FF3B3B3B,0,FF1C1C1C,FF3B3B3B,0,0,0,0,0,0,0,0,0,0,0
  181. DATA 0,0,0,0,0,0,0,0,FF002300,FF407C42,FF326C34,0,0,0,FF448A46,FF143C15,0,FF0C1A0C,0,0,0,0,0,0,0,0,0,FF030B03,0,0,0,0,0,FF030B03,0,0,0,0,0,0,0,FF131413,FF3B3B3B,FF2B2B2B,FF0B0B0B,FF343434,FF343434,FF1C1C1C,0,FF2B2B2B,FF3B3B3B,FF2B2B2B,0,FF3B3B3B,FF3B3B3B,FF3B3B3B,0,0,FF343434,FF1C1C1C,FF343434,FF131413,FF131413,FF3B3B3B,0,FF2B2B2B,FF343434,0,0,0,0,0,0,0,0,0,0,0
  182. DATA 0,0,0,0,0,0,0,FF0B0B0B,0,FF78CC7A,FF6FCB72,FF5FB661,FF3B7B3D,FF4C9E4E,FF82DD84,FF2C642D,0,0,0,0,0,0,FF031303,0,0,FF0B130B,FF030B03,FF030B03,FF4D934F,FF143C15,0,FF122413,FF131413,0,0,0,0,0,0,0,0,FF242424,FF343434,FF2B2B2B,FF343434,FF2B2B2B,FF343434,FF0B0B0B,FF1C1C1C,FF343434,FF1C1C1C,FF343434,FF1C1C1C,FF343434,FF1C1C1C,FF343434,0,FF131413,FF343434,0,FF343434,0,FF242424,FF3B3B3B,0,FF3B3B3B,FF242424,0,0,0,0,0,0,0,0,0,0,0
  183. DATA 0,0,0,0,0,0,0,FF031303,0,FF266328,FF5BB35D,FF186C1C,FF63BB65,FF54A456,FF53AC54,FF357736,FF002E00,FF61AD62,FF08350A,0,FF030B03,0,0,0,FF0C1A0C,0,0,FF1D5B20,FF88E48A,FF357736,0,0,0,FF003B00,FF0C1A0C,0,0,0,0,0,0,FF343434,FF242424,FF343434,FF3B3B3B,FF0B0B0B,FF343434,0,FF343434,FF1C1C1C,FF343434,FF1C1C1C,FF343434,FF242424,FF242424,FF2B2B2B,0,FF343434,FF2B2B2B,0,FF343434,FF242424,FF343434,FF343434,FF343434,FF3B3B3B,FF242424,0,0,0,0,0,0,0,0,0,0,0
  184. DATA 0,0,0,0,0,0,0,0,FF131413,0,FF66C269,FF407C42,FF002E00,FF002E00,FF448545,FF6CCA6E,FF63BB65,FF7BD47D,FF144716,0,FF030B03,0,FF2C642D,0,FF002300,FF6FC271,FF004700,FF4C9E4E,FF5DBB5F,FF57AD59,FF2E6C30,FF4D934F,FF72C473,FF72C473,0,FF0B130B,0,0,FF2B2B2B,FF1C1C1C,0,FF3B3B3B,0,FF242424,FF2B2B2B,0,FF343434,0,FF343434,FF343434,FF242424,FF1C1C1C,FF3B3B3B,0,FF1D2122,FF343434,FF2B2B2B,FF343434,0,0,FF1C1C1C,FF343434,FF242424,FF131413,FF2B2B2B,FF2B2B2B,FF2B2B2B,0,0,0,0,0,0,0,0,0,0,0
  185. DATA 0,0,0,0,0,0,0,FF0B130B,0,FF6FC271,FF7BD47D,FF005400,FF2E6C30,FF62B464,FF003B00,FF5BAB5C,FF2C812E,FF53AC54,0,0,FF1C1C1C,0,FF72CD74,FF62B464,FF005B00,FF72CD74,FF6CCA6E,FF66C269,FF003400,FF66B968,FF5BB35D,FF4EAB50,FF74D476,FF326C34,0,FF0B130B,0,FF2B2B2B,FF343434,0,FF1C1C1C,FF343434,0,0,FF031303,FF0B130B,FF343434,FF1C1C1C,FF343434,FF343434,FF252B25,FF414241,FF131413,0,0,FF2B2B2B,FF2B2B2B,0,0,0,0,0,0,FF3B3B3B,FF131413,FF2B2B2B,FF2B2B2B,0,0,0,0,0,0,0,0,0,0,0
  186. DATA 0,0,0,0,0,0,0,0,0,FF2C642D,FF439544,FF6FCB72,FF3C833F,FF5FB661,FF3A753B,0,FF5BAB5C,FF5FBA61,FF3C833F,FF407C42,0,0,FF5BB35D,FF53AC54,FF74D476,FF4C9E4E,FF478F49,FF3A753B,0,0,FF003400,FF68BF6A,FF2E6C30,0,FF0C1A0C,0,0,FF3B3B3B,0,0,FF343434,FF201F20,FF030B03,FF131413,0,0,FF2B2B2B,FF343434,FF1B241B,FF302F2F,FF1D001D,0,0,0,0,0,0,0,0,0,0,0,FF2B2B2B,FF2B2B2B,0,FF343434,FF242424,0,0,0,0,0,0,0,0,0,0,0
  187. DATA 0,0,0,0,0,0,0,FF030B03,0,FF002E00,FF449B49,FF63BB65,FF326C34,FF357736,FF63BB65,0,FF61AD62,FF5BAB5C,FF74D476,FF54A456,FF5BAB5C,FF54A456,FF5BB35D,FF002E00,FF61AD62,FF3B7B3D,0,FF448A46,FF63BB65,FF2A752D,FF6CC46D,FF398B3B,0,FF122413,0,0,0,FF343434,FF343434,FF343434,FF343434,0,0,0,FF326C34,FF144716,0,FF122413,0,0,FF448545,FF4B8C4C,FF001900,FF141C14,FF0C1A0C,0,0,FF0B0B0B,0,0,0,0,FF2B2B2B,FF2B2B2B,FF1C1C1C,FF3B3B3B,0,0,0,0,0,0,0,0,0,0,0,0
  188. DATA 0,0,0,0,0,0,0,FF0C1A0C,0,FF549D54,FF82DD84,FF439544,0,0,FF62B464,FF448545,0,FF002300,FF63BB65,FF002E00,FF62B464,FF74D476,FF6FCB72,0,0,FF357736,FF66C269,FF5BB35D,FF054B0A,FF549D54,FF6FCB72,FF5FBA61,FF7BD47D,FF003400,0,FF030B03,0,0,FF2B2B2B,FF242424,FF030B03,0,FF326C34,FF72C473,FF82DD84,FF7FD381,0,0,FF3A753B,FF7FD381,FF72CD74,FF88E48A,FF48854A,0,0,FF030B03,FF0B0B0B,FF343434,0,0,0,0,FF0B0B0B,FF343434,FF343434,FF131413,0,0,0,0,0,0,0,0,0,0,0,0
  189. DATA 0,0,0,0,0,0,0,0,0,FF030B03,FF1A521C,FF4C9E4E,FF6FCB72,FF3A753B,FF0E4811,FF6CC46D,0,FF448545,FF5BAB5C,0,FF5BB35D,FF2A752D,FF1A521C,FF003B00,FF62B464,FF63BB65,FF2C642D,0,0,0,FF449B49,FF72CD74,FF4B8C4C,0,FF0B130B,0,0,0,0,0,FF0B130B,0,FF549D54,FF439544,FF72C473,FF69B36B,0,FF62B464,FF86DC88,FF4B8C4C,FF004700,FF7FD381,FF005400,FF448545,FF4D934F,0,FF1C1C1C,FF343434,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF0B0B0B,FF2B2B2B,FF0B0B0B,0,0,0
  190. DATA 0,0,0,0,0,0,0,0,0,0,0,FF3E8E40,FF6CCA6E,FF357736,0,FF549D54,FF5BAB5C,FF005B00,FF4C9E4E,FF2A752D,FF66C269,0,FF357736,FF6CC46D,FF478F49,0,0,0,FF48854A,FF63BB65,FF54A456,FF0E4811,0,FF0B130B,0,0,0,0,0,0,0,FF1B241B,0,FF266328,FF7FD381,FF004700,FF78CC7A,FF78CC7A,FF003B00,0,FF235225,FF7FD381,FF78CC7A,FF7BD47D,FF448545,0,FF252B25,FF2B2B2B,FF242424,0,0,0,0,0,0,0,0,FF2B2B2B,FF242424,FF2B2B2B,0,FF0B0B0B,FF343434,FF3B3B3B,FF1C1C1C,0,0,0
  191. DATA 0,0,0,0,0,0,0,0,FF0C1A0C,0,FF4D934F,FF88E48A,FF53AC54,FF61AD62,FF1D471E,0,FF5BAB5C,FF53AC54,FF6CC46D,FF66C269,FF57AD59,FF53AC54,FF6CC46D,FF1A521C,0,FF0C2E0E,FF001900,0,FF54A456,FF74D476,FF54A456,FF235225,0,0,FF181718,FF343434,FF343434,FF2B2B2B,0,0,FF1C1C1C,FF363935,0,FF4B8C4C,FF82DD84,FF7BD47D,FF69B36B,0,0,FF1B241B,0,FF2C642D,FF48854A,0,0,FF242424,FF2B2B2B,FF2B2B2B,FF242424,FF0B0B0B,FF131413,FF120D0D,FF1C1C1C,FF2B2B2B,FF0B0B0B,0,FF2B2B2B,FF343434,FF2B2B2B,FF343434,0,FF2B2B2B,FF343434,0,FF0B0B0B,0,0,0
  192. DATA 0,0,0,0,0,0,0,0,0,0,FF0C2E0E,FF003400,FF53AC54,FF74D476,FF398B3B,FF4B8C4C,FF228935,FF66C269,FF6CC46D,0,FF63BB65,FF54A456,0,0,0,FF4D934F,FF78CC7A,FF5BB35D,FF5BB35D,FF63BB65,FF7FD381,FF3B7B3D,0,FF0C1A0C,FF3B3B3B,FF1C1C1C,0,FF343434,FF242424,0,FF2B2B2B,FF2B2B2B,0,FF002300,FF69B36B,FF529454,0,FF131413,FF031303,0,FF030B03,0,0,FF1C1C1C,FF141C14,0,FF2B2B2B,FF242424,0,FF343434,FF343434,FF3B3B3B,FF2B2B2B,FF343434,FF2B2B2B,0,FF3B3B3B,0,FF242424,FF2B2B2B,0,0,FF343434,FF343434,0,0,0,0
  193. DATA 0,0,0,0,0,0,0,0,0,FF0C1A0C,0,FF386F39,FF88E48A,FF5DBB5F,FF5BAB5C,FF449B49,FF83AF61,FF6FAC58,FF006A08,FF62B464,FF449B49,FF348237,FF5BAB5C,FF5BAB5C,FF549D54,FF439544,FF6CCA6E,FF398B3B,FF235225,FF144716,0,0,0,FF2B2B2B,FF2B2B2B,0,0,FF343434,FF2B2B2B,0,FF343434,FF1C1C1C,0,FF090408,0,0,FF141C14,FF1B241B,0,FF131413,FF1C1C1C,FF031303,FF2E332C,FF3B3B3B,FF343434,0,FF343434,FF1C1C1C,FF0B0B0B,FF343434,0,FF343434,0,FF242424,FF2B2B2B,FF0B0B0B,FF343434,0,FF343434,FF1C1C1C,FF242424,FF2B2B2B,0,FF343434,FF242424,0,0,0
  194. DATA 0,0,0,0,0,0,0,0,0,FF030B03,0,FF235225,FF326C34,FF112300,0,FF86002F,FFD35A60,FFC45458,FF5C934D,FF77DA7D,FF46A245,FF88E48A,FF63BB65,FF006C29,FF2D904B,FF399E50,FF6FCB72,FF70BD6F,0,0,FF141C14,FF0B130B,0,FF343434,FF131413,0,FF242424,FF343434,0,0,FF343434,FF1C1C1C,FF0B0B0B,0,FF2E332C,FF2E332C,FF343434,FF343434,0,FF2B2B2B,FF343434,0,FF3B3B3B,FF242424,FF2B2B2B,0,FF343434,0,FF242424,FF343434,0,FF343434,0,FF2B2B2B,FF2B2B2B,0,FF3B3B3B,0,FF343434,FF1C1C1C,FF343434,FF3B3B3B,FF242424,FF343434,FF131413,0,0,0
  195. DATA 0,0,0,0,0,0,0,0,0,0,FF030B03,0,0,FF140000,0,FF913C38,FFBE4341,FFD56364,FF8E4632,FF305A21,FF3C833F,FF469951,FF4C803B,FF7C5918,FF8E6F28,FF7C5918,FF3A510B,FF005C28,FF161A0C,FF091204,0,0,FF131413,FF343434,0,0,FF0B0B0B,0,0,FF0F1010,FF343434,FF343434,FF3B3B3B,FF131413,FF343434,FF343434,FF363935,FF2B2B2B,0,FF343434,FF242424,0,FF2B2B2B,FF3B3B3B,FF0B0B0B,FF131413,FF343434,0,FF2B2B2B,FF242424,FF0B0B0B,FF343434,0,FF2B2B2B,FF2B2B2B,FF242424,FF3B3B3B,FF343434,FF343434,FF2B2B2B,FF2B2B2B,FF1C1C1C,FF343434,FF1C1C1C,0,0,0,0
  196. DATA 0,0,0,0,0,0,0,0,0,0,0,FF0B130B,FF252B25,FF2A2625,0,FF812929,FFD35A60,FFC45458,FFD56364,FFC45458,0,FF5E4002,FFD4BB62,FFCBB25D,FFC5AD59,FFCBB25D,FFD4BB62,FF967F3B,0,FF161A0C,0,0,FF242424,FF343434,0,0,0,FF0B0B0B,FF131413,FF1C1C1C,FF343434,0,FF2B2B2B,FF2B2B2B,FF343434,0,FF2B2B2B,FF242424,0,FF343434,FF1C1C1C,FF2B2B2B,0,FF242424,FF343434,FF242424,FF343434,0,FF3B3B3B,0,FF1C1C1C,FF343434,0,FF0B0B0B,FF343434,FF343434,FF0B0B0B,FF242424,FF0B0B0B,0,0,0,0,0,0,0,0,0
  197. DATA 0,0,0,0,0,0,0,0,0,0,FF242424,FF343434,FF242424,FF002928,FF773B3B,FFD56364,FFC45458,FFCA5252,FFBE4341,FFD35A60,FFC19353,FFAD9941,FF6E5921,0,0,0,FF69541A,FFD4BB62,FFB29B4C,0,FF1B1C11,0,FF2B2B2B,FF2B2B2B,0,0,0,FF1C1C1C,FF343434,FF242424,FF2B2B2B,0,FF343434,FF1C1C1C,FF343434,0,FF2B2B2B,FF242424,FF131413,FF343434,FF242424,FF414241,FF242424,FF343434,FF2B2B2B,FF2B2B2B,FF242424,FF343434,FF242424,0,FF0B0B0B,FF0B0B0B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  198. DATA 0,0,0,0,0,0,0,0,0,FF242424,FF2B2B2B,0,0,FF001D1C,FF603030,FFBE4341,FFD56364,FF913C38,FF9B3240,FFC17452,FFD7C065,FF452D00,0,FF1B1C11,FF1B1B0D,FF1B1B0D,0,0,FFDAC066,FF8E7937,0,FF130E01,FF2B2B2B,FF2B2B2B,0,FF0B0B0B,0,FF2B2B2B,FF242424,FF2B2B2B,FF242424,0,FF343434,FF2B2B2B,FF343434,0,FF131413,FF343434,FF3B3B3B,FF242424,FF2B2B2B,FF1C1C1C,FF343434,FF2B2B2B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  199. DATA 0,0,0,0,0,0,0,0,FF0B0B0B,FF343434,0,0,0,FF1A1010,FF002928,FF773B3B,FF8B4242,FF2E332C,0,FFB29B4C,FFAA9349,0,FF292510,0,0,0,FF292510,0,FF766128,FFD4BB62,FF1E0000,0,FF302F2F,FF242424,0,0,0,FF3B3B3B,FF0B0B0B,FF343434,FF131413,0,FF242424,FF3B3B3B,FF1C1C1C,0,0,0,FF1B1C11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  200. DATA 0,0,0,0,0,0,0,0,FF2B2B2B,FF1C1C1C,0,0,0,0,FF120D0D,FF001D1C,0,FF26241D,FF000019,FFC5AD59,FF8A7433,0,FF151104,0,0,0,0,FF222111,0,FFC5AD59,FF967F3B,0,FF2E332C,FF343434,0,FF0B0B0B,FF343434,FF242424,0,FF2B2B2B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF0B0F14,0,FF02030A,0,0,0,0,0,0,0
  201. DATA 0,0,0,0,0,0,0,0,FF2B2B2B,0,0,0,0,0,0,0,FF140000,FF1B1C11,FF000019,FFC5AD59,FF8E7937,0,FF151104,0,0,0,0,FF191406,0,FF967F3B,FFCBB25D,0,FF1B1B0D,FF302F2F,FF343434,FF343434,FF242424,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF02030A,FF060911,0,FF13150B,0,0,0,0,FF060911,0,0,0,0,0
  202. DATA 0,0,0,0,0,0,0,FF1C1C1C,FF242424,0,0,0,0,0,0,0,0,FF26241D,FF000019,FFB49D51,FFAA9349,0,FF1B1B0D,0,0,0,0,0,0,FF3C2300,FFD4BB62,FF5E4002,0,FF130E01,0,0,0,0,0,0,0,0,FF0B0B0B,FF242424,0,0,0,0,0,0,0,0,0,0,0,FF1C1C1C,FF1C1C1C,0,0,0,0,0,0,FF060911,0,0,FF192335,0,FF6D7EA8,FF1E325B,FF000019,FF16191E,0,FF02030A,0,0,0,0
  203. DATA 0,0,0,0,0,0,0,FF2B2B2B,FF120D0D,0,0,0,0,0,0,0,0,FF26241D,FF000019,FF8A7433,FFCBB25D,0,FF1B1C11,0,0,0,0,0,FF1B1B0D,0,FFAA9349,FFCBB25D,0,FF02030A,FF201E0E,FF130E01,0,0,0,FF0B0B0B,0,FF2B2B2B,FF242424,FF242424,FF2B2B2B,FF1C1C1C,0,FF0B0B0B,0,0,0,0,FF0B0B0B,FF0B0B0B,FF2B2B2B,FF242424,FF242424,FF2B2B2B,FF0B0B0B,FF0B0B0B,0,0,0,0,FF364158,FF00002E,FF617295,FF7E92C3,FF8298D3,FF7287C0,FF8597C3,FF00002E,FF364158,0,0,0,0,0
  204. DATA 0,0,0,0,0,0,FF2B2B2B,FF242424,0,0,0,0,0,0,0,0,0,FF2A2625,FF1D2122,FF1E0000,FFD4BB62,FF6E5921,0,FF191406,0,0,0,0,0,FF0B130B,0,FFC5AD59,FFCBB25D,FF452D00,0,0,FF0D0B03,0,0,FF2B2B2B,FF131413,FF131413,FF343434,FF343434,FF2B2B2B,0,FF2B2B2B,FF131413,0,0,0,0,FF2B2B2B,0,FF1C1C1C,FF343434,FF343434,FF1C1C1C,0,FF2B2B2B,0,0,FF161C29,FF000024,FF4F6294,FF8597C3,0,FF8597C3,FF95ACE5,FF9BADDD,FF334368,FF58668A,FF7E92C3,FF000024,FF29303E,0,0,0
  205. DATA 0,0,0,0,0,FF242424,FF2B2B2B,0,0,0,0,0,0,0,0,0,0,FF2B2B2B,FF201E0E,0,FFA59149,FFC5AD59,0,FF1B1B0D,0,0,0,0,0,FF0C0400,FF13150B,0,FFAA9349,FFD4B95D,FFB8A255,FF7A6731,0,FF1C1C1C,FF2B2B2B,FF2B2B2B,FF1C1C1C,0,FF1C1C1C,FF2B2B2B,0,0,FF2B2B2B,FF242424,FF242424,0,FF201F1F,FF2B2B2B,FF2B2B2B,FF131413,0,FF242424,FF242424,0,FF131413,FF2B2B2B,FF2B2B2B,FF242424,0,FF7B8CB3,FF7D93CC,FF8A9ED2,FF000019,0,FF8DA2D4,FF4C5D87,0,FF7284B2,FF8298D3,FF8698C9,FF334368,0,FF060911,0
  206. DATA 0,0,0,FF131413,FF2B2B2B,FF2B2B2B,0,0,0,0,0,0,0,0,0,0,FF242424,FF2B2B2B,0,FF00080A,FF1E0000,FFD4BB62,FF7A6731,0,FF151104,0,0,0,0,FF1B1C11,0,0,FF310000,FFC4A64D,FFF5DE82,FFA89453,0,FF1B1C11,FF242424,FF343434,FF2B2B2B,FF0B0B0B,FF131413,FF2B2B2B,0,FF242424,FF343434,FF2B2B2B,FF131413,0,FF0B0B0B,FF2B2B2B,FF343434,FF2B2B2B,0,FF242424,FF242424,0,FF2B2B2B,FF343434,FF2B2B2B,FF0B0B0B,FF02030A,FF49609C,FF95ACE5,FF9FB4EB,FF7284B2,FF00002E,FF8DA2D4,FF364B7E,FF45567C,FF90A5DF,FF9FB4EB,FF6D83C1,FF031C43,0,FF02030A,0
  207. DATA 0,0,FF242424,FF3B3B3B,FF2B2B2B,0,0,0,0,0,0,0,0,0,0,0,FF2B2B2B,FF0B0B0B,0,FF201E0E,0,FF9C8644,FFC5AD59,0,FF1B1C11,0,FF151104,FF191406,FF030B03,0,FF5E4B17,FFB49D51,FFDAC066,FFB8A255,FF5E4002,0,FF0D0B03,FF1C1C1C,FF2B2B2B,FF131413,FF1C1C1C,FF2B2B2B,FF242424,FF2B2B2B,FF2B2B2B,FF242424,FF0B0B0B,FF242424,FF242424,0,FF242424,FF242424,FF0B0B0B,FF242424,FF2B2B2B,FF2B2B2B,FF2B2B2B,FF2B2B2B,FF242424,FF0B0B0B,FF272829,FF1B1B0D,FF031C43,FF7D8FB8,FF6D7EA8,FF26417D,FF8597C3,FF7F95D0,FF8298D3,FF7F95D0,FF93A5D3,FF4F6294,FF485D93,FF8597C3,FF45567C,0,FF0B0F14,0
  208. DATA 0,0,0,FF131413,FF242424,FF2B2B2B,FF2B2B2B,FF131413,0,0,0,0,0,0,0,FF1C1C1C,FF2B2B2B,0,0,FF0D0B03,0,FF5E4B17,FFD4BB62,FF301400,0,FF222111,0,0,0,FFB8A255,FFDAC066,FFB29B4C,FF59430D,0,0,FF13150B,0,0,0,0,0,FF1C1C1C,FF2B2B2B,FF242424,FF2B2B2B,0,0,0,0,0,0,0,0,0,FF242424,FF2B2B2B,FF2B2B2B,FF242424,0,0,0,0,FF0D182D,FF1E325B,FF000019,0,FF000050,FF90A5DF,FF5F7FCC,FF90A5DF,FF49609C,0,0,FF001F52,FF1B2A47,0,0,0
  209. DATA 0,0,0,0,0,0,FF242424,FF2B2B2B,FF2B2B2B,0,0,0,0,0,0,FF242424,FF1C1C1C,0,0,0,0,FF3C2300,FFD0B760,FF5E4B17,0,0,FF665422,FF7A6731,0,FFCEB563,FFB29B4C,0,0,FF201E0E,FF130E01,0,0,FF1C1C1C,FF2B2B2B,FF242424,FF2B2B2B,FF2B2B2B,FF242424,FF2B2B2B,FF242424,FF343434,FF242424,FF2B2B2B,FF272829,0,FF242424,FF2B2B2B,FF242424,FF2B2B2B,FF242424,FF242424,FF242424,FF242424,FF2B2B2B,FF242424,FF2E2F31,FF1B1B0D,FF1B2A47,FF8597C3,FF8A9ED2,FF7287C0,FF9BADDD,FF657AB4,FF8298D3,FF657AB4,FF93A5D3,FF8597C3,FF7D93CC,FF93A5D3,FF4C5D87,0,FF0F1219,0
  210. DATA 0,0,0,0,0,0,0,FF131413,FF2B2B2B,0,0,FF2B2B2B,FF131413,0,0,FF2B2B2B,FF1C1C1C,0,0,0,0,FF452D00,FFD4BB62,FF330A00,FF330A00,FFB49D51,FFDAC066,FFE6CD73,FF8E6F28,FFCBB25D,FFA59149,0,FF292510,0,0,0,0,0,FF242424,FF343434,FF242424,0,FF131413,FF2B2B2B,0,FF131413,FF343434,FF2B2B2B,FF131413,0,0,FF2B2B2B,FF343434,FF1C1C1C,0,FF242424,FF242424,0,FF242424,FF343434,FF2B2B2B,FF131413,0,FF485D93,FF95ACE5,FF9BAEE4,FF364B7E,0,FF8A9ED2,FF334368,0,FF8298D3,FF9FB4EB,FF6D82BD,FF00002E,FF0D0B03,0,0
  211. DATA 0,0,0,0,0,0,0,FF131413,FF2B2B2B,0,FF2B2B2B,FF343434,FF2B2B2B,FF2B2B2B,0,FF242424,FF1C1C1C,0,0,FF130E01,0,FF69541A,FFD4B95D,FFB19342,FFD6BF68,FFB8A255,FF513100,FF8A7433,FFD4BB62,FFB49D51,FF1E0000,0,0,0,0,0,0,FF131413,FF242424,FF242424,FF1C1C1C,0,FF1C1C1C,FF2B2B2B,0,0,FF2B2B2B,FF1C1C1C,FF242424,0,FF242424,FF1C1C1C,FF2B2B2B,FF131413,0,FF2B2B2B,FF242424,0,FF131413,FF2B2B2B,FF201F20,FF26241D,0,FF7182A6,FF657AB4,FF8A9ED2,0,FF000050,FF90A5DF,FF4F6294,0,FF7284B2,FF798EC9,FF7284B2,FF3D4964,0,FF060911,0
  212. DATA 0,0,0,0,0,0,0,0,FF1C1C1C,FF2B2B2B,FF242424,0,0,FF242424,FF2B2B2B,FF343434,FF2B2B2B,0,0,FF201E0E,0,FF9C8644,FFF5DE82,FFC4A64D,FF665422,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF242424,0,FF1C1C1C,FF343434,FF343434,FF2B2B2B,0,FF242424,FF0B0B0B,0,0,0,0,FF242424,0,FF242424,FF343434,FF343434,FF242424,0,FF242424,0,0,FF16191E,0,FF45567C,FF6A7A9E,FF000F44,FF93A5D3,FF95ACE5,FF9BAEE4,FF58668A,FF334368,FF6D7EA8,0,FF0D0B03,0,0,0
  213. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF242424,FF2B2B2B,0,0,FF0D0B03,0,FF665422,FF766128,0,0,FF222111,FF0C0400,FF191406,FF161A0C,FF1B1B0D,0,0,0,0,0,0,0,0,0,0,0,FF2B2B2B,FF1C1C1C,FF242424,FF242424,FF1C1C1C,0,0,0,0,0,0,0,FF131413,FF242424,FF242424,FF242424,FF242424,FF0B0B0B,0,0,0,0,FF1C1C1C,FF0B0F14,0,FF6A7A9E,FF657AB4,FF7D93CC,FF657AB4,FF7B8CB3,0,0,FF1D2122,0,0,0,0
  214. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF0D0B03,0,0,FF1B1B0D,FF151104,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF0B0B0B,FF1C1C1C,0,0,0,0,0,0,0,0,0,0,0,FF1C1C1C,FF131413,0,0,0,0,0,0,0,FF02030A,FF16191E,0,0,FF617295,FF142747,0,FF16191E,FF0B0B0B,0,0,0,0,0
  215. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF151104,FF191406,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF131413,0,0,FF131413,0,0,0,0,0,0,0
  216. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF0F1219,FF02030A,0,0,0,0,0,0,0,0
  217. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  218. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  219. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  220. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  221. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  222.  
  223. frame4:
  224. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  225. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  226. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  227. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  228. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  229. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  230. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  231. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF1C1C1C,FF2B2B2B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  232. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF141414,0,0,0,FF3B3B3B,FF333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF141414,FF0B0B0B,0,FF242424,FF2B2B2B,0,0,0,0,0,0,0,0,0,0
  233. DATA 0,0,0,0,0,0,0,0,0,FF0C1A0C,FF0B130B,0,0,0,FF0C1A0C,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF3B3B3B,FF1C1C1C,0,FF141414,FF424242,FF242424,0,0,0,0,0,0,0,0,0,0,FF141414,FF1C1C1C,FF1C1C1C,FF242424,0,FF333333,FF1C1C1C,0,FF3B3B3B,FF2B2B2B,0,0,0,0,0,0,0,0,0,0
  234. DATA 0,0,0,0,0,0,0,0,0,0,0,FF090408,FF0C1A0C,FF0B0B0B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF0C1A0C,0,0,0,0,0,0,0,0,0,0,0,0,0,FF424242,FF2B2B2B,0,FF2B2B2B,FF3B3B3B,FF1C1C1C,0,0,FF0B0B0B,0,0,FF242424,FF1C1C1C,FF333333,FF141414,0,FF2B2B2B,FF3B3B3B,FF3B3B3B,FF242424,0,FF3B3B3B,0,FF1C1C1C,FF3B3B3B,0,0,0,0,0,0,0,0,0,0,0
  235. DATA 0,0,0,0,0,0,0,0,FF002300,FF407C42,FF326C34,0,0,0,FF448A46,FF143C15,0,FF0C1A0C,0,0,0,0,0,0,0,0,0,FF030B03,0,0,0,0,0,FF030B03,0,0,0,0,0,0,0,FF141414,FF3B3B3B,FF2B2B2B,FF0B0B0B,FF333333,FF333333,FF1C1C1C,0,FF2B2B2B,FF3B3B3B,FF2B2B2B,0,FF3B3B3B,FF3B3B3B,FF3B3B3B,0,0,FF333333,FF1C1C1C,FF333333,FF141414,FF141414,FF3B3B3B,0,FF2B2B2B,FF333333,0,0,0,0,0,0,0,0,0,0,0
  236. DATA 0,0,0,0,0,0,0,FF0B0B0B,0,FF76CB78,FF6FCB72,FF5FB661,FF3B7B3D,FF4A9C4C,FF81E183,FF2C662E,0,0,0,0,0,0,FF031303,0,0,FF0B130B,FF030B03,FF030B03,FF4F9351,FF143C15,0,FF112111,FF141414,0,0,0,0,0,0,0,0,FF242424,FF333333,FF2B2B2B,FF333333,FF2B2B2B,FF333333,FF0B0B0B,FF1C1C1C,FF333333,FF1C1C1C,FF333333,FF1C1C1C,FF333333,FF1C1C1C,FF333333,0,FF141414,FF333333,0,FF333333,0,FF242424,FF3B3B3B,0,FF3B3B3B,FF242424,0,0,0,0,0,0,0,0,0,0,0
  237. DATA 0,0,0,0,0,0,0,FF031303,0,FF266328,FF5BB35D,FF186C1C,FF63BB65,FF56A658,FF53AB55,FF347936,FF002E00,FF61AC62,FF08350A,0,FF030B03,0,0,0,FF0C1A0C,0,0,FF1D5B20,FF87E589,FF347535,0,0,0,FF003B00,FF0C1A0C,0,0,0,0,0,0,FF333333,FF242424,FF333333,FF3B3B3B,FF0B0B0B,FF333333,0,FF333333,FF1C1C1C,FF333333,FF1C1C1C,FF333333,FF242424,FF242424,FF2B2B2B,0,FF333333,FF2B2B2B,0,FF333333,FF242424,FF333333,FF333333,FF333333,FF3B3B3B,FF242424,0,0,0,0,0,0,0,0,0,0,0
  238. DATA 0,0,0,0,0,0,0,0,FF141414,0,FF66C269,FF407C42,FF002E00,FF002E00,FF448545,FF6CCA6E,FF63BB65,FF7CD37E,FF144A16,0,FF030B03,0,FF2C662E,0,FF002300,FF6FC271,FF004900,FF4FA051,FF5DBB5F,FF57AD59,FF2E6C30,FF4B944C,FF72C473,FF72C473,0,FF0B130B,0,0,FF2B2B2B,FF1C1C1C,0,FF3B3B3B,0,FF242424,FF2B2B2B,0,FF333333,0,FF333333,FF333333,FF242424,FF1C1C1C,FF3B3B3B,0,FF1D2122,FF333333,FF2B2B2B,FF333333,0,0,FF1C1C1C,FF333333,FF242424,FF141414,FF2B2B2B,FF2B2B2B,FF2B2B2B,0,0,0,0,0,0,0,0,0,0,0
  239. DATA 0,0,0,0,0,0,0,FF0B130B,0,FF6FC271,FF79DA7B,FF005400,FF2E6C30,FF62B464,FF003B00,FF5BAB5C,FF2C812E,FF53AB55,0,0,FF1C1C1C,0,FF72CD74,FF62B464,FF005B00,FF72CD74,FF6CCA6E,FF66C269,FF003400,FF66B968,FF5BB35D,FF4EAB50,FF76D578,FF326C34,0,FF0B130B,0,FF2B2B2B,FF333333,0,FF1C1C1C,FF333333,0,0,FF031303,FF0B130B,FF333333,FF1C1C1C,FF333333,FF333333,FF252B25,FF3D433E,FF141414,0,0,FF2B2B2B,FF2B2B2B,0,0,0,0,0,0,FF3B3B3B,FF141414,FF2B2B2B,FF2B2B2B,0,0,0,0,0,0,0,0,0,0,0
  240. DATA 0,0,0,0,0,0,0,0,0,FF2A5E2C,FF439544,FF6FCB72,FF3C833F,FF5FB661,FF3A753B,0,FF5BAB5C,FF5FBA61,FF3C833F,FF407C42,0,0,FF5BB35D,FF53AB55,FF73D375,FF4A9C4C,FF478F49,FF3A753B,0,0,FF003400,FF68BF6A,FF2E6C30,0,FF0C1A0C,0,0,FF3B3B3B,0,0,FF333333,FF201F20,FF030B03,FF141414,0,0,FF2B2B2B,FF333333,FF1B231C,FF302F2F,FF1D001D,0,0,0,0,0,0,0,0,0,0,0,FF2B2B2B,FF2B2B2B,0,FF333333,FF242424,0,0,0,0,0,0,0,0,0,0,0
  241. DATA 0,0,0,0,0,0,0,FF030B03,0,FF002E00,FF459C4A,FF63BB65,FF326C34,FF347535,FF63BB65,0,FF61AC62,FF5BAB5C,FF73D375,FF53A455,FF5BAB5C,FF53A455,FF5BB35D,FF002E00,FF61AC62,FF3B7B3D,0,FF448A46,FF63BB65,FF2A792D,FF6CC46D,FF378839,0,FF162A16,0,0,0,FF333333,FF333333,FF333333,FF333333,0,0,0,FF326C34,FF144A16,0,FF112111,0,0,FF448545,FF4B8C4B,FF001900,FF141C14,FF0C1A0C,0,0,FF0B0B0B,0,0,0,0,FF2B2B2B,FF2B2B2B,FF1C1C1C,FF3B3B3B,0,0,0,0,0,0,0,0,0,0,0,0
  242. DATA 0,0,0,0,0,0,0,FF0C1A0C,0,FF569E58,FF81E183,FF439544,0,0,FF62B464,FF448545,0,FF002300,FF63BB65,FF002E00,FF62B464,FF73D375,FF6FCB72,0,0,FF347936,FF66C269,FF5BB35D,FF054B0A,FF539D54,FF6FCB72,FF5FBA61,FF7CD37E,FF003400,0,FF030B03,0,0,FF2B2B2B,FF242424,FF030B03,0,FF326C34,FF72C473,FF84DA85,FF7FD281,0,0,FF3A753B,FF7FD281,FF72CD74,FF89E38B,FF48854A,0,0,FF030B03,FF0B0B0B,FF333333,0,0,0,0,FF0B0B0B,FF333333,FF333333,FF141414,0,0,0,0,0,0,0,0,0,0,0,0
  243. DATA 0,0,0,0,0,0,0,0,0,FF030B03,FF1C531E,FF4FA051,FF6FCB72,FF3A753B,FF0E4B11,FF6CC46D,0,FF448545,FF5BAB5C,0,FF5BB35D,FF2B742D,FF1C531E,FF003B00,FF62B464,FF63BB65,FF2C662E,0,0,0,FF439845,FF72CD74,FF4B8C4B,0,FF0B130B,0,0,0,0,0,FF0B130B,0,FF539D54,FF439544,FF72C473,FF68AF6A,0,FF62B464,FF86DC88,FF4B8C4B,FF004600,FF7FD281,FF005400,FF448545,FF4F9351,0,FF1C1C1C,FF333333,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF0B0B0B,FF2B2B2B,FF0B0B0B,0,0,0
  244. DATA 0,0,0,0,0,0,0,0,0,0,0,FF3E8E40,FF6CCA6E,FF367638,0,FF539D54,FF5BAB5C,FF005B00,FF4CA04E,FF2B742D,FF66C269,0,FF367638,FF6CC46D,FF478F49,0,0,0,FF48854A,FF63BB65,FF53A455,FF0D4510,0,FF0B130B,0,0,0,0,0,0,0,FF1B231C,0,FF266328,FF7FD281,FF004600,FF79CD7B,FF79CD7B,FF003B00,0,FF235325,FF83D785,FF79CD7B,FF7CD37E,FF448545,0,FF252B25,FF2B2B2B,FF242424,0,0,0,0,0,0,0,0,FF2B2B2B,FF242424,FF2B2B2B,0,FF0B0B0B,FF333333,FF3B3B3B,FF1C1C1C,0,0,0
  245. DATA 0,0,0,0,0,0,0,0,FF0C1A0C,0,FF4F9351,FF87E589,FF52B053,FF5EAE60,FF1D471E,0,FF5BAB5C,FF53AB55,FF6CC46D,FF64C066,FF57AD59,FF53AB55,FF6CC46D,FF184F1A,0,FF0C2E0E,FF001900,0,FF53A455,FF73D375,FF56A658,FF235325,0,0,FF181718,FF333333,FF333333,FF2B2B2B,0,0,FF1C1C1C,FF363935,0,FF4F8D50,FF84DA85,FF7CD37E,FF6AB56C,0,0,FF182818,0,FF2C662E,FF48854A,0,0,FF242424,FF2B2B2B,FF2B2B2B,FF242424,FF0B0B0B,FF141414,FF120D0D,FF1C1C1C,FF2B2B2B,FF0B0B0B,0,FF2B2B2B,FF333333,FF2B2B2B,FF333333,0,FF2B2B2B,FF333333,0,FF0B0B0B,0,0,0
  246. DATA 0,0,0,0,0,0,0,0,0,0,FF0C2E0E,FF003400,FF53AB55,FF76D578,FF3A8C3C,FF4B8C4B,FF228935,FF66C269,FF6CC46D,0,FF63BB65,FF53A455,0,0,0,FF4B944C,FF79CD7B,FF5BB35D,FF5BB35D,FF63BB65,FF7FD281,FF3B7B3D,0,FF0C1A0C,FF3B3B3B,FF1C1C1C,0,FF333333,FF242424,0,FF2B2B2B,FF2B2B2B,0,FF002300,FF6AB56C,FF529454,0,FF141414,FF031303,0,FF030B03,0,0,FF1C1C1C,FF141C14,0,FF2B2B2B,FF242424,0,FF333333,FF333333,FF3B3B3B,FF2B2B2B,FF333333,FF2B2B2B,0,FF3B3B3B,0,FF242424,FF2B2B2B,0,0,FF333333,FF333333,0,0,0,0
  247. DATA 0,0,0,0,0,0,0,0,0,FF0C1A0C,0,FF386F39,FF89E38B,FF5DBB5F,FF5BAB5C,FF459C4A,FF83AF61,FF6FAC58,FF006A08,FF62B464,FF459C4A,FF348237,FF5BAB5C,FF5BAB5C,FF539D54,FF439544,FF6CCA6E,FF3A8C3C,FF235325,FF164317,0,0,0,FF2B2B2B,FF2B2B2B,0,0,FF333333,FF2B2B2B,0,FF333333,FF1C1C1C,0,FF090408,0,0,FF141C14,FF1B231C,0,FF141414,FF1C1C1C,FF031303,FF2D332D,FF3B3B3B,FF333333,0,FF333333,FF1C1C1C,FF0B0B0B,FF333333,0,FF333333,0,FF242424,FF2B2B2B,FF0B0B0B,FF333333,0,FF333333,FF1C1C1C,FF242424,FF2B2B2B,0,FF333333,FF242424,0,0,0
  248. DATA 0,0,0,0,0,0,0,0,0,FF030B03,0,FF244F25,FF326C34,FF112300,0,FF86002F,FFD55B63,FFC34F56,FF5C934D,FF77DA7D,FF46A245,FF89E38B,FF63BB65,FF006C29,FF2D904B,FF399E50,FF6FCB72,FF70BD6F,0,0,FF141C14,FF0B130B,0,FF333333,FF141414,0,FF242424,FF333333,0,0,FF333333,FF1C1C1C,FF0B0B0B,0,FF2D332D,FF2D332D,FF333333,FF333333,0,FF2B2B2B,FF333333,0,FF3B3B3B,FF242424,FF2B2B2B,0,FF333333,0,FF242424,FF333333,0,FF333333,0,FF2B2B2B,FF2B2B2B,0,FF3B3B3B,0,FF333333,FF1C1C1C,FF333333,FF3B3B3B,FF242424,FF333333,FF141414,0,0,0
  249. DATA 0,0,0,0,0,0,0,0,0,0,FF030B03,0,0,FF140000,0,FF913E3A,FFBE4743,FFD56364,FF8E4632,FF305A21,FF3C833F,FF469951,FF4C803B,FF7D5518,FF8C6D2B,FF7A5C17,FF3A510B,FF005C28,FF161A0C,FF091204,0,0,FF141414,FF333333,0,0,FF0B0B0B,0,0,FF0F1010,FF333333,FF333333,FF3B3B3B,FF141414,FF333333,FF333333,FF363935,FF2B2B2B,0,FF333333,FF242424,0,FF2B2B2B,FF3B3B3B,FF0B0B0B,FF141414,FF333333,0,FF2B2B2B,FF242424,FF0B0B0B,FF333333,0,FF2B2B2B,FF2B2B2B,FF242424,FF3B3B3B,FF333333,FF333333,FF2B2B2B,FF2B2B2B,FF1C1C1C,FF333333,FF1C1C1C,0,0,0,0
  250. DATA 0,0,0,0,0,0,0,0,0,0,0,FF0B130B,FF252B25,FF2A2625,0,FF812929,FFD15A5A,FFC35555,FFD56364,FFC5575A,0,FF613B00,FFD4BB62,FFCBB35D,FFC4AC56,FFCBB35D,FFD4BB62,FF9B7F39,0,FF161A0C,0,0,FF242424,FF333333,0,0,0,FF0B0B0B,FF141414,FF1C1C1C,FF333333,0,FF2B2B2B,FF2B2B2B,FF333333,0,FF2B2B2B,FF242424,0,FF333333,FF1C1C1C,FF2B2B2B,0,FF242424,FF333333,FF242424,FF333333,0,FF3B3B3B,0,FF1C1C1C,FF333333,0,FF0B0B0B,FF333333,FF333333,FF0B0B0B,FF242424,FF0B0B0B,0,0,0,0,0,0,0,0,0
  251. DATA 0,0,0,0,0,0,0,0,0,0,FF242424,FF333333,FF242424,FF002928,FF773B3B,FFD56364,FFC5575A,FFCA5252,FFBE4743,FFD55B63,FFC19353,FFAD9941,FF6E5921,0,0,0,FF685217,FFD4BB62,FFB29B4C,0,FF1B1C11,0,FF2B2B2B,FF2B2B2B,0,0,0,FF1C1C1C,FF333333,FF242424,FF2B2B2B,0,FF333333,FF1C1C1C,FF333333,0,FF2B2B2B,FF242424,FF141414,FF333333,FF242424,FF424242,FF242424,FF333333,FF2B2B2B,FF2B2B2B,FF242424,FF333333,FF242424,0,FF0B0B0B,FF0B0B0B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  252. DATA 0,0,0,0,0,0,0,0,0,FF242424,FF2B2B2B,0,0,FF001D1C,FF603030,FFBD3D3D,FFD56364,FF903935,FF9B3240,FFC17452,FFD7C065,FF452D00,0,FF1B1C11,FF1B1B0D,FF1B1B0D,0,0,FFDAC066,FF8E7937,0,FF130E01,FF2B2B2B,FF2B2B2B,0,FF0B0B0B,0,FF2B2B2B,FF242424,FF2B2B2B,FF242424,0,FF333333,FF2B2B2B,FF333333,0,FF141414,FF333333,FF3B3B3B,FF242424,FF2B2B2B,FF1C1C1C,FF333333,FF2B2B2B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  253. DATA 0,0,0,0,0,0,0,0,FF0B0B0B,FF333333,0,0,0,FF1A1010,FF002928,FF773B3B,FF8B4242,FF2A3027,0,FFB29B4C,FFAA9349,0,FF292510,0,0,0,FF292510,0,FF776125,FFD4BB62,FF1D0000,0,FF302F2F,FF242424,0,0,0,FF3B3B3B,FF0B0B0B,FF333333,FF141414,0,FF242424,FF3B3B3B,FF1C1C1C,0,0,0,FF1B1C11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  254. DATA 0,0,0,0,0,0,0,0,FF2B2B2B,FF1C1C1C,0,0,0,0,FF120D0D,FF001D1C,0,FF26241C,FF00001C,FFC5AD59,FF8A7433,0,FF151104,0,0,0,0,FF1F2012,0,FFC5AD59,FF96813E,0,FF34332C,FF333333,0,FF0B0B0B,FF333333,FF242424,0,FF2B2B2B,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  255. DATA 0,0,0,0,0,0,0,0,FF2B2B2B,0,0,0,0,0,0,0,FF140000,FF1B1C11,FF00001C,FFC5AD59,FF8E7937,0,FF151104,0,0,0,0,FF191406,0,FF917C3A,FFC8AF5D,0,FF1B1B0D,FF302F2F,FF333333,FF333333,FF242424,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  256. DATA 0,0,0,0,0,0,0,FF1C1C1C,FF242424,0,0,0,0,0,0,0,0,FF26241C,FF000014,FFB49D51,FFAA9349,0,FF1B1B0D,0,0,0,0,0,0,FF3C2300,FFD4BB62,FF5D4304,0,FF130E01,0,0,0,0,0,0,0,0,FF0B0B0B,FF242424,0,0,0,0,0,0,0,0,0,0,0,FF1C1C1C,FF1C1C1C,0,0,0,0,0,0,0,0,0,0,0,FF242424,0,0,0,0,0,0,0,0,0
  257. DATA 0,0,0,0,0,0,0,FF2B2B2B,FF120D0D,0,0,0,0,0,0,0,0,FF29271E,FF00001C,FF8A7433,FFCBB35D,0,FF1B1C11,0,0,0,0,0,FF1B1B0D,0,FFAA9349,FFCBB35D,0,FF000008,FF201E0E,FF130E01,0,0,0,FF0B0B0B,0,FF2B2B2B,FF242424,FF242424,FF2B2B2B,FF1C1C1C,0,FF0B0B0B,0,0,0,0,FF0B0B0B,FF0B0B0B,FF2B2B2B,FF242424,FF242424,FF2B2B2B,FF0B0B0B,FF0B0B0B,0,0,0,0,FF0B0B0B,0,FF1C1C1C,FF242424,FF2B2B2B,FF242424,FF2B2B2B,0,FF0B0B0B,0,0,0,0,0
  258. DATA 0,0,0,0,0,0,FF2B2B2B,FF242424,0,0,0,0,0,0,0,0,0,FF2A2625,FF1D2122,FF230000,FFD4BB62,FF6E5921,0,FF191406,0,0,0,0,0,FF0B130B,0,FFC5AD59,FFCBB35D,FF452D00,0,0,FF0D0B03,0,0,FF2B2B2B,FF141414,FF141414,FF333333,FF333333,FF2B2B2B,0,FF2B2B2B,FF141414,0,0,0,0,FF2B2B2B,0,FF1C1C1C,FF333333,FF333333,FF1C1C1C,0,FF2B2B2B,0,0,0,0,FF141414,FF2B2B2B,0,FF2B2B2B,FF333333,FF333333,FF0B0B0B,FF1C1C1C,FF2B2B2B,0,FF0B0B0B,0,0,0
  259. DATA 0,0,0,0,0,FF242424,FF2B2B2B,0,0,0,0,0,0,0,0,0,0,FF2B2B2B,FF201E0E,0,FFA59149,FFC5AD59,0,FF1B1B0D,0,0,0,0,0,FF0C0400,FF12150A,0,FFAA9349,FFD1B75F,FFBAA354,FF786734,0,FF1C1C1C,FF2B2B2B,FF2B2B2B,FF1C1C1C,0,FF1C1C1C,FF2B2B2B,0,0,FF2B2B2B,FF242424,FF242424,0,FF201F1F,FF2B2B2B,FF2B2B2B,FF141414,0,FF242424,FF242424,0,FF141414,FF2B2B2B,FF2B2B2B,FF1C1C1C,0,FF2B2B2B,FF242424,FF2B2B2B,0,0,FF2B2B2B,FF141414,0,FF242424,FF2B2B2B,FF2B2B2B,FF141414,0,0,0
  260. DATA 0,0,0,FF141414,FF2B2B2B,FF2B2B2B,0,0,0,0,0,0,0,0,0,0,FF242424,FF2B2B2B,0,FF00080A,FF1D0000,FFD4BB62,FF7D682C,0,FF151104,0,0,0,0,FF1B1C11,0,0,FF310000,FFC7A647,FFF5DE82,FFA89453,0,FF1B1C11,FF242424,FF333333,FF2B2B2B,FF0B0B0B,FF141414,FF2B2B2B,0,FF242424,FF333333,FF2B2B2B,FF141414,0,FF0B0B0B,FF2B2B2B,FF333333,FF2B2B2B,0,FF242424,FF242424,0,FF2B2B2B,FF333333,FF2B2B2B,FF0B0B0B,0,FF141414,FF333333,FF333333,FF242424,0,FF2B2B2B,FF0B0B0B,FF141414,FF333333,FF333333,FF242424,0,0,0,0
  261. DATA 0,0,FF242424,FF3B3B3B,FF2B2B2B,0,0,0,0,0,0,0,0,0,0,0,FF2B2B2B,FF0B0B0B,0,FF201E0E,0,FF9C8644,FFC5AD59,0,FF1B1C11,0,FF151104,FF191406,FF030B03,0,FF604B16,FFB49D51,FFDAC066,FFBAA354,FF5D4304,0,FF0D0B03,FF1C1C1C,FF2B2B2B,FF141414,FF1C1C1C,FF2B2B2B,FF242424,FF2B2B2B,FF2B2B2B,FF242424,FF0B0B0B,FF242424,FF242424,0,FF242424,FF242424,FF0B0B0B,FF242424,FF2B2B2B,FF2B2B2B,FF2B2B2B,FF2B2B2B,FF242424,FF0B0B0B,FF242424,FF242424,0,FF2B2B2B,FF242424,FF0B0B0B,FF2B2B2B,FF2B2B2B,FF2B2B2B,FF2B2B2B,FF2B2B2B,FF141414,FF141414,FF2B2B2B,FF141414,0,0,0
  262. DATA 0,0,0,FF141414,FF242424,FF2B2B2B,FF2B2B2B,FF141414,0,0,0,0,0,0,0,FF1C1C1C,FF2B2B2B,0,0,FF0D0B03,0,FF604B16,FFD4BB62,FF301400,0,FF242211,0,0,0,FFB4A058,FFDAC066,FFB29B4C,FF59430D,0,0,FF12150A,0,0,0,0,0,FF1C1C1C,FF2B2B2B,FF242424,FF2B2B2B,0,0,0,0,0,0,0,0,0,FF242424,FF2B2B2B,FF2B2B2B,FF242424,0,0,0,0,0,0,0,0,0,FF2B2B2B,FF242424,FF2B2B2B,FF141414,0,0,0,0,0,0,0
  263. DATA 0,0,0,0,0,0,FF242424,FF2B2B2B,FF2B2B2B,0,0,0,0,0,0,FF242424,FF1C1C1C,0,0,0,0,FF3C2300,FFD1B75F,FF5B4A19,0,0,FF655423,FF786734,0,FFCEB563,FFB29B4C,0,0,FF201E0E,FF130E01,0,0,FF1C1C1C,FF2B2B2B,FF242424,FF2B2B2B,FF2B2B2B,FF242424,FF2B2B2B,FF242424,FF333333,FF242424,FF2B2B2B,FF272728,0,FF242424,FF2B2B2B,FF242424,FF2B2B2B,FF242424,FF242424,FF242424,FF242424,FF2B2B2B,FF242424,FF2B2B2B,FF242424,0,FF2B2B2B,FF2B2B2B,FF242424,FF333333,FF1C1C1C,FF2B2B2B,FF1C1C1C,FF2B2B2B,FF2B2B2B,FF2B2B2B,FF2B2B2B,FF1C1C1C,0,0,0
  264. DATA 0,0,0,0,0,0,0,FF141414,FF2B2B2B,0,0,FF2B2B2B,FF141414,0,0,FF2B2B2B,FF1C1C1C,0,0,0,0,FF452D00,FFD4BB62,FF370800,FF2F0C00,FFB49D51,FFDAC066,FFE6CD73,FF907125,FFCBB35D,FFA59149,0,FF292510,0,0,0,0,0,FF242424,FF333333,FF242424,0,FF141414,FF2B2B2B,0,FF141414,FF333333,FF2B2B2B,FF141414,0,0,FF2B2B2B,FF333333,FF1C1C1C,0,FF242424,FF242424,0,FF242424,FF333333,FF2B2B2B,0,0,FF141414,FF333333,FF333333,FF0B0B0B,0,FF2B2B2B,FF0B0B0B,0,FF2B2B2B,FF333333,FF242424,0,0,0,0
  265. DATA 0,0,0,0,0,0,0,FF141414,FF2B2B2B,0,FF2B2B2B,FF333333,FF2B2B2B,FF2B2B2B,0,FF242424,FF1C1C1C,0,0,FF130E01,0,FF6A551D,FFD6BA5B,FFB19342,FFD6BF68,FFBAA354,FF513100,FF8A7433,FFD4BB62,FFB49D51,FF1D0000,0,0,0,0,0,0,FF141414,FF242424,FF242424,FF1C1C1C,0,FF1C1C1C,FF2B2B2B,0,0,FF2B2B2B,FF1C1C1C,FF242424,0,FF242424,FF1C1C1C,FF2B2B2B,FF141414,0,FF2B2B2B,FF242424,0,FF141414,FF2B2B2B,FF1C1C1C,FF1C1C1C,0,FF242424,FF1C1C1C,FF2B2B2B,0,0,FF333333,FF141414,0,FF242424,FF242424,FF242424,FF141414,0,0,0
  266. DATA 0,0,0,0,0,0,0,0,FF1C1C1C,FF2B2B2B,FF242424,0,0,FF242424,FF2B2B2B,FF333333,FF2B2B2B,0,0,FF201E0E,0,FF9C8644,FFF5DE82,FFC0A652,FF695522,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF242424,0,FF1C1C1C,FF333333,FF333333,FF2B2B2B,0,FF242424,FF0B0B0B,0,0,0,0,FF242424,0,FF242424,FF333333,FF333333,FF242424,0,FF242424,0,0,0,0,FF141414,FF242424,0,FF2B2B2B,FF333333,FF333333,FF141414,FF0B0B0B,FF242424,0,0,0,0,0
  267. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF242424,FF2B2B2B,0,0,FF0D0B03,0,FF655423,FF75612B,0,0,FF242211,FF0C0400,FF191406,FF161A0C,FF1B1B0D,0,0,0,0,0,0,0,0,0,0,0,FF2B2B2B,FF1C1C1C,FF242424,FF242424,FF1C1C1C,0,0,0,0,0,0,0,FF141414,FF242424,FF242424,FF242424,FF242424,FF0B0B0B,0,0,0,0,0,0,0,FF242424,FF1C1C1C,FF2B2B2B,FF1C1C1C,FF242424,0,0,0,0,0,0,0
  268. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF0D0B03,0,0,FF1B1B0D,FF151104,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF0B0B0B,FF1C1C1C,0,0,0,0,0,0,0,0,0,0,0,FF1C1C1C,FF141414,0,0,0,0,0,0,0,0,0,0,0,FF1C1C1C,0,0,0,0,0,0,0,0,0
  269. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF151104,FF191406,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  270. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  271. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  272. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  273. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  274. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  275. DATA 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  276.  
  277. SUB CircleFill (CX AS INTEGER, CY AS INTEGER, R AS INTEGER, C AS _UNSIGNED LONG)
  278.     ' CX = center x coordinate
  279.     ' CY = center y coordinate
  280.     '  R = radius
  281.     '  C = fill color
  282.     DIM Radius AS INTEGER, RadiusError AS INTEGER
  283.     DIM X AS INTEGER, Y AS INTEGER
  284.     Radius = ABS(R)
  285.     RadiusError = -Radius
  286.     X = Radius
  287.     Y = 0
  288.     IF Radius = 0 THEN PSET (CX, CY), C: EXIT SUB
  289.     LINE (CX - X, CY)-(CX + X, CY), C, BF
  290.     WHILE X > Y
  291.         RadiusError = RadiusError + Y * 2 + 1
  292.         IF RadiusError >= 0 THEN
  293.             IF X <> Y + 1 THEN
  294.                 LINE (CX - Y, CY - X)-(CX + Y, CY - X), C, BF
  295.                 LINE (CX - Y, CY + X)-(CX + Y, CY + X), C, BF
  296.             END IF
  297.             X = X - 1
  298.             RadiusError = RadiusError - X * 2
  299.         END IF
  300.         Y = Y + 1
  301.         LINE (CX - X, CY - Y)-(CX + X, CY - Y), C, BF
  302.         LINE (CX - X, CY + Y)-(CX + X, CY + Y), C, BF
  303.     WEND
  304.  
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 23, 2020, 12:08:59 pm
@SMcNeill  Fireworks never get old, nice colorful version.

@FellippeHeitor  nice, no monster data load program :)

This has been a crummy year and I hear allot of people saying it's hard to get into the spirit, gotta say this thread sure helped distract me :)
Title: Re: %uD83C%uDF84%uD83C%uDF81%u2728 Holiday Season - are you ready to code?
Post by: Ashish on December 23, 2020, 01:25:35 pm
Ashish's Submission -

Code: [Select]
'coded for holidays 2020
'Merry Christmas! & Happy Holidays!
'from Ashish
RANDOMIZE TIMER
_TITLE "Merry Christmas 2020! Greetings From Ashish!"
SCREEN _NEWIMAGE(800, 600, 32)


TYPE vec3
    x AS SINGLE
    y AS SINGLE
    z AS SINGLE
END TYPE

TYPE snow_obj
    pos AS vec3
    vel AS vec3
END TYPE

DECLARE LIBRARY 'camera control function
    SUB gluLookAt (BYVAL eyeX#, BYVAL eyeY#, BYVAL eyeZ#, BYVAL centerX#, BYVAL centerY#, BYVAL centerZ#, BYVAL upX#, BYVAL upY#, BYVAL upZ#)
END DECLARE

DIM SHARED perlin_octaves, perlin_amp_falloff 'noise related variables
DIM SHARED max_w, max_h
max_w = 100: max_h = 100

DIM SHARED gl_init

DIM SHARED snow(1000) AS snow_obj

FOR i = 0 TO UBOUND(snow)
    snow(i).pos.y = p5random(10, 20)
    IF RND > 0.5 THEN snow(i).pos.x = p5random(-20, -2) ELSE snow(i).pos.x = p5random(2, 20)
    IF RND > 0.5 THEN snow(i).pos.z = p5random(-20, -2) ELSE snow(i).pos.z = p5random(2, 20)

    snow(i).vel.y = p5random(-0.3, -0.05)
NEXT

DIM SHARED map_vert(max_w * max_h * 6), map_norm(max_w * max_h * 6), h_map(100, 100) AS vec3
DIM SHARED max_vert_index

REDIM SHARED pineMesh(0) AS SINGLE, pineMeshInfo(0) AS mesh_part_info, pineMeshFileInfo AS MDL_INFO
f$ = Writetree.basData("tree.binobj")
objImportBin f$, pineMesh(), pineMeshInfo(), pineMeshFileInfo


DIM SHARED sky_tex AS LONG
sky_tex = _NEWIMAGE(800, 600, 32)
_DEST sky_tex
FOR i = 0 TO 300
    LINE (0, i)-(800, i), _RGB(map(i, 0, 300, 46, 130), map(i, 0, 300, 0, 2), map(i, 0, 300, 91, 130))
NEXT
FOR i = 300 TO 600
    LINE (0, i)-(800, i), _RGB(map(i, 300, 600, 130, 237), map(i, 300, 600, 2, 173), map(i, 300, 600, 130, 90))
NEXT
_DEST 0


FOR i = 0 TO 100
    FOR j = 0 TO 100
        ' pset (i,j),_rgb32(150*abs(noise(i*0.05,j*0.05,0))+50)

        h_map(i, j).x = map(i, 0, 100, -30, 30)
        h_map(i, j).y = -2 + 8 * ABS(noise(i * 0.05, j * 0.05, 0))
        h_map(i, j).z = map(j, 0, 100, -30, 30)
    NEXT j
NEXT i

init_land

_PUTIMAGE , sky_tex
_GLRENDER _ONTOP
gl_init = 1
DO
    FOR i = 0 TO UBOUND(snow)
        snow(i).pos.y = snow(i).pos.y + snow(i).vel.y
        IF snow(i).pos.y < -2 THEN
            snow(i).pos.y = p5random(10, 20)
            IF RND > 0.5 THEN snow(i).pos.x = p5random(-20, -2) ELSE snow(i).pos.x = p5random(2, 20)
            IF RND > 0.5 THEN snow(i).pos.z = p5random(-20, -2) ELSE snow(i).pos.z = p5random(2, 20)

            snow(i).vel.y = p5random(-0.3, -0.05)
        END IF
    NEXT
    _LIMIT 60
LOOP

SUB _GL ()
    STATIC init, clock
    IF gl_init = 0 THEN EXIT SUB
    IF init = 0 THEN
        init = 1
        _glViewport 0, 0, 800, 600

    END IF


    _glEnable _GL_DEPTH_TEST
    _glEnable _GL_LIGHTING
    _glEnable _GL_LIGHT0

    _glShadeModel _GL_SMOOTH

    'bluish light
    _glLightfv _GL_LIGHT0, _GL_AMBIENT, glVec4(0.05, 0.05, 0.1, 0)
    _glLightfv _GL_LIGHT0, _GL_DIFFUSE, glVec4(0.95, 0.95, 1, 0)
    _glLightfv _GL_LIGHT0, _GL_SPECULAR, glVec4(0.6, 0.6, 0.6, 0) ' glVec4(0.75, 0.80, 0.85, 0)


    _glMatrixMode _GL_PROJECTION
    _glLoadIdentity
    _gluPerspective 60, 1.3333, 0.1, 50


    _glMatrixMode _GL_MODELVIEW
    _glLoadIdentity
    gluLookAt 8, 10, 8, 0, 5, 0, 0, 1, 0
    _glRotatef clock, 0, 1, 0

    'land
    _glColor3f 1, 1, 1
    _glEnable _GL_COLOR_MATERIAL
    _glEnableClientState _GL_VERTEX_ARRAY
    _glVertexPointer 3, _GL_FLOAT, 0, _OFFSET(map_vert())
    _glEnableClientState _GL_NORMAL_ARRAY
    _glNormalPointer _GL_FLOAT, 0, _OFFSET(map_norm())

    _glDrawArrays _GL_TRIANGLE_STRIP, 1, (max_vert_index / 3) - 1
    'tree
    _glDisable _GL_COLOR_MATERIAL
    _glPushMatrix
    _glTranslatef 0, ABS(h_map(50, 50).y + 1), 0
    objDraw pineMesh(), pineMeshInfo(), pineMeshFileInfo
    _glPopMatrix


    'snow
    _glDisable _GL_LIGHTING
    _glPointSize 8.0
    _glColor3f 1, 1, 1
    _glEnable _GL_COLOR_MATERIAL
    _glEnableClientState _GL_VERTEX_ARRAY
    _glVertexPointer 3, _GL_FLOAT, 24, _OFFSET(snow())
    _glDrawArrays _GL_POINTS, 1, UBOUND(snow)
    _glFlush
    clock = clock + 0.5
END SUB

SUB init_land ()
    DIM A AS vec3, B AS vec3, C AS vec3, R AS vec3
    max_vert_index = 0
    DO
        IF z MOD 2 = 0 THEN x = x + 1 ELSE x = x - 1

        A = h_map(x, z) 'get out coordinates from our stored data
        B = h_map(x, z + 1)
        C = h_map(x + 1, z)

        OBJ_CalculateNormal A, B, C, R 'calculates the normal of a triangle

        'store color, coordinate & normal data in an array
        map_norm(max_vert_index) = R.x: map_norm(max_vert_index + 1) = R.y: map_norm(max_vert_index + 2) = R.z
        map_vert(max_vert_index) = A.x: map_vert(max_vert_index + 1) = A.y: map_vert(max_vert_index + 2) = A.z

        map_norm(max_vert_index + 3) = R.x: map_norm(max_vert_index + 4) = R.y: map_norm(max_vert_index + 5) = R.z
        map_vert(max_vert_index + 3) = B.x: map_vert(max_vert_index + 4) = B.y: map_vert(max_vert_index + 5) = B.z

        max_vert_index = max_vert_index + 6

        IF x = max_w - 1 THEN
            IF z MOD 2 = 0 THEN x = x + 1: z = z + 1
        END IF
        IF x = 1 THEN
            IF z MOD 2 = 1 THEN x = x - 1: z = z + 1
        END IF
        IF z = max_h - 1 THEN EXIT DO
    LOOP
END SUB

SUB OBJ_CalculateNormal (p1 AS vec3, p2 AS vec3, p3 AS vec3, N AS vec3)
    DIM U AS vec3, V AS vec3

    U.x = p2.x - p1.x
    U.y = p2.y - p1.y
    U.z = p2.z - p1.z

    V.x = p3.x - p1.x
    V.y = p3.y - p1.y
    V.z = p3.z - p1.z

    N.x = (U.y * V.z) - (U.z * V.y)
    N.y = (U.z * V.x) - (U.x * V.z)
    N.z = (U.x * V.y) - (U.y * V.x)
    OBJ_Normalize N
END SUB

SUB OBJ_Normalize (V AS vec3)
    mag! = SQR(V.x * V.x + V.y * V.y + V.z * V.z)
    V.x = V.x / mag!
    V.y = V.y / mag!
    V.z = V.z / mag!
END SUB

'>>>>>>>>>>>> p5js.bas CONTENT START >>>>>>>>>>>>>>>>>>>>>>>>>>>
FUNCTION map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!)
    map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
END FUNCTION

FUNCTION p5random! (mn!, mx!)
    IF mn! > mx! THEN
        SWAP mn!, mx!
    END IF
    p5random! = RND * (mx! - mn!) + mn!
END FUNCTION

FUNCTION noise! (x AS SINGLE, y AS SINGLE, z AS SINGLE)
    STATIC p5NoiseSetup AS _BYTE
    STATIC perlin() AS SINGLE
    STATIC PERLIN_YWRAPB AS SINGLE, PERLIN_YWRAP AS SINGLE
    STATIC PERLIN_ZWRAPB AS SINGLE, PERLIN_ZWRAP AS SINGLE
    STATIC PERLIN_SIZE AS SINGLE

    IF NOT p5NoiseSetup THEN
        p5NoiseSetup = -1

        PERLIN_YWRAPB = 4
        PERLIN_YWRAP = INT(1 * (2 ^ PERLIN_YWRAPB))
        PERLIN_ZWRAPB = 8
        PERLIN_ZWRAP = INT(1 * (2 ^ PERLIN_ZWRAPB))
        PERLIN_SIZE = 4095

        perlin_octaves = 4
        perlin_amp_falloff = 0.5

        REDIM perlin(PERLIN_SIZE + 1) AS SINGLE
        DIM i AS SINGLE
        FOR i = 0 TO PERLIN_SIZE + 1
            perlin(i) = RND
        NEXT
    END IF

    x = ABS(x)
    y = ABS(y)
    z = ABS(z)

    DIM xi AS SINGLE, yi AS SINGLE, zi AS SINGLE
    xi = INT(x)
    yi = INT(y)
    zi = INT(z)

    DIM xf AS SINGLE, yf AS SINGLE, zf AS SINGLE
    xf = x - xi
    yf = y - yi
    zf = z - zi

    DIM r AS SINGLE, ampl AS SINGLE, o AS SINGLE
    r = 0
    ampl = .5

    FOR o = 1 TO perlin_octaves
        DIM of AS SINGLE, rxf AS SINGLE
        DIM ryf AS SINGLE, n1 AS SINGLE, n2 AS SINGLE, n3 AS SINGLE
        of = xi + INT(yi * (2 ^ PERLIN_YWRAPB)) + INT(zi * (2 ^ PERLIN_ZWRAPB))

        rxf = 0.5 * (1.0 - COS(xf * _PI))
        ryf = 0.5 * (1.0 - COS(yf * _PI))

        n1 = perlin(of AND PERLIN_SIZE)
        n1 = n1 + rxf * (perlin((of + 1) AND PERLIN_SIZE) - n1)
        n2 = perlin((of + PERLIN_YWRAP) AND PERLIN_SIZE)
        n2 = n2 + rxf * (perlin((of + PERLIN_YWRAP + 1) AND PERLIN_SIZE) - n2)
        n1 = n1 + ryf * (n2 - n1)

        of = of + PERLIN_ZWRAP
        n2 = perlin(of AND PERLIN_SIZE)
        n2 = n2 + rxf * (perlin((of + 1) AND PERLIN_SIZE) - n2)
        n3 = perlin((of + PERLIN_YWRAP) AND PERLIN_SIZE)
        n3 = n3 + rxf * (perlin((of + PERLIN_YWRAP + 1) AND PERLIN_SIZE) - n3)
        n2 = n2 + ryf * (n3 - n2)

        n1 = n1 + (0.5 * (1.0 - COS(zf * _PI))) * (n2 - n1)

        r = r + n1 * ampl
        ampl = ampl * perlin_amp_falloff
        xi = INT(xi * (2 ^ 1))
        xf = xf * 2
        yi = INT(yi * (2 ^ 1))
        yf = yf * 2
        zi = INT(zi * (2 ^ 1))
        zf = zf * 2

        IF xf >= 1.0 THEN xi = xi + 1: xf = xf - 1
        IF yf >= 1.0 THEN yi = yi + 1: yf = yf - 1
        IF zf >= 1.0 THEN zi = zi + 1: zf = zf - 1
    NEXT
    noise! = r
END FUNCTION

SUB noiseDetail (lod!, falloff!)
    IF lod! > 0 THEN perlin_octaves = lod!
    IF falloff! > 0 THEN perlin_amp_falloff = falloff!
END SUB

'>>>>>>>>>>>>> p5js.bas CONTENT END >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

'->>>>>>> OBJ_LOADER_LIB.BAS CONTENT START>>>>>>>>>>>>>>

'An LIBRARY version of OBJ Loader
'Contain useful Functions/methods for your making your 3D Apps/Games

SUB internal_OBJ_types ()
    TYPE MDL_INFO
        num_of_vertices AS _UNSIGNED LONG
        num_of_normals AS _UNSIGNED LONG
        num_of_tex_coords AS _UNSIGNED LONG
        num_of_objects AS _UNSIGNED LONG
        num_of_faces AS _UNSIGNED LONG
        num_of_materials AS _UNSIGNED LONG
        materialPresent AS _BYTE
        mode AS INTEGER
    END TYPE


    TYPE material_info
        exits AS _BYTE 'material exits or not
        init AS _BYTE
        id AS STRING * 128 'material name
        amb AS vec3 'ambient
        diff AS vec3 'diffuse
        spec AS vec3 'specular
        emis AS vec3 'emission
        img_tex_name AS STRING * 128 'name of the image texture file name
        img_tex AS LONG 'image handle
        gl_tex AS LONG 'GL tex handle
        shine AS SINGLE 'shineness
        trans AS SINGLE 'transparency
    END TYPE

    TYPE mesh_part_info
        start AS _UNSIGNED LONG 'start index of mesh()
        length AS _UNSIGNED LONG 'length
        init AS _BYTE 'intialize?
        mtl AS material_info 'material properties
        origin AS vec3 'origin of each mesh_part
        atOrigin AS _BYTE 'is it at the origin
        hidden AS _BYTE 'if hidden, it will not render when calling with objDraw(). However, it can be made render by objDrawMeshPart()
    END TYPE

END SUB

SUB objHideMeshPart (which$, mesh_part() AS mesh_part_info)
    FOR i = 0 TO UBOUND(mesh_part)
        IF _TRIM$(mesh_part(i).mtl.id) = which$ THEN
            mesh_part(i).hidden = -1
            EXIT SUB
        END IF
    NEXT
END SUB

SUB objUnhideMeshPart (which$, mesh_part() AS mesh_part_info)
    FOR i = 0 TO UBOUND(mesh_part)
        IF _TRIM$(mesh_part(i).mtl.id) = which$ THEN
            mesh_part(i).hidden = 0
            EXIT SUB
        END IF
    NEXT
END SUB

SUB setMeshPartOrigin (which$, mesh_part() AS mesh_part_info, mesh() AS SINGLE)
    FOR i = 0 TO UBOUND(mesh_part)
        IF _TRIM$(mesh_part(i).mtl.id) = which$ THEN
            IF NOT mesh_part(i).atOrigin THEN
                FOR j = 8 * mesh_part(i).start TO 8 * (mesh_part(i).start + mesh_part(i).length - 1) STEP 8
                    mesh(j) = mesh(j) - mesh_part(i).origin.x
                    mesh(j + 1) = mesh(j + 1) - mesh_part(i).origin.y
                    mesh(j + 2) = mesh(j + 2) - mesh_part(i).origin.z
                NEXT
                mesh_part(i).atOrigin = -1
            END IF
            _glTranslatef mesh_part(i).origin.x, mesh_part(i).origin.y, mesh_part(i).origin.z
            ' ? mesh_part(i).origin.x,mesh_part(i).origin.y,mesh_part(i).origin.z
            EXIT SUB
        END IF
    NEXT
END SUB

SUB resetMeshPartOrigin (which$, mesh_part() AS mesh_part_info, mesh() AS SINGLE)
    FOR i = 0 TO UBOUND(mesh_part)
        IF _TRIM$(mesh_part(i).mtl.id) = which$ THEN
            IF mesh_part(i).atOrigin THEN
                FOR j = 8 * mesh_part(i).start TO 8 * (mesh_part(i).start + mesh_part(i).length - 1) STEP 8
                    mesh(j) = mesh(j) + mesh_part(i).origin.x
                    mesh(j + 1) = mesh(j + 1) + mesh_part(i).origin.y
                    mesh(j + 2) = mesh(j + 2) + mesh_part(i).origin.z
                NEXT
                mesh_part(i).atOrigin = 0
            END IF
            EXIT SUB
        END IF
    NEXT
END SUB

SUB objImportBin (inFile$, mesh() AS SINGLE, mesh_part() AS mesh_part_info, mdl_info AS MDL_INFO)
    REDIM mesh(0) AS SINGLE, mesh_part(0) AS mesh_part_info
    x = _INSTRREV(inFile$, "/") + _INSTRREV(inFile$, "\")
    DIM path$, count AS _UNSIGNED LONG
    path$ = LEFT$(inFile$, x)

    f = FREEFILE

    OPEN inFile$ FOR BINARY AS #f
    GET #f, , mdl_info
    GET #f, , count
    REDIM mesh_part(count) AS mesh_part_info
    GET #f, , mesh_part()
    GET #f, , count
    REDIM mesh(count) AS SINGLE
    GET #f, , mesh()
    CLOSE #f

    FOR i = 0 TO UBOUND(mesh_part)
        mesh_part(i).mtl.img_tex = 0
        mesh_part(i).mtl.gl_tex = 0
        mesh_part(i).mtl.img_tex = _LOADIMAGE(path$ + _TRIM$(mesh_part(i).mtl.img_tex_name))
    NEXT
END SUB

SUB objExportBin (outFile$, mesh() AS SINGLE, mesh_part() AS mesh_part_info, mdl_info AS MDL_INFO)
    IF _FILEEXISTS(outFile$) THEN KILL outFile$
    DIM count AS _UNSIGNED LONG, mn AS vec3, mx AS vec3

    'just to calculate origin of each mesh part by simple the mean of their max & min position vector
    FOR i = 0 TO UBOUND(mesh_part)
        ' ? "ID : ";_TRIM$(mesh_part(i).mtl.id)
        count = 8 * mesh_part(i).start
        mn.x = mesh(count): mn.y = mesh(count + 1): mn.z = mesh(count + 2)
        mx.x = mesh(count): mx.y = mesh(count + 1): mx.z = mesh(count + 2)
        ' ? "Max : (";mx.x;",";mx.y;",";mx.z;")"
        ' ? "Min : (";mn.x;",";mn.y;",";mn.z;")"
        FOR j = count TO count + 8 * (mesh_part(i).length - 1) STEP 8
            IF mn.x >= mesh(j) THEN mn.x = mesh(j)
            IF mn.y >= mesh(j + 1) THEN mn.y = mesh(j + 1)
            IF mn.z >= mesh(j + 2) THEN mn.z = mesh(j + 2)

            IF mx.x <= mesh(j) THEN mx.x = mesh(j)
            IF mx.y <= mesh(j + 1) THEN mx.y = mesh(j + 1)
            IF mx.z <= mesh(j + 2) THEN mx.z = mesh(j + 2)
        NEXT
        ' ? "Max : (";mx.x;",";mx.y;",";mx.z;")"
        ' ? "Min : (";mn.x;",";mn.y;",";mn.z;")"
        ' sleep
        mesh_part(i).origin.x = (mn.x + mx.x) * 0.5
        mesh_part(i).origin.y = (mn.y + mx.y) * 0.5
        mesh_part(i).origin.z = (mn.z + mx.z) * 0.5

    NEXT

    f = FREEFILE
    OPEN outFile$ FOR BINARY AS #f
    PUT #f, , mdl_info 'MODEL GENERAL INFO
    count = UBOUND(mesh_part) 'length of mesh_part() array
    PUT #f, , count
    PUT #f, , mesh_part()
    count = UBOUND(mesh) 'length of mesh() array
    PUT #f, , count
    PUT #f, , mesh()
    CLOSE #f
END SUB

SUB objInit (mesh_part() AS mesh_part_info)
    FOR i = 0 TO UBOUND(mesh_part)
        IF mesh_part(i).mtl.img_tex < -1 THEN mesh_part(i).mtl.gl_tex = feedGLTexture(mesh_part(i).mtl.img_tex)
    NEXT
END SUB

SUB objDrawMeshPart (which$, mesh() AS SINGLE, mesh_part() AS mesh_part_info, mdl_info AS MDL_INFO)
    FOR i = 0 TO UBOUND(mesh_part)
        IF which$ = _TRIM$(mesh_part(i).mtl.id) THEN
            IF mesh_part(i).mtl.trans = 1 THEN _glDisable _GL_BLEND ELSE _glEnable _GL_BLEND
            _glMaterialfv _GL_FRONT, _GL_AMBIENT, glVec4(mesh_part(i).mtl.amb.x, mesh_part(i).mtl.amb.y, mesh_part(i).mtl.amb.z, mesh_part(i).mtl.trans)
            _glMaterialfv _GL_FRONT, _GL_DIFFUSE, glVec4(mesh_part(i).mtl.diff.x, mesh_part(i).mtl.diff.y, mesh_part(i).mtl.diff.z, mesh_part(i).mtl.trans)
            _glMaterialfv _GL_FRONT, _GL_SPECULAR, glVec4(mesh_part(i).mtl.spec.x, mesh_part(i).mtl.spec.y, mesh_part(i).mtl.spec.z, mesh_part(i).mtl.trans)
            _glMaterialfv _GL_FRONT, _GL_EMISSION, glVec4(mesh_part(i).mtl.emis.x, mesh_part(i).mtl.emis.y, mesh_part(i).mtl.emis.z, mesh_part(i).mtl.trans)
            _glMaterialfv _GL_FRONT, _GL_SHININESS, glVec4(mesh_part(i).mtl.shine * 0.128, 0, 0, 0)
            _glEnableClientState _GL_VERTEX_ARRAY
            _glVertexPointer 3, _GL_FLOAT, 32, _OFFSET(mesh()) + 32 * mesh_part(i).start
            IF mdl_info.num_of_tex_coords > 0 THEN
                selectTexture mesh_part(i).mtl.gl_tex
                _glEnableClientState _GL_TEXTURE_COORD_ARRAY
                _glTexCoordPointer 3, _GL_FLOAT, 32, _OFFSET(mesh()) + 12 + 32 * mesh_part(i).start
            END IF
            IF mdl_info.num_of_normals > 0 THEN
                _glEnableClientState _GL_NORMAL_ARRAY
                _glNormalPointer _GL_FLOAT, 32, _OFFSET(mesh()) + 20 + 32 * mesh_part(i).start
            END IF
            IF mdl_info.mode = 1 THEN _glDrawArrays _GL_TRIANGLES, 0, mesh_part(i).length
            IF mdl_info.mode = 2 THEN _glDrawArrays _GL_LINES, 0, mesh_part(i).length

            EXIT SUB
        END IF
    NEXT
    _glDisableClientState _GL_VERTEX_ARRAY
    _glDisableClientState _GL_NORMAL_ARRAY
    _glDisableClientState _GL_TEXTURE_COORD_ARRAY
END SUB
SUB objDraw (mesh() AS SINGLE, mesh_part() AS mesh_part_info, mdl_info AS MDL_INFO)
    FOR i = 0 TO UBOUND(mesh_part) 'draw the mesh
        IF mesh_part(i).hidden THEN _CONTINUE 'no need to draw the hidden/unactive part (if there)
        IF mdl_info.materialPresent = 1 THEN
            IF mesh_part(i).mtl.trans = 1 THEN _glDisable _GL_BLEND ELSE _glEnable _GL_BLEND
            _glMaterialfv _GL_FRONT, _GL_AMBIENT, glVec4(mesh_part(i).mtl.amb.x, mesh_part(i).mtl.amb.y, mesh_part(i).mtl.amb.z, mesh_part(i).mtl.trans)
            _glMaterialfv _GL_FRONT, _GL_DIFFUSE, glVec4(mesh_part(i).mtl.diff.x, mesh_part(i).mtl.diff.y, mesh_part(i).mtl.diff.z, mesh_part(i).mtl.trans)
            _glMaterialfv _GL_FRONT, _GL_SPECULAR, glVec4(mesh_part(i).mtl.spec.x, mesh_part(i).mtl.spec.y, mesh_part(i).mtl.spec.z, mesh_part(i).mtl.trans)
            _glMaterialfv _GL_FRONT, _GL_EMISSION, glVec4(mesh_part(i).mtl.emis.x, mesh_part(i).mtl.emis.y, mesh_part(i).mtl.emis.z, mesh_part(i).mtl.trans)
            _glMaterialfv _GL_FRONT, _GL_SHININESS, glVec4(mesh_part(i).mtl.shine * 0.128, 0, 0, 0)
        END IF
        _glEnableClientState _GL_VERTEX_ARRAY
        _glVertexPointer 3, _GL_FLOAT, 32, _OFFSET(mesh()) + 32 * mesh_part(i).start
        IF mdl_info.num_of_tex_coords > 0 THEN
            selectTexture mesh_part(i).mtl.gl_tex
            _glEnableClientState _GL_TEXTURE_COORD_ARRAY
            _glTexCoordPointer 3, _GL_FLOAT, 32, _OFFSET(mesh()) + 12 + 32 * mesh_part(i).start
        END IF
        IF mdl_info.num_of_normals > 0 THEN
            _glEnableClientState _GL_NORMAL_ARRAY
            _glNormalPointer _GL_FLOAT, 32, _OFFSET(mesh()) + 20 + 32 * mesh_part(i).start
        END IF
        IF mdl_info.mode = 1 THEN _glDrawArrays _GL_TRIANGLES, 0, mesh_part(i).length
        IF mdl_info.mode = 2 THEN _glDrawArrays _GL_LINES, 0, mesh_part(i).length
    NEXT
    _glDisableClientState _GL_VERTEX_ARRAY
    _glDisableClientState _GL_NORMAL_ARRAY
    _glDisableClientState _GL_TEXTURE_COORD_ARRAY
END SUB

SUB objLoad (f$, mesh() AS SINGLE, mesh_part() AS mesh_part_info, mdl_info AS MDL_INFO)
    'seprate file name and path
    x = _INSTRREV(f$, "/") + _INSTRREV(f$, "\")
    IF x = 0 THEN
        obj_file$ = f$
    ELSE
        obj_file$ = RIGHT$(f$, LEN(f$) - x)
        path$ = LEFT$(f$, x)
    END IF

    DIM tag(4) AS STRING * 3, p(4) AS _UNSIGNED LONG 'tag() contain keywords like v, vt, etc. p() store the position for each keywords independently
    DIM v(4) AS _UNSIGNED LONG 'v(0) -> no. of vertices, v(1)->no. of tex. coord.,v(2)->no. of normals, v(3)->no. of faces
    REDIM vert(2) AS SINGLE, norm(2) AS SINGLE, texcoord(1) AS SINGLE 'vert(), norm() and texcoord() will store all the vertices, normals and texture coordinates()
    REDIM mesh(23) AS SINGLE '(3 vert + 2 tex coord + 3 norm )* 3 vert of triangle : This is the main data which we will pass to OpenGL
    REDIM materials(0) AS material_info, mesh_part(0) AS mesh_part_info 'contain properties of mesh like materials
    DIM materialPresent

    tag(0) = CHR$(10) + "v ": tag(1) = CHR$(10) + "vt": tag(2) = CHR$(10) + "vn": tag(3) = CHR$(10) + "f ": tag(4) = CHR$(10) + "o "
    DIM LINE_FEED AS STRING * 1
    LINE_FEED = CHR$(10)
    OPEN f$ FOR BINARY AS #1
    length = LOF(1)
    a$ = SPACE$(length)
    GET #1, , a$
    CLOSE #1

    'check if the mtl file exits for the given OBJ
    x = INSTR(1, a$, LINE_FEED + "mtllib")
    IF x THEN 'yes it exits
        FOR i = x + 8 TO LEN(a$)
            IF MID$(a$, i, 1) = CHR$(13) OR MID$(a$, i, 1) = LINE_FEED THEN y = i: EXIT FOR
        NEXT
        mtl_file$ = path$ + _TRIM$(MID$(a$, x + 8, y - (x + 8)))
        IF NOT _FILEEXISTS(mtl_file$) THEN PRINT "ERROR : File not found - " + mtl_file$: END
        x = 1
        materialPresent = 1
        mtl_index = -1 'so it start with 0 in the loop
        OPEN mtl_file$ FOR INPUT AS #2
        WHILE NOT EOF(2)
            LINE INPUT #2, b$
            IF LEFT$(b$, 1) <> "#" THEN 'to avoid comments. Comments in OBJ/MTL start with #
                IF LEFT$(b$, 6) = "newmtl" THEN 'new material
                    mtl_index = mtl_index + 1
                    REDIM _PRESERVE materials(mtl_index) AS material_info
                    materials(mtl_index).id = _TRIM$(MID$(b$, 7, LEN(b$) - 6))
                    materials(mtl_index).exits = 1
                ELSEIF LEFT$(b$, 2) = "Ka" THEN 'ambient
                    y1 = INSTR(4, b$, " ")
                    y2 = INSTR(y1 + 1, b$, " ")
                    materials(mtl_index).amb.x = VAL(MID$(b$, 4, y1 - 3))
                    materials(mtl_index).amb.y = VAL(MID$(b$, y1, y2 - y1 + 1))
                    materials(mtl_index).amb.z = VAL(RIGHT$(b$, LEN(b$) - y2 + 1))
                ELSEIF LEFT$(b$, 2) = "Kd" THEN 'diffuse
                    y1 = INSTR(4, b$, " ")
                    y2 = INSTR(y1 + 1, b$, " ")
                    materials(mtl_index).diff.x = VAL(MID$(b$, 4, y1 - 3))
                    materials(mtl_index).diff.y = VAL(MID$(b$, y1, y2 - y1 + 1))
                    materials(mtl_index).diff.z = VAL(RIGHT$(b$, LEN(b$) - y2 + 1))
                ELSEIF LEFT$(b$, 2) = "Ks" THEN 'specular
                    y1 = INSTR(4, b$, " ")
                    y2 = INSTR(y1 + 1, b$, " ")
                    materials(mtl_index).spec.x = VAL(MID$(b$, 4, y1 - 3))
                    materials(mtl_index).spec.y = VAL(MID$(b$, y1, y2 - y1 + 1))
                    materials(mtl_index).spec.z = VAL(RIGHT$(b$, LEN(b$) - y2 + 1))
                ELSEIF LEFT$(b$, 2) = "Ke" THEN 'emission
                    y1 = INSTR(4, b$, " ")
                    y2 = INSTR(y1 + 1, b$, " ")
                    materials(mtl_index).emis.x = VAL(MID$(b$, 4, y1 - 3))
                    materials(mtl_index).emis.y = VAL(MID$(b$, y1, y2 - y1 + 1))
                    materials(mtl_index).emis.z = VAL(RIGHT$(b$, LEN(b$) - y2 + 1))
                ELSEIF LEFT$(b$, 2) = "Ns" THEN 'shineness
                    materials(mtl_index).shine = VAL(MID$(b$, 3, LEN(b$) - 2))
                ELSEIF LEFT$(b$, 2) = "d " THEN 'transparency
                    materials(mtl_index).trans = VAL(MID$(b$, 2, LEN(b$) - 1))
                ELSEIF LEFT$(b$, 6) = "map_Kd" THEN 'texture file name
                    img_file$ = path$ + _TRIM$(MID$(b$, 7, LEN(b$) - 6))
                    materials(mtl_index).img_tex_name = _TRIM$(MID$(b$, 7, LEN(b$) - 6))
                    dummy_img& = _LOADIMAGE(img_file$)
                    IF NOT dummy_img& < -1 THEN PRINT "ERROR : Could not load the texture - " + img_file$: END
                    materials(mtl_index).img_tex = dummy_img&
                END IF
            END IF
        WEND
        CLOSE #2
    END IF

    p(0) = 1: p(1) = 1: p(2) = 1: p(3) = 1: p(4) = 1
    'get position of first mention of material to be used
    mtl_first = INSTR(1, a$, LINE_FEED + "usemtl"): mtl_second = INSTR(mtl_first + 1, a$, LINE_FEED + "usemtl")
    mtl_id$ = _TRIM$(MID$(a$, mtl_first + 8, INSTR(mtl_first + 8, a$, LINE_FEED) - (mtl_first + 8)))
    FOR j = 0 TO UBOUND(materials)
        IF RTRIM$(materials(j).id) = mtl_id$ THEN mtl_index = j: EXIT FOR
    NEXT
    'This is the main loop of reading the file. It does all the things which is required.
    DO
        x = INSTR(p(c), a$, tag(c))
        IF x > 0 THEN
            v(c) = v(c) + 1
            IF c = 0 THEN 'store vertices
                y1 = INSTR(x + 3, a$, " ")
                y2 = INSTR(y1 + 1, a$, " ")
                y3 = INSTR(y2 + 1, a$, LINE_FEED)
                vert(v_index) = VAL(MID$(a$, x + 3, y1 - (x + 3)))
                vert(v_index + 1) = VAL(MID$(a$, y1, y2 - y1))
                vert(v_index + 2) = VAL(MID$(a$, y2, y3 - y2))
                v_index = v_index + 3
                REDIM _PRESERVE vert(UBOUND(vert) + 3) AS SINGLE
            ELSEIF c = 1 THEN 'store tex coord.
                y1 = INSTR(x + 4, a$, " ")
                y2 = INSTR(y1 + 1, a$, LINE_FEED)
                texcoord(vt_index) = VAL(MID$(a$, x + 4, y1 - (x + 4)))
                texcoord(vt_index + 1) = -VAL(MID$(a$, y1, y2 - y1))
                vt_index = vt_index + 2
                REDIM _PRESERVE texcoord(UBOUND(texcoord) + 2) AS SINGLE
            ELSEIF c = 2 THEN 'store normals
                y1 = INSTR(x + 4, a$, " ")
                y2 = INSTR(y1 + 1, a$, " ")
                y3 = INSTR(y2 + 1, a$, LINE_FEED)
                norm(vn_index) = VAL(MID$(a$, x + 4, y1 - (x + 4)))
                norm(vn_index + 1) = VAL(MID$(a$, y1, y2 - y1))
                norm(vn_index + 2) = VAL(MID$(a$, y2, y3 - y2))
                vn_index = vn_index + 3
                REDIM _PRESERVE norm(UBOUND(norm) + 3) AS SINGLE
            ELSEIF c = 3 THEN 'face part
                'check if there is new material to be used for face. If not then array length for current mesh_info() increases
                check_for_obj:
                IF x > mtl_first AND x < mtl_second OR mtl_second = 0 THEN
                    IF mesh_part(mp_index).init = 0 THEN mesh_part(mp_index).init = 1: mesh_part(mp_index).start = m_index / 8: mesh_part(mp_index).mtl = materials(mtl_index)
                    mesh_part(mp_index).length = mesh_part(mp_index).length + 3 '3 vertex in a face
                ELSE
                    mtl_first = mtl_second
                    mtl_second = INSTR(mtl_first + 1, a$, LINE_FEED + "usemtl")
                    mtl_id$ = _TRIM$(MID$(a$, mtl_first + 8, INSTR(mtl_first + 8, a$, LINE_FEED) - (mtl_first + 8)))
                    FOR j = 0 TO UBOUND(materials)
                        IF RTRIM$(materials(j).id) = mtl_id$ THEN mtl_index = j: EXIT FOR
                    NEXT
                    mp_index = mp_index + 1
                    REDIM _PRESERVE mesh_part(mp_index) AS mesh_part_info
                    GOTO check_for_obj
                END IF
                'reading of face data comes heer
                spc_1 = x + 2: spc_2 = INSTR(spc_1 + 1, a$, " ")
                y_max = INSTR(x + 1, a$, LINE_FEED)

                n = -1 'so start with 0 in while loop
                'get the each vertex info block which are sperated by space
                REDIM dat(0) AS STRING
                WHILE 1 'spc_2<y_max
                    n = n + 1
                    REDIM _PRESERVE dat(n) AS STRING
                    IF spc_2 >= y_max OR spc_2 < spc_1 THEN
                        dat(n) = MID$(a$, spc_1 + 1, y_max - (spc_1 + 1))
                        EXIT WHILE
                    ELSE
                        dat(n) = MID$(a$, spc_1 + 1, spc_2 - (spc_1 + 1))
                    END IF
                    SWAP spc_1, spc_2
                    spc_2 = INSTR(spc_1 + 1, a$, " ")
                WEND

                REDIM z_ref(n, 1) AS INTEGER
                'get ref info for v,vt,vn
                FOR i = 0 TO n
                    z_ref(i, 0) = INSTR(1, dat(i), "/")
                    z_ref(i, 1) = _INSTRREV(dat(i), "/")
                NEXT

                IF z_ref(0, 0) = 0 THEN 'only v data given
                    IF (n + 1) > 3 THEN 'polygon face given : So, subdivide the polygon in minimum no. of triangles
                        v_r1 = (VAL(dat(0)) - 1) * 3
                        FOR i = 3 TO (n + 1)
                            v_r2 = (VAL(dat(i - 2)) - 1) * 3
                            v_r3 = (VAL(dat(i - 1)) - 1) * 3
                            mesh(m_index) = vert(v_r1): mesh(m_index + 1) = vert(v_r1 + 1): mesh(m_index + 2) = vert(v_r1 + 2)
                            m_index = m_index + 8
                            mesh(m_index) = vert(v_r2): mesh(m_index + 1) = vert(v_r2 + 1): mesh(m_index + 2) = vert(v_r2 + 2)
                            m_index = m_index + 8
                            mesh(m_index) = vert(v_r3): mesh(m_index + 1) = vert(v_r3 + 1): mesh(m_index + 2) = vert(v_r3 + 2)
                            m_index = m_index + 8
                            REDIM _PRESERVE mesh(UBOUND(mesh) + 24) AS SINGLE
                        NEXT
                        'add additional new vertices
                        mesh_part(mp_index).length = mesh_part(mp_index).length + 3 * (n - 2) '3*(X - 2) - 3 => 3*(X - 3), now here X = n+1, so, 3*(n-2)
                    ELSE 'simply a triangle face
                        FOR j = 0 TO 2
                            v_r1 = (VAL(dat(j)) - 1) * 3
                            mesh(m_index) = vert(v_r1): mesh(m_index + 1) = vert(v_r1 + 1): mesh(m_index + 2) = vert(v_r1 + 2)
                            m_index = m_index + 8
                        NEXT
                        REDIM _PRESERVE mesh(UBOUND(mesh) + 24) AS SINGLE
                    END IF
                ELSEIF z_ref(0, 1) - z_ref(0, 0) = 1 THEN 'only v and vn data given
                    IF (n + 1) > 3 THEN
                        v_r1 = (VAL(LEFT$(dat(0), z_ref(0, 0))) - 1) * 3
                        vn_r1 = (VAL(RIGHT$(dat(0), LEN(dat(0)) - z_ref(0, 1))) - 1) * 3
                        FOR i = 3 TO (n + 1)
                            v_r2 = (VAL(LEFT$(dat(i - 2), z_ref(i - 2, 0))) - 1) * 3: vn_r2 = (VAL(RIGHT$(dat(i - 2), LEN(dat(i - 2)) - z_ref((i - 2), 1))) - 1) * 3
                            v_r3 = (VAL(LEFT$(dat(i - 1), z_ref(i - 1, 0))) - 1) * 3: vn_r3 = (VAL(RIGHT$(dat(i - 1), LEN(dat(i - 1)) - z_ref((i - 1), 1))) - 1) * 3

                            mesh(m_index) = vert(v_r1): mesh(m_index + 1) = vert(v_r1 + 1): mesh(m_index + 2) = vert(v_r1 + 2)
                            mesh(m_index + 5) = norm(vn_r1): mesh(m_index + 6) = norm(vn_r1 + 1): mesh(m_index + 7) = norm(vn_r1 + 2)
                            m_index = m_index + 8
                            mesh(m_index) = vert(v_r2): mesh(m_index + 1) = vert(v_r2 + 1): mesh(m_index + 2) = vert(v_r2 + 2)
                            mesh(m_index + 5) = norm(vn_r2): mesh(m_index + 6) = norm(vn_r2 + 1): mesh(m_index + 7) = norm(vn_r2 + 2)
                            m_index = m_index + 8
                            mesh(m_index) = vert(v_r3): mesh(m_index + 1) = vert(v_r3 + 1): mesh(m_index + 2) = vert(v_r3 + 2)
                            mesh(m_index + 5) = norm(vn_r3): mesh(m_index + 6) = norm(vn_r3 + 1): mesh(m_index + 7) = norm(vn_r3 + 2)
                            m_index = m_index + 8
                            REDIM _PRESERVE mesh(UBOUND(mesh) + 24) AS SINGLE
                        NEXT
                        'add additional new vertices
                        mesh_part(mp_index).length = mesh_part(mp_index).length + 3 * (n - 2) '3*(X - 2) - 3 => 3*(X - 3), now here X = n+1, so, 3*(n-2)
                    ELSE
                        FOR j = 0 TO 2
                            v_r1 = (VAL(LEFT$(dat(j), z_ref(j, 0) - 1)) - 1) * 3: vn_r1 = (VAL(RIGHT$(dat(j), LEN(dat(j)) - z_ref(j, 1))) - 1) * 3
                            'v
                            mesh(m_index) = vert(v_r1): mesh(m_index + 1) = vert(v_r1 + 1): mesh(m_index + 2) = vert(v_r1 + 2)
                            'vn
                            mesh(m_index + 5) = norm(vn_r1): mesh(m_index + 6) = norm(vn_r1 + 1): mesh(m_index + 7) = norm(vn_r1 + 2)
                            m_index = m_index + 8
                        NEXT
                        REDIM _PRESERVE mesh(UBOUND(mesh) + 24) AS SINGLE
                    END IF
                ELSE 'v, vn and vt data given
                    IF (n + 1) > 3 THEN
                        'reference for first vertex of a polygon
                        v_r1 = (VAL(LEFT$(dat(0), z_ref(0, 0))) - 1) * 3
                        vn_r1 = (VAL(RIGHT$(dat(0), LEN(dat(0)) - z_ref(0, 1))) - 1) * 3
                        vt_r1 = (VAL(MID$(dat(0), z_ref(0, 0) + 1, z_ref(0, 1) - (z_ref(0, 0) + 1))) - 1) * 2
                        FOR i = 3 TO (n + 1)
                            v_r2 = (VAL(LEFT$(dat(i - 2), z_ref(i - 2, 0))) - 1) * 3: vn_r2 = (VAL(RIGHT$(dat(i - 2), LEN(dat(i - 2)) - z_ref((i - 2), 1))) - 1) * 3: vt_r2 = (VAL(MID$(dat(i - 2), z_ref(i - 2, 0) + 1, z_ref(i - 2, 1) - (z_ref(i - 2, 0) + 1))) - 1) * 2
                            v_r3 = (VAL(LEFT$(dat(i - 1), z_ref(i - 1, 0))) - 1) * 3: vn_r3 = (VAL(RIGHT$(dat(i - 1), LEN(dat(i - 1)) - z_ref((i - 1), 1))) - 1) * 3: vt_r3 = (VAL(MID$(dat(i - 1), z_ref(i - 1, 0) + 1, z_ref(i - 1, 1) - (z_ref(i - 1, 0) + 1))) - 1) * 2
                            mesh(m_index) = vert(v_r1): mesh(m_index + 1) = vert(v_r1 + 1): mesh(m_index + 2) = vert(v_r1 + 2)
                            mesh(m_index + 3) = texcoord(vt_r1): mesh(m_index + 4) = texcoord(vt_r1 + 1)
                            mesh(m_index + 5) = norm(vn_r1): mesh(m_index + 6) = norm(vn_r1 + 1): mesh(m_index + 7) = norm(vn_r1 + 2)
                            m_index = m_index + 8
                            mesh(m_index) = vert(v_r2): mesh(m_index + 1) = vert(v_r2 + 1): mesh(m_index + 2) = vert(v_r2 + 2)
                            mesh(m_index + 3) = texcoord(vt_r2): mesh(m_index + 4) = texcoord(vt_r2 + 1)
                            mesh(m_index + 5) = norm(vn_r2): mesh(m_index + 6) = norm(vn_r2 + 1): mesh(m_index + 7) = norm(vn_r2 + 2)
                            m_index = m_index + 8
                            mesh(m_index) = vert(v_r3): mesh(m_index + 1) = vert(v_r3 + 1): mesh(m_index + 2) = vert(v_r3 + 2)
                            mesh(m_index + 3) = texcoord(vt_r3): mesh(m_index + 4) = texcoord(vt_r3 + 1)
                            mesh(m_index + 5) = norm(vn_r3): mesh(m_index + 6) = norm(vn_r3 + 1): mesh(m_index + 7) = norm(vn_r3 + 2)
                            m_index = m_index + 8
                            REDIM _PRESERVE mesh(UBOUND(mesh) + 24) AS SINGLE
                        NEXT
                        mesh_part(mp_index).length = mesh_part(mp_index).length + 3 * (n - 2) '3*(X - 2) - 3 => 3*(X - 3), now here X = n+1, so, 3*(n-2)
                    ELSE
                        FOR j = 0 TO 2
                            v_r1 = (VAL(LEFT$(dat(j), z_ref(j, 0) - 1)) - 1) * 3: vn_r1 = (VAL(RIGHT$(dat(j), LEN(dat(j)) - z_ref(j, 1))) - 1) * 3: vt_r1 = (VAL(MID$(dat(j), z_ref(j, 0) + 1, z_ref(j, 1) - (z_ref(j, 0) + 1))) - 1) * 2
                            'v
                            mesh(m_index) = vert(v_r1): mesh(m_index + 1) = vert(v_r1 + 1): mesh(m_index + 2) = vert(v_r1 + 2)
                            'vt
                            mesh(m_index + 3) = texcoord(vt_r1): mesh(m_index + 4) = texcoord(vt_r1 + 1)
                            'vn
                            mesh(m_index + 5) = norm(vn_r1): mesh(m_index + 6) = norm(vn_r1 + 1): mesh(m_index + 7) = norm(vn_r1 + 2)
                            m_index = m_index + 8
                        NEXT
                        REDIM _PRESERVE mesh(UBOUND(mesh) + 24) AS SINGLE
                    END IF
                END IF

                ERASE dat, z_ref
            END IF
            p(c) = x + 1
        ELSE
            IF c = 4 THEN EXIT DO ELSE c = c + 1
        END IF
        x = 0
    LOOP

    mdl_info.num_of_vertices = v(0)
    mdl_info.num_of_tex_coords = v(1)
    mdl_info.num_of_normals = v(2)
    mdl_info.num_of_objects = v(4)
    mdl_info.num_of_faces = v(3)
    mdl_info.num_of_materials = UBOUND(materials) + 1
    mdl_info.materialPresent = materialPresent
    mdl_info.mode = 1
    ERASE vert, norm, texcoord 'not require now. So save memory whenever possible.
    a$ = ""
END SUB

'################# Internal Functions ##################################

FUNCTION feedGLTexture& (img AS LONG)
    IF img < -1 THEN
        DIM m AS _MEM
        m = _MEMIMAGE(img)

        _glGenTextures 1, _OFFSET(feedGLTexture&)
        _glBindTexture _GL_TEXTURE_2D, feedGLTexture&

        _glTexImage2D _GL_TEXTURE_2D, 0, _GL_RGBA, _WIDTH(img&), _HEIGHT(img&), 0, _GL_BGRA_EXT, _GL_UNSIGNED_BYTE, m.OFFSET

        _MEMFREE m
        _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MAG_FILTER, _GL_LINEAR
        _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MIN_FILTER, _GL_NEAREST

    ELSE
        PRINT "FUNCTION feedGlTexture&() : invalid image handle passed"
    END IF
END FUNCTION

SUB selectTexture (tex&)
    _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MAG_FILTER, _GL_LINEAR
    _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MIN_FILTER, _GL_LINEAR
    _glBindTexture _GL_TEXTURE_2D, tex&
END SUB

FUNCTION glVec4%& (x, y, z, w)
    STATIC internal_vec4(3)
    internal_vec4(0) = x
    internal_vec4(1) = y
    internal_vec4(2) = z
    internal_vec4(3) = w
    glVec4%& = _OFFSET(internal_vec4())
END FUNCTION
'>>>>>>>>>>> OBJ_LOADER_LIB.BAS CONTENT END >>>>>>>>>>>>>>>>>>>>>>>>>>>

'============================================================
'=== This file was created with MakeDATA.bas by RhoSigma, ===
'=== you must $INCLUDE this at the end of your program.   ===
'============================================================

'=====================================================================
'Function to write the embedded DATAs back to disk. Call this FUNCTION
'once, before you will access the represented file for the first time.
'After the call always use the returned realFile$ ONLY to access the
'written file, as the filename was maybe altered in order to avoid the
'overwriting of an existing file of the same name in the given location.
'---------------------------------------------------------------------
'SYNTAX: realFile$ = Writetree.basData$ (wantFile$)
'
'INPUTS: wantFile$ --> The filename you would like to write the DATAs
'                      to, can contain a full or relative path.
'
'RESULT: realFile$ --> On success the path and filename finally used
'                      after applied checks, use ONLY this returned
'                      name to access the file.
'                   -> On failure this FUNCTION will panic with the
'                      appropriate ERROR code, you may handle this as
'                      needed with your own ON ERROR GOTO... handler.
'=====================================================================
FUNCTION Writetree.basData$ (file$)
    '--- separate filename body & extension ---
    FOR po% = LEN(file$) TO 1 STEP -1
        IF MID$(file$, po%, 1) = "." THEN
            body$ = LEFT$(file$, po% - 1)
            ext$ = MID$(file$, po%)
            EXIT FOR
        ELSEIF MID$(file$, po%, 1) = "\" OR MID$(file$, po%, 1) = "/" OR po% = 1 THEN
            body$ = file$
            ext$ = ""
            EXIT FOR
        END IF
    NEXT po%
    '--- avoid overwriting of existing files ---
    num% = 1
    WHILE _FILEEXISTS(file$)
        file$ = body$ + "(" + LTRIM$(STR$(num%)) + ")" + ext$
        num% = num% + 1
    WEND
    '--- write DATAs ---
    ff% = FREEFILE
    OPEN file$ FOR OUTPUT AS ff%
    RESTORE tree.bas
    READ numL&, numB&
    FOR i& = 1 TO numL&
        READ dat&
        PRINT #ff%, MKL$(dat&);
    NEXT i&
    IF numB& > 0 THEN
        FOR i& = 1 TO numB&
            READ dat&
            PRINT #ff%, CHR$(dat&);
        NEXT i&
    END IF
    CLOSE ff%
    '--- set result ---
    Writetree.basData$ = file$
    EXIT FUNCTION

    '--- DATAs representing the contents of file tree.binobj
    '---------------------------------------------------------------------
    tree.bas:
    DATA 2056,7
    DATA &H0000002F,&H00000026,&H00000000,&H00000005,&H00000025,&H00000002,&H03000101,&H00000000
    DATA &H2A000000,&H01000000,&H614D0001,&H69726574,&H302E6C61,&H20203130,&H20202020,&H20202020
    DATA &H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020
    DATA &H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020
    DATA &H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020
    DATA &H20202020,&H20202020,&H00002020,&H00003F80,&H00003F80,&H2B563F80,&H8B593E33,&H00003F07
    DATA &H00000000,&H999A0000,&H00003F19,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H28280000,&H000042C0,&H00003F80,&H7E020000,&H000040A9,&H00000000,&H0000002A,&H0000002A
    DATA &H4D000101,&H72657461,&H2E6C6169,&H20313030,&H20202020,&H20202020,&H20202020,&H20202020
    DATA &H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020
    DATA &H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020
    DATA &H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020
    DATA &H00202020,&H003F8000,&H003F8000,&H563F8000,&H593E332B,&H003F078B,&H00000000,&H9A000000
    DATA &H003F1999,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H28000000,&H0042C028
    DATA &H003F8000,&HD5000000,&H00408258,&H00000000,&H00005400,&H00002A00,&H00010100,&H6574614D
    DATA &H6C616972,&H3130302E,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020
    DATA &H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020
    DATA &H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020
    DATA &H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H3F800000
    DATA &H3F800000,&H3F800000,&H3E332B56,&H3F078B59,&H00000000,&H00000000,&H3F19999A,&H00000000
    DATA &H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H42C02828,&H3F800000,&H00000000
    DATA &H402F8672,&H00000000,&H007E0000,&H00540000,&H01010000,&H74614D00,&H61697265,&H30302E6C
    DATA &H20202032,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020
    DATA &H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020
    DATA &H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H20202020
    DATA &H20202020,&H20202020,&H20202020,&H20202020,&H20202020,&H80000020,&H8000003F,&H8000003F
    DATA &H3A09033F,&HB0CDC83F,&H1DBCA93E,&H0000003D,&H0000003F,&H0000003F,&H00000000,&H00000000
    DATA &H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00000000,&H00000000,&H00000000,&HC0282800,&H80000042,&H0000003F,&H00000000,&H00000000
    DATA &HA7000000,&H66000006,&H36BF782E,&H00408A78,&H00000000,&H00000000,&H0B000000,&H99BF56B5
    DATA &H6A3ED6BB,&H00BEB1DE,&HCF000000,&H0040C883,&H00000000,&H00000000,&H0B000000,&H99BF56B5
    DATA &H6A3ED6BB,&H95BEB1DE,&H36BF2F7D,&H95408A78,&H00BF2F7D,&H00000000,&H0B000000,&H99BF56B5
    DATA &H6A3ED6BB,&H00BEB1DE,&H36000000,&H66408A78,&H00BF782E,&H00000000,&H6A000000,&H993EB1DE
    DATA &H0B3ED6BB,&H00BF56B5,&HCF000000,&H0040C883,&H00000000,&H00000000,&H6A000000,&H993EB1DE
    DATA &H0B3ED6BB,&H95BF56B5,&H363F2F7D,&H95408A78,&H00BF2F7D,&H00000000,&H6A000000,&H993EB1DE
    DATA &H0B3ED6BB,&H95BF56B5,&H36BF2F7D,&H95408A78,&H003F2F7D,&H00000000,&H0B000000,&H99BF56B5
    DATA &H6A3ED6BB,&H003EB1DE,&HCF000000,&H0040C883,&H00000000,&H00000000,&H0B000000,&H99BF56B5
    DATA &H6A3ED6BB,&H663EB1DE,&H36BF782E,&H00408A78,&H00000000,&H00000000,&H0B000000,&H99BF56B5
    DATA &H6A3ED6BB,&H003EB1DE,&H36000000,&H66408A78,&H003F782E,&H00000000,&H6A000000,&H99BEB1DE
    DATA &H0B3ED6BB,&H003F56B5,&HCF000000,&H0040C883,&H00000000,&H00000000,&H6A000000,&H99BEB1DE
    DATA &H0B3ED6BB,&H953F56B5,&H36BF2F7D,&H95408A78,&H003F2F7D,&H00000000,&H6A000000,&H99BEB1DE
    DATA &H0B3ED6BB,&H953F56B5,&H363F2F7D,&H95408A78,&H003F2F7D,&H00000000,&H6A000000,&H993EB1DE
    DATA &H0B3ED6BB,&H003F56B5,&HCF000000,&H0040C883,&H00000000,&H00000000,&H6A000000,&H993EB1DE
    DATA &H0B3ED6BB,&H003F56B5,&H36000000,&H66408A78,&H003F782E,&H00000000,&H6A000000,&H993EB1DE
    DATA &H0B3ED6BB,&H663F56B5,&H363F782E,&H00408A78,&H00000000,&H00000000,&H0B000000,&H993F56B5
    DATA &H6A3ED6BB,&H003EB1DE,&HCF000000,&H0040C883,&H00000000,&H00000000,&H0B000000,&H993F56B5
    DATA &H6A3ED6BB,&H953EB1DE,&H363F2F7D,&H95408A78,&H003F2F7D,&H00000000,&H0B000000,&H993F56B5
    DATA &H6A3ED6BB,&H953EB1DE,&H36BF2F7D,&H95408A78,&H00BF2F7D,&H00000000,&H6A000000,&H99BEB1DE
    DATA &H0B3ED6BB,&H00BF56B5,&HCF000000,&H0040C883,&H00000000,&H00000000,&H6A000000,&H99BEB1DE
    DATA &H0B3ED6BB,&H00BF56B5,&H36000000,&H66408A78,&H00BF782E,&H00000000,&H6A000000,&H99BEB1DE
    DATA &H0B3ED6BB,&H95BF56B5,&H363F2F7D,&H95408A78,&H00BF2F7D,&H00000000,&H0B000000,&H993F56B5
    DATA &H6A3ED6BB,&H00BEB1DE,&HCF000000,&H0040C883,&H00000000,&H00000000,&H0B000000,&H993F56B5
    DATA &H6A3ED6BB,&H66BEB1DE,&H363F782E,&H00408A78,&H00000000,&H00000000,&H0B000000,&H993F56B5
    DATA &H6A3ED6BB,&H00BEB1DE,&H36000000,&H66408A78,&H00BF782E,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H95000000,&H363F2F7D,&H95408A78,&H00BF2F7D,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H66000000,&H363F782E,&H00408A78,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&H36000000,&H66408A78,&H00BF782E,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H66000000,&H363F782E,&H00408A78,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H95000000,&H363F2F7D,&H95408A78,&H003F2F7D,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&H36000000,&H66408A78,&H00BF782E,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H95000000,&H363F2F7D,&H95408A78,&H003F2F7D,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&H36000000,&H66408A78,&H003F782E,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&H36000000,&H66408A78,&H00BF782E,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&H36000000,&H66408A78,&H003F782E,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H95000000,&H36BF2F7D,&H95408A78,&H003F2F7D,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&H36000000,&H66408A78,&H00BF782E,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H95000000,&H36BF2F7D,&H95408A78,&H003F2F7D,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H66000000,&H36BF782E,&H00408A78,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&H36000000,&H66408A78,&H00BF782E,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H66000000,&H36BF782E,&H00408A78,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H95000000,&H36BF2F7D,&H95408A78,&H00BF2F7D,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H05000000,&H29BFC353,&H00402308,&H00000000,&H00000000,&H0B000000,&H99BF56B5
    DATA &H6A3ED6BB,&H00BEB1DE,&H95000000,&H0040B32D,&H00000000,&H00000000,&H0B000000,&H99BF56B5
    DATA &H6A3ED6BB,&H75BEB1DE,&H29BF8A1D,&H75402308,&H00BF8A1D,&H00000000,&H0B000000,&H99BF56B5
    DATA &H6A3ED6BB,&H00BEB1DE,&H29000000,&H05402308,&H00BFC353,&H00000000,&H6A000000,&H993EB1DE
    DATA &H0B3ED6BB,&H00BF56B5,&H95000000,&H0040B32D,&H00000000,&H00000000,&H6A000000,&H993EB1DE
    DATA &H0B3ED6BB,&H75BF56B5,&H293F8A1D,&H75402308,&H00BF8A1D,&H00000000,&H6A000000,&H993EB1DE
    DATA &H0B3ED6BB,&H75BF56B5,&H29BF8A1D,&H75402308,&H003F8A1D,&H00000000,&H0B000000,&H99BF56B5
    DATA &H6A3ED6BB,&H003EB1DE,&H95000000,&H0040B32D,&H00000000,&H00000000,&H0B000000,&H99BF56B5
    DATA &H6A3ED6BB,&H053EB1DE,&H29BFC353,&H00402308,&H00000000,&H00000000,&H0B000000,&H99BF56B5
    DATA &H6A3ED6BB,&H003EB1DE,&H29000000,&H05402308,&H003FC353,&H00000000,&H6A000000,&H99BEB1DE
    DATA &H0B3ED6BB,&H003F56B5,&H95000000,&H0040B32D,&H00000000,&H00000000,&H6A000000,&H99BEB1DE
    DATA &H0B3ED6BB,&H753F56B5,&H29BF8A1D,&H75402308,&H003F8A1D,&H00000000,&H6A000000,&H99BEB1DE
    DATA &H0B3ED6BB,&H753F56B5,&H293F8A1D,&H75402308,&H003F8A1D,&H00000000,&H6A000000,&H993EB1DE
    DATA &H0B3ED6BB,&H003F56B5,&H95000000,&H0040B32D,&H00000000,&H00000000,&H6A000000,&H993EB1DE
    DATA &H0B3ED6BB,&H003F56B5,&H29000000,&H05402308,&H003FC353,&H00000000,&H6A000000,&H993EB1DE
    DATA &H0B3ED6BB,&H053F56B5,&H293FC353,&H00402308,&H00000000,&H00000000,&H0B000000,&H993F56B5
    DATA &H6A3ED6BB,&H003EB1DE,&H95000000,&H0040B32D,&H00000000,&H00000000,&H0B000000,&H993F56B5
    DATA &H6A3ED6BB,&H753EB1DE,&H293F8A1D,&H75402308,&H003F8A1D,&H00000000,&H0B000000,&H993F56B5
    DATA &H6A3ED6BB,&H753EB1DE,&H29BF8A1D,&H75402308,&H00BF8A1D,&H00000000,&H6A000000,&H99BEB1DE
    DATA &H0B3ED6BB,&H00BF56B5,&H95000000,&H0040B32D,&H00000000,&H00000000,&H6A000000,&H99BEB1DE
    DATA &H0B3ED6BB,&H00BF56B5,&H29000000,&H05402308,&H00BFC353,&H00000000,&H6A000000,&H99BEB1DE
    DATA &H0B3ED6BB,&H75BF56B5,&H293F8A1D,&H75402308,&H00BF8A1D,&H00000000,&H0B000000,&H993F56B5
    DATA &H6A3ED6BB,&H00BEB1DE,&H95000000,&H0040B32D,&H00000000,&H00000000,&H0B000000,&H993F56B5
    DATA &H6A3ED6BB,&H05BEB1DE,&H293FC353,&H00402308,&H00000000,&H00000000,&H0B000000,&H993F56B5
    DATA &H6A3ED6BB,&H00BEB1DE,&H29000000,&H05402308,&H00BFC353,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H75000000,&H293F8A1D,&H75402308,&H00BF8A1D,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H05000000,&H293FC353,&H00402308,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&H29000000,&H05402308,&H00BFC353,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H05000000,&H293FC353,&H00402308,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H75000000,&H293F8A1D,&H75402308,&H003F8A1D,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&H29000000,&H05402308,&H00BFC353,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H75000000,&H293F8A1D,&H75402308,&H003F8A1D,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&H29000000,&H05402308,&H003FC353,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&H29000000,&H05402308,&H00BFC353,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&H29000000,&H05402308,&H003FC353,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H75000000,&H29BF8A1D,&H75402308,&H003F8A1D,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&H29000000,&H05402308,&H00BFC353,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H75000000,&H29BF8A1D,&H75402308,&H003F8A1D,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H05000000,&H29BFC353,&H00402308,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&H29000000,&H05402308,&H00BFC353,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H05000000,&H29BFC353,&H00402308,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H75000000,&H29BF8A1D,&H75402308,&H00BF8A1D,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H38000000,&HEBC00587,&H003F27FC,&H00000000,&H00000000,&H0B000000,&H99BF56B5
    DATA &H6A3ED6BB,&H00BEB1DE,&HD5000000,&H00409A86,&H00000000,&H00000000,&H0B000000,&H99BF56B5
    DATA &H6A3ED6BB,&H5EBEB1DE,&HEBBFBCD6,&H5E3F27FC,&H00BFBCD6,&H00000000,&H0B000000,&H99BF56B5
    DATA &H6A3ED6BB,&H00BEB1DE,&HEB000000,&H383F27FC,&H00C00587,&H00000000,&H6A000000,&H993EB1DE
    DATA &H0B3ED6BB,&H00BF56B5,&HD5000000,&H00409A86,&H00000000,&H00000000,&H6A000000,&H993EB1DE
    DATA &H0B3ED6BB,&H5EBF56B5,&HEB3FBCD6,&H5E3F27FC,&H00BFBCD6,&H00000000,&H6A000000,&H993EB1DE
    DATA &H0B3ED6BB,&H5EBF56B5,&HEBBFBCD6,&H5E3F27FC,&H003FBCD6,&H00000000,&H0B000000,&H99BF56B5
    DATA &H6A3ED6BB,&H003EB1DE,&HD5000000,&H00409A86,&H00000000,&H00000000,&H0B000000,&H99BF56B5
    DATA &H6A3ED6BB,&H383EB1DE,&HEBC00587,&H003F27FC,&H00000000,&H00000000,&H0B000000,&H99BF56B5
    DATA &H6A3ED6BB,&H003EB1DE,&HEB000000,&H383F27FC,&H00400587,&H00000000,&H6A000000,&H99BEB1DE
    DATA &H0B3ED6BB,&H003F56B5,&HD5000000,&H00409A86,&H00000000,&H00000000,&H6A000000,&H99BEB1DE
    DATA &H0B3ED6BB,&H5E3F56B5,&HEBBFBCD6,&H5E3F27FC,&H003FBCD6,&H00000000,&H6A000000,&H99BEB1DE
    DATA &H0B3ED6BB,&H5E3F56B5,&HEB3FBCD6,&H5E3F27FC,&H003FBCD6,&H00000000,&H6A000000,&H993EB1DE
    DATA &H0B3ED6BB,&H003F56B5,&HD5000000,&H00409A86,&H00000000,&H00000000,&H6A000000,&H993EB1DE
    DATA &H0B3ED6BB,&H003F56B5,&HEB000000,&H383F27FC,&H00400587,&H00000000,&H6A000000,&H993EB1DE
    DATA &H0B3ED6BB,&H383F56B5,&HEB400587,&H003F27FC,&H00000000,&H00000000,&H0B000000,&H993F56B5
    DATA &H6A3ED6BB,&H003EB1DE,&HD5000000,&H00409A86,&H00000000,&H00000000,&H0B000000,&H993F56B5
    DATA &H6A3ED6BB,&H5E3EB1DE,&HEB3FBCD6,&H5E3F27FC,&H003FBCD6,&H00000000,&H0B000000,&H993F56B5
    DATA &H6A3ED6BB,&H5E3EB1DE,&HEBBFBCD6,&H5E3F27FC,&H00BFBCD6,&H00000000,&H6A000000,&H99BEB1DE
    DATA &H0B3ED6BB,&H00BF56B5,&HD5000000,&H00409A86,&H00000000,&H00000000,&H6A000000,&H99BEB1DE
    DATA &H0B3ED6BB,&H00BF56B5,&HEB000000,&H383F27FC,&H00C00587,&H00000000,&H6A000000,&H99BEB1DE
    DATA &H0B3ED6BB,&H5EBF56B5,&HEB3FBCD6,&H5E3F27FC,&H00BFBCD6,&H00000000,&H0B000000,&H993F56B5
    DATA &H6A3ED6BB,&H00BEB1DE,&HD5000000,&H00409A86,&H00000000,&H00000000,&H0B000000,&H993F56B5
    DATA &H6A3ED6BB,&H38BEB1DE,&HEB400587,&H003F27FC,&H00000000,&H00000000,&H0B000000,&H993F56B5
    DATA &H6A3ED6BB,&H00BEB1DE,&HEB000000,&H383F27FC,&H00C00587,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H5E000000,&HEB3FBCD6,&H5E3F27FC,&H00BFBCD6,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H38000000,&HEB400587,&H003F27FC,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&HEB000000,&H383F27FC,&H00C00587,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H38000000,&HEB400587,&H003F27FC,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H5E000000,&HEB3FBCD6,&H5E3F27FC,&H003FBCD6,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&HEB000000,&H383F27FC,&H00C00587,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H5E000000,&HEB3FBCD6,&H5E3F27FC,&H003FBCD6,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&HEB000000,&H383F27FC,&H00400587,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&HEB000000,&H383F27FC,&H00C00587,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&HEB000000,&H383F27FC,&H00400587,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H5E000000,&HEBBFBCD6,&H5E3F27FC,&H003FBCD6,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&HEB000000,&H383F27FC,&H00C00587,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H5E000000,&HEBBFBCD6,&H5E3F27FC,&H003FBCD6,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H38000000,&HEBC00587,&H003F27FC,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&HEB000000,&H383F27FC,&H00C00587,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H38000000,&HEBC00587,&H003F27FC,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H5E000000,&HEBBFBCD6,&H5E3F27FC,&H00BFBCD6,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&H00000000,&H3DBF8000,&H00BF2161,&H00000000,&H41000000,&H003EC3F1
    DATA &HB6000000,&H00BF6C84,&H00000000,&H3D3F8000,&H00BF2161,&H00000000,&H41000000,&H003EC3F1
    DATA &HB6000000,&HBDBF6C84,&H003EE439,&HBD3F8000,&H00BEE439,&H00000000,&H41000000,&H003EC3F1
    DATA &HB6000000,&H00BF6C84,&H00000000,&H3DBF8000,&H00BF2161,&H00000000,&H41000000,&H003EC3F1
    DATA &HB6000000,&HBDBF6C84,&H003EE439,&HBD3F8000,&H00BEE439,&H00000000,&H41000000,&H003EC3F1
    DATA &HB6000000,&HBDBF6C84,&H003EE439,&HBDBF8000,&H00BEE439,&H00000000,&H41000000,&H003EC3F1
    DATA &HB6000000,&HBDBF6C84,&H003EE439,&HBDBF8000,&H00BEE439,&H00000000,&HB6000000,&H003F6C84
    DATA &H41000000,&HBDBEC3F1,&H003EE439,&HBD3F8000,&H00BEE439,&H00000000,&HB6000000,&H003F6C84
    DATA &H41000000,&H3DBEC3F1,&H003F2161,&H003F8000,&H00000000,&H00000000,&HB6000000,&H003F6C84
    DATA &H41000000,&HBDBEC3F1,&H003EE439,&HBDBF8000,&H00BEE439,&H00000000,&HB6000000,&H003F6C84
    DATA &H41000000,&H3DBEC3F1,&H003F2161,&H003F8000,&H00000000,&H00000000,&HB6000000,&H003F6C84
    DATA &H41000000,&H3DBEC3F1,&H003F2161,&H00BF8000,&H00000000,&H00000000,&HB6000000,&H003F6C84
    DATA &H41000000,&H3DBEC3F1,&H003F2161,&H00BF8000,&H00000000,&H00000000,&HB6000000,&H003F6C84
    DATA &H41000000,&H3D3EC3F1,&H003F2161,&H003F8000,&H00000000,&H00000000,&HB6000000,&H003F6C84
    DATA &H41000000,&HBD3EC3F1,&H003EE439,&HBD3F8000,&H003EE439,&H00000000,&HB6000000,&H003F6C84
    DATA &H41000000,&H3D3EC3F1,&H003F2161,&H00BF8000,&H00000000,&H00000000,&HB6000000,&H003F6C84
    DATA &H41000000,&HBD3EC3F1,&H003EE439,&HBD3F8000,&H003EE439,&H00000000,&HB6000000,&H003F6C84
    DATA &H41000000,&HBD3EC3F1,&H003EE439,&HBDBF8000,&H003EE439,&H00000000,&HB6000000,&H003F6C84
    DATA &H41000000,&HBD3EC3F1,&H003EE439,&HBDBF8000,&H003EE439,&H00000000,&H41000000,&H003EC3F1
    DATA &HB6000000,&HBD3F6C84,&H003EE439,&HBD3F8000,&H003EE439,&H00000000,&H41000000,&H003EC3F1
    DATA &HB6000000,&H003F6C84,&H00000000,&H3D3F8000,&H003F2161,&H00000000,&H41000000,&H003EC3F1
    DATA &HB6000000,&HBD3F6C84,&H003EE439,&HBDBF8000,&H003EE439,&H00000000,&H41000000,&H003EC3F1
    DATA &HB6000000,&H003F6C84,&H00000000,&H3D3F8000,&H003F2161,&H00000000,&H41000000,&H003EC3F1
    DATA &HB6000000,&H003F6C84,&H00000000,&H3DBF8000,&H003F2161,&H00000000,&H41000000,&H003EC3F1
    DATA &HB6000000,&H003F6C84,&H00000000,&H3DBF8000,&H003F2161,&H00000000,&H41000000,&H00BEC3F1
    DATA &HB6000000,&H003F6C84,&H00000000,&H3D3F8000,&H003F2161,&H00000000,&H41000000,&H00BEC3F1
    DATA &HB6000000,&HBD3F6C84,&H00BEE439,&HBD3F8000,&H003EE439,&H00000000,&H41000000,&H00BEC3F1
    DATA &HB6000000,&H003F6C84,&H00000000,&H3DBF8000,&H003F2161,&H00000000,&H41000000,&H00BEC3F1
    DATA &HB6000000,&HBD3F6C84,&H00BEE439,&HBD3F8000,&H003EE439,&H00000000,&H41000000,&H00BEC3F1
    DATA &HB6000000,&HBD3F6C84,&H00BEE439,&HBDBF8000,&H003EE439,&H00000000,&H41000000,&H00BEC3F1
    DATA &HB6000000,&HBD3F6C84,&H00BEE439,&HBDBF8000,&H003EE439,&H00000000,&HB6000000,&H00BF6C84
    DATA &H41000000,&HBD3EC3F1,&H00BEE439,&HBD3F8000,&H003EE439,&H00000000,&HB6000000,&H00BF6C84
    DATA &H41000000,&H3D3EC3F1,&H00BF2161,&H003F8000,&H00000000,&H00000000,&HB6000000,&H00BF6C84
    DATA &H41000000,&HBD3EC3F1,&H00BEE439,&HBDBF8000,&H003EE439,&H00000000,&HB6000000,&H00BF6C84
    DATA &H41000000,&H3D3EC3F1,&H00BF2161,&H003F8000,&H00000000,&H00000000,&HB6000000,&H00BF6C84
    DATA &H41000000,&H3D3EC3F1,&H00BF2161,&H00BF8000,&H00000000,&H00000000,&HB6000000,&H00BF6C84
    DATA &H41000000,&HBD3EC3F1,&H003EE439,&HBD3F8000,&H00BEE439,&H00000000,&H00000000,&H00000000
    DATA &H003F8000,&H00000000,&H00000000,&H3D3F8000,&H00BF2161,&H00000000,&H00000000,&H00000000
    DATA &H003F8000,&HBD000000,&H00BEE439,&HBD3F8000,&H00BEE439,&H00000000,&H00000000,&H00000000
    DATA &H003F8000,&HBD000000,&H003EE439,&HBD3F8000,&H00BEE439,&H00000000,&H00000000,&H00000000
    DATA &H003F8000,&HBD000000,&H00BEE439,&HBD3F8000,&H00BEE439,&H00000000,&H00000000,&H00000000
    DATA &H003F8000,&H3D000000,&H00BF2161,&H003F8000,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H003F8000,&HBD000000,&H003EE439,&HBD3F8000,&H00BEE439,&H00000000,&H00000000,&H00000000
    DATA &H003F8000,&H3D000000,&H00BF2161,&H003F8000,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H003F8000,&HBD000000,&H00BEE439,&HBD3F8000,&H003EE439,&H00000000,&H00000000,&H00000000
    DATA &H003F8000,&HBD000000,&H003EE439,&HBD3F8000,&H00BEE439,&H00000000,&H00000000,&H00000000
    DATA &H003F8000,&HBD000000,&H00BEE439,&HBD3F8000,&H003EE439,&H00000000,&H00000000,&H00000000
    DATA &H003F8000,&H00000000,&H00000000,&H3D3F8000,&H003F2161,&H00000000,&H00000000,&H00000000
    DATA &H003F8000,&HBD000000,&H003EE439,&HBD3F8000,&H00BEE439,&H00000000,&H00000000,&H00000000
    DATA &H003F8000,&H00000000,&H00000000,&H3D3F8000,&H003F2161,&H00000000,&H00000000,&H00000000
    DATA &H003F8000,&HBD000000,&H003EE439,&HBD3F8000,&H003EE439,&H00000000,&H00000000,&H00000000
    DATA &H003F8000,&HBD000000,&H003EE439,&HBD3F8000,&H00BEE439,&H00000000,&H00000000,&H00000000
    DATA &H003F8000,&HBD000000,&H003EE439,&HBD3F8000,&H003EE439,&H00000000,&H00000000,&H00000000
    DATA &H003F8000,&H3D000000,&H003F2161,&H003F8000,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H003F8000,&HBD000000,&H00BEE439,&HBDBF8000,&H00BEE439,&H00000000,&H41000000,&H00BEC3F1
    DATA &HB6000000,&HBDBF6C84,&H00BEE439,&HBD3F8000,&H00BEE439,&H00000000,&H41000000,&H00BEC3F1
    DATA &HB6000000,&H00BF6C84,&H00000000,&H3D3F8000,&H00BF2161,&H00000000,&H41000000,&H00BEC3F1
    DATA &HB6000000,&HBDBF6C84,&H00BEE439,&HBDBF8000,&H00BEE439,&H00000000,&H41000000,&H00BEC3F1
    DATA &HB6000000,&H00BF6C84,&H00000000,&H3D3F8000,&H00BF2161,&H00000000,&H41000000,&H00BEC3F1
    DATA &HB6000000,&H00BF6C84,&H00000000,&H3DBF8000,&H00BF2161,&H00000000,&H41000000,&H00BEC3F1
    DATA &HB6000000,&H3DBF6C84,&H00BF2161,&H00BF8000,&H00000000,&H00000000,&HB6000000,&H00BF6C84
    DATA &H41000000,&H3DBEC3F1,&H00BF2161,&H003F8000,&H00000000,&H00000000,&HB6000000,&H00BF6C84
    DATA &H41000000,&HBDBEC3F1,&H00BEE439,&HBD3F8000,&H00BEE439,&H00000000,&HB6000000,&H00BF6C84
    DATA &H41000000,&H3DBEC3F1,&H00BF2161,&H00BF8000,&H00000000,&H00000000,&HB6000000,&H00BF6C84
    DATA &H41000000,&HBDBEC3F1,&H00BEE439,&HBD3F8000,&H00BEE439,&H00000000,&HB6000000,&H00BF6C84
    DATA &H41000000,&HBDBEC3F1,&H00BEE439,&HBDBF8000,&H00BEE439,&H00000000,&HB6000000,&H00BF6C84
    DATA &H41000000,&H00BEC3F1,&H00000000,&H3DBF8000,&H00BF2161,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&HBD000000,&H003EE439,&HBDBF8000,&H00BEE439,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H3D000000,&H003F2161,&H00BF8000,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&H00000000,&H3DBF8000,&H00BF2161,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H3D000000,&H003F2161,&H00BF8000,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&HBD000000,&H003EE439,&HBDBF8000,&H003EE439,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&H00000000,&H3DBF8000,&H00BF2161,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&HBD000000,&H003EE439,&HBDBF8000,&H003EE439,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&H00000000,&H3DBF8000,&H003F2161,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&H00000000,&H3DBF8000,&H00BF2161,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&H00000000,&H3DBF8000,&H003F2161,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&HBD000000,&H00BEE439,&HBDBF8000,&H003EE439,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&H00000000,&H3DBF8000,&H00BF2161,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&HBD000000,&H00BEE439,&HBDBF8000,&H003EE439,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H3D000000,&H00BF2161,&H00BF8000,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&H00000000,&H3DBF8000,&H00BF2161,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H3D000000,&H00BF2161,&H00BF8000,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&HBD000000,&H00BEE439,&HBDBF8000,&H00BEE439,&H00000000,&H00000000,&H00000000
    DATA &H00BF8000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000,&H00000000
    DATA &H00,&H00,&H00,&H00,&H00,&H00,&H00
END FUNCTION

PS: All the programs in this thread were amazing... I enjoyed each of them!



 
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: johnno56 on December 23, 2020, 04:58:45 pm
Very nicely done!
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 23, 2020, 05:30:58 pm
Another gift from the GL master! Nice one @Ashish :)

You know I was kinda expecting something like this from Fellippe:
Code: QB64: [Select]
  1. OPTION _EXPLICIT ' bplus mod of Fellippe's Pendula 2020-12-23
  2.  
  3. SCREEN _NEWIMAGE(1000, 600, 32)
  4. _DELAY .25
  5.  
  6. CONST maxPendulum = 15
  7. f& = _LOADFONT("Arial.ttf", 20, "MONOSPACE")
  8. DIM theta(maxPendulum), accel(maxPendulum), speed(maxPendulum)
  9. DIM length(maxPendulum), mass(maxPendulum)
  10. DIM px, py, bx, by, rr, btx, bty, btx2, bty2
  11.  
  12. DIM a, x1, y1, x2, y2, x3, y3, x4, y4 'try one more time for ornament tops
  13.  
  14. g = 9.81
  15. FOR i = 0 TO maxPendulum
  16.     theta(i) = _PI / 1.5
  17.     speed(i) = 0
  18.     length(i) = 100 + i * 30
  19.     mass(i) = 1 - i * .01
  20.  
  21. px = _WIDTH / 2
  22. py = -5
  23.  
  24. _TITLE "Pendula by FellippeHeitor with alittle mod by bplus"
  25. COLOR , &H000000
  26.     CLS
  27.     FOR i = maxPendulum TO 1 STEP -1 'reverse som lines aren't drawn over previous ones
  28.         accel(i) = mass(i) * g * SIN(theta(i)) / 100
  29.         speed(i) = speed(i) + accel(i) / 100
  30.         theta(i) = theta(i) + speed(i)
  31.         bx = px + length(i) * SIN(theta(i))
  32.         btx = px + (length(i) - 30) * SIN(theta(i))
  33.         btx2 = px + (length(i) - 32) * SIN(theta(i))
  34.         by = py - length(i) * COS(theta(i))
  35.         bty = py - (length(i) - 30) * COS(theta(i))
  36.         bty2 = py - (length(i) - 32) * COS(theta(i))
  37.         LINE (px, py)-(bx, by), &HAAFF8800
  38.         FOR rr = 25 TO 0 STEP -.25
  39.             IF i MOD 2 THEN CIRCLE (bx, by), rr, _RGB32(255 - rr * 7, 0, 0) ELSE CIRCLE (bx, by), rr, _RGB32(0, 255 - rr * 7, 0)
  40.         NEXT
  41.         CIRCLE (btx2, bty2), 3, &HFFFF8800
  42.         a = _ATAN2(py - by, px - bx) - _PI / 2
  43.         x1 = btx + 5 * COS(a): y1 = bty + 5 * SIN(a)
  44.         x2 = btx + 5 * COS(a + _PI): y2 = bty + 5 * SIN(a + _PI)
  45.         x3 = x1 + 7 * COS(a - _PI / 2): y3 = y1 + 7 * SIN(a - _PI / 2)
  46.         x4 = x2 + 7 * COS(a - _PI + _PI / 2): y4 = y2 + 7 * SIN(a - _PI + _PI / 2)
  47.         IF i MOD 2 THEN
  48.             ftri x1, y1, x2, y2, x3, y3, &HFF660000
  49.             ftri x3, y3, x4, y4, x2, y2, &HFF660000
  50.         ELSE
  51.             ftri x1, y1, x2, y2, x3, y3, &HFF007700
  52.             ftri x3, y3, x4, y4, x2, y2, &HFF007700
  53.         END IF
  54.         _PRINTSTRING (bx - 5, by - 9), MID$("Merry Christmas", i, 1)
  55.     NEXT
  56.     _DISPLAY
  57.     _LIMIT 60
  58.  
  59.  
  60. SUB ftri (x1, y1, x2, y2, x3, y3, K AS _UNSIGNED LONG)
  61.     DIM D AS LONG
  62.     STATIC a&
  63.     D = _DEST
  64.     IF a& = 0 THEN a& = _NEWIMAGE(1, 1, 32)
  65.     _DEST a&
  66.     _DONTBLEND a& '  '<<<< new 2019-12-16 fix
  67.     PSET (0, 0), K
  68.     _BLEND a& '<<<< new 2019-12-16 fix
  69.     _DEST D
  70.     _MAPTRIANGLE _SEAMLESS(0, 0)-(0, 0)-(0, 0), a& TO(x1, y1)-(x2, y2)-(x3, y3)
  71.  
  72.  

;-))

I confess being stymied trying to give the pendula little ornament like tops, the trig system used here is backwards from everything I've ever done in Basic. I will try one more time because I think I was going wrong trying to use this system, stick to what I know and all that... :)

BTW I posted a translation of this at JB and was informed that mass should not be needed but might compensate for some other thing... I think STx said similar. But got Wows, anyway. So Cheers @FellippeHeitor :)

Update: Yeah! Got it fixed to how I wanted it, using regular trig system. Reposted code above 7:55 PM my time.
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: FellippeHeitor on December 23, 2020, 05:43:50 pm
Lol, I had a hard time remembering what pendulum code you were talking about until I ran it. Great mod!
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: FellippeHeitor on December 23, 2020, 07:40:27 pm
Thanks to everyone who submitted their code! Here's our annual Holiday Season Code Sampler video:

Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Petr on December 24, 2020, 05:05:13 am
Nicely done, Fellippe. Merry Christmas!
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Dimster on December 24, 2020, 08:10:41 am
What a beautiful Christmas butterfly you QB64 coders have created. Thanks for same. Hope you all get a good poke in the arm in the New Year and have a Merry Christmas.
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 24, 2020, 11:13:49 am
Well I think it's way too short, most samplers let you at least taste the candy, not just smell it ;-))

But I blame Dav, his music track ran too short! Poor Fellippe had to jam everything into 2 minutes of sound track and a good job at that.

Next year I suggest a whole album from Dav so Fellippe can make a movie ;-))

Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: FellippeHeitor on December 24, 2020, 11:25:04 am
I did have to extend the original track though... Can you spot the patch?

Dav, don't spill it 😂
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: bplus on December 24, 2020, 11:35:31 am
I did have to extend the original track though... Can you spot the patch?

Dav, don't spill it 😂

Um... once the work is finished, probably not a good idea to point out the bugs.

My brother the perfectionist does that often and danged if those hidden bugs don't look 1000 x's bigger than they were before he pointed them out!
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: FellippeHeitor on December 24, 2020, 11:50:03 am
😂
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Pete on December 26, 2020, 01:29:04 am


Code: QB64: [Select]
  1. beta% = 1 ' Testing text
  2. debug% = 0 ' Debugger stats.
  3. scrb.opt = 0 ' Variable size scrollbar box.
  4.  
  5. DIM scrn AS my_scrn
  6. DIM page AS my_page
  7. DIM margin AS my_margin
  8. DIM scrb AS my_scrb
  9. DIM cursor AS my_cursor
  10. DIM mb AS my_mb
  11.  
  12.  
  13. TYPE my_scrn
  14.     w AS INTEGER
  15.     h AS INTEGER
  16.  
  17. TYPE my_page
  18.     w AS INTEGER
  19.     h AS INTEGER
  20.     c AS INTEGER
  21.  
  22. TYPE my_margin
  23.     t AS INTEGER
  24.     b AS INTEGER
  25.     l AS INTEGER
  26.     r AS INTEGER
  27.  
  28. TYPE my_scrb
  29.     t AS INTEGER
  30.     b AS INTEGER
  31.     l AS INTEGER
  32.     x AS INTEGER
  33.     i AS INTEGER
  34.     d AS INTEGER
  35.     h AS INTEGER
  36.     s AS INTEGER
  37.     opt AS INTEGER
  38.     adjust AS INTEGER
  39.  
  40. TYPE my_cursor
  41.     find AS INTEGER
  42.     scbrrow AS INTEGER ' row + scr
  43.     scbrcol AS INTEGER ' POS(0)
  44.     holdscr AS INTEGER ' Holds scr
  45.     holdrow AS INTEGER ' Holds row
  46.     holdscrbx AS INTEGER ' Holds scrb.x
  47.     top AS INTEGER
  48.     bot AS INTEGER
  49.  
  50. TYPE my_mb
  51.     l AS INTEGER
  52.     r AS INTEGER
  53.     m AS INTEGER
  54.     w AS INTEGER
  55.     drag AS INTEGER
  56.     dragon AS INTEGER
  57.  
  58. GOSUB setvariables
  59.  
  60. GOSUB getvar_setscrn
  61.  
  62. IF beta% THEN GOSUB betatestfile
  63.  
  64.     GOSUB getkey
  65.  
  66.     IF updatescrn% THEN
  67.  
  68.         GOSUB keyeffect
  69.  
  70.         GOSUB determinewrap
  71.  
  72.         IF wrap.on% THEN GOSUB wrapper
  73.  
  74.         GOSUB displaydoc
  75.  
  76.         updatescrn% = 0
  77.     END IF
  78.  
  79.  
  80. ' **************************** GOSUB ROUTINES *******************************
  81.  
  82. setvariables:
  83. scrn.h = 25
  84. margin.t = 3
  85. margin.b = 3
  86. margin.l = 5
  87. margin.r = 5
  88. border.thk = 0
  89. border.stl = 1
  90. ins% = 7
  91. ovm% = 1 ' Change this to 0 for no over margin cursoring. 0 needed if right margin is at edge of screen.
  92. scrn.w = 80
  93. scrn.h = 25
  94. dwidth = scrn.w - (margin.l + margin.r): dwidth2 = dwidth + 2
  95. page.h = scrn.h - (margin.t + margin.b + CINT(border.thk / border.stl + .01))
  96. page.w = scrn.w - (margin.l + margin.r + border.thk * 2)
  97. REDIM x$(page.h)
  98. c1% = 7: c2% = 0: h1% = 15: h2% = 1 ' Normal text and highlighted text colors.
  99. RETURN ' ==================================================================
  100.  
  101. betatestfile:
  102. SELECT CASE beta%
  103.     CASE 1
  104.         REDIM x$(10)
  105.         a$ = "Money's Short" + CHR$(255) + CHR$(255) + "Times Are Crap" + CHR$(255) + CHR$(255) + "Here's Your Flocking" + CHR$(255) + CHR$(255) + "Christmas App"
  106.     CASE 2
  107.         OPEN "mybetatest.txt" FOR BINARY AS #1
  108.         a$ = SPACE$(LOF(1))
  109.         GET #1, , a$
  110.         CLOSE #1
  111.         i% = (LEN(a$) / dwidth) * 2
  112.         REDIM x$(i%)
  113.         DO UNTIL INSTR(a$, CHR$(13) + CHR$(10)) = 0
  114.             a$ = MID$(a$, 1, INSTR(a$, CHR$(13) + CHR$(10)) - 1) + CHR$(255) + MID$(a$, INSTR(a$, CHR$(13) + CHR$(10)) + 2)
  115.         LOOP
  116.  
  117. wrap.on% = -1: GOSUB wrapper
  118. filled% = page.h: row = 1
  119. LOCATE margin.t + row, margin.l + 1
  120. GOSUB displaydoc
  121. GOSUB movescrollbox
  122. RETURN ' ==================================================================
  123.  
  124. keyeffect:
  125. IF a$ = "" THEN
  126.     x$(row + scr) = "" + CHR$(10): wrap.on% = -1
  127.     x$(row + scr) = a$ + CHR$(10)
  128.  
  129. aux$ = a$
  130.  
  131. IF INSTR(aux$, CHR$(4)) AND cur$ = CHR$(32) THEN
  132.     MID$(aux$, INSTR(aux$, CHR$(4)), 1) = cur$
  133.  
  134. RETURN ' ==================================================================
  135.  
  136. determinewrap:
  137. IF row > 1 OR scr > 0 THEN ' Wrap to line above analysis. Determine if the line above the text input line should wrap up the first word of the text input.
  138.     l0% = dwidth - (INSTR(x$(row - 2 + scr + 1), CHR$(10)) - 1) ' -1 chops off chr$(10)
  139.     l1% = INSTR(aux$ + CHR$(32), CHR$(32)) - 1
  140.     IF l0% >= l1% AND l1% > 0 OR LEFT$(aux$, 1) = CHR$(32) AND l0% >= 0 THEN ' The line above has enough room to wrap up the first word of the current text line.
  141.         x$(row + scr) = a$ + CHR$(10) ' The current line array is changed to the current line of text input.
  142.         a$ = MID$(x$(row - 1 + scr), 1, INSTR(x$(row - 1 + scr), CHR$(10)) - 1) ' The current line of text input is now the line above.
  143.         IF row = 1 THEN
  144.             scr = scr - 1: GOSUB scrollscrn
  145.         ELSE
  146.             row = row - 1
  147.         END IF
  148.         wrap.on% = -1
  149.         RETURN
  150.     END IF
  151.  
  152. IF RIGHT$(aux$, 1) <> CHR$(32) AND row + scr < noe OR INSTR(aux$, CHR$(255)) THEN ' Delete last space of a text line, except the last line. Current line below will wrap to line below.
  153.     wrap.on% = -1
  154.     xcurrent$ = aux$
  155.     xcurrent% = dwidth - LEN(xcurrent$)
  156.  
  157.     IF row + scr + 1 > UBOUND(x$) THEN
  158.         xbelow$ = "" ' Text line below is blank, but the line above may be too long and still needs to be wrapped down.
  159.     ELSE
  160.         xbelow$ = MID$(x$(row + 1 + scr), 1, LEN(x$(row + 1 + scr)) - 1)
  161.     END IF
  162.  
  163.     IF LEFT$(xbelow$, 1) = CHR$(32) THEN
  164.         xbelow% = 1 ' Leading space.
  165.     ELSE
  166.         xbelow% = INSTR(xbelow$ + CHR$(32), CHR$(32)) - 1
  167.     END IF
  168.  
  169.     IF xcurrent% >= xbelow% AND xbelow% > 0 OR xcurrent% < 0 THEN
  170.         wrap.on% = -1
  171.     END IF
  172.  
  173. RETURN ' ==================================================================
  174.  
  175. wrapper:
  176. start% = 1: ii% = 0: filled% = 0 ' Do not exit this routine without zeroing wrap.on%.
  177. acut$ = a$ + acut$: a$ = ""
  178.  
  179.     ' Continue to concatenate until full text line or greater is achieved or until end of doc.
  180.     DO UNTIL ii% >= noe - (row + scr) ' > is a precaution. I had one error where if failed to exit loop with = alone.
  181.         acut$ = acut$ + MID$(x$(row + scr + ii% + 1), 1, INSTR(x$(row + scr + ii% + 1), CHR$(10)) - 1) ' Cut off chr$(10).
  182.         x$(row + scr + ii% + 1) = ""
  183.         ii% = ii% + 1
  184.         IF LEN(acut$) > dwidth THEN EXIT DO
  185.     LOOP
  186.  
  187.     '==========================================================================================
  188.  
  189.     ' Cut text line and place into next text array. -------------------------------------------
  190.  
  191.     h% = INSTR(MID$(acut$, 1, dwidth + 1), CHR$(4))
  192.     IF h% THEN
  193.         IF cur$ = CHR$(32) OR cur$ = CHR$(255) THEN
  194.             MID$(acut$, h%, 1) = cur$
  195.         END IF
  196.     END IF
  197.  
  198.     IF INSTR(MID$(acut$, 1, dwidth + 1), CHR$(255)) THEN
  199.         x$ = MID$(acut$, 1, INSTR(acut$, CHR$(255)))
  200.         start% = start% + INSTR(acut$, CHR$(255))
  201.     ELSEIF RIGHT$(MID$(acut$, start%, dwidth + 1), 1) = CHR$(32) THEN
  202.         x$ = MID$(acut$, start%, dwidth + 1)
  203.         start% = start% + dwidth + 1
  204.     ELSEIF INSTR(MID$(acut$, start%, dwidth) + CHR$(32), CHR$(32)) > dwidth THEN
  205.         x$ = MID$(acut$, 1, dwidth)
  206.         start% = start% + dwidth
  207.     ELSE
  208.         IF LEN(acut$) > dwidth THEN
  209.             k% = _INSTRREV(MID$(acut$, 1, dwidth), CHR$(32)) ' Include the space so word following is left justified on current line when word proceeding wraps to top line.
  210.             x$ = MID$(acut$, 1, k%)
  211.             start% = start% + k%
  212.         ELSE
  213.             k% = LEN(acut$)
  214.             x$ = MID$(acut$, 1, k%)
  215.             start% = start% + k%
  216.         END IF
  217.     END IF
  218.  
  219.     IF h% THEN
  220.         IF cur$ = CHR$(32) OR cur$ = CHR$(255) THEN
  221.             MID$(x$, h%, 1) = CHR$(4)
  222.         END IF
  223.     END IF
  224.  
  225.     filled% = filled% + 1
  226.  
  227.     IF LEN(x$) THEN
  228.         j% = row - 1 + scr + filled%
  229.         IF j% > UBOUND(x$) THEN REDIM _PRESERVE x$(j%)
  230.         x$(j%) = x$ + CHR$(10)
  231.     END IF
  232.  
  233.     acut$ = MID$(acut$, start%)
  234.     start% = 1
  235. LOOP UNTIL ii% >= noe - (row + scr) AND acut$ = ""
  236.  
  237. ' Determine end of doc line.
  238.  
  239. IF row + scr + filled% - 1 > noe THEN
  240.     noe = filled% + row + scr - 1
  241.     FOR i% = noe TO 1 STEP -1
  242.         IF LEN(x$(i%)) AND LEFT$(x$(i%), 1) <> CHR$(10) THEN noe = i%: EXIT FOR
  243.     NEXT
  244.  
  245. x$(0) = "" ' Precaution.
  246.     IF LEFT$(x$(noe), 1) = CHR$(10) THEN x$(noe) = ""
  247.     IF x$(noe) = "" AND noe > 1 THEN noe = noe - 1 ELSE EXIT DO
  248.  
  249. q% = 1 ' Display begins 1 line above row to handle any wrap changes.
  250. wrap.on% = 0
  251. RETURN ' ==================================================================
  252.  
  253. displaydoc:
  254. ' Routine to display doc arrays to page.
  255.  
  256. IF noe >= UBOUND(x$) THEN REDIM _PRESERVE x$(noe + 1)
  257. IF UBOUND(x$) > noe + 1 THEN REDIM _PRESERVE x$(noe + 1)
  258.  
  259. j% = UBOUND(x$)
  260. FOR i% = j% TO 1 STEP -1
  261.     IF INSTR(x$(i%), CHR$(10)) = 1 THEN
  262.         x$(i%) = ""
  263.     ELSE
  264.         IF INSTR(x$(i%), CHR$(10)) > 1 THEN EXIT FOR
  265.     END IF
  266.  
  267. gg% = 0
  268. FOR g% = 1 TO noe
  269.     IF INSTR(x$(g%), CHR$(4)) THEN gg% = g%: EXIT FOR
  270.  
  271. IF gg% > scr + row AND row + scr < noe AND row = page.h THEN
  272.     scr = scr + 1: GOSUB scrollscrn: row = row - 1: LOCATE margin.t + row, POS(0)
  273.  
  274. yy% = CSRLIN: xx% = POS(0)
  275.  
  276. IF row = 1 OR wrap.on% = 0 THEN q% = 0 ' Disable print line above.
  277.  
  278. k% = filled% + q% ' Number of altered lines to print to screen. If q% = 1 the line above the current row is also printed. Note that since the FOR loop starts at j% = 0, k% is actually one less than the number of lines altered in the wrap routine.
  279. IF row - q% + k% >= page.h THEN k% = page.h - (row - q%)
  280. IF scr + row - q% + k% > UBOUND(x$) THEN k% = UBOUND(x$) - (scr + row - q%)
  281.  
  282. IF noe - scr < page.h AND noe >= page.h THEN ' Adjust to bottom of the text screen.
  283.     scr = noe - page.h
  284.     IF noe - scr = page.h AND LEN(MID$(x$(noe), 1, INSTR(x$(noe), CHR$(10)) - 1)) >= dwidth OR noe - scr = page.h AND INSTR(x$(noe), CHR$(255)) THEN
  285.         scr = scr + 1 ' Raises everything up one line below bottom line to allow for the blank line occupied by the cursor at column 1.
  286.         IF POS(0) = margin.l + 1 AND row = page.h - 1 AND INSTR(x$(row + scr), CHR$(255)) THEN yy% = yy% + 1
  287.     ELSE
  288.         yy% = yy% + 1
  289.     END IF
  290.     row = 1: k% = page.h - 1: q% = 0
  291.  
  292. FOR j% = 0 TO k%
  293.     i% = row - q% + j% ' Display row.
  294.     LOCATE i% + margin.t, margin.l + 1
  295.     a1$ = SPACE$(dwidth + 1)
  296.     x$ = RTRIM$(MID$(x$(scr + i%), 1, INSTR(x$(scr + i%), CHR$(10)) - 1))
  297.     MID$(a1$, 1, LEN(MID$(x$(scr + i%), 1, dwidth))) = x$
  298.  
  299.     h% = INSTR(x$, CHR$(4))
  300.     IF h% THEN ' Re-establish cursor position.
  301.         yy% = CSRLIN: xx% = margin.l + border.thk + h%
  302.         MID$(a1$, h%, 1) = cur$ ' NOTE: h% can be longer than len(a1$) when # is a space at end of full line of text. When this happens, QB64 will simply not include it in the shaorter a1$.
  303.         MID$(x$(scr + i%), h%, 1) = cur$: cur$ = ""
  304.     END IF
  305.  
  306.     PRINT a1$;
  307.  
  308. q% = 0
  309. LOCATE yy%, xx%
  310.  
  311. row = CSRLIN - margin.t ' Needed here and in getkey for auto events.
  312.  
  313. '----------------------------------------------------------------------------------------------------------------------------
  314. REM BKSP CHR$(8) used at end of doc requires this routine to re-position cursor at the end of a wrapped upwards piece of text.
  315. IF cur$ = "eod" THEN
  316.     b$ = CHR$(0) + "u": GOSUB getkeyauto: cur$ = ""
  317. '----------------------------------------------------------------------------------------------------------------------------
  318.  
  319. IF curadvance% THEN
  320.     SELECT CASE curadvance%
  321.         CASE 1
  322.             b$ = CHR$(0) + ">"
  323.         CASE -1
  324.             ' Paragraph. variable is set to -1 for paragraphs.
  325.             b$ = CHR$(0) + "^"
  326.     END SELECT
  327.  
  328.     GOSUB getkeyauto ' Make sure this routine always exits getkeyauto so it can return here after advancing cursor. Remember, non character keys don't exit that loop unless b$ = "". There is a kloop% condition to meet this gosub/return requirement.
  329.  
  330.     curadvance% = 0
  331.  
  332. GOSUB makescrb
  333. RETURN ' ==================================================================
  334.  
  335. ' -------------------------------------------------------------------------
  336. '                             NESTED GOSUBS
  337. ' -------------------------------------------------------------------------
  338.  
  339. markercalc:
  340. IF hlbypass% = 0 THEN
  341.     o% = (row - 1) * dwidth2 + dwidth + 1
  342.     hlbypass% = 0
  343.  
  344. o1% = (o% - (o% MOD dwidth2)) / dwidth2 + 1 ' Relative (margin independent) cursor row origin.
  345. d% = (row - 1) * dwidth2 + col ' Relative (margin independent) cursor destination marker.
  346. o2% = o% MOD dwidth2 ' Relative (margin independent) cursor column origin.
  347. d1% = row ' Relative (margin independent) cursor row destination. Note: row is also relative (margin independent).
  348. d2% = col ' Relative (margin independent) cursor column destination. Note: col is also relative (margin independent).
  349.  
  350. scrollscrn: '
  351. yy% = CSRLIN: xx% = POS(0)
  352. scrmov = scr - oldscr
  353.  
  354. IF mark% AND markbypass% = 0 THEN
  355.     mark% = mark% - scrmov * dwidth2
  356.     markrow% = markrow% - scrmov
  357.     d% = (CSRLIN - margin.t - 1 - scrmov) * dwidth2 + POS(0) - margin.l
  358.     IF mhl1% THEN
  359.         mhl1% = mhl1% - scrmov * dwidth2
  360.         mhl1row% = mhl1row% - scrmov
  361.     END IF
  362.  
  363.     j% = d1% - scrmov
  364.     IF cutdrow% > scr AND cutdrow% <= page.h + scr THEN ' On screen
  365.         j% = cutdrow% - scr
  366.         d% = (j% - 1) * dwidth2 + cutdcol%
  367.     ELSE ' Off screen.
  368.         IF cutdrow% < scr THEN ' Above screen.
  369.             d% = 1
  370.             mhl1row% = 0
  371.         ELSE ' Below screen.
  372.             a1$ = MID$(x$(page.h + scr), 1, INSTR(x$(page.h + scr), CHR$(10)) - 1)
  373.             d% = (page.h - 1) * dwidth2 + LEN(a1$)
  374.             IF LEN(a1$) > dwidth THEN dmodify% = 1 ELSE d% = d% + 1
  375.         END IF
  376.     END IF
  377.     d1% = (d% - (d% MOD dwidth2)) / dwidth2 + 1
  378.     d2% = d% MOD dwidth2 ' Relative (margin independent) cursor column origin.
  379.     yy% = margin.t + d1%: xx% = margin.l + d2%
  380.     row = d1%: col = d2%
  381.     LOCATE yy%, xx%
  382.     j% = 0
  383.     IF cutmrow% THEN
  384.         SELECT CASE cutmrow%
  385.             CASE IS < cutdrow%: j% = cutmrow%: j1% = cutmcol%
  386.             CASE IS = cutdrow% ' Highlighting begins and ends on same row. Ex: Left and right arrow keys.
  387.                 IF cutmcol% < cutdcol% THEN j% = cutmrow%: j1% = cutmcol% ELSE j% = cutdrow%: j1% = cutdcol% ' Right arrow vs left arrow directions.
  388.             CASE IS > cutdrow%: j% = cutdrow%: j1% = cutdcol%
  389.         END SELECT
  390.  
  391.         jtop% = cutmrow%: jbot% = cutdrow%: IF jtop% > jbot% THEN SWAP jtop%, jbot%
  392.         IF h% < 0 THEN j% = -j% ' Preserve highlighted text while using scrollbar.
  393.     END IF
  394.     j% = 0 ' For all non-mark% (highlighted) text line printing.
  395.  
  396. FOR i% = 1 TO page.h
  397.     IF scr + i% > noe THEN EXIT FOR
  398.     LOCATE margin.t + i%, margin.l + 1
  399.     a1$ = SPACE$(dwidth + 1)
  400.     MID$(a1$, 1) = MID$(x$(scr + i%), 1, INSTR(x$(scr + i%), CHR$(10)) - 1)
  401.     a2$ = MID$(x$(scr + i%), 1, INSTR(x$(scr + i%), CHR$(10)) - 1)
  402.     a3$ = SPACE$(dwidth + 1 - LEN(a2$))
  403.     x1 = c1%: x2 = c2%: x3 = c1%: x4 = c2%: k% = LEN(a2$)
  404.  
  405.     SELECT CASE j%
  406.         CASE 0
  407.             PRINT a1$;
  408.         CASE IS < 0
  409.             IF i% + scr = jtop% THEN
  410.                 IF cutmrow% = cutdrow% THEN k% = ABS(cutmcol% - cutdcol%)
  411.                 x3 = h1%: x4 = h2%
  412.             ELSEIF i% + scr > jtop% AND i% + scr < jbot% THEN
  413.                 j1% = 1: x3 = h1%: x4 = h2%
  414.             ELSEIF i% + scr = jbot% THEN
  415.                 j1% = 1: x3 = h1%: x4 = h2%
  416.                 IF cutmrow% < cutdrow% THEN k% = col - 1 ELSE k% = cutmcol% - 1
  417.             END IF
  418.  
  419.             COLOR x1, x2: PRINT MID$(a2$, 1, j1% - 1);
  420.             COLOR x3, x4: PRINT MID$(a2$, j1%, k%);
  421.             COLOR c1%, c2%: PRINT MID$(a2$, j1% + k%) + a3$;
  422.         CASE ELSE
  423.             IF i% = h% THEN
  424.                 IF cutmrow% = cutdrow% THEN ' Left/Right Highlighting on origination row.
  425.                     x3 = h1%: x4 = h2%: k% = ABS(cutmcol% - cutdcol%)
  426.                 ELSE ' Left/Right/Up/Down Highlighting from row before scrolling row.
  427.                     x3 = h1%: x4 = h2%
  428.                     IF cutdrow% > cutmrow% THEN
  429.                         j1% = 1: k% = col - 1
  430.                     ELSE
  431.                         ' Do nothing. Arrow left and up do not require any change in parameters here.
  432.                     END IF
  433.                 END IF
  434.             ELSE
  435.                 IF i% + scr > jtop% AND i% + scr < jbot% THEN
  436.                     j1% = 1: x3 = h1%: x4 = h2%
  437.                 ELSE
  438.                     IF i% + scr = cutmrow% THEN
  439.                         x3 = h1%: x4 = h2%
  440.                         IF cutdrow% < cutmrow% THEN
  441.                             j1% = 1: k% = cutmcol% - 1
  442.                         ELSEIF cutdrow% = cutmrow% THEN
  443.                             k% = ABS(cutmcol% - cutdcol%)
  444.                         ELSEIF cutdrow% > cutmrow% THEN
  445.                             ' Do nothing.
  446.                         END IF
  447.                     ELSEIF i% + scr = cutdrow% THEN
  448.                         x3 = h1%: x4 = h2%
  449.                         IF cutdrow% > cutmrow% THEN
  450.                             j1% = 1: k% = cutdcol% - 1
  451.                         ELSE
  452.                             k% = ABS(LEN(a2$) - cutdcol%)
  453.                         END IF
  454.                     END IF
  455.                 END IF
  456.             END IF
  457.             COLOR x1, x2: PRINT MID$(a2$, 1, j1% - 1);
  458.             COLOR x3, x4: PRINT MID$(a2$, j1%, k%);
  459.             COLOR c1%, c2%: PRINT MID$(a2$, j1% + k%, LEN(a2$) - k%) + a3$;
  460.     END SELECT
  461. oldscr = scr
  462. COLOR c1%, c2%
  463. LOCATE yy%, xx%
  464.  
  465. GOSUB movescrollbox
  466.  
  467.  
  468. wipescrn:
  469. yy% = CSRLIN: xx% = POS(0)
  470. a1$ = SPACE$(dwidth + 1)
  471. FOR i% = 1 TO page.h
  472.     LOCATE i% + margin.t, margin.l + 1
  473.     PRINT a1$;
  474. LOCATE yy%, xx%
  475.  
  476. hlwipescrn:
  477. yy% = CSRLIN: xx% = POS(0)
  478. FOR j% = 1 TO page.h
  479.     IF j% + scr > noe THEN EXIT FOR
  480.     x$ = SPACE$(dwidth + 1)
  481.     a1$ = x$(j% + scr)
  482.     MID$(x$, 1, dwidth + 1) = MID$(a1$, 1, INSTR(a1$, CHR$(10)) - 1)
  483.     LOCATE margin.t + j%, margin.l + 1
  484.     PRINT x$;
  485. GOSUB clearmarkers
  486. LOCATE yy%, xx%
  487.  
  488. clearmarkers:
  489. ' Clear most variables used in highlighting process. Some others are non-essential to conditions.
  490. mark% = 0: o% = 0: mhl% = 0: mhl1% = 0: mhl1col% = 0: mhl1row% = 0: mhlclear% = 0: cutdrow% = 0
  491. cutmrow% = 0: o1% = 0: o2% = 0: d% = 0: d1% = 0: d2% = 0: dmodify% = 0
  492. markrow% = 0: markcol% = 0: cutmcol% = 0: cutdcol% = 0
  493.  
  494. betatest:
  495. ss% = CSRLIN: ww% = POS(0)
  496. z$ = MID$(beta$, 1, INSTR(beta$, "|") - 1)
  497. beta$ = MID$(beta$, INSTR(beta$, "|") + 1)
  498. IF LEFT$(z$, 1) = CHR$(32) THEN
  499.     b$ = CHR$(0) + CHR$(VAL(MID$(z$, 2)))
  500.     b$ = CHR$(VAL(z$))
  501. IF LEN(beta$) THEN
  502.     LOCATE 24, 1: PRINT SPACE$(40);: LOCATE 24, 1
  503.     COLOR 1, 0
  504.     PRINT LEN(beta$) \ 2; VAL(z$);
  505.     IF LEFT$(z$, 1) = CHR$(32) THEN PRINT " 0"; CHR$(VAL(MID$(z$, 2)));
  506.     IF ASC(b$) > 31 THEN PRINT " b$ = "; b$;
  507.     LOCATE ss%, ww%
  508.     COLOR 7, 0
  509.  
  510. '^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  511. '                          LARGEST GOSUB ROUTINE
  512. getkey:
  513.     _LIMIT 30
  514.     IF debug% THEN GOSUB debugger
  515.  
  516.     DEF SEG = 0 ' Look for Shift key press.
  517.     IF PEEK(1047) MOD 16 = 1 OR PEEK(1047) MOD 16 = 2 THEN shift% = -1 ELSE shift% = 0
  518.     IF PEEK(1047) MOD 16 = 3 OR PEEK(1047) MOD 16 = 4 THEN ctrl% = -1 ELSE ctrl% = 0
  519.     IF PEEK(1047) MOD 16 = 5 OR PEEK(1047) MOD 16 = 6 THEN ctrlshift% = -1 ELSE ctrlshift% = 0
  520.     DEF SEG
  521.  
  522.     ' Mouse clicks can influence b$ outside of the keypress loop. That's why b$ = "" in some keypress routines when they are completed.
  523.     IF autokey% = 0 THEN
  524.         b$ = INKEY$
  525.         IF LEN(b$) THEN
  526.             IF curhide% = -1 THEN
  527.                 GOSUB backtocursor
  528.             ELSE
  529.                 GOSUB getcurinfo
  530.             END IF
  531.             locked% = 0 ' A key press removes all mouse and mouse wheel locks.
  532.             IF ctrlshift% THEN IF b$ = CHR$(0) + "s" OR b$ = CHR$(0) + "t" THEN shift% = -1
  533.         END IF
  534.     ELSE
  535.         autokey% = 0
  536.         IF LEN(autokey$) THEN b$ = autokey$: autokey$ = ""
  537.     END IF
  538.  
  539.     IF LEN(beta$) THEN GOSUB betatest
  540.  
  541.     IF mhl% THEN
  542.         null$ = INKEY$: b$ = "" ' Clear key buffer when left mouse button is held down and lock out keys.
  543.     END IF
  544.  
  545.     IF mark% THEN
  546.         IF b$ >= CHR$(32) AND b$ <= CHR$(127) THEN
  547.             autokey% = -99: autokey$ = b$
  548.             b$ = CHR$(0) + "S"
  549.         END IF
  550.     END IF
  551.  
  552.     IF mark% AND b$ = CHR$(24) OR mark% AND b$ = CHR$(3) OR mark% AND b$ = CHR$(0) + "S" OR b$ = CHR$(1) OR b$ = CHR$(22) OR ctrlshift% AND b$ = CHR$(0) + "u" OR ctrlshift% AND b$ = CHR$(0) + "w" THEN ' Cut/Copy/Paste
  553.  
  554.         SELECT CASE b$
  555.             CASE CHR$(0) + "w" ' Ctrl + Shift + Home
  556.                 ' Required hold variables.
  557.                 hold1% = row: hold2% = scr: hold3% = POS(0) - margin.l
  558.  
  559.                 IF mark% THEN
  560.                     markbypass% = -1: GOSUB getkeyauto: markbypass% = 0
  561.  
  562.                     IF cutmrow% < cutdrow% THEN
  563.                         j% = cutmrow% - scr: k% = cutdrow% - scr: IF k% > page.h THEN k% = page.h
  564.                         FOR i% = j% TO k%
  565.                             x$ = SPACE$(dwidth + 1)
  566.                             a1$ = x$(i% + scr)
  567.                             MID$(x$, 1, dwidth + 1) = MID$(a1$, 1, INSTR(a1$, CHR$(10)) - 1)
  568.                             LOCATE margin.t + i%, margin.l + 1
  569.                             PRINT x$;
  570.                         NEXT
  571.                         mark% = (cutmrow% - 1) * dwidth2 + cutmcol% - 1 ' Note the -1 is here to "flip" to the other side of the highlighted line and not overlap.
  572.                         markrow% = (mark% - (mark% MOD dwidth2)) / dwidth2 + 1
  573.                         markcol% = mark% MOD dwidth2
  574.                     ELSE
  575.                         mark% = (cutmrow% - 1) * dwidth2 + cutmcol%
  576.                         markrow% = cutmrow%: markcol% = cutmcol% - 1 ' - 1 required to avoid overlap.
  577.                     END IF
  578.  
  579.                     IF mark% = 0 THEN ' Shift + Ctrl + Home resulted in clearing all text when all text was previously highlighted. Ex: Shift + Ctrl + A followed by Shift + Ctrl + HOme.
  580.                         GOSUB clearmarkers
  581.                     ELSE
  582.                         cutdrow% = 1: cutdcol% = 1
  583.                     END IF
  584.  
  585.                     col = 1 ' Required.
  586.                     b$ = ""
  587.                 ELSE
  588.                     GOSUB wipescrn
  589.                     GOSUB clearmarkers
  590.                     mark% = (hold1% + hold2% - 1) * dwidth2 + hold3%: markrow% = hold1% + hold2%: markcol% = hold3%
  591.                     cutmrow% = hold1% + hold2%: cutmcol% = markcol%
  592.                     cutdrow% = 1: cutdcol% = 1: col = 1
  593.                 END IF
  594.  
  595.                 row = 1: scr = 0: LOCATE margin.t + row, margin.l + 1
  596.  
  597.                 GOSUB markercalc
  598.  
  599.                 j% = page.h: k% = 1: g% = 0: IF j% >= cutmrow% THEN j% = cutmrow%: g% = 1
  600.                 COLOR h1%, h2%
  601.                 FOR i% = 0 TO j% - 1 - g%
  602.                     LOCATE margin.t + 1 + i%, margin.l + 1
  603.                     PRINT MID$(x$(k% + i%), 1, INSTR(x$(k% + i%), CHR$(10)) - 1);
  604.                 NEXT
  605.                 IF g% THEN
  606.                     LOCATE margin.t + 1 + i%, margin.l + 1
  607.                     PRINT MID$(x$(k% + i%), 1, markcol%);
  608.                     COLOR c1%, c2%
  609.                     PRINT MID$(x$(k% + i%), markcol% + 1);
  610.                 END IF
  611.                 COLOR c1%, c2%
  612.                 LOCATE margin.t + 1, margin.l + 1
  613.                 b$ = ""
  614.             CASE CHR$(0) + "u" ' Ctrl + Shift + End
  615.                 hold1% = row: hold2% = scr: hold3% = POS(0) - margin.l
  616.                 holdcutmrow% = cutmrow%: holdcutmcol% = cutmcol%: holdcutdrow% = cutdrow%: holdcutdcol% = cutdcol%
  617.  
  618.                 IF mark% THEN
  619.                     markbypass% = -1: GOSUB getkeyauto: markbypass% = 0
  620.  
  621.                     IF cutmrow% > cutdrow% THEN ' Highlighting was from bottom up.
  622.                         hold1% = cutmrow% - scr: hold2% = scr: hold3% = cutmcol%
  623.                     ELSE ' Highlighting continuing from top down.
  624.                         mark% = (cutmrow% - 1) * dwidth2 + cutmcol%
  625.                         markrow% = cutmrow%
  626.                         cutdrow% = row + scr: cutdcol% = POS(0) - margin.l
  627.                         hold1% = cutmrow% - hold2% ' orig scr. hold1% is now row.
  628.                         hold3% = cutmcol%
  629.                     END IF
  630.                 ELSE
  631.                     GOSUB clearmarkers: GOSUB getkeyauto
  632.                     mark% = (hold1% + hold2% - 1) * dwidth2 + hold3%: markrow% = hold1% + hold2%: markcol% = hold3%
  633.                     cutmrow% = hold1% + hold2%: cutmcol% = markcol%
  634.                     cutdrow% = noe: cutdcol% = LEN(MID$(x$(noe), 1, INSTR(x$(noe), CHR$(10)) - 1)) + 1
  635.                 END IF
  636.  
  637.                 yy% = CSRLIN: xx% = POS(0): col = xx% - margin.l
  638.  
  639.                 GOSUB markercalc
  640.  
  641.                 COLOR h1%, h2%
  642.  
  643.                 IF noe - cutmrow% < page.h THEN
  644.                     j% = page.h - (cutmrow% - scr)
  645.                     k% = cutmrow% - scr
  646.                 ELSE
  647.                     j% = page.h - 1: k% = 1: hold1% = 1: hold2% = scr: hold3% = 1
  648.                 END IF
  649.  
  650.                 IF noe < page.h THEN j% = noe - hold1%
  651.                 LOCATE margin.t + k%, margin.l + hold3%
  652.                 a1$ = MID$(x$(hold1% + hold2%), 1, INSTR(x$(hold1% + hold2%), CHR$(10)) - 1)
  653.                 PRINT MID$(a1$, hold3%);
  654.                 FOR i% = 1 TO j%
  655.                     LOCATE margin.t + k% + i%, margin.l + 1
  656.                     PRINT MID$(x$(hold1% + hold2% + i%), 1, INSTR(x$(hold1% + hold2% + i%), CHR$(10)) - 1);
  657.                 NEXT
  658.                 COLOR c1%, c2%
  659.                 LOCATE yy%, xx%
  660.  
  661.                 IF mark% <> 0 AND hold1% = row AND cutmrow% = holdcutmrow% AND cutmcol% = holdcutmcol% AND cutdrow% = holdcutdrow% AND cutdcol% = holdcutdcol% THEN
  662.                     GOSUB clearmarkers
  663.                 END IF
  664.  
  665.                 b$ = ""
  666.             CASE CHR$(1)
  667.                 GOSUB clearmarkers
  668.                 b$ = CHR$(0) + "u"
  669.                 GOSUB getkeyauto
  670.                 yy% = CSRLIN: xx% = POS(0)
  671.                 mark% = dwidth2 * -scr + 1: markrow% = -scr + 1: markcol% = 1
  672.                 cutmrow% = 1: cutmcol% = 1
  673.                 cutdrow% = noe: cutdcol% = LEN(MID$(x$(noe), 1, INSTR(x$(noe), CHR$(10)) - 1)) + 1
  674.                 col = xx% - margin.l
  675.  
  676.                 GOSUB markercalc
  677.  
  678.                 LOCATE margin.t + 1, margin.l + 1
  679.                 j% = page.h: k% = scr + 1
  680.                 IF noe < page.h THEN j% = noe
  681.                 COLOR h1%, h2%
  682.                 FOR i% = 0 TO j% - 1
  683.                     LOCATE margin.t + 1 + i%, margin.l + 1
  684.                     PRINT MID$(x$(k% + i%), 1, INSTR(x$(k% + i%), CHR$(10)) - 1);
  685.                 NEXT
  686.                 COLOR c1%, c2%
  687.                 LOCATE yy%, xx%
  688.                 b$ = ""
  689.             CASE CHR$(0) + "S", CHR$(24) ' Del and Cut Ctrl + X
  690.                 IF b$ = CHR$(24) THEN GOSUB copytext
  691.                 IF cutmrow% = cutdrow% THEN ' Same line delete.
  692.                     GOSUB singlelinedelete
  693.                     updatescrn% = 1
  694.                     b$ = "exit": EXIT DO
  695.                 ELSE ' Multiple line delete.
  696.                     GOSUB multilinedelete
  697.                     b$ = ""
  698.                 END IF
  699.             CASE CHR$(3) ' Copy Ctrl + C
  700.                 GOSUB copytext
  701.                 b$ = "exit": EXIT DO
  702.             CASE CHR$(22) ' Paste Ctrl + V
  703.                 ' NOTE: col is not defined in these wp routines but is when scrollscrn is called.
  704.                 GOSUB clipboardconvert
  705.                 IF row = 1 AND scr > 0 THEN
  706.                     scr = scr - 1: h% = 0: GOSUB scrollscrn: row = row + 1
  707.                     LOCATE margin.t + row, margin.l + col
  708.                 ELSEIF row = page.h AND scr + page.h < noe THEN
  709.                     scr = scr + 1: h% = 0: GOSUB scrollscrn: row = row - 1
  710.                     LOCATE margin.t + row, margin.l + col
  711.                 END IF
  712.  
  713.                 IF mark% THEN
  714.                     i1% = cutmrow%: j1% = cutmcol%
  715.                     i2% = cutdrow%: j2% = cutdcol%
  716.                     IF cutdrow% < cutmrow% OR cutdrow% = cutmrow% AND cutdcol% < cutmcol% THEN SWAP i1%, i2%: SWAP j1%, j2%
  717.                 ELSE
  718.                     i1% = row + scr: j1% = POS(0) - margin.l
  719.                     i2% = row + scr: j2% = POS(0) - margin.l
  720.                 END IF
  721.                 a1$ = MID$(x$(i1%), 1, INSTR(x$(i1%), CHR$(10)) - 1)
  722.                 a2$ = MID$(a1$, 1, j1% - 1)
  723.                 a1$ = MID$(x$(i2%), 1, INSTR(x$(i2%), CHR$(10)) - 1)
  724.                 a3$ = MID$(a1$, j2%)
  725.                 IF a3$ = "" THEN
  726.                     cur$ = "eod"
  727.                 ELSE
  728.                     cur$ = LEFT$(a3$, 1): MID$(a3$, 1, 1) = CHR$(4)
  729.                 END IF
  730.                 IF row > 1 THEN
  731.                     row = row - 1
  732.                     a1$ = MID$(x$(i1% - 1), 1, INSTR(x$(i1% - 1), CHR$(10)) - 1)
  733.                     a$ = a1$ + a2$ + myCLIPBOARD$ + a3$
  734.                 ELSE
  735.                     a$ = a2$ + myCLIPBOARD$ + a3$
  736.                 END IF
  737.  
  738.                 IF mark% THEN
  739.                     FOR i% = i1% TO i2%
  740.                         x$(i%) = ""
  741.                     NEXT
  742.                 ELSE
  743.                     x$(i1%) = ""
  744.                 END IF
  745.  
  746.                 wrap.on% = -1: GOSUB wrapper
  747.  
  748.                 IF cur$ = "eod" THEN
  749.                     scr = noe - page.h
  750.                     IF scr < 0 THEN scr = 0
  751.                     row = 1
  752.                 ELSE
  753.                     FOR i% = 1 TO noe
  754.                         IF INSTR(x$(i%), CHR$(4)) THEN
  755.                             scr = i% - page.h + 1
  756.                             IF scr < 0 THEN scr = 0
  757.                             row = 1
  758.                             EXIT FOR
  759.                         END IF
  760.                     NEXT
  761.                 END IF
  762.  
  763.                 LOCATE row + margin.t, margin.l + 1
  764.                 filled% = page.h: GOSUB displaydoc
  765.                 GOSUB movescrollbox
  766.                 b$ = ""
  767.         END SELECT
  768.     END IF
  769.  
  770.     IF LEN(b$) OR mhl% THEN
  771.         IF mhl% OR shift% AND INSTR("KMHPOGIQts", MID$(b$, 2, 1)) AND LEN(b$) = 2 THEN
  772.             ' Left mouse button down or Shift key down with a highlighting key pressed.
  773.             IF mark% = 0 THEN
  774.                 col = POS(0) - margin.l
  775.                 mark% = (row - 1) * dwidth2 + col: markrow% = row: markcol% = col ' Highlight cursor position markers.
  776.                 IF cutmrow% = 0 THEN cutmrow% = markrow% + scr: cutmcol% = markcol% ' Marks the entry row and column position for all the cummulative highlighted text and allows this text to be preserved when scrolling.
  777.             END IF
  778.         ELSE
  779.             ' Disable highlight key when active and a key is pressed without Shift key held or
  780.             IF ctrlshift% OR ctrl% AND INSTR("tsuw", MID$(b$, 2, 1)) = 0 THEN
  781.                 b$ = ""
  782.             ELSE
  783.                 IF mark% AND LEN(b$) > 0 THEN ' Highlighted text and key press. Note: Left mouse click to clear text is in another routine.
  784.                     IF b$ <> CHR$(3) AND b$ <> CHR$(22) AND b$ <> CHR$(24) THEN GOSUB hlwipescrn ' Use this or some other routine to clear the highlighted text off the screen.
  785.                 END IF
  786.             END IF
  787.         END IF
  788.  
  789.         IF mhl% AND locked% <> 2 THEN ' Left mouse button click or held highlighting.
  790.             IF my% = CSRLIN THEN
  791.                 ' Lateral movement. Do nothing. Action is taken in the select case mov routine.
  792.             ELSE ' Simulate an up or down arrow key routines for mouse highlighting when changing rows.
  793.                 IF my% < CSRLIN THEN b$ = CHR$(0) + "H" ' Highlight upwards.
  794.                 IF my% > CSRLIN THEN b$ = CHR$(0) + "P" ' Highlight downwards.
  795.             END IF
  796.         END IF
  797.  
  798.         IF keylogger% THEN
  799.             SELECT CASE LEN(b$)
  800.                 CASE 1
  801.                     z$ = LTRIM$(STR$(ASC(b$))) + "|"
  802.                 CASE 2
  803.                     z$ = " " + LTRIM$(STR$(ASC(MID$(b$, 2, 1)))) + "|"
  804.             END SELECT
  805.             keylogger$ = keylogger$ + z$: z$ = ""
  806.         END IF
  807.  
  808.         IF LEN(b$) = 1 OR b$ = CHR$(0) + "S" THEN
  809.             IF row = 1 AND scr > 0 THEN ' Scroll screen down so cursor is on row 2 instead of 1.
  810.                 scr = scr - 1: GOSUB scrollscrn: row = row + 1: LOCATE margin.t + row, POS(0)
  811.             END IF
  812.  
  813.             IF row = page.h AND row + scr < noe THEN ' Scroll screen up so cursor is on row above last row.
  814.                 scr = scr + 1: GOSUB scrollscrn: row = row - 1: LOCATE margin.t + row, POS(0)
  815.             END IF
  816.         END IF
  817.  
  818.         getkeyauto:
  819.         row = CSRLIN - margin.t ' Needed here for auto cursor up / down changes. Also needed at display routine where wrap can make row changes if a word above is wrapped down when backspacing.
  820.         kloop% = 0
  821.         DO
  822.             ' Determine cursor boundaries at end of a text line. --------------
  823.             a$ = MID$(x$(row + scr), 1, INSTR(x$(row + scr), CHR$(10)) - 1)
  824.             IF INSTR(a$, CHR$(255)) THEN ' Special to paragraph.
  825.                 IF INSTR(MID$(a$, 2), CHR$(255)) THEN
  826.                     n% = LEN(a$)
  827.                 END IF
  828.                 IF a$ = CHR$(255) THEN n% = 1
  829.             ELSEIF LEN(a$) > dwidth THEN ' Space in right margin.
  830.                 n% = dwidth + ovm%
  831.             ELSE ' All within margin length situations.
  832.                 IF row + scr < noe THEN ' Rows above last line.
  833.                     n% = LEN(a$)
  834.                 ELSE 'Last line.
  835.                     n% = LEN(a$) + 1
  836.                 END IF
  837.             END IF
  838.  
  839.             n% = n% + margin.l
  840.  
  841.             ' --------------------------------------------------------------------
  842.  
  843.             IF autobkspdel% THEN
  844.                 IF kloop% = LEN(b$) THEN
  845.                     b$ = b$ + CHR$(0) + "S"
  846.                     autobkspdel% = 0
  847.                 END IF
  848.             ELSEIF autodelforward% THEN
  849.                 IF kloop% = LEN(b$) THEN
  850.                     b$ = b$ + CHR$(0) + "S"
  851.                     autodelforward% = 0
  852.                 END IF
  853.             END IF
  854.  
  855.             DO
  856.                 DO
  857.                     reloop% = 0
  858.  
  859.                     IF mhl% AND locked% <> 2 THEN ' Left mouse key highlighting.
  860.  
  861.                         IF row = mhl1row% THEN ' Detect when the row in the loop matches the row marked to terminate the loop.
  862.                             SELECT CASE mhl1col% ' Now that the loop has terminated at the marked row, find the marked column.
  863.                                 CASE 999 ' Column at loop exit is already at the marked column.
  864.                                     mhl% = 0: EXIT DO
  865.                                 CASE ELSE ' Set col variable to mouse column marker and zero out that marker along with the simulated key press.
  866.                                     ' New col position allows highlighter routine to highlight text on this row to this column.
  867.                                     col = mhl1col%: LOCATE , margin.l + col
  868.                                     mhl1col% = 999 ' 0
  869.                                     b$ = CHR$(0) + CHR$(0): kloop% = 0 ' Important. Must nullify variable to avoid case selection below.
  870.                             END SELECT
  871.                         END IF
  872.                     END IF
  873.  
  874.                     IF mark% AND markbypass% = 0 THEN
  875.                         a1$ = MID$(x$(row + scr), 1, INSTR(x$(row + scr), CHR$(10)) - 1)
  876.                         SELECT CASE MID$(b$, 2, 1) ' Cursor movement routine. May be replace or incorporated into outer cursor movement routines.
  877.                             CASE "I"
  878.                                 IF shift% THEN
  879.                                     IF scr > 0 THEN
  880.                                         k% = page.h - 1 ' The number of lines scrolled up. Ex: in a 9-line doc, scroll up 16 lines.
  881.                                         IF k% > scr THEN k% = scr
  882.                                         cutdrow% = row + scr - k%: cutdcol% = 1 ' No need for a reverse condition. Page Up treats them the same. For ref cutmrow% > cutdrow% is forward.
  883.                                         scr = scr - k%
  884.                                         LOCATE margin.t + 1, margin.l + 1
  885.                                         FOR i% = 1 TO page.h
  886.                                             x$ = SPACE$(dwidth + 1)
  887.                                             a1$ = x$(i% + scr)
  888.                                             MID$(x$, 1, dwidth + 1) = MID$(a1$, 1, INSTR(a1$, CHR$(10)) - 1)
  889.                                             LOCATE margin.t + i%, margin.l + 1
  890.                                             PRINT x$;
  891.                                         NEXT
  892.                                         LOCATE margin.t + row, margin.l + 1
  893.                                         GOSUB movescrollbox
  894.                                     ELSE
  895.                                         b$ = ""
  896.                                     END IF
  897.                                 END IF
  898.                             CASE "Q"
  899.                                 IF shift% THEN
  900.                                     IF noe > page.h THEN
  901.                                         k% = (page.h - 1) * 2 ' The number of lines scrolled down. Ex: in a 9-line doc, scroll down 16 lines.
  902.                                         IF k% + scr > noe THEN k% = noe - scr - 1
  903.  
  904.                                         IF cutmrow% < cutdrow% OR cutdrow% = 0 THEN
  905.                                             cutdrow% = row + scr + k% - page.h: cutdcol% = LEN(MID$(x$(row + scr + k% - page.h), 1, INSTR(x$(row + scr + k% - page.h), CHR$(10)) - 1))
  906.                                         ELSE ' Reverse on previously highlighted text.
  907.                                             cutdrow% = row + scr + k% - page.h + 1: cutdcol% = 1
  908.                                         END IF
  909.  
  910.                                         scr = scr + k% - page.h + 1
  911.                                         LOCATE margin.t + 1, margin.l + 1
  912.  
  913.                                         FOR i% = 1 TO page.h
  914.                                             x$ = SPACE$(dwidth + 1)
  915.                                             a1$ = x$(i% + scr)
  916.                                             MID$(x$, 1, dwidth + 1) = MID$(a1$, 1, INSTR(a1$, CHR$(10)) - 1)
  917.                                             LOCATE margin.t + i%, margin.l + 1
  918.                                             PRINT x$;
  919.                                         NEXT
  920.  
  921.                                         hold1% = row: row = CSRLIN - margin.t
  922.                                         GOSUB movescrollbox
  923.                                         LOCATE margin.t + row, margin.l + 1
  924.                                         row = hold1%: col = 1
  925.                                     ELSE ' Doc too small to page down.
  926.                                         b$ = ""
  927.                                     END IF
  928.                                 END IF
  929.                             CASE "H"
  930.                                 IF row > 1 THEN
  931.                                     row = row - 1
  932.                                 ELSE
  933.                                     IF scr > 0 THEN
  934.                                         row = row + 1: scr = scr - 1
  935.                                         h% = 2: GOSUB scrollscrn
  936.                                         row = 1
  937.                                     END IF
  938.                                 END IF
  939.                             CASE "P"
  940.                                 IF row < page.h THEN
  941.                                     IF row + scr < noe THEN row = row + 1
  942.                                 ELSE
  943.                                     IF row + scr < noe% THEN
  944.                                         row = row - 1: scr = scr + 1
  945.                                         h% = page.h - 1: GOSUB scrollscrn
  946.                                         row = page.h
  947.                                     END IF
  948.                                 END IF
  949.                             CASE "M"
  950.                                 IF col < LEN(a1$) OR col = LEN(a1$) AND LEN(a1$) < dwidth + 1 AND row + scr = noe% THEN
  951.                                     col = col + 1
  952.                                 ELSE
  953.                                     IF row < page.h THEN
  954.                                         IF row + scr < noe THEN row = row + 1: col = 1
  955.                                     ELSE
  956.                                         IF row + scr < noe% THEN
  957.                                             row = row - 1: scr = scr + 1
  958.                                             h% = page.h - 1: GOSUB scrollscrn
  959.                                             row = page.h: col = 1
  960.                                             LOCATE margin.t + row, margin.l + col
  961.                                         END IF
  962.                                     END IF
  963.                                 END IF
  964.                             CASE "K"
  965.                                 IF col > 1 THEN
  966.                                     col = col - 1
  967.                                 ELSE
  968.                                     IF row > 1 THEN
  969.                                         row = row - 1
  970.                                         a1$ = MID$(x$(row + scr), 1, INSTR(x$(row + scr), CHR$(10)) - 1)
  971.                                         col = LEN(a1$): IF col < dwidth - 1 THEN col = col + 1
  972.                                         IF LEFT$(a1$, 1) = CHR$(255) THEN col = 1
  973.                                     ELSE
  974.                                         IF scr > 0 THEN
  975.                                             row = row + 1: scr = scr - 1
  976.                                             h% = 2: GOSUB scrollscrn
  977.                                             row = 1: a1$ = MID$(x$(row + scr), 1, INSTR(x$(row + scr), CHR$(10)) - 1)
  978.                                             col = LEN(a1$): IF col < dwidth - 1 THEN col = col + 1
  979.                                             IF LEFT$(a1$, 1) = CHR$(255) THEN col = 1
  980.                                         END IF
  981.                                     END IF
  982.                                 END IF
  983.                             CASE "G"
  984.                                 col = 1
  985.                             CASE "O"
  986.                                 col = LEN(a1$): IF col < dwidth - 1 THEN col = col + 1
  987.                                 IF LEFT$(a1$, 1) = CHR$(255) THEN col = 1
  988.                             CASE "s" ' Arrow left.
  989.                                 c_s_travel% = 0: c_s_tracker% = 0
  990.                                 k% = POS(0) - margin.l
  991.                                 a1$ = MID$(x$(row + scr), k%, 1)
  992.                                 IF a1$ = CHR$(32) THEN
  993.                                     g% = -1 'find the first space after any solid character.
  994.                                 ELSE
  995.                                     IF MID$(x$(row + scr), k% - 1, 1) = CHR$(32) OR k% = 1 THEN
  996.                                         g% = 2
  997.                                     ELSE
  998.                                         g% = 1
  999.                                     END IF
  1000.                                 END IF
  1001.                                 FOR i% = row + scr TO 1 STEP -1
  1002.                                     a1$ = MID$(x$(i%), 1, INSTR(x$(i%), CHR$(10)) - 1)
  1003.                                     FOR j% = k% TO 1 STEP -1
  1004.                                         SELECT CASE g%
  1005.                                             CASE -1
  1006.                                                 IF MID$(a1$, j%, 1) = CHR$(255) AND c_s_travel% > 1 THEN
  1007.                                                     k% = -1: EXIT FOR
  1008.                                                 END IF
  1009.  
  1010.                                                 IF MID$(a1$, j%, 1) <> CHR$(32) THEN
  1011.                                                     c_s_tracker% = c_s_tracker% + 1
  1012.                                                 ELSE
  1013.                                                     IF c_s_tracker% THEN k% = -1: EXIT FOR
  1014.                                                 END IF
  1015.                                             CASE 1
  1016.                                                 IF MID$(a1$, j%, 1) = CHR$(255) AND c_s_travel% > 1 THEN
  1017.                                                     k% = -1: EXIT FOR
  1018.                                                 END IF
  1019.  
  1020.                                                 IF MID$(a1$, j%, 1) = CHR$(32) THEN
  1021.                                                     k% = -1: EXIT FOR
  1022.                                                 END IF
  1023.                                             CASE 2
  1024.                                                 IF MID$(a1$, j%, 1) = CHR$(255) AND c_s_travel% > 1 THEN
  1025.                                                     k% = -1: EXIT FOR
  1026.                                                 ELSE
  1027.                                                     IF MID$(a1$, j%, 1) = CHR$(32) THEN
  1028.                                                         IF c_s_tracker% THEN k% = -1: EXIT FOR
  1029.                                                     ELSE
  1030.                                                         IF c_s_travel% THEN c_s_tracker% = c_s_tracker% + 1
  1031.                                                     END IF
  1032.                                                 END IF
  1033.                                         END SELECT
  1034.                                         c_s_travel% = c_s_travel% + 1
  1035.                                     NEXT j%
  1036.                                     IF k% = -1 THEN EXIT FOR
  1037.                                     k% = LEN(MID$(x$(i% - 1), 1, INSTR(x$(i% - 1), CHR$(10)) - 1))
  1038.                                 NEXT i%
  1039.  
  1040.                                 col = POS(0) - margin.l: a1$ = MID$(x$(row + scr), 1, INSTR(x$(row + scr), CHR$(10)) - 1)
  1041.                                 FOR c_s_index% = 1 TO c_s_travel% - 1
  1042.                                     IF col > 1 THEN
  1043.                                         col = col - 1
  1044.                                     ELSE
  1045.                                         IF row > 1 THEN
  1046.                                             row = row - 1
  1047.                                             a1$ = MID$(x$(row + scr), 1, INSTR(x$(row + scr), CHR$(10)) - 1)
  1048.                                             col = LEN(a1$)
  1049.                                         ELSE
  1050.                                             IF scr > 0 THEN
  1051.                                                 row = row + 1: scr = scr - 1
  1052.                                                 h% = 2: GOSUB scrollscrn
  1053.                                                 row = 1
  1054.                                                 a1$ = MID$(x$(row + scr), 1, INSTR(x$(row + scr), CHR$(10)) - 1)
  1055.                                                 col = LEN(a1$)
  1056.                                             END IF
  1057.                                         END IF
  1058.                                     END IF
  1059.  
  1060.                                     LOCATE margin.t + row, margin.l + col
  1061.  
  1062.                                     GOSUB highlighter
  1063.                                 NEXT
  1064.                                 b$ = "": EXIT DO
  1065.                             CASE "t"
  1066.                                 c_s_travel% = 0: c_s_tracker% = 0
  1067.                                 k% = POS(0) - margin.l
  1068.                                 a1$ = MID$(x$(row + scr), k%, 1)
  1069.                                 IF a1$ = CHR$(32) THEN g% = -1 ELSE g% = 1
  1070.                                 FOR i% = row + scr TO noe
  1071.                                     a1$ = MID$(x$(i%), 1, INSTR(x$(i%), CHR$(10)) - 1)
  1072.                                     FOR j% = k% TO LEN(a1$)
  1073.                                         SELECT CASE g%
  1074.                                             CASE -1
  1075.                                                 IF MID$(a1$, j%, 1) = CHR$(255) AND c_s_travel% THEN
  1076.                                                     k% = -1: EXIT FOR
  1077.                                                 END IF
  1078.                                                 IF MID$(a1$, j%, 1) <> CHR$(32) THEN
  1079.                                                     k% = -1: EXIT FOR
  1080.                                                 ELSE
  1081.                                                     c_s_tracker% = c_s_tracker% + 1
  1082.                                                 END IF
  1083.                                             CASE 1
  1084.                                                 IF MID$(a1$, j%, 1) = CHR$(255) AND c_s_travel% THEN
  1085.                                                     k% = -1: EXIT FOR
  1086.                                                 END IF
  1087.  
  1088.                                                 IF MID$(a1$, j%, 1) = CHR$(32) THEN
  1089.                                                     c_s_tracker% = c_s_tracker% + 1
  1090.                                                 ELSE
  1091.                                                     IF c_s_tracker% THEN k% = -1: EXIT FOR
  1092.                                                 END IF
  1093.                                         END SELECT
  1094.                                         c_s_travel% = c_s_travel% + 1
  1095.                                     NEXT j%
  1096.                                     IF k% = -1 THEN EXIT FOR
  1097.                                     k% = 1
  1098.                                 NEXT i%
  1099.  
  1100.                                 FOR c_s_index% = 1 TO c_s_travel%
  1101.                                     col = POS(0) - margin.l: a1$ = MID$(x$(row + scr), 1, INSTR(x$(row + scr), CHR$(10)) - 1)
  1102.  
  1103.                                     IF col < LEN(a1$) OR col = LEN(a1$) AND LEN(a1$) < dwidth + 1 AND row + scr = noe% THEN
  1104.                                         col = col + 1
  1105.                                     ELSE
  1106.                                         IF row < page.h THEN
  1107.                                             row = row + 1: col = 1
  1108.                                         ELSE
  1109.                                             IF row + scr < noe% THEN
  1110.                                                 row = row - 1: scr = scr + 1
  1111.                                                 h% = page.h - 1: GOSUB scrollscrn
  1112.                                                 row = page.h: col = 1
  1113.                                                 LOCATE margin.t + row, margin.l + col
  1114.                                             END IF
  1115.                                         END IF
  1116.                                     END IF
  1117.                                     LOCATE margin.t + row, margin.l + col
  1118.                                     IF mark% THEN GOSUB highlighter '  Cursor may need to advance after mark% is zeroed in highlighter routine.
  1119.                                 NEXT
  1120.                                 b$ = "": EXIT DO
  1121.                         END SELECT
  1122.  
  1123.                         LOCATE margin.t + row, margin.l + col ' Note: Both row and col variables are relative and must be added to any left or top margin variables to appear in the proper row and column positions on the screen.
  1124.  
  1125.                         IF b$ <> CHR$(0) + "I" AND b$ <> CHR$(0) + "Q" THEN
  1126.                             GOSUB highlighter
  1127.                         ELSE
  1128.                             hold1% = row: GOSUB markercalc: h% = 0: GOSUB scrollscrn
  1129.                             row = hold1%: col = 1
  1130.                             LOCATE margin.t + row, margin.l + col
  1131.                             GOSUB markercalc
  1132.                             GOSUB movescrollbox ' Required. Scrollscrn polls this but the cursor gets repositioned, after that call, in line above.
  1133.                         END IF
  1134.  
  1135.                         a1$ = MID$(x$(row + scr), 1, INSTR(x$(row + scr), CHR$(10)) - 1)
  1136.  
  1137.                         IF col > LEN(a1$) THEN
  1138.                             col = LEN(a1$)
  1139.                             IF col < dwidth - 1 THEN col = col + 1
  1140.                             LOCATE margin.t + row, margin.l + col ' Note: Both row and col variables are relative and must be added to any left or top margin variables to appear in the proper row and column positions on the screen.
  1141.                         END IF
  1142.  
  1143.                         IF b$ = CHR$(0) + CHR$(0) OR mhl% = 0 THEN b$ = "exit-partial": EXIT DO ELSE reloop% = 1 ' Otherwise it loops.
  1144.  
  1145.                     ELSE
  1146.  
  1147.                         SELECT CASE MID$(b$, kloop% + 1, 2)
  1148.                             CASE CHR$(13) ' Paragraph.
  1149.                                 updatescrn% = 1
  1150.                                 k% = POS(0) - (margin.l + border.thk)
  1151.                                 IF k% > dwidth THEN
  1152.                                     ' There is a space in the margin, so leave that space and push the paragraph symbol to the line below.
  1153.                                     a$ = MID$(a$, 1, k%) + CHR$(255) + MID$(a$, k% + 1)
  1154.                                 ELSE
  1155.                                     a$ = MID$(a$, 1, k% - 1) + CHR$(255) + MID$(a$, k%)
  1156.                                 END IF
  1157.  
  1158.                                 ' wrapper is engaged by text line instr() analysis, later.
  1159.                                 curadvance% = -1
  1160.                                 noe = noe + 1: REDIM _PRESERVE x$(noe + 1)
  1161.                                 b$ = "exit"
  1162.                                 EXIT DO
  1163.                             CASE CHR$(0) + "H"
  1164.                                 IF row > 1 THEN
  1165.                                     row = row - 1
  1166.                                     LOCATE margin.t + row, POS(0)
  1167.                                     IF INSTR(x$(row + scr), CHR$(10)) - 1 < POS(0) - margin.l THEN
  1168.                                         IF LEN(b$) = 2 THEN b$ = b$ + CHR$(0) + "O"
  1169.                                     END IF
  1170.                                 ELSEIF scr > 0 THEN
  1171.                                     scr = scr - 1: h% = 0: GOSUB scrollscrn
  1172.                                     IF INSTR(x$(row + scr), CHR$(10)) - 1 < POS(0) - margin.l THEN
  1173.                                         IF LEN(b$) = 2 THEN b$ = b$ + CHR$(0) + "O"
  1174.                                     END IF
  1175.                                 END IF
  1176.                             CASE CHR$(0) + "P"
  1177.                                 IF row < page.h AND row + scr < noe THEN
  1178.                                     row = row + 1
  1179.                                     LOCATE margin.t + row, POS(0)
  1180.                                     IF INSTR(x$(row + scr), CHR$(10)) - 1 < POS(0) - margin.l THEN
  1181.                                         IF LEN(b$) = 2 THEN b$ = b$ + CHR$(0) + "O"
  1182.                                     END IF
  1183.                                 ELSEIF row + scr < noe THEN
  1184.                                     scr = scr + 1
  1185.                                     h% = 0: GOSUB scrollscrn
  1186.                                     IF INSTR(x$(row + scr), CHR$(10)) - 1 < POS(0) - margin.l THEN
  1187.                                         IF LEN(b$) = 2 THEN b$ = b$ + CHR$(0) + "O"
  1188.                                     END IF
  1189.                                 ELSEIF row + scr = noe AND LEN(a$) > dwidth OR row + scr = noe AND INSTR(a$, CHR$(255)) THEN ' On last filled text line.
  1190.                                     IF noe = UBOUND(x$) OR row = page.h THEN
  1191.                                         noe = noe + 1
  1192.                                         REDIM _PRESERVE x$(noe)
  1193.                                         scr = scr + 1: h% = 0: GOSUB scrollscrn
  1194.                                     ELSE
  1195.                                         row = row + 1
  1196.                                         GOSUB movescrollbox
  1197.                                     END IF
  1198.                                     LOCATE margin.t + row, margin.l + 1
  1199.                                 END IF
  1200.                             CASE CHR$(0) + "s" ' Arrow left.
  1201.                                 c_s_travel% = 0: c_s_tracker% = 0
  1202.                                 k% = POS(0) - margin.l
  1203.                                 a1$ = MID$(x$(row + scr), k%, 1)
  1204.                                 IF a1$ = CHR$(32) THEN
  1205.                                     g% = -1 'find the first space after any solid character.
  1206.                                 ELSE
  1207.                                     IF MID$(x$(row + scr), k% - 1, 1) = CHR$(32) OR k% = 1 THEN
  1208.                                         g% = 2
  1209.                                     ELSE
  1210.                                         g% = 1
  1211.                                     END IF
  1212.                                 END IF
  1213.                                 FOR i% = row + scr TO 1 STEP -1
  1214.                                     a1$ = MID$(x$(i%), 1, INSTR(x$(i%), CHR$(10)) - 1)
  1215.                                     FOR j% = k% TO 1 STEP -1
  1216.                                         SELECT CASE g%
  1217.                                             CASE -1
  1218.                                                 IF MID$(a1$, j%, 1) = CHR$(255) AND c_s_travel% > 1 THEN
  1219.                                                     k% = -1: EXIT FOR
  1220.                                                 ELSE
  1221.                                                     IF MID$(a1$, j%, 1) <> CHR$(32) THEN
  1222.                                                         c_s_tracker% = c_s_tracker% + 1
  1223.                                                     ELSE
  1224.                                                         IF c_s_tracker% THEN k% = -1: EXIT FOR
  1225.                                                     END IF
  1226.                                                 END IF
  1227.                                             CASE 1
  1228.                                                 IF MID$(a1$, j%, 1) = CHR$(255) AND c_s_travel% > 1 THEN
  1229.                                                     k% = -1: EXIT FOR
  1230.                                                 ELSE
  1231.                                                     IF MID$(a1$, j%, 1) = CHR$(32) THEN
  1232.                                                         k% = -1: EXIT FOR
  1233.                                                     END IF
  1234.                                                 END IF
  1235.                                             CASE 2
  1236.                                                 IF MID$(a1$, j%, 1) = CHR$(255) AND c_s_travel% > 1 THEN
  1237.                                                     k% = -1: EXIT FOR
  1238.                                                 ELSE
  1239.                                                     IF MID$(a1$, j%, 1) = CHR$(32) THEN
  1240.                                                         IF c_s_tracker% THEN k% = -1: EXIT FOR
  1241.                                                     ELSE
  1242.                                                         IF c_s_travel% THEN c_s_tracker% = c_s_tracker% + 1
  1243.                                                     END IF
  1244.                                                 END IF
  1245.                                         END SELECT
  1246.                                         c_s_travel% = c_s_travel% + 1
  1247.                                     NEXT j%
  1248.                                     IF k% = -1 THEN EXIT FOR
  1249.                                     k% = LEN(MID$(x$(i% - 1), 1, INSTR(x$(i% - 1), CHR$(10)) - 1))
  1250.                                 NEXT i%
  1251.  
  1252.                                 FOR c_s_index% = 1 TO c_s_travel% - 1: autokey = -1: b$ = CHR$(0) + "K": GOSUB getkeyauto: NEXT
  1253.                             CASE CHR$(0) + "t"
  1254.                                 c_s_travel% = 0: c_s_tracker% = 0
  1255.                                 k% = POS(0) - margin.l
  1256.                                 a1$ = MID$(x$(row + scr), k%, 1)
  1257.                                 IF a1$ = CHR$(32) THEN g% = -1 ELSE g% = 1
  1258.                                 FOR i% = row + scr TO noe
  1259.                                     a1$ = MID$(x$(i%), 1, INSTR(x$(i%), CHR$(10)) - 1)
  1260.                                     FOR j% = k% TO LEN(a1$)
  1261.                                         SELECT CASE g%
  1262.                                             CASE -1
  1263.                                                 IF MID$(a1$, j%, 1) = CHR$(255) AND c_s_travel% THEN
  1264.                                                     k% = -1: EXIT FOR
  1265.                                                     IF MID$(a1$, j%, 1) <> CHR$(32) THEN
  1266.                                                         k% = -1: EXIT FOR
  1267.                                                     ELSE
  1268.                                                         c_s_tracker% = c_s_tracker% + 1
  1269.                                                     END IF
  1270.                                                 END IF
  1271.                                             CASE 1
  1272.                                                 IF MID$(a1$, j%, 1) = CHR$(255) AND c_s_travel% THEN
  1273.                                                     k% = -1: EXIT FOR
  1274.                                                 ELSE
  1275.                                                     IF MID$(a1$, j%, 1) = CHR$(32) THEN
  1276.                                                         c_s_tracker% = c_s_tracker% + 1
  1277.                                                     ELSE
  1278.                                                         IF c_s_tracker% THEN k% = -1: EXIT FOR
  1279.                                                     END IF
  1280.                                                 END IF
  1281.                                         END SELECT
  1282.                                         c_s_travel% = c_s_travel% + 1
  1283.                                     NEXT j%
  1284.                                     IF k% = -1 THEN EXIT FOR
  1285.                                     k% = 1
  1286.                                 NEXT i%
  1287.  
  1288.                                 FOR c_s_index% = 1 TO c_s_travel%: autokey = -1: b$ = CHR$(0) + "M": GOSUB getkeyauto: NEXT
  1289.                             CASE CHR$(0) + "K"
  1290.                                 IF POS(0) > margin.l + 1 + border.thk THEN
  1291.                                     LOCATE , POS(0) - 1
  1292.                                 ELSE
  1293.                                     IF row = 1 AND scr = 0 THEN
  1294.                                         ' Do nothing.
  1295.                                     ELSE
  1296.                                         b$ = b$ + CHR$(0) + "H" + CHR$(0) + "O"
  1297.                                     END IF
  1298.                                 END IF
  1299.                             CASE CHR$(0) + "M"
  1300.                                 IF POS(0) < n% THEN
  1301.                                     LOCATE , POS(0) + 1
  1302.                                 ELSE
  1303.                                     IF row + scr < noe OR row + scr = noe AND LEN(a$) > dwidth OR row + scr = noe AND INSTR(a$, CHR$(255)) THEN
  1304.                                         b$ = b$ + CHR$(0) + "P" + CHR$(0) + "G"
  1305.                                     END IF
  1306.                                 END IF
  1307.                             CASE CHR$(0) + "I"
  1308.                                 LOCATE , margin.l + 1
  1309.                                 k% = page.h - 1 + row - 2
  1310.                                 FOR j% = 0 TO k%
  1311.                                     b$ = b$ + CHR$(0) + "H"
  1312.                                 NEXT
  1313.                                 FOR j% = 1 TO row - 1
  1314.                                     b$ = b$ + CHR$(0) + "P"
  1315.                                 NEXT
  1316.                                 b$ = b$ + CHR$(0) + "G"
  1317.                             CASE CHR$(0) + "Q"
  1318.                                 LOCATE , margin.l + 1
  1319.                                 k% = (page.h - 1) + (page.h - row) - 1
  1320.                                 FOR j% = 0 TO k%
  1321.                                     b$ = b$ + CHR$(0) + "P"
  1322.                                 NEXT
  1323.                                 FOR j% = 1 TO page.h - row
  1324.                                     b$ = b$ + CHR$(0) + "H"
  1325.                                 NEXT
  1326.                                 b$ = b$ + CHR$(0) + "G"
  1327.                             CASE CHR$(0) + "G" ' Cursor home on current line.
  1328.                                 LOCATE , margin.l + 1
  1329.                             CASE CHR$(0) + "O" ' Cursor end on current line.
  1330.                                 IF kloop% = 0 THEN ' User key press.
  1331.                                     IF row + scr < noe AND n% - margin.l <= dwidth AND INSTR(a$, CHR$(255)) = 0 THEN
  1332.                                         LOCATE , n% + 1 ' Allows more text to be added to the line in front of the last character.
  1333.                                     ELSE ' last line
  1334.                                         LOCATE , n%
  1335.                                     END IF
  1336.                                 ELSE ' Automated cursor advance. For these routines, the cursor never goes past last character.
  1337.                                     LOCATE , n%
  1338.                                 END IF
  1339.                             CASE CHR$(0) + "w" ' Ctrl + Home
  1340.                                 row = 1
  1341.                                 IF scr > 0 THEN
  1342.                                     scr = 0
  1343.                                     h% = 0: GOSUB scrollscrn
  1344.                                 END IF
  1345.                                 LOCATE margin.t + 1, margin.l + 1
  1346.                             CASE CHR$(0) + "u" ' Ctrl + End
  1347.                                 IF noe > page.h THEN
  1348.                                     row = page.h
  1349.                                     scr = noe - row
  1350.                                     LOCATE margin.t + 1, margin.l + 1
  1351.                                     h% = 0: GOSUB scrollscrn
  1352.                                     LOCATE margin.t + page.h, margin.l + dwidth
  1353.                                 ELSE
  1354.                                     row = noe
  1355.                                     LOCATE margin.t + row, margin.l + dwidth
  1356.                                 END IF
  1357.                                 IF LEN(MID$(x$(row + scr), 1, INSTR(x$(row + scr), CHR$(10)) - 1)) = dwidth + 1 THEN b$ = b$ + CHR$(0) + "P"
  1358.                                 b$ = b$ + CHR$(0) + "O"
  1359.                             CASE CHR$(0) + "R"
  1360.                                 IF ins% = 30 THEN ins% = 7 ELSE ins% = 30
  1361.                                 LOCATE , , 1, 7, ins%
  1362.                             CASE CHR$(9)
  1363.                                 RUN
  1364.                             CASE CHR$(27)
  1365.                                 SYSTEM
  1366.                             CASE CHR$(0) + "S"
  1367.                                 IF row = 1 AND scr = 0 THEN IF INSTR(x$(1), CHR$(10)) <= 0 THEN b$ = "": EXIT DO
  1368.                                 updatescrn% = 1
  1369.                                 IF POS(0) - margin.l > LEN(a$) AND row + scr < noe THEN
  1370.                                     b$ = "**" + CHR$(0) + "G" + CHR$(0) + "P": autodelforward% = -1
  1371.                                 ELSE ' delete the character under the cursor.
  1372.                                     a$ = MID$(a$, 1, POS(0) - margin.l - 1) + MID$(a$, POS(0) - margin.l + 1)
  1373.                                     IF a$ = "" AND INSTR(x$(row + scr), CHR$(10)) <= 1 THEN '
  1374.                                         ' Take no action. blank doc.
  1375.                                     ELSE ' Delete character from current cursor position.
  1376.                                         IF MID$(a$, POS(0) - margin.l, 1) = "" THEN
  1377.                                             IF row + scr < noe THEN ' The furthest right character on the line was deleted, and now the cursor must be positioned at the start of the next line, otherwise cur$ would be null.
  1378.                                                 '1 of 2 places CUR$ replacement is set. >>>
  1379.                                                 cur$ = LEFT$(x$(row + scr + 1), 1): MID$(x$(row + scr + 1), 1, 1) = CHR$(4)
  1380.                                             ELSE
  1381.                                                 IF row + scr > 1 THEN
  1382.                                                     cur$ = "eod"
  1383.                                                 ELSE
  1384.                                                     ' Do nothing. Single line no wrap possible.
  1385.                                                 END IF
  1386.                                             END IF
  1387.                                         ELSE ' character deleted was at or between the first and next to the last character on the line.
  1388.                                             cur$ = MID$(a$, POS(0) - margin.l, 1): MID$(a$, POS(0) - margin.l, 1) = CHR$(4)
  1389.                                         END IF
  1390.                                         b$ = "exit": EXIT DO
  1391.                                     END IF
  1392.                                 END IF
  1393.                             CASE CHR$(8)
  1394.                                 IF POS(0) = margin.l + 1 AND row = 1 AND scr = 0 THEN
  1395.                                     ' First character of doc. Do not delete using backspace.
  1396.                                 ELSE
  1397.                                     b$ = "**" + CHR$(0) + "K": autobkspdel% = -1
  1398.                                 END IF
  1399.                             CASE CHR$(32) TO CHR$(127)
  1400.                                 updatescrn% = 1
  1401.                                 j% = POS(0)
  1402.                                 k% = j% - (margin.l + border.thk)
  1403.                                 ' 1 of 2 places CUR$ replacement is set. >>>
  1404.                                 SELECT CASE ins%
  1405.                                     CASE 30 'Overwrite
  1406.                                         cur$ = b$
  1407.                                         IF k% <= LEN(a$) AND k% <= dwidth THEN
  1408.                                             MID$(a$, k%, 1) = CHR$(4) ' Display occurs in FOR/NEXT print to screen routine.
  1409.                                         ELSEIF j% = margin.l + dwidth + 1 THEN
  1410.                                             IF RIGHT$(a$, 1) = CHR$(32) AND LEN(a$) = dwidth + 1 THEN
  1411.                                                 MID$(a$, k%, 1) = CHR$(4)
  1412.                                             ELSE
  1413.                                                 a$ = a$ + CHR$(4)
  1414.                                                 IF row + scr < noe AND INSTR(x$(row + scr + 1), CHR$(10)) - 1 > 1 THEN
  1415.                                                     x$(row + scr + 1) = MID$(x$(row + scr + 1), 2)
  1416.                                                 END IF
  1417.                                             END IF
  1418.                                         ELSE
  1419.                                             a$ = a$ + CHR$(4)
  1420.                                         END IF
  1421.                                         curadvance% = 1: b$ = "exit"
  1422.                                         EXIT DO
  1423.                                     CASE 7 ' Insert
  1424.                                         cur$ = b$
  1425.                                         a$ = MID$(a$, 1, k% - 1) + CHR$(4) + MID$(a$, k%)
  1426.                                         curadvance% = 1: b$ = "exit"
  1427.                                         EXIT DO
  1428.                                 END SELECT
  1429.  
  1430.                             CASE CHR$(0) + ">"
  1431.                                 IF POS(0) - (margin.l + border.thk) < dwidth + 1 THEN
  1432.                                     LOCATE , POS(0) + 1
  1433.                                     b$ = "exit"
  1434.                                 ELSE
  1435.                                     IF row + scr < noe OR row + scr = noe AND LEN(a$) > dwidth THEN
  1436.                                         b$ = b$ + CHR$(0) + "P" + CHR$(0) + "G"
  1437.                                     END IF
  1438.                                 END IF
  1439.                             CASE CHR$(0) + "^"
  1440.                                 IF row = page.h THEN
  1441.                                     scr = scr + 1
  1442.                                     GOSUB scrollscrn
  1443.                                 ELSE
  1444.                                     row = row + 1
  1445.                                     GOSUB movescrollbox
  1446.                                 END IF
  1447.  
  1448.                                 LOCATE margin.t + row, margin.l + 1
  1449.                                 b$ = "exit"
  1450.  
  1451.                             CASE CHR$(0) + CHR$(0)
  1452.                                 b$ = "exit-partial"
  1453.                             CASE ""
  1454.                                 b$ = "exit": EXIT DO
  1455.                         END SELECT
  1456.  
  1457.                         row = CSRLIN - margin.t
  1458.  
  1459.                         kloop% = kloop% + 2
  1460.                         IF kloop% > 4 AND curadvance% THEN b$ = "exit": EXIT DO ' Allow a coming return back to the curadvance gosub getkeyauto line.
  1461.  
  1462.                     END IF ' mark% vs non-mark%
  1463.  
  1464.                 LOOP WHILE reloop%
  1465.  
  1466.             LOOP UNTIL mhl% = 0
  1467.  
  1468.             IF MID$(b$, 1, 4) = "exit" THEN EXIT DO ' exit and exit-partial exits here.
  1469.         LOOP
  1470.         IF b$ = "exit-partial" THEN b$ = ""
  1471.  
  1472.     END IF
  1473.  
  1474.     IF b$ = "exit" THEN b$ = "": EXIT DO
  1475.  
  1476.     ' Audit Mouse Routines ====================================================
  1477.     DO
  1478.         mb.w = 0
  1479.         WHILE _MOUSEINPUT
  1480.             mb.w = mb.w + _MOUSEWHEEL
  1481.         WEND
  1482.  
  1483.         IF mb.w = 0 THEN
  1484.             mx% = _MOUSEX ' Mouse column.
  1485.             my% = _MOUSEY ' Mouse row.
  1486.             mb.l = _MOUSEBUTTON(1)
  1487.             mb.r = _MOUSEBUTTON(2)
  1488.             mb.m = _MOUSEBUTTON(3)
  1489.         END IF
  1490.  
  1491.         IF locked% < 0 THEN ' Mouse effects on mouse lock. key press effects are determined at inkey$ input, as key variable cannot be evaluated here, due to b$ = "" manipulations in the keypress routine.
  1492.             IF mb.l OR mb.r OR mb.m THEN locked% = 0
  1493.         END IF
  1494.  
  1495.         IF mb.w THEN ' Determine if wheel is being used to scroll highlighted or unhighlighted text.
  1496.             IF shift% THEN
  1497.                 locked% = -1
  1498.                 mhl1row% = row: mhl1col% = col: mhl1% = (row - 1) * dwidth2 + col
  1499.             ELSE
  1500.                 locked% = 2 ' 2 is lock scrollbar, no highlighting permitted.
  1501.             END IF
  1502.         END IF
  1503.  
  1504.         IF mb.l AND locked% <> 1 OR mb.w AND locked% <> -1 THEN
  1505.             ' Scrollbar routine.
  1506.             IF mx% >= scrb.l - 1 AND mx% <= scrb.l + 1 AND my% - (scrb.t + 1) >= scrb.x AND my% - (scrb.t + 1) <= scrb.x + scrb.s - 1 THEN draglock% = -1
  1507.             IF draglock% = -1 AND my% > scrb.t AND my% < scrb.b OR mx% = scrb.l AND scrb.s <> 0 AND my% >= scrb.t AND my% <= scrb.b AND mb.w = 0 OR scrbardrag% <> 0 AND my% > scrb.t AND my% < scrb.b AND mb.w = 0 OR mb.w > 0 AND scrb.x + scrb.s < scrb.h OR mb.w < 0 AND scrb.x > 0 THEN ' Mouse on scrollbar, doing a bar cursor drag or using the scroll wheel.
  1508.                 locked% = 2 ' Locked on scrollbar
  1509.                 IF my% = scrb.t AND scrb.x > 0 OR my% = scrb.b AND scrb.x + scrb.s < scrb.h OR mb.w <> 0 THEN ' Mouse on a scrollbar arrow.
  1510.                     IF my% = scrb.t AND mb.w = 0 OR mb.w < 0 THEN scrb.x = scrb.x - 1: h% = -1 ELSE scrb.x = scrb.x + 1: h% = -2 ' Top or bottom arrow.
  1511.                     IF mb.w = 0 THEN delay.on! = .15
  1512.                     j% = INT(scrb.x * ((noe - scrb.d) / (scrb.h - scrb.s)))
  1513.  
  1514.                     IF j% >= 0 THEN ' Condition exists unless j% is negative such as doc is blank and mouse wheel is rolled downward.
  1515.                         scrb.i = j%
  1516.  
  1517.                         IF mark% = 0 THEN h% = 0 ' h% was assigned a few lines up but gets zeroed here if there is no highlighting.
  1518.  
  1519.                         scr = scrb.i
  1520.  
  1521.                         GOSUB makescrb ' Positions scrollbar box.
  1522.  
  1523.                         GOSUB scrollscrn
  1524.                     END IF
  1525.  
  1526.                 ELSEIF my% - (scrb.t + 1) >= scrb.x AND my% - (scrb.t + 1) <= scrb.x + scrb.s - 1 AND scrbardrag% = 0 THEN ' Mouse on scrollbar block.
  1527.                     scrbardrag% = -1: scrb.adjust = (my% - (scrb.t + 1)) - scrb.x
  1528.                 ELSEIF draglock% = -1 AND my% > scrb.t AND my% < scrb.b OR my% > scrb.t AND my% < scrb.b THEN ' Mouse on scrollbar between scrollbar arrow and cursor.
  1529.                     IF draglock% = -1 AND my% > scrb.t AND my% < scrb.b OR my% - (scrb.t + 1) - scrb.adjust >= 0 AND my% - (scrb.t + 1) + scrb.s - scrb.adjust <= scrb.h AND scrbardrag% <> -1 OR scrbardrag% = 0 THEN
  1530.                         IF scrbardrag% = 0 THEN ' No drag, so adjust for cursor length for a click inside the scrollbar above or below the current scrollbar cursor position.
  1531.                             IF my% - (scrb.t + 1) > scrb.x THEN
  1532.                                 scrb.adjust = (my% - (scrb.t + 1)) - scrb.x - 1: h% = -1
  1533.                             ELSE
  1534.                                 scrb.adjust = (my% - (scrb.t + 1)) - scrb.x + 1: h% = -2
  1535.                             END IF
  1536.                         END IF
  1537.                         scrb.x = my% - (scrb.t + 1) - scrb.adjust
  1538.                         scrb.i = INT(scrb.x * ((noe - scrb.d) / (scrb.h - scrb.s)))
  1539.  
  1540.                         IF mark% = 0 THEN h% = 0 ' h% was assigned a few lines up but gets zeroed here if there is no highlighting.
  1541.  
  1542.                         scr = scrb.i
  1543.  
  1544.                         GOSUB makescrb
  1545.  
  1546.                         GOSUB scrollscrn
  1547.  
  1548.                     ELSE ' Scrollbar is at top or bottom and mouse cursor is moving vertically along the scrollbar cursor. This allows the variable to readjust.
  1549.                         IF mx% = scrb.l THEN scrbardrag% = 0: scrb.adjust = 0: draglock% = 0
  1550.                     END IF
  1551.                 END IF
  1552.                 ' =======================================================
  1553.  
  1554.                 IF scr < cursor.top OR scr > cursor.bot THEN
  1555.                     LOCATE , , 0: curhide% = -1
  1556.                 ELSE
  1557.                     IF mark% = 0 THEN
  1558.                         IF row + scr <> cursor.scbrrow AND cursor.scbrrow <> 0 THEN
  1559.                             row = cursor.scbrrow - scr
  1560.                             LOCATE margin.t + row, POS(0)
  1561.                         END IF
  1562.                         LOCATE , , 1: curhide% = 0
  1563.                     ELSE
  1564.                         LOCATE , , 1: curhide% = 0
  1565.                     END IF
  1566.                 END IF
  1567.  
  1568.             END IF
  1569.  
  1570.             IF delay.on! THEN ' Scrollbar delay.
  1571.                 _DELAY delay.on!
  1572.                 delay.on! = 0 ' Toggle off.
  1573.             END IF
  1574.  
  1575.             IF locked% = 2 THEN EXIT DO
  1576.         ELSE
  1577.             scrbardrag% = 0: scrb.adjust = 0: draglock% = 0
  1578.             IF locked% = 2 AND mb.l = 0 THEN locked% = 0
  1579.         END IF
  1580.  
  1581.         IF mb.w AND locked% = -1 THEN ' shift key down. Mouse wheel highlighting.
  1582.             IF mb.w > 0 THEN
  1583.                 b$ = CHR$(0) + "P"
  1584.             ELSE
  1585.                 b$ = CHR$(0) + "H"
  1586.             END IF
  1587.             autokey% = -1 ' Note: Gosub getkeyauto will not work here.
  1588.             EXIT DO
  1589.         END IF
  1590.  
  1591.         IF mb.l THEN
  1592.             IF mx% > margin.l AND mx% <= margin.l + dwidth + 1 AND my% >= margin.t + 1 AND my% <= margin.t + page.h OR mark% <> 0 AND locked% = 1 OR mark% <> 0 AND locked% = 3 THEN ' Cursor in-bounds.
  1593.                 IF curhide% THEN curhide% = 0: row = my% - margin.t: col = mx% - margin.l: LOCATE margin.t + row, margin.l + col, 1: EXIT DO
  1594.                 j% = 0: ii2% = my% - margin.t
  1595.                 IF ii2% < 1 THEN
  1596.                     ii2% = 1
  1597.                     j% = -1
  1598.                     locked% = 3
  1599.                 ELSEIF ii2% > noe THEN
  1600.                     ii2% = noe
  1601.                     j% = 1
  1602.                     locked% = 3
  1603.                 ELSEIF ii2% > page.h THEN
  1604.                     ii2% = page.h
  1605.                     j% = 1
  1606.                     locked% = 3
  1607.                 END IF
  1608.  
  1609.                 a1$ = MID$(x$(ii2% + scr), 1, INSTR(x$(ii2% + scr), CHR$(10)) - 1)
  1610.  
  1611.                 mxalt% = mx%
  1612.                 IF mx% < margin.l + 1 THEN mxalt% = margin.l + 1
  1613.                 IF mx% > margin.l + LEN(a1$) THEN
  1614.                     mxalt% = margin.l + LEN(a1$) + 1
  1615.                     IF mxalt% - margin.l > dwidth + 1 THEN mxalt% = margin.l + dwidth + 1
  1616.                 END IF
  1617.                 IF INSTR(a1$, CHR$(255)) THEN
  1618.                     IF LEFT$(a1$, 1) = CHR$(255) THEN
  1619.                         mxalt% = margin.l + 1
  1620.                     ELSE
  1621.                         IF mx% - margin.l > LEN(a1$) THEN maxalt% = margin.l + LEN(a1$) - 1
  1622.                     END IF
  1623.                 END IF
  1624.  
  1625.                 IF my% > margin.t + page.h OR my% < margin.t + 1 THEN
  1626.                     IF mark% THEN
  1627.                         IF j% = -1 THEN
  1628.                             IF scr > 0 THEN
  1629.                                 col = mxalt% - margin.l
  1630.                                 LOCATE margin.t + ii2%, margin.l + col
  1631.                                 row = row + 1: scr = scr - 1
  1632.                                 h% = 2: GOSUB scrollscrn
  1633.                                 row = CSRLIN - margin.t
  1634.                             END IF
  1635.                         ELSE
  1636.                             IF ii2% + scr < noe% THEN
  1637.                                 col = mxalt% - margin.l
  1638.                                 LOCATE margin.t + ii2%, margin.l + col
  1639.                                 row = row - 1: scr = scr + 1
  1640.                                 h% = page.h - 1: GOSUB scrollscrn
  1641.                                 row = CSRLIN - margin.t
  1642.                             END IF
  1643.                         END IF
  1644.                     END IF
  1645.                 END IF
  1646.  
  1647.                 IF mhlclear% THEN ' Check to see if highlighting should be removed.
  1648.                     IF shift% THEN ' Do not remove highlighted text.
  1649.                         mhlclear% = 0
  1650.                     ELSE
  1651.                         GOSUB hlwipescrn ' Remove highlighted text.
  1652.                     END IF
  1653.                 END IF
  1654.  
  1655.                 IF shift% OR (ii2% - 1) * dwidth2 + mxalt% - margin.l <> mhl1% AND mhl1% <> 0 THEN
  1656.                     mhl% = -1 ' Left mouse key highlighting enabled when Shift key held and left mouse button click or when Shift held or not held if left mouse button is held while changing row/column (drag).
  1657.                     locked% = 1
  1658.                     mhl1row% = ii2%: mhl1col% = mxalt% - margin.l: mhl1% = (ii2% - 1) * dwidth2 + mxalt% - margin.l
  1659.                     EXIT DO
  1660.                 ELSE
  1661.                     IF mhl1% <> (ii2% - 1) * dwidth2 + mxalt% - margin.l THEN
  1662.                         mhl1% = (ii2% - 1) * dwidth2 + mxalt% - margin.l
  1663.                         row = ii2%: col = mxalt% - margin.l
  1664.                         LOCATE margin.t + row, margin.l + col
  1665.                         curhide% = 0: GOSUB getcurinfo: LOCATE , , 1
  1666.                     END IF
  1667.                 END IF
  1668.             END IF
  1669.         ELSE
  1670.             mhl1% = 0 ' Left mouse button not engaged so zero the highlighting marker.
  1671.             IF locked% AND mb.w = 0 THEN locked% = 0 ' Undo mouse lock unless mouse wheel is in current use.
  1672.             IF mark% THEN mhlclear% = -1 ' Will be triggered the next time the left mouse button is pressed to remove all highlighted text.
  1673.         END IF
  1674.         EXIT DO
  1675.     LOOP ' Mouse loop terminates here.
  1676.  
  1677. IF noe < row + scr THEN noe = row + scr
  1678. RETURN ' ==================================================================
  1679.  
  1680. '==========================================================================
  1681. '                                  NOTES
  1682.     INSTR(x$(c%), CHR$(10)) > 1 Indicates an array with text.
  1683.     INSTR(x$(row + scr), CHR$(10)) <= 1 Indicates an array without text.
  1684.     Value = 0: (Valid)   Array is empty with no EOL.
  1685.     Value = 1: (Invalid) Array is empty but has a EOL added. This should not be present, but I think it occurs when a line is initially erased. This needs more investigation.
  1686.     Value > 1: (Valid)   Array contains text.
  1687. '==========================================================================
  1688.  
  1689. getvar_setscrn:
  1690. scrn.w = _WIDTH
  1691. scrn.h = _HEIGHT
  1692. scrb.x = 0 ' Relative position of the scrollbar cursor from top of scrb.h. 0 Off / 1 to
  1693. page.w = scrn.w - (margin.l + margin.r)
  1694. page.h = scrn.h - (margin.t + margin.b)
  1695. scrb.t = margin.t + 1
  1696. scrb.b = margin.t + page.h
  1697. scrb.l = margin.l + page.w + 2
  1698. page.w = scrn.w - (margin.l + margin.r)
  1699. page.h = scrn.h - (margin.t + margin.b)
  1700. scrb.d = scrb.b - scrb.t + 1
  1701. scrb.h = scrb.b - scrb.t - 1 ' Max. vertical scroll. Bar minus the top and bottom arrow symbols.
  1702.  
  1703. IF noe THEN
  1704.     a$ = "": row = 1: scr = 0
  1705.     FOR i% = 1 TO noe
  1706.         a$ = a$ + MID$(x$(i%), 1, INSTR(x$(i%), CHR$(10)) - 1)
  1707.     NEXT
  1708.     wrap.on% = -1: GOSUB wrapper
  1709.     noe = filled%: filled% = 0
  1710.  
  1711. WIDTH scrn.w, scrn.h: CLS
  1712. LOCATE margin.t + 1, margin.l + 1, 1, 7, ins%
  1713. row = CSRLIN - margin.t: scr = 0
  1714. filled% = noe
  1715.  
  1716. IF page.h > noe THEN
  1717.     scrb.s = 0 ' No scroll box required.
  1718.     IF scrb.opt = 0 THEN
  1719.         scrb.s = (scrb.h + 1) * 2 - noe: IF scrb.s <= 0 THEN scrb.s = 1
  1720.     ELSE
  1721.         scrb.s = 1
  1722.     END IF
  1723.  
  1724. IF row = 0 THEN row = 1
  1725. IF page.c = 0 THEN page.c = 7 ' Cursor apearance as underline.
  1726.  
  1727. GOSUB displaydoc
  1728.  
  1729. LOCATE margin.t + row, margin.l + 1, 1, 7, page.c
  1730.  
  1731. movescrollbox:
  1732. IF page.h > noe THEN
  1733.     scrb.s = 0 ' No scroll box required.
  1734.     RETURN ' Required to prevent unhandled conditions in scrollbar box movement.
  1735.     IF scrb.opt = 0 THEN
  1736.         scrb.s = (scrb.h + 1) * 2 - noe: IF scrb.s <= 0 THEN scrb.s = 1
  1737.     ELSE
  1738.         scrb.s = 1
  1739.     END IF
  1740. IF scr = 0 THEN
  1741.     scrb.x = 0
  1742.     IF scrb.x < page.h - 3 AND row + scr >= INT((scrb.x + 1) * ((noe - scrb.d) / (scrb.h - scrb.s))) + page.h THEN
  1743.         scrb.x = 0
  1744.         DO UNTIL scrb.x = scrb.h - scrb.s OR page.h + scr < INT((scrb.x + 1) * ((noe - scrb.d) / (scrb.h - scrb.s))) + page.h
  1745.             scrb.x = scrb.x + 1
  1746.         LOOP
  1747.  
  1748.     ELSEIF row + scr < scrb.i THEN
  1749.         scrb.x = page.h - 3
  1750.         DO UNTIL page.h + scr > INT((scrb.x + 1 - 2) * ((noe - scrb.d) / (scrb.h - scrb.s))) + page.h
  1751.             scrb.x = scrb.x - 1
  1752.         LOOP
  1753.     END IF
  1754.  
  1755. IF scrb.x + scrb.s > scrb.h THEN ' Scrollbox expansion adjustment.
  1756.     scrb.x = scrb.h - scrb.s
  1757.  
  1758. GOSUB makescrb
  1759.  
  1760. scrb.i = INT(scrb.x * ((noe - scrb.d) / (scrb.h - scrb.s)))
  1761.  
  1762. makescrb:
  1763. yy% = CSRLIN: xx% = POS(0)
  1764. LOCATE scrb.t, scrb.l
  1765. COLOR 0, 7
  1766. PRINT CHR$(24);
  1767. COLOR 7, 0
  1768. FOR i% = 1 TO scrb.h
  1769.     LOCATE scrb.t + i%, scrb.l
  1770.     PRINT CHR$(177);
  1771. NEXT i%
  1772. LOCATE scrb.b, scrb.l
  1773. COLOR 0, 7
  1774. PRINT CHR$(25);
  1775. COLOR 7, 0
  1776. IF noe > scrb.h + 2 THEN
  1777.     FOR i% = 1 TO scrb.s
  1778.         LOCATE scrb.t + scrb.x + i%, scrb.l
  1779.         COLOR 1, 0
  1780.         PRINT CHR$(176); ' Scrollbar box.
  1781.     NEXT
  1782.     COLOR 7, 0
  1783. LOCATE yy%, xx%
  1784.  
  1785. getcurinfo:
  1786. cursor.scbrrow = row + scr
  1787. cursor.scbrcol = POS(0) - margin.l
  1788. cursor.holdscr = scr
  1789. cursor.holdrow = row
  1790. cursor.top = scr - page.h + row
  1791. cursor.bot = scr + row - 1
  1792. cursor.holdscrbx = scrb.x
  1793.  
  1794. backtocursor:
  1795. scr = cursor.holdscr
  1796. row = 1
  1797. LOCATE margin.t + row, margin.l + 1
  1798. filled% = page.h: GOSUB displaydoc
  1799. row = cursor.holdrow
  1800. col = cursor.scbrcol
  1801. scrb.x = cursor.holdscrbx
  1802. scrb.i = scr
  1803. curhide% = 0
  1804. GOSUB getcurinfo
  1805. LOCATE margin.t + row, margin.l + col, 1
  1806.  
  1807. highlighter:
  1808. yy% = CSRLIN: xx% = POS(0)
  1809.  
  1810. IF cutmrow% THEN
  1811.     cutdrow% = row + scr: cutdcol% = col ' Also found in scrollscrn routine.
  1812.  
  1813. IF o% = 0 THEN
  1814.     o% = mark%
  1815.     o% = d% ' o% is the start marker or last marker. If zero, it is the same as the start marker (mark%) but if the highlighting process is ongoing, it is the same as the last highlighting marker (d%).
  1816.  
  1817. hlbypass% = -1: GOSUB markercalc ' o% has already been set. hlbypass% gets zeroed in gosub statement.
  1818.  
  1819. IF d% >= o% THEN mov% = 1 ELSE mov% = -1: ' Difference between origin and destination markers determine if the movement is positive (right, down) or negative (left, up).
  1820.  
  1821.     CASE 1 ' End, right, or down
  1822.         x1% = o1%: x2% = o2%: LOCATE margin.t + x1%, margin.l + x2%
  1823.         a1$ = MID$(x$(x1% + scr), 1, INSTR(x$(x1% + scr), CHR$(10)) - 1)
  1824.         ' Highlighting on line above, from origin row.
  1825.         IF x1% = markrow% AND o1% = d1% AND mhl% THEN ' Mouse only when the origin row is the same as the original marker row and the destination row is the same as the origin row. This is right movement within the same line of text.
  1826.             i% = 0: DO UNTIL i% = d2% - x2%: GOSUB getcolor: PRINT MID$(a1$, x2% + i%, 1);: i% = i% + 1: LOOP
  1827.         ELSEIF x1% = markrow% AND ABS(o% - d%) > 1 THEN ' End key press. Exclude mouse here, as down mouse highlighting is done in a conditional statement, below.
  1828.             GOSUB getcolor: PRINT MID$(a1$, x2%, ABS(o2% - markcol%)); ' Print from origin column to initial marker column.
  1829.             GOSUB getcolor: PRINT MID$(a1$, x2% + ABS(o2% - markcol%)); ' Print from initial marker column to destination column.
  1830.         ELSE ' Right arrow key, down arrow key or mouse moving down.
  1831.             GOSUB getcolor: PRINT MID$(a1$, x2%, ABS(o1% - d1%) * dwidth2 + ABS(o2% - d2%)); ' Trick method to determine length of highlighting.
  1832.         END IF
  1833.  
  1834.         IF o1% - d1% THEN ' Highlighting on current row after row above is finished.
  1835.             x1% = row: x2% = col: LOCATE margin.t + x1%, margin.l + 1
  1836.             a1$ = MID$(x$(x1% + scr), 1, INSTR(x$(x1% + scr), CHR$(10)) - 1)
  1837.             IF x1% = markrow% AND ABS(o% - d%) > 1 THEN ' Highlight the destination row if downward move is made after an upward highlight has been made.
  1838.                 IF d2% < markcol% THEN i% = d2% ELSE i% = markcol% ' Set i% to the furthest column.
  1839.                 GOSUB getcolor: PRINT MID$(a1$, 1, i% - 1); ' unhighlight to the furthest column.
  1840.                 GOSUB getcolor: PRINT MID$(a1$, i%, ABS(d2% - i%));
  1841.             ELSE ' Arrow down or mouse downward, either with original marker row on same line.
  1842.                 GOSUB getcolor: PRINT MID$(a1$, 1, d2% - 1); ' Highlight from first column on current row to destination on current row.
  1843.             END IF
  1844.         END IF
  1845.  
  1846.     CASE -1 ' Home, up, or Left.
  1847.         x1% = row: x2% = col: LOCATE margin.t + x1%, margin.l + x2%
  1848.         a1$ = MID$(x$(x1% + scr), 1, INSTR(x$(x1% + scr), CHR$(10)) - 1)
  1849.  
  1850.         IF x1% = markrow% AND o1% = d1% AND mhl% THEN ' Mouse only when the origin row is the same as the original marker row and the destination row is the same as the origin row. This is left movement within the same line of text.
  1851.             IF mx% - margin.l <= LEN(a1$) THEN
  1852.                 i% = 0: DO UNTIL i% = o2% - x2%: GOSUB getcolor: PRINT MID$(a1$, x2% + i%, 1);: i% = i% + 1: LOOP
  1853.             END IF
  1854.         ELSEIF x1% = markrow% AND ABS(o1% - d1%) >= 1 THEN ' Mouse or arrow back up to highlighted line above.
  1855.             GOSUB getcolor: PRINT MID$(a1$, x2%, ABS(d2% - markcol%)); ' Highlight from cursor to previously highlighted text to the right, if any.
  1856.             GOSUB getcolor: PRINT MID$(a1$, x2% + ABS(d2% - markcol%)); ' Unhighlight previous text to the right.
  1857.         ELSE ' Arrow left, home, arrow up or mouse upwards, either without any highlighting above.
  1858.             GOSUB getcolor: PRINT MID$(a1$, x2%, ABS(o1% - d1%) * dwidth2 + ABS(o2% - d2%)); ' Trick method to determine length of highlighting.
  1859.         END IF
  1860.  
  1861.         IF o1% <> d1% AND d2% <= o2% THEN ' Bottom line with arrow up or mouse upwards. Note: Mouse initially moves straight up, and moves laterally in another pass. This is why o2% always equals d2% as with an arrow up move.
  1862.             x1% = o1%: x2% = o2%: LOCATE margin.t + x1%, margin.l + 1
  1863.             a1$ = MID$(x$(x1% + scr), 1, INSTR(x$(x1% + scr), CHR$(10)) - 1)
  1864.  
  1865.             IF x1% = markrow% THEN
  1866.                 IF markcol% >= d2% THEN i% = d2% ELSE i% = markcol%
  1867.                 GOSUB getcolor: PRINT MID$(a1$, 1, i% - 1);
  1868.                 GOSUB getcolor: PRINT MID$(a1$, i%, ABS(i% - d2%));
  1869.             ELSE
  1870.                 IF x1% = page.h AND dmodify% THEN d2% = d2% + dmodify%
  1871.                 GOSUB getcolor: PRINT MID$(a1$, 1, d2% - 1);
  1872.             END IF
  1873.         END IF
  1874.  
  1875. dmodify% = 0
  1876. IF d% = mark% THEN GOSUB clearmarkers
  1877.  
  1878. COLOR c1%, c2%
  1879. LOCATE yy%, xx%
  1880.  
  1881. GOSUB movescrollbox
  1882.  
  1883.  
  1884. getcolor: ' Reads the screen under the cursor and reverses the colors.
  1885. IF POS(0) - margin.l > dwidth + 1 THEN ' Cursor in scrollbar space after full line of text was printed.
  1886.     COLOR h1%, h2%
  1887.     IF SCREEN(CSRLIN, POS(0), 1) <> 7 THEN COLOR c1%, c2% ELSE COLOR h1%, h2%
  1888.  
  1889. copytext:
  1890. _CLIPBOARD$ = "": myCLIPBOARD$ = ""
  1891. i1% = cutmrow%: i2% = cutdrow%
  1892. IF i1% > i2% THEN SWAP i1%, i2%
  1893. j% = cutmcol%: k% = cutdcol%
  1894. IF cutmrow% > cutdrow% THEN SWAP j%, k%
  1895.  
  1896. IF cutmrow% = cutdrow% THEN
  1897.     myCLIPBOARD$ = MID$(x$(i1%), j%, k% - j%)
  1898.     IF INSTR(myCLIPBOARD$, CHR$(255)) THEN a1$ = myCLIPBOARD$: MID$(a1$, INSTR(a1$, CHR$(255)), 1) = CHR$(13): _CLIPBOARD$ = a1$ + CHR$(10) ELSE _CLIPBOARD$ = myCLIPBOARD$
  1899.     a1$ = MID$(MID$(x$(i1%), 1, INSTR(x$(i1%), CHR$(10)) - 1), j%)
  1900.     myCLIPBOARD$ = a1$
  1901.     IF INSTR(a1$, CHR$(255)) THEN MID$(a1$, INSTR(a1$, CHR$(255)), 1) = CHR$(13): _CLIPBOARD$ = _CLIPBOARD$ + a1$ + CHR$(10) ELSE _CLIPBOARD$ = _CLIPBOARD$ + a1$
  1902.     FOR i% = 1 TO i2% - i1% - 1
  1903.         a1$ = MID$(x$(i1% + i%), 1, INSTR(x$(i1% + i%), CHR$(10)) - 1)
  1904.         myCLIPBOARD$ = myCLIPBOARD$ + a1$
  1905.         IF INSTR(a1$, CHR$(255)) THEN MID$(a1$, INSTR(a1$, CHR$(255)), 1) = CHR$(13): _CLIPBOARD$ = _CLIPBOARD$ + a1$ + CHR$(10) ELSE _CLIPBOARD$ = _CLIPBOARD$ + a1$
  1906.     NEXT
  1907.     a1$ = MID$(x$(i2%), 1, k% - 1)
  1908.     myCLIPBOARD$ = myCLIPBOARD$ + a1$
  1909.     IF INSTR(a1$, CHR$(255)) THEN MID$(a1$, INSTR(a1$, CHR$(255)), 1) = CHR$(13): _CLIPBOARD$ = _CLIPBOARD$ + a1$ + CHR$(10) ELSE _CLIPBOARD$ = _CLIPBOARD$ + a1$
  1910.  
  1911. singlelinedelete:
  1912. a1$ = MID$(x$(row + scr), 1, INSTR(x$(row + scr), CHR$(10)) - 1)
  1913. IF cutmcol% < cutdcol% THEN j% = cutmcol%: k% = cutdcol% ELSE j% = cutdcol%: k% = cutmcol%
  1914. GOSUB clearmarkers
  1915. a2$ = MID$(a1$, 1, j% - 1)
  1916. a3$ = MID$(a1$, k%)
  1917. IF a3$ = "" THEN
  1918.     cur$ = "eod"
  1919.     cur$ = MID$(a3$, 1, 1): MID$(a3$, 1, 1) = CHR$(4)
  1920. a$ = a2$ + a3$
  1921.  
  1922. multilinedelete:
  1923. i1% = cutmrow%: i2% = cutdrow%
  1924. j% = cutmcol%: k% = cutdcol%
  1925. IF i1% > i2% THEN SWAP i1%, i2%: SWAP j%, k% ' Highlighting was upwards instead of downwards.
  1926.  
  1927. GOSUB clearmarkers
  1928.  
  1929. oldrow = row: oldscr = scr
  1930. a2$ = MID$(x$(i1%), 1, j% - 1)
  1931. a1$ = MID$(x$(i2%), 1, INSTR(x$(i2%), CHR$(10)) - 1)
  1932. a3$ = MID$(a1$, k%)
  1933. b$ = ""
  1934.  
  1935. IF a3$ = "" THEN
  1936.     IF i2% < noe THEN
  1937.         cur$ = MID$(x$(i2% + 1), 1, 1): MID$(x$(i2% + 1), 1, 1) = CHR$(4)
  1938.     ELSE
  1939.         cur$ = "eod"
  1940.     END IF
  1941.     cur$ = MID$(a3$, 1, 1): MID$(a3$, 1, 1) = CHR$(4)
  1942.  
  1943. a$ = a2$ + a3$
  1944.  
  1945. IF i1% > 1 THEN
  1946.     i1% = i1% - 1
  1947.     a1$ = MID$(x$(i1%), 1, INSTR(x$(i1%), CHR$(10)) - 1)
  1948.     a$ = a1$ + a$
  1949.  
  1950. FOR i% = i1% TO i2%
  1951.     x$(i%) = ""
  1952.  
  1953. row = 1: scr = i1% - row
  1954.  
  1955. a1$ = "": a2$ = "": a3$ = ""
  1956. wrap.on% = -1: GOSUB wrapper
  1957. REDIM _PRESERVE x$(noe + 1)
  1958.  
  1959. IF noe < page.h THEN GOSUB wipescrn ' Wipe screen.
  1960.  
  1961. LOCATE row + margin.t, margin.l + 1
  1962.  
  1963. IF i1% < oldscr THEN ELSE scr = oldscr
  1964.  
  1965. IF scr > 0 THEN ' Adjust towards bottom of screen.
  1966.     IF noe - scr < page.h THEN
  1967.         scr = noe - page.h - 1
  1968.         IF scr < 0 THEN scr = 0
  1969.     END IF
  1970.  
  1971. filled% = page.h: GOSUB displaydoc
  1972. GOSUB movescrollbox
  1973.  
  1974. clipboardconvert:
  1975. myCLIPBOARD$ = _CLIPBOARD$
  1976. DO UNTIL INSTR(myCLIPBOARD$, CHR$(13) + CHR$(10)) = 0
  1977.     j% = INSTR(myCLIPBOARD$, CHR$(13) + CHR$(10))
  1978.     DO UNTIL MID$(myCLIPBOARD$, j%, 2) <> CHR$(13) + CHR$(10)
  1979.         myCLIPBOARD$ = MID$(myCLIPBOARD$, 1, j% - 1) + CHR$(255) + MID$(myCLIPBOARD$, j% + 2)
  1980.         j% = j% + 2
  1981.     LOOP
  1982.  
  1983. debugger:
  1984. ss% = CSRLIN: tt% = POS(0)
  1985. LOCATE 1, 42
  1986. PRINT "mark rw col"; mark%; markrow%; markcol%; "   "
  1987. LOCATE , 42
  1988. PRINT "orig  o1 o2"; o%; "o1% ="; o1%; "o2% ="; o2%; "   "
  1989. LOCATE , 42
  1990. PRINT "dest  d1 d2"; d%; "d1% ="; d1%; "d2% ="; d2%; "   "
  1991. IF mov% > 0 THEN mov$ = "pos" ELSE IF mov% < 0 THEN mov$ = "neg" ELSE mov$ = "neutral"
  1992. LOCATE , 42
  1993. PRINT "moving     "; mov$; "   "
  1994. LOCATE , 42
  1995. PRINT "o2 - d2 =  "; ABS(o1% - d1%); ABS(o2% - d2%); "   "
  1996. LOCATE , 42
  1997. PRINT "yy%   xx%  "; yy%; xx%; "   "
  1998. LOCATE , 42
  1999. PRINT "yy% multi  "; (yy% - 1) * dwidth + col; "   "
  2000. LOCATE , 42
  2001. PRINT "cutmrow%   "; cutmrow%; cutmcol%; "   "
  2002. LOCATE , 42
  2003. PRINT "cutdrow%   "; cutdrow%; cutdcol%; "   "
  2004. LOCATE , 42
  2005. PRINT "row col scr"; row; col; scr; "   "
  2006. LOCATE , 42
  2007. PRINT "mhl1%      "; mhl1%; "   "
  2008. LOCATE , 42
  2009. PRINT "mhl1row%   "; mhl1row%; "   "
  2010. LOCATE , 42
  2011. PRINT "mhl1col%   "; mhl1col%; "   "
  2012. LOCATE , 42
  2013. PRINT "locked%    "; locked%; "   "
  2014. LOCATE , 42
  2015. PRINT "scrb.x  i s"; scrb.x; scrb.i; scrb.s; "   "
  2016. LOCATE , 42
  2017. PRINT "b$         "; b$; kloop%; "            "
  2018. LOCATE , 42
  2019. IF LEN(cur$) THEN cur% = ASC(cur$) ELSE cur% = 0
  2020. PRINT "cur$ cur%  "; cur$; cur%; ""
  2021. LOCATE , 42
  2022. PRINT "noe uboundx "; noe; UBOUND(x$); "            "
  2023. LOCATE , 42
  2024. PRINT "cursor.t / b"; cursor.top; cursor.bot; "    ";
  2025. LOCATE , 42
  2026. PRINT "scrbardrag% "; scrbardrag%; draglock%; "    ";
  2027. LOCATE ss%, tt%
  2028.  

It's really rough, and probably buggy. This is the stage where I start renaming variables, optimize the code and re-order the gosubs to better match the program flow, but this is as far along I am for now. Sorry, no save yet, but you can type in it or take any typed out text and copy and paste it into the app. If you select all (Ctrl + A) and copy (Ctrl + C) from the app, you can paste it to Notepad and save it as "mybetatest.txt" in the same folder you are running this app in. If you do so, you will need to change line two beta% to beta% = 2. The saved Notepad text will now open in the app at the next run.

Merry Christmas

Pete   
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: TempodiBasic on December 26, 2020, 12:51:04 pm
Hi guys and gals

I had a fine idea but not so much time! So for now I post this my whishes
Code: QB64: [Select]
  1. DIM SHARED GlInit AS INTEGER, s AS SINGLE, Glactive AS INTEGER
  2.  
  3. A = _NEWIMAGE(800, 600, 32)
  4.  
  5.  
  6. CONST Yellow1 = _RGB32(200, 200, 10, 255), Yellow2 = _RGB32(200, 200, 60, 255), Black = _RGB32(0, 0, 0, 255), Red = _RGB32(230, 0, 0, 255)
  7. _TITLE "Happy Christmas QB64 community!"
  8.  
  9. LOCATE 2, ((_WIDTH / 2) - 80) / 8: PRINT "Opengl graphic demo"
  10. GlInit = -1
  11. Glactive = -1
  12. r = 1
  13. z = 10
  14. s = _PI(2) / z
  15.     IF r > 0.35 THEN r = r - 0.05
  16.     FOR w = 0 TO _PI(2) STEP s / 2
  17.  
  18.         _DELAY .15
  19.     NEXT w
  20. COLOR Yellow1
  21. PRINT " Happy Christmas QB64 community"
  22.  
  23. 'area subs-------------
  24.  
  25. 'area GL --------------------
  26. SUB _GL ()
  27.     SHARED w AS SINGLE
  28.     IF NOT Glactive THEN EXIT SUB
  29.     IF GlInit THEN
  30.         _glViewport 0, 0, _WIDTH, _HEIGHT
  31.         _glClearColor 1, 0, 0, 1
  32.         GlInit = 0
  33.     END IF
  34.     _glClear _GL_COLOR_BUFFER_BIT
  35.     RotatingStarsFull 0, -0.2, r, -w
  36.     IncrDrawPoint 0, -0.2, r, 10, -w
  37.     IncrRotStarsvoid 0, -0.2, r, -w
  38.     'Q
  39.     RotatingStarsFull -0.7, 0.8, 0.05, -w
  40.     RotatingStarsFull -0.8, 0.8, 0.05, -w
  41.     RotatingStarsFull -0.9, 0.7, 0.05, -w
  42.     RotatingStarsFull -0.9, 0.6, 0.05, -w
  43.     RotatingStarsFull -0.9, 0.5, 0.05, -w
  44.     RotatingStarsFull -0.8, 0.4, 0.05, -w
  45.     RotatingStarsFull -0.7, 0.4, 0.05, -w
  46.     RotatingStarsFull -0.6, 0.7, 0.05, -w
  47.     RotatingStarsFull -0.6, 0.6, 0.05, -w
  48.     RotatingStarsFull -0.6, 0.5, 0.05, -w
  49.     RotatingStarsFull -0.55, 0.4, 0.05, -w
  50.     'B
  51.  
  52.     RotatingStarsFull -0.2, 0.8, 0.05, -w
  53.     RotatingStarsFull -0.4, 0.8, 0.05, -w
  54.     RotatingStarsFull -0.4, 0.7, 0.05, -w
  55.     RotatingStarsFull -0.4, 0.6, 0.05, -w
  56.     RotatingStarsFull -0.4, 0.5, 0.05, -w
  57.     RotatingStarsFull -0.4, 0.4, 0.05, -w
  58.     RotatingStarsFull -0.2, 0.4, 0.05, -w
  59.     RotatingStarsFull -0.1, 0.7, 0.05, -w
  60.     RotatingStarsFull -0.2, 0.6, 0.05, -w
  61.     RotatingStarsFull -0.1, 0.5, 0.05, -w
  62.     '6
  63.     RotatingStarsFull 0.4, 0.8, 0.05, -w
  64.     RotatingStarsFull 0.3, 0.8, 0.05, -w
  65.     RotatingStarsFull 0.2, 0.7, 0.05, -w
  66.     RotatingStarsFull 0.1, 0.6, 0.05, -w
  67.     RotatingStarsFull 0.1, 0.5, 0.05, -w
  68.     RotatingStarsFull 0.2, 0.4, 0.05, -w
  69.     RotatingStarsFull 0.3, 0.3, 0.05, -w
  70.     RotatingStarsFull 0.3, 0.3, 0.05, -w
  71.     RotatingStarsFull 0.4, 0.4, 0.05, -w
  72.     RotatingStarsFull 0.3, 0.5, 0.05, -w
  73.     RotatingStarsFull 0.4, 0.5, 0.05, -w
  74.     RotatingStarsFull 0.2, 0.5, 0.05, -w
  75.  
  76.     '4
  77.     RotatingStarsFull 0.8, 0.8, 0.05, -w
  78.     RotatingStarsFull 0.7, 0.7, 0.05, -w
  79.     RotatingStarsFull 0.8, 0.7, 0.05, -w
  80.     RotatingStarsFull 0.6, 0.5, 0.05, -w
  81.     RotatingStarsFull 0.8, 0.6, 0.05, -w
  82.     RotatingStarsFull 0.65, 0.6, 0.05, -w
  83.     RotatingStarsFull 0.7, 0.5, 0.05, -w
  84.     RotatingStarsFull 0.9, 0.5, 0.05, -w
  85.     RotatingStarsFull 0.8, 0.5, 0.05, -w
  86.     RotatingStarsFull 0.8, 0.4, 0.05, -w
  87.     RotatingStarsFull 0.8, 0.3, 0.05, -w
  88.  
  89.     _glFlush
  90.  
  91. SUB IncrDrawPoint (x AS SINGLE, y AS SINGLE, r1 AS SINGLE, s1 AS INTEGER, w AS SINGLE)
  92.     STATIC s2 AS INTEGER
  93.     IF s2 - s1 = 0 THEN s2 = 2 ELSE s2 = s2 + 1
  94.     drawpoint x, y, r1, s2, 2 * s, w
  95.  
  96. SUB IncrRotStarsvoid (x AS SINGLE, y AS SINGLE, r1 AS SINGLE, w AS SINGLE)
  97.     STATIC r2 AS SINGLE
  98.     IF r2 >= r1 THEN r2 = 0 ELSE r2 = r2 + 0.001
  99.     RotatingStarsVoid x, y, r2, w
  100.  
  101. SUB drawpoint (x AS SINGLE, y AS SINGLE, r1 AS SINGLE, s1 AS INTEGER, s2 AS SINGLE, w AS SINGLE)
  102.     DIM i AS SINGLE, cx AS SINGLE, cy AS SINGLE
  103.     _glColor4f 0.8, .8, 0.1, 1.0
  104.     _glPointSize s1 ' it works with 2 or more !
  105.     _glBegin _GL_POINTS
  106.     FOR i = 0 TO _PI(2) STEP s2
  107.         cx = (COS(i + w) * r1) + x
  108.         cy = (SIN(i + w) * r1) + y
  109.         _glVertex2f cx, cy
  110.     NEXT i
  111.     _glEnd
  112.  
  113.  
  114.  
  115.  
  116. SUB RotatingStarsFull (x AS SINGLE, y AS SINGLE, r1 AS SINGLE, w AS SINGLE)
  117.     DIM i, cx AS SINGLE, cy AS SINGLE, j AS INTEGER, k AS INTEGER, h AS INTEGER
  118.     _glColor4f 0.8, .8, 0.1, 1.0
  119.  
  120.     _glBegin _GL_TRIANGLE_FAN
  121.  
  122.     h = 0
  123.     FOR i = 0 TO _PI(2) STEP s
  124.         h = h + 1
  125.         IF h MOD 2 = 0 THEN
  126.             j = 2: k = 1
  127.         ELSE
  128.             j = 1: k = 2
  129.         END IF
  130.  
  131.         cx = (COS(i - s + w) * (r1 / k)) + x
  132.         cy = (SIN(i - s + w) * (r1 / k)) + y
  133.         _glVertex2f cx, cy
  134.  
  135.         cx = (COS(i + w) * (r1 / j)) + x
  136.         cy = (SIN(i + w) * (r1 / j)) + y
  137.         _glVertex2f cx, cy
  138.         cx = (COS(i + s + w) * (r1 / k)) + x
  139.         cy = (SIN(i + s + w) * (r1 / k)) + y
  140.         _glVertex2f cx, cy
  141.     NEXT i
  142.  
  143.     _glEnd
  144.  
  145. SUB RotatingStarsVoid (x AS SINGLE, y AS SINGLE, r1 AS SINGLE, w AS SINGLE)
  146.     DIM i, cx AS SINGLE, cy AS SINGLE, j AS INTEGER, k AS INTEGER, h AS INTEGER
  147.     _glColor4f 0.8, 1, 0.1, 1.0
  148.  
  149.     _glBegin _GL_LINES
  150.  
  151.     h = 0
  152.     FOR i = 0 TO _PI(2) STEP s
  153.         h = h + 1
  154.         IF h MOD 2 = 0 THEN
  155.             j = 2: k = 1
  156.         ELSE
  157.             j = 1: k = 2
  158.         END IF
  159.  
  160.  
  161.         cx = (COS(i + w) * (r1 / j)) + x
  162.         cy = (SIN(i + w) * (r1 / j)) + y
  163.         _glVertex2f cx, cy
  164.         cx = (COS(i + s + w) * (r1 / k)) + x
  165.         cy = (SIN(i + s + w) * (r1 / k)) + y
  166.         _glVertex2f cx, cy
  167.     NEXT i
  168.  
  169.     _glEnd
  170.  

here a screenshot
  [ This attachment cannot be displayed inline in 'Print Page' view ]  

Merry Christmas and happy life!

PS all you have posted something of beautiful! Thanks to share these your works!
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Aurel on December 27, 2020, 09:40:56 am
I must say that i like your snow-animation Sierraken ;
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Aurel on December 27, 2020, 09:46:51 am
Also well done Static ..i like it
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Pete on December 28, 2020, 02:18:08 am
So did I win? I bet I did. I posted the biggest app on the board. It's huge!!! If I didn't... it's rigged.

Pete
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: STxAxTIC on December 28, 2020, 02:21:25 am
Aw thanks Aurel!

My first fan art!... jkjk

Glad you liked it!
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: Dav on December 28, 2020, 09:54:27 am
I gotta say, that landscape thing you posted was pretty doggone awesome, @STxAxTIC. You could turn that into a flight simulator game.

- Dav
Title: Re: 🎄🎁✨ Holiday Season - are you ready to code?
Post by: STxAxTIC on December 28, 2020, 12:59:59 pm
Thanks much @Dav - it's been one of those back-burner projects spanning over a few years. I haven't decided on a proper endgame for this engine... Ditch particles and go with 3d triangles? Commit to particles and do something minecraft-like? If I could live several lifetimes, I would do both...