#define LINUX
#define SOUNDDEVICE "/dev/dsp"
#define quiet 0

#define error(x) fprintf(stderr,"%s\n",x)

#define NEXTBYTE ((unsigned char)MMF[MMF_OFF++])
#define NEXTUL MMF[MMF_OFF]|(MMF[MMF_OFF+1]<<8)|(MMF[MMF_OFF+2]<<16)|(MMF[MMF_OFF+3]<<24);MMF_OFF+=4;
#define NEXTBLOCK(dest,bytes) memcpy((dest),&MMF[MMF_OFF],(bytes));MMF_OFF+=(bytes);
#define THROWAWAY(bytes) MMF_OFF+=bytes;
#define WRITEBLOCK(destfp,bytes) write((destfp),&MMF[MMF_OFF],bytes);MMF_OFF+=(bytes);
#define FWRITEBLOCK(destfp,bytes) fwrite(&MMF[MMF_OFF],bytes,1,destfp);MMF_OFF+=(bytes);

/* 0=not rotated, 1=table lookup, 2=blit-rotate */
#define rotated 1

#define cachesound 0
#define dirtyrect 0
#define sound 1
#define debug 0
#define deb if (debug) printf


#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>           
#include <unistd.h>
#include <string.h>
                   
#include <vga.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
 
#ifndef LINUX
#error THIS PROGRAM REQUIRES LINUX
#endif

#include <linux/soundcard.h>

int ifd;

int bufferstep=0;

unsigned short int pagesize;

unsigned char *MMF;
unsigned long int MMF_OFF=0;

unsigned long FSIZE;

char *buf;

unsigned short int palrange=1;

unsigned short int trans[64000];

#define _ANSI_ARGS_(x) x

unsigned long pix[256];
XColor pal[256];

unsigned char *bbuf;
unsigned char *fbuf;
unsigned char *fbuf1;
unsigned char *fbuf2;
/*unsigned char *scrollin;*/

unsigned long int pmr;

int wwidth=320,wheight=200;
int bwidth,bheight;
Colormap cmap;
static Display *display;
static Window window;
static GC gc;
static XImage *ximage;

#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/extensions/XShm.h>

static int HandleXError _ANSI_ARGS_((Display *dpy, XErrorEvent *event));
static void InstallXErrorHandler _ANSI_ARGS_((void));
static void DeInstallXErrorHandler _ANSI_ARGS_((void));

static int shmem_flag=1;
static XShmSegmentInfo shminfo1;
static int gXErrorFlag;
static int CompletionType = -1;

int speed=22050;
int bits=AFMT_U8;
int stereo=0;      
/*int frag=0x00020009;  /* 2 fragments of 2^9=512 bytes */   
/*int frag=0x0002000f;  /* 2 fragments of 2^15=32k bytes */   
/*int frag=0x0004000e;  /* 2 fragments of 2^15=32k bytes */ 
/*int frag=0x0008000d;  /* 2 fragments of 2^15=32k bytes */
int frag=0x00100009;  /* 16 fragments of 2^12=4096 bytes */

int ffd;

int c1,c2,c3,c4;
long int remaining;

unsigned char twoseconds[55000];
/*unsigned char modexbuf[64000];*/

unsigned long int nextblock;

static int HandleXError(dpy, event)
Display *dpy;
XErrorEvent *event;
{
  gXErrorFlag = 1;

  return 0;
}

static void InstallXErrorHandler()
{
  XSetErrorHandler(HandleXError);
  XFlush(display);
}

static void DeInstallXErrorHandler()
{
  XSetErrorHandler(NULL);
  XFlush(display);
}

