SCREEN 13
TYPE vec3
x AS SINGLE
y AS SINGLE
z AS SINGLE
END TYPE
DIM cam AS vec3, ctr AS vec3, ctn AS vec3
DIM lpt AS vec3, lno AS vec3, ltn AS vec3
DIM nor AS vec3, dir AS vec3
DIM ref AS vec3, pln AS vec3
SetPal
dir.x = 2
dir.y = 2
dir.z = 0
normvec3 dir
pln.y = -4
ctr.x = 0
ctr.y = 0
ctr.z = 16
r = 3
speed = 1 / 30
WHILE 1
lpt.x = 8 * COS(move * speed)
lpt.y = 1
lpt.z = 9
ctr.y = ABS(r * COS(move * speed)) + pln.y + r
FOR y = 100 TO -99 STEP -1
FOR x = -160 TO 160
sx = x + 160
sy = 100 - y
cam.x = x / 200
cam.y = y / 200
cam.z = 1
t = intersec(cam, ctr, r)
IF t > 0 AND cam.y * t > pln.y THEN
mul3vec cam, t
sub3vec nor, cam, ctr
sub3vec lno, lpt, cam
mul3vec cam, -1
normvec3 nor
normvec3 cam
normvec3 lno
refl = 2 * mul3(cam, nor)
ref.x = refl * nor.x - cam.x
ref.y = refl * nor.y - cam.y
ref.z = refl * nor.z - cam.z
normvec3 ref
ldir = mul3(nor, dir): IF ldir < 0 THEN ldir = 0
lspe = mul3(ref, lno): IF lspe < 0 THEN lspe = 0 ELSE lspe = lspe ^ 7
lv = ldir * .8 + lspe * .5
IF lv < 0 THEN lv = 0
IF lv > 1 THEN lv = 1
PSET (sx, sy), lv * 63 + 64
ELSE
IF y < 0 THEN
IF cam.y = 0 THEN cam.y = 1
pln.z = pln.y / cam.y
pln.x = cam.x * pln.z
u = INT(pln.x)
v = INT(pln.z)
c = ((v + move) XOR (u + 16)) AND 63
c = 16 * c / pln.z
IF c > 63 THEN c = 63
sub3vec ctn, ctr, pln
sub3vec ltn, lpt, pln
t = intersec(ltn, ctn, r)
IF t > 0 THEN c = c \ 2
PSET (sx, sy), 64 + c
ELSE
PSET (sx, sy), 0
END IF
END IF
NEXT
NEXT
move = move + 1
WEND
FUNCTION intersec (cam AS vec3, ctr AS vec3, r AS SINGLE)
a = mul3(cam, cam)
b = -mul3(cam, ctr) * 2
c = mul3(ctr, ctr) - r ^ 2
d = b ^ 2 - 4 * a * c
t = 0
IF d >= 0 THEN
d = SQR(d)
t1 = (-b - d) / (2 * a)
t2 = (-b + d) / (2 * a)
IF t1 < 0 AND t2 < 0 THEN t = -1
IF t1 < 0 AND t2 > 0 THEN t = t2
IF t1 > 0 AND t2 < 0 THEN t = t1
IF t1 > 0 AND t2 > 0 THEN
IF t1 < t2 THEN t = t1 ELSE t = t2
END IF
END IF
intersec = t
END FUNCTION
FUNCTION length (a AS vec3)
length = SQR(mul3(a, a))
END FUNCTION
FUNCTION mul3 (a AS vec3, b AS vec3)
mul3 = a.x * b.x + a.y * b.y + a.z * b.z
END FUNCTION
SUB mul3vec (v AS vec3, k AS SINGLE)
v.x = v.x * k
v.y = v.y * k
v.z = v.z * k
END SUB
SUB sub3vec (c AS vec3, a AS vec3, b AS vec3)
c.x = a.x - b.x
c.y = a.y - b.y
c.z = a.z - b.z
END SUB
SUB normvec3 (v AS vec3)
mul3vec v, 1 / length(v)
END SUB
SUB SetPal
FOR i = 0 TO 63
OUT 968, i + 64
OUT 969, i
OUT 969, i
OUT 969, i
NEXT
END SUB