ZX Spectrum Raytracer

The place for codemasters or beginners to talk about programming any language for the Spectrum.
Post Reply
berarma
Microbot
Posts: 129
Joined: Thu Mar 09, 2023 10:55 am

ZX Spectrum Raytracer

Post by berarma »

Not mine, but I found it interesting. I wonder how much faster it would run in machine code.

https://gabrielgambetta.com/zx-raytracer.html
Xela
Dizzy
Posts: 76
Joined: Tue Apr 18, 2023 8:17 am

Re: ZX Spectrum Raytracer

Post by Xela »

About x10 times faster:

Image
Spectrum Next "pure" Basic 28Mhz

Image
Spectrum Next Tobos FP 28Mhz
User avatar
flatduckrecords
Manic Miner
Posts: 933
Joined: Thu May 07, 2020 11:47 am
Location: Oban, Scotland
Contact:

Re: ZX Spectrum Raytracer

Post by flatduckrecords »

The sources are listed in the article but here's a .tap file I made if anyone else wants to try it out:

zxrt.tap
User avatar
ZXDunny
Manic Miner
Posts: 542
Joined: Tue Nov 14, 2017 3:45 pm

Re: ZX Spectrum Raytracer

Post by ZXDunny »

320x192, 8bpp in SpecBAS:

Image
Xela
Dizzy
Posts: 76
Joined: Tue Apr 18, 2023 8:17 am

Re: ZX Spectrum Raytracer

Post by Xela »

ZXDunny wrote: Fri Jan 26, 2024 12:15 pm 320x192, 8bpp in SpecBAS:
Can I ask you for the program in an adapted form for specbas? The copypaste method did not work for me. Apart from the BRIGHT 1 error, which was clearly highlighted, there is something else preventing it from running.
User avatar
ZXDunny
Manic Miner
Posts: 542
Joined: Tue Nov 14, 2017 3:45 pm

Re: ZX Spectrum Raytracer

Post by ZXDunny »

Sure :)

Code: Select all

