-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathEngine3D_DrawXLine.p
1497 lines (1266 loc) · 35.2 KB
/
Engine3D_DrawXLine.p
1
unit Engine3D_DrawXLine;{ Dimensione delle variabili globali: 95 }interfaceuses types, memory, quickdraw, icons, Dream3Display_Tipi, Engine3D_Globals, Engine3D_Roofs; const One = $10000;procedure ScanForX (var ThePolyN : integer; TheX : integer; var TheXLine : integer; var ThePoly : Poly3D);procedure DrawXLine ( TheX : integer; TheCIconX : integer; ThePoly : Poly3D);procedure CopyTheBack;procedure DrawTheRest ( TheX : integer);procedure PlotMaskPICT ( ThePICTPtr : ptr; TheMaskPtr : ptr; var TheDimension : rect; var TheRect : rect);procedure PlotHMaskPICT ( ThePICTPtr : ptr; TheMaskPtr : ptr; var TheDimension : rect; var TheRect : rect; StartX, EndX : integer);function GetNPCFace ( TheDirection : integer) : integer; procedure FastPlotHCicon ( TheCIconPtr : ptr; var TheRect : rect);procedure PlotMMaskPICT ( TheMaskPtr : ptr; var TheDimension : rect; var TheRect : rect);procedure PlotHMMaskPICT ( ThePICTPtr : integerptr; var TheDimension : rect; var TheRect : rect; StartX, EndX : integer);procedure PlotGhostPICT ( ThePICTPtr : ptr; TheMaskPtr : ptr; var TheDimension : rect; var TheRect : rect; StartX, EndX : integer);var ZeroRect : rect; LastIcon : integer; LastSeed : integer; FloorSpaceRect, CeilingSpaceRect : LongRect; Empty : boolean; TheCurIcon : ciconhandle; CIconSpaceRect : rect; ScreenSpaceRect : LongRect; implementation{$R-}uses qdoffscreen, toolutils, AppleEvents, AERegistry, fixmath, cilindro, dreamtypes, segload, Engine3D_DrawProc, Engine3D_CIconArray, Engine3D_DrawFloor;type Byte3 = packed array [0..2] of byte; Byte3Ptr = ^Byte3; BytePtr = ^byte; const OutOfFireDistance = 1500;var YStart, YEnd : integer; DstAddr : ptr; Middle : integer;{$S Engine3D}procedure ScanForX (var ThePolyN : integer; TheX : integer; var TheXLine : integer; var ThePoly : Poly3D);label 101; var LocalPolys : PolyArrayPtr; LocalPolyN : integer; LocalThePolyN : integer; ThePolyLevel : integer; LocalCurrentLevel : integer; begin LocalPolys := Polys; LocalPolyN := PolyN; LocalThePolyN := ThePolyN; LocalCurrentLevel := CurrentLevel; while LocalThePolyN <= LocalPolyN do begin{101:} ThePolyLevel := LocalPolys^ [LocalThePolyN].Levels; if ThePolyLevel > LocalCurrentLevel then begin ThePoly := LocalPolys^ [LocalThePolyN]; LocalThePolyN := LocalThePolyN + 1; if (TheX >= ThePoly.ProjCorner0.X) and (TheX <= ThePoly.ProjCorner1.X) then begin if ThePoly.PoType = RoofPoly then begin DrawRoof (ThePoly.BaseRef, TheX); LocalCurrentLevel := CurrentLevel; goto 101; end; TheXLine := bsr (fixdiv (TheX - ThePoly.ProjCorner0.X, ThePoly.XDist + 1), 10); if ThePoly.Dir <> 0 then TheXLine := CIconMaxH - TheXLine; if LocalCurrentLevel = 0 then begin ZBuffer [TheX] := ThePoly.MiddleZ;{ if Dettaglio = 2 then begin ZBuffer [TheX + 1] := ThePoly.MiddleZ; end else if Dettaglio = 3 then begin ZBuffer [TheX + 1] := ThePoly.MiddleZ; ZBuffer [TheX + 2] := ThePoly.MiddleZ; end; end else} if Dettaglio = 2 then ZBuffer [TheX + 1] := ThePoly.MiddleZ; end; Base^ [ThePoly.BaseRef].Seen := true;{ LocalThePolyN := LocalThePolyN + 1;} ThePolyN := LocalThePolyN; exit (ScanForX); end; end else LocalThePolyN := LocalThePolyN + 1;101: end; ThePoly.CIcon := 0; ThePolyN := LocalThePolyN;end;{$S Engine3D}procedure PutFloor2;var I : integer; SrcAddr, LocalDstAddr : ptr; ISrcAddr, IDstAddr : integerptr; LocalSrcRow : integer; LocalDstRow : integer; Delta : integer; begin if YEnd > 199 then exit (PutFloor2); LocalSrcRow := SrcRow; LocalDstRow := DstRow; with ScreenSpaceRect do begin top := YEnd; bottom := 199; end; Delta := ScreenSpaceRect.bottom - ScreenSpaceRect.top; with FloorSpaceRect do begin left := bsr (abs (random), 11); top := FloorSpaceRect.bottom - (Delta) - 1; end; SrcAddr := ptr (longint (Environment.FloorGWorld^.portpixmap^^.BaseAddr) + FloorSpaceRect.left + SrcRow * FloorSpaceRect.top); case Dettaglio of 1 : begin LocalDstAddr := DstAddr; for I := Delta downto 0 do begin LocalDstAddr^ := SrcAddr^; SrcAddr := ptr (longint (SrcAddr) + LocalSrcRow); LocalDstAddr := ptr (longint (LocalDstAddr) + LocalDstRow); end; end; 2 : begin IDstAddr := integerptr (DstAddr); ISrcAddr := integerptr (SrcAddr); for I := Delta downto 0 do begin IDstAddr^ := ISrcAddr^; ISrcAddr := integerptr (longint (ISrcAddr) + LocalSrcRow); IDstAddr := integerptr (longint (IDstAddr) + LocalDstRow); end; end;{ 3 : begin TDstAddr := Byte3Ptr (DstAddr); TSrcAddr := Byte3Ptr (SrcAddr); for I := Delta downto 0 do begin TDstAddr^ := TSrcAddr^; TSrcAddr := Byte3Ptr (longint (TSrcAddr) + LocalSrcRow); TDstAddr := Byte3Ptr (longint (TDstAddr) + LocalDstRow); end; end;} end; end; {$S Engine3D}procedure PutCeiling;var I : integer; SrcAddr : ptr; ISrcAddr, IDstAddr : integerptr; LocalDstRow : integer; LocalSrcRow : integer; begin with ScreenSpaceRect do begin bottom := YStart - 1; end; with CeilingSpaceRect do left := bsr (abs (random), 12); LocalSrcRow := SrcRow; LocalDstRow := DstRow; case Dettaglio of 1 : begin DstAddr := ptr (longint (OffScreenAddr) + ScreenSpaceRect.left); SrcAddr := ptr (longint (Environment.CeilingGWorld^.portpixmap^^.BaseAddr) + CeilingSpaceRect.left); for I := ScreenSpaceRect.bottom downto 0 do begin DstAddr^ := SrcAddr^; SrcAddr := ptr (longint (SrcAddr) + LocalSrcRow); DstAddr := ptr (longint (DstAddr) + LocalDstRow); end; end; 2 : begin IDstAddr := integerptr (longint (OffScreenAddr) + ScreenSpaceRect.left); ISrcAddr := integerptr (longint (Environment.CeilingGWorld^.portpixmap^^.BaseAddr) + CeilingSpaceRect.left); for I := ScreenSpaceRect.bottom downto 0 do begin IDstAddr^ := ISrcAddr^; ISrcAddr := integerptr (longint (ISrcAddr) + LocalSrcRow); IDstAddr := integerptr (longint (IDstAddr) + LocalDstRow); end; DstAddr := ptr (IDstAddr); end; end;end; {$S Engine3D}procedure DrawXLine ( TheX : integer; TheCIconX : integer; ThePoly : Poly3D);label 100; var TheMolti : fixed; {$S Engine3D}procedure FastCopyBits ( IsBorder : boolean);label 100; var I : integer; SrcAddr : ptr; LocalDstAddr : ptr; IDstAddr : integerptr; Dy, IconY : fixed; MaxMin2 : integer; LocalDstRow : integer; KBlack : byte; DKBlack : integer;{$S Engine3D}procedure FastBorder;var I : integer; TmpB : byte; TmpI : integer; SuperLocalDstAddr : ptr; SuperIDstAddr : integerptr; begin SuperLocalDstAddr := LocalDstAddr; case Dettaglio of 1 : begin I := MaxMin2 - Max (0, ScreenSpaceRect.top) + 1; if I <= 0 then goto 100; repeat TmpB := SrcAddr^; if TmpB <> 0 then SuperLocalDstAddr^ := TmpB; IconY := IconY + Dy; while IconY > One do begin IconY := IconY - One; SrcAddr := ptr (longint (SrcAddr) + 64); end; SuperLocalDstAddr := ptr (longint (SuperLocalDstAddr) + LocalDstRow); I := I - 1; until I = 0; DstAddr := SuperLocalDstAddr; end; 2 : begin if Middle < OutOfFireDistance then begin LocalDstRow := LocalDstRow - 1; I := MaxMin2 - Max (0, ScreenSpaceRect.top) + 1; if I <= 0 then goto 100; repeat TmpB := SrcAddr^; if TmpB <> 0 then SuperLocalDstAddr^ := TmpB; SuperLocalDstAddr := ptr (longint (SuperLocalDstAddr) + 1); TmpB := SrcAddr^; if TmpB <> 0 then SuperLocalDstAddr^ := TmpB; IconY := IconY + Dy; while IconY > One do begin IconY := IconY - One; SrcAddr := ptr (longint (SrcAddr) + 64); end; SuperLocalDstAddr := ptr (longint (SuperLocalDstAddr) + LocalDstRow); DstAddr := SuperLocalDstAddr; I := I - 1; until I = 0; end else begin if CIconSpaceRect.left = 63 then SrcAddr := ptr (longint (SrcAddr) - 1); SuperIDstAddr := integerptr (SuperLocalDstAddr); I := MaxMin2 - Max (0, ScreenSpaceRect.top) + 1; if I <= 0 then goto 100; repeat TmpI := integerptr (SrcAddr)^; if TmpI <> 0 then SuperIDstAddr^ := TmpI; IconY := IconY + Dy; while IconY > One do begin IconY := IconY - One; SrcAddr := ptr (longint (SrcAddr) + 64); end; SuperIDstAddr := integerptr (longint (SuperIDstAddr) + LocalDstRow); I := I - 1; until I = 0; DstAddr := ptr (SuperIDstAddr); end; end; end;end;begin LocalDstRow := DstRow; if ThePoly.MiddleZ > 0 then Middle := bsr (ThePoly.MiddleZ, 4) else Middle := 0; if Middle < Environment.LightIndex3 then Index := 3 else if Middle < Environment.LightIndex2 then Index := 2 else If Middle < Environment.LightIndex1 then Index := 1 else Index := 0; Index := Index + Base^ [ThePoly.BaseRef].Light; if Index > 3 then Index := 3 else if Index < 0 then Index := 0; LocalDstAddr := ptr (longint (OffScreenAddr) + ScreenSpaceRect.left); MaxMin2 := Min (ScreenSpaceRect.bottom, 199) - 1; if Index <> 0 then begin if ScreenSpaceRect.bottom - ScreenSpaceRect.top > 1023 then Dy := fixdiv (64, ScreenSpaceRect.bottom - ScreenSpaceRect.top) else Dy := Div64^ [ScreenSpaceRect.bottom - ScreenSpaceRect.top]; if ThePoly.PoType <> 6 then SrcAddr := ptr (longint (CIconArray [Index, ThePoly.CIcon]) + CIconSpaceRect.left) else SrcAddr := ptr (longint (ThePoly.CIcon) + CIconSpaceRect.left); IconY := 0; if ScreenSpaceRect.top < 0 then begin IconY := Dy * (- ScreenSpaceRect.top); SrcAddr := ptr (longint (SrcAddr) + band (bsr (IconY, 10), $FFFFFFC0)); while IconY > One do begin IconY := IconY - One; end; end else LocalDstAddr := ptr (longint (LocalDstAddr) + DstRowTop^ [ScreenSpaceRect.top]); if IsBorder then begin FastBorder; goto 100; end; case Dettaglio of 1 : begin I := MaxMin2 - Max (0, ScreenSpaceRect.top) + 1; if I <= 0 then goto 100; repeat LocalDstAddr^ := SrcAddr^; IconY := IconY + Dy; while IconY > One do begin IconY := IconY - One; SrcAddr := ptr (longint (SrcAddr) + 64); end; LocalDstAddr := ptr (longint (LocalDstAddr) + LocalDstRow); I := I - 1; until I = 0; DstAddr := LocalDstAddr; end; 2 : begin if Middle < OutOfFireDistance then begin LocalDstRow := LocalDstRow - 1; I := MaxMin2 - Max (0, ScreenSpaceRect.top) + 1; if I <= 0 then goto 100; repeat LocalDstAddr^ := SrcAddr^; LocalDstAddr := ptr (longint (LocalDstAddr) + 1); LocalDstAddr^ := SrcAddr^; IconY := IconY + Dy; while IconY > One do begin IconY := IconY - One; SrcAddr := ptr (longint (SrcAddr) + 64); end; LocalDstAddr := ptr (longint (LocalDstAddr) + LocalDstRow); DstAddr := LocalDstAddr; I := I - 1; until I = 0; end else begin if CIconSpaceRect.left = 63 then SrcAddr := ptr (longint (SrcAddr) - 1); IDstAddr := integerptr (LocalDstAddr); I := MaxMin2 - Max (0, ScreenSpaceRect.top) + 1; if I <= 0 then goto 100; repeat IDstAddr^ := integerptr (SrcAddr)^; IconY := IconY + Dy; while IconY > One do begin IconY := IconY - One; SrcAddr := ptr (longint (SrcAddr) + 64); end; IDstAddr := integerptr (longint (IDstAddr) + LocalDstRow); I := I - 1; until I = 0; DstAddr := ptr (IDstAddr); end; end; end; end else begin if ScreenSpaceRect.top > 0 then LocalDstAddr := ptr (longint (LocalDstAddr) + DstRowTop^ [ScreenSpaceRect.top]); case Dettaglio of 1 : begin KBlack := TheKBlack; for I := MaxMin2 - Max (0, ScreenSpaceRect.top) downto 0 do begin LocalDstAddr^ := KBlack; LocalDstAddr := ptr (longint (LocalDstAddr) + LocalDstRow); end; DstAddr := LocalDstAddr; end; 2 : begin DKBlack := TheDKBlack; IDstAddr := integerptr (LocalDstAddr); for I := MaxMin2 - Max (0, ScreenSpaceRect.top) downto 0 do begin IDstAddr^ := DKBlack; IDstAddr := integerptr (longint (IDstAddr) + LocalDstRow); end; DstAddr := ptr (IDstAddr); end; end; end;100:end;{$S Engine3D}function ScaleIconRect (Start, Stop, Limit : integer) : integer;begin if Limit >= Stop then begin ScaleIconRect := CIconMaxH + 1; exit (ScaleIconRect); end; if Limit > Start then ScaleIconRect := bsl (Limit - Start, 6) div (Stop - Start) else ScaleIconRect := -1;end;{$S Engine3D}procedure DrawLevels;var TheBaseL : Poly3DBase; Tmp : integer; LocalCIconRect : rect; LocalScreenRect : LongRect; TmpY : integer; {$S Engine3D}procedure FastCopyBits2 ( TheEnd : integer);label 100; var I : integer; SrcAddr, DstAddr : ptr; IDstAddr : integerptr; Dy, IconY : fixed; MaxMin2 : integer; LocalDstRow : integer; begin DstAddr := ptr (longint (OffScreenAddr) + LocalScreenRect.left); MaxMin2 := Min (LocalScreenRect.bottom - 1, TheEnd); LocalDstRow := DstRow; if Index <> 0 then begin if LocalScreenRect.bottom - LocalScreenRect.top > 1023 then Dy := fixdiv (64, LocalScreenRect.bottom - LocalScreenRect.top) else Dy := Div64^ [LocalScreenRect.bottom - LocalScreenRect.top]; SrcAddr := ptr (longint (CIconArray [Index, TheBaseL.CIcon]) + LocalCIconRect.left); IconY := 0; if LocalScreenRect.top < 0 then begin SrcAddr := ptr (longint (SrcAddr) + band (bsr (Dy * (- LocalScreenRect.top), 10), $FFFFFFC0)); end else DstAddr := ptr (longint (DstAddr) + DstRowTop^ [LocalScreenRect.top]); case Dettaglio of 1 : begin I := MaxMin2 - Max (0, LocalScreenRect.top) + 1; if I <= 0 then goto 100; repeat DstAddr^ := SrcAddr^; IconY := IconY + Dy; while IconY > One do begin IconY := IconY - One; SrcAddr := ptr (longint (SrcAddr) + 64); end; DstAddr := ptr (longint (DstAddr) + LocalDstRow); I := I - 1; until I = 0; end; 2 : begin if Middle < OutOfFireDistance then begin LocalDstRow := LocalDstRow - 1; I := MaxMin2 - Max (0, LocalScreenRect.top) + 1; if I <= 0 then goto 100; repeat DstAddr^ := ptr (SrcAddr)^; DstAddr := ptr (longint (DstAddr) + 1); DstAddr^ := ptr (SrcAddr)^; IconY := IconY + Dy; while IconY > One do begin IconY := IconY - One; SrcAddr := ptr (longint (SrcAddr) + 64); end; DstAddr := ptr (longint (DstAddr) + LocalDstRow); I := I - 1; until I = 0 end else begin if LocalCIconRect.left = 63 then SrcAddr := ptr (longint (SrcAddr) - 1); IDstAddr := integerptr (DstAddr); I := MaxMin2 - Max (0, LocalScreenRect.top) + 1; if I <= 0 then goto 100; repeat IDstAddr^ := integerptr (SrcAddr)^; IconY := IconY + Dy; while IconY > One do begin IconY := IconY - One; SrcAddr := ptr (longint (SrcAddr) + 64); end; IDstAddr := integerptr (longint (IDstAddr) + LocalDstRow); I := I - 1; until I = 0; end; end; end; end else begin if LocalScreenRect.top > 0 then DstAddr := ptr (longint (DstAddr) + DstRowTop^ [LocalScreenRect.top]); case Dettaglio of 1 : begin for I := MaxMin2 - Max (0, LocalScreenRect.top) downto 0 do begin DstAddr^ := TheKBlack; DstAddr := ptr (longint (DstAddr) + LocalDstRow); end; end; 2 : begin IDstAddr := integerptr (DstAddr); for I := MaxMin2 - Max (0, LocalScreenRect.top) downto 0 do begin IDstAddr^ := TheDKBlack; IDstAddr := integerptr (longint (IDstAddr) + LocalDstRow); end; end; end; end;100:end;begin CurrentLevel := 2; with ThePoly do with ScreenSpaceRect do begin top := 2 * YStart - YEnd; { + bsr ((TheX - ProjCorner0.X) * (DYStart - DYEnd), 16) + WindowYCenter;} bottom := YStart; end; LocalCIconRect := CIconSpaceRect; LocalScreenRect := ScreenSpaceRect; TheBaseL := BaseLevels^ [ThePoly.Next]; TmpY := ScaleIconRect (LocalScreenRect.top, LocalScreenRect.bottom, CurrentMaxY); if TmpY <> -1 then begin LocalCIconRect.bottom := TmpY; FastCopyBits2 (CurrentMaxY); if LocalScreenRect.top < CurrentMaxY then CurrentMaxY := LocalScreenRect.top; end; while TheBaseL.Next <> 0 do begin with ScreenSpaceRect do begin Tmp := top; top := 2 * Tmp - bottom; bottom := Tmp; end; LocalCIconRect := CIconSpaceRect; LocalScreenRect := ScreenSpaceRect; TheBaseL := BaseLevels^ [TheBaseL.Next]; TmpY := ScaleIconRect (LocalScreenRect.top, LocalScreenRect.bottom, CurrentMaxY); if TmpY <> -1 then begin LocalCIconRect.bottom := TmpY; LocalScreenRect.bottom := CurrentMaxY; end; FastCopyBits2 (CurrentMaxY); if LocalScreenRect.top < CurrentMaxY then CurrentMaxY := LocalScreenRect.top; CurrentLevel := CurrentLevel + 1; end;end; begin with ThePoly do begin TheMolti := (TheX - ProjCorner0.X) * DYStart; YEnd := YEnd0 + bsr ((TheX - ProjCorner0.X) * DYEnd, 16) + WindowYCenter + 1; YStart := YStart0 + bsr (TheMolti, 16) + WindowYCenter; end; with CIconSpaceRect do begin left := TheCIconX; end; with ScreenSpaceRect do begin left := TheX + WindowXCenter; top := YStart; bottom := YEnd; end; if (CurrentMaxY <> 200) then begin if ThePoly.MiddleZ > 0 then Middle := bsr (ThePoly.MiddleZ, 4) else Middle := 0; if Middle < Environment.LightIndex3 then Index := 3 else if Middle < Environment.LightIndex2 then Index := 2 else If Middle < Environment.LightIndex1 then Index := 1 else Index := 0; Index := Index + Base^ [ThePoly.BaseRef].Light; if Index > 3 then Index := 3 else if Index < 0 then Index := 0; if ThePoly.PoType = 0 then DrawLevels; goto 100; end; if (ThePoly.FullMask) or (ThePoly.PoType = 9) then SetVMin (YEnd - 1); CurrentLevel := 1; if (ThePoly.PoType = 9) then begin CurrentMaxY := YStart; FastCopyBits (true); end else if not (ThePoly.FullMask) then begin FastCopyBits (true); exit (DrawXLine); end else begin if YStart < CurrentMaxY then CurrentMaxY := YStart; FastCopyBits (false); if ThePoly.Next <> 0 then DrawLevels; end; if (Environment.FloorPictID <> 0) and (ord (ThePoly.FullMask) <> 0) then if not (Environment.DrawTheFloors) then PutFloor2 else begin end; if (Environment.CeilingPictID <> 0) and (ThePoly.FullMask) then if not (Environment.DrawTheCeilings) then PutCeiling;100:end;{$S Engine3D}procedure DrawTheRest ( TheX : integer);begin DstAddr := ptr (longint (OffScreenAddr) + TheX + DstRow * bsr (Environment.CommonRect.bottom - Environment.CommonRect.top, 1)); PutFloor2;end;{$S Engine3D}procedure CopyTheBack;var TheRectLeft, TheRectRight, TheRect : rect; begin with Environment do begin if not lockpixels (GroundGWorld^.portpixmap) then exit (CopyTheBack); TheRect := CommonRect; TheRect.bottom := bsr (TheRect.bottom, 1); setrect (TheRectLeft, (NAngles - 1 - ViewAngle) * AmplitudeOffSet, 0, (NAngles - 1 - ViewAngle) * AmplitudeOffSet + BackgroundAmplitude, BackgroundRect.bottom); TheRectRight.right := TheRectLeft.right - BackgroundRect.right; if TheRectRight.right <= 0 then copybits (bitmapptr (GroundGWorld^.portpixmap^)^, bitmapptr (OffScreenLab^.portpixmap^)^, TheRectLeft, TheRect, srccopy, nil) else begin TheRect.right := trunc (CommonRect.right * ((BackgroundRect.right - TheRectLeft.left) / BackgroundAmplitude)); TheRectLeft.right := BackgroundRect.right; copybits (bitmapptr (GroundGWorld^.portpixmap^)^, bitmapptr (OffScreenLab^.portpixmap^)^, TheRectLeft, TheRect, srccopy, nil); TheRect.left := TheRect.right; TheRect.right := CommonRect.right; with TheRectRight do begin left := 0; top := 0; bottom := BackgroundRect.bottom; end; copybits (bitmapptr (GroundGWorld^.portpixmap^)^, bitmapptr (OffScreenLab^.portpixmap^)^, TheRectRight, TheRect, srccopy, nil); end; unlockpixels (GroundGWorld^.portpixmap); end;end;{$S Engine3D}function GetNPCFace ( TheDirection : integer) : integer;var Tmp : integer; begin Tmp := 90 + TheDirection - Environment.ViewAngle; if Tmp > 179 then Tmp := Tmp - 180 else if Tmp < 0 then Tmp := Tmp + 180; case Tmp of 0..15 : GetNPCFace := 1; 16..45 : GetNPCFace := 6; 46..75 : GetNPCFace := 5; 76..105 : GetNPCFace := 4; 106..135 : GetNPCFace := 3; 136..165 : GetNPCFace := 2; 166..179 : GetNPCFace := 1; end;end;{$S Engine3D}procedure PlotMaskPICT ( ThePICTPtr : ptr; TheMaskPtr : ptr; var TheDimension : rect; var TheRect : rect);var I, J : integer; Dx, Dy : fixed; DrawRect : rect; DstAddr : ptr; IcX, IcY : fixed; TheDstRow, TheSrcRow : integer; ThePICT : ptr; ThePICTBase : ptr; TheMaskBase : integerptr; TheMask : integerptr; begin Dx := fixdiv (TheDimension.right, TheRect.right - TheRect.left + 2); Dy := fixdiv (TheDimension.bottom, TheRect.bottom - TheRect.top + 2); ThePICT := ThePICTPtr; TheMask := integerptr (TheMaskPtr); DstAddr := OffScreenAddr; TheSrcRow := TheDimension.right + 1; TheDstRow := DstRow - Environment.CommonRect.right; if TheRect.top < 0 then begin ThePICT := ptr (longint (ThePICT) - TheSrcRow * hiword (TheRect.top * Dy)); TheMask := integerptr (longint (TheMask) - TheSrcRow * hiword (TheRect.top * Dy)); DrawRect.top := 0; end else begin DstAddr := ptr (longint (DstAddr) + TheRect.top * DstRow); DrawRect.top := TheRect.top; end; if TheRect.left < 0 then begin ThePICT := ptr (longint (ThePICT) - hiword (Dx * TheRect.left)); TheMask := integerptr (longint (TheMask) - hiword (Dx * TheRect.left)); DrawRect.left := 0; end else begin DrawRect.left := TheRect.left; TheDstRow := TheDstRow + TheRect.left; DstAddr := ptr (longint (DstAddr) + TheRect.left); end; if TheRect.right > Environment.CommonRect.right then begin DrawRect.right := Environment.CommonRect.right; end else begin DrawRect.right := TheRect.right; TheDstRow := TheDstRow + Environment.CommonRect.right - TheRect.right; end; if TheRect.bottom > 199 then DrawRect.bottom := 199 else DrawRect.bottom := TheRect.bottom; ThePICTBase := ThePICT; TheMaskBase := TheMask; IcY := 0; J := DrawRect.bottom - DrawRect.top; while J > 0 do begin ThePICT := ThePICTBase; TheMask := TheMaskBase; IcX := 0; J := J - 1; I := DrawRect.right - DrawRect.left; while I > 0 do begin I := I - 1; if bsr (TheMask^, 8) <> 0 then DstAddr^ := ThePICT^; IcX := IcX + Dx; while IcX > $10000 do begin IcX := IcX - $10000; TheMask := integerptr (longint (TheMask) + 1); ThePICT := ptr (longint (ThePICT) + 1); end; DstAddr := ptr (longint (DstAddr) + 1); end; IcY := IcY + Dy; while IcY > $10000 do begin IcY := IcY - $10000; TheMaskBase := integerptr (longint (TheMaskBase) + TheSrcRow); ThePICTBase := ptr (longint (ThePICTBase) + TheSrcRow); end; DstAddr := ptr (longint (DstAddr) + TheDstRow); end;end;{$S Engine3D}procedure PlotMMaskPICT ( TheMaskPtr : ptr; var TheDimension : rect; var TheRect : rect);var I, J : integer; Dx, Dy : fixed; DrawRect : rect; DstAddr : ptr; IcX, IcY : fixed; TheDstRow, TheSrcRow : integer; TheMaskBase : integerptr; TheMask : integerptr; TheColor : byte; begin Dx := fixdiv (TheDimension.right, TheRect.right - TheRect.left + 2); Dy := fixdiv (TheDimension.bottom, TheRect.bottom - TheRect.top + 2); TheMask := integerptr (TheMaskPtr); DstAddr := OffScreenAddr; TheSrcRow := TheDimension.right + 1; TheDstRow := DstRow - Environment.CommonRect.right; if TheRect.top < 0 then begin TheMask := integerptr (longint (TheMask) - TheSrcRow * hiword (TheRect.top * Dy)); DrawRect.top := 0; end else begin DstAddr := ptr (longint (DstAddr) + TheRect.top * DstRow); DrawRect.top := TheRect.top; end; if TheRect.left < 0 then begin TheMask := integerptr (longint (TheMask) - hiword (Dx * TheRect.left)); DrawRect.left := 0; end else begin DrawRect.left := TheRect.left; TheDstRow := TheDstRow + TheRect.left; DstAddr := ptr (longint (DstAddr) + TheRect.left); end; if TheRect.right > Environment.CommonRect.right then begin DrawRect.right := Environment.CommonRect.right; end else begin DrawRect.right := TheRect.right; TheDstRow := TheDstRow + Environment.CommonRect.right - TheRect.right; end; if TheRect.bottom > 199 then DrawRect.bottom := 199 else DrawRect.bottom := TheRect.bottom; TheMaskBase := TheMask; IcY := 0; TheColor := TheKBlack; J := DrawRect.bottom - DrawRect.top; while J > 0 do begin TheMask := TheMaskBase; IcX := 0; J := J - 1; I := DrawRect.right - DrawRect.left; while I > 0 do begin I := I - 1; if bsr (TheMask^, 8) <> 0 then DstAddr^ := TheColor; IcX := IcX + Dx; while IcX > $10000 do begin IcX := IcX - $10000; TheMask := integerptr (longint (TheMask) + 1); end; DstAddr := ptr (longint (DstAddr) + 1); end; IcY := IcY + Dy; while IcY > $10000 do begin IcY := IcY - $10000; TheMaskBase := integerptr (longint (TheMaskBase) + TheSrcRow); end; DstAddr := ptr (longint (DstAddr) + TheDstRow); end;end;{$S Engine3D}procedure PlotHMaskPICT ( ThePICTPtr : ptr; TheMaskPtr : ptr; var TheDimension : rect; var TheRect : rect; StartX, EndX : integer);var I, J : integer; Dx, Dy : fixed; DrawRect : rect; DstAddr : ptr; IcX, IcY : fixed; TheDstRow, TheSrcRow : integer; ThePICT : ptr; ThePICTBase : ptr; TheMaskBase : integerptr; TheMask : integerptr; begin Dx := fixdiv (TheDimension.right, TheRect.right - TheRect.left + 1); Dy := fixdiv (TheDimension.bottom, TheRect.bottom - TheRect.top + 1); ThePICT := ThePICTPtr; TheMask := integerptr (TheMaskPtr); DstAddr := OffScreenAddr; TheSrcRow := TheDimension.right + 1; TheDstRow := DstRow - Environment.CommonRect.right; if TheRect.top < 0 then begin ThePICT := ptr (longint (ThePICT) - TheSrcRow * hiword (TheRect.top * Dy)); TheMask := integerptr (longint (TheMask) - TheSrcRow * hiword (TheRect.top * Dy)); DrawRect.top := 0; end else begin DstAddr := ptr (longint (DstAddr) + TheRect.top * DstRow); DrawRect.top := TheRect.top; end; J := Max (StartX, 0); if TheRect.left < J then begin ThePICT := ptr (longint (ThePICT) + hiword (Dx * (J - TheRect.left))); TheMask := integerptr (longint (TheMask) + hiword (Dx * (J - TheRect.left))); DrawRect.left := J; if StartX > 0 then begin TheDstRow := TheDstRow + StartX; DstAddr := ptr (longint (DstAddr) + StartX); end; end else begin DrawRect.left := TheRect.left; TheDstRow := TheDstRow + TheRect.left; DstAddr := ptr (longint (DstAddr) + TheRect.left); end; J := Min (EndX, Environment.CommonRect.right); if TheRect.right > J then begin DrawRect.right := J; if EndX < Environment.CommonRect.right then TheDstRow := TheDstRow + Environment.CommonRect.right - EndX; end else begin DrawRect.right := TheRect.right; TheDstRow := TheDstRow + Environment.CommonRect.right - TheRect.right end; if TheRect.bottom > 199 then DrawRect.bottom := 199 else DrawRect.bottom := TheRect.bottom; ThePICTBase := ThePICT; TheMaskBase := TheMask; IcY := 0; J := DrawRect.bottom - DrawRect.top; while J > 0 do begin ThePICT := ThePICTBase; TheMask := TheMaskBase; IcX := 0; J := J - 1; I := DrawRect.right - DrawRect.left; while I > 0 do begin I := I - 1; if bsr (TheMask^, 8) <> 0 then DstAddr^ := ThePICT^; IcX := IcX + Dx; while IcX > $10000 do begin IcX := IcX - $10000; TheMask := integerptr (longint (TheMask) + 1); ThePICT := ptr (longint (ThePICT) + 1); end; DstAddr := ptr (longint (DstAddr) + 1); end; IcY := IcY + Dy; while IcY > $10000 do begin IcY := IcY - $10000; TheMaskBase := integerptr (longint (TheMaskBase) + TheSrcRow); ThePICTBase := ptr (longint (ThePICTBase) + TheSrcRow); end; DstAddr := ptr (longint (DstAddr) + TheDstRow); end;end;{$S Engine3D}procedure PlotHMMaskPICT ( ThePICTPtr : integerptr; var TheDimension : rect; var TheRect : rect; StartX, EndX : integer);var I, J : integer; Dx, Dy : fixed; DrawRect : rect; DstAddr : ptr; IcX, IcY : fixed; TheDstRow, TheSrcRow : integer; ThePICT : integerptr; ThePICTBase : integerptr; TheColor : integer; begin Dx := fixdiv (TheDimension.right, TheRect.right - TheRect.left + 1); Dy := fixdiv (TheDimension.bottom, TheRect.bottom - TheRect.top + 1); ThePICT := ThePICTPtr; DstAddr := OffScreenAddr; TheSrcRow := TheDimension.right + 1; TheDstRow := DstRow - Environment.CommonRect.right; if TheRect.top < 0 then begin ThePICT := integerptr (longint (ThePICT) - TheSrcRow * hiword (TheRect.top * Dy)); DrawRect.top := 0; end else begin DstAddr := ptr (longint (DstAddr) + TheRect.top * DstRow); DrawRect.top := TheRect.top; end; J := Max (StartX, 0); if TheRect.left < J then begin ThePICT := integerptr (longint (ThePICT) + hiword (Dx * (J - TheRect.left))); DrawRect.left := J; if StartX > 0 then begin TheDstRow := TheDstRow + StartX; DstAddr := ptr (longint (DstAddr) + StartX); end; end else begin DrawRect.left := TheRect.left; TheDstRow := TheDstRow + TheRect.left; DstAddr := ptr (longint (DstAddr) + TheRect.left); end; J := Min (EndX, Environment.CommonRect.right); if TheRect.right > J then begin DrawRect.right := J; if EndX < Environment.CommonRect.right then TheDstRow := TheDstRow + Environment.CommonRect.right - EndX; end else begin DrawRect.right := TheRect.right; TheDstRow := TheDstRow + Environment.CommonRect.right - TheRect.right end; if TheRect.bottom > 199 then DrawRect.bottom := 199 else DrawRect.bottom := TheRect.bottom; ThePICTBase := ThePICT; IcY := 0; TheColor := TheKBlack; J := DrawRect.bottom - DrawRect.top; while J > 0 do begin ThePICT := ThePICTBase; IcX := 0; J := J - 1; I := DrawRect.right - DrawRect.left; while I > 0 do begin I := I - 1; if bsr (ThePICT^, 8) <> 0 then DstAddr^ := TheColor; IcX := IcX + Dx; while IcX > $10000 do begin IcX := IcX - $10000; ThePICT := integerptr (longint (ThePICT) + 1); end; DstAddr := ptr (longint (DstAddr) + 1); end; IcY := IcY + Dy; while IcY > $10000 do begin IcY := IcY - $10000; ThePICTBase := integerptr (longint (ThePICTBase) + TheSrcRow); end; DstAddr := ptr (longint (DstAddr) + TheDstRow); end;end;{$S Engine3D}procedure FastPlotHCicon ( TheCIconPtr : ptr; var TheRect : rect);var I, J : integer; DrawRect : rect; DstAddr : ptr; TheDstRow, TheSrcRow : integer; TmpInt : byte; ThePICT : ptr; ThePICTBase : ptr; begin ThePICT := TheCIconPtr; DstAddr := OffScreenAddr; TheSrcRow := 64; TheDstRow := DstRow - Environment.CommonRect.right; DstAddr := ptr (longint (DstAddr) + TheRect.top * DstRow); DrawRect.top := TheRect.top; DrawRect.left := TheRect.left; TheDstRow := TheDstRow + TheRect.left; DstAddr := ptr (longint (DstAddr) + TheRect.left); DrawRect.right := TheRect.right; TheDstRow := TheDstRow + Environment.CommonRect.right - TheRect.right; if TheRect.bottom > 199 then DrawRect.bottom := 199 else DrawRect.bottom := TheRect.bottom; ThePICTBase := ThePICT; J := DrawRect.bottom - DrawRect.top; while J > 0 do begin ThePICT := ThePICTBase; J := J - 1; I := DrawRect.right - DrawRect.left; while I > 0 do begin I := I - 1; TmpInt := ThePICT^; if TmpInt <> 0 then DstAddr^ := TmpInt; ThePICT := ptr (longint (ThePICT) + 1); DstAddr := ptr (longint (DstAddr) + 1); end; ThePICTBase := ptr (longint (ThePICTBase) + TheSrcRow); DstAddr := ptr (longint (DstAddr) + TheDstRow); end;end;{$S Engine3D}procedure PlotGhostPICT ( ThePICTPtr : ptr; TheMaskPtr : ptr; var TheDimension : rect; var TheRect : rect; StartX, EndX : integer);var I, J : integer; Dx, Dy : fixed; DrawRect : rect; DstAddr : ptr; IcX, IcY : fixed; TheDstRow, TheSrcRow : integer; ThePICT : BytePtr; ThePICTBase : BytePtr; TheMaskBase : integerptr; TheMask : integerptr; LocalPalette : BytePtr; begin Dx := fixdiv (TheDimension.right, TheRect.right - TheRect.left + 1); Dy := fixdiv (TheDimension.bottom, TheRect.bottom - TheRect.top + 1); ThePICT := BytePtr (ThePICTPtr); TheMask := integerptr (TheMaskPtr); DstAddr := ptr (OffScreenAddr); TheSrcRow := TheDimension.right + 1; TheDstRow := DstRow - Environment.CommonRect.right; if TheRect.top < 0 then begin ThePICT := BytePtr (longint (ThePICT) - TheSrcRow * hiword (TheRect.top * Dy)); TheMask := integerptr (longint (TheMask) - TheSrcRow * hiword (TheRect.top * Dy)); DrawRect.top := 0; end else begin DstAddr := ptr (longint (DstAddr) + TheRect.top * DstRow); DrawRect.top := TheRect.top; end; J := Max (StartX, 0); if TheRect.left < J then begin ThePICT := BytePtr (longint (ThePICT) + hiword (Dx * (J - TheRect.left))); TheMask := integerptr (longint (TheMask) + hiword (Dx * (J - TheRect.left))); DrawRect.left := J; if StartX > 0 then begin TheDstRow := TheDstRow + StartX; DstAddr := ptr (longint (DstAddr) + StartX); end; end else begin DrawRect.left := TheRect.left; TheDstRow := TheDstRow + TheRect.left; DstAddr := ptr (longint (DstAddr) + TheRect.left); end; J := Min (EndX, Environment.CommonRect.right); if TheRect.right > J then begin DrawRect.right := J; if EndX < Environment.CommonRect.right then TheDstRow := TheDstRow + Environment.CommonRect.right - EndX; end else begin DrawRect.right := TheRect.right; TheDstRow := TheDstRow + Environment.CommonRect.right - TheRect.right end; if TheRect.bottom > 199 then DrawRect.bottom := 199 else DrawRect.bottom := TheRect.bottom; ThePICTBase := ThePICT; TheMaskBase := TheMask; IcY := 0; LocalPalette := BytePtr (MixedPalette); if localPalette = nil then exit (PlotGhostPICT); J := DrawRect.bottom - DrawRect.top; while J > 0 do begin ThePICT := ThePICTBase; TheMask := TheMaskBase; IcX := 0; J := J - 1; I := DrawRect.right - DrawRect.left; while I > 0 do begin I := I - 1; if bsr (TheMask^, 8) <> 0 then DstAddr^ := ptr (longint (LocalPalette) + bor (bsr (ThePICT^, 8), bsl (band (DstAddr^, $FF), 8)))^; IcX := IcX + Dx; while IcX > $10000 do begin IcX := IcX - $10000; TheMask := integerptr (longint (TheMask) + 1); ThePICT := BytePtr (longint (ThePICT) + 1); end; DstAddr := ptr (longint (DstAddr) + 1); end; IcY := IcY + Dy; while IcY > $10000 do begin IcY := IcY - $10000; TheMaskBase := integerptr (longint (TheMaskBase) + TheSrcRow); ThePICTBase := BytePtr (longint (ThePICTBase) + TheSrcRow); end; DstAddr := ptr (longint (DstAddr) + TheDstRow); end;end;end.