#include <windows.h>



//---- TYPES -----------------------------------------------------------------//



//---- Image -----------------------------------------------------------------//

class Image
{
  public:

  int w, h;
  unsigned int *buf;



  //---- Image

  Image()
  {
    w = 0;
    h = 0;
    buf = NULL;
  }



  //---- Image

  Image(int w, int h)
  {
    this->w = w;
    this->h = h;

    buf = (unsigned int *)malloc(w*h*4);

    int col = GetTickCount() * 0x8A37F832 + ((int)this)*0xAF897BC7;
    
    for(int i=0; i<w*h; i++) buf[i] = col;
  }



  //---- blit

  void blit(Image *im, int x, int y)
  {
    int imw = im->w;

    int dx = x, dy = y;
    int sx = 0, sy = 0;
    int sw = im->w, sh = im->h;

    if(dx < 0) { sx = -dx; sw -= sx; dx = 0; }
    if(dy < 0) { sy = -dy; sh -= sy; dy = 0; }

    if(dx + sw > w) { sw = w-dx; }
    if(dy + sh > h) { sh = h-dy; }

    int i, j;

    for(j=0; j<sh; j++) for(i=0; i<sw; i++)
    {
      buf[ (j+dy)*w + (i+dx) ] = im->buf[ (j+sy)*imw + (i+sx) ];
    }
  }



  //---- blit

  void blit(Image *im, int x, int y, double alpha)
  {
    if(alpha <= 0.0)
    {
      blit(im, x, y);
      return;
    }
    else if(alpha >= 1.0)
    {
      return;
    }

    int imw = im->w;

    int dx = x, dy = y;
    int sx = 0, sy = 0;
    int sw = im->w, sh = im->h;

    if(dx < 0) { sx = -dx; sw -= sx; dx = 0; }
    if(dy < 0) { sy = -dy; sh -= sy; dy = 0; }

    if(dx + sw > w) { sw = w-dx; }
    if(dy + sh > h) { sh = h-dy; }

    int a = 256*alpha;
    if(a < 0) a = 0;
    if(a > 256) a = 256;

    int aa = 256-a;

    int i, j;
    int col1, r1, g1, b1;
    int col2, r2, g2, b2;

    for(j=0; j<sh; j++) for(i=0; i<sw; i++)
    {
      col1 = im->buf[ (j+sy)*imw + (i+sx) ];

      r1 = (col1>>16)&255;
      g1 = (col1>>8)&255;
      b1 = (col1)&255;

      col2 = buf[ (j+dy)*w + (i+dx) ];

      r2 = (col2>>16)&255;
      g2 = (col2>>8)&255;
      b2 = (col2)&255;
      
      r1 = (r1*aa + r2*a) >> 8;
      g1 = (g1*aa + g2*a) >> 8;
      b1 = (b1*aa + b2*a) >> 8;

      buf[ (j+dy)*w + (i+dx) ] = (r1<<16) + (g1<<8) + b1;
    }
  }



  //---- display

  void display(HDC dc)
  {
    BITMAPINFO bmi;

    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biWidth = w;
    bmi.bmiHeader.biHeight = -(signed)h;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biBitCount = 32;
    bmi.bmiHeader.biCompression = BI_RGB;
    bmi.bmiHeader.biSizeImage = 0;
    bmi.bmiHeader.biXPelsPerMeter = 1000;
    bmi.bmiHeader.biYPelsPerMeter = 1000;
    bmi.bmiHeader.biClrUsed = 0;
    bmi.bmiHeader.biClrImportant = 0;

    StretchDIBits(
      dc,
      0, 0, w, h,
      0, 0, w, h,
      (LPVOID)buf,
      (LPBITMAPINFO)&bmi,
      DIB_RGB_COLORS, SRCCOPY
    );

  }

};



//---- ZN --------------------------------------------------------------------//

class ZN
{
  public:

  Image *im;
  int w, h;

  Image *znlogo;



  //---- ZN

  ZN(int w, int h)
  {
    this->w = w;
    this->h = h;
    im = new Image(640, 480);

    znlogo = new Image(320, 160);
  }



  //---- recalc

  void recalc(double time)
  {
    //- Constants

    static double ZNLOGO_STARTFADE =   5.000;
    static double ZNLOGO_ENDFADE   =   7.000;

    static double BOXES_START      =   4.500;

    //- Clear buffer

    int i;

    for(i=0; i<w*h; i++) im->buf[i] = 0x336699;

    //  Draw 3d things

    //  Draw ZN logo

    double alpha = (time - ZNLOGO_STARTFADE) / (ZNLOGO_ENDFADE - ZNLOGO_STARTFADE);
    im->blit(znlogo, (w - znlogo->w)/2, (h - znlogo->h) / 2, alpha);

  }



  //---- display

  void display(HDC dc)
  {
    im->display(dc);
  }


};



//---- FUNCTIONS -------------------------------------------------------------//




//---- END OF FILE -----------------------------------------------------------//




