#INCLUDE "maths.module" #INCLUDE "const.inc" #INCLUDE "prots.inc" PROC ring ( CHAN OF RING toRing, fromRing, CHAN OF polyChan toRenderer, fromRenderer, CHAN OF BYTES joyStick, CHAN OF BYTE toJoystick, VAL INT playerId, playerHasScreen, myType ) VAL maxTrees IS 12 : -- descope library def [maxTrees][ b.boundSize] INT boundBox : [maxPolys * (6 * 4) ] INT externalP : [ 2 * maxPolys ] INT externalStack : PROC buildBoxes ( CHAN OF polyChan mainIn, orderedOut, --[maxTrees][p.polySize * maxPolys] INT polyStore, CHAN OF polyChan toRinger ) --[16]REAL32 trans : -- buffer VAL NIL IS -15 : -- arbritrary value, invalid tree pointer VAL true IS 1 : VAL false IS 0 : -- for eliminate back faces field VAL maxPatches IS 4 : [maxPatches][2] INT patches : INT nPatches : [maxTrees]INT starter : PROC storePoly ( INT treesCreated ) -- here all of the polygon defs are stored, ready to be passed -- to the main process to build the BSP tree PROC getABCD ([4]REAL32 ABCD, VAL [3][4]REAL32 XYZW) a IS ABCD[0] : b IS ABCD[1] : c IS ABCD[2] : d IS ABCD[3] : REAL32 x1,x2,x3,y1,y2,y3,z1,z2,z3: SEQ VAL [4]REAL32 xyzw IS XYZW[0] : SEQ x1 := xyzw[0] y1 := xyzw[1] z1 := xyzw[2] VAL [4]REAL32 xyzw IS XYZW[1] : SEQ x2 := xyzw[0] y2 := xyzw[1] z2 := xyzw[2] VAL [4]REAL32 xyzw IS XYZW[2] : SEQ x3 := xyzw[0] y3 := xyzw[1] z3 := xyzw[2] a := (y1 * (z2-z3)) a := a + (y2*(z3-z1)) a := a + (y3*(z1-z2)) b := (z1*(x2-x3)) b := b + ((z2*(x3-x1)) + (z3*(x1-x2))) c := (x1*(y2-y3)) c := c + ((x2*(y3-y1)) + (x3*(y1-y2))) d := (-x1) * ((y2*z3) - (y3*z2)) d := d - ( x2 * ((y3*z1) - (y1*z3)) ) d := d - ( x3 * ((y1*z2) - (y2*z1)) ) : PROC getPolys(CHAN OF polyChan in, INT noPolys, []INT polyStore, INT start) --input polygons, and create linked list INT last : SEQ in ? CASE c.nPoly ; noPolys SEQ i = 0 FOR noPolys INT len : p IS [polyStore FROM start FOR p.polySize] : SEQ last := start + p.nextOffset in ? CASE c.poly ; len::p iabcd IS [p FROM p.ABCD FOR 4] : [4]REAL32 abcd RETYPES iabcd : pnt IS [p FROM p.first FOR (3 * 4) ] : [3][4]REAL32 points RETYPES pnt : SEQ getABCD(abcd, points) start := start + p.polySize polyStore [ last] := start -- pointer from previous polyStore [ last] := NIL -- end of list : p IS externalP : INT p.p, polyCol, polys, nextPoly : -- nextPoly is used to point to the next poly in the proper tree -- p.p is used in parsing the tree definition, to create a -- compacted tree. This tree is then traversed, and the correct -- pointers generated PROC addPoly ( VAL [] INT polygon ) SEQ [ p FROM p.p FOR SIZE polygon ] := polygon --polyCol := (polyCol PLUS 3) /\ #FF --p [p.p + 1] := polyCol p.p := p.p + (SIZE polygon) p [0] := p [0] + 1 polys := polys + 1 nextPoly := nextPoly + p.polySize --polys * p.polySize : INT rotorOffset, tailOffset, gunAoffset, gunBoffset : [8] INT rotorLocation, tailLocation, gunAlocation, gunBlocation : PROC createChopper () VAL pol IS p.polySize : VAL ox IS 65 : VAL a IS 0: VAL b IS 1: VAL c IS 2: VAL d IS 3: VAL tail0 IS 4: VAL tail1 IS 5: VAL tail2 IS 6: VAL tail3 IS 7: VAL tail4 IS 8: VAL bod0 IS 9 : VAL bod1 IS 10 : VAL bod2 IS 11 : VAL bod3 IS 12 : VAL bod4 IS 13 : VAL bod5 IS 14 : VAL bod6 IS 15 : VAL r00 IS 16: VAL r01 IS 17 : SEQ p [0] := 0 p.p := 1 polys := 0 -- nextPoly := 0 addPoly ( [ 4, 86, ox-105, -10, -20, 1, ox-105, -15, -20, 1, ox-45, -15, -20, 1, ox-45, -10, -20, 1, pol * b, NIL, NIL, NIL, true ] ) addPoly ( [ 3, 86, ox-110, -10, -15, 1, ox-105, -15, -20, 1, ox-105, -10, -20, 1, pol * c, NIL, NIL, NIL, true ] ) addPoly ( [ 4, 86, ox-45, 10, -20, 1, ox-45, 15, -20, 1, ox-105, 15, -20, 1, ox-105, 10, -20, 1, pol * d, NIL, NIL, NIL, true ] ) addPoly ( [ 3, 86, ox-105, 10, -20, 1, ox-105, 15, -20, 1, ox-110, 10, -15, 1, rotorOffset, NIL, -- this gets patched ... NIL, NIL, true ] ) rotorOffset := p.frontOffset + (d * pol) -- patch to rotor addPoly ( [ 4, 90, ox+10, 8, 15, 1, ox+10, -8, 15, 1, ox+10, -7, 11, 1, ox+10, 7, 11, 1, NIL, tail1 * pol, NIL, NIL, false ] ) addPoly ( [ 4, 91, ox+10, 8, 15, 1, ox-55, 8, 15, 1, ox-55, -8, 15, 1, ox+ 10, -8, 15, 1, NIL, tail2 * pol, NIL, NIL, false ] ) addPoly ( [ 4, 92, ox+10, 8, 15, 1, ox+10, 7, 11, 1, ox-55, 4, -1, 1, ox-55, 8, 15, 1, NIL, tail3 * pol, NIL, NIL, false ] ) addPoly ( [ 4, 92, ox-55, -8, 15, 1, ox-55, -4, -1, 1, ox+10, -7, 11, 1, ox+10, -8, 15, 1, NIL, tail4 * pol, NIL, NIL, false ] ) addPoly ( [ 4, 93, ox+10, 7, 11, 1, ox+10, -7, 11, 1, ox-55, -4, -1, 1, ox-55, 4, -1, 1, NIL, NIL, NIL, NIL, false ] ) addPoly ( [ 4, 88, ox-55, -10, 15, 1, ox-55, -10, -10, 1, ox-55, 10, -10, 1, ox-55, 10, 15, 1, tailOffset, bod1 * pol, NIL, NIL , false] ) tailOffset := p.frontOffset + (bod0 * pol) -- patch to tail rotor addPoly ( [ 5, 87, ox-55, -10, 15, 1, ox-75, -10, 15, 1, ox-105, -10, 0, 1, ox-95, -10, -15, 1, ox-55, -10, -10, 1, gunAoffset, bod2 * pol, NIL, NIL , false ]) gunAoffset := p.frontOffset + (bod1 * pol) -- patch to gunA addPoly ( [ 5, 87, ox-55, 10, -10, 1, ox-95, 10, -15, 1, ox-105, 10, 0, 1, ox-75, 10, 15, 1, ox-55, 10, 15, 1, gunBoffset, bod3 * pol, NIL, NIL , false ]) gunBoffset := p.frontOffset + (bod2 * pol) -- patch to gunB addPoly ( [ 4, 84, ox-55, -10, 15, 1, ox-55, 10, 15, 1, ox-75, 10, 15, 1, ox-75, -10, 15, 1, NIL, bod4 * pol, NIL, NIL , false ]) addPoly ( [ 4, 84, ox-75, -10, 15, 1, ox-75, 10, 15, 1, ox-105, 10, 0, 1, ox-105, -10, 0, 1, NIL, bod5 * pol, NIL, NIL , false ]) addPoly ( [ 4, 61, ox-105, -10, 0, 1, ox-105, 10, 0, 1, ox-95, 10, -15, 1, ox-95, -10, -15, 1, NIL, bod6 * pol, NIL, NIL , false ]) addPoly ( [ 4, 59, ox-55, 10, -10, 1, ox-55, -10, -10, 1, ox-95, -10, -15, 1, ox-95, 10, -15, 1, NIL, NIL, NIL, NIL , false ]) SEQ i = 0 FOR 8 VAL rotorColour IS 79 : -- 250 : -- (250 + (i * 3)) /\ #FF : [4] INT x, y : SEQ rotorLocation [i] := pol * ((i * 4) + r00) VAL threeDegrees IS 0.666 (REAL32) : VAL r IS 63.0 (REAL32) : REAL32 sinTh, cosTh, theta, rx, ry : SEQ VAL rii IS (REAL32 ROUND i) : VAL ri IS rii + 0.37 (REAL32) : theta := ((ri * 22.5 (REAL32)) * 3.1415926 (REAL32)) / 180.0 (REAL32) sinTh := SIN ( theta ) cosTh := COS ( theta ) rx := r * cosTh x[0] := INT ROUND rx ry := r * sinTh y[0] := INT ROUND ry sinTh := SIN ( theta+threeDegrees ) cosTh := COS ( theta+threeDegrees ) rx := r * cosTh x[1] := INT ROUND rx ry := r * sinTh y[1] := INT ROUND ry theta := theta + 3.1415926 (REAL32) sinTh := SIN ( theta ) cosTh := COS ( theta ) rx := r * cosTh x[2] := INT ROUND rx ry := r * sinTh y[2] := INT ROUND ry sinTh := SIN ( theta+threeDegrees ) cosTh := COS ( theta+threeDegrees ) rx := r * cosTh x[3] := INT ROUND rx ry := r * sinTh y[3] := INT ROUND ry addPoly ( [ 3, rotorColour, ox-65, 0, 25, 1, x[0]+(ox-65), y[0], 25, 1, x[1]+(ox-65), y[1], 25, 1, rotorLocation [i] + pol, bod0 * pol, NIL, NIL , true ] ) addPoly ( [ 3, rotorColour, ox-65, 0, 25, 1, x[2]+(ox-65), y[2], 25, 1, x[3]+(ox-65), y[3], 25, 1, NIL, NIL, NIL, NIL , true ] ) tailLocation [i] := rotorLocation [i] + (pol * 2) VAL threeDegrees IS 0.63 (REAL32) : VAL r IS 13.0 (REAL32) : REAL32 sinTh, cosTh, theta, rx, ry : SEQ VAL rii IS (REAL32 ROUND i) : VAL ri IS rii + 0.47 (REAL32) : theta := ((ri * 45.0 (REAL32)) * 3.1415926 (REAL32)) / 180.0 (REAL32) sinTh := SIN ( theta ) cosTh := COS ( theta ) rx := r * cosTh x[0] := INT ROUND rx ry := r * sinTh y[0] := INT ROUND ry sinTh := SIN ( theta+threeDegrees ) cosTh := COS ( theta+threeDegrees ) rx := r * cosTh x[1] := INT ROUND rx ry := r * sinTh y[1] := INT ROUND ry theta := theta + 3.1415926 (REAL32) sinTh := SIN ( theta ) cosTh := COS ( theta ) rx := r * cosTh x[2] := INT ROUND rx ry := r * sinTh y[2] := INT ROUND ry sinTh := SIN ( theta+threeDegrees ) cosTh := COS ( theta+threeDegrees ) rx := r * cosTh x[3] := INT ROUND rx ry := r * sinTh y[3] := INT ROUND ry addPoly ( [ 3, rotorColour, ox+8, -10, 10, 1, x[0] + (ox+8), -10, y[0] + 10, 1, x[1] + (ox+8), -10, y[1] + 10, 1, NIL, tailLocation [i] + pol, NIL, NIL , true ] ) addPoly ( [ 3, rotorColour, ox+8, -10, 10, 1, x[2] + (ox+8), -10, y[2] + 10, 1, x[3] + (ox+8), -10, y[3] + 10, 1, NIL, tail0 * pol, NIL, NIL , true ] ) VAL g00 IS (32 + r00) : SEQ i = 0 FOR 8 INT ny : SEQ ny := i << 3 gunAlocation[i] := pol * ((i * 2) + g00) addPoly ( [ 4, 13, ox-105, ((-12) - ny), -10, 1, ox-100, ((-12) - ny), -13, 1, ox-80, ((-12) - ny), -9, 1, ox-102, ((-12) - ny), -8, 1, NIL, NIL, NIL, NIL , true ] ) gunBlocation[i] := gunAlocation[i] + pol addPoly ( [ 4, 13, ox-102, 12+ny, -8 , 1, ox-80, 12+ny, -9 , 1, ox-100, 12+ny, -13, 1, ox-105, 12+ny, -10, 1, NIL, NIL, NIL, NIL , true ] ) : PROC createMissile () VAL pol IS p.polySize : VAL ox IS 65 : VAL a IS 0: VAL b IS 1: VAL c IS 2: VAL d IS 3: VAL e IS 4 : SEQ p [0] := 0 p.p := 1 polys := 0 -- nextPoly := 0 addPoly ( [ 4, 10, ox-105, -1, -10, 1, ox-100, -1, -13, 1, ox-80, -1, -9, 1, ox-102, -1, -8, 1, NIL, b * pol, NIL, NIL , true ] ) addPoly ( [ 4, 11, ox-102, 1, -8, 1, ox-80, 1, -9, 1, ox-100, 1, -13, 1, ox-105, 1, -10, 1, NIL, c * pol, NIL, NIL , true ] ) addPoly ( [ 4, 13, ox-102, -1, -8, 1, ox-80, -1, -9, 1, ox-80, 1, -9, 1, ox-102, 1, -8, 1, NIL, d * pol, NIL, NIL , true ] ) addPoly ( [ 4, 12, ox-100, -1, -13, 1, ox-105, -1, -10, 1, ox-105, 1, -10, 1, ox-100, 1, -13, 1, NIL, e * pol, NIL, NIL , true ] ) addPoly ( [ 4, 13, ox-80, -1, -9, 1, ox-80, 1, -9, 1, ox-100, 1, -13, 1, ox-100, -1, -13, 1, NIL, NIL, NIL, NIL , true ] ) : PROC createGround () VAL greens IS [ 19, 53, 24, 28, 22, 52, 27, 55 ] : VAL floorZ IS 0 : VAL pol IS p.polySize : SEQ p [0] := 0 p.p := 1 polys := 0 -- nextPoly := 0 SEQ VAL x IS -1600000 : VAL y IS -1600000 : VAL edge IS 3200000 : addPoly ( [ 4, 21, x, floorZ, y, 1, x+edge, floorZ, y, 1, x+edge, floorZ, y+edge, 1, x, floorZ, y+edge, 1, nextPoly + (65 * pol), NIL, nextPoly + pol, NIL , true ] ) SEQ i = 0 FOR 4 VAL x IS (-1600000) + (800000 * i) : SEQ j = 0 FOR 4 VAL y IS (-1600000) + (800000 * j) : INT colour : SEQ colour := greens [(i+(j TIMES 4)) / 7] SEQ texi = 0 FOR 4 VAL texx IS x + (texi * 200000) : SEQ texj = 0 FOR 4 VAL texy IS y + (texj * 200000) : SEQ colour := greens [((i+j) + (texi+(texj TIMES 3))) / 7] IF ((i = 3) AND (j = 3)) AND ((texi = 3) AND (texj = 3)) addPoly ( [ 4, colour, texx, floorZ, texy, 1, texx+200000, floorZ, texy, 1, texx+200000, floorZ, texy+200000, 1, texx, floorZ, texy+200000, 1, NIL, NIL, NIL, NIL , true ] ) (texi = 3) AND (texj = 3) addPoly ( [ 4, colour, texx, floorZ, texy, 1, texx+200000, floorZ, texy, 1, texx+200000, floorZ, texy+200000, 1, texx, floorZ, texy+200000, 1, NIL, NIL, nextPoly + pol, NIL , true ] ) (texi = 2) AND (texj = 1) addPoly ( [ 4, colour, texx, floorZ, texy - 14000, 1, texx+280000, floorZ, texy - 14000, 1, texx+280000, floorZ, texy+280000, 1, texx, floorZ, texy+280000, 1, NIL, NIL, nextPoly + pol, NIL , true ] ) (texi = 1) AND (texj = 0) addPoly ( [ 4, colour, texx, floorZ, texy, 1, texx+200000, floorZ, texy, 1, texx+200000, floorZ, texy+310000, 1, texx, floorZ, texy+310000, 1, NIL, NIL, nextPoly + pol, NIL , true ] ) (texi = 0) AND (texj = 2) addPoly ( [ 4, colour, texx, floorZ, texy - 30000, 1, texx+230000, floorZ, texy - 30000, 1, texx+230000, floorZ, texy+200000, 1, texx, floorZ, texy+200000, 1, NIL, NIL, nextPoly + pol, NIL , true ] ) TRUE SKIP VAL ox IS 2200 : SEQ addPoly ( [ 4, 70, ox+1100, floorZ, -2000, 1, ox+1100, floorZ, 39500, 1, ox-1100, floorZ, 39500, 1, ox-1100, floorZ, -2000, 1, nextPoly + pol, NIL, nextPoly + (pol + pol), NIL , false ] ) addPoly ( [ 4, 70, ox-1700, floorZ, -2000, 1, ox-1700, floorZ, 1200, 1, ox-2100, floorZ, 1200, 1, ox-2100, floorZ, -2000, 1, NIL, NIL, NIL, NIL , false ] ) SEQ i = 0 FOR 20 VAL y0 IS (-2000) + (600 + (i * 1980)) : VAL stripe IS 600 : INT next : SEQ IF i = 19 next := NIL TRUE next := nextPoly + pol addPoly ( [ 4, 77, ox+70, floorZ, y0, 1, ox+70, floorZ, y0+stripe, 1, ox-70, floorZ, y0+stripe, 1, ox-70, floorZ, y0, 1, NIL, NIL, next, NIL , false ] ) : VAL vsc IS 30000 : VAL browns IS [ 55, 52, 54, 56, 53 ] : PROC createNorthHills () VAL floorZ IS 0 : VAL pol IS p.polySize : SEQ p [0] := 0 p.p := 1 polys := 0 -- nextPoly := 0 VAL sc IS 100000 : SEQ addPoly ( [ 4, browns [0], -(16*sc), floorZ, 16*sc, 1, 4*sc, floorZ, 16*sc, 1, 3*sc, floorZ-(5*vsc), 16*sc, 1, -(8*sc), floorZ-(8*vsc), 16*sc, 1, nextPoly + pol, NIL, NIL, NIL, true ] ) addPoly ( [ 3, browns [1], 16*sc, floorZ, 16*sc, 1, 13*sc, floorZ-(7*vsc), 16*sc, 1, 8*sc, floorZ, 16*sc, 1, nextPoly + pol, NIL , NIL, NIL, true ] ) addPoly ( [ 3, browns [2], 12*sc, floorZ, 16*sc, 1, 6*sc, floorZ-(9 * vsc), 16*sc, 1, 0, floorZ, 16*sc, 1, NIL, NIL, NIL, NIL, true ] ) : PROC createSouthHills () VAL floorZ IS 0 : VAL pol IS p.polySize : SEQ p [0] := 0 p.p := 1 polys := 0 -- nextPoly := 0 VAL sc IS 100000 : SEQ addPoly ( [ 5, browns [3], -(5*sc), floorZ, -(16*sc), 1, 2*sc, floorZ-(7 * vsc), -(16*sc), 1, 4*sc, floorZ-(8 * vsc), -(16*sc), 1, 10*sc, floorZ-(6 * vsc), -(16*sc), 1, 16*sc, floorZ, -(16*sc), 1, nextPoly + pol, nextPoly + (pol + pol), NIL, NIL, true ] ) addPoly ( [ 4, browns [1], -(12*sc), floorZ, -(16*sc), 1, -(9*sc), floorZ-(6*vsc), -(16*sc), 1, -(4*sc), floorZ-(10*vsc), -(16*sc), 1, (4*sc), floorZ, -(16*sc), 1, NIL, NIL , NIL, NIL, true ] ) addPoly ( [ 5, browns [2], 3*sc, floorZ, -(16*sc), 1, -(4*sc), floorZ-(7 * vsc), -(16*sc), 1, -(7*sc), floorZ-(9 * vsc), -(16*sc), 1, -(13*sc), floorZ-(6 * vsc), -(16*sc), 1, -(16*sc), floorZ, -(16*sc), 1, NIL, NIL, NIL, NIL , true ] ) : PROC createEastHills () VAL floorZ IS 0 : VAL pol IS p.polySize : SEQ p [0] := 0 p.p := 1 polys := 0 -- nextPoly := 0 VAL sc IS 100000 : SEQ addPoly ( [ 5, browns [3], 16*sc, floorZ, -(8*sc), 1, 16*sc, floorZ-(10*vsc), -(2*sc), 1, 16*sc, floorZ-(12*vsc), 8*sc, 1, 16*sc, floorZ-(8*vsc), 12*sc, 1, 16*sc, floorZ, 13*sc, 1, NIL, NIL, NIL, NIL, true ] ) : PROC createWestHills () VAL floorZ IS 0 : VAL pol IS p.polySize : SEQ p [0] := 0 p.p := 1 polys := 0 -- nextPoly := 0 VAL sc IS 100000 : SEQ addPoly ( [ 4, browns [4], -(16*sc), floorZ, -(16*sc), 1, -(16*sc), floorZ-(6*vsc), -(4*sc), 1, -(16*sc), floorZ-(4*vsc), 4*sc, 1, -(16*sc), floorZ, 6*sc, 1, NIL, NIL, NIL, NIL, true ] ) : PROC createExplosion () VAL pol IS p.polySize : VAL uStep IS one / 8.0 (REAL32) : VAL vStep IS one / 8.0 (REAL32) : VAL r IS 22.0 (REAL32) : [3][8][8]INT circle : VAL pi IS (22.0 (REAL32)) / (7.0 (REAL32)) : SEQ p [0] := 0 p.p := 1 polys := 0 -- nextPoly := 0 REAL32 u, v : SEQ u := zero SEQ i = 0 FOR 8 REAL32 twopu: SEQ twopu := (pi * u) * 2.0 (REAL32) --pu := pi * u v := zero SEQ j = 0 FOR 8 REAL32 spu, cpu, spv, cpv, twopv, c2pu : SEQ twopv := (pi * v) * 2.0 (REAL32) spu := SIN ( twopu ) c2pu := COS ( twopu ) spv := SIN ( twopv ) cpv := COS ( twopv ) circle[0][i][j] := INT ROUND (r * (spu * spv)) circle[1][i][j] := INT ROUND (r * (spu * cpv)) circle[2][i][j] := INT ROUND (r * c2pu) v := v + vStep u := u + uStep SEQ i = 0 FOR 4 SEQ j = 0 FOR 8 INT point : SEQ IF (i = 3) AND (j = 7) point := NIL TRUE point := nextPoly + pol VAL x IS (2*i) : VAL z IS (((2*i) + 1) /\ 7) : VAL y IS ((j+1) /\ 7) : [4]INT p1, p2, p3, p4 : SEQ p1[0] := circle[0][x][j] p1[1] := circle[1][x][j] p1[2] := circle[2][x][j] p2[0] := circle[0][x][y] p2[1] := circle[1][x][y] p2[2] := circle[2][x][y] p3[0] := circle[0][z][y] p3[1] := circle[1][z][y] p3[2] := circle[2][z][y] p4[0] := circle[0][z][j] p4[1] := circle[1][z][j] p4[2] := circle[2][z][j] addPoly ( [ 4, (224 + (i + j)), p4[0], p4[1], p4[2], 1, p1[0], p1[1], p1[2], 1, p2[0], p2[1], p2[2], 1, p3[0], p3[1], p3[2], 1, NIL, point , NIL, NIL , true ] ) : PROC createPlane () VAL pol IS p.polySize : VAL a IS 0: VAL x IS 1: VAL z IS 2: VAL h IS 3: VAL d IS 4: VAL i IS 5: VAL l IS 6: VAL e IS 7: VAL f IS 8: VAL g IS 9: VAL j IS 10: VAL k IS 11: VAL m IS 12 : SEQ p [0] := 0 p.p := 1 polys := 0 -- nextPoly := 0 -- a, half the wing addPoly ( [ 4, 16, -65, 0, 0, 1, -20, -55, 0, 1, -10, -55, 0, 1, -10, 0 , 0, 1, pol * x, gunAoffset , NIL, NIL , true ] ) gunAoffset := p.backOffset + (a * pol) -- patch to gunA -- x, the other half of the wing addPoly ( [ 4, 16, -65, 0, 0, 1, -10, 0 , 0, 1, -10, 55, 0, 1, -20, 55, 0, 1, pol * z, gunBoffset, NIL, NIL , true ] ) gunBoffset := p.backOffset + (x * pol) -- patch to gunB -- z, the base addPoly ( [ 6, 16, 0, -15, 0, 1, 0, 15, 0, 1, -75, 10, 0, 1, -130, 5, 0, 1, -130, -5, 0, 1, -75, -10, 0, 1, pol * h, NIL, NIL, NIL , true ] ) -- h, top addPoly ( [ 4, 99, -70, 5, 20, 1, -70, -5, 20, 1, -8, -10, 20, 1, -8, 10, 20, 1, pol * e, pol * d, NIL, NIL , true ] ) -- d, back enclosure addPoly ( [ 4, 128, -8, 10, 20, 1, -8, -10, 20, 1, 0, -15, 0, 1, 0, 15, 0, 1, NIL, pol * i, NIL, NIL , true ] ) -- i, top at front addPoly ( [ 4, 7, -70, -5, 20, 1, -70, 5, 20, 1, -125, 3, 6, 1, -125, -3, 6, 1, NIL, pol * l, NIL, NIL , true ] ) -- l, front enclosure addPoly ( [ 4, 25, -125, -3, 6, 1, -125, 3, 6, 1, -130, 5, 0, 1, -130, -5, 0, 1, NIL, pol * f, NIL, NIL , true ] ) -- e, tail plane addPoly ( [ 4, 104, -8, 0, 20, 1, -20, 0, 50, 1, -30, 0, 45, 1, -40, 0, 20, 1, NIL, NIL, NIL, NIL, true ] ) --fourD * pol, fourA * pol , true ] ) -- f, back side shell addPoly ( [ 4, 25, 0, -15, 0, 1, -8, -10, 20, 1, -70, -5, 20, 1, -75, -10, 0, 1, NIL, pol * g, NIL, NIL , true ] ) -- g, back side shell addPoly ( [ 4, 25, -75, 10, 0, 1, -70, 5, 20, 1, -8, 10, 20, 1, 0, 15, 0, 1, NIL, pol * j, NIL, NIL , true ] ) -- j, front side shell addPoly ( [ 4, 28, -75, -10, 0, 1, -70, -5, 20, 1, -125, -3, 6, 1, -130, -5, 0, 1, NIL, pol * k, NIL, NIL , true ] ) -- k, front side shell addPoly ( [ 4, 28, -130, 5, 0, 1, -125, 3, 6, 1, -70, 5, 20, 1, -75, 10, 0, 1, NIL , NIL, NIL, NIL , true ] ) SEQ i = 0 FOR 8 INT ny : SEQ ny := i << 3 gunAlocation[i] := pol * ((i * 2) + m) -- a guided missile (A) addPoly ( [ 4, 13, 0, -40, ((-5) - ny), 1, -40, -45, ((-5) - ny), 1, -60, -40, ((-5) - ny), 1, -40, -35, ((-5) - ny), 1, NIL, NIL, NIL, NIL , true ] ) gunBlocation[i] := gunAlocation[i] + pol -- a guided missile (B) addPoly ( [ 4, 13, 0, 40, ((-5) - ny), 1, -40, 45, ((-5) - ny), 1, -60, 40, ((-5) - ny), 1, -40, 35, ((-5) - ny), 1, NIL, NIL, NIL, NIL , true ] ) : PROC createXwing () VAL pol IS p.polySize : VAL a IS 0: VAL b IS 1: VAL c IS 2: VAL d IS 3: VAL e IS 4: VAL f IS 5: VAL g IS 6: VAL h IS 7: VAL z IS 8: VAL i IS 9: VAL j IS 10: VAL k IS 11: VAL l IS 12: VAL m IS 13: VAL n IS 14: VAL o IS 15: VAL qp IS 16: VAL q IS 17: VAL r IS 18: SEQ p [0] := 0 p.p := 1 polys := 0 -- nextPoly := 0 addPoly ( [ 4, 78, 60, -10, 20, 1, 60, 10, 20, 1, 0, 10, 20, 1, 0, -10, 20, 1, NIL, pol * b , NIL, NIL , true ] ) addPoly ( [ 4, 77, 60, -10, 20, 1, 0, -10, 20, 1, 0, -16, 0, 1, 40, -16, 0, 1, pol * qp, pol * c , NIL, NIL , true ] ) addPoly ( [ 4, 77, 0, 10, 20, 1, 60, 10, 20, 1, 40, 16, 0, 1, 0, 16, 0, 1, pol * o, pol * d , NIL, NIL , true ] ) addPoly ( [ 5, 128, 40,-16, 0, 1, 30, 0,-10, 1, 40, 16, 0, 1, 60, 10, 20, 1, 60,-10, 20, 1, NIL, pol * e , NIL, NIL , true ] ) addPoly ( [ 4, 66, 0, -16, 0, 1, 0, 0, -10, 1, 30, 0, -10, 1, 40, -16, 0, 1, pol * r, pol * f , NIL, NIL , true ] ) addPoly ( [ 4, 66, 0, 16, 0, 1, 40, 16, 0, 1, 30, 0, -10, 1, 0, 0, -10, 1, pol * q, pol * g , NIL, NIL , true ] ) addPoly ( [ 3, 64, 0, -16, 0, 1, -160, -3, 0, 1, 0, 0, -10, 1, NIL, pol * h , NIL, NIL , true ] ) addPoly ( [ 3, 64, 0, 16, 0, 1, 0, 0, -10, 1, -160, 3, 0, 1, NIL, pol * z , NIL, NIL , true ] ) addPoly ( [ 3, 65, 0, 0, -10, 1, -160, -3, 0, 1, -160, 3, 0, 1, NIL, pol * i , NIL, NIL , true ] ) addPoly ( [ 3, 10, 0, -13, 10, 1, -160, -3, 0, 1, 0, -16, 0, 1, NIL, pol * j , NIL, NIL , true ] ) addPoly ( [ 3, 10, 0, 13, 10, 1, 0, 16, 0, 1, -160, 3, 0, 1, NIL, pol * k , NIL, NIL , true ] ) addPoly ( [ 4, 78, -80, 8, 5, 1, -160, 3, 0, 1, -160, -3, 0, 1, -80, -8, 5, 1, pol * l , NIL, NIL, NIL , true ] ) addPoly ( [ 4, 64, -80, 8, 5, 1, -80, -8, 5, 1, 0, -10, 20, 1, 0, 10, 20, 1, NIL, pol * m , NIL, NIL , true ] ) addPoly ( [ 3, 64, -80, 8, 5, 1, 0, 10, 20, 1, 0, 13, 10, 1, NIL, pol * n , NIL, NIL , true ] ) addPoly ( [ 3, 64, -80, -8, 5, 1, 0, -13, 10, 1, 0, -10, 20, 1, NIL, NIL , NIL, NIL , true ] ) addPoly ( [ 4, 72, 0, 16, 0, 1, 30, 16, 0, 1, 30, 110, 40, 1, 20, 110, 40, 1, NIL, NIL , NIL, NIL , true ] ) addPoly ( [ 4, 72, 0, -16, 0, 1, 20, -110, 40, 1, 30, -110, 40, 1, 30, -16, 0, 1, NIL, NIL , NIL, NIL , true ] ) addPoly ( [ 4, 72, 0, 16, 0, 1, 30, 16, 0, 1, 30, 110, -40, 1, 20, 110, -40, 1, NIL, NIL , NIL, NIL , true ] ) addPoly ( [ 4, 72, 0, -16, 0, 1, 20, -110, -40, 1, 30, -110, -40, 1, 30, -16, 0, 1, NIL, NIL , NIL, NIL , true ] ) : [p.polySize] INT testPoly : p1 IS [testPoly FROM p.first FOR (maxVertices * 4) ] : [maxVertices][4]REAL32 rp1 RETYPES p1 : INT number : [maxTrees]INT len : BOOL going : INT frameNumber : PROC buildTree(VAL INT treeNumber) bound IS boundBox[treeNumber] : length IS len[treeNumber] : CHAN OF polyChan toTree : SEQ IF treeNumber > (maxTrees - 1) SKIP TRUE INT s, noPolys : SEQ s := starter[treeNumber] REAL32 minX, minY, minZ, maxX, maxY, maxZ : INT count : SEQ minX := zero minY := zero minZ := zero maxX := zero maxY := zero maxZ := zero count := 1 noPolys := p[0] --toTree ! c.nPoly ; noPolys SEQ i = 0 FOR noPolys INT colour, noVert : SEQ noVert := p[count] [ testPoly FROM 0 FOR 2 ] := [ p FROM count FOR 2 ] count := count + 2 SEQ j = 0 FOR noVert SEQ SEQ k = 0 FOR 4 rp1[j][k] := REAL32 TRUNC (p[count + k]) tx IS rp1[j][0] : ty IS rp1[j][1] : tz IS rp1[j][2] : SEQ IF tx < minX minX := tx tx > maxX maxX := tx TRUE SKIP IF ty < minY minY := ty ty > maxY maxY := ty TRUE SKIP IF tz < minZ minZ := tz tz > maxZ maxZ := tz TRUE SKIP count := count + 4 -- patch tree, texture pointers VAL offset IS p.frontOffset : SEQ testPoly [ offset] := p [ count] -- TREE front pointer testPoly [ offset+1] := p [ count+1] -- TREE back pointer testPoly [ offset+2] := p [ count+2] -- TEXTURE front pointer testPoly [ offset+3] := p [ count+3] -- TEXTURE back pointer testPoly [ offset+4] := p [ count+4] -- display back faces count := count + 5 --toTree ! c.poly ; p.polySize::testPoly bound [b.noVertices] := 8 ib IS [bound FROM b.first FOR (boundVertices * 4) ] : [boundVertices * 4]REAL32 bb RETYPES ib : SEQ bb := [minX, minY, minZ, one, maxX, minY, minZ, one, minX, maxY, minZ, one, maxX, maxY, minZ, one, minX, minY, maxZ, one, maxX, minY, maxZ, one, minX, maxY, maxZ, one, maxX, maxY, maxZ, one ] treesCreated := treesCreated + 1 : SEQ nextPoly := 0 starter[0] := 0 createChopper () buildTree ( 0) createPlane () buildTree ( 1) createGround () buildTree ( 2) createNorthHills () buildTree ( 3) createSouthHills () buildTree ( 4) createWestHills () buildTree ( 5) createEastHills () buildTree ( 6) createExplosion () buildTree ( 7) createMissile () buildTree ( 8) createXwing () buildTree ( 9) : BOOL traversing : INT numberOfTrees : SEQ numberOfTrees := 0 storePoly (numberOfTrees) -- create all trees toRinger ! c.nPoly ; numberOfTrees SEQ i = 0 FOR numberOfTrees toRinger ! c.poly ; b.boundSize::boundBox[i] : PROC player (CHAN OF RING toRing, fromRing, CHAN OF polyChan toPipe, fromPipe, CHAN OF BYTES keyboard, startChan, screen, VAL INT me, VAL BOOL playerHasScreen, VAL INT myType ) VAL maxPlayers IS 10 : [16]REAL32 N0, N1, T0, T1 : -- general work vectors (transforms etc) PROC DotProd(REAL32 cth, [3] REAL32 a,b) SEQ cth:= ((a[0]*b[0]) + (a[1]*b[1])) + (a[2]*b[2]) : PROC MatMul4b4 ( [16] REAL32 r, VAL [16] REAL32 a, b ) VAL X IS 0 : VAL Y IS 1 : VAL Z IS 2 : VAL W IS 3 : VAL XYZW IS 4 : VAL [XYZW][XYZW] REAL32 A RETYPES a : VAL [XYZW][XYZW] REAL32 B RETYPES b : [XYZW][XYZW] REAL32 R RETYPES r : [XYZW][XYZW]REAL32 result : SEQ SEQ i = 0 FOR XYZW result.i IS result[i] : VAL Ai IS A[i] : SEQ VAL j IS X : result.i [j] := (((Ai[X] * B[X][j]) + (Ai[Y] * B[Y][j])) + (Ai[Z] * B[Z][j])) + (Ai[W] * B[W][j]) VAL j IS Y : result.i [j] := (((Ai[X] * B[X][j]) + (Ai[Y] * B[Y][j])) + (Ai[Z] * B[Z][j])) + (Ai[W] * B[W][j]) VAL j IS Z : result.i [j] := (((Ai[X] * B[X][j]) + (Ai[Y] * B[Y][j])) + (Ai[Z] * B[Z][j])) + (Ai[W] * B[W][j]) VAL j IS W : result.i [j] := (((Ai[X] * B[X][j]) + (Ai[Y] * B[Y][j])) + (Ai[Z] * B[Z][j])) + (Ai[W] * B[W][j]) R := result : PROC matMul4 ([4]REAL32 r, VAL [4]REAL32 A, VAL [16] REAL32 b) VAL X IS 0 : VAL Y IS 1 : VAL Z IS 2 : VAL W IS 3 : VAL XYZW IS 4 : VAL [XYZW][XYZW] REAL32 B RETYPES b : [XYZW] REAL32 result : SEQ VAL j IS X : result [j] := (((A[X] * B[X][j]) + (A[Y] * B[Y][j])) + (A[Z] * B[Z][j])) + (A[W] * B[W][j]) VAL j IS Y : result [j] := (((A[X] * B[X][j]) + (A[Y] * B[Y][j])) + (A[Z] * B[Z][j])) + (A[W] * B[W][j]) VAL j IS Z : result [j] := (((A[X] * B[X][j]) + (A[Y] * B[Y][j])) + (A[Z] * B[Z][j])) + (A[W] * B[W][j]) VAL j IS W : result [j] := (((A[X] * B[X][j]) + (A[Y] * B[Y][j])) + (A[Z] * B[Z][j])) + (A[W] * B[W][j]) r := result : PROC ZMat ([] REAL32 a) VAL words IS (SIZE a) - 1 : SEQ a [0] := 0.0 (REAL32) [ a FROM 1 FOR words ] := [ a FROM 0 FOR words ] : PROC UMat ([16] REAL32 a) VAL words IS 15 : SEQ a [0] := 0.0 (REAL32) [ a FROM 1 FOR words ] := [ a FROM 0 FOR words ] a [ 0] := 1.0 (REAL32) a [ 5] := 1.0 (REAL32) a [10] := 1.0 (REAL32) a [15] := 1.0 (REAL32) : PROC scale ( VAL REAL32 facX, facY, facZ, [4 * 4] REAL32 N ) [4 * 4] REAL32 T, R : SEQ ZMat ( T) T [ 0] := facX T [ 5] := facY T [ 10] := facZ T [ 15] := 1.0(REAL32) MatMul4b4 ( N, N, T) --MatMul4b4 ( R, N, T) --[ N FROM 0 FOR 16] := [ R FROM 0 FOR 16 ] : PROC rotate (VAL REAL32 deg, VAL BYTE axis, [ 4 * 4] REAL32 N ) [4 * 4] REAL32 T, R : VAL CONV IS 0.01745329(REAL32): REAL32 sth,cth: SEQ ZMat ( T) sth := SIN ( deg * CONV ) cth := COS ( deg * CONV ) IF axis = 'x' SEQ T [ 0] := 1.0 (REAL32) T [ 15] := 1.0 (REAL32) T [ 5] := cth T [ 10] := cth T [ 6] := -sth T [ 9] := sth axis = 'y' SEQ T [ 5] := 1.0 (REAL32) T [ 15] := 1.0 (REAL32) T [ 0] := cth T [ 10] := cth T [ 8] := -sth T [ 2] := sth axis = 'z' SEQ T [ 10] := 1.0 (REAL32) T [ 15] := 1.0 (REAL32) T [ 0] := cth T [ 5] := cth T [ 1] := -sth T [ 4] := sth MatMul4b4 ( N, N, T) --[ N FROM 0 FOR 16 ] := [ R FROM 0 FOR 16 ] : PROC quickRotate ( VAL REAL32 sth, cth, VAL BYTE axis, [ 4 * 4] REAL32 N ) [4 * 4] REAL32 T, R : SEQ ZMat ( T) IF axis = 'x' SEQ T [ 0] := 1.0 (REAL32) T [ 15] := 1.0 (REAL32) T [ 5] := cth T [ 10] := cth T [ 6] := -sth T [ 9] := sth axis = 'y' SEQ T [ 5] := 1.0 (REAL32) T [ 15] := 1.0 (REAL32) T [ 0] := cth T [ 10] := cth T [ 8] := -sth T [ 2] := sth axis = 'z' SEQ T [ 10] := 1.0 (REAL32) T [ 15] := 1.0 (REAL32) T [ 0] := cth T [ 5] := cth T [ 1] := -sth T [ 4] := sth MatMul4b4 ( N, N, T) --[ N FROM 0 FOR 16 ] := [ R FROM 0 FOR 16 ] : PROC translate ( VAL REAL32 X, Y, Z, [4 * 4] REAL32 N ) SEQ N [ 12] := N [ 12] + X N [ 13] := N [ 13] + Y N [ 14] := N [ 14] + Z : VAL maxPatches IS 4 : VAL r.identity IS 0 : VAL r.objectLen IS 1 : -- used in sort lis: VAL r.attribute IS 2 : VAL r.nPatches IS 3 : VAL r.boundCentre IS 4 : -- x, y, z, (rad * rad) VAL r.forTrans IS (r.boundCentre + 4 ) : VAL r.revTrans IS (r.forTrans + 16) : -- not needed by other players VAL r.patch IS (r.revTrans + 16) : -- -- space for 'maxPatches * 2' INTS (optional) -- -- VAL r.minRingSize IS r.patch : VAL r.maxRingSize IS (r.patch + ( maxPatches * 2 ) ) : VAL a.type IS 0 : VAL a.number IS 1 : -- missile number VAL a.state IS 2 : VAL a.launch IS 3 : -- laucnhing VAL a.type.chopper IS 0 (BYTE) : VAL a.type.plane IS 1 (BYTE) : VAL a.type.explosion IS 7 (BYTE) : VAL a.type.missile IS 8 (BYTE) : VAL a.type.Xwing IS 9 (BYTE) : VAL a.type.tower IS 10(BYTE) : VAL a.type.cray IS 11(BYTE) : VAL a.state.ok IS 0(BYTE) : VAL a.state.explode IS 1(BYTE) : VAL a.state.hit IS 2(BYTE) : -- missile has hit somebody PROC mover (CHAN OF movement toMain, fromMain, CHAN OF BYTES keyboard, fstart, VAL INT me, myType) VAL maxMissiles IS 2 : REAL32 turnZ , turnX, turnY : -- angles REAL32 turnSinX, turnCosX : REAL32 turnSinY, turnCosY : REAL32 turnSinZ, turnCosZ : REAL32 ndx, ndy, ndz : INT patch1Offset, patch2Offset, patch3Offset, patch4Offset : [8] INT patch1, patch2, patch3, patch4 : [2][4]REAL32 missileStart : PROC createPatches (VAL INT mine) -- creates any patches, and missile start locations VAL NIL IS -15 : -- arbritrary value, invalid tree pointer PROC makeChopperPatches () VAL pol IS p.polySize : VAL ox IS 65 : VAL a IS 0: VAL b IS 1: VAL c IS 2: VAL d IS 3: VAL tail0 IS 4: VAL tail1 IS 5: VAL tail2 IS 6: VAL tail3 IS 7: VAL tail4 IS 8: VAL bod0 IS 9 : VAL bod1 IS 10 : VAL bod2 IS 11 : VAL bod3 IS 12 : VAL bod4 IS 13 : VAL bod5 IS 14 : VAL bod6 IS 15 : VAL r00 IS 16: VAL r01 IS 17 : SEQ patch1Offset := p.frontOffset + (d * pol) -- patch to rotor patch2Offset := p.frontOffset + (bod0 * pol) -- patch to tail rotor patch3Offset := p.frontOffset + (bod1 * pol) -- patch to gunA patch4Offset := p.frontOffset + (bod2 * pol) -- patch to gunB SEQ i = 0 FOR 8 SEQ patch1 [i] := pol * ((i * 4) + r00) patch2 [i] := patch1 [i] + (pol * 2) VAL g00 IS (32 + r00) : SEQ i = 0 FOR 8 SEQ patch3 [i] := pol * ((i * 2) + g00) patch4 [i] := patch3 [i] + pol VAL ny IS (7 << 3) : SEQ missileStart[0][0] := REAL32 TRUNC (ox-105) missileStart[0][1] := REAL32 TRUNC ((-12) - ny) missileStart[0][2] := REAL32 TRUNC (-10) missileStart[0][3] := one missileStart[1][0] := REAL32 TRUNC (ox-105) missileStart[1][1] := REAL32 TRUNC (12 + ny) missileStart[1][2] := REAL32 TRUNC (-10) missileStart[1][3] := one : PROC makePlanePatches () VAL pol IS p.polySize : VAL a IS 0: VAL x IS 1: VAL z IS 2: VAL h IS 3: VAL d IS 4: VAL i IS 5: VAL l IS 6: VAL e IS 7: VAL f IS 8: VAL g IS 9: VAL j IS 10: VAL k IS 11: VAL m IS 12 : SEQ patch1Offset := p.backOffset + (a * pol) -- patch to gunA patch2Offset := p.backOffset + (x * pol) -- patch to gunB SEQ i = 0 FOR 8 SEQ patch1 [i] := pol * ((i * 2) + m) patch2 [i] := patch1 [i] + pol VAL ny IS 7 << 3 : SEQ missileStart[0][0] := REAL32 TRUNC (-40) missileStart[0][1] := REAL32 TRUNC (-45) missileStart[0][2] := REAL32 TRUNC ((-5) - ny) missileStart[0][3] := one missileStart[1][0] := REAL32 TRUNC (-40) missileStart[1][1] := REAL32 TRUNC 45 missileStart[1][2] := REAL32 TRUNC ((-5) - ny) missileStart[1][3] := one : PROC makeXwingPatches () SEQ missileStart[0][0] := REAL32 TRUNC 0 missileStart[0][1] := REAL32 TRUNC (-132) missileStart[0][2] := REAL32 TRUNC (-44) missileStart[0][3] := one missileStart[1][0] := REAL32 TRUNC 0 missileStart[1][1] := REAL32 TRUNC 132 missileStart[1][2] := REAL32 TRUNC (-44) missileStart[1][3] := one : SEQ IF mine = (INT a.type.chopper) makeChopperPatches () mine = (INT a.type.plane) makePlanePatches () mine = (INT a.type.Xwing) makeXwingPatches () mine = (INT a.type.cray) makeXwingPatches () -- tacky TRUE SKIP : VAL ix IS 2200.0 (REAL32) : VAL iy IS (REAL32 TRUNC (- 500)) : --(me * (-1800)) : VAL izz IS me : VAL runStart IS -2000 : VAL startZ IS runStart - (4 * 3800) : VAL iz IS REAL32 TRUNC (startZ + (izz * 3800)) : VAL dtx IS 1.0 (REAL32): VAL dty IS 1.0 (REAL32): VAL dtz IS 1.0 (REAL32) : [r.maxRingSize] INT ringData : mF IS [ ringData FROM r.forTrans FOR 16 ] : mR IS [ ringData FROM r.revTrans FOR 16 ] : [16] REAL32 myFor RETYPES mF : [16] REAL32 myRev RETYPES mR : [4]BYTE attr RETYPES ringData [ r.attribute] : noPatches IS ringData [ r.nPatches] : bc IS [ringData FROM r.boundCentre FOR 4] : [4] REAL32 bound RETYPES bc : [r.maxRingSize] INT playerStore : maF IS [ playerStore FROM r.forTrans FOR 16 ] : maR IS [ playerStore FROM r.revTrans FOR 16 ] : [16] REAL32 mainFor RETYPES maF : [16] REAL32 mainRev RETYPES maR : pStore IS [playerStore FROM r.patch FOR (maxPatches * 2)] : [4]REAL32 save RETYPES [pStore FROM 4 FOR 4] : [360] INT sines, cosines : -- in 1 degree intervals, scaled by 256 [headUpSize] INT displayList : [r.minRingSize]INT missileData : [maxMissiles]INT ammoStatus : [maxMissiles][r.maxRingSize] INT missileStore : [maxPoints][3]REAL32 mapData : INT mapSize : [16]REAL32 rotateOffsetFor : [16]REAL32 rotateOffsetRev : [4] REAL32 viewPoint : [16]REAL32 screenRev : [4] REAL32 absvel : -- velocity in x, y, z planes [4] REAL32 zVel : REAL32 msx, msy, msz : -- scale REAL32 isx, isy, isz : -- 1/scale REAL32 mythetaX, mythetaY, mythetaZ : -- rotation REAL32 mythSinX, mythCosX : REAL32 mythSinY, mythCosY : REAL32 mythSinZ, mythCosZ : INT missilesLaunching: VAL m.identity IS 0: VAL m.objectLen IS 1: -- used in sort list VAL m.attribute IS 2: VAL m.nPatches IS 3: -- set to 0 VAL m.boundCentre IS 4: -- x, y, z, (rad * rad: VAL m.forTrans IS (r.boundCentre + 4 ): VAL m.revTrans IS (r.forTrans + 16): -- not needed by other players VAL m.patch IS (r.revTrans + 16): -- use patch pace to store stuff like thetaX,Y,Z -- in case missile is controlled by player -- VAL m.missileSize IS m.patch : [4] BYTE missAttr RETYPES missileData [ m.attribute] : [4] REAL32 mbnd RETYPES [ missileData FROM m.boundCentre FOR 4] : [16]REAL32 mFor RETYPES [ missileData FROM m.forTrans FOR 16 ] : [16]REAL32 mRev RETYPES [ missileData FROM m.revTrans FOR 16 ] : INT disp.p, basic.p : VAL bright IS 127 : VAL red IS 15 : VAL dialCentre IS [ [ 285, 32 ], [ 350, 32 ], [ 415, 32 ], [ 480, 32 ]] : PROC add ( VAL INT a ) SEQ displayList [ disp.p] := a disp.p := disp.p + 1 : PROC addCircle ( VAL INT type, xc, yc, radius, colour ) SEQ add ( type ) add ( xc) add ( yc) add ( radius) add ( colour) : PROC addPoint ( VAL INT type, xc, yc, colour ) SEQ add ( type ) add ( xc) add ( yc) add ( colour) : PROC addLine ( VAL INT x0, y0, dx, dy, colour ) SEQ add ( d.line ) add ( x0 ) add ( y0 ) add ( dx ) add ( dy ) add ( colour ) : PROC addRLine ( VAL INT dx, dy ) SEQ add ( d.rline ) add ( dx ) add ( dy ) : PROC initSines () SEQ i = 0 FOR 360 VAL angle IS (REAL32 ROUND i) * 0.01745 (REAL32) : REAL32 cosTh, sinTh : SEQ cosTh := COS ( angle ) sinTh := SIN ( angle ) cosines [i] := INT ROUND (255.99 (REAL32) * cosTh ) sines [i] := INT ROUND (255.99 (REAL32) * sinTh ) : PROC initHeadUp () VAL col IS 120 : SEQ initSines () disp.p := 0 SEQ i = 0 FOR 4 SEQ addCircle ( d.outlineCircle, dialCentre [i][0], dialCentre [i][1], 30, bright ) addCircle ( d.outlineCircle, dialCentre [i][0], dialCentre [i][1], 4, 62 ) VAL letterStart IS [ 400, 15 ] : SEQ addLine ( letterStart [0], letterStart [1], 5, 10, col ) addRLine ( 5, -10 ) addLine ( letterStart [0]+2, letterStart [1]+3, 4, 0, col ) addLine ( letterStart [0]+13, letterStart [1]+10, 0, -10, col ) addRLine ( 6, 0 ) addLine ( letterStart [0]+22, letterStart [1], 0, 10, col ) addLine ( letterStart [0]+17, letterStart [1]+10, 10, 0, col ) addLine ( dialCentre [0][0], dialCentre [0][1]+4, -18, -3, bright ) addRLine ( 18, -3 ) addRLine ( 18, 3 ) addRLine ( -18, 3 ) addRLine ( 0, 9 ) addLine ( dialCentre [1][0], dialCentre [1][1]+4, -18, 0, bright ) addRLine ( 24, 8 ) addRLine ( 6, 5 ) addRLine ( 4, 0 ) addRLine ( -8, -13 ) addRLine ( -8, 0 ) addLine ( 110, 10, 100, 0, bright ) addRLine ( 0, 100 ) addRLine ( -100, 0 ) addRLine ( 0, -100 ) --addCircle ( d.outlinefilledCircle, 160, 60, 2, bright ) addCircle ( d.outlineCircle, 160, 60, 2, bright ) basic.p := disp.p : PROC dial ( VAL INT dial, angle, radius, colour ) INT index : SEQ index := angle \ 360 IF index < 0 index := index + 360 TRUE SKIP addLine ( dialCentre [dial][0], dialCentre [dial][1], (cosines [index] TIMES radius) / 256, (sines [index] TIMES radius) / 256, colour ) : PROC halfDial ( VAL INT dial, angle, radius, colour ) INT index : SEQ index := angle \ 360 IF index < 0 index := index + 360 TRUE SKIP VAL dx IS (cosines [index] TIMES radius) / 512 : VAL dy IS (sines [index] TIMES radius) / 512 : addLine ( dialCentre [dial][0] + dx, dialCentre [dial][1] + dy, dx, dy, colour ) : PROC sevenSegLED ( VAL INT x, y, digit ) SEQ add ( d.7segLED ) add ( x ) add ( y ) add ( digit ) : PROC writen ( VAL INT num, x0, y0 ) INT n : INT tens, ones, huns, thous : SEQ IF num < 0 SEQ sevenSegLED ( x0, y0, 10 ) n := -num TRUE n := num n := n \ 10000 thous := n / 1000 n := n \ 1000 huns := (n / 100) n := n \ 100 tens := (n / 10) ones := n - (tens TIMES 10) sevenSegLED ( x0+18, y0, thous ) sevenSegLED ( x0+36, y0, huns ) sevenSegLED ( x0+54, y0, tens ) sevenSegLED ( x0+72, y0, ones ) : TIMER clk : INT now : INT startM : INT frameNumber : BOOL running : BOOL fire, move, m1Active, m2Active : BOOL mSwitch, pSwitch, switch : INT missilesActive, control, m1seq, m2seq : INT driveMissile : PROC initScales() SEQ msx := 25.0 (REAL32) msy := 25.0 (REAL32) msz := 25.0 (REAL32) isx := one / msx isy := one / msy isz := one / msz : PROC alterScales() VAL two IS 2.2 (REAL32) : SEQ msx := msx + two msy := msy + two msz := msz + two isx := one / msx isy := one / msy isz := one / msz : PROC computeMyTrig () VAL convert IS 0.017453292 (REAL32) : REAL32 thx, thy, thz : SEQ IF mythetaX > 360.0 (REAL32) mythetaX := mythetaX - 360.0 (REAL32) mythetaX < (-360.0 (REAL32)) mythetaX := mythetaX + 360.0 (REAL32) TRUE SKIP IF mythetaY > 360.0 (REAL32) mythetaY := mythetaY - 360.0 (REAL32) mythetaY < (-360.0 (REAL32)) mythetaY := mythetaY + 360.0 (REAL32) TRUE SKIP IF mythetaZ > 360.0 (REAL32) mythetaZ := mythetaZ - 360.0 (REAL32) mythetaZ < (-360.0 (REAL32)) mythetaZ := mythetaZ + 360.0 (REAL32) TRUE SKIP thx := mythetaX * convert thy := mythetaY * convert thz := mythetaZ * convert mythSinX := SIN ( thx ) mythCosX := COS ( thx ) mythSinY := SIN ( thy ) mythCosY := COS ( thy ) mythSinZ := SIN ( thz ) mythCosZ := COS ( thz ) : PROC initPlayer () [4]REAL32 playerPos RETYPES [ringData FROM r.boundCentre FOR 4] : SEQ ZMat (zVel) playerPos[0] := ix playerPos[1] := iy playerPos[2] := iz playerPos[3] := one mythetaX := zero mythetaY := zero mythetaZ := zero initScales () computeMyTrig () : PROC startMissile ( VAL INT no, [4 * 4] REAL32 N0 ) [4 * 4] REAL32 R : INT i : SEQ i := 0 WHILE ammoStatus[i] <> 0 i := i + 1 mStore IS missileStore[i] : mData IS missileData : [4] BYTE missAttr RETYPES mData [ m.attribute] : mx IS mbnd[0] : my IS mbnd[1] : mz IS mbnd[2] : SEQ mData [m.identity] := me mData [m.nPatches] := 0 missAttr [ a.type] := a.type.missile missAttr [a.number] := (BYTE i) missAttr [a.state] := a.state.ok ammoStatus [i] := 200 -- set to indicate missile is active matMul4 ( mbnd, missileStart[no], myFor) SEQ mFor := mainFor --rotateOffsetFor -- rotate model to z axis mRev := mainRev [mStore FROM 0 FOR r.minRingSize] := [missileData FROM 0 FOR m.missileSize] translate(mx, my, mz, mFor) UMat (N0) N0[12] := -mx N0[13] := -my N0[14] := -mz MatMul4b4 (mRev, N0, mRev ) toMain ! m.missileAck ; m.missileSize::missileData t IS [mStore FROM m.patch FOR (maxPatches * 2)] : [maxPatches*2]REAL32 temp RETYPES t : [4]REAL32 mvel RETYPES [temp FROM 0 FOR 4] : --0,1,2,3 [3]REAL32 theets RETYPES [temp FROM 4 FOR 3] : --4,5,6 REAL32 speed RETYPES temp [7] : [4]REAL32 vel : SEQ ZMat(vel) vel [ 3] := one vel [ axisZ] := (1024.0 (REAL32)) + zVel[axisZ] speed := vel[ axisZ] SEQ UMat ( N0) quickRotate ( mythSinX, mythCosX, 'x', N0 ) quickRotate ( mythSinY, mythCosY, 'y', N0 ) matMul4 ( mvel, vel, N0 ) theets[0] := mythetaX theets[1] := mythetaY theets[2] := zero : VAL velStep IS 19.0 (REAL32) : INT score : REAL32 maxVel, minVel : VAL cMax IS ( (42.0 (REAL32)) * velStep) : VAL cMin IS -( (21.0 (REAL32)) * velStep) : VAL pMax IS ( (62.0 (REAL32)) * velStep) : VAL pMin IS ( (0.0 (REAL32)) * velStep) : VAL xwMax IS ( (62.0 (REAL32)) * velStep) : VAL xwMin IS ( (2.0 (REAL32)) * velStep) : VAL crMax IS ( (62.0 (REAL32)) * velStep) : VAL crMin IS ( (2.0 (REAL32)) * velStep) : VAL maxTab IS [cMax, pMax, zero, zero, zero, zero, zero, zero, zero, xwMax, zero, crMax ] : VAL minTab IS [cMin, pMin, zero, zero, zero, zero, zero, zero, zero, xwMin, zero, crMin ] : [3] REAL32 stack : INT hitCycle, hitCount : INT switchCycle : VAL chopperPatches IS 4: VAL planePatches IS 2: VAL XwingPatches IS 0: INT patches, startCount : BOOL hit, reStart, turbo, towerView : INT iSpeed, tCount, totalTurboCount, towerCount : SEQ reStart := FALSE hit := FALSE hitCycle := 0 hitCount := 0 initHeadUp () frameNumber := me /\ 7 missilesLaunching := 0 startM := 0 SEQ i = 0 FOR maxMissiles ammoStatus[i] := 0 missilesActive := 0 m1seq := 0 m2seq := 0 m1Active := FALSE m2Active := FALSE attr [ a.type] := (BYTE myType) attr [ a.launch] := 0(BYTE) maxVel := maxTab[myType] minVel := minTab[myType] UMat(N0) quickRotate ( -one, zero, 'x', N0 ) quickRotate ( -one, zero, 'y', N0 ) rotateOffsetFor := N0 scale ( msx, msy, msz, N0) toMain ! m.trany ; N0 UMat(N0) --scale ( isx, isy, isz, N0) quickRotate ( one, zero, 'y', N0 ) quickRotate ( one, zero, 'x', N0 ) rotateOffsetRev := N0 IF attr[a.type] = a.type.chopper patches := chopperPatches attr[a.type] = a.type.plane patches := planePatches attr[a.type] = a.type.Xwing patches := 0 -- at present attr[a.type] = a.type.cray patches := 0 -- at present TRUE SEQ patches := 0 UMat(rotateOffsetFor) UMat(rotateOffsetRev) ringData[r.identity] := me initPlayer () createPatches (myType) noPatches := patches playerStore := ringData turbo := FALSE totalTurboCount := 0 tCount := 0 score := 0 startCount := 1 switch := FALSE mSwitch := FALSE pSwitch := FALSE switchCycle := 0 running := TRUE towerView := FALSE WHILE running SEQ IF hit SEQ mythetaX := mythetaX + 10.0 (REAL32) mythetaY := mythetaY + 10.0 (REAL32) mythetaZ := mythetaZ + 10.0 (REAL32) computeMyTrig () TRUE [12] BYTE buttons : INT keys : BYTE k0 : BOOL roll, pitch : SEQ fire := FALSE roll := FALSE pitch := FALSE IF reStart fstart ? k0::buttons TRUE keyboard ? k0::buttons SEQ keys := (INT k0) SEQ i = 0 FOR keys char IS buttons[i] : SEQ IF char = '8' SEQ mythetaX := mythetaX + dtx pitch := TRUE char = '2' SEQ mythetaX := mythetaX - dtx pitch := TRUE (char = ' ') AND (NOT turbo) SEQ move := FALSE fire := TRUE char = '4' SEQ mythetaZ := mythetaZ - dtz roll := TRUE char = '6' SEQ mythetaZ := mythetaZ + dtz roll := TRUE (char = 't') AND (NOT switch) AND (NOT turbo) z IS zVel[axisZ] : SEQ totalTurboCount := totalTurboCount + 1 IF totalTurboCount > 20 SEQ hit := TRUE totalTurboCount := 0 TRUE SEQ z := 4000.0 (REAL32) tCount := 0 turbo := TRUE (char = 'v') z IS zVel[axisZ] : SEQ turbo := FALSE tCount := 0 z := maxVel (char = 'a') AND (NOT switch) AND (NOT turbo) z IS zVel[axisZ] : SEQ z := z + velStep IF z > maxVel z := maxVel TRUE SKIP (char = 'd') AND (NOT switch) AND (NOT turbo) z IS zVel[axisZ] : SEQ z := z - velStep IF z < minVel z := minVel TRUE SKIP (char = 's') AND (NOT turbo) SEQ IF (switch AND (switchCycle > 20)) SEQ switch := FALSE mSwitch := FALSE pSwitch := FALSE switchCycle := 0 missile IS missileStore[driveMissile] : garbStore IS [missile FROM m.patch FOR (maxPatches * 2)] : [3]REAL32 thetaStore RETYPES [garbStore FROM 4 FOR 3] : REAL32 speed RETYPES garbStore[7] : SEQ thetaStore[0] := mythetaX thetaStore[1] := mythetaY thetaStore[2] := mythetaZ speed := zVel[axisZ] SEQ mythetaX := save[0] mythetaY := save[1] mythetaZ := save[2] zVel[axisZ] := save[3] --computeMyTrig () TRUE SEQ driveMissile := -1 SEQ i = 0 FOR 2 IF ammoStatus[i] <> 0 driveMissile := i TRUE SKIP IF driveMissile < 0 SKIP switchCycle < 20 SKIP TRUE SEQ switch := TRUE mSwitch := FALSE pSwitch := FALSE fire := FALSE SEQ save[0] := mythetaX save[1] := mythetaY save[2] := mythetaZ save[3] := zVel[axisZ] missile IS missileStore[driveMissile] : garbStore IS [missile FROM m.patch FOR (maxPatches * 2)] : [3]REAL32 thetaStore RETYPES [garbStore FROM 4 FOR 3] : REAL32 speed RETYPES garbStore[7] : SEQ mythetaX := thetaStore[0] mythetaY := thetaStore[1] mythetaZ := thetaStore[2] zVel[axisZ] := speed -- computeMyTrig() switchCycle := 0 char = '@' reStart := FALSE TRUE SKIP IF roll SKIP TRUE SEQ IF mythetaZ = zero SKIP TRUE IF mythetaZ > zero mythetaZ := mythetaZ - one --0.5 (REAL32) TRUE mythetaZ := mythetaZ + one --0.5 (REAL32) move := NOT switch SEQ mythetaY := mythetaY + (mythetaZ / 5.0 (REAL32)) computeMyTrig () IF fire AND (NOT switch) SEQ IF (missilesActive + missilesLaunching) = maxMissiles SKIP m1Active AND m2Active -- still in launch sequence SKIP m1Active SEQ missilesLaunching := missilesLaunching + 1 m2Active := TRUE -- start launch of m2 m2Active SKIP -- wait for reload TRUE SEQ missilesLaunching := missilesLaunching + 1 m1Active := TRUE -- start launch of m1 move [4]REAL32 absVel RETYPES [playerStore FROM r.patch FOR 4] : SEQ UMat ( N0 ) quickRotate ( mythSinX, mythCosX, 'x', N0 ) quickRotate ( mythSinY, mythCosY, 'y', N0 ) matMul4 ( absVel, zVel, N0 ) IF (tCount > 200) AND turbo SEQ tCount := 0 turbo := FALSE zVel[axisZ] := maxVel TRUE tCount := tCount + 1 TRUE -- switch SEQ missile IS missileStore[driveMissile] : garbStore IS [missile FROM m.patch FOR (maxPatches * 2)] : [4]REAL32 mVel RETYPES [garbStore FROM 0 FOR 4] : SEQ UMat ( N0 ) quickRotate ( mythSinX, mythCosX, 'x', N0 ) quickRotate ( mythSinY, mythCosY, 'y', N0 ) matMul4 ( mVel, zVel, N0 ) iSpeed := INT TRUNC zVel [ axisZ] IF switch PAR INT number : SEQ IF missilesActive > 0 SEQ i = 0 FOR missilesActive fromMain ? CASE m.reqMissile ; number missile IS missileStore[number] : mA IS [missile FROM m.boundCentre FOR 4] : [4]REAL32 missAbs RETYPES mA : mV IS [missile FROM m.patch FOR 3] : [3]REAL32 missVel RETYPES mV : [16]REAL32 missFor RETYPES [missile FROM m.forTrans FOR 16] : [16]REAL32 missRev RETYPES [missile FROM m.revTrans FOR 16] : as IS ammoStatus[number] : SEQ as := as - 1 -- decrement frame count IF as = 0 SEQ toMain ! m.missileAck ; 0::missileData -- take it out of the ring missilesActive := missilesActive - 1 IF number = driveMissile -- were we driving it mSwitch := TRUE TRUE SKIP TRUE [4 * 4] REAL32 R : N0 IS N1 : -- shock horror SEQ IF number = driveMissile -- were we driving it SEQ SEQ i = 0 FOR 3 missAbs[i] := missAbs[i] + missVel[i] viewPoint := missAbs IF missAbs[1] > zero -- below the ground !!! SEQ toMain ! m.missileAck ; 0::missileData -- take it out of the ring as := 0 missilesActive := missilesActive - 1 mSwitch := TRUE TRUE SEQ [missileData FROM 0 FOR m.missileSize] := [missile FROM 0 FOR m.missileSize] mx IS missAbs[0] : my IS missAbs[1] : mz IS missAbs[2] : SEQ mFor := rotateOffsetFor -- rotate model to z axis scale ( msx, msy, msz, mFor) quickRotate ( mythSinZ, mythCosZ, 'z', mFor ) quickRotate ( mythSinX, mythCosX, 'x', mFor ) quickRotate ( mythSinY, mythCosY, 'y', mFor ) missFor := mFor -- save it translate (mx, my, mz, mFor) UMat ( N0) UMat ( mRev) N0[12] := -mx N0[13] := -my N0[14] := -mz quickRotate ( -mythSinY, mythCosY, 'y', mRev ) quickRotate ( -mythSinX, mythCosX, 'x', mRev ) quickRotate ( -mythSinZ, mythCosZ, 'z', mRev ) MatMul4b4 (screenRev, N0, mRev) --screenRev := N0 scale(isx, isy, isz, mRev) MatMul4b4 (missRev, mRev, rotateOffsetRev) MatMul4b4 ( mRev, N0, missRev) toMain ! m.missileAck ; m.missileSize::missileData TRUE mx IS missAbs[0] : my IS missAbs[1] : mz IS missAbs[2] : SEQ SEQ i = 0 FOR 3 missAbs[i] := missAbs[i] + missVel[i] IF my > zero -- below the ground !!! SEQ toMain ! m.missileAck ; 0::missileData -- take it out of the ring as := 0 missilesActive := missilesActive - 1 TRUE SEQ [missileData FROM 0 FOR m.missileSize] := [missile FROM 0 FOR m.missileSize] translate(mx, my, mz, mFor) UMat (N0) N0[12] := -mx N0[13] := -my N0[14] := -mz MatMul4b4 (mRev, N0, mRev ) toMain ! m.missileAck ; m.missileSize::missileData m.missileDead ; number SEQ ammoStatus[number] := 0 missilesActive := missilesActive - 1 IF number = driveMissile -- were we driving it mSwitch := TRUE TRUE SKIP TRUE SKIP SEQ IF m1Active SEQ m1seq := m1seq + 1 IF m1seq = 8 SEQ startM := 1 m1Active := FALSE m1seq := 0 TRUE SKIP TRUE SKIP IF m2Active SEQ m2seq := m2seq + 1 IF m2seq = 8 SEQ startM := 2 m2Active := FALSE m2seq := 0 TRUE SKIP TRUE SKIP [4]REAL32 playerPos RETYPES [playerStore FROM r.boundCentre FOR 4] : [4]REAL32 absVel RETYPES [playerStore FROM r.patch FOR 4] : SEQ noPatches := patches SEQ i = 0 FOR 3 playerPos[i] := playerPos[i] + absVel[i] IF playerPos[1] > zero SEQ playerPos[1] := one -- zero hit := TRUE pSwitch := TRUE TRUE SKIP px IS playerPos[0] : py IS playerPos[1] : pz IS playerPos[2] : SEQ [ringData FROM 0 FOR r.minRingSize] := [playerStore FROM 0 FOR r.minRingSize] translate(px, py, pz, myFor) UMat (N0) N0[12] := -px N0[13] := -py N0[14] := -pz MatMul4b4 (myRev, N0, myRev ) patchList IS [ ringData FROM r.patch FOR (maxPatches * 2)]: [maxPatches][2]INT patch RETYPES patchList : p0 IS patch[0] : p1 IS patch[1] : p2 IS patch[2] : p3 IS patch[3] : IF myType = (INT a.type.chopper) SEQ p0 := [ patch1Offset, patch1 [ frameNumber/\7]] p1 := [ patch2Offset, patch2 [ frameNumber/\7]] p2 := [ patch3Offset, patch3 [m1seq] ] p3 := [ patch4Offset, patch4 [m2seq] ] myType = (INT a.type.plane) SEQ p0 := [ patch1Offset, patch1 [ m1seq ]] p1 := [ patch2Offset, patch2 [ m2seq ]] TRUE SKIP TRUE PAR INT number : SEQ IF missilesActive > 0 SEQ i = 0 FOR missilesActive fromMain ? CASE m.reqMissile ; number missile IS missileStore[number] : mA IS [missile FROM m.boundCentre FOR 3] : [3]REAL32 missAbs RETYPES mA : mV IS [missile FROM m.patch FOR 3] : [3]REAL32 missVel RETYPES mV : as IS ammoStatus[number] : SEQ as := as - 1 IF as = 0 SEQ toMain ! m.missileAck ; 0::missileData -- take it out of the ring missilesActive := missilesActive - 1 TRUE [4 * 4] REAL32 R : N0 IS N1 : -- shock horror SEQ mx IS missAbs[0] : my IS missAbs[1] : mz IS missAbs[2] : SEQ SEQ i = 0 FOR 3 missAbs[i] := missAbs[i] + missVel[i] IF my > zero -- below the ground !!! SEQ toMain ! m.missileAck ; 0::missileData -- take it out of the ring as := 0 missilesActive := missilesActive - 1 TRUE SEQ [missileData FROM 0 FOR m.missileSize] := [missile FROM 0 FOR m.missileSize] translate(mx, my, mz, mFor) UMat (N0) N0[12] := -mx N0[13] := -my N0[14] := -mz MatMul4b4 (mRev, N0, mRev ) toMain ! m.missileAck ; m.missileSize::missileData m.missileDead ; number SEQ ammoStatus[number] := 0 missilesActive := missilesActive - 1 TRUE SKIP SEQ IF m1Active SEQ m1seq := m1seq + 1 IF m1seq = 8 SEQ startM := 1 m1Active := FALSE m1seq := 0 TRUE SKIP TRUE SKIP IF m2Active SEQ m2seq := m2seq + 1 IF m2seq = 8 SEQ startM := 2 m2Active := FALSE m2seq := 0 TRUE SKIP TRUE SKIP [4]REAL32 playerPos RETYPES [playerStore FROM r.boundCentre FOR 4] : [4]REAL32 absVel RETYPES [playerStore FROM r.patch FOR 4] : SEQ noPatches := patches SEQ i = 0 FOR 3 playerPos[i] := playerPos[i] + absVel[i] bound := playerPos viewPoint := playerPos IF playerPos[1] > zero SEQ hit := TRUE playerPos[1] := one IF hitCycle = 0 SEQ stack[0] := mythetaX stack[1] := mythetaY stack[2] := mythetaZ TRUE SKIP TRUE SKIP px IS playerPos[0] : py IS playerPos[1] : pz IS playerPos[2] : SEQ myFor := rotateOffsetFor -- rotate model to z axis scale ( msx, msy, msz, myFor) -- done in init quickRotate ( mythSinZ, mythCosZ, 'z', myFor ) quickRotate ( mythSinX, mythCosX, 'x', myFor ) quickRotate ( mythSinY, mythCosY, 'y', myFor ) mainFor := myFor -- save translate (px, py, pz, myFor) UMat ( N0) UMat ( myRev) N0[12] := -px N0[13] := -py N0[14] := -pz quickRotate ( -mythSinY, mythCosY, 'y', myRev ) quickRotate ( -mythSinX, mythCosX, 'x', myRev ) quickRotate ( -mythSinZ, mythCosZ, 'z', myRev ) MatMul4b4 (screenRev, N0, myRev) --screenRev := N0 scale(isx, isy, isz, myRev) MatMul4b4 (mainRev, myRev, rotateOffsetRev) MatMul4b4 ( myRev, N0, mainRev) patchList IS [ ringData FROM r.patch FOR (maxPatches * 2)]: [maxPatches][2]INT patch RETYPES patchList : p0 IS patch[0] : p1 IS patch[1] : p2 IS patch[2] : p3 IS patch[3] : IF myType = (INT a.type.chopper) SEQ p0 := [ patch1Offset, patch1 [ frameNumber/\7]] p1 := [ patch2Offset, patch2 [ frameNumber/\7]] p2 := [ patch3Offset, patch3 [m1seq] ] p3 := [ patch4Offset, patch4 [m2seq] ] myType = (INT a.type.plane) SEQ p0 := [ patch1Offset, patch1 [ m1seq ]] p1 := [ patch2Offset, patch2 [ m2seq ]] TRUE SKIP SEQ fromMain ? CASE m.reqNextObj ; mapSize::mapData SKIP m.beenHit ; mapSize::mapData hit := TRUE m.score ; mapSize::mapData score := score + 10 IF switch AND hit SEQ mSwitch := FALSE pSwitch := FALSE switch := FALSE switchCycle := 0 missile IS missileStore[driveMissile] : garbStore IS [missile FROM m.patch FOR (maxPatches * 2)] : [3]REAL32 thetaStore RETYPES [garbStore FROM 4 FOR 3] : REAL32 speed RETYPES garbStore[7] : SEQ thetaStore[0] := mythetaX thetaStore[1] := mythetaY thetaStore[2] := mythetaZ speed := zVel[axisZ] SEQ mythetaX := save[0] mythetaY := save[1] mythetaZ := save[2] zVel[axisZ] := save[3] computeMyTrig () driveMissile := -1 (pSwitch OR mSwitch) --OR hit SEQ mSwitch := FALSE pSwitch := FALSE switch := FALSE switchCycle := 0 missile IS missileStore[driveMissile] : garbStore IS [missile FROM m.patch FOR (maxPatches * 2)] : [3]REAL32 thetaStore RETYPES [garbStore FROM 4 FOR 3] : REAL32 speed RETYPES garbStore[7] : SEQ thetaStore[0] := mythetaX thetaStore[1] := mythetaY thetaStore[2] := mythetaZ speed := zVel[axisZ] SEQ mythetaX := save[0] mythetaY := save[1] mythetaZ := save[2] zVel[axisZ] := save[3] computeMyTrig () driveMissile := -1 TRUE SKIP switchCycle := switchCycle + 1 IF hit [4]REAL32 playerPos RETYPES [playerStore FROM r.boundCentre FOR 4] : [4]REAL32 absVel RETYPES [playerStore FROM r.patch FOR 4] : SEQ IF hitCycle =0 SEQ score := score - 5 stack[0] := mythetaX stack[1] := mythetaY stack[2] := mythetaZ TRUE SKIP SEQ hitCycle := hitCycle + 1 IF hitCycle < 60 SKIP hitCycle = 60 absVel[1] := 300.0 (REAL32) (hitCycle > 60) AND (playerPos[1] < zero) SEQ attr [ a.type] := a.type.explosion noPatches := 0 absVel[0] := zero absVel[2] := zero absVel[1] := absVel[1] + 9.81 (REAL32) IF hitCycle < 140 alterScales() hitCycle = 300 SEQ hitCycle := 169 playerPos[1] := 1.0 (REAL32) TRUE hitCycle := 140 (playerPos[1] > zero) AND (hitCycle < 170) -- hit the floor SEQ attr [ a.type] := a.type.explosion noPatches := 0 absVel[0] := zero absVel[1] := zero absVel[2] := zero alterScales() hitCycle = 170 SEQ attr [ a.type] := a.type.explosion noPatches := 0 initScales() hitCycle > 170 SEQ attr [ a.type] := a.type.explosion hitCycle := 0 noPatches := 0 hit := FALSE hitCount := hitCount + 1 turbo := FALSE tCount := 0 reStart := TRUE startCount := 0 mythetaX := 0.0 (REAL32) TRUE SKIP TRUE SKIP IF startM <> 0 SEQ startMissile ( startM - 1, N0) startM := 0 missilesLaunching := missilesLaunching - 1 missilesActive := missilesActive + 1 TRUE SKIP PAR INT len : SEQ len := r.minRingSize + (noPatches * 2) toMain ! m.player ; viewPoint ; screenRev ; len::ringData SEQ writen ( iSpeed, 4, 107 ) writen ( ammoStatus [ 0], 4, 70 ) writen ( ammoStatus [ 1], 4, 33 ) writen ( score, 400, 107 ) INT horiz : SEQ horiz := INT ROUND mythetaZ dial ( 0, horiz, 30, 15 ) dial ( 0, horiz-20, 30, 13 ) dial ( 0, horiz-40, 30, 11 ) dial ( 0, 220+horiz, 30, 11 ) dial ( 0, 200+horiz, 30, 13 ) dial ( 0, 180+horiz, 30, 15 ) horiz := -(INT ROUND mythetaX) dial ( 1, horiz, 30, 63 ) dial ( 1, horiz-20, 30, 60 ) dial ( 1, horiz-40, 30, 57 ) dial ( 1, 220+horiz, 30, 57 ) dial ( 1, 200+horiz, 30, 60 ) dial ( 1, 180+horiz, 30, 63 ) INT horiz : SEQ horiz := INT ROUND mythetaY halfDial ( 3, horiz, 30, 15 ) halfDial ( 3, horiz+180, 30, 30 ) halfDial ( 3, horiz+90, 30, 30 ) halfDial ( 3, horiz-90, 30, 30 ) INT bigAlt, littleAlt, hourHand : VAL pos IS (INT ROUND viewPoint[1]) + 500 : SEQ littleAlt := 90 + (pos / 10) bigAlt := 90 + (pos / 100) hourHand := 90 + (pos / 1000) dial ( 2, littleAlt, 30, 63 ) dial ( 2, bigAlt, 26, 15 ) dial ( 2, hourHand, 22, 30 ) SEQ SEQ i = 0 FOR mapSize p IS mapData [i] : [2]INT point : -- x, z SEQ -- NOTE x and y are reversed, as x-y is now the plane, and z is the height x IS point[0] : y IS point[1] : INT tipe RETYPES p[2] : INT horiz : SEQ x := - (INT TRUNC p[0]) -- x y := INT TRUNC p[1] -- z VAL scale IS 5000 : SEQ x := x / scale y := y / scale VAL minMapX IS -50 : VAL maxMapX IS 50 : VAL minMapY IS -50 : VAL maxMapY IS 50 : VAL centreX IS 160 : VAL centreY IS 60 : SEQ IF x < minMapX SKIP x > maxMapX SKIP TRUE IF y < minMapY SKIP y > maxMapY SKIP TRUE INT x1, y1 : SEQ x1 := centreX + x y1 := centreY + y IF tipe = (INT a.type.missile) addPoint (d.point, x1, y1, red) tipe = (INT a.type.explosion) SEQ addPoint (d.point, x1 , y1, 240) addPoint (d.point, x1+1, y1, 245) addPoint (d.point, x1, y1+1, 250) addPoint (d.point, x1+1, y1+1, 255) TRUE addPoint (d.point, x1, y1, bright) TRUE SKIP add ( d.stop ) IF switch VAL hairCol IS 73 : VAL rad IS 15 : SEQ addCircle ( d.outlineCircle, 256, 246, rad, hairCol ) addLine ( 236, 246, 40, 0, hairCol) addLine ( 256, 226, 0, 40, hairCol) TRUE SKIP add ( d.stop ) toMain ! m.headUpDisplay; disp.p::displayList disp.p := basic.p -- chop back display list IF (reStart) AND (startCount = 0) SEQ startCount := 1 attr [ a.type] := (BYTE myType) ringData[r.identity] := me initPlayer () createPatches (myType) noPatches := patches playerStore := ringData TRUE SKIP frameNumber := frameNumber PLUS 1 : PROC main ( CHAN OF RING fromRingHandler, toRingHandler, CHAN OF movement toMover, fromMover, CHAN OF polyChan toTraverser, fromTraverser, CHAN OF BYTES screen, VAL INT me, VAL BOOL playerHasScreen ) VAL maxObjects IS 20 : VAL maxStatics IS 10 : VAL NIL IS -15 : BOOL scoreUpdate : PROC wrch ( VAL BYTE ch ) IF playerHasScreen SKIP -- screen ! 18; ch TRUE SKIP : [maxObjects * r.maxRingSize] INT objectStore : [maxTrees][b.boundSize]INT boundBox : [6]REAL32 myBoundBox : [r.maxRingSize]INT ringData, myRingData : mF IS [myRingData FROM r.forTrans FOR 16] : mR IS [myRingData FROM r.revTrans FOR 16] : [16]REAL32 myFor RETYPES mF : [16]REAL32 myRev RETYPES mR : [4]BYTE myAttr RETYPES myRingData[r.attribute] : mType IS myAttr[a.type] : oF IS [ringData FROM r.forTrans FOR 16] : oR IS [ringData FROM r.revTrans FOR 16] : [16]REAL32 objFor RETYPES oF : [16]REAL32 objRev RETYPES oR : bc IS [ringData FROM r.boundCentre FOR 4] : [4]REAL32 bound RETYPES bc : ident IS ringData[0] : [6]REAL32 clipLimits : cxMin IS clipLimits[0] : cxMax IS clipLimits[1] : cyMin IS clipLimits[2] : cyMax IS clipLimits[3] : czMin IS clipLimits[4] : czMax IS clipLimits[5] : [16]REAL32 frontFor : INT listPointer, noObjects, head, tail : VAL o.p IS 0 : VAL o.z IS 1 : VAL o.prev IS 2 : VAL o.next IS 3 : VAL listRecord IS o.next + 1 : [maxObjects][listRecord] INT objectList : [headUpSize] INT displayList : INT disp.p : PROC transformBox ([b.boundSize]INT inBox, [16]REAL32 trans) INT noVertices : iv IS [inBox FROM b.first FOR (4*boundVertices) ] : [boundVertices][4]REAL32 riv RETYPES iv : SEQ noVertices := inBox[0] SEQ i = 0 FOR noVertices matMul4 ( riv[i], riv[i], trans) : PROC findMinMax ( [b.boundSize] INT box, [6] REAL32 myBox ) nv IS box[0] : minX IS myBox[0] : minY IS myBox[1] : minZ IS myBox[2] : maxX IS myBox[3] : maxY IS myBox[4] : maxZ IS myBox[5] : [boundVertices][4]REAL32 p RETYPES [box FROM b.first FOR (boundVertices * 4)] : VAL w IS 80.0 (REAL32) : VAL w2 IS w / 2.5 (REAL32) : SEQ minX := -w minY := -w2 minZ := -w2 maxX := w maxY := w2 maxZ := w2 : INT mapCount : [maxPoints][3]REAL32 mapStore : PROC trivReject([b.boundSize] INT object, [6]REAL32 limits, [16]REAL32 screenTrans, INT type, BOOL notChuckedAway) [4]REAL32 p : x IS p[0] : y IS p[1] : z IS p[2] : preVerts IS [object FROM b.first FOR (boundVertices * 4) ] : [boundVertices][4]REAL32 prePoint RETYPES preVerts : lxMin IS limits[0] : lxMax IS limits[1] : lyMin IS limits[2] : lyMax IS limits[3] : lzMin IS limits[4] : lzMax IS limits[5] : INT count : SEQ notChuckedAway := FALSE count := 0 WHILE (count < boundVertices) AND (NOT notChuckedAway) -- ???? prep IS prePoint[count] : SEQ matMul4(p, prep, screenTrans) -- do it here, saves doing it every time IF count = 0 IF mapCount > maxPoints SKIP TRUE map IS mapStore[mapCount] : INT mapType RETYPES map[2] : SEQ map[0] := p[0] -- x map[1] := p[2] -- z mapType := type mapCount := mapCount + 1 -- addMap(p) TRUE SKIP IF z < lzMin SKIP z > lzMax SKIP TRUE REAL32 w : SEQ w := (z * oneOverD) + one x := x / w IF x < lxMin SKIP x > lxMax SKIP TRUE SEQ y := y / w IF y < lyMin SKIP y > lyMax SKIP TRUE notChuckedAway := TRUE count := count + 1 : PROC insertList ( REAL32 z, []INT object, VAL INT s, VAL [16]REAL32 screenRev) VAL ptrToMe IS noObjects : listItem IS objectList [ ptrToMe] : --[4]REAL32 bound RETYPES [object FROM r.boundCentre FOR 4] : --z IS bound[axisZ] : [16]REAL32 oFr RETYPES [object FROM r.forTrans FOR 16] : [4]BYTE attr RETYPES object[r.attribute] : id IS object[r.identity] : [16]REAL32 trany : [16]INT itr RETYPES trany : INT iz, ty : BOOL ok : SEQ ty := INT (attr[a.type]) MatMul4b4 ( trany, oFr, screenRev) trivReject(boundBox[ty], clipLimits, trany, ty, ok) IF ok SEQ iz := (INT ROUND z) listItem [ o.p] := listPointer listItem [ o.z] := iz [ objectStore FROM listPointer FOR s ] := [ object FROM 0 FOR s ] IF head = NIL SEQ head := 0 tail := 0 listItem [ o.prev] := NIL listItem [ o.next] := NIL frontFor := oFr TRUE BOOL testingZ : INT ptr : SEQ ptr := head testingZ := TRUE WHILE testingZ testItem IS objectList [ptr] : IF iz < testItem [ o.z] SEQ listItem [ o.prev] := testItem [ o.prev] -- chain me back testItem [ o.prev] := ptrToMe -- chain him BACK to me listItem [ o.next] := ptr -- chain me NEXT to him IF listItem [ o.prev] = NIL SEQ head := ptrToMe frontFor := oFr TRUE SKIP testingZ := FALSE testItem [ o.next] = NIL SEQ testItem [ o.next] := ptrToMe listItem [ o.prev] := ptr listItem [ o.next] := NIL tail := ptrToMe testingZ := FALSE TRUE ptr := testItem [ o.next] [ objectStore FROM (listPointer + r.forTrans) FOR 16 ] := itr noObjects := noObjects + 1 listPointer := listPointer + r.maxRingSize TRUE SKIP : PROC collisionTest ([b.boundSize]INT object, [6]REAL32 limits, [16]REAL32 screenTrans, BOOL hit) [4]REAL32 p : x IS p[0] : y IS p[1] : z IS p[2] : preVerts IS [object FROM b.first FOR (boundVertices * 4) ] : [boundVertices][4]REAL32 prePoint RETYPES preVerts : lxMin IS limits[0] : lyMin IS limits[1] : lzMin IS limits[2] : lxMax IS limits[3] : lyMax IS limits[4] : lzMax IS limits[5] : INT count : SEQ count := 0 WHILE (count < boundVertices) AND (NOT hit) -- ???? prep IS prePoint[count] : SEQ matMul4(p, prep, screenTrans) -- do it here, saves doing it every time IF z < lzMin SKIP z > lzMax SKIP TRUE SEQ IF x < lxMin SKIP x > lxMax SKIP TRUE SEQ IF y < lyMin SKIP y > lyMax SKIP TRUE hit := TRUE count := count + 1 : [16]REAL32 screenRev : [4]REAL32 viewPoint : -- my current position INT length, mylength : [16]REAL32 trany : BOOL stillAlive, playing : BOOL hit : INT hitCount : SEQ scoreUpdate := FALSE cxMin := (REAL32 TRUNC xMin) cxMax := (REAL32 TRUNC xMax) cyMin := (REAL32 TRUNC yMin) cyMax := (REAL32 TRUNC yMax) czMin := (REAL32 TRUNC zMin) czMax := (REAL32 TRUNC zMax) INT len, trees : SEQ fromTraverser ? CASE c.nPoly ; trees SEQ i = 0 FOR trees fromTraverser ? CASE c.poly ; len::boundBox[i] stillAlive := TRUE playing := TRUE fromMover ? CASE m.trany ; trany toMover ! m.reqNextObj ; 0::mapStore fromMover ? CASE m.player ; viewPoint ; screenRev ; mylength::myRingData fromMover ? CASE m.headUpDisplay; disp.p::displayList PAR toRingHandler ! mylength::myRingData [b.boundSize]INT tempBox : [4]BYTE a RETYPES myRingData[r.attribute] : t IS a[a.type] : INT typ : SEQ typ := INT t tempBox := boundBox[typ] -- make a copy of it transformBox(tempBox, trany) findMinMax(tempBox, myBoundBox) hit := FALSE -- signals if I have been hit hitCount := 0 WHILE stillAlive AND playing BOOL readingRing : INT lSeq : [4] REAL32 absPos, relPos : z IS relPos [ 2] : SEQ mapCount := 0 lSeq := 0 PAR IF playerHasScreen SEQ toTraverser ! c.headUpDisplay; disp.p::displayList toTraverser ! c.endframe toTraverser ! c.transformAck; screenRev toTraverser ! c.vpoint ; viewPoint toTraverser ! c.world -- reduce bandwidth TRUE SKIP SEQ readingRing := TRUE head := NIL tail := NIL listPointer := 0 noObjects := 0 [4]BYTE attr RETYPES ringData[r.attribute] : WHILE readingRing [16]REAL32 trany : SEQ fromRingHandler ? length::ringData IF (ident <> me) SEQ IF attr[a.type] = a.type.missile INT ty : SEQ ty := (INT attr[a.type]) IF attr[a.state] = a.state.hit -- signal a hit SKIP hit toRingHandler ! length::ringData --toRingHandler ! ringData[r.attribute] TRUE bBox IS boundBox[ty] : SEQ MatMul4b4 ( trany, objFor, myRev) collisionTest(bBox, myBoundBox, trany, hit) IF hit attr[a.state] := a.state.hit -- signal a hit to missile owner TRUE SKIP toRingHandler ! length::ringData --toRingHandler ! ringData[r.attribute] TRUE SKIP SEQ --[absPos FROM 0 FOR 3] := [bound FROM 0 FOR 3] bound[3] := one --matMul4 (bound, bound, screenRev) matMul4 (relPos, bound, screenRev) insertList ( z, ringData, length, screenRev) attr[a.type] = a.type.missile INT no : SEQ no := INT ( attr[a.number] ) PAR IF attr[a.state] = a.state.hit -- a hit has been flagged SEQ --toRingHandler ! 0::ringData -- remove it from ring scoreUpdate := TRUE toMover ! m.missileDead ; no TRUE [r.maxRingSize]INT tempRing : SEQ toMover ! m.reqMissile ; no fromMover ? CASE m.missileAck ; length::tempRing toRingHandler ! length::tempRing SEQ SEQ --[absPos FROM 0 FOR 3] := [bound FROM 0 FOR 3] bound[3] := one --matMul4 (bound, bound, screenRev) matMul4 (relPos, bound, screenRev) insertList ( z, ringData, length, screenRev) TRUE SEQ readingRing := FALSE [16]REAL32 rev, for : SEQ rev := screenRev for := myFor PAR IF playerHasScreen INT ptr : BOOL traversing : SEQ ptr := tail traversing := ptr <> NIL WHILE traversing --[16] REAL32 trany : INT l : --, id, s : item IS objectList [ ptr] : SEQ l := item [ o.p] -- pointer to object ob IS [ objectStore FROM l FOR r.maxRingSize ] : oFr IS [ ob FROM r.forTrans FOR 16 ] : oRv IS [ ob FROM r.revTrans FOR 16 ] : [16]REAL32 oFor RETYPES oFr : [16]REAL32 oRev RETYPES oRv : a IS ob [ r.attribute] : pL IS [ ob FROM r.patch FOR (maxPatches * 2) ] : [ maxPatches][2]INT patchList RETYPES pL : [4] BYTE attr RETYPES a : INT np, type : [4] REAL32 relView : SEQ type := INT attr [ a.type] np := ob [ r.nPatches] toTraverser ! c.transformAck ; oFor -- done in insertList matMul4 ( relView, viewPoint, oRev) toTraverser ! c.vpoint ; relView -- me toTraverser ! c.selPatch ; type ; np::patchList ptr := item [ o.prev] traversing := ptr <> NIL TRUE SKIP SEQ IF hit -- missile has hit me from ring SKIP TRUE IF head = NIL SKIP TRUE INT l, id, s : item IS objectList [ head ] : SEQ l := item [ o.p] -- pointer to object id := objectStore [ l + r.identity ] ob IS [ objectStore FROM l FOR r.maxRingSize ] : oFr IS [ ob FROM r.forTrans FOR 16 ] : oRv IS [ ob FROM r.revTrans FOR 16 ] : [16]REAL32 oFor RETYPES oFr : [16]REAL32 oRev RETYPES oRv : a IS ob [ r.attribute] : [4] BYTE attr RETYPES a : INT ty : SEQ ty := INT (attr[a.type] ) MatMul4b4 ( trany, frontFor, myRev) collisionTest (boundBox[ty], myBoundBox, trany, hit) BOOL m, someoneLaunching : SEQ someoneLaunching := lSeq <> 0 IF hit SEQ toMover ! m.beenHit ; mapCount::mapStore hit := FALSE scoreUpdate SEQ toMover ! m.score ; mapCount::mapStore scoreUpdate := FALSE TRUE toMover ! m.reqNextObj ; mapCount::mapStore m := TRUE WHILE m SEQ fromMover ? CASE m.player ; viewPoint ; screenRev ; mylength::myRingData toRingHandler ! mylength::myRingData m.missileAck ; mylength::myRingData toRingHandler ! mylength::myRingData m.headUpDisplay; disp.p::displayList m := FALSE : PROC ringHandler (CHAN OF RING fromRing, toRing, fromMain, toMain, VAL INT me) [r.maxRingSize]INT ringDataIn, ringDataOut : BOOL ringRunning : INT lenOut, lenIn : SEQ ringRunning := TRUE fromMain ? lenOut::ringDataOut PAR toRing ! lenOut::ringDataOut fromRing ? lenIn::ringDataIn WHILE ringRunning [4]BYTE attr RETYPES ringDataIn[r.attribute] : identity IS ringDataIn[r.identity] : SEQ IF attr[a.type] = a.type.missile SEQ toMain ! lenIn::ringDataIn IF (attr[a.state] = a.state.hit) AND (identity = me) lenOut := 0 -- take out of ring attr[a.state] = a.state.hit SEQ ringDataOut := ringDataIn lenOut := lenIn TRUE fromMain ? lenOut::ringDataOut identity = me -- -- when we recieve this packet, we should know the positions of -- all other objects, and so passing this packet to the main -- process should result in the main updating the packet, and -- returning it (post haste!) -- [4]BYTE attr RETYPES ringDataOut[r.attribute] : SEQ toMain ! lenIn::ringDataIn fromMain ? lenOut::ringDataOut -- could be new missile or player IF attr [ a.type] = a.type.missile SEQ lenIn := lenOut ringDataIn := ringDataOut PAR toRing ! lenIn::ringDataIn fromMain ? lenOut::ringDataOut TRUE SKIP TRUE SEQ -- PAR toMain ! lenIn::ringDataIn -- internal channel SEQ ringDataOut := ringDataIn lenOut := lenIn IF lenOut = 0 -- object taken out of ring fromRing ? lenIn::ringDataIn TRUE PAR toRing ! lenOut::ringDataOut fromRing ? lenIn::ringDataIn : PROC ringBuffer ( CHAN OF RING in, out) [ r.maxRingSize ] INT ringData : WHILE TRUE INT l : SEQ in ? l::ringData out ! l::ringData : CHAN OF RING mainRing, ringMain, handlerBuffer, bufferHandler, a, b : CHAN OF movement mainMove, moveMain : PRI PAR PAR ringBuffer ( handlerBuffer, b ) ringBuffer ( b, toRing) ringBuffer ( fromRing, a) ringBuffer ( a, bufferHandler) ringHandler ( bufferHandler, handlerBuffer, mainRing, ringMain, me ) PAR mover ( moveMain, mainMove, keyboard, startChan, me, myType ) main ( ringMain, mainRing, mainMove, moveMain, toPipe, fromPipe, screen, me, playerHasScreen ) : PROC startUp (VAL INT ime, CHAN OF BYTES toMover) [4]BYTE buttons : BYTE len : INT counter : WHILE TRUE SEQ buttons[0] := '.' len := BYTE 1 counter := (4 - ime) * 30 buttons[0] := 'a' len := BYTE 1 SEQ i = 0 FOR 4 toMover ! len::buttons buttons[0] := '.' len := BYTE 1 SEQ i = 0 FOR ((4 - ime) TIMES 60) toMover ! len::buttons buttons[0] := 'a' len := BYTE 1 SEQ i = 0 FOR 12 SEQ toMover ! len::buttons buttons[0] := '2' len := BYTE 1 SEQ i = 0 FOR 2 SEQ toMover ! len::buttons buttons[0] := 'a' len := BYTE 1 SEQ i = 0 FOR 20 SEQ toMover ! len::buttons buttons[0] := '8' len := BYTE 1 SEQ i = 0 FOR 2 SEQ toMover ! len::buttons buttons[0] := '@' len := BYTE 1 toMover ! len::buttons : CHAN OF polyChan pip, carob : CHAN OF BYTES startMover : SEQ toJoystick ! (BYTE playerId) IF playerHasScreen = 1 CHAN OF BYTES keyboard, screen : CHAN OF polyChan a, b, tp : PAR startUp ( playerId, startMover) buildBoxes ( a, b, tp) player ( toRing, fromRing, toRenderer, tp, joyStick, startMover, screen, playerId , TRUE, myType ) TRUE CHAN OF BYTES k, s : CHAN OF polyChan a, b : PAR startUp ( playerId, startMover) buildBoxes ( a, b, pip) player ( toRing, fromRing, carob, pip, joyStick, startMover, s, playerId , FALSE, myType ) :