Home » Archimedes archive » Acorn User » AU 1994-02.adf » !FEMS_App_FEMS_App » !FEMS/FEMS2
!FEMS/FEMS2
This website contains an archive of files for the Acorn Electron, BBC Micro, Acorn Archimedes, Commodore 16 and Commodore 64 computers, which Dominic Ford has rescued from his private collection of floppy disks and cassettes.
Some of these files were originally commercial releases in the 1980s and 1990s, but they are now widely available online. I assume that copyright over them is no longer being asserted. If you own the copyright and would like files to be removed, please contact me.
Tape/disk: | Home » Archimedes archive » Acorn User » AU 1994-02.adf » !FEMS_App_FEMS_App |
Filename: | !FEMS/FEMS2 |
Read OK: | ✔ |
File size: | C0B2 bytes |
Load address: | 0000 |
Exec address: | 0000 |
File contents
10REM ><FEMS$dir>.FEMS2TAN3 20REM Finite Element Materials Simulation 30REM with development version of OO3D routines 40REM version 2.1: restyling of objects 50REM 2.11 cylinder definition 60REM 2.12 nearest neigbours bonding 70REM 2.13 generalised frame storage 80REM 2.14 backgrounds built in 90REM 2.15 backgrounds Z-mixed with objects 100REM 2.16 mixed backgrounds, replay, preview 110REM 2.17 2 colour RLE 120REM 2.17b flat shading removed 130REM 2.18 read scene definition files 140REM 2.19 cuboid definition, compound objects (cuboids only) 150REM 2.20 any object in compound 160REM 2.21 PROCoutput_facets, PROCframe_actions, anims inside sims 170REM 2.211 const. sep. sphere (background & foreground) 180REM units for angles, velocities etc. 190REM solid_sphere 200REM 2.212 spin command 210REM local damping 220REM 2.213 rotating frame damping 230REM repelling objects 240REM 2.214 frozen objects 250REM proper air damping 260REM 2.215 cuboid surface fixed 270REM variable solid damping 280REM force parameter for repel 290REM 2.216 repel largely machine coded (outer point loop in BASIC) 300REM 2.217 multiple and box-bounded pulls 310REM 2.218 units for angular velocity 320REM + hourglass during repel preprop 330 340ch%=0 350anim%=FALSE 360ON ERROR PROCerror 370 380MODE 0 390SYS "OS_GetEnv" TO env$ 400i%=INSTR(env$,"-file ") 410IF i%=0 THEN 420 file$="^.sims.ChairStair" 430ELSE 440 file$=MID$(env$,i%+6) 450 i%=INSTR(file$," ") 460 IF i% THEN file$=LEFT$(file$,i%-1) 470ENDIF 480SYS "OS_File",5,file$ TO ot%,,type%,,length% 490IF ot%<>1 THEN ERROR 1,"File """+file$+""" not found" 500type%=(type%>>8) AND &FFF 510 520CASE type% OF 530 WHEN &FFF: 540 PROCinit 550 PROCread_script(file$) 560 PROCinit2 570 PROCcreate_frames 580 PROCsaveit 590 WHEN &3C7: 600 PROCload(file$,length%) 610 PROCinit_replay 620 OTHERWISE:ERROR 1,"File wrong type" 630ENDCASE 640PROCdisplay_frames 650END 660: 670DEF PROCinit 680PROCinit3OOD 690DIM scrap% 256*4 700DIM sin 2048*4:cos=sin+256*4 710PRINT'"Filling sine array..."; 720FOR A%=0 TO 1023:sin!(A%*4)=&400*SIN(A%*PI/512)+.5:NEXT 730FOR A%=0 TO 1023:sin!((A%+1024)*4)=sin!(A%*4):NEXT 740DIM per% &801*4 750PRINT'"Filling perspective array..."; 760FOR N%=0 TO &800:per%!(N%*4)=&600/(1+N%/&400):NEXT 770DIM ptp%(3),szp%(3) 780maxobjs%=8 790world%=FNcreate(7,maxobjs%) 800DIM bgdef%(maxobjs%,6) 810DIM pull% 12*64:pulls%=0 820inch%=&B400 830PROCassem_nebo 840ENDPROC 850: 860DEF PROCdefaults 870xres%=320:yres%=256 880ren%=2 890fsp%=1 900rstyle%=0 910aim%=600 920VA%=700:VB%=912 930stostyle%=0 940grav_x%=0:grav_y%=0:grav_z%=-600 950dampsh%=2 960mode%=4 970ENDPROC 980: 990DEF PROCread_script(file$) 1000CLS 1010ch%=OPENIN(file$) 1020IF ch%=0 THEN ERROR 1,"Could not open script file" 1030IF FNline<>"fems2" THEN PROCrse("Script file invalid: did not start with ""FEMS2""") 1040PROCdefaults 1050solids%=0:backgrounds%=0:objects%=0 1060REPEAT 1070 c$=FNline 1080 CASE c$ OF 1090 WHEN "rendering":PROCget_openbrack(c$):PROCread_rendering 1100 WHEN "solid":PROCget_openbrack(c$):solids%+=1:PROCread_object(-1) 1110 WHEN "background":PROCget_openbrack(c$):backgrounds%+=1:PROCread_object(0) 1120 WHEN "frame_aim":aim%=FNget_num(c$,1,1) 1130 WHEN "time_div":fsp%=FNget_num(c$,1,1) 1140 WHEN "gravity":grav_x%=FNget_num(c$,3,2):grav_y%=FNget_num(c$,3,2):grav_z%=FNget_num(c$,3,2) 1150 WHEN "" 1160 OTHERWISE PROCnot_rec 1170 ENDCASE 1180UNTIL EOF#ch% 1190CLOSE#ch%:ch%=0 1200IF solids%<1 THEN ERROR 1,"No solids defined" 1210IF backgrounds%<1 THEN ERROR 1,"No backgrounds defined" 1220ENDPROC 1230: 1240DEF PROCread_rendering 1250REPEAT 1260 c$=FNline 1270 CASE c$ OF 1280 WHEN "type":rstyle%=FNselect(c$,FNline,"all_dots,wireframe,dots,lines") 1290 WHEN "resolution":xres%=FNget_num(c$,2,1):yres%=FNget_num(c$,2,1) 1300 WHEN "background":ren%=2*FNselect(c$,FNline,"back,mix") 1310 WHEN "view":VB%=(FNget_num(c$,2,3)) AND &3FF 1320 VA%=(768-FNget_num(c$,2,3)) AND &3FF 1330 WHEN "}","" 1340 OTHERWISE PROCnot_rec 1350 ENDCASE 1360UNTIL EOF#ch% OR c$="}" 1370mode%=2 1380CASE rstyle% OF 1390 WHEN 0,2:stostyle%=0 1400 WHEN 1,3:stostyle%=0 1410 WHEN 4:stostyle%=-1:mode%=16 1420ENDCASE 1430mode%=FNmode(xres%,yres%,mode%) 1440IF mode%<0 PROCrse("No suitable screen mode found") 1450ENDPROC 1460: 1470DEF PROCread_object(sol%) 1480LOCAL otype%,c$,Q%,i% 1490otype%=-2:thing%=0 1500IF sol%=0 Q%=backgrounds% ELSE Q%=0 1510com_stage%=0:faco%=0:poco%=0 1520REPEAT 1530 c$=FNline 1540 CASE c$ OF 1550 WHEN "create":PROCread_create(sol%,Q%):bgdef%(Q%,0)=otype% 1560 WHEN "translate":PROCneed_create 1570 x%=FNget_num(c$,3,4):y%=FNget_num(c$,3,4):z%=FNget_num(c$,3,4) 1580 PROCtranslate(thing%,co0%,co0%,x%,y%,z%) 1590 bgdef%(Q%,1)=x%:bgdef%(Q%,2)=y%:bgdef%(Q%,3)=z% 1600 WHEN "rotate":IF sol%=0 PROCrse("background objects cannot be rotated") 1610 PROCneed_create:PROCrotate(thing%,co0%,co0%,FNget_num(c$,3,3),FNget_num(c$,3,3),FNget_num(c$,3,3)) 1620 WHEN "nearbonds":PROCread_nearbonds(sol%) 1630 WHEN "repel":PROCread_repel(sol%) 1640 WHEN "damping":PROCneed_create:thing%!odm%=FNget_num(c$,1,1) 1650 WHEN "air_damp":PROCneed_create:thing%!adm%=FNget_num(c$,1,1) 1660 PROCflag_surface_points(thing%) 1670 WHEN "solid_damp":PROCneed_create:thing%!rdm%=FNget_num(c$,1,2) 1680 WHEN "velocity":PROCneed_create:IF sol%=0 PROCrse("background objects cannot be given a velocity") 1690 PROCset_velocity(thing%,FNget_num(c$,3,5),FNget_num(c$,3,5),FNget_num(c$,3,5)) 1700 WHEN "spin":PROCneed_create:IF sol%=0 PROCrse("background objects cannot be spun") 1710 PROCset_spin(thing%,FNget_num(c$,3,6),FNget_num(c$,3,6),FNget_num(c$,3,6)) 1720 WHEN "scale":PROCneed_create:IF sol%=0 PROCrse("scale not implemented for background objects") 1730 PROCscale_object(thing%,FNget_num(c$,3,2),FNget_num(c$,3,2),FNget_num(c$,3,2)) 1740 WHEN "pull":PROCread_pull(thing%) 1750 WHEN "fix_vel":PROCread_fix_vel(thing%) 1760 WHEN "}","" 1770 OTHERWISE PROCnot_rec 1780 ENDCASE 1790UNTIL EOF#ch% OR c$="}" 1800IF poco%>thing%!nop% THEN PROCrse("too many points created") 1810thing%!nop%=poco% 1820IF faco%>thing%!nof% THEN PROCrse("too many facets created") 1830thing%!nof%=faco% 1840thing%!sep%=szp%(0) 1850ENDPROC 1860: 1870DEF PROCread_pull(thing%) 1880IF sol%=0 PROCrse("background objects cannot be pulled") 1890LOCAL f%,l%,s%,B%,C% 1900f%=FNget_num(c$,6,1):l%=FNget_num(c$,6,1):s%=FNget_num(c$,6,1) 1910IF s%<=0 THEN PROCrse("the pull point step must be greater than zero") 1920C%=FNfixed_vel_no(FNget_num(c$,6,5),FNget_num(c$,6,5),FNget_num(c$,6,5)) 1930IF l%>=thing%!nop% THEN l%=thing%!nop%-1 1940B%=FNpoint_flags(thing%) 1950WHILE f%>=0 AND f%<=l% 1960 B%?f%=(B%?f% AND 3) OR (C%<<2) 1970 f%+=s% 1980ENDWHILE 1990ENDPROC 2000: 2010DEF PROCread_fix_vel(thing%) 2020PROCneed_create 2030IF sol%=0 PROCrse("background objects cannot be pulled") 2040LOCAL a%,b%,c%,x%,y%,z%,ex%,ey%,ez%,A%,B%,C%,cp% 2050x%=FNget_num(c$,9,4):y%=FNget_num(c$,9,4):z%=FNget_num(c$,9,4) 2060ex%=FNget_num(c$,9,4):ey%=FNget_num(c$,9,4):ez%=FNget_num(c$,9,4) 2070C%=FNfixed_vel_no(FNget_num(c$,6,5),FNget_num(c$,6,5),FNget_num(c$,6,5)) 2080B%=FNpoint_flags(thing%) 2090ex%+=x%:IF ex%<x% SWAP x%,ex% 2100ey%+=y%:IF ey%<y% SWAP y%,ey% 2110ez%+=z%:IF ez%<z% SWAP z%,ez% 2120cp%=thing%!co0% 2130FOR A%=0 TO thing%!nop%-1 2140 c%=-!cp%:a%=cp%!4:b%=cp%!8 2150 IF a%>=x% AND a%<=ex% AND b%>=y% AND b%<=ey% AND c%>=z% AND c%<=ez% THEN B%?A%=(B%?A% AND 3) OR (C%<<2) 2160 cp%+=12 2170NEXT 2180ENDPROC 2190: 2200DEF FNfixed_vel_no(x%,y%,z%) 2210LOCAL C%,P% 2220C%=1:P%+=pull%+12 2230WHILE C%<=pulls% AND (!P%<>-z% OR P%!4<>x% OR P%!8<>y%) 2240 C%+=1:P%+=12 2250ENDWHILE 2260IF C%<=pulls% THEN =C% 2270IF pulls%=63 THEN PROCrse("You can only have 63 different pull velocities") 2280!P%=-z%:P%!4=x%:P%!8=y% 2290pulls%+=1:=pulls% 2300: 2310DEF FNpoint_flags(thing%) 2320IF thing%!ptf%>0 THEN =thing%!ptf% 2330LOCAL A%,B% 2340thing%!ptf%=FNcreate(8,thing%!pts%) 2350B%=thing%!ptf% 2360FOR A%=0 TO thing%!nop%-1:B%?A%=0:NEXT 2370=B% 2380: 2390DEF PROCflag_surface_points(thing%) 2400LOCAL A%,B%,C% 2410B%=FNpoint_flags(thing%) 2420C%=thing%!fac% 2430FOR A%=0 TO thing%!nof%-1 2440 B%?(C%!0)=B%?(C%!0) OR 1 2450 B%?(C%!4)=B%?(C%!4) OR 1 2460 B%?(C%!8)=B%?(C%!8) OR 1 2470 C%+=elsiz%(3) 2480NEXT 2490ENDPROC 2500: 2510DEF PROCread_repel(sol%) 2520IF sol%=0 THEN PROCrse("repel is not applicable to background objects") 2530PROCneed_create 2540thing%!rep%=FNget_num(c$,1,1) 2550IF thing%!rep%=0 THEN ENDPROC 2560LOCAL A%,B%,C%,D%,nd%,cl% 2570SYS "Hourglass_On" 2580PROCflag_surface_points(thing%) 2590 2600B%=FNpoint_flags(thing%) 2610C%=thing%!co0% 2620FOR i%=0 TO thing%!nop%-1 2630 SYS "Hourglass_Percentage",100*i%/thing%!nop% 2640 IF (B%?i% AND 3)=1 THEN 2650 cl%=-1:nd%=(2*szp%(0)>>7)^2:D%=thing%!co0% 2660 FOR j%=0 TO thing%!nop%-1 2670 IF (B%?j% AND 3)<>1 THEN A%=(!C%-!D%>>7)^2+(C%!4-D%!4>>7)^2+(C%!8-D%!8>>7)^2:IF A%<nd% THEN nd%=A%:cl%=j% 2680 D%+=12 2690 NEXT 2700 IF cl%>=0 THEN B%?cl%=(B%?cl% OR 2) AND (NOT 1) 2710 ENDIF 2720 C%+=12 2730NEXT 2740SYS "Hourglass_Off" 2750ENDPROC 2760: 2770DEF PROCread_nearbonds(sol%) 2780IF sol%=0 THEN PROCrse("nearbonds is not applicable to background objects") 2790PROCget_openbrack(c$) 2800PROCneed_create 2810LOCAL c$,lambda%,R 2820lambda%=30:R=2.5 2830REPEAT 2840 c$=FNline 2850 CASE c$ OF 2860 WHEN "spring_const":lambda%=FNget_num(c$,1,1) 2870 WHEN "range":R=FNget_num(c$,1,2) 2880 WHEN "}","" 2890 OTHERWISE PROCnot_rec 2900 ENDCASE 2910UNTIL EOF#ch% OR c$="}" 2920LOCAL c%,ls%,ms%,E%,F%,C%,A%,B%,G%,H%,s%,D% 2930ls%=szp%(0):ms%=R*ls% 2940c%=lambda%*fsp%*ls% 2950s%=0:WHILE (ms%>>s%)>255:s%+=1:ENDWHILE 2960ms%=ms%>>s%:c%=c%>>s%:ls%=ls%>>s% 2970!scrap%=1<<s% 2980B%=INT(c%/ls%)<<24:FOR C%=1 TO ls%:scrap%!(C%*4)=(C%<<s%) OR B%:NEXT 2990FOR C%=ls%+1 TO ms%:scrap%!(C%*4)=(C%<<s%) OR (INT(c%/C%)<<24):NEXT 3000!neboblock=scrap% 3010neboblock!4=ms%*ms% 3020neboblock!12=s% 3030neboblock!16=(.5*ls%)^2 3040H%=thing%!co0%:E%=thing%!pts% 3050B%=USR(nearcount) 3060thing%!nob%=B% 3070thing%!bnd%=FNcreate(6,B%) 3080neboblock!8=thing%!bnd% 3090D%=thing%!bnd%+8*thing%!nob% 3100CALL nearbond 3110B%=neboblock!8 3120IF B%>D% THEN END 3130thing%!nob%=(B%-thing%!bnd%)/8 3140ENDPROC 3150: 3160DEF PROCread_create(sol%,Q%) 3170PROCget_openbrack(c$) 3180IF FNline<>"type" THEN PROCrse("create needs a type first") 3190LOCAL c$,o$,offx%,offy%,offz% 3200offx%=0:offy%=0:offz%=0 3210o$=FNline 3220otype%=FNselect(c$,o$,"compound,sheet,cube,tube,sphere,stairs,cuboid,solid_sphere")-1 3230CASE otype% OF 3240 WHEN 0,1,3:nptp%=1:nszp%=1 3250 WHEN 2,4,5:nptp%=3:nszp%=3 3260 WHEN 6:nptp%=2:nszp%=1 3270 WHEN -1:PROCread_compound:otype%=-1 3280ENDCASE 3290IF otype%<0 THEN ENDPROC 3300REPEAT 3310 c$=FNline 3320 CASE c$ OF 3330 WHEN "points":FOR i%=1 TO nptp%:ptp%(i%)=FNget_num(o$+" "+c$,nptp%,1):NEXT 3340 WHEN "size":FOR i%=1 TO nszp%:szp%(i%)=FNget_num(o$+" "+c$,nszp%,4):bgdef%(Q%,i%+3)=szp%(i%):NEXT 3350 WHEN "offset":offx%=FNget_num(c$,3,4):offy%=FNget_num(c$,3,4):offz%=FNget_num(c$,3,4) 3360 WHEN "}","" 3370 OTHERWISE PROCnot_rec 3380 ENDCASE 3390UNTIL EOF#ch% OR c$="}" 3400IF EVAL("FNcreate_"+o$) 3410ENDPROC 3420: 3430DEF PROCread_compound 3440LOCAL P%,c$ 3450IF com_stage%>0 PROCrse("Compound objects cannot be nested") 3460com_nop%=0:com_nof%=0 3470P%=PTR#ch% 3480FOR com_stage%=1 TO 2 3490 PRINT'"** compound object - pass ";com_stage%;" **" 3500 PTR#ch%=P% 3510 IF com_stage%=2 THEN com_stage%=0:com_thing%=FNcreate_object(com_nop%,com_nof%):com_stage%=2:faco%=0:poco%=0 3520 REPEAT 3530 c$=FNline 3540 CASE c$ OF 3550 WHEN "part":PROCread_create(-1,0) 3560 WHEN "}": 3570 OTHERWISE:PROCrse("Expected ""part"" or ""}""") 3580 ENDCASE 3590 UNTIL c$="}" 3600NEXT 3610com_stage%=0 3620PROCset_velocity(com_thing%,0,0,0) 3630ENDPROC 3640: 3650DEF PROCblurb 3660LOCAL i%,j%,k%,B%,C%,D%,E%,F%,x%,y%,z%,nd% 3670nd%=(.5*szp%(0)>>7)^2 3680B%=FNpoint_flags(thing%) 3690C%=thing%!co0% 3700D%=thing%!fac% 3710E%=FNfixed_vel_no(0,0,0) 3720F%=0 3730FOR i%=0 TO poco%-2 3740 IF C%!(i%*12)>F% F%=C%!(i%*12) 3750NEXT 3760F%+=100*&B400 3770SYS "Hourglass_On" 3780FOR i%=0 TO poco%-2 3790 SYS "Hourglass_Percentage",100*i%/(poco%-2) 3800 x%=C%!(i%*12):y%=C%!(i%*12+4):z%=C%!(i%*12+8) 3810 FOR j%=i%+1 TO poco%-1 3820 IF B%?j%=0 THEN 3830 IF (x%-C%!(j%*12)>>7)^2+(y%-C%!(j%*12+4)>>7)^2+(z%-C%!(j%*12+8)>>7)^2<=nd% THEN 3840 PRINT i%,j%,B%?i%,B%?j% 3850 x%=x%+C%!(j%*12)>>1:y%=y%+C%!(j%*12+4)>>1:z%=z%+C%!(j%*12+8)>>1 3860 B%?j%=E% 3870 C%!(j%*12)=F%:C%!(j%*12+4)=0:C%!(j%*12+8)=0 3880 D%=thing%!fac% 3890 FOR k%=0 TO faco%-1 3900 IF D%!0=j% D%!0=i% 3910 IF D%!4=j% D%!4=i% 3920 IF D%!8=j% D%!8=i% 3930 D%+=elsiz%(3) 3940 NEXT 3950 ENDIF 3960 ENDIF 3970 NEXT 3980 C%!(i%*12)=x%:C%!(i%*12+4)=y%:C%!(i%*12+8)=z% 3990NEXT 4000SYS "Hourglass_Off" 4010ENDPROC 4020: 4030DEF PROCneed_create 4040IF otype%=-2 THEN PROCrse("You need to create the object before you can do this") 4050ENDPROC 4060: 4070DEF PROCset_velocity(thing%,x%,y%,z%) 4080IF com_stage%<>0 THEN ENDPROC 4090LOCAL P%,A% 4100P%=thing%!vel%:IF P%=0 ENDPROC 4110FOR A%=0 TO thing%!nop%-1 4120 P%!0=-z%:P%!4=x%:P%!8=y%:P%+=12 4130NEXT 4140ENDPROC 4150: 4160DEF PROCset_spin(thing%,wx,wy,wz) 4170IF com_stage%<>0 THEN ENDPROC 4180LOCAL P%,Q%,A% 4190wx=wx*PI/25600 4200wy=wy*PI/25600 4210wz=wz*PI/25600 4220P%=thing%!vel%:IF P%=0 ENDPROC 4230Q%=thing%!co0%:IF Q%=0 ENDPROC 4240FOR A%=0 TO thing%!nop%-1 4250 P%!0-=wy*(Q%!4)-wx*(Q%!8) 4260 P%!4+=wz*(Q%!8)+wy*(Q%!0) 4270 P%!8-=wx*(Q%!0)+wz*(Q%!4) 4280 P%+=12:Q%+=12 4290NEXT 4300ENDPROC 4310: 4320DEF PROCscale_object(thing%,X,Y,Z) 4330LOCAL P%,A% 4340IF sol% szp%(0)=szp%(0)*(X+Y+Z)/3 4350P%=thing%!co0%:IF P%=0 ENDPROC 4360FOR A%=0 TO thing%!nop%-1 4370 P%!0=P%!0*Z:P%!4=P%!4*X:P%!8=P%!8*Y:P%+=12 4380NEXT 4390ENDPROC 4400: 4410DEF FNcreate_sheet 4420LOCAL co%,A%,N% 4430N%=ptp%(1):szp%(0)=szp%(1)/(N%-1) 4440thing%=FNcreate_object(N%^2,2*(N%-1)^2) 4450IF thing%=0 THEN =0 4460offx%-=.5*szp%(1) 4470offy%-=.5*szp%(1) 4480co%=thing%!co0%+poco%*12 4490FOR A%=0 TO thing%!nop%-1 4500 co%!0=-offz% 4510 co%!4=szp%(0)*(A% MOD N%)+offx% 4520 co%!8=szp%(0)*(A% DIV N%)+offy% 4530 co%+=12 4540NEXT 4550IF FNsurface(thing%,thing%!fac%+faco%*elsiz%(3),poco%,1,N%,N%,N%,0,0) 4560poco%+=thing%!nop% 4570PROCset_velocity(thing%,0,0,0) 4580=0 4590: 4600DEF FNcreate_sphere 4610ptp%(2)=1 4620=FNcreate_solid_sphere 4630: 4640DEF FNcreate_solid_sphere 4650LOCAL A%,B%,C%,E%,N%,Q%,S%,W%,Z%,NR%,NP%,OB%,OS%,OQ%,wind%,co% 4660NR%=ptp%(1) 4670R%=szp%(1):szp%(0)=PI*szp%(1)/NR% 4680A%=(R%/szp%(0))-.9 4690IF ptp%(2)>A% ptp%(2)=A% 4700IF ptp%(2)<1 ptp%(2)=1 4710NP%=FNCSS_points(NR%):B%=NP%*2-4 4720IF ptp%(2)>1 THEN 4730 FOR A%=1 TO ptp%(2)-1 4740 NP%+=FNCSS_points(NR%*(R%-A%*szp%(0))/R%+.5) 4750 NEXT 4760ENDIF 4770thing%=FNcreate_object(NP%,B%) 4780IF thing%=0 THEN =0 4790co%=thing%!co0%+poco%*12 4800FOR S%=0 TO ptp%(2)-1 4810 NR%=ptp%(1)*R%/szp%(1)-.5 4820 FOR A%=0 TO NR% 4830 B%=.5+2*(NR%+1)*SIN(PI*A%/NR%) 4840 W%=R%*SIN(PI*A%/NR%) 4850 Z%=R%*COS(PI*A%/NR%)+offz% 4860 FOR C%=0 TO B%-1 4870 IF B%<1 THEN 4880 co%!4=0:co%!8=0 4890 ELSE 4900 co%!4=W%*COS(2*PI*C%/B%)+offx% 4910 co%!8=W%*SIN(2*PI*C%/B%)+offy% 4920 ENDIF 4930 co%!0=-Z% 4940 co%+=12 4950 NEXT 4960 NEXT 4970 R%-=szp%(0) 4980 IF S%=0 E%=(co%-thing%!co0%)/12-1 4990NEXT 5000 5010wind%=1 5020NR%=ptp%(1)-1 5030FP%=thing%!fac%+faco%*elsiz%(3) 5040B%=1:N%=1 5050FOR A%=1 TO ((NR%+1) DIV 2) 5060 OS%=N%-B%:OB%=B% 5070 B%=.5+2*(NR%+1)*SIN(PI*A%/NR%) 5080 Q%=OS% 5090 FOR C%=0 TO B%-1 5100 OQ%=Q% 5110 IF A%=1 Q%=0 ELSE Q%=OS%+((C%*OB%/B%+1)MOD OB%) 5120 PROCCSS_fac(N%+C%,N%+((C%+1)MOD B%),Q%,A%) 5130 IF OQ%<>Q% THEN PROCCSS_fac(N%+C%,Q%,OQ%,A%) 5140 NEXT 5150 N%+=B% 5160NEXT 5170poco%+=NP% 5180PROCset_velocity(thing%,0,0,0) 5190=0 5200: 5210DEF PROCCSS_fac(D%,B%,C%,A%) 5220FP%=FNdefine_facet(FP%,C%+poco%,B%+poco%,D%+poco%,3) 5230IF A%*2<NR%+1 FP%=FNdefine_facet(FP%,E%-C%,E%-B%,E%-D%,3) 5240ENDPROC 5250: 5260DEF FNCSS_points(NR%) 5270LOCAL A%,N% 5280NR%-=1:N%=2 5290FOR A%=0 TO NR% 5300 N%+=.5+2*(NR%+1)*SIN(PI*A%/NR%) 5310NEXT 5320=N% 5330: 5340DEF FNcreate_cube 5350ptp%(2)=ptp%(1):ptp%(3)=ptp%(1) 5360szp%(2)=szp%(1):szp%(3)=szp%(1) 5370IF com_stage%<>1 offx%-=.5*szp%(1):offy%-=.5*szp%(1):offz%-=.5*szp%(1) 5380=FNcreate_cuboid 5390: 5400DEF FNcreate_tube 5410LOCAL A%,C%,D%,co%,A,R%,N1%,N2%,N3%,AS 5420N1%=ptp%(1):N2%=ptp%(2):N3%=ptp%(3) 5430thing%=FNcreate_object(N1%*N2%*N3%,4*N2%*(N1%+N3%-2)) 5440IF thing%=0 THEN =0 5450offz%-=szp%(1)/2 5460szp%(1)=szp%(1)/(N1%-1) 5470szp%(3)=szp%(3)/(N3%-1) 5480AS=2*PI/N2% 5490szp%(0)=(szp%(1)+szp%(2)*AS+szp%(3))/3 5500co%=thing%!co0%+poco%*12 5510FOR A%=0 TO thing%!nop%-1 5520 A=(A% MOD N2%)*AS 5530 R%=szp%(2)+szp%(3)*((A% DIV (N2%*N1%))-(N3%-1)*.5) 5540 co%!0=-szp%(1)*((A% DIV N2%) MOD N1%)-offz% 5550 co%!4=R%*COS(A)+offx% 5560 co%!8=R%*SIN(A)+offy% 5570 co%+=12 5580NEXT 5590C%=FNsurface(thing%,thing%!fac%+faco%*elsiz%(3),poco%,1,N2%,N2%,N1%,-1,1) 5600C%=FNsurface(thing%,C%,poco%+N2%*N1%*(N3%-1),1,N2%,N2%,N1%,1,1) 5610C%=FNsurface(thing%,C%,poco%,1,N2%*N1%,N2%,N3%,1,1) 5620C%=FNsurface(thing%,C%,poco%+N2%*(N1%-1),1,N2%*N1%,N2%,N3%,-1,1) 5630poco%+=thing%!nop% 5640PROCset_velocity(thing%,0,0,0) 5650=0 5660: 5670DEF FNcreate_stairs 5680LOCAL co%,A%,Y%,X%,Z%,N1%,N2%,N3% 5690N1%=ptp%(1):N2%=ptp%(2):N3%=ptp%(3) 5700thing%=FNcreate_object(N1%*N2%*N3%,2*(N1%-1)*(N2%*N3%-1)) 5710IF thing%=0 THEN =0 5720szp%(1)=szp%(1)/(N1%-1) 5730szp%(3)=szp%(3)/(N3%-1) 5740co%=thing%!co0%+poco%*12 5750offx%=-.5*(N1%-1)*szp%(1) 5760FOR A%=0 TO N1%*N2%*N3%-1 5770 X%=A% MOD N1%:Z%=A% DIV N1% 5780 Y%=Z% MOD N3%:Z%=Z% DIV N3% 5790 co%!0=-Z%*szp%(2)-offz% 5800 co%!4=X%*szp%(1)+offx% 5810 co%!8=(Y%+Z%*(N3%-1))*szp%(3)+offy% 5820 co%+=12 5830NEXT 5840Y%=FNsurface(thing%,thing%!fac%+faco%*elsiz%(3),poco%,1,N1%,N1%,N2%*N3%,0,0) 5850poco%+=thing%!nop% 5860PROCset_velocity(thing%,0,0,0) 5870=0 5880: 5890DEF FNcreate_cuboid 5900LOCAL X%,Y%,Z%,A%,B%,C%,D%,E%,co%,N1%,N2%,N3%,S1%,S2%,S3% 5910N1%=ptp%(1):N2%=ptp%(2):N3%=ptp%(3) 5920N1%-=(N1%=0):N2%-=(N2%=0):N3%-=(N3%=0) 5930thing%=FNcreate_object(N1%*N2%*N3%,4*((N1%-1)*(N2%-1)+(N2%-1)*(N3%-1)+(N3%-1)*(N1%-1))) 5940IF thing%=0 THEN =0 5950S1%=szp%(1)/(N1%-1):S2%=szp%(2)/(N2%-1):S3%=szp%(3)/(N3%-1) 5960szp%(0)=(S1%+S2%+S3%)/3 5970co%=thing%!co0%+poco%*12 5980FOR A%=0 TO thing%!nop%-1 5990 X%=A% MOD N1%:Y%=(A% DIV N1%) MOD N2%:Z%=A% DIV (N1%*N2%) 6000 co%!0=-(S3%*Z%+offz%) 6010 co%!4=S1%*X%+offx% 6020 co%!8=S2%*Y%+offy% 6030 co%+=12 6040NEXT 6050A%=poco%+N1%*N2%*(N3%-1) 6060X%=thing%!fac%+faco%*elsiz%(3) 6070C%=FNsurface(thing%,X%,poco%,1,N1%,N1%,N2%,-1,0) 6080C%=FNsurface(thing%,C%,A% ,1,N1%,N1%,N2%, 1,0) 6090A%=poco%+N1%*(N2%-1) 6100C%=FNsurface(thing%,C%,poco%,N1%*N2%,1,N3%,N1%,-1,0) 6110C%=FNsurface(thing%,C%,A% ,N1%*N2%,1,N3%,N1%, 1,0) 6120A%=poco%+N1%-1 6130C%=FNsurface(thing%,C%,poco%,N1%,N1%*N2%,N2%,N3%,-1,0) 6140C%=FNsurface(thing%,C%,A% ,N1%,N1%*N2%,N2%,N3%, 1,0) 6150poco%+=N1%*N2%*N3% 6160PROCset_velocity(thing%,0,0,0) 6170=0 6180: 6190DEF FNcreate_object(pts%,facs%) 6200IF com_stage%=1 THEN com_nop%+=pts%:com_nof%+=facs%:=0 6210IF com_stage%=2 =com_thing% 6220IF objects%=maxobjs% THEN PROCrse("Max. no. of objects reached") 6230thing%=world%+objects%*elsiz%(7) 6240objects%+=1 6250IF sol% THEN flags%=%1011111 ELSE flags%=%1010111 6260PROCinitthing(thing%,pts%,facs%,0,flags%) 6270=thing% 6280: 6290DEF FNselect(c$,o$,l$) 6300p%=INSTR(","+l$+",",","+o$+",") 6310IF p%=0 THEN PROCrse(c$+" should be one of "+l$) 6320l$=LEFT$(l$,p%):p%=0:r%=-1 6330REPEAT:p%=INSTR(l$,",",p%+1):r%+=1:UNTIL p%=0 6340=r% 6350: 6360DEF PROCget_openbrack(c$) 6370IF FNline<>"{" THEN PROCrse("open backet expected after "+c$) 6380ENDPROC 6390: 6400DEF FNget_num(c$,n%,t%) 6410REM t%=1 integer >=0 6420REM t%=2 float 6430REM t%=3 angle 6440REM t%=4 distance 6450REM t%=5 velocity 6460REM t%=6 angular velocity 6470LOCAL A$,P%,B%,s%,V,M 6480A$=FNline 6490P%=0:REPEAT 6500 P%+=1 6510 B%=ASC(MID$(A$,P%,1)) 6520 IF P%=1 AND (B%=43 OR B%=45) THEN B%=48 6530UNTIL (B%<48 OR B%>57) AND B%<>46 6540IF P%=1 AND n%=1 THEN PROCrse("A numeric arguament is expected after "+c$) 6550IF P%=1 THEN PROCrse(STR$n%+" numeric arguaments are expected after "+c$) 6560CASE MID$(A$,P%) OF 6570 WHEN "":s%=t%:M=1 6580 IF t%=3 THEN M=128/45 6590 WHEN "deg":s%=3:M=128/45 6600 WHEN "rad":s%=3:M=512/PI 6610 WHEN "in":s%=4:M=&B400 6620 WHEN "ft":s%=4:M=12*&B400 6630 WHEN "cm":s%=4:M=18142 6640 WHEN "mm":s%=4:M=1814.2 6650 WHEN "ips":s%=5:M=&B400/50 6660 WHEN "ftps":s%=5:M=12*&B400/50 6670 WHEN "cmps":s%=5:M=18142/50 6680 WHEN "mmps":s%=5:M=1814.2/50 6690 WHEN "degps":s%=6:M=128/(45*50) 6700 WHEN "radps":s%=6:M=512/(PI*50) 6710 WHEN "rpm":s%=6:M=1024/3000 6720 OTHERWISE PROCrse("Unknown units used here") 6730ENDCASE 6740IF s%<>t% THEN PROCrse("Inappropriate units used here") 6750V=VAL(LEFT$(A$,P%-1)) 6760IF t%=1 THEN IF V<0 OR V<>INT(V) THEN PROCrse("Non-negative integer expected here") 6770=V*M 6780: 6790DEF PROCrse(A$) 6800CLOSE#ch%:ch%=0 6810PRINT'A$ 6820END 6830: 6840DEF PROCnot_rec:PROCrse("command """+c$+""" not recognised in this context"):ENDPROC 6850: 6860DEF FNline 6870LOCAL A$,B%,C%,R% 6880R%=0:A$="":B%=0 6890REPEAT 6900 C%=B%:IF EOF#ch% THEN B%=-1 ELSE B%=BGET#ch% 6910 IF B%>31 THEN VDU B% ELSE IF (B%=13 OR B%=10) AND C%<>23-B% THEN PRINT 6920 IF B%>64 AND B%<91 THEN B%+=32 6930 IF R%=0 AND B%>33 AND B%<>58 AND B%<>44 THEN A$+=CHR$B% 6940 IF B%=42 AND C%=47 THEN R%+=1 6950 IF B%=47 AND C%=42 THEN R%-=1:A$=LEFT$(A$,LENA$-2):IF R%<0 THEN PROCrse("More remarks closed than opened!") 6960UNTIL B%<0 OR ((B%<33 OR B%=58 OR B%=44) AND R%=0 AND A$<>"") 6970=A$ 6980: 6990DEF PROCinit2 7000 7010maxpts%=0 7020FOR i%=0 TO objects%-1 7030 thing%=world%+i%*elsiz%(7) 7040 IF thing%!vel%>0 THEN IF thing%!nop%>maxpts% THEN maxpts%=thing%!nop% 7050NEXT 7060DIM vel2% maxpts%*12 7070 7080tsh%=LN(fsp%)/LN(2)+.5:fsp%=1<<tsh% 7090grav_x%=grav_x%>>(tsh%*2) 7100grav_y%=grav_y%>>(tsh%*2) 7110grav_z%=grav_z%>>(tsh%*2) 7120dampsh%+=tsh%*2 7130 7140T%=1<<30 7150DIM recip% 4100 7160PRINT"Filling reciprocal table..." 7170FOR A%=1 TO 1023:recip%!(A%*4)=T%/A%+.5:NEXT 7180!recip%=&7FFFFFFF 7190 7200PROCassem 7210PROCassemstore(mode%,stostyle%) 7220 7230PRINT'"Creating pointers to facets..."; 7240totnof%=0 7250FOR i%=0 TO objects%-1 7260 thing%=world%+i%*elsiz%(7) 7270 totnof%+=thing%!nof% 7280NEXT 7290facpt%=FNcreate(4,totnof%):C%=0 7300FOR i%=0 TO objects%-1 7310 thing%=world%+i%*elsiz%(7) 7320 C%=FNinit_facpoint(thing%!fac%,facpt%,thing%!nof%,C%) 7330NEXT 7340 7350PRINT'"Making animation area..."; 7360DIM E% -1 7370storend%=(USR(basic_stack)-E%)-4000 7380DIM store% storend% 7390storend%=store%+storend% 7400store%+=16 7410!storend=storend%-1 7420 7430DIM timblk% 8,stri% 256 7440PROCinit_screen 7450ENDPROC 7460: 7470DEF PROCinit_screen 7480DIM Iblock% 16 7490MODE mode% OR 128 7500IF MODE<>mode% THEN ERROR 1,"Could not obtain requested screen mode" 7510OFF 7520COLOUR FNModeVar(3),255,255,255 7530*FX 112 1 7540CLS 7550*FX 112 2 7560CLS 7570*FX 113 1 7580!Iblock%=149:Iblock%!4=148:Iblock%!8=-1 7590SYS "OS_ReadVduVariables",Iblock%,scrpos1 7600!scrpos=!scrpos2 7610*fx 113 2 7620ENDPROC 7630: 7640DEF PROCcreate_frames 7650store%!-16=216 7660store%!-12=(xres%<<16) OR yres% 7670store%!-8=0 7680store%!-4=stostyle%+1 7690startime%=TIME 7700FOR i%=0 TO objects%-1 7710 PROCrotnpersp(world%+i%*elsiz%(7),VA%,VB%,0) 7720NEXT 7730MOUSE TO 1250,970 7740CLS:PROCrender(ren%,rstyle%) 7750CLS:PROCrender(1,rstyle%) 7760!storepos=store%:PROCstoreframe(stostyle%):store1%=!storepos 7770IF store1%=0 THEN ERROR 1,"Not enough space to store background frame" 7780 7790quit%=FALSE 7800gentime%=0 7810REPEAT 7820 startime%=TIME 7830 FOR j%=1 TO fsp% 7840 FOR i%=0 TO objects%-1 7850 PROCmove(i%,world%+i%*elsiz%(7)) 7860 NEXT 7870 NEXT 7880 movetime%=TIME 7890 FOR i%=0 TO objects%-1 7900 PROCrotnpersp(world%+i%*elsiz%(7),VA%,VB%,0) 7910 NEXT 7920 CLS 7930 laststore%=!storepos 7940 IF ren%=0 C%=store%:CALL show 7950 PROCrender(ren%,rstyle%) 7960 C%=store%:CALL show 7970 PROCstoreframe(stostyle%) 7980 C%=store%:CALL show 7990 anim%=TRUE 8000 PROCframe_actions(!(store%-8)-1) 8010 nk%=0:REPEAT:k%=nk%:nk%=INKEY(0):UNTIL nk%<0 8020 k%+=32*(k%>97 AND k%<123) 8030 IF k%=80 THEN PROCpreview 8040 IF k%=81 THEN quit%=TRUE 8050UNTIL quit% 8060CLS 8070PRINT"You can let go now" 8080REPEAT UNTIL NOT INKEY(-17) 8090VDU 11:PRINT SPC(20) 8100*fx 21 0 8110SYS "OS_PrettyPrint",CHR$13+"From now on you can press Escape and type PROCsave(""filename"") to save the animation."+CHR$13+CHR$0 8120ENDPROC 8130: 8140DEF PROCframe_actions(frame%) 8150REM IF frame%=30 THEN PROCoutput_facets("$.Temp.facets30") 8160REM IF INKEY(-3) THEN OSCLI("Screensave <FEMS$Dir>.^.shots.pic"+STR$(frame%)):VDU 7 8170PROCstatus(frame%) 8180IF frame%=aim% THEN 8190 PRINT "Paused...":VDU 7 8200 *fx 21 0 8210 IF GET 8220 VDU 11:PRINT SPC(10) 8230ENDIF 8240ENDPROC 8250: 8260DEF PROCoutput_facets(f$) 8270LOCAL cp%,fp%,j%,ch%,T% 8280ch%=OPENOUT(f$) 8290FOR i%=0 TO objects%-1 8300 thing%=world%+elsiz%(7)*i% 8310 cp%=thing%!co0% 8320 fp%=thing%!fac% 8330 T%=1:PRINT#ch%,T% 8340 PRINT#ch%,thing%!nof% 8350 FOR j%=0 TO thing%!nof%-1 8360 T%=cp%+12*fp%!0:PRINT#ch%,T%!4,T%!8,-!T% 8370 T%=cp%+12*fp%!4:PRINT#ch%,T%!4,T%!8,-!T% 8380 T%=cp%+12*fp%!8:PRINT#ch%,T%!4,T%!8,-!T% 8390 fp%+=elsiz%(3) 8400 NEXT 8410NEXT 8420CLOSE#ch% 8430ENDPROC 8440: 8450DEF PROCpreview 8460LOCAL C% 8470*FX 112 1 8480CLS 8490*FX 113 1 8500bank%=1 8510REPEAT 8520 PROCshow 8530 PROCpause(100) 8540UNTIL NOT INKEY(-56) 8550*FX 112 2 8560CLS 8570*FX 113 2 8580!scrpos=!scrpos2 8590C%=store%:CALL show 8600C%=laststore%:CALL show 8610*fx 21 0 8620ENDPROC 8630: 8640DEF PROCpause(T%) 8650T%=T%+TIME 8660REPEAT UNTIL TIME>T% 8670ENDPROC 8680: 8690DEF PROCdisplay_frames 8700*FX 112 1 8710CLS 8720*FX 113 1 8730!scrpos=!scrpos2 8740C%=store%:store1%=USR(show) 8750bank%=1 8760PROCshow 8770REPEAT 8780 *FX 15 8790 G%=GET 8800 IF G%=32 THEN 8810 REPEAT 8820 PROCshow 8830 *FX 15 8840 G%=INKEY(100) 8850 UNTIL G%>-1 8860 ELSE 8870 PROCshow 8880 ENDIF 8890UNTIL FALSE 8900ENDPROC 8910: 8920DEF PROCshow 8930LOCAL C%,A% 8940A%=store1% 8950FOR F%=1 TO !(store%-8)-1 8960 bank%=bank% EOR 3 8970 !scrpos=scrpos!(bank%*4) 8980 SYS "OS_Byte",112,bank% 8990 CLS 9000 C%=store%:CALL show 9010 C%=A%:A%=USR(show) 9020 IF INKEY(-2) THEN PROCpause(10):REPEAT UNTIL NOT INKEY(-1) 9030 WAIT:SYS "OS_Byte",113,bank% 9040NEXT 9050ENDPROC 9060: 9070DEF PROCstoreframe(S%) 9080CASE S% OF 9090 WHEN -1:!storepos+=4 9100 WHEN 0:CALL frstore 9110 WHEN 1:CALL frstore 9120 WHEN 2:!storepos+=4:!(store%-8)+=1 9130 OTHERWISE ERROR 1234,"Frame store type not known" 9140ENDCASE 9150IF !storepos=0 THEN quit%=TRUE ELSE !(store%-8)+=1 9160ENDPROC 9170: 9180DEF FNmode(xres%,yres%,cols%) 9190LOCAL mode%,best%,lc%,nc%,E% 9200lc%=256:best%=-1 9210FOR mode%=0 TO 127 9220 SYS "XOS_ReadModeVariable",mode%,3 TO ,,nc%;E% 9230 IF (E% AND 1)=0 AND nc%+1>=cols% AND nc%<lc% THEN 9240 IF FNModeVar(11)+1=xres% AND FNModeVar(12)+1=yres% THEN best%=mode%:lc%=nc% 9250 ENDIF 9260NEXT 9270=best% 9280: 9290DEF PROCsaveit 9300dir$=file$ 9310WHILE INSTR(file$,".")>0:file$=MID$(file$,INSTR(file$,".")+1):ENDWHILE 9320dir$=LEFT$(dir$,LENdir$-LENfile$-1)+".anims" 9330SYS "OS_File",5,dir$ TO ot% 9340IF ot%<>1 THEN SYS "OS_PrettyPrint",CHR$13+"Press S now to save the animation as "+dir$+"."+file$+CHR$13+CHR$0 9350*fx 21 0 9360k$=GET$ 9370IF ot%=1 THEN k$="x" 9380IF k$="S" OR k$="s" THEN 9390 IF ot%=0 THEN SYS "OS_File",8,dir$ 9400 PROCsave(dir$+"."+file$) 9410ENDIF 9420ENDPROC 9430: 9440DEF PROCsave(file$) 9450LOCAL E%,F% 9460IF !storepos=0 THEN E%=storend% ELSE E%=!storepos 9470F%=store%-16 9480SYS "OS_File",&A,file$,&3C7,,F%,E% 9490ENDPROC 9500: 9510DEF PROCload(file$,length%) 9520DIM store% length% 9530PRINT"Loading animation..."; 9540SYS "OS_File",&10,file$,store%,0 9550store%+=16 9560anim%=TRUE 9570ENDPROC 9580: 9590DEF PROCinit_replay 9600IF store%!-16<>216 THEN ERROR 1,"File version not known" 9610xres%=store%!-12 9620yres%=xres% AND &FFFF:xres%=xres%>>>16 9630stostyle%=(store%!-4)-1 9640IF stostyle%<>0 AND stostyle%<>1 THEN ERROR 1,"Storage type not known" 9650mode%=FNmode(xres%,yres%,2) 9660IF mode%<0 ERROR 1,"No suitable screen mode found" 9670PROCassemstore(mode%,stostyle%) 9680PROCinit_screen 9690ENDPROC 9700: 9710DEF PROCrepel_points(t1%,t2%) 9720LOCAL i%,j%,f1%,f12%,c1%,c2%,x%,y%,z%,x1%,y1%,z1%,v1%,R% 9730f12%=t1%!rep%*t2%!rep% 9740s%=t1%!sep%:IF s%>t2%!sep% s%=t2%!sep% 9750s%=s%*2 9760r%=(s%/128)^2 9770c1%=t1%!co0%:v1%=t1%!vel%:f1%=t1%!ptf% 9780!frict=frsh% 9790!pts12=12*(t2%!nop%-1) 9800FOR i%=0 TO t1%!nop%-1 9810 IF (f1%?i%) AND 3 THEN 9820 x1%=c1%!0:y1%=c1%!4:z1%=c1%!8 9830 f%=f12%:IF (f1%?i%) AND 2 THEN f%=f%*4 9840 !v1pos=v1%:!v2pos=t2%!vel% 9850 PROCtemp(x1%,y1%,z1%,t2%!co0%,t2%!ptf%,f%,s%,r%) 9860 ENDIF 9870 c1%+=12:v1%+=12 9880NEXT 9890ENDPROC 9900: 9910DEF PROCtemp(A%,B%,C%,D%,E%,F%,G%,H%) 9920CALL repel_code 9930ENDPROC 9940: 9950DEF PROCrepel_objects(i%,t1%) 9960IF i%>objects%-2 OR t1%!ptf%=0 THEN ENDPROC 9970LOCAL j%,t2% 9980FOR j%=i%+1 TO objects%-1 9990 t2%=world%+j%*elsiz%(7) 10000 IF t2%!ptf%>0 THEN PROCrepel_points(t1%,t2%) 10010NEXT 10020ENDPROC 10030: 10040DEF PROCrot_damp(thing%,dsh%) 10050LOCAL p%,ve%,co%,x,y,z,vx,vy,vz,xc,yc,zc,vxc,vyc,vzc,Lx,Ly,Lz,i% 10060p%=thing%!nop% 10070 10080REM find centre of mass and linear velocity 10090xc=0:yc=0:zc=0 10100vxc=0:vyc=0:vzc=0 10110ve%=thing%!vel% 10120co%=thing%!co0% 10130FOR i%=0 TO p%-1 10140 xc+=co%!0:yc+=co%!4:zc+=co%!8 10150 vxc+=ve%!0:vyc+=ve%!4:vzc+=ve%!8 10160 ve%+=12:co%+=12 10170NEXT 10180vxc=vxc/p%:vyc=vyc/p%:vzc=vzc/p% 10190xc=xc/p%:yc=yc/p%:zc=zc/p% 10200 10210REM find ang. mom. about CoM 10220Lx=0:Ly=0:Lz=0 10230ve%=thing%!vel% 10240co%=thing%!co0% 10250FOR i%=0 TO p%-1 10260 x=co%!0-xc:y=co%!4-yc:z=co%!8-zc 10270 vx=ve%!0-vxc:vy=ve%!4-vyc:vz=ve%!8-vzc 10280 Lx-=y*vz-z*vy:Ly-=z*vx-x*vz:Lz-=x*vy-y*vx 10290 ve%+=12:co%+=12 10300NEXT 10310L=SQR(Lx*Lx+Ly*Ly+Lz*Lz) 10320IF L=0 THEN 10330 ax=0:ay=0:az=0 10340ELSE 10350 REM find moment of inertia about ang. mom. axis 10360 REM and hence rotation vector 10370 nLx=Lx/L:nLy=Ly/L:nLz=Lz/L 10380 I=0 10390 co%=thing%!co0% 10400 FOR i%=0 TO p%-1 10410 x=co%!0-xc:y=co%!4-yc:z=co%!8-zc 10420 a=nLx*x+nLy*y+nLz*z 10430 dx=x-nLx*a:dy=y-nLy*a:dz=z-nLz*a 10440 I+=dx*dx+dy*dy+dz*dz 10450 co%+=12 10460 NEXT 10470 ax=Lx/I:ay=Ly/I:az=Lz/I 10480ENDIF 10490 10500ve%=thing%!vel% 10510co%=thing%!co0% 10520IF dsh%<0 THEN 10530 FOR i%=0 TO p%-1 10540 x=co%!0-xc:y=co%!4-yc:z=co%!8-zc 10550 ve%!0=vxc+y*az-z*ay 10560 ve%!4=vyc+z*ax-x*az 10570 ve%!8=vzc+x*ay-y*ax 10580 ve%+=12:co%+=12 10590 NEXT 10600ELSE 10610 dsh%=1<<(dsh%+14) 10620 FOR i%=0 TO p%-1 10630 x=co%!0-xc:y=co%!4-yc:z=co%!8-zc 10640 vx=vxc+y*az-z*ay 10650 vy=vyc+z*ax-x*az 10660 vz=vzc+x*ay-y*ax 10670 x=ve%!0-vx:y=ve%!4-vy:z=ve%!8-vz 10680 I=dsh%/(SQR(x*x+y*y+z*z)+dsh%) 10690 ve%!0=vx+x*I:ve%!4=vy+y*I:ve%!8=vz+z*I 10700 ve%+=12:co%+=12 10710 NEXT 10720ENDIF 10730ENDPROC 10740: 10750DEF PROCair_damp(thing%,dsh%) 10760LOCAL f%,i%,x,y,z,I,ve% 10770f%=FNpoint_flags(thing%) 10780ve%=thing%!vel% 10790dsh%=1<<(dsh%+14) 10800FOR i%=0 TO thing%!nop%-1 10810 IF f%?i% AND 1 THEN 10820 x=ve%!0:y=ve%!4:z=ve%!8 10830 I=dsh%/(SQR(x*x+y*y+z*z)+dsh%) 10840 ve%!0=x*I:ve%!4=y*I:ve%!8=z*I 10850 ve%+=12 10860 ENDIF 10870NEXT 10880ENDPROC 10890: 10900DEF PROCmove(on%,thing%) 10910IF quit% OR thing%!vel%=0 THEN ENDPROC 10920SYS "Hourglass_On" 10930PROCdamp(thing%) 10940PROCalter_vels(thing%) 10950IF thing%!rdm%<0 PROCrot_damp(thing%,-1) 10960PROCadd_vels(thing%) 10970SYS "Hourglass_Off" 10980ENDPROC 10990: 11000DEF PROCdamp(thing%) 11010LOCAL pts% 11020pts%=thing%!nop% 11030!vepos=thing%!vel% 11040!copos=thing%!co0% 11050!pts12=12*(pts%-1) 11060IF thing%!rdm%<32 AND thing%!rdm%>=0 THEN PROCrot_damp(thing%,thing%!rdm%+tsh%) 11070IF thing%!adm%<32 THEN PROCair_damp(thing%,thing%!adm%+tsh%) 11080IF thing%!odm%<32 THEN !dampsh=thing%!odm%+tsh%:CALL old_damp 11090ENDPROC 11100: 11110DEF PROCalter_vels(thing%) 11120LOCAL pts%,vb%,cb%,A%,B%,E%,F%,x,y,z,nx,ny,nz,h%,flx% 11130pts%=thing%!nop% 11140!vepos=thing%!vel% 11150!copos=thing%!co0% 11160 11170IF thing%!rdm%>=0 THEN 11180 !bopos=thing%!bnd% 11190 E%=thing%!nob%-1 11200 SYS "Hourglass_LEDs",1 11210 CALL bond 11220ENDIF 11230 11240frsh%=4+tsh% 11250frnd%=.5*(1<<frsh%) 11260SYS "Hourglass_LEDs",3 11270PROCrepel_objects(on%,thing%) 11280 11290cb%=!copos:vb%=!vepos 11300SYS "Hourglass_LEDs",2 11310FOR A%=0 TO pts%-1 11320 vb%!0-=grav_z%:vb%!4+=grav_x%:vb%!8+=grav_y% 11330 x=cb%!4:y=cb%!8:z=cb%!0 11340 FOR B%=1 TO backgrounds% 11350 x-=bgdef%(B%,1):y-=bgdef%(B%,2):z+=bgdef%(B%,3) 11360 CASE bgdef%(B%,0) OF 11370 WHEN 0:IF z>-5000 THEN vb%!0-=(z+5000)>>1:vb%!4-=(vb%!4+frnd%)>>frsh%:vb%!8-=(vb%!8+frnd%)>>frsh% 11380 WHEN 3:r=SQR(x*x+y*y+z*z):E%=bgdef%(B%,4)+5000 11390 IF r<E% THEN 11400 r=2*(E%-r)/r 11410 vb%!0-=(vb%!0+frnd%)>>frsh%:vb%!0+=z*r 11420 vb%!4-=(vb%!4+frnd%)>>frsh%:vb%!4+=x*r 11430 vb%!8-=(vb%!8+frnd%)>>frsh%:vb%!8+=y*r 11440 ENDIF 11450 WHEN 4: 11460 n%=.5*(y/bgdef%(B%,6)-z/bgdef%(B%,5)) 11470 h%=-n%*bgdef%(B%,5)-5000 11480 IF z>h% THEN 11490 IF vb%!0>0 vb%!0-=(z-h%)>>1:vb%!4=vb%!4>>2:vb%!8=vb%!8>>2 11500 ELSE 11510 h%=(n%+1)*bgdef%(B%,6)-5000 11520 IF y>h% AND vb%!8>0 THEN vb%!8-=(y-h%)>>1::vb%!4=vb%!4>>2:vb%!0=vb%!0>>2 11530 ENDIF 11540 ENDCASE 11550 x+=bgdef%(B%,1):y+=bgdef%(B%,2):z-=bgdef%(B%,3) 11560 NEXT 11570 IF ((ABS(vb%!0)+ABS(vb%!4)+ABS(vb%!8))>>tsh%)>3E6 THEN quit%=TRUE 11580 vb%+=12:cb%+=12 11590NEXT 11600ENDPROC 11610: 11620DEF PROCadd_vels(thing%) 11630LOCAL cb%,vb%,pb%,A%,B% 11640cb%=thing%!co0% 11650vb%=thing%!vel% 11660pb%=thing%!ptf% 11670IF pb%<=0 THEN 11680 FOR A%=0 TO thing%!nop%-1 11690 cb%!0+=(vb%!0>>tsh%):cb%!4+=(vb%!4>>tsh%):cb%!8+=(vb%!8>>tsh%) 11700 vb%+=12:cb%+=12 11710 NEXT 11720ELSE 11730 FOR A%=0 TO thing%!nop%-1 11740 B%=pb%?A%>>2:IF B%=0 THEN B%=vb% ELSE B%=pull%+12*B% 11750 cb%!0+=B%!0>>tsh%:cb%!4+=B%!4>>tsh%:cb%!8+=B%!8>>tsh% 11760 vb%+=12:cb%+=12 11770 NEXT 11780ENDIF 11790ENDPROC 11800: 11810DEF FNsurface(thing%,P%,S%,XI%,YI%,XN%,YN%,wind%,LP%) 11820LOCAL X%,Y%,A%,B% 11830IF P%=0 THEN P%=thing%!fac%:IF P%<TOP THEN ERROR 1,"bad pointer passed to FNsurface" 11840IF XN%<2 OR YN%<2 THEN =P% 11850IF S%+(XN%-1+(LP% AND 1))*(YN%-1+.5*(LP% AND 2))>thing%!nof% THEN ERROR 1,"not enough facet space" 11860FOR Y%=0 TO YN%-2 11870 FOR X%=0 TO XN%-2 11880 A%=S%+X%*XI%+Y%*YI% 11890 P%=FNdefine_facet(P%,A%+XI%,A%,A%+YI%,1+(X%=-(LP% AND 1) OR Y%=-(LP% AND 2))) 11900 P%=FNdefine_facet(P%,A%+YI%,A%+XI%+YI%,A%+XI%,0) 11910 NEXT 11920 IF LP% AND 1 THEN 11930 A%=S%+(XN%-1)*XI%+Y%*YI%:B%=S%+Y%*YI% 11940 P%=FNdefine_facet(P%,B%,A%,A%+YI%,1+(Y%=-(LP% AND 2))) 11950 P%=FNdefine_facet(P%,A%+YI%,B%+YI%,B%,0) 11960 ENDIF 11970NEXT 11980IF LP% AND 2 THEN 11990 FOR X%=0 TO XN%-2 12000 B%=S%+X%*XI%:A%=B%+(YN%-1)*YI% 12010 P%=FNdefine_facet(P%,A%+XI%,A%,B%,1+(X%=-(LP% AND 1))) 12020 P%=FNdefine_facet(P%,B%,B%+XI%,A%+XI%,0) 12030 NEXT 12040 IF LP% AND 1 THEN 12050 A%=(XN%-1)*XI%:B%=(YN%-1)*YI% 12060 P%=FNdefine_facet(P%,S%+B%,S%+A%+B%,S%+A%,0) 12070 P%=FNdefine_facet(P%,S%+A%,S%,S%+B%,0) 12080 ENDIF 12090ENDIF 12100=P% 12110: 12120DEF FNModeVar(V%) 12130SYS"OS_ReadModeVariable",mode%,V% TO ,,V% 12140=V% 12150: 12160DEF PROCassemstore(mode%,stostyle%) 12170L2BPP%=FNModeVar(10) 12180NPIX%=FNModeVar(7)*8>>L2BPP% 12190MASK%=(1<<(1<<L2BPP%))-1 12200cspace=1000 12210DIM code cspace 12220A%=0:B%=1:C%=2:D%=3:E%=4:F%=5:G%=6:H%=7 12230link=14:sp=13:pc=15 12240FOR PASS=0 TO 2 STEP 2 12250P%=code 12260F%=5 12270[ OPT PASS 12280ALIGN 12290.frstore 12300STMFD (sp)!,{link} 12310LDR C%,storepos:CMP C%,#0:LDMEQFD (sp)!,{pc} 12320LDR R11,storend 12330SUB R8,R11,C%:CMP R8,#5:MOVLE C%,#0:BLE exfrstrlp 12340MOV A%,#0 12350MOV R10,#MASK%:MOV H%,R10 12360LDR B%,scrpos:BL findpix 12370STRB A%,[C%],#1 12380MOV R8,A%,ASR#8:STRB R8,[C%],#1 12390MOV R8,A%,ASR#16:STRB R8,[C%],#1 12400.frstrlp 12410CMP A%,#NPIX%:BGE exfrstrlp 12420CMP C%,R11:BGE exfrstrlp 12430ADD A%,A%,#1:MOV E%,A% 12440BL findpix:SUB D%,A%,E% 12450.frstrlp2 12460CMP D%,#128:BLT exfrstrlp2 12470CMP C%,R11:BGE exfrstrlp 12480MOV E%,D%,ASR#7 12490CMP E%,#128:MOVGE E%,#127 12500ORR R8,E%,#&80:STRB R8,[C%],#1 12510SUB D%,D%,E%,ASL#7 12520B frstrlp2 12530.exfrstrlp2 12540STRB D%,[C%],#1 12550B frstrlp 12560.exfrstrlp 12570CMP C%,R11:MOVGE C%,#0 12580STR C%,storepos 12590LDMFD (sp)!,{pc} 12600 12610.findpix 12620STMFD (sp)!,{R8,R9,link} 12630.fpixlp 12640CMP A%,#NPIX%:LDMGEFD (sp)!,{R8,R9,pc} 12650LDRB R8,[B%,A%,ASR#(3-L2BPP%)] 12660AND R9,A%,#7>>L2BPP% 12670MOV R9,R9,ASL#L2BPP% 12680ANDS R8,R8,R10,ASL R9 12690] 12700IF stostyle%=0 THEN [OPT PASS:LDMNEFD (sp)!,{R8,R9,pc}:] 12710IF stostyle%=1 THEN 12720 [ OPT PASS 12730 CMP R8,H%,ASL R9 12740 EOREQ H%,H%,R10 12750 LDMEQFD (sp)!,{R8,R9,pc} 12760 ] 12770ENDIF 12780[ OPT PASS 12790ADD A%,A%,#1 12800B fpixlp 12810 12820.show 12830STMFD (sp)!,{link} 12840MOV R10,#MASK% 12850LDR B%,scrpos 12860LDRB A%,[C%],#1 12870LDRB R8,[C%],#1:ORR A%,A%,R8,ASL#8 12880LDRB R8,[C%],#1:ORR A%,A%,R8,ASL#16 12890] 12900IF stostyle%=0 THEN 12910 [OPT PASS 12920 .shloop 12930 CMP A%,#NPIX%:BGE exshloop 12940 LDRB R8,[B%,A%,ASR#(3-L2BPP%)] 12950 AND R9,A%,#7>>L2BPP% 12960 MOV R9,R9,ASL#L2BPP% 12970 EOR R8,R8,R10,ASL R9 12980 STRB R8,[B%,A%,ASR#(3-L2BPP%)] 12990 ADD A%,A%,#1 13000 ] 13010ENDIF 13020IF stostyle%=1 THEN 13030 [ OPT PASS 13040 .shloop 13050 \ want pixel A% set 13060 13070 \ get next offset 13080 CMP A%,#NPIX%:BGE exshloop 13090 ADD G%,A%,#1:.shloop3 13100 LDRB D%,[C%],#1 13110 TST D%,#&80:ANDNE D%,D%,#&7F:MOVNE D%,D%,ASL#7 13120 ADD G%,G%,D%:CMP D%,#128:BGE shloop3 13130 13140 \ plot pixels A% to G%-1 13150 .shloop4 13160 LDRB R8,[B%,A%,ASR#(3-L2BPP%)] 13170 AND R9,A%,#7>>L2BPP% 13180 MOV R9,R9,ASL#L2BPP% 13190 EOR R8,R8,R10,ASL R9 13200 STRB R8,[B%,A%,ASR#(3-L2BPP%)] 13210 ADD A%,A%,#1:CMP A%,G%:BLT shloop4 13220 ADD A%,A%,#1 13230 13240 \ get next offset 13250 CMP A%,#NPIX%:BGE exshloop 13260 ] 13270ENDIF 13280[ OPT PASS 13290.shloop2 13300LDRB D%,[C%],#1 13310TST D%,#&80:ANDNE D%,D%,#&7F:MOVNE D%,D%,ASL#7 13320ADD A%,A%,D%:CMP D%,#128:BGE shloop2 13330B shloop 13340.exshloop 13350MOV A%,C%:LDMFD (sp)!,{pc} 13360 13370.copy1t2 13380STMFD (sp)!,{link} 13390LDR R0,scrlen 13400LDR R1,scrpos2:LDR R2,scrpos1 13410ADD R0,R1,R0 13420.cop1t2lp 13430LDMIA R1!,{R3-R10}:STMIA R2!,{R3-R10} 13440CMP R1,R0:BLT cop1t2lp 13450LDMFD (sp)!,{pc} 13460 13470.eor2w1 13480STMFD (sp)!,{link} 13490LDR R0,scrlen 13500LDR R1,scrpos2:LDR R2,scrpos1 13510ADD R0,R1,R0 13520.eor2w1lp 13530LDMIA R1!,{R3-R6}:LDMIA R2,{R7-R10} 13540EOR R3,R3,R7:EOR R4,R4,R8:EOR R5,R5,R9:EOR R6,R6,R10 13550STMIA R2!,{R3-R6} 13560CMP R1,R0:BLT eor2w1lp 13570LDMFD (sp)!,{pc} 13580 13590.bank EQUD 1 13600.storepos EQUD 0 13610.storend EQUD 0 13620.scrpos EQUD 0 13630.scrpos1 EQUD 0 13640.scrpos2 EQUD 0 13650.scrlen EQUD FNModeVar(7) 13660] 13670IF P%>code+cspace THEN ERROR 1,"Out of room for code" 13680NEXT PASS 13690ENDPROC 13700: 13710DEF PROCassem_nebo 13720PROCassemRoot 13730A%=0:B%=1:C%=2:D%=3:E%=4:F%=5:G%=6:H%=7 13740uDiv32=FNassemDiv(5,0,2,8,9) 13750DIM scrap% 256*4 13760cspace=500 13770DIM code cspace 13780link=14:sp=13:pc=15 13790FOR PASS=0 TO 2 STEP 2 13800P%=code 13810[ OPT PASS 13820.nearbond 13830STMFD (sp)!,{link} 13840LDR R8,neboblock:LDR R9,neboblock+4:LDR B%,neboblock+8:LDR R10,neboblock+12 13850SUB E%,E%,#1:MOV R12,#12:MLA H%,E%,R12,H% 13860.nblp2 13870SUB G%,H%,#12:SUB F%,E%,#1 13880.nblp1 13890LDR A%,[H%,#8]:LDR R12,[G%,#8]:SUB A%,A%,R12 13900MOV A%,A%,ASR R10:MUL C%,A%,A%:CMP C%,R9:BGT nbskip 13910LDR A%,[H%,#4]:LDR R12,[G%,#4]:SUB A%,A%,R12 13920MOV A%,A%,ASR R10:MLA C%,A%,A%,C%:CMP C%,R9:BGT nbskip 13930LDR A%,[H%,#0]:LDR R12,[G%,#0]:SUB A%,A%,R12 13940MOV A%,A%,ASR R10:MLA C%,A%,A%,C%:CMP C%,R9:BGT nbskip 13950LDR A%,neboblock+16:CMP C%,A%:BLT nbskip 13960CMP B%,D%:ADDGE B%,B%,#8:BGE nbskip 13970BL root:LDR A%,[R8,A%,ASL#2]:STR A%,[B%,#4] 13980ORR A%,E%,F%,ASL#16:STR A%,[B%],#8 13990.nbskip 14000SUB G%,G%,#12:SUBS F%,F%,#1:BGE nblp1 14010SUB H%,H%,#12:SUBS E%,E%,#1:BGT nblp2 14020STR B%,neboblock+8 14030LDMFD (sp)!,{pc} 14040.neboblock EQUD 0:EQUD 0:EQUD 0:EQUD 0:EQUD 0 14050 14060.nearcount 14070STMFD (sp)!,{link} 14080LDR R8,neboblock:LDR R9,neboblock+4:LDR R10,neboblock+12 14090MOV B%,#0 14100SUB E%,E%,#1:MOV R12,#12:MLA H%,E%,R12,H% 14110.cnblp2 14120SUB G%,H%,#12:SUB F%,E%,#1 14130.cnblp1 14140LDR A%,[H%,#8]:LDR R12,[G%,#8]:SUB A%,A%,R12 14150MOV A%,A%,ASR R10:MUL C%,A%,A%:CMP C%,R9:BGT cnbskip 14160LDR A%,[H%,#4]:LDR R12,[G%,#4]:SUB A%,A%,R12 14170MOV A%,A%,ASR R10:MLA C%,A%,A%,C%:CMP C%,R9:BGT cnbskip 14180LDR A%,[H%,#0]:LDR R12,[G%,#0]:SUB A%,A%,R12 14190MOV A%,A%,ASR R10:MLA C%,A%,A%,C%:CMP C%,R9:BGT cnbskip 14200LDR A%,neboblock+16:CMP C%,A%:BLT cnbskip 14210ADD B%,B%,#1 14220.cnbskip 14230SUB G%,G%,#12:SUBS F%,F%,#1:BGE cnblp1 14240SUB H%,H%,#12:SUBS E%,E%,#1:BGT cnblp2 14250MOV R0,B% 14260LDMFD (sp)!,{pc} 14270] 14280IF P%>code+cspace THEN ERROR 1,"Out of room for code" 14290NEXT PASS 14300ENDPROC 14310: 14320DEF PROCassem 14330cspace=3000 14340DIM code cspace 14350A%=0:B%=1:C%=2:D%=3:E%=4:F%=5:G%=6:H%=7 14360repeldiv=FNassemDiv(F%,D%,6,7,8) 14370X%=0:Y%=1:Z%=3 14380AI%=12:BI%=11:SA%=9:CB%=8:SB%=7 14390link=14:sp=13:pc=15 14400FOR PASS=0 TO 2 STEP 2 14410P%=code 14420[ OPT PASS 14430 14440.basic_stack 14450MOV R0,R13 14460MOV pc,link 14470 14480.avZ 14490MOV R10,#12 14500STMFD (sp)!,{link} 14510.avzloop 14520LDMIA C%,{R7,R8,R9} 14530MLA R7,R10,R7,D% 14540MLA R8,R10,R8,D% 14550MLA R9,R10,R9,D% 14560LDR F%,[R7] 14570LDR R11,[R8]:ADD F%,F%,R11 14580LDR R11,[R9]:ADD F%,F%,R11 14590STR F%,[C%,#12] 14600ADD C%,C%,#elsiz%(3) 14610SUBS E%,E%,#1:BGE avzloop 14620LDMFD (sp)!,{pc} 14630 14640.hidefaces 14650STMFD (sp)!,{link} 14660.hideflp 14670LDR F%,[C%,#16] 14680LDMIA C%,{R7,R9,R11} 14690ADD R7,D%,R7,ASL#3 14700ADD R9,D%,R9,ASL#3 14710ADD R11,D%,R11,ASL#3 14720LDMIA R7,{R7,R8} 14730LDMIA R9,{R9,R10} 14740LDMIA R11,{R11,R12} 14750SUB R9 ,R9 ,R7:SUB R10,R10,R8 14760SUB R11,R11,R7:SUB R12,R12,R8 14770MUL R7,R9,R12:MUL R8,R10,R11 14780BIC F%,F%,#&20000000 14790CMP R7,R8:ORRLT F%,F%,#&20000000 14800STR F%,[C%,#16] 14810ADD C%,C%,#elsiz%(3) 14820SUBS E%,E%,#1:BGE hideflp 14830LDMFD (sp)!,{pc} 14840 14850.pts12 EQUD 0 14860.vel2pos EQUD vel2% 14870.storesp EQUD 0 14880.dampran EQUD (1.0*180)^2 14890.dampsh EQUD dampsh% 14900.divtab EQUD recip% 14910 14920.v1pos EQUD 0:.v2pos EQUD 0 14930.frict EQUD 0 14940 14950.repel_code 14960STMFD (sp)!,{link} 14970LDR R10,pts12 14980MOV R8,R4 14990LDR R9,v2pos 15000.repel_lp1 15010\ 0,1,2=x1%,y1%,z1% 3=c2% 4= 5=f% 6=s% 7=r% 8=f2% 9=v2% 15020LDRB R4,[R8]:TST R4,#3:BLNE repel_comppair 15030\ R11,R12 changed 15040ADD R3,R3,#12 15050ADD R9,R9,#12 15060ADD R8,R8,#1 15070SUBS R10,R10,#12 15080BGE repel_lp1 15090LDMFD (sp)!,{pc} 15100 15110.repel_comppair 15120\STMFD (sp)!,{R0-R3,R10,link} 15130STMFD (sp)!,{R0-R3,R9-R10,link} 15140\ 0,1,2=x1%,y1%,z1% 3=c2% 4=f2%?0 5=f% 6=s% 7=r% 15150LDMIA R3,{R10,R11,R12} 15160SUB R0,R0,R10:SUB R1,R1,R11:SUB R2,R2,R12 15170MOV R0,R0,ASR#7:MOV R1,R1,ASR#7:MOV R2,R2,ASR#7 15180MUL R3,R0,R0:MLA R3,R1,R1,R3:MLA R3,R2,R2,R3 15190\ R0,R1,R2,R3,R10,R11,R12 changed 15200CMP R3,R7:BLLT repel_pair 15210\ R0,R1,R2,R3,R10,R11,R12 changed 15220LDMFD (sp)!,{R0-R3,R9-R10,pc} 15230\ R11,R12 changed 15240 15250.repel_pair 15260STMFD (sp)!,{R4-R8,link} 15270\ (0,1,2)=(dx,dy,dz) 3=d^2 4=f2%?j% 5=f% 6=s% 7=r% 15280LDR R10,v1pos:MOV R11,R9:LDR R12,frict 15290BL rroot 15300CMP R3,#2:MOVLT R3,#2 15310SUB R6,R6,R3:MUL R5,R6,R5 15320BL repeldiv 15330\ 3,5,6,7,8 changed 15340MUL R0,R6,R0:MUL R1,R6,R1:MUL R2,R6,R2 15350AND R4,R4,#2:RSB R3,R4,#8 15360LDMIA R10,{R4,R5,R6} 15370SUB R4,R4,R4,ASR R12:ADD R4,R4,R0,ASR R3 15380SUB R5,R5,R5,ASR R12:ADD R5,R5,R1,ASR R3 15390SUB R6,R6,R6,ASR R12:ADD R6,R6,R2,ASR R3 15400STMIA R10,{R4,R5,R6} 15410LDMIA R11,{R4,R5,R6} 15420SUB R4,R4,R4,ASR R12:SUB R4,R4,R0,ASR R3 15430SUB R5,R5,R5,ASR R12:SUB R5,R5,R1,ASR R3 15440SUB R6,R6,R6,ASR R12:SUB R6,R6,R2,ASR R3 15450STMIA R11,{R4,R5,R6} 15460\ R0,R1,R2,R3,R4,R5,R6,R7,R8,R10,R11,R12 changed 15470LDMFD (sp)!,{R4-R8,pc} 15480\ R0,R1,R2,R3,R10,R11,R12 changed 15490 15500.rroot 15510STMFD (sp)!,{R4-R9,link} 15520\ square=R3 15530MOV R4,#&C0000000 15540MOV R5,#30:MOV R6,#0:MOV R7,#0 15550.lp_rroot 15560MOV R6,R6,LSL#1:MOV R7,R7,LSL#2 15570AND R9,R3,R4:MOV R9,R9,LSR R5 15580ORR R7,R7,R9:MOV R8,R6,LSL#1:ADD R8,R8,#1 15590CMP R7,R8:SUBGE R7,R7,R8:ADDGE R6,R6,#1 15600MOV R4,R4,LSR#2:SUBS R5,R5,#2 15610BPL lp_rroot 15620MOV R3,R6,ASL#7 15630LDMFD (sp)!,{R4-R9,pc} 15640 15650.old_damp 15660LDR A%,pts12 15670LDR B%,vepos 15680LDR R9,dampsh 15690.damploop 15700LDMIA B%,{R10,R11,R12} 15710MOVS C%,R10,ASR#7:MUL D%,C%,C%:RSBMI D%,D%,#0:SUB R10,R10,D%,ASR R9 15720MOVS C%,R11,ASR#7:MUL D%,C%,C%:RSBMI D%,D%,#0:SUB R11,R11,D%,ASR R9 15730MOVS C%,R12,ASR#7:MUL D%,C%,C%:RSBMI D%,D%,#0:SUB R12,R12,D%,ASR R9 15740STMIA (B%)!,{R10,R11,R12} 15750SUBS A%,A%,#12:BGE damploop 15760MOV pc,link 15770 15780.qfsort 15790STMFD (sp)!,{A%,B%,C%,F%,G%,link} 15800ADD A%,F%,G%:MOV A%,A%,ASR#1 15810LDR E%,[D%,A%,ASL#2]:LDR C%,[E%,#12] 15820MOV A%,F%:MOV B%,G% 15830.qfslp1 15840LDR E%,[D%,A%,ASL#2]:LDR E%,[E%,#12] 15850CMP E%,C%:ADDLT A%,A%,#1:BLT qfslp1 15860.qfslp2 15870LDR E%,[D%,B%,ASL#2]:LDR E%,[E%,#12] 15880CMP C%,E%:SUBLT B%,B%,#1:BLT qfslp2 15890CMP A%,B%:BGT skipswap 15900LDR E%,[D%,A%,ASL#2]:LDR R9,[D%,B%,ASL#2] 15910STR R9,[D%,A%,ASL#2]:STR E%,[D%,B%,ASL#2] 15920.skipswap 15930ADD A%,A%,#1:SUB B%,B%,#1 15940CMP A%,B%:BLE qfslp1 15950MOV C%,G%:CMP F%,B%:MOVLT G%,B%:BLLT qfsort 15960MOV G%,C%:CMP A%,G%:MOVLT F%,A%:BLLT qfsort 15970LDMFD (sp)!,{A%,B%,C%,F%,G%,pc} 15980 15990.bond 16000STMFD (sp)!,{link} 16010.bondloop 16020LDR R8,bopos:LDR G%,[R8,E%,ASL#3] 16030ADD R8,R8,#4:LDR F%,[R8,E%,ASL#3] 16040MOV H%,G%,LSR#16:EOR G%,G%,H%,LSL#16 16050MOV R8,#12:MUL G%,R8,G%:MUL H%,R8,H% 16060LDR R8,copos 16070ADD R9,R8,G%:LDMIA R9,{R0,R1,R2} 16080ADD R9,R8,H%:LDMIA R9,{R10,R11,R12} 16090SUB R10,R0,R10:SUB R11,R1,R11:SUB R12,R2,R12 16100MOV B%,#0 16110CMP R10,#0:RSBLT R10,R10,#0:ORRLT B%,B%,#1 16120CMP R11,#0:RSBLT R11,R11,#0:ORRLT B%,B%,#2 16130CMP R12,#0:RSBLT R12,R12,#0:ORRLT B%,B%,#4 16140MOV D%,#1:MOV R8,#&6800 16150.zssl:CMP R8,R10,ASR D%:ADDLT D%,D%,#1:BLT zssl 16160.xssl:CMP R8,R11,ASR D%:ADDLT D%,D%,#1:BLT xssl 16170.yssl:CMP R8,R12,ASR D%:ADDLT D%,D%,#1:BLT yssl 16180MOV R10,R10,ASR D%:MOV R11,R11,ASR D%:MOV R12,R12,ASR D% 16190MUL C%,R10,R10:MLA C%,R11,R11,C%:MLA C%,R12,R12,C% 16200BL root:CMP A%,#0:BEQ divby0 16210MOV R8,F%,LSR#24:MOV R9,F%,LSL#8:MOV R9,R9,LSR#8 16220MOV F%,A%,ASL D%:SUB F%,F%,R9:MUL F%,R8,F% 16230CMP F%,#0:RSBLT F%,F%,#0:EORLT B%,B%,#7 16240MOV D%,#0:MOV R8,#&8000 16250.fssl:CMP R8,F%,ASR D%:ADDLT D%,D%,#1:BLT fssl 16260RSB D%,D%,#12:MOV F%,F%,ASL D%:ADD D%,D%,#7 16270BL uDiv32 16280MUL R10,C%,R10:MOV R10,R10,ASR D%:TST B%,#1:RSBNE R10,R10,#0 16290MUL R11,C%,R11:MOV R11,R11,ASR D%:TST B%,#2:RSBNE R11,R11,#0 16300MUL R12,C%,R12:MOV R12,R12,ASR D%:TST B%,#4:RSBNE R12,R12,#0 16310LDR R8,vepos 16320ADD R9,R8,G%:LDMIA R9,{R0,R1,R2}:SUB R0,R0,R10:SUB R1,R1,R11:SUB R2,R2,R12:STMIA R9,{R0,R1,R2} 16330ADD R9,R8,H%:LDMIA R9,{R0,R1,R2}:ADD R0,R0,R10:ADD R1,R1,R11:ADD R2,R2,R12:STMIA R9,{R0,R1,R2} 16340.divby0 16350SUBS E%,E%,#1:BGE bondloop 16360LDMFD (sp)!,{pc} 16370.bopos EQUD 0 16380.nopts EQUD 0 16390 16400.rotate 16410STMFD (sp)!,{link} 16420ADR AI%,sinpos:LDMIA AI%,{SB%,CB%} 16430LDR R4,nopts:LDR R10,copos:LDR R9,store2pos:LDR R14,store3pos 16440.loop 16450\ look up coordinates 16460LDMIA R10!,{X%,Y%,Z%} 16470MOV X%,X%,ASR#10:MOV Y%,Y%,ASR#10:MOV Z%,Z%,ASR#10 16480ADD X%,X%,X%,ASR#1:ADD Y%,Y%,Y%,ASR#1:ADD Z%,Z%,Z%,ASR#1 16490\ rotate around x axis 16500LDR AI%,cos2%:LDR BI%,sin2% 16510MUL R5,AI%,Y%:MLA R5,Z%,BI%,R5:MOV R5,R5,ASR#10 16520MUL Z%,AI%,Z%:MUL R6,Y%,BI%:SUB Z%,Z%,R6:MOV Z%,Z%,ASR#10 16530MOV Y%,R5 16540\ rotate around y axis 16550LDR AI%,cos%:LDR BI%,sin% 16560MUL R5,X%,AI%:MUL R6,Z%,BI%:SUB R5,R5,R6:MOV R5,R5,ASR#10 16570MUL Z%,AI%,Z%:MLA Z%,X%,BI%,Z%:MOV X%,R5 16580MOV Z%,Z%,ASR#10 16590\ store 3D point 16600STMIA R14!,{X%,Y%,Z%} 16610\ apply perspective, store 2D point 16620LDR R5,perpos:RSBS R6,X%,#&400:MOVLT R6,#0 16630CMP R6,#&800:MOVGT R6,#&800 16640LDR R6,[R5,R6,ASL#2] 16650MUL Y%,R6,Y%:MOV Y%,Y%,ASR#10:ADD Y%,Y%,#1+FNModeVar(11)<<FNModeVar(4)-1 16660MUL Z%,R6,Z%:MOV Z%,Z%,ASR#10:ADD Z%,Z%,#1+FNModeVar(12)<<FNModeVar(5)-1 16670STMIA R9!,{Y%,Z%} 16680\ 16690SUBS R4,R4,#1:BGT loop 16700LDMFD (sp)!,{pc} 16710 16720.sinpos EQUD sin:.cospos EQUD cos 16730.perpos EQUD per% 16740.sin% EQUD 0:.cos% EQUD 0 16750.sin2% EQUD 0:.cos2% EQUD 0 16760.copos EQUD 0 16770.vepos EQUD 0 16780.store2pos EQUD 0 16790.store3pos EQUD 0 16800] 16810IF P%>code+cspace THEN ERROR 1,"Out of room for code" 16820NEXT PASS 16830ENDPROC 16840: 16850DEF FNassemDiv(lhs,rhs,div,mod,count) 16860LOCAL code,PASS 16870DIM code 64 16880FOR PASS=0 TO 2 STEP 2 16890P%=code 16900[ OPT PASS 16910MOV mod,#0 16920MOV div,#0 16930MOV count,#32 16940.divLp1 16950SUBS count,count,#1 16960MOVEQ pc,link 16970MOVS lhs,lhs,ASL#1 16980BPL divLp1 16990.divLp2 17000MOVS lhs,lhs,ASL#1 17010ADC mod,mod,mod 17020CMP mod,rhs 17030SUBCS mod,mod,rhs 17040ADC div,div,div 17050SUBS count,count,#1 17060BNE divLp2 17070.divErr 17080MOV R15,R14 17090] 17100IF P%>code+64 THEN ERROR 1234,"Out of room for code" 17110NEXT PASS 17120=code 17130: 17140DEF PROCassemRoot 17150DIM code% 200 17160link=14:sp=13:pc=15 17170sqrt=0:square=2:mask=1:shift=3 17180diff=4:subtrahend=5:t=6:min=7 17190FOR pass%=0 TO 2 STEP 2 17200P%=code% 17210[OPT pass% 17220.Rstore EQUS STRING$(4*8,CHR$0) 17230.root 17240ADR sqrt,Rstore:STMIA sqrt,{1-7,link} 17250MOV mask,#&C0000000 17260MOV shift,#30 17270MOV sqrt,#0 17280MOV min,#0 17290.nextbit 17300MOV sqrt,sqrt,LSL#1 17310MOV min,min,LSL#2 17320AND t,square,mask 17330MOV t,t,LSR shift 17340ORR min,min,t 17350MOV subtrahend,sqrt,LSL#1 17360ADD subtrahend,subtrahend,#1 17370CMP min,subtrahend 17380SUBGE min,min,subtrahend 17390ADDGE sqrt,sqrt,#1 17400MOV mask,mask,LSR#2 17410SUBS shift,shift,#2 17420BPL nextbit 17430ADR R1,Rstore:LDMIA R1,{1-7,pc} 17440] 17450NEXT 17460ENDPROC 17470: 17480DEF PROCerror 17490ON ERROR OFF 17500MODE 0 17510PRINT REPORT$;" at line ";ERL 17520SYS "Hourglass_Smash" 17530IF ch%>0 CLOSE#ch% 17540IF anim% THEN SYS "OS_PrettyPrint","Enter PROCsave(""filename"") to save the animation in memory"+CHR$13+"Press F4 to return to the Desktop"+CHR$13+CHR$0 17550*Key 4 |USYS"Wimp_CommandWindow",-1|MQUIT|M 17560END 17570: 17580DEF PROCstatus(FR%) 17590LOCAL A$,O%,H% 17600frames%=(storend%-store1%)*FR%/(!storepos-store1%) 17610VDU 30:PRINT"Frame ";FR%;"/";frames% 17620PRINT;!storepos-store%;" bytes (";INT(.5+100*(!storepos-store%)/(storend%-store%));"%)" 17630O%=TIME-startime% 17640PRINT"last frame: ";O% DIV 100;".";(O% DIV 10)MOD 10;O% MOD 10;"s" 17650REM PRINT;movetime%-startime%;"+";TIME-movetime% 17660gentime%+=TIME-startime% 17670IF aim%<frames% AND aim%>FR% THEN frames%=aim% 17680O%=gentime%*(frames%-FR%)/FR% 17690!timblk%=3:timblk%!4=0:SYS "OS_Word",14,timblk% 17700H%=timblk%!3 17710!timblk%=(!timblk% AND &FFFFFF)+(O% AND &FFFFFF) 17720timblk%!3=H%+(O%>>24)+timblk%?3 17730SYS "OS_ConvertDateAndTime",timblk%,stri%,255,"%z12:%mi%pm" TO ,O% 17740?O%=13:PRINT;frames%;" frames at ";$stri% 17750ENDPROC 17760: 17770DEF ---------------------------------------------------------------------- 17780: 17790DEF PROCinitthing(thing%,np%,nf%,nb%,f%) 17800thing%!nop%=np% 17810thing%!nof%=nf% 17820thing%!nob%=nb% 17830IF f% AND &01 THEN thing%!co0%=FNcreate(1,np%) 17840IF f% AND &02 THEN thing%!co1%=FNcreate(1,np%) 17850IF f% AND &04 THEN thing%!co2%=FNcreate(2,np%) 17860IF f% AND &08 THEN thing%!vel%=FNcreate(1,np%) ELSE thing%!vel%=0 17870IF f% AND &10 THEN thing%!fac%=FNcreate(3,nf%) 17880IF f% AND &20 THEN thing%!bnd%=FNcreate(6,nb%) 17890IF f% AND &40 THEN thing%!fno%=FNcreate(1,nf%) 17900IF f% AND &80 THEN thing%!ptf%=FNcreate(1,nf%) ELSE thing%!ptf%=0 17910thing%!odm%=32 17920thing%!rdm%=32 17930thing%!adm%=32 17940thing%!rep%=0 17950ENDPROC 17960: 17970DEF PROCinit3OOD 17980LOCAL A% 17990maxobjs%=20 18000types%=9 18010wind%=1 18020DIM elsiz%(types%-1) 18030elsiz%(0)=0:elsiz%(1)=12:elsiz%(2)=8:elsiz%(3)=20:elsiz%(4)=4:elsiz%(5)=4 18040elsiz%(6)=8:elsiz%(7)=64:elsiz%(8)=1 18050nop%=0:nof%=4:nob%=8:co0%=12:co1%=16:co2%=20:vel%=24:fac%=28:bnd%=32:fno%=36:adm%=40:rdm%=44:odm%=48:sep%=52:ptf%=56:rep%=60 18060ENDPROC 18070: 18080DEF FNcreate(TYPE%,NOEL%) 18090IF TYPE%>=types% OR TYPE%<0 THEN ERROR 1234,"Invalid object type" 18100IF NOEL%<0 THEN ERROR 1234,"Silly number of elements requested" 18110LOCAL A%,S% 18120DIM S% NOEL%*elsiz%(TYPE%) 18130IF TYPE%=7 THEN 18140 FOR A%=0 TO NOEL%*elsiz%(TYPE%)-4:S%!A%=0:NEXT 18150ENDIF 18160=S% 18170: 18180DEF FNinit_facpoint(A%,B%,N%,S%) 18190IF N%=0 ENDPROC 18200LOCAL C%,Q% 18210B%+=S%*elsiz%(4) 18220FOR C%=0 TO N%-1:B%!(C%*elsiz%(4))=A%+C%*elsiz%(3):NEXT 18230=S%+N% 18240: 18250DEF PROCrotnpersp(A%,D%,E%,F%) 18260!sin%=sin!(D%*4):!cos%=cos!(D%*4) 18270!sin2%=sin!(E%*4):!cos2%=cos!(E%*4) 18280!nopts=A%!nop% 18290!copos=A%!co0% 18300!store3pos=A%!co1% 18310!store2pos=A%!co2% 18320CALL rotate 18330ENDPROC 18340: 18350DEF PROCrotate(thing%,AS%,BS%,D%,E%,F%) 18360AS%=thing%!AS%:BS%=thing%!BS% 18370LOCAL C%,CX,SX,CY,SY,CZ,SZ,X,Y,Z,T 18380D%=(D% AND &3FF)*4:CX=cos!D%/&400:SX=sin!D%/&400 18390E%=(E% AND &3FF)*4:CY=cos!E%/&400:SY=sin!E%/&400 18400F%=(F% AND &3FF)*4:CZ=cos!F%/&400:SZ=sin!F%/&400 18410FOR C%=0 TO thing%!nop%-1 18420 Z=!AS%:X=AS%!4:T=AS%!8 18430 Y=T*CX+Z*SX:Z=Z*CX-T*SX 18440 T=X*CY-Z*SY:Z=X*SY+Z*CY 18450 X=T*CZ-Y*SZ:Y=T*SZ+Y*CZ 18460 BS%!0=Z:BS%!4=X:BS%!8=Y 18470 AS%+=12:BS%+=12 18480NEXT 18490ENDPROC 18500: 18510DEF PROCtranslate(thing%,AS%,BS%,D%,E%,F%) 18520LOCAL C% 18530AS%=thing%!AS%:BS%=thing%!BS% 18540FOR C%=0 TO thing%!nop%-1 18550 BS%!0=AS%!0-F%:BS%!4=AS%!4+D%:BS%!8=AS%!8+E% 18560 AS%+=12:BS%+=12 18570NEXT 18580ENDPROC 18590: 18600DEF FNdefine_facet(A%,C%,D%,E%,F%) 18610IF C%=D% OR D%=E% OR E%=C% THEN =A% 18620IF A%<TOP THEN ERROR 1,"bad pointer passed to define_facet" 18630IF wind%>0 SWAP C%,E% 18640!A%=C%:A%!4=D%:A%!8=E%:A%!12=0:A%!16=0 18650A%?17=objects%-1 18660A%?19=&20 18670IF wind%=0 A%?19=A%?19 OR &40 18680IF (F% AND 1) A%?19=A%?19 OR &10 18690IF (F% AND 2) A%?19=A%?19 OR &80 18700faco%+=1 18710=A%+elsiz%(3) 18720: 18730DEF PROCcalcavZ(A%,B%) 18740LOCAL C%,D%,E% 18750C%=A%!fac%:D%=A%!B%:E%=A%!nof%-1 18760CALL avZ:ENDPROC 18770: 18780DEF PROCfudge(A%) 18790LOCAL C%,D%,E%,I% 18800C%=A%!fac%:D%=A%!nof%-1 18810FOR I%=0 TO D% 18820 C%!12-=200:C%+=elsiz%(3) 18830NEXT 18840ENDPROC 18850: 18860DEF PROChidefaces(A%) 18870LOCAL C%,D%,E% 18880C%=A%!fac%:D%=A%!co2%:E%=A%!nof%-1 18890CALL hidefaces 18900ENDPROC 18910: 18920DEF PROCZsort 18930LOCAL D%,F%,G% 18940D%=facpt%:F%=0:G%=totnof%-1 18950CALL qfsort:ENDPROC 18960: 18970DEF PROCrender(skip%,S%) 18980LOCAL AS%,BS%,CS%,DS%,I%,A%,B%,C% 18990AS%=facpt% 19000IF S%>1 THEN 19010 FOR I%=0 TO objects%-1 19020 thing%=world%+I%*elsiz%(7) 19030 PROCcalcavZ(thing%,co1%) 19040 IF thing%!vel%=0 PROCfudge(thing%) 19050 PROChidefaces(thing%) 19060 NEXT 19070 PROCZsort 19080ENDIF 19090CASE S% OF 19100WHEN 0: 19110FOR I%=0 TO totnof%-1 19120 CS%=AS%!(I%*4):thing%=world%+elsiz%(7)*CS%?17:BS%=thing%!co2% 19130 IF SGN(thing%!vel%)<>skip% THEN 19140 A%=BS%+8*!CS%:B%=BS%+8*CS%!4:C%=BS%+8*CS%!8 19150 POINT !A%,A%!4:POINT !B%,B%!4:POINT !C%,C%!4 19160 ENDIF 19170NEXT 19180WHEN 1: 19190FOR I%=0 TO totnof%-1 19200 CS%=AS%!(I%*4):thing%=world%+elsiz%(7)*CS%?17:BS%=thing%!co2% 19210 IF (CS%?19 AND &10)=0 AND SGN(thing%!vel%)<>skip% THEN 19220 A%=BS%+8*!CS%:B%=BS%+8*CS%!4:C%=BS%+8*CS%!8 19230 MOVE !A%,A%!4:DRAW !B%,B%!4:DRAW !C%,C%!4 19240 IF CS%?19 AND &80 THEN DRAW !A%,A%!4 19250 ENDIF 19260NEXT 19270WHEN 2: 19280FOR I%=0 TO totnof%-1 19290 CS%=AS%!(I%*4):thing%=world%+elsiz%(7)*CS%?17:BS%=thing%!co2% 19300 IF CS%?19 AND &60 AND SGN(thing%!vel%)<>skip% THEN 19310 A%=BS%+8*!CS%:B%=BS%+8*CS%!4:C%=BS%+8*CS%!8 19320 MOVE !A%,A%!4:MOVE !B%,B%!4:PLOT 87,!C%,C%!4 19330 PLOT 65,0,0:POINT !A%,A%!4:POINT !B%,B%!4 19340 ENDIF 19350NEXT 19360WHEN 3: 19370FOR I%=0 TO totnof%-1 19380 CS%=AS%!(I%*4):thing%=world%+elsiz%(7)*CS%?17:BS%=thing%!co2% 19390 IF (CS%?19 AND &60)<>0 AND SGN(thing%!vel%)<>skip% THEN 19400 A%=BS%+8*!CS%:B%=BS%+8*CS%!4:C%=BS%+8*CS%!8 19410 MOVE !A%,A%!4:MOVE !B%,B%!4:PLOT 87,!C%,C%!4 19420 DRAW !B%,B%!4:DRAW !A%,A%!4 19430 IF CS%?19 AND &80 DRAW !C%,C%!4 19440 ENDIF 19450NEXT 19460ENDCASE 19470ENDPROC
� ><FEMS$dir>.FEMS2�3 )� Finite Element Materials Simulation /� with development version of OO3D routines ('� version 2.1: restyling of objects 2� 2.11 cylinder definition <%� 2.12 nearest neigbours bonding F%� 2.13 generalised frame storage P � 2.14 backgrounds built in Z,� 2.15 backgrounds Z-mixed with objects d.� 2.16 mixed backgrounds, replay, preview n� 2.17 2 colour RLE x � 2.17b flat shading removed �'� 2.18 read scene definition files �>� 2.19 cuboid definition, compound objects (cuboids only) �"� 2.20 any object in compound �C� 2.21 PROCoutput_facets, PROCframe_actions, anims inside sims �8� 2.211 const. sep. sphere (background & foreground) �-� units for angles, velocities etc. �� solid_sphere �� 2.212 spin command �� local damping �"� 2.213 rotating frame damping �� repelling objects �� 2.214 frozen objects �� proper air damping � 2.215 cuboid surface fixed "� variable solid damping %� force parameter for repel "C� 2.216 repel largely machine coded (outer point loop in BASIC) ,*� 2.217 multiple and box-bounded pulls 6&� 2.218 units for angular velocity @*� + hourglass during repel preprop J T ch%=0 ^anim%=� h� � �error r |� 0 �ș "OS_GetEnv" � env$ �i%=�env$,"-file ") �� i%=0 � � file$="^.sims.ChairStair" �� � file$=�env$,i%+6) � i%=�file$," ") � � i% � file$=�file$,i%-1) �� �.ș "OS_File",5,file$ � ot%,,type%,,length% �1� ot%<>1 � � 1,"File """+file$+""" not found" �type%=(type%>>8) � &FFF � Ȏ type% � � &FFF: �init & �read_script(file$) 0 �init2 : �create_frames D �saveit N � &3C7: X �load(file$,length%) b �init_replay l :� 1,"File wrong type" v� ��display_frames �� �: �� �init � �init3OOD �� scrap% 256*4 �� sin 2048*4:cos=sin+256*4 ��'"Filling sine array..."; �2� A%=0 � 1023:sin!(A%*4)=&400*�(A%*�/512)+.5:� �0� A%=0 � 1023:sin!((A%+1024)*4)=sin!(A%*4):� �� per% &801*4 �%�'"Filling perspective array..."; �0� N%=0 � &800:per%!(N%*4)=&600/(1+N%/&400):� � ptp%(3),szp%(3) maxobjs%=8 world%=�create(7,maxobjs%) � bgdef%(maxobjs%,6) *� pull% 12*64:pulls%=0 4inch%=&B400 >�assem_nebo H� R: \� �defaults fxres%=320:yres%=256 p ren%=2 z fsp%=1 � rstyle%=0 �aim%=600 �VA%=700:VB%=912 �stostyle%=0 �$grav_x%=0:grav_y%=0:grav_z%=-600 � dampsh%=2 �mode%=4 �� �: �� �read_script(file$) �� �ch%=�(file$) �.� ch%=0 � � 1,"Could not open script file" P� �line<>"fems2" � �rse("Script file invalid: did not start with ""FEMS2""") �defaults 'solids%=0:backgrounds%=0:objects%=0 $� . c$=�line 8 Ȏ c$ � B6 � "rendering":�get_openbrack(c$):�read_rendering L> � "solid":�get_openbrack(c$):solids%+=1:�read_object(-1) VG � "background":�get_openbrack(c$):backgrounds%+=1:�read_object(0) `) � "frame_aim":aim%=�get_num(c$,1,1) j( � "time_div":fsp%=�get_num(c$,1,1) t\ � "gravity":grav_x%=�get_num(c$,3,2):grav_y%=�get_num(c$,3,2):grav_z%=�get_num(c$,3,2) ~ � "" � �not_rec � � �� �#ch% ��#ch%:ch%=0 �)� solids%<1 � � 1,"No solids defined" �3� backgrounds%<1 � � 1,"No backgrounds defined" �� �: �� �read_rendering �� � c$=�line � Ȏ c$ � H � "type":rstyle%=�select(c$,�line,"all_dots,wireframe,dots,lines") B � "resolution":xres%=�get_num(c$,2,1):yres%=�get_num(c$,2,1) 8 � "background":ren%=2*�select(c$,�line,"back,mix") , � "view":VB%=(�get_num(c$,2,3)) � &3FF (( VA%=(768-�get_num(c$,2,3)) � &3FF 2 � "}","" < �not_rec F � P� �#ch% � c$="}" Zmode%=2 dȎ rstyle% � n � 0,2:stostyle%=0 x � 1,3:stostyle%=0 � � 4:stostyle%=-1:mode%=16 �� �"mode%=�mode(xres%,yres%,mode%) �3� mode%<0 �rse("No suitable screen mode found") �� �: �� �read_object(sol%) �� otype%,c$,Q%,i% �otype%=-2:thing%=0 �#� sol%=0 Q%=backgrounds% � Q%=0 � com_stage%=0:faco%=0:poco%=0 �� � c$=�line Ȏ c$ � : � "create":�read_create(sol%,Q%):bgdef%(Q%,0)=otype% � "translate":�need_create "B x%=�get_num(c$,3,4):y%=�get_num(c$,3,4):z%=�get_num(c$,3,4) ,, �translate(thing%,co0%,co0%,x%,y%,z%) 66 bgdef%(Q%,1)=x%:bgdef%(Q%,2)=y%:bgdef%(Q%,3)=z% @F � "rotate":� sol%=0 �rse("background objects cannot be rotated") J` �need_create:�rotate(thing%,co0%,co0%,�get_num(c$,3,3),�get_num(c$,3,3),�get_num(c$,3,3)) T) � "nearbonds":�read_nearbonds(sol%) ^! � "repel":�read_repel(sol%) h; � "damping":�need_create:thing%!odm%=�get_num(c$,1,1) r< � "air_damp":�need_create:thing%!adm%=�get_num(c$,1,1) |# �flag_surface_points(thing%) �> � "solid_damp":�need_create:thing%!rdm%=�get_num(c$,1,2) �^ � "velocity":�need_create:� sol%=0 �rse("background objects cannot be given a velocity") �O �set_velocity(thing%,�get_num(c$,3,5),�get_num(c$,3,5),�get_num(c$,3,5)) �N � "spin":�need_create:� sol%=0 �rse("background objects cannot be spun") �K �set_spin(thing%,�get_num(c$,3,6),�get_num(c$,3,6),�get_num(c$,3,6)) �Z � "scale":�need_create:� sol%=0 �rse("scale not implemented for background objects") �O �scale_object(thing%,�get_num(c$,3,2),�get_num(c$,3,2),�get_num(c$,3,2)) �! � "pull":�read_pull(thing%) �' � "fix_vel":�read_fix_vel(thing%) � � "}","" � �not_rec � � �� �#ch% � c$="}" 9� poco%>thing%!nop% � �rse("too many points created") thing%!nop%=poco% 9� faco%>thing%!nof% � �rse("too many facets created") &thing%!nof%=faco% 0thing%!sep%=szp%(0) :� D: N� �read_pull(thing%) X8� sol%=0 �rse("background objects cannot be pulled") b� f%,l%,s%,B%,C% l?f%=�get_num(c$,6,1):l%=�get_num(c$,6,1):s%=�get_num(c$,6,1) vC� s%<=0 � �rse("the pull point step must be greater than zero") �HC%=�fixed_vel_no(�get_num(c$,6,5),�get_num(c$,6,5),�get_num(c$,6,5)) �(� l%>=thing%!nop% � l%=thing%!nop%-1 �B%=�point_flags(thing%) �ȕ f%>=0 � f%<=l% � B%?f%=(B%?f% � 3) � (C%<<2) � f%+=s% �� �� �: �� �read_fix_vel(thing%) ��need_create �8� sol%=0 �rse("background objects cannot be pulled") �0� a%,b%,c%,x%,y%,z%,ex%,ey%,ez%,A%,B%,C%,cp% ?x%=�get_num(c$,9,4):y%=�get_num(c$,9,4):z%=�get_num(c$,9,4) Bex%=�get_num(c$,9,4):ey%=�get_num(c$,9,4):ez%=�get_num(c$,9,4) HC%=�fixed_vel_no(�get_num(c$,6,5),�get_num(c$,6,5),�get_num(c$,6,5)) B%=�point_flags(thing%) *ex%+=x%:� ex%<x% Ȕ x%,ex% 4ey%+=y%:� ey%<y% Ȕ y%,ey% >ez%+=z%:� ez%<z% Ȕ z%,ez% Hcp%=thing%!co0% R� A%=0 � thing%!nop%-1 \ c%=-!cp%:a%=cp%!4:b%=cp%!8 f[ � a%>=x% � a%<=ex% � b%>=y% � b%<=ey% � c%>=z% � c%<=ez% � B%?A%=(B%?A% � 3) � (C%<<2) p cp%+=12 z� �� �: �� �fixed_vel_no(x%,y%,z%) �� C%,P% �C%=1:P%+=pull%+12 �4ȕ C%<=pulls% � (!P%<>-z% � P%!4<>x% � P%!8<>y%) � C%+=1:P%+=12 �� �� C%<=pulls% � =C% �H� pulls%=63 � �rse("You can only have 63 different pull velocities") �!P%=-z%:P%!4=x%:P%!8=y% �pulls%+=1:=pulls% �: � �point_flags(thing%) "� thing%!ptf%>0 � =thing%!ptf% � A%,B% $&thing%!ptf%=�create(8,thing%!pts%) .B%=thing%!ptf% 8$� A%=0 � thing%!nop%-1:B%?A%=0:� B=B% L: V"� �flag_surface_points(thing%) `� A%,B%,C% jB%=�point_flags(thing%) tC%=thing%!fac% ~� A%=0 � thing%!nof%-1 � B%?(C%!0)=B%?(C%!0) � 1 � B%?(C%!4)=B%?(C%!4) � 1 � B%?(C%!8)=B%?(C%!8) � 1 � C%+=elsiz%(3) �� �� �: �� �read_repel(sol%) �D� sol%=0 � �rse("repel is not applicable to background objects") ��need_create � thing%!rep%=�get_num(c$,1,1) �� thing%!rep%=0 � � � A%,B%,C%,D%,nd%,cl% ș "Hourglass_On" �flag_surface_points(thing%) (B%=�point_flags(thing%) 2C%=thing%!co0% <� i%=0 � thing%!nop%-1 F1 ș "Hourglass_Percentage",100*i%/thing%!nop% P � (B%?i% � 3)=1 � Z0 cl%=-1:nd%=(2*szp%(0)>>7)^2:D%=thing%!co0% d � j%=0 � thing%!nop%-1 nf � (B%?j% � 3)<>1 � A%=(!C%-!D%>>7)^2+(C%!4-D%!4>>7)^2+(C%!8-D%!8>>7)^2:� A%<nd% � nd%=A%:cl%=j% x D%+=12 � � �, � cl%>=0 � B%?cl%=(B%?cl% � 2) � (� 1) � � � C%+=12 �� �ș "Hourglass_Off" �� �: �� �read_nearbonds(sol%) �H� sol%=0 � �rse("nearbonds is not applicable to background objects") ��get_openbrack(c$) ��need_create �� c$,lambda%,R lambda%=30:R=2.5 � c$=�line " Ȏ c$ � ,/ � "spring_const":lambda%=�get_num(c$,1,1) 6" � "range":R=�get_num(c$,1,2) @ � "}","" J �not_rec T � ^� �#ch% � c$="}" h+� c%,ls%,ms%,E%,F%,C%,A%,B%,G%,H%,s%,D% rls%=szp%(0):ms%=R*ls% |c%=lambda%*fsp%*ls% �!s%=0:ȕ (ms%>>s%)>255:s%+=1:� �%ms%=ms%>>s%:c%=c%>>s%:ls%=ls%>>s% �!scrap%=1<<s% �?B%=�(c%/ls%)<<24:� C%=1 � ls%:scrap%!(C%*4)=(C%<<s%) � B%:� �>� C%=ls%+1 � ms%:scrap%!(C%*4)=(C%<<s%) � (�(c%/C%)<<24):� �!neboblock=scrap% �neboblock!4=ms%*ms% �neboblock!12=s% �neboblock!16=(.5*ls%)^2 �!H%=thing%!co0%:E%=thing%!pts% �B%=�(nearcount) �thing%!nob%=B% �thing%!bnd%=�create(6,B%) neboblock!8=thing%!bnd% D%=thing%!bnd%+8*thing%!nob% � nearbond &B%=neboblock!8 0� B%>D% � � :"thing%!nob%=(B%-thing%!bnd%)/8 D� N: X� �read_create(sol%,Q%) b�get_openbrack(c$) l7� �line<>"type" � �rse("create needs a type first") v� c$,o$,offx%,offy%,offz% �offx%=0:offy%=0:offz%=0 �o$=�line �Xotype%=�select(c$,o$,"compound,sheet,cube,tube,sphere,stairs,cuboid,solid_sphere")-1 �Ȏ otype% � � � 0,1,3:nptp%=1:nszp%=1 � � 2,4,5:nptp%=3:nszp%=3 � � 6:nptp%=2:nszp%=1 �" � -1:�read_compound:otype%=-1 �� �� otype%<0 � � �� � c$=�line � Ȏ c$ � F � "points":� i%=1 � nptp%:ptp%(i%)=�get_num(o$+" "+c$,nptp%,1):� ] � "size":� i%=1 � nszp%:szp%(i%)=�get_num(o$+" "+c$,nszp%,4):bgdef%(Q%,i%+3)=szp%(i%):� U � "offset":offx%=�get_num(c$,3,4):offy%=�get_num(c$,3,4):offz%=�get_num(c$,3,4) � "}","" * �not_rec 4 � >� �#ch% � c$="}" H� �("FNcreate_"+o$) R� \: f� �read_compound p� P%,c$ z<� com_stage%>0 �rse("Compound objects cannot be nested") �com_nop%=0:com_nof%=0 �P%=�#ch% �� com_stage%=1 � 2 �4 �'"** compound object - pass ";com_stage%;" **" � �#ch%=P% �l � com_stage%=2 � com_stage%=0:com_thing%=�create_object(com_nop%,com_nof%):com_stage%=2:faco%=0:poco%=0 � � � c$=�line � Ȏ c$ � �" � "part":�read_create(-1,0) � � "}": �+ :�rse("Expected ""part"" or ""}""") � � � c$="}" � com_stage%=0 $#�set_velocity(com_thing%,0,0,0) .� 8: B� �blurb L*� i%,j%,k%,B%,C%,D%,E%,F%,x%,y%,z%,nd% Vnd%=(.5*szp%(0)>>7)^2 `B%=�point_flags(thing%) jC%=thing%!co0% tD%=thing%!fac% ~E%=�fixed_vel_no(0,0,0) �F%=0 �� i%=0 � poco%-2 �" � C%!(i%*12)>F% F%=C%!(i%*12) �� �F%+=100*&B400 �ș "Hourglass_On" �� i%=0 � poco%-2 �/ ș "Hourglass_Percentage",100*i%/(poco%-2) �2 x%=C%!(i%*12):y%=C%!(i%*12+4):z%=C%!(i%*12+8) � � j%=i%+1 � poco%-1 � � B%?j%=0 � �Q � (x%-C%!(j%*12)>>7)^2+(y%-C%!(j%*12+4)>>7)^2+(z%-C%!(j%*12+8)>>7)^2<=nd% � � i%,j%,B%?i%,B%?j% F x%=x%+C%!(j%*12)>>1:y%=y%+C%!(j%*12+4)>>1:z%=z%+C%!(j%*12+8)>>1 B%?j%=E% 2 C%!(j%*12)=F%:C%!(j%*12+4)=0:C%!(j%*12+8)=0 ( D%=thing%!fac% 2 � k%=0 � faco%-1 < � D%!0=j% D%!0=i% F � D%!4=j% D%!4=i% P � D%!8=j% D%!8=i% Z D%+=elsiz%(3) d � n � x � � � �2 C%!(i%*12)=x%:C%!(i%*12+4)=y%:C%!(i%*12+8)=z% �� �ș "Hourglass_Off" �� �: �� �need_create �N� otype%=-2 � �rse("You need to create the object before you can do this") �� �: �$� �set_velocity(thing%,x%,y%,z%) �� com_stage%<>0 � � �� P%,A% P%=thing%!vel%:� P%=0 � � A%=0 � thing%!nop%-1 $ P%!0=-z%:P%!4=x%:P%!8=y%:P%+=12 "� ,� 6: @ � �set_spin(thing%,wx,wy,wz) J� com_stage%<>0 � � T� P%,Q%,A% ^wx=wx*�/25600 hwy=wy*�/25600 rwz=wz*�/25600 |P%=thing%!vel%:� P%=0 � �Q%=thing%!co0%:� Q%=0 � �� A%=0 � thing%!nop%-1 � P%!0-=wy*(Q%!4)-wx*(Q%!8) � P%!4+=wz*(Q%!8)+wy*(Q%!0) � P%!8-=wx*(Q%!0)+wz*(Q%!4) � P%+=12:Q%+=12 �� �� �: �!� �scale_object(thing%,X,Y,Z) �� P%,A% �$� sol% szp%(0)=szp%(0)*(X+Y+Z)/3 �P%=thing%!co0%:� P%=0 � � A%=0 � thing%!nop%-1 / P%!0=P%!0*Z:P%!4=P%!4*X:P%!8=P%!8*Y:P%+=12 � &� 0: :� �create_sheet D� co%,A%,N% N%N%=ptp%(1):szp%(0)=szp%(1)/(N%-1) X*thing%=�create_object(N%^2,2*(N%-1)^2) b� thing%=0 � =0 loffx%-=.5*szp%(1) voffy%-=.5*szp%(1) �co%=thing%!co0%+poco%*12 �� A%=0 � thing%!nop%-1 � co%!0=-offz% �" co%!4=szp%(0)*(A% � N%)+offx% �" co%!8=szp%(0)*(A% � N%)+offy% � co%+=12 �� �G� �surface(thing%,thing%!fac%+faco%*elsiz%(3),poco%,1,N%,N%,N%,0,0) �poco%+=thing%!nop% ��set_velocity(thing%,0,0,0) �=0 �: �� �create_sphere ptp%(2)=1 =�create_solid_sphere : � �create_solid_sphere *>� A%,B%,C%,E%,N%,Q%,S%,W%,Z%,NR%,NP%,OB%,OS%,OQ%,wind%,co% 4NR%=ptp%(1) >$R%=szp%(1):szp%(0)=�*szp%(1)/NR% HA%=(R%/szp%(0))-.9 R� ptp%(2)>A% ptp%(2)=A% \� ptp%(2)<1 ptp%(2)=1 f#NP%=�CSS_points(NR%):B%=NP%*2-4 p� ptp%(2)>1 � z � A%=1 � ptp%(2)-1 �1 NP%+=�CSS_points(NR%*(R%-A%*szp%(0))/R%+.5) � � �� �!thing%=�create_object(NP%,B%) �� thing%=0 � =0 �co%=thing%!co0%+poco%*12 �� S%=0 � ptp%(2)-1 � NR%=ptp%(1)*R%/szp%(1)-.5 � � A%=0 � NR% �! B%=.5+2*(NR%+1)*�(�*A%/NR%) � W%=R%*�(�*A%/NR%) � Z%=R%*�(�*A%/NR%)+offz% � � C%=0 � B%-1 � B%<1 � co%!4=0:co%!8=0 � $# co%!4=W%*�(2*�*C%/B%)+offx% .# co%!8=W%*�(2*�*C%/B%)+offy% 8 � B co%!0=-Z% L co%+=12 V � ` � j R%-=szp%(0) t% � S%=0 E%=(co%-thing%!co0%)/12-1 ~� � �wind%=1 �NR%=ptp%(1)-1 �#FP%=thing%!fac%+faco%*elsiz%(3) � B%=1:N%=1 �� A%=1 � ((NR%+1) � 2) � OS%=N%-B%:OB%=B% � B%=.5+2*(NR%+1)*�(�*A%/NR%) � Q%=OS% � � C%=0 � B%-1 � OQ%=Q% �/ � A%=1 Q%=0 � Q%=OS%+((C%*OB%/B%+1)� OB%) + �CSS_fac(N%+C%,N%+((C%+1)� B%),Q%,A%) + � OQ%<>Q% � �CSS_fac(N%+C%,Q%,OQ%,A%) � N%+=B% (� 2poco%+=NP% <�set_velocity(thing%,0,0,0) F=0 P: Z� �CSS_fac(D%,B%,C%,A%) d7FP%=�define_facet(FP%,C%+poco%,B%+poco%,D%+poco%,3) n;� A%*2<NR%+1 FP%=�define_facet(FP%,E%-C%,E%-B%,E%-D%,3) x� �: �� �CSS_points(NR%) �� A%,N% �NR%-=1:N%=2 �� A%=0 � NR% �! N%+=.5+2*(NR%+1)*�(�*A%/NR%) �� �=N% �: �� �create_cube �#ptp%(2)=ptp%(1):ptp%(3)=ptp%(1) �#szp%(2)=szp%(1):szp%(3)=szp%(1) �I� com_stage%<>1 offx%-=.5*szp%(1):offy%-=.5*szp%(1):offz%-=.5*szp%(1) =�create_cuboid : � �create_tube "&� A%,C%,D%,co%,A,R%,N1%,N2%,N3%,AS ,'N1%=ptp%(1):N2%=ptp%(2):N3%=ptp%(3) 68thing%=�create_object(N1%*N2%*N3%,4*N2%*(N1%+N3%-2)) @� thing%=0 � =0 Joffz%-=szp%(1)/2 Tszp%(1)=szp%(1)/(N1%-1) ^szp%(3)=szp%(3)/(N3%-1) hAS=2*�/N2% r*szp%(0)=(szp%(1)+szp%(2)*AS+szp%(3))/3 |co%=thing%!co0%+poco%*12 �� A%=0 � thing%!nop%-1 � A=(A% � N2%)*AS �5 R%=szp%(2)+szp%(3)*((A% � (N2%*N1%))-(N3%-1)*.5) �, co%!0=-szp%(1)*((A% � N2%) � N1%)-offz% � co%!4=R%*�(A)+offx% � co%!8=R%*�(A)+offy% � co%+=12 �� �LC%=�surface(thing%,thing%!fac%+faco%*elsiz%(3),poco%,1,N2%,N2%,N1%,-1,1) �BC%=�surface(thing%,C%,poco%+N2%*N1%*(N3%-1),1,N2%,N2%,N1%,1,1) �6C%=�surface(thing%,C%,poco%,1,N2%*N1%,N2%,N3%,1,1) �CC%=�surface(thing%,C%,poco%+N2%*(N1%-1),1,N2%*N1%,N2%,N3%,-1,1) �poco%+=thing%!nop% �set_velocity(thing%,0,0,0) =0 : &� �create_stairs 0!� co%,A%,Y%,X%,Z%,N1%,N2%,N3% :'N1%=ptp%(1):N2%=ptp%(2):N3%=ptp%(3) D<thing%=�create_object(N1%*N2%*N3%,2*(N1%-1)*(N2%*N3%-1)) N� thing%=0 � =0 Xszp%(1)=szp%(1)/(N1%-1) bszp%(3)=szp%(3)/(N3%-1) lco%=thing%!co0%+poco%*12 voffx%=-.5*(N1%-1)*szp%(1) �� A%=0 � N1%*N2%*N3%-1 � X%=A% � N1%:Z%=A% � N1% � Y%=Z% � N3%:Z%=Z% � N3% � co%!0=-Z%*szp%(2)-offz% � co%!4=X%*szp%(1)+offx% �( co%!8=(Y%+Z%*(N3%-1))*szp%(3)+offy% � co%+=12 �� �OY%=�surface(thing%,thing%!fac%+faco%*elsiz%(3),poco%,1,N1%,N1%,N2%*N3%,0,0) �poco%+=thing%!nop% ��set_velocity(thing%,0,0,0) �=0 �: � �create_cuboid 9� X%,Y%,Z%,A%,B%,C%,D%,E%,co%,N1%,N2%,N3%,S1%,S2%,S3% 'N1%=ptp%(1):N2%=ptp%(2):N3%=ptp%(3) *N1%-=(N1%=0):N2%-=(N2%=0):N3%-=(N3%=0) *Zthing%=�create_object(N1%*N2%*N3%,4*((N1%-1)*(N2%-1)+(N2%-1)*(N3%-1)+(N3%-1)*(N1%-1))) 4� thing%=0 � =0 >?S1%=szp%(1)/(N1%-1):S2%=szp%(2)/(N2%-1):S3%=szp%(3)/(N3%-1) Hszp%(0)=(S1%+S2%+S3%)/3 Rco%=thing%!co0%+poco%*12 \� A%=0 � thing%!nop%-1 f6 X%=A% � N1%:Y%=(A% � N1%) � N2%:Z%=A% � (N1%*N2%) p co%!0=-(S3%*Z%+offz%) z co%!4=S1%*X%+offx% � co%!8=S2%*Y%+offy% � co%+=12 �� �A%=poco%+N1%*N2%*(N3%-1) �"X%=thing%!fac%+faco%*elsiz%(3) �3C%=�surface(thing%,X%,poco%,1,N1%,N1%,N2%,-1,0) �3C%=�surface(thing%,C%,A% ,1,N1%,N1%,N2%, 1,0) �A%=poco%+N1%*(N2%-1) �7C%=�surface(thing%,C%,poco%,N1%*N2%,1,N3%,N1%,-1,0) �7C%=�surface(thing%,C%,A% ,N1%*N2%,1,N3%,N1%, 1,0) �A%=poco%+N1%-1 �9C%=�surface(thing%,C%,poco%,N1%,N1%*N2%,N2%,N3%,-1,0) �9C%=�surface(thing%,C%,A% ,N1%,N1%*N2%,N2%,N3%, 1,0) poco%+=N1%*N2%*N3% �set_velocity(thing%,0,0,0) =0 $: . � �create_object(pts%,facs%) 86� com_stage%=1 � com_nop%+=pts%:com_nof%+=facs%:=0 B� com_stage%=2 =com_thing% L=� objects%=maxobjs% � �rse("Max. no. of objects reached") V$thing%=world%+objects%*elsiz%(7) `objects%+=1 j.� sol% � flags%=%1011111 � flags%=%1010111 t*�initthing(thing%,pts%,facs%,0,flags%) ~=thing% �: �� �select(c$,o$,l$) �p%=�","+l$+",",","+o$+",") �-� p%=0 � �rse(c$+" should be one of "+l$) �l$=�l$,p%):p%=0:r%=-1 �#�:p%=�l$,",",p%+1):r%+=1:� p%=0 �=r% �: �� �get_openbrack(c$) �9� �line<>"{" � �rse("open backet expected after "+c$) �� �: � �get_num(c$,n%,t%) � t%=1 integer >=0 � t%=2 float � t%=3 angle (� t%=4 distance 2� t%=5 velocity <� t%=6 angular velocity F� A$,P%,B%,s%,V,M PA$=�line Z P%=0:� d P%+=1 n B%=�(�A$,P%,1)) x% � P%=1 � (B%=43 � B%=45) � B%=48 �� (B%<48 � B%>57) � B%<>46 �E� P%=1 � n%=1 � �rse("A numeric arguament is expected after "+c$) �C� P%=1 � �rse(�n%+" numeric arguaments are expected after "+c$) �Ȏ �A$,P%) � � � "":s%=t%:M=1 � � t%=3 � M=128/45 � � "deg":s%=3:M=128/45 � � "rad":s%=3:M=512/� � � "in":s%=4:M=&B400 � � "ft":s%=4:M=12*&B400 � � "cm":s%=4:M=18142 � � "mm":s%=4:M=1814.2 � � "ips":s%=5:M=&B400/50 � "ftps":s%=5:M=12*&B400/50 � "cmps":s%=5:M=18142/50 � "mmps":s%=5:M=1814.2/50 "! � "degps":s%=6:M=128/(45*50) , � "radps":s%=6:M=512/(�*50) 6 � "rpm":s%=6:M=1024/3000 @& �rse("Unknown units used here") J� T4� s%<>t% � �rse("Inappropriate units used here") ^V=�(�A$,P%-1)) hI� t%=1 � � V<0 � V<>�(V) � �rse("Non-negative integer expected here") r=V*M |: �� �rse(A$) ��#ch%:ch%=0 ��'A$ �� �: �J� �not_rec:�rse("command """+c$+""" not recognised in this context"):� �: �� �line �� A$,B%,C%,R% �R%=0:A$="":B%=0 �� �% C%=B%:� �#ch% � B%=-1 � B%=�#ch% �7 � B%>31 � � B% � � (B%=13 � B%=10) � C%<>23-B% � � � B%>64 � B%<91 � B%+=32 / � R%=0 � B%>33 � B%<>58 � B%<>44 � A$+=�B% � B%=42 � C%=47 � R%+=1 &\ � B%=47 � C%=42 � R%-=1:A$=�A$,�A$-2):� R%<0 � �rse("More remarks closed than opened!") 06� B%<0 � ((B%<33 � B%=58 � B%=44) � R%=0 � A$<>"") :=A$ D: N� �init2 X b maxpts%=0 l� i%=0 � objects%-1 v thing%=world%+i%*elsiz%(7) �B � thing%!vel%>0 � � thing%!nop%>maxpts% � maxpts%=thing%!nop% �� �� vel2% maxpts%*12 � �%tsh%=�(fsp%)/�(2)+.5:fsp%=1<<tsh% �grav_x%=grav_x%>>(tsh%*2) �grav_y%=grav_y%>>(tsh%*2) �grav_z%=grav_z%>>(tsh%*2) �dampsh%+=tsh%*2 � �T%=1<<30 �� recip% 4100 �"�"Filling reciprocal table..." *� A%=1 � 1023:recip%!(A%*4)=T%/A%+.5:� !recip%=&7FFFFFFF �assem * �assemstore(mode%,stostyle%) 4 >'�'"Creating pointers to facets..."; H totnof%=0 R� i%=0 � objects%-1 \ thing%=world%+i%*elsiz%(7) f totnof%+=thing%!nof% p� z"facpt%=�create(4,totnof%):C%=0 �� i%=0 � objects%-1 � thing%=world%+i%*elsiz%(7) �9 C%=�init_facpoint(thing%!fac%,facpt%,thing%!nof%,C%) �� � �!�'"Making animation area..."; �� E% -1 �%storend%=(�(basic_stack)-E%)-4000 �� store% storend% �storend%=store%+storend% �store%+=16 �!storend=storend%-1 � � timblk% 8,stri% 256 �init_screen � $: .� �init_screen 8� Iblock% 16 B� mode% � 128 L=� �<>mode% � � 1,"Could not obtain requested screen mode" V� `� �ModeVar(3),255,255,255 j *FX 112 1 t� ~ *FX 112 2 �� � *FX 113 1 �+!Iblock%=149:Iblock%!4=148:Iblock%!8=-1 �,ș "OS_ReadVduVariables",Iblock%,scrpos1 �!scrpos=!scrpos2 � *fx 113 2 �� �: �� �create_frames �store%!-16=216 �"store%!-12=(xres%<<16) � yres% �store%!-8=0 store%!-4=stostyle%+1 startime%=� � i%=0 � objects%-1 . �rotnpersp(world%+i%*elsiz%(7),VA%,VB%,0) (� 2ȗ � 1250,970 <�:�render(ren%,rstyle%) F�:�render(1,rstyle%) P=!storepos=store%:�storeframe(stostyle%):store1%=!storepos ZB� store1%=0 � � 1,"Not enough space to store background frame" d nquit%=� xgentime%=0 �� � startime%=� � � j%=1 � fsp% � � i%=0 � objects%-1 �$ �move(i%,world%+i%*elsiz%(7)) � � � � � movetime%=� � � i%=0 � objects%-1 �/ �rotnpersp(world%+i%*elsiz%(7),VA%,VB%,0) � � � � � laststore%=!storepos � ren%=0 C%=store%:� show �render(ren%,rstyle%) C%=store%:� show " �storeframe(stostyle%) , C%=store%:� show 6 anim%=� @" �frame_actions(!(store%-8)-1) J$ nk%=0:�:k%=nk%:nk%=�(0):� nk%<0 T k%+=32*(k%>97 � k%<123) ^ � k%=80 � �preview h � k%=81 � quit%=� r� quit% |� ��"You can let go now" �� � � �(-17) �� 11:� �(20) �*fx 21 0 �|ș "OS_PrettyPrint",�13+"From now on you can press Escape and type PROCsave(""filename"") to save the animation."+�13+�0 �� �: �� �frame_actions(frame%) �<� IF frame%=30 THEN PROCoutput_facets("$.Temp.facets30") �U� IF INKEY(-3) THEN OSCLI("Screensave <FEMS$Dir>.^.shots.pic"+STR$(frame%)):VDU 7 ��status(frame%) �� frame%=aim% � � � "Paused...":� 7 *fx 21 0 � � � 11:� �(10) &� 0 � :: D� �output_facets(f$) N� cp%,fp%,j%,ch%,T% X ch%=�(f$) b� i%=0 � objects%-1 l thing%=world%+elsiz%(7)*i% v cp%=thing%!co0% � fp%=thing%!fac% � T%=1:�#ch%,T% � �#ch%,thing%!nof% � � j%=0 � thing%!nof%-1 �* T%=cp%+12*fp%!0:�#ch%,T%!4,T%!8,-!T% �* T%=cp%+12*fp%!4:�#ch%,T%!4,T%!8,-!T% �* T%=cp%+12*fp%!8:�#ch%,T%!4,T%!8,-!T% � fp%+=elsiz%(3) � � �� � �#ch% �� �: !� �preview !� C% ! *FX 112 1 ! � !* *FX 113 1 !4bank%=1 !>� !H �show !R �pause(100) !\� � �(-56) !f *FX 112 2 !p� !z *FX 113 2 !�!scrpos=!scrpos2 !�C%=store%:� show !�C%=laststore%:� show !�*fx 21 0 !�� !�: !�� �pause(T%) !�T%=T%+� !�� � �>T% !�� !�: !�� �display_frames !� *FX 112 1 "� " *FX 113 1 "!scrpos=!scrpos2 "$C%=store%:store1%=�(show) ".bank%=1 "8 �show "B� "L *FX 15 "V G%=� "` � G%=32 � "j � "t �show "~ *FX 15 "� G%=�(100) "� � G%>-1 "� � "� �show "� � "�� � "�� "�: "�� �show "�� C%,A% "�A%=store1% "�� F%=1 � !(store%-8)-1 # bank%=bank% � 3 # !scrpos=scrpos!(bank%*4) # ș "OS_Byte",112,bank% # � #( C%=store%:� show #2 C%=A%:A%=�(show) #<% � �(-2) � �pause(10):� � � �(-1) #F Ȗ:ș "OS_Byte",113,bank% #P� #Z� #d: #n� �storeframe(S%) #xȎ S% � #� � -1:!storepos+=4 #� � 0:� frstore #� � 1:� frstore #�$ � 2:!storepos+=4:!(store%-8)+=1 #�* � 1234,"Frame store type not known" #�� #�,� !storepos=0 � quit%=� � !(store%-8)+=1 #�� #�: #�� �mode(xres%,yres%,cols%) #�� mode%,best%,lc%,nc%,E% #�lc%=256:best%=-1 #�� mode%=0 � 127 $1 ș "XOS_ReadModeVariable",mode%,3 � ,,nc%;E% $, � (E% � 1)=0 � nc%+1>=cols% � nc%<lc% � $I � �ModeVar(11)+1=xres% � �ModeVar(12)+1=yres% � best%=mode%:lc%=nc% $" � $,� $6 =best% $@: $J � �saveit $Tdir$=file$ $^2ȕ �file$,".")>0:file$=�file$,�file$,".")+1):� $h'dir$=�dir$,�dir$-�file$-1)+".anims" $rș "OS_File",5,dir$ � ot% $|d� ot%<>1 � ș "OS_PrettyPrint",�13+"Press S now to save the animation as "+dir$+"."+file$+�13+�0 $�*fx 21 0 $�k$=� $�� ot%=1 � k$="x" $�� k$="S" � k$="s" � $�" � ot%=0 � ș "OS_File",8,dir$ $� �save(dir$+"."+file$) $�� $�� $�: $�� �save(file$) $�� E%,F% $�.� !storepos=0 � E%=storend% � E%=!storepos $�F%=store%-16 %%ș "OS_File",&A,file$,&3C7,,F%,E% %� %: %&� �load(file$,length%) %0� store% length% %:�"Loading animation..."; %D#ș "OS_File",&10,file$,store%,0 %Nstore%+=16 %Xanim%=� %b� %l: %v� �init_replay %�4� store%!-16<>216 � � 1,"File version not known" %�xres%=store%!-12 %�(yres%=xres% � &FFFF:xres%=xres%>>>16 %�stostyle%=(store%!-4)-1 %�@� stostyle%<>0 � stostyle%<>1 � � 1,"Storage type not known" %�mode%=�mode(xres%,yres%,2) %�1� mode%<0 � 1,"No suitable screen mode found" %� �assemstore(mode%,stostyle%) %��init_screen %�� %�: %�� �repel_points(t1%,t2%) %�8� i%,j%,f1%,f12%,c1%,c2%,x%,y%,z%,x1%,y1%,z1%,v1%,R% &f12%=t1%!rep%*t2%!rep% &)s%=t1%!sep%:� s%>t2%!sep% s%=t2%!sep% &s%=s%*2 & r%=(s%/128)^2 &**c1%=t1%!co0%:v1%=t1%!vel%:f1%=t1%!ptf% &4!frict=frsh% &>!pts12=12*(t2%!nop%-1) &H� i%=0 � t1%!nop%-1 &R � (f1%?i%) � 3 � &\# x1%=c1%!0:y1%=c1%!4:z1%=c1%!8 &f& f%=f12%:� (f1%?i%) � 2 � f%=f%*4 &p !v1pos=v1%:!v2pos=t2%!vel% &z3 �temp(x1%,y1%,z1%,t2%!co0%,t2%!ptf%,f%,s%,r%) &� � &� c1%+=12:v1%+=12 &�� &�� &�: &�$� �temp(A%,B%,C%,D%,E%,F%,G%,H%) &�� repel_code &�� &�: &�� �repel_objects(i%,t1%) &�$� i%>objects%-2 � t1%!ptf%=0 � � &�� j%,t2% &�� j%=i%+1 � objects%-1 ' t2%=world%+j%*elsiz%(7) '* � t2%!ptf%>0 � �repel_points(t1%,t2%) '� '$� '.: '8� �rot_damp(thing%,dsh%) 'B@� p%,ve%,co%,x,y,z,vx,vy,vz,xc,yc,zc,vxc,vyc,vzc,Lx,Ly,Lz,i% 'Lp%=thing%!nop% 'V '`-� find centre of mass and linear velocity 'jxc=0:yc=0:zc=0 'tvxc=0:vyc=0:vzc=0 '~ve%=thing%!vel% '�co%=thing%!co0% '�� i%=0 � p%-1 '�" xc+=co%!0:yc+=co%!4:zc+=co%!8 '�% vxc+=ve%!0:vyc+=ve%!4:vzc+=ve%!8 '� ve%+=12:co%+=12 '�� '�$vxc=vxc/p%:vyc=vyc/p%:vzc=vzc/p% '�xc=xc/p%:yc=yc/p%:zc=zc/p% '� '�� find ang. mom. about CoM '�Lx=0:Ly=0:Lz=0 '�ve%=thing%!vel% ( co%=thing%!co0% ( � i%=0 � p%-1 (% x=co%!0-xc:y=co%!4-yc:z=co%!8-zc (+ vx=ve%!0-vxc:vy=ve%!4-vyc:vz=ve%!8-vzc ((. Lx-=y*vz-z*vy:Ly-=z*vx-x*vz:Lz-=x*vy-y*vx (2 ve%+=12:co%+=12 (<� (FL=�(Lx*Lx+Ly*Ly+Lz*Lz) (P� L=0 � (Z ax=0:ay=0:az=0 (d� (n2 � find moment of inertia about ang. mom. axis (x! � and hence rotation vector (� nLx=Lx/L:nLy=Ly/L:nLz=Lz/L (� I=0 (� co%=thing%!co0% (� � i%=0 � p%-1 (�& x=co%!0-xc:y=co%!4-yc:z=co%!8-zc (� a=nLx*x+nLy*y+nLz*z (�& dx=x-nLx*a:dy=y-nLy*a:dz=z-nLz*a (� I+=dx*dx+dy*dy+dz*dz (� co%+=12 (� � (� ax=Lx/I:ay=Ly/I:az=Lz/I (�� (� )ve%=thing%!vel% )co%=thing%!co0% )� dsh%<0 � )" � i%=0 � p%-1 ),& x=co%!0-xc:y=co%!4-yc:z=co%!8-zc )6 ve%!0=vxc+y*az-z*ay )@ ve%!4=vyc+z*ax-x*az )J ve%!8=vzc+x*ay-y*ax )T ve%+=12:co%+=12 )^ � )h� )r dsh%=1<<(dsh%+14) )| � i%=0 � p%-1 )�& x=co%!0-xc:y=co%!4-yc:z=co%!8-zc )� vx=vxc+y*az-z*ay )� vy=vyc+z*ax-x*az )� vz=vzc+x*ay-y*ax )�& x=ve%!0-vx:y=ve%!4-vy:z=ve%!8-vz )�" I=dsh%/(�(x*x+y*y+z*z)+dsh%) )�, ve%!0=vx+x*I:ve%!4=vy+y*I:ve%!8=vz+z*I )� ve%+=12:co%+=12 )� � )�� )�� )�: )�� �air_damp(thing%,dsh%) *� f%,i%,x,y,z,I,ve% *f%=�point_flags(thing%) *ve%=thing%!vel% *&dsh%=1<<(dsh%+14) *0� i%=0 � thing%!nop%-1 *: � f%?i% � 1 � *D x=ve%!0:y=ve%!4:z=ve%!8 *N" I=dsh%/(�(x*x+y*y+z*z)+dsh%) *X# ve%!0=x*I:ve%!4=y*I:ve%!8=z*I *b ve%+=12 *l � *v� *�� *�: *�� �move(on%,thing%) *�� quit% � thing%!vel%=0 � � *�ș "Hourglass_On" *��damp(thing%) *��alter_vels(thing%) *�(� thing%!rdm%<0 �rot_damp(thing%,-1) *��add_vels(thing%) *�ș "Hourglass_Off" *�� *�: *�� �damp(thing%) + � pts% +pts%=thing%!nop% +!vepos=thing%!vel% + !copos=thing%!co0% +*!pts12=12*(pts%-1) +4J� thing%!rdm%<32 � thing%!rdm%>=0 � �rot_damp(thing%,thing%!rdm%+tsh%) +>9� thing%!adm%<32 � �air_damp(thing%,thing%!adm%+tsh%) +H:� thing%!odm%<32 � !dampsh=thing%!odm%+tsh%:� old_damp +R� +\: +f� �alter_vels(thing%) +p5� pts%,vb%,cb%,A%,B%,E%,F%,x,y,z,nx,ny,nz,h%,flx% +zpts%=thing%!nop% +�!vepos=thing%!vel% +�!copos=thing%!co0% +� +�� thing%!rdm%>=0 � +� !bopos=thing%!bnd% +� E%=thing%!nob%-1 +� ș "Hourglass_LEDs",1 +� � bond +�� +� +�frsh%=4+tsh% +�frnd%=.5*(1<<frsh%) +�ș "Hourglass_LEDs",3 ,�repel_objects(on%,thing%) , ,cb%=!copos:vb%=!vepos ,$ș "Hourglass_LEDs",2 ,.� A%=0 � pts%-1 ,81 vb%!0-=grav_z%:vb%!4+=grav_x%:vb%!8+=grav_y% ,B x=cb%!4:y=cb%!8:z=cb%!0 ,L � B%=1 � backgrounds% ,V5 x-=bgdef%(B%,1):y-=bgdef%(B%,2):z+=bgdef%(B%,3) ,` Ȏ bgdef%(B%,0) � ,ja � 0:� z>-5000 � vb%!0-=(z+5000)>>1:vb%!4-=(vb%!4+frnd%)>>frsh%:vb%!8-=(vb%!8+frnd%)>>frsh% ,t0 � 3:r=�(x*x+y*y+z*z):E%=bgdef%(B%,4)+5000 ,~ � r<E% � ,� r=2*(E%-r)/r ,�/ vb%!0-=(vb%!0+frnd%)>>frsh%:vb%!0+=z*r ,�/ vb%!4-=(vb%!4+frnd%)>>frsh%:vb%!4+=x*r ,�/ vb%!8-=(vb%!8+frnd%)>>frsh%:vb%!8+=y*r ,� � ,� � 4: ,�- n%=.5*(y/bgdef%(B%,6)-z/bgdef%(B%,5)) ,� h%=-n%*bgdef%(B%,5)-5000 ,� � z>h% � ,�A � vb%!0>0 vb%!0-=(z-h%)>>1:vb%!4=vb%!4>>2:vb%!8=vb%!8>>2 ,� � ,�$ h%=(n%+1)*bgdef%(B%,6)-5000 - K � y>h% � vb%!8>0 � vb%!8-=(y-h%)>>1::vb%!4=vb%!4>>2:vb%!0=vb%!0>>2 - � - � -5 x+=bgdef%(B%,1):y+=bgdef%(B%,2):z-=bgdef%(B%,3) -( � -29 � ((�(vb%!0)+�(vb%!4)+�(vb%!8))>>tsh%)>3E6 � quit%=� -< vb%+=12:cb%+=12 -F� -P� -Z: -d� �add_vels(thing%) -n� cb%,vb%,pb%,A%,B% -xcb%=thing%!co0% -�vb%=thing%!vel% -�pb%=thing%!ptf% -�� pb%<=0 � -� � A%=0 � thing%!nop%-1 -�D cb%!0+=(vb%!0>>tsh%):cb%!4+=(vb%!4>>tsh%):cb%!8+=(vb%!8>>tsh%) -� vb%+=12:cb%+=12 -� � -�� -� � A%=0 � thing%!nop%-1 -�3 B%=pb%?A%>>2:� B%=0 � B%=vb% � B%=pull%+12*B% -�; cb%!0+=B%!0>>tsh%:cb%!4+=B%!4>>tsh%:cb%!8+=B%!8>>tsh% -� vb%+=12:cb%+=12 -� � .� .� .: ."6� �surface(thing%,P%,S%,XI%,YI%,XN%,YN%,wind%,LP%) .,� X%,Y%,A%,B% .6K� P%=0 � P%=thing%!fac%:� P%<�P � � 1,"bad pointer passed to FNsurface" .@� XN%<2 � YN%<2 � =P% .JZ� S%+(XN%-1+(LP% � 1))*(YN%-1+.5*(LP% � 2))>thing%!nof% � � 1,"not enough facet space" .T� Y%=0 � YN%-2 .^ � X%=0 � XN%-2 .h A%=S%+X%*XI%+Y%*YI% .rM P%=�define_facet(P%,A%+XI%,A%,A%+YI%,1+(X%=-(LP% � 1) � Y%=-(LP% � 2))) .|5 P%=�define_facet(P%,A%+YI%,A%+XI%+YI%,A%+XI%,0) .� � .� � LP% � 1 � .�+ A%=S%+(XN%-1)*XI%+Y%*YI%:B%=S%+Y%*YI% .�9 P%=�define_facet(P%,B%,A%,A%+YI%,1+(Y%=-(LP% � 2))) .�- P%=�define_facet(P%,A%+YI%,B%+YI%,B%,0) .� � .�� .�� LP% � 2 � .� � X%=0 � XN%-2 .�$ B%=S%+X%*XI%:A%=B%+(YN%-1)*YI% .�9 P%=�define_facet(P%,A%+XI%,A%,B%,1+(X%=-(LP% � 1))) .�- P%=�define_facet(P%,B%,B%+XI%,A%+XI%,0) .� � / � LP% � 1 � /# A%=(XN%-1)*XI%:B%=(YN%-1)*YI% /1 P%=�define_facet(P%,S%+B%,S%+A%+B%,S%+A%,0) /&+ P%=�define_facet(P%,S%+A%,S%,S%+B%,0) /0 � /:� /D=P% /N: /X� �ModeVar(V%) /b+ș"OS_ReadModeVariable",mode%,V% � ,,V% /l=V% /v: /�"� �assemstore(mode%,stostyle%) /�L2BPP%=�ModeVar(10) /�NPIX%=�ModeVar(7)*8>>L2BPP% /�MASK%=(1<<(1<<L2BPP%))-1 /�cspace=1000 /�� code cspace /�+A%=0:B%=1:C%=2:D%=3:E%=4:F%=5:G%=6:H%=7 /�link=14:sp=13:pc=15 /�� PASS=0 � 2 � 2 /�P%=code /�F%=5 /�[ OPT PASS /� ALIGN 0.frstore 0STMFD (sp)!,{link} 00LDR C%,storepos:CMP C%,#0:LDMEQFD (sp)!,{pc} 0 LDR R11,storend 0*5SUB R8,R11,C%:CMP R8,#5:MOVLE C%,#0:BLE exfrstrlp 04 MOV A%,#0 0>MOV R10,#MASK%:MOV H%,R10 0HLDR B%,scrpos:BL findpix 0RSTRB A%,[C%],#1 0\#MOV R8,A%,ASR#8:STRB R8,[C%],#1 0f$MOV R8,A%,ASR#16:STRB R8,[C%],#1 0p.frstrlp 0zCMP A%,#NPIX%:BGE exfrstrlp 0�CMP C%,R11:BGE exfrstrlp 0�ADD A%,A%,#1:MOV E%,A% 0�BL findpix:SUB D%,A%,E% 0� .frstrlp2 0�CMP D%,#128:BLT exfrstrlp2 0�CMP C%,R11:BGE exfrstrlp 0�MOV E%,D%,ASR#7 0�CMP E%,#128:MOVGE E%,#127 0�!�R R8,E%,#&80:STRB R8,[C%],#1 0�SUB D%,D%,E%,ASL#7 0�B frstrlp2 0�.exfrstrlp2 0�STRB D%,[C%],#1 1 B frstrlp 1.exfrstrlp 1CMP C%,R11:MOVGE C%,#0 1$STR C%,storepos 1.LDMFD (sp)!,{pc} 18 1B.findpix 1LSTMFD (sp)!,{R8,R9,link} 1V.fpixlp 1`*CMP A%,#NPIX%:LDMGEFD (sp)!,{R8,R9,pc} 1j"LDRB R8,[B%,A%,ASR#(3-L2BPP%)] 1t� R9,A%,#7>>L2BPP% 1~MOV R9,R9,ASL#L2BPP% 1��S R8,R8,R10,ASL R9 1�] 1�8� stostyle%=0 � [OPT PASS:LDMNEFD (sp)!,{R8,R9,pc}:] 1�� stostyle%=1 � 1� [ OPT PASS 1� CMP R8,H%,ASL R9 1� �EQ H%,H%,R10 1� LDMEQFD (sp)!,{R8,R9,pc} 1� ] 1�� 1�[ OPT PASS 1�ADD A%,A%,#1 2 B fpixlp 2 2 .show 2STMFD (sp)!,{link} 2(MOV R10,#MASK% 22LDR B%,scrpos 2<LDRB A%,[C%],#1 2F%LDRB R8,[C%],#1:�R A%,A%,R8,ASL#8 2P&LDRB R8,[C%],#1:�R A%,A%,R8,ASL#16 2Z] 2d� stostyle%=0 � 2n [OPT PASS 2x .shloop 2� CMP A%,#NPIX%:BGE exshloop 2�# LDRB R8,[B%,A%,ASR#(3-L2BPP%)] 2� � R9,A%,#7>>L2BPP% 2� MOV R9,R9,ASL#L2BPP% 2� � R8,R8,R10,ASL R9 2�# STRB R8,[B%,A%,ASR#(3-L2BPP%)] 2� ADD A%,A%,#1 2� ] 2�� 2�� stostyle%=1 � 2� [ OPT PASS 2� .shloop 2� \ want pixel A% set 3 3 \ get next offset 3 CMP A%,#NPIX%:BGE exshloop 3" ADD G%,A%,#1:.shloop3 3, LDRB D%,[C%],#1 361 TST D%,#&80:�NE D%,D%,#&7F:MOVNE D%,D%,ASL#7 3@) ADD G%,G%,D%:CMP D%,#128:BGE shloop3 3J 3T \ plot pixels A% to G%-1 3^ .shloop4 3h# LDRB R8,[B%,A%,ASR#(3-L2BPP%)] 3r � R9,A%,#7>>L2BPP% 3| MOV R9,R9,ASL#L2BPP% 3� � R8,R8,R10,ASL R9 3�# STRB R8,[B%,A%,ASR#(3-L2BPP%)] 3�' ADD A%,A%,#1:CMP A%,G%:BLT shloop4 3� ADD A%,A%,#1 3� 3� \ get next offset 3� CMP A%,#NPIX%:BGE exshloop 3� ] 3�� 3�[ OPT PASS 3�.shloop2 3�LDRB D%,[C%],#1 3�0TST D%,#&80:�NE D%,D%,#&7F:MOVNE D%,D%,ASL#7 4(ADD A%,A%,D%:CMP D%,#128:BGE shloop2 4B shloop 4 .exshloop 4&MOV A%,C%:LDMFD (sp)!,{pc} 40 4:.copy1t2 4DSTMFD (sp)!,{link} 4NLDR R0,scrlen 4X!LDR R1,scrpos2:LDR R2,scrpos1 4bADD R0,R1,R0 4l .cop1t2lp 4v)LDMIA R1!,{R3-R10}:STMIA R2!,{R3-R10} 4�CMP R1,R0:BLT cop1t2lp 4�LDMFD (sp)!,{pc} 4� 4�.eor2w1 4�STMFD (sp)!,{link} 4�LDR R0,scrlen 4�!LDR R1,scrpos2:LDR R2,scrpos1 4�ADD R0,R1,R0 4� .eor2w1lp 4�'LDMIA R1!,{R3-R6}:LDMIA R2,{R7-R10} 4�0� R3,R3,R7:� R4,R4,R8:� R5,R5,R9:� R6,R6,R10 4�STMIA R2!,{R3-R6} 4�CMP R1,R0:BLT eor2w1lp 5LDMFD (sp)!,{pc} 5 5.bank EQUD 1 5 .storepos EQUD 0 5*.storend EQUD 0 54.scrpos EQUD 0 5>.scrpos1 EQUD 0 5H.scrpos2 EQUD 0 5R.scrlen EQUD �ModeVar(7) 5\] 5f1� P%>code+cspace � � 1,"Out of room for code" 5p � PASS 5z� 5�: 5�� �assem_nebo 5��assemRoot 5�+A%=0:B%=1:C%=2:D%=3:E%=4:F%=5:G%=6:H%=7 5�uDiv32=�assemDiv(5,0,2,8,9) 5�� scrap% 256*4 5�cspace=500 5�� code cspace 5�link=14:sp=13:pc=15 5�� PASS=0 � 2 � 2 5�P%=code 5�[ OPT PASS 5� .nearbond 6STMFD (sp)!,{link} 6OLDR R8,neboblock:LDR R9,neboblock+4:LDR B%,neboblock+8:LDR R10,neboblock+12 6-SUB E%,E%,#1:MOV R12,#12:MLA H%,E%,R12,H% 6$ .nblp2 6.SUB G%,H%,#12:SUB F%,E%,#1 68 .nblp1 6B0LDR A%,[H%,#8]:LDR R12,[G%,#8]:SUB A%,A%,R12 6L7MOV A%,A%,ASR R10:MUL C%,A%,A%:CMP C%,R9:BGT nbskip 6V0LDR A%,[H%,#4]:LDR R12,[G%,#4]:SUB A%,A%,R12 6`:MOV A%,A%,ASR R10:MLA C%,A%,A%,C%:CMP C%,R9:BGT nbskip 6j0LDR A%,[H%,#0]:LDR R12,[G%,#0]:SUB A%,A%,R12 6t:MOV A%,A%,ASR R10:MLA C%,A%,A%,C%:CMP C%,R9:BGT nbskip 6~,LDR A%,neboblock+16:CMP C%,A%:BLT nbskip 6�'CMP B%,D%:ADDGE B%,B%,#8:BGE nbskip 6�/BL root:LDR A%,[R8,A%,ASL#2]:STR A%,[B%,#4] 6�%�R A%,E%,F%,ASL#16:STR A%,[B%],#8 6�.nbskip 6�)SUB G%,G%,#12:SUBS F%,F%,#1:BGE nblp1 6�)SUB H%,H%,#12:SUBS E%,E%,#1:BGT nblp2 6�STR B%,neboblock+8 6�LDMFD (sp)!,{pc} 6�1.neboblock EQUD 0:EQUD 0:EQUD 0:EQUD 0:EQUD 0 6� 6�.nearcount 6�STMFD (sp)!,{link} 7 <LDR R8,neboblock:LDR R9,neboblock+4:LDR R10,neboblock+12 7 MOV B%,#0 7-SUB E%,E%,#1:MOV R12,#12:MLA H%,E%,R12,H% 7.cnblp2 7(SUB G%,H%,#12:SUB F%,E%,#1 72.cnblp1 7<0LDR A%,[H%,#8]:LDR R12,[G%,#8]:SUB A%,A%,R12 7F8MOV A%,A%,ASR R10:MUL C%,A%,A%:CMP C%,R9:BGT cnbskip 7P0LDR A%,[H%,#4]:LDR R12,[G%,#4]:SUB A%,A%,R12 7Z;MOV A%,A%,ASR R10:MLA C%,A%,A%,C%:CMP C%,R9:BGT cnbskip 7d0LDR A%,[H%,#0]:LDR R12,[G%,#0]:SUB A%,A%,R12 7n;MOV A%,A%,ASR R10:MLA C%,A%,A%,C%:CMP C%,R9:BGT cnbskip 7x-LDR A%,neboblock+16:CMP C%,A%:BLT cnbskip 7�ADD B%,B%,#1 7�.cnbskip 7�*SUB G%,G%,#12:SUBS F%,F%,#1:BGE cnblp1 7�*SUB H%,H%,#12:SUBS E%,E%,#1:BGT cnblp2 7� MOV R0,B% 7�LDMFD (sp)!,{pc} 7�] 7�1� P%>code+cspace � � 1,"Out of room for code" 7� � PASS 7�� 7�: 7�� �assem 7�cspace=3000 8� code cspace 8+A%=0:B%=1:C%=2:D%=3:E%=4:F%=5:G%=6:H%=7 8#repeldiv=�assemDiv(F%,D%,6,7,8) 8"X%=0:Y%=1:Z%=3 8,#AI%=12:BI%=11:SA%=9:CB%=8:SB%=7 86link=14:sp=13:pc=15 8@� PASS=0 � 2 � 2 8JP%=code 8T[ OPT PASS 8^ 8h.basic_stack 8rMOV R0,R13 8|MOV pc,link 8� 8�.avZ 8�MOV R10,#12 8�STMFD (sp)!,{link} 8�.avzloop 8�LDMIA C%,{R7,R8,R9} 8�MLA R7,R10,R7,D% 8�MLA R8,R10,R8,D% 8�MLA R9,R10,R9,D% 8�LDR F%,[R7] 8�LDR R11,[R8]:ADD F%,F%,R11 8�LDR R11,[R9]:ADD F%,F%,R11 8�STR F%,[C%,#12] 9ADD C%,C%,#elsiz%(3) 9SUBS E%,E%,#1:BGE avzloop 9LDMFD (sp)!,{pc} 9& 90.hidefaces 9:STMFD (sp)!,{link} 9D.hideflp 9NLDR F%,[C%,#16] 9XLDMIA C%,{R7,R9,R11} 9bADD R7,D%,R7,ASL#3 9lADD R9,D%,R9,ASL#3 9vADD R11,D%,R11,ASL#3 9�LDMIA R7,{R7,R8} 9�LDMIA R9,{R9,R10} 9�LDMIA R11,{R11,R12} 9�!SUB R9 ,R9 ,R7:SUB R10,R10,R8 9�!SUB R11,R11,R7:SUB R12,R12,R8 9� MUL R7,R9,R12:MUL R8,R10,R11 9�BIC F%,F%,#&20000000 9�#CMP R7,R8:�RLT F%,F%,#&20000000 9�STR F%,[C%,#16] 9�ADD C%,C%,#elsiz%(3) 9�SUBS E%,E%,#1:BGE hideflp 9�LDMFD (sp)!,{pc} 9� :.pts12 EQUD 0 :.vel2pos EQUD vel2% :.storesp EQUD 0 : .dampran EQUD (1.0*180)^2 :*.dampsh EQUD dampsh% :4.divtab EQUD recip% :> :H.v1pos EQUD 0:.v2pos EQUD 0 :R.frict EQUD 0 :\ :f.repel_code :pSTMFD (sp)!,{link} :zLDR R10,pts12 :� MOV R8,R4 :�LDR R9,v2pos :�.repel_lp1 :�;\ 0,1,2=x1%,y1%,z1% 3=c2% 4= 5=f% 6=s% 7=r% 8=f2% 9=v2% :�.LDRB R4,[R8]:TST R4,#3:BLNE repel_comppair :�\ R11,R12 changed :�ADD R3,R3,#12 :�ADD R9,R9,#12 :�ADD R8,R8,#1 :�SUBS R10,R10,#12 :�BGE repel_lp1 :�LDMFD (sp)!,{pc} :� ;.repel_comppair ;!\STMFD (sp)!,{R0-R3,R10,link} ;#STMFD (sp)!,{R0-R3,R9-R10,link} ;$4\ 0,1,2=x1%,y1%,z1% 3=c2% 4=f2%?0 5=f% 6=s% 7=r% ;.LDMIA R3,{R10,R11,R12} ;8-SUB R0,R0,R10:SUB R1,R1,R11:SUB R2,R2,R12 ;B3MOV R0,R0,ASR#7:MOV R1,R1,ASR#7:MOV R2,R2,ASR#7 ;L0MUL R3,R0,R0:MLA R3,R1,R1,R3:MLA R3,R2,R2,R3 ;V%\ R0,R1,R2,R3,R10,R11,R12 changed ;`CMP R3,R7:BLLT repel_pair ;j%\ R0,R1,R2,R3,R10,R11,R12 changed ;t!LDMFD (sp)!,{R0-R3,R9-R10,pc} ;~\ R11,R12 changed ;� ;�.repel_pair ;�STMFD (sp)!,{R4-R8,link} ;�6\ (0,1,2)=(dx,dy,dz) 3=d^2 4=f2%?j% 5=f% 6=s% 7=r% ;�*LDR R10,v1pos:MOV R11,R9:LDR R12,frict ;�BL rroot ;�CMP R3,#2:MOVLT R3,#2 ;�SUB R6,R6,R3:MUL R5,R6,R5 ;�BL repeldiv ;�\ 3,5,6,7,8 changed ;�*MUL R0,R6,R0:MUL R1,R6,R1:MUL R2,R6,R2 ;�� R4,R4,#2:RSB R3,R4,#8 <