home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / MCGA#07.ZIP / MCGA07.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1992-06-12  |  9.5 KB  |  493 lines

  1. Unit MCGA07;
  2.  
  3. interface
  4.  
  5. type
  6.   PCXHeaderPtr=  ^PCXHeader;
  7.   PCXHeader   =  record
  8.                    Signature      :  Char;
  9.                    Version        :  Char;
  10.                    Encoding       :  Char;
  11.                    BitsPerPixel   :  Char;
  12.                    XMin,YMin,
  13.                    XMax,YMax      :  Integer;
  14.                    HRes,VRes      :  Integer;
  15.                    Palette        :  Array [0..47] of byte;
  16.                    Reserved       :  Char;
  17.                    Planes         :  Char;
  18.                    BytesPerLine   :  Integer;
  19.                    PaletteType    :  Integer;
  20.                    Filler         :  Array [0..57] of byte;
  21.                  end;
  22.  
  23.   PointerType =  array [0..65500] of byte;
  24.   NewPointer  =  ^PointerType;
  25.  
  26. var
  27.   ScreenWide  :  Word;
  28.  
  29. Procedure SetGraphMode (Num:Byte);
  30. Procedure SetPixel     (X,Y:Integer;Color:Byte);
  31. Function  GetPixel     (X,Y:Integer) : Word;
  32. Procedure ClearScreen  (Color:Byte);
  33.  
  34. Procedure Line         (X1,Y1,X2,Y2:Integer;Color:Byte);
  35. Procedure Box          (X1,Y1,X2,Y2:Integer;Color:Byte);
  36. Procedure DisplayPCX   (X,Y:Integer;Buf:Pointer);
  37.  
  38. Function  ImageSize    (X1,Y1,X2,Y2:Integer) : Word;
  39. Procedure GetImagePas  (X1,Y1,X2,Y2:Integer;P:Pointer);
  40. Procedure PutImagePas  (X1,Y1:Integer;P:Pointer);
  41. Procedure GetImageAsm  (X1,Y1,X2,Y2:Integer;P:Pointer);
  42. Procedure PutImageAsm  (X1,Y1:Integer;P:Pointer);
  43.  
  44. implementation
  45.  
  46. var
  47.   ScreenAddr  :  Word;
  48.  
  49. Procedure Move (Var Source,Dest;Count:Word);
  50. begin
  51.   asm
  52.     push ds
  53.     cld
  54.     lds  si,Source
  55.     les  di,Dest
  56.     mov  cx,Count
  57.     shr  cx,1
  58.     rep  movsw
  59.  
  60.     mov  cx,Count
  61.     test cl,1
  62.     jz   @@EvenCount
  63.     movsb
  64.  
  65.   @@EvenCount:
  66.     pop  ds
  67.   end;
  68. end;
  69.  
  70. Procedure SetGraphMode (Num:Byte);
  71. begin
  72.   asm
  73.     mov al,Num
  74.     mov ah,0
  75.     int 10h
  76.     end;
  77.   Case Num of
  78.     $13 : ScreenWide := 320;
  79.     end;
  80.   ScreenAddr := $A000;
  81. end;
  82.  
  83. Procedure SetPixel (X,Y:Integer;Color:Byte);
  84. begin
  85.   asm
  86.     push ds
  87.     mov  ax,ScreenAddr
  88.     mov  ds,ax
  89.  
  90.     mov  ax,Y
  91.     mov  bx,320
  92.     mul  bx
  93.     mov  bx,X
  94.     add  bx,ax
  95.  
  96.     mov  al,Color
  97.     mov  byte ptr ds:[bx],al
  98.     pop  ds
  99.     end;
  100. end;
  101.  
  102. Function GetPixel (X,Y:Integer) : Word;
  103. begin
  104.   asm
  105.     push ds
  106.     mov  ax,ScreenAddr
  107.     mov  ds,ax
  108.  
  109.     mov  ax,Y
  110.     mov  bx,320
  111.     mul  bx
  112.     mov  bx,X
  113.     add  bx,ax
  114.  
  115.     xor  ax,ax
  116.     mov  al,byte ptr ds:[bx]
  117.     mov  @Result,ax
  118.     pop  ds
  119.     end;
  120. end;
  121.  
  122. Procedure ClearScreen (Color:Byte);
  123. begin
  124.   asm
  125.     push es
  126.     mov  ax,ScreenAddr
  127.     mov  es,ax
  128.  
  129.     xor  di,di
  130.  
  131.     cld
  132.  
  133.     mov  al,Color
  134.     mov  cx,320*200
  135.  
  136.     rep  stosb
  137.  
  138.     pop  es
  139.     end;
  140. end;
  141.  
  142. Procedure HorzLine (X1,X2,Y1:Integer;Color:Byte);
  143. var
  144.   Temp   :  Integer;
  145. begin
  146.   If X1 > X2 then begin
  147.     Temp := X1;
  148.     X1   := X2;
  149.     X2   := Temp;
  150.     end;
  151.   asm
  152.     push es
  153.     mov  ax,ScreenAddr
  154.     mov  es,ax               { Point es to screen segment }
  155.  
  156.     cld
  157.  
  158.     mov  ax,Y1               { Calculate starting video memory location }
  159.     mov  di,ScreenWide
  160.     mul  di                  { Multiply row number by width of screen }
  161.     mov  di,X1
  162.     add  di,ax               { Add to that result the X value }
  163.                              { Result: es:di -> first pixel to draw }
  164.     mov  cx,X2
  165.     sub  cx,X1
  166.     inc  cx                  { cx = number of pixels to draw }
  167.  
  168.     mov  al,Color            { put the color in al }
  169.  
  170.     rep  stosb               { use a fast 8088 instruction to store al }
  171.  
  172.     pop  es
  173.     end;
  174. end;
  175.  
  176. Procedure VertLine (X1,Y1,Y2:Integer;Color:Byte);
  177. var
  178.   Temp   :  Integer;
  179. begin
  180.   If Y1 > Y2 then begin
  181.     Temp := Y1;
  182.     Y1   := Y2;
  183.     Y2   := Temp;
  184.     end;
  185.   asm
  186.     push es
  187.     mov  ax,ScreenAddr
  188.     mov  es,ax               { Point es to screen segment }
  189.  
  190.     mov  ax,Y1               { Calculate starting video memory location }
  191.     mov  di,ScreenWide
  192.     mul  di                  { Multiply row number by width of screen }
  193.     mov  di,X1
  194.     add  di,ax               { Add to that result the X value }
  195.                              { Result: es:di -> first pixel to draw }
  196.     mov  cx,Y2
  197.     sub  cx,Y1
  198.     inc  cx                  { cx = number of pixels to draw }
  199.  
  200.     mov  al,Color            { put the color in al }
  201.  
  202. @Loop1:
  203.     mov  es:[di],al
  204.     add  di,ScreenWide
  205.     loop @Loop1
  206.  
  207.     pop  es
  208.     end;
  209. end;
  210.  
  211. Procedure Line (X1,Y1,X2,Y2:Integer;Color:Byte);
  212. var
  213.   I,
  214.   YIncr,
  215.   D,DX,DY,
  216.   AIncr,BIncr :  Integer;
  217.   Ofs         :  Word;
  218. begin                                  { uses Bresenham's algorithm for }
  219.   If X1 = X2 then begin                { drawing a line.  Very fast for }
  220.     VertLine (X1,Y1,Y2,Color);         { little ol' Pascal              }
  221.     Exit;
  222.     end;
  223.   If Y1 = Y2 then begin
  224.     HorzLine (X1,X2,Y2,Color);
  225.     Exit;
  226.     end;
  227.   If X1 > X2 then begin
  228.     D  := X1;
  229.     X1 := X2;
  230.     X2 := D;
  231.     D  := Y1;
  232.     Y1 := Y2;
  233.     Y2 := D;
  234.     end;
  235.   If Y2 > Y1 then YIncr :=  320
  236.              else YIncr := -320;
  237.   DX := X2 - X1;
  238.   DY := Abs (Y2-Y1);
  239.   D := 2 * DY - DX;
  240.   AIncr := 2 * (DY - DX);
  241.   BIncr := 2 * DY;
  242.  
  243.  
  244.   Ofs := Word(Y1) * 320 + Word(X1);
  245.  
  246.   Mem [$A000:Ofs] := Color;
  247.  
  248.   For I := X1 + 1 to X2 do begin
  249.     If D >= 0 then begin
  250.       Inc (Ofs,YIncr);
  251.       Inc (D,AIncr);
  252.       end
  253.     Else Inc (D,BIncr);
  254.     Inc (Ofs);
  255.     Mem [$A000:Ofs] := Color;
  256.     end;
  257. end;
  258.  
  259. Procedure Box (X1,Y1,X2,Y2:Integer;Color:Byte);
  260. var
  261.   Y :  Integer;
  262. begin
  263.   For Y := Y1 to Y2 do
  264.     HorzLine (X1,X2,Y,Color);
  265. end;
  266.  
  267. Procedure ExtractLineASM (BytesWide:Integer;Var Source,Dest:Pointer);
  268. var
  269.   DestSeg,
  270.   DestOfs,
  271.   SourceSeg,
  272.   SourceOfs   :  Word;
  273. begin
  274.   SourceSeg := Seg (Source^);
  275.   SourceOfs := Ofs (Source^);
  276.   DestSeg   := Seg (Dest^);
  277.   DestOfs   := Ofs (Dest^);
  278.  
  279.   asm
  280.     push  ds
  281.     push  si
  282.  
  283.     cld
  284.  
  285.     mov   ax,DestSeg
  286.     mov   es,ax
  287.     mov   di,DestOfs     { es:di -> destination pointer }
  288.     mov   ax,SourceSeg
  289.     mov   ds,ax
  290.     mov   si,SourceOfs   { ds:si -> source buffer }
  291.  
  292.     mov   bx,di
  293.     add   bx,BytesWide   { bx holds position to stop for this row }
  294.     xor   cx,cx
  295.  
  296.   @@GetNextByte:
  297.     cmp   bx,di          { are we done with the line }
  298.     jbe   @@ExitHere
  299.  
  300.     lodsb                { al contains next byte }
  301.  
  302.     mov   ah,al
  303.     and   ah,0C0h
  304.     cmp   ah,0C0h
  305.  
  306.     jne    @@SingleByte
  307.                          { must be a run of bytes }
  308.     mov   cl,al
  309.     and   cl,3Fh
  310.     lodsb
  311.     rep   stosb
  312.     jmp   @@GetNextByte
  313.  
  314.   @@SingleByte:
  315.     stosb
  316.     jmp   @@GetNextByte
  317.  
  318.   @@ExitHere:
  319.     mov   SourceSeg,ds
  320.     mov   SourceOfs,si
  321.     mov   DestSeg,es
  322.     mov   DestOfs,di
  323.  
  324.     pop   si
  325.     pop   ds
  326.   end;
  327.  
  328.   Source := Ptr (SourceSeg,SourceOfs);
  329.   Dest   := Ptr (DestSeg,DestOfs);
  330. end;
  331.  
  332. Procedure DisplayPCX (X,Y:Integer;Buf:Pointer);
  333. var
  334.   I,NumRows,
  335.   BytesWide   :  Integer;
  336.   Header      :  PCXHeaderPtr;
  337.   DestPtr     :  Pointer;
  338.   Offset      :  Word;
  339. begin
  340.   Header    := Ptr (Seg(Buf^),Ofs(Buf^));
  341.   Buf       := Ptr (Seg(Buf^),Ofs(Buf^)+128);
  342.   Offset    := Y * 320 + X;
  343.   NumRows   := Header^.YMax - Header^.YMin + 1;
  344.   BytesWide := Header^.XMax - Header^.XMin + 1;
  345.   If Odd (BytesWide) then Inc (BytesWide);
  346.  
  347.   For I := 1 to NumRows do begin
  348.     DestPtr := Ptr ($A000,Offset);
  349.     ExtractLineASM (BytesWide,Buf,DestPtr);
  350.     Inc (Offset,320);
  351.     end;
  352. end;
  353.  
  354. Function ImageSize (X1,Y1,X2,Y2:Integer) : Word;
  355. begin
  356.   ImageSize := Word(Y2 - Y1 + 1) * Word(X2 - X1 + 1) + 4;
  357. end;
  358.  
  359. Procedure GetImagePas (X1,Y1,X2,Y2:Integer;P:Pointer);
  360. var
  361.   I           :  Integer;
  362.   Count,
  363.   ScnPos,
  364.   Wide,High   :  Word;
  365.   Buf         :  NewPointer absolute P;
  366. begin
  367.   Wide   := (X2 - X1) + 1;
  368.   High   := (Y2 - Y1) + 1;
  369.   ScnPos := (Y1 * 320) + X1;
  370.   Count  := 4;
  371.  
  372.   Move (Wide,Buf^[0],SizeOf(Wide));
  373.   Move (High,Buf^[2],SizeOf(High));
  374.  
  375.   For I := Y1 to Y2 do begin
  376.     Move (Mem[$A000:ScnPos],Buf^[Count],Wide);
  377.     Inc (ScnPos,ScreenWide);
  378.     Inc ( Count,Wide);
  379.     end;
  380. end;
  381.  
  382. Procedure PutImagePas (X1,Y1:Integer;P:Pointer);
  383. var
  384.   I           :  Integer;
  385.   Count,
  386.   ScnPos,
  387.   Wide,High   :  Word;
  388.   Buf         :  NewPointer absolute P;
  389. begin
  390.   ScnPos := (Word(Y1) * 320) + Word(X1);
  391.   Count  := 4;
  392.  
  393.   Move (Buf^[0],Wide,SizeOf(Wide));
  394.   Move (Buf^[2],High,SizeOf(High));
  395.  
  396.   For I := 1 to High do begin
  397.     Move (Buf^[Count],Mem[$A000:ScnPos],Wide);
  398.     Inc (ScnPos,ScreenWide);
  399.     Inc ( Count,Wide);
  400.     end;
  401. end;
  402.  
  403. Procedure GetImageAsm (X1,Y1,X2,Y2:Integer;P:Pointer); assembler;
  404. asm
  405.     mov  bx,ScreenWide
  406.     push ds
  407.     les  di,P
  408.  
  409.     mov  ax,0A000h
  410.     mov  ds,ax
  411.     mov  ax,Y1
  412.     mov  dx,320
  413.     mul  dx
  414.     add  ax,X1
  415.     mov  si,ax
  416.  
  417.     cld
  418.  
  419.     mov  ax,X2
  420.     sub  ax,X1
  421.     inc  ax
  422.     mov  dx,ax
  423.     stosw
  424.  
  425.     mov  ax,Y2
  426.     sub  ax,Y1
  427.     inc  ax
  428.     stosw
  429.     mov  cx,ax
  430.  
  431.   @@1:
  432.     mov  cx,dx
  433.  
  434.     shr  cx,1
  435.     rep  movsw
  436.  
  437.     test dx,1
  438.     jz   @@2
  439.     movsb
  440.   @@2:
  441.     add  si,bx
  442.     sub  si,dx
  443.  
  444.     dec  ax
  445.     jnz  @@1
  446.  
  447.     pop  ds
  448. end;
  449.  
  450. Procedure PutImageAsm (X1,Y1:Integer;P:Pointer); assembler;
  451. asm
  452.     mov  bx,ScreenWide
  453.     push ds
  454.     lds  si,P
  455.  
  456.     mov  ax,0A000h
  457.     mov  es,ax
  458.     mov  ax,Y1
  459.     mov  dx,320
  460.     mul  dx
  461.     add  ax,X1
  462.     mov  di,ax
  463.  
  464.     cld
  465.  
  466.     lodsw
  467.     mov  dx,ax
  468.  
  469.     lodsw
  470.  
  471.   @@1:
  472.     mov  cx,dx
  473.  
  474.     shr  cx,1
  475.     rep  movsw
  476.  
  477.     test dx,1
  478.     jz   @@2
  479.     movsb
  480.   @@2:
  481.     add  di,bx
  482.     sub  di,dx
  483.  
  484.     dec  ax
  485.     jnz  @@1
  486.  
  487.     pop  ds
  488. end;
  489.  
  490.  
  491. Begin
  492. End.
  493.