2 origin flip: PAPER 0: INK 7: CLS : let TME=MSECS: LET SW=SCRW/2: LET SH=SCRH/2: GO SUB 8000: GO SUB 7000: DIM C(64): DIM L(64): LET DZ=(ScrW/800)*2: FOR X=0 TO scrw-1 STEP 8: FOR Y=0 TO scrh-1 STEP 8
40 LET DX=(X-SW)/256: LET DY=(Y-SH)/256: GO SUB 1000: LET CTL=PC: LET LTL=PL: LET DX=(X-SW+7)/256: GO SUB 1000: LET CTR=PC: LET LTR=PL: LET DY=(Y-SH+7)/256: GO SUB 1000: LET CBR=PC: LET LBR=PL: LET DX=(X-SW)/256: GO SUB 1000: LET CBL=PC: LET LBL=PL
51 IF CTL=0 AND CTR=0 AND CBR=0 AND CBL=0 THEN GO TO 500
111 LET CI=1: DIM A(8): LET PL=0: FOR U=X TO X+7: LET DX=(U-SW)/256: FOR V=Y TO Y+7: IF CI=1 THEN LET PC=CTL: LET PL=LTL: GO TO 160
141 IF CI=8 THEN LET PC=CBL: LET PL=LBL: GO TO 160
142 IF CI=57 THEN LET PC=CTR: LET PL=LTR: GO TO 160
143 IF CI=64 THEN LET PC=CBR: LET PL=LBR: GO TO 160
150 LET DY=(V-SH)/256: GO SUB 1000
160 LET A(PC+1)=A(PC+1)+1: LET C(CI)=PC: LET L(CI)=PL: LET CI=CI+1: NEXT V: NEXT U: LET MFC=0: FOR C=2 TO 8: IF A(C)>MFC THEN LET MFC=A(C): LET MFI=C
204 NEXT C: LET FC=MFI-1: INK FC
301 LET CI=1: FOR U=X TO X+7: FOR V=Y TO Y+7: IF C(CI)>0 AND H(CI)<=L(CI) THEN PLOT U,V
325 LET CI=CI+1: NEXT V: NEXT U
500 NEXT Y: GO SUB 3000: PRINT AT 0,0; INK 7;(msecs-TME)/1000: NEXT X: STOP
1000 LET MT=1E10: LET A=2*(DX*DX+DY*DY+DZ*DZ): FOR S=1 TO NS: LET B=2*(DX*S(S,1)+DY*S(S,2)+DZ*S(S,3)): LET C=(S(S,1)*S(S,1)+S(S,2)*S(S,2)+S(S,3)*S(S,3))-S(S,4): LET D=B*B-2*A*C: IF D<0 THEN GO TO 1500
1231 LET D=SQR (D): LET T=(B+D)/A: IF T>0 AND T<MT THEN LET PC=S(S,5): LET MT=T: LET CS=S
1250 LET T=(B-D)/A: IF T>0 AND T<MT THEN LET PC=S(S,5): LET MT=T: LET CS=S
1500 NEXT S: IF MT=1E10 THEN LET PC=0: RETURN
1600 LET IX=DX*MT: LET IY=DY*MT: LET IZ=DZ*MT: LET NX=IX-S(CS,1): LET NY=IY-S(CS,2): LET NZ=IZ-S(CS,3): LET PL=AI: GO SUB 2100: IF H=1 THEN RETURN
1615 LET NL=(NX*LX+NY*LY+NZ*LZ): IF NL>0 THEN LET PL=PL+DI*NL/SQR (NX*NX+NY*NY+NZ*NZ)
2000 RETURN
2100 LET A=2*(LX*LX+LY*LY+LZ*LZ): FOR S=1 TO NS: LET CX=IX-S(S,1): LET CY=IY-S(S,2): LET CZ=IZ-S(S,3): LET B=-2*(CX*LX+CY*LY+CZ*LZ): LET C=(CX*CX+CY*CY+CZ*CZ)-S(S,4): LET D=B*B-2*A*C: IF D<0 THEN GO TO 2210
2160 LET D=SQR (D): LET T=(B+D)/A: IF T>0.01 THEN LET H=1: RETURN
2190 LET T=(B-D)/A: IF T>0.01 THEN LET H=1: RETURN
2210 NEXT S: LET H=0: RETURN
3000 RETURN
7000 DIM H(64): RESTORE 7100: FOR I=1 TO 64: READ H(I): LET H(I)=H(I)/64: NEXT I: RETURN
7100 DATA 0,32,8,40,2,34,10,42
7101 DATA 48,16,56,24,50,18,58,26
7102 DATA 12,44,4,36,14,46,6,38
7103 DATA 60,28,52,20,62,30,54,22
7104 DATA 3,35,11,43,1,33,9,41
7105 DATA 51,19,59,27,49,17,57,25
7106 DATA 15,47,7,39,13,45,5,37
7107 DATA 63,31,55,23,61,29,53,21
8000 LET LX=-1/SQR (2): LET LY=1/SQR (2): LET LZ=0: LET AI=0.075: LET DI=1-AI: RESTORE 9000: READ NS: DIM S(NS,5): FOR S=1 TO NS: FOR I=1 TO 5: READ S(S,I): NEXT I: NEXT S: RETURN
9000 DATA 4
9001 DATA 0,-1,4,1,2
9002 DATA 2,0,4,1,1
9003 DATA -2,0,4,1,4
9004 DATA 0,-5001,0,5000^2,6
It's been updated for varying resolutions, and added ORIGIN FLIP to get the graphics upside-down.
Xela
Dizzy
Posts: 76
Joined: Tue Apr 18, 2023 8:17 am

Re: ZX Spectrum Raytracer

Post by Xela »

ZXDunny wrote: Fri Jan 26, 2024 1:49 pm Sure :)

It's been updated for varying resolutions, and added ORIGIN FLIP to get the graphics upside-down.
I seem to be doing something wrong... :)

I copied the text, save it to a file, tried to load it into SpecBAS, got error 31 LOAD failed, 0:1

I tried to copy and paste into SpecBAS editor, I choose RUN from the menu, I get this window:
Image

and that's it...

Looks like it's time to start reading the manual :D
User avatar
ZXDunny
Manic Miner
Posts: 542
Joined: Tue Nov 14, 2017 3:45 pm

Re: ZX Spectrum Raytracer

Post by ZXDunny »

Xela wrote: Fri Jan 26, 2024 2:01 pm I seem to be doing something wrong... :)

I copied the text, save it to a file, tried to load it into SpecBAS, got error 31 LOAD failed, 0:1

