<<{CedarChest}Top>MazeWar.DF=>MazeWarCommonStuffImpl.Mesa>> <> 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: ROPE _ NARROW[k]; k2: ROPE _ GetPixKey[data]; RETURN [k1.Compare[s2: k2, case: FALSE]]; END; GetPlayerPics: PUBLIC PROC [root: ROPE] RETURNS [pp: PlayerPics] = BEGIN <> 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: ROPE _ NIL; 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.