PROGRAM DeskTopCDPlayer;

{********************************************
 **         DESKTOP CD PLAYER 1.3          **
 **                                        **
 **             by D. Amor '92             **
 **                                        **
 **       written in KICK-PASCAL v2.1      **
 ********************************************}

{$opt q}

USES ExecIO,Intuition,Graphics;

CONST CD_RESET    = 1;
      CD_MOTOR    = 9;
      CD_CNUM     =13;
      CD_CSTATE   =14;
      CD_ISROM    =37;
      CD_PLAYTRACK=43;
      CD_TOCMSF   =49;
      CD_SUBQMSF  =51;
      CD_PAUSE    =52;
      CD_STOPPLAY =53;
      CD_FADE     =57;
      nTOC        =100;
      mSing     =40;
      mCD       =10;

TYPE Bord_Type = ARRAY [01..10] OF INTEGER;
     Scro_Type = ARRAY [01..20] OF INTEGER;
     Port_Type = ARRAY [00..01] OF ^MsgPort;
     ioRq_Type = ARRAY [00..01] OF ^IOStdReq;
     Stri_Type = ARRAY [00..05] OF STRING[23];
     Thre_Type = STRING[3];
     Grup_Type = STRING[30];
     Gru2_Type = STRING[23];

VAR BorderDatA              : ARRAY [0..4] OF Bord_Type; STATIC;
    ITxt                    : ARRAY [1..13] OF IntuiText;STATIC;
    BorderA                 : ARRAY [0..7] OF Border;    STATIC;
    GadgetA                 : ARRAY [1..13] OF Gadget;   STATIC;
    cdStatus                : ARRAY [0..50] OF BYTE;     STATIC;
    TOCArray                : ARRAY [0..8*nTOC] OF BYTE; STATIC;
    BaTiSo                  : ARRAY [0..mSing,0..mCD] OF Grup_Type; STATIC;
    SongTitle               : ARRAY [0..20] OF Gru2_Type;STATIC;
    Win                     : ^Window;                   STATIC;
    Rp                      : ^RastPort;                 STATIC;
    ReplyPort               : Port_Type;                 STATIC;
    ioReq                   : ioRq_Type;                 STATIC;
    TAttr0                  : TextAttr;                  STATIC;
    channel,command,max,
    watch,song,display,x,y,
    bandnumber,albumnumber  : BYTE;                      STATIC;
    Fehler1,Fehler2         : LONG;                      STATIC;
    ende,pause,fade,play,
    single,repeet,removed   : BOOLEAN;                   STATIC;
    Msg                     : ^IntuiMessage;             STATIC;
    AktGad                  : ^Gadget;                   STATIC;
    MDat                    : ^Scro_Type;                STATIC;
    MImage1                 : Image;                     STATIC;
    PropInfo1               : PropInfo;                  STATIC;
    GadID                   : WORD;                      STATIC;
    MyText                  : Stri_Type;                 STATIC;
    con                     : PTR;                       STATIC;
    ErrorMessage            : STRING[180];               STATIC;
    singer                  : INTEGER;                   STATIC;

PROCEDURE Print(t: Stri_Type; x,y: BYTE);

VAR it: IntuiText;
    i : BYTE;

BEGIN
  FOR i:=0 TO 5 DO
  BEGIN
    it:=IntuiText(1,0,1,0,0,NIL,t[I],NIL);
    PrintIText(Rp,^it,x,y+i*9);
  END;
END;

PROCEDURE WaitStartUp;

BEGIN
  Removed:=TRUE;
  MyText:=Stri_Type("0 Tracks  ","00:00     ","No Disc   ","","","");
  Print(MyText,88,42);
END;

PROCEDURE CD_Action(command: BYTE; offSet, laenge: LONG; data: PTR;
                    channel: BYTE);

VAR ioError: INTEGER;

BEGIN
  WITH ioReq[channel]^ DO
  BEGIN
    io_Command:=command;
    io_Flags:=0;
    io_Length:=laenge;
    io_Data:=data;
    io_OffSet:=offset;
  END;
  IF command=CD_PLAYTRACK THEN
  BEGIN
    SendIO(ioReq[channel]);
    ioError:=0
  END
  ELSE ioError:=DoIO(ioReq[channel]);
  IF ioError=-6 THEN WaitStartUp;
END;

PROCEDURE Clear(y1,y2: BYTE);

BEGIN
  SetAPen(Win^.RPort,0);
  RectFill(Win^.RPort,88,y1,263,y2);
  SetAPen(Win^.RPort,1);
END;

PROCEDURE ShowBottom;

BEGIN
  MyText:=Stri_Type("","","",SongTitle[song],
                    BaTiSo[bandnumber,albumnumber],
                    BaTiSo[bandnumber,0]);
  Print(MyText,88,42);
END;

PROCEDURE AddNill(VAR mins,secs: Thre_Type; VAR min,sec: BYTE);

