/** VGB: portable GameBoy emulator ***************************/
/**                                                         **/
/**                        Common.h                         **/
/**                                                         **/
/** This file contains parts of the drivers which are       **/
/** common for both Unix/X and MSDOS.                       **/
/**                                                         **/
/** Copyright (C) Marat Fayzullin 1995                      **/
/**     You are not allowed to distribute this software     **/
/**     commercially. Please, notify me, if you make any    **/   
/**     changes to this file.                               **/
/*************************************************************/


/****************************************************************/
/*** Refresh a line.                                          ***/
/****************************************************************/
void RefreshLine(byte Y)
{
/*	printf("XBuf1=%x\n",XBuf);
	StartDisplay(Y);
	printf("XBuf2=%x\n",XBuf);
*/

  register byte Offset,Mask,*P,*T,*R,D0,D1,X1,X2;

  R=XBuf+WIDTH*Y;
    
  if((LCDCONT&0x81)!=0x81)
    for(X1=0;X1<WIDTH;X1++) *R++=Palette[0];
  else
  {
    Offset=Y+SCROLLY;
    T=BgdTab+((word)(Offset&0xF8)<<2);
    Offset=(Offset&0x07)<<1;
      
    D0=*(T+(SCROLLX>>3));
    if(~LCDCONT&0x10) D0+=0x80;
    P=ChrGen+(D0<<4)+Offset;
    D0=*P++;D1=*P;Mask=0x80>>(SCROLLX&0x07);   
  
    X1=SCROLLX;X2=SCROLLX+WIDTH;
    while(X1!=X2)
    {
      *R=Palette[BPal[D0&Mask? (D1&Mask? 3:1):(D1&Mask? 2:0)]];
      R++;X1++;
      if(!(Mask>>=1))
      {
        D0=*(T+(X1>>3));
        if(~LCDCONT&0x10) D0+=0x80;
        P=ChrGen+(D0<<4)+Offset;
        D0=*P++;D1=*P;Mask=0x80;
      }
    }
  }
      
  X1=WNDPOSX-7;X2=LCDCONT&0x02;
  if(((LCDCONT&0xA0)==0xA0)&&(WNDPOSY<Y)&&(X1<WIDTH))
  {
    R-=WIDTH-X1;
    Offset=Y-WNDPOSY;
    T=WndTab+((word)(Offset&0xF8)<<2);
    Offset=(Offset&0x07)<<1;
     
    D0=*T+0x80;
    P=RAM+0x8800+((word)D0<<4)+Offset;
    D0=*P++;D1=*P;Mask=0x80;   
  
    for(;X1<WIDTH;X1++,R++)
    {
      *R=Palette[BPal[D0&Mask? (D1&Mask? 3:1):(D1&Mask? 2:0)]];
      if(!(Mask>>=1))
      {
        D0=*(++T)+0x80;
        P=RAM+0x8800+((word)D0<<4)+Offset;
        D0=*P++;D1=*P;Mask=0x80;
      }
    }
  }
}


/****************************************************************/
/*** Refresh sprites.                                         ***/
/****************************************************************/
void RefreshSprites()
{
  register byte *P,*T,*R,*S,I,J,K,N,D0,D1;
  register offset DX,DY;

  N=LCDCONT&0x04? 16:8;

  for(S=RAM+0xFE9C,J=40;J;S-=4,J--)
    if(S[0]&&(S[0]<160)&&(S[1]>=8)&&(S[1]<=152))
    {
      if(S[0]<16) { D0=0;K=16-S[0];I=(K<N)? N-K:0; }
      else        { D0=S[0]-16;K=0;I=(160-S[0]<N)? 160-S[0]:N; }
      P=XBuf+D0*WIDTH+S[1]-(S[3]&0x20? 1:8);
      DX=(S[3]&0x20? -1:1);DY=2;
      if(S[3]&0x40) { DY=-DY;K=N-K-1; }
      T=RAM+0x8000+((long)((N>8)? S[2]&0xFE:S[2])<<4)+(K<<1);
      R=(S[3]&0x10)? SPal1:SPal0;

      for(;I;I--,P+=WIDTH-(DX<<3),T+=DY)
        for(K=0x80,D0=*T,D1=*(T+1);K;K>>=1,P+=DX)
          if((D0|D1)&K) *P=Palette[R[D0&K? (D1&K? 3:1):(D1&K? 2:0)]];
    }
}


/****************************************************************/
/*** Display the screen buffer.                               ***/
/****************************************************************/
void RefreshScreen() { PutImage(); }

