/*
**      $VER: SP_PlaySubs.c 3.4 (22.1.97)
**
**      SPObject player API
**
**      (C) Copyright 1994-97 Andreas R. Kleinert
**      All Rights Reserved.
*/

#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  __aligned __far ST_Module   = N;
ULONG __aligned __far ST_Len      = N;
ULONG __aligned __far 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)
    {
     struct STHeader *header;


     header = (APTR) SPObjectHandle->ah_STModule;

     if(   (*((ULONG *)&header->st_ID[0]) != ID_MK)
        && (*((ULONG *)&header->st_ID[0]) != ID_MKPlus)
        && (*((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_ReadDos(struct SPObjectHandle *SPObjectHandle);

ULONG __saveds __stdargs SPLI_Read(struct SPObjectHandle *SPObjectHandle)
{
 ULONG *tstptr = N;
 ULONG  retval = SPERR_NO_ERROR;


 if(ST_Module) return(SPERR_NO_CHANNELS);

 if(!XpkBase) XpkBase = (APTR) OpenLibrary("xpkmaster.library", 2);

      if(XpkBase) retval = SPLI_ReadXPK(SPObjectHandle);
 else             retval = SPLI_ReadDos(SPObjectHandle);

 /* still packed ? */

 tstptr = (APTR) SPObjectHandle->ah_STModule;

 if(*tstptr == ID_PP20) retval = SPERR_DECODE_ERROR;
 if(*tstptr == ID_XPKF) retval = SPERR_DECODE_ERROR;

 return(retval);
}

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[0];

 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)
  {
   if(Buf && BufSize)
    {
     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;
  }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);

   if(filesize)
    {
     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;
    }else retval = SPERR_DECODE_ERROR;

   Close(fh);
  }else retval = SPERR_FILE_NOT_FOUND;

 return(retval);
}