void init_display(name)
char *name;
{
  int crv, cbu, cgu, cgv;
  int y, u, v, r, g, b;
  int i;
  char dummy;
  int screen;
  int private;
  XColor xcolor;
  unsigned int fg, bg;
  char *hello = "Space Ace";
  XSizeHints hint;
  XVisualInfo vinfo;
  XEvent xev;
  unsigned long tmp_pixel;
  XWindowAttributes xwa;

  display = XOpenDisplay(name);

  if (display == NULL)
    error("Cannot open display\n");

  screen = DefaultScreen(display);

  hint.x = 200;
  hint.y = 200;
  hint.width = wwidth;
  hint.height = wheight;

  hint.flags = PSize;

  /* Get some colors */
/*
  bg = WhitePixel (display, screen);
  fg = BlackPixel (display, screen);*/

  /* Make the window */

  if (!XMatchVisualInfo(display, screen, 8, PseudoColor, &vinfo))
  {
    if (!XMatchVisualInfo(display, screen, 8, GrayScale, &vinfo))
      error("requires 8 bit display\n");
  }

  window = XCreateSimpleWindow (display, DefaultRootWindow (display),
             hint.x, hint.y, hint.width, hint.height, 0, 0, 0);

  XSelectInput(display, window, StructureNotifyMask);

  /* Tell other applications about this window */

  XSetStandardProperties (display, window, hello, hello, None, NULL, 0, &hint);

  /* Map window. */

  XMapWindow(display, window);

  /* Wait for map. */
  do
  {
    XNextEvent(display, &xev);
  }
  while (xev.type != MapNotify || xev.xmap.event != window);

  XSelectInput(display, window, NoEventMask);

  /* allocate colors */

  gc = DefaultGC(display, screen);
  cmap = DefaultColormap(display, screen);
    
  /* create private colormap */
  
  XGetWindowAttributes(display, window, &xwa);
  cmap = XCreateColormap(display, window, xwa.visual, AllocNone);
  XSetWindowColormap(display, window, cmap);
  
  if (XAllocColorCells(display, cmap, False, &pmr, 0, pix, 256)==0)
    {
      printf("** XAllocColorCells FAILED **");
    };

  for (i=0;i<256;i++)
    {
      pal[i].flags|=DoRed|DoGreen|DoBlue;
      pal[i].pixel=pix[i];
    }

/*  for (i=0;i<256;i++)
    {
      xcolor.red=i<<8;
      xcolor.green=i<<8;
      xcolor.blue=i<<8;
      XAllocColor(display, cmap, &xcolor);
      mapping[i]=xcolor.pixel;
    }*/
  
  if (XShmQueryExtension(display))
    shmem_flag = 1;
  else
  {
    shmem_flag = 0;
    if (!quiet)
      fprintf(stderr, "Shared memory not supported\nReverting to normal Xlib\n")
	;
  }
}

void createshm(int width,int height)
{
  if (shmem_flag)
    CompletionType = XShmGetEventBase(display) + ShmCompletion;

  InstallXErrorHandler();

  if (shmem_flag)
  {

    ximage = XShmCreateImage(display, None, 8, ZPixmap, NULL,
                             &shminfo1,
                             width, height);

    /* If no go, then revert to normal Xlib calls. */

    if (ximage==NULL)
    {
      if (!quiet)
        fprintf(stderr, "Shared memory error, disabling (Ximage error)\n");
    }

    /* Success here, continue. */

    shminfo1.shmid = shmget(IPC_PRIVATE, 
                            width*height,
                            IPC_CREAT | 0777);

    if (shminfo1.shmid<0)
    {
      perror("shmget");
      XDestroyImage(ximage);
      if (!quiet)
        fprintf(stderr, "Shared memory error, disabling (seg id error)\n");
    }

    shminfo1.shmaddr = (char *) shmat(shminfo1.shmid, 0, 0);

    if (shminfo1.shmaddr==((char *) -1))
    {
      XDestroyImage(ximage);
      if (!quiet)
      {
        fprintf(stderr, "Shared memory error, disabling (address error)\n");
      }
    }

    shminfo1.readOnly = False;
    XShmAttach(display, &shminfo1);
    shmctl(shminfo1.shmid, IPC_RMID, 0 );

    buf = ximage->data = shminfo1.shmaddr;
   
    XSync(display, False);

    if (gXErrorFlag)
    {
      /* Ultimate failure here. */
      XDestroyImage(ximage);
      shmdt(shminfo1.shmaddr);
      if (!quiet)
        fprintf(stderr, "Shared memory error, disabling.\n");
      gXErrorFlag = 0;
    }
    else
    {
      shmctl(shminfo1.shmid, IPC_RMID, 0);
    }

    if (!quiet)
    {
      fprintf(stderr, "Sharing memory. [ %d x %d ]\n",width,height);
    }
  }
/*  else
  {
shmemerror:
    shmem_flag = 0;

    ximage = XCreateImage(display,None,8,ZPixmap,0,&dummy,
                          coded_picture_width,coded_picture_height,8,0);

    if (!(dithered_image = (unsigned char *)malloc(coded_picture_width*
                                                   coded_picture_height)))
      error("malloc failed");

  }*/

  DeInstallXErrorHandler();
}

