Conversion from ZX Spectrum BASIC to Purebasic
Posted: Fri Nov 24, 2023 11:28 pm
This ZX Spectrum code is a very impressive mirror sphere raytracing example, and it will look good in Purebasic, as we can make the resolution greater.
I'm trying to convert this ZX Spectrum BASIC Code into Purebasic:
I have it mostly done, I have just run into a little problem somewhere and I can't see where in my Purebasic code:
I have kept the GOTO and GOSUB numbers as the same Text-label for ease of browsing. I tried to keep to the Spectrum code as much as possible.
This will look great on Purebasic as I said, we can add colour etc.
It's the old chequerboard/mirror sphere raytracing example.
Please help if you can.
It is very close to being correct.
There is probably one or two small differences.
I'm trying to convert this ZX Spectrum BASIC Code into Purebasic:
Code: Select all
10 FOR g=0 TO 300: RESTORE 30: LET spheres=1: IF spheres THEN DIM c(spheres,3): DIM r(spheres): DIM q(spheres)
20 FOR k=1 TO spheres: READ c(k,1),c(k,2),c(k,3),r: LET r(k)=r: LET q(k)=r*r: NEXT k
30 DATA 0.3+0.5*SIN (2*PI*g/60),-0.6,1.5+0.5*COS (2*PI*g/75),0.4: REM 2+0.5*COS (2*PI*g/50)
40 REM DATA 0.9/10,-1/10,4,0.1
50 FOR i=0 TO 175: FOR j=0 TO 255
60 LET x=0.3: LET y=-0.5: LET z=0
70 LET dx=j-128: LET dy=88-i: LET dz=300: LET dd=dx*dx+dy*dy+dz*dz
80 GO SUB 100: NEXT j: NEXT i
90 SAVE STR$ g SCREEN$ : CLS : NEXT g: STOP
100 LET n=-(y>=0 OR dy<=0): IF NOT n THEN LET s=-y/dy
110 FOR k=1 TO spheres
120 LET px=c(k,1)-x: LET py=c(k,2)-y: LET pz=c(k,3)-z
130 LET pp=px*px+py*py+pz*pz
140 LET sc=px*dx+py*dy+pz*dz
150 IF sc<=0 THEN GO TO 200
160 LET bb=sc*sc/dd
170 LET aa=q(k)-pp+bb
180 IF aa<=0 THEN GO TO 200
190 LET sc=(SQR bb-SQR aa)/SQR dd: IF sc<s OR n<0 THEN LET n=k: LET s=sc
200 NEXT k
210 IF n<0 THEN RETURN
220 LET dx=dx*s: LET dy=dy*s: LET dz=dz*s: LET dd=dd*s*s
230 LET x=x+dx: LET y=y+dy: LET z=z+dz
240 IF n=0 THEN GO TO 300
250 LET nx=x-c(n,1): LET ny=y-c(n,2): LET nz=z-c(n,3)
270 LET l=2*(dx*nx+dy*ny+dz*nz)/q(n)
280 LET dx=dx-nx*l: LET dy=dy-ny*l: LET dz=dz-nz*l
290 GO TO 100
300 FOR k=1 TO spheres
310 LET u=c(k,1)-x: LET v=c(k,3)-z: IF u*u+v*v<=q(k) THEN RETURN
320 NEXT k
330 IF (x-INT x>.6)<>(z-INT z>.6) THEN PLOT j,i
340 RETURN
Code: Select all
#width=256
#height=178
OpenWindow(0,0,0,#width,#height,"SpecRayTrace")
CreateImage(0,#width,#height)
ImageGadget(0, 0, 0, #width, #height, ImageID(0))
EnableExplicit
Global.f r,x,y,z
Global.f dx,dy,dz
Global.f dd,s
Global.f px,py,pz,pp,sc,bb,aa,u,v
Global.f nx,ny,nz,l
Global.i g,i,j,spheres,k
Global.i n
Global.f Dim arr(5)
For g=0 To 200
Delay(1000)
StartDrawing(ImageOutput(0))
Box(0,0,#width,#height,#Black)
spheres=1:
If spheres
Dim c.f(spheres,4)
Dim r.f(spheres)
Dim q.f(spheres)
EndIf
arr(1)=0.3+0.5*Sin(2*#PI*g/40)
arr(2)-0.6
arr(3)=1.5+1*Cos (2*#PI*g/50)
arr(4)=0.4
For k=1 To spheres
c(k,1)=arr(1)
c(k,2)=arr(2)
c(k,3)=arr(3)
r=arr(4)
r(k)=r
q(k)=r*r
Next k
For i=0 To #height-1
For j=0 To #width-1
x=0.3
y=-0.5
z=0
dx=j-#width/2
dy=#height/2-i
dz=#width*6/5
dd=dx*dx+dy*dy+dz*dz
Gosub onehundred
Next j
Next i
StopDrawing()
SetGadgetState(0,ImageID(0))
Next g
End
onehundred:
n=-Bool((y>=0) Or (dy<=0))
If Not n
s=-y/dy
EndIf
For k=1 To spheres
px=c(k,1)-x
py=c(k,2)-y
pz=c(k,3)-z
pp=px*px+py*py+pz*pz
sc=px*dx+py*dy+pz*dz
If sc<=0
Goto twohundred
EndIf
bb=sc*sc/dd
aa=q(k)-pp+bb
If aa<=0
Goto twohundred
EndIf
sc=(Sqr( bb)-Sqr(aa)/Sqr(dd))
If sc<s Or n<0
n=k
s=sc
EndIf
twohundred:
Next k
If n<0
Return
EndIf
dx=dx*s
dy=dy*s
dz=dz*s
dd=dd*s*s
x=x+dx
y=y+dy
z=z+dz
If n=0
Goto threehundred
EndIf
nx=x-c(n,1)
ny=y-c(n,2)
nz=z-c(n,3)
l=2*(dx*nx+dy*ny+dz*nz)/q(n)
dx=dx-nx*l
dy=dy-ny*l
dz=dz-nz*l
Goto onehundred
threehundred:
For k=1 To spheres
u=c(k,1)-x
v=c(k,3)-z
If u*u+v*v<=q(k)
Return
EndIf
Next k
If Bool(x-Int(x)>0.5) <> Bool(z-Int(z)>0.5)
Plot(j,#height-i-1,#White)
EndIf
Return
This will look great on Purebasic as I said, we can add colour etc.
It's the old chequerboard/mirror sphere raytracing example.
Please help if you can.
It is very close to being correct.
There is probably one or two small differences.