/* ->c.pic */
/* picture box handling Draw code */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "os.h"
#include "bbc.h"
#include "h.sprite"
#include "h.wimp"
#include "h.werr"
#include "h.flex"

#include "h.DrawLevel0"

#include "h.wos"
#include "h.ram"
#include "h.file"
#include "h.strdef"
#include "h.trans"

#include "h.pic"



/****************************************************************************/
/*                              Render a picture box                        */



void picrend(wimp_box * box,Draw_diag diag,wimp_redrawstr * redrawstr)
{
 Draw_redrawstr r;
 double scale=1.0;
 double sx1=1.0;
 double sx2=1.0;
 Draw_error e;
 int gx0;
 int gy0;
 int gx1; 
 int gy1;
 int ox;
 int oy;


 if(!diag.length || !diag.data) return;      /* no buffer do nothing */


 ox=redrawstr->box.x0-redrawstr->scx;
 oy=redrawstr->box.y1-redrawstr->scy;


 gx0=ox+box->x0;  
 gy0=oy-box->y0;  
 gx1=ox+box->x1;  
 gy1=oy-box->y1;


 if(redrawstr->g.x0>gx0) r.g.x0=redrawstr->g.x0;
 else                    r.g.x0=gx0;

 if(redrawstr->g.x1<gx1) r.g.x1=redrawstr->g.x1;
 else                    r.g.x1=gx1;

 if(redrawstr->g.y0>gy0) r.g.y0=redrawstr->g.y0;
 else                    r.g.y0=gy0;

 if(redrawstr->g.y1<gy1) r.g.y1=redrawstr->g.y1;
 else                    r.g.y1=gy1;


 Draw_queryBox(diag, &r.box, TRUE);

 if(!(r.box.x1-r.box.x0)) return;
 if(!(r.box.y1-r.box.y0)) return;


 sx1=((double)(gx1-gx0))/((double)(r.box.x1 -r.box.x0 ));
 sx2=((double)(gy1-gy0))/((double)(r.box.y1 -r.box.y0 ));
 if(sx1>sx2) scale=sx2; 
 else        scale=sx1;


/* r.scx = (r.box.x0 - gx0) + (int)((double)r.box.x0*scale); */
 r.scx = (r.box.x0 - gx0) + (int)((double)r.box.x0*sx1); 
                                             /* (ox+osunits(box->x)); */
/* r.scy = (r.box.y1 - gy0) + (int)((double)r.box.y0*scale);  */


 r.scy = (r.box.y1 - gy0) + (int)((double)r.box.y0*sx2); 
                                     /* (oy-osunits(yps+box->y+box->h)); */


 if (Draw_verify_diag(diag, &e))
 {
  /* Draw a box and set the clipping region */

  bbc_gwindow(r.g.x0,r.g.y0,r.g.x1-deltax,r.g.y1-deltay);

/*  if(!Draw_render_diag(diag,&r,scale,scale,&e))  */
  if(!Draw_render_diag(diag,&r,sx1,sx2,&e)) 
  {
   if (e.type == DrawOwnError)
         werr(0,"render failed: code %d at %d\n",
                e.err.draw.code, e.err.draw.location);
      else
        werr(0,"render failed: os error %s\n", e.err.os.errmess);

   /*   vecopen();
      vecclose(); */
    }
  }
  else
  {
    werr(0,"verify failed: code %d at %d\n",
                     e.err.draw.code, e.err.draw.location);
   /* vecopen();
    vecclose(); */
  }

 bbc_gwindow(redrawstr->g.x0,redrawstr->g.y0,
                                redrawstr->g.x1-deltax,redrawstr->g.y1-deltay);
}




/***************************************************************************/
/* boot draw file code                                                     */

void picinit(void)
{
 Draw_registerMemoryFunctions(flex_alloc,flex_extend,flex_free);
}


/*****************************************************************************/


#define DRAWWX 16
#define DRAWWORDS 16


