Program Effectmod;

{ Dieses Programm ist © by QXC & VWP! Alle Rechte liegen beim Autor!
  Alle Sourcecodes sind nur zur Demonstration und Veranschaulichung des
  WaveTracer-Modulinterfaces gedacht und zu verwenden }

USES Intuition,Graphics,ExecIO;


type BPTR=long;

var DWindow                             :^Window;

var XGadget                             :^Gadget;
var Schieber,Textgad                    :array [1..2] of Gadget;
var SchieberInfo                        :array [1..2] of PropInfo;
var TextInfo                            :array [1..2] of StringInfo;
var SImage                              :array [1..2] of Image;
var Buffer,UndoBuffer                   :array [1..2] of string[20];

var IMsg                                :^IntuiMessage;
var Addr1,RealE1                        :long;
var Data1                               :^long;
var RawCode,GadCode,ChBit,ChID          :byte;
var i                                   :integer;
var l                                   :long;
var Valid                               :boolean;

{$path "WaveTracer/","RAM:include/";incl "WTIncl.mod","ModIncl.mod",
       "EffIncl.mod","Schieber.mod"}

{ WTIncl.mod   - WaveTracer Strukturen
  ModIncl.mod  - Proceduren und Strukturen sowie Variablendefinitionen
                 zum Port-Handling
  EffIncl.mod  - Proceduren für Effektmodule, wie z.B. WRITE oder
                 MAKEBORDER (nicht mitgeliefert, da hier keine umwerfend
                 komplizerte oder innovative Routinen implementiert sind)
  Schieber.mod - Procedure zum einfachen Generieren von Prop-Gadgets }



procedure DOGRAMMOPHON(SAddr :long);

var SwapData                    :boolean;
var NewData                     :long;

begin
   if SAddr=0 then exit;
   SwapData:=false;
   with MyWTStdMsg^ do begin
      Flags:=0;
      WTMsgPrc^:=MsgPrc(WTM_GETABORTINFO,'','','','','',0,0,0,0,0,NIL);
                                { WTM_GETABORTINFO-Abfrage vorbereiten }
      Addr1:=SAddr;
      randomize;
      i:=0;
      repeat
         repeat
            Data1:=ptr(Addr1); Addr1:=Addr1+4;
            NewData:=random(ActWaveOp^.Operator[1]*3); NewData:=NewData*10000;
           if Data1^>0 then Data1^:=Data1^-NewData;
            if Data1^<=0 then Data1^:=Data1^+NewData;
            if ((random(255)=0) and (random(67-ActWaveOp^.Operator[1])=0)) or
             ((random(255)=0) and (abs(Data1^)>600000))
             then if SwapData then SwapData:=false else SwapData:=true;
            if SwapData then Data1^:=Data1^*(-1);
            i:=i+1;
         until (Addr1>=RealE1) or (i>2000);
         i:=0;
         MESSAGEHANDLE;         { alle 2000 Schritte wird WTM_GETABORTINFO auf
                                  gerufen, um abzufragen, ob evtl. die Esc-Taste
                                  gedrückt wurde }
         if WTMsgPrc^.PRC_Long1=-1 then begin
                                { PRC_Long1=-1 -> Operation wurde unterbrochen }
            Valid:=false;
            exit;
         end;
      until Addr1>=RealE1;
   end;
end;



procedure DEFINEGRAMMOPHON;

