[Cedar]<CedarChest®>Top>MazeWar.df=>MazeWarPlayerImpl3.Mesa
Last Edited by: Spreitzer, June 18, 1985 1:55:34 pm PDT
DIRECTORY Commander, Imager, ImagerBackdoor, ImagerPixelMap, MazeWarPlayer, MazeWarPlayerInsides, ViewerBlast, ViewerClasses, ViewerOps;
MazeWarPlayerImpl3: CEDAR MONITOR
IMPORTS Imager, ImagerBackdoor, ImagerPixelMap, MazeWarPlayerInsides, ViewerBlast, ViewerOps
EXPORTS MazeWarPlayerInsides =
INVARIANT
No paints are going on.
BEGIN OPEN MazeWarPlayerInsides;
wb: Number = w+2;
PaintMaze: PUBLIC ENTRY PROC [self: Viewer, context: Imager.Context, whatChanged: REF, clear: BOOL] RETURNS [quit: BOOLFALSE] --ViewerClasses.PaintProc-- =
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];
context.TranslateT[[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
context.TranslateT[[p.mv.inX, p.mv.inY]];
context.SetColor[ImagerBackdoor.invert];
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;
context.SetColor[ImagerBackdoor.invert];
DrawPlayerTop[context, oRow, oCol, oAngle];
DrawPlayerTop[context, p.srow, p.scol, p.sangle];
END;
context.TranslateT[[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.sSize-top;
blastContext.SetColor[Imager.white];
blastContext.MaskRectangle[[-wb, -wb, 2*wb, 2*wb]];
blastContext.SetColor[Imager.black];
ViewerBlast.MaskPixelMap[context: blastContext,
pm: screenBitmap.Clip[
[sMin: topCompl, fMin: left, sSize: 2*wb, fSize: 2*wb]],
deviceOrgF: left+wb, deviceOrgS: topCompl+wb];
ViewerBlast.Blast[pm: blastBitmap, lowerLeft: [left, top-2*wb], speedChooser: ViewerBlast.RandomSpeed, initial: TRUE, backwards: FALSE];
DrawHall[blastContext, p.mv, prow, pcol, pdrow, pdcol, pangle];
ViewerBlast.Blast[pm: blastBitmap, 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 ← ViewerBlast.ScreenPixelMap[];
blastBitmap: Bitmap ← ImagerPixelMap.Create[0, [0, 0, 2*wb, 2*wb]];
blastContext: Context ← ViewerBlast.PixelMapContext[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.fSize/2,
q.mv.inY + q.mv.topY + b.sSize/2 - b.sSize];
ViewerBlast.Blast[pm: b, lowerLeft: lowerLeft, speedChooser: ViewerBlast.RandomSpeed, backwards: backwards];
END
ELSE ViewerBlast.DrawBitmap[context: context, bitmap: b, fOrigin: b.fSize/2, sOrigin: b.sSize/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 context.MaskBox[[x, y-tvd, x+tvd, y]];
ENDLOOP;
ENDLOOP;
END;
DrawPlayerTop: PROC [context: Context, row, col: INTEGER, angle: Angle] =
BEGIN
ViewerBlast.DrawBitmap[context: context, bitmap: topviews[angle], fOrigin: -col*tvd, sOrigin: -row*tvd];
END;
Setup: PROC =
BEGIN
blastContext.TranslateT[[wb, wb]];
END;
Setup[];
END.