/*
void test(void)
{
 int paltab[16];
 unsigned int c1;
 int target;

  paltab[0]=0x0;
  paltab[1]=0x10101000;
  paltab[2]=0x20202000;
  paltab[3]=0x30303000;
  paltab[4]=0x4000;
  paltab[5]=0x10105000;
  paltab[6]=0x20206000;
  paltab[7]=0x30307000;
  paltab[8]=0x40000000;
  paltab[9]=0x50101000;
  paltab[10]=0x60202000;
  paltab[11]=0x70303000;
  paltab[12]=0x40004000;
  paltab[13]=0x50105000;
  paltab[14]=0x60206000;
  paltab[15]=0x70307000;



  for(target=0;target<256;target++)
  {
       c1=paltab[(target & 0xF)];

       if(target & 0x10) c1|=0x8000;
       else              c1&=~0x8000;

       if(target & 0x20) c1|=0x400000;
       else              c1&=~0x400000;

       if(target & 0x40) c1|=0x800000;
       else              c1&=~0x800000;

       if(target & 0x80) c1|=0x80000000;
       else              c1&=~0x80000000;

       c1&=0xF0F0F000;
       c1|=(c1>>4);


   if(((c1>>8) & 0xFF)==((c1>>16) & 0xFF) &&
      ((c1>>8) & 0xFF)==((c1>>24) & 0xFF))

   printf("target=%d col=%x\n",target,c1);

  }

}

 */










static void genpalette(int spbpp,int * palentries,int * paltab)
{
 if(spbpp==3)
 {
  paltab[0]=0x0;
  paltab[1]=0x10101000;
  paltab[2]=0x20202000;
  paltab[3]=0x30303000;
  paltab[4]=0x4000;
  paltab[5]=0x10105000;
  paltab[6]=0x20206000;
  paltab[7]=0x30307000;
  paltab[8]=0x40000000;
  paltab[9]=0x50101000;
  paltab[10]=0x60202000;
  paltab[11]=0x70303000;
  paltab[12]=0x40004000;
  paltab[13]=0x50105000;
  paltab[14]=0x60206000;
  paltab[15]=0x70307000;
  *palentries=16;
 }
 else
 if(spbpp==2)
 {
  paltab[0]=0xffffff00;
  paltab[1]=0xdddddd00;
  paltab[2]=0xbbbbbb00;
  paltab[3]=0x99999900;
  paltab[4]=0x77777700;
  paltab[5]=0x55555500;
  paltab[6]=0x33333300;
  paltab[7]=0x00000000;
  paltab[8]=0x99440000;
  paltab[9]=0x00eeee00;
  paltab[10]=0x00cc0000;
  paltab[11]=0x0000dd00;
  paltab[12]=0xbbeeee00;
  paltab[13]=0x00885500;
  paltab[14]=0x00bbff00;
  paltab[15]=0xffbb0000;
  *palentries=16;
 }
 else
 if(spbpp==1)
 {
  paltab[0]=0xffffff00;
  paltab[1]=0xdddddd00;
  paltab[2]=0x99999900;
  paltab[3]=0x00000000;
  *palentries=4;
 }
 else
 {
  paltab[0]=0xffffff00;
  paltab[1]=0x00000000;
  *palentries=2;
 }
}




int savesprite(char * filename,Draw_diag * diag)
{
 int    nosprites=1;
 int    foffset=16;
 int    firstfree;
 int    spritelen;
 char * buff;
 int    realfile;
 FILE * fp;

 fp=ropen(filename,"wb");
 if(!fp) return(0);
 
 buff=diag->data;

 spritelen=*((int*)(buff+DRAWWX*4));
 firstfree=spritelen+16;

 rwrite(&nosprites,1,sizeof(int),fp);
 rwrite(&foffset,1,sizeof(int),fp);
 rwrite(&firstfree,1,sizeof(int),fp);

 rwrite(buff+DRAWWX*4,spritelen,1,fp);

 realfile=!ramfp(fp);

 rclose(fp);
 if(realfile) setftype(filename,SPRITE);

 return(1);
}