begin
   with MyWTStdMsg^ do begin
      with ActWaveOp^ do if Operator[1]=-1 then begin
                                { Wenn Operator[1]-1 ist, so wurde das Modul
                                  zum ersten mal aufgerufen. Es sind die nötigen
                                  Voreinstellungen zu tätigen }
         Operator[1]:=10;
         Channels:=UsedChannels;
      end;
      Flags:=0;
      WTMsgPrc^:=MsgPrc(WTM_OPENDWIN,'Definition GRAMMOPHON','','','','',120,0,3,0,0,NIL);
      MESSAGEHANDLE;
                                { Definitionsfenster öffnen: Höhe 120 Punkte
                                  Gadgets: OK/Cancel -> 1
                                           Kanalgadgets -> 2 }
      if (WTMsgPrc^.PRC_Long1=-1) or (WTMsgPrc^.PRC_NewPtr=NIL) then begin
                                { Abbrechen, wenn PRC_Long1=-1 oder
                                  PRC_NewPtr=NIL, da das Fenster nicht geöffnet
                                  werden konnte }
         Flags:=MDE_ERROR;
         exit;
      end;
      DWindow:=WTMsgPrc^.PRC_NewPtr;
                                { Pointer auf Window-Struktur }
      WTMsgPrc^:=MsgPrc(WTM_SETCHANNELGADS,'','','','','',ActiveMode,ActWaveOp^.Channels,0,0,0,NIL);
      MESSAGEHANDLE;
                                { Kanalgadgets im Fenster Selektieren: Soundmode
                                  und voreingestellte Kanäle als Defaultwerte }
      CREATEPROPGAD(10,80,pred(ActWaveOp^.Operator[1])*1331,1331,1,8,DWindow^);
                                { eine "Schieber.mod"-Procedure }
      Buffer[1]:=intstr(ActWaveOp^.Operator[1]);

      WRITE(410,81,2,0,DWindow^,'Rausch- und Knister-Faktor');
      AddGadget(DWindow,^TextGad[1],NIL);
      AddGadget(DWindow,^Schieber[1],NIL);
      RefreshGadgets(DWindow^.FirstGadget,DWindow,NIL);
      repeat

         RawCode:=0; GadCode:=0; Valid:=false;
         l:=wait(-1);
         IMsg:=Get_Msg(DWindow^.UserPort);
         If IMsg<>Nil Then begin
            if IMsg^.class in [GADGETDOWN,GADGETUP] then begin
               XGadget:=IMsg^.IAddress; GadCode:=XGadget^.GadgetID;
            end;
            if IMsg^.class=RAWKEY then RawCode:=IMsg^.Code;
            Reply_Msg(IMsg);
            Valid:=true;
         End;

         if (Gadcode=9) or not (Schieber[1].flags and SELECTED=0) then begin
            ActWaveOp^.Operator[1]:=succ(SchieberInfo[1].HorizPot div 1337);
            Buffer[1]:=intstr(ActWaveOp^.Operator[1]);
            RefreshGadgets(^TextGad[1],DWindow,NIL);
         end;
         if Gadcode=10 then begin
            val(Buffer[1],ActWaveOp^.Operator[1],i);
            if ActWaveOp^.Operator[1]<1 then ActWaveOp^.Operator[1]:=1;
            if ActWaveOp^.Operator[1]>50 then ActWaveOp^.Operator[1]:=50;
            Buffer[1]:=intstr(ActWaveOp^.Operator[1]);
            SchieberInfo[1].HorizPot:=pred(ActWaveOp^.Operator[1])*1337;
            RefreshGadgets(^Schieber[1],DWindow,NIL);
         end;

      Until (GadCode in [1..2]) or (RawCode=68) or (RawCode=69);
      Flags:=0;
      WTMsgPrc^:=MsgPrc(WTM_GETCHANNELGADS,'','','','','',0,0,0,0,0,NIL);
      MESSAGEHANDLE;
      ActWaveOp^.Channels:=WTMsgPrc^.PRC_Long1;
                                { Kanalgadgets auf Selektierung hin abfragen }
      WTMsgPrc^:=MsgPrc(WTM_LEAVEWIN,'','','','','',Rawcode,GadCode,0,0,0,DWindow);
      MESSAGEHANDLE;
                                { Das Fenster wieder schließen; es darf hier nicht
                                  mit CloseWindow geschlossen werden, wenn mit
                                  WTM_OPENDWIN geöffnet wurde! }
      if WTMsgPrc^.PRC_Long1=1 then Flags:=MDE_READY else Flags:=MDE_CANCELLED;
                                { Ergebnis von WTM_LEAVEDEF: 1 - OK-Gadget ge-
                                  drückt -> mit MDE_READY beenden sonst Cancel-
                                  Gadget gedrückt -> mit MDE_CANCELLED beenden }
   end;
end;



begin {*** MAIN ***}
   OpenLib(IntBase,'intuition.library',0);
   OpenLib(GfxBase,'graphics.library',0);
   if CREATEPORTS(PORT_EFFECTMOD) then begin
                                { "ModIncl.mod": Messageport anlegen }
      with MyWTStdMsg^ do if Version=VERSION_EFFECTMOD then begin
         if Flags=MDC_DEFINEIT then DEFINEGRAMMOPHON
                                { Vom WaveTracer kam das Kommando, die nötigen
                                  Einstellungen zu definieren }
         else if Flags=MDC_DOIT then begin
                                { Kommando Operation ausführen }
            Flags:=0;
            WTMsgPrc^:=MsgPrc(WTM_WORKINFO,'Grammophon, '+COPYRIGHT,'','','','',0,0,0,0,0,NIL);
            MESSAGEHANDLE;
                                { Copyright-Info ausgeben und damit Status-
                                  Anzeige zeichnen; Unbedingt notwendig! }
            Valid:=true;
            ChBit:=1;
            for ChID:=1 to 6 do begin
               if Valid and not (ActWaveOp^.Channels and ChBit=0) then begin
                  Flags:=0;
                  WTMsgPrc^:=MsgPrc(WTM_GETMARKADDR,'','','','','',ChID,0,0,0,0,NIL);
                  MESSAGEHANDLE;
                                { WTM_GETMARKADDR liefert die Absoluten Adressen
                                  des markierten Bereiches; Funktion ist zukünftig
                                  durch WTM_GETOFFSET zu ersetzen!! }
                  RealE1:=WTMsgPrc^.PRC_Long3;
                                { Absolute EndAdresse }
                  DOGRAMMOPHON(WTMsgPrc^.PRC_Long1);
                                { Operation mit Absoluter Anfangsadresse ausführen }
               end;
               ChBit:=ChBit*2;
            end;
            Flags:=MDE_READY;
         end;
      end else Flags:=MDE_WRONG_MODULEVERSION;
                                { Moduleversion wurde nicht erkannt! }
      MESSAGEHANDLE;            { Messagehandling in "ModIncl.mod" }
      RemPort(MyPort);          { Port wieder entfernen }
   end;
   CloseLib(GfxBase);
   CloseLib(IntBase);
end.
