(*---------------------------------------------------------------------------
  :Program.    IFFSupport.def
  :Author.     Fridtjof Siebert
  :Address.    Nobileweg 67, D-7000-Stuttgart-40
  :Phone.      (0)711/822509
  :Shortcut.   [fbs]
  :Version.    1.5
  :Copyright.  Shareware or PD, anyway you like. (I like Shareware better)
  :Language.   Modula-II
  :Translator. M2Amiga v3.2
  :Imports.    LoadBody.asm [fbs]
  :History.    V1.1 [fbs] 27-Jul-88  First published Version
  :History.    V1.2 [fbs] 16-Nov-88: Removed error with NIL-RectanglePtr
  :History.    V1.3 [fbs] 28-Dec-88: Some small changes, inspired by S. Salewski
  :History.    V1.4 [fbs] 23-Mar-89: Removed bug with ExtraHB-Pictures
  :History.    V1.5 [fbs] 03-Jun-89: v3.2, removed Add/RemIntServer()-Bug (3.2)
  :Contents.   PROCEDUREs für IFF-Bilder (Load, Save, ColorCycling).
  :Remark.     Let's wave! The Cure. The Mission. Sisters of Mercy !!!
  :Remark.     Wer am 20 Mai nicht in Konstanz war tut mir Leid!!!
---------------------------------------------------------------------------*)

DEFINITION MODULE IFFSupport;

FROM Intuition IMPORT ScreenPtr, NewScreen, WindowPtr, NewWindow;
FROM Graphics  IMPORT BitMapPtr, RastPortPtr, ViewPortPtr, RectanglePtr;
FROM Exec      IMPORT UByte;

(*---------------------------  Types:  ------------------------------------*)

TYPE
  IFFTitles = (BMHD,CMAP,GRAB,DEST,CAMG,CRNG,BODY,SPRT,CCRT,CMHD,DPPV);
  IFFTitleSet = SET OF IFFTitles;
(* SPRT,CCRT,CMHD,DPPV not implemented !!!                                 *)

  ViewTypes = (vt0,Ersy,Lace,LPen,vt4,vt5,vt6,Extra,Gaud,Color,DblPF,HoMod,
               vt12,vt13,vt14,Hires,v16);
  ViewTypeSet = SET OF ViewTypes;
(* which ViewModes are selected *)

TYPE

