Graphics
Unit Grafix;
{$G+}
Interface
Type
PFont = Pointer; { ’¨¯ - 㪠§ â¥«ì ¬ âà¨çë© èà¨äâ }
TPal = Array [0..255, 1..3] of Byte; { ’¨¯ - ¯ «¨âà , åà ¨â ª®¬¯®¥âë 256-⨠}
{ 梥⮢: ªà áãî, §¥«¥ãî ¨ á¨îî }
THeader = Record { ‘âàãªâãà § £®«®¢ª VOB-ä ©« }
ID : Array [1..12] of Char; { ˆ¤¥â¨ä¨ª â®à }
V, SV : Byte; { ‚¥àá¨ï ¨ ¯®¤¢¥àá¨ï }
L, H : Word; { ˜¨à¨ ¨ ¢ëá®â }
Mask : Boolean; { ਧ ª «¨ç¨ï ¬ ᪨ }
Pack : Byte; { ਧ ª 㯠ª®¢ª¨ }
PSize, { §¬¥à ¤ ëå à¨á㪠}
MSize : Word; { §¬¥à ¤ ëå ¬ ᪨ à¨á㪠}
Res : Array [1..8] of Byte { ¥§¥à¢ }
End;
TPoint = Record { ’¨¯ - â®çª . 㦥 ¤«ï à¨á®¢ ¨ï }
X, Y : Integer { «®¬ ëå «¨¨© ¨ ¬®£®ã£®«ì¨ª®¢ }
End;
TPCXHeader = Record { ‘âàãªâãà § £®«®¢ª PCX-ä ©« }
Manufact,
Ver,
Encoding,
BitsPerPixel : Byte;
X1, Y1, X2, Y2,
Hdpi, Vdpi : Word;
ColorMap : Array [0..47] of Byte;
Res,
Planes : Byte;
BytesPerLine,
PalInfo,
HScrSize,
VScrSize : Word;
Filler : Array [0..53] of Byte;
End;
Const
VSeg = $A000; { ‘¥£¬¥â ¢¨¤¥® ¡ãä¥à }
MaxX = 319;
MaxY = 199;
MaxColor = 255;
GetMaxX = MaxX;
GetMaxY = MaxY;
GetMaxColor = MaxColor;
GrOk = 0; { ¥â ®è¨¡ª¨ }
GrInit = -1; { Žè¨¡ª ¯à¨ ¨¨æ¨ «¨§ 樨 £à 䨪¨ }
GrLoadFont = -2; { Žè¨¡ª ¯à¨ § £à㧪¥ èà¨äâ }
GrLoadObj = -3; { Žè¨¡ª ¯à¨ § £à㧪¥ ª à⨪¨ }
GrSaveObj = -4; { Žè¨¡ª ¯à¨ § ¯¨á¨ ª à⨪¨ }
Seq_Addr = $3C4;
CRTC_Addr = $3D4;
Misc_Output_Addr = $3C2;
Graph_Cntrl_Addr = $3CE;
Var
VSegA : Word; { ‘¥£¬¥â ªâ¨¢®© ¢¨¤¥® áâà ¨æë }
GrResult : Integer; { Žè¨¡ª ®¯¥à 樨 }
CurFont : PFont; { “ª § ⥫ì ⥪ã騩 èà¨äâ }
FontSize : Word; { Ž¡ê¥¬ ⥪ã饣® èà¨äâ }
FontX, FontY : Byte; { ƒ®à¨§. ¨ ¢¥àâ. à §¬¥àë èà¨äâ }
TranspColor : Byte; { –¢¥â ¯à®§à ç®á⨠á¯à ©â }
_Poly : Array [0..319,1..2] of Integer; { ®¤ à¨á®¢ ¨¥ ¬®£®ã£-ª®¢ }
{ ¨ ᤢ¨£¨ }
_LeftTable,
_RightTable : Array [0..199,0..2] of Integer; { ®¤ ⥪áâãàãî § «¨¢ªã }
Function IsVGA : Boolean;
{ ‚®§¢à é ¥â TRUE, ¥á«¨ ¢ á¨á⥬¥ ãáâ ®¢«¥ VGA-ª àâ }
Procedure InitGraph;
{ ˆ¨æ¨ «¨§¨àã¥â £à 䨪ã; á®áâ®ï¨¥ ¢ ¯¥à¥¬¥®© GrResult }
Procedure CloseGraph;
{ ‡ ªàë¢ ¥â £à 䨪ã (ãáâ ¢«¨¢ ¥â 梥¨®© ⥪áâ®¢ë© à¥¦¨¬ 80x25) }
Procedure ClearScreen (C : Byte);
{ Žç¨é ¥â íªà 梥⮬ C; ªâ¨¢®© áâà ¨æ¥ }
Procedure Border (C : Byte);
{ “áâ ¢«¨¢ ¥â 梥â C à ¬ª¨ íªà }
Procedure PutPixel (X, Y : Word; C : Byte);
{ ¨áã¥â â®çªã ¢ ¯®§¨æ¨¨ (X,Y) 梥⮬ C; ªâ¨¢®© áâà ¨æ¥ }
Function GetPixel (X, Y : Word) : Byte;
{ ‚®§¢à é¥â 梥â â®çª¨ ¢ ¯®§¨æ¨¨ (X,Y); /á }
Procedure LineH (X, Y, L : Word; C : Byte);
{ ¨áã¥â £®à¨§®â «ìãî «¨¨î ®â â®çª¨ (X,Y) ¤«¨ë L 梥⮬ C; a/c }
Procedure LineV (X, Y, H : Word; C : Byte);
{ ¨áã¥â ¢¥à⨪ «ìãî «¨¨î ®â â®çª¨ (X,Y) ¢ëá®âë H 梥⮬ C; a/c }
Procedure Line (X1, Y1, X2, Y2 : Word; C : Byte);
{ ¨áã¥â «¨¨î, ᮥ¤¨ïîéãî â®çª¨ (X1,Y1) ¨ (X2,Y2), 梥⮬ C; a/c }
Procedure Box (X, Y, L, H : Word; C : Byte; Fill : Boolean);
{ ¨áã¥â ¯àאַ㣮«ì¨ª ®â â®çª¨ (X,Y) ¤«¨ë L ¨ ¢ëá®âë H 梥⮬ C,
¥á«¨ Fill = True, â® ¯àאַ㣮«ì¨ª § ªà 訢 ¥âáï ⥬ ¦¥ 梥⮬; /á }
Procedure Circle (X, Y, R : Word; C : Byte; Fill : Boolean);
{ ¨áã¥â ®ªà㦮áâì æ¢¥â C á æ¥â஬ ¢ â®çª¥ (X,Y) à ¤¨ãá R;
¥á«¨ Fill = True, â® ®ªà㦮áâì § ªà 訢 ¥âáï ⥬ ¦¥ 梥⮬; /á }
Procedure Fill (X, Y : Word; C : Byte);
{ ¥à¥ªà 訢 ¥â ®¤®æ¢¥âãî ®¡« áâì, ¢ ª®â®àãî ¯®¯ « â®çª (X,Y),
¢ ®¢ë© 梥â - C; âॡã¥â 120 âëá. ¡ ©â á ª®¯¥©ª ¬¨ ᢮¡®¤®©
¯ ¬ï⨠¢ ªãç¥; â® ¦ã⪮ â®à¬®§ïé ï ¯à®æ¥¤ãà ; /á }
Procedure DrawPoly (Num : Word; PolyPoints : Array of TPoint; C : Byte);
{ ¨áã¥â «®¬ ãî æ¢¥â C ¯® ¥¥ Num ¢¥àè¨ ¬ ¢ PolyPoints; /á }
Procedure DrawPoly2 (Num : Word; PolyPoints : Array of TPoint; C : Byte);
{ ¨áã¥â § ¬ªãâãî «®¬ ãî æ¢¥â C ¯® ¥¥ Num ¢¥àè¨ ¬ ¢
PolyPoints; /á }
Procedure FillPoly (Num : Word; PolyPoints : Array of TPoint; C : Byte);
{ ¨áã¥â ᯫ®è®© ¬®£®ã£®«ì¨ª 梥â C ¯® ¥£® Num ¢¥àè¨ ¬ ¢
PolyPoints; /á }
Procedure FillPolyPat (Num : Word; PolyPoints : Array of TPoint;
L, H : Word; Var Pat);
{ ‡ ¯®«ï¥â ¬®£®ã£®«ì¨ª á Num ¢¥àè¨ ¬¨ ¢ PolyPoints ®¤¨ ª®¢ë¬¨
¯àאַ㣮«ì¨ª ¬¨ (à §¬¥à LxH â®ç¥ª), ¨§®¡à ¦¥¨¥ ª®â®àëå åà ¨âáï
¢ L*H-¡ ©â®¬ ¬ áᨢ¥ Pat; /á }
Procedure LoadFont (Name : String; Var PF : PFont; Var Size : Word);
{ ‡ £à㦠¥â ¬ âà¨çë© èà¨äâ á ¤¨áª®¢ë¬ ¨¬¥¥¬ Name, १¥à¢¨àãï ¯ ¬ïâì
¤«ï PF, ¢ Size ¢®§¢à é ¥âáï ®¡ê¥¬ § १¥à¢¨à®¢ ®© ¯ ¬ïâ¨;
á®áâ®ï¨¥ ¢ ¯¥à¥¬¥®© GrResult }
Procedure SetFont (PF : PFont);
{ “áâ ¢«¨¢ ¥â ⥪ã騩 èà¨äâ, ¯® 㪠§ â¥«î ¥£® PF }
Procedure WriteC (X, Y : Word; B, T : Byte; C : Char);
{ Žâ®¡à ¦ ¥â ᨬ¢®« C ¢ ¯®§¨æ¨¨ (X,Y), 梥⮬ T 䮥 B;
¥á«¨ B = T, â® ä® ¥ ¨§¬¥ï¥âáï; /á }
Procedure WriteS (X, Y : Word; B, T : Byte; S : String);
{ € «®£¨ç® ¯à®æ¥¤ãॠWriteC ®â®¡à ¦ ¥â áâபã S; /á }
Procedure ReadS (X, Y : Word; B, T : Byte; Var S : String; N : Byte);
{ ‘ç¨âë¢ ¥â (¨§¬¥ï¥â) á ª« ¢¨ âãàë áâபã S ¬ ªá¨¬ «ì®© ¤«¨ë N,
®¤®¢à¥¬¥® ¯à®¨§¢®¤¨âáï ¥¥ ®â®¡à ¦¥¨¥ íªà ¥, ãá«®¢¨ï
®â®¡à ¦¥¨ï â ª¨¥ ¦¥ ª ª ¨ ¢ ¯à®æ¥¤ãॠWriteC; ¯à¨¬¥ç.: ¯® ª« ¢¨è¥
ESC ¢¢®¤ § ª 稢 ¥âáï á ¢®§¢à 饨¥¬ ¯ãá⮩ áâப¨; /á }
Function ImageSize (L, H : Word) : Word;
{ ‚®§¢à é ¥â ®¡ê¥¬ âॡ㥬®© ¯ ¬ï⨠¤«ï á®åà ¥¨ï ¢ ¥©
¯àאַ㣮«ì®£® ãç á⪠¨§®¡à ¦¥¨ï à §¬¥à®¬ L x H }
Procedure GetImage (X, Y, L, H : Word; Var BitMap);
{ ‘®åà ï¥â ¢ ¯¥à¥¬¥®© BitMap ¯àאַ㣮«ìë© ãç á⮪ ¨§®¡à ¦¥¨ï
¨§ ¯®§¨æ¨¨ (X,Y) à §¬¥à®¬ L x H; /á }
Procedure GetClippedImage (X, Y : Integer; L, H : Word; Var BitMap);
{ „¥« ¥â â® ¦¥, çâ® ¨ GetImage, á ⮩ «¨èì à §¨æ¥©, çâ® ª à⨪ ¥
®¡ï§ â¥«ì® ¤®«¦ ¯®«®áâìî 㬥é âìáï íªà ¥, çâ® ¡ë«® ¥®¡å®¤¨¬®
¤«ï ¯à ¢¨«ì®© à ¡®âë GetImage }
Procedure PutImage (X, Y : Word; Var BitMap);
{ ‚®ááâ ¢«¨¢ ¥â ¨§ ¯¥à¥¬¥®© BitMap ¯àאַ㣮«ìë© ãç á⮪
¨§®¡à ¦¥¨ï ¢ ¯®§¨æ¨î (X,Y); /á }
Procedure PutTranspImage (X, Y : Word; Var BitMap);
{ ‚®ááâ ¢«¨¢ ¥â ¨§ ¯¥à¥¬¥®© BitMap "¯à®§à çë©" ¯àאַ㣮«ìë©
ãç á⮪ ¨§®¡à ¦¥¨ï ¢ ¯®§¨æ¨î (X,Y); 梥⠯஧à ç®á⨠åà ¨âáï
¢ TranspColor; /á }
Procedure PutImagePart (X, Y : Word; Var BitMap; PX, PY, PL, PH : Word);
{ Žâ®¡à ¦ ¥â ¯àאַ㣮«ìãî ç áâì ®â ª à⨪¨ BitMap ¢ ¯®§¨æ¨î (X,Y)
íªà ¥; (PX,PY) - «¥¢ë© ¢¥à娩 㣮« ¯àאַ㣮«ì¨ª ¢ ª à⨪¥, PL ¨
PH § ¤ îâ à §¬¥à ¯àאַ㣮«ì¨ª ; /á }
Procedure PutTranspImagePart (X, Y : Word; Var BitMap; PX, PY, PL, PH : Word);
{ Žâ®¡à ¦ ¥â ¯àאַ㣮«ìãî ç áâì ®â "¯à®§à 箩" ª à⨪¨ BitMap ¢
¯®§¨æ¨î (X,Y) íªà ¥; (PX,PY) - «¥¢ë© ¢¥à娩 㣮« ¯àאַ㣮«ì¨ª
¢ ª à⨪¥, PL ¨ PH § ¤ îâ à §¬¥à ¯àאַ㣮«ì¨ª ; /á }
Procedure PutClippedImage (X, Y : Integer; Var BitMap);
{ „¥« ¥â â® ¦¥, çâ® ¨ PutImage, á ⮩ «¨èì à §¨æ¥©, çâ® ª à⨪ ¥
®¡ï§ â¥«ì® ¤®«¦ ¯®«®áâìî 㬥é âìáï íªà ¥, çâ® ¡ë«® ¥®¡å®¤¨¬®
¤«ï ¯à ¢¨«ì®© à ¡®âë PutImage }
Procedure PutTranspClippedImage (X, Y : Integer; Var BitMap);
{ „¥« ¥â â® ¦¥, çâ® ¨ PutImage, á ⮩ «¨èì à §¨æ¥©, çâ® "¯à®§à ç ï"
ª à⨪ ¥ ®¡ï§ â¥«ì® ¤®«¦ ¯®«®áâìî 㬥é âìáï íªà ¥,
çâ® ¡ë«® ¥®¡å®¤¨¬® ¤«ï ¯à ¢¨«ì®© à ¡®âë PutImage }
Procedure PutClippedImagePart (X, Y : Integer; Var BitMap; PX, PY, PL, PH : Word);
{ „¥« ¥â â® ¦¥, çâ® ¨ PutImagePart, á ⮩ «¨èì à §¨æ¥©, çâ®
ª à⨪ ¥ ®¡ï§ â¥«ì® ¤®«¦ ¯®«®áâìî 㬥é âìáï íªà ¥,
çâ® ¡ë«® ¥®¡å®¤¨¬® ¤«ï ¯à ¢¨«ì®© à ¡®âë PutImagePart }
Procedure PutTranspClippedImagePart (X, Y : Integer; Var BitMap; PX, PY, PL, PH : Word);
{ „¥« ¥â â® ¦¥, çâ® ¨ PutTranspImagePart, á ⮩ «¨èì à §¨æ¥©, çâ®
"¯à®§à ç ï" ª à⨪ ¥ ®¡ï§ â¥«ì® ¤®«¦ ¯®«®áâìî 㬥é âìáï
íªà ¥, çâ® ¡ë«® ¥®¡å®¤¨¬® ¤«ï ¯à ¢¨«ì®© à ¡®âë PutTranspImagePart }
Procedure LoadObject (Name : String; Var PBitMap : Pointer; Var Size : Word);
{ ‡ £à㦠¥â ¯àאַ㣮«ìãî ª à⨪ã á ¤¨áª®¢ë¬ ¨¬¥¥¬ Name,
१¥à¢¨àãï ¯ ¬ïâì ¤«ï PBitMap, ¢ Size ¢®§¢à é ¥âáï ®¡ê¥¬
§ १¥à¢¨à®¢ ®© ¯ ¬ïâ¨; ¢®§¬®¦® ¯®á«¥¤ãî饥 ®â®¡à ¦¥¨¥
á ¯®¬®éìî ¢á直å PutImage'© }
Procedure LoadPCX256 (Name : String; Var PBitMap : Pointer; Var Size : Word;
Var Pal : TPal);
{ ‡ £à㦠¥â ¯àאַ㣮«ìãî 256 梥âãî PCX-ª à⨪ã á ¤¨áª®¢ë¬ ¨¬¥¥¬
Name, १¥à¢¨àãï ¯ ¬ïâì ¤«ï PBitMap, ¢ Size ¢®§¢à é ¥âáï ®¡ê¥¬
§ १¥à¢¨à®¢ ®© ¯ ¬ïâ¨; ¢®§¬®¦® ¯®á«¥¤ãî饥 ®â®¡à ¦¥¨¥
á ¯®¬®éìî ¢á¥å PutImage'©, ªà®¬¥ PutImageM }
Procedure SavePCX256 (Name : String; X, Y, L, H : Word);
{ ‡ ¯¨áë¢ ¥â ¢ ä ©« á ¨¬¥¥¬ Name ¯àאַ㣮«ìë© ãç á⮪ ¨§®¡à ¦¥¨ï
á ªâ¨¢®© áâà ¨æë ¢ ä®à¬ ⥠PCX; (X,Y) ¨ LxH - ª®®à¤¨ âë ¨
à §¬¥àë ãç á⪠¨§®¡à ¦¥¨ï áâà ¨æ¥ }
Procedure PutImageM (X, Y : Word; Var BitMap);
{ ‚®ááâ ¢«¨¢ ¥â ¨§ ¯¥à¥¬¥®© BitMap ¯àאַ㣮«ìë© ãç á⮪
¨§®¡à ¦¥¨ï, ¨¬¥î饣® ¬ áªã, ¢ ¯®§¨æ¨î (X,Y); ¢ ç «¥ íªà
ª« ¤ë¢ ¥âáï ¯® AND ¬ ᪠, § ⥬ ª« ¤ë¢ ¥âáï ¯® XOR á ¬
ª à⨪ , - íâ® ¤«ï ⮣®, çâ®¡ë ¨§®¡à ¦¥¨¥ íªà ¥ ¥
¢ë£«ï¤¥«® 祬-⮠䮥 ¥¯®ï⮩ ¯àאַ㣮«ì®© ⥨
(¨ë¬¨ á«®¢ ¬¨, çâ®¡ë ¥ § â¨à «áï ¯®«®áâìî ä® ª à⨪¨); /á }
Procedure SetActivePage (PageSeg : Word);
{ ¥à¥ª«îç ¥â ªâ¨¢ãî áâà ¨æã, ªã¤ ¡ã¤¥â ¢ë¢®¤¨âáï £à ä¨ç¥áª ï
¨ä®à¬ æ¨ï, â®ç¥¥ ¯¥à¥ª«îç ¥â ᥣ¬¥â ¯ ¬ï⨠í⮩ áâà ¨æë,
¯à¨¬¥ç.: ¯®¤ áâà ¨æã ¤®«¦ ¡ëâì § १¥à¢¨à®¢ ¯ ¬ïâì ®¡ê¥¬®¬
64000 ¡ ©â, çâ®¡ë ¯¥à¥ª«îç¨âìáï ®â®¡à ¦ ¥¬ãî áâà ¨æã,
¤®áâ â®ç® 㪠§ âì PageSeg à ¢ë¬ VSeg ($A000) }
Procedure DisplayPage (PageSeg : Word);
{ Žâ®¡à ¦ ¥â ªâ¨¢ãî áâà ¨æã ¯® ¥¥ ᥣ¬¥âã PageSeg íªà }
Procedure DisplayBox (PageSeg, X, Y, L, H : Word);
{ Žâ®¡à ¦ ¥â ¯àאַ㣮«ìë© ãç á⮪ ªâ¨¢®© áâà ¨æë ¯® ¥¥
ᥣ¬¥âã ¯ ¬ï⨠¨ ¯ à ¬¥âà ¬ ãç á⪠: (X,Y) ¨ LxH }
Procedure WaitRetrace;
{ „®¦¨¤ ¥âáï ¬®¬¥â ¢®§¢à â «ãç ¨§ ¯à ¢®£® ¨¦¥£® 㣫 í«¥ªâà®®- }
{ «ã祢®© âà㡪¨ ¢ «¥¢ë© ¢¥à娩. ƒà ä¨ç¥áª¨¥ ¬ ¨¯ã«ï樨 ¢ íâ®â ¬®¬¥â}
{ ¥ ¡ã¤ãâ ¢ë§ë¢ ⨠¬¥«ìª ¨ï íªà ¥. ‚ íâ®â ¬®¬¥â 㤮¡® ¬¥ïâì }
{ ¯ «¨âàã; ¢®ááâ ¢«¨¢ âì ä®®¢®¥ ¨§®¡à ¦¥¨¥ ¯®¤ á¯à ©â®¬ ¨ }
{ à¨á®¢ âì ¤à㣮© á¯à ©â ¢ í⮩ ¯®§¨æ¨¨ ¨«¨ â®â çâ® ¡ë«, ® ¢ }
{ ¤à㣮© ¯®§¨æ¨¨. }
Procedure GetCRGB (C : Byte; Var R, G, B : Byte);
{ ‚®§¢à é ¥â ᮤ¥à¦ ¨¥ ªà ᮩ, §¥«¥®© ¨ ᨥ© ª®¬¯®¥â ¤«ï
梥â C ¢ ⥪ã饩 ¯ «¨âॠ}
Procedure SetCRGB (C : Byte; R, G, B : Byte);
{ “áâ ¢«¨¢ ¥â ᮤ¥à¦ ¨¥ ªà ᮩ, §¥«¥®© ¨ ᨥ© ª®¬¯®¥â ¤«ï
梥â C ¢ ⥪ã饩 ¯ «¨âॠ}
Procedure GetPal (Var Pal);
{ ‚®§¢à é ¥â ¢ Pal ⥪ãéãî ¯ «¨âàã }
Procedure SetPal (Var Pal);
{ “áâ ¢«¨¢ ¥â ¯ «¨âàã Pal ⥪ã饩 }
Procedure FadeUp (Pal : TPal);
{ « ¢® "¯à®ï¢«ï¥â" ⥪ãéãî ¯ «¨âàã ¤® ¯ «¨âàë Pal }
Procedure FadeDown;
{ « ¢® "£ á¨â" ⥪ãéãî ¯ «¨âàã }
Procedure BlackOutPut;
{ Ž¡ã«ï¥â ⥪ãéãî ¯ «¨âàã, ¤¥« ï ¥¥ ç¥à®© }
Procedure TextureMapPoly (X1,Y1, X2,Y2, X3,Y3, X4,Y4, L, H : Integer;
PicSeg : Word);
{ ‡ «¨¢ ¥â ç¥âëà¥ã£®«ì¨ª á § ¤ 묨 ª®®à¤¨ â ¬¨ ⥪áâãன;
PicSeg - ᥣ¬¥â ¤à¥á ⥪áâãàë, à §¬¥é¥®© ¢ ªãç¥ (¯à¨
¯®¬®é¨ GetMem ¨«¨ New), LxH - à §¬¥à ⥪áâãàë; ¯à¨¬¥ç ¨¥:
¯¥à¢ ï ª®®à¤¨ â ᮮ⢥âáâ¢ã¥â «¥¢®¬ã ¢¥à奬ã 㣫ã ⥪áâãàë,
ª®®à¤¨ âë à ᯮ« £ îâáï ¯® ç ᮢ®© áâ५ª¥ }
Procedure TextureMapPoly2 (X1,Y1, X2,Y2, X3,Y3, X4,Y4, L, H : Integer;
N : Byte; PicSeg : Word);
{ ‚믮«ï¥â â® ¦¥, çâ® ¨ ¯à®æ¥¤ãà TextureMapPoly, ® á ⮩ } { N: ÚÄÂÄ¿ }
{ à §¨æ¥©, çâ® ¢ L ¨ H 㪠§ë¢ îâáï à §¬¥àë ç¥â¢¥à⨠⥪áâãàë } { ³0³1³ }
{ (¯®«®¢¨ë è¨à¨ë ¨ ¢ëá®âë ⥪áâãàë), ¢ N - ®¬¥à ç¥â¢¥à⨠} { ÃÄÅÄ´ }
{ ⥪áâãàë. 㦮 íâ® ¤«ï ¨§®¡à ¦¥¨ï ¡«¨§ª¨å ª £« §ã âà¥å- } { ³2³3³ }
{ ¬¥àëå ®¡ê¥ªâ®¢, ª®â®àë¥ ¢ë£«ï¤ïâ ¯à®á⮠㦠ᮠ¯à¨ ¨á¯®«ì- } { ÀÄÁÄÙ }
{ §®¢ ¨¨ TextureMapPoly. }
Procedure DisplayOff;
{ "‚몫îç ¥â" ¤¨á¯«¥© - ® áâ ®¢¨âáï ç¥àë¬ (£à ä¨ç¥áª¨© ०¨¬) }
Procedure DisplayOn;
{ "‚ª«îç ¥â" ¤¨á¯«¥© - ¨§®¡à ¦¥¨¥ ¯®ï¢«ï¥âáï ¢®¢ì (£à ä¨ç¥áª¨© ०¨¬) }
Implementation
Uses
CRT, Packer;
Function IsVGA : Boolean; Assembler;
Asm
Mov AX, 1A00h
Int 10h
Cmp AL, 1Ah
JNE @@NotVGA
Cmp BL, 7
JE @@VGA
Cmp BL, 8
JE @@VGA
@@NotVGA:
Mov AL, 0
Jmp @@Quit
@@VGA:
Mov AL, 1
@@Quit:
End;
Procedure InitGraph; Assembler;
Asm
Mov AX, 013H
Int 010H
Mov AH, 00FH
Int 010H
Cmp AL, 013H
JNE @1
Mov GrResult, GrOk
Jmp @2
@1:
Mov GrResult, GrInit
@2:
End;
Procedure CloseGraph; Assembler;
Asm
Mov AX, 003H
Int 010H
End;
Procedure ClearScreen (C : Byte); Assembler;
Asm
Mov AX, VSegA
Mov ES, AX
Xor DI, DI
CLD
Mov AL, C
Mov AH, AL
Mov CX, 32000
Rep STOSW
End;
Procedure Border (C : Byte); Assembler;
Asm
Mov AX, 01001H
Mov BH, C
Int 010H
End;
Procedure PutPixel (X, Y : Word; C : Byte); Assembler;
Asm
Mov AX, VSegA
Mov ES, AX
Mov DI, X
Mov BX, Y
ShL BX, 6
Add DI, BX
ShL BX, 2
Add DI, BX
Mov AL, C
STOSB
End;
Function GetPixel (X, Y : Word) : Byte; Assembler;
Asm
Mov AX, VSegA
Mov ES, AX
Mov DI, X
Mov BX, Y
ShL BX, 6
Add DI, BX
ShL BX, 2
Add DI, BX
Mov AL, ES:[DI]
End;
Procedure LineH (X, Y, L : Word; C : Byte); Assembler;
Asm
Mov AX, VSegA
Mov ES, AX
Mov DI, X
Mov BX, Y
ShL BX, 6
Add DI, BX
ShL BX, 2
Add DI, BX
Mov AL, C
Mov CX, L
CLD
Rep STOSB
End;
Procedure LineV (X, Y, H : Word; C : Byte); Assembler;
Asm
Mov AX, VSegA
Mov ES, AX
Mov DI, X
Mov BX, Y
ShL BX, 6
Add DI, BX
ShL BX, 2
Add DI, BX
Mov AL, C
Mov CX, H
CLD
@1:
STOSB
Add DI, 319
Loop @1
End;
Function Sgn (I : Integer) : Integer; Assembler;
Asm
Mov AX, I
Or AX, AX
JZ @end
ShL AX, 1
JC @1
Mov AX, 1
Jmp @end
@1:
Mov AX, -1
@end:
End;
Function _Abs (I : Integer) : Integer; Assembler;
Asm
Mov AX, I
Test AX, 8000h
JZ @end
Neg AX
@end:
End;
Procedure Line (X1, Y1, X2, Y2 : Word; C : Byte);
Var
SX, SY, M, N,
DX1, DY1, DX2, DY2 : Integer;
Begin
SX := X2-X1;
SY := Y2-Y1;
DX1 := Sgn (SX);
DY1 := Sgn (SY);
M := _Abs (SX);
N := _Abs (SY);
DX2 := DX1;
DY2 := 0;
If M < N then
Begin
M := _Abs (SY);
N := _Abs (SX);
DX2 := 0;
DY2 := DY1
End;
Asm
Mov AX, VSegA
Mov ES, AX
Mov DI, X1
Mov BX, Y1
ShL BX, 6
Add DI, BX
ShL BX, 2
Add DI, BX { ES:DI = ^ ¯¥à¢ãî â®çªã }
Mov AX, DY1
Test AX, 8000h
JZ @lb0
Neg AX
ShL AX, 6
Mov BX, AX
ShL AX, 2
Add BX, AX
Neg BX
Jmp @lb1
@lb0:
ShL AX, 6
Mov BX, AX
ShL AX, 2
Add BX, AX
@lb1:
Add BX, DX1
Mov AX, DY2
Test AX, 8000h
JZ @lb2
Neg AX
ShL AX, 6
Mov DX, AX
ShL AX, 2
Add DX, AX
Neg DX
Jmp @lb3
@lb2:
ShL AX, 6
Mov DX, AX
ShL AX, 2
Add DX, AX
@lb3:
Add DX, DX2
Mov AL, C
Xor SI, SI
Mov CX, M
Inc CX
@cycle:
Mov ES:[DI], AL
Add SI, N
Cmp SI, M
JC @cl1
Sub SI, M
Add DI, BX { + ‘¬¥é¥¨¥ á«¥¤. í«¥¬¥â }
Loop @cycle
Jmp @end
@cl1:
Add DI, DX { + ‘¬¥é¥¨¥ á«¥¤. â®çª¨ }
Loop @cycle
@end:
End
End;
Procedure Box (X, Y, L, H : Word; C : Byte; Fill : Boolean);
Begin
If L or H = 0 then Exit;
If not Fill then
Begin
LineH (X, Y, L, C);
LineH (X, Y+H-1, L, C);
LineV (X, Y, H, C);
LineV (X+L-1, Y, H, C)
End
Else
Asm
Mov AX, VSegA
Mov ES, AX
Mov DI, X
Mov BX, Y
ShL BX, 6
Add DI, BX
ShL BX, 2
Add DI, BX
CLD
Mov BX, L
Mov DX, H
Mov AL, C
@1:
Push DI
Mov CX, BX
Rep STOSB
Pop DI
Add DI, 320
Dec DX
JNZ @1
End
End;
Function SqrWN (X : Word) : Byte; Assembler; { Yi+1 = (Yi + X/Yi) / 2 }
{ ‚®§¢à é ¥â ª®à¥ì, ª¢ ¤à â ª®â®à®£® ï¥âáï ¡«¨¦ ©è¨¬ ª à£ã¬¥âã }
Asm
Mov CX, X
Push BP
Mov BP, 1
Mov BX, CX
JCXZ @end2
Cmp CX, 0FFFFH
JNE @cycle
Mov BX, 0FFH
Jmp @end2
@cycle:
Xor DX, DX
Mov AX, CX
Div BX
Add AX, BX
Shr AX, 1
Mov DI, SI
Mov SI, BX
Mov BX, AX
Inc BP
Cmp BX, SI
JE @end
Cmp BP, 3
JC @cycle
Cmp BX, DI
JNE @cycle
Cmp SI, BX
JNC @end
Mov BX, SI
@end:
Mov AX, BX
Mul BX
Sub AX, CX
Neg AX
Inc AX
Mov SI, AX { à §¨æ à£ã¬¥â ¨ ª¢ ¤à â ª®àï }
Inc BX
Mov AX, BX
Mul BX
Sub AX, CX { à §¨æ à£. ¨ ª¢ ¤à â 㢥«¨ç¥®£® ª®àï }
Cmp AX, SI
JC @end2
Dec BX
@end2:
Pop BP
Mov AX, BX
End;
Procedure Circle (X, Y, R : Word; C : Byte; Fill : Boolean);
Var
A, B : Word;
begin
If R = 0 then Exit;
If not Fill then
For A := 0 to R do
Begin
B := SqrWN(Sqr(R)-Sqr(A));
PutPixel (X-A, Y-B, C);
PutPixel (X+A, Y-B, C);
PutPixel (X-A, Y+B, C);
PutPixel (X+A, Y+B, C);
PutPixel (X-B, Y-A, C);
PutPixel (X-B, Y+A, C);
PutPixel (X+B, Y-A, C);
PutPixel (X+B, Y+A, C)
End
Else
For A := 0 to R do
Begin
B := SqrWN(Sqr(R)-Sqr(A));
LineH (X-B, Y-A, 1+B shl 1, C);
LineH (X-B, Y+A, 1+B shl 1, C)
End
End;
Procedure Fill (X, Y : Word; C : Byte);
Var
P1, P2 : Pointer;
Sg1, Sg2, P,
ZX, ZY, ZP : Word;
CO : Byte;
Begin
GetMem (P1, 64000);
GetMem (P2, 64000);
Sg1 := Seg(P1^);
Sg2 := Seg(P2^);
Asm
Mov AX, VSegA
Mov ES, AX
Mov DI, X
Mov BX, Y
ShL BX, 6
Add DI, BX
ShL BX, 2
Add DI, BX
Mov AL, ES:[DI]
Cmp AL, C
JE @end
Mov CO, AL
Mov ZP, 0
Mov AX, X
Mov ZX, AX
Mov AX, Y
Mov ZY, AX
@cycle:
Mov AX, VSegA
Mov ES, AX
Mov DI, ZX
Mov BX, ZY
ShL BX, 6
Add DI, BX
ShL BX, 2
Add DI, BX
Mov P, DI
Mov AL, C
Mov ES:[DI], AL
Mov AX, ZX
Or AX, AX
JZ @l2
Mov AL, ES:[DI-1]
Cmp AL, CO
JNE @l2
Dec DI
Push ES
Mov AX, Sg1
Mov BX, ZP
Cmp BX, 32000
JC @l1
Mov AX, Sg2
Sub BX, 32000
@l1:
Mov ES, AX
Shl BX, 1
Mov ES:[BX], DI
Inc ZP
Pop ES
Inc DI
@l2:
Mov AX, ZX
Cmp AX, 319
JNC @r2
Mov AL, ES:[DI+1]
Cmp AL, CO
JNE @r2
Inc DI
Push ES
Mov AX, Sg1
Mov BX, ZP
Cmp BX, 32000
JC @r1
Mov AX, Sg2
Sub BX, 32000
@r1:
Mov ES, AX
Shl BX, 1
Mov ES:[BX], DI
Inc ZP
Pop ES
Dec DI
@r2:
Mov AX, ZY
Or AX, AX
JZ @u2
Mov AL, ES:[DI-320]
Cmp AL, CO
JNE @u2
Sub DI, 320
Push ES
Mov AX, Sg1
Mov BX, ZP
Cmp BX, 32000
JC @u1
Mov AX, Sg2
Sub BX, 32000
@u1:
Mov ES, AX
Shl BX, 1
Mov ES:[BX], DI
Inc ZP
Pop ES
Add DI, 320
@u2:
Mov AX, ZY
Cmp AX, 199
JNC @d2
Mov AL, ES:[DI+320]
Cmp AL, CO
JNE @d2
Add DI, 320
Push ES
Mov AX, Sg1
Mov BX, ZP
Cmp BX, 32000
JC @d1
Mov AX, Sg2
Sub BX, 32000
@d1:
Mov ES, AX
Shl BX, 1
Mov ES:[BX], DI
Inc ZP
Pop ES
Sub DI, 320
@d2:
Mov BX, ZP
Or BX, BX
JZ @end
Dec BX
Mov ZP, BX
Mov AX, Sg1
Cmp BX, 32000
JC @p1
Mov AX, Sg2
Sub BX, 32000
@p1:
Mov ES, AX
Shl BX, 1
Mov AX, ES:[BX]
Mov P, AX
Mov AX, P
Xor DX, DX
Mov BX, 320
Div BX
Mov ZY, AX
Mov ZX, DX
Jmp @cycle
@end:
End;
FreeMem (P2, 64000);
FreeMem (P1, 64000)
End;
Procedure DrawPoly (Num : Word; PolyPoints : Array of TPoint; C : Byte);
Var I : Word;
Begin
If Num > 1 then
For I := 0 to Num-2 do Begin
Line (PolyPoints[I].X, PolyPoints[I].Y,
PolyPoints[I+1].X, PolyPoints[I+1].Y, C)
End
End;
Procedure DrawPoly2 (Num : Word; PolyPoints : Array of TPoint; C : Byte);
Var I : Word;
Begin
If Num > 0 then Begin
For I := 0 to Num-2 do Begin
Line (PolyPoints[I].X, PolyPoints[I].Y,
PolyPoints[I+1].X, PolyPoints[I+1].Y, C)
End;
Line (PolyPoints[Num-1].X, PolyPoints[Num-1].Y,
PolyPoints[0].X, PolyPoints[0].Y, C)
End
End;
Procedure FillPoly (Num : Word; PolyPoints : Array of TPoint; C : Byte);
Var I, Y, Ymin, Ymax : Integer;
Procedure DoSide (X1, Y1, X2, Y2 : Integer);
Var
Temp, I, X, Y,
SX, SY, M, N,
DX1, DY1, DX2, DY2 : Integer;
Begin
SX := X2-X1; SY := Y2-Y1;
DX1 := Sgn(SX); DY1 := Sgn(SY);
M := _Abs(SX); N := _Abs(SY);
DX2 := DX1; DY2 := 0;
If M < N then Begin
M := _Abs(SY); N := _Abs(SX);
DX2 := 0; DY2 := DY1
End;
X := X1; Y := Y1;
Temp := 0;
For I := 0 to M do Begin
If (Y >= 0) and (Y <= 199) then Begin
If X < _Poly[Y,1] then _Poly[Y,1] := X;
If X > _Poly[Y,2] then _Poly[Y,2] := X
End;
Inc (Temp, N);
If Temp < M then Begin
Inc (X, DX2); Inc (Y, DY2)
End
Else Begin
Dec (Temp, M);
Inc (X, DX1); Inc (Y, DY1)
End
End
End;
Begin
If Num < 3 then Exit;
Ymin := PolyPoints[0].Y; Ymax := Ymin;
For I := 0 to Num-1 do Begin
If PolyPoints[I].Y < Ymin then Ymin := PolyPoints[I].Y;
If PolyPoints[I].Y > Ymax then Ymax := PolyPoints[I].Y
End;
If (Ymin > 199) or (Ymax < 0) then Exit;
If Ymin < 0 then Ymin := 0; If Ymax > 199 then Ymax := 199;
For Y := Ymin to Ymax do Begin
_Poly[Y,1] := 320; _Poly[Y,2] := -1
End;
For I := 0 to Num-2 do
DoSide (PolyPoints[I].X, PolyPoints[I].Y,
PolyPoints[I+1].X, PolyPoints[I+1].Y);
DoSide (PolyPoints[Num-1].X, PolyPoints[Num-1].Y,
PolyPoints[0].X, PolyPoints[0].Y);
For Y := Ymin to Ymax do Begin
If _Poly[Y,1] < 0 then _Poly[Y,1] := 0;
If _Poly[Y,2] > 319 then _Poly[Y,2] := 319;
LineH (_Poly[Y,1], Y, _Poly[Y,2]-_Poly[Y,1]+1, C)
End
End;
Procedure FillPolyPat (Num : Word; PolyPoints : Array of TPoint;
L, H : Word; Var Pat);
Var
I, X, Y, Ymin, Ymax : Integer;
PA : Array [0..63999] of byte absolute Pat;
Procedure DoSide (X1, Y1, X2, Y2 : Integer);
Var
Temp, I, X, Y,
SX, SY, M, N,
DX1, DY1, DX2, DY2 : Integer;
Begin
SX := X2-X1; SY := Y2-Y1;
DX1 := Sgn(SX); DY1 := Sgn(SY);
M := _Abs(SX); N := _Abs(SY);
DX2 := DX1; DY2 := 0;
If M < N then Begin
M := _Abs(SY); N := _Abs(SX);
DX2 := 0; DY2 := DY1
End;
X := X1; Y := Y1;
Temp := 0;
For I := 0 to M do Begin
If (Y >= 0) and (Y <= 199) then Begin
If X < _Poly[Y,1] then _Poly[Y,1] := X;
If X > _Poly[Y,2] then _Poly[Y,2] := X
End;
Inc (Temp, N);
If Temp < M then Begin
Inc (X, DX2); Inc (Y, DY2)
End
Else Begin
Dec (Temp, M);
Inc (X, DX1); Inc (Y, DY1)
End
End
End;
Begin
If Num < 3 then Exit;
Ymin := PolyPoints[0].Y; Ymax := Ymin;
For I := 0 to Num-1 do Begin
If PolyPoints[I].Y < Ymin then Ymin := PolyPoints[I].Y;
If PolyPoints[I].Y > Ymax then Ymax := PolyPoints[I].Y
End;
If (Ymin > 199) or (Ymax < 0) then Exit;
If Ymin < 0 then Ymin := 0; If Ymax > 199 then Ymax := 199;
For Y := Ymin to Ymax do Begin
_Poly[Y,1] := 320; _Poly[Y,2] := -1
End;
For I := 0 to Num-2 do
DoSide (PolyPoints[I].X, PolyPoints[I].Y,
PolyPoints[I+1].X, PolyPoints[I+1].Y);
DoSide (PolyPoints[Num-1].X, PolyPoints[Num-1].Y,
PolyPoints[0].X, PolyPoints[0].Y);
For Y := Ymin to Ymax do Begin
If _Poly[Y,1] < 0 then _Poly[Y,1] := 0;
If _Poly[Y,2] > 319 then _Poly[Y,2] := 319;
I := L * (Y mod H);
For X := _Poly[Y,1] to _Poly[Y,2] do
PutPixel (X, Y, PA[I + (X mod 8)])
End
End;
Procedure LoadFont (Name : String; Var PF : PFont; Var Size : Word);
Var
F : File;
Label
LErr;
Begin
PF := nil;
Assign (F, Name);
{$i-}
Reset (F, 1);
{$i+}
If IOResult <> 0 then
Begin
LErr:
If PF <> nil then
FreeMem (PF, Size);
PF := nil;
Size := 0;
GrResult := GrLoadFont;
Exit
End;
{$i-} Size := FileSize(F); {$i+}
If IOResult <> 0 then Goto LErr;
GetMem (PF, Size);
{$i-} BlockRead (F, PF^, Size); {$i+}
If IOResult <> 0 then Goto LErr;
{$i-} Close (F); {$i+}
If IOResult <> 0 then Goto LErr;
GrResult := GrOk
End;
Procedure SetFont (PF : PFont);
Begin
FontX := Lo(Word(PF^));
FontY := Hi(Word(PF^));
CurFont := PF
End;
Procedure WriteC (X, Y : Word; B, T : Byte; C : Char); Assembler;
Asm
Push BP
Push DS
Mov AX, Word Ptr CurFont+2
Mov ES, AX
Mov DI, Word Ptr CurFont { ES:DI - Font Addr }
Mov CX, AX
Or CX, DI
JZ @End { ES:DI - nil }
Add DI, 2
Xor AH, AH
Mov AL, C
Shl AX, 1
Shl AX, 1
Shl AX, 1
Add DI, AX { ES:DI - Char Addr }
Mov AH, FontY
Mov AL, FontX { Char size -> stack }
Push AX
Mov AX, VSegA
Mov DS, AX
Mov AX, Y
Mov BX, 320
Mul BX
Add AX, X
Mov BX, AX { DS:BX - Screen Addr }
Mov DH, B
Mov DL, T { DX - Colors Back & Text }
Mov AX, SP
Mov BP, AX
Mov CH, SS:[BP+1]
@1:
Mov CL, SS:[BP]
Push BX
Mov AL, ES:[DI]
@2:
Mov AH, DL
Shl AL, 1
JC @Put
Cmp DH, DL
JE @NoPut
Mov AH, DH
@Put:
Mov DS:[BX], AH
@NoPut:
Inc BX
Dec CL
JNZ @2
Inc DI
Pop BX
Add BX, 320
Dec CH
JNZ @1
Pop AX
@End:
Pop DS
Pop BP
End;
Procedure WriteS (X, Y : Word; B, T : Byte; S : String);
Var
N : Byte;
Begin
If S = '' then Exit;
For N := 1 to Length(S) do
Begin
WriteC (X, Y, B, T, S[N]);
Inc (X, FontX)
End
End;
Procedure ReadS (X, Y : Word; B, T : Byte; Var S : String; N : Byte);
Const
CM = 20;
Var
C : Char;
P : Byte;
Cnt : Byte;
Begin
Box (X, Y, N*FontX, FontY, B, True);
WriteS (X, Y, B, T, S);
P := Length(S);
If P < N then
WriteC (X+P*FontX, Y, B, T, '_');
Cnt := 0;
Repeat
If KeyPressed then C := ReadKey
Else C := #$FF;
If C = #0 then
Begin
ReadKey;
C := #$FF
End;
If C = #27 then
Begin
S := '';
Break
End;
If C = #13 then Break;
If (C = #8) and (P > 0) then
Begin
Dec (S[0]);
If P < N then
WriteC (X+P*FontX, Y, B, T, ' ');
Dec (P);
WriteC (X+P*FontX, Y, B, T, '_');
Continue
End;
If (C in [#32..#254]) and (P < N) then
Begin
S := S + C;
WriteC (X+P*FontX, Y, B, T, C);
Inc (P);
If P < N then
WriteC (X+P*FontX, Y, B, T, '_')
End;
Delay (20);
Inc (Cnt);
If Cnt = CM then Cnt := 0;
If P < N then
If Cnt < CM div 2 then
WriteC (X+P*FontX, Y, B, T, '_')
Else
WriteC (X+P*FontX, Y, B, T, ' ')
Until False
End;
Function ImageSize (L, H : Word) : Word;
Begin
ImageSize := 4+L*H
End;
Procedure GetImage (X, Y, L, H : Word; Var BitMap); Assembler;
Asm
Push DS
Mov AX, H
Push AX
Mov DX, L
LES DI, BitMap { ES:DI - Memory Addr (BitMap^) }
Mov SI, X
Mov BX, Y
ShL BX, 6
Add SI, BX
ShL BX, 2
Add SI, BX
Mov AX, VSegA
Mov DS, AX { DS:SI - Screen Addr }
Mov ES:[DI], DX
Pop AX
Mov ES:[DI+2], AX { L & H -> BitMap }
Add DI, 4
CLD
Shr DX, 1
JC @2 { If L is ODD }
@1:
Mov BX, SI
Mov CX, DX
Rep MovSW
Mov SI, BX
Add SI, 320
Dec AX
JNZ @1
Pop DS
Jmp @end
@2:
Mov BX, SI
Mov CX, DX
MovSB
Rep MovSW
Mov SI, BX
Add SI, 320
Dec AX
JNZ @2
Pop DS
@end:
End;
Procedure GetImagePart (X, Y, L, H : Word; Var BitMap; PX, PY, PL, PH : Word); Assembler;
Asm
Push DS
Push BP
Mov SI, X
Mov BX, Y
ShL BX, 6
Add SI, BX
ShL BX, 2
Add SI, BX
Mov AX, VSegA
Mov DS, AX { DS:SI - Screen Addr }
LES DI, BitMap { ES:DI - ^BitMap }
Mov AX, L
Mov Word Ptr ES:[DI], AX
Mov AX, H
Mov Word Ptr ES:[DI+2], AX
Mov AX, PY
Mul L { DX:AX - vertical offset in image }
Add AX, 4
Add AX, PX
Mov DX, PL { Output length }
Mov BX, PH { Output height }
Mov BP, L { Image length }
Add DI, AX { ES:DI - correct starting addr }
CLD
Shr DX, 1
JC @2
@1:
Mov AX, SI
Mov CX, DX
Push DI
Rep MovSW
Pop DI
Add DI, BP
Mov SI, AX
Add SI, 320
Dec BX
JNZ @1
Jmp @end
@2:
Mov AX, SI
Mov CX, DX
Push DI
Rep MovSW
MovSB
Pop DI
Add DI, BP
Mov SI, AX
Add SI, 320
Dec BX
JNZ @2
@end:
Pop BP
Pop DS
End;
Procedure GetClippedImage (X, Y : Integer; L, H : Word; Var BitMap);
Var
Dims : Array [0..1] of Word absolute BitMap; {Dims[0]=Length;Dims[1]=Height}
RX, RY, RL, RH, IX, IY : Integer;
Begin
If (X > 319) or (Y > 199) then Exit; { Image is out of screen }
RX := X; RY := Y; { Start X & Y at screen }
RL := L; RH := H; { Length & Height at begining }
IX := 0; IY := 0; { IX & IY - coos in image to }
{ start drawin it (at begining) }
If RX < 0 then Begin
Inc (RL, RX); { Output length corrected }
Dec (IX, RX); { IX corrected }
RX := 0 { Screen X corrected }
End;
If RY < 0 then Begin
Inc (RH, RY); { Output height corrected }
Dec (IY, RY); { IY corrected }
RY := 0 { Screen Y corrected }
End;
If (RL <= 0) or (RH <= 0) then Exit; { Image is out of screen }
If RX+RL > 320 then RL := 320-RX; { Last correct in a length }
If RY+RH > 200 then RH := 200-RY; { Last correct in a height }
GetImagePart (RX, RY, L, H, BitMap, IX, IY, RL, RH) { Drawing clipped image... }
End;
Procedure PutImage (X, Y : Word; Var BitMap); Assembler;
Asm
Push DS
Mov DI, X
Mov BX, Y
ShL BX, 6
Add DI, BX
ShL BX, 2
Add DI, BX
Mov AX, VSegA
Mov ES, AX { ES:DI - Screen Addr }
LDS SI, BitMap { DS:SI - BitMap }
Mov DX, DS:[SI] { L }
Mov BX, DS:[SI+2] { H }
Add SI, 4
CLD
Shr DX, 1
JC @2
@1:
Mov AX, DI
Mov CX, DX
Rep MovSW
Mov DI, AX
Add DI, 320
Dec BX
JNZ @1
Pop DS
Jmp @end
@2:
Mov AX, DI
Mov CX, DX
Rep MovSW
MovSB
Mov DI, AX
Add DI, 320
Dec BX
JNZ @2
Pop DS
@end:
End;
Procedure PutTranspImage (X, Y : Word; Var BitMap); Assembler;
Asm
Push DS
Push BP
Mov DI, X
Mov BX, Y
ShL BX, 6
Add DI, BX
ShL BX, 2
Add DI, BX
Mov AX, VSegA
Mov ES, AX { ES:DI - Screen Addr }
Mov AH, TranspColor
LDS SI, BitMap { DS:SI - BitMap }
Mov DX, DS:[SI] { L }
Mov BX, DS:[SI+2] { H }
Add SI, 4
CLD
@cycle:
Mov BP, DI
Mov CX, DX
@cyc:
LODSB
Cmp AL, AH
JE @transp
STOSB
Jmp @norm
@transp:
Inc DI
@norm:
Loop @cyc
Mov DI, BP
Add DI, 320
Dec BX
JNZ @cycle
Pop BP
Pop DS
End;
Procedure PutImagePart (X, Y : Word; Var BitMap; PX, PY, PL, PH : Word); Assembler;
Asm
Push DS
Push BP
Mov DI, X
Mov BX, Y
ShL BX, 6
Add DI, BX
ShL BX, 2
Add DI, BX
Mov AX, VSegA
Mov ES, AX { ES:DI - Screen Addr }
LDS SI, BitMap { DS:SI - ^BitMap }
Mov AX, PY
Mul Word Ptr DS:[SI] { DX:AX - vertical offset in image }
Add AX, 4
Add AX, PX
Mov DX, PL { Output length }
Mov BX, PH { Output height }
Mov BP, DS:[SI] { Image length }
Add SI, AX { DS:SI - correct starting addr }
CLD
Shr DX, 1
JC @2
@1:
Mov AX, DI
Mov CX, DX
Push SI
Rep MovSW
Pop SI
Add SI, BP
Mov DI, AX
Add DI, 320
Dec BX
JNZ @1
Jmp @end
@2:
Mov AX, DI
Mov CX, DX
Push SI
Rep MovSW
MovSB
Pop SI
Add SI, BP
Mov DI, AX
Add DI, 320
Dec BX
JNZ @2
@end:
Pop BP
Pop DS
End;
Procedure PutTranspImagePart (X, Y : Word; Var BitMap; PX, PY, PL, PH : Word); Assembler;
Asm
Push DS
Push BP
Mov DI, X
Mov BX, Y
ShL BX, 6
Add DI, BX
ShL BX, 2
Add DI, BX
Mov AX, VSegA
Mov ES, AX { ES:DI - Screen Addr }
Push Word Ptr TranspColor
LDS SI, BitMap { DS:SI - ^BitMap }
Mov AX, PY
Mul Word Ptr DS:[SI] { DX:AX - vertical offset in image }
Add AX, 4
Add AX, PX
Mov DX, PL { Output length }
Mov BX, PH { Output height }
Mov BP, DS:[SI] { Image length }
Add SI, AX { DS:SI - correct starting addr }
CLD
Pop AX
@cycle:
Push DI
Mov CX, DX
Push SI
@cyc:
LODSB
Cmp AL, AH
JE @transp
STOSB
Jmp @norm
@transp:
Inc DI
@norm:
Loop @cyc
Pop SI
Add SI, BP
Pop DI
Add DI, 320
Dec BX
JNZ @cycle
Pop BP
Pop DS
End;
Procedure PutClippedImage (X, Y : Integer; Var BitMap);
Var
Dims : Array [0..1] of Word absolute BitMap; {Dims[0]=Length;Dims[1]=Height}
RX, RY, RL, RH, IX, IY : Integer;
Begin
If (X > 319) or (Y > 199) then Exit; { Image is out of screen }
RX := X; RY := Y; { Start X & Y at screen }
RL := Dims[0]; RH := Dims[1]; { Length & Height at begining }
IX := 0; IY := 0; { IX & IY - coos in image to }
{ start drawin it (at begining) }
If RX < 0 then Begin
Inc (RL, RX); { Output length corrected }
Dec (IX, RX); { IX corrected }
RX := 0 { Screen X corrected }
End;
If RY < 0 then Begin
Inc (RH, RY); { Output height corrected }
Dec (IY, RY); { IY corrected }
RY := 0 { Screen Y corrected }
End;
If (RL <= 0) or (RH <= 0) then Exit; { Image is out of screen }
If RX+RL > 320 then RL := 320-RX; { Last correct in a length }
If RY+RH > 200 then RH := 200-RY; { Last correct in a height }
PutImagePart (RX, RY, BitMap, IX, IY, RL, RH) { Drawing clipped image... }
End;
Procedure PutTranspClippedImage (X, Y : Integer; Var BitMap);
Var
Dims : Array [0..1] of Word absolute BitMap; {Dims[0]=Length;Dims[1]=Height}
RX, RY, RL, RH, IX, IY : Integer;
Begin
If (X > 319) or (Y > 199) then Exit; { Image is out of screen }
RX := X; RY := Y; { Start X & Y at screen }
RL := Dims[0]; RH := Dims[1]; { Length & Height at begining }
IX := 0; IY := 0; { IX & IY - coos in image to }
{ start drawin it (at begining) }
If RX < 0 then Begin
Inc (RL, RX); { Output length corrected }
Dec (IX, RX); { IX corrected }
RX := 0 { Screen X corrected }
End;
If RY < 0 then Begin
Inc (RH, RY); { Output height corrected }
Dec (IY, RY); { IY corrected }
RY := 0 { Screen Y corrected }
End;
If (RL <= 0) or (RH <= 0) then Exit; { Image is out of screen }
If RX+RL > 320 then RL := 320-RX; { Last correct in a length }
If RY+RH > 200 then RH := 200-RY; { Last correct in a height }
PutTranspImagePart (RX, RY, BitMap, IX, IY, RL, RH) { Drawing clipped image... }
End;
Procedure PutClippedImagePart (X, Y : Integer; Var BitMap; PX, PY, PL, PH : Word);
Var
Dims : Array [0..1] of Word absolute BitMap; {Dims[0]=Length;Dims[1]=Height}
RX, RY, RL, RH, IX, IY : Integer;
Begin
If (X > 319) or (Y > 199) then Exit; { Image is out of screen }
RX := X; RY := Y; { Start X & Y at screen }
RL := PL; RH := PH; { Length & Height at begining }
IX := PX; IY := PY; { IX & IY - coos in image to }
{ start drawin it (at begining) }
If RX < 0 then Begin
Inc (RL, RX); { Output length corrected }
Dec (IX, RX); { IX corrected }
RX := 0 { Screen X corrected }
End;
If RY < 0 then Begin
Inc (RH, RY); { Output height corrected }
Dec (IY, RY); { IY corrected }
RY := 0 { Screen Y corrected }
End;
If (RL <= 0) or (RH <= 0) then Exit; { Image is out of screen }
If RX+RL > 320 then RL := 320-RX; { Last correct in a length }
If RY+RH > 200 then RH := 200-RY; { Last correct in a height }
PutImagePart (RX, RY, BitMap, IX, IY, RL, RH) { Drawing clipped image... }
End;
Procedure PutTranspClippedImagePart (X, Y : Integer; Var BitMap; PX, PY, PL, PH : Word);
Var
Dims : Array [0..1] of Word absolute BitMap; {Dims[0]=Length;Dims[1]=Height}
RX, RY, RL, RH, IX, IY : Integer;
Begin
If (X > 319) or (Y > 199) then Exit; { Image is out of screen }
RX := X; RY := Y; { Start X & Y at screen }
RL := PL; RH := PH; { Length & Height at begining }
IX := PX; IY := PY; { IX & IY - coos in image to }
{ start drawin it (at begining) }
If RX < 0 then Begin
Inc (RL, RX); { Output length corrected }
Dec (IX, RX); { IX corrected }
RX := 0 { Screen X corrected }
End;
If RY < 0 then Begin
Inc (RH, RY); { Output height corrected }
Dec (IY, RY); { IY corrected }
RY := 0 { Screen Y corrected }
End;
If (RL <= 0) or (RH <= 0) then Exit; { Image is out of screen }
If RX+RL > 320 then RL := 320-RX; { Last correct in a length }
If RY+RH > 200 then RH := 200-RY; { Last correct in a height }
PutTranspImagePart (RX, RY, BitMap, IX, IY, RL, RH) { Drawing clipped image... }
End;
Procedure LoadObject (Name : String; Var PBitMap : Pointer; Var Size : Word);
Const
ID : Array [1..12] of Char = 'EGO''S FILE. ';
Var
F : File;
H : THeader;
I : Byte;
P : Pointer;
SF: Word;
Label
LErr;
Begin
PBitMap := nil;
Assign (F, Name);
{$i-}
Reset (F, 1);
{$i+}
If IOResult <> 0 then
Begin
LErr:
If PBitMap <> nil then
FreeMem (PBitMap, Size);
PBitMap := nil;
Size := 0;
GrResult := GrLoadObj;
Exit
End;
{$i-} BlockRead (F, H, SizeOf(H)); {$i+}
If IOResult <> 0 then Goto LErr;
For I := 1 to 12 do
If H.ID[I] <> ID[I] then Goto LErr;
Case H.Pack of
$00, $FF:
Begin
Size := (Ord(H.Mask)+1)*H.L*H.H+4;
GetMem (PBitMap, Size);
Word(PBitMap^) := H.L;
PBitMap := Ptr(Seg(PBitMap^), Ofs(PBitMap^)+2);
Word(PBitMap^) := H.H;
PBitMap := Ptr(Seg(PBitMap^), Ofs(PBitMap^)+2);
{$i-} BlockRead (F, PBitMap^, Size-4); {$i+}
PBitMap := Ptr(Seg(PBitMap^), Ofs(PBitMap^)-4);
If IOResult <> 0 then Goto LErr;
{$i-} Close (F); {$i+}
If IOResult <> 0 then Goto LErr;
End;
$01:
Begin
{$I-} SF := FileSize(F)-32; {$I+}
If IOResult <> 0 then Goto LErr;
Size := (Ord(H.Mask)+1)*H.L*H.H+4;
GetMem (PBitMap, Size);
GetMem (P, SF);
{$I-} BlockRead (F, P^, SF); {$I+}
If IOResult <> 0 then
Begin FreeMem (P, SF); Goto LErr End;
{$I-} Close (F); {$I+}
If IOResult <> 0 then
Begin FreeMem (P, SF); Goto LErr End;
Word(PBitMap^) := H.L;
PBitMap := Ptr(Seg(PBitMap^), Ofs(PBitMap^)+2);
Word(PBitMap^) := H.H;
PBitMap := Ptr(Seg(PBitMap^), Ofs(PBitMap^)+2);
UnPack (P^, PBitMap^, H.PSize);
If H.Mask then
Begin
P := Ptr(Seg(P^), Ofs(P^)+H.PSize);
PBitMap := Ptr(Seg(PBitMap^), Ofs(PBitMap^)+H.L*H.H);
UnPack (P^, PBitMap^, H.MSize);
PBitMap := Ptr(Seg(PBitMap^), Ofs(PBitMap^)-H.L*H.H);
P := Ptr(Seg(P^), Ofs(P^)-H.PSize)
End;
PBitMap := Ptr(Seg(PBitMap^), Ofs(PBitMap^)-4);
FreeMem (P, SF)
End;
End;
GrResult := GrOk
End;
Procedure LoadPCX256 (Name : String; Var PBitMap : Pointer; Var Size : Word;
Var Pal : TPal);
Var
Hd : TPCXHeader;
F : File;
L, H : Word;
PFBuf, Temp : Pointer;
Sz : Word;
Label LErr;
Begin
GrResult := GrOk;
Temp := nil;
Assign (F, Name);
{$I-} Reset (F, 1); {$I+}
If IOResult <> 0 then Begin
LErr:
If Temp <> nil then FreeMem (Temp, Size);
GrResult := GrLoadObj;
PBitMap := nil;
Size := 0;
Exit
End;
{$I-} BlockRead (F, Hd, 128); {$I+} { Load header }
If IOResult <> 0 then Goto LErr;
If (Hd.BitsPerPixel <> 8) or (Hd.Planes <> 1) then Goto LErr;
L := Hd.X2 - Hd.X1 + 1;
H := Hd.Y2 - Hd.Y1 + 1;
Size := 4 + L*H;
If Size > 64004 then Goto LErr; { If not in the range }
GetMem (Temp, Size); { Allocate memory for unpacked bitmap }
{$I-} Seek (F, FileSize(F)-768); {$I+}
If IOResult <> 0 then Goto LErr;
{$I-} BlockRead (F, Pal, 768); {$I+} { Load palette part }
If IOResult <> 0 then Goto LErr;
{$I-} Seek (F, 128); {$I+}
If IOResult <> 0 then Goto LErr;
Sz := FileSize(F)-896;
GetMem (PFBuf, Sz); { Allocate memory for file buffer }
{$I-} BlockRead (F, PFBuf^, Sz); {$I+} { Load picture body }
If IOResult <> 0 then Begin
FreeMem (PFBuf, Sz);
Goto LErr
End;
{$I-} Close (F); {$I+}
If IOResult <> 0 then Begin
FreeMem (PFBuf, Sz);
Goto LErr
End;
Asm
Push DS
Mov SI, Word Ptr Pal;
Mov DI, SI
Mov AX, Word Ptr Pal+2;
Mov DS, AX
Mov ES, AX
Mov CX, 768
CLD
@loop:
LODSB
Shr AL, 2 { Normalizing palette }
STOSB
Loop @loop
Pop DS
End;
Asm
Push DS
Push BP
LES DI, Temp { ES:DI = ^ unpacking buffer }
CLD
Mov AX, L { Picture length stored to memory }
STOSW
Push AX { Local constant L }
Mov AX, H
STOSW { Picture height stored to memory }
Mov BX, H
Push Hd.BytesPerLine { Local constant Hd.BytesPerLine }
LDS SI, PFBuf { DS:SI = ^ file buffer with packed pic }
Mov BP, SP { Pointer to the local constants }
Xor CH, CH { Hi byte of repeat counter,always 0 }
Xor DX, DX { Written pixels counter }
@cyc:
LODSB
Cmp AL, 0C0h
JNC @repeat { If need to repeat pixel }
Cmp DX, SS:[BP+2]
JNC @1 { If run off the line }
STOSB { Writing if all right }
@1:
Inc DX
Jmp @next
@repeat:
And AL, 3Fh
Mov CL, AL { CX = repeat count }
Add DX, CX
LODSB { AL = repeated pixel (color) }
Cmp DX, SS:[BP+2]
JG @2 { If run off the line }
Rep STOSB { Writing if all right }
Jmp @next
@2:
Add CX, SS:[BP+2]
Sub CX, DX { CX = corrected repeat count }
Rep STOSB
@next:
Cmp DX, SS:[BP]
JNE @cyc { Line isn't done }
Xor DX, DX
Dec BX
JNZ @cyc { Going to the next line }
Add SP, 4 { Remove local constants from stack }
Pop BP { Restore original BP }
Pop DS { Restore original DS }
End;
FreeMem (PFBuf, Sz); { Deallocating file buffer }
PBitMap := Temp { Returning address of our bitmap }
End;
Procedure SavePCX256 (Name : String; X, Y, L, H : Word);
Const
Z : Byte = 12;
Var
F : File;
Hd : TPCXHeader;
Pal,
Buf : Array [0..767] of Byte;
J, Cnt,
Len : Word;
Rep, B : Byte;
PLeft, P : ^Byte;
Label
LErr;
Begin
FillChar (Hd, SizeOf(Hd), 0);
Hd.X1 := 0; Hd.Y1 := 0; Hd.X2 := L-1; Hd.Y2 := H-1;
Hd.Manufact := 10; Hd.Ver := 5; Hd.Encoding := 1;
Hd.BitsPerPixel := 8; Hd.Planes := 1; Hd.PalInfo := 1;
Hd.BytesPerLine := L + (L and 1);
Assign (F, Name);
{$I-} Rewrite (F, 1); {$I+}
If IOResult <> 0 then Begin
LErr:
GrResult := GrSaveObj;
Exit
End;
{$I-} BlockWrite (F, Hd, SizeOf(Hd)); {$I+}
If IOResult <> 0 then Begin
{$I-} Close (F); {$I+}
Goto LErr
End;
PLeft := Ptr (VSegA, Y*320+X);
For J := 0 to H-1 do Begin
Cnt := 0;
Len := 0;
P := PLeft;
Repeat
B := P^; Inc (Word(P)); Inc (Cnt);
Rep := 1;
While (B = P^) and (Rep < 63) and (Cnt < L) do Begin
Inc (Rep);
Inc (Cnt);
Inc (Word(P))
End;
If Rep > 1 then Begin
Buf[Len] := $C0 or Rep;
Buf[Len+1] := B;
Inc (Len, 2)
End
Else Begin
If B >= $C0 then Begin
Buf[Len] := $C1; Inc (Len)
End;
Buf[Len] := B;
Inc (Len)
End
Until Cnt = L;
Buf[Len] := 0;
{$I-} BlockWrite (F, Buf, Len + (L and 1)); {$I+}
If IOResult <> 0 then Begin
{$I-} Close (F); {$I+}
Goto LErr
End;
Inc (Word(PLeft), 320)
End;
BlockWrite (F, Z, 1);
GetPal (Pal);
For J := 0 to 767 do Pal[J] := Pal[J] shl 2;
BlockWrite (F, Pal, 768);
Close (F)
End;
Procedure PutImageM (X, Y : Word; Var BitMap); Assembler;
Asm
Push DS
Push BP
Mov DI, X
Mov BX, Y
ShL BX, 6
Add DI, BX
ShL BX, 2
Add DI, BX
Mov AX, VSegA
Mov ES, AX { ES:DI - Screen Addr }
LDS SI, BitMap { DS:SI - BitMap }
Mov AX, DS:[SI] { L }
Mov BX, DS:[SI+2] { H }
Mul BX
Mov BP, AX { BP = L*H }
Mov DX, DS:[SI] { L }
Add SI, 4
CLD
@1:
Push DI
Mov CX, DX
@2:
Mov AL, ES:[DI]
And AL, DS:[SI+BP]
Xor AL, DS:[SI]
STOSB
Inc SI
Loop @2
Pop DI
Add DI, 320
Dec BX
JNZ @1
Pop BP
Pop DS
End;
Procedure SetActivePage (PageSeg : Word);
Begin
VSegA := PageSeg
End;
Procedure DisplayPage (PageSeg : Word); Assembler;
Asm
Push DS
Mov AX, SegA000
Mov ES, AX
Xor DI, DI
Mov AX, PageSeg
Mov DS, AX
Mov SI, DI
CLD
Mov CX, 32000
Rep MovSW
Pop DS
End;
Procedure DisplayBox (PageSeg, X, Y, L, H : Word); Assembler;
Asm
Push DS
Mov AX, SegA000
Mov ES, AX
Mov DI, X
Mov BX, Y
ShL BX, 6
Add DI, BX
ShL BX, 2
Add DI, BX { ES:DI - Screen Addr }
Mov BX, H { H }
Mov DX, L { L }
Mov AX, PageSeg
Mov SI, DI { DI - Offset in Page }
Mov DS, AX { DS:SI - Addr in Page }
CLD
Shr DX, 1
JC @2 { If L is ODD }
@1:
Mov CX, DX
Push SI
Rep MovSW
Pop SI
Add SI, 320
Mov DI, SI
Dec BX
JNZ @1
Pop DS
Jmp @end
@2:
Mov CX, DX
Push SI
MovSB
Rep MovSW
Pop SI
Add SI, 320
Mov DI, SI
Dec BX
JNZ @2
Pop DS
@end:
End;
Procedure WaitRetrace; Assembler;
{ This waits until you are in a Verticle Retrace ... this means that all
screen manipulation you do only appears on screen in the next verticle
retrace ... this removes most of the "fuzz" that you see on the screen
when changing the pallette. It unfortunately slows down your program
by "synching" your program with your monitor card ... it does mean
that the program will run at almost the same speed on different
speeds of computers which have similar monitors. In our SilkyDemo,
we used a WaitRetrace, and it therefore runs at the same (fairly
fast) speed when Turbo is on or off. }
Label
L1, L2;
Asm
Mov DX, 3DAH
L1:
In AL,DX
And AL,08H
JNZ L1
L2:
In AL,DX
And AL,08H
JZ L2
End;
Procedure GetCRGB (C : Byte; Var R, G, B : Byte);
Begin
Port[$3C7] := C;
R := Port[$3C9];
G := Port[$3C9];
B := Port[$3C9]
End;
Procedure SetCRGB (C : Byte; R, G, B : Byte);
Begin
Port[$3C8] := C;
Port[$3C9] := R;
Port[$3C9] := G;
Port[$3C9] := B
End;
Procedure GetPal (Var Pal); Assembler;
Asm
LES DI, Pal
Mov CX, 768
CLD
Mov DX, 3C7h
Xor AL, AL
Out DX, AL
Inc DX
Inc DX
Rep InSB
End;
Procedure SetPal (Var Pal); Assembler;
Asm
Mov BX, DS
LDS SI, Pal
Mov CX, 768
CLD
Mov DX, 3C8h
Xor AL, AL
Out DX, AL
Inc DX
Rep OutSB
Mov DS, BX
End;
Procedure FadeUp (Pal : TPal);
Var
Cnt, C,
R, G, B : Byte;
Begin
For Cnt := 0 to 63 do
Begin
WaitRetrace;
For C := 0 to 255 do
Begin
GetCRGB (C, R, G, B);
If 64-Cnt <= Pal[C,1]-R then
Inc (R);
If 64-Cnt <= Pal[C,2]-G then
Inc (G);
If 64-Cnt <= Pal[C,3]-B then
Inc (B);
SetCRGB (C, R, G, B)
End
End
End;
Procedure FadeDown;
Var
Cnt, C,
R, G, B : Byte;
Begin
For Cnt := 0 to 63 do
Begin
WaitRetrace;
For C := 0 to 255 do
Begin
GetCRGB (C, R, G, B);
If R > 0 then Dec (R);
If G > 0 then Dec (G);
If B > 0 then Dec (B);
SetCRGB (C, R, G, B)
End
End
End;
Procedure BlackOutPut;
Var C : Byte;
Begin
For C := 0 to 255 do
SetCRGB (C, 0, 0, 0)
End;
Procedure TextureMapPoly (X1,Y1, X2,Y2, X3,Y3, X4,Y4, L, H : Integer;
PicSeg : Word);
Procedure ScanLeftSide (X1,X2,Ytop,LH:Integer;Side:Byte);
{ Scan in our needed variables ... X on the left, texturmap X, texturemap Y }
Var
Y, X, PX, PY, DPX, DPY,
SX, SY, M, N, DX1, DY1, DX2, DY2, I, T, Xm, Yt : Integer;
Begin
{ SX := X2-X1; SY := LH;} { !!! }
SX := X1-X2; SY := -LH; { !!! }
DX1 := Sgn(SX); DY1 := Sgn(SY);
M := _Abs(SX); N := _Abs(SY);
DX2 := DX1; DY2 := 0;
If M < N then Begin
M := _Abs(SY); N := _Abs(SX);
DX2 := 0; DY2 := DY1
End;
LH := LH + 1;
If Side = 1 then Begin
PX := (L-1) shl 7;
PY := 0;
DPX:= (-(L-1) shl 7) div LH;
DPY := 0;
End;
If Side = 2 then Begin
PX := (L-1) shl 7;
PY := (H-1) shl 7;
DPX := 0;
DPY := (-(H-1) shl 7) div LH;
End;
If Side = 3 then Begin
PX := 0;
PY := (H-1) shl 7;
DPX := (L-1) shl 7 div LH;
DPY := 0;
End;
If Side = 4 then Begin
PX := 0;
PY := 0;
DPX := 0;
DPY := (H-1) shl 7 div LH;
End;
{ X := X1; Y := Ytop;} { !!! }
X := X2; Y := Ytop+LH-1; { !!! }
Yt := Y; Xm := X;
T := 0;
For I := 0 to M do Begin
If Y = Yt then Begin
If Xm > X then Xm := X
End
Else Begin
If (Yt >= 0) and (Yt <= 199) then
_LeftTable[Yt,0] := Xm;
Yt := Y; Xm := X
End;
Inc (T, N);
If T < M then Begin
Inc (X, DX2); Inc (Y, DY2)
End
Else Begin
Dec (T, M);
Inc (X, DX1); Inc (Y, DY1)
End;
End;
If (Yt >= 0) and (Yt <= 199) then
_LeftTable[Yt,0] := Xm;
For Y := 0 to LH-1 do Begin
If (Ytop+Y >= 0) and (Ytop+Y <= 199) then Begin
_LeftTable[Ytop+Y,1] := PX shr 7;
_LeftTable[Ytop+Y,2] := PY shr 7
End;
PX := PX + DPX;
PY := PY + DPY
End
End;
Procedure ScanRightSide (X1, X2, Ytop, LH : Integer; Side : Byte);
{ Scan in our needed variables ... X on the right, texturmap X, texturemap Y }
Var
Y, X, PX, PY, DPX, DPY,
SX, SY, M, N, DX1, DY1, DX2, DY2, I, T, Xm, Yt : Integer;
Begin
SX := X2-X1; SY := LH;
DX1 := Sgn(SX); DY1 := Sgn(SY);
M := _Abs(SX); N := _Abs(SY);
DX2 := DX1; DY2 := 0;
If M < N then Begin
M := _Abs(SY); N := _Abs(SX);
DX2 := 0; DY2 := DY1
End;
LH := LH + 1;
If Side = 1 then Begin
PX := 0;
PY := 0;
DPX := (L-1) shl 7 div LH;
DPY := 0;
End;
If Side = 2 then Begin
PX := (L-1) shl 7;
PY := 0;
DPX := 0;
DPY := (H-1) shl 7 div LH;
End;
If Side = 3 then Begin
PX := (L-1) shl 7;
PY := (H-1) shl 7;
DPX := (-(L-1)) shl 7 div LH;
DPY := 0;
End;
If Side = 4 then Begin
PX := 0;
PY := (H-1) shl 7;
DPX := 0;
DPY := (-(H-1)) shl 7 div LH;
End;
X := X1; Y := Ytop;
Yt := Y; Xm := X;
T := 0;
For I := 0 to M do Begin
If Y = Yt then Begin
If Xm < X then Xm := X
End
Else Begin
If (Yt >= 0) and (Yt <= 199) then
_RightTable[Yt,0] := Xm;
Yt := Y; Xm := X
End;
Inc (T, N);
If T < M then Begin
Inc (X, DX2); Inc (Y, DY2)
End
Else Begin
Dec (T, M);
Inc (X, DX1); Inc (Y, DY1)
End;
End;
If (Yt >= 0) and (Yt <= 199) then
_RightTable[Yt,0] := Xm;
For Y := 0 to LH-1 do Begin
If (Ytop+Y >= 0) and (Ytop+Y <= 199) then Begin
_RightTable[Ytop+Y,1] := PX shr 7;
_RightTable[Ytop+Y,2] := PY shr 7
End;
PX := PX + DPX;
PY := PY + DPY
End
End;
Var
Ymin, Ymax,
PX1, PY1, PX2, PY2,
XL, XR, X, Y, LW,
DPX, DPY : Integer;
Label LC;
Begin
Ymin := Y1; Ymax := Y1;
If Y1 < Ymin then Ymin := Y1;
If Y1 > Ymax then Ymax := Y1;
If Y2 < Ymin then Ymin := Y2;
If Y2 > Ymax then Ymax := Y2;
If Y3 < Ymin then Ymin := Y3;
If Y3 > Ymax then Ymax := Y3;
If Y4 < Ymin then Ymin := Y4;
If Y4 > Ymax then Ymax := Y4;
If Ymax-Ymin < 2 then Exit;
If (Ymin > 199) or (Ymax < 0) then Exit;
If Y2 < Y1 then ScanLeftSide (X2, X1, Y2, Y1-Y2, 1)
Else ScanRightSide (X1, X2, Y1, Y2-Y1, 1);
{ If point2.Y is above point1.Y, Point1 to Point2 is on the "left",
and our leftside array must be altered }
If Y3 < Y2 then ScanLeftSide (X3, X2, Y3, Y2-Y3, 2)
Else ScanRightSide (X2, X3, Y2, Y3-Y2, 2);
If Y4 < Y3 then ScanLeftSide (X4, X3, Y4, Y3-Y4, 3)
Else ScanRightSide (X3, X4, Y3, Y4-Y3, 3);
If Y1 < Y4 then ScanLeftSide (X1, X4, Y1, Y4-Y1, 4)
Else ScanRightSide (X4, X1, Y4, Y1-Y4, 4);
{ This uses the tables we have created to actually draw the texture }
If Ymin < 0 then Ymin:=0;
If Ymax > 199 then Ymax:=199;
For Y := Ymin to Ymax do Begin
XL := _LeftTable[Y,0]; { X Starting position }
PX1 := _LeftTable[Y,1] shl 7; { Texture X at start }
PY1 := _LeftTable[Y,2] shl 7; { Texture Y at stary }
XR := _RightTable[Y,0]; { X Ending position }
PX2 := _RightTable[Y,1] shl 7; { Texture X at End }
PY2 := _RightTable[Y,2] shl 7; { Texture Y at End }
LW := XR-XL; { Width of line }
If LW <= 0 then Goto LC;
DPX := (PX2-PX1) div LW;
DPY := (PY2-PY1) div LW;
While XL < 0 do Begin
PX1 := PX1 + DPX;
PY1 := PY1 + DPY;
Inc (XL);
Dec (LW); If LW < 0 then Goto LC
End;
While XR > 319 do Begin
Dec (XR);
Dec (LW); If LW < 0 then Goto LC
End;
Asm
Push DS
Mov AX, VSegA
Mov ES, AX
Mov DI, XL
Mov BX, Y
ShL BX, 6
Add DI, BX
ShL BX, 2
Add DI, BX { ES:DI - Screen start addr }
Mov AX, PicSeg
Mov DS, AX
Mov CX, LW
Inc CX { Line length }
Mov BX, PX1 { Texture X }
Mov DX, PY1 { Texture Y }
CLD
@cyc:
Mov SI, BX
Shr SI, 7
Push DX
Shr DX, 7
Mov AX, L
Mul DX
Add SI, AX { DS:SI - Addres in texture }
Pop DX
MOVSB { Copy pixel:texture->screen }
Add BX, DPX { PX1 = PX1 + DPX }
Add DX, DPY { PY1 = PY1 + DPY }
Loop @cyc
Pop DS
End;
LC:
End;
End;
Procedure TextureMapPoly2 (X1,Y1, X2,Y2, X3,Y3, X4,Y4, L, H : Integer;
N : Byte; PicSeg : Word);
Procedure ScanLeftSide (X1,X2,Ytop,LH:Integer;Side:Byte);
{ Scan in our needed variables ... X on the left, texturmap X, texturemap Y }
Var
Y, X, PX, PY, DPX, DPY,
SX, SY, M, N, DX1, DY1, DX2, DY2, I, T, Xm, Yt : Integer;
Begin
{ SX := X2-X1; SY := LH;} { !!! }
SX := X1-X2; SY := -LH; { !!! }
DX1 := Sgn(SX); DY1 := Sgn(SY);
M := _Abs(SX); N := _Abs(SY);
DX2 := DX1; DY2 := 0;
If M < N then Begin
M := _Abs(SY); N := _Abs(SX);
DX2 := 0; DY2 := DY1
End;
LH := LH + 1;
If Side = 1 then Begin
PX := (L-1) shl 7;
PY := 0;
DPX:= (-(L-1) shl 7) div LH;
DPY := 0;
End;
If Side = 2 then Begin
PX := (L-1) shl 7;
PY := (H-1) shl 7;
DPX := 0;
DPY := (-(H-1) shl 7) div LH;
End;
If Side = 3 then Begin
PX := 0;
PY := (H-1) shl 7;
DPX := (L-1) shl 7 div LH;
DPY := 0;
End;
If Side = 4 then Begin
PX := 0;
PY := 0;
DPX := 0;
DPY := (H-1) shl 7 div LH;
End;
{ X := X1; Y := Ytop;} { !!! }
X := X2; Y := Ytop+LH-1; { !!! }
Yt := Y; Xm := X;
T := 0;
For I := 0 to M do Begin
If Y = Yt then Begin
If Xm > X then Xm := X
End
Else Begin
If (Yt >= 0) and (Yt <= 199) then
_LeftTable[Yt,0] := Xm;
Yt := Y; Xm := X
End;
Inc (T, N);
If T < M then Begin
Inc (X, DX2); Inc (Y, DY2)
End
Else Begin
Dec (T, M);
Inc (X, DX1); Inc (Y, DY1)
End;
End;
If (Yt >= 0) and (Yt <= 199) then
_LeftTable[Yt,0] := Xm;
For Y := 0 to LH-1 do Begin
If (Ytop+Y >= 0) and (Ytop+Y <= 199) then Begin
_LeftTable[Ytop+Y,1] := PX shr 7;
_LeftTable[Ytop+Y,2] := PY shr 7
End;
PX := PX + DPX;
PY := PY + DPY
End
End;
Procedure ScanRightSide (X1, X2, Ytop, LH : Integer; Side : Byte);
{ Scan in our needed variables ... X on the right, texturmap X, texturemap Y }
Var
Y, X, PX, PY, DPX, DPY,
SX, SY, M, N, DX1, DY1, DX2, DY2, I, T, Xm, Yt : Integer;
Begin
SX := X2-X1; SY := LH;
DX1 := Sgn(SX); DY1 := Sgn(SY);
M := _Abs(SX); N := _Abs(SY);
DX2 := DX1; DY2 := 0;
If M < N then Begin
M := _Abs(SY); N := _Abs(SX);
DX2 := 0; DY2 := DY1
End;
LH := LH + 1;
If Side = 1 then Begin
PX := 0;
PY := 0;
DPX := (L-1) shl 7 div LH;
DPY := 0;
End;
If Side = 2 then Begin
PX := (L-1) shl 7;
PY := 0;
DPX := 0;
DPY := (H-1) shl 7 div LH;
End;
If Side = 3 then Begin
PX := (L-1) shl 7;
PY := (H-1) shl 7;
DPX := (-(L-1)) shl 7 div LH;
DPY := 0;
End;
If Side = 4 then Begin
PX := 0;
PY := (H-1) shl 7;
DPX := 0;
DPY := (-(H-1)) shl 7 div LH;
End;
X := X1; Y := Ytop;
Yt := Y; Xm := X;
T := 0;
For I := 0 to M do Begin
If Y = Yt then Begin
If Xm < X then Xm := X
End
Else Begin
If (Yt >= 0) and (Yt <= 199) then
_RightTable[Yt,0] := Xm;
Yt := Y; Xm := X
End;
Inc (T, N);
If T < M then Begin
Inc (X, DX2); Inc (Y, DY2)
End
Else Begin
Dec (T, M);
Inc (X, DX1); Inc (Y, DY1)
End;
End;
If (Yt >= 0) and (Yt <= 199) then
_RightTable[Yt,0] := Xm;
For Y := 0 to LH-1 do Begin
If (Ytop+Y >= 0) and (Ytop+Y <= 199) then Begin
_RightTable[Ytop+Y,1] := PX shr 7;
_RightTable[Ytop+Y,2] := PY shr 7
End;
PX := PX + DPX;
PY := PY + DPY
End
End;
Var
Ymin, Ymax,
PX1, PY1, PX2, PY2,
XL, XR, X, Y, LW,
DPX, DPY : Integer;
Label LC;
Begin
Ymin := Y1; Ymax := Y1;
If Y1 < Ymin then Ymin := Y1;
If Y1 > Ymax then Ymax := Y1;
If Y2 < Ymin then Ymin := Y2;
If Y2 > Ymax then Ymax := Y2;
If Y3 < Ymin then Ymin := Y3;
If Y3 > Ymax then Ymax := Y3;
If Y4 < Ymin then Ymin := Y4;
If Y4 > Ymax then Ymax := Y4;
If Ymax-Ymin < 2 then Exit;
If (Ymin > 199) or (Ymax < 0) then Exit;
If Y2 < Y1 then ScanLeftSide (X2, X1, Y2, Y1-Y2, 1)
Else ScanRightSide (X1, X2, Y1, Y2-Y1, 1);
{ If point2.Y is above point1.Y, Point1 to Point2 is on the "left",
and our leftside array must be altered }
If Y3 < Y2 then ScanLeftSide (X3, X2, Y3, Y2-Y3, 2)
Else ScanRightSide (X2, X3, Y2, Y3-Y2, 2);
If Y4 < Y3 then ScanLeftSide (X4, X3, Y4, Y3-Y4, 3)
Else ScanRightSide (X3, X4, Y3, Y4-Y3, 3);
If Y1 < Y4 then ScanLeftSide (X1, X4, Y1, Y4-Y1, 4)
Else ScanRightSide (X4, X1, Y4, Y1-Y4, 4);
{ This uses the tables we have created to actually draw the texture }
If Ymin < 0 then Ymin:=0;
If Ymax > 199 then Ymax:=199;
For Y := Ymin to Ymax do Begin
XL := _LeftTable[Y,0]; { X Starting position }
PX1 := _LeftTable[Y,1] shl 7; { Texture X at start }
PY1 := _LeftTable[Y,2] shl 7; { Texture Y at stary }
XR := _RightTable[Y,0]; { X Ending position }
PX2 := _RightTable[Y,1] shl 7; { Texture X at End }
PY2 := _RightTable[Y,2] shl 7; { Texture Y at End }
LW := XR-XL; { Width of line }
If LW <= 0 then Goto LC;
DPX := (PX2-PX1) div LW;
DPY := (PY2-PY1) div LW;
While XL < 0 do Begin
PX1 := PX1 + DPX;
PY1 := PY1 + DPY;
Inc (XL);
Dec (LW); If LW < 0 then Goto LC
End;
While XR > 319 do Begin
Dec (XR);
Dec (LW); If LW < 0 then Goto LC
End;
Inc (PX1, (L * (N and 1)) shl 7);
Inc (PY1, (H * (N shr 1)) shl 7);
Asm
Push DS
Mov AX, VSegA
Mov ES, AX
Mov DI, XL
Mov BX, Y
ShL BX, 6
Add DI, BX
ShL BX, 2
Add DI, BX { ES:DI - Screen start addr }
Mov AX, PicSeg
Mov DS, AX
Mov CX, LW
Inc CX { Line length }
Mov BX, PX1 { Texture X }
Mov DX, PY1 { Texture Y }
CLD
@cyc:
Mov SI, BX
Shr SI, 7
Push DX
Shr DX, 7
Mov AX, L
Mul DX
Shl AX, 1
Add SI, AX { DS:SI - Addres in texture }
Pop DX
MOVSB { Copy pixel:texture->screen }
Add BX, DPX { PX1 = PX1 + DPX }
Add DX, DPY { PY1 = PY1 + DPY }
Loop @cyc
Pop DS
End;
LC:
End;
End;
Procedure DisplayOff; Assembler;
Asm
CLI
Mov DX, Seq_Addr
Mov AL, 1
Out DX, AL
Inc DX
In AL, DX
Or AL, 20h
Mov AH, AL
Mov AL, 1
Dec DX
Out DX, AX
STI
End;
Procedure DisplayOn; Assembler;
Asm
CLI
Mov DX, Seq_Addr
Mov AL, 1
Out DX, AL
Inc DX
In AL, DX
And AL, 0DFh
Mov AH, AL
Mov AL, 1
Dec DX
Out DX, AX
STI
End;
Begin
GrResult := GrOk;
CurFont := nil;
FontX := 0;
FontY := 0;
VSegA := SegA000;
TranspColor := Black
End.