
#include <ppm.h>
#include <ggi/ggi.h>
#include <stdio.h>


typedef ggi_color *SpriteRaster;
typedef struct
{
  SpriteRaster raster;
  int x,y;
} Sprite;


Sprite *loadsprite(const char *fn)
{
  FILE *loadfie;
  int loadsprx, loadspry;
  pixval loadimgmax;
  int loadadj;
  pixel **loadimg;
  Sprite *NewSprite;
  

  // open the file read only
  if (!(loadfie=fopen(fn,"r")))
    {
      return NULL;
    }

  NewSprite = malloc(sizeof(Sprite));

  // load the image pnm file and convert it to our Sprite type
  loadimg = ppm_readppm(loadfie,&(NewSprite->x),&(NewSprite->y),&loadimgmax);
  
  fclose(loadfie);
  
  if (loadimg)
    {
      NewSprite->raster = malloc(sizeof(ggi_color)*NewSprite->y*NewSprite->x);
      loadadj = 65536 / loadimgmax;
      for (loadsprx = 0; loadsprx < NewSprite->x; loadsprx++)
	{
	  for (loadspry = 0; loadspry < NewSprite->y; loadspry++)
	    {
	      NewSprite->raster[(loadspry*NewSprite->x)+loadsprx].r = 
		PPM_GETR(loadimg[loadspry][loadsprx])*loadadj;
	     
	      NewSprite->raster[(loadspry*NewSprite->x)+loadsprx].g = 
		PPM_GETG(loadimg[loadspry][loadsprx])*loadadj;

	      NewSprite->raster[(loadspry*NewSprite->x)+loadsprx].b = 
		PPM_GETB(loadimg[loadspry][loadsprx])*loadadj;
	    }
	}
    }
  else
    {
      free(NewSprite);
      NewSprite = 0;
    }

  ppm_freearray(loadimg,loadspry);
  return NewSprite;
}

int drawsprite(ggi_visual_t vis, Sprite *asprite,int xloc, int yloc)
{
  ggi_pixel drawpix;
  int drawx, drawy;

  if (!(vis && asprite))
    {
      return -1;
    }
  
  for (drawy = 0; drawy < asprite->y; drawy++)
    {
      for (drawx = 0; drawx < asprite->x; drawx++)
	{
	  drawpix = ggiMapColor(vis,&(asprite->raster[(drawy*asprite->x)+drawx]));
	  ggiSetGCForeground(vis, drawpix);
	  ggiDrawPixel(vis, drawx+xloc, drawy+yloc);    
	}
    }
  return 0;
}

main()
{
  int myx, myy,i,err;
  Sprite *MySprite;
  ggi_visual_t myvis;
  ggi_mode mymode;
  
  if (!(MySprite = loadsprite("foo.ppm")))
    {
      puts("can't load sprite.");
      exit(0);
    }

  // start up ggi..
  if (ggiInit())
    {
      printf("Foo! Can't init!\n");
      exit(1);  /* can't start! */
    }
  
  // initialize ggi and do the ggi thing
  myvis = ggiOpen(NULL);
  
  if (!myvis)
    {
      ggiPanic("Foo! No visual!\n");
    }    
  
  err = ggiCheckGraphMode (myvis, GGI_AUTO, GGI_AUTO,
			   GGI_AUTO, GGI_AUTO, GT_TRUECOLOR, &mymode);
  if (err) 
    {
      ggiClose (myvis);
      ggiExit ();
      fprintf(stderr,"Error finding working truecolor mode.");
      exit(1);
    }
  
  err = ggiSetMode (myvis, &mymode);
  if (err) 
    {
      ggiClose (myvis);
      ggiExit ();
      fprintf(stderr,"Error setting mode.");
      exit(1);
    }
  
  ggiAddFlags(myvis,GGIFLAG_ASYNC);
  ggiSetDisplayFrame(myvis,0);
  ggiSetWriteFrame(myvis,0);
  
  while (!ggiKbhit(myvis))
    {
      drawsprite(myvis,MySprite,30,30);
      ggiFlush(myvis);
    }
}

