[Back to EGAVGA SWAG index] [Back to Main SWAG index] [Original]

    { ---RLTGA.PAS--- The Run-Length Encoded Targa (type 9) viewer for DOS ---}
    { ===Coded by Patrick O'Malley===                                         }
    { ---Is this OK for SWAG?---                                              }
    { ===Please mention me if you use this proggy in one of your proggys===   }
    { ---Sorry about the lack of comments. I did add _some_ tho ;)---         }
    { ---My InterNet E-Mail address is: d005530c@dcfreenet.seflin.lib.fl.us---}

    { Just a small note about the strange stuff at the end of the proggy:
      That virtual screen that is written to is used to flip the TGA around.
      These TGAs are encoded bottom-up. Since I can't read the file from
      bottom up, I must flip the file around after it has been read. }

    {$X+}
    Program Read_Encoded_TGA;
    Uses Crt;
    Type TGAHeader = record
                       IDFieldLength : Byte;
                       ColorMapType : Byte;
                       ImageType : Byte;
                       CMapOrigin : Integer;
                       CMapLength : Integer;
                       CMapSize : Byte;
                       XOrigin : Integer;
                       YOrigin : Integer;
                       Width : Integer;
                       Height : Integer;
                       ImagePixSize : Byte;
                       ImageDescriptor : Byte;
                     end;
         ImageIDFieldType = Array[1..256] of byte;

    Const VGA = $A000;

    Var Header : TGAHeader;
        ImageIDField : ImageIDFieldType;
        TGA : File;
        TGAName : String;
        VGAScreen : Pointer;
        VGASeg : Word;
        Pal : Array[0..255,0..2] of byte;
        Counter,Count : Word;
        Temp : Byte;
        PixelCount : Word;
        Rep : Byte;
        NewByte : Byte;
        MaxPix : Word;

    Procedure SetColor(Col, R, G, B : Byte);
    Begin
       Asm
          mov   dx, 3c8h
          mov   al, [Col]
          out   dx, al
          inc   dx
          mov   al, [R]
          out   dx, al
          mov   al, [G]
          out   dx, al
          mov   al, [B]
          out   dx, al
       End;
    End; {SetColor}

    Procedure SetMcga;
    Begin
       Asm
          mov   ax, 0013h
          int   10h
       End;
    End;  {SetMCGA}

    Procedure SetText;
    Begin
       Asm
          mov   ax, 0003h
          int   10h
       End;
    End; {SetText}

    Procedure Error(Str : String);
    Begin
      writeln(Str);
      Halt(1);
    End;

    Begin
      TGAName := Paramstr(1);
      If TGAName = '' then Error('Enter filename on Command Line.');
      {$I-}
      Assign(TGA,TGAName);
      Reset(TGA,1);
      IF IOResult <> 0 then Error('File not found!');
      {$I+}
      BlockRead(TGA,Header,SizeOf(Header));
      {This next part checks for an image ID field (header.IDFieldLength > 0)
       then, if one is found, reads it into ImageIDField. Should be less than
       256 bytes (let's hope). It is usually omitted (header.IDFieldLength=0).}
      If Header.IDFieldLength > 0 then
        BlockRead(TGA,ImageIDField,Header.IDFieldLength);
      {Make sure that it is an encoded type 9 TGA}
      If Header.ImageType <> 9 then Begin
        Close(TGA);
        Error('Not a color-mapped type-9 Targa!');
      End;
      SetMCGA;
      {Read colors}
      For Counter := 0 to Header.CMapLength-1 do
        For Count := 0 to 2 do Begin
          BlockRead(TGA,Temp,1);
          Pal[Counter,Count] := Temp shr 2;
        End;
      {Set colors}
      For Counter := 0 to 255 do
        SetColor(Counter,Pal[Counter,2],Pal[Counter,1],Pal[Counter,0]);
      {Read image stuff!}
      MaxPix := (Header.Height*Header.Width);
      PixelCount := 0;
      GetMem(VGAScreen,64000);
      VGASeg := Seg(VGAScreen^);
      FillChar(Mem[VGASeg:0],64000,0);
      Repeat
        BlockRead(TGA,Temp,1);
        If Temp shr 7 = 1 then begin
          BlockRead(TGA,NewByte,1);
          Rep := Temp AND 127;
          For Count := 1 to rep+1 do begin
            Mem[VGASeg:PixelCount] := NewByte;
            Inc(PixelCount);
          End;
        end
        else
        Begin
          Rep := Temp AND 127;
          For Count := 1 to Rep+1 do Begin
            BlockRead(TGA,NewByte,1);
            Mem[VGASeg:PixelCount] := NewByte;
            Inc(PixelCount);
          End;
        End;
      Until PixelCount = MaxPix;
      {Flip the screen onto the display}
      For Count := 0 to Header.Width-1 do  {x}
        For Counter := 0 to Header.Height-1 do {y}
          Mem[VGA:Counter*320+Count] :=
    Mem[VGASeg:((Header.Height-1)-Counter)*Header.Width+Count];  Readkey;
      Close(TGA);
      Freemem(VGAScreen,64000);
      SetText;
    End.

[Back to EGAVGA SWAG index] [Back to Main SWAG index] [Original]