I tried to copy and paste into SpecBAS editor, I choose RUN from the menu, I get this window:
Your version of SpecBAS is too old. Grab a new executable from here: https://github.com/ZXDunny/SpecBAS/blob ... pecBAS.exe and replace your exe with that one.
User avatar
g0blinish
Manic Miner
Posts: 303
Joined: Sun Jun 17, 2018 2:54 pm

Re: ZX Spectrum Raytracer

Post by g0blinish »

BasinC:
Image
User avatar
g0blinish
Manic Miner
Posts: 303
Joined: Sun Jun 17, 2018 2:54 pm

Re: ZX Spectrum Raytracer

Post by g0blinish »

oops, wrong source

Image
User avatar
Pobulous
Dynamite Dan
Posts: 1592
Joined: Wed Nov 15, 2017 12:51 pm

Re: ZX Spectrum Raytracer

Post by Pobulous »

g0blinish wrote: Fri Jan 26, 2024 2:39 pm oops, wrong source

Image
Still not the final source....
Xela
Dizzy
Posts: 76
Joined: Tue Apr 18, 2023 8:17 am

Re: ZX Spectrum Raytracer

Post by Xela »

ZXDunny wrote: Fri Jan 26, 2024 2:22 pm Grab a new executable from here
Thanx! Now it's working!
ggambetta
Drutt
Posts: 1
Joined: Mon Jan 29, 2024 8:41 am

Re: ZX Spectrum Raytracer

Post by ggambetta »

Well hello there! I wrote the raytracer, and I'm beyond flattered that you guys found it interesting enough to play around with it :)

I've been toying with different ways to improve the attribute clash even more, here's as far as I got:

Image

What it does is computing the average intensity of the two most frequent colors in each 8x8 block. If both are "bright", it PLOTs all the pixels, in either color. If one is "dark" and one is "bright", it does ordered dithering of the "bright" one. If both are "dark", it does ordered dithering of the most frequent one.

Works decently well, but the tradeoff is that the dark areas of the image lose some "light intensity resolution" (i.e. areas that should be ordered-dithered look all black instead).

I'd appreciate any ideas :)
User avatar
bluespikey
Dynamite Dan
Posts: 1138
Joined: Tue Jun 30, 2020 3:54 pm

Re: ZX Spectrum Raytracer

Post by bluespikey »

ggambetta wrote: Mon Jan 29, 2024 8:46 am
I'd appreciate any ideas :)
A colourised Tau Ceti would be grand :)
Wall_Axe
Manic Miner
Posts: 505
Joined: Mon Nov 13, 2017 11:13 pm

Re: ZX Spectrum Raytracer

Post by Wall_Axe »

It looks very good. Are other shapes available like oblongs, can spheres occupy the same space to create new shapes like egg shapes?
User avatar
ParadigmShifter
Dynamite Dan
Posts: 1779
Joined: Sat Sep 09, 2023 4:55 am

Re: ZX Spectrum Raytracer

Post by ParadigmShifter »

+1 for oblong, my favourite shape name. I think you mean oblongoids though?
User avatar
flatduckrecords
Manic Miner
Posts: 933
Joined: Thu May 07, 2020 11:47 am
Location: Oban, Scotland
Contact:

Re: ZX Spectrum Raytracer

Post by flatduckrecords »

Wall_Axe wrote: Fri Feb 02, 2024 8:57 pm It looks very good. Are other shapes available like oblongs, can spheres occupy the same space to create new shapes like egg shapes?
@ggambetta’s book Computer Graphics from Scratch explains how it all works but here’s a snippet from section one:
We could choose any arbitrary geometric primitive as the building block of our scenes; for raytracing, we’ll use spheres because they’re easy to manipulate with equations.
Part 1, Section 1, Basic Raytracing
User avatar
ParadigmShifter
Dynamite Dan
Posts: 1779
Joined: Sat Sep 09, 2023 4:55 am

Re: ZX Spectrum Raytracer

Post by ParadigmShifter »

Well it's all parametric rather than polygons so they could have had more variety.

Oblongoids, Cylinders, Cones and Tori are all popular. Tori are a bit gnarly working out intersections though IIRC.
C.Born
Manic Miner
Posts: 368
Joined: Sat Dec 09, 2017 4:09 pm

Re: ZX Spectrum Raytracer

Post by C.Born »

ggambetta wrote: Mon Jan 29, 2024 8:46 am Well hello there! I wrote the raytracer, and I'm beyond flattered that you guys found it interesting enough to play around with it :)

