1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292
|
10REM >Snow
20REM Copyright 2010, 7th software
30REM All rights reserved.
40REM www.7thsoftware.co.uk
50REM
60REM Redistribution and use in source and binary forms, with or without
70REM modification, are permitted provided that the following conditions are met:
80REM
90REM 1. Redistributions of source code must retain the above copyright notice,
100REM this list of conditions and the following disclaimer.
110REM
120REM 2. Redistributions in binary form must reproduce the above copyright notice,
130REM this list of conditions and the following disclaimer in the documentation
140REM and/or other materials provided with the distribution.
150REM
160REM 3. Neither the name of the copyright holder nor the names of its contributors
170REM may be used to endorse or promote products derived from this software without
180REM specific prior written permission.
190REM
200REM THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
210REM AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
220REM IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
230REM ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
240REM LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
250REM CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
260REM SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
270REM INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
280REM CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
290REM ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
300REM POSSIBILITY OF SUCH DAMAGE.
310REM
320REM --
330REM
340REM Dedicated to Karen.
341REM
342REM Adjusted for 64-bit Matrix Brandy
350
360ON ERROR PROCerror
370PROCinitialise
380PROCplot_sky
390PROCsnowing_loop
400QUIT
410:
420REM Simple error handler
430DEF PROCerror
440ON ERROR OFF
450PRINT'REPORT$" (";ERL")"
460END
470ENDPROC
480:
490REM Initialise global constants and variables
500DEF PROCinitialise
510LOCAL f%, c%, pwd$
520
530REM MODE 640,480,32
540MODE 1280,720,32
550REM MODE 1920,1080,32
560OFF
570MOUSE OFF
580
590REM Get some SWI numbers, which are faster to use than SWI name strings
600SYS "OS_SWINumberFromString",, "OS_ReadMonotonicTime" TO ReadMono%
610SYS "OS_SWINumberFromString",, "ColourTrans_SetGCOL" TO SetGCOL%
620
630REM Number of snow flakes
640MG_flakes% = 1999
650G_flakes% = MG_flakes% + 1
660
670REM Some maximum values
680MAX_Z% = 20
690
700REM Wind
710wind_ax = 0
720wind_az = 0
730
740REM Background colour
750bb% = 64 + RND(64)
760gg% = (bb% * 0.2) + RND(bb% * 0.6)
770rr% = (bb% * 0.1) + RND(bb% * 0.3)
780
790REM Screen dimensions
800DIM blk%% 32
810!blk%% = 4
820blk%%!4 = 5
830blk%%!8 = 11
840blk%%!12 = 12
850blk%%!16 = -1
860SYS "OS_ReadVduVariables", blk%%, blk%%
870S_xe% = !blk%%
880S_ye% = blk%%!4
890S_x% = (blk%%!8 + 1) << S_xe%
900S_y% = (blk%%!12 + 1) << S_ye%
910
920REM Colour look-up table
930DIM col%(MAX_Z%)
940FOR f% = 0 TO MAX_Z%
950c% = &FF - (f% * 9.5)
960col%(f%) = (c% << 24) OR (c% << 16) OR (c% << 8)
970NEXT
980
990REM Initialise the snow flakes
1000F_x% = 0
1010F_y% = 1
1020F_c% = 2
1030F_a% = 3
1040F_z% = 4
1050DIM plot_flake(G_flakes%, F_z%)
1060FOR f% = 0 TO G_flakes%
1070PROCinit_flake(f%)
1080plot_flake(f%, F_y%) = RND(S_y%) + S_y%
1090NEXT
1100ENDPROC
1110:
1120REM Plot the sky, very slowly
1130DEF PROCplot_sky
1140LOCAL y%
1150
1160FOR y% = S_y% TO 0 STEP -1 << S_ye%
1170PROCset_bg_col(y%)
1180LINE 0, y%, S_x%, y%
1190NEXT
1200ENDPROC
1210:
1220REM Run the snowing animation for a while before exiting to the next part of the demo
1230DEF PROCsnowing_loop
1240LOCAL start%, stop%, time%, tick%
1250
1260time% = 0
1270tick% = 0
1280SYS ReadMono% TO start%
1290REPEAT
1300PROCanimate
1310SYS ReadMono% TO stop%
1320
1330REM Tweak the number of snow flakes if the machine isn't managing to animate fast enough
1340time% += stop% - start%
1350start% = stop%
1360tick% += 1
1370IF tick% = 10 THEN
1380PROCadjust_fps(time%)
1390time% = 0
1400tick% = 0
1410ENDIF
1420UNTIL FALSE
1430ENDPROC
1440:
1450REM Initialise the position of a snowflake
1460DEF PROCinit_flake(f%)
1470LOCAL col%
1480
1490CASE RND(4) OF
1500WHEN 1
1510plot_flake(f%, F_x%) = RND(S_x% * 0.5) + S_x% + 12
1520plot_flake(f%, F_y%) = RND(S_y%)
1530WHEN 2
1540plot_flake(f%, F_x%) = RND(S_x% * 0.5) - S_x% - 12
1550plot_flake(f%, F_y%) = RND(S_y%)
1560WHEN 3
1570plot_flake(f%, F_x%) = RND(S_x% * 2) - (S_x% * 0.5)
1580plot_flake(f%, F_y%) = 12 + S_y%
1590WHEN 4
1600plot_flake(f%, F_x%) = RND(S_x%)
1610plot_flake(f%, F_y%) = RND(S_y%)
1620ENDCASE
1630plot_flake(f%, F_a%) = RND(360) - 1
1640plot_flake(f%, F_z%) = RND(MAX_Z%) - 1
1650
1660col% = plot_flake(f%, F_z%) + RND(9) - 5
1670IF col% < 0 THEN
1680col% = 0
1690ELSE
1700IF col% >= MAX_Z% THEN col% = MAX_Z% - 1
1710ENDIF
1720plot_flake(f%, F_c%) = col%(col%)
1730ENDPROC
1740:
1750REM Update the position of all the snowflakes by one frame
1760DEF PROCanimate
1770LOCAL f%, x%, y%, z%, dw
1780
1790REM Update the angle of the wind direction and variability with depth
1800wind_ax += (RND(75) - 1) / 100
1810wind_az += (RND(30) - 1) / 10
1820IF wind_ax >= 360 THEN wind_ax = wind_ax MOD 360
1830IF wind_az >= 360 THEN wind_az = wind_az MOD 360
1840wind_x = COS RAD wind_ax
1850wind_z = COS RAD wind_az
1860
1870REM Loop through all the snow flakes
1880FOR f% = 0 TO G_flakes%
1890x% = plot_flake(f%, F_x%)
1900y% = plot_flake(f%, F_y%)
1910z% = plot_flake(f%, F_z%)
1920
1930REM x position is changed by wind_x (with z lending some perspective)
1940REM Magic numbers all assume approx 10 to 15 fps for sensible looking movement
1950dw = wind_x + (wind_x * wind_z * z% * 0.5)
1960plot_flake(f%, F_x%) += (MAX_Z% * 4 * dw) / (z% + 7)
1970plot_flake(f%, F_y%) -= 6 + ((MAX_Z% << 1) - z%) * 0.5
1980plot_flake(f%, F_x%) += ((MAX_Z% - z%) * 0.25) * COS RAD plot_flake(f%, F_a%)
1990plot_flake(f%, F_a%) += 5 + RND(10)
2000
2010REM If the snowflake has landed somewhere, reinitialise it somewhere else
2020IF plot_flake(f%, F_y%) < -64 THEN
2030REM Don't bother with the undraw because we're off the bottom of the screen
2040PROCinit_flake(f%)
2050z% = plot_flake(f%, F_z%)
2060ELSE
2070PROCremove_flake(x%, y%, z%)
2080ENDIF
2090SYS SetGCOL%, plot_flake(f%, F_c%)
2100PROCplot_flake(plot_flake(f%, F_x%), plot_flake(f%, F_y%), z%)
2110NEXT
2120ENDPROC
2130:
2140REM Tweak the number of snowflakes to try to maintain a reasonable number of frames per second
2150DEF PROCadjust_fps(time%)
2160LOCAL max%, f%
2170
2180REM Calculate new maximum number of snowflakes
2190IF time% THEN
2200max% = G_flakes% * 66.67 / time%
2210IF max% >= MG_flakes% THEN max% = MG_flakes%
2220ELSE
2230max% = MG_flakes%
2240ENDIF
2250
2260REM Remove any surpluss flakes
2270FOR f% = max% + 1 TO G_flakes%
2280PROCremove_flake(plot_flake(f%, F_x%), plot_flake(f%, F_y%), plot_flake(f%, F_z%))
2290NEXT
2300G_flakes% = max%
2310ENDPROC
2320:
2330REM Plot a snowflake at a given position and distance from viewer
2340DEF PROCplot_flake(x%, y%, z%)
2350CASE z% DIV 2 OF
2360WHEN 0, 1
2370RECTANGLE FILL x% - 2, y% - 2, 4, 4
2380POINT x% - 4, y%
2390POINT x% + 4, y%
2400POINT x%, y% - 4
2410POINT x%, y% + 4
2420WHEN 2, 3
2430LINE x% - 4, y% - 4, x% + 4, y% + 4
2440LINE x% + 4, y% - 4, x% - 4, y% + 4
2450LINE x% - 2, y%, x% + 2, y%
2460LINE x%, y% - 2, x%, y% + 2
2470WHEN 4
2480RECTANGLE FILL x% - 2, y% - 2, 4, 4
2490WHEN 5
2500LINE x% - 2, y%, x%, y% + 2
2510LINE x%, y% - 2, x% + 2, y%
2520WHEN 6
2530LINE x% - 2, y%, x% + 2, y%
2540LINE x%, y% - 2, x%, y% + 2
2550WHEN 7
2560RECTANGLE x%, y%, 2
2570WHEN 8, 9
2580LINE x%, y%, x% + 2, y%
2590OTHERWISE
2600POINT x%, y%
2610ENDCASE
2620ENDPROC
2630:
2640REM Clear an area of screen where a snow flake was
2650DEF PROCremove_flake(x%, y%, z%)
2660PROCset_bg_col(y%)
2670CASE z% DIV 2 OF
2680WHEN 0, 1, 2, 3
2690RECTANGLE FILL x% - 4, y% - 4, 10, 10
2700WHEN 4, 5, 6
2710RECTANGLE FILL x% - 2, y% - 2, 4, 4
2720WHEN 7
2730RECTANGLE x%, y%, 2
2740WHEN 8, 9
2750LINE x%, y%, x% + 2, y%
2760OTHERWISE
2770POINT x%, y%
2780ENDCASE
2790ENDPROC
2800:
2810REM Given a vertical position, return the appropriate background colour for the current gradient
2820DEF PROCset_bg_col(y%)
2830LOCAL r%, g%, b%
2840
2850r% = rr% * (y%*1.5 / S_y%)
2860g% = gg% * (y%*1.5 / S_y%)
2870b% = bb% * (y%*1.5 / S_y%)
2880SYS SetGCOL%, (b% << 24) OR (g% << 16) OR (r% << 8)
2890ENDPROC
2900:
|