
 /* SV_WriteSubs.c
    - Functions for Writing of SVO Files -
    (c) 1990-93 by Andreas R. Kleinert
    Last changes : 19.12.1993
 */

#include "svobject.h"


 /* PUBLIC functions */

ULONG __saveds __asm SVO_Write( register __a1 struct SVObjectHandle *SVObjectHandle_a1);


long __saveds __stdargs SetPalette(struct Screen *screen, struct SVObjectHandle *SVObjectHandle);

/* *************************************************** */
/* *						     * */
/* * SVO_Write : ...                                 * */
/* *						     * */
/* *************************************************** */

ULONG __saveds __asm SVO_Write( register __a1 struct SVObjectHandle *SVObjectHandle_a1)
{
 struct SVObjectHandle *SVObjectHandle = SVObjectHandle_a1;

 struct RastPort *rp;
 struct BitMap	 *bm;
 struct ViewPort *vp;
 ULONG i, j, actcolors, packed, linebytes;
 BYTE *planeptr, *buffer, *bufferptr;
 ULONG depth, rows, interleaved = FALSE;
 ULONG retval = SVERR_NO_ERROR;

 char filename [256], filename_svo [256];

 if(!SVObjectHandle)                              return(SVERR_NO_HANDLE);
 if(!SVObjectHandle->ah_WriteScreen)              return(SVERR_ILLEGAL_ACCESS);
 if(SVObjectHandle->ah_Medium != AKO_MEDIUM_DISK) return(SVERR_ACTION_NOT_SUPPORTED);

 if(strlen(SVObjectHandle->ah_WriteName) > 4)
  {
   if(!stricmp(&SVObjectHandle->ah_WriteName[strlen(SVObjectHandle->ah_WriteName)-4], ".svo"))
    {
     strcpy(filename_svo, SVObjectHandle->ah_WriteName);
     strcpy(filename,     SVObjectHandle->ah_WriteName);
     filename[strlen(filename)-4] = (char) 0;
    }else
    {
     strcpy(filename,     SVObjectHandle->ah_WriteName);
     strcpy(filename_svo, SVObjectHandle->ah_WriteName);
     strcat(filename_svo, ".svo");
    }
  }else
  {
   strcpy(filename_svo, SVObjectHandle->ah_WriteName);
   strcat(filename_svo, ".svo");
   strcpy(filename,     SVObjectHandle->ah_WriteName);
  }

 SVObjectHandle->ah_filehandle_dest = Open(filename_svo, MODE_NEWFILE);
 if(!SVObjectHandle->ah_filehandle_dest) return(SVERR_NO_FILE);

 SVObjectHandle->ah_filehandle_dest2 = Open(filename, MODE_NEWFILE);
 if(!SVObjectHandle->ah_filehandle_dest2) return(SVERR_NO_FILE);

 SVObjectHandle->ah_ramhandle = AIM_GetMemList();
 if(!SVObjectHandle->ah_ramhandle) return(SVERR_NO_MEMORY);

 SVObjectHandle->ah_SVOHeader = AllocVec(sizeof(struct SVOHeader), (MEMF_CLEAR|MEMF_PUBLIC));
 if(!SVObjectHandle->ah_SVOHeader) return(SVERR_NO_MEMORY);

 rows  = SVLI_GetBitMapHeight(SVObjectHandle->ah_WriteScreen);

 rp	     = (struct RastPort *) &(SVObjectHandle->ah_WriteScreen->RastPort);
 bm	     = (struct BitMap   *) SVObjectHandle->ah_WriteScreen->RastPort.BitMap;
 vp	     = (struct ViewPort *) &(SVObjectHandle->ah_WriteScreen->ViewPort);
 depth       = SVLI_GetBitMapDepth(SVObjectHandle->ah_WriteScreen);
 actcolors   = ColorAcc(depth);
 interleaved = SVLI_CheckInterleaved(SVObjectHandle->ah_WriteScreen);

 /* init header */

 strcpy(SVObjectHandle->ah_SVOHeader->svo_ID, SVO_ID);

 SVObjectHandle->ah_SVOHeader->svo_PixelBits      = 1;
 SVObjectHandle->ah_SVOHeader->svo_PixelDepth     = depth;
 
 SVObjectHandle->ah_SVOHeader->svo_LeftEdge   = SVObjectHandle->ah_WriteScreen->LeftEdge;
 SVObjectHandle->ah_SVOHeader->svo_TopEdge    = SVObjectHandle->ah_WriteScreen->TopEdge;
 SVObjectHandle->ah_SVOHeader->svo_Width      = SVObjectHandle->ah_WriteScreen->Width;
 SVObjectHandle->ah_SVOHeader->svo_Height     = SVObjectHandle->ah_WriteScreen->Height;
 
 SVObjectHandle->ah_SVOHeader->svo_Depth      = depth;

 SVObjectHandle->ah_SVOHeader->svo_ViewMode16 = (UWORD) SVObjectHandle->ah_WriteScreen->ViewPort.Modes & FLAGMASK_13;
 SVObjectHandle->ah_SVOHeader->svo_ViewMode32 = (ULONG) GetVPModeID(&SVObjectHandle->ah_WriteScreen->ViewPort) & FLAGMASK;

 SetPalette(SVObjectHandle->ah_WriteScreen, SVObjectHandle);

 if(interleaved) SVObjectHandle->ah_SVOHeader->svo_BytesPerLine = bm->BytesPerRow/depth;
  else           SVObjectHandle->ah_SVOHeader->svo_BytesPerLine = bm->BytesPerRow;


 planeptr = (BYTE *) N;

 buffer = AIM_AllocMemEntry(SVObjectHandle->ah_ramhandle, SVLI_GetBodySize(SVObjectHandle->ah_WriteScreen), (MEMF_CLEAR|MEMF_PUBLIC));

 bufferptr = buffer;

 if(!buffer) return(SVERR_NO_MEMORY);

 linebytes = bm->BytesPerRow;

 if(interleaved)
  {
   for(i=0; i<depth; i++)
    {
     for(j=0; j<rows; j++)
      {
       CopyMem(bm->Planes[0]+(i*linebytes/depth)+(j*linebytes), bufferptr, linebytes/depth);
       bufferptr += (linebytes/depth);
      }
    }
  }else
  {
   for(j=0;j<depth;j++)
    {
     CopyMem(bm->Planes[j], bufferptr, rows*linebytes);
     bufferptr += (rows*linebytes);
    }
  }

 packed = SVLI_GetBodySize(SVObjectHandle->ah_WriteScreen);

 Write(SVObjectHandle->ah_filehandle_dest,  SVObjectHandle->ah_SVOHeader, SVOHEADER_SIZE);
 Write(SVObjectHandle->ah_filehandle_dest2,                       buffer,         packed);

 return(retval);
}

