PaintMaze:
PUBLIC
ENTRY
PROC [self: Viewer, context: Imager.Context, whatChanged:
REF, clear:
BOOL]
RETURNS [quit:
BOOL ←
FALSE]
--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;
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;