BEGIN
  mins:=INTSTR(min);
  secs:=INTSTR(sec);
  IF min<10 THEN mins:="0"+mins;
  IF sec<10 THEN secs:="0"+secs;
END;

PROCEDURE InitText;

BEGIN
  MyText:=Stri_Type("CD-Audio:",
                    "Playtime:",
                    "Status  :",
                    "Title   :",
                    "Album   :",
                    "Group   :");
  Print(MyText,8,42);
END;

PROCEDURE StopText(max,min,sec: BYTE);

VAR mins,secs: STRING[3];

BEGIN
  Clear(42,94);
  AddNill(mins,secs,min,sec);
  MyText:=Stri_Type(INTSTR(max)+" Tracks",mins+":"+secs,"Stop",SongTitle[song],
                    BaTiSo[bandnumber,albumnumber],
                    BaTiSo[bandnumber,0]);
  Print(MyText,88,42);
END;

PROCEDURE StartUp;

BEGIN
  Removed:=FALSE;
  CD_Action(CD_ISROM,0,0,NIL,0);
  CD_Action(CD_TOCMSF,0,nTOC,^TOCArray,0);
  max:=TOCArray[3];
  StopText(max,TOCArray[5],TOCArray[6]);
END;

PROCEDURE ShowAll(VAR min,sec: BYTE; VAR song: BYTE; VAR play: BOOLEAN;
                  scan: BOOLEAN);

VAR tracks,mins,secs: STRING[3];
    StopPlaying     : STRING[15];

BEGIN
  tracks:=INTSTR(song);
  StopPlaying:="Stop       ";
  AddNill(mins,secs,min,sec);
  IF play THEN StopPlaying:="Playing    ";
  IF scan THEN StopPlaying:="Scanning   ";
  MyText:=Stri_Type("Track "+tracks+"  ",mins+":"+secs+" ",StopPlaying,SongTitle[song],
                    BaTiSo[bandnumber,albumnumber],
                    BaTiSo[bandnumber,0]);
  Print(MyText,88,42);
END;

PROCEDURE CheckSec(VAR sec,sec2,min: BYTE);

BEGIN
  sec:=sec-sec2;
  IF sec>59 THEN
  BEGIN
    sec:=sec+60;
    DEC(min);
  END
END;

PROCEDURE GetTime(VAR max,min,sec: BYTE);

VAR song2,min2,sec2: BYTE;

BEGIN
  min2:=TOCArray[(song SHL 3)+5];
  sec2:=TOCArray[(song SHL 3)+6];
  IF song<max THEN song2:=(SUCC(song) SHL 3)+5
              ELSE song2:=5;
  min:=TOCArray[song2];
  sec:=TOCArray[SUCC(song2)];
  min:=min-min2;
  CheckSec(sec,sec2,min);
END;

PROCEDURE ShowTrack(VAR song: BYTE; VAR play: BOOLEAN);

VAR min,sec: BYTE;

BEGIN
  Clear(42,94);
  GetTime(max,min,sec);
  ShowAll(min,sec,song,play,FALSE);
END;

PROCEDURE ShowNothing;

BEGIN
  MyText:=Stri_Type("","No Display","","","","");
  Print(MyText,88,42);
END;

PROCEDURE StartPlayer(VAR play,Single: BOOLEAN; VAR Song: BYTE);

VAR NumberOfSongs: BYTE;

BEGIN
  IF Single THEN NumberOfSongs:=0
            ELSE NumberOfSongs:=SUCC(Max);
  CD_Action(CD_PLAYTRACK,Song,NumberOfSongs,NIL,0);
  play:=TRUE;
  DELAY(10);
END;

PROCEDURE PausePlayer(VAR Pause: BOOLEAN);

BEGIN
  MyText:=Stri_Type("","","Pause     ","","","");
  Print(MyText,88,42);
  IF Pause THEN CD_Action(CD_PAUSE,0,1,NIL,1)
           ELSE CD_Action(CD_PAUSE,0,0,NIL,1);
  Pause:=NOT Pause;
END;

PROCEDURE StopPlayer(VAR play: BOOLEAN);;

VAR a: LONG;

BEGIN
  AbortIO(ioReq[0]);
  a:=WaitIO(ioReq[0]);
  CD_Action(CD_STOPPLAY,0,0,NIL,0);
  play:=FALSE;
END;

PROCEDURE DimOffPlayer(VAR Fade: BOOLEAN);

VAR I: INTEGER;

BEGIN
  IF Fade THEN CD_Action(CD_FADE,0,150,NIL,1)
          ELSE CD_Action(CD_FADE,32767,150,NIL,1);
  Fade:=NOT Fade
END;

PROCEDURE Scroll_Fade(VAR PropInfo1: PropInfo);

VAR Zahl: INTEGER;

BEGIN
  WITH PropInfo1 DO
  BEGIN
    Zahl:=32767-VertPot DIV (SUCC(VertBody) SHL 1);
    CD_Action(CD_FADE,Zahl,0,NIL,1);
  END;
