
 /* SuperPlay V1.5
    Multi-Sound-Replayer
    (c) 1993-94 by Andreas R. Kleinert. All rights reserved.
    Compiler     : SAS/C V6.51
    Last changes : 08.05.1994
 */

#include "SuperPlay.h"
#include <intuition/intuitionbase.h>


   /* Help-, Info- and Error-Texts */

char entry1_text  [] = "\2331;32;40m"SP_STRDEF_VERSION " " SP_STRDEF_DATE"\2330;32;40m\2333;32;40m (SHAREWARE)\2330;32;40m\n(c) 1994 by Andreas Ralph Kleinert. All rights reserved.\n"
                       "Andreas R. Kleinert, Grube Hohe Grethe 23, D-57074 Siegen, Germany.\n";
char entry2_text  [] = "Player program for use with SuperPlay-Library.\n";
char entry3_text  [] = "USAGE : \2330;33;40mSuperPlay\2330;31;40m\n";

char ver_text [] = SP_STRDEF_VER SP_STRDEF_VERSION " " SP_STRDEF_DATE;

char intuitionlib_text	[] = "You need \42intuition.library\42 V37+ !";
char graphicslib_text	[] = "You need \42graphics.library\42 V37+ !";
char gadtoolslib_text	[] = "You need \42gadtools.library\42 V37+ !";
char asllib_text	[] = "You need \42asl.library\42 V37+ !";
char splib_text  	[] = "You need \42superplay.library\42 V1+ !";

char no_win_text        [] = "Can't open GUI Window !";
char no_scr_text        [] = "Can't open GUI Screen !";
char no_handle_text     [] = "Not enough memory !";


/* *************************************************** */
/* *						     * */
/* * Function Declarations			     * */
/* *						     * */
/* *************************************************** */

void __regargs SPS_HandleGadgets(void);
void __regargs Leave(char *errtext, APTR mlist, long code);

ULONG __regargs SPS_Play(char *filename, ULONG flag);
ULONG __regargs SPS_PlayRequest(ULONG flag);

ULONG __regargs SPS_Conv(char *filename, ULONG code);
ULONG __regargs SPS_ConvRequest(ULONG code);

ULONG __regargs SPS_FileRequest(struct SP_RememberPath *sprp, char *title, char *left, char *right);
void  __regargs SPS_DisplayError(char *text);

void __stdargs SP_Printf(char *formatstring, ...);
void __stdargs SP_SPrintf(char *buffer, char *formatstring, ...);


/* *************************************************** */
/* *						     * */
/* * Additional Base Declarations		     * */
/* *						     * */
/* *************************************************** */

struct IntuitionBase *IntuitionBase  = N;
struct GfxBase	     *GfxBase	     = N;
struct Library	     *GadToolsBase   = N;
struct Library	     *AslBase        = N;
struct SuperPlayBase *SuperPlayBase  = N;


/* *************************************************** */
/* *						     * */
/* * Globally Accessed Variables		     * */
/* *						     * */
/* *************************************************** */

struct SPS_SPOList *SPOList = N;
APTR playhandle             = N;


/* *************************************************** */
/* *						     * */
/* * Compiler Stuff for BackgroundIO		     * */
/* *						     * */
/* *************************************************** */

long  __stack	     = 32768;
char *__procname     = "SuperPlay";
long  __priority     = 1;
long  __BackGroundIO = 1;	    /* TRUE : We DO BackGroundIO !     */

extern BPTR _Backstdout;	    /* NULL, if started from Workbench */


/* *************************************************** */
/* *						     * */
/* * <CTRL-C>-Handling				     * */
/* *						     * */
/* *************************************************** */

void CXBRK(void);
void CXBRK(void)
{
 Leave("*** BREAK ***", N, 0);
}


/* *************************************************** */
/* *						     * */
/* * MAIN					     * */
/* *						     * */
/* *************************************************** */

void main(long argc, char **argv)
{
 SetTaskPri(FindTask(N), __priority);

 if(argc && argv[1][0] =='?')
  {
   SP_Printf("%s%s%s", entry1_text, entry2_text, entry3_text);

   Leave(N, N, 0);
  }

 if(OS_VER < 37) Leave("You need OS V2.04+ !", N, 20);

 IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 37);
 if(!IntuitionBase) Leave(intuitionlib_text, N, 20);

 GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 37);
 if(!GfxBase) Leave(graphicslib_text, N, 20);

 GadToolsBase = (struct Library *) OpenLibrary("gadtools.library", 37);
 if(!GadToolsBase) Leave(gadtoolslib_text, N, 20);

 AslBase = (struct Library *) OpenLibrary("asl.library", 37);
 if(!AslBase) Leave(asllib_text, N, 20);

 SuperPlayBase = (struct SuperPlayBase *) OpenLibrary("superplay.library", 1);
 if(!SuperPlayBase) Leave(splib_text, N, 20);

 SPOList = SPS_GetSPOList();
 SPS_HandleGadgets();

 Leave(N, N, 0);
}