int savesubsprite(char * filename,Draw_diag * diag,
                                          int xmin,int xmax,int ymin,int ymax)
{
 int           nosprites=1;
 int           foffset=16;
 int           firstfree;
 int           spritelen;
 char *        buff;
 int           realfile;
 FILE *        fp;
 int           spmode;
 int           spdx;
 int           spdy;
 int           spwidth;
 int           spheight;
 int           spbpp;
 int           spbitmask;
 sprite_id     sid;
 sprite_info   sinfo;
 int           xpix;
 int           ypix;
 int           palentries;
 int           paltab[16];
 int           pal[32];
 sprite_header shdr;
 int           i;
 int           bytewidth;
 sprite_header * srcspa;
 char        * srcspimage;
 int           srcspbitwidth;
 int           srcspbytewidth;
 char        * p;


 buff=diag->data;

 sid.s.addr=(sprite_area *)(buff+DRAWWORDS*4);
 sid.tag=sprite_id_addr;
 sprite_readsize((sprite_area *)(buff+DRAWWORDS*4),&sid,&sinfo);

 spwidth=sinfo.width;
 spheight=sinfo.height;
 spmode=sinfo.mode;

 getdeltas(spmode,&spdx,&spdy);
 getbpp(spmode,&spbpp,&spbitmask);
 genpalette(spbpp,&palentries,paltab);

 srcspa=(sprite_header *)(buff+DRAWWORDS*4);
 srcspimage=(buff+DRAWWORDS*4)+srcspa->image;
 srcspbitwidth=srcspa->width*32+srcspa->rbit;
 srcspbytewidth=(srcspa->width+1)*4;

/* xmin/=spdx;
 xmax/=spdx;
 ymin/=spdy;
 ymax/=spdy; */

 ymin=-ymin;
 ymax=-ymax;

/* dprintf(0,"xmin=%d xmax=%d ymin=%d ymax=%d",xmin,xmax,ymin,ymax); */

 xpix=xmax-xmin;
 ypix=-(ymax-ymin);

 bytewidth=((xpix*(1<<spbpp)+31) & (~31))>>3;


/* dprintf(5,"bytewidth=%d spbpp=%d xpix=%d",bytewidth,spbpp,xpix); */


 spritelen=sizeof(sprite_header)+2*palentries*4+bytewidth*ypix;

 shdr.next=spritelen;
 memset(shdr.name,0,12);
 strcpy(shdr.name,transtoken("selection"));
 shdr.width=(bytewidth/4)-1;
 shdr.height=ypix-1;
 shdr.lbit=0;
 shdr.rbit=(xpix*(1<<spbpp)-1) % 32; 
 shdr.image=sizeof(sprite_header)+2*palentries*4;
 shdr.mask=shdr.image;
 shdr.mode=spmode;

 for(i=0;i<palentries;i++)
 {
  pal[i*2]=pal[i*2+1]=paltab[i];
 }

 fp=ropen(filename,"wb");
 if(!fp) return(0);

 firstfree=spritelen+16;

 rwrite(&nosprites,1,sizeof(int),fp);
 rwrite(&foffset,1,sizeof(int),fp);
 rwrite(&firstfree,1,sizeof(int),fp);
 rwrite(&shdr,1,sizeof(sprite_header),fp);
 rwrite(pal,2*palentries,sizeof(int),fp);

 for(i=0;i<ypix;i++)
 {
  p=srcspimage+(ymax+i)*srcspbytewidth+(xmin>>(3-spbpp));
  rwrite(p,1,bytewidth,fp);
 }

 realfile=!ramfp(fp);

 rclose(fp);
 if(realfile) setftype(filename,SPRITE);
 return(1);
}