END;

PROCEDURE CheckPlayer;

BEGIN
  IF play THEN
  BEGIN
    StopPlayer(play);
    StartPlayer(play,single,song);
  END
  ELSE ShowTrack(song,play);
END;

PROCEDURE ShowTime(VAR song: BYTE; VAR play,single,repeet: BOOLEAN;
                   scan: BOOLEAN);

VAR min,sec,min2,sec2: BYTE;

BEGIN
  CD_Action(CD_SUBQMSF,0,0,^CDStatus,1);
  IF single THEN BEGIN
                   DELAY(10);
                   IF song<>CDStatus[2] THEN
                   BEGIN
                     StopPlayer(play);
                     IF Repeet THEN
                     BEGIN
                       CD_Action(CD_PLAYTRACK,song,0,NIL,0);
                       play:=TRUE;
                     END;
                   END;
                 END
                 ELSE song:=CDStatus[2];
  min:=CDStatus[9];
  sec:=CDStatus[10];
  CASE Display OF
    1: BEGIN
         GetTime(max,min2,sec2);
         min:=min2-min;
         CheckSec(sec2,sec,min);
         sec:=sec2;
       END;
    2..3: IF NOT single THEN
          BEGIN
            min2:=TOCArray[(song SHL 3)+5];
            sec2:=TOCArray[(song SHL 3)+6];
            min:=min2+min;
            sec:=sec2+sec;
            IF sec>59 THEN
            BEGIN
              sec:=sec-60;
              INC(min);
            END;
            IF Display=3 THEN
            BEGIN
              min:=TOCArray[5]-min;
              sec2:=TOCArray[6];
              CheckSec(sec2,sec,min);
              sec:=sec2;
            END;
          END
          ELSE
          BEGIN
            Display:=4;
            ShowNothing;
          END;
    OTHERWISE;
  END;
  DELAY(5);
  IF Display<4 THEN ShowAll(min,sec,song,play,scan);
END;

PROCEDURE ScanIntoCD;

VAR i,j: BYTE;

  FUNCTION GetAnswer: BOOLEAN;

  VAR AktGad: ^Gadget;
      GadID : WORD;

  BEGIN
    ShowTime(i,play,single,repeet,TRUE);
    DELAY(40);
    msg:=Get_Msg(Win^.UserPort);
    AktGad:=Msg^.IAddress;
    GadID:=AktGad^.GadgetID;
    GetAnswer:=(GadID=5);
  END;

BEGIN
  FOR i:=1 TO max DO
  BEGIN
    CD_Action(CD_FADE,32767,0,NIL,1);
    Clear(68,78);
    StartPlayer(play,single,i);
    FOR j:=1 TO 9 DO IF GetAnswer THEN Exit;
    CD_Action(CD_FADE,0,150,NIL,1);
    FOR j:=1 TO 3 DO IF GetAnswer THEN Exit;
    StopPlayer(play);
  END;
END;

PROCEDURE DisplayInfo(Win: p_Window);

VAR Win2 : ^Window;
    Con2 : PTR;
    TAttr: TextAttr;
    itxt : IntuiText;
    BDatA: ARRAY [0..2] OF Bord_Type;
    BA   : ARRAY [0..4] OF Border;
    GA   : Gadget;
    Msg  : ^IntuiMessage;

BEGIN
  Win2:=Open_Window(Win^.LeftEdge+4,Win^.TopEdge+41,268,55,1,GADGETUP,
                    ACTIVATE,NIL,NIL,0,0,0,0);
  Con2:=OpenConsole(Win2);
  WriteCon(Con2,""\e"0 p"\e"9C"\e"32mCDTV-Player 1.3"\e"31m"\n"  Written by Danny Amor in 1992"\n"    This program is "\e"32mFREEWARE"\e"31m!"\n"   Written in KICK-PASCAL v2.1");
  TAttr:=TextAttr("topaz.font",8,0,99);
  ITxt:=IntuiText(1,0,0,36,3,^TAttr,"OK",NIL);
  BDatA[0]:=Bord_Type(1,1,1,12,0,13,0,0,86,0);
  BDatA[1]:=Bord_Type(86,13,86,1,87,0,87,13,1,13);
  BDatA[2]:=Bord_Type(0,54,266,54,266,1,267,0,267,54);
  BA[0]:=Border(0,0,2,0,0,5,^BDatA[0],^BA[1]);
  BA[1]:=Border(0,0,1,0,0,5,^BDatA[1],NIL);
  BA[2]:=Border(0,0,2,0,0,5,^BDatA[1],^BA[3]);
  BA[3]:=Border(0,0,1,0,0,5,^BDatA[0],NIL);
  BA[4]:=Border(0,0,2,0,0,5,^BDatA[2],NIL);
  DrawBorder(Win2^.RPort,^BA[4],0,0);
  GA:=Gadget(NIL,90,37,88,14,GADGHIMAGE,RELVERIFY+GADGIMMEDIATE,BOOLGADGET,^BA[0],^BA[2],^ITxt,0,NIL,1,0);
  AddGadget(Win2,^GA,NIL);
  RefreshGadgets(^GA,Win2,NIL);
  Msg:=Wait_Port(Win2^.UserPort);
  Msg:=Get_Msg(Win2^.UserPort);
  Reply_Msg(Msg);
  Close_Window(Win2);
