rem Jigsaw IV (Assembly Version)....... Rev 10.0 rem A J Tooth // 6th November 2004 rem Revised for arbitrary screen resolution // July 2007 rem Preamble================================== on error if (err=17) then quit *FLOAT 64 himem=lomem + 10000000 install @lib$+"MyUtils.bbc" install @lib$+"BMP_Utils.bbc" rem Preamble================================== rem Maximise display proc_maxim(xscreen%,yscreen%) : colour 132,50,0,0 : colour 132 : cls rem Set Parameters proc_setpars : cls rem Set the Start and End points along each edge proc_edge rem Calculate and Store Crossing Points proc_cross rem Display the Jigsaw proc_fullscreen(xscreen%,yscreen%) : colour 143 : cls proc_Jigdisp : proc_cont(1) : colour 132,50,0,0 : colour 132 : cls rem Get bmp proc_getbmp : proc_cont(3) rem Sawn-up Jigsaw proc_jumble : proc_cont(3) rem Jigsaw proc_ordered if js$="w" then proc_Jigdisp *SCREENSAVE "Jig.bmp" a$=get$ quit end rem End of Program ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ rem Continue routine def proc_cont(Col%) local a$,x,y,m& colour Col% : print tab(0,0);"Finished. Press any key or left-click to continue." a$="" repeat mouse x,y,m& a$=inkey$(1) if m&=4 then a$="m" until a$<>"" endproc rem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ rem Set the Start and End points along each edge def proc_edge local i%,j%,Xs%,Ys%,Xe%,Ye%,fac rem Upper and Lower Edges for i%=1 to Lv% fac=(2*rnd(1))-1 Xs%=int(i%*SpX + (0.25*fac*SpX)) Trk%(i%,0,1)=Xs% : Trk%(i%,0,2)=0 fac=(2*rnd(1))-1 Xe%=int(i%*SpX + (0.25*fac*SpX)) Trk%(i%,Lh%+1,1)=Xe% : Trk%(i%,Lh%+1,2)=Ynum%-1 next i% rem Corner Points Trk%(0,0,1)=0 : Trk%(0,0,2)=0 Trk%(0,Lh%+1,1)=0 : Trk%(0,Lh%+1,2)=Ynum%-1 Trk%(Lv%+1,0,1)=Xnum%-1 : Trk%(Lv%+1,0,2)=0 Trk%(Lv%+1,Lh%+1,1)=Xnum%-1 : Trk%(Lv%+1,Lh%+1,2)=Ynum%-1 rem Left and Right Edges for j%=1 to Lh% fac=(2*rnd(1))-1 Ys%=int(j%*SpY + (0.1*fac*SpY)) Trk%(0,j%,2)=Ys% : Trk%(0,j%,1)=0 fac=(2*rnd(1))-1 Ye%=int(j%*SpY + (0.1*fac*SpY)) Trk%(Lv%+1,j%,2)=Ye% : Trk%(Lv%+1,j%,1)=Xnum%-1 next j% endproc rem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ rem Calculate and Store Crossing Points def proc_cross local i%,j%,Ax,Ay,Bx,By,Cx,Cy,Dx,Dy,det,x,y,Xx%,Yy%,mu Lrg%=29 if Min%<10 then Lrg%=79 if Min%>30 then Lrg%=11 Sml%=(Lrg%+1)/2 for i%=1 to Lv% for j%=1 to Lh% Ax=0 : Ay=Trk%(0,j%,2) Cx=Trk%(i%,0,1) : Cy=0 Bx=Xnum%-1 By=Trk%(Lv%+1,j%,2) - Ay Dx=Trk%(i%,Lh%+1,1) - Cx Dy=Ynum%-1 det=Dy*Bx-Dx*By mu=((Cx-Ax)*By - (Cy-Ay)*Bx)/det x=(Cx+mu*Dx) : y=(Cy+mu*Dy) rem Rounding if x-int(x)<.5 then Xx%=int(x) else Xx%=int(x)+1 if y-int(y)<.5 then Yy%=int(y) else Yy%=int(y)+1 rem Aberrate the positions Trk%(i%,j%,1)=Xx% + rnd(Lrg%)-Sml% : Trk%(i%,j%,2)=Yy% + rnd(Lrg%)-Sml% next j% next i% endproc rem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ rem Display the Jigsaw def proc_Jigdisp local i%,j% gcol 0 for i%=1 to Lv% x1%=2*Trk%(i%,0,1) : y1%=2*Trk%(i%,0,2) for j%=1 to Lh% x2%=2*Trk%(i%,j%,1) : y2%=2*Trk%(i%,j%,2) proc_smudge(x1%,y1%,x2%,y2%) x1%=x2% : y1%=y2% next j% x2%=2*Trk%(i%,Lh%+1,1) : y2%=2*Trk%(i%,Lh%+1,2) proc_smudge(x1%,y1%,x2%,y2%) next i% for j%=1 to Lh% x1%=2*Trk%(0,j%,1) : y1%=2*Trk%(0,j%,2) for i%=1 to Lv% x2%=2*Trk%(i%,j%,1) : y2%=2*Trk%(i%,j%,2) proc_smudge(x1%,y1%,x2%,y2%) x1%=x2% : y1%=y2% next i% x2%=2*Trk%(Lv%+1,j%,1) : y2%=2*Trk%(Lv%+1,j%,2) proc_smudge(x1%,y1%,x2%,y2%) next j% endproc rem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ def proc_smudge(X1%,Y1%,X2%,Y2%) local j% R=sqr((X2%-X1%)*(X2%-X1%) + (Y2%-Y1%)*(Y2%-Y1%)) for j%=0 to Num% rem Shift end-points in direction of normal vector a1=(y2%-y1%)*.005*j%/R x12=X1%+a1 x22=X2%+a1 a2=-(X2%-X1%)*.005*j%/R y12=Y1%+a2 y22=Y2%+a2 a1=-a1 : a2=-a2 v12=X1%+a1 v22=X2%+a1 w12=Y1%+a2 w22=Y2%+a2 line x12,y12,x22,y22 line v12,w12,v22,w22 next j% endproc rem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ rem Setup def proc_setup dim dir% 317 dim Header%(54) dim Ref% 3 dim flll% 800, PiX% 3, PiY% 3, l% 3, m% 3, PrX% 3, PrY% 3 dim pream% 600, lam% 7, mu% 7, Ax% 3, Ay% 3, Bx% 3, By% 3 dim LocX% 3, LocY% 3, iRes% 3, iRx% 7, iRy% 7, Cx% 3, Cy% 3, Dx% 3, Dy% 3 dim rotrans% 400, command% 10 $command%="REFRESH" rem Dual-pass assembly, in case of labels for pass&=0 to 2 step 2 proc_pream(pass&) proc_flll(pass&) proc_rotrans(pass&) next pass& endproc rem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ rem Get bmp def proc_getbmp proc_pichooseSZ(Name$, FulName$, Pre$, wdth%, hght%, lgth%) proc_gendisp(1,FulName$,0,0,wdth%,hght%,pf%,lgth%) Wlim%=((wdth%*3+3)and-4) proc_setup endproc rem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ rem Set Parameters def proc_setpars Xnum%=xscreen% : Ynum%=yscreen% : Num%=50 dim rgb% 3, r% 0, g% 0, b% 0 input tab(5,5);"How many vertical lines? (2 to 60)",Lv% if Lv%<=2 then Lv%=2 if Lv%>60 then Lv%=60 input tab(5,6);"How many horizontal lines? (2 to 50)",Lh% if Lh%<=2 then Lh%=2 if Lh%>50 then Lh%=50 print tab(5,10);"Normal display (-n- or left-click), or varied (-v- or right-click)?" repeat mouse x,y,m& in$=inkey$(1) if m&=4 then in$="n" if m&=1 then in$="v" until (in$="n" or in$="v") repeat mouse x,y,m& until m&=0 print tab(5,15);"Final picture with jigsaw lines (-w- or left-click) or without (-o- or right-click)?" repeat mouse x,y,m& js$=inkey$(1) if m&=4 then js$="w" if m&=1 then js$="o" until (js$="w" or js$="o") Max%=(Lv%+1)*(Lh%+1) rem Track where the crossing nodes are dim Trk%(Lv%+1,Lh%+1,2), in% 0, rll% 0, pt11% 7, pt9% 7, pt8% 7, pt12% 7, sr% 3 dim Stp% 3, Theta% 7, Rx% 3, Ry% 3, Trns% 0 rem Average internode spacing SpX=(Xnum%/(Lv%+1)) SpY=(Ynum%/(Lh%+1)) Min%=Lv% : if Min%>Lh% then Min%=Lh% !Stp%=80+int(xscreen%/Min%) if in$="v" then ?in%=1 else ?in%=0 ?rll%=0 |pt11%=1.075 : |pt9%=0.925 : |pt8%=0.85 : |pt12%=1.15 endproc rem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ rem Vectors for Sides of each Quadrilateral def proc_vecs(Px%,Py%) !LocX%=Trk%(Px%,Py%,1) : !LocY%=Trk%(Px%,Py%,2) !Ax%=Trk%(Px%+1,Py%,1) - !LocX% : !Ay%=Trk%(Px%+1,Py%,2) - !LocY% !Bx%=Trk%(Px%+1,Py%+1,1) - Trk%(Px%+1,Py%,1) !By%=Trk%(Px%+1,Py%+1,2) - Trk%(Px%+1,Py%,2) !Cx%=Trk%(Px%,Py%+1,1) - !LocX% : !Cy%=Trk%(Px%,Py%+1,2) - !LocY% !Dx%=Trk%(Px%+1,Py%+1,1) - Trk%(Px%,Py%+1,1) !Dy%=Trk%(Px%+1,Py%+1,2) - Trk%(Px%,Py%+1,2) endproc rem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ rem Plot Preamble - Assembly Routine def proc_pream(opt%) P%=pream% [opt opt% mov edx,0 ;Initialise outer loop counter mov [l%],edx mov al,[in%] cmp al,1 jne loopout inc byte [rll%] mov al,[rll%] cmp al,5 jne nt5 mov al,0 mov [rll%],al .nt5 .loopout mov edx,0 ;Initialise inner loop counter mov [m%],edx .loopin finit fild dword [l%] ;Calculate lam And mu fild dword [Stp%] fdivp st1,st0 fst qword [lam%] fild dword [m%] fild dword [Stp%] fdivp st1,st0 fmulp st1,st0 fstp qword [mu%] ;Calculate lam And mu fld qword [lam%] ;PiX% calculation fild dword [Ax%] fmulp st1,st0 fld qword [mu%] fild dword [Bx%] fmulp st1,st0 faddp st1,st0 fst qword [iRx%] fistp dword [iRes%] mov eax,[iRes%] add eax,[LocX%] mov [PrX%],eax mov [PiX%],eax ;PiX% calculation fld qword [lam%] ;PiY% calculation fild dword [Ay%] fmulp st1,st0 fld qword [mu%] fild dword [By%] fmulp st1,st0 faddp st1,st0 fst qword [iRy%] fistp dword [iRes%] mov eax,[iRes%] add eax,[LocY%] mov [PrY%],eax mov [PiY%],eax ;PiY% calculation mov al,[Trns%] cmp al,0 je ntr1 call rotrans% ;rotrans 0nly used f0r sawn-up jigsaw .ntr1 call flll% ;Pl0t routine fld qword [lam%] ;PiX% calculation fild dword [Cx%] fmulp st1,st0 fld qword [mu%] fild dword [Dx%] fmulp st1,st0 faddp st1,st0 fst qword [iRx%] fistp dword [iRes%] mov eax,[iRes%] add eax,[LocX%] mov [PrX%],eax mov [PiX%],eax ;PiX% calculation fld qword [lam%] ;PiY% calculation fild dword [Cy%] fmulp st1,st0 fld qword [mu%] fild dword [Dy%] fmulp st1,st0 faddp st1,st0 fst qword [iRy%] fistp dword [iRes%] mov eax,[iRes%] add eax,[LocY%] mov [PrY%],eax mov [PiY%],eax ;PiY% calculation mov al,[Trns%] cmp al,0 je ntr2 call rotrans% ;rotrans 0nly used f0r sawn-up jigsaw .ntr2 call flll% ;Pl0t routine inc dword [m%] ;Inner loop control mov edx,[m%] cmp edx,[Stp%] jle near loopin mov edx,command% call "oscli" inc dword [l%] ;Outer loop control mov edx,[l%] cmp edx,[Stp%] jle near loopout ret ] endproc rem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ def proc_dump |lam%=!l%/!Stp% : |mu%=|lam%*(!m%/!Stp%) : rem DONE rem First 2 sides !PiX%=!LocX%+int(|lam%*!Ax%+|mu%*!Bx%) : rem DONE !PiY%=!LocY%+int(|lam%*!Ay%+|mu%*!By%) : rem DONE rem Second 2 sides !PiX%=!LocX%+int(|lam%*!Cx%+|mu%*!Dx%) : rem DONE !PiY%=!LocY%+int(|lam%*!Cy%+|mu%*!Dy%) : rem DONE endproc rem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ rem Plot to Screen - Assembly Routine def proc_flll(opt%) P%=flll% [opt opt% mov eax,[PiY%] imul eax,[^Wlim%] add eax,[PiX%] add eax,[PiX%] add eax,[PiX%] add eax,54 mov ecx,pf%[eax] mov [rgb%],ecx mov ebx,rgb% mov dl,[in%] cmp dl,1 jne near cse1 mov dl,[rll%] cmp dl,0 je near cse1 finit cmp dl,1 jne nd1 fld qword [pt9%] jmp rest .nd1 cmp dl,2 jne nd2 fld qword [pt8%] jmp rest .nd2 cmp dl,3 jne nd3 fld qword [pt12%] jmp rest .nd3 fld qword [pt11%] .rest fld st0 fld st0 mov edx,0 mov dl,[ebx] mov [sr%],edx fild dword [sr%] fmulp st1,st0 fistp dword [sr%] mov edx,[sr%] cmp dh,0 je nfix1 mov dl,255 .nfix1 mov [b%],dl inc ebx mov edx,0 mov dl,[ebx] mov [sr%],edx fild dword [sr%] fmulp st1,st0 fistp dword [sr%] mov edx,[sr%] cmp dh,0 je nfix2 mov dl,255 .nfix2 mov [g%],dl inc ebx mov edx,0 mov dl,[ebx] mov [sr%],edx fild dword [sr%] fmulp st1,st0 fistp dword [sr%] mov edx,[sr%] cmp dh,0 je nfix3 mov dl,255 .nfix3 mov [r%],dl jmp cse2 .cse1 mov al,[ebx] mov [b%],al inc ebx mov al,[ebx] mov [g%],al inc ebx mov al,[ebx] mov [r%],al .cse2 mov al,19 ;Changes the rgb vlue f0r colr 10 call "oswrch" mov al,10 call "oswrch" mov al,16 call "oswrch" mov al,[r%] call "oswrch" mov al,[g%] call "oswrch" mov al,[b%] call "oswrch" mov al,18 ;Calls gc0l routine call "oswrch" mov al,0 call "oswrch" mov al,10 call "oswrch" mov al,25 ;Calls pl0t routine call "oswrch" mov al,69 call "oswrch" mov ebx,[PrX%] shl ebx,1 mov al,bl call "oswrch" mov al,bh call "oswrch" mov ebx,[PrY%] shl ebx,1 mov al,bl call "oswrch" mov al,bh call "oswrch" ret ] endproc rem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ rem Rotate and Translate - Assembly Routine rem Only invoked for the sawn-up jigsaw def proc_rotrans(opt%) P%=rotrans% [opt opt% fld qword [Theta%] fsincos fld qword [iRx%] fmulp st1,st0 fld qword [iRy%] fmulp st2,st0 fsubp st1,st0 fistp dword [iRes%] mov eax,[iRes%] add eax,[Rx%] mov [PrX%],eax fld qword [Theta%] fsincos fld qword [iRy%] fmulp st1,st0 fld qword [iRx%] fmulp st2,st0 faddp st1,st0 fistp dword [iRes%] mov eax,[iRes%] add eax,[Ry%] mov [PrY%],eax ret ] endproc rem ==================================================================== rem Sawn-up Jigsaw def proc_jumble local a%,b% rem First of all clear the screen colour 128 : cls *REFRESH OFF ?Trns%=1 a%=0 repeat b%=0 repeat rem Pick a random angle and a random position for each piece The=rnd(1) : |Theta%=The*2*pi !Rx%=rnd(Xnum%-200)+100 : !Ry%=rnd(Ynum%-200)+100 sys "GetCurrentProcess" to hprocess% sys "SetPriorityClass", hprocess%, &100 rem Vectors for Sides of each Quadrilateral proc_vecs(a%,b%) rem Call Assembly Routine call pream% sys "GetCurrentProcess" to hprocess% sys "SetPriorityClass", hprocess%, &20 b%+=1 b$="" b$=inkey$(10) mouse x,y,m& if m&=4 then a$="m" until (b%>Lh% or b$<>"") a%+=1 until (a%>Lv% or b$<>"") *REFRESH ON endproc rem ==================================================================== rem Jigsaw def proc_ordered rem First of all clear the screen colour 128:cls *REFRESH OFF Cmt%=0 : ?Trns%=0 repeat rem Find the next empty space repeat Px%=rnd(Lv%+1)-1 : Py%=rnd(Lh%+1)-1 k$=inkey$(1) until (Trk%(Px%,Py%,0)=0 or k$<>"") Trk%(Px%,Py%,0)=1 Cmt%+=1 sys "GetCurrentProcess" to hprocess% sys "SetPriorityClass", hprocess%, &100 rem Vectors for Sides of each Quadrilateral proc_vecs(Px%,Py%) rem Call Assembly Routine call pream% sys "GetCurrentProcess" to hprocess% sys "SetPriorityClass", hprocess%, &20 b$="" b$=inkey$(10) mouse x,y,m& if m&=4 then a$="m" until (b$<>"" or k$<>"" or Cmt%=Max%) *REFRESH ON endproc rem ====================================================================