home *** CD-ROM | disk | FTP | other *** search
/ HOT Scene Stuff / hotscenestuffzyklop1996.iso / diskmags / deutsch / microcod / stod1 / text / text015.txt < prev    next >
Text File  |  1994-11-03  |  5KB  |  118 lines

  1.  
  2.  
  3.                       PCX-Bilder in Pascal
  4.                       --------------------
  5.  
  6. Nachdem Ihr sicherlich die Theorieabhandlung der PCX-Bilder gele-
  7. sen habt, geht es nun gleich weiter mit der Umsetzung in die
  8. Praxis mit Pascal.
  9.  
  10. Das folgende Programm liest ein 320x200x256-PCX-Bild ein und
  11. bringt es auf den Bildschirm. Eine höhere Auflösung ist zwar auch
  12. machbar, doch ein wenig komplizierter, wenn man kein passenden
  13. BGI-Aufsatz hat. In der nächsten Ausgabe von STOD dürfte wohl
  14. (wenn ich genügend Zeit finde) auch ein wenig zu dem Thema ste-
  15. hen.
  16.  
  17. Nun aber zum Programm. Obwohl es eigentlich nicht nötig ist,
  18. überprüfe ich trotzdem am Anfang des Programms, ob es sich über-
  19. haupt um ein PCX-Bild handelt (erstes Byte muß '0A' sein). Den
  20. Rest des Headers übergehe ich einfach mal. Dann werden 30000
  21. Byte aus der Datei gelesen. Die tatsächliche Anzahl der gelesenen
  22. Bytes werden von der Prozedur 'BlockRead' in 'GeleseneBytes' zu-
  23. rückgeliefert. Der Rest des Programms, das meiner Meinung nach
  24. genügend dokumentiert ist, läßt sich nach dem Schema beschreiben,
  25. das auch schon im allgemein abgefaßten Text steht: Sollte die
  26. Zählvariable 'Index' einen Werte ungleich 0 beinhalten, so wird
  27. das nächste Byte sooft in den Videospeicher geschrieben, wie es
  28. Index vorschreibt. Andernfalls wird das nächste Byte daraufhin
  29. überprüft, ob es ein Zählbyte ist (Byte AND $C0 = $C0). Ist das
  30. der Fall, wird das Byte in Index gespeichert, und es geht wieder
  31. von vorne los. Sollte es nicht so sein, repräsentiert das jetzige
  32. Byte einen einzelnen Pixel und wird in den Videospeicher übertra-
  33. gen. Danach geht's ebenfalls von vorne los.
  34. Zum Schluß der Prozedur wird dann noch die Palette gesetzt, die
  35. sich am Ende der Datei befindet.
  36.  
  37. Die Prozedur:
  38.  
  39. PROCEDURE PCX(PCXFile:STRING);
  40. VAR PCX                        : FILE;
  41.     Daten                      : ^BYTE;
  42.     DatenMem                   : POINTER;
  43.     Pal,ScreenPos,Pos,Index,
  44.     Wiederholung,GeleseneBytes : WORD;
  45. BEGIN
  46.   ASSIGN(PCX,PCXFile);
  47.   {$I-}
  48.    RESET(PCX,1);
  49.    IF IOResult <> 0 THEN Exit;
  50.   {$I+}
  51.   GetMem(Daten,30000);                        {Bytes reservieren}
  52.   DatenMem := Daten;                      {Anfangsadresse merken}
  53.   BlockRead(PCX,Daten^,128,GeleseneBytes);         {Header lesen}
  54.   IF Daten^ <> $0A THEN BEGIN            {PCX-Kennung vorhanden?}
  55.    Close(PCX);                         {Nein: Prozedur verlassen}
  56.    Exit;
  57.   END;
  58.   Index := 0; ScreenPos := 0;
  59.   REPEAT
  60.    BlockRead(PCX,Daten^,30000,GeleseneBytes);       {Bytes lesen}
  61.    Pos := 0;
  62.    WHILE (Pos < GeleseneBytes) AND (ScreenPos <= 64000) DO BEGIN
  63.             {Solange Daten noch übrig sind, und nicht schon alle
  64.                                               Pixel gesetzt sind}
  65.     IF Index > 0 THEN BEGIN                  {Wiederholungsbyte?}
  66.      FOR Wiederholung := 1 TO Index DO BEGIN               {Ja: }
  67.       MEM[$A000:ScreenPos] := Daten^; {Schreibe Farbe sooft, wie
  68.                                                    {Index besagt}
  69.       Inc(ScreenPos);
  70.      END;
  71.      Index := 0;                           {Nein: Index auf null}
  72.     END ELSE IF (Daten^ AND $C0) = $C0 THEN
  73.      Index := Daten^ AND $3F         {Wenn Byte = Zählbyte, dann
  74.                                                    Index := Byte}
  75.     ELSE BEGIN                          {Sonst: }
  76.      MEM[$A000:ScreenPos] := Daten^;   {Schreibe Byte in Video-
  77.                                          speicher - Einzelfarbe}
  78.      Inc(ScreenPos);
  79.     END;
  80.     Inc(Pos); Inc(Daten);
  81.    END;
  82.    Daten := DatenMem;          {Ursprüngliche Adresse herstellen}
  83.   UNTIL GeleseneBytes = 0;
  84.   Seek(PCX,FileSize(PCX)-769);    {Auf 769. Byte vor Ende setzen}
  85.   BlockRead(PCX,Daten^,769);                     {769 Byte lesen}
  86.   IF Daten^ = $0C THEN BEGIN                {Paletten-Erkennung?}
  87.     Inc(Daten);               {Auf Anfang der Farbtabelle setzen}
  88.     FOR Pal := 1 TO 768 DO BEGIN
  89.      Daten^ := Daten^ SHR 2;    {Paletteneinträge durch 4 teilen}
  90.      Inc(Daten);
  91.     END;
  92.     Dec(Daten,768);                    {Wieder auf Anfang setzen}
  93.     ASM
  94.      MOV BX,0
  95.      MOV CX,256
  96.      MOV AX,1012h
  97.      LES DX,Daten
  98.      INT 10h                                  {Palette eintragen}
  99.    END;
  100.   END;
  101.   Daten := DatenMem;     {Daten wieder auf ursprüngliche Adresse
  102.                                                           setzen}
  103.   FreeMem(Daten,30000);               {Speicher wieder freigeben}
  104.   Close (PCX);
  105. END;
  106.  
  107.  
  108.  
  109. Tja, soviel zu dieser Prozedur. Das Listing muß (natürlich!)
  110. nicht abgeschrieben werden, sondern befindet sich in dem Ver-
  111. zeichnis 'SOURCES' im STOD-Pfad. Eine Demo-Prog wird da eventuell
  112. auch noch zu finden sein - schaut Euch mal ein wenig um.
  113.  
  114. Und wie immer: Sollten noch irgendwelche Fragen oder Verbes-
  115. serungsvorschläge vorhanden sein ---> her damit!
  116.  
  117.  
  118.                                                  Kemil