
 /* SP_PlaySubs.c
    - Functions for Playing ST Files -
    (c) 1992-94 by Andreas R. Kleinert
    Last changes : 17.05.1994
 */

#include "spobject.h"

ULONG __saveds __asm SPO_Read( register __a1 struct SPObjectHandle *SPObjectHandle_a1);
ULONG __saveds __asm SPO_StartReplay( register __a1 struct SPObjectHandle *SPObjectHandle);
ULONG __saveds __asm SPO_ContinueReplay( register __a1 struct SPObjectHandle *SPObjectHandle_a1);
ULONG __saveds __asm SPO_FastForward( register __a1 struct SPObjectHandle *SPObjectHandle_a1);
ULONG __saveds __asm SPO_FastBackward( register __a1 struct SPObjectHandle *SPObjectHandle_a1);

ULONG __saveds __stdargs SPLI_Read(struct SPObjectHandle *SPObjectHandle);


 /* Globale Variablen */

APTR  ST_Module   = N;
ULONG ST_Len      = N;
ULONG ST_RunState = N;

ULONG __saveds __asm SPO_Read( register __a1 struct SPObjectHandle *SPObjectHandle_a1)
{
 struct SPObjectHandle *SPObjectHandle = SPObjectHandle_a1;

 ULONG           retval        = SPERR_NO_ERROR;
 BPTR            fh            = N;

 if(!SPObjectHandle) return(SPERR_NO_HANDLE);

 if(fh = Open(SPObjectHandle->ah_ReadName, MODE_OLDFILE))
  {
   retval = SPLI_Read(SPObjectHandle);
   if(!retval)
    {
     ULONG           *tstptr = (APTR) SPObjectHandle->ah_STModule;
     struct STHeader *header = (APTR) SPObjectHandle->ah_STModule;

     if(*tstptr == ID_PP20) retval = SPERR_DECODE_ERROR; /* still packed */
     if(*tstptr == ID_XPKF) retval = SPERR_DECODE_ERROR; /* still packed */

     if(!retval)
      {
       if(   (*((ULONG *)&header->st_ID[0])!= ID_MK)
          && (*((ULONG *)&header->st_ID[0]) != ID_FLT4) ) retval = SPERR_UNKNOWN_FILE_FORMAT;
      }
    }

   Close(fh);

  }else retval = SPERR_FILE_NOT_FOUND;

 return(retval);
}

ULONG __saveds __asm SPO_StartReplay( register __a1 struct SPObjectHandle *SPObjectHandle_a1)
{
 struct SPObjectHandle *SPObjectHandle = SPObjectHandle_a1;

 ULONG retval = SPERR_NO_ERROR;

 if(!SPObjectHandle)              return(SPERR_NO_HANDLE);
 if(!SPObjectHandle->ah_STModule) return(SPERR_ILLEGAL_ACCESS);

 ST_Start();

 return(retval);
}

ULONG __saveds __asm SPO_ContinueReplay( register __a1 struct SPObjectHandle *SPObjectHandle_a1)
{
 struct SPObjectHandle *SPObjectHandle = SPObjectHandle_a1;
 ULONG retval = SPERR_NO_ERROR;

 if(!SPObjectHandle)              return(SPERR_NO_HANDLE);
 if(!SPObjectHandle->ah_STModule) return(SPERR_ILLEGAL_ACCESS);

 if(!ST_IsPlaying()) ST_Start();

 return(retval);
}

ULONG __saveds __asm SPO_FastForward( register __a1 struct SPObjectHandle *SPObjectHandle_a1)
{
 struct SPObjectHandle *SPObjectHandle = SPObjectHandle_a1;
 ULONG retval = SPERR_NO_ERROR;

 if(!SPObjectHandle)              return(SPERR_NO_HANDLE);
 if(!SPObjectHandle->ah_STModule) return(SPERR_ILLEGAL_ACCESS);

 retval = SPERR_ACTION_NOT_SUPPORTED;

 return(retval);
}

ULONG __saveds __asm SPO_FastBackward( register __a1 struct SPObjectHandle *SPObjectHandle_a1)
{
 struct SPObjectHandle *SPObjectHandle = SPObjectHandle_a1;
 ULONG retval = SPERR_NO_ERROR;

 if(!SPObjectHandle)              return(SPERR_NO_HANDLE);
 if(!SPObjectHandle->ah_STModule) return(SPERR_ILLEGAL_ACCESS);

 retval = SPERR_ACTION_NOT_SUPPORTED;

 return(retval);
}

 /* sub-routines for XPK, PP and enencoded loading */

ULONG __saveds __stdargs SPLI_ReadXPK(struct SPObjectHandle *SPObjectHandle);
ULONG __saveds __stdargs SPLI_ReadPP( struct SPObjectHandle *SPObjectHandle);
ULONG __saveds __stdargs SPLI_ReadDos(struct SPObjectHandle *SPObjectHandle);