static void dummysprite(int * buff,int size)
{
 char * p, * q;
 int h,w,xhi,yhi,mode,dx,dy;
 sprite_id   sid;
 sprite_info sinfo;

 /* sprite at offset 64 */

 sid.s.addr=(sprite_area *)(buff+DRAWWORDS);
 sid.tag=sprite_id_addr;
 sprite_readsize((sprite_area *)(buff+DRAWWORDS),&sid,&sinfo);

 w=sinfo.width;
 h=sinfo.height;
 mode=sinfo.mode;

/* dprintf(0,"width=%d height=%d mode=%d",w,h,mode); */

 getdeltas(mode,&dx,&dy);

 xhi=w*256*dx;                         /* draw units */
 yhi=h*256*dy;

 strcpy((char *)buff,"Draw");
 *(buff+1)=201;
 *(buff+2)=0;
 p=(char*)(buff+3);
 q=p+12;
 strcpy(p,"ArcDraw");
 p+=strlen(p);
 for(;p<q;p++) *p=32;

 *(buff+6)=0;
 *(buff+7)=0;
 *(buff+8)=xhi;
 *(buff+9)=yhi;

 *(buff+10)=5;
 *(buff+11)=size;

 *(buff+12)=0;
 *(buff+13)=0;
 *(buff+14)=xhi;
 *(buff+15)=yhi;
}




os_error * createsprite(Draw_diag * diag,int mode,int xpix,int ypix)
{
 os_error      * ep;
 int             sshift;
 int             bytes;
 int             fudge;
 int             spritelen;
 char          * buff;
 sprite_header * shdr;
 int             palentries;
 int             paltab[16];
 int             spdx;
 int             spdy;
 int             spbpp;
 int             spbitmask;
 int             bytewidth;
 int           * pal;
 int             i;


 getdeltas(mode,&spdx,&spdy);
 getbpp(mode,&spbpp,&spbitmask);

 genpalette(spbpp,&palentries,paltab);

 sshift=DRAWWORDS*4;
 bytewidth=((xpix*(1<<spbpp)+31) & (~31))>>3;

 spritelen=sizeof(sprite_header)+2*palentries*4+
             bytewidth*ypix;


 fudge=(4-((spritelen+sshift) & 0x3)) & 0x3;
 bytes=fudge+spritelen+sshift;


 if(!diag->data) ep=flex_alloce((flex_ptr)&(diag->data),bytes);
 else            ep=flex_extende((flex_ptr)&(diag->data),bytes);

 if(!ep)
 {
  buff=diag->data;

  shdr=(sprite_header*)(buff+sshift);
  pal=(int*)(buff+sshift+sizeof(sprite_header));

  shdr->next=sizeof(sprite_header)+2*palentries*4+bytewidth*ypix;
  memset(shdr->name,0,12);
  strcpy(shdr->name,"fax");
  shdr->width=(bytewidth/4)-1;
  shdr->height=ypix-1;
  shdr->lbit=0;
  shdr->rbit=(xpix*(1<<spbpp)-1) % 32; 
  shdr->image=sizeof(sprite_header)+2*palentries*4;
  shdr->mask=shdr->image;
  shdr->mode=mode;

  memset(buff+sshift+shdr->image,spbpp==3?255:0,bytewidth*ypix);

  for(i=0;i<palentries;i++)
  {
   pal[i*2]=pal[i*2+1]=paltab[i];
  }

  dummysprite((int*)buff,spritelen+fudge+24); 

  diag->length=bytes;
 }

 return(ep);
}


/*****************************************************************************/

static char   * spimage;
static int      spbitwidth;
static int      spbytewidth;
static int      spheight;
static int      spwidth;
static int      spxpos;
static int      spypos;
static iblock   ximage;
static int      imagexpix;
static int      imageypix;
static int      imagexpos;
static int      imageypos;
static int      spbpp;
static int      spbitinc;
static int      spbitmask;
static int      spmode;



static void fillhorizstrip(void)
{
 int    liney;
 int    oldliney;
 int    y;
 int    y1;
 char * p;
 char * q;


 if(ximage.ysmul>ximage.ysdiv)
 {
  oldliney=liney=0;

  for(y=0;y<imageypix;y++)
  {
   oldliney=liney;

   liney=y*ximage.ysmul;
   liney/=ximage.ysdiv;

   for(y1=oldliney+1;y1<liney;y1++)
   {
    p=spimage+oldliney*spbytewidth;
    q=spimage+y1*spbytewidth;
    memcpy(q,p,spbytewidth);
   }
  }

  for(y1=oldliney+1;y1<spheight;y1++)
  {
   p=spimage+oldliney*spbytewidth;
   q=spimage+y1*spbytewidth;
   memcpy(q,p,spbytewidth);
  }
 }
}



