home *** CD-ROM | disk | FTP | other *** search
- PROGRAM IFF;
-
- { Lade - und Anzeigeprogramm für ILBM-Bilder
- Jens "Himpelsoft" Gelhar 1989/90
-
- Dieses Programm kennen Sie vielleicht schon als Demo der frühen Versionen
- von KICK-Pascal. Es ist aber inzwischen stark verbessert worden. Zum
- einen konnte die Ladegeschwindigkeit auf ein recht gutes Niveau
- gesteigert werden, so daß man das lauffähige Programm wirklich sinnvoll
- benutzen kann. Außerdem kann man es jetzt auch direkt von der Workbench
- starten, indem man es entweder als "Default Tool" im Icon eines Bildes
- einträgt oder zuerst das Bild-Icon und dann mit "geSHIFTetem" Doppelklick
- ein Exe-File von "IFF.p" startet.
- Beim Start aus dem CLI kann man jetzt den Dateinamen als Parameter
- angeben, etwa
-
- Iff Bild
-
- Es gibt eine ganze Menge Optionen, die beim Start aus dem CLI gewählt
- werden können, indem man ihre Kennbuchstaben mit einem vorangestellten
- "-" in beliebiger Reihenfolge vor oder hinter dem Dateinamen angibt,
- etwa:
-
- IFF Bild -n -t
-
- Die Optionen kann man auch beim Workbench-Start benutzen, indem man
- im Icon des Bildes als "Tool Type" ein bestimmtes Wort schreibt.
- Hier ist eine Liste aller Optionen:
- -n Das Bild wird auf keinen Fall im Interlace-Modus dargestellt (ist
- besser für die Augen). Als Tool Type ist "NoInter" oder "NoLace"
- zu wählen.
- -i Das Bild WIRD im Interlace-Modus ausgegeben. Tool Type: "INTER"
- oder "LACE".
- -h erzwingt Hold-And-Modify-Modus. Tool Type: "HAM". Diese Option
- ist weitgehend überflüssig, denn bei Lo-Res-Bildern mit 6 Planes
- wird defaultmäßig der HAM-Mode gewählt.
- -l Option für Lo-Res-Modus (320*256 Punkte). Tool Type: "LoRes".
- -m schaltet auf hohe Auflösung (640 Punkte breit). Tool Type: "HiRes"
- oder "MedRes".
- -x wählt den Extra-Halfbrite-Modus, was aber nur bei Lo-Res-Bildern
- mit 6 Bitplanes geht. Beim Start von der Workbench ist "XHALF"
- als Tool Type anzugeben.
- -t "Talk"-Option: Während des Ladens werden Informationen über das
- Bild und die Bilddaten ausgegeben. Diese Option ist nur beim
- CLI-Start anwählbar.
-
- Das Bild wird so lange angezeigt, bis eine der Tasten Space, Return,
- Enter oder Escape gedrückt wird. Wenn das Bild größer als die
- Bildschirmauflösung ist, z. B. weil ein Hi-Res-Interlace-Bild mit der
- Option "-l" geladen wurde, kann der angezeigte Bildausschnitt mit den
- Cursortasten gescrollt werden.
-
- Die Bilddaten werden in der vorliegenden Version nicht mehr direkt
- auf den Bildschirm geladen, sondern zuerst in einen Puffer abgelegt,
- von wo jeweils der gerade aktuelle Ausschnitt (bei übergroßen Bildern)
- mit Zuhilfenahme des Blitters auf den Screen kopiert wird.
-
- Dieses Programm ist nicht nur ungemein nützlich - welcher Amiganer
- hat nicht im Laufe der Zeit eine mehr oder weniger umfangreiche
- IFF-Bildersammlung angelegt und will sie des öfteren ansehen, ohne
- erst ein Malprogramm o. Ä. zu laden - sondern auch lehrreich: es
- demonstriert folgende immer wiederkehrende Programmieraufgaben:
- - Parameterübernahme vom CLI und der Workbench. Wie Sie sehen können,
- ist es überhaupt nicht schwierig, einen Dateinamen von der Workbench
- zu holen. Man muß nur die Include-Datei "workbench/startup.h"
- einlesen und ein wenig mit Zeigern und Records hantieren.
- - Schnelle Dateihandhabung: Die alte Version von "IFF.p" war allein
- deshalb so lahm, weil die Daten in kleinen Portionen - Byte für
- Byte, teilweise auch Langwortweise - aus der Bilddatei gelesen
- wurden. Dabei macht sich dann bemerkbar, daß das DOS des Amiga nicht
- gerade schnell ist. In der neuen Version legt "IFF.p" einen 10 KByte
- großen Pufferspeicher an, aus dem dann byteweise gelesen werden
- kann, bis er leer ist und neu geladen werden muß.
- - Benutzung des Blitters. Aus einem Pufferspeicher, in den die
- Bilddaten zunächst geladen werden, werden sie mit dem Blitter
- blit(t)zschnell in die Bitmap des Screens kopiert.
- }
-
- { MaxonPascal3-Anpassung: Falk Zühlsdorff (PackMAN) 1994
-
- benutzt: geänderte 'Workbench/startup.h' © by PackMAN
-
- bei Tooltype z.B. HAM=TRUE im Icon angeben... }
-
- {$opt q}
-
- USES Graphics,Intuition,Custom,DOS;
- {$incl "workbench/startup.h","icon.lib",'workbench/Workbench.h'}
-
- CONST
- BufSize = 10000; { Länge des Datei-Buffers }
- ScreenBar = 11; { Höhe Screen-Titelbalken }
- ScreenW = 336; { Breite Lo-Res-Screen }
- ScreenH = 250; { Höhe Lo-Res-Screen ohne Titelbalken}
- MaxPlane = 11; { höchstens 12 Planes }
-
- TYPE
- BitMapHeader = RECORD
- Width, Height: Word;
- dX, dY: Integer;
- Depth, Mask: Byte;
- Kompr, Pad: Boolean;
- transcolor: Word;
- XAspect, YAspect: Byte;
- SWidth, SHeight: integer
- END;
-
- VAR
- Fil: FILE OF BYTE; { IFF-Datei }
- FName: STRING; { Dateiname }
- FilLen, FilPos: Long; { Merker für "FileSize" und "FilePos" }
-
- ScrMode: Word;
- SBreite, SHoehe, Tiefe: integer; { Maße des geöffneten Screens }
- RGB: ARRAY [ 0..63 ] OF RECORD
- R,G,B: Byte
- END;
-
- Ende, FileEnde, ErrorFlag:Boolean;
- Talky, Inter, NonInter, HamMode, XHalf, LoRes, Res640: Boolean;
-
- HeadFlag, BodyFlag, CamgFlag, CmapFlag: Boolean; { Flags: Hunk gelesen ? }
- BMHD: BitMapHeader; { Inhalt des BMHD-Hunks }
-
- BitMaps: ARRAY[0..11] OF Long;
- BytesProZeile: integer;
-
- XOffs, YOffs: integer; { Scroll-Position }
- XStep, YStep: integer; { Scrool-Schrittweite }
-
- MyWindow: p_Window;
- MyScreen: p_Screen;
-
- Msg: p_IntuiMessage; { RAWKEY-Message }
-
-
-
- PROCEDURE ParameterAuswerten;
- { Bei Start von Workbench oder CLI Dateinamen des Bildes ermitteln }
-
- VAR Para: STRING;
- i: integer;
-
- PROCEDURE OverRead;
- BEGIN
- WHILE (Para[i] > chr(0) ) AND (Para[i] <= ' ') DO i:=i+1;
- IF (Para[i]='-') AND (Upcase( Para[ i+1 ] ) IN ['A'..'Z'] ) THEN
- BEGIN
- CASE Upcase( Para[ i+1] ) OF
- 'H': HamMode := true;
- 'I': Inter := true;
- 'L': LoRes := true;
- 'M': Res640 := true;
- 'N': NonInter := true;
- 'T': Talky := true;
- 'X': XHalf := true;
- OTHERWISE
- i := i-2
- END;
- i := i + 2;
- OverRead
- END;
- END;
-
- PROCEDURE StartVonWorkbench; {einige Änderungen © by PackMAN}
- TYPE mytooltype = ^char;
- VAR StMess : p_WBStartup;
- DiskObj : p_DiskObject;
- OldLock : BPTR;
- i, j : integer;
- St : STRING[10];
- toolarray : ^mytooltype;
- BEGIN
- OpenLib(IconBase,'icon.library',0);
- StMess := StartupMessage;
- IF StMess^.sm_NumArgs < 2 THEN
- FName := ''
- ELSE
- WITH StMess^.sm_ArgList^[2] DO
- BEGIN
- { Als Datei wird das Argument Nr. #2 genommen. Falls noch
- mehr Icons aktiviert sing (z. B. durch "Shift-Klick",
- werden diese ignoroert. }
- FName := wa_Name;
- { reiner Name ohne Pfad! Deshalb muss das aktuelle Verzeichnis
- entsprechend gewählt werden: }
- OldLock := CurrentDir( wa_Lock );
- { "ToolTypes" holen }
- DiskObj := GetDiskObject( FName ); { Icon laden }
- IF DiskObj<>NIL THEN
- BEGIN
- toolarray:=DiskObj^.do_ToolTypes;
- St:=FindToolType(toolarray,'HAM');
- IF St='true' THEN HamMode:=true;
- St:=FindToolType(toolarray,'NOLACE');
- IF St='true' THEN NonInter:=true;
- St:=FindToolType(toolarray,'NOINTER');
- IF St='true' THEN NonInter:=true;
- St:=FindToolType(toolarray,'LACE');
- IF St='true' THEN Inter:=true;
- St:=FindToolType(toolarray,'INTER');
- IF St='true' THEN Inter:=true;
- St:=FindToolType(toolarray,'HIRES');
- IF St='true' THEN Res640:=true;
- St:=FindToolType(toolarray,'MEDRES');
- IF St='true' THEN res640:=true;
- St:=FindToolType(toolarray,'LORES');
- IF St='true' THEN LoRes:=true;
-
- FreeDiskObject( DiskObj );
- END;
- END;
- CloseLib(IconBase);
- END;
-
- BEGIN
- Talky := false; { Defaultwerte für }
- Inter := false; { Optionen }
- NonInter := false;
- HamMode := false;
- LoRes := false;
- Res640 := false;
- XHalf := false;
- IF FromWB THEN
- StartVonWorkbench
- ELSE { Start vom CLI }
- BEGIN
- FName := '';
- IF ParameterLen < 80 THEN
- BEGIN
- Para := ParameterStr;
- Para[ ParameterLen+1 ] := chr(0);
- i := 1;
- OverRead;
- IF Para[i] IN [chr(0),'?'] THEN
- BEGIN { Kein Parameter angegeben }
- writeln(#27'[33mIFF'#27'[31m - Laden und Anzeigen von IFF-Bildern');
- writeln('Geschrieben von '#27'[33mJens Gelhar'#27'[31m 1990 mit '#27'[33mKICK-Pascal'#27'[31m.');
- write ('<Dateiname> [-h] [-i] [-l] [-m] [-n] [-t] [-x] : ' );
- readln( Para );
- i := 1;
- OverRead
- END;
- WHILE Para[i] > ' ' DO
- BEGIN
- FName := FName+Para[i];
- i := i+1
- END;
- OverRead;
- IF Para[i] <> chr(0) THEN Error( 'Falscher Parameter!' )
- END
- END;
- END;
-
-
-
- PROCEDURE DateiOeffnen;
- BEGIN
- Reset ( Fil, FName );
- IF IOResult<>0 THEN
- Error('Datei konnte nicht geöffnet werden.');
- Buffer ( Fil, BufSize );
- FilLen := FileSize( Fil );
- FilPos := 0;
- ErrorFlag := false;
- FileEnde := false;
- END;
-
-
-
- PROCEDURE CloseAll;
- { Datei, Screen usw. Schließen }
- VAR i: integer;
- BEGIN
- Close( Fil );
- FOR i:=0 TO MaxPlane DO
- IF BitMaps[i]<>0 THEN
- Free_Mem( BitMaps[i], BytesProZeile*BMHD.Height );
- IF MyWindow<>NIL THEN
- Close_Window( MyWindow );
- IF MyScreen<>NIL THEN
- Close_Screen( MyScreen );
- IF NOT FromWB THEN Writeln;
- END;
-
-
- PROCEDURE LoadILBM;
- VAR Hunkname: STRING[5];
- LongWord: Long;
- i, Zeile, Plane, Count: integer;
- IntText: IntuiText;
- CamgWord: Word;
- FormLen: Long;
- HunkEnd: Long;
-
-
- PROCEDURE FileError;
- BEGIN
- IF NOT ErrorFlag THEN
- BEGIN
- Writeln('File Error!');
- ErrorFlag:=true;
- FileEnde := true
- END
- END;
-
-
- PROCEDURE Lies ( p: Ptr; L: Long);
- { "L" Bytes nach Adresse "p" laden }
- VAR p2: ^ARRAY[1..MaxLong] OF BYTE;
- i : Long;
- BEGIN
- p2 := p;
- IF ErrorFlag THEN
- { Fehler bereits aufgetreten => alles mit Nullen füllen }
- BEGIN
- FOR i:=1 TO L DO p2^[i]:=0;
- END
- ELSE
- BEGIN
- BlockRead(Fil, p2^, L);
- FileEnde := EoF(Fil);
- ErrorFlag := IoResult<>0
- END;
- END;
-
-
- PROCEDURE OverRead (L:Long);
- { "L" Bytes überlesen }
- VAR buf:String[50];
- BEGIN
- WHILE (L>50) and not ErrorFlag Do
- BEGIN
- Lies(^buf,50);
- L:=L-50;
- END;
- Lies(^Buf,L mod 50)
- END;
-
-
- PROCEDURE ReadHunkName;
- BEGIN
- Hunkname[5]:=chr(0);
- Lies(^Hunkname,4)
- END;
-
-
- PROCEDURE ReadLong;
- BEGIN
- Lies(^Longword,4);
- END;
-
-
- PROCEDURE LiesZeile(Adr:Long);
- Var Size: integer;
- i,j: integer;
- Head: Short;
- Body: Byte;
- Zeile: ^ARRAY[0..MaxInt] OF Byte;
- BEGIN
- IF Not ErrorFlag THEN
- BEGIN
- Zeile := Ptr(Adr);
- Size := ((BMHD.Width + 15) SHR 3) AND $FFE;
- IF not BMHD.Kompr THEN
- Lies(Ptr(Adr),Size)
- ELSE
- BEGIN
- i:=0;
- WHILE (i < Size) and not ErrorFlag Do
- BEGIN
- Lies( ^Head, 1 );
- IF Head >= 0 THEN
- BEGIN
- Lies(Ptr(Adr+i),Head+1);
- i:=i+Head+1
- END
- ELSE
- IF Head <> -128 THEN
- BEGIN
- Lies( ^Body, 1 );
- FOR j := i TO i-Head DO Zeile^[j] := Body;
- i := 1 + i - Head;
- END
- END
- END;
- END
- END;
-
- PROCEDURE Hunk_BMHD;
- BEGIN
- IF HeadFlag THEN FileError;
-
- Lies( ^BMHD, SizeOf(BitMapHeader) );
- OverRead( LongWord-SizeOf(BitMapHeader) );
-
- WITH BMHD DO
- BEGIN
- IF Talky THEN
- BEGIN
- Writeln('Breite: ',Width);
- Writeln('Höhe: ',Height);
- Writeln('Tiefe: ',Depth);
- Writeln('Screen: ',SWidth,'*',SHeight);
- Writeln('Maske: ',Mask);
- IF Kompr THEN
- Writeln('Komprimiert')
- END;
-
- SBreite := ScreenW;
- SHoehe := ScreenH;
- ScrMode:=GENLOCK_VIDEO;
- Tiefe := Depth;
-
- { Grafikmodus und Auflösung ermitteln: }
-
- IF SHeight > ScreenH THEN { Interlace erforderlich }
- BEGIN
- ScrMode := ScrMode+LACE;
- SHoehe := 2*SHoehe
- END;
-
- IF SWidth>ScreenW THEN
- BEGIN
- ScrMode := ScrMode+HIRES;
- SBreite := 2*SBreite
- END;
-
- IF (SBreite=ScreenW) AND (Tiefe=6) THEN
- ScrMode := ScrMode+HAM;
- { Bei 6 Planes Lo-Res wird HAM vermutet. }
-
- BytesProZeile := ((Width+15) AND $fff0) SHR 3;
- FOR i:=0 TO Depth-1 DO
- Bitmaps[i] :=
- Alloc_Mem( BytesProZeile*Height, 2);
- END;
- HeadFlag := true;
- END;
-
-
- PROCEDURE Hunk_CMAP;
- VAR i: integer;
- BEGIN
- Cmapflag := true;
- FOR i:=0 TO LongWord DIV 3-1 DO
- Lies( ^RGB[i AND $3f], 3 );
- END;
-
-
- PROCEDURE Hunk_BODY;
- BEGIN
- IF Bodyflag OR NOT HeadFlag THEN FileError;
-
- FOR Zeile := 0 TO BMHD.Height-1 DO
- FOR Plane := 0 TO BMHD.Depth-1 DO
- LiesZeile( Bitmaps[Plane] + Zeile*BytesProZeile );
- BodyFlag := true
- END;
-
-
- PROCEDURE Hunk_CAMG;
- VAR i: integer;
- PROCEDURE Hexx(n: Word);
- BEGIN
- IF n>15 THEN Hexx(n DIV 16);
- write('0123456789abcdef'.[n AND $f +1]);
- END;
- BEGIN
- CamgFlag := true;
- FOR i:=1 TO (LongWord+1) DIV 2 DO
- BEGIN
- Lies(^CamgWord,2);
- END;
- IF Talky THEN
- BEGIN
- write(' Viewmode: '); Hexx(CamgWord); writeln;
- END;
- END;
-
- BEGIN { Proc LoadILBM }
- HeadFlag := false;
- Bodyflag := false;
- CamgFlag := false;
- CmapFlag := false;
-
- FOR i:=0 TO MaxPlane DO Bitmaps[i] := 0;
-
- ReadHunkName;
- IF HunkName<>'FORM' THEN
- BEGIN
- CloseAll;
- Error('Kein IFF-Format.')
- END;
- IF NOT FromWB THEN
- Write('Loading ',FName,'...');
- IF Talky THEN Writeln;
-
- ReadLong;
- FormLen := LongWord;
-
- ReadHunkName;
- IF HunkName<>'ILBM' THEN
- BEGIN
- CloseAll;
- Error('Kein ILBM-File.')
- END;
-
- WHILE FilePos(Fil)+12 < FileSize(Fil) DO
- BEGIN
- ReadHunkName;
- ReadLong;
- IF Talky THEN
- Writeln( HunkName, LongWord:8, ' Bytes' );
-
- { Nur Hunks gerader Länge: }
- LongWord := (LongWord + 1) AND $FFFFFe;
- HunkEnd := FilePos(Fil) + LongWord;
-
- IF HunkName='BMHD' THEN
- Hunk_BMHD
- ELSE
- IF HunkName='CMAP' THEN
- Hunk_CMAP
- ELSE
- IF HunkName='BODY' THEN
- Hunk_BODY
- ELSE
- IF HunkName='CAMG' THEN
- Hunk_CAMG;
-
- IF ( FilePos(Fil) < HunkEnd ) AND ( HunkEnd < FileSize(Fil) ) THEN
- OverRead( HunkEnd-FilePos(Fil) );
-
- END;
-
- IF NOT HeadFlag THEN Exit;
-
- { Grafikmodus, Auflösung und Bildschirmgröße ermitteln }
-
- IF CamgFlag THEN ScrMode:=CamgWord;
-
- IF HAMMode AND (Tiefe=6) THEN
- BEGIN
- SBreite := ScreenW; ScrMode := ScrMode OR HAM
- END;
- IF LoRes THEN
- BEGIN
- SBreite := ScreenW; SHoehe := ScreenH;
- ScrMode := Scrmode AND NOT(HIRES OR LACE)
- END;
- IF Res640 THEN
- BEGIN
- SBreite := 2*ScreenW;
- ScrMode := ScrMode OR HIRES;
- END;
- IF Inter THEN
- BEGIN
- SHoehe := 2*ScreenH; ScrMode := ScrMode OR LACE
- END;
- IF NonInter THEN
- BEGIN
- SHoehe := ScreenH; ScrMode := ScrMode AND NOT LACE
- END;
- IF XHalf AND (Tiefe=6) THEN
- BEGIN
- SBreite := ScreenW;
- ScrMode := ScrMode OR EXTRA_HALFBRITE AND NOT HAM
- END;
-
- IF SHoehe > BMHD.Height THEN SHoehe := BMHD.Height;
- IF SBreite > BMHD.Width THEN SBreite := BMHD.Width;
-
- XOffs := (BMHD.Width-SBreite) DIV 2;
- YOffs := (BMHD.Height-SHoehe) DIV 2;
- XStep := (BMHD.Width DIV 80 + 15) AND $7ff0;
- YStep := BMHD.Height DIV 40;
- END;
-
-
- PROCEDURE OeffneScreen;
- { Nach Ergebnissen von LoadILBM Bildschirm öffnen }
- VAR i : integer;
- MyView : Ptr;
- BEGIN
- MyScreen:=Open_Screen( 0, 0, SBreite, SHoehe+ScreenBar, Tiefe,
- 0, 1, ScrMode, FName);
- MyWindow:=Open_Window( 0, ScreenBar, SBreite, SHoehe, 1,
- RAWKEY,ACTIVATE+BORDERLESS, Nil, MyScreen,
- SBreite, SHoehe, SBreite, SHoehe );
- MyView := ^MyScreen^.ViewPort;
- FOR i:=0 TO 1 SHL Tiefe -1 DO
- WITH RGB[i] DO
- SetRGB4( MyView, i, r div 16, g div 16, b div 16)
- END;
-
-
- PROCEDURE DisplayPicture;
- VAR Plane: integer;
- Wort: Word;
-
- PROCEDURE BlitIt (Von, Nach: Long; x,y,Mod1,Mod2: integer);
- { Anfangsadressen "Von", "Nach", "x" Worte breit, "y" Zeilen,
- Modulowerte in Bytes (!) }
- VAR i, j, k: integer;
- v, n: ^ARRAY[0..MaxInt] OF Word;
- C: Custom ABSOLUTE $dff000;
- BEGIN
- OwnBlitter;
- { Zitat A. Krämer: "OwnBlitter! Hör' mir bloß auf mit Ownblitter!"
- Eigentlich sollte jene Funktion warten, bis der Blitter mit
- seiner vorherigen Operation fertig ist. Macht sie aber nicht
- immer. Deshalb sorgen wir selbst dafür, daß mit dem Erteilen des
- nächsten Auftrags gewartet wird: }
- WHILE C.DMACONR AND $4000 <> 0 DO;
-
- C.BLTAPT := Ptr(Von);
- C.BLTDPT := Ptr(Nach);
- C.BLTAMOD := Mod1;
- C.BLTDMOD := Mod2;
- C.BLTCON0 := %0000100111110000;
- C.BLTCON1 := 0;
- C.BLTAFWM := $ffff;
- C.BLTALWM := $ffff;
- C.BLTSIZE := (y AND $3FF) SHL 6 + (x AND $3F);
- DisownBlitter
- END;
-
- BEGIN
- Wort := (SBreite+15) shr 4;
- WITH MyScreen^.Bitmap DO
- FOR Plane:=0 TO BMHD.Depth-1 DO
- BlitIt ( BitMaps[Plane] + 2*(XOffs SHR 4) + YOffs*BytesProZeile,
- Long( Planes[Plane] ) + ScreenBar*BytesPerRow,
- Wort,
- SHoehe,
- BytesProZeile- 2 * Wort,
- (BytesPerRow+1)AND $FFE - 2*Wort );
- END;
-
-
-
- BEGIN
- MyScreen := NIL;
- MyWindow := NIL;
-
- ParameterAuswerten;
- IF FName='' THEN Exit;
- DateiOeffnen;
- LoadILBM;
-
- IF NOT (HeadFlag AND Bodyflag) THEN Exit; { Kein Bild geladen!! }
- OeffneScreen;
- DisplayPicture;
-
- Ende := false;
- REPEAT
- Msg := Wait_Port(MyWindow^.UserPort);
- Msg := Get_Msg(MyWindow^.UserPort);
- CASE Msg^.Code OF
- $4c: BEGIN
- IF YOffs >= YStep THEN YOffs := YOffs-YStep
- ELSE YOffs := 0;
- DisplayPicture
- END;
- $4d: BEGIN
- IF YOffs+YStep+SHoehe <= BMHD.Height THEN
- YOffs := YOffs+YStep
- ELSE YOffs := BMHD.Height-SHoehe;
- DisplayPicture
- END;
- $4e: BEGIN
- IF XOffs+XStep+SBreite <= BMHD.Width THEN
- XOffs := XOffs+XStep
- ELSE XOffs := BMHD.Width-SBreite;
- DisplayPicture
- END;
- $4f: BEGIN
- IF XOffs >= XStep THEN XOffs := XOffs-XStep
- ELSE XOffs := 0;
- DisplayPicture
- END;
- $40, $43, $44, $45: Ende := true;
- OTHERWISE
- { andere Taste }
- END;
-
- REPEAT { Nachlaufen vermeiden! }
- Msg := Get_Msg(MyWindow^.UserPort)
- UNTIL Msg=NIL;
-
- UNTIL Ende;
- CloseAll
- END.
-
-