ULONG __saveds __stdargs SPLI_Read(struct SPObjectHandle *SPObjectHandle)
{
      if(XpkBase) return( SPLI_ReadXPK(SPObjectHandle) );
 else if(PPBase)  return( SPLI_ReadPP( SPObjectHandle) );
 else             return( SPLI_ReadDos(SPObjectHandle) );

 return(N); /* dummy */
}

ULONG __saveds __stdargs SPLI_ReadXPK(struct SPObjectHandle *SPObjectHandle)
{
 ULONG           retval        = SPERR_NO_ERROR;
 UBYTE          *Buf           = N;
 ULONG           BufSize       = N;
 struct TagItem  xpk_pars        [6];
 ULONG           xpk_errorcode;
 UBYTE           xpk_errormsg    [XPKERRMSGSIZE + 1];

 if(!SPObjectHandle) return(SPERR_NO_HANDLE);

 xpk_pars[0].ti_Tag = XPK_GetOutBuf;    xpk_pars[0].ti_Data = (ULONG) &Buf;
 xpk_pars[1].ti_Tag = XPK_GetOutBufLen; xpk_pars[1].ti_Data = (ULONG) &BufSize;
 xpk_pars[2].ti_Tag = XPK_InName;       xpk_pars[2].ti_Data = (ULONG)  SPObjectHandle->ah_ReadName;
 xpk_pars[3].ti_Tag = XPK_GetError;     xpk_pars[3].ti_Data = (ULONG)  xpk_errormsg;
 xpk_pars[4].ti_Tag = XPK_PassThru;     xpk_pars[4].ti_Data = (ULONG)  TRUE;
 xpk_pars[5].ti_Tag = TAG_END;          xpk_pars[5].ti_Data = (ULONG)  N;

 xpk_errorcode  = XpkUnpack(&xpk_pars[0]);
 if(!xpk_errorcode)
  {
   SPObjectHandle->ah_STModule = ST_Module = AllocVec(BufSize, (MEMF_CLEAR|MEMF_PUBLIC|MEMF_CHIP));
   if(SPObjectHandle->ah_STModule)
    {
     SPObjectHandle->ah_STLen = ST_Len = BufSize;

     CopyMem(Buf, SPObjectHandle->ah_STModule, SPObjectHandle->ah_STLen);
    }else retval = SPERR_NO_MEMORY;
  }else retval = SPERR_DECODE_ERROR;

 if(Buf) FreeMem(Buf, BufSize);

 return(retval);
}

ULONG __saveds __stdargs SPLI_ReadPP(struct SPObjectHandle *SPObjectHandle)
{
 ULONG  retval  = SPERR_NO_ERROR;
 ULONG  code;
 UBYTE *Buf     = N;
 ULONG  BufSize = N;

 if(!SPObjectHandle) return(SPERR_NO_HANDLE);

 code = ppLoadData(SPObjectHandle->ah_ReadName, DECR_POINTER, N, (APTR) &Buf, (APTR) &BufSize, N);
 if(!code)
  {
   SPObjectHandle->ah_STModule = ST_Module = AllocVec(BufSize, (MEMF_CLEAR|MEMF_PUBLIC|MEMF_CHIP));
   if(SPObjectHandle->ah_STModule)
    {
     SPObjectHandle->ah_STLen = ST_Len = BufSize;

     CopyMem(Buf, SPObjectHandle->ah_STModule, SPObjectHandle->ah_STLen);
    }else retval = SPERR_NO_MEMORY;
  }else retval =SPERR_DECODE_ERROR;

 if(Buf) FreeMem(Buf, BufSize);

 return(retval);
}

ULONG __saveds __stdargs SPLI_ReadDos(struct SPObjectHandle *SPObjectHandle)
{
 ULONG retval = SPERR_NO_ERROR;
 BPTR  fh;
 ULONG filesize;

 if(!SPObjectHandle) return(SPERR_NO_HANDLE);

 if(fh = Open(SPObjectHandle->ah_ReadName, MODE_OLDFILE))
  {
              Seek(fh, N, OFFSET_END); 
   filesize = Seek(fh, N, OFFSET_BEGINNING); 

   SPObjectHandle->ah_STModule = ST_Module = AllocVec(filesize, (MEMF_CLEAR|MEMF_PUBLIC|MEMF_CHIP));
   if(SPObjectHandle->ah_STModule)
    {
     SPObjectHandle->ah_STLen = ST_Len = filesize;

     Read(fh, SPObjectHandle->ah_STModule, SPObjectHandle->ah_STLen);
    }else retval = SPERR_NO_MEMORY;

   Close(fh);
  }else retval = SPERR_FILE_NOT_FOUND;

 return(retval);
}
