01-17-2026, 11:03 AM
This is the last of my old programs from .org. Seasoned members may remember it for its entertaining (?) whimsicality. It is slightly updated for this PE Edition.
The program was created to demonstrate the amazing graphics capabilities of QB64, using the simple coding techniques of the QB64 _MAPTRIANGLE statement: the 3D _MAPTRIANGLE method gives a convincing 3D perspective view. Both 2D and 3D _MAPTRIANGLE methods are used and the advantages of the 3D method are evident.
Unzip the file and extract the folder into your PEQB64 directory. In the IDE make sure that you have the Run Option “Save EXE in source folder” checked. At program start there is a delay while the disk files are read and loaded into memory and image manipulations are performed.
Pi-in-the-Sky PE Edition.zip (Size: 18.08 MB / Downloads: 13)
The video shows a short excerpt of the running program.
The program features a number of animations (some 2D and some 3D) enhanced in some cases with accompanying audio.
The scene a landscape within which a variety of animations will occur. It takes approximately 10 mins to run through all of the animation sequences. There are earthly animations and celestial animations. During the celestial animations, there may be ghostly appearances in the terrestrial graveyard.
In the blue text I give details of the program coding methods, descriptions of the animations and background information. You do not need to read the blue text to run and enjoy (well, maybe!) the program.
I started this project purely because the phrase "pi in the sky" popped into my head, and so started coding to produce a pi symbol randomly rotating about three axes in 3D. The obvious QB64 method is _MAPTRIANGLE(3D). All you have to do is work out the mathematics of rotations about the three Cartesian co-ordinates and plug the resulting corner positions into _MAPTRIANGLE(3D). The surface of the image is everywhere flat, but its corners move freely in the 3D space of _MAPTRIANGLE(3D), and as (vanishing point) perspective is coded into the _MAPTRIANGLE(3D) method, a very good-looking display is produced. I must emphasise that this QB64 method is so well produced that it can be used by novice and low-skill coders. In the Skill Range Venn Diagram, I sit in the low-skill sector, and I cannot do the real-3D stuff of our competent members.
To do this project I have had to go back to school-level calculus, geometry & algebra; oh, happy days! Having got the pi animation working, I then set about adding other features to demonstrate what can done with QB64 graphics. The final project uses both software and hardware imaging, and for the hardware images both _MAPTRIANGLE(2D) and _MAPTRIANGLE(3D). The program is designed to show how such images will interact. The program also uses a load of _MEM object processing in order to manipulate images, both at initiation and on-the-fly in real time.
Background Image
The graphical animations take place in front of a background image. This background (a landscape with added features) is software (,32 type) and has a single _PUTIMAGE directly after creating the 32-bit screen. This image stays displayed despite the running loop executing a _DISPLAY at each cycle (30 fps).
pi Animation
In order to change colour as the pi moves around, real-time editing of the image file is required. This is achieved by _MEM object manipulation each display cycle. _MEM processing can only be achieved with software images, whereas the pi image is hardware. So, firstly a software image is created at initiation and then at each cycle, a _MEM object of the software image is taken, that object is manipulated and the software image is copied to hardware and that image is displayed. Both the _MEM object and the hardware image are freed each cycle at the earliest opportunity. This method is repeated for all other real-time image manipulations.
Earthly and Celestial Animations
There are both earth-bound and celestial animations. The earth-bound animations (along with clouds and some rain) are continuous, whereas the celestial animations cycle in a random manner.
Earthly Animations
Beehive
Bees emerge and swarm from a suspended beehive in the foreground. The bees fly in the 3D space of _MAPTRIANGLE(3D) and both the hive and the (QB64) bee images are hardware (3D). After emerging in an outward direction the bees turn and fly in the opposite direction away from the viewer "into" the screen. Bees in front of the hive occlude it, and behind the hive they are occluded by it. As the hive image is a flat object, a bee moving from directly in front of to directly behind the hive travels right through it. The bees all appear to move to the right as they move away, but this is just the perspective. All the bees return to the hive after their flight out. In order to achieve such paths, the bees are flying in parabolic curves in the 3D space. There is the sound of humming bees, the more bes that are out the louder they sound.
Fountain
A fountain squirts droplets of water into the pond. There are 500 droplets of water each moving under gravity in the _MAPTRIANGLE(3D) space. Although as many droplets are sent behind the fountain as in the front, it looks as if they only fall at the front. This is just an artefact of the perspective.
Windmill
The moving windmill sails clearly show the 3D and perspective effects of _MAPTRIANGLE(3D). The sails appear to move in and out as they rotate and are smaller the further away they are. As the bees, fountain droplets and windmill sails are _MAPTRIANGLE(3D) images, they occlude each other dependent upon which is further away. The windmill itself is not a 3D object but part of the software background. The industrious Miller Heitor looks out from the windmill.
Clouds and Rain
Clouds pass above. They are slightly transparent so that objects behind can still be seen. One of the clouds is rain-bearing and a shower of 500 raindrops passes through. The clouds and raindrops are not 3D, and occlusions occur based upon order in which the _PUTIMAGE functions occur.
Flower Growth
As the rain passes, flowers can spring up in the earth. Flower images are 2D.
Rainbow
When the rain is in just the right place, a rainbow appears. The rainbow is a _MAPTRIANGLE(3D) image and occlusions with other such objects are dependent upon distance into the screen.
Graveyard
Ghostly images appear in the graveyard when certain celestial events take place. The gravestone images are part of the background 2D image.
Celestial Animations
At times, celestial animations occur.
Concorde
Fly-past of a supersonic passenger aircraft. The Concorde image is 2D. The aircraft creates a sonic boom. A ghostly image of Douglas Bader appears in the graveyard. Eventually the image disappears into thin air. This graphic effect is achieved, again, by _MEM object real-time processing (in this case changing alpha sequentially). Images here are 2D.
ET
A silhouette from a well-known science fiction film travels across the sky. The image is 2D. A ghostly film director appears in the graveyard.
Star Trek
The spacecraft from a well-known science-fiction television series moves through the _MAPTRIANGLE(3D) space coming from the distance. Members of the crew appear in the graveyard. Because the graveyard images are small and transparent, it is rather difficult to recognise who they are. From left to right they are McCoy, Uhura, Kirk, Sulu and Spock.
ISS
The 2D International Space Station passes overhead. The sound is that of Sputnik 1. Cosmonaut Yuri Gagarin appears in the graveyard.
Meteors
A 3D meteor shower occurs while Galileo looks on from the grave.
Transit
A transit of Venus occurs. This is a very rare event, the last occurring in 2012 and the next due in 2117, so we are very privileged. The goddess appears in the graveyard.
Thunderbirds
A bomb falls onto the windmill. Call for action from a well-known science-fiction television series. Help arrives and the bomb is safely removed. All images are 2D. The graveyard crew are Alan, Scott, Virgil, Gordon and John.
Zodiac
The signs of the Zodiac circle in the heavens. The image is the surface of an open-ended cylinder. This is the only non-flat 3D image in this program, and the real-3D effect requires multiple _MAPTRIANGLE(3D) processes. The Zodiac sign at the front is brightened, and this effect is, again, produced by real-time _MEM processing. In the video you can see how the Zodiac and pi images have a real 3D look with correct perspective and occlusion. Zodiac symbols of the prominent sign appear in the graveyard. For you I see a romantic liaison with a group from the shoe-making industry. Cobblers!
UFO
An alien spacecraft arrives and settles for a moment, and after probing the environment it lifts off and flies away. The image is _MAPTRIANGLE(3D) and occlusions with the windmill sails are correct. In order to make the landing, the spacecraft follows a helical path (circular x-, z- path and linear y- path). The arrival of this alien craft arouses the interest of two FBI special agents.
Spotlight
A spotlight illuminates the sky and reveals a pertinent message. The spotlight image is only 2D, and would have been better as 3D but is done this way to show the limitations. Again, _MEM processing is required to make the message image respond to the spotlight.
Discussion
This was a tinkering project. As ideas came, I'd change to new areas of coding and then return to unfinished parts. This is a bad method to do projects. Returning to old parts, you don't quite remember exactly what you previously did and end up making mistakes. But it is what it is. If left running, the program will cycle through the animations randomly, but I note that it crashes out at the start of the third cycle, so clearly there remains at least one error.
The program was created to demonstrate the amazing graphics capabilities of QB64, using the simple coding techniques of the QB64 _MAPTRIANGLE statement: the 3D _MAPTRIANGLE method gives a convincing 3D perspective view. Both 2D and 3D _MAPTRIANGLE methods are used and the advantages of the 3D method are evident.
Unzip the file and extract the folder into your PEQB64 directory. In the IDE make sure that you have the Run Option “Save EXE in source folder” checked. At program start there is a delay while the disk files are read and loaded into memory and image manipulations are performed.
Pi-in-the-Sky PE Edition.zip (Size: 18.08 MB / Downloads: 13)
The video shows a short excerpt of the running program.
The program features a number of animations (some 2D and some 3D) enhanced in some cases with accompanying audio.
The scene a landscape within which a variety of animations will occur. It takes approximately 10 mins to run through all of the animation sequences. There are earthly animations and celestial animations. During the celestial animations, there may be ghostly appearances in the terrestrial graveyard.
In the blue text I give details of the program coding methods, descriptions of the animations and background information. You do not need to read the blue text to run and enjoy (well, maybe!) the program.
I started this project purely because the phrase "pi in the sky" popped into my head, and so started coding to produce a pi symbol randomly rotating about three axes in 3D. The obvious QB64 method is _MAPTRIANGLE(3D). All you have to do is work out the mathematics of rotations about the three Cartesian co-ordinates and plug the resulting corner positions into _MAPTRIANGLE(3D). The surface of the image is everywhere flat, but its corners move freely in the 3D space of _MAPTRIANGLE(3D), and as (vanishing point) perspective is coded into the _MAPTRIANGLE(3D) method, a very good-looking display is produced. I must emphasise that this QB64 method is so well produced that it can be used by novice and low-skill coders. In the Skill Range Venn Diagram, I sit in the low-skill sector, and I cannot do the real-3D stuff of our competent members.
To do this project I have had to go back to school-level calculus, geometry & algebra; oh, happy days! Having got the pi animation working, I then set about adding other features to demonstrate what can done with QB64 graphics. The final project uses both software and hardware imaging, and for the hardware images both _MAPTRIANGLE(2D) and _MAPTRIANGLE(3D). The program is designed to show how such images will interact. The program also uses a load of _MEM object processing in order to manipulate images, both at initiation and on-the-fly in real time.
Background Image
The graphical animations take place in front of a background image. This background (a landscape with added features) is software (,32 type) and has a single _PUTIMAGE directly after creating the 32-bit screen. This image stays displayed despite the running loop executing a _DISPLAY at each cycle (30 fps).
pi Animation
In order to change colour as the pi moves around, real-time editing of the image file is required. This is achieved by _MEM object manipulation each display cycle. _MEM processing can only be achieved with software images, whereas the pi image is hardware. So, firstly a software image is created at initiation and then at each cycle, a _MEM object of the software image is taken, that object is manipulated and the software image is copied to hardware and that image is displayed. Both the _MEM object and the hardware image are freed each cycle at the earliest opportunity. This method is repeated for all other real-time image manipulations.
Earthly and Celestial Animations
There are both earth-bound and celestial animations. The earth-bound animations (along with clouds and some rain) are continuous, whereas the celestial animations cycle in a random manner.
Earthly Animations
Beehive
Bees emerge and swarm from a suspended beehive in the foreground. The bees fly in the 3D space of _MAPTRIANGLE(3D) and both the hive and the (QB64) bee images are hardware (3D). After emerging in an outward direction the bees turn and fly in the opposite direction away from the viewer "into" the screen. Bees in front of the hive occlude it, and behind the hive they are occluded by it. As the hive image is a flat object, a bee moving from directly in front of to directly behind the hive travels right through it. The bees all appear to move to the right as they move away, but this is just the perspective. All the bees return to the hive after their flight out. In order to achieve such paths, the bees are flying in parabolic curves in the 3D space. There is the sound of humming bees, the more bes that are out the louder they sound.
Fountain
A fountain squirts droplets of water into the pond. There are 500 droplets of water each moving under gravity in the _MAPTRIANGLE(3D) space. Although as many droplets are sent behind the fountain as in the front, it looks as if they only fall at the front. This is just an artefact of the perspective.
Windmill
The moving windmill sails clearly show the 3D and perspective effects of _MAPTRIANGLE(3D). The sails appear to move in and out as they rotate and are smaller the further away they are. As the bees, fountain droplets and windmill sails are _MAPTRIANGLE(3D) images, they occlude each other dependent upon which is further away. The windmill itself is not a 3D object but part of the software background. The industrious Miller Heitor looks out from the windmill.
Clouds and Rain
Clouds pass above. They are slightly transparent so that objects behind can still be seen. One of the clouds is rain-bearing and a shower of 500 raindrops passes through. The clouds and raindrops are not 3D, and occlusions occur based upon order in which the _PUTIMAGE functions occur.
Flower Growth
As the rain passes, flowers can spring up in the earth. Flower images are 2D.
Rainbow
When the rain is in just the right place, a rainbow appears. The rainbow is a _MAPTRIANGLE(3D) image and occlusions with other such objects are dependent upon distance into the screen.
Graveyard
Ghostly images appear in the graveyard when certain celestial events take place. The gravestone images are part of the background 2D image.
Celestial Animations
At times, celestial animations occur.
Concorde
Fly-past of a supersonic passenger aircraft. The Concorde image is 2D. The aircraft creates a sonic boom. A ghostly image of Douglas Bader appears in the graveyard. Eventually the image disappears into thin air. This graphic effect is achieved, again, by _MEM object real-time processing (in this case changing alpha sequentially). Images here are 2D.
ET
A silhouette from a well-known science fiction film travels across the sky. The image is 2D. A ghostly film director appears in the graveyard.
Star Trek
The spacecraft from a well-known science-fiction television series moves through the _MAPTRIANGLE(3D) space coming from the distance. Members of the crew appear in the graveyard. Because the graveyard images are small and transparent, it is rather difficult to recognise who they are. From left to right they are McCoy, Uhura, Kirk, Sulu and Spock.
ISS
The 2D International Space Station passes overhead. The sound is that of Sputnik 1. Cosmonaut Yuri Gagarin appears in the graveyard.
Meteors
A 3D meteor shower occurs while Galileo looks on from the grave.
Transit
A transit of Venus occurs. This is a very rare event, the last occurring in 2012 and the next due in 2117, so we are very privileged. The goddess appears in the graveyard.
Thunderbirds
A bomb falls onto the windmill. Call for action from a well-known science-fiction television series. Help arrives and the bomb is safely removed. All images are 2D. The graveyard crew are Alan, Scott, Virgil, Gordon and John.
Zodiac
The signs of the Zodiac circle in the heavens. The image is the surface of an open-ended cylinder. This is the only non-flat 3D image in this program, and the real-3D effect requires multiple _MAPTRIANGLE(3D) processes. The Zodiac sign at the front is brightened, and this effect is, again, produced by real-time _MEM processing. In the video you can see how the Zodiac and pi images have a real 3D look with correct perspective and occlusion. Zodiac symbols of the prominent sign appear in the graveyard. For you I see a romantic liaison with a group from the shoe-making industry. Cobblers!
UFO
An alien spacecraft arrives and settles for a moment, and after probing the environment it lifts off and flies away. The image is _MAPTRIANGLE(3D) and occlusions with the windmill sails are correct. In order to make the landing, the spacecraft follows a helical path (circular x-, z- path and linear y- path). The arrival of this alien craft arouses the interest of two FBI special agents.
Spotlight
A spotlight illuminates the sky and reveals a pertinent message. The spotlight image is only 2D, and would have been better as 3D but is done this way to show the limitations. Again, _MEM processing is required to make the message image respond to the spotlight.
Discussion
This was a tinkering project. As ideas came, I'd change to new areas of coding and then return to unfinished parts. This is a bad method to do projects. Returning to old parts, you don't quite remember exactly what you previously did and end up making mistakes. But it is what it is. If left running, the program will cycle through the animations randomly, but I note that it crashes out at the start of the third cycle, so clearly there remains at least one error.
Code: (Select All)
'Pi-in-the-Sky PE Edition Graphics Program by Magdha 2026-01-17 ex Qwerkey
'A Program which compares the use of _MAPTRIANGLE(2D) and _MAPTRIANGLE(3D)
'in an amusing and entertaining way.
'The use of _MEM object processing for graphics is illustrated.
'Acknowledgements: findsounds.com, freesound.org, freepik.com, pinclipart.com, imgbin.com, kissclipart.com, pngimg.com, vectorstock.com, sciencealert.com, startrek.com
CONST False = 0, True = NOT False
CONST XScreen% = 1100, YScreen% = 800, ZOffset% = -620
CONST PiSizeLess1% = 499, PiDisp% = 100, SunSize%% = 500, AmblinHalf%% = 50
CONST RBee% = 120, CBee% = 80
CONST BeeEntX% = -350, BeeEntY% = -250, HiveWidth% = 1009, HiveHeight% = 589, BWidth% = 350
CONST FountX% = -128, FountY% = -230, G! = 0.01
CONST ZodHeight% = 70, SpotRad% = 80, WQB64X% = 500, WQB64Y% = 350
CONST QB64X% = 300, QB64Y% = 50, UFOHalfX% = 150, UFOHalfY% = 60, UFORad% = 700
CONST Wind% = 150, WindX% = 550, WindHeight% = 280, SailX% = 44, SailY% = -154
'Derived Constant Variables:
CONST Zeta! = 0.07 * _PI 'Derived CONST (using formulae)
CONST ABee! = -4 * CBee% / (RBee% * RBee%), HX1% = -50 - (XScreen% / 2), HY1% = 300 - (YScreen% / 2)
CONST HX2% = HX1% + BWidth%, HY3% = HY1% - (BWidth% * HiveHeight% / HiveWidth%)
CONST ZBow% = ZOffset% + 100, ZodWidth% = ZodHeight% * 300 / 240, ZRad! = 12 * ZodWidth% / (2 * _PI)
CONST SpotInc! = 2 * _PI / 100, LampX% = XScreen% - 50, LampY% = YScreen% - 220
CONST Iota! = -0.23 * _PI, WindY% = YScreen% - 294, MillBombX1% = WindX% + 17, MillBombY1% = WindY% + 8
DIM Clouds&(15), CloudPos!(15, 2), CloudGo%%(15), RedGreenBlue!(5), Raindrops!(500, 1), Fountain!(500, 6)
DIM AmblinPos!(3), Enterprise!(2), Flora!(9, 5), FloraCount%(9), QB64Bees!(500, 4), Buzz%%(500), ConcordePos!(1)
DIM Perseids!(30, 6), Transit!(1), Virgil!(10), ZodiacSymImg&(12), SpotLight!(1)
DIM DispOrder%%(9), GraveImg&(5, 1), CrewImg&(5), TracyImg&(5), UFOImg&(3), LogoImg&(4)
DIM PiMem AS _MEM, PiOff AS _OFFSET, CMem AS _MEM, COff AS _OFFSET
DIM SHARED DispTrans!(8, 2), DoAnime%%
_TITLE "Pi in the Sky"
$EXEICON:'.\pi.ico'
RANDOMIZE (TIMER)
'Load (and manipulate) image files and load sounds
PRINT "Loading Files..."; 'The loading and manipulation of many image files takes a little time
'ET Image
TempImg1& = _LOADIMAGE("cyclist.png", 32) 'Software image
TempImg& = _NEWIMAGE(2 * AmblinHalf%% + 1, 2 * AmblinHalf%% + 1, 32)
_DEST TempImg&
_PUTIMAGE , TempImg1&
_FREEIMAGE TempImg1&
AmblinImg& = HardwareImage&(TempImg&) 'Convert image to hardware
'Wheels Image
TempImg1& = _NEWIMAGE(26, 2, 32)
_DEST TempImg1&
COLOR _RGB32(0, 0, 0), _RGBA32(0, 0, 0, 0)
CLS
LINE (0, 0)-(25, 1), , BF
TempImg& = _NEWIMAGE(27, 27, 32)
_DEST TempImg&
COLOR _RGB32(0, 0, 0), _RGBA32(0, 0, 0, 0)
CLS
CIRCLE (13, 13), 3
PAINT (13, 13)
CIRCLE (13, 13), 10
CIRCLE (13, 13), 13
PAINT (1, 13)
_PUTIMAGE (1, 12), TempImg1&
_MAPTRIANGLE (0, 0)-(25, 0)-(0, 1), TempImg1& TO(13, 1)-(14, 25)-(12, 1)
_MAPTRIANGLE (25, 1)-(0, 1)-(25, 0), TempImg1& TO(13, 25)-(12, 1)-(14, 25)
_MAPTRIANGLE (0, 0)-(25, 0)-(0, 1), TempImg1& TO(5, 5)-(22, 21)-(4, 5)
_MAPTRIANGLE (25, 1)-(0, 1)-(25, 0), TempImg1& TO(21, 21)-(4, 5)-(22, 21)
_MAPTRIANGLE (0, 0)-(25, 0)-(0, 1), TempImg1& TO(21, 5)-(5, 22)-(21, 4)
_MAPTRIANGLE (25, 1)-(0, 1)-(25, 0), TempImg1& TO(5, 21)-(21, 4)-(5, 22)
_FREEIMAGE TempImg1&
SpokesImg& = HardwareImage&(TempImg&)
SpielbergImg& = _NEWIMAGE(42, 110, 32)
_DEST SpielbergImg&
_PUTIMAGE , _LOADIMAGE("director.png", 32)
'Now manipulate image using _MEM processing
CMem = _MEMIMAGE(SpielbergImg&)
COff = 0
'Check for image background:
'If background set alpha (transparency) to zero
'Else set alpha to 120 to give a semi-transparent (ghostly) image
WHILE COff < CMem.SIZE
IF _MEMGET(CMem, CMem.OFFSET + COff + 3, _UNSIGNED _BYTE) < 50 THEN
_MEMPUT CMem, CMem.OFFSET + COff + 3, 0 AS _UNSIGNED _BYTE 'Alpha
ELSE
_MEMPUT CMem, CMem.OFFSET + COff + 3, 120 AS _UNSIGNED _BYTE 'Alpha
END IF
COff = COff + 4
WEND
_MEMFREE CMem 'Always free memory of _MEM object once manipulation is done
ETSound& = _SNDOPEN("eetea.mp3")
'Concorde Image
TempImg& = _NEWIMAGE(250, 1180, 32)
_DEST TempImg&
COLOR _RGBA32(180, 180, 210, 60), _RGBA32(0, 0, 0, 0)
CLS
_PUTIMAGE (0, 380)-(240, 416), _LOADIMAGE("concorde.png", 32)
LINE (244, 386)-(40, 1179)
LINE (244, 386)-(91, 0)
LINE (245, 386)-(41, 1179)
LINE (245, 386)-(92, 0)
LINE (246, 386)-(42, 1179)
LINE (246, 386)-(92, 0)
LINE (247, 386)-(43, 1179)
LINE (247, 386)-(93, 0)
LINE (248, 386)-(44, 1179)
LINE (248, 386)-(94, 0)
ConcordeImg& = HardwareImage&(TempImg&)
BaderImg& = _NEWIMAGE(42, 110, 32)
_DEST BaderImg&
_PUTIMAGE , _LOADIMAGE("bader.png", 32)
CMem = _MEMIMAGE(BaderImg&)
COff = 0
WHILE COff < CMem.SIZE
IF _MEMGET(CMem, CMem.OFFSET + COff + 3, _UNSIGNED _BYTE) < 50 THEN
_MEMPUT CMem, CMem.OFFSET + COff + 3, 0 AS _UNSIGNED _BYTE 'Alpha
ELSE
_MEMPUT CMem, CMem.OFFSET + COff + 3, 120 AS _UNSIGNED _BYTE 'Alpha
END IF
COff = COff + 4
WEND
_MEMFREE CMem
BoomSound& = _SNDOPEN("boom.mp3")
'Thunderbird2 Image
TempImg& = _LOADIMAGE("flyingbird.png", 32)
CMem = _MEMIMAGE(TempImg&)
COff = 0
'Check for image foreground:
'If not foreground set alpha (transparency) to zero (background)
WHILE COff < CMem.SIZE
B0~%% = _MEMGET(CMem, CMem.OFFSET + COff, _UNSIGNED _BYTE)
B1~%% = _MEMGET(CMem, CMem.OFFSET + COff + 1, _UNSIGNED _BYTE)
B2~%% = _MEMGET(CMem, CMem.OFFSET + COff + 2, _UNSIGNED _BYTE)
IF B0~%% + B1~%% + B2~%% > 750 THEN
_MEMPUT CMem, CMem.OFFSET + COff + 3, 0 AS _UNSIGNED _BYTE 'Alpha
END IF
COff = COff + 4
WEND
ThunderImg& = HardwareImage&(TempImg&)
'Bomb Image
BombImg& = _LOADIMAGE("bomb.png", 33)
'Windmill Bomb Image
MillBombImg& = _LOADIMAGE("windmillbomb.png", 33)
'Magnet Image
MagnetImg& = _LOADIMAGE("magnet.png", 33)
'Chain Image
TempImg1& = _LOADIMAGE("link.png", 32)
TempImg& = _NEWIMAGE(10, 400, 32)
_DEST TempImg&
FOR K%% = 0 TO 19
_PUTIMAGE (0, K%% * 20)-(9, (K%% + 1) * 20), TempImg1&
NEXT K%%
_FREEIMAGE TempImg1&
ChainImg& = HardwareImage&(TempImg&)
'Tracy Brothers Images
TempImg1& = _LOADIMAGE("bros.png", 32)
FOR K%% = 1 TO 5
'All grave images must be software
READ CrewDat%%
TracyImg&(CrewDat%%) = _NEWIMAGE(42, 110, 32)
_DEST TracyImg&(CrewDat%%)
_PUTIMAGE , TempImg1&, , (10 + (K%% - 1) * 116, 8)-(12 + (K%% - 1) * 116 + 103, 323)
CMem = _MEMIMAGE(TracyImg&(CrewDat%%))
COff = 0
WHILE COff < CMem.SIZE
IF _MEMGET(CMem, CMem.OFFSET + COff + 3, _UNSIGNED _BYTE) < 50 THEN
_MEMPUT CMem, CMem.OFFSET + COff + 3, 0 AS _UNSIGNED _BYTE 'Alpha
ELSE
_MEMPUT CMem, CMem.OFFSET + COff + 3, 140 AS _UNSIGNED _BYTE 'Alpha
END IF
COff = COff + 4
WEND
_MEMFREE CMem
NEXT K%%
_FREEIMAGE TempImg1&
BombSound& = _SNDOPEN("bombdrop.mp3")
_SNDVOL BombSound&, 0.5
TunderbirdsSound& = _SNDOPEN("birdsong.mp3")
'Star Trek Image
TempImg& = _LOADIMAGE("starship.png", 32)
CMem = _MEMIMAGE(TempImg&)
COff = 0
WHILE COff < CMem.SIZE
B0~%% = _MEMGET(CMem, CMem.OFFSET + COff, _UNSIGNED _BYTE)
B1~%% = _MEMGET(CMem, CMem.OFFSET + COff + 1, _UNSIGNED _BYTE)
B2~%% = _MEMGET(CMem, CMem.OFFSET + COff + 2, _UNSIGNED _BYTE)
IF B0~%% + B1~%% + B2~%% < 40 THEN
_MEMPUT CMem, CMem.OFFSET + COff + 3, 0 AS _UNSIGNED _BYTE 'Alpha
END IF
COff = COff + 4
WEND
StarTrekImg& = HardwareImage&(TempImg&)
'Star Trek Crew Images
TempImg1& = _LOADIMAGE("crew.png", 32)
FOR K%% = 1 TO 5
'All grave images here must be software (converted to hardware during calc)
READ CrewDat%%
CrewImg&(CrewDat%%) = _NEWIMAGE(42, 110, 32)
_DEST CrewImg&(CrewDat%%)
_PUTIMAGE , TempImg1&, , (12 + (K%% - 1) * 195, 0)-(12 + (K%% - 1) * 195 + 177, 474)
CMem = _MEMIMAGE(CrewImg&(CrewDat%%))
COff = 0
WHILE COff < CMem.SIZE
IF _MEMGET(CMem, CMem.OFFSET + COff + 3, _UNSIGNED _BYTE) < 50 THEN
_MEMPUT CMem, CMem.OFFSET + COff + 3, 0 AS _UNSIGNED _BYTE 'Alpha
ELSE
_MEMPUT CMem, CMem.OFFSET + COff + 3, 140 AS _UNSIGNED _BYTE 'Alpha
END IF
COff = COff + 4
WEND
_MEMFREE CMem
NEXT K%%
_FREEIMAGE TempImg1&
TrekSound& = _SNDOPEN("tvtheme.mp3")
'ISS Image
TempImg& = _LOADIMAGE("iss1.png", 32)
CMem = _MEMIMAGE(TempImg&)
COff = 0
WHILE COff < CMem.SIZE
B0~%% = _MEMGET(CMem, CMem.OFFSET + COff, _UNSIGNED _BYTE)
B1~%% = _MEMGET(CMem, CMem.OFFSET + COff + 1, _UNSIGNED _BYTE)
B2~%% = _MEMGET(CMem, CMem.OFFSET + COff + 2, _UNSIGNED _BYTE)
IF B0~%% + B1~%% + B2~%% < 40 THEN
_MEMPUT CMem, CMem.OFFSET + COff + 3, 0 AS _UNSIGNED _BYTE 'Alpha
END IF
COff = COff + 4
WEND
ISSImg& = HardwareImage&(TempImg&)
CosmonautImg& = _NEWIMAGE(42, 110, 32)
_DEST CosmonautImg&
_PUTIMAGE , _LOADIMAGE("yuri.png", 32)
CMem = _MEMIMAGE(CosmonautImg&)
COff = 0
WHILE COff < CMem.SIZE
IF _MEMGET(CMem, CMem.OFFSET + COff + 3, _UNSIGNED _BYTE) < 50 THEN
_MEMPUT CMem, CMem.OFFSET + COff + 3, 0 AS _UNSIGNED _BYTE 'Alpha
ELSE
_MEMPUT CMem, CMem.OFFSET + COff + 3, 120 AS _UNSIGNED _BYTE 'Alpha
END IF
COff = COff + 4
WEND
_MEMFREE CMem
SputnikSound& = _SNDOPEN("sputnik.mp3")
'Meteor Image
MeteorImg& = _LOADIMAGE("meteor.png", 33)
GalileoImg& = _NEWIMAGE(42, 110, 32)
_DEST GalileoImg&
_PUTIMAGE , _LOADIMAGE("galileo.png", 32)
CMem = _MEMIMAGE(GalileoImg&)
COff = 0
WHILE COff < CMem.SIZE
IF _MEMGET(CMem, CMem.OFFSET + COff + 3, _UNSIGNED _BYTE) < 50 THEN
_MEMPUT CMem, CMem.OFFSET + COff + 3, 0 AS _UNSIGNED _BYTE 'Alpha
ELSE
_MEMPUT CMem, CMem.OFFSET + COff + 3, 120 AS _UNSIGNED _BYTE 'Alpha
END IF
COff = COff + 4
WEND
_MEMFREE CMem
MeteorWindSound& = _SNDOPEN("gust.mp3")
MeteorSound& = _SNDOPEN("meaty_or.mp3")
'Venus Image
TempImg& = _NEWIMAGE(5, 5, 32)
_DEST TempImg&
COLOR _RGBA32(0, 0, 0, 255), _RGBA32(100, 100, 100, 0)
CLS
CIRCLE (2, 2), 2
PAINT (2, 2)
VenusImg& = HardwareImage&(TempImg&)
BotticelliImg& = _NEWIMAGE(42, 110, 32)
_DEST BotticelliImg&
_PUTIMAGE , _LOADIMAGE("venus.png", 32)
CMem = _MEMIMAGE(BotticelliImg&)
COff = 0
WHILE COff < CMem.SIZE
IF _MEMGET(CMem, CMem.OFFSET + COff + 3, _UNSIGNED _BYTE) < 50 THEN
_MEMPUT CMem, CMem.OFFSET + COff + 3, 0 AS _UNSIGNED _BYTE 'Alpha
ELSE
_MEMPUT CMem, CMem.OFFSET + COff + 3, 120 AS _UNSIGNED _BYTE 'Alpha
END IF
COff = COff + 4
WEND
_MEMFREE CMem
VenusSound& = _SNDOPEN("holst_v.mp3")
'UFO Image
TempImg& = _LOADIMAGE("ufo.png", 32)
CMem = _MEMIMAGE(TempImg&)
COff = 0
WHILE COff < CMem.SIZE
IF _MEMGET(CMem, CMem.OFFSET + COff + 3, _UNSIGNED _BYTE) > 50 THEN
_MEMPUT CMem, CMem.OFFSET + COff + 1, (_MEMGET(CMem, CMem.OFFSET + COff, _UNSIGNED _BYTE) * 0.7) AS _UNSIGNED _BYTE 'Blue
_MEMPUT CMem, CMem.OFFSET + COff + 1, (_MEMGET(CMem, CMem.OFFSET + COff + 1, _UNSIGNED _BYTE) * 0.1) AS _UNSIGNED _BYTE 'Green
_MEMPUT CMem, CMem.OFFSET + COff + 2, (_MEMGET(CMem, CMem.OFFSET + COff + 2, _UNSIGNED _BYTE) * 0.7) AS _UNSIGNED _BYTE 'Red
ELSE
_MEMPUT CMem, CMem.OFFSET + COff + 3, 0 AS _UNSIGNED _BYTE 'Alpha
END IF
COff = COff + 4
WEND
UFOImg&(0) = HardwareImage&(TempImg&)
TempImg& = _LOADIMAGE("ufo.png", 32)
CMem = _MEMIMAGE(TempImg&)
COff = 0
WHILE COff < CMem.SIZE
IF _MEMGET(CMem, CMem.OFFSET + COff + 3, _UNSIGNED _BYTE) > 50 THEN
_MEMPUT CMem, CMem.OFFSET + COff + 1, (_MEMGET(CMem, CMem.OFFSET + COff, _UNSIGNED _BYTE) * 0.95) AS _UNSIGNED _BYTE 'Blue
_MEMPUT CMem, CMem.OFFSET + COff + 1, (_MEMGET(CMem, CMem.OFFSET + COff + 1, _UNSIGNED _BYTE) * 0.1) AS _UNSIGNED _BYTE 'Green
_MEMPUT CMem, CMem.OFFSET + COff + 2, (_MEMGET(CMem, CMem.OFFSET + COff + 2, _UNSIGNED _BYTE) * 0.95) AS _UNSIGNED _BYTE 'Red
ELSE
_MEMPUT CMem, CMem.OFFSET + COff + 3, 0 AS _UNSIGNED _BYTE 'Alpha
END IF
COff = COff + 4
WEND
UFOImg&(1) = HardwareImage&(TempImg&)
TempImg1& = _LOADIMAGE("foxylady.png", 32)
FOR K%% = 2 TO 3
UFOImg&(K%%) = _NEWIMAGE(42, 110, 32)
_DEST UFOImg&(K%%)
_PUTIMAGE , TempImg1&, , ((K%% - 2) * 317, 0)-((K%% - 2) * 317 + 291, 577)
CMem = _MEMIMAGE(UFOImg&(K%%))
COff = 0
WHILE COff < CMem.SIZE
IF _MEMGET(CMem, CMem.OFFSET + COff + 3, _UNSIGNED _BYTE) < 50 THEN
_MEMPUT CMem, CMem.OFFSET + COff + 3, 0 AS _UNSIGNED _BYTE 'Alpha
ELSE
_MEMPUT CMem, CMem.OFFSET + COff + 3, 120 AS _UNSIGNED _BYTE 'Alpha
END IF
COff = COff + 4
WEND
_MEMFREE CMem
NEXT K%%
AlienImg& = _NEWIMAGE(42, 110, 32)
_PUTIMAGE , _LOADIMAGE("alien.jpg", 32), AlienImg&
CMem = _MEMIMAGE(AlienImg&)
COff = 0
WHILE COff < CMem.SIZE
IF _MEMGET(CMem, CMem.OFFSET + COff + 2, _UNSIGNED _BYTE) > 230 AND _MEMGET(CMem, CMem.OFFSET + COff + 1, _UNSIGNED _BYTE) > 230 AND _MEMGET(CMem, CMem.OFFSET + COff, _UNSIGNED _BYTE) > 230 THEN
_MEMPUT CMem, CMem.OFFSET + COff + 3, 0 AS _UNSIGNED _BYTE 'Alpha
_MEMPUT CMem, CMem.OFFSET + COff, 0 AS _UNSIGNED _BYTE 'Blue
ELSE
_MEMPUT CMem, CMem.OFFSET + COff + 3, 120 AS _UNSIGNED _BYTE 'Alpha
END IF
COff = COff + 4
WEND
_MEMFREE CMem
XSound& = _SNDOPEN("xsound.mp3")
XCallSound& = _SNDOPEN("xcalling.mp3")
XMachSound& = _SNDOPEN("xmachine.mp3")
'Zodiac Images
TempImg1& = _LOADIMAGE("zodiac.png", 32)
ZodiacTmpImg& = _NEWIMAGE(12 * ZodWidth%, ZodHeight%, 32)
_DEST ZodiacTmpImg&
FOR K%% = 4 TO 12
_PUTIMAGE ((K%% - 4) * ZodWidth% + 5, 5)-((K%% - 3) * ZodWidth% - 5, ZodHeight% - 5), TempImg1&, , (((K%% - 1) MOD 3) * 344, ((K%% - 1) \ 3) * 255 + 5)-(((K%% - 1) MOD 3) * 344 + 290, ((K%% - 1) \ 3) * 255 + 5 + 230)
NEXT K%%
FOR K%% = 1 TO 3
_PUTIMAGE ((K%% + 8) * ZodWidth% + 5, 5)-((K%% + 9) * ZodWidth% - 5, ZodHeight% - 5), TempImg1&, , (((K%% - 1) MOD 3) * 344, ((K%% - 1) \ 3) * 255 + 5)-(((K%% - 1) MOD 3) * 344 + 290, ((K%% - 1) \ 3) * 255 + 5 + 230)
NEXT K%%
CMem = _MEMIMAGE(ZodiacTmpImg&)
COff = 0
WHILE COff < CMem.SIZE
IF _MEMGET(CMem, CMem.OFFSET + COff + 3, _UNSIGNED _BYTE) > 180 THEN
_MEMPUT CMem, CMem.OFFSET + COff, 152 AS _UNSIGNED _BYTE 'Blue
_MEMPUT CMem, CMem.OFFSET + COff + 1, 202 AS _UNSIGNED _BYTE 'Green
_MEMPUT CMem, CMem.OFFSET + COff + 2, 204 AS _UNSIGNED _BYTE 'Red
ELSE
_MEMPUT CMem, CMem.OFFSET + COff, 50 AS _UNSIGNED _BYTE 'Blue
_MEMPUT CMem, CMem.OFFSET + COff + 1, 50 AS _UNSIGNED _BYTE 'Green
_MEMPUT CMem, CMem.OFFSET + COff + 2, 100 AS _UNSIGNED _BYTE 'Red
END IF
_MEMPUT CMem, CMem.OFFSET + COff + 3, 100 AS _UNSIGNED _BYTE 'Alpha
COff = COff + 4
WEND
_MEMFREE CMem
_FREEIMAGE TempImg1&
'Zodiac Symbols
TempImg1& = _LOADIMAGE("zodiacsym.png", 32)
FOR K%% = 1 TO 12
TempImg& = _NEWIMAGE(40, 40, 32)
_DEST TempImg&
_PUTIMAGE , TempImg1&, , (((K%% - 1) MOD 4) * 250 + 20, ((K%% - 1) \ 4) * 328 + 40)-(((K%% - 1) MOD 4) * 250 + 20 + 210, ((K%% - 1) \ 4) * 328 + 40 + 180)
ZodiacSymImg&(K%%) = HardwareImage&(TempImg&)
NEXT K%%
_FREEIMAGE TempImg1&
MysticSound& = _SNDOPEN("holst_n.mp3")
'Beam Image
TempImg& = _NEWIMAGE(501, 51, 32)
_DEST TempImg&
COLOR _RGBA32(200, 200, 100, 70), _RGBA32(200, 200, 100, 70)
CLS
BeamImg& = HardwareImage&(TempImg&)
'Spot Image
TempImg& = _NEWIMAGE(2 * SpotRad% + 1, 2 * SpotRad% + 1, 32)
_DEST TempImg&
COLOR _RGBA32(200, 200, 100, 120), _RGBA32(200, 200, 100, 0)
CLS
CIRCLE (SpotRad%, SpotRad%), SpotRad%
PAINT (SpotRad%, SpotRad%)
SpotImg& = HardwareImage&(TempImg&)
'Spotlight Image
SpotlightTmpImg& = _LOADIMAGE("spotlight.png", 32)
CMem = _MEMIMAGE(SpotlightTmpImg&)
COff = 0
WHILE COff < CMem.SIZE
IF _MEMGET(CMem, CMem.OFFSET + COff + 3, _UNSIGNED _BYTE) < 100 THEN _MEMPUT CMem, CMem.OFFSET + COff + 3, 0 AS _UNSIGNED _BYTE 'Alpha
COff = COff + 4
WEND
_MEMFREE CMem
'BlueSkies Image
RedPhoenix& = _LOADIMAGE("Red Phoenix.png", 32)
BluePhoenix& = _NEWIMAGE(200, 200, 32)
_DEST BluePhoenix&
COLOR _RGBA32(100, 100, 100, 100), _RGBA32(100, 100, 100, 0)
CLS
_PUTIMAGE , RedPhoenix&
_SOURCE BluePhoenix&
FOR PX% = 0 TO 199
FOR PY% = 0 TO 199
Col~& = POINT(PX%, PY%)
IF _ALPHA32(Col~&) > 20 THEN
PSET (PX%, PY%), _RGBA32(20, 20, 250, 200)
ELSE
PSET (PX%, PY%), _RGBA32(0, 0, 0, 0)
END IF
NEXT PY%
NEXT PX%
QB64TempImg& = _NEWIMAGE(WQB64X%, WQB64Y%, 32)
_DEST QB64TempImg&
COLOR _RGBA32(40, 40, 250, 100), _RGBA32(0, 0, 0, 0)
CLS
_FONT _LOADFONT("arialbd.ttf", 100)
_PRINTSTRING (120, 10), "QB64"
_FONT _LOADFONT("arialbd.ttf", 60)
_PRINTSTRING (10, 140), "Phoenix"
_PRINTSTRING (10, 200), "Edition"
_PUTIMAGE (270, 130)-(470, 330), BluePhoenix&
_FREEIMAGE BluePhoenix&
_FREEIMAGE RedPhoenix&
'Logo Images
FOR K%% = 1 TO 4
TempImg1& = _NEWIMAGE(102, 108, 32)
_DEST TempImg1&
COLOR _RGBA32(0, 0, 0, 54)
SELECT CASE K%%
CASE 1
'Q
LINE (12, 12)-(36, 84), , BF
LINE (69, 12)-(87, 84), , BF
LINE (63, 38)-(68, 84), , BF
LINE (37, 12)-(68, 25), , BF
LINE (37, 71)-(62, 84), , BF
LINE (37, 85)-(62, 99), , BF
CASE 2
'B
LINE (8, 12)-(32, 84), , BF
LINE (64, 12)-(77, 84), , BF
LINE (78, 12)-(88, 39), , BF
LINE (78, 59)-(88, 84), , BF
LINE (33, 12)-(63, 25), , BF
LINE (33, 39)-(63, 57), , BF
LINE (33, 72)-(63, 84), , BF
CASE 3
'6
LINE (12, 12)-(36, 85), , BF
LINE (68, 44)-(94, 85), , BF
LINE (37, 12)-(94, 25), , BF
LINE (37, 44)-(67, 58), , BF
LINE (37, 71)-(67, 85), , BF
CASE ELSE
'4
LINE (8, 12)-(31, 58), , BF
LINE (63, 12)-(88, 85), , BF
LINE (32, 38)-(62, 58), , BF
END SELECT
TempImg& = _NEWIMAGE(51, 54, 32)
_DEST TempImg&
_PUTIMAGE , TempImg1&
LogoImg&(K%%) = _COPYIMAGE(TempImg&, 33)
_FREEIMAGE TempImg1&
_FREEIMAGE TempImg&
NEXT K%%
BlueSkiesSound& = _SNDOPEN("reeves.mp3")
'Raindrop Image
TempImg& = _NEWIMAGE(2, 3, 32)
_DEST TempImg&
COLOR _RGBA32(150, 120, 20, 140), _RGBA32(100, 100, 100, 0)
CLS
PSET (1, 0)
LINE (0, 1)-(1, 2), , B
DropImg& = HardwareImage&(TempImg&)
'Flower Image
TempImg& = _NEWIMAGE(14, 30, 32)
_DEST TempImg&
_PUTIMAGE , _LOADIMAGE("corn.png", 32)
CornImg& = HardwareImage&(TempImg&)
'Rainbow Image
TempImg& = _NEWIMAGE(501, 301, 32)
_DEST TempImg&
COLOR _RGBA32(255, 0, 0, 0), _RGBA32(0, 0, 0, 0)
CLS
FOR K%% = 0 TO 127
SELECT CASE K%%
CASE 0 TO 58
COLOR _RGBA32(255 - 2 * K%%, 15 + CINT(4.4 * K%%), 0, 80)
CASE 59 TO 116
COLOR _RGBA32(0, 255 - 1.8 * (K%% - 58), 15 + CINT(4.4 * (K%% - 58)), 80)
CASE ELSE
COLOR _RGBA32(15 + CINT(13.5 * (K%% - 116)), 0, 200 - 2 * (K%% - 116), 80)
END SELECT
CIRCLE (249, 300), 250 - CINT(80 * K%% / 127)
CIRCLE (250, 300), 250 - CINT(80 * K%% / 127)
CIRCLE (251, 300), 250 - CINT(80 * K%% / 127)
NEXT K%%
RainbowImg& = HardwareImage&(TempImg&)
'Flying Bee Image
TempImg1& = _LOADIMAGE("QB64Bee-Alpha.png", 32)
WBee% = _WIDTH(TempImg1&) - 1
HBee% = _HEIGHT(TempImg1&) - 1
TempImg& = _NEWIMAGE(_WIDTH(TempImg1&), _HEIGHT(TempImg1&), 32)
_DEST TempImg&
COLOR _RGBA32(200, 200, 200, 150), RGBA32(0, 0, 0, 0)
CLS
_PUTIMAGE , TempImg1&
_FREEIMAGE TempImg1&
BeeImg& = HardwareImage&(TempImg&)
'Hive Image
TempImg2& = _LOADIMAGE("branch.png", 32)
CMem = _MEMIMAGE(TempImg2&)
COff = 0
WHILE COff < CMem.SIZE
B0~%% = _MEMGET(CMem, CMem.OFFSET + COff, _UNSIGNED _BYTE) 'Blue
B1~%% = _MEMGET(CMem, CMem.OFFSET + COff + 1, _UNSIGNED _BYTE) 'Green
B2~%% = _MEMGET(CMem, CMem.OFFSET + COff + 2, _UNSIGNED _BYTE) 'Red
B3~%% = _MEMGET(CMem, CMem.OFFSET + COff + 3, _UNSIGNED _BYTE) 'Alpha
IF B0~%% + B1~%% + B2~%% > 690 THEN
_MEMPUT CMem, CMem.OFFSET + COff + 3, 0 AS _UNSIGNED _BYTE 'Alpha
END IF
COff = COff + 4
WEND
_MEMFREE CMem
TempImg1& = _LOADIMAGE("blackhive.png", 32)
CMem = _MEMIMAGE(TempImg1&)
COff = 0
WHILE COff < CMem.SIZE
B0~%% = _MEMGET(CMem, CMem.OFFSET + COff, _UNSIGNED _BYTE) 'Blue
B1~%% = _MEMGET(CMem, CMem.OFFSET + COff + 1, _UNSIGNED _BYTE) 'Green
B2~%% = _MEMGET(CMem, CMem.OFFSET + COff + 2, _UNSIGNED _BYTE) 'Red
B3~%% = _MEMGET(CMem, CMem.OFFSET + COff + 3, _UNSIGNED _BYTE) 'Alpha
IF B0~%% + B1~%% + B2~%% < 30 THEN
_MEMPUT CMem, CMem.OFFSET + COff + 3, 0 AS _UNSIGNED _BYTE 'Alpha
END IF
COff = COff + 4
WEND
_MEMFREE CMem
TempImg& = _NEWIMAGE(HiveWidth% + 1, HiveHeight% + 1, 32)
_DEST TempImg&
_PUTIMAGE (600, 150), TempImg1&
_PUTIMAGE (0, 0), TempImg2&
HiveImg& = HardwareImage&(TempImg&)
_FREEIMAGE TempImg2&
_FREEIMAGE TempImg1&
HiveSound& = _SNDOPEN("beehive.mp3")
'Fountain Drop Image
TempImg1& = _LOADIMAGE("droplet.png", 32)
W% = _WIDTH(TempImg1&) - 1
H% = _HEIGHT(TempImg1&) - 1
TempImg& = _NEWIMAGE(W% + 1, H% + 1, 32)
_DEST TempImg&
_PUTIMAGE , TempImg1&
CMem = _MEMIMAGE(TempImg&)
COff = 0
WHILE COff < CMem.SIZE
IF _MEMGET(CMem, CMem.OFFSET + COff + 3, _UNSIGNED _BYTE) <> 0 THEN _MEMPUT CMem, CMem.OFFSET + COff + 3, 80 AS _UNSIGNED _BYTE 'Alpha
COff = COff + 4
WEND
DropletImg& = HardwareImage&(TempImg&)
' _MEMFREE CMem Already freed by HardwareImage& (_freeimage)
_FREEIMAGE TempImg1&
'Fountain Image
FountainImg& = _LOADIMAGE("fountain2.png", 33)
'Windmill Sails Image
TempImg& = _NEWIMAGE(300, 300, 32)
_DEST TempImg&
_PUTIMAGE , _LOADIMAGE("sails.png", 32)
SailsImg& = HardwareImage&(TempImg&)
'Pi Image
TempImg1& = _LOADIMAGE("pi1.png", 32)
PiTempImg& = _NEWIMAGE(PiSizeLess1% + 1, PiSizeLess1% + 1, 32)
_DEST PiTempImg&
_PUTIMAGE , TempImg1&
_FREEIMAGE TempImg1&
PiMem = _MEMIMAGE(PiTempImg&) 'Will not allow hardware image for _MEM object processing
PiOff = 0
WHILE PiOff < PiMem.SIZE
IF _MEMGET(PiMem, PiMem.OFFSET + PiOff + 1, _UNSIGNED _BYTE) > 20 THEN
_MEMPUT PiMem, PiMem.OFFSET + PiOff + 3, 255 AS _UNSIGNED _BYTE 'Alpha
_MEMPUT PiMem, PiMem.OFFSET + PiOff + 2, 0 AS _UNSIGNED _BYTE 'Red
_MEMPUT PiMem, PiMem.OFFSET + PiOff + 1, 255 AS _UNSIGNED _BYTE 'Green
_MEMPUT PiMem, PiMem.OFFSET + PiOff + 0, 0 AS _UNSIGNED _BYTE 'Blue
ELSE
_MEMPUT PiMem, PiMem.OFFSET + PiOff + 3, 0 AS _UNSIGNED _BYTE 'Alpha
END IF
PiOff = PiOff + 4
WEND
PiImg& = _COPYIMAGE(PiTempImg&, 33)
'Cloud Images
FOR K%% = 0 TO 15
READ X1%, Y1%, X2%, Y2%
W% = X2% - X1% + 1 'The +1's are needed
H% = Y2% - Y1% + 1
TempImg& = _NEWIMAGE(W%, H%, 32)
_DEST TempImg&
_PUTIMAGE (0, 0)-(W% - 1, H% - 1), _LOADIMAGE("mccloud.jpg", 32), , (X1%, Y1%)-(X2%, Y2%)
CMem = _MEMIMAGE(TempImg&) 'Don't need to DIM CMem each image
COff = 0
WHILE COff < CMem.SIZE 'The clouds different this way from previous) - must be because of placing onto screen peviously
B0~%% = _MEMGET(CMem, CMem.OFFSET + COff, _UNSIGNED _BYTE) 'Blue
B1~%% = _MEMGET(CMem, CMem.OFFSET + COff + 1, _UNSIGNED _BYTE) 'Green
B2~%% = _MEMGET(CMem, CMem.OFFSET + COff + 2, _UNSIGNED _BYTE) 'Red
IF B2~%% >= 30 AND B2~%% <= 80 AND B1~%% >= 170 AND B1~%% <= 210 AND B0~%% >= 230 THEN
_MEMPUT CMem, CMem.OFFSET + COff + 3, 0 AS _UNSIGNED _BYTE 'Alpha
ELSE
_MEMPUT CMem, CMem.OFFSET + COff + 3, 100 AS _UNSIGNED _BYTE 'Alpha
IF K%% = 0 THEN 'Dark Rain-cloud
_MEMPUT CMem, CMem.OFFSET + COff, CINT(0.7 * B0~%%) AS _UNSIGNED _BYTE
_MEMPUT CMem, CMem.OFFSET + COff + 1, CINT(0.7 * B1~%%) AS _UNSIGNED _BYTE
_MEMPUT CMem, CMem.OFFSET + COff + 2, CINT(0.7 * B2~%%) AS _UNSIGNED _BYTE
END IF
END IF
COff = COff + 4
WEND
IF K%% >= 12 THEN
READ X1%, Y1%, X2%, Y2%
FOR N% = X1% TO X2%
FOR M% = Y1% TO Y2%
COff = 4 * (N% + M% * W%)
_MEMPUT CMem, CMem.OFFSET + COff + 3, 0 AS _UNSIGNED _BYTE 'Alpha
NEXT M%
NEXT N%
IF K%% = 15 THEN
READ X1%, Y1%, X2%, Y2%
FOR N% = X1% TO X2%
FOR M% = Y1% TO Y2%
COff = 4 * (N% + M% * W%)
_MEMPUT CMem, CMem.OFFSET + COff + 3, 0 AS _UNSIGNED _BYTE 'Alpha
NEXT M%
NEXT N%
READ X1%, Y1%, X2%, Y2%
FOR N% = X1% TO X2%
FOR M% = Y1% TO Y2%
COff = 4 * (N% + M% * W%)
_MEMPUT CMem, CMem.OFFSET + COff + 3, 0 AS _UNSIGNED _BYTE 'Alpha
NEXT M%
NEXT N%
END IF
_MEMFREE CMem
END IF
Clouds&(K%%) = HardwareImage&(TempImg&)
NEXT K%%
'Background Images
'Moon Image
MoonTmpImg& = _NEWIMAGE(89, 99, 32)
_DEST MoonTmpImg&
COLOR _RGBA32(200, 200, 200, 0), RGBA32(0, 0, 0, 0)
CLS
_PUTIMAGE , _LOADIMAGE("moon.png", 32)
CMem = _MEMIMAGE(MoonTmpImg&)
COff = 0
WHILE COff < CMem.SIZE
B0~%% = _MEMGET(CMem, CMem.OFFSET + COff, _UNSIGNED _BYTE)
B1~%% = _MEMGET(CMem, CMem.OFFSET + COff + 1, _UNSIGNED _BYTE)
B2~%% = _MEMGET(CMem, CMem.OFFSET + COff + 2, _UNSIGNED _BYTE)
IF B0~%% + B1~%% + B2~%% < 80 THEN
_MEMPUT CMem, CMem.OFFSET + COff + 3, 0 AS _UNSIGNED _BYTE 'Alpha
END IF
COff = COff + 4
WEND
_MEMFREE CMem
'Background Mask Image
MaskTmpImg& = _NEWIMAGE(XScreen%, YScreen%, 32)
_DEST MaskTmpImg&
COLOR _RGB32(100, 100, 100), _RGBA32(0, 0, 0, 50)
'Initialisations
'Set clouds start positions (some to left of screen) & speeds
FOR K%% = 1 TO 15
CloudPos!(K%%, 0) = (RND * (XScreen% + _WIDTH(Clouds&(K%%)))) - _WIDTH(Clouds&(K%%)) - 5
CloudPos!(K%%, 1) = RND * 350 + 10
CloudPos!(K%%, 2) = 0.3 + 0.03 * (RND - 0.5)
CloudGo%%(K%%) = True
NEXT K%%
CloudPos!(0, 0) = -_WIDTH(Clouds&(0)) - 5
CloudPos!(0, 1) = RND * 350 + 10
CloudPos!(0, 2) = 0.3 + 0.03 * (RND - 0.5)
CloudGo%%(0) = True
Puddle% = YScreen% - 110
FOR N% = 0 TO 500
Raindrops!(N%, 1) = CINT((Puddle% - (CloudPos!(0, 1) + 36)) * RND)
Raindrops!(N%, 0) = 5 + CINT(86 * RND)
NEXT N%
'Pi coordinates
Phi! = _PI(0.1)
'Initial Pi colour
RedGreenBlue!(2) = 30 + CINT(223 * RND)
RedGreenBlue!(1) = 30 + CINT(223 * RND)
RedGreenBlue!(0) = 30 + CINT(223 * RND)
RedGreenBlue!(5) = -0.701
RedGreenBlue!(4) = -0.797
RedGreenBlue!(3) = -0.887
'Flowers
FOR K%% = 0 TO 9
FloraCount%(K%%) = 0
NEXT K%%
Blooming%% = False
'Fountain
FOR N% = 0 TO 500
Fountain!(N%, 0) = 0
Fountain!(N%, 1) = 100 'Start height
Fountain!(N%, 1) = -101
Fountain!(N%, 3) = 0.2 + 0.15 * (RND - 0.5)
Fountain!(N%, 4) = 0.6 + 0.2 * (RND - 0.5)
Fountain!(N%, 5) = _PI(1) + _PI(2) * RND
NEXT N%
WFount% = _WIDTH(DropletImg&) - 1
HFount% = _HEIGHT(DropletImg&) - 1
FX1% = FountX% - 8
FX2% = 8 + FountX%
FY1% = FountY% - 100
CALL OffScreen
DispOrder%%(0) = 10
FOR K%% = 1 TO 9
DispOrder%%(K%%) = K%%
NEXT K%%
MinGrave%% = 0
DispIndex%% = 10
PauseCount% = 0
PauseStop% = 600
DoBuzz%% = False
Swarm% = 0
DoSwarm% = 0
PauseSwarm% = 150
DoFount%% = False
PauseFont% = 300
WaitFont% = 0
ZBow1! = ZOffset% - 500
'Screen (Hardware 2nd)
SCREEN _NEWIMAGE(XScreen%, YScreen%, 32)
_SCREENMOVE 20, 5
_DEST 0
_DISPLAYORDER _SOFTWARE , _HARDWARE
'Draw Background
'Background is software and is only put once
'Other images are hardware and put each cycle
Ysun% = CINT(700 * SunSize% / 1000)
_PUTIMAGE (XScreen% - SunSize%, 0)-(XScreen% - 1, Ysun%), _LOADIMAGE("brightsun.png", 32)
LINE (0, 0)-(XScreen% - SunSize%, YScreen% - 1), _RGB32(58, 161, 255), BF
LINE (XScreen% - SunSize%, Ysun%)-(XScreen% - 1, YScreen% - 1), _RGB32(58, 161, 255), BF
_PUTIMAGE (100, 70)-(154, 130), MoonTmpImg&
_FREEIMAGE MoonTmpImg&
_PUTIMAGE (0, YScreen% - 1 - 350)-(XScreen% - 1, YScreen% - 1), _LOADIMAGE("landscape2a.png", 32)
FOR K%% = 1 TO 5
_PUTIMAGE (680 + K%% * 70, YScreen% - 140 - ABS(K%% - 3) * 14), _LOADIMAGE("gravestone.png", 32)
_MAPTRIANGLE (0, 0)-(57, 0)-(0, 69), _LOADIMAGE("soil.png", 32) TO(678 + K%% * 70, YScreen% - 42 - ABS(K%% - 3) * 14)-(678 + K%% * 70 + 58, YScreen% - 42 - ABS(K%% - 3) * 14)-(678 + K%% * 70 - 2, YScreen% - 42 - ABS(K%% - 3) * 14 + 69)
_MAPTRIANGLE (57, 69)-(0, 69)-(57, 0), _LOADIMAGE("soil.png", 32) TO(678 + K%% * 70 + 60, YScreen% - 42 - ABS(K%% - 3) * 14 + 69)-(678 + K%% * 70 - 2, YScreen% - 42 - ABS(K%% - 3) * 14 + 69)-(678 + K%% * 70 + 58, YScreen% - 42 - ABS(K%% - 3) * 14)
NEXT K%%
_PUTIMAGE (890, YScreen% - 154)-(944, YScreen% - 55), _LOADIMAGE("gravestone.png", 32)
_PUTIMAGE (324, YScreen% - 100), _LOADIMAGE("pond.png", 32)
_PUTIMAGE (LampX% - 20, LampY% - 20), SpotlightTmpImg&
SpotlightImg& = HardwareImage&(SpotlightTmpImg&)
_PUTIMAGE , MaskTmpImg&
_FREEIMAGE MaskTmpImg&
_FREEIMAGE MoonTmpImg&
TempImg& = _LOADIMAGE("windmill.png", 32) 'Windmill must not occlude flowers or be occluded by spotlight beam
CMem = _MEMIMAGE(TempImg&)
WHILE COff < CMem.SIZE
IF _MEMGET(CMem, CMem.OFFSET + COff + 3, _UNSIGNED _BYTE) < 230 THEN _MEMPUT CMem, CMem.OFFSET + COff + 3, 0 AS _UNSIGNED _BYTE 'Alpha
COff = COff + 4
WEND
_MEMFREE CMem
_PUTIMAGE (WindX%, WindY%)-(WindX% + CINT(WindHeight% * _WIDTH(TempImg&) / _HEIGHT(TempImg&)), WindY% + WindHeight%), TempImg&
_FREEIMAGE TempImg&
$CHECKING:OFF
'Checking off to help quicken up _MEM processing & reduce CPU load
'Now actually run working loop
WHILE INKEY$ = "" 'Press any key to terminate
_LIMIT 30
'Pi position & orientation
X0! = 200 * COS(Alpha!)
Y0! = 70 * COS(Beta!) + 105
'Rotate in Z-axis
PX1! = -PiDisp%
PY1! = PiDisp%
CALL Twist(Theta!, PX1!, PY1!)
PX2! = PiDisp%
PY2! = PiDisp%
CALL Twist(Theta!, PX2!, PY2!)
PX3! = -PiDisp%
PY3! = -PiDisp%
CALL Twist(Theta!, PX3!, PY3!)
PX4! = PiDisp%
PY4! = -PiDisp%
CALL Twist(Theta!, PX4!, PY4!)
'Rotate in Y-axis
PZ1! = 0
CALL Twist(Phi!, PZ1!, PX1!)
PZ2! = 0
CALL Twist(Phi!, PZ2!, PX2!)
PZ3! = 0
CALL Twist(Phi!, PZ3!, PX3!)
PZ4! = 0
CALL Twist(Phi!, PZ4!, PX4!)
'Rotate in X-axis
CALL Twist(Chi!, PY1!, PZ1!)
CALL Twist(Chi!, PY2!, PZ2!)
CALL Twist(Chi!, PY3!, PZ3!)
CALL Twist(Chi!, PY4!, PZ4!)
PX1! = PX1! + X0!
PX2! = PX2! + X0!
PX3! = PX3! + X0!
PX4! = PX4! + X0!
PY1! = PY1! + Y0!
PY2! = PY2! + Y0!
PY3! = PY3! + Y0!
PY4! = PY4! + Y0!
PZ1! = PZ1! + ZOffset%
PZ2! = PZ2! + ZOffset%
PZ3! = PZ3! + ZOffset%
PZ4! = PZ4! + ZOffset%
'Draw Images
'_DEST 0 Not needed
'Rainbow Image
IF CloudGo%%(0) AND CloudPos!(0, 0) > 10 AND CloudPos!(0, 0) < 320 THEN
_MAPTRIANGLE (0, 0)-(499, 0)-(0, 299), RainbowImg& TO(-700, 50, ZBow%)-(-300, 50, ZBow1!)-(-700, -300, ZBow%)
_MAPTRIANGLE (499, 299)-(0, 299)-(499, 0), RainbowImg& TO(-300, -300, ZBow1!)-(-700, -300, ZBow%)-(-300, 50, ZBow1!)
END IF
'Animations
SELECT CASE DoAnime%%
CASE 1
'Concorde
_PUTIMAGE (DispTrans!(0, 0), DispTrans!(0, 1)), ConcordeImg&
CASE 2
'Ee, Tea!
_PUTIMAGE (DispTrans!(0, 0), DispTrans!(0, 1)), AmblinImg&
_MAPTRIANGLE (0, 0)-(26, 0)-(0, 26), SpokesImg& TO(DispTrans!(1, 0), DispTrans!(1, 1))-(DispTrans!(2, 0), DispTrans!(2, 1))-(DispTrans!(3, 0), DispTrans!(3, 1))
_MAPTRIANGLE (26, 26)-(0, 26)-(26, 0), SpokesImg& TO(DispTrans!(4, 0), DispTrans!(4, 1))-(DispTrans!(3, 0), DispTrans!(3, 1))-(DispTrans!(2, 0), DispTrans!(2, 1))
_MAPTRIANGLE (0, 0)-(26, 0)-(0, 26), SpokesImg& TO(DispTrans!(5, 0), DispTrans!(5, 1))-(DispTrans!(6, 0), DispTrans!(6, 1))-(DispTrans!(7, 0), DispTrans!(7, 1))
_MAPTRIANGLE (26, 26)-(0, 26)-(26, 0), SpokesImg& TO(DispTrans!(8, 0), DispTrans!(8, 1))-(DispTrans!(7, 0), DispTrans!(7, 1))-(DispTrans!(6, 0), DispTrans!(6, 1))
CASE 3
'Star Trek
_MAPTRIANGLE (0, 0)-(452, 0)-(0, 196), StarTrekImg& TO(DispTrans!(1, 0), DispTrans!(1, 1), DispTrans!(1, 2))-(DispTrans!(2, 0), DispTrans!(1, 1), DispTrans!(1, 2))-(DispTrans!(1, 0), DispTrans!(3, 1), DispTrans!(1, 2))
_MAPTRIANGLE (452, 196)-(0, 196)-(452, 0), StarTrekImg& TO(DispTrans!(2, 0), DispTrans!(3, 1), DispTrans!(1, 2))-(DispTrans!(1, 0), DispTrans!(3, 1), DispTrans!(1, 2))-(DispTrans!(2, 0), DispTrans!(1, 1), DispTrans!(1, 2))
CASE 4
'ISS
_PUTIMAGE (DispTrans!(0, 0), DispTrans!(0, 1)), ISSImg&
CASE 5
'Meteors
FOR K%% = 0 TO 30
XDum1! = Perseids!(K%%, 0) - Perseids!(K%%, 6)
XDum! = Perseids!(K%%, 0) + Perseids!(K%%, 6)
YDum1! = Perseids!(K%%, 1) - Perseids!(K%%, 6) + 300
YDum! = Perseids!(K%%, 1) + Perseids!(K%%, 6) + 300
_MAPTRIANGLE (0, 0)-(35, 0)-(0, 35), MeteorImg& TO(XDum1!, YDum!, Perseids!(K%%, 2))-(XDum!, YDum!, Perseids!(K%%, 2))-(XDum1!, YDum1!, Perseids!(K%%, 2))
_MAPTRIANGLE (35, 35)-(0, 35)-(35, 0), MeteorImg& TO(XDum!, YDum1!, Perseids!(K%%, 2))-(XDum1!, YDum1!, Perseids!(K%%, 2))-(XDum!, YDum!, Perseids!(K%%, 2))
NEXT K%%
CASE 6
'Transit
_PUTIMAGE (DispTrans!(0, 0), DispTrans!(0, 1)), VenusImg&
CASE 7
'Thunderbird
IF BombsAway%% = 2 THEN
_PUTIMAGE (MillBombX1%, MillBombY1%), MillBombImg&
ELSE
_PUTIMAGE (DispTrans!(1, 0), DispTrans!(1, 1)), BombImg&
END IF
_PUTIMAGE (DispTrans!(3, 0), DispTrans!(3, 1))-(DispTrans!(4, 0), DispTrans!(4, 1)), ChainImg&, , (0, DispTrans!(5, 1))-(9, 399)
_PUTIMAGE (DispTrans!(2, 0), DispTrans!(2, 1)), MagnetImg&
_PUTIMAGE (DispTrans!(0, 0), DispTrans!(0, 1)), ThunderImg&
CASE 8
'Zodiac
FOR N% = 1 TO 100
X1! = (N% - 1) * 12 * ZodWidth% / 100
X2! = N% * 12 * ZodWidth% / 100
Y2! = 0
Y4! = ZodHeight%
Psi! = _PI(0.5) + (N% - 1) * _PI(2) / 100 - Pip!
DeltaPsi! = _PI(2) / 100
X11! = ZRad! * COS(Psi!)
Z11! = ZRad! * SIN(Psi!) + ZOffset% - 20
Y12! = 250
X12! = ZRad! * COS(Psi! + DeltaPsi!)
Z12! = ZRad! * SIN(Psi! + DeltaPsi!) + ZOffset% - 20
Y14! = Y12! - ZodHeight%
_MAPTRIANGLE (X1!, Y2!)-(X2!, Y2!)-(X1!, Y4!), ZodiacImg& TO(X11!, Y12!, Z11!)-(X12!, Y12!, Z12!)-(X11!, Y14!, Z11!)
_MAPTRIANGLE (X2!, Y4!)-(X1!, Y4!)-(X2!, Y2!), ZodiacImg& TO(X12!, Y14!, Z12!)-(X11!, Y14!, Z11!)-(X12!, Y12!, Z12!)
NEXT N%
_PUTIMAGE (896, 680), ZodiacSymImg&(Sym%%)
CASE 9
'UFO
_MAPTRIANGLE (0, 0)-(299, 0)-(0, 156), UFOImg&(UNorm%%) TO(DispTrans!(1, 0), DispTrans!(1, 1), DispTrans!(1, 2))-(DispTrans!(2, 0), DispTrans!(2, 1), DispTrans!(1, 2))-(DispTrans!(3, 0), DispTrans!(3, 1), DispTrans!(1, 2))
_MAPTRIANGLE (299, 156)-(0, 156)-(299, 0), UFOImg&(UNorm%%) TO(DispTrans!(4, 0), DispTrans!(4, 1), DispTrans!(1, 2))-(DispTrans!(3, 0), DispTrans!(3, 1), DispTrans!(1, 2))-(DispTrans!(2, 0), DispTrans!(2, 1), DispTrans!(1, 2))
CASE 10
'Spotlight (Would be better 3D)
IF DispTrans!(0, 0) > 0 THEN
_PUTIMAGE (QB64X%, QB64Y%), QB64Img&
_PUTIMAGE (DispTrans!(0, 0), DispTrans!(0, 1)), SpotImg&
FOR N% = 1 TO 100
F9! = DispTrans!(1, 0) - (N% - 1) * SpotInc!
G9! = DispTrans!(1, 0) - N% * SpotInc!
_MAPTRIANGLE (0, 0)-(500, 0)-(0, 50), BeamImg& TO(SpotLight!(0) - SpotRad% * SIN(G9!), SpotLight!(1) - SpotRad% * COS(G9!))-(LampX%, LampY%)-(SpotLight!(0) - SpotRad% * SIN(F9!), SpotLight!(1) - SpotRad% * COS(F9!))
NEXT N%
_FREEIMAGE QB64Img&
_PUTIMAGE (LampX% - 20, LampY% - 20), SpotlightImg&
FOR K%% = 1 TO 4
_PUTIMAGE (752 + K%% * 70, 670), LogoImg&(K%%)
NEXT K%%
END IF
END SELECT
'Clouds
FOR K%% = 0 TO 15
IF CloudGo%%(K%%) THEN
_PUTIMAGE (CINT(CloudPos!(K%%, 0)), CINT(CloudPos!(K%%, 1))), Clouds&(K%%)
IF K%% = 0 AND (CloudPos!(0, 0) < MillBombX1% - 100 OR CloudPos!(0, 0) > MillBombX1% + 130) THEN
'Rain
FOR N% = 0 TO 500
_PUTIMAGE (CINT(CloudPos!(0, 0) + Raindrops!(N%, 0)), CINT(CloudPos!(0, 1) + 36 + Raindrops!(N%, 1))), DropImg&
NEXT N%
END IF
END IF
NEXT K%%
'Flowers
FOR K%% = 0 TO 9
IF FloraCount%(K%%) > 1 AND FloraCount%(K%%) < 300 THEN
_PUTIMAGE (Flora!(K%%, 3), Flora!(K%%, 4))-(Flora!(K%%, 5), Flora!(K%%, 1)), CornImg&
END IF
NEXT K%%
'Pi
_MAPTRIANGLE _SEAMLESS(0, 0)-(PiSizeLess1%, 0)-(0, PiSizeLess1%), PiImg& TO(PX1!, PY1!, PZ1!)-(PX2!, PY2!, PZ2!)-(PX3!, PY3!, PZ3!)
_MAPTRIANGLE _SEAMLESS(PiSizeLess1%, PiSizeLess1%)-(0, PiSizeLess1%)-(PiSizeLess1%, 0), PiImg& TO(PX4!, PY4!, PZ4!)-(PX3!, PY3!, PZ3!)-(PX2!, PY2!, PZ2!)
_FREEIMAGE PiImg&
'Hive & Bees
_MAPTRIANGLE (0, 0)-(HiveWidth%, 0)-(0, HiveHeight%), HiveImg& TO(HX1%, HY1%, ZOffset%)-(HX2%, HY1%, ZOffset%)-(HX1%, HY3%, ZOffset%)
_MAPTRIANGLE (HiveWidth%, HiveHeight%)-(0, HiveHeight%)-(HiveWidth%, 0), HiveImg& TO(HX2%, HY3%, ZOffset%)-(HX1%, HY3%, ZOffset%)-(HX2%, HY1%, ZOffset%)
FOR N% = 0 TO 500
IF Buzz%%(N%) THEN
'z-axiz rotation about x = -r/2 (epsilon):
XDum! = QB64Bees!(N%, 0) + RBee% / 2
YDum! = 0
CALL Twist(QB64Bees!(N%, 4), XDum!, YDum!)
'y-axis rotation about x = -r/2 (zeta):
ZDum! = QB64Bees!(N%, 2)
CALL Twist(Zeta!, XDum!, ZDum!)
ZDum! = ZOffset% + ZDum!
XDum1! = BeeEntX% + XDum! - 10
XDum! = BeeEntX% + XDum! + 10
YDum1! = BeeEntY% + YDum! - 10
YDum! = BeeEntY% + YDum! + 10
_MAPTRIANGLE (0, 0)-(WBee%, 0)-(0, HBee%), BeeImg& TO(XDum1!, YDum!, ZDum!)-(XDum!, YDum!, ZDum!)-(XDum1!, YDum1!, ZDum!)
_MAPTRIANGLE (WBee%, HBee%)-(0, HBee%)-(WBee%, 0), BeeImg& TO(XDum!, YDum1!, ZDum!)-(XDum1!, YDum1!, ZDum!)-(XDum!, YDum!, ZDum!)
END IF
NEXT N%
'Fountain
_MAPTRIANGLE (0, 0)-(89, 0)-(0, 321), FountainImg& TO(FX1%, FountY%, ZOffset%)-(FX2%, FountY%, ZOffset%)-(FX1%, FY1%, ZOffset%)
_MAPTRIANGLE (89, 321)-(0, 321)-(90, 0), FountainImg& TO(FX2%, FY1%, ZOffset%)-(FX1%, FY1%, ZOffset%)-(FX2%, FountY%, ZOffset%)
FOR N% = 0 TO 500
IF Fountain!(N%, 1) > -100 THEN
ZDum! = Fountain!(N%, 2) + ZOffset%
XDum1! = Fountain!(N%, 6) - 4
XDum! = Fountain!(N%, 6) + 4
YDum1! = Fountain!(N%, 1) - 4 + FountY%
YDum! = Fountain!(N%, 1) + 4 + FountY%
_MAPTRIANGLE (0, 0)-(WFount%, 0)-(0, HFount%), DropletImg& TO(XDum1!, YDum1!, ZDum!)-(XDum!, YDum1!, ZDum!)-(XDum1!, YDum!, ZDum!)
_MAPTRIANGLE (WFount%, HFount%)-(0, HFount%)-(WFount%%, 0), DropletImg& TO(XDum!, YDum!, ZDum!)-(XDum1!, YDum!, ZDum!)-(XDum!, YDum1!, ZDum!)
END IF
NEXT N%
'Windmill
_MAPTRIANGLE _SEAMLESS(0, 0)-(299, 0)-(0, 299), SailsImg& TO(WX1!, WY1!, WZ1!)-(WX2!, WY2!, WZ2!)-(WX3!, WY3!, WZ3!)
_MAPTRIANGLE _SEAMLESS(299, 299)-(0, 299)-(299, 0), SailsImg& TO(WX4!, WY4!, WZ4!)-(WX3!, WY3!, WZ3!)-(WX2!, WY2!, WZ2!)
'Graven Images
IF MinGrave%% > 0 THEN
M1% = 110 - (GraveCount% - GraveDisp%)
M2% = M1% + 15
FOR K%% = MinGrave%% TO MaxGrave%%
GX% = 756 + (K%% - 1) * 70
GY% = 650 + 109
SELECT CASE GraveCount%
CASE GraveDisp% + 110 'Raise & disappear are set at 110 cycles
'Finish
_FREEIMAGE GraveImg&(K%%, 0)
_FREEIMAGE GraveImg&(K%%, 1)
MinGrave%% = 0
CASE IS > GraveDisp%
'Disappear into thin air - CMem manipulation for each image displayed
_FREEIMAGE GraveImg&(K%%, 1)
CMem = _MEMIMAGE(GraveImg&(K%%, 0))
FOR M% = M1% TO M2%
IF M% <= 109 THEN
FOR N% = 0 TO 41
COff = 4 * (N% + M% * 42) + CMem.OFFSET
IF _MEMGET(CMem, COff, _UNSIGNED _BYTE) > 0 THEN _MEMPUT CMem, COff + 3, (M2% - M%) * 160 / 15 AS _UNSIGNED _BYTE 'Alpha (Use Blue as marker)
NEXT N%
END IF
NEXT M%
_MEMFREE CMem
GraveImg&(K%%, 1) = _COPYIMAGE(GraveImg&(K%%, 0), 33)
_PUTIMAGE (GX%, 650), GraveImg&(K%%, 1)
CASE IS < 110 'Grave images timed on GraveCount% not AnimeCount%
'Raise from the Dead
_PUTIMAGE (GX%, GY% - GraveCount%)-(GX% + 41, GY%), GraveImg&(K%%, 1), , (0, 0)-(41, GraveCount%)
CASE ELSE
'Full image Displayed
_PUTIMAGE (GX%, 650), GraveImg&(K%%, 1)
END SELECT
NEXT K%%
GraveCount% = GraveCount% + 1
END IF
_DISPLAY
'Now data manipulations
'Pi Image Colour
'The Red/Green/Blue parameters of the software Pi image are set by _MEMPUT statements of the _MEM object
'_MEM processing can only be done on software images
PiOff = 0
WHILE PiOff < PiMem.SIZE
IF _MEMGET(PiMem, PiMem.OFFSET + PiOff + 3, _UNSIGNED _BYTE) <> 0 THEN
_MEMPUT PiMem, PiMem.OFFSET + PiOff + 2, CINT(RedGreenBlue!(0)) AS _UNSIGNED _BYTE 'Red
_MEMPUT PiMem, PiMem.OFFSET + PiOff + 1, CINT(RedGreenBlue!(1)) AS _UNSIGNED _BYTE 'Green
_MEMPUT PiMem, PiMem.OFFSET + PiOff + 0, CINT(RedGreenBlue!(2)) AS _UNSIGNED _BYTE 'Blue
END IF
PiOff = PiOff + 4
WEND
PiImg& = _COPYIMAGE(PiTempImg&, 33)
'The line above copies the Pi software image to hardware, ready for display
'The _MEM processing of the software image and then copy to hardware at each cycle
'is done for all images that need real-time image manipulation
'Here we sequence the Red/Green/Blue parameters of the software Pi image
RedGreenBlue!(2) = RedGreenBlue!(2) + RedGreenBlue!(5)
IF (RedGreenBlue!(2) < 30 AND RedGreenBlue!(5) < 0) OR (RedGreenBlue!(2) > 253 AND RedGreenBlue!(5) > 0) THEN RedGreenBlue!(5) = -RedGreenBlue!(5)
RedGreenBlue!(1) = RedGreenBlue!(1) + RedGreenBlue!(4)
IF (RedGreenBlue!(1) < 30 AND RedGreenBlue!(4) < 0) OR (RedGreenBlue!(1) > 253 AND RedGreenBlue!(4) > 0) THEN RedGreenBlue!(4) = -RedGreenBlue!(4)
RedGreenBlue!(0) = RedGreenBlue!(0) + RedGreenBlue!(3)
IF (RedGreenBlue!(0) < 30 AND RedGreenBlue!(3) < 0) OR (RedGreenBlue!(0) > 253 AND RedGreenBlue!(3) > 0) THEN RedGreenBlue!(3) = -RedGreenBlue!(3)
'Pi rotation angles
Theta! = PiBand!(Theta! - 0.05)
Phi! = PiBand!(Phi! + 0.02)
Chi! = PiBand!(Chi! + 0.022)
Alpha! = PiBand!(Alpha! + 0.015)
Beta! = PiBand!(Beta! + 0.017)
'Animation Parameters
SELECT CASE DoAnime%%
CASE 0
PauseCount% = PauseCount% + 1
IF PauseCount% = PauseStop% THEN
PauseCount% = 0
PauseStop% = 150 + INT(RND * 200)
RANDOMIZE (TIMER)
IF DispIndex%% = 10 THEN
DispIndex%% = 0
FOR K%% = 1 TO 10
K3%% = 1 + INT(RND * 9)
K4%% = 1 + INT(RND * 9)
IF K3%% <> K4%% THEN SWAP DispOrder%%(K3%%), DispOrder%%(K4%%)
NEXT K%%
END IF
DoAnime%% = DispOrder%%(DispIndex%%)
DispIndex%% = DispIndex%% + 1
AnimeCount% = 0
GraveCount% = 0
SELECT CASE DoAnime%%
CASE 1 'Concorde
ConcordePos!(0) = -260
ConcordePos!(1) = 0
GraveImg&(3, 0) = _COPYIMAGE(BaderImg&, 32)
GraveImg&(3, 1) = _COPYIMAGE(BaderImg&, 33)
MinGrave%% = 3
MaxGrave%% = 3
GraveDisp% = 150
CASE 2 'ET
AmblinPos!(0) = -2 * (AmblinHalf%% + 1) - 30
AmblinPos!(1) = 235
AmblinPos!(2) = 1.6 + CINT(0.4 * RND)
AmblinPos!(3) = -0.4
GraveImg&(3, 0) = _COPYIMAGE(SpielbergImg&, 32)
GraveImg&(3, 1) = _COPYIMAGE(SpielbergImg&, 33)
MinGrave%% = 3
MaxGrave%% = 3
GraveDisp% = 580
_SNDPLAY ETSound&
CASE 3 'Star Trek
Enterprise!(2) = -5000
Enterprise!(1) = -300
Enterprise!(0) = -500
FOR K%% = 1 TO 5
GraveImg&(K%%, 0) = _COPYIMAGE(CrewImg&(K%%), 32)
GraveImg&(K%%, 1) = _COPYIMAGE(CrewImg&(K%%), 33)
NEXT K%%
GraveDisp% = 1240
CASE 4 'ISS
ISSAngle! = _PI(-0.12)
ISS% = -2000
DispTrans!(0, 0) = CINT(XScreen% / 2 - 100 - ISS% * SIN(ISSAngle!))
DispTrans!(0, 1) = CINT(ISS% * COS(ISSAngle!) - ISS% + 10)
GraveImg&(3, 0) = _COPYIMAGE(CosmonautImg&, 32)
GraveImg&(3, 1) = _COPYIMAGE(CosmonautImg&, 33)
MinGrave%% = 3
MaxGrave%% = 3
GraveDisp% = 460
_SNDLOOP SputnikSound&
CASE 5 'Meteors
MaxRocks% = 600 + INT(RND * 200)
FOR K%% = 0 TO 30
Perseids!(K%%, 2) = ZOffset% - 2025
NEXT K%%
GraveImg&(3, 0) = _COPYIMAGE(GalileoImg&, 32)
GraveImg&(3, 1) = _COPYIMAGE(GalileoImg&, 33)
GraveDisp% = MaxRocks% - 200
_SNDLOOP MeteorWindSound&
_SNDLOOP MeteorSound&
CASE 6 'Transit
Transit!(0) = 966
Transit!(1) = 90
GraveImg&(3, 0) = _COPYIMAGE(BotticelliImg&, 32)
GraveImg&(3, 1) = _COPYIMAGE(BotticelliImg&, 33)
MinGrave%% = 3
MaxGrave%% = 3
GraveDisp% = 960
_SNDPLAY VenusSound&
CASE 7 'Thunderbirds
Virgil!(0) = XScreen% + 150
Virgil!(2) = 0.35 + RND * 0.05 'Thunderbird vert vel
Virgil!(1) = 200 + 418 * Virgil!(2)
Virgil!(3) = 623 'Bomb position
Virgil!(4) = -60
Virgil(8) = Virgil!(0) + 100 'Chain X- upper
Virgil(9) = Virgil!(1) + 30 'Chain y- upper
Virgil(10) = -0.2 + (0.05 * RND) 'Magnet vert vel
Virgil(6) = Virgil!(0) + 100 - 20 'Magnet position
Virgil(7) = 470 + 418 * Virgil(10)
Virgil!(5) = Virgil(7) + 4 - (Virgil!(1) + 30) ' Chain length
BombsAway%% = 1
FOR K%% = 1 TO 5
GraveImg&(K%%, 0) = _COPYIMAGE(TracyImg&(K%%), 32)
GraveImg&(K%%, 1) = _COPYIMAGE(TracyImg&(K%%), 33)
NEXT K%%
GraveDisp% = 620
CASE 8 'Zodiac
Pip! = _PI(1 / 12)
Sym%% = 1
OldSym%% = 1
CMem = _MEMIMAGE(ZodiacTmpImg&)
FOR M% = 0 TO ZodHeight% - 1
FOR N% = 5 TO ZodWidth% - 5
COff = 4 * (N% + 12 * M% * ZodWidth%)
IF _MEMGET(CMem, CMem.OFFSET + COff, _UNSIGNED _BYTE) > 60 THEN
_MEMPUT CMem, CMem.OFFSET + COff, 190 AS _UNSIGNED _BYTE 'Blue For Brightest
_MEMPUT CMem, CMem.OFFSET + COff + 1, 253 AS _UNSIGNED _BYTE 'Green
_MEMPUT CMem, CMem.OFFSET + COff + 2, 255 AS _UNSIGNED _BYTE 'Red
_MEMPUT CMem, CMem.OFFSET + COff + 3, 160 AS _UNSIGNED _BYTE 'Alpha
END IF
NEXT N%
NEXT M%
ZodiacImg& = _COPYIMAGE(ZodiacTmpImg&, 33)
_MEMFREE CMem
_SNDPLAY MysticSound&
CASE 9 'UFO
Xi! = _PI(0.4)
Omicron! = 0
UFOY! = 400
UNorm%% = 0
FOR K%% = 2 TO 3
GraveImg&(K%% + 1, 0) = _COPYIMAGE(UFOImg&(K%%), 32)
GraveImg&(K%% + 1, 1) = _COPYIMAGE(UFOImg&(K%%), 33)
NEXT K%%
GraveDisp% = 1240
CASE 10 'Spotlight
S1! = 0
S2! = 0
CMem = _MEMIMAGE(QB64TempImg&)
_SNDPLAY BlueSkiesSound&
END SELECT
END IF
CASE 1 'Concorde
ConcordePos!(0) = ConcordePos!(0) + 5
ConcordePos!(1) = ConcordePos!(1) - 1.25 + (RND - 0.5) * 0.1
DispTrans!(0, 0) = ConcordePos!(0)
DispTrans!(0, 1) = ConcordePos!(1)
IF ConcordePos!(0) > XScreen% + 100 THEN
CALL OffScreen
ELSEIF AnimeCount% = 93 THEN
_SNDPLAY BoomSound&
END IF
CASE 2 'ET
AmblinAngle! = PiBand!(AmblinAngle! + 0.03)
AmblinPos!(0) = AmblinPos!(0) + AmblinPos!(2)
AmblinPos!(1) = AmblinPos!(1) + AmblinPos!(3)
IF AmblinPos!(1) < -2 * (AmblinHalf%% + 1) THEN CALL OffScreen
DispTrans!(0, 0) = CINT(AmblinPos!(0))
DispTrans!(0, 1) = CINT(AmblinPos!(1))
X100! = -13
Y100! = -13
X200! = X100! + 26
Y200! = Y100!
X300! = X100!
Y300! = Y100! + 26
X400! = X100! + 26
Y400! = Y100! + 26
CALL Twist(AmblinAngle!, X100!, Y100!)
CALL Twist(AmblinAngle!, X200!, Y200!)
CALL Twist(AmblinAngle!, X300!, Y300!)
CALL Twist(AmblinAngle!, X400!, Y400!)
DispTrans!(1, 0) = CINT(AmblinPos!(0) + 18 + 13 + X100!)
DispTrans!(1, 1) = CINT(AmblinPos!(1) + 70 + 13 + Y100!)
DispTrans!(2, 0) = CINT(AmblinPos!(0) + 18 + 13 + X200!)
DispTrans!(2, 1) = CINT(AmblinPos!(1) + 70 + 13 + Y200!)
DispTrans!(3, 0) = CINT(AmblinPos!(0) + 18 + 13 + X300!)
DispTrans!(3, 1) = CINT(AmblinPos!(1) + 70 + 13 + Y300!)
DispTrans!(4, 0) = CINT(AmblinPos!(0) + 18 + 13 + X400!)
DispTrans!(4, 1) = CINT(AmblinPos!(1) + 70 + 13 + Y400!)
DispTrans!(5, 0) = CINT(AmblinPos!(0) + 68 + 13 + X100!)
DispTrans!(5, 1) = CINT(AmblinPos!(1) + 50 + 13 + Y100!)
DispTrans!(6, 0) = CINT(AmblinPos!(0) + 68 + 13 + X200!)
DispTrans!(6, 1) = CINT(AmblinPos!(1) + 50 + 13 + Y200!)
DispTrans!(7, 0) = CINT(AmblinPos!(0) + 68 + 13 + X300!)
DispTrans!(7, 1) = CINT(AmblinPos!(1) + 50 + 13 + Y300!)
DispTrans!(8, 0) = CINT(AmblinPos!(0) + 68 + 13 + X400!)
DispTrans!(8, 1) = CINT(AmblinPos!(1) + 50 + 13 + Y400!)
CASE 3 'Star Trek
IF Enterprise!(2) < 0 THEN
Enterprise!(2) = Enterprise!(2) + 2 - Enterprise!(2) / 2000
ELSE
Enterprise!(2) = Enterprise!(2) + 2
END IF
Enterprise!(1) = Enterprise!(1) + 0.36
Enterprise!(0) = Enterprise!(0) + 0.607
DispTrans!(1, 0) = Enterprise!(0)
DispTrans!(1, 1) = Enterprise!(1)
DispTrans!(1, 2) = ZOffset% + Enterprise!(2)
DispTrans!(2, 0) = Enterprise!(0) + 150
DispTrans!(3, 1) = Enterprise!(1) - 87
IF Enterprise!(0) > XScreen% / 2 + 10 THEN CALL OffScreen
IF AnimeCount% = 180 THEN
_SNDPLAY TrekSound&
MinGrave%% = 1
MaxGrave%% = 5
END IF
CASE 4 'ISS
ISSAngle! = ISSAngle! + 0.001
DispTrans!(0, 0) = CINT(XScreen% / 2 - 100 - ISS% * SIN(ISSAngle!))
DispTrans!(0, 1) = CINT(ISS% * COS(ISSAngle!) - ISS% + 10)
IF ISSAngle! > _PI(0.12) THEN
CALL OffScreen
_SNDSTOP SputnikSound&
END IF
CASE 5 'Meteor Shower
FOR K%% = 0 TO 30
IF Perseids!(K%%, 2) = ZOffset% - 2025 AND RND > 0.99 AND AnimeCount% <= MaxRocks% THEN
Perseids!(K%%, 0) = 0
Perseids!(K%%, 1) = 300
Perseids!(K%%, 2) = ZOffset% - 2020
Perseids!(K%%, 3) = (RND - 0.5) * 0.8
Perseids!(K%%, 4) = (RND - 0.5) * 0.3
Perseids!(K%%, 5) = 10 + (RND - 0.5) * 1
Perseids!(K%%, 6) = 0 'Meteor size
ELSEIF Perseids!(K%%, 2) > ZOffset% - 2025 THEN
Perseids!(K%%, 0) = Perseids!(K%%, 0) + Perseids!(K%%, 3)
Perseids!(K%%, 1) = Perseids!(K%%, 1) + Perseids!(K%%, 4)
Perseids!(K%%, 2) = Perseids!(K%%, 2) + Perseids!(K%%, 5)
Perseids!(K%%, 4) = Perseids!(K%%, 4) - 0.025 + (RND - 0.5) * 0.002
SELECT CASE Perseids!(K%%, 2) - ZOffset%
CASE IS < -1800
Perseids!(K%%, 6) = (2020 + (Perseids!(K%%, 2) - ZOffset%)) * 5 / 220
CASE IS >= 320
Perseids!(K%%, 2) = ZOffset% - 2025 'Go back to zero
CASE IS > 0
Perseids!(K%%, 6) = (320 - (Perseids!(K%%, 2) - ZOffset%)) * 5 / 320
END SELECT
END IF
NEXT K%%
IF AnimeCount% = 100 THEN
MinGrave%% = 3
MaxGrave%% = 3
ELSEIF AnimeCount% > MaxRocks% THEN
K%% = 0
CALL OffScreen
WHILE K%% <= 30 AND DoAnime%% = 0 'DoAnime%% = 0 from OffScreen
IF Perseids!(K%%, 2) <> ZOffset% - 2025 THEN DoAnime%% = 5
K%% = K%% + 1
WEND
_SNDSTOP MeteorSound&
_SNDSTOP MeteorWindSound&
END IF
CASE 6 'Transit of Venus
Transit!(0) = Transit!(0) + 0.05
Transit!(1) = Transit!(1) + 0.015
DispTrans!(0, 0) = CINT(Transit!(0))
DispTrans!(0, 1) = CINT(Transit!(1))
IF Transit!(0) > 1028 THEN CALL OffScreen
CASE 7 'Thunderbirds
SELECT CASE BombsAway%%
CASE 1
Virgil(4) = Virgil(4) + 2.6
IF AnimeCount% = 30 THEN _SNDPLAY BombSound&
IF Virgil(4) >= 515 THEN
Virgil(4) = 515
BombsAway%% = 2
END IF
CASE 2
IF AnimeCount% = 300 THEN
_SNDPLAY TunderbirdsSound&
MinGrave%% = 1
MaxGrave%% = 5
END IF
Virgil!(0) = Virgil!(0) - 1.7
Virgil!(1) = Virgil!(1) - Virgil!(2)
Virgil(6) = Virgil!(0) + 100 - 20 'Magnet position
Virgil(7) = Virgil!(7) - Virgil(10)
Virgil(8) = Virgil!(0) + 100 'Chain X- upper
Virgil(9) = Virgil!(1) + 30 'Chain y- upper
IF Virgil!(0) < 540 THEN
BombsAway%% = 3
Virgil!(0) = 540
Virgil(6) = 620 'Magnet position
Virgil(7) = 470
END IF
Virgil!(5) = Virgil(7) + 4 - (Virgil!(1) + 30) ' Chain length
CASE ELSE
Virgil!(0) = Virgil!(0) - 1.7
Virgil!(1) = Virgil!(1) - Virgil!(2)
Virgil(6) = Virgil!(0) + 100 - 20 'Magnet position
Virgil(7) = Virgil!(1) + 30 + Virgil!(5) - 4
Virgil(8) = Virgil!(0) + 100 'Chain X- upper
Virgil(9) = Virgil!(1) + 30 'Chain y- upper
Virgil!(3) = Virgil(6) + 3 'Bomb position
Virgil!(4) = Virgil(7) + 45
END SELECT
DispTrans!(0, 0) = CINT(Virgil(0))
DispTrans!(0, 1) = CINT(Virgil(1))
DispTrans!(1, 0) = CINT(Virgil(3))
DispTrans!(1, 1) = CINT(Virgil(4))
DispTrans!(2, 0) = CINT(Virgil(6))
DispTrans!(2, 1) = CINT(Virgil(7))
DispTrans!(3, 0) = CINT(Virgil(8))
DispTrans!(3, 1) = CINT(Virgil(9))
DispTrans!(4, 0) = CINT(Virgil(8) + 9)
DispTrans!(4, 1) = CINT(Virgil!(1) + 30 + Virgil!(5))
DispTrans!(5, 1) = CINT(399 - Virgil(5))
IF Virgil!(0) < -300 THEN
CALL OffScreen
_SNDSTOP TunderbirdsSound&
END IF
CASE 8 'Zodiac
Pip! = PiBand!(Pip! + _PI(0.001))
IF AnimeCount% = 3000 THEN
CALL OffScreen
_FREEIMAGE ZodiacImg&
CMem = _MEMIMAGE(ZodiacTmpImg&)
FOR M% = 0 TO ZodHeight% - 1
FOR N% = 5 TO ZodWidth% - 5
COff = 4 * (N% + 12 * M% * ZodWidth% + (OldSym%% - 1) * ZodWidth%) + CMem.OFFSET
IF _MEMGET(CMem, COff, _UNSIGNED _BYTE) > 60 THEN
_MEMPUT CMem, COff, 152 AS _UNSIGNED _BYTE 'Blue
_MEMPUT CMem, COff + 1, 202 AS _UNSIGNED _BYTE 'Green
_MEMPUT CMem, COff + 2, 204 AS _UNSIGNED _BYTE 'Red
_MEMPUT CMem, COff + 3, 100 AS _UNSIGNED _BYTE 'Alpha
END IF
NEXT N%
NEXT M%
_MEMFREE CMem
END IF
IF Pip! >= 0 THEN
Sym%% = INT(1 + 12 * Pip! / _PI(2))
ELSE
Sym%% = INT(13 + 12 * Pip! / _PI(2))
END IF
IF Sym%% <> OldSym%% THEN
_FREEIMAGE ZodiacImg&
CMem = _MEMIMAGE(ZodiacTmpImg&)
FOR M% = 0 TO ZodHeight% - 1
FOR N% = 5 TO ZodWidth% - 5
COff = 4 * (N% + 12 * M% * ZodWidth% + (OldSym%% - 1) * ZodWidth%) + CMem.OFFSET
IF _MEMGET(CMem, COff, _UNSIGNED _BYTE) > 60 THEN
_MEMPUT CMem, COff, 152 AS _UNSIGNED _BYTE 'Blue
_MEMPUT CMem, COff + 1, 202 AS _UNSIGNED _BYTE 'Green
_MEMPUT CMem, COff + 2, 204 AS _UNSIGNED _BYTE 'Red
_MEMPUT CMem, COff + 3, 100 AS _UNSIGNED _BYTE 'Alpha
END IF
COff = 4 * (N% + 12 * M% * ZodWidth% + (Sym%% - 1) * ZodWidth%) + CMem.OFFSET
IF _MEMGET(CMem, COff, _UNSIGNED _BYTE) > 60 THEN
_MEMPUT CMem, COff, 190 AS _UNSIGNED _BYTE 'Blue For Brightest
_MEMPUT CMem, COff + 1, 253 AS _UNSIGNED _BYTE 'Green
_MEMPUT CMem, COff + 2, 255 AS _UNSIGNED _BYTE 'Red
_MEMPUT CMem, COff + 3, 160 AS _UNSIGNED _BYTE 'Alpha
END IF
NEXT N%
NEXT M%
ZodiacImg& = _COPYIMAGE(ZodiacTmpImg&, 33)
_MEMFREE CMem
OldSym%% = Sym%%
END IF
CASE 9 'UFO
'Windmill ought to be hardware 3D for ufo to go behind, but just fly above windmill at all times
SELECT CASE AnimeCount%
CASE IS < 1810
'Come in to land
Xi! = Xi! + 0.002
CALL SinCos(Xi!, UFORad%, UFOX!, UFOZ!)
UFOX! = UFOX! + 580
UFOY! = UFOY! - 0.4
IF AnimeCount% = 150 THEN
_SNDPLAY XSound&
MinGrave%% = 3
MaxGrave%% = 4
END IF
CASE IS < 2000
'Descend
UFOY! = UFOY! - 0.8
CASE IS < 2020
'Settle
IF AnimeCount% = 2001 THEN
GraveCount% = 0
GraveImg&(3, 0) = _COPYIMAGE(AlienImg&, 32)
GraveImg&(3, 1) = _COPYIMAGE(AlienImg&, 33)
MinGrave%% = 3
MaxGrave%% = 3
GraveDisp% = 870
END IF
CASE IS < 2300
'Ground activity
IF UNorm%% = 1 AND AnimeCount% / 15 = AnimeCount% \ 15 THEN
UNorm%% = 0
ELSEIF UNorm%% = 0 AND (AnimeCount% + 10) / 15 = (AnimeCount% + 10) \ 15 THEN
UNorm%% = 1
END IF
IF AnimeCount% = 2040 THEN
_SNDLOOP XMachSound&
ELSEIF AnimeCount% = 2299 THEN
UNorm%% = 0
_SNDSTOP XMachSound&
END IF
CASE IS < 2400
'Launch
UFOY! = UFOY! + 0.8
CASE IS < 2500
'Tilt ready for flight: Rotate in Z-axis
UX1! = -UFOHalfX%
UY1! = UFOHalfY%
CALL Twist(Omicron!, UX1!, UY1!)
UX2! = UFOHalfX%
UY2! = UFOHalfY%
CALL Twist(Omicron!, UX2!, UY2!)
UX3! = -UFOHalfX%
UY3! = -UFOHalfY%
CALL Twist(Omicron!, UX3!, UY3!)
UX4! = UFOHalfX%
UY4! = -UFOHalfY%
CALL Twist(Omicron!, UX4!, UY4!)
Omicron! = Omicron! - 0.002
CASE IS < 3060
'Flight back to alien centre
IF AnimeCount% = 2515 THEN _SNDPLAY XCallSound&
UFOX! = UFOX! + 0.5
UFOY! = UFOY! + 2.7
UFOZ! = UFOZ! + 2.3
CASE ELSE
CALL OffScreen
END SELECT
IF AnimeCount% < 2400 THEN
DispTrans!(1, 0) = UFOX! - UFOHalfX%
DispTrans!(1, 1) = UFOY! + UFOHalfY%
DispTrans!(2, 0) = UFOX! + UFOHalfX%
DispTrans!(2, 1) = DispTrans!(1, 1)
DispTrans!(3, 0) = DispTrans!(1, 0)
DispTrans!(3, 1) = UFOY! - UFOHalfY%
DispTrans!(4, 0) = DispTrans!(2, 0)
DispTrans!(4, 1) = DispTrans!(3, 1)
ELSE
DispTrans!(1, 0) = UFOX! + UX1!
DispTrans!(1, 1) = UFOY! + UY1!
DispTrans!(2, 0) = UFOX! + UX2!
DispTrans!(2, 1) = UFOY! + UY2!
DispTrans!(3, 0) = UFOX! + UX3!
DispTrans!(3, 1) = UFOY! + UY3!
DispTrans!(4, 0) = UFOX! + UX4!
DispTrans!(4, 1) = UFOY! + UY4!
END IF
DispTrans!(1, 2) = ZOffset! + UFOZ! - 600
IF UNorm%% = 1 THEN DispTrans!(1, 2) = DispTrans!(1, 2) + 10
CASE 10 'Spotlight
SpotLight!(0) = QB64X% + 0.5 * SpotRad% + ((WQB64X% - SpotRad%) / 2) * (1 + COS(S1!))
SpotLight!(1) = QB64Y% + 0.5 * SpotRad% + ((WQB64Y% - SpotRad%) / 2) * (1 - COS(S2!))
D9! = SQR((LampX% - SpotLight!(0)) * (LampX% - SpotLight!(0)) + (LampY% - SpotLight!(1)) * (LampY% - SpotLight!(1)))
DispTrans!(1, 0) = _ACOS(SpotRad% / D9!) - _ACOS((SpotLight!(1) - LampY%) / D9!)
DispTrans!(0, 0) = CINT(SpotLight!(0) - SpotRad%)
DispTrans!(0, 1) = CINT(SpotLight!(1) - SpotRad%)
FOR N% = 0 TO WQB64X% - 1
FOR M% = 0 TO WQB64Y% - 1
COff = 4 * (N% + M% * WQB64X%) + CMem.OFFSET
IF _MEMGET(CMem, COff, _UNSIGNED _BYTE) <> 0 THEN
Q0% = QB64X% + N% - SpotLight!(0)
Q1% = QB64Y% + M% - SpotLight!(1)
IF SQR(Q0% * Q0% + Q1% * Q1%) < SpotRad% THEN
_MEMPUT CMem, COff + 3, 255 AS _UNSIGNED _BYTE 'Alpha
ELSE
_MEMPUT CMem, COff + 3, 0 AS _UNSIGNED _BYTE 'Alpha
END IF
END IF
NEXT M%
NEXT N%
QB64Img& = _COPYIMAGE(QB64TempImg&, 33)
S1! = PiBand!(S1! + 0.01)
S2! = PiBand!(S2! + 0.007)
IF AnimeCount% = 2405 THEN
CALL OffScreen
_MEMFREE CMem
_FREEIMAGE QB64Img&
END IF
END SELECT
IF DoAnime%% > 0 THEN AnimeCount% = AnimeCount% + 1
'Clouds
FOR K%% = 0 TO 15
IF CloudGo%%(K%%) THEN
CloudPos!(K%%, 0) = CloudPos!(K%%, 0) + CloudPos!(K%%, 2) + (RND - 0.5) * 0.02
IF K%% = 0 THEN
IF CloudPos!(K%%, 0) > MillBombX1% + 128 AND Puddle% = YScreen% - 110 THEN
Puddle% = YScreen% - 180
FOR N% = 0 TO 500
Raindrops!(N%, 1) = CINT((Puddle% - (CloudPos!(0, 1) + 36)) * RND)
NEXT N%
END IF
END IF
IF CloudPos!(K%%, 0) > XScreen% + 10 THEN
CloudGo%%(K%%) = False
END IF
ELSEIF RND > 0.99 THEN
CloudPos!(K%%, 0) = -_WIDTH(Clouds&(K%%)) - 5 'Clouds start off off-screen left
CloudPos!(K%%, 1) = RND * 350 + 10
CloudPos!(K%%, 2) = 0.3 + 0.03 * (RND - 0.5)
IF K%% = 0 THEN
Puddle% = YScreen% - 110
FOR N% = 0 TO 500
Raindrops!(N%, 1) = CINT((Puddle% - (CloudPos!(0, 1) + 36)) * RND)
NEXT N%
END IF
CloudGo%%(K%%) = True
END IF
NEXT K%%
'Raindrops
FOR N% = 0 TO 500
Raindrops!(N%, 1) = Raindrops!(N%, 1) + RND * 0.75
IF Raindrops!(N%, 1) > Puddle% - (CloudPos!(0, 1) + 36) THEN Raindrops!(N%, 1) = 0
NEXT N%
'Rainbow
ZBow1! = ZOffset% - 500 + 10 * SIN(Sigma!)
Sigma! = PiBand!(Sigma! + 0.07)
'Flowers
FOR K%% = 0 TO 9
IF FloraCount%(K%%) > 0 THEN 'Growth/Living/Kill
IF FloraCount%(K%%) = 16 THEN Blooming%% = False 'Stop Blooming
IF FloraCount%(K%%) < 120 THEN Flora!(K%%, 2) = Flora!(K%%, 2) + 0.25 'Growth
IF FloraCount%(K%%) < 400 THEN
XHalf%% = CINT(14 * Flora!(K%%, 2) / 60)
Flora!(K%%, 3) = Flora!(K%%, 0) - XHalf%%
Flora!(K%%, 4) = Flora!(K%%, 1) - CINT(Flora!(K%%, 2))
Flora!(K%%, 5) = Flora!(K%%, 0) + XHalf%%
FloraCount%(K%%) = FloraCount%(K%%) + 1
ELSE
FloraCount%(K%%) = 0 'Kill
END IF
ELSEIF FloraCount%(K%%) = 0 AND NOT Blooming%% AND ((CloudPos!(0, 0) > 14 AND CloudPos!(0, 0) < WindX% - 10) OR (CloudPos!(0, 0) > MillBombX1% + 132 AND CloudPos!(0, 0) < XScreen% - 90)) THEN 'Limit to before windmill
Blooming%% = True
FloraCount%(K%%) = 1
Flora!(K%%, 0) = CloudPos!(0, 0) - 5
Flora!(K%%, 1) = Puddle% + 15 * (RND - 0.5)
Flora!(K%%, 2) = 0
END IF
NEXT K%%
'Bees
'About 320 bees out at any one time
Swarm% = 0
FOR N% = 0 TO 500
IF Buzz%%(N%) THEN
Swarm% = Swarm% + 1
Eta! = ATN(2 * ABee! * QB64Bees!(N%, 0)) 'Simple atn() works - _ATAN2() not needed and didn't work successfully
CALL SinCos(Eta!, QB64Bees!(N%, 3), deltaX!, deltaZ!)
QB64Bees!(N%, 0) = QB64Bees!(N%, 0) + deltaX!
QB64Bees!(N%, 2) = QB64Bees!(N%, 2) + deltaZ!
IF QB64Bees!(N%, 2) < QB64Bees!(N%, 1) THEN QB64Bees!(N%, 3) = -0.6 - 0.3 * (RND - 0.5)
IF QB64Bees!(N%, 0) < -RBee% / 2 THEN Buzz%%(N%) = False
ELSE
IF RND > 0.999 AND DoBuzz%% THEN
Buzz%%(N%) = True
QB64Bees!(N%, 0) = -RBee% / 2 'X
QB64Bees!(N%, 2) = CBee% + ABee! * (QB64Bees!(N%, 0) * QB64Bees!(N%, 0)) 'Z
QB64Bees!(N%, 3) = 0.6 + 0.3 * (RND - 0.5) 'V
QB64Bees!(N%, 4) = _PI(RND) 'Epsilon: Y-X angle
QB64Bees!(N%, 1) = -300 - 100 * (RND - 0.5) 'Furthest z- Bee Path (-ve)
END IF
END IF
NEXT N%
IF Swarm% = 0 THEN
IF DoSwarm% = 0 THEN _SNDSTOP HiveSound&
DoSwarm% = DoSwarm% + 1
IF DoSwarm% = PauseSwarm% THEN
DoBuzz%% = True
SwarmTime% = 150 + CINT(RND * 1800)
BeesOut% = 0
_SNDLOOP HiveSound&
_SNDVOL HiveSound&, 0
END IF
ELSE
_SNDVOL HiveSound&, Swarm% / 500
BeesOut% = BeesOut% + 1
IF BeesOut% = SwarmTime% THEN
DoBuzz%% = False
PauseSwarm% = 150 + CINT(RND * 800)
DoSwarm% = 0
END IF
END IF
'Fountain
FOR N% = 0 TO 500
IF Fountain!(N%, 1) < -100 THEN
IF RND > 0.98 AND DoFount%% THEN
Fountain!(N%, 0) = 0
Fountain!(N%, 1) = 0 ' start height
Fountain!(N%, 3) = 0.2 + 0.15 * (RND - 0.5)
Fountain!(N%, 4) = 0.8 + 0.2 * (RND - 0.5)
Fountain!(N%, 5) = _PI(-0.5) + _PI(2) * (RND - 0.5)
'rotate -pi to +pi around y- axis
Fountain!(N%, 2) = 0
Fountain!(N%, 6) = Fountain!(N%, 0)
CALL Twist(Fountain!(N%, 5), Fountain!(N%, 6), Fountain!(N%, 2)) 'D1/2 will get changed
Fountain!(N%, 6) = Fountain!(N%, 6) + FountX%
END IF
ELSE
Fountain!(N%, 0) = Fountain!(N%, 0) + Fountain!(N%, 3)
Fountain!(N%, 1) = Fountain!(N%, 1) + Fountain!(N%, 4)
Fountain!(N%, 4) = Fountain!(N%, 4) - G!
'rotate -pi to +pi around y- axis
Fountain!(N%, 2) = 0
Fountain!(N%, 6) = Fountain!(N%, 0)
CALL Twist(Fountain!(N%, 5), Fountain!(N%, 6), Fountain!(N%, 2)) 'D1/2 will get changed
Fountain!(N%, 6) = Fountain!(N%, 6) + FountX%
END IF
NEXT N%
IF NOT DoFount%% THEN
WaitFont% = WaitFont% + 1
IF WaitFont% = PauseFont% THEN
DoFount%% = True
FontTime% = 150 + CINT(RND * 1800)
FontCount% = 0
END IF
ELSE
FontCount% = FontCount% + 1
IF FontCount% = FontTime% THEN
DoFount%% = False
PauseFont% = 150 + CINT(RND * 800)
WaitFont% = 0
END IF
END IF
'Windmill
'Rotate in Z-axis
WX1! = -Wind%
WY1! = Wind%
CALL Twist(Lambda!, WX1!, WY1!)
WX2! = Wind%
WY2! = Wind%
CALL Twist(Lambda!, WX2!, WY2!)
WX3! = -Wind%
WY3! = -Wind%
CALL Twist(Lambda!, WX3!, WY3!)
WX4! = Wind%
WY4! = -Wind%
CALL Twist(Lambda!, WX4!, WY4!)
'Rotate in Y-axis
WZ1! = 0
CALL Twist(Iota!, WZ1!, WX1!)
WZ2! = 0
CALL Twist(Iota!, WZ2!, WX2!)
WZ3! = 0
CALL Twist(Iota!, WZ3!, WX3!)
WZ4! = 0
CALL Twist(Iota!, WZ4!, WX4!)
WX1! = CINT(WX1! + SailX%)
WX2! = CINT(WX2! + SailX%)
WX3! = CINT(WX3! + SailX%)
WX4! = CINT(WX4! + SailX%)
WY1! = CINT(WY1! + SailY%)
WY2! = CINT(WY2! + SailY%)
WY3! = CINT(WY3! + SailY%)
WY4! = CINT(WY4! + SailY%)
WZ1! = CINT(WZ1! + ZOffset%)
WZ2! = CINT(WZ2! + ZOffset%)
WZ3! = CINT(WZ3! + ZOffset%)
WZ4! = CINT(WZ4! + ZOffset%)
Lambda! = PiBand!(Lambda! - 0.01)
WEND
SYSTEM
FUNCTION HardwareImage& (ImageName&)
HardwareImage& = _COPYIMAGE(ImageName&, 33)
_FREEIMAGE ImageName&
END FUNCTION
FUNCTION PiBand! (PiAngle!)
SELECT CASE PiAngle!
CASE IS < -_PI
PiBand! = PiAngle! + _PI(2)
CASE IS > _PI
PiBand! = PiAngle! - _PI(2)
CASE ELSE
PiBand! = PiAngle!
END SELECT
END FUNCTION
SUB Twist (Angle!, D1!, D2!) 'D1/2 will get changed
' x' = x cos theta -y sin theta; y' = x sin theta +y cos theta
DTemp! = D1!
D1! = DTemp! * COS(Angle!) - D2! * SIN(Angle!)
D2! = DTemp! * SIN(Angle!) + D2! * COS(Angle!)
END SUB
SUB SinCos (Angled!, R!, X!, Y!)
X! = R! * COS(Angled!)
Y! = R! * SIN(Angled!)
END SUB
SUB OffScreen
FOR K1%% = 0 TO 8
DispTrans!(K1%%, 0) = -1000
DispTrans!(K1%%, 2) = ZOffset%
NEXT K1%%
DoAnime%% = 0
END SUB
'Tracy Brothers Order
DATA 2,3,1,4,5
DATA 1,3,5,2,4
'Cloud Manipulation Data
DATA 252,118,354,170
DATA 330,166,426,214
DATA 30,34,184,104
DATA 186,26,390,118
DATA 394,22,584,110
DATA 76,110,216,156
DATA 426,110,594,204
DATA 14,156,144,206
DATA 20,308,186,370
DATA 188,294,344,362
DATA 14,388,134,442
DATA 166,378,336,440
DATA 384,206,586,274
DATA 0,0,42,8
'with A
DATA 366,288,564,364
DATA 40,70,80,76
'with B
DATA 346,356,620,448
DATA 114,0,154,8
'with C
DATA 62,156,390,290
DATA 190,0,292,14
DATA 268,10,328,58
DATA 0,0,82,50
'with D