END;

PROCEDURE LoadKaraoke(VAR Singer: INTEGER);

VAR Dat        : FILE OF CHAR;
    Num2,B     : INTEGER;
    AHA        : STRING[30];
    I,J        : BYTE;

BEGIN
  RESET(Dat,"CDTV-Player:CDTV-Player/Lyrics/A-ZMusix");
  IF ioResult=0 THEN
  BEGIN
    READLN(Dat,AHA);
    IF AHA="#MUSIX" THEN
    BEGIN
      READLN(Dat,AHA);
      IF AHA[1]="#" THEN
      BEGIN
        DELETE(AHA,1,1);
        VAL(AHA,Singer,B);
        FOR I:=1 TO Singer DO
        BEGIN
          READLN(Dat,AHA);
          BaTiSo[I,0]:=AHA;
          READLN(Dat,AHA);
          IF (AHA[1]="#") AND (AHA[2]="#") THEN
          BEGIN
            DELETE(AHA,1,2);
            VAL(AHA,Num2,B);
            IF Num2>1 THEN
            FOR J:=1 TO Num2 DO
            BEGIN
              READLN(Dat,AHA);
              BaTiSo[I,J]:=AHA;
            END
            ELSE
            BEGIN
              READLN(Dat,AHA);
              BaTiSo[I,1]:=AHA;
            END;
          END;
        END;
      END;
      CLOSE(Dat);
    END;
  END;
END;

PROCEDURE LoadSongLyrics;

VAR Dat        : FILE OF CHAR;
    Num1,Num2,B: INTEGER;
    AHA        : STRING[30];
    I,J        : BYTE;
    Fname      : STRING[90];

BEGIN
  Fname:="CDTV-Player:CDTV-Player/Lyrics/"+BaTiSo[bandnumber,0]+"/"+BaTiSo[bandnumber,albumnumber];
  RESET(Dat,Fname);
  IF ioResult=0 THEN
  BEGIN
    READLN(Dat,AHA);
    IF AHA="#TITLE" THEN
    BEGIN
      READLN(Dat,AHA);
      READLN(Dat,AHA);
      IF AHA[1]="#" THEN
      BEGIN
        DELETE(AHA,1,1);
        VAL(AHA,Num1,B);
        FOR I:=1 TO Num1 DO
        BEGIN
          REPEAT
            READLN(Dat,AHA);
          UNTIL (AHA[1]="#") AND (AHA[2]="#");
          READLN(Dat,AHA);
          SongTitle[I]:=AHA;
        END;
      END;
      CLOSE(Dat);
    END;
  END;
END;

PROCEDURE Karaoke(VAR BandNumber: BYTE; VAR Singer: INTEGER);

