/* * NOTE: mgif can now display flicker files, too. i used t his before * that was added and thought it might be useful standalone... */ #undef FULL_SCREEN /* * showfl - display a flicker-mode .FL file * * file consists of: * * offset size item * ------ ---- --------------------------------- * 0 10 magic (FLICKER91a) * 10 256 header * 2 w (in pixels, NOT bytes) * 2 h (in pixels, NOT bytes) * 252 reserved (should be 0 for FLICKER91a) * 266 n pixel data (3 "screens" holding bytes, 8 pixels * per byte). for widths not evenly divisible by 8, * a partial byte is used. so: * * if (w % 8) * nbytes = ((w + 8) / 8); * else * nbytes = (w / 8); * and * * nlines = h; * * n will be 3 * nbytes * nlines. for a 320x200 image, * n is 24000 (similar GIF is 25k to 50k bytes). */ static char *sccsid = "@(#) showfl 1.0 91/6/6 rosenkra\0\0 "; char *myname = "showfl\0\0\0\0\0\0"; char *version = "showfl 1.0 91/6/6 rosenkra\0\0\0 "; #include #include #define reg_t register #define DBG(x) /*printf x*/ #define SCRNSPACE 48256L /* buffer size for 3 screens (words) */ /* leave extra to word-align */ /* * globals: */ int _Width; /* image size */ int _Hight; int _ScrnBuf[SCRNSPACE]; /* enuf for 3 screens... */ int *_Scrn; /* -> first screen */ int montage = 0; /* * local functions */ int read_fl (); int showfl (); /*------------------------------*/ /* main */ /*------------------------------*/ main (argc, argv) int argc; char *argv[]; { reg_t long ii; reg_t int *pscrn; int count; /* * align to page boundary */ _Scrn = (int *) (((long) _ScrnBuf + 256L) & 0xFFFFFF00L); /* * parse args... */ for (argc--, argv++; (argc && **argv == '-'); argc--, argv++) { switch (*(*argv+1)) { case 'v': printf ("%s\n", version); exit (0); /* NO RETURN */ case 'h': usage (0); /* NO RETURN */ case 'm': montage++; break; default: break; } } /* * make sure we have at least one file... */ if (argc < 1) usage (1); /* NO RETURN */ if (montage) { /* * for either 4 320x200 images or 6 200x200 images. first * read them. note changing ptr into screen buffers... */ pscrn = _Scrn; count = 0; while (argc--) { printf ("Reading %s\n", *argv); if (!read_fl (*argv, pscrn, &_Width, &_Hight)) { fprintf (stderr, "read_fl failed for %s\n", *argv); exit (1); } count++; argv++; if ((_Width <= 320) && (_Width > 200) && (_Hight <= 400) && (_Hight > 200)) { /* * 2 320x400 images... */ if (count == 1) pscrn = (int *) ((long) _Scrn + 40L); else break; } else if ((_Width <= 320) && (_Width > 200) && (_Hight <= 200)) { /* * 4 320x200 images... */ if (count == 1) pscrn = (int *) ((long) _Scrn + 40L); else if (count == 2) pscrn = (int *) ((long) _Scrn + 16000L); else if (count == 3) pscrn = (int *) ((long) _Scrn + 16040L); else break; } else if ((_Width <= 200) && (_Hight <= 200)) { /* * 6 200x200 images... */ if (count == 1) pscrn = (int *) ((long) _Scrn + 25L); else if (count == 2) pscrn = (int *) ((long) _Scrn + 50L); else if (count == 3) pscrn = (int *) ((long) _Scrn + 16000L); else if (count == 4) pscrn = (int *) ((long) _Scrn + 16025L); else if (count == 5) pscrn = (int *) ((long) _Scrn + 16050L); else break; } else break; } /* * show them all... */ showfl (_Scrn); } else { /* * loop on files */ while (argc--) { /* * read file. if ok, display... */ printf ("Reading %s\n", *argv); if (read_fl (*argv, _Scrn, &_Width, &_Hight)) showfl (_Scrn); /* * clear screen buffer for next image if there * is one... */ if (argc) { pscrn = _ScrnBuf; for (ii = 0L; ii < SCRNSPACE; ii++) *pscrn++ = 0; argv++; } } } exit (0); } /*------------------------------*/ /* read_fl */ /*------------------------------*/ #define NCHUNK 400 /* size of chuck to read */ #define FL3MAGSZ 10 /* size of magic (chars) */ #define FL3HDRSZ 256 /* size of header */ #define MAGIC_FL3 "FLICKER91a" /* magic string */ int read_fl (fname, pscrn, w, h) char *fname; /* file name (in) */ int *pscrn; /* where to put screen data (out) */ int *w; /* size of image, pixels (out) */ int *h; { /* * read the flicker file. return 0 if error else 1. */ reg_t char *pbuf; reg_t int *pint; reg_t int nbytes; reg_t int nlines; reg_t long ii; int fd; FILE *stream; char magic[FL3MAGSZ+10]; char header[FL3HDRSZ+10]; char *pheader; DBG (("enter read_fl...\n")); /* * open the .fl file, binary... */ if ((stream = fopenb (fname, "r")) == (FILE *) NULL) { printf ("Error openning %s.\n", fname); return (0); } fd = fileno (stream); /* * read .fl magic */ read (fd, magic, (int) FL3MAGSZ); if (strncmp (magic, MAGIC_FL3, 10)) { printf ("Bad magic here...\n"); fclose (stream); return (0); } /* * read .fl header: * * offset size item * ------ ---- ----------------------------------------- * 0 2 width (pixels) * 2 2 height (pixels) */ if (header & 1) pheader = (char *) (&header[1]); else pheader = (char *) (&header[0]); read (fd, pheader, (int) FL3HDRSZ); pint = &pheader[0]; *w = *pint; pint = &pheader[2]; *h = *pint; #ifdef FULL_SCREEN /* * read the screens, sequentially. each screen is 32000 and there * are 3 screens for a total of 96000 bytes. work with NCHUNK bytes * at a time. */ pbuf = (char *) pscrn; for (ii = 0L; ii < 96000L/NCHUNK; ii++) /* number of reads */ { read (fd, pbuf, (int) NCHUNK); pbuf += (long) NCHUNK; } #else /* * this is space-saver version. we only need the actual pixels, * not the whole screen saved. find actual byte count for files * with w not evenly divisible by 8. */ if ((int) *w % 8) nbytes = ((*w + 8) >> 3); else nbytes = (*w >> 3); nlines = *h; /* screen 1 */ for (pbuf = (char *) pscrn, ii = 0L; ii < nlines; ii++) { read (fd, pbuf, nbytes); pbuf += 80L; /* 640x400 screen has 80 bytes/line */ } /* screen 2 */ for (pbuf = (char *) ((long) pscrn + 32000L), ii = 0L; ii < nlines; ii++) { read (fd, pbuf, nbytes); pbuf += 80L; } /* screen 3 */ for (pbuf = (char *) ((long) pscrn + 64000L), ii = 0L; ii < nlines; ii++) { read (fd, pbuf, nbytes); pbuf += 80L; } #endif /* * done. return success... */ fclose (stream); DBG (("read_fl returning...\n")); return (1); } /*------------------------------*/ /* showfl */ /*------------------------------*/ int showfl (s0) int *s0; { /* * show a flicker image already in memory. for 640x400 ONLY!!! * returns char read to stop the display as low byte of int. */ reg_t long ii; reg_t char *ps1; reg_t char *ps2; char *old1; char *old2; int *s1, *s2, *s3; long ret; DBG (("enter showfl...\n")); /* * remember old screen */ old1 = Logbase (); old2 = Physbase (); /* * clear these (phys and logical) */ ps1 = old1; ps2 = old2; for (ii = 0L; ii < 32000L; ii++) { *ps1++ = 0; *ps2++ = 0; } /* * set phys screen to first screen */ Setscreen (old2, s0, -1); /* * set pointers */ s1 = (int *) Physbase (); s2 = (int *) ((long) s1 + 32000L); s3 = (int *) ((long) s2 + 32000L); /* * display until a key is pressed */ do { Setscreen (old2, s1, -1); Vsync (); Setscreen (old2, s2, -1); Vsync (); Setscreen (old2, s3, -1); Vsync (); } while (!Bconstat (2)); /* * get the key... */ ret = Bconin (2) & 0x000000ffL; /* * reset screen */ Setscreen (old1, old2, -1); /* * clear keypresses */ while (Bconstat (2)) Bconin (2); /* * done. */ return ((int) ret); } /*------------------------------*/ /* usage */ /*------------------------------*/ usage (excode) int excode; { printf ("Usage: %s [-m] file.fl ...\n", myname); exit (excode); }