void destroyshm()
{
    XShmDetach(display, &shminfo1);
    XDestroyImage(ximage);
    shmdt(shminfo1.shmaddr);
}

void doPalette(void)
{
//  XStoreColors(display, cmap, &pal[0], 256);
int i;

for (i=0;i<256;i++)
{
vga_setpalette(i, (pal[i].red)/(65535/63), pal[i].green/(65535/63), pal[i].blue/(65535/63));
}
vga_waitretrace();
}

void getPalette(void)
{
  int i,j;
  char fn[100];
  FILE *im;

  deb("\t- Palette [ ");
  c1=NEXTBYTE;
  palrange=NEXTBYTE;
  for (i=0;i<5;i++)
    {
      j=NEXTBYTE;
      deb("%ld ",j);
    }
  deb("]\n");

  if (palrange==0) palrange=256;
  for (i=0;i<palrange;i++)
    {
      pal[i].red=NEXTBYTE<<10;
      pal[i].green=NEXTBYTE<<10;
      pal[i].blue=NEXTBYTE<<10;
    }
/*  XSetWindowColormap(display, window, cmap);*/

/*  sprintf(fn,"pal%ld.pal",position);
  printf("\t- Palette (dumping to %s)\n",fn);
  im = fopen(fn,"wb");
  for (i=0;i<remaining;i++)
    {
      fputc(fgetc(fp),im);
    }
  fclose(im);*/
}

void doBackground(void)
{
  int i,j,lastpix,nwidth,nheight;
  char fn[100];
  FILE *im;

  deb("\t- Background (");

  THROWAWAY(7);

  nwidth=NEXTBYTE;
  nwidth|=NEXTBYTE<<8;

  THROWAWAY(2);

  nheight=NEXTBYTE;
  nheight|=NEXTBYTE<<8;

  THROWAWAY(4);

  deb("%ldx%ld) ",nwidth,nheight);
  fflush(stdout);

  if ((nwidth<320) || (nheight<200)) return;

  if ((nwidth!=bwidth) || (nheight!=bheight))
    {
      if ((bbuf==NULL)
	  ||(fbuf1==NULL)
	  ||(fbuf2==NULL)
	  )
	{
	  printf("Uh-oh, NULL.\n");
	  fflush(stdout);
	}

      free(bbuf);
      free(fbuf1);
      free(fbuf2);
      destroyshm();
      fbuf1=malloc(nwidth*nheight);
      fbuf2=malloc(nwidth*nheight);
      if (bufferstep) fbuf=fbuf1;
      else fbuf=fbuf2;
      bbuf=malloc(nwidth*nheight);
      if (rotated==1)
	createshm(bwidth=nwidth,bheight=nheight);
      else
	createshm(bheight=nheight,bwidth=nwidth);
      pagesize=(bwidth*bheight)/4;
    }

  j=lastpix=0;
  i=0;

  while (i<(bwidth*bheight))
    {
      c1=NEXTBYTE;remaining--;

      if (c1&128)
	{
	  c2=NEXTBYTE;remaining--;
	  for (j=256;j>c1;j--)
	    {
	      bbuf[i]=(unsigned char)c2;
	      i++;
	      if (!(i<(bwidth*bheight))) break;
	    }
	}
      else
	{
	  NEXTBLOCK(&bbuf[i],c1);
	  i+=c1;
	}
    }

  memcpy(fbuf1,bbuf,bwidth*bheight);
  memcpy(fbuf2,bbuf,bwidth*bheight);

  deb("[%ldx%ld]\n",bheight,bwidth);fflush(stdout);

/*  XPutImage(display, window, gc, ximage,
	    0,  0, 0, 0, bheight, bwidth);*/

/*  sprintf(fn,"back%ld.img",position);
  printf("\t- Background image (dumping to %s)\n",fn);
  im = fopen(fn,"wb");
  for (i=0;i<remaining;i++)
    {
      fputc(fgetc(fp),im);
    }
  fclose(im);*/
}