VAR OLDOFFSET,OFFSET,I,J,
    SongCount  : BYTE;
    Win2       : ^Window;
    Itx        : ARRAY [1..6] OF IntuiText;
    GA         : ARRAY [1..7] OF Gadget;
    TAtt       : TextAttr;
    PropInfo2  : PropInfo;
    MDat       : ^Scro_Type;
    MImage2    : Image;
    BDatA      : ARRAY [1..2] OF Bord_Type;
    BA         : ARRAY [1..2] OF Border;
    Ende2      : BOOLEAN;
    Msg2       : ^IntuiMessage;
    AktGad2    : ^Gadget;
    PropInt,GADID: INTEGER;

  PROCEDURE PutOnGadgets1;

  VAR I: BYTE;

  BEGIN
    FOR I:=1 TO 6 DO
    BEGIN
      ITx[I]:=IntuiText(1,0,0,0,0,^TAtt,BaTiSo[I+OFFSET,0],NIL);
      GA[I]:=Gadget(NIL,4,PRED(I)*8+3,238,8,0,RELVERIFY+GADGIMMEDIATE,BOOLGADGET,NIL,NIL,^ITx[I],0,NIL,I,0);
      AddGadget(Win2,^GA[I],NIL);
    END;
  END;

  PROCEDURE PutOnGadgets2;

  VAR I,J: BYTE;

  BEGIN
    IF SongCount<6 THEN J:=SongCount
                     ELSE J:=6;
    FOR I:=1 TO J DO
    BEGIN
      ITx[I]:=IntuiText(1,0,0,0,0,^TAtt,BaTiSo[bandnumber,I+OFFSET],NIL);
      GA[I]:=Gadget(NIL,4,PRED(I)*8+3,238,8,0,RELVERIFY+GADGIMMEDIATE,BOOLGADGET,NIL,NIL,^ITx[I],0,NIL,I,0);
      AddGadget(Win2,^GA[I],NIL);
    END;
  END;

  PROCEDURE Print2(t: STR; x,y: BYTE);

  VAR it: IntuiText;
      i : BYTE;

  BEGIN
    it:=IntuiText(1,0,1,0,0,NIL,t,NIL);
    PrintIText(Win2^.RPort,^it,x,SUCC(y));
  END;

  PROCEDURE MoveGadgets(second: BOOLEAN);

  VAR I      : BYTE;
      J,DIREC: INTEGER;
      UPDOWN : SHORT;
      outerr : BOOLEAN;

  BEGIN
    OLDOFFSET:=OFFSET;
    WITH PropInfo2 DO OFFSET:=VertPot DIV (SUCC(VertBody) SHL 1);
    IF OFFSET<>OLDOFFSET THEN
    BEGIN
      DIREC:=OFFSET-OLDOFFSET;
      UPDOWN:=DIREC DIV ABS(DIREC);
      FOR J:=1 TO ABS(DIREC) DO
      BEGIN
        FOR I:=1 TO 8 DO
          ScrollRaster(Win2^.RPort,0,UPDOWN,4,3,238,50);
        IF second THEN
        BEGIN
          IF UPDOWN>0 THEN
          BEGIN
            Move(Win2^.RPort,4,49);
            outerr:=GfxText(Win2^.RPort,BaTiSo[bandnumber,OLDOFFSET+6+J],LENGTH(BaTiSo[bandnumber,OLDOFFSET+6+J]));
          END
          IF UPDOWN<0 THEN
          BEGIN
            Move(Win2^.RPort,4,9);
            outerr:=GfxText(Win2^.RPort,BaTiSo[bandnumber,SUCC(OLDOFFSET)-J],LENGTH(BaTiSo[bandnumber,SUCC(OLDOFFSET)-J]));
          END        END
        ELSE
        BEGIN
          IF UPDOWN>0 THEN
          BEGIN
            Move(Win2^.RPort,4,49);
            outerr:=GfxText(Win2^.RPort,BaTiSo[OLDOFFSET+6+J,0],LENGTH(BaTiSo[OLDOFFSET+6+J,0]));
          END
          IF UPDOWN<0 THEN
          BEGIN
            Move(Win2^.RPort,4,9);
            outerr:=GfxText(Win2^.RPort,BaTiSo[SUCC(OLDOFFSET)-J,0],LENGTH(BaTiSo[SUCC(OLDOFFSET)-J,0]));
          END
        END;
      END;
      FOR I:=1 TO 6 DO RemoveGadgets(Win2,^GA[I]);
      IF second THEN PutOnGadgets2
                ELSE PutOnGadgets1;
      RefreshGadgets(Win2^.FirstGadget,Win2,NIL);
    END;
  END;