I've been toying with different ways to improve the attribute clash even more, here's as far as I got:

Image

What it does is computing the average intensity of the two most frequent colors in each 8x8 block. If both are "bright", it PLOTs all the pixels, in either color. If one is "dark" and one is "bright", it does ordered dithering of the "bright" one. If both are "dark", it does ordered dithering of the most frequent one.

Works decently well, but the tradeoff is that the dark areas of the image lose some "light intensity resolution" (i.e. areas that should be ordered-dithered look all black instead).

I'd appreciate any ideas :)
Hi, if the timing is importend you should 0 the TIME by POKE 23672,0: POKE 23673,0: POKE 23674,0 just before you start the real calculation
btw, if you set your GO SUBS at the beginning of the whole program they are found quicker. meaning LINE 1000 should be LINE 10
and presetting al variables is best done first indeed, but at the back of the memory meaning the invoking off the variables is best done in LINE 9900 eg with a GO TO 1 to move to the start of the program
do you have a version 4 ?
i look at the rendering of version 3 now

EDIT
he, you have 5 versions already
https://gabrielgambetta.com/zx-raytracer-5-src.html
all above comments still valid,
AND removing all EXTRA S P A C E S will speed up aswell, since ZX Basic is "live decoded" meaning every CHR$ is checked in every loop again !!
C.Born
Manic Miner
Posts: 368
Joined: Sat Dec 09, 2017 4:09 pm

Re: ZX Spectrum Raytracer

Post by C.Born »

ZXDunny wrote: Fri Jan 26, 2024 1:49 pm Sure :)

Code: Select all