/* *************************************************** */
/* *						     * */
/* * Leave : Global Exit Function Replacement	     * */
/* *						     * */
/* *************************************************** */

void __regargs Leave(char *errtext, APTR mlist, long code)
{
 if(Scr)
  {
   if(SP_Main_Wnd) CloseSP_Main_Window();

   CloseDownScreen();
  }

 if(SPOList)    SPS_FreeSPOList(SPOList);
 if(playhandle) SPL_FreeHandle(playhandle);

 if(SuperPlayBase)  CloseLibrary((APTR) SuperPlayBase);
 if(AslBase)        CloseLibrary((APTR) AslBase);
 if(GadToolsBase)   CloseLibrary((APTR) GadToolsBase);
 if(GfxBase)        CloseLibrary((APTR) GfxBase);
 if(IntuitionBase)  CloseLibrary((APTR) IntuitionBase);

 if(_Backstdout)
  {
   if(errtext) Write(_Backstdout, errtext, strlen(errtext));
   Close(_Backstdout);
  }

 exit(code); /* FAILED */
}

/* *************************************************** */
/* *						     * */
/* * SPS_HandleGadgets : ...                         * */
/* *						     * */
/* *************************************************** */

void __regargs SPS_HandleGadgets(void)
{
 struct TagItem __aligned tags[2];
 struct IntuiMessage *msg;
 ULONG class, code, gadid, last_spogad = 0;
 struct Gadget *address;
 struct SPS_SPOEntry   *spe_node = N;
 struct SPO_ObjectNode *spo_node = N;
 ULONG retval = SPERR_NO_ERROR;

 spe_node = SPS_GetSPOEntry(SPOList, 0);
 spo_node = spe_node->spe_SPO_ObjectNode;

 SetupScreen();
 if(Scr)
  {
   OpenSP_Main_Window();
   SP_Main_Render();

   if(SP_Main_Wnd)
    {
     ModifyIDCMP(SP_Main_Wnd,   (BUTTONIDCMP|MXIDCMP|IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW)
                              ^ (IDCMP_INTUITICKS | IDCMP_MOUSEMOVE | IDCMP_MOUSEBUTTONS)
                              |  IDCMP_VANILLAKEY | IDCMP_RAWKEY);

     tags[0].ti_Tag  = (Tag)   GTCY_Labels;
     tags[0].ti_Data = (ULONG) SPOList->spl_Labels;

     tags[1].ti_Tag  = (Tag)  TAG_DONE;
     tags[1].ti_Data = (ULONG) N;

     GT_SetGadgetAttrsA(SP_Main_Gadgets[GD_SPOGad], SP_Main_Wnd, N, &tags[0]);

     for(;;)
      {
       if(retval)
        {
         if(retval == SPERR_ACTION_NOT_SUPPORTED) DisplayBeep(Scr);
          else SPS_DisplayError(SPL_GetErrorString(retval));

         retval = SPERR_NO_ERROR;
        }

       WaitPort(SP_Main_Wnd->UserPort);
       if(!(msg = GT_GetIMsg(SP_Main_Wnd->UserPort))) continue;

       class   = msg->Class;
       code    = msg->Code;
       address = msg->IAddress;
       gadid   = address->GadgetID;

       GT_ReplyIMsg(msg);

       if(class == IDCMP_CLOSEWINDOW) break;
       if(class == IDCMP_VANILLAKEY)
        {
         switch(toupper(code))
          {
           case 'O' : {
                       if(last_spogad < SPOList->spl_NumEntries-1) last_spogad++;
                        else                                       last_spogad = 0;

                       tags[0].ti_Tag  = (Tag)   GTCY_Active;
                       tags[0].ti_Data = (ULONG) last_spogad;

                       /* tags[0] is still TAG_DONE ... */

                       GT_SetGadgetAttrsA(SP_Main_Gadgets[GD_SPOGad], SP_Main_Wnd, N, &tags[0]);

                       break;
                      }
           case 'C' : { class = IDCMP_GADGETUP; gadid = GD_ConvertGad; break; }
           case 'P' : { class = IDCMP_GADGETUP; gadid = GD_PlayGad;    break; }
           case 'S' : { class = IDCMP_GADGETUP; gadid = GD_StopGad;    break; }
           case 'T' : { class = IDCMP_GADGETUP; gadid = GD_ContGad;    break; }
           case 'F' : { class = IDCMP_GADGETUP; gadid = GD_ForGad;     break; }
           case 'B' : { class = IDCMP_GADGETUP; gadid = GD_BackGad;    break; }
           case 'I' : { class = IDCMP_GADGETUP; gadid = GD_InfoGad;    break; }
           case 'L' : { class = IDCMP_GADGETUP; gadid = GD_LEDGad;     break; }
           default : break;
          }
        }
       if(   class == IDCMP_GADGETUP
          || class == IDCMP_GADGETDOWN)
        {
         switch(gadid)
          {
           case GD_SPOGad :
            {
             spe_node = SPS_GetSPOEntry(SPOList, code);
             spo_node = spe_node->spe_SPO_ObjectNode;

             last_spogad = code;

             break;
            }
           case GD_ConvertGad :
            {
             retval = SPS_ConvRequest(spe_node->spe_ObjectSubCode);

             break;
            }
           case GD_PlayGad :
            {
             retval = SPS_PlayRequest(TRUE);

             break;
            }
           case GD_StopGad :
            {
             if(playhandle) SPL_StopReplay(playhandle);
              else SPS_DisplayError("No File loaded");

             break;
            }
           case GD_ContGad :
            {
             if(playhandle) retval = SPL_ContinueReplay(playhandle);
              else SPS_DisplayError("No File loaded");

             break;
            }
           case GD_ForGad :
            {
             if(playhandle) retval = SPL_FastForward(playhandle);
              else SPS_DisplayError("No File loaded");

             break;
            }
           case GD_BackGad :
            {
             if(playhandle) retval = SPL_FastBackward(playhandle);
              else SPS_DisplayError("No File loaded");

             break;
            }
           case GD_InfoGad :
            {
             if(playhandle) retval = SPL_FileInfoRequest(playhandle, SP_Main_Wnd, N);
              else SPS_DisplayError("No File loaded");

             break;
            }
           case GD_LEDGad :
            {
             UBYTE *address = (UBYTE *) 0xbfe001;

             if(*address & 2) /* it's OFF, make it OFF */ *address |= 2;
              else                                        *address &= 253;

             break;
            }
           default : break;
          }
        }
      }

     while( msg = GT_GetIMsg(SP_Main_Wnd->UserPort) ) GT_ReplyIMsg(msg);
    }else Leave(no_win_text, N, 202);
  }else Leave(no_scr_text, N, 202);
}

