### 1. 3D prototypes

```--------------77257F0331B

I've modofied Mr. Honnor's 3D prototype and speed it up by nearly a
frame per second. Unfortunately, it seems to be his algorithm
(perspecive correction every pixel!) which runs slowly.

Matt Sephton
--
u5ms at csc.liv.ac.uk
http://www.csc.liv.ac.uk/~u5ms/

--------------77257F0331B
Content-Disposition: inline; filename="ancients.ex"

-- Hi, I've signalled some optimisations you may be interested in for your
-- proper game if it uses similar code to this example. They are preceded by
--MS:
-- Time this .ex by pressing escape after a full 'cycle', or run the original
-- then run my modified version

-- INCLUDE FILES
without type_check
include graphics.e
include image.e
--include machine.e --dont need these yet!
--include mouse.e
--include ratbag.e

-- CONSTANTS

--doesn't use trig for perspective,
--but will soon use trig for rotation.

--constant pi  = 3.141592654
constant X   = 1
constant Y   = 2

-- VARIABLES

atom count
atom t
atom pos
atom key
object junk
sequence map
sequence sky
sequence page
sequence vp
--
count=0
t=time()
pos=1
key=-1
map = (repeat(repeat(2,100),100))
for hx = 1 to 100 do
for hy = 1 to 100 do
if rand(50)=1 then
map[hx][hy]=1
end if
end for
end for
page={1,0}
vp={159,99}
map[20][20]=1
map[21][20]=1
map[22][20]=1
map[23][20]=1
map[24][20]=1
map[20][21]=1
map[21][21]=1
map[22][21]=1
map[23][21]=1
map[21][22]=1
map[22][22]=1
for hx = 2 to 99 do
for hy = 2 to 99 do
if map[hx][hy]=1 then
--if map[hx][hy+1] !=1 then
--map[hx][hy+1]=0
--end if
--if map[hx][hy-1] !=1 then
--map[hx][hy-1]=0
--end if
--if map[hx-1][hy] !=1 then
--map[hx-1][hy]=0
--end if
--if map[hx+1][hy] !=1 then
--map[hx+1][hy]=0
--end if
--MS:
map[hx][hy+1]= (map[hx][hy+1] = 1)
map[hx][hy-1]= (map[hx][hy-1] = 1)
map[hx-1][hy]= (map[hx-1][hy] = 1)
map[hx+1][hy]= (map[hx+1][hy] = 1)
end if
end for
end for

-- FUNCTIONS
procedure pause()
while get_key()=-1 do end while
end procedure

function even(atom x)
--if floor(x/2)=x/2 then
--return 1
--else
--return 0
--end if
--MS:
return floor(x/2)=x/2
end function

function ch(atom c , atom x , atom y)
--if c=2 and even(x+y)then
--c=15
--end if
--return c
--MS:
if c=2 then
if even(x+y) then
c=15
end if
end if
return c
end function

function pers(atom pointx , atom pointy)
sequence point2
point2={pointx,pointy}
point2[X]=point2[X]-vp[X]
--point2[X]=(point2[X]*2)/((point2[Y]*2)/vp[X]+1)
--MS:
point2[X]=point2[X]*2/(point2[Y]*2/vp[X]+1)
point2[X]=point2[X]+vp[X]
point2[Y]=point2[Y]/(point2[Y]/vp[Y]+1)
return {point2[X],199-point2[Y]}
end function

procedure screen()
--Note?
--is multiply by 16 possible by bitwise shift? ask mailing list.
--MS:
integer x16, y16

junk=page[2]
page[2]=page[1]
page[1]=junk
set_active_page(page[1])
set_display_page(page[2])
display_image({0,0},sky)
for x = -15 to 35 do
for y = 20 to 1 by -1 do
if x+y >5 and x-y <16 and map[x+16][y+pos] !=1 then
--polygon(ch(map[x+16][y+pos],x+16,y+pos),1,
--{   pers(x*16-16,y*16-16),  pers(x*16,y*16-16),
--pers(x*16,y*16),        pers(x*16-16,y*16)})
--MS: x*16 and y*16 now only computed once, maybe even better when bitwise?
x16 = x*16
y16 = y*16
polygon(ch(map[x+16][y+pos],x+16,y+pos),1,
{   pers(x16-16,y16-16),  pers(x16,y16-16),
pers(x16,y16),        pers(x16-16,y16)})
end if
end for
end for
end procedure

-- SETUP

junk = graphics_mode(13)
junk = palette(2,{0,35,0})
junk = palette(15,{0,25,0})
junk = palette(14,{0,0,40})
junk = palette(1,{0,0,55})
for w = 0 to 13 do
--junk=palette(13-w,{0,w*2,w*6})
--MS:
junk=palette(13-w,{0,w+w,w*6})
end for
sky=repeat(repeat(0,320),200)
junk = palette(0,{40,30,0})
for w = 1 to 200 do
sky[w]=repeat(floor(w/20)+3,320)
end for

set_active_page(page[1])
set_display_page(page[2])

-- PROGRAM

display_image({0,0},sky)

t=time()

while key != 27 do
key = get_key()
pos = pos+1
screen()
if pos=80 then
pos=1
end if
count=count+1
end while
junk=graphics_mode(-1)
printf(1,"%.2f",count/(time()-t))
puts(1," Frames Per Second\nHit A Key!")
pause()

--------------77257F0331B--
```