static char masktab[4]={0x1,0x3,0x7,0xFF};
static char coordmasktab[4]={0x7,0x3,0x1,0x0};

static void fillvertstrip2(void)
{
 int    xpix;
 int    oldxpix;
 int    y;
 int    x1;
 int    y1;
 char * p;
 char * q;
 char * s;
 int    pshift;
 int    qshift;
 int    mask;
 int    mshift;
 int    mult;
 int    cmask;


 mask=masktab[spbpp];
 cmask=coordmasktab[spbpp];
 mshift=3-spbpp;
 mult=1<<spbpp;

 if(ximage.xsmul>ximage.xsdiv)
 {
  oldxpix=xpix=0;

  for(y=0;y<imageypix;y++)
  {
   oldxpix=xpix;

   xpix=y*ximage.xsmul;
   xpix/=ximage.xsdiv;

   q=spimage;
   q+=(xpix>>mshift);
   qshift=(xpix & cmask)*mult;

   for(x1=oldxpix+1;x1<xpix;x1++)
   {
    p=spimage;
    p+=(x1>>mshift);
    pshift=(x1 & cmask)*mult;
    s=q;

    for(y1=0;y1<spheight;y1++)
    {
     *p|=(((*s)>>qshift)&mask)<<pshift;
     s+=spbytewidth;
     p+=spbytewidth;
    }
   }
  }
 }
}







static void fillvertstrip1(void)
{
 int    xpix;
 int    oldxpix;
 int    y;
 int    x1;
 int    y1;
 char * p;
 char * q;
 char * s;
 int    pshift;
 int    qshift;
 int    mask;
 int    mshift;
 int    mult;
 int    cmask;


 mask=masktab[spbpp];
 cmask=coordmasktab[spbpp];
 mshift=3-spbpp;
 mult=1<<spbpp;

 if(ximage.xsmul>ximage.xsdiv)
 {
  oldxpix=xpix=spwidth;

  for(y=0;y<imageypix;y++)
  {
   oldxpix=xpix;

   xpix=imageypix-1-y;

   xpix*=ximage.xsmul;
   xpix/=ximage.xsdiv;

   q=spimage;
   q+=(xpix>>mshift);
   qshift=(xpix & cmask)*mult;

   for(x1=oldxpix-1;x1>xpix;x1--)
   {
    p=spimage;
    p+=(x1>>mshift);
    pshift=(x1 & cmask)*mult;
    s=q;

    for(y1=0;y1<spheight;y1++)
    {
     *p|=(((*s)>>qshift)&mask)<<pshift;
     s+=spbytewidth;
     p+=spbytewidth;
    }
   }
  }
 }
}