/* *************************************************** */
/* *						     * */
/* * SPS_Play : Play Routine                         * */
/* *						     * */
/* *************************************************** */

ULONG __regargs SPS_Play(char *filename, ULONG flag)
{
 ULONG retval = SPERR_NO_ERROR;

 if(playhandle)
  {
   SPL_FreeHandle(playhandle); playhandle = N;
  }

 playhandle = SPL_AllocHandle(N);
 if(playhandle)
  {
   if(!(retval = SPL_InitHandleAsDOS(playhandle, N)))
    {
     if(flag) retval = SPL_SuperPlay(playhandle, filename);
      else    retval = SPL_ReadPlayData(playhandle, filename);

    }else retval = SPERR_NO_HANDLE;
  }

 return(retval);
}

/* *************************************************** */
/* *						     * */
/* * SPS_PlayRequest : FileRequest, then SPS_Play()  * */
/* *						     * */
/* *************************************************** */

struct SP_RememberPath __aligned sprp_show;

ULONG __regargs SPS_PlayRequest(ULONG flag)
{
 char *filename = sprp_show.rp_Path;
 ULONG retval = SPERR_NO_ERROR;
 long bool;
 
 if(flag) bool = SPS_FileRequest(&sprp_show, "Select File to Play :", "Play", "Quit");
  else    bool = SPS_FileRequest(&sprp_show, "Select File to Convert :", "Convert", "Quit");

 if(filename[0]==(char) 0) bool = FALSE;

 if(bool) retval = SPS_Play(filename, flag);

 return(retval);
}

/* *************************************************** */
/* *						     * */
/* * SPS_Conv : Conv Routine                         * */
/* *						     * */
/* *************************************************** */

ULONG __regargs SPS_Conv(char *filename, ULONG code)
{
 ULONG retval = SPERR_NO_ERROR;
 APTR savehandle = N;

 savehandle = SPL_AllocHandle(N);
 if(savehandle)
  {
               retval = SPL_SetWriteType(savehandle, code, N);
   if(!retval) retval = SPL_SetWriteName(savehandle, filename, N);
   if(!retval) retval = SPL_SuperWrite(savehandle, playhandle);

   SPL_FreeHandle(savehandle);
  }

 return(retval);
}

/* *************************************************** */
/* *						     * */
/* * SPS_ConvRequest : FileRequest, then SPS_Conv()  * */
/* *						     * */
/* *************************************************** */

struct SP_RememberPath __aligned sprp_save;