void show(void)
{
  unsigned short int i,j,k;

  if (rotated==1)
    {
      if ((bwidth==320) && (bheight==200))
	{
	  for (i=0;i<64000;i++)
	    {
	      ximage->data[i]=fbuf[trans[i]];
	    }
//	  XShmPutImage(display, window, gc, ximage,
//		    0,  0, 0, 0, bwidth, bheight,True);
{
static unsigned char *poo=NULL;
if (!poo) poo = vga_getgraphmem();
	memcpy(poo, ximage->data, 320*200);
}

	}	      
    }
  else if (rotated==0)
    {
      if (debug)
	{
	  memcpy(ximage->data,fbuf,bwidth*bheight);
	  XShmPutImage(display, window, gc, ximage,
		    0,  0, 200, 0, bheight, bwidth,True);
	  
	  memcpy(ximage->data,bbuf,bwidth*bheight);
	  XShmPutImage(display, window, gc, ximage,
		    0,  0, 400, 0, bheight, bwidth,True);
	  
	  if (0)
	    {
	      memcpy(&fbuf[pagesize],fbuf,pagesize);
	      memcpy(&fbuf[pagesize*2],fbuf,pagesize);
	      memcpy(&fbuf[pagesize*3],fbuf,pagesize);
	    }   
	}
      
      k=bwidth/4;
      j=k;
      for (i=0;i<k;i++)
	{
	  j--;
	  /*	  memcpy(&(ximage->data[(j*4+3)*bheight]),&fbuf[i*bheight],bheight);
	  memcpy(&(ximage->data[(j*4+2)*bheight]),&fbuf[(i+bwidth/4)*bheight],bheight);
	  memcpy(&(ximage->data[(j*4+1)*bheight]),&fbuf[(i+bwidth/2)*bheight],bheight);
	  memcpy(&(ximage->data[(j*4)*bheight]),&fbuf[(i+3*(bwidth/4))*bheight],bheight);*/
	}
/*      XPutImage(display, window, gc, ximage,
		0,  0, 0, 0, bheight, bwidth);*/

      XShmPutImage(display,window,gc,ximage,0,0,0,0,bheight,bwidth,True);
    }

}

void doForeground(void)
{
  int j,lastpix,nwidth,nheight,k,page,p1,p2,p3,p4,p5,p6;
  unsigned long int i,ix,iy;
  unsigned long int xx;
  char fn[100];
  FILE *im;

  unsigned char tab[128];

  deb("\t- Foreground (");

  if (1)
  {
    THROWAWAY(5);
    remaining-=5;
/*    for (i=0;i<5;i++) printf("%ld.",NEXTBYTE);*/

    xx=NEXTUL;
    remaining-=4;
/*    deb("*%ld*",xx);*/

    i=NEXTUL;
    remaining-=4;
/*    deb("*%ld*",i);*/

    if ((i-xx)!=134) deb("--XXXXXXX--%ld--",i-xx);
  }
  
  /*  XSetForeground(display, gc, pix[255]);
      XFillRectangle(display,window,gc,0,330,640,480);
      XSetForeground(display, gc, pix[63]);*/
  
#define ww 41
#define ix ((i/ww)*8)
#define iy ((i%ww)*2)
#define copyback {\
		    p4=iy*bheight+ix;\
		    for (p1=0;p1<8;p1++)\
		    {\
		       for (p2=0;p2<2;p2++)\
		       {\
			  p5=p4+p1+(p2*bheight);\
			  fbuf[p5]=bbuf[p5];\
			  p5+=pagesize;\
			  fbuf[p5]=bbuf[p5];\
			  p5+=pagesize;\
			  fbuf[p5]=bbuf[p5];\
			  p5+=pagesize;\
			  fbuf[p5]=bbuf[p5];\
		      }\
		   }\
		}
	
    i=0;
  
  for (j=0;j<134;j++)
    {
      c1=NEXTBYTE;
      
      if ((c1!=0)&&(j<128))
	{
	  if (c1&128) copyback; i++;
	  if (c1&64) copyback; i++;
	  if (c1&32) copyback; i++;
	  if (c1&16) copyback; i++;
	  if (c1&8) copyback; i++;
	  if (c1&4) copyback; i++;
	  if (c1&2) copyback; i++;
	  if (c1&1) copyback; i++;
	}
      else i+=8;
    }
  
  j=lastpix=0;
  i=page=0;

  if (1)
    {
      while ((i<((bwidth*bheight)))/*&&(remaining>0)*/)
	{ 
	  c1 = NEXTBYTE;/* remaining--;*/
	  /*      printf("** - %3d %3d\n",c1&0xC0,c1);
		  fflush(stdout);*/

	  if (c1==0x81)  /* next line */
	    {
	      i=i/bheight;
	      i++;
	      i=i*bheight;
	    }
	  else if (c1==0x80) /* next page */
	    {
	      deb("'@%ld,",i);
	      page++;
	      i=pagesize*page;
	      deb("%ld'",i);
	    }
	  else if (c1 > 129)  /* runlength piece, 0 transparent */
	    {
	      c2=NEXTBYTE;/*remaining--;*/
	      if (c2!=0) memset(&fbuf[i],c2,256-c1);
	      i+=256-c1;
	    }
	  else  /* raw block, 0 transparent */
	    {
	      if (c1>63) {deb("`*'");fflush(stdout);}
/*	      if (c1==0) printf("<0length>\n");fflush(stdout);*/
	      for (j=0;j<c1;j++)
		{
		  c2=NEXTBYTE;/*remaining--;*/
		  if (c2) fbuf[i]=c2;
/*		  if (c2) fbuf[i]=255; else fbuf[i]=64;*/
		  i++;
		}
	    }
	  /*      else printf("%d ",c1&0xC0);*/
	}
    }

  deb("[%ldx%ld]\n",bheight,bwidth);fflush(stdout);

  if (0)
    {
      sprintf(fn,"fore%ld.img",nextblock);
/*      sprintf(fn,"fore.img",nextblock);*/
      printf("\t- Foreground image (dumping to %s)\n",fn);
      im = fopen(fn,"wb");
      FWRITEBLOCK(im,remaining);
      fclose(im);
    }
}