static void writehorizstrip(int spxpos,int spypos,int length)
{
 char * p;
 int    i;
 int    rem;
 int    code;
 int    shift;

 rem=(spxpos*ximage.xsmul) % ximage.xsdiv;
 spxpos*=ximage.xsmul;
 spxpos/=ximage.xsdiv;
 spypos*=ximage.ysmul;
 spypos/=ximage.ysdiv;

 if(spbpp==0)
 {
  p=spimage+spypos*spbytewidth+(spxpos>>3);

  for(i=0;i<length;i++)
  {
   rem+=ximage.xsmul;
   while(rem>=ximage.xsdiv)
   {
    *p|=(1<<(spxpos & 0x7));
    rem-=ximage.xsdiv;
    spxpos++;
    if(!(spxpos & 0x7)) p++;
   }
  }
 }
 else
 if(spbpp==1)
 {
  p=spimage+spypos*spbytewidth+(spxpos>>2);
  shift=(spxpos & 0x3)*2;

  for(i=0;i<length;i++)
  {
   rem+=ximage.xsmul;

   while(1)
   {
    code=(*p>>shift) & 0x3;
    code+=spbitinc;
    if(code>3)code=3;
    *p=(*p & (~(3<<shift)))+(code<<shift);

    if(rem>=ximage.xsdiv)
    {
     rem-=ximage.xsdiv;
     spxpos++;
     shift=spxpos & 0x3;
     shift*=2;
     if(!shift) p++;
    }

    if(rem<ximage.xsdiv) break;
   }
  }
 }
 else
 if(spbpp==2)
 {
  p=spimage+spypos*spbytewidth+(spxpos>>1);
  shift=(spxpos & 0x1)*4;

  for(i=0;i<length;i++)
  {
   rem+=ximage.xsmul;

   while(1)
   {
    code=(*p>>shift) & 0x7;
    code+=spbitinc;
    if(code>7)code=7;
    *p=(*p & (~(7<<shift)))+(code<<shift);

    if(rem>=ximage.xsdiv)
    {
     rem-=ximage.xsdiv;
     spxpos++;
     shift=spxpos & 0x1;
     shift*=4;
     if(!shift) p++;
    }

    if(rem<ximage.xsdiv) break;
   }
  }
 }
 else
 {
  p=spimage+spypos*spbytewidth+spxpos;

  for(i=0;i<length;i++)
  {
   rem+=ximage.xsmul;

   while(1)
   {
    code=*p;
    if(code>=252) code=255-code;
    else
    if(code>=208) code=211-code+4;
    else
    if(code>=44)  code=47-code+8;
    else          code=code+12;

    code+=spbitinc;
    if(code>15) code=15;

    if(code>=12) code=15-code;
    else
    if(code>=8)  code=11-code+44;
    else
    if(code>=4)  code=7-code+208;
    else         code=3-code+252;

    *p=code;
  
    if(rem>=ximage.xsdiv)
    {
     rem-=ximage.xsdiv;
     p++;
    }

    if(rem<ximage.xsdiv) break;
   }
  }
 }
}





static void writevertstrip(int spxpos,int spypos,int length)
{
 char * p;
 int    i;
 int    rem;
 int    code;
 int    shift;


 rem=(spxpos*ximage.xsmul) % ximage.xsdiv;
 spxpos*=ximage.xsmul;
 spxpos/=ximage.xsdiv;
 spypos*=ximage.ysmul;
 spypos/=ximage.ysdiv;

 if(spbpp==0)
 {
  p=spimage+spypos*spbytewidth+(spxpos>>3);

  for(i=0;i<length;i++)
  {
   rem+=ximage.ysmul;
   while(rem>=ximage.ysdiv)
   {
    *p|=(1<<(spxpos & 0x7));
    rem-=ximage.ysdiv;
    p+=spbytewidth;
   }
  }
 }
 else
 if(spbpp==1)
 {
  p=spimage+spypos*spbytewidth+(spxpos>>2);
  shift=(spxpos & 0x3)*2;

  for(i=0;i<length;i++)
  {
   rem+=ximage.ysmul;

   while(1)
   {
    code=(*p>>shift) & 0x3;
    code+=spbitinc;
    if(code>3)code=3;
    *p=(*p & (~(3<<shift)))+(code<<shift);

    if(rem>=ximage.ysdiv)
    {
     rem-=ximage.ysdiv;
     p+=spbytewidth;
    }

    if(rem<ximage.ysdiv) break;
   }
  }
 }
 else
 if(spbpp==2)
 {
  p=spimage+spypos*spbytewidth+(spxpos>>1);
  shift=(spxpos & 0x1)*4;

  for(i=0;i<length;i++)
  {
   rem+=ximage.ysmul;

   while(1)
   {
    code=(*p>>shift) & 0x7;
    code+=spbitinc;
    if(code>7)code=7;
    *p=(*p & (~(7<<shift)))+(code<<shift);

    if(rem>=ximage.ysdiv)
    {
     rem-=ximage.ysdiv;
     p+=spbytewidth;
    }

    if(rem<ximage.ysdiv) break;
   }
  }
 }
 else
 {
  p=spimage+spypos*spbytewidth+spxpos;

  for(i=0;i<length;i++)
  {
   rem+=ximage.xsmul;

   while(1)
   {
    code=*p;
    if(code>=252) code=255-code;
    else
    if(code>=208) code=211-code+4;
    else
    if(code>=44)  code=47-code+8;
    else          code=code+12;

    code+=spbitinc;
    if(code>15) code=15;

    if(code>=12) code=15-code;
    else
    if(code>=8)  code=11-code+44;
    else
    if(code>=4)  code=7-code+208;
    else         code=3-code+252;

    *p=code;

    if(rem>=ximage.xsdiv)
    {
     rem-=ximage.xsdiv;
     p+=spbytewidth;
    }

    if(rem<ximage.xsdiv) break;
   }
  }
 }
}




