www.pudn.com > virtual_gameboy-0.8.8.zip > COMMON.H


/** 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,1996                 **/ 
/**               John Stiles     1996                      **/ 
/**               Marcel de Kogel 1996                      **/ 
/**     You are not allowed to distribute this software     **/ 
/**     commercially. Please, notify me, if you make any    **/    
/**     changes to this file.                               **/ 
/*************************************************************/ 
 
/** USE_XPAL *************************************************/ 
/** When defined, it makes Common.h drivers use XPal[] to   **/ 
/** obtain color numbers (when there is no 1:1              **/ 
/** correspondence, for example in X11).                    **/ 
/*************************************************************/ 
#define USE_XPAL 
 
#ifdef USE_XPAL 
#define XPAL(N) XPal[N] 
#else 
#define XPAL(N) N 
#endif 
 
/****************************************************************/ 
/*** Refresh a line.                                          ***/ 
/****************************************************************/ 
void RefreshLine(byte Y) 
{ 
  /* Conversion matrix where result has bits */ 
  /* flipped over and inverted.              */ 
  static byte spriteconv[256] = 
  { 
    0xFF,0x7F,0xBF,0x3F,0xDF,0x5F,0x9F,0x1F,0xEF,0x6F,0xAF,0x2F, 
    0xCF,0x4F,0x8F,0x0F,0xF7,0x77,0xB7,0x37,0xD7,0x57,0x97,0x17, 
    0xE7,0x67,0xA7,0x27,0xC7,0x47,0x87,0x07,0xFB,0x7B,0xBB,0x3B, 
    0xDB,0x5B,0x9B,0x1B,0xEB,0x6B,0xAB,0x2B,0xCB,0x4B,0x8B,0x0B, 
    0xF3,0x73,0xB3,0x33,0xD3,0x53,0x93,0x13,0xE3,0x63,0xA3,0x23, 
    0xC3,0x43,0x83,0x03,0xFD,0x7D,0xBD,0x3D,0xDD,0x5D,0x9D,0x1D, 
    0xED,0x6D,0xAD,0x2D,0xCD,0x4D,0x8D,0x0D,0xF5,0x75,0xB5,0x35, 
    0xD5,0x55,0x95,0x15,0xE5,0x65,0xA5,0x25,0xC5,0x45,0x85,0x05, 
    0xF9,0x79,0xB9,0x39,0xD9,0x59,0x99,0x19,0xE9,0x69,0xA9,0x29, 
    0xC9,0x49,0x89,0x09,0xF1,0x71,0xB1,0x31,0xD1,0x51,0x91,0x11, 
    0xE1,0x61,0xA1,0x21,0xC1,0x41,0x81,0x01,0xFE,0x7E,0xBE,0x3E, 
    0xDE,0x5E,0x9E,0x1E,0xEE,0x6E,0xAE,0x2E,0xCE,0x4E,0x8E,0x0E, 
    0xF6,0x76,0xB6,0x36,0xD6,0x56,0x96,0x16,0xE6,0x66,0xA6,0x26, 
    0xC6,0x46,0x86,0x06,0xFA,0x7A,0xBA,0x3A,0xDA,0x5A,0x9A,0x1A, 
    0xEA,0x6A,0xAA,0x2A,0xCA,0x4A,0x8A,0x0A,0xF2,0x72,0xB2,0x32, 
    0xD2,0x52,0x92,0x12,0xE2,0x62,0xA2,0x22,0xC2,0x42,0x82,0x02, 
    0xFC,0x7C,0xBC,0x3C,0xDC,0x5C,0x9C,0x1C,0xEC,0x6C,0xAC,0x2C, 
    0xCC,0x4C,0x8C,0x0C,0xF4,0x74,0xB4,0x34,0xD4,0x54,0x94,0x14, 
    0xE4,0x64,0xA4,0x24,0xC4,0x44,0x84,0x04,0xF8,0x78,0xB8,0x38, 
    0xD8,0x58,0x98,0x18,0xE8,0x68,0xA8,0x28,0xC8,0x48,0x88,0x08, 
    0xF0,0x70,0xB0,0x30,0xD0,0x50,0x90,0x10,0xE0,0x60,0xA0,0x20, 
    0xC0,0x40,0x80,0x00 
  }; 
  byte *X; 
  byte ZBuf[44]; 
  byte Offset,*P,*T,*R,*Z,Z0,D0,X1,X2; 
  unsigned int D1; 
  byte N,*S; 
  unsigned K; 
  int shift; 
 
#ifdef USE_XPAL 
#define PAL(N)  Pal[N] 
#define WPAL(N) WPal[N] 
  byte Pal[4],WPal[4]; 
  Pal[0]=XPal[BPal[0]];Pal[1]=XPal[BPal[1]]; 
  Pal[2]=XPal[BPal[2]];Pal[3]=XPal[BPal[3]]; 
  WPal[0]=(XPal+8)[BPal[0]];WPal[1]=(XPal+8)[BPal[1]]; 
  WPal[2]=(XPal+8)[BPal[2]];WPal[3]=(XPal+8)[BPal[3]]; 
#else 
#define PAL(N)  BPal[N] 
#define WPAL(N) BPal[N]+8 
#endif 
 
  X=R=XBuf+WIDTH*Y+(WIDTH-160)/2; 
  Z=ZBuf; 
 
  if((LCDCONT&0x81)!=0x81) 
  { 
    /* Clearing screen buffer */ 
    memset(R,XPAL(0),160); 
    /* Clearing Z-buffer */ 
    memset(Z,0x00,22); 
    memset(Z+22,0x00,22); 
  } 
  else 
  { 
    Offset=Y+SCROLLY; 
    T=BgdTab+((int)(Offset&0xF8)<<2); 
    Offset=(Offset&0x07)<<1; 
 
    shift=SCROLLX&0x07; 
    R-=shift; 
    X1=SCROLLX>>3; 
    Z[0]=Z[22]=0; 
 
    /* Determine how much background is shown */ 
    X2=(WNDPOSX>7)? WNDPOSX-7:0; 
    if((~LCDCONT&0x20)||(WNDPOSY>Y)||(X2>159)) X2=160; 
    X2=X1+((X2+7)>>3); 
 
    for(;X1<=X2;X1++) 
    { 
      D0=*(T+(X1&0x1F)); 
      if(~LCDCONT&0x10) D0+=0x80; 
      P=ChrGen+(D0<<4)+Offset; 
      D0=*P; 
 
      /* Modifying Z-buffer */ 
      D1=(int)(D0|*(P+1))<>8; 
      Z[1]=D1&0xFF; 
      Z[22]=0x00; 
      ++Z; 
 
      /* Modifying screen buffer */ 
      D1=(int)*(P+1)<<1; 
      D1=(D1&0xAAA)|((D1&0x555)<<7)|(D0&0x55)|((int)(D0&0xAA)<<7); 
      R[0]=PAL((D1&0xC000)>>14); 
      R[1]=PAL((D1&0x00C0)>>6 ); 
      R[2]=PAL((D1&0x3000)>>12); 
      R[3]=PAL((D1&0x0030)>>4 ); 
      R[4]=PAL((D1&0x0C00)>>10); 
      R[5]=PAL((D1&0x000C)>>2 ); 
      R[6]=PAL((D1&0x0300)>>8 ); 
      R[7]=PAL( D1&0x003      ); 
 
      /* Moving pointers */ 
      R+=8; 
    } 
  } 
 
  X1=(WNDPOSX>7)? WNDPOSX-7:0; 
  if(((LCDCONT&0xA0)==0xA0)&&(WNDPOSY<=Y)&&(X1<160)) 
  { 
    R=X+X1; 
    Z=ZBuf+X1/8+1; 
    Offset=Y-WNDPOSY; 
    T=WndTab+((int)(Offset&0xF8)<<2); 
    Offset=(Offset&0x07)<<1; 
 
    D0=0xFF>>(X1&0x07); 
    if(LCDCONT&0x02) Z[22]=Z0=0x00; 
    else { Z[22]=D0;Z0=0xFF; } 
    Z[0]|=D0;Z++; 
 
    for(X1>>=3;X1<(160>>3);X1++) 
    { 
      D0=*(T++)+0x80; 
      P=RAM+0x8800+((int)D0<<4)+Offset; 
 
      /* Modifying Z-buffer */ 
      Z[22]=Z0;Z[0]=0xFF;++Z; 
 
      /* Modifying screen buffer */ 
      D0=*P;D1=(int)*(P+1)<<1; 
      D1=(D1&0xAAA)|((D1&0x555)<<7)|(D0&0x55)|((int)(D0&0xAA)<<7); 
      R[0]=WPAL((D1&0xC000)>>14); 
      R[1]=WPAL((D1&0x00C0)>>6 ); 
      R[2]=WPAL((D1&0x3000)>>12); 
      R[3]=WPAL((D1&0x0030)>>4 ); 
      R[4]=WPAL((D1&0x0C00)>>10); 
      R[5]=WPAL((D1&0x000C)>>2 ); 
      R[6]=WPAL((D1&0x0300)>>8 ); 
      R[7]=WPAL( D1&0x0003     ); 
 
      /* Moving pointers */ 
      R+=8; 
    } 
  } 
 if (!(LCDCONT&0x80)) return; 
 
 /* Refresh sprites */ 
#undef PAL 
#ifdef USE_XPAL 
#define PAL(N) Pal[N] 
#else 
#define PAL(N) R[N]+4 
#endif 
 
  N=LCDCONT&0x04? 16:8; 
  for(S=RAM+0xFE9C;S>RAM+0xFE9C-40*4;S-=4) 
  { 
    if(Y>=(S[0]-16)&&Y<(S[0]-16+N)&&S[1]&&(S[1]<168)) 
    { 
      shift=S[1]-(S[3]&0x20? 1:8); 
      P=X+shift; 
      Z=ZBuf+shift/8+1; 
      /* Only clip to window if priority flag is set */ 
      if ((S[3]&0x80)==0) Z+=22; 
      shift&=7; 
      T=RAM+0x8000+(((N>8)? S[2]&0xFE:S[2])<<4); 
      if(S[3]&0x40) 
       T+=(N-1-Y+S[0]-16)*2; 
      else 
       T+=(Y-S[0]+16)*2; 
      R=S[3]&0x10? SPal1:SPal0; 
#ifdef USE_XPAL 
      Pal[0]=(XPal+4)[R[0]];Pal[1]=(XPal+4)[R[1]]; 
      Pal[2]=(XPal+4)[R[2]];Pal[3]=(XPal+4)[R[3]]; 
#endif 
      if(S[3]&0x20) 
      { 
        shift=7-shift; 
        D0=*T;D1=*(T+1);K=D0|D1;D1<<=1; 
        D1=(D1&0xAAA)|((D1&0x555)<<7)|(D0&0x55)|((unsigned)(D0&0xAA)<<7); 
        K&=spriteconv[((Z[-1]*256+Z[0])>>shift)&0xFF]; 
        if(K&0x80) P[0]=PAL((D1&0xC000)>>14); 
        if(K&0x40) P[-1]=PAL((D1&0x00C0)>>6 ); 
        if(K&0x20) P[-2]=PAL((D1&0x3000)>>12); 
        if(K&0x10) P[-3]=PAL((D1&0x0030)>>4 ); 
        if(K&0x08) P[-4]=PAL((D1&0x0C00)>>10); 
        if(K&0x04) P[-5]=PAL((D1&0x000C)>>2 ); 
        if(K&0x02) P[-6]=PAL((D1&0x0300)>>8 ); 
        if(K&0x01) P[-7]=PAL( D1&0x0003     ); 
      } 
      else 
      { 
        shift=8-shift; 
        D0=*T;D1=*(T+1);K=D0|D1;D1<<=1; 
        D1=(D1&0xAAA)|((D1&0x555)<<7)|(D0&0x55)|((unsigned)(D0&0xAA)<<7); 
        K&=~((Z[0]*256+Z[1])>>shift); 
        if(K&0x80) P[0]=PAL((D1&0xC000)>>14); 
        if(K&0x40) P[1]=PAL((D1&0x00C0)>>6 ); 
        if(K&0x20) P[2]=PAL((D1&0x3000)>>12); 
        if(K&0x10) P[3]=PAL((D1&0x0030)>>4 ); 
        if(K&0x08) P[4]=PAL((D1&0x0C00)>>10); 
        if(K&0x04) P[5]=PAL((D1&0x000C)>>2 ); 
        if(K&0x02) P[6]=PAL((D1&0x0300)>>8 ); 
        if(K&0x01) P[7]=PAL( D1&0x0003     ); 
      } 
    } 
  } 
} 
 
/****************************************************************/ 
/*** Display the screen buffer.                               ***/ 
/****************************************************************/ 
void RefreshScreen() { PutImage(); }