void doAudio(void)
{
  int audiolen,i,k;

  THROWAWAY(1); /* dispose of a byte? */

  audiolen=NEXTUL;

  deb("\t- Audio, length %ld bytes [ ",audiolen);

  for (i=0;i<4;i++)
    {
      k=NEXTBYTE;
      deb("%ld ",k);
    }

  
/*  NEXTBLOCK(twoseconds,audiolen);*/
/*  fread(twoseconds,audiolen,1,fp);*/
/*  write(ifd,twoseconds,audiolen);*/

  WRITEBLOCK(ifd,audiolen);

  deb("]\n");
}

void gentrans(void)
{
  unsigned short int i,x,y;

  i=0;
  for (x=0;x<320;x++)
    { 
      for (y=0;y<200;y++)
	{
	  if (x<80)
	    {
	      trans[y*320+(x*4)]=i;
	    }
	  else
	    if (x<160)
	      {
		trans[(y*320+(x*4+1))-320]=i;
	      }
	    else
	      if (x<240)
		{
		  trans[(y*320+(x*4+2))-640]=i;
		}
	      else
		{
		  trans[(y*320+(x*4+3))-960]=i;
		}
	  i++;
	}
    }
}

void doAction(void)
{
  unsigned long int up,down,left,right,fire,nothing;

  THROWAWAY(3);
  
  up=NEXTUL;
  down=NEXTUL;
  nothing=NEXTUL;
  left=NEXTUL;
  right=NEXTUL;
  fire=NEXTUL;

  printf("> ");
  if (up==128<<24) printf("UP! ");
  if (down==128<<24) printf("DOWN! ");
  if (left==128<<24) printf("LEFT! ");
  if (right==128<<24) printf("RIGHT! ");
  if (fire==128<<24) printf("FIRE! ");
  if (nothing==128<<24) printf("(nothing) ");
  printf("\n");
}

