/**
 * Written by Tyler Montbriand.
 * Shows an eerie rotating starfield.  Freeware.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <SDL/SDL.h>

typedef struct star
{
  unsigned short	a;
  Uint8			r;
  unsigned long		z;
} star;

#define SCREEN_W	640
#define SCREEN_H	480
#define CENTER_X	(SCREEN_W/2)
#define CENTER_Y	(SCREEN_H/2)
#define NUM_STARS	2048
#define MAXDIST		240L
#define MINDIST		0L

#define SQUARE(X)  ((X)*(X))

#define HSV_QUAD (MAXDIST/6)

#define FRAME_TIME 20

static SDL_Rect rects[2][NUM_STARS];
SDL_Surface *screen;

void hsv(int pos, SDL_Color *c);
void BS_SetIcon();

Uint32 coord_transform(int *x, int *y, const struct star *s, unsigned long pos)
{
  SDL_Color c;
  float a=(logf(MAXDIST-(s->z - pos))/2) + ((s->a*2*3.14159)/360.0); 

  float res=(MAXDIST-sqrtf(SQUARE(MAXDIST)-SQUARE(MAXDIST-(s->z - pos))));

  (*x)=(res+s->r)*sin(a)+CENTER_X;
  (*y)=(res+s->r)*cos(a)+CENTER_Y;

  hsv((5*HSV_QUAD)-res,&c);
  return(SDL_MapRGB(screen->format,c.r,c.g,c.b));
}

int main(int argc, char *argv[])
{
  Uint32 blankcol;
  int running=1,n;
  int which=0;
  struct star stars[NUM_STARS];
  unsigned long pos=0.0f;
  Uint32 lasttick;

  if(SDL_Init(SDL_INIT_VIDEO)<0)
    return(1);

  atexit(SDL_Quit);

  BS_SetIcon();
  screen=SDL_SetVideoMode(SCREEN_W,SCREEN_H,32,SDL_ANYFORMAT);
  if(screen==NULL)
    return(2);

  SDL_WM_SetCaption("Hyperspace","Hyperspace");

  blankcol=SDL_MapRGB(screen->format,127,0,0);

  memset(rects,0,sizeof(rects));

  for(n=0; n<NUM_STARS; n++)
  {
    stars[n].z=rand()%(MAXDIST-MINDIST)+MINDIST;
    stars[n].a=rand()%360;
    stars[n].r=rand()%256;
  }

  lasttick=SDL_GetTicks();

  SDL_FillRect(screen,NULL,blankcol);
  SDL_Flip(screen);

  while(running)
  {
    SDL_Event event;

    while(SDL_PollEvent(&event))
    switch(event.type)
    {
    case SDL_QUIT:
      running=0;
      break;

    default:
      break;
    }

    {
      Uint32 ntime=SDL_GetTicks();
      if((ntime-lasttick)<FRAME_TIME)
      {
        SDL_Delay(FRAME_TIME-(ntime-lasttick));
        continue;
      }

      pos+=(ntime-lasttick)/FRAME_TIME;
      lasttick=ntime;
    }

    which=which^1;

    for(n=0; n<NUM_STARS; n++)
    {
      Uint32 c;
      int x,y;
      if(stars[n].z <= pos)
        stars[n].z=pos+MAXDIST;

      c=coord_transform(&x,&y,stars+n,pos);

      {
        SDL_Rect r={x,y,2,2};
        SDL_FillRect(screen,rects[which^1]+n,blankcol);

	if(	(r.x < (SCREEN_W - 2)) &&
		(r.x >= 0) &&
		(r.y < (SCREEN_H - 2)) &&
		(r.y >= 0))
	{
	        SDL_FillRect(screen,&r,c);
	        rects[which][n]=r;
	}
	else
	{
		rects[which][n].x=0;
		rects[which][n].y=0;
		rects[which][n].w=0;
		rects[which][n].h=0;
		stars[n].z=pos+MAXDIST;
	}
      }
    }

    SDL_UpdateRects(screen,NUM_STARS*2,(SDL_Rect *)rects);
//    SDL_Flip(screen);
  }

  return(0);
}

void hsv(int quad, SDL_Color *c)
{
  Uint8 mod=(quad%HSV_QUAD);
  Uint8 intens=(mod*255)/42;

//  c->r=127;
//  c->g=0;
//  c->b=0;
  switch(quad/HSV_QUAD)
  {
  case 0:
    (c->r)=255-intens;
    (c->g)=intens;
    (c->b)=intens;
    break;

  case 1:
//    (c->r)=255-intens;
//    (c->g)=255;
//    (c->b)=0;
    (c->r)=(intens/2);
    (c->g)=255-(intens/2);
    (c->b)=255;
    break;

  case 2:
//    (c->r)=0;
//    (c->g)=255;
//    (c->b)=intens;

    (c->r)=(intens+255)/2;
    (c->g)=128-(intens/2);
    (c->b)=255;
    break;

  case 3:
    (c->r)=127;
    (c->g)=0;
    (c->b)=255;
    break;

  case 4:
    (c->r)=127-(intens/8);
//    (c->r)=255-(intens/2);
    (c->g)=0;
    (c->b)=255-intens;
    break;

  case 5:	// Red full intensity, blue decreasing intensity
    c->r = 127;
    c->g = 0;
    c->b = 0;
    break;

  default:
    break;
  }
}

#include <SDL/SDL.h>
#include <SDL/SDL_rwops.h>

static const unsigned char burningsmell_icon_32x32[]={
	0x42,0x4d,0x76,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x76,0x00,0x00,0x00,
	0x28,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x01,0x00,
	0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x12,0x0b,0x00,0x00,
	0x12,0x0b,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x04,0x05,
	0x44,0x00,0x0d,0x12,0x29,0x00,0x17,0x25,0x10,0x00,0x08,0x06,0x6a,0x00,
	0x01,0x01,0x95,0x00,0x2e,0x44,0x1c,0x00,0x01,0x00,0xcf,0x00,0x40,0x5a,
	0x33,0x00,0x37,0x44,0x6a,0x00,0x40,0x55,0x49,0x00,0x47,0x6d,0x4b,0x00,
	0x50,0x68,0x65,0x00,0x69,0x6f,0x5f,0x00,0xff,0x05,0xfd,0x00,0x68,0x73,
	0x84,0x00,0x95,0x98,0xa6,0x00,0xff,0xeb,0xef,0xff,0xff,0xff,0xec,0x9c,
	0xff,0xfe,0xfc,0xcc,0xcd,0xdd,0xdd,0xdd,0xff,0xf7,0xbf,0xff,0xff,0xff,
	0xfe,0x2e,0xff,0xee,0xbc,0xbc,0xcd,0xdd,0xdd,0xdd,0xff,0xf9,0x9e,0xff,
	0xff,0xff,0xfe,0x59,0xbe,0x9b,0x99,0xbc,0xcd,0xdd,0xdd,0xdd,0xff,0xfb,
	0xa5,0xef,0xff,0xfe,0xfc,0x55,0x99,0x9b,0xa9,0xb7,0x5c,0xdd,0xdd,0xdd,
	0xff,0xfe,0x55,0xbf,0xeb,0xbb,0xbe,0x55,0x59,0x99,0x79,0xb7,0xcc,0xdd,
	0xdd,0xdd,0xff,0xff,0xb5,0x5b,0xba,0x9a,0x99,0x72,0x75,0xbb,0xbb,0xb7,
	0x7c,0xcd,0xdd,0xdd,0xee,0xee,0xb5,0x5b,0xb9,0x99,0x99,0xb5,0x55,0x9b,
	0xb9,0xb7,0x75,0xcd,0xdd,0xdd,0xbb,0xbb,0xbb,0x29,0x9b,0x9b,0xbb,0xb9,
	0x55,0x9b,0xb9,0xba,0xcc,0xcc,0xdd,0xdd,0xb9,0x99,0xb9,0x59,0xab,0xbb,
	0xbb,0xe9,0x55,0x59,0xa9,0x9a,0x55,0x5c,0xdd,0xdd,0x9b,0xaa,0x77,0x55,
	0x9e,0xbb,0xba,0xa7,0x55,0x27,0xaa,0x9a,0x75,0xcc,0xcd,0xdd,0x8b,0xaa,
	0xc5,0x95,0x7b,0xb8,0x99,0xcc,0x8c,0x99,0x77,0x77,0x9e,0x88,0xfd,0xdd,
	0xb9,0xb9,0x97,0x75,0x59,0xb9,0xbb,0xc8,0xc2,0x59,0x5c,0xb9,0x83,0x38,
	0x8d,0xdd,0xec,0xb9,0x59,0x95,0x55,0xb9,0xcc,0x8c,0xc5,0xc5,0x98,0x83,
	0x30,0x40,0x33,0xdd,0xbb,0x88,0xe9,0xb5,0x25,0x9b,0x88,0x9c,0x55,0x52,
	0x21,0x00,0x03,0x40,0x33,0xdd,0x99,0xe8,0x8b,0x88,0x92,0x29,0x97,0x77,
	0x75,0xcf,0x00,0x33,0x46,0x66,0x40,0x1d,0x97,0x77,0x99,0xbb,0x55,0x55,
	0x57,0x52,0x21,0x24,0x40,0x34,0x66,0x66,0x43,0x1d,0x97,0x7a,0x7a,0xab,
	0x55,0x55,0x57,0x10,0x00,0x16,0x40,0x36,0x66,0x66,0x63,0x1d,0x57,0xa7,
	0x98,0x80,0x11,0x82,0x21,0x00,0x33,0x03,0x31,0x36,0x64,0x46,0x64,0x0d,
	0x59,0x08,0x33,0x30,0x03,0x61,0x13,0x66,0x66,0x44,0x30,0x46,0x64,0x03,
	0x66,0x0d,0x22,0x33,0x34,0x43,0x33,0x41,0x36,0x66,0x66,0x64,0x43,0x46,
	0x46,0x66,0x64,0x1d,0x21,0x33,0x46,0x44,0x40,0x10,0x66,0x64,0x44,0x66,
	0x44,0x04,0x66,0x66,0x60,0x1d,0x11,0x44,0x66,0x64,0x44,0x34,0x66,0x34,
	0x46,0x34,0x44,0x18,0x34,0x43,0x00,0xdd,0x00,0x34,0x66,0x66,0x44,0x44,
	0x44,0x44,0x66,0x66,0x64,0x43,0x30,0x00,0x0d,0xdd,0x30,0x03,0x46,0x66,
	0x64,0x63,0x44,0x66,0x66,0x64,0x33,0x64,0x33,0x30,0xdd,0xdd,0x34,0x34,
	0x46,0x64,0x64,0x43,0x33,0x46,0x66,0x64,0x03,0xdd,0xdd,0xdd,0xdd,0xdd,
	0xdd,0x44,0x46,0x33,0x46,0x34,0x30,0x11,0x00,0x30,0x3d,0xdd,0xdd,0xdd,
	0xdd,0xdd,0xdd,0x64,0x46,0x66,0x64,0x04,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
	0xdd,0xdd,0xdd,0xdd,0xdd,0x34,0x33,0x36,0x43,0x1d,0xdd,0xdd,0xdd,0xdd,
	0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xd0,0x34,0x43,0xdd,0xdd,0xdd,
	0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
	0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
	0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
	0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd
	};

static const unsigned int burningsmell_icon_32x32_length=630;

void BS_SetIcon()
{
  SDL_Surface *s;
  SDL_RWops *rw=SDL_RWFromConstMem(burningsmell_icon_32x32,
                                   burningsmell_icon_32x32_length);
  if(rw==NULL)
  {
    fprintf(stderr,"Couldn't load RWop\n");
    return;
  }
  s=SDL_LoadBMP_RW(rw,0);
  SDL_RWclose(rw);
  if(s==NULL)
  {
    fprintf(stderr,"Couldn't load BMP\n");
    return;
  }
  SDL_SetColorKey(s,SDL_SRCCOLORKEY,SDL_MapRGB(s->format,255,0,255));
  SDL_WM_SetIcon(s,NULL);
}

#ifdef BS_ICON_TEST
int main(int argc, char *argv[])
{
  SDL_Init(SDL_INIT_VIDEO);
  BS_SetIcon();
  SDL_SetVideoMode(320,240,32,SDL_ANYFORMAT);
  SDL_Delay(5000);
  SDL_Quit();
  return(0);
}
#endif/*BS_ICON_TEST*/