void writeblackrun(int length)
{

 if((imagexpos+length)>=imagexpix)
 {
  length=imagexpix-imagexpos-1;
  if(!length) return;
 }


 if(ximage.mirrorlr)
 {
  spxpos=imagexpix-1-imagexpos;
  if(ximage.mirrorud) spypos=imageypix-imageypos-1;
  else                spypos=imageypos;

  if(ximage.rotate)
  {
   if(ximage.plus90)
          writevertstrip(imageypix-1-spypos,spxpos-length,length);
   else   writevertstrip(spypos,imagexpix-1-spxpos,length);

  }
  else    writehorizstrip(spxpos-length,spypos,length);
 }
 else
 {
  spxpos=imagexpos;
  if(ximage.mirrorud) spypos=imageypix-imageypos-1;
  else                spypos=imageypos;

  if(ximage.rotate)
  {
   if(ximage.plus90) 
          writevertstrip(imageypix-1-spypos,spxpos,length);
   else   writevertstrip(spypos,imagexpix-1-spxpos-length,length);
  }
  else               writehorizstrip(spxpos,spypos,length);
 }

 imagexpos+=length;

}



/* just skip writing point */

void writewhiterun(int length)
{
 if((imagexpos+length)>=imagexpix) length=imagexpix-imagexpos-1;
 imagexpos+=length;
}


void writenewrow(void)
{
 imagexpos=0;
 if(imageypos<(imageypix-1)) imageypos++;
}




void writestart(Draw_diag * diag,iblock * image,int xpix,int ypix)
{
 sprite_header * spa;
 int             totmul;
 int             totdiv;

 ximage=*image;
 imagexpix=xpix;
 imageypix=ypix;
 imageypos=0;
 imagexpos=0;


 spa=(sprite_header*)(diag->data+DRAWWORDS*4);

 spmode=spa->mode;
 getbpp(spmode,&spbpp,&spbitmask);

 spbitwidth=spa->width*32+spa->rbit;
 spwidth=spbitwidth/(1<<spbpp);

 spbytewidth=(spa->width+1)*4;
 spheight=spa->height+1;
 spimage=diag->data+(spa->image+DRAWWORDS*4);

 totmul=ximage.xsmul*ximage.ysmul;
 totdiv=ximage.xsdiv*ximage.ysdiv;

 if(spbpp==0) spbitinc=1;
 else
 if(spbpp==1)
 {
  spbitinc=4;
  spbitinc*=totmul;
  spbitinc/=totdiv;
  if(!spbitinc) spbitinc=1;
  else
  if(spbitinc>4) spbitinc=4;
 }
 else
 if(spbpp==2)
 {
  spbitinc=8;
  spbitinc*=totmul;
  spbitinc/=totdiv;
  if(!spbitinc) spbitinc=1;
  else
  if(spbitinc>8) spbitinc=8;
 }
 else
 {
  spbitinc=16;
  spbitinc*=totmul;
  spbitinc/=totdiv;
  if(!spbitinc) spbitinc=1;
  else
  if(spbitinc>16) spbitinc=16;
 }
}



void writeend(void)
{
 if(ximage.rotate) 
 {
  if(ximage.plus90) fillvertstrip1();
  else              fillvertstrip2();
 }
 else              fillhorizstrip();
}


