[Ivy]<Spreitzer>Top>MazeWar.df=>MazeWarPlayerImpl3.Mesa
Last Edited by: Spreitzer, June 30, 1984 4:40:12 pm PDT
DIRECTORY Commander, Graphics, GraphicsOps, MazeWarFinder, MazeWarPlayer, MazeWarPlayerInsides, ViewerBlast, ViewerClasses, ViewerOps;
MazeWarPlayerImpl3: CEDAR MONITOR
IMPORTS Graphics, GraphicsOps, MazeWarPlayerInsides, ViewerBlast, ViewerOps
EXPORTS MazeWarPlayerInsides =
INVARIANT
No paints are going on.
BEGIN OPEN MazeWarPlayerInsides;
wb: Number = w+2;
PaintMaze: PUBLIC ENTRY ViewerClasses.PaintProc--PROC [self: Viewer, context: Graphics.Context, whatChanged: REF ANY, clear: BOOL]-- =
BEGIN ENABLE UNWIND => {}; --not strictly right, but it helps debugging
Decisions: PROC =
BEGIN
crow, ccol, d, me, di: INTEGER;
mes: Square;
row ← p.row;
col ← p.col;
angle ← p.angle;
peek ← p.peek;
[prow, pcol, pdrow, pdcol, pangle] ← Peek[peek, row, col, angle];
IF fromScratch ← whatChanged = NIL THEN NULL
ELSE IF notMe ← whatChanged # p THEN
BEGIN
q ← NARROW[whatChanged];
shot ← q.shot;
wasShown ← q.sdistance > 0;
q.shot ← FALSE;
row ← q.row;
col ← q.col;
angle ← q.angle;
[prow, pcol, pdrow, pdcol, pangle] ← Peek[p.speek, p.srow, p.scol, p.sangle];
oDistance ← q.sdistance;
oAngle ← (q.sangle + 4 - pangle) MOD 4;
IF nowShown ← (q.sdistance ← Visible[p.mv, prow, pcol, pdrow, pdcol, row, col]) > 0 THEN
BEGIN
q.srow ← row;
q.scol ← col;
q.sangle ← angle;
nowShown ← TRUE;
END;
IF wasShown = nowShown THEN NULL
ELSE IF wasShown THEN shownPlayers ← Filter[shownPlayers, q]
ELSE shownPlayers ← CONS[q, shownPlayers];
RETURN;
END
ELSE BEGIN
oRow ← p.srow; oCol ← p.scol; oAngle ← p.sangle;
END;
IF shot ← p.shot THEN p.shot ← FALSE;
FOR sp: PlayerList ← shownPlayers, sp.rest WHILE sp # NIL DO
sp.first.sdistance ← -1;
ENDLOOP;
shownPlayers ← NIL;
crow ← prow;
ccol ← pcol;
mes ← p.mv.squares[me ← Index[p.mv, prow, pcol]];
d ← 0;
di ← Direction[p.mv, pdrow, pdcol];
WHILE mes.open DO
nu: INTEGER ← me + di;
IF d>0 AND mes.occupants # NIL THEN
BEGIN
FOR pl: PlayerList ← mes.occupants, pl.rest WHILE pl # NIL DO
pa: Angle ← pl.first.angle;
pl.first.srow ← crow;
pl.first.scol ← ccol;
pl.first.sangle ← pa;
pl.first.sdistance ← d;
shownPlayers ← CONS[pl.first, shownPlayers];
ENDLOOP;
END;
d ← d + 1;
mes ← p.mv.squares[me ← nu];
crow ← crow + pdrow;
ccol ← ccol + pdcol;
ENDLOOP;
p.srow ← row;
p.scol ← col;
p.sangle ← angle;
p.speek ← peek;
END;
p: Player ← NARROW[self.data];
q: Player ← NIL;
fromScratch, notMe, wasShown, nowShown, shot: BOOLEAN;
oRow, oCol, oDistance, oAngle: INTEGER;
row, col, peek, prow, pcol, pdrow, pdcol: INTEGER;
angle, pangle: Angle;
CallUnderMonitor1[Decisions];
Graphics.Translate[context, p.mv.topX, p.mv.topY];
IF fromScratch THEN
BEGIN
DrawTopview[context, p.mv];
DrawPlayerTop[context, row, col, angle];
END
ELSE IF notMe THEN
BEGIN
Graphics.Translate[context, p.mv.inX, p.mv.inY];
[] ← Graphics.SetPaintMode[context, invert];
Graphics.SetCP[context, 0, 0];
IF wasShown THEN DrawHallPlayer[context, q, oDistance, oAngle, shot, FALSE];
IF nowShown THEN DrawHallPlayer[context, q, q.sdistance, (angle + 4 - pangle) MOD 4, shot, TRUE];
RETURN;
END
ELSE BEGIN
IF clear THEN ERROR;
[] ← Graphics.SetPaintMode[context, invert];
DrawPlayerTop[context, oRow, oCol, oAngle];
DrawPlayerTop[context, p.srow, p.scol, p.sangle];
END;
Graphics.Translate[context, p.mv.inX, p.mv.inY];
IF shot THEN
BEGIN
left, top, topCompl: INTEGER;
[left, top] ← ViewerOps.UserToScreenCoords[
self,
p.mv.inX + p.mv.topX - wb,
p.mv.inY + p.mv.topY + wb];
topCompl ← screenBitmap.height-top;
Graphics.SetCP[blastContext, 0, 0];
[] ← Graphics.SetPaintMode[blastContext, opaque];
IF left < 0 OR topCompl < 0 THEN
BEGIN--ViewerBlast.DrawBitmap should do this, but doesn't
Graphics.SetColor[blastContext, Graphics.white];
Graphics.DrawBox[blastContext, [-wb, -wb, wb, wb]];
Graphics.SetColor[blastContext, Graphics.black];
END;
ViewerBlast.DrawBitmap[self: blastContext, bitmap: screenBitmap,
w: 2*wb, h: 2*wb, x: left, y: topCompl,
xorigin: left+wb, yorigin: screenBitmap.height-top+wb];
ViewerBlast.Blast[bm: blastBitmap, bmw: [0, 0, blastBitmap.width, blastBitmap.height], lowerLeft: [left, top-2*wb], speedChooser: ViewerBlast.RandomSpeed, initial: TRUE, backwards: FALSE];
DrawHall[blastContext, p.mv, prow, pcol, pdrow, pdcol, pangle];
ViewerBlast.Blast[bm: blastBitmap, bmw: [0, 0, blastBitmap.width, blastBitmap.height], lowerLeft: [left, top-2*wb], speedChooser: ViewerBlast.RandomSpeed, initial: TRUE, backwards: TRUE];
END
ELSE BEGIN
DrawHall[context, p.mv, prow, pcol, pdrow, pdcol, pangle];
END;
END;
screenBitmap: Bitmap ← GraphicsOps.ScreenBitmap[];
blastBitmap: Bitmap ← GraphicsOps.NewBitmap[2*wb, 2*wb];
blastContext: Context ← GraphicsOps.NewContextFromBitmap[blastBitmap];
DrawHallPlayer: PROC [context: Context, q: Player, d: INTEGER, angle: Angle, shot, backwards: BOOLEAN] =
BEGIN
b: Bitmap ← q.pics.pics[d][angle];
IF shot THEN
BEGIN
lowerLeft: ViewerBlast.IntPt;
[lowerLeft.x, lowerLeft.y] ← ViewerOps.UserToScreenCoords[
q.mv.maze,
q.mv.inX + q.mv.topX - b.width/2,
q.mv.inY + q.mv.topY + b.height/2 - b.height];
ViewerBlast.Blast[bm: b, bmw: [0, 0, b.width, b.height], lowerLeft: lowerLeft, speedChooser: ViewerBlast.RandomSpeed, backwards: backwards];
END
ELSE GraphicsOps.DrawBitmap[self: context, bitmap: b, w: b.width, h: b.height, x: 0, y: 0, xorigin: b.width/2, yorigin: b.height/2];
END;
DrawTopview: PROC [context: Context, mv: MazeView] =
BEGIN
FOR row: INTEGER IN [0 .. mv.rows) DO
FOR col: INTEGER IN [0 .. mv.cols) DO
x: INTEGER ← col*tvd;
y: INTEGER ← -row*tvd;
index: INTEGER ← Index[mv, row, col];
IF NOT mv.squares[index].open THEN Graphics.DrawBox[context, [x, y-tvd, x+tvd, y]];
ENDLOOP;
ENDLOOP;
END;
DrawPlayerTop: PROC [context: Context, row, col: INTEGER, angle: Angle] =
BEGIN
Graphics.SetCP[context, col*tvd, -(row+1)*tvd];
GraphicsOps.DrawBitmap[self: context, bitmap: topviews[angle], w: tvd, h: tvd, x: 0, y: 0, xorigin: 0, yorigin: tvd];
END;
releaseDirectory: ROPE ← DefaultRemoteNames.Get[].current;
Setup: PROC =
BEGIN
[] ← CommandTool.Run[bcdName: releaseDirectory.Cat["MazeWar>MazeWarCommon.BCD"]];
[] ← CommandTool.Run[bcdName: "[Ivy]<MBrown>Top>PutFPatchImpl.BCD"];
Graphics.Translate[blastContext, wb, wb];
END;
Setup[];
END.