/* *************************************************** */
/* *						     * */
/* * SetPalette : ...                                * */
/* *						     * */
/* *************************************************** */

long __saveds __stdargs SetPalette(struct Screen *screen, struct SVObjectHandle *SVObjectHandle)
{
 struct ViewPort *vp;
 struct BitMap	 *bm;
 struct ColorMap *cm;
 long i, actcolors;

 if(!SVObjectHandle && !screen) return(FALSE);

 vp        = (struct ViewPort *) &(screen->ViewPort);
 bm	   = (struct BitMap   *) screen->RastPort.BitMap;
 cm        = (struct ColorMap *) vp->ColorMap; 
 actcolors = ColorAcc(bm->Depth);

 for(i=0;i<actcolors;i++)
  {
   if(OS_VER < 39)
    {
     /* Standard / ECS "4 Bit of 12 Bit" Colors (RGB4) */

     ULONG color12;

     color12 = (ULONG) GetRGB4(cm, i);

     SVObjectHandle->ah_SVOHeader->svo_Colors[i][0] = ((color12 >> 8)&15) << 4;
     SVObjectHandle->ah_SVOHeader->svo_Colors[i][1] = ((color12 >> 4)&15) << 4;
     SVObjectHandle->ah_SVOHeader->svo_Colors[i][2] = ( color12      &15) << 4;
    }else
    {
     /* AGA "8 Bit of 32 Bit" Colors (RGB32) */

     ULONG color96 [3];

     GetRGB32(cm, i, 1, &color96[0]);

     SVObjectHandle->ah_SVOHeader->svo_Colors[i][0] = (UBYTE) (color96[0] & 0xFF);
     SVObjectHandle->ah_SVOHeader->svo_Colors[i][1] = (UBYTE) (color96[1] & 0xFF);
     SVObjectHandle->ah_SVOHeader->svo_Colors[i][2] = (UBYTE) (color96[2] & 0xFF);
    }
  }

 return(TRUE);
}