BEGIN
  Win2:=Open_Window(Win^.LeftEdge+4,Win^.TopEdge+41,268,55,1,GADGETUP
                    OR GADGETDOWN OR MOUSEMOVE,ACTIVATE,NIL,NIL,0,0,0,0);
  SetAPen(Win2^.RPort,1);
  OFFSET:=0;
  OLDOFFSET:=0;
  Ende2:=FALSE;
  TAtt:=TextAttr("topaz.font",8,0,99);
  IF Singer<7 THEN PropInt:=0
              ELSE PropInt:=$7FFF DIV (Singer-5);
  PropInfo2:=PropInfo(PROPBORDERLESS OR FREEVERT,0,0,0,PropInt,0,0,0,0,0,0);
  MDat:=PTR(Alloc_Mem(SIZEOF(Scro_Type),2));
  MDat^:=Scro_Type(8,24,24,3864,3096,3096,2072,24,24,32760,-16,-16384,
                   -16384,-16256,-16000,-16000,-14464,-16384,-16384,-32768);
  MImage2:=Image(0,0,13,10,2,MDat,3,0,NIL);
  PutOnGadgets1;
  GA[7]:=Gadget(NIL,246,4,13,47,GADGHBOX OR GADGIMAGE,GADGIMMEDIATE
                OR RELVERIFY OR FOLLOWMOUSE,PROPGADGET,^MImage2,NIL,
                NIL,0,^PropInfo2,7,0);
  AddGadget(Win2,^GA[7],NIL);
  BDatA[1]:=Bord_Type(262,2,244,2,244,51,243,52,243,2);
  BDatA[2]:=Bord_Type(244,52,262,52,262,3,263,2,263,52);
  BA[1]:=Border(0,0,2,0,0,5,^BDatA[1],^BA[2]);
  BA[2]:=Border(0,0,1,0,0,5,^BDatA[2],NIL);
  RefreshGadgets(Win2^.FirstGadget,Win2,NIL);
  DrawBorder(Win2^.RPort,^BA,-1,0);
  REPEAT
    Msg2:=Wait_Port(Win2^.UserPort);
    Msg2:=Get_Msg(Win2^.UserPort);
    CASE Msg2^.Class OF
    GADGETUP:
        BEGIN
          AktGad2:=Msg2^.IAddress;
          CASE AktGad2^.GadgetID OF
            1..6: BEGIN
                    bandnumber:=AktGad2^.GadgetID+OFFSET;
                    Ende2:=TRUE;
                  END;
               7: IF SINGER>6 THEN MoveGadgets(FALSE);
            OTHERWISE;
          END;
        END;
      MOUSEMOVE: IF GadID=7 THEN MoveGadgets(FALSE);
      GADGETDOWN: BEGIN
                    AktGad2:=Msg2^.IAddress;
                    GadID:=AktGad2^.GadgetID;
                  END;
      OTHERWISE;
    END;
    Reply_Msg(Msg2);
  UNTIL Ende2;
  OFFSET:=0;
  OLDOFFSET:=0;
  Ende2:=FALSE;
  FOR I:=1 TO 6 DO RemoveGadgets(Win2,^GA[I]);
  SetAPen(Win2^.RPort,0);
  RectFill(Win2^.RPort,4,3,238,50);
  SetAPen(Win2^.RPort,1);
  SongCount:=0;
  REPEAT
    INC(SongCount);
  UNTIL (BaTiSo[bandnumber,SongCount]="") OR (SongCount=mCD);
  DEC(SongCount);
  PutOnGadgets2;
  IF SongCount<7 THEN PropInt:=0
                 ELSE PropInt:=$7FFF DIV (SongCount-5);
  ModifyProp(^GA[7],Win2,NIL,PROPBORDERLESS OR FREEVERT,0,0,0,PropInt);
  RefreshGadgets(Win2^.FirstGadget,Win2,NIL);
  REPEAT
    Msg2:=Wait_Port(Win2^.UserPort);
    Msg2:=Get_Msg(Win2^.UserPort);
    CASE Msg2^.Class OF
    GADGETUP:
      BEGIN
        AktGad2:=Msg2^.IAddress;
        CASE AktGad2^.GadgetID OF
          1..6: BEGIN
                  albumnumber:=AktGad2^.GadgetID+OFFSET;
                  Ende2:=TRUE;
                END;
             7: IF SongCount>6 THEN MoveGadgets(TRUE);
          OTHERWISE;
        END;
      END;
    MOUSEMOVE: IF GadID=7 THEN MoveGadgets(TRUE);
    GADGETDOWN: BEGIN
                  AktGad2:=Msg2^.IAddress;
                  GadID:=AktGad2^.GadgetID;
                END;
    OTHERWISE;
    END;
    Reply_Msg(Msg2);
  UNTIL Ende2;
  LoadSongLyrics;
  Clear(68,94);
  ShowBottom;
  Close_Window(Win2);
END;

PROCEDURE DeviceCloser;

BEGIN
  IF play THEN StopPlayer(play);
  CloseDevice(ioReq[1]);
  CloseDevice(ioReq[0]);
  DeleteExtIO(ioReq[1]);
  DeleteExtIO(ioReq[0]);
  DeletePort(ReplyPort[1]);
  DeletePort(ReplyPort[0]);
END;

