{CedarChest}Top>MazeWar.DF=>MazeWarCommonStuffImpl.Mesa
Last Edited by: Spreitzer, August 17, 1985 5:37:35 pm PDT
DIRECTORY Basics, FS, Imager, ImagerBackdoor, ImagerColorOperator, ImagerPath, ImagerPixelArray, ImagerPixelMap, ImagerTransformation, MazeWarPlayerInsides, MessageWindow, RedBlackTree, Rope, ViewerBlast;
MazeWarCommonStuffImpl: CEDAR MONITOR
IMPORTS FS, Imager, ImagerBackdoor, ImagerColorOperator, ImagerPixelArray, ImagerPixelMap, ImagerTransformation, MessageWindow, RedBlackTree, Rope, ViewerBlast
EXPORTS MazeWarPlayerInsides
= BEGIN OPEN MazeWarPlayerInsides;
suffixes: ARRAY Angle OF ROPE ← ["Back.ais", "Right.ais", "Front.ais", "Left.ais"];
defaultPlayerPics: PUBLIC PlayerPics ← NEW [PlayerPicsRep ← [NIL, ALL[ALL[nilBitmap]]]];
picsTable: RedBlackTree.Table ← RedBlackTree.Create[GetPixKey, ComparePix];
GetPixKey: PROC [r: REF ANY] RETURNS [rope: ROPE] --RedBlackTree.GetKey-- = {
rope ← WITH r SELECT FROM
x: ROPE => x,
x: PlayerPics => x.name,
ENDCASE => ERROR};
ComparePix: PROC [k, data: REF ANY] RETURNS [Basics.Comparison] --RedBlackTree.Compare-- =
BEGIN
k1: ROPENARROW[k];
k2: ROPE ← GetPixKey[data];
RETURN [k1.Compare[s2: k2, case: FALSE]];
END;
GetPlayerPics: PUBLIC PROC [root: ROPE] RETURNS [pp: PlayerPics] =
BEGIN
IF root.Length[] < 1 OR root.Equal["default", FALSE] THEN RETURN [defaultPlayerPics];
pp ← NARROW[picsTable.Lookup[root]];
IF pp = NIL THEN {
newPics: PlayerPics ← ReadPlayerPics[root];
Insert: ENTRY PROC = {
pp ← NARROW[picsTable.Lookup[root]];
IF pp = NIL THEN picsTable.Insert[pp ← newPics, GetPixKey[newPics]]};
Insert[];
};
END;
NormalizePlayerPicsRoot: PUBLIC PROC [rawRoot: ROPE] RETURNS [normalRoot: ROPE] = {
suff: ROPE = suffixes[FIRST[Angle]];
suffL: INT = suff.Length[];
nameL: INT;
rawFileName: ROPE;
fullRawFileName, remoteFileName, fullRemoteFileName: ROPENIL;
cp: FS.ComponentPositions;
negate: BOOL = '- = rawRoot.Fetch[0];
IF negate THEN rawRoot ← rawRoot.Substr[start: 1];
rawFileName ← rawRoot.Cat[suff];
[fullRawFileName, cp] ← FS.ExpandName[rawFileName];
IF cp.server.length = 0 THEN {
[attachedTo: remoteFileName] ← FS.FileInfo[rawFileName];
IF remoteFileName.Length[] = 0 THEN RETURN [NIL];
}
ELSE {
remoteFileName ← fullRawFileName;
};
[fullRemoteFileName, cp] ← FS.ExpandName[remoteFileName];
normalRoot ← fullRemoteFileName.Substr[len: cp.ext.start + cp.ext.length];
nameL ← normalRoot.Length[];
IF NOT normalRoot.Substr[start: nameL - suffL].Equal[suff, FALSE] THEN ERROR;
normalRoot ← normalRoot.Substr[len: nameL - suffL];
IF negate THEN normalRoot ← Rope.Cat["-", normalRoot];
};
identityTransform: ImagerTransformation.Transformation ← ImagerTransformation.Translate[[0, 0]];
ReadPlayerPics: PROC [root: ROPE] RETURNS [pp: PlayerPics] =
BEGIN
negate: BOOLEAN ← '- = root.Fetch[0];
MessageWindow.Append[Rope.Cat["Patience... loading images from ", root, " ..."], TRUE];
pp ← NEW [PlayerPicsRep ← [root, ALL[ALL[nilBitmap]]]];
IF negate THEN root ← root.Substr[1, root.Length[]-1];
FOR a: Angle IN Angle DO
image: ImagerPixelArray.PixelArray;
ib: Imager.Box;
imageSize, cx, cy: REAL;
maxSample: ImagerPixelArray.Sample;
image ← ImagerPixelArray.FromAIS[root.Cat[suffixes[a]]];
maxSample ← ImagerPixelArray.MaxSampleValue[image, 0];
ib ← ImageBox[image];
imageSize ← MAX[ib.xmax-ib.xmin, ib.ymax-ib.ymin];
cx ← (ib.xmin+ib.xmax)/2;
cy ← (ib.ymin+ib.ymax)/2;
FOR d: INTEGER IN [1 .. MaxDistance] DO
rd: INTEGER ← r/(z1+(d-1)*dz);
scale: REAL ← 2*rd/imageSize;
context: Context;
PaintIt: PROC = {
context.ScaleT[scale];
context.TranslateT[[-cx, -cy]];
SELECT maxSample FROM
1 => context.SetSampledBlack[image];
ENDCASE => context.SetSampledColor[
pa: image,
colorOperator: ImagerColorOperator.GrayLinearColorModel[sWhite: maxSample, sBlack: 0, maxSampleValue: maxSample]
];
context.MaskBox[ib];
};
pp.pics[d][a] ← ImagerPixelMap.Create[0, [0, 0, rd*2, rd*2]];
context ← ViewerBlast.PixelMapContext[pp.pics[d][a]];
context.TranslateT[[rd, rd]];
IF negate THEN {
context.DoSave[PaintIt];
context.SetColor[ImagerBackdoor.invert];
context.MaskRectangle[[-rd, -rd, rd*2, rd*2]];
}
ELSE PaintIt[];
ENDLOOP;
ENDLOOP;
MessageWindow.Append[" done", FALSE];
END;
Rotate: PROC [x, y: REAL, angle: Angle] RETURNS [rx, ry: REAL] =
BEGIN
IF angle >= 2 THEN {x ← -x; y ← -y; angle ← angle-2};
IF angle = 0 THEN RETURN [x, y];
RETURN [-y, x];
END;
LosePlayerPics: PUBLIC ENTRY PROC [root: ROPE] = {[] ← picsTable.Delete[root]};
DefineDefaultPlayerPics: PROC = {
FOR a: Angle IN Angle DO
FOR d: INTEGER IN [1 .. MaxDistance] DO
Arrow: ImagerPath.PathProc = {
Draw: PROC [x, z: REAL] =
BEGIN
y: REAL;
[z, x] ← Rotate[z, x, a];
z ← ((z+1)*dz/2 + (d-1)*dz + z1)/r;
y ← -1/z;
x ← x/z;
lineTo[[x, y]];
END;
Move: PROC [x, z: REAL] =
BEGIN
y: REAL;
[z, x] ← Rotate[z, x, a];
z ← ((z+1)*dz/2 + (d-1)*dz + z1)/r;
y ← -1/z;
x ← x/z;
moveTo[[x, y]];
END;
Move[0, 1];
Draw[-1, 0];
Draw[-.5, 0];
Draw[-.5, -1];
Draw[.5, -1];
Draw[.5, 0];
Draw[1, 0];
Draw[0, 1];
};
context: Context;
rd: INTEGER ← (s + d-1)/d;
defaultPlayerPics.pics[d][a] ← ImagerPixelMap.Create[0, [0, 0, rd*2, rd*2]];
context ← ViewerBlast.PixelMapContext[defaultPlayerPics.pics[d][a]];
context.SetColor[Imager.white];
context.MaskRectangle[[0, 0, rd*2, rd*2]];
context.SetColor[Imager.black];
context.TranslateT[[rd, rd]];
context.MaskFill[Arrow];
ENDLOOP;
ENDLOOP;
};
ImageBox: PROC [pa: ImagerPixelArray.PixelArray] RETURNS [b: Imager.Box] = {
r: ImagerTransformation.Rectangle ← pa.m.TransformRectangle[[0, 0, pa.sSize, pa.fSize]];
b ← [xmin: r.x, ymin: r.y, xmax: r.x+r.w, ymax: r.y+r.h];
};
Setup: PROC =
BEGIN
END;
Setup[];
END.