2 origin flip: PAPER 0: INK 7: CLS : let TME=MSECS: LET SW=SCRW/2: LET SH=SCRH/2: GO SUB 8000: GO SUB 7000: DIM C(64): DIM L(64): LET DZ=(ScrW/800)*2: FOR X=0 TO scrw-1 STEP 8: FOR Y=0 TO scrh-1 STEP 8
40 LET DX=(X-SW)/256: LET DY=(Y-SH)/256: GO SUB 1000: LET CTL=PC: LET LTL=PL: LET DX=(X-SW+7)/256: GO SUB 1000: LET CTR=PC: LET LTR=PL: LET DY=(Y-SH+7)/256: GO SUB 1000: LET CBR=PC: LET LBR=PL: LET DX=(X-SW)/256: GO SUB 1000: LET CBL=PC: LET LBL=PL
51 IF CTL=0 AND CTR=0 AND CBR=0 AND CBL=0 THEN GO TO 500
111 LET CI=1: DIM A(8): LET PL=0: FOR U=X TO X+7: LET DX=(U-SW)/256: FOR V=Y TO Y+7: IF CI=1 THEN LET PC=CTL: LET PL=LTL: GO TO 160
141 IF CI=8 THEN LET PC=CBL: LET PL=LBL: GO TO 160
142 IF CI=57 THEN LET PC=CTR: LET PL=LTR: GO TO 160
143 IF CI=64 THEN LET PC=CBR: LET PL=LBR: GO TO 160
150 LET DY=(V-SH)/256: GO SUB 1000
160 LET A(PC+1)=A(PC+1)+1: LET C(CI)=PC: LET L(CI)=PL: LET CI=CI+1: NEXT V: NEXT U: LET MFC=0: FOR C=2 TO 8: IF A(C)>MFC THEN LET MFC=A(C): LET MFI=C
204 NEXT C: LET FC=MFI-1: INK FC
301 LET CI=1: FOR U=X TO X+7: FOR V=Y TO Y+7: IF C(CI)>0 AND H(CI)<=L(CI) THEN PLOT U,V
325 LET CI=CI+1: NEXT V: NEXT U
500 NEXT Y: GO SUB 3000: PRINT AT 0,0; INK 7;(msecs-TME)/1000: NEXT X: STOP
1000 LET MT=1E10: LET A=2*(DX*DX+DY*DY+DZ*DZ): FOR S=1 TO NS: LET B=2*(DX*S(S,1)+DY*S(S,2)+DZ*S(S,3)): LET C=(S(S,1)*S(S,1)+S(S,2)*S(S,2)+S(S,3)*S(S,3))-S(S,4): LET D=B*B-2*A*C: IF D<0 THEN GO TO 1500
1231 LET D=SQR (D): LET T=(B+D)/A: IF T>0 AND T<MT THEN LET PC=S(S,5): LET MT=T: LET CS=S
1250 LET T=(B-D)/A: IF T>0 AND T<MT THEN LET PC=S(S,5): LET MT=T: LET CS=S
1500 NEXT S: IF MT=1E10 THEN LET PC=0: RETURN
1600 LET IX=DX*MT: LET IY=DY*MT: LET IZ=DZ*MT: LET NX=IX-S(CS,1): LET NY=IY-S(CS,2): LET NZ=IZ-S(CS,3): LET PL=AI: GO SUB 2100: IF H=1 THEN RETURN
1615 LET NL=(NX*LX+NY*LY+NZ*LZ): IF NL>0 THEN LET PL=PL+DI*NL/SQR (NX*NX+NY*NY+NZ*NZ)
2000 RETURN
2100 LET A=2*(LX*LX+LY*LY+LZ*LZ): FOR S=1 TO NS: LET CX=IX-S(S,1): LET CY=IY-S(S,2): LET CZ=IZ-S(S,3): LET B=-2*(CX*LX+CY*LY+CZ*LZ): LET C=(CX*CX+CY*CY+CZ*CZ)-S(S,4): LET D=B*B-2*A*C: IF D<0 THEN GO TO 2210
2160 LET D=SQR (D): LET T=(B+D)/A: IF T>0.01 THEN LET H=1: RETURN
2190 LET T=(B-D)/A: IF T>0.01 THEN LET H=1: RETURN
2210 NEXT S: LET H=0: RETURN
3000 RETURN
7000 DIM H(64): RESTORE 7100: FOR I=1 TO 64: READ H(I): LET H(I)=H(I)/64: NEXT I: RETURN
7100 DATA 0,32,8,40,2,34,10,42
7101 DATA 48,16,56,24,50,18,58,26
7102 DATA 12,44,4,36,14,46,6,38
7103 DATA 60,28,52,20,62,30,54,22
7104 DATA 3,35,11,43,1,33,9,41
7105 DATA 51,19,59,27,49,17,57,25
7106 DATA 15,47,7,39,13,45,5,37
7107 DATA 63,31,55,23,61,29,53,21
8000 LET LX=-1/SQR (2): LET LY=1/SQR (2): LET LZ=0: LET AI=0.075: LET DI=1-AI: RESTORE 9000: READ NS: DIM S(NS,5): FOR S=1 TO NS: FOR I=1 TO 5: READ S(S,I): NEXT I: NEXT S: RETURN
9000 DATA 4
9001 DATA 0,-1,4,1,2
9002 DATA 2,0,4,1,1
9003 DATA -2,0,4,1,4
9004 DATA 0,-5001,0,5000^2,6
It's been updated for varying resolutions, and added ORIGIN FLIP to get the graphics upside-down.
Hi i modded yr mod a tinybit to make it independent from specbas or basinc.
i replaced the MSECS to the DEF FN t()=PEEK 23674*65536+PEEK 23673*256+PEEK 23672
and i re-replaced the compiler-variables with the LET statement.
I was thinking about the screenflip , 175-y usualy does the job. maybe i look for it.
and the subroutine at first for speed...
so, nothing new here. just "emulator compiler compatible"
cheers!

Code: Select all

 1 RUN 9100
10 LET MT=1E10: LET A=2*(DX*DX+DY*DY+DZ*DZ): FOR S=1 TO NS: LET B=2*(DX*S(S,1)+DY*S(S,2)+DZ*S(S,3)): LET C=(S(S,1)*S(S,1)+S(S,2)*S(S,2)+S(S,3)*S(S,3))-S(S,4): LET D=B*B-2*A*C: IF D<0 THEN GO TO 13
11 LET D=SQR (D): LET T=(B+D)/A: IF T>0 AND T<MT THEN LET PC=S(S,5): LET MT=T: LET CS=S
12 LET T=(B-D)/A: IF T>0 AND T<MT THEN LET PC=S(S,5): LET MT=T: LET CS=S
13 NEXT S: IF MT=1E10 THEN LET PC=0: RETURN
14 LET IX=DX*MT: LET IY=DY*MT: LET IZ=DZ*MT: LET NX=IX-S(CS,1): LET NY=IY-S(CS,2): LET NZ=IZ-S(CS,3): LET PL=AI: GO SUB 17: IF H=1 THEN RETURN
15 LET NL=(NX*LX+NY*LY+NZ*LZ): IF NL>0 THEN LET PL=PL+DI*NL/SQR (NX*NX+NY*NY+NZ*NZ)
16 RETURN
17 LET A=2*(LX*LX+LY*LY+LZ*LZ): FOR S=1 TO NS: LET CX=IX-S(S,1): LET CY=IY-S(S,2): LET CZ=IZ-S(S,3): LET B=-2*(CX*LX+CY*LY+CZ*LZ): LET C=(CX*CX+CY*CY+CZ*CZ)-S(S,4): LET D=B*B-2*A*C: IF D<0 THEN GO TO 21
18 LET D=SQR (D): LET T=(B+D)/A: IF T>0.01 THEN LET H=1: RETURN
19 LET T=(B-D)/A: IF T>0.01 THEN LET H=1: RETURN
21 NEXT S: LET H=0: RETURN