BEGIN
  Win:=Open_Window(50,0,300,128,1,_CLOSEWINDOW OR GADGETUP OR GADGETDOWN OR
                   MOUSEMOVE OR DISKREMOVED OR DISKINSERTED,WINDOWDRAG OR
                   WINDOWDEPTH OR WINDOWCLOSE OR ACTIVATE,
                   "CDTV-Player by D. Amor '92 ",NIL,0,0,0,0);
  Rp:=Win^.RPort;
  ReplyPort[0]:=CreatePort("CD-Port0",0);
  ReplyPort[1]:=CreatePort("CD-Port1",0);
  ioReq[0]:=CreateExtIO(ReplyPort[0],64);
  ioReq[1]:=CreateExtIO(ReplyPort[1],64);
  Fehler1:=OpenDevice("cdtv.device",0,ioReq[0],0);
  Fehler2:=OpenDevice("cdtv.device",0,ioReq[1],0);
  IF (Fehler1=0) AND (Fehler2=0) THEN
  BEGIN
    AddExitServer(DeviceCloser);
    TAttr0:=TextAttr("topaz.font",8,0,99);
    ITxt[1]:=IntuiText(1,0,0,32,3,^TAttr0,"REW",NIL);
    ITxt[2]:=IntuiText(1,0,0,28,3,^TAttr0,"PLAY",NIL);
    ITxt[3]:=IntuiText(1,0,0,36,3,^TAttr0,"FF",NIL);
    ITxt[4]:=IntuiText(1,0,0,24,3,^TAttr0,"PAUSE",NIL);
    ITxt[5]:=IntuiText(1,0,0,28,3,^TAttr0,"STOP",NIL);
    ITxt[6]:=IntuiText(1,0,0,28,3,^TAttr0,"FADE",NIL);
    ITxt[8]:=IntuiText(1,0,0,16,3,^TAttr0,"DISPLAY",NIL);
    ITxt[9]:=IntuiText(1,0,0,20,3,^TAttr0,"SINGLE",NIL);
    ITxt[10]:=IntuiText(1,0,0,20,3,^TAttr0,"REPEAT",NIL);
    ITxt[11]:=IntuiText(1,0,0,28,3,^TAttr0,"SCAN",NIL);
    ITxt[12]:=IntuiText(1,0,0,28,3,^TAttr0,"INFO",NIL);
    ITxt[13]:=IntuiText(1,0,0,16,3,^TAttr0,"KARAOKE",NIL);
    MDat:=PTR(Alloc_Mem(SIZEOF(Scro_Type),2));
    MDat^:=Scro_Type(8,24,24,3864,3096,3096,2072,24,24,32760,-16,-16384,
                     -16384,-16256,-16000,-16000,-14464,-16384,-16384,-32768);
    MImage1:=Image(0,0,13,10,2,MDat,3,0,NIL);
    BorderDatA[0]:=Bord_Type(1,1,1,12,0,13,0,0,86,0);
    BorderDatA[1]:=Bord_Type(86,13,86,1,87,0,87,13,1,13);
    BorderA[0]:=Border(0,0,2,0,0,5,^BorderDatA[0],^BorderA[1]);
    BorderA[1]:=Border(0,0,1,0,0,5,^BorderDatA[1],NIL);
    BorderA[2]:=Border(0,0,2,0,0,5,^BorderDatA[1],^BorderA[3]);
    BorderA[3]:=Border(0,0,1,0,0,5,^BorderDatA[0],NIL);
    BorderDatA[2]:=Bord_Type(2,41,2,95,3,94,3,41,268,41);
    BorderDatA[3]:=Bord_Type(269,95,269,41,268,42,268,95,3,95);
    BorderDatA[4]:=Bord_Type(272,11,272,125,273,124,273,11,290,11);
    BorderA[4]:=Border(0,0,2,0,0,5,^BorderDatA[2],^BorderA[5]);
    BorderA[5]:=Border(0,0,1,0,0,5,^BorderDatA[3],^BorderA[6]);
    BorderA[6]:=Border(0,0,2,0,0,5,^BorderDatA[4],NIL);
    PropInfo1:=PropInfo(FREEVERT,0,0,32767,0,0,0,0,0,0,0);
    FOR watch:=1 TO 3 DO
      GadgetA[watch]:=Gadget(^GadgetA[SUCC(watch)],4+PRED(watch)*90,11,88,14,GADGHIMAGE,RELVERIFY+GADGIMMEDIATE,BOOLGADGET,^BorderA[0],^BorderA[2],^ITxt[watch],0,NIL,watch,0);
    GadgetA[4]:=Gadget(^GadgetA[5],4,26,88,14,GADGHIMAGE,RELVERIFY+GADGIMMEDIATE+TOGGLESELECT,BOOLGADGET,^BorderA[0],^BorderA[2],^ITxt[4],0,NIL,4,0);
    GadgetA[5]:=Gadget(^GadgetA[6],94,26,88,14,GADGHIMAGE,RELVERIFY+GADGIMMEDIATE,BOOLGADGET,^BorderA[0],^BorderA[2],^ITxt[5],0,NIL,5,0);
    GadgetA[6]:=Gadget(^GadgetA[7],184,26,88,14,GADGHIMAGE,RELVERIFY+GADGIMMEDIATE+TOGGLESELECT,BOOLGADGET,^BorderA[0],^BorderA[2],^ITxt[6],0,NIL,6,0);
    GadgetA[7]:=Gadget(^GadgetA[8],274,11,21,115,GADGHBOX OR GADGIMAGE,GADGIMMEDIATE
                       OR RELVERIFY OR FOLLOWMOUSE,PROPGADGET,^MImage1,NIL,
                       NIL,0,^PropInfo1,7,0);
    GadgetA[8]:=Gadget(^GadgetA[9],4,97,88,14,GADGHIMAGE,RELVERIFY+GADGIMMEDIATE,BOOLGADGET,^BorderA[0],^BorderA[2],^ITxt[8],0,NIL,8,0);
    GadgetA[9]:=Gadget(^GadgetA[10],94,97,88,14,GADGHIMAGE,RELVERIFY+GADGIMMEDIATE+TOGGLESELECT,BOOLGADGET,^BorderA[0],^BorderA[2],^ITxt[9],0,NIL,9,0);
    GadgetA[10]:=Gadget(^GadgetA[11],184,97,88,14,GADGHIMAGE,RELVERIFY+GADGIMMEDIATE+TOGGLESELECT,BOOLGADGET,^BorderA[0],^BorderA[2],^ITxt[10],0,NIL,10,0);
    GadgetA[11]:=Gadget(^GadgetA[12],94,112,88,14,GADGHIMAGE,RELVERIFY+GADGIMMEDIATE,BOOLGADGET,^BorderA[0],^BorderA[2],^ITxt[11],0,NIL,11,0);
    GadgetA[12]:=Gadget(^GadgetA[13],184,112,88,14,GADGHIMAGE,RELVERIFY+GADGIMMEDIATE,BOOLGADGET,^BorderA[0],^BorderA[2],^ITxt[12],0,NIL,12,0);
    GadgetA[13]:=Gadget(NIL,4,112,88,14,GADGHIMAGE,RELVERIFY+GADGIMMEDIATE,BOOLGADGET,^BorderA[0],^BorderA[2],^ITxt[13],0,NIL,13,0);
    watch:=AddGList(Win,^GadgetA[1],1,13,NIL);
    RefreshGList(^GadgetA[1],Win,NIL,13);
    DrawBorder(Rp,^BorderA[4],2,0);
    ende:=FALSE;    pause:=TRUE;
    fade:=TRUE;     repeet:=FALSE;
    play:=FALSE;    single:=FALSE;
    FOR x:=0 TO mSing DO
      FOR y:=0 TO mCD DO
        BaTiSo[x,y]:="";
    LoadKaraoke(singer);
    bandnumber:=0;  albumnumber:=0;
    Song:=1;        Display:=0;
    FOR watch:=1 TO 20 DO SongTitle[watch]:="";
    InitText;
    CD_Action(CD_CSTATE,0,0,NIL,0);
    CD_Action(CD_FADE,32767,0,NIL,1);
    IF ioReq[channel]^.io_Actual=255 THEN WaitStartUp
                                     ELSE StartUp;
    REPEAT
      REPEAT
        IF (NOT play) OR (display=4) THEN Msg:=Wait_Port(Win^.UserPort);
        Msg:=Get_Msg(Win^.UserPort);
        IF (watch=255) AND play AND pause THEN ShowTime(song,play,single,repeet,FALSE);
        INC(watch);
      UNTIL Msg<>NIL;
      CASE Msg^.Class OF
        _CLOSEWINDOW: Ende:=TRUE;
        DISKREMOVED: BEGIN
                       CD_Action(CD_CSTATE,0,0,NIL,0);
                       IF ioReq[channel]^.io_Actual=255 THEN
                       BEGIN
                         WaitStartUp;
                         play:=FALSE;
                       END;
                     END;
        DISKINSERTED: BEGIN
                        CD_Action(CD_CSTATE,0,0,NIL,0);
                        IF (ioReq[channel]^.io_Actual=0) AND removed THEN Startup;
                      END;
        GADGETUP: IF NOT removed THEN
                  BEGIN
                    AktGad:=Msg^.IAddress;
                    CASE AktGad^.GadgetID OF
                      1: IF song>1 THEN
                         BEGIN
                           DEC(song);
                           CheckPlayer;
                         END;
                      2: IF NOT play THEN StartPlayer(play,single,song);
                      3: IF song<max THEN
                         BEGIN
                           INC(song);
                           CheckPlayer;
                         END;
                      4: PausePlayer(pause);
                      5: IF play THEN
                         BEGIN
                           StopPlayer(play);
                           StopText(max,TOCArray[5],TOCArray[6]);
                         END;
                      6: DimOffPlayer(fade);
                      7: IF NOT Fade THEN Scroll_Fade(PropInfo1)
                      8: BEGIN
                           INC(Display);
                           CASE Display OF
                             4: ShowNothing;
                             5: BEGIN
                                  Clear(50,58);
                                  display:=0;
                                END;
                             OTHERWISE;
                           END;
                         END;
                      9: single:=NOT single;
                      10: repeet:=NOT repeet;
                      11: IF NOT play THEN ScanIntoCD;
                      12: DisplayInfo(Win);
                      13: Karaoke(bandnumber,singer);
                      OTHERWISE
                    END;
                  END;
        MOUSEMOVE: IF GadID=7 THEN Scroll_Fade(PropInfo1);
        GADGETDOWN: BEGIN
                       AktGad:=Msg^.IAddress;
                       GadID:=AktGad^.GadgetID;
                    END;
        OTHERWISE
      END;
      Reply_Msg(Msg);
    UNTIL Ende
  END
  ELSE
  BEGIN
    con:=OpenConsole(win);
    ErrorMessage:="I'm sorry! Can't find "\e"33m'cdtv.device'!"\e"31m"\n"This machine doesn't look like a"\n\e"33mCDTV"\e"31m or an "\e"33mA570/A670"\e"31m! In case I'm"\n"wrong please write to me."\n"See Doc.File!"\n;
    WriteCon(con,ErrorMessage);
    CloseConsole(con);
    play:=FALSE;
    Msg:=Wait_Port(Win^.UserPort);
    Msg:=Get_Msg(Win^.UserPort);
  END;
END.

