Author Topic: 3D Bouncing Balls (GL) - Historical Copy  (Read 2710 times)

0 Members and 1 Guest are viewing this topic.

Offline Qwerkey

  • Forum Resident
  • Posts: 755
3D Bouncing Balls (GL) - Historical Copy
« on: July 15, 2018, 07:52:00 am »
This program simulates coloured balls moving and colliding.  It is a copy of my program which first appeared on [abandoned, outdated and now likely malicious qb64 dot net website - don’t go there], and there is nothing changed or added.  It is copied here because [abandoned, outdated and now likely malicious qb64 dot net website - don’t go there] is now non-existent.

The 3D full perspective visualisation is enhanced by making the actual balls 3D shapes.  The 2D ball image is mapped via _MAPTRIANGLE to an actual spherical shape.  You will notice that this method has the effect of distorting the ball shape, especially at distances from the centre of the screen.  This arises because of the vanishing-point perspective used in _MAPTIANGLE(3D).

Esc to quit the program.

Richard

Code: QB64: [Select]
  1. ' 3D Bouncing Balls Using _MAPTRIANGLE by QWERKEY (Richard Notley) 21/04/18
  2.  
  3. ' Cyperium method for sphere image
  4.  
  5. CONST True = -1`, False = 0`
  6. _TITLE "3D Bouncing Balls"
  7.  
  8. CONST NoBalls%% = 10, Uscreen% = 1000, Vscreen% = 800, NoPhis%% = 16, NoAlphas%% = 6, XBright! = 0.5
  9. CONST Pi! = 4 * ATN(1), Rad1%% = 25, PerspDist% = 550, DeltaSepn! = 0.25 'small offset to stop balls sticking
  10. CONST Alpha! = Pi! / (2 * NoAlphas%%), Phi! = 2 * Pi! / NoPhis%%
  11. DIM BallStats!(NoBalls%% - 1, 9), ViewOrder%%(NoBalls%% - 1), Cyperium&(NoBalls%% - 1)
  12. DIM MapConv%(NoPhis%%, NoAlphas%%, 1, 2)
  13.  
  14. 'Conversion from 2D
  15. FOR N%% = 0 TO NoPhis%%
  16.     FOR M%% = 0 TO NoAlphas%%
  17.         MapConv%(N%%, M%%, 0, 0) = 128 + CINT(127 * SIN((Pi! / 2) - M%% * Alpha!) * COS(N%% * Phi!))
  18.         MapConv%(N%%, M%%, 0, 1) = 128 + CINT(127 * SIN((Pi! / 2) - M%% * Alpha!) * SIN(N%% * Phi!))
  19.         MapConv%(N%%, M%%, 1, 0) = CINT(Rad1%% * SIN((Pi! / 2) - M%% * Alpha!) * COS(N%% * Phi!))
  20.         MapConv%(N%%, M%%, 1, 1) = CINT(Rad1%% * SIN((Pi! / 2) - M%% * Alpha!) * SIN(N%% * Phi!))
  21.         MapConv%(N%%, M%%, 1, 2) = CINT(Rad1%% * COS((Pi! / 2) - M%% * Alpha!))
  22.     NEXT M%%
  23. NEXT N%%
  24.  
  25. 'Screen Background
  26. TempImage& = _NEWIMAGE(Uscreen%, Vscreen%, 32)
  27. _DEST TempImage&
  28. COLOR _RGB(255, 255, 255), _RGB(10, 60, 60)
  29. FOR UCol% = 0 TO Uscreen% - 1
  30.     FOR VCol% = 0 TO Vscreen% - 1
  31.         PSET (UCol%, VCol%), _RGB(100, INT(180 * UCol% / Uscreen%), INT(180 * VCol% / Vscreen%))
  32.     NEXT VCol%
  33. NEXT UCol%
  34. Background& = MakeHardware&(TempImage&)
  35.  
  36. 'Set array for depth order
  37. JumpStart%% = 1
  38. WHILE JumpStart%% <= NoBalls%%: JumpStart%% = JumpStart%% * 2: WEND
  39. FOR N%% = 0 TO NoBalls%% - 1
  40.     ViewOrder%%(N%%) = N%%
  41. NEXT N%%
  42.  
  43. ' Define characteristics of balls
  44. DATA 255,0,0
  45. DATA 219,80,0
  46. DATA 150,100,0
  47. DATA 138,117,0
  48. DATA 80,155,20
  49. DATA 0,255,0
  50. DATA 20,135,100
  51. DATA 0,105,150
  52. DATA 0,60,150
  53. DATA 0,0,255
  54. FOR N%% = 0 TO NoBalls%% - 1
  55.     'Ball mass
  56.     BallStats!(N%%, 0) = 0.1 + (0.8 * N%% / (NoBalls%% - 1))
  57.     IF BallStats!(N%%, 0) = 0 THEN BallStats!(N%%, 0) = 0.000001
  58.     'Ball colours (temporarily use (N%%,1,2,3)
  59.     FOR P%% = 1 TO 3
  60.         READ BallStats!(N%%, P%%)
  61.     NEXT P%%
  62.     TempImage& = _NEWIMAGE(256, 256, 32)
  63.     _DEST TempImage&
  64.     COLOR _RGB(BallStats!(N%%, 1), BallStats!(N%%, 2), BallStats!(N%%, 3)), _RGBA(0, 0, 0, 0)
  65.     'Image data goes from 1 to 255 (not 0 to 255)
  66.     FOR Z% = 128 TO 255
  67.         FOR X% = 1 TO 255
  68.             FOR Y% = 1 TO 255
  69.                 DeltaX% = X% - 127
  70.                 DeltaY% = Y% - 127
  71.                 DeltaZ% = Z% - 127
  72.                 Dist! = SQR((DeltaX% * DeltaX%) + (DeltaY% * DeltaY%) + (DeltaZ% * DeltaZ%))
  73.                 IF Dist! > 125 AND Dist! < 127 THEN PSET (X%, Y%), _RGB(CINT(Z% * BallStats!(N%%, 1) * (1 - (XBright! * X% / 255)) / 255), CINT(Z% * BallStats!(N%%, 2) * (1 - (XBright! * X% / 255)) / 255), CINT(Z% * BallStats!(N%%, 3) * (1 - (XBright! * X% / 255)) / 255))
  74.             NEXT
  75.         NEXT
  76.     NEXT
  77.     Cyperium&(N%%) = MakeHardware&(TempImage&)
  78.     'Ball positions/velocities
  79.     FOR P%% = 4 TO 6
  80.         BallStats!(N%%, P%%) = (0.5 - RND) * 1000
  81.     NEXT P%%
  82.     FOR P%% = 7 TO 9
  83.         Velocity! = 0.5 - RND
  84.         IF Velocity! < 0 THEN
  85.             Velocity! = Velocity! - 0.5
  86.         ELSE
  87.             Velocity! = Velocity! + 0.5
  88.         END IF
  89.         BallStats!(N%%, P%%) = Velocity! * 3
  90.     NEXT P%%
  91. NEXT N%%
  92.  
  93. 'Create screen
  94. SCREEN _NEWIMAGE(Uscreen%, Vscreen%, 32)
  95. _DISPLAYORDER _HARDWARE 'do not even render the software layer, just the hardware one.
  96.  
  97. 'Initialise axes and rotations
  98. ZRot! = (RND - 0.5) * 0.0011: YRot! = (RND - 0.5) * 0.0011: XRot! = (RND - 0.5) * 0.0011
  99. ZTime% = 15 + INT(47 * RND): YTime%% = 15 + INT(47 * RND): XTime% = 15 + INT(47 * RND)
  100. ZStart! = TIMER: YStart! = TIMER: XStart! = TIMER
  101. Zaxis! = 0: Yaxis! = 0: Xaxis! = 0
  102. Stereo` = True
  103.  
  104. WHILE Stereo`
  105.     _LIMIT 120 'Game Frames/Second Rate
  106.  
  107.     _PUTIMAGE (0, 0), Background&
  108.  
  109.     'Calculate moves
  110.     FOR N%% = 0 TO NoBalls%% - 1
  111.         FOR P%% = 1 TO 3
  112.             BallStats!(N%%, 3 + P%%) = BallStats!(N%%, 3 + P%%) + BallStats!(N%%, 6 + P%%)
  113.         NEXT P%%
  114.     NEXT N%%
  115.  
  116.     'Check for collsions
  117.     FOR N%% = 0 TO NoBalls%% - 2
  118.         FOR M%% = N%% + 1 TO NoBalls%% - 1
  119.             SepnSqd! = (BallStats!(N%%, 4) - BallStats!(M%%, 4)) * (BallStats!(N%%, 4) - BallStats!(M%%, 4)) + (BallStats!(N%%, 5) - BallStats!(M%%, 5)) * (BallStats!(N%%, 5) - BallStats!(M%%, 5)) + (BallStats!(N%%, 6) - BallStats!(M%%, 6)) * (BallStats!(N%%, 6) - BallStats!(M%%, 6))
  120.             IF SepnSqd! <= 4 * Rad1%% * Rad1%% THEN
  121.                 ' Set new velocities
  122.                 Multiplier! = 0: NDist! = 0: MDist! = 0
  123.                 FOR P%% = 1 TO 3
  124.                     Multiplier! = Multiplier! + (BallStats!(N%%, 6 + P%%) - BallStats!(M%%, 6 + P%%)) * (BallStats!(N%%, 3 + P%%) - BallStats!(M%%, 3 + P%%))
  125.                     NDist! = NDist! + BallStats!(N%%, 3 + P%%) * BallStats!(N%%, 3 + P%%)
  126.                     MDist! = MDist! + BallStats!(M%%, 3 + P%%) * BallStats!(M%%, 3 + P%%)
  127.                 NEXT P%%
  128.                 NDist! = SQR(NDist!)
  129.                 MDist! = SQR(MDist!)
  130.                 Multiplier! = 2 * Multiplier! / (SepnSqd! * (BallStats!(N%%, 0) + BallStats!(M%%, 0)))
  131.                 FOR P%% = 1 TO 3
  132.                     SepnVect! = BallStats!(N%%, 3 + P%%) - BallStats!(M%%, 3 + P%%)
  133.                     BallStats!(N%%, 6 + P%%) = BallStats!(N%%, 6 + P%%) - (Multiplier! * BallStats!(M%%, 0) * SepnVect!)
  134.                     BallStats!(M%%, 6 + P%%) = BallStats!(M%%, 6 + P%%) + (Multiplier! * BallStats!(N%%, 0) * SepnVect!)
  135.                     IF NDist! > MDist! THEN
  136.                         BallStats!(M%%, 3 + P%%) = BallStats!(M%%, 3 + P%%) - (DeltaSepn! * (BallStats!(N%%, 3 + P%%) - BallStats!(M%%, 3 + P%%)) / SQR(SepnSqd!))
  137.                     ELSE
  138.                         BallStats!(N%%, 3 + P%%) = BallStats!(N%%, 3 + P%%) + (DeltaSepn! * (BallStats!(N%%, 3 + P%%) - BallStats!(M%%, 3 + P%%)) / SQR(SepnSqd!))
  139.                     END IF
  140.                 NEXT P%%
  141.             END IF
  142.         NEXT M%%
  143.     NEXT N%%
  144.  
  145.     'Look for reflection off sides
  146.     FOR N%% = 0 TO NoBalls%% - 1
  147.         FOR P%% = 1 TO 3
  148.             IF BallStats!(N%%, 3 + P%%) > 500 - Rad1%% THEN
  149.                 BallStats!(N%%, 6 + P%%) = -BallStats!(N%%, 6 + P%%)
  150.                 IF BallStats!(N%%, 3 + P%%) + BallStats!(N%%, 6 + P%%) > 500 - Rad1%% THEN
  151.                     BallStats!(N%%, 3 + P%%) = BallStats!(N%%, 3 + P%%) - DeltaSepn!
  152.                 END IF
  153.             ELSEIF BallStats!(N%%, 3 + P%%) < -500 + Rad1%% THEN
  154.                 BallStats!(N%%, 6 + P%%) = -BallStats!(N%%, 6 + P%%)
  155.                 IF BallStats!(N%%, 3 + P%%) + BallStats!(N%%, 6 + P%%) < -500 + Rad1%% THEN
  156.                     BallStats!(N%%, 3 + P%%) = BallStats!(N%%, 3 + P%%) + DeltaSepn!
  157.                 END IF
  158.             END IF
  159.         NEXT P%%
  160.     NEXT N%%
  161.  
  162.     'Adjust for angle of rotation
  163.     FOR N%% = 0 TO NoBalls%% - 1
  164.         R2! = SQR(BallStats!(N%%, 4) * BallStats!(N%%, 4) + BallStats!(N%%, 5) * BallStats!(N%%, 5) + BallStats!(N%%, 6) * BallStats!(N%%, 6))
  165.         Theta2! = _ACOS(BallStats!(N%%, 6) / R2!)
  166.         Phi2! = _ATAN2(BallStats!(N%%, 5), BallStats!(N%%, 4)) + Zaxis!
  167.         BallStats!(N%%, 1) = R2! * SIN(Theta2!) * COS(Phi2!)
  168.         BallStats!(N%%, 2) = R2! * SIN(Theta2!) * SIN(Phi2!)
  169.         BallStats!(N%%, 3) = R2! * COS(Theta2!)
  170.         R2! = SQR(BallStats!(N%%, 1) * BallStats!(N%%, 1) + BallStats!(N%%, 2) * BallStats!(N%%, 2) + BallStats!(N%%, 3) * BallStats!(N%%, 3))
  171.         Theta2! = _ACOS(BallStats!(N%%, 1) / R2!)
  172.         Phi2! = _ATAN2(BallStats!(N%%, 3), BallStats!(N%%, 2)) + Xaxis!
  173.         BallStats!(N%%, 2) = R2! * SIN(Theta2!) * COS(Phi2!)
  174.         BallStats!(N%%, 3) = R2! * SIN(Theta2!) * SIN(Phi2!)
  175.         BallStats!(N%%, 1) = R2! * COS(Theta2!)
  176.         R2! = SQR(BallStats!(N%%, 1) * BallStats!(N%%, 1) + BallStats!(N%%, 2) * BallStats!(N%%, 2) + BallStats!(N%%, 3) * BallStats!(N%%, 3))
  177.         Theta2! = _ACOS(BallStats!(N%%, 2) / R2!)
  178.         Phi2! = _ATAN2(BallStats!(N%%, 1), BallStats!(N%%, 3)) + Yaxis!
  179.         BallStats!(N%%, 3) = CINT(R2! * SIN(Theta2!) * COS(Phi2!))
  180.         BallStats!(N%%, 1) = CINT(R2! * SIN(Theta2!) * SIN(Phi2!))
  181.         BallStats!(N%%, 2) = CINT(R2! * COS(Theta2!))
  182.     NEXT N%%
  183.  
  184.     'Change display order: furthest first
  185.     Jump%% = JumpStart%%
  186.     WHILE Jump%% > 1
  187.         Jump%% = (Jump%% - 1) \ 2
  188.         DoneHere` = False
  189.         WHILE NOT DoneHere`
  190.             DoneHere` = True
  191.             FOR Upper%% = 1 TO NoBalls%% - Jump%%
  192.                 Lower%% = Upper%% + Jump%%
  193.                 'BallStats! z-dim
  194.                 IF BallStats!(ViewOrder%%(Upper%% - 1), 3) > BallStats!(ViewOrder%%(Lower%% - 1), 3) THEN
  195.                     SWAP ViewOrder%%(Upper%% - 1), ViewOrder%%(Lower%% - 1)
  196.                     DoneHere` = False
  197.                 END IF
  198.             NEXT Upper%%
  199.         WEND
  200.     WEND
  201.  
  202.     'Display balls
  203.     FOR N1%% = NoBalls%% - 1 TO 0 STEP -1
  204.         P%% = ViewOrder%%(N1%%)
  205.         '_PUTIMAGE (BallStats!(P%%, 1) + 500, BallStats!(P%%, 2) + 400), Cyperium&(P%%)
  206.         'Ball views done with _MAPTRIANGLE 3D
  207.         FOR N%% = 0 TO NoPhis%% - 1
  208.             FOR M%% = 0 TO NoAlphas%% - 2
  209.                 Ax% = MapConv%(N%%, M%%, 1, 0) + BallStats!(P%%, 1)
  210.                 Ay% = MapConv%(N%%, M%%, 1, 1) + BallStats!(P%%, 2)
  211.                 Az% = MapConv%(N%%, M%%, 1, 2) + BallStats!(P%%, 3) - PerspDist%
  212.                 Bx% = MapConv%(N%%, M%% + 1, 1, 0) + BallStats!(P%%, 1)
  213.                 By% = MapConv%(N%%, M%% + 1, 1, 1) + BallStats!(P%%, 2)
  214.                 Bz% = MapConv%(N%%, M%% + 1, 1, 2) + BallStats!(P%%, 3) - PerspDist%
  215.                 Cx% = MapConv%(N%% + 1, M%% + 1, 1, 0) + BallStats!(P%%, 1)
  216.                 Cy% = MapConv%(N%% + 1, M%% + 1, 1, 1) + BallStats!(P%%, 2)
  217.                 Cz% = MapConv%(N%% + 1, M%% + 1, 1, 2) + BallStats!(P%%, 3) - PerspDist%
  218.                 _MAPTRIANGLE (MapConv%(N%%, M%%, 0, 0), MapConv%(N%%, M%%, 0, 1))-(MapConv%(N%%, M%% + 1, 0, 0), MapConv%(N%%, M%% + 1, 0, 1))-(MapConv%(N%% + 1, M%% + 1, 0, 0), MapConv%(N%% + 1, M%% + 1, 0, 1)), Cyperium&(P%%) TO(Ax%, Ay%, Az%)-(Bx%, By%, Bz%)-(Cx%, Cy%, Cz%)
  219.                 _MAPTRIANGLE (MapConv%(N%% + 1, M%% + 1, 0, 0), MapConv%(N%% + 1, M%% + 1, 0, 1))-(MapConv%(N%% + 1, M%%, 0, 0), MapConv%(N%% + 1, M%%, 0, 1))-(MapConv%(N%%, M%%, 0, 0), MapConv%(N%%, M%%, 0, 1)), Cyperium&(P%%) TO(Cx%, Cy%, Cz%)-(MapConv%(N%% + 1, M%%, 1, 0) + BallStats!(P%%, 1), MapConv%(N%% + 1, M%%, 1, 1) + BallStats!(P%%, 2), MapConv%(N%% + 1, M%%, 1, 2) + BallStats!(P%%, 3) - PerspDist%)-(Ax%, Ay%, Az%)
  220.                 '_MAPTRIANGLE (MapConv%(N%%, M%%, 0, 0), MapConv%(N%%, M%%, 0, 1))-(MapConv%(N%%, M%% + 1, 0, 0), MapConv%(N%%, M%% + 1, 0, 1))-(MapConv%(N%% + 1, M%% + 1, 0, 0), MapConv%(N%% + 1, M%% + 1, 0, 1)), Cyperium&(P%%) TO(MapConv%(N%%, M%%, 1, 0) + BallStats!(P%%, 1), MapConv%(N%%, M%%, 1, 1) + BallStats!(P%%, 2), MapConv%(N%%, M%%, 1, 2) + BallStats!(P%%, 3) - PerspDist%)-(MapConv%(N%%, M%% + 1, 1, 0) + BallStats!(P%%, 1), MapConv%(N%%, M%% + 1, 1, 1) + BallStats!(P%%, 2), MapConv%(N%%, M%% + 1, 1, 2) + BallStats!(P%%, 3) - PerspDist%)-(MapConv%(N%% + 1, M%% + 1, 1, 0) + BallStats!(P%%, 1), MapConv%(N%% + 1, M%% + 1, 1, 1) + BallStats!(P%%, 2), MapConv%(N%% + 1, M%% + 1, 1, 2) + BallStats!(P%%, 3) - PerspDist%)
  221.                 '_MAPTRIANGLE (MapConv%(N%% + 1, M%% + 1, 0, 0), MapConv%(N%% + 1, M%% + 1, 0, 1))-(MapConv%(N%% + 1, M%%, 0, 0), MapConv%(N%% + 1, M%%, 0, 1))-(MapConv%(N%%, M%%, 0, 0), MapConv%(N%%, M%%, 0, 1)), Cyperium&(P%%) TO(MapConv%(N%% + 1, M%% + 1, 1, 0) + BallStats!(P%%, 1), MapConv%(N%% + 1, M%% + 1, 1, 1) + BallStats!(P%%, 2), MapConv%(N%% + 1, M%% + 1, 1, 2) + BallStats!(P%%, 3) - PerspDist%)-(MapConv%(N%% + 1, M%%, 1, 0) + BallStats!(P%%, 1), MapConv%(N%% + 1, M%%, 1, 1) + BallStats!(P%%, 2), MapConv%(N%% + 1, M%%, 1, 2) + BallStats!(P%%, 3) - PerspDist%)-(MapConv%(N%%, M%%, 1, 0) + BallStats!(P%%, 1), MapConv%(N%%, M%%, 1, 1) + BallStats!(P%%, 2), MapConv%(N%%, M%%, 1, 2) + BallStats!(P%%, 3) - PerspDist%)
  222.             NEXT M%%
  223.             _MAPTRIANGLE (MapConv%(N%%, NoAlphas%% - 1, 0, 0), MapConv%(N%%, NoAlphas%% - 1, 0, 1))-(128, 128)-(MapConv%(N%% + 1, NoAlphas%% - 1, 0, 0), MapConv%(N%% + 1, NoAlphas%% - 1, 0, 1)), Cyperium&(P%%) TO(Bx%, By%, Bz%)-(BallStats!(P%%, 1), BallStats!(P%%, 2), BallStats!(P%%, 3) + Rad1%% - PerspDist%)-(Cx%, Cy%, Cz%)
  224.             '_MAPTRIANGLE (MapConv%(N%%, NoAlphas%% - 1, 0, 0), MapConv%(N%%, NoAlphas%% - 1, 0, 1))-(128, 128)-(MapConv%(N%% + 1, NoAlphas%% - 1, 0, 0), MapConv%(N%% + 1, NoAlphas%% - 1, 0, 1)), Cyperium&(P%%) TO(MapConv%(N%%, NoAlphas%% - 1, 1, 0) + BallStats!(P%%, 1), MapConv%(N%%, NoAlphas%% - 1, 1, 1) + BallStats!(P%%, 2), MapConv%(N%%, NoAlphas%% - 1, 1, 2) + BallStats!(P%%, 3) - PerspDist%)-(BallStats!(P%%, 1), BallStats!(P%%, 2), BallStats!(P%%, 3) + Rad1%% - PerspDist%)-(MapConv%(N%% + 1, NoAlphas%% - 1, 1, 0) + BallStats!(P%%, 1), MapConv%(N%% + 1, NoAlphas%% - 1, 1, 1) + BallStats!(P%%, 2), MapConv%(N%% + 1, NoAlphas%% - 1, 1, 2) + BallStats!(P%%, 3) - PerspDist%)
  225.         NEXT N%%
  226.     NEXT N1%%
  227.  
  228.     'rotate around z- axis
  229.     Zaxis! = Zaxis! + ZRot!
  230.     IF Zaxis! > Pi! THEN
  231.         Zaxis! = Zaxis! - 2 * Pi!
  232.     ELSEIF Zaxis! < -Pi! THEN
  233.         Zaxis! = Zaxis! + 2 * Pi!
  234.     END IF
  235.  
  236.     'rotate around y- axis
  237.     Yaxis! = Yaxis! + YRot!
  238.     IF Yaxis! > Pi! THEN
  239.         Yaxis! = Yaxis! - 2 * Pi!
  240.     ELSEIF Yaxis! < -Pi! THEN
  241.         Yaxis! = Yaxis! + 2 * Pi!
  242.     END IF
  243.  
  244.     'rotate around x- axis
  245.     Xaxis! = Xaxis! + XRot!
  246.     IF Xaxis! > Pi! THEN
  247.         Xaxis! = Xaxis! - 2 * Pi!
  248.     ELSEIF Xaxis! < -Pi! THEN
  249.         Xaxis! = Xaxis! + 2 * Pi!
  250.     END IF
  251.  
  252.     IF TIMER > ZStart! + ZTime% THEN
  253.         ZRot! = (RND - 0.5) * 0.0011
  254.         ZTime% = 15 + INT(47 * RND)
  255.         ZStart! = TIMER
  256.         RANDOMIZE (ZStart!)
  257.     END IF
  258.     IF TIMER > YStart! + YTime%% THEN
  259.         YRot! = (RND - 0.5) * 0.0011
  260.         YTime%% = 15 + INT(47 * RND)
  261.         YStart! = TIMER
  262.     END IF
  263.     IF TIMER > XStart! + XTime% THEN
  264.         XRot! = (RND - 0.5) * 0.0011
  265.         XTime% = 15 + INT(47 * RND)
  266.         XStart! = TIMER
  267.     END IF
  268.  
  269.     IF _KEYHIT = 27 THEN Stereo` = False 'Esc  to quit
  270.  
  271.     _DISPLAY
  272.  
  273.  
  274.  
  275. FUNCTION MakeHardware& (Imagename&)
  276.     MakeHardware& = _COPYIMAGE(Imagename&, 33)
  277.     _FREEIMAGE Imagename&
  278.  


« Last Edit: July 09, 2020, 07:47:01 am by Qwerkey »