home *** CD-ROM | disk | FTP | other *** search
- /*
- * Mac hack of
- * readfiles.c - routines to load images, fonts, and execution files.
- *
- * Copyright (c) 1991 by Patrick J. Naughton
- */
-
- #pragma segment Readfiles
-
- #include "grasp.h"
-
- ImageStruct *image[MAXIMAGES];
- int numimages = 0;
- FontStruct *font[MAXFONTS];
- int numfonts = 0;
- ExecStruct *exec[MAXEXECS];
- int numexecs = 0;
-
- extern ImageStruct *readgifimage();
-
- void
- lowerstr(s)
- char *s;
- {
- while (*s) {
- if (*s >= 'A' && *s <= 'Z')
- *s = *s + 'a' - 'A';
- s++;
- }
- }
-
- void
- hexdump(fp, n)
- FILE *fp;
- int n;
- {
- long ofs = ftell(fp);
- int i, j;
- u_char b[16];
-
- for (j = 0; j < n; j++) {
- for (i = 0; i < 16; i++) {
- b[i] = GetByte(fp);
- fprintf(stderr,"%02x ", b[i]);
- }
- fprintf(stderr," ");
- for (i = 0; i < 16; i++)
- fprintf(stderr,"%c ", isprint(b[i]) ? b[i] : '.');
- fprintf(stderr,"\n");
- }
- fseek(fp, ofs, 0);
- }
-
- /*-
- Border Color Table
- Color Color Palette 1 2 3
- ----- ----- ------- -----------------------------------
- 0 Black 0 Green Red Brown
- 1 Blue 1 Cyan Magenta White
- 2 Green 2 Cyan Red White
- 3 Cyan 3 Bright Green Bright Red Yellow
- 4 Red 4 Bright Cyan Bright Magenta White
- 5 Magenta 5 Bright Cyan Bright Red White
- 6 Brown -------------------------------------------
- 7 Grey
- 8 Dark Grey (Bright Black)
- 9 Bright Blue
- 10 Bright Green
- 11 Bright Cyan
- 12 Bright Red
- 13 Bright Magenta
- 14 Yellow (Bright Brown)
- 15 White (Bright Grey)
- */
-
- u_short egapal[16][3] = {
- {0x0000, 0x0000, 0x0000}, {0x0000, 0x0000, 0xaaaa},
- {0x0000, 0xaaaa, 0x0000}, {0x0000, 0xaaaa, 0xaaaa},
- {0xaaaa, 0x0000, 0x0000}, {0xaaaa, 0x0000, 0xaaaa},
- {0xaaaa, 0x5555, 0x0000}, {0xaaaa, 0xaaaa, 0xaaaa},
- {0x5555, 0x5555, 0x5555}, {0x5555, 0x5555, 0xffff},
- {0x5555, 0xffff, 0x5555}, {0x5555, 0xffff, 0xffff},
- {0xffff, 0x5555, 0x5555}, {0xffff, 0x5555, 0xffff},
- {0xffff, 0xffff, 0x5555}, {0xffff, 0xffff, 0xffff}
- };
-
- int cgapal[3][6] = {
- {2, 3, 3, 10, 11, 11},
- {4, 5, 4, 12, 13, 12},
- {6, 15, 15, 14, 15, 15}
- };
-
-
- Colormap CreateEGAcmap()
- {
- Colormap cmap;
- XColor colors[16];
- u_long pixels[16];
- u_long pmasks;
- int i;
-
- cmap = XCreateColormap(dsp, win, vis, AllocNone);
- XAllocColorCells(dsp, cmap, True, &pmasks, 0, pixels, 16);
-
- for (i = 0; i < 16; i++) {
- colors[i].pixel = pixels[i];
- colors[i].red = egapal[i][0];
- colors[i].green = egapal[i][1];
- colors[i].blue = egapal[i][2];
- colors[i].flags = DoRed | DoGreen | DoBlue;
- }
- XStoreColors(dsp, cmap, colors, 16);
- return cmap;
- }
-
- int
- findext(s)
- char *s;
- {
- int i;
- static char *exts[] = {
- "pic", "pcx", "pal", "clp", "gif", "set", "fnt", "txt"
- };
- static int extcodes[] = {
- EXT_PIC, EXT_PCX, EXT_PAL, EXT_CLP, EXT_GIF, EXT_SET, EXT_FNT, EXT_TXT
- };
-
- ++s; /* get past the dot */
- for (i = 0; i < (sizeof exts / sizeof exts[0]); i++)
- if (!strcmp(s, exts[i]))
- return extcodes[i];
- return -1;
- }
-
- void
- stringtofont(ex, i)
- ExecStruct *ex;
- {
- int k;
- char *s = strtok(ex->Code[i].val.s, ".");
- lowerstr(s);
- for (k = 0; k < numfonts; k++) {
- if (!strcmp(font[k]->name, s)) {
- free(ex->Code[i].val.s);
- ex->Code[i].token = FONTTYPE;
- ex->Code[i].val.font = font[k];
- break;
- }
- }
- if (k == numfonts) {
- fprintf(stderr,"font \"%s\" referenced but not in directory.\n", s);
- ex->Code[i].token = FONTTYPE;
- ex->Code[i].val.font = 0;
- }
- }
-
- void
- stringtoimage(ex, i, deftype)
- ExecStruct *ex;
- int i;
- int deftype;
- {
- int k;
- char *s = strtok(ex->Code[i].val.s, ".");
- char *ext = strrchr(ex->Code[i].val.s, '.');
- if (ext) {
- int extcode = findext(ext);
- for (k = 0; k < numimages; k++) {
- if (!strcmp(image[k]->name, s) && image[k]->type == extcode) {
- free(ex->Code[i].val.s);
- ex->Code[i].token = IMAGE;
- ex->Code[i].val.image = image[k];
- break;
- }
- }
- } else {
- for (k = 0; k < numimages; k++) {
- if (!strcmp(image[k]->name, s)) {
- /*
- * this might be the second time through here, so don't free
- * the string more than once...
- */
- if (ex->Code[i].token == STRING) {
- free(ex->Code[i].val.s);
- ex->Code[i].token = IMAGE;
- }
- ex->Code[i].val.image = image[k];
- if (image[k]->type == deftype)
- break;
- }
- }
- }
- if (ex->Code[i].token != IMAGE)
- error("%s: image \"%s\" referenced but not in directory.\n", s);
- }
-
- void
- stringtolabel(ex, i)
- ExecStruct *ex;
- int i;
- {
- int k;
- char *s = strtok(ex->Code[i].val.s, ".");
- lowerstr(s);
- for (k = 0; k < ex->numlabels; k++) {
- if (!strcmp(s, ex->label[k].string)) {
- free(ex->Code[i].val.s);
- ex->Code[i].token = INTEGER;
- ex->Code[i].val.i = ex->label[k].ipaddr;
- break;
- }
- if (k == ex->numlabels)
- error("%s: label \"%s\" referenced but not found.\n", s);
- }
- }
-
- void
- stringtoexec(ex, i)
- ExecStruct *ex;
- int i;
- {
- int k;
- char *s = strtok(ex->Code[i].val.s, ".");
- lowerstr(s);
- for (k = 0; k < numexecs; k++) {
- if (!strcmp(exec[k]->name, s)) {
- free(ex->Code[i].val.s);
- ex->Code[i].token = EXECTYPE;
- ex->Code[i].val.exec = exec[k];
- break;
- }
- }
- if (k == numexecs)
- error("%s: exec \"%s\" referenced but not in directory.\n", s);
- }
-
-
- int
- calcwidth(data, width, height, left)
- u_char *data;
- int width;
- int height;
- int *left;
- {
- int bpsl = (width + 7) >> 3;
- int right;
- int mask;
- int i;
- int j;
-
- /*find left */
- *left = 0;
- for (i = 0; i < bpsl; i++) {
- for (mask = 0x80; mask > 0; mask >>= 1) {
- for (j = 0; j < height; j++) {
- if (data[j * bpsl + i] & mask)
- goto calcright;
- }
- (*left)++;
- }
- }
- *left = 0;
- return width / 2; /* must be the space char... */
-
- calcright:/* find right */
-
- right = bpsl * 8;
- for (i = bpsl - 1; i >= 0; i--) {
- for (mask = 0x01; mask < 0x100; mask <<= 1) {
- for (j = 0; j < height; j++) {
- if (data[j * bpsl + i] & mask)
- return right - *left;
- }
- right--;
- }
- }
- error("%s: bad width calc.");
- }
-
-
- FontStruct *
- readfont(fp, dirent)
- FILE *fp;
- FilenameStruct *dirent;
- {
- FontStruct *font;
- XImage xim;
- int first;
- int num;
- int datasize;
- int i;
- char *data;
-
- fseek(fp, dirent->offset, 0);
- font = (FontStruct *) malloc(sizeof(FontStruct));
- font->name = strtok(strdup(dirent->fname), ".");
- (void) GetLong(fp); /* skip file length */
- (void) GetWord(fp); /* skip length */
- if (imverbose)
- hexdump(fp, 4);
- num = GetByte(fp);
- /* hack for trashed fonts... */
- if (num == -1) {
- free(font->name);
- free(font);
- return (FontStruct *) 0;
- }
- first = GetByte(fp);
- font->width = GetByte(fp);
- font->height = GetByte(fp);
- datasize = GetByte(fp);
- data = (char *) malloc(datasize);
- if (!data)
- error("%s: couldn't malloc glyph memory\n");
- if (verbose)
- fprintf(stderr, "%s: (FNT) %d %dx%d,%d(%d) glyphs, from %d to %d\n",
- font->name, num, font->width, font->height,
- datasize, font->height * ((font->width + 7) >> 3),
- first, first + num - 1);
-
-
- xim.height = font->height;
- xim.width = font->width;
- xim.depth = 1;
- xim.xoffset = 0;
- xim.format = XYBitmap;
- xim.data = data;
- xim.byte_order = MSBFirst;
- xim.bitmap_unit = 8;
- xim.bitmap_bit_order = MSBFirst;
- xim.bitmap_pad = 8;
- xim.bytes_per_line = (font->width + 7) / 8;
-
- for (i = 0; i < 256; i++) {
- if (i >= first && i < first + num) {
- fread(data, datasize, 1, fp);
- font->glyphs[i].width = calcwidth(data, font->width, font->height,
- &font->glyphs[i].lbearing);
- font->glyphs[i].pix = XCreatePixmap(dsp, win,
- font->width, font->height, 1);
- XPutImage(dsp, font->glyphs[i].pix, gc1, &xim, 0, 0, 0, 0,
- font->width, font->height);
- } else {
- font->glyphs[i].pix = (Pixmap) 0;
- font->glyphs[i].width = 0;
- font->glyphs[i].lbearing = 0;
- }
- }
-
-
- free(data);
-
- return font;
- }
-
-
- FontStruct *
- readset(fp, dirent)
- FILE *fp;
- FilenameStruct *dirent;
- {
- FontStruct *font;
- XImage xim;
- int first;
- int num;
- int datasize;
- int i;
- char *data;
- char fontname[14];
- int type;
- int checktype;
- int fontascent;
- int proportional;
- int bpsl;
- int lfgap;
- int italics;
- int fntinvert;
- int fnthbold;
- int fntvbold;
- int fnthmag;
- int fntvmag;
- int fnthfract;
- int fntvfract;
- int fntdirection;
- int fntrot90;
- int fnthflip;
- int fntvflip;
- int fntcolor;
- int fntsubtype;
- char unused[18];
- int dataofs;
-
- int celloffs[256];
- int cellwidth[256];
-
- fseek(fp, dirent->offset, 0);
-
- (void) GetLong(fp); /* skip file length */
-
- if (imverbose)
- hexdump(fp, 4);
-
- /* non-compressed type = 0x10 or compressed type = 0x14 */
- type = GetByte(fp);
- if (type != 0x10 && type != 0x14)
- return readfont(fp, dirent);
-
- fread(fontname, 13, 1, fp);
- fontname[13] = 0;
- /* non-compressed font = 0xba, compressed font = 0xdc */
- checktype = GetByte(fp);
-
- font = (FontStruct *) malloc(sizeof(FontStruct));
- font->name = strtok(strdup(dirent->fname), ".");
-
- fontascent = GetByte(fp);
- num = GetByte(fp);
- /* limited to the lower 94 ASCII characters: 0x21 - 0x7E */
- first = GetByte(fp) + 0x20;
- proportional = GetByte(fp); /* 0 = non-proportional */
- font->width = GetByte(fp);
- font->height = GetByte(fp);
- bpsl = GetByte(fp);
- datasize = font->height * bpsl;
- spacegap = GetByte(fp);
- chargap = GetByte(fp);
- lfgap = GetByte(fp);
- (void) GetWord(fp); /* skip file length */
- italics = GetByte(fp);
-
- fntinvert = GetByte(fp); /* 0 = dont invert, 1 = invert */
- fnthbold = GetByte(fp); /* number of overlapping bits horizontal */
- fntvbold = GetByte(fp); /* number of overlapping bits vertical */
- fnthmag = GetByte(fp); /* integral horizontal bit magnification */
- fntvmag = GetByte(fp); /* integral vertical bit magnification */
- fnthfract = GetByte(fp); /* fractional horizontal bit magnification */
- fntvfract = GetByte(fp); /* fractional vertical bit magnification */
- fntdirection = GetByte(fp); /* Print direction 0 = left to right, 1...3 =
- * counterclock 1...3 */
- fntrot90 = GetByte(fp); /* rotation 0 = up, 1...3 = counterclock 1...3 */
- fnthflip = GetByte(fp); /* horizontal flip 0 = no, 1 = yes */
- fntvflip = GetByte(fp); /* vertical flip 0 = no, 1 = yes */
- fntcolor = GetByte(fp); /* color of font */
- fntsubtype = GetByte(fp); /* subcategory type of this font */
- fread(unused, 18, 1, fp);
-
- if (verbose)
- fprintf(stderr, "%s[%s]: (SET) %d %dx%d,%d %sglyphs, from %d to %d\n",
- font->name, fontname, num, font->width, font->height, datasize,
- proportional ? "var-" : "fixed-", first, first + num - 1);
-
- if (type == 0x10) {
- for (i = 0; i <= num; i++)
- celloffs[i] = GetWord(fp);
- if (proportional) {
- for (i = 0; i <= num; i++)
- cellwidth[i] = GetByte(fp);
- }
- dataofs = ftell(fp) - dirent->offset + 4;
- data = (char *) malloc(datasize * num);
- if (!data)
- error("%s: couldn't malloc glyph memory\n");
- fread(data, num, datasize, fp);
-
- xim.width = font->width;
- xim.height = font->height;
- xim.depth = 1;
- xim.xoffset = 0;
- xim.format = XYBitmap;
- xim.data = 0;
- xim.byte_order = MSBFirst;
- xim.bitmap_unit = 8;
- xim.bitmap_bit_order = MSBFirst;
- xim.bitmap_pad = 8;
- xim.bytes_per_line = bpsl;
-
- for (i = 0; i < 256; i++) {
- font->glyphs[i].pix = (Pixmap) 0;
- font->glyphs[i].width = 0;
- font->glyphs[i].lbearing = 0;
- }
-
- for (i = 0; i <= num; i++) {
- int j = first + i - 1;
-
- font->glyphs[j].lbearing = 0;
- font->glyphs[j].width = proportional ? cellwidth[i] : font->width;
- font->glyphs[j].pix = XCreatePixmap(dsp, win,
- font->glyphs[j].width, font->height, 1);
- xim.data = &data[celloffs[i] - dataofs];
- XPutImage(dsp, font->glyphs[j].pix, gc1, &xim, 0, 0, 0, 0,
- font->glyphs[j].width, font->height);
- }
-
- free(data);
-
- } else {
- fprintf(stderr,"dont do compressed SET's yet.\n");
- }
- return font;
- }
-
-
- ImageStruct *
- readimage(fp, dirent, filetype)
- FILE *fp;
- FilenameStruct *dirent;
- int filetype;
- {
- ImageStruct *im;
- XImage *xim;
- int i;
- int j;
- int format;
- int bpsl;
- int blocks;
- int datasize;
- long blockoffset;
- u_char *ptr;
- int bpp;
- int planes;
- int idx;
- int magic;
- int unknown;
- int type;
- int edesc;
- int exsize;
- short maxcolorval;
- u_long pixels[256];
- u_long pmasks;
- int filelen;
-
- im = (ImageStruct *) malloc(sizeof(ImageStruct));
-
- fseek(fp, dirent->offset, 0);
-
- filelen = GetLong(fp); /* length of whole image file... */
-
- if (imverbose)
- hexdump(fp, 4);
-
- im->name = strtok(strdup(dirent->fname), ".");
- im->type = filetype;
-
- magic = GetWord(fp);
- if (magic != 0x1234) { /* I'm guessing here */
- im->w = GetWord(fp);
- im->h = GetWord(fp);
- fprintf(stderr,"\nstrange magic, maybe bad data\n");
- fprintf(stderr,"%dx%d %d, %d, %d, %d\n", im->w, im->h, im->w * im->h / 4,
- magic - 6, ((im->w + 3) >> 2) * im->h, filelen - 6);
-
- return NULL;
-
- /* found in magic.gl
- "15934x16190 64492865, 15928, 64500960, 1044266552"
- im->w im->h w*h/4 magic-6 (w+3)>>2)*h filelen-6
-
- magic == im.w
-
- */
- im->xoff = 0;
- im->yoff = 0;
- bpp = 2;
- planes = 1;
- type = 'a';
- edesc = 1;
- exsize = 0;
- } else {
- im->w = GetWord(fp);
- im->h = GetWord(fp);
- im->xoff = GetWord(fp);
- im->yoff = GetWord(fp);
- bpp = GetByte(fp);
- planes = ((bpp & 0xf0) >> 4) + 1;
- bpp &= 0x0f;
- if (GetByte(fp) != 0xff)
- error("%s: %s is corrupt\n", im->name);
- type = GetByte(fp);
- edesc = GetWord(fp);
- exsize = GetWord(fp);
- }
-
- if (bpp == 1 && planes == 1) {
- im->d = 1;
- format = XYBitmap;
- bpsl = (im->w + 7) >> 3;
- XSetForeground(dsp, gc, white);
- XSetBackground(dsp, gc, black);
- } else {
- im->d = 8;
- format = ZPixmap;
- bpsl = im->w;
- }
- datasize = bpsl * im->h;
- ptr = (u_char *) malloc(datasize);
- if (!ptr)
- error("%s: readimage: malloc failed on image data.\n");
-
- if (verbose)
- fprintf(stderr,
- "%s: (PIC) %dx%dx%d(%1x:%1x) [%d,%d] sz=%d t=%c edesc=%02x ext=%d\n",
- im->name,
- im->w,
- im->h,
- im->d,
- bpp, planes,
- im->xoff,
- im->yoff,
- datasize,
- type,
- edesc,
- exsize);
-
- if (edesc != 0)
- im->cmap = XCreateColormap(dsp, win, vis, AllocNone);
-
- switch (edesc) {
- case 0:
- im->cmaplen = 0;
- im->cmap = (Colormap) 0;
- break;
- case 1:
- im->cmaplen = 4;
- break;
- case 2:
- im->cmaplen = 16;
- maxcolorval = 15;
- break;
- case 3:
- im->cmaplen = 16;
- maxcolorval = 63;
- break;
- case 4:
- im->cmaplen = 256;
- maxcolorval = 63;
- break;
- case 5:
- im->cmaplen = 16;
- maxcolorval = 63;
- break;
- default:
- error("%s: bad edesc: %d\n", edesc);
- }
-
- if (im->cmaplen > 0)
- XAllocColorCells(dsp, im->cmap, True, &pmasks, 0, pixels, im->cmaplen);
-
- switch (edesc) {
- case 0:
- break;
- case 1:
- {
- char pal;
-
- if (exsize != 2)
- error("%s: unexpected esize: %d\n", exsize);
- pal = GetByte(fp);
- j = GetByte(fp);
- i = 0;
-
- im->colors[i].pixel = pixels[i];
- im->colors[i].red = egapal[j][0];
- im->colors[i].green = egapal[j][1];
- im->colors[i].blue = egapal[j][2];
- im->colors[i].flags = DoRed | DoGreen | DoBlue;
- for (i = 1; i < im->cmaplen; i++) {
- j = cgapal[i - 1][pal];
- im->colors[i].pixel = pixels[i];
- im->colors[i].red = egapal[j][0];
- im->colors[i].green = egapal[j][1];
- im->colors[i].blue = egapal[j][2];
- im->colors[i].flags = DoRed | DoGreen | DoBlue;
- }
-
- }
- break;
- case 2:
- case 3:
- if (exsize != im->cmaplen)
- error("%s: bad exsize: %d\n", exsize);
- for (i = 0; i < im->cmaplen; i++) {
- int pal = GetByte(fp);
- im->colors[i].pixel = pixels[i];
- im->colors[i].red = decodepal(pal, 0x20, 0x04) << 8;
- im->colors[i].green = decodepal(pal, 0x10, 0x02) << 8;
- im->colors[i].blue = decodepal(pal, 0x08, 0x01) << 8;
- im->colors[i].flags = DoRed | DoGreen | DoBlue;
- }
- break;
- case 4:
- case 5:
- #define fixcolr( c) ((c*255/maxcolorval) << 8)
-
- if (exsize != 0 && exsize != im->cmaplen * 3)
- fprintf(stderr,"bad exsize: %d\n", exsize);
- for (i = 0; i < im->cmaplen; i++) {
- unsigned short r,g,b;
- im->colors[i].pixel = pixels[i];
- im->colors[i].red = fixcolr(r=GetByte(fp));
- im->colors[i].green = fixcolr(g=GetByte(fp));
- im->colors[i].blue = fixcolr(b=GetByte(fp));
- }
- break;
- }
-
- if (edesc > 0) {
- if (verbose) {
- fprintf(stderr,"%d colors\n", im->cmaplen);
- /*----
- for (i = 0; i < im->cmaplen; i++) {
- fprintf(stderr,"%02x%02x%02x ",
- im->colors[i].red >> 8,
- im->colors[i].green >> 8,
- im->colors[i].blue >> 8);
- if (!((i + 1) % 8))
- fprintf(stderr,"\n");
- }
- -----*/
- }
- XStoreColors(dsp, im->cmap, im->colors, im->cmaplen);
- }
- if (magic != 0x1234) { /* BSAVE */
- fread(ptr, filelen - 6, 1, fp);
- } else {
- blocks = GetWord(fp);
- if (blocks == 0) {
- if (imverbose)
- fprintf(stderr,"unpacked data\n");
- fread(ptr, datasize, 1, fp);
- } else {
-
- if (imverbose) {
- fprintf(stderr,"%d image blocks\n", blocks);
- hexdump(fp, 4);
- }
- blockoffset = ftell(fp);
- idx = 0;
- for (i = 0; i < blocks; i++) {
- u_char esc;
- int rlebytes;
- int bufsize;
-
- fseek(fp, blockoffset, 0);
-
- rlebytes = GetWord(fp);
- bufsize = GetWord(fp);
- esc = GetByte(fp);
-
- blockoffset += rlebytes;
-
- if (imverbose) {
- fprintf(stderr,"block: %d (len = %d) (bufsize = %d) (esc = %d)\n",
- i, rlebytes, bufsize, esc);
- hexdump(fp, 4);
- }
- rlebytes -= 5;
- while (rlebytes) {
- u_char c = GetByte(fp);
- rlebytes--;
- if (c == esc) {
- u_int count = GetByte(fp);
- rlebytes--;
- if (count == 0) {
- count = GetWord(fp);
- rlebytes -= 2;
- }
- c = GetByte(fp);
- rlebytes--;
- #if 1
- if (idx + count > datasize) {
- fprintf(stderr, "*");
- goto bailimage;
- }
- #endif
- memset(&ptr[idx], c, count);
- idx += count;
- } else {
- #if 1
- if (idx + 1 > datasize) {
- fprintf(stderr, "*");
- goto bailimage;
- }
- #endif
- ptr[idx] = c;
- idx++;
- }
- }
- }
- }
- }
- bailimage:
-
- switch (bpp) {
- case 1:
- switch (planes) {
- case 1:
- break;
- case 2:
- case 3:
- error("%s: %d plane decoding not implemented\n", planes);
- break;
- case 4:
- {
- u_char *dst;
- u_char *src;
- u_char *old;
- int srcbpsl = (im->w + 7) >> 3;
- int plane0 = srcbpsl * 0 * im->h;
- int plane1 = srcbpsl * 1 * im->h;
- int plane2 = srcbpsl * 2 * im->h;
- int plane3 = srcbpsl * 3 * im->h;
-
- src = old = ptr;
- dst = ptr = (u_char *) malloc(datasize);
-
- if (!dst)
- error("%s: readimage:4: malloc failed on image data.\n");
-
- for (j = 0; j < im->h; j++) {
- int mask = 0x80;
- int addr = j * srcbpsl;
- for (i = 0; i < im->w; i++, mask >>= 1) {
- if (mask == 0) {
- mask = 0x80;
- addr++;
- }
- *dst++ = ((src[plane0 + addr] & mask) != 0) +
- 2 * ((src[plane1 + addr] & mask) != 0) +
- 4 * ((src[plane2 + addr] & mask) != 0) +
- 8 * ((src[plane3 + addr] & mask) != 0);
- }
- }
- free(old);
- }
- break;
- }
- break;
- case 2:
- switch (planes) {
- case 1:
- {
- u_char *dst;
- u_char *src;
- u_char *old;
- int rem;
-
- src = old = ptr;
- dst = ptr = (u_char *) malloc(datasize);
-
- if (!dst)
- error("%s: readimage:2: malloc failed on image data.\n");
-
- rem = im->w & 3;
- for (i = 0; i < im->h; i++) {
- for (j = 0; j < im->w >> 2; j++) {
- *dst++ = *src >> 6 & 3;
- *dst++ = *src >> 4 & 3;
- *dst++ = *src >> 2 & 3;
- *dst++ = *src >> 0 & 3;
- src++;
- }
- switch (rem) {
- case 3:
- dst[2] = *src >> 2 & 3;
- case 2:
- dst[1] = *src >> 4 & 3;
- case 1:
- dst[0] = *src >> 6 & 3;
- src++;
- dst += rem;
- case 0:
- break;
- }
- }
- free(old);
- }
- break;
- default:
- error("%s: %d plane decoding not implemented\n", planes);
- break;
- }
- break;
- case 4:
- {
- u_char *dst;
- u_char *src;
- u_char *old;
-
- src = old = ptr;
- dst = ptr = (u_char *) malloc(datasize);
-
- if (!dst)
- error("%s: readimage:4b: malloc failed on image data.\n");
-
- for (i = 0; i < im->h; i++) {
- for (j = 0; j < im->w / 2; j++) {
- *dst++ = *src >> 4 & 0xf;
- *dst++ = *src >> 0 & 0xf;
- src++;
- }
- }
- free(old);
- }
- break;
- case 8:
- break;
- }
-
- /* invert the image top to bottom */
- // is this where we mess up left edge -> right edge ??
- {
- u_char *buffer;
- buffer = (u_char *) malloc(bpsl);
- for (i = 0; i < im->h / 2; i++) {
- memcpy(buffer, ptr + (im->h - i - 1) * bpsl, bpsl);
- memcpy(ptr + (im->h - i - 1) * bpsl, ptr + i * bpsl, bpsl);
- memcpy(ptr + i * bpsl, buffer, bpsl);
- }
- free(buffer);
- }
-
- xim = XCreateImage(dsp, vis, im->d, format, 0, ptr, im->w, im->h, 8, bpsl);
- //im->pix = XCreatePixmap(dsp, win, im->w, im->h, 8);
- //XPutImage(dsp, im->pix, gc, xim, 0, 0, 0, 0, im->w, im->h);
- //XSync(dsp, False);
- // mac, non-X fix
- im->w= xim->width; // patch in case CreateImage needed to change size
- im->h= xim->height;
- im->pix = (Pixmap) xim;
-
- return im;
- }
-
-
- ImageStruct *
- readpcximage(fp, dirent)
- FILE *fp;
- FilenameStruct *dirent;
- {
- ImageStruct *im;
- XImage *xim;
- int i;
- int j;
- u_char pcxhd[128];
- int magic;
- int version;
- int encoded;
- int bpp;
- int xmin, ymin, xmax, ymax;
- int planes;
- int bpsl;
-
- int datasize;
- u_char *ptr;
- int maxcolorval;
- u_long pixels[256];
- u_long pmasks;
- int filelen;
- int format;
-
- im = (ImageStruct *) malloc(sizeof(ImageStruct));
-
- fseek(fp, dirent->offset, 0);
-
- filelen = GetLong(fp); /* length of whole image file... */
-
- if (imverbose)
- hexdump(fp, 4);
-
- im->name = strtok(strdup(dirent->fname), ".");
- im->type = EXT_PCX;
-
- fread(pcxhd, 128, 1, fp);
- magic = pcxhd[0];
- if (magic != 0x0a)
- fprintf(stderr,"I don't think this is really a .pcx file!\n");
- version = pcxhd[1];
- encoded = pcxhd[2];
- xmin = pcxhd[4] + (256 * pcxhd[5]);
- ymin = pcxhd[6] + (256 * pcxhd[7]);
- xmax = pcxhd[8] + (256 * pcxhd[9]);
- ymax = pcxhd[10] + (256 * pcxhd[11]);
- im->w = xmax - xmin + 1;
- im->h = ymax - ymin + 1;
- im->xoff = im->yoff = 0;
- bpsl = pcxhd[66] + (256 * pcxhd[67]);
- bpp = pcxhd[3];
- planes = pcxhd[65];
-
- if (bpp == 1 && planes == 1) {
- im->d = 1;
- format = XYBitmap;
- XSetForeground(dsp, gc, white);
- XSetBackground(dsp, gc, black);
- } else {
- im->d = 8;
- format = ZPixmap;
- bpsl = im->w;
- }
- datasize = bpsl * im->h;
- ptr = (u_char *) malloc(datasize);
- if (!ptr)
- error("%s: readpcximage: malloc failed on image data.\n");
-
- if (verbose)
- fprintf(stderr,"%s: (PCX) %dx%dx%d(%1x:%1x) [%d,%d] sz=%d ver=%d enc=%d\n",
- im->name,
- im->w,
- im->h,
- im->d,
- bpp, planes,
- im->xoff,
- im->yoff,
- datasize,
- version,
- encoded);
-
- if (version != 0)
- im->cmap = XCreateColormap(dsp, win, vis, AllocNone);
-
- switch (version) {
- case 0:
- case 3:
- im->cmaplen = 0;
- im->cmap = (Colormap) 0;
- break;
- case 2:
- im->cmaplen = 16;
- maxcolorval = 255;
- break;
- case 5:
- im->cmaplen = 256;
- maxcolorval = 255;
- break;
- case 1:
- case 4:
- default:
- error("%s: bad pcx version: %d\n", version);
- }
-
- if (im->cmaplen > 0)
- XAllocColorCells(dsp, im->cmap, True, &pmasks, 0, pixels, im->cmaplen);
-
- switch (version) {
- case 0:
- case 3:
- break;
- case 2: /* I'm guessing here! */
- for (i = 0; i < im->cmaplen; i++) {
- im->colors[i].pixel = pixels[i];
- im->colors[i].red = pcxhd[16 + i + 0] << 8;
- im->colors[i].green = pcxhd[16 + i + 1] << 8;
- im->colors[i].blue = pcxhd[16 + i + 2] << 8;
- im->colors[i].flags = DoRed | DoGreen | DoBlue;
- }
- break;
- case 5:
- fseek(fp, dirent->offset + filelen + 4 - 769, 0);
- if (GetByte(fp) != 12)
- fprintf(stderr,"I don't think this is a VGA palette.\n");
- for (i = 0; i < im->cmaplen; i++) {
- im->colors[i].pixel = pixels[i];
- im->colors[i].red = GetByte(fp) << 8;
- im->colors[i].green = GetByte(fp) << 8;
- im->colors[i].blue = GetByte(fp) << 8;
- im->colors[i].flags = DoRed | DoGreen | DoBlue;
- }
- fseek(fp, dirent->offset + 4 + 128, 0);
- break;
- }
-
- if (version > 0) {
- if (imverbose) {
- fprintf(stderr,"%d colors\n", im->cmaplen);
- /*---
- for (i = 0; i < im->cmaplen; i++) {
- fprintf(stderr,"%02x%02x%02x ",
- im->colors[i].red >> 8,
- im->colors[i].green >> 8,
- im->colors[i].blue >> 8);
- if (!((i + 1) % 8))
- fprintf(stderr,"\n");
- }
- ---*/
- }
- XStoreColors(dsp, im->cmap, im->colors, im->cmaplen);
- }
- if (encoded) {
- /*
- * Goes like this: Read a byte. If the two high bits are set, then the
- * low 6 bits contain a repeat count, and the byte to repeat is the
- * next byte in the file. If the two high bits are not set, then this
- * is the byte to write.
- */
-
- int i = 0;
-
- while (i < datasize) {
- int byte = GetByte(fp);
- if ((byte & 0xc0) == 0xc0) {
- int count = byte & 0x3f;
- int value = GetByte(fp);
- if (i + count > datasize)
- count = datasize - i - 1; /* catch overflow */
- memset(ptr + i, value, count);
- i += count;
- } else {
- ptr[i++] = byte;
- }
- }
- } else
- fread(ptr, datasize, 1, fp);
-
- /*
- * need to do planar -> chunky conversion here if we support > 1 plane pcx
- * files.
- */
-
- xim = XCreateImage(dsp, vis, im->d, format, 0, ptr, im->w, im->h, 8, bpsl);
- /*****
- im->pix = XCreatePixmap(dsp, win, im->w, im->h, 8);
- XPutImage(dsp, im->pix, gc, xim, 0, 0, 0, 0, im->w, im->h);
- XSync(dsp, False);
- *****/
- // mac, non-X fix
- im->w= xim->width; // patch in case CreateImage needed to change size
- im->h= xim->height;
- im->pix = (Pixmap) xim;
-
- return im;
- }
-
-
- void
- printcodes(ex)
- ExecStruct *ex;
- {
- int i;
- for (i = 0; i < ex->numcodes; i++) {
- fprintf(stderr,"%4d: ", i);
- if (ex->Code[i].token < NTOKENS)
- fprintf(stderr,"[TOK] %s (%d) (%d args)\n",
- tokens[ex->Code[i].token], ex->Code[i].token,
- ex->Code[i].val.i);
- else {
- switch (ex->Code[i].token) {
- case INTEGER:
- fprintf(stderr,"[INT] %d\n", ex->Code[i].val.i);
- break;
- case STRING:
- fprintf(stderr,"[STR] \"%s\"\n", ex->Code[i].val.s);
- break;
- case IMAGE:
- fprintf(stderr,"[IMG] \"%s\"\n", ex->Code[i].val.image->name);
- break;
- case FONTTYPE:
- fprintf(stderr,"[FNT] \"%s\"\n", ex->Code[i].val.font->name);
- break;
- case EXECTYPE:
- fprintf(stderr,"[EXC] \"%s\"\n", ex->Code[i].val.exec->name);
- break;
- case WILDTYPE:
- fprintf(stderr,"[WLD] \"@\"\n");
- break;
- default:
- error("%s: printcodes bogosity (%d)\n", ex->Code[i].token);
- }
- }
- }
- fprintf(stderr,"labels:\n");
- for (i = 0; i < ex->numlabels; i++)
- fprintf(stderr,"[LABEL] \"%s\" %d\n", ex->label[i].string, ex->label[i].ipaddr);
- }
-
-
- /* turn all cload and pload args into pointers to the
- * actual image structure instead of the filename
- * turn all fload args into pointers to the font structure
- * instead of the filename, and change the '@' string to a WILDTYPE.
- */
- void
- converttypes(ex)
- ExecStruct *ex;
- {
- int i, j;
- for (i = 0; i < ex->numcodes; i++) {
- int t = ex->Code[i].token;
- char *s = ex->Code[i].val.s;
- char nargs = ex->Code[i].val.i;
-
- switch (t) {
- case STRING:
- if (s[0] == '@' && s[1] == 0) {
- ex->Code[i].token = WILDTYPE;
- ex->Code[i].val.i = 0;
- }
- break;
- case FLOAD:
- stringtofont(ex, i + 1);
- break;
- case CLOAD:
- stringtoimage(ex, i + 1, EXT_CLP);
- break;
- case PLOAD:
- stringtoimage(ex, i + 1, EXT_PIC);
- break;
- case LINK:
- case CALL:
- stringtoexec(ex, i + 1);
- if (nargs > 1)
- stringtolabel(ex, i + 2);
- break;
- case DATABEGIN:
- case GOTO:
- case GOSUB:
- stringtolabel(ex, i + 1);
- break;
- case IFKEY:
- for (j = 2; j <= nargs; j += 2)
- stringtolabel(ex, i + j);
- break;
- case IFMEM:
- case IFVIDEO:
- case WAITKEY:
- if (nargs > 1)
- stringtolabel(ex, i + 2);
- break;
- }
- }
- }
-
- ExecStruct *
- readtxt(fp, dir)
- FILE *fp;
- FilenameStruct *dir;
- {
- ExecStruct *ex;
- int len;
- char *txt;
- int i;
-
- ex = (ExecStruct *) malloc(sizeof(ExecStruct));
- ex->name = strtok(strdup(dir->fname), ".");
-
- fseek(fp, dir->offset, 0);
- len = GetLong(fp);
- len &= 0x00ffffff; /* hack */
- ex->txt = (char *) malloc(len + 1);
- fread(ex->txt, len, 1, fp);
- ex->txt[len] = 26;
- if (showtext)
- puts(ex->txt);
- return ex;
- }
-
-
- void
- readfiles(fp, dir, count)
- FILE *fp;
- FilenameStruct *dir;
- int count;
- {
- int i;
- ImageStruct *im;
-
- for (i = 0; i < count; i++) {
- char *p = strrchr(dir[i].fname, '.');
- int extcode;
- if (!p)
- error("%s: %s has no extension.\n", dir[i].fname);
- extcode = findext(p);
- switch (extcode) {
- case EXT_PCX:
- image[numimages++] = readpcximage(fp, &dir[i]);
- break;
- case EXT_PIC:
- case EXT_CLP:
- case EXT_PAL:
- im = readimage(fp, &dir[i], extcode);
- if ((im==NULL) && (numimages>0)) im= image[numimages-1]; /* klugde fix */
- image[numimages++] = im;
- break;
- case EXT_GIF:
- image[numimages++] = readgifimage(fp, &dir[i]);
- break;
- case EXT_SET:
- font[numfonts++] = readset(fp, &dir[i]);
- if (font[numfonts - 1] == (FontStruct *) 0)
- --numfonts;
- break;
- case EXT_FNT:
- font[numfonts++] = readfont(fp, &dir[i]);
- if (font[numfonts - 1] == (FontStruct *) 0)
- --numfonts;
- break;
- case EXT_TXT:
- exec[numexecs++] = readtxt(fp, &dir[i]);
- break;
- default:
- fprintf(stderr,"skipping %s: unknown extension.\n", dir[i].fname);
- }
- }
-
- for (i = 0; i < numexecs; i++) {
- ExecStruct *ex = exec[i];
- parsefile(ex, ex->txt);
- converttypes(ex);
- if (printthecodes)
- printcodes(ex);
- }
-
- /********
- if (imageloop) {
- int im = 0;
-
- // XMapWindow(dsp, win);
- // XSync(dsp, False);
-
- while (1) {
- // XEvent ev;
- // XNextEvent(dsp, &ev);
- if (ev.type == ButtonPress) {
- if (++im >= numimages)
- im = 0;
- // if (((XButtonEvent *) & ev)->button == Button3)
- // break;
- XStoreName(dsp, win, image[im]->name);
- XSetWindowColormap(dsp, win, image[im]->cmap);
- XCopyArea(dsp, image[im]->pix, win, gc,
- 0, 0,
- image[im]->w,
- image[im]->h,
- 0, 0);
-
- }
- }
- }
- **********/
- }
-