ULONG __regargs SPS_ConvRequest(ULONG code)
{
 char *filename = sprp_save.rp_Path;
 ULONG retval = SPERR_NO_ERROR;
 long bool;

 retval = SPS_PlayRequest(FALSE);
 if(!retval)
  {
   bool = SPS_FileRequest(&sprp_save, "Enter new FileName :", "Done", "Quit");

   if(filename[0]==(char) 0) bool = FALSE;

   if(bool) retval = SPS_Conv(filename, code);
  }

 return(retval);
}

/* *************************************************** */
/* *						     * */
/* * SPS_FileRequest : FileRequester Routine         * */
/* *						     * */
/* *************************************************** */

ULONG __regargs SPS_FileRequest(struct SP_RememberPath *sprp, char *title, char *left, char *right)
{
 struct TagItem __aligned tags[7];
 struct FileRequester *request = N;
 ULONG bool = FALSE;

 tags[0].ti_Tag  = (Tag)   ASLFR_TitleText;
 tags[0].ti_Data = (ULONG) title;

 tags[1].ti_Tag  = (Tag)   ASLFR_PositiveText;
 tags[1].ti_Data = (ULONG) left;

 tags[2].ti_Tag  = (Tag)   ASLFR_NegativeText;
 tags[2].ti_Data = (ULONG) right;

 tags[3].ti_Tag  = (Tag)   ASLFR_InitialFile;
 tags[3].ti_Data = (ULONG) sprp->rp_File;

 tags[4].ti_Tag  = (Tag)   ASLFR_InitialDrawer;
 tags[4].ti_Data = (ULONG) sprp->rp_Dir;

 tags[5].ti_Tag  = (Tag)   ASLFR_RejectIcons;
 tags[5].ti_Data = (ULONG) TRUE;

 tags[6].ti_Tag  = (Tag)   TAG_DONE;
 tags[6].ti_Data = (ULONG) N;
 
 request = AllocAslRequest(ASL_FileRequest, N);
 if(request)
  {
   if(AslRequest(request, &tags[0]))
    {
     strcpy(sprp->rp_Dir,  request->rf_Dir);
     strcpy(sprp->rp_File, request->rf_File);

     strcpy(sprp->rp_Path, request->rf_Dir);

     if(   (sprp->rp_Path[strlen(sprp->rp_Path)-1] != ':')
         &&(sprp->rp_Path[strlen(sprp->rp_Path)-1] != '/')
         &&(sprp->rp_Path[strlen(sprp->rp_Path)-1] != ' ')
         &&(sprp->rp_Path[0] != (char) 0                 ) ) strcat(sprp->rp_Path, "/");

     strcat(sprp->rp_Path, request->rf_File);

     bool = TRUE;
    }

   FreeFileRequest(request);
  }

 return(bool);
}

void __regargs SPS_DisplayError(char *text)
{
 struct Window *popup_win = N;
 ULONG idcmp = N;
 struct EasyStruct *estr = AllocVec(sizeof(struct EasyStruct), (MEMF_CLEAR|MEMF_PUBLIC));

 if(estr)
  {
   estr->es_StructSize   = sizeof(struct EasyStruct);
   estr->es_Flags        = N;
   estr->es_Title        = "SuperPlay Message";
   estr->es_TextFormat   = text;
   estr->es_GadgetFormat = "Confirm";

                  popup_win = SP_Main_Wnd;
   if(!popup_win) popup_win = IntuitionBase->FirstScreen->FirstWindow;

   EasyRequestArgs(popup_win, estr, &idcmp, N);
   FreeVec(estr);
  }
}

/* *************************************************** */
/* *                                                 * */
/* * SP_Printf : Replacement for printf()-Output     * */
/* *                                                 * */
/* *************************************************** */

#define KIP_BUFLEN (1200)

extern void Fmt(void);

extern BPTR _Backstdout;

void __stdargs SP_Printf(char *formatstring, ...)
{
 UBYTE *buffer;

 if(_Backstdout)
  {
   buffer = (BYTE *) AllocVec(KIP_BUFLEN, MEMF_CLEAR);
   if(buffer)
    {
     RawDoFmt((APTR) formatstring, (APTR) (((ULONG *)&formatstring)+1), (APTR) &Fmt, (APTR) buffer);

     Write(_Backstdout, buffer, strlen(buffer));

     FreeVec(buffer);
    }
  }
}

/* *************************************************** */
/* *                                                 * */
/* * SP_SPrintf : Replacement for sprintf()-Routine  * */
/* *                                                 * */
/* *************************************************** */

/* currently unused */

#ifdef USE_SP_SPRINTF

void __stdargs SP_SPrintf(char *buffer, char *formatstring, ...)
{
 RawDoFmt((APTR) formatstring, (APTR) (((ULONG *)&formatstring)+1), (APTR) &Fmt, (APTR) buffer);
}

#endif /* USE_SP_SPRINTF */