void main(int argc, char **argv)  
{
  int i,j;
  unsigned char blocktype;
  struct stat fi;

  init_display(":0");

vga_init();
vga_setmode(G320x200x256);

  XSetForeground(display, gc, pix[64]); /* fairly constant black */
  XFillRectangle(display, window, gc, 0, 0, wwidth,wheight);

  fbuf1=malloc(320*200);
  fbuf2=malloc(320*200);
  if (bufferstep) fbuf=fbuf1;
  else fbuf=fbuf2;
  bbuf=malloc(320*200);
  if (rotated==1)
    createshm(320,200);
  else
    createshm(200,320);
  bwidth=320;
  bheight=200;
  pagesize=16000;

  if (sound)
    {
      if ((ifd=open(SOUNDDEVICE,O_WRONLY))==-1)
	{
	  fprintf(stderr,"warning: %s: ",SOUNDDEVICE);
	  perror(SOUNDDEVICE);
	  /*      exit(-1);*/
	}
    }

  if (rotated==1) gentrans();

#ifdef LINUX
  if (sound)
    {
      ioctl(ifd, SNDCTL_DSP_SETFRAGMENT, &frag);
      
      ioctl(ifd,SNDCTL_DSP_RESET);
      ioctl(ifd,SNDCTL_DSP_SPEED,&speed);
      printf("Speed: %dHz (desired: 22050Hz)\n",speed);
      ioctl(ifd,SNDCTL_DSP_SAMPLESIZE,&bits);
      printf("Bits: %d (desired: %d)\n",bits,AFMT_U8);
      ioctl(ifd,SNDCTL_DSP_STEREO,&stereo);
      printf("Stereo: %d (desired: 0)\n",stereo);
      ioctl(ifd,SNDCTL_DSP_SYNC);
    }
#endif

  ffd = open(argv[1],O_RDONLY);
  if (ffd==-1)
    {
      perror("open");
      exit(0);
    }
  fstat(ffd, &fi);
  FSIZE=fi.st_size;
  if ((MMF=(unsigned char *)mmap(NULL,FSIZE,PROT_READ,MAP_PRIVATE,ffd,0))==(unsigned char *)-1)
    {
      perror("mmap");
      exit(0);
    }

/*  for (i=0;i<fi.st_size;i++)
    {
      fputc(MMF[MMF_OFF++],stdout);
    }
  exit(0);*/

  MMF_OFF=0;

  while (MMF_OFF<FSIZE)
    {
      nextblock=NEXTUL;
      
      if (MMF_OFF>=FSIZE)
	{
	  deb("EOF\n");
	  goto finish;
	  break;
	}

      blocktype=NEXTBYTE; /* get block type */

      if (nextblock==128<<24)   /* freaky next-block-address */
	{
	  deb("\n-----------------------SCENE END <%d> - skipping over marker...\n",blocktype);
	  THROWAWAY(3);

	  nextblock=NEXTUL;

	  if (MMF_OFF>=FSIZE)
	    {
	      deb("EOF\n");
	      goto finish;
	      break;
	    }

	  blocktype=NEXTBYTE; /* get block type */
	}

      remaining=nextblock-MMF_OFF;

      deb("%ld\t%ld:\t%ld\t%ld",MMF_OFF,blocktype,remaining,nextblock);

      fflush(stdout);

      switch(blocktype) /* BLOCK TYPE */
	{
	case 0: /* BACKGROUND */
	  {
	    doBackground();
	    break;
	  }
	case 1: /* FOREGROUND */
	  {
	    doForeground();
	    break;
	  }
	case 2: /* AUDIO BLOCK */
	  {
	    if (sound) doAudio();
	    break;
	  }
	case 3: /* ACTION BLOCK */
	  {
	    deb("\t- ACTION - ");
	    doAction();
	    break;
	  }
	case 4: /* DISPOSE BACKGROUND? */
	  {
	    deb("\t- cut!");
	    memset(bbuf,0,bwidth*bheight);
	    while (remaining--) deb(" %d",NEXTBYTE);
	    deb("\n");
	    break;
	  }
	case 5: /* SYNC BLOCK */
	  {
	    deb("\t- SYNC");
	    for (i=0;i<5;i++) deb(" %d",NEXTBYTE);
	    deb("\n");
	    doPalette();
	    show();
	    XFlush(display);
/*	    XSync(display,False);*/
/*	    fgetc(stdin);*/
	    if (bufferstep) fbuf=fbuf1;
	    else fbuf=fbuf2;
	    bufferstep=!bufferstep;   /* swap buffers */
	    break;
	  }
	case 6: /* PALETTE */
	  {
	    getPalette();
	    break;
	  }
	case 7: /* SEQ ID */
	  {
	    deb("\t- Seq ID = ");
	    for (i=0;i<3;i++) deb("%d ",NEXTBYTE);
	    deb("\n");
	    break;
	  }
	default:
	  {
	    printf("\tUNKNOWN <%ld>",blocktype);
	    printf("\n");
	    break;
	  }
	}
      MMF_OFF=nextblock;
    }

 finish:
  XSync(display,False);
  destroyshm();
  if (sound) ioctl(ifd,SNDCTL_DSP_SYNC);

/*
  XShmPutImage(display, window, gc, ximage,
	       0,  0, 0, 0, width, height, False); 
  XPutImage(display, window, gc, ximage,
	    0,  0, 0, 0, width, height);
  XFlush(display);                                

  
  write(ifd,ximage->data,64000);
  fread(twoseconds,42000,1,fp);
  write(ifd,twoseconds,42000);*/

}