(*-------------  The Structure that keeps all the data:  ------------------*)
(* You don't have to understand all variables in this structure! Only some *)
(* are important, like BMHD.width/height or CMAP.red[] etc. The other data *)
(* is used by the Routines that are exported from this module,like DoCycle *)
(* etc.                                                                    *)

  IFFInfoTypePtr = POINTER TO IFFInfoType;
  IFFInfoType = RECORD
  (* This contains all Data needed for a Picture *)

(*------  Which Data is availble:  ------*)
    IFFTitle: IFFTitleSet;     (* all Sub-Records, whose equally named Flag*)
(* is set here, contain readable data                                      *)

(*------  Information on BitMap:  ------*)
    BMHD: RECORD

      width,height: INTEGER;   (* the Picture's Size                       *)
      depth: UByte;            (* it's Depth (how many BitPlanes)          *)
      left,top: INTEGER;       (* it's Location                            *)
      masking: UByte;          (* Masking (see Documentation)              *)
      transCol: INTEGER;       (* Transparent Color                        *)
      xAspect,yAspect: UByte;  (* Verzerrung                               *)
      scrnWidth,scrnHeight: INTEGER; (* The Image's Screen's Size          *)
    END;

(*------  Information on Colors:  ------*)
    CMAP: RECORD

      colorCnt: CARDINAL;      (* Number of Colors used                    *)
      red,green,blue:   ARRAY[0..63] OF UByte;
       (* the Colors (I hope for 6 Bitplanes to be possible anytime)       *)
    END;

(*------  Information on HotSpot:  ------*)
    GRAB: RECORD

      hotX,hotY: INTEGER;      (* Hot-Spot of this Image (if exists        *)
    END;

(*------  Information on Destination-Bitmap:  ------*)
    DEST: RECORD
      depth: UByte;            (* number of Planes                         *)
      planePick: CARDINAL;
      planeOnOff: CARDINAL;    (* set or clear other Planes ?              *)
      planeMask: CARDINAL;     (* planes to be changed                     *)
    END;

(*------  Information on any Special ViewMode:  ------*)
    CAMG: RECORD
      viewType: ViewTypeSet;   (* ViewMode                                 *)
    END;

(*------  Information on ColorCycling:  ------*)
    CRNG: RECORD
      count: CARDINAL;         (* Number of ColorCyclings                  *)
      data: ARRAY[0..15] OF RECORD

        rate: INTEGER;         (* velocity, 800H is 60 per second          *)
        on: BOOLEAN;           (* decide, wether CRNG is active or not     *)
        forward: BOOLEAN;      (* Direction (DPaint)                       *)
        low,high: UByte;       (* lower and upper Color of this Range      *)
      END;
    END;
(*------  Internal Information:  ------*)
    Internal: RECORD
      CycleID: CARDINAL;       (* that's to distinguish different cyclings *)
    END;
  END;

(* That's been quite a complex Variable. If you wanna use it, do it this   *)
(* way:                                                                    *)
(* e.g. You wanna know, how Deep your Image is. Ça marche comme ça:        *)
(* MyDepth := IFFInfo.BMHD.depth;                                          *)
(* You can get the speed of the second Colorcycle this way:                *)
(* speed := IFFInfo.CRNG.data[2].rate;                                     *)

(*--------------  That's the Variable, that contains all Data  ------------*)
(* this should be imported to your Module to get the Data. Don't forget to *)
(* save the data, e.g. to a variable of the same type. Everytime you load  *)
(* a new IFF-File, the data is scratched !!! (i.e. the new data is written *)
(* into this structure.)                                                   *)

VAR
  IFFInfo: IFFInfoType;

(*--------------------  The NewScreen-Structure.  -------------------------*)
(* this can be used to open the Screen, if dontopen is specified           *)

VAR
  NuScreen: NewScreen;

(*--------------------  The NewWindow-Structure.  -------------------------*)
(* this can be used to open the Window later. Don't forget to put Screen-  *)
(* Ptr in NuWindow.screen !!!                                              *)

VAR
  NuWindow: NewWindow;

(*------------------------   Error-Message:  -----------------------------*)
(* IFFError contains Error-Number if ReadILBM or WriteILBM failed.        *)

TYPE
  IFFErrors = (iffNoErr,iffOutofMem,iffOpenScreenfailed,iffOpenWindowfailed,
               iffOpenfailed,iffWrongIFF,iffReadWritefailed);
VAR
  IFFError: IFFErrors;

(*-------------------------------------------------------------------------*)
(*                                                                         *)
(*                          R e a d  I L B M :                             *)
(*                                                                         *)
(*-------------------------------------------------------------------------*)


TYPE
  ReadILBMFlags = (front,visible,dontopen,window);
  ReadILBMFlagSet = SET OF ReadILBMFlags;

PROCEDURE ReadILBM(name: ARRAY OF CHAR; Flags: ReadILBMFlagSet;
                   VAR Screen: ScreenPtr; VAR Window: WindowPtr): BOOLEAN;

(* ReadILBM() lädt ein IFF-Bild und öffnet das geladene Bild als Screen.   *)
(* Name: The IFF-Filename                                                  *)
(* Flags:                                                                  *)
(*  -front:    decides whether Screen is first or last one while loading   *)
(*  -visible:  decides if display should be turned off (that's faster)     *)
(*  -dontopen: avoids to open the Screen. The Returned value is NIL        *)
(*  -window:   if set, an Window of the same size as the Image is opened.  *)
(*             So, Gadgets etc. can be added to it.                        *)
(* Screen: Pointer to Screen-structure of opened Screen                    *)
(* Window: Pointer to the opened Window or NIL if window isn't set.        *)
(* Result: FALSE if error occured. Then there's no Screen opened.          *)


(*-------------------------------------------------------------------------*)
(*                                                                         *)
(*                         Start Colorcycling:                             *)
(*                                                                         *)
(*-------------------------------------------------------------------------*)

PROCEDURE DoCycle(Info: IFFInfoTypePtr; Screen: ScreenPtr): BOOLEAN;
(* this should create an interrupt, that does cycling. You needn't worry,  *)
(* whether ther's cycling data or not. Don't forget to call EndCycle to    *)
(* remove the Cycling-Interrupt !!!                                        *)
(* if result is false, any error occured. Don't call EndCycle in this case!*)


(*-------------------------------------------------------------------------*)
(*                                                                         *)
(*                         End Colorcycling:                               *)
(*                                                                         *)
(*-------------------------------------------------------------------------*)

PROCEDURE EndCycle(Info: IFFInfoTypePtr);
(* remove cycling-Interrupt                                                *)


(*-------------------------------------------------------------------------*)
(*                                                                         *)
(*              Initialize BMHD, CMAP & CAMG for WriteILBMAll:             *)
(*                                                                         *)
(*-------------------------------------------------------------------------*)

PROCEDURE InitIFFInfo(Info: IFFInfoTypePtr;
                      RP: RastPortPtr;
                      VP: ViewPortPtr;
                      VAR Rect: RectanglePtr);

(* Initialize essential parts of IFFInfoType-Variable.                     *)
(* This can be used to simplify the initialization of an IFFInfoType       *)
(* RP:         RastPort containing the BitMap etc.                         *)
(* VP:         ViewPort containing the Colors, ViewModes etc.              *)
(* Rect:       The Rectangle Region in your RastPort, that should be saved *)
(*             or NIL to save hole RastPort                                *)


(*-------------------------------------------------------------------------*)
(*                                                                         *)
(*                        Save an ILBM-File:                               *)
(*                                                                         *)
(*-------------------------------------------------------------------------*)

PROCEDURE WriteILBMAll(Name: ARRAY OF CHAR;
                       Info: IFFInfoTypePtr;
                       BM: BitMapPtr;
                       FirstLine, LeftOffset: INTEGER;
                       CompressIt: BOOLEAN): BOOLEAN;
(* Saves IFF-File named Name                                               *)
(* This is a very Low-Level Procedure. You should use it to save Pictures  *)
(* with ColorCycling and things like that.                                 *)
(* To save Screens, Windows or so use the other Procedures !               *)
(* Info^.IFFTitle must have set the Flags of all initialized Sub-Records   *)
(* BM:            contains the Graphicdata. In fact BM doesn't have to be  *)
(*                part of a RastPort. It can be used to save a MaskPlane.  *)
(*                Then BM has to contain one extra Plane and BM^.depth and *)
(*                Info^.BMHD.depth have to be increased by 1.              *)
(* FirstLine:     is the TopEdge within BM                                 *)
(* LeftOffset:    is the LeftEdge within BM. Must be a Word-Address,       *)
(*                i.e. 16*n                                                *)
(* an examble to call this can be is the Implementation of WriteILBM()     *)


(*-------------------------------------------------------------------------*)
(*                                                                         *)
(*                 Save a RastPort and ViewPort ILBM-File:                 *)
(*                                                                         *)
(*-------------------------------------------------------------------------*)

PROCEDURE WriteILBM(Name: ARRAY OF CHAR;
                    RP: RastPortPtr;
                    VP: ViewPortPtr;
                    Rect: RectanglePtr;
                    CompressIt: BOOLEAN): BOOLEAN;

(* Creates an ILBM-File                                                    *)
(* Name:       File's Name                                                 *)
(* RP:         RastPort containing the BitMap etc.                         *)
(* VP:         ViewPort containing the Colors, ViewModes etc.              *)
(* Rect:       The Rectangle Region in your RastPort, that should be saved *)
(*             or NIL to save hole RastPort                                *)
(* Compressit: Create compressed ILBM-File or not ?                        *)
(* Result is FALSE if any Error occured.                                   *)
(* example to save a Window:                                               *)
(*      OK := WriteILBM("Test.iff",                                        *)
(*                      MyWindow^.rPort,                                   *)
(*                      ADR(MyWindow^.screen^.viewPort,                    *)
(*                      TRUE);                                             *)


(*-------------------------------------------------------------------------*)
(*                                                                         *)
(*                    Save a Screen as ILBM-File:                          *)
(*                                                                         *)
(*-------------------------------------------------------------------------*)

PROCEDURE WriteILBMScreen(Name: ARRAY OF CHAR;
                          Screen: ScreenPtr;
                          Rect: RectanglePtr;
                          CompressIt: BOOLEAN): BOOLEAN;

(* This creates an ILBM-File from a Screen                                 *)
(* Name:       File's Name                                                 *)
(* Screen:     Screen to be saved                                          *)
(* Rect:       The Rectangle Region in your Screen, that should be saved   *)
(*             or NIL to save hole Screen                                  *)
(* CompressIt: Create a Compressed ILBM-File                               *)
(* Returns TRUE if no Error occured.                                       *)
(* example: OK := WriteILBMScreen("Test.iff",MyScreen,NIL,TRUE);           *)


END IFFSupport.
