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
<