39 FOR X=0 TO scrw-1 STEP 8: FOR Y=0 TO scrh-1 STEP 8
40 LET DX=(X-SW)/256: LET DY=(Y-SH)/256: GO SUB 10: LET CTL=PC: LET LTL=PL: LET DX=(X-SW+7)/256: GO SUB 10: LET CTR=PC: LET LTR=PL: LET DY=(Y-SH+7)/256: GO SUB 10: LET CBR=PC: LET LBR=PL: LET DX=(X-SW)/256: GO SUB 10: LET CBL=PC: LET LBL=PL
51 IF CTL=0 AND CTR=0 AND CBR=0 AND CBL=0 THEN GO TO 500
111 LET CI=1: DIM A(8): LET PL=0: FOR U=X TO X+7: LET DX=(U-SW)/256: FOR V=Y TO Y+7: IF CI=1 THEN LET PC=CTL: LET PL=LTL: GO TO 160
141 IF CI=8 THEN LET PC=CBL: LET PL=LBL: GO TO 160
142 IF CI=57 THEN LET PC=CTR: LET PL=LTR: GO TO 160
143 IF CI=64 THEN LET PC=CBR: LET PL=LBR: GO TO 160
150 LET DY=(V-SH)/256: GO SUB 10
160 LET A(PC+1)=A(PC+1)+1: LET C(CI)=PC: LET L(CI)=PL: LET CI=CI+1: NEXT V: NEXT U: LET MFC=0: FOR C=2 TO 8: IF A(C)>MFC THEN LET MFC=A(C): LET MFI=C
204 NEXT C: LET FC=MFI-1: INK FC
301 LET CI=1: FOR U=X TO X+7: FOR V=Y TO Y+7: IF C(CI)>0 AND H(CI)<=L(CI) THEN PLOT U,V
325 LET CI=CI+1: NEXT V: NEXT U
500 NEXT Y: PRINT AT 0,0; INK 7;(FN t()-TME)/1000: NEXT X: STOP

7000 DIM H(64): RESTORE 7100: FOR I=1 TO 64: READ H(I): LET H(I)=H(I)/64: NEXT I
7100 DATA 0,32,8,40,2,34,10,42
7101 DATA 48,16,56,24,50,18,58,26
7102 DATA 12,44,4,36,14,46,6,38
7103 DATA 60,28,52,20,62,30,54,22
7104 DATA 3,35,11,43,1,33,9,41
7105 DATA 51,19,59,27,49,17,57,25
7106 DATA 15,47,7,39,13,45,5,37
7107 DATA 63,31,55,23,61,29,53,21
8000 LET LX=-1/SQR (2): LET LY=1/SQR (2): LET LZ=0: LET AI=0.075: LET DI=1-AI: RESTORE 9000: READ NS: DIM S(NS,5): FOR S=1 TO NS: FOR I=1 TO 5: READ S(S,I): NEXT I: NEXT S: RETURN
9000 DATA 4
9001 DATA 0,-1,4,1,2
9002 DATA 2,0,4,1,1
9003 DATA -2,0,4,1,4
9004 DATA 0,-5001,0,5000^2,6

9101 LET SCRW=255: LET SCRH=175: DEF FN t()=PEEK 23674*65536+PEEK 23673*256+PEEK 23672
9102 BORDER 0: PAPER 0: INK 7: CLS : LET TME=FN t(): LET SW=SCRW/2: LET SH=SCRH/2: GO SUB 7000: DIM C(64): DIM L(64): LET DZ=(ScrW/800)*2
9110 GO TO 39
Post Reply